From 655b9d426208915ac78a11f5bcb226d79bf186df Mon Sep 17 00:00:00 2001 From: root Date: Mon, 27 Jun 2022 12:18:45 -0400 Subject: [PATCH 001/631] Python: Timing attack --- .../PossibleTimingAttackAgainstSignature.ql | 55 ++++++ .../Security/CWE-208/SafeComparison.py | 33 ++++ .../Security/CWE-208/TimingAttack.qhelp | 52 ++++++ .../Security/CWE-208/TimingAttack.qll | 168 ++++++++++++++++++ .../CWE-208/TimingAttackAgainstHeader.ql | 34 ++++ .../TimingAttackAgainstSensitiveInfo.ql | 34 ++++ .../CWE-208/TimingAttackAgainstSignature.ql | 38 ++++ .../Security/CWE-208/UnSafeComparison.py | 34 ++++ ...sibleTimingAttackAgainstSignature.expected | 8 + ...PossibleTimingAttackAgainstSignature.qlref | 1 + .../TimingAttackAgainstHeader.expected | 6 + .../CWE-208/TimingAttackAgainstHeader.py | 26 +++ .../CWE-208/TimingAttackAgainstHeader.qlref | 1 + .../TimingAttackAgainstSensitiveInfo.expected | 6 + .../TimingAttackAgainstSensitiveInfo.py | 36 ++++ .../TimingAttackAgainstSensitiveInfo.qlref | 1 + .../CWE-208/TimingAttackAgainstSignature.py | 19 ++ 17 files changed, 552 insertions(+) create mode 100644 python/ql/src/experimental/Security/CWE-208/PossibleTimingAttackAgainstSignature.ql create mode 100644 python/ql/src/experimental/Security/CWE-208/SafeComparison.py create mode 100644 python/ql/src/experimental/Security/CWE-208/TimingAttack.qhelp create mode 100644 python/ql/src/experimental/Security/CWE-208/TimingAttack.qll create mode 100644 python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHeader.ql create mode 100644 python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstSensitiveInfo.ql create mode 100644 python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstSignature.ql create mode 100644 python/ql/src/experimental/Security/CWE-208/UnSafeComparison.py create mode 100644 python/ql/test/experimental/query-tests/Security/CWE-208/PossibleTimingAttackAgainstSignature.expected create mode 100644 python/ql/test/experimental/query-tests/Security/CWE-208/PossibleTimingAttackAgainstSignature.qlref create mode 100644 python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstHeader.expected create mode 100644 python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstHeader.py create mode 100644 python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstHeader.qlref create mode 100644 python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstSensitiveInfo.expected create mode 100644 python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstSensitiveInfo.py create mode 100644 python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstSensitiveInfo.qlref create mode 100644 python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstSignature.py diff --git a/python/ql/src/experimental/Security/CWE-208/PossibleTimingAttackAgainstSignature.ql b/python/ql/src/experimental/Security/CWE-208/PossibleTimingAttackAgainstSignature.ql new file mode 100644 index 00000000000..1d84d2c1179 --- /dev/null +++ b/python/ql/src/experimental/Security/CWE-208/PossibleTimingAttackAgainstSignature.ql @@ -0,0 +1,55 @@ +/** + * @name Timing attack against digest validation + * @description When checking a signature over a message, a constant-time algorithm should be used. + * Otherwise, an attacker may be able to forge a valid digest for an arbitrary message + * by running a timing attack if they can send to the validation procedure + * both the message and the signature. + * A successful attack can result in authentication bypass. + * @kind path-problem + * @problem.severity error + * @precision high + * @id py/timing-attack-against-signature + * @tags security + * external/cwe/cwe-208 + */ + +import python +import semmle.python.dataflow.new.DataFlow +import semmle.python.dataflow.new.TaintTracking +import semmle.python.ApiGraphs +import TimingAttack +import DataFlow::PathGraph + +/** + * A configuration that tracks data flow from cryptographic operations + * to equality test + */ +class PossibleTimingAttackAgainstSignature extends TaintTracking::Configuration { + PossibleTimingAttackAgainstSignature() { this = "PossibleTimingAttackAgainstSignature" } + + override predicate isSource(DataFlow::Node source) { + source = API::moduleImport("hmac").getMember("digest").getACall() or + source = + API::moduleImport("hmac") + .getMember("new") + .getReturn() + .getMember(["digest", "hexdigest"]) + .getACall() or + source = + API::moduleImport("hashlib") + .getMember([ + "new", "sha1", "sha224", "sha256", "sha384", "sha512", "blake2b", "blake2s", "md5" + ]) + .getReturn() + .getMember(["digest", "hexdigest"]) + .getACall() + } + + override predicate isSink(DataFlow::Node sink) { sink instanceof CompareSink } +} + +from PossibleTimingAttackAgainstSignature config, DataFlow::PathNode source, DataFlow::PathNode sink +where config.hasFlowPath(source, sink) +select sink.getNode(), source, sink, "Possible Timing attack against $@ validation.", source, + source.getNode() + diff --git a/python/ql/src/experimental/Security/CWE-208/SafeComparison.py b/python/ql/src/experimental/Security/CWE-208/SafeComparison.py new file mode 100644 index 00000000000..377da6dd35b --- /dev/null +++ b/python/ql/src/experimental/Security/CWE-208/SafeComparison.py @@ -0,0 +1,33 @@ +#!/usr/bin/env python +# -*- coding: UTF-8 -*- + +""" +@Desc :preventing timing attack +""" +import hmac +from flask import Flask +from flask import request +import hashlib + +key = "e179017a-62b0-4996-8a38-e91aa9f1" + +@app.route('/good1') +def good1(): + Secret = request.headers.get('X-Auth-Token') + if not hmac.compare_digest(Secret, "token"): + raise Exception('bad token') + return 'good1' + +@app.route('/good2') +def check_credentials(password): + return hmac.compare_digest(password, "token") + +def sign(pre_key, msg, alg): + return hmac.new(pre_key, msg, alg).digest() + +def verify(msg, sig): + return hmac.compare_digest(sig, sign(key, msg, hashlib.sha256)) #good + +if __name__ == '__main__': + app.debug = True + app.run() diff --git a/python/ql/src/experimental/Security/CWE-208/TimingAttack.qhelp b/python/ql/src/experimental/Security/CWE-208/TimingAttack.qhelp new file mode 100644 index 00000000000..e048ec6b3b9 --- /dev/null +++ b/python/ql/src/experimental/Security/CWE-208/TimingAttack.qhelp @@ -0,0 +1,52 @@ + + + + +

+ Timing Attack is based on the leakage of information of secret parameters by studying +how long it takes the system to respond to different inputs. + it can be circumvented by using a constant-time algorithm for checking the value of sensitive info, +more precisely, the comparison time should not depend on the content of the input. Otherwise the attacker gains +information that is indirectly leaked by the application. This information is then used for malicious purposes, +such as guessing the password of a user. +

+
+ + + +

+ Two types of countermeasures can be applied against timing attacks. The first one consists +in eliminating timing variations whereas the second renders these variations useless for an attacker. +The only absolute way to prevent timing attacks is to make the computation strictly constant time, +independent of the input. + + Use hmac.compare_digest() method to securely check the value of sensitive info. +If this method is used, then the calculation time depends only on the length of input byte arrays, +and does not depend on the contents of the arrays. + Unlike == is a fail fast check, If the first byte is not equal, it will return immediately. +

+
+ +

+ The following example uses == which is a fail fast check for validating a secret. +

+ + +

+ The next example use a safe constant-time algorithm for validating a secret: +

+ +
+ + +
  • + Wikipedia: + Timing attack. +
  • + +
  • + hmac.compare_digest() method +
  • +
    + +
    diff --git a/python/ql/src/experimental/Security/CWE-208/TimingAttack.qll b/python/ql/src/experimental/Security/CWE-208/TimingAttack.qll new file mode 100644 index 00000000000..6dddbb56fd3 --- /dev/null +++ b/python/ql/src/experimental/Security/CWE-208/TimingAttack.qll @@ -0,0 +1,168 @@ +private import python +private import semmle.python.dataflow.new.TaintTracking +private import semmle.python.dataflow.new.TaintTracking2 +private import semmle.python.dataflow.new.TaintTracking3 +private import semmle.python.ApiGraphs +private import semmle.python.dataflow.new.RemoteFlowSources + +/** A data flow sink for comparison. */ +class CompareSink extends DataFlow::Node { + CompareSink() { + exists(Compare compare | + ( + compare.getOp(0) instanceof Eq or + compare.getOp(0) instanceof NotEq or + compare.getOp(0) instanceof In or + compare.getOp(0) instanceof NotIn + ) and + ( + compare.getLeft() = this.asExpr() + or + compare.getComparator(0) = this.asExpr() + ) + ) + } +} + +/** A string for `match` that identifies strings that look like they represent secret data. */ +private string suspicious() { + result = + [ + "%password%", "%passwd%", "%pwd%", "%refresh%token%", "%secret%token", "%secret%key", + "%passcode%", "%passphrase%", "%token%", "%secret%", "%credential%", "%key%", "%UserPass%" + ] +} + +/** A variable that may hold sensitive information, judging by its name. * */ +class CredentialExpr extends Expr { + CredentialExpr() { + exists(Variable v | this = v.getAnAccess() | v.getId().toLowerCase().matches(suspicious())) + } +} + +/** + * A data flow source of the client Secret obtained according to the remote endpoint identifier specified + * (`X-auth-token`, `proxy-authorization`, `X-Csrf-Header`, etc.) in the header. + * + * For example: `request.headers.get("X-Auth-Token")`. + */ +abstract class ClientSuppliedsecret extends DataFlow::CallCfgNode { } + +private class FlaskClientSuppliedsecret extends ClientSuppliedsecret { + FlaskClientSuppliedsecret() { + exists(RemoteFlowSource rfs, DataFlow::AttrRead get | + rfs.getSourceType() = "flask.request" and this.getFunction() = get + | + // `get` is a call to request.headers.get or request.headers.get_all or request.headers.getlist + // request.headers + get.getObject() + .(DataFlow::AttrRead) + // request + .getObject() + .getALocalSource() = rfs and + get.getAttributeName() in ["get", "get_all", "getlist"] and + get.getObject().(DataFlow::AttrRead).getAttributeName() = "headers" and + this.getArg(0).asExpr().(StrConst).getText().toLowerCase() = sensitiveheaders() + ) + } +} + +private class DjangoClientSuppliedsecret extends ClientSuppliedsecret { + DjangoClientSuppliedsecret() { + exists(RemoteFlowSource rfs, DataFlow::AttrRead get | + rfs.getSourceType() = "django.http.request.HttpRequest" and this.getFunction() = get + | + // `get` is a call to request.headers.get or request.META.get + // request.headers + get.getObject() + .(DataFlow::AttrRead) + // request + .getObject() + .getALocalSource() = rfs and + get.getAttributeName() = "get" and + get.getObject().(DataFlow::AttrRead).getAttributeName() in ["headers", "META"] and + this.getArg(0).asExpr().(StrConst).getText().toLowerCase() = sensitiveheaders() + ) + } +} + +private class TornadoClientSuppliedsecret extends ClientSuppliedsecret { + TornadoClientSuppliedsecret() { + exists(RemoteFlowSource rfs, DataFlow::AttrRead get | + rfs.getSourceType() = "tornado.web.RequestHandler" and this.getFunction() = get + | + // `get` is a call to `rfs`.request.headers.get + // `rfs`.request.headers + get.getObject() + .(DataFlow::AttrRead) + // `rfs`.request + .getObject() + .(DataFlow::AttrRead) + // `rfs` + .getObject() + .getALocalSource() = rfs and + get.getAttributeName() in ["get", "get_list"] and + get.getObject().(DataFlow::AttrRead).getAttributeName() = "headers" and + this.getArg(0).asExpr().(StrConst).getText().toLowerCase() = sensitiveheaders() + ) + } +} + +/** A string for `match` that identifies strings that look like they represent Sensitive Headers. */ +private string sensitiveheaders() { + result = + [ + "x-auth-token", "x-csrf-token", "http_x_csrf_token", "x-csrf-param", "x-csrf-header", + "http_x_csrf_token", "x-api-key", "authorization", "proxy-authorization" + ] +} + +/** + * A config that tracks data flow from remote user input to cryptographic operations + */ +private class UserInputMsgConfig extends TaintTracking::Configuration { + UserInputMsgConfig() { this = "UserInputMsgConfig" } + + override predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource } + + override predicate isSink(DataFlow::Node sink) { + sink = API::moduleImport("hmac").getMember("digest").getACall() or + sink = + API::moduleImport("hmac") + .getMember("new") + .getReturn() + .getMember(["digest", "hexdigest"]) + .getACall() or + sink = + API::moduleImport("hashlib") + .getMember([ + "new", "sha1", "sha224", "sha256", "sha384", "sha512", "blake2b", "blake2s", "md5" + ]) + .getReturn() + .getMember(["digest", "hexdigest"]) + .getACall() + } +} + +/** + * A config that tracks data flow from remote user input to Variable that hold sensitive info + */ +class UserInputSecretConfig extends TaintTracking2::Configuration { + UserInputSecretConfig() { this = "UserInputSecretConfig" } + + override predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource } + + override predicate isSink(DataFlow::Node sink) { sink.asExpr() instanceof CredentialExpr } +} + +/** + * A config that tracks data flow from remote user input to Equality test + */ +class UserInputInComparisonConfig extends TaintTracking3::Configuration { + UserInputInComparisonConfig() { this = "UserInputInComparisonConfig" } + + override predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource } + + override predicate isSink(DataFlow::Node sink) { sink instanceof CompareSink } +} + diff --git a/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHeader.ql b/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHeader.ql new file mode 100644 index 00000000000..1c28a239343 --- /dev/null +++ b/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHeader.ql @@ -0,0 +1,34 @@ +/** + * @name Timing attack against header value + * @description Use of a non-constant-time verification routine to check the value of an HTTP header, + * possibly allowing a timing attack to infer the header's expected value. + * @kind path-problem + * @problem.severity error + * @precision high + * @id py/timing-attack-against-header-value + * @tags security + * external/cwe/cwe-208 + */ + +import python +import semmle.python.dataflow.new.DataFlow +import semmle.python.dataflow.new.TaintTracking +import TimingAttack +import DataFlow::PathGraph + +/** + * Taint-tracking configuration tracing flow from obtaining a client Secret from an HTTP header to a unsafe Comparison. + */ +class ClientSuppliedSecretConfig extends TaintTracking::Configuration { + ClientSuppliedSecretConfig() { this = "ClientSuppliedSecretConfig" } + + override predicate isSource(DataFlow::Node source) { source instanceof ClientSuppliedsecret } + + override predicate isSink(DataFlow::Node sink) { sink instanceof CompareSink } +} + +from ClientSuppliedSecretConfig config, DataFlow::PathNode source, DataFlow::PathNode sink +where config.hasFlowPath(source, sink) +select sink.getNode(), source, sink, "Timing attack against $@ validation.", source.getNode(), + "client-supplied token" + diff --git a/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstSensitiveInfo.ql b/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstSensitiveInfo.ql new file mode 100644 index 00000000000..7640e2474b0 --- /dev/null +++ b/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstSensitiveInfo.ql @@ -0,0 +1,34 @@ +/** + * @name Timing attack against secret + * @description Use of a non-constant-time verification routine to check the value of an secret, + * possibly allowing a timing attack to retrieve sensitive information. + * @kind path-problem + * @problem.severity error + * @precision high + * @id py/timing-attack-sensitive-info + * @tags security + * external/cwe/cwe-208 + */ + +import python +import semmle.python.dataflow.new.DataFlow +import semmle.python.dataflow.new.TaintTracking +import TimingAttack +import DataFlow::PathGraph + +/** + * Taint-tracking configuration tracing flow from obtaining a client Secret to a unsafe Comparison. + */ +class ClientSuppliedSecretConfig extends TaintTracking::Configuration { + ClientSuppliedSecretConfig() { this = "ClientSuppliedSecretConfig" } + + override predicate isSource(DataFlow::Node source) { source.asExpr() instanceof CredentialExpr } + + override predicate isSink(DataFlow::Node sink) { sink instanceof CompareSink } +} + +from ClientSuppliedSecretConfig config, DataFlow::PathNode source, DataFlow::PathNode sink +where config.hasFlowPath(source, sink) +select sink.getNode(), source, sink, "Timing attack against $@ validation.", source.getNode(), + "client-supplied token" + diff --git a/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstSignature.ql b/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstSignature.ql new file mode 100644 index 00000000000..7616c1e734f --- /dev/null +++ b/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstSignature.ql @@ -0,0 +1,38 @@ +/** + * @name Timing attack against digest validation + * @description When checking a signature over a message, a constant-time algorithm should be used. + * Otherwise, an attacker may be able to forge a valid digest for an arbitrary message + * by running a timing attack if they can send to the validation procedure + * both the message and the signature. + * A successful attack can result in authentication bypass. + * @kind path-problem + * @problem.severity error + * @precision high + * @id py/timing-attack-against-signature + * @tags security + * external/cwe/cwe-208 + */ + +import python +import semmle.python.dataflow.new.DataFlow +import semmle.python.dataflow.new.TaintTracking +import TimingAttack +import DataFlow::PathGraph + +/** + * A configuration that tracks data flow from cryptographic operations + * to Equality test. + */ +class TimingAttackAgainstsignature extends TaintTracking::Configuration { + TimingAttackAgainstsignature() { this = "TimingAttackAgainstsignature" } + + override predicate isSource(DataFlow::Node source) { source instanceof UserInputMsgConfig } + + override predicate isSink(DataFlow::Node sink) { sink instanceof UserInputInComparisonConfig } +} + +from TimingAttackAgainstsignature config, DataFlow::PathNode source, DataFlow::PathNode sink +where config.hasFlowPath(source, sink) +select sink.getNode(), source, sink, "Timing attack against $@ validation.", source, + source.getNode() + diff --git a/python/ql/src/experimental/Security/CWE-208/UnSafeComparison.py b/python/ql/src/experimental/Security/CWE-208/UnSafeComparison.py new file mode 100644 index 00000000000..a90688568bb --- /dev/null +++ b/python/ql/src/experimental/Security/CWE-208/UnSafeComparison.py @@ -0,0 +1,34 @@ +#!/usr/bin/env python +# -*- coding: UTF-8 -*- +""" +@Desc :timing attack +""" + +from flask import Flask +from flask import request +import hmac + +app = Flask(__name__) + +key = "e179017a-62b0-4996-8a38-e91aa9f1" + +@app.route('/bad1') +def bad1(): + Secret = request.headers.get('X-Auth-Token') + if not Secret == "key": + raise Exception('bad token') + return 'bad1' + +@app.route('/bad2') +def check_credentials(password): + return password == "token" + +def sign(pre_key, msg, alg): + return hmac.new(pre_key, msg, alg).digest() + +def verify(msg, sig): + return sig == sign(key, msg, hashlib.sha256) #bad + +if __name__ == '__main__': + app.debug = True + app.run() diff --git a/python/ql/test/experimental/query-tests/Security/CWE-208/PossibleTimingAttackAgainstSignature.expected b/python/ql/test/experimental/query-tests/Security/CWE-208/PossibleTimingAttackAgainstSignature.expected new file mode 100644 index 00000000000..33c8ad2e663 --- /dev/null +++ b/python/ql/test/experimental/query-tests/Security/CWE-208/PossibleTimingAttackAgainstSignature.expected @@ -0,0 +1,8 @@ +edges +| TimingAttackAgainstSignature.py:13:12:13:47 | ControlFlowNode for Attribute() | TimingAttackAgainstSignature.py:19:19:19:48 | ControlFlowNode for sign() | +nodes +| TimingAttackAgainstSignature.py:13:12:13:47 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | +| TimingAttackAgainstSignature.py:19:19:19:48 | ControlFlowNode for sign() | semmle.label | ControlFlowNode for sign() | +subpaths +#select +| TimingAttackAgainstSignature.py:19:19:19:48 | ControlFlowNode for sign() | TimingAttackAgainstSignature.py:13:12:13:47 | ControlFlowNode for Attribute() | TimingAttackAgainstSignature.py:19:19:19:48 | ControlFlowNode for sign() | Possible Timing attack against $@ validation. | TimingAttackAgainstSignature.py:13:12:13:47 | ControlFlowNode for Attribute() | TimingAttackAgainstSignature.py:13:12:13:47 | ControlFlowNode for Attribute() | diff --git a/python/ql/test/experimental/query-tests/Security/CWE-208/PossibleTimingAttackAgainstSignature.qlref b/python/ql/test/experimental/query-tests/Security/CWE-208/PossibleTimingAttackAgainstSignature.qlref new file mode 100644 index 00000000000..3a113b0fd71 --- /dev/null +++ b/python/ql/test/experimental/query-tests/Security/CWE-208/PossibleTimingAttackAgainstSignature.qlref @@ -0,0 +1 @@ +experimental/Security/CWE/CWE-208/PossibleTimingAttackAgainstSignature.ql diff --git a/python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstHeader.expected b/python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstHeader.expected new file mode 100644 index 00000000000..14c8b8bf1eb --- /dev/null +++ b/python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstHeader.expected @@ -0,0 +1,6 @@ +edges +nodes +| TimingAttackAgainstHeader.py:14:12:14:46 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | +subpaths +#select +| TimingAttackAgainstHeader.py:14:12:14:46 | ControlFlowNode for Attribute() | TimingAttackAgainstHeader.py:14:12:14:46 | ControlFlowNode for Attribute() | TimingAttackAgainstHeader.py:14:12:14:46 | ControlFlowNode for Attribute() | Timing attack against $@ validation. | TimingAttackAgainstHeader.py:14:12:14:46 | ControlFlowNode for Attribute() | client-supplied token | diff --git a/python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstHeader.py b/python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstHeader.py new file mode 100644 index 00000000000..8c31aba39f8 --- /dev/null +++ b/python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstHeader.py @@ -0,0 +1,26 @@ +#!/usr/bin/env python +# -*- coding: UTF-8 -*- +""" +@Desc :Timing Attack Against Header +""" +from flask import Flask +from flask import request +from django.utils.crypto import constant_time_compare + +app = Flask(__name__) + +@app.route('/bad') +def bad1(): + if not request.headers.get('X-Auth-Token') == "key": + raise Exception('bad token') + return 'bad1' + +@app.route('/good') +def good1(): + if not constant_time_compare(Secret, "token"): + raise Exception('bad token') + return 'good1' + +if __name__ == '__main__': + app.debug = True + app.run() diff --git a/python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstHeader.qlref b/python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstHeader.qlref new file mode 100644 index 00000000000..086df8ab1bb --- /dev/null +++ b/python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstHeader.qlref @@ -0,0 +1 @@ +experimental/Security/CWE/CWE-208/TimingAttackAgainstHeader.ql diff --git a/python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstSensitiveInfo.expected b/python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstSensitiveInfo.expected new file mode 100644 index 00000000000..4dc0ff5843c --- /dev/null +++ b/python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstSensitiveInfo.expected @@ -0,0 +1,6 @@ +edges +nodes +| TimingAttackAgainstSensitiveInfo.py:15:16:15:23 | ControlFlowNode for password | semmle.label | ControlFlowNode for password | +subpaths +#select +| TimingAttackAgainstSensitiveInfo.py:15:16:15:23 | ControlFlowNode for password | TimingAttackAgainstSensitiveInfo.py:15:16:15:23 | ControlFlowNode for password | TimingAttackAgainstSensitiveInfo.py:15:16:15:23 | ControlFlowNode for password | Timing attack against $@ validation. | TimingAttackAgainstSensitiveInfo.py:15:16:15:23 | ControlFlowNode for password | client-supplied token | diff --git a/python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstSensitiveInfo.py b/python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstSensitiveInfo.py new file mode 100644 index 00000000000..6c5a1fa7c5f --- /dev/null +++ b/python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstSensitiveInfo.py @@ -0,0 +1,36 @@ +#!/usr/bin/env python +# -*- coding: UTF-8 -*- +""" +@Desc :timing attack against Secret +""" +from flask import Flask +from flask import request + +app = Flask(__name__) + +@app.route('/bad') +def check_credentials(): + if request.method == 'POST': + password = request.form['pwd'] + return password == "token" + +@app.route('/good') +def check_credentials(password): + if request.method == 'POST': + password = request.form['pwd'] + return constant_time_string_compare(password, "token") + +def constant_time_string_compare(a, b): + if len(a) != len(b): + return False + + result = 0 + + for x, y in zip(a, b): + result |= ord(x) ^ ord(y) + + return result == 0 + +if __name__ == '__main__': + app.debug = True + app.run() diff --git a/python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstSensitiveInfo.qlref b/python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstSensitiveInfo.qlref new file mode 100644 index 00000000000..c6d983ebaf5 --- /dev/null +++ b/python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstSensitiveInfo.qlref @@ -0,0 +1 @@ +experimental/Security/CWE/CWE-208/TimingAttackAgainstSensitiveInfo.ql diff --git a/python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstSignature.py b/python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstSignature.py new file mode 100644 index 00000000000..d18b7055173 --- /dev/null +++ b/python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstSignature.py @@ -0,0 +1,19 @@ +#!/usr/bin/env python +# -*- coding: UTF-8 -*- +""" +@Desc :Timing Attack Against Signature +""" +import hashlib +import hmac +from django.utils.crypto import constant_time_compare + +key = "e179017a-62b0-4996-8a38-e91aa9f1" + +def sign(pre_key, msg, alg): + return hmac.new(pre_key, msg, alg).digest() + +def verify1(msg, sig): + return constant_time_string_compare(sig, sign(key, msg, hashlib.sha256)) #good + +def verify2(msg, sig): + return sig == sign(key, msg, hashlib.sha256) #bad From acbb4042df204342a02c2fb1706a513c07cfcffd Mon Sep 17 00:00:00 2001 From: Ahmed Farid Date: Wed, 29 Jun 2022 00:51:12 +0100 Subject: [PATCH 002/631] Update TimingAttack.qhelp --- python/ql/src/experimental/Security/CWE-208/TimingAttack.qhelp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/python/ql/src/experimental/Security/CWE-208/TimingAttack.qhelp b/python/ql/src/experimental/Security/CWE-208/TimingAttack.qhelp index e048ec6b3b9..cc0c391ca18 100644 --- a/python/ql/src/experimental/Security/CWE-208/TimingAttack.qhelp +++ b/python/ql/src/experimental/Security/CWE-208/TimingAttack.qhelp @@ -7,8 +7,7 @@ how long it takes the system to respond to different inputs. it can be circumvented by using a constant-time algorithm for checking the value of sensitive info, more precisely, the comparison time should not depend on the content of the input. Otherwise the attacker gains -information that is indirectly leaked by the application. This information is then used for malicious purposes, -such as guessing the password of a user. +information that is indirectly leaked by the application. This information is then used for malicious purposes.

    From 5742046edffc1971c957674b9c30db0671656c4a Mon Sep 17 00:00:00 2001 From: Ahmed Farid Date: Wed, 29 Jun 2022 00:51:51 +0100 Subject: [PATCH 003/631] Update PossibleTimingAttackAgainstSignature.ql --- .../Security/CWE-208/PossibleTimingAttackAgainstSignature.ql | 1 - 1 file changed, 1 deletion(-) diff --git a/python/ql/src/experimental/Security/CWE-208/PossibleTimingAttackAgainstSignature.ql b/python/ql/src/experimental/Security/CWE-208/PossibleTimingAttackAgainstSignature.ql index 1d84d2c1179..5a86ca3ebea 100644 --- a/python/ql/src/experimental/Security/CWE-208/PossibleTimingAttackAgainstSignature.ql +++ b/python/ql/src/experimental/Security/CWE-208/PossibleTimingAttackAgainstSignature.ql @@ -52,4 +52,3 @@ from PossibleTimingAttackAgainstSignature config, DataFlow::PathNode source, Dat where config.hasFlowPath(source, sink) select sink.getNode(), source, sink, "Possible Timing attack against $@ validation.", source, source.getNode() - From e20fefc3ad00236a9cf8affea442fd5308de92a3 Mon Sep 17 00:00:00 2001 From: Ahmed Farid Date: Wed, 29 Jun 2022 00:54:03 +0100 Subject: [PATCH 004/631] Update TimingAttackAgainstHeader.ql --- .../experimental/Security/CWE-208/TimingAttackAgainstHeader.ql | 1 - 1 file changed, 1 deletion(-) diff --git a/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHeader.ql b/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHeader.ql index 1c28a239343..f51b6acdf80 100644 --- a/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHeader.ql +++ b/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHeader.ql @@ -31,4 +31,3 @@ from ClientSuppliedSecretConfig config, DataFlow::PathNode source, DataFlow::Pat where config.hasFlowPath(source, sink) select sink.getNode(), source, sink, "Timing attack against $@ validation.", source.getNode(), "client-supplied token" - From 41b4c06f2d2e82e47974d2412e529d8b5766c0a1 Mon Sep 17 00:00:00 2001 From: Ahmed Farid Date: Wed, 29 Jun 2022 00:54:44 +0100 Subject: [PATCH 005/631] Update TimingAttackAgainstSignature.ql --- .../Security/CWE-208/TimingAttackAgainstSignature.ql | 1 - 1 file changed, 1 deletion(-) diff --git a/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstSignature.ql b/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstSignature.ql index 7616c1e734f..a7ce928e36e 100644 --- a/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstSignature.ql +++ b/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstSignature.ql @@ -35,4 +35,3 @@ from TimingAttackAgainstsignature config, DataFlow::PathNode source, DataFlow::P where config.hasFlowPath(source, sink) select sink.getNode(), source, sink, "Timing attack against $@ validation.", source, source.getNode() - From 98909c206985185f06e298a44fe98ddea886f8f6 Mon Sep 17 00:00:00 2001 From: Ahmed Farid Date: Wed, 29 Jun 2022 00:55:21 +0100 Subject: [PATCH 006/631] Update TimingAttackAgainstSensitiveInfo.ql --- .../Security/CWE-208/TimingAttackAgainstSensitiveInfo.ql | 1 - 1 file changed, 1 deletion(-) diff --git a/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstSensitiveInfo.ql b/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstSensitiveInfo.ql index 7640e2474b0..04fff48479d 100644 --- a/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstSensitiveInfo.ql +++ b/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstSensitiveInfo.ql @@ -31,4 +31,3 @@ from ClientSuppliedSecretConfig config, DataFlow::PathNode source, DataFlow::Pat where config.hasFlowPath(source, sink) select sink.getNode(), source, sink, "Timing attack against $@ validation.", source.getNode(), "client-supplied token" - From f5d0791b4f61fe6151e01a2c5fd46a1a0b7118bf Mon Sep 17 00:00:00 2001 From: Ahmed Farid Date: Wed, 29 Jun 2022 00:56:15 +0100 Subject: [PATCH 007/631] Update TimingAttack.qll --- python/ql/src/experimental/Security/CWE-208/TimingAttack.qll | 1 - 1 file changed, 1 deletion(-) diff --git a/python/ql/src/experimental/Security/CWE-208/TimingAttack.qll b/python/ql/src/experimental/Security/CWE-208/TimingAttack.qll index 6dddbb56fd3..7e3923def0d 100644 --- a/python/ql/src/experimental/Security/CWE-208/TimingAttack.qll +++ b/python/ql/src/experimental/Security/CWE-208/TimingAttack.qll @@ -165,4 +165,3 @@ class UserInputInComparisonConfig extends TaintTracking3::Configuration { override predicate isSink(DataFlow::Node sink) { sink instanceof CompareSink } } - From ec363166bad3830a7b7d47151a680c7a3f6932af Mon Sep 17 00:00:00 2001 From: Taus Date: Mon, 11 Jul 2022 15:24:31 +0200 Subject: [PATCH 008/631] Python: Make `UserInputMsgConfig` public --- python/ql/src/experimental/Security/CWE-208/TimingAttack.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/ql/src/experimental/Security/CWE-208/TimingAttack.qll b/python/ql/src/experimental/Security/CWE-208/TimingAttack.qll index 7e3923def0d..c943daf15c6 100644 --- a/python/ql/src/experimental/Security/CWE-208/TimingAttack.qll +++ b/python/ql/src/experimental/Security/CWE-208/TimingAttack.qll @@ -120,7 +120,7 @@ private string sensitiveheaders() { /** * A config that tracks data flow from remote user input to cryptographic operations */ -private class UserInputMsgConfig extends TaintTracking::Configuration { +class UserInputMsgConfig extends TaintTracking::Configuration { UserInputMsgConfig() { this = "UserInputMsgConfig" } override predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource } From f4654136d63a06ec3ec7e3c6ec674606a18b1416 Mon Sep 17 00:00:00 2001 From: Ahmed Farid Date: Thu, 14 Jul 2022 17:56:13 +0100 Subject: [PATCH 009/631] Update TimingAttack.qhelp --- .../ql/src/experimental/Security/CWE-208/TimingAttack.qhelp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/python/ql/src/experimental/Security/CWE-208/TimingAttack.qhelp b/python/ql/src/experimental/Security/CWE-208/TimingAttack.qhelp index cc0c391ca18..96fe0aca9b5 100644 --- a/python/ql/src/experimental/Security/CWE-208/TimingAttack.qhelp +++ b/python/ql/src/experimental/Security/CWE-208/TimingAttack.qhelp @@ -46,6 +46,10 @@ and does not depend on the contents of the arrays.
  • hmac.compare_digest() method
  • + +
  • + RFC 2104 +
  • From 7406273346be94a03ade12dc1b7c8ff91f1bece4 Mon Sep 17 00:00:00 2001 From: Ahmed Farid Date: Thu, 14 Jul 2022 17:56:58 +0100 Subject: [PATCH 010/631] Update TimingAttack.qhelp --- python/ql/src/experimental/Security/CWE-208/TimingAttack.qhelp | 1 + 1 file changed, 1 insertion(+) diff --git a/python/ql/src/experimental/Security/CWE-208/TimingAttack.qhelp b/python/ql/src/experimental/Security/CWE-208/TimingAttack.qhelp index 96fe0aca9b5..f684894a8ce 100644 --- a/python/ql/src/experimental/Security/CWE-208/TimingAttack.qhelp +++ b/python/ql/src/experimental/Security/CWE-208/TimingAttack.qhelp @@ -48,6 +48,7 @@ and does not depend on the contents of the arrays.
  • + HMAC: RFC 2104
  • From bfce1898b9905759e706190d0b4e060d9ad47b75 Mon Sep 17 00:00:00 2001 From: Ahmed Farid Date: Wed, 20 Jul 2022 00:49:09 +0100 Subject: [PATCH 011/631] Update and rename PossibleTimingAttackAgainstSignature.ql to PossibleTimingAttackAgainstHash.ql --- ...AgainstSignature.ql => PossibleTimingAttackAgainstHash.ql} | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) rename python/ql/src/experimental/Security/CWE-208/{PossibleTimingAttackAgainstSignature.ql => PossibleTimingAttackAgainstHash.ql} (91%) diff --git a/python/ql/src/experimental/Security/CWE-208/PossibleTimingAttackAgainstSignature.ql b/python/ql/src/experimental/Security/CWE-208/PossibleTimingAttackAgainstHash.ql similarity index 91% rename from python/ql/src/experimental/Security/CWE-208/PossibleTimingAttackAgainstSignature.ql rename to python/ql/src/experimental/Security/CWE-208/PossibleTimingAttackAgainstHash.ql index 5a86ca3ebea..1e3302b8d1e 100644 --- a/python/ql/src/experimental/Security/CWE-208/PossibleTimingAttackAgainstSignature.ql +++ b/python/ql/src/experimental/Security/CWE-208/PossibleTimingAttackAgainstHash.ql @@ -24,8 +24,8 @@ import DataFlow::PathGraph * A configuration that tracks data flow from cryptographic operations * to equality test */ -class PossibleTimingAttackAgainstSignature extends TaintTracking::Configuration { - PossibleTimingAttackAgainstSignature() { this = "PossibleTimingAttackAgainstSignature" } +class PossibleTimingAttackAgainstHash extends TaintTracking::Configuration { + PossibleTimingAttackAgainstHash() { this = "PossibleTimingAttackAgainstHash" } override predicate isSource(DataFlow::Node source) { source = API::moduleImport("hmac").getMember("digest").getACall() or From 27d81548a70381813b89e6aa4c0e4462547d878b Mon Sep 17 00:00:00 2001 From: Ahmed Farid Date: Wed, 20 Jul 2022 00:55:22 +0100 Subject: [PATCH 012/631] Update PossibleTimingAttackAgainstHash.ql --- .../CWE-208/PossibleTimingAttackAgainstHash.ql | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/python/ql/src/experimental/Security/CWE-208/PossibleTimingAttackAgainstHash.ql b/python/ql/src/experimental/Security/CWE-208/PossibleTimingAttackAgainstHash.ql index 1e3302b8d1e..017b45d37b6 100644 --- a/python/ql/src/experimental/Security/CWE-208/PossibleTimingAttackAgainstHash.ql +++ b/python/ql/src/experimental/Security/CWE-208/PossibleTimingAttackAgainstHash.ql @@ -1,14 +1,13 @@ /** - * @name Timing attack against digest validation - * @description When checking a signature over a message, a constant-time algorithm should be used. - * Otherwise, an attacker may be able to forge a valid digest for an arbitrary message - * by running a timing attack if they can send to the validation procedure - * both the message and the signature. + * @name Timing attack against Hash + * @description When checking a Hash over a message, a constant-time algorithm should be used. + * Otherwise, an attacker may be able to forge a valid Hash for an arbitrary message + * by running a timing attack if they can send to the validation procedure. * A successful attack can result in authentication bypass. * @kind path-problem * @problem.severity error * @precision high - * @id py/timing-attack-against-signature + * @id py/timing-attack-against-Hash * @tags security * external/cwe/cwe-208 */ @@ -48,7 +47,7 @@ class PossibleTimingAttackAgainstHash extends TaintTracking::Configuration { override predicate isSink(DataFlow::Node sink) { sink instanceof CompareSink } } -from PossibleTimingAttackAgainstSignature config, DataFlow::PathNode source, DataFlow::PathNode sink +from PossibleTimingAttackAgainstHash config, DataFlow::PathNode source, DataFlow::PathNode sink where config.hasFlowPath(source, sink) select sink.getNode(), source, sink, "Possible Timing attack against $@ validation.", source, source.getNode() From 3d092f9569e1eae24ad4396236fbd84eed653fdd Mon Sep 17 00:00:00 2001 From: Ahmed Farid Date: Wed, 20 Jul 2022 00:56:52 +0100 Subject: [PATCH 013/631] Update TimingAttackAgainstSignature.ql --- .../CWE-208/TimingAttackAgainstSignature.ql | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstSignature.ql b/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstSignature.ql index a7ce928e36e..3a18a088643 100644 --- a/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstSignature.ql +++ b/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstSignature.ql @@ -1,14 +1,13 @@ /** - * @name Timing attack against digest validation - * @description When checking a signature over a message, a constant-time algorithm should be used. - * Otherwise, an attacker may be able to forge a valid digest for an arbitrary message - * by running a timing attack if they can send to the validation procedure - * both the message and the signature. + * @name Timing attack against Hash + * @description When checking a Hash over a message, a constant-time algorithm should be used. + * Otherwise, an attacker may be able to forge a valid Hash for an arbitrary message + * by running a timing attack if they can send to the validation procedure. * A successful attack can result in authentication bypass. * @kind path-problem * @problem.severity error * @precision high - * @id py/timing-attack-against-signature + * @id py/timing-attack-against-hash * @tags security * external/cwe/cwe-208 */ @@ -23,15 +22,15 @@ import DataFlow::PathGraph * A configuration that tracks data flow from cryptographic operations * to Equality test. */ -class TimingAttackAgainstsignature extends TaintTracking::Configuration { - TimingAttackAgainstsignature() { this = "TimingAttackAgainstsignature" } +class TimingAttackAgainsthash extends TaintTracking::Configuration { + TimingAttackAgainsthash() { this = "TimingAttackAgainsthash" } override predicate isSource(DataFlow::Node source) { source instanceof UserInputMsgConfig } override predicate isSink(DataFlow::Node sink) { sink instanceof UserInputInComparisonConfig } } -from TimingAttackAgainstsignature config, DataFlow::PathNode source, DataFlow::PathNode sink +from TimingAttackAgainsthash config, DataFlow::PathNode source, DataFlow::PathNode sink where config.hasFlowPath(source, sink) select sink.getNode(), source, sink, "Timing attack against $@ validation.", source, source.getNode() From b3925ae9880eeabb17e76ef151541e2e0b9e51a3 Mon Sep 17 00:00:00 2001 From: Ahmed Farid Date: Wed, 20 Jul 2022 00:57:26 +0100 Subject: [PATCH 014/631] Update PossibleTimingAttackAgainstSignature.qlref --- .../Security/CWE-208/PossibleTimingAttackAgainstSignature.qlref | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/ql/test/experimental/query-tests/Security/CWE-208/PossibleTimingAttackAgainstSignature.qlref b/python/ql/test/experimental/query-tests/Security/CWE-208/PossibleTimingAttackAgainstSignature.qlref index 3a113b0fd71..11452a116c9 100644 --- a/python/ql/test/experimental/query-tests/Security/CWE-208/PossibleTimingAttackAgainstSignature.qlref +++ b/python/ql/test/experimental/query-tests/Security/CWE-208/PossibleTimingAttackAgainstSignature.qlref @@ -1 +1 @@ -experimental/Security/CWE/CWE-208/PossibleTimingAttackAgainstSignature.ql +experimental/Security/CWE/CWE-208/PossibleTimingAttackAgainstHash.ql From 4f082e28e5c690d152454128e14ffddc4445f3cf Mon Sep 17 00:00:00 2001 From: Ahmed Farid Date: Wed, 20 Jul 2022 12:26:57 +0100 Subject: [PATCH 015/631] Update and rename TimingAttackAgainstSignature.py to TimingAttackAgainstHash.py --- ...mingAttackAgainstSignature.py => TimingAttackAgainstHash.py} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename python/ql/test/experimental/query-tests/Security/CWE-208/{TimingAttackAgainstSignature.py => TimingAttackAgainstHash.py} (91%) diff --git a/python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstSignature.py b/python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstHash.py similarity index 91% rename from python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstSignature.py rename to python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstHash.py index d18b7055173..8d2c331d03c 100644 --- a/python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstSignature.py +++ b/python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstHash.py @@ -1,7 +1,7 @@ #!/usr/bin/env python # -*- coding: UTF-8 -*- """ -@Desc :Timing Attack Against Signature +@Desc :Timing Attack Against Hash """ import hashlib import hmac From e7742bd87c72eea72663102b1ba271a3617ea1cc Mon Sep 17 00:00:00 2001 From: Ahmed Farid Date: Wed, 20 Jul 2022 12:58:13 +0100 Subject: [PATCH 016/631] Create CryptographicOperation.qll Provides models for Python's Cryptography-related libraries --- .../frameworks/CryptographicOperation.qll | 73 +++++++++++++++++++ 1 file changed, 73 insertions(+) create mode 100644 python/ql/src/experimental/semmle/python/frameworks/CryptographicOperation.qll diff --git a/python/ql/src/experimental/semmle/python/frameworks/CryptographicOperation.qll b/python/ql/src/experimental/semmle/python/frameworks/CryptographicOperation.qll new file mode 100644 index 00000000000..a948a1582da --- /dev/null +++ b/python/ql/src/experimental/semmle/python/frameworks/CryptographicOperation.qll @@ -0,0 +1,73 @@ +private import python +private import semmle.python.dataflow.new.DataFlow +private import experimental.semmle.python.Concepts +private import semmle.python.ApiGraphs + +/** + * Provides models for Python's Cryptography-related libraries. + */ +private module Cryptographyimpl { + private string hashName() { + result = ["sha1", "sha224", "sha256", "sha384", "sha512", "blake2b", "blake2s", "md5"] + } + + /** Gets a reference to the `hmac` module. */ + API::Node hmac() { result = API::moduleImport("hmac") } + + /** Gets a reference to the `hashlib` module. */ + API::Node hashlib() { result = API::moduleImport("hashlib") } + + /** + * A hashing operation by supplying initial data when calling the `hmac.new` function. + */ + private class HmaclibNewCall extends DataFlow::CallCfgNode, CryptographicOperation::Range { + HmaclibNewCall() { this = hmac().getMember("new").getACall() } + + override DataFlow::Node getAnInput() { + result in [this.getArg(1), this.getArgByName("msg")] + } + } + + /** + * A hashing operation by supplying initial data when calling the prdifined functions in `hashlib` package (such as `hashlib.md5`) + */ + private class HashlibHashCall extends DataFlow::CallCfgNode, CryptographicOperation::Range { + HashlibHashCall() { + this = hashlib().getMember(hashName()).getACall() + } + + override DataFlow::Node getAnInput() { result = this.getArg(0) } + } + + /** + * A hashing operation by supplying initial data when calling the `hashlib.new` function. + */ + private class HashlibNewCall extends DataFlow::CallCfgNode, CryptographicOperation::Range { + HashlibNewCall() { + this = hashlib().getMember("new").getACall() + } + + override DataFlow::Node getAnInput() { + result in [this.getArg(1), this.getArgByName("data")] + } + } + + /** + * A hashing operation from the `hashlib` package using one of the predefined classes + * (such as `hashlib.md5` or `hashlib.new`), by calling its' `update` mehtod. + */ + private class HashlibHashClassUpdateCall extends DataFlow::CallCfgNode, CryptographicOperation::Range { + HashlibHashClassUpdateCall() { this = hashlib().getMember([hashName(), "new"]).getReturn().getMember("update").getACall() } + + override DataFlow::Node getAnInput() { result = this.getArg(0) } + } + + /** + * A hashing operation from the `hmac` package using `hmac.new` class, by calling its' `update` mehtod. + */ + private class HmaclibNewUpdateCall extends DataFlow::CallCfgNode, CryptographicOperation::Range { + HmaclibNewUpdateCall() { this = hmac().getMember("new").getReturn().getMember("update").getACall() } + + override DataFlow::Node getAnInput() { result = this.getArg(0) } + } +} From 238d3250c3e3bc6d77e57e0f20f7ef5982474256 Mon Sep 17 00:00:00 2001 From: Ahmed Farid Date: Wed, 20 Jul 2022 13:00:30 +0100 Subject: [PATCH 017/631] Update Concepts.qll --- .../experimental/semmle/python/Concepts.qll | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/python/ql/src/experimental/semmle/python/Concepts.qll b/python/ql/src/experimental/semmle/python/Concepts.qll index 433d89dbad1..3962ea3f28f 100644 --- a/python/ql/src/experimental/semmle/python/Concepts.qll +++ b/python/ql/src/experimental/semmle/python/Concepts.qll @@ -15,6 +15,36 @@ private import semmle.python.dataflow.new.TaintTracking private import experimental.semmle.python.Frameworks private import semmle.python.Concepts +/** Provides classes for modeling cryptography operation related APIs. */ +module CryptographicOperation { + /** + * A data-flow node that collects methods taking input. + * + * Extend this class to model new APIs. If you want to refine existing API models, + * extend `CryptographicOperation` instead. + */ + abstract class Range extends DataFlow::Node { + /** + * Gets the argument containing the data. + */ + abstract DataFlow::Node getAnInput(); + } +} + +/** + * A data flow node for cryptography operation. + * + * Extend this class to refine existing API models. If you want to model new APIs, + * extend `CryptographicOperation::Range` instead. + */ +class CryptographicOperation extends DataFlow::Node { + CryptographicOperation::Range range; + + CryptographicOperation() { this = range } + + DataFlow::Node getAnInput() { result = range.getAnInput() } +} + /** Provides classes for modeling copying file related APIs. */ module CopyFile { /** From ee743e61e9e3e3534f20698fd59e04a1c85e6be1 Mon Sep 17 00:00:00 2001 From: Ahmed Farid Date: Wed, 20 Jul 2022 13:03:55 +0100 Subject: [PATCH 018/631] Update TimingAttack.qll --- .../Security/CWE-208/TimingAttack.qll | 37 +++++++++++-------- 1 file changed, 22 insertions(+), 15 deletions(-) diff --git a/python/ql/src/experimental/Security/CWE-208/TimingAttack.qll b/python/ql/src/experimental/Security/CWE-208/TimingAttack.qll index c943daf15c6..e014ae1ebe7 100644 --- a/python/ql/src/experimental/Security/CWE-208/TimingAttack.qll +++ b/python/ql/src/experimental/Security/CWE-208/TimingAttack.qll @@ -5,6 +5,27 @@ private import semmle.python.dataflow.new.TaintTracking3 private import semmle.python.ApiGraphs private import semmle.python.dataflow.new.RemoteFlowSources +class ProduceHashCall extends DataFlow::CallCfgNode { + ProduceHashCall() { + this = API::moduleImport("hmac").getMember("digest").getACall() or + this = + API::moduleImport("hmac") + .getMember("new") + .getReturn() + .getMember(["digest", "hexdigest"]) + .getACall() or + this = + API::moduleImport("hashlib") + .getMember([ + "new", "sha1", "sha224", "sha256", "sha384", "sha512", "blake2b", "blake2s", "md5" + ]) + .getReturn() + .getMember(["digest", "hexdigest"]) + .getACall() + } + +} + /** A data flow sink for comparison. */ class CompareSink extends DataFlow::Node { CompareSink() { @@ -126,21 +147,7 @@ class UserInputMsgConfig extends TaintTracking::Configuration { override predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource } override predicate isSink(DataFlow::Node sink) { - sink = API::moduleImport("hmac").getMember("digest").getACall() or - sink = - API::moduleImport("hmac") - .getMember("new") - .getReturn() - .getMember(["digest", "hexdigest"]) - .getACall() or - sink = - API::moduleImport("hashlib") - .getMember([ - "new", "sha1", "sha224", "sha256", "sha384", "sha512", "blake2b", "blake2s", "md5" - ]) - .getReturn() - .getMember(["digest", "hexdigest"]) - .getACall() + sink = any(CryptographicOperation cryptography).getAnInput() } } From 7d0d39e019a2d8967aba630850a680d240dbd5d2 Mon Sep 17 00:00:00 2001 From: Ahmed Farid Date: Wed, 20 Jul 2022 13:05:49 +0100 Subject: [PATCH 019/631] Update PossibleTimingAttackAgainstHash.ql --- .../CWE-208/PossibleTimingAttackAgainstHash.ql | 18 +----------------- 1 file changed, 1 insertion(+), 17 deletions(-) diff --git a/python/ql/src/experimental/Security/CWE-208/PossibleTimingAttackAgainstHash.ql b/python/ql/src/experimental/Security/CWE-208/PossibleTimingAttackAgainstHash.ql index 017b45d37b6..1ba71b7ee87 100644 --- a/python/ql/src/experimental/Security/CWE-208/PossibleTimingAttackAgainstHash.ql +++ b/python/ql/src/experimental/Security/CWE-208/PossibleTimingAttackAgainstHash.ql @@ -26,23 +26,7 @@ import DataFlow::PathGraph class PossibleTimingAttackAgainstHash extends TaintTracking::Configuration { PossibleTimingAttackAgainstHash() { this = "PossibleTimingAttackAgainstHash" } - override predicate isSource(DataFlow::Node source) { - source = API::moduleImport("hmac").getMember("digest").getACall() or - source = - API::moduleImport("hmac") - .getMember("new") - .getReturn() - .getMember(["digest", "hexdigest"]) - .getACall() or - source = - API::moduleImport("hashlib") - .getMember([ - "new", "sha1", "sha224", "sha256", "sha384", "sha512", "blake2b", "blake2s", "md5" - ]) - .getReturn() - .getMember(["digest", "hexdigest"]) - .getACall() - } + override predicate isSource(DataFlow::Node source) { source instanceof ProduceHashCall } override predicate isSink(DataFlow::Node sink) { sink instanceof CompareSink } } From 687179079387258f6f168017e7184602e18d8483 Mon Sep 17 00:00:00 2001 From: Ahmed Farid Date: Wed, 20 Jul 2022 13:07:14 +0100 Subject: [PATCH 020/631] Rename TimingAttackAgainstSignature.ql to TimingAttackAgainstHash.ql --- ...TimingAttackAgainstSignature.ql => TimingAttackAgainstHash.ql} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename python/ql/src/experimental/Security/CWE-208/{TimingAttackAgainstSignature.ql => TimingAttackAgainstHash.ql} (100%) diff --git a/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstSignature.ql b/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHash.ql similarity index 100% rename from python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstSignature.ql rename to python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHash.ql From 6a782f47a9d8ef44153482c93e0afd6d15e58a3c Mon Sep 17 00:00:00 2001 From: Ahmed Farid Date: Wed, 20 Jul 2022 13:08:21 +0100 Subject: [PATCH 021/631] Update Frameworks.qll --- python/ql/src/experimental/semmle/python/Frameworks.qll | 1 + 1 file changed, 1 insertion(+) diff --git a/python/ql/src/experimental/semmle/python/Frameworks.qll b/python/ql/src/experimental/semmle/python/Frameworks.qll index 98fb86f6d92..69e7b83b34b 100644 --- a/python/ql/src/experimental/semmle/python/Frameworks.qll +++ b/python/ql/src/experimental/semmle/python/Frameworks.qll @@ -18,3 +18,4 @@ private import experimental.semmle.python.frameworks.CopyFile private import experimental.semmle.python.frameworks.Sendgrid private import experimental.semmle.python.libraries.FlaskMail private import experimental.semmle.python.libraries.SmtpLib +private import experimental.semmle.python.frameworks.CryptographicOperation From fd558604cce38da0b95e4a70b50df0cddcb2baf8 Mon Sep 17 00:00:00 2001 From: Ahmed Farid Date: Thu, 21 Jul 2022 18:48:07 +0100 Subject: [PATCH 022/631] Update TimingAttack.qll --- python/ql/src/experimental/Security/CWE-208/TimingAttack.qll | 1 + 1 file changed, 1 insertion(+) diff --git a/python/ql/src/experimental/Security/CWE-208/TimingAttack.qll b/python/ql/src/experimental/Security/CWE-208/TimingAttack.qll index e014ae1ebe7..35c04ebf20e 100644 --- a/python/ql/src/experimental/Security/CWE-208/TimingAttack.qll +++ b/python/ql/src/experimental/Security/CWE-208/TimingAttack.qll @@ -4,6 +4,7 @@ private import semmle.python.dataflow.new.TaintTracking2 private import semmle.python.dataflow.new.TaintTracking3 private import semmle.python.ApiGraphs private import semmle.python.dataflow.new.RemoteFlowSources +private import experimental.semmle.python.Concepts class ProduceHashCall extends DataFlow::CallCfgNode { ProduceHashCall() { From 2f72cc5ca8f57c78463d0b9cec90f7e00a87cb32 Mon Sep 17 00:00:00 2001 From: Ahmed Farid Date: Fri, 22 Jul 2022 03:28:32 +0100 Subject: [PATCH 023/631] Update PossibleTimingAttackAgainstHash.ql --- .../Security/CWE-208/PossibleTimingAttackAgainstHash.ql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/ql/src/experimental/Security/CWE-208/PossibleTimingAttackAgainstHash.ql b/python/ql/src/experimental/Security/CWE-208/PossibleTimingAttackAgainstHash.ql index 1ba71b7ee87..a3cc78342ce 100644 --- a/python/ql/src/experimental/Security/CWE-208/PossibleTimingAttackAgainstHash.ql +++ b/python/ql/src/experimental/Security/CWE-208/PossibleTimingAttackAgainstHash.ql @@ -6,7 +6,7 @@ * A successful attack can result in authentication bypass. * @kind path-problem * @problem.severity error - * @precision high + * @precision medium * @id py/timing-attack-against-Hash * @tags security * external/cwe/cwe-208 From 656e8cf44ea31adbe5a62041e17811e8e62cc2be Mon Sep 17 00:00:00 2001 From: Ahmed Farid Date: Tue, 26 Jul 2022 15:13:32 +0100 Subject: [PATCH 024/631] Delete CryptographicOperation.qll --- .../frameworks/CryptographicOperation.qll | 73 ------------------- 1 file changed, 73 deletions(-) delete mode 100644 python/ql/src/experimental/semmle/python/frameworks/CryptographicOperation.qll diff --git a/python/ql/src/experimental/semmle/python/frameworks/CryptographicOperation.qll b/python/ql/src/experimental/semmle/python/frameworks/CryptographicOperation.qll deleted file mode 100644 index a948a1582da..00000000000 --- a/python/ql/src/experimental/semmle/python/frameworks/CryptographicOperation.qll +++ /dev/null @@ -1,73 +0,0 @@ -private import python -private import semmle.python.dataflow.new.DataFlow -private import experimental.semmle.python.Concepts -private import semmle.python.ApiGraphs - -/** - * Provides models for Python's Cryptography-related libraries. - */ -private module Cryptographyimpl { - private string hashName() { - result = ["sha1", "sha224", "sha256", "sha384", "sha512", "blake2b", "blake2s", "md5"] - } - - /** Gets a reference to the `hmac` module. */ - API::Node hmac() { result = API::moduleImport("hmac") } - - /** Gets a reference to the `hashlib` module. */ - API::Node hashlib() { result = API::moduleImport("hashlib") } - - /** - * A hashing operation by supplying initial data when calling the `hmac.new` function. - */ - private class HmaclibNewCall extends DataFlow::CallCfgNode, CryptographicOperation::Range { - HmaclibNewCall() { this = hmac().getMember("new").getACall() } - - override DataFlow::Node getAnInput() { - result in [this.getArg(1), this.getArgByName("msg")] - } - } - - /** - * A hashing operation by supplying initial data when calling the prdifined functions in `hashlib` package (such as `hashlib.md5`) - */ - private class HashlibHashCall extends DataFlow::CallCfgNode, CryptographicOperation::Range { - HashlibHashCall() { - this = hashlib().getMember(hashName()).getACall() - } - - override DataFlow::Node getAnInput() { result = this.getArg(0) } - } - - /** - * A hashing operation by supplying initial data when calling the `hashlib.new` function. - */ - private class HashlibNewCall extends DataFlow::CallCfgNode, CryptographicOperation::Range { - HashlibNewCall() { - this = hashlib().getMember("new").getACall() - } - - override DataFlow::Node getAnInput() { - result in [this.getArg(1), this.getArgByName("data")] - } - } - - /** - * A hashing operation from the `hashlib` package using one of the predefined classes - * (such as `hashlib.md5` or `hashlib.new`), by calling its' `update` mehtod. - */ - private class HashlibHashClassUpdateCall extends DataFlow::CallCfgNode, CryptographicOperation::Range { - HashlibHashClassUpdateCall() { this = hashlib().getMember([hashName(), "new"]).getReturn().getMember("update").getACall() } - - override DataFlow::Node getAnInput() { result = this.getArg(0) } - } - - /** - * A hashing operation from the `hmac` package using `hmac.new` class, by calling its' `update` mehtod. - */ - private class HmaclibNewUpdateCall extends DataFlow::CallCfgNode, CryptographicOperation::Range { - HmaclibNewUpdateCall() { this = hmac().getMember("new").getReturn().getMember("update").getACall() } - - override DataFlow::Node getAnInput() { result = this.getArg(0) } - } -} From e6dd21a57dbb899ea993eb234d6d6ce5439abfcd Mon Sep 17 00:00:00 2001 From: Ahmed Farid Date: Tue, 26 Jul 2022 15:14:02 +0100 Subject: [PATCH 025/631] Update Frameworks.qll --- python/ql/src/experimental/semmle/python/Frameworks.qll | 1 - 1 file changed, 1 deletion(-) diff --git a/python/ql/src/experimental/semmle/python/Frameworks.qll b/python/ql/src/experimental/semmle/python/Frameworks.qll index 69e7b83b34b..98fb86f6d92 100644 --- a/python/ql/src/experimental/semmle/python/Frameworks.qll +++ b/python/ql/src/experimental/semmle/python/Frameworks.qll @@ -18,4 +18,3 @@ private import experimental.semmle.python.frameworks.CopyFile private import experimental.semmle.python.frameworks.Sendgrid private import experimental.semmle.python.libraries.FlaskMail private import experimental.semmle.python.libraries.SmtpLib -private import experimental.semmle.python.frameworks.CryptographicOperation From c98af44df847c6b928b93786f58c13db997c1a01 Mon Sep 17 00:00:00 2001 From: Ahmed Farid Date: Tue, 26 Jul 2022 15:15:06 +0100 Subject: [PATCH 026/631] Update Concepts.qll --- .../experimental/semmle/python/Concepts.qll | 30 ------------------- 1 file changed, 30 deletions(-) diff --git a/python/ql/src/experimental/semmle/python/Concepts.qll b/python/ql/src/experimental/semmle/python/Concepts.qll index 3962ea3f28f..433d89dbad1 100644 --- a/python/ql/src/experimental/semmle/python/Concepts.qll +++ b/python/ql/src/experimental/semmle/python/Concepts.qll @@ -15,36 +15,6 @@ private import semmle.python.dataflow.new.TaintTracking private import experimental.semmle.python.Frameworks private import semmle.python.Concepts -/** Provides classes for modeling cryptography operation related APIs. */ -module CryptographicOperation { - /** - * A data-flow node that collects methods taking input. - * - * Extend this class to model new APIs. If you want to refine existing API models, - * extend `CryptographicOperation` instead. - */ - abstract class Range extends DataFlow::Node { - /** - * Gets the argument containing the data. - */ - abstract DataFlow::Node getAnInput(); - } -} - -/** - * A data flow node for cryptography operation. - * - * Extend this class to refine existing API models. If you want to model new APIs, - * extend `CryptographicOperation::Range` instead. - */ -class CryptographicOperation extends DataFlow::Node { - CryptographicOperation::Range range; - - CryptographicOperation() { this = range } - - DataFlow::Node getAnInput() { result = range.getAnInput() } -} - /** Provides classes for modeling copying file related APIs. */ module CopyFile { /** From dc89773fe83d2819d5b7520b5cafe21fc16ea408 Mon Sep 17 00:00:00 2001 From: Ahmed Farid Date: Tue, 26 Jul 2022 15:30:31 +0100 Subject: [PATCH 027/631] Update TimingAttack.qll --- .../Security/CWE-208/TimingAttack.qll | 68 +++++++++++++------ 1 file changed, 48 insertions(+), 20 deletions(-) diff --git a/python/ql/src/experimental/Security/CWE-208/TimingAttack.qll b/python/ql/src/experimental/Security/CWE-208/TimingAttack.qll index 35c04ebf20e..140db2c3cf6 100644 --- a/python/ql/src/experimental/Security/CWE-208/TimingAttack.qll +++ b/python/ql/src/experimental/Security/CWE-208/TimingAttack.qll @@ -2,10 +2,11 @@ private import python private import semmle.python.dataflow.new.TaintTracking private import semmle.python.dataflow.new.TaintTracking2 private import semmle.python.dataflow.new.TaintTracking3 +private import semmle.python.dataflow.new.DataFlow private import semmle.python.ApiGraphs private import semmle.python.dataflow.new.RemoteFlowSources -private import experimental.semmle.python.Concepts +/** A data flow source of the hash obtained */ class ProduceHashCall extends DataFlow::CallCfgNode { ProduceHashCall() { this = API::moduleImport("hmac").getMember("digest").getACall() or @@ -28,9 +29,8 @@ class ProduceHashCall extends DataFlow::CallCfgNode { } /** A data flow sink for comparison. */ -class CompareSink extends DataFlow::Node { - CompareSink() { - exists(Compare compare | +private predicate existsFailFastCheck(Expr firstInput, Expr secondInput) { + exists(Compare compare | ( compare.getOp(0) instanceof Eq or compare.getOp(0) instanceof NotEq or @@ -38,10 +38,45 @@ class CompareSink extends DataFlow::Node { compare.getOp(0) instanceof NotIn ) and ( - compare.getLeft() = this.asExpr() + compare.getLeft() = firstInput and + compare.getComparator(0) = secondInput or - compare.getComparator(0) = this.asExpr() + compare.getLeft() = secondInput and + compare.getComparator(0) = firstInput ) + ) +} + +/** A sink that compares input using fail fast check. */ +class NonConstantTimeComparisonOfHashSink extends DataFlow::Node { + Expr anotherParameter; + + NonConstantTimeComparisonOfHashSink() { + existsFailFastCheck(this.asExpr(), anotherParameter) and + not anotherParameter.isConstant() + } + + /** Holds if remote user input was used in the comparison. */ + predicate includesUserInput() { + exists(UserInputInComparisonConfig config | + config.hasFlowTo(DataFlow2::exprNode(anotherParameter)) + ) + } +} + +/** A sink that compares input using fail fast check. */ +class NonConstantTimeComparisonOfSecretSink extends DataFlow::Node { + Expr anotherParameter; + + NonConstantTimeComparisonOfSecretSink() { + existsFailFastCheck(this.asExpr(), anotherParameter) and + not anotherParameter.isConstant() + } + + /** Holds if remote user input was used in the comparison. */ + predicate includesUserInput() { + exists(UserInputSecretConfig config | + config.hasFlowTo(DataFlow2::exprNode(anotherParameter)) ) } } @@ -139,19 +174,6 @@ private string sensitiveheaders() { ] } -/** - * A config that tracks data flow from remote user input to cryptographic operations - */ -class UserInputMsgConfig extends TaintTracking::Configuration { - UserInputMsgConfig() { this = "UserInputMsgConfig" } - - override predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource } - - override predicate isSink(DataFlow::Node sink) { - sink = any(CryptographicOperation cryptography).getAnInput() - } -} - /** * A config that tracks data flow from remote user input to Variable that hold sensitive info */ @@ -171,5 +193,11 @@ class UserInputInComparisonConfig extends TaintTracking3::Configuration { override predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource } - override predicate isSink(DataFlow::Node sink) { sink instanceof CompareSink } + override predicate isSink(DataFlow::Node sink) { + exists(Compare cmp, Expr left, Expr right, Cmpop cmpop | + cmpop.getSymbol() = ["==", "in", "is not", "!="] and + cmp.compares(left, cmpop, right) and + sink.asExpr() = [left, right] + ) + } } From 2f3172e74b6c982f00af758a8d69a451765e6a9e Mon Sep 17 00:00:00 2001 From: Ahmed Farid Date: Tue, 26 Jul 2022 15:34:40 +0100 Subject: [PATCH 028/631] Update TimingAttackAgainstHeader.ql --- .../experimental/Security/CWE-208/TimingAttackAgainstHeader.ql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHeader.ql b/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHeader.ql index f51b6acdf80..6d14477b413 100644 --- a/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHeader.ql +++ b/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHeader.ql @@ -17,7 +17,7 @@ import TimingAttack import DataFlow::PathGraph /** - * Taint-tracking configuration tracing flow from obtaining a client Secret from an HTTP header to a unsafe Comparison. + * A configuration tracing flow from a client Secret obtained by an HTTP header to a unsafe Comparison. */ class ClientSuppliedSecretConfig extends TaintTracking::Configuration { ClientSuppliedSecretConfig() { this = "ClientSuppliedSecretConfig" } From 961cc8778fc69fdd730f70e79effb70ad6a3483a Mon Sep 17 00:00:00 2001 From: Ahmed Farid Date: Tue, 26 Jul 2022 15:36:07 +0100 Subject: [PATCH 029/631] Update PossibleTimingAttackAgainstHash.ql --- .../Security/CWE-208/PossibleTimingAttackAgainstHash.ql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/ql/src/experimental/Security/CWE-208/PossibleTimingAttackAgainstHash.ql b/python/ql/src/experimental/Security/CWE-208/PossibleTimingAttackAgainstHash.ql index a3cc78342ce..044baec26b1 100644 --- a/python/ql/src/experimental/Security/CWE-208/PossibleTimingAttackAgainstHash.ql +++ b/python/ql/src/experimental/Security/CWE-208/PossibleTimingAttackAgainstHash.ql @@ -28,7 +28,7 @@ class PossibleTimingAttackAgainstHash extends TaintTracking::Configuration { override predicate isSource(DataFlow::Node source) { source instanceof ProduceHashCall } - override predicate isSink(DataFlow::Node sink) { sink instanceof CompareSink } + override predicate isSink(DataFlow::Node sink) { sink instanceof NonConstantTimeComparisonOfHashSink } } from PossibleTimingAttackAgainstHash config, DataFlow::PathNode source, DataFlow::PathNode sink From 912f40255d520f10bb2ab776528056cd891f22e0 Mon Sep 17 00:00:00 2001 From: Ahmed Farid Date: Tue, 26 Jul 2022 15:37:02 +0100 Subject: [PATCH 030/631] Update TimingAttackAgainstSensitiveInfo.ql --- .../Security/CWE-208/TimingAttackAgainstSensitiveInfo.ql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstSensitiveInfo.ql b/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstSensitiveInfo.ql index 04fff48479d..879a211a3cf 100644 --- a/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstSensitiveInfo.ql +++ b/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstSensitiveInfo.ql @@ -24,7 +24,7 @@ class ClientSuppliedSecretConfig extends TaintTracking::Configuration { override predicate isSource(DataFlow::Node source) { source.asExpr() instanceof CredentialExpr } - override predicate isSink(DataFlow::Node sink) { sink instanceof CompareSink } + override predicate isSink(DataFlow::Node sink) { sink instanceof NonConstantTimeComparisonOfSecretSink } } from ClientSuppliedSecretConfig config, DataFlow::PathNode source, DataFlow::PathNode sink From 9c08f9fbe601a8f085f9de8e1e701d08ddafd1c3 Mon Sep 17 00:00:00 2001 From: Ahmed Farid Date: Tue, 26 Jul 2022 15:38:37 +0100 Subject: [PATCH 031/631] Update TimingAttackAgainstHeader.ql --- .../Security/CWE-208/TimingAttackAgainstHeader.ql | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHeader.ql b/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHeader.ql index 6d14477b413..f15439a0651 100644 --- a/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHeader.ql +++ b/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHeader.ql @@ -24,7 +24,13 @@ class ClientSuppliedSecretConfig extends TaintTracking::Configuration { override predicate isSource(DataFlow::Node source) { source instanceof ClientSuppliedsecret } - override predicate isSink(DataFlow::Node sink) { sink instanceof CompareSink } + override predicate isSink(DataFlow::Node sink) { + exists(Compare cmp, Expr left, Expr right, Cmpop cmpop | + cmpop.getSymbol() = ["==", "in", "is not", "!="] and + cmp.compares(left, cmpop, right) and + sink.asExpr() = [left, right] + ) + } } from ClientSuppliedSecretConfig config, DataFlow::PathNode source, DataFlow::PathNode sink From bfb8395dce54a0967ab4df80b72ca9fd89ecdcaf Mon Sep 17 00:00:00 2001 From: Ahmed Farid Date: Tue, 26 Jul 2022 16:05:57 +0100 Subject: [PATCH 032/631] Update TimingAttackAgainstSensitiveInfo.ql --- .../Security/CWE-208/TimingAttackAgainstSensitiveInfo.ql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstSensitiveInfo.ql b/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstSensitiveInfo.ql index 879a211a3cf..033fe0200be 100644 --- a/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstSensitiveInfo.ql +++ b/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstSensitiveInfo.ql @@ -17,7 +17,7 @@ import TimingAttack import DataFlow::PathGraph /** - * Taint-tracking configuration tracing flow from obtaining a client Secret to a unsafe Comparison. + * A configuration tracing flow from obtaining a client Secret to a unsafe Comparison. */ class ClientSuppliedSecretConfig extends TaintTracking::Configuration { ClientSuppliedSecretConfig() { this = "ClientSuppliedSecretConfig" } From 735fee53a44b8486a95ef7871021e643cf4140b0 Mon Sep 17 00:00:00 2001 From: Ahmed Farid Date: Tue, 26 Jul 2022 16:35:26 +0100 Subject: [PATCH 033/631] Update TimingAttack.qll --- .../Security/CWE-208/TimingAttack.qll | 22 +++++++++---------- 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/python/ql/src/experimental/Security/CWE-208/TimingAttack.qll b/python/ql/src/experimental/Security/CWE-208/TimingAttack.qll index 140db2c3cf6..239aeeced9a 100644 --- a/python/ql/src/experimental/Security/CWE-208/TimingAttack.qll +++ b/python/ql/src/experimental/Security/CWE-208/TimingAttack.qll @@ -3,6 +3,7 @@ private import semmle.python.dataflow.new.TaintTracking private import semmle.python.dataflow.new.TaintTracking2 private import semmle.python.dataflow.new.TaintTracking3 private import semmle.python.dataflow.new.DataFlow +private import semmle.python.dataflow.new.DataFlow2 private import semmle.python.ApiGraphs private import semmle.python.dataflow.new.RemoteFlowSources @@ -48,10 +49,10 @@ private predicate existsFailFastCheck(Expr firstInput, Expr secondInput) { } /** A sink that compares input using fail fast check. */ -class NonConstantTimeComparisonOfHashSink extends DataFlow::Node { +class NonConstantTimeComparisonSink extends DataFlow::Node { Expr anotherParameter; - NonConstantTimeComparisonOfHashSink() { + NonConstantTimeComparisonSink() { existsFailFastCheck(this.asExpr(), anotherParameter) and not anotherParameter.isConstant() } @@ -64,19 +65,16 @@ class NonConstantTimeComparisonOfHashSink extends DataFlow::Node { } } -/** A sink that compares input using fail fast check. */ -class NonConstantTimeComparisonOfSecretSink extends DataFlow::Node { - Expr anotherParameter; +/** A data flow source of the secret obtained. */ +class SecretSource extends DataFlow::Node { + CredentialExpr secret; - NonConstantTimeComparisonOfSecretSink() { - existsFailFastCheck(this.asExpr(), anotherParameter) and - not anotherParameter.isConstant() - } + SecretSource() { secret = this.asExpr() } - /** Holds if remote user input was used in the comparison. */ + /** Holds if the source of secret was remote user input. */ predicate includesUserInput() { exists(UserInputSecretConfig config | - config.hasFlowTo(DataFlow2::exprNode(anotherParameter)) + config.hasFlowTo(DataFlow2::exprNode(secret)) ) } } @@ -188,7 +186,7 @@ class UserInputSecretConfig extends TaintTracking2::Configuration { /** * A config that tracks data flow from remote user input to Equality test */ -class UserInputInComparisonConfig extends TaintTracking3::Configuration { +class UserInputInComparisonConfig extends TaintTracking2::Configuration { UserInputInComparisonConfig() { this = "UserInputInComparisonConfig" } override predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource } From b42293dbbbf29d5c90cb939233e1430d97884961 Mon Sep 17 00:00:00 2001 From: Ahmed Farid Date: Tue, 26 Jul 2022 16:40:24 +0100 Subject: [PATCH 034/631] Update TimingAttackAgainstSensitiveInfo.ql --- .../Security/CWE-208/TimingAttackAgainstSensitiveInfo.ql | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstSensitiveInfo.ql b/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstSensitiveInfo.ql index 033fe0200be..ed11db9c5bb 100644 --- a/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstSensitiveInfo.ql +++ b/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstSensitiveInfo.ql @@ -22,12 +22,17 @@ import DataFlow::PathGraph class ClientSuppliedSecretConfig extends TaintTracking::Configuration { ClientSuppliedSecretConfig() { this = "ClientSuppliedSecretConfig" } - override predicate isSource(DataFlow::Node source) { source.asExpr() instanceof CredentialExpr } + override predicate isSource(DataFlow::Node source) { source instanceof SecretSource } - override predicate isSink(DataFlow::Node sink) { sink instanceof NonConstantTimeComparisonOfSecretSink } + override predicate isSink(DataFlow::Node sink) { sink instanceof NonConstantTimeComparisonSink } } from ClientSuppliedSecretConfig config, DataFlow::PathNode source, DataFlow::PathNode sink where config.hasFlowPath(source, sink) + config.hasFlowPath(source, sink) and + ( + source.getNode().(SecretSource).includesUserInput() and + sink.getNode().(NonConstantTimeComparisonSink).includesUserInput() + ) select sink.getNode(), source, sink, "Timing attack against $@ validation.", source.getNode(), "client-supplied token" From 32d380828daff5e898b531e47a32bad083ec3c7b Mon Sep 17 00:00:00 2001 From: Ahmed Farid Date: Tue, 26 Jul 2022 16:41:23 +0100 Subject: [PATCH 035/631] Update TimingAttackAgainstSensitiveInfo.ql --- .../Security/CWE-208/TimingAttackAgainstSensitiveInfo.ql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstSensitiveInfo.ql b/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstSensitiveInfo.ql index ed11db9c5bb..3b406a8c4e6 100644 --- a/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstSensitiveInfo.ql +++ b/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstSensitiveInfo.ql @@ -31,7 +31,7 @@ from ClientSuppliedSecretConfig config, DataFlow::PathNode source, DataFlow::Pat where config.hasFlowPath(source, sink) config.hasFlowPath(source, sink) and ( - source.getNode().(SecretSource).includesUserInput() and + source.getNode().(SecretSource).includesUserInput() or sink.getNode().(NonConstantTimeComparisonSink).includesUserInput() ) select sink.getNode(), source, sink, "Timing attack against $@ validation.", source.getNode(), From bdf94ceeee0a35e1b54ecc568cc0f58e1eaad632 Mon Sep 17 00:00:00 2001 From: Ahmed Farid Date: Tue, 26 Jul 2022 16:44:08 +0100 Subject: [PATCH 036/631] Update TimingAttackAgainstHash.ql --- .../Security/CWE-208/TimingAttackAgainstHash.ql | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHash.ql b/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHash.ql index 3a18a088643..66ec3b5a319 100644 --- a/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHash.ql +++ b/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHash.ql @@ -25,12 +25,12 @@ import DataFlow::PathGraph class TimingAttackAgainsthash extends TaintTracking::Configuration { TimingAttackAgainsthash() { this = "TimingAttackAgainsthash" } - override predicate isSource(DataFlow::Node source) { source instanceof UserInputMsgConfig } + override predicate isSource(DataFlow::Node source) { source instanceof ProduceHashCall } - override predicate isSink(DataFlow::Node sink) { sink instanceof UserInputInComparisonConfig } + override predicate isSink(DataFlow::Node sink) { sink instanceof NonConstantTimeComparisonSink } } from TimingAttackAgainsthash config, DataFlow::PathNode source, DataFlow::PathNode sink -where config.hasFlowPath(source, sink) +where config.hasFlowPath(source, sink) and sink.getNode().(NonConstantTimeComparisonSink).includesUserInput() select sink.getNode(), source, sink, "Timing attack against $@ validation.", source, source.getNode() From d68f8c5325d7a34e17ba136a9a5f136c3354560c Mon Sep 17 00:00:00 2001 From: Ahmed Farid Date: Tue, 26 Jul 2022 16:44:33 +0100 Subject: [PATCH 037/631] Update PossibleTimingAttackAgainstHash.ql --- .../Security/CWE-208/PossibleTimingAttackAgainstHash.ql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/ql/src/experimental/Security/CWE-208/PossibleTimingAttackAgainstHash.ql b/python/ql/src/experimental/Security/CWE-208/PossibleTimingAttackAgainstHash.ql index 044baec26b1..c3a35aaa216 100644 --- a/python/ql/src/experimental/Security/CWE-208/PossibleTimingAttackAgainstHash.ql +++ b/python/ql/src/experimental/Security/CWE-208/PossibleTimingAttackAgainstHash.ql @@ -28,7 +28,7 @@ class PossibleTimingAttackAgainstHash extends TaintTracking::Configuration { override predicate isSource(DataFlow::Node source) { source instanceof ProduceHashCall } - override predicate isSink(DataFlow::Node sink) { sink instanceof NonConstantTimeComparisonOfHashSink } + override predicate isSink(DataFlow::Node sink) { sink instanceof NonConstantTimeComparisonSink } } from PossibleTimingAttackAgainstHash config, DataFlow::PathNode source, DataFlow::PathNode sink From f35985097dc040e7af479b32f17ba32f2f7fdb80 Mon Sep 17 00:00:00 2001 From: Ahmed Farid Date: Tue, 26 Jul 2022 23:50:44 +0100 Subject: [PATCH 038/631] Update and rename PossibleTimingAttackAgainstSignature.expected to PossibleTimingAttackAgainstHash.expected --- .../CWE-208/PossibleTimingAttackAgainstHash.expected | 8 ++++++++ .../CWE-208/PossibleTimingAttackAgainstSignature.expected | 8 -------- 2 files changed, 8 insertions(+), 8 deletions(-) create mode 100644 python/ql/test/experimental/query-tests/Security/CWE-208/PossibleTimingAttackAgainstHash.expected delete mode 100644 python/ql/test/experimental/query-tests/Security/CWE-208/PossibleTimingAttackAgainstSignature.expected diff --git a/python/ql/test/experimental/query-tests/Security/CWE-208/PossibleTimingAttackAgainstHash.expected b/python/ql/test/experimental/query-tests/Security/CWE-208/PossibleTimingAttackAgainstHash.expected new file mode 100644 index 00000000000..978bcdbac6f --- /dev/null +++ b/python/ql/test/experimental/query-tests/Security/CWE-208/PossibleTimingAttackAgainstHash.expected @@ -0,0 +1,8 @@ +edges +| TimingAttackAgainstHash.py:13:12:13:47 | ControlFlowNode for Attribute() | TimingAttackAgainstHash.py:19:19:19:48 | ControlFlowNode for sign() | +nodes +| TimingAttackAgainstHash.py:13:12:13:47 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | +| TimingAttackAgainstHash.py:19:19:19:48 | ControlFlowNode for sign() | semmle.label | ControlFlowNode for sign() | +subpaths +#select +| TimingAttackAgainstHash.py:19:19:19:48 | ControlFlowNode for sign() | TimingAttackAgainstHash.py:13:12:13:47 | ControlFlowNode for Attribute() | TimingAttackAgainstHash.py:19:19:19:48 | ControlFlowNode for sign() | Timing attack against $@ validation. | TimingAttackAgainstHash.py:13:12:13:47 | ControlFlowNode for Attribute() | TimingAttackAgainstHash.py:13:12:13:47 | ControlFlowNode for Attribute() | diff --git a/python/ql/test/experimental/query-tests/Security/CWE-208/PossibleTimingAttackAgainstSignature.expected b/python/ql/test/experimental/query-tests/Security/CWE-208/PossibleTimingAttackAgainstSignature.expected deleted file mode 100644 index 33c8ad2e663..00000000000 --- a/python/ql/test/experimental/query-tests/Security/CWE-208/PossibleTimingAttackAgainstSignature.expected +++ /dev/null @@ -1,8 +0,0 @@ -edges -| TimingAttackAgainstSignature.py:13:12:13:47 | ControlFlowNode for Attribute() | TimingAttackAgainstSignature.py:19:19:19:48 | ControlFlowNode for sign() | -nodes -| TimingAttackAgainstSignature.py:13:12:13:47 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | -| TimingAttackAgainstSignature.py:19:19:19:48 | ControlFlowNode for sign() | semmle.label | ControlFlowNode for sign() | -subpaths -#select -| TimingAttackAgainstSignature.py:19:19:19:48 | ControlFlowNode for sign() | TimingAttackAgainstSignature.py:13:12:13:47 | ControlFlowNode for Attribute() | TimingAttackAgainstSignature.py:19:19:19:48 | ControlFlowNode for sign() | Possible Timing attack against $@ validation. | TimingAttackAgainstSignature.py:13:12:13:47 | ControlFlowNode for Attribute() | TimingAttackAgainstSignature.py:13:12:13:47 | ControlFlowNode for Attribute() | From 0083a7fa6dec11a85aa3c552e562da9c544e2082 Mon Sep 17 00:00:00 2001 From: Ahmed Farid Date: Tue, 26 Jul 2022 23:53:18 +0100 Subject: [PATCH 039/631] Update TimingAttackAgainstSensitiveInfo.ql --- .../Security/CWE-208/TimingAttackAgainstSensitiveInfo.ql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstSensitiveInfo.ql b/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstSensitiveInfo.ql index 3b406a8c4e6..a6e178cb5b6 100644 --- a/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstSensitiveInfo.ql +++ b/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstSensitiveInfo.ql @@ -28,7 +28,7 @@ class ClientSuppliedSecretConfig extends TaintTracking::Configuration { } from ClientSuppliedSecretConfig config, DataFlow::PathNode source, DataFlow::PathNode sink -where config.hasFlowPath(source, sink) +where config.hasFlowPath(source, sink) and ( source.getNode().(SecretSource).includesUserInput() or From d01d7ba766abb336d5235d34e73df9e9c840cba4 Mon Sep 17 00:00:00 2001 From: Ahmed Farid Date: Tue, 26 Jul 2022 23:53:39 +0100 Subject: [PATCH 040/631] Create PossibleTimingAttackAgainstSensitiveInfo.ql --- ...ossibleTimingAttackAgainstSensitiveInfo.ql | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 python/ql/src/experimental/Security/CWE-208/PossibleTimingAttackAgainstSensitiveInfo.ql diff --git a/python/ql/src/experimental/Security/CWE-208/PossibleTimingAttackAgainstSensitiveInfo.ql b/python/ql/src/experimental/Security/CWE-208/PossibleTimingAttackAgainstSensitiveInfo.ql new file mode 100644 index 00000000000..0e5ab58ad25 --- /dev/null +++ b/python/ql/src/experimental/Security/CWE-208/PossibleTimingAttackAgainstSensitiveInfo.ql @@ -0,0 +1,33 @@ +/** + * @name Timing attack against secret + * @description Use of a non-constant-time verification routine to check the value of an secret, + * possibly allowing a timing attack to retrieve sensitive information. + * @kind path-problem + * @problem.severity error + * @precision medium + * @id py/timing-attack-sensitive-info + * @tags security + * external/cwe/cwe-208 + */ + +import python +import semmle.python.dataflow.new.DataFlow +import semmle.python.dataflow.new.TaintTracking +import TimingAttack +import DataFlow::PathGraph + +/** + * A configuration tracing flow from obtaining a client Secret to a unsafe Comparison. + */ +class ClientSuppliedSecretConfig extends TaintTracking::Configuration { + ClientSuppliedSecretConfig() { this = "ClientSuppliedSecretConfig" } + + override predicate isSource(DataFlow::Node source) { source instanceof SecretSource } + + override predicate isSink(DataFlow::Node sink) { sink instanceof NonConstantTimeComparisonSink } +} + +from ClientSuppliedSecretConfig config, DataFlow::PathNode source, DataFlow::PathNode sink +where config.hasFlowPath(source, sink) +select sink.getNode(), source, sink, "Timing attack against $@ validation.", source.getNode(), + "client-supplied token" From ad57ff4defe8bef0165bb5a90c4695fb4d5c6cf2 Mon Sep 17 00:00:00 2001 From: Ahmed Farid Date: Tue, 26 Jul 2022 23:56:24 +0100 Subject: [PATCH 041/631] Rename PossibleTimingAttackAgainstSignature.qlref to PossibleTimingAttackAgainstHash.qlref --- ...ainstSignature.qlref => PossibleTimingAttackAgainstHash.qlref} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename python/ql/test/experimental/query-tests/Security/CWE-208/{PossibleTimingAttackAgainstSignature.qlref => PossibleTimingAttackAgainstHash.qlref} (100%) diff --git a/python/ql/test/experimental/query-tests/Security/CWE-208/PossibleTimingAttackAgainstSignature.qlref b/python/ql/test/experimental/query-tests/Security/CWE-208/PossibleTimingAttackAgainstHash.qlref similarity index 100% rename from python/ql/test/experimental/query-tests/Security/CWE-208/PossibleTimingAttackAgainstSignature.qlref rename to python/ql/test/experimental/query-tests/Security/CWE-208/PossibleTimingAttackAgainstHash.qlref From ca4fa0aaae0599848eb07d77ea242fcaa741c8b8 Mon Sep 17 00:00:00 2001 From: Ahmed Farid Date: Wed, 27 Jul 2022 00:06:28 +0100 Subject: [PATCH 042/631] Update TimingAttack.qll --- python/ql/src/experimental/Security/CWE-208/TimingAttack.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/ql/src/experimental/Security/CWE-208/TimingAttack.qll b/python/ql/src/experimental/Security/CWE-208/TimingAttack.qll index 239aeeced9a..4d6e316ff1e 100644 --- a/python/ql/src/experimental/Security/CWE-208/TimingAttack.qll +++ b/python/ql/src/experimental/Security/CWE-208/TimingAttack.qll @@ -71,7 +71,7 @@ class SecretSource extends DataFlow::Node { SecretSource() { secret = this.asExpr() } - /** Holds if the source of secret was remote user input. */ + /** Holds if the secret was deliverd by remote user. */ predicate includesUserInput() { exists(UserInputSecretConfig config | config.hasFlowTo(DataFlow2::exprNode(secret)) From 11e888f0ac199c6d93bc74a8d803a1c0664c8255 Mon Sep 17 00:00:00 2001 From: Ahmed Farid Date: Wed, 27 Jul 2022 00:25:13 +0100 Subject: [PATCH 043/631] Update TimingAttackAgainstSensitiveInfo.expected From e3340c93455028723344467c18c5a4a86fdd987a Mon Sep 17 00:00:00 2001 From: Ahmed Farid Date: Wed, 27 Jul 2022 00:25:42 +0100 Subject: [PATCH 044/631] Update TimingAttackAgainstSensitiveInfo.py --- .../Security/CWE-208/TimingAttackAgainstSensitiveInfo.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstSensitiveInfo.py b/python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstSensitiveInfo.py index 6c5a1fa7c5f..6d3d60234a5 100644 --- a/python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstSensitiveInfo.py +++ b/python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstSensitiveInfo.py @@ -12,13 +12,13 @@ app = Flask(__name__) def check_credentials(): if request.method == 'POST': password = request.form['pwd'] - return password == "token" + return password == sec @app.route('/good') -def check_credentials(password): +def check_credentials(sec): if request.method == 'POST': password = request.form['pwd'] - return constant_time_string_compare(password, "token") + return constant_time_string_compare(password, sec) def constant_time_string_compare(a, b): if len(a) != len(b): From 9b2ff70332c590899021ece93161aed65d7e7fd3 Mon Sep 17 00:00:00 2001 From: Ahmed Farid Date: Thu, 4 Aug 2022 00:56:30 +0100 Subject: [PATCH 045/631] format document --- .../Security/CWE-208/TimingAttack.qll | 37 +++++++++---------- 1 file changed, 17 insertions(+), 20 deletions(-) diff --git a/python/ql/src/experimental/Security/CWE-208/TimingAttack.qll b/python/ql/src/experimental/Security/CWE-208/TimingAttack.qll index 4d6e316ff1e..54e3318a950 100644 --- a/python/ql/src/experimental/Security/CWE-208/TimingAttack.qll +++ b/python/ql/src/experimental/Security/CWE-208/TimingAttack.qll @@ -12,7 +12,7 @@ class ProduceHashCall extends DataFlow::CallCfgNode { ProduceHashCall() { this = API::moduleImport("hmac").getMember("digest").getACall() or this = - API::moduleImport("hmac") + API::moduleImport("hmac") .getMember("new") .getReturn() .getMember(["digest", "hexdigest"]) @@ -26,25 +26,24 @@ class ProduceHashCall extends DataFlow::CallCfgNode { .getMember(["digest", "hexdigest"]) .getACall() } - } /** A data flow sink for comparison. */ private predicate existsFailFastCheck(Expr firstInput, Expr secondInput) { exists(Compare compare | - ( - compare.getOp(0) instanceof Eq or - compare.getOp(0) instanceof NotEq or - compare.getOp(0) instanceof In or - compare.getOp(0) instanceof NotIn - ) and - ( - compare.getLeft() = firstInput and - compare.getComparator(0) = secondInput - or - compare.getLeft() = secondInput and - compare.getComparator(0) = firstInput - ) + ( + compare.getOp(0) instanceof Eq or + compare.getOp(0) instanceof NotEq or + compare.getOp(0) instanceof In or + compare.getOp(0) instanceof NotIn + ) and + ( + compare.getLeft() = firstInput and + compare.getComparator(0) = secondInput + or + compare.getLeft() = secondInput and + compare.getComparator(0) = firstInput + ) ) } @@ -54,7 +53,7 @@ class NonConstantTimeComparisonSink extends DataFlow::Node { NonConstantTimeComparisonSink() { existsFailFastCheck(this.asExpr(), anotherParameter) and - not anotherParameter.isConstant() + not anotherParameter.isConstant() } /** Holds if remote user input was used in the comparison. */ @@ -73,9 +72,7 @@ class SecretSource extends DataFlow::Node { /** Holds if the secret was deliverd by remote user. */ predicate includesUserInput() { - exists(UserInputSecretConfig config | - config.hasFlowTo(DataFlow2::exprNode(secret)) - ) + exists(UserInputSecretConfig config | config.hasFlowTo(DataFlow2::exprNode(secret))) } } @@ -191,7 +188,7 @@ class UserInputInComparisonConfig extends TaintTracking2::Configuration { override predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource } - override predicate isSink(DataFlow::Node sink) { + override predicate isSink(DataFlow::Node sink) { exists(Compare cmp, Expr left, Expr right, Cmpop cmpop | cmpop.getSymbol() = ["==", "in", "is not", "!="] and cmp.compares(left, cmpop, right) and From 473ff0ef597f084b86bedafc8fc2871092f62482 Mon Sep 17 00:00:00 2001 From: Ahmed Farid Date: Thu, 4 Aug 2022 12:02:50 +0100 Subject: [PATCH 046/631] Create TimingAttackAgainstHash.qhelp --- .../CWE-208/TimingAttackAgainstHash.qhelp | 55 +++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHash.qhelp diff --git a/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHash.qhelp b/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHash.qhelp new file mode 100644 index 00000000000..2602a5a0cca --- /dev/null +++ b/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHash.qhelp @@ -0,0 +1,55 @@ + + + + +

    + Timing Attack is based on the leakage of information by studying how long it takes the system to respond to different inputs. + it can be circumvented by using a constant-time algorithm for checking the value of Hash, +more precisely, the comparison time should not depend on the content of the input. Otherwise the attacker gains +information that is indirectly leaked by the application. This information is then used for malicious purposes. +

    +
    + + + +

    + Two types of countermeasures can be applied against timing attacks. The first one consists +in eliminating timing variations whereas the second renders these variations useless for an attacker. +The only absolute way to prevent timing attacks is to make the computation strictly constant time, +independent of the input. + + Use hmac.compare_digest() method to securely check the value of Hash. +If this method is used, then the calculation time depends only on the length of input byte arrays, +and does not depend on the contents of the arrays. + Unlike == is a fail fast check, If the first byte is not equal, it will return immediately. +

    +
    + +

    + The following example uses == which is a fail fast check for validating a Hash. +

    + + +

    + The next example use a safe constant-time algorithm for validating a Hash: +

    + +
    + + +
  • + Wikipedia: + Timing attack. +
  • + +
  • + hmac.compare_digest() method +
  • + +
  • + HMAC: + RFC 2104 +
  • +
    + +
    From 2bb9448c9f03849f77ec9f15b1624de0c28c4c49 Mon Sep 17 00:00:00 2001 From: Ahmed Farid Date: Thu, 4 Aug 2022 12:03:48 +0100 Subject: [PATCH 047/631] Create PossibleTimingAttackAgainstHash.qhelp --- .../Security/CWE-208/PossibleTimingAttackAgainstHash.qhelp | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 python/ql/src/experimental/Security/CWE-208/PossibleTimingAttackAgainstHash.qhelp diff --git a/python/ql/src/experimental/Security/CWE-208/PossibleTimingAttackAgainstHash.qhelp b/python/ql/src/experimental/Security/CWE-208/PossibleTimingAttackAgainstHash.qhelp new file mode 100644 index 00000000000..37b803553d8 --- /dev/null +++ b/python/ql/src/experimental/Security/CWE-208/PossibleTimingAttackAgainstHash.qhelp @@ -0,0 +1,4 @@ + + + + From 89e1ad40f2864c6b9031f92e8340f4b410f1677c Mon Sep 17 00:00:00 2001 From: Ahmed Farid Date: Thu, 4 Aug 2022 12:10:06 +0100 Subject: [PATCH 048/631] Create TimingAttackAgainstHeaderValue.ql --- .../CWE-208/TimingAttackAgainstHeaderValue.ql | 50 +++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHeaderValue.ql diff --git a/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHeaderValue.ql b/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHeaderValue.ql new file mode 100644 index 00000000000..547610b9bc2 --- /dev/null +++ b/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHeaderValue.ql @@ -0,0 +1,50 @@ + + + + +

    + A constant-time algorithm should be used for checking the value of sensitive headers. +In other words, the comparison time should not depend on the content of the input. +Otherwise timing information could be used to infer the header's expected, secret value. +

    +
    + + + +

    + Two types of countermeasures can be applied against timing attacks. The first one consists +in eliminating timing variations whereas the second renders these variations useless for an attacker. +The only absolute way to prevent timing attacks is to make the computation strictly constant time, +independent of the input. + + Use hmac.compare_digest() method to securely check the secret value. +If this method is used, then the calculation time depends only on the length of input byte arrays, +and does not depend on the contents of the arrays. + Unlike == is a fail fast check, If the first byte is not equal, it will return immediately. +

    +
    + +

    + The following example uses == which is a fail fast check for validating the value of sensitive headers. +

    + + +

    + The next example use a safe constant-time algorithm for validating the value of sensitive headers: +

    + +
    + + +
  • + Wikipedia: + Timing attack. +
  • + +
  • + hmac.compare_digest() method +
  • + +
    + +
    From 399972071cf8f715f79b55bde9251c945841af04 Mon Sep 17 00:00:00 2001 From: Ahmed Farid Date: Thu, 4 Aug 2022 12:11:28 +0100 Subject: [PATCH 049/631] Rename TimingAttackAgainstHeaderValue.ql to TimingAttackAgainstHeaderValue.qhelp --- ...AgainstHeaderValue.ql => TimingAttackAgainstHeaderValue.qhelp} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename python/ql/src/experimental/Security/CWE-208/{TimingAttackAgainstHeaderValue.ql => TimingAttackAgainstHeaderValue.qhelp} (100%) diff --git a/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHeaderValue.ql b/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHeaderValue.qhelp similarity index 100% rename from python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHeaderValue.ql rename to python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHeaderValue.qhelp From 10df8e6c021c83097edd9ab4f85eb6285875518a Mon Sep 17 00:00:00 2001 From: Ahmed Farid Date: Thu, 4 Aug 2022 12:12:44 +0100 Subject: [PATCH 050/631] Rename TimingAttackAgainstHeader.ql to TimingAttackAgainstHeaderValue.ql --- ...ngAttackAgainstHeader.ql => TimingAttackAgainstHeaderValue.ql} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename python/ql/src/experimental/Security/CWE-208/{TimingAttackAgainstHeader.ql => TimingAttackAgainstHeaderValue.ql} (100%) diff --git a/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHeader.ql b/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHeaderValue.ql similarity index 100% rename from python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHeader.ql rename to python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHeaderValue.ql From c13477c14f6d07bc265e656157fb420439fce5c2 Mon Sep 17 00:00:00 2001 From: Ahmed Farid Date: Thu, 4 Aug 2022 12:16:06 +0100 Subject: [PATCH 051/631] Update and rename TimingAttack.qhelp to TimingAttackAgainstSensitiveInfo.qhelp --- ...ck.qhelp => TimingAttackAgainstSensitiveInfo.qhelp} | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) rename python/ql/src/experimental/Security/CWE-208/{TimingAttack.qhelp => TimingAttackAgainstSensitiveInfo.qhelp} (91%) diff --git a/python/ql/src/experimental/Security/CWE-208/TimingAttack.qhelp b/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstSensitiveInfo.qhelp similarity index 91% rename from python/ql/src/experimental/Security/CWE-208/TimingAttack.qhelp rename to python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstSensitiveInfo.qhelp index f684894a8ce..683af727470 100644 --- a/python/ql/src/experimental/Security/CWE-208/TimingAttack.qhelp +++ b/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstSensitiveInfo.qhelp @@ -29,12 +29,12 @@ and does not depend on the contents of the arrays.

    The following example uses == which is a fail fast check for validating a secret.

    - +

    The next example use a safe constant-time algorithm for validating a secret:

    - + @@ -46,11 +46,7 @@ and does not depend on the contents of the arrays.
  • hmac.compare_digest() method
  • - -
  • - HMAC: - RFC 2104 -
  • +
    From c59a8b0c57ebbb470f6960a1be3ad3b64149b722 Mon Sep 17 00:00:00 2001 From: Ahmed Farid Date: Thu, 4 Aug 2022 12:17:43 +0100 Subject: [PATCH 052/631] Create PossibleTimingAttackAgainstSensitiveInfo.qhelp --- .../CWE-208/PossibleTimingAttackAgainstSensitiveInfo.qhelp | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 python/ql/src/experimental/Security/CWE-208/PossibleTimingAttackAgainstSensitiveInfo.qhelp diff --git a/python/ql/src/experimental/Security/CWE-208/PossibleTimingAttackAgainstSensitiveInfo.qhelp b/python/ql/src/experimental/Security/CWE-208/PossibleTimingAttackAgainstSensitiveInfo.qhelp new file mode 100644 index 00000000000..959bdc97a16 --- /dev/null +++ b/python/ql/src/experimental/Security/CWE-208/PossibleTimingAttackAgainstSensitiveInfo.qhelp @@ -0,0 +1,4 @@ + + + + From 1fed6074e9062800f34049a6d3419f6f55ea581d Mon Sep 17 00:00:00 2001 From: Ahmed Farid Date: Thu, 4 Aug 2022 12:25:47 +0100 Subject: [PATCH 053/631] Create SafeComparisonOfHash.py --- .../Security/CWE-208/SafeComparisonOfHash.py | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 python/ql/src/experimental/Security/CWE-208/SafeComparisonOfHash.py diff --git a/python/ql/src/experimental/Security/CWE-208/SafeComparisonOfHash.py b/python/ql/src/experimental/Security/CWE-208/SafeComparisonOfHash.py new file mode 100644 index 00000000000..6c4d56bc678 --- /dev/null +++ b/python/ql/src/experimental/Security/CWE-208/SafeComparisonOfHash.py @@ -0,0 +1,17 @@ +#!/usr/bin/env python +# -*- coding: UTF-8 -*- + +""" +@Desc :preventing timing attack Against Hash +""" +import hmac +import hashlib + +key = "e179017a-62b0-4996-8a38-e91aa9f1" +msg = "Test" + +def sign(pre_key, imsg, alg): + return hmac.new(pre_key, msg, alg).digest() + +def verify(msg, sig): + return hmac.compare_digest(sig, sign(key, msg, hashlib.sha256)) #good From 9c0a71d880932f7b86a07bc5a63953bbb62ac82b Mon Sep 17 00:00:00 2001 From: Ahmed Farid Date: Thu, 4 Aug 2022 12:27:35 +0100 Subject: [PATCH 054/631] Update SafeComparisonOfHash.py --- .../src/experimental/Security/CWE-208/SafeComparisonOfHash.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/ql/src/experimental/Security/CWE-208/SafeComparisonOfHash.py b/python/ql/src/experimental/Security/CWE-208/SafeComparisonOfHash.py index 6c4d56bc678..3aadc9b577c 100644 --- a/python/ql/src/experimental/Security/CWE-208/SafeComparisonOfHash.py +++ b/python/ql/src/experimental/Security/CWE-208/SafeComparisonOfHash.py @@ -11,7 +11,7 @@ key = "e179017a-62b0-4996-8a38-e91aa9f1" msg = "Test" def sign(pre_key, imsg, alg): - return hmac.new(pre_key, msg, alg).digest() + return hmac.new(pre_key, imsg, alg).digest() def verify(msg, sig): return hmac.compare_digest(sig, sign(key, msg, hashlib.sha256)) #good From e28cf7ebe222e0c110c2e6522b356dfb8e20788c Mon Sep 17 00:00:00 2001 From: Ahmed Farid Date: Thu, 4 Aug 2022 12:28:46 +0100 Subject: [PATCH 055/631] Create UnSafeComparisonOfHash.py --- .../Security/CWE-208/UnSafeComparisonOfHash.py | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 python/ql/src/experimental/Security/CWE-208/UnSafeComparisonOfHash.py diff --git a/python/ql/src/experimental/Security/CWE-208/UnSafeComparisonOfHash.py b/python/ql/src/experimental/Security/CWE-208/UnSafeComparisonOfHash.py new file mode 100644 index 00000000000..e518ee05379 --- /dev/null +++ b/python/ql/src/experimental/Security/CWE-208/UnSafeComparisonOfHash.py @@ -0,0 +1,17 @@ +#!/usr/bin/env python +# -*- coding: UTF-8 -*- + +""" +@Desc :timing attack Against Hash +""" +import hmac +import hashlib + +key = "e179017a-62b0-4996-8a38-e91aa9f1" +msg = "Test" + +def sign(pre_key, imsg, alg): + return hmac.new(pre_key, imsg, alg).digest() + +def verify(msg, sig): + return sig == sign(key, msg, hashlib.sha256) #bad From 035de1fffe666dc9234a7615b68922ba05e6af23 Mon Sep 17 00:00:00 2001 From: Ahmed Farid Date: Thu, 4 Aug 2022 12:30:12 +0100 Subject: [PATCH 056/631] Rename python/ql/src/experimental/Security/CWE-208/PossibleTimingAttackAgainstHash.qhelp to python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHash/PossibleTimingAttackAgainstHash.qhelp --- .../PossibleTimingAttackAgainstHash.qhelp | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename python/ql/src/experimental/Security/CWE-208/{ => TimingAttackAgainstHash}/PossibleTimingAttackAgainstHash.qhelp (100%) diff --git a/python/ql/src/experimental/Security/CWE-208/PossibleTimingAttackAgainstHash.qhelp b/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHash/PossibleTimingAttackAgainstHash.qhelp similarity index 100% rename from python/ql/src/experimental/Security/CWE-208/PossibleTimingAttackAgainstHash.qhelp rename to python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHash/PossibleTimingAttackAgainstHash.qhelp From 5afc0a777333420f63ceec68d8775e48c8c85a5e Mon Sep 17 00:00:00 2001 From: Ahmed Farid Date: Thu, 4 Aug 2022 12:30:38 +0100 Subject: [PATCH 057/631] Rename python/ql/src/experimental/Security/CWE-208/PossibleTimingAttackAgainstHash.ql to python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHash/PossibleTimingAttackAgainstHash.ql --- .../PossibleTimingAttackAgainstHash.ql | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename python/ql/src/experimental/Security/CWE-208/{ => TimingAttackAgainstHash}/PossibleTimingAttackAgainstHash.ql (100%) diff --git a/python/ql/src/experimental/Security/CWE-208/PossibleTimingAttackAgainstHash.ql b/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHash/PossibleTimingAttackAgainstHash.ql similarity index 100% rename from python/ql/src/experimental/Security/CWE-208/PossibleTimingAttackAgainstHash.ql rename to python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHash/PossibleTimingAttackAgainstHash.ql From 028ac192598535f56a2be65863a2a88a63917816 Mon Sep 17 00:00:00 2001 From: Ahmed Farid Date: Thu, 4 Aug 2022 12:30:56 +0100 Subject: [PATCH 058/631] Rename python/ql/src/experimental/Security/CWE-208/SafeComparisonOfHash.py to python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHash/SafeComparisonOfHash.py --- .../CWE-208/{ => TimingAttackAgainstHash}/SafeComparisonOfHash.py | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename python/ql/src/experimental/Security/CWE-208/{ => TimingAttackAgainstHash}/SafeComparisonOfHash.py (100%) diff --git a/python/ql/src/experimental/Security/CWE-208/SafeComparisonOfHash.py b/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHash/SafeComparisonOfHash.py similarity index 100% rename from python/ql/src/experimental/Security/CWE-208/SafeComparisonOfHash.py rename to python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHash/SafeComparisonOfHash.py From ad53176546bb6057e63d48d52ad4ab1e0e5a8bdf Mon Sep 17 00:00:00 2001 From: Ahmed Farid Date: Thu, 4 Aug 2022 12:35:24 +0100 Subject: [PATCH 059/631] Rename python/ql/src/experimental/Security/CWE-208/TimingAttack.qll to python/ql/src/experimental/semmle/python/security/TimingAttack.qll --- .../{Security/CWE-208 => semmle/python/security}/TimingAttack.qll | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename python/ql/src/experimental/{Security/CWE-208 => semmle/python/security}/TimingAttack.qll (100%) diff --git a/python/ql/src/experimental/Security/CWE-208/TimingAttack.qll b/python/ql/src/experimental/semmle/python/security/TimingAttack.qll similarity index 100% rename from python/ql/src/experimental/Security/CWE-208/TimingAttack.qll rename to python/ql/src/experimental/semmle/python/security/TimingAttack.qll From b5ff606b414844babf6bd2db97684e353cfb89ae Mon Sep 17 00:00:00 2001 From: Ahmed Farid Date: Thu, 4 Aug 2022 12:36:36 +0100 Subject: [PATCH 060/631] Update PossibleTimingAttackAgainstSensitiveInfo.ql --- .../CWE-208/PossibleTimingAttackAgainstSensitiveInfo.ql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/ql/src/experimental/Security/CWE-208/PossibleTimingAttackAgainstSensitiveInfo.ql b/python/ql/src/experimental/Security/CWE-208/PossibleTimingAttackAgainstSensitiveInfo.ql index 0e5ab58ad25..e4dcda45093 100644 --- a/python/ql/src/experimental/Security/CWE-208/PossibleTimingAttackAgainstSensitiveInfo.ql +++ b/python/ql/src/experimental/Security/CWE-208/PossibleTimingAttackAgainstSensitiveInfo.ql @@ -13,7 +13,7 @@ import python import semmle.python.dataflow.new.DataFlow import semmle.python.dataflow.new.TaintTracking -import TimingAttack +import experimental.semmle.python.security.TimingAttack import DataFlow::PathGraph /** From 61b7d898132cf004dc12f726e0ef49a8f8562825 Mon Sep 17 00:00:00 2001 From: Ahmed Farid Date: Thu, 4 Aug 2022 12:36:58 +0100 Subject: [PATCH 061/631] Update TimingAttackAgainstHash.ql --- .../experimental/Security/CWE-208/TimingAttackAgainstHash.ql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHash.ql b/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHash.ql index 66ec3b5a319..b2266f21095 100644 --- a/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHash.ql +++ b/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHash.ql @@ -15,7 +15,7 @@ import python import semmle.python.dataflow.new.DataFlow import semmle.python.dataflow.new.TaintTracking -import TimingAttack +import experimental.semmle.python.security.TimingAttack import DataFlow::PathGraph /** From 31692f523fd32a6d3a6095d2fc53feb88234a348 Mon Sep 17 00:00:00 2001 From: Ahmed Farid Date: Thu, 4 Aug 2022 12:37:57 +0100 Subject: [PATCH 062/631] Update PossibleTimingAttackAgainstHash.ql --- .../TimingAttackAgainstHash/PossibleTimingAttackAgainstHash.ql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHash/PossibleTimingAttackAgainstHash.ql b/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHash/PossibleTimingAttackAgainstHash.ql index c3a35aaa216..6c757a91ec6 100644 --- a/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHash/PossibleTimingAttackAgainstHash.ql +++ b/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHash/PossibleTimingAttackAgainstHash.ql @@ -16,7 +16,7 @@ import python import semmle.python.dataflow.new.DataFlow import semmle.python.dataflow.new.TaintTracking import semmle.python.ApiGraphs -import TimingAttack +import experimental.semmle.python.security.TimingAttack import DataFlow::PathGraph /** From 8490a54af52a083ed1fba765690dca3579313e49 Mon Sep 17 00:00:00 2001 From: Ahmed Farid Date: Thu, 4 Aug 2022 12:38:31 +0100 Subject: [PATCH 063/631] Update TimingAttackAgainstSensitiveInfo.ql --- .../Security/CWE-208/TimingAttackAgainstSensitiveInfo.ql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstSensitiveInfo.ql b/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstSensitiveInfo.ql index a6e178cb5b6..9e7b0a82be5 100644 --- a/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstSensitiveInfo.ql +++ b/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstSensitiveInfo.ql @@ -13,7 +13,7 @@ import python import semmle.python.dataflow.new.DataFlow import semmle.python.dataflow.new.TaintTracking -import TimingAttack +import experimental.semmle.python.security.TimingAttack import DataFlow::PathGraph /** From cf47104f62359d67538d6f65986f42141e39c4b6 Mon Sep 17 00:00:00 2001 From: Ahmed Farid Date: Thu, 4 Aug 2022 12:39:31 +0100 Subject: [PATCH 064/631] Update TimingAttackAgainstHeaderValue.ql --- .../Security/CWE-208/TimingAttackAgainstHeaderValue.ql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHeaderValue.ql b/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHeaderValue.ql index f15439a0651..00a64744aef 100644 --- a/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHeaderValue.ql +++ b/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHeaderValue.ql @@ -13,7 +13,7 @@ import python import semmle.python.dataflow.new.DataFlow import semmle.python.dataflow.new.TaintTracking -import TimingAttack +import experimental.semmle.python.security.TimingAttack import DataFlow::PathGraph /** From 4b0c42951f1ac6e8bb9ead5ffded5a321137b413 Mon Sep 17 00:00:00 2001 From: Ahmed Farid Date: Thu, 4 Aug 2022 12:41:27 +0100 Subject: [PATCH 065/631] Rename python/ql/src/experimental/Security/CWE-208/UnSafeComparisonOfHash.py to python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHash/UnSafeComparisonOfHash.py --- .../{ => TimingAttackAgainstHash}/UnSafeComparisonOfHash.py | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename python/ql/src/experimental/Security/CWE-208/{ => TimingAttackAgainstHash}/UnSafeComparisonOfHash.py (100%) diff --git a/python/ql/src/experimental/Security/CWE-208/UnSafeComparisonOfHash.py b/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHash/UnSafeComparisonOfHash.py similarity index 100% rename from python/ql/src/experimental/Security/CWE-208/UnSafeComparisonOfHash.py rename to python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHash/UnSafeComparisonOfHash.py From cf36a30909b75cd4d365c5a8971611a9ecd7f457 Mon Sep 17 00:00:00 2001 From: Ahmed Farid Date: Thu, 4 Aug 2022 12:41:51 +0100 Subject: [PATCH 066/631] Rename python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHash.qhelp to python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHash/TimingAttackAgainstHash.qhelp --- .../{ => TimingAttackAgainstHash}/TimingAttackAgainstHash.qhelp | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename python/ql/src/experimental/Security/CWE-208/{ => TimingAttackAgainstHash}/TimingAttackAgainstHash.qhelp (100%) diff --git a/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHash.qhelp b/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHash/TimingAttackAgainstHash.qhelp similarity index 100% rename from python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHash.qhelp rename to python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHash/TimingAttackAgainstHash.qhelp From a747bacbe54588f142fe0b60fc6390d9d1393c88 Mon Sep 17 00:00:00 2001 From: Ahmed Farid Date: Thu, 4 Aug 2022 12:42:08 +0100 Subject: [PATCH 067/631] Rename python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHash.ql to python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHash/TimingAttackAgainstHash.ql --- .../{ => TimingAttackAgainstHash}/TimingAttackAgainstHash.ql | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename python/ql/src/experimental/Security/CWE-208/{ => TimingAttackAgainstHash}/TimingAttackAgainstHash.ql (100%) diff --git a/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHash.ql b/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHash/TimingAttackAgainstHash.ql similarity index 100% rename from python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHash.ql rename to python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHash/TimingAttackAgainstHash.ql From ae4ded08fac92a12ae796842d41009f51e326c0d Mon Sep 17 00:00:00 2001 From: Ahmed Farid Date: Thu, 4 Aug 2022 12:42:52 +0100 Subject: [PATCH 068/631] Update and rename TimingAttackAgainstHeader.qlref to TimingAttackAgainstHeaderValue.qlref --- .../query-tests/Security/CWE-208/TimingAttackAgainstHeader.qlref | 1 - .../Security/CWE-208/TimingAttackAgainstHeaderValue.qlref | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) delete mode 100644 python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstHeader.qlref create mode 100644 python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstHeaderValue.qlref diff --git a/python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstHeader.qlref b/python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstHeader.qlref deleted file mode 100644 index 086df8ab1bb..00000000000 --- a/python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstHeader.qlref +++ /dev/null @@ -1 +0,0 @@ -experimental/Security/CWE/CWE-208/TimingAttackAgainstHeader.ql diff --git a/python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstHeaderValue.qlref b/python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstHeaderValue.qlref new file mode 100644 index 00000000000..7e6067274e2 --- /dev/null +++ b/python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstHeaderValue.qlref @@ -0,0 +1 @@ +experimental/Security/CWE/CWE-208/TimingAttackAgainstHeaderValue.ql From fe51a917ecefd8a1af82407310dcf0bbe6f23c0f Mon Sep 17 00:00:00 2001 From: Ahmed Farid Date: Thu, 4 Aug 2022 12:43:21 +0100 Subject: [PATCH 069/631] Rename python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstSensitiveInfo.qhelp to python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstSensitiveInfo/TimingAttackAgainstSensitiveInfo.qhelp --- .../TimingAttackAgainstSensitiveInfo.qhelp | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename python/ql/src/experimental/Security/CWE-208/{ => TimingAttackAgainstSensitiveInfo}/TimingAttackAgainstSensitiveInfo.qhelp (100%) diff --git a/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstSensitiveInfo.qhelp b/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstSensitiveInfo/TimingAttackAgainstSensitiveInfo.qhelp similarity index 100% rename from python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstSensitiveInfo.qhelp rename to python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstSensitiveInfo/TimingAttackAgainstSensitiveInfo.qhelp From 59f05b4d626969d0a71f824221725e71557fa017 Mon Sep 17 00:00:00 2001 From: Ahmed Farid Date: Thu, 4 Aug 2022 12:43:35 +0100 Subject: [PATCH 070/631] Rename python/ql/src/experimental/Security/CWE-208/PossibleTimingAttackAgainstSensitiveInfo.qhelp to python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstSensitiveInfo/PossibleTimingAttackAgainstSensitiveInfo.qhelp --- .../PossibleTimingAttackAgainstSensitiveInfo.qhelp | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename python/ql/src/experimental/Security/CWE-208/{ => TimingAttackAgainstSensitiveInfo}/PossibleTimingAttackAgainstSensitiveInfo.qhelp (100%) diff --git a/python/ql/src/experimental/Security/CWE-208/PossibleTimingAttackAgainstSensitiveInfo.qhelp b/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstSensitiveInfo/PossibleTimingAttackAgainstSensitiveInfo.qhelp similarity index 100% rename from python/ql/src/experimental/Security/CWE-208/PossibleTimingAttackAgainstSensitiveInfo.qhelp rename to python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstSensitiveInfo/PossibleTimingAttackAgainstSensitiveInfo.qhelp From a34478d58fd426fd539431103796f4df30dd0216 Mon Sep 17 00:00:00 2001 From: Ahmed Farid Date: Thu, 4 Aug 2022 12:43:53 +0100 Subject: [PATCH 071/631] Rename python/ql/src/experimental/Security/CWE-208/PossibleTimingAttackAgainstSensitiveInfo.ql to python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstSensitiveInfo/PossibleTimingAttackAgainstSensitiveInfo.ql --- .../PossibleTimingAttackAgainstSensitiveInfo.ql | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename python/ql/src/experimental/Security/CWE-208/{ => TimingAttackAgainstSensitiveInfo}/PossibleTimingAttackAgainstSensitiveInfo.ql (100%) diff --git a/python/ql/src/experimental/Security/CWE-208/PossibleTimingAttackAgainstSensitiveInfo.ql b/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstSensitiveInfo/PossibleTimingAttackAgainstSensitiveInfo.ql similarity index 100% rename from python/ql/src/experimental/Security/CWE-208/PossibleTimingAttackAgainstSensitiveInfo.ql rename to python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstSensitiveInfo/PossibleTimingAttackAgainstSensitiveInfo.ql From 428132a58e4de2ecf68719c31ccb20e76bb3d338 Mon Sep 17 00:00:00 2001 From: Ahmed Farid Date: Thu, 4 Aug 2022 12:44:10 +0100 Subject: [PATCH 072/631] Rename python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstSensitiveInfo.ql to python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstSensitiveInfo/TimingAttackAgainstSensitiveInfo.ql --- .../TimingAttackAgainstSensitiveInfo.ql | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename python/ql/src/experimental/Security/CWE-208/{ => TimingAttackAgainstSensitiveInfo}/TimingAttackAgainstSensitiveInfo.ql (100%) diff --git a/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstSensitiveInfo.ql b/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstSensitiveInfo/TimingAttackAgainstSensitiveInfo.ql similarity index 100% rename from python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstSensitiveInfo.ql rename to python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstSensitiveInfo/TimingAttackAgainstSensitiveInfo.ql From 76c8e7d2e857da87451732e6f69c1312a2ada3fc Mon Sep 17 00:00:00 2001 From: Ahmed Farid Date: Thu, 4 Aug 2022 12:44:45 +0100 Subject: [PATCH 073/631] Rename python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHeaderValue.ql to python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHeaderValue/TimingAttackAgainstHeaderValue.ql --- .../TimingAttackAgainstHeaderValue.ql | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename python/ql/src/experimental/Security/CWE-208/{ => TimingAttackAgainstHeaderValue}/TimingAttackAgainstHeaderValue.ql (100%) diff --git a/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHeaderValue.ql b/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHeaderValue/TimingAttackAgainstHeaderValue.ql similarity index 100% rename from python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHeaderValue.ql rename to python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHeaderValue/TimingAttackAgainstHeaderValue.ql From e1435afea95db3123dce9b1c837e82cfa5aa6b9c Mon Sep 17 00:00:00 2001 From: Ahmed Farid Date: Thu, 4 Aug 2022 12:45:01 +0100 Subject: [PATCH 074/631] Rename python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHeaderValue.qhelp to python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHeaderValue/TimingAttackAgainstHeaderValue.qhelp --- .../TimingAttackAgainstHeaderValue.qhelp | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename python/ql/src/experimental/Security/CWE-208/{ => TimingAttackAgainstHeaderValue}/TimingAttackAgainstHeaderValue.qhelp (100%) diff --git a/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHeaderValue.qhelp b/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHeaderValue/TimingAttackAgainstHeaderValue.qhelp similarity index 100% rename from python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHeaderValue.qhelp rename to python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHeaderValue/TimingAttackAgainstHeaderValue.qhelp From a98a77ad40824fbcd51d944ce11f6e2719917cf2 Mon Sep 17 00:00:00 2001 From: Ahmed Farid Date: Thu, 4 Aug 2022 12:48:19 +0100 Subject: [PATCH 075/631] Create SafeComparisonOfHeaderValue.py --- .../SafeComparisonOfHeaderValue.py | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHeaderValue/SafeComparisonOfHeaderValue.py diff --git a/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHeaderValue/SafeComparisonOfHeaderValue.py b/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHeaderValue/SafeComparisonOfHeaderValue.py new file mode 100644 index 00000000000..8e5295524ac --- /dev/null +++ b/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHeaderValue/SafeComparisonOfHeaderValue.py @@ -0,0 +1,20 @@ +#!/usr/bin/env python +# -*- coding: UTF-8 -*- + +""" +@Desc :preventing timing attack against header value +""" + +from flask import Flask +from flask import request + +@app.route('/good1') +def good1(): + Secret = request.headers.get('X-Auth-Token') + if not hmac.compare_digest("secret", "token"): + raise Exception('bad token') + return 'good' + +if __name__ == '__main__': + app.debug = True + app.run() From a6af455eae11d5291dd3249bcc020ef3c67eaaba Mon Sep 17 00:00:00 2001 From: Ahmed Farid Date: Thu, 4 Aug 2022 12:50:55 +0100 Subject: [PATCH 076/631] Create UnsafeComparisonOfHeaderValue.py --- .../UnsafeComparisonOfHeaderValue.py | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHeaderValue/UnsafeComparisonOfHeaderValue.py diff --git a/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHeaderValue/UnsafeComparisonOfHeaderValue.py b/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHeaderValue/UnsafeComparisonOfHeaderValue.py new file mode 100644 index 00000000000..f4a732a4f51 --- /dev/null +++ b/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHeaderValue/UnsafeComparisonOfHeaderValue.py @@ -0,0 +1,20 @@ +#!/usr/bin/env python +# -*- coding: UTF-8 -*- + +""" +@Desc :preventing timing attack against header value +""" + +from flask import Flask +from flask import request + +@app.route('/bad') +def good1(): + secret = request.headers.get('X-Auth-Token') + if secret == "token": + raise Exception('bad token') + return 'bad' + +if __name__ == '__main__': + app.debug = True + app.run() From 5eef14a0a9e6a62abbc35ac9c6f1ee1101d6a0f4 Mon Sep 17 00:00:00 2001 From: Ahmed Farid Date: Thu, 4 Aug 2022 12:51:30 +0100 Subject: [PATCH 077/631] Update SafeComparisonOfHeaderValue.py --- .../SafeComparisonOfHeaderValue.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHeaderValue/SafeComparisonOfHeaderValue.py b/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHeaderValue/SafeComparisonOfHeaderValue.py index 8e5295524ac..15c6a841d34 100644 --- a/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHeaderValue/SafeComparisonOfHeaderValue.py +++ b/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHeaderValue/SafeComparisonOfHeaderValue.py @@ -8,10 +8,10 @@ from flask import Flask from flask import request -@app.route('/good1') +@app.route('/good') def good1(): - Secret = request.headers.get('X-Auth-Token') - if not hmac.compare_digest("secret", "token"): + secret = request.headers.get('X-Auth-Token') + if not hmac.compare_digest(secret, "token"): raise Exception('bad token') return 'good' From dd613834694bd7c3d2f8d68d7c9409978024e9b6 Mon Sep 17 00:00:00 2001 From: Ahmed Farid Date: Fri, 5 Aug 2022 12:46:46 +0100 Subject: [PATCH 078/631] Create SafeComparisonOfSensitiveInfo.py --- .../SafeComparisonOfSensitiveInfo.py | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstSensitiveInfo/SafeComparisonOfSensitiveInfo.py diff --git a/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstSensitiveInfo/SafeComparisonOfSensitiveInfo.py b/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstSensitiveInfo/SafeComparisonOfSensitiveInfo.py new file mode 100644 index 00000000000..4ef45cca269 --- /dev/null +++ b/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstSensitiveInfo/SafeComparisonOfSensitiveInfo.py @@ -0,0 +1,17 @@ +#!/usr/bin/env python +# -*- coding: UTF-8 -*- + +""" +@Desc :preventing timing attack sensitive info +""" +import hmac +from flask import Flask +from flask import request + +@app.route('/good') +def check_credentials(password): + return hmac.compare_digest(password, "token") + +if __name__ == '__main__': + app.debug = True + app.run() From c7828bf9b434a983d914807ba70c70ecd4e33921 Mon Sep 17 00:00:00 2001 From: Ahmed Farid Date: Fri, 5 Aug 2022 12:47:58 +0100 Subject: [PATCH 079/631] Create UnSafeComparisonOfSensitiveInfo.py --- .../UnSafeComparisonOfSensitiveInfo.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstSensitiveInfo/UnSafeComparisonOfSensitiveInfo.py diff --git a/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstSensitiveInfo/UnSafeComparisonOfSensitiveInfo.py b/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstSensitiveInfo/UnSafeComparisonOfSensitiveInfo.py new file mode 100644 index 00000000000..d01fe61a62e --- /dev/null +++ b/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstSensitiveInfo/UnSafeComparisonOfSensitiveInfo.py @@ -0,0 +1,16 @@ +#!/usr/bin/env python +# -*- coding: UTF-8 -*- +""" +@Desc :timing attack against sensitive info +""" + +from flask import Flask +from flask import request + +@app.route('/bad') +def check_credentials(password): + return password == "token" + +if __name__ == '__main__': + app.debug = True + app.run() From d9e85a90645b90ab2f7defb66d2420803fc8fe7b Mon Sep 17 00:00:00 2001 From: Ahmed Farid Date: Fri, 5 Aug 2022 12:48:51 +0100 Subject: [PATCH 080/631] Delete SafeComparison.py --- .../Security/CWE-208/SafeComparison.py | 33 ------------------- 1 file changed, 33 deletions(-) delete mode 100644 python/ql/src/experimental/Security/CWE-208/SafeComparison.py diff --git a/python/ql/src/experimental/Security/CWE-208/SafeComparison.py b/python/ql/src/experimental/Security/CWE-208/SafeComparison.py deleted file mode 100644 index 377da6dd35b..00000000000 --- a/python/ql/src/experimental/Security/CWE-208/SafeComparison.py +++ /dev/null @@ -1,33 +0,0 @@ -#!/usr/bin/env python -# -*- coding: UTF-8 -*- - -""" -@Desc :preventing timing attack -""" -import hmac -from flask import Flask -from flask import request -import hashlib - -key = "e179017a-62b0-4996-8a38-e91aa9f1" - -@app.route('/good1') -def good1(): - Secret = request.headers.get('X-Auth-Token') - if not hmac.compare_digest(Secret, "token"): - raise Exception('bad token') - return 'good1' - -@app.route('/good2') -def check_credentials(password): - return hmac.compare_digest(password, "token") - -def sign(pre_key, msg, alg): - return hmac.new(pre_key, msg, alg).digest() - -def verify(msg, sig): - return hmac.compare_digest(sig, sign(key, msg, hashlib.sha256)) #good - -if __name__ == '__main__': - app.debug = True - app.run() From 21f9ee449a424d43d9ed178167d176ff5d887388 Mon Sep 17 00:00:00 2001 From: Ahmed Farid Date: Fri, 5 Aug 2022 12:49:00 +0100 Subject: [PATCH 081/631] Delete UnSafeComparison.py --- .../Security/CWE-208/UnSafeComparison.py | 34 ------------------- 1 file changed, 34 deletions(-) delete mode 100644 python/ql/src/experimental/Security/CWE-208/UnSafeComparison.py diff --git a/python/ql/src/experimental/Security/CWE-208/UnSafeComparison.py b/python/ql/src/experimental/Security/CWE-208/UnSafeComparison.py deleted file mode 100644 index a90688568bb..00000000000 --- a/python/ql/src/experimental/Security/CWE-208/UnSafeComparison.py +++ /dev/null @@ -1,34 +0,0 @@ -#!/usr/bin/env python -# -*- coding: UTF-8 -*- -""" -@Desc :timing attack -""" - -from flask import Flask -from flask import request -import hmac - -app = Flask(__name__) - -key = "e179017a-62b0-4996-8a38-e91aa9f1" - -@app.route('/bad1') -def bad1(): - Secret = request.headers.get('X-Auth-Token') - if not Secret == "key": - raise Exception('bad token') - return 'bad1' - -@app.route('/bad2') -def check_credentials(password): - return password == "token" - -def sign(pre_key, msg, alg): - return hmac.new(pre_key, msg, alg).digest() - -def verify(msg, sig): - return sig == sign(key, msg, hashlib.sha256) #bad - -if __name__ == '__main__': - app.debug = True - app.run() From 01490414e8e9339840f746b118613c7e6a96ac75 Mon Sep 17 00:00:00 2001 From: Ahmed Farid Date: Fri, 12 Aug 2022 12:25:31 +0100 Subject: [PATCH 082/631] Update TimingAttackAgainstHeader.py --- .../query-tests/Security/CWE-208/TimingAttackAgainstHeader.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstHeader.py b/python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstHeader.py index 8c31aba39f8..d08aecc3262 100644 --- a/python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstHeader.py +++ b/python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstHeader.py @@ -5,7 +5,7 @@ """ from flask import Flask from flask import request -from django.utils.crypto import constant_time_compare +import hmac app = Flask(__name__) @@ -17,7 +17,7 @@ def bad1(): @app.route('/good') def good1(): - if not constant_time_compare(Secret, "token"): + if not hmac.compare_digest(Secret, "token"): raise Exception('bad token') return 'good1' From 0e0c6e08b5bd394d05bb5343be833a5b4cfddbda Mon Sep 17 00:00:00 2001 From: Ahmed Farid Date: Mon, 15 Aug 2022 11:18:31 +0100 Subject: [PATCH 083/631] Update TimingAttack.qll --- .../src/experimental/semmle/python/security/TimingAttack.qll | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/python/ql/src/experimental/semmle/python/security/TimingAttack.qll b/python/ql/src/experimental/semmle/python/security/TimingAttack.qll index 54e3318a950..f42ff4a7264 100644 --- a/python/ql/src/experimental/semmle/python/security/TimingAttack.qll +++ b/python/ql/src/experimental/semmle/python/security/TimingAttack.qll @@ -52,8 +52,7 @@ class NonConstantTimeComparisonSink extends DataFlow::Node { Expr anotherParameter; NonConstantTimeComparisonSink() { - existsFailFastCheck(this.asExpr(), anotherParameter) and - not anotherParameter.isConstant() + existsFailFastCheck(this.asExpr(), anotherParameter) } /** Holds if remote user input was used in the comparison. */ From 7cb1683f5ba77ce9aacfcc078cccbdbda405309b Mon Sep 17 00:00:00 2001 From: Ahmed Farid Date: Mon, 15 Aug 2022 11:21:40 +0100 Subject: [PATCH 084/631] Update TimingAttackAgainstSensitiveInfo.py --- .../CWE-208/TimingAttackAgainstSensitiveInfo.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstSensitiveInfo.py b/python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstSensitiveInfo.py index 6d3d60234a5..3c7c7b027df 100644 --- a/python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstSensitiveInfo.py +++ b/python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstSensitiveInfo.py @@ -8,17 +8,17 @@ from flask import request app = Flask(__name__) -@app.route('/bad') -def check_credentials(): +@app.route('/bad', methods = ['POST', 'GET']) +def bad(): if request.method == 'POST': password = request.form['pwd'] - return password == sec + return password == "1234" -@app.route('/good') -def check_credentials(sec): +@app.route('/good', methods = ['POST', 'GET']) +def good(): if request.method == 'POST': password = request.form['pwd'] - return constant_time_string_compare(password, sec) + return constant_time_string_compare(password, "1234") def constant_time_string_compare(a, b): if len(a) != len(b): From 5de103303d7509fdf798c0b6251fcce119ac30a7 Mon Sep 17 00:00:00 2001 From: Ahmed Farid Date: Mon, 15 Aug 2022 11:26:34 +0100 Subject: [PATCH 085/631] Update TimingAttackAgainstHeader.py --- .../Security/CWE-208/TimingAttackAgainstHeader.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstHeader.py b/python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstHeader.py index d08aecc3262..43c34c4976c 100644 --- a/python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstHeader.py +++ b/python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstHeader.py @@ -10,16 +10,17 @@ import hmac app = Flask(__name__) @app.route('/bad') -def bad1(): - if not request.headers.get('X-Auth-Token') == "key": +def bad(): + if not request.headers.get('X-Auth-Token') == "token": raise Exception('bad token') - return 'bad1' + return 'bad' @app.route('/good') -def good1(): +def good(): + Secret = request.headers.get('X-Auth-Token') if not hmac.compare_digest(Secret, "token"): raise Exception('bad token') - return 'good1' + return 'good' if __name__ == '__main__': app.debug = True From 521dbd0e82d7ca3442a8e6285935bed677832607 Mon Sep 17 00:00:00 2001 From: Ahmed Farid Date: Mon, 15 Aug 2022 11:28:51 +0100 Subject: [PATCH 086/631] Update TimingAttackAgainstSensitiveInfo.py --- .../CWE-208/TimingAttackAgainstSensitiveInfo.py | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstSensitiveInfo.py b/python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstSensitiveInfo.py index 3c7c7b027df..5db572f5486 100644 --- a/python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstSensitiveInfo.py +++ b/python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstSensitiveInfo.py @@ -5,6 +5,7 @@ """ from flask import Flask from flask import request +from django.utils.crypto import constant_time_compare app = Flask(__name__) @@ -19,17 +20,6 @@ def good(): if request.method == 'POST': password = request.form['pwd'] return constant_time_string_compare(password, "1234") - -def constant_time_string_compare(a, b): - if len(a) != len(b): - return False - - result = 0 - - for x, y in zip(a, b): - result |= ord(x) ^ ord(y) - - return result == 0 if __name__ == '__main__': app.debug = True From 7d23b8058247e354aeda13d9259a5e2c5615de15 Mon Sep 17 00:00:00 2001 From: Ahmed Farid Date: Mon, 15 Aug 2022 11:29:09 +0100 Subject: [PATCH 087/631] Update TimingAttackAgainstHash.py --- .../Security/CWE-208/TimingAttackAgainstHash.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstHash.py b/python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstHash.py index 8d2c331d03c..1209858ea04 100644 --- a/python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstHash.py +++ b/python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstHash.py @@ -17,3 +17,14 @@ def verify1(msg, sig): def verify2(msg, sig): return sig == sign(key, msg, hashlib.sha256) #bad + +def constant_time_string_compare(a, b): + if len(a) != len(b): + return False + + result = 0 + + for x, y in zip(a, b): + result |= ord(x) ^ ord(y) + + return result == 0 From 18b103dbd5b22fd63183f4cad4cdb64096e0aa53 Mon Sep 17 00:00:00 2001 From: Ahmed Farid Date: Mon, 15 Aug 2022 11:29:29 +0100 Subject: [PATCH 088/631] Update TimingAttackAgainstHash.py --- .../query-tests/Security/CWE-208/TimingAttackAgainstHash.py | 1 - 1 file changed, 1 deletion(-) diff --git a/python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstHash.py b/python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstHash.py index 1209858ea04..d48904ee719 100644 --- a/python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstHash.py +++ b/python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstHash.py @@ -5,7 +5,6 @@ """ import hashlib import hmac -from django.utils.crypto import constant_time_compare key = "e179017a-62b0-4996-8a38-e91aa9f1" From a724bd1e32e50712ee7275d8fc79cecc3e63bd3f Mon Sep 17 00:00:00 2001 From: Ahmed Farid Date: Mon, 15 Aug 2022 14:42:17 +0100 Subject: [PATCH 089/631] Update UnSafeComparisonOfSensitiveInfo.py --- .../UnSafeComparisonOfSensitiveInfo.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstSensitiveInfo/UnSafeComparisonOfSensitiveInfo.py b/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstSensitiveInfo/UnSafeComparisonOfSensitiveInfo.py index d01fe61a62e..58366b64891 100644 --- a/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstSensitiveInfo/UnSafeComparisonOfSensitiveInfo.py +++ b/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstSensitiveInfo/UnSafeComparisonOfSensitiveInfo.py @@ -7,9 +7,11 @@ from flask import Flask from flask import request -@app.route('/bad') -def check_credentials(password): - return password == "token" +@app.route('/bad', methods = ['POST', 'GET']) +def bad(password): + if request.method == 'POST': + password = request.form['pwd'] + return password == "test" if __name__ == '__main__': app.debug = True From 773bb5fffd3cea938e916bd61fe884e3ae4a1c11 Mon Sep 17 00:00:00 2001 From: Ahmed Farid Date: Mon, 15 Aug 2022 14:43:32 +0100 Subject: [PATCH 090/631] Update SafeComparisonOfHeaderValue.py --- .../SafeComparisonOfHeaderValue.py | 1 + 1 file changed, 1 insertion(+) diff --git a/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHeaderValue/SafeComparisonOfHeaderValue.py b/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHeaderValue/SafeComparisonOfHeaderValue.py index 15c6a841d34..e60b7f84fac 100644 --- a/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHeaderValue/SafeComparisonOfHeaderValue.py +++ b/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHeaderValue/SafeComparisonOfHeaderValue.py @@ -7,6 +7,7 @@ from flask import Flask from flask import request +import hmac @app.route('/good') def good1(): From c578a3489240a50443cec649e37c4c0285de2459 Mon Sep 17 00:00:00 2001 From: Ahmed Farid Date: Mon, 15 Aug 2022 15:12:38 +0100 Subject: [PATCH 091/631] Update SafeComparisonOfHeaderValue.py --- .../SafeComparisonOfHeaderValue.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHeaderValue/SafeComparisonOfHeaderValue.py b/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHeaderValue/SafeComparisonOfHeaderValue.py index e60b7f84fac..d5eca98ca3e 100644 --- a/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHeaderValue/SafeComparisonOfHeaderValue.py +++ b/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHeaderValue/SafeComparisonOfHeaderValue.py @@ -10,7 +10,7 @@ from flask import request import hmac @app.route('/good') -def good1(): +def good(): secret = request.headers.get('X-Auth-Token') if not hmac.compare_digest(secret, "token"): raise Exception('bad token') From 054e0726b074228f8125508c0c08f96c647ba4e9 Mon Sep 17 00:00:00 2001 From: Ahmed Farid Date: Mon, 15 Aug 2022 15:13:17 +0100 Subject: [PATCH 092/631] Update UnsafeComparisonOfHeaderValue.py --- .../UnsafeComparisonOfHeaderValue.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHeaderValue/UnsafeComparisonOfHeaderValue.py b/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHeaderValue/UnsafeComparisonOfHeaderValue.py index f4a732a4f51..91bfadac9e5 100644 --- a/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHeaderValue/UnsafeComparisonOfHeaderValue.py +++ b/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHeaderValue/UnsafeComparisonOfHeaderValue.py @@ -9,7 +9,7 @@ from flask import Flask from flask import request @app.route('/bad') -def good1(): +def bad(): secret = request.headers.get('X-Auth-Token') if secret == "token": raise Exception('bad token') From 8ebf4280789a23b7384b75246d3ad7c72b0f9e64 Mon Sep 17 00:00:00 2001 From: Ahmed Farid Date: Mon, 15 Aug 2022 15:15:24 +0100 Subject: [PATCH 093/631] Update SafeComparisonOfSensitiveInfo.py --- .../SafeComparisonOfSensitiveInfo.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstSensitiveInfo/SafeComparisonOfSensitiveInfo.py b/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstSensitiveInfo/SafeComparisonOfSensitiveInfo.py index 4ef45cca269..051fc38701d 100644 --- a/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstSensitiveInfo/SafeComparisonOfSensitiveInfo.py +++ b/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstSensitiveInfo/SafeComparisonOfSensitiveInfo.py @@ -4,14 +4,14 @@ """ @Desc :preventing timing attack sensitive info """ -import hmac from flask import Flask from flask import request +import hmac -@app.route('/good') -def check_credentials(password): - return hmac.compare_digest(password, "token") - -if __name__ == '__main__': - app.debug = True - app.run() +app = Flask(__name__) + +@app.route('/bad', methods = ['POST', 'GET']) +def bad(): + if request.method == 'POST': + password = request.form['pwd'] + return hmac.compare_digest(password, "1234") From f2bf58bdb654989d7ef7db0cc83116743b04f43a Mon Sep 17 00:00:00 2001 From: Ahmed Farid Date: Mon, 15 Aug 2022 15:16:30 +0100 Subject: [PATCH 094/631] Update TimingAttackAgainstSensitiveInfo.py --- .../Security/CWE-208/TimingAttackAgainstSensitiveInfo.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstSensitiveInfo.py b/python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstSensitiveInfo.py index 5db572f5486..a34b3b7c5ae 100644 --- a/python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstSensitiveInfo.py +++ b/python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstSensitiveInfo.py @@ -19,7 +19,7 @@ def bad(): def good(): if request.method == 'POST': password = request.form['pwd'] - return constant_time_string_compare(password, "1234") + return constant_time_compare(password, "1234") if __name__ == '__main__': app.debug = True From dbd60767255a6e28008fd79f820e7a99f50e3fe4 Mon Sep 17 00:00:00 2001 From: Ahmed Farid Date: Mon, 15 Aug 2022 15:18:09 +0100 Subject: [PATCH 095/631] Update SafeComparisonOfSensitiveInfo.py --- .../SafeComparisonOfSensitiveInfo.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstSensitiveInfo/SafeComparisonOfSensitiveInfo.py b/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstSensitiveInfo/SafeComparisonOfSensitiveInfo.py index 051fc38701d..d6be8c0c478 100644 --- a/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstSensitiveInfo/SafeComparisonOfSensitiveInfo.py +++ b/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstSensitiveInfo/SafeComparisonOfSensitiveInfo.py @@ -15,3 +15,7 @@ def bad(): if request.method == 'POST': password = request.form['pwd'] return hmac.compare_digest(password, "1234") + +if __name__ == '__main__': + app.debug = True + app.run() From 169d27951a562ccccbb8c392fce27696962c25e7 Mon Sep 17 00:00:00 2001 From: Ahmed Farid Date: Mon, 15 Aug 2022 15:19:13 +0100 Subject: [PATCH 096/631] Update UnSafeComparisonOfSensitiveInfo.py --- .../UnSafeComparisonOfSensitiveInfo.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstSensitiveInfo/UnSafeComparisonOfSensitiveInfo.py b/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstSensitiveInfo/UnSafeComparisonOfSensitiveInfo.py index 58366b64891..3438c45b6c0 100644 --- a/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstSensitiveInfo/UnSafeComparisonOfSensitiveInfo.py +++ b/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstSensitiveInfo/UnSafeComparisonOfSensitiveInfo.py @@ -8,7 +8,7 @@ from flask import Flask from flask import request @app.route('/bad', methods = ['POST', 'GET']) -def bad(password): +def bad(): if request.method == 'POST': password = request.form['pwd'] return password == "test" From 5ecadd06ae8a2e7723e0476027383d823b4cbf5f Mon Sep 17 00:00:00 2001 From: Ahmed Farid Date: Mon, 15 Aug 2022 15:21:10 +0100 Subject: [PATCH 097/631] Update TimingAttackAgainstHash.py --- .../query-tests/Security/CWE-208/TimingAttackAgainstHash.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstHash.py b/python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstHash.py index d48904ee719..db068312c9f 100644 --- a/python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstHash.py +++ b/python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstHash.py @@ -11,10 +11,10 @@ key = "e179017a-62b0-4996-8a38-e91aa9f1" def sign(pre_key, msg, alg): return hmac.new(pre_key, msg, alg).digest() -def verify1(msg, sig): +def VerifyGood(msg, sig): return constant_time_string_compare(sig, sign(key, msg, hashlib.sha256)) #good -def verify2(msg, sig): +def verifyBad(msg, sig): return sig == sign(key, msg, hashlib.sha256) #bad def constant_time_string_compare(a, b): From c85ad1b2c03eb315b11d23166550b7e42d95591e Mon Sep 17 00:00:00 2001 From: Ahmed Farid Date: Tue, 16 Aug 2022 11:50:37 +0100 Subject: [PATCH 098/631] Update TimingAttackAgainstHash.py --- .../query-tests/Security/CWE-208/TimingAttackAgainstHash.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstHash.py b/python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstHash.py index db068312c9f..c7730ef69b2 100644 --- a/python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstHash.py +++ b/python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstHash.py @@ -11,7 +11,7 @@ key = "e179017a-62b0-4996-8a38-e91aa9f1" def sign(pre_key, msg, alg): return hmac.new(pre_key, msg, alg).digest() -def VerifyGood(msg, sig): +def verifyGood(msg, sig): return constant_time_string_compare(sig, sign(key, msg, hashlib.sha256)) #good def verifyBad(msg, sig): From 68cf084b8fc56ae252ac2c4ff99cf3342b4af986 Mon Sep 17 00:00:00 2001 From: Ahmed Farid Date: Tue, 16 Aug 2022 12:03:14 +0100 Subject: [PATCH 099/631] Update TimingAttackAgainstSensitiveInfo.expected --- .../CWE-208/TimingAttackAgainstSensitiveInfo.expected | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstSensitiveInfo.expected b/python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstSensitiveInfo.expected index 4dc0ff5843c..63d5e8ad821 100644 --- a/python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstSensitiveInfo.expected +++ b/python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstSensitiveInfo.expected @@ -1,6 +1,6 @@ edges nodes -| TimingAttackAgainstSensitiveInfo.py:15:16:15:23 | ControlFlowNode for password | semmle.label | ControlFlowNode for password | +| TimingAttackAgainstSensitiveInfo.py:16:16:16:23 | ControlFlowNode for password | semmle.label | ControlFlowNode for password | subpaths #select -| TimingAttackAgainstSensitiveInfo.py:15:16:15:23 | ControlFlowNode for password | TimingAttackAgainstSensitiveInfo.py:15:16:15:23 | ControlFlowNode for password | TimingAttackAgainstSensitiveInfo.py:15:16:15:23 | ControlFlowNode for password | Timing attack against $@ validation. | TimingAttackAgainstSensitiveInfo.py:15:16:15:23 | ControlFlowNode for password | client-supplied token | +| TimingAttackAgainstSensitiveInfo.py:16:16:16:23 | ControlFlowNode for password | TimingAttackAgainstSensitiveInfo.py:16:16:16:23 | ControlFlowNode for password | TimingAttackAgainstSensitiveInfo.py:16:16:16:23 | ControlFlowNode for password | Timing attack against $@ validation. | TimingAttackAgainstSensitiveInfo.py:16:16:16:23 | ControlFlowNode for password | client-supplied token | From abc49bd62b29afed5f260c4d825080edf4bb092c Mon Sep 17 00:00:00 2001 From: Ahmed Farid Date: Tue, 16 Aug 2022 12:06:34 +0100 Subject: [PATCH 100/631] Update TimingAttackAgainstHeader.py --- .../query-tests/Security/CWE-208/TimingAttackAgainstHeader.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstHeader.py b/python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstHeader.py index 43c34c4976c..211c36274d7 100644 --- a/python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstHeader.py +++ b/python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstHeader.py @@ -17,8 +17,8 @@ def bad(): @app.route('/good') def good(): - Secret = request.headers.get('X-Auth-Token') - if not hmac.compare_digest(Secret, "token"): + tok = request.headers.get('X-Auth-Token') + if not hmac.compare_digest(tok, "token"): raise Exception('bad token') return 'good' From 74f68aa60ad5bc09d6bcb3bd5413aa7032f204e1 Mon Sep 17 00:00:00 2001 From: Ahmed Farid Date: Tue, 16 Aug 2022 12:20:52 +0100 Subject: [PATCH 101/631] Update TimingAttackAgainstHeader.expected From 44f054bedee0ec92ada54aab0285c999ed48c4a2 Mon Sep 17 00:00:00 2001 From: Ahmed Farid Date: Tue, 16 Aug 2022 12:31:33 +0100 Subject: [PATCH 102/631] Update PossibleTimingAttackAgainstHash.expected --- .../CWE-208/PossibleTimingAttackAgainstHash.expected | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/python/ql/test/experimental/query-tests/Security/CWE-208/PossibleTimingAttackAgainstHash.expected b/python/ql/test/experimental/query-tests/Security/CWE-208/PossibleTimingAttackAgainstHash.expected index 978bcdbac6f..8fdcb13b9b7 100644 --- a/python/ql/test/experimental/query-tests/Security/CWE-208/PossibleTimingAttackAgainstHash.expected +++ b/python/ql/test/experimental/query-tests/Security/CWE-208/PossibleTimingAttackAgainstHash.expected @@ -1,8 +1,8 @@ edges -| TimingAttackAgainstHash.py:13:12:13:47 | ControlFlowNode for Attribute() | TimingAttackAgainstHash.py:19:19:19:48 | ControlFlowNode for sign() | +| TimingAttackAgainstHash.py:12:12:12:47 | ControlFlowNode for Attribute() | TimingAttackAgainstHash.py:18:19:18:48 | ControlFlowNode for sign() | nodes -| TimingAttackAgainstHash.py:13:12:13:47 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | -| TimingAttackAgainstHash.py:19:19:19:48 | ControlFlowNode for sign() | semmle.label | ControlFlowNode for sign() | +| TimingAttackAgainstHash.py:12:12:12:47 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | +| TimingAttackAgainstHash.py:18:19:18:48 | ControlFlowNode for sign() | semmle.label | ControlFlowNode for sign() | subpaths #select -| TimingAttackAgainstHash.py:19:19:19:48 | ControlFlowNode for sign() | TimingAttackAgainstHash.py:13:12:13:47 | ControlFlowNode for Attribute() | TimingAttackAgainstHash.py:19:19:19:48 | ControlFlowNode for sign() | Timing attack against $@ validation. | TimingAttackAgainstHash.py:13:12:13:47 | ControlFlowNode for Attribute() | TimingAttackAgainstHash.py:13:12:13:47 | ControlFlowNode for Attribute() | +| TimingAttackAgainstHash.py:18:19:18:48 | ControlFlowNode for sign() | TimingAttackAgainstHash.py:12:12:12:47 | ControlFlowNode for Attribute() | TimingAttackAgainstHash.py:18:19:18:48 | ControlFlowNode for sign() | Possible Timing attack against $@ validation. | TimingAttackAgainstHash.py:12:12:12:47 | ControlFlowNode for Attribute() | TimingAttackAgainstHash.py:12:12:12:47 | ControlFlowNode for Attribute() | From abcfb1cd6310025b4be07919be182bf479450e82 Mon Sep 17 00:00:00 2001 From: Ahmed Farid Date: Tue, 16 Aug 2022 12:33:19 +0100 Subject: [PATCH 103/631] Update TimingAttack.qll --- .../ql/src/experimental/semmle/python/security/TimingAttack.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/ql/src/experimental/semmle/python/security/TimingAttack.qll b/python/ql/src/experimental/semmle/python/security/TimingAttack.qll index f42ff4a7264..9f08e873e78 100644 --- a/python/ql/src/experimental/semmle/python/security/TimingAttack.qll +++ b/python/ql/src/experimental/semmle/python/security/TimingAttack.qll @@ -80,7 +80,7 @@ private string suspicious() { result = [ "%password%", "%passwd%", "%pwd%", "%refresh%token%", "%secret%token", "%secret%key", - "%passcode%", "%passphrase%", "%token%", "%secret%", "%credential%", "%key%", "%UserPass%" + "%passcode%", "%passphrase%", "%token%", "%secret%", "%credential%", "%UserPass%" ] } From 1dd4400c673094a4da8c38fa3a903e62cfbfbc0b Mon Sep 17 00:00:00 2001 From: Ahmed Farid Date: Tue, 16 Aug 2022 13:33:17 +0100 Subject: [PATCH 104/631] Update PossibleTimingAttackAgainstHash.qlref --- .../Security/CWE-208/PossibleTimingAttackAgainstHash.qlref | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/ql/test/experimental/query-tests/Security/CWE-208/PossibleTimingAttackAgainstHash.qlref b/python/ql/test/experimental/query-tests/Security/CWE-208/PossibleTimingAttackAgainstHash.qlref index 11452a116c9..73a8e6960ef 100644 --- a/python/ql/test/experimental/query-tests/Security/CWE-208/PossibleTimingAttackAgainstHash.qlref +++ b/python/ql/test/experimental/query-tests/Security/CWE-208/PossibleTimingAttackAgainstHash.qlref @@ -1 +1 @@ -experimental/Security/CWE/CWE-208/PossibleTimingAttackAgainstHash.ql +experimental/Security/CWE-208/TimingAttackAgainstHash/PossibleTimingAttackAgainstHash.ql From ecbe663c2fe1f1e5046a33abb84d4aff3f94a47d Mon Sep 17 00:00:00 2001 From: Ahmed Farid Date: Tue, 16 Aug 2022 13:34:24 +0100 Subject: [PATCH 105/631] Update TimingAttackAgainstSensitiveInfo.qlref --- .../Security/CWE-208/TimingAttackAgainstSensitiveInfo.qlref | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstSensitiveInfo.qlref b/python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstSensitiveInfo.qlref index c6d983ebaf5..acfe13f6aad 100644 --- a/python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstSensitiveInfo.qlref +++ b/python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstSensitiveInfo.qlref @@ -1 +1 @@ -experimental/Security/CWE/CWE-208/TimingAttackAgainstSensitiveInfo.ql +experimental/Security/CWE-208/TimingAttackAgainstSensitiveInfo/PossibleTimingAttackAgainstSensitiveInfo.ql From e8376a522ceed53113c330ccecde2aeb0a5191d2 Mon Sep 17 00:00:00 2001 From: Ahmed Farid Date: Tue, 16 Aug 2022 13:35:20 +0100 Subject: [PATCH 106/631] Update TimingAttackAgainstHeaderValue.qlref --- .../Security/CWE-208/TimingAttackAgainstHeaderValue.qlref | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstHeaderValue.qlref b/python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstHeaderValue.qlref index 7e6067274e2..9da35da9d6d 100644 --- a/python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstHeaderValue.qlref +++ b/python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstHeaderValue.qlref @@ -1 +1 @@ -experimental/Security/CWE/CWE-208/TimingAttackAgainstHeaderValue.ql +experimental/Security/CWE-208/TimingAttackAgainstHeaderValue/TimingAttackAgainstHeaderValue.ql From 67476d0a3672bd34d62038a6a74393e097fd4a77 Mon Sep 17 00:00:00 2001 From: Ahmed Farid Date: Tue, 16 Aug 2022 13:36:59 +0100 Subject: [PATCH 107/631] Rename TimingAttackAgainstSensitiveInfo.qlref to PossibleTimingAttackAgainstSensitiveInfo.qlref --- ...eInfo.qlref => PossibleTimingAttackAgainstSensitiveInfo.qlref} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename python/ql/test/experimental/query-tests/Security/CWE-208/{TimingAttackAgainstSensitiveInfo.qlref => PossibleTimingAttackAgainstSensitiveInfo.qlref} (100%) diff --git a/python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstSensitiveInfo.qlref b/python/ql/test/experimental/query-tests/Security/CWE-208/PossibleTimingAttackAgainstSensitiveInfo.qlref similarity index 100% rename from python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstSensitiveInfo.qlref rename to python/ql/test/experimental/query-tests/Security/CWE-208/PossibleTimingAttackAgainstSensitiveInfo.qlref From d8719f3b1f2c68f2a8d5ee491e194b15f349bc04 Mon Sep 17 00:00:00 2001 From: Ahmed Farid Date: Tue, 16 Aug 2022 14:50:21 +0100 Subject: [PATCH 108/631] Rename TimingAttackAgainstSensitiveInfo.expected to PossibleTimingAttackAgainstSensitiveInfo.expected --- ...expected => PossibleTimingAttackAgainstSensitiveInfo.expected} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename python/ql/test/experimental/query-tests/Security/CWE-208/{TimingAttackAgainstSensitiveInfo.expected => PossibleTimingAttackAgainstSensitiveInfo.expected} (100%) diff --git a/python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstSensitiveInfo.expected b/python/ql/test/experimental/query-tests/Security/CWE-208/PossibleTimingAttackAgainstSensitiveInfo.expected similarity index 100% rename from python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstSensitiveInfo.expected rename to python/ql/test/experimental/query-tests/Security/CWE-208/PossibleTimingAttackAgainstSensitiveInfo.expected From 31ecb0727fae01892c1535084d7e12801b22182b Mon Sep 17 00:00:00 2001 From: Ahmed Farid Date: Tue, 16 Aug 2022 14:50:54 +0100 Subject: [PATCH 109/631] Rename TimingAttackAgainstHeader.expected to TimingAttackAgainstHeaderValue.expected --- ...nstHeader.expected => TimingAttackAgainstHeaderValue.expected} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename python/ql/test/experimental/query-tests/Security/CWE-208/{TimingAttackAgainstHeader.expected => TimingAttackAgainstHeaderValue.expected} (100%) diff --git a/python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstHeader.expected b/python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstHeaderValue.expected similarity index 100% rename from python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstHeader.expected rename to python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstHeaderValue.expected From 6a94d45643ee49cc8a982b361eacc0ad0fc01d93 Mon Sep 17 00:00:00 2001 From: Ahmed Farid Date: Tue, 16 Aug 2022 16:26:45 +0100 Subject: [PATCH 110/631] Rename python/ql/test/experimental/query-tests/Security/CWE-208/PossibleTimingAttackAgainstHash.expected to python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstHash/PossibleTimingAttackAgainstHash.expected --- .../PossibleTimingAttackAgainstHash.expected | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename python/ql/test/experimental/query-tests/Security/CWE-208/{ => TimingAttackAgainstHash}/PossibleTimingAttackAgainstHash.expected (100%) diff --git a/python/ql/test/experimental/query-tests/Security/CWE-208/PossibleTimingAttackAgainstHash.expected b/python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstHash/PossibleTimingAttackAgainstHash.expected similarity index 100% rename from python/ql/test/experimental/query-tests/Security/CWE-208/PossibleTimingAttackAgainstHash.expected rename to python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstHash/PossibleTimingAttackAgainstHash.expected From fa3940f69a722d606bea50d40d92c7fcadb8b792 Mon Sep 17 00:00:00 2001 From: Ahmed Farid Date: Tue, 16 Aug 2022 16:27:02 +0100 Subject: [PATCH 111/631] Rename python/ql/test/experimental/query-tests/Security/CWE-208/PossibleTimingAttackAgainstHash.qlref to python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstHash/PossibleTimingAttackAgainstHash.qlref --- .../PossibleTimingAttackAgainstHash.qlref | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename python/ql/test/experimental/query-tests/Security/CWE-208/{ => TimingAttackAgainstHash}/PossibleTimingAttackAgainstHash.qlref (100%) diff --git a/python/ql/test/experimental/query-tests/Security/CWE-208/PossibleTimingAttackAgainstHash.qlref b/python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstHash/PossibleTimingAttackAgainstHash.qlref similarity index 100% rename from python/ql/test/experimental/query-tests/Security/CWE-208/PossibleTimingAttackAgainstHash.qlref rename to python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstHash/PossibleTimingAttackAgainstHash.qlref From 87b67ed64f54f6f9da87ee262bc91d1233e48980 Mon Sep 17 00:00:00 2001 From: Ahmed Farid Date: Tue, 16 Aug 2022 16:27:19 +0100 Subject: [PATCH 112/631] Rename python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstHash.py to python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstHash/TimingAttackAgainstHash.py --- .../{ => TimingAttackAgainstHash}/TimingAttackAgainstHash.py | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename python/ql/test/experimental/query-tests/Security/CWE-208/{ => TimingAttackAgainstHash}/TimingAttackAgainstHash.py (100%) diff --git a/python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstHash.py b/python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstHash/TimingAttackAgainstHash.py similarity index 100% rename from python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstHash.py rename to python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstHash/TimingAttackAgainstHash.py From b8fe0e2eee1f096470db9663b3c04ac97a92f681 Mon Sep 17 00:00:00 2001 From: Ahmed Farid Date: Tue, 16 Aug 2022 16:27:45 +0100 Subject: [PATCH 113/631] Rename python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstHeader.py to python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstHeaderValue/TimingAttackAgainstHeader.py --- .../TimingAttackAgainstHeader.py | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename python/ql/test/experimental/query-tests/Security/CWE-208/{ => TimingAttackAgainstHeaderValue}/TimingAttackAgainstHeader.py (100%) diff --git a/python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstHeader.py b/python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstHeaderValue/TimingAttackAgainstHeader.py similarity index 100% rename from python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstHeader.py rename to python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstHeaderValue/TimingAttackAgainstHeader.py From 6536b602df768d95290346e7c792f11f031eed35 Mon Sep 17 00:00:00 2001 From: Ahmed Farid Date: Tue, 16 Aug 2022 16:28:00 +0100 Subject: [PATCH 114/631] Rename python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstHeaderValue.expected to python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstHeaderValue/TimingAttackAgainstHeaderValue.expected --- .../TimingAttackAgainstHeaderValue.expected | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename python/ql/test/experimental/query-tests/Security/CWE-208/{ => TimingAttackAgainstHeaderValue}/TimingAttackAgainstHeaderValue.expected (100%) diff --git a/python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstHeaderValue.expected b/python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstHeaderValue/TimingAttackAgainstHeaderValue.expected similarity index 100% rename from python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstHeaderValue.expected rename to python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstHeaderValue/TimingAttackAgainstHeaderValue.expected From f956fe12d56ed5f7fb7fcc6bc287ddf3802f6d6f Mon Sep 17 00:00:00 2001 From: Ahmed Farid Date: Tue, 16 Aug 2022 16:28:17 +0100 Subject: [PATCH 115/631] Rename python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstHeaderValue.qlref to python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstHeaderValue/TimingAttackAgainstHeaderValue.qlref --- .../TimingAttackAgainstHeaderValue.qlref | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename python/ql/test/experimental/query-tests/Security/CWE-208/{ => TimingAttackAgainstHeaderValue}/TimingAttackAgainstHeaderValue.qlref (100%) diff --git a/python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstHeaderValue.qlref b/python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstHeaderValue/TimingAttackAgainstHeaderValue.qlref similarity index 100% rename from python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstHeaderValue.qlref rename to python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstHeaderValue/TimingAttackAgainstHeaderValue.qlref From 2377880d0c77771f49bedde6ead24419e28d1186 Mon Sep 17 00:00:00 2001 From: Ahmed Farid Date: Tue, 16 Aug 2022 16:28:36 +0100 Subject: [PATCH 116/631] Rename python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstSensitiveInfo.py to python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstSensitiveInfo/TimingAttackAgainstSensitiveInfo.py --- .../TimingAttackAgainstSensitiveInfo.py | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename python/ql/test/experimental/query-tests/Security/CWE-208/{ => TimingAttackAgainstSensitiveInfo}/TimingAttackAgainstSensitiveInfo.py (100%) diff --git a/python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstSensitiveInfo.py b/python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstSensitiveInfo/TimingAttackAgainstSensitiveInfo.py similarity index 100% rename from python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstSensitiveInfo.py rename to python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstSensitiveInfo/TimingAttackAgainstSensitiveInfo.py From 685cd97b8e17cb0755700872d832bf2d15ea88f4 Mon Sep 17 00:00:00 2001 From: Ahmed Farid Date: Tue, 16 Aug 2022 16:28:51 +0100 Subject: [PATCH 117/631] Rename python/ql/test/experimental/query-tests/Security/CWE-208/PossibleTimingAttackAgainstSensitiveInfo.expected to python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstSensitiveInfo/PossibleTimingAttackAgainstSensitiveInfo.expected --- .../PossibleTimingAttackAgainstSensitiveInfo.expected | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename python/ql/test/experimental/query-tests/Security/CWE-208/{ => TimingAttackAgainstSensitiveInfo}/PossibleTimingAttackAgainstSensitiveInfo.expected (100%) diff --git a/python/ql/test/experimental/query-tests/Security/CWE-208/PossibleTimingAttackAgainstSensitiveInfo.expected b/python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstSensitiveInfo/PossibleTimingAttackAgainstSensitiveInfo.expected similarity index 100% rename from python/ql/test/experimental/query-tests/Security/CWE-208/PossibleTimingAttackAgainstSensitiveInfo.expected rename to python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstSensitiveInfo/PossibleTimingAttackAgainstSensitiveInfo.expected From 9cb7a0ac2e4af01faa769f7fbe77337e3dd78ca6 Mon Sep 17 00:00:00 2001 From: Ahmed Farid Date: Tue, 16 Aug 2022 16:29:05 +0100 Subject: [PATCH 118/631] Rename python/ql/test/experimental/query-tests/Security/CWE-208/PossibleTimingAttackAgainstSensitiveInfo.qlref to python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstSensitiveInfo/PossibleTimingAttackAgainstSensitiveInfo.qlref --- .../PossibleTimingAttackAgainstSensitiveInfo.qlref | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename python/ql/test/experimental/query-tests/Security/CWE-208/{ => TimingAttackAgainstSensitiveInfo}/PossibleTimingAttackAgainstSensitiveInfo.qlref (100%) diff --git a/python/ql/test/experimental/query-tests/Security/CWE-208/PossibleTimingAttackAgainstSensitiveInfo.qlref b/python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstSensitiveInfo/PossibleTimingAttackAgainstSensitiveInfo.qlref similarity index 100% rename from python/ql/test/experimental/query-tests/Security/CWE-208/PossibleTimingAttackAgainstSensitiveInfo.qlref rename to python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstSensitiveInfo/PossibleTimingAttackAgainstSensitiveInfo.qlref From 10d5ab20f549d0fe4241b806731eadb99116716a Mon Sep 17 00:00:00 2001 From: Ahmed Farid Date: Wed, 17 Aug 2022 12:19:02 +0100 Subject: [PATCH 119/631] fix qhelp --- .../TimingAttackAgainstHash/TimingAttackAgainstHash.qhelp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHash/TimingAttackAgainstHash.qhelp b/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHash/TimingAttackAgainstHash.qhelp index 2602a5a0cca..5f1b1feb8e3 100644 --- a/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHash/TimingAttackAgainstHash.qhelp +++ b/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHash/TimingAttackAgainstHash.qhelp @@ -28,7 +28,7 @@ and does not depend on the contents of the arrays.

    The following example uses == which is a fail fast check for validating a Hash.

    - +

    The next example use a safe constant-time algorithm for validating a Hash: From 01828936e21de6f20766735291eb13bf1299e4fa Mon Sep 17 00:00:00 2001 From: Ahmed Farid Date: Wed, 17 Aug 2022 12:19:44 +0100 Subject: [PATCH 120/631] fix qhelp --- .../TimingAttackAgainstSensitiveInfo.qhelp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstSensitiveInfo/TimingAttackAgainstSensitiveInfo.qhelp b/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstSensitiveInfo/TimingAttackAgainstSensitiveInfo.qhelp index 683af727470..dd6d2de2573 100644 --- a/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstSensitiveInfo/TimingAttackAgainstSensitiveInfo.qhelp +++ b/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstSensitiveInfo/TimingAttackAgainstSensitiveInfo.qhelp @@ -29,7 +29,7 @@ and does not depend on the contents of the arrays.

    The following example uses == which is a fail fast check for validating a secret.

    - +

    The next example use a safe constant-time algorithm for validating a secret: From 5daeea7aebe2e1abf7085a073b2efe5709a328cc Mon Sep 17 00:00:00 2001 From: Ahmed Farid Date: Wed, 17 Aug 2022 12:24:40 +0100 Subject: [PATCH 121/631] Adjust the @id property --- .../TimingAttackAgainstHash/PossibleTimingAttackAgainstHash.ql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHash/PossibleTimingAttackAgainstHash.ql b/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHash/PossibleTimingAttackAgainstHash.ql index 6c757a91ec6..6659d562633 100644 --- a/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHash/PossibleTimingAttackAgainstHash.ql +++ b/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHash/PossibleTimingAttackAgainstHash.ql @@ -7,7 +7,7 @@ * @kind path-problem * @problem.severity error * @precision medium - * @id py/timing-attack-against-Hash + * @id py/timing-attack-against-hash * @tags security * external/cwe/cwe-208 */ From b29ca57ce19a1cbaa825ecd2dbc3cf7d9e266af3 Mon Sep 17 00:00:00 2001 From: Ahmed Farid Date: Wed, 17 Aug 2022 12:46:57 +0100 Subject: [PATCH 122/631] Autoformat TimingAttack.qll --- .../src/experimental/semmle/python/security/TimingAttack.qll | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/python/ql/src/experimental/semmle/python/security/TimingAttack.qll b/python/ql/src/experimental/semmle/python/security/TimingAttack.qll index 9f08e873e78..981dc46dcc6 100644 --- a/python/ql/src/experimental/semmle/python/security/TimingAttack.qll +++ b/python/ql/src/experimental/semmle/python/security/TimingAttack.qll @@ -51,9 +51,7 @@ private predicate existsFailFastCheck(Expr firstInput, Expr secondInput) { class NonConstantTimeComparisonSink extends DataFlow::Node { Expr anotherParameter; - NonConstantTimeComparisonSink() { - existsFailFastCheck(this.asExpr(), anotherParameter) - } + NonConstantTimeComparisonSink() { existsFailFastCheck(this.asExpr(), anotherParameter) } /** Holds if remote user input was used in the comparison. */ predicate includesUserInput() { @@ -195,3 +193,4 @@ class UserInputInComparisonConfig extends TaintTracking2::Configuration { ) } } + From 9b4d1789b1e3f3696c7ccf409a78e67c2c8503bb Mon Sep 17 00:00:00 2001 From: Ahmed Farid Date: Wed, 17 Aug 2022 12:49:58 +0100 Subject: [PATCH 123/631] Autoformat TimingAttackAgainstHash.ql --- .../TimingAttackAgainstHash/TimingAttackAgainstHash.ql | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHash/TimingAttackAgainstHash.ql b/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHash/TimingAttackAgainstHash.ql index b2266f21095..e4db280b581 100644 --- a/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHash/TimingAttackAgainstHash.ql +++ b/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHash/TimingAttackAgainstHash.ql @@ -31,6 +31,9 @@ class TimingAttackAgainsthash extends TaintTracking::Configuration { } from TimingAttackAgainsthash config, DataFlow::PathNode source, DataFlow::PathNode sink -where config.hasFlowPath(source, sink) and sink.getNode().(NonConstantTimeComparisonSink).includesUserInput() +where + config.hasFlowPath(source, sink) and + sink.getNode().(NonConstantTimeComparisonSink).includesUserInput() select sink.getNode(), source, sink, "Timing attack against $@ validation.", source, source.getNode() + From a7dcf96f553c7719d7c80ae3894bec18eea9b758 Mon Sep 17 00:00:00 2001 From: Ahmed Farid Date: Wed, 17 Aug 2022 12:53:07 +0100 Subject: [PATCH 124/631] Autoformat TimingAttackAgainstSensitiveInfo.ql --- .../TimingAttackAgainstSensitiveInfo.ql | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstSensitiveInfo/TimingAttackAgainstSensitiveInfo.ql b/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstSensitiveInfo/TimingAttackAgainstSensitiveInfo.ql index 9e7b0a82be5..ca24a35fed2 100644 --- a/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstSensitiveInfo/TimingAttackAgainstSensitiveInfo.ql +++ b/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstSensitiveInfo/TimingAttackAgainstSensitiveInfo.ql @@ -28,7 +28,7 @@ class ClientSuppliedSecretConfig extends TaintTracking::Configuration { } from ClientSuppliedSecretConfig config, DataFlow::PathNode source, DataFlow::PathNode sink -where +where config.hasFlowPath(source, sink) and ( source.getNode().(SecretSource).includesUserInput() or @@ -36,3 +36,4 @@ where ) select sink.getNode(), source, sink, "Timing attack against $@ validation.", source.getNode(), "client-supplied token" + From cb5331bdd8c62ffa05a4e82a9c83ba77a5024421 Mon Sep 17 00:00:00 2001 From: Ahmed Farid Date: Wed, 17 Aug 2022 12:54:34 +0100 Subject: [PATCH 125/631] Autoformat TimingAttackAgainstHeaderValue.ql --- .../TimingAttackAgainstHeaderValue.ql | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHeaderValue/TimingAttackAgainstHeaderValue.ql b/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHeaderValue/TimingAttackAgainstHeaderValue.ql index 00a64744aef..bcf9369ee37 100644 --- a/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHeaderValue/TimingAttackAgainstHeaderValue.ql +++ b/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHeaderValue/TimingAttackAgainstHeaderValue.ql @@ -24,12 +24,12 @@ class ClientSuppliedSecretConfig extends TaintTracking::Configuration { override predicate isSource(DataFlow::Node source) { source instanceof ClientSuppliedsecret } - override predicate isSink(DataFlow::Node sink) { + override predicate isSink(DataFlow::Node sink) { exists(Compare cmp, Expr left, Expr right, Cmpop cmpop | cmpop.getSymbol() = ["==", "in", "is not", "!="] and cmp.compares(left, cmpop, right) and sink.asExpr() = [left, right] - ) + ) } } @@ -37,3 +37,4 @@ from ClientSuppliedSecretConfig config, DataFlow::PathNode source, DataFlow::Pat where config.hasFlowPath(source, sink) select sink.getNode(), source, sink, "Timing attack against $@ validation.", source.getNode(), "client-supplied token" + From 9f3de035c7e3ecefc14dd4d3fcdcef7951365de7 Mon Sep 17 00:00:00 2001 From: Ahmed Farid Date: Wed, 17 Aug 2022 12:57:57 +0100 Subject: [PATCH 126/631] Autoformat PossibleTimingAttackAgainstHash.ql --- .../TimingAttackAgainstHash/PossibleTimingAttackAgainstHash.ql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHash/PossibleTimingAttackAgainstHash.ql b/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHash/PossibleTimingAttackAgainstHash.ql index 6659d562633..8c8c9938e15 100644 --- a/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHash/PossibleTimingAttackAgainstHash.ql +++ b/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHash/PossibleTimingAttackAgainstHash.ql @@ -15,7 +15,6 @@ import python import semmle.python.dataflow.new.DataFlow import semmle.python.dataflow.new.TaintTracking -import semmle.python.ApiGraphs import experimental.semmle.python.security.TimingAttack import DataFlow::PathGraph @@ -35,3 +34,4 @@ from PossibleTimingAttackAgainstHash config, DataFlow::PathNode source, DataFlow where config.hasFlowPath(source, sink) select sink.getNode(), source, sink, "Possible Timing attack against $@ validation.", source, source.getNode() + From 313dbc9120a702b19db4cfafb4279e4951f56030 Mon Sep 17 00:00:00 2001 From: Ahmed Farid Date: Wed, 17 Aug 2022 12:59:09 +0100 Subject: [PATCH 127/631] Autoformat PossibleTimingAttackAgainstSensitiveInfo.ql --- .../PossibleTimingAttackAgainstSensitiveInfo.ql | 1 + 1 file changed, 1 insertion(+) diff --git a/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstSensitiveInfo/PossibleTimingAttackAgainstSensitiveInfo.ql b/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstSensitiveInfo/PossibleTimingAttackAgainstSensitiveInfo.ql index e4dcda45093..43b49d205be 100644 --- a/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstSensitiveInfo/PossibleTimingAttackAgainstSensitiveInfo.ql +++ b/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstSensitiveInfo/PossibleTimingAttackAgainstSensitiveInfo.ql @@ -31,3 +31,4 @@ from ClientSuppliedSecretConfig config, DataFlow::PathNode source, DataFlow::Pat where config.hasFlowPath(source, sink) select sink.getNode(), source, sink, "Timing attack against $@ validation.", source.getNode(), "client-supplied token" + From 76de2f42037bc632a96c4820ff5ebf1dbd1a6ccb Mon Sep 17 00:00:00 2001 From: Taus Date: Wed, 17 Aug 2022 15:12:51 +0000 Subject: [PATCH 128/631] Python: Remove trailing newlines These were causing the autoformatting check to fail. I'm not really sure how these newlines got introduced. Possibly some editor option or `git-commit` hook? --- .../TimingAttackAgainstHash/PossibleTimingAttackAgainstHash.ql | 1 - .../CWE-208/TimingAttackAgainstHash/TimingAttackAgainstHash.ql | 1 - .../TimingAttackAgainstHeaderValue.ql | 1 - .../PossibleTimingAttackAgainstSensitiveInfo.ql | 1 - .../TimingAttackAgainstSensitiveInfo.ql | 1 - .../ql/src/experimental/semmle/python/security/TimingAttack.qll | 1 - 6 files changed, 6 deletions(-) diff --git a/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHash/PossibleTimingAttackAgainstHash.ql b/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHash/PossibleTimingAttackAgainstHash.ql index 8c8c9938e15..3abd61836a8 100644 --- a/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHash/PossibleTimingAttackAgainstHash.ql +++ b/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHash/PossibleTimingAttackAgainstHash.ql @@ -34,4 +34,3 @@ from PossibleTimingAttackAgainstHash config, DataFlow::PathNode source, DataFlow where config.hasFlowPath(source, sink) select sink.getNode(), source, sink, "Possible Timing attack against $@ validation.", source, source.getNode() - diff --git a/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHash/TimingAttackAgainstHash.ql b/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHash/TimingAttackAgainstHash.ql index e4db280b581..8f098cec409 100644 --- a/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHash/TimingAttackAgainstHash.ql +++ b/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHash/TimingAttackAgainstHash.ql @@ -36,4 +36,3 @@ where sink.getNode().(NonConstantTimeComparisonSink).includesUserInput() select sink.getNode(), source, sink, "Timing attack against $@ validation.", source, source.getNode() - diff --git a/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHeaderValue/TimingAttackAgainstHeaderValue.ql b/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHeaderValue/TimingAttackAgainstHeaderValue.ql index bcf9369ee37..e2986100bbe 100644 --- a/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHeaderValue/TimingAttackAgainstHeaderValue.ql +++ b/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHeaderValue/TimingAttackAgainstHeaderValue.ql @@ -37,4 +37,3 @@ from ClientSuppliedSecretConfig config, DataFlow::PathNode source, DataFlow::Pat where config.hasFlowPath(source, sink) select sink.getNode(), source, sink, "Timing attack against $@ validation.", source.getNode(), "client-supplied token" - diff --git a/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstSensitiveInfo/PossibleTimingAttackAgainstSensitiveInfo.ql b/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstSensitiveInfo/PossibleTimingAttackAgainstSensitiveInfo.ql index 43b49d205be..e4dcda45093 100644 --- a/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstSensitiveInfo/PossibleTimingAttackAgainstSensitiveInfo.ql +++ b/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstSensitiveInfo/PossibleTimingAttackAgainstSensitiveInfo.ql @@ -31,4 +31,3 @@ from ClientSuppliedSecretConfig config, DataFlow::PathNode source, DataFlow::Pat where config.hasFlowPath(source, sink) select sink.getNode(), source, sink, "Timing attack against $@ validation.", source.getNode(), "client-supplied token" - diff --git a/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstSensitiveInfo/TimingAttackAgainstSensitiveInfo.ql b/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstSensitiveInfo/TimingAttackAgainstSensitiveInfo.ql index ca24a35fed2..2f6165753fc 100644 --- a/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstSensitiveInfo/TimingAttackAgainstSensitiveInfo.ql +++ b/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstSensitiveInfo/TimingAttackAgainstSensitiveInfo.ql @@ -36,4 +36,3 @@ where ) select sink.getNode(), source, sink, "Timing attack against $@ validation.", source.getNode(), "client-supplied token" - diff --git a/python/ql/src/experimental/semmle/python/security/TimingAttack.qll b/python/ql/src/experimental/semmle/python/security/TimingAttack.qll index 981dc46dcc6..df313b712e3 100644 --- a/python/ql/src/experimental/semmle/python/security/TimingAttack.qll +++ b/python/ql/src/experimental/semmle/python/security/TimingAttack.qll @@ -193,4 +193,3 @@ class UserInputInComparisonConfig extends TaintTracking2::Configuration { ) } } - From 3d17989107f44958d60b52413b3f966bba20e5eb Mon Sep 17 00:00:00 2001 From: Taus Date: Wed, 17 Aug 2022 17:09:18 +0000 Subject: [PATCH 129/631] Python: Fix broken `select` statement Based on the alert description, "message" seemed like a suitable word to use here. --- .../PossibleTimingAttackAgainstHash.ql | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHash/PossibleTimingAttackAgainstHash.ql b/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHash/PossibleTimingAttackAgainstHash.ql index 3abd61836a8..f8e791c96ba 100644 --- a/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHash/PossibleTimingAttackAgainstHash.ql +++ b/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHash/PossibleTimingAttackAgainstHash.ql @@ -32,5 +32,5 @@ class PossibleTimingAttackAgainstHash extends TaintTracking::Configuration { from PossibleTimingAttackAgainstHash config, DataFlow::PathNode source, DataFlow::PathNode sink where config.hasFlowPath(source, sink) -select sink.getNode(), source, sink, "Possible Timing attack against $@ validation.", source, - source.getNode() +select sink.getNode(), source, sink, "Possible Timing attack against $@ validation.", + source.getNode(), "message" From 687cd929032cf66c7ec05f970b2e5ced284af237 Mon Sep 17 00:00:00 2001 From: Taus Date: Fri, 19 Aug 2022 11:43:57 +0000 Subject: [PATCH 130/631] Python: Update `.expected` file --- .../PossibleTimingAttackAgainstHash.expected | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstHash/PossibleTimingAttackAgainstHash.expected b/python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstHash/PossibleTimingAttackAgainstHash.expected index 8fdcb13b9b7..dabc3f76a56 100644 --- a/python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstHash/PossibleTimingAttackAgainstHash.expected +++ b/python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstHash/PossibleTimingAttackAgainstHash.expected @@ -5,4 +5,4 @@ nodes | TimingAttackAgainstHash.py:18:19:18:48 | ControlFlowNode for sign() | semmle.label | ControlFlowNode for sign() | subpaths #select -| TimingAttackAgainstHash.py:18:19:18:48 | ControlFlowNode for sign() | TimingAttackAgainstHash.py:12:12:12:47 | ControlFlowNode for Attribute() | TimingAttackAgainstHash.py:18:19:18:48 | ControlFlowNode for sign() | Possible Timing attack against $@ validation. | TimingAttackAgainstHash.py:12:12:12:47 | ControlFlowNode for Attribute() | TimingAttackAgainstHash.py:12:12:12:47 | ControlFlowNode for Attribute() | +| TimingAttackAgainstHash.py:18:19:18:48 | ControlFlowNode for sign() | TimingAttackAgainstHash.py:12:12:12:47 | ControlFlowNode for Attribute() | TimingAttackAgainstHash.py:18:19:18:48 | ControlFlowNode for sign() | Possible Timing attack against $@ validation. | TimingAttackAgainstHash.py:12:12:12:47 | ControlFlowNode for Attribute() | message | From bd45ea94d0b3bf3659e63578135f00f7905aadfe Mon Sep 17 00:00:00 2001 From: Taus Date: Fri, 19 Aug 2022 12:31:12 +0000 Subject: [PATCH 131/631] Python: Fix `TimingAttackAgainstHash.ql` select --- .../TimingAttackAgainstHash/TimingAttackAgainstHash.ql | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHash/TimingAttackAgainstHash.ql b/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHash/TimingAttackAgainstHash.ql index 8f098cec409..c0ebdc285e8 100644 --- a/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHash/TimingAttackAgainstHash.ql +++ b/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHash/TimingAttackAgainstHash.ql @@ -34,5 +34,5 @@ from TimingAttackAgainsthash config, DataFlow::PathNode source, DataFlow::PathNo where config.hasFlowPath(source, sink) and sink.getNode().(NonConstantTimeComparisonSink).includesUserInput() -select sink.getNode(), source, sink, "Timing attack against $@ validation.", source, - source.getNode() +select sink.getNode(), source, sink, "Timing attack against $@ validation.", source.getNode(), + "message" From ee05e2ca761286e12a08ff718dfaee88a9c01b60 Mon Sep 17 00:00:00 2001 From: Ahmed Farid Date: Tue, 23 Aug 2022 12:27:20 +0100 Subject: [PATCH 132/631] add `x-gitlab-token` to sensitive headers --- .../ql/src/experimental/semmle/python/security/TimingAttack.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/ql/src/experimental/semmle/python/security/TimingAttack.qll b/python/ql/src/experimental/semmle/python/security/TimingAttack.qll index df313b712e3..04687d3caa1 100644 --- a/python/ql/src/experimental/semmle/python/security/TimingAttack.qll +++ b/python/ql/src/experimental/semmle/python/security/TimingAttack.qll @@ -162,7 +162,7 @@ private string sensitiveheaders() { result = [ "x-auth-token", "x-csrf-token", "http_x_csrf_token", "x-csrf-param", "x-csrf-header", - "http_x_csrf_token", "x-api-key", "authorization", "proxy-authorization" + "http_x_csrf_token", "x-api-key", "authorization", "proxy-authorization", "x-gitlab-token" ] } From 93257be9134cf938c1871c8cb902be71845c72eb Mon Sep 17 00:00:00 2001 From: Ahmed Farid Date: Tue, 23 Aug 2022 12:51:48 +0100 Subject: [PATCH 133/631] Add Werkzeug source --- .../semmle/python/security/TimingAttack.qll | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/python/ql/src/experimental/semmle/python/security/TimingAttack.qll b/python/ql/src/experimental/semmle/python/security/TimingAttack.qll index 04687d3caa1..4b64bd12f5b 100644 --- a/python/ql/src/experimental/semmle/python/security/TimingAttack.qll +++ b/python/ql/src/experimental/semmle/python/security/TimingAttack.qll @@ -157,6 +157,25 @@ private class TornadoClientSuppliedsecret extends ClientSuppliedsecret { } } +private class WerkzeugClientSuppliedsecret extends ClientSuppliedsecret { + WerkzeugClientSuppliedsecret() { + exists(RemoteFlowSource rfs, DataFlow::AttrRead get | + rfs.getSourceType() = "werkzeug.datastructures" and this.getFunction() = get + | + // `get` is a call to datastructures.headers.get or datastructures.headers.get_all or datastructures.headers.getlist + // datastructures.headers + get.getObject() + .(DataFlow::AttrRead) + // request + .getObject() + .getALocalSource() = rfs and + get.getAttributeName() in ["get", "get_all", "getlist"] and + get.getObject().(DataFlow::AttrRead).getAttributeName() = "Headers" and + this.getArg(0).asExpr().(StrConst).getText().toLowerCase() = sensitiveheaders() + ) + } +} + /** A string for `match` that identifies strings that look like they represent Sensitive Headers. */ private string sensitiveheaders() { result = From 66fb420d00af685e9933d17275276122873ae630 Mon Sep 17 00:00:00 2001 From: Ahmed Farid Date: Mon, 29 Aug 2022 18:08:09 +0100 Subject: [PATCH 134/631] Update PossibleTimingAttackAgainstHash.ql --- .../TimingAttackAgainstHash/PossibleTimingAttackAgainstHash.ql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHash/PossibleTimingAttackAgainstHash.ql b/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHash/PossibleTimingAttackAgainstHash.ql index f8e791c96ba..71e82bd715f 100644 --- a/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHash/PossibleTimingAttackAgainstHash.ql +++ b/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHash/PossibleTimingAttackAgainstHash.ql @@ -7,7 +7,7 @@ * @kind path-problem * @problem.severity error * @precision medium - * @id py/timing-attack-against-hash + * @id py/possible-timing-attack-against-hash * @tags security * external/cwe/cwe-208 */ From 199e3d94620270d625aecf3b37c42c7f7db8ba6b Mon Sep 17 00:00:00 2001 From: Ahmed Farid Date: Mon, 29 Aug 2022 18:13:45 +0100 Subject: [PATCH 135/631] Rename the query ID --- .../PossibleTimingAttackAgainstSensitiveInfo.ql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstSensitiveInfo/PossibleTimingAttackAgainstSensitiveInfo.ql b/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstSensitiveInfo/PossibleTimingAttackAgainstSensitiveInfo.ql index e4dcda45093..47173999a91 100644 --- a/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstSensitiveInfo/PossibleTimingAttackAgainstSensitiveInfo.ql +++ b/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstSensitiveInfo/PossibleTimingAttackAgainstSensitiveInfo.ql @@ -5,7 +5,7 @@ * @kind path-problem * @problem.severity error * @precision medium - * @id py/timing-attack-sensitive-info + * @id py/possible-timing-attack-sensitive-info * @tags security * external/cwe/cwe-208 */ From 141b65fea85c3d03ea3e60affeb3d6955c6229cf Mon Sep 17 00:00:00 2001 From: Ahmed Farid Date: Mon, 29 Aug 2022 18:18:19 +0100 Subject: [PATCH 136/631] Fix typo --- .../TimingAttackAgainstHash/TimingAttackAgainstHash.qhelp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHash/TimingAttackAgainstHash.qhelp b/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHash/TimingAttackAgainstHash.qhelp index 5f1b1feb8e3..2dfe5296167 100644 --- a/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHash/TimingAttackAgainstHash.qhelp +++ b/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHash/TimingAttackAgainstHash.qhelp @@ -6,7 +6,7 @@ Timing Attack is based on the leakage of information by studying how long it takes the system to respond to different inputs. it can be circumvented by using a constant-time algorithm for checking the value of Hash, more precisely, the comparison time should not depend on the content of the input. Otherwise the attacker gains -information that is indirectly leaked by the application. This information is then used for malicious purposes. +information that is indirectly leaked by the application. This information may then be used for malicious purposes.

    From baa0fd41480fc47c8965270fc3ae889fc2004960 Mon Sep 17 00:00:00 2001 From: Ahmed Farid Date: Mon, 29 Aug 2022 18:25:26 +0100 Subject: [PATCH 137/631] Convert `%UserPass%` word to lowercase --- .../ql/src/experimental/semmle/python/security/TimingAttack.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/ql/src/experimental/semmle/python/security/TimingAttack.qll b/python/ql/src/experimental/semmle/python/security/TimingAttack.qll index 4b64bd12f5b..8c49392bf1f 100644 --- a/python/ql/src/experimental/semmle/python/security/TimingAttack.qll +++ b/python/ql/src/experimental/semmle/python/security/TimingAttack.qll @@ -78,7 +78,7 @@ private string suspicious() { result = [ "%password%", "%passwd%", "%pwd%", "%refresh%token%", "%secret%token", "%secret%key", - "%passcode%", "%passphrase%", "%token%", "%secret%", "%credential%", "%UserPass%" + "%passcode%", "%passphrase%", "%token%", "%secret%", "%credential%", "%userpass%" ] } From b2551a5581db5286ac6512ee3eb325c0a3151613 Mon Sep 17 00:00:00 2001 From: Ahmed Farid Date: Mon, 29 Aug 2022 18:30:43 +0100 Subject: [PATCH 138/631] Update the name of the class (and its subclasses) --- .../semmle/python/security/TimingAttack.qll | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/python/ql/src/experimental/semmle/python/security/TimingAttack.qll b/python/ql/src/experimental/semmle/python/security/TimingAttack.qll index 8c49392bf1f..3c76edd1482 100644 --- a/python/ql/src/experimental/semmle/python/security/TimingAttack.qll +++ b/python/ql/src/experimental/semmle/python/security/TimingAttack.qll @@ -95,9 +95,9 @@ class CredentialExpr extends Expr { * * For example: `request.headers.get("X-Auth-Token")`. */ -abstract class ClientSuppliedsecret extends DataFlow::CallCfgNode { } +abstract class ClientSuppliedSecret extends DataFlow::CallCfgNode { } -private class FlaskClientSuppliedsecret extends ClientSuppliedsecret { +private class FlaskClientSuppliedSecret extends ClientSuppliedSecret { FlaskClientSuppliedsecret() { exists(RemoteFlowSource rfs, DataFlow::AttrRead get | rfs.getSourceType() = "flask.request" and this.getFunction() = get @@ -116,7 +116,7 @@ private class FlaskClientSuppliedsecret extends ClientSuppliedsecret { } } -private class DjangoClientSuppliedsecret extends ClientSuppliedsecret { +private class DjangoClientSuppliedSecret extends ClientSuppliedSecret { DjangoClientSuppliedsecret() { exists(RemoteFlowSource rfs, DataFlow::AttrRead get | rfs.getSourceType() = "django.http.request.HttpRequest" and this.getFunction() = get @@ -135,7 +135,7 @@ private class DjangoClientSuppliedsecret extends ClientSuppliedsecret { } } -private class TornadoClientSuppliedsecret extends ClientSuppliedsecret { +private class TornadoClientSuppliedSecret extends ClientSuppliedSecret { TornadoClientSuppliedsecret() { exists(RemoteFlowSource rfs, DataFlow::AttrRead get | rfs.getSourceType() = "tornado.web.RequestHandler" and this.getFunction() = get @@ -157,7 +157,7 @@ private class TornadoClientSuppliedsecret extends ClientSuppliedsecret { } } -private class WerkzeugClientSuppliedsecret extends ClientSuppliedsecret { +private class WerkzeugClientSuppliedSecret extends ClientSuppliedSecret { WerkzeugClientSuppliedsecret() { exists(RemoteFlowSource rfs, DataFlow::AttrRead get | rfs.getSourceType() = "werkzeug.datastructures" and this.getFunction() = get From 9995e91bb716868d49b2956edc1aa97579508880 Mon Sep 17 00:00:00 2001 From: Ahmed Farid Date: Mon, 29 Aug 2022 18:57:56 +0100 Subject: [PATCH 139/631] Update the name of the class (and its subclasses) --- .../experimental/semmle/python/security/TimingAttack.qll | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/python/ql/src/experimental/semmle/python/security/TimingAttack.qll b/python/ql/src/experimental/semmle/python/security/TimingAttack.qll index 3c76edd1482..3500974aeaa 100644 --- a/python/ql/src/experimental/semmle/python/security/TimingAttack.qll +++ b/python/ql/src/experimental/semmle/python/security/TimingAttack.qll @@ -98,7 +98,7 @@ class CredentialExpr extends Expr { abstract class ClientSuppliedSecret extends DataFlow::CallCfgNode { } private class FlaskClientSuppliedSecret extends ClientSuppliedSecret { - FlaskClientSuppliedsecret() { + FlaskClientSuppliedSecret() { exists(RemoteFlowSource rfs, DataFlow::AttrRead get | rfs.getSourceType() = "flask.request" and this.getFunction() = get | @@ -117,7 +117,7 @@ private class FlaskClientSuppliedSecret extends ClientSuppliedSecret { } private class DjangoClientSuppliedSecret extends ClientSuppliedSecret { - DjangoClientSuppliedsecret() { + DjangoClientSuppliedSecret() { exists(RemoteFlowSource rfs, DataFlow::AttrRead get | rfs.getSourceType() = "django.http.request.HttpRequest" and this.getFunction() = get | @@ -136,7 +136,7 @@ private class DjangoClientSuppliedSecret extends ClientSuppliedSecret { } private class TornadoClientSuppliedSecret extends ClientSuppliedSecret { - TornadoClientSuppliedsecret() { + TornadoClientSuppliedSecret() { exists(RemoteFlowSource rfs, DataFlow::AttrRead get | rfs.getSourceType() = "tornado.web.RequestHandler" and this.getFunction() = get | @@ -158,7 +158,7 @@ private class TornadoClientSuppliedSecret extends ClientSuppliedSecret { } private class WerkzeugClientSuppliedSecret extends ClientSuppliedSecret { - WerkzeugClientSuppliedsecret() { + WerkzeugClientSuppliedSecret() { exists(RemoteFlowSource rfs, DataFlow::AttrRead get | rfs.getSourceType() = "werkzeug.datastructures" and this.getFunction() = get | From 0177cd810eb70de8b28f965bceda4b91bf6db7f1 Mon Sep 17 00:00:00 2001 From: Ahmed Farid Date: Tue, 30 Aug 2022 13:58:54 +0100 Subject: [PATCH 140/631] Update `suspicious()` --- .../src/experimental/semmle/python/security/TimingAttack.qll | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/python/ql/src/experimental/semmle/python/security/TimingAttack.qll b/python/ql/src/experimental/semmle/python/security/TimingAttack.qll index 3500974aeaa..467873cb1e7 100644 --- a/python/ql/src/experimental/semmle/python/security/TimingAttack.qll +++ b/python/ql/src/experimental/semmle/python/security/TimingAttack.qll @@ -78,7 +78,8 @@ private string suspicious() { result = [ "%password%", "%passwd%", "%pwd%", "%refresh%token%", "%secret%token", "%secret%key", - "%passcode%", "%passphrase%", "%token%", "%secret%", "%credential%", "%userpass%" + "%passcode%", "%passphrase%", "%token%", "%secret%", "%credential%", "%userpass%", + "%digest%", "%signature%", "%mac%" ] } From de58d0f0247f01fcafc9328afe0b7e92276f4479 Mon Sep 17 00:00:00 2001 From: Ahmed Farid Date: Tue, 30 Aug 2022 16:34:43 +0100 Subject: [PATCH 141/631] Update the subclasses of `ClientSuppliedSecret` class --- .../semmle/python/security/TimingAttack.qll | 84 ++++++------------- 1 file changed, 24 insertions(+), 60 deletions(-) diff --git a/python/ql/src/experimental/semmle/python/security/TimingAttack.qll b/python/ql/src/experimental/semmle/python/security/TimingAttack.qll index 467873cb1e7..1065e27915c 100644 --- a/python/ql/src/experimental/semmle/python/security/TimingAttack.qll +++ b/python/ql/src/experimental/semmle/python/security/TimingAttack.qll @@ -96,84 +96,48 @@ class CredentialExpr extends Expr { * * For example: `request.headers.get("X-Auth-Token")`. */ -abstract class ClientSuppliedSecret extends DataFlow::CallCfgNode { } +abstract class ClientSuppliedSecret extends API::CallNode { } private class FlaskClientSuppliedSecret extends ClientSuppliedSecret { FlaskClientSuppliedSecret() { - exists(RemoteFlowSource rfs, DataFlow::AttrRead get | - rfs.getSourceType() = "flask.request" and this.getFunction() = get - | - // `get` is a call to request.headers.get or request.headers.get_all or request.headers.getlist - // request.headers - get.getObject() - .(DataFlow::AttrRead) - // request - .getObject() - .getALocalSource() = rfs and - get.getAttributeName() in ["get", "get_all", "getlist"] and - get.getObject().(DataFlow::AttrRead).getAttributeName() = "headers" and - this.getArg(0).asExpr().(StrConst).getText().toLowerCase() = sensitiveheaders() - ) + this = Flask::request().getMember("headers").getMember(["get", "get_all", "getlist"]).getACall() and + this.getParameter(0, ["key", "name"]).toString().toLowerCase() = sensitiveheaders() } } private class DjangoClientSuppliedSecret extends ClientSuppliedSecret { DjangoClientSuppliedSecret() { - exists(RemoteFlowSource rfs, DataFlow::AttrRead get | - rfs.getSourceType() = "django.http.request.HttpRequest" and this.getFunction() = get - | - // `get` is a call to request.headers.get or request.META.get - // request.headers - get.getObject() - .(DataFlow::AttrRead) - // request - .getObject() - .getALocalSource() = rfs and - get.getAttributeName() = "get" and - get.getObject().(DataFlow::AttrRead).getAttributeName() in ["headers", "META"] and - this.getArg(0).asExpr().(StrConst).getText().toLowerCase() = sensitiveheaders() - ) + this = + PrivateDjango::DjangoImpl::Http::Request::HttpRequest::classRef() + .getMember(["headers", "META"]) + .getMember("get") + .getACall() and + this.getParameter(0, "key").toString().toLowerCase() = sensitiveheaders() } } +/** Gets a reference to the `tornado.web.RequestHandler` module. */ +API::Node requesthandler() { + result = API::moduleImport("tornado").getMember("web").getMember("RequestHandler") +} + private class TornadoClientSuppliedSecret extends ClientSuppliedSecret { TornadoClientSuppliedSecret() { - exists(RemoteFlowSource rfs, DataFlow::AttrRead get | - rfs.getSourceType() = "tornado.web.RequestHandler" and this.getFunction() = get - | - // `get` is a call to `rfs`.request.headers.get - // `rfs`.request.headers - get.getObject() - .(DataFlow::AttrRead) - // `rfs`.request - .getObject() - .(DataFlow::AttrRead) - // `rfs` - .getObject() - .getALocalSource() = rfs and - get.getAttributeName() in ["get", "get_list"] and - get.getObject().(DataFlow::AttrRead).getAttributeName() = "headers" and - this.getArg(0).asExpr().(StrConst).getText().toLowerCase() = sensitiveheaders() - ) + this = requesthandler().getMember(["headers", "META"]).getMember("get").getACall() and + this.getParameter(0, "key").toString().toLowerCase() = sensitiveheaders() } } +/** Gets a reference to the `werkzeug.datastructures.Headers` module. */ +API::Node headers() { + result = API::moduleImport("werkzeug").getMember("datastructures").getMember("Headers") +} + private class WerkzeugClientSuppliedSecret extends ClientSuppliedSecret { WerkzeugClientSuppliedSecret() { - exists(RemoteFlowSource rfs, DataFlow::AttrRead get | - rfs.getSourceType() = "werkzeug.datastructures" and this.getFunction() = get - | - // `get` is a call to datastructures.headers.get or datastructures.headers.get_all or datastructures.headers.getlist - // datastructures.headers - get.getObject() - .(DataFlow::AttrRead) - // request - .getObject() - .getALocalSource() = rfs and - get.getAttributeName() in ["get", "get_all", "getlist"] and - get.getObject().(DataFlow::AttrRead).getAttributeName() = "Headers" and - this.getArg(0).asExpr().(StrConst).getText().toLowerCase() = sensitiveheaders() - ) + this = + headers().getMember(["headers", "META"]).getMember(["get", "get_all", "getlist"]).getACall() and + this.getParameter(0, ["key", "name"]).toString().toLowerCase() = sensitiveheaders() } } From 23f268f3b9285b1a29b8050e7471293d0a864d6d Mon Sep 17 00:00:00 2001 From: Ahmed Farid Date: Tue, 30 Aug 2022 16:39:40 +0100 Subject: [PATCH 142/631] Import Django and Flask model --- .../ql/src/experimental/semmle/python/security/TimingAttack.qll | 2 ++ 1 file changed, 2 insertions(+) diff --git a/python/ql/src/experimental/semmle/python/security/TimingAttack.qll b/python/ql/src/experimental/semmle/python/security/TimingAttack.qll index 1065e27915c..8a006d981fc 100644 --- a/python/ql/src/experimental/semmle/python/security/TimingAttack.qll +++ b/python/ql/src/experimental/semmle/python/security/TimingAttack.qll @@ -6,6 +6,8 @@ private import semmle.python.dataflow.new.DataFlow private import semmle.python.dataflow.new.DataFlow2 private import semmle.python.ApiGraphs private import semmle.python.dataflow.new.RemoteFlowSources +private import semmle.python.frameworks.Flask +private import semmle.python.frameworks.Django /** A data flow source of the hash obtained */ class ProduceHashCall extends DataFlow::CallCfgNode { From 133a3c19f04e37cff7c312d828f961b5fcc73631 Mon Sep 17 00:00:00 2001 From: Ahmed Farid Date: Wed, 31 Aug 2022 11:09:24 +0100 Subject: [PATCH 143/631] Add more source of crypto call --- .../semmle/python/security/TimingAttack.qll | 96 +++++++++++++++++-- 1 file changed, 90 insertions(+), 6 deletions(-) diff --git a/python/ql/src/experimental/semmle/python/security/TimingAttack.qll b/python/ql/src/experimental/semmle/python/security/TimingAttack.qll index 8a006d981fc..75535c8e270 100644 --- a/python/ql/src/experimental/semmle/python/security/TimingAttack.qll +++ b/python/ql/src/experimental/semmle/python/security/TimingAttack.qll @@ -9,9 +9,23 @@ private import semmle.python.dataflow.new.RemoteFlowSources private import semmle.python.frameworks.Flask private import semmle.python.frameworks.Django -/** A data flow source of the hash obtained */ -class ProduceHashCall extends DataFlow::CallCfgNode { - ProduceHashCall() { +/** A method call that produces cryptographic result. */ +abstract private class ProduceCryptoCall extends API::CallNode { + /** Gets a type of cryptographic operation such as HMAC, signature or ciphertext. */ + abstract string getResultType(); +} + +/** Gets a reference to the `cryptography.hazmat.primitives` module. */ +API::Node cryptographylib() { + result = API::moduleImport("cryptography").getMember("hazmat").getMember("primitives") +} + +/** Gets a reference to the `Crypto` module. */ +API::Node cryptodome() { result = API::moduleImport(["Crypto", "Cryptodome"]) } + +/** A method call that produces a MAC. */ +class ProduceMacCall extends ProduceCryptoCall { + ProduceMacCall() { this = API::moduleImport("hmac").getMember("digest").getACall() or this = API::moduleImport("hmac") @@ -19,15 +33,85 @@ class ProduceHashCall extends DataFlow::CallCfgNode { .getReturn() .getMember(["digest", "hexdigest"]) .getACall() or + this = + cryptodome() + .getMember("Hash") + .getMember("HMAC") + .getMember(["new", "HMAC"]) + .getMember(["digest", "hexdigest"]) + .getACall() or + this = + cryptographylib() + .getMember("hmac") + .getMember("HMAC") + .getReturn() + .getMember("finalize") + .getACall() or + this = + cryptographylib() + .getMember("cmac") + .getMember("CMAC") + .getReturn() + .getMember("finalize") + .getACall() or + this = + cryptodome() + .getMember("Hash") + .getMember("CMAC") + .getMember(["new", "CMAC"]) + .getMember(["digest", "hexdigest"]) + .getACall() + } + + override string getResultType() { result = "MAC" } +} + +/** A method call that produces a signature. */ +private class ProduceSignatureCall extends ProduceCryptoCall { + ProduceSignatureCall() { + this = + cryptodome() + .getMember("Signature") + .getMember(["DSS", "pkcs1_15", "pss", "eddsa"]) + .getMember("new") + .getReturn() + .getMember("sign") + .getACall() + } + + override string getResultType() { result = "signature" } +} + +private string hashalgo() { + result = ["sha1", "sha224", "sha256", "sha384", "sha512", "blake2b", "blake2s", "md5"] +} + +/** A method call that produces a Hash. */ +private class ProduceHashCall extends ProduceCryptoCall { + ProduceHashCall() { + this = + cryptographylib() + .getMember("hashes") + .getMember("Hash") + .getReturn() + .getMember("finalize") + .getACall() or this = API::moduleImport("hashlib") - .getMember([ - "new", "sha1", "sha224", "sha256", "sha384", "sha512", "blake2b", "blake2s", "md5" - ]) + .getMember(["new", hashalgo()]) + .getReturn() + .getMember(["digest", "hexdigest"]) + .getACall() or + this = + cryptodome() + .getMember(hashalgo()) + .getMember("new") .getReturn() .getMember(["digest", "hexdigest"]) .getACall() } + + override string getResultType() { result = "Hash" } } /** A data flow sink for comparison. */ From ca28d79541b04a0493af3bb2f073912343e56146 Mon Sep 17 00:00:00 2001 From: Ahmed Farid Date: Wed, 31 Aug 2022 11:15:39 +0100 Subject: [PATCH 144/631] Prevent crosstalk between the configurations --- .../src/experimental/semmle/python/security/TimingAttack.qll | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/python/ql/src/experimental/semmle/python/security/TimingAttack.qll b/python/ql/src/experimental/semmle/python/security/TimingAttack.qll index 75535c8e270..3f55e3b5c5a 100644 --- a/python/ql/src/experimental/semmle/python/security/TimingAttack.qll +++ b/python/ql/src/experimental/semmle/python/security/TimingAttack.qll @@ -1,7 +1,6 @@ private import python -private import semmle.python.dataflow.new.TaintTracking private import semmle.python.dataflow.new.TaintTracking2 -private import semmle.python.dataflow.new.TaintTracking3 +private import semmle.python.dataflow.new.TaintTracking private import semmle.python.dataflow.new.DataFlow private import semmle.python.dataflow.new.DataFlow2 private import semmle.python.ApiGraphs @@ -239,7 +238,7 @@ private string sensitiveheaders() { /** * A config that tracks data flow from remote user input to Variable that hold sensitive info */ -class UserInputSecretConfig extends TaintTracking2::Configuration { +class UserInputSecretConfig extends TaintTracking::Configuration { UserInputSecretConfig() { this = "UserInputSecretConfig" } override predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource } From 740bf716cb2654caf43948914efd94355333ddc1 Mon Sep 17 00:00:00 2001 From: Ahmed Farid Date: Wed, 31 Aug 2022 12:22:01 +0100 Subject: [PATCH 145/631] Update TimingAttack.qll --- .../ql/src/experimental/semmle/python/security/TimingAttack.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/ql/src/experimental/semmle/python/security/TimingAttack.qll b/python/ql/src/experimental/semmle/python/security/TimingAttack.qll index 3f55e3b5c5a..fb512405a10 100644 --- a/python/ql/src/experimental/semmle/python/security/TimingAttack.qll +++ b/python/ql/src/experimental/semmle/python/security/TimingAttack.qll @@ -10,7 +10,7 @@ private import semmle.python.frameworks.Django /** A method call that produces cryptographic result. */ abstract private class ProduceCryptoCall extends API::CallNode { - /** Gets a type of cryptographic operation such as HMAC, signature or ciphertext. */ + /** Gets a type of cryptographic operation such as HMAC, signature or Hash. */ abstract string getResultType(); } From 275ed0d6e57f51208d6f592584c00247aee9b025 Mon Sep 17 00:00:00 2001 From: Ahmed Farid Date: Wed, 31 Aug 2022 12:37:36 +0100 Subject: [PATCH 146/631] Update `select` statement --- .../TimingAttackAgainstHash/TimingAttackAgainstHash.ql | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHash/TimingAttackAgainstHash.ql b/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHash/TimingAttackAgainstHash.ql index c0ebdc285e8..f60e712cb4f 100644 --- a/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHash/TimingAttackAgainstHash.ql +++ b/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHash/TimingAttackAgainstHash.ql @@ -25,7 +25,7 @@ import DataFlow::PathGraph class TimingAttackAgainsthash extends TaintTracking::Configuration { TimingAttackAgainsthash() { this = "TimingAttackAgainsthash" } - override predicate isSource(DataFlow::Node source) { source instanceof ProduceHashCall } + override predicate isSource(DataFlow::Node source) { source instanceof ProduceCryptoCall } override predicate isSink(DataFlow::Node sink) { sink instanceof NonConstantTimeComparisonSink } } @@ -34,5 +34,5 @@ from TimingAttackAgainsthash config, DataFlow::PathNode source, DataFlow::PathNo where config.hasFlowPath(source, sink) and sink.getNode().(NonConstantTimeComparisonSink).includesUserInput() -select sink.getNode(), source, sink, "Timing attack against $@ validation.", source.getNode(), - "message" +select sink.getNode(), source, sink, "Timing attack against $@ validation.", + source.getNode().(ProduceCryptoCall).getResultType(), "message" From f2688c4a021182394748046bbdf51ec9aa205005 Mon Sep 17 00:00:00 2001 From: Ahmed Farid Date: Wed, 31 Aug 2022 12:39:00 +0100 Subject: [PATCH 147/631] Update `select` statement --- .../PossibleTimingAttackAgainstHash.ql | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHash/PossibleTimingAttackAgainstHash.ql b/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHash/PossibleTimingAttackAgainstHash.ql index 71e82bd715f..0d5809694b3 100644 --- a/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHash/PossibleTimingAttackAgainstHash.ql +++ b/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHash/PossibleTimingAttackAgainstHash.ql @@ -25,7 +25,7 @@ import DataFlow::PathGraph class PossibleTimingAttackAgainstHash extends TaintTracking::Configuration { PossibleTimingAttackAgainstHash() { this = "PossibleTimingAttackAgainstHash" } - override predicate isSource(DataFlow::Node source) { source instanceof ProduceHashCall } + override predicate isSource(DataFlow::Node source) { source instanceof ProduceCryptoCall } override predicate isSink(DataFlow::Node sink) { sink instanceof NonConstantTimeComparisonSink } } @@ -33,4 +33,4 @@ class PossibleTimingAttackAgainstHash extends TaintTracking::Configuration { from PossibleTimingAttackAgainstHash config, DataFlow::PathNode source, DataFlow::PathNode sink where config.hasFlowPath(source, sink) select sink.getNode(), source, sink, "Possible Timing attack against $@ validation.", - source.getNode(), "message" + source.getNode().(ProduceCryptoCall).getResultType(), "message" From 12960fd00f66a59e5e15decfce8492b177b564ec Mon Sep 17 00:00:00 2001 From: Ahmed Farid Date: Wed, 31 Aug 2022 12:39:46 +0100 Subject: [PATCH 148/631] Update TimingAttack.qll --- .../ql/src/experimental/semmle/python/security/TimingAttack.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/ql/src/experimental/semmle/python/security/TimingAttack.qll b/python/ql/src/experimental/semmle/python/security/TimingAttack.qll index fb512405a10..4906b9b22b3 100644 --- a/python/ql/src/experimental/semmle/python/security/TimingAttack.qll +++ b/python/ql/src/experimental/semmle/python/security/TimingAttack.qll @@ -9,7 +9,7 @@ private import semmle.python.frameworks.Flask private import semmle.python.frameworks.Django /** A method call that produces cryptographic result. */ -abstract private class ProduceCryptoCall extends API::CallNode { +abstract class ProduceCryptoCall extends API::CallNode { /** Gets a type of cryptographic operation such as HMAC, signature or Hash. */ abstract string getResultType(); } From 13d1a4fdc146cbdbe43397808ae2745da9560bcf Mon Sep 17 00:00:00 2001 From: Ahmed Farid Date: Wed, 31 Aug 2022 12:46:17 +0100 Subject: [PATCH 149/631] Update TimingAttackAgainstHeaderValue.ql --- .../TimingAttackAgainstHeaderValue.ql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHeaderValue/TimingAttackAgainstHeaderValue.ql b/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHeaderValue/TimingAttackAgainstHeaderValue.ql index e2986100bbe..99d870afc83 100644 --- a/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHeaderValue/TimingAttackAgainstHeaderValue.ql +++ b/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHeaderValue/TimingAttackAgainstHeaderValue.ql @@ -22,7 +22,7 @@ import DataFlow::PathGraph class ClientSuppliedSecretConfig extends TaintTracking::Configuration { ClientSuppliedSecretConfig() { this = "ClientSuppliedSecretConfig" } - override predicate isSource(DataFlow::Node source) { source instanceof ClientSuppliedsecret } + override predicate isSource(DataFlow::Node source) { source instanceof ClientSuppliedSecret } override predicate isSink(DataFlow::Node sink) { exists(Compare cmp, Expr left, Expr right, Cmpop cmpop | From 56d48e6264796a47bc6d83b742db9228864921d0 Mon Sep 17 00:00:00 2001 From: Ahmed Farid Date: Wed, 31 Aug 2022 15:59:51 +0100 Subject: [PATCH 150/631] Add more tests --- .../TimingAttackAgainstHash.py | 21 ++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstHash/TimingAttackAgainstHash.py b/python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstHash/TimingAttackAgainstHash.py index c7730ef69b2..1d312f028eb 100644 --- a/python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstHash/TimingAttackAgainstHash.py +++ b/python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstHash/TimingAttackAgainstHash.py @@ -5,8 +5,26 @@ """ import hashlib import hmac +from cryptography.hazmat.primitives import cmac +from cryptography.hazmat.primitives.ciphers import algorithms +from Crypto.Signature import pkcs1_15 +from Crypto.Hash import SHA256 +from Crypto.PublicKey import RSA -key = "e179017a-62b0-4996-8a38-e91aa9f1" + +def UnsafeCmacCheck(actualCmac): + expected = cmac.CMAC(algorithms.AES(key)) + expected.update(b"message to authenticate") + expected.finalize() + return actualCmac == expected + + +def UnsafeCheckSignature(expected): + message = b'To be signed' + key = RSA.import_key(open('private_key.der').read()) + h = SHA256.new(message) + signature = pkcs1_15.new(key).sign(h) + return expected == signature def sign(pre_key, msg, alg): return hmac.new(pre_key, msg, alg).digest() @@ -15,6 +33,7 @@ def verifyGood(msg, sig): return constant_time_string_compare(sig, sign(key, msg, hashlib.sha256)) #good def verifyBad(msg, sig): + key = "e179017a-62b0-4996-8a38-e91aa9f1" return sig == sign(key, msg, hashlib.sha256) #bad def constant_time_string_compare(a, b): From 8153b790ad2ed2228bdd65a19fb1a80bb9647c26 Mon Sep 17 00:00:00 2001 From: Ahmed Farid Date: Wed, 31 Aug 2022 16:01:09 +0100 Subject: [PATCH 151/631] Update test result --- .../PossibleTimingAttackAgainstHash.expected | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstHash/PossibleTimingAttackAgainstHash.expected b/python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstHash/PossibleTimingAttackAgainstHash.expected index dabc3f76a56..ece6b8d6897 100644 --- a/python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstHash/PossibleTimingAttackAgainstHash.expected +++ b/python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstHash/PossibleTimingAttackAgainstHash.expected @@ -1,8 +1,12 @@ edges -| TimingAttackAgainstHash.py:12:12:12:47 | ControlFlowNode for Attribute() | TimingAttackAgainstHash.py:18:19:18:48 | ControlFlowNode for sign() | +| TimingAttackAgainstHash.py:26:17:26:41 | ControlFlowNode for Attribute() | TimingAttackAgainstHash.py:27:24:27:32 | ControlFlowNode for signature | +| TimingAttackAgainstHash.py:30:12:30:47 | ControlFlowNode for Attribute() | TimingAttackAgainstHash.py:37:19:37:48 | ControlFlowNode for sign() | nodes -| TimingAttackAgainstHash.py:12:12:12:47 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | -| TimingAttackAgainstHash.py:18:19:18:48 | ControlFlowNode for sign() | semmle.label | ControlFlowNode for sign() | +| TimingAttackAgainstHash.py:26:17:26:41 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | +| TimingAttackAgainstHash.py:27:24:27:32 | ControlFlowNode for signature | semmle.label | ControlFlowNode for signature | +| TimingAttackAgainstHash.py:30:12:30:47 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | +| TimingAttackAgainstHash.py:37:19:37:48 | ControlFlowNode for sign() | semmle.label | ControlFlowNode for sign() | subpaths #select -| TimingAttackAgainstHash.py:18:19:18:48 | ControlFlowNode for sign() | TimingAttackAgainstHash.py:12:12:12:47 | ControlFlowNode for Attribute() | TimingAttackAgainstHash.py:18:19:18:48 | ControlFlowNode for sign() | Possible Timing attack against $@ validation. | TimingAttackAgainstHash.py:12:12:12:47 | ControlFlowNode for Attribute() | message | +| TimingAttackAgainstHash.py:27:24:27:32 | ControlFlowNode for signature | TimingAttackAgainstHash.py:26:17:26:41 | ControlFlowNode for Attribute() | TimingAttackAgainstHash.py:27:24:27:32 | ControlFlowNode for signature | Possible Timing attack against $@ validation. | signature | message | +| TimingAttackAgainstHash.py:37:19:37:48 | ControlFlowNode for sign() | TimingAttackAgainstHash.py:30:12:30:47 | ControlFlowNode for Attribute() | TimingAttackAgainstHash.py:37:19:37:48 | ControlFlowNode for sign() | Possible Timing attack against $@ validation. | MAC | message | From a42cb20b862b04af6356c758c7b590c231e44d7a Mon Sep 17 00:00:00 2001 From: Ahmed Farid Date: Wed, 31 Aug 2022 16:07:58 +0100 Subject: [PATCH 152/631] Update TimingAttack.qll --- .../experimental/semmle/python/security/TimingAttack.qll | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/python/ql/src/experimental/semmle/python/security/TimingAttack.qll b/python/ql/src/experimental/semmle/python/security/TimingAttack.qll index 4906b9b22b3..a02583ca52d 100644 --- a/python/ql/src/experimental/semmle/python/security/TimingAttack.qll +++ b/python/ql/src/experimental/semmle/python/security/TimingAttack.qll @@ -186,7 +186,7 @@ abstract class ClientSuppliedSecret extends API::CallNode { } private class FlaskClientSuppliedSecret extends ClientSuppliedSecret { FlaskClientSuppliedSecret() { this = Flask::request().getMember("headers").getMember(["get", "get_all", "getlist"]).getACall() and - this.getParameter(0, ["key", "name"]).toString().toLowerCase() = sensitiveheaders() + this.getParameter(0, "key").asSink().asExpr().(StrConst).getText().toLowerCase() = sensitiveheaders() } } @@ -197,7 +197,7 @@ private class DjangoClientSuppliedSecret extends ClientSuppliedSecret { .getMember(["headers", "META"]) .getMember("get") .getACall() and - this.getParameter(0, "key").toString().toLowerCase() = sensitiveheaders() + this.getParameter(0, "key").asSink().asExpr().(StrConst).getText().toLowerCase() = sensitiveheaders() } } @@ -209,7 +209,7 @@ API::Node requesthandler() { private class TornadoClientSuppliedSecret extends ClientSuppliedSecret { TornadoClientSuppliedSecret() { this = requesthandler().getMember(["headers", "META"]).getMember("get").getACall() and - this.getParameter(0, "key").toString().toLowerCase() = sensitiveheaders() + this.getParameter(0, "key").asSink().asExpr().(StrConst).getText().toLowerCase() = sensitiveheaders() } } @@ -222,7 +222,7 @@ private class WerkzeugClientSuppliedSecret extends ClientSuppliedSecret { WerkzeugClientSuppliedSecret() { this = headers().getMember(["headers", "META"]).getMember(["get", "get_all", "getlist"]).getACall() and - this.getParameter(0, ["key", "name"]).toString().toLowerCase() = sensitiveheaders() + this.getParameter(0, "key").asSink().asExpr().(StrConst).getText().toLowerCase() = sensitiveheaders() } } From daff7775ca38f947bf9848a90eb4a305e4a9f9e7 Mon Sep 17 00:00:00 2001 From: Ahmed Farid Date: Wed, 31 Aug 2022 16:09:22 +0100 Subject: [PATCH 153/631] Update TimingAttack.qll --- .../src/experimental/semmle/python/security/TimingAttack.qll | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/python/ql/src/experimental/semmle/python/security/TimingAttack.qll b/python/ql/src/experimental/semmle/python/security/TimingAttack.qll index a02583ca52d..1fe382459d7 100644 --- a/python/ql/src/experimental/semmle/python/security/TimingAttack.qll +++ b/python/ql/src/experimental/semmle/python/security/TimingAttack.qll @@ -186,7 +186,7 @@ abstract class ClientSuppliedSecret extends API::CallNode { } private class FlaskClientSuppliedSecret extends ClientSuppliedSecret { FlaskClientSuppliedSecret() { this = Flask::request().getMember("headers").getMember(["get", "get_all", "getlist"]).getACall() and - this.getParameter(0, "key").asSink().asExpr().(StrConst).getText().toLowerCase() = sensitiveheaders() + this.getParameter(0, ["key", "name"]).asSink().asExpr().(StrConst).getText().toLowerCase() = sensitiveheaders() } } @@ -222,7 +222,7 @@ private class WerkzeugClientSuppliedSecret extends ClientSuppliedSecret { WerkzeugClientSuppliedSecret() { this = headers().getMember(["headers", "META"]).getMember(["get", "get_all", "getlist"]).getACall() and - this.getParameter(0, "key").asSink().asExpr().(StrConst).getText().toLowerCase() = sensitiveheaders() + this.getParameter(0, ["key", "name"]).asSink().asExpr().(StrConst).getText().toLowerCase() = sensitiveheaders() } } From cf83b07aae34d43ebf186bca4205694af14ddfea Mon Sep 17 00:00:00 2001 From: Ahmed Farid Date: Wed, 31 Aug 2022 17:04:02 +0100 Subject: [PATCH 154/631] Add more source of crypto call --- .../semmle/python/security/TimingAttack.qll | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/python/ql/src/experimental/semmle/python/security/TimingAttack.qll b/python/ql/src/experimental/semmle/python/security/TimingAttack.qll index 1fe382459d7..2b8ec13f301 100644 --- a/python/ql/src/experimental/semmle/python/security/TimingAttack.qll +++ b/python/ql/src/experimental/semmle/python/security/TimingAttack.qll @@ -10,7 +10,7 @@ private import semmle.python.frameworks.Django /** A method call that produces cryptographic result. */ abstract class ProduceCryptoCall extends API::CallNode { - /** Gets a type of cryptographic operation such as HMAC, signature or Hash. */ + /** Gets a type of cryptographic operation such as MAC, signature, Hash or ciphertext. */ abstract string getResultType(); } @@ -113,6 +113,21 @@ private class ProduceHashCall extends ProduceCryptoCall { override string getResultType() { result = "Hash" } } +/** A method call that produces a ciphertext. */ +private class ProduceCiphertextCall extends ProduceCryptoCall { + ProduceCiphertextCall() { + this = + cryptodome() + .getMember("Cipher") + .getMember(["DES", "DES3", "ARC2", "ARC4", "Blowfish", "PKCS1_v1_5"]) + .getMember(["ARC4Cipher", "new", "PKCS115_Cipher"]) + .getMember("encrypt") + .getACall() + } + + override string getResultType() { result = "ciphertext" } +} + /** A data flow sink for comparison. */ private predicate existsFailFastCheck(Expr firstInput, Expr secondInput) { exists(Compare compare | From 0fd684cde83f81d3c7373551f520a5c9f2c41666 Mon Sep 17 00:00:00 2001 From: Ahmed Farid Date: Wed, 31 Aug 2022 17:13:43 +0100 Subject: [PATCH 155/631] Add more source of crypto call --- .../experimental/semmle/python/security/TimingAttack.qll | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/python/ql/src/experimental/semmle/python/security/TimingAttack.qll b/python/ql/src/experimental/semmle/python/security/TimingAttack.qll index 2b8ec13f301..5db95bf4948 100644 --- a/python/ql/src/experimental/semmle/python/security/TimingAttack.qll +++ b/python/ql/src/experimental/semmle/python/security/TimingAttack.qll @@ -122,6 +122,13 @@ private class ProduceCiphertextCall extends ProduceCryptoCall { .getMember(["DES", "DES3", "ARC2", "ARC4", "Blowfish", "PKCS1_v1_5"]) .getMember(["ARC4Cipher", "new", "PKCS115_Cipher"]) .getMember("encrypt") + .getACall() or + this = + cryptographylib() + .getMember("ciphers") + .getMember("Cipher") + .getReturn() + .getMember("finalize") .getACall() } From a50c226ca94a3c3033e2d7e39859ef53d579278f Mon Sep 17 00:00:00 2001 From: Ahmed Farid Date: Sat, 3 Sep 2022 12:10:55 +0100 Subject: [PATCH 156/631] Autoformat --- .../semmle/python/security/TimingAttack.qll | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/python/ql/src/experimental/semmle/python/security/TimingAttack.qll b/python/ql/src/experimental/semmle/python/security/TimingAttack.qll index 5db95bf4948..ad739fc42a4 100644 --- a/python/ql/src/experimental/semmle/python/security/TimingAttack.qll +++ b/python/ql/src/experimental/semmle/python/security/TimingAttack.qll @@ -185,8 +185,8 @@ private string suspicious() { result = [ "%password%", "%passwd%", "%pwd%", "%refresh%token%", "%secret%token", "%secret%key", - "%passcode%", "%passphrase%", "%token%", "%secret%", "%credential%", "%userpass%", - "%digest%", "%signature%", "%mac%" + "%passcode%", "%passphrase%", "%token%", "%secret%", "%credential%", "%userpass%", "%digest%", + "%signature%", "%mac%" ] } @@ -208,7 +208,8 @@ abstract class ClientSuppliedSecret extends API::CallNode { } private class FlaskClientSuppliedSecret extends ClientSuppliedSecret { FlaskClientSuppliedSecret() { this = Flask::request().getMember("headers").getMember(["get", "get_all", "getlist"]).getACall() and - this.getParameter(0, ["key", "name"]).asSink().asExpr().(StrConst).getText().toLowerCase() = sensitiveheaders() + this.getParameter(0, ["key", "name"]).asSink().asExpr().(StrConst).getText().toLowerCase() = + sensitiveheaders() } } @@ -219,7 +220,8 @@ private class DjangoClientSuppliedSecret extends ClientSuppliedSecret { .getMember(["headers", "META"]) .getMember("get") .getACall() and - this.getParameter(0, "key").asSink().asExpr().(StrConst).getText().toLowerCase() = sensitiveheaders() + this.getParameter(0, "key").asSink().asExpr().(StrConst).getText().toLowerCase() = + sensitiveheaders() } } @@ -231,7 +233,8 @@ API::Node requesthandler() { private class TornadoClientSuppliedSecret extends ClientSuppliedSecret { TornadoClientSuppliedSecret() { this = requesthandler().getMember(["headers", "META"]).getMember("get").getACall() and - this.getParameter(0, "key").asSink().asExpr().(StrConst).getText().toLowerCase() = sensitiveheaders() + this.getParameter(0, "key").asSink().asExpr().(StrConst).getText().toLowerCase() = + sensitiveheaders() } } @@ -244,7 +247,8 @@ private class WerkzeugClientSuppliedSecret extends ClientSuppliedSecret { WerkzeugClientSuppliedSecret() { this = headers().getMember(["headers", "META"]).getMember(["get", "get_all", "getlist"]).getACall() and - this.getParameter(0, ["key", "name"]).asSink().asExpr().(StrConst).getText().toLowerCase() = sensitiveheaders() + this.getParameter(0, ["key", "name"]).asSink().asExpr().(StrConst).getText().toLowerCase() = + sensitiveheaders() } } From 94b91536f9742f4cc14c13a5826d418c679eb8a2 Mon Sep 17 00:00:00 2001 From: Ahmed Farid Date: Sat, 3 Sep 2022 14:05:07 +0100 Subject: [PATCH 157/631] Replacing `getParameter` by `getArg` and `getArgByName` --- .../semmle/python/security/TimingAttack.qll | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/python/ql/src/experimental/semmle/python/security/TimingAttack.qll b/python/ql/src/experimental/semmle/python/security/TimingAttack.qll index ad739fc42a4..8507b9ebfb3 100644 --- a/python/ql/src/experimental/semmle/python/security/TimingAttack.qll +++ b/python/ql/src/experimental/semmle/python/security/TimingAttack.qll @@ -203,12 +203,12 @@ class CredentialExpr extends Expr { * * For example: `request.headers.get("X-Auth-Token")`. */ -abstract class ClientSuppliedSecret extends API::CallNode { } +abstract class ClientSuppliedSecret extends DataFlow::CallCfgNode { } private class FlaskClientSuppliedSecret extends ClientSuppliedSecret { FlaskClientSuppliedSecret() { this = Flask::request().getMember("headers").getMember(["get", "get_all", "getlist"]).getACall() and - this.getParameter(0, ["key", "name"]).asSink().asExpr().(StrConst).getText().toLowerCase() = + [this.getArg(0), this.getArgByName(["key", "name"])].asExpr().(StrConst).getText().toLowerCase() = sensitiveheaders() } } @@ -220,7 +220,7 @@ private class DjangoClientSuppliedSecret extends ClientSuppliedSecret { .getMember(["headers", "META"]) .getMember("get") .getACall() and - this.getParameter(0, "key").asSink().asExpr().(StrConst).getText().toLowerCase() = + [this.getArg(0), this.getArgByName("key")].asExpr().(StrConst).getText().toLowerCase() = sensitiveheaders() } } @@ -233,7 +233,7 @@ API::Node requesthandler() { private class TornadoClientSuppliedSecret extends ClientSuppliedSecret { TornadoClientSuppliedSecret() { this = requesthandler().getMember(["headers", "META"]).getMember("get").getACall() and - this.getParameter(0, "key").asSink().asExpr().(StrConst).getText().toLowerCase() = + [this.getArg(0), this.getArgByName("key")].asExpr().(StrConst).getText().toLowerCase() = sensitiveheaders() } } @@ -247,7 +247,7 @@ private class WerkzeugClientSuppliedSecret extends ClientSuppliedSecret { WerkzeugClientSuppliedSecret() { this = headers().getMember(["headers", "META"]).getMember(["get", "get_all", "getlist"]).getACall() and - this.getParameter(0, ["key", "name"]).asSink().asExpr().(StrConst).getText().toLowerCase() = + [this.getArg(0), this.getArgByName(["key", "name"])].asExpr().(StrConst).getText().toLowerCase() = sensitiveheaders() } } From f84331f5a53d1b2c43e5022f952bfa6722c799f3 Mon Sep 17 00:00:00 2001 From: Ahmed Farid Date: Mon, 5 Sep 2022 00:53:10 +0100 Subject: [PATCH 158/631] Provides classes for modeling HTTP Header APIs --- .../experimental/semmle/python/Concepts.qll | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/python/ql/src/experimental/semmle/python/Concepts.qll b/python/ql/src/experimental/semmle/python/Concepts.qll index 433d89dbad1..1347949af93 100644 --- a/python/ql/src/experimental/semmle/python/Concepts.qll +++ b/python/ql/src/experimental/semmle/python/Concepts.qll @@ -371,6 +371,39 @@ class HeaderDeclaration extends DataFlow::Node { DataFlow::Node getValueArg() { result = range.getValueArg() } } +/** Provides classes for modeling HTTP Header APIs. */ +module HeaderCollection { + /** + * A data-flow node that collects functions getting HTTP Headers. + * + * Extend this class to model new APIs. If you want to refine existing API models, + * extend `HeaderCollection` instead. + */ + abstract class Range extends DataFlow::Node { + /** + * Gets the argument containing the header name. + */ + abstract DataFlow::Node getNameArg(); + } +} + +/** + * A data-flow node that collects functions getting HTTP Headers. + * + * Extend this class to refine existing API models. If you want to model new APIs, + * extend `HeaderCollection::Range` instead. + */ +class HeaderCollection extends DataFlow::Node { + HeaderCollection::Range range; + + HeaderCollection() { this = range } + + /** + * Gets the argument containing the header name. + */ + DataFlow::Node getNameArg() { result = range.getNameArg() } +} + /** Provides classes for modeling Csv writer APIs. */ module CsvWriter { /** From 23871b3f5a43af571a46df81126acfb82183bbf5 Mon Sep 17 00:00:00 2001 From: Ahmed Farid Date: Mon, 5 Sep 2022 18:26:56 +0100 Subject: [PATCH 159/631] Update Concepts.qll --- .../experimental/semmle/python/Concepts.qll | 33 ------------------- 1 file changed, 33 deletions(-) diff --git a/python/ql/src/experimental/semmle/python/Concepts.qll b/python/ql/src/experimental/semmle/python/Concepts.qll index 1347949af93..433d89dbad1 100644 --- a/python/ql/src/experimental/semmle/python/Concepts.qll +++ b/python/ql/src/experimental/semmle/python/Concepts.qll @@ -371,39 +371,6 @@ class HeaderDeclaration extends DataFlow::Node { DataFlow::Node getValueArg() { result = range.getValueArg() } } -/** Provides classes for modeling HTTP Header APIs. */ -module HeaderCollection { - /** - * A data-flow node that collects functions getting HTTP Headers. - * - * Extend this class to model new APIs. If you want to refine existing API models, - * extend `HeaderCollection` instead. - */ - abstract class Range extends DataFlow::Node { - /** - * Gets the argument containing the header name. - */ - abstract DataFlow::Node getNameArg(); - } -} - -/** - * A data-flow node that collects functions getting HTTP Headers. - * - * Extend this class to refine existing API models. If you want to model new APIs, - * extend `HeaderCollection::Range` instead. - */ -class HeaderCollection extends DataFlow::Node { - HeaderCollection::Range range; - - HeaderCollection() { this = range } - - /** - * Gets the argument containing the header name. - */ - DataFlow::Node getNameArg() { result = range.getNameArg() } -} - /** Provides classes for modeling Csv writer APIs. */ module CsvWriter { /** From 0b8bdc0f85aab2f4d1557f887f50af23f1adcc12 Mon Sep 17 00:00:00 2001 From: Taus Date: Tue, 6 Sep 2022 16:37:43 +0000 Subject: [PATCH 160/631] Python: Fix broken test --- ...leTimingAttackAgainstSensitiveInfo.expected | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstSensitiveInfo/PossibleTimingAttackAgainstSensitiveInfo.expected b/python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstSensitiveInfo/PossibleTimingAttackAgainstSensitiveInfo.expected index 63d5e8ad821..4bde57c0b96 100644 --- a/python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstSensitiveInfo/PossibleTimingAttackAgainstSensitiveInfo.expected +++ b/python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstSensitiveInfo/PossibleTimingAttackAgainstSensitiveInfo.expected @@ -1,6 +1,24 @@ edges +| TimingAttackAgainstSensitiveInfo.py:14:8:14:14 | ControlFlowNode for request | TimingAttackAgainstSensitiveInfo.py:15:20:15:31 | ControlFlowNode for Attribute | +| TimingAttackAgainstSensitiveInfo.py:15:20:15:26 | ControlFlowNode for request | TimingAttackAgainstSensitiveInfo.py:15:20:15:31 | ControlFlowNode for Attribute | +| TimingAttackAgainstSensitiveInfo.py:15:20:15:31 | ControlFlowNode for Attribute | TimingAttackAgainstSensitiveInfo.py:15:20:15:38 | ControlFlowNode for Subscript | +| TimingAttackAgainstSensitiveInfo.py:15:20:15:38 | ControlFlowNode for Subscript | TimingAttackAgainstSensitiveInfo.py:16:16:16:23 | ControlFlowNode for password | +| TimingAttackAgainstSensitiveInfo.py:20:8:20:14 | ControlFlowNode for request | TimingAttackAgainstSensitiveInfo.py:21:20:21:31 | ControlFlowNode for Attribute | +| TimingAttackAgainstSensitiveInfo.py:21:20:21:26 | ControlFlowNode for request | TimingAttackAgainstSensitiveInfo.py:21:20:21:31 | ControlFlowNode for Attribute | +| TimingAttackAgainstSensitiveInfo.py:21:20:21:31 | ControlFlowNode for Attribute | TimingAttackAgainstSensitiveInfo.py:21:20:21:38 | ControlFlowNode for Subscript | +| TimingAttackAgainstSensitiveInfo.py:21:20:21:38 | ControlFlowNode for Subscript | TimingAttackAgainstSensitiveInfo.py:22:38:22:45 | ControlFlowNode for password | nodes +| TimingAttackAgainstSensitiveInfo.py:14:8:14:14 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | +| TimingAttackAgainstSensitiveInfo.py:15:20:15:26 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | +| TimingAttackAgainstSensitiveInfo.py:15:20:15:31 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | +| TimingAttackAgainstSensitiveInfo.py:15:20:15:38 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript | | TimingAttackAgainstSensitiveInfo.py:16:16:16:23 | ControlFlowNode for password | semmle.label | ControlFlowNode for password | +| TimingAttackAgainstSensitiveInfo.py:16:16:16:23 | ControlFlowNode for password | semmle.label | ControlFlowNode for password | +| TimingAttackAgainstSensitiveInfo.py:20:8:20:14 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | +| TimingAttackAgainstSensitiveInfo.py:21:20:21:26 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | +| TimingAttackAgainstSensitiveInfo.py:21:20:21:31 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | +| TimingAttackAgainstSensitiveInfo.py:21:20:21:38 | ControlFlowNode for Subscript | semmle.label | ControlFlowNode for Subscript | +| TimingAttackAgainstSensitiveInfo.py:22:38:22:45 | ControlFlowNode for password | semmle.label | ControlFlowNode for password | subpaths #select | TimingAttackAgainstSensitiveInfo.py:16:16:16:23 | ControlFlowNode for password | TimingAttackAgainstSensitiveInfo.py:16:16:16:23 | ControlFlowNode for password | TimingAttackAgainstSensitiveInfo.py:16:16:16:23 | ControlFlowNode for password | Timing attack against $@ validation. | TimingAttackAgainstSensitiveInfo.py:16:16:16:23 | ControlFlowNode for password | client-supplied token | From 64bb022adfd0a58c683b440c2c017469f43fa8d4 Mon Sep 17 00:00:00 2001 From: Ahmed Farid Date: Wed, 7 Sep 2022 11:12:53 +0100 Subject: [PATCH 161/631] Add `www-authenticate` to sensitiveheaders() --- .../src/experimental/semmle/python/security/TimingAttack.qll | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/python/ql/src/experimental/semmle/python/security/TimingAttack.qll b/python/ql/src/experimental/semmle/python/security/TimingAttack.qll index 8507b9ebfb3..ee6be383415 100644 --- a/python/ql/src/experimental/semmle/python/security/TimingAttack.qll +++ b/python/ql/src/experimental/semmle/python/security/TimingAttack.qll @@ -257,7 +257,8 @@ private string sensitiveheaders() { result = [ "x-auth-token", "x-csrf-token", "http_x_csrf_token", "x-csrf-param", "x-csrf-header", - "http_x_csrf_token", "x-api-key", "authorization", "proxy-authorization", "x-gitlab-token" + "http_x_csrf_token", "x-api-key", "authorization", "proxy-authorization", "x-gitlab-token", + "www-authenticate" ] } From cd51b4991dc4999bb7d9232a6481755e20f30c52 Mon Sep 17 00:00:00 2001 From: Raul Garcia Date: Tue, 18 Oct 2022 11:48:13 -0700 Subject: [PATCH 162/631] Initial CHeckin - CNG basic case --- .../QuantumVulnerableDiscovery/WinCng.ql | 39 +++++++++ .../QuantumVulnerableDiscovery/WindowsCng.qll | 7 ++ .../WindowsCngPQVAsymmetricKeyUsage.qll | 81 +++++++++++++++++++ .../QuantumVulnerableDiscovery/WinCng.qlref | 1 + 4 files changed, 128 insertions(+) create mode 100644 cpp/ql/src/experimental/campaigns/nccoe-pqc-migration/QuantumVulnerableDiscovery/WinCng.ql create mode 100644 cpp/ql/src/experimental/campaigns/nccoe-pqc-migration/QuantumVulnerableDiscovery/WindowsCng.qll create mode 100644 cpp/ql/src/experimental/campaigns/nccoe-pqc-migration/QuantumVulnerableDiscovery/WindowsCngPQVAsymmetricKeyUsage.qll create mode 100644 cpp/ql/test/experimental/campaigns/nccoe-pqc-migration/QuantumVulnerableDiscovery/WinCng.qlref diff --git a/cpp/ql/src/experimental/campaigns/nccoe-pqc-migration/QuantumVulnerableDiscovery/WinCng.ql b/cpp/ql/src/experimental/campaigns/nccoe-pqc-migration/QuantumVulnerableDiscovery/WinCng.ql new file mode 100644 index 00000000000..15400fb7f60 --- /dev/null +++ b/cpp/ql/src/experimental/campaigns/nccoe-pqc-migration/QuantumVulnerableDiscovery/WinCng.ql @@ -0,0 +1,39 @@ +/** + * @id cpp/nist-pqc/pqc-vulnerable-algorithms-cng + * @name Usage of PQC vulnerable algorithms + * @description Usage of PQC vulnerable algorithms. + * @microsoft.severity important + * @kind path-problem + * @problem.severity warning + * @precision high + * @tags security + * pqc + * nist + */ + +import cpp +import DataFlow::PathGraph +import WindowsCng +import WindowsCngPQVAsymmetricKeyUsage + +// CNG-specific DataFlow configuration +class BCryptConfiguration extends TaintTracking::Configuration { + BCryptConfiguration() { + this = "BCryptConfiguration" + } + override predicate isSource(DataFlow::Node source) { + source instanceof BCryptOpenAlgorithmProviderSource + } + + override predicate isSink(DataFlow::Node sink) { + sink instanceof BCryptOpenAlgorithmProviderSink + } + + override predicate isAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) { + isWindowsCngAsymmetricKeyAdditionalTaintStep( node1, node2) + } +} + +from BCryptConfiguration config, DataFlow::PathNode source, DataFlow::PathNode sink +where config.hasFlowPath(source, sink) +select sink.getNode(), source, sink, "PQC vulnerable algorithm in use has been detected." \ No newline at end of file diff --git a/cpp/ql/src/experimental/campaigns/nccoe-pqc-migration/QuantumVulnerableDiscovery/WindowsCng.qll b/cpp/ql/src/experimental/campaigns/nccoe-pqc-migration/QuantumVulnerableDiscovery/WindowsCng.qll new file mode 100644 index 00000000000..92f54b7ed0e --- /dev/null +++ b/cpp/ql/src/experimental/campaigns/nccoe-pqc-migration/QuantumVulnerableDiscovery/WindowsCng.qll @@ -0,0 +1,7 @@ +import cpp +import DataFlow::PathGraph +import semmle.code.cpp.dataflow.TaintTracking + +abstract class BCryptOpenAlgorithmProviderSink extends DataFlow::Node {} +abstract class BCryptOpenAlgorithmProviderSource extends DataFlow::Node {} + diff --git a/cpp/ql/src/experimental/campaigns/nccoe-pqc-migration/QuantumVulnerableDiscovery/WindowsCngPQVAsymmetricKeyUsage.qll b/cpp/ql/src/experimental/campaigns/nccoe-pqc-migration/QuantumVulnerableDiscovery/WindowsCngPQVAsymmetricKeyUsage.qll new file mode 100644 index 00000000000..1e354fb4abd --- /dev/null +++ b/cpp/ql/src/experimental/campaigns/nccoe-pqc-migration/QuantumVulnerableDiscovery/WindowsCngPQVAsymmetricKeyUsage.qll @@ -0,0 +1,81 @@ +import cpp +import WindowsCng + +//TODO: Verify NCrypt calls (parameters) & find all other APIs that should be included (i.e. decrypt, etc.) + +predicate isExprAlgIdForBCryptOpenAlgorithmProvider(Expr e){ + exists( FunctionCall call | + // BCryptOpenAlgorithmProvider 2nd argument specifies the algorithm to be used + e = call.getArgument(1) + and + call.getTarget().hasGlobalName("BCryptOpenAlgorithmProvider") + ) +} + +predicate isExprAlgHandleForBCryptGenerateOrImportKeyPair(Expr e){ + exists( FunctionCall call | + e = call.getArgument(0) + and + ( call.getTarget().hasGlobalName("BCryptImportKeyPair") or + call.getTarget().hasGlobalName("BCryptGenerateKeyPair")) + ) +} + +predicate isExprOutKeyHandleForBCryptGenerateOrImportKeyPair(Expr e){ + exists( FunctionCall call | + ( e = call.getArgument(3) and call.getTarget().hasGlobalName("BCryptImportKeyPair") )or + ( e = call.getArgument(1) and call.getTarget().hasGlobalName("BCryptGenerateKeyPair") ) + ) +} + +predicate isExprKeyHandleForBCryptSignHash(Expr e){ + exists( FunctionCall call | + e = call.getArgument(0) + and + call.getTarget().hasGlobalName("BCryptSignHash") + ) +} + +class BCryptSignHashArgumentSink extends BCryptOpenAlgorithmProviderSink { + BCryptSignHashArgumentSink() { + isExprKeyHandleForBCryptSignHash(this.asExpr()) + } +} + +class BCryptOpenAlgorithmProviderPqcVulnerableAlgorithmsSource extends BCryptOpenAlgorithmProviderSource { + BCryptOpenAlgorithmProviderPqcVulnerableAlgorithmsSource() { + this.asExpr() instanceof StringLiteral and + ( + this.asExpr().getValue() in ["DH", "DSA", "ECDSA", "ECDH"] + or this.asExpr().getValue().matches("ECDH%") + or this.asExpr().getValue().matches("RSA%") + ) + } + +} + +predicate isAdditionalTaintStepOpenAlgolrithmProviderToGenerateOrImportKeyPair(DataFlow::Node node1, DataFlow::Node node2) +{ + isExprAlgIdForBCryptOpenAlgorithmProvider(node1.asExpr()) and + isExprAlgHandleForBCryptGenerateOrImportKeyPair(node2.asExpr()) +} + + +predicate isAdditionalTaintStepWithinGenerateOrImportKeyPair(DataFlow::Node node1, DataFlow::Node node2) +{ + isExprAlgHandleForBCryptGenerateOrImportKeyPair(node1.asExpr()) and + isExprOutKeyHandleForBCryptGenerateOrImportKeyPair(node2.asExpr()) +} + +predicate isAdditionalTaintStepGenerateOrImportKeyPairToSignHash(DataFlow::Node node1, DataFlow::Node node2) +{ + isExprOutKeyHandleForBCryptGenerateOrImportKeyPair(node1.asExpr()) and + isExprKeyHandleForBCryptSignHash(node2.asExpr()) +} + +predicate isWindowsCngAsymmetricKeyAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) { + isAdditionalTaintStepOpenAlgolrithmProviderToGenerateOrImportKeyPair(node1, node2) + or isAdditionalTaintStepWithinGenerateOrImportKeyPair(node1, node2) + or isAdditionalTaintStepGenerateOrImportKeyPairToSignHash(node1, node2) +} + diff --git a/cpp/ql/test/experimental/campaigns/nccoe-pqc-migration/QuantumVulnerableDiscovery/WinCng.qlref b/cpp/ql/test/experimental/campaigns/nccoe-pqc-migration/QuantumVulnerableDiscovery/WinCng.qlref new file mode 100644 index 00000000000..6e6f369e60a --- /dev/null +++ b/cpp/ql/test/experimental/campaigns/nccoe-pqc-migration/QuantumVulnerableDiscovery/WinCng.qlref @@ -0,0 +1 @@ +experimental/campaigns/nccoe-pqc-migration/QuantumVulnerableDiscovery/WinCng.ql \ No newline at end of file From d4ba46ce82a19c4cf8e8eac4fbeb4d07d1091a5f Mon Sep 17 00:00:00 2001 From: Raul Garcia Date: Mon, 7 Nov 2022 15:05:28 -0800 Subject: [PATCH 163/631] Initial PR - Proof of Concept using CNG --- .../QuantumVulnerableDiscovery/WindowsCng.qll | 7 ++ .../WindowsCngPQCVAsymmetricKeyUsage.ql | 40 +++++++++ .../WindowsCngPQCVAsymmetricKeyUsage.qll | 81 +++++++++++++++++++ 3 files changed, 128 insertions(+) create mode 100644 cpp/ql/src/experimental/campaigns/nccoe-pqc-migration/QuantumVulnerableDiscovery/WindowsCng.qll create mode 100644 cpp/ql/src/experimental/campaigns/nccoe-pqc-migration/QuantumVulnerableDiscovery/WindowsCngPQCVAsymmetricKeyUsage.ql create mode 100644 cpp/ql/src/experimental/campaigns/nccoe-pqc-migration/QuantumVulnerableDiscovery/WindowsCngPQCVAsymmetricKeyUsage.qll diff --git a/cpp/ql/src/experimental/campaigns/nccoe-pqc-migration/QuantumVulnerableDiscovery/WindowsCng.qll b/cpp/ql/src/experimental/campaigns/nccoe-pqc-migration/QuantumVulnerableDiscovery/WindowsCng.qll new file mode 100644 index 00000000000..92f54b7ed0e --- /dev/null +++ b/cpp/ql/src/experimental/campaigns/nccoe-pqc-migration/QuantumVulnerableDiscovery/WindowsCng.qll @@ -0,0 +1,7 @@ +import cpp +import DataFlow::PathGraph +import semmle.code.cpp.dataflow.TaintTracking + +abstract class BCryptOpenAlgorithmProviderSink extends DataFlow::Node {} +abstract class BCryptOpenAlgorithmProviderSource extends DataFlow::Node {} + diff --git a/cpp/ql/src/experimental/campaigns/nccoe-pqc-migration/QuantumVulnerableDiscovery/WindowsCngPQCVAsymmetricKeyUsage.ql b/cpp/ql/src/experimental/campaigns/nccoe-pqc-migration/QuantumVulnerableDiscovery/WindowsCngPQCVAsymmetricKeyUsage.ql new file mode 100644 index 00000000000..86fe64528ee --- /dev/null +++ b/cpp/ql/src/experimental/campaigns/nccoe-pqc-migration/QuantumVulnerableDiscovery/WindowsCngPQCVAsymmetricKeyUsage.ql @@ -0,0 +1,40 @@ +/** + * @id cpp/nist-pqc/pqc-vulnerable-algorithms-cng + * @name Usage of PQC vulnerable algorithms + * @description Usage of PQC vulnerable algorithms. + * @microsoft.severity important + * @kind path-problem + * @problem.severity warning + * @precision high + * @tags security + * pqc + * nist + */ + +import cpp +import DataFlow::PathGraph +import WindowsCng +import WindowsCngPQCVAsymmetricKeyUsage + +// CNG-specific DataFlow configuration +class BCryptConfiguration extends DataFlow::Configuration { + BCryptConfiguration() { + this = "BCryptConfiguration" + } + override predicate isSource(DataFlow::Node source) { + source instanceof BCryptOpenAlgorithmProviderSource + } + + override predicate isSink(DataFlow::Node sink) { + sink instanceof BCryptOpenAlgorithmProviderSink + } + + override predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) { + isWindowsCngAsymmetricKeyAdditionalTaintStep( node1, node2) + } +} + +from BCryptConfiguration config, DataFlow::PathNode source, DataFlow::PathNode sink +where config.hasFlowPath(source, sink) +select sink.getNode(), source, sink, "PQC vulnerable algorithm $@ in use has been detected.", + source.getNode().asExpr(), source.getNode().asExpr().toString() \ No newline at end of file diff --git a/cpp/ql/src/experimental/campaigns/nccoe-pqc-migration/QuantumVulnerableDiscovery/WindowsCngPQCVAsymmetricKeyUsage.qll b/cpp/ql/src/experimental/campaigns/nccoe-pqc-migration/QuantumVulnerableDiscovery/WindowsCngPQCVAsymmetricKeyUsage.qll new file mode 100644 index 00000000000..1e354fb4abd --- /dev/null +++ b/cpp/ql/src/experimental/campaigns/nccoe-pqc-migration/QuantumVulnerableDiscovery/WindowsCngPQCVAsymmetricKeyUsage.qll @@ -0,0 +1,81 @@ +import cpp +import WindowsCng + +//TODO: Verify NCrypt calls (parameters) & find all other APIs that should be included (i.e. decrypt, etc.) + +predicate isExprAlgIdForBCryptOpenAlgorithmProvider(Expr e){ + exists( FunctionCall call | + // BCryptOpenAlgorithmProvider 2nd argument specifies the algorithm to be used + e = call.getArgument(1) + and + call.getTarget().hasGlobalName("BCryptOpenAlgorithmProvider") + ) +} + +predicate isExprAlgHandleForBCryptGenerateOrImportKeyPair(Expr e){ + exists( FunctionCall call | + e = call.getArgument(0) + and + ( call.getTarget().hasGlobalName("BCryptImportKeyPair") or + call.getTarget().hasGlobalName("BCryptGenerateKeyPair")) + ) +} + +predicate isExprOutKeyHandleForBCryptGenerateOrImportKeyPair(Expr e){ + exists( FunctionCall call | + ( e = call.getArgument(3) and call.getTarget().hasGlobalName("BCryptImportKeyPair") )or + ( e = call.getArgument(1) and call.getTarget().hasGlobalName("BCryptGenerateKeyPair") ) + ) +} + +predicate isExprKeyHandleForBCryptSignHash(Expr e){ + exists( FunctionCall call | + e = call.getArgument(0) + and + call.getTarget().hasGlobalName("BCryptSignHash") + ) +} + +class BCryptSignHashArgumentSink extends BCryptOpenAlgorithmProviderSink { + BCryptSignHashArgumentSink() { + isExprKeyHandleForBCryptSignHash(this.asExpr()) + } +} + +class BCryptOpenAlgorithmProviderPqcVulnerableAlgorithmsSource extends BCryptOpenAlgorithmProviderSource { + BCryptOpenAlgorithmProviderPqcVulnerableAlgorithmsSource() { + this.asExpr() instanceof StringLiteral and + ( + this.asExpr().getValue() in ["DH", "DSA", "ECDSA", "ECDH"] + or this.asExpr().getValue().matches("ECDH%") + or this.asExpr().getValue().matches("RSA%") + ) + } + +} + +predicate isAdditionalTaintStepOpenAlgolrithmProviderToGenerateOrImportKeyPair(DataFlow::Node node1, DataFlow::Node node2) +{ + isExprAlgIdForBCryptOpenAlgorithmProvider(node1.asExpr()) and + isExprAlgHandleForBCryptGenerateOrImportKeyPair(node2.asExpr()) +} + + +predicate isAdditionalTaintStepWithinGenerateOrImportKeyPair(DataFlow::Node node1, DataFlow::Node node2) +{ + isExprAlgHandleForBCryptGenerateOrImportKeyPair(node1.asExpr()) and + isExprOutKeyHandleForBCryptGenerateOrImportKeyPair(node2.asExpr()) +} + +predicate isAdditionalTaintStepGenerateOrImportKeyPairToSignHash(DataFlow::Node node1, DataFlow::Node node2) +{ + isExprOutKeyHandleForBCryptGenerateOrImportKeyPair(node1.asExpr()) and + isExprKeyHandleForBCryptSignHash(node2.asExpr()) +} + +predicate isWindowsCngAsymmetricKeyAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) { + isAdditionalTaintStepOpenAlgolrithmProviderToGenerateOrImportKeyPair(node1, node2) + or isAdditionalTaintStepWithinGenerateOrImportKeyPair(node1, node2) + or isAdditionalTaintStepGenerateOrImportKeyPairToSignHash(node1, node2) +} + From 96116c2d2d38b4a9719beaf5efe69ae4421ee5fc Mon Sep 17 00:00:00 2001 From: "REDMOND\\brodes" Date: Tue, 8 Nov 2022 10:59:13 -0500 Subject: [PATCH 164/631] Suggested query changes. --- .../QuantumVulnerableDiscovery/WinCng.ql | 2 +- .../WindowsCngPQCVAsymmetricKeyUsage.qll | 57 +++++++++++++ .../WindowsCngPQVAsymmetricKeyUsage.qll | 81 ------------------- 3 files changed, 58 insertions(+), 82 deletions(-) create mode 100644 cpp/ql/src/experimental/campaigns/nccoe-pqc-migration/QuantumVulnerableDiscovery/WindowsCngPQCVAsymmetricKeyUsage.qll delete mode 100644 cpp/ql/src/experimental/campaigns/nccoe-pqc-migration/QuantumVulnerableDiscovery/WindowsCngPQVAsymmetricKeyUsage.qll diff --git a/cpp/ql/src/experimental/campaigns/nccoe-pqc-migration/QuantumVulnerableDiscovery/WinCng.ql b/cpp/ql/src/experimental/campaigns/nccoe-pqc-migration/QuantumVulnerableDiscovery/WinCng.ql index 15400fb7f60..195a8ee85dc 100644 --- a/cpp/ql/src/experimental/campaigns/nccoe-pqc-migration/QuantumVulnerableDiscovery/WinCng.ql +++ b/cpp/ql/src/experimental/campaigns/nccoe-pqc-migration/QuantumVulnerableDiscovery/WinCng.ql @@ -14,7 +14,7 @@ import cpp import DataFlow::PathGraph import WindowsCng -import WindowsCngPQVAsymmetricKeyUsage +import WindowsCngPQCVAsymmetricKeyUsage // CNG-specific DataFlow configuration class BCryptConfiguration extends TaintTracking::Configuration { diff --git a/cpp/ql/src/experimental/campaigns/nccoe-pqc-migration/QuantumVulnerableDiscovery/WindowsCngPQCVAsymmetricKeyUsage.qll b/cpp/ql/src/experimental/campaigns/nccoe-pqc-migration/QuantumVulnerableDiscovery/WindowsCngPQCVAsymmetricKeyUsage.qll new file mode 100644 index 00000000000..14dd5e4beda --- /dev/null +++ b/cpp/ql/src/experimental/campaigns/nccoe-pqc-migration/QuantumVulnerableDiscovery/WindowsCngPQCVAsymmetricKeyUsage.qll @@ -0,0 +1,57 @@ +import cpp +import WindowsCng +//TODO: Verify NCrypt calls (parameters) & find all other APIs that should be included (i.e. decrypt, etc.) +predicate isExprKeyHandleForBCryptSignHash(Expr e){ + exists( FunctionCall call | + e = call.getArgument(0) + and + call.getTarget().hasGlobalName("BCryptSignHash") + ) +} + +class BCryptSignHashArgumentSink extends BCryptOpenAlgorithmProviderSink { + BCryptSignHashArgumentSink() { + isExprKeyHandleForBCryptSignHash(this.asExpr()) + } +} + +class BCryptOpenAlgorithmProviderPqcVulnerableAlgorithmsSource extends BCryptOpenAlgorithmProviderSource { + BCryptOpenAlgorithmProviderPqcVulnerableAlgorithmsSource() { + this.asExpr() instanceof StringLiteral and + ( + this.asExpr().getValue() in ["DH", "DSA", "ECDSA", "ECDH"] + or this.asExpr().getValue().matches("ECDH%") + or this.asExpr().getValue().matches("RSA%") + ) + } +} + +predicate stepOpenAlgorithmProvider(DataFlow::Node node1, DataFlow::Node node2) +{ + exists( FunctionCall call | + // BCryptOpenAlgorithmProvider 2nd argument specifies the algorithm to be used + node1.asExpr() = call.getArgument(1) + and + call.getTarget().hasGlobalName("BCryptOpenAlgorithmProvider") + and + node2.asDefiningArgument() = call.getArgument(0) + ) +} + +predicate stepImportGenerateKeyPair(DataFlow::Node node1, DataFlow::Node node2) +{ + exists( FunctionCall call | + node1.asExpr() = call.getArgument(0) + and + ( call.getTarget().hasGlobalName("BCryptImportKeyPair") or + call.getTarget().hasGlobalName("BCryptGenerateKeyPair")) + and + node2.asDefiningArgument() = call.getArgument(1) + ) +} + +predicate isWindowsCngAsymmetricKeyAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) { + stepOpenAlgorithmProvider(node1, node2) + or + stepImportGenerateKeyPair(node1, node2) +} \ No newline at end of file diff --git a/cpp/ql/src/experimental/campaigns/nccoe-pqc-migration/QuantumVulnerableDiscovery/WindowsCngPQVAsymmetricKeyUsage.qll b/cpp/ql/src/experimental/campaigns/nccoe-pqc-migration/QuantumVulnerableDiscovery/WindowsCngPQVAsymmetricKeyUsage.qll deleted file mode 100644 index 1e354fb4abd..00000000000 --- a/cpp/ql/src/experimental/campaigns/nccoe-pqc-migration/QuantumVulnerableDiscovery/WindowsCngPQVAsymmetricKeyUsage.qll +++ /dev/null @@ -1,81 +0,0 @@ -import cpp -import WindowsCng - -//TODO: Verify NCrypt calls (parameters) & find all other APIs that should be included (i.e. decrypt, etc.) - -predicate isExprAlgIdForBCryptOpenAlgorithmProvider(Expr e){ - exists( FunctionCall call | - // BCryptOpenAlgorithmProvider 2nd argument specifies the algorithm to be used - e = call.getArgument(1) - and - call.getTarget().hasGlobalName("BCryptOpenAlgorithmProvider") - ) -} - -predicate isExprAlgHandleForBCryptGenerateOrImportKeyPair(Expr e){ - exists( FunctionCall call | - e = call.getArgument(0) - and - ( call.getTarget().hasGlobalName("BCryptImportKeyPair") or - call.getTarget().hasGlobalName("BCryptGenerateKeyPair")) - ) -} - -predicate isExprOutKeyHandleForBCryptGenerateOrImportKeyPair(Expr e){ - exists( FunctionCall call | - ( e = call.getArgument(3) and call.getTarget().hasGlobalName("BCryptImportKeyPair") )or - ( e = call.getArgument(1) and call.getTarget().hasGlobalName("BCryptGenerateKeyPair") ) - ) -} - -predicate isExprKeyHandleForBCryptSignHash(Expr e){ - exists( FunctionCall call | - e = call.getArgument(0) - and - call.getTarget().hasGlobalName("BCryptSignHash") - ) -} - -class BCryptSignHashArgumentSink extends BCryptOpenAlgorithmProviderSink { - BCryptSignHashArgumentSink() { - isExprKeyHandleForBCryptSignHash(this.asExpr()) - } -} - -class BCryptOpenAlgorithmProviderPqcVulnerableAlgorithmsSource extends BCryptOpenAlgorithmProviderSource { - BCryptOpenAlgorithmProviderPqcVulnerableAlgorithmsSource() { - this.asExpr() instanceof StringLiteral and - ( - this.asExpr().getValue() in ["DH", "DSA", "ECDSA", "ECDH"] - or this.asExpr().getValue().matches("ECDH%") - or this.asExpr().getValue().matches("RSA%") - ) - } - -} - -predicate isAdditionalTaintStepOpenAlgolrithmProviderToGenerateOrImportKeyPair(DataFlow::Node node1, DataFlow::Node node2) -{ - isExprAlgIdForBCryptOpenAlgorithmProvider(node1.asExpr()) and - isExprAlgHandleForBCryptGenerateOrImportKeyPair(node2.asExpr()) -} - - -predicate isAdditionalTaintStepWithinGenerateOrImportKeyPair(DataFlow::Node node1, DataFlow::Node node2) -{ - isExprAlgHandleForBCryptGenerateOrImportKeyPair(node1.asExpr()) and - isExprOutKeyHandleForBCryptGenerateOrImportKeyPair(node2.asExpr()) -} - -predicate isAdditionalTaintStepGenerateOrImportKeyPairToSignHash(DataFlow::Node node1, DataFlow::Node node2) -{ - isExprOutKeyHandleForBCryptGenerateOrImportKeyPair(node1.asExpr()) and - isExprKeyHandleForBCryptSignHash(node2.asExpr()) -} - -predicate isWindowsCngAsymmetricKeyAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) { - isAdditionalTaintStepOpenAlgolrithmProviderToGenerateOrImportKeyPair(node1, node2) - or isAdditionalTaintStepWithinGenerateOrImportKeyPair(node1, node2) - or isAdditionalTaintStepGenerateOrImportKeyPairToSignHash(node1, node2) -} - From 7a27635a11eb27bcfa00e87d777b027667a5866d Mon Sep 17 00:00:00 2001 From: "REDMOND\\brodes" Date: Tue, 8 Nov 2022 12:11:43 -0500 Subject: [PATCH 165/631] Moving queries and modifying query to include BCryptEncrypt --- .../{ => WinCng}/WinCng.ql | 2 +- .../{ => WinCng}/WindowsCng.qll | 0 .../WindowsCngPQCVulnerableUsage.ql} | 0 .../WindowsCngPQCVulnerableUsage.qll} | 14 ++++++++++++-- 4 files changed, 13 insertions(+), 3 deletions(-) rename cpp/ql/src/experimental/campaigns/nccoe-pqc-migration/QuantumVulnerableDiscovery/{ => WinCng}/WinCng.ql (94%) rename cpp/ql/src/experimental/campaigns/nccoe-pqc-migration/QuantumVulnerableDiscovery/{ => WinCng}/WindowsCng.qll (100%) rename cpp/ql/src/experimental/campaigns/nccoe-pqc-migration/QuantumVulnerableDiscovery/{WindowsCngPQCVAsymmetricKeyUsage.ql => WinCng/WindowsCngPQCVulnerableUsage.ql} (100%) rename cpp/ql/src/experimental/campaigns/nccoe-pqc-migration/QuantumVulnerableDiscovery/{WindowsCngPQCVAsymmetricKeyUsage.qll => WinCng/WindowsCngPQCVulnerableUsage.qll} (86%) diff --git a/cpp/ql/src/experimental/campaigns/nccoe-pqc-migration/QuantumVulnerableDiscovery/WinCng.ql b/cpp/ql/src/experimental/campaigns/nccoe-pqc-migration/QuantumVulnerableDiscovery/WinCng/WinCng.ql similarity index 94% rename from cpp/ql/src/experimental/campaigns/nccoe-pqc-migration/QuantumVulnerableDiscovery/WinCng.ql rename to cpp/ql/src/experimental/campaigns/nccoe-pqc-migration/QuantumVulnerableDiscovery/WinCng/WinCng.ql index 195a8ee85dc..7f19a74aa70 100644 --- a/cpp/ql/src/experimental/campaigns/nccoe-pqc-migration/QuantumVulnerableDiscovery/WinCng.ql +++ b/cpp/ql/src/experimental/campaigns/nccoe-pqc-migration/QuantumVulnerableDiscovery/WinCng/WinCng.ql @@ -14,7 +14,7 @@ import cpp import DataFlow::PathGraph import WindowsCng -import WindowsCngPQCVAsymmetricKeyUsage +import WindowsCngPQCVulnerableUsage // CNG-specific DataFlow configuration class BCryptConfiguration extends TaintTracking::Configuration { diff --git a/cpp/ql/src/experimental/campaigns/nccoe-pqc-migration/QuantumVulnerableDiscovery/WindowsCng.qll b/cpp/ql/src/experimental/campaigns/nccoe-pqc-migration/QuantumVulnerableDiscovery/WinCng/WindowsCng.qll similarity index 100% rename from cpp/ql/src/experimental/campaigns/nccoe-pqc-migration/QuantumVulnerableDiscovery/WindowsCng.qll rename to cpp/ql/src/experimental/campaigns/nccoe-pqc-migration/QuantumVulnerableDiscovery/WinCng/WindowsCng.qll diff --git a/cpp/ql/src/experimental/campaigns/nccoe-pqc-migration/QuantumVulnerableDiscovery/WindowsCngPQCVAsymmetricKeyUsage.ql b/cpp/ql/src/experimental/campaigns/nccoe-pqc-migration/QuantumVulnerableDiscovery/WinCng/WindowsCngPQCVulnerableUsage.ql similarity index 100% rename from cpp/ql/src/experimental/campaigns/nccoe-pqc-migration/QuantumVulnerableDiscovery/WindowsCngPQCVAsymmetricKeyUsage.ql rename to cpp/ql/src/experimental/campaigns/nccoe-pqc-migration/QuantumVulnerableDiscovery/WinCng/WindowsCngPQCVulnerableUsage.ql diff --git a/cpp/ql/src/experimental/campaigns/nccoe-pqc-migration/QuantumVulnerableDiscovery/WindowsCngPQCVAsymmetricKeyUsage.qll b/cpp/ql/src/experimental/campaigns/nccoe-pqc-migration/QuantumVulnerableDiscovery/WinCng/WindowsCngPQCVulnerableUsage.qll similarity index 86% rename from cpp/ql/src/experimental/campaigns/nccoe-pqc-migration/QuantumVulnerableDiscovery/WindowsCngPQCVAsymmetricKeyUsage.qll rename to cpp/ql/src/experimental/campaigns/nccoe-pqc-migration/QuantumVulnerableDiscovery/WinCng/WindowsCngPQCVulnerableUsage.qll index 14dd5e4beda..48e9d1326fc 100644 --- a/cpp/ql/src/experimental/campaigns/nccoe-pqc-migration/QuantumVulnerableDiscovery/WindowsCngPQCVAsymmetricKeyUsage.qll +++ b/cpp/ql/src/experimental/campaigns/nccoe-pqc-migration/QuantumVulnerableDiscovery/WinCng/WindowsCngPQCVulnerableUsage.qll @@ -1,11 +1,21 @@ import cpp import WindowsCng + +predicate vulnerableCngFunctionName(string name) { + name in ["BCryptSignHash", "BCryptEncrypt"] +} + +predicate vulnerableCngFunction(Function f) +{ + exists(string name | f.hasGlobalName(name) and vulnerableCngFunctionName(name)) +} + //TODO: Verify NCrypt calls (parameters) & find all other APIs that should be included (i.e. decrypt, etc.) predicate isExprKeyHandleForBCryptSignHash(Expr e){ exists( FunctionCall call | e = call.getArgument(0) - and - call.getTarget().hasGlobalName("BCryptSignHash") + and + vulnerableCngFunction(call.getTarget()) ) } From 1e9c2b3335bdea69e9f88e976eed7dbb985cde0f Mon Sep 17 00:00:00 2001 From: "REDMOND\\brodes" Date: Tue, 8 Nov 2022 12:13:05 -0500 Subject: [PATCH 166/631] Applied formatting. --- .../WinCng/WindowsCngPQCVulnerableUsage.qll | 84 ++++++++----------- 1 file changed, 37 insertions(+), 47 deletions(-) diff --git a/cpp/ql/src/experimental/campaigns/nccoe-pqc-migration/QuantumVulnerableDiscovery/WinCng/WindowsCngPQCVulnerableUsage.qll b/cpp/ql/src/experimental/campaigns/nccoe-pqc-migration/QuantumVulnerableDiscovery/WinCng/WindowsCngPQCVulnerableUsage.qll index 48e9d1326fc..9af62fdfa97 100644 --- a/cpp/ql/src/experimental/campaigns/nccoe-pqc-migration/QuantumVulnerableDiscovery/WinCng/WindowsCngPQCVulnerableUsage.qll +++ b/cpp/ql/src/experimental/campaigns/nccoe-pqc-migration/QuantumVulnerableDiscovery/WinCng/WindowsCngPQCVulnerableUsage.qll @@ -1,67 +1,57 @@ import cpp import WindowsCng -predicate vulnerableCngFunctionName(string name) { - name in ["BCryptSignHash", "BCryptEncrypt"] -} +predicate vulnerableCngFunctionName(string name) { name in ["BCryptSignHash", "BCryptEncrypt"] } -predicate vulnerableCngFunction(Function f) -{ - exists(string name | f.hasGlobalName(name) and vulnerableCngFunctionName(name)) +predicate vulnerableCngFunction(Function f) { + exists(string name | f.hasGlobalName(name) and vulnerableCngFunctionName(name)) } //TODO: Verify NCrypt calls (parameters) & find all other APIs that should be included (i.e. decrypt, etc.) -predicate isExprKeyHandleForBCryptSignHash(Expr e){ - exists( FunctionCall call | - e = call.getArgument(0) - and - vulnerableCngFunction(call.getTarget()) - ) +predicate isExprKeyHandleForBCryptSignHash(Expr e) { + exists(FunctionCall call | + e = call.getArgument(0) and + vulnerableCngFunction(call.getTarget()) + ) } class BCryptSignHashArgumentSink extends BCryptOpenAlgorithmProviderSink { - BCryptSignHashArgumentSink() { - isExprKeyHandleForBCryptSignHash(this.asExpr()) - } + BCryptSignHashArgumentSink() { isExprKeyHandleForBCryptSignHash(this.asExpr()) } } class BCryptOpenAlgorithmProviderPqcVulnerableAlgorithmsSource extends BCryptOpenAlgorithmProviderSource { - BCryptOpenAlgorithmProviderPqcVulnerableAlgorithmsSource() { - this.asExpr() instanceof StringLiteral and - ( - this.asExpr().getValue() in ["DH", "DSA", "ECDSA", "ECDH"] - or this.asExpr().getValue().matches("ECDH%") - or this.asExpr().getValue().matches("RSA%") - ) - } + BCryptOpenAlgorithmProviderPqcVulnerableAlgorithmsSource() { + this.asExpr() instanceof StringLiteral and + ( + this.asExpr().getValue() in ["DH", "DSA", "ECDSA", "ECDH"] or + this.asExpr().getValue().matches("ECDH%") or + this.asExpr().getValue().matches("RSA%") + ) + } } -predicate stepOpenAlgorithmProvider(DataFlow::Node node1, DataFlow::Node node2) -{ - exists( FunctionCall call | - // BCryptOpenAlgorithmProvider 2nd argument specifies the algorithm to be used - node1.asExpr() = call.getArgument(1) - and - call.getTarget().hasGlobalName("BCryptOpenAlgorithmProvider") - and - node2.asDefiningArgument() = call.getArgument(0) - ) +predicate stepOpenAlgorithmProvider(DataFlow::Node node1, DataFlow::Node node2) { + exists(FunctionCall call | + // BCryptOpenAlgorithmProvider 2nd argument specifies the algorithm to be used + node1.asExpr() = call.getArgument(1) and + call.getTarget().hasGlobalName("BCryptOpenAlgorithmProvider") and + node2.asDefiningArgument() = call.getArgument(0) + ) } -predicate stepImportGenerateKeyPair(DataFlow::Node node1, DataFlow::Node node2) -{ - exists( FunctionCall call | - node1.asExpr() = call.getArgument(0) - and - ( call.getTarget().hasGlobalName("BCryptImportKeyPair") or - call.getTarget().hasGlobalName("BCryptGenerateKeyPair")) - and - node2.asDefiningArgument() = call.getArgument(1) - ) +predicate stepImportGenerateKeyPair(DataFlow::Node node1, DataFlow::Node node2) { + exists(FunctionCall call | + node1.asExpr() = call.getArgument(0) and + ( + call.getTarget().hasGlobalName("BCryptImportKeyPair") or + call.getTarget().hasGlobalName("BCryptGenerateKeyPair") + ) and + node2.asDefiningArgument() = call.getArgument(1) + ) } predicate isWindowsCngAsymmetricKeyAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) { - stepOpenAlgorithmProvider(node1, node2) - or - stepImportGenerateKeyPair(node1, node2) -} \ No newline at end of file + stepOpenAlgorithmProvider(node1, node2) + or + stepImportGenerateKeyPair(node1, node2) +} From 43760b6bb125e91a454b9a6d4be1232e0e857e51 Mon Sep 17 00:00:00 2001 From: "REDMOND\\brodes" Date: Tue, 8 Nov 2022 12:20:15 -0500 Subject: [PATCH 167/631] Misc. compartmentalization and naming changes. --- .../WinCng/WindowsCngPQCVulnerableUsage.ql | 4 ++-- .../WinCng/WindowsCngPQCVulnerableUsage.qll | 13 ++++++++----- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/cpp/ql/src/experimental/campaigns/nccoe-pqc-migration/QuantumVulnerableDiscovery/WinCng/WindowsCngPQCVulnerableUsage.ql b/cpp/ql/src/experimental/campaigns/nccoe-pqc-migration/QuantumVulnerableDiscovery/WinCng/WindowsCngPQCVulnerableUsage.ql index 86fe64528ee..b77ad05ced0 100644 --- a/cpp/ql/src/experimental/campaigns/nccoe-pqc-migration/QuantumVulnerableDiscovery/WinCng/WindowsCngPQCVulnerableUsage.ql +++ b/cpp/ql/src/experimental/campaigns/nccoe-pqc-migration/QuantumVulnerableDiscovery/WinCng/WindowsCngPQCVulnerableUsage.ql @@ -14,7 +14,7 @@ import cpp import DataFlow::PathGraph import WindowsCng -import WindowsCngPQCVAsymmetricKeyUsage +import WindowsCngPQCVulnerableUsage // CNG-specific DataFlow configuration class BCryptConfiguration extends DataFlow::Configuration { @@ -30,7 +30,7 @@ class BCryptConfiguration extends DataFlow::Configuration { } override predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) { - isWindowsCngAsymmetricKeyAdditionalTaintStep( node1, node2) + isWindowsCngAdditionalTaintStep( node1, node2) } } diff --git a/cpp/ql/src/experimental/campaigns/nccoe-pqc-migration/QuantumVulnerableDiscovery/WinCng/WindowsCngPQCVulnerableUsage.qll b/cpp/ql/src/experimental/campaigns/nccoe-pqc-migration/QuantumVulnerableDiscovery/WinCng/WindowsCngPQCVulnerableUsage.qll index 9af62fdfa97..17139faabe6 100644 --- a/cpp/ql/src/experimental/campaigns/nccoe-pqc-migration/QuantumVulnerableDiscovery/WinCng/WindowsCngPQCVulnerableUsage.qll +++ b/cpp/ql/src/experimental/campaigns/nccoe-pqc-migration/QuantumVulnerableDiscovery/WinCng/WindowsCngPQCVulnerableUsage.qll @@ -3,10 +3,16 @@ import WindowsCng predicate vulnerableCngFunctionName(string name) { name in ["BCryptSignHash", "BCryptEncrypt"] } +predicate keyGenAndImportFunctionName(string name) { name in ["BCryptImportKeyPair", "BCryptGenerateKeyPair"] } + predicate vulnerableCngFunction(Function f) { exists(string name | f.hasGlobalName(name) and vulnerableCngFunctionName(name)) } +predicate keyGenAndImportFunction(Function f){ + exists(string name | f.hasGlobalName(name) and keyGenAndImportFunctionName(name)) +} + //TODO: Verify NCrypt calls (parameters) & find all other APIs that should be included (i.e. decrypt, etc.) predicate isExprKeyHandleForBCryptSignHash(Expr e) { exists(FunctionCall call | @@ -42,15 +48,12 @@ predicate stepOpenAlgorithmProvider(DataFlow::Node node1, DataFlow::Node node2) predicate stepImportGenerateKeyPair(DataFlow::Node node1, DataFlow::Node node2) { exists(FunctionCall call | node1.asExpr() = call.getArgument(0) and - ( - call.getTarget().hasGlobalName("BCryptImportKeyPair") or - call.getTarget().hasGlobalName("BCryptGenerateKeyPair") - ) and + keyGenAndImportFunction(call.getTarget()) and node2.asDefiningArgument() = call.getArgument(1) ) } -predicate isWindowsCngAsymmetricKeyAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) { +predicate isWindowsCngAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) { stepOpenAlgorithmProvider(node1, node2) or stepImportGenerateKeyPair(node1, node2) From eceda7a787bd5e3ac9a7d8bcb53cff12062f474a Mon Sep 17 00:00:00 2001 From: "REDMOND\\brodes" Date: Tue, 8 Nov 2022 12:39:49 -0500 Subject: [PATCH 168/631] More cleanup --- .../WinCng/WinCng.ql | 39 ------------------- .../WinCng/WindowsCngPQCVulnerableUsage.qll | 22 +++++------ 2 files changed, 10 insertions(+), 51 deletions(-) delete mode 100644 cpp/ql/src/experimental/campaigns/nccoe-pqc-migration/QuantumVulnerableDiscovery/WinCng/WinCng.ql diff --git a/cpp/ql/src/experimental/campaigns/nccoe-pqc-migration/QuantumVulnerableDiscovery/WinCng/WinCng.ql b/cpp/ql/src/experimental/campaigns/nccoe-pqc-migration/QuantumVulnerableDiscovery/WinCng/WinCng.ql deleted file mode 100644 index 7f19a74aa70..00000000000 --- a/cpp/ql/src/experimental/campaigns/nccoe-pqc-migration/QuantumVulnerableDiscovery/WinCng/WinCng.ql +++ /dev/null @@ -1,39 +0,0 @@ -/** - * @id cpp/nist-pqc/pqc-vulnerable-algorithms-cng - * @name Usage of PQC vulnerable algorithms - * @description Usage of PQC vulnerable algorithms. - * @microsoft.severity important - * @kind path-problem - * @problem.severity warning - * @precision high - * @tags security - * pqc - * nist - */ - -import cpp -import DataFlow::PathGraph -import WindowsCng -import WindowsCngPQCVulnerableUsage - -// CNG-specific DataFlow configuration -class BCryptConfiguration extends TaintTracking::Configuration { - BCryptConfiguration() { - this = "BCryptConfiguration" - } - override predicate isSource(DataFlow::Node source) { - source instanceof BCryptOpenAlgorithmProviderSource - } - - override predicate isSink(DataFlow::Node sink) { - sink instanceof BCryptOpenAlgorithmProviderSink - } - - override predicate isAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) { - isWindowsCngAsymmetricKeyAdditionalTaintStep( node1, node2) - } -} - -from BCryptConfiguration config, DataFlow::PathNode source, DataFlow::PathNode sink -where config.hasFlowPath(source, sink) -select sink.getNode(), source, sink, "PQC vulnerable algorithm in use has been detected." \ No newline at end of file diff --git a/cpp/ql/src/experimental/campaigns/nccoe-pqc-migration/QuantumVulnerableDiscovery/WinCng/WindowsCngPQCVulnerableUsage.qll b/cpp/ql/src/experimental/campaigns/nccoe-pqc-migration/QuantumVulnerableDiscovery/WinCng/WindowsCngPQCVulnerableUsage.qll index 17139faabe6..fbac511039b 100644 --- a/cpp/ql/src/experimental/campaigns/nccoe-pqc-migration/QuantumVulnerableDiscovery/WinCng/WindowsCngPQCVulnerableUsage.qll +++ b/cpp/ql/src/experimental/campaigns/nccoe-pqc-migration/QuantumVulnerableDiscovery/WinCng/WindowsCngPQCVulnerableUsage.qll @@ -1,30 +1,28 @@ import cpp import WindowsCng -predicate vulnerableCngFunctionName(string name) { name in ["BCryptSignHash", "BCryptEncrypt"] } - predicate keyGenAndImportFunctionName(string name) { name in ["BCryptImportKeyPair", "BCryptGenerateKeyPair"] } -predicate vulnerableCngFunction(Function f) { - exists(string name | f.hasGlobalName(name) and vulnerableCngFunctionName(name)) -} - predicate keyGenAndImportFunction(Function f){ exists(string name | f.hasGlobalName(name) and keyGenAndImportFunctionName(name)) } //TODO: Verify NCrypt calls (parameters) & find all other APIs that should be included (i.e. decrypt, etc.) -predicate isExprKeyHandleForBCryptSignHash(Expr e) { - exists(FunctionCall call | - e = call.getArgument(0) and - vulnerableCngFunction(call.getTarget()) - ) + + +predicate isCallArgument(string funcGlobalName, Expr arg, int index){ + exists(Call c | c.getArgument(index) = arg and c.getTarget().hasGlobalName(funcGlobalName)) } class BCryptSignHashArgumentSink extends BCryptOpenAlgorithmProviderSink { - BCryptSignHashArgumentSink() { isExprKeyHandleForBCryptSignHash(this.asExpr()) } + BCryptSignHashArgumentSink() { isCallArgument("BCryptSignHash", this.asExpr(), 0) } } +class BCryptEncryptArgumentSink extends BCryptOpenAlgorithmProviderSink { + BCryptEncryptArgumentSink() { isCallArgument("BCryptEncrypt", this.asExpr(), 0) } + } + + class BCryptOpenAlgorithmProviderPqcVulnerableAlgorithmsSource extends BCryptOpenAlgorithmProviderSource { BCryptOpenAlgorithmProviderPqcVulnerableAlgorithmsSource() { this.asExpr() instanceof StringLiteral and From da8a7f36d18263f213cf86f1652ae7aeea29f963 Mon Sep 17 00:00:00 2001 From: "REDMOND\\brodes" Date: Tue, 8 Nov 2022 12:43:22 -0500 Subject: [PATCH 169/631] More cleanup --- .../WinCng/WindowsCngPQCVulnerableUsage.qll | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/cpp/ql/src/experimental/campaigns/nccoe-pqc-migration/QuantumVulnerableDiscovery/WinCng/WindowsCngPQCVulnerableUsage.qll b/cpp/ql/src/experimental/campaigns/nccoe-pqc-migration/QuantumVulnerableDiscovery/WinCng/WindowsCngPQCVulnerableUsage.qll index fbac511039b..412941a48e5 100644 --- a/cpp/ql/src/experimental/campaigns/nccoe-pqc-migration/QuantumVulnerableDiscovery/WinCng/WindowsCngPQCVulnerableUsage.qll +++ b/cpp/ql/src/experimental/campaigns/nccoe-pqc-migration/QuantumVulnerableDiscovery/WinCng/WindowsCngPQCVulnerableUsage.qll @@ -1,12 +1,6 @@ import cpp import WindowsCng -predicate keyGenAndImportFunctionName(string name) { name in ["BCryptImportKeyPair", "BCryptGenerateKeyPair"] } - -predicate keyGenAndImportFunction(Function f){ - exists(string name | f.hasGlobalName(name) and keyGenAndImportFunctionName(name)) -} - //TODO: Verify NCrypt calls (parameters) & find all other APIs that should be included (i.e. decrypt, etc.) @@ -46,7 +40,7 @@ predicate stepOpenAlgorithmProvider(DataFlow::Node node1, DataFlow::Node node2) predicate stepImportGenerateKeyPair(DataFlow::Node node1, DataFlow::Node node2) { exists(FunctionCall call | node1.asExpr() = call.getArgument(0) and - keyGenAndImportFunction(call.getTarget()) and + exists(string name | name in ["BCryptImportKeyPair", "BCryptGenerateKeyPair"] and call.getTarget().hasGlobalName(name)) and node2.asDefiningArgument() = call.getArgument(1) ) } From b242b4bba6420ebd80d6dedc191a18d42131ae22 Mon Sep 17 00:00:00 2001 From: "REDMOND\\brodes" Date: Tue, 8 Nov 2022 12:49:57 -0500 Subject: [PATCH 170/631] More re-org --- .../WinCng/WindowsCng.qll | 30 +++++++++++- .../WinCng/WindowsCngPQCVulnerableUsage.ql | 19 +------- .../WinCng/WindowsCngPQCVulnerableUsage.qll | 48 ++++++++----------- 3 files changed, 49 insertions(+), 48 deletions(-) diff --git a/cpp/ql/src/experimental/campaigns/nccoe-pqc-migration/QuantumVulnerableDiscovery/WinCng/WindowsCng.qll b/cpp/ql/src/experimental/campaigns/nccoe-pqc-migration/QuantumVulnerableDiscovery/WinCng/WindowsCng.qll index 92f54b7ed0e..44900790b63 100644 --- a/cpp/ql/src/experimental/campaigns/nccoe-pqc-migration/QuantumVulnerableDiscovery/WinCng/WindowsCng.qll +++ b/cpp/ql/src/experimental/campaigns/nccoe-pqc-migration/QuantumVulnerableDiscovery/WinCng/WindowsCng.qll @@ -2,6 +2,32 @@ import cpp import DataFlow::PathGraph import semmle.code.cpp.dataflow.TaintTracking -abstract class BCryptOpenAlgorithmProviderSink extends DataFlow::Node {} -abstract class BCryptOpenAlgorithmProviderSource extends DataFlow::Node {} +abstract class BCryptOpenAlgorithmProviderSink extends DataFlow::Node { } +abstract class BCryptOpenAlgorithmProviderSource extends DataFlow::Node { } + +predicate isCallArgument(string funcGlobalName, Expr arg, int index) { + exists(Call c | c.getArgument(index) = arg and c.getTarget().hasGlobalName(funcGlobalName)) +} + +//TODO: Verify NCrypt calls (parameters) & find all other APIs that should be included (i.e. decrypt, etc.) +// ------------------ SINKS ---------------------- +class BCryptSignHashArgumentSink extends BCryptOpenAlgorithmProviderSink { + BCryptSignHashArgumentSink() { isCallArgument("BCryptSignHash", this.asExpr(), 0) } +} + +class BCryptEncryptArgumentSink extends BCryptOpenAlgorithmProviderSink { + BCryptEncryptArgumentSink() { isCallArgument("BCryptEncrypt", this.asExpr(), 0) } +} + +// ----------------- SOURCES ----------------------- +class BCryptOpenAlgorithmProviderPqcVulnerableAlgorithmsSource extends BCryptOpenAlgorithmProviderSource { + BCryptOpenAlgorithmProviderPqcVulnerableAlgorithmsSource() { + this.asExpr() instanceof StringLiteral and + ( + this.asExpr().getValue() in ["DH", "DSA", "ECDSA", "ECDH"] or + this.asExpr().getValue().matches("ECDH%") or + this.asExpr().getValue().matches("RSA%") + ) + } +} diff --git a/cpp/ql/src/experimental/campaigns/nccoe-pqc-migration/QuantumVulnerableDiscovery/WinCng/WindowsCngPQCVulnerableUsage.ql b/cpp/ql/src/experimental/campaigns/nccoe-pqc-migration/QuantumVulnerableDiscovery/WinCng/WindowsCngPQCVulnerableUsage.ql index b77ad05ced0..ca1fd22e5f1 100644 --- a/cpp/ql/src/experimental/campaigns/nccoe-pqc-migration/QuantumVulnerableDiscovery/WinCng/WindowsCngPQCVulnerableUsage.ql +++ b/cpp/ql/src/experimental/campaigns/nccoe-pqc-migration/QuantumVulnerableDiscovery/WinCng/WindowsCngPQCVulnerableUsage.ql @@ -16,25 +16,8 @@ import DataFlow::PathGraph import WindowsCng import WindowsCngPQCVulnerableUsage -// CNG-specific DataFlow configuration -class BCryptConfiguration extends DataFlow::Configuration { - BCryptConfiguration() { - this = "BCryptConfiguration" - } - override predicate isSource(DataFlow::Node source) { - source instanceof BCryptOpenAlgorithmProviderSource - } - - override predicate isSink(DataFlow::Node sink) { - sink instanceof BCryptOpenAlgorithmProviderSink - } - - override predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) { - isWindowsCngAdditionalTaintStep( node1, node2) - } -} from BCryptConfiguration config, DataFlow::PathNode source, DataFlow::PathNode sink where config.hasFlowPath(source, sink) select sink.getNode(), source, sink, "PQC vulnerable algorithm $@ in use has been detected.", - source.getNode().asExpr(), source.getNode().asExpr().toString() \ No newline at end of file + source.getNode().asExpr(), source.getNode().asExpr().toString() diff --git a/cpp/ql/src/experimental/campaigns/nccoe-pqc-migration/QuantumVulnerableDiscovery/WinCng/WindowsCngPQCVulnerableUsage.qll b/cpp/ql/src/experimental/campaigns/nccoe-pqc-migration/QuantumVulnerableDiscovery/WinCng/WindowsCngPQCVulnerableUsage.qll index 412941a48e5..0accc61f8db 100644 --- a/cpp/ql/src/experimental/campaigns/nccoe-pqc-migration/QuantumVulnerableDiscovery/WinCng/WindowsCngPQCVulnerableUsage.qll +++ b/cpp/ql/src/experimental/campaigns/nccoe-pqc-migration/QuantumVulnerableDiscovery/WinCng/WindowsCngPQCVulnerableUsage.qll @@ -1,33 +1,6 @@ import cpp import WindowsCng -//TODO: Verify NCrypt calls (parameters) & find all other APIs that should be included (i.e. decrypt, etc.) - - -predicate isCallArgument(string funcGlobalName, Expr arg, int index){ - exists(Call c | c.getArgument(index) = arg and c.getTarget().hasGlobalName(funcGlobalName)) -} - -class BCryptSignHashArgumentSink extends BCryptOpenAlgorithmProviderSink { - BCryptSignHashArgumentSink() { isCallArgument("BCryptSignHash", this.asExpr(), 0) } -} - -class BCryptEncryptArgumentSink extends BCryptOpenAlgorithmProviderSink { - BCryptEncryptArgumentSink() { isCallArgument("BCryptEncrypt", this.asExpr(), 0) } - } - - -class BCryptOpenAlgorithmProviderPqcVulnerableAlgorithmsSource extends BCryptOpenAlgorithmProviderSource { - BCryptOpenAlgorithmProviderPqcVulnerableAlgorithmsSource() { - this.asExpr() instanceof StringLiteral and - ( - this.asExpr().getValue() in ["DH", "DSA", "ECDSA", "ECDH"] or - this.asExpr().getValue().matches("ECDH%") or - this.asExpr().getValue().matches("RSA%") - ) - } -} - predicate stepOpenAlgorithmProvider(DataFlow::Node node1, DataFlow::Node node2) { exists(FunctionCall call | // BCryptOpenAlgorithmProvider 2nd argument specifies the algorithm to be used @@ -40,7 +13,10 @@ predicate stepOpenAlgorithmProvider(DataFlow::Node node1, DataFlow::Node node2) predicate stepImportGenerateKeyPair(DataFlow::Node node1, DataFlow::Node node2) { exists(FunctionCall call | node1.asExpr() = call.getArgument(0) and - exists(string name | name in ["BCryptImportKeyPair", "BCryptGenerateKeyPair"] and call.getTarget().hasGlobalName(name)) and + exists(string name | + name in ["BCryptImportKeyPair", "BCryptGenerateKeyPair"] and + call.getTarget().hasGlobalName(name) + ) and node2.asDefiningArgument() = call.getArgument(1) ) } @@ -50,3 +26,19 @@ predicate isWindowsCngAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node n or stepImportGenerateKeyPair(node1, node2) } + + +// CNG-specific DataFlow configuration +class BCryptConfiguration extends DataFlow::Configuration { + BCryptConfiguration() { this = "BCryptConfiguration" } + + override predicate isSource(DataFlow::Node source) { + source instanceof BCryptOpenAlgorithmProviderSource + } + + override predicate isSink(DataFlow::Node sink) { sink instanceof BCryptOpenAlgorithmProviderSink } + + override predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) { + isWindowsCngAdditionalTaintStep(node1, node2) + } +} From 46bfa35c3516fe92d52a5fb3ca928e16446a0b0f Mon Sep 17 00:00:00 2001 From: "REDMOND\\brodes" Date: Tue, 8 Nov 2022 12:52:41 -0500 Subject: [PATCH 171/631] More reformatting --- .../WinCng/WindowsCng.qll | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/cpp/ql/src/experimental/campaigns/nccoe-pqc-migration/QuantumVulnerableDiscovery/WinCng/WindowsCng.qll b/cpp/ql/src/experimental/campaigns/nccoe-pqc-migration/QuantumVulnerableDiscovery/WinCng/WindowsCng.qll index 44900790b63..af82ea651e9 100644 --- a/cpp/ql/src/experimental/campaigns/nccoe-pqc-migration/QuantumVulnerableDiscovery/WinCng/WindowsCng.qll +++ b/cpp/ql/src/experimental/campaigns/nccoe-pqc-migration/QuantumVulnerableDiscovery/WinCng/WindowsCng.qll @@ -21,13 +21,14 @@ class BCryptEncryptArgumentSink extends BCryptOpenAlgorithmProviderSink { } // ----------------- SOURCES ----------------------- -class BCryptOpenAlgorithmProviderPqcVulnerableAlgorithmsSource extends BCryptOpenAlgorithmProviderSource { - BCryptOpenAlgorithmProviderPqcVulnerableAlgorithmsSource() { - this.asExpr() instanceof StringLiteral and - ( - this.asExpr().getValue() in ["DH", "DSA", "ECDSA", "ECDH"] or - this.asExpr().getValue().matches("ECDH%") or - this.asExpr().getValue().matches("RSA%") - ) - } +predicate providerString(StringLiteral lit) { + exists(string s | s = lit.getValue() | + s in ["DH", "DSA", "ECDSA", "ECDH"] or + s.matches("ECDH%") or + s.matches("RSA%") + ) +} + +class BCryptOpenAlgorithmProviderPqcVulnerableAlgorithmsSource extends BCryptOpenAlgorithmProviderSource { + BCryptOpenAlgorithmProviderPqcVulnerableAlgorithmsSource() { providerString(this.asExpr()) } } From 5f2a42bb483c57e6cdcb48515c136ede6e7ebef8 Mon Sep 17 00:00:00 2001 From: "REDMOND\\brodes" Date: Tue, 8 Nov 2022 12:53:34 -0500 Subject: [PATCH 172/631] Changing predicate names. --- .../QuantumVulnerableDiscovery/WinCng/WindowsCng.qll | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cpp/ql/src/experimental/campaigns/nccoe-pqc-migration/QuantumVulnerableDiscovery/WinCng/WindowsCng.qll b/cpp/ql/src/experimental/campaigns/nccoe-pqc-migration/QuantumVulnerableDiscovery/WinCng/WindowsCng.qll index af82ea651e9..5c775da7b97 100644 --- a/cpp/ql/src/experimental/campaigns/nccoe-pqc-migration/QuantumVulnerableDiscovery/WinCng/WindowsCng.qll +++ b/cpp/ql/src/experimental/campaigns/nccoe-pqc-migration/QuantumVulnerableDiscovery/WinCng/WindowsCng.qll @@ -21,7 +21,7 @@ class BCryptEncryptArgumentSink extends BCryptOpenAlgorithmProviderSink { } // ----------------- SOURCES ----------------------- -predicate providerString(StringLiteral lit) { +predicate vulnProviderLiteral(StringLiteral lit) { exists(string s | s = lit.getValue() | s in ["DH", "DSA", "ECDSA", "ECDH"] or s.matches("ECDH%") or @@ -30,5 +30,5 @@ predicate providerString(StringLiteral lit) { } class BCryptOpenAlgorithmProviderPqcVulnerableAlgorithmsSource extends BCryptOpenAlgorithmProviderSource { - BCryptOpenAlgorithmProviderPqcVulnerableAlgorithmsSource() { providerString(this.asExpr()) } + BCryptOpenAlgorithmProviderPqcVulnerableAlgorithmsSource() { vulnProviderLiteral(this.asExpr()) } } From b15a5a903074c51896aba8f33061ab08995d60f8 Mon Sep 17 00:00:00 2001 From: "REDMOND\\brodes" Date: Tue, 8 Nov 2022 13:04:51 -0500 Subject: [PATCH 173/631] Comments and reorg. --- .../WinCng/WindowsCng.qll | 40 ++++++++++++++----- .../WinCng/WindowsCngPQCVulnerableUsage.ql | 1 - .../WinCng/WindowsCngPQCVulnerableUsage.qll | 20 +++++++++- 3 files changed, 47 insertions(+), 14 deletions(-) diff --git a/cpp/ql/src/experimental/campaigns/nccoe-pqc-migration/QuantumVulnerableDiscovery/WinCng/WindowsCng.qll b/cpp/ql/src/experimental/campaigns/nccoe-pqc-migration/QuantumVulnerableDiscovery/WinCng/WindowsCng.qll index 5c775da7b97..3869ba7d9fd 100644 --- a/cpp/ql/src/experimental/campaigns/nccoe-pqc-migration/QuantumVulnerableDiscovery/WinCng/WindowsCng.qll +++ b/cpp/ql/src/experimental/campaigns/nccoe-pqc-migration/QuantumVulnerableDiscovery/WinCng/WindowsCng.qll @@ -6,21 +6,19 @@ abstract class BCryptOpenAlgorithmProviderSink extends DataFlow::Node { } abstract class BCryptOpenAlgorithmProviderSource extends DataFlow::Node { } +// ------------------ Helper Predicates ---------------------- +/** + * Holds if there is a call with global name`funcGlobalName` with argument `arg` of that call + * at argument index `index`. + */ predicate isCallArgument(string funcGlobalName, Expr arg, int index) { exists(Call c | c.getArgument(index) = arg and c.getTarget().hasGlobalName(funcGlobalName)) } -//TODO: Verify NCrypt calls (parameters) & find all other APIs that should be included (i.e. decrypt, etc.) -// ------------------ SINKS ---------------------- -class BCryptSignHashArgumentSink extends BCryptOpenAlgorithmProviderSink { - BCryptSignHashArgumentSink() { isCallArgument("BCryptSignHash", this.asExpr(), 0) } -} - -class BCryptEncryptArgumentSink extends BCryptOpenAlgorithmProviderSink { - BCryptEncryptArgumentSink() { isCallArgument("BCryptEncrypt", this.asExpr(), 0) } -} - -// ----------------- SOURCES ----------------------- +/** + * Holdes if StringLiteral `lit` has a string value indicative of a post quantum crypto + * vulnerable algorithm identifier. + */ predicate vulnProviderLiteral(StringLiteral lit) { exists(string s | s = lit.getValue() | s in ["DH", "DSA", "ECDSA", "ECDH"] or @@ -29,6 +27,26 @@ predicate vulnProviderLiteral(StringLiteral lit) { ) } +//TODO: Verify NCrypt calls (parameters) & find all other APIs that should be included (i.e. decrypt, etc.) +// ------------------ Default SINKS ---------------------- +/** + * Argument at index 0 of call to BCryptSignHash + */ +class BCryptSignHashArgumentSink extends BCryptOpenAlgorithmProviderSink { + BCryptSignHashArgumentSink() { isCallArgument("BCryptSignHash", this.asExpr(), 0) } +} + +/** + * Argument at index 0 of call to BCryptEncrypt + */ +class BCryptEncryptArgumentSink extends BCryptOpenAlgorithmProviderSink { + BCryptEncryptArgumentSink() { isCallArgument("BCryptEncrypt", this.asExpr(), 0) } +} + +// ----------------- Default SOURCES ----------------------- +/** + * A string identifier of known PQC vulnerable algorithms. + */ class BCryptOpenAlgorithmProviderPqcVulnerableAlgorithmsSource extends BCryptOpenAlgorithmProviderSource { BCryptOpenAlgorithmProviderPqcVulnerableAlgorithmsSource() { vulnProviderLiteral(this.asExpr()) } } diff --git a/cpp/ql/src/experimental/campaigns/nccoe-pqc-migration/QuantumVulnerableDiscovery/WinCng/WindowsCngPQCVulnerableUsage.ql b/cpp/ql/src/experimental/campaigns/nccoe-pqc-migration/QuantumVulnerableDiscovery/WinCng/WindowsCngPQCVulnerableUsage.ql index ca1fd22e5f1..ea07019eca0 100644 --- a/cpp/ql/src/experimental/campaigns/nccoe-pqc-migration/QuantumVulnerableDiscovery/WinCng/WindowsCngPQCVulnerableUsage.ql +++ b/cpp/ql/src/experimental/campaigns/nccoe-pqc-migration/QuantumVulnerableDiscovery/WinCng/WindowsCngPQCVulnerableUsage.ql @@ -16,7 +16,6 @@ import DataFlow::PathGraph import WindowsCng import WindowsCngPQCVulnerableUsage - from BCryptConfiguration config, DataFlow::PathNode source, DataFlow::PathNode sink where config.hasFlowPath(source, sink) select sink.getNode(), source, sink, "PQC vulnerable algorithm $@ in use has been detected.", diff --git a/cpp/ql/src/experimental/campaigns/nccoe-pqc-migration/QuantumVulnerableDiscovery/WinCng/WindowsCngPQCVulnerableUsage.qll b/cpp/ql/src/experimental/campaigns/nccoe-pqc-migration/QuantumVulnerableDiscovery/WinCng/WindowsCngPQCVulnerableUsage.qll index 0accc61f8db..e017991a05e 100644 --- a/cpp/ql/src/experimental/campaigns/nccoe-pqc-migration/QuantumVulnerableDiscovery/WinCng/WindowsCngPQCVulnerableUsage.qll +++ b/cpp/ql/src/experimental/campaigns/nccoe-pqc-migration/QuantumVulnerableDiscovery/WinCng/WindowsCngPQCVulnerableUsage.qll @@ -1,6 +1,12 @@ import cpp import WindowsCng +/** + * Steps from input variable (argument 1) to output variable (argument 0) + * for CNG API BCryptOpenAlgorithmProvider. + * Argument 1 represents LPCWSTR (a string algorithm ID) + * Argument 0 represents BCRYPT_ALG_HANDLE + */ predicate stepOpenAlgorithmProvider(DataFlow::Node node1, DataFlow::Node node2) { exists(FunctionCall call | // BCryptOpenAlgorithmProvider 2nd argument specifies the algorithm to be used @@ -10,6 +16,12 @@ predicate stepOpenAlgorithmProvider(DataFlow::Node node1, DataFlow::Node node2) ) } +/** + * Steps from input variable (argument 0) to output variable (argument 1) + * for CNG APIs BCryptImportKeyPair and BCryptGenerateKeyPair. + * Argument 0 represents a BCRYPT_ALG_HANDLE. + * Argument 1 represents a BCRYPT_KEY_HANDLE. + */ predicate stepImportGenerateKeyPair(DataFlow::Node node1, DataFlow::Node node2) { exists(FunctionCall call | node1.asExpr() = call.getArgument(0) and @@ -21,14 +33,18 @@ predicate stepImportGenerateKeyPair(DataFlow::Node node1, DataFlow::Node node2) ) } +/** + * Additional DataFlow steps from input variables to output handle variables on CNG apis. + */ predicate isWindowsCngAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) { stepOpenAlgorithmProvider(node1, node2) or stepImportGenerateKeyPair(node1, node2) } - -// CNG-specific DataFlow configuration +/** + * CNG-specific DataFlow configuration + */ class BCryptConfiguration extends DataFlow::Configuration { BCryptConfiguration() { this = "BCryptConfiguration" } From f5ce07d22c7983328894f955b6f28f547d4ad599 Mon Sep 17 00:00:00 2001 From: "REDMOND\\brodes" Date: Tue, 8 Nov 2022 13:40:47 -0500 Subject: [PATCH 174/631] Class re-org --- .../WinCng/WindowsCng.qll | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/cpp/ql/src/experimental/campaigns/nccoe-pqc-migration/QuantumVulnerableDiscovery/WinCng/WindowsCng.qll b/cpp/ql/src/experimental/campaigns/nccoe-pqc-migration/QuantumVulnerableDiscovery/WinCng/WindowsCng.qll index 3869ba7d9fd..ef7314c6426 100644 --- a/cpp/ql/src/experimental/campaigns/nccoe-pqc-migration/QuantumVulnerableDiscovery/WinCng/WindowsCng.qll +++ b/cpp/ql/src/experimental/campaigns/nccoe-pqc-migration/QuantumVulnerableDiscovery/WinCng/WindowsCng.qll @@ -33,14 +33,28 @@ predicate vulnProviderLiteral(StringLiteral lit) { * Argument at index 0 of call to BCryptSignHash */ class BCryptSignHashArgumentSink extends BCryptOpenAlgorithmProviderSink { - BCryptSignHashArgumentSink() { isCallArgument("BCryptSignHash", this.asExpr(), 0) } + int index; + string funcName; + + BCryptSignHashArgumentSink() { + index = 0 and + funcName = "BCryptSignHash" and + isCallArgument(funcName, this.asExpr(), index) + } } /** * Argument at index 0 of call to BCryptEncrypt */ class BCryptEncryptArgumentSink extends BCryptOpenAlgorithmProviderSink { - BCryptEncryptArgumentSink() { isCallArgument("BCryptEncrypt", this.asExpr(), 0) } + int index; + string funcName; + + BCryptEncryptArgumentSink() { + index = 0 and + funcName = "BCryptEncrypt" and + isCallArgument(funcName, this.asExpr(), index) + } } // ----------------- Default SOURCES ----------------------- From 24382453c3aa7bcc2cbb880b31f5b02494df8528 Mon Sep 17 00:00:00 2001 From: "REDMOND\\brodes" Date: Tue, 8 Nov 2022 14:21:10 -0500 Subject: [PATCH 175/631] More comments, and added sink BCryptGenerateKeyPair --- .../WinCng/WindowsCng.qll | 27 +++++++++++++++++-- .../WinCng/WindowsCngPQCVulnerableUsage.qll | 6 +++++ 2 files changed, 31 insertions(+), 2 deletions(-) diff --git a/cpp/ql/src/experimental/campaigns/nccoe-pqc-migration/QuantumVulnerableDiscovery/WinCng/WindowsCng.qll b/cpp/ql/src/experimental/campaigns/nccoe-pqc-migration/QuantumVulnerableDiscovery/WinCng/WindowsCng.qll index ef7314c6426..d3f499eaadf 100644 --- a/cpp/ql/src/experimental/campaigns/nccoe-pqc-migration/QuantumVulnerableDiscovery/WinCng/WindowsCng.qll +++ b/cpp/ql/src/experimental/campaigns/nccoe-pqc-migration/QuantumVulnerableDiscovery/WinCng/WindowsCng.qll @@ -2,8 +2,14 @@ import cpp import DataFlow::PathGraph import semmle.code.cpp.dataflow.TaintTracking +/** + * Base abstract class to be extended to allow indirect extensions of vulnerable sinks. + */ abstract class BCryptOpenAlgorithmProviderSink extends DataFlow::Node { } +/** + * Base abstract class to be extended to allow indirect extensions of vulnerable sources. + */ abstract class BCryptOpenAlgorithmProviderSource extends DataFlow::Node { } // ------------------ Helper Predicates ---------------------- @@ -30,7 +36,8 @@ predicate vulnProviderLiteral(StringLiteral lit) { //TODO: Verify NCrypt calls (parameters) & find all other APIs that should be included (i.e. decrypt, etc.) // ------------------ Default SINKS ---------------------- /** - * Argument at index 0 of call to BCryptSignHash + * Argument at index 0 of call to BCryptSignHash: + * [in] BCRYPT_KEY_HANDLE hKey, */ class BCryptSignHashArgumentSink extends BCryptOpenAlgorithmProviderSink { int index; @@ -44,7 +51,23 @@ class BCryptSignHashArgumentSink extends BCryptOpenAlgorithmProviderSink { } /** - * Argument at index 0 of call to BCryptEncrypt + * Argument at index 0 of call to BCryptGenerateKeyPair: + * [in, out] BCRYPT_ALG_HANDLE hAlgorithm, + */ +class BCryptGenerateKeyPair extends BCryptOpenAlgorithmProviderSink { + int index; + string funcName; + + BCryptGenerateKeyPair() { + index = 0 and + funcName = "BCryptGenerateKeyPair" and + isCallArgument(funcName, this.asExpr(), index) + } +} + +/** + * Argument at index 0 of call to BCryptEncrypt: + * [in, out] BCRYPT_KEY_HANDLE hKey, */ class BCryptEncryptArgumentSink extends BCryptOpenAlgorithmProviderSink { int index; diff --git a/cpp/ql/src/experimental/campaigns/nccoe-pqc-migration/QuantumVulnerableDiscovery/WinCng/WindowsCngPQCVulnerableUsage.qll b/cpp/ql/src/experimental/campaigns/nccoe-pqc-migration/QuantumVulnerableDiscovery/WinCng/WindowsCngPQCVulnerableUsage.qll index e017991a05e..436ef57926a 100644 --- a/cpp/ql/src/experimental/campaigns/nccoe-pqc-migration/QuantumVulnerableDiscovery/WinCng/WindowsCngPQCVulnerableUsage.qll +++ b/cpp/ql/src/experimental/campaigns/nccoe-pqc-migration/QuantumVulnerableDiscovery/WinCng/WindowsCngPQCVulnerableUsage.qll @@ -48,10 +48,16 @@ predicate isWindowsCngAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node n class BCryptConfiguration extends DataFlow::Configuration { BCryptConfiguration() { this = "BCryptConfiguration" } + /** + * Uses indirect extensions of BCryptOpenAlgorithmProviderSource + */ override predicate isSource(DataFlow::Node source) { source instanceof BCryptOpenAlgorithmProviderSource } + /** + * Uses indirect extensions of BCryptOpenAlgorithmProviderSink + */ override predicate isSink(DataFlow::Node sink) { sink instanceof BCryptOpenAlgorithmProviderSink } override predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) { From 60a67dce7380926d373afc4077a7f1634d90e8da Mon Sep 17 00:00:00 2001 From: "REDMOND\\brodes" Date: Tue, 8 Nov 2022 14:57:34 -0500 Subject: [PATCH 176/631] Adding NCryptEncrypt sink --- .../WinCng/WindowsCng.qll | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/cpp/ql/src/experimental/campaigns/nccoe-pqc-migration/QuantumVulnerableDiscovery/WinCng/WindowsCng.qll b/cpp/ql/src/experimental/campaigns/nccoe-pqc-migration/QuantumVulnerableDiscovery/WinCng/WindowsCng.qll index d3f499eaadf..4c426dd38b1 100644 --- a/cpp/ql/src/experimental/campaigns/nccoe-pqc-migration/QuantumVulnerableDiscovery/WinCng/WindowsCng.qll +++ b/cpp/ql/src/experimental/campaigns/nccoe-pqc-migration/QuantumVulnerableDiscovery/WinCng/WindowsCng.qll @@ -80,6 +80,21 @@ class BCryptEncryptArgumentSink extends BCryptOpenAlgorithmProviderSink { } } +/** + * Argument at index 0 of call to NCryptEncrypt: + * [in] NCRYPT_KEY_HANDLE hKey, + */ +class NCryptEncryptArgumentSink extends BCryptOpenAlgorithmProviderSink { + int index; + string funcName; + + NCryptEncryptArgumentSink() { + index = 0 and + funcName = "NCryptEncrypt" and + isCallArgument(funcName, this.asExpr(), index) + } +} + // ----------------- Default SOURCES ----------------------- /** * A string identifier of known PQC vulnerable algorithms. From 59ca3b26cda95e79cd635f05330f149af15300e8 Mon Sep 17 00:00:00 2001 From: "REDMOND\\brodes" Date: Tue, 8 Nov 2022 15:00:21 -0500 Subject: [PATCH 177/631] Adding SslEncryptPacket sink. --- .../WinCng/WindowsCng.qll | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/cpp/ql/src/experimental/campaigns/nccoe-pqc-migration/QuantumVulnerableDiscovery/WinCng/WindowsCng.qll b/cpp/ql/src/experimental/campaigns/nccoe-pqc-migration/QuantumVulnerableDiscovery/WinCng/WindowsCng.qll index 4c426dd38b1..ba400e9ed4c 100644 --- a/cpp/ql/src/experimental/campaigns/nccoe-pqc-migration/QuantumVulnerableDiscovery/WinCng/WindowsCng.qll +++ b/cpp/ql/src/experimental/campaigns/nccoe-pqc-migration/QuantumVulnerableDiscovery/WinCng/WindowsCng.qll @@ -95,6 +95,22 @@ class NCryptEncryptArgumentSink extends BCryptOpenAlgorithmProviderSink { } } + +/** + * Argument at index 1 of call to NCryptEncrypt: + * _Inout_ NCRYPT_KEY_HANDLE hKey, + */ +class SslEncryptPacketArgumentSink extends BCryptOpenAlgorithmProviderSink { + int index; + string funcName; + + SslEncryptPacketArgumentSink() { + index = 1 and + funcName = "SslEncryptPacket" and + isCallArgument(funcName, this.asExpr(), index) + } +} + // ----------------- Default SOURCES ----------------------- /** * A string identifier of known PQC vulnerable algorithms. From 68d668e71907d0cfada55fd73eeb364e9b1f27f3 Mon Sep 17 00:00:00 2001 From: "REDMOND\\brodes" Date: Tue, 8 Nov 2022 15:40:00 -0500 Subject: [PATCH 178/631] Final bug fixes and new sink. --- .../WinCng/WindowsCng.qll | 46 +++++++++---------- .../WinCng/WindowsCngPQCVulnerableUsage.qll | 10 ++-- 2 files changed, 27 insertions(+), 29 deletions(-) diff --git a/cpp/ql/src/experimental/campaigns/nccoe-pqc-migration/QuantumVulnerableDiscovery/WinCng/WindowsCng.qll b/cpp/ql/src/experimental/campaigns/nccoe-pqc-migration/QuantumVulnerableDiscovery/WinCng/WindowsCng.qll index ba400e9ed4c..72a4d7df8a9 100644 --- a/cpp/ql/src/experimental/campaigns/nccoe-pqc-migration/QuantumVulnerableDiscovery/WinCng/WindowsCng.qll +++ b/cpp/ql/src/experimental/campaigns/nccoe-pqc-migration/QuantumVulnerableDiscovery/WinCng/WindowsCng.qll @@ -33,8 +33,22 @@ predicate vulnProviderLiteral(StringLiteral lit) { ) } -//TODO: Verify NCrypt calls (parameters) & find all other APIs that should be included (i.e. decrypt, etc.) // ------------------ Default SINKS ---------------------- +/** + * Argument at index 0 of call to NCryptSignHash: + * [in] NCRYPT_KEY_HANDLE hKey + */ +class NCryptSignHashArgumentSink extends BCryptOpenAlgorithmProviderSink { + int index; + string funcName; + + NCryptSignHashArgumentSink() { + index = 0 and + funcName = "NCryptSignHash " and + isCallArgument(funcName, this.asExpr(), index) + } +} + /** * Argument at index 0 of call to BCryptSignHash: * [in] BCRYPT_KEY_HANDLE hKey, @@ -85,30 +99,14 @@ class BCryptEncryptArgumentSink extends BCryptOpenAlgorithmProviderSink { * [in] NCRYPT_KEY_HANDLE hKey, */ class NCryptEncryptArgumentSink extends BCryptOpenAlgorithmProviderSink { - int index; - string funcName; + int index; + string funcName; - NCryptEncryptArgumentSink() { - index = 0 and - funcName = "NCryptEncrypt" and - isCallArgument(funcName, this.asExpr(), index) - } -} - - -/** - * Argument at index 1 of call to NCryptEncrypt: - * _Inout_ NCRYPT_KEY_HANDLE hKey, - */ -class SslEncryptPacketArgumentSink extends BCryptOpenAlgorithmProviderSink { - int index; - string funcName; - - SslEncryptPacketArgumentSink() { - index = 1 and - funcName = "SslEncryptPacket" and - isCallArgument(funcName, this.asExpr(), index) - } + NCryptEncryptArgumentSink() { + index = 0 and + funcName = "NCryptEncrypt" and + isCallArgument(funcName, this.asExpr(), index) + } } // ----------------- Default SOURCES ----------------------- diff --git a/cpp/ql/src/experimental/campaigns/nccoe-pqc-migration/QuantumVulnerableDiscovery/WinCng/WindowsCngPQCVulnerableUsage.qll b/cpp/ql/src/experimental/campaigns/nccoe-pqc-migration/QuantumVulnerableDiscovery/WinCng/WindowsCngPQCVulnerableUsage.qll index 436ef57926a..d37fdff66c9 100644 --- a/cpp/ql/src/experimental/campaigns/nccoe-pqc-migration/QuantumVulnerableDiscovery/WinCng/WindowsCngPQCVulnerableUsage.qll +++ b/cpp/ql/src/experimental/campaigns/nccoe-pqc-migration/QuantumVulnerableDiscovery/WinCng/WindowsCngPQCVulnerableUsage.qll @@ -25,11 +25,11 @@ predicate stepOpenAlgorithmProvider(DataFlow::Node node1, DataFlow::Node node2) predicate stepImportGenerateKeyPair(DataFlow::Node node1, DataFlow::Node node2) { exists(FunctionCall call | node1.asExpr() = call.getArgument(0) and - exists(string name | - name in ["BCryptImportKeyPair", "BCryptGenerateKeyPair"] and - call.getTarget().hasGlobalName(name) - ) and - node2.asDefiningArgument() = call.getArgument(1) + exists(string name | call.getTarget().hasGlobalName(name) | + name = "BCryptImportKeyPair" and node2.asDefiningArgument() = call.getArgument(3) + or + name = "BCryptGenerateKeyPair" and node2.asDefiningArgument() = call.getArgument(1) + ) ) } From 345b7e4c4e9440662c617a273d039adb89e6372e Mon Sep 17 00:00:00 2001 From: "REDMOND\\brodes" Date: Tue, 8 Nov 2022 15:43:23 -0500 Subject: [PATCH 179/631] Comments. --- .../WinCng/WindowsCngPQCVulnerableUsage.qll | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/cpp/ql/src/experimental/campaigns/nccoe-pqc-migration/QuantumVulnerableDiscovery/WinCng/WindowsCngPQCVulnerableUsage.qll b/cpp/ql/src/experimental/campaigns/nccoe-pqc-migration/QuantumVulnerableDiscovery/WinCng/WindowsCngPQCVulnerableUsage.qll index d37fdff66c9..db4e7215e35 100644 --- a/cpp/ql/src/experimental/campaigns/nccoe-pqc-migration/QuantumVulnerableDiscovery/WinCng/WindowsCngPQCVulnerableUsage.qll +++ b/cpp/ql/src/experimental/campaigns/nccoe-pqc-migration/QuantumVulnerableDiscovery/WinCng/WindowsCngPQCVulnerableUsage.qll @@ -19,8 +19,12 @@ predicate stepOpenAlgorithmProvider(DataFlow::Node node1, DataFlow::Node node2) /** * Steps from input variable (argument 0) to output variable (argument 1) * for CNG APIs BCryptImportKeyPair and BCryptGenerateKeyPair. - * Argument 0 represents a BCRYPT_ALG_HANDLE. - * Argument 1 represents a BCRYPT_KEY_HANDLE. + * BCryptGenerateKeyPair: + * Argument 0 represents a BCRYPT_ALG_HANDLE. + * Argument 1 represents a BCRYPT_KEY_HANDLE. + * BCryptImportKeyPair: + * Argument 0 represents a BCRYPT_ALG_HANDLE. + * Argument 3 represents a BCRYPT_KEY_HANDLE. */ predicate stepImportGenerateKeyPair(DataFlow::Node node1, DataFlow::Node node2) { exists(FunctionCall call | From 820d94098fb9c258e827bcb12822e47b1cac010e Mon Sep 17 00:00:00 2001 From: Rasmus Lerchedahl Petersen Date: Thu, 1 Dec 2022 09:56:51 +0100 Subject: [PATCH 180/631] python: port `py/comparison-using-is` see triage [here](https://github.com/github/codeql-python-team/issues/628#issuecomment-1328933001) - no longer try to interpret the class of operands - simply alert in clear bad cases of uninterned literals - surprisingly(?), all tests still pass --- .../Expressions/IncorrectComparisonUsingIs.ql | 57 ++++++++++++++++--- 1 file changed, 49 insertions(+), 8 deletions(-) diff --git a/python/ql/src/Expressions/IncorrectComparisonUsingIs.ql b/python/ql/src/Expressions/IncorrectComparisonUsingIs.ql index 5352dc9c9fa..aab2ba6bfa1 100644 --- a/python/ql/src/Expressions/IncorrectComparisonUsingIs.ql +++ b/python/ql/src/Expressions/IncorrectComparisonUsingIs.ql @@ -11,16 +11,57 @@ */ import python -import IsComparisons -from Compare comp, Cmpop op, ClassValue c, string alt -where - invalid_portable_is_comparison(comp, op, c) and - not cpython_interned_constant(comp.getASubExpression()) and - ( - op instanceof Is and alt = "==" +/** Holds if the comparison `comp` uses `is` or `is not` (represented as `op`) to compare its `left` and `right` arguments. */ +predicate comparison_using_is(Compare comp, ControlFlowNode left, Cmpop op, ControlFlowNode right) { + exists(CompareNode fcomp | fcomp = comp.getAFlowNode() | + fcomp.operands(left, op, right) and + (op instanceof Is or op instanceof IsNot) + ) +} + +private predicate cpython_interned_value(Expr e) { + exists(string text | text = e.(StrConst).getText() | + text.length() = 0 or - op instanceof IsNot and alt = "!=" + text.length() = 1 and text.regexpMatch("[U+0000-U+00ff]") + ) + or + exists(int i | i = e.(IntegerLiteral).getN().toInt() | -5 <= i and i <= 256) + or + exists(Tuple t | t = e and not exists(t.getAnElt())) +} + +predicate uninterned_literal(Expr e) { + ( + e instanceof StrConst + or + e instanceof IntegerLiteral + or + e instanceof FloatLiteral + or + e instanceof Dict + or + e instanceof List + or + e instanceof Tuple + ) and + not cpython_interned_value(e) +} + +from Compare comp, Cmpop op, string alt +where + exists(ControlFlowNode left, ControlFlowNode right | + comparison_using_is(comp, left, op, right) and + ( + op instanceof Is and alt = "==" + or + op instanceof IsNot and alt = "!=" + ) + | + uninterned_literal(left.getNode()) + or + uninterned_literal(right.getNode()) ) select comp, "Values compared using '" + op.getSymbol() + From b3a1d02d8cb4b8b2a6192abd47b3a7d40cd0b98a Mon Sep 17 00:00:00 2001 From: Asger F Date: Wed, 30 Nov 2022 10:50:36 +0100 Subject: [PATCH 181/631] JS: Add data extension docs --- .../codeql-for-javascript.rst | 3 + ...tomizing-library-models-for-javascript.rst | 392 ++++++++++++++++++ 2 files changed, 395 insertions(+) create mode 100644 docs/codeql/codeql-language-guides/customizing-library-models-for-javascript.rst diff --git a/docs/codeql/codeql-language-guides/codeql-for-javascript.rst b/docs/codeql/codeql-language-guides/codeql-for-javascript.rst index 11a4c5e456c..3219b1f141d 100644 --- a/docs/codeql/codeql-language-guides/codeql-for-javascript.rst +++ b/docs/codeql/codeql-language-guides/codeql-for-javascript.rst @@ -13,6 +13,7 @@ Experiment and learn how to write effective and efficient queries for CodeQL dat codeql-library-for-typescript analyzing-data-flow-in-javascript-and-typescript using-flow-labels-for-precise-data-flow-analysis + customizing-library-models-for-javascript specifying-additional-remote-flow-sources-for-javascript using-type-tracking-for-api-modeling abstract-syntax-tree-classes-for-working-with-javascript-and-typescript-programs @@ -30,6 +31,8 @@ Experiment and learn how to write effective and efficient queries for CodeQL dat - :doc:`Specifying remote flow sources for JavaScript `: You can model potential sources of untrusted user input in your code without making changes to the CodeQL standard library by specifying extra remote flow sources in an external file. +- :doc:`Customizing library models for JavaScript `: You can model potential sources of untrusted user input in your code without making changes to the CodeQL standard library by specifying extra remote flow sources in an external file. + - :doc:`Using type tracking for API modeling `: You can track data through an API by creating a model using the CodeQL type-tracking library for JavaScript. - :doc:`Abstract syntax tree classes for working with JavaScript and TypeScript programs `: CodeQL has a large selection of classes for representing the abstract syntax tree of JavaScript and TypeScript programs. diff --git a/docs/codeql/codeql-language-guides/customizing-library-models-for-javascript.rst b/docs/codeql/codeql-language-guides/customizing-library-models-for-javascript.rst new file mode 100644 index 00000000000..d225e9485f6 --- /dev/null +++ b/docs/codeql/codeql-language-guides/customizing-library-models-for-javascript.rst @@ -0,0 +1,392 @@ +.. \_customizing-library-models-for-javascript: + +Customizing Library Models for JavaScript +========================================= + +.. pull-quote:: + + Beta Notice - Unstable API + + Library customization using data extensions is currently in beta and subject to change. + + Breaking changes to this format may occur while in beta. + +The JavaScript analysis can be customized by adding library models in data extension files. + +A data extension for JavaScript is a YAML file of form: + +.. code-block:: yaml + + extensions: + - addsTo: + pack: codeql/javascript-all + extensible: + data: + - + - + - ... + +The data extension can contribute to the following extension points: + +- **sourceModel**\(type, path, kind) +- **sinkModel**\(type, path, kind) +- **typeModel**\(type1, type2, path) +- **summaryModel**\(type, path, input, output, kind) + +TODO: mention how to actually load the data extension and/or link to page about data extensions. + +We'll explain how to use these using a few examples, and provide a `reference <#reference-1>`_ at the end of this article. + +Example: Taint sink in the 'execa' package +------------------------------------------ + +In this example, we'll show how to add the argument passed to **execa** below as a command-line injection sink: + +.. code-block:: js + + import { shell } from "execa"; + shell(cmd); // <-- add 'cmd' as a taint sink + +This sink is already recognized by the CodeQL JS analysis, but for the sake of example we'll show how it could be added as an extension. + +This can be achieved with the following data extension: + +.. code-block:: yaml + + extensions: + - addsTo: + pack: codeql/javascript-all + extensible: sinkModel + data: + - ["execa", "Member[shell].Argument[0]", "command-line-injection"] + +To break this down: + +- Since we're adding a new sink, we add a tuple to the **sinkModel** extension point. +- The first column, **"execa"**, identifies a set of values from which to begin the search for the sink. + The string **"execa"** means we start at the places where the codebase imports the NPM package **execa**. +- The second column is an access path that is evaluated from left to right, starting at the values that were identified by the first column. + + - **Member[shell]** selects accesses to the **shell** member of the **execa** package. + - **Argument[0]** selects the first argument to calls to that member. + +- **command-line-injection** indicates that this is considered a sink for the command injection query. + +Example: Taint sources from window 'message' events +--------------------------------------------------- + +In this example, we'll show how the **event.data** expression below could be marked as a remote flow source: + +.. code-block:: js + + window.addEventListener("message", function (event) { + let data = event.data; // <-- add 'event.data' as a taint source + }); + +This source is already known by the CodeQL JS analysis, but we'll show how it could be added as an extension. This can be achieved with the following extension: + +.. code-block:: yaml + + extensions: + - addsTo: + pack: codeql/javascript-all + extensible: sourceModel + data: + - [ + "global", + "Member[addEventListener].Argument[1].Parameter[0].Member[data]", + "remote-flow", + ] + +To break this down: + +- Since we're adding a new taint source, we add a tuple to the **sourceModel** extension point. +- The first column, **"global"**, begins the search at references to the global object (also known as **window**). This is a special JavaScript object that contains all global variables and methods. +- **Member[addEventListener]** selects accesses to the **addEventListener** member. +- **Argument[1]** selects the second argument of calls to that member (the argument containing the callback). +- **Parameter[0]** selects the first parameter of the callback (the parameter named **event**). +- **Member[data]** selects accesses to the **data** property of the event object. +- Finally, the kind **remote-flow** indicates that this is considered a source of remote flow. + +Continued example: Restricting the event type +--------------------------------------------- + +The model above treats all events as sources of remote flow, not just **message** events. +For example, it would also pick up this irrelevant source: + +.. code-block:: js + + window.addEventListener("onclick", function (event) { + let data = event.data; // <-- 'event.data' became a spurious taint source + }); + + +We can refine the model by adding the **WithStringArgument** component to restrict the set of calls being considered: + +.. code-block:: yaml + + extensions: + - addsTo: + pack: codeql/javascript-all + extensible: sourceModel + data: + - [ + "global", + "Member[addEventListener].WithStringArgument[0=message].Argument[1].Parameter[0].Member[data]", + "remote-flow", + ] + +The **WithStringArgument[0=message]** component here selects the subset of calls to **addEventListener** where the first argument is a string literal with the value **"message"**. + +Example: Using types to add MySQL injection sinks +------------------------------------------------- + +In this example, we'll show how to add the following SQL injection sink: + +.. code-block:: ts + + import { Connection } from "mysql"; + + function submit(connection: Connection, q: string) { + connection.query(q); // <-- add 'q' as a SQL injection sink + } + +We can recognize this using the following extension: + +.. code-block:: yaml + + extensions: + - addsTo: + pack: codeql/javascript-all + extensible: sinkModel + data: + - ["mysql.Connection", "Member[query].Argument[0]", "sql-injection"] + +To break this down: + +- The first column, **"mysql.Connection"**, begins the search at any expression whose value is known to be an instance of + the **Connection** type from the **mysql** package. This will select the **connection** parameter above because of its type annotation. +- **Member[query]** selects the **query** member from the connection object. +- **Argument[0]** selects the first argument of a call to that member. +- **sql-injection** indicates that this is considered a sink for the SQL injection query. + +This works for the example above because the **connection** parameter has a type annotation that matches what the model is looking for. + +In the next section, we'll show how to generalize the model to handle the absense of type annotations. + +Continued example: Dealing with untyped code +-------------------------------------------- + +Suppose we want the model from above to detect the sink in this snippet: + +.. code-block:: js + + import { getConnection } from "@example/db"; + let connection = getConnection(); + connection.query(q); // <-- add 'q' as a SQL injection sink + +There is no type annotation on **connection**, and there is no indication of what **getConnection()** returns. +Using a **typeModel** tuple we can tell our model that this function returns an instance of **mysql.Connection**: + +.. code-block:: yaml + + extensions: + - addsTo: + pack: codeql/javascript-all + extensible: typeModel + data: + - ["mysql.Connection", "@example/db", "Member[getConnection].ReturnValue"] + +To break this down: + +- Since we're providing type information, we add a tuple to the **typeModel** extension point. +- The first column, **"mysql.Connection"**, names the type that we're adding a new definition for. +- The second column, **"@example/db"**, begins the search at imports of the hypothetical NPM package **@example/db**. +- **Member[getConnection]** selects references to the **getConnection** member from that package. +- **ReturnValue** selects the return value from a call to that member. + +The new model states that the return value of **getConnection()** has type **mysql.Connection**. +Combining this with the sink model we added earlier, the sink in the example is detected by the model. + +The mechanism used here is how library models work for both TypeScript and plain JavaScript. +A good library model contains **typeModel** tuples to ensure it works even in codebases without type annotations. +For example, the **mysql** model that is included with the CodeQL JS analysis includes this type definition (among many others): + +.. code-block:: yaml + + - ["mysql.Connection", "mysql", "Member[createConnection].ReturnValue"] + +Reference +========= + +Extension points +---------------- + +sourceModel(type, path, kind) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Adds a new taint source. Most taint-tracking queries will use the new source. + +- **type**: Name of a type from which to evaluate **path**. +- **path**: Access path leading to the source. +- **kind**: Kind of source to add. Currently only **remote-flow** is used. + +Example: + +.. code-block:: yaml + + extensions: + - addsTo: + pack: codeql/javascript-all + extensible: sourceModel + data: + - ["global", "Member[user].Member[name]", "remote-flow"] + +sinkModel(type, path, kind) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Adds a new taint sink. Sinks are query-specific and will usually affect one or two queries. + +- **type**: Name of a type from which to evaluate **path**. +- **path**: Access path leading to the sink. +- **kind**: Kind of sink to add. See `sink kinds <#sink-kinds>`_ for a list of supported kinds. + +Example: + +.. code-block:: yaml + + extensions: + - addsTo: + pack: codeql/javascript-all + extensible: sinkModel + data: + - ["global", "Member[eval].Argument[0]", "code-injection"] + +summaryModel(type, path, input, output, kind) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Adds flow through a function call. + +- **type**: Name of a type from which to evaluate **path**. +- **path**: Access path leading to a function call. +- **input**: Path relative to the function call that leads to input of the flow. +- **output**: Path relative to the function call leading to the output of the flow. +- **kind**: Kind of summary to add. Can be **taint** for taint-propagating flow, or **value** for value-preserving flow. + +Example: + +.. code-block:: yaml + + extensions: + - addsTo: + pack: codeql/javascript-all + extensible: summaryModel + data: + - [ + "global", + "Member[decodeURIComponent]", + "Argument[0]", + "ReturnValue", + "taint", + ] + +typeModel(type1, type2, path) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Adds a new definition of a type. + +- **type1**: Name of the type to define. +- **type2**: Name of the type from which to evaluate **path**. +- **path**: Access path leading from **type2** to **type1**. + +Example: + +.. code-block:: yaml + + extensions: + - addsTo: + pack: codeql/javascript-all + extensible: typeModel + data: + - [ + "mysql.Connection", + "@example/db", + "Member[getConnection].ReturnValue", + ] + +Types +----- + +A type is a string that identifies a set of values. +In each of the extension points mentioned above, the first column is always the name of a type. +A type can be defined by adding **typeModel** tuples for that type. Additionally, the following built-in types are available: + +- The name of an NPM package matches imports of that package. For example, the type **express** matches the expression **require("express")**. If the package name includes dots, it must be surrounded by single quotes, such as in **'lodash.escape'**. +- The type **global** identifies the global object, also known as **window**. In JavaScript, global variables are properties of the global object, so global variables can be identified using this type. (This type also matches imports of the NPM package named **global**, which is a package that happens to export the global object.) +- A qualified type name of form **.** identifies expressions of type **** from ****. For example, **mysql.Connection** identifies expression of type **Connection** from the **mysql** package. Note that this only works if type annotations are present in the codebase, or if sufficient **typeModel** tuples have been provided for that type. + +Access paths +------------ + +The **path**, **input**, and **output** columns consist of a **.**-separated list of components, which is evaluted from left to right, with each step selecting a new set of values derived from the previous set of values. + +The following components are supported: + +- **Argument[**\ `number`\ **]** selects the argument at the given index. +- **Argument[this]** selects the receiver of a method call. +- **Parameter[**\ `number`\ **]** selects the parameter at the given index. +- **Parameter[this]** selects the **this** parameter of a function. +- **ReturnValue** selects the return value of a function or call. +- **Member[**\ `name`\ **]** selects the property with the given name. +- **AnyMember** selects any property regardless of name. +- **ArrayElement** selects an element of an array. +- **Element** selects an element of an array, iterator, or set object. +- **MapValue** selects a value of a map object. +- **Awaited** selects the value of a promise. +- **Instance** selects instances of a class. + +The following components are called "call site filters". They select a subset of the previously-selected calls, if the call fits certain criteria: + +- **WithArity[**\ `number`\ **]** selects the subset of calls that have the given number of arguments. +- **WithStringArgument[**\ `number`\ **=**\ `value`\ **]** selects the subset of calls where the argument at the given index is a string literal with the given value. + +Components related to decorators: + +- **DecoratedClass** selects a class that has the current value as a decorator. For example, **Member[Component].DecoratedClass** selects any class that is decorated with **@Component**. +- **DecoratedParameter** selects a parameter that is decorated by the current value. +- **DecoratedMember** selects a method, field, or accessor that is decorated by the current value. + +Some additional notes about the syntax of operands: + +- Multiple operands may be given to a single component, as a shorthand for the union of the operands. For example, **Member[foo,bar]** matches the union of **Member[foo]** and **Member[bar]**. +- Numeric operands to **Argument**, **Parameter**, and **WithArity** may be given as an interval. For example, **Argument[0..2]** matches argument 0, 1, or 2. +- **Argument[N-1]** selects the last argument of a call, and **Parameter[N-1]** selects the last parameter of a function, with **N-2** being the second-to-last and so on. + +Kinds +----- + +Source kinds +~~~~~~~~~~~~ + +- **remote-flow**: A generic source of remote flow. Most taint-tracking queries will use such a source. Currently this is the only supported source kind. + +Sink kinds +~~~~~~~~~~ + +Unlike sources, sinks tend to be highly query-specific, rarely affecting more than one or two queries. Not every query supports customizable sinks. If there is no suitable sink kind below, it is best to add a new query instead. + +- **code-injection**: A sink that can be used to inject code, such as in calls to **eval**. +- **command-line-injection**: A sink that can be used to inject shell commands, such as in calls to **child_process.spawn**. +- **path-injection**: A sink that can be used for path injection in a file system access, such as in a calls to **fs.readFile**. +- **sql-injection**: A sink that can be used for SQL injection, such as in a MySQL **query** call. +- **nosql-injection**: A sink that can be used for NoSQL injection, such as in a MongoDB **findOne** call. +- **html-injection**: A sink that can be used for HTML injection, such as in a jQuery **$()** call. +- **request-forgery**: A sink that controls the URL of a request, such as in a **fetch** call. +- **url-redirection**: A sink that can be used to redirect the user to a malicious URL. +- **unsafe-deserialization**: A deserialization sink that can lead to code execution or other unsafe behaviour, such as an unsafe YAML parser. + +Summary kinds +~~~~~~~~~~~~~ + +- **taint**: A summary that propagates taint. This means the output is not necessarily equal to the input, but it was derived from the input in an unrestrictive way. An attacker who controls the input will have significant control over the output as well. +- **value**: A summary that preserves the value of the input or creates a copy of the input such that all of its object properties are preserved. From 9ce0c6024788355b5d93f91bc612de68d122beca Mon Sep 17 00:00:00 2001 From: Asger F Date: Fri, 9 Dec 2022 12:37:39 +0100 Subject: [PATCH 182/631] JS: Rephrase link in ToC --- docs/codeql/codeql-language-guides/codeql-for-javascript.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/codeql/codeql-language-guides/codeql-for-javascript.rst b/docs/codeql/codeql-language-guides/codeql-for-javascript.rst index 3219b1f141d..0a067e87799 100644 --- a/docs/codeql/codeql-language-guides/codeql-for-javascript.rst +++ b/docs/codeql/codeql-language-guides/codeql-for-javascript.rst @@ -31,7 +31,7 @@ Experiment and learn how to write effective and efficient queries for CodeQL dat - :doc:`Specifying remote flow sources for JavaScript `: You can model potential sources of untrusted user input in your code without making changes to the CodeQL standard library by specifying extra remote flow sources in an external file. -- :doc:`Customizing library models for JavaScript `: You can model potential sources of untrusted user input in your code without making changes to the CodeQL standard library by specifying extra remote flow sources in an external file. +- :doc:`Customizing library models for JavaScript `: You can model the libraries used in your code without making changes to the CodeQL standard library by specifying source, sink, and flow summaries in a data extension file. - :doc:`Using type tracking for API modeling `: You can track data through an API by creating a model using the CodeQL type-tracking library for JavaScript. From 111cabbfc1f47a8c6f836d8e077a09cfc5a4af43 Mon Sep 17 00:00:00 2001 From: Asger F Date: Fri, 9 Dec 2022 12:51:46 +0100 Subject: [PATCH 183/631] JS: Add deprecation notice to page about JSON-based format --- .../codeql-language-guides/codeql-for-javascript.rst | 2 -- .../customizing-library-models-for-javascript.rst | 2 +- ...-additional-remote-flow-sources-for-javascript.rst | 11 +++++++---- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/docs/codeql/codeql-language-guides/codeql-for-javascript.rst b/docs/codeql/codeql-language-guides/codeql-for-javascript.rst index 0a067e87799..98f8d27a155 100644 --- a/docs/codeql/codeql-language-guides/codeql-for-javascript.rst +++ b/docs/codeql/codeql-language-guides/codeql-for-javascript.rst @@ -29,8 +29,6 @@ Experiment and learn how to write effective and efficient queries for CodeQL dat - :doc:`Using flow labels for precise data flow analysis `: You can associate flow labels with each value tracked by the flow analysis to determine whether the flow contains potential vulnerabilities. -- :doc:`Specifying remote flow sources for JavaScript `: You can model potential sources of untrusted user input in your code without making changes to the CodeQL standard library by specifying extra remote flow sources in an external file. - - :doc:`Customizing library models for JavaScript `: You can model the libraries used in your code without making changes to the CodeQL standard library by specifying source, sink, and flow summaries in a data extension file. - :doc:`Using type tracking for API modeling `: You can track data through an API by creating a model using the CodeQL type-tracking library for JavaScript. diff --git a/docs/codeql/codeql-language-guides/customizing-library-models-for-javascript.rst b/docs/codeql/codeql-language-guides/customizing-library-models-for-javascript.rst index d225e9485f6..60075c23921 100644 --- a/docs/codeql/codeql-language-guides/customizing-library-models-for-javascript.rst +++ b/docs/codeql/codeql-language-guides/customizing-library-models-for-javascript.rst @@ -1,4 +1,4 @@ -.. \_customizing-library-models-for-javascript: +.. _customizing-library-models-for-javascript: Customizing Library Models for JavaScript ========================================= diff --git a/docs/codeql/codeql-language-guides/specifying-additional-remote-flow-sources-for-javascript.rst b/docs/codeql/codeql-language-guides/specifying-additional-remote-flow-sources-for-javascript.rst index cc3fe5e9469..81cc1ff854c 100644 --- a/docs/codeql/codeql-language-guides/specifying-additional-remote-flow-sources-for-javascript.rst +++ b/docs/codeql/codeql-language-guides/specifying-additional-remote-flow-sources-for-javascript.rst @@ -3,13 +3,16 @@ Specifying additional remote flow sources for JavaScript ======================================================== -You can model potential sources of untrusted user input in your code without making changes to the CodeQL standard library by specifying extra remote flow sources in an external file. - .. pull-quote:: - Note + Deprecation Notice - Specifying remote flow sources in external files is currently in beta and subject to change. + Specifying remote flow sources with the JSON format described here is soon to be deprecated + and will be removed in the future. + + See :ref:`Customizing Library Models for JavaScript `. + +You can model potential sources of untrusted user input in your code without making changes to the CodeQL standard library by specifying extra remote flow sources in an external file. As mentioned in the :ref:`Data flow cheat sheet for JavaScript `, the CodeQL libraries for JavaScript provide a class `RemoteFlowSource `__ to represent sources of untrusted user input, sometimes also referred to as remote flow From bbce52535a84e38ffd8fc1036fbcdf7a758c935e Mon Sep 17 00:00:00 2001 From: Asger F Date: Fri, 9 Dec 2022 12:59:09 +0100 Subject: [PATCH 184/631] JS: Add clarification in another customization doc --- javascript/documentation/library-customization.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/javascript/documentation/library-customization.rst b/javascript/documentation/library-customization.rst index 62d8756e0a1..b06e5b5cab1 100644 --- a/javascript/documentation/library-customization.rst +++ b/javascript/documentation/library-customization.rst @@ -2,7 +2,7 @@ Customizing the JavaScript analysis =================================== This document describes the main extension points offered by the JavaScript analysis for customizing -analysis behavior without editing the queries or libraries themselves. +analysis behavior from CodeQL without editing the queries or libraries themselves. Customization mechanisms ------------------------ From fab798d65428f834a02dcef2c12d8158a5940d33 Mon Sep 17 00:00:00 2001 From: Asger F Date: Thu, 15 Dec 2022 11:45:53 +0100 Subject: [PATCH 185/631] JS: Add some text at the beginning of the reference --- .../customizing-library-models-for-javascript.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/codeql/codeql-language-guides/customizing-library-models-for-javascript.rst b/docs/codeql/codeql-language-guides/customizing-library-models-for-javascript.rst index 60075c23921..99147a63a19 100644 --- a/docs/codeql/codeql-language-guides/customizing-library-models-for-javascript.rst +++ b/docs/codeql/codeql-language-guides/customizing-library-models-for-javascript.rst @@ -219,6 +219,8 @@ For example, the **mysql** model that is included with the CodeQL JS analysis in Reference ========= +The following sections provide reference material for extension points, access paths, types, and kinds. + Extension points ---------------- From 1c3dd93cbeda2d48fb6e6329fb17a38af44ab0b7 Mon Sep 17 00:00:00 2001 From: Asger F Date: Thu, 15 Dec 2022 11:46:27 +0100 Subject: [PATCH 186/631] JS: Rename section and remove broken link It seems Sphinx just isn't capable of rendering these intra-document links. --- .../customizing-library-models-for-javascript.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/codeql/codeql-language-guides/customizing-library-models-for-javascript.rst b/docs/codeql/codeql-language-guides/customizing-library-models-for-javascript.rst index 99147a63a19..0dd19dea8de 100644 --- a/docs/codeql/codeql-language-guides/customizing-library-models-for-javascript.rst +++ b/docs/codeql/codeql-language-guides/customizing-library-models-for-javascript.rst @@ -35,7 +35,7 @@ The data extension can contribute to the following extension points: TODO: mention how to actually load the data extension and/or link to page about data extensions. -We'll explain how to use these using a few examples, and provide a `reference <#reference-1>`_ at the end of this article. +We'll explain how to use these using a few examples, and provide some reference material at the end of this article. Example: Taint sink in the 'execa' package ------------------------------------------ @@ -216,8 +216,8 @@ For example, the **mysql** model that is included with the CodeQL JS analysis in - ["mysql.Connection", "mysql", "Member[createConnection].ReturnValue"] -Reference -========= +Reference material +------------------ The following sections provide reference material for extension points, access paths, types, and kinds. From 5c14eabb0c2cd48353cbe8176b4b8ddc6549bf81 Mon Sep 17 00:00:00 2001 From: Asger F Date: Thu, 15 Dec 2022 12:07:58 +0100 Subject: [PATCH 187/631] JS: Remove broken link to 'sink kinds' section --- .../customizing-library-models-for-javascript.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/codeql/codeql-language-guides/customizing-library-models-for-javascript.rst b/docs/codeql/codeql-language-guides/customizing-library-models-for-javascript.rst index 0dd19dea8de..5f6ac930933 100644 --- a/docs/codeql/codeql-language-guides/customizing-library-models-for-javascript.rst +++ b/docs/codeql/codeql-language-guides/customizing-library-models-for-javascript.rst @@ -251,7 +251,7 @@ Adds a new taint sink. Sinks are query-specific and will usually affect one or t - **type**: Name of a type from which to evaluate **path**. - **path**: Access path leading to the sink. -- **kind**: Kind of sink to add. See `sink kinds <#sink-kinds>`_ for a list of supported kinds. +- **kind**: Kind of sink to add. See the section on sink kinds for a list of supported kinds. Example: From cfdac73948dd29d67cd92bfc0cd66102ad8c158a Mon Sep 17 00:00:00 2001 From: Asger F Date: Thu, 15 Dec 2022 12:07:45 +0100 Subject: [PATCH 188/631] JS: Add decodeURIComponent example --- ...tomizing-library-models-for-javascript.rst | 39 +++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/docs/codeql/codeql-language-guides/customizing-library-models-for-javascript.rst b/docs/codeql/codeql-language-guides/customizing-library-models-for-javascript.rst index 5f6ac930933..071047e4251 100644 --- a/docs/codeql/codeql-language-guides/customizing-library-models-for-javascript.rst +++ b/docs/codeql/codeql-language-guides/customizing-library-models-for-javascript.rst @@ -216,6 +216,45 @@ For example, the **mysql** model that is included with the CodeQL JS analysis in - ["mysql.Connection", "mysql", "Member[createConnection].ReturnValue"] +Example: Adding flow through 'decodeURIComponent' +------------------------------------------------- + +In this example, we'll show how to add flow through calls to `decodeURIComponent`: + +.. code-block:: js + + let y = decodeURIComponent(x); // add taint flow from 'x' to 'y' + +This flow is already recognized by the CodeQL JS analysis, but this is how it could be added with an extension: + +.. code-block:: yaml + + extensions: + - addsTo: + pack: codeql/javascript-all + extensible: summaryModel + data: + - [ + "global", + "Member[decodeURIComponent]", + "Argument[0]", + "ReturnValue", + "taint", + ] + +To break this down: + +- Since we're adding flow *through* a function call, we add a tuple to the **summaryModel** extension point. +- The first column, **"global"**, begins the search for relevant calls at references to the global object. + In JavaScript, global variables are properties of the global object, so this lets us access global variables or functions. +- The second column, **Member[decodeURIComponent]**, is a path leading to the function calls we wish to model. + In this case, we select references to the **decodeURIComponent** member from the global object, that is, + the global variable named **decodeURIComponent**. +- The third column, **Argument[0]**, indicates the input of the flow. In this case, the first argument to the function call. +- The fourth column, **ReturnValue**, indicates the output of the flow. In this case, the return value of the function call. +- The last column, **taint**, indicates the kind of flow to add. The value **taint** means the output is not necessarily equal + to the input, but was was derived from the input in a taint-preserving way. + Reference material ------------------ From 3f4ecd5fdd04ba61400d4cd7de4e9bc48fb1d585 Mon Sep 17 00:00:00 2001 From: Asger F Date: Thu, 15 Dec 2022 12:20:40 +0100 Subject: [PATCH 189/631] JS: Add underscore.forEach example --- ...tomizing-library-models-for-javascript.rst | 44 +++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/docs/codeql/codeql-language-guides/customizing-library-models-for-javascript.rst b/docs/codeql/codeql-language-guides/customizing-library-models-for-javascript.rst index 071047e4251..fe80ad15e34 100644 --- a/docs/codeql/codeql-language-guides/customizing-library-models-for-javascript.rst +++ b/docs/codeql/codeql-language-guides/customizing-library-models-for-javascript.rst @@ -255,6 +255,50 @@ To break this down: - The last column, **taint**, indicates the kind of flow to add. The value **taint** means the output is not necessarily equal to the input, but was was derived from the input in a taint-preserving way. +Example: Adding flow through 'underscore.forEach' +------------------------------------------------- + +In this example, we'll show how to add flow through calls to **forEach** from the **underscore** package: + +.. code-block:: js + + require('underscore').forEach([x, y], (v) => { ... }); // add value flow from 'x' and 'y' to 'v' + +This flow is already recognized by the CodeQL JS analysis, but we'll show how it could be added with an extension. + +.. code-block:: yaml + + extensions: + - addsTo: + pack: codeql/javascript-all + extensible: summaryModel + data: + - [ + "underscore", + "Member[forEach]", + "Argument[0].ArrayElement", + "Argument[1].Parameter[0]", + "value", + ] + +To break this down: + +- Since we're adding flow *through* a function call, we add a tuple to the **summaryModel** extension point. +- The first column, **"underscore"**, begins the search for relevant calls at places where the **underscore** package is imported. +- The second column, **Member[forEach]**, selects references to the **forEach** member from the **underscore** package. +- The third column specifies the input of the flow: + + - **Argument[0]** selects the first argument of **forEach**, which is the array being iterated over. + - **ArrayElement** selects the elements of that array (the expressions **x** and **y**). + +- The fourth column specifies the output of the flow: + + - **Argument[1]** selects the second argument of **forEach** (the argument containing the callback function). + - **Parameter[0]** selects the first parameter of the callback function (the parameter named **v**). + +- The last column, **value**, indicates the kind of flow to add. The value **value** means the input value is unchanged as + it flows to the output. + Reference material ------------------ From fb6a6e550c40285b3d4cb0bf9d3a4931c24e9c67 Mon Sep 17 00:00:00 2001 From: Asger F Date: Thu, 15 Dec 2022 12:42:59 +0100 Subject: [PATCH 190/631] JS: Factor beta notice into a reusable snippet --- .../customizing-library-models-for-javascript.rst | 8 +------- .../reusables/beta-note-customizing-library-models.rst | 7 +++++++ 2 files changed, 8 insertions(+), 7 deletions(-) create mode 100644 docs/codeql/reusables/beta-note-customizing-library-models.rst diff --git a/docs/codeql/codeql-language-guides/customizing-library-models-for-javascript.rst b/docs/codeql/codeql-language-guides/customizing-library-models-for-javascript.rst index fe80ad15e34..beb050fdc49 100644 --- a/docs/codeql/codeql-language-guides/customizing-library-models-for-javascript.rst +++ b/docs/codeql/codeql-language-guides/customizing-library-models-for-javascript.rst @@ -3,13 +3,7 @@ Customizing Library Models for JavaScript ========================================= -.. pull-quote:: - - Beta Notice - Unstable API - - Library customization using data extensions is currently in beta and subject to change. - - Breaking changes to this format may occur while in beta. +.. include:: ../reusables/beta-note-customizing-library-models.rst The JavaScript analysis can be customized by adding library models in data extension files. diff --git a/docs/codeql/reusables/beta-note-customizing-library-models.rst b/docs/codeql/reusables/beta-note-customizing-library-models.rst new file mode 100644 index 00000000000..051078d61d0 --- /dev/null +++ b/docs/codeql/reusables/beta-note-customizing-library-models.rst @@ -0,0 +1,7 @@ +.. pull-quote:: + + Beta Notice - Unstable API + + Library customization using data extensions is currently in beta and subject to change. + + Breaking changes to this format may occur while in beta. From 2052ba6fa695428e5c6e09b72012d8ac8018520f Mon Sep 17 00:00:00 2001 From: Asger F Date: Thu, 15 Dec 2022 12:45:53 +0100 Subject: [PATCH 191/631] JS: sake of example -> this example --- .../customizing-library-models-for-javascript.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/codeql/codeql-language-guides/customizing-library-models-for-javascript.rst b/docs/codeql/codeql-language-guides/customizing-library-models-for-javascript.rst index beb050fdc49..1ce93c522c1 100644 --- a/docs/codeql/codeql-language-guides/customizing-library-models-for-javascript.rst +++ b/docs/codeql/codeql-language-guides/customizing-library-models-for-javascript.rst @@ -41,7 +41,7 @@ In this example, we'll show how to add the argument passed to **execa** below as import { shell } from "execa"; shell(cmd); // <-- add 'cmd' as a taint sink -This sink is already recognized by the CodeQL JS analysis, but for the sake of example we'll show how it could be added as an extension. +This sink is already recognized by the CodeQL JS analysis, but for the sake of this example we'll show how it could be added as an extension. This can be achieved with the following data extension: From c2a10a3206fec354e37a8f536cfa8ef0067f12a4 Mon Sep 17 00:00:00 2001 From: Asger F Date: Thu, 15 Dec 2022 12:46:46 +0100 Subject: [PATCH 192/631] JS: Elaborate on comment about window --- .../customizing-library-models-for-javascript.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/codeql/codeql-language-guides/customizing-library-models-for-javascript.rst b/docs/codeql/codeql-language-guides/customizing-library-models-for-javascript.rst index 1ce93c522c1..f1a73a95e36 100644 --- a/docs/codeql/codeql-language-guides/customizing-library-models-for-javascript.rst +++ b/docs/codeql/codeql-language-guides/customizing-library-models-for-javascript.rst @@ -95,7 +95,7 @@ This source is already known by the CodeQL JS analysis, but we'll show how it co To break this down: - Since we're adding a new taint source, we add a tuple to the **sourceModel** extension point. -- The first column, **"global"**, begins the search at references to the global object (also known as **window**). This is a special JavaScript object that contains all global variables and methods. +- The first column, **"global"**, begins the search at references to the global object (also known as **window** in browser contexts). This is a special JavaScript object that contains all global variables and methods. - **Member[addEventListener]** selects accesses to the **addEventListener** member. - **Argument[1]** selects the second argument of calls to that member (the argument containing the callback). - **Parameter[0]** selects the first parameter of the callback (the parameter named **event**). From 016136a2e32cdf04c5ed82048e3d33a09c6aad16 Mon Sep 17 00:00:00 2001 From: Ahmed Farid Date: Thu, 16 Feb 2023 01:10:36 +0100 Subject: [PATCH 193/631] Update TimingAttack.qll --- .../semmle/python/security/TimingAttack.qll | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/python/ql/src/experimental/semmle/python/security/TimingAttack.qll b/python/ql/src/experimental/semmle/python/security/TimingAttack.qll index ee6be383415..2ae48662d34 100644 --- a/python/ql/src/experimental/semmle/python/security/TimingAttack.qll +++ b/python/ql/src/experimental/semmle/python/security/TimingAttack.qll @@ -289,3 +289,34 @@ class UserInputInComparisonConfig extends TaintTracking2::Configuration { ) } } + +private class CompareSink extends DataFlow::Node { + CompareSink() { + exists(Compare compare | + ( + compare.getOp(0) instanceof Eq or + compare.getOp(0) instanceof NotEq or + compare.getOp(0) instanceof In + ) and + ( + compare.getLeft() = this.asExpr() and + not compare.getComparator(0).(StrConst).getText() = "bearer" + or + compare.getComparator(0) = this.asExpr() and + not compare.getLeft().(StrConst).getText() = "bearer" + ) + ) or + exists(Compare compare | + ( + compare.getOp(0) instanceof IsNot + ) and + ( + compare.getLeft() = this.asExpr() and + not compare.getComparator(0) instanceof None + or + compare.getComparator(0) = this.asExpr() and + not compare.getLeft() instanceof None + ) + ) + } +} From b8f9b2b42426868d79decbacc77f6c8b8cbefc31 Mon Sep 17 00:00:00 2001 From: Ahmed Farid Date: Thu, 16 Feb 2023 01:11:41 +0100 Subject: [PATCH 194/631] Update TimingAttackAgainstHeaderValue.ql --- .../TimingAttackAgainstHeaderValue.ql | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHeaderValue/TimingAttackAgainstHeaderValue.ql b/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHeaderValue/TimingAttackAgainstHeaderValue.ql index 99d870afc83..d8e3aeb5e9f 100644 --- a/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHeaderValue/TimingAttackAgainstHeaderValue.ql +++ b/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHeaderValue/TimingAttackAgainstHeaderValue.ql @@ -24,13 +24,7 @@ class ClientSuppliedSecretConfig extends TaintTracking::Configuration { override predicate isSource(DataFlow::Node source) { source instanceof ClientSuppliedSecret } - override predicate isSink(DataFlow::Node sink) { - exists(Compare cmp, Expr left, Expr right, Cmpop cmpop | - cmpop.getSymbol() = ["==", "in", "is not", "!="] and - cmp.compares(left, cmpop, right) and - sink.asExpr() = [left, right] - ) - } + override predicate isSink(DataFlow::Node sink) { sink instanceof CompareSink } } from ClientSuppliedSecretConfig config, DataFlow::PathNode source, DataFlow::PathNode sink From fbfe23b7c4b7ed0f16518565096468566f1d06d5 Mon Sep 17 00:00:00 2001 From: Ahmed Farid Date: Thu, 16 Feb 2023 01:21:50 +0100 Subject: [PATCH 195/631] Update TimingAttack.qll --- .../ql/src/experimental/semmle/python/security/TimingAttack.qll | 2 ++ 1 file changed, 2 insertions(+) diff --git a/python/ql/src/experimental/semmle/python/security/TimingAttack.qll b/python/ql/src/experimental/semmle/python/security/TimingAttack.qll index 2ae48662d34..a0124ba711b 100644 --- a/python/ql/src/experimental/semmle/python/security/TimingAttack.qll +++ b/python/ql/src/experimental/semmle/python/security/TimingAttack.qll @@ -308,6 +308,8 @@ private class CompareSink extends DataFlow::Node { ) or exists(Compare compare | ( + compare.getOp(0) instanceof Eq or + compare.getOp(0) instanceof NotEq or compare.getOp(0) instanceof IsNot ) and ( From 01b865f75b91e496b6a1e62a0113da69ec3ed7f1 Mon Sep 17 00:00:00 2001 From: Ahmed Farid Date: Thu, 16 Feb 2023 01:36:06 +0100 Subject: [PATCH 196/631] Update TimingAttack.qll --- .../src/experimental/semmle/python/security/TimingAttack.qll | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/python/ql/src/experimental/semmle/python/security/TimingAttack.qll b/python/ql/src/experimental/semmle/python/security/TimingAttack.qll index a0124ba711b..855973e1b58 100644 --- a/python/ql/src/experimental/semmle/python/security/TimingAttack.qll +++ b/python/ql/src/experimental/semmle/python/security/TimingAttack.qll @@ -307,9 +307,7 @@ private class CompareSink extends DataFlow::Node { ) ) or exists(Compare compare | - ( - compare.getOp(0) instanceof Eq or - compare.getOp(0) instanceof NotEq or + ( compare.getOp(0) instanceof IsNot ) and ( From 005839b46231b5101741c33354afe4b22d626637 Mon Sep 17 00:00:00 2001 From: Ahmed Farid Date: Thu, 16 Feb 2023 12:49:40 +0100 Subject: [PATCH 197/631] Update TimingAttack.qll --- .../experimental/semmle/python/security/TimingAttack.qll | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/python/ql/src/experimental/semmle/python/security/TimingAttack.qll b/python/ql/src/experimental/semmle/python/security/TimingAttack.qll index 855973e1b58..b8957a89506 100644 --- a/python/ql/src/experimental/semmle/python/security/TimingAttack.qll +++ b/python/ql/src/experimental/semmle/python/security/TimingAttack.qll @@ -146,10 +146,12 @@ private predicate existsFailFastCheck(Expr firstInput, Expr secondInput) { ) and ( compare.getLeft() = firstInput and - compare.getComparator(0) = secondInput + compare.getComparator(0) = secondInput and + not compare.getAComparator() instanceof None or compare.getLeft() = secondInput and - compare.getComparator(0) = firstInput + compare.getComparator(0) = firstInput and + not compare.getAComparator() instanceof None ) ) } From 4b3efa87dcf24dbc07569f50bce69809c679d0bd Mon Sep 17 00:00:00 2001 From: Ahmed Farid Date: Thu, 16 Feb 2023 14:01:29 +0100 Subject: [PATCH 198/631] Update TimingAttack.qll --- .../semmle/python/security/TimingAttack.qll | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/python/ql/src/experimental/semmle/python/security/TimingAttack.qll b/python/ql/src/experimental/semmle/python/security/TimingAttack.qll index b8957a89506..30c7821c598 100644 --- a/python/ql/src/experimental/semmle/python/security/TimingAttack.qll +++ b/python/ql/src/experimental/semmle/python/security/TimingAttack.qll @@ -292,6 +292,25 @@ class UserInputInComparisonConfig extends TaintTracking2::Configuration { } } +/** + * A configuration tracing flow from a client Secret obtained by an HTTP header to a len() function. + */ +private class ExcludeLenFunc extends TaintTracking2::Configuration { + ExcludeLenFunc() { this = "ExcludeLenFunc" } + + override predicate isSource(DataFlow::Node source) { source instanceof ClientSuppliedSecret } + + override predicate isSink(DataFlow::Node sink) { + exists(Call call | + call.getFunc().(Name).getId() = "len" and + sink.asExpr() = call.getArg(0) + ) + } +} + +/** + * Holds if there is a fast-fail check. + */ private class CompareSink extends DataFlow::Node { CompareSink() { exists(Compare compare | @@ -321,4 +340,13 @@ private class CompareSink extends DataFlow::Node { ) ) } + +/** + * Holds if there is a flow to len(). + */ + predicate FlowToLen() { + exists(ExcludeLenFunc config, DataFlow2::PathNode source, DataFlow2::PathNode sink | + config.hasFlowPath(source, sink) + ) + } } From f70f5c7935268aecb24a0e59a8272e9e1e023fdf Mon Sep 17 00:00:00 2001 From: Ahmed Farid Date: Thu, 16 Feb 2023 14:03:26 +0100 Subject: [PATCH 199/631] Update TimingAttackAgainstHeaderValue.ql --- .../TimingAttackAgainstHeaderValue.ql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHeaderValue/TimingAttackAgainstHeaderValue.ql b/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHeaderValue/TimingAttackAgainstHeaderValue.ql index d8e3aeb5e9f..6a41486f0e1 100644 --- a/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHeaderValue/TimingAttackAgainstHeaderValue.ql +++ b/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHeaderValue/TimingAttackAgainstHeaderValue.ql @@ -28,6 +28,6 @@ class ClientSuppliedSecretConfig extends TaintTracking::Configuration { } from ClientSuppliedSecretConfig config, DataFlow::PathNode source, DataFlow::PathNode sink -where config.hasFlowPath(source, sink) +where config.hasFlowPath(source, sink) and not sink.getNode().(CompareSink).FlowToLen() select sink.getNode(), source, sink, "Timing attack against $@ validation.", source.getNode(), "client-supplied token" From f57861b6a39b73fc8d9cfca578f5a699402f5fd3 Mon Sep 17 00:00:00 2001 From: Ahmed Farid Date: Thu, 16 Feb 2023 14:14:13 +0100 Subject: [PATCH 200/631] Update TimingAttack.qll --- .../ql/src/experimental/semmle/python/security/TimingAttack.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/ql/src/experimental/semmle/python/security/TimingAttack.qll b/python/ql/src/experimental/semmle/python/security/TimingAttack.qll index 30c7821c598..ebd6d4a49b1 100644 --- a/python/ql/src/experimental/semmle/python/security/TimingAttack.qll +++ b/python/ql/src/experimental/semmle/python/security/TimingAttack.qll @@ -344,7 +344,7 @@ private class CompareSink extends DataFlow::Node { /** * Holds if there is a flow to len(). */ - predicate FlowToLen() { + predicate flowtolen() { exists(ExcludeLenFunc config, DataFlow2::PathNode source, DataFlow2::PathNode sink | config.hasFlowPath(source, sink) ) From a421e3a3a366f7f7d01eec6f3053a3f949ed83d3 Mon Sep 17 00:00:00 2001 From: Ahmed Farid Date: Thu, 16 Feb 2023 14:14:43 +0100 Subject: [PATCH 201/631] Update TimingAttackAgainstHeaderValue.ql --- .../TimingAttackAgainstHeaderValue.ql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHeaderValue/TimingAttackAgainstHeaderValue.ql b/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHeaderValue/TimingAttackAgainstHeaderValue.ql index 6a41486f0e1..e88dbdcba36 100644 --- a/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHeaderValue/TimingAttackAgainstHeaderValue.ql +++ b/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHeaderValue/TimingAttackAgainstHeaderValue.ql @@ -28,6 +28,6 @@ class ClientSuppliedSecretConfig extends TaintTracking::Configuration { } from ClientSuppliedSecretConfig config, DataFlow::PathNode source, DataFlow::PathNode sink -where config.hasFlowPath(source, sink) and not sink.getNode().(CompareSink).FlowToLen() +where config.hasFlowPath(source, sink) and not sink.getNode().(CompareSink).flowtolen() select sink.getNode(), source, sink, "Timing attack against $@ validation.", source.getNode(), "client-supplied token" From ccbb58966f0b484b8acd71b23f9b4828a3132824 Mon Sep 17 00:00:00 2001 From: Ahmed Farid Date: Thu, 16 Feb 2023 14:15:04 +0100 Subject: [PATCH 202/631] Update TimingAttack.qll --- .../ql/src/experimental/semmle/python/security/TimingAttack.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/ql/src/experimental/semmle/python/security/TimingAttack.qll b/python/ql/src/experimental/semmle/python/security/TimingAttack.qll index ebd6d4a49b1..46a0072b19b 100644 --- a/python/ql/src/experimental/semmle/python/security/TimingAttack.qll +++ b/python/ql/src/experimental/semmle/python/security/TimingAttack.qll @@ -311,7 +311,7 @@ private class ExcludeLenFunc extends TaintTracking2::Configuration { /** * Holds if there is a fast-fail check. */ -private class CompareSink extends DataFlow::Node { +class CompareSink extends DataFlow::Node { CompareSink() { exists(Compare compare | ( From 27e2307d0c05ad134df166f264d1b993d823930e Mon Sep 17 00:00:00 2001 From: Rasmus Wriedt Larsen Date: Fri, 17 Feb 2023 15:48:18 +0100 Subject: [PATCH 203/631] Python: Add import regression for refined variable --- .../experimental/import-resolution/importflow.ql | 3 +++ .../ql/test/experimental/import-resolution/main.py | 4 ++++ .../test/experimental/import-resolution/refined.py | 12 ++++++++++++ 3 files changed, 19 insertions(+) create mode 100644 python/ql/test/experimental/import-resolution/refined.py diff --git a/python/ql/test/experimental/import-resolution/importflow.ql b/python/ql/test/experimental/import-resolution/importflow.ql index e6e51afa963..94f5e4b0ec8 100644 --- a/python/ql/test/experimental/import-resolution/importflow.ql +++ b/python/ql/test/experimental/import-resolution/importflow.ql @@ -11,6 +11,9 @@ private class SourceString extends DataFlow::Node { SourceString() { this.asExpr().(StrConst).getText() = contents and this.asExpr().getParent() instanceof Assign + or + this.asExpr().(ClassExpr).getInnerScope().getName() = "SOURCE" and + contents = "SOURCE" } string getContents() { result = contents } diff --git a/python/ql/test/experimental/import-resolution/main.py b/python/ql/test/experimental/import-resolution/main.py index 840da95a03c..6ff5506cab4 100644 --- a/python/ql/test/experimental/import-resolution/main.py +++ b/python/ql/test/experimental/import-resolution/main.py @@ -93,6 +93,10 @@ check("subpackage2_attr", subpackage2_attr, "subpackage2_attr", globals()) #$ pr from if_then_else import if_then_else_defined check("if_then_else_defined", if_then_else_defined, "if_defined", globals()) #$ prints=if_defined prints=else_defined_1 prints=else_defined_2 +# check that refined definitions are handled correctly +import refined # $ imports=refined as=refined +check("refined.SOURCE", refined.SOURCE, refined.SOURCE, globals()) #$ MISSING: prints=SOURCE + exit(__file__) print() diff --git a/python/ql/test/experimental/import-resolution/refined.py b/python/ql/test/experimental/import-resolution/refined.py new file mode 100644 index 00000000000..a687ce15655 --- /dev/null +++ b/python/ql/test/experimental/import-resolution/refined.py @@ -0,0 +1,12 @@ +from trace import * +enter(__file__) + +class SOURCE(object): pass + +check("SOURCE", SOURCE, SOURCE, globals()) #$ prints=SOURCE + +SOURCE.foo = 42 + +check("SOURCE", SOURCE, SOURCE, globals()) #$ prints=SOURCE + +exit(__file__) From fb425b73fcac5d88c97a35b0a87479f1613308ff Mon Sep 17 00:00:00 2001 From: Rasmus Wriedt Larsen Date: Tue, 21 Feb 2023 15:47:36 +0100 Subject: [PATCH 204/631] Python: Add import test of `py/insecure-protocol` --- .../InsecureProtocol.expected | 5 ++++ .../import_all_one_file.py | 30 +++++++++++++++++++ .../CWE-327-InsecureProtocol/import_def.py | 11 +++++++ .../CWE-327-InsecureProtocol/import_use.py | 18 +++++++++++ 4 files changed, 64 insertions(+) create mode 100644 python/ql/test/query-tests/Security/CWE-327-InsecureProtocol/import_all_one_file.py create mode 100644 python/ql/test/query-tests/Security/CWE-327-InsecureProtocol/import_def.py create mode 100644 python/ql/test/query-tests/Security/CWE-327-InsecureProtocol/import_use.py diff --git a/python/ql/test/query-tests/Security/CWE-327-InsecureProtocol/InsecureProtocol.expected b/python/ql/test/query-tests/Security/CWE-327-InsecureProtocol/InsecureProtocol.expected index c08e19e5f1c..f097438b213 100644 --- a/python/ql/test/query-tests/Security/CWE-327-InsecureProtocol/InsecureProtocol.expected +++ b/python/ql/test/query-tests/Security/CWE-327-InsecureProtocol/InsecureProtocol.expected @@ -10,6 +10,11 @@ | InsecureProtocol.py:19:1:19:19 | ControlFlowNode for Attribute() | Insecure SSL/TLS protocol version SSLv2 specified by $@. | InsecureProtocol.py:19:1:19:19 | ControlFlowNode for Attribute() | call to SSL.Context | | InsecureProtocol.py:23:1:23:43 | ControlFlowNode for Attribute() | Insecure SSL/TLS protocol version SSLv2 specified by $@. | InsecureProtocol.py:23:1:23:43 | ControlFlowNode for Attribute() | call to ssl.wrap_socket | | InsecureProtocol.py:24:1:24:35 | ControlFlowNode for SSLContext() | Insecure SSL/TLS protocol version SSLv2 specified by $@. | InsecureProtocol.py:24:1:24:35 | ControlFlowNode for SSLContext() | call to SSLContext | +| import_all_one_file.py:25:14:25:45 | ControlFlowNode for copy_completely_insecure_context | Insecure SSL/TLS protocol version TLSv1 allowed by $@. | import_all_one_file.py:9:36:9:67 | ControlFlowNode for Attribute() | call to ssl.SSLContext | +| import_all_one_file.py:25:14:25:45 | ControlFlowNode for copy_completely_insecure_context | Insecure SSL/TLS protocol version TLSv1_1 allowed by $@. | import_all_one_file.py:9:36:9:67 | ControlFlowNode for Attribute() | call to ssl.SSLContext | +| import_all_one_file.py:29:14:29:39 | ControlFlowNode for copy_also_insecure_context | Insecure SSL/TLS protocol version TLSv1_1 allowed by $@. | import_all_one_file.py:12:30:12:61 | ControlFlowNode for Attribute() | call to ssl.SSLContext | +| import_use.py:13:14:13:40 | ControlFlowNode for completely_insecure_context | Insecure SSL/TLS protocol version TLSv1 allowed by $@. | import_def.py:7:31:7:62 | ControlFlowNode for Attribute() | call to ssl.SSLContext | +| import_use.py:13:14:13:40 | ControlFlowNode for completely_insecure_context | Insecure SSL/TLS protocol version TLSv1_1 allowed by $@. | import_def.py:7:31:7:62 | ControlFlowNode for Attribute() | call to ssl.SSLContext | | pyOpenSSL_fluent.py:8:27:8:33 | ControlFlowNode for context | Insecure SSL/TLS protocol version SSLv2 allowed by $@. | pyOpenSSL_fluent.py:6:15:6:44 | ControlFlowNode for Attribute() | call to SSL.Context | | pyOpenSSL_fluent.py:8:27:8:33 | ControlFlowNode for context | Insecure SSL/TLS protocol version SSLv3 allowed by $@. | pyOpenSSL_fluent.py:6:15:6:44 | ControlFlowNode for Attribute() | call to SSL.Context | | pyOpenSSL_fluent.py:8:27:8:33 | ControlFlowNode for context | Insecure SSL/TLS protocol version TLSv1 allowed by $@. | pyOpenSSL_fluent.py:6:15:6:44 | ControlFlowNode for Attribute() | call to SSL.Context | diff --git a/python/ql/test/query-tests/Security/CWE-327-InsecureProtocol/import_all_one_file.py b/python/ql/test/query-tests/Security/CWE-327-InsecureProtocol/import_all_one_file.py new file mode 100644 index 00000000000..aab459ceeea --- /dev/null +++ b/python/ql/test/query-tests/Security/CWE-327-InsecureProtocol/import_all_one_file.py @@ -0,0 +1,30 @@ +# use to compare alerts without import + +import ssl + +copy_secure_context = ssl.SSLContext(ssl.PROTOCOL_TLS) +copy_secure_context.options |= ssl.OP_NO_TLSv1 | ssl.OP_NO_TLSv1_1 + +# this is just to allow us to see how un-altered exports work +copy_completely_insecure_context = ssl.SSLContext(ssl.PROTOCOL_TLS) + +# and an insecure export that is refined +copy_also_insecure_context = ssl.SSLContext(ssl.PROTOCOL_TLS) +copy_also_insecure_context.options |= ssl.OP_NO_TLSv1 + + + +import socket +hostname = 'www.python.org' + +with socket.create_connection((hostname, 443)) as sock: + with copy_secure_context.wrap_socket(sock, server_hostname=hostname) as ssock: + print(ssock.version()) + +with socket.create_connection((hostname, 443)) as sock: + with copy_completely_insecure_context.wrap_socket(sock, server_hostname=hostname) as ssock: + print(ssock.version()) + +with socket.create_connection((hostname, 443)) as sock: + with copy_also_insecure_context.wrap_socket(sock, server_hostname=hostname) as ssock: + print(ssock.version()) diff --git a/python/ql/test/query-tests/Security/CWE-327-InsecureProtocol/import_def.py b/python/ql/test/query-tests/Security/CWE-327-InsecureProtocol/import_def.py new file mode 100644 index 00000000000..d8e37542b94 --- /dev/null +++ b/python/ql/test/query-tests/Security/CWE-327-InsecureProtocol/import_def.py @@ -0,0 +1,11 @@ +import ssl + +secure_context = ssl.SSLContext(ssl.PROTOCOL_TLS) +secure_context.options |= ssl.OP_NO_TLSv1 | ssl.OP_NO_TLSv1_1 + +# this is just to allow us to see how un-altered exports work +completely_insecure_context = ssl.SSLContext(ssl.PROTOCOL_TLS) + +# and an insecure export that is refined +also_insecure_context = ssl.SSLContext(ssl.PROTOCOL_TLS) +also_insecure_context.options |= ssl.OP_NO_TLSv1 diff --git a/python/ql/test/query-tests/Security/CWE-327-InsecureProtocol/import_use.py b/python/ql/test/query-tests/Security/CWE-327-InsecureProtocol/import_use.py new file mode 100644 index 00000000000..3c12fd81355 --- /dev/null +++ b/python/ql/test/query-tests/Security/CWE-327-InsecureProtocol/import_use.py @@ -0,0 +1,18 @@ +# check that query works properly with imports + +import socket +from import_def import secure_context, completely_insecure_context, also_insecure_context + +hostname = 'www.python.org' + +with socket.create_connection((hostname, 443)) as sock: + with secure_context.wrap_socket(sock, server_hostname=hostname) as ssock: + print(ssock.version()) + +with socket.create_connection((hostname, 443)) as sock: + with completely_insecure_context.wrap_socket(sock, server_hostname=hostname) as ssock: + print(ssock.version()) + +with socket.create_connection((hostname, 443)) as sock: + with also_insecure_context.wrap_socket(sock, server_hostname=hostname) as ssock: + print(ssock.version()) From 00eec6986cacd1ae6e4789278c41f35fe5ed4f06 Mon Sep 17 00:00:00 2001 From: Rasmus Wriedt Larsen Date: Fri, 17 Feb 2023 15:52:53 +0100 Subject: [PATCH 205/631] Python: Allow import of refined variable However, as illustrated by the `CWE-327-InsecureProtocol` test, this fix is NOT good enough, since now even the `secure_context` is considered to be insecure (for both versions). Ouch. Will fix this in a later commit, since it was only discoverd late on. --- .../ql/lib/change-notes/2023-02-17-import-refined-variable.md | 4 ++++ .../semmle/python/dataflow/new/internal/ImportResolution.qll | 3 +++ python/ql/test/experimental/import-resolution/main.py | 2 +- .../CWE-327-InsecureProtocol/InsecureProtocol.expected | 4 ++++ 4 files changed, 12 insertions(+), 1 deletion(-) create mode 100644 python/ql/lib/change-notes/2023-02-17-import-refined-variable.md diff --git a/python/ql/lib/change-notes/2023-02-17-import-refined-variable.md b/python/ql/lib/change-notes/2023-02-17-import-refined-variable.md new file mode 100644 index 00000000000..e2dfcd8fd1a --- /dev/null +++ b/python/ql/lib/change-notes/2023-02-17-import-refined-variable.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* Fixed module resolution so we allow imports of definitions that have had an attribute assigned to it, such as `class Foo; Foo.bar = 42`. 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 7af9ca524aa..4895feff946 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/ImportResolution.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/ImportResolution.qll @@ -79,6 +79,9 @@ module ImportResolution { or // to handle definitions guarded by if-then-else essaDef = v.getDefinition().(PhiFunction).getAnInput() + or + // refined variable + essaDef = v.getDefinition().(EssaNodeRefinement).getInput().getDefinition() ) | defn.getNode() = essaDef.(AssignmentDefinition).getValue() diff --git a/python/ql/test/experimental/import-resolution/main.py b/python/ql/test/experimental/import-resolution/main.py index 6ff5506cab4..2a94f180388 100644 --- a/python/ql/test/experimental/import-resolution/main.py +++ b/python/ql/test/experimental/import-resolution/main.py @@ -95,7 +95,7 @@ check("if_then_else_defined", if_then_else_defined, "if_defined", globals()) #$ # check that refined definitions are handled correctly import refined # $ imports=refined as=refined -check("refined.SOURCE", refined.SOURCE, refined.SOURCE, globals()) #$ MISSING: prints=SOURCE +check("refined.SOURCE", refined.SOURCE, refined.SOURCE, globals()) #$ prints=SOURCE exit(__file__) diff --git a/python/ql/test/query-tests/Security/CWE-327-InsecureProtocol/InsecureProtocol.expected b/python/ql/test/query-tests/Security/CWE-327-InsecureProtocol/InsecureProtocol.expected index f097438b213..cc0d620aa1c 100644 --- a/python/ql/test/query-tests/Security/CWE-327-InsecureProtocol/InsecureProtocol.expected +++ b/python/ql/test/query-tests/Security/CWE-327-InsecureProtocol/InsecureProtocol.expected @@ -13,8 +13,12 @@ | import_all_one_file.py:25:14:25:45 | ControlFlowNode for copy_completely_insecure_context | Insecure SSL/TLS protocol version TLSv1 allowed by $@. | import_all_one_file.py:9:36:9:67 | ControlFlowNode for Attribute() | call to ssl.SSLContext | | import_all_one_file.py:25:14:25:45 | ControlFlowNode for copy_completely_insecure_context | Insecure SSL/TLS protocol version TLSv1_1 allowed by $@. | import_all_one_file.py:9:36:9:67 | ControlFlowNode for Attribute() | call to ssl.SSLContext | | import_all_one_file.py:29:14:29:39 | ControlFlowNode for copy_also_insecure_context | Insecure SSL/TLS protocol version TLSv1_1 allowed by $@. | import_all_one_file.py:12:30:12:61 | ControlFlowNode for Attribute() | call to ssl.SSLContext | +| import_use.py:9:14:9:27 | ControlFlowNode for secure_context | Insecure SSL/TLS protocol version TLSv1 allowed by $@. | import_def.py:3:18:3:49 | ControlFlowNode for Attribute() | call to ssl.SSLContext | +| import_use.py:9:14:9:27 | ControlFlowNode for secure_context | Insecure SSL/TLS protocol version TLSv1_1 allowed by $@. | import_def.py:3:18:3:49 | ControlFlowNode for Attribute() | call to ssl.SSLContext | | import_use.py:13:14:13:40 | ControlFlowNode for completely_insecure_context | Insecure SSL/TLS protocol version TLSv1 allowed by $@. | import_def.py:7:31:7:62 | ControlFlowNode for Attribute() | call to ssl.SSLContext | | import_use.py:13:14:13:40 | ControlFlowNode for completely_insecure_context | Insecure SSL/TLS protocol version TLSv1_1 allowed by $@. | import_def.py:7:31:7:62 | ControlFlowNode for Attribute() | call to ssl.SSLContext | +| import_use.py:17:14:17:34 | ControlFlowNode for also_insecure_context | Insecure SSL/TLS protocol version TLSv1 allowed by $@. | import_def.py:10:25:10:56 | ControlFlowNode for Attribute() | call to ssl.SSLContext | +| import_use.py:17:14:17:34 | ControlFlowNode for also_insecure_context | Insecure SSL/TLS protocol version TLSv1_1 allowed by $@. | import_def.py:10:25:10:56 | ControlFlowNode for Attribute() | call to ssl.SSLContext | | pyOpenSSL_fluent.py:8:27:8:33 | ControlFlowNode for context | Insecure SSL/TLS protocol version SSLv2 allowed by $@. | pyOpenSSL_fluent.py:6:15:6:44 | ControlFlowNode for Attribute() | call to SSL.Context | | pyOpenSSL_fluent.py:8:27:8:33 | ControlFlowNode for context | Insecure SSL/TLS protocol version SSLv3 allowed by $@. | pyOpenSSL_fluent.py:6:15:6:44 | ControlFlowNode for Attribute() | call to SSL.Context | | pyOpenSSL_fluent.py:8:27:8:33 | ControlFlowNode for context | Insecure SSL/TLS protocol version TLSv1 allowed by $@. | pyOpenSSL_fluent.py:6:15:6:44 | ControlFlowNode for Attribute() | call to SSL.Context | From e522009666776c507583feb75899bb4714a4209c Mon Sep 17 00:00:00 2001 From: Rasmus Wriedt Larsen Date: Fri, 17 Feb 2023 15:56:16 +0100 Subject: [PATCH 206/631] Python: More complex import examples We need some recursive unwinding to get all of these right --- .../import-resolution/if_then_else_refined.py | 19 +++++++++++++++++++ .../experimental/import-resolution/main.py | 5 ++++- .../experimental/import-resolution/refined.py | 2 ++ 3 files changed, 25 insertions(+), 1 deletion(-) create mode 100644 python/ql/test/experimental/import-resolution/if_then_else_refined.py diff --git a/python/ql/test/experimental/import-resolution/if_then_else_refined.py b/python/ql/test/experimental/import-resolution/if_then_else_refined.py new file mode 100644 index 00000000000..670c7f178e9 --- /dev/null +++ b/python/ql/test/experimental/import-resolution/if_then_else_refined.py @@ -0,0 +1,19 @@ +# combination of refined and if_then_else + +from trace import * +enter(__file__) + +class SOURCE(): pass + +# definition based on "random" choice in this case it will always go the the if-branch, +# but our analysis is not able to figure this out +if eval("True"): + src = SOURCE +else: + src = SOURCE + +src.foo = 42 + +check("src", src, src, globals()) #$ prints=SOURCE + +exit(__file__) diff --git a/python/ql/test/experimental/import-resolution/main.py b/python/ql/test/experimental/import-resolution/main.py index 2a94f180388..9b0b71f9b59 100644 --- a/python/ql/test/experimental/import-resolution/main.py +++ b/python/ql/test/experimental/import-resolution/main.py @@ -95,7 +95,10 @@ check("if_then_else_defined", if_then_else_defined, "if_defined", globals()) #$ # check that refined definitions are handled correctly import refined # $ imports=refined as=refined -check("refined.SOURCE", refined.SOURCE, refined.SOURCE, globals()) #$ prints=SOURCE +check("refined.SOURCE", refined.SOURCE, refined.SOURCE, globals()) #$ MISSING: prints=SOURCE + +import if_then_else_refined # $ imports=if_then_else_refined as=if_then_else_refined +check("if_then_else_refined.src", if_then_else_refined.src, if_then_else_refined.src, globals()) #$ MISSING: prints=SOURCE exit(__file__) diff --git a/python/ql/test/experimental/import-resolution/refined.py b/python/ql/test/experimental/import-resolution/refined.py index a687ce15655..3694168c5df 100644 --- a/python/ql/test/experimental/import-resolution/refined.py +++ b/python/ql/test/experimental/import-resolution/refined.py @@ -6,6 +6,8 @@ class SOURCE(object): pass check("SOURCE", SOURCE, SOURCE, globals()) #$ prints=SOURCE SOURCE.foo = 42 +SOURCE.bar = 43 +SOURCE.baz = 44 check("SOURCE", SOURCE, SOURCE, globals()) #$ prints=SOURCE From 4a66e48dc52fc438c406cbdd565ca4f187b7bcca Mon Sep 17 00:00:00 2001 From: Rasmus Wriedt Larsen Date: Fri, 17 Feb 2023 16:09:50 +0100 Subject: [PATCH 207/631] Python: Allow import resolution with recursive phi/refine steps --- .../new/internal/ImportResolution.qll | 23 +++++++++++-------- .../experimental/import-resolution/main.py | 4 ++-- 2 files changed, 16 insertions(+), 11 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 4895feff946..c440ace2922 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/ImportResolution.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/ImportResolution.qll @@ -64,6 +64,19 @@ private import semmle.python.dataflow.new.internal.DataFlowPrivate * `bar` subpackage. */ module ImportResolution { + /** + * Holds if there is an ESSA step from `defFrom` to `defTo`, which should be allowed + * for import resolution. + */ + private predicate allowedEssaImportStep(EssaDefinition defFrom, EssaDefinition defTo) { + // to handle definitions guarded by if-then-else + defFrom = defTo.(PhiFunction).getAnInput() + or + // refined variable + // example: https://github.com/nvbn/thefuck/blob/ceeaeab94b5df5a4fe9d94d61e4f6b0bbea96378/thefuck/utils.py#L25-L45 + defFrom = defTo.(EssaNodeRefinement).getInput().getDefinition() + } + /** * 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 @@ -74,15 +87,7 @@ module ImportResolution { exists(EssaVariable v, EssaDefinition essaDef | v.getName() = name and v.getAUse() = ImportStar::getStarImported*(m).getANormalExit() and - ( - essaDef = v.getDefinition() - or - // to handle definitions guarded by if-then-else - essaDef = v.getDefinition().(PhiFunction).getAnInput() - or - // refined variable - essaDef = v.getDefinition().(EssaNodeRefinement).getInput().getDefinition() - ) + allowedEssaImportStep*(essaDef, v.getDefinition()) | defn.getNode() = essaDef.(AssignmentDefinition).getValue() or diff --git a/python/ql/test/experimental/import-resolution/main.py b/python/ql/test/experimental/import-resolution/main.py index 9b0b71f9b59..f7cba832232 100644 --- a/python/ql/test/experimental/import-resolution/main.py +++ b/python/ql/test/experimental/import-resolution/main.py @@ -95,10 +95,10 @@ check("if_then_else_defined", if_then_else_defined, "if_defined", globals()) #$ # check that refined definitions are handled correctly import refined # $ imports=refined as=refined -check("refined.SOURCE", refined.SOURCE, refined.SOURCE, globals()) #$ MISSING: prints=SOURCE +check("refined.SOURCE", refined.SOURCE, refined.SOURCE, globals()) #$ prints=SOURCE import if_then_else_refined # $ imports=if_then_else_refined as=if_then_else_refined -check("if_then_else_refined.src", if_then_else_refined.src, if_then_else_refined.src, globals()) #$ MISSING: prints=SOURCE +check("if_then_else_refined.src", if_then_else_refined.src, if_then_else_refined.src, globals()) #$ prints=SOURCE exit(__file__) From 6a5eebe89162cce170b4656b66c3fbe8d019f178 Mon Sep 17 00:00:00 2001 From: Rasmus Wriedt Larsen Date: Wed, 22 Feb 2023 12:26:01 +0100 Subject: [PATCH 208/631] Python: Add test of `module_export` --- .../import-resolution/ModuleExport.expected | 232 ++++++++++++++++++ .../import-resolution/ModuleExport.ql | 9 + 2 files changed, 241 insertions(+) create mode 100644 python/ql/test/experimental/import-resolution/ModuleExport.expected create mode 100644 python/ql/test/experimental/import-resolution/ModuleExport.ql diff --git a/python/ql/test/experimental/import-resolution/ModuleExport.expected b/python/ql/test/experimental/import-resolution/ModuleExport.expected new file mode 100644 index 00000000000..6733a9e378a --- /dev/null +++ b/python/ql/test/experimental/import-resolution/ModuleExport.expected @@ -0,0 +1,232 @@ +| attr_clash.__init__ | __all__ | trace.py:52:11:52:46 | ControlFlowNode for List | +| attr_clash.__init__ | __file__ | attr_clash/__init__.py:2:7:2:14 | ControlFlowNode for __file__ | +| attr_clash.__init__ | __file__ | attr_clash/__init__.py:6:6:6:13 | ControlFlowNode for __file__ | +| attr_clash.__init__ | _indent_level | trace.py:3:17:3:17 | ControlFlowNode for IntegerLiteral | +| attr_clash.__init__ | _print | trace.py:5:10:5:14 | ControlFlowNode for print | +| attr_clash.__init__ | _status | trace.py:21:11:21:11 | ControlFlowNode for IntegerLiteral | +| attr_clash.__init__ | check | trace.py:26:1:26:61 | ControlFlowNode for FunctionExpr | +| attr_clash.__init__ | clashing_attr | attr_clash/__init__.py:4:17:4:31 | ControlFlowNode for Str | +| attr_clash.__init__ | enter | trace.py:11:1:11:21 | ControlFlowNode for FunctionExpr | +| attr_clash.__init__ | exit | trace.py:16:1:16:20 | ControlFlowNode for FunctionExpr | +| attr_clash.__init__ | print | trace.py:7:1:7:27 | ControlFlowNode for FunctionExpr | +| attr_clash.__init__ | print_function | trace.py:1:24:1:37 | ControlFlowNode for ImportMember | +| attr_clash.__init__ | status | trace.py:23:1:23:13 | ControlFlowNode for FunctionExpr | +| attr_clash.clashing_attr | __all__ | trace.py:52:11:52:46 | ControlFlowNode for List | +| attr_clash.clashing_attr | __file__ | attr_clash/clashing_attr.py:2:7:2:14 | ControlFlowNode for __file__ | +| attr_clash.clashing_attr | __file__ | attr_clash/clashing_attr.py:4:6:4:13 | ControlFlowNode for __file__ | +| attr_clash.clashing_attr | _indent_level | trace.py:3:17:3:17 | ControlFlowNode for IntegerLiteral | +| attr_clash.clashing_attr | _print | trace.py:5:10:5:14 | ControlFlowNode for print | +| attr_clash.clashing_attr | _status | trace.py:21:11:21:11 | ControlFlowNode for IntegerLiteral | +| attr_clash.clashing_attr | check | trace.py:26:1:26:61 | ControlFlowNode for FunctionExpr | +| attr_clash.clashing_attr | enter | trace.py:11:1:11:21 | ControlFlowNode for FunctionExpr | +| attr_clash.clashing_attr | exit | trace.py:16:1:16:20 | ControlFlowNode for FunctionExpr | +| attr_clash.clashing_attr | print | trace.py:7:1:7:27 | ControlFlowNode for FunctionExpr | +| attr_clash.clashing_attr | print_function | trace.py:1:24:1:37 | ControlFlowNode for ImportMember | +| attr_clash.clashing_attr | status | trace.py:23:1:23:13 | ControlFlowNode for FunctionExpr | +| attr_clash.non_clashing_submodule | __all__ | trace.py:52:11:52:46 | ControlFlowNode for List | +| attr_clash.non_clashing_submodule | __file__ | attr_clash/non_clashing_submodule.py:2:7:2:14 | ControlFlowNode for __file__ | +| attr_clash.non_clashing_submodule | __file__ | attr_clash/non_clashing_submodule.py:4:6:4:13 | ControlFlowNode for __file__ | +| attr_clash.non_clashing_submodule | _indent_level | trace.py:3:17:3:17 | ControlFlowNode for IntegerLiteral | +| attr_clash.non_clashing_submodule | _print | trace.py:5:10:5:14 | ControlFlowNode for print | +| attr_clash.non_clashing_submodule | _status | trace.py:21:11:21:11 | ControlFlowNode for IntegerLiteral | +| attr_clash.non_clashing_submodule | check | trace.py:26:1:26:61 | ControlFlowNode for FunctionExpr | +| attr_clash.non_clashing_submodule | enter | trace.py:11:1:11:21 | ControlFlowNode for FunctionExpr | +| attr_clash.non_clashing_submodule | exit | trace.py:16:1:16:20 | ControlFlowNode for FunctionExpr | +| attr_clash.non_clashing_submodule | print | trace.py:7:1:7:27 | ControlFlowNode for FunctionExpr | +| attr_clash.non_clashing_submodule | print_function | trace.py:1:24:1:37 | ControlFlowNode for ImportMember | +| attr_clash.non_clashing_submodule | status | trace.py:23:1:23:13 | ControlFlowNode for FunctionExpr | +| bar | __all__ | trace.py:52:11:52:46 | ControlFlowNode for List | +| bar | __file__ | bar.py:2:7:2:14 | ControlFlowNode for __file__ | +| bar | __file__ | bar.py:6:6:6:13 | ControlFlowNode for __file__ | +| bar | _indent_level | trace.py:3:17:3:17 | ControlFlowNode for IntegerLiteral | +| bar | _print | trace.py:5:10:5:14 | ControlFlowNode for print | +| bar | _status | trace.py:21:11:21:11 | ControlFlowNode for IntegerLiteral | +| bar | bar_attr | bar.py:4:12:4:21 | ControlFlowNode for Str | +| bar | check | trace.py:26:1:26:61 | ControlFlowNode for FunctionExpr | +| bar | enter | trace.py:11:1:11:21 | ControlFlowNode for FunctionExpr | +| bar | exit | trace.py:16:1:16:20 | ControlFlowNode for FunctionExpr | +| bar | print | trace.py:7:1:7:27 | ControlFlowNode for FunctionExpr | +| bar | print_function | trace.py:1:24:1:37 | ControlFlowNode for ImportMember | +| bar | status | trace.py:23:1:23:13 | ControlFlowNode for FunctionExpr | +| foo | __all__ | trace.py:52:11:52:46 | ControlFlowNode for List | +| foo | __file__ | foo.py:2:7:2:14 | ControlFlowNode for __file__ | +| foo | __file__ | foo.py:14:6:14:13 | ControlFlowNode for __file__ | +| foo | __private_foo_attr | foo.py:8:22:8:41 | ControlFlowNode for Str | +| foo | _indent_level | trace.py:3:17:3:17 | ControlFlowNode for IntegerLiteral | +| foo | _print | trace.py:5:10:5:14 | ControlFlowNode for print | +| foo | _status | trace.py:21:11:21:11 | ControlFlowNode for IntegerLiteral | +| foo | bar_reexported | foo.py:11:8:11:10 | ControlFlowNode for ImportExpr | +| foo | check | trace.py:26:1:26:61 | ControlFlowNode for FunctionExpr | +| foo | enter | trace.py:11:1:11:21 | ControlFlowNode for FunctionExpr | +| foo | exit | trace.py:16:1:16:20 | ControlFlowNode for FunctionExpr | +| foo | foo_attr | foo.py:5:12:5:21 | ControlFlowNode for Str | +| foo | print | trace.py:7:1:7:27 | ControlFlowNode for FunctionExpr | +| foo | print_function | trace.py:1:24:1:37 | ControlFlowNode for ImportMember | +| foo | status | trace.py:23:1:23:13 | ControlFlowNode for FunctionExpr | +| if_then_else | __all__ | trace.py:52:11:52:46 | ControlFlowNode for List | +| if_then_else | __file__ | if_then_else.py:2:7:2:14 | ControlFlowNode for __file__ | +| if_then_else | __file__ | if_then_else.py:16:6:16:13 | ControlFlowNode for __file__ | +| if_then_else | _indent_level | trace.py:3:17:3:17 | ControlFlowNode for IntegerLiteral | +| if_then_else | _print | trace.py:5:10:5:14 | ControlFlowNode for print | +| if_then_else | _status | trace.py:21:11:21:11 | ControlFlowNode for IntegerLiteral | +| if_then_else | check | trace.py:26:1:26:61 | ControlFlowNode for FunctionExpr | +| if_then_else | enter | trace.py:11:1:11:21 | ControlFlowNode for FunctionExpr | +| if_then_else | exit | trace.py:16:1:16:20 | ControlFlowNode for FunctionExpr | +| if_then_else | if_then_else_defined | if_then_else.py:7:28:7:39 | ControlFlowNode for Str | +| if_then_else | if_then_else_defined | if_then_else.py:12:32:12:47 | ControlFlowNode for Str | +| if_then_else | if_then_else_defined | if_then_else.py:14:32:14:47 | ControlFlowNode for Str | +| if_then_else | print | trace.py:7:1:7:27 | ControlFlowNode for FunctionExpr | +| if_then_else | print_function | trace.py:1:24:1:37 | ControlFlowNode for ImportMember | +| if_then_else | status | trace.py:23:1:23:13 | ControlFlowNode for FunctionExpr | +| if_then_else_refined | SOURCE | if_then_else_refined.py:6:1:6:15 | ControlFlowNode for ClassExpr | +| if_then_else_refined | __all__ | trace.py:52:11:52:46 | ControlFlowNode for List | +| if_then_else_refined | __file__ | if_then_else_refined.py:4:7:4:14 | ControlFlowNode for __file__ | +| if_then_else_refined | __file__ | if_then_else_refined.py:19:6:19:13 | ControlFlowNode for __file__ | +| if_then_else_refined | _indent_level | trace.py:3:17:3:17 | ControlFlowNode for IntegerLiteral | +| if_then_else_refined | _print | trace.py:5:10:5:14 | ControlFlowNode for print | +| if_then_else_refined | _status | trace.py:21:11:21:11 | ControlFlowNode for IntegerLiteral | +| if_then_else_refined | check | trace.py:26:1:26:61 | ControlFlowNode for FunctionExpr | +| if_then_else_refined | enter | trace.py:11:1:11:21 | ControlFlowNode for FunctionExpr | +| if_then_else_refined | exit | trace.py:16:1:16:20 | ControlFlowNode for FunctionExpr | +| if_then_else_refined | print | trace.py:7:1:7:27 | ControlFlowNode for FunctionExpr | +| if_then_else_refined | print_function | trace.py:1:24:1:37 | ControlFlowNode for ImportMember | +| if_then_else_refined | src | if_then_else_refined.py:11:11:11:16 | ControlFlowNode for SOURCE | +| if_then_else_refined | src | if_then_else_refined.py:13:11:13:16 | ControlFlowNode for SOURCE | +| if_then_else_refined | status | trace.py:23:1:23:13 | ControlFlowNode for FunctionExpr | +| main | __all__ | trace.py:52:11:52:46 | ControlFlowNode for List | +| main | __file__ | main.py:24:7:24:14 | ControlFlowNode for __file__ | +| main | __file__ | main.py:103:6:103:13 | ControlFlowNode for __file__ | +| main | __file__ | package/subpackage2/__init__.py:2:7:2:14 | ControlFlowNode for __file__ | +| main | __file__ | package/subpackage2/__init__.py:6:6:6:13 | ControlFlowNode for __file__ | +| main | _indent_level | trace.py:3:17:3:17 | ControlFlowNode for IntegerLiteral | +| main | _print | trace.py:5:10:5:14 | ControlFlowNode for print | +| main | _status | trace.py:21:11:21:11 | ControlFlowNode for IntegerLiteral | +| main | aliased_subpackage | main.py:54:6:54:12 | ControlFlowNode for ImportExpr | +| main | aliased_subpackage | main.py:54:21:54:52 | ControlFlowNode for ImportMember | +| main | aliased_subpackage | main.py:65:8:65:25 | ControlFlowNode for ImportExpr | +| main | bar_attr | main.py:42:6:42:8 | ControlFlowNode for ImportExpr | +| main | bar_attr | main.py:42:17:42:24 | ControlFlowNode for ImportMember | +| main | check | trace.py:26:1:26:61 | ControlFlowNode for FunctionExpr | +| main | clashing_attr | main.py:83:6:83:15 | ControlFlowNode for ImportExpr | +| main | clashing_attr | main.py:83:24:83:36 | ControlFlowNode for ImportMember | +| main | enter | trace.py:11:1:11:21 | ControlFlowNode for FunctionExpr | +| main | exit | trace.py:16:1:16:20 | ControlFlowNode for FunctionExpr | +| main | foo | main.py:27:8:27:10 | ControlFlowNode for ImportExpr | +| main | foo_alias | main.py:34:8:34:10 | ControlFlowNode for ImportExpr | +| main | if_then_else_defined | main.py:93:6:93:17 | ControlFlowNode for ImportExpr | +| main | if_then_else_defined | main.py:93:26:93:45 | ControlFlowNode for ImportMember | +| main | if_then_else_refined | main.py:100:8:100:27 | ControlFlowNode for ImportExpr | +| main | local_import | main.py:57:1:57:19 | ControlFlowNode for FunctionExpr | +| main | namespace_module_attr | main.py:79:10:79:43 | ControlFlowNode for ImportExpr | +| main | namespace_module_attr | main.py:79:52:79:72 | ControlFlowNode for ImportMember | +| main | non_clashing_submodule | main.py:83:6:83:15 | ControlFlowNode for ImportExpr | +| main | non_clashing_submodule | main.py:83:39:83:60 | ControlFlowNode for ImportMember | +| main | package | main.py:69:8:69:25 | ControlFlowNode for ImportExpr | +| main | package | main.py:73:8:73:35 | ControlFlowNode for ImportExpr | +| main | package_attr_alias | main.py:50:6:50:12 | ControlFlowNode for ImportExpr | +| main | package_attr_alias | main.py:50:21:50:54 | ControlFlowNode for ImportMember | +| main | print | trace.py:7:1:7:27 | ControlFlowNode for FunctionExpr | +| main | print_function | main.py:21:6:21:15 | ControlFlowNode for ImportExpr | +| main | print_function | main.py:21:24:21:37 | ControlFlowNode for ImportMember | +| main | print_function | trace.py:1:24:1:37 | ControlFlowNode for ImportMember | +| main | refined | main.py:97:8:97:14 | ControlFlowNode for ImportExpr | +| main | status | trace.py:23:1:23:13 | ControlFlowNode for FunctionExpr | +| main | subpackage2_attr | package/subpackage2/__init__.py:4:20:4:37 | ControlFlowNode for Str | +| main | subpackage_attr | main.py:46:6:46:23 | ControlFlowNode for ImportExpr | +| main | subpackage_attr | main.py:46:32:46:46 | ControlFlowNode for ImportMember | +| main | sys | main.py:22:8:22:10 | ControlFlowNode for ImportExpr | +| namespace_package.namespace_module | __all__ | trace.py:52:11:52:46 | ControlFlowNode for List | +| namespace_package.namespace_module | __file__ | namespace_package/namespace_module.py:2:7:2:14 | ControlFlowNode for __file__ | +| namespace_package.namespace_module | __file__ | namespace_package/namespace_module.py:6:6:6:13 | ControlFlowNode for __file__ | +| namespace_package.namespace_module | _indent_level | trace.py:3:17:3:17 | ControlFlowNode for IntegerLiteral | +| namespace_package.namespace_module | _print | trace.py:5:10:5:14 | ControlFlowNode for print | +| namespace_package.namespace_module | _status | trace.py:21:11:21:11 | ControlFlowNode for IntegerLiteral | +| namespace_package.namespace_module | check | trace.py:26:1:26:61 | ControlFlowNode for FunctionExpr | +| namespace_package.namespace_module | enter | trace.py:11:1:11:21 | ControlFlowNode for FunctionExpr | +| namespace_package.namespace_module | exit | trace.py:16:1:16:20 | ControlFlowNode for FunctionExpr | +| namespace_package.namespace_module | namespace_module_attr | namespace_package/namespace_module.py:4:25:4:47 | ControlFlowNode for Str | +| namespace_package.namespace_module | print | trace.py:7:1:7:27 | ControlFlowNode for FunctionExpr | +| namespace_package.namespace_module | print_function | trace.py:1:24:1:37 | ControlFlowNode for ImportMember | +| namespace_package.namespace_module | status | trace.py:23:1:23:13 | ControlFlowNode for FunctionExpr | +| package.__init__ | __all__ | trace.py:52:11:52:46 | ControlFlowNode for List | +| package.__init__ | __file__ | package/__init__.py:2:7:2:14 | ControlFlowNode for __file__ | +| package.__init__ | __file__ | package/__init__.py:7:6:7:13 | ControlFlowNode for __file__ | +| package.__init__ | _indent_level | trace.py:3:17:3:17 | ControlFlowNode for IntegerLiteral | +| package.__init__ | _print | trace.py:5:10:5:14 | ControlFlowNode for print | +| package.__init__ | _status | trace.py:21:11:21:11 | ControlFlowNode for IntegerLiteral | +| package.__init__ | attr_used_in_subpackage | package/__init__.py:4:27:4:51 | ControlFlowNode for Str | +| package.__init__ | check | trace.py:26:1:26:61 | ControlFlowNode for FunctionExpr | +| package.__init__ | enter | trace.py:11:1:11:21 | ControlFlowNode for FunctionExpr | +| package.__init__ | exit | trace.py:16:1:16:20 | ControlFlowNode for FunctionExpr | +| package.__init__ | package_attr | package/__init__.py:5:16:5:29 | ControlFlowNode for Str | +| package.__init__ | print | trace.py:7:1:7:27 | ControlFlowNode for FunctionExpr | +| package.__init__ | print_function | trace.py:1:24:1:37 | ControlFlowNode for ImportMember | +| package.__init__ | status | trace.py:23:1:23:13 | ControlFlowNode for FunctionExpr | +| package.subpackage2.__init__ | __all__ | trace.py:52:11:52:46 | ControlFlowNode for List | +| package.subpackage2.__init__ | __file__ | package/subpackage2/__init__.py:2:7:2:14 | ControlFlowNode for __file__ | +| package.subpackage2.__init__ | __file__ | package/subpackage2/__init__.py:6:6:6:13 | ControlFlowNode for __file__ | +| package.subpackage2.__init__ | _indent_level | trace.py:3:17:3:17 | ControlFlowNode for IntegerLiteral | +| package.subpackage2.__init__ | _print | trace.py:5:10:5:14 | ControlFlowNode for print | +| package.subpackage2.__init__ | _status | trace.py:21:11:21:11 | ControlFlowNode for IntegerLiteral | +| package.subpackage2.__init__ | check | trace.py:26:1:26:61 | ControlFlowNode for FunctionExpr | +| package.subpackage2.__init__ | enter | trace.py:11:1:11:21 | ControlFlowNode for FunctionExpr | +| package.subpackage2.__init__ | exit | trace.py:16:1:16:20 | ControlFlowNode for FunctionExpr | +| package.subpackage2.__init__ | print | trace.py:7:1:7:27 | ControlFlowNode for FunctionExpr | +| package.subpackage2.__init__ | print_function | trace.py:1:24:1:37 | ControlFlowNode for ImportMember | +| package.subpackage2.__init__ | status | trace.py:23:1:23:13 | ControlFlowNode for FunctionExpr | +| package.subpackage2.__init__ | subpackage2_attr | package/subpackage2/__init__.py:4:20:4:37 | ControlFlowNode for Str | +| package.subpackage.__init__ | __all__ | trace.py:52:11:52:46 | ControlFlowNode for List | +| package.subpackage.__init__ | __file__ | package/subpackage/__init__.py:2:7:2:14 | ControlFlowNode for __file__ | +| package.subpackage.__init__ | __file__ | package/subpackage/__init__.py:14:6:14:13 | ControlFlowNode for __file__ | +| package.subpackage.__init__ | _indent_level | trace.py:3:17:3:17 | ControlFlowNode for IntegerLiteral | +| package.subpackage.__init__ | _print | trace.py:5:10:5:14 | ControlFlowNode for print | +| package.subpackage.__init__ | _status | trace.py:21:11:21:11 | ControlFlowNode for IntegerLiteral | +| package.subpackage.__init__ | check | trace.py:26:1:26:61 | ControlFlowNode for FunctionExpr | +| package.subpackage.__init__ | enter | trace.py:11:1:11:21 | ControlFlowNode for FunctionExpr | +| package.subpackage.__init__ | exit | trace.py:16:1:16:20 | ControlFlowNode for FunctionExpr | +| package.subpackage.__init__ | imported_attr | package/subpackage/__init__.py:7:6:7:7 | ControlFlowNode for ImportExpr | +| package.subpackage.__init__ | imported_attr | package/subpackage/__init__.py:7:16:7:55 | ControlFlowNode for ImportMember | +| package.subpackage.__init__ | irrelevant_attr | package/subpackage/__init__.py:11:6:11:15 | ControlFlowNode for ImportExpr | +| package.subpackage.__init__ | irrelevant_attr | package/subpackage/__init__.py:11:24:11:38 | ControlFlowNode for ImportMember | +| package.subpackage.__init__ | print | trace.py:7:1:7:27 | ControlFlowNode for FunctionExpr | +| package.subpackage.__init__ | print_function | trace.py:1:24:1:37 | ControlFlowNode for ImportMember | +| package.subpackage.__init__ | status | trace.py:23:1:23:13 | ControlFlowNode for FunctionExpr | +| package.subpackage.__init__ | subpackage_attr | package/subpackage/__init__.py:4:19:4:35 | ControlFlowNode for Str | +| package.subpackage.submodule | __all__ | trace.py:52:11:52:46 | ControlFlowNode for List | +| package.subpackage.submodule | __file__ | package/subpackage/submodule.py:2:7:2:14 | ControlFlowNode for __file__ | +| package.subpackage.submodule | __file__ | package/subpackage/submodule.py:7:6:7:13 | ControlFlowNode for __file__ | +| package.subpackage.submodule | _indent_level | trace.py:3:17:3:17 | ControlFlowNode for IntegerLiteral | +| package.subpackage.submodule | _print | trace.py:5:10:5:14 | ControlFlowNode for print | +| package.subpackage.submodule | _status | trace.py:21:11:21:11 | ControlFlowNode for IntegerLiteral | +| package.subpackage.submodule | check | trace.py:26:1:26:61 | ControlFlowNode for FunctionExpr | +| package.subpackage.submodule | enter | trace.py:11:1:11:21 | ControlFlowNode for FunctionExpr | +| package.subpackage.submodule | exit | trace.py:16:1:16:20 | ControlFlowNode for FunctionExpr | +| package.subpackage.submodule | irrelevant_attr | package/subpackage/submodule.py:5:19:5:35 | ControlFlowNode for Str | +| package.subpackage.submodule | print | trace.py:7:1:7:27 | ControlFlowNode for FunctionExpr | +| package.subpackage.submodule | print_function | trace.py:1:24:1:37 | ControlFlowNode for ImportMember | +| package.subpackage.submodule | status | trace.py:23:1:23:13 | ControlFlowNode for FunctionExpr | +| package.subpackage.submodule | submodule_attr | package/subpackage/submodule.py:4:18:4:33 | ControlFlowNode for Str | +| refined | SOURCE | refined.py:4:1:4:21 | ControlFlowNode for ClassExpr | +| refined | __all__ | trace.py:52:11:52:46 | ControlFlowNode for List | +| refined | __file__ | refined.py:2:7:2:14 | ControlFlowNode for __file__ | +| refined | __file__ | refined.py:14:6:14:13 | ControlFlowNode for __file__ | +| refined | _indent_level | trace.py:3:17:3:17 | ControlFlowNode for IntegerLiteral | +| refined | _print | trace.py:5:10:5:14 | ControlFlowNode for print | +| refined | _status | trace.py:21:11:21:11 | ControlFlowNode for IntegerLiteral | +| refined | check | trace.py:26:1:26:61 | ControlFlowNode for FunctionExpr | +| refined | enter | trace.py:11:1:11:21 | ControlFlowNode for FunctionExpr | +| refined | exit | trace.py:16:1:16:20 | ControlFlowNode for FunctionExpr | +| refined | print | trace.py:7:1:7:27 | ControlFlowNode for FunctionExpr | +| refined | print_function | trace.py:1:24:1:37 | ControlFlowNode for ImportMember | +| refined | status | trace.py:23:1:23:13 | ControlFlowNode for FunctionExpr | +| trace | __all__ | trace.py:52:11:52:46 | ControlFlowNode for List | +| trace | _indent_level | trace.py:3:17:3:17 | ControlFlowNode for IntegerLiteral | +| trace | _print | trace.py:5:10:5:14 | ControlFlowNode for print | +| trace | _status | trace.py:21:11:21:11 | ControlFlowNode for IntegerLiteral | +| trace | check | trace.py:26:1:26:61 | ControlFlowNode for FunctionExpr | +| trace | enter | trace.py:11:1:11:21 | ControlFlowNode for FunctionExpr | +| trace | exit | trace.py:16:1:16:20 | ControlFlowNode for FunctionExpr | +| trace | print | trace.py:7:1:7:27 | ControlFlowNode for FunctionExpr | +| trace | print_function | trace.py:1:6:1:15 | ControlFlowNode for ImportExpr | +| trace | print_function | trace.py:1:24:1:37 | ControlFlowNode for ImportMember | +| trace | status | trace.py:23:1:23:13 | ControlFlowNode for FunctionExpr | diff --git a/python/ql/test/experimental/import-resolution/ModuleExport.ql b/python/ql/test/experimental/import-resolution/ModuleExport.ql new file mode 100644 index 00000000000..9d45b0ec8d0 --- /dev/null +++ b/python/ql/test/experimental/import-resolution/ModuleExport.ql @@ -0,0 +1,9 @@ +import python +import semmle.python.dataflow.new.DataFlow +import semmle.python.dataflow.new.internal.ImportResolution + +from Module m, string name, DataFlow::Node defn +where + ImportResolution::module_export(m, name, defn) and + exists(m.getLocation().getFile().getRelativePath()) +select m.getName(), name, defn From 6ba39d5fb348900a09e197e8bb9c951d78e7797b Mon Sep 17 00:00:00 2001 From: Rasmus Wriedt Larsen Date: Wed, 22 Feb 2023 14:50:42 +0100 Subject: [PATCH 209/631] Python: Add import regression for re-exported things --- .../import-resolution/ModuleExport.expected | 35 ++++++++++++++++++- .../experimental/import-resolution/baz.py | 6 ++++ .../experimental/import-resolution/main.py | 4 +++ .../import-resolution/simplistic_reexport.py | 19 ++++++++++ 4 files changed, 63 insertions(+), 1 deletion(-) create mode 100644 python/ql/test/experimental/import-resolution/baz.py create mode 100644 python/ql/test/experimental/import-resolution/simplistic_reexport.py diff --git a/python/ql/test/experimental/import-resolution/ModuleExport.expected b/python/ql/test/experimental/import-resolution/ModuleExport.expected index 6733a9e378a..dc633f7e707 100644 --- a/python/ql/test/experimental/import-resolution/ModuleExport.expected +++ b/python/ql/test/experimental/import-resolution/ModuleExport.expected @@ -48,6 +48,19 @@ | bar | print | trace.py:7:1:7:27 | ControlFlowNode for FunctionExpr | | bar | print_function | trace.py:1:24:1:37 | ControlFlowNode for ImportMember | | bar | status | trace.py:23:1:23:13 | ControlFlowNode for FunctionExpr | +| baz | __all__ | trace.py:52:11:52:46 | ControlFlowNode for List | +| baz | __file__ | baz.py:2:7:2:14 | ControlFlowNode for __file__ | +| baz | __file__ | baz.py:6:6:6:13 | ControlFlowNode for __file__ | +| baz | _indent_level | trace.py:3:17:3:17 | ControlFlowNode for IntegerLiteral | +| baz | _print | trace.py:5:10:5:14 | ControlFlowNode for print | +| baz | _status | trace.py:21:11:21:11 | ControlFlowNode for IntegerLiteral | +| baz | baz_attr | baz.py:4:12:4:21 | ControlFlowNode for Str | +| baz | check | trace.py:26:1:26:61 | ControlFlowNode for FunctionExpr | +| baz | enter | trace.py:11:1:11:21 | ControlFlowNode for FunctionExpr | +| baz | exit | trace.py:16:1:16:20 | ControlFlowNode for FunctionExpr | +| baz | print | trace.py:7:1:7:27 | ControlFlowNode for FunctionExpr | +| baz | print_function | trace.py:1:24:1:37 | ControlFlowNode for ImportMember | +| baz | status | trace.py:23:1:23:13 | ControlFlowNode for FunctionExpr | | foo | __all__ | trace.py:52:11:52:46 | ControlFlowNode for List | | foo | __file__ | foo.py:2:7:2:14 | ControlFlowNode for __file__ | | foo | __file__ | foo.py:14:6:14:13 | ControlFlowNode for __file__ | @@ -95,7 +108,7 @@ | if_then_else_refined | status | trace.py:23:1:23:13 | ControlFlowNode for FunctionExpr | | main | __all__ | trace.py:52:11:52:46 | ControlFlowNode for List | | main | __file__ | main.py:24:7:24:14 | ControlFlowNode for __file__ | -| main | __file__ | main.py:103:6:103:13 | ControlFlowNode for __file__ | +| main | __file__ | main.py:107:6:107:13 | ControlFlowNode for __file__ | | main | __file__ | package/subpackage2/__init__.py:2:7:2:14 | ControlFlowNode for __file__ | | main | __file__ | package/subpackage2/__init__.py:6:6:6:13 | ControlFlowNode for __file__ | | main | _indent_level | trace.py:3:17:3:17 | ControlFlowNode for IntegerLiteral | @@ -130,6 +143,7 @@ | main | print_function | main.py:21:24:21:37 | ControlFlowNode for ImportMember | | main | print_function | trace.py:1:24:1:37 | ControlFlowNode for ImportMember | | main | refined | main.py:97:8:97:14 | ControlFlowNode for ImportExpr | +| main | simplistic_reexport | main.py:103:8:103:26 | ControlFlowNode for ImportExpr | | main | status | trace.py:23:1:23:13 | ControlFlowNode for FunctionExpr | | main | subpackage2_attr | package/subpackage2/__init__.py:4:20:4:37 | ControlFlowNode for Str | | main | subpackage_attr | main.py:46:6:46:23 | ControlFlowNode for ImportExpr | @@ -219,6 +233,25 @@ | refined | print | trace.py:7:1:7:27 | ControlFlowNode for FunctionExpr | | refined | print_function | trace.py:1:24:1:37 | ControlFlowNode for ImportMember | | refined | status | trace.py:23:1:23:13 | ControlFlowNode for FunctionExpr | +| simplistic_reexport | __all__ | trace.py:52:11:52:46 | ControlFlowNode for List | +| simplistic_reexport | __file__ | baz.py:2:7:2:14 | ControlFlowNode for __file__ | +| simplistic_reexport | __file__ | baz.py:6:6:6:13 | ControlFlowNode for __file__ | +| simplistic_reexport | __file__ | simplistic_reexport.py:4:7:4:14 | ControlFlowNode for __file__ | +| simplistic_reexport | __file__ | simplistic_reexport.py:19:6:19:13 | ControlFlowNode for __file__ | +| simplistic_reexport | _indent_level | trace.py:3:17:3:17 | ControlFlowNode for IntegerLiteral | +| simplistic_reexport | _print | trace.py:5:10:5:14 | ControlFlowNode for print | +| simplistic_reexport | _status | trace.py:21:11:21:11 | ControlFlowNode for IntegerLiteral | +| simplistic_reexport | bar_attr | simplistic_reexport.py:6:6:6:8 | ControlFlowNode for ImportExpr | +| simplistic_reexport | bar_attr | simplistic_reexport.py:6:17:6:24 | ControlFlowNode for ImportMember | +| simplistic_reexport | bar_attr | simplistic_reexport.py:9:12:9:24 | ControlFlowNode for Str | +| simplistic_reexport | baz_attr | baz.py:4:12:4:21 | ControlFlowNode for Str | +| simplistic_reexport | baz_attr | simplistic_reexport.py:16:12:16:24 | ControlFlowNode for Str | +| simplistic_reexport | check | trace.py:26:1:26:61 | ControlFlowNode for FunctionExpr | +| simplistic_reexport | enter | trace.py:11:1:11:21 | ControlFlowNode for FunctionExpr | +| simplistic_reexport | exit | trace.py:16:1:16:20 | ControlFlowNode for FunctionExpr | +| simplistic_reexport | print | trace.py:7:1:7:27 | ControlFlowNode for FunctionExpr | +| simplistic_reexport | print_function | trace.py:1:24:1:37 | ControlFlowNode for ImportMember | +| simplistic_reexport | status | trace.py:23:1:23:13 | ControlFlowNode for FunctionExpr | | trace | __all__ | trace.py:52:11:52:46 | ControlFlowNode for List | | trace | _indent_level | trace.py:3:17:3:17 | ControlFlowNode for IntegerLiteral | | trace | _print | trace.py:5:10:5:14 | ControlFlowNode for print | diff --git a/python/ql/test/experimental/import-resolution/baz.py b/python/ql/test/experimental/import-resolution/baz.py new file mode 100644 index 00000000000..66838a315be --- /dev/null +++ b/python/ql/test/experimental/import-resolution/baz.py @@ -0,0 +1,6 @@ +from trace import * +enter(__file__) + +baz_attr = "baz_attr" + +exit(__file__) diff --git a/python/ql/test/experimental/import-resolution/main.py b/python/ql/test/experimental/import-resolution/main.py index f7cba832232..ee777707b92 100644 --- a/python/ql/test/experimental/import-resolution/main.py +++ b/python/ql/test/experimental/import-resolution/main.py @@ -100,6 +100,10 @@ check("refined.SOURCE", refined.SOURCE, refined.SOURCE, globals()) #$ prints=SOU import if_then_else_refined # $ imports=if_then_else_refined as=if_then_else_refined check("if_then_else_refined.src", if_then_else_refined.src, if_then_else_refined.src, globals()) #$ prints=SOURCE +import simplistic_reexport # $ imports=simplistic_reexport as=simplistic_reexport +check("simplistic_reexport.bar_attr", simplistic_reexport.bar_attr, "overwritten", globals()) #$ prints=overwritten SPURIOUS: prints="" prints=bar_attr +check("simplistic_reexport.baz_attr", simplistic_reexport.baz_attr, "overwritten", globals()) #$ prints=overwritten SPURIOUS: prints=baz_attr + exit(__file__) print() diff --git a/python/ql/test/experimental/import-resolution/simplistic_reexport.py b/python/ql/test/experimental/import-resolution/simplistic_reexport.py new file mode 100644 index 00000000000..2847a8a66e0 --- /dev/null +++ b/python/ql/test/experimental/import-resolution/simplistic_reexport.py @@ -0,0 +1,19 @@ +# we might consider anything imported to also be exported, but this is not the case + +from trace import * +enter(__file__) + +from bar import bar_attr +check("bar_attr", bar_attr, "bar_attr", globals()) #$ prints=bar_attr + +bar_attr = "overwritten" +check("bar_attr", bar_attr, "overwritten", globals()) #$ prints=overwritten + + +from baz import * +check("baz_attr", baz_attr, "baz_attr", globals()) #$ MISSING: prints=baz_attr + +baz_attr = "overwritten" +check("baz_attr", baz_attr, "overwritten", globals()) #$ prints=overwritten + +exit(__file__) From 4df7dfbff65e24d20286bf1fff4a343cfde354ef Mon Sep 17 00:00:00 2001 From: Rasmus Wriedt Larsen Date: Wed, 22 Feb 2023 14:52:35 +0100 Subject: [PATCH 210/631] Python: Don't import module as module_attr For `from import ` we would use to treat the `` (ImportExpr) as a definition of the name ``. Since this removes bad import-flow, and nothing broke, I'm guessing this was never intentional. --- .../dataflow/new/internal/ImportResolution.qll | 2 +- .../import-resolution/ModuleExport.expected | 13 ------------- .../ql/test/experimental/import-resolution/main.py | 2 +- 3 files changed, 2 insertions(+), 15 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 c440ace2922..a123f05dbc4 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/ImportResolution.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/ImportResolution.qll @@ -95,7 +95,7 @@ module ImportResolution { ) or exists(Alias a | - defn.asExpr() = [a.getValue(), a.getValue().(ImportMember).getModule()] and + defn.asExpr() = a.getValue() and a.getAsname().(Name).getId() = name and defn.getScope() = m ) diff --git a/python/ql/test/experimental/import-resolution/ModuleExport.expected b/python/ql/test/experimental/import-resolution/ModuleExport.expected index dc633f7e707..11cf82374d6 100644 --- a/python/ql/test/experimental/import-resolution/ModuleExport.expected +++ b/python/ql/test/experimental/import-resolution/ModuleExport.expected @@ -114,39 +114,30 @@ | main | _indent_level | trace.py:3:17:3:17 | ControlFlowNode for IntegerLiteral | | main | _print | trace.py:5:10:5:14 | ControlFlowNode for print | | main | _status | trace.py:21:11:21:11 | ControlFlowNode for IntegerLiteral | -| main | aliased_subpackage | main.py:54:6:54:12 | ControlFlowNode for ImportExpr | | main | aliased_subpackage | main.py:54:21:54:52 | ControlFlowNode for ImportMember | | main | aliased_subpackage | main.py:65:8:65:25 | ControlFlowNode for ImportExpr | -| main | bar_attr | main.py:42:6:42:8 | ControlFlowNode for ImportExpr | | main | bar_attr | main.py:42:17:42:24 | ControlFlowNode for ImportMember | | main | check | trace.py:26:1:26:61 | ControlFlowNode for FunctionExpr | -| main | clashing_attr | main.py:83:6:83:15 | ControlFlowNode for ImportExpr | | main | clashing_attr | main.py:83:24:83:36 | ControlFlowNode for ImportMember | | main | enter | trace.py:11:1:11:21 | ControlFlowNode for FunctionExpr | | main | exit | trace.py:16:1:16:20 | ControlFlowNode for FunctionExpr | | main | foo | main.py:27:8:27:10 | ControlFlowNode for ImportExpr | | main | foo_alias | main.py:34:8:34:10 | ControlFlowNode for ImportExpr | -| main | if_then_else_defined | main.py:93:6:93:17 | ControlFlowNode for ImportExpr | | main | if_then_else_defined | main.py:93:26:93:45 | ControlFlowNode for ImportMember | | main | if_then_else_refined | main.py:100:8:100:27 | ControlFlowNode for ImportExpr | | main | local_import | main.py:57:1:57:19 | ControlFlowNode for FunctionExpr | -| main | namespace_module_attr | main.py:79:10:79:43 | ControlFlowNode for ImportExpr | | main | namespace_module_attr | main.py:79:52:79:72 | ControlFlowNode for ImportMember | -| main | non_clashing_submodule | main.py:83:6:83:15 | ControlFlowNode for ImportExpr | | main | non_clashing_submodule | main.py:83:39:83:60 | ControlFlowNode for ImportMember | | main | package | main.py:69:8:69:25 | ControlFlowNode for ImportExpr | | main | package | main.py:73:8:73:35 | ControlFlowNode for ImportExpr | -| main | package_attr_alias | main.py:50:6:50:12 | ControlFlowNode for ImportExpr | | main | package_attr_alias | main.py:50:21:50:54 | ControlFlowNode for ImportMember | | main | print | trace.py:7:1:7:27 | ControlFlowNode for FunctionExpr | -| main | print_function | main.py:21:6:21:15 | ControlFlowNode for ImportExpr | | main | print_function | main.py:21:24:21:37 | ControlFlowNode for ImportMember | | main | print_function | trace.py:1:24:1:37 | ControlFlowNode for ImportMember | | main | refined | main.py:97:8:97:14 | ControlFlowNode for ImportExpr | | main | simplistic_reexport | main.py:103:8:103:26 | ControlFlowNode for ImportExpr | | main | status | trace.py:23:1:23:13 | ControlFlowNode for FunctionExpr | | main | subpackage2_attr | package/subpackage2/__init__.py:4:20:4:37 | ControlFlowNode for Str | -| main | subpackage_attr | main.py:46:6:46:23 | ControlFlowNode for ImportExpr | | main | subpackage_attr | main.py:46:32:46:46 | ControlFlowNode for ImportMember | | main | sys | main.py:22:8:22:10 | ControlFlowNode for ImportExpr | | namespace_package.namespace_module | __all__ | trace.py:52:11:52:46 | ControlFlowNode for List | @@ -198,9 +189,7 @@ | package.subpackage.__init__ | check | trace.py:26:1:26:61 | ControlFlowNode for FunctionExpr | | package.subpackage.__init__ | enter | trace.py:11:1:11:21 | ControlFlowNode for FunctionExpr | | package.subpackage.__init__ | exit | trace.py:16:1:16:20 | ControlFlowNode for FunctionExpr | -| package.subpackage.__init__ | imported_attr | package/subpackage/__init__.py:7:6:7:7 | ControlFlowNode for ImportExpr | | package.subpackage.__init__ | imported_attr | package/subpackage/__init__.py:7:16:7:55 | ControlFlowNode for ImportMember | -| package.subpackage.__init__ | irrelevant_attr | package/subpackage/__init__.py:11:6:11:15 | ControlFlowNode for ImportExpr | | package.subpackage.__init__ | irrelevant_attr | package/subpackage/__init__.py:11:24:11:38 | ControlFlowNode for ImportMember | | package.subpackage.__init__ | print | trace.py:7:1:7:27 | ControlFlowNode for FunctionExpr | | package.subpackage.__init__ | print_function | trace.py:1:24:1:37 | ControlFlowNode for ImportMember | @@ -241,7 +230,6 @@ | simplistic_reexport | _indent_level | trace.py:3:17:3:17 | ControlFlowNode for IntegerLiteral | | simplistic_reexport | _print | trace.py:5:10:5:14 | ControlFlowNode for print | | simplistic_reexport | _status | trace.py:21:11:21:11 | ControlFlowNode for IntegerLiteral | -| simplistic_reexport | bar_attr | simplistic_reexport.py:6:6:6:8 | ControlFlowNode for ImportExpr | | simplistic_reexport | bar_attr | simplistic_reexport.py:6:17:6:24 | ControlFlowNode for ImportMember | | simplistic_reexport | bar_attr | simplistic_reexport.py:9:12:9:24 | ControlFlowNode for Str | | simplistic_reexport | baz_attr | baz.py:4:12:4:21 | ControlFlowNode for Str | @@ -260,6 +248,5 @@ | trace | enter | trace.py:11:1:11:21 | ControlFlowNode for FunctionExpr | | trace | exit | trace.py:16:1:16:20 | ControlFlowNode for FunctionExpr | | trace | print | trace.py:7:1:7:27 | ControlFlowNode for FunctionExpr | -| trace | print_function | trace.py:1:6:1:15 | ControlFlowNode for ImportExpr | | trace | print_function | trace.py:1:24:1:37 | ControlFlowNode for ImportMember | | trace | status | trace.py:23:1:23:13 | ControlFlowNode for FunctionExpr | diff --git a/python/ql/test/experimental/import-resolution/main.py b/python/ql/test/experimental/import-resolution/main.py index ee777707b92..4e09ad6173c 100644 --- a/python/ql/test/experimental/import-resolution/main.py +++ b/python/ql/test/experimental/import-resolution/main.py @@ -101,7 +101,7 @@ import if_then_else_refined # $ imports=if_then_else_refined as=if_then_else_ref check("if_then_else_refined.src", if_then_else_refined.src, if_then_else_refined.src, globals()) #$ prints=SOURCE import simplistic_reexport # $ imports=simplistic_reexport as=simplistic_reexport -check("simplistic_reexport.bar_attr", simplistic_reexport.bar_attr, "overwritten", globals()) #$ prints=overwritten SPURIOUS: prints="" prints=bar_attr +check("simplistic_reexport.bar_attr", simplistic_reexport.bar_attr, "overwritten", globals()) #$ prints=overwritten SPURIOUS: prints=bar_attr check("simplistic_reexport.baz_attr", simplistic_reexport.baz_attr, "overwritten", globals()) #$ prints=overwritten SPURIOUS: prints=baz_attr exit(__file__) From d77ce4f3d7217e7e9c7f3469a3477fface9bbeed Mon Sep 17 00:00:00 2001 From: Rasmus Wriedt Larsen Date: Wed, 22 Feb 2023 15:00:55 +0100 Subject: [PATCH 211/631] Python: minor rewrite of `from import *` handling --- .../python/dataflow/new/internal/ImportResolution.qll | 6 +++++- 1 file 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 a123f05dbc4..76542363a0c 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/ImportResolution.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/ImportResolution.qll @@ -86,7 +86,7 @@ module ImportResolution { predicate module_export(Module m, string name, DataFlow::CfgNode defn) { exists(EssaVariable v, EssaDefinition essaDef | v.getName() = name and - v.getAUse() = ImportStar::getStarImported*(m).getANormalExit() and + v.getAUse() = m.getANormalExit() and allowedEssaImportStep*(essaDef, v.getDefinition()) | defn.getNode() = essaDef.(AssignmentDefinition).getValue() @@ -94,6 +94,10 @@ module ImportResolution { defn.getNode() = essaDef.(ArgumentRefinement).getArgument() ) or + // `from import *` + module_export(ImportStar::getStarImported+(m), name, defn) + or + // `import ` or `from import ` exists(Alias a | defn.asExpr() = a.getValue() and a.getAsname().(Name).getId() = name and From be5812cf910a568037eeebd08592b572c0c09e5b Mon Sep 17 00:00:00 2001 From: Rasmus Wriedt Larsen Date: Wed, 22 Feb 2023 15:08:47 +0100 Subject: [PATCH 212/631] Python: `from import *` ignores `__all__` regression Notice that `has_defined_all_indirection` all have both `all_defined_bar_copy` and `all_defined_foo_copy` marked as exported, even though only `all_defined_foo_copy` is available. --- .../import-resolution/ModuleExport.expected | 71 +++++++++++++++++-- .../import-resolution/has_defined_all.py | 9 +++ .../import-resolution/has_defined_all_copy.py | 11 +++ .../has_defined_all_indirection.py | 6 ++ .../experimental/import-resolution/main.py | 42 +++++++++++ 5 files changed, 134 insertions(+), 5 deletions(-) create mode 100644 python/ql/test/experimental/import-resolution/has_defined_all.py create mode 100644 python/ql/test/experimental/import-resolution/has_defined_all_copy.py create mode 100644 python/ql/test/experimental/import-resolution/has_defined_all_indirection.py diff --git a/python/ql/test/experimental/import-resolution/ModuleExport.expected b/python/ql/test/experimental/import-resolution/ModuleExport.expected index 11cf82374d6..e73deb80468 100644 --- a/python/ql/test/experimental/import-resolution/ModuleExport.expected +++ b/python/ql/test/experimental/import-resolution/ModuleExport.expected @@ -76,6 +76,53 @@ | foo | print | trace.py:7:1:7:27 | ControlFlowNode for FunctionExpr | | foo | print_function | trace.py:1:24:1:37 | ControlFlowNode for ImportMember | | foo | status | trace.py:23:1:23:13 | ControlFlowNode for FunctionExpr | +| has_defined_all | __all__ | has_defined_all.py:7:11:7:29 | ControlFlowNode for List | +| has_defined_all | __all__ | trace.py:52:11:52:46 | ControlFlowNode for List | +| has_defined_all | __file__ | has_defined_all.py:2:7:2:14 | ControlFlowNode for __file__ | +| has_defined_all | __file__ | has_defined_all.py:9:6:9:13 | ControlFlowNode for __file__ | +| has_defined_all | _indent_level | trace.py:3:17:3:17 | ControlFlowNode for IntegerLiteral | +| has_defined_all | _print | trace.py:5:10:5:14 | ControlFlowNode for print | +| has_defined_all | _status | trace.py:21:11:21:11 | ControlFlowNode for IntegerLiteral | +| has_defined_all | all_defined_bar | has_defined_all.py:5:19:5:35 | ControlFlowNode for Str | +| has_defined_all | all_defined_foo | has_defined_all.py:4:19:4:35 | ControlFlowNode for Str | +| has_defined_all | check | trace.py:26:1:26:61 | ControlFlowNode for FunctionExpr | +| has_defined_all | enter | trace.py:11:1:11:21 | ControlFlowNode for FunctionExpr | +| has_defined_all | exit | trace.py:16:1:16:20 | ControlFlowNode for FunctionExpr | +| has_defined_all | print | trace.py:7:1:7:27 | ControlFlowNode for FunctionExpr | +| has_defined_all | print_function | trace.py:1:24:1:37 | ControlFlowNode for ImportMember | +| has_defined_all | status | trace.py:23:1:23:13 | ControlFlowNode for FunctionExpr | +| has_defined_all_copy | __all__ | has_defined_all_copy.py:9:11:9:34 | ControlFlowNode for List | +| has_defined_all_copy | __all__ | trace.py:52:11:52:46 | ControlFlowNode for List | +| has_defined_all_copy | __file__ | has_defined_all_copy.py:4:7:4:14 | ControlFlowNode for __file__ | +| has_defined_all_copy | __file__ | has_defined_all_copy.py:11:6:11:13 | ControlFlowNode for __file__ | +| has_defined_all_copy | _indent_level | trace.py:3:17:3:17 | ControlFlowNode for IntegerLiteral | +| has_defined_all_copy | _print | trace.py:5:10:5:14 | ControlFlowNode for print | +| has_defined_all_copy | _status | trace.py:21:11:21:11 | ControlFlowNode for IntegerLiteral | +| has_defined_all_copy | all_defined_bar_copy | has_defined_all_copy.py:7:24:7:45 | ControlFlowNode for Str | +| has_defined_all_copy | all_defined_foo_copy | has_defined_all_copy.py:6:24:6:45 | ControlFlowNode for Str | +| has_defined_all_copy | check | trace.py:26:1:26:61 | ControlFlowNode for FunctionExpr | +| has_defined_all_copy | enter | trace.py:11:1:11:21 | ControlFlowNode for FunctionExpr | +| has_defined_all_copy | exit | trace.py:16:1:16:20 | ControlFlowNode for FunctionExpr | +| has_defined_all_copy | print | trace.py:7:1:7:27 | ControlFlowNode for FunctionExpr | +| has_defined_all_copy | print_function | trace.py:1:24:1:37 | ControlFlowNode for ImportMember | +| has_defined_all_copy | status | trace.py:23:1:23:13 | ControlFlowNode for FunctionExpr | +| has_defined_all_indirection | __all__ | has_defined_all_copy.py:9:11:9:34 | ControlFlowNode for List | +| has_defined_all_indirection | __all__ | trace.py:52:11:52:46 | ControlFlowNode for List | +| has_defined_all_indirection | __file__ | has_defined_all_copy.py:4:7:4:14 | ControlFlowNode for __file__ | +| has_defined_all_indirection | __file__ | has_defined_all_copy.py:11:6:11:13 | ControlFlowNode for __file__ | +| has_defined_all_indirection | __file__ | has_defined_all_indirection.py:2:7:2:14 | ControlFlowNode for __file__ | +| has_defined_all_indirection | __file__ | has_defined_all_indirection.py:6:6:6:13 | ControlFlowNode for __file__ | +| has_defined_all_indirection | _indent_level | trace.py:3:17:3:17 | ControlFlowNode for IntegerLiteral | +| has_defined_all_indirection | _print | trace.py:5:10:5:14 | ControlFlowNode for print | +| has_defined_all_indirection | _status | trace.py:21:11:21:11 | ControlFlowNode for IntegerLiteral | +| has_defined_all_indirection | all_defined_bar_copy | has_defined_all_copy.py:7:24:7:45 | ControlFlowNode for Str | +| has_defined_all_indirection | all_defined_foo_copy | has_defined_all_copy.py:6:24:6:45 | ControlFlowNode for Str | +| has_defined_all_indirection | check | trace.py:26:1:26:61 | ControlFlowNode for FunctionExpr | +| has_defined_all_indirection | enter | trace.py:11:1:11:21 | ControlFlowNode for FunctionExpr | +| has_defined_all_indirection | exit | trace.py:16:1:16:20 | ControlFlowNode for FunctionExpr | +| has_defined_all_indirection | print | trace.py:7:1:7:27 | ControlFlowNode for FunctionExpr | +| has_defined_all_indirection | print_function | trace.py:1:24:1:37 | ControlFlowNode for ImportMember | +| has_defined_all_indirection | status | trace.py:23:1:23:13 | ControlFlowNode for FunctionExpr | | if_then_else | __all__ | trace.py:52:11:52:46 | ControlFlowNode for List | | if_then_else | __file__ | if_then_else.py:2:7:2:14 | ControlFlowNode for __file__ | | if_then_else | __file__ | if_then_else.py:16:6:16:13 | ControlFlowNode for __file__ | @@ -106,9 +153,17 @@ | if_then_else_refined | src | if_then_else_refined.py:11:11:11:16 | ControlFlowNode for SOURCE | | if_then_else_refined | src | if_then_else_refined.py:13:11:13:16 | ControlFlowNode for SOURCE | | if_then_else_refined | status | trace.py:23:1:23:13 | ControlFlowNode for FunctionExpr | +| main | __all__ | has_defined_all.py:7:11:7:29 | ControlFlowNode for List | +| main | __all__ | has_defined_all_copy.py:9:11:9:34 | ControlFlowNode for List | | main | __all__ | trace.py:52:11:52:46 | ControlFlowNode for List | +| main | __file__ | has_defined_all.py:2:7:2:14 | ControlFlowNode for __file__ | +| main | __file__ | has_defined_all.py:9:6:9:13 | ControlFlowNode for __file__ | +| main | __file__ | has_defined_all_copy.py:4:7:4:14 | ControlFlowNode for __file__ | +| main | __file__ | has_defined_all_copy.py:11:6:11:13 | ControlFlowNode for __file__ | +| main | __file__ | has_defined_all_indirection.py:2:7:2:14 | ControlFlowNode for __file__ | +| main | __file__ | has_defined_all_indirection.py:6:6:6:13 | ControlFlowNode for __file__ | | main | __file__ | main.py:24:7:24:14 | ControlFlowNode for __file__ | -| main | __file__ | main.py:107:6:107:13 | ControlFlowNode for __file__ | +| main | __file__ | main.py:149:6:149:13 | ControlFlowNode for __file__ | | main | __file__ | package/subpackage2/__init__.py:2:7:2:14 | ControlFlowNode for __file__ | | main | __file__ | package/subpackage2/__init__.py:6:6:6:13 | ControlFlowNode for __file__ | | main | _indent_level | trace.py:3:17:3:17 | ControlFlowNode for IntegerLiteral | @@ -116,6 +171,10 @@ | main | _status | trace.py:21:11:21:11 | ControlFlowNode for IntegerLiteral | | main | aliased_subpackage | main.py:54:21:54:52 | ControlFlowNode for ImportMember | | main | aliased_subpackage | main.py:65:8:65:25 | ControlFlowNode for ImportExpr | +| main | all_defined_bar | has_defined_all.py:5:19:5:35 | ControlFlowNode for Str | +| main | all_defined_bar_copy | has_defined_all_copy.py:7:24:7:45 | ControlFlowNode for Str | +| main | all_defined_foo | has_defined_all.py:4:19:4:35 | ControlFlowNode for Str | +| main | all_defined_foo_copy | has_defined_all_copy.py:6:24:6:45 | ControlFlowNode for Str | | main | bar_attr | main.py:42:17:42:24 | ControlFlowNode for ImportMember | | main | check | trace.py:26:1:26:61 | ControlFlowNode for FunctionExpr | | main | clashing_attr | main.py:83:24:83:36 | ControlFlowNode for ImportMember | @@ -123,8 +182,10 @@ | main | exit | trace.py:16:1:16:20 | ControlFlowNode for FunctionExpr | | main | foo | main.py:27:8:27:10 | ControlFlowNode for ImportExpr | | main | foo_alias | main.py:34:8:34:10 | ControlFlowNode for ImportExpr | -| main | if_then_else_defined | main.py:93:26:93:45 | ControlFlowNode for ImportMember | -| main | if_then_else_refined | main.py:100:8:100:27 | ControlFlowNode for ImportExpr | +| main | has_defined_all | main.py:100:8:100:22 | ControlFlowNode for ImportExpr | +| main | has_defined_all_indirection | main.py:118:8:118:34 | ControlFlowNode for ImportExpr | +| main | if_then_else_defined | main.py:135:26:135:45 | ControlFlowNode for ImportMember | +| main | if_then_else_refined | main.py:142:8:142:27 | ControlFlowNode for ImportExpr | | main | local_import | main.py:57:1:57:19 | ControlFlowNode for FunctionExpr | | main | namespace_module_attr | main.py:79:52:79:72 | ControlFlowNode for ImportMember | | main | non_clashing_submodule | main.py:83:39:83:60 | ControlFlowNode for ImportMember | @@ -134,8 +195,8 @@ | main | print | trace.py:7:1:7:27 | ControlFlowNode for FunctionExpr | | main | print_function | main.py:21:24:21:37 | ControlFlowNode for ImportMember | | main | print_function | trace.py:1:24:1:37 | ControlFlowNode for ImportMember | -| main | refined | main.py:97:8:97:14 | ControlFlowNode for ImportExpr | -| main | simplistic_reexport | main.py:103:8:103:26 | ControlFlowNode for ImportExpr | +| main | refined | main.py:139:8:139:14 | ControlFlowNode for ImportExpr | +| main | simplistic_reexport | main.py:145:8:145:26 | ControlFlowNode for ImportExpr | | main | status | trace.py:23:1:23:13 | ControlFlowNode for FunctionExpr | | main | subpackage2_attr | package/subpackage2/__init__.py:4:20:4:37 | ControlFlowNode for Str | | main | subpackage_attr | main.py:46:32:46:46 | ControlFlowNode for ImportMember | diff --git a/python/ql/test/experimental/import-resolution/has_defined_all.py b/python/ql/test/experimental/import-resolution/has_defined_all.py new file mode 100644 index 00000000000..9716a9a2ee1 --- /dev/null +++ b/python/ql/test/experimental/import-resolution/has_defined_all.py @@ -0,0 +1,9 @@ +from trace import * +enter(__file__) + +all_defined_foo = "all_defined_foo" +all_defined_bar = "all_defined_bar" + +__all__ = ["all_defined_foo"] + +exit(__file__) diff --git a/python/ql/test/experimental/import-resolution/has_defined_all_copy.py b/python/ql/test/experimental/import-resolution/has_defined_all_copy.py new file mode 100644 index 00000000000..bfcb1eb5054 --- /dev/null +++ b/python/ql/test/experimental/import-resolution/has_defined_all_copy.py @@ -0,0 +1,11 @@ +# a copy of `has_defined_all.py` that is imported by `has_defined_all_indirection.py` +# with its' own names such that we can check both `import *` without any cross-talk +from trace import * +enter(__file__) + +all_defined_foo_copy = "all_defined_foo_copy" +all_defined_bar_copy = "all_defined_bar_copy" + +__all__ = ["all_defined_foo_copy"] + +exit(__file__) diff --git a/python/ql/test/experimental/import-resolution/has_defined_all_indirection.py b/python/ql/test/experimental/import-resolution/has_defined_all_indirection.py new file mode 100644 index 00000000000..c928205fdcb --- /dev/null +++ b/python/ql/test/experimental/import-resolution/has_defined_all_indirection.py @@ -0,0 +1,6 @@ +from trace import * +enter(__file__) + +from has_defined_all_copy import * + +exit(__file__) diff --git a/python/ql/test/experimental/import-resolution/main.py b/python/ql/test/experimental/import-resolution/main.py index 4e09ad6173c..fab3a447d64 100644 --- a/python/ql/test/experimental/import-resolution/main.py +++ b/python/ql/test/experimental/import-resolution/main.py @@ -84,6 +84,48 @@ from attr_clash import clashing_attr, non_clashing_submodule #$ imports=attr_cla check("clashing_attr", clashing_attr, "clashing_attr", globals()) #$ prints=clashing_attr SPURIOUS: prints="" check("non_clashing_submodule", non_clashing_submodule, "", globals()) #$ prints="" +# check that import * only imports the __all__ attributes +from has_defined_all import * +check("all_defined_foo", all_defined_foo, "all_defined_foo", globals()) #$ prints=all_defined_foo + +try: + check("all_defined_bar", all_defined_bar, "all_defined_bar", globals()) #$ SPURIOUS: prints=all_defined_bar + raise Exception("Did not get expected NameError") +except NameError as e: + if "all_defined_bar" in str(e): + print("Got expected NameError:", e) + else: + raise + +import has_defined_all # $ imports=has_defined_all as=has_defined_all +check("has_defined_all.all_defined_foo", has_defined_all.all_defined_foo, "all_defined_foo", globals()) #$ prints=all_defined_foo +check("has_defined_all.all_defined_bar", has_defined_all.all_defined_bar, "all_defined_bar", globals()) #$ prints=all_defined_bar + +# same check as above, but going through one level of indirection (which can make a difference) +from has_defined_all_indirection import * +check("all_defined_foo_copy", all_defined_foo_copy, "all_defined_foo_copy", globals()) #$ prints=all_defined_foo_copy + +try: + check("all_defined_bar_copy", all_defined_bar_copy, "all_defined_bar_copy", globals()) #$ SPURIOUS: prints=all_defined_bar_copy + raise Exception("Did not get expected NameError") +except NameError as e: + if "all_defined_bar_copy" in str(e): + print("Got expected NameError:", e) + else: + raise + +# same check as above, but going through one level of indirection (which can make a difference) +import has_defined_all_indirection # $ imports=has_defined_all_indirection as=has_defined_all_indirection +check("has_defined_all_indirection.all_defined_foo_copy", has_defined_all_indirection.all_defined_foo_copy, "all_defined_foo_copy", globals()) #$ prints=all_defined_foo_copy + +try: + check("has_defined_all_indirection.all_defined_bar_copy", has_defined_all_indirection.all_defined_bar_copy, "all_defined_bar_copy", globals()) #$ SPURIOUS: prints=all_defined_bar_copy + raise Exception("Did not get expected AttributeError") +except AttributeError as e: + if "all_defined_bar_copy" in str(e): + print("Got expected AttributeError:", e) + else: + raise # check that import * from an __init__ file works from package.subpackage2 import * From c8a76246d8992dade7496409fc07da6e31423e42 Mon Sep 17 00:00:00 2001 From: Rasmus Wriedt Larsen Date: Wed, 22 Feb 2023 15:33:02 +0100 Subject: [PATCH 213/631] Python: Take `__all__` into consideration for re-export of `from import *` However, we can see that `from import *` and `import pkg` are handled differently. Would have liked `has_defined_all_indirection` to behave in the same way no matter how the import was made. --- .../new/internal/ImportResolution.qll | 6 +- .../import-resolution/ModuleExport.expected | 133 ------------------ .../experimental/import-resolution/main.py | 2 +- 3 files changed, 6 insertions(+), 135 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 76542363a0c..5e0192b1553 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/ImportResolution.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/ImportResolution.qll @@ -95,7 +95,11 @@ module ImportResolution { ) or // `from import *` - module_export(ImportStar::getStarImported+(m), name, defn) + exists(Module importedFrom | + importedFrom = ImportStar::getStarImported(m) and + module_export(importedFrom, name, defn) and + potential_module_export(importedFrom, name) + ) or // `import ` or `from import ` exists(Alias a | diff --git a/python/ql/test/experimental/import-resolution/ModuleExport.expected b/python/ql/test/experimental/import-resolution/ModuleExport.expected index e73deb80468..341a58e4d34 100644 --- a/python/ql/test/experimental/import-resolution/ModuleExport.expected +++ b/python/ql/test/experimental/import-resolution/ModuleExport.expected @@ -1,180 +1,93 @@ -| attr_clash.__init__ | __all__ | trace.py:52:11:52:46 | ControlFlowNode for List | | attr_clash.__init__ | __file__ | attr_clash/__init__.py:2:7:2:14 | ControlFlowNode for __file__ | | attr_clash.__init__ | __file__ | attr_clash/__init__.py:6:6:6:13 | ControlFlowNode for __file__ | -| attr_clash.__init__ | _indent_level | trace.py:3:17:3:17 | ControlFlowNode for IntegerLiteral | -| attr_clash.__init__ | _print | trace.py:5:10:5:14 | ControlFlowNode for print | -| attr_clash.__init__ | _status | trace.py:21:11:21:11 | ControlFlowNode for IntegerLiteral | | attr_clash.__init__ | check | trace.py:26:1:26:61 | ControlFlowNode for FunctionExpr | | attr_clash.__init__ | clashing_attr | attr_clash/__init__.py:4:17:4:31 | ControlFlowNode for Str | | attr_clash.__init__ | enter | trace.py:11:1:11:21 | ControlFlowNode for FunctionExpr | | attr_clash.__init__ | exit | trace.py:16:1:16:20 | ControlFlowNode for FunctionExpr | -| attr_clash.__init__ | print | trace.py:7:1:7:27 | ControlFlowNode for FunctionExpr | -| attr_clash.__init__ | print_function | trace.py:1:24:1:37 | ControlFlowNode for ImportMember | | attr_clash.__init__ | status | trace.py:23:1:23:13 | ControlFlowNode for FunctionExpr | -| attr_clash.clashing_attr | __all__ | trace.py:52:11:52:46 | ControlFlowNode for List | | attr_clash.clashing_attr | __file__ | attr_clash/clashing_attr.py:2:7:2:14 | ControlFlowNode for __file__ | | attr_clash.clashing_attr | __file__ | attr_clash/clashing_attr.py:4:6:4:13 | ControlFlowNode for __file__ | -| attr_clash.clashing_attr | _indent_level | trace.py:3:17:3:17 | ControlFlowNode for IntegerLiteral | -| attr_clash.clashing_attr | _print | trace.py:5:10:5:14 | ControlFlowNode for print | -| attr_clash.clashing_attr | _status | trace.py:21:11:21:11 | ControlFlowNode for IntegerLiteral | | attr_clash.clashing_attr | check | trace.py:26:1:26:61 | ControlFlowNode for FunctionExpr | | attr_clash.clashing_attr | enter | trace.py:11:1:11:21 | ControlFlowNode for FunctionExpr | | attr_clash.clashing_attr | exit | trace.py:16:1:16:20 | ControlFlowNode for FunctionExpr | -| attr_clash.clashing_attr | print | trace.py:7:1:7:27 | ControlFlowNode for FunctionExpr | -| attr_clash.clashing_attr | print_function | trace.py:1:24:1:37 | ControlFlowNode for ImportMember | | attr_clash.clashing_attr | status | trace.py:23:1:23:13 | ControlFlowNode for FunctionExpr | -| attr_clash.non_clashing_submodule | __all__ | trace.py:52:11:52:46 | ControlFlowNode for List | | attr_clash.non_clashing_submodule | __file__ | attr_clash/non_clashing_submodule.py:2:7:2:14 | ControlFlowNode for __file__ | | attr_clash.non_clashing_submodule | __file__ | attr_clash/non_clashing_submodule.py:4:6:4:13 | ControlFlowNode for __file__ | -| attr_clash.non_clashing_submodule | _indent_level | trace.py:3:17:3:17 | ControlFlowNode for IntegerLiteral | -| attr_clash.non_clashing_submodule | _print | trace.py:5:10:5:14 | ControlFlowNode for print | -| attr_clash.non_clashing_submodule | _status | trace.py:21:11:21:11 | ControlFlowNode for IntegerLiteral | | attr_clash.non_clashing_submodule | check | trace.py:26:1:26:61 | ControlFlowNode for FunctionExpr | | attr_clash.non_clashing_submodule | enter | trace.py:11:1:11:21 | ControlFlowNode for FunctionExpr | | attr_clash.non_clashing_submodule | exit | trace.py:16:1:16:20 | ControlFlowNode for FunctionExpr | -| attr_clash.non_clashing_submodule | print | trace.py:7:1:7:27 | ControlFlowNode for FunctionExpr | -| attr_clash.non_clashing_submodule | print_function | trace.py:1:24:1:37 | ControlFlowNode for ImportMember | | attr_clash.non_clashing_submodule | status | trace.py:23:1:23:13 | ControlFlowNode for FunctionExpr | -| bar | __all__ | trace.py:52:11:52:46 | ControlFlowNode for List | | bar | __file__ | bar.py:2:7:2:14 | ControlFlowNode for __file__ | | bar | __file__ | bar.py:6:6:6:13 | ControlFlowNode for __file__ | -| bar | _indent_level | trace.py:3:17:3:17 | ControlFlowNode for IntegerLiteral | -| bar | _print | trace.py:5:10:5:14 | ControlFlowNode for print | -| bar | _status | trace.py:21:11:21:11 | ControlFlowNode for IntegerLiteral | | bar | bar_attr | bar.py:4:12:4:21 | ControlFlowNode for Str | | bar | check | trace.py:26:1:26:61 | ControlFlowNode for FunctionExpr | | bar | enter | trace.py:11:1:11:21 | ControlFlowNode for FunctionExpr | | bar | exit | trace.py:16:1:16:20 | ControlFlowNode for FunctionExpr | -| bar | print | trace.py:7:1:7:27 | ControlFlowNode for FunctionExpr | -| bar | print_function | trace.py:1:24:1:37 | ControlFlowNode for ImportMember | | bar | status | trace.py:23:1:23:13 | ControlFlowNode for FunctionExpr | -| baz | __all__ | trace.py:52:11:52:46 | ControlFlowNode for List | | baz | __file__ | baz.py:2:7:2:14 | ControlFlowNode for __file__ | | baz | __file__ | baz.py:6:6:6:13 | ControlFlowNode for __file__ | -| baz | _indent_level | trace.py:3:17:3:17 | ControlFlowNode for IntegerLiteral | -| baz | _print | trace.py:5:10:5:14 | ControlFlowNode for print | -| baz | _status | trace.py:21:11:21:11 | ControlFlowNode for IntegerLiteral | | baz | baz_attr | baz.py:4:12:4:21 | ControlFlowNode for Str | | baz | check | trace.py:26:1:26:61 | ControlFlowNode for FunctionExpr | | baz | enter | trace.py:11:1:11:21 | ControlFlowNode for FunctionExpr | | baz | exit | trace.py:16:1:16:20 | ControlFlowNode for FunctionExpr | -| baz | print | trace.py:7:1:7:27 | ControlFlowNode for FunctionExpr | -| baz | print_function | trace.py:1:24:1:37 | ControlFlowNode for ImportMember | | baz | status | trace.py:23:1:23:13 | ControlFlowNode for FunctionExpr | -| foo | __all__ | trace.py:52:11:52:46 | ControlFlowNode for List | | foo | __file__ | foo.py:2:7:2:14 | ControlFlowNode for __file__ | | foo | __file__ | foo.py:14:6:14:13 | ControlFlowNode for __file__ | | foo | __private_foo_attr | foo.py:8:22:8:41 | ControlFlowNode for Str | -| foo | _indent_level | trace.py:3:17:3:17 | ControlFlowNode for IntegerLiteral | -| foo | _print | trace.py:5:10:5:14 | ControlFlowNode for print | -| foo | _status | trace.py:21:11:21:11 | ControlFlowNode for IntegerLiteral | | foo | bar_reexported | foo.py:11:8:11:10 | ControlFlowNode for ImportExpr | | foo | check | trace.py:26:1:26:61 | ControlFlowNode for FunctionExpr | | foo | enter | trace.py:11:1:11:21 | ControlFlowNode for FunctionExpr | | foo | exit | trace.py:16:1:16:20 | ControlFlowNode for FunctionExpr | | foo | foo_attr | foo.py:5:12:5:21 | ControlFlowNode for Str | -| foo | print | trace.py:7:1:7:27 | ControlFlowNode for FunctionExpr | -| foo | print_function | trace.py:1:24:1:37 | ControlFlowNode for ImportMember | | foo | status | trace.py:23:1:23:13 | ControlFlowNode for FunctionExpr | | has_defined_all | __all__ | has_defined_all.py:7:11:7:29 | ControlFlowNode for List | -| has_defined_all | __all__ | trace.py:52:11:52:46 | ControlFlowNode for List | | has_defined_all | __file__ | has_defined_all.py:2:7:2:14 | ControlFlowNode for __file__ | | has_defined_all | __file__ | has_defined_all.py:9:6:9:13 | ControlFlowNode for __file__ | -| has_defined_all | _indent_level | trace.py:3:17:3:17 | ControlFlowNode for IntegerLiteral | -| has_defined_all | _print | trace.py:5:10:5:14 | ControlFlowNode for print | -| has_defined_all | _status | trace.py:21:11:21:11 | ControlFlowNode for IntegerLiteral | | has_defined_all | all_defined_bar | has_defined_all.py:5:19:5:35 | ControlFlowNode for Str | | has_defined_all | all_defined_foo | has_defined_all.py:4:19:4:35 | ControlFlowNode for Str | | has_defined_all | check | trace.py:26:1:26:61 | ControlFlowNode for FunctionExpr | | has_defined_all | enter | trace.py:11:1:11:21 | ControlFlowNode for FunctionExpr | | has_defined_all | exit | trace.py:16:1:16:20 | ControlFlowNode for FunctionExpr | -| has_defined_all | print | trace.py:7:1:7:27 | ControlFlowNode for FunctionExpr | -| has_defined_all | print_function | trace.py:1:24:1:37 | ControlFlowNode for ImportMember | | has_defined_all | status | trace.py:23:1:23:13 | ControlFlowNode for FunctionExpr | | has_defined_all_copy | __all__ | has_defined_all_copy.py:9:11:9:34 | ControlFlowNode for List | -| has_defined_all_copy | __all__ | trace.py:52:11:52:46 | ControlFlowNode for List | | has_defined_all_copy | __file__ | has_defined_all_copy.py:4:7:4:14 | ControlFlowNode for __file__ | | has_defined_all_copy | __file__ | has_defined_all_copy.py:11:6:11:13 | ControlFlowNode for __file__ | -| has_defined_all_copy | _indent_level | trace.py:3:17:3:17 | ControlFlowNode for IntegerLiteral | -| has_defined_all_copy | _print | trace.py:5:10:5:14 | ControlFlowNode for print | -| has_defined_all_copy | _status | trace.py:21:11:21:11 | ControlFlowNode for IntegerLiteral | | has_defined_all_copy | all_defined_bar_copy | has_defined_all_copy.py:7:24:7:45 | ControlFlowNode for Str | | has_defined_all_copy | all_defined_foo_copy | has_defined_all_copy.py:6:24:6:45 | ControlFlowNode for Str | | has_defined_all_copy | check | trace.py:26:1:26:61 | ControlFlowNode for FunctionExpr | | has_defined_all_copy | enter | trace.py:11:1:11:21 | ControlFlowNode for FunctionExpr | | has_defined_all_copy | exit | trace.py:16:1:16:20 | ControlFlowNode for FunctionExpr | -| has_defined_all_copy | print | trace.py:7:1:7:27 | ControlFlowNode for FunctionExpr | -| has_defined_all_copy | print_function | trace.py:1:24:1:37 | ControlFlowNode for ImportMember | | has_defined_all_copy | status | trace.py:23:1:23:13 | ControlFlowNode for FunctionExpr | -| has_defined_all_indirection | __all__ | has_defined_all_copy.py:9:11:9:34 | ControlFlowNode for List | -| has_defined_all_indirection | __all__ | trace.py:52:11:52:46 | ControlFlowNode for List | -| has_defined_all_indirection | __file__ | has_defined_all_copy.py:4:7:4:14 | ControlFlowNode for __file__ | -| has_defined_all_indirection | __file__ | has_defined_all_copy.py:11:6:11:13 | ControlFlowNode for __file__ | | has_defined_all_indirection | __file__ | has_defined_all_indirection.py:2:7:2:14 | ControlFlowNode for __file__ | | has_defined_all_indirection | __file__ | has_defined_all_indirection.py:6:6:6:13 | ControlFlowNode for __file__ | -| has_defined_all_indirection | _indent_level | trace.py:3:17:3:17 | ControlFlowNode for IntegerLiteral | -| has_defined_all_indirection | _print | trace.py:5:10:5:14 | ControlFlowNode for print | -| has_defined_all_indirection | _status | trace.py:21:11:21:11 | ControlFlowNode for IntegerLiteral | -| has_defined_all_indirection | all_defined_bar_copy | has_defined_all_copy.py:7:24:7:45 | ControlFlowNode for Str | | has_defined_all_indirection | all_defined_foo_copy | has_defined_all_copy.py:6:24:6:45 | ControlFlowNode for Str | | has_defined_all_indirection | check | trace.py:26:1:26:61 | ControlFlowNode for FunctionExpr | | has_defined_all_indirection | enter | trace.py:11:1:11:21 | ControlFlowNode for FunctionExpr | | has_defined_all_indirection | exit | trace.py:16:1:16:20 | ControlFlowNode for FunctionExpr | -| has_defined_all_indirection | print | trace.py:7:1:7:27 | ControlFlowNode for FunctionExpr | -| has_defined_all_indirection | print_function | trace.py:1:24:1:37 | ControlFlowNode for ImportMember | | has_defined_all_indirection | status | trace.py:23:1:23:13 | ControlFlowNode for FunctionExpr | -| if_then_else | __all__ | trace.py:52:11:52:46 | ControlFlowNode for List | | if_then_else | __file__ | if_then_else.py:2:7:2:14 | ControlFlowNode for __file__ | | if_then_else | __file__ | if_then_else.py:16:6:16:13 | ControlFlowNode for __file__ | -| if_then_else | _indent_level | trace.py:3:17:3:17 | ControlFlowNode for IntegerLiteral | -| if_then_else | _print | trace.py:5:10:5:14 | ControlFlowNode for print | -| if_then_else | _status | trace.py:21:11:21:11 | ControlFlowNode for IntegerLiteral | | if_then_else | check | trace.py:26:1:26:61 | ControlFlowNode for FunctionExpr | | if_then_else | enter | trace.py:11:1:11:21 | ControlFlowNode for FunctionExpr | | if_then_else | exit | trace.py:16:1:16:20 | ControlFlowNode for FunctionExpr | | if_then_else | if_then_else_defined | if_then_else.py:7:28:7:39 | ControlFlowNode for Str | | if_then_else | if_then_else_defined | if_then_else.py:12:32:12:47 | ControlFlowNode for Str | | if_then_else | if_then_else_defined | if_then_else.py:14:32:14:47 | ControlFlowNode for Str | -| if_then_else | print | trace.py:7:1:7:27 | ControlFlowNode for FunctionExpr | -| if_then_else | print_function | trace.py:1:24:1:37 | ControlFlowNode for ImportMember | | if_then_else | status | trace.py:23:1:23:13 | ControlFlowNode for FunctionExpr | | if_then_else_refined | SOURCE | if_then_else_refined.py:6:1:6:15 | ControlFlowNode for ClassExpr | -| if_then_else_refined | __all__ | trace.py:52:11:52:46 | ControlFlowNode for List | | if_then_else_refined | __file__ | if_then_else_refined.py:4:7:4:14 | ControlFlowNode for __file__ | | if_then_else_refined | __file__ | if_then_else_refined.py:19:6:19:13 | ControlFlowNode for __file__ | -| if_then_else_refined | _indent_level | trace.py:3:17:3:17 | ControlFlowNode for IntegerLiteral | -| if_then_else_refined | _print | trace.py:5:10:5:14 | ControlFlowNode for print | -| if_then_else_refined | _status | trace.py:21:11:21:11 | ControlFlowNode for IntegerLiteral | | if_then_else_refined | check | trace.py:26:1:26:61 | ControlFlowNode for FunctionExpr | | if_then_else_refined | enter | trace.py:11:1:11:21 | ControlFlowNode for FunctionExpr | | if_then_else_refined | exit | trace.py:16:1:16:20 | ControlFlowNode for FunctionExpr | -| if_then_else_refined | print | trace.py:7:1:7:27 | ControlFlowNode for FunctionExpr | -| if_then_else_refined | print_function | trace.py:1:24:1:37 | ControlFlowNode for ImportMember | | if_then_else_refined | src | if_then_else_refined.py:11:11:11:16 | ControlFlowNode for SOURCE | | if_then_else_refined | src | if_then_else_refined.py:13:11:13:16 | ControlFlowNode for SOURCE | | if_then_else_refined | status | trace.py:23:1:23:13 | ControlFlowNode for FunctionExpr | -| main | __all__ | has_defined_all.py:7:11:7:29 | ControlFlowNode for List | -| main | __all__ | has_defined_all_copy.py:9:11:9:34 | ControlFlowNode for List | -| main | __all__ | trace.py:52:11:52:46 | ControlFlowNode for List | -| main | __file__ | has_defined_all.py:2:7:2:14 | ControlFlowNode for __file__ | -| main | __file__ | has_defined_all.py:9:6:9:13 | ControlFlowNode for __file__ | -| main | __file__ | has_defined_all_copy.py:4:7:4:14 | ControlFlowNode for __file__ | -| main | __file__ | has_defined_all_copy.py:11:6:11:13 | ControlFlowNode for __file__ | -| main | __file__ | has_defined_all_indirection.py:2:7:2:14 | ControlFlowNode for __file__ | -| main | __file__ | has_defined_all_indirection.py:6:6:6:13 | ControlFlowNode for __file__ | | main | __file__ | main.py:24:7:24:14 | ControlFlowNode for __file__ | | main | __file__ | main.py:149:6:149:13 | ControlFlowNode for __file__ | -| main | __file__ | package/subpackage2/__init__.py:2:7:2:14 | ControlFlowNode for __file__ | -| main | __file__ | package/subpackage2/__init__.py:6:6:6:13 | ControlFlowNode for __file__ | -| main | _indent_level | trace.py:3:17:3:17 | ControlFlowNode for IntegerLiteral | -| main | _print | trace.py:5:10:5:14 | ControlFlowNode for print | -| main | _status | trace.py:21:11:21:11 | ControlFlowNode for IntegerLiteral | | main | aliased_subpackage | main.py:54:21:54:52 | ControlFlowNode for ImportMember | | main | aliased_subpackage | main.py:65:8:65:25 | ControlFlowNode for ImportExpr | -| main | all_defined_bar | has_defined_all.py:5:19:5:35 | ControlFlowNode for Str | -| main | all_defined_bar_copy | has_defined_all_copy.py:7:24:7:45 | ControlFlowNode for Str | | main | all_defined_foo | has_defined_all.py:4:19:4:35 | ControlFlowNode for Str | -| main | all_defined_foo_copy | has_defined_all_copy.py:6:24:6:45 | ControlFlowNode for Str | | main | bar_attr | main.py:42:17:42:24 | ControlFlowNode for ImportMember | | main | check | trace.py:26:1:26:61 | ControlFlowNode for FunctionExpr | | main | clashing_attr | main.py:83:24:83:36 | ControlFlowNode for ImportMember | @@ -192,105 +105,61 @@ | main | package | main.py:69:8:69:25 | ControlFlowNode for ImportExpr | | main | package | main.py:73:8:73:35 | ControlFlowNode for ImportExpr | | main | package_attr_alias | main.py:50:21:50:54 | ControlFlowNode for ImportMember | -| main | print | trace.py:7:1:7:27 | ControlFlowNode for FunctionExpr | | main | print_function | main.py:21:24:21:37 | ControlFlowNode for ImportMember | -| main | print_function | trace.py:1:24:1:37 | ControlFlowNode for ImportMember | | main | refined | main.py:139:8:139:14 | ControlFlowNode for ImportExpr | | main | simplistic_reexport | main.py:145:8:145:26 | ControlFlowNode for ImportExpr | | main | status | trace.py:23:1:23:13 | ControlFlowNode for FunctionExpr | | main | subpackage2_attr | package/subpackage2/__init__.py:4:20:4:37 | ControlFlowNode for Str | | main | subpackage_attr | main.py:46:32:46:46 | ControlFlowNode for ImportMember | | main | sys | main.py:22:8:22:10 | ControlFlowNode for ImportExpr | -| namespace_package.namespace_module | __all__ | trace.py:52:11:52:46 | ControlFlowNode for List | | namespace_package.namespace_module | __file__ | namespace_package/namespace_module.py:2:7:2:14 | ControlFlowNode for __file__ | | namespace_package.namespace_module | __file__ | namespace_package/namespace_module.py:6:6:6:13 | ControlFlowNode for __file__ | -| namespace_package.namespace_module | _indent_level | trace.py:3:17:3:17 | ControlFlowNode for IntegerLiteral | -| namespace_package.namespace_module | _print | trace.py:5:10:5:14 | ControlFlowNode for print | -| namespace_package.namespace_module | _status | trace.py:21:11:21:11 | ControlFlowNode for IntegerLiteral | | namespace_package.namespace_module | check | trace.py:26:1:26:61 | ControlFlowNode for FunctionExpr | | namespace_package.namespace_module | enter | trace.py:11:1:11:21 | ControlFlowNode for FunctionExpr | | namespace_package.namespace_module | exit | trace.py:16:1:16:20 | ControlFlowNode for FunctionExpr | | namespace_package.namespace_module | namespace_module_attr | namespace_package/namespace_module.py:4:25:4:47 | ControlFlowNode for Str | -| namespace_package.namespace_module | print | trace.py:7:1:7:27 | ControlFlowNode for FunctionExpr | -| namespace_package.namespace_module | print_function | trace.py:1:24:1:37 | ControlFlowNode for ImportMember | | namespace_package.namespace_module | status | trace.py:23:1:23:13 | ControlFlowNode for FunctionExpr | -| package.__init__ | __all__ | trace.py:52:11:52:46 | ControlFlowNode for List | | package.__init__ | __file__ | package/__init__.py:2:7:2:14 | ControlFlowNode for __file__ | | package.__init__ | __file__ | package/__init__.py:7:6:7:13 | ControlFlowNode for __file__ | -| package.__init__ | _indent_level | trace.py:3:17:3:17 | ControlFlowNode for IntegerLiteral | -| package.__init__ | _print | trace.py:5:10:5:14 | ControlFlowNode for print | -| package.__init__ | _status | trace.py:21:11:21:11 | ControlFlowNode for IntegerLiteral | | package.__init__ | attr_used_in_subpackage | package/__init__.py:4:27:4:51 | ControlFlowNode for Str | | package.__init__ | check | trace.py:26:1:26:61 | ControlFlowNode for FunctionExpr | | package.__init__ | enter | trace.py:11:1:11:21 | ControlFlowNode for FunctionExpr | | package.__init__ | exit | trace.py:16:1:16:20 | ControlFlowNode for FunctionExpr | | package.__init__ | package_attr | package/__init__.py:5:16:5:29 | ControlFlowNode for Str | -| package.__init__ | print | trace.py:7:1:7:27 | ControlFlowNode for FunctionExpr | -| package.__init__ | print_function | trace.py:1:24:1:37 | ControlFlowNode for ImportMember | | package.__init__ | status | trace.py:23:1:23:13 | ControlFlowNode for FunctionExpr | -| package.subpackage2.__init__ | __all__ | trace.py:52:11:52:46 | ControlFlowNode for List | | package.subpackage2.__init__ | __file__ | package/subpackage2/__init__.py:2:7:2:14 | ControlFlowNode for __file__ | | package.subpackage2.__init__ | __file__ | package/subpackage2/__init__.py:6:6:6:13 | ControlFlowNode for __file__ | -| package.subpackage2.__init__ | _indent_level | trace.py:3:17:3:17 | ControlFlowNode for IntegerLiteral | -| package.subpackage2.__init__ | _print | trace.py:5:10:5:14 | ControlFlowNode for print | -| package.subpackage2.__init__ | _status | trace.py:21:11:21:11 | ControlFlowNode for IntegerLiteral | | package.subpackage2.__init__ | check | trace.py:26:1:26:61 | ControlFlowNode for FunctionExpr | | package.subpackage2.__init__ | enter | trace.py:11:1:11:21 | ControlFlowNode for FunctionExpr | | package.subpackage2.__init__ | exit | trace.py:16:1:16:20 | ControlFlowNode for FunctionExpr | -| package.subpackage2.__init__ | print | trace.py:7:1:7:27 | ControlFlowNode for FunctionExpr | -| package.subpackage2.__init__ | print_function | trace.py:1:24:1:37 | ControlFlowNode for ImportMember | | package.subpackage2.__init__ | status | trace.py:23:1:23:13 | ControlFlowNode for FunctionExpr | | package.subpackage2.__init__ | subpackage2_attr | package/subpackage2/__init__.py:4:20:4:37 | ControlFlowNode for Str | -| package.subpackage.__init__ | __all__ | trace.py:52:11:52:46 | ControlFlowNode for List | | package.subpackage.__init__ | __file__ | package/subpackage/__init__.py:2:7:2:14 | ControlFlowNode for __file__ | | package.subpackage.__init__ | __file__ | package/subpackage/__init__.py:14:6:14:13 | ControlFlowNode for __file__ | -| package.subpackage.__init__ | _indent_level | trace.py:3:17:3:17 | ControlFlowNode for IntegerLiteral | -| package.subpackage.__init__ | _print | trace.py:5:10:5:14 | ControlFlowNode for print | -| package.subpackage.__init__ | _status | trace.py:21:11:21:11 | ControlFlowNode for IntegerLiteral | | package.subpackage.__init__ | check | trace.py:26:1:26:61 | ControlFlowNode for FunctionExpr | | package.subpackage.__init__ | enter | trace.py:11:1:11:21 | ControlFlowNode for FunctionExpr | | package.subpackage.__init__ | exit | trace.py:16:1:16:20 | ControlFlowNode for FunctionExpr | | package.subpackage.__init__ | imported_attr | package/subpackage/__init__.py:7:16:7:55 | ControlFlowNode for ImportMember | | package.subpackage.__init__ | irrelevant_attr | package/subpackage/__init__.py:11:24:11:38 | ControlFlowNode for ImportMember | -| package.subpackage.__init__ | print | trace.py:7:1:7:27 | ControlFlowNode for FunctionExpr | -| package.subpackage.__init__ | print_function | trace.py:1:24:1:37 | ControlFlowNode for ImportMember | | package.subpackage.__init__ | status | trace.py:23:1:23:13 | ControlFlowNode for FunctionExpr | | package.subpackage.__init__ | subpackage_attr | package/subpackage/__init__.py:4:19:4:35 | ControlFlowNode for Str | -| package.subpackage.submodule | __all__ | trace.py:52:11:52:46 | ControlFlowNode for List | | package.subpackage.submodule | __file__ | package/subpackage/submodule.py:2:7:2:14 | ControlFlowNode for __file__ | | package.subpackage.submodule | __file__ | package/subpackage/submodule.py:7:6:7:13 | ControlFlowNode for __file__ | -| package.subpackage.submodule | _indent_level | trace.py:3:17:3:17 | ControlFlowNode for IntegerLiteral | -| package.subpackage.submodule | _print | trace.py:5:10:5:14 | ControlFlowNode for print | -| package.subpackage.submodule | _status | trace.py:21:11:21:11 | ControlFlowNode for IntegerLiteral | | package.subpackage.submodule | check | trace.py:26:1:26:61 | ControlFlowNode for FunctionExpr | | package.subpackage.submodule | enter | trace.py:11:1:11:21 | ControlFlowNode for FunctionExpr | | package.subpackage.submodule | exit | trace.py:16:1:16:20 | ControlFlowNode for FunctionExpr | | package.subpackage.submodule | irrelevant_attr | package/subpackage/submodule.py:5:19:5:35 | ControlFlowNode for Str | -| package.subpackage.submodule | print | trace.py:7:1:7:27 | ControlFlowNode for FunctionExpr | -| package.subpackage.submodule | print_function | trace.py:1:24:1:37 | ControlFlowNode for ImportMember | | package.subpackage.submodule | status | trace.py:23:1:23:13 | ControlFlowNode for FunctionExpr | | package.subpackage.submodule | submodule_attr | package/subpackage/submodule.py:4:18:4:33 | ControlFlowNode for Str | | refined | SOURCE | refined.py:4:1:4:21 | ControlFlowNode for ClassExpr | -| refined | __all__ | trace.py:52:11:52:46 | ControlFlowNode for List | | refined | __file__ | refined.py:2:7:2:14 | ControlFlowNode for __file__ | | refined | __file__ | refined.py:14:6:14:13 | ControlFlowNode for __file__ | -| refined | _indent_level | trace.py:3:17:3:17 | ControlFlowNode for IntegerLiteral | -| refined | _print | trace.py:5:10:5:14 | ControlFlowNode for print | -| refined | _status | trace.py:21:11:21:11 | ControlFlowNode for IntegerLiteral | | refined | check | trace.py:26:1:26:61 | ControlFlowNode for FunctionExpr | | refined | enter | trace.py:11:1:11:21 | ControlFlowNode for FunctionExpr | | refined | exit | trace.py:16:1:16:20 | ControlFlowNode for FunctionExpr | -| refined | print | trace.py:7:1:7:27 | ControlFlowNode for FunctionExpr | -| refined | print_function | trace.py:1:24:1:37 | ControlFlowNode for ImportMember | | refined | status | trace.py:23:1:23:13 | ControlFlowNode for FunctionExpr | -| simplistic_reexport | __all__ | trace.py:52:11:52:46 | ControlFlowNode for List | -| simplistic_reexport | __file__ | baz.py:2:7:2:14 | ControlFlowNode for __file__ | -| simplistic_reexport | __file__ | baz.py:6:6:6:13 | ControlFlowNode for __file__ | | simplistic_reexport | __file__ | simplistic_reexport.py:4:7:4:14 | ControlFlowNode for __file__ | | simplistic_reexport | __file__ | simplistic_reexport.py:19:6:19:13 | ControlFlowNode for __file__ | -| simplistic_reexport | _indent_level | trace.py:3:17:3:17 | ControlFlowNode for IntegerLiteral | -| simplistic_reexport | _print | trace.py:5:10:5:14 | ControlFlowNode for print | -| simplistic_reexport | _status | trace.py:21:11:21:11 | ControlFlowNode for IntegerLiteral | | simplistic_reexport | bar_attr | simplistic_reexport.py:6:17:6:24 | ControlFlowNode for ImportMember | | simplistic_reexport | bar_attr | simplistic_reexport.py:9:12:9:24 | ControlFlowNode for Str | | simplistic_reexport | baz_attr | baz.py:4:12:4:21 | ControlFlowNode for Str | @@ -298,8 +167,6 @@ | simplistic_reexport | check | trace.py:26:1:26:61 | ControlFlowNode for FunctionExpr | | simplistic_reexport | enter | trace.py:11:1:11:21 | ControlFlowNode for FunctionExpr | | simplistic_reexport | exit | trace.py:16:1:16:20 | ControlFlowNode for FunctionExpr | -| simplistic_reexport | print | trace.py:7:1:7:27 | ControlFlowNode for FunctionExpr | -| simplistic_reexport | print_function | trace.py:1:24:1:37 | ControlFlowNode for ImportMember | | simplistic_reexport | status | trace.py:23:1:23:13 | ControlFlowNode for FunctionExpr | | trace | __all__ | trace.py:52:11:52:46 | ControlFlowNode for List | | trace | _indent_level | trace.py:3:17:3:17 | ControlFlowNode for IntegerLiteral | diff --git a/python/ql/test/experimental/import-resolution/main.py b/python/ql/test/experimental/import-resolution/main.py index fab3a447d64..98b97fafb0e 100644 --- a/python/ql/test/experimental/import-resolution/main.py +++ b/python/ql/test/experimental/import-resolution/main.py @@ -119,7 +119,7 @@ import has_defined_all_indirection # $ imports=has_defined_all_indirection as=ha check("has_defined_all_indirection.all_defined_foo_copy", has_defined_all_indirection.all_defined_foo_copy, "all_defined_foo_copy", globals()) #$ prints=all_defined_foo_copy try: - check("has_defined_all_indirection.all_defined_bar_copy", has_defined_all_indirection.all_defined_bar_copy, "all_defined_bar_copy", globals()) #$ SPURIOUS: prints=all_defined_bar_copy + check("has_defined_all_indirection.all_defined_bar_copy", has_defined_all_indirection.all_defined_bar_copy, "all_defined_bar_copy", globals()) raise Exception("Did not get expected AttributeError") except AttributeError as e: if "all_defined_bar_copy" in str(e): From 8eaaf8e3e5aa7e24bacae7ad9df3d7727d37564e Mon Sep 17 00:00:00 2001 From: Rasmus Wriedt Larsen Date: Wed, 22 Feb 2023 15:42:28 +0100 Subject: [PATCH 214/631] Python: Ignore `trace.py` in `ModuleExport.ql` test I guess we could have done this at the very start of introducing this test in this PR, but I think the last commit was mostly inspired from looking at all the things that evidently was re-exported from the trace import, even when I knew they were not available because of the `__all__` definition. --- .../import-resolution/ModuleExport.expected | 86 ------------------- .../import-resolution/ModuleExport.ql | 3 +- 2 files changed, 2 insertions(+), 87 deletions(-) diff --git a/python/ql/test/experimental/import-resolution/ModuleExport.expected b/python/ql/test/experimental/import-resolution/ModuleExport.expected index 341a58e4d34..ebe5e897444 100644 --- a/python/ql/test/experimental/import-resolution/ModuleExport.expected +++ b/python/ql/test/experimental/import-resolution/ModuleExport.expected @@ -1,98 +1,51 @@ | attr_clash.__init__ | __file__ | attr_clash/__init__.py:2:7:2:14 | ControlFlowNode for __file__ | | attr_clash.__init__ | __file__ | attr_clash/__init__.py:6:6:6:13 | ControlFlowNode for __file__ | -| attr_clash.__init__ | check | trace.py:26:1:26:61 | ControlFlowNode for FunctionExpr | | attr_clash.__init__ | clashing_attr | attr_clash/__init__.py:4:17:4:31 | ControlFlowNode for Str | -| attr_clash.__init__ | enter | trace.py:11:1:11:21 | ControlFlowNode for FunctionExpr | -| attr_clash.__init__ | exit | trace.py:16:1:16:20 | ControlFlowNode for FunctionExpr | -| attr_clash.__init__ | status | trace.py:23:1:23:13 | ControlFlowNode for FunctionExpr | | attr_clash.clashing_attr | __file__ | attr_clash/clashing_attr.py:2:7:2:14 | ControlFlowNode for __file__ | | attr_clash.clashing_attr | __file__ | attr_clash/clashing_attr.py:4:6:4:13 | ControlFlowNode for __file__ | -| attr_clash.clashing_attr | check | trace.py:26:1:26:61 | ControlFlowNode for FunctionExpr | -| attr_clash.clashing_attr | enter | trace.py:11:1:11:21 | ControlFlowNode for FunctionExpr | -| attr_clash.clashing_attr | exit | trace.py:16:1:16:20 | ControlFlowNode for FunctionExpr | -| attr_clash.clashing_attr | status | trace.py:23:1:23:13 | ControlFlowNode for FunctionExpr | | attr_clash.non_clashing_submodule | __file__ | attr_clash/non_clashing_submodule.py:2:7:2:14 | ControlFlowNode for __file__ | | attr_clash.non_clashing_submodule | __file__ | attr_clash/non_clashing_submodule.py:4:6:4:13 | ControlFlowNode for __file__ | -| attr_clash.non_clashing_submodule | check | trace.py:26:1:26:61 | ControlFlowNode for FunctionExpr | -| attr_clash.non_clashing_submodule | enter | trace.py:11:1:11:21 | ControlFlowNode for FunctionExpr | -| attr_clash.non_clashing_submodule | exit | trace.py:16:1:16:20 | ControlFlowNode for FunctionExpr | -| attr_clash.non_clashing_submodule | status | trace.py:23:1:23:13 | ControlFlowNode for FunctionExpr | | bar | __file__ | bar.py:2:7:2:14 | ControlFlowNode for __file__ | | bar | __file__ | bar.py:6:6:6:13 | ControlFlowNode for __file__ | | bar | bar_attr | bar.py:4:12:4:21 | ControlFlowNode for Str | -| bar | check | trace.py:26:1:26:61 | ControlFlowNode for FunctionExpr | -| bar | enter | trace.py:11:1:11:21 | ControlFlowNode for FunctionExpr | -| bar | exit | trace.py:16:1:16:20 | ControlFlowNode for FunctionExpr | -| bar | status | trace.py:23:1:23:13 | ControlFlowNode for FunctionExpr | | baz | __file__ | baz.py:2:7:2:14 | ControlFlowNode for __file__ | | baz | __file__ | baz.py:6:6:6:13 | ControlFlowNode for __file__ | | baz | baz_attr | baz.py:4:12:4:21 | ControlFlowNode for Str | -| baz | check | trace.py:26:1:26:61 | ControlFlowNode for FunctionExpr | -| baz | enter | trace.py:11:1:11:21 | ControlFlowNode for FunctionExpr | -| baz | exit | trace.py:16:1:16:20 | ControlFlowNode for FunctionExpr | -| baz | status | trace.py:23:1:23:13 | ControlFlowNode for FunctionExpr | | foo | __file__ | foo.py:2:7:2:14 | ControlFlowNode for __file__ | | foo | __file__ | foo.py:14:6:14:13 | ControlFlowNode for __file__ | | foo | __private_foo_attr | foo.py:8:22:8:41 | ControlFlowNode for Str | | foo | bar_reexported | foo.py:11:8:11:10 | ControlFlowNode for ImportExpr | -| foo | check | trace.py:26:1:26:61 | ControlFlowNode for FunctionExpr | -| foo | enter | trace.py:11:1:11:21 | ControlFlowNode for FunctionExpr | -| foo | exit | trace.py:16:1:16:20 | ControlFlowNode for FunctionExpr | | foo | foo_attr | foo.py:5:12:5:21 | ControlFlowNode for Str | -| foo | status | trace.py:23:1:23:13 | ControlFlowNode for FunctionExpr | | has_defined_all | __all__ | has_defined_all.py:7:11:7:29 | ControlFlowNode for List | | has_defined_all | __file__ | has_defined_all.py:2:7:2:14 | ControlFlowNode for __file__ | | has_defined_all | __file__ | has_defined_all.py:9:6:9:13 | ControlFlowNode for __file__ | | has_defined_all | all_defined_bar | has_defined_all.py:5:19:5:35 | ControlFlowNode for Str | | has_defined_all | all_defined_foo | has_defined_all.py:4:19:4:35 | ControlFlowNode for Str | -| has_defined_all | check | trace.py:26:1:26:61 | ControlFlowNode for FunctionExpr | -| has_defined_all | enter | trace.py:11:1:11:21 | ControlFlowNode for FunctionExpr | -| has_defined_all | exit | trace.py:16:1:16:20 | ControlFlowNode for FunctionExpr | -| has_defined_all | status | trace.py:23:1:23:13 | ControlFlowNode for FunctionExpr | | has_defined_all_copy | __all__ | has_defined_all_copy.py:9:11:9:34 | ControlFlowNode for List | | has_defined_all_copy | __file__ | has_defined_all_copy.py:4:7:4:14 | ControlFlowNode for __file__ | | has_defined_all_copy | __file__ | has_defined_all_copy.py:11:6:11:13 | ControlFlowNode for __file__ | | has_defined_all_copy | all_defined_bar_copy | has_defined_all_copy.py:7:24:7:45 | ControlFlowNode for Str | | has_defined_all_copy | all_defined_foo_copy | has_defined_all_copy.py:6:24:6:45 | ControlFlowNode for Str | -| has_defined_all_copy | check | trace.py:26:1:26:61 | ControlFlowNode for FunctionExpr | -| has_defined_all_copy | enter | trace.py:11:1:11:21 | ControlFlowNode for FunctionExpr | -| has_defined_all_copy | exit | trace.py:16:1:16:20 | ControlFlowNode for FunctionExpr | -| has_defined_all_copy | status | trace.py:23:1:23:13 | ControlFlowNode for FunctionExpr | | has_defined_all_indirection | __file__ | has_defined_all_indirection.py:2:7:2:14 | ControlFlowNode for __file__ | | has_defined_all_indirection | __file__ | has_defined_all_indirection.py:6:6:6:13 | ControlFlowNode for __file__ | | has_defined_all_indirection | all_defined_foo_copy | has_defined_all_copy.py:6:24:6:45 | ControlFlowNode for Str | -| has_defined_all_indirection | check | trace.py:26:1:26:61 | ControlFlowNode for FunctionExpr | -| has_defined_all_indirection | enter | trace.py:11:1:11:21 | ControlFlowNode for FunctionExpr | -| has_defined_all_indirection | exit | trace.py:16:1:16:20 | ControlFlowNode for FunctionExpr | -| has_defined_all_indirection | status | trace.py:23:1:23:13 | ControlFlowNode for FunctionExpr | | if_then_else | __file__ | if_then_else.py:2:7:2:14 | ControlFlowNode for __file__ | | if_then_else | __file__ | if_then_else.py:16:6:16:13 | ControlFlowNode for __file__ | -| if_then_else | check | trace.py:26:1:26:61 | ControlFlowNode for FunctionExpr | -| if_then_else | enter | trace.py:11:1:11:21 | ControlFlowNode for FunctionExpr | -| if_then_else | exit | trace.py:16:1:16:20 | ControlFlowNode for FunctionExpr | | if_then_else | if_then_else_defined | if_then_else.py:7:28:7:39 | ControlFlowNode for Str | | if_then_else | if_then_else_defined | if_then_else.py:12:32:12:47 | ControlFlowNode for Str | | if_then_else | if_then_else_defined | if_then_else.py:14:32:14:47 | ControlFlowNode for Str | -| if_then_else | status | trace.py:23:1:23:13 | ControlFlowNode for FunctionExpr | | if_then_else_refined | SOURCE | if_then_else_refined.py:6:1:6:15 | ControlFlowNode for ClassExpr | | if_then_else_refined | __file__ | if_then_else_refined.py:4:7:4:14 | ControlFlowNode for __file__ | | if_then_else_refined | __file__ | if_then_else_refined.py:19:6:19:13 | ControlFlowNode for __file__ | -| if_then_else_refined | check | trace.py:26:1:26:61 | ControlFlowNode for FunctionExpr | -| if_then_else_refined | enter | trace.py:11:1:11:21 | ControlFlowNode for FunctionExpr | -| if_then_else_refined | exit | trace.py:16:1:16:20 | ControlFlowNode for FunctionExpr | | if_then_else_refined | src | if_then_else_refined.py:11:11:11:16 | ControlFlowNode for SOURCE | | if_then_else_refined | src | if_then_else_refined.py:13:11:13:16 | ControlFlowNode for SOURCE | -| if_then_else_refined | status | trace.py:23:1:23:13 | ControlFlowNode for FunctionExpr | | main | __file__ | main.py:24:7:24:14 | ControlFlowNode for __file__ | | main | __file__ | main.py:149:6:149:13 | ControlFlowNode for __file__ | | main | aliased_subpackage | main.py:54:21:54:52 | ControlFlowNode for ImportMember | | main | aliased_subpackage | main.py:65:8:65:25 | ControlFlowNode for ImportExpr | | main | all_defined_foo | has_defined_all.py:4:19:4:35 | ControlFlowNode for Str | | main | bar_attr | main.py:42:17:42:24 | ControlFlowNode for ImportMember | -| main | check | trace.py:26:1:26:61 | ControlFlowNode for FunctionExpr | | main | clashing_attr | main.py:83:24:83:36 | ControlFlowNode for ImportMember | -| main | enter | trace.py:11:1:11:21 | ControlFlowNode for FunctionExpr | -| main | exit | trace.py:16:1:16:20 | ControlFlowNode for FunctionExpr | | main | foo | main.py:27:8:27:10 | ControlFlowNode for ImportExpr | | main | foo_alias | main.py:34:8:34:10 | ControlFlowNode for ImportExpr | | main | has_defined_all | main.py:100:8:100:22 | ControlFlowNode for ImportExpr | @@ -108,73 +61,34 @@ | main | print_function | main.py:21:24:21:37 | ControlFlowNode for ImportMember | | main | refined | main.py:139:8:139:14 | ControlFlowNode for ImportExpr | | main | simplistic_reexport | main.py:145:8:145:26 | ControlFlowNode for ImportExpr | -| main | status | trace.py:23:1:23:13 | ControlFlowNode for FunctionExpr | | main | subpackage2_attr | package/subpackage2/__init__.py:4:20:4:37 | ControlFlowNode for Str | | main | subpackage_attr | main.py:46:32:46:46 | ControlFlowNode for ImportMember | | main | sys | main.py:22:8:22:10 | ControlFlowNode for ImportExpr | | namespace_package.namespace_module | __file__ | namespace_package/namespace_module.py:2:7:2:14 | ControlFlowNode for __file__ | | namespace_package.namespace_module | __file__ | namespace_package/namespace_module.py:6:6:6:13 | ControlFlowNode for __file__ | -| namespace_package.namespace_module | check | trace.py:26:1:26:61 | ControlFlowNode for FunctionExpr | -| namespace_package.namespace_module | enter | trace.py:11:1:11:21 | ControlFlowNode for FunctionExpr | -| namespace_package.namespace_module | exit | trace.py:16:1:16:20 | ControlFlowNode for FunctionExpr | | namespace_package.namespace_module | namespace_module_attr | namespace_package/namespace_module.py:4:25:4:47 | ControlFlowNode for Str | -| namespace_package.namespace_module | status | trace.py:23:1:23:13 | ControlFlowNode for FunctionExpr | | package.__init__ | __file__ | package/__init__.py:2:7:2:14 | ControlFlowNode for __file__ | | package.__init__ | __file__ | package/__init__.py:7:6:7:13 | ControlFlowNode for __file__ | | package.__init__ | attr_used_in_subpackage | package/__init__.py:4:27:4:51 | ControlFlowNode for Str | -| package.__init__ | check | trace.py:26:1:26:61 | ControlFlowNode for FunctionExpr | -| package.__init__ | enter | trace.py:11:1:11:21 | ControlFlowNode for FunctionExpr | -| package.__init__ | exit | trace.py:16:1:16:20 | ControlFlowNode for FunctionExpr | | package.__init__ | package_attr | package/__init__.py:5:16:5:29 | ControlFlowNode for Str | -| package.__init__ | status | trace.py:23:1:23:13 | ControlFlowNode for FunctionExpr | | package.subpackage2.__init__ | __file__ | package/subpackage2/__init__.py:2:7:2:14 | ControlFlowNode for __file__ | | package.subpackage2.__init__ | __file__ | package/subpackage2/__init__.py:6:6:6:13 | ControlFlowNode for __file__ | -| package.subpackage2.__init__ | check | trace.py:26:1:26:61 | ControlFlowNode for FunctionExpr | -| package.subpackage2.__init__ | enter | trace.py:11:1:11:21 | ControlFlowNode for FunctionExpr | -| package.subpackage2.__init__ | exit | trace.py:16:1:16:20 | ControlFlowNode for FunctionExpr | -| package.subpackage2.__init__ | status | trace.py:23:1:23:13 | ControlFlowNode for FunctionExpr | | package.subpackage2.__init__ | subpackage2_attr | package/subpackage2/__init__.py:4:20:4:37 | ControlFlowNode for Str | | package.subpackage.__init__ | __file__ | package/subpackage/__init__.py:2:7:2:14 | ControlFlowNode for __file__ | | package.subpackage.__init__ | __file__ | package/subpackage/__init__.py:14:6:14:13 | ControlFlowNode for __file__ | -| package.subpackage.__init__ | check | trace.py:26:1:26:61 | ControlFlowNode for FunctionExpr | -| package.subpackage.__init__ | enter | trace.py:11:1:11:21 | ControlFlowNode for FunctionExpr | -| package.subpackage.__init__ | exit | trace.py:16:1:16:20 | ControlFlowNode for FunctionExpr | | package.subpackage.__init__ | imported_attr | package/subpackage/__init__.py:7:16:7:55 | ControlFlowNode for ImportMember | | package.subpackage.__init__ | irrelevant_attr | package/subpackage/__init__.py:11:24:11:38 | ControlFlowNode for ImportMember | -| package.subpackage.__init__ | status | trace.py:23:1:23:13 | ControlFlowNode for FunctionExpr | | package.subpackage.__init__ | subpackage_attr | package/subpackage/__init__.py:4:19:4:35 | ControlFlowNode for Str | | package.subpackage.submodule | __file__ | package/subpackage/submodule.py:2:7:2:14 | ControlFlowNode for __file__ | | package.subpackage.submodule | __file__ | package/subpackage/submodule.py:7:6:7:13 | ControlFlowNode for __file__ | -| package.subpackage.submodule | check | trace.py:26:1:26:61 | ControlFlowNode for FunctionExpr | -| package.subpackage.submodule | enter | trace.py:11:1:11:21 | ControlFlowNode for FunctionExpr | -| package.subpackage.submodule | exit | trace.py:16:1:16:20 | ControlFlowNode for FunctionExpr | | package.subpackage.submodule | irrelevant_attr | package/subpackage/submodule.py:5:19:5:35 | ControlFlowNode for Str | -| package.subpackage.submodule | status | trace.py:23:1:23:13 | ControlFlowNode for FunctionExpr | | package.subpackage.submodule | submodule_attr | package/subpackage/submodule.py:4:18:4:33 | ControlFlowNode for Str | | refined | SOURCE | refined.py:4:1:4:21 | ControlFlowNode for ClassExpr | | refined | __file__ | refined.py:2:7:2:14 | ControlFlowNode for __file__ | | refined | __file__ | refined.py:14:6:14:13 | ControlFlowNode for __file__ | -| refined | check | trace.py:26:1:26:61 | ControlFlowNode for FunctionExpr | -| refined | enter | trace.py:11:1:11:21 | ControlFlowNode for FunctionExpr | -| refined | exit | trace.py:16:1:16:20 | ControlFlowNode for FunctionExpr | -| refined | status | trace.py:23:1:23:13 | ControlFlowNode for FunctionExpr | | simplistic_reexport | __file__ | simplistic_reexport.py:4:7:4:14 | ControlFlowNode for __file__ | | simplistic_reexport | __file__ | simplistic_reexport.py:19:6:19:13 | ControlFlowNode for __file__ | | simplistic_reexport | bar_attr | simplistic_reexport.py:6:17:6:24 | ControlFlowNode for ImportMember | | simplistic_reexport | bar_attr | simplistic_reexport.py:9:12:9:24 | ControlFlowNode for Str | | simplistic_reexport | baz_attr | baz.py:4:12:4:21 | ControlFlowNode for Str | | simplistic_reexport | baz_attr | simplistic_reexport.py:16:12:16:24 | ControlFlowNode for Str | -| simplistic_reexport | check | trace.py:26:1:26:61 | ControlFlowNode for FunctionExpr | -| simplistic_reexport | enter | trace.py:11:1:11:21 | ControlFlowNode for FunctionExpr | -| simplistic_reexport | exit | trace.py:16:1:16:20 | ControlFlowNode for FunctionExpr | -| simplistic_reexport | status | trace.py:23:1:23:13 | ControlFlowNode for FunctionExpr | -| trace | __all__ | trace.py:52:11:52:46 | ControlFlowNode for List | -| trace | _indent_level | trace.py:3:17:3:17 | ControlFlowNode for IntegerLiteral | -| trace | _print | trace.py:5:10:5:14 | ControlFlowNode for print | -| trace | _status | trace.py:21:11:21:11 | ControlFlowNode for IntegerLiteral | -| trace | check | trace.py:26:1:26:61 | ControlFlowNode for FunctionExpr | -| trace | enter | trace.py:11:1:11:21 | ControlFlowNode for FunctionExpr | -| trace | exit | trace.py:16:1:16:20 | ControlFlowNode for FunctionExpr | -| trace | print | trace.py:7:1:7:27 | ControlFlowNode for FunctionExpr | -| trace | print_function | trace.py:1:24:1:37 | ControlFlowNode for ImportMember | -| trace | status | trace.py:23:1:23:13 | ControlFlowNode for FunctionExpr | diff --git a/python/ql/test/experimental/import-resolution/ModuleExport.ql b/python/ql/test/experimental/import-resolution/ModuleExport.ql index 9d45b0ec8d0..c4f0f7af7d8 100644 --- a/python/ql/test/experimental/import-resolution/ModuleExport.ql +++ b/python/ql/test/experimental/import-resolution/ModuleExport.ql @@ -5,5 +5,6 @@ import semmle.python.dataflow.new.internal.ImportResolution from Module m, string name, DataFlow::Node defn where ImportResolution::module_export(m, name, defn) and - exists(m.getLocation().getFile().getRelativePath()) + exists(m.getLocation().getFile().getRelativePath()) and + not defn.getScope() = any(Module trace | trace.getName() = "trace") select m.getName(), name, defn From 321a4b4ef20111f6962f231ee66b8a8c4e52a08e Mon Sep 17 00:00:00 2001 From: Rasmus Wriedt Larsen Date: Wed, 22 Feb 2023 16:32:53 +0100 Subject: [PATCH 215/631] Python: `ModuleExport.ql` test: ignore `main.py` It's not very useful to look at, and it's a mess when you change any tests to see all the changes lines in the expected output that you really do not care about! --- .../import-resolution/ModuleExport.expected | 25 ------------------- .../import-resolution/ModuleExport.ql | 3 ++- 2 files changed, 2 insertions(+), 26 deletions(-) diff --git a/python/ql/test/experimental/import-resolution/ModuleExport.expected b/python/ql/test/experimental/import-resolution/ModuleExport.expected index ebe5e897444..c1a1a6d2c35 100644 --- a/python/ql/test/experimental/import-resolution/ModuleExport.expected +++ b/python/ql/test/experimental/import-resolution/ModuleExport.expected @@ -39,31 +39,6 @@ | if_then_else_refined | __file__ | if_then_else_refined.py:19:6:19:13 | ControlFlowNode for __file__ | | if_then_else_refined | src | if_then_else_refined.py:11:11:11:16 | ControlFlowNode for SOURCE | | if_then_else_refined | src | if_then_else_refined.py:13:11:13:16 | ControlFlowNode for SOURCE | -| main | __file__ | main.py:24:7:24:14 | ControlFlowNode for __file__ | -| main | __file__ | main.py:149:6:149:13 | ControlFlowNode for __file__ | -| main | aliased_subpackage | main.py:54:21:54:52 | ControlFlowNode for ImportMember | -| main | aliased_subpackage | main.py:65:8:65:25 | ControlFlowNode for ImportExpr | -| main | all_defined_foo | has_defined_all.py:4:19:4:35 | ControlFlowNode for Str | -| main | bar_attr | main.py:42:17:42:24 | ControlFlowNode for ImportMember | -| main | clashing_attr | main.py:83:24:83:36 | ControlFlowNode for ImportMember | -| main | foo | main.py:27:8:27:10 | ControlFlowNode for ImportExpr | -| main | foo_alias | main.py:34:8:34:10 | ControlFlowNode for ImportExpr | -| main | has_defined_all | main.py:100:8:100:22 | ControlFlowNode for ImportExpr | -| main | has_defined_all_indirection | main.py:118:8:118:34 | ControlFlowNode for ImportExpr | -| main | if_then_else_defined | main.py:135:26:135:45 | ControlFlowNode for ImportMember | -| main | if_then_else_refined | main.py:142:8:142:27 | ControlFlowNode for ImportExpr | -| main | local_import | main.py:57:1:57:19 | ControlFlowNode for FunctionExpr | -| main | namespace_module_attr | main.py:79:52:79:72 | ControlFlowNode for ImportMember | -| main | non_clashing_submodule | main.py:83:39:83:60 | ControlFlowNode for ImportMember | -| main | package | main.py:69:8:69:25 | ControlFlowNode for ImportExpr | -| main | package | main.py:73:8:73:35 | ControlFlowNode for ImportExpr | -| main | package_attr_alias | main.py:50:21:50:54 | ControlFlowNode for ImportMember | -| main | print_function | main.py:21:24:21:37 | ControlFlowNode for ImportMember | -| main | refined | main.py:139:8:139:14 | ControlFlowNode for ImportExpr | -| main | simplistic_reexport | main.py:145:8:145:26 | ControlFlowNode for ImportExpr | -| main | subpackage2_attr | package/subpackage2/__init__.py:4:20:4:37 | ControlFlowNode for Str | -| main | subpackage_attr | main.py:46:32:46:46 | ControlFlowNode for ImportMember | -| main | sys | main.py:22:8:22:10 | ControlFlowNode for ImportExpr | | namespace_package.namespace_module | __file__ | namespace_package/namespace_module.py:2:7:2:14 | ControlFlowNode for __file__ | | namespace_package.namespace_module | __file__ | namespace_package/namespace_module.py:6:6:6:13 | ControlFlowNode for __file__ | | namespace_package.namespace_module | namespace_module_attr | namespace_package/namespace_module.py:4:25:4:47 | ControlFlowNode for Str | diff --git a/python/ql/test/experimental/import-resolution/ModuleExport.ql b/python/ql/test/experimental/import-resolution/ModuleExport.ql index c4f0f7af7d8..4b84527573e 100644 --- a/python/ql/test/experimental/import-resolution/ModuleExport.ql +++ b/python/ql/test/experimental/import-resolution/ModuleExport.ql @@ -6,5 +6,6 @@ from Module m, string name, DataFlow::Node defn where ImportResolution::module_export(m, name, defn) and exists(m.getLocation().getFile().getRelativePath()) and - not defn.getScope() = any(Module trace | trace.getName() = "trace") + not defn.getScope() = any(Module trace | trace.getName() = "trace") and + not m.getName() = "main" select m.getName(), name, defn From bea0acb497f4ac9426c17508380f1b7bfea393ef Mon Sep 17 00:00:00 2001 From: Rasmus Wriedt Larsen Date: Thu, 23 Feb 2023 00:22:01 +0100 Subject: [PATCH 216/631] Python: Add barrier test to import resolution Just like the one added for `py/insecure-protocol` in fb425b7, but instead added in the import-resolution tests, such that we don't have to remember it's in a completely different directory. --- .../import-resolution/ModuleExport.expected | 3 +++ .../import-resolution/block_flow_check.py | 14 ++++++++++++++ .../experimental/import-resolution/importflow.ql | 4 ++++ .../ql/test/experimental/import-resolution/main.py | 4 ++++ 4 files changed, 25 insertions(+) create mode 100644 python/ql/test/experimental/import-resolution/block_flow_check.py diff --git a/python/ql/test/experimental/import-resolution/ModuleExport.expected b/python/ql/test/experimental/import-resolution/ModuleExport.expected index c1a1a6d2c35..abfa29d0f58 100644 --- a/python/ql/test/experimental/import-resolution/ModuleExport.expected +++ b/python/ql/test/experimental/import-resolution/ModuleExport.expected @@ -11,6 +11,9 @@ | baz | __file__ | baz.py:2:7:2:14 | ControlFlowNode for __file__ | | baz | __file__ | baz.py:6:6:6:13 | ControlFlowNode for __file__ | | baz | baz_attr | baz.py:4:12:4:21 | ControlFlowNode for Str | +| block_flow_check | SOURCE | block_flow_check.py:4:1:4:21 | ControlFlowNode for ClassExpr | +| block_flow_check | __file__ | block_flow_check.py:2:7:2:14 | ControlFlowNode for __file__ | +| block_flow_check | __file__ | block_flow_check.py:14:6:14:13 | ControlFlowNode for __file__ | | foo | __file__ | foo.py:2:7:2:14 | ControlFlowNode for __file__ | | foo | __file__ | foo.py:14:6:14:13 | ControlFlowNode for __file__ | | foo | __private_foo_attr | foo.py:8:22:8:41 | ControlFlowNode for Str | diff --git a/python/ql/test/experimental/import-resolution/block_flow_check.py b/python/ql/test/experimental/import-resolution/block_flow_check.py new file mode 100644 index 00000000000..cd939b037e6 --- /dev/null +++ b/python/ql/test/experimental/import-resolution/block_flow_check.py @@ -0,0 +1,14 @@ +from trace import * +enter(__file__) + +class SOURCE(object): + @staticmethod + def block_flow(): pass + +check("SOURCE", SOURCE, SOURCE, globals()) #$ prints=SOURCE + +SOURCE.block_flow() + +check("SOURCE", SOURCE, SOURCE, globals()) + +exit(__file__) diff --git a/python/ql/test/experimental/import-resolution/importflow.ql b/python/ql/test/experimental/import-resolution/importflow.ql index 94f5e4b0ec8..afb2278d1c5 100644 --- a/python/ql/test/experimental/import-resolution/importflow.ql +++ b/python/ql/test/experimental/import-resolution/importflow.ql @@ -66,6 +66,10 @@ private class ImportConfiguration extends DataFlow::Configuration { override predicate isSink(DataFlow::Node sink) { sink = API::moduleImport("trace").getMember("check").getACall().getArg(1) } + + override predicate isBarrier(DataFlow::Node node) { + exists(DataFlow::MethodCallNode call | call.calls(node, "block_flow")) + } } class ResolutionTest extends InlineExpectationsTest { diff --git a/python/ql/test/experimental/import-resolution/main.py b/python/ql/test/experimental/import-resolution/main.py index 98b97fafb0e..31a4f60d56d 100644 --- a/python/ql/test/experimental/import-resolution/main.py +++ b/python/ql/test/experimental/import-resolution/main.py @@ -146,6 +146,10 @@ import simplistic_reexport # $ imports=simplistic_reexport as=simplistic_reexpor check("simplistic_reexport.bar_attr", simplistic_reexport.bar_attr, "overwritten", globals()) #$ prints=overwritten SPURIOUS: prints=bar_attr check("simplistic_reexport.baz_attr", simplistic_reexport.baz_attr, "overwritten", globals()) #$ prints=overwritten SPURIOUS: prints=baz_attr +# check that we don't treat all assignments as being exports +import block_flow_check #$ imports=block_flow_check as=block_flow_check +check("block_flow_check.SOURCE", block_flow_check.SOURCE, block_flow_check.SOURCE, globals()) #$ SPURIOUS: prints=SOURCE + exit(__file__) print() From 97fefd2545d64dc07eeda5081804999c8cff0af9 Mon Sep 17 00:00:00 2001 From: Rasmus Wriedt Larsen Date: Wed, 22 Feb 2023 16:04:03 +0100 Subject: [PATCH 217/631] Python: Attempt to fix import flow It's nice that it fixes the `InsecureProtocol` test-case (which maybe should have been a test-case for the import resolution library in the first place?) But it's not quite right: 1. it adds spurious flow for `clashing_attr` 2. it runs into huge problems for typetracking_imports/tracked.expected 3. it runs into the problem for https://github.com/github/codeql/pull/10176 with an `from import *` blocking flow from previously defined variable, that is NOT overridden. (simplistic_reexport.bar_attr) --- .../new/internal/ImportResolution.qll | 59 ++++-- .../typetracking_imports/tracked.expected | 19 ++ .../import-resolution/ModuleExport.expected | 194 ++++++++++++------ .../experimental/import-resolution/main.py | 6 +- .../InsecureProtocol.expected | 3 - 5 files changed, 192 insertions(+), 89 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 5e0192b1553..5090ba8fcd3 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/ImportResolution.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/ImportResolution.qll @@ -78,34 +78,63 @@ 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`). + * Holds if the module `m` defines a name `name` with the value `val`. The value + * represents the value `name` will have at the end of the module (the last place we + * have def-use flow to). + * + * Note: The handling of re-exporting imports is a bit simplistic. We assume that if + * an import is made, it will be re-exported (which will not be the case if a new + * value is assigned to the name, or it is deleted). */ pragma[nomagic] - predicate module_export(Module m, string name, DataFlow::CfgNode defn) { - exists(EssaVariable v, EssaDefinition essaDef | - v.getName() = name and - v.getAUse() = m.getANormalExit() and - allowedEssaImportStep*(essaDef, v.getDefinition()) + predicate module_export(Module m, string name, DataFlow::Node val) { + // Definitions made inside `m` itself + // + // for code such as `foo = ...; foo.bar = ...` there will be TWO + // EssaDefinition/EssaVariable. One for `foo = ...` (AssignmentDefinition) and one + // for `foo.bar = ...`. The one for `foo.bar = ...` (EssaNodeRefinement). The + // EssaNodeRefinement is the one that will reach the end of the module (normal + // exit). + // + // However, we cannot just use the EssaNodeRefinement as the `val`, because the + // normal data-flow depends on use-use flow, and use-use flow targets CFG nodes not + // EssaNodes. So we need to go back from the EssaDefinition/EssaVariable that + // reaches the end of the module, to the first definition of the variable, and then + // track forwards using use-use flow to find a suitable CFG node that has flow into + // it from use-use flow. + exists(EssaVariable lastUseVar, EssaVariable firstDef | + lastUseVar.getName() = name and + // we ignore special variable $ introduced by our analysis (not used for anything) + // we ignore special variable * introduced by `from import *` -- TODO: understand why we even have this? + not name in ["$", "*"] and + lastUseVar.getAUse() = m.getANormalExit() and + allowedEssaImportStep*(firstDef, lastUseVar) and + not allowedEssaImportStep(_, firstDef) | - defn.getNode() = essaDef.(AssignmentDefinition).getValue() + not EssaFlow::defToFirstUse(firstDef, _) and + val.asVar() = firstDef or - defn.getNode() = essaDef.(ArgumentRefinement).getArgument() + exists(ControlFlowNode mid, ControlFlowNode end | + EssaFlow::defToFirstUse(firstDef, mid) and + EssaFlow::useToNextUse*(mid, end) and + not EssaFlow::useToNextUse(end, _) and + lastUseVar.getAUse() = end and + val.asCfgNode() = end + ) ) or - // `from import *` + // re-exports from `from import *` exists(Module importedFrom | importedFrom = ImportStar::getStarImported(m) and - module_export(importedFrom, name, defn) and + module_export(importedFrom, name, val) and potential_module_export(importedFrom, name) ) or - // `import ` or `from import ` + // re-exports from `import ` or `from import ` exists(Alias a | - defn.asExpr() = a.getValue() and + val.asExpr() = a.getValue() and a.getAsname().(Name).getId() = name and - defn.getScope() = m + val.getScope() = m ) } diff --git a/python/ql/test/experimental/dataflow/typetracking_imports/tracked.expected b/python/ql/test/experimental/dataflow/typetracking_imports/tracked.expected index e69de29bb2d..546325a8645 100644 --- a/python/ql/test/experimental/dataflow/typetracking_imports/tracked.expected +++ b/python/ql/test/experimental/dataflow/typetracking_imports/tracked.expected @@ -0,0 +1,19 @@ +| pkg/alias_only_direct.py:1:26:1:36 | Comment # $ tracked | Missing result:tracked= | +| pkg/alias_problem.py:1:26:1:36 | Comment # $ tracked | Missing result:tracked= | +| pkg/alias_problem_fixed.py:3:26:3:36 | Comment # $ tracked | Missing result:tracked= | +| pkg/problem_absolute_import.py:1:29:1:39 | Comment # $ tracked | Missing result:tracked= | +| pkg/use.py:2:30:2:40 | Comment # $ tracked | Missing result:tracked= | +| pkg/use.py:3:16:3:26 | Comment # $ tracked | Missing result:tracked= | +| pkg/use.py:9:36:9:46 | Comment # $ tracked | Missing result:tracked= | +| pkg/use.py:10:16:10:26 | Comment # $ tracked | Missing result:tracked= | +| pkg/use.py:16:42:16:52 | Comment # $ tracked | Missing result:tracked= | +| pkg/use.py:17:16:17:26 | Comment # $ tracked | Missing result:tracked= | +| pkg/use.py:23:33:23:43 | Comment # $ tracked | Missing result:tracked= | +| pkg/use.py:24:16:24:26 | Comment # $ tracked | Missing result:tracked= | +| pkg/use.py:30:40:30:50 | Comment # $ tracked | Missing result:tracked= | +| pkg/use.py:31:16:31:26 | Comment # $ tracked | Missing result:tracked= | +| pkg/use.py:37:49:37:59 | Comment # $ tracked | Missing result:tracked= | +| pkg/use.py:38:16:38:26 | Comment # $ tracked | Missing result:tracked= | +| pkg/use.py:43:47:43:57 | Comment # $ tracked | Missing result:tracked= | +| pkg/use.py:44:16:44:26 | Comment # $ tracked | Missing result:tracked= | +| pkg/works_absolute_import.py:2:29:2:39 | Comment # $ tracked | Missing result:tracked= | diff --git a/python/ql/test/experimental/import-resolution/ModuleExport.expected b/python/ql/test/experimental/import-resolution/ModuleExport.expected index abfa29d0f58..ad2dffde65b 100644 --- a/python/ql/test/experimental/import-resolution/ModuleExport.expected +++ b/python/ql/test/experimental/import-resolution/ModuleExport.expected @@ -1,72 +1,130 @@ -| attr_clash.__init__ | __file__ | attr_clash/__init__.py:2:7:2:14 | ControlFlowNode for __file__ | -| attr_clash.__init__ | __file__ | attr_clash/__init__.py:6:6:6:13 | ControlFlowNode for __file__ | -| attr_clash.__init__ | clashing_attr | attr_clash/__init__.py:4:17:4:31 | ControlFlowNode for Str | -| attr_clash.clashing_attr | __file__ | attr_clash/clashing_attr.py:2:7:2:14 | ControlFlowNode for __file__ | -| attr_clash.clashing_attr | __file__ | attr_clash/clashing_attr.py:4:6:4:13 | ControlFlowNode for __file__ | -| attr_clash.non_clashing_submodule | __file__ | attr_clash/non_clashing_submodule.py:2:7:2:14 | ControlFlowNode for __file__ | -| attr_clash.non_clashing_submodule | __file__ | attr_clash/non_clashing_submodule.py:4:6:4:13 | ControlFlowNode for __file__ | -| bar | __file__ | bar.py:2:7:2:14 | ControlFlowNode for __file__ | -| bar | __file__ | bar.py:6:6:6:13 | ControlFlowNode for __file__ | -| bar | bar_attr | bar.py:4:12:4:21 | ControlFlowNode for Str | -| baz | __file__ | baz.py:2:7:2:14 | ControlFlowNode for __file__ | -| baz | __file__ | baz.py:6:6:6:13 | ControlFlowNode for __file__ | -| baz | baz_attr | baz.py:4:12:4:21 | ControlFlowNode for Str | -| block_flow_check | SOURCE | block_flow_check.py:4:1:4:21 | ControlFlowNode for ClassExpr | -| block_flow_check | __file__ | block_flow_check.py:2:7:2:14 | ControlFlowNode for __file__ | -| block_flow_check | __file__ | block_flow_check.py:14:6:14:13 | ControlFlowNode for __file__ | -| foo | __file__ | foo.py:2:7:2:14 | ControlFlowNode for __file__ | -| foo | __file__ | foo.py:14:6:14:13 | ControlFlowNode for __file__ | -| foo | __private_foo_attr | foo.py:8:22:8:41 | ControlFlowNode for Str | +| attr_clash.__init__ | __name__ | attr_clash/__init__.py:0:0:0:0 | GSSA Variable __name__ | +| attr_clash.__init__ | __package__ | attr_clash/__init__.py:0:0:0:0 | GSSA Variable __package__ | +| attr_clash.__init__ | clashing_attr | attr_clash/__init__.py:4:1:4:13 | GSSA Variable clashing_attr | +| attr_clash.__init__ | enter | attr_clash/__init__.py:2:1:2:5 | ControlFlowNode for enter | +| attr_clash.__init__ | exit | attr_clash/__init__.py:6:1:6:4 | ControlFlowNode for exit | +| attr_clash.clashing_attr | __name__ | attr_clash/clashing_attr.py:0:0:0:0 | GSSA Variable __name__ | +| attr_clash.clashing_attr | __package__ | attr_clash/clashing_attr.py:0:0:0:0 | GSSA Variable __package__ | +| attr_clash.clashing_attr | enter | attr_clash/clashing_attr.py:2:1:2:5 | ControlFlowNode for enter | +| attr_clash.clashing_attr | exit | attr_clash/clashing_attr.py:4:1:4:4 | ControlFlowNode for exit | +| attr_clash.non_clashing_submodule | __name__ | attr_clash/non_clashing_submodule.py:0:0:0:0 | GSSA Variable __name__ | +| attr_clash.non_clashing_submodule | __package__ | attr_clash/non_clashing_submodule.py:0:0:0:0 | GSSA Variable __package__ | +| attr_clash.non_clashing_submodule | enter | attr_clash/non_clashing_submodule.py:2:1:2:5 | ControlFlowNode for enter | +| attr_clash.non_clashing_submodule | exit | attr_clash/non_clashing_submodule.py:4:1:4:4 | ControlFlowNode for exit | +| bar | __name__ | bar.py:0:0:0:0 | GSSA Variable __name__ | +| bar | __package__ | bar.py:0:0:0:0 | GSSA Variable __package__ | +| bar | bar_attr | bar.py:4:1:4:8 | GSSA Variable bar_attr | +| bar | enter | bar.py:2:1:2:5 | ControlFlowNode for enter | +| bar | exit | bar.py:6:1:6:4 | ControlFlowNode for exit | +| baz | __name__ | baz.py:0:0:0:0 | GSSA Variable __name__ | +| baz | __package__ | baz.py:0:0:0:0 | GSSA Variable __package__ | +| baz | baz_attr | baz.py:4:1:4:8 | GSSA Variable baz_attr | +| baz | enter | baz.py:2:1:2:5 | ControlFlowNode for enter | +| baz | exit | baz.py:6:1:6:4 | ControlFlowNode for exit | +| block_flow_check | SOURCE | block_flow_check.py:12:25:12:30 | ControlFlowNode for SOURCE | +| block_flow_check | __name__ | block_flow_check.py:0:0:0:0 | GSSA Variable __name__ | +| block_flow_check | __package__ | block_flow_check.py:0:0:0:0 | GSSA Variable __package__ | +| block_flow_check | check | block_flow_check.py:12:1:12:5 | ControlFlowNode for check | +| block_flow_check | enter | block_flow_check.py:2:1:2:5 | ControlFlowNode for enter | +| block_flow_check | exit | block_flow_check.py:14:1:14:4 | ControlFlowNode for exit | +| block_flow_check | globals | block_flow_check.py:12:33:12:39 | ControlFlowNode for globals | +| block_flow_check | object | block_flow_check.py:4:14:4:19 | ControlFlowNode for object | +| block_flow_check | staticmethod | block_flow_check.py:0:0:0:0 | GSSA Variable staticmethod | +| foo | __name__ | foo.py:0:0:0:0 | GSSA Variable __name__ | +| foo | __package__ | foo.py:0:0:0:0 | GSSA Variable __package__ | +| foo | __private_foo_attr | foo.py:8:1:8:18 | GSSA Variable __private_foo_attr | | foo | bar_reexported | foo.py:11:8:11:10 | ControlFlowNode for ImportExpr | -| foo | foo_attr | foo.py:5:12:5:21 | ControlFlowNode for Str | -| has_defined_all | __all__ | has_defined_all.py:7:11:7:29 | ControlFlowNode for List | -| has_defined_all | __file__ | has_defined_all.py:2:7:2:14 | ControlFlowNode for __file__ | -| has_defined_all | __file__ | has_defined_all.py:9:6:9:13 | ControlFlowNode for __file__ | -| has_defined_all | all_defined_bar | has_defined_all.py:5:19:5:35 | ControlFlowNode for Str | -| has_defined_all | all_defined_foo | has_defined_all.py:4:19:4:35 | ControlFlowNode for Str | -| has_defined_all_copy | __all__ | has_defined_all_copy.py:9:11:9:34 | ControlFlowNode for List | -| has_defined_all_copy | __file__ | has_defined_all_copy.py:4:7:4:14 | ControlFlowNode for __file__ | -| has_defined_all_copy | __file__ | has_defined_all_copy.py:11:6:11:13 | ControlFlowNode for __file__ | -| has_defined_all_copy | all_defined_bar_copy | has_defined_all_copy.py:7:24:7:45 | ControlFlowNode for Str | -| has_defined_all_copy | all_defined_foo_copy | has_defined_all_copy.py:6:24:6:45 | ControlFlowNode for Str | -| has_defined_all_indirection | __file__ | has_defined_all_indirection.py:2:7:2:14 | ControlFlowNode for __file__ | -| has_defined_all_indirection | __file__ | has_defined_all_indirection.py:6:6:6:13 | ControlFlowNode for __file__ | -| has_defined_all_indirection | all_defined_foo_copy | has_defined_all_copy.py:6:24:6:45 | ControlFlowNode for Str | -| if_then_else | __file__ | if_then_else.py:2:7:2:14 | ControlFlowNode for __file__ | -| if_then_else | __file__ | if_then_else.py:16:6:16:13 | ControlFlowNode for __file__ | -| if_then_else | if_then_else_defined | if_then_else.py:7:28:7:39 | ControlFlowNode for Str | -| if_then_else | if_then_else_defined | if_then_else.py:12:32:12:47 | ControlFlowNode for Str | -| if_then_else | if_then_else_defined | if_then_else.py:14:32:14:47 | ControlFlowNode for Str | -| if_then_else_refined | SOURCE | if_then_else_refined.py:6:1:6:15 | ControlFlowNode for ClassExpr | -| if_then_else_refined | __file__ | if_then_else_refined.py:4:7:4:14 | ControlFlowNode for __file__ | -| if_then_else_refined | __file__ | if_then_else_refined.py:19:6:19:13 | ControlFlowNode for __file__ | -| if_then_else_refined | src | if_then_else_refined.py:11:11:11:16 | ControlFlowNode for SOURCE | -| if_then_else_refined | src | if_then_else_refined.py:13:11:13:16 | ControlFlowNode for SOURCE | -| namespace_package.namespace_module | __file__ | namespace_package/namespace_module.py:2:7:2:14 | ControlFlowNode for __file__ | -| namespace_package.namespace_module | __file__ | namespace_package/namespace_module.py:6:6:6:13 | ControlFlowNode for __file__ | -| namespace_package.namespace_module | namespace_module_attr | namespace_package/namespace_module.py:4:25:4:47 | ControlFlowNode for Str | -| package.__init__ | __file__ | package/__init__.py:2:7:2:14 | ControlFlowNode for __file__ | -| package.__init__ | __file__ | package/__init__.py:7:6:7:13 | ControlFlowNode for __file__ | -| package.__init__ | attr_used_in_subpackage | package/__init__.py:4:27:4:51 | ControlFlowNode for Str | -| package.__init__ | package_attr | package/__init__.py:5:16:5:29 | ControlFlowNode for Str | -| package.subpackage2.__init__ | __file__ | package/subpackage2/__init__.py:2:7:2:14 | ControlFlowNode for __file__ | -| package.subpackage2.__init__ | __file__ | package/subpackage2/__init__.py:6:6:6:13 | ControlFlowNode for __file__ | -| package.subpackage2.__init__ | subpackage2_attr | package/subpackage2/__init__.py:4:20:4:37 | ControlFlowNode for Str | -| package.subpackage.__init__ | __file__ | package/subpackage/__init__.py:2:7:2:14 | ControlFlowNode for __file__ | -| package.subpackage.__init__ | __file__ | package/subpackage/__init__.py:14:6:14:13 | ControlFlowNode for __file__ | +| foo | bar_reexported | foo.py:12:34:12:47 | ControlFlowNode for bar_reexported | +| foo | check | foo.py:12:1:12:5 | ControlFlowNode for check | +| foo | enter | foo.py:2:1:2:5 | ControlFlowNode for enter | +| foo | exit | foo.py:14:1:14:4 | ControlFlowNode for exit | +| foo | foo_attr | foo.py:5:1:5:8 | GSSA Variable foo_attr | +| foo | globals | foo.py:12:71:12:77 | ControlFlowNode for globals | +| has_defined_all | __all__ | has_defined_all.py:7:1:7:7 | GSSA Variable __all__ | +| has_defined_all | __name__ | has_defined_all.py:0:0:0:0 | GSSA Variable __name__ | +| has_defined_all | __package__ | has_defined_all.py:0:0:0:0 | GSSA Variable __package__ | +| has_defined_all | all_defined_bar | has_defined_all.py:5:1:5:15 | GSSA Variable all_defined_bar | +| has_defined_all | all_defined_foo | has_defined_all.py:4:1:4:15 | GSSA Variable all_defined_foo | +| has_defined_all | enter | has_defined_all.py:2:1:2:5 | ControlFlowNode for enter | +| has_defined_all | exit | has_defined_all.py:9:1:9:4 | ControlFlowNode for exit | +| has_defined_all_copy | __all__ | has_defined_all_copy.py:9:1:9:7 | GSSA Variable __all__ | +| has_defined_all_copy | __name__ | has_defined_all_copy.py:0:0:0:0 | GSSA Variable __name__ | +| has_defined_all_copy | __package__ | has_defined_all_copy.py:0:0:0:0 | GSSA Variable __package__ | +| has_defined_all_copy | all_defined_bar_copy | has_defined_all_copy.py:7:1:7:20 | GSSA Variable all_defined_bar_copy | +| has_defined_all_copy | all_defined_foo_copy | has_defined_all_copy.py:6:1:6:20 | GSSA Variable all_defined_foo_copy | +| has_defined_all_copy | enter | has_defined_all_copy.py:4:1:4:5 | ControlFlowNode for enter | +| has_defined_all_copy | exit | has_defined_all_copy.py:11:1:11:4 | ControlFlowNode for exit | +| has_defined_all_indirection | __name__ | has_defined_all_indirection.py:0:0:0:0 | GSSA Variable __name__ | +| has_defined_all_indirection | __package__ | has_defined_all_indirection.py:0:0:0:0 | GSSA Variable __package__ | +| has_defined_all_indirection | all_defined_foo_copy | has_defined_all_copy.py:6:1:6:20 | GSSA Variable all_defined_foo_copy | +| has_defined_all_indirection | exit | has_defined_all_indirection.py:6:1:6:4 | ControlFlowNode for exit | +| if_then_else | __name__ | if_then_else.py:0:0:0:0 | GSSA Variable __name__ | +| if_then_else | __package__ | if_then_else.py:0:0:0:0 | GSSA Variable __package__ | +| if_then_else | enter | if_then_else.py:2:1:2:5 | ControlFlowNode for enter | +| if_then_else | eval | if_then_else.py:11:8:11:11 | ControlFlowNode for eval | +| if_then_else | exit | if_then_else.py:16:1:16:4 | ControlFlowNode for exit | +| if_then_else | if_then_else_defined | if_then_else.py:7:5:7:24 | GSSA Variable if_then_else_defined | +| if_then_else | if_then_else_defined | if_then_else.py:12:9:12:28 | GSSA Variable if_then_else_defined | +| if_then_else | if_then_else_defined | if_then_else.py:14:9:14:28 | GSSA Variable if_then_else_defined | +| if_then_else_refined | SOURCE | if_then_else_refined.py:11:11:11:16 | ControlFlowNode for SOURCE | +| if_then_else_refined | SOURCE | if_then_else_refined.py:13:11:13:16 | ControlFlowNode for SOURCE | +| if_then_else_refined | __name__ | if_then_else_refined.py:0:0:0:0 | GSSA Variable __name__ | +| if_then_else_refined | __package__ | if_then_else_refined.py:0:0:0:0 | GSSA Variable __package__ | +| if_then_else_refined | check | if_then_else_refined.py:17:1:17:5 | ControlFlowNode for check | +| if_then_else_refined | enter | if_then_else_refined.py:4:1:4:5 | ControlFlowNode for enter | +| if_then_else_refined | eval | if_then_else_refined.py:10:4:10:7 | ControlFlowNode for eval | +| if_then_else_refined | exit | if_then_else_refined.py:19:1:19:4 | ControlFlowNode for exit | +| if_then_else_refined | globals | if_then_else_refined.py:17:24:17:30 | ControlFlowNode for globals | +| if_then_else_refined | src | if_then_else_refined.py:17:19:17:21 | ControlFlowNode for src | +| namespace_package.namespace_module | __name__ | namespace_package/namespace_module.py:0:0:0:0 | GSSA Variable __name__ | +| namespace_package.namespace_module | __package__ | namespace_package/namespace_module.py:0:0:0:0 | GSSA Variable __package__ | +| namespace_package.namespace_module | enter | namespace_package/namespace_module.py:2:1:2:5 | ControlFlowNode for enter | +| namespace_package.namespace_module | exit | namespace_package/namespace_module.py:6:1:6:4 | ControlFlowNode for exit | +| namespace_package.namespace_module | namespace_module_attr | namespace_package/namespace_module.py:4:1:4:21 | GSSA Variable namespace_module_attr | +| package.__init__ | __name__ | package/__init__.py:0:0:0:0 | GSSA Variable __name__ | +| package.__init__ | __package__ | package/__init__.py:0:0:0:0 | GSSA Variable __package__ | +| package.__init__ | attr_used_in_subpackage | package/__init__.py:4:1:4:23 | GSSA Variable attr_used_in_subpackage | +| package.__init__ | enter | package/__init__.py:2:1:2:5 | ControlFlowNode for enter | +| package.__init__ | exit | package/__init__.py:7:1:7:4 | ControlFlowNode for exit | +| package.__init__ | package_attr | package/__init__.py:5:1:5:12 | GSSA Variable package_attr | +| package.subpackage2.__init__ | __name__ | package/subpackage2/__init__.py:0:0:0:0 | GSSA Variable __name__ | +| package.subpackage2.__init__ | __package__ | package/subpackage2/__init__.py:0:0:0:0 | GSSA Variable __package__ | +| package.subpackage2.__init__ | enter | package/subpackage2/__init__.py:2:1:2:5 | ControlFlowNode for enter | +| package.subpackage2.__init__ | exit | package/subpackage2/__init__.py:6:1:6:4 | ControlFlowNode for exit | +| package.subpackage2.__init__ | subpackage2_attr | package/subpackage2/__init__.py:4:1:4:16 | GSSA Variable subpackage2_attr | +| package.subpackage.__init__ | __name__ | package/subpackage/__init__.py:0:0:0:0 | GSSA Variable __name__ | +| package.subpackage.__init__ | __package__ | package/subpackage/__init__.py:0:0:0:0 | GSSA Variable __package__ | +| package.subpackage.__init__ | check | package/subpackage/__init__.py:12:1:12:5 | ControlFlowNode for check | +| package.subpackage.__init__ | enter | package/subpackage/__init__.py:2:1:2:5 | ControlFlowNode for enter | +| package.subpackage.__init__ | exit | package/subpackage/__init__.py:14:1:14:4 | ControlFlowNode for exit | +| package.subpackage.__init__ | globals | package/subpackage/__init__.py:12:79:12:85 | ControlFlowNode for globals | | package.subpackage.__init__ | imported_attr | package/subpackage/__init__.py:7:16:7:55 | ControlFlowNode for ImportMember | +| package.subpackage.__init__ | imported_attr | package/subpackage/__init__.py:8:24:8:36 | ControlFlowNode for imported_attr | | package.subpackage.__init__ | irrelevant_attr | package/subpackage/__init__.py:11:24:11:38 | ControlFlowNode for ImportMember | -| package.subpackage.__init__ | subpackage_attr | package/subpackage/__init__.py:4:19:4:35 | ControlFlowNode for Str | -| package.subpackage.submodule | __file__ | package/subpackage/submodule.py:2:7:2:14 | ControlFlowNode for __file__ | -| package.subpackage.submodule | __file__ | package/subpackage/submodule.py:7:6:7:13 | ControlFlowNode for __file__ | -| package.subpackage.submodule | irrelevant_attr | package/subpackage/submodule.py:5:19:5:35 | ControlFlowNode for Str | -| package.subpackage.submodule | submodule_attr | package/subpackage/submodule.py:4:18:4:33 | ControlFlowNode for Str | -| refined | SOURCE | refined.py:4:1:4:21 | ControlFlowNode for ClassExpr | -| refined | __file__ | refined.py:2:7:2:14 | ControlFlowNode for __file__ | -| refined | __file__ | refined.py:14:6:14:13 | ControlFlowNode for __file__ | -| simplistic_reexport | __file__ | simplistic_reexport.py:4:7:4:14 | ControlFlowNode for __file__ | -| simplistic_reexport | __file__ | simplistic_reexport.py:19:6:19:13 | ControlFlowNode for __file__ | +| package.subpackage.__init__ | irrelevant_attr | package/subpackage/__init__.py:11:24:11:38 | GSSA Variable irrelevant_attr | +| package.subpackage.__init__ | submodule | package/subpackage/__init__.py:12:35:12:43 | ControlFlowNode for submodule | +| package.subpackage.__init__ | subpackage_attr | package/subpackage/__init__.py:4:1:4:15 | GSSA Variable subpackage_attr | +| package.subpackage.submodule | __name__ | package/subpackage/submodule.py:0:0:0:0 | GSSA Variable __name__ | +| package.subpackage.submodule | __package__ | package/subpackage/submodule.py:0:0:0:0 | GSSA Variable __package__ | +| package.subpackage.submodule | enter | package/subpackage/submodule.py:2:1:2:5 | ControlFlowNode for enter | +| package.subpackage.submodule | exit | package/subpackage/submodule.py:7:1:7:4 | ControlFlowNode for exit | +| package.subpackage.submodule | irrelevant_attr | package/subpackage/submodule.py:5:1:5:15 | GSSA Variable irrelevant_attr | +| package.subpackage.submodule | submodule_attr | package/subpackage/submodule.py:4:1:4:14 | GSSA Variable submodule_attr | +| refined | SOURCE | refined.py:12:25:12:30 | ControlFlowNode for SOURCE | +| refined | __name__ | refined.py:0:0:0:0 | GSSA Variable __name__ | +| refined | __package__ | refined.py:0:0:0:0 | GSSA Variable __package__ | +| refined | check | refined.py:12:1:12:5 | ControlFlowNode for check | +| refined | enter | refined.py:2:1:2:5 | ControlFlowNode for enter | +| refined | exit | refined.py:14:1:14:4 | ControlFlowNode for exit | +| refined | globals | refined.py:12:33:12:39 | ControlFlowNode for globals | +| refined | object | refined.py:4:14:4:19 | ControlFlowNode for object | +| simplistic_reexport | __name__ | simplistic_reexport.py:0:0:0:0 | GSSA Variable __name__ | +| simplistic_reexport | __package__ | simplistic_reexport.py:0:0:0:0 | GSSA Variable __package__ | | simplistic_reexport | bar_attr | simplistic_reexport.py:6:17:6:24 | ControlFlowNode for ImportMember | -| simplistic_reexport | bar_attr | simplistic_reexport.py:9:12:9:24 | ControlFlowNode for Str | -| simplistic_reexport | baz_attr | baz.py:4:12:4:21 | ControlFlowNode for Str | -| simplistic_reexport | baz_attr | simplistic_reexport.py:16:12:16:24 | ControlFlowNode for Str | +| simplistic_reexport | baz_attr | baz.py:4:1:4:8 | GSSA Variable baz_attr | +| simplistic_reexport | baz_attr | simplistic_reexport.py:17:19:17:26 | ControlFlowNode for baz_attr | +| simplistic_reexport | check | simplistic_reexport.py:17:1:17:5 | ControlFlowNode for check | +| simplistic_reexport | enter | baz.py:2:1:2:5 | ControlFlowNode for enter | +| simplistic_reexport | exit | baz.py:6:1:6:4 | ControlFlowNode for exit | +| simplistic_reexport | exit | simplistic_reexport.py:19:1:19:4 | ControlFlowNode for exit | +| simplistic_reexport | globals | simplistic_reexport.py:17:44:17:50 | ControlFlowNode for globals | diff --git a/python/ql/test/experimental/import-resolution/main.py b/python/ql/test/experimental/import-resolution/main.py index 31a4f60d56d..4d868437964 100644 --- a/python/ql/test/experimental/import-resolution/main.py +++ b/python/ql/test/experimental/import-resolution/main.py @@ -81,7 +81,7 @@ if sys.version_info[0] == 3: 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="" +check("clashing_attr", clashing_attr, "clashing_attr", globals()) #$ prints=clashing_attr SPURIOUS: prints="" SPURIOUS: prints="" SPURIOUS: prints="" check("non_clashing_submodule", non_clashing_submodule, "", globals()) #$ prints="" # check that import * only imports the __all__ attributes @@ -143,12 +143,12 @@ import if_then_else_refined # $ imports=if_then_else_refined as=if_then_else_ref check("if_then_else_refined.src", if_then_else_refined.src, if_then_else_refined.src, globals()) #$ prints=SOURCE import simplistic_reexport # $ imports=simplistic_reexport as=simplistic_reexport -check("simplistic_reexport.bar_attr", simplistic_reexport.bar_attr, "overwritten", globals()) #$ prints=overwritten SPURIOUS: prints=bar_attr +check("simplistic_reexport.bar_attr", simplistic_reexport.bar_attr, "overwritten", globals()) #$ MISSING: prints=overwritten SPURIOUS: prints=bar_attr check("simplistic_reexport.baz_attr", simplistic_reexport.baz_attr, "overwritten", globals()) #$ prints=overwritten SPURIOUS: prints=baz_attr # check that we don't treat all assignments as being exports import block_flow_check #$ imports=block_flow_check as=block_flow_check -check("block_flow_check.SOURCE", block_flow_check.SOURCE, block_flow_check.SOURCE, globals()) #$ SPURIOUS: prints=SOURCE +check("block_flow_check.SOURCE", block_flow_check.SOURCE, block_flow_check.SOURCE, globals()) exit(__file__) diff --git a/python/ql/test/query-tests/Security/CWE-327-InsecureProtocol/InsecureProtocol.expected b/python/ql/test/query-tests/Security/CWE-327-InsecureProtocol/InsecureProtocol.expected index cc0d620aa1c..f85319fee6f 100644 --- a/python/ql/test/query-tests/Security/CWE-327-InsecureProtocol/InsecureProtocol.expected +++ b/python/ql/test/query-tests/Security/CWE-327-InsecureProtocol/InsecureProtocol.expected @@ -13,11 +13,8 @@ | import_all_one_file.py:25:14:25:45 | ControlFlowNode for copy_completely_insecure_context | Insecure SSL/TLS protocol version TLSv1 allowed by $@. | import_all_one_file.py:9:36:9:67 | ControlFlowNode for Attribute() | call to ssl.SSLContext | | import_all_one_file.py:25:14:25:45 | ControlFlowNode for copy_completely_insecure_context | Insecure SSL/TLS protocol version TLSv1_1 allowed by $@. | import_all_one_file.py:9:36:9:67 | ControlFlowNode for Attribute() | call to ssl.SSLContext | | import_all_one_file.py:29:14:29:39 | ControlFlowNode for copy_also_insecure_context | Insecure SSL/TLS protocol version TLSv1_1 allowed by $@. | import_all_one_file.py:12:30:12:61 | ControlFlowNode for Attribute() | call to ssl.SSLContext | -| import_use.py:9:14:9:27 | ControlFlowNode for secure_context | Insecure SSL/TLS protocol version TLSv1 allowed by $@. | import_def.py:3:18:3:49 | ControlFlowNode for Attribute() | call to ssl.SSLContext | -| import_use.py:9:14:9:27 | ControlFlowNode for secure_context | Insecure SSL/TLS protocol version TLSv1_1 allowed by $@. | import_def.py:3:18:3:49 | ControlFlowNode for Attribute() | call to ssl.SSLContext | | import_use.py:13:14:13:40 | ControlFlowNode for completely_insecure_context | Insecure SSL/TLS protocol version TLSv1 allowed by $@. | import_def.py:7:31:7:62 | ControlFlowNode for Attribute() | call to ssl.SSLContext | | import_use.py:13:14:13:40 | ControlFlowNode for completely_insecure_context | Insecure SSL/TLS protocol version TLSv1_1 allowed by $@. | import_def.py:7:31:7:62 | ControlFlowNode for Attribute() | call to ssl.SSLContext | -| import_use.py:17:14:17:34 | ControlFlowNode for also_insecure_context | Insecure SSL/TLS protocol version TLSv1 allowed by $@. | import_def.py:10:25:10:56 | ControlFlowNode for Attribute() | call to ssl.SSLContext | | import_use.py:17:14:17:34 | ControlFlowNode for also_insecure_context | Insecure SSL/TLS protocol version TLSv1_1 allowed by $@. | import_def.py:10:25:10:56 | ControlFlowNode for Attribute() | call to ssl.SSLContext | | pyOpenSSL_fluent.py:8:27:8:33 | ControlFlowNode for context | Insecure SSL/TLS protocol version SSLv2 allowed by $@. | pyOpenSSL_fluent.py:6:15:6:44 | ControlFlowNode for Attribute() | call to SSL.Context | | pyOpenSSL_fluent.py:8:27:8:33 | ControlFlowNode for context | Insecure SSL/TLS protocol version SSLv3 allowed by $@. | pyOpenSSL_fluent.py:6:15:6:44 | ControlFlowNode for Attribute() | call to SSL.Context | From 373907265b9f7d5438445fd3caa3f81071338080 Mon Sep 17 00:00:00 2001 From: Rasmus Wriedt Larsen Date: Wed, 22 Feb 2023 16:12:19 +0100 Subject: [PATCH 218/631] Python: Fixed most problems from last commit That one line was an afterthought, and certainly did not work as intended. --- .../new/internal/ImportResolution.qll | 1 - .../typetracking_imports/tracked.expected | 19 ---------------- .../import-resolution/ModuleExport.expected | 22 +++++++++++++++++++ .../experimental/import-resolution/main.py | 2 +- 4 files changed, 23 insertions(+), 21 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 5090ba8fcd3..74ee1b83142 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/ImportResolution.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/ImportResolution.qll @@ -118,7 +118,6 @@ module ImportResolution { EssaFlow::defToFirstUse(firstDef, mid) and EssaFlow::useToNextUse*(mid, end) and not EssaFlow::useToNextUse(end, _) and - lastUseVar.getAUse() = end and val.asCfgNode() = end ) ) diff --git a/python/ql/test/experimental/dataflow/typetracking_imports/tracked.expected b/python/ql/test/experimental/dataflow/typetracking_imports/tracked.expected index 546325a8645..e69de29bb2d 100644 --- a/python/ql/test/experimental/dataflow/typetracking_imports/tracked.expected +++ b/python/ql/test/experimental/dataflow/typetracking_imports/tracked.expected @@ -1,19 +0,0 @@ -| pkg/alias_only_direct.py:1:26:1:36 | Comment # $ tracked | Missing result:tracked= | -| pkg/alias_problem.py:1:26:1:36 | Comment # $ tracked | Missing result:tracked= | -| pkg/alias_problem_fixed.py:3:26:3:36 | Comment # $ tracked | Missing result:tracked= | -| pkg/problem_absolute_import.py:1:29:1:39 | Comment # $ tracked | Missing result:tracked= | -| pkg/use.py:2:30:2:40 | Comment # $ tracked | Missing result:tracked= | -| pkg/use.py:3:16:3:26 | Comment # $ tracked | Missing result:tracked= | -| pkg/use.py:9:36:9:46 | Comment # $ tracked | Missing result:tracked= | -| pkg/use.py:10:16:10:26 | Comment # $ tracked | Missing result:tracked= | -| pkg/use.py:16:42:16:52 | Comment # $ tracked | Missing result:tracked= | -| pkg/use.py:17:16:17:26 | Comment # $ tracked | Missing result:tracked= | -| pkg/use.py:23:33:23:43 | Comment # $ tracked | Missing result:tracked= | -| pkg/use.py:24:16:24:26 | Comment # $ tracked | Missing result:tracked= | -| pkg/use.py:30:40:30:50 | Comment # $ tracked | Missing result:tracked= | -| pkg/use.py:31:16:31:26 | Comment # $ tracked | Missing result:tracked= | -| pkg/use.py:37:49:37:59 | Comment # $ tracked | Missing result:tracked= | -| pkg/use.py:38:16:38:26 | Comment # $ tracked | Missing result:tracked= | -| pkg/use.py:43:47:43:57 | Comment # $ tracked | Missing result:tracked= | -| pkg/use.py:44:16:44:26 | Comment # $ tracked | Missing result:tracked= | -| pkg/works_absolute_import.py:2:29:2:39 | Comment # $ tracked | Missing result:tracked= | diff --git a/python/ql/test/experimental/import-resolution/ModuleExport.expected b/python/ql/test/experimental/import-resolution/ModuleExport.expected index ad2dffde65b..30d1fd5369d 100644 --- a/python/ql/test/experimental/import-resolution/ModuleExport.expected +++ b/python/ql/test/experimental/import-resolution/ModuleExport.expected @@ -1,27 +1,33 @@ +| attr_clash.__init__ | __file__ | attr_clash/__init__.py:6:6:6:13 | ControlFlowNode for __file__ | | attr_clash.__init__ | __name__ | attr_clash/__init__.py:0:0:0:0 | GSSA Variable __name__ | | attr_clash.__init__ | __package__ | attr_clash/__init__.py:0:0:0:0 | GSSA Variable __package__ | | attr_clash.__init__ | clashing_attr | attr_clash/__init__.py:4:1:4:13 | GSSA Variable clashing_attr | | attr_clash.__init__ | enter | attr_clash/__init__.py:2:1:2:5 | ControlFlowNode for enter | | attr_clash.__init__ | exit | attr_clash/__init__.py:6:1:6:4 | ControlFlowNode for exit | +| attr_clash.clashing_attr | __file__ | attr_clash/clashing_attr.py:4:6:4:13 | ControlFlowNode for __file__ | | attr_clash.clashing_attr | __name__ | attr_clash/clashing_attr.py:0:0:0:0 | GSSA Variable __name__ | | attr_clash.clashing_attr | __package__ | attr_clash/clashing_attr.py:0:0:0:0 | GSSA Variable __package__ | | attr_clash.clashing_attr | enter | attr_clash/clashing_attr.py:2:1:2:5 | ControlFlowNode for enter | | attr_clash.clashing_attr | exit | attr_clash/clashing_attr.py:4:1:4:4 | ControlFlowNode for exit | +| attr_clash.non_clashing_submodule | __file__ | attr_clash/non_clashing_submodule.py:4:6:4:13 | ControlFlowNode for __file__ | | attr_clash.non_clashing_submodule | __name__ | attr_clash/non_clashing_submodule.py:0:0:0:0 | GSSA Variable __name__ | | attr_clash.non_clashing_submodule | __package__ | attr_clash/non_clashing_submodule.py:0:0:0:0 | GSSA Variable __package__ | | attr_clash.non_clashing_submodule | enter | attr_clash/non_clashing_submodule.py:2:1:2:5 | ControlFlowNode for enter | | attr_clash.non_clashing_submodule | exit | attr_clash/non_clashing_submodule.py:4:1:4:4 | ControlFlowNode for exit | +| bar | __file__ | bar.py:6:6:6:13 | ControlFlowNode for __file__ | | bar | __name__ | bar.py:0:0:0:0 | GSSA Variable __name__ | | bar | __package__ | bar.py:0:0:0:0 | GSSA Variable __package__ | | bar | bar_attr | bar.py:4:1:4:8 | GSSA Variable bar_attr | | bar | enter | bar.py:2:1:2:5 | ControlFlowNode for enter | | bar | exit | bar.py:6:1:6:4 | ControlFlowNode for exit | +| baz | __file__ | baz.py:6:6:6:13 | ControlFlowNode for __file__ | | baz | __name__ | baz.py:0:0:0:0 | GSSA Variable __name__ | | baz | __package__ | baz.py:0:0:0:0 | GSSA Variable __package__ | | baz | baz_attr | baz.py:4:1:4:8 | GSSA Variable baz_attr | | baz | enter | baz.py:2:1:2:5 | ControlFlowNode for enter | | baz | exit | baz.py:6:1:6:4 | ControlFlowNode for exit | | block_flow_check | SOURCE | block_flow_check.py:12:25:12:30 | ControlFlowNode for SOURCE | +| block_flow_check | __file__ | block_flow_check.py:14:6:14:13 | ControlFlowNode for __file__ | | block_flow_check | __name__ | block_flow_check.py:0:0:0:0 | GSSA Variable __name__ | | block_flow_check | __package__ | block_flow_check.py:0:0:0:0 | GSSA Variable __package__ | | block_flow_check | check | block_flow_check.py:12:1:12:5 | ControlFlowNode for check | @@ -30,6 +36,7 @@ | block_flow_check | globals | block_flow_check.py:12:33:12:39 | ControlFlowNode for globals | | block_flow_check | object | block_flow_check.py:4:14:4:19 | ControlFlowNode for object | | block_flow_check | staticmethod | block_flow_check.py:0:0:0:0 | GSSA Variable staticmethod | +| foo | __file__ | foo.py:14:6:14:13 | ControlFlowNode for __file__ | | foo | __name__ | foo.py:0:0:0:0 | GSSA Variable __name__ | | foo | __package__ | foo.py:0:0:0:0 | GSSA Variable __package__ | | foo | __private_foo_attr | foo.py:8:1:8:18 | GSSA Variable __private_foo_attr | @@ -41,6 +48,7 @@ | foo | foo_attr | foo.py:5:1:5:8 | GSSA Variable foo_attr | | foo | globals | foo.py:12:71:12:77 | ControlFlowNode for globals | | has_defined_all | __all__ | has_defined_all.py:7:1:7:7 | GSSA Variable __all__ | +| has_defined_all | __file__ | has_defined_all.py:9:6:9:13 | ControlFlowNode for __file__ | | has_defined_all | __name__ | has_defined_all.py:0:0:0:0 | GSSA Variable __name__ | | has_defined_all | __package__ | has_defined_all.py:0:0:0:0 | GSSA Variable __package__ | | has_defined_all | all_defined_bar | has_defined_all.py:5:1:5:15 | GSSA Variable all_defined_bar | @@ -48,16 +56,20 @@ | has_defined_all | enter | has_defined_all.py:2:1:2:5 | ControlFlowNode for enter | | has_defined_all | exit | has_defined_all.py:9:1:9:4 | ControlFlowNode for exit | | has_defined_all_copy | __all__ | has_defined_all_copy.py:9:1:9:7 | GSSA Variable __all__ | +| has_defined_all_copy | __file__ | has_defined_all_copy.py:11:6:11:13 | ControlFlowNode for __file__ | | has_defined_all_copy | __name__ | has_defined_all_copy.py:0:0:0:0 | GSSA Variable __name__ | | has_defined_all_copy | __package__ | has_defined_all_copy.py:0:0:0:0 | GSSA Variable __package__ | | has_defined_all_copy | all_defined_bar_copy | has_defined_all_copy.py:7:1:7:20 | GSSA Variable all_defined_bar_copy | | has_defined_all_copy | all_defined_foo_copy | has_defined_all_copy.py:6:1:6:20 | GSSA Variable all_defined_foo_copy | | has_defined_all_copy | enter | has_defined_all_copy.py:4:1:4:5 | ControlFlowNode for enter | | has_defined_all_copy | exit | has_defined_all_copy.py:11:1:11:4 | ControlFlowNode for exit | +| has_defined_all_indirection | __file__ | has_defined_all_indirection.py:6:6:6:13 | ControlFlowNode for __file__ | | has_defined_all_indirection | __name__ | has_defined_all_indirection.py:0:0:0:0 | GSSA Variable __name__ | | has_defined_all_indirection | __package__ | has_defined_all_indirection.py:0:0:0:0 | GSSA Variable __package__ | | has_defined_all_indirection | all_defined_foo_copy | has_defined_all_copy.py:6:1:6:20 | GSSA Variable all_defined_foo_copy | +| has_defined_all_indirection | enter | has_defined_all_indirection.py:2:1:2:5 | ControlFlowNode for enter | | has_defined_all_indirection | exit | has_defined_all_indirection.py:6:1:6:4 | ControlFlowNode for exit | +| if_then_else | __file__ | if_then_else.py:16:6:16:13 | ControlFlowNode for __file__ | | if_then_else | __name__ | if_then_else.py:0:0:0:0 | GSSA Variable __name__ | | if_then_else | __package__ | if_then_else.py:0:0:0:0 | GSSA Variable __package__ | | if_then_else | enter | if_then_else.py:2:1:2:5 | ControlFlowNode for enter | @@ -68,6 +80,7 @@ | if_then_else | if_then_else_defined | if_then_else.py:14:9:14:28 | GSSA Variable if_then_else_defined | | if_then_else_refined | SOURCE | if_then_else_refined.py:11:11:11:16 | ControlFlowNode for SOURCE | | if_then_else_refined | SOURCE | if_then_else_refined.py:13:11:13:16 | ControlFlowNode for SOURCE | +| if_then_else_refined | __file__ | if_then_else_refined.py:19:6:19:13 | ControlFlowNode for __file__ | | if_then_else_refined | __name__ | if_then_else_refined.py:0:0:0:0 | GSSA Variable __name__ | | if_then_else_refined | __package__ | if_then_else_refined.py:0:0:0:0 | GSSA Variable __package__ | | if_then_else_refined | check | if_then_else_refined.py:17:1:17:5 | ControlFlowNode for check | @@ -76,22 +89,26 @@ | if_then_else_refined | exit | if_then_else_refined.py:19:1:19:4 | ControlFlowNode for exit | | if_then_else_refined | globals | if_then_else_refined.py:17:24:17:30 | ControlFlowNode for globals | | if_then_else_refined | src | if_then_else_refined.py:17:19:17:21 | ControlFlowNode for src | +| namespace_package.namespace_module | __file__ | namespace_package/namespace_module.py:6:6:6:13 | ControlFlowNode for __file__ | | namespace_package.namespace_module | __name__ | namespace_package/namespace_module.py:0:0:0:0 | GSSA Variable __name__ | | namespace_package.namespace_module | __package__ | namespace_package/namespace_module.py:0:0:0:0 | GSSA Variable __package__ | | namespace_package.namespace_module | enter | namespace_package/namespace_module.py:2:1:2:5 | ControlFlowNode for enter | | namespace_package.namespace_module | exit | namespace_package/namespace_module.py:6:1:6:4 | ControlFlowNode for exit | | namespace_package.namespace_module | namespace_module_attr | namespace_package/namespace_module.py:4:1:4:21 | GSSA Variable namespace_module_attr | +| package.__init__ | __file__ | package/__init__.py:7:6:7:13 | ControlFlowNode for __file__ | | package.__init__ | __name__ | package/__init__.py:0:0:0:0 | GSSA Variable __name__ | | package.__init__ | __package__ | package/__init__.py:0:0:0:0 | GSSA Variable __package__ | | package.__init__ | attr_used_in_subpackage | package/__init__.py:4:1:4:23 | GSSA Variable attr_used_in_subpackage | | package.__init__ | enter | package/__init__.py:2:1:2:5 | ControlFlowNode for enter | | package.__init__ | exit | package/__init__.py:7:1:7:4 | ControlFlowNode for exit | | package.__init__ | package_attr | package/__init__.py:5:1:5:12 | GSSA Variable package_attr | +| package.subpackage2.__init__ | __file__ | package/subpackage2/__init__.py:6:6:6:13 | ControlFlowNode for __file__ | | package.subpackage2.__init__ | __name__ | package/subpackage2/__init__.py:0:0:0:0 | GSSA Variable __name__ | | package.subpackage2.__init__ | __package__ | package/subpackage2/__init__.py:0:0:0:0 | GSSA Variable __package__ | | package.subpackage2.__init__ | enter | package/subpackage2/__init__.py:2:1:2:5 | ControlFlowNode for enter | | package.subpackage2.__init__ | exit | package/subpackage2/__init__.py:6:1:6:4 | ControlFlowNode for exit | | package.subpackage2.__init__ | subpackage2_attr | package/subpackage2/__init__.py:4:1:4:16 | GSSA Variable subpackage2_attr | +| package.subpackage.__init__ | __file__ | package/subpackage/__init__.py:14:6:14:13 | ControlFlowNode for __file__ | | package.subpackage.__init__ | __name__ | package/subpackage/__init__.py:0:0:0:0 | GSSA Variable __name__ | | package.subpackage.__init__ | __package__ | package/subpackage/__init__.py:0:0:0:0 | GSSA Variable __package__ | | package.subpackage.__init__ | check | package/subpackage/__init__.py:12:1:12:5 | ControlFlowNode for check | @@ -104,6 +121,7 @@ | package.subpackage.__init__ | irrelevant_attr | package/subpackage/__init__.py:11:24:11:38 | GSSA Variable irrelevant_attr | | package.subpackage.__init__ | submodule | package/subpackage/__init__.py:12:35:12:43 | ControlFlowNode for submodule | | package.subpackage.__init__ | subpackage_attr | package/subpackage/__init__.py:4:1:4:15 | GSSA Variable subpackage_attr | +| package.subpackage.submodule | __file__ | package/subpackage/submodule.py:7:6:7:13 | ControlFlowNode for __file__ | | package.subpackage.submodule | __name__ | package/subpackage/submodule.py:0:0:0:0 | GSSA Variable __name__ | | package.subpackage.submodule | __package__ | package/subpackage/submodule.py:0:0:0:0 | GSSA Variable __package__ | | package.subpackage.submodule | enter | package/subpackage/submodule.py:2:1:2:5 | ControlFlowNode for enter | @@ -111,6 +129,7 @@ | package.subpackage.submodule | irrelevant_attr | package/subpackage/submodule.py:5:1:5:15 | GSSA Variable irrelevant_attr | | package.subpackage.submodule | submodule_attr | package/subpackage/submodule.py:4:1:4:14 | GSSA Variable submodule_attr | | refined | SOURCE | refined.py:12:25:12:30 | ControlFlowNode for SOURCE | +| refined | __file__ | refined.py:14:6:14:13 | ControlFlowNode for __file__ | | refined | __name__ | refined.py:0:0:0:0 | GSSA Variable __name__ | | refined | __package__ | refined.py:0:0:0:0 | GSSA Variable __package__ | | refined | check | refined.py:12:1:12:5 | ControlFlowNode for check | @@ -118,13 +137,16 @@ | refined | exit | refined.py:14:1:14:4 | ControlFlowNode for exit | | refined | globals | refined.py:12:33:12:39 | ControlFlowNode for globals | | refined | object | refined.py:4:14:4:19 | ControlFlowNode for object | +| simplistic_reexport | __file__ | simplistic_reexport.py:19:6:19:13 | ControlFlowNode for __file__ | | simplistic_reexport | __name__ | simplistic_reexport.py:0:0:0:0 | GSSA Variable __name__ | | simplistic_reexport | __package__ | simplistic_reexport.py:0:0:0:0 | GSSA Variable __package__ | | simplistic_reexport | bar_attr | simplistic_reexport.py:6:17:6:24 | ControlFlowNode for ImportMember | +| simplistic_reexport | bar_attr | simplistic_reexport.py:10:19:10:26 | ControlFlowNode for bar_attr | | simplistic_reexport | baz_attr | baz.py:4:1:4:8 | GSSA Variable baz_attr | | simplistic_reexport | baz_attr | simplistic_reexport.py:17:19:17:26 | ControlFlowNode for baz_attr | | simplistic_reexport | check | simplistic_reexport.py:17:1:17:5 | ControlFlowNode for check | | simplistic_reexport | enter | baz.py:2:1:2:5 | ControlFlowNode for enter | +| simplistic_reexport | enter | simplistic_reexport.py:4:1:4:5 | ControlFlowNode for enter | | simplistic_reexport | exit | baz.py:6:1:6:4 | ControlFlowNode for exit | | simplistic_reexport | exit | simplistic_reexport.py:19:1:19:4 | ControlFlowNode for exit | | simplistic_reexport | globals | simplistic_reexport.py:17:44:17:50 | ControlFlowNode for globals | diff --git a/python/ql/test/experimental/import-resolution/main.py b/python/ql/test/experimental/import-resolution/main.py index 4d868437964..1fe6a9c3c65 100644 --- a/python/ql/test/experimental/import-resolution/main.py +++ b/python/ql/test/experimental/import-resolution/main.py @@ -143,7 +143,7 @@ import if_then_else_refined # $ imports=if_then_else_refined as=if_then_else_ref check("if_then_else_refined.src", if_then_else_refined.src, if_then_else_refined.src, globals()) #$ prints=SOURCE import simplistic_reexport # $ imports=simplistic_reexport as=simplistic_reexport -check("simplistic_reexport.bar_attr", simplistic_reexport.bar_attr, "overwritten", globals()) #$ MISSING: prints=overwritten SPURIOUS: prints=bar_attr +check("simplistic_reexport.bar_attr", simplistic_reexport.bar_attr, "overwritten", globals()) #$ prints=overwritten SPURIOUS: prints=bar_attr check("simplistic_reexport.baz_attr", simplistic_reexport.baz_attr, "overwritten", globals()) #$ prints=overwritten SPURIOUS: prints=baz_attr # check that we don't treat all assignments as being exports From 13ae98ea76180f062423294634ddcb2d4470d6ff Mon Sep 17 00:00:00 2001 From: Rasmus Wriedt Larsen Date: Wed, 22 Feb 2023 16:19:15 +0100 Subject: [PATCH 219/631] Python: Fix submodule exported under wrong name (when attribute clash) --- .../dataflow/new/internal/ImportResolution.qll | 16 ++++++++++++++-- .../test/experimental/import-resolution/main.py | 2 +- 2 files changed, 15 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 74ee1b83142..64ae4e50430 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/ImportResolution.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/ImportResolution.qll @@ -307,9 +307,21 @@ module ImportResolution { module_reexport(reexporter, attr_name, m) ) or - // 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. + // submodules of packages will be available as `.` after doing + // `import .` at least once in the program, or can be directly + // imported with `from import ` (even with an empty + // `.__init__` file). + // + // Until an import of `.` is executed, it is technically possible + // that `.` (or `from import `) can refer to an + // attribute set in `.__init__`. + // + // Therefore, if there is an attribute defined in `.__init__` with the same + // name as a submodule, we always consider that this attribute _could_ be a + // reference to the submodule, even if we don't know that the submodule has been + // imported yet. exists(string submodule, Module package | + submodule = result.asVar().getName() and SsaSource::init_module_submodule_defn(result.asVar().getSourceVariable(), package.getEntryNode()) and m = getModuleFromName(package.getPackageName() + "." + submodule) diff --git a/python/ql/test/experimental/import-resolution/main.py b/python/ql/test/experimental/import-resolution/main.py index 1fe6a9c3c65..12fe78fa695 100644 --- a/python/ql/test/experimental/import-resolution/main.py +++ b/python/ql/test/experimental/import-resolution/main.py @@ -81,7 +81,7 @@ if sys.version_info[0] == 3: 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="" SPURIOUS: prints="" +check("clashing_attr", clashing_attr, "clashing_attr", globals()) #$ prints=clashing_attr SPURIOUS: prints="" check("non_clashing_submodule", non_clashing_submodule, "", globals()) #$ prints="" # check that import * only imports the __all__ attributes From 96c0d95b10e6c7face76c96cf81d7aa3836d7398 Mon Sep 17 00:00:00 2001 From: Rasmus Wriedt Larsen Date: Wed, 22 Feb 2023 16:34:02 +0100 Subject: [PATCH 220/631] Python: Illustrate that `clashing_attr` can be submodule --- python/ql/test/experimental/import-resolution/main.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/python/ql/test/experimental/import-resolution/main.py b/python/ql/test/experimental/import-resolution/main.py index 12fe78fa695..31308c5bdfa 100644 --- a/python/ql/test/experimental/import-resolution/main.py +++ b/python/ql/test/experimental/import-resolution/main.py @@ -84,6 +84,10 @@ from attr_clash import clashing_attr, non_clashing_submodule #$ imports=attr_cla check("clashing_attr", clashing_attr, "clashing_attr", globals()) #$ prints=clashing_attr SPURIOUS: prints="" check("non_clashing_submodule", non_clashing_submodule, "", globals()) #$ prints="" +import attr_clash.clashing_attr as _doesnt_matter #$ imports=attr_clash.clashing_attr as=_doesnt_matter +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, "", globals()) #$ prints="" SPURIOUS: prints=clashing_attr + # check that import * only imports the __all__ attributes from has_defined_all import * check("all_defined_foo", all_defined_foo, "all_defined_foo", globals()) #$ prints=all_defined_foo From b7bdc551d54db603862e58e5357cc180da227650 Mon Sep 17 00:00:00 2001 From: Rasmus Wriedt Larsen Date: Thu, 23 Feb 2023 00:50:01 +0100 Subject: [PATCH 221/631] Python: Show import resolution is a bit generous with exported value --- .../import-resolution/ModuleExport.expected | 14 ++++++++++++ .../import-resolution/generous_export.py | 22 +++++++++++++++++++ .../experimental/import-resolution/main.py | 4 ++++ 3 files changed, 40 insertions(+) create mode 100644 python/ql/test/experimental/import-resolution/generous_export.py diff --git a/python/ql/test/experimental/import-resolution/ModuleExport.expected b/python/ql/test/experimental/import-resolution/ModuleExport.expected index 30d1fd5369d..0e250ab4b79 100644 --- a/python/ql/test/experimental/import-resolution/ModuleExport.expected +++ b/python/ql/test/experimental/import-resolution/ModuleExport.expected @@ -47,6 +47,20 @@ | foo | exit | foo.py:14:1:14:4 | ControlFlowNode for exit | | foo | foo_attr | foo.py:5:1:5:8 | GSSA Variable foo_attr | | foo | globals | foo.py:12:71:12:77 | ControlFlowNode for globals | +| generous_export | Exception | generous_export.py:16:11:16:19 | ControlFlowNode for Exception | +| generous_export | SOURCE | generous_export.py:15:11:15:16 | ControlFlowNode for SOURCE | +| generous_export | SOURCE | generous_export.py:20:25:20:30 | ControlFlowNode for SOURCE | +| generous_export | __file__ | generous_export.py:22:6:22:13 | ControlFlowNode for __file__ | +| generous_export | __name__ | generous_export.py:0:0:0:0 | GSSA Variable __name__ | +| generous_export | __package__ | generous_export.py:0:0:0:0 | GSSA Variable __package__ | +| generous_export | check | generous_export.py:20:1:20:5 | ControlFlowNode for check | +| generous_export | enter | generous_export.py:2:1:2:5 | ControlFlowNode for enter | +| generous_export | eval | generous_export.py:10:4:10:7 | ControlFlowNode for eval | +| generous_export | exit | generous_export.py:22:1:22:4 | ControlFlowNode for exit | +| generous_export | globals | generous_export.py:20:33:20:39 | ControlFlowNode for globals | +| generous_export | object | generous_export.py:4:14:4:19 | ControlFlowNode for object | +| generous_export | print | generous_export.py:15:5:15:9 | ControlFlowNode for print | +| generous_export | staticmethod | generous_export.py:0:0:0:0 | GSSA Variable staticmethod | | has_defined_all | __all__ | has_defined_all.py:7:1:7:7 | GSSA Variable __all__ | | has_defined_all | __file__ | has_defined_all.py:9:6:9:13 | ControlFlowNode for __file__ | | has_defined_all | __name__ | has_defined_all.py:0:0:0:0 | GSSA Variable __name__ | diff --git a/python/ql/test/experimental/import-resolution/generous_export.py b/python/ql/test/experimental/import-resolution/generous_export.py new file mode 100644 index 00000000000..cbea96e19ce --- /dev/null +++ b/python/ql/test/experimental/import-resolution/generous_export.py @@ -0,0 +1,22 @@ +from trace import * +enter(__file__) + +class SOURCE(object): + @staticmethod + def block_flow(): pass + +check("SOURCE", SOURCE, SOURCE, globals()) #$ prints=SOURCE + +if eval("False"): + # With our current import resolution, this value for SOURCE will be considered to be + # a valid value at the end of this module, because it's the end of a use-use flow. + # This is clearly wrong, so our import resolution is a bit too generous on what is + # exported + print(SOURCE) + raise Exception() + +SOURCE.block_flow() + +check("SOURCE", SOURCE, SOURCE, globals()) + +exit(__file__) diff --git a/python/ql/test/experimental/import-resolution/main.py b/python/ql/test/experimental/import-resolution/main.py index 31308c5bdfa..ce1bee040f4 100644 --- a/python/ql/test/experimental/import-resolution/main.py +++ b/python/ql/test/experimental/import-resolution/main.py @@ -154,6 +154,10 @@ check("simplistic_reexport.baz_attr", simplistic_reexport.baz_attr, "overwritten import block_flow_check #$ imports=block_flow_check as=block_flow_check check("block_flow_check.SOURCE", block_flow_check.SOURCE, block_flow_check.SOURCE, globals()) +# show that import resolution is a bit too generous with definitions +import generous_export #$ imports=generous_export as=generous_export +check("generous_export.SOURCE", generous_export.SOURCE, generous_export.SOURCE, globals()) #$ SPURIOUS: prints=SOURCE + exit(__file__) print() From 11000fd12313bb8e513bd28216123c8145511bc3 Mon Sep 17 00:00:00 2001 From: Rasmus Wriedt Larsen Date: Mon, 27 Feb 2023 17:00:17 +0100 Subject: [PATCH 222/631] Python: Fix `ModuleExport.ql` test for Python 2 --- .../experimental/import-resolution/ModuleExport.expected | 6 ------ .../test/experimental/import-resolution/ModuleExport.ql | 8 +++++++- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/python/ql/test/experimental/import-resolution/ModuleExport.expected b/python/ql/test/experimental/import-resolution/ModuleExport.expected index 0e250ab4b79..b1f63a02a78 100644 --- a/python/ql/test/experimental/import-resolution/ModuleExport.expected +++ b/python/ql/test/experimental/import-resolution/ModuleExport.expected @@ -103,12 +103,6 @@ | if_then_else_refined | exit | if_then_else_refined.py:19:1:19:4 | ControlFlowNode for exit | | if_then_else_refined | globals | if_then_else_refined.py:17:24:17:30 | ControlFlowNode for globals | | if_then_else_refined | src | if_then_else_refined.py:17:19:17:21 | ControlFlowNode for src | -| namespace_package.namespace_module | __file__ | namespace_package/namespace_module.py:6:6:6:13 | ControlFlowNode for __file__ | -| namespace_package.namespace_module | __name__ | namespace_package/namespace_module.py:0:0:0:0 | GSSA Variable __name__ | -| namespace_package.namespace_module | __package__ | namespace_package/namespace_module.py:0:0:0:0 | GSSA Variable __package__ | -| namespace_package.namespace_module | enter | namespace_package/namespace_module.py:2:1:2:5 | ControlFlowNode for enter | -| namespace_package.namespace_module | exit | namespace_package/namespace_module.py:6:1:6:4 | ControlFlowNode for exit | -| namespace_package.namespace_module | namespace_module_attr | namespace_package/namespace_module.py:4:1:4:21 | GSSA Variable namespace_module_attr | | package.__init__ | __file__ | package/__init__.py:7:6:7:13 | ControlFlowNode for __file__ | | package.__init__ | __name__ | package/__init__.py:0:0:0:0 | GSSA Variable __name__ | | package.__init__ | __package__ | package/__init__.py:0:0:0:0 | GSSA Variable __package__ | diff --git a/python/ql/test/experimental/import-resolution/ModuleExport.ql b/python/ql/test/experimental/import-resolution/ModuleExport.ql index 4b84527573e..56db660b103 100644 --- a/python/ql/test/experimental/import-resolution/ModuleExport.ql +++ b/python/ql/test/experimental/import-resolution/ModuleExport.ql @@ -7,5 +7,11 @@ where ImportResolution::module_export(m, name, defn) and exists(m.getLocation().getFile().getRelativePath()) and not defn.getScope() = any(Module trace | trace.getName() = "trace") and - not m.getName() = "main" + not m.getName() = "main" and + // Since we test on both Python 2 and Python 3, but `namespace_package` is not allowed + // on Python 2 because of the missing `__init__.py` files, we remove those results + // from Python 3 tests as well. One alternative is to only run these tests under + // Python 3, but that does not seems like a good solution -- we could easily miss a + // Python 2 only regression then :O + not m.getName() = "namespace_package.namespace_module" select m.getName(), name, defn From 6a578c62b0eb3ef21f5e6416378deb9d96a632b2 Mon Sep 17 00:00:00 2001 From: Ahmed Farid Date: Mon, 27 Feb 2023 22:16:09 +0100 Subject: [PATCH 223/631] Update TimingAttack.qll --- .../src/experimental/semmle/python/security/TimingAttack.qll | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/python/ql/src/experimental/semmle/python/security/TimingAttack.qll b/python/ql/src/experimental/semmle/python/security/TimingAttack.qll index 46a0072b19b..01613de2ed9 100644 --- a/python/ql/src/experimental/semmle/python/security/TimingAttack.qll +++ b/python/ql/src/experimental/semmle/python/security/TimingAttack.qll @@ -316,8 +316,7 @@ class CompareSink extends DataFlow::Node { exists(Compare compare | ( compare.getOp(0) instanceof Eq or - compare.getOp(0) instanceof NotEq or - compare.getOp(0) instanceof In + compare.getOp(0) instanceof NotEq ) and ( compare.getLeft() = this.asExpr() and From e09975f8532acfddf52a77c5287d61a7dd4d358a Mon Sep 17 00:00:00 2001 From: Asger F Date: Wed, 1 Mar 2023 13:46:13 +0100 Subject: [PATCH 224/631] JS: Replace 'remote-flow' kind with 'remote' --- .../customizing-library-models-for-javascript.rst | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/codeql/codeql-language-guides/customizing-library-models-for-javascript.rst b/docs/codeql/codeql-language-guides/customizing-library-models-for-javascript.rst index f1a73a95e36..89a7ced5035 100644 --- a/docs/codeql/codeql-language-guides/customizing-library-models-for-javascript.rst +++ b/docs/codeql/codeql-language-guides/customizing-library-models-for-javascript.rst @@ -89,7 +89,7 @@ This source is already known by the CodeQL JS analysis, but we'll show how it co - [ "global", "Member[addEventListener].Argument[1].Parameter[0].Member[data]", - "remote-flow", + "remote", ] To break this down: @@ -100,7 +100,7 @@ To break this down: - **Argument[1]** selects the second argument of calls to that member (the argument containing the callback). - **Parameter[0]** selects the first parameter of the callback (the parameter named **event**). - **Member[data]** selects accesses to the **data** property of the event object. -- Finally, the kind **remote-flow** indicates that this is considered a source of remote flow. +- Finally, the kind **remote** indicates that this is considered a source of remote flow. Continued example: Restricting the event type --------------------------------------------- @@ -127,7 +127,7 @@ We can refine the model by adding the **WithStringArgument** component to restri - [ "global", "Member[addEventListener].WithStringArgument[0=message].Argument[1].Parameter[0].Member[data]", - "remote-flow", + "remote", ] The **WithStringArgument[0=message]** component here selects the subset of calls to **addEventListener** where the first argument is a string literal with the value **"message"**. @@ -308,7 +308,7 @@ Adds a new taint source. Most taint-tracking queries will use the new source. - **type**: Name of a type from which to evaluate **path**. - **path**: Access path leading to the source. -- **kind**: Kind of source to add. Currently only **remote-flow** is used. +- **kind**: Kind of source to add. Currently only **remote** is used. Example: @@ -319,7 +319,7 @@ Example: pack: codeql/javascript-all extensible: sourceModel data: - - ["global", "Member[user].Member[name]", "remote-flow"] + - ["global", "Member[user].Member[name]", "remote"] sinkModel(type, path, kind) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -447,7 +447,7 @@ Kinds Source kinds ~~~~~~~~~~~~ -- **remote-flow**: A generic source of remote flow. Most taint-tracking queries will use such a source. Currently this is the only supported source kind. +- **remote**: A generic source of remote flow. Most taint-tracking queries will use such a source. Currently this is the only supported source kind. Sink kinds ~~~~~~~~~~ From b9b8b8b28a9f0dca2f2a080026134fd50fe1a2ba Mon Sep 17 00:00:00 2001 From: Asger F Date: Fri, 3 Mar 2023 13:46:15 +0100 Subject: [PATCH 225/631] JS: Remove public links to customization docs --- docs/codeql/codeql-language-guides/codeql-for-javascript.rst | 3 --- ...pecifying-additional-remote-flow-sources-for-javascript.rst | 2 -- 2 files changed, 5 deletions(-) diff --git a/docs/codeql/codeql-language-guides/codeql-for-javascript.rst b/docs/codeql/codeql-language-guides/codeql-for-javascript.rst index 98f8d27a155..be3950c53ec 100644 --- a/docs/codeql/codeql-language-guides/codeql-for-javascript.rst +++ b/docs/codeql/codeql-language-guides/codeql-for-javascript.rst @@ -13,7 +13,6 @@ Experiment and learn how to write effective and efficient queries for CodeQL dat codeql-library-for-typescript analyzing-data-flow-in-javascript-and-typescript using-flow-labels-for-precise-data-flow-analysis - customizing-library-models-for-javascript specifying-additional-remote-flow-sources-for-javascript using-type-tracking-for-api-modeling abstract-syntax-tree-classes-for-working-with-javascript-and-typescript-programs @@ -29,8 +28,6 @@ Experiment and learn how to write effective and efficient queries for CodeQL dat - :doc:`Using flow labels for precise data flow analysis `: You can associate flow labels with each value tracked by the flow analysis to determine whether the flow contains potential vulnerabilities. -- :doc:`Customizing library models for JavaScript `: You can model the libraries used in your code without making changes to the CodeQL standard library by specifying source, sink, and flow summaries in a data extension file. - - :doc:`Using type tracking for API modeling `: You can track data through an API by creating a model using the CodeQL type-tracking library for JavaScript. - :doc:`Abstract syntax tree classes for working with JavaScript and TypeScript programs `: CodeQL has a large selection of classes for representing the abstract syntax tree of JavaScript and TypeScript programs. diff --git a/docs/codeql/codeql-language-guides/specifying-additional-remote-flow-sources-for-javascript.rst b/docs/codeql/codeql-language-guides/specifying-additional-remote-flow-sources-for-javascript.rst index 81cc1ff854c..7ee1706db45 100644 --- a/docs/codeql/codeql-language-guides/specifying-additional-remote-flow-sources-for-javascript.rst +++ b/docs/codeql/codeql-language-guides/specifying-additional-remote-flow-sources-for-javascript.rst @@ -10,8 +10,6 @@ Specifying additional remote flow sources for JavaScript Specifying remote flow sources with the JSON format described here is soon to be deprecated and will be removed in the future. - See :ref:`Customizing Library Models for JavaScript `. - You can model potential sources of untrusted user input in your code without making changes to the CodeQL standard library by specifying extra remote flow sources in an external file. As mentioned in the :ref:`Data flow cheat sheet for JavaScript `, the CodeQL libraries for JavaScript From 3d5c06b782dc474f9b359ecdb8fb13423e86822c Mon Sep 17 00:00:00 2001 From: Asger F Date: Mon, 6 Mar 2023 12:46:12 +0100 Subject: [PATCH 226/631] Revert "JS: Remove public links to customization docs" This reverts commit b9b8b8b28a9f0dca2f2a080026134fd50fe1a2ba. --- docs/codeql/codeql-language-guides/codeql-for-javascript.rst | 3 +++ ...pecifying-additional-remote-flow-sources-for-javascript.rst | 2 ++ 2 files changed, 5 insertions(+) diff --git a/docs/codeql/codeql-language-guides/codeql-for-javascript.rst b/docs/codeql/codeql-language-guides/codeql-for-javascript.rst index be3950c53ec..98f8d27a155 100644 --- a/docs/codeql/codeql-language-guides/codeql-for-javascript.rst +++ b/docs/codeql/codeql-language-guides/codeql-for-javascript.rst @@ -13,6 +13,7 @@ Experiment and learn how to write effective and efficient queries for CodeQL dat codeql-library-for-typescript analyzing-data-flow-in-javascript-and-typescript using-flow-labels-for-precise-data-flow-analysis + customizing-library-models-for-javascript specifying-additional-remote-flow-sources-for-javascript using-type-tracking-for-api-modeling abstract-syntax-tree-classes-for-working-with-javascript-and-typescript-programs @@ -28,6 +29,8 @@ Experiment and learn how to write effective and efficient queries for CodeQL dat - :doc:`Using flow labels for precise data flow analysis `: You can associate flow labels with each value tracked by the flow analysis to determine whether the flow contains potential vulnerabilities. +- :doc:`Customizing library models for JavaScript `: You can model the libraries used in your code without making changes to the CodeQL standard library by specifying source, sink, and flow summaries in a data extension file. + - :doc:`Using type tracking for API modeling `: You can track data through an API by creating a model using the CodeQL type-tracking library for JavaScript. - :doc:`Abstract syntax tree classes for working with JavaScript and TypeScript programs `: CodeQL has a large selection of classes for representing the abstract syntax tree of JavaScript and TypeScript programs. diff --git a/docs/codeql/codeql-language-guides/specifying-additional-remote-flow-sources-for-javascript.rst b/docs/codeql/codeql-language-guides/specifying-additional-remote-flow-sources-for-javascript.rst index 7ee1706db45..81cc1ff854c 100644 --- a/docs/codeql/codeql-language-guides/specifying-additional-remote-flow-sources-for-javascript.rst +++ b/docs/codeql/codeql-language-guides/specifying-additional-remote-flow-sources-for-javascript.rst @@ -10,6 +10,8 @@ Specifying additional remote flow sources for JavaScript Specifying remote flow sources with the JSON format described here is soon to be deprecated and will be removed in the future. + See :ref:`Customizing Library Models for JavaScript `. + You can model potential sources of untrusted user input in your code without making changes to the CodeQL standard library by specifying extra remote flow sources in an external file. As mentioned in the :ref:`Data flow cheat sheet for JavaScript `, the CodeQL libraries for JavaScript From f8b5a820f41c7b0b32bb5dca05543cd77ec83348 Mon Sep 17 00:00:00 2001 From: Rasmus Lerchedahl Petersen Date: Mon, 6 Mar 2023 14:31:17 +0100 Subject: [PATCH 227/631] python: revert change in expected behaviour --- .../InsecureProtocol.expected | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/python/ql/test/query-tests/Security/CWE-327-InsecureProtocol/InsecureProtocol.expected b/python/ql/test/query-tests/Security/CWE-327-InsecureProtocol/InsecureProtocol.expected index d6bc954de82..c08e19e5f1c 100644 --- a/python/ql/test/query-tests/Security/CWE-327-InsecureProtocol/InsecureProtocol.expected +++ b/python/ql/test/query-tests/Security/CWE-327-InsecureProtocol/InsecureProtocol.expected @@ -12,25 +12,28 @@ | InsecureProtocol.py:24:1:24:35 | ControlFlowNode for SSLContext() | Insecure SSL/TLS protocol version SSLv2 specified by $@. | InsecureProtocol.py:24:1:24:35 | ControlFlowNode for SSLContext() | call to SSLContext | | pyOpenSSL_fluent.py:8:27:8:33 | ControlFlowNode for context | Insecure SSL/TLS protocol version SSLv2 allowed by $@. | pyOpenSSL_fluent.py:6:15:6:44 | ControlFlowNode for Attribute() | call to SSL.Context | | pyOpenSSL_fluent.py:8:27:8:33 | ControlFlowNode for context | Insecure SSL/TLS protocol version SSLv3 allowed by $@. | pyOpenSSL_fluent.py:6:15:6:44 | ControlFlowNode for Attribute() | call to SSL.Context | +| pyOpenSSL_fluent.py:8:27:8:33 | ControlFlowNode for context | Insecure SSL/TLS protocol version TLSv1 allowed by $@. | pyOpenSSL_fluent.py:6:15:6:44 | ControlFlowNode for Attribute() | call to SSL.Context | +| pyOpenSSL_fluent.py:8:27:8:33 | ControlFlowNode for context | Insecure SSL/TLS protocol version TLSv1_1 allowed by $@. | pyOpenSSL_fluent.py:6:15:6:44 | ControlFlowNode for Attribute() | call to SSL.Context | | pyOpenSSL_fluent.py:18:27:18:33 | ControlFlowNode for context | Insecure SSL/TLS protocol version SSLv2 allowed by $@. | pyOpenSSL_fluent.py:15:15:15:44 | ControlFlowNode for Attribute() | call to SSL.Context | | pyOpenSSL_fluent.py:18:27:18:33 | ControlFlowNode for context | Insecure SSL/TLS protocol version SSLv3 allowed by $@. | pyOpenSSL_fluent.py:15:15:15:44 | ControlFlowNode for Attribute() | call to SSL.Context | +| pyOpenSSL_fluent.py:18:27:18:33 | ControlFlowNode for context | Insecure SSL/TLS protocol version TLSv1_1 allowed by $@. | pyOpenSSL_fluent.py:15:15:15:44 | ControlFlowNode for Attribute() | call to SSL.Context | | ssl_fluent.py:9:14:9:20 | ControlFlowNode for context | Insecure SSL/TLS protocol version TLSv1 allowed by $@. | ssl_fluent.py:6:15:6:46 | ControlFlowNode for Attribute() | call to ssl.SSLContext | | ssl_fluent.py:9:14:9:20 | ControlFlowNode for context | Insecure SSL/TLS protocol version TLSv1_1 allowed by $@. | ssl_fluent.py:6:15:6:46 | ControlFlowNode for Attribute() | call to ssl.SSLContext | | ssl_fluent.py:19:14:19:20 | ControlFlowNode for context | Insecure SSL/TLS protocol version TLSv1_1 allowed by $@. | ssl_fluent.py:15:15:15:46 | ControlFlowNode for Attribute() | call to ssl.SSLContext | | ssl_fluent.py:28:14:28:20 | ControlFlowNode for context | Insecure SSL/TLS protocol version TLSv1_1 allowed by $@. | ssl_fluent.py:24:15:24:53 | ControlFlowNode for Attribute() | call to ssl.SSLContext | | ssl_fluent.py:37:14:37:20 | ControlFlowNode for context | Insecure SSL/TLS protocol version TLSv1_1 allowed by $@. | ssl_fluent.py:33:15:33:53 | ControlFlowNode for Attribute() | call to ssl.SSLContext | -| ssl_fluent.py:57:14:57:20 | ControlFlowNode for context | Insecure SSL/TLS protocol version SSLv2 allowed by $@. | ssl_fluent.py:54:15:54:49 | ControlFlowNode for Attribute() | call to ssl.SSLContext | -| ssl_fluent.py:57:14:57:20 | ControlFlowNode for context | Insecure SSL/TLS protocol version SSLv3 allowed by $@. | ssl_fluent.py:54:15:54:49 | ControlFlowNode for Attribute() | call to ssl.SSLContext | +| ssl_fluent.py:57:14:57:20 | ControlFlowNode for context | Insecure SSL/TLS protocol version TLSv1 allowed by $@. | ssl_fluent.py:54:15:54:49 | ControlFlowNode for Attribute() | call to ssl.SSLContext | +| ssl_fluent.py:57:14:57:20 | ControlFlowNode for context | Insecure SSL/TLS protocol version TLSv1_1 allowed by $@. | ssl_fluent.py:54:15:54:49 | ControlFlowNode for Attribute() | call to ssl.SSLContext | | ssl_fluent.py:71:14:71:20 | ControlFlowNode for context | Insecure SSL/TLS protocol version TLSv1 allowed by $@. | ssl_fluent.py:62:12:62:43 | ControlFlowNode for Attribute() | call to ssl.SSLContext | | ssl_fluent.py:71:14:71:20 | ControlFlowNode for context | Insecure SSL/TLS protocol version TLSv1 allowed by $@. | ssl_fluent.py:101:15:101:46 | ControlFlowNode for Attribute() | call to ssl.SSLContext | | ssl_fluent.py:71:14:71:20 | ControlFlowNode for context | Insecure SSL/TLS protocol version TLSv1_1 allowed by $@. | ssl_fluent.py:62:12:62:43 | ControlFlowNode for Attribute() | call to ssl.SSLContext | -| ssl_fluent.py:71:14:71:20 | ControlFlowNode for context | Insecure SSL/TLS protocol version TLSv1_1 allowed by $@. | ssl_fluent.py:65:15:65:46 | ControlFlowNode for Attribute() | call to ssl.SSLContext | | ssl_fluent.py:71:14:71:20 | ControlFlowNode for context | Insecure SSL/TLS protocol version TLSv1_1 allowed by $@. | ssl_fluent.py:101:15:101:46 | ControlFlowNode for Attribute() | call to ssl.SSLContext | -| ssl_fluent.py:71:14:71:20 | ControlFlowNode for context | Insecure SSL/TLS protocol version TLSv1_1 allowed by $@. | ssl_fluent.py:115:15:115:46 | ControlFlowNode for Attribute() | call to ssl.SSLContext | +| ssl_fluent.py:71:14:71:20 | ControlFlowNode for context | Insecure SSL/TLS protocol version TLSv1_1 allowed by $@. | ssl_fluent.py:117:5:117:11 | ControlFlowNode for context | context modification | +| ssl_fluent.py:71:14:71:20 | ControlFlowNode for context | Insecure SSL/TLS protocol version TLSv1_1 allowed by $@. | ssl_fluent.py:135:5:135:11 | ControlFlowNode for context | context modification | | ssl_fluent.py:77:14:77:20 | ControlFlowNode for context | Insecure SSL/TLS protocol version TLSv1 allowed by $@. | ssl_fluent.py:62:12:62:43 | ControlFlowNode for Attribute() | call to ssl.SSLContext | | ssl_fluent.py:77:14:77:20 | ControlFlowNode for context | Insecure SSL/TLS protocol version TLSv1_1 allowed by $@. | ssl_fluent.py:62:12:62:43 | ControlFlowNode for Attribute() | call to ssl.SSLContext | -| ssl_fluent.py:97:14:97:20 | ControlFlowNode for context | Insecure SSL/TLS protocol version TLSv1_1 allowed by $@. | ssl_fluent.py:65:15:65:46 | ControlFlowNode for Attribute() | call to ssl.SSLContext | -| ssl_fluent.py:146:14:146:20 | ControlFlowNode for context | Insecure SSL/TLS protocol version TLSv1_1 allowed by $@. | ssl_fluent.py:142:15:142:46 | ControlFlowNode for Attribute() | call to ssl.SSLContext | -| ssl_fluent.py:165:14:165:20 | ControlFlowNode for context | Insecure SSL/TLS protocol version SSLv3 allowed by $@. | ssl_fluent.py:161:15:161:65 | ControlFlowNode for Attribute() | call to ssl.create_default_context | +| ssl_fluent.py:97:14:97:20 | ControlFlowNode for context | Insecure SSL/TLS protocol version TLSv1_1 allowed by $@. | ssl_fluent.py:95:5:95:11 | ControlFlowNode for context | context modification | +| ssl_fluent.py:146:14:146:20 | ControlFlowNode for context | Insecure SSL/TLS protocol version TLSv1_1 allowed by $@. | ssl_fluent.py:143:5:143:11 | ControlFlowNode for context | context modification | +| ssl_fluent.py:165:14:165:20 | ControlFlowNode for context | Insecure SSL/TLS protocol version SSLv3 allowed by $@. | ssl_fluent.py:162:5:162:11 | ControlFlowNode for context | context modification | | ssl_fluent.py:165:14:165:20 | ControlFlowNode for context | Insecure SSL/TLS protocol version TLSv1 allowed by $@. | ssl_fluent.py:161:15:161:65 | ControlFlowNode for Attribute() | call to ssl.create_default_context | | ssl_fluent.py:165:14:165:20 | ControlFlowNode for context | Insecure SSL/TLS protocol version TLSv1_1 allowed by $@. | ssl_fluent.py:161:15:161:65 | ControlFlowNode for Attribute() | call to ssl.create_default_context | From 2cc8fbaa50b221010af7eab9747e081c33a72178 Mon Sep 17 00:00:00 2001 From: Rasmus Wriedt Larsen Date: Mon, 6 Mar 2023 14:48:48 +0100 Subject: [PATCH 228/631] Python: Accept changes due to better import resolution of `operator.py` --- python/ql/test/experimental/dataflow/coverage/classes.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/python/ql/test/experimental/dataflow/coverage/classes.py b/python/ql/test/experimental/dataflow/coverage/classes.py index d74a632b7c3..664adedcc00 100644 --- a/python/ql/test/experimental/dataflow/coverage/classes.py +++ b/python/ql/test/experimental/dataflow/coverage/classes.py @@ -546,7 +546,7 @@ class With_length_hint: def test_length_hint(): import operator - with_length_hint = With_length_hint() #$ MISSING: arg1="SSA variable with_length_hint" func=With_length_hint.__length_hint__ + with_length_hint = With_length_hint() #$ arg1="SSA variable with_length_hint" func=With_length_hint.__length_hint__ operator.length_hint(with_length_hint) @@ -1381,7 +1381,7 @@ class With_index: def test_index(): import operator - with_index = With_index() #$ MISSING: arg1="SSA variable with_index" func=With_index.__index__ + with_index = With_index() #$ arg1="SSA variable with_index" func=With_index.__index__ operator.index(with_index) From 8160f742a59297752236183678d9863724fb42c0 Mon Sep 17 00:00:00 2001 From: Rasmus Lerchedahl Petersen Date: Mon, 6 Mar 2023 19:47:53 +0100 Subject: [PATCH 229/631] Python: small clean-up - no need for th 2-suffix - context creations are no longer unrestrictions --- python/ql/src/Security/CWE-327/FluentApiModel.qll | 4 ++-- python/ql/src/Security/CWE-327/PyOpenSSL.qll | 4 +--- python/ql/src/Security/CWE-327/Ssl.qll | 4 ---- 3 files changed, 3 insertions(+), 9 deletions(-) diff --git a/python/ql/src/Security/CWE-327/FluentApiModel.qll b/python/ql/src/Security/CWE-327/FluentApiModel.qll index 3f479bc1627..2e6f9ffd398 100644 --- a/python/ql/src/Security/CWE-327/FluentApiModel.qll +++ b/python/ql/src/Security/CWE-327/FluentApiModel.qll @@ -20,7 +20,7 @@ import TlsLibraryModel * Since we really want "the last unrestriction, not nullified by a restriction", * we also disallow flow into restrictions. */ -module InsecureContextConfiguration2 implements DataFlow::StateConfigSig { +module InsecureContextConfiguration implements DataFlow::StateConfigSig { private newtype TFlowState = TMkFlowState(TlsLibrary library, int bits) { bits in [0 .. max(any(ProtocolVersion v).getBit()) * 2 - 1] @@ -112,7 +112,7 @@ module InsecureContextConfiguration2 implements DataFlow::StateConfigSig { } } -private module InsecureContextFlow = DataFlow::MakeWithState; +private module InsecureContextFlow = DataFlow::MakeWithState; /** * Holds if `conectionCreation` marks the creation of a connection based on the contex diff --git a/python/ql/src/Security/CWE-327/PyOpenSSL.qll b/python/ql/src/Security/CWE-327/PyOpenSSL.qll index 534f7c474e5..a156323fc2e 100644 --- a/python/ql/src/Security/CWE-327/PyOpenSSL.qll +++ b/python/ql/src/Security/CWE-327/PyOpenSSL.qll @@ -79,7 +79,5 @@ class PyOpenSsl extends TlsLibrary { override ProtocolRestriction protocol_restriction() { result instanceof SetOptionsCall } - override ProtocolUnrestriction protocol_unrestriction() { - result instanceof UnspecificPyOpenSslContextCreation - } + override ProtocolUnrestriction protocol_unrestriction() { none() } } diff --git a/python/ql/src/Security/CWE-327/Ssl.qll b/python/ql/src/Security/CWE-327/Ssl.qll index 0f2ce77acc7..58a4721a3ea 100644 --- a/python/ql/src/Security/CWE-327/Ssl.qll +++ b/python/ql/src/Security/CWE-327/Ssl.qll @@ -217,9 +217,5 @@ class Ssl extends TlsLibrary { result instanceof OptionsAugAndNot or result instanceof ContextSetVersion - or - result instanceof UnspecificSslContextCreation - or - result instanceof UnspecificSslDefaultContextCreation } } From 072df5dbc09185f151634a4c99726f2030525e06 Mon Sep 17 00:00:00 2001 From: Rasmus Lerchedahl Petersen Date: Tue, 7 Mar 2023 14:41:13 +0100 Subject: [PATCH 230/631] python: remove protocol family this concept was due to my confusion between TLS and SSL23, but they are aliases. We might want to bring back the concept if we model DTLS. Also, model what exactly creations allow, bring this back from the unrestrictions they used to be. We accept the changes regarding sources being reported differently. --- .../src/Security/CWE-327/FluentApiModel.qll | 11 +++- python/ql/src/Security/CWE-327/PyOpenSSL.qll | 31 ++++++---- python/ql/src/Security/CWE-327/Ssl.qll | 55 ++++++++--------- .../src/Security/CWE-327/TlsLibraryModel.qll | 60 +++++++++---------- .../InsecureProtocol.expected | 10 ++-- 5 files changed, 85 insertions(+), 82 deletions(-) diff --git a/python/ql/src/Security/CWE-327/FluentApiModel.qll b/python/ql/src/Security/CWE-327/FluentApiModel.qll index 2e6f9ffd398..3d63cab940e 100644 --- a/python/ql/src/Security/CWE-327/FluentApiModel.qll +++ b/python/ql/src/Security/CWE-327/FluentApiModel.qll @@ -61,9 +61,14 @@ module InsecureContextConfiguration implements DataFlow::StateConfigSig { } predicate isSource(DataFlow::Node source, FlowState state) { - exists(ProtocolFamily family | - source = state.getLibrary().unspecific_context_creation(family) and - state.getBits() = family.getBits() + exists(ContextCreation creation | source = creation | + creation = state.getLibrary().unspecific_context_creation() and + state.getBits() = + sum(ProtocolVersion version | + version = creation.getProtocol() and version.isInsecure() + | + version.getBit() + ) ) } diff --git a/python/ql/src/Security/CWE-327/PyOpenSSL.qll b/python/ql/src/Security/CWE-327/PyOpenSSL.qll index a156323fc2e..9b685ecfd1c 100644 --- a/python/ql/src/Security/CWE-327/PyOpenSSL.qll +++ b/python/ql/src/Security/CWE-327/PyOpenSSL.qll @@ -12,14 +12,18 @@ class PyOpenSslContextCreation extends ContextCreation, DataFlow::CallCfgNode { this = API::moduleImport("OpenSSL").getMember("SSL").getMember("Context").getACall() } - override string getProtocol() { + override ProtocolVersion getProtocol() { exists(DataFlow::Node protocolArg, PyOpenSsl pyo | protocolArg in [this.getArg(0), this.getArgByName("method")] | - protocolArg in [ - pyo.specific_version(result).getAValueReachableFromSource(), - pyo.unspecific_version(result).getAValueReachableFromSource() - ] + protocolArg = pyo.specific_version(result).getAValueReachableFromSource() + or + protocolArg = pyo.unspecific_version().getAValueReachableFromSource() and + // PyOpenSSL also allows DTLS + // see https://www.pyopenssl.org/en/stable/api/ssl.html#OpenSSL.SSL.Context + // although they are not mentioned here: + // https://www.pyopenssl.org/en/stable/api/ssl.html#OpenSSL.SSL.TLS_METHOD + result = any(ProtocolVersion pv) ) } } @@ -51,18 +55,21 @@ class SetOptionsCall extends ProtocolRestriction, DataFlow::CallCfgNode { } } -class UnspecificPyOpenSslContextCreation extends PyOpenSslContextCreation, UnspecificContextCreation { - // UnspecificPyOpenSslContextCreation() { library instanceof PyOpenSsl } -} - +// class UnspecificPyOpenSslContextCreation extends PyOpenSslContextCreation, UnspecificContextCreation { +// override ProtocolVersion getProtocol() { result = PyOpenSslContextCreation.super.getProtocol() } +// } class PyOpenSsl extends TlsLibrary { PyOpenSsl() { this = "pyOpenSSL" } override string specific_version_name(ProtocolVersion version) { result = version + "_METHOD" } - override string unspecific_version_name(ProtocolFamily family) { - // `"TLS_METHOD"` is not actually available in pyOpenSSL yet, but should be coming soon.. - result = family + "_METHOD" + override string unspecific_version_name() { + // See + // - https://www.pyopenssl.org/en/23.0.0/api/ssl.html#module-OpenSSL.SSL + // - https://www.openssl.org/docs/manmaster/man3/DTLS_server_method.html#NOTES + result = ["TLS", "SSLv23"] + "_METHOD" + or + result = "TLS_" + ["CLIENT", "SERVER"] + "_METHOD" } override API::Node version_constants() { result = API::moduleImport("OpenSSL").getMember("SSL") } diff --git a/python/ql/src/Security/CWE-327/Ssl.qll b/python/ql/src/Security/CWE-327/Ssl.qll index 58a4721a3ea..c3fd0366436 100644 --- a/python/ql/src/Security/CWE-327/Ssl.qll +++ b/python/ql/src/Security/CWE-327/Ssl.qll @@ -10,20 +10,21 @@ import TlsLibraryModel class SslContextCreation extends ContextCreation, DataFlow::CallCfgNode { SslContextCreation() { this = API::moduleImport("ssl").getMember("SSLContext").getACall() } - override string getProtocol() { + override ProtocolVersion getProtocol() { exists(DataFlow::Node protocolArg, Ssl ssl | protocolArg in [this.getArg(0), this.getArgByName("protocol")] | - protocolArg = - [ - ssl.specific_version(result).getAValueReachableFromSource(), - ssl.unspecific_version(result).getAValueReachableFromSource() - ] + protocolArg = ssl.specific_version(result).getAValueReachableFromSource() + or + protocolArg = ssl.unspecific_version().getAValueReachableFromSource() and + // see https://docs.python.org/3/library/ssl.html#id7 + result in ["TLSv1", "TLSv1_1", "TLSv1_2", "TLSv1_3"] ) or not exists(this.getArg(_)) and not exists(this.getArgByName(_)) and - result = "TLS" + // see https://docs.python.org/3/library/ssl.html#id7 + result in ["TLSv1", "TLSv1_1", "TLSv1_2", "TLSv1_3"] } } @@ -34,7 +35,7 @@ class SslDefaultContextCreation extends ContextCreation { // Allowed insecure versions are "TLSv1" and "TLSv1_1" // see https://docs.python.org/3/library/ssl.html#context-creation - override string getProtocol() { result = "TLS" } + override ProtocolVersion getProtocol() { result in ["TLSv1", "TLSv1_1", "TLSv1_2", "TLSv1_3"] } } /** Gets a reference to an `ssl.Context` instance. */ @@ -161,33 +162,29 @@ class ContextSetVersion extends ProtocolRestriction, ProtocolUnrestriction, Data } } -class UnspecificSslContextCreation extends SslContextCreation, UnspecificContextCreation { - // UnspecificSslContextCreation() { library instanceof Ssl } - // override ProtocolVersion getUnrestriction() { - // result = UnspecificContextCreation.super.getUnrestriction() and - // // These are turned off by default since Python 3.6 - // // see https://docs.python.org/3.6/library/ssl.html#ssl.SSLContext - // not result in ["SSLv2", "SSLv3"] - // } -} - -class UnspecificSslDefaultContextCreation extends SslDefaultContextCreation { - // override DataFlow::Node getContext() { result = this } - // // see https://docs.python.org/3/library/ssl.html#ssl.create_default_context - // override ProtocolVersion getUnrestriction() { - // result in ["TLSv1", "TLSv1_1", "TLSv1_2", "TLSv1_3"] - // } -} - +// class UnspecificSslContextCreation extends SslContextCreation, UnspecificContextCreation { +// // UnspecificSslContextCreation() { library instanceof Ssl } +// override ProtocolVersion getProtocol() { +// result = UnspecificContextCreation.super.getProtocol() and +// // These are turned off by default since Python 3.6 +// // see https://docs.python.org/3.6/library/ssl.html#ssl.SSLContext +// not result in ["SSLv2", "SSLv3"] +// } +// } +// class UnspecificSslDefaultContextCreation extends SslDefaultContextCreation { +// // override DataFlow::Node getContext() { result = this } +// // see https://docs.python.org/3/library/ssl.html#ssl.create_default_context +// override ProtocolVersion getProtocol() { result in ["TLSv1", "TLSv1_1", "TLSv1_2", "TLSv1_3"] } +// } class Ssl extends TlsLibrary { Ssl() { this = "ssl" } override string specific_version_name(ProtocolVersion version) { result = "PROTOCOL_" + version } - override string unspecific_version_name(ProtocolFamily family) { - family = "SSLv23" and result = "PROTOCOL_" + family + override string unspecific_version_name() { + result = "PROTOCOL_SSLv23" or - family = "TLS" and result = "PROTOCOL_" + family + ["", "_CLIENT", "_SERVER"] + result = "PROTOCOL_TLS" + ["", "_CLIENT", "_SERVER"] } override API::Node version_constants() { result = API::moduleImport("ssl") } diff --git a/python/ql/src/Security/CWE-327/TlsLibraryModel.qll b/python/ql/src/Security/CWE-327/TlsLibraryModel.qll index b45fa24a870..1e99755c1a9 100644 --- a/python/ql/src/Security/CWE-327/TlsLibraryModel.qll +++ b/python/ql/src/Security/CWE-327/TlsLibraryModel.qll @@ -37,29 +37,23 @@ class ProtocolVersion extends string { or this = "TLSv1_3" and result = 32 } - - /** Gets the protocol family for this protocol version. */ - ProtocolFamily getFamily() { - result = "SSLv23" and this in ["SSLv2", "SSLv3"] - or - result = "TLS" and this in ["TLSv1", "TLSv1_1", "TLSv1_2", "TLSv1_3"] - } -} - -/** An unspecific protocol version */ -class ProtocolFamily extends string { - ProtocolFamily() { this in ["SSLv23", "TLS"] } - - /** Gets the bit mask for this protocol family. */ - int getBits() { - result = sum(ProtocolVersion version | version.getFamily() = this | version.getBit()) - } } /** The creation of a context. */ abstract class ContextCreation extends DataFlow::Node { - /** Gets the protocol version or family for this context. */ - abstract string getProtocol(); + /** + * Gets the protocol version for this context. + * There can be multiple values if the context was created + * using a non-specific version such as `TLS`. + */ + abstract ProtocolVersion getProtocol(); + + /** + * Holds if the context was created with a specific version + * rather than with a version flexible method, see: + * https://www.openssl.org/docs/manmaster/man3/DTLS_server_method.html#NOTES + */ + predicate specificVersion() { count(this.getProtocol()) = 1 } } /** The creation of a connection from a context. */ @@ -91,13 +85,12 @@ abstract class ProtocolUnrestriction extends DataFlow::Node { * This also serves as unrestricting these protocols. */ abstract class UnspecificContextCreation extends ContextCreation { - // override ProtocolVersion getUnrestriction() { - // // There is only one family, the two names are aliases in OpenSSL. - // // see https://github.com/openssl/openssl/blob/13888e797c5a3193e91d71e5f5a196a2d68d266f/include/openssl/ssl.h.in#L1953-L1955 - // family in ["SSLv23", "TLS"] and - // // see https://docs.python.org/3/library/ssl.html#ssl-contexts - // result in ["SSLv2", "SSLv3", "TLSv1", "TLSv1_1", "TLSv1_2", "TLSv1_3"] - // } + override ProtocolVersion getProtocol() { + // There is only one family, the two names are aliases in OpenSSL. + // see https://github.com/openssl/openssl/blob/13888e797c5a3193e91d71e5f5a196a2d68d266f/include/openssl/ssl.h.in#L1953-L1955 + // see https://docs.python.org/3/library/ssl.html#ssl-contexts + result in ["SSLv2", "SSLv3", "TLSv1", "TLSv1_1", "TLSv1_2", "TLSv1_3"] + } } /** A model of a SSL/TLS library. */ @@ -108,8 +101,8 @@ abstract class TlsLibrary extends string { /** Gets the name of a specific protocol version. */ abstract string specific_version_name(ProtocolVersion version); - /** Gets a name, which is a member of `version_constants`, that can be used to specify the protocol family `family`. */ - abstract string unspecific_version_name(ProtocolFamily family); + /** Gets a name, which is a member of `version_constants`, that can be used to specify the entire protocol family. */ + abstract string unspecific_version_name(); /** Gets an API node representing the module or class holding the version constants. */ abstract API::Node version_constants(); @@ -119,9 +112,9 @@ abstract class TlsLibrary extends string { result = this.version_constants().getMember(this.specific_version_name(version)) } - /** Gets an API node representing the protocol family `family`. */ - API::Node unspecific_version(ProtocolFamily family) { - result = this.version_constants().getMember(this.unspecific_version_name(family)) + /** Gets an API node representing the protocol entire family. */ + API::Node unspecific_version() { + result = this.version_constants().getMember(this.unspecific_version_name()) } /** Gets a creation of a context with a default protocol. */ @@ -133,14 +126,15 @@ abstract class TlsLibrary extends string { /** Gets a creation of a context with a specific protocol version, known to be insecure. */ ContextCreation insecure_context_creation(ProtocolVersion version) { result in [this.specific_context_creation(), this.default_context_creation()] and + result.specificVersion() and result.getProtocol() = version and version.isInsecure() } /** Gets a context that was created using `family`, known to have insecure instances. */ - ContextCreation unspecific_context_creation(ProtocolFamily family) { + ContextCreation unspecific_context_creation() { result in [this.specific_context_creation(), this.default_context_creation()] and - result.getProtocol() = family + not result.specificVersion() } /** Gets a dataflow node representing a connection being created in an insecure manner, not from a context. */ diff --git a/python/ql/test/query-tests/Security/CWE-327-InsecureProtocol/InsecureProtocol.expected b/python/ql/test/query-tests/Security/CWE-327-InsecureProtocol/InsecureProtocol.expected index c08e19e5f1c..3e889d20f57 100644 --- a/python/ql/test/query-tests/Security/CWE-327-InsecureProtocol/InsecureProtocol.expected +++ b/python/ql/test/query-tests/Security/CWE-327-InsecureProtocol/InsecureProtocol.expected @@ -27,13 +27,13 @@ | ssl_fluent.py:71:14:71:20 | ControlFlowNode for context | Insecure SSL/TLS protocol version TLSv1 allowed by $@. | ssl_fluent.py:62:12:62:43 | ControlFlowNode for Attribute() | call to ssl.SSLContext | | ssl_fluent.py:71:14:71:20 | ControlFlowNode for context | Insecure SSL/TLS protocol version TLSv1 allowed by $@. | ssl_fluent.py:101:15:101:46 | ControlFlowNode for Attribute() | call to ssl.SSLContext | | ssl_fluent.py:71:14:71:20 | ControlFlowNode for context | Insecure SSL/TLS protocol version TLSv1_1 allowed by $@. | ssl_fluent.py:62:12:62:43 | ControlFlowNode for Attribute() | call to ssl.SSLContext | +| ssl_fluent.py:71:14:71:20 | ControlFlowNode for context | Insecure SSL/TLS protocol version TLSv1_1 allowed by $@. | ssl_fluent.py:65:15:65:46 | ControlFlowNode for Attribute() | call to ssl.SSLContext | | ssl_fluent.py:71:14:71:20 | ControlFlowNode for context | Insecure SSL/TLS protocol version TLSv1_1 allowed by $@. | ssl_fluent.py:101:15:101:46 | ControlFlowNode for Attribute() | call to ssl.SSLContext | -| ssl_fluent.py:71:14:71:20 | ControlFlowNode for context | Insecure SSL/TLS protocol version TLSv1_1 allowed by $@. | ssl_fluent.py:117:5:117:11 | ControlFlowNode for context | context modification | -| ssl_fluent.py:71:14:71:20 | ControlFlowNode for context | Insecure SSL/TLS protocol version TLSv1_1 allowed by $@. | ssl_fluent.py:135:5:135:11 | ControlFlowNode for context | context modification | +| ssl_fluent.py:71:14:71:20 | ControlFlowNode for context | Insecure SSL/TLS protocol version TLSv1_1 allowed by $@. | ssl_fluent.py:115:15:115:46 | ControlFlowNode for Attribute() | call to ssl.SSLContext | | ssl_fluent.py:77:14:77:20 | ControlFlowNode for context | Insecure SSL/TLS protocol version TLSv1 allowed by $@. | ssl_fluent.py:62:12:62:43 | ControlFlowNode for Attribute() | call to ssl.SSLContext | | ssl_fluent.py:77:14:77:20 | ControlFlowNode for context | Insecure SSL/TLS protocol version TLSv1_1 allowed by $@. | ssl_fluent.py:62:12:62:43 | ControlFlowNode for Attribute() | call to ssl.SSLContext | -| ssl_fluent.py:97:14:97:20 | ControlFlowNode for context | Insecure SSL/TLS protocol version TLSv1_1 allowed by $@. | ssl_fluent.py:95:5:95:11 | ControlFlowNode for context | context modification | -| ssl_fluent.py:146:14:146:20 | ControlFlowNode for context | Insecure SSL/TLS protocol version TLSv1_1 allowed by $@. | ssl_fluent.py:143:5:143:11 | ControlFlowNode for context | context modification | -| ssl_fluent.py:165:14:165:20 | ControlFlowNode for context | Insecure SSL/TLS protocol version SSLv3 allowed by $@. | ssl_fluent.py:162:5:162:11 | ControlFlowNode for context | context modification | +| ssl_fluent.py:97:14:97:20 | ControlFlowNode for context | Insecure SSL/TLS protocol version TLSv1_1 allowed by $@. | ssl_fluent.py:65:15:65:46 | ControlFlowNode for Attribute() | call to ssl.SSLContext | +| ssl_fluent.py:146:14:146:20 | ControlFlowNode for context | Insecure SSL/TLS protocol version TLSv1_1 allowed by $@. | ssl_fluent.py:142:15:142:46 | ControlFlowNode for Attribute() | call to ssl.SSLContext | +| ssl_fluent.py:165:14:165:20 | ControlFlowNode for context | Insecure SSL/TLS protocol version SSLv3 allowed by $@. | ssl_fluent.py:161:15:161:65 | ControlFlowNode for Attribute() | call to ssl.create_default_context | | ssl_fluent.py:165:14:165:20 | ControlFlowNode for context | Insecure SSL/TLS protocol version TLSv1 allowed by $@. | ssl_fluent.py:161:15:161:65 | ControlFlowNode for Attribute() | call to ssl.create_default_context | | ssl_fluent.py:165:14:165:20 | ControlFlowNode for context | Insecure SSL/TLS protocol version TLSv1_1 allowed by $@. | ssl_fluent.py:161:15:161:65 | ControlFlowNode for Attribute() | call to ssl.create_default_context | From da338c26baf6e198258948eee54857e4bbb13149 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Thu, 23 Feb 2023 19:20:47 +0000 Subject: [PATCH 231/631] Swift: Add a few more test cases for sensitive data. --- .../CWE-311/CleartextStorageDatabase.expected | 20 ++++++++++++++ .../Security/CWE-311/SensitiveExprs.expected | 10 +++++++ .../Security/CWE-311/testCoreData2.swift | 27 +++++++++++++++++++ 3 files changed, 57 insertions(+) diff --git a/swift/ql/test/query-tests/Security/CWE-311/CleartextStorageDatabase.expected b/swift/ql/test/query-tests/Security/CWE-311/CleartextStorageDatabase.expected index 2afbfed846b..6c336a380e0 100644 --- a/swift/ql/test/query-tests/Security/CWE-311/CleartextStorageDatabase.expected +++ b/swift/ql/test/query-tests/Security/CWE-311/CleartextStorageDatabase.expected @@ -28,6 +28,13 @@ edges | testCoreData2.swift:62:30:62:30 | bankAccountNo : | testCoreData2.swift:62:4:62:4 | [post] obj [myBankAccountNumber] : | | testCoreData2.swift:65:3:65:3 | [post] obj [myBankAccountNumber] : | testCoreData2.swift:65:3:65:3 | [post] obj | | testCoreData2.swift:65:29:65:29 | bankAccountNo : | testCoreData2.swift:65:3:65:3 | [post] obj [myBankAccountNumber] : | +| testCoreData2.swift:79:2:79:2 | [post] dbObj [myValue] : | testCoreData2.swift:79:2:79:2 | [post] dbObj | +| testCoreData2.swift:79:18:79:28 | .bankAccountNo : | testCoreData2.swift:79:2:79:2 | [post] dbObj [myValue] : | +| testCoreData2.swift:80:2:80:2 | [post] dbObj [myValue] : | testCoreData2.swift:80:2:80:2 | [post] dbObj | +| testCoreData2.swift:80:18:80:28 | ...! : | testCoreData2.swift:80:2:80:2 | [post] dbObj [myValue] : | +| testCoreData2.swift:80:18:80:28 | .bankAccountNo2 : | testCoreData2.swift:80:18:80:28 | ...! : | +| testCoreData2.swift:87:2:87:10 | [post] ...? [myValue] : | testCoreData2.swift:87:2:87:10 | [post] ...? | +| testCoreData2.swift:87:22:87:32 | .bankAccountNo : | testCoreData2.swift:87:2:87:10 | [post] ...? [myValue] : | | testCoreData.swift:18:19:18:26 | value : | testCoreData.swift:19:12:19:12 | value | | testCoreData.swift:31:3:31:3 | newValue : | testCoreData.swift:32:13:32:13 | newValue | | testCoreData.swift:61:25:61:25 | password : | testCoreData.swift:18:19:18:26 | value : | @@ -145,6 +152,16 @@ nodes | testCoreData2.swift:65:3:65:3 | [post] obj | semmle.label | [post] obj | | testCoreData2.swift:65:3:65:3 | [post] obj [myBankAccountNumber] : | semmle.label | [post] obj [myBankAccountNumber] : | | testCoreData2.swift:65:29:65:29 | bankAccountNo : | semmle.label | bankAccountNo : | +| testCoreData2.swift:79:2:79:2 | [post] dbObj | semmle.label | [post] dbObj | +| testCoreData2.swift:79:2:79:2 | [post] dbObj [myValue] : | semmle.label | [post] dbObj [myValue] : | +| testCoreData2.swift:79:18:79:28 | .bankAccountNo : | semmle.label | .bankAccountNo : | +| testCoreData2.swift:80:2:80:2 | [post] dbObj | semmle.label | [post] dbObj | +| testCoreData2.swift:80:2:80:2 | [post] dbObj [myValue] : | semmle.label | [post] dbObj [myValue] : | +| testCoreData2.swift:80:18:80:28 | ...! : | semmle.label | ...! : | +| testCoreData2.swift:80:18:80:28 | .bankAccountNo2 : | semmle.label | .bankAccountNo2 : | +| testCoreData2.swift:87:2:87:10 | [post] ...? | semmle.label | [post] ...? | +| testCoreData2.swift:87:2:87:10 | [post] ...? [myValue] : | semmle.label | [post] ...? [myValue] : | +| testCoreData2.swift:87:22:87:32 | .bankAccountNo : | semmle.label | .bankAccountNo : | | testCoreData.swift:18:19:18:26 | value : | semmle.label | value : | | testCoreData.swift:19:12:19:12 | value | semmle.label | value | | testCoreData.swift:31:3:31:3 | newValue : | semmle.label | newValue : | @@ -302,6 +319,9 @@ subpaths | testCoreData2.swift:60:4:60:4 | obj | testCoreData2.swift:60:30:60:30 | bankAccountNo : | testCoreData2.swift:60:4:60:4 | [post] obj | This operation stores '[post] obj' in a database. It may contain unencrypted sensitive data from $@. | testCoreData2.swift:60:30:60:30 | bankAccountNo : | bankAccountNo | | testCoreData2.swift:62:4:62:4 | obj | testCoreData2.swift:62:30:62:30 | bankAccountNo : | testCoreData2.swift:62:4:62:4 | [post] obj | This operation stores '[post] obj' in a database. It may contain unencrypted sensitive data from $@. | testCoreData2.swift:62:30:62:30 | bankAccountNo : | bankAccountNo | | testCoreData2.swift:65:3:65:3 | obj | testCoreData2.swift:65:29:65:29 | bankAccountNo : | testCoreData2.swift:65:3:65:3 | [post] obj | This operation stores '[post] obj' in a database. It may contain unencrypted sensitive data from $@. | testCoreData2.swift:65:29:65:29 | bankAccountNo : | bankAccountNo | +| testCoreData2.swift:79:2:79:2 | dbObj | testCoreData2.swift:79:18:79:28 | .bankAccountNo : | testCoreData2.swift:79:2:79:2 | [post] dbObj | This operation stores '[post] dbObj' in a database. It may contain unencrypted sensitive data from $@. | testCoreData2.swift:79:18:79:28 | .bankAccountNo : | .bankAccountNo | +| testCoreData2.swift:80:2:80:2 | dbObj | testCoreData2.swift:80:18:80:28 | .bankAccountNo2 : | testCoreData2.swift:80:2:80:2 | [post] dbObj | This operation stores '[post] dbObj' in a database. It may contain unencrypted sensitive data from $@. | testCoreData2.swift:80:18:80:28 | .bankAccountNo2 : | .bankAccountNo2 | +| testCoreData2.swift:87:2:87:10 | ...? | testCoreData2.swift:87:22:87:32 | .bankAccountNo : | testCoreData2.swift:87:2:87:10 | [post] ...? | This operation stores '[post] ...?' in a database. It may contain unencrypted sensitive data from $@. | testCoreData2.swift:87:22:87:32 | .bankAccountNo : | .bankAccountNo | | testCoreData.swift:19:12:19:12 | value | testCoreData.swift:61:25:61:25 | password : | testCoreData.swift:19:12:19:12 | value | This operation stores 'value' in a database. It may contain unencrypted sensitive data from $@. | testCoreData.swift:61:25:61:25 | password : | password | | testCoreData.swift:32:13:32:13 | newValue | testCoreData.swift:64:16:64:16 | password : | testCoreData.swift:32:13:32:13 | newValue | This operation stores 'newValue' in a database. It may contain unencrypted sensitive data from $@. | testCoreData.swift:64:16:64:16 | password : | password | | testCoreData.swift:48:15:48:15 | password | testCoreData.swift:48:15:48:15 | password | testCoreData.swift:48:15:48:15 | password | This operation stores 'password' in a database. It may contain unencrypted sensitive data from $@. | testCoreData.swift:48:15:48:15 | password | password | 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 8243711db6a..9a80108ad02 100644 --- a/swift/ql/test/query-tests/Security/CWE-311/SensitiveExprs.expected +++ b/swift/ql/test/query-tests/Security/CWE-311/SensitiveExprs.expected @@ -36,6 +36,16 @@ | testCoreData2.swift:62:30:62:30 | bankAccountNo | label:bankAccountNo, type:private information | | testCoreData2.swift:65:3:65:7 | .myBankAccountNumber | label:myBankAccountNumber, type:private information | | testCoreData2.swift:65:29:65:29 | bankAccountNo | label:bankAccountNo, type:private information | +| testCoreData2.swift:79:18:79:28 | .bankAccountNo | label:bankAccountNo, type:private information | +| testCoreData2.swift:80:18:80:28 | .bankAccountNo2 | label:bankAccountNo2, type:private information | +| testCoreData2.swift:82:18:82:18 | bankAccountNo | label:bankAccountNo, type:private information | +| testCoreData2.swift:83:18:83:18 | bankAccountNo | label:bankAccountNo, type:private information | +| testCoreData2.swift:84:18:84:18 | bankAccountNo2 | label:bankAccountNo2, type:private information | +| testCoreData2.swift:85:18:85:18 | bankAccountNo2 | label:bankAccountNo2, type:private information | +| testCoreData2.swift:87:22:87:32 | .bankAccountNo | label:bankAccountNo, type:private information | +| testCoreData2.swift:88:22:88:22 | bankAccountNo | label:bankAccountNo, type:private information | +| testCoreData2.swift:89:22:89:22 | bankAccountNo2 | label:bankAccountNo2, type:private information | +| testCoreData2.swift:91:10:91:10 | bankAccountNo | label:bankAccountNo, type:private information | | 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/testCoreData2.swift b/swift/ql/test/query-tests/Security/CWE-311/testCoreData2.swift index 25121dbdb51..ee92de17b70 100644 --- a/swift/ql/test/query-tests/Security/CWE-311/testCoreData2.swift +++ b/swift/ql/test/query-tests/Security/CWE-311/testCoreData2.swift @@ -65,3 +65,30 @@ class testCoreData2_2 { obj.myBankAccountNumber = bankAccountNo // BAD } } + +class MyContainer { + var value: Int = 0 + var value2: Int! = 0 + var bankAccountNo: Int = 0 + var bankAccountNo2: Int! = 0 +} + +func testCoreData2_3(dbObj: MyManagedObject2, maybeObj: MyManagedObject2?, container: MyContainer, bankAccountNo: MyContainer, bankAccountNo2: MyContainer!) { + dbObj.myValue = container.value // GOOD (not sensitive) + dbObj.myValue = container.value2 // GOOD (not sensitive) + dbObj.myValue = container.bankAccountNo // BAD + dbObj.myValue = container.bankAccountNo2 // BAD + + dbObj.myValue = bankAccountNo.value // BAD [NOT DETECTED] + dbObj.myValue = bankAccountNo.value2 // BAD [NOT DETECTED] + dbObj.myValue = bankAccountNo2.value // BAD [NOT DETECTED] + dbObj.myValue = bankAccountNo2.value2 // BAD [NOT DETECTED] + + maybeObj?.myValue = container.bankAccountNo // BAD + maybeObj?.myValue = bankAccountNo.value // BAD [NOT DETECTED] + maybeObj?.myValue = bankAccountNo2.value2 // BAD [NOT DETECTED] + + var a = bankAccountNo // sensitive + var b = a.value + dbObj.myValue = b // BAD [NOT DETECTED] +} From ffa279e87b1af5d405a463ef867470acbbfd5b6a Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Thu, 9 Mar 2023 11:45:57 +0000 Subject: [PATCH 232/631] Swift: Add additional taint steps into fields. ed --- .../CleartextStorageDatabaseExtensions.qll | 9 +- .../CWE-311/CleartextStorageDatabase.expected | 97 +++++++++++++++++++ .../Security/CWE-311/testCoreData2.swift | 14 +-- 3 files changed, 112 insertions(+), 8 deletions(-) diff --git a/swift/ql/lib/codeql/swift/security/CleartextStorageDatabaseExtensions.qll b/swift/ql/lib/codeql/swift/security/CleartextStorageDatabaseExtensions.qll index 9485f27510d..4fb19373956 100644 --- a/swift/ql/lib/codeql/swift/security/CleartextStorageDatabaseExtensions.qll +++ b/swift/ql/lib/codeql/swift/security/CleartextStorageDatabaseExtensions.qll @@ -122,14 +122,21 @@ private class CleartextStorageDatabaseEncryptionSanitizer extends CleartextStora /** * An additional taint step for cleartext database storage vulnerabilities. - * Needed until we have proper content flow through arrays. */ private class CleartextStorageDatabaseArrayAdditionalTaintStep extends CleartextStorageDatabaseAdditionalTaintStep { override predicate step(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) { + // needed until we have proper content flow through arrays. exists(ArrayExpr arr | nodeFrom.asExpr() = arr.getAnElement() and nodeTo.asExpr() = arr ) + or + // if an object is sensitive, its fields are always sensitive + // (this is needed because the sensitive data sources are in a sense + // approximate; for example we might identify `passwordBox` as a source, + // whereas it is more accurate to say that `passwordBox.textField` is the + // true source). + nodeTo.asExpr().(LookupExpr).getBase() = nodeFrom.asExpr() } } diff --git a/swift/ql/test/query-tests/Security/CWE-311/CleartextStorageDatabase.expected b/swift/ql/test/query-tests/Security/CWE-311/CleartextStorageDatabase.expected index 6c336a380e0..ae6c111d392 100644 --- a/swift/ql/test/query-tests/Security/CWE-311/CleartextStorageDatabase.expected +++ b/swift/ql/test/query-tests/Security/CWE-311/CleartextStorageDatabase.expected @@ -28,13 +28,56 @@ edges | testCoreData2.swift:62:30:62:30 | bankAccountNo : | testCoreData2.swift:62:4:62:4 | [post] obj [myBankAccountNumber] : | | testCoreData2.swift:65:3:65:3 | [post] obj [myBankAccountNumber] : | testCoreData2.swift:65:3:65:3 | [post] obj | | testCoreData2.swift:65:29:65:29 | bankAccountNo : | testCoreData2.swift:65:3:65:3 | [post] obj [myBankAccountNumber] : | +| testCoreData2.swift:70:9:70:9 | self : | file://:0:0:0:0 | .value : | +| testCoreData2.swift:71:9:71:9 | self : | file://:0:0:0:0 | .value2 : | | testCoreData2.swift:79:2:79:2 | [post] dbObj [myValue] : | testCoreData2.swift:79:2:79:2 | [post] dbObj | | testCoreData2.swift:79:18:79:28 | .bankAccountNo : | testCoreData2.swift:79:2:79:2 | [post] dbObj [myValue] : | | testCoreData2.swift:80:2:80:2 | [post] dbObj [myValue] : | testCoreData2.swift:80:2:80:2 | [post] dbObj | | testCoreData2.swift:80:18:80:28 | ...! : | testCoreData2.swift:80:2:80:2 | [post] dbObj [myValue] : | | testCoreData2.swift:80:18:80:28 | .bankAccountNo2 : | testCoreData2.swift:80:18:80:28 | ...! : | +| testCoreData2.swift:82:2:82:2 | [post] dbObj [myValue] : | testCoreData2.swift:82:2:82:2 | [post] dbObj | +| testCoreData2.swift:82:18:82:18 | bankAccountNo : | testCoreData2.swift:70:9:70:9 | self : | +| testCoreData2.swift:82:18:82:18 | bankAccountNo : | testCoreData2.swift:82:18:82:32 | .value : | +| testCoreData2.swift:82:18:82:32 | .value : | testCoreData2.swift:82:2:82:2 | [post] dbObj [myValue] : | +| testCoreData2.swift:83:2:83:2 | [post] dbObj [myValue] : | testCoreData2.swift:83:2:83:2 | [post] dbObj | +| testCoreData2.swift:83:18:83:18 | bankAccountNo : | testCoreData2.swift:71:9:71:9 | self : | +| testCoreData2.swift:83:18:83:18 | bankAccountNo : | testCoreData2.swift:83:18:83:32 | ...! : | +| testCoreData2.swift:83:18:83:18 | bankAccountNo : | testCoreData2.swift:83:18:83:32 | .value2 : | +| testCoreData2.swift:83:18:83:32 | ...! : | testCoreData2.swift:83:2:83:2 | [post] dbObj [myValue] : | +| testCoreData2.swift:83:18:83:32 | .value2 : | testCoreData2.swift:83:18:83:32 | ...! : | +| testCoreData2.swift:84:2:84:2 | [post] dbObj [myValue] : | testCoreData2.swift:84:2:84:2 | [post] dbObj | +| testCoreData2.swift:84:18:84:18 | ...! : | testCoreData2.swift:70:9:70:9 | self : | +| testCoreData2.swift:84:18:84:18 | ...! : | testCoreData2.swift:84:18:84:33 | .value : | +| testCoreData2.swift:84:18:84:18 | bankAccountNo2 : | testCoreData2.swift:84:18:84:18 | ...! : | +| testCoreData2.swift:84:18:84:18 | bankAccountNo2 : | testCoreData2.swift:84:18:84:33 | .value : | +| testCoreData2.swift:84:18:84:33 | .value : | testCoreData2.swift:84:2:84:2 | [post] dbObj [myValue] : | +| testCoreData2.swift:85:2:85:2 | [post] dbObj [myValue] : | testCoreData2.swift:85:2:85:2 | [post] dbObj | +| testCoreData2.swift:85:18:85:18 | ...! : | testCoreData2.swift:71:9:71:9 | self : | +| testCoreData2.swift:85:18:85:18 | ...! : | testCoreData2.swift:85:18:85:33 | .value2 : | +| testCoreData2.swift:85:18:85:18 | bankAccountNo2 : | testCoreData2.swift:85:18:85:18 | ...! : | +| testCoreData2.swift:85:18:85:18 | bankAccountNo2 : | testCoreData2.swift:85:18:85:33 | ...! : | +| testCoreData2.swift:85:18:85:33 | ...! : | testCoreData2.swift:85:2:85:2 | [post] dbObj [myValue] : | +| testCoreData2.swift:85:18:85:33 | .value2 : | testCoreData2.swift:85:18:85:33 | ...! : | | testCoreData2.swift:87:2:87:10 | [post] ...? [myValue] : | testCoreData2.swift:87:2:87:10 | [post] ...? | | testCoreData2.swift:87:22:87:32 | .bankAccountNo : | testCoreData2.swift:87:2:87:10 | [post] ...? [myValue] : | +| testCoreData2.swift:88:2:88:10 | [post] ...? [myValue] : | testCoreData2.swift:88:2:88:10 | [post] ...? | +| testCoreData2.swift:88:22:88:22 | bankAccountNo : | testCoreData2.swift:70:9:70:9 | self : | +| testCoreData2.swift:88:22:88:22 | bankAccountNo : | testCoreData2.swift:88:22:88:36 | .value : | +| testCoreData2.swift:88:22:88:36 | .value : | testCoreData2.swift:88:2:88:10 | [post] ...? [myValue] : | +| testCoreData2.swift:89:2:89:10 | [post] ...? [myValue] : | testCoreData2.swift:89:2:89:10 | [post] ...? | +| testCoreData2.swift:89:22:89:22 | ...! : | testCoreData2.swift:71:9:71:9 | self : | +| testCoreData2.swift:89:22:89:22 | ...! : | testCoreData2.swift:89:22:89:37 | .value2 : | +| testCoreData2.swift:89:22:89:22 | bankAccountNo2 : | testCoreData2.swift:89:22:89:22 | ...! : | +| testCoreData2.swift:89:22:89:22 | bankAccountNo2 : | testCoreData2.swift:89:22:89:37 | ...! : | +| testCoreData2.swift:89:22:89:37 | ...! : | testCoreData2.swift:89:2:89:10 | [post] ...? [myValue] : | +| testCoreData2.swift:89:22:89:37 | .value2 : | testCoreData2.swift:89:22:89:37 | ...! : | +| testCoreData2.swift:91:10:91:10 | bankAccountNo : | testCoreData2.swift:92:10:92:10 | a : | +| testCoreData2.swift:91:10:91:10 | bankAccountNo : | testCoreData2.swift:93:18:93:18 | b : | +| testCoreData2.swift:92:10:92:10 | a : | testCoreData2.swift:70:9:70:9 | self : | +| testCoreData2.swift:92:10:92:10 | a : | testCoreData2.swift:92:10:92:12 | .value : | +| testCoreData2.swift:92:10:92:12 | .value : | testCoreData2.swift:93:18:93:18 | b : | +| testCoreData2.swift:93:2:93:2 | [post] dbObj [myValue] : | testCoreData2.swift:93:2:93:2 | [post] dbObj | +| testCoreData2.swift:93:18:93:18 | b : | testCoreData2.swift:93:2:93:2 | [post] dbObj [myValue] : | | testCoreData.swift:18:19:18:26 | value : | testCoreData.swift:19:12:19:12 | value | | testCoreData.swift:31:3:31:3 | newValue : | testCoreData.swift:32:13:32:13 | newValue | | testCoreData.swift:61:25:61:25 | password : | testCoreData.swift:18:19:18:26 | value : | @@ -111,6 +154,8 @@ edges | testRealm.swift:59:11:59:11 | myPassword : | testRealm.swift:16:6:16:6 | value : | | testRealm.swift:59:11:59:11 | myPassword : | testRealm.swift:59:2:59:2 | [post] g [data] : | nodes +| file://:0:0:0:0 | .value2 : | semmle.label | .value2 : | +| file://:0:0:0:0 | .value : | semmle.label | .value : | | file://:0:0:0:0 | [post] self [data] : | semmle.label | [post] self [data] : | | file://:0:0:0:0 | [post] self [notStoredBankAccountNumber] : | semmle.label | [post] self [notStoredBankAccountNumber] : | | file://:0:0:0:0 | value : | semmle.label | value : | @@ -152,6 +197,8 @@ nodes | testCoreData2.swift:65:3:65:3 | [post] obj | semmle.label | [post] obj | | testCoreData2.swift:65:3:65:3 | [post] obj [myBankAccountNumber] : | semmle.label | [post] obj [myBankAccountNumber] : | | testCoreData2.swift:65:29:65:29 | bankAccountNo : | semmle.label | bankAccountNo : | +| testCoreData2.swift:70:9:70:9 | self : | semmle.label | self : | +| testCoreData2.swift:71:9:71:9 | self : | semmle.label | self : | | testCoreData2.swift:79:2:79:2 | [post] dbObj | semmle.label | [post] dbObj | | testCoreData2.swift:79:2:79:2 | [post] dbObj [myValue] : | semmle.label | [post] dbObj [myValue] : | | testCoreData2.swift:79:18:79:28 | .bankAccountNo : | semmle.label | .bankAccountNo : | @@ -159,9 +206,45 @@ nodes | testCoreData2.swift:80:2:80:2 | [post] dbObj [myValue] : | semmle.label | [post] dbObj [myValue] : | | testCoreData2.swift:80:18:80:28 | ...! : | semmle.label | ...! : | | testCoreData2.swift:80:18:80:28 | .bankAccountNo2 : | semmle.label | .bankAccountNo2 : | +| testCoreData2.swift:82:2:82:2 | [post] dbObj | semmle.label | [post] dbObj | +| testCoreData2.swift:82:2:82:2 | [post] dbObj [myValue] : | semmle.label | [post] dbObj [myValue] : | +| testCoreData2.swift:82:18:82:18 | bankAccountNo : | semmle.label | bankAccountNo : | +| testCoreData2.swift:82:18:82:32 | .value : | semmle.label | .value : | +| testCoreData2.swift:83:2:83:2 | [post] dbObj | semmle.label | [post] dbObj | +| testCoreData2.swift:83:2:83:2 | [post] dbObj [myValue] : | semmle.label | [post] dbObj [myValue] : | +| testCoreData2.swift:83:18:83:18 | bankAccountNo : | semmle.label | bankAccountNo : | +| testCoreData2.swift:83:18:83:32 | ...! : | semmle.label | ...! : | +| testCoreData2.swift:83:18:83:32 | .value2 : | semmle.label | .value2 : | +| testCoreData2.swift:84:2:84:2 | [post] dbObj | semmle.label | [post] dbObj | +| testCoreData2.swift:84:2:84:2 | [post] dbObj [myValue] : | semmle.label | [post] dbObj [myValue] : | +| testCoreData2.swift:84:18:84:18 | ...! : | semmle.label | ...! : | +| testCoreData2.swift:84:18:84:18 | bankAccountNo2 : | semmle.label | bankAccountNo2 : | +| testCoreData2.swift:84:18:84:33 | .value : | semmle.label | .value : | +| testCoreData2.swift:85:2:85:2 | [post] dbObj | semmle.label | [post] dbObj | +| testCoreData2.swift:85:2:85:2 | [post] dbObj [myValue] : | semmle.label | [post] dbObj [myValue] : | +| testCoreData2.swift:85:18:85:18 | ...! : | semmle.label | ...! : | +| testCoreData2.swift:85:18:85:18 | bankAccountNo2 : | semmle.label | bankAccountNo2 : | +| testCoreData2.swift:85:18:85:33 | ...! : | semmle.label | ...! : | +| testCoreData2.swift:85:18:85:33 | .value2 : | semmle.label | .value2 : | | testCoreData2.swift:87:2:87:10 | [post] ...? | semmle.label | [post] ...? | | testCoreData2.swift:87:2:87:10 | [post] ...? [myValue] : | semmle.label | [post] ...? [myValue] : | | testCoreData2.swift:87:22:87:32 | .bankAccountNo : | semmle.label | .bankAccountNo : | +| testCoreData2.swift:88:2:88:10 | [post] ...? | semmle.label | [post] ...? | +| testCoreData2.swift:88:2:88:10 | [post] ...? [myValue] : | semmle.label | [post] ...? [myValue] : | +| testCoreData2.swift:88:22:88:22 | bankAccountNo : | semmle.label | bankAccountNo : | +| testCoreData2.swift:88:22:88:36 | .value : | semmle.label | .value : | +| testCoreData2.swift:89:2:89:10 | [post] ...? | semmle.label | [post] ...? | +| testCoreData2.swift:89:2:89:10 | [post] ...? [myValue] : | semmle.label | [post] ...? [myValue] : | +| testCoreData2.swift:89:22:89:22 | ...! : | semmle.label | ...! : | +| testCoreData2.swift:89:22:89:22 | bankAccountNo2 : | semmle.label | bankAccountNo2 : | +| testCoreData2.swift:89:22:89:37 | ...! : | semmle.label | ...! : | +| testCoreData2.swift:89:22:89:37 | .value2 : | semmle.label | .value2 : | +| testCoreData2.swift:91:10:91:10 | bankAccountNo : | semmle.label | bankAccountNo : | +| testCoreData2.swift:92:10:92:10 | a : | semmle.label | a : | +| testCoreData2.swift:92:10:92:12 | .value : | semmle.label | .value : | +| testCoreData2.swift:93:2:93:2 | [post] dbObj | semmle.label | [post] dbObj | +| testCoreData2.swift:93:2:93:2 | [post] dbObj [myValue] : | semmle.label | [post] dbObj [myValue] : | +| testCoreData2.swift:93:18:93:18 | b : | semmle.label | b : | | testCoreData.swift:18:19:18:26 | value : | semmle.label | value : | | testCoreData.swift:19:12:19:12 | value | semmle.label | value | | testCoreData.swift:31:3:31:3 | newValue : | semmle.label | newValue : | @@ -302,6 +385,13 @@ nodes subpaths | testCoreData2.swift:43:35:43:35 | bankAccountNo : | testCoreData2.swift:23:13:23:13 | value : | file://:0:0:0:0 | [post] self [notStoredBankAccountNumber] : | testCoreData2.swift:43:2:43:2 | [post] obj [notStoredBankAccountNumber] : | | testCoreData2.swift:52:41:52:41 | bankAccountNo : | testCoreData2.swift:23:13:23:13 | value : | file://:0:0:0:0 | [post] self [notStoredBankAccountNumber] : | testCoreData2.swift:52:2:52:10 | [post] ...? [notStoredBankAccountNumber] : | +| testCoreData2.swift:82:18:82:18 | bankAccountNo : | testCoreData2.swift:70:9:70:9 | self : | file://:0:0:0:0 | .value : | testCoreData2.swift:82:18:82:32 | .value : | +| testCoreData2.swift:83:18:83:18 | bankAccountNo : | testCoreData2.swift:71:9:71:9 | self : | file://:0:0:0:0 | .value2 : | testCoreData2.swift:83:18:83:32 | .value2 : | +| testCoreData2.swift:84:18:84:18 | ...! : | testCoreData2.swift:70:9:70:9 | self : | file://:0:0:0:0 | .value : | testCoreData2.swift:84:18:84:33 | .value : | +| testCoreData2.swift:85:18:85:18 | ...! : | testCoreData2.swift:71:9:71:9 | self : | file://:0:0:0:0 | .value2 : | testCoreData2.swift:85:18:85:33 | .value2 : | +| testCoreData2.swift:88:22:88:22 | bankAccountNo : | testCoreData2.swift:70:9:70:9 | self : | file://:0:0:0:0 | .value : | testCoreData2.swift:88:22:88:36 | .value : | +| testCoreData2.swift:89:22:89:22 | ...! : | testCoreData2.swift:71:9:71:9 | self : | file://:0:0:0:0 | .value2 : | testCoreData2.swift:89:22:89:37 | .value2 : | +| testCoreData2.swift:92:10:92:10 | a : | testCoreData2.swift:70:9:70:9 | self : | file://:0:0:0:0 | .value : | testCoreData2.swift:92:10:92:12 | .value : | | testRealm.swift:34:11:34:11 | myPassword : | testRealm.swift:16:6:16:6 | value : | file://:0:0:0:0 | [post] self [data] : | testRealm.swift:34:2:34:2 | [post] a [data] : | | testRealm.swift:42:11:42:11 | myPassword : | testRealm.swift:16:6:16:6 | value : | file://:0:0:0:0 | [post] self [data] : | testRealm.swift:42:2:42:2 | [post] c [data] : | | testRealm.swift:52:12:52:12 | myPassword : | testRealm.swift:16:6:16:6 | value : | file://:0:0:0:0 | [post] self [data] : | testRealm.swift:52:2:52:3 | [post] ...! [data] : | @@ -321,7 +411,14 @@ subpaths | testCoreData2.swift:65:3:65:3 | obj | testCoreData2.swift:65:29:65:29 | bankAccountNo : | testCoreData2.swift:65:3:65:3 | [post] obj | This operation stores '[post] obj' in a database. It may contain unencrypted sensitive data from $@. | testCoreData2.swift:65:29:65:29 | bankAccountNo : | bankAccountNo | | testCoreData2.swift:79:2:79:2 | dbObj | testCoreData2.swift:79:18:79:28 | .bankAccountNo : | testCoreData2.swift:79:2:79:2 | [post] dbObj | This operation stores '[post] dbObj' in a database. It may contain unencrypted sensitive data from $@. | testCoreData2.swift:79:18:79:28 | .bankAccountNo : | .bankAccountNo | | testCoreData2.swift:80:2:80:2 | dbObj | testCoreData2.swift:80:18:80:28 | .bankAccountNo2 : | testCoreData2.swift:80:2:80:2 | [post] dbObj | This operation stores '[post] dbObj' in a database. It may contain unencrypted sensitive data from $@. | testCoreData2.swift:80:18:80:28 | .bankAccountNo2 : | .bankAccountNo2 | +| testCoreData2.swift:82:2:82:2 | dbObj | testCoreData2.swift:82:18:82:18 | bankAccountNo : | testCoreData2.swift:82:2:82:2 | [post] dbObj | This operation stores '[post] dbObj' in a database. It may contain unencrypted sensitive data from $@. | testCoreData2.swift:82:18:82:18 | bankAccountNo : | bankAccountNo | +| testCoreData2.swift:83:2:83:2 | dbObj | testCoreData2.swift:83:18:83:18 | bankAccountNo : | testCoreData2.swift:83:2:83:2 | [post] dbObj | This operation stores '[post] dbObj' in a database. It may contain unencrypted sensitive data from $@. | testCoreData2.swift:83:18:83:18 | bankAccountNo : | bankAccountNo | +| testCoreData2.swift:84:2:84:2 | dbObj | testCoreData2.swift:84:18:84:18 | bankAccountNo2 : | testCoreData2.swift:84:2:84:2 | [post] dbObj | This operation stores '[post] dbObj' in a database. It may contain unencrypted sensitive data from $@. | testCoreData2.swift:84:18:84:18 | bankAccountNo2 : | bankAccountNo2 | +| testCoreData2.swift:85:2:85:2 | dbObj | testCoreData2.swift:85:18:85:18 | bankAccountNo2 : | testCoreData2.swift:85:2:85:2 | [post] dbObj | This operation stores '[post] dbObj' in a database. It may contain unencrypted sensitive data from $@. | testCoreData2.swift:85:18:85:18 | bankAccountNo2 : | bankAccountNo2 | | testCoreData2.swift:87:2:87:10 | ...? | testCoreData2.swift:87:22:87:32 | .bankAccountNo : | testCoreData2.swift:87:2:87:10 | [post] ...? | This operation stores '[post] ...?' in a database. It may contain unencrypted sensitive data from $@. | testCoreData2.swift:87:22:87:32 | .bankAccountNo : | .bankAccountNo | +| testCoreData2.swift:88:2:88:10 | ...? | testCoreData2.swift:88:22:88:22 | bankAccountNo : | testCoreData2.swift:88:2:88:10 | [post] ...? | This operation stores '[post] ...?' in a database. It may contain unencrypted sensitive data from $@. | testCoreData2.swift:88:22:88:22 | bankAccountNo : | bankAccountNo | +| testCoreData2.swift:89:2:89:10 | ...? | testCoreData2.swift:89:22:89:22 | bankAccountNo2 : | testCoreData2.swift:89:2:89:10 | [post] ...? | This operation stores '[post] ...?' in a database. It may contain unencrypted sensitive data from $@. | testCoreData2.swift:89:22:89:22 | bankAccountNo2 : | bankAccountNo2 | +| testCoreData2.swift:93:2:93:2 | dbObj | testCoreData2.swift:91:10:91:10 | bankAccountNo : | testCoreData2.swift:93:2:93:2 | [post] dbObj | This operation stores '[post] dbObj' in a database. It may contain unencrypted sensitive data from $@. | testCoreData2.swift:91:10:91:10 | bankAccountNo : | bankAccountNo | | testCoreData.swift:19:12:19:12 | value | testCoreData.swift:61:25:61:25 | password : | testCoreData.swift:19:12:19:12 | value | This operation stores 'value' in a database. It may contain unencrypted sensitive data from $@. | testCoreData.swift:61:25:61:25 | password : | password | | testCoreData.swift:32:13:32:13 | newValue | testCoreData.swift:64:16:64:16 | password : | testCoreData.swift:32:13:32:13 | newValue | This operation stores 'newValue' in a database. It may contain unencrypted sensitive data from $@. | testCoreData.swift:64:16:64:16 | password : | password | | testCoreData.swift:48:15:48:15 | password | testCoreData.swift:48:15:48:15 | password | testCoreData.swift:48:15:48:15 | password | This operation stores 'password' in a database. It may contain unencrypted sensitive data from $@. | testCoreData.swift:48:15:48:15 | password | password | diff --git a/swift/ql/test/query-tests/Security/CWE-311/testCoreData2.swift b/swift/ql/test/query-tests/Security/CWE-311/testCoreData2.swift index ee92de17b70..c0db195bf67 100644 --- a/swift/ql/test/query-tests/Security/CWE-311/testCoreData2.swift +++ b/swift/ql/test/query-tests/Security/CWE-311/testCoreData2.swift @@ -79,16 +79,16 @@ func testCoreData2_3(dbObj: MyManagedObject2, maybeObj: MyManagedObject2?, conta dbObj.myValue = container.bankAccountNo // BAD dbObj.myValue = container.bankAccountNo2 // BAD - dbObj.myValue = bankAccountNo.value // BAD [NOT DETECTED] - dbObj.myValue = bankAccountNo.value2 // BAD [NOT DETECTED] - dbObj.myValue = bankAccountNo2.value // BAD [NOT DETECTED] - dbObj.myValue = bankAccountNo2.value2 // BAD [NOT DETECTED] + dbObj.myValue = bankAccountNo.value // BAD + dbObj.myValue = bankAccountNo.value2 // BAD + dbObj.myValue = bankAccountNo2.value // BAD + dbObj.myValue = bankAccountNo2.value2 // BAD maybeObj?.myValue = container.bankAccountNo // BAD - maybeObj?.myValue = bankAccountNo.value // BAD [NOT DETECTED] - maybeObj?.myValue = bankAccountNo2.value2 // BAD [NOT DETECTED] + maybeObj?.myValue = bankAccountNo.value // BAD + maybeObj?.myValue = bankAccountNo2.value2 // BAD var a = bankAccountNo // sensitive var b = a.value - dbObj.myValue = b // BAD [NOT DETECTED] + dbObj.myValue = b // BAD } From e17c059f5eb52511486f5c09fe4d332447c835fd Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Fri, 17 Feb 2023 09:00:07 +0000 Subject: [PATCH 233/631] Swift: More reliable sink recognition. This is needed for the real world results, but I could not reproduce the issue in tests. I think it may have something to do with classes defined across different files / modules??? --- .../security/CleartextStorageDatabaseExtensions.qll | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/swift/ql/lib/codeql/swift/security/CleartextStorageDatabaseExtensions.qll b/swift/ql/lib/codeql/swift/security/CleartextStorageDatabaseExtensions.qll index 4fb19373956..00867716347 100644 --- a/swift/ql/lib/codeql/swift/security/CleartextStorageDatabaseExtensions.qll +++ b/swift/ql/lib/codeql/swift/security/CleartextStorageDatabaseExtensions.qll @@ -48,10 +48,10 @@ private class CoreDataStore extends CleartextStorageDatabaseSink { // example in `coreDataObj.data = sensitive` the post-update node corresponding // with `coreDataObj.data` is a sink. // (ideally this would be only members with the `@NSManaged` attribute) - exists(ClassOrStructDecl cd, Expr e | - cd.getABaseTypeDecl*().getName() = "NSManagedObject" and + exists(NominalType t, Expr e | + t.getABaseType*().getName() = "NSManagedObject" and this.(DataFlow::PostUpdateNode).getPreUpdateNode().asExpr() = e and - e.getFullyConverted().getType() = cd.getType() and + e.getFullyConverted().getType() = t and not e.(DeclRefExpr).getDecl() instanceof SelfParamDecl ) } @@ -66,10 +66,10 @@ private class RealmStore extends CleartextStorageDatabaseSink instanceof DataFlo // any write into a class derived from `RealmSwiftObject` is a sink. For // example in `realmObj.data = sensitive` the post-update node corresponding // with `realmObj.data` is a sink. - exists(ClassOrStructDecl cd, Expr e | - cd.getABaseTypeDecl*().getName() = "RealmSwiftObject" and + exists(NominalType t, Expr e | + t.getABaseType*().getName() = "RealmSwiftObject" and this.getPreUpdateNode().asExpr() = e and - e.getFullyConverted().getType() = cd.getType() and + e.getFullyConverted().getType() = t and not e.(DeclRefExpr).getDecl() instanceof SelfParamDecl ) } From c4c0009f8af668f66bfa840f7371f5fccc053fe9 Mon Sep 17 00:00:00 2001 From: Asger F Date: Mon, 13 Mar 2023 09:35:35 +0100 Subject: [PATCH 234/631] Apply suggestions from code review Co-authored-by: Andrew Eisenberg --- docs/codeql/codeql-language-guides/codeql-for-javascript.rst | 1 - .../customizing-library-models-for-javascript.rst | 3 +++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/codeql/codeql-language-guides/codeql-for-javascript.rst b/docs/codeql/codeql-language-guides/codeql-for-javascript.rst index 98f8d27a155..b94c5252107 100644 --- a/docs/codeql/codeql-language-guides/codeql-for-javascript.rst +++ b/docs/codeql/codeql-language-guides/codeql-for-javascript.rst @@ -13,7 +13,6 @@ Experiment and learn how to write effective and efficient queries for CodeQL dat codeql-library-for-typescript analyzing-data-flow-in-javascript-and-typescript using-flow-labels-for-precise-data-flow-analysis - customizing-library-models-for-javascript specifying-additional-remote-flow-sources-for-javascript using-type-tracking-for-api-modeling abstract-syntax-tree-classes-for-working-with-javascript-and-typescript-programs diff --git a/docs/codeql/codeql-language-guides/customizing-library-models-for-javascript.rst b/docs/codeql/codeql-language-guides/customizing-library-models-for-javascript.rst index 89a7ced5035..7242b3691a4 100644 --- a/docs/codeql/codeql-language-guides/customizing-library-models-for-javascript.rst +++ b/docs/codeql/codeql-language-guides/customizing-library-models-for-javascript.rst @@ -1,5 +1,8 @@ .. _customizing-library-models-for-javascript: +:orphan: +:nosearch: + Customizing Library Models for JavaScript ========================================= From ecb46e808c7a64a9528010d5c5526c6831dda67b Mon Sep 17 00:00:00 2001 From: Asger F Date: Mon, 13 Mar 2023 09:39:05 +0100 Subject: [PATCH 235/631] JS: extension point -> extensible predicate --- ...tomizing-library-models-for-javascript.rst | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/docs/codeql/codeql-language-guides/customizing-library-models-for-javascript.rst b/docs/codeql/codeql-language-guides/customizing-library-models-for-javascript.rst index 89a7ced5035..911063bae68 100644 --- a/docs/codeql/codeql-language-guides/customizing-library-models-for-javascript.rst +++ b/docs/codeql/codeql-language-guides/customizing-library-models-for-javascript.rst @@ -14,13 +14,13 @@ A data extension for JavaScript is a YAML file of form: extensions: - addsTo: pack: codeql/javascript-all - extensible: + extensible: data: - - - ... -The data extension can contribute to the following extension points: +The data extension can contribute to the following extensible predicates: - **sourceModel**\(type, path, kind) - **sinkModel**\(type, path, kind) @@ -56,7 +56,7 @@ This can be achieved with the following data extension: To break this down: -- Since we're adding a new sink, we add a tuple to the **sinkModel** extension point. +- Since we're adding a new sink, we add a tuple to the **sinkModel** extensible predicate. - The first column, **"execa"**, identifies a set of values from which to begin the search for the sink. The string **"execa"** means we start at the places where the codebase imports the NPM package **execa**. - The second column is an access path that is evaluated from left to right, starting at the values that were identified by the first column. @@ -94,7 +94,7 @@ This source is already known by the CodeQL JS analysis, but we'll show how it co To break this down: -- Since we're adding a new taint source, we add a tuple to the **sourceModel** extension point. +- Since we're adding a new taint source, we add a tuple to the **sourceModel** extensible predicate. - The first column, **"global"**, begins the search at references to the global object (also known as **window** in browser contexts). This is a special JavaScript object that contains all global variables and methods. - **Member[addEventListener]** selects accesses to the **addEventListener** member. - **Argument[1]** selects the second argument of calls to that member (the argument containing the callback). @@ -193,7 +193,7 @@ Using a **typeModel** tuple we can tell our model that this function returns an To break this down: -- Since we're providing type information, we add a tuple to the **typeModel** extension point. +- Since we're providing type information, we add a tuple to the **typeModel** extensible predicate. - The first column, **"mysql.Connection"**, names the type that we're adding a new definition for. - The second column, **"@example/db"**, begins the search at imports of the hypothetical NPM package **@example/db**. - **Member[getConnection]** selects references to the **getConnection** member from that package. @@ -238,7 +238,7 @@ This flow is already recognized by the CodeQL JS analysis, but this is how it co To break this down: -- Since we're adding flow *through* a function call, we add a tuple to the **summaryModel** extension point. +- Since we're adding flow *through* a function call, we add a tuple to the **summaryModel** extensible predicate. - The first column, **"global"**, begins the search for relevant calls at references to the global object. In JavaScript, global variables are properties of the global object, so this lets us access global variables or functions. - The second column, **Member[decodeURIComponent]**, is a path leading to the function calls we wish to model. @@ -277,7 +277,7 @@ This flow is already recognized by the CodeQL JS analysis, but we'll show how it To break this down: -- Since we're adding flow *through* a function call, we add a tuple to the **summaryModel** extension point. +- Since we're adding flow *through* a function call, we add a tuple to the **summaryModel** extensible predicate. - The first column, **"underscore"**, begins the search for relevant calls at places where the **underscore** package is imported. - The second column, **Member[forEach]**, selects references to the **forEach** member from the **underscore** package. - The third column specifies the input of the flow: @@ -296,10 +296,10 @@ To break this down: Reference material ------------------ -The following sections provide reference material for extension points, access paths, types, and kinds. +The following sections provide reference material for extensible predicates, access paths, types, and kinds. -Extension points ----------------- +Extensible predicates +--------------------- sourceModel(type, path, kind) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -397,7 +397,7 @@ Types ----- A type is a string that identifies a set of values. -In each of the extension points mentioned above, the first column is always the name of a type. +In each of the extensible predicates mentioned above, the first column is always the name of a type. A type can be defined by adding **typeModel** tuples for that type. Additionally, the following built-in types are available: - The name of an NPM package matches imports of that package. For example, the type **express** matches the expression **require("express")**. If the package name includes dots, it must be surrounded by single quotes, such as in **'lodash.escape'**. From 05b0cc22312d21ac4234666c13d2550a347a280d Mon Sep 17 00:00:00 2001 From: Stephan Brandauer Date: Mon, 13 Mar 2023 14:21:29 +0100 Subject: [PATCH 236/631] Update MaD Declarations after Triage --- java/ql/lib/ext/hudson.model.model.yml | 13 +++++++++++++ java/ql/lib/ext/hudson.scm.model.yml | 18 ++++++++++++++++++ java/ql/lib/ext/hudson.util.model.yml | 11 +++++++++++ 3 files changed, 42 insertions(+) create mode 100644 java/ql/lib/ext/hudson.model.model.yml create mode 100644 java/ql/lib/ext/hudson.scm.model.yml create mode 100644 java/ql/lib/ext/hudson.util.model.yml diff --git a/java/ql/lib/ext/hudson.model.model.yml b/java/ql/lib/ext/hudson.model.model.yml new file mode 100644 index 00000000000..de05ce7176d --- /dev/null +++ b/java/ql/lib/ext/hudson.model.model.yml @@ -0,0 +1,13 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: sinkModel + data: + - ["hudson.model", "DownloadService", True, "loadJSON", "(URL)", "", "Argument[0]", "open-url", "ai-generated"] + - ["hudson.model", "DownloadService", True, "loadJSONHTML", "(URL)", "", "Argument[0]", "open-url", "ai-generated"] + - ["hudson.model", "Items", True, "load", "(ItemGroup,File)", "", "Argument[1]", "read-file", "ai-generated"] + - addsTo: + pack: codeql/java-all + extensible: summaryModel + data: + - ["hudson.model", "Node", True, "createPath", "(String)", "", "Argument[0]", "ReturnValue", "taint", "ai-generated"] diff --git a/java/ql/lib/ext/hudson.scm.model.yml b/java/ql/lib/ext/hudson.scm.model.yml new file mode 100644 index 00000000000..942fba356d1 --- /dev/null +++ b/java/ql/lib/ext/hudson.scm.model.yml @@ -0,0 +1,18 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: sinkModel + data: + - ["hudson.scm", "ChangeLogParser", True, "parse", "(AbstractBuild,File)", "", "Argument[1]", "read-file", "ai-generated"] + - ["hudson.scm", "ChangeLogParser", True, "parse", "(Run,RepositoryBrowser,File)", "", "Argument[2]", "read-file", "ai-generated"] + - ["hudson.scm", "SCM", True, "checkout", "(AbstractBuild,Launcher,FilePath,BuildListener,File)", "", "Argument[2]", "create-file", "ai-generated"] # A repo will be checked out into this location.. + - ["hudson.scm", "SCM", True, "checkout", "(Run,Launcher,FilePath,TaskListener,File,SCMRevisionState)", "", "Argument[2]", "create-file", "ai-generated"] + - ["hudson.scm", "SCM", True, "compareRemoteRevisionWith", "(Job,Launcher,FilePath,TaskListener,SCMRevisionState)", "", "Argument[2]", "read-file", "ai-generated"] + - addsTo: + pack: codeql/java-all + extensible: summaryModel + data: + - ["hudson.scm", "SCM", True, "getModuleRoot", "(FilePath,AbstractBuild)", "", "Argument[0]", "ReturnValue", "taint", "ai-generated"] + - ["hudson.scm", "SCM", True, "getModuleRoot", "(FilePath)", "", "Argument[0]", "ReturnValue", "taint", "ai-generated"] + - ["hudson.scm", "SCM", True, "getModuleRoots", "(FilePath,AbstractBuild)", "", "Argument[0]", "ReturnValue.ArrayElement", "taint", "ai-generated"] + - ["hudson.scm", "SCM", True, "getModuleRoots", "(FilePath)", "", "Argument[0]", "ReturnValue.ArrayElement", "taint", "ai-generated"] diff --git a/java/ql/lib/ext/hudson.util.model.yml b/java/ql/lib/ext/hudson.util.model.yml new file mode 100644 index 00000000000..369f4dd9ccf --- /dev/null +++ b/java/ql/lib/ext/hudson.util.model.yml @@ -0,0 +1,11 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: sinkModel + data: + - ["hudson.util", "AtomicFileWriter", True, "AtomicFileWriter", "(File)", "", "Argument[0]", "create-file", "ai-generated"] + - ["hudson.util", "AtomicFileWriter", True, "AtomicFileWriter", "(Path,Charset,boolean,boolean)", "", "Argument[0]", "create-file", "ai-generated"] + - ["hudson.util", "AtomicFileWriter", True, "AtomicFileWriter", "(Path,Charset)", "", "Argument[0]", "create-file", "ai-generated"] + - ["hudson.util", "ClasspathBuilder", True, "add", "(FilePath)", "", "Argument[0]", "read-file", "ai-generated"] + - ["hudson.util", "IOUtils", True, "mkdirs", "(File)", "", "Argument[0]", "create-file", "ai-generated"] + - ["hudson.util", "TextFile", True, "TextFile", "(File)", "", "Argument[0]", "create-file", "ai-generated"] # @atorralba, PTAL - this class can be used to later write to/read from the file, but also only check existence. Could make ctor a step instead..? From f1a8d4936f760a2bfff75b14c363d52ccb9920c3 Mon Sep 17 00:00:00 2001 From: Rasmus Lerchedahl Petersen Date: Tue, 14 Mar 2023 13:45:30 +0100 Subject: [PATCH 237/631] python: Fix link to type inference Link to type tracking instead and actually add link. --- docs/codeql/codeql-language-guides/functions-in-python.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/codeql/codeql-language-guides/functions-in-python.rst b/docs/codeql/codeql-language-guides/functions-in-python.rst index fbb4ff0d6e5..d389dab31d6 100644 --- a/docs/codeql/codeql-language-guides/functions-in-python.rst +++ b/docs/codeql/codeql-language-guides/functions-in-python.rst @@ -75,12 +75,12 @@ This query uses ``Call`` and ``Name`` to find calls to the function ``eval`` - w select call, "call to 'eval'." 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. +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. +Due to the dynamic nature of Python, such syntactic queries can be inaccurate. If one is looking for invocations of the built-in function ``eval``, +it is preferred to use the API graph, see ":doc:`Using API graphs in Python `." Further reading --------------- .. include:: ../reusables/python-further-reading.rst .. include:: ../reusables/codeql-ref-tools-further-reading.rst - From bfbd3d95f95876f43d398fed70cadfe55c77c2e1 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Tue, 14 Mar 2023 16:03:55 +0000 Subject: [PATCH 238/631] Swift: Clean up the result message. --- .../CWE-311/CleartextStorageDatabase.ql | 12 +++-- .../CWE-311/CleartextStorageDatabase.expected | 54 +++++++++---------- 2 files changed, 35 insertions(+), 31 deletions(-) diff --git a/swift/ql/src/queries/Security/CWE-311/CleartextStorageDatabase.ql b/swift/ql/src/queries/Security/CWE-311/CleartextStorageDatabase.ql index 4052a335663..f38d93d30d5 100644 --- a/swift/ql/src/queries/Security/CWE-311/CleartextStorageDatabase.ql +++ b/swift/ql/src/queries/Security/CWE-311/CleartextStorageDatabase.ql @@ -26,9 +26,13 @@ DataFlow::Node cleanupNode(DataFlow::Node n) { result = n } -from CleartextStorageConfig config, DataFlow::PathNode sourceNode, DataFlow::PathNode sinkNode -where config.hasFlowPath(sourceNode, sinkNode) -select cleanupNode(sinkNode.getNode()), sourceNode, sinkNode, - "This operation stores '" + sinkNode.getNode().toString() + +from + CleartextStorageConfig config, DataFlow::PathNode sourceNode, DataFlow::PathNode sinkNode, + DataFlow::Node cleanSink +where + config.hasFlowPath(sourceNode, sinkNode) and + cleanSink = cleanupNode(sinkNode.getNode()) +select cleanSink, sourceNode, sinkNode, + "This operation stores '" + cleanSink.toString() + "' in a database. It may contain unencrypted sensitive data from $@.", sourceNode, sourceNode.getNode().toString() diff --git a/swift/ql/test/query-tests/Security/CWE-311/CleartextStorageDatabase.expected b/swift/ql/test/query-tests/Security/CWE-311/CleartextStorageDatabase.expected index ae6c111d392..a8cb322c75e 100644 --- a/swift/ql/test/query-tests/Security/CWE-311/CleartextStorageDatabase.expected +++ b/swift/ql/test/query-tests/Security/CWE-311/CleartextStorageDatabase.expected @@ -397,34 +397,34 @@ subpaths | testRealm.swift:52:12:52:12 | myPassword : | testRealm.swift:16:6:16:6 | value : | file://:0:0:0:0 | [post] self [data] : | testRealm.swift:52:2:52:3 | [post] ...! [data] : | | testRealm.swift:59:11:59:11 | myPassword : | testRealm.swift:16:6:16:6 | value : | file://:0:0:0:0 | [post] self [data] : | testRealm.swift:59:2:59:2 | [post] g [data] : | #select -| testCoreData2.swift:37:2:37:2 | obj | testCoreData2.swift:37:16:37:16 | bankAccountNo : | testCoreData2.swift:37:2:37:2 | [post] obj | This operation stores '[post] obj' in a database. It may contain unencrypted sensitive data from $@. | testCoreData2.swift:37:16:37:16 | bankAccountNo : | bankAccountNo | -| testCoreData2.swift:39:2:39:2 | obj | testCoreData2.swift:39:28:39:28 | bankAccountNo : | testCoreData2.swift:39:2:39:2 | [post] obj | This operation stores '[post] obj' in a database. It may contain unencrypted sensitive data from $@. | testCoreData2.swift:39:28:39:28 | bankAccountNo : | bankAccountNo | -| testCoreData2.swift:41:2:41:2 | obj | testCoreData2.swift:41:29:41:29 | bankAccountNo : | testCoreData2.swift:41:2:41:2 | [post] obj | This operation stores '[post] obj' in a database. It may contain unencrypted sensitive data from $@. | testCoreData2.swift:41:29:41:29 | bankAccountNo : | bankAccountNo | -| testCoreData2.swift:43:2:43:2 | obj | testCoreData2.swift:43:35:43:35 | bankAccountNo : | testCoreData2.swift:43:2:43:2 | [post] obj | This operation stores '[post] obj' in a database. It may contain unencrypted sensitive data from $@. | testCoreData2.swift:43:35:43:35 | bankAccountNo : | bankAccountNo | -| testCoreData2.swift:46:2:46:10 | ...? | testCoreData2.swift:46:22:46:22 | bankAccountNo : | testCoreData2.swift:46:2:46:10 | [post] ...? | This operation stores '[post] ...?' in a database. It may contain unencrypted sensitive data from $@. | testCoreData2.swift:46:22:46:22 | bankAccountNo : | bankAccountNo | -| testCoreData2.swift:48:2:48:10 | ...? | testCoreData2.swift:48:34:48:34 | bankAccountNo : | testCoreData2.swift:48:2:48:10 | [post] ...? | This operation stores '[post] ...?' in a database. It may contain unencrypted sensitive data from $@. | testCoreData2.swift:48:34:48:34 | bankAccountNo : | bankAccountNo | -| testCoreData2.swift:50:2:50:10 | ...? | testCoreData2.swift:50:35:50:35 | bankAccountNo : | testCoreData2.swift:50:2:50:10 | [post] ...? | This operation stores '[post] ...?' in a database. It may contain unencrypted sensitive data from $@. | testCoreData2.swift:50:35:50:35 | bankAccountNo : | bankAccountNo | -| testCoreData2.swift:52:2:52:10 | ...? | testCoreData2.swift:52:41:52:41 | bankAccountNo : | testCoreData2.swift:52:2:52:10 | [post] ...? | This operation stores '[post] ...?' in a database. It may contain unencrypted sensitive data from $@. | testCoreData2.swift:52:41:52:41 | bankAccountNo : | bankAccountNo | -| testCoreData2.swift:57:3:57:3 | obj | testCoreData2.swift:57:29:57:29 | bankAccountNo : | testCoreData2.swift:57:3:57:3 | [post] obj | This operation stores '[post] obj' in a database. It may contain unencrypted sensitive data from $@. | testCoreData2.swift:57:29:57:29 | bankAccountNo : | bankAccountNo | -| testCoreData2.swift:60:4:60:4 | obj | testCoreData2.swift:60:30:60:30 | bankAccountNo : | testCoreData2.swift:60:4:60:4 | [post] obj | This operation stores '[post] obj' in a database. It may contain unencrypted sensitive data from $@. | testCoreData2.swift:60:30:60:30 | bankAccountNo : | bankAccountNo | -| testCoreData2.swift:62:4:62:4 | obj | testCoreData2.swift:62:30:62:30 | bankAccountNo : | testCoreData2.swift:62:4:62:4 | [post] obj | This operation stores '[post] obj' in a database. It may contain unencrypted sensitive data from $@. | testCoreData2.swift:62:30:62:30 | bankAccountNo : | bankAccountNo | -| testCoreData2.swift:65:3:65:3 | obj | testCoreData2.swift:65:29:65:29 | bankAccountNo : | testCoreData2.swift:65:3:65:3 | [post] obj | This operation stores '[post] obj' in a database. It may contain unencrypted sensitive data from $@. | testCoreData2.swift:65:29:65:29 | bankAccountNo : | bankAccountNo | -| testCoreData2.swift:79:2:79:2 | dbObj | testCoreData2.swift:79:18:79:28 | .bankAccountNo : | testCoreData2.swift:79:2:79:2 | [post] dbObj | This operation stores '[post] dbObj' in a database. It may contain unencrypted sensitive data from $@. | testCoreData2.swift:79:18:79:28 | .bankAccountNo : | .bankAccountNo | -| testCoreData2.swift:80:2:80:2 | dbObj | testCoreData2.swift:80:18:80:28 | .bankAccountNo2 : | testCoreData2.swift:80:2:80:2 | [post] dbObj | This operation stores '[post] dbObj' in a database. It may contain unencrypted sensitive data from $@. | testCoreData2.swift:80:18:80:28 | .bankAccountNo2 : | .bankAccountNo2 | -| testCoreData2.swift:82:2:82:2 | dbObj | testCoreData2.swift:82:18:82:18 | bankAccountNo : | testCoreData2.swift:82:2:82:2 | [post] dbObj | This operation stores '[post] dbObj' in a database. It may contain unencrypted sensitive data from $@. | testCoreData2.swift:82:18:82:18 | bankAccountNo : | bankAccountNo | -| testCoreData2.swift:83:2:83:2 | dbObj | testCoreData2.swift:83:18:83:18 | bankAccountNo : | testCoreData2.swift:83:2:83:2 | [post] dbObj | This operation stores '[post] dbObj' in a database. It may contain unencrypted sensitive data from $@. | testCoreData2.swift:83:18:83:18 | bankAccountNo : | bankAccountNo | -| testCoreData2.swift:84:2:84:2 | dbObj | testCoreData2.swift:84:18:84:18 | bankAccountNo2 : | testCoreData2.swift:84:2:84:2 | [post] dbObj | This operation stores '[post] dbObj' in a database. It may contain unencrypted sensitive data from $@. | testCoreData2.swift:84:18:84:18 | bankAccountNo2 : | bankAccountNo2 | -| testCoreData2.swift:85:2:85:2 | dbObj | testCoreData2.swift:85:18:85:18 | bankAccountNo2 : | testCoreData2.swift:85:2:85:2 | [post] dbObj | This operation stores '[post] dbObj' in a database. It may contain unencrypted sensitive data from $@. | testCoreData2.swift:85:18:85:18 | bankAccountNo2 : | bankAccountNo2 | -| testCoreData2.swift:87:2:87:10 | ...? | testCoreData2.swift:87:22:87:32 | .bankAccountNo : | testCoreData2.swift:87:2:87:10 | [post] ...? | This operation stores '[post] ...?' in a database. It may contain unencrypted sensitive data from $@. | testCoreData2.swift:87:22:87:32 | .bankAccountNo : | .bankAccountNo | -| testCoreData2.swift:88:2:88:10 | ...? | testCoreData2.swift:88:22:88:22 | bankAccountNo : | testCoreData2.swift:88:2:88:10 | [post] ...? | This operation stores '[post] ...?' in a database. It may contain unencrypted sensitive data from $@. | testCoreData2.swift:88:22:88:22 | bankAccountNo : | bankAccountNo | -| testCoreData2.swift:89:2:89:10 | ...? | testCoreData2.swift:89:22:89:22 | bankAccountNo2 : | testCoreData2.swift:89:2:89:10 | [post] ...? | This operation stores '[post] ...?' in a database. It may contain unencrypted sensitive data from $@. | testCoreData2.swift:89:22:89:22 | bankAccountNo2 : | bankAccountNo2 | -| testCoreData2.swift:93:2:93:2 | dbObj | testCoreData2.swift:91:10:91:10 | bankAccountNo : | testCoreData2.swift:93:2:93:2 | [post] dbObj | This operation stores '[post] dbObj' in a database. It may contain unencrypted sensitive data from $@. | testCoreData2.swift:91:10:91:10 | bankAccountNo : | bankAccountNo | +| testCoreData2.swift:37:2:37:2 | obj | testCoreData2.swift:37:16:37:16 | bankAccountNo : | testCoreData2.swift:37:2:37:2 | [post] obj | This operation stores 'obj' in a database. It may contain unencrypted sensitive data from $@. | testCoreData2.swift:37:16:37:16 | bankAccountNo : | bankAccountNo | +| testCoreData2.swift:39:2:39:2 | obj | testCoreData2.swift:39:28:39:28 | bankAccountNo : | testCoreData2.swift:39:2:39:2 | [post] obj | This operation stores 'obj' in a database. It may contain unencrypted sensitive data from $@. | testCoreData2.swift:39:28:39:28 | bankAccountNo : | bankAccountNo | +| testCoreData2.swift:41:2:41:2 | obj | testCoreData2.swift:41:29:41:29 | bankAccountNo : | testCoreData2.swift:41:2:41:2 | [post] obj | This operation stores 'obj' in a database. It may contain unencrypted sensitive data from $@. | testCoreData2.swift:41:29:41:29 | bankAccountNo : | bankAccountNo | +| testCoreData2.swift:43:2:43:2 | obj | testCoreData2.swift:43:35:43:35 | bankAccountNo : | testCoreData2.swift:43:2:43:2 | [post] obj | This operation stores 'obj' in a database. It may contain unencrypted sensitive data from $@. | testCoreData2.swift:43:35:43:35 | bankAccountNo : | bankAccountNo | +| testCoreData2.swift:46:2:46:10 | ...? | testCoreData2.swift:46:22:46:22 | bankAccountNo : | testCoreData2.swift:46:2:46:10 | [post] ...? | This operation stores '...?' in a database. It may contain unencrypted sensitive data from $@. | testCoreData2.swift:46:22:46:22 | bankAccountNo : | bankAccountNo | +| testCoreData2.swift:48:2:48:10 | ...? | testCoreData2.swift:48:34:48:34 | bankAccountNo : | testCoreData2.swift:48:2:48:10 | [post] ...? | This operation stores '...?' in a database. It may contain unencrypted sensitive data from $@. | testCoreData2.swift:48:34:48:34 | bankAccountNo : | bankAccountNo | +| testCoreData2.swift:50:2:50:10 | ...? | testCoreData2.swift:50:35:50:35 | bankAccountNo : | testCoreData2.swift:50:2:50:10 | [post] ...? | This operation stores '...?' in a database. It may contain unencrypted sensitive data from $@. | testCoreData2.swift:50:35:50:35 | bankAccountNo : | bankAccountNo | +| testCoreData2.swift:52:2:52:10 | ...? | testCoreData2.swift:52:41:52:41 | bankAccountNo : | testCoreData2.swift:52:2:52:10 | [post] ...? | This operation stores '...?' in a database. It may contain unencrypted sensitive data from $@. | testCoreData2.swift:52:41:52:41 | bankAccountNo : | bankAccountNo | +| testCoreData2.swift:57:3:57:3 | obj | testCoreData2.swift:57:29:57:29 | bankAccountNo : | testCoreData2.swift:57:3:57:3 | [post] obj | This operation stores 'obj' in a database. It may contain unencrypted sensitive data from $@. | testCoreData2.swift:57:29:57:29 | bankAccountNo : | bankAccountNo | +| testCoreData2.swift:60:4:60:4 | obj | testCoreData2.swift:60:30:60:30 | bankAccountNo : | testCoreData2.swift:60:4:60:4 | [post] obj | This operation stores 'obj' in a database. It may contain unencrypted sensitive data from $@. | testCoreData2.swift:60:30:60:30 | bankAccountNo : | bankAccountNo | +| testCoreData2.swift:62:4:62:4 | obj | testCoreData2.swift:62:30:62:30 | bankAccountNo : | testCoreData2.swift:62:4:62:4 | [post] obj | This operation stores 'obj' in a database. It may contain unencrypted sensitive data from $@. | testCoreData2.swift:62:30:62:30 | bankAccountNo : | bankAccountNo | +| testCoreData2.swift:65:3:65:3 | obj | testCoreData2.swift:65:29:65:29 | bankAccountNo : | testCoreData2.swift:65:3:65:3 | [post] obj | This operation stores 'obj' in a database. It may contain unencrypted sensitive data from $@. | testCoreData2.swift:65:29:65:29 | bankAccountNo : | bankAccountNo | +| testCoreData2.swift:79:2:79:2 | dbObj | testCoreData2.swift:79:18:79:28 | .bankAccountNo : | testCoreData2.swift:79:2:79:2 | [post] dbObj | This operation stores 'dbObj' in a database. It may contain unencrypted sensitive data from $@. | testCoreData2.swift:79:18:79:28 | .bankAccountNo : | .bankAccountNo | +| testCoreData2.swift:80:2:80:2 | dbObj | testCoreData2.swift:80:18:80:28 | .bankAccountNo2 : | testCoreData2.swift:80:2:80:2 | [post] dbObj | This operation stores 'dbObj' in a database. It may contain unencrypted sensitive data from $@. | testCoreData2.swift:80:18:80:28 | .bankAccountNo2 : | .bankAccountNo2 | +| testCoreData2.swift:82:2:82:2 | dbObj | testCoreData2.swift:82:18:82:18 | bankAccountNo : | testCoreData2.swift:82:2:82:2 | [post] dbObj | This operation stores 'dbObj' in a database. It may contain unencrypted sensitive data from $@. | testCoreData2.swift:82:18:82:18 | bankAccountNo : | bankAccountNo | +| testCoreData2.swift:83:2:83:2 | dbObj | testCoreData2.swift:83:18:83:18 | bankAccountNo : | testCoreData2.swift:83:2:83:2 | [post] dbObj | This operation stores 'dbObj' in a database. It may contain unencrypted sensitive data from $@. | testCoreData2.swift:83:18:83:18 | bankAccountNo : | bankAccountNo | +| testCoreData2.swift:84:2:84:2 | dbObj | testCoreData2.swift:84:18:84:18 | bankAccountNo2 : | testCoreData2.swift:84:2:84:2 | [post] dbObj | This operation stores 'dbObj' in a database. It may contain unencrypted sensitive data from $@. | testCoreData2.swift:84:18:84:18 | bankAccountNo2 : | bankAccountNo2 | +| testCoreData2.swift:85:2:85:2 | dbObj | testCoreData2.swift:85:18:85:18 | bankAccountNo2 : | testCoreData2.swift:85:2:85:2 | [post] dbObj | This operation stores 'dbObj' in a database. It may contain unencrypted sensitive data from $@. | testCoreData2.swift:85:18:85:18 | bankAccountNo2 : | bankAccountNo2 | +| testCoreData2.swift:87:2:87:10 | ...? | testCoreData2.swift:87:22:87:32 | .bankAccountNo : | testCoreData2.swift:87:2:87:10 | [post] ...? | This operation stores '...?' in a database. It may contain unencrypted sensitive data from $@. | testCoreData2.swift:87:22:87:32 | .bankAccountNo : | .bankAccountNo | +| testCoreData2.swift:88:2:88:10 | ...? | testCoreData2.swift:88:22:88:22 | bankAccountNo : | testCoreData2.swift:88:2:88:10 | [post] ...? | This operation stores '...?' in a database. It may contain unencrypted sensitive data from $@. | testCoreData2.swift:88:22:88:22 | bankAccountNo : | bankAccountNo | +| testCoreData2.swift:89:2:89:10 | ...? | testCoreData2.swift:89:22:89:22 | bankAccountNo2 : | testCoreData2.swift:89:2:89:10 | [post] ...? | This operation stores '...?' in a database. It may contain unencrypted sensitive data from $@. | testCoreData2.swift:89:22:89:22 | bankAccountNo2 : | bankAccountNo2 | +| testCoreData2.swift:93:2:93:2 | dbObj | testCoreData2.swift:91:10:91:10 | bankAccountNo : | testCoreData2.swift:93:2:93:2 | [post] dbObj | This operation stores 'dbObj' in a database. It may contain unencrypted sensitive data from $@. | testCoreData2.swift:91:10:91:10 | bankAccountNo : | bankAccountNo | | testCoreData.swift:19:12:19:12 | value | testCoreData.swift:61:25:61:25 | password : | testCoreData.swift:19:12:19:12 | value | This operation stores 'value' in a database. It may contain unencrypted sensitive data from $@. | testCoreData.swift:61:25:61:25 | password : | password | | testCoreData.swift:32:13:32:13 | newValue | testCoreData.swift:64:16:64:16 | password : | testCoreData.swift:32:13:32:13 | newValue | This operation stores 'newValue' in a database. It may contain unencrypted sensitive data from $@. | testCoreData.swift:64:16:64:16 | password : | password | | testCoreData.swift:48:15:48:15 | password | testCoreData.swift:48:15:48:15 | password | testCoreData.swift:48:15:48:15 | password | This operation stores 'password' in a database. It may contain unencrypted sensitive data from $@. | testCoreData.swift:48:15:48:15 | password | password | | testCoreData.swift:51:24:51:24 | password | testCoreData.swift:51:24:51:24 | password | testCoreData.swift:51:24:51:24 | password | This operation stores 'password' in a database. It may contain unencrypted sensitive data from $@. | testCoreData.swift:51:24:51:24 | password | password | | testCoreData.swift:58:15:58:15 | password | testCoreData.swift:58:15:58:15 | password | testCoreData.swift:58:15:58:15 | password | This operation stores 'password' in a database. It may contain unencrypted sensitive data from $@. | testCoreData.swift:58:15:58:15 | password | password | -| testCoreData.swift:64:2:64:2 | obj | testCoreData.swift:64:16:64:16 | password : | testCoreData.swift:64:2:64:2 | [post] obj | This operation stores '[post] obj' in a database. It may contain unencrypted sensitive data from $@. | testCoreData.swift:64:16:64:16 | password : | password | +| testCoreData.swift:64:2:64:2 | obj | testCoreData.swift:64:16:64:16 | password : | testCoreData.swift:64:2:64:2 | [post] obj | This operation stores 'obj' in a database. It may contain unencrypted sensitive data from $@. | testCoreData.swift:64:16:64:16 | password : | password | | testCoreData.swift:78:15:78:15 | x | testCoreData.swift:77:24:77:24 | x : | testCoreData.swift:78:15:78:15 | x | This operation stores 'x' in a database. It may contain unencrypted sensitive data from $@. | testCoreData.swift:77:24:77:24 | x : | x | | testCoreData.swift:81:15:81:15 | y | testCoreData.swift:80:10:80:22 | call to getPassword() : | testCoreData.swift:81:15:81:15 | y | This operation stores 'y' in a database. It may contain unencrypted sensitive data from $@. | testCoreData.swift:80:10:80:22 | call to getPassword() : | call to getPassword() | | testCoreData.swift:85:15:85:17 | .password | testCoreData.swift:85:15:85:17 | .password | testCoreData.swift:85:15:85:17 | .password | This operation stores '.password' in a database. It may contain unencrypted sensitive data from $@. | testCoreData.swift:85:15:85:17 | .password | .password | @@ -482,7 +482,7 @@ subpaths | testGRDB.swift:208:80:208:89 | [...] | testGRDB.swift:208:81:208:81 | password : | testGRDB.swift:208:80:208:89 | [...] | This operation stores '[...]' in a database. It may contain unencrypted sensitive data from $@. | testGRDB.swift:208:81:208:81 | password : | password | | testGRDB.swift:210:84:210:93 | [...] | testGRDB.swift:210:85:210:85 | password : | testGRDB.swift:210:84:210:93 | [...] | This operation stores '[...]' in a database. It may contain unencrypted sensitive data from $@. | testGRDB.swift:210:85:210:85 | password : | password | | testGRDB.swift:212:98:212:107 | [...] | testGRDB.swift:212:99:212:99 | password : | testGRDB.swift:212:98:212:107 | [...] | This operation stores '[...]' in a database. It may contain unencrypted sensitive data from $@. | testGRDB.swift:212:99:212:99 | password : | password | -| testRealm.swift:34:2:34:2 | a | testRealm.swift:34:11:34:11 | myPassword : | testRealm.swift:34:2:34:2 | [post] a | This operation stores '[post] a' in a database. It may contain unencrypted sensitive data from $@. | testRealm.swift:34:11:34:11 | myPassword : | myPassword | -| testRealm.swift:42:2:42:2 | c | testRealm.swift:42:11:42:11 | myPassword : | testRealm.swift:42:2:42:2 | [post] c | This operation stores '[post] c' in a database. It may contain unencrypted sensitive data from $@. | testRealm.swift:42:11:42:11 | myPassword : | myPassword | -| testRealm.swift:52:2:52:3 | ...! | testRealm.swift:52:12:52:12 | myPassword : | testRealm.swift:52:2:52:3 | [post] ...! | This operation stores '[post] ...!' in a database. It may contain unencrypted sensitive data from $@. | testRealm.swift:52:12:52:12 | myPassword : | myPassword | -| testRealm.swift:59:2:59:2 | g | testRealm.swift:59:11:59:11 | myPassword : | testRealm.swift:59:2:59:2 | [post] g | This operation stores '[post] g' in a database. It may contain unencrypted sensitive data from $@. | testRealm.swift:59:11:59:11 | myPassword : | myPassword | +| testRealm.swift:34:2:34:2 | a | testRealm.swift:34:11:34:11 | myPassword : | testRealm.swift:34:2:34:2 | [post] a | This operation stores 'a' in a database. It may contain unencrypted sensitive data from $@. | testRealm.swift:34:11:34:11 | myPassword : | myPassword | +| testRealm.swift:42:2:42:2 | c | testRealm.swift:42:11:42:11 | myPassword : | testRealm.swift:42:2:42:2 | [post] c | This operation stores 'c' in a database. It may contain unencrypted sensitive data from $@. | testRealm.swift:42:11:42:11 | myPassword : | myPassword | +| testRealm.swift:52:2:52:3 | ...! | testRealm.swift:52:12:52:12 | myPassword : | testRealm.swift:52:2:52:3 | [post] ...! | This operation stores '...!' in a database. It may contain unencrypted sensitive data from $@. | testRealm.swift:52:12:52:12 | myPassword : | myPassword | +| testRealm.swift:59:2:59:2 | g | testRealm.swift:59:11:59:11 | myPassword : | testRealm.swift:59:2:59:2 | [post] g | This operation stores 'g' in a database. It may contain unencrypted sensitive data from $@. | testRealm.swift:59:11:59:11 | myPassword : | myPassword | From 725d784be89d43172108bc1bfbb863907d0754c2 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Tue, 14 Mar 2023 16:13:26 +0000 Subject: [PATCH 239/631] Swift: Make the same result presentation change to swift/cleartext-storage-preferences. --- .../Security/CWE-312/CleartextStoragePreferences.ql | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/swift/ql/src/queries/Security/CWE-312/CleartextStoragePreferences.ql b/swift/ql/src/queries/Security/CWE-312/CleartextStoragePreferences.ql index 051b7afb9aa..25944e293a0 100644 --- a/swift/ql/src/queries/Security/CWE-312/CleartextStoragePreferences.ql +++ b/swift/ql/src/queries/Security/CWE-312/CleartextStoragePreferences.ql @@ -25,10 +25,14 @@ DataFlow::Node cleanupNode(DataFlow::Node n) { result = n } -from CleartextStorageConfig config, DataFlow::PathNode sourceNode, DataFlow::PathNode sinkNode -where config.hasFlowPath(sourceNode, sinkNode) -select cleanupNode(sinkNode.getNode()), sourceNode, sinkNode, - "This operation stores '" + sinkNode.getNode().toString() + "' in " + +from + CleartextStorageConfig config, DataFlow::PathNode sourceNode, DataFlow::PathNode sinkNode, + DataFlow::Node cleanSink +where + config.hasFlowPath(sourceNode, sinkNode) and + cleanSink = cleanupNode(sinkNode.getNode()) +select cleanSink, sourceNode, sinkNode, + "This operation stores '" + cleanSink.toString() + "' in " + sinkNode.getNode().(CleartextStoragePreferencesSink).getStoreName() + ". It may contain unencrypted sensitive data from $@.", sourceNode, sourceNode.getNode().toString() From 01a85164eef3953f1be4dbf1fa16e26daf6b1e0b Mon Sep 17 00:00:00 2001 From: Harry Maclean Date: Wed, 15 Mar 2023 18:08:23 +1300 Subject: [PATCH 240/631] Ruby: Bump rust toolchain to 1.68 --- ruby/extractor/rust-toolchain.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ruby/extractor/rust-toolchain.toml b/ruby/extractor/rust-toolchain.toml index a4602066f4b..e56467f055c 100644 --- a/ruby/extractor/rust-toolchain.toml +++ b/ruby/extractor/rust-toolchain.toml @@ -2,6 +2,6 @@ # extractor. It is set to the lowest version of Rust we want to support. [toolchain] -channel = "1.54" +channel = "1.68" profile = "minimal" components = [ "rustfmt" ] From 907fbeaae83e55dbebacc22523b323d32e97e73f Mon Sep 17 00:00:00 2001 From: Harry Maclean Date: Wed, 15 Mar 2023 22:03:48 +1300 Subject: [PATCH 241/631] Ruby: Update build instructions for new extractor --- ruby/doc/HOWTO.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ruby/doc/HOWTO.md b/ruby/doc/HOWTO.md index d2c4c316db5..ccfb8c9bc5e 100644 --- a/ruby/doc/HOWTO.md +++ b/ruby/doc/HOWTO.md @@ -7,7 +7,7 @@ This document contains information about common development tasks. [Install Rust](https://www.rust-lang.org/tools/install), then run: ```bash -cargo build --release +(cd extractor && cargo build --release) ``` ## Generating the database schema and QL library @@ -16,7 +16,7 @@ The generated `ql/lib/ruby.dbscheme` and `ql/lib/codeql/ruby/ast/internal/TreeSi ```bash # Run the generator -cargo run --release -p ruby-generator -- --dbscheme ql/lib/ruby.dbscheme --library ql/lib/codeql/ruby/ast/internal/TreeSitter.qll +(cd extractor && cargo run --release --bin generator -- --dbscheme ../ql/lib/ruby.dbscheme --library ../ql/lib/codeql/ruby/ast/internal/TreeSitter.qll) # Then auto-format the QL library codeql query format -i ql/lib/codeql/ruby/ast/internal/TreeSitter.qll ``` From e7ead76fe98a046ffc3de9c1cbf9d1002c99bce1 Mon Sep 17 00:00:00 2001 From: Harry Maclean Date: Thu, 16 Mar 2023 12:04:33 +1300 Subject: [PATCH 242/631] Ruby: Build extractor via cargo-cross on linux --- .github/workflows/ruby-build.yml | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ruby-build.yml b/.github/workflows/ruby-build.yml index 6fdd497a802..c8c73d83024 100644 --- a/.github/workflows/ruby-build.yml +++ b/.github/workflows/ruby-build.yml @@ -48,6 +48,9 @@ jobs: run: | brew install gnu-tar echo "/usr/local/opt/gnu-tar/libexec/gnubin" >> $GITHUB_PATH + - name: Install cargo-cross + if: runner.os == 'Linux' + run: cargo install cross --version 0.2.1 - uses: ./.github/actions/os-version id: os_version - name: Cache entire extractor @@ -80,7 +83,15 @@ jobs: run: cd extractor && cargo test --verbose - name: Release build if: steps.cache-extractor.outputs.cache-hit != 'true' - run: cd extractor && cargo build --release + # On linux, build the extractor via cross in a centos7 container. + # This ensures we don't depend on glibc > 2.17. + run: | + if [[ "$RUNNER_OS" == "Linux" ]]; then + CARGO=cross + else + CARGO=cargo + fi + cd extractor && "$CARGO" build --release - name: Generate dbscheme if: ${{ matrix.os == 'ubuntu-latest' && steps.cache-extractor.outputs.cache-hit != 'true'}} run: extractor/target/release/generator --dbscheme ql/lib/ruby.dbscheme --library ql/lib/codeql/ruby/ast/internal/TreeSitter.qll From 7b81fe3109b26badd31c4afabd09a08779fb4222 Mon Sep 17 00:00:00 2001 From: Harry Maclean Date: Thu, 16 Mar 2023 12:11:12 +1300 Subject: [PATCH 243/631] Ruby: fix conditional use of cross in build --- .github/workflows/ruby-build.yml | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/.github/workflows/ruby-build.yml b/.github/workflows/ruby-build.yml index c8c73d83024..1e7746c8c40 100644 --- a/.github/workflows/ruby-build.yml +++ b/.github/workflows/ruby-build.yml @@ -81,17 +81,14 @@ jobs: - name: Run tests if: steps.cache-extractor.outputs.cache-hit != 'true' run: cd extractor && cargo test --verbose - - name: Release build - if: steps.cache-extractor.outputs.cache-hit != 'true' - # On linux, build the extractor via cross in a centos7 container. - # This ensures we don't depend on glibc > 2.17. - run: | - if [[ "$RUNNER_OS" == "Linux" ]]; then - CARGO=cross - else - CARGO=cargo - fi - cd extractor && "$CARGO" build --release + # On linux, build the extractor via cross in a centos7 container. + # This ensures we don't depend on glibc > 2.17. + - name: Release build (linux) + if: steps.cache-extractor.outputs.cache-hit != 'true' && runner.os == 'Linux' + run: cd extractor && cross build --release + - name: Release build (windows and macos) + if: steps.cache-extractor.outputs.cache-hit != 'true' && runner.os != 'Linux' + run: cd extractor && cargo build --release - name: Generate dbscheme if: ${{ matrix.os == 'ubuntu-latest' && steps.cache-extractor.outputs.cache-hit != 'true'}} run: extractor/target/release/generator --dbscheme ql/lib/ruby.dbscheme --library ql/lib/codeql/ruby/ast/internal/TreeSitter.qll From 0eb0c26b726cf2f9ead18e1c0ebd4c12ba59635b Mon Sep 17 00:00:00 2001 From: Harry Maclean Date: Thu, 16 Mar 2023 12:24:47 +1300 Subject: [PATCH 244/631] Ruby: Add some documentation This is primarily to bust the build cache. --- ruby/extractor/src/bin/extractor.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ruby/extractor/src/bin/extractor.rs b/ruby/extractor/src/bin/extractor.rs index 300a94444a6..c79e3e1b51c 100644 --- a/ruby/extractor/src/bin/extractor.rs +++ b/ruby/extractor/src/bin/extractor.rs @@ -320,6 +320,8 @@ fn scan_erb( (result, line_breaks) } +/// Advance `index` to the next non-whitespace character. +/// Newlines are **not** considered whitespace. fn skip_space(content: &[u8], index: usize) -> usize { let mut index = index; while index < content.len() { From 7feab09ea953f4f3614ec16a399bf8e306511db5 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Thu, 16 Mar 2023 08:57:31 +0000 Subject: [PATCH 245/631] Swift: Specialize the additional taint step a bit more. --- .../swift/security/CleartextStorageDatabaseExtensions.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/swift/ql/lib/codeql/swift/security/CleartextStorageDatabaseExtensions.qll b/swift/ql/lib/codeql/swift/security/CleartextStorageDatabaseExtensions.qll index b123b95354b..e8529ff5d06 100644 --- a/swift/ql/lib/codeql/swift/security/CleartextStorageDatabaseExtensions.qll +++ b/swift/ql/lib/codeql/swift/security/CleartextStorageDatabaseExtensions.qll @@ -137,7 +137,7 @@ private class CleartextStorageDatabaseArrayAdditionalTaintStep extends Cleartext // approximate; for example we might identify `passwordBox` as a source, // whereas it is more accurate to say that `passwordBox.textField` is the // true source). - nodeTo.asExpr().(LookupExpr).getBase() = nodeFrom.asExpr() + nodeTo.asExpr().(MemberRefExpr).getBase() = nodeFrom.asExpr() } } From 170fde5bc01fd540388ee9effa07435df3223771 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Thu, 16 Mar 2023 12:51:40 +0000 Subject: [PATCH 246/631] Swift: Add some more test cases. --- .../CWE-311/CleartextStorageDatabase.expected | 60 +++++++++++++++++++ .../Security/CWE-311/SensitiveExprs.expected | 2 + .../Security/CWE-311/testCoreData2.swift | 12 ++++ 3 files changed, 74 insertions(+) diff --git a/swift/ql/test/query-tests/Security/CWE-311/CleartextStorageDatabase.expected b/swift/ql/test/query-tests/Security/CWE-311/CleartextStorageDatabase.expected index a8cb322c75e..540cdad43da 100644 --- a/swift/ql/test/query-tests/Security/CWE-311/CleartextStorageDatabase.expected +++ b/swift/ql/test/query-tests/Security/CWE-311/CleartextStorageDatabase.expected @@ -1,6 +1,8 @@ edges +| file://:0:0:0:0 | self [value] : | file://:0:0:0:0 | .value : | | file://:0:0:0:0 | value : | file://:0:0:0:0 | [post] self [data] : | | file://:0:0:0:0 | value : | file://:0:0:0:0 | [post] self [notStoredBankAccountNumber] : | +| file://:0:0:0:0 | value : | file://:0:0:0:0 | [post] self [value] : | | testCoreData2.swift:23:13:23:13 | value : | file://:0:0:0:0 | value : | | testCoreData2.swift:37:2:37:2 | [post] obj [myValue] : | testCoreData2.swift:37:2:37:2 | [post] obj | | testCoreData2.swift:37:16:37:16 | bankAccountNo : | testCoreData2.swift:37:2:37:2 | [post] obj [myValue] : | @@ -29,6 +31,8 @@ edges | testCoreData2.swift:65:3:65:3 | [post] obj [myBankAccountNumber] : | testCoreData2.swift:65:3:65:3 | [post] obj | | testCoreData2.swift:65:29:65:29 | bankAccountNo : | testCoreData2.swift:65:3:65:3 | [post] obj [myBankAccountNumber] : | | testCoreData2.swift:70:9:70:9 | self : | file://:0:0:0:0 | .value : | +| testCoreData2.swift:70:9:70:9 | self [value] : | file://:0:0:0:0 | self [value] : | +| testCoreData2.swift:70:9:70:9 | value : | file://:0:0:0:0 | value : | | testCoreData2.swift:71:9:71:9 | self : | file://:0:0:0:0 | .value2 : | | testCoreData2.swift:79:2:79:2 | [post] dbObj [myValue] : | testCoreData2.swift:79:2:79:2 | [post] dbObj | | testCoreData2.swift:79:18:79:28 | .bankAccountNo : | testCoreData2.swift:79:2:79:2 | [post] dbObj [myValue] : | @@ -78,6 +82,30 @@ edges | testCoreData2.swift:92:10:92:12 | .value : | testCoreData2.swift:93:18:93:18 | b : | | testCoreData2.swift:93:2:93:2 | [post] dbObj [myValue] : | testCoreData2.swift:93:2:93:2 | [post] dbObj | | testCoreData2.swift:93:18:93:18 | b : | testCoreData2.swift:93:2:93:2 | [post] dbObj [myValue] : | +| testCoreData2.swift:95:10:95:10 | bankAccountNo : | testCoreData2.swift:97:12:97:12 | c : | +| testCoreData2.swift:95:10:95:10 | bankAccountNo : | testCoreData2.swift:97:12:97:14 | .value : | +| testCoreData2.swift:97:2:97:2 | [post] d [value] : | testCoreData2.swift:98:18:98:18 | d [value] : | +| testCoreData2.swift:97:12:97:12 | c : | testCoreData2.swift:70:9:70:9 | self : | +| testCoreData2.swift:97:12:97:12 | c : | testCoreData2.swift:97:12:97:14 | .value : | +| testCoreData2.swift:97:12:97:14 | .value : | testCoreData2.swift:70:9:70:9 | value : | +| testCoreData2.swift:97:12:97:14 | .value : | testCoreData2.swift:97:2:97:2 | [post] d [value] : | +| testCoreData2.swift:98:2:98:2 | [post] dbObj [myValue] : | testCoreData2.swift:98:2:98:2 | [post] dbObj | +| testCoreData2.swift:98:18:98:18 | d [value] : | testCoreData2.swift:70:9:70:9 | self [value] : | +| testCoreData2.swift:98:18:98:18 | d [value] : | testCoreData2.swift:98:18:98:20 | .value : | +| testCoreData2.swift:98:18:98:20 | .value : | testCoreData2.swift:98:2:98:2 | [post] dbObj [myValue] : | +| testCoreData2.swift:101:10:101:10 | bankAccountNo : | testCoreData2.swift:104:18:104:18 | e : | +| testCoreData2.swift:101:10:101:10 | bankAccountNo : | testCoreData2.swift:104:18:104:20 | .value : | +| testCoreData2.swift:101:10:101:10 | bankAccountNo : | testCoreData2.swift:105:18:105:18 | e : | +| testCoreData2.swift:101:10:101:10 | bankAccountNo : | testCoreData2.swift:105:18:105:20 | ...! : | +| testCoreData2.swift:104:2:104:2 | [post] dbObj [myValue] : | testCoreData2.swift:104:2:104:2 | [post] dbObj | +| testCoreData2.swift:104:18:104:18 | e : | testCoreData2.swift:70:9:70:9 | self : | +| testCoreData2.swift:104:18:104:18 | e : | testCoreData2.swift:104:18:104:20 | .value : | +| testCoreData2.swift:104:18:104:20 | .value : | testCoreData2.swift:104:2:104:2 | [post] dbObj [myValue] : | +| testCoreData2.swift:105:2:105:2 | [post] dbObj [myValue] : | testCoreData2.swift:105:2:105:2 | [post] dbObj | +| testCoreData2.swift:105:18:105:18 | e : | testCoreData2.swift:71:9:71:9 | self : | +| testCoreData2.swift:105:18:105:18 | e : | testCoreData2.swift:105:18:105:20 | .value2 : | +| testCoreData2.swift:105:18:105:20 | ...! : | testCoreData2.swift:105:2:105:2 | [post] dbObj [myValue] : | +| testCoreData2.swift:105:18:105:20 | .value2 : | testCoreData2.swift:105:18:105:20 | ...! : | | testCoreData.swift:18:19:18:26 | value : | testCoreData.swift:19:12:19:12 | value | | testCoreData.swift:31:3:31:3 | newValue : | testCoreData.swift:32:13:32:13 | newValue | | testCoreData.swift:61:25:61:25 | password : | testCoreData.swift:18:19:18:26 | value : | @@ -156,8 +184,12 @@ edges nodes | file://:0:0:0:0 | .value2 : | semmle.label | .value2 : | | file://:0:0:0:0 | .value : | semmle.label | .value : | +| file://:0:0:0:0 | .value : | semmle.label | .value : | | file://:0:0:0:0 | [post] self [data] : | semmle.label | [post] self [data] : | | file://:0:0:0:0 | [post] self [notStoredBankAccountNumber] : | semmle.label | [post] self [notStoredBankAccountNumber] : | +| file://:0:0:0:0 | [post] self [value] : | semmle.label | [post] self [value] : | +| file://:0:0:0:0 | self [value] : | semmle.label | self [value] : | +| file://:0:0:0:0 | value : | semmle.label | value : | | file://:0:0:0:0 | value : | semmle.label | value : | | file://:0:0:0:0 | value : | semmle.label | value : | | testCoreData2.swift:23:13:23:13 | value : | semmle.label | value : | @@ -198,6 +230,8 @@ nodes | testCoreData2.swift:65:3:65:3 | [post] obj [myBankAccountNumber] : | semmle.label | [post] obj [myBankAccountNumber] : | | testCoreData2.swift:65:29:65:29 | bankAccountNo : | semmle.label | bankAccountNo : | | testCoreData2.swift:70:9:70:9 | self : | semmle.label | self : | +| testCoreData2.swift:70:9:70:9 | self [value] : | semmle.label | self [value] : | +| testCoreData2.swift:70:9:70:9 | value : | semmle.label | value : | | testCoreData2.swift:71:9:71:9 | self : | semmle.label | self : | | testCoreData2.swift:79:2:79:2 | [post] dbObj | semmle.label | [post] dbObj | | testCoreData2.swift:79:2:79:2 | [post] dbObj [myValue] : | semmle.label | [post] dbObj [myValue] : | @@ -245,6 +279,24 @@ nodes | testCoreData2.swift:93:2:93:2 | [post] dbObj | semmle.label | [post] dbObj | | testCoreData2.swift:93:2:93:2 | [post] dbObj [myValue] : | semmle.label | [post] dbObj [myValue] : | | testCoreData2.swift:93:18:93:18 | b : | semmle.label | b : | +| testCoreData2.swift:95:10:95:10 | bankAccountNo : | semmle.label | bankAccountNo : | +| testCoreData2.swift:97:2:97:2 | [post] d [value] : | semmle.label | [post] d [value] : | +| testCoreData2.swift:97:12:97:12 | c : | semmle.label | c : | +| testCoreData2.swift:97:12:97:14 | .value : | semmle.label | .value : | +| testCoreData2.swift:98:2:98:2 | [post] dbObj | semmle.label | [post] dbObj | +| testCoreData2.swift:98:2:98:2 | [post] dbObj [myValue] : | semmle.label | [post] dbObj [myValue] : | +| testCoreData2.swift:98:18:98:18 | d [value] : | semmle.label | d [value] : | +| testCoreData2.swift:98:18:98:20 | .value : | semmle.label | .value : | +| testCoreData2.swift:101:10:101:10 | bankAccountNo : | semmle.label | bankAccountNo : | +| testCoreData2.swift:104:2:104:2 | [post] dbObj | semmle.label | [post] dbObj | +| testCoreData2.swift:104:2:104:2 | [post] dbObj [myValue] : | semmle.label | [post] dbObj [myValue] : | +| testCoreData2.swift:104:18:104:18 | e : | semmle.label | e : | +| testCoreData2.swift:104:18:104:20 | .value : | semmle.label | .value : | +| testCoreData2.swift:105:2:105:2 | [post] dbObj | semmle.label | [post] dbObj | +| testCoreData2.swift:105:2:105:2 | [post] dbObj [myValue] : | semmle.label | [post] dbObj [myValue] : | +| testCoreData2.swift:105:18:105:18 | e : | semmle.label | e : | +| testCoreData2.swift:105:18:105:20 | ...! : | semmle.label | ...! : | +| testCoreData2.swift:105:18:105:20 | .value2 : | semmle.label | .value2 : | | testCoreData.swift:18:19:18:26 | value : | semmle.label | value : | | testCoreData.swift:19:12:19:12 | value | semmle.label | value | | testCoreData.swift:31:3:31:3 | newValue : | semmle.label | newValue : | @@ -392,6 +444,11 @@ subpaths | testCoreData2.swift:88:22:88:22 | bankAccountNo : | testCoreData2.swift:70:9:70:9 | self : | file://:0:0:0:0 | .value : | testCoreData2.swift:88:22:88:36 | .value : | | testCoreData2.swift:89:22:89:22 | ...! : | testCoreData2.swift:71:9:71:9 | self : | file://:0:0:0:0 | .value2 : | testCoreData2.swift:89:22:89:37 | .value2 : | | testCoreData2.swift:92:10:92:10 | a : | testCoreData2.swift:70:9:70:9 | self : | file://:0:0:0:0 | .value : | testCoreData2.swift:92:10:92:12 | .value : | +| testCoreData2.swift:97:12:97:12 | c : | testCoreData2.swift:70:9:70:9 | self : | file://:0:0:0:0 | .value : | testCoreData2.swift:97:12:97:14 | .value : | +| testCoreData2.swift:97:12:97:14 | .value : | testCoreData2.swift:70:9:70:9 | value : | file://:0:0:0:0 | [post] self [value] : | testCoreData2.swift:97:2:97:2 | [post] d [value] : | +| testCoreData2.swift:98:18:98:18 | d [value] : | testCoreData2.swift:70:9:70:9 | self [value] : | file://:0:0:0:0 | .value : | testCoreData2.swift:98:18:98:20 | .value : | +| testCoreData2.swift:104:18:104:18 | e : | testCoreData2.swift:70:9:70:9 | self : | file://:0:0:0:0 | .value : | testCoreData2.swift:104:18:104:20 | .value : | +| testCoreData2.swift:105:18:105:18 | e : | testCoreData2.swift:71:9:71:9 | self : | file://:0:0:0:0 | .value2 : | testCoreData2.swift:105:18:105:20 | .value2 : | | testRealm.swift:34:11:34:11 | myPassword : | testRealm.swift:16:6:16:6 | value : | file://:0:0:0:0 | [post] self [data] : | testRealm.swift:34:2:34:2 | [post] a [data] : | | testRealm.swift:42:11:42:11 | myPassword : | testRealm.swift:16:6:16:6 | value : | file://:0:0:0:0 | [post] self [data] : | testRealm.swift:42:2:42:2 | [post] c [data] : | | testRealm.swift:52:12:52:12 | myPassword : | testRealm.swift:16:6:16:6 | value : | file://:0:0:0:0 | [post] self [data] : | testRealm.swift:52:2:52:3 | [post] ...! [data] : | @@ -419,6 +476,9 @@ subpaths | testCoreData2.swift:88:2:88:10 | ...? | testCoreData2.swift:88:22:88:22 | bankAccountNo : | testCoreData2.swift:88:2:88:10 | [post] ...? | This operation stores '...?' in a database. It may contain unencrypted sensitive data from $@. | testCoreData2.swift:88:22:88:22 | bankAccountNo : | bankAccountNo | | testCoreData2.swift:89:2:89:10 | ...? | testCoreData2.swift:89:22:89:22 | bankAccountNo2 : | testCoreData2.swift:89:2:89:10 | [post] ...? | This operation stores '...?' in a database. It may contain unencrypted sensitive data from $@. | testCoreData2.swift:89:22:89:22 | bankAccountNo2 : | bankAccountNo2 | | testCoreData2.swift:93:2:93:2 | dbObj | testCoreData2.swift:91:10:91:10 | bankAccountNo : | testCoreData2.swift:93:2:93:2 | [post] dbObj | This operation stores 'dbObj' in a database. It may contain unencrypted sensitive data from $@. | testCoreData2.swift:91:10:91:10 | bankAccountNo : | bankAccountNo | +| testCoreData2.swift:98:2:98:2 | dbObj | testCoreData2.swift:95:10:95:10 | bankAccountNo : | testCoreData2.swift:98:2:98:2 | [post] dbObj | This operation stores 'dbObj' in a database. It may contain unencrypted sensitive data from $@. | testCoreData2.swift:95:10:95:10 | bankAccountNo : | bankAccountNo | +| testCoreData2.swift:104:2:104:2 | dbObj | testCoreData2.swift:101:10:101:10 | bankAccountNo : | testCoreData2.swift:104:2:104:2 | [post] dbObj | This operation stores 'dbObj' in a database. It may contain unencrypted sensitive data from $@. | testCoreData2.swift:101:10:101:10 | bankAccountNo : | bankAccountNo | +| testCoreData2.swift:105:2:105:2 | dbObj | testCoreData2.swift:101:10:101:10 | bankAccountNo : | testCoreData2.swift:105:2:105:2 | [post] dbObj | This operation stores 'dbObj' in a database. It may contain unencrypted sensitive data from $@. | testCoreData2.swift:101:10:101:10 | bankAccountNo : | bankAccountNo | | testCoreData.swift:19:12:19:12 | value | testCoreData.swift:61:25:61:25 | password : | testCoreData.swift:19:12:19:12 | value | This operation stores 'value' in a database. It may contain unencrypted sensitive data from $@. | testCoreData.swift:61:25:61:25 | password : | password | | testCoreData.swift:32:13:32:13 | newValue | testCoreData.swift:64:16:64:16 | password : | testCoreData.swift:32:13:32:13 | newValue | This operation stores 'newValue' in a database. It may contain unencrypted sensitive data from $@. | testCoreData.swift:64:16:64:16 | password : | password | | testCoreData.swift:48:15:48:15 | password | testCoreData.swift:48:15:48:15 | password | testCoreData.swift:48:15:48:15 | password | This operation stores 'password' in a database. It may contain unencrypted sensitive data from $@. | testCoreData.swift:48:15:48:15 | password | password | 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 9a80108ad02..4f0e89775e4 100644 --- a/swift/ql/test/query-tests/Security/CWE-311/SensitiveExprs.expected +++ b/swift/ql/test/query-tests/Security/CWE-311/SensitiveExprs.expected @@ -46,6 +46,8 @@ | testCoreData2.swift:88:22:88:22 | bankAccountNo | label:bankAccountNo, type:private information | | testCoreData2.swift:89:22:89:22 | bankAccountNo2 | label:bankAccountNo2, type:private information | | testCoreData2.swift:91:10:91:10 | bankAccountNo | label:bankAccountNo, type:private information | +| testCoreData2.swift:95:10:95:10 | bankAccountNo | label:bankAccountNo, type:private information | +| testCoreData2.swift:101:10:101:10 | bankAccountNo | label:bankAccountNo, type:private information | | 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/testCoreData2.swift b/swift/ql/test/query-tests/Security/CWE-311/testCoreData2.swift index c0db195bf67..9cb61b3bd77 100644 --- a/swift/ql/test/query-tests/Security/CWE-311/testCoreData2.swift +++ b/swift/ql/test/query-tests/Security/CWE-311/testCoreData2.swift @@ -91,4 +91,16 @@ func testCoreData2_3(dbObj: MyManagedObject2, maybeObj: MyManagedObject2?, conta var a = bankAccountNo // sensitive var b = a.value dbObj.myValue = b // BAD + + let c = bankAccountNo // sensitive + var d: MyContainer = MyContainer() + d.value = c.value + dbObj.myValue = d.value // BAD + dbObj.myValue = d.value2 // GOOD + + let e = bankAccountNo // sensitive + var f: MyContainer? + f?.value = e.value + dbObj.myValue = e.value // BAD + dbObj.myValue = e.value2 // GOOD [FALSE POSITIVE] } From d4020ad3059a1ee4fbe0d26becbab708fee1a9fe Mon Sep 17 00:00:00 2001 From: Harry Maclean Date: Fri, 17 Mar 2023 10:31:58 +1300 Subject: [PATCH 247/631] Ruby: Run extractor test on centos 7 --- .github/workflows/ruby-build.yml | 39 ++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/.github/workflows/ruby-build.yml b/.github/workflows/ruby-build.yml index 1e7746c8c40..b06fc70bf9e 100644 --- a/.github/workflows/ruby-build.yml +++ b/.github/workflows/ruby-build.yml @@ -235,3 +235,42 @@ jobs: shell: bash run: | codeql database analyze --search-path "${{ runner.temp }}/ruby-bundle" --format=sarifv2.1.0 --output=out.sarif ../database ruby-code-scanning.qls + + # This is a copy of the 'test' job that runs in a centos7 container. + # This tests that the extractor works correctly on systems with an old glibc. + test-centos7: + defaults: + run: + working-directory: ${{ github.workspace }} + strategy: + fail-fast: false + runs-on: ubuntu-latest + container: + image: centos:centos7 + needs: [package] + steps: + - uses: actions/checkout@v3 + - name: Fetch CodeQL + uses: ./.github/actions/fetch-codeql + + - name: Download Ruby bundle + uses: actions/download-artifact@v3 + with: + name: codeql-ruby-bundle + path: ${{ runner.temp }} + - name: Unzip Ruby bundle + shell: bash + run: unzip -q -d "${{ runner.temp }}/ruby-bundle" "${{ runner.temp }}/codeql-ruby-bundle.zip" + + - name: Run QL test + shell: bash + run: | + codeql test run --search-path "${{ runner.temp }}/ruby-bundle" --additional-packs "${{ runner.temp }}/ruby-bundle" ruby/ql/test/library-tests/ast/constants/ + - name: Create database + shell: bash + run: | + codeql database create --search-path "${{ runner.temp }}/ruby-bundle" --language ruby --source-root ruby/ql/test/library-tests/ast/constants/ ../database + - name: Analyze database + shell: bash + run: | + codeql database analyze --search-path "${{ runner.temp }}/ruby-bundle" --format=sarifv2.1.0 --output=out.sarif ../database ruby-code-scanning.qls From c447e125bbd775f6f407c1495ecfe6fb4093c8ec Mon Sep 17 00:00:00 2001 From: Harry Maclean Date: Fri, 17 Mar 2023 10:59:49 +1300 Subject: [PATCH 248/631] Ruby: Install gh cli in centos7 test --- .github/workflows/ruby-build.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/workflows/ruby-build.yml b/.github/workflows/ruby-build.yml index b06fc70bf9e..3449c87fdaa 100644 --- a/.github/workflows/ruby-build.yml +++ b/.github/workflows/ruby-build.yml @@ -247,8 +247,14 @@ jobs: runs-on: ubuntu-latest container: image: centos:centos7 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} needs: [package] steps: + - name: Install gh cli + run: | + yum-config-manager --add-repo https://cli.github.com/packages/rpm/gh-cli.repo + yum install -y gh - uses: actions/checkout@v3 - name: Fetch CodeQL uses: ./.github/actions/fetch-codeql From 2abb03304dc2ee0db01872492b7440578d55d6ad Mon Sep 17 00:00:00 2001 From: Harry Maclean Date: Fri, 17 Mar 2023 11:56:04 +1300 Subject: [PATCH 249/631] Install required dependencies for gh in centos 7 --- .github/workflows/ruby-build.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ruby-build.yml b/.github/workflows/ruby-build.yml index 3449c87fdaa..a40c19662f5 100644 --- a/.github/workflows/ruby-build.yml +++ b/.github/workflows/ruby-build.yml @@ -254,7 +254,10 @@ jobs: - name: Install gh cli run: | yum-config-manager --add-repo https://cli.github.com/packages/rpm/gh-cli.repo - yum install -y gh + # fetch-codeql requires unzip and jq + # jq is available in epel-release (https://docs.fedoraproject.org/en-US/epel/) + yum install -y gh unzip epel-release + yum install -y jq - uses: actions/checkout@v3 - name: Fetch CodeQL uses: ./.github/actions/fetch-codeql From 5332344e5d4ad8e87b7ada11f780754d89a14e89 Mon Sep 17 00:00:00 2001 From: Harry Maclean Date: Fri, 17 Mar 2023 12:13:30 +1300 Subject: [PATCH 250/631] Work around github actions bug --- .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 a40c19662f5..1445d0c6589 100644 --- a/.github/workflows/ruby-build.yml +++ b/.github/workflows/ruby-build.yml @@ -262,24 +262,29 @@ jobs: - name: Fetch CodeQL uses: ./.github/actions/fetch-codeql + # Due to a bug in Actions, we can't use runner.temp here. + # https://github.com/actions/runner/issues/2185 + - name: Ensure temp directory exists + run: mkdir -p /tmp + - name: Download Ruby bundle uses: actions/download-artifact@v3 with: name: codeql-ruby-bundle - path: ${{ runner.temp }} + path: /tmp - name: Unzip Ruby bundle shell: bash - run: unzip -q -d "${{ runner.temp }}/ruby-bundle" "${{ runner.temp }}/codeql-ruby-bundle.zip" + run: unzip -q -d /tmp/ruby-bundle /tmp/codeql-ruby-bundle.zip - name: Run QL test shell: bash run: | - codeql test run --search-path "${{ runner.temp }}/ruby-bundle" --additional-packs "${{ runner.temp }}/ruby-bundle" ruby/ql/test/library-tests/ast/constants/ + codeql test run --search-path /tmp/ruby-bundle --additional-packs /tmp/ruby-bundle ruby/ql/test/library-tests/ast/constants/ - name: Create database shell: bash run: | - codeql database create --search-path "${{ runner.temp }}/ruby-bundle" --language ruby --source-root ruby/ql/test/library-tests/ast/constants/ ../database + codeql database create --search-path /tmp/ruby-bundle --language ruby --source-root ruby/ql/test/library-tests/ast/constants/ ../database - name: Analyze database shell: bash run: | - codeql database analyze --search-path "${{ runner.temp }}/ruby-bundle" --format=sarifv2.1.0 --output=out.sarif ../database ruby-code-scanning.qls + codeql database analyze --search-path /tmp/ruby-bundle --format=sarifv2.1.0 --output=out.sarif ../database ruby-code-scanning.qls From fcf1f6a6f9ff85cc98f7b59cbf8f5e212ae2b3ea Mon Sep 17 00:00:00 2001 From: Ian Lynagh Date: Mon, 20 Mar 2023 11:49:54 +0000 Subject: [PATCH 251/631] Kotlin: Don't use distutils in build script We were getting DeprecationWarning: The distutils package is deprecated and slated for removal in Python 3.12. Use setuptools or check PEP 632 for potential alternatives during the build. --- java/kotlin-extractor/build.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/java/kotlin-extractor/build.py b/java/kotlin-extractor/build.py index f31484bdec3..b52ff05b00e 100755 --- a/java/kotlin-extractor/build.py +++ b/java/kotlin-extractor/build.py @@ -11,8 +11,6 @@ import os import os.path import sys import shlex -import distutils -from distutils import dir_util def parse_args(): @@ -203,7 +201,7 @@ def compile(jars, java_jars, dependency_folder, transform_to_embeddable, output, version.replace('.', '_') if os.path.exists(d): # copy and overwrite files from the version folder to the include folder - distutils.dir_util.copy_tree(d, include_version_folder) + shutil.copytree(d, include_version_folder, dirs_exist_ok=True) # remove all version folders: for version in kotlin_plugin_versions.many_versions: From 116108851f08953d2e258273c953e91780f3b2c7 Mon Sep 17 00:00:00 2001 From: Stephan Brandauer Date: Mon, 20 Mar 2023 13:45:39 +0100 Subject: [PATCH 252/631] Update MaD Declarations after Triage --- java/ql/lib/ext/hudson.cli.model.yml | 6 ++++++ java/ql/lib/ext/hudson.lifecycle.model.yml | 6 ++++++ java/ql/lib/ext/hudson.model.yml | 24 ++++++++++++++++++++++ java/ql/lib/ext/hudson.util.io.model.yml | 7 +++++++ 4 files changed, 43 insertions(+) create mode 100644 java/ql/lib/ext/hudson.cli.model.yml create mode 100644 java/ql/lib/ext/hudson.lifecycle.model.yml create mode 100644 java/ql/lib/ext/hudson.model.yml create mode 100644 java/ql/lib/ext/hudson.util.io.model.yml diff --git a/java/ql/lib/ext/hudson.cli.model.yml b/java/ql/lib/ext/hudson.cli.model.yml new file mode 100644 index 00000000000..5ac446f2b7c --- /dev/null +++ b/java/ql/lib/ext/hudson.cli.model.yml @@ -0,0 +1,6 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: sinkModel + data: + - ["hudson.cli", "FullDuplexHttpStream", True, "FullDuplexHttpStream", "(URL,String,String)", "", "Argument[0]", "open-url", "ai-generated"] diff --git a/java/ql/lib/ext/hudson.lifecycle.model.yml b/java/ql/lib/ext/hudson.lifecycle.model.yml new file mode 100644 index 00000000000..84fae40ab92 --- /dev/null +++ b/java/ql/lib/ext/hudson.lifecycle.model.yml @@ -0,0 +1,6 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: sinkModel + data: + - ["hudson.lifecycle", "Lifecycle", True, "rewriteHudsonWar", "(File)", "", "Argument[0]", "create-file", "ai-generated"] diff --git a/java/ql/lib/ext/hudson.model.yml b/java/ql/lib/ext/hudson.model.yml new file mode 100644 index 00000000000..cb640c09361 --- /dev/null +++ b/java/ql/lib/ext/hudson.model.yml @@ -0,0 +1,24 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: sinkModel + data: + - ["hudson", "FilePath", False, "copyFrom", "(FileItem)", "", "Argument[0]", "read-file", "ai-generated"] + - ["hudson", "FilePath", False, "copyRecursiveTo", "(DirScanner,FilePath,String,TarCompression)", "", "Argument[1]", "create-file", "ai-generated"] + - ["hudson", "FilePath", False, "copyRecursiveTo", "(DirScanner,FilePath,String)", "", "Argument[1]", "write-file", "ai-generated"] + - ["hudson", "FilePath", False, "copyRecursiveTo", "(String,FilePath)", "", "Argument[1]", "create-file", "ai-generated"] + - ["hudson", "FilePath", False, "copyRecursiveTo", "(String,String,FilePath)", "", "Argument[0]", "read-file", "ai-generated"] + - ["hudson", "FilePath", False, "copyRecursiveTo", "(String,String,FilePath)", "", "Argument[2]", "create-file", "ai-generated"] + - ["hudson", "FilePath", False, "copyTo", "(FilePath)", "", "Argument[0]", "create-file", "ai-generated"] + - ["hudson", "FilePath", False, "installIfNecessaryFrom", "(URL,TaskListener,String)", "", "Argument[0]", "open-url", "ai-generated"] + - ["hudson", "FilePath", False, "newInputStreamDenyingSymlinkAsNeeded", "(File,String,boolean)", "", "Argument[0]", "read-file", "ai-generated"] + - addsTo: + pack: codeql/java-all + extensible: summaryModel + data: + - ["hudson", "FilePath", False, "child", "(String)", "", "Argument[0]", "ReturnValue", "taint", "ai-generated"] + - ["hudson", "FilePath", False, "list", "(String,String,boolean)", "", "Argument[0]", "ReturnValue", "taint", "ai-generated"] + - ["hudson", "FilePath", False, "list", "(String,String,boolean)", "", "Argument[1]", "ReturnValue", "taint", "ai-generated"] + - ["hudson", "FilePath", False, "list", "(String)", "", "Argument[0]", "ReturnValue", "taint", "ai-generated"] + - ["hudson", "FilePath", False, "normalize", "(String)", "", "Argument[0]", "ReturnValue", "taint", "ai-generated"] + - ["hudson", "FilePath", False, "sibling", "(String)", "", "Argument[0]", "ReturnValue", "taint", "ai-generated"] diff --git a/java/ql/lib/ext/hudson.util.io.model.yml b/java/ql/lib/ext/hudson.util.io.model.yml new file mode 100644 index 00000000000..a629beab66c --- /dev/null +++ b/java/ql/lib/ext/hudson.util.io.model.yml @@ -0,0 +1,7 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: sinkModel + data: + - ["hudson.util.io", "ReopenableFileOutputStream", True, "ReopenableFileOutputStream", "(File)", "", "Argument[0]", "create-file", "ai-generated"] + - ["hudson.util.io", "RewindableFileOutputStream", True, "RewindableFileOutputStream", "(File)", "", "Argument[0]", "create-file", "ai-generated"] From 6a5db750c4543da479e2318325a2e685a6cfeecc Mon Sep 17 00:00:00 2001 From: Rasmus Lerchedahl Petersen Date: Mon, 20 Mar 2023 15:07:46 +0100 Subject: [PATCH 253/631] python: add test to validation (and fix it) --- python/ql/test/experimental/dataflow/validTest.py | 1 + .../test/experimental/dataflow/variable-capture/collections.py | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/python/ql/test/experimental/dataflow/validTest.py b/python/ql/test/experimental/dataflow/validTest.py index c2280521113..585f2fbf776 100644 --- a/python/ql/test/experimental/dataflow/validTest.py +++ b/python/ql/test/experimental/dataflow/validTest.py @@ -67,6 +67,7 @@ if __name__ == "__main__": check_tests_valid("variable-capture.in") check_tests_valid("variable-capture.nonlocal") check_tests_valid("variable-capture.dict") + check_tests_valid("variable-capture.collections") check_tests_valid("module-initialization.multiphase") check_tests_valid("fieldflow.test") check_tests_valid_after_version("match.test", (3, 10)) diff --git a/python/ql/test/experimental/dataflow/variable-capture/collections.py b/python/ql/test/experimental/dataflow/variable-capture/collections.py index 11504695ceb..0920c8d595a 100644 --- a/python/ql/test/experimental/dataflow/variable-capture/collections.py +++ b/python/ql/test/experimental/dataflow/variable-capture/collections.py @@ -31,7 +31,7 @@ def SINK_F(x): print("OK") l = [NONSOURCE] -SINK_F(l_mod[0]) +SINK_F(l[0]) l_mod = [SOURCE for x in l] SINK(l_mod[0]) #$ captured From 93c9f59e868752157af239bd10d6a4b4b2f68be3 Mon Sep 17 00:00:00 2001 From: Rasmus Wriedt Larsen Date: Mon, 20 Mar 2023 15:39:20 +0100 Subject: [PATCH 254/631] Python: Extract version specific coverage/classes.py tests Since we can analyze operator.py from Python3, but not in Python 2 (since it's implemented in C), we get a difference for the index tests. note: `operator.length_hint` is only available in Python 3.4 and later, so would always fail under Python 2. --- .../coverage-py2/argumentRoutingTest.expected | 0 .../coverage-py2/argumentRoutingTest.qlref | 1 + .../dataflow/coverage-py2/classes.py | 54 ++++++++++++++ .../coverage-py3/argumentRoutingTest.expected | 0 .../coverage-py3/argumentRoutingTest.qlref | 1 + .../dataflow/coverage-py3/classes.py | 72 +++++++++++++++++++ .../experimental/dataflow/coverage/classes.py | 22 ------ .../test/experimental/dataflow/validTest.py | 2 + 8 files changed, 130 insertions(+), 22 deletions(-) create mode 100644 python/ql/test/experimental/dataflow/coverage-py2/argumentRoutingTest.expected create mode 100644 python/ql/test/experimental/dataflow/coverage-py2/argumentRoutingTest.qlref create mode 100644 python/ql/test/experimental/dataflow/coverage-py2/classes.py create mode 100644 python/ql/test/experimental/dataflow/coverage-py3/argumentRoutingTest.expected create mode 100644 python/ql/test/experimental/dataflow/coverage-py3/argumentRoutingTest.qlref create mode 100644 python/ql/test/experimental/dataflow/coverage-py3/classes.py diff --git a/python/ql/test/experimental/dataflow/coverage-py2/argumentRoutingTest.expected b/python/ql/test/experimental/dataflow/coverage-py2/argumentRoutingTest.expected new file mode 100644 index 00000000000..e69de29bb2d diff --git a/python/ql/test/experimental/dataflow/coverage-py2/argumentRoutingTest.qlref b/python/ql/test/experimental/dataflow/coverage-py2/argumentRoutingTest.qlref new file mode 100644 index 00000000000..58bedc4c88c --- /dev/null +++ b/python/ql/test/experimental/dataflow/coverage-py2/argumentRoutingTest.qlref @@ -0,0 +1 @@ +../coverage/argumentRoutingTest.ql diff --git a/python/ql/test/experimental/dataflow/coverage-py2/classes.py b/python/ql/test/experimental/dataflow/coverage-py2/classes.py new file mode 100644 index 00000000000..48dbaea8e93 --- /dev/null +++ b/python/ql/test/experimental/dataflow/coverage-py2/classes.py @@ -0,0 +1,54 @@ +# Python 2 specific tests, like the one in coverage/classes.py +# +# User-defined methods, both instance methods and class methods, can be called in many non-standard ways +# i.e. differently from simply `c.f()` or `C.f()`. For example, a user-defined `__await__` method on a +# class `C` will be called by the syntactic construct `await c` when `c` is an instance of `C`. +# +# These tests should cover all the class calls that we hope to support. +# It is based on https://docs.python.org/3/reference/datamodel.html, and headings refer there. +# +# All functions starting with "test_" should run and execute `print("OK")` exactly once. +# This can be checked by running validTest.py. + +import sys +import os + +sys.path.append(os.path.dirname(os.path.dirname((__file__)))) +from testlib import expects + + +def SINK1(x): + pass + + +def SINK2(x): + pass + + +def SINK3(x): + pass + + +def SINK4(x): + pass + + +def OK(): + print("OK") + + +# 3.3.8. Emulating numeric types + +# object.__index__(self) +class With_index: + def __index__(self): + SINK1(self) + OK() # Call not found + return 0 + + +def test_index(): + import operator + + with_index = With_index() #$ MISSING: arg1="SSA variable with_index" func=With_index.__index__ + operator.index(with_index) diff --git a/python/ql/test/experimental/dataflow/coverage-py3/argumentRoutingTest.expected b/python/ql/test/experimental/dataflow/coverage-py3/argumentRoutingTest.expected new file mode 100644 index 00000000000..e69de29bb2d diff --git a/python/ql/test/experimental/dataflow/coverage-py3/argumentRoutingTest.qlref b/python/ql/test/experimental/dataflow/coverage-py3/argumentRoutingTest.qlref new file mode 100644 index 00000000000..58bedc4c88c --- /dev/null +++ b/python/ql/test/experimental/dataflow/coverage-py3/argumentRoutingTest.qlref @@ -0,0 +1 @@ +../coverage/argumentRoutingTest.ql diff --git a/python/ql/test/experimental/dataflow/coverage-py3/classes.py b/python/ql/test/experimental/dataflow/coverage-py3/classes.py new file mode 100644 index 00000000000..308c79acbb4 --- /dev/null +++ b/python/ql/test/experimental/dataflow/coverage-py3/classes.py @@ -0,0 +1,72 @@ +# Python 3 specific tests, like the one in coverage/classes.py +# +# User-defined methods, both instance methods and class methods, can be called in many non-standard ways +# i.e. differently from simply `c.f()` or `C.f()`. For example, a user-defined `__await__` method on a +# class `C` will be called by the syntactic construct `await c` when `c` is an instance of `C`. +# +# These tests should cover all the class calls that we hope to support. +# It is based on https://docs.python.org/3/reference/datamodel.html, and headings refer there. +# +# All functions starting with "test_" should run and execute `print("OK")` exactly once. +# This can be checked by running validTest.py. + +import sys +import os + +sys.path.append(os.path.dirname(os.path.dirname((__file__)))) +from testlib import expects + + +def SINK1(x): + pass + + +def SINK2(x): + pass + + +def SINK3(x): + pass + + +def SINK4(x): + pass + + +def OK(): + print("OK") + + + +# 3.3.7. Emulating container types + +# object.__length_hint__(self) +class With_length_hint: + def __length_hint__(self): + SINK1(self) + OK() + return 0 + + +def test_length_hint(): + import operator + + with_length_hint = With_length_hint() #$ arg1="SSA variable with_length_hint" func=With_length_hint.__length_hint__ + operator.length_hint(with_length_hint) + + +# 3.3.8. Emulating numeric types + +# object.__index__(self) +class With_index: + def __index__(self): + SINK1(self) + OK() # Call not found + return 0 + + +def test_index(): + import operator + + with_index = With_index() #$ arg1="SSA variable with_index" func=With_index.__index__ + operator.index(with_index) diff --git a/python/ql/test/experimental/dataflow/coverage/classes.py b/python/ql/test/experimental/dataflow/coverage/classes.py index 664adedcc00..2569921d6c9 100644 --- a/python/ql/test/experimental/dataflow/coverage/classes.py +++ b/python/ql/test/experimental/dataflow/coverage/classes.py @@ -535,21 +535,6 @@ def test_len_if(): pass -# object.__length_hint__(self) -class With_length_hint: - def __length_hint__(self): - SINK1(self) - OK() # Call not found - return 0 - - -def test_length_hint(): - import operator - - with_length_hint = With_length_hint() #$ arg1="SSA variable with_length_hint" func=With_length_hint.__length_hint__ - operator.length_hint(with_length_hint) - - # object.__getitem__(self, key) class With_getitem: def __getitem__(self, key): @@ -1378,13 +1363,6 @@ class With_index: return 0 -def test_index(): - import operator - - with_index = With_index() #$ arg1="SSA variable with_index" func=With_index.__index__ - operator.index(with_index) - - def test_index_slicing(): with_index = With_index() #$ MISSING: arg1="SSA variable with_index" func=With_index.__index__ [0][with_index:1] diff --git a/python/ql/test/experimental/dataflow/validTest.py b/python/ql/test/experimental/dataflow/validTest.py index c2280521113..b12ee2953f8 100644 --- a/python/ql/test/experimental/dataflow/validTest.py +++ b/python/ql/test/experimental/dataflow/validTest.py @@ -64,6 +64,8 @@ if __name__ == "__main__": check_tests_valid("coverage.test") check_tests_valid("coverage.argumentPassing") check_tests_valid("coverage.datamodel") + check_tests_valid("coverage-py2.classes") + check_tests_valid("coverage-py3.classes") check_tests_valid("variable-capture.in") check_tests_valid("variable-capture.nonlocal") check_tests_valid("variable-capture.dict") From c3cb3ad4776b3adf46615ef9ee9dc6918fb1bdc4 Mon Sep 17 00:00:00 2001 From: Raul Garcia Date: Mon, 20 Mar 2023 18:32:37 -0700 Subject: [PATCH 255/631] Cleaning up main branch Cleaning up main branch --- .../WinCng/WindowsCng.qll | 118 ------------------ .../WinCng/WindowsCngPQCVulnerableUsage.ql | 22 ---- .../WinCng/WindowsCngPQCVulnerableUsage.qll | 70 ----------- 3 files changed, 210 deletions(-) delete mode 100644 cpp/ql/src/experimental/campaigns/nccoe-pqc-migration/QuantumVulnerableDiscovery/WinCng/WindowsCng.qll delete mode 100644 cpp/ql/src/experimental/campaigns/nccoe-pqc-migration/QuantumVulnerableDiscovery/WinCng/WindowsCngPQCVulnerableUsage.ql delete mode 100644 cpp/ql/src/experimental/campaigns/nccoe-pqc-migration/QuantumVulnerableDiscovery/WinCng/WindowsCngPQCVulnerableUsage.qll diff --git a/cpp/ql/src/experimental/campaigns/nccoe-pqc-migration/QuantumVulnerableDiscovery/WinCng/WindowsCng.qll b/cpp/ql/src/experimental/campaigns/nccoe-pqc-migration/QuantumVulnerableDiscovery/WinCng/WindowsCng.qll deleted file mode 100644 index 72a4d7df8a9..00000000000 --- a/cpp/ql/src/experimental/campaigns/nccoe-pqc-migration/QuantumVulnerableDiscovery/WinCng/WindowsCng.qll +++ /dev/null @@ -1,118 +0,0 @@ -import cpp -import DataFlow::PathGraph -import semmle.code.cpp.dataflow.TaintTracking - -/** - * Base abstract class to be extended to allow indirect extensions of vulnerable sinks. - */ -abstract class BCryptOpenAlgorithmProviderSink extends DataFlow::Node { } - -/** - * Base abstract class to be extended to allow indirect extensions of vulnerable sources. - */ -abstract class BCryptOpenAlgorithmProviderSource extends DataFlow::Node { } - -// ------------------ Helper Predicates ---------------------- -/** - * Holds if there is a call with global name`funcGlobalName` with argument `arg` of that call - * at argument index `index`. - */ -predicate isCallArgument(string funcGlobalName, Expr arg, int index) { - exists(Call c | c.getArgument(index) = arg and c.getTarget().hasGlobalName(funcGlobalName)) -} - -/** - * Holdes if StringLiteral `lit` has a string value indicative of a post quantum crypto - * vulnerable algorithm identifier. - */ -predicate vulnProviderLiteral(StringLiteral lit) { - exists(string s | s = lit.getValue() | - s in ["DH", "DSA", "ECDSA", "ECDH"] or - s.matches("ECDH%") or - s.matches("RSA%") - ) -} - -// ------------------ Default SINKS ---------------------- -/** - * Argument at index 0 of call to NCryptSignHash: - * [in] NCRYPT_KEY_HANDLE hKey - */ -class NCryptSignHashArgumentSink extends BCryptOpenAlgorithmProviderSink { - int index; - string funcName; - - NCryptSignHashArgumentSink() { - index = 0 and - funcName = "NCryptSignHash " and - isCallArgument(funcName, this.asExpr(), index) - } -} - -/** - * Argument at index 0 of call to BCryptSignHash: - * [in] BCRYPT_KEY_HANDLE hKey, - */ -class BCryptSignHashArgumentSink extends BCryptOpenAlgorithmProviderSink { - int index; - string funcName; - - BCryptSignHashArgumentSink() { - index = 0 and - funcName = "BCryptSignHash" and - isCallArgument(funcName, this.asExpr(), index) - } -} - -/** - * Argument at index 0 of call to BCryptGenerateKeyPair: - * [in, out] BCRYPT_ALG_HANDLE hAlgorithm, - */ -class BCryptGenerateKeyPair extends BCryptOpenAlgorithmProviderSink { - int index; - string funcName; - - BCryptGenerateKeyPair() { - index = 0 and - funcName = "BCryptGenerateKeyPair" and - isCallArgument(funcName, this.asExpr(), index) - } -} - -/** - * Argument at index 0 of call to BCryptEncrypt: - * [in, out] BCRYPT_KEY_HANDLE hKey, - */ -class BCryptEncryptArgumentSink extends BCryptOpenAlgorithmProviderSink { - int index; - string funcName; - - BCryptEncryptArgumentSink() { - index = 0 and - funcName = "BCryptEncrypt" and - isCallArgument(funcName, this.asExpr(), index) - } -} - -/** - * Argument at index 0 of call to NCryptEncrypt: - * [in] NCRYPT_KEY_HANDLE hKey, - */ -class NCryptEncryptArgumentSink extends BCryptOpenAlgorithmProviderSink { - int index; - string funcName; - - NCryptEncryptArgumentSink() { - index = 0 and - funcName = "NCryptEncrypt" and - isCallArgument(funcName, this.asExpr(), index) - } -} - -// ----------------- Default SOURCES ----------------------- -/** - * A string identifier of known PQC vulnerable algorithms. - */ -class BCryptOpenAlgorithmProviderPqcVulnerableAlgorithmsSource extends BCryptOpenAlgorithmProviderSource { - BCryptOpenAlgorithmProviderPqcVulnerableAlgorithmsSource() { vulnProviderLiteral(this.asExpr()) } -} diff --git a/cpp/ql/src/experimental/campaigns/nccoe-pqc-migration/QuantumVulnerableDiscovery/WinCng/WindowsCngPQCVulnerableUsage.ql b/cpp/ql/src/experimental/campaigns/nccoe-pqc-migration/QuantumVulnerableDiscovery/WinCng/WindowsCngPQCVulnerableUsage.ql deleted file mode 100644 index ea07019eca0..00000000000 --- a/cpp/ql/src/experimental/campaigns/nccoe-pqc-migration/QuantumVulnerableDiscovery/WinCng/WindowsCngPQCVulnerableUsage.ql +++ /dev/null @@ -1,22 +0,0 @@ -/** - * @id cpp/nist-pqc/pqc-vulnerable-algorithms-cng - * @name Usage of PQC vulnerable algorithms - * @description Usage of PQC vulnerable algorithms. - * @microsoft.severity important - * @kind path-problem - * @problem.severity warning - * @precision high - * @tags security - * pqc - * nist - */ - -import cpp -import DataFlow::PathGraph -import WindowsCng -import WindowsCngPQCVulnerableUsage - -from BCryptConfiguration config, DataFlow::PathNode source, DataFlow::PathNode sink -where config.hasFlowPath(source, sink) -select sink.getNode(), source, sink, "PQC vulnerable algorithm $@ in use has been detected.", - source.getNode().asExpr(), source.getNode().asExpr().toString() diff --git a/cpp/ql/src/experimental/campaigns/nccoe-pqc-migration/QuantumVulnerableDiscovery/WinCng/WindowsCngPQCVulnerableUsage.qll b/cpp/ql/src/experimental/campaigns/nccoe-pqc-migration/QuantumVulnerableDiscovery/WinCng/WindowsCngPQCVulnerableUsage.qll deleted file mode 100644 index db4e7215e35..00000000000 --- a/cpp/ql/src/experimental/campaigns/nccoe-pqc-migration/QuantumVulnerableDiscovery/WinCng/WindowsCngPQCVulnerableUsage.qll +++ /dev/null @@ -1,70 +0,0 @@ -import cpp -import WindowsCng - -/** - * Steps from input variable (argument 1) to output variable (argument 0) - * for CNG API BCryptOpenAlgorithmProvider. - * Argument 1 represents LPCWSTR (a string algorithm ID) - * Argument 0 represents BCRYPT_ALG_HANDLE - */ -predicate stepOpenAlgorithmProvider(DataFlow::Node node1, DataFlow::Node node2) { - exists(FunctionCall call | - // BCryptOpenAlgorithmProvider 2nd argument specifies the algorithm to be used - node1.asExpr() = call.getArgument(1) and - call.getTarget().hasGlobalName("BCryptOpenAlgorithmProvider") and - node2.asDefiningArgument() = call.getArgument(0) - ) -} - -/** - * Steps from input variable (argument 0) to output variable (argument 1) - * for CNG APIs BCryptImportKeyPair and BCryptGenerateKeyPair. - * BCryptGenerateKeyPair: - * Argument 0 represents a BCRYPT_ALG_HANDLE. - * Argument 1 represents a BCRYPT_KEY_HANDLE. - * BCryptImportKeyPair: - * Argument 0 represents a BCRYPT_ALG_HANDLE. - * Argument 3 represents a BCRYPT_KEY_HANDLE. - */ -predicate stepImportGenerateKeyPair(DataFlow::Node node1, DataFlow::Node node2) { - exists(FunctionCall call | - node1.asExpr() = call.getArgument(0) and - exists(string name | call.getTarget().hasGlobalName(name) | - name = "BCryptImportKeyPair" and node2.asDefiningArgument() = call.getArgument(3) - or - name = "BCryptGenerateKeyPair" and node2.asDefiningArgument() = call.getArgument(1) - ) - ) -} - -/** - * Additional DataFlow steps from input variables to output handle variables on CNG apis. - */ -predicate isWindowsCngAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) { - stepOpenAlgorithmProvider(node1, node2) - or - stepImportGenerateKeyPair(node1, node2) -} - -/** - * CNG-specific DataFlow configuration - */ -class BCryptConfiguration extends DataFlow::Configuration { - BCryptConfiguration() { this = "BCryptConfiguration" } - - /** - * Uses indirect extensions of BCryptOpenAlgorithmProviderSource - */ - override predicate isSource(DataFlow::Node source) { - source instanceof BCryptOpenAlgorithmProviderSource - } - - /** - * Uses indirect extensions of BCryptOpenAlgorithmProviderSink - */ - override predicate isSink(DataFlow::Node sink) { sink instanceof BCryptOpenAlgorithmProviderSink } - - override predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) { - isWindowsCngAdditionalTaintStep(node1, node2) - } -} From 569c38c83374bdef3b684bc2a8601558c654e7ed Mon Sep 17 00:00:00 2001 From: Raul Garcia Date: Mon, 20 Mar 2023 18:38:42 -0700 Subject: [PATCH 256/631] Cleanup main cleanup main --- .../nccoe-pqc-migration/QuantumVulnerableDiscovery/WinCng.qlref | 1 - 1 file changed, 1 deletion(-) delete mode 100644 cpp/ql/test/experimental/campaigns/nccoe-pqc-migration/QuantumVulnerableDiscovery/WinCng.qlref diff --git a/cpp/ql/test/experimental/campaigns/nccoe-pqc-migration/QuantumVulnerableDiscovery/WinCng.qlref b/cpp/ql/test/experimental/campaigns/nccoe-pqc-migration/QuantumVulnerableDiscovery/WinCng.qlref deleted file mode 100644 index 6e6f369e60a..00000000000 --- a/cpp/ql/test/experimental/campaigns/nccoe-pqc-migration/QuantumVulnerableDiscovery/WinCng.qlref +++ /dev/null @@ -1 +0,0 @@ -experimental/campaigns/nccoe-pqc-migration/QuantumVulnerableDiscovery/WinCng.ql \ No newline at end of file From 1400b4b520e77eeb2d439ceec0a8baf5c257b236 Mon Sep 17 00:00:00 2001 From: Raul Garcia Date: Mon, 20 Mar 2023 18:52:58 -0700 Subject: [PATCH 257/631] Update UnsafeUsageOfClientSideEncryptionVersion.ql * predicate `isUnsafeClientSideAzureStorageEncryptionViaObjectCreation` was not useful (it was meant to detect the SDK code, not its usage) * fixed & simplified `isUnsafeClientSideAzureStorageEncryptionViaAttributes`, the original query was not finding the right code. NOTE: tested with a real project: https://github.com/wastore/azure-storage-samples-for-python/tree/master/ClientSideEncryptionToServerSideEncryptionMigrationSamples/ClientSideEncryptionV1ToV2 --- ...nsafeUsageOfClientSideEncryptionVersion.ql | 86 ++++++------------- 1 file changed, 24 insertions(+), 62 deletions(-) diff --git a/python/ql/src/experimental/Security/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql b/python/ql/src/experimental/Security/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql index 5799e0193ce..3eac4385391 100644 --- a/python/ql/src/experimental/Security/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql +++ b/python/ql/src/experimental/Security/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql @@ -16,76 +16,38 @@ import semmle.python.ApiGraphs predicate isUnsafeClientSideAzureStorageEncryptionViaAttributes(Call call, AttrNode node) { exists( - API::Node n, API::Node n2, Attribute a, AssignStmt astmt, API::Node uploadBlob, - ControlFlowNode ctrlFlowNode, string s + API::Node n, ControlFlowNode startingNode, Attribute attr, ControlFlowNode ctrlFlowNode, + Attribute attrUploadBlob, ControlFlowNode ctrlFlowNodeUploadBlob, string s1, string s2, + string s3 | - s in ["key_encryption_key", "key_resolver_function"] and - n = - API::moduleImport("azure") - .getMember("storage") - .getMember("blob") - .getMember("BlobClient") - .getReturn() - .getMember(s) and - n2 = - API::moduleImport("azure") - .getMember("storage") - .getMember("blob") - .getMember("BlobClient") - .getReturn() - .getMember("upload_blob") and - n.getAValueReachableFromSource().asExpr() = a and - astmt.getATarget() = a and - a.getAFlowNode() = node and - uploadBlob = - API::moduleImport("azure") - .getMember("storage") - .getMember("blob") - .getMember("BlobClient") - .getReturn() - .getMember("upload_blob") and - uploadBlob.getACall().asExpr() = call and - ctrlFlowNode = call.getAFlowNode() and - node.strictlyReaches(ctrlFlowNode) and - node != ctrlFlowNode and + call.getAChildNode() = attrUploadBlob and + node = ctrlFlowNode + | + s1 in ["key_encryption_key", "key_resolver_function"] and + s2 in ["ContainerClient", "BlobClient", "BlobServiceClient"] and + s3 in ["upload_blob"] and + n = API::moduleImport("azure").getMember("storage").getMember("blob").getMember(s2).getAMember() and + startingNode = n.getACall().getReturn().getAValueReachableFromSource().asExpr().getAFlowNode() and + startingNode.strictlyReaches(ctrlFlowNode) and + attr.getAFlowNode() = ctrlFlowNode and + attr.getName() = s1 and + ctrlFlowNode.strictlyReaches(ctrlFlowNodeUploadBlob) and + attrUploadBlob.getAFlowNode() = ctrlFlowNodeUploadBlob and + attrUploadBlob.getName() = s3 and not exists( - AssignStmt astmt2, Attribute a2, AttrNode encryptionVersionSet, StrConst uc, - API::Node encryptionVersion + Attribute attrBarrier, ControlFlowNode ctrlFlowNodeBarrier, AssignStmt astmt2, StrConst uc | + startingNode.strictlyReaches(ctrlFlowNodeBarrier) and + attrBarrier.getAFlowNode() = ctrlFlowNodeBarrier and + attrBarrier.getName() = "encryption_version" and uc = astmt2.getValue() and uc.getText() in ["'2.0'", "2.0"] and - encryptionVersion = - API::moduleImport("azure") - .getMember("storage") - .getMember("blob") - .getMember("BlobClient") - .getReturn() - .getMember("encryption_version") and - encryptionVersion.getAValueReachableFromSource().asExpr() = a2 and - astmt2.getATarget() = a2 and - a2.getAFlowNode() = encryptionVersionSet and - encryptionVersionSet.strictlyReaches(ctrlFlowNode) - ) - ) -} - -predicate isUnsafeClientSideAzureStorageEncryptionViaObjectCreation(Call call, ControlFlowNode node) { - exists(API::Node c, string s, Keyword k | k.getAFlowNode() = node | - c.getACall().asExpr() = call and - c = API::moduleImport("azure").getMember("storage").getMember("blob").getMember(s) and - s in ["ContainerClient", "BlobClient", "BlobServiceClient"] and - k.getArg() = "key_encryption_key" and - k = call.getANamedArg() and - not k.getValue() instanceof None and - not exists(Keyword k2 | k2 = call.getANamedArg() | - k2.getArg() = "encryption_version" and - k2.getValue().(StrConst).getText() in ["'2.0'", "2.0"] + astmt2.getATarget().getAChildNode*() = attrBarrier and + ctrlFlowNodeBarrier.strictlyReaches(ctrlFlowNodeUploadBlob) ) ) } from Call call, ControlFlowNode node -where - isUnsafeClientSideAzureStorageEncryptionViaAttributes(call, node) or - isUnsafeClientSideAzureStorageEncryptionViaObjectCreation(call, node) +where isUnsafeClientSideAzureStorageEncryptionViaAttributes(call, node) select node, "Unsafe usage of v1 version of Azure Storage client-side encryption." From e90559b86d9739cd3ce2eb0611f8901d4c7c3602 Mon Sep 17 00:00:00 2001 From: Rasmus Wriedt Larsen Date: Tue, 21 Mar 2023 10:24:28 +0100 Subject: [PATCH 258/631] Python: Add missing `options` files I could not for the life of me figure out why the tests were failing, when they were working for me locally :facepalm: --- python/ql/test/experimental/dataflow/coverage-py2/options | 1 + python/ql/test/experimental/dataflow/coverage-py3/options | 1 + 2 files changed, 2 insertions(+) create mode 100644 python/ql/test/experimental/dataflow/coverage-py2/options create mode 100644 python/ql/test/experimental/dataflow/coverage-py3/options diff --git a/python/ql/test/experimental/dataflow/coverage-py2/options b/python/ql/test/experimental/dataflow/coverage-py2/options new file mode 100644 index 00000000000..8dd8d25c998 --- /dev/null +++ b/python/ql/test/experimental/dataflow/coverage-py2/options @@ -0,0 +1 @@ +semmle-extractor-options: --max-import-depth=1 --lang=2 diff --git a/python/ql/test/experimental/dataflow/coverage-py3/options b/python/ql/test/experimental/dataflow/coverage-py3/options new file mode 100644 index 00000000000..cfef58cf2b2 --- /dev/null +++ b/python/ql/test/experimental/dataflow/coverage-py3/options @@ -0,0 +1 @@ +semmle-extractor-options: --max-import-depth=1 --lang=3 From a865f1666d7de8b183cbf70ab703bfdc692fb163 Mon Sep 17 00:00:00 2001 From: Chris Smowton Date: Tue, 21 Mar 2023 09:25:33 +0000 Subject: [PATCH 259/631] maven-httpo-repository: add Maven wrapper Maven 3.9.1 changes the format of the error message this test is looking for (though it still matches the target regex). Use the Maven wrapper to avoid such sensitivity to the precise version present in the environment. --- .../maven-http-repository/.gitattributes | 6 + .../.mvn/wrapper/maven-wrapper.jar | Bin 0 -> 59925 bytes .../.mvn/wrapper/maven-wrapper.properties | 18 ++ .../diagnostics/maven-http-repository/mvnw | 287 ++++++++++++++++++ .../maven-http-repository/mvnw.cmd | 187 ++++++++++++ 5 files changed, 498 insertions(+) create mode 100644 java/ql/integration-tests/all-platforms/java/diagnostics/maven-http-repository/.gitattributes create mode 100644 java/ql/integration-tests/all-platforms/java/diagnostics/maven-http-repository/.mvn/wrapper/maven-wrapper.jar create mode 100644 java/ql/integration-tests/all-platforms/java/diagnostics/maven-http-repository/.mvn/wrapper/maven-wrapper.properties create mode 100755 java/ql/integration-tests/all-platforms/java/diagnostics/maven-http-repository/mvnw create mode 100644 java/ql/integration-tests/all-platforms/java/diagnostics/maven-http-repository/mvnw.cmd diff --git a/java/ql/integration-tests/all-platforms/java/diagnostics/maven-http-repository/.gitattributes b/java/ql/integration-tests/all-platforms/java/diagnostics/maven-http-repository/.gitattributes new file mode 100644 index 00000000000..36e4b9d7df9 --- /dev/null +++ b/java/ql/integration-tests/all-platforms/java/diagnostics/maven-http-repository/.gitattributes @@ -0,0 +1,6 @@ +# +# https://help.github.com/articles/dealing-with-line-endings/ +# +# These are explicitly windows files and should use crlf +*.bat text eol=crlf +*.cmd text eol=crlf diff --git a/java/ql/integration-tests/all-platforms/java/diagnostics/maven-http-repository/.mvn/wrapper/maven-wrapper.jar b/java/ql/integration-tests/all-platforms/java/diagnostics/maven-http-repository/.mvn/wrapper/maven-wrapper.jar new file mode 100644 index 0000000000000000000000000000000000000000..bf82ff01c6cdae4a1bb754a6e062954d77ac5c11 GIT binary patch literal 59925 zcmb5U1CS=sk~ZA7ZQHhc+Mc%Ywrx+_*0gQgw(Xv_ZBOg(y}RG;-uU;sUu;#Jh>EHw zGfrmZsXF;&D$0O@!2kh40RbILm8t;!w*&h7T24$wm|jX=oKf)`hV~7E`UmXw?e4Pt z`>_l#5YYGC|ANU0%S(xiDXTEZiATrw!Spl1gyQYxsqjrZO`%3Yq?k$Dr=tVr?HIeHlsmnE9=ZU6I2QoCjlLn85rrn7M!RO}+ z%|6^Q>sv`K3j6Ux>as6NoB}L8q#ghm_b)r{V+Pf3xj>b^+M8ZFY`k|FHgl zM!^0D!qDCjU~cj+fXM$0v@vuwvHcft?EeYw=4fbdZ{qkb#PI)>7{J=%Ux*@pi~i^9 z{(nu6>i-Y^_7lUudx7B}(hUFa*>e0ZwEROS{eRc_U*VV`F$C=Jtqb-$9MS)~&L3im zV)8%4)^9W3c4IT94|h)3k zdAT_~?$Z0{&MK=M0K)Y#_0R;gEjTs0uy4JHvr6q{RKur)D^%t>W+U;a*TZ;VL{kcnJJT z3mD=m7($$%?Y#>-Edcet`uWDH(@wIl+|_f#5l8odHg_|+)4AAYP9)~B^10nU306iE zaS4Y#5&gTL4eHH6&zd(VGyR0Qccx;>0R~Y5#29OkJpSAyr4&h1CYY|I}o)z ze}OiPf5V~(ABejc1pN%8rJQHwPn_`O*q7Dm)p}3K(mm1({hFmfY{yYbM)&Y`2R=h? zTtYwx?$W-*1LqsUrUY&~BwJjr)rO{qI$a`=(6Uplsti7Su#&_03es*Yp0{U{(nQCr z?5M{cLyHT_XALxWu5fU>DPVo99l3FAB<3mtIS<_+71o0jR1A8rd30@j;B75Z!uH;< z{shmnFK@pl080=?j0O8KnkE;zsuxzZx z4X2?!Dk7}SxCereOJK4-FkOq3i{GD#xtAE(tzLUiN~R2WN*RMuA3uYv-3vr9N8;p- z0ovH_gnvKnB5M{_^d`mUsVPvYv`38c2_qP$*@)N(ZmZosbxiRG=Cbm`0ZOx23Zzgs zLJPF;&V~ZV;Nb8ELEf73;P5ciI7|wZBtDl}on%WwtCh8Lf$Yfq`;Hb1D!-KYz&Kd< z+WE+o-gPb6S%ah2^mF80rK=H*+8mQdyrR+)Ar5krl4S!TAAG+sv8o+Teg)`9b22%4 zI7vnPTq&h=o=Z|$;>tEj(i@KN^8N@nk}}6SBhDIGCE4TrmVvM^PlBVZsbZcmR$P7v3{Pw88(jhhI?28MZ>uB%H z&+HAqu-MDFVk5|LYqUXBMR74n1nJ|qLNe#G7UaE>J{uX(rz6McAWj)Ui2R!4y&B01 z`}LOF7k|z0$I+psk+U^Z3YiAH-{>k*@z|0?L4MPNdtsPB+(F791LsRX$Dm(Gycm1k}n z#a2T#*)k-v{}p@^L5PC^@bH+-YO4v`l7Gq)9pgSns??ISG!M6>7&GySTZkVhykqk* zijh9sE`ky?DQPo+7}Vu@?}15_zTovL$r%h~*)=6*vTz?G#h|~>p(ukh%MKOCV^Jxa zi~lMP5+^-OW%Te@b#UoL6T1%9h-W}*hUtdu!>odxuT`kTg6U3+a@6QTiwM0I zqXcEI2x-gOS74?=&<18fYRv&Ms)R>e;Qz&0N20K9%CM_Iq#3V8%pwU>rAGbaXoGVS z-r5a$;fZ>75!`u@7=vV?y@7J;S;E#lvQ?Ar>%ao zOX)rc794W?X64tUEk>y|m_aCxU#N>o!Xw7##(7dIZDuYn0+9DoafcrK_(IUSl$m`A zZF1;0D&2KMWxq{!JlB#Yo*~RCRR~RBkfBb1)-;J`)fjK%LQgUfj-6(iNb3|)(r4fB z-3-I@OH8NV#Rr1`+c=9-0s3A3&EDUg1gC3 zVVb)^B@WE;ePBj#Rg2m!twC+Fe#io0Tzv)b#xh64;e}usgfxu(SfDvcONCs$<@#J@ zQrOhaWLG+)32UCO&4%us+o5#=hq*l-RUMAc6kp~sY%|01#<|RDV=-c0(~U2iF;^~Z zEGyIGa;#2iBbNLww#a{)mO^_H26>4DzS zW3Ln9#3bY?&5y|}CNM1c33!u1X@E`O+UCM*7`0CQ9bK1=r%PTO%S(Xhn0jV&cY5!; zknWK#W@!pMK$6<7w)+&nQZwlnxpxV_loGvL47cDabBUjf{BtT=5h1f2O&`n<$C%+3 zm$_pHm|BCm`G@w&Db)?4fM_YHa%}k|QMMl^&R}^}qj!z-hSy7npCB+A1jrr|1}lLs zw#c+UwVNwxP{=c;rL2BGdx*7zEe1Bcd{@%1-n8y7D4tiWqfpUVh-lHmLXM^KZShOH z*xFp)8|Y+bM`|>mg}p~MOHeh4Ev0_oE?T1n|HMCuuhyf*JDmFP(@8+hi#f-8(!7>g zH}lOHg#Nw(x(LkB`Q;g)oVAM{fXLqlew~t2GU);6V}=6Hx<4O5T!!-c93s;NqxUDm zofsXe!Q%wAD~BBUQ3dIiCtR4WMh-t>ISH?ZMus*wja+&<^&&Gm-nBlDvNS4vFnsl^ ztNpIbyMcWMPfKMe=YnWeIVj|?e>nZbwm$=sV@Qj@A@PE#Gnjlk{CGPDsqFS_)9LEa zuKx7=Sa>|^MiSKB?)pG()OoM}_%lx|mMlX&!?+`^^4bT=yz=ZoxWH_ngA*jX*IZcHOjb62dT(qTvBPn`2AFuL0q` zG+T@693;<++Z2>R2bD`qi0y2-Zf>Ao)K0f&d2P zfP78gpA6dVzjNaH?(M_mDL)R0U=lEaBZvDI4%DXB?8uw7yMJ~gE#%4F`v`Nr+^}vY zNk!D`{o4;L#H`(&_&69MXgCe`BzoU+!tF?72v9Ywy}vJ>QpqhIh5d@V>0xHtnyvuH zkllrfsI^;%I{@6lUi{~rA_w0mAm940-d++CcVAe<%1_RMLrby@&kK~cJQDXKIiybT z-kqt-K3rNz|3HT@un%{nW0OI{_DTXa-Gt@ONBB`7yPzA#K+GBJn@t@$=}KtxV871R zdlK|BI%we#j)k%=s3KJX%`+e4L~_qWz2@P z#)_IbEn(N_Ea!@g!rjt?kw;wph2ziGM|CPAOSzd(_Cp~tpAPO_7R!r5msJ4J@6?@W zb7r0)y);{W17k3}ls4DaNKdRpv@#b#oh4zlV3U@E2TCET9y3LQs1&)-c6+olCeAYp zOdn^BGxjbJIUL0yuFK_Dqpq%@KGOvu(ZgtKw;O*bxSb1Yp#>D?c~ir9P;<3wS2!-P zMc%jlfyqGiZiTjBA(FcUQ9mq#D-cvB9?$ctRZ;8+0s}_I8~6!fM~(jD=psem4Ee>J zWw&CJ7z{P9{Q7Ubye9)gwd`}~OSe#Rf$+;U1GvliVlhuHCK9yJZ2>_y@94OzD`#Ze z9)jO->@7)Bx~CeDJqQK|0%Pfmg&-w7mHdq3hENhQ;IKK;+>|iFp;c?M^kE!kGY&!y zk0I0Fk*!r6F59pwb<6v2ioT*86d(Tee%E1tmlfVjA#rHqA%a~cH`ct#9wX$-o9erW zXJEEOOJ&dezJO$TrCEB2LVOPr4a1H9%k<&lGZo1LDHNDa_xlUqto!CGM^Y}cxJn@x ziOYwn=mHBj_FAw|vMAK^Oqb(dg4Q?7Umqwc#pL?^vpIVNpINMEiP4Ml+xGo3f$#n$ zSTA3aJ)pM~4OPF>OOXOH&EW^(@T%5hknDw^bLpH%?4DjNr1s9Q9(3+8zy87a{1<&7 zQ@0A|_nnege~*7+LF5%wzLWD`lXWotLU4Y&{0i|(kn5hdwj^9o@)((-j86#TKNN|Got?9j^EYE8XJ}!o>}=@hY~siOur_pZ`mJW+ zg}Q?7Q_~bhh6s%uqEU!cv`B=jEp1K|eld>}I`pHtYzif`aZCe88}u$J6??5!TjY7Z zi_PXV!PdeegMrv48ein(j_-BWXDa73W&U|uQY2%u#HZ5hI@4>q?YPsd?K$Vm;~XD| za8S@laz_>}&|R%BD&V-i4%Q6dPCyvF3vd@kU>rvB!x*5ubENu_D>JSGcAwBe1xXs> z#6>7f9RU7nBW^%VMe9x%V$+)28`I~HD=gM$1Sivq)mNV>xD~CileqbUCO{vWg4Rh# zor2~~5hCEN)_0u$!q<(|hY5H=>Bbu%&{4ZV_rD1<#JLjo7b^d16tZ8WIRSY-f>X{Z zrJFo^lCo+3AagC{EW4g= z#o?8?8vCfRVy)U15jF^~4Gl{&Ybt92qe)hZ^_X>`+9vgWKwyZiaxznCo|TfVh3jIi zcEf?H`U;iFaJh=3Gy2JXApN`o zE=O1Gg$YQt6|76IiMNF?q#SA1bPB@dw#H+-V@9gL>;1mg+Cb#k1ey8`dvR+(4ebj= zUV1Z)tKRo}YEh@TN=$v(;aR{{n8vk`w|nNuHuckt$h27 z8*aBefUxw1*r#xB#9egcpXEi_*UAJYXXk!L7j@ zEHre9TeA?cA^qC?JqR^Tr%MObx)3(nztwV-kCeU-pv~$-T<>1;$_fqD%D@B13@6nJvk$Tb z%oMcxY|wp&wv8pf7?>V>*_$XB&mflZG#J;cO4(H9<>)V(X0~FRrD50GSAr_n^}6UI=}MTD3{q9rAHBj;!)G9GGx;~wMc8S8e@_! z_A@g2tE?_kGw#r}Y07^+v*DjB7v08O#kihqtSjT)2uwHG1UbSIKEAO<7Nt3T;R`YCSSj z!e)qa4Y~g>{F>ed`oWGW>((#s$zQGbsS&sg}^pBd?yeAN05Roe8> zT5^XsnI??pY-edI9fQNz3&cr}&YORzr4;sw1u{|Ne1V}nxSb|%Xa_Xy5#TrcTBpS@ z368Ly!a8oDB$mv21-kqD9t&0#7+@mt50oW4*qGcwbx}EyQ=zv+>?xQUL*ja2`WGq` z)sWi!%{f{lG)P(lu6{68R~smEp!Jy9!#~65DQ1AHIc%r7doy*L!1L>x7gLJdR;hH_ zP$2dAdV+VY*^|&oN=|}3-FdyGooDOM-vAGCT@@JyuF4C(otz>?^9!lR%m-tde}ePe z)Jp)zydtP%C02mCPddGz5R9NYvrS6)Bv$~r@W&cP5lLp7-4NrEQDN3%6AmXH@Tdfj zZ+k^}6%>L=d8BK-pxgvV`ix>w6F;U0C zlZ#lnOYYDhj4r)_+s){%-OP5Z{)Xy~)T{p`w1d-Z`uhiyaHX5R=prRWzg^tr8b$NI z3YKgTUvnV)o{xug^1=F=B;=5i^p6ZQ3ES<#>@?2!i0763S{RDit@XiOrjHyVHS*O` z`z@(K2K8gwhd0$u@upveU3ryuDP~by=Xy(MYd_#3r)*XC z^9+R*>njXE-TIP1lci2Q!U>qTn(dh*x7Zxv8r{aX7H$;tD?d1a-PrZ_=K*c8e050Z zQPw-n`us6g%-5T&A%0G0Pakpyp2}L*esj#H#HB!%;_(n z?@GhGHsn-TmjhdE&(mGUnQ3irA0sJtKpZ!N{aFsHtyTb#dkl=dRF+oo-dwy<#wYi=wik;LC6p#Fm zMTEA@?rBOmn>eCuHR%C{!jx>b|+<6B-)Z%(=lG{@y_@8s2x4Hym6ckPdCB$7NZFp_|El()ANXTORs zO@b$@1`3tXjEm>;bX)%xTUC>T)r6eTFtq*Rp*_?%C+fEzT##kVNH` zV}-lw6&hY;cyl5#RR-w!&K4e)Nf4noLFyjiAbKvP7Y!=2lRiRjc$&d?P~!zM@4!?3-vyqs zhm*63jiRI7cfruv!o=zO%H2cQ#o64%*4YAJ=xp~No53pO?eEA$`fR4x=^|*#{u3bx z1YB3OT97ZU3=ol)l`K!lB?~Dj(p_i0)NN=fdgz(QBu>8xV*FGZUb7m4NEbrA+BJ1O z%CPI+T>JPq9zpg~<>QR+je>?{g)rSuWpyCDcc2@rE8T>oNWPiP*u zLZc3LaQVEsC6emsi7DCL0;U0BP!SwAkXuetI25TYuCwD8~Z|M@2_ z0FaBG|x zW)FZvkPsN^5(Q}whYFk-E8)zC(+hZMRe5VA6GZM!beBdDBqq#Rye$I~h@Kf8ae!Ay z*>8BsT)dYB${E3A^j5m_ks3*1_a^uA+^E{Gxcgw2`f7jw8=^DG391okclzQA zwB6_C;;k_7OnwT<<5RjXf#XxTO9}jrCP+Ina|?UA%gFvNJy7HFEx9r{(c&yDZ9e2aovtJL$um8u>s&1k@G6# z-s55RDvTcFYZji6x+UMyCu{&*d4N<{6;H^PEF!?X@SqMfGFR}LYImL1;U}{iT!qnA zgqLCyvSp>>nS}|sv56Dnwxdo&HrZG1WQL_EkC!D6j)JW4Tv1yyqe&aM- zHXlKm;srQVctoDYl&e}E-P8h#PCQNW{Dg*Te>(zP#h*8faKJ!x-}2Rd)+>ssE`OS? zH{q>EEfl3rrD`3e_VOu!qFXm7TC9*Ni&^{$S76?jtB;*1+&lyEq_j{|Nhg&s;W6R9 zB#r9L#a7UU(Vnq#7asUx%ZyVz{CiVL5!CBl-7p|Kl&=g>)8e?z&u?Q^r>L@P zcB6n=#5Wz+@-j`qSB=wD1p_n<(NhAp8wa!IxDP?M&_ zKNcJonwpOS>a3-OBC9jGV@*WND}F8~E_QS7+H3ZK6w&kq>B}kc123ypkAfx`&en&T z+?U=!q?N5DDkt(2$KU;t^dR}IVC|M)pn@S)m{saxD4V?TZZWh@hK|C|n(P&eXLAq1 zZ#v0gPhHJYiyjEkJT~&%u@zLE`Lm!p!&-VAfk?eF{HN%PeV5S87-u3n;g}^R(OZqI zA|##x9SAAKAb!FSr9+E^(}_HX+lb+XLQiWF2UmH*7tM?y7R{u3(Vr<5h8V>Y-c`SgYgD9RvV*ZP{xBLuk-5sAcGP5G zDdk)Ua8PaYS-R*C(V(}4>%>{X%~yk{l3&El7iOz}m0Y8MAl_Qc`-2(z2T3kJ4L1Ek zW&^0C5lA$XL5oFZ0#iRevGn2ZyiotWRIag?#IT-E$gv92YXfp3P1BJxO zShcix4$;b#UM2o=3x#3;cA8Q#>eO8bAQ6o|-tw;9#7`gGIFVll^%!T5&!M|F|99EZ z?=t(Tag~g}`Wep_VX!|sgf_=8n|trl((YTM-kWDQ1U@WIg!~YjGqsZNOrayhav_lrw< zgSle+;b;p^Ff)tDt~?&TweI#6(}<3?Uw1@|4MvG2w}sQgX*N;Q=eD+(bJ%jKJ9L2o z3%MlC9=i-DKzXOun`;&7ZI$Iw?Y|j!RhIn*O`mRl2_vUnE*Rf6$?{IC&#;ZS4_)ww zZ${m6i^cVHNiw5#0MSjEF!NaQfSr&DbTX&tHM{Ke)6Pt9^4_Jf%G&51@IH0aA7QRc zPHND$ytZTZ7-07AEv8Rn%5+<=Bx1tWJSG_?CqXuJ99Zwp=hP2?0a{F)A8HLWkv z)nWbhcgRVdtQ4DpZiw6*)QeCWDXGN6@7m@}SN?Ai*4{l!jL`wrp_lL`bJF6HVAOnj zNa*fTj+{niV5~*O zN5NwHHcEed1knV2GNSZ~H6A+13`U_yY?Dlr@mtyq*Eutin@fLqITcw+{ zgfCsGo5WmpCuv^;uTtgub$oSUezlUgy1KkqBTfdC=XJ}^QYY+iHNnhYEU)j7Oq^M^ zVSeY5OiE#eElD6|4Haq&dOHw4)&QX=k_Ut{?Uvr21pd&diJ zB2+roNX!_7mJ$9n7GNdG8v{=K#ifQnT&%`l82sR{h&TKf?oxK%8RlG}Ia$WP=oQ3C z8x#$S3Rrheyw7recyTpSGf`^->QMX@9dPE# z?9u`K#Vk!hl`$zv<^Wl(#=J4ewGvm4>kxbr*k(>JDRyr_k#52zWRbBBxSsQfy=+DkvQ40v`jh_1C>g+G@4HuqNae&XeekQeAwk+&jN88l@etjc2U0(3m{pQ8vycb^=k>?R~DSv8<0tRfmLp27RlxR~V8j?ClC z)_B-Ne*s0#m}G~_QwykU<`~vMvpTlr7=W&w=#4eEKq!$muL_QJblmEh6*MUg!$z4fC{DBd*3h=N|lf1X7dTfqL1v6~_al z%J+WD;fSJ>TKV*mid$G+8eIjdfK%pu!#kkan;Qi>LK<0bn$?ecFn-b|@+^+OT=0nl zZzN%OUn9w14s`D45>E^)F8?Z?;l!%DF^oL|Yt!@m^V@3twFD@^D5$*5^c%)sM*sbi zk(RQq-d<^O7T8RfFwEK9_us2+S$&W1-Z3OR+XF6$eJl7IgHM~N8sHzWeuzxpB% zE9h3~^*;?_y)7i>a4#z6(ZQ%RaIo)|BtphTOyY@sM+vd#MYN11?ZV(xUvXb&MFg6g z=p`JrH(5;XsW4xVbiJ?|`nutpC1h*K1p~zS%9GcwUz0UWv0GXKX{69Mbhpcsxie0^ zGqgqzpqFAefIt5 zbjNv;*RSO}%{l!Z)c-Qw`A_=i-}4-?=swGSMI^E7)y37u+#O1^yiI2ehK4F|VMVkK z!hIFgJ+Ixg^6jI3#G8UbMwE1a!y~wFx@T(|6G*f($Q=e5na9eDt?f6v;SI;w0g-j% z!J#+aN|M&6l+$5a()!Cs22!+qIEIPkl)zxaaqx#rxQ_>N-kau^^0U$_bj`Aj28>km zI4^hUZb4$c;z)GTY)9y!5eJ{HNqSO{kJDcTYt-+y5;5RiVE9 z-rfg@X78JdxPkxzqWM?WOW8U(8(Lfc7xz`AqOH6jg!Y-7TpXRJ!mtM~T)9C^L}gSL z;YSLGDG_JZayritQkYm6_9cy96BXEf5-2!+OGf|OA7sdZg?o)Z<$B#|?fq|82c!WU zA|T92NDMBJCWHwuFa{aCfTqmu)kwClHDDbMnUQhx07}$x&ef5J(Vmp?fxerb?&J3W zEcoupee$`(0-Aipdr2XA7n`Vp9X;@`bGTh>URo?1%p&sSNNw!h%G)TZ^kT8~og*H% z!X8H2flq&|Mvn=U>8LSX_1WeQi24JnteP@|j;(g*B2HR-L-*$Ubi+J1heSK4&4lJ| zV!1rQLp=f2`FKko6Wb9aaD_i=<=1h?02JU2)?Ey_SS%6EQ>I20QL=(nW-P4=5mvTJ z&kgssLD)l`rHDCI`%vQMOV-yUxHQyhojHdYC*$H1=nrJKqFo93>xvB=M`$}Roksx# zRgV+d8#sk=v+tN#P-n?dx%RC(iv;9-YS-7PrZu#xJ5%k4i*8joRv1J`M_tOQR`{eV zE~<8%VC63sx|_U&{Bpy&?!~^Ce+CNv^T)?diyKrA zu^d&el}PFVWKFz9wkriy~eruRakPmmS0ZsKRiEMGj!_V`HL0FT$ zQU#r2x}sc&kxyY}K}1C{S`{Vdq_TYD4*4zgkU_ShWmQwGl2*ks*=_2Y*s%9QE)5EL zjq8+CA~jxHywIXd=tyIho1XBio%O)2-sMmqnmR&ZQWWD*!GB&UKv6%Ta=zRBv&eyf z{;f~`|5~B_&z17;pNS$3XoIA~G@mWw1YgrTRH95$f&qLKq5wY@A`UX)0I9GbBoHcu zF+!}=i8N>_J}axHrlmb)A1>vwib%T;N(z z!qkz-mizPTt^2F1``LZ#Is;SC`!6@p@t72+xBF5s!+V#&XJ54bJ|~2p(;ngG3+4NA zG?$Orjti%b`%<{?^7HlMZ3wR29z7?;KBDbAvK`kgqx4(N-xp5MuWJ1**FC|9j~trE zo`+jX&aFP*4hP;(>mA>X7yZujK`$QP9w?a`f9cQJaAA2cdE{Tm@v?W3gT&w=XzhbY zCDpADyRHQ?5fOuf*DrAnVn6BjADR2&!sV&wX1+TC*Qk}9xt8KA7}6LBN-_;c;r`H= zwL1uGsU0;W?OEez?W5HYvu>6SR+O8l#ZM+X@T3>y9G^L76W?!YFcytB^-`NyTDB=; zw421!sr`Wwopu>VDWNN>IN&RxE08d0JJZigpK%)p|Ep&aHWO`AFP)}VkqQg1S#TY> z(W)bm7duX(Nvry|l%sGs+Eudz3=_A0i@M47VtBp1RTz_zxlmqgi53tT!_i)(bad*R zt<1n~oT!|>QLmYf?YL$n8QEJ2A6liMI!hRY#mB@?9sWAUW8! z3#M&1`ZQmRP*o`jtHjbA78}!&iq6v&rlp|5&!}O}NT>|10NoWbiq5@7lhquTSHBCO z2a!-M+(e10feoq(nVw~!ZC;y+4M=F0%n)oHB7{BRYdVpeTN zryeS3Ecv^OC_2HcYbRWnOSY2McCa2PfRXH~!iu|fA^#y<&eJkS1^d|DM3)QKAnMe1 zp%9s~@jq$zOV8LQ$SoOZGMPYE@s<@m$#S(N##mh{yFb!URLo?VmR4c2D<_vio;v$u zEJivu^J$RML#dZFhO#!?D8s-JTIP{sV5EqzlSRH3SEW;p+f8?qW%}bdYNyDgxQcQg z)s4r6KHcPGxO_ErHr?P}mfM;FZE)8_I3? zDjMJvQui}|DLHJ=GXcz4%f~W;nZtC{WKitP66ONo4K<7TO!t?TYs_icsROOjf=!bP z#iDYw8Xa2L$P!_IMS+YdG$s?Gh(pybF}++ekEr=v(g97IC8z28gdGEK?6QPNA@g_H znGEeNG!5O#5gfi{IY+V>Q!Z=}bTeH|H2IGYcgh~!jjG`b~gGo!$<2(Kis_p5;(P-s_l8JWL!*jOOFW7(UIXj)5^C~7r z>g7M$hT|sIVBpur@M~;gi~j(BNMp8UkYv?y&{`-sK=@)-@S(2kqobO@Wt_pSnMh|eW*8azy%8exS@DAQxn9~G zE=4(L_gg-jHh5LtdXPgG=|7Xcq4E&x?X2G2ma(6{%4i1k?yUE4(M*Qk6_ z1vv$_*9q$Ow(QAvO;Y5T^gBQ8XX5ULw$iW6S>Q`+1H*Qj+COZ<4PxD-Fwh71j0cBx zz1pnDR}STs5k`ekB^)M`Iu39H@BwM@^8_X7VVp@epjNMqRjF($LBH!#dnEe)By}7T z7*XbIUY>#irgB@|lb)RRvHN^cPT%6slXqX1FW;4YMtNurd;?3g>rm zCSyAc0+aO+x0NojMi`4bp59%=g=zuk4R4o~hTUxxaj-YA z@UtFr6OY{A=_+?qZnrqBO49}q~-hZ!+0QZzD)8F6c7AMQ8Edl-y|d#R;NOh4ukOeId((#ChBKo`M=8Z@5!BZsX7A3n)%+;0Dy*bI-#fNe6_VV1{v%_*=I&54mqAWAg z3XmVyRkbAG&>7rIx23lx*caz7vL$Tha&FcrqTEUNZXhFsibRbc*L@H$q*&{Bx?^60 zRY;2!ODe~pKwKFrQ{(`51;0#9$tKAkXx7c-OI>j-bmJb*`eqq_;q-_i>B=}Mn^h`z za=K-$4B2-GE(-X{u|gHZ+)8*(@CW35iUra3LHje(qEJao_&fXoo%kNF}#{ zYeCndcH;)cUYsmcLrAwQySyF2t+dUrBDL;uWF|wuX8S|lr+Kg8>%G?Kuzxf;L!gZoxAqhd;`!i$5wZfphJ-c zd|uR@Q=cF4N1HXz1y}KjQJ8{7#aqNM_|j!oz6@&wEfq)8)wG4ngiGocMk=1Ft54#R zLyJe(u>P{fm>k_wUn20W9BZ#%fN9ZePCU*5DGK$uQ{GP3{oE1Qd^}1uSrdHw<-AM% znk>YZOU^R94BahzlbdB994?8{%lZ*NSZ4J+IKP3;K9;B))u#S>TRHMqa-y}{@z#V5wvOmV6zw~pafq=5ncOsU z`b-zkO|3C@lwd3SiQZeinzVP4uu+V>2-LKKA)WQXBXPb#G9E8UQ%5@sBgZtYwKzkq zNI6FloMR!lx7fV|WjJ*b`&y_UK9mPl*` z;XO8P%7{H*K=GrNF#+K3At?5`_oXT|Vz!Rh_05t2S&yd`A2 zjcyVJB|#czi?o<&biP<}0alxnpPLzJ9d#_R9(c$2IPXg7=4mL{7WoN>JTCCZ%zV{) zm691r%m?d5yR3l=Qxn7|f0?e7@ zk^9ia@dNTbyi6%GO;kec5sHCjtyr*i1QSY;G}gTsivUQRTG(i)y`O_~K{I*S+x=>M z;}<><>$k8!-=R}>b#)kmSE&~qf+xi@lJazu^F@~pV>MQ3ISq0)qH;F^;_yT@vc-Pr z390Cb$Zq{edB^7W@Mz_+gQ$>@*@>hJIjn4*`B@N%Lt_t1J1wT!aN`jpEBE5;Z|_X| zT^67k%@CVrtYeC}n;uLV%ZSClL-hu4Q5t8ke5a8BZ`=p#4yh?Xa^Q~OrJm_6aD?yj z!Od*^0L5!;q95XIh28eUbyJRpma5tq`0ds9GcX^qcBuCk#1-M-PcC@xgaV`dTbrNS$rEmz&;`STTF>1pK8< z7ykUcQ^6tZ?Yk3DVGovmRU?@pWL#e2L7cLSeBrZc$+IyWiBmoex!W#F#PlFAMT00niUZfkGz z0o{&eGEc{wC^aE3-eC$<2|Ini!y;&5zPE>9MO-I7kOD#cLp<3a%Juu2?88km=iL=? zg)Nm=ku7YEsu57C#BvklPYQ>o_{4C>a9C*0Px#k2ZkQ)j3FI#lIW3mT#f*2!gL4$_ zZDI76!tIw5o=j7Opkr~D0loH62&g?CHDg;Lp^HZ;W7)N+=s>^NuhmsYC?}lxS;sOE z69`R?BLA*%2m_L7BSZ^X5BKaWF-Y?b-HqGLcTd9NU7vY8k|j{O`cOrwxB2WW@tmhU zt`FA4?YCJwFISu42CLh~%e8Qg093rgqDa!ASGd!qoQ1e+yhXD=@Q7u0*^ddk+;D{) zKG0?!-U>8p8=*&(bw!x;E{EjWUUQyY3zVB2V}@t$lg*Bn3FId6V_Ez&aJ%8kzKZg$ zVwL+>zsp;_`X|m4RRvc|Wtejy* z?bG~}+B%y$b6zBRba$P?mX#UbwE{i{@jbuL@tZ6Rn;SCu#2M*$dpQIn$Hqv`MgjBn zURSnq5+1ReLXsI#*A8G1&h5`YFo^I17Y=&&1eQDtwY8HI3#DdGWslPJSP1` z1D()O()qzD6U~BYRUPw6gfc4Wx!am$yM#i~5MCmF8=7(q7;n3?L@7uuvn$;8B8wk8 z3>T-EJ5X9Z3@yH;L=9QFtWmzdE_;Kw^v+te+u`pF zN4&*o>iRKeC&l_{U^a`eymoog3(GY&2h;5vMyRyld37+7bW+&7tvIfrL9TpA@{Z

    dy!05UMhSKsK zV1FiJ5SlAhkpcl_H0wRzql?0Qp5wz72o2cMC@utM(|&o0ZO_JpXr+N7l~F?Ef_02md^m|Ly|(EN; z%;)3t6SWt{5hgzszZWS1v^AU?`~Rctor7%qx@EySW!tuG+qP}nwr$(CZQHi1PTA*F z*Vo_ezW4q*-hHnl_8%)^$Bx*s=9+Vi%$1qr5fK%c+Hm4kiE$B;kgV)wam25w$Y7#k5$> zyB^6k3i~L_6~PX554`c3Lxx;&_sT;I^U92G@fS6#(Xv!B%;H3+{e)1R6lyU)8AK1_ z?@>F5H=sXG=ep;kDRZO_ofS}`Jus*Qp3`_V4v~&b-RQ=t8AN5H5{@!_Il~0 zZd!-aH=h)(7CJ&tL%%{P{6d_g=5tsj%S3Z!QxjrLdjoKmNP-zSjdJ!?qL(UMq38ps zjKSz5gzwhDFA;5md5yYb>QN)U_@8Xpjl4yw5065)+#MSGp;yQ*{%mt>12;$~R{eVV>o|juO{Z^ z^o^m@DOBrE2mm1nLgBfA(Wi=X9R%(1UYZcZJ!3;*bR^smI~6lyn`O4BOwo-STsQcyodVA~leg9`{=l(qDl@DCM>s+w`%S_q*PIjYP ziuHHuj0VVW1%+TH*lx9#-$^q&l)G_ojju-w{# zVs{oOc>_fcS51xY+19tN`;V~R0wVyuxdkS|t zC}~Gtu-UyA{H5~6*ocUWM)RfQ076mL1r zFVWV%zx!_*zk`5&dFbdq4nbWxIwAu=`+$V-`m<*-Z*mE2X|>OCAJVV;wlq0E$hVe@&x7V(!xg1*;%`} zxxBu5;jmZEH*e!Rj=Mz|udBR8BR6LiGoLWb<1=<14it;Fuk$6=7YCR&;F+%r`{S6M zP92W>ECy`pZR$Q<6n8Zw1|uh*M=zK=QP0b38_aX#$gB^y>EahIiUzy^MP1ct%UhZX z>FFLVJ=H`FRSq!<_DtWyjLZ6t^Nf|?<69Aj$U0*lrAJG0{t;t8Y^SKLacoR%3EXw+ zDi5T^PkjmJp7@B|$lkEwHHaQ7BGc$})@qNRqk4JH!(bgPM!{Mb&Kz|UGk?QskODW5-NCJ3`Fbks<}%TsOB+e{Hn1i7BP z(XsKkfl`r0N)u1VqaPYGlDxR3>%y{&vYaQCnX8AAv8h8>a^4<#jAhtfa;TdoFlN=?Ac{@Cdxj{YI z!kxobbr?~GU8JKwH2Ywa(#i=Rzof$nu?4-zlN#QJflTO^QkyarxNI<~MY1}jy~Jz` zBRwV&0+G01D9biQ4PR*1NiSqTXZB~NdI6yVEU|AiWJYA>k9G=*`R^VFjr{jhqZ$&G za0#huq)Mhb&8oR!jrv%;xRe@b&PWBXh7ATurhUY7yobngzP;($8b5g z9U{5JMt%fMp(N6ZVGsYa2p(#ry;Y&;GG(DG((_GrS%r&waWuX94*RX8>&x|Lzv8WCaXaWo(3FK=U@G#S$8kCX_R6q|VO;WbeXk~x zmq?NS+S2WfO|{j{dKy5``SRA!r+%)`DCW{s?8uZJW{-4%x}KJzAtiyY6b#)!fe0kA z)=W5C>X6ZLRFH_-$)Z(B8Hr}FD#FLGum2gRluDsrJHf$do$r!ORQqrI6~=-H0vPiG zC2V88MIp?Xhc&UnIS(c)naRXTu-r!%x0J;3uWjp5K%!b_v$;;T0*{_2txs!*+BgP} z%eY2;N7AFz(g@fFy&(hWk`R9#fRZ&X598A7xjHyoDJ4!3CK{Grr4>0bTBw3ps{tN7KqVY^)~B5St2NQS9wH_Lc=s8$1H5J?52_$nh z+rnm{F~bVIsiCZ^Gy&eV*X9JTJZB^`|6F$9|Fq@ekZKP~h_BWGsow^hUpo~MCTrdk^1B;= zNXiYAZnUPm>}{vX*&Yb&{0FNvW!V)h-<{na1yT-|kAkG7xU7QA-NAc|e4Nf2`OWnV zxbr6@^wO^6xW+Xdu=Z{sdK+Qw3Dii+X&Y(VdCv>CFEIOt?MCM?9@CDUKm7+N>%!q z$WI;(L@2YJ&Qfwr7k@<77r}%_q3O8c#><<+(JFdeT2?e+nsP4h+`n(HuX8^8qLN88 zv^9`|ICnNwS^PYDf7ebCGG~QNosD6-%$5;6Yx$`PGlZVnxs6ntftJW^L?iy3KIBDW&1q;{OspV)`a4w`+K45XmW5g6HLPL(lu zM^>HAPux}=ZJ?|;f=zDh!2|)WLyu7pHcc)9vAr(R_-sI`3GRfExjVpYMgql~xox)Q z)W3=WFT93oMdC)bluYO{cphI8Hjl&)W$TKN(PAk2r&mB9-)@%@xbewYx!c z{}phewJ939{qT;q&KR_!>>XnVYPC^kRaX%+G_v;*kg4g0jdi&G2G5$4#bk+*0mK8` zie_>y1oDA_0hGE(n`I(s0k(P&;*KDaX278vofbbNMZ-&1MCmPD*6d6oN$VjMzpTd@C8e zg81s83_+Y#T;duYQ%tXE$RWVk=@P5Z1VY<1C?mU)7?G9IHYx#rHCx1Mhb!ajXBoJ-rANULXqSAu0Mn9s%@_;uy-AOG|5#jDZ3j5dR7|< zR_{f>x5E@uRa$=rDD-yel$t(bf5=#v9ZWObAu%fou?4KkV-kvjmRiGX7iDe(Q)_^=>m}`2$#Xi#5CpJTi#5EF1T1mmPB}c@A6ou~a`>sHSeM4gF(ksh|DObX#Ao1r$Jp3I3 z-#zhd+d&)DO54E0K@@kKgxRB5%x&3BZ$OrawIi6~b_kN~$5G(kH6b5BD&%g70UWu6 z-ub`EccvhA2YleM%U@;V)N{Ixrkd0bjN}m=kn%!g%wE&P@WcBs>5NJ~t}y$Ar7F1n_=iC*<|&`C=qG#+ z0|)?s_kRK(@&?Z40!~gQHirKa2ua%+8CVNj{J7LD3|*Wp?EV9bZ1_j%PH`5U;9>aTZzwPD=a zXur{4zSk&)HrOFOmSK8ZKMHdg*HQk|a($OZ(0puje1K8EZNjPavWjhh64i-B(p7Zf z2g`IQ_W)I`lGa!LCabrDUSVPmGZbVX*#xhnAH|koEn~hs`=w;zVM^IEU${9oXf4C9 zk#|zrR`2_TI+u08MszOoi%H;viD}|x@Ax-{F_aW3ZIQHw-pT;hgNi%weuhcB7xt*kubK4fep+r)eaJIl%p9|sqv{M(E4lgwXe=HL2nYvO$$HX>QpPxqUn}WG zs*l{rztHOO@k5#cP%_alezmlZW9HCcT_;auQpbtV(Kh6e(9wF`C;OM(L&uqUaFglN zk@mRfKGV716J9j|zU-6W(m9pmEF&sbiZMv*M3~8lC~<@%sH8mKCL5zS4h--)TNbi$ zGT~m~}sa$tL(& zG_GBAe(+OZUY}-iY-rcb4f^fNZt_IXS52F^MC6>C?-IuOUttpxwVQBy0~D@|I1g*pQ^8D9@mu?5(kge3_GjbOm2G+7-z zkx`X#L5jF0+(b=RSgOE*XGFk$mF562Yft^UFH0micC5KNH~tfuDq*ce5Q~fKPyieC z9su^F5Df-F2X&FrZ1?<8uQ5h`uh~m z=&m+g_sL;h^%^JcRk%COiklbyo`Co8z9C%hj$&e+^pKMm>7Jt({+@)$DJbC`QjMHZ zi%3X-hLW4Gca)8|Pf3A1t4Ud8Gcj`ZNDE=lz<+3#C9z0jMR_q934+6jFXzJ$uCq~+ za-#O3p1hSU;tiKizC8=Mh@y(Ne3L{f0B?%ewopC*gCiXqueXVpGg9HaGK>hK#}F8++%^d7M6b=5@V(e#PAgrUnD^4)b1JPZ-PGNWqckW?kadj9w8b7f zp6l)!4JIwHtcBOekEW-B`yJ(E6n$+g06FFIjgZzz&+`UpKdgY-=lxNe1BI|=Cg;T; z?FYQs{*)^&tV>xbx0m~jf7l5>`+q#>!*0u^UJNZmE(3w>j|yNHB$#6zkjE;_0pL0S ze2gb)=zGHVUt5ge;3k7XmZcc5;mh=#z-ZobkM!xX0De$bw@9s|&m~zN9 z!K5tX5=4qA2sK|$bdVMz5etUdXN!`}2PL8R7qLr)Si} z!IONdCg$e~UlJ3u{n50K+;kj7SP&tC(^xDUbl{fdvL#ilA93{7Vm|&0)1p+nx=!XmT2qv6B?FjPHZV*SamC-ro9lXMAbWtsPx?Xq1Kcc_^$@r-YuI4|#Q?})HOyhMfBUVTIsc4Su?*`>kGqVs(0tbI_r0@mbv4tR&NZCQd@%?W!R_Br)qtk^~)!$ zd{bZ$2k_tV&)c$dz%vTer6*=naysJcAnpE2vboBzhwzL3ZZg^xE_1)_2eUw2B&FcL zW(!+zg@=0oy{=sCi##j;)Rn!Ty7I5A;QytP@}FjBaRXc9p9bUK6(&VZ!%ayA`L8Y0 zHgiu1Y%~0(WC8`wPF)OYDg?-xhpK#kN37I*3t$V> zeFT`E`_n>;_dQuVYN1PBmZ_}9TfEcl#^=`Abh1!Ek&ykSp^2 zUtg|J2l-(Fu4-@Z^fZW1~i@QYwP9Q9$d-lN6U6i%K#778wN;pE7`?CIfN* z4j%4F^H^LF6Q70%gi@GEB7#Kar{F)1=Hjc!yt?q2&-sWb^&Mo@Ali3 zYsI8ugwjs$rA3@sca{d2=a5mZ6PM=U7R~l1{udpZzpk<&^i)W$IV*$FUzyJ>#@G4l zunDZP3O}4G8=e2)DEXo;q|ooRSY*pQ@?dPnSA%LBmzMuh zj6iCX{hWsksbMQPykb&WEA^2^)4$ly11z>xG12rAj}?8Ft!(tswaOoNlpt=|kqrTJ z&?vxxBG>4bNn(%_w*|gVh^|*LD_=TzvKLX^EG3#)_JHhIOGSwPo4|0o#`B(-!+g_f zebxHKe=60kQz4i3=g8Q=o!~GyJjpp(m|JFSl$~J?ocx92m&&RUW=F?w)i?X8sjbbg z0+7xvpM&&Mvk2s6TEQh%-l$+wW+-wwx(yPsAW>CS<4@5r)9$_e^l&p0?yxh8t`Ni| zvkg20%R$9KD0hWHDff&(!UL3EXA@7RAORZg2_v!tmF`q!lSi%o$>srm>6H|S)B^2X ztV|vT66Q&WzEYv3LCrtL@fFVn_1u!3AIwvi9c5g^-LY)$kEOwFcdT%;T!@=Lh3b{K zJ5DKC5TfipAQ;Xelrj5>A z=_T7N`9+b0vmdY_zM3SwtpmRY?wNX&N^VG?5}z__+A;qz)l|ZX+QaujvNXdiXZ(V? z{OmPo1P@Yd;$G3ic^NHAm|1j%cIXFahDM~236V%gF?}nu9!H?ApHB?XA?IZs*m$xN z6e^ufgCQ0+_=81#=-f_IGbvy4Xizg)_Q^<)baO)G5(DO zgxn}JpKET9(UqMupTD8jB3cp z4G`IGH%ByG7iZ-QD?Esze`e049rA`qU8-l!$qPyeHl#z_q%CNdv(L)XI;?Ng4p}qk zjkLr}p4PA1I;7{Kc1WJp_Y!Q55JqK#sB5nY)=dehb&d)~g=roafxSw>Sbm)`xVXcf zG#`10jAW<8I#Nd!Q<)M`*0YE;dZ$(eKex&V5$dNnGAi-clRskp_SX#aKy?8;Y^RA; z@xEcdlr!iVGK@89*}AMBb@T}NL#V3*a00ErFr0GKMbDa2oQ-DkTV{N0Y_X9!nY1oWN1B)$PK)1Hfas5LPvtlH8ZL@g6sQ;=~> z=vTK;Y5TAt=ya36;hG?pES_n__RRVv!qlpCcy$N%vN$cm%p@=41Lzl*;2C>KsLXaT zT7L{$DZI@k7u*!SE|y2=Df|?99>gyrLB^ur~Y)vi9TpSJl6Z57d+o)lQAdh`R5kMGB7)eE`*Q;2G zQEcRN!Q?$b+o zUoag8iRTMmKuJ)5s&zS~S*B1~zU7tUT|q&h!EInBeZf#vwR|05>zpU0zRe0VWg5C; z+*3eGa6)oAS)jk-xN&bD5&{yx=Oh{=T<=akX4F4Yue*V0VM zkH4;7TLKmx%@)s6c5z_Q&5qaRX;$2vIP-ud)H84PAd0uJX*ee_AkeYKVtI6CW@W(9 z8KHRBux28|zpfOJu7mRVm*s z%?_&|3rLG%MZsk-XuimeAl!(zkxHX`$uQhJ=7%bztEXtmw!ImA{G>b$_T&F%g zFsQ^s?i59_UX8n_!c>ZltM6ABcMHOtRyrRBB3#Yo+AYyiYjPIXgd#0RF$%&xX*?+- zsPtBuy)cPjVkYkf31o50Tp3zUe-dekc|5FYz`%%l5L^>Pje2fT{!AGEHxWG_Yi|{!_@x>cc6%5SD z$ZvA==C5j@X;L3MCV!XA?SG9M0(T#83W28(9aS(t{d&siNAR`PZa(ke>q+Bbo82ut zvU5xmnR~F1ffCpw7|Fg1Gx@$)QGYDzf$|nfH3sKP3=Huhz#4)dH-ay~7cR-ML4hxY zJC3AyNh<#3hBqDyFFY{D#*eE*cnh{slzoT{|2On)ATR!sO#t-^ABA9?$(s~V<1UDq zyo>|Hc*Nrxk#`IYFkXaDTnoHWAP3E#`a^&-`SJ1RcPRHkeTbBZ&q3G_0==kIKNsi8 zPK+SND@w;5@(Jm9!|;LDkth-G0@RZYW&YJ3k={qg)_?xtrkih&RnY!V zo$Y^|7$WW_MlSzvW>1PbggdqghA-L1jCJc$kjxUIfuHEPj zLAS_=)=>DNjluF!EIspf<>8IN^gzw?ak~<)+k{ykeXo%GE=68f$Z;ZaxUAiN%zGF_5d-JZ0I9JZ*6=&gi*5l3i_WA7VrU|K{v|a zF=S?&Yw?$7*XrNDug-5bH}qO#ji37gcoNsG74BAO>OHL zJ+$W5wVs^^UjrNk2QiwyJ(aXP&FiHZNvXoDgPCs;lE0r3q^E zb1QZFSr@``4tbojlnOSCOUjP5QW*?2!?w1>p3YwB&Mp*GO3M*qgz>{jv{ak$b7(E?tkY*+R+^&>> z2dO%o%W=L!QGyw(WuAnw#oO{!I(8KwC|wq_y)<9lMxDiZwL#OlUU_DnD8&!tX&a7f zewQGgB8{dwkjR8EC%AP&bY^iirN#jA47*}#6?~g6@a?%^7(){yv(mgF=P`2yXr$Ab zuYEY=Rw^DeYTFZ^Ywa=6!`PU?q?O*FI=gFl`bbPev2k8T+=C;_X>sLJQt7BpOATpg zrpfyxa?;Uc`KUT2B@@q5dI0rCDDr{Q8d~En$h%e_rtAvjTEMd-OH%Qc7)o~}(R!O` z(i0MG6N^6LsC174qc^gK-0ayYDy1n5!q9mg_|@<( zH^wGhrdBV;Qzf}LA3=l3S|l{2(ylqgc3&K7pj~tzGSA`-wO86b&05pv_SO)Zw_hfmjx}wah`^|Qo(J(X2h!rc zPxx05-j4zshLMr@l7%0`IwPtjmgCwA{Sxj^m0H$vopZOcn-(l18gE{v?!K>bbY!=G2sL;OsI!wlS zl`om0y?Z#6@8vtXFRh`e5wNSy>T)H41%)Nt*jt9t?c#B>nBknI{Kbhq*5+Q8Lxe_H!J*!N? zH;Gr-bx%ExZEmt^9#)xcGN#!|?Xz6|l^~v7U7wM4&5cAIxbMj53pOBXW2LxqE#=+s zUC(EG;8)Odp&Rd)Qg_wrCnDExg_o7dmilm!?}lv0f5NK>w#Db7WRQa5Z94pw011GV zyHnjESKowJ&H%GT#al{iWgq|S`7S)99~4MXM?gl`=`rD9WWj$*)*NbWq$x&Jdq^ z(Q<+*Sx9NqE8$^Fqc(bfoIHwRM8##C@jW61>q;vG-*gk8G>_$;P+4b&%lQGl^XQpt z@48~+y!wp4mqN@Q?HOZ!Yr_;kT-E1R!Dz4OldNG)t;&2^&}q?~dMa&r60E7E)}#>< zrV*SWbim~#un~*J_!+nsWF_-x*9gTk>Hl>g2f7!ZQCMExX9omA0+-Fd%?Ek`^u5Av zTse2a$3`W_+4p=xIbdWKo>d*OlH=zIocE<>kNpS;Lx`OQ&-Q1P$CASxn1-0~RGYd=l#b>XT!xg+7u%F$Q7jSakj)eTa>Ty2qji4Eb4HFzvHy#qP|SXp zeb#Lbt?Nt*I~QuZr{s3Gk%GGcNPV5a16K0EjBCtb^pLdk4E5uLHP+1tY@v3z5hntx9$Vv0Tj2xkovNOuQz_TE%+7VTio)we=x|p6Zw6woNPx zcG_Z2O%BbGxfe9ld2ol=fLGR4aFV*%y*3D#mSjOJI|7z5B4+&ACSoxT&RK_fuBkxk z1Z{D-MxPSpq+f$DN!oyle^-|TkMi;fqFJ1UGd5NFA{AM^B_NurnPV??jj4yDq`QF! zXQ%rlV=SedtGKM5GccN+LZ_zY*nRh^QhVnOGA2jgF~DjqY%>eUXu}5pt)p9N9V|0Q zXC@$-8kj_9y)dSR&f2Q-S$t*V60-4m5IfeHAp)(*?%V*RU3YRI+fVm;XbrN;Znfre zHV>~Kt<08qOPU*d|3s=CmW8uaSX^bMnclwZa0*-JYD_xdlH-9QSVqCTFRD6%n}VS4 zy>uY+r9H8?BwSa;PMf%#`x7lDq2Ra&?)MJ=q&X-Vdw3kLg=AF;bh`Ngu`{SU0AP{2FA1bXzI)&Qc+N zQe2V^EkBDVUja~}gLyF(bfSN%OWm}6u4HUH3r`v7TIiEzS4!DYc1O$+O(bDf_b(zmfoP2*iYBPA-5lKMee z{!TLNugW*re`hye;8u`de34Z~ks!!LT7(P~?WfwY)j%M(rRlsVfY75wv`_j8-f<~Zh@@_No5u3lgB08$gw3J7t6YYm|-P>#mI z?Ihgih8w9<&jhN0?+L@xpaZf^v}|(+(B!Te$gx^{k_-y^@xZ8pvz4Teo8$&XcRy}gCz)E#b#7b-MxVm-OaCXYoKRhcAIJfQDELSMoUPZ2A zGJT9WYcGs3O6S~oE52|3o?hBGjTo}Z^#p~Y8HA5Pg?)uzq1dK9(?}wqZwRa130=%H zYf~z=E0yYqfTG0fyWBEMhY>h2^w4T@H3nLOIgGoExay2GP9=7H+(sF!>QtGs1-g&W z_gbac+_K^zlCn7G0blgrvHCKoOxX2B-RbMlZrJ;wg{CYdkQ}uH=vCz{^XL9b5MT@I1LRLBCN2G_*J_s4ZGh zWx7MbR#kfA8X5^2SsOa1ssX$FKr+_smpYMtr_8IC^|BTXp$X~a|@aOR`r7XM(DK=Ni-`62A>;$AvH z9_f{d2&YCRYk$@WOzak*c~OoAFfe6f@DJQ(UOb0(1s-V6+8}t zM%Y6TDbM(n0`0~e(Z=fVgsQi^OTtAv{cQHYLACfn!I5^C`4kt?8a_m$6 zbcTozSL$v*0uQgb2#l)xk-#q3kt{M?g;oWD0s&KKtKIf|mIluc_x>!Nn=F(UZhmoC@MLVWfWf8%A{!LJ-a9ibm(5(&roPX(GX)q zd@M1x1j~Z)riLkJ6l^njEwFgGs7mySZY8C9vkvltS$4KH+PxmEb7GD8$Z)quJ$36>!5YC6H4?tWLx3jX zL_~2klDHUK>j@1}T+ZgC#@^9#==euU-lRuP-UC^5Cc+L8jCGOV7-{#UL(6{hSs1p> z-8|04uLdI$1?;BBEEg_BTk#KN4^e`X!u!4==E(^tnRt1KV|!i-9k}i*QR9@it-?e5<6jq(E{}G5amY*n+H0gn_Y9 z-8;^pTZ~?CK_9>Yi%5S(q=#!=vps#u3bpC*N25|FGH$TQ9Pd_4r2%$YW!S{i=_C!G zD_fX}hHLaDE%xg_fp|i?KbzndD++)5bCZZKr8}JL`2AxVDM>tTh|-T>%j~EB_}}&( z|K(H^a5QtVF|l}x|sSOHm@dqAK_|9T*4ARfIiVq!E1 z{?^1IHFL*xX$M4a3Mm5YU!EpeD1oBkARcKhJu}}&7N2i-A0U4zc4~oNFEZ@*1*d{J z{!TQ-;$6U&WxGgOjF^lV^S+fK(41yMfFZe${01$COSKm>OdY0Ko`nRwC?nIcv5sS48^fobUN+7gD3h<@?TK=U zsq2}1JqYJDkDjs^)6H3!Y^(ni&NTu{w6vfAOZuc(I-NvUIA5QH9(Sk7D2hx zNiT)h!1lkZYyV}v{?Q|*B<@K93LuZprFU9Oj(?x*`7jTy!&B9yOv zBC(n=8x!WoL6TsFoU<~Hlq~@JoFJC(_I;+4<3?2gkpWZU!T~EWMF7v*q|26`QcQ^K zyY7tY=WEzh-Beb}LTZdzTqsr?>f%%?W^OSKq2qcG1lkqAukEF_zkk$u>XCWe4? z#Ea%vy>ICg-GEoSljel7W)-xQqU;Q+>#pyscZDYnsvo{+1MT9<8T4`~uVdxf?M~|B zynet59NiL z!rIjSxz;b%7{vy1l_G16WSgRE^<nid77&vHB`Hc!j_1F`ZD`0gi18)_8?o51 zU@6a|ci)iO?`1pg1#z@MGaRt#+VAApkLK*L@84Osn8n1p&wayu_RhR=UwwK_{XRd- z@_u3Wn-N%#fS{lWoezfKS`U=q7T4pO{SIjeFQMNZYxLGubs&kZYA-$P^!^hNiAC_F z(&Wq`HKids+xS2b*p4AAYkL|*f4oYA(x!rpT&_C7K;2ZG?{}K&D<-FkT@)`3VJ0Xb zH#wfssnie>s1svHRy7r9dzwfw#yY({tYB*1nNx)vazVXK$6z6(v#cyYmxjT(-pz)Q zmT^!`Ze~41QiQ(6|xf}+@C5ZNKgKywZ9F6&s&=xLzP2GjAv3Y0oF|N9sQ z)#f|e$7y6jIc&Qc}%ut}8+Yq?|zk-iAB&`7zddtXt^a zODQ(DgQqHOTe)pS1jRV(Z4SSYxFFm9bj`YffOXR_nrFrf=Pmfr^F8?NXDAH)RY_IJ zia@*!T}8>IHGTVN@d71~NRP5^{UuSEQBA;iP@E>vHBrii=Mt#3LM<}6v(uCW8I>pj z)iuPfGO41XkYTVm86?P+ZI7a!bu#F#q8E#ld66=_3qe5(7rwYzkyP1Cj<^O27m+O1 zqSOMa#3!)|Oi}&%<#TTC!j#90$`EUJWnuAw(DgEXbdGZ}D3-~lWKfV3CT06jARCpc zgW3?!cGxC<4bPFx>G2K|pQw6%H=mDNJ9f0i7Z9 zM9Op2T#uZC_CRl%l}%9a`x8xq0TEG6nyJmw%8@N+>W!pE-tgq@Th2AO(m( z5h}V(JEs-EqPp`)cKevppHePn%`Qoa-TTm}v83nfYu{=X)eka!5~;S>wiZ9KJjMq6 z>Fgx8lpK|M8rEmK1%a_jTLUsb8vpPoSY+$7N+_;3vCrkzy8E~s*E6qfhheM@ zrP!Wm9FgoRV70zMFupOPdouaMx%rka;9iusBffkukbq&Oa!Av$T*C5wgjUDJqJ6aB z(?h;NzQ4!^wA4Jl_hYZYcSg~3H}db;N0wk864a3n*J6lB-nb)I+5y2n+93^b!`=_} zy?b!&O*YX7-^{Ztu`4-1**M4EM4h_wU2-D?C}Aqy5ML7Yl@D#`Ppq--or&5LPqq_} zTx|N&G1%{D- z63FD%(!Xv4BFxTlU%s)bFl{J%a)l zqbCh9*g7WHB#?5O@r&ddY*myj&i_IQQSRbI!%jx#TIh8Iq)wt}a5M>>xO${;MLFTF zQ_O(@DdX&)d|+07Gko>hSrJy|%;=1|&mC?0hPHtn%4a35agZa4ED#_egj-4`fBqo0R#9mQ#BIn&i-6N6{L`Zvuc zhVM*t=AS0*G3(^>#-9WE*H7jAAN6DZVp#r5)s#1Ibo$Ty%9LoC$U%Pi5WROaGDy=C zPt+z^E_YxBba`ZMfei{n!7?uADyKFLcYluL^~1#!m1QqvZ}0E6J}Q3>QHVrfykO_w zv$|82jDqR3+Dr8`t0^fspZL6W?}Nb;in4>0ln_bv#S{!mP!7LHENN-l=~@%6ujbu+43{~BuZ zw^SLl6$KJ<_cuxbNb7Q!O0hDnWC6M4;8A_GNy9bkmdF>;M}Dt+#2h+{u6VQ^>0eSK z?k25<;(Ths!zu0AKiM3QGv1%~7fk+3?IroYB0MoYk(mh#@FSK8vIjI`ov_bH&I$oz zrLZYtsUQX0EBOWR#C}5l3RW{%Bo}~%2(30eRFFehtEwIkdu=PDTFFsev{oQPGaF9N zLO7CGqMw|o4 zXEdacLL>~Z9Q8;+O$?#CmfUc5aG9?YnHuPISSR3nZ8JM_D8dyb$SQv2-HWX?N}@nm z^pSjPE?!b&xN4pT6Iqj~IYUn!w~x*r*YJ!DJC8qDd%4PPqge{1d$*@GPtr)Wz z>kkUX_B@U^7XN4)%$HV&YAuDsY&6oUGVU~47&0HNr6)8$M29v4AHrT6Y7amNwe@2$ zMSs9J#(B)Opvkmq-rs#zH^A-}z<5I6p~|}zU3FOP#3gE}fPLjmm(O>k5}KVb$R=n4 zvES$OqRV_LtbbnFs2e-~T>F$+Tee&KFz1vD>C`sQ)TI=mBR(H3_R%|oh4VtiF3Lw_ z7tdE0!H=H2f)&ytAwMlWbDnuG(ULf9m*DTI1h-oaT(SX8kWAje29U8iM_5m`S?wCh z|2)fTcQ|>_y8p(TEt&BeR`_UPS^SO_Aw+z!Pzmz)2I2q4*o0Z?4L!A|{tFwR-u=j9 zsk_AMkBW&!9LF;X`vOexf?OkPMS?qF1or}T8%dvO4jne0W%dkm317^C;}z8p2F%50 zC&$arDGBdTWteETu7-Ej;`Eo6}jy1~TUaAs~m zhhS2-ZEu)clw!Zg9(sfvs-2Us;-4ssADLua7E|t`zlU(bj*`I2HTml-oa)BD4e;6x z#Il6qrF;-Y&tW8D@woFayo)8iO4hl9<<`}vd|k|mufrz)`$@MDyYyXLUZ9H^p@Jxe zn3mtSIH_Iw3x1|2Uhj^WaR8u^ISw=>@4vIf@UM=kjX!9O{)a6V`2W#l{>NGNfA8Xd zH=IuY-n}iVHvby@n;Z4Nh6Epb#M;g4i74tF_sb-Rd>-;(kwu z!RK#BjQOW9?`I~}#+8PwCNmj9+V$-8Ece{>&Gqh|xAzMwe+X%;d4~ahM4=pFn5%J& z@T0^41a(ePmuQCKNZXc45sKg7Sq99%CmTnsy4$U_RC+C;tYjWEXHr!g4%MNwS8o=t zU5BBC4m*jkf0GUk%P;RA01A1p(jYj9Vw|c~O0{}Vr%@Vn#JfdxEAB5UcKs;NtiXs5`3}FZBK{*S)g3 z$55~%jX_?tZ2!@XL*pbtJ0W!BhNlhcAlYmd__dLYu$LT3VyZdB7?{G*%+mk){+zJ4 zs;d!SlV0vINdFQ8yIDmbS|~){ZQ+Xl-0nVjY{WBZH5Ok(qD#50@k&HaWJ=SGQjG>sw?0g%xYX zo)I%5ZHB10EwcdHota@yKcn98pHZ*azYhpLLnCWD!~gxero1VS zp@{gsIoVg3UI+zeB3s%p_gfSf;DeNK@ONMnGm*)fS&4SKAx4v=6GM980?4Bv)-VW8 z#%=F+UKG0m8qZe7ZTAh#?Cr)Tq8}KQ_&S>Q)0X>H>+#1=Ija73_V>pJg^y?j*~!oY z-dh3EgHGCh#cwnQaC#T22>X=76ohcssCz$4SzkX0OcV~A(0xas~l-q|+(dlYU+po{VjMHA~h+?A9sV>Gg8pemGtgwQ5AD<1!^m1fsM?$4U=Pdx_dA z1Vdd^{^<QaRq{WW`$q8N+3kYCzjK`3k>V=-aI z24Nj-l1^-9@jCMfs_jjagNd?f30jHf$A9_`|w#Lm3Kw0)GM{<}zxR z>)9>F0>Hl3fVi{#9s@Nu0wh9jAuXw^`{pc}oS@tT^KC?^x}q(lC%Kz#g8xDh&VExs zNwY#ntAS8{_V% z>+5d(Cat43U!n=EJ35}M^%!aT7r^byL#@M=>I%4i#Ns}GAERjzpA-XOl0L$U&V?$O zU5Et*b(n1e(Qj=l+Kt#miKG*{HUE^I6ZIRiZkqVvq{2)w$2r|dfN{q6-d5PiP=H>y zFfj3n#fJ%9Wti#CMh3gPv`;=Zu!_H}OdwcEN1rtFVw`_} z_Z7iZ!2v$7Z1VH$Qo_SQ#Tns=?5 z`x!jNy9?0?NhcNi)A88qo3M6Dd#sE$?1>im5Hw1V3NN-b%$fzwzRli)mN1NdKEb(pdIM^yv_VSLm-8J|0?3wwKx390yng>H+3*|GL-*W zhqW^PVcIsjKMvvlr>9Td{6EOHk^L&Om4yV2S>uv;W9x#II$Ugm-=BcL6@dv|(oORY zX7m_FEQ`+Ch_@gwICp#EKsW=&-ti&EPRU}DiodxpG8l}z?0>$@*Qfn^lwUA4vHp>T zn8Xuty_)qK^|cm#L>NdIiWn4-tCFP#ErT)SiO;BWj^5g|5=@2g>;78mCz@MVas?|7 zTw9y_YH6PE62ZarIw}?Se;E~U6>#}oDb;e5%H*HjJ*!+#%z=w@6J{Q%VSe+1aY$-A zYiu2F<=VJ^sE|Gv9({JrR4pe`8$PwHv2b13V1af%!1$s2UkY;kRS;<6g!xUC8O*#Q-fj;-J7t=$q+gn)jXnj( z1wxL)j~-PE{e9s9bfni~T8*~RgP&P!!_c?gcR8}vTUg>9en5>d&RK=wqPzDm#gp4$ zj01f?E#o{t{#5aQ|3r&h{ZwH5!#4lnpFjQM4u=2m&Px?_6-;NO@5vh4aaz$4;+Vfo zXzFr0t(35F%ut&_KV4xqqT+;eWs@}=fuc#Njz-9FE@W#<@0CnSrHbWCOXB6BNkoY5 zx5$>A@1ET6XYn+j+&CX^rNsROBZnuWN+;2(HE>lR0 zdt+vO8Q`bJK=B4C;yF_|RX7V=U2w9SiCA@8{v$N4F98y0ULq4>-vfwx=hNc^ke)jP z=JtUX3@51;5GL@pCPIo6e?R{P_1Z&Yh~!3;`{l=LI!TdT+GBjnhRsd0E4$?t(cF!z z4~#=v5NNe=^9uQHzBg*}*h}OJs4&Oz+O9l{@=ma&6>15fDnS3Lu zhNjlUH_tu4aG8~G#M(x%^W-&-9c^k#MVC8F+(@<=A-S%`Ub$W?Fc$Kt5+9$Idch*` z8DPZGrrDga&I@4J#R*`!JUMdw*O>xdJluM;2O(QyC6bm(|7=LXtOMpeK2{Oc%&@VGgIM}n=xPTsHZu*o|%=ydsHI*DGc2AD4b$rWMYr_F+cj(?lYu$Y(d0;`Gym zsVB+o4{0WaVAxWNLo&g-2maMO*qGgJH^Fz&7= z2fEolQG2QIcl}C3QYX&n7uJjBQw?>=S+N}$3TvDBB4GzLg zRLYKx^=)OTX4DgErJ$67t1~NTT)b{xDBJpm-PJp6oYIFy>k5yf4es3Dl0RBGlcl=6 zkeqZGj7n2lOVEiD7>~>izlNL*I0?~Dk3B&I=?k3@VF&JxNNflsY7~FfIS1h??ud;d z(DEysJz}!|k{hFP%wR_V1vv6eo}VD6bZprUiHm6Oc!Z({ZoD1T7?|r-)XyP$bG-Kk zs+K#Tcp+0iFn)Ojr~N=xynz_nO>QaMQGRLk!77)=oI))vu#!h&Wy>uG*Xlp#{1EDy z%3$r6jdxpHLNJIgSmO)!3NMHED&BdX_<))Ch(?8pE>b8Lyn%w;OM+3lR+y?QTQooRsb|E)Y+ibYPpR&p z6s+)b!X(VTwzS7+!HF5!N~m_e9HxfjR~m1(1NVhmD`i`y54ph*TuOHuB+7D#w|bn^rs6qM}j4>u88m-909 z8Qn378h$ehryt=81-d2(punML3ZG(*KwecJa-AGkfNPyvMS%^{9mNgCm4!IL&HC@J z^l77MMF&_St=`G-5)v585Jn?7Ln~EA!8Fe_82Ch>P0PpQ+VT)sB9MB@HR@Z3(I;CA zJo(00bBCDqE0P=Q-p@S%iEzyp(jhvEEnkvBeitFmh~)w7kJK)2IQLuSThcG;t;19m zA}y3r+ik(BUg}RFoeS0@+Aw!O=T#}{7vd=KmTSobahGQvS@-iPF`2(zEWZ|rcL;+h z*A_P95X#6hgKb=iO8R&>Lx(@?U7Hnbcz{}VWQ+Y_<#T}WigYMJ>43m!22#ZMp5gld zvjS`{o;AuM{G5Q_d%Q8HaIyEgX^dy2Nw)g^$op4#@1uRb@iKc^`0oDIN}!Mz`O)-4 zeusYO!vEkuT+-Cu{)g`VLl%DQ1^)|Es7&0Jo|i!!?smr5TtY%458>ez*n}wn6hK@k z`Jf#NB}A3*Xpcyjt>2`!1o+JMh!McM?KR%_f7^?f=04Td*%F0@2j|n!kd%~Ws5j%c1tuc1<14SI~GT{=5FRz6U0JD0S?LmuiOd&*a4Hl2GA3j*mk~0 zHG{zh;!{+DZUTEyhhE~-I~nx~s|gCSu*A?HC1m3($CYe+6H9wDyGls11or9(nytJ| zd*-n%2D@K`5fS*rJ)?+*sq?mMo6t0*6fGywY7RRNIp4Ub#|f4Kahsq^&@5tt_sEw0 z6$tBs!r=*u#H5mic33oSM;v_oggvkemK}+&k^{?7?z2fqgf*5IzCiS_fY*Gr3UPfh4gBdXY(XjrTV_9xzp6snGzFWJz6*U5Ae z>b#^$8`}Oa>Yx%)Z5Ua^{d@1j`9<3&2(qX3VKiS|pK-r78?u0jI73d-73h_vE*v9^nb#_S=Y|+zY*z1#s8FFs5YJ2SHfgyTzIL#sp<+tP{L67dQd6i78rY* zPo1dBFRd8bfj;rLUm!egc@bm@LV0>{3_0s5RelFi_9kbtHD7z!KV_t9cYA;Qp^bbc zltWd_-A&ujR6b=W(!+E`0+JwY$>sB{$|=DQjq@`FVnLG&nzyoVm#wvk&sDJ%kUz$< zsz`N9uTKBzKyxY92j4VNeFI0ST2*<$kTnW%H&05Zz(!w3IP3>SMCedaI4A zV!|4#j{auL*KY|)(UQMQZG@D-G_i}_&nIGbPs1fosoM8gw&|v0gvu#GWiJny6dkAA z-tutWs3nWft)s%3*w5>H2Uz2q{mj;TB{`%`((Z0bgJ@|&bigU0=wieD!l+jHeA2opi z+<@NBOcX&dBF*y`WU)wDjBvt|L{|-1lJPd|sI&$C8(Rp_U|c3sZXHuWY9QX6;iwQ@ zLl)3S<^&wxggq*BjIn5v)~&}bg&vOc?VbThy}Qj`JF9KRFi;(X#(;=Vy)XB6dBV3J zDevR#SQo(;_9_)=xm+BwUe=4x19DusZ;98PG=+T`ysxWBjg|D)oYj_G%rpHZl7LV) zX$v2yquc{&c9dXA4Uk6IXmP8L=$*(MyP&AihZ^D6zu3_R{e=R?eo&(G zgA&1i|9A5rl>F<&q)_1>d>FMGiksGIAa&&UH3jzB36t8@&K8KuOPGl~Sdzxq8MLok zG>?S8p?u(Vy!;k|@2}?>b17=?6)Ue>Yv6hw&-f2<^6QYo2k0O#M4vuP>vh?m3~FAs zWF|jlFeAtn3PM((0JAqP$ndl)Z#OhZ5y~7=^E}9~1p_iy!7Z70a`oMBSE#o}pjLJh zVTz*5IIgH$C%LtC9E*RfOV079G@4(p_z1lzvA&$?%4XRKRqv;AP-^Pnu?;u+((h8i zL2LgIFjx6Cw&tN3x_U7nKUtE$c!a$9$#6D#qZGn;&uoa&U&%^Lp(&%yiJeB8xx|}Y z`tgF8XP6d)@q^wa%SeIAAnL0Rk7uuKv@%S~4y(V+fD5CQP@ZZivy)%ess1v}K?`t@ zQuF)fi}JY6u72#6vftxICFm+nwzg$GCg1zMT?(U0_l)Pc5!=B4LxEJS4ns<{gO;!< zXgw`8Hc(F_hbG98bMbG9=a+QL9r8@r^6nI{s-;H15v2MGagO#T9zUH9Ae$D7YdLjA z+b+6rUT1u5x61&npD`pu?-5155E}FMJ^B~@Z|iSJ|IA;1n~6ymKz||ax)GgDo`@H! z=P1HkG53^qWlx#xF?6NhQERNoVoC3Pkt;yj{nM9isXV40D1&?jp+)C!d0N7Z~W~jmsBwN~D`fatRBJZO#*%k>!yjFS^0uKVbnUJd2Ryq$#3wPIxJfZVqJ{k&L&9 zXGCBQb4AEn#6de{voh66ZgSnUtK&f&3VPU`{pLb@%fxrO3nm!q)B}6PdXBGvSNwRb znYu@N!ldSa(*GSjg59@YnmN^50&QLU~Q;g};bg&FW1uN-D6+(tiSj13|*jaU7szS?JO%dg{la; zsYTbJ>S51)l`=Ja293O0qU*grE{>~Vl~KEju8(CD)=RK6c8wXv=Ry{0eQY>gXHbMs zf(9?Q^CXoZo16h3k5t4ol0WgU@(59J#$rXL#!T$oiR2;)m5l~P=ou9rBG zKW3L*?Z8_lpgc$u*MB}N{M3p2H4S>dtnu8Y?ig969?)uZXiMBkgy{rwyvHX{IwQ*1 zAaq*bEdCiNur{67aksM~O|G6rDQ9Zva~!a|*~U!cX7%1NuGu&KR{sIq?_r_$D%$FK zxv_K6f~%Io%g_V7`)TPMKhqWVq~k!XKec!HEiArL`92$v=|=Fy{>{a`u^4b%_X}@F zaX=)3VSRhobHA_OLU51xa|m;}5)1(E>KAu5Af;kUL_1Q|j#ePnvNgw%f9VT`kTto~ zH}bUvD8g--TZr)D%6`~)z-4bH@U}GFb+C$o1;du}!_&pT=wTNZRcmcOcPPeBVAB6U zApYkL{b%<4&!DbQ;Zh1g7M80S$3itpF5HI{9ABip!2*Jmd?dIe6pq(l?`GSuohd_}1NBcI-LaLWPNMI*u862C=;tK_$ z(n&p`Ly#LKfE1kWXOo8=oF9Zma{O61Y#!*hdweURwIrF`@}}l=L)N;UYbO*a0={5B zQUPPZEY(0o5Osk`nMW4tB5m+6q$f&l_QhIa+@Wd8uwM`_ByCMc5C*DD%?Pb~C@-qq zcUh(7rHYZwlq0;NNurHgAibV_8IBFj&GvdPGrx4aFyXuJ79qf40_xr5Z*&bu?vUHi zrL{iT&VA80Zh;VY{H%tC6_8BZ({o_1Zv)FXq{4b}9w7xB9s!AIEI+J~1?*I0z!gqC z3xG=tIMJp6tvi@N)02M3zh-%m@oA)pc$rU1H2dNhDf8U~Nl`etmlVKWe5;&7d?}X) z#txXgpFv;o;ZgP|?+G}GT#aCqPZCeLfh~{RR&(0C1`nBj>JD@+Yd*Zipb_W7Gf&dR z5V2ZWykWs2WOT2WZg=R5kzfX%oX!y=y@3yCsa3&v#Q~(KRS0=IQG@~}1gL_Hi9MPT zOb$ZvS{D{a8pi$b?0yjmst@Cz0w#;kwov4k0bZp8{{js0aEg`EA7HHgs5Ad#3jY5h z$|y+wcqmZ4jM^{z+5*F5kf?I-8xU8MX!ONG3S{RC{6wKbw}R+RQPww&oWsAMXvhap zt+d>3e}@taRsYzaJdD+4Db3PcR$O_GT)VSUS82Aly#Lhr7-D^DHL6>UFAa!(Z`tDH2S}%#z)&5j#_v zI%kw=H*yBO2=zB(wjZ=7X^wI{0z0=}w?GQ@HU*|v+fE|{v@1JogpFc!`~(7k&3Q|dsgmZW#r!!e8PcYLjUy34;4uRDf z9#U%h>|eU(4V1H2NwYq^1oLj0j2<77JiF#IyodH-sB`399Jg_m`T>J$i9NBqF_T2| zyC&(TTyrJmb{i;KT(J-dQ+S^>oT@Y3lhjgdc2vlbcOEcq*0q?A*6wQ_9vQ>{0LuDb zZRZ6M1wCSOOxa5#T1c;C9jdqIy%R@%1LB=aqoVR=;61$~LOOqq4|2q|NfP$om`cza zxN$MGnK9`qf0*4Mo_0+=CIO(it+Jy|&3OL}#D@u}0H~9Qi!g9G0v+R!Lxh||kCi%P z(<{KR{57SQLKrXLIm6Z6l& zc$4!0Kzl;r(d}r&AQ6n@8xKsH{QdVC#Q%mnNLtVTh4tKLwY8B;`=gfQktp{QX3*lp z`jUi_(Lx+oeZBQoN2=!c z*Zn<;PjN}Bi2kG?u(|4nb8Qp|G&Vaa0zF69U4C+aLaW{18t48hLP};2qUR{TriE(( z_nufef{Tz|-WBOp)YCQ zAo-a9Tr1n4nZc&V?(4X#(kb*jw}?4Yd6IXU`Uo~-tv&3WlZt7X=AE&j>pXna8_WF7 zu%l%hY6M+wzY%r-KGIFb{7Rh~U65B(_(#e9GL)8hnJqlywnCmU+XCwELaE~6}7dR^0< zmG6o(Pe~FJK>Sp-LmmQ_Y{Ny|<%<-BV3k!?K4k7SP4Ui}8v#G&m)pT5%^uHxV*AOf5Z3mFX_%v@} zNJoU0h@y`^L0CQPfmGf{+kDXi6rb#B zHBK+?u?~L}H9l@Q&SWpRuHhg?M142jRAWZ!52aHNiFbvJ8aIyf!pst`fjGf5-6-f= zwb!bz9W=``d@FkoH4BPMZw#@XZv2wK9l1@uAviWs!4QCw$(cAyCaF|bC^_yq$P%7Z zu{nCX$L?(D3Z0;9JzjM5)QOA}SWlpp#I+9B9jRNo7%=6RC*+7oc@0!e*%D|r3Xd&G zl(~xANHEg(s8pe8%^PLPo!Pq5z$A2(dTpf|bb^>)2{CN|a^v@|NwKqqt4y zZJw|xD>_7omTcgs+u=xRHk>B!XurguZl!#dFd1?Y8D;e#LZ6?H0EVS0ayB!QtN-g$ zcH%6hKcDnOkn3A`eE6n7uz(m=Q__Lq7zgQdsbNhgsPy3#m~(CooW9}SsSp8C3pFuJO|^k466PtsDJwZU4jVD^=Zf6c$sz zJx3=tMkj&d{`&C7jN}vI;f;uc?!x`X7yFG4w_mUx-5YG#Gg~Rqd!M6RXb^Pvi z%t2y}>Hezt%l@$N_n%u|v#*jgp3)OuAYCVJJ)n-Lh+21Y{5( z{EQ?{{yV5!#4u$K;;=zlSwb&nd8J2pr6J!ak^wTk~#7Pug_Ji~W zzIeweDy5|82Dy0Q5*14Ejdd$Dj$?r03lnnPl=5km%95RA6a~DGO6YZEuqdOgUaFQO zu4U~)q1@XvD5O}+Z-ug-R`dp$p%jSwk9xHvD07!%0Tc#7cqp%hs;f4&p-QVcZpkl( z`ElaX+Gb+m8b%|Bzs)6CF9b07oG6b5{^&0|4*JL1*mI&oIx`Bew_lWCMGHW+^3k^T zMzNXq(UD+64Ee8TSm5)lC^r`p9Ug|pAbz()b%^tO2IYYLF!PBtzZWsd% zvISKmColu+(}g)1pXXz_g*7c$hjGX{Ga7|Zq2>!uK?&*K9$hJ&Et&?ekLm>0lfgUI z4MCYovgLTSV>!|vG=YIL0FMldJtyfX3?Oyt8JihgBD<$+&SSv@nW0}+4f^>V=?Jex zISZFs+aFnEzB3pEbC_uWhcEv`H8VLSZ#J!#o;EbI?WSGIwwI5GE;R)DF@be11NTRj zkL(pD$XEpP#a>4CVoAC8AxU(M|H*%J8Pc*TD%d;?W4CO2VlbT3e26X=rIpJMW)||t zBtD;=S4a_foJ;IY*+jQH0n*l_#f+dqI!IR5z`tP>Si>@8Uo<S{B0)7%2v-7I!k$kBpHTmCx3?f$ z-V45|wQlS}4y_x{$ax0I*8%XXm3rf9hzemc%s^*5MWkUflo)UxE7I_{PCY`gk8D7? zq}n;5q%8X6nvMkAp|ztEy>0Vq?p3_-m<;NH90_JLIdb`iwJGs})O^2~OaVug9$s;( z1TZ#2rV}R?B2&11e18F2sxI5*ZBPkV_iN@8bnk)$Oa^XTk>TskAA@lF)Y$Wlk=8bD z^~8Br&7r7Oww1+Qove3QT|**)gcG2hqNcwNmx zdKav4mfpGzC$czs#!CmON)5DFpNkY2Zp|nDF;s7?)6KX+izo--brmr3100TkLCV3NKFgNP zzRDHL-TM{8UGWvFl$e9gDvqs1tm7e8r(%k}m`Y@=_?SSB!g#1F`AJPqV30|!=_t#h z(Fz>96BCh@xDW?bmtWDKMo`x_sQAIHQw8-0=%M6^dS$u~RhUPwsr4pG9c@snMx#!v zz4g;^nRb;#+41L~7pu1BqmOog{Kai+aTtfhd#kjHA~ZLN2kB_bi;KzHjR#|?NgMbq zDtE4{hNCD4;Yl8%E#gLcPNNlK;#P_4h`pCd8+gw2kPiuIy;x?#P+wJDc1lF@JeRB@ z$Q|W*vmy&|?Fno9LHPW%3srylO;$JUqKUMV+^Jr}>;^sS*5lp}0mQKrIH+7jfcj1_ zg+s$)`O(~+Z5M1?oCRX%$?t%xb;lIl73z~;%t!lwX8%D0z6e`q4aN9(@%@&dO|W@V z;++@g`9#rU`e;?9(L$G*XN(8Bx}*DJ_pXYD$X;RIbq8Rr%D=?B$lobn(>RSrmZ>`M z-l<&a!zIsh8VZC13ys|@+*k?NH}m`AtVbM^IEkd?ryM$Cw+$2q#>N(Yi)YDlurNR8 z>WtKfeX;c>G{i;QZ0iQAs5v{=VT)>lsdThblcv*gG3QgFQq=PcL_cL3UQ$N(Nxf4R z4mK|YaaoT7B+@rRIk94fCa+#z8pbv>GA{?k6IfD9Qd$Y`8?O7`P8u?l8Bd@O1+~5F zk3b}KkS^EVpdSt0anCSL5RrJwt8hsKk+@l)dZiqBrNB~tHz-%_@?V2tbD~Rua0hn; zWoW$_b;r;ONq=)Qf5hY79~#b-t;BQ{x$wsnqi}_51Z!v z?L4$6bsRH{)NG@|>9RUTPPU;ONhxDMcV4ew6>^FOq?dPAiRxB-ce;+K97R*jDvO87 z%8ORzfSUXc=Fjj9(@u|Z<>=g^{8`_qMa2JjSc)TIdA9;7Ovs|WIF^2?5?@bHmEE9n z?$-A4c@Mu-|KO#O;O7Z`a9q zxJ`0HDXm>7us3bPC>`CLNegu8cx_I)SX5V?5VP5TcLnIIvESG{2TtKQ!ND(1UekCl zc7Z~|Rf=E8iPbjA*?%a-$`REL@!^e6s)e9S6@+6`78Q&|uy3@IdM-hfL5b}12!>@7 zfi4+{dXzwG`c-9RA($`Q=dT2GyitLcY8XS@vZwkO3Ci+XqErPHx&*hRQ>k!PAe-D( zKu_wUU(Mob>8;nnjzNB<#*tzzfAQ<1dwkKY{0Grhe`2(zv-PHPL9cVv!zUYJW6qGB=2E|tUuu!j*P^h z6A5wz`(>$mvRL93>J%R=#xIxH;;J2358v*)8^Nzz=BoGRGwaZ{3P8dA#muN~;kYDc z>n7*>Wq6krKp{owp7p!m9-g#sJ3KjP8~sZMC@ntYOMBxNs?=;(gUT<86<6XlZGIJq zmjh$mh%uR~bHRQ7BgV^SsjIB;v!HL`s&hF=eEGq3m?O6obVrt*UTHzU@Z4X z-?+ybh4+k#yoVF~sH@?!)5R-q4Q|Rswd5kTiVN*bX#f!fWUUvZ%G_8Wh_-8~Krz1T{UZn5L6|icUfS5@Q;jk& zVuJ-%WbUU5U_BeB_uF?JDo7x^y#3+W2V|U%!@mnHH_HruYy(upytxuSII3PphBQALx?9`yvjWq z!{rDyhWNr%9n&I}DeE;wT&`j5^IrP1xa2A;y)KY>>7rzO`p2Zq`2~9mCr27&C9Y}$ zfx-Fm65aMd-EO3PxIP63dL05*oaG(80iFDGhV@zm4jY1XbsMVt3-+Lk$CYS|8+hS& z8-%Yo2Jc~sPn4sx_K6vo)bL^3@`#>GdT8enLM_X2n`ng{EjEy6QHHDJ@!K4W-u}5j z;R82L;^tjjS9s~0wa*aDf%rR1PNM34(^t5xCC6U85Qv z#9;JkXR1$G`yyCjQMyIG)@UwUJ-!4f);oc9t_(w1yln2mwLz7>DA6+c{VHy#uD;PW zN?W=wE0W_bC`8(N-?(lFJxtjI;7k!>)4VR^AiV>FUDtB2%X2l;BD&j^t*Qr5y0^;) zw?b0Lo~#FTBRnG3aNY;OfGPz$bxA(;DSs7~`8HJMf(s=V$pp@Z>o_eid+dOnJS&Ua za40~9C)`k?Zi>!KS8xnaf9n^g-+oHVESv4eYS(du>_~|A515P|J4yDM=;2 zM0UyQN$}xOR(jHhN`2J1+j$tsogdDId=a1G34kCCB(G4k&=$@;>O>I|B>>^{_48Sc zF7goM;qdlV<~?UOte=}I&Ji_tE;=J>U=Zsh&qu-Rdjs0a+UHRgr^ak6plCe6KMeF@ zJU>)>K~p3`ao6e%LWVNsOi6dIjRmGE6I-(kifp$A3{Sw{=m9-@#~)7C{Vyvh&i?kDsRp06ZX^m-c+W=jeJ^p~r` z&+tq(N2?f3FuG>)h|bl(t=@I?$kxS)Nd|=ilsIL(qm|b|;aqq@BJM+w07*Q$e{p1b zO-~@UruWqZ<2gtf-?x_M^b)WpXI+Vm9hQZ_$sO<6#&`h%{5IL4!UqK9F4uw1q`lGK z{0=2%_apif(a-9CV}ppmK!6k0&h0_%`)R_3$Lf)y<^B~YGbDr6N0;I?p&eL8ihQ+5`uJtvS zwQtSfbOCxj}B3QIBrNu;DxC)>e6{U)~!hCzoqNp zny3{~n|&&G;_;E;K01dODI8 zgce24dlcM~M_7Q@}Ut2iC8q15dzD=iGf1Qb}_RWK_mU~xGb!Gi?!VX_-6|Lq=cFf7%4eVe=NU9K=Wtel9tQbDhyk7@)G zaj0%HnuKM}X@kYq@wq8P8UR1P)|Y09o!s#I`tXB|@NbghgAV!lkM0-Gs6jjMIJD5~ zLTaM>2S^zW_=`bgY{)EZmpg5NLtngzEc@%fOLn^h?{04}l=FyNQF^+-l}ln;N$hmK zs2B#P%)WyHu$muQ{niPwIQuM9iJKo*_bCE-xZ`Z`Ay@{x264);+4~-3-OIP`T-_`# zcPeW@wg{)zN6*M}nuJ;(iPbyb|6*;C%?G9x{IRt_{!DECkKr)?_lU;ef7!wRXIhh~ z{OXLMjPxZGE}TT-R6%H#QB;~Xm}EFe9!XYu$?iDUVr#}hM9pkPMw>)@R}d$J6`8?0 zlQf6iR@+cvy2>IC8e=EIH=_Fr1?>&keJd>^B{lK96=5)r-aH_DJkfsL)$Vn@#gXs5 z^)|2l3$yQ#bdR)*R1ofOEmCKVLP9=hd%Cg0imbqfWFZuEnWf4A+bwIgp6Fm8DZ5NW z9#*z_|FNv%tp!F_|2^DKvo?fmnI~PCrHkyKxU54iYVWw-r`#WH1%;I6#AaySpFu+JAajI9B6z9S6suF{--a*iU!GEB`hCyV+7663v!t`g(2DAf^( zvqL8QNtR_6sWrH?nM7C`d^aC+_^@#|yt$va@g@GW)5eal`&80|=ud zy3H!oR{ftWnPfWzqfu6(PngIVY4=rTa-mUM)x;s0BB)^ecXT%Ht3tf}4*m0dr!KVu zHuSYNA8)lLcAv_i3|cY6Gmlf87vpW zgQK60L2h^GY9g%N=dM-xTG!K_Ac~xyX35Q)Ff>57LNZBXOgcjz2f@}X4z`BsMOa+#jN$U=Mv3JwNnzIQSVcM;*Z3^E zA{w3pwPu#}T&w5q>C*~S!>Ck;QfkE4_@~-}UTIWF({*R?NVbKF#Tt%?4oqa2m1%() zy5ShK6#7M)xe0fFu-=Hz<HZzOA9QOVm*w#3~(}3Db$((Bg$sXXoT3D=1ov zkfK!s{bCbgA!eie60>QMBl$du2R;Ll3Orz#P0szlxIga=FiAe;RxOO3j-ZZT+Q5*? z6Q|eE7B>era5Jggs7a`%P6Eqn0q!c6Z}Qx?#9q-qP&^E*n=zQ71Rd7O)>QQ;5D{>< z2$yN_=V^VeVH*_*rA`uoo|=OY-_oF8)MjR)Bm6AOLGqg_X~2FldHi{{#Wi`MrnVzD zalyDY`H#%&obRVPCEA+Q3Z{==JPNl2U5QKkReQteUVho+E$bNh{-J=04tckZ#4b={ z#YfY19!wIu2|?Mr#~!MdwAhG$=D?u3d+3Y#ql3UC%v@ma(Y->Q6+guK5nSZ@t8GPl zx0v*OK4X_58bPD7r_r&0b8Ke7bAga^g~lBc+6|!@rJbWB4|#ay?>4(A_g~*E1n;i@ zK}pYZg7p5CMF#s2%bg+NMygbkP)>)A8rmWDUoh6^L%h% zUUA?NX=0>Bf2xpSkG+4hsathn7-sQHVo1_lFx>~p=JvevkF4kt|1(jzakgQep^wom zfv;MAa8fkl6)X+?yXVr&KOyuO2y@d*%*(WiWs2?0ULdr`zIB!l;Q2S1<20 z7k5(g7f7pd_44zx-869ZHB4^e`7ds-q;y|P;N;>sldO2o=P!Jawe8~XL`#|I-*kidTo?f;>AJ5z^yPW zL_Yy?tCFf_94%n=(yi!hm6D8JwG0Jd^AsX>tTdbR>88;CQdLJ z+Iljw44H!snRV~hZ+`*L@|C{R2I#7>_C4}O(DEM*Z}R&T2-zmMU=mc?Isr*%;l2Z6E@GdQXQ zE6yFGUdVB+48dw^#eF9P@tRto9xXw7caarv>W81sy`xkBCuxLSS zJYB2+XzL$#8wSySDztc86VU-1jzEqUjNycoV#A3LHku%J`m6DjMA&sBA%70|xj?F> z$%deE3^iWo4K}dQJT1D^^_tdz*`(?FuPq%TL5j8}E2Sgk6A=q77Ds1ZK30w{YP>p& z#8Vq#UY6HzAXjm1xJI4Cl-el^%?p2>fy%Q1LhYK1u%WXGg+sMSOM7{D<9fHu zb+yr%#^ebn7uVIY#S~TK9&<jqK}aJc*IBTk3GesKj0%hEbwuH<+{l)@|rc5 z-GAQ-{>shxYk_GNTO?bgUxJQ-v*(hd_CtaB7b_}5`75XJCbf7RdWO2IB<%VdjUhYJ z7abavE%-q)IMZ(_rXmIk8F0$b2D^fJ^0L!SFQ5mNFGF1!vnRa4I-tx|iXn0K<@piu zn!I_Zc>>#8+J`5P%s$me=Di=Bw0FgqGs=|<>MNzw1bHV!z{tO=ts#3LXvR1i7b-bB z(+XTuNJdAmk#H8ahCAUo5Qv$Z{fbN`t@EL+^l`ZQC3gjy8wnWDjeoZ~-X)RmQva6+ zAGHTbjm(R?DsQ^~dbshIIZMyjaTi`&a1+4*v%>4I+w4}F5KMetKAu0j2ezypAqt?~ zIT!PzHOjTgtiStX=)^XLORSQ-T8qwJbKZV^5`a2_Gx?9e%J=f;XO4t{e|#d~(b1GJ z^$Gx@Zl~deLFp61-Us0Gwc!6HhMq<4J6Dn~itURCUOqntcF|)BJI97<8wc2{_enZy zpQYA?u{$78y*U+Vo3?EV&0iyA3X^e@^)cYW-}n9(1BqMq&0Wxs1(oS1R!Zdmh#os@ zGedoc|34|qg>mCjeSZ;yrfpDU|J?f7%CZ25%mj+lgz{;?5%t#KjMYM#a!k_dxKL=O zw%h=CknWQy=-0?1w6l62Uw>z^%}<=K-$VSu?AJn;lNsw#0&Zfci4WRjOh7A;3M6@8 z^LHs+(~mJ31E3#i4h&vKXpTNhdd9K~voy6W9!>;Z%1xc&r!$%{6E{rXI9`I4OqQNy zxJG*RRQSJ2I}>;)w>OSYhR9M~LZos{lo*6aQd!12G`6~;m}DQuPLfa|WlLRKT+1|B zveXroREliLTFIIgd*oJ1uD}18D_+jkpnH6Ltk3UzmiN5pJ?FgVd8qGL{!Dwzg4I zc39+X9C0Lx{^I$>^PQTBw{Rf3>3_1Om{>t(y9z0b^~)7bDnHXYu{`Eble#U_&d!&& zqO0muWxsKCv7awPsWYwfe3b6hW)i9BW@9*n&ud8*nVdYs9=}KKc5lSZ*Y`aF(3%ap zE0P%VUey^Lu(i4%-Ej2%ie^l4si4mG?ef)m+S?0RB6Dg+JSu{nl}^7YYktIO@2mXg zk6v{~eslFzn0gh)_}|ncga~)ueQfGhocpp+;sA$J2xw~&(AF9YwKW`wbJkP_az%>tbe^WB+J|Mg2}58P`%3hV|#z$|=ikYS{X?2i_aoWVRqrw4GpRmSYS!x-AdZqF1dN@&?yW(6tB{}(slgRUw^dojogkv5-xylMbrrR#(P?LBG6U_1d zQ-8r#_esbnGGsqz-4h|7i~gBpB{xT3sAEf?O&#b5@0H&NPIZ((W9#CKl(AZR>XME` zPb()$5P(&J=uEVS-MZpoOfkqk;1$&rj&6sb^2G1b7ka?Ij}Axx}kXn%#&Ka~=( zBEvbvGPh3#IS#_E#a-6As2n2Z8TwkqN*zO|#2W&)1eLqCc(ck-Ndj;4+eDMHIV!@E z2`}z$+Q+u8`;uvWxbY`D(P8UE-9Rw>pa4WEPe**>A*Ffc}-k zi2sj41}83Yj_aGWadB=UoS))DMxUQ;iFq7o#;?R<_pkho;(Z-2L8j8P^u^D%f+dPG;UpB}sTa&=$IoCtP3saye==&j8<*KzwMwDHF+b<+pKzqR{Y_P<(F0mwn zrcl;zL6KVauEe4gHDhPT>Z@l>wLeSVa>1q*r+G8fesLU+(e^7VMd_Za%hk|*$~GF3 zn(%p#^~OgrCASlWg73E2-_vMibv(SI?cLZI?rTqZtAZ%clOC0It!$JlW0yQ1n#S!g z*z@YiP5%vnB#(n^Cz#oLcZFs+q^eM3S-;B$08#&rD;RZ<<^bHMtZmD^iqw zuBB65e^pB8LmvG%aninJoT`EGDyKd=Wa&3AYvQlr4>f1xEy1lR(5T+zoBBF2uU+0g zDv*2a$^5ln%`9J`F_)uF_lEA&znh=2`?0e2I!uhX68b>eF0xOMaUf^1X~ue9sF|S;^NedDo+GnDO%C+Gy1zg=|O+5EmS8KfwBxOGp^YhWZl9LB+ zoWXCn6}9=cTl!D|ka`B=OG1C=u5GOp{kS!4e_KL!?fWQ3@Ge#H@5XwH z8|@}}^H&;Lh*`Eq-rHN*GBln$7*!&cCq~X4tGQ10-EhUmc2~V$442}#p4}EhN{}hO zt)h1`@j%<93zx6DSiUeHVsA)enh?3KU(twm7ct2hzoFi8Fhz4PBbR4oFYZ&Q$;dT> z!C3D0%&p~^eRAO~HLXDdSN+63B{Q}9X>L4NT6^*ZUtz>@ANBO)j_s3mRYP4t;v;y1 z1J$k76io@2(v=)lQ}ui_yf*ydMmBj?=0@)9wY8RMTQft)j}b1B_xu07p-@NTt1O1- zrP&glb2U2-`-Q`(;a+19I#@FcwNEcG3AfmuF+c=pxVoPID8#uB=m8}g~n(O(fV>{k-yrT z%?ghWQ)IKh$vXwJZ@YAD40G=ap`+1KK4p)Br_1Woavo@T^m<>PC&B#hU!|J&ey|k_ z4nD3pDDgS3(P11-Y$uQNhZVz5N6F>F!h6BZllEk!_MdK|&aPx|cXhY3a?=stT8Y=e zON`*J*XWAt)HGrxwZ*q+Vqa@ZR!L$}q20V!284MwiP%v31Gsxj)?B>8!)?>u^OApn zubibAoVP(51dG%rOn3B)1%o>rsY(~gcHxBV%zHNcGJAG5LXzusqp zf6xIB1mL$bi4w3Gd_OZ<=ql@JspAZdBy`p3fx$rYJ<-5uph=7HP0s?jFr8%~{M}+| zNTO>9R$pfs>diHr8rccBgeCIxUk5pYDmyHW0xgInO29$zSUV$u*HXpl8RB4To$Jl) z{=g^)d?NLZLQw)fbI!8X+h+vqVdLNM)J_c802p356&!dPP6 zCE7UwrwB-(Cm67|{rYWDP!Y8AfYQ_I;43A7XB{1Ynw2%tgXFFTJT;NX#G{D6V^}|d zVDJD7^jm?x;T-)4a6Qv{?DzgRb=^((gMaJ8lLIg#^ggES;cg28O4wNB&wi4wpM0>1vR)_@;4cOr@Ob#+|3e&Q7EJv(^^|?+hTO*&u!_h2Ss`y zx5A)}f$&VC1c<8AQN@#OY^LLn!S!0&Q*9~*T1_5YgpxCYw2a=t(UH`pO*9TnO)F@Z z{`~n3`;;u525tv@p!e>cBQ9@1N1Q-(w^ep?vvNE_t6@CZl1Ngs1HH`dhzAnP1TKgR z&x+=ipcT78VZ`UK6Yo4@10Zu1dFQ^1lLKX#%I7Y+9FjbP)?{2X?wBENh6hH0t!iov~!_g0%`C9z|%z*OpA9f0PuiVfdgO zf~Mpy6+QnL1HT-G5DZEdApC1jdVT`D&y5iJDway1HzLD3f(U2xlZ7~o-yeiq2;Q4Q zs9aAMpu!K)v!10Ec)Wr4NDwHhZq{nR)NJ^N3n_D#JihOkz~zHi5)l;c*?&PH>xu*& VCNKd3JGtOvEm(5t0lFyE{{i--k}m)N literal 0 HcmV?d00001 diff --git a/java/ql/integration-tests/all-platforms/java/diagnostics/maven-http-repository/.mvn/wrapper/maven-wrapper.properties b/java/ql/integration-tests/all-platforms/java/diagnostics/maven-http-repository/.mvn/wrapper/maven-wrapper.properties new file mode 100644 index 00000000000..6686a643d7d --- /dev/null +++ b/java/ql/integration-tests/all-platforms/java/diagnostics/maven-http-repository/.mvn/wrapper/maven-wrapper.properties @@ -0,0 +1,18 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.0/apache-maven-3.9.0-bin.zip +wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.1/maven-wrapper-3.1.1.jar diff --git a/java/ql/integration-tests/all-platforms/java/diagnostics/maven-http-repository/mvnw b/java/ql/integration-tests/all-platforms/java/diagnostics/maven-http-repository/mvnw new file mode 100755 index 00000000000..b7f064624f8 --- /dev/null +++ b/java/ql/integration-tests/all-platforms/java/diagnostics/maven-http-repository/mvnw @@ -0,0 +1,287 @@ +#!/bin/sh +# ---------------------------------------------------------------------------- +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# ---------------------------------------------------------------------------- + +# ---------------------------------------------------------------------------- +# Apache Maven Wrapper startup batch script, version 3.1.1 +# +# Required ENV vars: +# ------------------ +# JAVA_HOME - location of a JDK home dir +# +# Optional ENV vars +# ----------------- +# MAVEN_OPTS - parameters passed to the Java VM when running Maven +# e.g. to debug Maven itself, use +# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 +# MAVEN_SKIP_RC - flag to disable loading of mavenrc files +# ---------------------------------------------------------------------------- + +if [ -z "$MAVEN_SKIP_RC" ] ; then + + if [ -f /usr/local/etc/mavenrc ] ; then + . /usr/local/etc/mavenrc + fi + + if [ -f /etc/mavenrc ] ; then + . /etc/mavenrc + fi + + if [ -f "$HOME/.mavenrc" ] ; then + . "$HOME/.mavenrc" + fi + +fi + +# OS specific support. $var _must_ be set to either true or false. +cygwin=false; +darwin=false; +mingw=false +case "`uname`" in + CYGWIN*) cygwin=true ;; + MINGW*) mingw=true;; + Darwin*) darwin=true + # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home + # See https://developer.apple.com/library/mac/qa/qa1170/_index.html + if [ -z "$JAVA_HOME" ]; then + if [ -x "/usr/libexec/java_home" ]; then + JAVA_HOME="`/usr/libexec/java_home`"; export JAVA_HOME + else + JAVA_HOME="/Library/Java/Home"; export JAVA_HOME + fi + fi + ;; +esac + +if [ -z "$JAVA_HOME" ] ; then + if [ -r /etc/gentoo-release ] ; then + JAVA_HOME=`java-config --jre-home` + fi +fi + +# For Cygwin, ensure paths are in UNIX format before anything is touched +if $cygwin ; then + [ -n "$JAVA_HOME" ] && + JAVA_HOME=`cygpath --unix "$JAVA_HOME"` + [ -n "$CLASSPATH" ] && + CLASSPATH=`cygpath --path --unix "$CLASSPATH"` +fi + +# For Mingw, ensure paths are in UNIX format before anything is touched +if $mingw ; then + [ -n "$JAVA_HOME" ] && + JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`" +fi + +if [ -z "$JAVA_HOME" ]; then + javaExecutable="`which javac`" + if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then + # readlink(1) is not available as standard on Solaris 10. + readLink=`which readlink` + if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then + if $darwin ; then + javaHome="`dirname \"$javaExecutable\"`" + javaExecutable="`cd \"$javaHome\" && pwd -P`/javac" + else + javaExecutable="`readlink -f \"$javaExecutable\"`" + fi + javaHome="`dirname \"$javaExecutable\"`" + javaHome=`expr "$javaHome" : '\(.*\)/bin'` + JAVA_HOME="$javaHome" + export JAVA_HOME + fi + fi +fi + +if [ -z "$JAVACMD" ] ; then + if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + else + JAVACMD="`\\unset -f command; \\command -v java`" + fi +fi + +if [ ! -x "$JAVACMD" ] ; then + echo "Error: JAVA_HOME is not defined correctly." >&2 + echo " We cannot execute $JAVACMD" >&2 + exit 1 +fi + +if [ -z "$JAVA_HOME" ] ; then + echo "Warning: JAVA_HOME environment variable is not set." +fi + +# traverses directory structure from process work directory to filesystem root +# first directory with .mvn subdirectory is considered project base directory +find_maven_basedir() { + if [ -z "$1" ] + then + echo "Path not specified to find_maven_basedir" + return 1 + fi + + basedir="$1" + wdir="$1" + while [ "$wdir" != '/' ] ; do + if [ -d "$wdir"/.mvn ] ; then + basedir=$wdir + break + fi + # workaround for JBEAP-8937 (on Solaris 10/Sparc) + if [ -d "${wdir}" ]; then + wdir=`cd "$wdir/.."; pwd` + fi + # end of workaround + done + printf '%s' "$(cd "$basedir"; pwd)" +} + +# concatenates all lines of a file +concat_lines() { + if [ -f "$1" ]; then + echo "$(tr -s '\n' ' ' < "$1")" + fi +} + +BASE_DIR=$(find_maven_basedir "$(dirname $0)") +if [ -z "$BASE_DIR" ]; then + exit 1; +fi + +MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"}; export MAVEN_PROJECTBASEDIR +if [ "$MVNW_VERBOSE" = true ]; then + echo $MAVEN_PROJECTBASEDIR +fi + +########################################################################################## +# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central +# This allows using the maven wrapper in projects that prohibit checking in binary data. +########################################################################################## +if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then + if [ "$MVNW_VERBOSE" = true ]; then + echo "Found .mvn/wrapper/maven-wrapper.jar" + fi +else + if [ "$MVNW_VERBOSE" = true ]; then + echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..." + fi + if [ -n "$MVNW_REPOURL" ]; then + wrapperUrl="$MVNW_REPOURL/org/apache/maven/wrapper/maven-wrapper/3.1.1/maven-wrapper-3.1.1.jar" + else + wrapperUrl="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.1/maven-wrapper-3.1.1.jar" + fi + while IFS="=" read key value; do + case "$key" in (wrapperUrl) wrapperUrl="$value"; break ;; + esac + done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties" + if [ "$MVNW_VERBOSE" = true ]; then + echo "Downloading from: $wrapperUrl" + fi + wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" + if $cygwin; then + wrapperJarPath=`cygpath --path --windows "$wrapperJarPath"` + fi + + if command -v wget > /dev/null; then + QUIET="--quiet" + if [ "$MVNW_VERBOSE" = true ]; then + echo "Found wget ... using wget" + QUIET="" + fi + if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then + wget $QUIET "$wrapperUrl" -O "$wrapperJarPath" + else + wget $QUIET --http-user="$MVNW_USERNAME" --http-password="$MVNW_PASSWORD" "$wrapperUrl" -O "$wrapperJarPath" + fi + [ $? -eq 0 ] || rm -f "$wrapperJarPath" + elif command -v curl > /dev/null; then + QUIET="--silent" + if [ "$MVNW_VERBOSE" = true ]; then + echo "Found curl ... using curl" + QUIET="" + fi + if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then + curl $QUIET -o "$wrapperJarPath" "$wrapperUrl" -f -L + else + curl $QUIET --user "$MVNW_USERNAME:$MVNW_PASSWORD" -o "$wrapperJarPath" "$wrapperUrl" -f -L + fi + [ $? -eq 0 ] || rm -f "$wrapperJarPath" + else + if [ "$MVNW_VERBOSE" = true ]; then + echo "Falling back to using Java to download" + fi + javaSource="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java" + javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" + # For Cygwin, switch paths to Windows format before running javac + if $cygwin; then + javaSource=`cygpath --path --windows "$javaSource"` + javaClass=`cygpath --path --windows "$javaClass"` + fi + if [ -e "$javaSource" ]; then + if [ ! -e "$javaClass" ]; then + if [ "$MVNW_VERBOSE" = true ]; then + echo " - Compiling MavenWrapperDownloader.java ..." + fi + # Compiling the Java class + ("$JAVA_HOME/bin/javac" "$javaSource") + fi + if [ -e "$javaClass" ]; then + # Running the downloader + if [ "$MVNW_VERBOSE" = true ]; then + echo " - Running MavenWrapperDownloader.java ..." + fi + ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR") + fi + fi + fi +fi +########################################################################################## +# End of extension +########################################################################################## + +MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS" + +# For Cygwin, switch paths to Windows format before running java +if $cygwin; then + [ -n "$JAVA_HOME" ] && + JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"` + [ -n "$CLASSPATH" ] && + CLASSPATH=`cygpath --path --windows "$CLASSPATH"` + [ -n "$MAVEN_PROJECTBASEDIR" ] && + MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"` +fi + +# Provide a "standardized" way to retrieve the CLI args that will +# work with both Windows and non-Windows executions. +MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@" +export MAVEN_CMD_LINE_ARGS + +WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain + +exec "$JAVACMD" \ + $MAVEN_OPTS \ + $MAVEN_DEBUG_OPTS \ + -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \ + "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ + ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@" diff --git a/java/ql/integration-tests/all-platforms/java/diagnostics/maven-http-repository/mvnw.cmd b/java/ql/integration-tests/all-platforms/java/diagnostics/maven-http-repository/mvnw.cmd new file mode 100644 index 00000000000..474c9d6b74c --- /dev/null +++ b/java/ql/integration-tests/all-platforms/java/diagnostics/maven-http-repository/mvnw.cmd @@ -0,0 +1,187 @@ +@REM ---------------------------------------------------------------------------- +@REM Licensed to the Apache Software Foundation (ASF) under one +@REM or more contributor license agreements. See the NOTICE file +@REM distributed with this work for additional information +@REM regarding copyright ownership. The ASF licenses this file +@REM to you under the Apache License, Version 2.0 (the +@REM "License"); you may not use this file except in compliance +@REM with the License. You may obtain a copy of the License at +@REM +@REM http://www.apache.org/licenses/LICENSE-2.0 +@REM +@REM Unless required by applicable law or agreed to in writing, +@REM software distributed under the License is distributed on an +@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +@REM KIND, either express or implied. See the License for the +@REM specific language governing permissions and limitations +@REM under the License. +@REM ---------------------------------------------------------------------------- + +@REM ---------------------------------------------------------------------------- +@REM Apache Maven Wrapper startup batch script, version 3.1.1 +@REM +@REM Required ENV vars: +@REM JAVA_HOME - location of a JDK home dir +@REM +@REM Optional ENV vars +@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands +@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a keystroke before ending +@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven +@REM e.g. to debug Maven itself, use +@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 +@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files +@REM ---------------------------------------------------------------------------- + +@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' +@echo off +@REM set title of command window +title %0 +@REM enable echoing by setting MAVEN_BATCH_ECHO to 'on' +@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% + +@REM set %HOME% to equivalent of $HOME +if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") + +@REM Execute a user defined script before this one +if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre +@REM check for pre script, once with legacy .bat ending and once with .cmd ending +if exist "%USERPROFILE%\mavenrc_pre.bat" call "%USERPROFILE%\mavenrc_pre.bat" %* +if exist "%USERPROFILE%\mavenrc_pre.cmd" call "%USERPROFILE%\mavenrc_pre.cmd" %* +:skipRcPre + +@setlocal + +set ERROR_CODE=0 + +@REM To isolate internal variables from possible post scripts, we use another setlocal +@setlocal + +@REM ==== START VALIDATION ==== +if not "%JAVA_HOME%" == "" goto OkJHome + +echo. +echo Error: JAVA_HOME not found in your environment. >&2 +echo Please set the JAVA_HOME variable in your environment to match the >&2 +echo location of your Java installation. >&2 +echo. +goto error + +:OkJHome +if exist "%JAVA_HOME%\bin\java.exe" goto init + +echo. +echo Error: JAVA_HOME is set to an invalid directory. >&2 +echo JAVA_HOME = "%JAVA_HOME%" >&2 +echo Please set the JAVA_HOME variable in your environment to match the >&2 +echo location of your Java installation. >&2 +echo. +goto error + +@REM ==== END VALIDATION ==== + +:init + +@REM Find the project base dir, i.e. the directory that contains the folder ".mvn". +@REM Fallback to current working directory if not found. + +set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% +IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir + +set EXEC_DIR=%CD% +set WDIR=%EXEC_DIR% +:findBaseDir +IF EXIST "%WDIR%"\.mvn goto baseDirFound +cd .. +IF "%WDIR%"=="%CD%" goto baseDirNotFound +set WDIR=%CD% +goto findBaseDir + +:baseDirFound +set MAVEN_PROJECTBASEDIR=%WDIR% +cd "%EXEC_DIR%" +goto endDetectBaseDir + +:baseDirNotFound +set MAVEN_PROJECTBASEDIR=%EXEC_DIR% +cd "%EXEC_DIR%" + +:endDetectBaseDir + +IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig + +@setlocal EnableExtensions EnableDelayedExpansion +for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a +@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% + +:endReadAdditionalConfig + +SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" +set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar" +set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain + +set WRAPPER_URL="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.1/maven-wrapper-3.1.1.jar" + +FOR /F "usebackq tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO ( + IF "%%A"=="wrapperUrl" SET WRAPPER_URL=%%B +) + +@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central +@REM This allows using the maven wrapper in projects that prohibit checking in binary data. +if exist %WRAPPER_JAR% ( + if "%MVNW_VERBOSE%" == "true" ( + echo Found %WRAPPER_JAR% + ) +) else ( + if not "%MVNW_REPOURL%" == "" ( + SET WRAPPER_URL="%MVNW_REPOURL%/org/apache/maven/wrapper/maven-wrapper/3.1.1/maven-wrapper-3.1.1.jar" + ) + if "%MVNW_VERBOSE%" == "true" ( + echo Couldn't find %WRAPPER_JAR%, downloading it ... + echo Downloading from: %WRAPPER_URL% + ) + + powershell -Command "&{"^ + "$webclient = new-object System.Net.WebClient;"^ + "if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^ + "$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^ + "}"^ + "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%WRAPPER_URL%', '%WRAPPER_JAR%')"^ + "}" + if "%MVNW_VERBOSE%" == "true" ( + echo Finished downloading %WRAPPER_JAR% + ) +) +@REM End of extension + +@REM Provide a "standardized" way to retrieve the CLI args that will +@REM work with both Windows and non-Windows executions. +set MAVEN_CMD_LINE_ARGS=%* + +%MAVEN_JAVA_EXE% ^ + %JVM_CONFIG_MAVEN_PROPS% ^ + %MAVEN_OPTS% ^ + %MAVEN_DEBUG_OPTS% ^ + -classpath %WRAPPER_JAR% ^ + "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" ^ + %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %* +if ERRORLEVEL 1 goto error +goto end + +:error +set ERROR_CODE=1 + +:end +@endlocal & set ERROR_CODE=%ERROR_CODE% + +if not "%MAVEN_SKIP_RC%"=="" goto skipRcPost +@REM check for post script, once with legacy .bat ending and once with .cmd ending +if exist "%USERPROFILE%\mavenrc_post.bat" call "%USERPROFILE%\mavenrc_post.bat" +if exist "%USERPROFILE%\mavenrc_post.cmd" call "%USERPROFILE%\mavenrc_post.cmd" +:skipRcPost + +@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' +if "%MAVEN_BATCH_PAUSE%"=="on" pause + +if "%MAVEN_TERMINATE_CMD%"=="on" exit %ERROR_CODE% + +cmd /C exit /B %ERROR_CODE% From 225ed1e220e88114a76d8dbabbd06d5f6697cd40 Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen Date: Wed, 15 Mar 2023 11:10:43 +0100 Subject: [PATCH 260/631] Java: Autoformat. --- java/ql/src/Security/CWE/CWE-190/ArithmeticTainted.ql | 3 ++- java/ql/src/Security/CWE/CWE-190/ArithmeticTaintedLocal.ql | 4 +++- java/ql/src/Security/CWE/CWE-190/ArithmeticUncontrolled.ql | 4 +++- .../src/Security/CWE/CWE-190/ArithmeticWithExtremeValues.ql | 3 ++- .../Security/CWE/CWE-200/TempDirLocalInformationDisclosure.ql | 4 +++- 5 files changed, 13 insertions(+), 5 deletions(-) diff --git a/java/ql/src/Security/CWE/CWE-190/ArithmeticTainted.ql b/java/ql/src/Security/CWE/CWE-190/ArithmeticTainted.ql index 99d9879d19e..c4294e92ef0 100644 --- a/java/ql/src/Security/CWE/CWE-190/ArithmeticTainted.ql +++ b/java/ql/src/Security/CWE/CWE-190/ArithmeticTainted.ql @@ -37,7 +37,8 @@ module RemoteUserInputOverflow = TaintTracking::Make; module Flow = - DataFlow::MergePathGraph; + DataFlow::MergePathGraph; import Flow::PathGraph diff --git a/java/ql/src/Security/CWE/CWE-190/ArithmeticTaintedLocal.ql b/java/ql/src/Security/CWE/CWE-190/ArithmeticTaintedLocal.ql index 5fae695bf56..9fb079ade70 100644 --- a/java/ql/src/Security/CWE/CWE-190/ArithmeticTaintedLocal.ql +++ b/java/ql/src/Security/CWE/CWE-190/ArithmeticTaintedLocal.ql @@ -39,7 +39,9 @@ module ArithmeticTaintedLocalUnderflowFlow = TaintTracking::Make; module Flow = - DataFlow::MergePathGraph; + DataFlow::MergePathGraph; import Flow::PathGraph diff --git a/java/ql/src/Security/CWE/CWE-190/ArithmeticUncontrolled.ql b/java/ql/src/Security/CWE/CWE-190/ArithmeticUncontrolled.ql index 636480f7400..718062a97c7 100644 --- a/java/ql/src/Security/CWE/CWE-190/ArithmeticUncontrolled.ql +++ b/java/ql/src/Security/CWE/CWE-190/ArithmeticUncontrolled.ql @@ -47,7 +47,9 @@ module ArithmeticUncontrolledUnderflowFlow = TaintTracking::Make; module Flow = - DataFlow::MergePathGraph; + DataFlow::MergePathGraph; import Flow::PathGraph diff --git a/java/ql/src/Security/CWE/CWE-190/ArithmeticWithExtremeValues.ql b/java/ql/src/Security/CWE/CWE-190/ArithmeticWithExtremeValues.ql index 72801f205aa..5a32334e691 100644 --- a/java/ql/src/Security/CWE/CWE-190/ArithmeticWithExtremeValues.ql +++ b/java/ql/src/Security/CWE/CWE-190/ArithmeticWithExtremeValues.ql @@ -62,7 +62,8 @@ private module MinValueFlowConfig implements DataFlow::ConfigSig { module MinValueFlow = DataFlow::Make; module Flow = - DataFlow::MergePathGraph; + DataFlow::MergePathGraph; import Flow::PathGraph diff --git a/java/ql/src/Security/CWE/CWE-200/TempDirLocalInformationDisclosure.ql b/java/ql/src/Security/CWE/CWE-200/TempDirLocalInformationDisclosure.ql index 76998b40b50..6d99eba59c2 100644 --- a/java/ql/src/Security/CWE/CWE-200/TempDirLocalInformationDisclosure.ql +++ b/java/ql/src/Security/CWE/CWE-200/TempDirLocalInformationDisclosure.ql @@ -261,7 +261,9 @@ module InsecureMethodPathGraph implements DataFlow::PathGraphSig; + DataFlow::MergePathGraph; import Flow::PathGraph From 56288eb3d2ab69e9094427d8cfef258ce1173be6 Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen Date: Fri, 16 Dec 2022 14:30:34 +0100 Subject: [PATCH 261/631] Java: Misc performance fixes --- java/ql/lib/semmle/code/java/ControlFlowGraph.qll | 2 ++ java/ql/lib/semmle/code/java/dataflow/SSA.qll | 2 ++ .../code/java/dataflow/internal/BaseSSA.qll | 1 + .../java/dataflow/internal/DataFlowImplCommon.qll | 15 ++++++++------- .../java/dataflow/internal/FlowSummaryImpl.qll | 1 + java/ql/lib/semmle/code/java/frameworks/JaxWS.qll | 2 ++ 6 files changed, 16 insertions(+), 7 deletions(-) diff --git a/java/ql/lib/semmle/code/java/ControlFlowGraph.qll b/java/ql/lib/semmle/code/java/ControlFlowGraph.qll index 94464bd263f..f94658e1372 100644 --- a/java/ql/lib/semmle/code/java/ControlFlowGraph.qll +++ b/java/ql/lib/semmle/code/java/ControlFlowGraph.qll @@ -365,6 +365,7 @@ private module ControlFlowGraphImpl { /** * Gets a non-overridable method that always throws an exception or calls `exit`. */ + pragma[assume_small_delta] private Method nonReturningMethod() { result instanceof MethodExit or @@ -381,6 +382,7 @@ private module ControlFlowGraphImpl { /** * Gets a virtual method that always throws an exception or calls `exit`. */ + pragma[assume_small_delta] private EffectivelyNonVirtualMethod likelyNonReturningMethod() { result.getReturnType() instanceof VoidType and not exists(ReturnStmt ret | ret.getEnclosingCallable() = result) and diff --git a/java/ql/lib/semmle/code/java/dataflow/SSA.qll b/java/ql/lib/semmle/code/java/dataflow/SSA.qll index 000d0275819..d4ff7ed0ac7 100644 --- a/java/ql/lib/semmle/code/java/dataflow/SSA.qll +++ b/java/ql/lib/semmle/code/java/dataflow/SSA.qll @@ -451,6 +451,7 @@ private module SsaImpl { * Holds if `f` is live in `b` at index `i`. The rank of `i` is `rankix` as * defined by `callDefUseRank`. */ + pragma[assume_small_delta] private predicate liveAtRank(TrackedField f, BasicBlock b, int rankix, int i) { callDefUseRank(f, b, rankix, i) and ( @@ -564,6 +565,7 @@ private module SsaImpl { } /** Holds if a phi node for `v` is needed at the beginning of basic block `b`. */ + pragma[assume_small_delta] cached predicate phiNode(TrackedVar v, BasicBlock b) { liveAtEntry(v, b) and diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/BaseSSA.qll b/java/ql/lib/semmle/code/java/dataflow/internal/BaseSSA.qll index f44ed438596..6f53dbd02c1 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/BaseSSA.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/BaseSSA.qll @@ -151,6 +151,7 @@ private module SsaImpl { } /** Holds if a phi node for `v` is needed at the beginning of basic block `b`. */ + pragma[assume_small_delta] cached predicate phiNode(BaseSsaSourceVariable v, BasicBlock b) { liveAtEntry(v, b) and 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 d09fdcfca3e..e6fce328326 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImplCommon.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImplCommon.qll @@ -140,10 +140,8 @@ private module LambdaFlow { } pragma[nomagic] - private TReturnPositionSimple viableReturnPosLambda( - DataFlowCall call, DataFlowCallOption lastCall, ReturnKind kind - ) { - result = TReturnPositionSimple0(viableCallableLambda(call, lastCall), kind) + private TReturnPositionSimple viableReturnPosLambda(DataFlowCall call, ReturnKind kind) { + result = TReturnPositionSimple0(viableCallableLambda(call, _), kind) } private predicate viableReturnPosOutNonLambda( @@ -155,11 +153,12 @@ private module LambdaFlow { ) } + pragma[nomagic] private predicate viableReturnPosOutLambda( - DataFlowCall call, DataFlowCallOption lastCall, TReturnPositionSimple pos, OutNode out + DataFlowCall call, TReturnPositionSimple pos, OutNode out ) { exists(ReturnKind kind | - pos = viableReturnPosLambda(call, lastCall, kind) and + pos = viableReturnPosLambda(call, kind) and out = getAnOutNode(call, kind) ) } @@ -188,6 +187,7 @@ private module LambdaFlow { else any() } + pragma[assume_small_delta] pragma[nomagic] predicate revLambdaFlow0( DataFlowCall lambdaCall, LambdaCallKind kind, Node node, DataFlowType t, boolean toReturn, @@ -274,6 +274,7 @@ private module LambdaFlow { ) } + pragma[assume_small_delta] pragma[nomagic] predicate revLambdaFlowOut( DataFlowCall lambdaCall, LambdaCallKind kind, TReturnPositionSimple pos, DataFlowType t, @@ -285,7 +286,7 @@ private module LambdaFlow { or // non-linear recursion revLambdaFlowOutLambdaCall(lambdaCall, kind, out, t, toJump, call, lastCall) and - viableReturnPosOutLambda(call, _, pos, out) + viableReturnPosOutLambda(call, pos, out) ) } diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/FlowSummaryImpl.qll b/java/ql/lib/semmle/code/java/dataflow/internal/FlowSummaryImpl.qll index 478328d90bf..6c718a66068 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/FlowSummaryImpl.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/FlowSummaryImpl.qll @@ -109,6 +109,7 @@ module Public { } /** Gets the stack obtained by dropping the first `i` elements, if any. */ + pragma[assume_small_delta] SummaryComponentStack drop(int i) { i = 0 and result = this or diff --git a/java/ql/lib/semmle/code/java/frameworks/JaxWS.qll b/java/ql/lib/semmle/code/java/frameworks/JaxWS.qll index 54b41f28a08..5c20af2f457 100644 --- a/java/ql/lib/semmle/code/java/frameworks/JaxWS.qll +++ b/java/ql/lib/semmle/code/java/frameworks/JaxWS.qll @@ -53,6 +53,7 @@ private predicate hasPathAnnotation(Annotatable annotatable) { * A method which is annotated with one or more JaxRS resource type annotations e.g. `@GET`, `@POST` etc. */ class JaxRsResourceMethod extends Method { + pragma[assume_small_delta] JaxRsResourceMethod() { exists(AnnotationType a | a = this.getAnAnnotation().getType() and @@ -91,6 +92,7 @@ class JaxRsResourceMethod extends Method { * This class contains resource methods, which are executed in response to requests. */ class JaxRsResourceClass extends Class { + pragma[assume_small_delta] JaxRsResourceClass() { // A root resource class has a @Path annotation on the class. hasPathAnnotation(this) From 0d6dd7d25a0cfe1fa4a7755b5b52fa9352284037 Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen Date: Wed, 15 Mar 2023 11:48:28 +0100 Subject: [PATCH 262/631] DataFlow: Sync. --- .../cpp/dataflow/internal/DataFlowImplCommon.qll | 15 ++++++++------- .../ir/dataflow/internal/DataFlowImplCommon.qll | 15 ++++++++------- .../dataflow/internal/DataFlowImplCommon.qll | 15 ++++++++------- .../csharp/dataflow/internal/FlowSummaryImpl.qll | 1 + .../go/dataflow/internal/DataFlowImplCommon.qll | 15 ++++++++------- .../go/dataflow/internal/FlowSummaryImpl.qll | 1 + .../dataflow/new/internal/DataFlowImplCommon.qll | 15 ++++++++------- .../dataflow/new/internal/FlowSummaryImpl.qll | 1 + .../ruby/dataflow/internal/DataFlowImplCommon.qll | 15 ++++++++------- .../ruby/dataflow/internal/FlowSummaryImpl.qll | 1 + .../dataflow/internal/DataFlowImplCommon.qll | 15 ++++++++------- .../swift/dataflow/internal/FlowSummaryImpl.qll | 1 + 12 files changed, 61 insertions(+), 49 deletions(-) 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 d09fdcfca3e..e6fce328326 100644 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImplCommon.qll +++ b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImplCommon.qll @@ -140,10 +140,8 @@ private module LambdaFlow { } pragma[nomagic] - private TReturnPositionSimple viableReturnPosLambda( - DataFlowCall call, DataFlowCallOption lastCall, ReturnKind kind - ) { - result = TReturnPositionSimple0(viableCallableLambda(call, lastCall), kind) + private TReturnPositionSimple viableReturnPosLambda(DataFlowCall call, ReturnKind kind) { + result = TReturnPositionSimple0(viableCallableLambda(call, _), kind) } private predicate viableReturnPosOutNonLambda( @@ -155,11 +153,12 @@ private module LambdaFlow { ) } + pragma[nomagic] private predicate viableReturnPosOutLambda( - DataFlowCall call, DataFlowCallOption lastCall, TReturnPositionSimple pos, OutNode out + DataFlowCall call, TReturnPositionSimple pos, OutNode out ) { exists(ReturnKind kind | - pos = viableReturnPosLambda(call, lastCall, kind) and + pos = viableReturnPosLambda(call, kind) and out = getAnOutNode(call, kind) ) } @@ -188,6 +187,7 @@ private module LambdaFlow { else any() } + pragma[assume_small_delta] pragma[nomagic] predicate revLambdaFlow0( DataFlowCall lambdaCall, LambdaCallKind kind, Node node, DataFlowType t, boolean toReturn, @@ -274,6 +274,7 @@ private module LambdaFlow { ) } + pragma[assume_small_delta] pragma[nomagic] predicate revLambdaFlowOut( DataFlowCall lambdaCall, LambdaCallKind kind, TReturnPositionSimple pos, DataFlowType t, @@ -285,7 +286,7 @@ private module LambdaFlow { or // non-linear recursion revLambdaFlowOutLambdaCall(lambdaCall, kind, out, t, toJump, call, lastCall) and - viableReturnPosOutLambda(call, _, pos, out) + viableReturnPosOutLambda(call, pos, out) ) } 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 d09fdcfca3e..e6fce328326 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 @@ -140,10 +140,8 @@ private module LambdaFlow { } pragma[nomagic] - private TReturnPositionSimple viableReturnPosLambda( - DataFlowCall call, DataFlowCallOption lastCall, ReturnKind kind - ) { - result = TReturnPositionSimple0(viableCallableLambda(call, lastCall), kind) + private TReturnPositionSimple viableReturnPosLambda(DataFlowCall call, ReturnKind kind) { + result = TReturnPositionSimple0(viableCallableLambda(call, _), kind) } private predicate viableReturnPosOutNonLambda( @@ -155,11 +153,12 @@ private module LambdaFlow { ) } + pragma[nomagic] private predicate viableReturnPosOutLambda( - DataFlowCall call, DataFlowCallOption lastCall, TReturnPositionSimple pos, OutNode out + DataFlowCall call, TReturnPositionSimple pos, OutNode out ) { exists(ReturnKind kind | - pos = viableReturnPosLambda(call, lastCall, kind) and + pos = viableReturnPosLambda(call, kind) and out = getAnOutNode(call, kind) ) } @@ -188,6 +187,7 @@ private module LambdaFlow { else any() } + pragma[assume_small_delta] pragma[nomagic] predicate revLambdaFlow0( DataFlowCall lambdaCall, LambdaCallKind kind, Node node, DataFlowType t, boolean toReturn, @@ -274,6 +274,7 @@ private module LambdaFlow { ) } + pragma[assume_small_delta] pragma[nomagic] predicate revLambdaFlowOut( DataFlowCall lambdaCall, LambdaCallKind kind, TReturnPositionSimple pos, DataFlowType t, @@ -285,7 +286,7 @@ private module LambdaFlow { or // non-linear recursion revLambdaFlowOutLambdaCall(lambdaCall, kind, out, t, toJump, call, lastCall) and - viableReturnPosOutLambda(call, _, pos, out) + viableReturnPosOutLambda(call, pos, out) ) } 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 d09fdcfca3e..e6fce328326 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImplCommon.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImplCommon.qll @@ -140,10 +140,8 @@ private module LambdaFlow { } pragma[nomagic] - private TReturnPositionSimple viableReturnPosLambda( - DataFlowCall call, DataFlowCallOption lastCall, ReturnKind kind - ) { - result = TReturnPositionSimple0(viableCallableLambda(call, lastCall), kind) + private TReturnPositionSimple viableReturnPosLambda(DataFlowCall call, ReturnKind kind) { + result = TReturnPositionSimple0(viableCallableLambda(call, _), kind) } private predicate viableReturnPosOutNonLambda( @@ -155,11 +153,12 @@ private module LambdaFlow { ) } + pragma[nomagic] private predicate viableReturnPosOutLambda( - DataFlowCall call, DataFlowCallOption lastCall, TReturnPositionSimple pos, OutNode out + DataFlowCall call, TReturnPositionSimple pos, OutNode out ) { exists(ReturnKind kind | - pos = viableReturnPosLambda(call, lastCall, kind) and + pos = viableReturnPosLambda(call, kind) and out = getAnOutNode(call, kind) ) } @@ -188,6 +187,7 @@ private module LambdaFlow { else any() } + pragma[assume_small_delta] pragma[nomagic] predicate revLambdaFlow0( DataFlowCall lambdaCall, LambdaCallKind kind, Node node, DataFlowType t, boolean toReturn, @@ -274,6 +274,7 @@ private module LambdaFlow { ) } + pragma[assume_small_delta] pragma[nomagic] predicate revLambdaFlowOut( DataFlowCall lambdaCall, LambdaCallKind kind, TReturnPositionSimple pos, DataFlowType t, @@ -285,7 +286,7 @@ private module LambdaFlow { or // non-linear recursion revLambdaFlowOutLambdaCall(lambdaCall, kind, out, t, toJump, call, lastCall) and - viableReturnPosOutLambda(call, _, pos, out) + viableReturnPosOutLambda(call, pos, out) ) } diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/FlowSummaryImpl.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/FlowSummaryImpl.qll index 478328d90bf..6c718a66068 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/FlowSummaryImpl.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/FlowSummaryImpl.qll @@ -109,6 +109,7 @@ module Public { } /** Gets the stack obtained by dropping the first `i` elements, if any. */ + pragma[assume_small_delta] SummaryComponentStack drop(int i) { i = 0 and result = this or diff --git a/go/ql/lib/semmle/go/dataflow/internal/DataFlowImplCommon.qll b/go/ql/lib/semmle/go/dataflow/internal/DataFlowImplCommon.qll index d09fdcfca3e..e6fce328326 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/DataFlowImplCommon.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/DataFlowImplCommon.qll @@ -140,10 +140,8 @@ private module LambdaFlow { } pragma[nomagic] - private TReturnPositionSimple viableReturnPosLambda( - DataFlowCall call, DataFlowCallOption lastCall, ReturnKind kind - ) { - result = TReturnPositionSimple0(viableCallableLambda(call, lastCall), kind) + private TReturnPositionSimple viableReturnPosLambda(DataFlowCall call, ReturnKind kind) { + result = TReturnPositionSimple0(viableCallableLambda(call, _), kind) } private predicate viableReturnPosOutNonLambda( @@ -155,11 +153,12 @@ private module LambdaFlow { ) } + pragma[nomagic] private predicate viableReturnPosOutLambda( - DataFlowCall call, DataFlowCallOption lastCall, TReturnPositionSimple pos, OutNode out + DataFlowCall call, TReturnPositionSimple pos, OutNode out ) { exists(ReturnKind kind | - pos = viableReturnPosLambda(call, lastCall, kind) and + pos = viableReturnPosLambda(call, kind) and out = getAnOutNode(call, kind) ) } @@ -188,6 +187,7 @@ private module LambdaFlow { else any() } + pragma[assume_small_delta] pragma[nomagic] predicate revLambdaFlow0( DataFlowCall lambdaCall, LambdaCallKind kind, Node node, DataFlowType t, boolean toReturn, @@ -274,6 +274,7 @@ private module LambdaFlow { ) } + pragma[assume_small_delta] pragma[nomagic] predicate revLambdaFlowOut( DataFlowCall lambdaCall, LambdaCallKind kind, TReturnPositionSimple pos, DataFlowType t, @@ -285,7 +286,7 @@ private module LambdaFlow { or // non-linear recursion revLambdaFlowOutLambdaCall(lambdaCall, kind, out, t, toJump, call, lastCall) and - viableReturnPosOutLambda(call, _, pos, out) + viableReturnPosOutLambda(call, pos, out) ) } diff --git a/go/ql/lib/semmle/go/dataflow/internal/FlowSummaryImpl.qll b/go/ql/lib/semmle/go/dataflow/internal/FlowSummaryImpl.qll index 478328d90bf..6c718a66068 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/FlowSummaryImpl.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/FlowSummaryImpl.qll @@ -109,6 +109,7 @@ module Public { } /** Gets the stack obtained by dropping the first `i` elements, if any. */ + pragma[assume_small_delta] SummaryComponentStack drop(int i) { i = 0 and result = this or 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 d09fdcfca3e..e6fce328326 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImplCommon.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImplCommon.qll @@ -140,10 +140,8 @@ private module LambdaFlow { } pragma[nomagic] - private TReturnPositionSimple viableReturnPosLambda( - DataFlowCall call, DataFlowCallOption lastCall, ReturnKind kind - ) { - result = TReturnPositionSimple0(viableCallableLambda(call, lastCall), kind) + private TReturnPositionSimple viableReturnPosLambda(DataFlowCall call, ReturnKind kind) { + result = TReturnPositionSimple0(viableCallableLambda(call, _), kind) } private predicate viableReturnPosOutNonLambda( @@ -155,11 +153,12 @@ private module LambdaFlow { ) } + pragma[nomagic] private predicate viableReturnPosOutLambda( - DataFlowCall call, DataFlowCallOption lastCall, TReturnPositionSimple pos, OutNode out + DataFlowCall call, TReturnPositionSimple pos, OutNode out ) { exists(ReturnKind kind | - pos = viableReturnPosLambda(call, lastCall, kind) and + pos = viableReturnPosLambda(call, kind) and out = getAnOutNode(call, kind) ) } @@ -188,6 +187,7 @@ private module LambdaFlow { else any() } + pragma[assume_small_delta] pragma[nomagic] predicate revLambdaFlow0( DataFlowCall lambdaCall, LambdaCallKind kind, Node node, DataFlowType t, boolean toReturn, @@ -274,6 +274,7 @@ private module LambdaFlow { ) } + pragma[assume_small_delta] pragma[nomagic] predicate revLambdaFlowOut( DataFlowCall lambdaCall, LambdaCallKind kind, TReturnPositionSimple pos, DataFlowType t, @@ -285,7 +286,7 @@ private module LambdaFlow { or // non-linear recursion revLambdaFlowOutLambdaCall(lambdaCall, kind, out, t, toJump, call, lastCall) and - viableReturnPosOutLambda(call, _, pos, out) + viableReturnPosOutLambda(call, pos, out) ) } diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/FlowSummaryImpl.qll b/python/ql/lib/semmle/python/dataflow/new/internal/FlowSummaryImpl.qll index 478328d90bf..6c718a66068 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/FlowSummaryImpl.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/FlowSummaryImpl.qll @@ -109,6 +109,7 @@ module Public { } /** Gets the stack obtained by dropping the first `i` elements, if any. */ + pragma[assume_small_delta] SummaryComponentStack drop(int i) { i = 0 and result = this or diff --git a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImplCommon.qll b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImplCommon.qll index d09fdcfca3e..e6fce328326 100644 --- a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImplCommon.qll +++ b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImplCommon.qll @@ -140,10 +140,8 @@ private module LambdaFlow { } pragma[nomagic] - private TReturnPositionSimple viableReturnPosLambda( - DataFlowCall call, DataFlowCallOption lastCall, ReturnKind kind - ) { - result = TReturnPositionSimple0(viableCallableLambda(call, lastCall), kind) + private TReturnPositionSimple viableReturnPosLambda(DataFlowCall call, ReturnKind kind) { + result = TReturnPositionSimple0(viableCallableLambda(call, _), kind) } private predicate viableReturnPosOutNonLambda( @@ -155,11 +153,12 @@ private module LambdaFlow { ) } + pragma[nomagic] private predicate viableReturnPosOutLambda( - DataFlowCall call, DataFlowCallOption lastCall, TReturnPositionSimple pos, OutNode out + DataFlowCall call, TReturnPositionSimple pos, OutNode out ) { exists(ReturnKind kind | - pos = viableReturnPosLambda(call, lastCall, kind) and + pos = viableReturnPosLambda(call, kind) and out = getAnOutNode(call, kind) ) } @@ -188,6 +187,7 @@ private module LambdaFlow { else any() } + pragma[assume_small_delta] pragma[nomagic] predicate revLambdaFlow0( DataFlowCall lambdaCall, LambdaCallKind kind, Node node, DataFlowType t, boolean toReturn, @@ -274,6 +274,7 @@ private module LambdaFlow { ) } + pragma[assume_small_delta] pragma[nomagic] predicate revLambdaFlowOut( DataFlowCall lambdaCall, LambdaCallKind kind, TReturnPositionSimple pos, DataFlowType t, @@ -285,7 +286,7 @@ private module LambdaFlow { or // non-linear recursion revLambdaFlowOutLambdaCall(lambdaCall, kind, out, t, toJump, call, lastCall) and - viableReturnPosOutLambda(call, _, pos, out) + viableReturnPosOutLambda(call, pos, out) ) } diff --git a/ruby/ql/lib/codeql/ruby/dataflow/internal/FlowSummaryImpl.qll b/ruby/ql/lib/codeql/ruby/dataflow/internal/FlowSummaryImpl.qll index 478328d90bf..6c718a66068 100644 --- a/ruby/ql/lib/codeql/ruby/dataflow/internal/FlowSummaryImpl.qll +++ b/ruby/ql/lib/codeql/ruby/dataflow/internal/FlowSummaryImpl.qll @@ -109,6 +109,7 @@ module Public { } /** Gets the stack obtained by dropping the first `i` elements, if any. */ + pragma[assume_small_delta] SummaryComponentStack drop(int i) { i = 0 and result = this or diff --git a/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowImplCommon.qll b/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowImplCommon.qll index d09fdcfca3e..e6fce328326 100644 --- a/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowImplCommon.qll +++ b/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowImplCommon.qll @@ -140,10 +140,8 @@ private module LambdaFlow { } pragma[nomagic] - private TReturnPositionSimple viableReturnPosLambda( - DataFlowCall call, DataFlowCallOption lastCall, ReturnKind kind - ) { - result = TReturnPositionSimple0(viableCallableLambda(call, lastCall), kind) + private TReturnPositionSimple viableReturnPosLambda(DataFlowCall call, ReturnKind kind) { + result = TReturnPositionSimple0(viableCallableLambda(call, _), kind) } private predicate viableReturnPosOutNonLambda( @@ -155,11 +153,12 @@ private module LambdaFlow { ) } + pragma[nomagic] private predicate viableReturnPosOutLambda( - DataFlowCall call, DataFlowCallOption lastCall, TReturnPositionSimple pos, OutNode out + DataFlowCall call, TReturnPositionSimple pos, OutNode out ) { exists(ReturnKind kind | - pos = viableReturnPosLambda(call, lastCall, kind) and + pos = viableReturnPosLambda(call, kind) and out = getAnOutNode(call, kind) ) } @@ -188,6 +187,7 @@ private module LambdaFlow { else any() } + pragma[assume_small_delta] pragma[nomagic] predicate revLambdaFlow0( DataFlowCall lambdaCall, LambdaCallKind kind, Node node, DataFlowType t, boolean toReturn, @@ -274,6 +274,7 @@ private module LambdaFlow { ) } + pragma[assume_small_delta] pragma[nomagic] predicate revLambdaFlowOut( DataFlowCall lambdaCall, LambdaCallKind kind, TReturnPositionSimple pos, DataFlowType t, @@ -285,7 +286,7 @@ private module LambdaFlow { or // non-linear recursion revLambdaFlowOutLambdaCall(lambdaCall, kind, out, t, toJump, call, lastCall) and - viableReturnPosOutLambda(call, _, pos, out) + viableReturnPosOutLambda(call, pos, out) ) } diff --git a/swift/ql/lib/codeql/swift/dataflow/internal/FlowSummaryImpl.qll b/swift/ql/lib/codeql/swift/dataflow/internal/FlowSummaryImpl.qll index 478328d90bf..6c718a66068 100644 --- a/swift/ql/lib/codeql/swift/dataflow/internal/FlowSummaryImpl.qll +++ b/swift/ql/lib/codeql/swift/dataflow/internal/FlowSummaryImpl.qll @@ -109,6 +109,7 @@ module Public { } /** Gets the stack obtained by dropping the first `i` elements, if any. */ + pragma[assume_small_delta] SummaryComponentStack drop(int i) { i = 0 and result = this or From 89d9d65755faeba01c3570417c4942b8626f95bd Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen Date: Tue, 21 Mar 2023 14:45:29 +0100 Subject: [PATCH 263/631] Java/C#: Remove useless disjuncts. --- .../dataflow/internal/rangeanalysis/SignAnalysisCommon.qll | 4 ---- .../dataflow/internal/rangeanalysis/SignAnalysisCommon.qll | 4 ---- 2 files changed, 8 deletions(-) diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/rangeanalysis/SignAnalysisCommon.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/rangeanalysis/SignAnalysisCommon.qll index e44cd40d872..6f0067517f9 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/rangeanalysis/SignAnalysisCommon.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/rangeanalysis/SignAnalysisCommon.qll @@ -45,10 +45,6 @@ private Sign certainExprSign(Expr e) { private predicate unknownSign(Expr e) { not exists(certainExprSign(e)) and ( - exists(IntegerLiteral lit | lit = e and not exists(lit.getValue().toInt())) - or - exists(LongLiteral lit | lit = e and not exists(lit.getValue().toFloat())) - or exists(CastingExpr cast, Type fromtyp | cast = e and fromtyp = cast.getSourceType() and diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/rangeanalysis/SignAnalysisCommon.qll b/java/ql/lib/semmle/code/java/dataflow/internal/rangeanalysis/SignAnalysisCommon.qll index e44cd40d872..6f0067517f9 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/rangeanalysis/SignAnalysisCommon.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/rangeanalysis/SignAnalysisCommon.qll @@ -45,10 +45,6 @@ private Sign certainExprSign(Expr e) { private predicate unknownSign(Expr e) { not exists(certainExprSign(e)) and ( - exists(IntegerLiteral lit | lit = e and not exists(lit.getValue().toInt())) - or - exists(LongLiteral lit | lit = e and not exists(lit.getValue().toFloat())) - or exists(CastingExpr cast, Type fromtyp | cast = e and fromtyp = cast.getSourceType() and From 34fe1a8f5e3ef8fbe564a370786e8ace3c7a06fc Mon Sep 17 00:00:00 2001 From: erik-krogh Date: Mon, 6 Feb 2023 16:14:24 +0100 Subject: [PATCH 264/631] use SSA in the GetLaterAccess module --- .../semmle/javascript/GlobalAccessPaths.qll | 31 ++++++++++++------- .../UnsafeCodeConstruction.expected | 8 +++++ 2 files changed, 28 insertions(+), 11 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/GlobalAccessPaths.qll b/javascript/ql/lib/semmle/javascript/GlobalAccessPaths.qll index dc28e44ecdd..01ce360f3b5 100644 --- a/javascript/ql/lib/semmle/javascript/GlobalAccessPaths.qll +++ b/javascript/ql/lib/semmle/javascript/GlobalAccessPaths.qll @@ -270,6 +270,16 @@ module AccessPath { /** A module for computing an access to a variable that happens after a property has been written onto it */ private module GetLaterAccess { + /** + * Gets an reference to the SSA variable `variable`. + * Either the definition or a use of the SSA variable + */ + private VarRef getAVariableRef(SsaVariable variable) { + result = variable.getAUse() + or + result = variable.getDefinition().(SsaExplicitDefinition).getDef().getTarget() + } + /** * Gets an access to a variable that is written to in `write`, where the access is after the write. * @@ -286,7 +296,7 @@ module AccessPath { pragma[noopt] DataFlow::Node getLaterBaseAccess(DataFlow::PropWrite write) { exists( - ControlFlowNode writeNode, BindingPattern access, VarRef otherAccess, Variable variable, + ControlFlowNode writeNode, BindingPattern access, VarRef otherAccess, SsaVariable variable, StmtContainer container | access = getBaseVar(write) and @@ -323,24 +333,23 @@ module AccessPath { } /** Gets an access to `var` inside `container` where `usedInWrite` indicates whether the access is the base of a property write. */ - private VarRef getAnAccessInContainer(Variable var, StmtContainer container, boolean usedInWrite) { - result.getVariable() = var and + private VarRef getAnAccessInContainer( + SsaVariable var, StmtContainer container, boolean usedInWrite + ) { + result = getAVariableRef(var) and result.getContainer() = container and - var.isLocal() and if result = getBaseVar(_) then usedInWrite = true else usedInWrite = false } /** Gets a variable that is relevant for the computations in the `GetLaterAccess` module. */ - private Variable getARelevantVariable() { + private SsaVariable getARelevantVariable() { // The variable might be used where `getLaterBaseAccess()` is called. exists(DataFlow::Node node | exists(fromRhs(node, _)) and - node.asExpr().(VarAccess).getVariable() = result + node.asExpr() = getAVariableRef(result) ) and // There is a write that writes to the variable. - getBaseVar(_).getVariable() = result and - // It's local. - result.isLocal() and // we skip global variables, because that turns messy quick. + getBaseVar(_) = getAVariableRef(result) and // There is both a "write" and "read" in the same container of the variable. exists(StmtContainer container | exists(getAnAccessInContainer(result, container, true)) and // a "write", an access to the variable that is the base of a property reference. @@ -350,9 +359,9 @@ module AccessPath { /** Gets a basic-block that has a read of the variable that is written to by `write`, where the basicblock occurs after `start`. */ private ReachableBasicBlock getASuccessorBBThatReadsVar(DataFlow::PropWrite write) { - exists(VarAccess baseExpr, Variable var, ControlFlowNode writeNode | + exists(VarRef baseExpr, SsaVariable var, ControlFlowNode writeNode | baseExpr = getBaseVar(write) and - var = baseExpr.getVariable() and + getAVariableRef(var) = baseExpr and var = getARelevantVariable() and writeNode = write.getWriteNode() and writeNode.getBasicBlock().(ReachableBasicBlock).strictlyDominates(result) and diff --git a/javascript/ql/test/query-tests/Security/CWE-094/CodeInjection/UnsafeCodeConstruction.expected b/javascript/ql/test/query-tests/Security/CWE-094/CodeInjection/UnsafeCodeConstruction.expected index 14733b4274d..725c600ecaa 100644 --- a/javascript/ql/test/query-tests/Security/CWE-094/CodeInjection/UnsafeCodeConstruction.expected +++ b/javascript/ql/test/query-tests/Security/CWE-094/CodeInjection/UnsafeCodeConstruction.expected @@ -42,8 +42,11 @@ nodes | lib/index.js:112:17:112:21 | taint | | lib/index.js:112:17:112:21 | taint | | lib/index.js:113:20:113:24 | taint | +| lib/index.js:115:38:115:42 | taint | | lib/index.js:121:34:121:38 | taint | | lib/index.js:129:32:129:36 | taint | +| lib/index.js:135:23:135:49 | this.op ... dOption | +| lib/index.js:135:23:135:49 | this.op ... dOption | | lib/index.js:136:23:136:49 | this.op ... dOption | | lib/index.js:136:23:136:49 | this.op ... dOption | | lib/index.js:137:23:137:49 | this.op ... dOption | @@ -94,12 +97,16 @@ edges | lib/index.js:98:30:98:34 | taint | lib/index.js:105:21:105:47 | this.op ... dOption | | lib/index.js:112:17:112:21 | taint | lib/index.js:113:20:113:24 | taint | | lib/index.js:112:17:112:21 | taint | lib/index.js:113:20:113:24 | taint | +| lib/index.js:112:17:112:21 | taint | lib/index.js:115:38:115:42 | taint | +| lib/index.js:112:17:112:21 | taint | lib/index.js:115:38:115:42 | taint | | lib/index.js:112:17:112:21 | taint | lib/index.js:121:34:121:38 | taint | | lib/index.js:112:17:112:21 | taint | lib/index.js:121:34:121:38 | taint | | lib/index.js:112:17:112:21 | taint | lib/index.js:129:32:129:36 | taint | | lib/index.js:112:17:112:21 | taint | lib/index.js:129:32:129:36 | taint | | lib/index.js:113:20:113:24 | taint | lib/index.js:138:23:138:32 | this.taint | | lib/index.js:113:20:113:24 | taint | lib/index.js:138:23:138:32 | this.taint | +| lib/index.js:115:38:115:42 | taint | lib/index.js:135:23:135:49 | this.op ... dOption | +| lib/index.js:115:38:115:42 | taint | lib/index.js:135:23:135:49 | this.op ... dOption | | lib/index.js:121:34:121:38 | taint | lib/index.js:136:23:136:49 | this.op ... dOption | | lib/index.js:121:34:121:38 | taint | lib/index.js:136:23:136:49 | this.op ... dOption | | lib/index.js:129:32:129:36 | taint | lib/index.js:137:23:137:49 | this.op ... dOption | @@ -114,6 +121,7 @@ edges | lib/index.js:104:21:104:47 | this.op ... dOption | lib/index.js:86:15:86:19 | taint | lib/index.js:104:21:104:47 | this.op ... dOption | This string concatenation which depends on $@ is later $@. | lib/index.js:86:15:86:19 | taint | library input | lib/index.js:104:10:104:67 | " var ... ing();" | interpreted as code | | lib/index.js:105:21:105:47 | this.op ... dOption | lib/index.js:86:15:86:19 | taint | lib/index.js:105:21:105:47 | this.op ... dOption | This string concatenation which depends on $@ is later $@. | lib/index.js:86:15:86:19 | taint | library input | lib/index.js:105:10:105:67 | " var ... ing();" | interpreted as code | | lib/index.js:106:21:106:30 | this.taint | lib/index.js:86:15:86:19 | taint | lib/index.js:106:21:106:30 | this.taint | This string concatenation which depends on $@ is later $@. | lib/index.js:86:15:86:19 | taint | library input | lib/index.js:106:10:106:50 | " var ... ing();" | interpreted as code | +| lib/index.js:135:23:135:49 | this.op ... dOption | lib/index.js:112:17:112:21 | taint | lib/index.js:135:23:135:49 | this.op ... dOption | This string concatenation which depends on $@ is later $@. | lib/index.js:112:17:112:21 | taint | library input | lib/index.js:135:12:135:69 | " var ... ing();" | interpreted as code | | lib/index.js:136:23:136:49 | this.op ... dOption | lib/index.js:112:17:112:21 | taint | lib/index.js:136:23:136:49 | this.op ... dOption | This string concatenation which depends on $@ is later $@. | lib/index.js:112:17:112:21 | taint | library input | lib/index.js:136:12:136:69 | " var ... ing();" | interpreted as code | | lib/index.js:137:23:137:49 | this.op ... dOption | lib/index.js:112:17:112:21 | taint | lib/index.js:137:23:137:49 | this.op ... dOption | This string concatenation which depends on $@ is later $@. | lib/index.js:112:17:112:21 | taint | library input | lib/index.js:137:12:137:69 | " var ... ing();" | interpreted as code | | lib/index.js:138:23:138:32 | this.taint | lib/index.js:112:17:112:21 | taint | lib/index.js:138:23:138:32 | this.taint | This string concatenation which depends on $@ is later $@. | lib/index.js:112:17:112:21 | taint | library input | lib/index.js:138:12:138:52 | " var ... ing();" | interpreted as code | From 070468ab6824245a820dde290fd21bb30da11020 Mon Sep 17 00:00:00 2001 From: erik-krogh Date: Mon, 20 Mar 2023 12:03:32 +0100 Subject: [PATCH 265/631] fix performance --- .../semmle/javascript/GlobalAccessPaths.qll | 30 ++++++++++++++----- 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/GlobalAccessPaths.qll b/javascript/ql/lib/semmle/javascript/GlobalAccessPaths.qll index 01ce360f3b5..8197ef276ec 100644 --- a/javascript/ql/lib/semmle/javascript/GlobalAccessPaths.qll +++ b/javascript/ql/lib/semmle/javascript/GlobalAccessPaths.qll @@ -275,9 +275,12 @@ module AccessPath { * Either the definition or a use of the SSA variable */ private VarRef getAVariableRef(SsaVariable variable) { - result = variable.getAUse() - or - result = variable.getDefinition().(SsaExplicitDefinition).getDef().getTarget() + ( + result = variable.getAUse() + or + result = variable.getDefinition().(SsaExplicitDefinition).getDef().getTarget() + ) and + variable = getARelevantVariableSimple() } /** @@ -341,13 +344,24 @@ module AccessPath { if result = getBaseVar(_) then usedInWrite = true else usedInWrite = false } - /** Gets a variable that is relevant for the computations in the `GetLaterAccess` module. */ - private SsaVariable getARelevantVariable() { + /** + * Gets a variable that is relevant for the computations in the `GetLaterAccess` module. + * This predicate restricts as much as it can, but without depending on `getAVariableRef`. + */ + pragma[inline] + private SsaVariable getARelevantVariableSimple() { // The variable might be used where `getLaterBaseAccess()` is called. exists(DataFlow::Node node | exists(fromRhs(node, _)) and - node.asExpr() = getAVariableRef(result) - ) and + node.asExpr() = result.getAUse() + ) + } + + /** + * Gets a variable that is relevant for the computations in the `GetLaterAccess` module. + * This predicate depends on `getAVariableRef`, which in turn depends on `getARelevantVariableSimple`. + */ + private SsaVariable getARelevantVariable() { // There is a write that writes to the variable. getBaseVar(_) = getAVariableRef(result) and // There is both a "write" and "read" in the same container of the variable. @@ -364,7 +378,7 @@ module AccessPath { getAVariableRef(var) = baseExpr and var = getARelevantVariable() and writeNode = write.getWriteNode() and - writeNode.getBasicBlock().(ReachableBasicBlock).strictlyDominates(result) and + result.getImmediateDominator+() = writeNode.getBasicBlock() and // manual magic. result = getAnAccessInContainer(getARelevantVariable(), _, false).getBasicBlock() ) From c023af7308931792cd2e871dbf80f570c5f28205 Mon Sep 17 00:00:00 2001 From: erik-krogh Date: Tue, 21 Mar 2023 11:43:25 +0100 Subject: [PATCH 266/631] manual recursion, and other join-order --- javascript/ql/lib/semmle/javascript/GlobalAccessPaths.qll | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/GlobalAccessPaths.qll b/javascript/ql/lib/semmle/javascript/GlobalAccessPaths.qll index 8197ef276ec..bf17def1cfa 100644 --- a/javascript/ql/lib/semmle/javascript/GlobalAccessPaths.qll +++ b/javascript/ql/lib/semmle/javascript/GlobalAccessPaths.qll @@ -316,7 +316,7 @@ module AccessPath { i < j ) or - otherAccess.getBasicBlock() = getASuccessorBBThatReadsVar(write) // more manual magic - outlined into a helper predicate. + otherAccess.getBasicBlock() = getASuccessorBBThatReadsVar(write) ) } @@ -378,10 +378,10 @@ module AccessPath { getAVariableRef(var) = baseExpr and var = getARelevantVariable() and writeNode = write.getWriteNode() and - result.getImmediateDominator+() = writeNode.getBasicBlock() and - // manual magic. - result = getAnAccessInContainer(getARelevantVariable(), _, false).getBasicBlock() + result.getImmediateDominator() = writeNode.getBasicBlock() ) + or + result.getImmediateDominator() = getASuccessorBBThatReadsVar(write) // more manual magic - outlined into a helper predicate. } } From 8b4826c0b4028ba1f063065ffc65581211be31b6 Mon Sep 17 00:00:00 2001 From: Raul Garcia Date: Tue, 21 Mar 2023 08:02:30 -0700 Subject: [PATCH 267/631] Singleton set literal fix Fixing auto-code scanning recommendation --- .../CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/ql/src/experimental/Security/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql b/python/ql/src/experimental/Security/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql index 3eac4385391..556132e5c64 100644 --- a/python/ql/src/experimental/Security/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql +++ b/python/ql/src/experimental/Security/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql @@ -25,7 +25,7 @@ predicate isUnsafeClientSideAzureStorageEncryptionViaAttributes(Call call, AttrN | s1 in ["key_encryption_key", "key_resolver_function"] and s2 in ["ContainerClient", "BlobClient", "BlobServiceClient"] and - s3 in ["upload_blob"] and + s3 = "upload_blob" and n = API::moduleImport("azure").getMember("storage").getMember("blob").getMember(s2).getAMember() and startingNode = n.getACall().getReturn().getAValueReachableFromSource().asExpr().getAFlowNode() and startingNode.strictlyReaches(ctrlFlowNode) and From 29f78624661f3a22baa867f4caca0bfa89d75089 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Tue, 21 Mar 2023 14:56:10 +0000 Subject: [PATCH 268/631] Swift: Add a test for getFullName. --- .../abstractfunctiondecl.expected | 15 ++++++++------- .../abstractfunctiondecl/abstractfunctiondecl.ql | 4 ++++ .../abstractfunctiondecl.swift | 7 +++++++ 3 files changed, 19 insertions(+), 7 deletions(-) diff --git a/swift/ql/test/library-tests/elements/decl/abstractfunctiondecl/abstractfunctiondecl.expected b/swift/ql/test/library-tests/elements/decl/abstractfunctiondecl/abstractfunctiondecl.expected index 649de8dd622..d8723c0068e 100644 --- a/swift/ql/test/library-tests/elements/decl/abstractfunctiondecl/abstractfunctiondecl.expected +++ b/swift/ql/test/library-tests/elements/decl/abstractfunctiondecl/abstractfunctiondecl.expected @@ -1,8 +1,9 @@ | abstractfunctiondecl.swift:2:1:2:15 | func1() | getName:func1(), hasName:func1() | -| abstractfunctiondecl.swift:5:2:5:16 | func2() | MethodDecl, getName:func2(), hasName:func2(), hasQualifiedName(2):Class1.func2(), hasQualifiedName(3):abstractfunctiondecl.Class1.func2() | -| abstractfunctiondecl.swift:8:3:8:17 | func3() | MethodDecl, getName:func3(), hasName:func3(), hasQualifiedName(2):Class1.Class2.func3(), hasQualifiedName(3):abstractfunctiondecl.Class1.Class2.func3() | -| abstractfunctiondecl.swift:13:2:13:13 | func4() | MethodDecl, getName:func4(), hasName:func4(), hasQualifiedName(2):Protocol1.func4(), hasQualifiedName(3):abstractfunctiondecl.Protocol1.func4() | -| abstractfunctiondecl.swift:17:2:17:16 | func4() | MethodDecl, getName:func4(), hasName:func4(), hasQualifiedName(2):Class3.func4(), hasQualifiedName(3):abstractfunctiondecl.Class3.func4() | -| abstractfunctiondecl.swift:21:2:21:16 | func5() | MethodDecl, getName:func5(), hasName:func5(), hasQualifiedName(2):Class3.func5(), hasQualifiedName(3):abstractfunctiondecl.Class3.func5() | -| abstractfunctiondecl.swift:25:2:25:16 | func6() | MethodDecl, getName:func6(), hasName:func6(), hasQualifiedName(2):Struct1.func6(), hasQualifiedName(3):abstractfunctiondecl.Struct1.func6() | -| abstractfunctiondecl.swift:31:2:31:16 | func7() | MethodDecl, getName:func7(), hasName:func7(), hasQualifiedName(2):Enum1.func7(), hasQualifiedName(3):abstractfunctiondecl.Enum1.func7() | +| abstractfunctiondecl.swift:5:2:5:16 | func2() | MethodDecl, getName:func2(), hasName:func2(), hasQualifiedName(2):Class1.func2(), hasQualifiedName(3):abstractfunctiondecl.Class1.func2(), memberOf:Class1 | +| abstractfunctiondecl.swift:8:3:8:17 | func3() | MethodDecl, getName:func3(), hasName:func3(), hasQualifiedName(2):Class1.Class2.func3(), hasQualifiedName(3):abstractfunctiondecl.Class1.Class2.func3(), memberOf:Class1.Class2 | +| abstractfunctiondecl.swift:13:2:13:13 | func4() | MethodDecl, getName:func4(), hasName:func4(), hasQualifiedName(2):Protocol1.func4(), hasQualifiedName(3):abstractfunctiondecl.Protocol1.func4(), memberOf:Protocol1 | +| abstractfunctiondecl.swift:17:2:17:16 | func4() | MethodDecl, getName:func4(), hasName:func4(), hasQualifiedName(2):Class3.func4(), hasQualifiedName(3):abstractfunctiondecl.Class3.func4(), memberOf:Class3 | +| abstractfunctiondecl.swift:21:2:21:16 | func5() | MethodDecl, getName:func5(), hasName:func5(), hasQualifiedName(2):Class3.func5(), hasQualifiedName(3):abstractfunctiondecl.Class3.func5(), memberOf:Class3 | +| abstractfunctiondecl.swift:25:2:25:16 | func6() | MethodDecl, getName:func6(), hasName:func6(), hasQualifiedName(2):Struct1.func6(), hasQualifiedName(3):abstractfunctiondecl.Struct1.func6(), memberOf:Struct1 | +| abstractfunctiondecl.swift:31:2:31:16 | func7() | MethodDecl, getName:func7(), hasName:func7(), hasQualifiedName(2):Enum1.func7(), hasQualifiedName(3):abstractfunctiondecl.Enum1.func7(), memberOf:Enum1 | +| abstractfunctiondecl.swift:37:3:37:17 | func8() | MethodDecl, getName:func8(), hasName:func8(), hasQualifiedName(2):Class4.func8(), hasQualifiedName(3):abstractfunctiondecl.Class4.func8(), memberOf:Class4 | diff --git a/swift/ql/test/library-tests/elements/decl/abstractfunctiondecl/abstractfunctiondecl.ql b/swift/ql/test/library-tests/elements/decl/abstractfunctiondecl/abstractfunctiondecl.ql index e3b3290890d..acd05cc4438 100644 --- a/swift/ql/test/library-tests/elements/decl/abstractfunctiondecl/abstractfunctiondecl.ql +++ b/swift/ql/test/library-tests/elements/decl/abstractfunctiondecl/abstractfunctiondecl.ql @@ -19,6 +19,10 @@ string describe(AbstractFunctionDecl f) { f.(MethodDecl).hasQualifiedName(a, b, c) and result = "hasQualifiedName(3):" + a + "." + b + "." + c ) + or + exists(Decl td | td.getAMember() = f | + result = "memberOf:" + td.asNominalTypeDecl().getFullName() + ) } from AbstractFunctionDecl f diff --git a/swift/ql/test/library-tests/elements/decl/abstractfunctiondecl/abstractfunctiondecl.swift b/swift/ql/test/library-tests/elements/decl/abstractfunctiondecl/abstractfunctiondecl.swift index 881fb93b5c2..3e0cb330708 100644 --- a/swift/ql/test/library-tests/elements/decl/abstractfunctiondecl/abstractfunctiondecl.swift +++ b/swift/ql/test/library-tests/elements/decl/abstractfunctiondecl/abstractfunctiondecl.swift @@ -30,3 +30,10 @@ enum Enum1 { case case2 func func7() {} } + +extension Class1 +{ + class Class4 { + func func8() {} + } +} From 91c324ea4fec1abd06057032b62b68a1e7e20bfe Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Tue, 21 Mar 2023 14:36:21 +0000 Subject: [PATCH 269/631] Swift: Fix for getFullName. --- swift/ql/lib/codeql/swift/elements/decl/TypeDecl.qll | 3 +++ .../decl/abstractfunctiondecl/abstractfunctiondecl.expected | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/swift/ql/lib/codeql/swift/elements/decl/TypeDecl.qll b/swift/ql/lib/codeql/swift/elements/decl/TypeDecl.qll index 6c2b446a422..8a49256078f 100644 --- a/swift/ql/lib/codeql/swift/elements/decl/TypeDecl.qll +++ b/swift/ql/lib/codeql/swift/elements/decl/TypeDecl.qll @@ -28,8 +28,11 @@ class TypeDecl extends Generated::TypeDecl { cached string getFullName() { not this.getEnclosingDecl() instanceof TypeDecl and + not this.getEnclosingDecl() instanceof ExtensionDecl and result = this.getName() or result = this.getEnclosingDecl().(TypeDecl).getFullName() + "." + this.getName() + or + result = this.getEnclosingDecl().(ExtensionDecl).getExtendedTypeDecl().getFullName() + "." + this.getName() } } diff --git a/swift/ql/test/library-tests/elements/decl/abstractfunctiondecl/abstractfunctiondecl.expected b/swift/ql/test/library-tests/elements/decl/abstractfunctiondecl/abstractfunctiondecl.expected index d8723c0068e..49d4c192730 100644 --- a/swift/ql/test/library-tests/elements/decl/abstractfunctiondecl/abstractfunctiondecl.expected +++ b/swift/ql/test/library-tests/elements/decl/abstractfunctiondecl/abstractfunctiondecl.expected @@ -6,4 +6,4 @@ | abstractfunctiondecl.swift:21:2:21:16 | func5() | MethodDecl, getName:func5(), hasName:func5(), hasQualifiedName(2):Class3.func5(), hasQualifiedName(3):abstractfunctiondecl.Class3.func5(), memberOf:Class3 | | abstractfunctiondecl.swift:25:2:25:16 | func6() | MethodDecl, getName:func6(), hasName:func6(), hasQualifiedName(2):Struct1.func6(), hasQualifiedName(3):abstractfunctiondecl.Struct1.func6(), memberOf:Struct1 | | abstractfunctiondecl.swift:31:2:31:16 | func7() | MethodDecl, getName:func7(), hasName:func7(), hasQualifiedName(2):Enum1.func7(), hasQualifiedName(3):abstractfunctiondecl.Enum1.func7(), memberOf:Enum1 | -| abstractfunctiondecl.swift:37:3:37:17 | func8() | MethodDecl, getName:func8(), hasName:func8(), hasQualifiedName(2):Class4.func8(), hasQualifiedName(3):abstractfunctiondecl.Class4.func8(), memberOf:Class4 | +| abstractfunctiondecl.swift:37:3:37:17 | func8() | MethodDecl, getName:func8(), hasName:func8(), hasQualifiedName(2):Class1.Class4.func8(), hasQualifiedName(3):abstractfunctiondecl.Class1.Class4.func8(), memberOf:Class1.Class4 | From 12b75e7be12c961162f97683635b49474e2a1cd6 Mon Sep 17 00:00:00 2001 From: Alexandre Boulgakov Date: Tue, 21 Mar 2023 16:02:38 +0000 Subject: [PATCH 270/631] Swift: Cleanup: Remove some unused #includes. --- swift/extractor/main.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/swift/extractor/main.cpp b/swift/extractor/main.cpp index 8220f8a1164..bb4f1d775c2 100644 --- a/swift/extractor/main.cpp +++ b/swift/extractor/main.cpp @@ -1,5 +1,3 @@ -#include -#include #include #include #include @@ -18,7 +16,6 @@ #include "swift/extractor/invocation/SwiftInvocationExtractor.h" #include "swift/extractor/trap/TrapDomain.h" #include "swift/extractor/infra/file/Path.h" -#include using namespace std::string_literals; From 0408e9dc2dbdf09a39ae0b122e3ef98b9de3042d Mon Sep 17 00:00:00 2001 From: Ed Minnix Date: Tue, 21 Mar 2023 15:28:16 -0400 Subject: [PATCH 271/631] Fix formatting of TypeDecl.qll --- swift/ql/lib/codeql/swift/elements/decl/TypeDecl.qll | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/swift/ql/lib/codeql/swift/elements/decl/TypeDecl.qll b/swift/ql/lib/codeql/swift/elements/decl/TypeDecl.qll index 8a49256078f..75189283435 100644 --- a/swift/ql/lib/codeql/swift/elements/decl/TypeDecl.qll +++ b/swift/ql/lib/codeql/swift/elements/decl/TypeDecl.qll @@ -33,6 +33,8 @@ class TypeDecl extends Generated::TypeDecl { or result = this.getEnclosingDecl().(TypeDecl).getFullName() + "." + this.getName() or - result = this.getEnclosingDecl().(ExtensionDecl).getExtendedTypeDecl().getFullName() + "." + this.getName() + result = + this.getEnclosingDecl().(ExtensionDecl).getExtendedTypeDecl().getFullName() + "." + + this.getName() } } From 4fc5742a62a052878a87afa0f9fffa308187fd80 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 22 Mar 2023 00:14:41 +0000 Subject: [PATCH 272/631] Add changed framework coverage reports --- java/documentation/library-coverage/coverage.csv | 10 ++++++---- java/documentation/library-coverage/coverage.rst | 8 ++++---- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/java/documentation/library-coverage/coverage.csv b/java/documentation/library-coverage/coverage.csv index 84e5a0db8eb..c0dcc806c02 100644 --- a/java/documentation/library-coverage/coverage.csv +++ b/java/documentation/library-coverage/coverage.csv @@ -52,19 +52,20 @@ jakarta.ws.rs.core,2,,149,,,,,,,,,,,,,,,,,,,,,,,,,,,,,2,,,,,,,,,94,55 java.beans,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1, java.io,42,,40,,17,,,,,,,,,,,,,,,3,,,,,,,,,,,,,22,,,,,,,,39,1 java.lang,16,,76,,,,,,,,,,,,8,,,,,3,,4,,,1,,,,,,,,,,,,,,,,53,23 -java.net,12,3,16,,,,,,,,,,,,,,,12,,,,,,,,,,,,,,,,,,,,,,3,16, -java.nio,20,,16,,15,,,,,,,,,,,,,,,3,,,,,,,,,,,,,2,,,,,,,,16, +java.net,12,3,17,,,,,,,,,,,,,,,12,,,,,,,,,,,,,,,,,,,,,,3,17, +java.nio,25,,29,,19,,,,,,,,,,,,,,,4,,,,,,,,,,,,,2,,,,,,,,29, java.sql,13,,2,,,,,,,,4,,,,,,,,,,,,,,,,,,9,,,,,,,,,,,,1,1 java.util,44,,465,,,,,,,,,,,,34,,,,,,,,5,2,,1,2,,,,,,,,,,,,,,38,427 javafx.scene.web,1,,,,,,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,,,,, javax.faces.context,2,7,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,2,,,,7,, +javax.imageio.stream,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1, javax.jms,,9,57,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,9,57, javax.json,,,123,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,100,23 javax.management.remote,2,,,,,,,,,,,,2,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -javax.naming,7,,,,,,,,,,,,6,1,,,,,,,,,,,,,,,,,,,,,,,,,,,, +javax.naming,7,,1,,,,,,,,,,6,1,,,,,,,,,,,,,,,,,,,,,,,,,,,1, javax.net.ssl,2,,,,,,,,,,,,,,,,,,,,,,,,,,,2,,,,,,,,,,,,,, javax.script,1,,,,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,,,,,,, -javax.servlet,4,21,2,,,,,3,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,21,2, +javax.servlet,5,21,2,,,,,3,1,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,21,2, javax.validation,1,1,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,, javax.ws.rs.client,1,,,,,,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,,,,, javax.ws.rs.container,,9,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,9,, @@ -108,6 +109,7 @@ org.apache.velocity.runtime,4,,,,,,,,,,,,,,,,,,,,,,,,,,,,,4,,,,,,,,,,,, org.codehaus.cargo.container.installer,3,,,,2,,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,,,,, org.codehaus.groovy.control,1,,,,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, org.dom4j,20,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,20,,,,,,,, +org.geogebra.web.full.main,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,,,,,,, org.hibernate,7,,,,,,,,,,,,,,,,,,,,,,,,,,,,7,,,,,,,,,,,,, org.jboss.logging,324,,,,,,,,,,,,,,324,,,,,,,,,,,,,,,,,,,,,,,,,,, org.jdbi.v3.core,6,,,,,,,,,,6,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, diff --git a/java/documentation/library-coverage/coverage.rst b/java/documentation/library-coverage/coverage.rst index cc6fdb875ff..01b16e25a87 100644 --- a/java/documentation/library-coverage/coverage.rst +++ b/java/documentation/library-coverage/coverage.rst @@ -18,10 +18,10 @@ Java framework & library support `Google Guava `_,``com.google.common.*``,,730,39,,6,,,,, JBoss Logging,``org.jboss.logging``,,,324,,,,,,, `JSON-java `_,``org.json``,,236,,,,,,,, - Java Standard Library,``java.*``,3,616,147,32,,,9,,,12 - Java extensions,"``javax.*``, ``jakarta.*``",63,609,33,1,,4,,1,1,2 + Java Standard Library,``java.*``,3,630,152,36,,,9,,,12 + Java extensions,"``javax.*``, ``jakarta.*``",63,611,34,1,,4,,1,1,2 Kotlin Standard Library,``kotlin*``,,1835,12,10,,,,,,2 `Spring `_,``org.springframework.*``,29,480,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.thoughtworks.xstream``, ``com.unboundid.ldap.sdk``, ``com.zaxxer.hikari``, ``flexjson``, ``freemarker.cache``, ``freemarker.template``, ``groovy.lang``, ``groovy.util``, ``hudson.model``, ``hudson.os``, ``hudson.remoting``, ``hudson.util``, ``io.netty.bootstrap``, ``io.netty.channel``, ``io.netty.handler.codec.http``, ``io.netty.handler.ssl``, ``io.netty.handler.stream``, ``io.netty.resolver``, ``io.netty.util.internal``, ``javafx.scene.web``, ``jodd.json``, ``net.sf.saxon.s9api``, ``ognl``, ``okhttp3``, ``org.apache.commons.codec``, ``org.apache.commons.compress.archivers.tar``, ``org.apache.commons.jelly``, ``org.apache.commons.jexl2``, ``org.apache.commons.jexl3``, ``org.apache.commons.logging``, ``org.apache.commons.ognl``, ``org.apache.directory.ldap.client.api``, ``org.apache.hadoop.hive.metastore``, ``org.apache.hive.hcatalog.templeton``, ``org.apache.ibatis.jdbc``, ``org.apache.log4j``, ``org.apache.shiro.codec``, ``org.apache.shiro.jndi``, ``org.apache.tools.ant``, ``org.apache.tools.zip``, ``org.apache.velocity.app``, ``org.apache.velocity.runtime``, ``org.codehaus.cargo.container.installer``, ``org.codehaus.groovy.control``, ``org.dom4j``, ``org.hibernate``, ``org.jdbi.v3.core``, ``org.jooq``, ``org.kohsuke.stapler``, ``org.mvel2``, ``org.openjdk.jmh.runner.options``, ``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,314,327,12,,,18,18,,28 - Totals,,217,8491,1640,146,6,10,113,33,1,113 + 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.thoughtworks.xstream``, ``com.unboundid.ldap.sdk``, ``com.zaxxer.hikari``, ``flexjson``, ``freemarker.cache``, ``freemarker.template``, ``groovy.lang``, ``groovy.util``, ``hudson.model``, ``hudson.os``, ``hudson.remoting``, ``hudson.util``, ``io.netty.bootstrap``, ``io.netty.channel``, ``io.netty.handler.codec.http``, ``io.netty.handler.ssl``, ``io.netty.handler.stream``, ``io.netty.resolver``, ``io.netty.util.internal``, ``javafx.scene.web``, ``jodd.json``, ``net.sf.saxon.s9api``, ``ognl``, ``okhttp3``, ``org.apache.commons.codec``, ``org.apache.commons.compress.archivers.tar``, ``org.apache.commons.jelly``, ``org.apache.commons.jexl2``, ``org.apache.commons.jexl3``, ``org.apache.commons.logging``, ``org.apache.commons.ognl``, ``org.apache.directory.ldap.client.api``, ``org.apache.hadoop.hive.metastore``, ``org.apache.hive.hcatalog.templeton``, ``org.apache.ibatis.jdbc``, ``org.apache.log4j``, ``org.apache.shiro.codec``, ``org.apache.shiro.jndi``, ``org.apache.tools.ant``, ``org.apache.tools.zip``, ``org.apache.velocity.app``, ``org.apache.velocity.runtime``, ``org.codehaus.cargo.container.installer``, ``org.codehaus.groovy.control``, ``org.dom4j``, ``org.geogebra.web.full.main``, ``org.hibernate``, ``org.jdbi.v3.core``, ``org.jooq``, ``org.kohsuke.stapler``, ``org.mvel2``, ``org.openjdk.jmh.runner.options``, ``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,314,328,12,,,18,18,,28 + Totals,,217,8507,1647,150,6,10,113,33,1,113 From 6cb134898856d01c7631b1e5d3e18252ac303d6d Mon Sep 17 00:00:00 2001 From: Harry Maclean Date: Wed, 22 Mar 2023 15:02:36 +1300 Subject: [PATCH 273/631] Ruby: Try different workaround for Actions bug --- .github/workflows/ruby-build.yml | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/.github/workflows/ruby-build.yml b/.github/workflows/ruby-build.yml index 1445d0c6589..f7314e5d4a5 100644 --- a/.github/workflows/ruby-build.yml +++ b/.github/workflows/ruby-build.yml @@ -262,29 +262,28 @@ jobs: - name: Fetch CodeQL uses: ./.github/actions/fetch-codeql - # Due to a bug in Actions, we can't use runner.temp here. + # Due to a bug in Actions, we can't use runner.temp in the run blocks here. # https://github.com/actions/runner/issues/2185 - - name: Ensure temp directory exists - run: mkdir -p /tmp - name: Download Ruby bundle uses: actions/download-artifact@v3 with: name: codeql-ruby-bundle - path: /tmp + path: ${{ runner.temp }} - name: Unzip Ruby bundle shell: bash run: unzip -q -d /tmp/ruby-bundle /tmp/codeql-ruby-bundle.zip + run: unzip -q -d "$RUNNER_TEMP"/ruby-bundle "$RUNNER_TEMP"/codeql-ruby-bundle.zip - name: Run QL test shell: bash run: | - codeql test run --search-path /tmp/ruby-bundle --additional-packs /tmp/ruby-bundle ruby/ql/test/library-tests/ast/constants/ + codeql test run --search-path "$RUNNER_TEMP"/ruby-bundle --additional-packs "$RUNNER_TEMP"/ruby-bundle ruby/ql/test/library-tests/ast/constants/ - name: Create database shell: bash run: | - codeql database create --search-path /tmp/ruby-bundle --language ruby --source-root ruby/ql/test/library-tests/ast/constants/ ../database + codeql database create --search-path "$RUNNER_TEMP"/ruby-bundle --language ruby --source-root ruby/ql/test/library-tests/ast/constants/ ../database - name: Analyze database shell: bash run: | - codeql database analyze --search-path /tmp/ruby-bundle --format=sarifv2.1.0 --output=out.sarif ../database ruby-code-scanning.qls + codeql database analyze --search-path "$RUNNER_TEMP"/ruby-bundle --format=sarifv2.1.0 --output=out.sarif ../database ruby-code-scanning.qls From b7600c6022f83e579f0372ba1e22808a080ddba4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 22 Mar 2023 04:06:21 +0000 Subject: [PATCH 274/631] Bump regex from 1.7.1 to 1.7.2 in /ql Bumps [regex](https://github.com/rust-lang/regex) from 1.7.1 to 1.7.2. - [Release notes](https://github.com/rust-lang/regex/releases) - [Changelog](https://github.com/rust-lang/regex/blob/master/CHANGELOG.md) - [Commits](https://github.com/rust-lang/regex/compare/1.7.1...1.7.2) --- updated-dependencies: - dependency-name: regex dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- ql/Cargo.lock | Bin 22516 -> 22516 bytes ql/buramu/Cargo.toml | 2 +- ql/extractor/Cargo.toml | 2 +- 3 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ql/Cargo.lock b/ql/Cargo.lock index 08d54ab697a6dbee77aecea32f35fb61f382395c..f1428bd8beaef8845004c2df1c2df279e95c1e92 100644 GIT binary patch delta 163 zcmV~$u@S;B3;@8(640fh<|J9Rl?r;AtYAr250d~HB-~{VhT$#)@V~Faz7C%+yx#N0 ztYeYrjl@%j9GFGDajwMzOqe|bXEicQg&-QxMBTG$7UboAK5P%X4NDv6YhWQO?o|O~ n671{@gwU)JD62zETEN;w6``O)jVd|SN)*&_`HjcT)ARHPr@%2_ delta 167 zcmWm6%?-jZ3_xLJiuS~b0UXCpoD1U4ff<}155OdqI!KW^2SYFdQU@TtywlTnZ0^|H z`vcCe-}!kXQB_VPWz<{ATpL#53fUrN^xT5RUVA1isvaOSs6o&`meysS_LqM+C#QBN sjx|CkJ#=X_P)KOxAp@MCnvZ0qc5EatW@G4m@W_^{kgUJUw70Na|0dotr2qf` diff --git a/ql/buramu/Cargo.toml b/ql/buramu/Cargo.toml index c7e1918975d..b12e6d9a9c6 100644 --- a/ql/buramu/Cargo.toml +++ b/ql/buramu/Cargo.toml @@ -9,4 +9,4 @@ edition = "2018" lazy_static = "1.4.0" chrono = "0.4.24" rayon = "1.7.0" -regex = "1.7.1" +regex = "1.7.2" diff --git a/ql/extractor/Cargo.toml b/ql/extractor/Cargo.toml index 308953d1f8f..e7dc17f2feb 100644 --- a/ql/extractor/Cargo.toml +++ b/ql/extractor/Cargo.toml @@ -20,4 +20,4 @@ tracing = "0.1" tracing-subscriber = { version = "0.3.16", features = ["env-filter"] } rayon = "1.7.0" num_cpus = "1.14.0" -regex = "1.7.1" +regex = "1.7.2" From 46ef954d5cfbd815755d47fb469707000ddae7e4 Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Tue, 21 Mar 2023 10:50:26 +0100 Subject: [PATCH 275/631] Java: Validate all accesspaths except for Field. --- .../semmle/code/java/dataflow/ExternalFlow.qll | 12 +++++++----- .../external-models/validatemodels.expected | 0 .../dataflow/external-models/validatemodels.ql | 15 +++++++++++++++ 3 files changed, 22 insertions(+), 5 deletions(-) create mode 100644 java/ql/test/library-tests/dataflow/external-models/validatemodels.expected create mode 100644 java/ql/test/library-tests/dataflow/external-models/validatemodels.ql diff --git a/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll b/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll index a736928361c..39d5bd27311 100644 --- a/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll +++ b/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll @@ -220,7 +220,7 @@ predicate modelCoverage(string package, int pkgs, string kind, string part, int /** Provides a query predicate to check the MaD models for validation errors. */ module ModelValidation { private string getInvalidModelInput() { - exists(string pred, string input, string part | + exists(string pred, AccessPath input, AccessPathToken part | sinkModel(_, _, _, _, _, _, input, _, _) and pred = "sink" or summaryModel(_, _, _, _, _, _, input, _, _, _) and pred = "summary" @@ -229,9 +229,10 @@ module ModelValidation { invalidSpecComponent(input, part) and not part = "" and not (part = "Argument" and pred = "sink") and - not parseArg(part, _) + not parseArg(part, _) and + not part.getName() = "Field" or - part = input.(AccessPath).getToken(0) and + part = input.getToken(0) and parseParam(part, _) or invalidIndexComponent(input, part) @@ -241,7 +242,7 @@ module ModelValidation { } private string getInvalidModelOutput() { - exists(string pred, string output, string part | + exists(string pred, AccessPath output, AccessPathToken part | sourceModel(_, _, _, _, _, _, output, _, _) and pred = "source" or summaryModel(_, _, _, _, _, _, _, output, _, _) and pred = "summary" @@ -249,7 +250,8 @@ module ModelValidation { ( invalidSpecComponent(output, part) and not part = "" and - not (part = ["Argument", "Parameter"] and pred = "source") + not (part = ["Argument", "Parameter"] and pred = "source") and + not part.getName() = "Field" or invalidIndexComponent(output, part) ) and diff --git a/java/ql/test/library-tests/dataflow/external-models/validatemodels.expected b/java/ql/test/library-tests/dataflow/external-models/validatemodels.expected new file mode 100644 index 00000000000..e69de29bb2d diff --git a/java/ql/test/library-tests/dataflow/external-models/validatemodels.ql b/java/ql/test/library-tests/dataflow/external-models/validatemodels.ql new file mode 100644 index 00000000000..84312d3d4e4 --- /dev/null +++ b/java/ql/test/library-tests/dataflow/external-models/validatemodels.ql @@ -0,0 +1,15 @@ +import java +import semmle.code.java.dataflow.ExternalFlow +import semmle.code.java.dataflow.internal.AccessPathSyntax +import ModelValidation + +private predicate getRelevantAccessPath(string path) { + summaryModel(_, _, _, _, _, _, path, _, _, _) or + summaryModel(_, _, _, _, _, _, _, path, _, _) or + sinkModel(_, _, _, _, _, _, path, _, _) or + sourceModel(_, _, _, _, _, _, path, _, _) +} + +private class AccessPathsExternal extends AccessPath::Range { + AccessPathsExternal() { getRelevantAccessPath(this) } +} From 71d184e8c0a4c00fe4ac4bded02765347304a418 Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Tue, 21 Mar 2023 11:08:33 +0100 Subject: [PATCH 276/631] C#: Validate all access paths except for Field and Property. --- .../semmle/code/csharp/dataflow/ExternalFlow.qll | 10 ++++++---- .../external-models/validatemodels.expected | 0 .../dataflow/external-models/validatemodels.ql | 15 +++++++++++++++ 3 files changed, 21 insertions(+), 4 deletions(-) create mode 100644 csharp/ql/test/library-tests/dataflow/external-models/validatemodels.expected create mode 100644 csharp/ql/test/library-tests/dataflow/external-models/validatemodels.ql diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/ExternalFlow.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/ExternalFlow.qll index 4067ba6e81c..2792c1d180c 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/ExternalFlow.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/ExternalFlow.qll @@ -160,7 +160,7 @@ predicate modelCoverage(string namespace, int namespaces, string kind, string pa /** Provides a query predicate to check the MaD models for validation errors. */ module ModelValidation { private string getInvalidModelInput() { - exists(string pred, AccessPath input, string part | + exists(string pred, AccessPath input, AccessPathToken part | sinkModel(_, _, _, _, _, _, input, _, _) and pred = "sink" or summaryModel(_, _, _, _, _, _, input, _, _, _) and pred = "summary" @@ -169,7 +169,8 @@ module ModelValidation { invalidSpecComponent(input, part) and not part = "" and not (part = "Argument" and pred = "sink") and - not parseArg(part, _) + not parseArg(part, _) and + not part.getName() = ["Field", "Property"] or part = input.getToken(_) and parseParam(part, _) @@ -181,7 +182,7 @@ module ModelValidation { } private string getInvalidModelOutput() { - exists(string pred, string output, string part | + exists(string pred, AccessPath output, AccessPathToken part | sourceModel(_, _, _, _, _, _, output, _, _) and pred = "source" or summaryModel(_, _, _, _, _, _, _, output, _, _) and pred = "summary" @@ -189,7 +190,8 @@ module ModelValidation { ( invalidSpecComponent(output, part) and not part = "" and - not (part = ["Argument", "Parameter"] and pred = "source") + not (part = ["Argument", "Parameter"] and pred = "source") and + not part.getName() = ["Field", "Property"] or invalidIndexComponent(output, part) ) and diff --git a/csharp/ql/test/library-tests/dataflow/external-models/validatemodels.expected b/csharp/ql/test/library-tests/dataflow/external-models/validatemodels.expected new file mode 100644 index 00000000000..e69de29bb2d diff --git a/csharp/ql/test/library-tests/dataflow/external-models/validatemodels.ql b/csharp/ql/test/library-tests/dataflow/external-models/validatemodels.ql new file mode 100644 index 00000000000..d9e073ab78e --- /dev/null +++ b/csharp/ql/test/library-tests/dataflow/external-models/validatemodels.ql @@ -0,0 +1,15 @@ +import csharp +import semmle.code.csharp.dataflow.ExternalFlow +import semmle.code.csharp.dataflow.internal.AccessPathSyntax +import ModelValidation + +private predicate getRelevantAccessPath(string path) { + summaryModel(_, _, _, _, _, _, path, _, _, _) or + summaryModel(_, _, _, _, _, _, _, path, _, _) or + sinkModel(_, _, _, _, _, _, path, _, _) or + sourceModel(_, _, _, _, _, _, path, _, _) +} + +private class AccessPathsExternal extends AccessPath::Range { + AccessPathsExternal() { getRelevantAccessPath(this) } +} From 801e0ff05050a5a842fdfda97f2e214dfbfc2958 Mon Sep 17 00:00:00 2001 From: erik-krogh Date: Wed, 22 Mar 2023 10:00:34 +0100 Subject: [PATCH 277/631] ReDoS: implement a better super-linear algorithm, with better worst-case performance --- .../ReDoS/PolynomialBackTracking.expected | 77 ++-- .../CWE-400/ReDoS/PolynomialReDoS.expected | 10 - shared/regex/codeql/regex/nfa/NfaUtils.qll | 4 + .../regex/nfa/SuperlinearBackTracking.qll | 361 +++++++++++------- 4 files changed, 273 insertions(+), 179 deletions(-) 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 cfc43062161..21aca8719f5 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 @@ -1,13 +1,14 @@ -| highlight.js:2:26:2:979 | ((traffic-flow\|traffic-generator\|firewall\|scheduler\|aaa\|accounting\|address-list\|address\|align\|area\|bandwidth-server\|bfd\|bgp\|bridge\|client\|clock\|community\|config\|connection\|console\|customer\|default\|dhcp-client\|dhcp-server\|discovery\|dns\|e-mail\|ethernet\|filter\|firewall\|firmware\|gps\|graphing\|group\|hardware\|health\|hotspot\|identity\|igmp-proxy\|incoming\|instance\|interface\|ip\|ipsec\|ipv6\|irq\|l2tp-server\|lcd\|ldp\|logging\|mac-server\|mac-winbox\|mangle\|manual\|mirror\|mme\|mpls\|nat\|nd\|neighbor\|network\|note\|ntp\|ospf\|ospf-v3\|ovpn-server\|page\|peer\|pim\|ping\|policy\|pool\|port\|ppp\|pppoe-client\|pptp-server\|prefix\|profile\|proposal\|proxy\|queue\|radius\|resource\|rip\|ripng\|route\|routing\|screen\|script\|security-profiles\|server\|service\|service-port\|settings\|shares\|smb\|sms\|sniffer\|snmp\|snooper\|socks\|sstp-server\|system\|tool\|tracking\|type\|upgrade\|upnp\|user-manager\|users\|user\|vlan\|secret\|vrrp\|watchdog\|web-access\|wireless\|pptp\|pppoe\|lan\|wan\|layer7-protocol\|lease\|simple\|raw);?\\s)+ | Strings starting with '/' and with many repetitions of 'aaa\\t' can start matching anywhere after the start of the preceeding (\\.\\.\\/\|\\/\|\\s)((traffic-flow\|traffic-generator\|firewall\|scheduler\|aaa\|accounting\|address-list\|address\|align\|area\|bandwidth-server\|bfd\|bgp\|bridge\|client\|clock\|community\|config\|connection\|console\|customer\|default\|dhcp-client\|dhcp-server\|discovery\|dns\|e-mail\|ethernet\|filter\|firewall\|firmware\|gps\|graphing\|group\|hardware\|health\|hotspot\|identity\|igmp-proxy\|incoming\|instance\|interface\|ip\|ipsec\|ipv6\|irq\|l2tp-server\|lcd\|ldp\|logging\|mac-server\|mac-winbox\|mangle\|manual\|mirror\|mme\|mpls\|nat\|nd\|neighbor\|network\|note\|ntp\|ospf\|ospf-v3\|ovpn-server\|page\|peer\|pim\|ping\|policy\|pool\|port\|ppp\|pppoe-client\|pptp-server\|prefix\|profile\|proposal\|proxy\|queue\|radius\|resource\|rip\|ripng\|route\|routing\|screen\|script\|security-profiles\|server\|service\|service-port\|settings\|shares\|smb\|sms\|sniffer\|snmp\|snooper\|socks\|sstp-server\|system\|tool\|tracking\|type\|upgrade\|upnp\|user-manager\|users\|user\|vlan\|secret\|vrrp\|watchdog\|web-access\|wireless\|pptp\|pppoe\|lan\|wan\|layer7-protocol\|lease\|simple\|raw);?\\s)+X | -| highlight.js:3:27:3:971 | ((traffic-flow\|traffic-generator\|firewall\|scheduler\|aaa\|accounting\|address-list\|address\|align\|area\|bandwidth-server\|bfd\|bgp\|bridge\|client\|clock\|community\|config\|connection\|console\|customer\|default\|dhcp-client\|dhcp-server\|discovery\|dns\|e-mail\|ethernet\|filter\|firmware\|gps\|graphing\|group\|hardware\|health\|hotspot\|identity\|igmp-proxy\|incoming\|instance\|interface\|ip\|ipsec\|ipv6\|irq\|l2tp-server\|lcd\|ldp\|logging\|mac-server\|mac-winbox\|mangle\|manual\|mirror\|mme\|mpls\|nat\|nd\|neighbor\|network\|note\|ntp\|ospf\|ospf-v3\|ovpn-server\|page\|peer\|pim\|ping\|policy\|pool\|port\|ppp\|pppoe-client\|pptp-server\|prefix\|profile\|proposal\|proxy\|queue\|radius\|resource\|rip\|ripng\|route\|routing\|screen\|script\|security-profiles\|server\|service\|service-port\|settings\|shares\|smb\|sms\|sniffer\|snmp\|snooper\|socks\|sstp-server\|system\|tool\|tracking\|type\|upgrade\|upnp\|user-manager\|users\|user\|vlan\|secret\|vrrp\|watchdog\|web-access\|wireless\|pptp\|pppoe\|lan\|wan\|layer7-protocol\|lease\|simple\|raw);?\\s)+ | Strings starting with '/' and with many repetitions of 'aaa\\t' can start matching anywhere after the start of the preceeding (\\.\\.\\/\|\\/\|\\s)((traffic-flow\|traffic-generator\|firewall\|scheduler\|aaa\|accounting\|address-list\|address\|align\|area\|bandwidth-server\|bfd\|bgp\|bridge\|client\|clock\|community\|config\|connection\|console\|customer\|default\|dhcp-client\|dhcp-server\|discovery\|dns\|e-mail\|ethernet\|filter\|firmware\|gps\|graphing\|group\|hardware\|health\|hotspot\|identity\|igmp-proxy\|incoming\|instance\|interface\|ip\|ipsec\|ipv6\|irq\|l2tp-server\|lcd\|ldp\|logging\|mac-server\|mac-winbox\|mangle\|manual\|mirror\|mme\|mpls\|nat\|nd\|neighbor\|network\|note\|ntp\|ospf\|ospf-v3\|ovpn-server\|page\|peer\|pim\|ping\|policy\|pool\|port\|ppp\|pppoe-client\|pptp-server\|prefix\|profile\|proposal\|proxy\|queue\|radius\|resource\|rip\|ripng\|route\|routing\|screen\|script\|security-profiles\|server\|service\|service-port\|settings\|shares\|smb\|sms\|sniffer\|snmp\|snooper\|socks\|sstp-server\|system\|tool\|tracking\|type\|upgrade\|upnp\|user-manager\|users\|user\|vlan\|secret\|vrrp\|watchdog\|web-access\|wireless\|pptp\|pppoe\|lan\|wan\|layer7-protocol\|lease\|simple\|raw);?\\s)+X | +| highlight.js:2:26:2:979 | ((traffic-flow\|traffic-generator\|firewall\|scheduler\|aaa\|accounting\|address-list\|address\|align\|area\|bandwidth-server\|bfd\|bgp\|bridge\|client\|clock\|community\|config\|connection\|console\|customer\|default\|dhcp-client\|dhcp-server\|discovery\|dns\|e-mail\|ethernet\|filter\|firewall\|firmware\|gps\|graphing\|group\|hardware\|health\|hotspot\|identity\|igmp-proxy\|incoming\|instance\|interface\|ip\|ipsec\|ipv6\|irq\|l2tp-server\|lcd\|ldp\|logging\|mac-server\|mac-winbox\|mangle\|manual\|mirror\|mme\|mpls\|nat\|nd\|neighbor\|network\|note\|ntp\|ospf\|ospf-v3\|ovpn-server\|page\|peer\|pim\|ping\|policy\|pool\|port\|ppp\|pppoe-client\|pptp-server\|prefix\|profile\|proposal\|proxy\|queue\|radius\|resource\|rip\|ripng\|route\|routing\|screen\|script\|security-profiles\|server\|service\|service-port\|settings\|shares\|smb\|sms\|sniffer\|snmp\|snooper\|socks\|sstp-server\|system\|tool\|tracking\|type\|upgrade\|upnp\|user-manager\|users\|user\|vlan\|secret\|vrrp\|watchdog\|web-access\|wireless\|pptp\|pppoe\|lan\|wan\|layer7-protocol\|lease\|simple\|raw);?\\s)+ | Strings starting with '/' and with many repetitions of 'ip\\t' can start matching anywhere after the start of the preceeding (\\.\\.\\/\|\\/\|\\s)((traffic-flow\|traffic-generator\|firewall\|scheduler\|aaa\|accounting\|address-list\|address\|align\|area\|bandwidth-server\|bfd\|bgp\|bridge\|client\|clock\|community\|config\|connection\|console\|customer\|default\|dhcp-client\|dhcp-server\|discovery\|dns\|e-mail\|ethernet\|filter\|firewall\|firmware\|gps\|graphing\|group\|hardware\|health\|hotspot\|identity\|igmp-proxy\|incoming\|instance\|interface\|ip\|ipsec\|ipv6\|irq\|l2tp-server\|lcd\|ldp\|logging\|mac-server\|mac-winbox\|mangle\|manual\|mirror\|mme\|mpls\|nat\|nd\|neighbor\|network\|note\|ntp\|ospf\|ospf-v3\|ovpn-server\|page\|peer\|pim\|ping\|policy\|pool\|port\|ppp\|pppoe-client\|pptp-server\|prefix\|profile\|proposal\|proxy\|queue\|radius\|resource\|rip\|ripng\|route\|routing\|screen\|script\|security-profiles\|server\|service\|service-port\|settings\|shares\|smb\|sms\|sniffer\|snmp\|snooper\|socks\|sstp-server\|system\|tool\|tracking\|type\|upgrade\|upnp\|user-manager\|users\|user\|vlan\|secret\|vrrp\|watchdog\|web-access\|wireless\|pptp\|pppoe\|lan\|wan\|layer7-protocol\|lease\|simple\|raw);?\\s)+X | +| highlight.js:3:27:3:971 | ((traffic-flow\|traffic-generator\|firewall\|scheduler\|aaa\|accounting\|address-list\|address\|align\|area\|bandwidth-server\|bfd\|bgp\|bridge\|client\|clock\|community\|config\|connection\|console\|customer\|default\|dhcp-client\|dhcp-server\|discovery\|dns\|e-mail\|ethernet\|filter\|firmware\|gps\|graphing\|group\|hardware\|health\|hotspot\|identity\|igmp-proxy\|incoming\|instance\|interface\|ip\|ipsec\|ipv6\|irq\|l2tp-server\|lcd\|ldp\|logging\|mac-server\|mac-winbox\|mangle\|manual\|mirror\|mme\|mpls\|nat\|nd\|neighbor\|network\|note\|ntp\|ospf\|ospf-v3\|ovpn-server\|page\|peer\|pim\|ping\|policy\|pool\|port\|ppp\|pppoe-client\|pptp-server\|prefix\|profile\|proposal\|proxy\|queue\|radius\|resource\|rip\|ripng\|route\|routing\|screen\|script\|security-profiles\|server\|service\|service-port\|settings\|shares\|smb\|sms\|sniffer\|snmp\|snooper\|socks\|sstp-server\|system\|tool\|tracking\|type\|upgrade\|upnp\|user-manager\|users\|user\|vlan\|secret\|vrrp\|watchdog\|web-access\|wireless\|pptp\|pppoe\|lan\|wan\|layer7-protocol\|lease\|simple\|raw);?\\s)+ | Strings starting with '/' and with many repetitions of 'ip\\t' can start matching anywhere after the start of the preceeding (\\.\\.\\/\|\\/\|\\s)((traffic-flow\|traffic-generator\|firewall\|scheduler\|aaa\|accounting\|address-list\|address\|align\|area\|bandwidth-server\|bfd\|bgp\|bridge\|client\|clock\|community\|config\|connection\|console\|customer\|default\|dhcp-client\|dhcp-server\|discovery\|dns\|e-mail\|ethernet\|filter\|firmware\|gps\|graphing\|group\|hardware\|health\|hotspot\|identity\|igmp-proxy\|incoming\|instance\|interface\|ip\|ipsec\|ipv6\|irq\|l2tp-server\|lcd\|ldp\|logging\|mac-server\|mac-winbox\|mangle\|manual\|mirror\|mme\|mpls\|nat\|nd\|neighbor\|network\|note\|ntp\|ospf\|ospf-v3\|ovpn-server\|page\|peer\|pim\|ping\|policy\|pool\|port\|ppp\|pppoe-client\|pptp-server\|prefix\|profile\|proposal\|proxy\|queue\|radius\|resource\|rip\|ripng\|route\|routing\|screen\|script\|security-profiles\|server\|service\|service-port\|settings\|shares\|smb\|sms\|sniffer\|snmp\|snooper\|socks\|sstp-server\|system\|tool\|tracking\|type\|upgrade\|upnp\|user-manager\|users\|user\|vlan\|secret\|vrrp\|watchdog\|web-access\|wireless\|pptp\|pppoe\|lan\|wan\|layer7-protocol\|lease\|simple\|raw);?\\s)+X | | highlight.js:6:12:6:695 | (Add\|Clear\|Close\|Copy\|Enter\|Exit\|Find\|Format\|Get\|Hide\|Join\|Lock\|Move\|New\|Open\|Optimize\|Pop\|Push\|Redo\|Remove\|Rename\|Reset\|Resize\|Search\|Select\|Set\|Show\|Skip\|Split\|Step\|Switch\|Undo\|Unlock\|Watch\|Backup\|Checkpoint\|Compare\|Compress\|Convert\|ConvertFrom\|ConvertTo\|Dismount\|Edit\|Expand\|Export\|Group\|Import\|Initialize\|Limit\|Merge\|New\|Out\|Publish\|Restore\|Save\|Sync\|Unpublish\|Update\|Approve\|Assert\|Complete\|Confirm\|Deny\|Disable\|Enable\|Install\|Invoke\|Register\|Request\|Restart\|Resume\|Start\|Stop\|Submit\|Suspend\|Uninstall\|Unregister\|Wait\|Debug\|Measure\|Ping\|Repair\|Resolve\|Test\|Trace\|Connect\|Disconnect\|Read\|Receive\|Send\|Write\|Block\|Grant\|Protect\|Revoke\|Unblock\|Unprotect\|Use\|ForEach\|Sort\|Tee\|Where)+ | Strings with many repetitions of 'Add' can start matching anywhere after the start of the preceeding (Add\|Clear\|Close\|Copy\|Enter\|Exit\|Find\|Format\|Get\|Hide\|Join\|Lock\|Move\|New\|Open\|Optimize\|Pop\|Push\|Redo\|Remove\|Rename\|Reset\|Resize\|Search\|Select\|Set\|Show\|Skip\|Split\|Step\|Switch\|Undo\|Unlock\|Watch\|Backup\|Checkpoint\|Compare\|Compress\|Convert\|ConvertFrom\|ConvertTo\|Dismount\|Edit\|Expand\|Export\|Group\|Import\|Initialize\|Limit\|Merge\|New\|Out\|Publish\|Restore\|Save\|Sync\|Unpublish\|Update\|Approve\|Assert\|Complete\|Confirm\|Deny\|Disable\|Enable\|Install\|Invoke\|Register\|Request\|Restart\|Resume\|Start\|Stop\|Submit\|Suspend\|Uninstall\|Unregister\|Wait\|Debug\|Measure\|Ping\|Repair\|Resolve\|Test\|Trace\|Connect\|Disconnect\|Read\|Receive\|Send\|Write\|Block\|Grant\|Protect\|Revoke\|Unblock\|Unprotect\|Use\|ForEach\|Sort\|Tee\|Where)+(-)[\\w\\d]+ | -| highlight.js:7:13:7:692 | (Add\|Clear\|Close\|Copy\|Enter\|Exit\|Find\|Format\|Get\|Hide\|Join\|Lock\|Move\|New\|Open\|Optimize\|Pop\|Push\|Redo\|Remove\|Rename\|Reset\|Resize\|Search\|Select\|Set\|Show\|Skip\|Split\|Step\|Switch\|Undo\|Unlock\|Watch\|Backup\|Checkpoint\|Compare\|Compress\|Convert\|ConvertFrom\|ConvertTo\|Dismount\|Edit\|Expand\|Export\|Group\|Import\|Initialize\|Limit\|Merge\|Out\|Publish\|Restore\|Save\|Sync\|Unpublish\|Update\|Approve\|Assert\|Complete\|Confirm\|Deny\|Disable\|Enable\|Install\|Invoke\|Register\|Request\|Restart\|Resume\|Start\|Stop\|Submit\|Suspend\|Uninstall\|Unregister\|Wait\|Debug\|Measure\|Ping\|Repair\|Resolve\|Test\|Trace\|Connect\|Disconnect\|Read\|Receive\|Send\|Write\|Block\|Grant\|Protect\|Revoke\|Unblock\|Unprotect\|Use\|ForEach\|Sort\|Tee\|Where)+ | Strings with many repetitions of 'Add' can start matching anywhere after the start of the preceeding (Add\|Clear\|Close\|Copy\|Enter\|Exit\|Find\|Format\|Get\|Hide\|Join\|Lock\|Move\|New\|Open\|Optimize\|Pop\|Push\|Redo\|Remove\|Rename\|Reset\|Resize\|Search\|Select\|Set\|Show\|Skip\|Split\|Step\|Switch\|Undo\|Unlock\|Watch\|Backup\|Checkpoint\|Compare\|Compress\|Convert\|ConvertFrom\|ConvertTo\|Dismount\|Edit\|Expand\|Export\|Group\|Import\|Initialize\|Limit\|Merge\|Out\|Publish\|Restore\|Save\|Sync\|Unpublish\|Update\|Approve\|Assert\|Complete\|Confirm\|Deny\|Disable\|Enable\|Install\|Invoke\|Register\|Request\|Restart\|Resume\|Start\|Stop\|Submit\|Suspend\|Uninstall\|Unregister\|Wait\|Debug\|Measure\|Ping\|Repair\|Resolve\|Test\|Trace\|Connect\|Disconnect\|Read\|Receive\|Send\|Write\|Block\|Grant\|Protect\|Revoke\|Unblock\|Unprotect\|Use\|ForEach\|Sort\|Tee\|Where)+(-)[\\w\\d]+ | +| highlight.js:7:13:7:692 | (Add\|Clear\|Close\|Copy\|Enter\|Exit\|Find\|Format\|Get\|Hide\|Join\|Lock\|Move\|New\|Open\|Optimize\|Pop\|Push\|Redo\|Remove\|Rename\|Reset\|Resize\|Search\|Select\|Set\|Show\|Skip\|Split\|Step\|Switch\|Undo\|Unlock\|Watch\|Backup\|Checkpoint\|Compare\|Compress\|Convert\|ConvertFrom\|ConvertTo\|Dismount\|Edit\|Expand\|Export\|Group\|Import\|Initialize\|Limit\|Merge\|Out\|Publish\|Restore\|Save\|Sync\|Unpublish\|Update\|Approve\|Assert\|Complete\|Confirm\|Deny\|Disable\|Enable\|Install\|Invoke\|Register\|Request\|Restart\|Resume\|Start\|Stop\|Submit\|Suspend\|Uninstall\|Unregister\|Wait\|Debug\|Measure\|Ping\|Repair\|Resolve\|Test\|Trace\|Connect\|Disconnect\|Read\|Receive\|Send\|Write\|Block\|Grant\|Protect\|Revoke\|Unblock\|Unprotect\|Use\|ForEach\|Sort\|Tee\|Where)+ | Strings with many repetitions of 'Pop' can start matching anywhere after the start of the preceeding (Add\|Clear\|Close\|Copy\|Enter\|Exit\|Find\|Format\|Get\|Hide\|Join\|Lock\|Move\|New\|Open\|Optimize\|Pop\|Push\|Redo\|Remove\|Rename\|Reset\|Resize\|Search\|Select\|Set\|Show\|Skip\|Split\|Step\|Switch\|Undo\|Unlock\|Watch\|Backup\|Checkpoint\|Compare\|Compress\|Convert\|ConvertFrom\|ConvertTo\|Dismount\|Edit\|Expand\|Export\|Group\|Import\|Initialize\|Limit\|Merge\|Out\|Publish\|Restore\|Save\|Sync\|Unpublish\|Update\|Approve\|Assert\|Complete\|Confirm\|Deny\|Disable\|Enable\|Install\|Invoke\|Register\|Request\|Restart\|Resume\|Start\|Stop\|Submit\|Suspend\|Uninstall\|Unregister\|Wait\|Debug\|Measure\|Ping\|Repair\|Resolve\|Test\|Trace\|Connect\|Disconnect\|Read\|Receive\|Send\|Write\|Block\|Grant\|Protect\|Revoke\|Unblock\|Unprotect\|Use\|ForEach\|Sort\|Tee\|Where)+(-)[\\w\\d]+ | | highlight.js:14:17:14:52 | [a-z0-9&#*=?@\\\\><:,()$[\\]_.{}!+%^-]+ | Strings with many repetitions of '!' can start matching anywhere after the start of the preceeding ([ ]*[a-z0-9&#*=?@\\\\><:,()$[\\]_.{}!+%^-]+)+ | | highlight.js:18:14:18:16 | .*? | Strings starting with ''' and with many repetitions of ''' can start matching anywhere after the start of the preceeding .*? | | highlight.js:18:20:18:22 | .*? | Strings starting with '"' and with many repetitions of '"' can start matching anywhere after the start of the preceeding .*? | | highlight.js:18:27:18:29 | .*? | Strings starting with '[' and with many repetitions of '[' can start matching anywhere after the start of the preceeding .*? | | highlight.js:18:33:18:69 | [^\\s!"#%&'()*+,.\\/;<=>@\\[\\\\\\]^`{\|}~]+ | Strings with many repetitions of '$' can start matching anywhere after the start of the preceeding .*? | -| highlight.js:19:56:19:61 | [^\\]]+ | Strings starting with '[' and with many repetitions of '.[' can start matching anywhere after the start of the preceeding (\\.\|\\.\\/\|\\/)?(""\|"[^"]+"\|''\|'[^']+'\|\\[\\]\|\\[[^\\]]+\\]\|[^\\s!"#%&'()*+,.\\/;<=>@\\[\\\\\\]^`{\|}~]+)((\\.\|\\/)(""\|"[^"]+"\|''\|'[^']+'\|\\[\\]\|\\[[^\\]]+\\]\|[^\\s!"#%&'()*+,.\\/;<=>@\\[\\\\\\]^`{\|}~]+))* | +| highlight.js:19:56:19:61 | [^\\]]+ | Strings starting with '[' and with many repetitions of '[' can start matching anywhere after the start of the preceeding (\\.\|\\.\\/\|\\/)?(""\|"[^"]+"\|''\|'[^']+'\|\\[\\]\|\\[[^\\]]+\\]\|[^\\s!"#%&'()*+,.\\/;<=>@\\[\\\\\\]^`{\|}~]+)((\\.\|\\/)(""\|"[^"]+"\|''\|'[^']+'\|\\[\\]\|\\[[^\\]]+\\]\|[^\\s!"#%&'()*+,.\\/;<=>@\\[\\\\\\]^`{\|}~]+))* | +| highlight.js:19:141:19:146 | [^\\]]+ | Strings starting with '"".[' and with many repetitions of '$.[' can start matching anywhere after the start of the preceeding (\\.\|\\.\\/\|\\/)?(""\|"[^"]+"\|''\|'[^']+'\|\\[\\]\|\\[[^\\]]+\\]\|[^\\s!"#%&'()*+,.\\/;<=>@\\[\\\\\\]^`{\|}~]+)((\\.\|\\/)(""\|"[^"]+"\|''\|'[^']+'\|\\[\\]\|\\[[^\\]]+\\]\|[^\\s!"#%&'()*+,.\\/;<=>@\\[\\\\\\]^`{\|}~]+))* | | highlight.js:22:12:22:82 | ((decltype\\(auto\\)\|(?:[a-zA-Z_]\\w*::)?[a-zA-Z_]\\w*(?:<.*?>)?)[\\*&\\s]+)+ | Strings with many repetitions of 'A\\t' can start matching anywhere after the start of the preceeding .*? | | highlight.js:22:43:22:45 | \\w* | Strings starting with 'A' and with many repetitions of 'A' can start matching anywhere after the start of the preceeding .*? | | highlight.js:22:66:22:68 | .*? | Strings starting with 'A<' and with many repetitions of 'A<' can start matching anywhere after the start of the preceeding \\w* | @@ -16,8 +17,8 @@ | highlight.js:23:42:23:44 | \\w* | Strings starting with 'A' and with many repetitions of 'A' can start matching anywhere after the start of the preceeding ((decltype\\(auto\\)\|([a-zA-Z_]\\w*::)?[a-zA-Z_]\\w*(<[^<>]+>)?)[\\*&\\s]+)+([a-zA-Z_]\\w*::)?[a-zA-Z]\\w*\\s*\\( | | highlight.js:23:63:23:68 | [^<>]+ | Strings starting with 'A<' and with many repetitions of ';>\\tA<' can start matching anywhere after the start of the preceeding ((decltype\\(auto\\)\|([a-zA-Z_]\\w*::)?[a-zA-Z_]\\w*(<[^<>]+>)?)[\\*&\\s]+)+([a-zA-Z_]\\w*::)?[a-zA-Z]\\w*\\s*\\( | | highlight.js:23:73:23:80 | [\\*&\\s]+ | Strings starting with 'A' and with many repetitions of '\\tA\\t' can start matching anywhere after the start of the preceeding ((decltype\\(auto\\)\|([a-zA-Z_]\\w*::)?[a-zA-Z_]\\w*(<[^<>]+>)?)[\\*&\\s]+)+([a-zA-Z_]\\w*::)?[a-zA-Z]\\w*\\s*\\( | -| highlight.js:26:14:26:34 | (([\\/.])[\\w\\-.\\/=]+)+ | Strings with many repetitions of '.-' can start matching anywhere after the start of the preceeding [\\w\\-.\\/=]+ | -| highlight.js:26:22:26:32 | [\\w\\-.\\/=]+ | Strings with many repetitions of '.-' can start matching anywhere after the start of the preceeding (([\\/.])[\\w\\-.\\/=]+)+ | +| highlight.js:26:14:26:34 | (([\\/.])[\\w\\-.\\/=]+)+ | Strings with many repetitions of '..' can start matching anywhere after the start of the preceeding [\\w\\-.\\/=]+ | +| highlight.js:26:22:26:32 | [\\w\\-.\\/=]+ | Strings with many repetitions of '..' can start matching anywhere after the start of the preceeding (([\\/.])[\\w\\-.\\/=]+)+ | | highlight.js:31:14:31:28 | (?:\\\\.\|[^`\\\\])+ | Strings starting with '`' and with many repetitions of '\\\\`' can start matching anywhere after the start of the preceeding `(?:\\\\.\|[^`\\\\])+` | | highlight.js:38:21:38:23 | \\w* | Strings starting with 'A' and with many repetitions of 'A' can start matching anywhere after the start of the preceeding [a-zA-Z_]\\w*\\([^()]*(\\([^()]*(\\([^()]*\\))*[^()]*\\))*[^()]*\\)\\s*\\{ | | highlight.js:38:54:38:59 | [^()]* | Strings starting with 'A((' and with many repetitions of ''' can start matching anywhere after the start of the preceeding [^()]* | @@ -93,7 +94,6 @@ | polynomial-redos.js:64:14:64:15 | Y* | Strings starting with 'fooY' and with many repetitions of 'Y' can start matching anywhere after the start of the preceeding (K\|Y)+ | | polynomial-redos.js:65:14:65:15 | .* | Strings starting with 'fooY' and with many repetitions of 'K' can start matching anywhere after the start of the preceeding (K\|Y)+ | | polynomial-redos.js:66:9:66:10 | .* | Strings starting with 'K' and with many repetitions of 'K' can start matching anywhere after the start of the preceeding (K\|Y).*X | -| polynomial-redos.js:67:8:67:9 | .* | Strings starting with 'X' and with many repetitions of 'Z' can start matching anywhere after the start of the preceeding [^Y].*X | | polynomial-redos.js:68:8:68:9 | .* | Strings starting with 'X' and with many repetitions of 'X' can start matching anywhere after the start of the preceeding [^Y].*$ | | polynomial-redos.js:69:8:69:9 | .* | Strings starting with 'X' and with many repetitions of 'X' can start matching anywhere after the start of the preceeding [^Y].*$ | | polynomial-redos.js:71:51:71:63 | [?\\x21-\\x7E]* | Strings starting with ',-+' and with many repetitions of '++' can start matching anywhere after the start of the preceeding [A-Za-z0-9+/]+ | @@ -123,7 +123,6 @@ | polynomial-redos.js:111:17:111:19 | \\s* | Strings with many repetitions of '\\t' can start matching anywhere after the start of the preceeding \\s*$ | | polynomial-redos.js:112:17:112:19 | \\s+ | Strings with many repetitions of '\\t' can start matching anywhere after the start of the preceeding \\s+$ | | polynomial-redos.js:114:22:114:24 | \\w* | Strings starting with '5' and with many repetitions of '5' can start matching anywhere after the start of the preceeding \\d* | -| polynomial-redos.js:116:21:116:28 | [\\d\\D]*? | Strings starting with '/*' and with many repetitions of 'a/*' can start matching anywhere after the start of the preceeding \\/\\*[\\d\\D]*?\\*\\/ | | polynomial-redos.js:118:17:118:23 | (#\\d+)+ | Strings with many repetitions of '0' can start matching anywhere after the start of the preceeding \\d+ | | polynomial-redos.js:124:33:124:35 | \\s+ | Strings with many repetitions of '\\t' can start matching anywhere after the start of the preceeding \\s+$ | | polynomial-redos.js:130:21:130:22 | c+ | Strings starting with 'c' and with many repetitions of 'c' can start matching anywhere after the start of the preceeding cc+D | @@ -134,22 +133,26 @@ | regexplib/address.js:27:93:27:95 | \\s* | Strings with many repetitions of '\\t' can start matching anywhere after the start of the preceeding (\\s*(7\|8)(\\d{7}\|\\d{3}(\\-\|\\s{1})\\d{4})\\s*) | | regexplib/address.js:38:39:38:45 | [ 0-9]* | Strings starting with 'po' and with many repetitions of ' ' can start matching anywhere after the start of the preceeding [ \|\\.]* | | regexplib/address.js:51:220:51:222 | \\w+ | Strings starting with 'C/O ' and with many repetitions of '0' can start matching anywhere after the start of the preceeding \\x20* | -| regexplib/address.js:51:331:51:344 | [a-zA-Z0-9\\-]+ | Strings starting with 'C/O 0#' and with many repetitions of '0APT0' can start matching anywhere after the start of the preceeding \\w+ | +| regexplib/address.js:51:331:51:344 | [a-zA-Z0-9\\-]+ | Strings starting with 'C/O 0#' and with many repetitions of 'FL0' can start matching anywhere after the start of the preceeding \\w+ | +| regexplib/address.js:51:399:51:401 | \\s+ | Strings starting with 'C/O 0' and with many repetitions of ' ' can start matching anywhere after the start of the preceeding \\x20* | | regexplib/address.js:51:415:51:419 | \\x20+ | Strings starting with 'C/O 0\\t0' and with many repetitions of ' 0 ' can start matching anywhere after the start of the preceeding \\x20* | +| regexplib/address.js:51:420:51:422 | \\w+ | Strings starting with 'C/O 0\\t0 ' and with many repetitions of '0 0 ' can start matching anywhere after the start of the preceeding \\w+ | | regexplib/address.js:51:616:51:618 | \\w+ | Strings starting with 'C/O 0\\tC/O ' and with many repetitions of '0' can start matching anywhere after the start of the preceeding \\x20* | -| regexplib/address.js:51:727:51:740 | [a-zA-Z0-9\\-]+ | Strings starting with 'C/O 0\\t0 0#' and with many repetitions of '0APT0' can start matching anywhere after the start of the preceeding \\w+ | -| regexplib/address.js:51:796:51:798 | \\s+ | Strings starting with 'C/O 0\\t' and with many repetitions of '\\t\\t' can start matching anywhere after the start of the preceeding \\s+ | +| regexplib/address.js:51:727:51:740 | [a-zA-Z0-9\\-]+ | Strings starting with 'C/O 0\\t0 0#' and with many repetitions of 'FL0' can start matching anywhere after the start of the preceeding \\w+ | +| regexplib/address.js:51:796:51:798 | \\s+ | Strings starting with 'C/O 0\\t' and with many repetitions of ' ' can start matching anywhere after the start of the preceeding \\s+ | | regexplib/address.js:51:803:51:811 | [A-Za-z]+ | Strings starting with 'C/O 0\\t\\t' and with many repetitions of 'A' can start matching anywhere after the start of the preceeding \\w+ | | regexplib/address.js:67:379:67:755 | [a-zA-Z0-9ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝßàáâãäåæçèéêëìíîïñòóôõöøùúûüýÿ\\.\\,\\-\\/\\' ]+ | Strings starting with '#' and with many repetitions of '#' can start matching anywhere after the start of the preceeding [a-zA-Z0-9ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝßàáâãäåæçèéêëìíîïñòóôõöøùúûüýÿ\\.\\,\\-\\/\\']+ | | regexplib/address.js:69:3:69:5 | \\s* | Strings with many repetitions of '\\t' can start matching anywhere after the start of the preceeding (\\s*\\(?0\\d{4}\\)?(\\s*\|-)\\d{3}(\\s*\|-)\\d{3}\\s*) | | regexplib/address.js:69:48:69:50 | \\s* | Strings with many repetitions of '\\t' can start matching anywhere after the start of the preceeding (\\s*\\(?0\\d{3}\\)?(\\s*\|-)\\d{3}(\\s*\|-)\\d{4}\\s*) | | regexplib/address.js:69:93:69:95 | \\s* | Strings with many repetitions of '\\t' can start matching anywhere after the start of the preceeding (\\s*(7\|8)(\\d{7}\|\\d{3}(\\-\|\\s{1})\\d{4})\\s*) | | regexplib/address.js:75:220:75:222 | \\w+ | Strings starting with 'C/O ' and with many repetitions of '0' can start matching anywhere after the start of the preceeding \\x20* | -| regexplib/address.js:75:331:75:344 | [a-zA-Z0-9\\-]+ | Strings starting with 'C/O 0#' and with many repetitions of '0APT0' can start matching anywhere after the start of the preceeding \\w+ | +| regexplib/address.js:75:331:75:344 | [a-zA-Z0-9\\-]+ | Strings starting with 'C/O 0#' and with many repetitions of 'FL0' can start matching anywhere after the start of the preceeding \\w+ | +| regexplib/address.js:75:399:75:401 | \\s+ | Strings starting with 'C/O 0' and with many repetitions of ' ' can start matching anywhere after the start of the preceeding \\x20* | | regexplib/address.js:75:415:75:419 | \\x20+ | Strings starting with 'C/O 0\\t0' and with many repetitions of ' 0 ' can start matching anywhere after the start of the preceeding \\x20* | +| regexplib/address.js:75:420:75:422 | \\w+ | Strings starting with 'C/O 0\\t0 ' and with many repetitions of '0 0 ' can start matching anywhere after the start of the preceeding \\w+ | | regexplib/address.js:75:616:75:618 | \\w+ | Strings starting with 'C/O 0\\tC/O ' and with many repetitions of '0' can start matching anywhere after the start of the preceeding \\x20* | -| regexplib/address.js:75:727:75:740 | [a-zA-Z0-9\\-]+ | Strings starting with 'C/O 0\\t0 0#' and with many repetitions of '0APT0' can start matching anywhere after the start of the preceeding \\w+ | -| regexplib/address.js:75:796:75:798 | \\s+ | Strings starting with 'C/O 0\\t' and with many repetitions of '\\t\\t' can start matching anywhere after the start of the preceeding \\s+ | +| regexplib/address.js:75:727:75:740 | [a-zA-Z0-9\\-]+ | Strings starting with 'C/O 0\\t0 0#' and with many repetitions of 'FL0' can start matching anywhere after the start of the preceeding \\w+ | +| regexplib/address.js:75:796:75:798 | \\s+ | Strings starting with 'C/O 0\\t' and with many repetitions of ' ' can start matching anywhere after the start of the preceeding \\s+ | | regexplib/address.js:75:803:75:811 | [A-Za-z]+ | Strings starting with 'C/O 0\\t\\t' and with many repetitions of 'A' can start matching anywhere after the start of the preceeding \\w+ | | regexplib/address.js:85:15:85:49 | ([0-9]\|[ ]\|[-]\|[\\(]\|[\\)]\|ext.\|[,])+ | Strings with many repetitions of ' ' can start matching anywhere after the start of the preceeding (?([0-9]\|[ ]\|[-]\|[\\(]\|[\\)]\|ext.\|[,])+)([ ]\|[:]\|\\t\|[-])*(?Home\|Office\|Work\|Away\|Fax\|FAX\|Phone) | | regexplib/address.js:85:51:85:67 | ([ ]\|[:]\|\\t\|[-])* | Strings starting with '0' and with many repetitions of ' ' can start matching anywhere after the start of the preceeding ([0-9]\|[ ]\|[-]\|[\\(]\|[\\)]\|ext.\|[,])+ | @@ -163,8 +166,10 @@ | regexplib/email.js:5:24:5:35 | [a-zA-Z0-9]+ | Strings starting with '0' and with many repetitions of '0' can start matching anywhere after the start of the preceeding ([_\\.\\-]?[a-zA-Z0-9]+)* | | regexplib/email.js:5:63:5:74 | [a-zA-Z0-9]+ | Strings starting with '0@0' and with many repetitions of '0' can start matching anywhere after the start of the preceeding [A-Za-z0-9]+ | | regexplib/email.js:8:16:8:49 | [^ \\t\\(\\)\\<\\>@,;\\:\\\\\\"\\.\\[\\]\\r\\n]+ | Strings with many repetitions of '!' can start matching anywhere after the start of the preceeding (?(?:(?:[^ \\t\\(\\)\\<\\>@,;\\:\\\\\\"\\.\\[\\]\\r\\n]+)\|(?:\\"(?:(?:[^\\"\\\\\\r\\n])\|(?:\\\\.))*\\"))(?:\\.(?:(?:[^ \\t\\(\\)\\<\\>@,;\\:\\\\\\"\\.\\[\\]\\r\\n]+)\|(?:\\"(?:(?:[^\\"\\\\\\r\\n])\|(?:\\\\.))*\\")))*)@(?(?:(?:[^ \\t\\(\\)\\<\\>@,;\\:\\\\\\"\\.\\[\\]\\r\\n]+)\|(?:\\[(?:(?:[^\\[\\]\\\\\\r\\n])\|(?:\\\\.))*\\]))(?:\\.(?:(?:[^ \\t\\(\\)\\<\\>@,;\\:\\\\\\"\\.\\[\\]\\r\\n]+)\|(?:\\[(?:(?:[^\\[\\]\\\\\\r\\n])\|(?:\\\\.))*\\])))*) | +| regexplib/email.js:8:57:8:84 | (?:(?:[^\\"\\\\\\r\\n])\|(?:\\\\.))* | Strings starting with '"' and with many repetitions of '\\\\"' can start matching anywhere after the start of the preceeding (?(?:(?:[^ \\t\\(\\)\\<\\>@,;\\:\\\\\\"\\.\\[\\]\\r\\n]+)\|(?:\\"(?:(?:[^\\"\\\\\\r\\n])\|(?:\\\\.))*\\"))(?:\\.(?:(?:[^ \\t\\(\\)\\<\\>@,;\\:\\\\\\"\\.\\[\\]\\r\\n]+)\|(?:\\"(?:(?:[^\\"\\\\\\r\\n])\|(?:\\\\.))*\\")))*)@(?(?:(?:[^ \\t\\(\\)\\<\\>@,;\\:\\\\\\"\\.\\[\\]\\r\\n]+)\|(?:\\[(?:(?:[^\\[\\]\\\\\\r\\n])\|(?:\\\\.))*\\]))(?:\\.(?:(?:[^ \\t\\(\\)\\<\\>@,;\\:\\\\\\"\\.\\[\\]\\r\\n]+)\|(?:\\[(?:(?:[^\\[\\]\\\\\\r\\n])\|(?:\\\\.))*\\])))*) | | regexplib/email.js:8:89:8:174 | (?:\\.(?:(?:[^ \\t\\(\\)\\<\\>@,;\\:\\\\\\"\\.\\[\\]\\r\\n]+)\|(?:\\"(?:(?:[^\\"\\\\\\r\\n])\|(?:\\\\.))*\\")))* | Strings starting with '!' and with many repetitions of '.!' can start matching anywhere after the start of the preceeding (?(?:(?:[^ \\t\\(\\)\\<\\>@,;\\:\\\\\\"\\.\\[\\]\\r\\n]+)\|(?:\\"(?:(?:[^\\"\\\\\\r\\n])\|(?:\\\\.))*\\"))(?:\\.(?:(?:[^ \\t\\(\\)\\<\\>@,;\\:\\\\\\"\\.\\[\\]\\r\\n]+)\|(?:\\"(?:(?:[^\\"\\\\\\r\\n])\|(?:\\\\.))*\\")))*)@(?(?:(?:[^ \\t\\(\\)\\<\\>@,;\\:\\\\\\"\\.\\[\\]\\r\\n]+)\|(?:\\[(?:(?:[^\\[\\]\\\\\\r\\n])\|(?:\\\\.))*\\]))(?:\\.(?:(?:[^ \\t\\(\\)\\<\\>@,;\\:\\\\\\"\\.\\[\\]\\r\\n]+)\|(?:\\[(?:(?:[^\\[\\]\\\\\\r\\n])\|(?:\\\\.))*\\])))*) | | regexplib/email.js:8:100:8:133 | [^ \\t\\(\\)\\<\\>@,;\\:\\\\\\"\\.\\[\\]\\r\\n]+ | Strings starting with '!.' and with many repetitions of '!.!' can start matching anywhere after the start of the preceeding (?(?:(?:[^ \\t\\(\\)\\<\\>@,;\\:\\\\\\"\\.\\[\\]\\r\\n]+)\|(?:\\"(?:(?:[^\\"\\\\\\r\\n])\|(?:\\\\.))*\\"))(?:\\.(?:(?:[^ \\t\\(\\)\\<\\>@,;\\:\\\\\\"\\.\\[\\]\\r\\n]+)\|(?:\\"(?:(?:[^\\"\\\\\\r\\n])\|(?:\\\\.))*\\")))*)@(?(?:(?:[^ \\t\\(\\)\\<\\>@,;\\:\\\\\\"\\.\\[\\]\\r\\n]+)\|(?:\\[(?:(?:[^\\[\\]\\\\\\r\\n])\|(?:\\\\.))*\\]))(?:\\.(?:(?:[^ \\t\\(\\)\\<\\>@,;\\:\\\\\\"\\.\\[\\]\\r\\n]+)\|(?:\\[(?:(?:[^\\[\\]\\\\\\r\\n])\|(?:\\\\.))*\\])))*) | +| regexplib/email.js:8:141:8:168 | (?:(?:[^\\"\\\\\\r\\n])\|(?:\\\\.))* | Strings starting with '!."' and with many repetitions of '\\\\""."' can start matching anywhere after the start of the preceeding (?(?:(?:[^ \\t\\(\\)\\<\\>@,;\\:\\\\\\"\\.\\[\\]\\r\\n]+)\|(?:\\"(?:(?:[^\\"\\\\\\r\\n])\|(?:\\\\.))*\\"))(?:\\.(?:(?:[^ \\t\\(\\)\\<\\>@,;\\:\\\\\\"\\.\\[\\]\\r\\n]+)\|(?:\\"(?:(?:[^\\"\\\\\\r\\n])\|(?:\\\\.))*\\")))*)@(?(?:(?:[^ \\t\\(\\)\\<\\>@,;\\:\\\\\\"\\.\\[\\]\\r\\n]+)\|(?:\\[(?:(?:[^\\[\\]\\\\\\r\\n])\|(?:\\\\.))*\\]))(?:\\.(?:(?:[^ \\t\\(\\)\\<\\>@,;\\:\\\\\\"\\.\\[\\]\\r\\n]+)\|(?:\\[(?:(?:[^\\[\\]\\\\\\r\\n])\|(?:\\\\.))*\\])))*) | | regexplib/email.js:12:2:12:4 | \\w+ | Strings with many repetitions of '0' can start matching anywhere after the start of the preceeding \\w+([-+.]\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*([,;]\\s*\\w+([-+.]\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*)* | | regexplib/email.js:12:5:12:15 | ([-+.]\\w+)* | Strings starting with '0' and with many repetitions of '+0' can start matching anywhere after the start of the preceeding \\w+([-+.]\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*([,;]\\s*\\w+([-+.]\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*)* | | regexplib/email.js:12:11:12:13 | \\w+ | Strings starting with '0+' and with many repetitions of '0+' can start matching anywhere after the start of the preceeding \\w+([-+.]\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*([,;]\\s*\\w+([-+.]\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*)* | @@ -195,12 +200,16 @@ | regexplib/markup.js:2:3:2:7 | [^>]* | Strings starting with '<' and with many repetitions of '<' can start matching anywhere after the start of the preceeding <[^>]*> | | regexplib/markup.js:3:440:3:456 | (\\s(?.+?))* | Strings starting with '.+?))* | +| regexplib/markup.js:5:1525:5:1527 | \\s* | Strings starting with '?'DateLiteral' ?# Per the VB Spec : DateLiteral ::= '#' DateOrTime '#' # ?'DateOrTime' DateValue ?# TimeValue ::= HourValue : MinuteValue 10 ?# Hour 01 - 24 : 60 ?# Minute 01 - 60 : ?# Optional Minute :01 - :60 ' and with many repetitions of ' ' can start matching anywhere after the start of the preceeding \\s* | +| regexplib/markup.js:6:11:6:25 | [\\w\\*\\)\\(\\,\\s]+ | Strings starting with 'SELECT\\t' and with many repetitions of 'SELECT\\t' can start matching anywhere after the start of the preceeding (SELECT\\s[\\w\\*\\)\\(\\,\\s]+\\sFROM\\s[\\w]+) | | regexplib/markup.js:6:99:6:113 | [\\s\\w\\d\\)\\(\\,]* | Strings starting with ' INSERT\\tINTO\\t0' and with many repetitions of '0' can start matching anywhere after the start of the preceeding [\\d\\w]+ | | regexplib/markup.js:7:8:7:23 | (?:\\\\.\|[^\\\\"]*)* | Strings starting with '"!' and with many repetitions of '\\\\"!\\\\a' can start matching anywhere after the start of the preceeding "([^"](?:\\\\.\|[^\\\\"]*)*)" | | regexplib/markup.js:9:6:9:13 | [\\s\\S]*? | Strings starting with ' | | regexplib/markup.js:12:40:12:42 | .*? | Strings starting with ') | | regexplib/markup.js:12:117:12:121 | [^>]* | Strings starting with ']*>) | +| regexplib/markup.js:12:149:12:153 | [^>]* | Strings starting with 'font-family:' and with many repetitions of 'font-family:' can start matching anywhere after the start of the preceeding (font-family:[^>]*[;']) | +| regexplib/markup.js:12:171:12:175 | [^>]* | Strings starting with 'font-size:' and with many repetitions of 'font-size:' can start matching anywhere after the start of the preceeding (font-size:[^>]*[;'])(?-s) | | regexplib/markup.js:13:6:13:12 | [^"']+? | Strings starting with '<' and with many repetitions of '!' can start matching anywhere after the start of the preceeding .*? | | regexplib/markup.js:13:14:13:16 | .+? | Strings starting with '<' and with many repetitions of '!' can start matching anywhere after the start of the preceeding .*? | | regexplib/markup.js:14:13:14:14 | .* | Strings starting with '<' and with many repetitions of 'a' can start matching anywhere after the start of the preceeding .* | @@ -216,7 +225,8 @@ | regexplib/markup.js:20:52:20:53 | .* | Strings with many repetitions of '=color' can start matching anywhere after the start of the preceeding [^>]+ | | regexplib/markup.js:20:155:20:156 | '+ | Strings with many repetitions of '''' can start matching anywhere after the start of the preceeding '+ | | regexplib/markup.js:20:197:20:198 | "+ | Strings with many repetitions of '""' can start matching anywhere after the start of the preceeding "+ | -| regexplib/markup.js:20:274:20:276 | .*? | Strings starting with ']+color.*>) #IF\\/THEN lookahead color in tag (.*?color\\s*?[=\|:]\\s*?) # IF found THEN move ahead ('+\\#*?[\\w\\s]*'+ # CAPTURE ColorName\\/Hex \|"+\\#*?[\\w\\s]*"+ # single or double \|\\#*\\w*\\b) # or no quotes\t.*?> # & move to end of tag \|.*?> # ELSE move to end of Tag ) # Close the If\\/Then lookahead # Use Multiline and IgnoreCase # Replace the matches from RE with MatchEvaluator below: # if m.Groups(1).Value<>"" then # Return "" # else # Return "" # end if | +| regexplib/markup.js:20:245:20:247 | .*? | Strings with many repetitions of 'color: # IF found THEN move ahead "" # single or double # or no quotes\\t' can start matching anywhere after the start of the preceeding .*? | +| regexplib/markup.js:20:274:20:276 | .*? | Strings starting with ']+color.*>) #IF\\/THEN lookahead color in tag (.*?color\\s*?[=\|:]\\s*?) # IF found THEN move ahead ('+\\#*?[\\w\\s]*'+ # CAPTURE ColorName\\/Hex \|"+\\#*?[\\w\\s]*"+ # single or double \|\\#*\\w*\\b) # or no quotes\t.*?> # & move to end of tag \|.*?> # ELSE move to end of Tag ) # Close the If\\/Then lookahead # Use Multiline and IgnoreCase # Replace the matches from RE with MatchEvaluator below: # if m.Groups(1).Value<>"" then # Return "" # else # Return "" # end if | | regexplib/markup.js:24:39:24:41 | \\s+ | Strings starting with '<A' and with many repetitions of '\\t-\\t!=\\t' can start matching anywhere after the start of the preceeding \\s* | | regexplib/markup.js:24:43:24:45 | \\S+ | Strings starting with '<A\\t' and with many repetitions of '-\\t!=' can start matching anywhere after the start of the preceeding \\s* | | regexplib/markup.js:24:48:24:50 | \\s* | Strings starting with '<A\\t!' and with many repetitions of '\\t=-\\t!\\t' can start matching anywhere after the start of the preceeding \\s+ | @@ -225,7 +235,6 @@ | regexplib/markup.js:25:45:25:49 | [^>]* | Strings starting with ']* | Strings starting with '<' and with many repetitions of '<' can start matching anywhere after the start of the preceeding <[^>]*name[\\s]*=[\\s]*"?[^\\w_]*"?[^>]*> | | regexplib/markup.js:27:34:27:38 | [^>]* | Strings starting with ']* | Strings starting with '<' and with many repetitions of ']*)(\\s[^<]*)> | | regexplib/markup.js:37:15:37:19 | [\\w]* | Strings starting with '[0' and with many repetitions of '0' can start matching anywhere after the start of the preceeding \\w+ | @@ -235,7 +244,6 @@ | regexplib/markup.js:43:45:43:49 | [^>]* | Strings starting with ']* | Strings starting with '<' and with many repetitions of '<' can start matching anywhere after the start of the preceeding <[^>]*name[\\s]*=[\\s]*"?[^\\w_]*"?[^>]*> | | regexplib/markup.js:44:34:44:38 | [^>]* | Strings starting with '' and with many repetitions of '' can start matching anywhere after the start of the preceeding [^']*? | | regexplib/markup.js:62:9:62:14 | [^>]*? | Strings starting with '' and with many repetitions of '>;' can start matching anywhere after the start of the preceeding .*? | | regexplib/markup.js:62:57:62:59 | .*? | Strings starting with '' and with many repetitions of '>a' can start matching anywhere after the start of the preceeding .*? | -| regexplib/markup.js:63:70:63:77 | [\\w\\W]*? | Strings with many repetitions of 'a/*' can start matching anywhere after the start of the preceeding (?((?m:^[\\t ]*\\/{2}[^\\n\\r\\v\\f]+[\\n\\r\\v\\f]*){2,})\|(\\/\\*[\\w\\W]*?\\*\\/)) | | regexplib/misc.js:4:36:4:44 | [a-zA-Z]* | Strings starting with 'A' and with many repetitions of 'AA' can start matching anywhere after the start of the preceeding [a-zA-Z]+ | -| regexplib/misc.js:76:2:76:27 | (AUX\|PRN\|NUL\|COM\\d\|LPT\\d)+ | Strings with many repetitions of 'AUX' can start matching anywhere after the start of the preceeding (AUX\|PRN\|NUL\|COM\\d\|LPT\\d)+\\s*$ | +| regexplib/misc.js:76:2:76:27 | (AUX\|PRN\|NUL\|COM\\d\|LPT\\d)+ | Strings with many repetitions of 'NUL' can start matching anywhere after the start of the preceeding (AUX\|PRN\|NUL\|COM\\d\|LPT\\d)+\\s*$ | | regexplib/misc.js:81:31:81:45 | [^a-z\\:\\,\\(\\)]* | Strings starting with '#' and with many repetitions of '#' can start matching anywhere after the start of the preceeding ([A-Zäöü0-9\\/][^a-z\\:\\,\\(\\)]*[A-Zäöü0-9])($\|[\\.\\:\\,\\;\\)\\-\\ \\+]\|s\\b) | | regexplib/misc.js:83:18:83:23 | [0-9]+ | Strings with many repetitions of '0' can start matching anywhere after the start of the preceeding \\d* | | regexplib/misc.js:83:24:83:26 | \\d* | Strings with many repetitions of '0' can start matching anywhere after the start of the preceeding \\d* | @@ -270,7 +278,7 @@ | regexplib/misc.js:95:25:95:26 | .+ | Strings starting with 'at\\t' and with many repetitions of 'at\\ta' can start matching anywhere after the start of the preceeding (at\\s)(?.+)(\\.)(?[^\\.]*)(\\()(?[^\\)]*)(\\))((\\sin\\s)(?.+)(:line )(?[\\d]*))? | | regexplib/misc.js:95:71:95:76 | [^\\)]* | Strings starting with 'at\\ta.(' and with many repetitions of '((' can start matching anywhere after the start of the preceeding .+ | | regexplib/misc.js:95:103:95:104 | .+ | Strings starting with 'at\\ta.()\\tin\\t' and with many repetitions of '()\\tin\\t-' can start matching anywhere after the start of the preceeding .+ | -| regexplib/misc.js:101:52:101:70 | [a-z0-9\\/\\.\\?\\=\\&]* | Strings starting with '".htm' and with many repetitions of '.asp' can start matching anywhere after the start of the preceeding [a-z0-9\\/\\.\\?\\=\\&]* | +| regexplib/misc.js:101:52:101:70 | [a-z0-9\\/\\.\\?\\=\\&]* | Strings starting with '".htm' and with many repetitions of '.htm' can start matching anywhere after the start of the preceeding [a-z0-9\\/\\.\\?\\=\\&]* | | regexplib/misc.js:112:3:112:5 | \\s* | Strings with many repetitions of '\\t' can start matching anywhere after the start of the preceeding (\\s*\\(?0\\d{4}\\)?\\s*\\d{6}\\s*) | | regexplib/misc.js:112:32:112:34 | \\s* | Strings with many repetitions of '\\t' can start matching anywhere after the start of the preceeding (\\s*\\(?0\\d{3}\\)?\\s*\\d{3}\\s*\\d{4}\\s*) | | regexplib/misc.js:114:6:114:8 | \\\|+ | Strings starting with 'a' and with many repetitions of '\|' can start matching anywhere after the start of the preceeding .+ | @@ -281,7 +289,7 @@ | regexplib/misc.js:123:36:123:38 | .*? | Strings starting with '?se[A' and with many repetitions of '?se[Aa' can start matching anywhere after the start of the preceeding (?s)(?:\\e\\[(?:(\\d+);?)*([A-Za-z])(.*?))(?=\\e\\[\|\\z) | | regexplib/misc.js:126:15:126:20 | [a-z]+ | Strings starting with 'a' and with many repetitions of 'aa' can start matching anywhere after the start of the preceeding [a-z]+ | | regexplib/misc.js:141:15:141:19 | [^;]+ | Strings starting with '{\\\\f\\\\' and with many repetitions of '{\\\\f\\\\:' can start matching anywhere after the start of the preceeding (\\{\\\\f\\d*)\\\\([^;]+;) | -| regexplib/misc.js:144:52:144:70 | [a-z0-9\\/\\.\\?\\=\\&]* | Strings starting with '".htm' and with many repetitions of '.asp' can start matching anywhere after the start of the preceeding [a-z0-9\\/\\.\\?\\=\\&]* | +| regexplib/misc.js:144:52:144:70 | [a-z0-9\\/\\.\\?\\=\\&]* | Strings starting with '".htm' and with many repetitions of '.htm' can start matching anywhere after the start of the preceeding [a-z0-9\\/\\.\\?\\=\\&]* | | regexplib/misc.js:148:12:148:18 | [^\\s>]+ | Strings starting with '<' and with many repetitions of ']+(\\s+[^"'=]+(=("[^"]*")\|('[^\\']*')\|([^\\s"'>]*))?)*\\s*\\/?> | | regexplib/misc.js:148:20:148:22 | \\s+ | Strings starting with '' and with many repetitions of 'href=! >;' can start matching anywhere after the start of the preceeding href\\s*=\\s*(?:(?:\\"(?[^\\"]*)\\")\|(?[^\\s*] ))>(?[^<]+)<\\/\\w> | +| regexplib/uri.js:29:2:29:45 | ((http\\:\\/\\/\|https\\:\\/\\/\|ftp\\:\\/\\/)\|(www.))+ | Strings with many repetitions of 'wwwa' can start matching anywhere after the start of the preceeding ((http\\:\\/\\/\|https\\:\\/\\/\|ftp\\:\\/\\/)\|(www.))+(([a-zA-Z0-9\\.-]+\\.[a-zA-Z]{2,4})\|([0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}))(\\/[a-zA-Z0-9%:/-_\\?\\.'~]*)? | +| regexplib/uri.js:29:48:29:62 | [a-zA-Z0-9\\.-]+ | Strings starting with 'wwwa' and with many repetitions of 'www--' can start matching anywhere after the start of the preceeding ((http\\:\\/\\/\|https\\:\\/\\/\|ftp\\:\\/\\/)\|(www.))+ | +| regexplib/uri.js:31:65:31:69 | [^<]+ | Strings starting with 'href=! >' and with many repetitions of 'href="">;' can start matching anywhere after the start of the preceeding href\\s*=\\s*(?:(?:\\"(?<url>[^\\"]*)\\")\|(?<url>[^\\s*] ))>(?<title>[^<]+)<\\/\\w> | | regexplib/uri.js:34:3:34:9 | [^\\=&]+ | Strings with many repetitions of '%' can start matching anywhere after the start of the preceeding ([^\\=&]+)(?<!param1\|param2\|param3)\\=([^\\=&]+)(&)? | | regexplib/uri.js:36:40:36:42 | \\d* | Strings starting with '$1' and with many repetitions of '1' can start matching anywhere after the start of the preceeding [1-9]+ | | regexplib/uri.js:38:20:38:28 | [a-z0-9]+ | Strings starting with 'a' and with many repetitions of '0' can start matching anywhere after the start of the preceeding [a-z]+ | @@ -393,7 +405,8 @@ | regexplib/uri.js:55:20:55:28 | [a-z0-9]+ | Strings starting with 'a' and with many repetitions of '0' can start matching anywhere after the start of the preceeding [a-z]+ | | regexplib/uri.js:55:35:55:40 | [a-z]+ | Strings starting with 'a.' and with many repetitions of 'aa' can start matching anywhere after the start of the preceeding [a-z0-9]+ | | regexplib/uri.js:55:52:55:60 | [a-z0-9]+ | Strings starting with 'a.a' and with many repetitions of '0' can start matching anywhere after the start of the preceeding [a-z]+ | -| regexplib/uri.js:58:2:58:45 | ((http\\:\\/\\/\|https\\:\\/\\/\|ftp\\:\\/\\/)\|(www.))+ | Strings with many repetitions of 'ftp://' can start matching anywhere after the start of the preceeding ((http\\:\\/\\/\|https\\:\\/\\/\|ftp\\:\\/\\/)\|(www.))+(([a-zA-Z0-9\\.-]+\\.[a-zA-Z]{2,4})\|([0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}))(\\/[a-zA-Z0-9%:/-_\\?\\.'~]*)? | +| regexplib/uri.js:58:2:58:45 | ((http\\:\\/\\/\|https\\:\\/\\/\|ftp\\:\\/\\/)\|(www.))+ | Strings with many repetitions of 'wwwa' can start matching anywhere after the start of the preceeding ((http\\:\\/\\/\|https\\:\\/\\/\|ftp\\:\\/\\/)\|(www.))+(([a-zA-Z0-9\\.-]+\\.[a-zA-Z]{2,4})\|([0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}))(\\/[a-zA-Z0-9%:/-_\\?\\.'~]*)? | +| regexplib/uri.js:58:48:58:62 | [a-zA-Z0-9\\.-]+ | Strings starting with 'wwwa' and with many repetitions of 'www--' can start matching anywhere after the start of the preceeding ((http\\:\\/\\/\|https\\:\\/\\/\|ftp\\:\\/\\/)\|(www.))+ | | regexplib/uri.js:64:31:64:36 | [\\w-]+ | Strings with many repetitions of '-' can start matching anywhere after the start of the preceeding [\\w-\\s]* | | regexplib/uri.js:70:16:70:31 | [a-zA-Z0-9\\-\\.]+ | Strings starting with '0' and with many repetitions of '00' can start matching anywhere after the start of the preceeding [a-zA-Z0-9]+ | | regexplib/uri.js:71:75:71:89 | [^\\/\\\\:*?"<>\|]+ | Strings starting with 'A:\\\\!.' and with many repetitions of '!.' can start matching anywhere after the start of the preceeding [^\\/\\\\:*?"<>\|]+ | @@ -475,10 +488,10 @@ | tst.js:254:51:254:53 | \\w* | Strings starting with 'foobarbazfoobarbazfoobarbaz' and with many repetitions of 'foobarbaz' can start matching anywhere after the start of the preceeding \\d* | | tst.js:254:63:254:65 | \\s* | Strings starting with 'foobarbazfoobarbazfoobarbazfoobarbaz' and with many repetitions of 'foobarbazfoobarbazfoobarbazfoobarbazfoobarbazfoobarbaz' can start matching anywhere after the start of the preceeding \\d* | | tst.js:254:75:254:77 | \\d* | Strings starting with 'foobarbazfoobarbazfoobarbazfoobarbazfoobarbaz' and with many repetitions of 'foobarbazfoobarbazfoobarbazfoobarbazfoobarbazfoobarbaz' can start matching anywhere after the start of the preceeding \\s* | -| tst.js:257:14:257:116 | (.thisisagoddamnlongstringforstresstestingthequery\|\\sthisisagoddamnlongstringforstresstestingthequery)* | Strings with many repetitions of '\\tthisisagoddamnlongstringforstresstestingthequery' can start matching anywhere after the start of the preceeding (.thisisagoddamnlongstringforstresstestingthequery\|\\sthisisagoddamnlongstringforstresstestingthequery)*- | +| tst.js:257:14:257:116 | (.thisisagoddamnlongstringforstresstestingthequery\|\\sthisisagoddamnlongstringforstresstestingthequery)* | Strings with many repetitions of 'athisisagoddamnlongstringforstresstestingthequery' can start matching anywhere after the start of the preceeding (.thisisagoddamnlongstringforstresstestingthequery\|\\sthisisagoddamnlongstringforstresstestingthequery)*- | | tst.js:260:14:260:77 | (thisisagoddamnlongstringforstresstestingthequery\|this\\w+query)* | Strings with many repetitions of 'this0query' can start matching anywhere after the start of the preceeding \\w+ | | tst.js:260:68:260:70 | \\w+ | Strings starting with 'this' and with many repetitions of 'this' can start matching anywhere after the start of the preceeding (thisisagoddamnlongstringforstresstestingthequery\|this\\w+query)* | -| tst.js:263:15:263:117 | (thisisagoddamnlongstringforstresstestingthequery\|imanotherbutunrelatedstringcomparedtotheotherstring)* | Strings with many repetitions of 'imanotherbutunrelatedstringcomparedtotheotherstring' can start matching anywhere after the start of the preceeding (thisisagoddamnlongstringforstresstestingthequery\|imanotherbutunrelatedstringcomparedtotheotherstring)*- | +| tst.js:263:15:263:117 | (thisisagoddamnlongstringforstresstestingthequery\|imanotherbutunrelatedstringcomparedtotheotherstring)* | Strings with many repetitions of 'thisisagoddamnlongstringforstresstestingthequery' can start matching anywhere after the start of the preceeding (thisisagoddamnlongstringforstresstestingthequery\|imanotherbutunrelatedstringcomparedtotheotherstring)*- | | tst.js:272:21:272:22 | b+ | Strings with many repetitions of 'b' can start matching anywhere after the start of the preceeding (b+)+ | | tst.js:275:25:275:27 | \\s+ | Strings starting with '<0' and with many repetitions of '\\t0="\\t0="\\t' can start matching anywhere after the start of the preceeding [^"]* | | tst.js:275:28:275:30 | \\w+ | Strings starting with '<0\\t' and with many repetitions of '0="\\t0="\\t' can start matching anywhere after the start of the preceeding [^"]* | @@ -521,7 +534,7 @@ | tst.js:375:15:375:16 | x* | Strings with many repetitions of 'x' can start matching anywhere after the start of the preceeding (x*)+(?=$\|y) | | tst.js:378:16:378:22 | [\\s\\S]* | Strings with many repetitions of 'a' can start matching anywhere after the start of the preceeding ([\\s\\S]*)+(?=$) | | tst.js:379:16:379:22 | [\\s\\S]* | Strings with many repetitions of 'a' can start matching anywhere after the start of the preceeding ([\\s\\S]*)+(?=$\|y) | -| tst.js:381:15:381:24 | (foo\|FOO)* | Strings with many repetitions of 'FOO' can start matching anywhere after the start of the preceeding (foo\|FOO)*bar | +| tst.js:381:15:381:24 | (foo\|FOO)* | Strings with many repetitions of 'foo' can start matching anywhere after the start of the preceeding (foo\|FOO)*bar | | tst.js:382:14:382:23 | (foo\|FOO)* | Strings with many repetitions of 'foo' can start matching anywhere after the start of the preceeding (foo\|FOO)*bar | | tst.js:384:15:384:26 | ([AB]\|[ab])* | Strings with many repetitions of 'A' can start matching anywhere after the start of the preceeding ([AB]\|[ab])*C | | tst.js:385:14:385:25 | ([DE]\|[de])* | Strings with many repetitions of 'd' can start matching anywhere after the start of the preceeding ([DE]\|[de])*F | 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 0892c7e0be5..fa629c55c77 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 @@ -163,8 +163,6 @@ nodes | polynomial-redos.js:65:24:65:30 | tainted | | polynomial-redos.js:66:19:66:25 | tainted | | polynomial-redos.js:66:19:66:25 | tainted | -| polynomial-redos.js:67:18:67:24 | tainted | -| polynomial-redos.js:67:18:67:24 | tainted | | polynomial-redos.js:68:18:68:24 | req.url | | polynomial-redos.js:68:18:68:24 | req.url | | polynomial-redos.js:68:18:68:24 | req.url | @@ -221,8 +219,6 @@ nodes | polynomial-redos.js:112:2:112:8 | tainted | | polynomial-redos.js:114:2:114:8 | tainted | | polynomial-redos.js:114:2:114:8 | tainted | -| polynomial-redos.js:116:2:116:8 | tainted | -| polynomial-redos.js:116:2:116:8 | tainted | | polynomial-redos.js:118:2:118:8 | tainted | | polynomial-redos.js:118:2:118:8 | tainted | | polynomial-redos.js:121:7:121:55 | replaced | @@ -405,8 +401,6 @@ edges | polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:65:24:65:30 | tainted | | polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:66:19:66:25 | tainted | | polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:66:19:66:25 | tainted | -| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:67:18:67:24 | tainted | -| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:67:18:67:24 | tainted | | polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:71:2:71:8 | tainted | | polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:71:2:71:8 | tainted | | polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:73:2:73:8 | tainted | @@ -457,8 +451,6 @@ edges | polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:112:2:112:8 | tainted | | polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:114:2:114:8 | tainted | | polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:114:2:114:8 | tainted | -| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:116:2:116:8 | tainted | -| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:116:2:116:8 | tainted | | polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:118:2:118:8 | tainted | | polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:118:2:118:8 | tainted | | polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:121:18:121:24 | tainted | @@ -551,7 +543,6 @@ edges | polynomial-redos.js:64:3:64:31 | /^foo(K ... ainted) | polynomial-redos.js:5:16:5:32 | req.query.tainted | polynomial-redos.js:64:24:64:30 | tainted | This $@ that depends on $@ may run slow on strings starting with 'fooY' and with many repetitions of 'Y'. | polynomial-redos.js:64:14:64:15 | Y* | regular expression | polynomial-redos.js:5:16:5:32 | req.query.tainted | a user-provided value | | polynomial-redos.js:65:3:65:31 | /^foo(K ... ainted) | polynomial-redos.js:5:16:5:32 | req.query.tainted | polynomial-redos.js:65:24:65:30 | tainted | This $@ that depends on $@ may run slow on strings starting with 'fooY' and with many repetitions of 'K'. | polynomial-redos.js:65:14:65:15 | .* | regular expression | polynomial-redos.js:5:16:5:32 | req.query.tainted | a user-provided value | | polynomial-redos.js:66:3:66:26 | /(K\|Y). ... ainted) | polynomial-redos.js:5:16:5:32 | req.query.tainted | polynomial-redos.js:66:19:66:25 | tainted | This $@ that depends on $@ may run slow on strings starting with 'K' and with many repetitions of 'K'. | polynomial-redos.js:66:9:66:10 | .* | regular expression | polynomial-redos.js:5:16:5:32 | req.query.tainted | a user-provided value | -| polynomial-redos.js:67:3:67:25 | /[^Y].* ... ainted) | polynomial-redos.js:5:16:5:32 | req.query.tainted | polynomial-redos.js:67:18:67:24 | tainted | This $@ that depends on $@ may run slow on strings starting with 'X' and with many repetitions of 'Z'. | polynomial-redos.js:67:8:67:9 | .* | regular expression | polynomial-redos.js:5:16:5:32 | req.query.tainted | a user-provided value | | polynomial-redos.js:69:3:69:26 | /[^Y].* ... q.body) | polynomial-redos.js:69:18:69:25 | req.body | polynomial-redos.js:69:18:69:25 | req.body | This $@ that depends on $@ may run slow on strings starting with 'X' and with many repetitions of 'X'. | polynomial-redos.js:69:8:69:9 | .* | regular expression | polynomial-redos.js:69:18:69:25 | req.body | a user-provided value | | polynomial-redos.js:71:2:71:67 | tainted ... E]*)$/) | polynomial-redos.js:5:16:5:32 | req.query.tainted | polynomial-redos.js:71:2:71:8 | tainted | This $@ that depends on $@ may run slow on strings starting with ',-+' and with many repetitions of '++'. | polynomial-redos.js:71:51:71:63 | [?\\x21-\\x7E]* | regular expression | polynomial-redos.js:5:16:5:32 | req.query.tainted | a user-provided value | | polynomial-redos.js:73:2:73:60 | tainted ... LWP7")) | polynomial-redos.js:5:16:5:32 | req.query.tainted | polynomial-redos.js:73:2:73:8 | tainted | This $@ that depends on $@ may run slow on strings starting with 'MSIE 0.0' and with many repetitions of '0'. | polynomial-redos.js:73:50:73:51 | .* | regular expression | polynomial-redos.js:5:16:5:32 | req.query.tainted | a user-provided value | @@ -579,7 +570,6 @@ edges | polynomial-redos.js:111:2:111:22 | tainted ... /\\s*$/) | polynomial-redos.js:5:16:5:32 | req.query.tainted | polynomial-redos.js:111:2:111:8 | tainted | This $@ that depends on $@ may run slow on strings with many repetitions of '\\t'. | polynomial-redos.js:111:17:111:19 | \\s* | regular expression | polynomial-redos.js:5:16:5:32 | req.query.tainted | a user-provided value | | polynomial-redos.js:112:2:112:22 | tainted ... /\\s+$/) | polynomial-redos.js:5:16:5:32 | req.query.tainted | polynomial-redos.js:112:2:112:8 | tainted | This $@ that depends on $@ may run slow on strings with many repetitions of '\\t'. | polynomial-redos.js:112:17:112:19 | \\s+ | regular expression | polynomial-redos.js:5:16:5:32 | req.query.tainted | a user-provided value | | polynomial-redos.js:114:2:114:27 | tainted ... 5\\w*$/) | polynomial-redos.js:5:16:5:32 | req.query.tainted | polynomial-redos.js:114:2:114:8 | tainted | This $@ that depends on $@ may run slow on strings starting with '5' and with many repetitions of '5'. | polynomial-redos.js:114:22:114:24 | \\w* | regular expression | polynomial-redos.js:5:16:5:32 | req.query.tainted | a user-provided value | -| polynomial-redos.js:116:2:116:35 | tainted ... \\*\\//g) | polynomial-redos.js:5:16:5:32 | req.query.tainted | polynomial-redos.js:116:2:116:8 | tainted | This $@ that depends on $@ may run slow on strings starting with '/*' and with many repetitions of 'a/*'. | polynomial-redos.js:116:21:116:28 | [\\d\\D]*? | regular expression | polynomial-redos.js:5:16:5:32 | req.query.tainted | a user-provided value | | polynomial-redos.js:118:2:118:25 | tainted ... \\d+)+/) | polynomial-redos.js:5:16:5:32 | req.query.tainted | polynomial-redos.js:118:2:118:8 | tainted | This $@ that depends on $@ may run slow on strings with many repetitions of '0'. | polynomial-redos.js:118:17:118:23 | (#\\d+)+ | regular expression | polynomial-redos.js:5:16:5:32 | req.query.tainted | a user-provided value | | polynomial-redos.js:124:12:124:43 | result. ... /g, '') | polynomial-redos.js:5:16:5:32 | req.query.tainted | polynomial-redos.js:124:12:124:17 | result | This $@ that depends on $@ may run slow on strings with many repetitions of '\\t'. | polynomial-redos.js:124:33:124:35 | \\s+ | regular expression | polynomial-redos.js:5:16:5:32 | req.query.tainted | a user-provided value | | polynomial-redos.js:130:2:130:31 | modifie ... g, "b") | polynomial-redos.js:5:16:5:32 | req.query.tainted | polynomial-redos.js:130:2:130:9 | modified | This $@ that depends on $@ may run slow on strings starting with 'c' and with many repetitions of 'c'. | polynomial-redos.js:130:21:130:22 | c+ | regular expression | polynomial-redos.js:5:16:5:32 | req.query.tainted | a user-provided value | diff --git a/shared/regex/codeql/regex/nfa/NfaUtils.qll b/shared/regex/codeql/regex/nfa/NfaUtils.qll index cb5091c40aa..7966b4fd741 100644 --- a/shared/regex/codeql/regex/nfa/NfaUtils.qll +++ b/shared/regex/codeql/regex/nfa/NfaUtils.qll @@ -851,6 +851,10 @@ module Make<RegexTreeViewSig TreeImpl> { * Gets the term represented by this state. */ RegExpTerm getRepr() { result = repr } + + predicate hasLocationInfo(string file, int line, int column, int endline, int endcolumn) { + repr.hasLocationInfo(file, line, column, endline, endcolumn) + } } /** diff --git a/shared/regex/codeql/regex/nfa/SuperlinearBackTracking.qll b/shared/regex/codeql/regex/nfa/SuperlinearBackTracking.qll index d06170502b4..4ae2cab0073 100644 --- a/shared/regex/codeql/regex/nfa/SuperlinearBackTracking.qll +++ b/shared/regex/codeql/regex/nfa/SuperlinearBackTracking.qll @@ -51,16 +51,26 @@ module Make<RegexTreeViewSig TreeImpl> { private State getRootState() { result = mkMatch(any(RegExpRoot r)) } private newtype TStateTuple = - MkStateTuple(State q1, State q2, State q3) { + /** + * A tuple of states `(q1, q2, q3)` in the product automaton that is reachable from `(pivot, pivot, succ)`. + */ + MkStateTuple(State pivot, State succ, State q1, State q2, State q3) { // starts at (pivot, pivot, succ) - isStartLoops(q1, q3) and q1 = q2 + isStartLoops(q1, q3) and + q1 = q2 and + pivot = q1 and + succ = q3 or - step(_, _, _, _, q1, q2, q3) and FeasibleTuple::isFeasibleTuple(q1, q2, q3) + // recurse: any transition out where all 3 edges share a char (and the resulting tuple isn't obviously infeasible) + exists(StateTuple prev | + prev = MkStateTuple(pivot, succ, _, _, _) and + hasCommonStep(prev, _, _, _, q1, q2, q3) and + FeasibleTuple::isFeasibleTuple(pivot, succ, q1, q2, q3) + ) } /** - * A state in the product automaton. - * The product automaton contains 3-tuples of states. + * A state `(q1, q2, q3)` in the product automaton, that is reachable from `(pivot, pivot, succ)`. * * We lazily only construct those states that we are actually * going to need. @@ -72,11 +82,13 @@ module Make<RegexTreeViewSig TreeImpl> { * of the elements matter. */ class StateTuple extends TStateTuple { + State pivot; + State succ; State q1; State q2; State q3; - StateTuple() { this = MkStateTuple(q1, q2, q3) } + StateTuple() { this = MkStateTuple(pivot, succ, q1, q2, q3) } /** * Gest a string representation of this tuple. @@ -88,6 +100,39 @@ module Make<RegexTreeViewSig TreeImpl> { */ pragma[noinline] predicate isTuple(State r1, State r2, State r3) { r1 = q1 and r2 = q2 and r3 = q3 } + + /** + * Gets the first state of the tuple. + */ + State getFirst() { result = q1 } + + /** + * Gets the second state of the tuple. + */ + State getSecond() { result = q2 } + + /** + * Gets the third state of the tuple. + */ + State getThird() { result = q3 } + + /** + * Gets the pivot state. + */ + State getPivot() { result = pivot } + + /** + * Gets the succ state. + */ + State getSucc() { result = succ } + + /** + * Holds if the pivot state has the specified location. + * This location has been chosen arbitrarily, and is only useful for debugging. + */ + predicate hasLocationInfo(string file, int line, int column, int endLine, int endColumn) { + pivot.hasLocationInfo(file, line, column, endLine, endColumn) + } } /** @@ -97,21 +142,36 @@ module Make<RegexTreeViewSig TreeImpl> { */ 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. + * Holds if the tuple `(r1, r2, r3)` might be on path from a start-state `(pivot, pivot, succ)` to an end-state `(pivot, succ, succ)` in the product automaton. */ - pragma[inline] - predicate isFeasibleTuple(State r1, State r2, State r3) { + bindingset[pivot, succ, r1, r2, r3] + pragma[inline_late] + predicate isFeasibleTuple(State pivot, State succ, State r1, State r2, State r3) { + isStartLoops(pivot, succ) and + // r1 can reach the pivot state + reachesBeginning(r1, pivot) and + // r2 and r3 can reach the succ state + reachesEnd(r2, succ) and + reachesEnd(r3, succ) and // 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) + delta+(r2) = r3 + } + + pragma[noinline] + private predicate reachesBeginning(State s, State pivot) { + isStartLoops(pivot, _) and + delta+(s) = pivot + } + + pragma[noinline] + private predicate reachesEnd(State s, State succ) { + isStartLoops(_, succ) and + delta+(s) = succ } /** @@ -129,24 +189,6 @@ module Make<RegexTreeViewSig TreeImpl> { 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)) - } } /** @@ -174,62 +216,25 @@ module Make<RegexTreeViewSig TreeImpl> { /** * Holds if there are transitions from the components of `q` to the corresponding * components of `r` labelled with `s1`, `s2`, and `s3`, respectively. + * Where the edges `s1`, `s2`, and `s3` all share at least one character. */ pragma[nomagic] - private predicate stepHelper( - StateTuple q, InputSymbol s1, InputSymbol s2, InputSymbol s3, StateTuple r - ) { + private 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) + hasCommonStep(q, s1, s2, s3, r1, r2, r3) and + r = + MkStateTuple(pragma[only_bind_out](q.getPivot()), pragma[only_bind_out](q.getSucc()), + pragma[only_bind_out](r1), pragma[only_bind_out](r2), pragma[only_bind_out](r3)) ) } - /** - * Holds if there are transitions from the components of `q` to the corresponding - * components of `r` labelled with `s1`, `s2`, and `s3`, respectively. - * - * Additionally, a heuristic is used to avoid blowups in the case of complex regexps. - * For regular expressions with more than 100 states, we only look at all the characters - * for the transitions out of `q` and only consider transitions that use the lexicographically - * smallest character. - */ - pragma[noinline] - predicate step(StateTuple q, InputSymbol s1, InputSymbol s2, InputSymbol s3, StateTuple r) { - stepHelper(q, s1, s2, s3, r) and - ( - countStates(any(State s | q.isTuple(s, _, _)).getRepr().getRootTerm()) < 100 - or - // arbitrarily pick an edge out of `q` for complex regexps. This is a heuristic to avoid potential blowups. - exists(string char | - char = - min(string str, InputSymbol x1, InputSymbol x2, InputSymbol x3 | - stepHelper(q, x1, x2, x3, _) and str = getAStepChar(x1, x2, x3) - | - str - ) and - char = getAStepChar(s1, s2, s3) - ) - ) - } - - // specialized version of `getAThreewayIntersect` to be used in `step` above. - pragma[noinline] - private string getAStepChar(InputSymbol s1, InputSymbol s2, InputSymbol s3) { - stepHelper(_, s1, s2, s3, _) and result = getAThreewayIntersect(s1, s2, s3) - } - - /** Gets the number of states in the NFA for `root`. This is used to determine a complexity metric used in the `step` predicate above. */ - private int countStates(RegExpTerm root) { - root.isRootTerm() and - result = count(State s | s.getRepr().getRootTerm() = root) - } - /** * Holds if there are transitions from the components of `q` to `r1`, `r2`, and `r3 * labelled with `s1`, `s2`, and `s3`, respectively. + * Where `s1`, `s2`, and `s3` all share at least one character. */ pragma[noopt] - predicate step( + predicate hasCommonStep( 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) | @@ -264,41 +269,59 @@ module Make<RegexTreeViewSig TreeImpl> { 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, _, _) - } + /** Gets a tuple reachable in a forwards exploratory search from the start state `(pivot, pivot, pivot)`. */ + private StateTuple getReachableFromStartStateForwards(State pivot, State succ) { + // base case. + isStartLoops(pivot, succ) and + result = MkStateTuple(pivot, succ, pivot, pivot, succ) + or + // recursive case + exists(StateTuple p | + p = getReachableFromStartStateForwards(pivot, succ) and + step(p, _, _, _, result) + ) + } /** - * A list of tuples of input symbols that describe a path in the product automaton - * starting from some start state. + * Gets a tuple tuple reachable from the end state `(succ, succ, succ)` in a backwards exploratory search. + * Where the end state was reachable from a forwards search from the start state `(pivot, pivot, pivot)`. + * The resulting tuples are exactly those that are on a path from the start state to the end 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 + ")" - ) - } + private StateTuple getARelevantStateTuple(State pivot, State succ) { + // base case. + isStartLoops(pivot, succ) and + result = MkStateTuple(pivot, succ, pivot, succ, succ) and + result = getReachableFromStartStateForwards(pivot, succ) + or + // recursive case + exists(StateTuple p | + p = getARelevantStateTuple(pivot, succ) and + step(result, _, _, _, p) and + pragma[only_bind_out](result) = getReachableFromStartStateForwards(pivot, succ) // was reachable in the forwards pass. + ) } /** * Holds if there exists a transition from `r` to `q` in the product automaton. + * Where `r` and `q` are both on a path from a start state to an end state. * Notice that the arguments are flipped, and thus the direction is backwards. */ pragma[noinline] - predicate tupleDeltaBackwards(StateTuple q, StateTuple r) { step(r, _, _, _, q) } + predicate tupleDeltaBackwards(StateTuple q, StateTuple r) { + step(r, _, _, _, q) and + // `step` ensures that `r` and `q` have the same pivot and succ. + r = getARelevantStateTuple(_, _) and + q = getARelevantStateTuple(_, _) + } /** - * Holds if `tuple` is an end state in our search. + * Holds if `tuple` is an end state in our search, and `tuple` is on a path from a start state to an end state. * That means there exists a pair of loops `(pivot, succ)` such that `tuple = (pivot, succ, succ)`. */ - predicate isEndTuple(StateTuple tuple) { tuple = getAnEndTuple(_, _) } + predicate isEndTuple(StateTuple tuple) { + tuple = getEndTuple(_, _) and + tuple = getARelevantStateTuple(_, _) + } /** * Gets the minimum length of a path from `r` to some an end state `end`. @@ -311,64 +334,128 @@ module Make<RegexTreeViewSig TreeImpl> { 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`. + * Holds if there is a step from `q` to `r` in the product automaton labeled with `s1`, `s2`, and `s3`. + * Where the step is on a path from a start state to an end state. */ - private predicate isReachableFromStartTuple( - State pivot, State succ, StateTuple tuple, Trace trace, int dist + private predicate isStepOnPath( + StateTuple q, InputSymbol s1, InputSymbol s2, InputSymbol s3, StateTuple r ) { - 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) + step(q, s1, s2, s3, r) and + exists(State pivot, State succ, StateTuple end | + end = MkStateTuple(pivot, succ, pivot, succ, succ) and + pragma[only_bind_out](distBackFromEnd(q, end)) = + pragma[only_bind_out](distBackFromEnd(r, end)) + 1 ) } - private predicate isReachableFromStartTuple( - State pivot, State succ, Trace trace, InputSymbol s1, InputSymbol s2, InputSymbol s3, - StateTuple tuple, int dist + /** + * Gets a unique number for a `state`. + * Is used to create an ordering of states and tuples of states. + */ + private int rankState(State state) { + state = + rank[result](State s | + exists(StateTuple tuple | + tuple = getARelevantStateTuple(_, _) and + s = [tuple.getFirst(), tuple.getSecond(), tuple.getThird()] + ) + | + s order by getTermLocationString(s.getRepr()) + ) + } + + /** + * Holds if there is a step from `q` to `r` in the product automaton labeled with `s1`, `s2`, and `s3`. + * Where the step is on a path from a start state to an end state. + * And the step is a uniquely chosen step from out of `q`. + */ + pragma[nomagic] + private predicate isUniqueMinStepOnPath( + StateTuple q, InputSymbol s1, InputSymbol s2, InputSymbol s3, StateTuple r ) { - // base case. - isStartLoops(pivot, succ) and - step(MkStateTuple(pivot, pivot, succ), s1, s2, s3, tuple) and - tuple = MkStateTuple(_, _, _) 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) - ) + isStepOnPath(q, s1, s2, s3, r) and + r = + min(StateTuple cand | + isStepOnPath(q, _, _, _, cand) + | + cand + order by + rankState(cand.getFirst()), rankState(cand.getSecond()), rankState(cand.getThird()) + ) + } + + private newtype TTrace = + Nil(State pivot, State succ) { + isStartLoops(pivot, succ) and + getStartTuple(pivot, succ) = getARelevantStateTuple(pivot, succ) + } or + Step(TTrace prev, StateTuple nextTuple) { + exists(StateTuple prevTuple, State pivot, State succ | + prev = Nil(pivot, succ) and + prevTuple = getStartTuple(pivot, succ) + or + prev = Step(_, prevTuple) + | + isUniqueMinStepOnPath(prevTuple, _, _, _, nextTuple) + ) + } + + /** + * A list of tuples of input symbols that describe a path in the product automaton + * starting from a start state `(pivot, pivot, succ)`. + */ + class Trace extends TTrace { + /** + * Gets a string representation of this Trace that can be used for debug purposes. + */ + string toString() { result = "a trace" } + + /** Gets a trace where the head has been removed. */ + Trace getPrev() { this = Step(result, _) } + + /** Gets the tuple at the head of this trace. */ + StateTuple getTuple() { + this = Step(_, result) + or + exists(State prev, State succ | + this = Nil(prev, succ) and + result = getStartTuple(prev, succ) + ) + } } /** * Gets the tuple `(pivot, succ, succ)` from the product automaton. */ - StateTuple getAnEndTuple(State pivot, State succ) { + StateTuple getEndTuple(State pivot, State succ) { isStartLoops(pivot, succ) and - result = MkStateTuple(pivot, succ, succ) + result = MkStateTuple(pivot, succ, pivot, succ, succ) + } + + /** + * Gets the tuple `(pivot, pivot, succ)` from the product automaton. + */ + StateTuple getStartTuple(State pivot, State succ) { + isStartLoops(pivot, succ) and + result = MkStateTuple(pivot, succ, pivot, pivot, 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) } + CharNode getPrev(CharNode t) { result = t.getPrev() } - /** Holds if `n` is used in `isPumpable`. */ - predicate isARelevantEnd(CharNode n) { - exists(State pivot, State succ | - isReachableFromStartTuple(pivot, succ, getAnEndTuple(pivot, succ), n, _) - ) - } + predicate isARelevantEnd(CharNode n) { n.getTuple() = getEndTuple(_, _) } string getChar(CharNode t) { - exists(InputSymbol s1, InputSymbol s2, InputSymbol s3 | t = Step(s1, s2, s3, _) | - result = getAThreewayIntersect(s1, s2, s3) - ) + result = + min(string c, InputSymbol s1, InputSymbol s2, InputSymbol s3 | + isUniqueMinStepOnPath(t.getPrev().getTuple(), s1, s2, s3, t.getTuple()) and + c = getAThreewayIntersect(s1, s2, s3) + | + c + ) } } @@ -386,8 +473,8 @@ module Make<RegexTreeViewSig TreeImpl> { */ predicate isPumpable(State pivot, State succ, string pump) { exists(StateTuple q, Trace t | - isReachableFromStartTuple(pivot, succ, q, t, _) and - q = getAnEndTuple(pivot, succ) and + q = getEndTuple(pivot, succ) and + q = t.getTuple() and pump = Concretizer<CharTreeImpl>::concretize(t) ) } From b071d3557e52b4185ad8c09f69c6920469cc81a3 Mon Sep 17 00:00:00 2001 From: erik-krogh <erik-krogh@github.com> Date: Wed, 22 Mar 2023 10:04:51 +0100 Subject: [PATCH 278/631] JS/PY/RB: add a worst-case test, that now performs OK --- .../Security/CWE-400/ReDoS/PolynomialBackTracking.expected | 1 + .../Security/CWE-400/ReDoS/PolynomialReDoS.expected | 5 +++++ .../query-tests/Security/CWE-400/ReDoS/polynomial-redos.js | 2 ++ .../CWE-730-PolynomialReDoS/PolynomialBackTracking.expected | 1 + .../CWE-730-PolynomialReDoS/PolynomialReDoS.expected | 1 + .../query-tests/Security/CWE-730-PolynomialReDoS/test.py | 2 +- .../cwe-1333-polynomial-redos/PolynomialReDoS.expected | 3 +++ .../security/cwe-1333-polynomial-redos/lib/index.rb | 2 ++ 8 files changed, 16 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 21aca8719f5..cd239562a46 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 @@ -128,6 +128,7 @@ | polynomial-redos.js:130:21:130:22 | c+ | Strings starting with 'c' and with many repetitions of 'c' can start matching anywhere after the start of the preceeding cc+D | | polynomial-redos.js:133:22:133:23 | f+ | Strings starting with 'f' and with many repetitions of 'f' can start matching anywhere after the start of the preceeding ff+G | | polynomial-redos.js:136:25:136:26 | h+ | Strings starting with 'h' and with many repetitions of 'h' can start matching anywhere after the start of the preceeding hh+I | +| polynomial-redos.js:138:322:138:323 | .* | Strings starting with 'AAAAAAAAAAAAAAAAAAAAAABBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC' and with many repetitions of 'AAAAAAAAAAAAAAAAAAAAAABBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC' can start matching anywhere after the start of the preceeding (AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)C.*X | | regexplib/address.js:27:3:27:5 | \\s* | Strings with many repetitions of '\\t' can start matching anywhere after the start of the preceeding (\\s*\\(?0\\d{4}\\)?(\\s*\|-)\\d{3}(\\s*\|-)\\d{3}\\s*) | | regexplib/address.js:27:48:27:50 | \\s* | Strings with many repetitions of '\\t' can start matching anywhere after the start of the preceeding (\\s*\\(?0\\d{3}\\)?(\\s*\|-)\\d{3}(\\s*\|-)\\d{4}\\s*) | | regexplib/address.js:27:93:27:95 | \\s* | Strings with many repetitions of '\\t' can start matching anywhere after the start of the preceeding (\\s*(7\|8)(\\d{7}\|\\d{3}(\\-\|\\s{1})\\d{4})\\s*) | 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 fa629c55c77..c29feaea831 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 @@ -243,6 +243,8 @@ nodes | polynomial-redos.js:135:21:135:47 | tainted ... /g, "") | | polynomial-redos.js:136:5:136:13 | modified3 | | polynomial-redos.js:136:5:136:13 | modified3 | +| polynomial-redos.js:138:5:138:11 | tainted | +| polynomial-redos.js:138:5:138:11 | tainted | edges | lib/closure.js:3:21:3:21 | x | lib/closure.js:4:16:4:16 | x | | lib/closure.js:3:21:3:21 | x | lib/closure.js:4:16:4:16 | x | @@ -457,6 +459,8 @@ edges | polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:129:17:129:23 | tainted | | polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:132:18:132:24 | tainted | | polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:135:21:135:27 | tainted | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:138:5:138:11 | tainted | +| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:138:5:138:11 | tainted | | polynomial-redos.js:5:16:5:32 | req.query.tainted | polynomial-redos.js:5:6:5:32 | tainted | | polynomial-redos.js:5:16:5:32 | req.query.tainted | polynomial-redos.js:5:6:5:32 | tainted | | polynomial-redos.js:68:18:68:24 | req.url | polynomial-redos.js:68:18:68:24 | req.url | @@ -575,3 +579,4 @@ edges | polynomial-redos.js:130:2:130:31 | modifie ... g, "b") | polynomial-redos.js:5:16:5:32 | req.query.tainted | polynomial-redos.js:130:2:130:9 | modified | This $@ that depends on $@ may run slow on strings starting with 'c' and with many repetitions of 'c'. | polynomial-redos.js:130:21:130:22 | c+ | regular expression | polynomial-redos.js:5:16:5:32 | req.query.tainted | a user-provided value | | polynomial-redos.js:133:2:133:32 | modifie ... g, "b") | polynomial-redos.js:5:16:5:32 | req.query.tainted | polynomial-redos.js:133:2:133:10 | modified2 | This $@ that depends on $@ may run slow on strings starting with 'f' and with many repetitions of 'f'. | polynomial-redos.js:133:22:133:23 | f+ | regular expression | polynomial-redos.js:5:16:5:32 | req.query.tainted | a user-provided value | | polynomial-redos.js:136:5:136:35 | modifie ... g, "b") | polynomial-redos.js:5:16:5:32 | req.query.tainted | polynomial-redos.js:136:5:136:13 | modified3 | This $@ that depends on $@ may run slow on strings starting with 'h' and with many repetitions of 'h'. | polynomial-redos.js:136:25:136:26 | h+ | regular expression | polynomial-redos.js:5:16:5:32 | req.query.tainted | a user-provided value | +| polynomial-redos.js:138:5:138:326 | tainted ... )C.*X/) | polynomial-redos.js:5:16:5:32 | req.query.tainted | polynomial-redos.js:138:5:138:11 | tainted | This $@ that depends on $@ may run slow on strings starting with 'AAAAAAAAAAAAAAAAAAAAAABBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC' and with many repetitions of 'AAAAAAAAAAAAAAAAAAAAAABBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC'. | polynomial-redos.js:138:322:138:323 | .* | regular expression | polynomial-redos.js:5:16:5:32 | req.query.tainted | a user-provided value | diff --git a/javascript/ql/test/query-tests/Security/CWE-400/ReDoS/polynomial-redos.js b/javascript/ql/test/query-tests/Security/CWE-400/ReDoS/polynomial-redos.js index c4a7d38fc6b..fc0ddde66b2 100644 --- a/javascript/ql/test/query-tests/Security/CWE-400/ReDoS/polynomial-redos.js +++ b/javascript/ql/test/query-tests/Security/CWE-400/ReDoS/polynomial-redos.js @@ -134,4 +134,6 @@ app.use(function(req, res) { var modified3 = tainted.replace(/\s+/g, ""); modified3.replace(/hh+I/g, "b"); // NOT OK + + tainted.match(/(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)C.*X/); // NOT OK }); diff --git a/python/ql/test/query-tests/Security/CWE-730-PolynomialReDoS/PolynomialBackTracking.expected b/python/ql/test/query-tests/Security/CWE-730-PolynomialReDoS/PolynomialBackTracking.expected index 21215fc17b3..b24726bf605 100644 --- a/python/ql/test/query-tests/Security/CWE-730-PolynomialReDoS/PolynomialBackTracking.expected +++ b/python/ql/test/query-tests/Security/CWE-730-PolynomialReDoS/PolynomialBackTracking.expected @@ -2,3 +2,4 @@ | test.py:9:14:9:29 | Str | test.py:9:27:9:29 | \\d+ | Strings starting with '0.9' and with many repetitions of '99' can start matching anywhere after the start of the preceeding \\d+ | | test.py:11:22:11:33 | Str | test.py:11:31:11:33 | \\s+ | Strings with many repetitions of ' ' can start matching anywhere after the start of the preceeding \\s+$ | | test.py:18:14:18:25 | Str | test.py:18:23:18:25 | \\s+ | Strings with many repetitions of ' ' can start matching anywhere after the start of the preceeding \\s+$ | +| test.py:20:23:20:274 | Str | test.py:20:273:20:274 | .* | Strings starting with 'AAAAAAAAAAAAAAAAAAAABBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC' and with many repetitions of 'AAAAAAAAAAAAAAAAAAAABBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC' can start matching anywhere after the start of the preceeding (AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)C.*Y | diff --git a/python/ql/test/query-tests/Security/CWE-730-PolynomialReDoS/PolynomialReDoS.expected b/python/ql/test/query-tests/Security/CWE-730-PolynomialReDoS/PolynomialReDoS.expected index ccbc591eb85..39611f1e2af 100644 --- a/python/ql/test/query-tests/Security/CWE-730-PolynomialReDoS/PolynomialReDoS.expected +++ b/python/ql/test/query-tests/Security/CWE-730-PolynomialReDoS/PolynomialReDoS.expected @@ -29,3 +29,4 @@ subpaths | test.py:9:32:9:35 | ControlFlowNode for text | test.py:2:26:2:32 | ControlFlowNode for ImportMember | test.py:9:32:9:35 | ControlFlowNode for text | This $@ that depends on a $@ may run slow on strings starting with '0.9' and with many repetitions of '99'. | test.py:9:27:9:29 | \\d+ | regular expression | test.py:2:26:2:32 | ControlFlowNode for ImportMember | user-provided value | | test.py:12:17:12:20 | ControlFlowNode for text | test.py:2:26:2:32 | ControlFlowNode for ImportMember | test.py:12:17:12:20 | ControlFlowNode for text | This $@ that depends on a $@ may run slow on strings with many repetitions of ' '. | test.py:11:31:11:33 | \\s+ | regular expression | test.py:2:26:2:32 | ControlFlowNode for ImportMember | user-provided value | | test.py:16:24:16:30 | ControlFlowNode for my_text | test.py:2:26:2:32 | ControlFlowNode for ImportMember | test.py:16:24:16:30 | ControlFlowNode for my_text | This $@ that depends on a $@ may run slow on strings with many repetitions of ' '. | test.py:18:23:18:25 | \\s+ | regular expression | test.py:2:26:2:32 | ControlFlowNode for ImportMember | user-provided value | +| test.py:21:18:21:21 | ControlFlowNode for text | test.py:2:26:2:32 | ControlFlowNode for ImportMember | test.py:21:18:21:21 | ControlFlowNode for text | This $@ that depends on a $@ may run slow on strings starting with 'AAAAAAAAAAAAAAAAAAAABBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC' and with many repetitions of 'AAAAAAAAAAAAAAAAAAAABBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC'. | test.py:20:273:20:274 | .* | regular expression | test.py:2:26:2:32 | ControlFlowNode for ImportMember | user-provided value | diff --git a/python/ql/test/query-tests/Security/CWE-730-PolynomialReDoS/test.py b/python/ql/test/query-tests/Security/CWE-730-PolynomialReDoS/test.py index a6b75b4bd38..622fa6803b9 100644 --- a/python/ql/test/query-tests/Security/CWE-730-PolynomialReDoS/test.py +++ b/python/ql/test/query-tests/Security/CWE-730-PolynomialReDoS/test.py @@ -17,6 +17,6 @@ def code_execution(): indirect(r"^\s+|\s+$", text) - reg2 = re.compile(r"(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)C.*") + reg2 = re.compile(r"(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)C.*Y") reg2.sub("", text) # NOT OK diff --git a/ruby/ql/test/query-tests/security/cwe-1333-polynomial-redos/PolynomialReDoS.expected b/ruby/ql/test/query-tests/security/cwe-1333-polynomial-redos/PolynomialReDoS.expected index c428efe29cd..0b59a3e7fc6 100644 --- a/ruby/ql/test/query-tests/security/cwe-1333-polynomial-redos/PolynomialReDoS.expected +++ b/ruby/ql/test/query-tests/security/cwe-1333-polynomial-redos/PolynomialReDoS.expected @@ -36,6 +36,7 @@ edges | PolynomialReDoS.rb:76:35:76:39 | input : | PolynomialReDoS.rb:77:5:77:9 | input | | lib/index.rb:2:11:2:11 | x : | lib/index.rb:4:13:4:13 | x | | lib/index.rb:8:13:8:13 | x : | lib/index.rb:9:15:9:15 | x | +| lib/index.rb:8:13:8:13 | x : | lib/index.rb:11:16:11:16 | x | nodes | PolynomialReDoS.rb:4:12:4:17 | call to params : | semmle.label | call to params : | | PolynomialReDoS.rb:4:12:4:24 | ...[...] : | semmle.label | ...[...] : | @@ -82,6 +83,7 @@ nodes | lib/index.rb:4:13:4:13 | x | semmle.label | x | | lib/index.rb:8:13:8:13 | x : | semmle.label | x : | | lib/index.rb:9:15:9:15 | x | semmle.label | x | +| lib/index.rb:11:16:11:16 | x | semmle.label | x | subpaths #select | PolynomialReDoS.rb:10:5:10:17 | ... =~ ... | PolynomialReDoS.rb:4:12:4:17 | call to params : | PolynomialReDoS.rb:10:5:10:8 | name | This $@ that depends on a $@ may run slow on strings with many repetitions of ' '. | PolynomialReDoS.rb:7:19:7:21 | \\s+ | regular expression | PolynomialReDoS.rb:4:12:4:17 | call to params | user-provided value | @@ -109,3 +111,4 @@ subpaths | PolynomialReDoS.rb:77:5:77:22 | call to gsub | PolynomialReDoS.rb:70:12:70:17 | call to params : | PolynomialReDoS.rb:77:5:77:9 | input | This $@ that depends on a $@ may run slow on strings with many repetitions of ' '. | PolynomialReDoS.rb:72:28:72:30 | \\s+ | regular expression | PolynomialReDoS.rb:70:12:70:17 | call to params | user-provided value | | lib/index.rb:4:13:4:26 | call to match | lib/index.rb:2:11:2:11 | x : | lib/index.rb:4:13:4:13 | x | This $@ that depends on a $@ may run slow on strings with many repetitions of 'a'. | lib/index.rb:4:22:4:23 | a+ | regular expression | lib/index.rb:2:11:2:11 | x | library input | | lib/index.rb:9:15:9:28 | call to match | lib/index.rb:8:13:8:13 | x : | lib/index.rb:9:15:9:15 | x | This $@ that depends on a $@ may run slow on strings with many repetitions of 'a'. | lib/index.rb:9:24:9:25 | a+ | regular expression | lib/index.rb:8:13:8:13 | x | library input | +| lib/index.rb:11:16:11:276 | call to match | lib/index.rb:8:13:8:13 | x : | lib/index.rb:11:16:11:16 | x | This $@ that depends on a $@ may run slow on strings starting with 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC' and with many repetitions of 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC'. | lib/index.rb:11:271:11:272 | .* | regular expression | lib/index.rb:8:13:8:13 | x | library input | diff --git a/ruby/ql/test/query-tests/security/cwe-1333-polynomial-redos/lib/index.rb b/ruby/ql/test/query-tests/security/cwe-1333-polynomial-redos/lib/index.rb index 5fb919ecf67..b6bf9570f4d 100644 --- a/ruby/ql/test/query-tests/security/cwe-1333-polynomial-redos/lib/index.rb +++ b/ruby/ql/test/query-tests/security/cwe-1333-polynomial-redos/lib/index.rb @@ -7,5 +7,7 @@ module Foo protected def baz(x) match = x.match(/a+$/) + + match2 = x.match(/(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)C.*Y$/) end end \ No newline at end of file From 3d9bbd78244e9192725e4fc07c604cda32bb6c5d Mon Sep 17 00:00:00 2001 From: erik-krogh <erik-krogh@github.com> Date: Wed, 22 Mar 2023 10:16:23 +0100 Subject: [PATCH 279/631] ReDoS: fix potential bad mistake caught by QL-for-QL --- shared/regex/codeql/regex/nfa/SuperlinearBackTracking.qll | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/shared/regex/codeql/regex/nfa/SuperlinearBackTracking.qll b/shared/regex/codeql/regex/nfa/SuperlinearBackTracking.qll index 4ae2cab0073..659023b87cd 100644 --- a/shared/regex/codeql/regex/nfa/SuperlinearBackTracking.qll +++ b/shared/regex/codeql/regex/nfa/SuperlinearBackTracking.qll @@ -390,9 +390,11 @@ module Make<RegexTreeViewSig TreeImpl> { getStartTuple(pivot, succ) = getARelevantStateTuple(pivot, succ) } or Step(TTrace prev, StateTuple nextTuple) { - exists(StateTuple prevTuple, State pivot, State succ | - prev = Nil(pivot, succ) and - prevTuple = getStartTuple(pivot, succ) + exists(StateTuple prevTuple | + exists(State pivot, State succ | + prev = Nil(pivot, succ) and + prevTuple = getStartTuple(pivot, succ) + ) or prev = Step(_, prevTuple) | From bdab57b9d3aafd6c2aeff4ada6c0d19c8cd2a1d7 Mon Sep 17 00:00:00 2001 From: Erik Krogh Kristensen <erik-krogh@github.com> Date: Wed, 22 Mar 2023 10:19:48 +0100 Subject: [PATCH 280/631] Update javascript/ql/lib/semmle/javascript/GlobalAccessPaths.qll Co-authored-by: Asger F <asgerf@github.com> --- javascript/ql/lib/semmle/javascript/GlobalAccessPaths.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/javascript/ql/lib/semmle/javascript/GlobalAccessPaths.qll b/javascript/ql/lib/semmle/javascript/GlobalAccessPaths.qll index bf17def1cfa..888f41e0a71 100644 --- a/javascript/ql/lib/semmle/javascript/GlobalAccessPaths.qll +++ b/javascript/ql/lib/semmle/javascript/GlobalAccessPaths.qll @@ -381,7 +381,7 @@ module AccessPath { result.getImmediateDominator() = writeNode.getBasicBlock() ) or - result.getImmediateDominator() = getASuccessorBBThatReadsVar(write) // more manual magic - outlined into a helper predicate. + result.getImmediateDominator() = getASuccessorBBThatReadsVar(write) } } From 4f9117963dcbacc9ebc6791053f589e060180e93 Mon Sep 17 00:00:00 2001 From: Rasmus Wriedt Larsen <rasmuswl@github.com> Date: Thu, 2 Feb 2023 14:25:46 +0100 Subject: [PATCH 281/631] Python: Model `sqlite3.dbapi2` --- python/ql/lib/semmle/python/frameworks/Stdlib.qll | 7 ++++++- python/ql/test/library-tests/frameworks/stdlib/pep249.py | 5 +++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/python/ql/lib/semmle/python/frameworks/Stdlib.qll b/python/ql/lib/semmle/python/frameworks/Stdlib.qll index e559d669248..e79aa270945 100644 --- a/python/ql/lib/semmle/python/frameworks/Stdlib.qll +++ b/python/ql/lib/semmle/python/frameworks/Stdlib.qll @@ -2435,9 +2435,14 @@ private module StdlibPrivate { * against a database. * * See https://devdocs.io/python~3.9/library/sqlite3 + * https://github.com/python/cpython/blob/3.11/Lib/sqlite3/dbapi2.py */ class Sqlite3 extends PEP249::PEP249ModuleApiNode { - Sqlite3() { this = API::moduleImport("sqlite3") } + Sqlite3() { + this = API::moduleImport("sqlite3") + or + this = API::moduleImport("sqlite3").getMember("dbapi2") + } } // --------------------------------------------------------------------------- diff --git a/python/ql/test/library-tests/frameworks/stdlib/pep249.py b/python/ql/test/library-tests/frameworks/stdlib/pep249.py index 3b82e5fb61a..d9f094396ef 100644 --- a/python/ql/test/library-tests/frameworks/stdlib/pep249.py +++ b/python/ql/test/library-tests/frameworks/stdlib/pep249.py @@ -6,3 +6,8 @@ db.execute("some sql", (42,)) # $ getSql="some sql" cursor = db.cursor() cursor.execute("some sql", (42,)) # $ getSql="some sql" + +import sqlite3.dbapi2 +conn = sqlite3.dbapi2.connect() +cursor = conn.cursor() +cursor.execute("some sql") # $ getSql="some sql" From e4db5f9a64bd36ff9ed917797c0087a33976981e Mon Sep 17 00:00:00 2001 From: Rasmus Wriedt Larsen <rasmuswl@github.com> Date: Thu, 2 Feb 2023 14:26:46 +0100 Subject: [PATCH 282/631] Python: Model `asyncpg.connection.connect()` --- python/ql/lib/semmle/python/frameworks/Asyncpg.qll | 1 + python/ql/test/library-tests/frameworks/asyncpg/test.py | 3 +++ 2 files changed, 4 insertions(+) diff --git a/python/ql/lib/semmle/python/frameworks/Asyncpg.qll b/python/ql/lib/semmle/python/frameworks/Asyncpg.qll index 259699eeb0e..8542d04ab14 100644 --- a/python/ql/lib/semmle/python/frameworks/Asyncpg.qll +++ b/python/ql/lib/semmle/python/frameworks/Asyncpg.qll @@ -22,6 +22,7 @@ private module Asyncpg { // * - 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;Member[connection].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;", // diff --git a/python/ql/test/library-tests/frameworks/asyncpg/test.py b/python/ql/test/library-tests/frameworks/asyncpg/test.py index ad99751ba3d..3286c6795e8 100644 --- a/python/ql/test/library-tests/frameworks/asyncpg/test.py +++ b/python/ql/test/library-tests/frameworks/asyncpg/test.py @@ -22,6 +22,9 @@ async def test_connection(): finally: await conn.close() + conn = await asyncpg.connection.connect() + conn.execute("sql") # $ mad-sink[sql-injection]="sql" + async def test_prepared_statement(): conn = await asyncpg.connect() From 170a93cc4fa6c37e1f8b561c08f4de758f5b92b8 Mon Sep 17 00:00:00 2001 From: Rasmus Wriedt Larsen <rasmuswl@github.com> Date: Thu, 2 Feb 2023 14:55:33 +0100 Subject: [PATCH 283/631] Python: Model `cassandra-driver` PyPI package --- .../codeql/reusables/supported-frameworks.rst | 4 +- python/ql/lib/semmle/python/Frameworks.qll | 3 +- .../python/frameworks/CassandraDriver.qll | 61 +++++++++++++++++++ .../cassandra-driver/ConceptsTest.expected | 0 .../cassandra-driver/ConceptsTest.ql | 2 + .../frameworks/cassandra-driver/test.py | 12 ++++ 6 files changed, 79 insertions(+), 3 deletions(-) create mode 100644 python/ql/lib/semmle/python/frameworks/CassandraDriver.qll create mode 100644 python/ql/test/library-tests/frameworks/cassandra-driver/ConceptsTest.expected create mode 100644 python/ql/test/library-tests/frameworks/cassandra-driver/ConceptsTest.ql create mode 100644 python/ql/test/library-tests/frameworks/cassandra-driver/test.py diff --git a/docs/codeql/reusables/supported-frameworks.rst b/docs/codeql/reusables/supported-frameworks.rst index 1c36480e9a7..e06f66ec4b5 100644 --- a/docs/codeql/reusables/supported-frameworks.rst +++ b/docs/codeql/reusables/supported-frameworks.rst @@ -224,6 +224,7 @@ and the CodeQL library pack ``codeql/python-all`` (`changelog <https://github.co aiomysql, Database aiopg, Database asyncpg, Database + cassandra-driver, Database clickhouse-driver, Database cx_Oracle, Database mysql-connector-python, Database @@ -233,9 +234,9 @@ and the CodeQL library pack ``codeql/python-all`` (`changelog <https://github.co oracledb, Database phoenixdb, Database psycopg2, Database - pyodbc, Database pymssql, Database PyMySQL, Database + pyodbc, Database sqlite3, Database Flask-SQLAlchemy, Database ORM peewee, Database ORM @@ -276,4 +277,3 @@ and the CodeQL library pack ``codeql/ruby-all`` (`changelog <https://github.com/ Ruby on Rails, Web framework rubyzip, Compression library typhoeus, HTTP client - diff --git a/python/ql/lib/semmle/python/Frameworks.qll b/python/ql/lib/semmle/python/Frameworks.qll index d9592fcafb3..7ce7cd8804e 100644 --- a/python/ql/lib/semmle/python/Frameworks.qll +++ b/python/ql/lib/semmle/python/Frameworks.qll @@ -3,12 +3,13 @@ */ // If you add modeling of a new framework/library, remember to add it to the docs in -// `docs/codeql/support/reusables/frameworks.rst` +// `docs/codeql/reusables/supported-frameworks.rst` private import semmle.python.frameworks.Aioch private import semmle.python.frameworks.Aiohttp private import semmle.python.frameworks.Aiomysql private import semmle.python.frameworks.Aiopg private import semmle.python.frameworks.Asyncpg +private import semmle.python.frameworks.CassandraDriver private import semmle.python.frameworks.ClickhouseDriver private import semmle.python.frameworks.Cryptodome private import semmle.python.frameworks.Cryptography diff --git a/python/ql/lib/semmle/python/frameworks/CassandraDriver.qll b/python/ql/lib/semmle/python/frameworks/CassandraDriver.qll new file mode 100644 index 00000000000..93fc9723b2e --- /dev/null +++ b/python/ql/lib/semmle/python/frameworks/CassandraDriver.qll @@ -0,0 +1,61 @@ +/** + * Provides classes modeling security-relevant aspects of the `cassandra-driver` PyPI package. + * See https://pypi.org/project/cassandra-driver/ + */ + +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 +private import semmle.python.frameworks.PEP249 + +/** + * Provides models for the `cassandra-driver` PyPI package. + * See https://pypi.org/project/cassandra-driver/ + */ +private module CassandraDriver { + /** + * A cassandra cluster session. + * + * see + * - https://docs.datastax.com/en/developer/python-driver/3.25/api/cassandra/cluster/#cassandra.cluster.Cluster.connect + * - https://docs.datastax.com/en/developer/python-driver/3.25/api/cassandra/cluster/#cassandra.cluster.Session + */ + API::Node session() { + result = + API::moduleImport("cassandra") + .getMember("cluster") + .getMember("Cluster") + .getReturn() + .getMember("connect") + .getReturn() + } + + /** + * see https://docs.datastax.com/en/developer/python-driver/3.25/api/cassandra/cluster/#cassandra.cluster.Session.execute + */ + class CassandraSessionExecuteCall extends SqlExecution::Range, API::CallNode { + CassandraSessionExecuteCall() { this = session().getMember("execute").getACall() } + + override DataFlow::Node getSql() { result = this.getParameter(0, "query").asSink() } + } + + /** + * see https://docs.datastax.com/en/developer/python-driver/3.25/api/cassandra/cluster/#cassandra.cluster.Session.execute_async + */ + class CassandraSessionExecuteAsyncCall extends SqlConstruction::Range, API::CallNode { + CassandraSessionExecuteAsyncCall() { this = session().getMember("execute_async").getACall() } + + override DataFlow::Node getSql() { result = this.getParameter(0, "query").asSink() } + } + + /** + * see https://docs.datastax.com/en/developer/python-driver/3.25/api/cassandra/cluster/#cassandra.cluster.Session.prepare + */ + class CassandraSessionPrepareCall extends SqlConstruction::Range, API::CallNode { + CassandraSessionPrepareCall() { this = session().getMember("prepare").getACall() } + + override DataFlow::Node getSql() { result = this.getParameter(0, "query").asSink() } + } +} diff --git a/python/ql/test/library-tests/frameworks/cassandra-driver/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/cassandra-driver/ConceptsTest.expected new file mode 100644 index 00000000000..e69de29bb2d diff --git a/python/ql/test/library-tests/frameworks/cassandra-driver/ConceptsTest.ql b/python/ql/test/library-tests/frameworks/cassandra-driver/ConceptsTest.ql new file mode 100644 index 00000000000..b557a0bccb6 --- /dev/null +++ b/python/ql/test/library-tests/frameworks/cassandra-driver/ConceptsTest.ql @@ -0,0 +1,2 @@ +import python +import experimental.meta.ConceptsTest diff --git a/python/ql/test/library-tests/frameworks/cassandra-driver/test.py b/python/ql/test/library-tests/frameworks/cassandra-driver/test.py new file mode 100644 index 00000000000..dfcdb133e4b --- /dev/null +++ b/python/ql/test/library-tests/frameworks/cassandra-driver/test.py @@ -0,0 +1,12 @@ +from cassandra.cluster import Cluster + +cluster = Cluster(...) +session = cluster.connect() + +session.execute("sql") # $ getSql="sql" + +future = session.execute_async("sql") # $ constructedSql="sql" +future.result() + +prepared = session.prepare("sql") # $ constructedSql="sql" +session.execute(prepared) # $ SPURIOUS: getSql=prepared From 53d9e4d4eb40240ed4c1086678ccebd448ff1a9d Mon Sep 17 00:00:00 2001 From: erik-krogh <erik-krogh@github.com> Date: Wed, 22 Mar 2023 10:29:30 +0100 Subject: [PATCH 284/631] QL: regen TreeSitter.qll --- ql/ql/src/codeql_ql/ast/internal/TreeSitter.qll | 6 ------ 1 file changed, 6 deletions(-) diff --git a/ql/ql/src/codeql_ql/ast/internal/TreeSitter.qll b/ql/ql/src/codeql_ql/ast/internal/TreeSitter.qll index 1e7bfa71352..d15da37b4f2 100644 --- a/ql/ql/src/codeql_ql/ast/internal/TreeSitter.qll +++ b/ql/ql/src/codeql_ql/ast/internal/TreeSitter.qll @@ -1866,12 +1866,6 @@ module JSON { /** Gets the location of this element. */ final L::Location getLocation() { json_ast_node_info(this, _, _, result) } - predicate hasLocationInfo( - string filepath, int startline, int startcolumn, int endline, int endcolumn - ) { - this.getLocation().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) - } - /** Gets the parent of this element. */ final AstNode getParent() { json_ast_node_info(this, result, _, _) } From 4bc6a0927d8079f00788d808a058119e2a9989d5 Mon Sep 17 00:00:00 2001 From: erik-krogh <erik-krogh@github.com> Date: Wed, 22 Mar 2023 10:45:50 +0100 Subject: [PATCH 285/631] fix queries that relied on the old TreeSitter.qll --- ql/ql/src/codeql_ql/StructuredLogs.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ql/ql/src/codeql_ql/StructuredLogs.qll b/ql/ql/src/codeql_ql/StructuredLogs.qll index f2e6939f7e6..60ea7e014ed 100644 --- a/ql/ql/src/codeql_ql/StructuredLogs.qll +++ b/ql/ql/src/codeql_ql/StructuredLogs.qll @@ -405,7 +405,7 @@ module KindPredicatesLog { or cand.(InLayer).getComputeRecursiveEvent() = recursive ) and - cand.hasLocationInfo(filepath, startline, _, _, _) + cand.getLocation().hasLocationInfo(filepath, startline, _, _, _) | cand order by filepath, startline ) From 5a3ddcfca69290abd6427b5fd7983fdd96eacf70 Mon Sep 17 00:00:00 2001 From: erik-krogh <erik-krogh@github.com> Date: Wed, 22 Mar 2023 10:53:39 +0100 Subject: [PATCH 286/631] QL: disable the consistency check --- ql/ql/src/queries/diagnostics/EmptyConsistencies.ql | 1 + 1 file changed, 1 insertion(+) diff --git a/ql/ql/src/queries/diagnostics/EmptyConsistencies.ql b/ql/ql/src/queries/diagnostics/EmptyConsistencies.ql index 5009e9370fb..85a65fbfdeb 100644 --- a/ql/ql/src/queries/diagnostics/EmptyConsistencies.ql +++ b/ql/ql/src/queries/diagnostics/EmptyConsistencies.ql @@ -58,6 +58,7 @@ where or ModConsistency::noResolve(node) and msg = "ModConsistency::noResolve" ) and + none() and // disabled for now not node.getLocation() .getFile() .getAbsolutePath() From b000b9b5c0d4a3172b70af69fe02a34432e155e8 Mon Sep 17 00:00:00 2001 From: Alex Ford <alexrford@github.com> Date: Wed, 22 Mar 2023 11:12:13 +0000 Subject: [PATCH 287/631] JS: add a missing space in alert message for js/weak-cryptographic-algorithm --- .../ql/src/Security/CWE-327/BrokenCryptoAlgorithm.ql | 2 +- .../Security/CWE-327/BrokenCryptoAlgorithm.expected | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/javascript/ql/src/Security/CWE-327/BrokenCryptoAlgorithm.ql b/javascript/ql/src/Security/CWE-327/BrokenCryptoAlgorithm.ql index 0f7e22b7f57..9826ebefe5f 100644 --- a/javascript/ql/src/Security/CWE-327/BrokenCryptoAlgorithm.ql +++ b/javascript/ql/src/Security/CWE-327/BrokenCryptoAlgorithm.ql @@ -21,4 +21,4 @@ where cfg.hasFlowPath(source, sink) and not source.getNode() instanceof CleartextPasswordExpr // flagged by js/insufficient-password-hash select sink.getNode(), source, sink, "A broken or weak cryptographic algorithm depends on $@.", - source.getNode(), "sensitive data from" + source.getNode().(Source).describe() + source.getNode(), "sensitive data from " + source.getNode().(Source).describe() diff --git a/javascript/ql/test/query-tests/Security/CWE-327/BrokenCryptoAlgorithm.expected b/javascript/ql/test/query-tests/Security/CWE-327/BrokenCryptoAlgorithm.expected index ce03e114f4e..1938b020355 100644 --- a/javascript/ql/test/query-tests/Security/CWE-327/BrokenCryptoAlgorithm.expected +++ b/javascript/ql/test/query-tests/Security/CWE-327/BrokenCryptoAlgorithm.expected @@ -26,8 +26,8 @@ edges | tst.js:19:17:19:24 | password | tst.js:19:17:19:24 | password | | tst.js:22:21:22:30 | secretText | tst.js:22:21:22:30 | secretText | #select -| tst.js:11:17:11:26 | secretText | tst.js:3:18:3:24 | trusted | tst.js:11:17:11:26 | secretText | A broken or weak cryptographic algorithm depends on $@. | tst.js:3:18:3:24 | trusted | sensitive data froman access to trusted | -| tst.js:11:17:11:26 | secretText | tst.js:11:17:11:26 | secretText | tst.js:11:17:11:26 | secretText | A broken or weak cryptographic algorithm depends on $@. | tst.js:11:17:11:26 | secretText | sensitive data froman access to secretText | -| tst.js:17:17:17:25 | o.trusted | tst.js:17:17:17:25 | o.trusted | tst.js:17:17:17:25 | o.trusted | A broken or weak cryptographic algorithm depends on $@. | tst.js:17:17:17:25 | o.trusted | sensitive data froman access to trusted | -| tst.js:22:21:22:30 | secretText | tst.js:3:18:3:24 | trusted | tst.js:22:21:22:30 | secretText | A broken or weak cryptographic algorithm depends on $@. | tst.js:3:18:3:24 | trusted | sensitive data froman access to trusted | -| tst.js:22:21:22:30 | secretText | tst.js:22:21:22:30 | secretText | tst.js:22:21:22:30 | secretText | A broken or weak cryptographic algorithm depends on $@. | tst.js:22:21:22:30 | secretText | sensitive data froman access to secretText | +| tst.js:11:17:11:26 | secretText | tst.js:3:18:3:24 | trusted | tst.js:11:17:11:26 | secretText | A broken or weak cryptographic algorithm depends on $@. | tst.js:3:18:3:24 | trusted | sensitive data from an access to trusted | +| tst.js:11:17:11:26 | secretText | tst.js:11:17:11:26 | secretText | tst.js:11:17:11:26 | secretText | A broken or weak cryptographic algorithm depends on $@. | tst.js:11:17:11:26 | secretText | sensitive data from an access to secretText | +| tst.js:17:17:17:25 | o.trusted | tst.js:17:17:17:25 | o.trusted | tst.js:17:17:17:25 | o.trusted | A broken or weak cryptographic algorithm depends on $@. | tst.js:17:17:17:25 | o.trusted | sensitive data from an access to trusted | +| tst.js:22:21:22:30 | secretText | tst.js:3:18:3:24 | trusted | tst.js:22:21:22:30 | secretText | A broken or weak cryptographic algorithm depends on $@. | tst.js:3:18:3:24 | trusted | sensitive data from an access to trusted | +| tst.js:22:21:22:30 | secretText | tst.js:22:21:22:30 | secretText | tst.js:22:21:22:30 | secretText | A broken or weak cryptographic algorithm depends on $@. | tst.js:22:21:22:30 | secretText | sensitive data from an access to secretText | From bed5eeb3723c41ef1d9845a80176a1736d5e91b8 Mon Sep 17 00:00:00 2001 From: Arthur Baars <aibaars@github.com> Date: Wed, 22 Mar 2023 12:30:15 +0100 Subject: [PATCH 288/631] Apply suggestions from code review --- .github/workflows/ruby-build.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/ruby-build.yml b/.github/workflows/ruby-build.yml index f7314e5d4a5..da064fce148 100644 --- a/.github/workflows/ruby-build.yml +++ b/.github/workflows/ruby-build.yml @@ -272,7 +272,6 @@ jobs: path: ${{ runner.temp }} - name: Unzip Ruby bundle shell: bash - run: unzip -q -d /tmp/ruby-bundle /tmp/codeql-ruby-bundle.zip run: unzip -q -d "$RUNNER_TEMP"/ruby-bundle "$RUNNER_TEMP"/codeql-ruby-bundle.zip - name: Run QL test From 2bba9057a09795c8fa4d85fba2be1677beaa3741 Mon Sep 17 00:00:00 2001 From: erik-krogh <erik-krogh@github.com> Date: Wed, 22 Mar 2023 13:49:33 +0100 Subject: [PATCH 289/631] better callgraph support for global variables --- .../ql/lib/semmle/javascript/GlobalAccessPaths.qll | 5 +++++ .../CWE-079/XssThroughDom/XssThroughDom.expected | 10 ++++++++++ .../Security/CWE-079/XssThroughDom/xss-through-dom.js | 11 +++++++++++ 3 files changed, 26 insertions(+) diff --git a/javascript/ql/lib/semmle/javascript/GlobalAccessPaths.qll b/javascript/ql/lib/semmle/javascript/GlobalAccessPaths.qll index 888f41e0a71..e9828e5bf25 100644 --- a/javascript/ql/lib/semmle/javascript/GlobalAccessPaths.qll +++ b/javascript/ql/lib/semmle/javascript/GlobalAccessPaths.qll @@ -243,6 +243,11 @@ module AccessPath { root.isGlobal() ) or + exists(Assignment assign | + fromReference(assign.getLhs().flow(), root) = result and + node = assign.getRhs().flow() + ) + or exists(FunctionDeclStmt fun | node = DataFlow::valueNode(fun) and result = fun.getIdentifier().(GlobalVarDecl).getName() and diff --git a/javascript/ql/test/query-tests/Security/CWE-079/XssThroughDom/XssThroughDom.expected b/javascript/ql/test/query-tests/Security/CWE-079/XssThroughDom/XssThroughDom.expected index 8a5fb51a44e..83147705499 100644 --- a/javascript/ql/test/query-tests/Security/CWE-079/XssThroughDom/XssThroughDom.expected +++ b/javascript/ql/test/query-tests/Security/CWE-079/XssThroughDom/XssThroughDom.expected @@ -159,6 +159,11 @@ nodes | xss-through-dom.js:141:25:141:27 | src | | xss-through-dom.js:150:24:150:26 | src | | xss-through-dom.js:150:24:150:26 | src | +| xss-through-dom.js:154:25:154:27 | msg | +| xss-through-dom.js:155:27:155:29 | msg | +| xss-through-dom.js:155:27:155:29 | msg | +| xss-through-dom.js:159:34:159:52 | $("textarea").val() | +| xss-through-dom.js:159:34:159:52 | $("textarea").val() | edges | forms.js:8:23:8:28 | values | forms.js:9:31:9:36 | values | | forms.js:8:23:8:28 | values | forms.js:9:31:9:36 | values | @@ -263,6 +268,10 @@ edges | xss-through-dom.js:139:11:139:52 | src | xss-through-dom.js:150:24:150:26 | src | | xss-through-dom.js:139:17:139:52 | documen ... k").src | xss-through-dom.js:139:11:139:52 | src | | xss-through-dom.js:139:17:139:52 | documen ... k").src | xss-through-dom.js:139:11:139:52 | src | +| xss-through-dom.js:154:25:154:27 | msg | xss-through-dom.js:155:27:155:29 | msg | +| xss-through-dom.js:154:25:154:27 | msg | xss-through-dom.js:155:27:155:29 | msg | +| xss-through-dom.js:159:34:159:52 | $("textarea").val() | xss-through-dom.js:154:25:154:27 | msg | +| xss-through-dom.js:159:34:159:52 | $("textarea").val() | xss-through-dom.js:154:25:154:27 | msg | #select | forms.js:9:31:9:40 | values.foo | forms.js:8:23:8:28 | values | forms.js:9:31:9:40 | values.foo | $@ is reinterpreted as HTML without escaping meta-characters. | forms.js:8:23:8:28 | values | DOM text | | forms.js:12:31:12:40 | values.bar | forms.js:11:24:11:29 | values | forms.js:12:31:12:40 | values.bar | $@ is reinterpreted as HTML without escaping meta-characters. | forms.js:11:24:11:29 | values | DOM text | @@ -307,3 +316,4 @@ edges | xss-through-dom.js:140:19:140:21 | src | xss-through-dom.js:139:17:139:52 | documen ... k").src | xss-through-dom.js:140:19:140:21 | src | $@ is reinterpreted as HTML without escaping meta-characters. | xss-through-dom.js:139:17:139:52 | documen ... k").src | DOM text | | xss-through-dom.js:141:25:141:27 | src | xss-through-dom.js:139:17:139:52 | documen ... k").src | xss-through-dom.js:141:25:141:27 | src | $@ is reinterpreted as HTML without escaping meta-characters. | xss-through-dom.js:139:17:139:52 | documen ... k").src | DOM text | | xss-through-dom.js:150:24:150:26 | src | xss-through-dom.js:139:17:139:52 | documen ... k").src | xss-through-dom.js:150:24:150:26 | src | $@ is reinterpreted as HTML without escaping meta-characters. | xss-through-dom.js:139:17:139:52 | documen ... k").src | DOM text | +| xss-through-dom.js:155:27:155:29 | msg | xss-through-dom.js:159:34:159:52 | $("textarea").val() | xss-through-dom.js:155:27:155:29 | msg | $@ is reinterpreted as HTML without escaping meta-characters. | xss-through-dom.js:159:34:159:52 | $("textarea").val() | DOM text | diff --git a/javascript/ql/test/query-tests/Security/CWE-079/XssThroughDom/xss-through-dom.js b/javascript/ql/test/query-tests/Security/CWE-079/XssThroughDom/xss-through-dom.js index 4c488c0dfa3..354194a597d 100644 --- a/javascript/ql/test/query-tests/Security/CWE-079/XssThroughDom/xss-through-dom.js +++ b/javascript/ql/test/query-tests/Security/CWE-079/XssThroughDom/xss-through-dom.js @@ -148,4 +148,15 @@ const cashDom = require("cash-dom"); cashDom("#id").html(DOMPurify ? DOMPurify.sanitize(src) : src); // OK $("<a />", { html: src }).appendTo("#id"); // NOT OK + + function foo() { + window.VeryUniqueXssTestName = { + send: function (msg) { + $("#id").html(msg); // NOT OK + }, + }; + + VeryUniqueXssTestName.send($("textarea").val()); + } + foo() })(); \ No newline at end of file From 635564531c7167a5fc6e29781b7dc7a735208d5c Mon Sep 17 00:00:00 2001 From: Alex Denisov <alexdenisov@github.com> Date: Fri, 17 Mar 2023 11:17:44 +0100 Subject: [PATCH 290/631] Swift: add a query showing successfully extracted files (cherry picked from commit 7c1552730045a9f6a8dfdbaef2c6ffd116c96b44) --- .../src/diagnostics/SuccessfullyExtractedFiles.ql | 15 +++++++++++++++ .../SuccessfullyExtractedFiles.expected | 1 + .../Diagnostics/SuccessfullyExtractedFiles.qlref | 1 + swift/ql/test/query-tests/Diagnostics/error.swift | 2 ++ swift/ql/test/query-tests/Diagnostics/main.swift | 0 5 files changed, 19 insertions(+) create mode 100644 swift/ql/src/diagnostics/SuccessfullyExtractedFiles.ql create mode 100644 swift/ql/test/query-tests/Diagnostics/SuccessfullyExtractedFiles.expected create mode 100644 swift/ql/test/query-tests/Diagnostics/SuccessfullyExtractedFiles.qlref create mode 100644 swift/ql/test/query-tests/Diagnostics/error.swift create mode 100644 swift/ql/test/query-tests/Diagnostics/main.swift diff --git a/swift/ql/src/diagnostics/SuccessfullyExtractedFiles.ql b/swift/ql/src/diagnostics/SuccessfullyExtractedFiles.ql new file mode 100644 index 00000000000..e65734a1d88 --- /dev/null +++ b/swift/ql/src/diagnostics/SuccessfullyExtractedFiles.ql @@ -0,0 +1,15 @@ +/** + * @name Successfully extracted files + * @description Lists all files in the source code directory that were extracted without encountering a problem in the file. + * @kind diagnostic + * @id swift/diagnostics/successfully-extracted-files + * @tags successfully-extracted-files + */ + +import swift + +from File f +where + not exists(CompilerError e | e.getFile() = f) and + f.getBaseName().regexpMatch(".*\\.swift\\z") +select f, "File successfully extracted." diff --git a/swift/ql/test/query-tests/Diagnostics/SuccessfullyExtractedFiles.expected b/swift/ql/test/query-tests/Diagnostics/SuccessfullyExtractedFiles.expected new file mode 100644 index 00000000000..6f7928d5adb --- /dev/null +++ b/swift/ql/test/query-tests/Diagnostics/SuccessfullyExtractedFiles.expected @@ -0,0 +1 @@ +| main.swift:0:0:0:0 | main.swift | File successfully extracted. | diff --git a/swift/ql/test/query-tests/Diagnostics/SuccessfullyExtractedFiles.qlref b/swift/ql/test/query-tests/Diagnostics/SuccessfullyExtractedFiles.qlref new file mode 100644 index 00000000000..5cdfe870715 --- /dev/null +++ b/swift/ql/test/query-tests/Diagnostics/SuccessfullyExtractedFiles.qlref @@ -0,0 +1 @@ +diagnostics/SuccessfullyExtractedFiles.ql diff --git a/swift/ql/test/query-tests/Diagnostics/error.swift b/swift/ql/test/query-tests/Diagnostics/error.swift new file mode 100644 index 00000000000..3f153f68bc3 --- /dev/null +++ b/swift/ql/test/query-tests/Diagnostics/error.swift @@ -0,0 +1,2 @@ +//codeql-extractor-expected-status: 1 +#error("Uh oh") \ No newline at end of file diff --git a/swift/ql/test/query-tests/Diagnostics/main.swift b/swift/ql/test/query-tests/Diagnostics/main.swift new file mode 100644 index 00000000000..e69de29bb2d From 5930499f1d02b3d804aa9feac4b9fd0000291fc2 Mon Sep 17 00:00:00 2001 From: Rasmus Wriedt Larsen <rasmuswl@github.com> Date: Wed, 22 Mar 2023 14:57:08 +0100 Subject: [PATCH 291/631] Python: Add test for missing `.executescript` SQL method --- python/ql/test/library-tests/frameworks/stdlib/pep249.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/python/ql/test/library-tests/frameworks/stdlib/pep249.py b/python/ql/test/library-tests/frameworks/stdlib/pep249.py index d9f094396ef..45c5a496bd7 100644 --- a/python/ql/test/library-tests/frameworks/stdlib/pep249.py +++ b/python/ql/test/library-tests/frameworks/stdlib/pep249.py @@ -6,6 +6,8 @@ db.execute("some sql", (42,)) # $ getSql="some sql" cursor = db.cursor() cursor.execute("some sql", (42,)) # $ getSql="some sql" +cursor.executescript("sql") # $ MISSING: getSql="sql" +cursor.executescript(sql_script="sql") # $ MISSING: getSql="sql" import sqlite3.dbapi2 conn = sqlite3.dbapi2.connect() From ea626a03b64d41a5c9dee070d1c57b8e5c3fd5b3 Mon Sep 17 00:00:00 2001 From: Jami Cogswell <jcogs33@Jamis-MacBook-Pro.local> Date: Mon, 20 Mar 2023 16:45:03 -0400 Subject: [PATCH 292/631] Java: add nativeSQL as summary model --- java/ql/lib/ext/java.sql.model.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/java/ql/lib/ext/java.sql.model.yml b/java/ql/lib/ext/java.sql.model.yml index e5516043989..2d4d9ee4321 100644 --- a/java/ql/lib/ext/java.sql.model.yml +++ b/java/ql/lib/ext/java.sql.model.yml @@ -3,6 +3,7 @@ extensions: pack: codeql/java-all extensible: sinkModel data: + # - ["java.sql", "Connection", True, "nativeSQL", "", "", "Argument[0]", "sql", "manual"] - ["java.sql", "Connection", True, "prepareCall", "", "", "Argument[0]", "sql", "manual"] - ["java.sql", "Connection", True, "prepareStatement", "", "", "Argument[0]", "sql", "manual"] - ["java.sql", "DatabaseMetaData", True, "getColumns", "(String,String,String,String)", "", "Argument[2]", "sql", "ai-generated"] @@ -20,6 +21,7 @@ extensions: pack: codeql/java-all extensible: summaryModel data: + - ["java.sql", "Connection", True, "nativeSQL", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] - ["java.sql", "PreparedStatement", True, "setString", "(int,String)", "", "Argument[1]", "Argument[this]", "value", "manual"] - ["java.sql", "ResultSet", True, "getString", "(String)", "", "Argument[this]", "ReturnValue", "taint", "manual"] - addsTo: From 974f4bc371a31b2a1d4876cff6e3374b72f00442 Mon Sep 17 00:00:00 2001 From: Jami Cogswell <jcogs33@Jamis-MacBook-Pro.local> Date: Mon, 6 Feb 2023 16:20:07 -0500 Subject: [PATCH 293/631] Java: remove nativeSql sink --- java/ql/lib/ext/java.sql.model.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/java/ql/lib/ext/java.sql.model.yml b/java/ql/lib/ext/java.sql.model.yml index 2d4d9ee4321..bdc13f7da24 100644 --- a/java/ql/lib/ext/java.sql.model.yml +++ b/java/ql/lib/ext/java.sql.model.yml @@ -3,7 +3,6 @@ extensions: pack: codeql/java-all extensible: sinkModel data: - # - ["java.sql", "Connection", True, "nativeSQL", "", "", "Argument[0]", "sql", "manual"] - ["java.sql", "Connection", True, "prepareCall", "", "", "Argument[0]", "sql", "manual"] - ["java.sql", "Connection", True, "prepareStatement", "", "", "Argument[0]", "sql", "manual"] - ["java.sql", "DatabaseMetaData", True, "getColumns", "(String,String,String,String)", "", "Argument[2]", "sql", "ai-generated"] From 82daf50ed46fad7c59ad6e29697565f766cb71d4 Mon Sep 17 00:00:00 2001 From: Jami Cogswell <jcogs33@Jamis-MacBook-Pro.local> Date: Mon, 20 Mar 2023 16:45:48 -0400 Subject: [PATCH 294/631] Java: add signature --- java/ql/lib/ext/java.sql.model.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/ql/lib/ext/java.sql.model.yml b/java/ql/lib/ext/java.sql.model.yml index bdc13f7da24..def9f5d1863 100644 --- a/java/ql/lib/ext/java.sql.model.yml +++ b/java/ql/lib/ext/java.sql.model.yml @@ -20,7 +20,7 @@ extensions: pack: codeql/java-all extensible: summaryModel data: - - ["java.sql", "Connection", True, "nativeSQL", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["java.sql", "Connection", True, "nativeSQL", "(String)", "", "Argument[0]", "ReturnValue", "taint", "manual"] - ["java.sql", "PreparedStatement", True, "setString", "(int,String)", "", "Argument[1]", "Argument[this]", "value", "manual"] - ["java.sql", "ResultSet", True, "getString", "(String)", "", "Argument[this]", "ReturnValue", "taint", "manual"] - addsTo: From 5f8d6c3c07f7b3f79cea831ea1ccc855f45b24ba Mon Sep 17 00:00:00 2001 From: Jami Cogswell <jcogs33@Jamis-MacBook-Pro.local> Date: Mon, 20 Mar 2023 16:39:49 -0400 Subject: [PATCH 295/631] Java: add change note --- java/ql/lib/change-notes/2023-03-20-nativesql-summary.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 java/ql/lib/change-notes/2023-03-20-nativesql-summary.md diff --git a/java/ql/lib/change-notes/2023-03-20-nativesql-summary.md b/java/ql/lib/change-notes/2023-03-20-nativesql-summary.md new file mode 100644 index 00000000000..8d350f77bd3 --- /dev/null +++ b/java/ql/lib/change-notes/2023-03-20-nativesql-summary.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* Added a summary model for the `nativeSQL` method of the `java.sql.Connection` interface. From eb43fa26441a441259b2ba5b3a14652db48e636d Mon Sep 17 00:00:00 2001 From: Rasmus Wriedt Larsen <rasmuswl@github.com> Date: Wed, 22 Mar 2023 15:07:03 +0100 Subject: [PATCH 296/631] Python: Make API graph version of PEP249 modeling This will allow us to more easily handle the executescript method, which we'll do in next commit. --- .../lib/semmle/python/frameworks/Django.qll | 4 +- .../lib/semmle/python/frameworks/PEP249.qll | 75 ++++++++++++++++++- .../lib/semmle/python/frameworks/Peewee.qll | 10 +-- 3 files changed, 78 insertions(+), 11 deletions(-) diff --git a/python/ql/lib/semmle/python/frameworks/Django.qll b/python/ql/lib/semmle/python/frameworks/Django.qll index f1300c34a6e..c656ee85fda 100644 --- a/python/ql/lib/semmle/python/frameworks/Django.qll +++ b/python/ql/lib/semmle/python/frameworks/Django.qll @@ -561,8 +561,8 @@ module PrivateDjango { API::Node connection() { result = db().getMember("connection") } /** A `django.db.connection` is a PEP249 compliant DB connection. */ - class DjangoDbConnection extends PEP249::Connection::InstanceSource { - DjangoDbConnection() { this = connection().asSource() } + class DjangoDbConnection extends PEP249::DatabaseConnection { + DjangoDbConnection() { this = connection() } } // ------------------------------------------------------------------------- diff --git a/python/ql/lib/semmle/python/frameworks/PEP249.qll b/python/ql/lib/semmle/python/frameworks/PEP249.qll index 594c3e938e2..b365cb83dc1 100644 --- a/python/ql/lib/semmle/python/frameworks/PEP249.qll +++ b/python/ql/lib/semmle/python/frameworks/PEP249.qll @@ -22,6 +22,67 @@ module PEP249 { override string toString() { result = this.(API::Node).toString() } } + /** + * An API graph node representing a database connection. + */ + abstract class DatabaseConnection extends API::Node { + /** Gets a string representation of this element. */ + override string toString() { result = this.(API::Node).toString() } + } + + private class DefaultDatabaseConnection extends DatabaseConnection { + DefaultDatabaseConnection() { + this = any(PEP249ModuleApiNode mod).getMember("connect").getReturn() + } + } + + /** + * An API graph node representing a database cursor. + */ + abstract class DatabaseCursor extends API::Node { + /** Gets a string representation of this element. */ + override string toString() { result = this.(API::Node).toString() } + } + + private class DefaultDatabaseCursor extends DatabaseCursor { + DefaultDatabaseCursor() { this = any(DatabaseConnection conn).getMember("cursor").getReturn() } + } + + private string getSqlKwargName() { + result in ["sql", "statement", "operation", "query", "query_string"] + } + + /** + * A call to `execute` or `executemany` method on a database cursor or a connection. + * + * See + * - https://peps.python.org/pep-0249/#execute + * - https://peps.python.org/pep-0249/#executemany + * + * 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 ExecuteMethodCall extends SqlExecution::Range, API::CallNode { + ExecuteMethodCall() { + exists(API::Node start | + start instanceof DatabaseCursor or start instanceof DatabaseConnection + | + this = start.getMember(["execute", "executemany"]).getACall() + ) + } + + override DataFlow::Node getSql() { + result in [this.getArg(0), this.getArgByName(getSqlKwargName()),] + } + } + + // --------------------------------------------------------------------------- + // old impl + // --------------------------------------------------------------------------- + // the goal is to deprecate it in favour of the API graph version, but currently this + // requires a rewrite of the Peewee modeling, which depends on rewriting the + // instance/instance-source stuff to use API graphs instead. + // so is postponed for now. /** Gets a reference to the `connect` function of a module that implements PEP 249. */ DataFlow::Node connect() { result = any(PEP249ModuleApiNode a).getMember("connect").getAValueReachableFromSource() @@ -147,7 +208,10 @@ module PEP249 { * 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() } + ExecuteCall() { + this.getFunction() = execute() and + not this instanceof ExecuteMethodCall + } override DataFlow::Node getSql() { result in [this.getArg(0), this.getArgByName("sql")] } } @@ -170,8 +234,13 @@ module PEP249 { * 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() } + ExecutemanyCall() { + this.getFunction() = executemany() and + not this instanceof ExecuteMethodCall + } - override DataFlow::Node getSql() { result in [this.getArg(0), this.getArgByName("sql")] } + override DataFlow::Node getSql() { + result in [this.getArg(0), this.getArgByName(getSqlKwargName())] + } } } diff --git a/python/ql/lib/semmle/python/frameworks/Peewee.qll b/python/ql/lib/semmle/python/frameworks/Peewee.qll index 1179371be76..f923b463b3e 100644 --- a/python/ql/lib/semmle/python/frameworks/Peewee.qll +++ b/python/ql/lib/semmle/python/frameworks/Peewee.qll @@ -163,11 +163,9 @@ private module Peewee { * A call to the `connection` method on a `peewee.Database` instance. * https://docs.peewee-orm.com/en/latest/peewee/api.html#Database.connection. */ - class PeeweeDatabaseConnectionCall extends PEP249::Connection::InstanceSource, - DataFlow::CallCfgNode - { + class PeeweeDatabaseConnectionCall extends PEP249::DatabaseConnection { PeeweeDatabaseConnectionCall() { - this = Database::instance().getMember("connection").getACall() + this = Database::instance().getMember("connection").getReturn() } } @@ -175,8 +173,8 @@ private module Peewee { * A call to the `cursor` method on a `peewee.Database` instance. * https://docs.peewee-orm.com/en/latest/peewee/api.html#Database.cursor. */ - class PeeweeDatabaseCursorCall extends PEP249::Cursor::InstanceSource, DataFlow::CallCfgNode { - PeeweeDatabaseCursorCall() { this = Database::instance().getMember("cursor").getACall() } + class PeeweeDatabaseCursorCall extends PEP249::DatabaseCursor { + PeeweeDatabaseCursorCall() { this = Database::instance().getMember("cursor").getReturn() } } /** From 2b4ebf7377bbd51a863da82b4dbad23bf3a6ca21 Mon Sep 17 00:00:00 2001 From: Rasmus Wriedt Larsen <rasmuswl@github.com> Date: Wed, 22 Mar 2023 15:08:53 +0100 Subject: [PATCH 297/631] Python: Add support for `.executescript` --- python/ql/lib/semmle/python/frameworks/PEP249.qll | 7 ++++--- python/ql/test/library-tests/frameworks/stdlib/pep249.py | 4 ++-- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/python/ql/lib/semmle/python/frameworks/PEP249.qll b/python/ql/lib/semmle/python/frameworks/PEP249.qll index b365cb83dc1..c385739ad40 100644 --- a/python/ql/lib/semmle/python/frameworks/PEP249.qll +++ b/python/ql/lib/semmle/python/frameworks/PEP249.qll @@ -49,11 +49,12 @@ module PEP249 { } private string getSqlKwargName() { - result in ["sql", "statement", "operation", "query", "query_string"] + result in ["sql", "statement", "operation", "query", "query_string", "sql_script"] } /** - * A call to `execute` or `executemany` method on a database cursor or a connection. + * A call to an execute method on a database cursor or a connection, such as `execute` + * or `executemany`. * * See * - https://peps.python.org/pep-0249/#execute @@ -67,7 +68,7 @@ module PEP249 { exists(API::Node start | start instanceof DatabaseCursor or start instanceof DatabaseConnection | - this = start.getMember(["execute", "executemany"]).getACall() + this = start.getMember(["execute", "executemany", "executescript"]).getACall() ) } diff --git a/python/ql/test/library-tests/frameworks/stdlib/pep249.py b/python/ql/test/library-tests/frameworks/stdlib/pep249.py index 45c5a496bd7..6f601f5b6c2 100644 --- a/python/ql/test/library-tests/frameworks/stdlib/pep249.py +++ b/python/ql/test/library-tests/frameworks/stdlib/pep249.py @@ -6,8 +6,8 @@ db.execute("some sql", (42,)) # $ getSql="some sql" cursor = db.cursor() cursor.execute("some sql", (42,)) # $ getSql="some sql" -cursor.executescript("sql") # $ MISSING: getSql="sql" -cursor.executescript(sql_script="sql") # $ MISSING: getSql="sql" +cursor.executescript("sql") # $ getSql="sql" +cursor.executescript(sql_script="sql") # $ getSql="sql" import sqlite3.dbapi2 conn = sqlite3.dbapi2.connect() From 9975facf9d200693dd7ae41fe3a7643e01a4901d Mon Sep 17 00:00:00 2001 From: Rasmus Wriedt Larsen <rasmuswl@github.com> Date: Wed, 22 Mar 2023 15:44:28 +0100 Subject: [PATCH 298/631] Python: Make asyncio version of PEP249 modeling library so it's also easy to modeling asyncio libraries Also ports aiomysql/aiopg to use this new modeling --- .../lib/semmle/python/frameworks/Aiomysql.qll | 53 ++++-------- .../ql/lib/semmle/python/frameworks/Aiopg.qll | 53 ++++-------- .../lib/semmle/python/frameworks/PEP249.qll | 80 ++++++++++++++++++- 3 files changed, 111 insertions(+), 75 deletions(-) diff --git a/python/ql/lib/semmle/python/frameworks/Aiomysql.qll b/python/ql/lib/semmle/python/frameworks/Aiomysql.qll index 3d43c13b91a..d5ac942506e 100644 --- a/python/ql/lib/semmle/python/frameworks/Aiomysql.qll +++ b/python/ql/lib/semmle/python/frameworks/Aiomysql.qll @@ -9,11 +9,10 @@ private import python private import semmle.python.dataflow.new.DataFlow private import semmle.python.Concepts private import semmle.python.ApiGraphs +private import semmle.python.frameworks.PEP249 /** Provides models for the `aiomysql` PyPI package. */ private module Aiomysql { - private import semmle.python.internal.Awaited - /** * Gets a `ConnectionPool` that is created when the result of `aiomysql.create_pool()` is awaited. * See https://aiomysql.readthedocs.io/en/stable/pool.html @@ -23,49 +22,29 @@ private module Aiomysql { } /** - * Gets a `Connection` that is created when + * A Connection that is created when * - the result of `aiomysql.connect()` is awaited. * - the result of calling `acquire` on a `ConnectionPool` is awaited. - * See https://aiomysql.readthedocs.io/en/stable/connection.html#connection + * See + * - https://aiomysql.readthedocs.io/en/stable/connection.html#connection + * - https://aiomysql.readthedocs.io/en/stable/pool.html#Pool.acquire */ - API::Node connection() { - result = API::moduleImport("aiomysql").getMember("connect").getReturn().getAwaited() - or - result = connectionPool().getMember("acquire").getReturn().getAwaited() + class AiomysqlConnection extends PEP249::AsyncDatabaseConnection { + AiomysqlConnection() { + this = API::moduleImport("aiomysql").getMember("connect").getReturn().getAwaited() + or + this = connectionPool().getMember("acquire").getReturn().getAwaited() + } } /** - * Gets a `Cursor` that is created when + * An additional cursor, that is created when * - the result of calling `cursor` on a `ConnectionPool` is awaited. - * - the result of calling `cursor` on a `Connection` is awaited. - * See https://aiomysql.readthedocs.io/en/stable/cursors.html + * See + * - https://aiomysql.readthedocs.io/en/stable/pool.html##Pool.cursor */ - API::Node cursor() { - result = connectionPool().getMember("cursor").getReturn().getAwaited() - or - result = connection().getMember("cursor").getReturn().getAwaited() - } - - /** - * A query. Calling `execute` on a `Cursor` constructs a query. - * See https://aiomysql.readthedocs.io/en/stable/cursors.html#Cursor.execute - */ - class CursorExecuteCall extends SqlConstruction::Range, API::CallNode { - CursorExecuteCall() { this = cursor().getMember("execute").getACall() } - - override DataFlow::Node getSql() { result = this.getParameter(0, "operation").asSink() } - } - - /** - * An awaited query. Awaiting the result of calling `execute` executes the query. - * See https://aiomysql.readthedocs.io/en/stable/cursors.html#Cursor.execute - */ - class AwaitedCursorExecuteCall extends SqlExecution::Range { - CursorExecuteCall executeCall; - - AwaitedCursorExecuteCall() { this = executeCall.getReturn().getAwaited().asSource() } - - override DataFlow::Node getSql() { result = executeCall.getSql() } + class AiomysqlCursor extends PEP249::AsyncDatabaseCursor { + AiomysqlCursor() { this = connectionPool().getMember("cursor").getReturn().getAwaited() } } /** diff --git a/python/ql/lib/semmle/python/frameworks/Aiopg.qll b/python/ql/lib/semmle/python/frameworks/Aiopg.qll index 979f7edb94f..e2fdfd1638d 100644 --- a/python/ql/lib/semmle/python/frameworks/Aiopg.qll +++ b/python/ql/lib/semmle/python/frameworks/Aiopg.qll @@ -9,11 +9,10 @@ private import python private import semmle.python.dataflow.new.DataFlow private import semmle.python.Concepts private import semmle.python.ApiGraphs +private import semmle.python.frameworks.PEP249 /** Provides models for the `aiopg` PyPI package. */ private module Aiopg { - private import semmle.python.internal.Awaited - /** * Gets a `ConnectionPool` that is created when the result of `aiopg.create_pool()` is awaited. * See https://aiopg.readthedocs.io/en/stable/core.html#pool @@ -23,49 +22,29 @@ private module Aiopg { } /** - * Gets a `Connection` that is created when + * A Connection that is created when * - the result of `aiopg.connect()` is awaited. * - the result of calling `acquire` on a `ConnectionPool` is awaited. - * See https://aiopg.readthedocs.io/en/stable/core.html#connection + * See + * - https://aiopg.readthedocs.io/en/stable/core.html#connection + * - https://aiopg.readthedocs.io/en/stable/core.html#aiopg.Pool.acquire */ - API::Node connection() { - result = API::moduleImport("aiopg").getMember("connect").getReturn().getAwaited() - or - result = connectionPool().getMember("acquire").getReturn().getAwaited() + class AiopgConnection extends PEP249::AsyncDatabaseConnection { + AiopgConnection() { + this = API::moduleImport("aiopg").getMember("connect").getReturn().getAwaited() + or + this = connectionPool().getMember("acquire").getReturn().getAwaited() + } } /** - * Gets a `Cursor` that is created when + * An additional cursor, that is created when * - the result of calling `cursor` on a `ConnectionPool` is awaited. - * - the result of calling `cursor` on a `Connection` is awaited. - * See https://aiopg.readthedocs.io/en/stable/core.html#cursor + * See + * - https://aiopg.readthedocs.io/en/stable/core.html#aiopg.Pool.cursor */ - API::Node cursor() { - result = connectionPool().getMember("cursor").getReturn().getAwaited() - or - result = connection().getMember("cursor").getReturn().getAwaited() - } - - /** - * A query. Calling `execute` on a `Cursor` constructs a query. - * See https://aiopg.readthedocs.io/en/stable/core.html#aiopg.Cursor.execute - */ - class CursorExecuteCall extends SqlConstruction::Range, API::CallNode { - CursorExecuteCall() { this = cursor().getMember("execute").getACall() } - - override DataFlow::Node getSql() { result = this.getParameter(0, "operation").asSink() } - } - - /** - * An awaited query. Awaiting the result of calling `execute` executes the query. - * See https://aiopg.readthedocs.io/en/stable/core.html#aiopg.Cursor.execute - */ - class AwaitedCursorExecuteCall extends SqlExecution::Range { - CursorExecuteCall execute; - - AwaitedCursorExecuteCall() { this = execute.getReturn().getAwaited().asSource() } - - override DataFlow::Node getSql() { result = execute.getSql() } + class AiopgCursor extends PEP249::AsyncDatabaseCursor { + AiopgCursor() { this = connectionPool().getMember("cursor").getReturn().getAwaited() } } /** diff --git a/python/ql/lib/semmle/python/frameworks/PEP249.qll b/python/ql/lib/semmle/python/frameworks/PEP249.qll index c385739ad40..30617e88d55 100644 --- a/python/ql/lib/semmle/python/frameworks/PEP249.qll +++ b/python/ql/lib/semmle/python/frameworks/PEP249.qll @@ -52,6 +52,8 @@ module PEP249 { result in ["sql", "statement", "operation", "query", "query_string", "sql_script"] } + private string getExecuteMethodName() { result in ["execute", "executemany", "executescript"] } + /** * A call to an execute method on a database cursor or a connection, such as `execute` * or `executemany`. @@ -68,7 +70,7 @@ module PEP249 { exists(API::Node start | start instanceof DatabaseCursor or start instanceof DatabaseConnection | - this = start.getMember(["execute", "executemany", "executescript"]).getACall() + this = start.getMember(getExecuteMethodName()).getACall() ) } @@ -77,6 +79,82 @@ module PEP249 { } } + // --------------------------------------------------------------------------- + // asyncio implementations + // --------------------------------------------------------------------------- + // + // we differentiate between normal and asyncio implementations, since we model the + // `execute` call differently -- as a SqlExecution vs SqlConstruction, since the SQL + // is only executed in asyncio after being awaited (which might happen in something + // like `asyncio.gather`) + /** + * An API graph node representing a module that implements PEP 249 using asyncio. + */ + abstract class AsyncPEP249ModuleApiNode extends API::Node { + /** Gets a string representation of this element. */ + override string toString() { result = this.(API::Node).toString() } + } + + /** + * An API graph node representing a asyncio database connection (after being awaited). + */ + abstract class AsyncDatabaseConnection extends API::Node { + /** Gets a string representation of this element. */ + override string toString() { result = this.(API::Node).toString() } + } + + private class DefaultAsyncDatabaseConnection extends AsyncDatabaseConnection { + DefaultAsyncDatabaseConnection() { + this = any(AsyncPEP249ModuleApiNode mod).getMember("connect").getReturn().getAwaited() + } + } + + /** + * An API graph node representing a asyncio database cursor (after being awaited). + */ + abstract class AsyncDatabaseCursor extends API::Node { + /** Gets a string representation of this element. */ + override string toString() { result = this.(API::Node).toString() } + } + + private class DefaultAsyncDatabaseCursor extends AsyncDatabaseCursor { + DefaultAsyncDatabaseCursor() { + this = any(AsyncDatabaseConnection conn).getMember("cursor").getReturn().getAwaited() + } + } + + /** + * A call to an execute method on an asyncio database cursor or an asyncio connection, + * such as `execute` or `executemany`. + * + * (This is not an SqlExecution, since that only happens when the coroutine is + * awaited) + * + * See ExecuteMethodCall for more details. + */ + private class AsyncExecuteMethodCall extends SqlConstruction::Range, API::CallNode { + AsyncExecuteMethodCall() { + exists(API::Node start | + start instanceof AsyncDatabaseCursor or start instanceof AsyncDatabaseConnection + | + this = start.getMember(getExecuteMethodName()).getACall() + ) + } + + override DataFlow::Node getSql() { + result in [this.getArg(0), this.getArgByName(getSqlKwargName()),] + } + } + + /** Actual execution of the AsyncExecuteMethodCall coroutine. */ + private class AwaitedAsyncExecuteMethodCall extends SqlExecution::Range { + AsyncExecuteMethodCall execute; + + AwaitedAsyncExecuteMethodCall() { this = execute.getReturn().getAwaited().asSource() } + + override DataFlow::Node getSql() { result = execute.getSql() } + } + // --------------------------------------------------------------------------- // old impl // --------------------------------------------------------------------------- From 3f40e3863fc959908495daf0c57389c6b4429b6e Mon Sep 17 00:00:00 2001 From: Jami Cogswell <jcogs33@Jamis-MacBook-Pro.local> Date: Wed, 22 Mar 2023 10:51:36 -0400 Subject: [PATCH 299/631] Add yml files to change note check --- .github/workflows/check-change-note.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/check-change-note.yml b/.github/workflows/check-change-note.yml index e951b17b89b..aa255d4cf5a 100644 --- a/.github/workflows/check-change-note.yml +++ b/.github/workflows/check-change-note.yml @@ -8,6 +8,7 @@ on: - "*/ql/src/**/*.qll" - "*/ql/lib/**/*.ql" - "*/ql/lib/**/*.qll" + - "*/ql/lib/**/*.yml" - "!**/experimental/**" - "!ql/**" - "!swift/**" From 7b3f710e9115d2b168dd3de36aa812b169f15b96 Mon Sep 17 00:00:00 2001 From: Rasmus Wriedt Larsen <rasmuswl@github.com> Date: Wed, 22 Mar 2023 15:45:55 +0100 Subject: [PATCH 300/631] Python: Model `aiosqlite` --- .../codeql/reusables/supported-frameworks.rst | 1 + python/ql/lib/semmle/python/Frameworks.qll | 1 + .../semmle/python/frameworks/Aiosqlite.qll | 39 +++++++++++++++++++ .../lib/semmle/python/frameworks/PEP249.qll | 4 +- .../aiosqlite/ConceptsTest.expected | 0 .../frameworks/aiosqlite/ConceptsTest.ql | 2 + .../frameworks/aiosqlite/test.py | 27 +++++++++++++ 7 files changed, 73 insertions(+), 1 deletion(-) create mode 100644 python/ql/lib/semmle/python/frameworks/Aiosqlite.qll create mode 100644 python/ql/test/library-tests/frameworks/aiosqlite/ConceptsTest.expected create mode 100644 python/ql/test/library-tests/frameworks/aiosqlite/ConceptsTest.ql create mode 100644 python/ql/test/library-tests/frameworks/aiosqlite/test.py diff --git a/docs/codeql/reusables/supported-frameworks.rst b/docs/codeql/reusables/supported-frameworks.rst index e06f66ec4b5..cd1112a6e0c 100644 --- a/docs/codeql/reusables/supported-frameworks.rst +++ b/docs/codeql/reusables/supported-frameworks.rst @@ -223,6 +223,7 @@ and the CodeQL library pack ``codeql/python-all`` (`changelog <https://github.co aioch, Database aiomysql, Database aiopg, Database + aiosqlite, Database asyncpg, Database cassandra-driver, Database clickhouse-driver, Database diff --git a/python/ql/lib/semmle/python/Frameworks.qll b/python/ql/lib/semmle/python/Frameworks.qll index 7ce7cd8804e..c0d3c5e0b23 100644 --- a/python/ql/lib/semmle/python/Frameworks.qll +++ b/python/ql/lib/semmle/python/Frameworks.qll @@ -7,6 +7,7 @@ private import semmle.python.frameworks.Aioch private import semmle.python.frameworks.Aiohttp private import semmle.python.frameworks.Aiomysql +private import semmle.python.frameworks.Aiosqlite private import semmle.python.frameworks.Aiopg private import semmle.python.frameworks.Asyncpg private import semmle.python.frameworks.CassandraDriver diff --git a/python/ql/lib/semmle/python/frameworks/Aiosqlite.qll b/python/ql/lib/semmle/python/frameworks/Aiosqlite.qll new file mode 100644 index 00000000000..842459e1c36 --- /dev/null +++ b/python/ql/lib/semmle/python/frameworks/Aiosqlite.qll @@ -0,0 +1,39 @@ +/** + * Provides classes modeling security-relevant aspects of the `aiosqlite` PyPI package. + * See + * - https://pypi.org/project/aiosqlite/ + */ + +private import python +private import semmle.python.dataflow.new.DataFlow +private import semmle.python.Concepts +private import semmle.python.ApiGraphs +private import semmle.python.frameworks.PEP249 + +/** Provides models for the `aiosqlite` PyPI package. */ +private module Aiosqlite { + /** + * A model of `aiosqlite` as a module that implements PEP 249 using asyncio, providing + * ways to execute SQL statements against a database. + */ + class AiosqlitePEP249 extends PEP249::AsyncPEP249ModuleApiNode { + AiosqlitePEP249() { this = API::moduleImport("aiosqlite") } + } + + /** + * An additional cursor, that is return from the coroutine Connection.execute, + * see https://aiosqlite.omnilib.dev/en/latest/api.html#aiosqlite.Connection.execute + */ + class AiosqliteCursor extends PEP249::AsyncDatabaseCursor { + AiosqliteCursor() { + this = + API::moduleImport("aiosqlite") + .getMember("connect") + .getReturn() + .getAwaited() + .getMember("execute") + .getReturn() + .getAwaited() + } + } +} diff --git a/python/ql/lib/semmle/python/frameworks/PEP249.qll b/python/ql/lib/semmle/python/frameworks/PEP249.qll index 30617e88d55..2425f4514f8 100644 --- a/python/ql/lib/semmle/python/frameworks/PEP249.qll +++ b/python/ql/lib/semmle/python/frameworks/PEP249.qll @@ -52,7 +52,9 @@ module PEP249 { result in ["sql", "statement", "operation", "query", "query_string", "sql_script"] } - private string getExecuteMethodName() { result in ["execute", "executemany", "executescript"] } + private string getExecuteMethodName() { + result in ["execute", "executemany", "executescript", "execute_insert", "execute_fetchall"] + } /** * A call to an execute method on a database cursor or a connection, such as `execute` diff --git a/python/ql/test/library-tests/frameworks/aiosqlite/ConceptsTest.expected b/python/ql/test/library-tests/frameworks/aiosqlite/ConceptsTest.expected new file mode 100644 index 00000000000..e69de29bb2d diff --git a/python/ql/test/library-tests/frameworks/aiosqlite/ConceptsTest.ql b/python/ql/test/library-tests/frameworks/aiosqlite/ConceptsTest.ql new file mode 100644 index 00000000000..b557a0bccb6 --- /dev/null +++ b/python/ql/test/library-tests/frameworks/aiosqlite/ConceptsTest.ql @@ -0,0 +1,2 @@ +import python +import experimental.meta.ConceptsTest diff --git a/python/ql/test/library-tests/frameworks/aiosqlite/test.py b/python/ql/test/library-tests/frameworks/aiosqlite/test.py new file mode 100644 index 00000000000..888f9377694 --- /dev/null +++ b/python/ql/test/library-tests/frameworks/aiosqlite/test.py @@ -0,0 +1,27 @@ +import aiosqlite + +# see https://pypi.org/project/aiosqlite/ + +async def test(): + db = await aiosqlite.connect(...) + + await db.execute("sql") # $ getSql="sql" constructedSql="sql" + await db.execute(sql="sql") # $ getSql="sql" constructedSql="sql" + + cursor = await db.cursor() + cursor.execute("sql") # $ constructedSql="sql" + + cursor = await db.execute("sql") # $ getSql="sql" constructedSql="sql" + cursor.execute("sql") # $ constructedSql="sql" + + async with aiosqlite.connect(...) as db: + db.row_factory = aiosqlite.Row + async with db.execute("sql") as cursor: # $ getSql="sql" constructedSql="sql" + async for row in cursor: + print(row['column']) + + # nonstandard + await db.execute_insert("sql") # $ getSql="sql" constructedSql="sql" + await db.execute_fetchall("sql") # $ getSql="sql" constructedSql="sql" + await db.executescript("sql") # $ getSql="sql" constructedSql="sql" + await db.executescript(sql_script="sql") # $ getSql="sql" constructedSql="sql" From 77f1539e713028cfceddb94fc92594d9194fc336 Mon Sep 17 00:00:00 2001 From: Rasmus Wriedt Larsen <rasmuswl@github.com> Date: Wed, 22 Mar 2023 15:57:09 +0100 Subject: [PATCH 301/631] Python: Add change-note --- python/ql/lib/change-notes/2023-03-22-database-modeling.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 python/ql/lib/change-notes/2023-03-22-database-modeling.md diff --git a/python/ql/lib/change-notes/2023-03-22-database-modeling.md b/python/ql/lib/change-notes/2023-03-22-database-modeling.md new file mode 100644 index 00000000000..6cd23bed44f --- /dev/null +++ b/python/ql/lib/change-notes/2023-03-22-database-modeling.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* Added modeling of SQL execution in the packages `sqlite3.dbapi2`, `cassandra-driver`, `aiosqlite`, and the functions `sqlite3.Connection.executescript`/`sqlite3.Cursor.executescript` and `asyncpg.connection.connect()`. From 59f2c7518653a813f7fab3c992533ba047633933 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen <mathiasvp@github.com> Date: Wed, 22 Mar 2023 14:53:37 +0000 Subject: [PATCH 302/631] C++: bool -> int conversions are safe conversions. --- .../semmle/code/cpp/semantic/SemanticType.qll | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/cpp/ql/lib/experimental/semmle/code/cpp/semantic/SemanticType.qll b/cpp/ql/lib/experimental/semmle/code/cpp/semantic/SemanticType.qll index ce3f4ed90b4..b86db02702c 100644 --- a/cpp/ql/lib/experimental/semmle/code/cpp/semantic/SemanticType.qll +++ b/cpp/ql/lib/experimental/semmle/code/cpp/semantic/SemanticType.qll @@ -250,16 +250,26 @@ SemType getSemanticType(Specific::Type type) { Specific::unknownType(type) and result = TSemUnknownType() } +private class SemNumericOrBooleanType extends SemSizedType { + SemNumericOrBooleanType() { + this instanceof SemNumericType + or + this instanceof SemBooleanType + } +} + /** * Holds if the conversion from `fromType` to `toType` can never overflow or underflow. */ -predicate conversionCannotOverflow(SemNumericType fromType, SemNumericType toType) { +predicate conversionCannotOverflow(SemNumericOrBooleanType fromType, SemNumericOrBooleanType toType) { // Identity cast fromType = toType or // Treat any cast to an FP type as safe. It can lose precision, but not overflow. toType instanceof SemFloatingPointType and fromType = any(SemNumericType n) or + fromType instanceof SemBooleanType and toType instanceof SemIntegerType + or exists(SemIntegerType fromInteger, SemIntegerType toInteger, int fromSize, int toSize | fromInteger = fromType and toInteger = toType and From 08e86044307d841a56cf6936c91806ab2a8a9634 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen <mathiasvp@github.com> Date: Tue, 21 Mar 2023 16:36:38 +0000 Subject: [PATCH 303/631] C++: Change 'Expr' to be EquivalenceClasses instead of Instructions. --- .../cpp/semantic/SemanticExprSpecific.qll | 90 ++++++++++++++++++- 1 file changed, 89 insertions(+), 1 deletion(-) diff --git a/cpp/ql/lib/experimental/semmle/code/cpp/semantic/SemanticExprSpecific.qll b/cpp/ql/lib/experimental/semmle/code/cpp/semantic/SemanticExprSpecific.qll index f72edf2f806..070e84731af 100644 --- a/cpp/ql/lib/experimental/semmle/code/cpp/semantic/SemanticExprSpecific.qll +++ b/cpp/ql/lib/experimental/semmle/code/cpp/semantic/SemanticExprSpecific.qll @@ -12,7 +12,95 @@ private import semmle.code.cpp.ir.ValueNumbering module SemanticExprConfig { class Location = Cpp::Location; - class Expr = IR::Instruction; + /** A `ConvertInstruction` or a `CopyValueInstruction`. */ + private class Conversion extends IR::UnaryInstruction { + Conversion() { + this instanceof IR::CopyValueInstruction + or + this instanceof IR::ConvertInstruction + } + + /** Holds if this instruction converts a value of type `tFrom` to a value of type `tTo`. */ + predicate converts(SemType tFrom, SemType tTo) { + exists(IR::ConvertInstruction convert | + this = convert and + tFrom = getSemanticType(convert.getUnary().getResultIRType()) and + tTo = getSemanticType(convert.getResultIRType()) + ) + or + exists(IR::CopyValueInstruction copy | + this = copy and + tFrom = getSemanticType(copy.getUnary().getResultIRType()) and + tTo = getSemanticType(copy.getResultIRType()) + ) + } + } + + /** + * Gets a conversion-like instruction that consumes `op`, and + * which is guaranteed to not overflow. + */ + private IR::Instruction safeConversion(IR::Operand op) { + exists(Conversion conv, SemType tFrom, SemType tTo | + conv.converts(tFrom, tTo) and + conversionCannotOverflow(tFrom, tTo) and + conv.getUnaryOperand() = op and + result = conv + ) + } + + /** Holds if `i1 = i2` or if `i2` is a safe conversion that consumes `i1`. */ + private predicate idOrSafeConversion(IR::Instruction i1, IR::Instruction i2) { + not i1.getResultIRType() instanceof IR::IRVoidType and + ( + i1 = i2 + or + i2 = safeConversion(i1.getAUse()) + ) + } + + module Equiv = QlBuiltins::EquivalenceRelation<IR::Instruction, idOrSafeConversion/2>; + + /** + * The expressions on which we perform range analysis. + */ + class Expr extends Equiv::EquivalenceClass { + /** Gets the n'th instruction in this equivalence class. */ + private IR::Instruction getInstruction(int n) { + result = + rank[n + 1](IR::Instruction instr, int i, IR::IRBlock block | + this = Equiv::getEquivalenceClass(instr) and block.getInstruction(i) = instr + | + instr order by i + ) + } + + /** Gets a textual representation of this element. */ + string toString() { result = this.getUnconverted().toString() } + + /** Gets the basic block of this expression. */ + IR::IRBlock getBlock() { result = getInstruction(0).getBlock() } + + /** Gets the unconverted instruction associated with this expression. */ + IR::Instruction getUnconverted() { result = this.getInstruction(0) } + + /** + * Gets the final instruction associated with this expression. This + * represents the result after applying all the safe conversions. + */ + IR::Instruction getConverted() { + exists(int n | + result = this.getInstruction(n) and + not exists(this.getInstruction(n + 1)) + ) + } + + /** Gets the type of the result produced by this instruction. */ + IR::IRType getResultIRType() { result = this.getConverted().getResultIRType() } + + /** Gets the location of the source code for this expression. */ + Location getLocation() { result = this.getUnconverted().getLocation() } + } SemBasicBlock getExprBasicBlock(Expr e) { result = getSemanticBasicBlock(e.getBlock()) } From cbe5243c89efaf23764ec128a0381037b1273681 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Wed, 22 Mar 2023 16:20:45 +0000 Subject: [PATCH 304/631] Swift: Accept test regressions. :( --- .../Security/CWE-259/ConstantPassword.expected | 6 ------ .../Security/CWE-760/ConstantSalt.expected | 6 ------ .../CWE-916/InsufficientHashIterations.expected | 13 ------------- 3 files changed, 25 deletions(-) diff --git a/swift/ql/test/query-tests/Security/CWE-259/ConstantPassword.expected b/swift/ql/test/query-tests/Security/CWE-259/ConstantPassword.expected index 91539ad285b..262f02eeb8b 100644 --- a/swift/ql/test/query-tests/Security/CWE-259/ConstantPassword.expected +++ b/swift/ql/test/query-tests/Security/CWE-259/ConstantPassword.expected @@ -18,8 +18,6 @@ edges | rncryptor.swift:69:24:69:24 | abc123 : | rncryptor.swift:107:61:107:61 | myConstPassword | | rncryptor.swift:69:24:69:24 | abc123 : | rncryptor.swift:108:97:108:97 | myConstPassword | | test.swift:43:39:43:134 | [...] : | test.swift:51:30:51:30 | constantPassword | -| test.swift:43:39:43:134 | [...] : | test.swift:56:40:56:40 | constantPassword | -| test.swift:43:39:43:134 | [...] : | test.swift:62:40:62:40 | constantPassword | | test.swift:43:39:43:134 | [...] : | test.swift:67:34:67:34 | constantPassword | nodes | rncryptor.swift:69:24:69:24 | abc123 : | semmle.label | abc123 : | @@ -43,8 +41,6 @@ nodes | rncryptor.swift:108:97:108:97 | myConstPassword | semmle.label | myConstPassword | | test.swift:43:39:43:134 | [...] : | semmle.label | [...] : | | test.swift:51:30:51:30 | constantPassword | semmle.label | constantPassword | -| test.swift:56:40:56:40 | constantPassword | semmle.label | constantPassword | -| test.swift:62:40:62:40 | constantPassword | semmle.label | constantPassword | | test.swift:67:34:67:34 | constantPassword | semmle.label | constantPassword | subpaths #select @@ -67,6 +63,4 @@ subpaths | rncryptor.swift:107:61:107:61 | myConstPassword | rncryptor.swift:69:24:69:24 | abc123 : | rncryptor.swift:107:61:107:61 | myConstPassword | The value 'abc123' is used as a constant password. | | rncryptor.swift:108:97:108:97 | myConstPassword | rncryptor.swift:69:24:69:24 | abc123 : | rncryptor.swift:108:97:108:97 | myConstPassword | The value 'abc123' is used as a constant password. | | test.swift:51:30:51:30 | constantPassword | test.swift:43:39:43:134 | [...] : | test.swift:51:30:51:30 | constantPassword | The value '[...]' is used as a constant password. | -| test.swift:56:40:56:40 | constantPassword | test.swift:43:39:43:134 | [...] : | test.swift:56:40:56:40 | constantPassword | The value '[...]' is used as a constant password. | -| test.swift:62:40:62:40 | constantPassword | test.swift:43:39:43:134 | [...] : | test.swift:62:40:62:40 | constantPassword | The value '[...]' is used as a constant password. | | test.swift:67:34:67:34 | constantPassword | test.swift:43:39:43:134 | [...] : | test.swift:67:34:67:34 | constantPassword | The value '[...]' is used as a constant password. | diff --git a/swift/ql/test/query-tests/Security/CWE-760/ConstantSalt.expected b/swift/ql/test/query-tests/Security/CWE-760/ConstantSalt.expected index 633e73c44e5..def58418e9e 100644 --- a/swift/ql/test/query-tests/Security/CWE-760/ConstantSalt.expected +++ b/swift/ql/test/query-tests/Security/CWE-760/ConstantSalt.expected @@ -15,8 +15,6 @@ edges | rncryptor.swift:60:29:60:29 | 0 : | rncryptor.swift:5:5:5:29 | [summary param] 0 in Data.init(_:) : | | rncryptor.swift:60:29:60:29 | 0 : | rncryptor.swift:60:24:60:30 | call to Data.init(_:) : | | test.swift:43:35:43:130 | [...] : | test.swift:51:49:51:49 | constantSalt | -| test.swift:43:35:43:130 | [...] : | test.swift:56:59:56:59 | constantSalt | -| test.swift:43:35:43:130 | [...] : | test.swift:62:59:62:59 | constantSalt | | test.swift:43:35:43:130 | [...] : | test.swift:67:53:67:53 | constantSalt | nodes | file://:0:0:0:0 | [summary] to write: return (return) in Data.init(_:) : | semmle.label | [summary] to write: return (return) in Data.init(_:) : | @@ -37,8 +35,6 @@ nodes | rncryptor.swift:79:160:79:160 | myConstantSalt2 | semmle.label | myConstantSalt2 | | test.swift:43:35:43:130 | [...] : | semmle.label | [...] : | | test.swift:51:49:51:49 | constantSalt | semmle.label | constantSalt | -| test.swift:56:59:56:59 | constantSalt | semmle.label | constantSalt | -| test.swift:62:59:62:59 | constantSalt | semmle.label | constantSalt | | test.swift:67:53:67:53 | constantSalt | semmle.label | constantSalt | subpaths | rncryptor.swift:59:29:59:29 | abcdef123456 : | rncryptor.swift:5:5:5:29 | [summary param] 0 in Data.init(_:) : | file://:0:0:0:0 | [summary] to write: return (return) in Data.init(_:) : | rncryptor.swift:59:24:59:43 | call to Data.init(_:) : | @@ -55,6 +51,4 @@ subpaths | rncryptor.swift:78:135:78:135 | myConstantSalt1 | rncryptor.swift:59:29:59:29 | abcdef123456 : | rncryptor.swift:78:135:78:135 | myConstantSalt1 | The value 'abcdef123456' is used as a constant salt, which is insecure for hashing passwords. | | rncryptor.swift:79:160:79:160 | myConstantSalt2 | rncryptor.swift:60:29:60:29 | 0 : | rncryptor.swift:79:160:79:160 | myConstantSalt2 | The value '0' is used as a constant salt, which is insecure for hashing passwords. | | test.swift:51:49:51:49 | constantSalt | test.swift:43:35:43:130 | [...] : | test.swift:51:49:51:49 | constantSalt | The value '[...]' is used as a constant salt, which is insecure for hashing passwords. | -| test.swift:56:59:56:59 | constantSalt | test.swift:43:35:43:130 | [...] : | test.swift:56:59:56:59 | constantSalt | The value '[...]' is used as a constant salt, which is insecure for hashing passwords. | -| test.swift:62:59:62:59 | constantSalt | test.swift:43:35:43:130 | [...] : | test.swift:62:59:62:59 | constantSalt | The value '[...]' is used as a constant salt, which is insecure for hashing passwords. | | test.swift:67:53:67:53 | constantSalt | test.swift:43:35:43:130 | [...] : | test.swift:67:53:67:53 | constantSalt | The value '[...]' is used as a constant salt, which is insecure for hashing passwords. | diff --git a/swift/ql/test/query-tests/Security/CWE-916/InsufficientHashIterations.expected b/swift/ql/test/query-tests/Security/CWE-916/InsufficientHashIterations.expected index 0e46106d3f2..e217064d1df 100644 --- a/swift/ql/test/query-tests/Security/CWE-916/InsufficientHashIterations.expected +++ b/swift/ql/test/query-tests/Security/CWE-916/InsufficientHashIterations.expected @@ -1,17 +1,4 @@ edges -| test.swift:20:45:20:45 | 99999 : | test.swift:33:22:33:43 | call to getLowIterationCount() : | -| test.swift:33:22:33:43 | call to getLowIterationCount() : | test.swift:37:84:37:84 | lowIterations | -| test.swift:33:22:33:43 | call to getLowIterationCount() : | test.swift:44:84:44:84 | lowIterations | nodes -| test.swift:20:45:20:45 | 99999 : | semmle.label | 99999 : | -| test.swift:33:22:33:43 | call to getLowIterationCount() : | semmle.label | call to getLowIterationCount() : | -| test.swift:37:84:37:84 | lowIterations | semmle.label | lowIterations | -| test.swift:38:84:38:84 | 80000 | semmle.label | 80000 | -| test.swift:44:84:44:84 | lowIterations | semmle.label | lowIterations | -| test.swift:45:84:45:84 | 80000 | semmle.label | 80000 | subpaths #select -| test.swift:37:84:37:84 | lowIterations | test.swift:20:45:20:45 | 99999 : | test.swift:37:84:37:84 | lowIterations | The value '99999' is an insufficient number of iterations for secure password hashing. | -| test.swift:38:84:38:84 | 80000 | test.swift:38:84:38:84 | 80000 | test.swift:38:84:38:84 | 80000 | The value '80000' is an insufficient number of iterations for secure password hashing. | -| test.swift:44:84:44:84 | lowIterations | test.swift:20:45:20:45 | 99999 : | test.swift:44:84:44:84 | lowIterations | The value '99999' is an insufficient number of iterations for secure password hashing. | -| test.swift:45:84:45:84 | 80000 | test.swift:45:84:45:84 | 80000 | test.swift:45:84:45:84 | 80000 | The value '80000' is an insufficient number of iterations for secure password hashing. | \ No newline at end of file From a4e9d38abb71f4e37720d1d1da82147e10effae1 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Wed, 22 Mar 2023 16:44:29 +0000 Subject: [PATCH 305/631] Swift: Fix the test regression. --- .../queries/Security/CWE-259/ConstantPassword.ql | 4 ++-- .../ql/src/queries/Security/CWE-760/ConstantSalt.ql | 4 ++-- .../Security/CWE-916/InsufficientHashIterations.ql | 2 +- .../Security/CWE-259/ConstantPassword.expected | 6 ++++++ .../Security/CWE-760/ConstantSalt.expected | 6 ++++++ .../CWE-916/InsufficientHashIterations.expected | 13 +++++++++++++ 6 files changed, 30 insertions(+), 5 deletions(-) diff --git a/swift/ql/src/queries/Security/CWE-259/ConstantPassword.ql b/swift/ql/src/queries/Security/CWE-259/ConstantPassword.ql index d7fd2e187de..48e53f50ab0 100644 --- a/swift/ql/src/queries/Security/CWE-259/ConstantPassword.ql +++ b/swift/ql/src/queries/Security/CWE-259/ConstantPassword.ql @@ -33,7 +33,7 @@ class ConstantPasswordSink extends Expr { ConstantPasswordSink() { // `password` arg in `init` is a sink exists(ClassOrStructDecl c, ConstructorDecl f, CallExpr call | - c.getFullName() = ["HKDF", "PBKDF1", "PBKDF2", "Scrypt"] and + c.getName() = ["HKDF", "PBKDF1", "PBKDF2", "Scrypt"] and c.getAMember() = f and call.getStaticTarget() = f and call.getArgumentWithLabel("password").getExpr() = this @@ -41,7 +41,7 @@ class ConstantPasswordSink extends Expr { or // RNCryptor (labelled arguments) exists(ClassOrStructDecl c, MethodDecl f, CallExpr call | - c.getFullName() = ["RNCryptor", "RNEncryptor", "RNDecryptor"] and + c.getName() = ["RNCryptor", "RNEncryptor", "RNDecryptor"] and c.getAMember() = f and call.getStaticTarget() = f and call.getArgumentWithLabel(["password", "withPassword", "forPassword"]).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 71f379a77ad..e510acffe3a 100644 --- a/swift/ql/src/queries/Security/CWE-760/ConstantSalt.ql +++ b/swift/ql/src/queries/Security/CWE-760/ConstantSalt.ql @@ -34,7 +34,7 @@ class ConstantSaltSink extends Expr { ConstantSaltSink() { // `salt` arg in `init` is a sink exists(ClassOrStructDecl c, ConstructorDecl f, CallExpr call | - c.getFullName() = ["HKDF", "PBKDF1", "PBKDF2", "Scrypt"] and + c.getName() = ["HKDF", "PBKDF1", "PBKDF2", "Scrypt"] and c.getAMember() = f and call.getStaticTarget() = f and call.getArgumentWithLabel("salt").getExpr() = this @@ -42,7 +42,7 @@ class ConstantSaltSink extends Expr { or // RNCryptor exists(ClassOrStructDecl c, MethodDecl f, CallExpr call | - c.getFullName() = ["RNCryptor", "RNEncryptor", "RNDecryptor"] and + c.getName() = ["RNCryptor", "RNEncryptor", "RNDecryptor"] and c.getAMember() = f and call.getStaticTarget() = f and call.getArgumentWithLabel(["salt", "encryptionSalt", "hmacSalt", "HMACSalt"]).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 d8cb049ea50..310b038d3f3 100644 --- a/swift/ql/src/queries/Security/CWE-916/InsufficientHashIterations.ql +++ b/swift/ql/src/queries/Security/CWE-916/InsufficientHashIterations.ql @@ -34,7 +34,7 @@ class InsufficientHashIterationsSink extends Expr { InsufficientHashIterationsSink() { // `iterations` arg in `init` is a sink exists(ClassOrStructDecl c, ConstructorDecl f, CallExpr call | - c.getFullName() = ["PBKDF1", "PBKDF2"] and + c.getName() = ["PBKDF1", "PBKDF2"] and c.getAMember() = f and call.getStaticTarget() = f and call.getArgumentWithLabel("iterations").getExpr() = this diff --git a/swift/ql/test/query-tests/Security/CWE-259/ConstantPassword.expected b/swift/ql/test/query-tests/Security/CWE-259/ConstantPassword.expected index 262f02eeb8b..91539ad285b 100644 --- a/swift/ql/test/query-tests/Security/CWE-259/ConstantPassword.expected +++ b/swift/ql/test/query-tests/Security/CWE-259/ConstantPassword.expected @@ -18,6 +18,8 @@ edges | rncryptor.swift:69:24:69:24 | abc123 : | rncryptor.swift:107:61:107:61 | myConstPassword | | rncryptor.swift:69:24:69:24 | abc123 : | rncryptor.swift:108:97:108:97 | myConstPassword | | test.swift:43:39:43:134 | [...] : | test.swift:51:30:51:30 | constantPassword | +| test.swift:43:39:43:134 | [...] : | test.swift:56:40:56:40 | constantPassword | +| test.swift:43:39:43:134 | [...] : | test.swift:62:40:62:40 | constantPassword | | test.swift:43:39:43:134 | [...] : | test.swift:67:34:67:34 | constantPassword | nodes | rncryptor.swift:69:24:69:24 | abc123 : | semmle.label | abc123 : | @@ -41,6 +43,8 @@ nodes | rncryptor.swift:108:97:108:97 | myConstPassword | semmle.label | myConstPassword | | test.swift:43:39:43:134 | [...] : | semmle.label | [...] : | | test.swift:51:30:51:30 | constantPassword | semmle.label | constantPassword | +| test.swift:56:40:56:40 | constantPassword | semmle.label | constantPassword | +| test.swift:62:40:62:40 | constantPassword | semmle.label | constantPassword | | test.swift:67:34:67:34 | constantPassword | semmle.label | constantPassword | subpaths #select @@ -63,4 +67,6 @@ subpaths | rncryptor.swift:107:61:107:61 | myConstPassword | rncryptor.swift:69:24:69:24 | abc123 : | rncryptor.swift:107:61:107:61 | myConstPassword | The value 'abc123' is used as a constant password. | | rncryptor.swift:108:97:108:97 | myConstPassword | rncryptor.swift:69:24:69:24 | abc123 : | rncryptor.swift:108:97:108:97 | myConstPassword | The value 'abc123' is used as a constant password. | | test.swift:51:30:51:30 | constantPassword | test.swift:43:39:43:134 | [...] : | test.swift:51:30:51:30 | constantPassword | The value '[...]' is used as a constant password. | +| test.swift:56:40:56:40 | constantPassword | test.swift:43:39:43:134 | [...] : | test.swift:56:40:56:40 | constantPassword | The value '[...]' is used as a constant password. | +| test.swift:62:40:62:40 | constantPassword | test.swift:43:39:43:134 | [...] : | test.swift:62:40:62:40 | constantPassword | The value '[...]' is used as a constant password. | | test.swift:67:34:67:34 | constantPassword | test.swift:43:39:43:134 | [...] : | test.swift:67:34:67:34 | constantPassword | The value '[...]' is used as a constant password. | diff --git a/swift/ql/test/query-tests/Security/CWE-760/ConstantSalt.expected b/swift/ql/test/query-tests/Security/CWE-760/ConstantSalt.expected index def58418e9e..633e73c44e5 100644 --- a/swift/ql/test/query-tests/Security/CWE-760/ConstantSalt.expected +++ b/swift/ql/test/query-tests/Security/CWE-760/ConstantSalt.expected @@ -15,6 +15,8 @@ edges | rncryptor.swift:60:29:60:29 | 0 : | rncryptor.swift:5:5:5:29 | [summary param] 0 in Data.init(_:) : | | rncryptor.swift:60:29:60:29 | 0 : | rncryptor.swift:60:24:60:30 | call to Data.init(_:) : | | test.swift:43:35:43:130 | [...] : | test.swift:51:49:51:49 | constantSalt | +| test.swift:43:35:43:130 | [...] : | test.swift:56:59:56:59 | constantSalt | +| test.swift:43:35:43:130 | [...] : | test.swift:62:59:62:59 | constantSalt | | test.swift:43:35:43:130 | [...] : | test.swift:67:53:67:53 | constantSalt | nodes | file://:0:0:0:0 | [summary] to write: return (return) in Data.init(_:) : | semmle.label | [summary] to write: return (return) in Data.init(_:) : | @@ -35,6 +37,8 @@ nodes | rncryptor.swift:79:160:79:160 | myConstantSalt2 | semmle.label | myConstantSalt2 | | test.swift:43:35:43:130 | [...] : | semmle.label | [...] : | | test.swift:51:49:51:49 | constantSalt | semmle.label | constantSalt | +| test.swift:56:59:56:59 | constantSalt | semmle.label | constantSalt | +| test.swift:62:59:62:59 | constantSalt | semmle.label | constantSalt | | test.swift:67:53:67:53 | constantSalt | semmle.label | constantSalt | subpaths | rncryptor.swift:59:29:59:29 | abcdef123456 : | rncryptor.swift:5:5:5:29 | [summary param] 0 in Data.init(_:) : | file://:0:0:0:0 | [summary] to write: return (return) in Data.init(_:) : | rncryptor.swift:59:24:59:43 | call to Data.init(_:) : | @@ -51,4 +55,6 @@ subpaths | rncryptor.swift:78:135:78:135 | myConstantSalt1 | rncryptor.swift:59:29:59:29 | abcdef123456 : | rncryptor.swift:78:135:78:135 | myConstantSalt1 | The value 'abcdef123456' is used as a constant salt, which is insecure for hashing passwords. | | rncryptor.swift:79:160:79:160 | myConstantSalt2 | rncryptor.swift:60:29:60:29 | 0 : | rncryptor.swift:79:160:79:160 | myConstantSalt2 | The value '0' is used as a constant salt, which is insecure for hashing passwords. | | test.swift:51:49:51:49 | constantSalt | test.swift:43:35:43:130 | [...] : | test.swift:51:49:51:49 | constantSalt | The value '[...]' is used as a constant salt, which is insecure for hashing passwords. | +| test.swift:56:59:56:59 | constantSalt | test.swift:43:35:43:130 | [...] : | test.swift:56:59:56:59 | constantSalt | The value '[...]' is used as a constant salt, which is insecure for hashing passwords. | +| test.swift:62:59:62:59 | constantSalt | test.swift:43:35:43:130 | [...] : | test.swift:62:59:62:59 | constantSalt | The value '[...]' is used as a constant salt, which is insecure for hashing passwords. | | test.swift:67:53:67:53 | constantSalt | test.swift:43:35:43:130 | [...] : | test.swift:67:53:67:53 | constantSalt | The value '[...]' is used as a constant salt, which is insecure for hashing passwords. | diff --git a/swift/ql/test/query-tests/Security/CWE-916/InsufficientHashIterations.expected b/swift/ql/test/query-tests/Security/CWE-916/InsufficientHashIterations.expected index e217064d1df..8f432710dc0 100644 --- a/swift/ql/test/query-tests/Security/CWE-916/InsufficientHashIterations.expected +++ b/swift/ql/test/query-tests/Security/CWE-916/InsufficientHashIterations.expected @@ -1,4 +1,17 @@ edges +| test.swift:20:45:20:45 | 99999 : | test.swift:33:22:33:43 | call to getLowIterationCount() : | +| test.swift:33:22:33:43 | call to getLowIterationCount() : | test.swift:37:84:37:84 | lowIterations | +| test.swift:33:22:33:43 | call to getLowIterationCount() : | test.swift:44:84:44:84 | lowIterations | nodes +| test.swift:20:45:20:45 | 99999 : | semmle.label | 99999 : | +| test.swift:33:22:33:43 | call to getLowIterationCount() : | semmle.label | call to getLowIterationCount() : | +| test.swift:37:84:37:84 | lowIterations | semmle.label | lowIterations | +| test.swift:38:84:38:84 | 80000 | semmle.label | 80000 | +| test.swift:44:84:44:84 | lowIterations | semmle.label | lowIterations | +| test.swift:45:84:45:84 | 80000 | semmle.label | 80000 | subpaths #select +| test.swift:37:84:37:84 | lowIterations | test.swift:20:45:20:45 | 99999 : | test.swift:37:84:37:84 | lowIterations | The value '99999' is an insufficient number of iterations for secure password hashing. | +| test.swift:38:84:38:84 | 80000 | test.swift:38:84:38:84 | 80000 | test.swift:38:84:38:84 | 80000 | The value '80000' is an insufficient number of iterations for secure password hashing. | +| test.swift:44:84:44:84 | lowIterations | test.swift:20:45:20:45 | 99999 : | test.swift:44:84:44:84 | lowIterations | The value '99999' is an insufficient number of iterations for secure password hashing. | +| test.swift:45:84:45:84 | 80000 | test.swift:45:84:45:84 | 80000 | test.swift:45:84:45:84 | 80000 | The value '80000' is an insufficient number of iterations for secure password hashing. | From 4cc3bfae33e9e5d2f72dd51a3d3be27dfb30790e Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen <mathiasvp@github.com> Date: Tue, 21 Mar 2023 16:37:43 +0000 Subject: [PATCH 306/631] C++: Fix places that assumed that 'Expr' was always 'Instruction'. --- .../cpp/semantic/SemanticExprSpecific.qll | 76 +++++++++++-------- .../ir/range-analysis/RangeAnalysis.ql | 2 +- .../ir/sign-analysis/SignAnalysis.ql | 3 +- 3 files changed, 47 insertions(+), 34 deletions(-) diff --git a/cpp/ql/lib/experimental/semmle/code/cpp/semantic/SemanticExprSpecific.qll b/cpp/ql/lib/experimental/semmle/code/cpp/semantic/SemanticExprSpecific.qll index 070e84731af..6c3f56fd924 100644 --- a/cpp/ql/lib/experimental/semmle/code/cpp/semantic/SemanticExprSpecific.qll +++ b/cpp/ql/lib/experimental/semmle/code/cpp/semantic/SemanticExprSpecific.qll @@ -105,7 +105,7 @@ module SemanticExprConfig { SemBasicBlock getExprBasicBlock(Expr e) { result = getSemanticBasicBlock(e.getBlock()) } private predicate anyConstantExpr(Expr expr, SemType type, string value) { - exists(IR::ConstantInstruction instr | instr = expr | + exists(IR::ConstantInstruction instr | getSemanticExpr(instr) = expr | type = getSemanticType(instr.getResultIRType()) and value = instr.getValue() ) @@ -146,41 +146,46 @@ module SemanticExprConfig { predicate nullLiteral(Expr expr, SemAddressType type) { anyConstantExpr(expr, type, _) } predicate stringLiteral(Expr expr, SemType type, string value) { - anyConstantExpr(expr, type, value) and expr instanceof IR::StringConstantInstruction + anyConstantExpr(expr, type, value) and + expr.getUnconverted() instanceof IR::StringConstantInstruction } predicate binaryExpr(Expr expr, Opcode opcode, SemType type, Expr leftOperand, Expr rightOperand) { - exists(IR::BinaryInstruction instr | instr = expr | + exists(IR::BinaryInstruction instr | + instr = expr.getUnconverted() and type = getSemanticType(instr.getResultIRType()) and - leftOperand = instr.getLeft() and - rightOperand = instr.getRight() and + leftOperand = getSemanticExpr(instr.getLeft()) and + rightOperand = getSemanticExpr(instr.getRight()) and // REVIEW: Merge the two `Opcode` types. opcode.toString() = instr.getOpcode().toString() ) } predicate unaryExpr(Expr expr, Opcode opcode, SemType type, Expr operand) { - type = getSemanticType(expr.getResultIRType()) and - ( - exists(IR::UnaryInstruction instr | instr = expr | - operand = instr.getUnary() and - // REVIEW: Merge the two operand types. - opcode.toString() = instr.getOpcode().toString() - ) - or - exists(IR::StoreInstruction instr | instr = expr | - operand = instr.getSourceValue() and - opcode instanceof Opcode::Store - ) + exists(IR::UnaryInstruction instr | instr = expr.getUnconverted() | + type = getSemanticType(instr.getResultIRType()) and + operand = getSemanticExpr(instr.getUnary()) and + // REVIEW: Merge the two operand types. + opcode.toString() = instr.getOpcode().toString() + ) + or + exists(IR::StoreInstruction instr | instr = expr.getUnconverted() | + type = getSemanticType(instr.getResultIRType()) and + operand = getSemanticExpr(instr.getSourceValue()) and + opcode instanceof Opcode::Store ) } predicate nullaryExpr(Expr expr, Opcode opcode, SemType type) { - type = getSemanticType(expr.getResultIRType()) and - ( - expr instanceof IR::LoadInstruction and opcode instanceof Opcode::Load - or - expr instanceof IR::InitializeParameterInstruction and + exists(IR::LoadInstruction load | + load = expr.getUnconverted() and + type = getSemanticType(load.getResultIRType()) and + opcode instanceof Opcode::Load + ) + or + exists(IR::InitializeParameterInstruction init | + init = expr.getUnconverted() and + type = getSemanticType(init.getResultIRType()) and opcode instanceof Opcode::InitializeParameter ) } @@ -267,7 +272,9 @@ module SemanticExprConfig { final override IR::Operand asOperand() { result = op } } - predicate explicitUpdate(SsaVariable v, Expr sourceExpr) { v.asInstruction() = sourceExpr } + predicate explicitUpdate(SsaVariable v, Expr sourceExpr) { + getSemanticExpr(v.asInstruction()) = sourceExpr + } predicate phi(SsaVariable v) { v.asInstruction() instanceof IR::PhiInstruction } @@ -280,9 +287,9 @@ module SemanticExprConfig { } Expr getAUse(SsaVariable v) { - result.(IR::LoadInstruction).getSourceValue() = v.asInstruction() + result.getUnconverted().(IR::LoadInstruction).getSourceValue() = v.asInstruction() or - result = valueNumber(v.asPointerArithGuard()).getAnInstruction() + result.getUnconverted() = valueNumber(v.asPointerArithGuard()).getAnInstruction() } SemType getSsaVariableType(SsaVariable v) { @@ -391,17 +398,21 @@ module SemanticExprConfig { } Expr getBoundExpr(Bound bound, int delta) { - result = bound.(IRBound::Bound).getInstruction(delta) + result = getSemanticExpr(bound.(IRBound::Bound).getInstruction(delta)) } class Guard = IRGuards::IRGuardCondition; predicate guard(Guard guard, BasicBlock block) { block = guard.getBlock() } - Expr getGuardAsExpr(Guard guard) { result = guard } + Expr getGuardAsExpr(Guard guard) { result = getSemanticExpr(guard) } predicate equalityGuard(Guard guard, Expr e1, Expr e2, boolean polarity) { - guard.comparesEq(e1.getAUse(), e2.getAUse(), 0, true, polarity) + exists(IR::Instruction left, IR::Instruction right | + getSemanticExpr(left) = e1 and + getSemanticExpr(right) = e2 and + guard.comparesEq(left.getAUse(), right.getAUse(), 0, true, polarity) + ) } predicate guardDirectlyControlsBlock(Guard guard, BasicBlock controlled, boolean branch) { @@ -412,16 +423,17 @@ module SemanticExprConfig { guard.controlsEdge(bb1, bb2, branch) } - Guard comparisonGuard(Expr e) { result = e } + Guard comparisonGuard(Expr e) { getSemanticExpr(result) = e } predicate implies_v2(Guard g1, boolean b1, Guard g2, boolean b2) { none() // TODO } + + /** Gets the expression associated with `instr`. */ + SemExpr getSemanticExpr(IR::Instruction instr) { result = Equiv::getEquivalenceClass(instr) } } -SemExpr getSemanticExpr(IR::Instruction instr) { result = instr } - -IR::Instruction getCppInstruction(SemExpr e) { e = result } +predicate getSemanticExpr = SemanticExprConfig::getSemanticExpr/1; SemBasicBlock getSemanticBasicBlock(IR::IRBlock block) { result = block } diff --git a/cpp/ql/test/library-tests/ir/range-analysis/RangeAnalysis.ql b/cpp/ql/test/library-tests/ir/range-analysis/RangeAnalysis.ql index d3e44c868cf..769d3e2b42b 100644 --- a/cpp/ql/test/library-tests/ir/range-analysis/RangeAnalysis.ql +++ b/cpp/ql/test/library-tests/ir/range-analysis/RangeAnalysis.ql @@ -12,7 +12,7 @@ class RangeAnalysisTest extends InlineExpectationsTest { override predicate hasActualResult(Location location, string element, string tag, string value) { exists(SemExpr e, IR::CallInstruction call | - call.getArgument(0) = e and + getSemanticExpr(call.getArgument(0)) = e and call.getStaticCallTarget().hasName("range") and tag = "range" and element = e.toString() and diff --git a/cpp/ql/test/library-tests/ir/sign-analysis/SignAnalysis.ql b/cpp/ql/test/library-tests/ir/sign-analysis/SignAnalysis.ql index d4f499fdc61..7b78b077a9b 100644 --- a/cpp/ql/test/library-tests/ir/sign-analysis/SignAnalysis.ql +++ b/cpp/ql/test/library-tests/ir/sign-analysis/SignAnalysis.ql @@ -4,6 +4,7 @@ import experimental.semmle.code.cpp.semantic.Semantic import experimental.semmle.code.cpp.semantic.analysis.RangeUtils import experimental.semmle.code.cpp.semantic.analysis.FloatDelta import experimental.semmle.code.cpp.semantic.analysis.RangeAnalysisSpecific +import experimental.semmle.code.cpp.semantic.SemanticExprSpecific import semmle.code.cpp.ir.IR as IR import TestUtilities.InlineExpectationsTest @@ -16,7 +17,7 @@ class SignAnalysisTest extends InlineExpectationsTest { override predicate hasActualResult(Location location, string element, string tag, string value) { exists(SemExpr e, IR::CallInstruction call | - call.getArgument(0) = e and + getSemanticExpr(call.getArgument(0)) = e and call.getStaticCallTarget().hasName("sign") and tag = "sign" and element = e.toString() and From 4d029acb114140e1ffe7f88a0fce2f1684fc0a1e Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen <mathiasvp@github.com> Date: Tue, 21 Mar 2023 16:38:08 +0000 Subject: [PATCH 307/631] C++: Accept test changes. --- .../SimpleRangeAnalysis_tests.cpp | 76 ++++++++++--------- 1 file changed, 40 insertions(+), 36 deletions(-) diff --git a/cpp/ql/test/library-tests/ir/range-analysis/SimpleRangeAnalysis_tests.cpp b/cpp/ql/test/library-tests/ir/range-analysis/SimpleRangeAnalysis_tests.cpp index 58ed4fdf396..eb91006594b 100644 --- a/cpp/ql/test/library-tests/ir/range-analysis/SimpleRangeAnalysis_tests.cpp +++ b/cpp/ql/test/library-tests/ir/range-analysis/SimpleRangeAnalysis_tests.cpp @@ -18,7 +18,7 @@ int test2(struct List* p) { int count = 0; for (; p; p = p->next) { count = (count+1) % 10; - range(count); // $ range=<=9 + range(count); // $ range=<=9 range=<=count:p+1 } range(count); // $ range=<=9 return count; @@ -29,7 +29,7 @@ int test3(struct List* p) { for (; p; p = p->next) { range(count++); // $ range=<=9 count = count % 10; - range(count); // $ range=<=9 + range(count); // $ range=<=9 range="<=... +++0" range=<=count:p+1 } range(count); // $ range=<=9 return count; @@ -40,13 +40,13 @@ int test4() { int total = 0; for (i = 0; i < 2; i = i+1) { range(i); // $ range=<=1 range=>=0 - range(total); + range(total); // $ range=>=0 total += i; - range(total); + range(total); // $ range=>=0 range=>=i+0 } - range(total); + range(total); // $ range=>=0 range(i); // $ range===2 - range(total + i); // $ range=>=i+1 + range(total + i); // $ range=>=i+1 range=>=2 range=>=i+0 return total + i; } @@ -55,13 +55,13 @@ int test5() { int total = 0; for (i = 0; i < 2; i++) { range(i); // $ range=<=1 range=>=0 - range(total); + range(total); // $ range=>=0 total += i; - range(total); + range(total); // $ range=>=0 range=>=i+0 } - range(total); + range(total); // $ range=>=0 range(i); // $ range===2 - range(total + i); // $ range=>=i+1 + range(total + i); // $ range=>=i+1 range=>=2 range=>=i+0 return total + i; } @@ -70,9 +70,9 @@ int test6() { int total = 0; for (i = 0; i+2 < 4; i = i+1) { range(i); // $ range=<=1 range=>=0 - range(total); + range(total); // $ range=>=0 total += i; - range(total); + range(total); // $ range=>=0 range=>=i+0 } return total + i; } @@ -149,7 +149,7 @@ int test11(char *p) { range(*p); } if (c == ':') { - range(c); + range(c); // $ range===58 c = *p; range(*p); if (c != '\0') { @@ -310,7 +310,7 @@ int test_mult01(int a, int b) { int r = a*b; // 0 .. 253 range(r); total += r; - range(total); // $ range=>=0 range=>=3+0 + range(total); // $ range=>=0 range=>=3+0 range=">=... * ...+0" } if (3 <= a && a <= 11 && -13 <= b && b <= 23) { range(a); // $ range=<=11 range=>=3 @@ -318,7 +318,7 @@ int test_mult01(int a, int b) { int r = a*b; // -143 .. 253 range(r); total += r; - range(total); + range(total); // $ range=">=... * ...+0" } if (3 <= a && a <= 11 && -13 <= b && b <= 0) { range(a); // $ range=<=11 range=>=3 @@ -358,7 +358,7 @@ int test_mult02(int a, int b) { int r = a*b; // 0 .. 253 range(r); total += r; - range(total); // $ range=>=0 range=>=0+0 + range(total); // $ range=>=0 range=>=0+0 range=">=... * ...+0" } if (0 <= a && a <= 11 && -13 <= b && b <= 23) { range(a); // $ range=<=11 range=>=0 @@ -366,7 +366,7 @@ int test_mult02(int a, int b) { int r = a*b; // -143 .. 253 range(r); total += r; - range(total); + range(total); // $ range=">=... * ...+0" } if (0 <= a && a <= 11 && -13 <= b && b <= 0) { range(a); // $ range=<=11 range=>=0 @@ -453,7 +453,7 @@ int test_mult04(int a, int b) { int r = a*b; // -391 .. 0 range(r); total += r; - range(total); // $ range="<=- ...+0" range=<=0 + range(total); // $ range="<=- ...+0" range=<=0 range="<=... * ...+0" } if (-17 <= a && a <= 0 && -13 <= b && b <= 23) { range(a); // $ range=<=0 range=>=-17 @@ -461,7 +461,7 @@ int test_mult04(int a, int b) { int r = a*b; // -391 .. 221 range(r); total += r; - range(total); + range(total); // $ range="<=... * ...+0" } if (-17 <= a && a <= 0 && -13 <= b && b <= 0) { range(a); // $ range=<=0 range=>=-17 @@ -501,7 +501,7 @@ int test_mult05(int a, int b) { int r = a*b; // -391 .. 0 range(r); total += r; - range(total); // $ range="<=- ...+0" range=<=0 + range(total); // $ range="<=- ...+0" range=<=0 range="<=... * ...+0" } if (-17 <= a && a <= -2 && -13 <= b && b <= 23) { range(a); // $ range=<=-2 range=>=-17 @@ -509,7 +509,7 @@ int test_mult05(int a, int b) { int r = a*b; // -391 .. 221 range(r); total += r; - range(total); + range(total); // $ range="<=... * ...+0" } if (-17 <= a && a <= -2 && -13 <= b && b <= 0) { range(a); // $ range=<=-2 range=>=-17 @@ -628,7 +628,7 @@ unsigned int test_ternary02(unsigned int x) { (range(x), 5); // $ range=>=300 range(y5); // y6 >= 0 } - range(y1 + y2 + y3 + y4 + y5); // $ range=">=... = ...:... ? ... : ...+0" range=">=call to range+0" + range(y1 + y2 + y3 + y4 + y5); // $ range=">=... = ...:... ? ... : ...+1" range=">=call to range+1" return y1 + y2 + y3 + y4 + y5; } @@ -693,7 +693,7 @@ int test_unsigned_mult01(unsigned int a, unsigned b) { int r = a*b; // 0 .. 253 range(r); total += r; - range(total); // $ range=">=(unsigned int)...+0" range=>=0 + range(total); // $ range=">=(unsigned int)...+0" range=>=0 range=>=(int)...+0 } if (3 <= a && a <= 11 && 13 <= b && b <= 23) { range(a); // $ range=<=11 range=>=3 @@ -701,7 +701,7 @@ int test_unsigned_mult01(unsigned int a, unsigned b) { int r = a*b; // 39 .. 253 range(r); total += r; - range(total); // $ range=">=(unsigned int)...+1" range=>=1 + range(total); // $ range=">=(unsigned int)...+1" range=>=1 range=>=(int)...+0 } range(total); // $ range=">=(unsigned int)...+0" range=>=0 return total; @@ -722,14 +722,14 @@ int test_unsigned_mult02(unsigned b) { int r = 11*b; // 0 .. 253 range(r); total += r; - range(total); // $ range=">=(unsigned int)...+0" range=>=0 + range(total); // $ range=">=(unsigned int)...+0" range=>=0 range=>=(int)...+0 } if (13 <= b && b <= 23) { range(b); // $ range=<=23 range=>=13 int r = 11*b; // 143 .. 253 range(r); total += r; - range(total); // $ range=">=(unsigned int)...+1" range=>=1 + range(total); // $ range=">=(unsigned int)...+1" range=>=1 range=>=(int)...+0 } range(total); // $ range=">=(unsigned int)...+0" range=>=0 return total; @@ -856,18 +856,18 @@ int notequal_type_endpoint(unsigned n) { void notequal_refinement(short n) { if (n < 0) { - range(n); + range(n); // $ range=<=-1 return; } if (n == 0) { range(n); // 0 .. 0 } else { - range(n); // 1 .. + range(n); // $ range=>=1 } if (n) { - range(n); // 1 .. + range(n); // $ range=>=1 } else { range(n); // 0 .. 0 } @@ -883,16 +883,16 @@ void notequal_refinement(short n) { void notequal_variations(short n, float f) { if (n != 0) { if (n >= 0) { - range(n); // 1 .. [BUG: we can't handle `!=` coming first] + range(n); // $ range=>=1 } } if (n >= 5) { if (2 * n - 10 == 0) { // Same as `n == 10/2` (modulo overflow) - range(n); + range(n); // $ range=>=5 MISSING: range===5 return; } - range(n); // 6 .. + range(n); // $ range=>=5 MISSING: range=>=6 } if (n != -32768 && n != -32767) { @@ -900,8 +900,12 @@ void notequal_variations(short n, float f) { } if (n >= 0) { - n ? (range(n), n) : (range(n), n); // ? 1.. : 0..0 - !n ? (range(n), n) : (range(n), n); // ? 0..0 : 1.. + n ? + (range(n), n) // $ range=>=1 + : (range(n), n); // $ MISSING: range===0 + !n ? + (range(n), n) // $ MISSING: range===0 + : (range(n), n); // $ range=>=1 } } @@ -917,7 +921,7 @@ void two_bounds_from_one_test(short ss, unsigned short us) { } if (ss < 0x8001) { // Lower bound removed in `getDefLowerBounds` - range(ss); // -32768 .. 32767 + range(ss); // $ range=<=32768 MISSING: range=>=-32768 } if ((short)us >= 0) { @@ -942,7 +946,7 @@ void widen_recursive_expr() { for (s = 0; s < 10; s++) { range(s); // $ range=<=9 range=>=0 int result = s + s; - range(result); // 0 .. 18 + range(result); // $ range=>=0 range=>=s+0 // 0 .. 18 } } From 6e38105615a68d3078ddd1f0f4fb6ad1d54ee106 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen <mathiasvp@github.com> Date: Tue, 21 Mar 2023 16:52:51 +0000 Subject: [PATCH 308/631] C++: Fix implicit 'this'. --- .../semmle/code/cpp/semantic/SemanticExprSpecific.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpp/ql/lib/experimental/semmle/code/cpp/semantic/SemanticExprSpecific.qll b/cpp/ql/lib/experimental/semmle/code/cpp/semantic/SemanticExprSpecific.qll index 6c3f56fd924..afffba57ae5 100644 --- a/cpp/ql/lib/experimental/semmle/code/cpp/semantic/SemanticExprSpecific.qll +++ b/cpp/ql/lib/experimental/semmle/code/cpp/semantic/SemanticExprSpecific.qll @@ -79,7 +79,7 @@ module SemanticExprConfig { string toString() { result = this.getUnconverted().toString() } /** Gets the basic block of this expression. */ - IR::IRBlock getBlock() { result = getInstruction(0).getBlock() } + IR::IRBlock getBlock() { result = this.getUnconverted().getBlock() } /** Gets the unconverted instruction associated with this expression. */ IR::Instruction getUnconverted() { result = this.getInstruction(0) } From d325082db31cb7590fc50e20926cb81e1fd893c2 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen <mathiasvp@github.com> Date: Tue, 21 Mar 2023 17:40:35 +0000 Subject: [PATCH 309/631] C++: Fix another place that assumed that 'Expr' was always 'Instruction'. --- .../src/experimental/Likely Bugs/OverrunWriteProductFlow.ql | 4 ++-- .../Security/CWE/CWE-193/ConstantSizeArrayOffByOne.ql | 2 +- .../experimental/Security/CWE/CWE-193/InvalidPointerDeref.ql | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/cpp/ql/src/experimental/Likely Bugs/OverrunWriteProductFlow.ql b/cpp/ql/src/experimental/Likely Bugs/OverrunWriteProductFlow.ql index 5e0d1d7b5bb..2cadfc12f04 100644 --- a/cpp/ql/src/experimental/Likely Bugs/OverrunWriteProductFlow.ql +++ b/cpp/ql/src/experimental/Likely Bugs/OverrunWriteProductFlow.ql @@ -24,7 +24,7 @@ import DataFlow::PathGraph pragma[nomagic] Instruction getABoundIn(SemBound b, IRFunction func) { - result = b.getExpr(0) and + getSemanticExpr(result) = b.getExpr(0) and result.getEnclosingIRFunction() = func } @@ -110,7 +110,7 @@ class StringSizeConfiguration extends ProductFlow::Configuration { state1 = s1.toString() and state2 = s2.toString() and add.hasOperands(node1.asOperand(), op) and - semBounded(op.getDef(), any(SemZeroBound zero), delta, true, _) and + semBounded(getSemanticExpr(op.getDef()), any(SemZeroBound zero), delta, true, _) and node2.asInstruction() = add and s1 = s2 + delta ) diff --git a/cpp/ql/src/experimental/Security/CWE/CWE-193/ConstantSizeArrayOffByOne.ql b/cpp/ql/src/experimental/Security/CWE/CWE-193/ConstantSizeArrayOffByOne.ql index 35cce4a30da..7a10b2ac544 100644 --- a/cpp/ql/src/experimental/Security/CWE/CWE-193/ConstantSizeArrayOffByOne.ql +++ b/cpp/ql/src/experimental/Security/CWE/CWE-193/ConstantSizeArrayOffByOne.ql @@ -19,7 +19,7 @@ import PointerArithmeticToDerefFlow::PathGraph pragma[nomagic] Instruction getABoundIn(SemBound b, IRFunction func) { - result = b.getExpr(0) and + getSemanticExpr(result) = b.getExpr(0) and result.getEnclosingIRFunction() = func } diff --git a/cpp/ql/src/experimental/Security/CWE/CWE-193/InvalidPointerDeref.ql b/cpp/ql/src/experimental/Security/CWE/CWE-193/InvalidPointerDeref.ql index 9cadcb505d0..069b5dc7108 100644 --- a/cpp/ql/src/experimental/Security/CWE/CWE-193/InvalidPointerDeref.ql +++ b/cpp/ql/src/experimental/Security/CWE/CWE-193/InvalidPointerDeref.ql @@ -24,7 +24,7 @@ import semmle.code.cpp.ir.IR pragma[nomagic] Instruction getABoundIn(SemBound b, IRFunction func) { - result = b.getExpr(0) and + getSemanticExpr(result) = b.getExpr(0) and result.getEnclosingIRFunction() = func } From 0c6b60b2c6f9ee2e92aee80c3f1adcb6fa978084 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen <mathiasvp@github.com> Date: Wed, 22 Mar 2023 12:54:28 +0000 Subject: [PATCH 310/631] C++: Avoid two joins on value number. --- .../cpp/semantic/SemanticExprSpecific.qll | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/cpp/ql/lib/experimental/semmle/code/cpp/semantic/SemanticExprSpecific.qll b/cpp/ql/lib/experimental/semmle/code/cpp/semantic/SemanticExprSpecific.qll index afffba57ae5..9d69154baa4 100644 --- a/cpp/ql/lib/experimental/semmle/code/cpp/semantic/SemanticExprSpecific.qll +++ b/cpp/ql/lib/experimental/semmle/code/cpp/semantic/SemanticExprSpecific.qll @@ -215,7 +215,7 @@ module SemanticExprConfig { newtype TSsaVariable = TSsaInstruction(IR::Instruction instr) { instr.hasMemoryResult() } or TSsaOperand(IR::Operand op) { op.isDefinitionInexact() } or - TSsaPointerArithmeticGuard(IR::PointerArithmeticInstruction instr) { + TSsaPointerArithmeticGuard(ValueNumber instr) { exists(Guard g, IR::Operand use | use = instr.getAUse() | g.comparesLt(use, _, _, _, _) or g.comparesLt(_, use, _, _, _) or @@ -231,7 +231,7 @@ module SemanticExprConfig { IR::Instruction asInstruction() { none() } - IR::PointerArithmeticInstruction asPointerArithGuard() { none() } + ValueNumber asPointerArithGuard() { none() } IR::Operand asOperand() { none() } } @@ -249,15 +249,15 @@ module SemanticExprConfig { } class SsaPointerArithmeticGuard extends SsaVariable, TSsaPointerArithmeticGuard { - IR::PointerArithmeticInstruction instr; + ValueNumber vn; - SsaPointerArithmeticGuard() { this = TSsaPointerArithmeticGuard(instr) } + SsaPointerArithmeticGuard() { this = TSsaPointerArithmeticGuard(vn) } - final override string toString() { result = instr.toString() } + final override string toString() { result = vn.toString() } - final override Location getLocation() { result = instr.getLocation() } + final override Location getLocation() { result = vn.getLocation() } - final override IR::PointerArithmeticInstruction asPointerArithGuard() { result = instr } + final override ValueNumber asPointerArithGuard() { result = vn } } class SsaOperand extends SsaVariable, TSsaOperand { @@ -289,7 +289,7 @@ module SemanticExprConfig { Expr getAUse(SsaVariable v) { result.getUnconverted().(IR::LoadInstruction).getSourceValue() = v.asInstruction() or - result.getUnconverted() = valueNumber(v.asPointerArithGuard()).getAnInstruction() + result.getUnconverted() = v.asPointerArithGuard().getAnInstruction() } SemType getSsaVariableType(SsaVariable v) { @@ -331,7 +331,7 @@ module SemanticExprConfig { final override predicate hasRead(SsaVariable v) { exists(IR::Operand operand | operand.getDef() = v.asInstruction() or - operand.getDef() = valueNumber(v.asPointerArithGuard()).getAnInstruction() + operand.getDef() = v.asPointerArithGuard().getAnInstruction() | not operand instanceof IR::PhiInputOperand and operand.getUse().getBlock() = block @@ -352,7 +352,7 @@ module SemanticExprConfig { final override predicate hasRead(SsaVariable v) { exists(IR::PhiInputOperand operand | operand.getDef() = v.asInstruction() or - operand.getDef() = valueNumber(v.asPointerArithGuard()).getAnInstruction() + operand.getDef() = v.asPointerArithGuard().getAnInstruction() | operand.getPredecessorBlock() = pred and operand.getUse().getBlock() = succ From cd7ba7c5039118a27ab73e479e56d837a33b6131 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen <mathiasvp@github.com> Date: Wed, 22 Mar 2023 12:54:50 +0000 Subject: [PATCH 311/631] C++: Fix join orders in 'eqBound'. --- .../code/cpp/semantic/analysis/SignAnalysisCommon.qll | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/cpp/ql/lib/experimental/semmle/code/cpp/semantic/analysis/SignAnalysisCommon.qll b/cpp/ql/lib/experimental/semmle/code/cpp/semantic/analysis/SignAnalysisCommon.qll index 94ef40e83fa..4e2c0cb98c8 100644 --- a/cpp/ql/lib/experimental/semmle/code/cpp/semantic/analysis/SignAnalysisCommon.qll +++ b/cpp/ql/lib/experimental/semmle/code/cpp/semantic/analysis/SignAnalysisCommon.qll @@ -328,10 +328,11 @@ module SignAnalysis<DeltaSig D, UtilSig<D> Utils> { * - `isEq = false` : `v != eqbound` */ private predicate eqBound(SemExpr eqbound, SemSsaVariable v, SemSsaReadPosition pos, boolean isEq) { - exists(SemGuard guard, boolean testIsTrue, boolean polarity | - pos.hasReadOfVar(v) and - semGuardControlsSsaRead(guard, pos, testIsTrue) and - guard.isEquality(eqbound, Utils::semSsaRead(v, D::fromInt(0)), polarity) and + exists(SemGuard guard, boolean testIsTrue, boolean polarity, SemExpr e | + pos.hasReadOfVar(pragma[only_bind_into](v)) and + semGuardControlsSsaRead(guard, pragma[only_bind_into](pos), testIsTrue) and + e = Utils::semSsaRead(pragma[only_bind_into](v), D::fromInt(0)) and + guard.isEquality(eqbound, e, polarity) and isEq = polarity.booleanXor(testIsTrue).booleanNot() and not unknownSign(eqbound) ) From 0f240d67389c77f1157a04e8dc87aa8e40ae6c26 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen <mathiasvp@github.com> Date: Wed, 22 Mar 2023 17:00:07 +0000 Subject: [PATCH 312/631] C++: Fix join order in 'boundFlowCond'. --- .../semmle/code/cpp/semantic/analysis/RangeAnalysisStage.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpp/ql/lib/experimental/semmle/code/cpp/semantic/analysis/RangeAnalysisStage.qll b/cpp/ql/lib/experimental/semmle/code/cpp/semantic/analysis/RangeAnalysisStage.qll index cdf0943eb65..3bf0128c87b 100644 --- a/cpp/ql/lib/experimental/semmle/code/cpp/semantic/analysis/RangeAnalysisStage.qll +++ b/cpp/ql/lib/experimental/semmle/code/cpp/semantic/analysis/RangeAnalysisStage.qll @@ -495,7 +495,7 @@ module RangeStage<DeltaSig D, BoundSig<D> Bounds, LangSig<D> LangParam, UtilSig< SemSsaVariable v2, SemGuard guardEq, boolean eqIsTrue, D::Delta d1, D::Delta d2, D::Delta oldDelta | - guardEq = semEqFlowCond(v, semSsaRead(v2, d1), d2, true, eqIsTrue) and + guardEq = semEqFlowCond(v, semSsaRead(pragma[only_bind_into](v2), d1), d2, true, eqIsTrue) and result = boundFlowCond(v2, e, oldDelta, upper, testIsTrue) and // guardEq needs to control guard guardEq.directlyControls(result.getBasicBlock(), eqIsTrue) and From 0462e2a6ea3acaf45f5f495b963d60c6cba9c677 Mon Sep 17 00:00:00 2001 From: erik-krogh <erik-krogh@github.com> Date: Wed, 22 Mar 2023 15:27:21 +0100 Subject: [PATCH 313/631] update some expected output --- .../test/library-tests/CallGraphs/FullTest/tests.expected | 8 ++++++++ .../test/library-tests/TypeTracking/ClassStyle.expected | 4 ++++ .../library-tests/TypeTracking/PredicateStyle.expected | 4 ++++ .../test/library-tests/frameworks/Express/tests.expected | 3 +++ 4 files changed, 19 insertions(+) diff --git a/javascript/ql/test/library-tests/CallGraphs/FullTest/tests.expected b/javascript/ql/test/library-tests/CallGraphs/FullTest/tests.expected index 15587d7d5b3..665b52e0b1f 100644 --- a/javascript/ql/test/library-tests/CallGraphs/FullTest/tests.expected +++ b/javascript/ql/test/library-tests/CallGraphs/FullTest/tests.expected @@ -85,6 +85,7 @@ test_getAFunctionValue | es2015.js:35:1:35:3 | sum | es2015.js:31:1:33:1 | functio ... +y+z;\\n} | | es2015.js:36:1:36:3 | sum | es2015.js:31:1:33:1 | functio ... +y+z;\\n} | | m2.js:2:6:2:18 | function() {} | m2.js:2:6:2:18 | function() {} | +| m.js:1:1:1:9 | exports.f | m.js:1:13:1:25 | function() {} | | m.js:1:1:1:25 | exports ... on() {} | m.js:1:13:1:25 | function() {} | | m.js:1:13:1:25 | function() {} | m.js:1:13:1:25 | function() {} | | m.js:2:1:2:9 | exports.f | m.js:1:13:1:25 | function() {} | @@ -100,16 +101,19 @@ test_getAFunctionValue | protoclass.js:3:10:3:10 | F | protoclass.js:3:1:5:1 | functio ... it();\\n} | | protoclass.js:4:3:4:11 | this.init | protoclass.js:7:20:11:1 | functio ... m();\\n} | | protoclass.js:7:1:7:1 | F | protoclass.js:3:1:5:1 | functio ... it();\\n} | +| protoclass.js:7:1:7:16 | F.prototype.init | protoclass.js:7:20:11:1 | functio ... m();\\n} | | protoclass.js:7:1:11:1 | F.proto ... m();\\n} | protoclass.js:7:20:11:1 | functio ... m();\\n} | | protoclass.js:7:20:11:1 | functio ... m();\\n} | protoclass.js:7:20:11:1 | functio ... m();\\n} | | protoclass.js:8:3:8:13 | this.method | protoclass.js:13:22:13:34 | function() {} | | protoclass.js:9:11:9:21 | this.method | protoclass.js:13:22:13:34 | function() {} | | protoclass.js:13:1:13:1 | F | protoclass.js:3:1:5:1 | functio ... it();\\n} | +| protoclass.js:13:1:13:18 | F.prototype.method | protoclass.js:13:22:13:34 | function() {} | | protoclass.js:13:1:13:34 | F.proto ... on() {} | protoclass.js:13:22:13:34 | function() {} | | protoclass.js:13:22:13:34 | function() {} | protoclass.js:13:22:13:34 | function() {} | | protoclass.js:15:16:15:16 | F | protoclass.js:3:1:5:1 | functio ... it();\\n} | | reflection.js:1:1:3:1 | functio ... x+y;\\n} | reflection.js:1:1:3:1 | functio ... x+y;\\n} | | reflection.js:5:3:5:5 | add | reflection.js:1:1:3:1 | functio ... x+y;\\n} | +| reflection.js:5:3:5:11 | add.apply | reflection.js:5:15:5:39 | functio ... n 56; } | | reflection.js:5:3:5:39 | add.app ... n 56; } | reflection.js:5:15:5:39 | functio ... n 56; } | | reflection.js:5:15:5:14 | this | reflection.js:1:1:3:1 | functio ... x+y;\\n} | | reflection.js:5:15:5:39 | functio ... n 56; } | reflection.js:5:15:5:39 | functio ... n 56; } | @@ -163,11 +167,13 @@ test_getAFunctionValue | tst.js:42:2:42:26 | functio ... rn x; } | tst.js:42:2:42:26 | functio ... rn x; } | | tst.js:44:1:44:15 | function A() {} | tst.js:44:1:44:15 | function A() {} | | tst.js:45:1:45:1 | A | tst.js:44:1:44:15 | function A() {} | +| tst.js:45:1:45:13 | A.prototype.f | tst.js:45:17:47:1 | functio ... .g();\\n} | | tst.js:45:1:47:1 | A.proto ... .g();\\n} | tst.js:45:17:47:1 | functio ... .g();\\n} | | tst.js:45:17:47:1 | functio ... .g();\\n} | tst.js:45:17:47:1 | functio ... .g();\\n} | | tst.js:46:2:46:7 | this.g | tst.js:48:17:48:29 | function() {} | | tst.js:46:2:46:7 | this.g | tst.js:61:17:61:29 | function() {} | | tst.js:48:1:48:1 | A | tst.js:44:1:44:15 | function A() {} | +| tst.js:48:1:48:13 | A.prototype.g | tst.js:48:17:48:29 | function() {} | | tst.js:48:1:48:29 | A.proto ... on() {} | tst.js:48:17:48:29 | function() {} | | tst.js:48:17:48:29 | function() {} | tst.js:48:17:48:29 | function() {} | | tst.js:50:1:50:15 | function B() {} | tst.js:50:1:50:15 | function B() {} | @@ -186,11 +192,13 @@ test_getAFunctionValue | tst.js:60:1:60:1 | C | tst.js:59:1:59:15 | function C() {} | | tst.js:60:19:60:19 | A | tst.js:44:1:44:15 | function A() {} | | tst.js:61:1:61:1 | C | tst.js:59:1:59:15 | function C() {} | +| tst.js:61:1:61:13 | C.prototype.g | tst.js:61:17:61:29 | function() {} | | tst.js:61:1:61:29 | C.proto ... on() {} | tst.js:61:17:61:29 | function() {} | | tst.js:61:17:61:29 | function() {} | tst.js:61:17:61:29 | function() {} | | tst.js:63:1:67:2 | (functi ... f();\\n}) | tst.js:63:2:67:1 | functio ... .f();\\n} | | tst.js:63:2:67:1 | functio ... .f();\\n} | tst.js:63:2:67:1 | functio ... .f();\\n} | | tst.js:64:17:64:17 | B | tst.js:50:1:50:15 | function B() {} | +| tst.js:65:5:65:7 | b.f | tst.js:65:11:65:23 | function() {} | | tst.js:65:5:65:23 | b.f = function() {} | tst.js:65:11:65:23 | function() {} | | tst.js:65:11:65:23 | function() {} | tst.js:65:11:65:23 | function() {} | | tst.js:66:5:66:7 | b.f | tst.js:52:5:54:2 | functio ... g();\\n\\t} | diff --git a/javascript/ql/test/library-tests/TypeTracking/ClassStyle.expected b/javascript/ql/test/library-tests/TypeTracking/ClassStyle.expected index cf561c366f2..4c7ad61df3b 100644 --- a/javascript/ql/test/library-tests/TypeTracking/ClassStyle.expected +++ b/javascript/ql/test/library-tests/TypeTracking/ClassStyle.expected @@ -12,6 +12,7 @@ test_ApiObject test_Connection | client.js:1:10:1:27 | exportedConnection | | tst.js:7:15:7:18 | conn | +| tst.js:8:5:8:19 | this.connection | | tst.js:11:5:11:19 | this.connection | | tst.js:16:10:16:49 | api.cha ... ction() | | tst.js:19:7:19:21 | getConnection() | @@ -20,7 +21,9 @@ test_Connection | tst.js:48:7:48:21 | getConnection() | | tst.js:54:37:54:51 | getConnection() | | tst.js:57:14:57:48 | config. ... ction') | +| tst.js:62:3:62:36 | MyAppli ... nection | | tst.js:62:40:62:79 | api.cha ... ction() | +| tst.js:63:3:63:34 | MyAppli ... onflict | | tst.js:63:38:63:77 | api.cha ... ction() | | tst.js:67:14:67:47 | MyAppli ... nection | | tst.js:78:35:78:49 | getConnection() | @@ -41,6 +44,7 @@ test_Connection | tst.js:118:12:118:26 | getConnection() | | tst.js:120:21:120:24 | conn | | tst.js:126:22:126:25 | conn | +| tst_conflict.js:6:3:6:34 | MyAppli ... onflict | | tst_conflict.js:6:38:6:77 | api.cha ... ction() | test_DataCallback | client.js:3:28:3:34 | x => {} | diff --git a/javascript/ql/test/library-tests/TypeTracking/PredicateStyle.expected b/javascript/ql/test/library-tests/TypeTracking/PredicateStyle.expected index 17ccc170403..0925e1bc58b 100644 --- a/javascript/ql/test/library-tests/TypeTracking/PredicateStyle.expected +++ b/javascript/ql/test/library-tests/TypeTracking/PredicateStyle.expected @@ -11,6 +11,7 @@ apiObject | tst_conflict.js:6:38:6:58 | api.cha ... hain2() | connection | type tracker with call steps | tst.js:7:15:7:18 | conn | +| type tracker with call steps | tst.js:8:5:8:19 | this.connection | | type tracker with call steps | tst.js:11:5:11:19 | this.connection | | type tracker with call steps | tst.js:80:16:80:19 | conn | | type tracker with call steps | tst.js:84:22:84:22 | x | @@ -30,7 +31,9 @@ connection | type tracker without call steps | tst.js:48:7:48:21 | getConnection() | | type tracker without call steps | tst.js:54:37:54:51 | getConnection() | | type tracker without call steps | tst.js:57:14:57:48 | config. ... ction') | +| type tracker without call steps | tst.js:62:3:62:36 | MyAppli ... nection | | type tracker without call steps | tst.js:62:40:62:79 | api.cha ... ction() | +| type tracker without call steps | tst.js:63:3:63:34 | MyAppli ... onflict | | type tracker without call steps | tst.js:63:38:63:77 | api.cha ... ction() | | type tracker without call steps | tst.js:67:14:67:47 | MyAppli ... nection | | type tracker without call steps | tst.js:78:35:78:49 | getConnection() | @@ -43,6 +46,7 @@ connection | type tracker without call steps | tst.js:118:12:118:26 | getConnection() | | type tracker without call steps | tst.js:120:21:120:24 | conn | | type tracker without call steps | tst.js:126:22:126:25 | conn | +| type tracker without call steps | tst_conflict.js:6:3:6:34 | MyAppli ... onflict | | type tracker without call steps | tst_conflict.js:6:38:6:77 | api.cha ... ction() | | type tracker without call steps with property conflict | tst.js:63:3:63:25 | MyAppli ... mespace | | type tracker without call steps with property conflict | tst_conflict.js:6:3:6:25 | MyAppli ... mespace | diff --git a/javascript/ql/test/library-tests/frameworks/Express/tests.expected b/javascript/ql/test/library-tests/frameworks/Express/tests.expected index 93f9b4c578e..6b1291c52ac 100644 --- a/javascript/ql/test/library-tests/frameworks/Express/tests.expected +++ b/javascript/ql/test/library-tests/frameworks/Express/tests.expected @@ -3227,10 +3227,13 @@ getRouteHandlerContainerStep | src/route-collection.js:1:18:4:1 | {\\n a: ... (req)\\n} | src/route-collection.js:3:6:3:35 | (req, r ... og(req) | src/advanced-routehandler-registration.js:116:14:116:30 | importedRoutes[p] | | src/route-collection.js:1:18:4:1 | {\\n a: ... (req)\\n} | src/route-collection.js:3:6:3:35 | (req, r ... og(req) | src/advanced-routehandler-registration.js:119:14:119:29 | importedRoutes.b | dbUse +| src/middleware-flow.js:6:5:6:10 | req.db | | src/middleware-flow.js:6:5:6:21 | req.db = new DB() | | src/middleware-flow.js:6:14:6:21 | new DB() | +| src/middleware-flow.js:7:5:7:15 | req.deep.db | | src/middleware-flow.js:7:5:7:26 | req.dee ... ew DB() | | src/middleware-flow.js:7:19:7:26 | new DB() | +| src/middleware-flow.js:8:5:8:22 | req.deep.access.db | | src/middleware-flow.js:8:5:8:33 | req.dee ... ew DB() | | src/middleware-flow.js:8:26:8:33 | new DB() | | src/middleware-flow.js:18:9:18:14 | req.db | From c4a7389873f13640e7409a46da58dc71a0c7229b Mon Sep 17 00:00:00 2001 From: Harry Maclean <hmac@github.com> Date: Thu, 16 Mar 2023 13:08:15 +1300 Subject: [PATCH 314/631] Ruby: Move extractor into shared crate This makes it possible for different languages to share this extractor. --- ruby/extractor/Cargo.lock | Bin 17879 -> 18100 bytes ruby/extractor/Cargo.toml | 1 + ruby/extractor/src/bin/extractor.rs | 2 +- ruby/extractor/src/bin/generator.rs | 4 ++-- shared/extractor/.gitignore | 2 ++ shared/extractor/Cargo.toml | 17 +++++++++++++++++ {ruby => shared}/extractor/src/diagnostics.rs | 0 {ruby => shared}/extractor/src/extractor.rs | 0 {ruby => shared}/extractor/src/file_paths.rs | 0 .../extractor/src/generator/dbscheme.rs | 0 .../extractor/src/generator/language.rs | 0 .../extractor/src/generator/mod.rs | 0 .../extractor/src/generator/ql.rs | 0 .../extractor/src/generator/ql_gen.rs | 0 {ruby => shared}/extractor/src/lib.rs | 0 {ruby => shared}/extractor/src/node_types.rs | 0 {ruby => shared}/extractor/src/trap.rs | 0 17 files changed, 23 insertions(+), 3 deletions(-) create mode 100644 shared/extractor/.gitignore create mode 100644 shared/extractor/Cargo.toml rename {ruby => shared}/extractor/src/diagnostics.rs (100%) rename {ruby => shared}/extractor/src/extractor.rs (100%) rename {ruby => shared}/extractor/src/file_paths.rs (100%) rename {ruby => shared}/extractor/src/generator/dbscheme.rs (100%) rename {ruby => shared}/extractor/src/generator/language.rs (100%) rename {ruby => shared}/extractor/src/generator/mod.rs (100%) rename {ruby => shared}/extractor/src/generator/ql.rs (100%) rename {ruby => shared}/extractor/src/generator/ql_gen.rs (100%) rename {ruby => shared}/extractor/src/lib.rs (100%) rename {ruby => shared}/extractor/src/node_types.rs (100%) rename {ruby => shared}/extractor/src/trap.rs (100%) diff --git a/ruby/extractor/Cargo.lock b/ruby/extractor/Cargo.lock index 6722006cd3a66f84756e624dad376fc6c4d4e72c..5aaae6b3212d11c1653e24167c764a0c077dde64 100644 GIT binary patch delta 58 zcmccK&A6qPaf22oYko><Va{Y09h=FXIvSJfbgU=Oa8TZ?$*G_$kPMd7O|2*?N=z=v LFWT&)Gg%S<SAY~? delta 19 acmdne%Xqz;af24;=1-jR%A3`6`y>HRo(CoX diff --git a/ruby/extractor/Cargo.toml b/ruby/extractor/Cargo.toml index 3a36533d280..b77f8a77c76 100644 --- a/ruby/extractor/Cargo.toml +++ b/ruby/extractor/Cargo.toml @@ -22,3 +22,4 @@ lazy_static = "1.4.0" serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" chrono = { version = "0.4.19", features = ["serde"] } +codeql-extractor = { path = "../../shared/extractor" } diff --git a/ruby/extractor/src/bin/extractor.rs b/ruby/extractor/src/bin/extractor.rs index c79e3e1b51c..d7d4d6df1f2 100644 --- a/ruby/extractor/src/bin/extractor.rs +++ b/ruby/extractor/src/bin/extractor.rs @@ -11,7 +11,7 @@ use std::io::BufRead; use std::path::{Path, PathBuf}; use tree_sitter::{Language, Parser, Range}; -use ruby_extractor::{diagnostics, extractor, file_paths, node_types, trap}; +use codeql_extractor::{diagnostics, extractor, file_paths, node_types, trap}; /** * Gets the number of threads the extractor should use, by reading the diff --git a/ruby/extractor/src/bin/generator.rs b/ruby/extractor/src/bin/generator.rs index 61d8efd671b..172575bc17e 100644 --- a/ruby/extractor/src/bin/generator.rs +++ b/ruby/extractor/src/bin/generator.rs @@ -6,8 +6,8 @@ use std::io::LineWriter; use std::io::Write; use std::path::PathBuf; -use ruby_extractor::generator::{dbscheme, language::Language, ql, ql_gen}; -use ruby_extractor::node_types; +use codeql_extractor::generator::{dbscheme, language::Language, ql, ql_gen}; +use codeql_extractor::node_types; /// Given the name of the parent node, and its field information, returns a pair, /// the first of which is the field's type. The second is an optional dbscheme diff --git a/shared/extractor/.gitignore b/shared/extractor/.gitignore new file mode 100644 index 00000000000..4fffb2f89cb --- /dev/null +++ b/shared/extractor/.gitignore @@ -0,0 +1,2 @@ +/target +/Cargo.lock diff --git a/shared/extractor/Cargo.toml b/shared/extractor/Cargo.toml new file mode 100644 index 00000000000..b19133557e2 --- /dev/null +++ b/shared/extractor/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "codeql-extractor" +version = "0.1.0" +edition = "2021" +authors = ["GitHub"] + +[dependencies] +flate2 = "1.0" +tree-sitter = "0.20" +tracing = "0.1" +rayon = "1.5.0" +regex = "1.7.1" +encoding = "0.2" +lazy_static = "1.4.0" +serde = { version = "1.0", features = ["derive"] } +serde_json = "1.0" +chrono = { version = "0.4.19", features = ["serde"] } diff --git a/ruby/extractor/src/diagnostics.rs b/shared/extractor/src/diagnostics.rs similarity index 100% rename from ruby/extractor/src/diagnostics.rs rename to shared/extractor/src/diagnostics.rs diff --git a/ruby/extractor/src/extractor.rs b/shared/extractor/src/extractor.rs similarity index 100% rename from ruby/extractor/src/extractor.rs rename to shared/extractor/src/extractor.rs diff --git a/ruby/extractor/src/file_paths.rs b/shared/extractor/src/file_paths.rs similarity index 100% rename from ruby/extractor/src/file_paths.rs rename to shared/extractor/src/file_paths.rs diff --git a/ruby/extractor/src/generator/dbscheme.rs b/shared/extractor/src/generator/dbscheme.rs similarity index 100% rename from ruby/extractor/src/generator/dbscheme.rs rename to shared/extractor/src/generator/dbscheme.rs diff --git a/ruby/extractor/src/generator/language.rs b/shared/extractor/src/generator/language.rs similarity index 100% rename from ruby/extractor/src/generator/language.rs rename to shared/extractor/src/generator/language.rs diff --git a/ruby/extractor/src/generator/mod.rs b/shared/extractor/src/generator/mod.rs similarity index 100% rename from ruby/extractor/src/generator/mod.rs rename to shared/extractor/src/generator/mod.rs diff --git a/ruby/extractor/src/generator/ql.rs b/shared/extractor/src/generator/ql.rs similarity index 100% rename from ruby/extractor/src/generator/ql.rs rename to shared/extractor/src/generator/ql.rs diff --git a/ruby/extractor/src/generator/ql_gen.rs b/shared/extractor/src/generator/ql_gen.rs similarity index 100% rename from ruby/extractor/src/generator/ql_gen.rs rename to shared/extractor/src/generator/ql_gen.rs diff --git a/ruby/extractor/src/lib.rs b/shared/extractor/src/lib.rs similarity index 100% rename from ruby/extractor/src/lib.rs rename to shared/extractor/src/lib.rs diff --git a/ruby/extractor/src/node_types.rs b/shared/extractor/src/node_types.rs similarity index 100% rename from ruby/extractor/src/node_types.rs rename to shared/extractor/src/node_types.rs diff --git a/ruby/extractor/src/trap.rs b/shared/extractor/src/trap.rs similarity index 100% rename from ruby/extractor/src/trap.rs rename to shared/extractor/src/trap.rs From 74671281f93950134c04732b4d8ebf90a4e1c5ac Mon Sep 17 00:00:00 2001 From: Harry Maclean <hmac@github.com> Date: Thu, 16 Mar 2023 13:27:19 +1300 Subject: [PATCH 315/631] Ruby: Remove unused dependencies from extractor --- ruby/extractor/Cargo.lock | Bin 18100 -> 18053 bytes ruby/extractor/Cargo.toml | 4 ---- 2 files changed, 4 deletions(-) diff --git a/ruby/extractor/Cargo.lock b/ruby/extractor/Cargo.lock index 5aaae6b3212d11c1653e24167c764a0c077dde64..9672eb98e70a303d63be3b2c3269fcd4f557a95b 100644 GIT binary patch delta 26 icmdne%h=k>xZ$79WKLbJ$t-pPll^oRH+SgjNCE(ceF)?L delta 42 ycmZqeW!%!sxZ$4;dqz=yUcQpf<X<{^lPfr-C;!ysp6skEHhDRx`sQ?9IY|I$=nsMb diff --git a/ruby/extractor/Cargo.toml b/ruby/extractor/Cargo.toml index b77f8a77c76..8179a1befe3 100644 --- a/ruby/extractor/Cargo.toml +++ b/ruby/extractor/Cargo.toml @@ -7,7 +7,6 @@ edition = "2018" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -flate2 = "1.0" tree-sitter = "0.20" tree-sitter-embedded-template = { git = "https://github.com/tree-sitter/tree-sitter-embedded-template.git", rev = "203f7bd3c1bbfbd98fc19add4b8fcb213c059205" } tree-sitter-ruby = { git = "https://github.com/tree-sitter/tree-sitter-ruby.git", rev = "206c7077164372c596ffa8eaadb9435c28941364" } @@ -19,7 +18,4 @@ num_cpus = "1.14.0" regex = "1.7.1" encoding = "0.2" lazy_static = "1.4.0" -serde = { version = "1.0", features = ["derive"] } -serde_json = "1.0" -chrono = { version = "0.4.19", features = ["serde"] } codeql-extractor = { path = "../../shared/extractor" } From c90299baeef774cd88b66cb53946a39fac314bd3 Mon Sep 17 00:00:00 2001 From: Harry Maclean <hmac@github.com> Date: Thu, 16 Mar 2023 14:50:33 +1300 Subject: [PATCH 316/631] Ruby: Move codeql_threads calculation to library --- ruby/extractor/Cargo.lock | Bin 18053 -> 18053 bytes ruby/extractor/Cargo.toml | 1 - ruby/extractor/src/bin/extractor.rs | 31 ++------------------ shared/extractor/Cargo.toml | 1 + shared/extractor/src/lib.rs | 1 + shared/extractor/src/options.rs | 44 ++++++++++++++++++++++++++++ 6 files changed, 48 insertions(+), 30 deletions(-) create mode 100644 shared/extractor/src/options.rs diff --git a/ruby/extractor/Cargo.lock b/ruby/extractor/Cargo.lock index 9672eb98e70a303d63be3b2c3269fcd4f557a95b..8d7f908a802efb7f2c2ea6fc9e87dbce8163cf30 100644 GIT binary patch delta 27 jcmZqeWo+$b+%TDQ@=s0f$<DfBo0oG=RNm~W>mUgLl#vPH delta 27 jcmZqeWo+$b+%TDQva7Dh<}I8Pl_yW;RNNe?t0M^jj@k)+ diff --git a/ruby/extractor/Cargo.toml b/ruby/extractor/Cargo.toml index 8179a1befe3..439d86d4c41 100644 --- a/ruby/extractor/Cargo.toml +++ b/ruby/extractor/Cargo.toml @@ -14,7 +14,6 @@ clap = "3.0" tracing = "0.1" tracing-subscriber = { version = "0.3.3", features = ["env-filter"] } rayon = "1.5.0" -num_cpus = "1.14.0" regex = "1.7.1" encoding = "0.2" lazy_static = "1.4.0" diff --git a/ruby/extractor/src/bin/extractor.rs b/ruby/extractor/src/bin/extractor.rs index d7d4d6df1f2..f2a764262d4 100644 --- a/ruby/extractor/src/bin/extractor.rs +++ b/ruby/extractor/src/bin/extractor.rs @@ -1,9 +1,8 @@ #[macro_use] extern crate lazy_static; -extern crate num_cpus; use clap::arg; -use encoding::{self}; +use encoding; use rayon::prelude::*; use std::borrow::Cow; use std::fs; @@ -13,32 +12,6 @@ use tree_sitter::{Language, Parser, Range}; use codeql_extractor::{diagnostics, extractor, file_paths, node_types, trap}; -/** - * Gets the number of threads the extractor should use, by reading the - * CODEQL_THREADS environment variable and using it as described in the - * extractor spec: - * - * "If the number is positive, it indicates the number of threads that should - * be used. If the number is negative or zero, it should be added to the number - * of cores available on the machine to determine how many threads to use - * (minimum of 1). If unspecified, should be considered as set to -1." - */ -fn num_codeql_threads() -> Result<usize, String> { - let threads_str = std::env::var("CODEQL_THREADS").unwrap_or_else(|_| "-1".to_owned()); - match threads_str.parse::<i32>() { - Ok(num) if num <= 0 => { - let reduction = -num as usize; - Ok(std::cmp::max(1, num_cpus::get() - reduction)) - } - Ok(num) => Ok(num as usize), - - Err(_) => Err(format!( - "Unable to parse CODEQL_THREADS value '{}'", - &threads_str - )), - } -} - lazy_static! { static ref CP_NUMBER: regex::Regex = regex::Regex::new("cp([0-9]+)").unwrap(); } @@ -67,7 +40,7 @@ fn main() -> std::io::Result<()> { .init(); let diagnostics = diagnostics::DiagnosticLoggers::new("ruby"); let mut main_thread_logger = diagnostics.logger(); - let num_threads = match num_codeql_threads() { + let num_threads = match codeql_extractor::options::num_threads() { Ok(num) => num, Err(e) => { main_thread_logger.write( diff --git a/shared/extractor/Cargo.toml b/shared/extractor/Cargo.toml index b19133557e2..4aa363f2965 100644 --- a/shared/extractor/Cargo.toml +++ b/shared/extractor/Cargo.toml @@ -15,3 +15,4 @@ lazy_static = "1.4.0" serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" chrono = { version = "0.4.19", features = ["serde"] } +num_cpus = "1.14.0" diff --git a/shared/extractor/src/lib.rs b/shared/extractor/src/lib.rs index 88c54864f4b..eb175417993 100644 --- a/shared/extractor/src/lib.rs +++ b/shared/extractor/src/lib.rs @@ -3,4 +3,5 @@ pub mod extractor; pub mod file_paths; pub mod generator; pub mod node_types; +pub mod options; pub mod trap; diff --git a/shared/extractor/src/options.rs b/shared/extractor/src/options.rs new file mode 100644 index 00000000000..1b43a215994 --- /dev/null +++ b/shared/extractor/src/options.rs @@ -0,0 +1,44 @@ +use num_cpus; + +/// Gets the number of threads the extractor should use. +/// This is controlled by the CODEQL_THREADS environment variable. +pub fn num_threads() -> Result<usize, String> { + let threads_str = std::env::var("CODEQL_THREADS").unwrap_or_else(|_| "-1".into()); + let num_cpus = num_cpus::get(); + parse_codeql_threads(&threads_str, num_cpus) + .ok_or_else(|| format!("Unable to parse CODEQL_THREADS value '{}'", &threads_str)) +} + +/// Parses the given string to determine the number of threads the extractor +/// should use, as described in the extractor spec: +/// +/// "If the number is positive, it indicates the number of threads that should +/// be used. If the number is negative or zero, it should be added to the number +/// of cores available on the machine to determine how many threads to use +/// (minimum of 1). If unspecified, should be considered as set to -1." +/// +/// # Examples +/// +/// ``` +/// use codeql_extractor::options::parse_codeql_threads; +/// +/// assert_eq!(parse_codeql_threads("1", 4), Some(1)); +/// assert_eq!(parse_codeql_threads("5", 4), Some(5)); +/// assert_eq!(parse_codeql_threads("0", 4), Some(4)); +/// assert_eq!(parse_codeql_threads("-1", 4), Some(3)); +/// assert_eq!(parse_codeql_threads("-3", 4), Some(1)); +/// assert_eq!(parse_codeql_threads("-4", 4), Some(1)); +/// assert_eq!(parse_codeql_threads("-5", 4), Some(1)); +/// assert_eq!(parse_codeql_threads("nope", 4), None); +/// ``` +pub fn parse_codeql_threads(threads_str: &str, num_cpus: usize) -> Option<usize> { + match threads_str.parse::<i32>() { + Ok(num) if num <= 0 => { + let reduction = num.abs_diff(0) as usize; + Some(std::cmp::max(1, num_cpus.saturating_sub(reduction))) + } + Ok(num) => Some(num as usize), + + Err(_) => None, + } +} From 6171eae7a2db52d4c05bcd95a4397e6883253c99 Mon Sep 17 00:00:00 2001 From: Harry Maclean <hmac@github.com> Date: Thu, 16 Mar 2023 15:05:13 +1300 Subject: [PATCH 317/631] QL: Use shared extractor library --- ql/Cargo.lock | Bin 22516 -> 24490 bytes ql/Cargo.toml | 1 - ql/extractor/Cargo.toml | 4 +- ql/extractor/src/extractor.rs | 650 ---------------------------------- ql/extractor/src/main.rs | 83 ++--- ql/extractor/src/trap.rs | 275 -------------- ql/generator/Cargo.toml | 2 +- ql/generator/src/dbscheme.rs | 130 ------- ql/generator/src/language.rs | 4 - ql/generator/src/main.rs | 9 +- ql/generator/src/ql.rs | 295 --------------- ql/generator/src/ql_gen.rs | 565 ----------------------------- ql/node-types/Cargo.toml | 11 - ql/node-types/src/lib.rs | 449 ----------------------- 14 files changed, 48 insertions(+), 2430 deletions(-) delete mode 100644 ql/extractor/src/extractor.rs delete mode 100644 ql/extractor/src/trap.rs delete mode 100644 ql/generator/src/dbscheme.rs delete mode 100644 ql/generator/src/language.rs delete mode 100644 ql/generator/src/ql.rs delete mode 100644 ql/generator/src/ql_gen.rs delete mode 100644 ql/node-types/Cargo.toml delete mode 100644 ql/node-types/src/lib.rs diff --git a/ql/Cargo.lock b/ql/Cargo.lock index f1428bd8beaef8845004c2df1c2df279e95c1e92..8d355f264b1d2baa67fd0b099873a80ce1222c5f 100644 GIT binary patch delta 1252 zcmaKs&1zFo5XT9k#T37wmZBmt6&Gz2&iBWnRF|%-YZu|1Gc%f+CT;FTS~r3VSMKgx zxKYRh_zdpciEp4FU3(JSP*Ri4<;<BoGr#%IaQ=L*efnDaa;1K`z#-tMR^P8(J?ypc zs2qk={n*;9c9-hw*iQrK_Fp!)>WwD#LWyE>?1i_-ouUk7H&rK_j~bIC6VK$-*((P9 zi8;=e<EvXwH%5EQAD8b=GuGeWu;>o@jqOI0wMARX>gU?C9TORNC7m|Wdj?#9j9N#j zJy(iIDz2qO%}xG`c^5fIN<1WE3`m33VSDx6S&de=4|vqt3kRW(1x|owe6I&X4F6DP zJVkf^Aie6&3oLS1J&ecY#kALR&D=MfMpw^Q?y#BUQ>61M@U~!Falw6CkF|Kr6uKyg zlt3R??ps477j-gZwXvwPD3ImiCM6_=EON^kND&yY<ax#2?Ul32orxHo5{t4JBel;Q zrz)K)u@Fc>l9HlB6H^R=OF}_h39E^DBMG=67MMuRI+V<7Oa!DOq81+9VjwvKbbbJH zslILR?l>DP_sTOLJ?D;+Wn(*rpri^4Wn>gh(7|e(tV}XMWHtn$ndD>_sw6HzO~*c$ zX}rdHRvdIlL{SJ8$fqETCM9)r+9#V>-sAjr%3G~KLd@!sh*{8pPF26xSLaS{R;Y8k z)?5fhz)&#I#<_$tg{VD7i6nzyP6nN<jikIu(Rv4Y%M!#qS}COSEb;2Wllf5pr+x3j zP7um~6A^jxU_DP72=YRU2ux{8GQ}7qWt;N=T00UJSl(nojA>K-y1zC$S>@M8A0EC~ Zx|!c2oW4`#U^u$8b)$Ci_Fn7z#$Wrnk<$PG delta 109 zcmZ3rpYh9j#tm#-n+3Qs7&rU!bZ~DLmpA0)%uh+xEvYO>EuO5wu0HucxA^2QdXk$x xb)wis({d6^QjL^!xD=G~5Xx?Ht4%&*{EZ7qDA!kV@&jY3$y_G2o108Ev;ZIeCcXdw diff --git a/ql/Cargo.toml b/ql/Cargo.toml index 4bc60c3333d..bb052f81d32 100644 --- a/ql/Cargo.toml +++ b/ql/Cargo.toml @@ -3,6 +3,5 @@ members = [ "autobuilder", "extractor", "generator", - "node-types", "buramu", ] diff --git a/ql/extractor/Cargo.toml b/ql/extractor/Cargo.toml index e7dc17f2feb..4f9b4aebef0 100644 --- a/ql/extractor/Cargo.toml +++ b/ql/extractor/Cargo.toml @@ -7,8 +7,6 @@ edition = "2018" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -flate2 = "1.0" -node-types = { path = "../node-types" } tree-sitter = ">= 0.20, < 0.21" tree-sitter-ql = { git = "https://github.com/tree-sitter/tree-sitter-ql.git", rev = "d08db734f8dc52f6bc04db53a966603122bc6985"} tree-sitter-ql-dbscheme = { git = "https://github.com/erik-krogh/tree-sitter-ql-dbscheme.git", rev = "63e1344353f63931e88bfbc2faa2e78e1421b213"} @@ -19,5 +17,5 @@ clap = "2.33" tracing = "0.1" tracing-subscriber = { version = "0.3.16", features = ["env-filter"] } rayon = "1.7.0" -num_cpus = "1.14.0" regex = "1.7.2" +codeql-extractor = { path = "../../shared/extractor" } diff --git a/ql/extractor/src/extractor.rs b/ql/extractor/src/extractor.rs deleted file mode 100644 index f5557e5a188..00000000000 --- a/ql/extractor/src/extractor.rs +++ /dev/null @@ -1,650 +0,0 @@ -use crate::trap; -use node_types::{EntryKind, Field, NodeTypeMap, Storage, TypeName}; -use std::collections::BTreeMap as Map; -use std::collections::BTreeSet as Set; -use std::fmt; -use std::path::Path; - -use tracing::{error, info, span, Level}; -use tree_sitter::{Language, Node, Parser, Range, Tree}; - -pub fn populate_file(writer: &mut trap::Writer, absolute_path: &Path) -> trap::Label { - let (file_label, fresh) = - writer.global_id(&trap::full_id_for_file(&normalize_path(absolute_path))); - if fresh { - writer.add_tuple( - "files", - vec![ - trap::Arg::Label(file_label), - trap::Arg::String(normalize_path(absolute_path)), - ], - ); - populate_parent_folders(writer, file_label, absolute_path.parent()); - } - file_label -} - -fn populate_empty_file(writer: &mut trap::Writer) -> trap::Label { - let (file_label, fresh) = writer.global_id("empty;sourcefile"); - if fresh { - writer.add_tuple( - "files", - vec![ - trap::Arg::Label(file_label), - trap::Arg::String("".to_string()), - ], - ); - } - file_label -} - -pub fn populate_empty_location(writer: &mut trap::Writer) { - let file_label = populate_empty_file(writer); - location(writer, file_label, 0, 0, 0, 0); -} - -pub fn populate_parent_folders( - writer: &mut trap::Writer, - child_label: trap::Label, - path: Option<&Path>, -) { - let mut path = path; - let mut child_label = child_label; - loop { - match path { - None => break, - Some(folder) => { - let (folder_label, fresh) = - writer.global_id(&trap::full_id_for_folder(&normalize_path(folder))); - writer.add_tuple( - "containerparent", - vec![ - trap::Arg::Label(folder_label), - trap::Arg::Label(child_label), - ], - ); - if fresh { - writer.add_tuple( - "folders", - vec![ - trap::Arg::Label(folder_label), - trap::Arg::String(normalize_path(folder)), - ], - ); - path = folder.parent(); - child_label = folder_label; - } else { - break; - } - } - } - } -} - -fn location( - writer: &mut trap::Writer, - file_label: trap::Label, - start_line: usize, - start_column: usize, - end_line: usize, - end_column: usize, -) -> trap::Label { - let (loc_label, fresh) = writer.global_id(&format!( - "loc,{{{}}},{},{},{},{}", - file_label, start_line, start_column, end_line, end_column - )); - if fresh { - writer.add_tuple( - "locations_default", - vec![ - trap::Arg::Label(loc_label), - trap::Arg::Label(file_label), - trap::Arg::Int(start_line), - trap::Arg::Int(start_column), - trap::Arg::Int(end_line), - trap::Arg::Int(end_column), - ], - ); - } - loc_label -} - -/// Extracts the source file at `path`, which is assumed to be canonicalized. -pub fn extract( - language: Language, - language_prefix: &str, - schema: &NodeTypeMap, - trap_writer: &mut trap::Writer, - path: &Path, - source: &[u8], - ranges: &[Range], -) -> std::io::Result<()> { - let path_str = format!("{}", path.display()); - let span = span!( - Level::TRACE, - "extract", - file = %path_str - ); - - let _enter = span.enter(); - - info!("extracting: {}", path_str); - - let mut parser = Parser::new(); - parser.set_language(language).unwrap(); - parser.set_included_ranges(ranges).unwrap(); - let tree = parser.parse(&source, None).expect("Failed to parse file"); - trap_writer.comment(format!("Auto-generated TRAP file for {}", path_str)); - let file_label = populate_file(trap_writer, path); - let mut visitor = Visitor::new( - source, - trap_writer, - // TODO: should we handle path strings that are not valid UTF8 better? - &path_str, - file_label, - language_prefix, - schema, - ); - traverse(&tree, &mut visitor); - - parser.reset(); - Ok(()) -} - -/// Normalizes the path according the common CodeQL specification. Assumes that -/// `path` has already been canonicalized using `std::fs::canonicalize`. -fn normalize_path(path: &Path) -> String { - if cfg!(windows) { - // The way Rust canonicalizes paths doesn't match the CodeQL spec, so we - // have to do a bit of work removing certain prefixes and replacing - // backslashes. - let mut components: Vec<String> = Vec::new(); - for component in path.components() { - match component { - std::path::Component::Prefix(prefix) => match prefix.kind() { - std::path::Prefix::Disk(letter) | std::path::Prefix::VerbatimDisk(letter) => { - components.push(format!("{}:", letter as char)); - } - std::path::Prefix::Verbatim(x) | std::path::Prefix::DeviceNS(x) => { - components.push(x.to_string_lossy().to_string()); - } - std::path::Prefix::UNC(server, share) - | std::path::Prefix::VerbatimUNC(server, share) => { - components.push(server.to_string_lossy().to_string()); - components.push(share.to_string_lossy().to_string()); - } - }, - std::path::Component::Normal(n) => { - components.push(n.to_string_lossy().to_string()); - } - std::path::Component::RootDir => {} - std::path::Component::CurDir => {} - std::path::Component::ParentDir => {} - } - } - components.join("/") - } else { - // For other operating systems, we can use the canonicalized path - // without modifications. - format!("{}", path.display()) - } -} - -struct ChildNode { - field_name: Option<&'static str>, - label: trap::Label, - type_name: TypeName, -} - -struct Visitor<'a> { - /// The file path of the source code (as string) - path: &'a str, - /// The label to use whenever we need to refer to the `@file` entity of this - /// source file. - file_label: trap::Label, - /// The source code as a UTF-8 byte array - source: &'a [u8], - /// A trap::Writer to accumulate trap entries - trap_writer: &'a mut trap::Writer, - /// A counter for top-level child nodes - toplevel_child_counter: usize, - /// Language-specific name of the AST info table - ast_node_info_table_name: String, - /// Language-specific name of the tokeninfo table - tokeninfo_table_name: String, - /// A lookup table from type name to node types - schema: &'a NodeTypeMap, - /// A stack for gathering information from child nodes. Whenever a node is - /// entered the parent's [Label], child counter, and an empty list is pushed. - /// All children append their data to the list. When the visitor leaves a - /// node the list containing the child data is popped from the stack and - /// matched against the dbscheme for the node. If the expectations are met - /// the corresponding row definitions are added to the trap_output. - stack: Vec<(trap::Label, usize, Vec<ChildNode>)>, -} - -impl<'a> Visitor<'a> { - fn new( - source: &'a [u8], - trap_writer: &'a mut trap::Writer, - path: &'a str, - file_label: trap::Label, - language_prefix: &str, - schema: &'a NodeTypeMap, - ) -> Visitor<'a> { - Visitor { - path, - file_label, - source, - trap_writer, - toplevel_child_counter: 0, - ast_node_info_table_name: format!("{}_ast_node_info", language_prefix), - tokeninfo_table_name: format!("{}_tokeninfo", language_prefix), - schema, - stack: Vec::new(), - } - } - - fn record_parse_error( - &mut self, - error_message: String, - full_error_message: String, - loc: trap::Label, - ) { - error!("{}", full_error_message); - let id = self.trap_writer.fresh_id(); - self.trap_writer.add_tuple( - "diagnostics", - vec![ - trap::Arg::Label(id), - trap::Arg::Int(40), // severity 40 = error - trap::Arg::String("parse_error".to_string()), - trap::Arg::String(error_message), - trap::Arg::String(full_error_message), - trap::Arg::Label(loc), - ], - ); - } - - fn record_parse_error_for_node( - &mut self, - error_message: String, - full_error_message: String, - node: Node, - ) { - let (start_line, start_column, end_line, end_column) = location_for(self.source, node); - let loc = location( - self.trap_writer, - self.file_label, - start_line, - start_column, - end_line, - end_column, - ); - self.record_parse_error(error_message, full_error_message, loc); - } - - fn enter_node(&mut self, node: Node) -> bool { - if node.is_error() || node.is_missing() { - let error_message = if node.is_missing() { - format!("parse error: expecting '{}'", node.kind()) - } else { - "parse error".to_string() - }; - let full_error_message = format!( - "{}:{}: {}", - &self.path, - node.start_position().row + 1, - error_message - ); - self.record_parse_error_for_node(error_message, full_error_message, node); - return false; - } - - let id = self.trap_writer.fresh_id(); - - self.stack.push((id, 0, Vec::new())); - true - } - - fn leave_node(&mut self, field_name: Option<&'static str>, node: Node) { - if node.is_error() || node.is_missing() { - return; - } - let (id, _, child_nodes) = self.stack.pop().expect("Vistor: empty stack"); - let (start_line, start_column, end_line, end_column) = location_for(self.source, node); - let loc = location( - self.trap_writer, - self.file_label, - start_line, - start_column, - end_line, - end_column, - ); - let table = self - .schema - .get(&TypeName { - kind: node.kind().to_owned(), - named: node.is_named(), - }) - .unwrap(); - let mut valid = true; - let (parent_id, parent_index) = match self.stack.last_mut() { - Some(p) if !node.is_extra() => { - p.1 += 1; - (p.0, p.1 - 1) - } - _ => { - self.toplevel_child_counter += 1; - (self.file_label, self.toplevel_child_counter - 1) - } - }; - match &table.kind { - EntryKind::Token { kind_id, .. } => { - self.trap_writer.add_tuple( - &self.ast_node_info_table_name, - vec![ - trap::Arg::Label(id), - trap::Arg::Label(parent_id), - trap::Arg::Int(parent_index), - trap::Arg::Label(loc), - ], - ); - self.trap_writer.add_tuple( - &self.tokeninfo_table_name, - vec![ - trap::Arg::Label(id), - trap::Arg::Int(*kind_id), - sliced_source_arg(self.source, node), - ], - ); - } - EntryKind::Table { - fields, - name: table_name, - } => { - if let Some(args) = self.complex_node(&node, fields, &child_nodes, id) { - self.trap_writer.add_tuple( - &self.ast_node_info_table_name, - vec![ - trap::Arg::Label(id), - trap::Arg::Label(parent_id), - trap::Arg::Int(parent_index), - trap::Arg::Label(loc), - ], - ); - let mut all_args = vec![trap::Arg::Label(id)]; - all_args.extend(args); - self.trap_writer.add_tuple(table_name, all_args); - } - } - _ => { - let error_message = format!("unknown table type: '{}'", node.kind()); - let full_error_message = format!( - "{}:{}: {}", - &self.path, - node.start_position().row + 1, - error_message - ); - self.record_parse_error(error_message, full_error_message, loc); - - valid = false; - } - } - if valid && !node.is_extra() { - // Extra nodes are independent root nodes and do not belong to the parent node - // Therefore we should not register them in the parent vector - if let Some(parent) = self.stack.last_mut() { - parent.2.push(ChildNode { - field_name, - label: id, - type_name: TypeName { - kind: node.kind().to_owned(), - named: node.is_named(), - }, - }); - }; - } - } - - fn complex_node( - &mut self, - node: &Node, - fields: &[Field], - child_nodes: &[ChildNode], - parent_id: trap::Label, - ) -> Option<Vec<trap::Arg>> { - let mut map: Map<&Option<String>, (&Field, Vec<trap::Arg>)> = Map::new(); - for field in fields { - map.insert(&field.name, (field, Vec::new())); - } - for child_node in child_nodes { - if let Some((field, values)) = map.get_mut(&child_node.field_name.map(|x| x.to_owned())) - { - //TODO: handle error and missing nodes - if self.type_matches(&child_node.type_name, &field.type_info) { - if let node_types::FieldTypeInfo::ReservedWordInt(int_mapping) = - &field.type_info - { - // We can safely unwrap because type_matches checks the key is in the map. - let (int_value, _) = int_mapping.get(&child_node.type_name.kind).unwrap(); - values.push(trap::Arg::Int(*int_value)); - } else { - values.push(trap::Arg::Label(child_node.label)); - } - } else if field.name.is_some() { - let error_message = format!( - "type mismatch for field {}::{} with type {:?} != {:?}", - node.kind(), - child_node.field_name.unwrap_or("child"), - child_node.type_name, - field.type_info - ); - let full_error_message = format!( - "{}:{}: {}", - &self.path, - node.start_position().row + 1, - error_message - ); - self.record_parse_error_for_node(error_message, full_error_message, *node); - } - } else if child_node.field_name.is_some() || child_node.type_name.named { - let error_message = format!( - "value for unknown field: {}::{} and type {:?}", - node.kind(), - &child_node.field_name.unwrap_or("child"), - &child_node.type_name - ); - let full_error_message = format!( - "{}:{}: {}", - &self.path, - node.start_position().row + 1, - error_message - ); - self.record_parse_error_for_node(error_message, full_error_message, *node); - } - } - let mut args = Vec::new(); - let mut is_valid = true; - for field in fields { - let child_values = &map.get(&field.name).unwrap().1; - match &field.storage { - Storage::Column { name: column_name } => { - if child_values.len() == 1 { - args.push(child_values.first().unwrap().clone()); - } else { - is_valid = false; - let error_message = format!( - "{} for field: {}::{}", - if child_values.is_empty() { - "missing value" - } else { - "too many values" - }, - node.kind(), - column_name - ); - let full_error_message = format!( - "{}:{}: {}", - &self.path, - node.start_position().row + 1, - error_message - ); - self.record_parse_error_for_node(error_message, full_error_message, *node); - } - } - Storage::Table { - name: table_name, - has_index, - column_name: _, - } => { - for (index, child_value) in child_values.iter().enumerate() { - if !*has_index && index > 0 { - error!( - "{}:{}: too many values for field: {}::{}", - &self.path, - node.start_position().row + 1, - node.kind(), - table_name, - ); - break; - } - let mut args = vec![trap::Arg::Label(parent_id)]; - if *has_index { - args.push(trap::Arg::Int(index)) - } - args.push(child_value.clone()); - self.trap_writer.add_tuple(table_name, args); - } - } - } - } - if is_valid { - Some(args) - } else { - None - } - } - - fn type_matches(&self, tp: &TypeName, type_info: &node_types::FieldTypeInfo) -> bool { - match type_info { - node_types::FieldTypeInfo::Single(single_type) => { - if tp == single_type { - return true; - } - if let EntryKind::Union { members } = &self.schema.get(single_type).unwrap().kind { - if self.type_matches_set(tp, members) { - return true; - } - } - } - node_types::FieldTypeInfo::Multiple { types, .. } => { - return self.type_matches_set(tp, types); - } - - node_types::FieldTypeInfo::ReservedWordInt(int_mapping) => { - return !tp.named && int_mapping.contains_key(&tp.kind) - } - } - false - } - - fn type_matches_set(&self, tp: &TypeName, types: &Set<TypeName>) -> bool { - if types.contains(tp) { - return true; - } - for other in types.iter() { - if let EntryKind::Union { members } = &self.schema.get(other).unwrap().kind { - if self.type_matches_set(tp, members) { - return true; - } - } - } - false - } -} - -// Emit a slice of a source file as an Arg. -fn sliced_source_arg(source: &[u8], n: Node) -> trap::Arg { - let range = n.byte_range(); - trap::Arg::String(String::from_utf8_lossy(&source[range.start..range.end]).into_owned()) -} - -// Emit a pair of `TrapEntry`s for the provided node, appropriately calibrated. -// The first is the location and label definition, and the second is the -// 'Located' entry. -fn location_for(source: &[u8], n: Node) -> (usize, usize, usize, usize) { - // Tree-sitter row, column values are 0-based while CodeQL starts - // counting at 1. In addition Tree-sitter's row and column for the - // end position are exclusive while CodeQL's end positions are inclusive. - // This means that all values should be incremented by 1 and in addition the - // end position needs to be shift 1 to the left. In most cases this means - // simply incrementing all values except the end column except in cases where - // the end column is 0 (start of a line). In such cases the end position must be - // set to the end of the previous line. - let start_line = n.start_position().row + 1; - let start_col = n.start_position().column + 1; - let mut end_line = n.end_position().row + 1; - let mut end_col = n.end_position().column; - if start_line > end_line || start_line == end_line && start_col > end_col { - // the range is empty, clip it to sensible values - end_line = start_line; - end_col = start_col - 1; - } else if end_col == 0 { - // end_col = 0 means that we are at the start of a line - // unfortunately 0 is invalid as column number, therefore - // we should update the end location to be the end of the - // previous line - let mut index = n.end_byte(); - if index > 0 && index <= source.len() { - index -= 1; - if source[index] != b'\n' { - error!("expecting a line break symbol, but none found while correcting end column value"); - } - end_line -= 1; - end_col = 1; - while index > 0 && source[index - 1] != b'\n' { - index -= 1; - end_col += 1; - } - } else { - error!( - "cannot correct end column value: end_byte index {} is not in range [1,{}]", - index, - source.len() - ); - } - } - (start_line, start_col, end_line, end_col) -} - -fn traverse(tree: &Tree, visitor: &mut Visitor) { - let cursor = &mut tree.walk(); - visitor.enter_node(cursor.node()); - let mut recurse = true; - loop { - if recurse && cursor.goto_first_child() { - recurse = visitor.enter_node(cursor.node()); - } else { - visitor.leave_node(cursor.field_name(), cursor.node()); - - if cursor.goto_next_sibling() { - recurse = visitor.enter_node(cursor.node()); - } else if cursor.goto_parent() { - recurse = false; - } else { - break; - } - } - } -} - -// Numeric indices. -#[derive(Debug, Copy, Clone)] -struct Index(usize); - -impl fmt::Display for Index { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{}", self.0) - } -} diff --git a/ql/extractor/src/main.rs b/ql/extractor/src/main.rs index da7f263e7ef..210abaf49d4 100644 --- a/ql/extractor/src/main.rs +++ b/ql/extractor/src/main.rs @@ -1,41 +1,9 @@ -mod extractor; -mod trap; - -extern crate num_cpus; - use rayon::prelude::*; use std::fs; use std::io::BufRead; use std::path::{Path, PathBuf}; -/** - * Gets the number of threads the extractor should use, by reading the - * CODEQL_THREADS environment variable and using it as described in the - * extractor spec: - * - * "If the number is positive, it indicates the number of threads that should - * be used. If the number is negative or zero, it should be added to the number - * of cores available on the machine to determine how many threads to use - * (minimum of 1). If unspecified, should be considered as set to -1." - */ -fn num_codeql_threads() -> usize { - let threads_str = std::env::var("CODEQL_THREADS").unwrap_or_else(|_| "-1".to_owned()); - match threads_str.parse::<i32>() { - Ok(num) if num <= 0 => { - let reduction = -num as usize; - std::cmp::max(1, num_cpus::get() - reduction) - } - Ok(num) => num as usize, - - Err(_) => { - tracing::error!( - "Unable to parse CODEQL_THREADS value '{}'; defaulting to 1 thread.", - &threads_str - ); - 1 - } - } -} +use codeql_extractor::{diagnostics, extractor, node_types, trap}; fn main() -> std::io::Result<()> { tracing_subscriber::fmt() @@ -45,7 +13,23 @@ fn main() -> std::io::Result<()> { .with_env_filter(tracing_subscriber::EnvFilter::from_default_env()) .init(); - let num_threads = num_codeql_threads(); + let diagnostics = diagnostics::DiagnosticLoggers::new("ql"); + let mut main_thread_logger = diagnostics.logger(); + let num_threads = match codeql_extractor::options::num_threads() { + Ok(num) => num, + Err(e) => { + main_thread_logger.write( + main_thread_logger + .new_entry("configuration-error", "Configuration error") + .message( + "{}; defaulting to 1 thread.", + &[diagnostics::MessageArg::Code(&e)], + ) + .severity(diagnostics::Severity::Warning), + ); + 1 + } + }; tracing::info!( "Using {} {}", num_threads, @@ -55,6 +39,20 @@ fn main() -> std::io::Result<()> { "threads" } ); + let trap_compression = match trap::Compression::from_env("CODEQL_QL_TRAP_COMPRESSION") { + Ok(x) => x, + Err(e) => { + main_thread_logger.write( + main_thread_logger + .new_entry("configuration-error", "Configuration error") + .message("{}; using gzip.", &[diagnostics::MessageArg::Code(&e)]) + .severity(diagnostics::Severity::Warning), + ); + trap::Compression::Gzip + } + }; + drop(main_thread_logger); + rayon::ThreadPoolBuilder::new() .num_threads(num_threads) .build_global() @@ -79,7 +77,6 @@ fn main() -> std::io::Result<()> { .value_of("output-dir") .expect("missing --output-dir"); let trap_dir = PathBuf::from(trap_dir); - let trap_compression = trap::Compression::from_env("CODEQL_QL_TRAP_COMPRESSION"); let file_list = matches.value_of("file-list").expect("missing --file-list"); let file_list = fs::File::open(file_list)?; @@ -119,26 +116,29 @@ fn main() -> std::io::Result<()> { let source = std::fs::read(&path)?; let code_ranges = vec![]; let mut trap_writer = trap::Writer::new(); + let mut diagnostics_writer = diagnostics.logger(); if line.ends_with(".dbscheme") { extractor::extract( dbscheme, "dbscheme", &dbscheme_schema, + &mut diagnostics_writer, &mut trap_writer, &path, &source, &code_ranges, - )? + ) } else if line.ends_with("qlpack.yml") { extractor::extract( yaml, "yaml", &yaml_schema, + &mut diagnostics_writer, &mut trap_writer, &path, &source, &code_ranges, - )? + ) } else if line.ends_with(".json") || line.ends_with(".jsonl") || line.ends_with(".jsonc") @@ -147,31 +147,34 @@ fn main() -> std::io::Result<()> { json, "json", &json_schema, + &mut diagnostics_writer, &mut trap_writer, &path, &source, &code_ranges, - )? + ) } else if line.ends_with(".blame") { extractor::extract( blame, "blame", &blame_schema, + &mut diagnostics_writer, &mut trap_writer, &path, &source, &code_ranges, - )? + ) } else { extractor::extract( language, "ql", &schema, + &mut diagnostics_writer, &mut trap_writer, &path, &source, &code_ranges, - )? + ) } std::fs::create_dir_all(&src_archive_file.parent().unwrap())?; std::fs::copy(&path, &src_archive_file)?; diff --git a/ql/extractor/src/trap.rs b/ql/extractor/src/trap.rs deleted file mode 100644 index 35a9b69f255..00000000000 --- a/ql/extractor/src/trap.rs +++ /dev/null @@ -1,275 +0,0 @@ -use std::borrow::Cow; -use std::fmt; -use std::io::{BufWriter, Write}; -use std::path::Path; - -use flate2::write::GzEncoder; - -pub struct Writer { - /// The accumulated trap entries - trap_output: Vec<Entry>, - /// A counter for generating fresh labels - counter: u32, - /// cache of global keys - global_keys: std::collections::HashMap<String, Label>, -} - -impl Writer { - pub fn new() -> Writer { - Writer { - counter: 0, - trap_output: Vec::new(), - global_keys: std::collections::HashMap::new(), - } - } - - pub fn fresh_id(&mut self) -> Label { - let label = Label(self.counter); - self.counter += 1; - self.trap_output.push(Entry::FreshId(label)); - label - } - - /// Gets a label that will hold the unique ID of the passed string at import time. - /// This can be used for incrementally importable TRAP files -- use globally unique - /// strings to compute a unique ID for table tuples. - /// - /// Note: You probably want to make sure that the key strings that you use are disjoint - /// for disjoint column types; the standard way of doing this is to prefix (or append) - /// the column type name to the ID. Thus, you might identify methods in Java by the - /// full ID "methods_com.method.package.DeclaringClass.method(argumentList)". - pub fn global_id(&mut self, key: &str) -> (Label, bool) { - if let Some(label) = self.global_keys.get(key) { - return (*label, false); - } - let label = Label(self.counter); - self.counter += 1; - self.global_keys.insert(key.to_owned(), label); - self.trap_output - .push(Entry::MapLabelToKey(label, key.to_owned())); - (label, true) - } - - pub fn add_tuple(&mut self, table_name: &str, args: Vec<Arg>) { - self.trap_output - .push(Entry::GenericTuple(table_name.to_owned(), args)) - } - - pub fn comment(&mut self, text: String) { - self.trap_output.push(Entry::Comment(text)); - } - - pub fn write_to_file(&self, path: &Path, compression: Compression) -> std::io::Result<()> { - let trap_file = std::fs::File::create(path)?; - match compression { - Compression::None => { - let mut trap_file = BufWriter::new(trap_file); - self.write_trap_entries(&mut trap_file) - } - Compression::Gzip => { - let trap_file = GzEncoder::new(trap_file, flate2::Compression::fast()); - let mut trap_file = BufWriter::new(trap_file); - self.write_trap_entries(&mut trap_file) - } - } - } - - fn write_trap_entries<W: Write>(&self, file: &mut W) -> std::io::Result<()> { - for trap_entry in &self.trap_output { - writeln!(file, "{}", trap_entry)?; - } - std::io::Result::Ok(()) - } -} - -pub enum Entry { - /// Maps the label to a fresh id, e.g. `#123=*`. - FreshId(Label), - /// Maps the label to a key, e.g. `#7=@"foo"`. - MapLabelToKey(Label, String), - /// foo_bar(arg*) - GenericTuple(String, Vec<Arg>), - Comment(String), -} - -impl fmt::Display for Entry { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match self { - Entry::FreshId(label) => write!(f, "{}=*", label), - Entry::MapLabelToKey(label, key) => { - write!(f, "{}=@\"{}\"", label, key.replace("\"", "\"\"")) - } - Entry::GenericTuple(name, args) => { - write!(f, "{}(", name)?; - for (index, arg) in args.iter().enumerate() { - if index > 0 { - write!(f, ",")?; - } - write!(f, "{}", arg)?; - } - write!(f, ")") - } - Entry::Comment(line) => write!(f, "// {}", line), - } - } -} - -#[derive(Debug, Copy, Clone)] -// Identifiers of the form #0, #1... -pub struct Label(u32); - -impl fmt::Display for Label { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "#{:x}", self.0) - } -} - -// Some untyped argument to a TrapEntry. -#[derive(Debug, Clone)] -pub enum Arg { - Label(Label), - Int(usize), - String(String), -} - -const MAX_STRLEN: usize = 1048576; - -impl fmt::Display for Arg { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match self { - Arg::Label(x) => write!(f, "{}", x), - Arg::Int(x) => write!(f, "{}", x), - Arg::String(x) => write!( - f, - "\"{}\"", - limit_string(x, MAX_STRLEN).replace("\"", "\"\"") - ), - } - } -} - -pub struct Program(Vec<Entry>); - -impl fmt::Display for Program { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - let mut text = String::new(); - for trap_entry in &self.0 { - text.push_str(&format!("{}\n", trap_entry)); - } - write!(f, "{}", text) - } -} - -pub fn full_id_for_file(normalized_path: &str) -> String { - format!("{};sourcefile", escape_key(normalized_path)) -} - -pub fn full_id_for_folder(normalized_path: &str) -> String { - format!("{};folder", escape_key(normalized_path)) -} - -/// Escapes a string for use in a TRAP key, by replacing special characters with -/// HTML entities. -fn escape_key<'a, S: Into<Cow<'a, str>>>(key: S) -> Cow<'a, str> { - fn needs_escaping(c: char) -> bool { - matches!(c, '&' | '{' | '}' | '"' | '@' | '#') - } - - let key = key.into(); - if key.contains(needs_escaping) { - let mut escaped = String::with_capacity(2 * key.len()); - for c in key.chars() { - match c { - '&' => escaped.push_str("&"), - '{' => escaped.push_str("{"), - '}' => escaped.push_str("}"), - '"' => escaped.push_str("""), - '@' => escaped.push_str("@"), - '#' => escaped.push_str("#"), - _ => escaped.push(c), - } - } - Cow::Owned(escaped) - } else { - key - } -} - -/// Limit the length (in bytes) of a string. If the string's length in bytes is -/// less than or equal to the limit then the entire string is returned. Otherwise -/// the string is sliced at the provided limit. If there is a multi-byte character -/// at the limit then the returned slice will be slightly shorter than the limit to -/// avoid splitting that multi-byte character. -fn limit_string(string: &str, max_size: usize) -> &str { - if string.len() <= max_size { - return string; - } - let p = string.as_bytes(); - let mut index = max_size; - // We want to clip the string at [max_size]; however, the character at that position - // may span several bytes. We need to find the first byte of the character. In UTF-8 - // encoded data any byte that matches the bit pattern 10XXXXXX is not a start byte. - // Therefore we decrement the index as long as there are bytes matching this pattern. - // This ensures we cut the string at the border between one character and another. - while index > 0 && (p[index] & 0b11000000) == 0b10000000 { - index -= 1; - } - &string[0..index] -} - -#[derive(Clone, Copy)] -pub enum Compression { - None, - Gzip, -} - -impl Compression { - pub fn from_env(var_name: &str) -> Compression { - match std::env::var(var_name) { - Ok(method) => match Compression::from_string(&method) { - Some(c) => c, - None => { - tracing::error!("Unknown compression method '{}'; using gzip.", &method); - Compression::Gzip - } - }, - // Default compression method if the env var isn't set: - Err(_) => Compression::Gzip, - } - } - - pub fn from_string(s: &str) -> Option<Compression> { - match s.to_lowercase().as_ref() { - "none" => Some(Compression::None), - "gzip" => Some(Compression::Gzip), - _ => None, - } - } - - pub fn extension(&self) -> &str { - match self { - Compression::None => "trap", - Compression::Gzip => "trap.gz", - } - } -} - -#[test] -fn limit_string_test() { - assert_eq!("hello", limit_string(&"hello world".to_owned(), 5)); - assert_eq!("hi ☹", limit_string(&"hi ☹☹".to_owned(), 6)); - assert_eq!("hi ", limit_string(&"hi ☹☹".to_owned(), 5)); -} - -#[test] -fn escape_key_test() { - assert_eq!("foo!", escape_key("foo!")); - assert_eq!("foo{}", escape_key("foo{}")); - assert_eq!("{}", escape_key("{}")); - assert_eq!("", escape_key("")); - assert_eq!("/path/to/foo.rb", escape_key("/path/to/foo.rb")); - assert_eq!( - "/path/to/foo&{}"@#.rb", - escape_key("/path/to/foo&{}\"@#.rb") - ); -} diff --git a/ql/generator/Cargo.toml b/ql/generator/Cargo.toml index 4fcc98be310..3a5665f33ae 100644 --- a/ql/generator/Cargo.toml +++ b/ql/generator/Cargo.toml @@ -8,7 +8,6 @@ edition = "2018" [dependencies] clap = "2.33" -node-types = { path = "../node-types" } tracing = "0.1" tracing-subscriber = { version = "0.3.16", features = ["env-filter"] } tree-sitter-ql = { git = "https://github.com/tree-sitter/tree-sitter-ql.git", rev = "d08db734f8dc52f6bc04db53a966603122bc6985"} @@ -16,3 +15,4 @@ tree-sitter-ql-dbscheme = { git = "https://github.com/erik-krogh/tree-sitter-ql- tree-sitter-ql-yaml = {git = "https://github.com/erik-krogh/tree-sitter-ql.git", rev = "cf704bf3671e1ae148e173464fb65a4d2bbf5f99"} tree-sitter-blame = {path = "../buramu/tree-sitter-blame"} tree-sitter-json = { git = "https://github.com/tausbn/tree-sitter-json.git", rev = "745663ee997f1576fe1e7187e6347e0db36ec7a9"} +codeql-extractor = { path = "../../shared/extractor" } diff --git a/ql/generator/src/dbscheme.rs b/ql/generator/src/dbscheme.rs deleted file mode 100644 index 335eee1950c..00000000000 --- a/ql/generator/src/dbscheme.rs +++ /dev/null @@ -1,130 +0,0 @@ -use crate::ql; -use std::collections::BTreeSet as Set; -use std::fmt; -/// Represents a distinct entry in the database schema. -pub enum Entry<'a> { - /// An entry defining a database table. - Table(Table<'a>), - /// An entry defining a database table. - Case(Case<'a>), - /// An entry defining type that is a union of other types. - Union(Union<'a>), -} - -/// A table in the database schema. -pub struct Table<'a> { - pub name: &'a str, - pub columns: Vec<Column<'a>>, - pub keysets: Option<Vec<&'a str>>, -} - -/// A union in the database schema. -pub struct Union<'a> { - pub name: &'a str, - pub members: Set<&'a str>, -} - -/// A table in the database schema. -pub struct Case<'a> { - pub name: &'a str, - pub column: &'a str, - pub branches: Vec<(usize, &'a str)>, -} - -/// A column in a table. -pub struct Column<'a> { - pub db_type: DbColumnType, - pub name: &'a str, - pub unique: bool, - pub ql_type: ql::Type<'a>, - pub ql_type_is_ref: bool, -} - -/// The database column type. -pub enum DbColumnType { - Int, - String, -} - -impl<'a> fmt::Display for Case<'a> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - writeln!(f, "case @{}.{} of", &self.name, &self.column)?; - let mut sep = " "; - for (c, tp) in &self.branches { - writeln!(f, "{} {} = @{}", sep, c, tp)?; - sep = "|"; - } - writeln!(f, ";") - } -} - -impl<'a> fmt::Display for Table<'a> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - if let Some(keyset) = &self.keysets { - write!(f, "#keyset[")?; - for (key_index, key) in keyset.iter().enumerate() { - if key_index > 0 { - write!(f, ", ")?; - } - write!(f, "{}", key)?; - } - writeln!(f, "]")?; - } - - writeln!(f, "{}(", self.name)?; - for (column_index, column) in self.columns.iter().enumerate() { - write!(f, " ")?; - if column.unique { - write!(f, "unique ")?; - } - write!( - f, - "{} ", - match column.db_type { - DbColumnType::Int => "int", - DbColumnType::String => "string", - } - )?; - write!(f, "{}: {}", column.name, column.ql_type)?; - if column.ql_type_is_ref { - write!(f, " ref")?; - } - if column_index + 1 != self.columns.len() { - write!(f, ",")?; - } - writeln!(f)?; - } - write!(f, ");")?; - - Ok(()) - } -} - -impl<'a> fmt::Display for Union<'a> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "@{} = ", self.name)?; - let mut first = true; - for member in &self.members { - if first { - first = false; - } else { - write!(f, " | ")?; - } - write!(f, "@{}", member)?; - } - Ok(()) - } -} - -/// Generates the dbscheme by writing the given dbscheme `entries` to the `file`. -pub fn write<'a>(file: &mut dyn std::io::Write, entries: &'a [Entry]) -> std::io::Result<()> { - for entry in entries { - match entry { - Entry::Case(case) => write!(file, "{}\n\n", case)?, - Entry::Table(table) => write!(file, "{}\n\n", table)?, - Entry::Union(union) => write!(file, "{}\n\n", union)?, - } - } - - Ok(()) -} diff --git a/ql/generator/src/language.rs b/ql/generator/src/language.rs deleted file mode 100644 index f0b0ed1790f..00000000000 --- a/ql/generator/src/language.rs +++ /dev/null @@ -1,4 +0,0 @@ -pub struct Language { - pub name: String, - pub node_types: &'static str, -} diff --git a/ql/generator/src/main.rs b/ql/generator/src/main.rs index 8c6bf63d859..8baed6d21a5 100644 --- a/ql/generator/src/main.rs +++ b/ql/generator/src/main.rs @@ -1,9 +1,3 @@ -mod dbscheme; -mod language; -mod ql; -mod ql_gen; - -use language::Language; use std::collections::BTreeMap as Map; use std::collections::BTreeSet as Set; use std::fs::File; @@ -11,6 +5,9 @@ use std::io::LineWriter; use std::io::Write; use std::path::PathBuf; +use codeql_extractor::generator::{dbscheme, language::Language, ql, ql_gen}; +use codeql_extractor::node_types; + /// Given the name of the parent node, and its field information, returns a pair, /// the first of which is the field's type. The second is an optional dbscheme /// entry that should be added. diff --git a/ql/generator/src/ql.rs b/ql/generator/src/ql.rs deleted file mode 100644 index 7dd94f24bea..00000000000 --- a/ql/generator/src/ql.rs +++ /dev/null @@ -1,295 +0,0 @@ -use std::collections::BTreeSet; -use std::fmt; - -#[derive(Clone, Eq, PartialEq, Hash)] -pub enum TopLevel<'a> { - Class(Class<'a>), - Import(Import<'a>), - Module(Module<'a>), -} - -impl<'a> fmt::Display for TopLevel<'a> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match self { - TopLevel::Import(imp) => write!(f, "{}", imp), - TopLevel::Class(cls) => write!(f, "{}", cls), - TopLevel::Module(m) => write!(f, "{}", m), - } - } -} - -#[derive(Clone, Eq, PartialEq, Hash)] -pub struct Import<'a> { - pub module: &'a str, - pub alias: Option<&'a str>, -} - -impl<'a> fmt::Display for Import<'a> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "import {}", &self.module)?; - if let Some(name) = &self.alias { - write!(f, " as {}", name)?; - } - Ok(()) - } -} -#[derive(Clone, Eq, PartialEq, Hash)] -pub struct Class<'a> { - pub qldoc: Option<String>, - pub name: &'a str, - pub is_abstract: bool, - pub supertypes: BTreeSet<Type<'a>>, - pub characteristic_predicate: Option<Expression<'a>>, - pub predicates: Vec<Predicate<'a>>, -} - -impl<'a> fmt::Display for Class<'a> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - if let Some(qldoc) = &self.qldoc { - write!(f, "/** {} */", qldoc)?; - } - if self.is_abstract { - write!(f, "abstract ")?; - } - write!(f, "class {} extends ", &self.name)?; - for (index, supertype) in self.supertypes.iter().enumerate() { - if index > 0 { - write!(f, ", ")?; - } - write!(f, "{}", supertype)?; - } - writeln!(f, " {{ ")?; - - if let Some(charpred) = &self.characteristic_predicate { - writeln!( - f, - " {}", - Predicate { - qldoc: None, - name: self.name, - overridden: false, - is_final: false, - return_type: None, - formal_parameters: vec![], - body: charpred.clone(), - } - )?; - } - - for predicate in &self.predicates { - writeln!(f, " {}", predicate)?; - } - - write!(f, "}}")?; - - Ok(()) - } -} - -#[derive(Clone, Eq, PartialEq, Hash)] -pub struct Module<'a> { - pub qldoc: Option<String>, - pub name: &'a str, - pub body: Vec<TopLevel<'a>>, -} - -impl<'a> fmt::Display for Module<'a> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - if let Some(qldoc) = &self.qldoc { - write!(f, "/** {} */", qldoc)?; - } - writeln!(f, "module {} {{ ", self.name)?; - for decl in &self.body { - writeln!(f, " {}", decl)?; - } - write!(f, "}}")?; - Ok(()) - } -} -// The QL type of a column. -#[derive(Clone, Eq, PartialEq, Hash, Ord, PartialOrd)] -pub enum Type<'a> { - /// Primitive `int` type. - Int, - - /// Primitive `string` type. - String, - - /// A database type that will need to be referred to with an `@` prefix. - At(&'a str), - - /// A user-defined type. - Normal(&'a str), -} - -impl<'a> fmt::Display for Type<'a> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match self { - Type::Int => write!(f, "int"), - Type::String => write!(f, "string"), - Type::Normal(name) => write!(f, "{}", name), - Type::At(name) => write!(f, "@{}", name), - } - } -} - -#[derive(Clone, Eq, PartialEq, Hash)] -pub enum Expression<'a> { - Var(&'a str), - String(&'a str), - Integer(usize), - Pred(&'a str, Vec<Expression<'a>>), - And(Vec<Expression<'a>>), - Or(Vec<Expression<'a>>), - Equals(Box<Expression<'a>>, Box<Expression<'a>>), - Dot(Box<Expression<'a>>, &'a str, Vec<Expression<'a>>), - Aggregate { - name: &'a str, - vars: Vec<FormalParameter<'a>>, - range: Option<Box<Expression<'a>>>, - expr: Box<Expression<'a>>, - second_expr: Option<Box<Expression<'a>>>, - }, -} - -impl<'a> fmt::Display for Expression<'a> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match self { - Expression::Var(x) => write!(f, "{}", x), - Expression::String(s) => write!(f, "\"{}\"", s), - Expression::Integer(n) => write!(f, "{}", n), - Expression::Pred(n, args) => { - write!(f, "{}(", n)?; - for (index, arg) in args.iter().enumerate() { - if index > 0 { - write!(f, ", ")?; - } - write!(f, "{}", arg)?; - } - write!(f, ")") - } - Expression::And(conjuncts) => { - if conjuncts.is_empty() { - write!(f, "any()") - } else { - for (index, conjunct) in conjuncts.iter().enumerate() { - if index > 0 { - write!(f, " and ")?; - } - write!(f, "({})", conjunct)?; - } - Ok(()) - } - } - Expression::Or(disjuncts) => { - if disjuncts.is_empty() { - write!(f, "none()") - } else { - for (index, disjunct) in disjuncts.iter().enumerate() { - if index > 0 { - write!(f, " or ")?; - } - write!(f, "({})", disjunct)?; - } - Ok(()) - } - } - Expression::Equals(a, b) => write!(f, "{} = {}", a, b), - Expression::Dot(x, member_pred, args) => { - write!(f, "{}.{}(", x, member_pred)?; - for (index, arg) in args.iter().enumerate() { - if index > 0 { - write!(f, ", ")?; - } - write!(f, "{}", arg)?; - } - write!(f, ")") - } - Expression::Aggregate { - name, - vars, - range, - expr, - second_expr, - } => { - write!(f, "{}(", name)?; - if !vars.is_empty() { - for (index, var) in vars.iter().enumerate() { - if index > 0 { - write!(f, ", ")?; - } - write!(f, "{}", var)?; - } - write!(f, " | ")?; - } - if let Some(range) = range { - write!(f, "{} | ", range)?; - } - write!(f, "{}", expr)?; - if let Some(second_expr) = second_expr { - write!(f, ", {}", second_expr)?; - } - write!(f, ")") - } - } - } -} - -#[derive(Clone, Eq, PartialEq, Hash)] -pub struct Predicate<'a> { - pub qldoc: Option<String>, - pub name: &'a str, - pub overridden: bool, - pub is_final: bool, - pub return_type: Option<Type<'a>>, - pub formal_parameters: Vec<FormalParameter<'a>>, - pub body: Expression<'a>, -} - -impl<'a> fmt::Display for Predicate<'a> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - if let Some(qldoc) = &self.qldoc { - write!(f, "/** {} */", qldoc)?; - } - if self.is_final { - write!(f, "final ")?; - } - if self.overridden { - write!(f, "override ")?; - } - match &self.return_type { - None => write!(f, "predicate ")?, - Some(return_type) => write!(f, "{} ", return_type)?, - } - write!(f, "{}(", self.name)?; - for (index, param) in self.formal_parameters.iter().enumerate() { - if index > 0 { - write!(f, ", ")?; - } - write!(f, "{}", param)?; - } - write!(f, ") {{ {} }}", self.body)?; - - Ok(()) - } -} - -#[derive(Clone, Eq, PartialEq, Hash)] -pub struct FormalParameter<'a> { - pub name: &'a str, - pub param_type: Type<'a>, -} - -impl<'a> fmt::Display for FormalParameter<'a> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{} {}", self.param_type, self.name) - } -} - -/// Generates a QL library by writing the given `elements` to the `file`. -pub fn write<'a>(file: &mut dyn std::io::Write, elements: &'a [TopLevel]) -> std::io::Result<()> { - for element in elements { - write!(file, "{}\n\n", &element)?; - } - Ok(()) -} diff --git a/ql/generator/src/ql_gen.rs b/ql/generator/src/ql_gen.rs deleted file mode 100644 index 007509e0074..00000000000 --- a/ql/generator/src/ql_gen.rs +++ /dev/null @@ -1,565 +0,0 @@ -use crate::ql; -use std::collections::BTreeSet; - -/// Creates the hard-coded `AstNode` class that acts as a supertype of all -/// classes we generate. -pub fn create_ast_node_class<'a>(ast_node: &'a str, node_info_table: &'a str) -> ql::Class<'a> { - // Default implementation of `toString` calls `this.getAPrimaryQlClass()` - let to_string = ql::Predicate { - qldoc: Some(String::from( - "Gets a string representation of this element.", - )), - name: "toString", - overridden: false, - is_final: false, - return_type: Some(ql::Type::String), - formal_parameters: vec![], - body: ql::Expression::Equals( - Box::new(ql::Expression::Var("result")), - Box::new(ql::Expression::Dot( - Box::new(ql::Expression::Var("this")), - "getAPrimaryQlClass", - vec![], - )), - ), - }; - let get_location = ql::Predicate { - name: "getLocation", - qldoc: Some(String::from("Gets the location of this element.")), - overridden: false, - is_final: true, - return_type: Some(ql::Type::Normal("L::Location")), - formal_parameters: vec![], - body: ql::Expression::Pred( - node_info_table, - vec![ - ql::Expression::Var("this"), - ql::Expression::Var("_"), // parent - ql::Expression::Var("_"), // parent index - ql::Expression::Var("result"), // location - ], - ), - }; - let get_a_field_or_child = create_none_predicate( - Some(String::from("Gets a field or child node of this node.")), - "getAFieldOrChild", - false, - Some(ql::Type::Normal("AstNode")), - ); - let get_parent = ql::Predicate { - qldoc: Some(String::from("Gets the parent of this element.")), - name: "getParent", - overridden: false, - is_final: true, - return_type: Some(ql::Type::Normal("AstNode")), - formal_parameters: vec![], - body: ql::Expression::Pred( - node_info_table, - vec![ - ql::Expression::Var("this"), - ql::Expression::Var("result"), - ql::Expression::Var("_"), // parent index - ql::Expression::Var("_"), // location - ], - ), - }; - let get_parent_index = ql::Predicate { - qldoc: Some(String::from( - "Gets the index of this node among the children of its parent.", - )), - name: "getParentIndex", - overridden: false, - is_final: true, - return_type: Some(ql::Type::Int), - formal_parameters: vec![], - body: ql::Expression::Pred( - node_info_table, - vec![ - ql::Expression::Var("this"), - ql::Expression::Var("_"), // parent - ql::Expression::Var("result"), // parent index - ql::Expression::Var("_"), // location - ], - ), - }; - let get_a_primary_ql_class = ql::Predicate { - qldoc: Some(String::from( - "Gets the name of the primary QL class for this element.", - )), - name: "getAPrimaryQlClass", - overridden: false, - is_final: false, - return_type: Some(ql::Type::String), - formal_parameters: vec![], - body: ql::Expression::Equals( - Box::new(ql::Expression::Var("result")), - Box::new(ql::Expression::String("???")), - ), - }; - let get_primary_ql_classes = ql::Predicate { - qldoc: Some( - "Gets a comma-separated list of the names of the primary CodeQL \ - classes to which this element belongs." - .to_owned(), - ), - name: "getPrimaryQlClasses", - overridden: false, - is_final: false, - return_type: Some(ql::Type::String), - formal_parameters: vec![], - body: ql::Expression::Equals( - Box::new(ql::Expression::Var("result")), - Box::new(ql::Expression::Aggregate { - name: "concat", - vars: vec![], - range: None, - expr: Box::new(ql::Expression::Dot( - Box::new(ql::Expression::Var("this")), - "getAPrimaryQlClass", - vec![], - )), - second_expr: Some(Box::new(ql::Expression::String(","))), - }), - ), - }; - ql::Class { - qldoc: Some(String::from("The base class for all AST nodes")), - name: "AstNode", - is_abstract: false, - supertypes: vec![ql::Type::At(ast_node)].into_iter().collect(), - characteristic_predicate: None, - predicates: vec![ - to_string, - get_location, - get_parent, - get_parent_index, - get_a_field_or_child, - get_a_primary_ql_class, - get_primary_ql_classes, - ], - } -} - -pub fn create_token_class<'a>(token_type: &'a str, tokeninfo: &'a str) -> ql::Class<'a> { - let tokeninfo_arity = 3; // id, kind, value - let get_value = ql::Predicate { - qldoc: Some(String::from("Gets the value of this token.")), - name: "getValue", - overridden: false, - is_final: true, - return_type: Some(ql::Type::String), - formal_parameters: vec![], - body: create_get_field_expr_for_column_storage("result", tokeninfo, 1, tokeninfo_arity), - }; - let to_string = ql::Predicate { - qldoc: Some(String::from( - "Gets a string representation of this element.", - )), - name: "toString", - overridden: true, - is_final: true, - return_type: Some(ql::Type::String), - formal_parameters: vec![], - body: ql::Expression::Equals( - Box::new(ql::Expression::Var("result")), - Box::new(ql::Expression::Dot( - Box::new(ql::Expression::Var("this")), - "getValue", - vec![], - )), - ), - }; - ql::Class { - qldoc: Some(String::from("A token.")), - name: "Token", - is_abstract: false, - supertypes: vec![ql::Type::At(token_type), ql::Type::Normal("AstNode")] - .into_iter() - .collect(), - characteristic_predicate: None, - predicates: vec![ - get_value, - to_string, - create_get_a_primary_ql_class("Token", false), - ], - } -} - -// Creates the `ReservedWord` class. -pub fn create_reserved_word_class(db_name: &str) -> ql::Class { - let class_name = "ReservedWord"; - let get_a_primary_ql_class = create_get_a_primary_ql_class(class_name, true); - ql::Class { - qldoc: Some(String::from("A reserved word.")), - name: class_name, - is_abstract: false, - supertypes: vec![ql::Type::At(db_name), ql::Type::Normal("Token")] - .into_iter() - .collect(), - characteristic_predicate: None, - predicates: vec![get_a_primary_ql_class], - } -} - -/// Creates a predicate whose body is `none()`. -fn create_none_predicate<'a>( - qldoc: Option<String>, - name: &'a str, - overridden: bool, - return_type: Option<ql::Type<'a>>, -) -> ql::Predicate<'a> { - ql::Predicate { - qldoc, - name, - overridden, - is_final: false, - return_type, - formal_parameters: Vec::new(), - body: ql::Expression::Pred("none", vec![]), - } -} - -/// Creates an overridden `getAPrimaryQlClass` predicate that returns the given -/// name. -fn create_get_a_primary_ql_class(class_name: &str, is_final: bool) -> ql::Predicate { - ql::Predicate { - qldoc: Some(String::from( - "Gets the name of the primary QL class for this element.", - )), - name: "getAPrimaryQlClass", - overridden: true, - is_final, - return_type: Some(ql::Type::String), - formal_parameters: vec![], - body: ql::Expression::Equals( - Box::new(ql::Expression::Var("result")), - Box::new(ql::Expression::String(class_name)), - ), - } -} - -/// Returns an expression to get a field that's defined as a column in the parent's table. -/// -/// # Arguments -/// -/// * `result_var_name` - the name of the variable to which the resulting value should be bound -/// * `table_name` - the name of parent's defining table -/// * `column_index` - the index in that table that defines the field -/// * `arity` - the total number of columns in the table -fn create_get_field_expr_for_column_storage<'a>( - result_var_name: &'a str, - table_name: &'a str, - column_index: usize, - arity: usize, -) -> ql::Expression<'a> { - let num_underscores_before = column_index; - let num_underscores_after = arity - 2 - num_underscores_before; - ql::Expression::Pred( - table_name, - [ - vec![ql::Expression::Var("this")], - vec![ql::Expression::Var("_"); num_underscores_before], - vec![ql::Expression::Var(result_var_name)], - vec![ql::Expression::Var("_"); num_underscores_after], - ] - .concat(), - ) -} - -/// Returns an expression to get the field with the given index from its -/// auxiliary table. The index name can be "_" so the expression will hold for -/// all indices. -fn create_get_field_expr_for_table_storage<'a>( - result_var_name: &'a str, - table_name: &'a str, - index_var_name: Option<&'a str>, -) -> ql::Expression<'a> { - ql::Expression::Pred( - table_name, - match index_var_name { - Some(index_var_name) => vec![ - ql::Expression::Var("this"), - ql::Expression::Var(index_var_name), - ql::Expression::Var(result_var_name), - ], - None => vec![ql::Expression::Var("this"), ql::Expression::Var("result")], - }, - ) -} - -/// Creates a pair consisting of a predicate to get the given field, and an -/// optional expression that will get the same field. When the field can occur -/// multiple times, the predicate will take an index argument, while the -/// expression will use the "don't care" expression to hold for all occurrences. -/// -/// # Arguments -/// -/// `main_table_name` - the name of the defining table for the parent node -/// `main_table_arity` - the number of columns in the main table -/// `main_table_column_index` - a mutable reference to a column index indicating -/// where the field is in the main table. If this is used (i.e. the field has -/// column storage), then the index is incremented. -/// `parent_name` - the name of the parent node -/// `field` - the field whose getters we are creating -/// `field_type` - the db name of the field's type (possibly being a union we created) -fn create_field_getters<'a>( - main_table_name: &'a str, - main_table_arity: usize, - main_table_column_index: &mut usize, - field: &'a node_types::Field, - nodes: &'a node_types::NodeTypeMap, -) -> (ql::Predicate<'a>, Option<ql::Expression<'a>>) { - let return_type = match &field.type_info { - node_types::FieldTypeInfo::Single(t) => { - Some(ql::Type::Normal(&nodes.get(t).unwrap().ql_class_name)) - } - node_types::FieldTypeInfo::Multiple { - types: _, - dbscheme_union: _, - ql_class, - } => Some(ql::Type::Normal(ql_class)), - node_types::FieldTypeInfo::ReservedWordInt(_) => Some(ql::Type::String), - }; - let formal_parameters = match &field.storage { - node_types::Storage::Column { .. } => vec![], - node_types::Storage::Table { has_index, .. } => { - if *has_index { - vec![ql::FormalParameter { - name: "i", - param_type: ql::Type::Int, - }] - } else { - vec![] - } - } - }; - - // For the expression to get a value, what variable name should the result - // be bound to? - let get_value_result_var_name = match &field.type_info { - node_types::FieldTypeInfo::ReservedWordInt(_) => "value", - node_types::FieldTypeInfo::Single(_) => "result", - node_types::FieldTypeInfo::Multiple { .. } => "result", - }; - - // Two expressions for getting the value. One that's suitable use in the - // getter predicate (where there may be a specific index), and another for - // use in `getAFieldOrChild` (where we use a "don't care" expression to - // match any index). - let (get_value, get_value_any_index) = match &field.storage { - node_types::Storage::Column { name: _ } => { - let column_index = *main_table_column_index; - *main_table_column_index += 1; - ( - create_get_field_expr_for_column_storage( - get_value_result_var_name, - main_table_name, - column_index, - main_table_arity, - ), - create_get_field_expr_for_column_storage( - get_value_result_var_name, - main_table_name, - column_index, - main_table_arity, - ), - ) - } - node_types::Storage::Table { - name: field_table_name, - has_index, - column_name: _, - } => ( - create_get_field_expr_for_table_storage( - get_value_result_var_name, - field_table_name, - if *has_index { Some("i") } else { None }, - ), - create_get_field_expr_for_table_storage( - get_value_result_var_name, - field_table_name, - if *has_index { Some("_") } else { None }, - ), - ), - }; - let (body, optional_expr) = match &field.type_info { - node_types::FieldTypeInfo::ReservedWordInt(int_mapping) => { - // Create an expression that binds the corresponding string to `result` for each `value`, e.g.: - // result = "foo" and value = 0 or - // result = "bar" and value = 1 or - // result = "baz" and value = 2 - let disjuncts = int_mapping - .iter() - .map(|(token_str, (value, _))| { - ql::Expression::And(vec![ - ql::Expression::Equals( - Box::new(ql::Expression::Var("result")), - Box::new(ql::Expression::String(token_str)), - ), - ql::Expression::Equals( - Box::new(ql::Expression::Var("value")), - Box::new(ql::Expression::Integer(*value)), - ), - ]) - }) - .collect(); - ( - ql::Expression::Aggregate { - name: "exists", - vars: vec![ql::FormalParameter { - name: "value", - param_type: ql::Type::Int, - }], - range: Some(Box::new(get_value)), - expr: Box::new(ql::Expression::Or(disjuncts)), - second_expr: None, - }, - // Since the getter returns a string and not an AstNode, it won't be part of getAFieldOrChild: - None, - ) - } - node_types::FieldTypeInfo::Single(_) | node_types::FieldTypeInfo::Multiple { .. } => { - (get_value, Some(get_value_any_index)) - } - }; - let qldoc = match &field.name { - Some(name) => format!("Gets the node corresponding to the field `{}`.", name), - None => { - if formal_parameters.is_empty() { - "Gets the child of this node.".to_owned() - } else { - "Gets the `i`th child of this node.".to_owned() - } - } - }; - ( - ql::Predicate { - qldoc: Some(qldoc), - name: &field.getter_name, - overridden: false, - is_final: true, - return_type, - formal_parameters, - body, - }, - optional_expr, - ) -} - -/// Converts the given node types into CodeQL classes wrapping the dbscheme. -pub fn convert_nodes(nodes: &node_types::NodeTypeMap) -> Vec<ql::TopLevel> { - let mut classes: Vec<ql::TopLevel> = Vec::new(); - let mut token_kinds = BTreeSet::new(); - for (type_name, node) in nodes { - if let node_types::EntryKind::Token { .. } = &node.kind { - if type_name.named { - token_kinds.insert(&type_name.kind); - } - } - } - - for (type_name, node) in nodes { - match &node.kind { - node_types::EntryKind::Token { kind_id: _ } => { - if type_name.named { - let get_a_primary_ql_class = - create_get_a_primary_ql_class(&node.ql_class_name, true); - let mut supertypes: BTreeSet<ql::Type> = BTreeSet::new(); - supertypes.insert(ql::Type::At(&node.dbscheme_name)); - supertypes.insert(ql::Type::Normal("Token")); - classes.push(ql::TopLevel::Class(ql::Class { - qldoc: Some(format!("A class representing `{}` tokens.", type_name.kind)), - name: &node.ql_class_name, - is_abstract: false, - supertypes, - characteristic_predicate: None, - predicates: vec![get_a_primary_ql_class], - })); - } - } - node_types::EntryKind::Union { members: _ } => { - // It's a tree-sitter supertype node, so we're wrapping a dbscheme - // union type. - classes.push(ql::TopLevel::Class(ql::Class { - qldoc: None, - name: &node.ql_class_name, - is_abstract: false, - supertypes: vec![ - ql::Type::At(&node.dbscheme_name), - ql::Type::Normal("AstNode"), - ] - .into_iter() - .collect(), - characteristic_predicate: None, - predicates: vec![], - })); - } - node_types::EntryKind::Table { - name: main_table_name, - fields, - } => { - if fields.is_empty() { - panic!("Encountered node '{}' with no fields", type_name.kind); - } - - // Count how many columns there will be in the main table. There - // will be one for the id, plus one for each field that's stored - // as a column. - let main_table_arity = 1 + fields - .iter() - .filter(|&f| matches!(f.storage, node_types::Storage::Column { .. })) - .count(); - - let main_class_name = &node.ql_class_name; - let mut main_class = ql::Class { - qldoc: Some(format!("A class representing `{}` nodes.", type_name.kind)), - name: main_class_name, - is_abstract: false, - supertypes: vec![ - ql::Type::At(&node.dbscheme_name), - ql::Type::Normal("AstNode"), - ] - .into_iter() - .collect(), - characteristic_predicate: None, - predicates: vec![create_get_a_primary_ql_class(main_class_name, true)], - }; - - let mut main_table_column_index: usize = 0; - let mut get_child_exprs: Vec<ql::Expression> = Vec::new(); - - // Iterate through the fields, creating: - // - classes to wrap union types if fields need them, - // - predicates to access the fields, - // - the QL expressions to access the fields that will be part of getAFieldOrChild. - for field in fields { - let (get_pred, get_child_expr) = create_field_getters( - main_table_name, - main_table_arity, - &mut main_table_column_index, - field, - nodes, - ); - main_class.predicates.push(get_pred); - if let Some(get_child_expr) = get_child_expr { - get_child_exprs.push(get_child_expr) - } - } - - main_class.predicates.push(ql::Predicate { - qldoc: Some(String::from("Gets a field or child node of this node.")), - name: "getAFieldOrChild", - overridden: true, - is_final: true, - return_type: Some(ql::Type::Normal("AstNode")), - formal_parameters: vec![], - body: ql::Expression::Or(get_child_exprs), - }); - - classes.push(ql::TopLevel::Class(main_class)); - } - } - } - - classes -} diff --git a/ql/node-types/Cargo.toml b/ql/node-types/Cargo.toml deleted file mode 100644 index 181bd6481e9..00000000000 --- a/ql/node-types/Cargo.toml +++ /dev/null @@ -1,11 +0,0 @@ -[package] -name = "node-types" -version = "0.1.0" -authors = ["GitHub"] -edition = "2018" - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[dependencies] -serde = { version = "1.0", features = ["derive"] } -serde_json = "1.0" diff --git a/ql/node-types/src/lib.rs b/ql/node-types/src/lib.rs deleted file mode 100644 index 9467e23fd62..00000000000 --- a/ql/node-types/src/lib.rs +++ /dev/null @@ -1,449 +0,0 @@ -use serde::Deserialize; -use std::collections::BTreeMap; -use std::path::Path; - -use std::collections::BTreeSet as Set; -use std::fs; - -/// A lookup table from TypeName to Entry. -pub type NodeTypeMap = BTreeMap<TypeName, Entry>; - -#[derive(Debug)] -pub struct Entry { - pub dbscheme_name: String, - pub ql_class_name: String, - pub kind: EntryKind, -} - -#[derive(Debug)] -pub enum EntryKind { - Union { members: Set<TypeName> }, - Table { name: String, fields: Vec<Field> }, - Token { kind_id: usize }, -} - -#[derive(Debug, Ord, PartialOrd, Eq, PartialEq)] -pub struct TypeName { - pub kind: String, - pub named: bool, -} - -#[derive(Debug)] -pub enum FieldTypeInfo { - /// The field has a single type. - Single(TypeName), - - /// The field can take one of several types, so we also provide the name of - /// the database union type that wraps them, and the corresponding QL class - /// name. - Multiple { - types: Set<TypeName>, - dbscheme_union: String, - ql_class: String, - }, - - /// The field can be one of several tokens, so the db type will be an `int` - /// with a `case @foo.kind` for each possibility. - ReservedWordInt(BTreeMap<String, (usize, String)>), -} - -#[derive(Debug)] -pub struct Field { - pub parent: TypeName, - pub type_info: FieldTypeInfo, - /// The name of the field or None for the anonymous 'children' - /// entry from node_types.json - pub name: Option<String>, - /// The name of the predicate to get this field. - pub getter_name: String, - pub storage: Storage, -} - -fn name_for_field_or_child(name: &Option<String>) -> String { - match name { - Some(name) => name.clone(), - None => "child".to_owned(), - } -} - -#[derive(Debug)] -pub enum Storage { - /// the field is stored as a column in the parent table - Column { name: String }, - /// the field is stored in a link table - Table { - /// the name of the table - name: String, - /// the name of the column for the field in the dbscheme - column_name: String, - /// does it have an associated index column? - has_index: bool, - }, -} - -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<NodeTypeMap> { - let file = fs::File::open(node_types_path)?; - let node_types: Vec<NodeInfo> = serde_json::from_reader(file)?; - Ok(convert_nodes(prefix, &node_types)) -} - -pub fn read_node_types_str(prefix: &str, node_types_json: &str) -> std::io::Result<NodeTypeMap> { - let node_types: Vec<NodeInfo> = serde_json::from_str(node_types_json)?; - Ok(convert_nodes(prefix, &node_types)) -} - -fn convert_type(node_type: &NodeType) -> TypeName { - TypeName { - kind: node_type.kind.to_string(), - named: node_type.named, - } -} - -fn convert_types(node_types: &[NodeType]) -> Set<TypeName> { - node_types.iter().map(convert_type).collect() -} - -pub fn convert_nodes(prefix: &str, nodes: &[NodeInfo]) -> NodeTypeMap { - let mut entries = NodeTypeMap::new(); - let mut token_kinds = Set::new(); - - // First, find all the token kinds - for node in nodes { - if node.subtypes.is_none() - && node.fields.as_ref().map_or(0, |x| x.len()) == 0 - && node.children.is_none() - { - let type_name = TypeName { - kind: node.kind.clone(), - named: node.named, - }; - token_kinds.insert(type_name); - } - } - - for node in nodes { - let flattened_name = &node_type_name(&node.kind, node.named); - let dbscheme_name = escape_name(flattened_name); - let ql_class_name = dbscheme_name_to_class_name(&dbscheme_name); - let dbscheme_name = format!("{}_{}", prefix, &dbscheme_name); - if let Some(subtypes) = &node.subtypes { - // It's a tree-sitter supertype node, for which we create a union - // type. - entries.insert( - TypeName { - kind: node.kind.clone(), - named: node.named, - }, - Entry { - dbscheme_name, - ql_class_name, - kind: EntryKind::Union { - members: convert_types(subtypes), - }, - }, - ); - } else if node.fields.as_ref().map_or(0, |x| x.len()) == 0 && node.children.is_none() { - // Token kind, handled above. - } else { - // It's a product type, defined by a table. - let type_name = TypeName { - kind: node.kind.clone(), - named: node.named, - }; - let table_name = escape_name(&(format!("{}_def", &flattened_name))); - let table_name = format!("{}_{}", prefix, &table_name); - - let mut fields = Vec::new(); - - // If the type also has fields or children, then we create either - // auxiliary tables or columns in the defining table for them. - if let Some(node_fields) = &node.fields { - for (field_name, field_info) in node_fields { - add_field( - prefix, - &type_name, - Some(field_name.to_string()), - field_info, - &mut fields, - &token_kinds, - ); - } - } - if let Some(children) = &node.children { - // Treat children as if they were a field called 'child'. - add_field( - prefix, - &type_name, - None, - children, - &mut fields, - &token_kinds, - ); - } - entries.insert( - type_name, - Entry { - dbscheme_name, - ql_class_name, - kind: EntryKind::Table { - name: table_name, - fields, - }, - }, - ); - } - } - let mut counter = 0; - for type_name in token_kinds { - let entry = if type_name.named { - counter += 1; - let unprefixed_name = node_type_name(&type_name.kind, true); - Entry { - dbscheme_name: escape_name(&format!("{}_token_{}", &prefix, &unprefixed_name)), - ql_class_name: dbscheme_name_to_class_name(&escape_name(&unprefixed_name)), - kind: EntryKind::Token { kind_id: counter }, - } - } else { - Entry { - dbscheme_name: format!("{}_reserved_word", &prefix), - ql_class_name: "ReservedWord".to_owned(), - kind: EntryKind::Token { kind_id: 0 }, - } - }; - entries.insert(type_name, entry); - } - entries -} - -fn add_field( - prefix: &str, - parent_type_name: &TypeName, - field_name: Option<String>, - field_info: &FieldInfo, - fields: &mut Vec<Field>, - token_kinds: &Set<TypeName>, -) { - let parent_flattened_name = node_type_name(&parent_type_name.kind, parent_type_name.named); - let column_name = escape_name(&name_for_field_or_child(&field_name)); - let storage = if !field_info.multiple && field_info.required { - // This field must appear exactly once, so we add it as - // a column to the main table for the node type. - Storage::Column { name: column_name } - } else { - // Put the field in an auxiliary table. - let has_index = field_info.multiple; - let field_table_name = escape_name(&format!( - "{}_{}_{}", - &prefix, - parent_flattened_name, - &name_for_field_or_child(&field_name) - )); - Storage::Table { - has_index, - name: field_table_name, - column_name, - } - }; - let converted_types = convert_types(&field_info.types); - 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 - // enumerate the possible values. - let mut field_token_ints: BTreeMap<String, (usize, String)> = BTreeMap::new(); - for (counter, t) in converted_types.into_iter().enumerate() { - let dbscheme_variant_name = - escape_name(&format!("{}_{}_{}", &prefix, parent_flattened_name, t.kind)); - field_token_ints.insert(t.kind.to_owned(), (counter, dbscheme_variant_name)); - } - FieldTypeInfo::ReservedWordInt(field_token_ints) - } else if field_info.types.len() == 1 { - FieldTypeInfo::Single(converted_types.into_iter().next().unwrap()) - } else { - // The dbscheme type for this field will be a union. In QL, it'll just be AstNode. - FieldTypeInfo::Multiple { - types: converted_types, - dbscheme_union: format!( - "{}_{}_{}_type", - &prefix, - &parent_flattened_name, - &name_for_field_or_child(&field_name) - ), - ql_class: "AstNode".to_owned(), - } - }; - let getter_name = format!( - "get{}", - dbscheme_name_to_class_name(&escape_name(&name_for_field_or_child(&field_name))) - ); - fields.push(Field { - parent: TypeName { - kind: parent_type_name.kind.to_string(), - named: parent_type_name.named, - }, - type_info, - name: field_name, - getter_name, - storage, - }); -} -#[derive(Deserialize)] -pub struct NodeInfo { - #[serde(rename = "type")] - pub kind: String, - pub named: bool, - #[serde(skip_serializing_if = "Option::is_none")] - pub fields: Option<BTreeMap<String, FieldInfo>>, - #[serde(skip_serializing_if = "Option::is_none")] - pub children: Option<FieldInfo>, - #[serde(skip_serializing_if = "Option::is_none")] - pub subtypes: Option<Vec<NodeType>>, -} - -#[derive(Deserialize)] -pub struct NodeType { - #[serde(rename = "type")] - pub kind: String, - pub named: bool, -} - -#[derive(Deserialize)] -pub struct FieldInfo { - pub multiple: bool, - pub required: bool, - pub types: Vec<NodeType>, -} - -/// Given a tree-sitter node type's (kind, named) pair, returns a single string -/// representing the (unescaped) name we'll use to refer to corresponding QL -/// type. -fn node_type_name(kind: &str, named: bool) -> String { - if named { - kind.to_string() - } else { - format!("{}_unnamed", kind) - } -} - -const RESERVED_KEYWORDS: [&str; 14] = [ - "boolean", "case", "date", "float", "int", "key", "of", "order", "ref", "string", "subtype", - "type", "unique", "varchar", -]; - -/// Returns a string that's a copy of `name` but suitably escaped to be a valid -/// QL identifier. -fn escape_name(name: &str) -> String { - let mut result = String::new(); - - // If there's a leading underscore, replace it with 'underscore_'. - if let Some(c) = name.chars().next() { - if c == '_' { - result.push_str("underscore"); - } - } - for c in name.chars() { - match c { - '{' => result.push_str("lbrace"), - '}' => result.push_str("rbrace"), - '<' => result.push_str("langle"), - '>' => result.push_str("rangle"), - '[' => result.push_str("lbracket"), - ']' => result.push_str("rbracket"), - '(' => result.push_str("lparen"), - ')' => result.push_str("rparen"), - '|' => result.push_str("pipe"), - '=' => result.push_str("equal"), - '~' => result.push_str("tilde"), - '?' => result.push_str("question"), - '`' => result.push_str("backtick"), - '^' => result.push_str("caret"), - '!' => result.push_str("bang"), - '#' => result.push_str("hash"), - '%' => result.push_str("percent"), - '&' => result.push_str("ampersand"), - '.' => result.push_str("dot"), - ',' => result.push_str("comma"), - '/' => result.push_str("slash"), - ':' => result.push_str("colon"), - ';' => result.push_str("semicolon"), - '"' => result.push_str("dquote"), - '*' => result.push_str("star"), - '+' => result.push_str("plus"), - '-' => result.push_str("minus"), - '@' => result.push_str("at"), - _ if c.is_uppercase() => { - result.push('_'); - result.push_str(&c.to_lowercase().to_string()) - } - _ => result.push(c), - } - } - - for &keyword in &RESERVED_KEYWORDS { - if result == keyword { - result.push_str("__"); - break; - } - } - - result -} - -pub fn to_snake_case(word: &str) -> String { - let mut prev_upper = true; - let mut result = String::new(); - for c in word.chars() { - if c.is_uppercase() { - if !prev_upper { - result.push('_') - } - prev_upper = true; - result.push(c.to_ascii_lowercase()); - } else { - prev_upper = false; - result.push(c); - } - } - result -} -/// Given a valid dbscheme name (i.e. in snake case), produces the equivalent QL -/// name (i.e. in CamelCase). For example, "foo_bar_baz" becomes "FooBarBaz". -fn dbscheme_name_to_class_name(dbscheme_name: &str) -> String { - fn to_title_case(word: &str) -> String { - let mut first = true; - let mut result = String::new(); - for c in word.chars() { - if first { - first = false; - result.push(c.to_ascii_uppercase()); - } else { - result.push(c); - } - } - result - } - dbscheme_name - .split('_') - .map(to_title_case) - .collect::<Vec<String>>() - .join("") -} - -#[test] -fn to_snake_case_test() { - assert_eq!("python", to_snake_case("Python")); - assert_eq!("yaml", to_snake_case("YAML")); - assert_eq!("set_literal", to_snake_case("SetLiteral")); -} From 8c60b6e65794d60c11ae0f43049b1ddfc90fc538 Mon Sep 17 00:00:00 2001 From: Harry Maclean <hmac@github.com> Date: Thu, 16 Mar 2023 15:35:00 +1300 Subject: [PATCH 318/631] QL: Merge extractor crates into one This mirrors the structure we have in the Ruby extractor, and will allow us to share more code. --- ql/Cargo.lock | Bin 24490 -> 24184 bytes ql/Cargo.toml | 2 -- ql/autobuilder/Cargo.toml | 9 --------- .../src/bin/autobuilder.rs} | 0 .../src/{main.rs => bin/extractor.rs} | 0 .../src/bin/generator.rs} | 0 ql/generator/Cargo.toml | 18 ------------------ ql/scripts/create-extractor-pack.ps1 | 6 +++--- ql/scripts/create-extractor-pack.sh | 7 +++---- 9 files changed, 6 insertions(+), 36 deletions(-) delete mode 100644 ql/autobuilder/Cargo.toml rename ql/{autobuilder/src/main.rs => extractor/src/bin/autobuilder.rs} (100%) rename ql/extractor/src/{main.rs => bin/extractor.rs} (100%) rename ql/{generator/src/main.rs => extractor/src/bin/generator.rs} (100%) delete mode 100644 ql/generator/Cargo.toml diff --git a/ql/Cargo.lock b/ql/Cargo.lock index 8d355f264b1d2baa67fd0b099873a80ce1222c5f..ac27495128e0b35c5f94436e0b6c45df7aa31a04 100644 GIT binary patch delta 19 bcmZ3rpYg{Y#tp{Co3o5%88<hXYG?rfRtN`R delta 74 zcmV-Q0JZ=4yaB4e0kAVO9bt8JZ(?<6Y-D9}A_{h8a&u{KZXi7%A}}s7E-;hPITy1q gGavy7Y%OPHZe?;|lYt8>lVmd;la(_rv(q!BD)kH+Q2+n{ diff --git a/ql/Cargo.toml b/ql/Cargo.toml index bb052f81d32..5e42fc8d5e5 100644 --- a/ql/Cargo.toml +++ b/ql/Cargo.toml @@ -1,7 +1,5 @@ [workspace] members = [ - "autobuilder", "extractor", - "generator", "buramu", ] diff --git a/ql/autobuilder/Cargo.toml b/ql/autobuilder/Cargo.toml deleted file mode 100644 index ac39f025ade..00000000000 --- a/ql/autobuilder/Cargo.toml +++ /dev/null @@ -1,9 +0,0 @@ -[package] -name = "ql-autobuilder" -version = "0.1.0" -authors = ["GitHub"] -edition = "2018" - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[dependencies] diff --git a/ql/autobuilder/src/main.rs b/ql/extractor/src/bin/autobuilder.rs similarity index 100% rename from ql/autobuilder/src/main.rs rename to ql/extractor/src/bin/autobuilder.rs diff --git a/ql/extractor/src/main.rs b/ql/extractor/src/bin/extractor.rs similarity index 100% rename from ql/extractor/src/main.rs rename to ql/extractor/src/bin/extractor.rs diff --git a/ql/generator/src/main.rs b/ql/extractor/src/bin/generator.rs similarity index 100% rename from ql/generator/src/main.rs rename to ql/extractor/src/bin/generator.rs diff --git a/ql/generator/Cargo.toml b/ql/generator/Cargo.toml deleted file mode 100644 index 3a5665f33ae..00000000000 --- a/ql/generator/Cargo.toml +++ /dev/null @@ -1,18 +0,0 @@ -[package] -name = "ql-generator" -version = "0.1.0" -authors = ["GitHub"] -edition = "2018" - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[dependencies] -clap = "2.33" -tracing = "0.1" -tracing-subscriber = { version = "0.3.16", features = ["env-filter"] } -tree-sitter-ql = { git = "https://github.com/tree-sitter/tree-sitter-ql.git", rev = "d08db734f8dc52f6bc04db53a966603122bc6985"} -tree-sitter-ql-dbscheme = { git = "https://github.com/erik-krogh/tree-sitter-ql-dbscheme.git", rev = "63e1344353f63931e88bfbc2faa2e78e1421b213"} -tree-sitter-ql-yaml = {git = "https://github.com/erik-krogh/tree-sitter-ql.git", rev = "cf704bf3671e1ae148e173464fb65a4d2bbf5f99"} -tree-sitter-blame = {path = "../buramu/tree-sitter-blame"} -tree-sitter-json = { git = "https://github.com/tausbn/tree-sitter-json.git", rev = "745663ee997f1576fe1e7187e6347e0db36ec7a9"} -codeql-extractor = { path = "../../shared/extractor" } diff --git a/ql/scripts/create-extractor-pack.ps1 b/ql/scripts/create-extractor-pack.ps1 index 65b4dfc348a..1229621c2c1 100644 --- a/ql/scripts/create-extractor-pack.ps1 +++ b/ql/scripts/create-extractor-pack.ps1 @@ -1,6 +1,6 @@ cargo build --release -cargo run --release -p ql-generator -- --dbscheme ql/src/ql.dbscheme --library ql/src/codeql_ql/ast/internal/TreeSitter.qll +cargo run --release --bin generator -- --dbscheme ql/src/ql.dbscheme --library ql/src/codeql_ql/ast/internal/TreeSitter.qll codeql query format -i ql\src\codeql_ql\ast\internal\TreeSitter.qll if (Test-Path -Path extractor-pack) { @@ -10,5 +10,5 @@ mkdir extractor-pack | Out-Null cp codeql-extractor.yml, ql\src\ql.dbscheme, ql\src\ql.dbscheme.stats extractor-pack cp -Recurse tools extractor-pack mkdir extractor-pack\tools\win64 | Out-Null -cp target\release\ql-extractor.exe extractor-pack\tools\win64\extractor.exe -cp target\release\ql-autobuilder.exe extractor-pack\tools\win64\autobuilder.exe +cp target\release\extractor.exe extractor-pack\tools\win64\extractor.exe +cp target\release\autobuilder.exe extractor-pack\tools\win64\autobuilder.exe diff --git a/ql/scripts/create-extractor-pack.sh b/ql/scripts/create-extractor-pack.sh index d1b3c6312d9..01fbc2ad5a7 100755 --- a/ql/scripts/create-extractor-pack.sh +++ b/ql/scripts/create-extractor-pack.sh @@ -20,13 +20,12 @@ else fi cargo build --release - -cargo run --release -p ql-generator -- --dbscheme ql/src/ql.dbscheme --library ql/src/codeql_ql/ast/internal/TreeSitter.qll +cargo run --release --bin generator -- --dbscheme ql/src/ql.dbscheme --library ql/src/codeql_ql/ast/internal/TreeSitter.qll $CODEQL_BINARY query format -i ql/src/codeql_ql/ast/internal/TreeSitter.qll rm -rf extractor-pack mkdir -p extractor-pack cp -r codeql-extractor.yml tools ql/src/ql.dbscheme ql/src/ql.dbscheme.stats extractor-pack/ mkdir -p extractor-pack/tools/${platform} -cp target/release/ql-extractor extractor-pack/tools/${platform}/extractor -cp target/release/ql-autobuilder extractor-pack/tools/${platform}/autobuilder +cp target/release/extractor extractor-pack/tools/${platform}/extractor +cp target/release/autobuilder extractor-pack/tools/${platform}/autobuilder From f2fc80b3c1416ef001dec2e0c4e5f39a282ff45d Mon Sep 17 00:00:00 2001 From: Harry Maclean <hmac@github.com> Date: Thu, 16 Mar 2023 15:37:25 +1300 Subject: [PATCH 319/631] QL: Bump rust to 1.68 --- ql/rust-toolchain.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ql/rust-toolchain.toml b/ql/rust-toolchain.toml index 38ca5da4f14..04b7b3d5fd6 100644 --- a/ql/rust-toolchain.toml +++ b/ql/rust-toolchain.toml @@ -2,6 +2,6 @@ # extractor. It is set to the lowest version of Rust we want to support. [toolchain] -channel = "1.59" +channel = "1.68" profile = "minimal" components = [ "rustfmt" ] From 856132bc2f70626221376b4f33031d3843990342 Mon Sep 17 00:00:00 2001 From: Harry Maclean <hmac@github.com> Date: Fri, 17 Mar 2023 13:16:36 +1300 Subject: [PATCH 320/631] Ruby: Fix cross-compilation Ensure that builds via cargo-cross, which are executed in a docker container, can see the shared library. --- ruby/actions/create-extractor-pack/action.yml | 2 +- ruby/extractor/Cross.toml | 6 ++++++ ruby/scripts/create-extractor-pack.sh | 14 +++++++++++--- 3 files changed, 18 insertions(+), 4 deletions(-) diff --git a/ruby/actions/create-extractor-pack/action.yml b/ruby/actions/create-extractor-pack/action.yml index 4396b7f79cc..7f18dea5902 100644 --- a/ruby/actions/create-extractor-pack/action.yml +++ b/ruby/actions/create-extractor-pack/action.yml @@ -24,6 +24,6 @@ runs: if: steps.cache-extractor.outputs.cache-hit != 'true' shell: bash run: | - cargo install cross --version 0.2.1 + cargo install cross --version 0.2.5 scripts/create-extractor-pack.sh working-directory: ruby diff --git a/ruby/extractor/Cross.toml b/ruby/extractor/Cross.toml index 17726bd5e82..043f2826a7a 100644 --- a/ruby/extractor/Cross.toml +++ b/ruby/extractor/Cross.toml @@ -1,2 +1,8 @@ [target.x86_64-unknown-linux-gnu] image = "centos/devtoolset-7-toolchain-centos7" + +[build.env] +# Provide the path to the shared extractor +# Cross mounts this directory as a volume, so builds inside the docker container +# can see it. +volumes = ["__CODEQL-EXTRACTOR=../../shared/extractor"] diff --git a/ruby/scripts/create-extractor-pack.sh b/ruby/scripts/create-extractor-pack.sh index 37ed267b856..c014ed52016 100755 --- a/ruby/scripts/create-extractor-pack.sh +++ b/ruby/scripts/create-extractor-pack.sh @@ -14,7 +14,15 @@ else fi (cd extractor && "$CARGO" build --release) -extractor/target/release/generator --dbscheme ql/lib/ruby.dbscheme --library ql/lib/codeql/ruby/ast/internal/TreeSitter.qll + +# If building via cross, the binaries will be in extractor/target/<triple>/release +# If building via cargo, the binaries will be in extractor/target/release +BIN_DIR=extractor/target/release +if [[ "$CARGO" == "cross" ]]; then + BIN_DIR=extractor/target/x86_64-unknown-linux-gnu/release +fi + +"$BIN_DIR/generator" --dbscheme ql/lib/ruby.dbscheme --library ql/lib/codeql/ruby/ast/internal/TreeSitter.qll codeql query format -i ql/lib/codeql/ruby/ast/internal/TreeSitter.qll @@ -22,5 +30,5 @@ rm -rf extractor-pack mkdir -p extractor-pack cp -r codeql-extractor.yml downgrades tools ql/lib/ruby.dbscheme ql/lib/ruby.dbscheme.stats extractor-pack/ mkdir -p extractor-pack/tools/${platform} -cp extractor/target/release/extractor extractor-pack/tools/${platform}/extractor -cp extractor/target/release/autobuilder extractor-pack/tools/${platform}/autobuilder +cp "$BIN_DIR/extractor" extractor-pack/tools/${platform}/extractor +cp "$BIN_DIR/autobuilder" extractor-pack/tools/${platform}/autobuilder From 45797b3de5fa5bf5d9bd77abab2bc72ed4293423 Mon Sep 17 00:00:00 2001 From: Harry Maclean <hmac@github.com> Date: Thu, 23 Mar 2023 12:20:12 +1300 Subject: [PATCH 321/631] Ruby: bump cross to 0.2.5 This include support for mounting external path dependencies as volumes. --- .github/workflows/ruby-build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ruby-build.yml b/.github/workflows/ruby-build.yml index da064fce148..3c9ee5bcf92 100644 --- a/.github/workflows/ruby-build.yml +++ b/.github/workflows/ruby-build.yml @@ -50,7 +50,7 @@ jobs: echo "/usr/local/opt/gnu-tar/libexec/gnubin" >> $GITHUB_PATH - name: Install cargo-cross if: runner.os == 'Linux' - run: cargo install cross --version 0.2.1 + run: cargo install cross --version 0.2.5 - uses: ./.github/actions/os-version id: os_version - name: Cache entire extractor From 271e41c6ddea204886775a142116af0f624af017 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 23 Mar 2023 00:16:48 +0000 Subject: [PATCH 322/631] Add changed framework coverage reports --- java/documentation/library-coverage/coverage.csv | 2 +- java/documentation/library-coverage/coverage.rst | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/java/documentation/library-coverage/coverage.csv b/java/documentation/library-coverage/coverage.csv index c0dcc806c02..680b2440aab 100644 --- a/java/documentation/library-coverage/coverage.csv +++ b/java/documentation/library-coverage/coverage.csv @@ -54,7 +54,7 @@ java.io,42,,40,,17,,,,,,,,,,,,,,,3,,,,,,,,,,,,,22,,,,,,,,39,1 java.lang,16,,76,,,,,,,,,,,,8,,,,,3,,4,,,1,,,,,,,,,,,,,,,,53,23 java.net,12,3,17,,,,,,,,,,,,,,,12,,,,,,,,,,,,,,,,,,,,,,3,17, java.nio,25,,29,,19,,,,,,,,,,,,,,,4,,,,,,,,,,,,,2,,,,,,,,29, -java.sql,13,,2,,,,,,,,4,,,,,,,,,,,,,,,,,,9,,,,,,,,,,,,1,1 +java.sql,13,,3,,,,,,,,4,,,,,,,,,,,,,,,,,,9,,,,,,,,,,,,2,1 java.util,44,,465,,,,,,,,,,,,34,,,,,,,,5,2,,1,2,,,,,,,,,,,,,,38,427 javafx.scene.web,1,,,,,,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,,,,, javax.faces.context,2,7,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,2,,,,7,, diff --git a/java/documentation/library-coverage/coverage.rst b/java/documentation/library-coverage/coverage.rst index 01b16e25a87..e2a186f1967 100644 --- a/java/documentation/library-coverage/coverage.rst +++ b/java/documentation/library-coverage/coverage.rst @@ -18,10 +18,10 @@ Java framework & library support `Google Guava <https://guava.dev/>`_,``com.google.common.*``,,730,39,,6,,,,, JBoss Logging,``org.jboss.logging``,,,324,,,,,,, `JSON-java <https://github.com/stleary/JSON-java>`_,``org.json``,,236,,,,,,,, - Java Standard Library,``java.*``,3,630,152,36,,,9,,,12 + Java Standard Library,``java.*``,3,631,152,36,,,9,,,12 Java extensions,"``javax.*``, ``jakarta.*``",63,611,34,1,,4,,1,1,2 Kotlin Standard Library,``kotlin*``,,1835,12,10,,,,,,2 `Spring <https://spring.io/>`_,``org.springframework.*``,29,480,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.thoughtworks.xstream``, ``com.unboundid.ldap.sdk``, ``com.zaxxer.hikari``, ``flexjson``, ``freemarker.cache``, ``freemarker.template``, ``groovy.lang``, ``groovy.util``, ``hudson.model``, ``hudson.os``, ``hudson.remoting``, ``hudson.util``, ``io.netty.bootstrap``, ``io.netty.channel``, ``io.netty.handler.codec.http``, ``io.netty.handler.ssl``, ``io.netty.handler.stream``, ``io.netty.resolver``, ``io.netty.util.internal``, ``javafx.scene.web``, ``jodd.json``, ``net.sf.saxon.s9api``, ``ognl``, ``okhttp3``, ``org.apache.commons.codec``, ``org.apache.commons.compress.archivers.tar``, ``org.apache.commons.jelly``, ``org.apache.commons.jexl2``, ``org.apache.commons.jexl3``, ``org.apache.commons.logging``, ``org.apache.commons.ognl``, ``org.apache.directory.ldap.client.api``, ``org.apache.hadoop.hive.metastore``, ``org.apache.hive.hcatalog.templeton``, ``org.apache.ibatis.jdbc``, ``org.apache.log4j``, ``org.apache.shiro.codec``, ``org.apache.shiro.jndi``, ``org.apache.tools.ant``, ``org.apache.tools.zip``, ``org.apache.velocity.app``, ``org.apache.velocity.runtime``, ``org.codehaus.cargo.container.installer``, ``org.codehaus.groovy.control``, ``org.dom4j``, ``org.geogebra.web.full.main``, ``org.hibernate``, ``org.jdbi.v3.core``, ``org.jooq``, ``org.kohsuke.stapler``, ``org.mvel2``, ``org.openjdk.jmh.runner.options``, ``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,314,328,12,,,18,18,,28 - Totals,,217,8507,1647,150,6,10,113,33,1,113 + Totals,,217,8508,1647,150,6,10,113,33,1,113 From ce6be1f6365cbd9aed71ebbb3fae37d4cfc0dab1 Mon Sep 17 00:00:00 2001 From: Kasper Svendsen <kaspersv@github.com> Date: Thu, 23 Mar 2023 08:32:16 +0100 Subject: [PATCH 323/631] Dataflow: Instantiate stage 1 access paths with proper unit type --- .../lib/semmle/code/cpp/dataflow/internal/DataFlowImpl.qll | 6 +----- .../semmle/code/cpp/ir/dataflow/internal/DataFlowImpl.qll | 6 +----- .../semmle/code/csharp/dataflow/internal/DataFlowImpl.qll | 6 +----- go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl.qll | 6 +----- .../lib/semmle/code/java/dataflow/internal/DataFlowImpl.qll | 6 +----- .../semmle/python/dataflow/new/internal/DataFlowImpl.qll | 6 +----- ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl.qll | 6 +----- .../ql/lib/codeql/swift/dataflow/internal/DataFlowImpl.qll | 6 +----- 8 files changed, 8 insertions(+), 40 deletions(-) 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 c47b0308855..9fee0c11fff 100644 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl.qll +++ b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl.qll @@ -445,11 +445,7 @@ module Impl<FullStateConfigSig Config> { } private module Stage1 implements StageSig { - class Ap extends int { - // workaround for bad functionality-induced joins (happens when using `Unit`) - pragma[nomagic] - Ap() { this in [0 .. 1] and this < 1 } - } + class Ap = Unit; private class Cc = boolean; 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 c47b0308855..9fee0c11fff 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 @@ -445,11 +445,7 @@ module Impl<FullStateConfigSig Config> { } private module Stage1 implements StageSig { - class Ap extends int { - // workaround for bad functionality-induced joins (happens when using `Unit`) - pragma[nomagic] - Ap() { this in [0 .. 1] and this < 1 } - } + class Ap = Unit; private class Cc = boolean; 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 c47b0308855..9fee0c11fff 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl.qll @@ -445,11 +445,7 @@ module Impl<FullStateConfigSig Config> { } private module Stage1 implements StageSig { - class Ap extends int { - // workaround for bad functionality-induced joins (happens when using `Unit`) - pragma[nomagic] - Ap() { this in [0 .. 1] and this < 1 } - } + class Ap = Unit; private class Cc = boolean; diff --git a/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl.qll b/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl.qll index c47b0308855..9fee0c11fff 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl.qll @@ -445,11 +445,7 @@ module Impl<FullStateConfigSig Config> { } private module Stage1 implements StageSig { - class Ap extends int { - // workaround for bad functionality-induced joins (happens when using `Unit`) - pragma[nomagic] - Ap() { this in [0 .. 1] and this < 1 } - } + class Ap = Unit; private class Cc = boolean; 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 c47b0308855..9fee0c11fff 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl.qll @@ -445,11 +445,7 @@ module Impl<FullStateConfigSig Config> { } private module Stage1 implements StageSig { - class Ap extends int { - // workaround for bad functionality-induced joins (happens when using `Unit`) - pragma[nomagic] - Ap() { this in [0 .. 1] and this < 1 } - } + class Ap = Unit; private class Cc = boolean; 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 c47b0308855..9fee0c11fff 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl.qll @@ -445,11 +445,7 @@ module Impl<FullStateConfigSig Config> { } private module Stage1 implements StageSig { - class Ap extends int { - // workaround for bad functionality-induced joins (happens when using `Unit`) - pragma[nomagic] - Ap() { this in [0 .. 1] and this < 1 } - } + class Ap = Unit; private class Cc = boolean; diff --git a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl.qll b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl.qll index c47b0308855..9fee0c11fff 100644 --- a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl.qll +++ b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl.qll @@ -445,11 +445,7 @@ module Impl<FullStateConfigSig Config> { } private module Stage1 implements StageSig { - class Ap extends int { - // workaround for bad functionality-induced joins (happens when using `Unit`) - pragma[nomagic] - Ap() { this in [0 .. 1] and this < 1 } - } + class Ap = Unit; private class Cc = boolean; diff --git a/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowImpl.qll b/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowImpl.qll index c47b0308855..9fee0c11fff 100644 --- a/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowImpl.qll +++ b/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowImpl.qll @@ -445,11 +445,7 @@ module Impl<FullStateConfigSig Config> { } private module Stage1 implements StageSig { - class Ap extends int { - // workaround for bad functionality-induced joins (happens when using `Unit`) - pragma[nomagic] - Ap() { this in [0 .. 1] and this < 1 } - } + class Ap = Unit; private class Cc = boolean; From eed8c72ce6c7ba5c7818e7f018a0a6f18e23ea38 Mon Sep 17 00:00:00 2001 From: Michael Nebel <michaelnebel@github.com> Date: Wed, 15 Mar 2023 11:56:55 +0100 Subject: [PATCH 324/631] Java: Refactor the model generator configurations to use the new API. --- .../utils/modelgenerator/CaptureSinkModels.ql | 4 - .../modelgenerator/CaptureSourceModels.ql | 4 - .../modelgenerator/internal/CaptureModels.qll | 122 ++++++++++-------- .../internal/CaptureModelsSpecific.qll | 26 ++-- .../internal/CaptureSummaryFlow.qll | 4 - 5 files changed, 77 insertions(+), 83 deletions(-) diff --git a/java/ql/src/utils/modelgenerator/CaptureSinkModels.ql b/java/ql/src/utils/modelgenerator/CaptureSinkModels.ql index 8d273ba77f8..4bc621ad6bb 100644 --- a/java/ql/src/utils/modelgenerator/CaptureSinkModels.ql +++ b/java/ql/src/utils/modelgenerator/CaptureSinkModels.ql @@ -8,10 +8,6 @@ import internal.CaptureModels -class Activate extends ActiveConfiguration { - override predicate activateToSinkConfig() { any() } -} - from DataFlowTargetApi api, string sink where sink = captureSink(api) select sink order by sink diff --git a/java/ql/src/utils/modelgenerator/CaptureSourceModels.ql b/java/ql/src/utils/modelgenerator/CaptureSourceModels.ql index f4fc9982797..51e6f68e62c 100644 --- a/java/ql/src/utils/modelgenerator/CaptureSourceModels.ql +++ b/java/ql/src/utils/modelgenerator/CaptureSourceModels.ql @@ -8,10 +8,6 @@ import internal.CaptureModels -class Activate extends ActiveConfiguration { - override predicate activateFromSourceConfig() { any() } -} - from DataFlowTargetApi api, string source where source = captureSource(api) select source order by source diff --git a/java/ql/src/utils/modelgenerator/internal/CaptureModels.qll b/java/ql/src/utils/modelgenerator/internal/CaptureModels.qll index 893c62191b3..7dbdc5bee52 100644 --- a/java/ql/src/utils/modelgenerator/internal/CaptureModels.qll +++ b/java/ql/src/utils/modelgenerator/internal/CaptureModels.qll @@ -5,14 +5,6 @@ private import CaptureModelsSpecific -class ActiveConfiguration extends Unit { - predicate activateThroughFlowConfig() { none() } - - predicate activateFromSourceConfig() { none() } - - predicate activateToSinkConfig() { none() } -} - class DataFlowTargetApi extends TargetApiSpecific { DataFlowTargetApi() { isRelevantForDataFlowModels(this) } } @@ -46,6 +38,20 @@ private predicate isRelevantContent(DataFlow::Content c) { DataFlowPrivate::containerContent(c) } +/** + * Gets the MaD string representation of the parameter node `p`. + */ +string parameterNodeAsInput(DataFlow::ParameterNode p) { + result = parameterAccess(p.asParameter()) + or + result = qualifierString() and p instanceof InstanceParameterNode +} + +/** + * Gets the MaD input string representation of `source`. + */ +string asInputArgument(DataFlow::Node source) { result = asInputArgumentSpecific(source) } + /** * Gets the summary model for `api` with `input`, `output` and `kind`. */ @@ -111,61 +117,70 @@ string captureQualifierFlow(TargetApiSpecific api) { private int accessPathLimit() { result = 2 } +private newtype TTaintState = + TTaintRead(int n) { n in [0 .. accessPathLimit()] } or + TTaintStore(int n) { n in [1 .. accessPathLimit()] } + +abstract private class TaintState extends TTaintState { + abstract string toString(); +} + /** * A FlowState representing a tainted read. */ -private class TaintRead extends DataFlow::FlowState { +private class TaintRead extends TaintState, TTaintRead { private int step; - TaintRead() { this = "TaintRead(" + step + ")" and step in [0 .. accessPathLimit()] } + TaintRead() { this = TTaintRead(step) } /** * Gets the flow state step number. */ int getStep() { result = step } + + override string toString() { result = "TaintRead(" + step + ")" } } /** * A FlowState representing a tainted write. */ -private class TaintStore extends DataFlow::FlowState { +private class TaintStore extends TaintState, TTaintStore { private int step; - TaintStore() { this = "TaintStore(" + step + ")" and step in [1 .. accessPathLimit()] } + TaintStore() { this = TTaintStore(step) } /** * Gets the flow state step number. */ int getStep() { result = step } + + override string toString() { result = "TaintStore(" + step + ")" } } /** - * A TaintTracking Configuration used for tracking flow through APIs. + * A data-flow configuration for tracking flow through APIs. * The sources are the parameters of an API and the sinks are the return values (excluding `this`) and parameters. * * This can be used to generate Flow summaries for APIs from parameter to return. */ -private class ThroughFlowConfig extends TaintTracking::Configuration { - ThroughFlowConfig() { - this = "ThroughFlowConfig" and any(ActiveConfiguration ac).activateThroughFlowConfig() - } +module ThroughFlowConfig implements DataFlow::StateConfigSig { + class FlowState = TaintState; - override predicate isSource(DataFlow::Node source, DataFlow::FlowState state) { + predicate isSource(DataFlow::Node source, FlowState state) { source instanceof DataFlow::ParameterNode and source.getEnclosingCallable() instanceof DataFlowTargetApi and state.(TaintRead).getStep() = 0 } - override predicate isSink(DataFlow::Node sink, DataFlow::FlowState state) { + predicate isSink(DataFlow::Node sink, FlowState state) { sink instanceof DataFlowImplCommon::ReturnNodeExt and not isOwnInstanceAccessNode(sink) and not exists(captureQualifierFlow(sink.asExpr().getEnclosingCallable())) and (state instanceof TaintRead or state instanceof TaintStore) } - override predicate isAdditionalTaintStep( - DataFlow::Node node1, DataFlow::FlowState state1, DataFlow::Node node2, - DataFlow::FlowState state2 + predicate isAdditionalFlowStep( + DataFlow::Node node1, FlowState state1, DataFlow::Node node2, FlowState state2 ) { exists(DataFlowImplCommon::TypedContent tc | DataFlowImplCommon::store(node1, tc, node2, _) and @@ -184,24 +199,28 @@ private class ThroughFlowConfig extends TaintTracking::Configuration { ) } - override predicate isSanitizer(DataFlow::Node n) { + predicate isBarrier(DataFlow::Node n) { exists(Type t | t = n.getType() and not isRelevantType(t)) } - override DataFlow::FlowFeature getAFeature() { + predicate isBarrier(DataFlow::Node node, FlowState state) { none() } + + DataFlow::FlowFeature getAFeature() { result instanceof DataFlow::FeatureEqualSourceSinkCallContext } } +private module ThroughFlow = TaintTracking::MakeWithState<ThroughFlowConfig>; + /** * Gets the summary model(s) of `api`, if there is flow from parameters to return value or parameter. */ string captureThroughFlow(DataFlowTargetApi api) { exists( - ThroughFlowConfig config, DataFlow::ParameterNode p, - DataFlowImplCommon::ReturnNodeExt returnNodeExt, string input, string output + DataFlow::ParameterNode p, DataFlowImplCommon::ReturnNodeExt returnNodeExt, string input, + string output | - config.hasFlow(p, returnNodeExt) and + ThroughFlow::hasFlow(p, returnNodeExt) and returnNodeExt.getEnclosingCallable() = api and input = parameterNodeAsInput(p) and output = returnNodeAsOutput(returnNodeExt) and @@ -211,41 +230,37 @@ string captureThroughFlow(DataFlowTargetApi api) { } /** - * A TaintTracking Configuration used for tracking flow through APIs. + * A dataflow configuration used for finding new sources. * The sources are the already known existing sources and the sinks are the API return nodes. * * This can be used to generate Source summaries for an API, if the API expose an already known source * via its return (then the API itself becomes a source). */ -private class FromSourceConfiguration extends TaintTracking::Configuration { - FromSourceConfiguration() { - this = "FromSourceConfiguration" and any(ActiveConfiguration ac).activateFromSourceConfig() - } +module FromSourceConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node source) { ExternalFlow::sourceNode(source, _) } - override predicate isSource(DataFlow::Node source) { ExternalFlow::sourceNode(source, _) } - - override predicate isSink(DataFlow::Node sink) { + predicate isSink(DataFlow::Node sink) { exists(DataFlowTargetApi c | sink instanceof DataFlowImplCommon::ReturnNodeExt and sink.getEnclosingCallable() = c ) } - override DataFlow::FlowFeature getAFeature() { - result instanceof DataFlow::FeatureHasSinkCallContext - } + DataFlow::FlowFeature getAFeature() { result instanceof DataFlow::FeatureHasSinkCallContext } - override predicate isAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) { + predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) { isRelevantTaintStep(node1, node2) } } +private module FromSource = TaintTracking::Make<FromSourceConfig>; + /** * Gets the source model(s) of `api`, if there is flow from an existing known source to the return of `api`. */ string captureSource(DataFlowTargetApi api) { - exists(DataFlow::Node source, DataFlow::Node sink, FromSourceConfiguration config, string kind | - config.hasFlow(source, sink) and + exists(DataFlow::Node source, DataFlow::Node sink, string kind | + FromSource::hasFlow(source, sink) and ExternalFlow::sourceNode(source, kind) and api = sink.getEnclosingCallable() and isRelevantSourceKind(kind) and @@ -254,35 +269,30 @@ string captureSource(DataFlowTargetApi api) { } /** - * A TaintTracking Configuration used for tracking flow through APIs. + * A dataflow configuration used for finding new sinks. * The sources are the parameters of the API and the fields of the enclosing type. * * This can be used to generate Sink summaries for APIs, if the API propagates a parameter (or enclosing type field) * into an existing known sink (then the API itself becomes a sink). */ -private class PropagateToSinkConfiguration extends TaintTracking::Configuration { - PropagateToSinkConfiguration() { - this = "parameters or fields flowing into sinks" and - any(ActiveConfiguration ac).activateToSinkConfig() - } +module PropagateToSinkConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node source) { apiSource(source) } - override predicate isSource(DataFlow::Node source) { apiSource(source) } + predicate isSink(DataFlow::Node sink) { ExternalFlow::sinkNode(sink, _) } - override predicate isSink(DataFlow::Node sink) { ExternalFlow::sinkNode(sink, _) } + predicate isBarrier(DataFlow::Node node) { sinkModelSanitizer(node) } - override predicate isSanitizer(DataFlow::Node node) { sinkModelSanitizer(node) } - - override DataFlow::FlowFeature getAFeature() { - result instanceof DataFlow::FeatureHasSourceCallContext - } + DataFlow::FlowFeature getAFeature() { result instanceof DataFlow::FeatureHasSourceCallContext } } +private module PropagateToSink = TaintTracking::Make<PropagateToSinkConfig>; + /** * Gets the sink model(s) of `api`, if there is flow from a parameter to an existing known sink. */ string captureSink(DataFlowTargetApi api) { - exists(DataFlow::Node src, DataFlow::Node sink, PropagateToSinkConfiguration config, string kind | - config.hasFlow(src, sink) and + exists(DataFlow::Node src, DataFlow::Node sink, string kind | + PropagateToSink::hasFlow(src, sink) and ExternalFlow::sinkNode(sink, kind) and api = src.getEnclosingCallable() and isRelevantSinkKind(kind) and diff --git a/java/ql/src/utils/modelgenerator/internal/CaptureModelsSpecific.qll b/java/ql/src/utils/modelgenerator/internal/CaptureModelsSpecific.qll index bce229d10a6..e22fc06df6e 100644 --- a/java/ql/src/utils/modelgenerator/internal/CaptureModelsSpecific.qll +++ b/java/ql/src/utils/modelgenerator/internal/CaptureModelsSpecific.qll @@ -130,7 +130,7 @@ private predicate partialModel(TargetApiSpecific api, string type, string name, } /** - * Computes the first 6 columns for CSV rows. + * Computes the first 6 columns for MaD rows. */ string asPartialModel(TargetApiSpecific api) { exists(string type, string name, string parameters | @@ -145,7 +145,7 @@ string asPartialModel(TargetApiSpecific api) { } /** - * Computes the first 4 columns for neutral CSV rows. + * Computes the first 4 columns for neutral MaD rows. */ string asPartialNeutralModel(TargetApiSpecific api) { exists(string type, string name, string parameters | @@ -187,11 +187,14 @@ predicate isRelevantType(J::Type t) { } /** - * Gets the CSV string representation of the qualifier. + * Gets the MaD string representation of the qualifier. */ string qualifierString() { result = "Argument[this]" } -private string parameterAccess(J::Parameter p) { +/** + * Gets the MaD string representation of the parameter `p`. + */ +string parameterAccess(J::Parameter p) { if p.getType() instanceof J::Array and not isPrimitiveTypeUsedForBulkData(p.getType().(J::Array).getElementType()) @@ -202,17 +205,10 @@ private string parameterAccess(J::Parameter p) { else result = "Argument[" + p.getPosition() + "]" } -/** - * Gets the CSV string representation of the parameter node `p`. - */ -string parameterNodeAsInput(DataFlow::ParameterNode p) { - result = parameterAccess(p.asParameter()) - or - result = qualifierString() and p instanceof DataFlow::InstanceParameterNode -} +class InstanceParameterNode = DataFlow::InstanceParameterNode; /** - * Gets the CSV string represention of the the return node `node`. + * Gets the MaD string represention of the the return node `node`. */ string returnNodeAsOutput(DataFlowImplCommon::ReturnNodeExt node) { if node.getKind() instanceof DataFlowImplCommon::ValueReturnKind @@ -268,9 +264,9 @@ predicate apiSource(DataFlow::Node source) { } /** - * Gets the CSV input string representation of `source`. + * Gets the MaD input string representation of `source`. */ -string asInputArgument(DataFlow::Node source) { +string asInputArgumentSpecific(DataFlow::Node source) { exists(int pos | source.(DataFlow::ParameterNode).isParameterOf(_, pos) and result = "Argument[" + pos + "]" diff --git a/java/ql/src/utils/modelgenerator/internal/CaptureSummaryFlow.qll b/java/ql/src/utils/modelgenerator/internal/CaptureSummaryFlow.qll index b859fef0ebb..65a892262f5 100644 --- a/java/ql/src/utils/modelgenerator/internal/CaptureSummaryFlow.qll +++ b/java/ql/src/utils/modelgenerator/internal/CaptureSummaryFlow.qll @@ -1,9 +1,5 @@ private import CaptureModels -private class Activate extends ActiveConfiguration { - override predicate activateThroughFlowConfig() { any() } -} - /** * Capture fluent APIs that return `this`. * Example of a fluent API: From d0732a765b651918dbe165a8e6e724e26f9f3723 Mon Sep 17 00:00:00 2001 From: Michael Nebel <michaelnebel@github.com> Date: Thu, 23 Mar 2023 09:52:42 +0100 Subject: [PATCH 325/631] C#: Sync files. --- .../modelgenerator/internal/CaptureModels.qll | 122 ++++++++++-------- 1 file changed, 66 insertions(+), 56 deletions(-) diff --git a/csharp/ql/src/utils/modelgenerator/internal/CaptureModels.qll b/csharp/ql/src/utils/modelgenerator/internal/CaptureModels.qll index 893c62191b3..7dbdc5bee52 100644 --- a/csharp/ql/src/utils/modelgenerator/internal/CaptureModels.qll +++ b/csharp/ql/src/utils/modelgenerator/internal/CaptureModels.qll @@ -5,14 +5,6 @@ private import CaptureModelsSpecific -class ActiveConfiguration extends Unit { - predicate activateThroughFlowConfig() { none() } - - predicate activateFromSourceConfig() { none() } - - predicate activateToSinkConfig() { none() } -} - class DataFlowTargetApi extends TargetApiSpecific { DataFlowTargetApi() { isRelevantForDataFlowModels(this) } } @@ -46,6 +38,20 @@ private predicate isRelevantContent(DataFlow::Content c) { DataFlowPrivate::containerContent(c) } +/** + * Gets the MaD string representation of the parameter node `p`. + */ +string parameterNodeAsInput(DataFlow::ParameterNode p) { + result = parameterAccess(p.asParameter()) + or + result = qualifierString() and p instanceof InstanceParameterNode +} + +/** + * Gets the MaD input string representation of `source`. + */ +string asInputArgument(DataFlow::Node source) { result = asInputArgumentSpecific(source) } + /** * Gets the summary model for `api` with `input`, `output` and `kind`. */ @@ -111,61 +117,70 @@ string captureQualifierFlow(TargetApiSpecific api) { private int accessPathLimit() { result = 2 } +private newtype TTaintState = + TTaintRead(int n) { n in [0 .. accessPathLimit()] } or + TTaintStore(int n) { n in [1 .. accessPathLimit()] } + +abstract private class TaintState extends TTaintState { + abstract string toString(); +} + /** * A FlowState representing a tainted read. */ -private class TaintRead extends DataFlow::FlowState { +private class TaintRead extends TaintState, TTaintRead { private int step; - TaintRead() { this = "TaintRead(" + step + ")" and step in [0 .. accessPathLimit()] } + TaintRead() { this = TTaintRead(step) } /** * Gets the flow state step number. */ int getStep() { result = step } + + override string toString() { result = "TaintRead(" + step + ")" } } /** * A FlowState representing a tainted write. */ -private class TaintStore extends DataFlow::FlowState { +private class TaintStore extends TaintState, TTaintStore { private int step; - TaintStore() { this = "TaintStore(" + step + ")" and step in [1 .. accessPathLimit()] } + TaintStore() { this = TTaintStore(step) } /** * Gets the flow state step number. */ int getStep() { result = step } + + override string toString() { result = "TaintStore(" + step + ")" } } /** - * A TaintTracking Configuration used for tracking flow through APIs. + * A data-flow configuration for tracking flow through APIs. * The sources are the parameters of an API and the sinks are the return values (excluding `this`) and parameters. * * This can be used to generate Flow summaries for APIs from parameter to return. */ -private class ThroughFlowConfig extends TaintTracking::Configuration { - ThroughFlowConfig() { - this = "ThroughFlowConfig" and any(ActiveConfiguration ac).activateThroughFlowConfig() - } +module ThroughFlowConfig implements DataFlow::StateConfigSig { + class FlowState = TaintState; - override predicate isSource(DataFlow::Node source, DataFlow::FlowState state) { + predicate isSource(DataFlow::Node source, FlowState state) { source instanceof DataFlow::ParameterNode and source.getEnclosingCallable() instanceof DataFlowTargetApi and state.(TaintRead).getStep() = 0 } - override predicate isSink(DataFlow::Node sink, DataFlow::FlowState state) { + predicate isSink(DataFlow::Node sink, FlowState state) { sink instanceof DataFlowImplCommon::ReturnNodeExt and not isOwnInstanceAccessNode(sink) and not exists(captureQualifierFlow(sink.asExpr().getEnclosingCallable())) and (state instanceof TaintRead or state instanceof TaintStore) } - override predicate isAdditionalTaintStep( - DataFlow::Node node1, DataFlow::FlowState state1, DataFlow::Node node2, - DataFlow::FlowState state2 + predicate isAdditionalFlowStep( + DataFlow::Node node1, FlowState state1, DataFlow::Node node2, FlowState state2 ) { exists(DataFlowImplCommon::TypedContent tc | DataFlowImplCommon::store(node1, tc, node2, _) and @@ -184,24 +199,28 @@ private class ThroughFlowConfig extends TaintTracking::Configuration { ) } - override predicate isSanitizer(DataFlow::Node n) { + predicate isBarrier(DataFlow::Node n) { exists(Type t | t = n.getType() and not isRelevantType(t)) } - override DataFlow::FlowFeature getAFeature() { + predicate isBarrier(DataFlow::Node node, FlowState state) { none() } + + DataFlow::FlowFeature getAFeature() { result instanceof DataFlow::FeatureEqualSourceSinkCallContext } } +private module ThroughFlow = TaintTracking::MakeWithState<ThroughFlowConfig>; + /** * Gets the summary model(s) of `api`, if there is flow from parameters to return value or parameter. */ string captureThroughFlow(DataFlowTargetApi api) { exists( - ThroughFlowConfig config, DataFlow::ParameterNode p, - DataFlowImplCommon::ReturnNodeExt returnNodeExt, string input, string output + DataFlow::ParameterNode p, DataFlowImplCommon::ReturnNodeExt returnNodeExt, string input, + string output | - config.hasFlow(p, returnNodeExt) and + ThroughFlow::hasFlow(p, returnNodeExt) and returnNodeExt.getEnclosingCallable() = api and input = parameterNodeAsInput(p) and output = returnNodeAsOutput(returnNodeExt) and @@ -211,41 +230,37 @@ string captureThroughFlow(DataFlowTargetApi api) { } /** - * A TaintTracking Configuration used for tracking flow through APIs. + * A dataflow configuration used for finding new sources. * The sources are the already known existing sources and the sinks are the API return nodes. * * This can be used to generate Source summaries for an API, if the API expose an already known source * via its return (then the API itself becomes a source). */ -private class FromSourceConfiguration extends TaintTracking::Configuration { - FromSourceConfiguration() { - this = "FromSourceConfiguration" and any(ActiveConfiguration ac).activateFromSourceConfig() - } +module FromSourceConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node source) { ExternalFlow::sourceNode(source, _) } - override predicate isSource(DataFlow::Node source) { ExternalFlow::sourceNode(source, _) } - - override predicate isSink(DataFlow::Node sink) { + predicate isSink(DataFlow::Node sink) { exists(DataFlowTargetApi c | sink instanceof DataFlowImplCommon::ReturnNodeExt and sink.getEnclosingCallable() = c ) } - override DataFlow::FlowFeature getAFeature() { - result instanceof DataFlow::FeatureHasSinkCallContext - } + DataFlow::FlowFeature getAFeature() { result instanceof DataFlow::FeatureHasSinkCallContext } - override predicate isAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) { + predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) { isRelevantTaintStep(node1, node2) } } +private module FromSource = TaintTracking::Make<FromSourceConfig>; + /** * Gets the source model(s) of `api`, if there is flow from an existing known source to the return of `api`. */ string captureSource(DataFlowTargetApi api) { - exists(DataFlow::Node source, DataFlow::Node sink, FromSourceConfiguration config, string kind | - config.hasFlow(source, sink) and + exists(DataFlow::Node source, DataFlow::Node sink, string kind | + FromSource::hasFlow(source, sink) and ExternalFlow::sourceNode(source, kind) and api = sink.getEnclosingCallable() and isRelevantSourceKind(kind) and @@ -254,35 +269,30 @@ string captureSource(DataFlowTargetApi api) { } /** - * A TaintTracking Configuration used for tracking flow through APIs. + * A dataflow configuration used for finding new sinks. * The sources are the parameters of the API and the fields of the enclosing type. * * This can be used to generate Sink summaries for APIs, if the API propagates a parameter (or enclosing type field) * into an existing known sink (then the API itself becomes a sink). */ -private class PropagateToSinkConfiguration extends TaintTracking::Configuration { - PropagateToSinkConfiguration() { - this = "parameters or fields flowing into sinks" and - any(ActiveConfiguration ac).activateToSinkConfig() - } +module PropagateToSinkConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node source) { apiSource(source) } - override predicate isSource(DataFlow::Node source) { apiSource(source) } + predicate isSink(DataFlow::Node sink) { ExternalFlow::sinkNode(sink, _) } - override predicate isSink(DataFlow::Node sink) { ExternalFlow::sinkNode(sink, _) } + predicate isBarrier(DataFlow::Node node) { sinkModelSanitizer(node) } - override predicate isSanitizer(DataFlow::Node node) { sinkModelSanitizer(node) } - - override DataFlow::FlowFeature getAFeature() { - result instanceof DataFlow::FeatureHasSourceCallContext - } + DataFlow::FlowFeature getAFeature() { result instanceof DataFlow::FeatureHasSourceCallContext } } +private module PropagateToSink = TaintTracking::Make<PropagateToSinkConfig>; + /** * Gets the sink model(s) of `api`, if there is flow from a parameter to an existing known sink. */ string captureSink(DataFlowTargetApi api) { - exists(DataFlow::Node src, DataFlow::Node sink, PropagateToSinkConfiguration config, string kind | - config.hasFlow(src, sink) and + exists(DataFlow::Node src, DataFlow::Node sink, string kind | + PropagateToSink::hasFlow(src, sink) and ExternalFlow::sinkNode(sink, kind) and api = src.getEnclosingCallable() and isRelevantSinkKind(kind) and From b17a71674a45e001f5cceba2105bac2f10dd8fa3 Mon Sep 17 00:00:00 2001 From: Michael Nebel <michaelnebel@github.com> Date: Thu, 16 Mar 2023 12:24:48 +0100 Subject: [PATCH 326/631] C#: Refactor the model generator configurations to use the new API. --- .../utils/modelgenerator/CaptureSinkModels.ql | 4 ---- .../utils/modelgenerator/CaptureSourceModels.ql | 4 ---- .../internal/CaptureModelsSpecific.qll | 17 +++++------------ .../internal/CaptureSummaryFlow.qll | 4 ---- 4 files changed, 5 insertions(+), 24 deletions(-) diff --git a/csharp/ql/src/utils/modelgenerator/CaptureSinkModels.ql b/csharp/ql/src/utils/modelgenerator/CaptureSinkModels.ql index bba5081c223..d00f49904a5 100644 --- a/csharp/ql/src/utils/modelgenerator/CaptureSinkModels.ql +++ b/csharp/ql/src/utils/modelgenerator/CaptureSinkModels.ql @@ -8,10 +8,6 @@ import internal.CaptureModels -class Activate extends ActiveConfiguration { - override predicate activateToSinkConfig() { any() } -} - from DataFlowTargetApi api, string sink where sink = captureSink(api) select sink order by sink diff --git a/csharp/ql/src/utils/modelgenerator/CaptureSourceModels.ql b/csharp/ql/src/utils/modelgenerator/CaptureSourceModels.ql index f504a291d7e..a4dc734d178 100644 --- a/csharp/ql/src/utils/modelgenerator/CaptureSourceModels.ql +++ b/csharp/ql/src/utils/modelgenerator/CaptureSourceModels.ql @@ -8,10 +8,6 @@ import internal.CaptureModels -class Activate extends ActiveConfiguration { - override predicate activateFromSourceConfig() { any() } -} - from DataFlowTargetApi api, string source where source = captureSource(api) select source order by source diff --git a/csharp/ql/src/utils/modelgenerator/internal/CaptureModelsSpecific.qll b/csharp/ql/src/utils/modelgenerator/internal/CaptureModelsSpecific.qll index 1fc7636ca65..8d019508abd 100644 --- a/csharp/ql/src/utils/modelgenerator/internal/CaptureModelsSpecific.qll +++ b/csharp/ql/src/utils/modelgenerator/internal/CaptureModelsSpecific.qll @@ -110,7 +110,7 @@ predicate isRelevantType(CS::Type t) { } /** - * Gets the CSV string representation of the qualifier. + * Gets the MaD string representation of the qualifier. */ string qualifierString() { result = "Argument[this]" } @@ -120,14 +120,7 @@ string parameterAccess(CS::Parameter p) { else result = "Argument[" + p.getPosition() + "]" } -/** - * Gets the CSV string representation of the parameter node `p`. - */ -string parameterNodeAsInput(DataFlow::ParameterNode p) { - result = parameterAccess(p.asParameter()) - or - result = qualifierString() and p instanceof DataFlowPrivate::InstanceParameterNode -} +class InstanceParameterNode = DataFlowPrivate::InstanceParameterNode; pragma[nomagic] private CS::Parameter getParameter(DataFlowImplCommon::ReturnNodeExt node, ParameterPosition pos) { @@ -135,7 +128,7 @@ private CS::Parameter getParameter(DataFlowImplCommon::ReturnNodeExt node, Param } /** - * Gets the CSV string representation of the the return node `node`. + * Gets the MaD string representation of the the return node `node`. */ string returnNodeAsOutput(DataFlowImplCommon::ReturnNodeExt node) { if node.getKind() instanceof DataFlowImplCommon::ValueReturnKind @@ -188,9 +181,9 @@ predicate apiSource(DataFlow::Node source) { } /** - * Gets the CSV input string representation of `source`. + * Gets the MaD input string representation of `source`. */ -string asInputArgument(DataFlow::Node source) { +string asInputArgumentSpecific(DataFlow::Node source) { exists(int pos | pos = source.(DataFlow::ParameterNode).getParameter().getPosition() and result = "Argument[" + pos + "]" diff --git a/csharp/ql/src/utils/modelgenerator/internal/CaptureSummaryFlow.qll b/csharp/ql/src/utils/modelgenerator/internal/CaptureSummaryFlow.qll index 1ed6b9a4850..2b3ce63249c 100644 --- a/csharp/ql/src/utils/modelgenerator/internal/CaptureSummaryFlow.qll +++ b/csharp/ql/src/utils/modelgenerator/internal/CaptureSummaryFlow.qll @@ -1,9 +1,5 @@ private import CaptureModels -private class Activate extends ActiveConfiguration { - override predicate activateThroughFlowConfig() { any() } -} - /** * Capture fluent APIs that return `this`. * Example of a fluent API: From ccb816ed844dcef50765138db161d9de262291a4 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli <redsun82@github.com> Date: Thu, 23 Mar 2023 10:22:18 +0100 Subject: [PATCH 327/631] Java: autoformat --- java/ql/src/Security/CWE/CWE-190/ArithmeticTainted.ql | 3 ++- .../Security/CWE/CWE-200/TempDirLocalInformationDisclosure.ql | 4 +++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/java/ql/src/Security/CWE/CWE-190/ArithmeticTainted.ql b/java/ql/src/Security/CWE/CWE-190/ArithmeticTainted.ql index 99d9879d19e..c4294e92ef0 100644 --- a/java/ql/src/Security/CWE/CWE-190/ArithmeticTainted.ql +++ b/java/ql/src/Security/CWE/CWE-190/ArithmeticTainted.ql @@ -37,7 +37,8 @@ module RemoteUserInputOverflow = TaintTracking::Make<RemoteUserInputOverflowConf module RemoteUserInputUnderflow = TaintTracking::Make<RemoteUserInputUnderflowConfig>; module Flow = - DataFlow::MergePathGraph<RemoteUserInputOverflow::PathNode, RemoteUserInputUnderflow::PathNode, RemoteUserInputOverflow::PathGraph, RemoteUserInputUnderflow::PathGraph>; + DataFlow::MergePathGraph<RemoteUserInputOverflow::PathNode, RemoteUserInputUnderflow::PathNode, + RemoteUserInputOverflow::PathGraph, RemoteUserInputUnderflow::PathGraph>; import Flow::PathGraph diff --git a/java/ql/src/Security/CWE/CWE-200/TempDirLocalInformationDisclosure.ql b/java/ql/src/Security/CWE/CWE-200/TempDirLocalInformationDisclosure.ql index 76998b40b50..6d99eba59c2 100644 --- a/java/ql/src/Security/CWE/CWE-200/TempDirLocalInformationDisclosure.ql +++ b/java/ql/src/Security/CWE/CWE-200/TempDirLocalInformationDisclosure.ql @@ -261,7 +261,9 @@ module InsecureMethodPathGraph implements DataFlow::PathGraphSig<MethodAccessIns } module Flow = - DataFlow::MergePathGraph<TempDirSystemGetPropertyToCreate::PathNode, MethodAccessInsecureFileCreation, TempDirSystemGetPropertyToCreate::PathGraph, InsecureMethodPathGraph>; + DataFlow::MergePathGraph<TempDirSystemGetPropertyToCreate::PathNode, + MethodAccessInsecureFileCreation, TempDirSystemGetPropertyToCreate::PathGraph, + InsecureMethodPathGraph>; import Flow::PathGraph From d258a1c72854eb9f7ccdd7f1e4ee185b589dce7b Mon Sep 17 00:00:00 2001 From: Michael Nebel <michaelnebel@github.com> Date: Thu, 16 Mar 2023 14:08:17 +0100 Subject: [PATCH 328/631] C#/Java: Some light re-factoring. --- .../src/utils/modelgenerator/CaptureDiscardedSummaryModels.ql | 2 +- csharp/ql/src/utils/modelgenerator/CaptureNeutralModels.ql | 2 +- csharp/ql/src/utils/modelgenerator/CaptureSummaryModels.ql | 2 +- .../src/utils/modelgenerator/internal/CaptureModelsSpecific.qll | 1 - .../{CaptureSummaryFlow.qll => CaptureSummaryFlowQuery.qll} | 0 java/ql/src/utils/modelgenerator/CaptureNeutralModels.ql | 2 +- java/ql/src/utils/modelgenerator/CaptureSummaryModels.ql | 2 +- .../src/utils/modelgenerator/internal/CaptureModelsSpecific.qll | 1 - .../{CaptureSummaryFlow.qll => CaptureSummaryFlowQuery.qll} | 0 9 files changed, 5 insertions(+), 7 deletions(-) rename csharp/ql/src/utils/modelgenerator/internal/{CaptureSummaryFlow.qll => CaptureSummaryFlowQuery.qll} (100%) rename java/ql/src/utils/modelgenerator/internal/{CaptureSummaryFlow.qll => CaptureSummaryFlowQuery.qll} (100%) diff --git a/csharp/ql/src/utils/modelgenerator/CaptureDiscardedSummaryModels.ql b/csharp/ql/src/utils/modelgenerator/CaptureDiscardedSummaryModels.ql index 3a2a3454900..dd9648ce2d4 100644 --- a/csharp/ql/src/utils/modelgenerator/CaptureDiscardedSummaryModels.ql +++ b/csharp/ql/src/utils/modelgenerator/CaptureDiscardedSummaryModels.ql @@ -6,7 +6,7 @@ import semmle.code.csharp.dataflow.internal.FlowSummaryImpl as FlowSummaryImpl import internal.CaptureModels -import internal.CaptureSummaryFlow +import internal.CaptureSummaryFlowQuery from DataFlowTargetApi api, string flow where diff --git a/csharp/ql/src/utils/modelgenerator/CaptureNeutralModels.ql b/csharp/ql/src/utils/modelgenerator/CaptureNeutralModels.ql index 933df8c765a..e4424c54ad5 100644 --- a/csharp/ql/src/utils/modelgenerator/CaptureNeutralModels.ql +++ b/csharp/ql/src/utils/modelgenerator/CaptureNeutralModels.ql @@ -8,7 +8,7 @@ import semmle.code.csharp.dataflow.internal.FlowSummaryImpl as FlowSummaryImpl import internal.CaptureModels -import internal.CaptureSummaryFlow +import internal.CaptureSummaryFlowQuery from DataFlowTargetApi api, string noflow where diff --git a/csharp/ql/src/utils/modelgenerator/CaptureSummaryModels.ql b/csharp/ql/src/utils/modelgenerator/CaptureSummaryModels.ql index 641c260adf8..920c5b57a74 100644 --- a/csharp/ql/src/utils/modelgenerator/CaptureSummaryModels.ql +++ b/csharp/ql/src/utils/modelgenerator/CaptureSummaryModels.ql @@ -8,7 +8,7 @@ import semmle.code.csharp.dataflow.internal.FlowSummaryImpl as FlowSummaryImpl import internal.CaptureModels -import internal.CaptureSummaryFlow +import internal.CaptureSummaryFlowQuery from DataFlowTargetApi api, string flow where flow = captureFlow(api) and not api.(FlowSummaryImpl::Public::SummarizedCallable).isManual() diff --git a/csharp/ql/src/utils/modelgenerator/internal/CaptureModelsSpecific.qll b/csharp/ql/src/utils/modelgenerator/internal/CaptureModelsSpecific.qll index 8d019508abd..0414de03016 100644 --- a/csharp/ql/src/utils/modelgenerator/internal/CaptureModelsSpecific.qll +++ b/csharp/ql/src/utils/modelgenerator/internal/CaptureModelsSpecific.qll @@ -7,7 +7,6 @@ private import dotnet private import semmle.code.csharp.commons.Util as Util private import semmle.code.csharp.commons.Collections as Collections private import semmle.code.csharp.dataflow.internal.DataFlowDispatch -private import semmle.code.csharp.frameworks.System as System private import semmle.code.csharp.frameworks.system.linq.Expressions import semmle.code.csharp.dataflow.ExternalFlow as ExternalFlow import semmle.code.csharp.dataflow.internal.DataFlowImplCommon as DataFlowImplCommon diff --git a/csharp/ql/src/utils/modelgenerator/internal/CaptureSummaryFlow.qll b/csharp/ql/src/utils/modelgenerator/internal/CaptureSummaryFlowQuery.qll similarity index 100% rename from csharp/ql/src/utils/modelgenerator/internal/CaptureSummaryFlow.qll rename to csharp/ql/src/utils/modelgenerator/internal/CaptureSummaryFlowQuery.qll diff --git a/java/ql/src/utils/modelgenerator/CaptureNeutralModels.ql b/java/ql/src/utils/modelgenerator/CaptureNeutralModels.ql index 1f0c9fa5427..06fc24a054c 100644 --- a/java/ql/src/utils/modelgenerator/CaptureNeutralModels.ql +++ b/java/ql/src/utils/modelgenerator/CaptureNeutralModels.ql @@ -7,7 +7,7 @@ */ import internal.CaptureModels -import internal.CaptureSummaryFlow +import internal.CaptureSummaryFlowQuery from DataFlowTargetApi api, string noflow where noflow = captureNoFlow(api) diff --git a/java/ql/src/utils/modelgenerator/CaptureSummaryModels.ql b/java/ql/src/utils/modelgenerator/CaptureSummaryModels.ql index 33d07d5f2c1..607ddbe4fb6 100644 --- a/java/ql/src/utils/modelgenerator/CaptureSummaryModels.ql +++ b/java/ql/src/utils/modelgenerator/CaptureSummaryModels.ql @@ -7,7 +7,7 @@ */ import internal.CaptureModels -import internal.CaptureSummaryFlow +import internal.CaptureSummaryFlowQuery from DataFlowTargetApi api, string flow where flow = captureFlow(api) diff --git a/java/ql/src/utils/modelgenerator/internal/CaptureModelsSpecific.qll b/java/ql/src/utils/modelgenerator/internal/CaptureModelsSpecific.qll index e22fc06df6e..8823a8977d5 100644 --- a/java/ql/src/utils/modelgenerator/internal/CaptureModelsSpecific.qll +++ b/java/ql/src/utils/modelgenerator/internal/CaptureModelsSpecific.qll @@ -3,7 +3,6 @@ */ private import java as J -private import semmle.code.java.dataflow.internal.DataFlowNodes private import semmle.code.java.dataflow.internal.DataFlowPrivate private import semmle.code.java.dataflow.internal.ContainerFlow as ContainerFlow private import semmle.code.java.dataflow.DataFlow as Df diff --git a/java/ql/src/utils/modelgenerator/internal/CaptureSummaryFlow.qll b/java/ql/src/utils/modelgenerator/internal/CaptureSummaryFlowQuery.qll similarity index 100% rename from java/ql/src/utils/modelgenerator/internal/CaptureSummaryFlow.qll rename to java/ql/src/utils/modelgenerator/internal/CaptureSummaryFlowQuery.qll From e189b36e3f710e9d06e3092ba765e3d8c7af0ab1 Mon Sep 17 00:00:00 2001 From: erik-krogh <erik-krogh@github.com> Date: Thu, 23 Mar 2023 10:35:58 +0100 Subject: [PATCH 329/631] materialize less strings when ranking states --- .../CWE-400/ReDoS/PolynomialBackTracking.expected | 10 +++++----- .../Security/CWE-400/ReDoS/PolynomialReDoS.expected | 2 +- .../PolynomialBackTracking.expected | 2 +- .../CWE-730-PolynomialReDoS/PolynomialReDoS.expected | 2 +- shared/regex/codeql/regex/nfa/NfaUtils.qll | 2 ++ .../regex/codeql/regex/nfa/SuperlinearBackTracking.qll | 10 +++++----- 6 files changed, 15 insertions(+), 13 deletions(-) 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 cd239562a46..db29a305639 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 @@ -1,7 +1,7 @@ | highlight.js:2:26:2:979 | ((traffic-flow\|traffic-generator\|firewall\|scheduler\|aaa\|accounting\|address-list\|address\|align\|area\|bandwidth-server\|bfd\|bgp\|bridge\|client\|clock\|community\|config\|connection\|console\|customer\|default\|dhcp-client\|dhcp-server\|discovery\|dns\|e-mail\|ethernet\|filter\|firewall\|firmware\|gps\|graphing\|group\|hardware\|health\|hotspot\|identity\|igmp-proxy\|incoming\|instance\|interface\|ip\|ipsec\|ipv6\|irq\|l2tp-server\|lcd\|ldp\|logging\|mac-server\|mac-winbox\|mangle\|manual\|mirror\|mme\|mpls\|nat\|nd\|neighbor\|network\|note\|ntp\|ospf\|ospf-v3\|ovpn-server\|page\|peer\|pim\|ping\|policy\|pool\|port\|ppp\|pppoe-client\|pptp-server\|prefix\|profile\|proposal\|proxy\|queue\|radius\|resource\|rip\|ripng\|route\|routing\|screen\|script\|security-profiles\|server\|service\|service-port\|settings\|shares\|smb\|sms\|sniffer\|snmp\|snooper\|socks\|sstp-server\|system\|tool\|tracking\|type\|upgrade\|upnp\|user-manager\|users\|user\|vlan\|secret\|vrrp\|watchdog\|web-access\|wireless\|pptp\|pppoe\|lan\|wan\|layer7-protocol\|lease\|simple\|raw);?\\s)+ | Strings starting with '/' and with many repetitions of 'ip\\t' can start matching anywhere after the start of the preceeding (\\.\\.\\/\|\\/\|\\s)((traffic-flow\|traffic-generator\|firewall\|scheduler\|aaa\|accounting\|address-list\|address\|align\|area\|bandwidth-server\|bfd\|bgp\|bridge\|client\|clock\|community\|config\|connection\|console\|customer\|default\|dhcp-client\|dhcp-server\|discovery\|dns\|e-mail\|ethernet\|filter\|firewall\|firmware\|gps\|graphing\|group\|hardware\|health\|hotspot\|identity\|igmp-proxy\|incoming\|instance\|interface\|ip\|ipsec\|ipv6\|irq\|l2tp-server\|lcd\|ldp\|logging\|mac-server\|mac-winbox\|mangle\|manual\|mirror\|mme\|mpls\|nat\|nd\|neighbor\|network\|note\|ntp\|ospf\|ospf-v3\|ovpn-server\|page\|peer\|pim\|ping\|policy\|pool\|port\|ppp\|pppoe-client\|pptp-server\|prefix\|profile\|proposal\|proxy\|queue\|radius\|resource\|rip\|ripng\|route\|routing\|screen\|script\|security-profiles\|server\|service\|service-port\|settings\|shares\|smb\|sms\|sniffer\|snmp\|snooper\|socks\|sstp-server\|system\|tool\|tracking\|type\|upgrade\|upnp\|user-manager\|users\|user\|vlan\|secret\|vrrp\|watchdog\|web-access\|wireless\|pptp\|pppoe\|lan\|wan\|layer7-protocol\|lease\|simple\|raw);?\\s)+X | | highlight.js:3:27:3:971 | ((traffic-flow\|traffic-generator\|firewall\|scheduler\|aaa\|accounting\|address-list\|address\|align\|area\|bandwidth-server\|bfd\|bgp\|bridge\|client\|clock\|community\|config\|connection\|console\|customer\|default\|dhcp-client\|dhcp-server\|discovery\|dns\|e-mail\|ethernet\|filter\|firmware\|gps\|graphing\|group\|hardware\|health\|hotspot\|identity\|igmp-proxy\|incoming\|instance\|interface\|ip\|ipsec\|ipv6\|irq\|l2tp-server\|lcd\|ldp\|logging\|mac-server\|mac-winbox\|mangle\|manual\|mirror\|mme\|mpls\|nat\|nd\|neighbor\|network\|note\|ntp\|ospf\|ospf-v3\|ovpn-server\|page\|peer\|pim\|ping\|policy\|pool\|port\|ppp\|pppoe-client\|pptp-server\|prefix\|profile\|proposal\|proxy\|queue\|radius\|resource\|rip\|ripng\|route\|routing\|screen\|script\|security-profiles\|server\|service\|service-port\|settings\|shares\|smb\|sms\|sniffer\|snmp\|snooper\|socks\|sstp-server\|system\|tool\|tracking\|type\|upgrade\|upnp\|user-manager\|users\|user\|vlan\|secret\|vrrp\|watchdog\|web-access\|wireless\|pptp\|pppoe\|lan\|wan\|layer7-protocol\|lease\|simple\|raw);?\\s)+ | Strings starting with '/' and with many repetitions of 'ip\\t' can start matching anywhere after the start of the preceeding (\\.\\.\\/\|\\/\|\\s)((traffic-flow\|traffic-generator\|firewall\|scheduler\|aaa\|accounting\|address-list\|address\|align\|area\|bandwidth-server\|bfd\|bgp\|bridge\|client\|clock\|community\|config\|connection\|console\|customer\|default\|dhcp-client\|dhcp-server\|discovery\|dns\|e-mail\|ethernet\|filter\|firmware\|gps\|graphing\|group\|hardware\|health\|hotspot\|identity\|igmp-proxy\|incoming\|instance\|interface\|ip\|ipsec\|ipv6\|irq\|l2tp-server\|lcd\|ldp\|logging\|mac-server\|mac-winbox\|mangle\|manual\|mirror\|mme\|mpls\|nat\|nd\|neighbor\|network\|note\|ntp\|ospf\|ospf-v3\|ovpn-server\|page\|peer\|pim\|ping\|policy\|pool\|port\|ppp\|pppoe-client\|pptp-server\|prefix\|profile\|proposal\|proxy\|queue\|radius\|resource\|rip\|ripng\|route\|routing\|screen\|script\|security-profiles\|server\|service\|service-port\|settings\|shares\|smb\|sms\|sniffer\|snmp\|snooper\|socks\|sstp-server\|system\|tool\|tracking\|type\|upgrade\|upnp\|user-manager\|users\|user\|vlan\|secret\|vrrp\|watchdog\|web-access\|wireless\|pptp\|pppoe\|lan\|wan\|layer7-protocol\|lease\|simple\|raw);?\\s)+X | | highlight.js:6:12:6:695 | (Add\|Clear\|Close\|Copy\|Enter\|Exit\|Find\|Format\|Get\|Hide\|Join\|Lock\|Move\|New\|Open\|Optimize\|Pop\|Push\|Redo\|Remove\|Rename\|Reset\|Resize\|Search\|Select\|Set\|Show\|Skip\|Split\|Step\|Switch\|Undo\|Unlock\|Watch\|Backup\|Checkpoint\|Compare\|Compress\|Convert\|ConvertFrom\|ConvertTo\|Dismount\|Edit\|Expand\|Export\|Group\|Import\|Initialize\|Limit\|Merge\|New\|Out\|Publish\|Restore\|Save\|Sync\|Unpublish\|Update\|Approve\|Assert\|Complete\|Confirm\|Deny\|Disable\|Enable\|Install\|Invoke\|Register\|Request\|Restart\|Resume\|Start\|Stop\|Submit\|Suspend\|Uninstall\|Unregister\|Wait\|Debug\|Measure\|Ping\|Repair\|Resolve\|Test\|Trace\|Connect\|Disconnect\|Read\|Receive\|Send\|Write\|Block\|Grant\|Protect\|Revoke\|Unblock\|Unprotect\|Use\|ForEach\|Sort\|Tee\|Where)+ | Strings with many repetitions of 'Add' can start matching anywhere after the start of the preceeding (Add\|Clear\|Close\|Copy\|Enter\|Exit\|Find\|Format\|Get\|Hide\|Join\|Lock\|Move\|New\|Open\|Optimize\|Pop\|Push\|Redo\|Remove\|Rename\|Reset\|Resize\|Search\|Select\|Set\|Show\|Skip\|Split\|Step\|Switch\|Undo\|Unlock\|Watch\|Backup\|Checkpoint\|Compare\|Compress\|Convert\|ConvertFrom\|ConvertTo\|Dismount\|Edit\|Expand\|Export\|Group\|Import\|Initialize\|Limit\|Merge\|New\|Out\|Publish\|Restore\|Save\|Sync\|Unpublish\|Update\|Approve\|Assert\|Complete\|Confirm\|Deny\|Disable\|Enable\|Install\|Invoke\|Register\|Request\|Restart\|Resume\|Start\|Stop\|Submit\|Suspend\|Uninstall\|Unregister\|Wait\|Debug\|Measure\|Ping\|Repair\|Resolve\|Test\|Trace\|Connect\|Disconnect\|Read\|Receive\|Send\|Write\|Block\|Grant\|Protect\|Revoke\|Unblock\|Unprotect\|Use\|ForEach\|Sort\|Tee\|Where)+(-)[\\w\\d]+ | -| highlight.js:7:13:7:692 | (Add\|Clear\|Close\|Copy\|Enter\|Exit\|Find\|Format\|Get\|Hide\|Join\|Lock\|Move\|New\|Open\|Optimize\|Pop\|Push\|Redo\|Remove\|Rename\|Reset\|Resize\|Search\|Select\|Set\|Show\|Skip\|Split\|Step\|Switch\|Undo\|Unlock\|Watch\|Backup\|Checkpoint\|Compare\|Compress\|Convert\|ConvertFrom\|ConvertTo\|Dismount\|Edit\|Expand\|Export\|Group\|Import\|Initialize\|Limit\|Merge\|Out\|Publish\|Restore\|Save\|Sync\|Unpublish\|Update\|Approve\|Assert\|Complete\|Confirm\|Deny\|Disable\|Enable\|Install\|Invoke\|Register\|Request\|Restart\|Resume\|Start\|Stop\|Submit\|Suspend\|Uninstall\|Unregister\|Wait\|Debug\|Measure\|Ping\|Repair\|Resolve\|Test\|Trace\|Connect\|Disconnect\|Read\|Receive\|Send\|Write\|Block\|Grant\|Protect\|Revoke\|Unblock\|Unprotect\|Use\|ForEach\|Sort\|Tee\|Where)+ | Strings with many repetitions of 'Pop' can start matching anywhere after the start of the preceeding (Add\|Clear\|Close\|Copy\|Enter\|Exit\|Find\|Format\|Get\|Hide\|Join\|Lock\|Move\|New\|Open\|Optimize\|Pop\|Push\|Redo\|Remove\|Rename\|Reset\|Resize\|Search\|Select\|Set\|Show\|Skip\|Split\|Step\|Switch\|Undo\|Unlock\|Watch\|Backup\|Checkpoint\|Compare\|Compress\|Convert\|ConvertFrom\|ConvertTo\|Dismount\|Edit\|Expand\|Export\|Group\|Import\|Initialize\|Limit\|Merge\|Out\|Publish\|Restore\|Save\|Sync\|Unpublish\|Update\|Approve\|Assert\|Complete\|Confirm\|Deny\|Disable\|Enable\|Install\|Invoke\|Register\|Request\|Restart\|Resume\|Start\|Stop\|Submit\|Suspend\|Uninstall\|Unregister\|Wait\|Debug\|Measure\|Ping\|Repair\|Resolve\|Test\|Trace\|Connect\|Disconnect\|Read\|Receive\|Send\|Write\|Block\|Grant\|Protect\|Revoke\|Unblock\|Unprotect\|Use\|ForEach\|Sort\|Tee\|Where)+(-)[\\w\\d]+ | +| highlight.js:7:13:7:692 | (Add\|Clear\|Close\|Copy\|Enter\|Exit\|Find\|Format\|Get\|Hide\|Join\|Lock\|Move\|New\|Open\|Optimize\|Pop\|Push\|Redo\|Remove\|Rename\|Reset\|Resize\|Search\|Select\|Set\|Show\|Skip\|Split\|Step\|Switch\|Undo\|Unlock\|Watch\|Backup\|Checkpoint\|Compare\|Compress\|Convert\|ConvertFrom\|ConvertTo\|Dismount\|Edit\|Expand\|Export\|Group\|Import\|Initialize\|Limit\|Merge\|Out\|Publish\|Restore\|Save\|Sync\|Unpublish\|Update\|Approve\|Assert\|Complete\|Confirm\|Deny\|Disable\|Enable\|Install\|Invoke\|Register\|Request\|Restart\|Resume\|Start\|Stop\|Submit\|Suspend\|Uninstall\|Unregister\|Wait\|Debug\|Measure\|Ping\|Repair\|Resolve\|Test\|Trace\|Connect\|Disconnect\|Read\|Receive\|Send\|Write\|Block\|Grant\|Protect\|Revoke\|Unblock\|Unprotect\|Use\|ForEach\|Sort\|Tee\|Where)+ | Strings with many repetitions of 'Add' can start matching anywhere after the start of the preceeding (Add\|Clear\|Close\|Copy\|Enter\|Exit\|Find\|Format\|Get\|Hide\|Join\|Lock\|Move\|New\|Open\|Optimize\|Pop\|Push\|Redo\|Remove\|Rename\|Reset\|Resize\|Search\|Select\|Set\|Show\|Skip\|Split\|Step\|Switch\|Undo\|Unlock\|Watch\|Backup\|Checkpoint\|Compare\|Compress\|Convert\|ConvertFrom\|ConvertTo\|Dismount\|Edit\|Expand\|Export\|Group\|Import\|Initialize\|Limit\|Merge\|Out\|Publish\|Restore\|Save\|Sync\|Unpublish\|Update\|Approve\|Assert\|Complete\|Confirm\|Deny\|Disable\|Enable\|Install\|Invoke\|Register\|Request\|Restart\|Resume\|Start\|Stop\|Submit\|Suspend\|Uninstall\|Unregister\|Wait\|Debug\|Measure\|Ping\|Repair\|Resolve\|Test\|Trace\|Connect\|Disconnect\|Read\|Receive\|Send\|Write\|Block\|Grant\|Protect\|Revoke\|Unblock\|Unprotect\|Use\|ForEach\|Sort\|Tee\|Where)+(-)[\\w\\d]+ | | highlight.js:14:17:14:52 | [a-z0-9&#*=?@\\\\><:,()$[\\]_.{}!+%^-]+ | Strings with many repetitions of '!' can start matching anywhere after the start of the preceeding ([ ]*[a-z0-9&#*=?@\\\\><:,()$[\\]_.{}!+%^-]+)+ | | highlight.js:18:14:18:16 | .*? | Strings starting with ''' and with many repetitions of ''' can start matching anywhere after the start of the preceeding .*? | | highlight.js:18:20:18:22 | .*? | Strings starting with '"' and with many repetitions of '"' can start matching anywhere after the start of the preceeding .*? | @@ -128,7 +128,7 @@ | polynomial-redos.js:130:21:130:22 | c+ | Strings starting with 'c' and with many repetitions of 'c' can start matching anywhere after the start of the preceeding cc+D | | polynomial-redos.js:133:22:133:23 | f+ | Strings starting with 'f' and with many repetitions of 'f' can start matching anywhere after the start of the preceeding ff+G | | polynomial-redos.js:136:25:136:26 | h+ | Strings starting with 'h' and with many repetitions of 'h' can start matching anywhere after the start of the preceeding hh+I | -| polynomial-redos.js:138:322:138:323 | .* | Strings starting with 'AAAAAAAAAAAAAAAAAAAAAABBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC' and with many repetitions of 'AAAAAAAAAAAAAAAAAAAAAABBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC' can start matching anywhere after the start of the preceeding (AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)C.*X | +| polynomial-redos.js:138:322:138:323 | .* | Strings starting with 'AAAAAAAAAAAAAAAAAAAAAABBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC' and with many repetitions of 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC' can start matching anywhere after the start of the preceeding (AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)C.*X | | regexplib/address.js:27:3:27:5 | \\s* | Strings with many repetitions of '\\t' can start matching anywhere after the start of the preceeding (\\s*\\(?0\\d{4}\\)?(\\s*\|-)\\d{3}(\\s*\|-)\\d{3}\\s*) | | regexplib/address.js:27:48:27:50 | \\s* | Strings with many repetitions of '\\t' can start matching anywhere after the start of the preceeding (\\s*\\(?0\\d{3}\\)?(\\s*\|-)\\d{3}(\\s*\|-)\\d{4}\\s*) | | regexplib/address.js:27:93:27:95 | \\s* | Strings with many repetitions of '\\t' can start matching anywhere after the start of the preceeding (\\s*(7\|8)(\\d{7}\|\\d{3}(\\-\|\\s{1})\\d{4})\\s*) | @@ -170,7 +170,7 @@ | regexplib/email.js:8:57:8:84 | (?:(?:[^\\"\\\\\\r\\n])\|(?:\\\\.))* | Strings starting with '"' and with many repetitions of '\\\\"' can start matching anywhere after the start of the preceeding (?<user>(?:(?:[^ \\t\\(\\)\\<\\>@,;\\:\\\\\\"\\.\\[\\]\\r\\n]+)\|(?:\\"(?:(?:[^\\"\\\\\\r\\n])\|(?:\\\\.))*\\"))(?:\\.(?:(?:[^ \\t\\(\\)\\<\\>@,;\\:\\\\\\"\\.\\[\\]\\r\\n]+)\|(?:\\"(?:(?:[^\\"\\\\\\r\\n])\|(?:\\\\.))*\\")))*)@(?<domain>(?:(?:[^ \\t\\(\\)\\<\\>@,;\\:\\\\\\"\\.\\[\\]\\r\\n]+)\|(?:\\[(?:(?:[^\\[\\]\\\\\\r\\n])\|(?:\\\\.))*\\]))(?:\\.(?:(?:[^ \\t\\(\\)\\<\\>@,;\\:\\\\\\"\\.\\[\\]\\r\\n]+)\|(?:\\[(?:(?:[^\\[\\]\\\\\\r\\n])\|(?:\\\\.))*\\])))*) | | regexplib/email.js:8:89:8:174 | (?:\\.(?:(?:[^ \\t\\(\\)\\<\\>@,;\\:\\\\\\"\\.\\[\\]\\r\\n]+)\|(?:\\"(?:(?:[^\\"\\\\\\r\\n])\|(?:\\\\.))*\\")))* | Strings starting with '!' and with many repetitions of '.!' can start matching anywhere after the start of the preceeding (?<user>(?:(?:[^ \\t\\(\\)\\<\\>@,;\\:\\\\\\"\\.\\[\\]\\r\\n]+)\|(?:\\"(?:(?:[^\\"\\\\\\r\\n])\|(?:\\\\.))*\\"))(?:\\.(?:(?:[^ \\t\\(\\)\\<\\>@,;\\:\\\\\\"\\.\\[\\]\\r\\n]+)\|(?:\\"(?:(?:[^\\"\\\\\\r\\n])\|(?:\\\\.))*\\")))*)@(?<domain>(?:(?:[^ \\t\\(\\)\\<\\>@,;\\:\\\\\\"\\.\\[\\]\\r\\n]+)\|(?:\\[(?:(?:[^\\[\\]\\\\\\r\\n])\|(?:\\\\.))*\\]))(?:\\.(?:(?:[^ \\t\\(\\)\\<\\>@,;\\:\\\\\\"\\.\\[\\]\\r\\n]+)\|(?:\\[(?:(?:[^\\[\\]\\\\\\r\\n])\|(?:\\\\.))*\\])))*) | | regexplib/email.js:8:100:8:133 | [^ \\t\\(\\)\\<\\>@,;\\:\\\\\\"\\.\\[\\]\\r\\n]+ | Strings starting with '!.' and with many repetitions of '!.!' can start matching anywhere after the start of the preceeding (?<user>(?:(?:[^ \\t\\(\\)\\<\\>@,;\\:\\\\\\"\\.\\[\\]\\r\\n]+)\|(?:\\"(?:(?:[^\\"\\\\\\r\\n])\|(?:\\\\.))*\\"))(?:\\.(?:(?:[^ \\t\\(\\)\\<\\>@,;\\:\\\\\\"\\.\\[\\]\\r\\n]+)\|(?:\\"(?:(?:[^\\"\\\\\\r\\n])\|(?:\\\\.))*\\")))*)@(?<domain>(?:(?:[^ \\t\\(\\)\\<\\>@,;\\:\\\\\\"\\.\\[\\]\\r\\n]+)\|(?:\\[(?:(?:[^\\[\\]\\\\\\r\\n])\|(?:\\\\.))*\\]))(?:\\.(?:(?:[^ \\t\\(\\)\\<\\>@,;\\:\\\\\\"\\.\\[\\]\\r\\n]+)\|(?:\\[(?:(?:[^\\[\\]\\\\\\r\\n])\|(?:\\\\.))*\\])))*) | -| regexplib/email.js:8:141:8:168 | (?:(?:[^\\"\\\\\\r\\n])\|(?:\\\\.))* | Strings starting with '!."' and with many repetitions of '\\\\""."' can start matching anywhere after the start of the preceeding (?<user>(?:(?:[^ \\t\\(\\)\\<\\>@,;\\:\\\\\\"\\.\\[\\]\\r\\n]+)\|(?:\\"(?:(?:[^\\"\\\\\\r\\n])\|(?:\\\\.))*\\"))(?:\\.(?:(?:[^ \\t\\(\\)\\<\\>@,;\\:\\\\\\"\\.\\[\\]\\r\\n]+)\|(?:\\"(?:(?:[^\\"\\\\\\r\\n])\|(?:\\\\.))*\\")))*)@(?<domain>(?:(?:[^ \\t\\(\\)\\<\\>@,;\\:\\\\\\"\\.\\[\\]\\r\\n]+)\|(?:\\[(?:(?:[^\\[\\]\\\\\\r\\n])\|(?:\\\\.))*\\]))(?:\\.(?:(?:[^ \\t\\(\\)\\<\\>@,;\\:\\\\\\"\\.\\[\\]\\r\\n]+)\|(?:\\[(?:(?:[^\\[\\]\\\\\\r\\n])\|(?:\\\\.))*\\])))*) | +| regexplib/email.js:8:141:8:168 | (?:(?:[^\\"\\\\\\r\\n])\|(?:\\\\.))* | Strings starting with '!."' and with many repetitions of '".!."' can start matching anywhere after the start of the preceeding (?<user>(?:(?:[^ \\t\\(\\)\\<\\>@,;\\:\\\\\\"\\.\\[\\]\\r\\n]+)\|(?:\\"(?:(?:[^\\"\\\\\\r\\n])\|(?:\\\\.))*\\"))(?:\\.(?:(?:[^ \\t\\(\\)\\<\\>@,;\\:\\\\\\"\\.\\[\\]\\r\\n]+)\|(?:\\"(?:(?:[^\\"\\\\\\r\\n])\|(?:\\\\.))*\\")))*)@(?<domain>(?:(?:[^ \\t\\(\\)\\<\\>@,;\\:\\\\\\"\\.\\[\\]\\r\\n]+)\|(?:\\[(?:(?:[^\\[\\]\\\\\\r\\n])\|(?:\\\\.))*\\]))(?:\\.(?:(?:[^ \\t\\(\\)\\<\\>@,;\\:\\\\\\"\\.\\[\\]\\r\\n]+)\|(?:\\[(?:(?:[^\\[\\]\\\\\\r\\n])\|(?:\\\\.))*\\])))*) | | regexplib/email.js:12:2:12:4 | \\w+ | Strings with many repetitions of '0' can start matching anywhere after the start of the preceeding \\w+([-+.]\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*([,;]\\s*\\w+([-+.]\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*)* | | regexplib/email.js:12:5:12:15 | ([-+.]\\w+)* | Strings starting with '0' and with many repetitions of '+0' can start matching anywhere after the start of the preceeding \\w+([-+.]\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*([,;]\\s*\\w+([-+.]\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*)* | | regexplib/email.js:12:11:12:13 | \\w+ | Strings starting with '0+' and with many repetitions of '0+' can start matching anywhere after the start of the preceeding \\w+([-+.]\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*([,;]\\s*\\w+([-+.]\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*)* | @@ -266,7 +266,7 @@ | regexplib/markup.js:62:51:62:55 | [^<]+ | Strings starting with '<a\\thref=\\t">' and with many repetitions of '>;' can start matching anywhere after the start of the preceeding .*? | | regexplib/markup.js:62:57:62:59 | .*? | Strings starting with '<a\\thref=\\t">' and with many repetitions of '>a' can start matching anywhere after the start of the preceeding .*? | | regexplib/misc.js:4:36:4:44 | [a-zA-Z]* | Strings starting with 'A' and with many repetitions of 'AA' can start matching anywhere after the start of the preceeding [a-zA-Z]+ | -| regexplib/misc.js:76:2:76:27 | (AUX\|PRN\|NUL\|COM\\d\|LPT\\d)+ | Strings with many repetitions of 'NUL' can start matching anywhere after the start of the preceeding (AUX\|PRN\|NUL\|COM\\d\|LPT\\d)+\\s*$ | +| regexplib/misc.js:76:2:76:27 | (AUX\|PRN\|NUL\|COM\\d\|LPT\\d)+ | Strings with many repetitions of 'AUX' can start matching anywhere after the start of the preceeding (AUX\|PRN\|NUL\|COM\\d\|LPT\\d)+\\s*$ | | regexplib/misc.js:81:31:81:45 | [^a-z\\:\\,\\(\\)]* | Strings starting with '#' and with many repetitions of '#' can start matching anywhere after the start of the preceeding ([A-Zäöü0-9\\/][^a-z\\:\\,\\(\\)]*[A-Zäöü0-9])($\|[\\.\\:\\,\\;\\)\\-\\ \\+]\|s\\b) | | regexplib/misc.js:83:18:83:23 | [0-9]+ | Strings with many repetitions of '0' can start matching anywhere after the start of the preceeding \\d* | | regexplib/misc.js:83:24:83:26 | \\d* | Strings with many repetitions of '0' can start matching anywhere after the start of the preceeding \\d* | @@ -364,7 +364,7 @@ | regexplib/uri.js:3:206:3:208 | \\w+ | Strings starting with 'ftp:// 0="' and with many repetitions of '00' can start matching anywhere after the start of the preceeding .* | | regexplib/uri.js:3:211:3:213 | \\w+ | Strings starting with 'ftp:// 0="0=' and with many repetitions of '00=' can start matching anywhere after the start of the preceeding .* | | regexplib/uri.js:5:42:5:43 | .* | Strings starting with 'A:\\\\0' and with many repetitions of ' ' can start matching anywhere after the start of the preceeding [\\w ]* | -| regexplib/uri.js:14:175:14:213 | [\\d\\w\\.\\/\\%\\+\\-\\=\\&\\?\\:\\\\\\"\\'\\,\\\|\\~\\;]* | Strings with many repetitions of '.co+' can start matching anywhere after the start of the preceeding [\\d\\w\\.\\/\\+\\-\\?\\:]* | +| regexplib/uri.js:14:175:14:213 | [\\d\\w\\.\\/\\%\\+\\-\\=\\&\\?\\:\\\\\\"\\'\\,\\\|\\~\\;]* | Strings with many repetitions of '.tv+' can start matching anywhere after the start of the preceeding [\\d\\w\\.\\/\\+\\-\\?\\:]* | | regexplib/uri.js:17:42:17:43 | .* | Strings starting with 'A:\\\\0' and with many repetitions of ' ' can start matching anywhere after the start of the preceeding [\\w ]* | | regexplib/uri.js:18:4:18:46 | ([A-Za-z0-9'~`!@#$%&^_+=\\(\\){},\\-\\[\\]\\;])+? | Strings starting with 'A' and with many repetitions of 'A' can start matching anywhere after the start of the preceeding \\A([A-Za-z0-9'~`!@#$%&^_+=\\(\\){},\\-\\[\\]\\;])+?([ A-Za-z0-9'~` !@#$%&^_+=\\(\\){},\\-\\[\\];]\|([.]))*?(?(3)(([ A-Za-z0-9'~`!@#$ %&^_+=\\(\\){},\\-\\[\\]\\;]*?)([A-Za-z0-9'~`!@#$%&^_+=\\(\\){},\\-\\[ \\];])+\\z)\|(\\z)) | | regexplib/uri.js:18:47:18:96 | ([ A-Za-z0-9'~` !@#$%&^_+=\\(\\){},\\-\\[\\];]\|([.]))*? | Strings starting with 'A!' and with many repetitions of '!' can start matching anywhere after the start of the preceeding ([A-Za-z0-9'~`!@#$%&^_+=\\(\\){},\\-\\[\\]\\;])+? | 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 c29feaea831..0ec4c40fd2c 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 @@ -579,4 +579,4 @@ edges | polynomial-redos.js:130:2:130:31 | modifie ... g, "b") | polynomial-redos.js:5:16:5:32 | req.query.tainted | polynomial-redos.js:130:2:130:9 | modified | This $@ that depends on $@ may run slow on strings starting with 'c' and with many repetitions of 'c'. | polynomial-redos.js:130:21:130:22 | c+ | regular expression | polynomial-redos.js:5:16:5:32 | req.query.tainted | a user-provided value | | polynomial-redos.js:133:2:133:32 | modifie ... g, "b") | polynomial-redos.js:5:16:5:32 | req.query.tainted | polynomial-redos.js:133:2:133:10 | modified2 | This $@ that depends on $@ may run slow on strings starting with 'f' and with many repetitions of 'f'. | polynomial-redos.js:133:22:133:23 | f+ | regular expression | polynomial-redos.js:5:16:5:32 | req.query.tainted | a user-provided value | | polynomial-redos.js:136:5:136:35 | modifie ... g, "b") | polynomial-redos.js:5:16:5:32 | req.query.tainted | polynomial-redos.js:136:5:136:13 | modified3 | This $@ that depends on $@ may run slow on strings starting with 'h' and with many repetitions of 'h'. | polynomial-redos.js:136:25:136:26 | h+ | regular expression | polynomial-redos.js:5:16:5:32 | req.query.tainted | a user-provided value | -| polynomial-redos.js:138:5:138:326 | tainted ... )C.*X/) | polynomial-redos.js:5:16:5:32 | req.query.tainted | polynomial-redos.js:138:5:138:11 | tainted | This $@ that depends on $@ may run slow on strings starting with 'AAAAAAAAAAAAAAAAAAAAAABBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC' and with many repetitions of 'AAAAAAAAAAAAAAAAAAAAAABBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC'. | polynomial-redos.js:138:322:138:323 | .* | regular expression | polynomial-redos.js:5:16:5:32 | req.query.tainted | a user-provided value | +| polynomial-redos.js:138:5:138:326 | tainted ... )C.*X/) | polynomial-redos.js:5:16:5:32 | req.query.tainted | polynomial-redos.js:138:5:138:11 | tainted | This $@ that depends on $@ may run slow on strings starting with 'AAAAAAAAAAAAAAAAAAAAAABBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC' and with many repetitions of 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC'. | polynomial-redos.js:138:322:138:323 | .* | regular expression | polynomial-redos.js:5:16:5:32 | req.query.tainted | a user-provided value | diff --git a/python/ql/test/query-tests/Security/CWE-730-PolynomialReDoS/PolynomialBackTracking.expected b/python/ql/test/query-tests/Security/CWE-730-PolynomialReDoS/PolynomialBackTracking.expected index b24726bf605..1aa6d91f343 100644 --- a/python/ql/test/query-tests/Security/CWE-730-PolynomialReDoS/PolynomialBackTracking.expected +++ b/python/ql/test/query-tests/Security/CWE-730-PolynomialReDoS/PolynomialBackTracking.expected @@ -2,4 +2,4 @@ | test.py:9:14:9:29 | Str | test.py:9:27:9:29 | \\d+ | Strings starting with '0.9' and with many repetitions of '99' can start matching anywhere after the start of the preceeding \\d+ | | test.py:11:22:11:33 | Str | test.py:11:31:11:33 | \\s+ | Strings with many repetitions of ' ' can start matching anywhere after the start of the preceeding \\s+$ | | test.py:18:14:18:25 | Str | test.py:18:23:18:25 | \\s+ | Strings with many repetitions of ' ' can start matching anywhere after the start of the preceeding \\s+$ | -| test.py:20:23:20:274 | Str | test.py:20:273:20:274 | .* | Strings starting with 'AAAAAAAAAAAAAAAAAAAABBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC' and with many repetitions of 'AAAAAAAAAAAAAAAAAAAABBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC' can start matching anywhere after the start of the preceeding (AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)C.*Y | +| test.py:20:23:20:274 | Str | test.py:20:273:20:274 | .* | Strings starting with 'AAAAAAAAAAAAAAAAAAAABBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC' and with many repetitions of 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC' can start matching anywhere after the start of the preceeding (AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)C.*Y | diff --git a/python/ql/test/query-tests/Security/CWE-730-PolynomialReDoS/PolynomialReDoS.expected b/python/ql/test/query-tests/Security/CWE-730-PolynomialReDoS/PolynomialReDoS.expected index 39611f1e2af..396a7de9a84 100644 --- a/python/ql/test/query-tests/Security/CWE-730-PolynomialReDoS/PolynomialReDoS.expected +++ b/python/ql/test/query-tests/Security/CWE-730-PolynomialReDoS/PolynomialReDoS.expected @@ -29,4 +29,4 @@ subpaths | test.py:9:32:9:35 | ControlFlowNode for text | test.py:2:26:2:32 | ControlFlowNode for ImportMember | test.py:9:32:9:35 | ControlFlowNode for text | This $@ that depends on a $@ may run slow on strings starting with '0.9' and with many repetitions of '99'. | test.py:9:27:9:29 | \\d+ | regular expression | test.py:2:26:2:32 | ControlFlowNode for ImportMember | user-provided value | | test.py:12:17:12:20 | ControlFlowNode for text | test.py:2:26:2:32 | ControlFlowNode for ImportMember | test.py:12:17:12:20 | ControlFlowNode for text | This $@ that depends on a $@ may run slow on strings with many repetitions of ' '. | test.py:11:31:11:33 | \\s+ | regular expression | test.py:2:26:2:32 | ControlFlowNode for ImportMember | user-provided value | | test.py:16:24:16:30 | ControlFlowNode for my_text | test.py:2:26:2:32 | ControlFlowNode for ImportMember | test.py:16:24:16:30 | ControlFlowNode for my_text | This $@ that depends on a $@ may run slow on strings with many repetitions of ' '. | test.py:18:23:18:25 | \\s+ | regular expression | test.py:2:26:2:32 | ControlFlowNode for ImportMember | user-provided value | -| test.py:21:18:21:21 | ControlFlowNode for text | test.py:2:26:2:32 | ControlFlowNode for ImportMember | test.py:21:18:21:21 | ControlFlowNode for text | This $@ that depends on a $@ may run slow on strings starting with 'AAAAAAAAAAAAAAAAAAAABBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC' and with many repetitions of 'AAAAAAAAAAAAAAAAAAAABBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC'. | test.py:20:273:20:274 | .* | regular expression | test.py:2:26:2:32 | ControlFlowNode for ImportMember | user-provided value | +| test.py:21:18:21:21 | ControlFlowNode for text | test.py:2:26:2:32 | ControlFlowNode for ImportMember | test.py:21:18:21:21 | ControlFlowNode for text | This $@ that depends on a $@ may run slow on strings starting with 'AAAAAAAAAAAAAAAAAAAABBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC' and with many repetitions of 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC'. | test.py:20:273:20:274 | .* | regular expression | test.py:2:26:2:32 | ControlFlowNode for ImportMember | user-provided value | diff --git a/shared/regex/codeql/regex/nfa/NfaUtils.qll b/shared/regex/codeql/regex/nfa/NfaUtils.qll index 7966b4fd741..3fd4b97c829 100644 --- a/shared/regex/codeql/regex/nfa/NfaUtils.qll +++ b/shared/regex/codeql/regex/nfa/NfaUtils.qll @@ -147,6 +147,8 @@ module Make<RegexTreeViewSig TreeImpl> { /** * Gets a string for the full location of `t`. */ + bindingset[t] + pragma[inline_late] string getTermLocationString(RegExpTerm t) { exists(string file, int startLine, int startColumn, int endLine, int endColumn | t.hasLocationInfo(file, startLine, startColumn, endLine, endColumn) and diff --git a/shared/regex/codeql/regex/nfa/SuperlinearBackTracking.qll b/shared/regex/codeql/regex/nfa/SuperlinearBackTracking.qll index 659023b87cd..c5441cc4d3b 100644 --- a/shared/regex/codeql/regex/nfa/SuperlinearBackTracking.qll +++ b/shared/regex/codeql/regex/nfa/SuperlinearBackTracking.qll @@ -354,13 +354,13 @@ module Make<RegexTreeViewSig TreeImpl> { */ private int rankState(State state) { state = - rank[result](State s | - exists(StateTuple tuple | - tuple = getARelevantStateTuple(_, _) and - s = [tuple.getFirst(), tuple.getSecond(), tuple.getThird()] + rank[result](State s, int startLine, int endLine, int startColumn, int endColumn | + exists(StateTuple tuple | tuple = getARelevantStateTuple(_, _) | + s = [tuple.getFirst(), tuple.getSecond(), tuple.getThird()] and + s.getRepr().hasLocationInfo(_, startLine, startColumn, endLine, endColumn) ) | - s order by getTermLocationString(s.getRepr()) + s order by startLine, startColumn, endLine, endColumn ) } From 3f18b7730f2ef82aea0dd039964cd359dd79888a Mon Sep 17 00:00:00 2001 From: erik-krogh <erik-krogh@github.com> Date: Thu, 23 Mar 2023 10:39:56 +0100 Subject: [PATCH 330/631] address some review comments --- .../codeql/regex/nfa/SuperlinearBackTracking.qll | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/shared/regex/codeql/regex/nfa/SuperlinearBackTracking.qll b/shared/regex/codeql/regex/nfa/SuperlinearBackTracking.qll index c5441cc4d3b..d0dea9a9b6e 100644 --- a/shared/regex/codeql/regex/nfa/SuperlinearBackTracking.qll +++ b/shared/regex/codeql/regex/nfa/SuperlinearBackTracking.qll @@ -283,7 +283,7 @@ module Make<RegexTreeViewSig TreeImpl> { } /** - * Gets a tuple tuple reachable from the end state `(succ, succ, succ)` in a backwards exploratory search. + * Gets a state tuple that can reach the end state `(succ, succ, succ)`, found via a backwards exploratory search. * Where the end state was reachable from a forwards search from the start state `(pivot, pivot, pivot)`. * The resulting tuples are exactly those that are on a path from the start state to the end state. */ @@ -302,16 +302,16 @@ module Make<RegexTreeViewSig TreeImpl> { } /** - * Holds if there exists a transition from `r` to `q` in the product automaton. - * Where `r` and `q` are both on a path from a start state to an end state. + * Holds if there exists a transition from `src` to `dst` in the product automaton. + * Where `src` and `dst` are both on a path from a start state to an end state. * Notice that the arguments are flipped, and thus the direction is backwards. */ pragma[noinline] - predicate tupleDeltaBackwards(StateTuple q, StateTuple r) { - step(r, _, _, _, q) and - // `step` ensures that `r` and `q` have the same pivot and succ. - r = getARelevantStateTuple(_, _) and - q = getARelevantStateTuple(_, _) + predicate tupleDeltaBackwards(StateTuple dst, StateTuple src) { + step(src, _, _, _, dst) and + // `step` ensures that `src` and `dst` have the same pivot and succ. + src = getARelevantStateTuple(_, _) and + dst = getARelevantStateTuple(_, _) } /** From 404cbc93eb896d79fcf86ed1fb1bee05e3fc5dd5 Mon Sep 17 00:00:00 2001 From: erik-krogh <erik-krogh@github.com> Date: Thu, 23 Mar 2023 10:46:22 +0100 Subject: [PATCH 331/631] rename succ to pumpEnd throughout SuperLinearBackTracking.qll --- .../regex/nfa/SuperlinearBackTracking.qll | 142 +++++++++--------- 1 file changed, 71 insertions(+), 71 deletions(-) diff --git a/shared/regex/codeql/regex/nfa/SuperlinearBackTracking.qll b/shared/regex/codeql/regex/nfa/SuperlinearBackTracking.qll index d0dea9a9b6e..3f16431e165 100644 --- a/shared/regex/codeql/regex/nfa/SuperlinearBackTracking.qll +++ b/shared/regex/codeql/regex/nfa/SuperlinearBackTracking.qll @@ -9,16 +9,16 @@ * Theorem 3 from the paper describes the basic idea. * * The following explains the idea using variables and predicate names that are used in the implementation: - * We consider a pair of repetitions, which we will call `pivot` and `succ`. + * We consider a pair of repetitions, which we will call `pivot` and `pumpEnd`. * * We create a product automaton of 3-tuples of states (see `StateTuple`). * There exists a transition `(a,b,c) -> (d,e,f)` in the product automaton * iff there exists three transitions in the NFA `a->d, b->e, c->f` where those three * transitions all match a shared character `char`. (see `getAThreewayIntersect`) * - * We start a search in the product automaton at `(pivot, pivot, succ)`, + * We start a search in the product automaton at `(pivot, pivot, pumpEnd)`, * and search for a series of transitions (a `Trace`), such that we end - * at `(pivot, succ, succ)` (see `isReachableFromStartTuple`). + * at `(pivot, pumpEnd, pumpEnd)` (see `isReachableFromStartTuple`). * * For example, consider the regular expression `/^\d*5\w*$/`. * The search will start at the tuple `(\d*, \d*, \w*)` and search @@ -52,29 +52,29 @@ module Make<RegexTreeViewSig TreeImpl> { private newtype TStateTuple = /** - * A tuple of states `(q1, q2, q3)` in the product automaton that is reachable from `(pivot, pivot, succ)`. + * A tuple of states `(q1, q2, q3)` in the product automaton that is reachable from `(pivot, pivot, pumpEnd)`. */ - MkStateTuple(State pivot, State succ, State q1, State q2, State q3) { - // starts at (pivot, pivot, succ) + MkStateTuple(State pivot, State pumpEnd, State q1, State q2, State q3) { + // starts at (pivot, pivot, pumpEnd) isStartLoops(q1, q3) and q1 = q2 and pivot = q1 and - succ = q3 + pumpEnd = q3 or // recurse: any transition out where all 3 edges share a char (and the resulting tuple isn't obviously infeasible) exists(StateTuple prev | - prev = MkStateTuple(pivot, succ, _, _, _) and + prev = MkStateTuple(pivot, pumpEnd, _, _, _) and hasCommonStep(prev, _, _, _, q1, q2, q3) and - FeasibleTuple::isFeasibleTuple(pivot, succ, q1, q2, q3) + FeasibleTuple::isFeasibleTuple(pivot, pumpEnd, q1, q2, q3) ) } /** - * A state `(q1, q2, q3)` in the product automaton, that is reachable from `(pivot, pivot, succ)`. + * A state `(q1, q2, q3)` in the product automaton, that is reachable from `(pivot, pivot, pumpEnd)`. * * We lazily only construct those states that we are actually * going to need. - * Either a start state `(pivot, pivot, succ)`, or a state + * Either a start state `(pivot, pivot, pumpEnd)`, or a state * where there exists a transition from an already existing state. * * The exponential variant of this query (`js/redos`) uses an optimization @@ -83,12 +83,12 @@ module Make<RegexTreeViewSig TreeImpl> { */ class StateTuple extends TStateTuple { State pivot; - State succ; + State pumpEnd; State q1; State q2; State q3; - StateTuple() { this = MkStateTuple(pivot, succ, q1, q2, q3) } + StateTuple() { this = MkStateTuple(pivot, pumpEnd, q1, q2, q3) } /** * Gest a string representation of this tuple. @@ -122,9 +122,9 @@ module Make<RegexTreeViewSig TreeImpl> { State getPivot() { result = pivot } /** - * Gets the succ state. + * Gets the pumpEnd state. */ - State getSucc() { result = succ } + State getPumpEnd() { result = pumpEnd } /** * Holds if the pivot state has the specified location. @@ -142,17 +142,17 @@ module Make<RegexTreeViewSig TreeImpl> { */ private module FeasibleTuple { /** - * Holds if the tuple `(r1, r2, r3)` might be on path from a start-state `(pivot, pivot, succ)` to an end-state `(pivot, succ, succ)` in the product automaton. + * Holds if the tuple `(r1, r2, r3)` might be on path from a start-state `(pivot, pivot, pumpEnd)` to an end-state `(pivot, pumpEnd, pumpEnd)` in the product automaton. */ - bindingset[pivot, succ, r1, r2, r3] + bindingset[pivot, pumpEnd, r1, r2, r3] pragma[inline_late] - predicate isFeasibleTuple(State pivot, State succ, State r1, State r2, State r3) { - isStartLoops(pivot, succ) and + predicate isFeasibleTuple(State pivot, State pumpEnd, State r1, State r2, State r3) { + isStartLoops(pivot, pumpEnd) and // r1 can reach the pivot state reachesBeginning(r1, pivot) and - // r2 and r3 can reach the succ state - reachesEnd(r2, succ) and - reachesEnd(r3, succ) and + // r2 and r3 can reach the pumpEnd state + reachesEnd(r2, pumpEnd) and + reachesEnd(r3, pumpEnd) and // The first element is either inside a repetition (or the start state itself) isRepetitionOrStart(r1) and // The last element is inside a repetition @@ -169,9 +169,9 @@ module Make<RegexTreeViewSig TreeImpl> { } pragma[noinline] - private predicate reachesEnd(State s, State succ) { - isStartLoops(_, succ) and - delta+(s) = succ + private predicate reachesEnd(State s, State pumpEnd) { + isStartLoops(_, pumpEnd) and + delta+(s) = pumpEnd } /** @@ -192,15 +192,15 @@ module Make<RegexTreeViewSig TreeImpl> { } /** - * Holds if `pivot` and `succ` are a pair of loops that could be the beginning of a quadratic blowup. + * Holds if `pivot` and `pumpEnd` 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. + * There is a slight implementation difference compared to the paper: this predicate requires that `pivot != pumpEnd`. + * The case where `pivot = pumpEnd` 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 + predicate isStartLoops(State pivot, State pumpEnd) { + pivot != pumpEnd and + pumpEnd.getRepr() instanceof InfiniteRepetitionQuantifier and + delta+(pivot) = pumpEnd and ( pivot.getRepr() instanceof InfiniteRepetitionQuantifier or @@ -223,7 +223,7 @@ module Make<RegexTreeViewSig TreeImpl> { exists(State r1, State r2, State r3 | hasCommonStep(q, s1, s2, s3, r1, r2, r3) and r = - MkStateTuple(pragma[only_bind_out](q.getPivot()), pragma[only_bind_out](q.getSucc()), + MkStateTuple(pragma[only_bind_out](q.getPivot()), pragma[only_bind_out](q.getPumpEnd()), pragma[only_bind_out](r1), pragma[only_bind_out](r2), pragma[only_bind_out](r3)) ) } @@ -270,34 +270,34 @@ module Make<RegexTreeViewSig TreeImpl> { } /** Gets a tuple reachable in a forwards exploratory search from the start state `(pivot, pivot, pivot)`. */ - private StateTuple getReachableFromStartStateForwards(State pivot, State succ) { + private StateTuple getReachableFromStartStateForwards(State pivot, State pumpEnd) { // base case. - isStartLoops(pivot, succ) and - result = MkStateTuple(pivot, succ, pivot, pivot, succ) + isStartLoops(pivot, pumpEnd) and + result = MkStateTuple(pivot, pumpEnd, pivot, pivot, pumpEnd) or // recursive case exists(StateTuple p | - p = getReachableFromStartStateForwards(pivot, succ) and + p = getReachableFromStartStateForwards(pivot, pumpEnd) and step(p, _, _, _, result) ) } /** - * Gets a state tuple that can reach the end state `(succ, succ, succ)`, found via a backwards exploratory search. - * Where the end state was reachable from a forwards search from the start state `(pivot, pivot, pivot)`. + * Gets a state tuple that can reach the end state `(pivot, pumpEnd, pumpEnd)`, found via a backwards exploratory search. + * Where the end state was reachable from a forwards search from the start state `(pivot, pivot, pumpEnd)`. * The resulting tuples are exactly those that are on a path from the start state to the end state. */ - private StateTuple getARelevantStateTuple(State pivot, State succ) { + private StateTuple getARelevantStateTuple(State pivot, State pumpEnd) { // base case. - isStartLoops(pivot, succ) and - result = MkStateTuple(pivot, succ, pivot, succ, succ) and - result = getReachableFromStartStateForwards(pivot, succ) + isStartLoops(pivot, pumpEnd) and + result = MkStateTuple(pivot, pumpEnd, pivot, pumpEnd, pumpEnd) and + result = getReachableFromStartStateForwards(pivot, pumpEnd) or // recursive case exists(StateTuple p | - p = getARelevantStateTuple(pivot, succ) and + p = getARelevantStateTuple(pivot, pumpEnd) and step(result, _, _, _, p) and - pragma[only_bind_out](result) = getReachableFromStartStateForwards(pivot, succ) // was reachable in the forwards pass. + pragma[only_bind_out](result) = getReachableFromStartStateForwards(pivot, pumpEnd) // was reachable in the forwards pass. ) } @@ -309,14 +309,14 @@ module Make<RegexTreeViewSig TreeImpl> { pragma[noinline] predicate tupleDeltaBackwards(StateTuple dst, StateTuple src) { step(src, _, _, _, dst) and - // `step` ensures that `src` and `dst` have the same pivot and succ. + // `step` ensures that `src` and `dst` have the same pivot and pumpEnd. src = getARelevantStateTuple(_, _) and dst = getARelevantStateTuple(_, _) } /** * Holds if `tuple` is an end state in our search, and `tuple` is on a path from a start state to an end state. - * That means there exists a pair of loops `(pivot, succ)` such that `tuple = (pivot, succ, succ)`. + * That means there exists a pair of loops `(pivot, pumpEnd)` such that `tuple = (pivot, pumpEnd, pumpEnd)`. */ predicate isEndTuple(StateTuple tuple) { tuple = getEndTuple(_, _) and @@ -341,8 +341,8 @@ module Make<RegexTreeViewSig TreeImpl> { StateTuple q, InputSymbol s1, InputSymbol s2, InputSymbol s3, StateTuple r ) { step(q, s1, s2, s3, r) and - exists(State pivot, State succ, StateTuple end | - end = MkStateTuple(pivot, succ, pivot, succ, succ) and + exists(State pivot, State pumpEnd, StateTuple end | + end = MkStateTuple(pivot, pumpEnd, pivot, pumpEnd, pumpEnd) and pragma[only_bind_out](distBackFromEnd(q, end)) = pragma[only_bind_out](distBackFromEnd(r, end)) + 1 ) @@ -385,15 +385,15 @@ module Make<RegexTreeViewSig TreeImpl> { } private newtype TTrace = - Nil(State pivot, State succ) { - isStartLoops(pivot, succ) and - getStartTuple(pivot, succ) = getARelevantStateTuple(pivot, succ) + Nil(State pivot, State pumpEnd) { + isStartLoops(pivot, pumpEnd) and + getStartTuple(pivot, pumpEnd) = getARelevantStateTuple(pivot, pumpEnd) } or Step(TTrace prev, StateTuple nextTuple) { exists(StateTuple prevTuple | - exists(State pivot, State succ | - prev = Nil(pivot, succ) and - prevTuple = getStartTuple(pivot, succ) + exists(State pivot, State pumpEnd | + prev = Nil(pivot, pumpEnd) and + prevTuple = getStartTuple(pivot, pumpEnd) ) or prev = Step(_, prevTuple) @@ -404,7 +404,7 @@ module Make<RegexTreeViewSig TreeImpl> { /** * A list of tuples of input symbols that describe a path in the product automaton - * starting from a start state `(pivot, pivot, succ)`. + * starting from a start state `(pivot, pivot, pumpEnd)`. */ class Trace extends TTrace { /** @@ -419,27 +419,27 @@ module Make<RegexTreeViewSig TreeImpl> { StateTuple getTuple() { this = Step(_, result) or - exists(State prev, State succ | - this = Nil(prev, succ) and - result = getStartTuple(prev, succ) + exists(State prev, State pumpEnd | + this = Nil(prev, pumpEnd) and + result = getStartTuple(prev, pumpEnd) ) } } /** - * Gets the tuple `(pivot, succ, succ)` from the product automaton. + * Gets the tuple `(pivot, pumpEnd, pumpEnd)` from the product automaton. */ - StateTuple getEndTuple(State pivot, State succ) { - isStartLoops(pivot, succ) and - result = MkStateTuple(pivot, succ, pivot, succ, succ) + StateTuple getEndTuple(State pivot, State pumpEnd) { + isStartLoops(pivot, pumpEnd) and + result = MkStateTuple(pivot, pumpEnd, pivot, pumpEnd, pumpEnd) } /** - * Gets the tuple `(pivot, pivot, succ)` from the product automaton. + * Gets the tuple `(pivot, pivot, pumpEnd)` from the product automaton. */ - StateTuple getStartTuple(State pivot, State succ) { - isStartLoops(pivot, succ) and - result = MkStateTuple(pivot, succ, pivot, pivot, succ) + StateTuple getStartTuple(State pivot, State pumpEnd) { + isStartLoops(pivot, pumpEnd) and + result = MkStateTuple(pivot, pumpEnd, pivot, pivot, pumpEnd) } /** An implementation of a chain containing chars for use by `Concretizer`. */ @@ -464,8 +464,8 @@ module Make<RegexTreeViewSig TreeImpl> { /** * 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`. + * 2) Transition from `pivot` to `pumpEnd`. + * 3) Transition from `pumpEnd` to `pumpEnd`. * * 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. @@ -473,9 +473,9 @@ module Make<RegexTreeViewSig TreeImpl> { * This predicate is used by `SuperLinearReDoSConfiguration`, and the final results are * available in the `hasReDoSResult` predicate. */ - predicate isPumpable(State pivot, State succ, string pump) { + predicate isPumpable(State pivot, State pumpEnd, string pump) { exists(StateTuple q, Trace t | - q = getEndTuple(pivot, succ) and + q = getEndTuple(pivot, pumpEnd) and q = t.getTuple() and pump = Concretizer<CharTreeImpl>::concretize(t) ) From 879dea29842bd0d37b2c0bd665d6a04116507c85 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Thu, 23 Mar 2023 10:32:02 +0000 Subject: [PATCH 332/631] Swift: Additional test cases. --- .../CWE-135/StringLengthConflation.expected | 12 ++++++++++++ .../CWE-135/StringLengthConflation.swift | 18 ++++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/swift/ql/test/query-tests/Security/CWE-135/StringLengthConflation.expected b/swift/ql/test/query-tests/Security/CWE-135/StringLengthConflation.expected index b8983944811..539b3796874 100644 --- a/swift/ql/test/query-tests/Security/CWE-135/StringLengthConflation.expected +++ b/swift/ql/test/query-tests/Security/CWE-135/StringLengthConflation.expected @@ -73,6 +73,12 @@ nodes | StringLengthConflation.swift:138:36:138:46 | ... .-(_:_:) ... | semmle.label | ... .-(_:_:) ... | | StringLengthConflation.swift:144:28:144:30 | .count : | semmle.label | .count : | | StringLengthConflation.swift:144:28:144:38 | ... .-(_:_:) ... | semmle.label | ... .-(_:_:) ... | +| StringLengthConflation.swift:151:45:151:53 | .count | semmle.label | .count | +| StringLengthConflation.swift:152:57:152:65 | .count | semmle.label | .count | +| StringLengthConflation.swift:156:45:156:52 | .count | semmle.label | .count | +| StringLengthConflation.swift:157:55:157:62 | .count | semmle.label | .count | +| StringLengthConflation.swift:161:45:161:53 | .count | semmle.label | .count | +| StringLengthConflation.swift:162:57:162:65 | .count | semmle.label | .count | | file://:0:0:0:0 | .length : | semmle.label | .length : | subpaths #select @@ -111,3 +117,9 @@ subpaths | StringLengthConflation.swift:137:34:137:44 | ... .-(_:_:) ... | StringLengthConflation.swift:137:34:137:36 | .count : | StringLengthConflation.swift:137:34:137:44 | ... .-(_:_:) ... | This String length is used in an NSString, but it may not be equivalent. | | StringLengthConflation.swift:138:36:138:46 | ... .-(_:_:) ... | StringLengthConflation.swift:138:36:138:38 | .count : | StringLengthConflation.swift:138:36:138:46 | ... .-(_:_:) ... | This String length is used in an NSString, but it may not be equivalent. | | StringLengthConflation.swift:144:28:144:38 | ... .-(_:_:) ... | StringLengthConflation.swift:144:28:144:30 | .count : | StringLengthConflation.swift:144:28:144:38 | ... .-(_:_:) ... | This String length is used in an NSString, but it may not be equivalent. | +| StringLengthConflation.swift:151:45:151:53 | .count | StringLengthConflation.swift:151:45:151:53 | .count | StringLengthConflation.swift:151:45:151:53 | .count | This String.unicodeScalars length is used in a String, but it may not be equivalent. | +| StringLengthConflation.swift:152:57:152:65 | .count | StringLengthConflation.swift:152:57:152:65 | .count | StringLengthConflation.swift:152:57:152:65 | .count | This String.unicodeScalars length is used in a String, but it may not be equivalent. | +| StringLengthConflation.swift:156:45:156:52 | .count | StringLengthConflation.swift:156:45:156:52 | .count | StringLengthConflation.swift:156:45:156:52 | .count | This String.utf8 length is used in a String, but it may not be equivalent. | +| StringLengthConflation.swift:157:55:157:62 | .count | StringLengthConflation.swift:157:55:157:62 | .count | StringLengthConflation.swift:157:55:157:62 | .count | This String.utf8 length is used in a String, but it may not be equivalent. | +| StringLengthConflation.swift:161:45:161:53 | .count | StringLengthConflation.swift:161:45:161:53 | .count | StringLengthConflation.swift:161:45:161:53 | .count | This String.utf16 length is used in a String, but it may not be equivalent. | +| StringLengthConflation.swift:162:57:162:65 | .count | StringLengthConflation.swift:162:57:162:65 | .count | StringLengthConflation.swift:162:57:162:65 | .count | This String.unicodeScalars length is used in a String, but it may not be equivalent. | diff --git a/swift/ql/test/query-tests/Security/CWE-135/StringLengthConflation.swift b/swift/ql/test/query-tests/Security/CWE-135/StringLengthConflation.swift index 7eac5d6299d..abea44b0e93 100644 --- a/swift/ql/test/query-tests/Security/CWE-135/StringLengthConflation.swift +++ b/swift/ql/test/query-tests/Security/CWE-135/StringLengthConflation.swift @@ -143,6 +143,24 @@ func test(s: String) { let nmstr8 = NSMutableString(string: s) nmstr8.insert("*", at: s.count - 1) // BAD: String length used in NSString print("insert '\(nmstr7)' / '\(nmstr8)'") + + // --- inspired by real world cases --- + + let scalars = s.unicodeScalars + let _ = s.index(s.startIndex, offsetBy: s.count) // GOOD + let _ = s.index(s.startIndex, offsetBy: scalars.count) // BAD + let _ = scalars.index(scalars.startIndex, offsetBy: scalars.count) // GOOD [FALSE POSITIVE] + let _ = scalars.index(scalars.startIndex, offsetBy: s.count) // BAD [NOT DETECTED] + + let s_utf8 = s.utf8 + let _ = s.index(s.startIndex, offsetBy: s_utf8.count) // BAD + let _ = s_utf8.index(s_utf8.startIndex, offsetBy: s_utf8.count) // GOOD [FALSE POSITIVE] + let _ = s_utf8.index(s_utf8.startIndex, offsetBy: s.count) // BAD [NOT DETECTED] + + let s_utf16 = s.utf16 + let _ = s.index(s.startIndex, offsetBy: s_utf16.count) // BAD + let _ = s_utf16.index(s_utf16.startIndex, offsetBy: scalars.count) // GOOD [FALSE POSITIVE] + let _ = s_utf16.index(s_utf16.startIndex, offsetBy: s.count) // BAD [NOT DETECTED] } // `begin :thumbsup: end`, with thumbs up emoji and skin tone modifier From dfcad7fa84df6d8eef7729a0c17f60dd5c063957 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Mon, 20 Mar 2023 16:08:03 +0000 Subject: [PATCH 333/631] Swift: Split the query into the usual three files. --- .../StringLengthConflationExtensions.qll | 40 +++++ .../security/StringLengthConflationQuery.qll | 141 +++++++++++++++ .../CWE-135/StringLengthConflation.ql | 167 +----------------- 3 files changed, 182 insertions(+), 166 deletions(-) create mode 100644 swift/ql/lib/codeql/swift/security/StringLengthConflationExtensions.qll create mode 100644 swift/ql/lib/codeql/swift/security/StringLengthConflationQuery.qll diff --git a/swift/ql/lib/codeql/swift/security/StringLengthConflationExtensions.qll b/swift/ql/lib/codeql/swift/security/StringLengthConflationExtensions.qll new file mode 100644 index 00000000000..a35f99d2a85 --- /dev/null +++ b/swift/ql/lib/codeql/swift/security/StringLengthConflationExtensions.qll @@ -0,0 +1,40 @@ +/** + * Provides classes and predicates for reasoning about string length + * conflation vulnerabilities. + */ + +import swift +import codeql.swift.dataflow.DataFlow + +/** + * A flow state for encoding types of Swift string encoding. + */ +class StringLengthConflationFlowState extends string { + string equivClass; + string singular; + + StringLengthConflationFlowState() { + this = "String" and singular = "a String" and equivClass = "String" + or + this = "NSString" and singular = "an NSString" and equivClass = "NSString" + or + this = "String.utf8" and singular = "a String.utf8" and equivClass = "String.utf8" + or + this = "String.utf16" and singular = "a String.utf16" and equivClass = "NSString" + or + this = "String.unicodeScalars" and + singular = "a String.unicodeScalars" and + equivClass = "String.unicodeScalars" + } + + /** + * Gets the equivalence class for this flow state. If these are equal, + * they should be treated as equivalent. + */ + string getEquivClass() { result = equivClass } + + /** + * Gets text for the singular form of this flow state. + */ + string getSingular() { result = singular } +} diff --git a/swift/ql/lib/codeql/swift/security/StringLengthConflationQuery.qll b/swift/ql/lib/codeql/swift/security/StringLengthConflationQuery.qll new file mode 100644 index 00000000000..47dd3555022 --- /dev/null +++ b/swift/ql/lib/codeql/swift/security/StringLengthConflationQuery.qll @@ -0,0 +1,141 @@ +/** + * Provides a taint-tracking configuration for reasoning about string length + * conflation vulnerabilities. + */ + +import swift +import codeql.swift.dataflow.DataFlow +import codeql.swift.dataflow.TaintTracking +import codeql.swift.security.StringLengthConflationExtensions + +/** + * A configuration for tracking string lengths originating from source that is + * a `String` or an `NSString` object, to a sink of a different kind that + * expects an incompatible measure of length. + */ +class StringLengthConflationConfiguration extends TaintTracking::Configuration { + StringLengthConflationConfiguration() { this = "StringLengthConflationConfiguration" } + + override predicate isSource(DataFlow::Node node, string flowstate) { + exists(MemberRefExpr memberRef, string className, string varName | + memberRef.getBase().getType().(NominalType).getABaseType*().getName() = className and + memberRef.getMember().(VarDecl).getName() = varName and + node.asExpr() = memberRef and + ( + // result of a call to `String.count` + className = "String" and + varName = "count" and + flowstate = "String" + or + // result of a call to `NSString.length` + className = ["NSString", "NSMutableString"] and + varName = "length" and + flowstate = "NSString" + or + // result of a call to `String.utf8.count` + className = "String.UTF8View" and + varName = "count" and + flowstate = "String.utf8" + or + // result of a call to `String.utf16.count` + className = "String.UTF16View" and + varName = "count" and + flowstate = "String.utf16" + or + // result of a call to `String.unicodeScalars.count` + className = "String.UnicodeScalarView" and + varName = "count" and + flowstate = "String.unicodeScalars" + ) + ) + } + + /** + * Holds if `node` is a sink and `flowstate` is the *correct* flow state for + * that sink. We actually want to report incorrect flow states. + */ + predicate isSinkImpl(DataFlow::Node node, string flowstate) { + exists(AbstractFunctionDecl funcDecl, CallExpr call, string funcName, int arg | + ( + // arguments to method calls... + exists(string className, ClassOrStructDecl c | + ( + // `NSRange.init` + className = "NSRange" and + funcName = "init(location:length:)" and + arg = [0, 1] + or + // `NSString.character` + className = ["NSString", "NSMutableString"] and + funcName = "character(at:)" and + arg = 0 + or + // `NSString.character` + className = ["NSString", "NSMutableString"] and + funcName = "substring(from:)" and + arg = 0 + or + // `NSString.character` + className = ["NSString", "NSMutableString"] and + funcName = "substring(to:)" and + arg = 0 + or + // `NSMutableString.insert` + className = "NSMutableString" and + funcName = "insert(_:at:)" and + arg = 1 + ) and + c.getName() = className and + c.getABaseTypeDecl*().(ClassOrStructDecl).getAMember() = funcDecl and + call.getStaticTarget() = funcDecl and + flowstate = "NSString" + ) + or + // arguments to function calls... + // `NSMakeRange` + funcName = "NSMakeRange(_:_:)" and + arg = [0, 1] and + call.getStaticTarget() = funcDecl and + flowstate = "NSString" + or + // arguments to method calls... + ( + // `String.dropFirst`, `String.dropLast`, `String.removeFirst`, `String.removeLast` + funcName = ["dropFirst(_:)", "dropLast(_:)", "removeFirst(_:)", "removeLast(_:)"] and + arg = 0 + or + // `String.prefix`, `String.suffix` + funcName = ["prefix(_:)", "suffix(_:)"] and + arg = 0 + or + // `String.Index.init` + funcName = "init(encodedOffset:)" and + arg = 0 + or + // `String.index` + funcName = ["index(_:offsetBy:)", "index(_:offsetBy:limitBy:)"] and + arg = [0, 1] + or + // `String.formIndex` + funcName = ["formIndex(_:offsetBy:)", "formIndex(_:offsetBy:limitBy:)"] and + arg = [0, 1] + ) and + call.getStaticTarget() = funcDecl and + flowstate = "String" + ) and + // match up `funcName`, `arg`, `node`. + funcDecl.getName() = funcName and + call.getArgument(arg).getExpr() = node.asExpr() + ) + } + + override predicate isSink(DataFlow::Node node, string flowstate) { + // Permit any *incorrect* flowstate, as those are the results the query + // should report. + exists(string correctFlowState | + isSinkImpl(node, correctFlowState) and + flowstate.(StringLengthConflationFlowState).getEquivClass() != + correctFlowState.(StringLengthConflationFlowState).getEquivClass() + ) + } +} diff --git a/swift/ql/src/queries/Security/CWE-135/StringLengthConflation.ql b/swift/ql/src/queries/Security/CWE-135/StringLengthConflation.ql index 70446bf61f2..4e5f5d20307 100644 --- a/swift/ql/src/queries/Security/CWE-135/StringLengthConflation.ql +++ b/swift/ql/src/queries/Security/CWE-135/StringLengthConflation.ql @@ -12,174 +12,9 @@ import swift import codeql.swift.dataflow.DataFlow -import codeql.swift.dataflow.TaintTracking +import codeql.swift.security.StringLengthConflationQuery import DataFlow::PathGraph -/** - * A flow state for this query, which is a type of Swift string encoding. - */ -class StringLengthConflationFlowState extends string { - string equivClass; - string singular; - - StringLengthConflationFlowState() { - this = "String" and singular = "a String" and equivClass = "String" - or - this = "NSString" and singular = "an NSString" and equivClass = "NSString" - or - this = "String.utf8" and singular = "a String.utf8" and equivClass = "String.utf8" - or - this = "String.utf16" and singular = "a String.utf16" and equivClass = "NSString" - or - this = "String.unicodeScalars" and - singular = "a String.unicodeScalars" and - equivClass = "String.unicodeScalars" - } - - /** - * Gets the equivalence class for this flow state. If these are equal, - * they should be treated as equivalent. - */ - string getEquivClass() { result = equivClass } - - /** - * Gets text for the singular form of this flow state. - */ - string getSingular() { result = singular } -} - -/** - * A configuration for tracking string lengths originating from source that is - * a `String` or an `NSString` object, to a sink of a different kind that - * expects an incompatible measure of length. - */ -class StringLengthConflationConfiguration extends TaintTracking::Configuration { - StringLengthConflationConfiguration() { this = "StringLengthConflationConfiguration" } - - override predicate isSource(DataFlow::Node node, string flowstate) { - exists(MemberRefExpr memberRef, string className, string varName | - memberRef.getBase().getType().(NominalType).getABaseType*().getName() = className and - memberRef.getMember().(VarDecl).getName() = varName and - node.asExpr() = memberRef and - ( - // result of a call to `String.count` - className = "String" and - varName = "count" and - flowstate = "String" - or - // result of a call to `NSString.length` - className = ["NSString", "NSMutableString"] and - varName = "length" and - flowstate = "NSString" - or - // result of a call to `String.utf8.count` - className = "String.UTF8View" and - varName = "count" and - flowstate = "String.utf8" - or - // result of a call to `String.utf16.count` - className = "String.UTF16View" and - varName = "count" and - flowstate = "String.utf16" - or - // result of a call to `String.unicodeScalars.count` - className = "String.UnicodeScalarView" and - varName = "count" and - flowstate = "String.unicodeScalars" - ) - ) - } - - /** - * Holds if `node` is a sink and `flowstate` is the *correct* flow state for - * that sink. We actually want to report incorrect flow states. - */ - predicate isSinkImpl(DataFlow::Node node, string flowstate) { - exists(AbstractFunctionDecl funcDecl, CallExpr call, string funcName, int arg | - ( - // arguments to method calls... - exists(string className, ClassOrStructDecl c | - ( - // `NSRange.init` - className = "NSRange" and - funcName = "init(location:length:)" and - arg = [0, 1] - or - // `NSString.character` - className = ["NSString", "NSMutableString"] and - funcName = "character(at:)" and - arg = 0 - or - // `NSString.character` - className = ["NSString", "NSMutableString"] and - funcName = "substring(from:)" and - arg = 0 - or - // `NSString.character` - className = ["NSString", "NSMutableString"] and - funcName = "substring(to:)" and - arg = 0 - or - // `NSMutableString.insert` - className = "NSMutableString" and - funcName = "insert(_:at:)" and - arg = 1 - ) and - c.getName() = className and - c.getABaseTypeDecl*().(ClassOrStructDecl).getAMember() = funcDecl and - call.getStaticTarget() = funcDecl and - flowstate = "NSString" - ) - or - // arguments to function calls... - // `NSMakeRange` - funcName = "NSMakeRange(_:_:)" and - arg = [0, 1] and - call.getStaticTarget() = funcDecl and - flowstate = "NSString" - or - // arguments to method calls... - ( - // `String.dropFirst`, `String.dropLast`, `String.removeFirst`, `String.removeLast` - funcName = ["dropFirst(_:)", "dropLast(_:)", "removeFirst(_:)", "removeLast(_:)"] and - arg = 0 - or - // `String.prefix`, `String.suffix` - funcName = ["prefix(_:)", "suffix(_:)"] and - arg = 0 - or - // `String.Index.init` - funcName = "init(encodedOffset:)" and - arg = 0 - or - // `String.index` - funcName = ["index(_:offsetBy:)", "index(_:offsetBy:limitBy:)"] and - arg = [0, 1] - or - // `String.formIndex` - funcName = ["formIndex(_:offsetBy:)", "formIndex(_:offsetBy:limitBy:)"] and - arg = [0, 1] - ) and - call.getStaticTarget() = funcDecl and - flowstate = "String" - ) and - // match up `funcName`, `arg`, `node`. - funcDecl.getName() = funcName and - call.getArgument(arg).getExpr() = node.asExpr() - ) - } - - override predicate isSink(DataFlow::Node node, string flowstate) { - // Permit any *incorrect* flowstate, as those are the results the query - // should report. - exists(string correctFlowState | - isSinkImpl(node, correctFlowState) and - flowstate.(StringLengthConflationFlowState).getEquivClass() != - correctFlowState.(StringLengthConflationFlowState).getEquivClass() - ) - } -} - from StringLengthConflationConfiguration config, DataFlow::PathNode source, DataFlow::PathNode sink, StringLengthConflationFlowState sourceFlowState, StringLengthConflationFlowState sinkFlowstate, From 4c0d02a87d23e56f206f480c64d33489ab5d50f7 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Mon, 20 Mar 2023 16:54:00 +0000 Subject: [PATCH 334/631] Swift: Standardize the sources, sinks etc. --- .../StringLengthConflationExtensions.qll | 165 +++++++++++++++++- .../security/StringLengthConflationQuery.qll | 124 ++----------- .../CWE-135/StringLengthConflation.ql | 9 +- 3 files changed, 176 insertions(+), 122 deletions(-) diff --git a/swift/ql/lib/codeql/swift/security/StringLengthConflationExtensions.qll b/swift/ql/lib/codeql/swift/security/StringLengthConflationExtensions.qll index a35f99d2a85..bd416392e62 100644 --- a/swift/ql/lib/codeql/swift/security/StringLengthConflationExtensions.qll +++ b/swift/ql/lib/codeql/swift/security/StringLengthConflationExtensions.qll @@ -7,13 +7,14 @@ import swift import codeql.swift.dataflow.DataFlow /** - * A flow state for encoding types of Swift string encoding. + * A type of Swift string encoding. This class is used as a flow state for + * the string length conflation taint tracking configuration. */ -class StringLengthConflationFlowState extends string { - string equivClass; +class StringType extends string { string singular; + string equivClass; - StringLengthConflationFlowState() { + StringType() { this = "String" and singular = "a String" and equivClass = "String" or this = "NSString" and singular = "an NSString" and equivClass = "NSString" @@ -38,3 +39,159 @@ class StringLengthConflationFlowState extends string { */ string getSingular() { result = singular } } + +/** + * A dataflow source for string length conflation vulnerabilities. That is, + * a `DataFlow::Node` where a string length is generated. + */ +abstract class StringLengthConflationSource extends DataFlow::Node { + /** + * Gets the `StringType` for this source. + */ + abstract StringType getStringType(); +} + +/** + * A dataflow sink for string length conflation vulnerabilities. That is, + * a `DataFlow::Node` where a string length is used. + */ +abstract class StringLengthConflationSink extends DataFlow::Node { + /** + * Gets the correct `StringType` for this sink. + */ + abstract StringType getCorrectStringType(); +} + +abstract class StringLengthConflationSanitizer extends DataFlow::Node { } + +/** + * A unit class for adding additional taint steps. + */ +class StringLengthConflationAdditionalTaintStep extends Unit { + /** + * Holds if the step from `node1` to `node2` should be considered a taint + * step for paths related to string length conflation vulnerabilities. + */ + abstract predicate step(DataFlow::Node nodeFrom, DataFlow::Node nodeTo); +} + +private class DefaultStringLengthConflationSource extends StringLengthConflationSource { + StringType stringType; + + DefaultStringLengthConflationSource() { + exists(MemberRefExpr memberRef, string className, string varName | + memberRef.getBase().getType().(NominalType).getABaseType*().getName() = className and + memberRef.getMember().(VarDecl).getName() = varName and + this.asExpr() = memberRef and + ( + // result of a call to `String.count` + className = "String" and + varName = "count" and + stringType = "String" + or + // result of a call to `NSString.length` + className = ["NSString", "NSMutableString"] and + varName = "length" and + stringType = "NSString" + or + // result of a call to `String.utf8.count` + className = "String.UTF8View" and + varName = "count" and + stringType = "String.utf8" + or + // result of a call to `String.utf16.count` + className = "String.UTF16View" and + varName = "count" and + stringType = "String.utf16" + or + // result of a call to `String.unicodeScalars.count` + className = "String.UnicodeScalarView" and + varName = "count" and + stringType = "String.unicodeScalars" + ) + ) + } + + override StringType getStringType() { result = stringType } +} + +private class DefaultStringLengthConflationSink extends StringLengthConflationSink { + StringType correctStringType; + + DefaultStringLengthConflationSink() { + exists(AbstractFunctionDecl funcDecl, CallExpr call, string funcName, int arg | + ( + // arguments to method calls... + exists(string className, ClassOrStructDecl c | + ( + // `NSRange.init` + className = "NSRange" and + funcName = "init(location:length:)" and + arg = [0, 1] + or + // `NSString.character` + className = ["NSString", "NSMutableString"] and + funcName = "character(at:)" and + arg = 0 + or + // `NSString.character` + className = ["NSString", "NSMutableString"] and + funcName = "substring(from:)" and + arg = 0 + or + // `NSString.character` + className = ["NSString", "NSMutableString"] and + funcName = "substring(to:)" and + arg = 0 + or + // `NSMutableString.insert` + className = "NSMutableString" and + funcName = "insert(_:at:)" and + arg = 1 + ) and + c.getName() = className and + c.getABaseTypeDecl*().(ClassOrStructDecl).getAMember() = funcDecl and + call.getStaticTarget() = funcDecl and + correctStringType = "NSString" + ) + or + // arguments to function calls... + // `NSMakeRange` + funcName = "NSMakeRange(_:_:)" and + arg = [0, 1] and + call.getStaticTarget() = funcDecl and + correctStringType = "NSString" + or + // arguments to method calls... + ( + // `String.dropFirst`, `String.dropLast`, `String.removeFirst`, `String.removeLast` + funcName = ["dropFirst(_:)", "dropLast(_:)", "removeFirst(_:)", "removeLast(_:)"] and + arg = 0 + or + // `String.prefix`, `String.suffix` + funcName = ["prefix(_:)", "suffix(_:)"] and + arg = 0 + or + // `String.Index.init` + funcName = "init(encodedOffset:)" and + arg = 0 + or + // `String.index` + funcName = ["index(_:offsetBy:)", "index(_:offsetBy:limitBy:)"] and + arg = [0, 1] + or + // `String.formIndex` + funcName = ["formIndex(_:offsetBy:)", "formIndex(_:offsetBy:limitBy:)"] and + arg = [0, 1] + ) and + call.getStaticTarget() = funcDecl and + correctStringType = "String" + ) and + // match up `funcName`, `arg`, `node`. + funcDecl.getName() = funcName and + call.getArgument(arg).getExpr() = this.asExpr() + ) + } + + override StringType getCorrectStringType() { result = correctStringType } +} diff --git a/swift/ql/lib/codeql/swift/security/StringLengthConflationQuery.qll b/swift/ql/lib/codeql/swift/security/StringLengthConflationQuery.qll index 47dd3555022..79de491af2b 100644 --- a/swift/ql/lib/codeql/swift/security/StringLengthConflationQuery.qll +++ b/swift/ql/lib/codeql/swift/security/StringLengthConflationQuery.qll @@ -17,125 +17,23 @@ class StringLengthConflationConfiguration extends TaintTracking::Configuration { StringLengthConflationConfiguration() { this = "StringLengthConflationConfiguration" } override predicate isSource(DataFlow::Node node, string flowstate) { - exists(MemberRefExpr memberRef, string className, string varName | - memberRef.getBase().getType().(NominalType).getABaseType*().getName() = className and - memberRef.getMember().(VarDecl).getName() = varName and - node.asExpr() = memberRef and - ( - // result of a call to `String.count` - className = "String" and - varName = "count" and - flowstate = "String" - or - // result of a call to `NSString.length` - className = ["NSString", "NSMutableString"] and - varName = "length" and - flowstate = "NSString" - or - // result of a call to `String.utf8.count` - className = "String.UTF8View" and - varName = "count" and - flowstate = "String.utf8" - or - // result of a call to `String.utf16.count` - className = "String.UTF16View" and - varName = "count" and - flowstate = "String.utf16" - or - // result of a call to `String.unicodeScalars.count` - className = "String.UnicodeScalarView" and - varName = "count" and - flowstate = "String.unicodeScalars" - ) - ) - } - - /** - * Holds if `node` is a sink and `flowstate` is the *correct* flow state for - * that sink. We actually want to report incorrect flow states. - */ - predicate isSinkImpl(DataFlow::Node node, string flowstate) { - exists(AbstractFunctionDecl funcDecl, CallExpr call, string funcName, int arg | - ( - // arguments to method calls... - exists(string className, ClassOrStructDecl c | - ( - // `NSRange.init` - className = "NSRange" and - funcName = "init(location:length:)" and - arg = [0, 1] - or - // `NSString.character` - className = ["NSString", "NSMutableString"] and - funcName = "character(at:)" and - arg = 0 - or - // `NSString.character` - className = ["NSString", "NSMutableString"] and - funcName = "substring(from:)" and - arg = 0 - or - // `NSString.character` - className = ["NSString", "NSMutableString"] and - funcName = "substring(to:)" and - arg = 0 - or - // `NSMutableString.insert` - className = "NSMutableString" and - funcName = "insert(_:at:)" and - arg = 1 - ) and - c.getName() = className and - c.getABaseTypeDecl*().(ClassOrStructDecl).getAMember() = funcDecl and - call.getStaticTarget() = funcDecl and - flowstate = "NSString" - ) - or - // arguments to function calls... - // `NSMakeRange` - funcName = "NSMakeRange(_:_:)" and - arg = [0, 1] and - call.getStaticTarget() = funcDecl and - flowstate = "NSString" - or - // arguments to method calls... - ( - // `String.dropFirst`, `String.dropLast`, `String.removeFirst`, `String.removeLast` - funcName = ["dropFirst(_:)", "dropLast(_:)", "removeFirst(_:)", "removeLast(_:)"] and - arg = 0 - or - // `String.prefix`, `String.suffix` - funcName = ["prefix(_:)", "suffix(_:)"] and - arg = 0 - or - // `String.Index.init` - funcName = "init(encodedOffset:)" and - arg = 0 - or - // `String.index` - funcName = ["index(_:offsetBy:)", "index(_:offsetBy:limitBy:)"] and - arg = [0, 1] - or - // `String.formIndex` - funcName = ["formIndex(_:offsetBy:)", "formIndex(_:offsetBy:limitBy:)"] and - arg = [0, 1] - ) and - call.getStaticTarget() = funcDecl and - flowstate = "String" - ) and - // match up `funcName`, `arg`, `node`. - funcDecl.getName() = funcName and - call.getArgument(arg).getExpr() = node.asExpr() - ) + flowstate = node.(StringLengthConflationSource).getStringType() } override predicate isSink(DataFlow::Node node, string flowstate) { // Permit any *incorrect* flowstate, as those are the results the query // should report. exists(string correctFlowState | - isSinkImpl(node, correctFlowState) and - flowstate.(StringLengthConflationFlowState).getEquivClass() != - correctFlowState.(StringLengthConflationFlowState).getEquivClass() + correctFlowState = node.(StringLengthConflationSink).getCorrectStringType() and + flowstate.(StringType).getEquivClass() != correctFlowState.(StringType).getEquivClass() ) } + + override predicate isSanitizer(DataFlow::Node sanitizer) { + sanitizer instanceof StringLengthConflationSanitizer + } + + override predicate isAdditionalTaintStep(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) { + any(StringLengthConflationAdditionalTaintStep s).step(nodeFrom, nodeTo) + } } diff --git a/swift/ql/src/queries/Security/CWE-135/StringLengthConflation.ql b/swift/ql/src/queries/Security/CWE-135/StringLengthConflation.ql index 4e5f5d20307..ddc5f9201f5 100644 --- a/swift/ql/src/queries/Security/CWE-135/StringLengthConflation.ql +++ b/swift/ql/src/queries/Security/CWE-135/StringLengthConflation.ql @@ -17,13 +17,12 @@ import DataFlow::PathGraph from StringLengthConflationConfiguration config, DataFlow::PathNode source, DataFlow::PathNode sink, - StringLengthConflationFlowState sourceFlowState, StringLengthConflationFlowState sinkFlowstate, - string message + StringType sourceType, StringType sinkType, string message where config.hasFlowPath(source, sink) and - config.isSource(source.getNode(), sourceFlowState) and - config.isSinkImpl(sink.getNode(), sinkFlowstate) and + config.isSource(source.getNode(), sourceType) and + sinkType = sink.getNode().(StringLengthConflationSink).getCorrectStringType() and message = - "This " + sourceFlowState + " length is used in " + sinkFlowstate.getSingular() + + "This " + sourceType + " length is used in " + sinkType.getSingular() + ", but it may not be equivalent." select sink.getNode(), source, sink, message From e266132f0aa1a76e6d5b71fd27fba90b6219d264 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Mon, 20 Mar 2023 18:45:36 +0000 Subject: [PATCH 335/631] Swift: Replace sinks with (extendable) CSV. --- .../codeql/swift/dataflow/ExternalFlow.qll | 3 +- .../StringLengthConflationExtensions.qll | 144 ++++++++---------- .../CWE-135/StringLengthConflation.expected | 10 -- .../CWE-135/StringLengthConflation.swift | 6 +- 4 files changed, 66 insertions(+), 97 deletions(-) diff --git a/swift/ql/lib/codeql/swift/dataflow/ExternalFlow.qll b/swift/ql/lib/codeql/swift/dataflow/ExternalFlow.qll index 214de0d5455..ab4743dadeb 100644 --- a/swift/ql/lib/codeql/swift/dataflow/ExternalFlow.qll +++ b/swift/ql/lib/codeql/swift/dataflow/ExternalFlow.qll @@ -16,7 +16,8 @@ * 1. The `namespace` 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. + * arbitrary subtype of that type. Set this to `false` if leaving the `type` + * blank (for example, a free function). * 4. The `name` column optionally selects a specific named member of the type. * 5. The `signature` column optionally restricts the named member. If * `signature` is blank then no such filtering is done. The format of the diff --git a/swift/ql/lib/codeql/swift/security/StringLengthConflationExtensions.qll b/swift/ql/lib/codeql/swift/security/StringLengthConflationExtensions.qll index bd416392e62..1573e28a47c 100644 --- a/swift/ql/lib/codeql/swift/security/StringLengthConflationExtensions.qll +++ b/swift/ql/lib/codeql/swift/security/StringLengthConflationExtensions.qll @@ -5,6 +5,7 @@ import swift import codeql.swift.dataflow.DataFlow +import codeql.swift.dataflow.ExternalFlow /** * A type of Swift string encoding. This class is used as a flow state for @@ -13,31 +14,50 @@ import codeql.swift.dataflow.DataFlow class StringType extends string { string singular; string equivClass; + string csvLabel; StringType() { - this = "String" and singular = "a String" and equivClass = "String" + this = "String" and + singular = "a String" and + equivClass = "String" and + csvLabel = "string-length" or - this = "NSString" and singular = "an NSString" and equivClass = "NSString" + this = "NSString" and + singular = "an NSString" and + equivClass = "NSString" and + csvLabel = "nsstring-length" or - this = "String.utf8" and singular = "a String.utf8" and equivClass = "String.utf8" + this = "String.utf8" and + singular = "a String.utf8" and + equivClass = "String.utf8" and + csvLabel = "string-utf8-length" or - this = "String.utf16" and singular = "a String.utf16" and equivClass = "NSString" + this = "String.utf16" and + singular = "a String.utf16" and + equivClass = "NSString" and + csvLabel = "string-utf16-length" or this = "String.unicodeScalars" and singular = "a String.unicodeScalars" and - equivClass = "String.unicodeScalars" + equivClass = "String.unicodeScalars" and + csvLabel = "string-unicodescalars-length" } /** - * Gets the equivalence class for this flow state. If these are equal, + * Gets the equivalence class for this string type. If these are equal, * they should be treated as equivalent. */ string getEquivClass() { result = equivClass } /** - * Gets text for the singular form of this flow state. + * Gets text for the singular form of this string type. */ string getSingular() { result = singular } + + /** + * Gets the label for this string type in CSV models. + */ + string getCsvLabel() { result = csvLabel } } /** @@ -115,83 +135,41 @@ private class DefaultStringLengthConflationSource extends StringLengthConflation override StringType getStringType() { result = stringType } } +/** + * A sink defined in a CSV model. + */ private class DefaultStringLengthConflationSink extends StringLengthConflationSink { - StringType correctStringType; + StringType stringType; - DefaultStringLengthConflationSink() { - exists(AbstractFunctionDecl funcDecl, CallExpr call, string funcName, int arg | - ( - // arguments to method calls... - exists(string className, ClassOrStructDecl c | - ( - // `NSRange.init` - className = "NSRange" and - funcName = "init(location:length:)" and - arg = [0, 1] - or - // `NSString.character` - className = ["NSString", "NSMutableString"] and - funcName = "character(at:)" and - arg = 0 - or - // `NSString.character` - className = ["NSString", "NSMutableString"] and - funcName = "substring(from:)" and - arg = 0 - or - // `NSString.character` - className = ["NSString", "NSMutableString"] and - funcName = "substring(to:)" and - arg = 0 - or - // `NSMutableString.insert` - className = "NSMutableString" and - funcName = "insert(_:at:)" and - arg = 1 - ) and - c.getName() = className and - c.getABaseTypeDecl*().(ClassOrStructDecl).getAMember() = funcDecl and - call.getStaticTarget() = funcDecl and - correctStringType = "NSString" - ) - or - // arguments to function calls... - // `NSMakeRange` - funcName = "NSMakeRange(_:_:)" and - arg = [0, 1] and - call.getStaticTarget() = funcDecl and - correctStringType = "NSString" - or - // arguments to method calls... - ( - // `String.dropFirst`, `String.dropLast`, `String.removeFirst`, `String.removeLast` - funcName = ["dropFirst(_:)", "dropLast(_:)", "removeFirst(_:)", "removeLast(_:)"] and - arg = 0 - or - // `String.prefix`, `String.suffix` - funcName = ["prefix(_:)", "suffix(_:)"] and - arg = 0 - or - // `String.Index.init` - funcName = "init(encodedOffset:)" and - arg = 0 - or - // `String.index` - funcName = ["index(_:offsetBy:)", "index(_:offsetBy:limitBy:)"] and - arg = [0, 1] - or - // `String.formIndex` - funcName = ["formIndex(_:offsetBy:)", "formIndex(_:offsetBy:limitBy:)"] and - arg = [0, 1] - ) and - call.getStaticTarget() = funcDecl and - correctStringType = "String" - ) and - // match up `funcName`, `arg`, `node`. - funcDecl.getName() = funcName and - call.getArgument(arg).getExpr() = this.asExpr() - ) - } + DefaultStringLengthConflationSink() { sinkNode(this, stringType.getCsvLabel()) } - override StringType getCorrectStringType() { result = correctStringType } + override StringType getCorrectStringType() { result = stringType } +} + +private class StringLengthConflationSinks extends SinkModelCsv { + override predicate row(string row) { + row = + [ + ";Sequence;true;dropFirst(_:);;;Argument[0];string-length", + ";Sequence;true;dropLast(_:);;;Argument[0];string-length", + ";Sequence;true;prefix(_:);;;Argument[0];string-length", + ";Sequence;true;suffix(_:);;;Argument[0];string-length", + ";Collection;true;formIndex(_:offsetBy:);;;Argument[0..1];string-length", + ";Collection;true;formIndex(_:offsetBy:limitBy:);;;Argument[0..1];string-length", + ";Collection;true;removeFirst(_:);;;Argument[0];string-length", + ";RangeReplaceableCollection;true;removeLast(_:);;;Argument[0];string-length", + ";String;true;index(_:offsetBy:);;;Argument[0..1];string-length", + ";String;true;index(_:offsetBy:limitBy:);;;Argument[0..1];string-length", + ";String.Index;true;init(encodedOffset:);;;Argument[0];string-length", + ";NSRange;true;init(location:length:);;;Argument[0..1];nsstring-length", + ";NSString;true;character(at:);;;Argument[0];nsstring-length", + ";NSString;true;substring(from:);;;Argument[0];nsstring-length", + ";NSString;true;substring(to:);;;Argument[0];nsstring-length", + ";NSMutableString;true;character(at:);;;Argument[0];nsstring-length", + ";NSMutableString;true;substring(from:);;;Argument[0];nsstring-length", + ";NSMutableString;true;substring(to:);;;Argument[0];nsstring-length", + ";NSMutableString;true;insert(_:at:);;;Argument[1];nsstring-length", + ";;false;NSMakeRange(_:_:);;;Argument[0..1];nsstring-length", + ] + } } diff --git a/swift/ql/test/query-tests/Security/CWE-135/StringLengthConflation.expected b/swift/ql/test/query-tests/Security/CWE-135/StringLengthConflation.expected index 539b3796874..00d4fb1f6ef 100644 --- a/swift/ql/test/query-tests/Security/CWE-135/StringLengthConflation.expected +++ b/swift/ql/test/query-tests/Security/CWE-135/StringLengthConflation.expected @@ -1,5 +1,4 @@ edges -| StringLengthConflation2.swift:35:36:35:38 | .count : | StringLengthConflation2.swift:35:36:35:46 | ... .-(_:_:) ... | | StringLengthConflation2.swift:37:34:37:36 | .count : | StringLengthConflation2.swift:37:34:37:44 | ... .-(_:_:) ... | | StringLengthConflation.swift:36:30:36:37 | len : | StringLengthConflation.swift:36:93:36:93 | len | | StringLengthConflation.swift:60:47:60:50 | .length : | StringLengthConflation.swift:60:47:60:59 | ... ./(_:_:) ... | @@ -28,8 +27,6 @@ edges | file://:0:0:0:0 | .length : | StringLengthConflation.swift:114:23:114:26 | .length : | | file://:0:0:0:0 | .length : | StringLengthConflation.swift:120:22:120:25 | .length : | nodes -| StringLengthConflation2.swift:35:36:35:38 | .count : | semmle.label | .count : | -| StringLengthConflation2.swift:35:36:35:46 | ... .-(_:_:) ... | semmle.label | ... .-(_:_:) ... | | StringLengthConflation2.swift:37:34:37:36 | .count : | semmle.label | .count : | | StringLengthConflation2.swift:37:34:37:44 | ... .-(_:_:) ... | semmle.label | ... .-(_:_:) ... | | StringLengthConflation.swift:36:30:36:37 | len : | semmle.label | len : | @@ -74,15 +71,11 @@ nodes | StringLengthConflation.swift:144:28:144:30 | .count : | semmle.label | .count : | | StringLengthConflation.swift:144:28:144:38 | ... .-(_:_:) ... | semmle.label | ... .-(_:_:) ... | | StringLengthConflation.swift:151:45:151:53 | .count | semmle.label | .count | -| StringLengthConflation.swift:152:57:152:65 | .count | semmle.label | .count | | StringLengthConflation.swift:156:45:156:52 | .count | semmle.label | .count | -| StringLengthConflation.swift:157:55:157:62 | .count | semmle.label | .count | | StringLengthConflation.swift:161:45:161:53 | .count | semmle.label | .count | -| StringLengthConflation.swift:162:57:162:65 | .count | semmle.label | .count | | file://:0:0:0:0 | .length : | semmle.label | .length : | subpaths #select -| StringLengthConflation2.swift:35:36:35:46 | ... .-(_:_:) ... | StringLengthConflation2.swift:35:36:35:38 | .count : | StringLengthConflation2.swift:35:36:35:46 | ... .-(_:_:) ... | This String length is used in an NSString, but it may not be equivalent. | | StringLengthConflation2.swift:37:34:37:44 | ... .-(_:_:) ... | StringLengthConflation2.swift:37:34:37:36 | .count : | StringLengthConflation2.swift:37:34:37:44 | ... .-(_:_:) ... | This String length is used in an NSString, but it may not be equivalent. | | StringLengthConflation.swift:36:93:36:93 | len | StringLengthConflation.swift:72:33:72:35 | .count : | StringLengthConflation.swift:36:93:36:93 | len | This String length is used in an NSString, but it may not be equivalent. | | StringLengthConflation.swift:53:43:53:46 | .length | StringLengthConflation.swift:53:43:53:46 | .length | StringLengthConflation.swift:53:43:53:46 | .length | This NSString length is used in a String, but it may not be equivalent. | @@ -118,8 +111,5 @@ subpaths | StringLengthConflation.swift:138:36:138:46 | ... .-(_:_:) ... | StringLengthConflation.swift:138:36:138:38 | .count : | StringLengthConflation.swift:138:36:138:46 | ... .-(_:_:) ... | This String length is used in an NSString, but it may not be equivalent. | | StringLengthConflation.swift:144:28:144:38 | ... .-(_:_:) ... | StringLengthConflation.swift:144:28:144:30 | .count : | StringLengthConflation.swift:144:28:144:38 | ... .-(_:_:) ... | This String length is used in an NSString, but it may not be equivalent. | | StringLengthConflation.swift:151:45:151:53 | .count | StringLengthConflation.swift:151:45:151:53 | .count | StringLengthConflation.swift:151:45:151:53 | .count | This String.unicodeScalars length is used in a String, but it may not be equivalent. | -| StringLengthConflation.swift:152:57:152:65 | .count | StringLengthConflation.swift:152:57:152:65 | .count | StringLengthConflation.swift:152:57:152:65 | .count | This String.unicodeScalars length is used in a String, but it may not be equivalent. | | StringLengthConflation.swift:156:45:156:52 | .count | StringLengthConflation.swift:156:45:156:52 | .count | StringLengthConflation.swift:156:45:156:52 | .count | This String.utf8 length is used in a String, but it may not be equivalent. | -| StringLengthConflation.swift:157:55:157:62 | .count | StringLengthConflation.swift:157:55:157:62 | .count | StringLengthConflation.swift:157:55:157:62 | .count | This String.utf8 length is used in a String, but it may not be equivalent. | | StringLengthConflation.swift:161:45:161:53 | .count | StringLengthConflation.swift:161:45:161:53 | .count | StringLengthConflation.swift:161:45:161:53 | .count | This String.utf16 length is used in a String, but it may not be equivalent. | -| StringLengthConflation.swift:162:57:162:65 | .count | StringLengthConflation.swift:162:57:162:65 | .count | StringLengthConflation.swift:162:57:162:65 | .count | This String.unicodeScalars length is used in a String, but it may not be equivalent. | diff --git a/swift/ql/test/query-tests/Security/CWE-135/StringLengthConflation.swift b/swift/ql/test/query-tests/Security/CWE-135/StringLengthConflation.swift index abea44b0e93..67b8feb657f 100644 --- a/swift/ql/test/query-tests/Security/CWE-135/StringLengthConflation.swift +++ b/swift/ql/test/query-tests/Security/CWE-135/StringLengthConflation.swift @@ -149,17 +149,17 @@ func test(s: String) { let scalars = s.unicodeScalars let _ = s.index(s.startIndex, offsetBy: s.count) // GOOD let _ = s.index(s.startIndex, offsetBy: scalars.count) // BAD - let _ = scalars.index(scalars.startIndex, offsetBy: scalars.count) // GOOD [FALSE POSITIVE] + let _ = scalars.index(scalars.startIndex, offsetBy: scalars.count) // GOOD let _ = scalars.index(scalars.startIndex, offsetBy: s.count) // BAD [NOT DETECTED] let s_utf8 = s.utf8 let _ = s.index(s.startIndex, offsetBy: s_utf8.count) // BAD - let _ = s_utf8.index(s_utf8.startIndex, offsetBy: s_utf8.count) // GOOD [FALSE POSITIVE] + let _ = s_utf8.index(s_utf8.startIndex, offsetBy: s_utf8.count) // GOOD let _ = s_utf8.index(s_utf8.startIndex, offsetBy: s.count) // BAD [NOT DETECTED] let s_utf16 = s.utf16 let _ = s.index(s.startIndex, offsetBy: s_utf16.count) // BAD - let _ = s_utf16.index(s_utf16.startIndex, offsetBy: scalars.count) // GOOD [FALSE POSITIVE] + let _ = s_utf16.index(s_utf16.startIndex, offsetBy: scalars.count) // GOOD let _ = s_utf16.index(s_utf16.startIndex, offsetBy: s.count) // BAD [NOT DETECTED] } From 9529bc5f095a8cd5e1105df5fb83fe72444b5a43 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Tue, 21 Mar 2023 11:07:36 +0000 Subject: [PATCH 336/631] Swift: The regressed test is not realistic, update it to be more like what really happens. --- .../Security/CWE-135/StringLengthConflation.expected | 4 ++++ .../Security/CWE-135/StringLengthConflation2.swift | 12 ++++++------ 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/swift/ql/test/query-tests/Security/CWE-135/StringLengthConflation.expected b/swift/ql/test/query-tests/Security/CWE-135/StringLengthConflation.expected index 00d4fb1f6ef..17e2c383dd8 100644 --- a/swift/ql/test/query-tests/Security/CWE-135/StringLengthConflation.expected +++ b/swift/ql/test/query-tests/Security/CWE-135/StringLengthConflation.expected @@ -1,4 +1,5 @@ edges +| StringLengthConflation2.swift:35:36:35:38 | .count : | StringLengthConflation2.swift:35:36:35:46 | ... .-(_:_:) ... | | StringLengthConflation2.swift:37:34:37:36 | .count : | StringLengthConflation2.swift:37:34:37:44 | ... .-(_:_:) ... | | StringLengthConflation.swift:36:30:36:37 | len : | StringLengthConflation.swift:36:93:36:93 | len | | StringLengthConflation.swift:60:47:60:50 | .length : | StringLengthConflation.swift:60:47:60:59 | ... ./(_:_:) ... | @@ -27,6 +28,8 @@ edges | file://:0:0:0:0 | .length : | StringLengthConflation.swift:114:23:114:26 | .length : | | file://:0:0:0:0 | .length : | StringLengthConflation.swift:120:22:120:25 | .length : | nodes +| StringLengthConflation2.swift:35:36:35:38 | .count : | semmle.label | .count : | +| StringLengthConflation2.swift:35:36:35:46 | ... .-(_:_:) ... | semmle.label | ... .-(_:_:) ... | | StringLengthConflation2.swift:37:34:37:36 | .count : | semmle.label | .count : | | StringLengthConflation2.swift:37:34:37:44 | ... .-(_:_:) ... | semmle.label | ... .-(_:_:) ... | | StringLengthConflation.swift:36:30:36:37 | len : | semmle.label | len : | @@ -76,6 +79,7 @@ nodes | file://:0:0:0:0 | .length : | semmle.label | .length : | subpaths #select +| StringLengthConflation2.swift:35:36:35:46 | ... .-(_:_:) ... | StringLengthConflation2.swift:35:36:35:38 | .count : | StringLengthConflation2.swift:35:36:35:46 | ... .-(_:_:) ... | This String length is used in an NSString, but it may not be equivalent. | | StringLengthConflation2.swift:37:34:37:44 | ... .-(_:_:) ... | StringLengthConflation2.swift:37:34:37:36 | .count : | StringLengthConflation2.swift:37:34:37:44 | ... .-(_:_:) ... | This String length is used in an NSString, but it may not be equivalent. | | StringLengthConflation.swift:36:93:36:93 | len | StringLengthConflation.swift:72:33:72:35 | .count : | StringLengthConflation.swift:36:93:36:93 | len | This String length is used in an NSString, but it may not be equivalent. | | StringLengthConflation.swift:53:43:53:46 | .length | StringLengthConflation.swift:53:43:53:46 | .length | StringLengthConflation.swift:53:43:53:46 | .length | This NSString length is used in a String, but it may not be equivalent. | diff --git a/swift/ql/test/query-tests/Security/CWE-135/StringLengthConflation2.swift b/swift/ql/test/query-tests/Security/CWE-135/StringLengthConflation2.swift index 1a0fbfdb638..ffd45c28b10 100644 --- a/swift/ql/test/query-tests/Security/CWE-135/StringLengthConflation2.swift +++ b/swift/ql/test/query-tests/Security/CWE-135/StringLengthConflation2.swift @@ -12,12 +12,7 @@ class NSObject { } -class NSStringBase : NSObject -{ - func substring(from: Int) -> String { return "" } -} - -class NSString : NSStringBase +class NSString : NSObject { init(string: String) { length = string.count } @@ -26,6 +21,11 @@ class NSString : NSStringBase private(set) var length: Int } +extension NSString +{ + func substring(from: Int) -> String { return "" } +} + // --- tests --- func test(s: String) { From a5bb93402cb615b66577ce0b115b1628040f9717 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Tue, 21 Mar 2023 15:52:27 +0000 Subject: [PATCH 337/631] Swift: Replace sources with (extendable) CSV. --- .../StringLengthConflationExtensions.qll | 63 ++++++++++--------- 1 file changed, 33 insertions(+), 30 deletions(-) diff --git a/swift/ql/lib/codeql/swift/security/StringLengthConflationExtensions.qll b/swift/ql/lib/codeql/swift/security/StringLengthConflationExtensions.qll index 1573e28a47c..e3064104738 100644 --- a/swift/ql/lib/codeql/swift/security/StringLengthConflationExtensions.qll +++ b/swift/ql/lib/codeql/swift/security/StringLengthConflationExtensions.qll @@ -95,40 +95,43 @@ class StringLengthConflationAdditionalTaintStep extends Unit { abstract predicate step(DataFlow::Node nodeFrom, DataFlow::Node nodeTo); } +/** + * A source defined in a CSV model. + */ private class DefaultStringLengthConflationSource extends StringLengthConflationSource { StringType stringType; - DefaultStringLengthConflationSource() { - exists(MemberRefExpr memberRef, string className, string varName | - memberRef.getBase().getType().(NominalType).getABaseType*().getName() = className and - memberRef.getMember().(VarDecl).getName() = varName and + DefaultStringLengthConflationSource() { sourceNode(this, stringType.getCsvLabel()) } + + override StringType getStringType() { result = stringType } +} + +private class StringLengthConflationSources extends SourceModelCsv { + override predicate row(string row) { + row = + [ + ";String;true;count;;;;string-length", + ";String.UTF8View;true;count;;;;string-utf8-length", + ";String.UTF16View;true;count;;;;string-utf16-length", + ";NSString;true;length;;;;nsstring-length", + ";NSMutableString;true;length;;;;nsstring-length", + ] + } +} + +/** + * An extra source that don't currently fit into the CSV scheme. + */ +private class ExtraStringLengthConflationSource extends StringLengthConflationSource { + StringType stringType; + + ExtraStringLengthConflationSource() { + exists(MemberRefExpr memberRef | + // result of a call to `String.unicodeScalars.count` + memberRef.getBase().getType().(NominalType).getName() = "String.UnicodeScalarView" and + memberRef.getMember().(VarDecl).getName() = "count" and this.asExpr() = memberRef and - ( - // result of a call to `String.count` - className = "String" and - varName = "count" and - stringType = "String" - or - // result of a call to `NSString.length` - className = ["NSString", "NSMutableString"] and - varName = "length" and - stringType = "NSString" - or - // result of a call to `String.utf8.count` - className = "String.UTF8View" and - varName = "count" and - stringType = "String.utf8" - or - // result of a call to `String.utf16.count` - className = "String.UTF16View" and - varName = "count" and - stringType = "String.utf16" - or - // result of a call to `String.unicodeScalars.count` - className = "String.UnicodeScalarView" and - varName = "count" and - stringType = "String.unicodeScalars" - ) + stringType = "String.unicodeScalars" ) } From de5cf84bd5eb6c3247cbd35798fb5e926988fdb5 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Thu, 23 Mar 2023 11:08:49 +0000 Subject: [PATCH 338/631] Swift: Address check failures. --- .../swift/security/StringLengthConflationExtensions.qll | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/swift/ql/lib/codeql/swift/security/StringLengthConflationExtensions.qll b/swift/ql/lib/codeql/swift/security/StringLengthConflationExtensions.qll index e3064104738..966734e5fcf 100644 --- a/swift/ql/lib/codeql/swift/security/StringLengthConflationExtensions.qll +++ b/swift/ql/lib/codeql/swift/security/StringLengthConflationExtensions.qll @@ -82,6 +82,9 @@ abstract class StringLengthConflationSink extends DataFlow::Node { abstract StringType getCorrectStringType(); } +/** + * A sanitizer for string length conflation vulnerabilities. + */ abstract class StringLengthConflationSanitizer extends DataFlow::Node { } /** @@ -110,8 +113,7 @@ private class StringLengthConflationSources extends SourceModelCsv { override predicate row(string row) { row = [ - ";String;true;count;;;;string-length", - ";String.UTF8View;true;count;;;;string-utf8-length", + ";String;true;count;;;;string-length", ";String.UTF8View;true;count;;;;string-utf8-length", ";String.UTF16View;true;count;;;;string-utf16-length", ";NSString;true;length;;;;nsstring-length", ";NSMutableString;true;length;;;;nsstring-length", From cfa5af969e6b6378a96af11facb6d05fafe825ab Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen <aschackmull@github.com> Date: Thu, 23 Mar 2023 11:07:19 +0100 Subject: [PATCH 339/631] Dataflow: Rename Make to Global and remove has* prefix. --- .../code/java/dataflow/internal/DataFlow.qll | 34 ++++++++++++------- .../java/dataflow/internal/DataFlowImpl.qll | 28 ++++++++++----- .../java/dataflow/internal/DataFlowImpl1.qll | 4 +-- .../internal/tainttracking1/TaintTracking.qll | 14 ++++++-- 4 files changed, 56 insertions(+), 24 deletions(-) diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlow.qll b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlow.qll index 617362ab4f0..82714ed1af6 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlow.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlow.qll @@ -2,7 +2,7 @@ * Provides an implementation of global (interprocedural) data flow. This file * re-exports the local (intraprocedural) data flow analysis from * `DataFlowImplSpecific::Public` and adds a global analysis, mainly exposed - * through the `Make` and `MakeWithState` modules. + * through the `Global` and `GlobalWithState` modules. */ private import DataFlowImplCommon @@ -73,10 +73,10 @@ signature module ConfigSig { */ default FlowFeature getAFeature() { none() } - /** Holds if sources should be grouped in the result of `hasFlowPath`. */ + /** Holds if sources should be grouped in the result of `flowPath`. */ default predicate sourceGrouping(Node source, string sourceGroup) { none() } - /** Holds if sinks should be grouped in the result of `hasFlowPath`. */ + /** Holds if sinks should be grouped in the result of `flowPath`. */ default predicate sinkGrouping(Node sink, string sinkGroup) { none() } /** @@ -166,10 +166,10 @@ signature module StateConfigSig { */ default FlowFeature getAFeature() { none() } - /** Holds if sources should be grouped in the result of `hasFlowPath`. */ + /** Holds if sources should be grouped in the result of `flowPath`. */ default predicate sourceGrouping(Node source, string sourceGroup) { none() } - /** Holds if sinks should be grouped in the result of `hasFlowPath`. */ + /** Holds if sinks should be grouped in the result of `flowPath`. */ default predicate sinkGrouping(Node sink, string sinkGroup) { none() } /** @@ -182,7 +182,7 @@ signature module StateConfigSig { } /** - * Gets the exploration limit for `hasPartialFlow` and `hasPartialFlowRev` + * Gets the exploration limit for `partialFlow` and `partialFlowRev` * measured in approximate number of interprocedural steps. */ signature int explorationLimitSig(); @@ -203,28 +203,28 @@ signature module DataFlowSig { * The corresponding paths are generated from the end-points and the graph * included in the module `PathGraph`. */ - predicate hasFlowPath(PathNode source, PathNode sink); + predicate flowPath(PathNode source, PathNode sink); /** * Holds if data can flow from `source` to `sink`. */ - predicate hasFlow(Node source, Node sink); + predicate flow(Node source, Node sink); /** * Holds if data can flow from some source to `sink`. */ - predicate hasFlowTo(Node sink); + predicate flowTo(Node sink); /** * Holds if data can flow from some source to `sink`. */ - predicate hasFlowToExpr(DataFlowExpr sink); + predicate flowToExpr(DataFlowExpr sink); } /** * Constructs a standard data flow computation. */ -module Make<ConfigSig Config> implements DataFlowSig { +module Global<ConfigSig Config> implements DataFlowSig { private module C implements FullStateConfigSig { import DefaultState<Config> import Config @@ -233,10 +233,15 @@ module Make<ConfigSig Config> implements DataFlowSig { import Impl<C> } +/** DEPRECATED: Use `Global` instead. */ +deprecated module Make<ConfigSig Config> implements DataFlowSig { + import Global<Config> +} + /** * Constructs a data flow computation using flow state. */ -module MakeWithState<StateConfigSig Config> implements DataFlowSig { +module GlobalWithState<StateConfigSig Config> implements DataFlowSig { private module C implements FullStateConfigSig { import Config } @@ -244,6 +249,11 @@ module MakeWithState<StateConfigSig Config> implements DataFlowSig { import Impl<C> } +/** DEPRECATED: Use `GlobalWithState` instead. */ +deprecated module MakeWithState<StateConfigSig Config> implements DataFlowSig { + import GlobalWithState<Config> +} + signature class PathNodeSig { /** Gets a textual representation of this element. */ string toString(); 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 c47b0308855..d18ef5acd6e 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl.qll @@ -91,10 +91,10 @@ signature module FullStateConfigSig { */ FlowFeature getAFeature(); - /** Holds if sources should be grouped in the result of `hasFlowPath`. */ + /** Holds if sources should be grouped in the result of `flowPath`. */ predicate sourceGrouping(Node source, string sourceGroup); - /** Holds if sinks should be grouped in the result of `hasFlowPath`. */ + /** Holds if sinks should be grouped in the result of `flowPath`. */ predicate sinkGrouping(Node sink, string sinkGroup); /** @@ -3633,7 +3633,7 @@ module Impl<FullStateConfigSig Config> { * The corresponding paths are generated from the end-points and the graph * included in the module `PathGraph`. */ - predicate hasFlowPath(PathNode source, PathNode sink) { + predicate flowPath(PathNode source, PathNode sink) { exists(PathNodeImpl flowsource, PathNodeImpl flowsink | source = flowsource and sink = flowsink | @@ -3643,6 +3643,9 @@ module Impl<FullStateConfigSig Config> { ) } + /** DEPRECATED: Use `flowPath` instead. */ + deprecated predicate hasFlowPath = flowPath/2; + private predicate flowsTo(PathNodeImpl flowsource, PathNodeSink flowsink, Node source, Node sink) { flowsource.isSource() and flowsource.getNodeEx().asNode() = source and @@ -3653,17 +3656,26 @@ module Impl<FullStateConfigSig Config> { /** * Holds if data can flow from `source` to `sink`. */ - predicate hasFlow(Node source, Node sink) { flowsTo(_, _, source, sink) } + predicate flow(Node source, Node sink) { flowsTo(_, _, source, sink) } + + /** DEPRECATED: Use `flow` instead. */ + deprecated predicate hasFlow = flow/2; /** * Holds if data can flow from some source to `sink`. */ - predicate hasFlowTo(Node sink) { sink = any(PathNodeSink n).getNodeEx().asNode() } + predicate flowTo(Node sink) { sink = any(PathNodeSink n).getNodeEx().asNode() } + + /** DEPRECATED: Use `flowTo` instead. */ + deprecated predicate hasFlowTo = flowTo/1; /** * Holds if data can flow from some source to `sink`. */ - predicate hasFlowToExpr(DataFlowExpr sink) { hasFlowTo(exprNode(sink)) } + predicate flowToExpr(DataFlowExpr sink) { flowTo(exprNode(sink)) } + + /** DEPRECATED: Use `flowToExpr` instead. */ + deprecated predicate hasFlowToExpr = flowToExpr/1; private predicate finalStats( boolean fwd, int nodes, int fields, int conscand, int states, int tuples @@ -4574,7 +4586,7 @@ module Impl<FullStateConfigSig Config> { * * To use this in a `path-problem` query, import the module `PartialPathGraph`. */ - predicate hasPartialFlow(PartialPathNode source, PartialPathNode node, int dist) { + predicate partialFlow(PartialPathNode source, PartialPathNode node, int dist) { partialFlow(source, node) and dist = node.getSourceDistance() } @@ -4594,7 +4606,7 @@ module Impl<FullStateConfigSig Config> { * Note that reverse flow has slightly lower precision than the corresponding * forward flow, as reverse flow disregards type pruning among other features. */ - predicate hasPartialFlowRev(PartialPathNode node, PartialPathNode sink, int dist) { + predicate partialFlowRev(PartialPathNode node, PartialPathNode sink, int dist) { revPartialFlow(node, sink) and dist = node.getSinkDistance() } diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl1.qll b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl1.qll index e6bdc74cceb..8415c022111 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl1.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl1.qll @@ -1,5 +1,5 @@ /** - * DEPRECATED: Use `Make` and `MakeWithState` instead. + * DEPRECATED: Use `Global` and `GlobalWithState` instead. * * Provides a `Configuration` class backwards-compatible interface to the data * flow library. @@ -388,7 +388,7 @@ private predicate hasFlow(Node source, Node sink, Configuration config) { } private predicate hasFlowPath(PathNode source, PathNode sink, Configuration config) { - hasFlowPath(source, sink) and source.getConfiguration() = config + flowPath(source, sink) and source.getConfiguration() = config } private predicate hasFlowTo(Node sink, Configuration config) { hasFlow(_, sink, config) } diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/tainttracking1/TaintTracking.qll b/java/ql/lib/semmle/code/java/dataflow/internal/tainttracking1/TaintTracking.qll index 7f96fe5e6fb..192a52f44e3 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/tainttracking1/TaintTracking.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/tainttracking1/TaintTracking.qll @@ -35,7 +35,7 @@ private module AddTaintDefaults<DataFlowInternal::FullStateConfigSig Config> imp /** * Constructs a standard taint tracking computation. */ -module Make<DataFlow::ConfigSig Config> implements DataFlow::DataFlowSig { +module Global<DataFlow::ConfigSig Config> implements DataFlow::DataFlowSig { private module Config0 implements DataFlowInternal::FullStateConfigSig { import DataFlowInternal::DefaultState<Config> import Config @@ -48,10 +48,15 @@ module Make<DataFlow::ConfigSig Config> implements DataFlow::DataFlowSig { import DataFlowInternal::Impl<C> } +/** DEPRECATED: Use `Global` instead. */ +deprecated module Make<DataFlow::ConfigSig Config> implements DataFlow::DataFlowSig { + import Global<Config> +} + /** * Constructs a taint tracking computation using flow state. */ -module MakeWithState<DataFlow::StateConfigSig Config> implements DataFlow::DataFlowSig { +module GlobalWithState<DataFlow::StateConfigSig Config> implements DataFlow::DataFlowSig { private module Config0 implements DataFlowInternal::FullStateConfigSig { import Config } @@ -62,3 +67,8 @@ module MakeWithState<DataFlow::StateConfigSig Config> implements DataFlow::DataF import DataFlowInternal::Impl<C> } + +/** DEPRECATED: Use `GlobalWithState` instead. */ +deprecated module MakeWithState<DataFlow::StateConfigSig Config> implements DataFlow::DataFlowSig { + import GlobalWithState<Config> +} From 2761aa73ca33d7f71906ed42197e9be08f711daf Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen <aschackmull@github.com> Date: Thu, 23 Mar 2023 11:08:19 +0100 Subject: [PATCH 340/631] Dataflow: Sync. --- .../code/cpp/dataflow/internal/DataFlow.qll | 34 ++++++++++++------- .../cpp/dataflow/internal/DataFlowImpl.qll | 28 ++++++++++----- .../cpp/dataflow/internal/DataFlowImpl1.qll | 4 +-- .../cpp/dataflow/internal/DataFlowImpl2.qll | 4 +-- .../cpp/dataflow/internal/DataFlowImpl3.qll | 4 +-- .../cpp/dataflow/internal/DataFlowImpl4.qll | 4 +-- .../dataflow/internal/DataFlowImplLocal.qll | 4 +-- .../internal/tainttracking1/TaintTracking.qll | 14 ++++++-- .../cpp/ir/dataflow/internal/DataFlow.qll | 34 ++++++++++++------- .../cpp/ir/dataflow/internal/DataFlowImpl.qll | 28 ++++++++++----- .../ir/dataflow/internal/DataFlowImpl1.qll | 4 +-- .../ir/dataflow/internal/DataFlowImpl2.qll | 4 +-- .../ir/dataflow/internal/DataFlowImpl3.qll | 4 +-- .../ir/dataflow/internal/DataFlowImpl4.qll | 4 +-- .../internal/tainttracking1/TaintTracking.qll | 14 ++++++-- .../csharp/dataflow/internal/DataFlow.qll | 34 ++++++++++++------- .../csharp/dataflow/internal/DataFlowImpl.qll | 28 ++++++++++----- .../dataflow/internal/DataFlowImpl1.qll | 4 +-- .../dataflow/internal/DataFlowImpl2.qll | 4 +-- .../dataflow/internal/DataFlowImpl3.qll | 4 +-- .../dataflow/internal/DataFlowImpl4.qll | 4 +-- .../dataflow/internal/DataFlowImpl5.qll | 4 +-- .../DataFlowImplForContentDataFlow.qll | 4 +-- .../internal/tainttracking1/TaintTracking.qll | 14 ++++++-- .../semmle/go/dataflow/internal/DataFlow.qll | 34 ++++++++++++------- .../go/dataflow/internal/DataFlowImpl.qll | 28 ++++++++++----- .../go/dataflow/internal/DataFlowImpl1.qll | 4 +-- .../go/dataflow/internal/DataFlowImpl2.qll | 4 +-- .../DataFlowImplForStringsNewReplacer.qll | 4 +-- .../internal/tainttracking1/TaintTracking.qll | 14 ++++++-- .../java/dataflow/internal/DataFlowImpl2.qll | 4 +-- .../java/dataflow/internal/DataFlowImpl3.qll | 4 +-- .../java/dataflow/internal/DataFlowImpl4.qll | 4 +-- .../java/dataflow/internal/DataFlowImpl5.qll | 4 +-- .../java/dataflow/internal/DataFlowImpl6.qll | 4 +-- .../python/dataflow/new/internal/DataFlow.qll | 34 ++++++++++++------- .../dataflow/new/internal/DataFlowImpl.qll | 28 ++++++++++----- .../dataflow/new/internal/DataFlowImpl1.qll | 4 +-- .../dataflow/new/internal/DataFlowImpl2.qll | 4 +-- .../dataflow/new/internal/DataFlowImpl3.qll | 4 +-- .../dataflow/new/internal/DataFlowImpl4.qll | 4 +-- .../new/internal/DataFlowImplForRegExp.qll | 4 +-- .../internal/tainttracking1/TaintTracking.qll | 14 ++++++-- .../ruby/dataflow/internal/DataFlow.qll | 34 ++++++++++++------- .../ruby/dataflow/internal/DataFlowImpl.qll | 28 ++++++++++----- .../ruby/dataflow/internal/DataFlowImpl1.qll | 4 +-- .../ruby/dataflow/internal/DataFlowImpl2.qll | 4 +-- .../DataFlowImplForHttpClientLibraries.qll | 4 +-- .../internal/DataFlowImplForPathname.qll | 4 +-- .../internal/tainttracking1/TaintTracking.qll | 14 ++++++-- .../swift/dataflow/internal/DataFlow.qll | 34 ++++++++++++------- .../swift/dataflow/internal/DataFlowImpl.qll | 28 ++++++++++----- .../swift/dataflow/internal/DataFlowImpl1.qll | 4 +-- .../internal/tainttracking1/TaintTracking.qll | 14 ++++++-- 54 files changed, 444 insertions(+), 220 deletions(-) diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlow.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlow.qll index 617362ab4f0..82714ed1af6 100644 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlow.qll +++ b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlow.qll @@ -2,7 +2,7 @@ * Provides an implementation of global (interprocedural) data flow. This file * re-exports the local (intraprocedural) data flow analysis from * `DataFlowImplSpecific::Public` and adds a global analysis, mainly exposed - * through the `Make` and `MakeWithState` modules. + * through the `Global` and `GlobalWithState` modules. */ private import DataFlowImplCommon @@ -73,10 +73,10 @@ signature module ConfigSig { */ default FlowFeature getAFeature() { none() } - /** Holds if sources should be grouped in the result of `hasFlowPath`. */ + /** Holds if sources should be grouped in the result of `flowPath`. */ default predicate sourceGrouping(Node source, string sourceGroup) { none() } - /** Holds if sinks should be grouped in the result of `hasFlowPath`. */ + /** Holds if sinks should be grouped in the result of `flowPath`. */ default predicate sinkGrouping(Node sink, string sinkGroup) { none() } /** @@ -166,10 +166,10 @@ signature module StateConfigSig { */ default FlowFeature getAFeature() { none() } - /** Holds if sources should be grouped in the result of `hasFlowPath`. */ + /** Holds if sources should be grouped in the result of `flowPath`. */ default predicate sourceGrouping(Node source, string sourceGroup) { none() } - /** Holds if sinks should be grouped in the result of `hasFlowPath`. */ + /** Holds if sinks should be grouped in the result of `flowPath`. */ default predicate sinkGrouping(Node sink, string sinkGroup) { none() } /** @@ -182,7 +182,7 @@ signature module StateConfigSig { } /** - * Gets the exploration limit for `hasPartialFlow` and `hasPartialFlowRev` + * Gets the exploration limit for `partialFlow` and `partialFlowRev` * measured in approximate number of interprocedural steps. */ signature int explorationLimitSig(); @@ -203,28 +203,28 @@ signature module DataFlowSig { * The corresponding paths are generated from the end-points and the graph * included in the module `PathGraph`. */ - predicate hasFlowPath(PathNode source, PathNode sink); + predicate flowPath(PathNode source, PathNode sink); /** * Holds if data can flow from `source` to `sink`. */ - predicate hasFlow(Node source, Node sink); + predicate flow(Node source, Node sink); /** * Holds if data can flow from some source to `sink`. */ - predicate hasFlowTo(Node sink); + predicate flowTo(Node sink); /** * Holds if data can flow from some source to `sink`. */ - predicate hasFlowToExpr(DataFlowExpr sink); + predicate flowToExpr(DataFlowExpr sink); } /** * Constructs a standard data flow computation. */ -module Make<ConfigSig Config> implements DataFlowSig { +module Global<ConfigSig Config> implements DataFlowSig { private module C implements FullStateConfigSig { import DefaultState<Config> import Config @@ -233,10 +233,15 @@ module Make<ConfigSig Config> implements DataFlowSig { import Impl<C> } +/** DEPRECATED: Use `Global` instead. */ +deprecated module Make<ConfigSig Config> implements DataFlowSig { + import Global<Config> +} + /** * Constructs a data flow computation using flow state. */ -module MakeWithState<StateConfigSig Config> implements DataFlowSig { +module GlobalWithState<StateConfigSig Config> implements DataFlowSig { private module C implements FullStateConfigSig { import Config } @@ -244,6 +249,11 @@ module MakeWithState<StateConfigSig Config> implements DataFlowSig { import Impl<C> } +/** DEPRECATED: Use `GlobalWithState` instead. */ +deprecated module MakeWithState<StateConfigSig Config> implements DataFlowSig { + import GlobalWithState<Config> +} + signature class PathNodeSig { /** Gets a textual representation of this element. */ string 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 c47b0308855..d18ef5acd6e 100644 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl.qll +++ b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl.qll @@ -91,10 +91,10 @@ signature module FullStateConfigSig { */ FlowFeature getAFeature(); - /** Holds if sources should be grouped in the result of `hasFlowPath`. */ + /** Holds if sources should be grouped in the result of `flowPath`. */ predicate sourceGrouping(Node source, string sourceGroup); - /** Holds if sinks should be grouped in the result of `hasFlowPath`. */ + /** Holds if sinks should be grouped in the result of `flowPath`. */ predicate sinkGrouping(Node sink, string sinkGroup); /** @@ -3633,7 +3633,7 @@ module Impl<FullStateConfigSig Config> { * The corresponding paths are generated from the end-points and the graph * included in the module `PathGraph`. */ - predicate hasFlowPath(PathNode source, PathNode sink) { + predicate flowPath(PathNode source, PathNode sink) { exists(PathNodeImpl flowsource, PathNodeImpl flowsink | source = flowsource and sink = flowsink | @@ -3643,6 +3643,9 @@ module Impl<FullStateConfigSig Config> { ) } + /** DEPRECATED: Use `flowPath` instead. */ + deprecated predicate hasFlowPath = flowPath/2; + private predicate flowsTo(PathNodeImpl flowsource, PathNodeSink flowsink, Node source, Node sink) { flowsource.isSource() and flowsource.getNodeEx().asNode() = source and @@ -3653,17 +3656,26 @@ module Impl<FullStateConfigSig Config> { /** * Holds if data can flow from `source` to `sink`. */ - predicate hasFlow(Node source, Node sink) { flowsTo(_, _, source, sink) } + predicate flow(Node source, Node sink) { flowsTo(_, _, source, sink) } + + /** DEPRECATED: Use `flow` instead. */ + deprecated predicate hasFlow = flow/2; /** * Holds if data can flow from some source to `sink`. */ - predicate hasFlowTo(Node sink) { sink = any(PathNodeSink n).getNodeEx().asNode() } + predicate flowTo(Node sink) { sink = any(PathNodeSink n).getNodeEx().asNode() } + + /** DEPRECATED: Use `flowTo` instead. */ + deprecated predicate hasFlowTo = flowTo/1; /** * Holds if data can flow from some source to `sink`. */ - predicate hasFlowToExpr(DataFlowExpr sink) { hasFlowTo(exprNode(sink)) } + predicate flowToExpr(DataFlowExpr sink) { flowTo(exprNode(sink)) } + + /** DEPRECATED: Use `flowToExpr` instead. */ + deprecated predicate hasFlowToExpr = flowToExpr/1; private predicate finalStats( boolean fwd, int nodes, int fields, int conscand, int states, int tuples @@ -4574,7 +4586,7 @@ module Impl<FullStateConfigSig Config> { * * To use this in a `path-problem` query, import the module `PartialPathGraph`. */ - predicate hasPartialFlow(PartialPathNode source, PartialPathNode node, int dist) { + predicate partialFlow(PartialPathNode source, PartialPathNode node, int dist) { partialFlow(source, node) and dist = node.getSourceDistance() } @@ -4594,7 +4606,7 @@ module Impl<FullStateConfigSig Config> { * Note that reverse flow has slightly lower precision than the corresponding * forward flow, as reverse flow disregards type pruning among other features. */ - predicate hasPartialFlowRev(PartialPathNode node, PartialPathNode sink, int dist) { + predicate partialFlowRev(PartialPathNode node, PartialPathNode sink, int dist) { revPartialFlow(node, sink) and dist = node.getSinkDistance() } diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl1.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl1.qll index e6bdc74cceb..8415c022111 100644 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl1.qll +++ b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl1.qll @@ -1,5 +1,5 @@ /** - * DEPRECATED: Use `Make` and `MakeWithState` instead. + * DEPRECATED: Use `Global` and `GlobalWithState` instead. * * Provides a `Configuration` class backwards-compatible interface to the data * flow library. @@ -388,7 +388,7 @@ private predicate hasFlow(Node source, Node sink, Configuration config) { } private predicate hasFlowPath(PathNode source, PathNode sink, Configuration config) { - hasFlowPath(source, sink) and source.getConfiguration() = config + flowPath(source, sink) and source.getConfiguration() = config } private predicate hasFlowTo(Node sink, Configuration config) { hasFlow(_, sink, config) } 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 e6bdc74cceb..8415c022111 100644 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl2.qll +++ b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl2.qll @@ -1,5 +1,5 @@ /** - * DEPRECATED: Use `Make` and `MakeWithState` instead. + * DEPRECATED: Use `Global` and `GlobalWithState` instead. * * Provides a `Configuration` class backwards-compatible interface to the data * flow library. @@ -388,7 +388,7 @@ private predicate hasFlow(Node source, Node sink, Configuration config) { } private predicate hasFlowPath(PathNode source, PathNode sink, Configuration config) { - hasFlowPath(source, sink) and source.getConfiguration() = config + flowPath(source, sink) and source.getConfiguration() = config } private predicate hasFlowTo(Node sink, Configuration config) { hasFlow(_, sink, config) } 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 e6bdc74cceb..8415c022111 100644 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl3.qll +++ b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl3.qll @@ -1,5 +1,5 @@ /** - * DEPRECATED: Use `Make` and `MakeWithState` instead. + * DEPRECATED: Use `Global` and `GlobalWithState` instead. * * Provides a `Configuration` class backwards-compatible interface to the data * flow library. @@ -388,7 +388,7 @@ private predicate hasFlow(Node source, Node sink, Configuration config) { } private predicate hasFlowPath(PathNode source, PathNode sink, Configuration config) { - hasFlowPath(source, sink) and source.getConfiguration() = config + flowPath(source, sink) and source.getConfiguration() = config } private predicate hasFlowTo(Node sink, Configuration config) { hasFlow(_, sink, config) } 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 e6bdc74cceb..8415c022111 100644 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl4.qll +++ b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl4.qll @@ -1,5 +1,5 @@ /** - * DEPRECATED: Use `Make` and `MakeWithState` instead. + * DEPRECATED: Use `Global` and `GlobalWithState` instead. * * Provides a `Configuration` class backwards-compatible interface to the data * flow library. @@ -388,7 +388,7 @@ private predicate hasFlow(Node source, Node sink, Configuration config) { } private predicate hasFlowPath(PathNode source, PathNode sink, Configuration config) { - hasFlowPath(source, sink) and source.getConfiguration() = config + flowPath(source, sink) and source.getConfiguration() = config } private predicate hasFlowTo(Node sink, Configuration config) { hasFlow(_, sink, config) } 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 e6bdc74cceb..8415c022111 100644 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImplLocal.qll +++ b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImplLocal.qll @@ -1,5 +1,5 @@ /** - * DEPRECATED: Use `Make` and `MakeWithState` instead. + * DEPRECATED: Use `Global` and `GlobalWithState` instead. * * Provides a `Configuration` class backwards-compatible interface to the data * flow library. @@ -388,7 +388,7 @@ private predicate hasFlow(Node source, Node sink, Configuration config) { } private predicate hasFlowPath(PathNode source, PathNode sink, Configuration config) { - hasFlowPath(source, sink) and source.getConfiguration() = config + flowPath(source, sink) and source.getConfiguration() = config } private predicate hasFlowTo(Node sink, Configuration config) { hasFlow(_, sink, config) } diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/tainttracking1/TaintTracking.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/tainttracking1/TaintTracking.qll index 7f96fe5e6fb..192a52f44e3 100644 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/tainttracking1/TaintTracking.qll +++ b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/tainttracking1/TaintTracking.qll @@ -35,7 +35,7 @@ private module AddTaintDefaults<DataFlowInternal::FullStateConfigSig Config> imp /** * Constructs a standard taint tracking computation. */ -module Make<DataFlow::ConfigSig Config> implements DataFlow::DataFlowSig { +module Global<DataFlow::ConfigSig Config> implements DataFlow::DataFlowSig { private module Config0 implements DataFlowInternal::FullStateConfigSig { import DataFlowInternal::DefaultState<Config> import Config @@ -48,10 +48,15 @@ module Make<DataFlow::ConfigSig Config> implements DataFlow::DataFlowSig { import DataFlowInternal::Impl<C> } +/** DEPRECATED: Use `Global` instead. */ +deprecated module Make<DataFlow::ConfigSig Config> implements DataFlow::DataFlowSig { + import Global<Config> +} + /** * Constructs a taint tracking computation using flow state. */ -module MakeWithState<DataFlow::StateConfigSig Config> implements DataFlow::DataFlowSig { +module GlobalWithState<DataFlow::StateConfigSig Config> implements DataFlow::DataFlowSig { private module Config0 implements DataFlowInternal::FullStateConfigSig { import Config } @@ -62,3 +67,8 @@ module MakeWithState<DataFlow::StateConfigSig Config> implements DataFlow::DataF import DataFlowInternal::Impl<C> } + +/** DEPRECATED: Use `GlobalWithState` instead. */ +deprecated module MakeWithState<DataFlow::StateConfigSig Config> implements DataFlow::DataFlowSig { + import GlobalWithState<Config> +} diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlow.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlow.qll index 617362ab4f0..82714ed1af6 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlow.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlow.qll @@ -2,7 +2,7 @@ * Provides an implementation of global (interprocedural) data flow. This file * re-exports the local (intraprocedural) data flow analysis from * `DataFlowImplSpecific::Public` and adds a global analysis, mainly exposed - * through the `Make` and `MakeWithState` modules. + * through the `Global` and `GlobalWithState` modules. */ private import DataFlowImplCommon @@ -73,10 +73,10 @@ signature module ConfigSig { */ default FlowFeature getAFeature() { none() } - /** Holds if sources should be grouped in the result of `hasFlowPath`. */ + /** Holds if sources should be grouped in the result of `flowPath`. */ default predicate sourceGrouping(Node source, string sourceGroup) { none() } - /** Holds if sinks should be grouped in the result of `hasFlowPath`. */ + /** Holds if sinks should be grouped in the result of `flowPath`. */ default predicate sinkGrouping(Node sink, string sinkGroup) { none() } /** @@ -166,10 +166,10 @@ signature module StateConfigSig { */ default FlowFeature getAFeature() { none() } - /** Holds if sources should be grouped in the result of `hasFlowPath`. */ + /** Holds if sources should be grouped in the result of `flowPath`. */ default predicate sourceGrouping(Node source, string sourceGroup) { none() } - /** Holds if sinks should be grouped in the result of `hasFlowPath`. */ + /** Holds if sinks should be grouped in the result of `flowPath`. */ default predicate sinkGrouping(Node sink, string sinkGroup) { none() } /** @@ -182,7 +182,7 @@ signature module StateConfigSig { } /** - * Gets the exploration limit for `hasPartialFlow` and `hasPartialFlowRev` + * Gets the exploration limit for `partialFlow` and `partialFlowRev` * measured in approximate number of interprocedural steps. */ signature int explorationLimitSig(); @@ -203,28 +203,28 @@ signature module DataFlowSig { * The corresponding paths are generated from the end-points and the graph * included in the module `PathGraph`. */ - predicate hasFlowPath(PathNode source, PathNode sink); + predicate flowPath(PathNode source, PathNode sink); /** * Holds if data can flow from `source` to `sink`. */ - predicate hasFlow(Node source, Node sink); + predicate flow(Node source, Node sink); /** * Holds if data can flow from some source to `sink`. */ - predicate hasFlowTo(Node sink); + predicate flowTo(Node sink); /** * Holds if data can flow from some source to `sink`. */ - predicate hasFlowToExpr(DataFlowExpr sink); + predicate flowToExpr(DataFlowExpr sink); } /** * Constructs a standard data flow computation. */ -module Make<ConfigSig Config> implements DataFlowSig { +module Global<ConfigSig Config> implements DataFlowSig { private module C implements FullStateConfigSig { import DefaultState<Config> import Config @@ -233,10 +233,15 @@ module Make<ConfigSig Config> implements DataFlowSig { import Impl<C> } +/** DEPRECATED: Use `Global` instead. */ +deprecated module Make<ConfigSig Config> implements DataFlowSig { + import Global<Config> +} + /** * Constructs a data flow computation using flow state. */ -module MakeWithState<StateConfigSig Config> implements DataFlowSig { +module GlobalWithState<StateConfigSig Config> implements DataFlowSig { private module C implements FullStateConfigSig { import Config } @@ -244,6 +249,11 @@ module MakeWithState<StateConfigSig Config> implements DataFlowSig { import Impl<C> } +/** DEPRECATED: Use `GlobalWithState` instead. */ +deprecated module MakeWithState<StateConfigSig Config> implements DataFlowSig { + import GlobalWithState<Config> +} + signature class PathNodeSig { /** Gets a textual representation of this element. */ string toString(); 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 c47b0308855..d18ef5acd6e 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 @@ -91,10 +91,10 @@ signature module FullStateConfigSig { */ FlowFeature getAFeature(); - /** Holds if sources should be grouped in the result of `hasFlowPath`. */ + /** Holds if sources should be grouped in the result of `flowPath`. */ predicate sourceGrouping(Node source, string sourceGroup); - /** Holds if sinks should be grouped in the result of `hasFlowPath`. */ + /** Holds if sinks should be grouped in the result of `flowPath`. */ predicate sinkGrouping(Node sink, string sinkGroup); /** @@ -3633,7 +3633,7 @@ module Impl<FullStateConfigSig Config> { * The corresponding paths are generated from the end-points and the graph * included in the module `PathGraph`. */ - predicate hasFlowPath(PathNode source, PathNode sink) { + predicate flowPath(PathNode source, PathNode sink) { exists(PathNodeImpl flowsource, PathNodeImpl flowsink | source = flowsource and sink = flowsink | @@ -3643,6 +3643,9 @@ module Impl<FullStateConfigSig Config> { ) } + /** DEPRECATED: Use `flowPath` instead. */ + deprecated predicate hasFlowPath = flowPath/2; + private predicate flowsTo(PathNodeImpl flowsource, PathNodeSink flowsink, Node source, Node sink) { flowsource.isSource() and flowsource.getNodeEx().asNode() = source and @@ -3653,17 +3656,26 @@ module Impl<FullStateConfigSig Config> { /** * Holds if data can flow from `source` to `sink`. */ - predicate hasFlow(Node source, Node sink) { flowsTo(_, _, source, sink) } + predicate flow(Node source, Node sink) { flowsTo(_, _, source, sink) } + + /** DEPRECATED: Use `flow` instead. */ + deprecated predicate hasFlow = flow/2; /** * Holds if data can flow from some source to `sink`. */ - predicate hasFlowTo(Node sink) { sink = any(PathNodeSink n).getNodeEx().asNode() } + predicate flowTo(Node sink) { sink = any(PathNodeSink n).getNodeEx().asNode() } + + /** DEPRECATED: Use `flowTo` instead. */ + deprecated predicate hasFlowTo = flowTo/1; /** * Holds if data can flow from some source to `sink`. */ - predicate hasFlowToExpr(DataFlowExpr sink) { hasFlowTo(exprNode(sink)) } + predicate flowToExpr(DataFlowExpr sink) { flowTo(exprNode(sink)) } + + /** DEPRECATED: Use `flowToExpr` instead. */ + deprecated predicate hasFlowToExpr = flowToExpr/1; private predicate finalStats( boolean fwd, int nodes, int fields, int conscand, int states, int tuples @@ -4574,7 +4586,7 @@ module Impl<FullStateConfigSig Config> { * * To use this in a `path-problem` query, import the module `PartialPathGraph`. */ - predicate hasPartialFlow(PartialPathNode source, PartialPathNode node, int dist) { + predicate partialFlow(PartialPathNode source, PartialPathNode node, int dist) { partialFlow(source, node) and dist = node.getSourceDistance() } @@ -4594,7 +4606,7 @@ module Impl<FullStateConfigSig Config> { * Note that reverse flow has slightly lower precision than the corresponding * forward flow, as reverse flow disregards type pruning among other features. */ - predicate hasPartialFlowRev(PartialPathNode node, PartialPathNode sink, int dist) { + predicate partialFlowRev(PartialPathNode node, PartialPathNode sink, int dist) { revPartialFlow(node, sink) and dist = node.getSinkDistance() } diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl1.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl1.qll index e6bdc74cceb..8415c022111 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl1.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl1.qll @@ -1,5 +1,5 @@ /** - * DEPRECATED: Use `Make` and `MakeWithState` instead. + * DEPRECATED: Use `Global` and `GlobalWithState` instead. * * Provides a `Configuration` class backwards-compatible interface to the data * flow library. @@ -388,7 +388,7 @@ private predicate hasFlow(Node source, Node sink, Configuration config) { } private predicate hasFlowPath(PathNode source, PathNode sink, Configuration config) { - hasFlowPath(source, sink) and source.getConfiguration() = config + flowPath(source, sink) and source.getConfiguration() = config } private predicate hasFlowTo(Node sink, Configuration config) { hasFlow(_, sink, config) } 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 e6bdc74cceb..8415c022111 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 @@ -1,5 +1,5 @@ /** - * DEPRECATED: Use `Make` and `MakeWithState` instead. + * DEPRECATED: Use `Global` and `GlobalWithState` instead. * * Provides a `Configuration` class backwards-compatible interface to the data * flow library. @@ -388,7 +388,7 @@ private predicate hasFlow(Node source, Node sink, Configuration config) { } private predicate hasFlowPath(PathNode source, PathNode sink, Configuration config) { - hasFlowPath(source, sink) and source.getConfiguration() = config + flowPath(source, sink) and source.getConfiguration() = config } private predicate hasFlowTo(Node sink, Configuration config) { hasFlow(_, sink, config) } 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 e6bdc74cceb..8415c022111 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 @@ -1,5 +1,5 @@ /** - * DEPRECATED: Use `Make` and `MakeWithState` instead. + * DEPRECATED: Use `Global` and `GlobalWithState` instead. * * Provides a `Configuration` class backwards-compatible interface to the data * flow library. @@ -388,7 +388,7 @@ private predicate hasFlow(Node source, Node sink, Configuration config) { } private predicate hasFlowPath(PathNode source, PathNode sink, Configuration config) { - hasFlowPath(source, sink) and source.getConfiguration() = config + flowPath(source, sink) and source.getConfiguration() = config } private predicate hasFlowTo(Node sink, Configuration config) { hasFlow(_, sink, config) } 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 e6bdc74cceb..8415c022111 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 @@ -1,5 +1,5 @@ /** - * DEPRECATED: Use `Make` and `MakeWithState` instead. + * DEPRECATED: Use `Global` and `GlobalWithState` instead. * * Provides a `Configuration` class backwards-compatible interface to the data * flow library. @@ -388,7 +388,7 @@ private predicate hasFlow(Node source, Node sink, Configuration config) { } private predicate hasFlowPath(PathNode source, PathNode sink, Configuration config) { - hasFlowPath(source, sink) and source.getConfiguration() = config + flowPath(source, sink) and source.getConfiguration() = config } private predicate hasFlowTo(Node sink, Configuration config) { hasFlow(_, sink, config) } diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/tainttracking1/TaintTracking.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/tainttracking1/TaintTracking.qll index 7f96fe5e6fb..192a52f44e3 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/tainttracking1/TaintTracking.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/tainttracking1/TaintTracking.qll @@ -35,7 +35,7 @@ private module AddTaintDefaults<DataFlowInternal::FullStateConfigSig Config> imp /** * Constructs a standard taint tracking computation. */ -module Make<DataFlow::ConfigSig Config> implements DataFlow::DataFlowSig { +module Global<DataFlow::ConfigSig Config> implements DataFlow::DataFlowSig { private module Config0 implements DataFlowInternal::FullStateConfigSig { import DataFlowInternal::DefaultState<Config> import Config @@ -48,10 +48,15 @@ module Make<DataFlow::ConfigSig Config> implements DataFlow::DataFlowSig { import DataFlowInternal::Impl<C> } +/** DEPRECATED: Use `Global` instead. */ +deprecated module Make<DataFlow::ConfigSig Config> implements DataFlow::DataFlowSig { + import Global<Config> +} + /** * Constructs a taint tracking computation using flow state. */ -module MakeWithState<DataFlow::StateConfigSig Config> implements DataFlow::DataFlowSig { +module GlobalWithState<DataFlow::StateConfigSig Config> implements DataFlow::DataFlowSig { private module Config0 implements DataFlowInternal::FullStateConfigSig { import Config } @@ -62,3 +67,8 @@ module MakeWithState<DataFlow::StateConfigSig Config> implements DataFlow::DataF import DataFlowInternal::Impl<C> } + +/** DEPRECATED: Use `GlobalWithState` instead. */ +deprecated module MakeWithState<DataFlow::StateConfigSig Config> implements DataFlow::DataFlowSig { + import GlobalWithState<Config> +} diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlow.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlow.qll index 617362ab4f0..82714ed1af6 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlow.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlow.qll @@ -2,7 +2,7 @@ * Provides an implementation of global (interprocedural) data flow. This file * re-exports the local (intraprocedural) data flow analysis from * `DataFlowImplSpecific::Public` and adds a global analysis, mainly exposed - * through the `Make` and `MakeWithState` modules. + * through the `Global` and `GlobalWithState` modules. */ private import DataFlowImplCommon @@ -73,10 +73,10 @@ signature module ConfigSig { */ default FlowFeature getAFeature() { none() } - /** Holds if sources should be grouped in the result of `hasFlowPath`. */ + /** Holds if sources should be grouped in the result of `flowPath`. */ default predicate sourceGrouping(Node source, string sourceGroup) { none() } - /** Holds if sinks should be grouped in the result of `hasFlowPath`. */ + /** Holds if sinks should be grouped in the result of `flowPath`. */ default predicate sinkGrouping(Node sink, string sinkGroup) { none() } /** @@ -166,10 +166,10 @@ signature module StateConfigSig { */ default FlowFeature getAFeature() { none() } - /** Holds if sources should be grouped in the result of `hasFlowPath`. */ + /** Holds if sources should be grouped in the result of `flowPath`. */ default predicate sourceGrouping(Node source, string sourceGroup) { none() } - /** Holds if sinks should be grouped in the result of `hasFlowPath`. */ + /** Holds if sinks should be grouped in the result of `flowPath`. */ default predicate sinkGrouping(Node sink, string sinkGroup) { none() } /** @@ -182,7 +182,7 @@ signature module StateConfigSig { } /** - * Gets the exploration limit for `hasPartialFlow` and `hasPartialFlowRev` + * Gets the exploration limit for `partialFlow` and `partialFlowRev` * measured in approximate number of interprocedural steps. */ signature int explorationLimitSig(); @@ -203,28 +203,28 @@ signature module DataFlowSig { * The corresponding paths are generated from the end-points and the graph * included in the module `PathGraph`. */ - predicate hasFlowPath(PathNode source, PathNode sink); + predicate flowPath(PathNode source, PathNode sink); /** * Holds if data can flow from `source` to `sink`. */ - predicate hasFlow(Node source, Node sink); + predicate flow(Node source, Node sink); /** * Holds if data can flow from some source to `sink`. */ - predicate hasFlowTo(Node sink); + predicate flowTo(Node sink); /** * Holds if data can flow from some source to `sink`. */ - predicate hasFlowToExpr(DataFlowExpr sink); + predicate flowToExpr(DataFlowExpr sink); } /** * Constructs a standard data flow computation. */ -module Make<ConfigSig Config> implements DataFlowSig { +module Global<ConfigSig Config> implements DataFlowSig { private module C implements FullStateConfigSig { import DefaultState<Config> import Config @@ -233,10 +233,15 @@ module Make<ConfigSig Config> implements DataFlowSig { import Impl<C> } +/** DEPRECATED: Use `Global` instead. */ +deprecated module Make<ConfigSig Config> implements DataFlowSig { + import Global<Config> +} + /** * Constructs a data flow computation using flow state. */ -module MakeWithState<StateConfigSig Config> implements DataFlowSig { +module GlobalWithState<StateConfigSig Config> implements DataFlowSig { private module C implements FullStateConfigSig { import Config } @@ -244,6 +249,11 @@ module MakeWithState<StateConfigSig Config> implements DataFlowSig { import Impl<C> } +/** DEPRECATED: Use `GlobalWithState` instead. */ +deprecated module MakeWithState<StateConfigSig Config> implements DataFlowSig { + import GlobalWithState<Config> +} + signature class PathNodeSig { /** Gets a textual representation of this element. */ string 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 c47b0308855..d18ef5acd6e 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl.qll @@ -91,10 +91,10 @@ signature module FullStateConfigSig { */ FlowFeature getAFeature(); - /** Holds if sources should be grouped in the result of `hasFlowPath`. */ + /** Holds if sources should be grouped in the result of `flowPath`. */ predicate sourceGrouping(Node source, string sourceGroup); - /** Holds if sinks should be grouped in the result of `hasFlowPath`. */ + /** Holds if sinks should be grouped in the result of `flowPath`. */ predicate sinkGrouping(Node sink, string sinkGroup); /** @@ -3633,7 +3633,7 @@ module Impl<FullStateConfigSig Config> { * The corresponding paths are generated from the end-points and the graph * included in the module `PathGraph`. */ - predicate hasFlowPath(PathNode source, PathNode sink) { + predicate flowPath(PathNode source, PathNode sink) { exists(PathNodeImpl flowsource, PathNodeImpl flowsink | source = flowsource and sink = flowsink | @@ -3643,6 +3643,9 @@ module Impl<FullStateConfigSig Config> { ) } + /** DEPRECATED: Use `flowPath` instead. */ + deprecated predicate hasFlowPath = flowPath/2; + private predicate flowsTo(PathNodeImpl flowsource, PathNodeSink flowsink, Node source, Node sink) { flowsource.isSource() and flowsource.getNodeEx().asNode() = source and @@ -3653,17 +3656,26 @@ module Impl<FullStateConfigSig Config> { /** * Holds if data can flow from `source` to `sink`. */ - predicate hasFlow(Node source, Node sink) { flowsTo(_, _, source, sink) } + predicate flow(Node source, Node sink) { flowsTo(_, _, source, sink) } + + /** DEPRECATED: Use `flow` instead. */ + deprecated predicate hasFlow = flow/2; /** * Holds if data can flow from some source to `sink`. */ - predicate hasFlowTo(Node sink) { sink = any(PathNodeSink n).getNodeEx().asNode() } + predicate flowTo(Node sink) { sink = any(PathNodeSink n).getNodeEx().asNode() } + + /** DEPRECATED: Use `flowTo` instead. */ + deprecated predicate hasFlowTo = flowTo/1; /** * Holds if data can flow from some source to `sink`. */ - predicate hasFlowToExpr(DataFlowExpr sink) { hasFlowTo(exprNode(sink)) } + predicate flowToExpr(DataFlowExpr sink) { flowTo(exprNode(sink)) } + + /** DEPRECATED: Use `flowToExpr` instead. */ + deprecated predicate hasFlowToExpr = flowToExpr/1; private predicate finalStats( boolean fwd, int nodes, int fields, int conscand, int states, int tuples @@ -4574,7 +4586,7 @@ module Impl<FullStateConfigSig Config> { * * To use this in a `path-problem` query, import the module `PartialPathGraph`. */ - predicate hasPartialFlow(PartialPathNode source, PartialPathNode node, int dist) { + predicate partialFlow(PartialPathNode source, PartialPathNode node, int dist) { partialFlow(source, node) and dist = node.getSourceDistance() } @@ -4594,7 +4606,7 @@ module Impl<FullStateConfigSig Config> { * Note that reverse flow has slightly lower precision than the corresponding * forward flow, as reverse flow disregards type pruning among other features. */ - predicate hasPartialFlowRev(PartialPathNode node, PartialPathNode sink, int dist) { + predicate partialFlowRev(PartialPathNode node, PartialPathNode sink, int dist) { revPartialFlow(node, sink) and dist = node.getSinkDistance() } diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl1.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl1.qll index e6bdc74cceb..8415c022111 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl1.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl1.qll @@ -1,5 +1,5 @@ /** - * DEPRECATED: Use `Make` and `MakeWithState` instead. + * DEPRECATED: Use `Global` and `GlobalWithState` instead. * * Provides a `Configuration` class backwards-compatible interface to the data * flow library. @@ -388,7 +388,7 @@ private predicate hasFlow(Node source, Node sink, Configuration config) { } private predicate hasFlowPath(PathNode source, PathNode sink, Configuration config) { - hasFlowPath(source, sink) and source.getConfiguration() = config + flowPath(source, sink) and source.getConfiguration() = config } private predicate hasFlowTo(Node sink, Configuration config) { hasFlow(_, sink, config) } 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 e6bdc74cceb..8415c022111 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl2.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl2.qll @@ -1,5 +1,5 @@ /** - * DEPRECATED: Use `Make` and `MakeWithState` instead. + * DEPRECATED: Use `Global` and `GlobalWithState` instead. * * Provides a `Configuration` class backwards-compatible interface to the data * flow library. @@ -388,7 +388,7 @@ private predicate hasFlow(Node source, Node sink, Configuration config) { } private predicate hasFlowPath(PathNode source, PathNode sink, Configuration config) { - hasFlowPath(source, sink) and source.getConfiguration() = config + flowPath(source, sink) and source.getConfiguration() = config } private predicate hasFlowTo(Node sink, Configuration config) { hasFlow(_, sink, config) } 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 e6bdc74cceb..8415c022111 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl3.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl3.qll @@ -1,5 +1,5 @@ /** - * DEPRECATED: Use `Make` and `MakeWithState` instead. + * DEPRECATED: Use `Global` and `GlobalWithState` instead. * * Provides a `Configuration` class backwards-compatible interface to the data * flow library. @@ -388,7 +388,7 @@ private predicate hasFlow(Node source, Node sink, Configuration config) { } private predicate hasFlowPath(PathNode source, PathNode sink, Configuration config) { - hasFlowPath(source, sink) and source.getConfiguration() = config + flowPath(source, sink) and source.getConfiguration() = config } private predicate hasFlowTo(Node sink, Configuration config) { hasFlow(_, sink, config) } 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 e6bdc74cceb..8415c022111 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl4.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl4.qll @@ -1,5 +1,5 @@ /** - * DEPRECATED: Use `Make` and `MakeWithState` instead. + * DEPRECATED: Use `Global` and `GlobalWithState` instead. * * Provides a `Configuration` class backwards-compatible interface to the data * flow library. @@ -388,7 +388,7 @@ private predicate hasFlow(Node source, Node sink, Configuration config) { } private predicate hasFlowPath(PathNode source, PathNode sink, Configuration config) { - hasFlowPath(source, sink) and source.getConfiguration() = config + flowPath(source, sink) and source.getConfiguration() = config } private predicate hasFlowTo(Node sink, Configuration config) { hasFlow(_, sink, config) } 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 e6bdc74cceb..8415c022111 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl5.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl5.qll @@ -1,5 +1,5 @@ /** - * DEPRECATED: Use `Make` and `MakeWithState` instead. + * DEPRECATED: Use `Global` and `GlobalWithState` instead. * * Provides a `Configuration` class backwards-compatible interface to the data * flow library. @@ -388,7 +388,7 @@ private predicate hasFlow(Node source, Node sink, Configuration config) { } private predicate hasFlowPath(PathNode source, PathNode sink, Configuration config) { - hasFlowPath(source, sink) and source.getConfiguration() = config + flowPath(source, sink) and source.getConfiguration() = config } private predicate hasFlowTo(Node sink, Configuration config) { hasFlow(_, sink, config) } 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 e6bdc74cceb..8415c022111 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImplForContentDataFlow.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImplForContentDataFlow.qll @@ -1,5 +1,5 @@ /** - * DEPRECATED: Use `Make` and `MakeWithState` instead. + * DEPRECATED: Use `Global` and `GlobalWithState` instead. * * Provides a `Configuration` class backwards-compatible interface to the data * flow library. @@ -388,7 +388,7 @@ private predicate hasFlow(Node source, Node sink, Configuration config) { } private predicate hasFlowPath(PathNode source, PathNode sink, Configuration config) { - hasFlowPath(source, sink) and source.getConfiguration() = config + flowPath(source, sink) and source.getConfiguration() = config } private predicate hasFlowTo(Node sink, Configuration config) { hasFlow(_, sink, config) } diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/tainttracking1/TaintTracking.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/tainttracking1/TaintTracking.qll index 7f96fe5e6fb..192a52f44e3 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/tainttracking1/TaintTracking.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/tainttracking1/TaintTracking.qll @@ -35,7 +35,7 @@ private module AddTaintDefaults<DataFlowInternal::FullStateConfigSig Config> imp /** * Constructs a standard taint tracking computation. */ -module Make<DataFlow::ConfigSig Config> implements DataFlow::DataFlowSig { +module Global<DataFlow::ConfigSig Config> implements DataFlow::DataFlowSig { private module Config0 implements DataFlowInternal::FullStateConfigSig { import DataFlowInternal::DefaultState<Config> import Config @@ -48,10 +48,15 @@ module Make<DataFlow::ConfigSig Config> implements DataFlow::DataFlowSig { import DataFlowInternal::Impl<C> } +/** DEPRECATED: Use `Global` instead. */ +deprecated module Make<DataFlow::ConfigSig Config> implements DataFlow::DataFlowSig { + import Global<Config> +} + /** * Constructs a taint tracking computation using flow state. */ -module MakeWithState<DataFlow::StateConfigSig Config> implements DataFlow::DataFlowSig { +module GlobalWithState<DataFlow::StateConfigSig Config> implements DataFlow::DataFlowSig { private module Config0 implements DataFlowInternal::FullStateConfigSig { import Config } @@ -62,3 +67,8 @@ module MakeWithState<DataFlow::StateConfigSig Config> implements DataFlow::DataF import DataFlowInternal::Impl<C> } + +/** DEPRECATED: Use `GlobalWithState` instead. */ +deprecated module MakeWithState<DataFlow::StateConfigSig Config> implements DataFlow::DataFlowSig { + import GlobalWithState<Config> +} diff --git a/go/ql/lib/semmle/go/dataflow/internal/DataFlow.qll b/go/ql/lib/semmle/go/dataflow/internal/DataFlow.qll index 617362ab4f0..82714ed1af6 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/DataFlow.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/DataFlow.qll @@ -2,7 +2,7 @@ * Provides an implementation of global (interprocedural) data flow. This file * re-exports the local (intraprocedural) data flow analysis from * `DataFlowImplSpecific::Public` and adds a global analysis, mainly exposed - * through the `Make` and `MakeWithState` modules. + * through the `Global` and `GlobalWithState` modules. */ private import DataFlowImplCommon @@ -73,10 +73,10 @@ signature module ConfigSig { */ default FlowFeature getAFeature() { none() } - /** Holds if sources should be grouped in the result of `hasFlowPath`. */ + /** Holds if sources should be grouped in the result of `flowPath`. */ default predicate sourceGrouping(Node source, string sourceGroup) { none() } - /** Holds if sinks should be grouped in the result of `hasFlowPath`. */ + /** Holds if sinks should be grouped in the result of `flowPath`. */ default predicate sinkGrouping(Node sink, string sinkGroup) { none() } /** @@ -166,10 +166,10 @@ signature module StateConfigSig { */ default FlowFeature getAFeature() { none() } - /** Holds if sources should be grouped in the result of `hasFlowPath`. */ + /** Holds if sources should be grouped in the result of `flowPath`. */ default predicate sourceGrouping(Node source, string sourceGroup) { none() } - /** Holds if sinks should be grouped in the result of `hasFlowPath`. */ + /** Holds if sinks should be grouped in the result of `flowPath`. */ default predicate sinkGrouping(Node sink, string sinkGroup) { none() } /** @@ -182,7 +182,7 @@ signature module StateConfigSig { } /** - * Gets the exploration limit for `hasPartialFlow` and `hasPartialFlowRev` + * Gets the exploration limit for `partialFlow` and `partialFlowRev` * measured in approximate number of interprocedural steps. */ signature int explorationLimitSig(); @@ -203,28 +203,28 @@ signature module DataFlowSig { * The corresponding paths are generated from the end-points and the graph * included in the module `PathGraph`. */ - predicate hasFlowPath(PathNode source, PathNode sink); + predicate flowPath(PathNode source, PathNode sink); /** * Holds if data can flow from `source` to `sink`. */ - predicate hasFlow(Node source, Node sink); + predicate flow(Node source, Node sink); /** * Holds if data can flow from some source to `sink`. */ - predicate hasFlowTo(Node sink); + predicate flowTo(Node sink); /** * Holds if data can flow from some source to `sink`. */ - predicate hasFlowToExpr(DataFlowExpr sink); + predicate flowToExpr(DataFlowExpr sink); } /** * Constructs a standard data flow computation. */ -module Make<ConfigSig Config> implements DataFlowSig { +module Global<ConfigSig Config> implements DataFlowSig { private module C implements FullStateConfigSig { import DefaultState<Config> import Config @@ -233,10 +233,15 @@ module Make<ConfigSig Config> implements DataFlowSig { import Impl<C> } +/** DEPRECATED: Use `Global` instead. */ +deprecated module Make<ConfigSig Config> implements DataFlowSig { + import Global<Config> +} + /** * Constructs a data flow computation using flow state. */ -module MakeWithState<StateConfigSig Config> implements DataFlowSig { +module GlobalWithState<StateConfigSig Config> implements DataFlowSig { private module C implements FullStateConfigSig { import Config } @@ -244,6 +249,11 @@ module MakeWithState<StateConfigSig Config> implements DataFlowSig { import Impl<C> } +/** DEPRECATED: Use `GlobalWithState` instead. */ +deprecated module MakeWithState<StateConfigSig Config> implements DataFlowSig { + import GlobalWithState<Config> +} + signature class PathNodeSig { /** Gets a textual representation of this element. */ string toString(); diff --git a/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl.qll b/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl.qll index c47b0308855..d18ef5acd6e 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl.qll @@ -91,10 +91,10 @@ signature module FullStateConfigSig { */ FlowFeature getAFeature(); - /** Holds if sources should be grouped in the result of `hasFlowPath`. */ + /** Holds if sources should be grouped in the result of `flowPath`. */ predicate sourceGrouping(Node source, string sourceGroup); - /** Holds if sinks should be grouped in the result of `hasFlowPath`. */ + /** Holds if sinks should be grouped in the result of `flowPath`. */ predicate sinkGrouping(Node sink, string sinkGroup); /** @@ -3633,7 +3633,7 @@ module Impl<FullStateConfigSig Config> { * The corresponding paths are generated from the end-points and the graph * included in the module `PathGraph`. */ - predicate hasFlowPath(PathNode source, PathNode sink) { + predicate flowPath(PathNode source, PathNode sink) { exists(PathNodeImpl flowsource, PathNodeImpl flowsink | source = flowsource and sink = flowsink | @@ -3643,6 +3643,9 @@ module Impl<FullStateConfigSig Config> { ) } + /** DEPRECATED: Use `flowPath` instead. */ + deprecated predicate hasFlowPath = flowPath/2; + private predicate flowsTo(PathNodeImpl flowsource, PathNodeSink flowsink, Node source, Node sink) { flowsource.isSource() and flowsource.getNodeEx().asNode() = source and @@ -3653,17 +3656,26 @@ module Impl<FullStateConfigSig Config> { /** * Holds if data can flow from `source` to `sink`. */ - predicate hasFlow(Node source, Node sink) { flowsTo(_, _, source, sink) } + predicate flow(Node source, Node sink) { flowsTo(_, _, source, sink) } + + /** DEPRECATED: Use `flow` instead. */ + deprecated predicate hasFlow = flow/2; /** * Holds if data can flow from some source to `sink`. */ - predicate hasFlowTo(Node sink) { sink = any(PathNodeSink n).getNodeEx().asNode() } + predicate flowTo(Node sink) { sink = any(PathNodeSink n).getNodeEx().asNode() } + + /** DEPRECATED: Use `flowTo` instead. */ + deprecated predicate hasFlowTo = flowTo/1; /** * Holds if data can flow from some source to `sink`. */ - predicate hasFlowToExpr(DataFlowExpr sink) { hasFlowTo(exprNode(sink)) } + predicate flowToExpr(DataFlowExpr sink) { flowTo(exprNode(sink)) } + + /** DEPRECATED: Use `flowToExpr` instead. */ + deprecated predicate hasFlowToExpr = flowToExpr/1; private predicate finalStats( boolean fwd, int nodes, int fields, int conscand, int states, int tuples @@ -4574,7 +4586,7 @@ module Impl<FullStateConfigSig Config> { * * To use this in a `path-problem` query, import the module `PartialPathGraph`. */ - predicate hasPartialFlow(PartialPathNode source, PartialPathNode node, int dist) { + predicate partialFlow(PartialPathNode source, PartialPathNode node, int dist) { partialFlow(source, node) and dist = node.getSourceDistance() } @@ -4594,7 +4606,7 @@ module Impl<FullStateConfigSig Config> { * Note that reverse flow has slightly lower precision than the corresponding * forward flow, as reverse flow disregards type pruning among other features. */ - predicate hasPartialFlowRev(PartialPathNode node, PartialPathNode sink, int dist) { + predicate partialFlowRev(PartialPathNode node, PartialPathNode sink, int dist) { revPartialFlow(node, sink) and dist = node.getSinkDistance() } diff --git a/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl1.qll b/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl1.qll index e6bdc74cceb..8415c022111 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl1.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl1.qll @@ -1,5 +1,5 @@ /** - * DEPRECATED: Use `Make` and `MakeWithState` instead. + * DEPRECATED: Use `Global` and `GlobalWithState` instead. * * Provides a `Configuration` class backwards-compatible interface to the data * flow library. @@ -388,7 +388,7 @@ private predicate hasFlow(Node source, Node sink, Configuration config) { } private predicate hasFlowPath(PathNode source, PathNode sink, Configuration config) { - hasFlowPath(source, sink) and source.getConfiguration() = config + flowPath(source, sink) and source.getConfiguration() = config } private predicate hasFlowTo(Node sink, Configuration config) { hasFlow(_, sink, config) } diff --git a/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl2.qll b/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl2.qll index e6bdc74cceb..8415c022111 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl2.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl2.qll @@ -1,5 +1,5 @@ /** - * DEPRECATED: Use `Make` and `MakeWithState` instead. + * DEPRECATED: Use `Global` and `GlobalWithState` instead. * * Provides a `Configuration` class backwards-compatible interface to the data * flow library. @@ -388,7 +388,7 @@ private predicate hasFlow(Node source, Node sink, Configuration config) { } private predicate hasFlowPath(PathNode source, PathNode sink, Configuration config) { - hasFlowPath(source, sink) and source.getConfiguration() = config + flowPath(source, sink) and source.getConfiguration() = config } private predicate hasFlowTo(Node sink, Configuration config) { hasFlow(_, sink, config) } diff --git a/go/ql/lib/semmle/go/dataflow/internal/DataFlowImplForStringsNewReplacer.qll b/go/ql/lib/semmle/go/dataflow/internal/DataFlowImplForStringsNewReplacer.qll index e6bdc74cceb..8415c022111 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/DataFlowImplForStringsNewReplacer.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/DataFlowImplForStringsNewReplacer.qll @@ -1,5 +1,5 @@ /** - * DEPRECATED: Use `Make` and `MakeWithState` instead. + * DEPRECATED: Use `Global` and `GlobalWithState` instead. * * Provides a `Configuration` class backwards-compatible interface to the data * flow library. @@ -388,7 +388,7 @@ private predicate hasFlow(Node source, Node sink, Configuration config) { } private predicate hasFlowPath(PathNode source, PathNode sink, Configuration config) { - hasFlowPath(source, sink) and source.getConfiguration() = config + flowPath(source, sink) and source.getConfiguration() = config } private predicate hasFlowTo(Node sink, Configuration config) { hasFlow(_, sink, config) } diff --git a/go/ql/lib/semmle/go/dataflow/internal/tainttracking1/TaintTracking.qll b/go/ql/lib/semmle/go/dataflow/internal/tainttracking1/TaintTracking.qll index 7f96fe5e6fb..192a52f44e3 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/tainttracking1/TaintTracking.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/tainttracking1/TaintTracking.qll @@ -35,7 +35,7 @@ private module AddTaintDefaults<DataFlowInternal::FullStateConfigSig Config> imp /** * Constructs a standard taint tracking computation. */ -module Make<DataFlow::ConfigSig Config> implements DataFlow::DataFlowSig { +module Global<DataFlow::ConfigSig Config> implements DataFlow::DataFlowSig { private module Config0 implements DataFlowInternal::FullStateConfigSig { import DataFlowInternal::DefaultState<Config> import Config @@ -48,10 +48,15 @@ module Make<DataFlow::ConfigSig Config> implements DataFlow::DataFlowSig { import DataFlowInternal::Impl<C> } +/** DEPRECATED: Use `Global` instead. */ +deprecated module Make<DataFlow::ConfigSig Config> implements DataFlow::DataFlowSig { + import Global<Config> +} + /** * Constructs a taint tracking computation using flow state. */ -module MakeWithState<DataFlow::StateConfigSig Config> implements DataFlow::DataFlowSig { +module GlobalWithState<DataFlow::StateConfigSig Config> implements DataFlow::DataFlowSig { private module Config0 implements DataFlowInternal::FullStateConfigSig { import Config } @@ -62,3 +67,8 @@ module MakeWithState<DataFlow::StateConfigSig Config> implements DataFlow::DataF import DataFlowInternal::Impl<C> } + +/** DEPRECATED: Use `GlobalWithState` instead. */ +deprecated module MakeWithState<DataFlow::StateConfigSig Config> implements DataFlow::DataFlowSig { + import GlobalWithState<Config> +} 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 e6bdc74cceb..8415c022111 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl2.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl2.qll @@ -1,5 +1,5 @@ /** - * DEPRECATED: Use `Make` and `MakeWithState` instead. + * DEPRECATED: Use `Global` and `GlobalWithState` instead. * * Provides a `Configuration` class backwards-compatible interface to the data * flow library. @@ -388,7 +388,7 @@ private predicate hasFlow(Node source, Node sink, Configuration config) { } private predicate hasFlowPath(PathNode source, PathNode sink, Configuration config) { - hasFlowPath(source, sink) and source.getConfiguration() = config + flowPath(source, sink) and source.getConfiguration() = config } private predicate hasFlowTo(Node sink, Configuration config) { hasFlow(_, sink, config) } 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 e6bdc74cceb..8415c022111 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl3.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl3.qll @@ -1,5 +1,5 @@ /** - * DEPRECATED: Use `Make` and `MakeWithState` instead. + * DEPRECATED: Use `Global` and `GlobalWithState` instead. * * Provides a `Configuration` class backwards-compatible interface to the data * flow library. @@ -388,7 +388,7 @@ private predicate hasFlow(Node source, Node sink, Configuration config) { } private predicate hasFlowPath(PathNode source, PathNode sink, Configuration config) { - hasFlowPath(source, sink) and source.getConfiguration() = config + flowPath(source, sink) and source.getConfiguration() = config } private predicate hasFlowTo(Node sink, Configuration config) { hasFlow(_, sink, config) } 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 e6bdc74cceb..8415c022111 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl4.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl4.qll @@ -1,5 +1,5 @@ /** - * DEPRECATED: Use `Make` and `MakeWithState` instead. + * DEPRECATED: Use `Global` and `GlobalWithState` instead. * * Provides a `Configuration` class backwards-compatible interface to the data * flow library. @@ -388,7 +388,7 @@ private predicate hasFlow(Node source, Node sink, Configuration config) { } private predicate hasFlowPath(PathNode source, PathNode sink, Configuration config) { - hasFlowPath(source, sink) and source.getConfiguration() = config + flowPath(source, sink) and source.getConfiguration() = config } private predicate hasFlowTo(Node sink, Configuration config) { hasFlow(_, sink, config) } 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 e6bdc74cceb..8415c022111 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl5.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl5.qll @@ -1,5 +1,5 @@ /** - * DEPRECATED: Use `Make` and `MakeWithState` instead. + * DEPRECATED: Use `Global` and `GlobalWithState` instead. * * Provides a `Configuration` class backwards-compatible interface to the data * flow library. @@ -388,7 +388,7 @@ private predicate hasFlow(Node source, Node sink, Configuration config) { } private predicate hasFlowPath(PathNode source, PathNode sink, Configuration config) { - hasFlowPath(source, sink) and source.getConfiguration() = config + flowPath(source, sink) and source.getConfiguration() = config } private predicate hasFlowTo(Node sink, Configuration config) { hasFlow(_, sink, config) } 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 e6bdc74cceb..8415c022111 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl6.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl6.qll @@ -1,5 +1,5 @@ /** - * DEPRECATED: Use `Make` and `MakeWithState` instead. + * DEPRECATED: Use `Global` and `GlobalWithState` instead. * * Provides a `Configuration` class backwards-compatible interface to the data * flow library. @@ -388,7 +388,7 @@ private predicate hasFlow(Node source, Node sink, Configuration config) { } private predicate hasFlowPath(PathNode source, PathNode sink, Configuration config) { - hasFlowPath(source, sink) and source.getConfiguration() = config + flowPath(source, sink) and source.getConfiguration() = config } private predicate hasFlowTo(Node sink, Configuration config) { hasFlow(_, sink, config) } diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlow.qll b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlow.qll index 617362ab4f0..82714ed1af6 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlow.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlow.qll @@ -2,7 +2,7 @@ * Provides an implementation of global (interprocedural) data flow. This file * re-exports the local (intraprocedural) data flow analysis from * `DataFlowImplSpecific::Public` and adds a global analysis, mainly exposed - * through the `Make` and `MakeWithState` modules. + * through the `Global` and `GlobalWithState` modules. */ private import DataFlowImplCommon @@ -73,10 +73,10 @@ signature module ConfigSig { */ default FlowFeature getAFeature() { none() } - /** Holds if sources should be grouped in the result of `hasFlowPath`. */ + /** Holds if sources should be grouped in the result of `flowPath`. */ default predicate sourceGrouping(Node source, string sourceGroup) { none() } - /** Holds if sinks should be grouped in the result of `hasFlowPath`. */ + /** Holds if sinks should be grouped in the result of `flowPath`. */ default predicate sinkGrouping(Node sink, string sinkGroup) { none() } /** @@ -166,10 +166,10 @@ signature module StateConfigSig { */ default FlowFeature getAFeature() { none() } - /** Holds if sources should be grouped in the result of `hasFlowPath`. */ + /** Holds if sources should be grouped in the result of `flowPath`. */ default predicate sourceGrouping(Node source, string sourceGroup) { none() } - /** Holds if sinks should be grouped in the result of `hasFlowPath`. */ + /** Holds if sinks should be grouped in the result of `flowPath`. */ default predicate sinkGrouping(Node sink, string sinkGroup) { none() } /** @@ -182,7 +182,7 @@ signature module StateConfigSig { } /** - * Gets the exploration limit for `hasPartialFlow` and `hasPartialFlowRev` + * Gets the exploration limit for `partialFlow` and `partialFlowRev` * measured in approximate number of interprocedural steps. */ signature int explorationLimitSig(); @@ -203,28 +203,28 @@ signature module DataFlowSig { * The corresponding paths are generated from the end-points and the graph * included in the module `PathGraph`. */ - predicate hasFlowPath(PathNode source, PathNode sink); + predicate flowPath(PathNode source, PathNode sink); /** * Holds if data can flow from `source` to `sink`. */ - predicate hasFlow(Node source, Node sink); + predicate flow(Node source, Node sink); /** * Holds if data can flow from some source to `sink`. */ - predicate hasFlowTo(Node sink); + predicate flowTo(Node sink); /** * Holds if data can flow from some source to `sink`. */ - predicate hasFlowToExpr(DataFlowExpr sink); + predicate flowToExpr(DataFlowExpr sink); } /** * Constructs a standard data flow computation. */ -module Make<ConfigSig Config> implements DataFlowSig { +module Global<ConfigSig Config> implements DataFlowSig { private module C implements FullStateConfigSig { import DefaultState<Config> import Config @@ -233,10 +233,15 @@ module Make<ConfigSig Config> implements DataFlowSig { import Impl<C> } +/** DEPRECATED: Use `Global` instead. */ +deprecated module Make<ConfigSig Config> implements DataFlowSig { + import Global<Config> +} + /** * Constructs a data flow computation using flow state. */ -module MakeWithState<StateConfigSig Config> implements DataFlowSig { +module GlobalWithState<StateConfigSig Config> implements DataFlowSig { private module C implements FullStateConfigSig { import Config } @@ -244,6 +249,11 @@ module MakeWithState<StateConfigSig Config> implements DataFlowSig { import Impl<C> } +/** DEPRECATED: Use `GlobalWithState` instead. */ +deprecated module MakeWithState<StateConfigSig Config> implements DataFlowSig { + import GlobalWithState<Config> +} + signature class PathNodeSig { /** Gets a textual representation of this element. */ string toString(); 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 c47b0308855..d18ef5acd6e 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl.qll @@ -91,10 +91,10 @@ signature module FullStateConfigSig { */ FlowFeature getAFeature(); - /** Holds if sources should be grouped in the result of `hasFlowPath`. */ + /** Holds if sources should be grouped in the result of `flowPath`. */ predicate sourceGrouping(Node source, string sourceGroup); - /** Holds if sinks should be grouped in the result of `hasFlowPath`. */ + /** Holds if sinks should be grouped in the result of `flowPath`. */ predicate sinkGrouping(Node sink, string sinkGroup); /** @@ -3633,7 +3633,7 @@ module Impl<FullStateConfigSig Config> { * The corresponding paths are generated from the end-points and the graph * included in the module `PathGraph`. */ - predicate hasFlowPath(PathNode source, PathNode sink) { + predicate flowPath(PathNode source, PathNode sink) { exists(PathNodeImpl flowsource, PathNodeImpl flowsink | source = flowsource and sink = flowsink | @@ -3643,6 +3643,9 @@ module Impl<FullStateConfigSig Config> { ) } + /** DEPRECATED: Use `flowPath` instead. */ + deprecated predicate hasFlowPath = flowPath/2; + private predicate flowsTo(PathNodeImpl flowsource, PathNodeSink flowsink, Node source, Node sink) { flowsource.isSource() and flowsource.getNodeEx().asNode() = source and @@ -3653,17 +3656,26 @@ module Impl<FullStateConfigSig Config> { /** * Holds if data can flow from `source` to `sink`. */ - predicate hasFlow(Node source, Node sink) { flowsTo(_, _, source, sink) } + predicate flow(Node source, Node sink) { flowsTo(_, _, source, sink) } + + /** DEPRECATED: Use `flow` instead. */ + deprecated predicate hasFlow = flow/2; /** * Holds if data can flow from some source to `sink`. */ - predicate hasFlowTo(Node sink) { sink = any(PathNodeSink n).getNodeEx().asNode() } + predicate flowTo(Node sink) { sink = any(PathNodeSink n).getNodeEx().asNode() } + + /** DEPRECATED: Use `flowTo` instead. */ + deprecated predicate hasFlowTo = flowTo/1; /** * Holds if data can flow from some source to `sink`. */ - predicate hasFlowToExpr(DataFlowExpr sink) { hasFlowTo(exprNode(sink)) } + predicate flowToExpr(DataFlowExpr sink) { flowTo(exprNode(sink)) } + + /** DEPRECATED: Use `flowToExpr` instead. */ + deprecated predicate hasFlowToExpr = flowToExpr/1; private predicate finalStats( boolean fwd, int nodes, int fields, int conscand, int states, int tuples @@ -4574,7 +4586,7 @@ module Impl<FullStateConfigSig Config> { * * To use this in a `path-problem` query, import the module `PartialPathGraph`. */ - predicate hasPartialFlow(PartialPathNode source, PartialPathNode node, int dist) { + predicate partialFlow(PartialPathNode source, PartialPathNode node, int dist) { partialFlow(source, node) and dist = node.getSourceDistance() } @@ -4594,7 +4606,7 @@ module Impl<FullStateConfigSig Config> { * Note that reverse flow has slightly lower precision than the corresponding * forward flow, as reverse flow disregards type pruning among other features. */ - predicate hasPartialFlowRev(PartialPathNode node, PartialPathNode sink, int dist) { + predicate partialFlowRev(PartialPathNode node, PartialPathNode sink, int dist) { revPartialFlow(node, sink) and dist = node.getSinkDistance() } diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl1.qll b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl1.qll index e6bdc74cceb..8415c022111 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl1.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl1.qll @@ -1,5 +1,5 @@ /** - * DEPRECATED: Use `Make` and `MakeWithState` instead. + * DEPRECATED: Use `Global` and `GlobalWithState` instead. * * Provides a `Configuration` class backwards-compatible interface to the data * flow library. @@ -388,7 +388,7 @@ private predicate hasFlow(Node source, Node sink, Configuration config) { } private predicate hasFlowPath(PathNode source, PathNode sink, Configuration config) { - hasFlowPath(source, sink) and source.getConfiguration() = config + flowPath(source, sink) and source.getConfiguration() = config } private predicate hasFlowTo(Node sink, Configuration config) { hasFlow(_, sink, config) } 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 e6bdc74cceb..8415c022111 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl2.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl2.qll @@ -1,5 +1,5 @@ /** - * DEPRECATED: Use `Make` and `MakeWithState` instead. + * DEPRECATED: Use `Global` and `GlobalWithState` instead. * * Provides a `Configuration` class backwards-compatible interface to the data * flow library. @@ -388,7 +388,7 @@ private predicate hasFlow(Node source, Node sink, Configuration config) { } private predicate hasFlowPath(PathNode source, PathNode sink, Configuration config) { - hasFlowPath(source, sink) and source.getConfiguration() = config + flowPath(source, sink) and source.getConfiguration() = config } private predicate hasFlowTo(Node sink, Configuration config) { hasFlow(_, sink, config) } 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 e6bdc74cceb..8415c022111 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl3.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl3.qll @@ -1,5 +1,5 @@ /** - * DEPRECATED: Use `Make` and `MakeWithState` instead. + * DEPRECATED: Use `Global` and `GlobalWithState` instead. * * Provides a `Configuration` class backwards-compatible interface to the data * flow library. @@ -388,7 +388,7 @@ private predicate hasFlow(Node source, Node sink, Configuration config) { } private predicate hasFlowPath(PathNode source, PathNode sink, Configuration config) { - hasFlowPath(source, sink) and source.getConfiguration() = config + flowPath(source, sink) and source.getConfiguration() = config } private predicate hasFlowTo(Node sink, Configuration config) { hasFlow(_, sink, config) } 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 e6bdc74cceb..8415c022111 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl4.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl4.qll @@ -1,5 +1,5 @@ /** - * DEPRECATED: Use `Make` and `MakeWithState` instead. + * DEPRECATED: Use `Global` and `GlobalWithState` instead. * * Provides a `Configuration` class backwards-compatible interface to the data * flow library. @@ -388,7 +388,7 @@ private predicate hasFlow(Node source, Node sink, Configuration config) { } private predicate hasFlowPath(PathNode source, PathNode sink, Configuration config) { - hasFlowPath(source, sink) and source.getConfiguration() = config + flowPath(source, sink) and source.getConfiguration() = config } private predicate hasFlowTo(Node sink, Configuration config) { hasFlow(_, sink, config) } diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImplForRegExp.qll b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImplForRegExp.qll index e6bdc74cceb..8415c022111 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImplForRegExp.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImplForRegExp.qll @@ -1,5 +1,5 @@ /** - * DEPRECATED: Use `Make` and `MakeWithState` instead. + * DEPRECATED: Use `Global` and `GlobalWithState` instead. * * Provides a `Configuration` class backwards-compatible interface to the data * flow library. @@ -388,7 +388,7 @@ private predicate hasFlow(Node source, Node sink, Configuration config) { } private predicate hasFlowPath(PathNode source, PathNode sink, Configuration config) { - hasFlowPath(source, sink) and source.getConfiguration() = config + flowPath(source, sink) and source.getConfiguration() = config } private predicate hasFlowTo(Node sink, Configuration config) { hasFlow(_, sink, config) } diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/tainttracking1/TaintTracking.qll b/python/ql/lib/semmle/python/dataflow/new/internal/tainttracking1/TaintTracking.qll index 7f96fe5e6fb..192a52f44e3 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/tainttracking1/TaintTracking.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/tainttracking1/TaintTracking.qll @@ -35,7 +35,7 @@ private module AddTaintDefaults<DataFlowInternal::FullStateConfigSig Config> imp /** * Constructs a standard taint tracking computation. */ -module Make<DataFlow::ConfigSig Config> implements DataFlow::DataFlowSig { +module Global<DataFlow::ConfigSig Config> implements DataFlow::DataFlowSig { private module Config0 implements DataFlowInternal::FullStateConfigSig { import DataFlowInternal::DefaultState<Config> import Config @@ -48,10 +48,15 @@ module Make<DataFlow::ConfigSig Config> implements DataFlow::DataFlowSig { import DataFlowInternal::Impl<C> } +/** DEPRECATED: Use `Global` instead. */ +deprecated module Make<DataFlow::ConfigSig Config> implements DataFlow::DataFlowSig { + import Global<Config> +} + /** * Constructs a taint tracking computation using flow state. */ -module MakeWithState<DataFlow::StateConfigSig Config> implements DataFlow::DataFlowSig { +module GlobalWithState<DataFlow::StateConfigSig Config> implements DataFlow::DataFlowSig { private module Config0 implements DataFlowInternal::FullStateConfigSig { import Config } @@ -62,3 +67,8 @@ module MakeWithState<DataFlow::StateConfigSig Config> implements DataFlow::DataF import DataFlowInternal::Impl<C> } + +/** DEPRECATED: Use `GlobalWithState` instead. */ +deprecated module MakeWithState<DataFlow::StateConfigSig Config> implements DataFlow::DataFlowSig { + import GlobalWithState<Config> +} diff --git a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlow.qll b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlow.qll index 617362ab4f0..82714ed1af6 100644 --- a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlow.qll +++ b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlow.qll @@ -2,7 +2,7 @@ * Provides an implementation of global (interprocedural) data flow. This file * re-exports the local (intraprocedural) data flow analysis from * `DataFlowImplSpecific::Public` and adds a global analysis, mainly exposed - * through the `Make` and `MakeWithState` modules. + * through the `Global` and `GlobalWithState` modules. */ private import DataFlowImplCommon @@ -73,10 +73,10 @@ signature module ConfigSig { */ default FlowFeature getAFeature() { none() } - /** Holds if sources should be grouped in the result of `hasFlowPath`. */ + /** Holds if sources should be grouped in the result of `flowPath`. */ default predicate sourceGrouping(Node source, string sourceGroup) { none() } - /** Holds if sinks should be grouped in the result of `hasFlowPath`. */ + /** Holds if sinks should be grouped in the result of `flowPath`. */ default predicate sinkGrouping(Node sink, string sinkGroup) { none() } /** @@ -166,10 +166,10 @@ signature module StateConfigSig { */ default FlowFeature getAFeature() { none() } - /** Holds if sources should be grouped in the result of `hasFlowPath`. */ + /** Holds if sources should be grouped in the result of `flowPath`. */ default predicate sourceGrouping(Node source, string sourceGroup) { none() } - /** Holds if sinks should be grouped in the result of `hasFlowPath`. */ + /** Holds if sinks should be grouped in the result of `flowPath`. */ default predicate sinkGrouping(Node sink, string sinkGroup) { none() } /** @@ -182,7 +182,7 @@ signature module StateConfigSig { } /** - * Gets the exploration limit for `hasPartialFlow` and `hasPartialFlowRev` + * Gets the exploration limit for `partialFlow` and `partialFlowRev` * measured in approximate number of interprocedural steps. */ signature int explorationLimitSig(); @@ -203,28 +203,28 @@ signature module DataFlowSig { * The corresponding paths are generated from the end-points and the graph * included in the module `PathGraph`. */ - predicate hasFlowPath(PathNode source, PathNode sink); + predicate flowPath(PathNode source, PathNode sink); /** * Holds if data can flow from `source` to `sink`. */ - predicate hasFlow(Node source, Node sink); + predicate flow(Node source, Node sink); /** * Holds if data can flow from some source to `sink`. */ - predicate hasFlowTo(Node sink); + predicate flowTo(Node sink); /** * Holds if data can flow from some source to `sink`. */ - predicate hasFlowToExpr(DataFlowExpr sink); + predicate flowToExpr(DataFlowExpr sink); } /** * Constructs a standard data flow computation. */ -module Make<ConfigSig Config> implements DataFlowSig { +module Global<ConfigSig Config> implements DataFlowSig { private module C implements FullStateConfigSig { import DefaultState<Config> import Config @@ -233,10 +233,15 @@ module Make<ConfigSig Config> implements DataFlowSig { import Impl<C> } +/** DEPRECATED: Use `Global` instead. */ +deprecated module Make<ConfigSig Config> implements DataFlowSig { + import Global<Config> +} + /** * Constructs a data flow computation using flow state. */ -module MakeWithState<StateConfigSig Config> implements DataFlowSig { +module GlobalWithState<StateConfigSig Config> implements DataFlowSig { private module C implements FullStateConfigSig { import Config } @@ -244,6 +249,11 @@ module MakeWithState<StateConfigSig Config> implements DataFlowSig { import Impl<C> } +/** DEPRECATED: Use `GlobalWithState` instead. */ +deprecated module MakeWithState<StateConfigSig Config> implements DataFlowSig { + import GlobalWithState<Config> +} + signature class PathNodeSig { /** Gets a textual representation of this element. */ string toString(); diff --git a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl.qll b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl.qll index c47b0308855..d18ef5acd6e 100644 --- a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl.qll +++ b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl.qll @@ -91,10 +91,10 @@ signature module FullStateConfigSig { */ FlowFeature getAFeature(); - /** Holds if sources should be grouped in the result of `hasFlowPath`. */ + /** Holds if sources should be grouped in the result of `flowPath`. */ predicate sourceGrouping(Node source, string sourceGroup); - /** Holds if sinks should be grouped in the result of `hasFlowPath`. */ + /** Holds if sinks should be grouped in the result of `flowPath`. */ predicate sinkGrouping(Node sink, string sinkGroup); /** @@ -3633,7 +3633,7 @@ module Impl<FullStateConfigSig Config> { * The corresponding paths are generated from the end-points and the graph * included in the module `PathGraph`. */ - predicate hasFlowPath(PathNode source, PathNode sink) { + predicate flowPath(PathNode source, PathNode sink) { exists(PathNodeImpl flowsource, PathNodeImpl flowsink | source = flowsource and sink = flowsink | @@ -3643,6 +3643,9 @@ module Impl<FullStateConfigSig Config> { ) } + /** DEPRECATED: Use `flowPath` instead. */ + deprecated predicate hasFlowPath = flowPath/2; + private predicate flowsTo(PathNodeImpl flowsource, PathNodeSink flowsink, Node source, Node sink) { flowsource.isSource() and flowsource.getNodeEx().asNode() = source and @@ -3653,17 +3656,26 @@ module Impl<FullStateConfigSig Config> { /** * Holds if data can flow from `source` to `sink`. */ - predicate hasFlow(Node source, Node sink) { flowsTo(_, _, source, sink) } + predicate flow(Node source, Node sink) { flowsTo(_, _, source, sink) } + + /** DEPRECATED: Use `flow` instead. */ + deprecated predicate hasFlow = flow/2; /** * Holds if data can flow from some source to `sink`. */ - predicate hasFlowTo(Node sink) { sink = any(PathNodeSink n).getNodeEx().asNode() } + predicate flowTo(Node sink) { sink = any(PathNodeSink n).getNodeEx().asNode() } + + /** DEPRECATED: Use `flowTo` instead. */ + deprecated predicate hasFlowTo = flowTo/1; /** * Holds if data can flow from some source to `sink`. */ - predicate hasFlowToExpr(DataFlowExpr sink) { hasFlowTo(exprNode(sink)) } + predicate flowToExpr(DataFlowExpr sink) { flowTo(exprNode(sink)) } + + /** DEPRECATED: Use `flowToExpr` instead. */ + deprecated predicate hasFlowToExpr = flowToExpr/1; private predicate finalStats( boolean fwd, int nodes, int fields, int conscand, int states, int tuples @@ -4574,7 +4586,7 @@ module Impl<FullStateConfigSig Config> { * * To use this in a `path-problem` query, import the module `PartialPathGraph`. */ - predicate hasPartialFlow(PartialPathNode source, PartialPathNode node, int dist) { + predicate partialFlow(PartialPathNode source, PartialPathNode node, int dist) { partialFlow(source, node) and dist = node.getSourceDistance() } @@ -4594,7 +4606,7 @@ module Impl<FullStateConfigSig Config> { * Note that reverse flow has slightly lower precision than the corresponding * forward flow, as reverse flow disregards type pruning among other features. */ - predicate hasPartialFlowRev(PartialPathNode node, PartialPathNode sink, int dist) { + predicate partialFlowRev(PartialPathNode node, PartialPathNode sink, int dist) { revPartialFlow(node, sink) and dist = node.getSinkDistance() } diff --git a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl1.qll b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl1.qll index e6bdc74cceb..8415c022111 100644 --- a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl1.qll +++ b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl1.qll @@ -1,5 +1,5 @@ /** - * DEPRECATED: Use `Make` and `MakeWithState` instead. + * DEPRECATED: Use `Global` and `GlobalWithState` instead. * * Provides a `Configuration` class backwards-compatible interface to the data * flow library. @@ -388,7 +388,7 @@ private predicate hasFlow(Node source, Node sink, Configuration config) { } private predicate hasFlowPath(PathNode source, PathNode sink, Configuration config) { - hasFlowPath(source, sink) and source.getConfiguration() = config + flowPath(source, sink) and source.getConfiguration() = config } private predicate hasFlowTo(Node sink, Configuration config) { hasFlow(_, sink, config) } diff --git a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl2.qll b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl2.qll index e6bdc74cceb..8415c022111 100644 --- a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl2.qll +++ b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl2.qll @@ -1,5 +1,5 @@ /** - * DEPRECATED: Use `Make` and `MakeWithState` instead. + * DEPRECATED: Use `Global` and `GlobalWithState` instead. * * Provides a `Configuration` class backwards-compatible interface to the data * flow library. @@ -388,7 +388,7 @@ private predicate hasFlow(Node source, Node sink, Configuration config) { } private predicate hasFlowPath(PathNode source, PathNode sink, Configuration config) { - hasFlowPath(source, sink) and source.getConfiguration() = config + flowPath(source, sink) and source.getConfiguration() = config } private predicate hasFlowTo(Node sink, Configuration config) { hasFlow(_, sink, config) } diff --git a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImplForHttpClientLibraries.qll b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImplForHttpClientLibraries.qll index e6bdc74cceb..8415c022111 100644 --- a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImplForHttpClientLibraries.qll +++ b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImplForHttpClientLibraries.qll @@ -1,5 +1,5 @@ /** - * DEPRECATED: Use `Make` and `MakeWithState` instead. + * DEPRECATED: Use `Global` and `GlobalWithState` instead. * * Provides a `Configuration` class backwards-compatible interface to the data * flow library. @@ -388,7 +388,7 @@ private predicate hasFlow(Node source, Node sink, Configuration config) { } private predicate hasFlowPath(PathNode source, PathNode sink, Configuration config) { - hasFlowPath(source, sink) and source.getConfiguration() = config + flowPath(source, sink) and source.getConfiguration() = config } private predicate hasFlowTo(Node sink, Configuration config) { hasFlow(_, sink, config) } diff --git a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImplForPathname.qll b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImplForPathname.qll index e6bdc74cceb..8415c022111 100644 --- a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImplForPathname.qll +++ b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImplForPathname.qll @@ -1,5 +1,5 @@ /** - * DEPRECATED: Use `Make` and `MakeWithState` instead. + * DEPRECATED: Use `Global` and `GlobalWithState` instead. * * Provides a `Configuration` class backwards-compatible interface to the data * flow library. @@ -388,7 +388,7 @@ private predicate hasFlow(Node source, Node sink, Configuration config) { } private predicate hasFlowPath(PathNode source, PathNode sink, Configuration config) { - hasFlowPath(source, sink) and source.getConfiguration() = config + flowPath(source, sink) and source.getConfiguration() = config } private predicate hasFlowTo(Node sink, Configuration config) { hasFlow(_, sink, config) } diff --git a/ruby/ql/lib/codeql/ruby/dataflow/internal/tainttracking1/TaintTracking.qll b/ruby/ql/lib/codeql/ruby/dataflow/internal/tainttracking1/TaintTracking.qll index 7f96fe5e6fb..192a52f44e3 100644 --- a/ruby/ql/lib/codeql/ruby/dataflow/internal/tainttracking1/TaintTracking.qll +++ b/ruby/ql/lib/codeql/ruby/dataflow/internal/tainttracking1/TaintTracking.qll @@ -35,7 +35,7 @@ private module AddTaintDefaults<DataFlowInternal::FullStateConfigSig Config> imp /** * Constructs a standard taint tracking computation. */ -module Make<DataFlow::ConfigSig Config> implements DataFlow::DataFlowSig { +module Global<DataFlow::ConfigSig Config> implements DataFlow::DataFlowSig { private module Config0 implements DataFlowInternal::FullStateConfigSig { import DataFlowInternal::DefaultState<Config> import Config @@ -48,10 +48,15 @@ module Make<DataFlow::ConfigSig Config> implements DataFlow::DataFlowSig { import DataFlowInternal::Impl<C> } +/** DEPRECATED: Use `Global` instead. */ +deprecated module Make<DataFlow::ConfigSig Config> implements DataFlow::DataFlowSig { + import Global<Config> +} + /** * Constructs a taint tracking computation using flow state. */ -module MakeWithState<DataFlow::StateConfigSig Config> implements DataFlow::DataFlowSig { +module GlobalWithState<DataFlow::StateConfigSig Config> implements DataFlow::DataFlowSig { private module Config0 implements DataFlowInternal::FullStateConfigSig { import Config } @@ -62,3 +67,8 @@ module MakeWithState<DataFlow::StateConfigSig Config> implements DataFlow::DataF import DataFlowInternal::Impl<C> } + +/** DEPRECATED: Use `GlobalWithState` instead. */ +deprecated module MakeWithState<DataFlow::StateConfigSig Config> implements DataFlow::DataFlowSig { + import GlobalWithState<Config> +} diff --git a/swift/ql/lib/codeql/swift/dataflow/internal/DataFlow.qll b/swift/ql/lib/codeql/swift/dataflow/internal/DataFlow.qll index 617362ab4f0..82714ed1af6 100644 --- a/swift/ql/lib/codeql/swift/dataflow/internal/DataFlow.qll +++ b/swift/ql/lib/codeql/swift/dataflow/internal/DataFlow.qll @@ -2,7 +2,7 @@ * Provides an implementation of global (interprocedural) data flow. This file * re-exports the local (intraprocedural) data flow analysis from * `DataFlowImplSpecific::Public` and adds a global analysis, mainly exposed - * through the `Make` and `MakeWithState` modules. + * through the `Global` and `GlobalWithState` modules. */ private import DataFlowImplCommon @@ -73,10 +73,10 @@ signature module ConfigSig { */ default FlowFeature getAFeature() { none() } - /** Holds if sources should be grouped in the result of `hasFlowPath`. */ + /** Holds if sources should be grouped in the result of `flowPath`. */ default predicate sourceGrouping(Node source, string sourceGroup) { none() } - /** Holds if sinks should be grouped in the result of `hasFlowPath`. */ + /** Holds if sinks should be grouped in the result of `flowPath`. */ default predicate sinkGrouping(Node sink, string sinkGroup) { none() } /** @@ -166,10 +166,10 @@ signature module StateConfigSig { */ default FlowFeature getAFeature() { none() } - /** Holds if sources should be grouped in the result of `hasFlowPath`. */ + /** Holds if sources should be grouped in the result of `flowPath`. */ default predicate sourceGrouping(Node source, string sourceGroup) { none() } - /** Holds if sinks should be grouped in the result of `hasFlowPath`. */ + /** Holds if sinks should be grouped in the result of `flowPath`. */ default predicate sinkGrouping(Node sink, string sinkGroup) { none() } /** @@ -182,7 +182,7 @@ signature module StateConfigSig { } /** - * Gets the exploration limit for `hasPartialFlow` and `hasPartialFlowRev` + * Gets the exploration limit for `partialFlow` and `partialFlowRev` * measured in approximate number of interprocedural steps. */ signature int explorationLimitSig(); @@ -203,28 +203,28 @@ signature module DataFlowSig { * The corresponding paths are generated from the end-points and the graph * included in the module `PathGraph`. */ - predicate hasFlowPath(PathNode source, PathNode sink); + predicate flowPath(PathNode source, PathNode sink); /** * Holds if data can flow from `source` to `sink`. */ - predicate hasFlow(Node source, Node sink); + predicate flow(Node source, Node sink); /** * Holds if data can flow from some source to `sink`. */ - predicate hasFlowTo(Node sink); + predicate flowTo(Node sink); /** * Holds if data can flow from some source to `sink`. */ - predicate hasFlowToExpr(DataFlowExpr sink); + predicate flowToExpr(DataFlowExpr sink); } /** * Constructs a standard data flow computation. */ -module Make<ConfigSig Config> implements DataFlowSig { +module Global<ConfigSig Config> implements DataFlowSig { private module C implements FullStateConfigSig { import DefaultState<Config> import Config @@ -233,10 +233,15 @@ module Make<ConfigSig Config> implements DataFlowSig { import Impl<C> } +/** DEPRECATED: Use `Global` instead. */ +deprecated module Make<ConfigSig Config> implements DataFlowSig { + import Global<Config> +} + /** * Constructs a data flow computation using flow state. */ -module MakeWithState<StateConfigSig Config> implements DataFlowSig { +module GlobalWithState<StateConfigSig Config> implements DataFlowSig { private module C implements FullStateConfigSig { import Config } @@ -244,6 +249,11 @@ module MakeWithState<StateConfigSig Config> implements DataFlowSig { import Impl<C> } +/** DEPRECATED: Use `GlobalWithState` instead. */ +deprecated module MakeWithState<StateConfigSig Config> implements DataFlowSig { + import GlobalWithState<Config> +} + signature class PathNodeSig { /** Gets a textual representation of this element. */ string toString(); diff --git a/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowImpl.qll b/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowImpl.qll index c47b0308855..d18ef5acd6e 100644 --- a/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowImpl.qll +++ b/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowImpl.qll @@ -91,10 +91,10 @@ signature module FullStateConfigSig { */ FlowFeature getAFeature(); - /** Holds if sources should be grouped in the result of `hasFlowPath`. */ + /** Holds if sources should be grouped in the result of `flowPath`. */ predicate sourceGrouping(Node source, string sourceGroup); - /** Holds if sinks should be grouped in the result of `hasFlowPath`. */ + /** Holds if sinks should be grouped in the result of `flowPath`. */ predicate sinkGrouping(Node sink, string sinkGroup); /** @@ -3633,7 +3633,7 @@ module Impl<FullStateConfigSig Config> { * The corresponding paths are generated from the end-points and the graph * included in the module `PathGraph`. */ - predicate hasFlowPath(PathNode source, PathNode sink) { + predicate flowPath(PathNode source, PathNode sink) { exists(PathNodeImpl flowsource, PathNodeImpl flowsink | source = flowsource and sink = flowsink | @@ -3643,6 +3643,9 @@ module Impl<FullStateConfigSig Config> { ) } + /** DEPRECATED: Use `flowPath` instead. */ + deprecated predicate hasFlowPath = flowPath/2; + private predicate flowsTo(PathNodeImpl flowsource, PathNodeSink flowsink, Node source, Node sink) { flowsource.isSource() and flowsource.getNodeEx().asNode() = source and @@ -3653,17 +3656,26 @@ module Impl<FullStateConfigSig Config> { /** * Holds if data can flow from `source` to `sink`. */ - predicate hasFlow(Node source, Node sink) { flowsTo(_, _, source, sink) } + predicate flow(Node source, Node sink) { flowsTo(_, _, source, sink) } + + /** DEPRECATED: Use `flow` instead. */ + deprecated predicate hasFlow = flow/2; /** * Holds if data can flow from some source to `sink`. */ - predicate hasFlowTo(Node sink) { sink = any(PathNodeSink n).getNodeEx().asNode() } + predicate flowTo(Node sink) { sink = any(PathNodeSink n).getNodeEx().asNode() } + + /** DEPRECATED: Use `flowTo` instead. */ + deprecated predicate hasFlowTo = flowTo/1; /** * Holds if data can flow from some source to `sink`. */ - predicate hasFlowToExpr(DataFlowExpr sink) { hasFlowTo(exprNode(sink)) } + predicate flowToExpr(DataFlowExpr sink) { flowTo(exprNode(sink)) } + + /** DEPRECATED: Use `flowToExpr` instead. */ + deprecated predicate hasFlowToExpr = flowToExpr/1; private predicate finalStats( boolean fwd, int nodes, int fields, int conscand, int states, int tuples @@ -4574,7 +4586,7 @@ module Impl<FullStateConfigSig Config> { * * To use this in a `path-problem` query, import the module `PartialPathGraph`. */ - predicate hasPartialFlow(PartialPathNode source, PartialPathNode node, int dist) { + predicate partialFlow(PartialPathNode source, PartialPathNode node, int dist) { partialFlow(source, node) and dist = node.getSourceDistance() } @@ -4594,7 +4606,7 @@ module Impl<FullStateConfigSig Config> { * Note that reverse flow has slightly lower precision than the corresponding * forward flow, as reverse flow disregards type pruning among other features. */ - predicate hasPartialFlowRev(PartialPathNode node, PartialPathNode sink, int dist) { + predicate partialFlowRev(PartialPathNode node, PartialPathNode sink, int dist) { revPartialFlow(node, sink) and dist = node.getSinkDistance() } diff --git a/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowImpl1.qll b/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowImpl1.qll index e6bdc74cceb..8415c022111 100644 --- a/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowImpl1.qll +++ b/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowImpl1.qll @@ -1,5 +1,5 @@ /** - * DEPRECATED: Use `Make` and `MakeWithState` instead. + * DEPRECATED: Use `Global` and `GlobalWithState` instead. * * Provides a `Configuration` class backwards-compatible interface to the data * flow library. @@ -388,7 +388,7 @@ private predicate hasFlow(Node source, Node sink, Configuration config) { } private predicate hasFlowPath(PathNode source, PathNode sink, Configuration config) { - hasFlowPath(source, sink) and source.getConfiguration() = config + flowPath(source, sink) and source.getConfiguration() = config } private predicate hasFlowTo(Node sink, Configuration config) { hasFlow(_, sink, config) } diff --git a/swift/ql/lib/codeql/swift/dataflow/internal/tainttracking1/TaintTracking.qll b/swift/ql/lib/codeql/swift/dataflow/internal/tainttracking1/TaintTracking.qll index 7f96fe5e6fb..192a52f44e3 100644 --- a/swift/ql/lib/codeql/swift/dataflow/internal/tainttracking1/TaintTracking.qll +++ b/swift/ql/lib/codeql/swift/dataflow/internal/tainttracking1/TaintTracking.qll @@ -35,7 +35,7 @@ private module AddTaintDefaults<DataFlowInternal::FullStateConfigSig Config> imp /** * Constructs a standard taint tracking computation. */ -module Make<DataFlow::ConfigSig Config> implements DataFlow::DataFlowSig { +module Global<DataFlow::ConfigSig Config> implements DataFlow::DataFlowSig { private module Config0 implements DataFlowInternal::FullStateConfigSig { import DataFlowInternal::DefaultState<Config> import Config @@ -48,10 +48,15 @@ module Make<DataFlow::ConfigSig Config> implements DataFlow::DataFlowSig { import DataFlowInternal::Impl<C> } +/** DEPRECATED: Use `Global` instead. */ +deprecated module Make<DataFlow::ConfigSig Config> implements DataFlow::DataFlowSig { + import Global<Config> +} + /** * Constructs a taint tracking computation using flow state. */ -module MakeWithState<DataFlow::StateConfigSig Config> implements DataFlow::DataFlowSig { +module GlobalWithState<DataFlow::StateConfigSig Config> implements DataFlow::DataFlowSig { private module Config0 implements DataFlowInternal::FullStateConfigSig { import Config } @@ -62,3 +67,8 @@ module MakeWithState<DataFlow::StateConfigSig Config> implements DataFlow::DataF import DataFlowInternal::Impl<C> } + +/** DEPRECATED: Use `GlobalWithState` instead. */ +deprecated module MakeWithState<DataFlow::StateConfigSig Config> implements DataFlow::DataFlowSig { + import GlobalWithState<Config> +} From ec34d4435951550dc67b3ed3dbdbde9ea56e5549 Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen <aschackmull@github.com> Date: Thu, 23 Mar 2023 11:55:11 +0100 Subject: [PATCH 341/631] Java: Rename references. --- .../frameworks/android/OnActivityResultSource.qll | 4 ++-- .../java/frameworks/google/GoogleHttpClientApi.qll | 4 ++-- .../frameworks/jackson/JacksonSerializability.qll | 4 ++-- .../security/AndroidSensitiveCommunicationQuery.qll | 2 +- .../java/security/ArbitraryApkInstallationQuery.qll | 10 +++++----- .../code/java/security/FragmentInjectionQuery.qll | 2 +- .../IntentUriPermissionManipulationQuery.qll | 2 +- .../semmle/code/java/security/LogInjectionQuery.qll | 2 +- .../code/java/security/RequestForgeryConfig.qll | 2 +- .../code/java/security/RsaWithoutOaepQuery.qll | 2 +- .../code/java/security/SensitiveLoggingQuery.qll | 2 +- .../security/UnsafeContentUriResolutionQuery.qll | 2 +- java/ql/lib/semmle/code/java/security/XSS.qll | 4 ++-- .../lib/semmle/code/java/security/XxeLocalQuery.qll | 2 +- .../lib/semmle/code/java/security/XxeRemoteQuery.qll | 2 +- .../java/security/regexp/PolynomialReDoSQuery.qll | 2 +- java/ql/src/Security/CWE/CWE-022/TaintedPath.ql | 6 +++--- java/ql/src/Security/CWE/CWE-022/TaintedPathLocal.ql | 6 +++--- java/ql/src/Security/CWE/CWE-022/ZipSlip.ql | 4 ++-- java/ql/src/Security/CWE/CWE-078/ExecTaintedLocal.ql | 4 ++-- java/ql/src/Security/CWE/CWE-079/XSS.ql | 4 ++-- java/ql/src/Security/CWE/CWE-079/XSSLocal.ql | 4 ++-- java/ql/src/Security/CWE/CWE-089/SqlConcatenated.ql | 4 ++-- java/ql/src/Security/CWE/CWE-089/SqlTaintedLocal.ql | 4 ++-- java/ql/src/Security/CWE/CWE-090/LdapInjection.ql | 2 +- .../ql/src/Security/CWE/CWE-090/LdapInjectionLib.qll | 2 +- .../Security/CWE/CWE-094/ArbitraryApkInstallation.ql | 2 +- .../Security/CWE/CWE-094/InsecureBeanValidation.ql | 4 ++-- .../ql/src/Security/CWE/CWE-113/ResponseSplitting.ql | 4 ++-- .../Security/CWE/CWE-113/ResponseSplittingLocal.ql | 4 ++-- java/ql/src/Security/CWE/CWE-117/LogInjection.ql | 2 +- .../CWE-129/ImproperValidationOfArrayConstruction.ql | 4 ++-- ...operValidationOfArrayConstructionCodeSpecified.ql | 4 ++-- .../ImproperValidationOfArrayConstructionLocal.ql | 4 ++-- .../CWE/CWE-129/ImproperValidationOfArrayIndex.ql | 4 ++-- .../ImproperValidationOfArrayIndexCodeSpecified.ql | 4 ++-- .../CWE-129/ImproperValidationOfArrayIndexLocal.ql | 4 ++-- .../CWE/CWE-134/ExternallyControlledFormatString.ql | 4 ++-- .../CWE-134/ExternallyControlledFormatStringLocal.ql | 4 ++-- .../ql/src/Security/CWE/CWE-190/ArithmeticTainted.ql | 8 ++++---- .../Security/CWE/CWE-190/ArithmeticTaintedLocal.ql | 8 ++++---- .../Security/CWE/CWE-190/ArithmeticUncontrolled.ql | 8 ++++---- .../CWE/CWE-190/ArithmeticWithExtremeValues.ql | 8 ++++---- .../AndroidWebViewSettingsAllowsContentAccess.ql | 4 ++-- .../CWE/CWE-200/TempDirLocalInformationDisclosure.ql | 8 ++++---- .../src/Security/CWE/CWE-209/StackTraceExposure.ql | 12 ++++++------ .../CWE/CWE-266/IntentUriPermissionManipulation.ql | 2 +- .../CWE/CWE-297/UnsafeHostnameVerification.ql | 4 ++-- .../Security/CWE/CWE-327/BrokenCryptoAlgorithm.ql | 4 ++-- .../CWE/CWE-327/MaybeBrokenCryptoAlgorithm.ql | 4 ++-- .../CWE/CWE-441/UnsafeContentUriResolution.ql | 2 +- .../ql/src/Security/CWE/CWE-470/FragmentInjection.ql | 2 +- java/ql/src/Security/CWE/CWE-532/SensitiveInfoLog.ql | 2 +- java/ql/src/Security/CWE/CWE-601/UrlRedirect.ql | 4 ++-- java/ql/src/Security/CWE/CWE-601/UrlRedirectLocal.ql | 4 ++-- java/ql/src/Security/CWE/CWE-611/XXE.ql | 2 +- java/ql/src/Security/CWE/CWE-611/XXELocal.ql | 2 +- java/ql/src/Security/CWE/CWE-614/InsecureCookie.ql | 4 ++-- java/ql/src/Security/CWE/CWE-643/XPathInjection.ql | 4 ++-- .../src/Security/CWE/CWE-681/NumericCastTainted.ql | 4 ++-- .../Security/CWE/CWE-681/NumericCastTaintedLocal.ql | 4 ++-- java/ql/src/Security/CWE/CWE-730/PolynomialReDoS.ql | 2 +- java/ql/src/Security/CWE/CWE-780/RsaWithoutOaep.ql | 2 +- .../Security/CWE/CWE-807/TaintedPermissionsCheck.ql | 4 ++-- java/ql/src/Security/CWE/CWE-918/RequestForgery.ql | 2 +- .../Security/CWE/CWE-927/SensitiveCommunication.ql | 2 +- java/ql/test/TestUtilities/InlineFlowTest.qll | 8 ++++---- .../library-tests/dataflow/inoutbarriers/test.ql | 8 ++++---- java/ql/test/library-tests/dataflow/partial/test.ql | 4 ++-- .../test/library-tests/dataflow/partial/testRev.ql | 4 ++-- java/ql/test/library-tests/dataflow/state/test.ql | 8 ++++---- .../security/CWE-094/ApkInstallationTest.ql | 2 +- .../query-tests/security/CWE-117/LogInjectionTest.ql | 2 +- .../CWE-266/IntentUriPermissionManipulationTest.ql | 2 +- .../CWE-441/UnsafeContentUriResolutionTest.ql | 2 +- .../security/CWE-470/FragmentInjectionTest.ql | 2 +- .../query-tests/security/CWE-532/SensitiveLogInfo.ql | 2 +- .../query-tests/security/CWE-730/PolynomialReDoS.ql | 2 +- .../security/CWE-780/RsaWithoutOaepTest.ql | 2 +- .../query-tests/security/CWE-918/RequestForgery.ql | 2 +- .../security/CWE-927/SensitiveCommunication.ql | 2 +- 81 files changed, 152 insertions(+), 152 deletions(-) diff --git a/java/ql/lib/semmle/code/java/frameworks/android/OnActivityResultSource.qll b/java/ql/lib/semmle/code/java/frameworks/android/OnActivityResultSource.qll index 8512308f241..c487c6cecc2 100644 --- a/java/ql/lib/semmle/code/java/frameworks/android/OnActivityResultSource.qll +++ b/java/ql/lib/semmle/code/java/frameworks/android/OnActivityResultSource.qll @@ -28,7 +28,7 @@ class OnActivityResultIncomingIntent extends DataFlow::Node { */ predicate isRemoteSource() { exists(RefType startingType, Expr startActivityForResultArg | - ImplicitStartActivityForResult::hasFlowToExpr(startActivityForResultArg) and + ImplicitStartActivityForResult::flowToExpr(startActivityForResultArg) and // startingType is the class enclosing the method that calls `startActivityForResult`. startingType = startActivityForResultArg.getEnclosingCallable().getDeclaringType() | @@ -104,7 +104,7 @@ private module ImplicitStartActivityForResultConfig implements DataFlow::ConfigS } private module ImplicitStartActivityForResult = - DataFlow::Make<ImplicitStartActivityForResultConfig>; + DataFlow::Global<ImplicitStartActivityForResultConfig>; /** An Android Activity or Fragment. */ private class ActivityOrFragment extends Class { diff --git a/java/ql/lib/semmle/code/java/frameworks/google/GoogleHttpClientApi.qll b/java/ql/lib/semmle/code/java/frameworks/google/GoogleHttpClientApi.qll index 72516e5427e..2793f1980c5 100644 --- a/java/ql/lib/semmle/code/java/frameworks/google/GoogleHttpClientApi.qll +++ b/java/ql/lib/semmle/code/java/frameworks/google/GoogleHttpClientApi.qll @@ -21,10 +21,10 @@ private module TypeLiteralToParseAsFlowConfig implements DataFlow::ConfigSig { } } -private module TypeLiteralToParseAsFlow = DataFlow::Make<TypeLiteralToParseAsFlowConfig>; +private module TypeLiteralToParseAsFlow = DataFlow::Global<TypeLiteralToParseAsFlowConfig>; private TypeLiteral getSourceWithFlowToParseAs() { - TypeLiteralToParseAsFlow::hasFlow(DataFlow::exprNode(result), _) + TypeLiteralToParseAsFlow::flow(DataFlow::exprNode(result), _) } /** A field that is deserialized by `HttpResponse.parseAs`. */ 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 e26d2312f1b..79fd19f4ef2 100644 --- a/java/ql/lib/semmle/code/java/frameworks/jackson/JacksonSerializability.qll +++ b/java/ql/lib/semmle/code/java/frameworks/jackson/JacksonSerializability.qll @@ -108,10 +108,10 @@ private module TypeLiteralToJacksonDatabindFlowConfig implements DataFlow::Confi } private module TypeLiteralToJacksonDatabindFlow = - DataFlow::Make<TypeLiteralToJacksonDatabindFlowConfig>; + DataFlow::Global<TypeLiteralToJacksonDatabindFlowConfig>; private TypeLiteral getSourceWithFlowToJacksonDatabind() { - TypeLiteralToJacksonDatabindFlow::hasFlow(DataFlow::exprNode(result), _) + TypeLiteralToJacksonDatabindFlow::flow(DataFlow::exprNode(result), _) } /** A type whose values are explicitly deserialized in a call to a Jackson method. */ diff --git a/java/ql/lib/semmle/code/java/security/AndroidSensitiveCommunicationQuery.qll b/java/ql/lib/semmle/code/java/security/AndroidSensitiveCommunicationQuery.qll index 2855f5989cf..e0c9fbff800 100644 --- a/java/ql/lib/semmle/code/java/security/AndroidSensitiveCommunicationQuery.qll +++ b/java/ql/lib/semmle/code/java/security/AndroidSensitiveCommunicationQuery.qll @@ -173,4 +173,4 @@ private module SensitiveCommunicationConfig implements DataFlow::ConfigSig { /** * Tracks taint flow from variables containing sensitive information to broadcast Intents. */ -module SensitiveCommunicationFlow = TaintTracking::Make<SensitiveCommunicationConfig>; +module SensitiveCommunicationFlow = TaintTracking::Global<SensitiveCommunicationConfig>; diff --git a/java/ql/lib/semmle/code/java/security/ArbitraryApkInstallationQuery.qll b/java/ql/lib/semmle/code/java/security/ArbitraryApkInstallationQuery.qll index 68b16f7f902..c44db421301 100644 --- a/java/ql/lib/semmle/code/java/security/ArbitraryApkInstallationQuery.qll +++ b/java/ql/lib/semmle/code/java/security/ArbitraryApkInstallationQuery.qll @@ -17,15 +17,15 @@ private module ApkInstallationConfig implements DataFlow::ConfigSig { ma.getMethod() instanceof SetDataMethod and ma.getArgument(0) = node.asExpr() and ( - PackageArchiveMimeTypeFlow::hasFlowToExpr(ma.getQualifier()) + PackageArchiveMimeTypeFlow::flowToExpr(ma.getQualifier()) or - InstallPackageActionFlow::hasFlowToExpr(ma.getQualifier()) + InstallPackageActionFlow::flowToExpr(ma.getQualifier()) ) ) } } -module ApkInstallationFlow = DataFlow::Make<ApkInstallationConfig>; +module ApkInstallationFlow = DataFlow::Global<ApkInstallationConfig>; private newtype ActionState = ActionUnset() or @@ -72,7 +72,7 @@ private module InstallPackageActionConfig implements DataFlow::StateConfigSig { predicate isBarrier(DataFlow::Node node, FlowState state) { none() } } -private module InstallPackageActionFlow = TaintTracking::MakeWithState<InstallPackageActionConfig>; +private module InstallPackageActionFlow = TaintTracking::GlobalWithState<InstallPackageActionConfig>; private newtype MimeTypeState = MimeTypeUnset() or @@ -117,4 +117,4 @@ private module PackageArchiveMimeTypeConfig implements DataFlow::StateConfigSig } private module PackageArchiveMimeTypeFlow = - TaintTracking::MakeWithState<PackageArchiveMimeTypeConfig>; + TaintTracking::GlobalWithState<PackageArchiveMimeTypeConfig>; diff --git a/java/ql/lib/semmle/code/java/security/FragmentInjectionQuery.qll b/java/ql/lib/semmle/code/java/security/FragmentInjectionQuery.qll index 7564993c1ed..94b1877a4a3 100644 --- a/java/ql/lib/semmle/code/java/security/FragmentInjectionQuery.qll +++ b/java/ql/lib/semmle/code/java/security/FragmentInjectionQuery.qll @@ -37,4 +37,4 @@ private module FragmentInjectionTaintConfig implements DataFlow::ConfigSig { * Taint-tracking flow for unsafe user input * that is used to create Android fragments dynamically. */ -module FragmentInjectionTaintFlow = TaintTracking::Make<FragmentInjectionTaintConfig>; +module FragmentInjectionTaintFlow = TaintTracking::Global<FragmentInjectionTaintConfig>; diff --git a/java/ql/lib/semmle/code/java/security/IntentUriPermissionManipulationQuery.qll b/java/ql/lib/semmle/code/java/security/IntentUriPermissionManipulationQuery.qll index d23a0c8ae4b..970cb4867fd 100644 --- a/java/ql/lib/semmle/code/java/security/IntentUriPermissionManipulationQuery.qll +++ b/java/ql/lib/semmle/code/java/security/IntentUriPermissionManipulationQuery.qll @@ -53,4 +53,4 @@ private module IntentUriPermissionManipulationConfig implements DataFlow::Config * Taint tracking flow for user-provided Intents being returned to third party apps. */ module IntentUriPermissionManipulationFlow = - TaintTracking::Make<IntentUriPermissionManipulationConfig>; + TaintTracking::Global<IntentUriPermissionManipulationConfig>; diff --git a/java/ql/lib/semmle/code/java/security/LogInjectionQuery.qll b/java/ql/lib/semmle/code/java/security/LogInjectionQuery.qll index a706da71e50..a26e08d3edc 100644 --- a/java/ql/lib/semmle/code/java/security/LogInjectionQuery.qll +++ b/java/ql/lib/semmle/code/java/security/LogInjectionQuery.qll @@ -38,4 +38,4 @@ private module LogInjectionConfig implements DataFlow::ConfigSig { /** * Taint-tracking flow for tracking untrusted user input used in log entries. */ -module LogInjectionFlow = TaintTracking::Make<LogInjectionConfig>; +module LogInjectionFlow = TaintTracking::Global<LogInjectionConfig>; diff --git a/java/ql/lib/semmle/code/java/security/RequestForgeryConfig.qll b/java/ql/lib/semmle/code/java/security/RequestForgeryConfig.qll index 1f19d9640e2..9d1f9b5081e 100644 --- a/java/ql/lib/semmle/code/java/security/RequestForgeryConfig.qll +++ b/java/ql/lib/semmle/code/java/security/RequestForgeryConfig.qll @@ -53,4 +53,4 @@ private module RequestForgeryConfig implements DataFlow::ConfigSig { predicate isBarrier(DataFlow::Node node) { node instanceof RequestForgerySanitizer } } -module RequestForgeryFlow = TaintTracking::Make<RequestForgeryConfig>; +module RequestForgeryFlow = TaintTracking::Global<RequestForgeryConfig>; diff --git a/java/ql/lib/semmle/code/java/security/RsaWithoutOaepQuery.qll b/java/ql/lib/semmle/code/java/security/RsaWithoutOaepQuery.qll index e7888afba5d..0d9df09bb74 100644 --- a/java/ql/lib/semmle/code/java/security/RsaWithoutOaepQuery.qll +++ b/java/ql/lib/semmle/code/java/security/RsaWithoutOaepQuery.qll @@ -42,4 +42,4 @@ private module RsaWithoutOaepConfig implements DataFlow::ConfigSig { } /** Flow for finding RSA ciphers initialized without using OAEP padding. */ -module RsaWithoutOaepFlow = DataFlow::Make<RsaWithoutOaepConfig>; +module RsaWithoutOaepFlow = DataFlow::Global<RsaWithoutOaepConfig>; diff --git a/java/ql/lib/semmle/code/java/security/SensitiveLoggingQuery.qll b/java/ql/lib/semmle/code/java/security/SensitiveLoggingQuery.qll index 2ca0c4b69c0..ea687d32a0a 100644 --- a/java/ql/lib/semmle/code/java/security/SensitiveLoggingQuery.qll +++ b/java/ql/lib/semmle/code/java/security/SensitiveLoggingQuery.qll @@ -65,4 +65,4 @@ private module SensitiveLoggerConfig implements DataFlow::ConfigSig { predicate isBarrierIn(Node node) { isSource(node) } } -module SensitiveLoggerFlow = TaintTracking::Make<SensitiveLoggerConfig>; +module SensitiveLoggerFlow = TaintTracking::Global<SensitiveLoggerConfig>; diff --git a/java/ql/lib/semmle/code/java/security/UnsafeContentUriResolutionQuery.qll b/java/ql/lib/semmle/code/java/security/UnsafeContentUriResolutionQuery.qll index f347f98c9c3..b59c4b79655 100644 --- a/java/ql/lib/semmle/code/java/security/UnsafeContentUriResolutionQuery.qll +++ b/java/ql/lib/semmle/code/java/security/UnsafeContentUriResolutionQuery.qll @@ -41,4 +41,4 @@ private module UnsafeContentResolutionConfig implements DataFlow::ConfigSig { } /** Taint-tracking flow to find paths from remote sources to content URI resolutions. */ -module UnsafeContentResolutionFlow = TaintTracking::Make<UnsafeContentResolutionConfig>; +module UnsafeContentResolutionFlow = TaintTracking::Global<UnsafeContentResolutionConfig>; diff --git a/java/ql/lib/semmle/code/java/security/XSS.qll b/java/ql/lib/semmle/code/java/security/XSS.qll index a2efc852fd2..2680631318f 100644 --- a/java/ql/lib/semmle/code/java/security/XSS.qll +++ b/java/ql/lib/semmle/code/java/security/XSS.qll @@ -43,7 +43,7 @@ private class DefaultXssSink extends XssSink { or exists(MethodAccess ma | ma.getMethod() instanceof WritingMethod and - XssVulnerableWriterSourceToWritingMethodFlow::hasFlowToExpr(ma.getQualifier()) and + XssVulnerableWriterSourceToWritingMethodFlow::flowToExpr(ma.getQualifier()) and this.asExpr() = ma.getArgument(_) ) } @@ -71,7 +71,7 @@ private module XssVulnerableWriterSourceToWritingMethodFlowConfig implements Dat } private module XssVulnerableWriterSourceToWritingMethodFlow = - TaintTracking::Make<XssVulnerableWriterSourceToWritingMethodFlowConfig>; + TaintTracking::Global<XssVulnerableWriterSourceToWritingMethodFlowConfig>; /** A method that can be used to output data to an output stream or writer. */ private class WritingMethod extends Method { diff --git a/java/ql/lib/semmle/code/java/security/XxeLocalQuery.qll b/java/ql/lib/semmle/code/java/security/XxeLocalQuery.qll index 02d68fceb5c..d3ac09798a6 100644 --- a/java/ql/lib/semmle/code/java/security/XxeLocalQuery.qll +++ b/java/ql/lib/semmle/code/java/security/XxeLocalQuery.qll @@ -42,4 +42,4 @@ module XxeLocalConfig implements DataFlow::ConfigSig { /** * Detect taint flow of unvalidated local user input that is used in XML external entity expansion. */ -module XxeLocalFlow = TaintTracking::Make<XxeLocalConfig>; +module XxeLocalFlow = TaintTracking::Global<XxeLocalConfig>; diff --git a/java/ql/lib/semmle/code/java/security/XxeRemoteQuery.qll b/java/ql/lib/semmle/code/java/security/XxeRemoteQuery.qll index 46108b7a680..06bccc993a4 100644 --- a/java/ql/lib/semmle/code/java/security/XxeRemoteQuery.qll +++ b/java/ql/lib/semmle/code/java/security/XxeRemoteQuery.qll @@ -42,4 +42,4 @@ module XxeConfig implements DataFlow::ConfigSig { /** * Detect taint flow of unvalidated remote user input that is used in XML external entity expansion. */ -module XxeFlow = TaintTracking::Make<XxeConfig>; +module XxeFlow = TaintTracking::Global<XxeConfig>; 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 b852c8393fb..e85e130e381 100644 --- a/java/ql/lib/semmle/code/java/security/regexp/PolynomialReDoSQuery.qll +++ b/java/ql/lib/semmle/code/java/security/regexp/PolynomialReDoSQuery.qll @@ -81,4 +81,4 @@ private module PolynomialRedosConfig implements DataFlow::ConfigSig { } } -module PolynomialRedosFlow = TaintTracking::Make<PolynomialRedosConfig>; +module PolynomialRedosFlow = TaintTracking::Global<PolynomialRedosConfig>; diff --git a/java/ql/src/Security/CWE/CWE-022/TaintedPath.ql b/java/ql/src/Security/CWE/CWE-022/TaintedPath.ql index c7c3ce0f835..4058978f29a 100644 --- a/java/ql/src/Security/CWE/CWE-022/TaintedPath.ql +++ b/java/ql/src/Security/CWE/CWE-022/TaintedPath.ql @@ -41,7 +41,7 @@ module TaintedPathConfig implements DataFlow::ConfigSig { } } -module TaintedPath = TaintTracking::Make<TaintedPathConfig>; +module TaintedPath = TaintTracking::Global<TaintedPathConfig>; import TaintedPath::PathGraph @@ -53,13 +53,13 @@ import TaintedPath::PathGraph * continue to report there; otherwise we report directly at `sink`. */ DataFlow::Node getReportingNode(DataFlow::Node sink) { - TaintedPath::hasFlowTo(sink) and + TaintedPath::flowTo(sink) and if exists(PathCreation pc | pc.getAnInput() = sink.asExpr()) then result.asExpr() = any(PathCreation pc | pc.getAnInput() = sink.asExpr()) else result = sink } from TaintedPath::PathNode source, TaintedPath::PathNode sink -where TaintedPath::hasFlowPath(source, sink) +where TaintedPath::flowPath(source, sink) select getReportingNode(sink.getNode()), source, sink, "This path depends on a $@.", source.getNode(), "user-provided value" diff --git a/java/ql/src/Security/CWE/CWE-022/TaintedPathLocal.ql b/java/ql/src/Security/CWE/CWE-022/TaintedPathLocal.ql index fa62e4e6dfd..94c2b0e68a0 100644 --- a/java/ql/src/Security/CWE/CWE-022/TaintedPathLocal.ql +++ b/java/ql/src/Security/CWE/CWE-022/TaintedPathLocal.ql @@ -41,7 +41,7 @@ module TaintedPathLocalConfig implements DataFlow::ConfigSig { } } -module TaintedPathLocalFlow = TaintTracking::Make<TaintedPathLocalConfig>; +module TaintedPathLocalFlow = TaintTracking::Global<TaintedPathLocalConfig>; import TaintedPathLocalFlow::PathGraph @@ -53,13 +53,13 @@ import TaintedPathLocalFlow::PathGraph * continue to report there; otherwise we report directly at `sink`. */ DataFlow::Node getReportingNode(DataFlow::Node sink) { - TaintedPathLocalFlow::hasFlowTo(sink) and + TaintedPathLocalFlow::flowTo(sink) and if exists(PathCreation pc | pc.getAnInput() = sink.asExpr()) then result.asExpr() = any(PathCreation pc | pc.getAnInput() = sink.asExpr()) else result = sink } from TaintedPathLocalFlow::PathNode source, TaintedPathLocalFlow::PathNode sink -where TaintedPathLocalFlow::hasFlowPath(source, sink) +where TaintedPathLocalFlow::flowPath(source, sink) select getReportingNode(sink.getNode()), source, sink, "This path depends on a $@.", source.getNode(), "user-provided value" diff --git a/java/ql/src/Security/CWE/CWE-022/ZipSlip.ql b/java/ql/src/Security/CWE/CWE-022/ZipSlip.ql index bae6311f362..b1afdfe65a4 100644 --- a/java/ql/src/Security/CWE/CWE-022/ZipSlip.ql +++ b/java/ql/src/Security/CWE/CWE-022/ZipSlip.ql @@ -44,7 +44,7 @@ module ZipSlipConfig implements DataFlow::ConfigSig { predicate isBarrier(DataFlow::Node node) { node instanceof PathInjectionSanitizer } } -module ZipSlipFlow = TaintTracking::Make<ZipSlipConfig>; +module ZipSlipFlow = TaintTracking::Global<ZipSlipConfig>; import ZipSlipFlow::PathGraph @@ -56,7 +56,7 @@ private class FileCreationSink extends DataFlow::Node { } from ZipSlipFlow::PathNode source, ZipSlipFlow::PathNode sink -where ZipSlipFlow::hasFlowPath(source, sink) +where ZipSlipFlow::flowPath(source, sink) select source.getNode(), source, sink, "Unsanitized archive entry, which may contain '..', is used in a $@.", sink.getNode(), "file system operation" diff --git a/java/ql/src/Security/CWE/CWE-078/ExecTaintedLocal.ql b/java/ql/src/Security/CWE/CWE-078/ExecTaintedLocal.ql index e8a80e372b7..5289ac39a9b 100644 --- a/java/ql/src/Security/CWE/CWE-078/ExecTaintedLocal.ql +++ b/java/ql/src/Security/CWE/CWE-078/ExecTaintedLocal.ql @@ -32,7 +32,7 @@ module LocalUserInputToArgumentToExecFlowConfig implements DataFlow::ConfigSig { } module LocalUserInputToArgumentToExecFlow = - TaintTracking::Make<LocalUserInputToArgumentToExecFlowConfig>; + TaintTracking::Global<LocalUserInputToArgumentToExecFlowConfig>; import LocalUserInputToArgumentToExecFlow::PathGraph @@ -40,7 +40,7 @@ from LocalUserInputToArgumentToExecFlow::PathNode source, LocalUserInputToArgumentToExecFlow::PathNode sink, ArgumentToExec execArg where - LocalUserInputToArgumentToExecFlow::hasFlowPath(source, sink) and + LocalUserInputToArgumentToExecFlow::flowPath(source, sink) and sink.getNode().asExpr() = execArg select execArg, source, sink, "This command line depends on a $@.", source.getNode(), "user-provided value" diff --git a/java/ql/src/Security/CWE/CWE-079/XSS.ql b/java/ql/src/Security/CWE/CWE-079/XSS.ql index f2b0a65f9fe..dbec746eaf6 100644 --- a/java/ql/src/Security/CWE/CWE-079/XSS.ql +++ b/java/ql/src/Security/CWE/CWE-079/XSS.ql @@ -29,11 +29,11 @@ module XssConfig implements DataFlow::ConfigSig { } } -module XssFlow = TaintTracking::Make<XssConfig>; +module XssFlow = TaintTracking::Global<XssConfig>; import XssFlow::PathGraph from XssFlow::PathNode source, XssFlow::PathNode sink -where XssFlow::hasFlowPath(source, sink) +where XssFlow::flowPath(source, sink) select sink.getNode(), source, sink, "Cross-site scripting vulnerability due to a $@.", source.getNode(), "user-provided value" diff --git a/java/ql/src/Security/CWE/CWE-079/XSSLocal.ql b/java/ql/src/Security/CWE/CWE-079/XSSLocal.ql index fd9c397f812..90bd2dccc44 100644 --- a/java/ql/src/Security/CWE/CWE-079/XSSLocal.ql +++ b/java/ql/src/Security/CWE/CWE-079/XSSLocal.ql @@ -21,11 +21,11 @@ module XssLocalConfig implements DataFlow::ConfigSig { predicate isSink(DataFlow::Node sink) { sink instanceof XssSink } } -module XssLocalFlow = TaintTracking::Make<XssLocalConfig>; +module XssLocalFlow = TaintTracking::Global<XssLocalConfig>; import XssLocalFlow::PathGraph from XssLocalFlow::PathNode source, XssLocalFlow::PathNode sink -where XssLocalFlow::hasFlowPath(source, sink) +where XssLocalFlow::flowPath(source, sink) select sink.getNode(), source, sink, "Cross-site scripting vulnerability due to $@.", source.getNode(), "user-provided value" diff --git a/java/ql/src/Security/CWE/CWE-089/SqlConcatenated.ql b/java/ql/src/Security/CWE/CWE-089/SqlConcatenated.ql index 209d778dca8..87f478de979 100644 --- a/java/ql/src/Security/CWE/CWE-089/SqlConcatenated.ql +++ b/java/ql/src/Security/CWE/CWE-089/SqlConcatenated.ql @@ -36,7 +36,7 @@ module UncontrolledStringBuilderSourceFlowConfig implements DataFlow::ConfigSig } module UncontrolledStringBuilderSourceFlow = - TaintTracking::Make<UncontrolledStringBuilderSourceFlowConfig>; + TaintTracking::Global<UncontrolledStringBuilderSourceFlowConfig>; from QueryInjectionSink query, Expr uncontrolled where @@ -45,7 +45,7 @@ where or exists(StringBuilderVar sbv | uncontrolledStringBuilderQuery(sbv, uncontrolled) and - UncontrolledStringBuilderSourceFlow::hasFlow(DataFlow::exprNode(sbv.getToStringCall()), query) + UncontrolledStringBuilderSourceFlow::flow(DataFlow::exprNode(sbv.getToStringCall()), query) ) ) and not queryTaintedBy(query, _, _) diff --git a/java/ql/src/Security/CWE/CWE-089/SqlTaintedLocal.ql b/java/ql/src/Security/CWE/CWE-089/SqlTaintedLocal.ql index 0ad803533c5..34e322247c9 100644 --- a/java/ql/src/Security/CWE/CWE-089/SqlTaintedLocal.ql +++ b/java/ql/src/Security/CWE/CWE-089/SqlTaintedLocal.ql @@ -31,13 +31,13 @@ module LocalUserInputToQueryInjectionFlowConfig implements DataFlow::ConfigSig { } module LocalUserInputToQueryInjectionFlow = - TaintTracking::Make<LocalUserInputToQueryInjectionFlowConfig>; + TaintTracking::Global<LocalUserInputToQueryInjectionFlowConfig>; import LocalUserInputToQueryInjectionFlow::PathGraph from LocalUserInputToQueryInjectionFlow::PathNode source, LocalUserInputToQueryInjectionFlow::PathNode sink -where LocalUserInputToQueryInjectionFlow::hasFlowPath(source, sink) +where LocalUserInputToQueryInjectionFlow::flowPath(source, sink) select sink.getNode(), source, sink, "This query depends on a $@.", source.getNode(), "user-provided value" diff --git a/java/ql/src/Security/CWE/CWE-090/LdapInjection.ql b/java/ql/src/Security/CWE/CWE-090/LdapInjection.ql index 66371f161ca..e879a33051d 100644 --- a/java/ql/src/Security/CWE/CWE-090/LdapInjection.ql +++ b/java/ql/src/Security/CWE/CWE-090/LdapInjection.ql @@ -17,6 +17,6 @@ import LdapInjectionLib import LdapInjectionFlow::PathGraph from LdapInjectionFlow::PathNode source, LdapInjectionFlow::PathNode sink -where LdapInjectionFlow::hasFlowPath(source, sink) +where LdapInjectionFlow::flowPath(source, sink) select sink.getNode(), source, sink, "This LDAP query depends on a $@.", source.getNode(), "user-provided value" diff --git a/java/ql/src/Security/CWE/CWE-090/LdapInjectionLib.qll b/java/ql/src/Security/CWE/CWE-090/LdapInjectionLib.qll index d682e4902d8..d6ca8b1169d 100644 --- a/java/ql/src/Security/CWE/CWE-090/LdapInjectionLib.qll +++ b/java/ql/src/Security/CWE/CWE-090/LdapInjectionLib.qll @@ -17,4 +17,4 @@ module LdapInjectionFlowConfig implements DataFlow::ConfigSig { } } -module LdapInjectionFlow = TaintTracking::Make<LdapInjectionFlowConfig>; +module LdapInjectionFlow = TaintTracking::Global<LdapInjectionFlowConfig>; diff --git a/java/ql/src/Security/CWE/CWE-094/ArbitraryApkInstallation.ql b/java/ql/src/Security/CWE/CWE-094/ArbitraryApkInstallation.ql index aab75a8d368..3255ac99bd6 100644 --- a/java/ql/src/Security/CWE/CWE-094/ArbitraryApkInstallation.ql +++ b/java/ql/src/Security/CWE/CWE-094/ArbitraryApkInstallation.ql @@ -15,5 +15,5 @@ import semmle.code.java.security.ArbitraryApkInstallationQuery import ApkInstallationFlow::PathGraph from ApkInstallationFlow::PathNode source, ApkInstallationFlow::PathNode sink -where ApkInstallationFlow::hasFlowPath(source, sink) +where ApkInstallationFlow::flowPath(source, sink) select sink.getNode(), source, sink, "Arbitrary Android APK installation." diff --git a/java/ql/src/Security/CWE/CWE-094/InsecureBeanValidation.ql b/java/ql/src/Security/CWE/CWE-094/InsecureBeanValidation.ql index c3a991ddcd5..5e957f23793 100644 --- a/java/ql/src/Security/CWE/CWE-094/InsecureBeanValidation.ql +++ b/java/ql/src/Security/CWE/CWE-094/InsecureBeanValidation.ql @@ -61,7 +61,7 @@ module BeanValidationConfig implements DataFlow::ConfigSig { predicate isSink(DataFlow::Node sink) { sink instanceof BeanValidationSink } } -module BeanValidationFlow = TaintTracking::Make<BeanValidationConfig>; +module BeanValidationFlow = TaintTracking::Global<BeanValidationConfig>; import BeanValidationFlow::PathGraph @@ -80,6 +80,6 @@ where or exists(SetMessageInterpolatorCall c | not c.isSafe()) ) and - BeanValidationFlow::hasFlowPath(source, sink) + BeanValidationFlow::flowPath(source, sink) select sink.getNode(), source, sink, "Custom constraint error message contains an unsanitized $@.", source, "user-provided value" diff --git a/java/ql/src/Security/CWE/CWE-113/ResponseSplitting.ql b/java/ql/src/Security/CWE/CWE-113/ResponseSplitting.ql index b1682dd5774..4fef0a620cd 100644 --- a/java/ql/src/Security/CWE/CWE-113/ResponseSplitting.ql +++ b/java/ql/src/Security/CWE/CWE-113/ResponseSplitting.ql @@ -42,12 +42,12 @@ module ResponseSplittingConfig implements DataFlow::ConfigSig { } } -module ResponseSplitting = TaintTracking::Make<ResponseSplittingConfig>; +module ResponseSplitting = TaintTracking::Global<ResponseSplittingConfig>; import ResponseSplitting::PathGraph from ResponseSplitting::PathNode source, ResponseSplitting::PathNode sink -where ResponseSplitting::hasFlowPath(source, sink) +where ResponseSplitting::flowPath(source, sink) select sink.getNode(), source, sink, "This header depends on a $@, which may cause a response-splitting vulnerability.", source.getNode(), "user-provided value" diff --git a/java/ql/src/Security/CWE/CWE-113/ResponseSplittingLocal.ql b/java/ql/src/Security/CWE/CWE-113/ResponseSplittingLocal.ql index 321f5659e27..402ad1ba1bc 100644 --- a/java/ql/src/Security/CWE/CWE-113/ResponseSplittingLocal.ql +++ b/java/ql/src/Security/CWE/CWE-113/ResponseSplittingLocal.ql @@ -26,12 +26,12 @@ module ResponseSplittingLocalConfig implements DataFlow::ConfigSig { } } -module ResponseSplitting = TaintTracking::Make<ResponseSplittingLocalConfig>; +module ResponseSplitting = TaintTracking::Global<ResponseSplittingLocalConfig>; import ResponseSplitting::PathGraph from ResponseSplitting::PathNode source, ResponseSplitting::PathNode sink -where ResponseSplitting::hasFlowPath(source, sink) +where ResponseSplitting::flowPath(source, sink) select sink.getNode(), source, sink, "This header depends on a $@, which may cause a response-splitting vulnerability.", source.getNode(), "user-provided value" diff --git a/java/ql/src/Security/CWE/CWE-117/LogInjection.ql b/java/ql/src/Security/CWE/CWE-117/LogInjection.ql index 61c1db901b0..dd4ffb6a10a 100644 --- a/java/ql/src/Security/CWE/CWE-117/LogInjection.ql +++ b/java/ql/src/Security/CWE/CWE-117/LogInjection.ql @@ -16,6 +16,6 @@ import semmle.code.java.security.LogInjectionQuery import LogInjectionFlow::PathGraph from LogInjectionFlow::PathNode source, LogInjectionFlow::PathNode sink -where LogInjectionFlow::hasFlowPath(source, sink) +where LogInjectionFlow::flowPath(source, sink) select sink.getNode(), source, sink, "This log entry depends on a $@.", source.getNode(), "user-provided value" diff --git a/java/ql/src/Security/CWE/CWE-129/ImproperValidationOfArrayConstruction.ql b/java/ql/src/Security/CWE/CWE-129/ImproperValidationOfArrayConstruction.ql index c723e7d7067..703bb23b6f5 100644 --- a/java/ql/src/Security/CWE/CWE-129/ImproperValidationOfArrayConstruction.ql +++ b/java/ql/src/Security/CWE/CWE-129/ImproperValidationOfArrayConstruction.ql @@ -23,7 +23,7 @@ private module ImproperValidationOfArrayConstructionConfig implements DataFlow:: } module ImproperValidationOfArrayConstructionFlow = - TaintTracking::Make<ImproperValidationOfArrayConstructionConfig>; + TaintTracking::Global<ImproperValidationOfArrayConstructionConfig>; import ImproperValidationOfArrayConstructionFlow::PathGraph @@ -34,7 +34,7 @@ from where arrayAccess.canThrowOutOfBoundsDueToEmptyArray(sizeExpr, arrayCreation) and sizeExpr = sink.getNode().asExpr() and - ImproperValidationOfArrayConstructionFlow::hasFlowPath(source, sink) + ImproperValidationOfArrayConstructionFlow::flowPath(source, sink) select arrayAccess.getIndexExpr(), source, sink, "This accesses the $@, but the array is initialized using a $@ which may be zero.", arrayCreation, "array", source.getNode(), "user-provided value" diff --git a/java/ql/src/Security/CWE/CWE-129/ImproperValidationOfArrayConstructionCodeSpecified.ql b/java/ql/src/Security/CWE/CWE-129/ImproperValidationOfArrayConstructionCodeSpecified.ql index a4335eeb2fe..8541074c493 100644 --- a/java/ql/src/Security/CWE/CWE-129/ImproperValidationOfArrayConstructionCodeSpecified.ql +++ b/java/ql/src/Security/CWE/CWE-129/ImproperValidationOfArrayConstructionCodeSpecified.ql @@ -27,7 +27,7 @@ module BoundedFlowSourceConfig implements DataFlow::ConfigSig { } } -module BoundedFlowSourceFlow = DataFlow::Make<BoundedFlowSourceConfig>; +module BoundedFlowSourceFlow = DataFlow::Global<BoundedFlowSourceConfig>; import BoundedFlowSourceFlow::PathGraph @@ -39,7 +39,7 @@ where arrayAccess.canThrowOutOfBoundsDueToEmptyArray(sizeExpr, arrayCreation) and sizeExpr = sink.getNode().asExpr() and boundedsource = source.getNode() and - BoundedFlowSourceFlow::hasFlowPath(source, sink) + BoundedFlowSourceFlow::flowPath(source, sink) select arrayAccess.getIndexExpr(), source, sink, "This accesses the $@, but the array is initialized using $@ which may be zero.", arrayCreation, "array", boundedsource, boundedsource.getDescription().toLowerCase() diff --git a/java/ql/src/Security/CWE/CWE-129/ImproperValidationOfArrayConstructionLocal.ql b/java/ql/src/Security/CWE/CWE-129/ImproperValidationOfArrayConstructionLocal.ql index a1d13c3d8db..f5539e4d05b 100644 --- a/java/ql/src/Security/CWE/CWE-129/ImproperValidationOfArrayConstructionLocal.ql +++ b/java/ql/src/Security/CWE/CWE-129/ImproperValidationOfArrayConstructionLocal.ql @@ -24,7 +24,7 @@ module ImproperValidationOfArrayConstructionLocalConfig implements DataFlow::Con } module ImproperValidationOfArrayConstructionLocalFlow = - TaintTracking::Make<ImproperValidationOfArrayConstructionLocalConfig>; + TaintTracking::Global<ImproperValidationOfArrayConstructionLocalConfig>; import ImproperValidationOfArrayConstructionLocalFlow::PathGraph @@ -35,7 +35,7 @@ from where arrayAccess.canThrowOutOfBoundsDueToEmptyArray(sizeExpr, arrayCreation) and sizeExpr = sink.getNode().asExpr() and - ImproperValidationOfArrayConstructionLocalFlow::hasFlowPath(source, sink) + ImproperValidationOfArrayConstructionLocalFlow::flowPath(source, sink) select arrayAccess.getIndexExpr(), source, sink, "This accesses the $@, but the array is initialized using a $@ which may be zero.", arrayCreation, "array", source.getNode(), "user-provided value" diff --git a/java/ql/src/Security/CWE/CWE-129/ImproperValidationOfArrayIndex.ql b/java/ql/src/Security/CWE/CWE-129/ImproperValidationOfArrayIndex.ql index 70b23e058a5..6c6755dc484 100644 --- a/java/ql/src/Security/CWE/CWE-129/ImproperValidationOfArrayIndex.ql +++ b/java/ql/src/Security/CWE/CWE-129/ImproperValidationOfArrayIndex.ql @@ -25,7 +25,7 @@ module ImproperValidationOfArrayIndexConfig implements DataFlow::ConfigSig { } module ImproperValidationOfArrayIndexFlow = - TaintTracking::Make<ImproperValidationOfArrayIndexConfig>; + TaintTracking::Global<ImproperValidationOfArrayIndexConfig>; import ImproperValidationOfArrayIndexFlow::PathGraph @@ -34,7 +34,7 @@ from ImproperValidationOfArrayIndexFlow::PathNode sink, CheckableArrayAccess arrayAccess where arrayAccess.canThrowOutOfBounds(sink.getNode().asExpr()) and - ImproperValidationOfArrayIndexFlow::hasFlowPath(source, sink) + ImproperValidationOfArrayIndexFlow::flowPath(source, sink) select arrayAccess.getIndexExpr(), source, sink, "This index depends on a $@ which can cause an ArrayIndexOutOfBoundsException.", source.getNode(), "user-provided value" diff --git a/java/ql/src/Security/CWE/CWE-129/ImproperValidationOfArrayIndexCodeSpecified.ql b/java/ql/src/Security/CWE/CWE-129/ImproperValidationOfArrayIndexCodeSpecified.ql index fd07e39b6ba..d2f8f6135a9 100644 --- a/java/ql/src/Security/CWE/CWE-129/ImproperValidationOfArrayIndexCodeSpecified.ql +++ b/java/ql/src/Security/CWE/CWE-129/ImproperValidationOfArrayIndexCodeSpecified.ql @@ -24,7 +24,7 @@ module BoundedFlowSourceConfig implements DataFlow::ConfigSig { } } -module BoundedFlowSourceFlow = DataFlow::Make<BoundedFlowSourceConfig>; +module BoundedFlowSourceFlow = DataFlow::Global<BoundedFlowSourceConfig>; import BoundedFlowSourceFlow::PathGraph @@ -34,7 +34,7 @@ from where arrayAccess.canThrowOutOfBounds(sink.getNode().asExpr()) and boundedsource = source.getNode() and - BoundedFlowSourceFlow::hasFlowPath(source, sink) and + BoundedFlowSourceFlow::flowPath(source, sink) and boundedsource != sink.getNode() and not ( ( diff --git a/java/ql/src/Security/CWE/CWE-129/ImproperValidationOfArrayIndexLocal.ql b/java/ql/src/Security/CWE/CWE-129/ImproperValidationOfArrayIndexLocal.ql index d57df422287..51f54eebd79 100644 --- a/java/ql/src/Security/CWE/CWE-129/ImproperValidationOfArrayIndexLocal.ql +++ b/java/ql/src/Security/CWE/CWE-129/ImproperValidationOfArrayIndexLocal.ql @@ -24,7 +24,7 @@ module ImproperValidationOfArrayIndexLocalConfig implements DataFlow::ConfigSig } module ImproperValidationOfArrayIndexLocalFlow = - TaintTracking::Make<ImproperValidationOfArrayIndexLocalConfig>; + TaintTracking::Global<ImproperValidationOfArrayIndexLocalConfig>; import ImproperValidationOfArrayIndexLocalFlow::PathGraph @@ -33,7 +33,7 @@ from ImproperValidationOfArrayIndexLocalFlow::PathNode sink, CheckableArrayAccess arrayAccess where arrayAccess.canThrowOutOfBounds(sink.getNode().asExpr()) and - ImproperValidationOfArrayIndexLocalFlow::hasFlowPath(source, sink) + ImproperValidationOfArrayIndexLocalFlow::flowPath(source, sink) select arrayAccess.getIndexExpr(), source, sink, "This index depends on a $@ which can cause an ArrayIndexOutOfBoundsException.", source.getNode(), "user-provided value" diff --git a/java/ql/src/Security/CWE/CWE-134/ExternallyControlledFormatString.ql b/java/ql/src/Security/CWE/CWE-134/ExternallyControlledFormatString.ql index da5bc5372a4..a2d2e9005ef 100644 --- a/java/ql/src/Security/CWE/CWE-134/ExternallyControlledFormatString.ql +++ b/java/ql/src/Security/CWE/CWE-134/ExternallyControlledFormatString.ql @@ -27,7 +27,7 @@ module ExternallyControlledFormatStringConfig implements DataFlow::ConfigSig { } module ExternallyControlledFormatStringFlow = - TaintTracking::Make<ExternallyControlledFormatStringConfig>; + TaintTracking::Global<ExternallyControlledFormatStringConfig>; import ExternallyControlledFormatStringFlow::PathGraph @@ -35,7 +35,7 @@ from ExternallyControlledFormatStringFlow::PathNode source, ExternallyControlledFormatStringFlow::PathNode sink, StringFormat formatCall where - ExternallyControlledFormatStringFlow::hasFlowPath(source, sink) and + ExternallyControlledFormatStringFlow::flowPath(source, sink) and sink.getNode().asExpr() = formatCall.getFormatArgument() select formatCall.getFormatArgument(), source, sink, "Format string depends on a $@.", source.getNode(), "user-provided value" diff --git a/java/ql/src/Security/CWE/CWE-134/ExternallyControlledFormatStringLocal.ql b/java/ql/src/Security/CWE/CWE-134/ExternallyControlledFormatStringLocal.ql index 0300eaea806..56026c61cfa 100644 --- a/java/ql/src/Security/CWE/CWE-134/ExternallyControlledFormatStringLocal.ql +++ b/java/ql/src/Security/CWE/CWE-134/ExternallyControlledFormatStringLocal.ql @@ -23,7 +23,7 @@ module ExternallyControlledFormatStringLocalConfig implements DataFlow::ConfigSi } module ExternallyControlledFormatStringLocalFlow = - TaintTracking::Make<ExternallyControlledFormatStringLocalConfig>; + TaintTracking::Global<ExternallyControlledFormatStringLocalConfig>; import ExternallyControlledFormatStringLocalFlow::PathGraph @@ -31,7 +31,7 @@ from ExternallyControlledFormatStringLocalFlow::PathNode source, ExternallyControlledFormatStringLocalFlow::PathNode sink, StringFormat formatCall where - ExternallyControlledFormatStringLocalFlow::hasFlowPath(source, sink) and + ExternallyControlledFormatStringLocalFlow::flowPath(source, sink) and sink.getNode().asExpr() = formatCall.getFormatArgument() select formatCall.getFormatArgument(), source, sink, "Format string depends on a $@.", source.getNode(), "user-provided value" diff --git a/java/ql/src/Security/CWE/CWE-190/ArithmeticTainted.ql b/java/ql/src/Security/CWE/CWE-190/ArithmeticTainted.ql index c4294e92ef0..81e572e4c4e 100644 --- a/java/ql/src/Security/CWE/CWE-190/ArithmeticTainted.ql +++ b/java/ql/src/Security/CWE/CWE-190/ArithmeticTainted.ql @@ -32,9 +32,9 @@ module RemoteUserInputUnderflowConfig implements DataFlow::ConfigSig { predicate isBarrier(DataFlow::Node n) { underflowBarrier(n) } } -module RemoteUserInputOverflow = TaintTracking::Make<RemoteUserInputOverflowConfig>; +module RemoteUserInputOverflow = TaintTracking::Global<RemoteUserInputOverflowConfig>; -module RemoteUserInputUnderflow = TaintTracking::Make<RemoteUserInputUnderflowConfig>; +module RemoteUserInputUnderflow = TaintTracking::Global<RemoteUserInputUnderflowConfig>; module Flow = DataFlow::MergePathGraph<RemoteUserInputOverflow::PathNode, RemoteUserInputUnderflow::PathNode, @@ -44,11 +44,11 @@ import Flow::PathGraph from Flow::PathNode source, Flow::PathNode sink, ArithExpr exp, string effect where - RemoteUserInputOverflow::hasFlowPath(source.asPathNode1(), sink.asPathNode1()) and + RemoteUserInputOverflow::flowPath(source.asPathNode1(), sink.asPathNode1()) and overflowSink(exp, sink.getNode().asExpr()) and effect = "overflow" or - RemoteUserInputUnderflow::hasFlowPath(source.asPathNode2(), sink.asPathNode2()) and + RemoteUserInputUnderflow::flowPath(source.asPathNode2(), sink.asPathNode2()) and underflowSink(exp, sink.getNode().asExpr()) and effect = "underflow" select exp, source, sink, diff --git a/java/ql/src/Security/CWE/CWE-190/ArithmeticTaintedLocal.ql b/java/ql/src/Security/CWE/CWE-190/ArithmeticTaintedLocal.ql index 9fb079ade70..21564787f73 100644 --- a/java/ql/src/Security/CWE/CWE-190/ArithmeticTaintedLocal.ql +++ b/java/ql/src/Security/CWE/CWE-190/ArithmeticTaintedLocal.ql @@ -25,7 +25,7 @@ module ArithmeticTaintedLocalOverflowConfig implements DataFlow::ConfigSig { } module ArithmeticTaintedLocalOverflowFlow = - TaintTracking::Make<ArithmeticTaintedLocalOverflowConfig>; + TaintTracking::Global<ArithmeticTaintedLocalOverflowConfig>; module ArithmeticTaintedLocalUnderflowConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { source instanceof LocalUserInput } @@ -36,7 +36,7 @@ module ArithmeticTaintedLocalUnderflowConfig implements DataFlow::ConfigSig { } module ArithmeticTaintedLocalUnderflowFlow = - TaintTracking::Make<ArithmeticTaintedLocalUnderflowConfig>; + TaintTracking::Global<ArithmeticTaintedLocalUnderflowConfig>; module Flow = DataFlow::MergePathGraph<ArithmeticTaintedLocalOverflowFlow::PathNode, @@ -47,11 +47,11 @@ import Flow::PathGraph from Flow::PathNode source, Flow::PathNode sink, ArithExpr exp, string effect where - ArithmeticTaintedLocalOverflowFlow::hasFlowPath(source.asPathNode1(), sink.asPathNode1()) and + ArithmeticTaintedLocalOverflowFlow::flowPath(source.asPathNode1(), sink.asPathNode1()) and overflowSink(exp, sink.getNode().asExpr()) and effect = "overflow" or - ArithmeticTaintedLocalUnderflowFlow::hasFlowPath(source.asPathNode2(), sink.asPathNode2()) and + ArithmeticTaintedLocalUnderflowFlow::flowPath(source.asPathNode2(), sink.asPathNode2()) and underflowSink(exp, sink.getNode().asExpr()) and effect = "underflow" select exp, source, sink, diff --git a/java/ql/src/Security/CWE/CWE-190/ArithmeticUncontrolled.ql b/java/ql/src/Security/CWE/CWE-190/ArithmeticUncontrolled.ql index 718062a97c7..3ab8deec9b2 100644 --- a/java/ql/src/Security/CWE/CWE-190/ArithmeticUncontrolled.ql +++ b/java/ql/src/Security/CWE/CWE-190/ArithmeticUncontrolled.ql @@ -33,7 +33,7 @@ module ArithmeticUncontrolledOverflowConfig implements DataFlow::ConfigSig { } module ArithmeticUncontrolledOverflowFlow = - TaintTracking::Make<ArithmeticUncontrolledOverflowConfig>; + TaintTracking::Global<ArithmeticUncontrolledOverflowConfig>; module ArithmeticUncontrolledUnderflowConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { source instanceof TaintSource } @@ -44,7 +44,7 @@ module ArithmeticUncontrolledUnderflowConfig implements DataFlow::ConfigSig { } module ArithmeticUncontrolledUnderflowFlow = - TaintTracking::Make<ArithmeticUncontrolledUnderflowConfig>; + TaintTracking::Global<ArithmeticUncontrolledUnderflowConfig>; module Flow = DataFlow::MergePathGraph<ArithmeticUncontrolledOverflowFlow::PathNode, @@ -55,11 +55,11 @@ import Flow::PathGraph from Flow::PathNode source, Flow::PathNode sink, ArithExpr exp, string effect where - ArithmeticUncontrolledOverflowFlow::hasFlowPath(source.asPathNode1(), sink.asPathNode1()) and + ArithmeticUncontrolledOverflowFlow::flowPath(source.asPathNode1(), sink.asPathNode1()) and overflowSink(exp, sink.getNode().asExpr()) and effect = "overflow" or - ArithmeticUncontrolledUnderflowFlow::hasFlowPath(source.asPathNode2(), sink.asPathNode2()) and + ArithmeticUncontrolledUnderflowFlow::flowPath(source.asPathNode2(), sink.asPathNode2()) and underflowSink(exp, sink.getNode().asExpr()) and effect = "underflow" select exp, source, sink, diff --git a/java/ql/src/Security/CWE/CWE-190/ArithmeticWithExtremeValues.ql b/java/ql/src/Security/CWE/CWE-190/ArithmeticWithExtremeValues.ql index 2de882000ae..a054f435229 100644 --- a/java/ql/src/Security/CWE/CWE-190/ArithmeticWithExtremeValues.ql +++ b/java/ql/src/Security/CWE/CWE-190/ArithmeticWithExtremeValues.ql @@ -45,7 +45,7 @@ module MaxValueFlowConfig implements DataFlow::ConfigSig { predicate isBarrier(DataFlow::Node n) { overflowBarrier(n) } } -module MaxValueFlow = DataFlow::Make<MaxValueFlowConfig>; +module MaxValueFlow = DataFlow::Global<MaxValueFlowConfig>; module MinValueFlowConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { @@ -59,7 +59,7 @@ module MinValueFlowConfig implements DataFlow::ConfigSig { predicate isBarrier(DataFlow::Node n) { underflowBarrier(n) } } -module MinValueFlow = DataFlow::Make<MinValueFlowConfig>; +module MinValueFlow = DataFlow::Global<MinValueFlowConfig>; module Flow = DataFlow::MergePathGraph<MaxValueFlow::PathNode, MinValueFlow::PathNode, MaxValueFlow::PathGraph, @@ -71,11 +71,11 @@ predicate query( Flow::PathNode source, Flow::PathNode sink, ArithExpr exp, string effect, Type srctyp ) { ( - MaxValueFlow::hasFlowPath(source.asPathNode1(), sink.asPathNode1()) and + MaxValueFlow::flowPath(source.asPathNode1(), sink.asPathNode1()) and overflowSink(exp, sink.getNode().asExpr()) and effect = "overflow" or - MinValueFlow::hasFlowPath(source.asPathNode2(), sink.asPathNode2()) and + MinValueFlow::flowPath(source.asPathNode2(), sink.asPathNode2()) and underflowSink(exp, sink.getNode().asExpr()) and effect = "underflow" ) and diff --git a/java/ql/src/Security/CWE/CWE-200/AndroidWebViewSettingsAllowsContentAccess.ql b/java/ql/src/Security/CWE/CWE-200/AndroidWebViewSettingsAllowsContentAccess.ql index 1b1ca51e7cd..c16b8577d73 100644 --- a/java/ql/src/Security/CWE/CWE-200/AndroidWebViewSettingsAllowsContentAccess.ql +++ b/java/ql/src/Security/CWE/CWE-200/AndroidWebViewSettingsAllowsContentAccess.ql @@ -102,7 +102,7 @@ module WebViewDisallowContentAccessConfig implements DataFlow::StateConfigSig { } module WebViewDisallowContentAccessFlow = - TaintTracking::MakeWithState<WebViewDisallowContentAccessConfig>; + TaintTracking::GlobalWithState<WebViewDisallowContentAccessConfig>; from Expr e where @@ -116,7 +116,7 @@ where // implicit: no setAllowContentAccess(false) exists(WebViewSource source | source.asExpr() = e and - not WebViewDisallowContentAccessFlow::hasFlow(source, _) + not WebViewDisallowContentAccessFlow::flow(source, _) ) select e, "Sensitive information may be exposed via a malicious link due to access to content:// links being allowed in this WebView." diff --git a/java/ql/src/Security/CWE/CWE-200/TempDirLocalInformationDisclosure.ql b/java/ql/src/Security/CWE/CWE-200/TempDirLocalInformationDisclosure.ql index 6d99eba59c2..400d7159b9a 100644 --- a/java/ql/src/Security/CWE/CWE-200/TempDirLocalInformationDisclosure.ql +++ b/java/ql/src/Security/CWE/CWE-200/TempDirLocalInformationDisclosure.ql @@ -133,7 +133,7 @@ module TempDirSystemGetPropertyToCreateConfig implements DataFlow::ConfigSig { predicate isSink(DataFlow::Node sink) { sink instanceof FileCreationSink and - not TempDirSystemGetPropertyDirectlyToMkdir::hasFlowTo(sink) + not TempDirSystemGetPropertyDirectlyToMkdir::flowTo(sink) } predicate isBarrier(DataFlow::Node sanitizer) { @@ -146,7 +146,7 @@ module TempDirSystemGetPropertyToCreateConfig implements DataFlow::ConfigSig { } module TempDirSystemGetPropertyToCreate = - TaintTracking::Make<TempDirSystemGetPropertyToCreateConfig>; + TaintTracking::Global<TempDirSystemGetPropertyToCreateConfig>; /** * Configuration that tracks calls to to `mkdir` or `mkdirs` that are are directly on the temp directory system property. @@ -179,7 +179,7 @@ module TempDirSystemGetPropertyDirectlyToMkdirConfig implements DataFlow::Config } module TempDirSystemGetPropertyDirectlyToMkdir = - TaintTracking::Make<TempDirSystemGetPropertyDirectlyToMkdirConfig>; + TaintTracking::Global<TempDirSystemGetPropertyDirectlyToMkdirConfig>; // // Begin configuration for tracking single-method calls that are vulnerable. @@ -270,7 +270,7 @@ import Flow::PathGraph from Flow::PathNode source, Flow::PathNode sink, string message where ( - TempDirSystemGetPropertyToCreate::hasFlowPath(source.asPathNode1(), sink.asPathNode1()) and + TempDirSystemGetPropertyToCreate::flowPath(source.asPathNode1(), sink.asPathNode1()) and message = "Local information disclosure vulnerability from $@ due to use of file or directory readable by other local users." or diff --git a/java/ql/src/Security/CWE/CWE-209/StackTraceExposure.ql b/java/ql/src/Security/CWE/CWE-209/StackTraceExposure.ql index be5d3dad848..0a40c11dfe9 100644 --- a/java/ql/src/Security/CWE/CWE-209/StackTraceExposure.ql +++ b/java/ql/src/Security/CWE/CWE-209/StackTraceExposure.ql @@ -42,7 +42,7 @@ module ServletWriterSourceToPrintStackTraceMethodFlowConfig implements DataFlow: } module ServletWriterSourceToPrintStackTraceMethodFlow = - TaintTracking::Make<ServletWriterSourceToPrintStackTraceMethodFlowConfig>; + TaintTracking::Global<ServletWriterSourceToPrintStackTraceMethodFlowConfig>; /** * A call that uses `Throwable.printStackTrace()` on a stream that is connected @@ -51,7 +51,7 @@ module ServletWriterSourceToPrintStackTraceMethodFlow = predicate printsStackToWriter(MethodAccess call) { exists(PrintStackTraceMethod printStackTrace | call.getMethod() = printStackTrace and - ServletWriterSourceToPrintStackTraceMethodFlow::hasFlowToExpr(call.getAnArgument()) + ServletWriterSourceToPrintStackTraceMethodFlow::flowToExpr(call.getAnArgument()) ) } @@ -87,7 +87,7 @@ module StackTraceStringToHttpResponseSinkFlowConfig implements DataFlow::ConfigS } module StackTraceStringToHttpResponseSinkFlow = - TaintTracking::Make<StackTraceStringToHttpResponseSinkFlowConfig>; + TaintTracking::Global<StackTraceStringToHttpResponseSinkFlowConfig>; /** * A write of stack trace data to an external stream. @@ -104,7 +104,7 @@ predicate printsStackExternally(MethodAccess call, Expr stackTrace) { predicate stringifiedStackFlowsExternally(DataFlow::Node externalExpr, Expr stackTrace) { exists(MethodAccess stackTraceString | stackTraceExpr(stackTrace, stackTraceString) and - StackTraceStringToHttpResponseSinkFlow::hasFlow(DataFlow::exprNode(stackTraceString), + StackTraceStringToHttpResponseSinkFlow::flow(DataFlow::exprNode(stackTraceString), externalExpr) ) } @@ -127,13 +127,13 @@ module GetMessageFlowSourceToHttpResponseSinkFlowConfig implements DataFlow::Con } module GetMessageFlowSourceToHttpResponseSinkFlow = - TaintTracking::Make<GetMessageFlowSourceToHttpResponseSinkFlowConfig>; + TaintTracking::Global<GetMessageFlowSourceToHttpResponseSinkFlowConfig>; /** * A call to `getMessage()` that then flows to a servlet response. */ predicate getMessageFlowsExternally(DataFlow::Node externalExpr, GetMessageFlowSource getMessage) { - GetMessageFlowSourceToHttpResponseSinkFlow::hasFlow(DataFlow::exprNode(getMessage), externalExpr) + GetMessageFlowSourceToHttpResponseSinkFlow::flow(DataFlow::exprNode(getMessage), externalExpr) } from Expr externalExpr, Expr errorInformation diff --git a/java/ql/src/Security/CWE/CWE-266/IntentUriPermissionManipulation.ql b/java/ql/src/Security/CWE/CWE-266/IntentUriPermissionManipulation.ql index 281415a0d91..d79abd6e417 100644 --- a/java/ql/src/Security/CWE/CWE-266/IntentUriPermissionManipulation.ql +++ b/java/ql/src/Security/CWE/CWE-266/IntentUriPermissionManipulation.ql @@ -20,7 +20,7 @@ import IntentUriPermissionManipulationFlow::PathGraph from IntentUriPermissionManipulationFlow::PathNode source, IntentUriPermissionManipulationFlow::PathNode sink -where IntentUriPermissionManipulationFlow::hasFlowPath(source, sink) +where IntentUriPermissionManipulationFlow::flowPath(source, sink) select sink.getNode(), source, sink, "This Intent can be set with arbitrary flags from a $@, " + "and used to give access to internal content providers.", source.getNode(), diff --git a/java/ql/src/Security/CWE/CWE-297/UnsafeHostnameVerification.ql b/java/ql/src/Security/CWE/CWE-297/UnsafeHostnameVerification.ql index f6663b8e87d..4bea66796b8 100644 --- a/java/ql/src/Security/CWE/CWE-297/UnsafeHostnameVerification.ql +++ b/java/ql/src/Security/CWE/CWE-297/UnsafeHostnameVerification.ql @@ -77,7 +77,7 @@ module TrustAllHostnameVerifierConfig implements DataFlow::ConfigSig { } } -module TrustAllHostnameVerifierFlow = DataFlow::Make<TrustAllHostnameVerifierConfig>; +module TrustAllHostnameVerifierFlow = DataFlow::Global<TrustAllHostnameVerifierConfig>; import TrustAllHostnameVerifierFlow::PathGraph @@ -118,7 +118,7 @@ from TrustAllHostnameVerifierFlow::PathNode source, TrustAllHostnameVerifierFlow::PathNode sink, RefType verifier where - TrustAllHostnameVerifierFlow::hasFlowPath(source, sink) and + TrustAllHostnameVerifierFlow::flowPath(source, sink) and not isNodeGuardedByFlag(sink.getNode()) and verifier = source.getNode().asExpr().(ClassInstanceExpr).getConstructedType() select sink, source, sink, diff --git a/java/ql/src/Security/CWE/CWE-327/BrokenCryptoAlgorithm.ql b/java/ql/src/Security/CWE/CWE-327/BrokenCryptoAlgorithm.ql index ec7ffcbccc1..a423eed3d22 100644 --- a/java/ql/src/Security/CWE/CWE-327/BrokenCryptoAlgorithm.ql +++ b/java/ql/src/Security/CWE/CWE-327/BrokenCryptoAlgorithm.ql @@ -38,7 +38,7 @@ module InsecureCryptoConfig implements ConfigSig { } } -module InsecureCryptoFlow = TaintTracking::Make<InsecureCryptoConfig>; +module InsecureCryptoFlow = TaintTracking::Global<InsecureCryptoConfig>; import InsecureCryptoFlow::PathGraph @@ -48,6 +48,6 @@ from where sink.getNode().asExpr() = c.getAlgoSpec() and source.getNode().asExpr() = s and - InsecureCryptoFlow::hasFlowPath(source, sink) + InsecureCryptoFlow::flowPath(source, sink) select c, source, sink, "Cryptographic algorithm $@ is weak and should not be used.", s, s.getValue() diff --git a/java/ql/src/Security/CWE/CWE-327/MaybeBrokenCryptoAlgorithm.ql b/java/ql/src/Security/CWE/CWE-327/MaybeBrokenCryptoAlgorithm.ql index 47446211438..b5f14421894 100644 --- a/java/ql/src/Security/CWE/CWE-327/MaybeBrokenCryptoAlgorithm.ql +++ b/java/ql/src/Security/CWE/CWE-327/MaybeBrokenCryptoAlgorithm.ql @@ -61,7 +61,7 @@ module InsecureCryptoConfig implements ConfigSig { } } -module InsecureCryptoFlow = TaintTracking::Make<InsecureCryptoConfig>; +module InsecureCryptoFlow = TaintTracking::Global<InsecureCryptoConfig>; import InsecureCryptoFlow::PathGraph @@ -71,7 +71,7 @@ from where sink.getNode().asExpr() = c.getAlgoSpec() and source.getNode().asExpr() = s and - InsecureCryptoFlow::hasFlowPath(source, sink) + InsecureCryptoFlow::flowPath(source, sink) select c, source, sink, "Cryptographic algorithm $@ may not be secure, consider using a different algorithm.", s, s.getValue() diff --git a/java/ql/src/Security/CWE/CWE-441/UnsafeContentUriResolution.ql b/java/ql/src/Security/CWE/CWE-441/UnsafeContentUriResolution.ql index ce90cc5e00f..4a8c9bc3ad1 100644 --- a/java/ql/src/Security/CWE/CWE-441/UnsafeContentUriResolution.ql +++ b/java/ql/src/Security/CWE/CWE-441/UnsafeContentUriResolution.ql @@ -17,7 +17,7 @@ import semmle.code.java.security.UnsafeContentUriResolutionQuery import UnsafeContentResolutionFlow::PathGraph from UnsafeContentResolutionFlow::PathNode src, UnsafeContentResolutionFlow::PathNode sink -where UnsafeContentResolutionFlow::hasFlowPath(src, sink) +where UnsafeContentResolutionFlow::flowPath(src, sink) select sink.getNode(), src, sink, "This ContentResolver method that resolves a URI depends on a $@.", src.getNode(), "user-provided value" diff --git a/java/ql/src/Security/CWE/CWE-470/FragmentInjection.ql b/java/ql/src/Security/CWE/CWE-470/FragmentInjection.ql index 5ffa7068980..6ff9a15eca4 100644 --- a/java/ql/src/Security/CWE/CWE-470/FragmentInjection.ql +++ b/java/ql/src/Security/CWE/CWE-470/FragmentInjection.ql @@ -16,7 +16,7 @@ import semmle.code.java.security.FragmentInjectionQuery import FragmentInjectionTaintFlow::PathGraph from FragmentInjectionTaintFlow::PathNode source, FragmentInjectionTaintFlow::PathNode sink -where FragmentInjectionTaintFlow::hasFlowPath(source, sink) +where FragmentInjectionTaintFlow::flowPath(source, sink) select sink.getNode(), source, sink, "Fragment depends on a $@, which may allow a malicious application to bypass access controls.", source.getNode(), "user-provided value" diff --git a/java/ql/src/Security/CWE/CWE-532/SensitiveInfoLog.ql b/java/ql/src/Security/CWE/CWE-532/SensitiveInfoLog.ql index a884ba6c242..9b306bc1bd1 100644 --- a/java/ql/src/Security/CWE/CWE-532/SensitiveInfoLog.ql +++ b/java/ql/src/Security/CWE/CWE-532/SensitiveInfoLog.ql @@ -16,6 +16,6 @@ import semmle.code.java.security.SensitiveLoggingQuery import SensitiveLoggerFlow::PathGraph from SensitiveLoggerFlow::PathNode source, SensitiveLoggerFlow::PathNode sink -where SensitiveLoggerFlow::hasFlowPath(source, sink) +where SensitiveLoggerFlow::flowPath(source, sink) select sink.getNode(), source, sink, "This $@ is written to a log file.", source.getNode(), "potentially sensitive information" diff --git a/java/ql/src/Security/CWE/CWE-601/UrlRedirect.ql b/java/ql/src/Security/CWE/CWE-601/UrlRedirect.ql index cf9393830b0..78c9c86c762 100644 --- a/java/ql/src/Security/CWE/CWE-601/UrlRedirect.ql +++ b/java/ql/src/Security/CWE/CWE-601/UrlRedirect.ql @@ -21,11 +21,11 @@ module UrlRedirectConfig implements DataFlow::ConfigSig { predicate isSink(DataFlow::Node sink) { sink instanceof UrlRedirectSink } } -module UrlRedirectFlow = TaintTracking::Make<UrlRedirectConfig>; +module UrlRedirectFlow = TaintTracking::Global<UrlRedirectConfig>; import UrlRedirectFlow::PathGraph from UrlRedirectFlow::PathNode source, UrlRedirectFlow::PathNode sink -where UrlRedirectFlow::hasFlowPath(source, sink) +where UrlRedirectFlow::flowPath(source, sink) select sink.getNode(), source, sink, "Untrusted URL redirection depends on a $@.", source.getNode(), "user-provided value" diff --git a/java/ql/src/Security/CWE/CWE-601/UrlRedirectLocal.ql b/java/ql/src/Security/CWE/CWE-601/UrlRedirectLocal.ql index de44173ec57..d8a28f52abb 100644 --- a/java/ql/src/Security/CWE/CWE-601/UrlRedirectLocal.ql +++ b/java/ql/src/Security/CWE/CWE-601/UrlRedirectLocal.ql @@ -21,11 +21,11 @@ module UrlRedirectLocalConfig implements DataFlow::ConfigSig { predicate isSink(DataFlow::Node sink) { sink instanceof UrlRedirectSink } } -module UrlRedirectLocalFlow = TaintTracking::Make<UrlRedirectLocalConfig>; +module UrlRedirectLocalFlow = TaintTracking::Global<UrlRedirectLocalConfig>; import UrlRedirectLocalFlow::PathGraph from UrlRedirectLocalFlow::PathNode source, UrlRedirectLocalFlow::PathNode sink -where UrlRedirectLocalFlow::hasFlowPath(source, sink) +where UrlRedirectLocalFlow::flowPath(source, sink) select sink.getNode(), source, sink, "Untrusted URL redirection depends on a $@.", source.getNode(), "user-provided value" diff --git a/java/ql/src/Security/CWE/CWE-611/XXE.ql b/java/ql/src/Security/CWE/CWE-611/XXE.ql index 708d4f08ee7..5520d332ed6 100644 --- a/java/ql/src/Security/CWE/CWE-611/XXE.ql +++ b/java/ql/src/Security/CWE/CWE-611/XXE.ql @@ -19,7 +19,7 @@ import semmle.code.java.security.XxeRemoteQuery import XxeFlow::PathGraph from XxeFlow::PathNode source, XxeFlow::PathNode sink -where XxeFlow::hasFlowPath(source, sink) +where XxeFlow::flowPath(source, sink) select sink.getNode(), source, sink, "XML parsing depends on a $@ without guarding against external entity expansion.", source.getNode(), "user-provided value" diff --git a/java/ql/src/Security/CWE/CWE-611/XXELocal.ql b/java/ql/src/Security/CWE/CWE-611/XXELocal.ql index 0ab4ddcc106..5e306a65349 100644 --- a/java/ql/src/Security/CWE/CWE-611/XXELocal.ql +++ b/java/ql/src/Security/CWE/CWE-611/XXELocal.ql @@ -19,7 +19,7 @@ import semmle.code.java.security.XxeLocalQuery import XxeLocalFlow::PathGraph from XxeLocalFlow::PathNode source, XxeLocalFlow::PathNode sink -where XxeLocalFlow::hasFlowPath(source, sink) +where XxeLocalFlow::flowPath(source, sink) select sink.getNode(), source, sink, "XML parsing depends on a $@ without guarding against external entity expansion.", source.getNode(), "user-provided value" diff --git a/java/ql/src/Security/CWE/CWE-614/InsecureCookie.ql b/java/ql/src/Security/CWE/CWE-614/InsecureCookie.ql index 807ef383dee..0d24e9315c1 100644 --- a/java/ql/src/Security/CWE/CWE-614/InsecureCookie.ql +++ b/java/ql/src/Security/CWE/CWE-614/InsecureCookie.ql @@ -47,10 +47,10 @@ module SecureCookieConfig implements DataFlow::ConfigSig { } } -module SecureCookieFlow = DataFlow::Make<SecureCookieConfig>; +module SecureCookieFlow = DataFlow::Global<SecureCookieConfig>; from MethodAccess add where add.getMethod() instanceof ResponseAddCookieMethod and - not SecureCookieFlow::hasFlowToExpr(add.getArgument(0)) + not SecureCookieFlow::flowToExpr(add.getArgument(0)) select add, "Cookie is added to response without the 'secure' flag being set." diff --git a/java/ql/src/Security/CWE/CWE-643/XPathInjection.ql b/java/ql/src/Security/CWE/CWE-643/XPathInjection.ql index eacebd3f098..18a4d76873b 100644 --- a/java/ql/src/Security/CWE/CWE-643/XPathInjection.ql +++ b/java/ql/src/Security/CWE/CWE-643/XPathInjection.ql @@ -22,11 +22,11 @@ module XPathInjectionConfig implements DataFlow::ConfigSig { predicate isSink(DataFlow::Node sink) { sink instanceof XPathInjectionSink } } -module XPathInjectionFlow = TaintTracking::Make<XPathInjectionConfig>; +module XPathInjectionFlow = TaintTracking::Global<XPathInjectionConfig>; import XPathInjectionFlow::PathGraph from XPathInjectionFlow::PathNode source, XPathInjectionFlow::PathNode sink -where XPathInjectionFlow::hasFlowPath(source, sink) +where XPathInjectionFlow::flowPath(source, sink) select sink.getNode(), source, sink, "XPath expression depends on a $@.", source.getNode(), "user-provided value" diff --git a/java/ql/src/Security/CWE/CWE-681/NumericCastTainted.ql b/java/ql/src/Security/CWE/CWE-681/NumericCastTainted.ql index 3caefe3fd09..3194e0f8e7b 100644 --- a/java/ql/src/Security/CWE/CWE-681/NumericCastTainted.ql +++ b/java/ql/src/Security/CWE/CWE-681/NumericCastTainted.ql @@ -34,14 +34,14 @@ module NumericCastFlowConfig implements DataFlow::ConfigSig { } } -module NumericCastFlow = TaintTracking::Make<NumericCastFlowConfig>; +module NumericCastFlow = TaintTracking::Global<NumericCastFlowConfig>; import NumericCastFlow::PathGraph from NumericCastFlow::PathNode source, NumericCastFlow::PathNode sink, NumericNarrowingCastExpr exp where sink.getNode().asExpr() = exp.getExpr() and - NumericCastFlow::hasFlowPath(source, sink) + NumericCastFlow::flowPath(source, sink) select exp, source, sink, "This cast to a narrower type depends on a $@, potentially causing truncation.", source.getNode(), "user-provided value" diff --git a/java/ql/src/Security/CWE/CWE-681/NumericCastTaintedLocal.ql b/java/ql/src/Security/CWE/CWE-681/NumericCastTaintedLocal.ql index 41757ab419a..b9224769562 100644 --- a/java/ql/src/Security/CWE/CWE-681/NumericCastTaintedLocal.ql +++ b/java/ql/src/Security/CWE/CWE-681/NumericCastTaintedLocal.ql @@ -32,7 +32,7 @@ module NumericCastFlowConfig implements DataFlow::ConfigSig { } } -module NumericCastFlow = TaintTracking::Make<NumericCastFlowConfig>; +module NumericCastFlow = TaintTracking::Global<NumericCastFlowConfig>; import NumericCastFlow::PathGraph @@ -42,7 +42,7 @@ from where exp.getExpr() = tainted and sink.getNode().asExpr() = tainted and - NumericCastFlow::hasFlowPath(source, sink) and + NumericCastFlow::flowPath(source, sink) and not exists(RightShiftOp e | e.getShiftedVariable() = tainted.getVariable()) select exp, source, sink, "This cast to a narrower type depends on a $@, potentially causing truncation.", source.getNode(), diff --git a/java/ql/src/Security/CWE/CWE-730/PolynomialReDoS.ql b/java/ql/src/Security/CWE/CWE-730/PolynomialReDoS.ql index 8a1244b93d1..2ba45ca083c 100644 --- a/java/ql/src/Security/CWE/CWE-730/PolynomialReDoS.ql +++ b/java/ql/src/Security/CWE/CWE-730/PolynomialReDoS.ql @@ -21,7 +21,7 @@ from PolynomialRedosFlow::PathNode source, PolynomialRedosFlow::PathNode sink, SuperlinearBackTracking::PolynomialBackTrackingTerm regexp where - PolynomialRedosFlow::hasFlowPath(source, sink) and + PolynomialRedosFlow::flowPath(source, sink) and regexp.getRootTerm() = sink.getNode().(PolynomialRedosSink).getRegExp() 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-780/RsaWithoutOaep.ql b/java/ql/src/Security/CWE/CWE-780/RsaWithoutOaep.ql index a2475202dd8..2191a4a7401 100644 --- a/java/ql/src/Security/CWE/CWE-780/RsaWithoutOaep.ql +++ b/java/ql/src/Security/CWE/CWE-780/RsaWithoutOaep.ql @@ -15,6 +15,6 @@ import semmle.code.java.security.RsaWithoutOaepQuery import RsaWithoutOaepFlow::PathGraph from RsaWithoutOaepFlow::PathNode source, RsaWithoutOaepFlow::PathNode sink -where RsaWithoutOaepFlow::hasFlowPath(source, sink) +where RsaWithoutOaepFlow::flowPath(source, sink) select source, source, sink, "This specification is used to $@ without OAEP padding.", sink, "initialize an RSA cipher" diff --git a/java/ql/src/Security/CWE/CWE-807/TaintedPermissionsCheck.ql b/java/ql/src/Security/CWE/CWE-807/TaintedPermissionsCheck.ql index bb48958443f..8debae02267 100644 --- a/java/ql/src/Security/CWE/CWE-807/TaintedPermissionsCheck.ql +++ b/java/ql/src/Security/CWE/CWE-807/TaintedPermissionsCheck.ql @@ -60,7 +60,7 @@ module TaintedPermissionsCheckFlowConfig implements DataFlow::ConfigSig { } } -module TaintedPermissionsCheckFlow = TaintTracking::Make<TaintedPermissionsCheckFlowConfig>; +module TaintedPermissionsCheckFlow = TaintTracking::Global<TaintedPermissionsCheckFlowConfig>; import TaintedPermissionsCheckFlow::PathGraph @@ -68,6 +68,6 @@ from TaintedPermissionsCheckFlow::PathNode source, TaintedPermissionsCheckFlow::PathNode sink, PermissionsConstruction p where - sink.getNode().asExpr() = p.getInput() and TaintedPermissionsCheckFlow::hasFlowPath(source, sink) + sink.getNode().asExpr() = p.getInput() and TaintedPermissionsCheckFlow::flowPath(source, sink) select p, source, sink, "Permissions check depends on a $@.", source.getNode(), "user-controlled value" diff --git a/java/ql/src/Security/CWE/CWE-918/RequestForgery.ql b/java/ql/src/Security/CWE/CWE-918/RequestForgery.ql index c3455dc4beb..570a7af54cc 100644 --- a/java/ql/src/Security/CWE/CWE-918/RequestForgery.ql +++ b/java/ql/src/Security/CWE/CWE-918/RequestForgery.ql @@ -16,6 +16,6 @@ import semmle.code.java.security.RequestForgeryConfig import RequestForgeryFlow::PathGraph from RequestForgeryFlow::PathNode source, RequestForgeryFlow::PathNode sink -where RequestForgeryFlow::hasFlowPath(source, sink) +where RequestForgeryFlow::flowPath(source, sink) select sink.getNode(), source, sink, "Potential server-side request forgery due to a $@.", source.getNode(), "user-provided value" diff --git a/java/ql/src/Security/CWE/CWE-927/SensitiveCommunication.ql b/java/ql/src/Security/CWE/CWE-927/SensitiveCommunication.ql index 59a7d827cf6..576927b1d72 100644 --- a/java/ql/src/Security/CWE/CWE-927/SensitiveCommunication.ql +++ b/java/ql/src/Security/CWE/CWE-927/SensitiveCommunication.ql @@ -16,6 +16,6 @@ import semmle.code.java.security.AndroidSensitiveCommunicationQuery import SensitiveCommunicationFlow::PathGraph from SensitiveCommunicationFlow::PathNode source, SensitiveCommunicationFlow::PathNode sink -where SensitiveCommunicationFlow::hasFlowPath(source, sink) +where SensitiveCommunicationFlow::flowPath(source, sink) select sink.getNode(), source, sink, "This call may leak $@.", source.getNode(), "sensitive information" diff --git a/java/ql/test/TestUtilities/InlineFlowTest.qll b/java/ql/test/TestUtilities/InlineFlowTest.qll index bd4ef924da2..efc5a6fab2b 100644 --- a/java/ql/test/TestUtilities/InlineFlowTest.qll +++ b/java/ql/test/TestUtilities/InlineFlowTest.qll @@ -57,9 +57,9 @@ module DefaultFlowConfig implements DataFlow::ConfigSig { int fieldFlowBranchLimit() { result = 1000 } } -private module DefaultValueFlow = DataFlow::Make<DefaultFlowConfig>; +private module DefaultValueFlow = DataFlow::Global<DefaultFlowConfig>; -private module DefaultTaintFlow = TaintTracking::Make<DefaultFlowConfig>; +private module DefaultTaintFlow = TaintTracking::Global<DefaultFlowConfig>; class DefaultValueFlowConf extends DataFlow::Configuration { DefaultValueFlowConf() { this = "qltest:defaultValueFlowConf" } @@ -118,13 +118,13 @@ class InlineFlowTest extends InlineExpectationsTest { predicate hasValueFlow(DataFlow::Node src, DataFlow::Node sink) { if exists(EnableLegacyConfiguration e) then getValueFlowConfig().hasFlow(src, sink) - else DefaultValueFlow::hasFlow(src, sink) + else DefaultValueFlow::flow(src, sink) } predicate hasTaintFlow(DataFlow::Node src, DataFlow::Node sink) { if exists(EnableLegacyConfiguration e) then getTaintFlowConfig().hasFlow(src, sink) - else DefaultTaintFlow::hasFlow(src, sink) + else DefaultTaintFlow::flow(src, sink) } DataFlow::Configuration getValueFlowConfig() { result = any(DefaultValueFlowConf config) } diff --git a/java/ql/test/library-tests/dataflow/inoutbarriers/test.ql b/java/ql/test/library-tests/dataflow/inoutbarriers/test.ql index a582f5b2456..7635dae3820 100644 --- a/java/ql/test/library-tests/dataflow/inoutbarriers/test.ql +++ b/java/ql/test/library-tests/dataflow/inoutbarriers/test.ql @@ -47,13 +47,13 @@ module Conf4 implements ConfigSig { } predicate flow(Node src, Node sink, string s) { - Make<Conf1>::hasFlow(src, sink) and s = "nobarrier" + Global<Conf1>::flow(src, sink) and s = "nobarrier" or - Make<Conf2>::hasFlow(src, sink) and s = "srcbarrier" + Global<Conf2>::flow(src, sink) and s = "srcbarrier" or - Make<Conf3>::hasFlow(src, sink) and s = "sinkbarrier" + Global<Conf3>::flow(src, sink) and s = "sinkbarrier" or - Make<Conf4>::hasFlow(src, sink) and s = "both" + Global<Conf4>::flow(src, sink) and s = "both" } from Node src, Node sink, string s diff --git a/java/ql/test/library-tests/dataflow/partial/test.ql b/java/ql/test/library-tests/dataflow/partial/test.ql index 399a876e9a9..4b2e5e71ff4 100644 --- a/java/ql/test/library-tests/dataflow/partial/test.ql +++ b/java/ql/test/library-tests/dataflow/partial/test.ql @@ -10,10 +10,10 @@ module Config implements ConfigSig { int explorationLimit() { result = 10 } -module PartialFlow = Make<Config>::FlowExploration<explorationLimit/0>; +module PartialFlow = Global<Config>::FlowExploration<explorationLimit/0>; import PartialFlow::PartialPathGraph from PartialFlow::PartialPathNode n, int dist -where PartialFlow::hasPartialFlow(_, n, dist) +where PartialFlow::partialFlow(_, n, dist) select dist, n diff --git a/java/ql/test/library-tests/dataflow/partial/testRev.ql b/java/ql/test/library-tests/dataflow/partial/testRev.ql index c869cb4f915..f3f71d69e3b 100644 --- a/java/ql/test/library-tests/dataflow/partial/testRev.ql +++ b/java/ql/test/library-tests/dataflow/partial/testRev.ql @@ -10,10 +10,10 @@ module Config implements ConfigSig { int explorationLimit() { result = 10 } -module PartialFlow = Make<Config>::FlowExploration<explorationLimit/0>; +module PartialFlow = Global<Config>::FlowExploration<explorationLimit/0>; import PartialFlow::PartialPathGraph from PartialFlow::PartialPathNode n, int dist -where PartialFlow::hasPartialFlowRev(n, _, dist) +where PartialFlow::partialFlowRev(n, _, dist) select dist, n diff --git a/java/ql/test/library-tests/dataflow/state/test.ql b/java/ql/test/library-tests/dataflow/state/test.ql index afd7ed9a97e..b82dd95c0b1 100644 --- a/java/ql/test/library-tests/dataflow/state/test.ql +++ b/java/ql/test/library-tests/dataflow/state/test.ql @@ -55,7 +55,7 @@ module Config implements DataFlow::StateConfigSig { int explorationLimit() { result = 0 } -module Flow = TaintTracking::MakeWithState<Config>; +module Flow = TaintTracking::GlobalWithState<Config>; module PartialFlow = Flow::FlowExploration<explorationLimit/0>; @@ -67,7 +67,7 @@ class HasFlowTest extends InlineExpectationsTest { override predicate hasActualResult(Location location, string element, string tag, string value) { tag = "flow" and exists(Flow::PathNode src, Flow::PathNode sink | - Flow::hasFlowPath(src, sink) and + Flow::flowPath(src, sink) and sink.getNode().getLocation() = location and element = sink.toString() and value = src.getState() @@ -75,7 +75,7 @@ class HasFlowTest extends InlineExpectationsTest { or tag = "pFwd" and exists(PartialFlow::PartialPathNode src, PartialFlow::PartialPathNode node | - PartialFlow::hasPartialFlow(src, node, _) and + PartialFlow::partialFlow(src, node, _) and checkNode(node.getNode()) and node.getNode().getLocation() = location and element = node.toString() and @@ -84,7 +84,7 @@ class HasFlowTest extends InlineExpectationsTest { or tag = "pRev" and exists(PartialFlow::PartialPathNode node, PartialFlow::PartialPathNode sink | - PartialFlow::hasPartialFlowRev(node, sink, _) and + PartialFlow::partialFlowRev(node, sink, _) and checkNode(node.getNode()) and node.getNode().getLocation() = location and element = node.toString() and diff --git a/java/ql/test/query-tests/security/CWE-094/ApkInstallationTest.ql b/java/ql/test/query-tests/security/CWE-094/ApkInstallationTest.ql index 1e40c0a5d25..dd6aec2ebe3 100644 --- a/java/ql/test/query-tests/security/CWE-094/ApkInstallationTest.ql +++ b/java/ql/test/query-tests/security/CWE-094/ApkInstallationTest.ql @@ -10,7 +10,7 @@ class HasApkInstallationTest extends InlineExpectationsTest { override predicate hasActualResult(Location location, string element, string tag, string value) { tag = "hasApkInstallation" and - exists(DataFlow::Node sink | ApkInstallationFlow::hasFlowTo(sink) | + exists(DataFlow::Node sink | ApkInstallationFlow::flowTo(sink) | sink.getLocation() = location and element = sink.toString() and value = "" diff --git a/java/ql/test/query-tests/security/CWE-117/LogInjectionTest.ql b/java/ql/test/query-tests/security/CWE-117/LogInjectionTest.ql index ba753b0d930..73a41b1bd8e 100644 --- a/java/ql/test/query-tests/security/CWE-117/LogInjectionTest.ql +++ b/java/ql/test/query-tests/security/CWE-117/LogInjectionTest.ql @@ -12,6 +12,6 @@ private class LogInjectionTest extends InlineFlowTest { override predicate hasValueFlow(DataFlow::Node src, DataFlow::Node sink) { none() } override predicate hasTaintFlow(DataFlow::Node src, DataFlow::Node sink) { - LogInjectionFlow::hasFlow(src, sink) + LogInjectionFlow::flow(src, sink) } } diff --git a/java/ql/test/query-tests/security/CWE-266/IntentUriPermissionManipulationTest.ql b/java/ql/test/query-tests/security/CWE-266/IntentUriPermissionManipulationTest.ql index c434dbe413a..d90039cf920 100644 --- a/java/ql/test/query-tests/security/CWE-266/IntentUriPermissionManipulationTest.ql +++ b/java/ql/test/query-tests/security/CWE-266/IntentUriPermissionManipulationTest.ql @@ -6,6 +6,6 @@ class IntentUriPermissionManipulationTest extends InlineFlowTest { override predicate hasValueFlow(DataFlow::Node src, DataFlow::Node sink) { none() } override predicate hasTaintFlow(DataFlow::Node src, DataFlow::Node sink) { - IntentUriPermissionManipulationFlow::hasFlow(src, sink) + IntentUriPermissionManipulationFlow::flow(src, sink) } } diff --git a/java/ql/test/query-tests/security/CWE-441/UnsafeContentUriResolutionTest.ql b/java/ql/test/query-tests/security/CWE-441/UnsafeContentUriResolutionTest.ql index 5e2046c6fbf..55c07bbd301 100644 --- a/java/ql/test/query-tests/security/CWE-441/UnsafeContentUriResolutionTest.ql +++ b/java/ql/test/query-tests/security/CWE-441/UnsafeContentUriResolutionTest.ql @@ -6,6 +6,6 @@ class Test extends InlineFlowTest { override predicate hasValueFlow(DataFlow::Node src, DataFlow::Node sink) { none() } override predicate hasTaintFlow(DataFlow::Node src, DataFlow::Node sink) { - UnsafeContentResolutionFlow::hasFlow(src, sink) + UnsafeContentResolutionFlow::flow(src, sink) } } diff --git a/java/ql/test/query-tests/security/CWE-470/FragmentInjectionTest.ql b/java/ql/test/query-tests/security/CWE-470/FragmentInjectionTest.ql index 22b02c818f5..2771dd3af90 100644 --- a/java/ql/test/query-tests/security/CWE-470/FragmentInjectionTest.ql +++ b/java/ql/test/query-tests/security/CWE-470/FragmentInjectionTest.ql @@ -6,6 +6,6 @@ class Test extends InlineFlowTest { override predicate hasValueFlow(DataFlow::Node src, DataFlow::Node sink) { none() } override predicate hasTaintFlow(DataFlow::Node src, DataFlow::Node sink) { - FragmentInjectionTaintFlow::hasFlow(src, sink) + FragmentInjectionTaintFlow::flow(src, sink) } } diff --git a/java/ql/test/query-tests/security/CWE-532/SensitiveLogInfo.ql b/java/ql/test/query-tests/security/CWE-532/SensitiveLogInfo.ql index b868dcabf85..5de153a9e35 100644 --- a/java/ql/test/query-tests/security/CWE-532/SensitiveLogInfo.ql +++ b/java/ql/test/query-tests/security/CWE-532/SensitiveLogInfo.ql @@ -4,7 +4,7 @@ import semmle.code.java.security.SensitiveLoggingQuery class HasFlowTest extends InlineFlowTest { override predicate hasTaintFlow(DataFlow::Node src, DataFlow::Node sink) { - SensitiveLoggerFlow::hasFlow(src, sink) + SensitiveLoggerFlow::flow(src, sink) } override predicate hasValueFlow(DataFlow::Node src, DataFlow::Node sink) { none() } 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 e31d890d908..75af0160def 100644 --- a/java/ql/test/query-tests/security/CWE-730/PolynomialReDoS.ql +++ b/java/ql/test/query-tests/security/CWE-730/PolynomialReDoS.ql @@ -9,7 +9,7 @@ class HasPolyRedos extends InlineExpectationsTest { override predicate hasActualResult(Location location, string element, string tag, string value) { tag = "hasPolyRedos" and exists(DataFlow::Node sink | - PolynomialRedosFlow::hasFlowTo(sink) and + PolynomialRedosFlow::flowTo(sink) and location = sink.getLocation() and element = sink.toString() and value = "" diff --git a/java/ql/test/query-tests/security/CWE-780/RsaWithoutOaepTest.ql b/java/ql/test/query-tests/security/CWE-780/RsaWithoutOaepTest.ql index cdfdaea621e..01af77284f0 100644 --- a/java/ql/test/query-tests/security/CWE-780/RsaWithoutOaepTest.ql +++ b/java/ql/test/query-tests/security/CWE-780/RsaWithoutOaepTest.ql @@ -7,6 +7,6 @@ class HasFlowTest extends InlineFlowTest { override predicate hasValueFlow(DataFlow::Node src, DataFlow::Node sink) { none() } override predicate hasTaintFlow(DataFlow::Node src, DataFlow::Node sink) { - RsaWithoutOaepFlow::hasFlow(src, sink) + RsaWithoutOaepFlow::flow(src, sink) } } diff --git a/java/ql/test/query-tests/security/CWE-918/RequestForgery.ql b/java/ql/test/query-tests/security/CWE-918/RequestForgery.ql index b27d81ee073..865e6e8f0d3 100644 --- a/java/ql/test/query-tests/security/CWE-918/RequestForgery.ql +++ b/java/ql/test/query-tests/security/CWE-918/RequestForgery.ql @@ -10,7 +10,7 @@ class HasFlowTest extends InlineExpectationsTest { override predicate hasActualResult(Location location, string element, string tag, string value) { tag = "SSRF" and exists(DataFlow::Node sink | - RequestForgeryFlow::hasFlowTo(sink) and + RequestForgeryFlow::flowTo(sink) and sink.getLocation() = location and element = sink.toString() and value = "" diff --git a/java/ql/test/query-tests/security/CWE-927/SensitiveCommunication.ql b/java/ql/test/query-tests/security/CWE-927/SensitiveCommunication.ql index c57c316310d..0f1864398b4 100644 --- a/java/ql/test/query-tests/security/CWE-927/SensitiveCommunication.ql +++ b/java/ql/test/query-tests/security/CWE-927/SensitiveCommunication.ql @@ -7,6 +7,6 @@ class HasFlowTest extends InlineFlowTest { override predicate hasValueFlow(DataFlow::Node src, DataFlow::Node sink) { none() } override predicate hasTaintFlow(DataFlow::Node src, DataFlow::Node sink) { - SensitiveCommunicationFlow::hasFlow(src, sink) + SensitiveCommunicationFlow::flow(src, sink) } } From 72415c7c2c729901ea16295d8105043f363e4751 Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen <aschackmull@github.com> Date: Thu, 23 Mar 2023 13:00:44 +0100 Subject: [PATCH 342/631] C++: Rename references. --- .../cpp/security/PrivateCleartextWrite.qll | 2 +- .../internal/DefaultTaintTrackingImpl.qll | 20 +++++++++---------- .../cpp/security/boostorg/asio/protocols.qll | 6 +++--- cpp/ql/src/Critical/OverflowDestination.ql | 4 ++-- .../Conversion/CastArrayPointerArithmetic.ql | 4 ++-- .../Likely Bugs/Format/NonConstantFormat.ql | 4 ++-- .../Leap Year/Adding365DaysPerYear.ql | 2 +- cpp/ql/src/Likely Bugs/Leap Year/LeapYear.qll | 6 +++--- .../UncheckedLeapYearAfterYearModification.ql | 4 ++-- .../Memory Management/NtohlArrayNoBound.ql | 2 +- .../Memory Management/NtohlArrayNoBound.qll | 2 +- .../Protocols/TlsSettingsMisconfiguration.ql | 8 ++++---- .../UseOfDeprecatedHardcodedProtocol.ql | 6 +++--- .../src/Security/CWE/CWE-020/ExternalAPIs.qll | 4 ++-- .../CWE/CWE-020/ExternalAPIsSpecific.qll | 2 +- .../CWE-020/IRUntrustedDataToExternalAPI.ql | 2 +- .../CWE/CWE-020/UntrustedDataToExternalAPI.ql | 2 +- .../Security/CWE/CWE-020/ir/ExternalAPIs.qll | 4 ++-- .../CWE/CWE-020/ir/ExternalAPIsSpecific.qll | 2 +- .../src/Security/CWE/CWE-022/TaintedPath.ql | 4 ++-- .../src/Security/CWE/CWE-078/ExecTainted.ql | 8 ++++---- .../CWE-129/ImproperArrayIndexValidation.ql | 4 ++-- .../CWE/CWE-190/ArithmeticUncontrolled.ql | 4 ++-- .../CWE/CWE-190/TaintedAllocationSize.ql | 4 ++-- .../CWE/CWE-295/SSLResultConflation.ql | 6 +++--- .../CWE/CWE-311/CleartextBufferWrite.ql | 4 ++-- .../CWE/CWE-311/CleartextFileWrite.ql | 4 ++-- .../CWE/CWE-311/CleartextTransmission.ql | 16 +++++++-------- .../CWE/CWE-313/CleartextSqliteDatabase.ql | 4 ++-- cpp/ql/src/Security/CWE/CWE-319/UseOfHttp.ql | 4 ++-- .../CWE/CWE-326/InsufficientKeySize.ql | 4 ++-- .../CWE/CWE-428/UnsafeCreateProcessCall.ql | 8 ++++---- .../Security/CWE/CWE-497/ExposedSystemData.ql | 6 +++--- .../CWE-497/PotentiallyExposedSystemData.ql | 4 ++-- cpp/ql/src/Security/CWE/CWE-611/XXE.ql | 4 ++-- .../CWE-732/UnsafeDaclSecurityDescriptor.ql | 8 ++++---- .../Security/CWE/CWE-078/WordexpTainted.ql | 4 ++-- .../CWE-190/AllocMultiplicationOverflow.ql | 4 ++-- .../CWE/CWE-193/ConstantSizeArrayOffByOne.ql | 8 ++++---- .../CWE/CWE-193/InvalidPointerDeref.ql | 6 +++--- .../CWE/CWE-359/PrivateCleartextWrite.ql | 2 +- .../analyzing-data-flow-in-cpp/exercise2.ql | 4 ++-- .../analyzing-data-flow-in-cpp/exercise4.ql | 4 ++-- .../fopen-flow-from-getenv.ql | 4 ++-- .../index-flow-from-ntohl.ql | 4 ++-- .../standardFlow.ql | 4 ++-- .../withAdditionalFlow.ql | 4 ++-- .../library-tests/dataflow/crement/from0.ql | 4 ++-- 48 files changed, 117 insertions(+), 117 deletions(-) diff --git a/cpp/ql/lib/experimental/semmle/code/cpp/security/PrivateCleartextWrite.qll b/cpp/ql/lib/experimental/semmle/code/cpp/security/PrivateCleartextWrite.qll index 416bf4b04f8..e733940bdc1 100644 --- a/cpp/ql/lib/experimental/semmle/code/cpp/security/PrivateCleartextWrite.qll +++ b/cpp/ql/lib/experimental/semmle/code/cpp/security/PrivateCleartextWrite.qll @@ -54,7 +54,7 @@ module PrivateCleartextWrite { predicate isBarrier(DataFlow::Node node) { node instanceof Sanitizer } } - module WriteFlow = TaintTracking::Make<WriteConfig>; + module WriteFlow = TaintTracking::Global<WriteConfig>; class PrivateDataSource extends Source { PrivateDataSource() { this.getExpr() instanceof PrivateDataExpr } diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DefaultTaintTrackingImpl.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DefaultTaintTrackingImpl.qll index 2c288b6d3da..e21a83fcb54 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DefaultTaintTrackingImpl.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DefaultTaintTrackingImpl.qll @@ -103,7 +103,7 @@ private module DefaultTaintTrackingConfig implements DataFlow::ConfigSig { } } -private module DefaultTaintTrackingFlow = TaintTracking::Make<DefaultTaintTrackingConfig>; +private module DefaultTaintTrackingFlow = TaintTracking::Global<DefaultTaintTrackingConfig>; private module ToGlobalVarTaintTrackingConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { source = getNodeForSource(_) } @@ -121,13 +121,13 @@ private module ToGlobalVarTaintTrackingConfig implements DataFlow::ConfigSig { predicate isBarrierIn(DataFlow::Node node) { nodeIsBarrierIn(node) } } -private module ToGlobalVarTaintTrackingFlow = TaintTracking::Make<ToGlobalVarTaintTrackingConfig>; +private module ToGlobalVarTaintTrackingFlow = TaintTracking::Global<ToGlobalVarTaintTrackingConfig>; private module FromGlobalVarTaintTrackingConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { // This set of sources should be reasonably small, which is good for // performance since the set of sinks is very large. - ToGlobalVarTaintTrackingFlow::hasFlowTo(source) + ToGlobalVarTaintTrackingFlow::flowTo(source) } predicate isSink(DataFlow::Node sink) { exists(adjustedSink(sink)) } @@ -145,7 +145,7 @@ private module FromGlobalVarTaintTrackingConfig implements DataFlow::ConfigSig { } private module FromGlobalVarTaintTrackingFlow = - TaintTracking::Make<FromGlobalVarTaintTrackingConfig>; + TaintTracking::Global<FromGlobalVarTaintTrackingConfig>; private predicate readsVariable(LoadInstruction load, Variable var) { load.getSourceAddress().(VariableAddressInstruction).getAstVariable() = var @@ -331,7 +331,7 @@ private import Cached cached predicate tainted(Expr source, Element tainted) { exists(DataFlow::Node sink | - DefaultTaintTrackingFlow::hasFlow(getNodeForSource(source), sink) and + DefaultTaintTrackingFlow::flow(getNodeForSource(source), sink) and tainted = adjustedSink(sink) ) } @@ -360,8 +360,8 @@ predicate taintedIncludingGlobalVars(Expr source, Element tainted, string global DataFlow::VariableNode variableNode, GlobalOrNamespaceVariable global, DataFlow::Node sink | global = variableNode.getVariable() and - ToGlobalVarTaintTrackingFlow::hasFlow(getNodeForSource(source), variableNode) and - FromGlobalVarTaintTrackingFlow::hasFlow(variableNode, sink) and + ToGlobalVarTaintTrackingFlow::flow(getNodeForSource(source), variableNode) and + FromGlobalVarTaintTrackingFlow::flow(variableNode, sink) and tainted = adjustedSink(sink) and global = globalVarFromId(globalVar) ) @@ -450,7 +450,7 @@ module TaintedWithPath { predicate isBarrierIn(DataFlow::Node node) { nodeIsBarrierIn(node) } } - private module AdjustedFlow = TaintTracking::Make<AdjustedConfig>; + private module AdjustedFlow = TaintTracking::Global<AdjustedConfig>; /* * A sink `Element` may map to multiple `DataFlowX::PathNode`s via (the @@ -472,7 +472,7 @@ module TaintedWithPath { // that makes it easiest to deal with the case where source = sink. TEndpointPathNode(Element e) { exists(DataFlow::Node sourceNode, DataFlow::Node sinkNode | - AdjustedFlow::hasFlow(sourceNode, sinkNode) + AdjustedFlow::flow(sourceNode, sinkNode) | sourceNode = getNodeForExpr(e) and exists(TaintTrackingConfiguration ttCfg | ttCfg.isSource(e)) @@ -634,7 +634,7 @@ module TaintedWithPath { exists(DataFlow::Node flowSource, DataFlow::Node flowSink | source = sourceNode.(InitialPathNode).inner() and flowSource = getNodeForExpr(source) and - AdjustedFlow::hasFlow(flowSource, flowSink) and + AdjustedFlow::flow(flowSource, flowSink) and tainted = adjustedSink(flowSink) and tainted = sinkNode.(FinalPathNode).inner() ) diff --git a/cpp/ql/lib/semmle/code/cpp/security/boostorg/asio/protocols.qll b/cpp/ql/lib/semmle/code/cpp/security/boostorg/asio/protocols.qll index 6a0841e13e2..e53be5980b1 100644 --- a/cpp/ql/lib/semmle/code/cpp/security/boostorg/asio/protocols.qll +++ b/cpp/ql/lib/semmle/code/cpp/security/boostorg/asio/protocols.qll @@ -399,7 +399,7 @@ module BoostorgAsio { import Config } - import DataFlow::Make<C> + import DataFlow::Global<C> } /** @@ -596,7 +596,7 @@ module BoostorgAsio { } } - module SslContextFlowsToSetOptionFlow = DataFlow::Make<SslContextFlowsToSetOptionConfig>; + module SslContextFlowsToSetOptionFlow = DataFlow::Global<SslContextFlowsToSetOptionConfig>; /** * An option value that flows to the first parameter of a call to `SetOptions()`. @@ -640,5 +640,5 @@ module BoostorgAsio { } } - module SslOptionFlow = DataFlow::Make<SslOptionConfig>; + module SslOptionFlow = DataFlow::Global<SslOptionConfig>; } diff --git a/cpp/ql/src/Critical/OverflowDestination.ql b/cpp/ql/src/Critical/OverflowDestination.ql index 39ce527e08a..4cfaaf8981b 100644 --- a/cpp/ql/src/Critical/OverflowDestination.ql +++ b/cpp/ql/src/Critical/OverflowDestination.ql @@ -84,11 +84,11 @@ module OverflowDestinationConfig implements DataFlow::ConfigSig { } } -module OverflowDestination = TaintTracking::Make<OverflowDestinationConfig>; +module OverflowDestination = TaintTracking::Global<OverflowDestinationConfig>; from FunctionCall fc, OverflowDestination::PathNode source, OverflowDestination::PathNode sink where - OverflowDestination::hasFlowPath(source, sink) and + OverflowDestination::flowPath(source, sink) and sourceSized(fc, sink.getNode().asIndirectConvertedExpr()) select fc, source, sink, "To avoid overflow, this operation should be bounded by destination-buffer size, not source-buffer size." diff --git a/cpp/ql/src/Likely Bugs/Conversion/CastArrayPointerArithmetic.ql b/cpp/ql/src/Likely Bugs/Conversion/CastArrayPointerArithmetic.ql index 03f622855ab..79a5d530c21 100644 --- a/cpp/ql/src/Likely Bugs/Conversion/CastArrayPointerArithmetic.ql +++ b/cpp/ql/src/Likely Bugs/Conversion/CastArrayPointerArithmetic.ql @@ -80,9 +80,9 @@ predicate introducesNewField(Class derived, Class base) { ) } -module CastToPointerArithFlow = DataFlow::MakeWithState<CastToPointerArithFlowConfig>; +module CastToPointerArithFlow = DataFlow::GlobalWithState<CastToPointerArithFlowConfig>; from CastToPointerArithFlow::PathNode source, CastToPointerArithFlow::PathNode sink -where CastToPointerArithFlow::hasFlowPath(source, sink) +where CastToPointerArithFlow::flowPath(source, sink) select sink, source, sink, "This pointer arithmetic may be done with the wrong type because of $@.", source, "this cast" diff --git a/cpp/ql/src/Likely Bugs/Format/NonConstantFormat.ql b/cpp/ql/src/Likely Bugs/Format/NonConstantFormat.ql index 2b2e9f6bf8b..65454332ab1 100644 --- a/cpp/ql/src/Likely Bugs/Format/NonConstantFormat.ql +++ b/cpp/ql/src/Likely Bugs/Format/NonConstantFormat.ql @@ -146,13 +146,13 @@ module NonConstFlowConfig implements DataFlow::ConfigSig { predicate isBarrier(DataFlow::Node node) { isBarrierNode(node) } } -module NonConstFlow = TaintTracking::Make<NonConstFlowConfig>; +module NonConstFlow = TaintTracking::Global<NonConstFlowConfig>; from FormattingFunctionCall call, Expr formatString where call.getArgument(call.getFormatParameterIndex()) = formatString and exists(DataFlow::Node sink | - NonConstFlow::hasFlowTo(sink) and + NonConstFlow::flowTo(sink) and isSinkImpl(sink, formatString) ) select formatString, diff --git a/cpp/ql/src/Likely Bugs/Leap Year/Adding365DaysPerYear.ql b/cpp/ql/src/Likely Bugs/Leap Year/Adding365DaysPerYear.ql index fe6581340de..71aa97c0ae5 100644 --- a/cpp/ql/src/Likely Bugs/Leap Year/Adding365DaysPerYear.ql +++ b/cpp/ql/src/Likely Bugs/Leap Year/Adding365DaysPerYear.ql @@ -16,7 +16,7 @@ import LeapYear from Expr source, Expr sink where - PossibleYearArithmeticOperationCheckFlow::hasFlow(DataFlow::exprNode(source), + PossibleYearArithmeticOperationCheckFlow::flow(DataFlow::exprNode(source), DataFlow::exprNode(sink)) select sink, "An arithmetic operation $@ that uses a constant value of 365 ends up modifying this date/time, without considering leap year scenarios.", diff --git a/cpp/ql/src/Likely Bugs/Leap Year/LeapYear.qll b/cpp/ql/src/Likely Bugs/Leap Year/LeapYear.qll index a838f4c6a0d..7a375e7b107 100644 --- a/cpp/ql/src/Likely Bugs/Leap Year/LeapYear.qll +++ b/cpp/ql/src/Likely Bugs/Leap Year/LeapYear.qll @@ -231,7 +231,7 @@ private module LeapYearCheckConfig implements DataFlow::ConfigSig { } } -module LeapYearCheckFlow = DataFlow::Make<LeapYearCheckConfig>; +module LeapYearCheckFlow = DataFlow::Global<LeapYearCheckConfig>; /** * Data flow configuration for finding an operation with hardcoded 365 that will flow into @@ -284,7 +284,7 @@ private module FiletimeYearArithmeticOperationCheckConfig implements DataFlow::C } module FiletimeYearArithmeticOperationCheckFlow = - DataFlow::Make<FiletimeYearArithmeticOperationCheckConfig>; + DataFlow::Global<FiletimeYearArithmeticOperationCheckConfig>; /** * Taint configuration for finding an operation with hardcoded 365 that will flow into any known date/time field. @@ -372,4 +372,4 @@ private module PossibleYearArithmeticOperationCheckConfig implements DataFlow::C } module PossibleYearArithmeticOperationCheckFlow = - TaintTracking::Make<PossibleYearArithmeticOperationCheckConfig>; + TaintTracking::Global<PossibleYearArithmeticOperationCheckConfig>; diff --git a/cpp/ql/src/Likely Bugs/Leap Year/UncheckedLeapYearAfterYearModification.ql b/cpp/ql/src/Likely Bugs/Leap Year/UncheckedLeapYearAfterYearModification.ql index f85270d523e..1cc51a0d3e2 100644 --- a/cpp/ql/src/Likely Bugs/Leap Year/UncheckedLeapYearAfterYearModification.ql +++ b/cpp/ql/src/Likely Bugs/Leap Year/UncheckedLeapYearAfterYearModification.ql @@ -31,7 +31,7 @@ where // If there is a data flow from the variable that was modified to a function that seems to check for leap year exists(VariableAccess source, ChecksForLeapYearFunctionCall fc | source = var.getAnAccess() and - LeapYearCheckFlow::hasFlow(DataFlow::exprNode(source), + LeapYearCheckFlow::flow(DataFlow::exprNode(source), DataFlow::exprNode(fc.getAnArgument())) ) or @@ -39,7 +39,7 @@ where exists(VariableAccess vacheck, YearFieldAccess yfacheck, ChecksForLeapYearFunctionCall fc | vacheck = var.getAnAccess() and yfacheck.getQualifier() = vacheck and - LeapYearCheckFlow::hasFlow(DataFlow::exprNode(yfacheck), + LeapYearCheckFlow::flow(DataFlow::exprNode(yfacheck), DataFlow::exprNode(fc.getAnArgument())) ) or diff --git a/cpp/ql/src/Likely Bugs/Memory Management/NtohlArrayNoBound.ql b/cpp/ql/src/Likely Bugs/Memory Management/NtohlArrayNoBound.ql index c23eda355c4..38ecd4183ff 100644 --- a/cpp/ql/src/Likely Bugs/Memory Management/NtohlArrayNoBound.ql +++ b/cpp/ql/src/Likely Bugs/Memory Management/NtohlArrayNoBound.ql @@ -12,5 +12,5 @@ import cpp import NtohlArrayNoBound from DataFlow::Node source, DataFlow::Node sink -where NetworkToBufferSizeFlow::hasFlow(source, sink) +where NetworkToBufferSizeFlow::flow(source, sink) select sink, "Unchecked use of data from network function $@.", source, source.toString() diff --git a/cpp/ql/src/Likely Bugs/Memory Management/NtohlArrayNoBound.qll b/cpp/ql/src/Likely Bugs/Memory Management/NtohlArrayNoBound.qll index e3b095d74dd..1bd90084c67 100644 --- a/cpp/ql/src/Likely Bugs/Memory Management/NtohlArrayNoBound.qll +++ b/cpp/ql/src/Likely Bugs/Memory Management/NtohlArrayNoBound.qll @@ -161,4 +161,4 @@ private module NetworkToBufferSizeConfig implements DataFlow::ConfigSig { } } -module NetworkToBufferSizeFlow = DataFlow::Make<NetworkToBufferSizeConfig>; +module NetworkToBufferSizeFlow = DataFlow::Global<NetworkToBufferSizeConfig>; diff --git a/cpp/ql/src/Likely Bugs/Protocols/TlsSettingsMisconfiguration.ql b/cpp/ql/src/Likely Bugs/Protocols/TlsSettingsMisconfiguration.ql index e7baf96615e..61989db1c6e 100644 --- a/cpp/ql/src/Likely Bugs/Protocols/TlsSettingsMisconfiguration.ql +++ b/cpp/ql/src/Likely Bugs/Protocols/TlsSettingsMisconfiguration.ql @@ -25,17 +25,17 @@ module ExistsAnyFlowConfig implements DataFlow::ConfigSig { } } -module ExistsAnyFlow = DataFlow::Make<ExistsAnyFlowConfig>; +module ExistsAnyFlow = DataFlow::Global<ExistsAnyFlowConfig>; bindingset[flag] predicate isOptionSet(ConstructorCall cc, int flag, FunctionCall fcSetOptions) { exists(VariableAccess contextSetOptions | - ExistsAnyFlow::hasFlow(DataFlow::exprNode(cc), DataFlow::exprNode(contextSetOptions)) and + ExistsAnyFlow::flow(DataFlow::exprNode(cc), DataFlow::exprNode(contextSetOptions)) and exists(BoostorgAsio::SslSetOptionsFunction f | f.getACallToThisFunction() = fcSetOptions | contextSetOptions = fcSetOptions.getQualifier() and forall(Expr optionArgument, Expr optionArgumentSource | optionArgument = fcSetOptions.getArgument(0) and - BoostorgAsio::SslOptionFlow::hasFlow(DataFlow::exprNode(optionArgumentSource), + BoostorgAsio::SslOptionFlow::flow(DataFlow::exprNode(optionArgumentSource), DataFlow::exprNode(optionArgument)) | optionArgument.getValue().toInt().bitShiftRight(16).bitAnd(flag) = flag @@ -49,7 +49,7 @@ predicate isOptionNotSet(ConstructorCall cc, int flag) { not isOptionSet(cc, fla from Expr protocolSource, Expr protocolSink, ConstructorCall cc, Expr e, string msg where - BoostorgAsio::SslContextCallTlsProtocolFlow::hasFlow(DataFlow::exprNode(protocolSource), + BoostorgAsio::SslContextCallTlsProtocolFlow::flow(DataFlow::exprNode(protocolSource), DataFlow::exprNode(protocolSink)) and cc.getArgument(0) = protocolSink and ( diff --git a/cpp/ql/src/Likely Bugs/Protocols/UseOfDeprecatedHardcodedProtocol.ql b/cpp/ql/src/Likely Bugs/Protocols/UseOfDeprecatedHardcodedProtocol.ql index 140cf8e2ccf..4df70695179 100644 --- a/cpp/ql/src/Likely Bugs/Protocols/UseOfDeprecatedHardcodedProtocol.ql +++ b/cpp/ql/src/Likely Bugs/Protocols/UseOfDeprecatedHardcodedProtocol.ql @@ -14,12 +14,12 @@ import semmle.code.cpp.security.boostorg.asio.protocols from Expr protocolSource, Expr protocolSink, ConstructorCall cc where - BoostorgAsio::SslContextCallFlow::hasFlow(DataFlow::exprNode(protocolSource), + BoostorgAsio::SslContextCallFlow::flow(DataFlow::exprNode(protocolSource), DataFlow::exprNode(protocolSink)) and - not BoostorgAsio::SslContextCallTlsProtocolFlow::hasFlow(DataFlow::exprNode(protocolSource), + not BoostorgAsio::SslContextCallTlsProtocolFlow::flow(DataFlow::exprNode(protocolSource), DataFlow::exprNode(protocolSink)) and cc.getArgument(0) = protocolSink and - BoostorgAsio::SslContextCallBannedProtocolFlow::hasFlow(DataFlow::exprNode(protocolSource), + BoostorgAsio::SslContextCallBannedProtocolFlow::flow(DataFlow::exprNode(protocolSource), DataFlow::exprNode(protocolSink)) select protocolSink, "Usage of $@ specifying a deprecated hardcoded protocol $@ in function $@.", cc, "boost::asio::ssl::context::context", protocolSource, protocolSource.toString(), diff --git a/cpp/ql/src/Security/CWE/CWE-020/ExternalAPIs.qll b/cpp/ql/src/Security/CWE/CWE-020/ExternalAPIs.qll index 6d6f17daf0e..70247bdf4a4 100644 --- a/cpp/ql/src/Security/CWE/CWE-020/ExternalAPIs.qll +++ b/cpp/ql/src/Security/CWE/CWE-020/ExternalAPIs.qll @@ -10,10 +10,10 @@ import ExternalAPIsSpecific /** A node representing untrusted data being passed to an external API. */ class UntrustedExternalApiDataNode extends ExternalApiDataNode { - UntrustedExternalApiDataNode() { UntrustedDataToExternalApiFlow::hasFlow(_, this) } + UntrustedExternalApiDataNode() { UntrustedDataToExternalApiFlow::flow(_, this) } /** Gets a source of untrusted data which is passed to this external API data node. */ - DataFlow::Node getAnUntrustedSource() { UntrustedDataToExternalApiFlow::hasFlow(result, this) } + DataFlow::Node getAnUntrustedSource() { UntrustedDataToExternalApiFlow::flow(result, this) } } /** DEPRECATED: Alias for UntrustedExternalApiDataNode */ diff --git a/cpp/ql/src/Security/CWE/CWE-020/ExternalAPIsSpecific.qll b/cpp/ql/src/Security/CWE/CWE-020/ExternalAPIsSpecific.qll index d2ab4f0309f..2505f718bc6 100644 --- a/cpp/ql/src/Security/CWE/CWE-020/ExternalAPIsSpecific.qll +++ b/cpp/ql/src/Security/CWE/CWE-020/ExternalAPIsSpecific.qll @@ -73,4 +73,4 @@ private module UntrustedDataToExternalApiConfig implements DataFlow::ConfigSig { predicate isSink(DataFlow::Node sink) { sink instanceof ExternalApiDataNode } } -module UntrustedDataToExternalApiFlow = TaintTracking::Make<UntrustedDataToExternalApiConfig>; +module UntrustedDataToExternalApiFlow = TaintTracking::Global<UntrustedDataToExternalApiConfig>; diff --git a/cpp/ql/src/Security/CWE/CWE-020/IRUntrustedDataToExternalAPI.ql b/cpp/ql/src/Security/CWE/CWE-020/IRUntrustedDataToExternalAPI.ql index d16ce6376dd..432f47f6735 100644 --- a/cpp/ql/src/Security/CWE/CWE-020/IRUntrustedDataToExternalAPI.ql +++ b/cpp/ql/src/Security/CWE/CWE-020/IRUntrustedDataToExternalAPI.ql @@ -16,7 +16,7 @@ import semmle.code.cpp.security.FlowSources import UntrustedDataToExternalApiFlow::PathGraph from UntrustedDataToExternalApiFlow::PathNode source, UntrustedDataToExternalApiFlow::PathNode sink -where UntrustedDataToExternalApiFlow::hasFlowPath(source, sink) +where UntrustedDataToExternalApiFlow::flowPath(source, sink) select sink, source, sink, "Call to " + sink.getNode().(ExternalApiDataNode).getExternalFunction().toString() + " with untrusted data from $@.", source, source.getNode().(RemoteFlowSource).getSourceType() diff --git a/cpp/ql/src/Security/CWE/CWE-020/UntrustedDataToExternalAPI.ql b/cpp/ql/src/Security/CWE/CWE-020/UntrustedDataToExternalAPI.ql index a00accd4d29..1cfd0a7132f 100644 --- a/cpp/ql/src/Security/CWE/CWE-020/UntrustedDataToExternalAPI.ql +++ b/cpp/ql/src/Security/CWE/CWE-020/UntrustedDataToExternalAPI.ql @@ -15,7 +15,7 @@ import ExternalAPIs import UntrustedDataToExternalApiFlow::PathGraph from UntrustedDataToExternalApiFlow::PathNode source, UntrustedDataToExternalApiFlow::PathNode sink -where UntrustedDataToExternalApiFlow::hasFlowPath(source, sink) +where UntrustedDataToExternalApiFlow::flowPath(source, sink) select sink, source, sink, "Call to " + sink.getNode().(ExternalApiDataNode).getExternalFunction().toString() + " with untrusted data from $@.", source, source.toString() diff --git a/cpp/ql/src/Security/CWE/CWE-020/ir/ExternalAPIs.qll b/cpp/ql/src/Security/CWE/CWE-020/ir/ExternalAPIs.qll index 6d6f17daf0e..70247bdf4a4 100644 --- a/cpp/ql/src/Security/CWE/CWE-020/ir/ExternalAPIs.qll +++ b/cpp/ql/src/Security/CWE/CWE-020/ir/ExternalAPIs.qll @@ -10,10 +10,10 @@ import ExternalAPIsSpecific /** A node representing untrusted data being passed to an external API. */ class UntrustedExternalApiDataNode extends ExternalApiDataNode { - UntrustedExternalApiDataNode() { UntrustedDataToExternalApiFlow::hasFlow(_, this) } + UntrustedExternalApiDataNode() { UntrustedDataToExternalApiFlow::flow(_, this) } /** Gets a source of untrusted data which is passed to this external API data node. */ - DataFlow::Node getAnUntrustedSource() { UntrustedDataToExternalApiFlow::hasFlow(result, this) } + DataFlow::Node getAnUntrustedSource() { UntrustedDataToExternalApiFlow::flow(result, this) } } /** DEPRECATED: Alias for UntrustedExternalApiDataNode */ diff --git a/cpp/ql/src/Security/CWE/CWE-020/ir/ExternalAPIsSpecific.qll b/cpp/ql/src/Security/CWE/CWE-020/ir/ExternalAPIsSpecific.qll index 4dd077f24ce..93da5497a22 100644 --- a/cpp/ql/src/Security/CWE/CWE-020/ir/ExternalAPIsSpecific.qll +++ b/cpp/ql/src/Security/CWE/CWE-020/ir/ExternalAPIsSpecific.qll @@ -63,4 +63,4 @@ private module UntrustedDataToExternalApiConfig implements DataFlow::ConfigSig { predicate isSink(DataFlow::Node sink) { sink instanceof ExternalApiDataNode } } -module UntrustedDataToExternalApiFlow = TaintTracking::Make<UntrustedDataToExternalApiConfig>; +module UntrustedDataToExternalApiFlow = TaintTracking::Global<UntrustedDataToExternalApiConfig>; diff --git a/cpp/ql/src/Security/CWE/CWE-022/TaintedPath.ql b/cpp/ql/src/Security/CWE/CWE-022/TaintedPath.ql index 89d8f975680..4e626d0bc77 100644 --- a/cpp/ql/src/Security/CWE/CWE-022/TaintedPath.ql +++ b/cpp/ql/src/Security/CWE/CWE-022/TaintedPath.ql @@ -90,7 +90,7 @@ module TaintedPathConfig implements DataFlow::ConfigSig { } } -module TaintedPath = TaintTracking::Make<TaintedPathConfig>; +module TaintedPath = TaintTracking::Global<TaintedPathConfig>; from FileFunction fileFunction, Expr taintedArg, FlowSource taintSource, @@ -98,7 +98,7 @@ from where taintedArg = sinkNode.getNode().asIndirectArgument() and fileFunction.outermostWrapperFunctionCall(taintedArg, callChain) and - TaintedPath::hasFlowPath(sourceNode, sinkNode) and + TaintedPath::flowPath(sourceNode, sinkNode) and taintSource = sourceNode.getNode() select taintedArg, sourceNode, sinkNode, "This argument to a file access function is derived from $@ and then passed to " + callChain + ".", diff --git a/cpp/ql/src/Security/CWE/CWE-078/ExecTainted.ql b/cpp/ql/src/Security/CWE/CWE-078/ExecTainted.ql index c7e01e0b983..cc4b748e5dc 100644 --- a/cpp/ql/src/Security/CWE/CWE-078/ExecTainted.ql +++ b/cpp/ql/src/Security/CWE/CWE-078/ExecTainted.ql @@ -76,7 +76,7 @@ class ExecState extends TExecState { DataFlow::Node getOutgoingNode() { result = outgoing } /** Holds if this is a possible `ExecState` for `sink`. */ - predicate isFeasibleForSink(DataFlow::Node sink) { ExecState::hasFlow(outgoing, sink) } + predicate isFeasibleForSink(DataFlow::Node sink) { ExecState::flow(outgoing, sink) } string toString() { result = "ExecState" } } @@ -109,7 +109,7 @@ module ExecStateConfig implements DataFlow::ConfigSig { } } -module ExecState = TaintTracking::Make<ExecStateConfig>; +module ExecState = TaintTracking::Global<ExecStateConfig>; module ExecTaintConfig implements DataFlow::StateConfigSig { class FlowState = TState; @@ -141,13 +141,13 @@ module ExecTaintConfig implements DataFlow::StateConfigSig { } } -module ExecTaint = TaintTracking::MakeWithState<ExecTaintConfig>; +module ExecTaint = TaintTracking::GlobalWithState<ExecTaintConfig>; from ExecTaint::PathNode sourceNode, ExecTaint::PathNode sinkNode, string taintCause, string callChain, DataFlow::Node concatResult, Expr command where - ExecTaint::hasFlowPath(sourceNode, sinkNode) and + ExecTaint::flowPath(sourceNode, sinkNode) and taintCause = sourceNode.getNode().(FlowSource).getSourceType() and isSinkImpl(sinkNode.getNode(), command, callChain) and concatResult = sinkNode.getState().(ExecState).getOutgoingNode() diff --git a/cpp/ql/src/Security/CWE/CWE-129/ImproperArrayIndexValidation.ql b/cpp/ql/src/Security/CWE/CWE-129/ImproperArrayIndexValidation.ql index 598e242b0ef..107be7bddfd 100644 --- a/cpp/ql/src/Security/CWE/CWE-129/ImproperArrayIndexValidation.ql +++ b/cpp/ql/src/Security/CWE/CWE-129/ImproperArrayIndexValidation.ql @@ -114,13 +114,13 @@ module ImproperArrayIndexValidationConfig implements DataFlow::ConfigSig { } } -module ImproperArrayIndexValidation = TaintTracking::Make<ImproperArrayIndexValidationConfig>; +module ImproperArrayIndexValidation = TaintTracking::Global<ImproperArrayIndexValidationConfig>; from ImproperArrayIndexValidation::PathNode source, ImproperArrayIndexValidation::PathNode sink, string sourceType where - ImproperArrayIndexValidation::hasFlowPath(source, sink) and + ImproperArrayIndexValidation::flowPath(source, sink) and isFlowSource(source.getNode(), sourceType) select sink.getNode(), source, sink, "An array indexing expression depends on $@ that might be outside the bounds of the array.", diff --git a/cpp/ql/src/Security/CWE/CWE-190/ArithmeticUncontrolled.ql b/cpp/ql/src/Security/CWE/CWE-190/ArithmeticUncontrolled.ql index a4d37eb4875..54c3b013471 100644 --- a/cpp/ql/src/Security/CWE/CWE-190/ArithmeticUncontrolled.ql +++ b/cpp/ql/src/Security/CWE/CWE-190/ArithmeticUncontrolled.ql @@ -122,7 +122,7 @@ module UncontrolledArithConfig implements DataFlow::ConfigSig { } } -module UncontrolledArith = TaintTracking::Make<UncontrolledArithConfig>; +module UncontrolledArith = TaintTracking::Global<UncontrolledArithConfig>; /** Gets the expression that corresponds to `node`, if any. */ Expr getExpr(DataFlow::Node node) { result = [node.asExpr(), node.asDefiningArgument()] } @@ -131,7 +131,7 @@ from UncontrolledArith::PathNode source, UncontrolledArith::PathNode sink, VariableAccess va, string effect where - UncontrolledArith::hasFlowPath(source, sink) and + UncontrolledArith::flowPath(source, sink) and sink.getNode().asExpr() = va and missingGuard(va, effect) select sink.getNode(), source, sink, diff --git a/cpp/ql/src/Security/CWE/CWE-190/TaintedAllocationSize.ql b/cpp/ql/src/Security/CWE/CWE-190/TaintedAllocationSize.ql index 4d242890528..740e4ad9e8e 100644 --- a/cpp/ql/src/Security/CWE/CWE-190/TaintedAllocationSize.ql +++ b/cpp/ql/src/Security/CWE/CWE-190/TaintedAllocationSize.ql @@ -95,14 +95,14 @@ module TaintedAllocationSizeConfig implements DataFlow::ConfigSig { } } -module TaintedAllocationSize = TaintTracking::Make<TaintedAllocationSizeConfig>; +module TaintedAllocationSize = TaintTracking::Global<TaintedAllocationSizeConfig>; from Expr alloc, TaintedAllocationSize::PathNode source, TaintedAllocationSize::PathNode sink, string taintCause where isFlowSource(source.getNode(), taintCause) and - TaintedAllocationSize::hasFlowPath(source, sink) and + TaintedAllocationSize::flowPath(source, sink) and allocSink(alloc, sink.getNode()) select alloc, source, sink, "This allocation size is derived from $@ and might overflow.", source.getNode(), "user input (" + taintCause + ")" diff --git a/cpp/ql/src/Security/CWE/CWE-295/SSLResultConflation.ql b/cpp/ql/src/Security/CWE/CWE-295/SSLResultConflation.ql index 34d211a53ae..5eab70c5cc9 100644 --- a/cpp/ql/src/Security/CWE/CWE-295/SSLResultConflation.ql +++ b/cpp/ql/src/Security/CWE/CWE-295/SSLResultConflation.ql @@ -33,14 +33,14 @@ module VerifyResultConfig implements DataFlow::ConfigSig { } } -module VerifyResult = DataFlow::Make<VerifyResultConfig>; +module VerifyResult = DataFlow::Global<VerifyResultConfig>; from DataFlow::Node source, DataFlow::Node sink1, DataFlow::Node sink2, GuardCondition guard, Expr c1, Expr c2, boolean testIsTrue where - VerifyResult::hasFlow(source, sink1) and - VerifyResult::hasFlow(source, sink2) and + VerifyResult::flow(source, sink1) and + VerifyResult::flow(source, sink2) and guard.comparesEq(sink1.asExpr(), c1, 0, false, testIsTrue) and // (value != c1) => testIsTrue guard.comparesEq(sink2.asExpr(), c2, 0, false, testIsTrue) and // (value != c2) => testIsTrue c1.getValue().toInt() = 0 and diff --git a/cpp/ql/src/Security/CWE/CWE-311/CleartextBufferWrite.ql b/cpp/ql/src/Security/CWE/CWE-311/CleartextBufferWrite.ql index d7bb69582d7..f2754c5811f 100644 --- a/cpp/ql/src/Security/CWE/CWE-311/CleartextBufferWrite.ql +++ b/cpp/ql/src/Security/CWE/CWE-311/CleartextBufferWrite.ql @@ -49,7 +49,7 @@ module ToBufferConfig implements DataFlow::ConfigSig { predicate isSink(DataFlow::Node sink) { isSinkImpl(sink, _) } } -module ToBufferFlow = TaintTracking::Make<ToBufferConfig>; +module ToBufferFlow = TaintTracking::Global<ToBufferConfig>; predicate isSinkImpl(DataFlow::Node sink, SensitiveBufferWrite w) { w.getASource() = sink.asIndirectExpr() @@ -59,7 +59,7 @@ from SensitiveBufferWrite w, ToBufferFlow::PathNode sourceNode, ToBufferFlow::PathNode sinkNode, FlowSource source where - ToBufferFlow::hasFlowPath(sourceNode, sinkNode) and + ToBufferFlow::flowPath(sourceNode, sinkNode) and sourceNode.getNode() = source and isSinkImpl(sinkNode.getNode(), w) select w, sourceNode, sinkNode, diff --git a/cpp/ql/src/Security/CWE/CWE-311/CleartextFileWrite.ql b/cpp/ql/src/Security/CWE/CWE-311/CleartextFileWrite.ql index 3c1a78b14c5..c04ceae7ada 100644 --- a/cpp/ql/src/Security/CWE/CWE-311/CleartextFileWrite.ql +++ b/cpp/ql/src/Security/CWE/CWE-311/CleartextFileWrite.ql @@ -33,7 +33,7 @@ module FromSensitiveConfig implements DataFlow::ConfigSig { } } -module FromSensitiveFlow = TaintTracking::Make<FromSensitiveConfig>; +module FromSensitiveFlow = TaintTracking::Global<FromSensitiveConfig>; predicate isSinkImpl(DataFlow::Node sink, FileWrite w, Expr dest) { exists(Expr e | @@ -81,7 +81,7 @@ from SensitiveExpr source, FromSensitiveFlow::PathNode sourceNode, FromSensitiveFlow::PathNode midNode, FileWrite w, Expr dest where - FromSensitiveFlow::hasFlowPath(sourceNode, midNode) and + FromSensitiveFlow::flowPath(sourceNode, midNode) and isSourceImpl(sourceNode.getNode(), source) and isSinkImpl(midNode.getNode(), w, dest) select w, sourceNode, midNode, diff --git a/cpp/ql/src/Security/CWE/CWE-311/CleartextTransmission.ql b/cpp/ql/src/Security/CWE/CWE-311/CleartextTransmission.ql index a0fb6bd2dac..fa0d2ffd82a 100644 --- a/cpp/ql/src/Security/CWE/CWE-311/CleartextTransmission.ql +++ b/cpp/ql/src/Security/CWE/CWE-311/CleartextTransmission.ql @@ -250,13 +250,13 @@ module FromSensitiveConfig implements DataFlow::ConfigSig { } } -module FromSensitiveFlow = TaintTracking::Make<FromSensitiveConfig>; +module FromSensitiveFlow = TaintTracking::Global<FromSensitiveConfig>; /** * A taint flow configuration for flow from a sensitive expression to an encryption operation. */ module ToEncryptionConfig implements DataFlow::ConfigSig { - predicate isSource(DataFlow::Node source) { FromSensitiveFlow::hasFlow(source, _) } + predicate isSource(DataFlow::Node source) { FromSensitiveFlow::flow(source, _) } predicate isSink(DataFlow::Node sink) { isSinkEncrypt(sink, _) } @@ -271,7 +271,7 @@ module ToEncryptionConfig implements DataFlow::ConfigSig { } } -module ToEncryptionFlow = TaintTracking::Make<ToEncryptionConfig>; +module ToEncryptionFlow = TaintTracking::Global<ToEncryptionConfig>; /** * A taint flow configuration for flow from an encryption operation to a network operation. @@ -279,25 +279,25 @@ module ToEncryptionFlow = TaintTracking::Make<ToEncryptionConfig>; module FromEncryptionConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { isSinkEncrypt(source, _) } - predicate isSink(DataFlow::Node sink) { FromSensitiveFlow::hasFlowTo(sink) } + predicate isSink(DataFlow::Node sink) { FromSensitiveFlow::flowTo(sink) } predicate isBarrier(DataFlow::Node node) { node.asExpr().getUnspecifiedType() instanceof IntegralType } } -module FromEncryptionFlow = TaintTracking::Make<FromEncryptionConfig>; +module FromEncryptionFlow = TaintTracking::Global<FromEncryptionConfig>; from FromSensitiveFlow::PathNode source, FromSensitiveFlow::PathNode sink, NetworkSendRecv networkSendRecv, string msg where // flow from sensitive -> network data - FromSensitiveFlow::hasFlowPath(source, sink) and + FromSensitiveFlow::flowPath(source, sink) and isSinkSendRecv(sink.getNode(), networkSendRecv) and // no flow from sensitive -> evidence of encryption - not ToEncryptionFlow::hasFlow(source.getNode(), _) and - not FromEncryptionFlow::hasFlowTo(sink.getNode()) and + not ToEncryptionFlow::flow(source.getNode(), _) and + not FromEncryptionFlow::flowTo(sink.getNode()) and // construct result if networkSendRecv instanceof NetworkSend then diff --git a/cpp/ql/src/Security/CWE/CWE-313/CleartextSqliteDatabase.ql b/cpp/ql/src/Security/CWE/CWE-313/CleartextSqliteDatabase.ql index 797302be5a4..0c060befeff 100644 --- a/cpp/ql/src/Security/CWE/CWE-313/CleartextSqliteDatabase.ql +++ b/cpp/ql/src/Security/CWE/CWE-313/CleartextSqliteDatabase.ql @@ -125,13 +125,13 @@ module FromSensitiveConfig implements DataFlow::ConfigSig { } } -module FromSensitiveFlow = TaintTracking::Make<FromSensitiveConfig>; +module FromSensitiveFlow = TaintTracking::Global<FromSensitiveConfig>; from SensitiveExpr sensitive, FromSensitiveFlow::PathNode source, FromSensitiveFlow::PathNode sink, SqliteFunctionCall sqliteCall where - FromSensitiveFlow::hasFlowPath(source, sink) and + FromSensitiveFlow::flowPath(source, sink) and isSourceImpl(source.getNode(), sensitive) and isSinkImpl(sink.getNode(), sqliteCall, _) select sqliteCall, source, sink, diff --git a/cpp/ql/src/Security/CWE/CWE-319/UseOfHttp.ql b/cpp/ql/src/Security/CWE/CWE-319/UseOfHttp.ql index ceddfbf9f40..423ed57dd98 100644 --- a/cpp/ql/src/Security/CWE/CWE-319/UseOfHttp.ql +++ b/cpp/ql/src/Security/CWE/CWE-319/UseOfHttp.ql @@ -89,10 +89,10 @@ module HttpStringToUrlOpenConfig implements DataFlow::ConfigSig { } } -module HttpStringToUrlOpen = TaintTracking::Make<HttpStringToUrlOpenConfig>; +module HttpStringToUrlOpen = TaintTracking::Global<HttpStringToUrlOpenConfig>; from HttpStringToUrlOpen::PathNode source, HttpStringToUrlOpen::PathNode sink, HttpStringLiteral str where - HttpStringToUrlOpen::hasFlowPath(source, sink) and + HttpStringToUrlOpen::flowPath(source, sink) and str = source.getNode().asIndirectExpr() select str, source, sink, "This URL may be constructed with the HTTP protocol." diff --git a/cpp/ql/src/Security/CWE/CWE-326/InsufficientKeySize.ql b/cpp/ql/src/Security/CWE/CWE-326/InsufficientKeySize.ql index f899889a59b..3cc10b7ad19 100644 --- a/cpp/ql/src/Security/CWE/CWE-326/InsufficientKeySize.ql +++ b/cpp/ql/src/Security/CWE/CWE-326/InsufficientKeySize.ql @@ -46,13 +46,13 @@ module KeyStrengthFlowConfig implements DataFlow::ConfigSig { } } -module KeyStrengthFlow = DataFlow::Make<KeyStrengthFlowConfig>; +module KeyStrengthFlow = DataFlow::Global<KeyStrengthFlowConfig>; from KeyStrengthFlow::PathNode source, KeyStrengthFlow::PathNode sink, FunctionCall fc, int param, string name, int minimumBits, int bits where - KeyStrengthFlow::hasFlowPath(source, sink) and + KeyStrengthFlow::flowPath(source, sink) and sink.getNode().asExpr() = fc.getArgument(param) and fc.getTarget().hasGlobalName(name) and minimumBits = getMinimumKeyStrength(name, param) and diff --git a/cpp/ql/src/Security/CWE/CWE-428/UnsafeCreateProcessCall.ql b/cpp/ql/src/Security/CWE/CWE-428/UnsafeCreateProcessCall.ql index e6dd4e7046e..2703f819b54 100644 --- a/cpp/ql/src/Security/CWE/CWE-428/UnsafeCreateProcessCall.ql +++ b/cpp/ql/src/Security/CWE/CWE-428/UnsafeCreateProcessCall.ql @@ -64,7 +64,7 @@ module NullAppNameCreateProcessFunctionConfig implements DataFlow::ConfigSig { } } -module NullAppNameCreateProcessFunction = DataFlow::Make<NullAppNameCreateProcessFunctionConfig>; +module NullAppNameCreateProcessFunction = DataFlow::Global<NullAppNameCreateProcessFunctionConfig>; /** * Dataflow that detects a call to CreateProcess with an unquoted commandLine argument @@ -85,7 +85,7 @@ module QuotedCommandInCreateProcessFunctionConfig implements DataFlow::ConfigSig } module QuotedCommandInCreateProcessFunction = - DataFlow::Make<QuotedCommandInCreateProcessFunctionConfig>; + DataFlow::Global<QuotedCommandInCreateProcessFunctionConfig>; bindingset[s] predicate isQuotedOrNoSpaceApplicationNameOnCmd(string s) { @@ -98,12 +98,12 @@ from CreateProcessFunctionCall call, string msg1, string msg2 where exists(Expr appName | appName = call.getArgument(call.getApplicationNameArgumentId()) and - NullAppNameCreateProcessFunction::hasFlowToExpr(appName) and + NullAppNameCreateProcessFunction::flowToExpr(appName) and msg1 = call.toString() + " with lpApplicationName == NULL (" + appName + ")" ) and exists(Expr cmd | cmd = call.getArgument(call.getCommandLineArgumentId()) and - QuotedCommandInCreateProcessFunction::hasFlowToExpr(cmd) and + QuotedCommandInCreateProcessFunction::flowToExpr(cmd) and msg2 = " and with an unquoted lpCommandLine (" + cmd + ") introduces a security vulnerability if the path contains spaces." diff --git a/cpp/ql/src/Security/CWE/CWE-497/ExposedSystemData.ql b/cpp/ql/src/Security/CWE/CWE-497/ExposedSystemData.ql index 7e76cf76c12..74a5e1ba4e0 100644 --- a/cpp/ql/src/Security/CWE/CWE-497/ExposedSystemData.ql +++ b/cpp/ql/src/Security/CWE/CWE-497/ExposedSystemData.ql @@ -30,15 +30,15 @@ module ExposedSystemDataConfig implements DataFlow::ConfigSig { } } -module ExposedSystemData = TaintTracking::Make<ExposedSystemDataConfig>; +module ExposedSystemData = TaintTracking::Global<ExposedSystemDataConfig>; from ExposedSystemData::PathNode source, ExposedSystemData::PathNode sink where - ExposedSystemData::hasFlowPath(source, sink) and + ExposedSystemData::flowPath(source, sink) and not exists( DataFlow::Node alt // remove duplicate results on conversions | - ExposedSystemData::hasFlow(source.getNode(), alt) and + ExposedSystemData::flow(source.getNode(), alt) and alt.asConvertedExpr() = sink.getNode().asIndirectExpr() and alt != sink.getNode() ) diff --git a/cpp/ql/src/Security/CWE/CWE-497/PotentiallyExposedSystemData.ql b/cpp/ql/src/Security/CWE/CWE-497/PotentiallyExposedSystemData.ql index a06314e3c97..9fa4f538378 100644 --- a/cpp/ql/src/Security/CWE/CWE-497/PotentiallyExposedSystemData.ql +++ b/cpp/ql/src/Security/CWE/CWE-497/PotentiallyExposedSystemData.ql @@ -51,9 +51,9 @@ module PotentiallyExposedSystemDataConfig implements DataFlow::ConfigSig { } } -module PotentiallyExposedSystemData = TaintTracking::Make<PotentiallyExposedSystemDataConfig>; +module PotentiallyExposedSystemData = TaintTracking::Global<PotentiallyExposedSystemDataConfig>; from PotentiallyExposedSystemData::PathNode source, PotentiallyExposedSystemData::PathNode sink -where PotentiallyExposedSystemData::hasFlowPath(source, sink) +where PotentiallyExposedSystemData::flowPath(source, sink) select sink, source, sink, "This operation potentially exposes sensitive system data from $@.", source, source.getNode().toString() diff --git a/cpp/ql/src/Security/CWE/CWE-611/XXE.ql b/cpp/ql/src/Security/CWE/CWE-611/XXE.ql index 1b611a42b8d..6b73e50c963 100644 --- a/cpp/ql/src/Security/CWE/CWE-611/XXE.ql +++ b/cpp/ql/src/Security/CWE/CWE-611/XXE.ql @@ -45,9 +45,9 @@ module XxeConfig implements DataFlow::StateConfigSig { } } -module XxeFlow = DataFlow::MakeWithState<XxeConfig>; +module XxeFlow = DataFlow::GlobalWithState<XxeConfig>; from XxeFlow::PathNode source, XxeFlow::PathNode sink -where XxeFlow::hasFlowPath(source, sink) +where XxeFlow::flowPath(source, sink) select sink, source, sink, "This $@ is not configured to prevent an XML external entity (XXE) attack.", source, "XML parser" diff --git a/cpp/ql/src/Security/CWE/CWE-732/UnsafeDaclSecurityDescriptor.ql b/cpp/ql/src/Security/CWE/CWE-732/UnsafeDaclSecurityDescriptor.ql index 8f36ab50aa8..5ed30e19bb3 100644 --- a/cpp/ql/src/Security/CWE/CWE-732/UnsafeDaclSecurityDescriptor.ql +++ b/cpp/ql/src/Security/CWE/CWE-732/UnsafeDaclSecurityDescriptor.ql @@ -39,7 +39,7 @@ module NullDaclConfig implements DataFlow::ConfigSig { } } -module NullDaclFlow = DataFlow::Make<NullDaclConfig>; +module NullDaclFlow = DataFlow::Global<NullDaclConfig>; /** * Dataflow that detects a call to SetSecurityDescriptorDacl with a pDacl @@ -70,7 +70,7 @@ module NonNullDaclConfig implements DataFlow::ConfigSig { } } -module NonNullDaclFlow = DataFlow::Make<NonNullDaclConfig>; +module NonNullDaclFlow = DataFlow::Global<NonNullDaclConfig>; from SetSecurityDescriptorDaclFunctionCall call, string message where @@ -88,7 +88,7 @@ where " that is set to NULL will result in an unprotected object." | var = call.getArgument(2) and - NullDaclFlow::hasFlowToExpr(var) and - not NonNullDaclFlow::hasFlowToExpr(var) + NullDaclFlow::flowToExpr(var) and + not NonNullDaclFlow::flowToExpr(var) ) select call, message diff --git a/cpp/ql/src/experimental/Security/CWE/CWE-078/WordexpTainted.ql b/cpp/ql/src/experimental/Security/CWE/CWE-078/WordexpTainted.ql index 7b72b2684e6..cf346cb812e 100644 --- a/cpp/ql/src/experimental/Security/CWE/CWE-078/WordexpTainted.ql +++ b/cpp/ql/src/experimental/Security/CWE/CWE-078/WordexpTainted.ql @@ -50,9 +50,9 @@ module WordexpTaintConfig implements DataFlow::ConfigSig { } } -module WordexpTaint = TaintTracking::Make<WordexpTaintConfig>; +module WordexpTaint = TaintTracking::Global<WordexpTaintConfig>; from WordexpTaint::PathNode sourceNode, WordexpTaint::PathNode sinkNode -where WordexpTaint::hasFlowPath(sourceNode, sinkNode) +where WordexpTaint::flowPath(sourceNode, sinkNode) select sinkNode.getNode(), sourceNode, sinkNode, "Using user-supplied data in a `wordexp` command, without disabling command substitution, can make code vulnerable to command injection." diff --git a/cpp/ql/src/experimental/Security/CWE/CWE-190/AllocMultiplicationOverflow.ql b/cpp/ql/src/experimental/Security/CWE/CWE-190/AllocMultiplicationOverflow.ql index 71958eaad91..00cf017297f 100644 --- a/cpp/ql/src/experimental/Security/CWE/CWE-190/AllocMultiplicationOverflow.ql +++ b/cpp/ql/src/experimental/Security/CWE/CWE-190/AllocMultiplicationOverflow.ql @@ -32,10 +32,10 @@ module MultToAllocConfig implements DataFlow::ConfigSig { } } -module MultToAlloc = DataFlow::Make<MultToAllocConfig>; +module MultToAlloc = DataFlow::Global<MultToAllocConfig>; from MultToAlloc::PathNode source, MultToAlloc::PathNode sink -where MultToAlloc::hasFlowPath(source, sink) +where MultToAlloc::flowPath(source, sink) select sink, source, sink, "Potentially overflowing value from $@ is used in the size of this allocation.", source, "multiplication" diff --git a/cpp/ql/src/experimental/Security/CWE/CWE-193/ConstantSizeArrayOffByOne.ql b/cpp/ql/src/experimental/Security/CWE/CWE-193/ConstantSizeArrayOffByOne.ql index 35cce4a30da..b8e439be05c 100644 --- a/cpp/ql/src/experimental/Security/CWE/CWE-193/ConstantSizeArrayOffByOne.ql +++ b/cpp/ql/src/experimental/Security/CWE/CWE-193/ConstantSizeArrayOffByOne.ql @@ -43,7 +43,7 @@ module FieldAddressToPointerArithmeticConfig implements DataFlow::ConfigSig { } } -module FieldAddressToPointerArithmeticFlow = DataFlow::Make<FieldAddressToPointerArithmeticConfig>; +module FieldAddressToPointerArithmeticFlow = DataFlow::Global<FieldAddressToPointerArithmeticConfig>; predicate isFieldAddressSource(Field f, DataFlow::Node source) { source.asInstruction().(FieldAddressInstruction).getField() = f @@ -70,7 +70,7 @@ predicate isInvalidPointerDerefSink(DataFlow::Node sink, Instruction i, string o predicate isConstantSizeOverflowSource(Field f, PointerAddInstruction pai, int delta) { exists(int size, int bound, DataFlow::Node source, DataFlow::InstructionNode sink | - FieldAddressToPointerArithmeticFlow::hasFlow(source, sink) and + FieldAddressToPointerArithmeticFlow::flow(source, sink) and isFieldAddressSource(f, source) and pai.getLeft() = sink.asInstruction() and f.getUnspecifiedType().(ArrayType).getArraySize() = size and @@ -90,13 +90,13 @@ module PointerArithmeticToDerefConfig implements DataFlow::ConfigSig { predicate isSink(DataFlow::Node sink) { isInvalidPointerDerefSink(sink, _, _) } } -module PointerArithmeticToDerefFlow = DataFlow::Make<PointerArithmeticToDerefConfig>; +module PointerArithmeticToDerefFlow = DataFlow::Global<PointerArithmeticToDerefConfig>; from Field f, PointerArithmeticToDerefFlow::PathNode source, PointerArithmeticToDerefFlow::PathNode sink, Instruction deref, string operation, int delta where - PointerArithmeticToDerefFlow::hasFlowPath(source, sink) and + PointerArithmeticToDerefFlow::flowPath(source, sink) and isInvalidPointerDerefSink(sink.getNode(), deref, operation) and isConstantSizeOverflowSource(f, source.getNode().asInstruction(), delta) select source, source, sink, diff --git a/cpp/ql/src/experimental/Security/CWE/CWE-193/InvalidPointerDeref.ql b/cpp/ql/src/experimental/Security/CWE/CWE-193/InvalidPointerDeref.ql index 9cadcb505d0..cfd610767de 100644 --- a/cpp/ql/src/experimental/Security/CWE/CWE-193/InvalidPointerDeref.ql +++ b/cpp/ql/src/experimental/Security/CWE/CWE-193/InvalidPointerDeref.ql @@ -209,7 +209,7 @@ module InvalidPointerToDerefConfig implements DataFlow::ConfigSig { predicate isSink(DataFlow::Node sink) { isInvalidPointerDerefSink(sink, _, _) } } -module InvalidPointerToDerefFlow = DataFlow::Make<InvalidPointerToDerefConfig>; +module InvalidPointerToDerefFlow = DataFlow::Global<InvalidPointerToDerefConfig>; /** * Holds if `pai` is a pointer-arithmetic operation and `source` is a dataflow node with a @@ -241,7 +241,7 @@ newtype TMergedPathNode = // pointer, but we want to raise an alert at the dereference. TPathNodeSink(Instruction i) { exists(DataFlow::Node n | - InvalidPointerToDerefFlow::hasFlow(_, n) and + InvalidPointerToDerefFlow::flow(_, n) and isInvalidPointerDerefSink(n, i, _) ) } @@ -349,7 +349,7 @@ predicate hasFlowPath( | conf1.hasFlowPath(source1.asPathNode1(), _, sink1, _) and joinOn1(pai, sink1, source3) and - InvalidPointerToDerefFlow::hasFlowPath(source3, sink3) and + InvalidPointerToDerefFlow::flowPath(source3, sink3) and joinOn2(sink3, sink.asSinkNode(), operation) ) } diff --git a/cpp/ql/src/experimental/Security/CWE/CWE-359/PrivateCleartextWrite.ql b/cpp/ql/src/experimental/Security/CWE/CWE-359/PrivateCleartextWrite.ql index c09277f38f2..2355c276b60 100644 --- a/cpp/ql/src/experimental/Security/CWE/CWE-359/PrivateCleartextWrite.ql +++ b/cpp/ql/src/experimental/Security/CWE/CWE-359/PrivateCleartextWrite.ql @@ -16,7 +16,7 @@ import experimental.semmle.code.cpp.security.PrivateCleartextWrite::PrivateClear import WriteFlow::PathGraph from WriteFlow::PathNode source, WriteFlow::PathNode sink -where WriteFlow::hasFlowPath(source, sink) +where WriteFlow::flowPath(source, sink) select sink.getNode(), source, sink, "This write into the external location '" + sink.getNode() + "' may contain unencrypted data from $@.", source, "this source of private data." diff --git a/cpp/ql/test/examples/docs-examples/analyzing-data-flow-in-cpp/exercise2.ql b/cpp/ql/test/examples/docs-examples/analyzing-data-flow-in-cpp/exercise2.ql index 3fbc4fc10fd..a27e6382916 100644 --- a/cpp/ql/test/examples/docs-examples/analyzing-data-flow-in-cpp/exercise2.ql +++ b/cpp/ql/test/examples/docs-examples/analyzing-data-flow-in-cpp/exercise2.ql @@ -12,11 +12,11 @@ module LiteralToGethostbynameConfig implements DataFlow::ConfigSig { } } -module LiteralToGethostbynameFlow = DataFlow::Make<LiteralToGethostbynameConfig>; +module LiteralToGethostbynameFlow = DataFlow::Global<LiteralToGethostbynameConfig>; from StringLiteral sl, FunctionCall fc, DataFlow::Node source, DataFlow::Node sink where source.asIndirectExpr(1) = sl and sink.asIndirectExpr(1) = fc.getArgument(0) and - LiteralToGethostbynameFlow::hasFlow(source, sink) + LiteralToGethostbynameFlow::flow(source, sink) select sl, fc diff --git a/cpp/ql/test/examples/docs-examples/analyzing-data-flow-in-cpp/exercise4.ql b/cpp/ql/test/examples/docs-examples/analyzing-data-flow-in-cpp/exercise4.ql index fc73440cd7b..09d580234fb 100644 --- a/cpp/ql/test/examples/docs-examples/analyzing-data-flow-in-cpp/exercise4.ql +++ b/cpp/ql/test/examples/docs-examples/analyzing-data-flow-in-cpp/exercise4.ql @@ -16,11 +16,11 @@ module GetenvToGethostbynameConfig implements DataFlow::ConfigSig { } } -module GetenvToGethostbynameFlow = DataFlow::Make<GetenvToGethostbynameConfig>; +module GetenvToGethostbynameFlow = DataFlow::Global<GetenvToGethostbynameConfig>; from Expr getenv, FunctionCall fc, DataFlow::Node source, DataFlow::Node sink where source.asIndirectExpr(1) = getenv and sink.asIndirectExpr(1) = fc.getArgument(0) and - GetenvToGethostbynameFlow::hasFlow(source, sink) + GetenvToGethostbynameFlow::flow(source, sink) select getenv, fc diff --git a/cpp/ql/test/examples/docs-examples/analyzing-data-flow-in-cpp/fopen-flow-from-getenv.ql b/cpp/ql/test/examples/docs-examples/analyzing-data-flow-in-cpp/fopen-flow-from-getenv.ql index 7d810156e7d..917193b2994 100644 --- a/cpp/ql/test/examples/docs-examples/analyzing-data-flow-in-cpp/fopen-flow-from-getenv.ql +++ b/cpp/ql/test/examples/docs-examples/analyzing-data-flow-in-cpp/fopen-flow-from-getenv.ql @@ -17,11 +17,11 @@ module EnvironmentToFileConfig implements DataFlow::ConfigSig { } } -module EnvironmentToFileFlow = DataFlow::Make<EnvironmentToFileConfig>; +module EnvironmentToFileFlow = DataFlow::Global<EnvironmentToFileConfig>; from Expr getenv, Expr fopen, DataFlow::Node source, DataFlow::Node sink where source.asIndirectExpr(1) = getenv and sink.asIndirectExpr(1) = fopen and - EnvironmentToFileFlow::hasFlow(source, sink) + EnvironmentToFileFlow::flow(source, sink) select fopen, "This 'fopen' uses data from $@.", getenv, "call to 'getenv'" diff --git a/cpp/ql/test/examples/docs-examples/analyzing-data-flow-in-cpp/index-flow-from-ntohl.ql b/cpp/ql/test/examples/docs-examples/analyzing-data-flow-in-cpp/index-flow-from-ntohl.ql index a81c3a71d75..15cc379131a 100644 --- a/cpp/ql/test/examples/docs-examples/analyzing-data-flow-in-cpp/index-flow-from-ntohl.ql +++ b/cpp/ql/test/examples/docs-examples/analyzing-data-flow-in-cpp/index-flow-from-ntohl.ql @@ -30,9 +30,9 @@ module NetworkToBufferSizeConfig implements DataFlow::ConfigSig { } } -module NetworkToBufferSizeFlow = TaintTracking::Make<NetworkToBufferSizeConfig>; +module NetworkToBufferSizeFlow = TaintTracking::Global<NetworkToBufferSizeConfig>; from DataFlow::Node ntohl, DataFlow::Node offset -where NetworkToBufferSizeFlow::hasFlow(ntohl, offset) +where NetworkToBufferSizeFlow::flow(ntohl, offset) select offset, "This array offset may be influenced by $@.", ntohl, "converted data from the network" diff --git a/cpp/ql/test/library-tests/dataflow/additional-flow-to-parameter/standardFlow.ql b/cpp/ql/test/library-tests/dataflow/additional-flow-to-parameter/standardFlow.ql index 1497702db76..d929b6557a4 100644 --- a/cpp/ql/test/library-tests/dataflow/additional-flow-to-parameter/standardFlow.ql +++ b/cpp/ql/test/library-tests/dataflow/additional-flow-to-parameter/standardFlow.ql @@ -14,8 +14,8 @@ module TestConfig implements DataFlow::ConfigSig { } } -module TestFlow = DataFlow::Make<TestConfig>; +module TestFlow = DataFlow::Global<TestConfig>; from DataFlow::Node sink, DataFlow::Node source -where TestFlow::hasFlow(source, sink) +where TestFlow::flow(source, sink) select sink, source diff --git a/cpp/ql/test/library-tests/dataflow/additional-flow-to-parameter/withAdditionalFlow.ql b/cpp/ql/test/library-tests/dataflow/additional-flow-to-parameter/withAdditionalFlow.ql index c46d2cddf88..49e98db06ae 100644 --- a/cpp/ql/test/library-tests/dataflow/additional-flow-to-parameter/withAdditionalFlow.ql +++ b/cpp/ql/test/library-tests/dataflow/additional-flow-to-parameter/withAdditionalFlow.ql @@ -25,8 +25,8 @@ module TestConfig implements DataFlow::ConfigSig { } } -module TestFlow = DataFlow::Make<TestConfig>; +module TestFlow = DataFlow::Global<TestConfig>; from DataFlow::Node sink, DataFlow::Node source -where TestFlow::hasFlow(source, sink) +where TestFlow::flow(source, sink) select sink, source diff --git a/cpp/ql/test/library-tests/dataflow/crement/from0.ql b/cpp/ql/test/library-tests/dataflow/crement/from0.ql index 90bf8401fba..d395920c030 100644 --- a/cpp/ql/test/library-tests/dataflow/crement/from0.ql +++ b/cpp/ql/test/library-tests/dataflow/crement/from0.ql @@ -7,8 +7,8 @@ module Cfg implements DataFlow::ConfigSig { predicate isSink(DataFlow::Node sink) { sink.asExpr() instanceof VariableAccess } } -module Flow = DataFlow::Make<Cfg>; +module Flow = DataFlow::Global<Cfg>; from Expr sink -where Flow::hasFlowToExpr(sink) +where Flow::flowToExpr(sink) select sink From d0b7ffda703edbde6d889d691c997c6ed59e9748 Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen <aschackmull@github.com> Date: Thu, 23 Mar 2023 13:01:38 +0100 Subject: [PATCH 343/631] Python/Ruby/Swift: Rename references. --- python/ql/src/Security/CWE-327/FluentApiModel.qll | 4 ++-- ruby/ql/lib/codeql/ruby/security/StoredXSSQuery.qll | 2 +- ruby/ql/lib/codeql/ruby/security/XSS.qll | 4 ++-- ruby/ql/src/queries/security/cwe-079/StoredXSS.ql | 2 +- swift/ql/src/queries/Summary/SummaryStats.ql | 4 ++-- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/python/ql/src/Security/CWE-327/FluentApiModel.qll b/python/ql/src/Security/CWE-327/FluentApiModel.qll index 3f479bc1627..6ba3231f49b 100644 --- a/python/ql/src/Security/CWE-327/FluentApiModel.qll +++ b/python/ql/src/Security/CWE-327/FluentApiModel.qll @@ -112,7 +112,7 @@ module InsecureContextConfiguration2 implements DataFlow::StateConfigSig { } } -private module InsecureContextFlow = DataFlow::MakeWithState<InsecureContextConfiguration2>; +private module InsecureContextFlow = DataFlow::GlobalWithState<InsecureContextConfiguration2>; /** * Holds if `conectionCreation` marks the creation of a connection based on the contex @@ -127,7 +127,7 @@ predicate unsafe_connection_creation_with_context( ) { // Connection created from a context allowing `insecure_version`. exists(InsecureContextFlow::PathNode src, InsecureContextFlow::PathNode sink | - InsecureContextFlow::hasFlowPath(src, sink) and + InsecureContextFlow::flowPath(src, sink) and src.getNode() = contextOrigin and sink.getNode() = connectionCreation and sink.getState().allowsInsecureVersion(insecure_version) and diff --git a/ruby/ql/lib/codeql/ruby/security/StoredXSSQuery.qll b/ruby/ql/lib/codeql/ruby/security/StoredXSSQuery.qll index abec1880e65..f08529988c7 100644 --- a/ruby/ql/lib/codeql/ruby/security/StoredXSSQuery.qll +++ b/ruby/ql/lib/codeql/ruby/security/StoredXSSQuery.qll @@ -56,7 +56,7 @@ module StoredXss { } } - import TaintTracking::Make<Config> + import TaintTracking::Global<Config> } /** DEPRECATED: Alias for StoredXss */ diff --git a/ruby/ql/lib/codeql/ruby/security/XSS.qll b/ruby/ql/lib/codeql/ruby/security/XSS.qll index dbed650250e..d4b99766a58 100644 --- a/ruby/ql/lib/codeql/ruby/security/XSS.qll +++ b/ruby/ql/lib/codeql/ruby/security/XSS.qll @@ -304,7 +304,7 @@ private module OrmTracking { } } - import DataFlow::Make<Config> + import DataFlow::Global<Config> } /** Provides default sources, sinks and sanitizers for detecting stored cross-site scripting (XSS) vulnerabilities. */ @@ -336,7 +336,7 @@ module StoredXss { private class OrmFieldAsSource extends Source instanceof DataFlow::CallNode { OrmFieldAsSource() { exists(DataFlow::CallNode subSrc | - OrmTracking::hasFlow(subSrc, this.getReceiver()) and + OrmTracking::flow(subSrc, this.getReceiver()) and subSrc.(OrmInstantiation).methodCallMayAccessField(this.getMethodName()) ) } diff --git a/ruby/ql/src/queries/security/cwe-079/StoredXSS.ql b/ruby/ql/src/queries/security/cwe-079/StoredXSS.ql index 1dc855230a1..da1bd427589 100644 --- a/ruby/ql/src/queries/security/cwe-079/StoredXSS.ql +++ b/ruby/ql/src/queries/security/cwe-079/StoredXSS.ql @@ -17,6 +17,6 @@ import codeql.ruby.security.StoredXSSQuery import StoredXss::PathGraph from StoredXss::PathNode source, StoredXss::PathNode sink -where StoredXss::hasFlowPath(source, sink) +where StoredXss::flowPath(source, sink) select sink.getNode(), source, sink, "Stored cross-site scripting vulnerability due to $@.", source.getNode(), "stored value" diff --git a/swift/ql/src/queries/Summary/SummaryStats.ql b/swift/ql/src/queries/Summary/SummaryStats.ql index 10dcc0c5199..444c4da2ca2 100644 --- a/swift/ql/src/queries/Summary/SummaryStats.ql +++ b/swift/ql/src/queries/Summary/SummaryStats.ql @@ -21,12 +21,12 @@ module TaintReachConfig implements DataFlow::ConfigSig { predicate isSink(DataFlow::Node node) { any() } } -module TaintReachFlow = TaintTracking::Make<TaintReachConfig>; +module TaintReachFlow = TaintTracking::Global<TaintReachConfig>; /** * Gets the total number of dataflow nodes that taint reaches (from any source). */ -int taintedNodesCount() { result = count(DataFlow::Node n | TaintReachFlow::hasFlowTo(n)) } +int taintedNodesCount() { result = count(DataFlow::Node n | TaintReachFlow::flowTo(n)) } /** * Gets the proportion of dataflow nodes that taint reaches (from any source), From 978c5f7bd814ee7ef67f79cb1a5deb3fc9b192b6 Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen <aschackmull@github.com> Date: Thu, 23 Mar 2023 13:05:39 +0100 Subject: [PATCH 344/631] Java/C++: Autoformat --- .../Leap Year/UncheckedLeapYearAfterYearModification.ql | 6 ++---- .../Security/CWE/CWE-193/ConstantSizeArrayOffByOne.ql | 3 ++- .../code/java/security/ArbitraryApkInstallationQuery.qll | 3 ++- java/ql/src/Security/CWE/CWE-209/StackTraceExposure.ql | 3 +-- java/ql/src/Security/CWE/CWE-807/TaintedPermissionsCheck.ql | 3 +-- 5 files changed, 8 insertions(+), 10 deletions(-) diff --git a/cpp/ql/src/Likely Bugs/Leap Year/UncheckedLeapYearAfterYearModification.ql b/cpp/ql/src/Likely Bugs/Leap Year/UncheckedLeapYearAfterYearModification.ql index 1cc51a0d3e2..03570b3611c 100644 --- a/cpp/ql/src/Likely Bugs/Leap Year/UncheckedLeapYearAfterYearModification.ql +++ b/cpp/ql/src/Likely Bugs/Leap Year/UncheckedLeapYearAfterYearModification.ql @@ -31,16 +31,14 @@ where // If there is a data flow from the variable that was modified to a function that seems to check for leap year exists(VariableAccess source, ChecksForLeapYearFunctionCall fc | source = var.getAnAccess() and - LeapYearCheckFlow::flow(DataFlow::exprNode(source), - DataFlow::exprNode(fc.getAnArgument())) + LeapYearCheckFlow::flow(DataFlow::exprNode(source), DataFlow::exprNode(fc.getAnArgument())) ) or // If there is a data flow from the field that was modified to a function that seems to check for leap year exists(VariableAccess vacheck, YearFieldAccess yfacheck, ChecksForLeapYearFunctionCall fc | vacheck = var.getAnAccess() and yfacheck.getQualifier() = vacheck and - LeapYearCheckFlow::flow(DataFlow::exprNode(yfacheck), - DataFlow::exprNode(fc.getAnArgument())) + LeapYearCheckFlow::flow(DataFlow::exprNode(yfacheck), DataFlow::exprNode(fc.getAnArgument())) ) or // If there is a successor or predecessor that sets the month = 1 diff --git a/cpp/ql/src/experimental/Security/CWE/CWE-193/ConstantSizeArrayOffByOne.ql b/cpp/ql/src/experimental/Security/CWE/CWE-193/ConstantSizeArrayOffByOne.ql index b8e439be05c..f90f0bdcab8 100644 --- a/cpp/ql/src/experimental/Security/CWE/CWE-193/ConstantSizeArrayOffByOne.ql +++ b/cpp/ql/src/experimental/Security/CWE/CWE-193/ConstantSizeArrayOffByOne.ql @@ -43,7 +43,8 @@ module FieldAddressToPointerArithmeticConfig implements DataFlow::ConfigSig { } } -module FieldAddressToPointerArithmeticFlow = DataFlow::Global<FieldAddressToPointerArithmeticConfig>; +module FieldAddressToPointerArithmeticFlow = + DataFlow::Global<FieldAddressToPointerArithmeticConfig>; predicate isFieldAddressSource(Field f, DataFlow::Node source) { source.asInstruction().(FieldAddressInstruction).getField() = f diff --git a/java/ql/lib/semmle/code/java/security/ArbitraryApkInstallationQuery.qll b/java/ql/lib/semmle/code/java/security/ArbitraryApkInstallationQuery.qll index c44db421301..d066f4974a1 100644 --- a/java/ql/lib/semmle/code/java/security/ArbitraryApkInstallationQuery.qll +++ b/java/ql/lib/semmle/code/java/security/ArbitraryApkInstallationQuery.qll @@ -72,7 +72,8 @@ private module InstallPackageActionConfig implements DataFlow::StateConfigSig { predicate isBarrier(DataFlow::Node node, FlowState state) { none() } } -private module InstallPackageActionFlow = TaintTracking::GlobalWithState<InstallPackageActionConfig>; +private module InstallPackageActionFlow = + TaintTracking::GlobalWithState<InstallPackageActionConfig>; private newtype MimeTypeState = MimeTypeUnset() or diff --git a/java/ql/src/Security/CWE/CWE-209/StackTraceExposure.ql b/java/ql/src/Security/CWE/CWE-209/StackTraceExposure.ql index 0a40c11dfe9..98a342bcb27 100644 --- a/java/ql/src/Security/CWE/CWE-209/StackTraceExposure.ql +++ b/java/ql/src/Security/CWE/CWE-209/StackTraceExposure.ql @@ -104,8 +104,7 @@ predicate printsStackExternally(MethodAccess call, Expr stackTrace) { predicate stringifiedStackFlowsExternally(DataFlow::Node externalExpr, Expr stackTrace) { exists(MethodAccess stackTraceString | stackTraceExpr(stackTrace, stackTraceString) and - StackTraceStringToHttpResponseSinkFlow::flow(DataFlow::exprNode(stackTraceString), - externalExpr) + StackTraceStringToHttpResponseSinkFlow::flow(DataFlow::exprNode(stackTraceString), externalExpr) ) } diff --git a/java/ql/src/Security/CWE/CWE-807/TaintedPermissionsCheck.ql b/java/ql/src/Security/CWE/CWE-807/TaintedPermissionsCheck.ql index 8debae02267..87266e0df47 100644 --- a/java/ql/src/Security/CWE/CWE-807/TaintedPermissionsCheck.ql +++ b/java/ql/src/Security/CWE/CWE-807/TaintedPermissionsCheck.ql @@ -67,7 +67,6 @@ import TaintedPermissionsCheckFlow::PathGraph from TaintedPermissionsCheckFlow::PathNode source, TaintedPermissionsCheckFlow::PathNode sink, PermissionsConstruction p -where - sink.getNode().asExpr() = p.getInput() and TaintedPermissionsCheckFlow::flowPath(source, sink) +where sink.getNode().asExpr() = p.getInput() and TaintedPermissionsCheckFlow::flowPath(source, sink) select p, source, sink, "Permissions check depends on a $@.", source.getNode(), "user-controlled value" From ab95a0b9f095d0e6cbb14bb236f6af208cbe978a Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen <aschackmull@github.com> Date: Thu, 23 Mar 2023 13:09:09 +0100 Subject: [PATCH 345/631] Java/C#: Rename references --- .../utils/modelgenerator/internal/CaptureModels.qll | 12 ++++++------ .../utils/modelgenerator/internal/CaptureModels.qll | 12 ++++++------ 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/csharp/ql/src/utils/modelgenerator/internal/CaptureModels.qll b/csharp/ql/src/utils/modelgenerator/internal/CaptureModels.qll index 7dbdc5bee52..5ca3ffed782 100644 --- a/csharp/ql/src/utils/modelgenerator/internal/CaptureModels.qll +++ b/csharp/ql/src/utils/modelgenerator/internal/CaptureModels.qll @@ -210,7 +210,7 @@ module ThroughFlowConfig implements DataFlow::StateConfigSig { } } -private module ThroughFlow = TaintTracking::MakeWithState<ThroughFlowConfig>; +private module ThroughFlow = TaintTracking::GlobalWithState<ThroughFlowConfig>; /** * Gets the summary model(s) of `api`, if there is flow from parameters to return value or parameter. @@ -220,7 +220,7 @@ string captureThroughFlow(DataFlowTargetApi api) { DataFlow::ParameterNode p, DataFlowImplCommon::ReturnNodeExt returnNodeExt, string input, string output | - ThroughFlow::hasFlow(p, returnNodeExt) and + ThroughFlow::flow(p, returnNodeExt) and returnNodeExt.getEnclosingCallable() = api and input = parameterNodeAsInput(p) and output = returnNodeAsOutput(returnNodeExt) and @@ -253,14 +253,14 @@ module FromSourceConfig implements DataFlow::ConfigSig { } } -private module FromSource = TaintTracking::Make<FromSourceConfig>; +private module FromSource = TaintTracking::Global<FromSourceConfig>; /** * Gets the source model(s) of `api`, if there is flow from an existing known source to the return of `api`. */ string captureSource(DataFlowTargetApi api) { exists(DataFlow::Node source, DataFlow::Node sink, string kind | - FromSource::hasFlow(source, sink) and + FromSource::flow(source, sink) and ExternalFlow::sourceNode(source, kind) and api = sink.getEnclosingCallable() and isRelevantSourceKind(kind) and @@ -285,14 +285,14 @@ module PropagateToSinkConfig implements DataFlow::ConfigSig { DataFlow::FlowFeature getAFeature() { result instanceof DataFlow::FeatureHasSourceCallContext } } -private module PropagateToSink = TaintTracking::Make<PropagateToSinkConfig>; +private module PropagateToSink = TaintTracking::Global<PropagateToSinkConfig>; /** * Gets the sink model(s) of `api`, if there is flow from a parameter to an existing known sink. */ string captureSink(DataFlowTargetApi api) { exists(DataFlow::Node src, DataFlow::Node sink, string kind | - PropagateToSink::hasFlow(src, sink) and + PropagateToSink::flow(src, sink) and ExternalFlow::sinkNode(sink, kind) and api = src.getEnclosingCallable() and isRelevantSinkKind(kind) and diff --git a/java/ql/src/utils/modelgenerator/internal/CaptureModels.qll b/java/ql/src/utils/modelgenerator/internal/CaptureModels.qll index 7dbdc5bee52..5ca3ffed782 100644 --- a/java/ql/src/utils/modelgenerator/internal/CaptureModels.qll +++ b/java/ql/src/utils/modelgenerator/internal/CaptureModels.qll @@ -210,7 +210,7 @@ module ThroughFlowConfig implements DataFlow::StateConfigSig { } } -private module ThroughFlow = TaintTracking::MakeWithState<ThroughFlowConfig>; +private module ThroughFlow = TaintTracking::GlobalWithState<ThroughFlowConfig>; /** * Gets the summary model(s) of `api`, if there is flow from parameters to return value or parameter. @@ -220,7 +220,7 @@ string captureThroughFlow(DataFlowTargetApi api) { DataFlow::ParameterNode p, DataFlowImplCommon::ReturnNodeExt returnNodeExt, string input, string output | - ThroughFlow::hasFlow(p, returnNodeExt) and + ThroughFlow::flow(p, returnNodeExt) and returnNodeExt.getEnclosingCallable() = api and input = parameterNodeAsInput(p) and output = returnNodeAsOutput(returnNodeExt) and @@ -253,14 +253,14 @@ module FromSourceConfig implements DataFlow::ConfigSig { } } -private module FromSource = TaintTracking::Make<FromSourceConfig>; +private module FromSource = TaintTracking::Global<FromSourceConfig>; /** * Gets the source model(s) of `api`, if there is flow from an existing known source to the return of `api`. */ string captureSource(DataFlowTargetApi api) { exists(DataFlow::Node source, DataFlow::Node sink, string kind | - FromSource::hasFlow(source, sink) and + FromSource::flow(source, sink) and ExternalFlow::sourceNode(source, kind) and api = sink.getEnclosingCallable() and isRelevantSourceKind(kind) and @@ -285,14 +285,14 @@ module PropagateToSinkConfig implements DataFlow::ConfigSig { DataFlow::FlowFeature getAFeature() { result instanceof DataFlow::FeatureHasSourceCallContext } } -private module PropagateToSink = TaintTracking::Make<PropagateToSinkConfig>; +private module PropagateToSink = TaintTracking::Global<PropagateToSinkConfig>; /** * Gets the sink model(s) of `api`, if there is flow from a parameter to an existing known sink. */ string captureSink(DataFlowTargetApi api) { exists(DataFlow::Node src, DataFlow::Node sink, string kind | - PropagateToSink::hasFlow(src, sink) and + PropagateToSink::flow(src, sink) and ExternalFlow::sinkNode(sink, kind) and api = src.getEnclosingCallable() and isRelevantSinkKind(kind) and From b1d9c651947a4e435b10808130c6f97880b24c3e Mon Sep 17 00:00:00 2001 From: Salah Baddou <sbaddou@palantir.com> Date: Thu, 23 Mar 2023 12:11:07 +0000 Subject: [PATCH 346/631] Add JndiInjection Sanitizer Class --- .../semmle/code/java/security/JndiInjectionQuery.qll | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/java/ql/lib/semmle/code/java/security/JndiInjectionQuery.qll b/java/ql/lib/semmle/code/java/security/JndiInjectionQuery.qll index 9130bb6c7a2..1c8ef38c7ea 100644 --- a/java/ql/lib/semmle/code/java/security/JndiInjectionQuery.qll +++ b/java/ql/lib/semmle/code/java/security/JndiInjectionQuery.qll @@ -17,7 +17,9 @@ class JndiInjectionFlowConfig extends TaintTracking::Configuration { override predicate isSink(DataFlow::Node sink) { sink instanceof JndiInjectionSink } override predicate isSanitizer(DataFlow::Node node) { - node.getType() instanceof PrimitiveType or node.getType() instanceof BoxedType + node.getType() instanceof PrimitiveType or node.getType() instanceof BoxedType + or + node instanceof JndiInjectionSanitizer } override predicate isAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) { @@ -25,6 +27,12 @@ class JndiInjectionFlowConfig extends TaintTracking::Configuration { } } +/** + * A Class to be extended for Sanitizer Customizations + */ + +abstract class JndiInjectionSanitizer extends DataFlow::Node { } + /** * A method that does a JNDI lookup when it receives a `SearchControls` argument with `setReturningObjFlag` = `true` */ From 27c29303dab7d79511de01106c7207713604a31e Mon Sep 17 00:00:00 2001 From: erik-krogh <erik-krogh@github.com> Date: Thu, 23 Mar 2023 13:12:22 +0100 Subject: [PATCH 347/631] add test diagnostics test for internal error --- .../internal-error/diagnostics.expected | 15 +++++++++++++++ .../internal-error/src/my_failure.ts | 17 +++++++++++++++++ .../diagnostics/internal-error/test.py | 7 +++++++ .../diagnostics/internal-error/tsconfig.json | 1 + 4 files changed, 40 insertions(+) create mode 100644 javascript/ql/integration-tests/all-platforms/diagnostics/internal-error/diagnostics.expected create mode 100644 javascript/ql/integration-tests/all-platforms/diagnostics/internal-error/src/my_failure.ts create mode 100644 javascript/ql/integration-tests/all-platforms/diagnostics/internal-error/test.py create mode 100644 javascript/ql/integration-tests/all-platforms/diagnostics/internal-error/tsconfig.json diff --git a/javascript/ql/integration-tests/all-platforms/diagnostics/internal-error/diagnostics.expected b/javascript/ql/integration-tests/all-platforms/diagnostics/internal-error/diagnostics.expected new file mode 100644 index 00000000000..72108d0ebb5 --- /dev/null +++ b/javascript/ql/integration-tests/all-platforms/diagnostics/internal-error/diagnostics.expected @@ -0,0 +1,15 @@ +{ + "timestamp": "2023-03-23T12:04:41.317+00:00", + "source": { + "id": "js/internal-error", + "name": "Internal error", + "extractorName": "javascript" + }, + "markdownMessage": "Internal error: com.semmle.util.exception.CatastrophicError: The TypeScript parser wrapper crashed with exit code 1", + "severity": "unknown", + "visibility": { + "cliSummaryTable": true, + "statusPage": false, + "telemetry": true + } +} \ No newline at end of file diff --git a/javascript/ql/integration-tests/all-platforms/diagnostics/internal-error/src/my_failure.ts b/javascript/ql/integration-tests/all-platforms/diagnostics/internal-error/src/my_failure.ts new file mode 100644 index 00000000000..29e78b136e8 --- /dev/null +++ b/javascript/ql/integration-tests/all-platforms/diagnostics/internal-error/src/my_failure.ts @@ -0,0 +1,17 @@ +type Output<K, S extends any[]> = { + (...args: S): any; +}; + +declare function createThing<K extends string, S extends any[]>( + type: K, + fn: (...args: S) => any +): Output<K, S>; + +const one = createThing("one", () => ({})); + +const two = createThing("two", () => ({})); + +const three = createThing("three", (cursor: string) => null); +const four = createThing("four", (error: number) => null); + +type Events = Array<typeof one | typeof two | typeof three | typeof four>; diff --git a/javascript/ql/integration-tests/all-platforms/diagnostics/internal-error/test.py b/javascript/ql/integration-tests/all-platforms/diagnostics/internal-error/test.py new file mode 100644 index 00000000000..3f6c33bf31c --- /dev/null +++ b/javascript/ql/integration-tests/all-platforms/diagnostics/internal-error/test.py @@ -0,0 +1,7 @@ +import os +from create_database_utils import * +from diagnostics_test_utils import * + +run_codeql_database_create([], lang="javascript", runFunction = runUnsuccessfully, db = None) + +check_diagnostics() diff --git a/javascript/ql/integration-tests/all-platforms/diagnostics/internal-error/tsconfig.json b/javascript/ql/integration-tests/all-platforms/diagnostics/internal-error/tsconfig.json new file mode 100644 index 00000000000..9e26dfeeb6e --- /dev/null +++ b/javascript/ql/integration-tests/all-platforms/diagnostics/internal-error/tsconfig.json @@ -0,0 +1 @@ +{} \ No newline at end of file From 1c1aa7ecdd164e9915669f1318b2dc76e72d0961 Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen <aschackmull@github.com> Date: Thu, 23 Mar 2023 13:17:36 +0100 Subject: [PATCH 348/631] Dataflow: Add change notes. --- cpp/ql/lib/change-notes/2023-03-23-dataflow-renaming.md | 6 ++++++ csharp/ql/lib/change-notes/2023-03-23-dataflow-renaming.md | 6 ++++++ go/ql/lib/change-notes/2023-03-23-dataflow-renaming.md | 6 ++++++ java/ql/lib/change-notes/2023-03-23-dataflow-renaming.md | 6 ++++++ python/ql/lib/change-notes/2023-03-23-dataflow-renaming.md | 6 ++++++ ruby/ql/lib/change-notes/2023-03-23-dataflow-renaming.md | 6 ++++++ 6 files changed, 36 insertions(+) create mode 100644 cpp/ql/lib/change-notes/2023-03-23-dataflow-renaming.md create mode 100644 csharp/ql/lib/change-notes/2023-03-23-dataflow-renaming.md create mode 100644 go/ql/lib/change-notes/2023-03-23-dataflow-renaming.md create mode 100644 java/ql/lib/change-notes/2023-03-23-dataflow-renaming.md create mode 100644 python/ql/lib/change-notes/2023-03-23-dataflow-renaming.md create mode 100644 ruby/ql/lib/change-notes/2023-03-23-dataflow-renaming.md diff --git a/cpp/ql/lib/change-notes/2023-03-23-dataflow-renaming.md b/cpp/ql/lib/change-notes/2023-03-23-dataflow-renaming.md new file mode 100644 index 00000000000..54df71fae46 --- /dev/null +++ b/cpp/ql/lib/change-notes/2023-03-23-dataflow-renaming.md @@ -0,0 +1,6 @@ +--- +category: deprecated +--- +* The recently introduced new data flow and taint tracking APIs have had a + number of module and predicate renamings. The old APIs remain in place for + now. diff --git a/csharp/ql/lib/change-notes/2023-03-23-dataflow-renaming.md b/csharp/ql/lib/change-notes/2023-03-23-dataflow-renaming.md new file mode 100644 index 00000000000..54df71fae46 --- /dev/null +++ b/csharp/ql/lib/change-notes/2023-03-23-dataflow-renaming.md @@ -0,0 +1,6 @@ +--- +category: deprecated +--- +* The recently introduced new data flow and taint tracking APIs have had a + number of module and predicate renamings. The old APIs remain in place for + now. diff --git a/go/ql/lib/change-notes/2023-03-23-dataflow-renaming.md b/go/ql/lib/change-notes/2023-03-23-dataflow-renaming.md new file mode 100644 index 00000000000..54df71fae46 --- /dev/null +++ b/go/ql/lib/change-notes/2023-03-23-dataflow-renaming.md @@ -0,0 +1,6 @@ +--- +category: deprecated +--- +* The recently introduced new data flow and taint tracking APIs have had a + number of module and predicate renamings. The old APIs remain in place for + now. diff --git a/java/ql/lib/change-notes/2023-03-23-dataflow-renaming.md b/java/ql/lib/change-notes/2023-03-23-dataflow-renaming.md new file mode 100644 index 00000000000..54df71fae46 --- /dev/null +++ b/java/ql/lib/change-notes/2023-03-23-dataflow-renaming.md @@ -0,0 +1,6 @@ +--- +category: deprecated +--- +* The recently introduced new data flow and taint tracking APIs have had a + number of module and predicate renamings. The old APIs remain in place for + now. diff --git a/python/ql/lib/change-notes/2023-03-23-dataflow-renaming.md b/python/ql/lib/change-notes/2023-03-23-dataflow-renaming.md new file mode 100644 index 00000000000..54df71fae46 --- /dev/null +++ b/python/ql/lib/change-notes/2023-03-23-dataflow-renaming.md @@ -0,0 +1,6 @@ +--- +category: deprecated +--- +* The recently introduced new data flow and taint tracking APIs have had a + number of module and predicate renamings. The old APIs remain in place for + now. diff --git a/ruby/ql/lib/change-notes/2023-03-23-dataflow-renaming.md b/ruby/ql/lib/change-notes/2023-03-23-dataflow-renaming.md new file mode 100644 index 00000000000..54df71fae46 --- /dev/null +++ b/ruby/ql/lib/change-notes/2023-03-23-dataflow-renaming.md @@ -0,0 +1,6 @@ +--- +category: deprecated +--- +* The recently introduced new data flow and taint tracking APIs have had a + number of module and predicate renamings. The old APIs remain in place for + now. From 1f70c59bbcf3cf9dc7dc4a19319e195690a32bc2 Mon Sep 17 00:00:00 2001 From: Asger F <asgerf@github.com> Date: Thu, 23 Mar 2023 13:36:14 +0100 Subject: [PATCH 349/631] Ruby: add test with deep unresolved classes --- .../library-tests/modules/ancestors.expected | 9 +++ .../library-tests/modules/methods.expected | 9 +++ .../library-tests/modules/modules.expected | 67 +++++++++++++++---- .../modules/superclasses.expected | 9 +++ .../modules/unresolved_subclass.rb | 10 +++ 5 files changed, 91 insertions(+), 13 deletions(-) diff --git a/ruby/ql/test/library-tests/modules/ancestors.expected b/ruby/ql/test/library-tests/modules/ancestors.expected index 9e2c70f6f1c..1a513f49e39 100644 --- a/ruby/ql/test/library-tests/modules/ancestors.expected +++ b/ruby/ql/test/library-tests/modules/ancestors.expected @@ -272,3 +272,12 @@ unresolved_subclass.rb: # 11| UnresolvedNamespace::A #-----| super -> Object + +# 14| ...::Subclass1 +#-----| super -> ResolvableBaseClass + +# 17| ...::Subclass2 +#-----| super -> Object + +# 21| ...::A +#-----| super -> Object diff --git a/ruby/ql/test/library-tests/modules/methods.expected b/ruby/ql/test/library-tests/modules/methods.expected index ae688090be5..89c312aea44 100644 --- a/ruby/ql/test/library-tests/modules/methods.expected +++ b/ruby/ql/test/library-tests/modules/methods.expected @@ -660,6 +660,15 @@ lookupMethod | unresolved_subclass.rb:11:1:12:3 | UnresolvedNamespace::A | new | calls.rb:117:5:117:16 | new | | unresolved_subclass.rb:11:1:12:3 | UnresolvedNamespace::A | puts | calls.rb:102:5:102:30 | puts | | unresolved_subclass.rb:11:1:12:3 | UnresolvedNamespace::A | to_s | calls.rb:172:5:173:7 | to_s | +| unresolved_subclass.rb:14:1:15:3 | ...::Subclass1 | new | calls.rb:117:5:117:16 | new | +| unresolved_subclass.rb:14:1:15:3 | ...::Subclass1 | puts | calls.rb:102:5:102:30 | puts | +| unresolved_subclass.rb:14:1:15:3 | ...::Subclass1 | to_s | calls.rb:172:5:173:7 | to_s | +| unresolved_subclass.rb:17:1:18:3 | ...::Subclass2 | new | calls.rb:117:5:117:16 | new | +| unresolved_subclass.rb:17:1:18:3 | ...::Subclass2 | puts | calls.rb:102:5:102:30 | puts | +| unresolved_subclass.rb:17:1:18:3 | ...::Subclass2 | to_s | calls.rb:172:5:173:7 | to_s | +| unresolved_subclass.rb:21:1:22:3 | ...::A | new | calls.rb:117:5:117:16 | new | +| unresolved_subclass.rb:21:1:22:3 | ...::A | puts | calls.rb:102:5:102:30 | puts | +| unresolved_subclass.rb:21:1:22:3 | ...::A | to_s | calls.rb:172:5:173:7 | to_s | enclosingMethod | calls.rb:2:5:2:14 | call to puts | calls.rb:1:1:3:3 | foo | | calls.rb:2:5:2:14 | self | calls.rb:1:1:3:3 | foo | diff --git a/ruby/ql/test/library-tests/modules/modules.expected b/ruby/ql/test/library-tests/modules/modules.expected index 21a4d6ba195..f4b14fe0004 100644 --- a/ruby/ql/test/library-tests/modules/modules.expected +++ b/ruby/ql/test/library-tests/modules/modules.expected @@ -97,6 +97,9 @@ getModule | unresolved_subclass.rb:4:1:5:3 | UnresolvedNamespace::Subclass1 | | unresolved_subclass.rb:7:1:8:3 | UnresolvedNamespace::Subclass2 | | unresolved_subclass.rb:11:1:12:3 | UnresolvedNamespace::A | +| unresolved_subclass.rb:14:1:15:3 | ...::Subclass1 | +| unresolved_subclass.rb:17:1:18:3 | ...::Subclass2 | +| unresolved_subclass.rb:21:1:22:3 | ...::A | getADeclaration | calls.rb:21:1:34:3 | M | calls.rb:21:1:34:3 | M | | calls.rb:43:1:58:3 | C | calls.rb:43:1:58:3 | C | @@ -113,7 +116,7 @@ getADeclaration | calls.rb:115:1:118:3 | Object | modules_rec.rb:1:1:11:26 | modules_rec.rb | | calls.rb:115:1:118:3 | Object | private.rb:1:1:105:40 | private.rb | | calls.rb:115:1:118:3 | Object | toplevel_self_singleton.rb:1:1:34:4 | toplevel_self_singleton.rb | -| calls.rb:115:1:118:3 | Object | unresolved_subclass.rb:1:1:12:4 | unresolved_subclass.rb | +| calls.rb:115:1:118:3 | Object | unresolved_subclass.rb:1:1:22:4 | unresolved_subclass.rb | | calls.rb:120:1:123:3 | Hash | calls.rb:120:1:123:3 | Hash | | calls.rb:125:1:138:3 | Array | calls.rb:125:1:138:3 | Array | | calls.rb:165:1:169:3 | S | calls.rb:165:1:169:3 | S | @@ -197,6 +200,9 @@ getADeclaration | unresolved_subclass.rb:4:1:5:3 | UnresolvedNamespace::Subclass1 | unresolved_subclass.rb:4:1:5:3 | Subclass1 | | unresolved_subclass.rb:7:1:8:3 | UnresolvedNamespace::Subclass2 | unresolved_subclass.rb:7:1:8:3 | Subclass2 | | unresolved_subclass.rb:11:1:12:3 | UnresolvedNamespace::A | unresolved_subclass.rb:11:1:12:3 | A | +| unresolved_subclass.rb:14:1:15:3 | ...::Subclass1 | unresolved_subclass.rb:14:1:15:3 | Subclass1 | +| unresolved_subclass.rb:17:1:18:3 | ...::Subclass2 | unresolved_subclass.rb:17:1:18:3 | Subclass2 | +| unresolved_subclass.rb:21:1:22:3 | ...::A | unresolved_subclass.rb:21:1:22:3 | A | getSuperClass | calls.rb:43:1:58:3 | C | calls.rb:115:1:118:3 | Object | | calls.rb:65:1:69:3 | D | calls.rb:43:1:58:3 | C | @@ -259,6 +265,9 @@ getSuperClass | unresolved_subclass.rb:4:1:5:3 | UnresolvedNamespace::Subclass1 | unresolved_subclass.rb:1:1:2:3 | ResolvableBaseClass | | unresolved_subclass.rb:7:1:8:3 | UnresolvedNamespace::Subclass2 | unresolved_subclass.rb:4:1:5:3 | UnresolvedNamespace::Subclass1 | | unresolved_subclass.rb:11:1:12:3 | UnresolvedNamespace::A | calls.rb:115:1:118:3 | Object | +| unresolved_subclass.rb:14:1:15:3 | ...::Subclass1 | unresolved_subclass.rb:1:1:2:3 | ResolvableBaseClass | +| unresolved_subclass.rb:17:1:18:3 | ...::Subclass2 | calls.rb:115:1:118:3 | Object | +| unresolved_subclass.rb:21:1:22:3 | ...::A | calls.rb:115:1:118:3 | Object | getAPrependedModule | calls.rb:115:1:118:3 | Object | calls.rb:171:1:174:3 | A | | calls.rb:171:1:174:3 | A | toplevel_self_singleton.rb:2:5:5:7 | A::B | @@ -419,6 +428,12 @@ resolveConstantReadAccess | unresolved_subclass.rb:7:40:7:69 | Subclass1 | UnresolvedNamespace::Subclass1 | | unresolved_subclass.rb:11:7:11:25 | UnresolvedNamespace | UnresolvedNamespace | | unresolved_subclass.rb:11:32:11:50 | UnresolvedNamespace | UnresolvedNamespace | +| unresolved_subclass.rb:14:7:14:25 | UnresolvedNamespace | UnresolvedNamespace | +| unresolved_subclass.rb:14:52:14:70 | ResolvableBaseClass | ResolvableBaseClass | +| unresolved_subclass.rb:17:7:17:25 | UnresolvedNamespace | UnresolvedNamespace | +| unresolved_subclass.rb:17:52:17:70 | UnresolvedNamespace | UnresolvedNamespace | +| unresolved_subclass.rb:21:7:21:25 | UnresolvedNamespace | UnresolvedNamespace | +| unresolved_subclass.rb:21:44:21:62 | UnresolvedNamespace | UnresolvedNamespace | resolveConstantWriteAccess | calls.rb:21:1:34:3 | M | M | | calls.rb:43:1:58:3 | C | C | @@ -1878,15 +1893,41 @@ enclosingModule | toplevel_self_singleton.rb:30:13:30:19 | self | toplevel_self_singleton.rb:25:5:33:7 | class << ... | | toplevel_self_singleton.rb:31:13:31:20 | call to call_you | toplevel_self_singleton.rb:25:5:33:7 | class << ... | | toplevel_self_singleton.rb:31:13:31:20 | self | toplevel_self_singleton.rb:25:5:33:7 | class << ... | -| unresolved_subclass.rb:1:1:2:3 | ResolvableBaseClass | unresolved_subclass.rb:1:1:12:4 | unresolved_subclass.rb | -| unresolved_subclass.rb:4:1:5:3 | Subclass1 | unresolved_subclass.rb:1:1:12:4 | unresolved_subclass.rb | -| unresolved_subclass.rb:4:7:4:25 | UnresolvedNamespace | unresolved_subclass.rb:1:1:12:4 | unresolved_subclass.rb | -| unresolved_subclass.rb:4:40:4:58 | ResolvableBaseClass | unresolved_subclass.rb:1:1:12:4 | unresolved_subclass.rb | -| unresolved_subclass.rb:7:1:8:3 | Subclass2 | unresolved_subclass.rb:1:1:12:4 | unresolved_subclass.rb | -| unresolved_subclass.rb:7:7:7:25 | UnresolvedNamespace | unresolved_subclass.rb:1:1:12:4 | unresolved_subclass.rb | -| unresolved_subclass.rb:7:40:7:58 | UnresolvedNamespace | unresolved_subclass.rb:1:1:12:4 | unresolved_subclass.rb | -| unresolved_subclass.rb:7:40:7:69 | Subclass1 | unresolved_subclass.rb:1:1:12:4 | unresolved_subclass.rb | -| unresolved_subclass.rb:11:1:12:3 | A | unresolved_subclass.rb:1:1:12:4 | unresolved_subclass.rb | -| unresolved_subclass.rb:11:7:11:25 | UnresolvedNamespace | unresolved_subclass.rb:1:1:12:4 | unresolved_subclass.rb | -| unresolved_subclass.rb:11:32:11:50 | UnresolvedNamespace | unresolved_subclass.rb:1:1:12:4 | unresolved_subclass.rb | -| unresolved_subclass.rb:11:32:11:53 | B | unresolved_subclass.rb:1:1:12:4 | unresolved_subclass.rb | +| unresolved_subclass.rb:1:1:2:3 | ResolvableBaseClass | unresolved_subclass.rb:1:1:22:4 | unresolved_subclass.rb | +| unresolved_subclass.rb:4:1:5:3 | Subclass1 | unresolved_subclass.rb:1:1:22:4 | unresolved_subclass.rb | +| unresolved_subclass.rb:4:7:4:25 | UnresolvedNamespace | unresolved_subclass.rb:1:1:22:4 | unresolved_subclass.rb | +| unresolved_subclass.rb:4:40:4:58 | ResolvableBaseClass | unresolved_subclass.rb:1:1:22:4 | unresolved_subclass.rb | +| unresolved_subclass.rb:7:1:8:3 | Subclass2 | unresolved_subclass.rb:1:1:22:4 | unresolved_subclass.rb | +| unresolved_subclass.rb:7:7:7:25 | UnresolvedNamespace | unresolved_subclass.rb:1:1:22:4 | unresolved_subclass.rb | +| unresolved_subclass.rb:7:40:7:58 | UnresolvedNamespace | unresolved_subclass.rb:1:1:22:4 | unresolved_subclass.rb | +| unresolved_subclass.rb:7:40:7:69 | Subclass1 | unresolved_subclass.rb:1:1:22:4 | unresolved_subclass.rb | +| unresolved_subclass.rb:11:1:12:3 | A | unresolved_subclass.rb:1:1:22:4 | unresolved_subclass.rb | +| unresolved_subclass.rb:11:7:11:25 | UnresolvedNamespace | unresolved_subclass.rb:1:1:22:4 | unresolved_subclass.rb | +| unresolved_subclass.rb:11:32:11:50 | UnresolvedNamespace | unresolved_subclass.rb:1:1:22:4 | unresolved_subclass.rb | +| unresolved_subclass.rb:11:32:11:53 | B | unresolved_subclass.rb:1:1:22:4 | unresolved_subclass.rb | +| unresolved_subclass.rb:14:1:15:3 | Subclass1 | unresolved_subclass.rb:1:1:22:4 | unresolved_subclass.rb | +| unresolved_subclass.rb:14:7:14:25 | UnresolvedNamespace | unresolved_subclass.rb:1:1:22:4 | unresolved_subclass.rb | +| unresolved_subclass.rb:14:7:14:29 | X1 | unresolved_subclass.rb:1:1:22:4 | unresolved_subclass.rb | +| unresolved_subclass.rb:14:7:14:33 | X2 | unresolved_subclass.rb:1:1:22:4 | unresolved_subclass.rb | +| unresolved_subclass.rb:14:7:14:37 | X3 | unresolved_subclass.rb:1:1:22:4 | unresolved_subclass.rb | +| unresolved_subclass.rb:14:52:14:70 | ResolvableBaseClass | unresolved_subclass.rb:1:1:22:4 | unresolved_subclass.rb | +| unresolved_subclass.rb:17:1:18:3 | Subclass2 | unresolved_subclass.rb:1:1:22:4 | unresolved_subclass.rb | +| unresolved_subclass.rb:17:7:17:25 | UnresolvedNamespace | unresolved_subclass.rb:1:1:22:4 | unresolved_subclass.rb | +| unresolved_subclass.rb:17:7:17:29 | X1 | unresolved_subclass.rb:1:1:22:4 | unresolved_subclass.rb | +| unresolved_subclass.rb:17:7:17:33 | X2 | unresolved_subclass.rb:1:1:22:4 | unresolved_subclass.rb | +| unresolved_subclass.rb:17:7:17:37 | X3 | unresolved_subclass.rb:1:1:22:4 | unresolved_subclass.rb | +| unresolved_subclass.rb:17:52:17:70 | UnresolvedNamespace | unresolved_subclass.rb:1:1:22:4 | unresolved_subclass.rb | +| unresolved_subclass.rb:17:52:17:74 | X1 | unresolved_subclass.rb:1:1:22:4 | unresolved_subclass.rb | +| unresolved_subclass.rb:17:52:17:78 | X2 | unresolved_subclass.rb:1:1:22:4 | unresolved_subclass.rb | +| unresolved_subclass.rb:17:52:17:82 | X3 | unresolved_subclass.rb:1:1:22:4 | unresolved_subclass.rb | +| unresolved_subclass.rb:17:52:17:93 | Subclass1 | unresolved_subclass.rb:1:1:22:4 | unresolved_subclass.rb | +| unresolved_subclass.rb:21:1:22:3 | A | unresolved_subclass.rb:1:1:22:4 | unresolved_subclass.rb | +| unresolved_subclass.rb:21:7:21:25 | UnresolvedNamespace | unresolved_subclass.rb:1:1:22:4 | unresolved_subclass.rb | +| unresolved_subclass.rb:21:7:21:29 | X1 | unresolved_subclass.rb:1:1:22:4 | unresolved_subclass.rb | +| unresolved_subclass.rb:21:7:21:33 | X2 | unresolved_subclass.rb:1:1:22:4 | unresolved_subclass.rb | +| unresolved_subclass.rb:21:7:21:37 | X3 | unresolved_subclass.rb:1:1:22:4 | unresolved_subclass.rb | +| unresolved_subclass.rb:21:44:21:62 | UnresolvedNamespace | unresolved_subclass.rb:1:1:22:4 | unresolved_subclass.rb | +| unresolved_subclass.rb:21:44:21:66 | X1 | unresolved_subclass.rb:1:1:22:4 | unresolved_subclass.rb | +| unresolved_subclass.rb:21:44:21:70 | X2 | unresolved_subclass.rb:1:1:22:4 | unresolved_subclass.rb | +| unresolved_subclass.rb:21:44:21:74 | X3 | unresolved_subclass.rb:1:1:22:4 | unresolved_subclass.rb | +| unresolved_subclass.rb:21:44:21:77 | B | unresolved_subclass.rb:1:1:22:4 | unresolved_subclass.rb | diff --git a/ruby/ql/test/library-tests/modules/superclasses.expected b/ruby/ql/test/library-tests/modules/superclasses.expected index 14121b1da31..3c19d706484 100644 --- a/ruby/ql/test/library-tests/modules/superclasses.expected +++ b/ruby/ql/test/library-tests/modules/superclasses.expected @@ -262,3 +262,12 @@ unresolved_subclass.rb: # 11| UnresolvedNamespace::A #-----| -> Object + +# 14| ...::Subclass1 +#-----| -> ResolvableBaseClass + +# 17| ...::Subclass2 +#-----| -> Object + +# 21| ...::A +#-----| -> Object diff --git a/ruby/ql/test/library-tests/modules/unresolved_subclass.rb b/ruby/ql/test/library-tests/modules/unresolved_subclass.rb index 309330c6af1..2dad594a2a5 100644 --- a/ruby/ql/test/library-tests/modules/unresolved_subclass.rb +++ b/ruby/ql/test/library-tests/modules/unresolved_subclass.rb @@ -10,3 +10,13 @@ end # Ensure Object is a transitive superclass of this class UnresolvedNamespace::A < UnresolvedNamespace::B end + +class UnresolvedNamespace::X1::X2::X3::Subclass1 < ResolvableBaseClass +end + +class UnresolvedNamespace::X1::X2::X3::Subclass2 < UnresolvedNamespace::X1::X2::X3::Subclass1 +end + +# Ensure Object is a transitive superclass of this +class UnresolvedNamespace::X1::X2::X3::A < UnresolvedNamespace::X1::X2::X3::B +end From 4993e7c149ab809d4ef43278e66d5defb099b642 Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen <aschackmull@github.com> Date: Thu, 23 Mar 2023 13:39:53 +0100 Subject: [PATCH 350/631] Dataflow: Rename output signature --- .../semmle/code/java/dataflow/internal/DataFlow.qll | 12 ++++++------ .../internal/tainttracking1/TaintTracking.qll | 8 ++++---- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlow.qll b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlow.qll index 82714ed1af6..137612c52af 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlow.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlow.qll @@ -188,9 +188,9 @@ signature module StateConfigSig { signature int explorationLimitSig(); /** - * The output of a data flow computation. + * The output of a global data flow computation. */ -signature module DataFlowSig { +signature module GlobalFlowSig { /** * A `Node` augmented with a call context (except for sinks) and an access path. * Only those `PathNode`s that are reachable from a source, and which can reach a sink, are generated. @@ -224,7 +224,7 @@ signature module DataFlowSig { /** * Constructs a standard data flow computation. */ -module Global<ConfigSig Config> implements DataFlowSig { +module Global<ConfigSig Config> implements GlobalFlowSig { private module C implements FullStateConfigSig { import DefaultState<Config> import Config @@ -234,14 +234,14 @@ module Global<ConfigSig Config> implements DataFlowSig { } /** DEPRECATED: Use `Global` instead. */ -deprecated module Make<ConfigSig Config> implements DataFlowSig { +deprecated module Make<ConfigSig Config> implements GlobalFlowSig { import Global<Config> } /** * Constructs a data flow computation using flow state. */ -module GlobalWithState<StateConfigSig Config> implements DataFlowSig { +module GlobalWithState<StateConfigSig Config> implements GlobalFlowSig { private module C implements FullStateConfigSig { import Config } @@ -250,7 +250,7 @@ module GlobalWithState<StateConfigSig Config> implements DataFlowSig { } /** DEPRECATED: Use `GlobalWithState` instead. */ -deprecated module MakeWithState<StateConfigSig Config> implements DataFlowSig { +deprecated module MakeWithState<StateConfigSig Config> implements GlobalFlowSig { import GlobalWithState<Config> } diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/tainttracking1/TaintTracking.qll b/java/ql/lib/semmle/code/java/dataflow/internal/tainttracking1/TaintTracking.qll index 192a52f44e3..3f8cef3698a 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/tainttracking1/TaintTracking.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/tainttracking1/TaintTracking.qll @@ -35,7 +35,7 @@ private module AddTaintDefaults<DataFlowInternal::FullStateConfigSig Config> imp /** * Constructs a standard taint tracking computation. */ -module Global<DataFlow::ConfigSig Config> implements DataFlow::DataFlowSig { +module Global<DataFlow::ConfigSig Config> implements DataFlow::GlobalFlowSig { private module Config0 implements DataFlowInternal::FullStateConfigSig { import DataFlowInternal::DefaultState<Config> import Config @@ -49,14 +49,14 @@ module Global<DataFlow::ConfigSig Config> implements DataFlow::DataFlowSig { } /** DEPRECATED: Use `Global` instead. */ -deprecated module Make<DataFlow::ConfigSig Config> implements DataFlow::DataFlowSig { +deprecated module Make<DataFlow::ConfigSig Config> implements DataFlow::GlobalFlowSig { import Global<Config> } /** * Constructs a taint tracking computation using flow state. */ -module GlobalWithState<DataFlow::StateConfigSig Config> implements DataFlow::DataFlowSig { +module GlobalWithState<DataFlow::StateConfigSig Config> implements DataFlow::GlobalFlowSig { private module Config0 implements DataFlowInternal::FullStateConfigSig { import Config } @@ -69,6 +69,6 @@ module GlobalWithState<DataFlow::StateConfigSig Config> implements DataFlow::Dat } /** DEPRECATED: Use `GlobalWithState` instead. */ -deprecated module MakeWithState<DataFlow::StateConfigSig Config> implements DataFlow::DataFlowSig { +deprecated module MakeWithState<DataFlow::StateConfigSig Config> implements DataFlow::GlobalFlowSig { import GlobalWithState<Config> } From d440bc2d0cc0c4c978378e44e09d324e3e9930b9 Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen <aschackmull@github.com> Date: Thu, 23 Mar 2023 13:40:23 +0100 Subject: [PATCH 351/631] Dataflow: Sync. --- .../semmle/code/cpp/dataflow/internal/DataFlow.qll | 12 ++++++------ .../internal/tainttracking1/TaintTracking.qll | 8 ++++---- .../code/cpp/ir/dataflow/internal/DataFlow.qll | 12 ++++++------ .../internal/tainttracking1/TaintTracking.qll | 8 ++++---- .../code/csharp/dataflow/internal/DataFlow.qll | 12 ++++++------ .../internal/tainttracking1/TaintTracking.qll | 8 ++++---- go/ql/lib/semmle/go/dataflow/internal/DataFlow.qll | 12 ++++++------ .../internal/tainttracking1/TaintTracking.qll | 8 ++++---- .../semmle/python/dataflow/new/internal/DataFlow.qll | 12 ++++++------ .../new/internal/tainttracking1/TaintTracking.qll | 8 ++++---- .../lib/codeql/ruby/dataflow/internal/DataFlow.qll | 12 ++++++------ .../internal/tainttracking1/TaintTracking.qll | 8 ++++---- .../lib/codeql/swift/dataflow/internal/DataFlow.qll | 12 ++++++------ .../internal/tainttracking1/TaintTracking.qll | 8 ++++---- 14 files changed, 70 insertions(+), 70 deletions(-) diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlow.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlow.qll index 82714ed1af6..137612c52af 100644 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlow.qll +++ b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlow.qll @@ -188,9 +188,9 @@ signature module StateConfigSig { signature int explorationLimitSig(); /** - * The output of a data flow computation. + * The output of a global data flow computation. */ -signature module DataFlowSig { +signature module GlobalFlowSig { /** * A `Node` augmented with a call context (except for sinks) and an access path. * Only those `PathNode`s that are reachable from a source, and which can reach a sink, are generated. @@ -224,7 +224,7 @@ signature module DataFlowSig { /** * Constructs a standard data flow computation. */ -module Global<ConfigSig Config> implements DataFlowSig { +module Global<ConfigSig Config> implements GlobalFlowSig { private module C implements FullStateConfigSig { import DefaultState<Config> import Config @@ -234,14 +234,14 @@ module Global<ConfigSig Config> implements DataFlowSig { } /** DEPRECATED: Use `Global` instead. */ -deprecated module Make<ConfigSig Config> implements DataFlowSig { +deprecated module Make<ConfigSig Config> implements GlobalFlowSig { import Global<Config> } /** * Constructs a data flow computation using flow state. */ -module GlobalWithState<StateConfigSig Config> implements DataFlowSig { +module GlobalWithState<StateConfigSig Config> implements GlobalFlowSig { private module C implements FullStateConfigSig { import Config } @@ -250,7 +250,7 @@ module GlobalWithState<StateConfigSig Config> implements DataFlowSig { } /** DEPRECATED: Use `GlobalWithState` instead. */ -deprecated module MakeWithState<StateConfigSig Config> implements DataFlowSig { +deprecated module MakeWithState<StateConfigSig Config> implements GlobalFlowSig { import GlobalWithState<Config> } diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/tainttracking1/TaintTracking.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/tainttracking1/TaintTracking.qll index 192a52f44e3..3f8cef3698a 100644 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/tainttracking1/TaintTracking.qll +++ b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/tainttracking1/TaintTracking.qll @@ -35,7 +35,7 @@ private module AddTaintDefaults<DataFlowInternal::FullStateConfigSig Config> imp /** * Constructs a standard taint tracking computation. */ -module Global<DataFlow::ConfigSig Config> implements DataFlow::DataFlowSig { +module Global<DataFlow::ConfigSig Config> implements DataFlow::GlobalFlowSig { private module Config0 implements DataFlowInternal::FullStateConfigSig { import DataFlowInternal::DefaultState<Config> import Config @@ -49,14 +49,14 @@ module Global<DataFlow::ConfigSig Config> implements DataFlow::DataFlowSig { } /** DEPRECATED: Use `Global` instead. */ -deprecated module Make<DataFlow::ConfigSig Config> implements DataFlow::DataFlowSig { +deprecated module Make<DataFlow::ConfigSig Config> implements DataFlow::GlobalFlowSig { import Global<Config> } /** * Constructs a taint tracking computation using flow state. */ -module GlobalWithState<DataFlow::StateConfigSig Config> implements DataFlow::DataFlowSig { +module GlobalWithState<DataFlow::StateConfigSig Config> implements DataFlow::GlobalFlowSig { private module Config0 implements DataFlowInternal::FullStateConfigSig { import Config } @@ -69,6 +69,6 @@ module GlobalWithState<DataFlow::StateConfigSig Config> implements DataFlow::Dat } /** DEPRECATED: Use `GlobalWithState` instead. */ -deprecated module MakeWithState<DataFlow::StateConfigSig Config> implements DataFlow::DataFlowSig { +deprecated module MakeWithState<DataFlow::StateConfigSig Config> implements DataFlow::GlobalFlowSig { import GlobalWithState<Config> } diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlow.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlow.qll index 82714ed1af6..137612c52af 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlow.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlow.qll @@ -188,9 +188,9 @@ signature module StateConfigSig { signature int explorationLimitSig(); /** - * The output of a data flow computation. + * The output of a global data flow computation. */ -signature module DataFlowSig { +signature module GlobalFlowSig { /** * A `Node` augmented with a call context (except for sinks) and an access path. * Only those `PathNode`s that are reachable from a source, and which can reach a sink, are generated. @@ -224,7 +224,7 @@ signature module DataFlowSig { /** * Constructs a standard data flow computation. */ -module Global<ConfigSig Config> implements DataFlowSig { +module Global<ConfigSig Config> implements GlobalFlowSig { private module C implements FullStateConfigSig { import DefaultState<Config> import Config @@ -234,14 +234,14 @@ module Global<ConfigSig Config> implements DataFlowSig { } /** DEPRECATED: Use `Global` instead. */ -deprecated module Make<ConfigSig Config> implements DataFlowSig { +deprecated module Make<ConfigSig Config> implements GlobalFlowSig { import Global<Config> } /** * Constructs a data flow computation using flow state. */ -module GlobalWithState<StateConfigSig Config> implements DataFlowSig { +module GlobalWithState<StateConfigSig Config> implements GlobalFlowSig { private module C implements FullStateConfigSig { import Config } @@ -250,7 +250,7 @@ module GlobalWithState<StateConfigSig Config> implements DataFlowSig { } /** DEPRECATED: Use `GlobalWithState` instead. */ -deprecated module MakeWithState<StateConfigSig Config> implements DataFlowSig { +deprecated module MakeWithState<StateConfigSig Config> implements GlobalFlowSig { import GlobalWithState<Config> } diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/tainttracking1/TaintTracking.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/tainttracking1/TaintTracking.qll index 192a52f44e3..3f8cef3698a 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/tainttracking1/TaintTracking.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/tainttracking1/TaintTracking.qll @@ -35,7 +35,7 @@ private module AddTaintDefaults<DataFlowInternal::FullStateConfigSig Config> imp /** * Constructs a standard taint tracking computation. */ -module Global<DataFlow::ConfigSig Config> implements DataFlow::DataFlowSig { +module Global<DataFlow::ConfigSig Config> implements DataFlow::GlobalFlowSig { private module Config0 implements DataFlowInternal::FullStateConfigSig { import DataFlowInternal::DefaultState<Config> import Config @@ -49,14 +49,14 @@ module Global<DataFlow::ConfigSig Config> implements DataFlow::DataFlowSig { } /** DEPRECATED: Use `Global` instead. */ -deprecated module Make<DataFlow::ConfigSig Config> implements DataFlow::DataFlowSig { +deprecated module Make<DataFlow::ConfigSig Config> implements DataFlow::GlobalFlowSig { import Global<Config> } /** * Constructs a taint tracking computation using flow state. */ -module GlobalWithState<DataFlow::StateConfigSig Config> implements DataFlow::DataFlowSig { +module GlobalWithState<DataFlow::StateConfigSig Config> implements DataFlow::GlobalFlowSig { private module Config0 implements DataFlowInternal::FullStateConfigSig { import Config } @@ -69,6 +69,6 @@ module GlobalWithState<DataFlow::StateConfigSig Config> implements DataFlow::Dat } /** DEPRECATED: Use `GlobalWithState` instead. */ -deprecated module MakeWithState<DataFlow::StateConfigSig Config> implements DataFlow::DataFlowSig { +deprecated module MakeWithState<DataFlow::StateConfigSig Config> implements DataFlow::GlobalFlowSig { import GlobalWithState<Config> } diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlow.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlow.qll index 82714ed1af6..137612c52af 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlow.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlow.qll @@ -188,9 +188,9 @@ signature module StateConfigSig { signature int explorationLimitSig(); /** - * The output of a data flow computation. + * The output of a global data flow computation. */ -signature module DataFlowSig { +signature module GlobalFlowSig { /** * A `Node` augmented with a call context (except for sinks) and an access path. * Only those `PathNode`s that are reachable from a source, and which can reach a sink, are generated. @@ -224,7 +224,7 @@ signature module DataFlowSig { /** * Constructs a standard data flow computation. */ -module Global<ConfigSig Config> implements DataFlowSig { +module Global<ConfigSig Config> implements GlobalFlowSig { private module C implements FullStateConfigSig { import DefaultState<Config> import Config @@ -234,14 +234,14 @@ module Global<ConfigSig Config> implements DataFlowSig { } /** DEPRECATED: Use `Global` instead. */ -deprecated module Make<ConfigSig Config> implements DataFlowSig { +deprecated module Make<ConfigSig Config> implements GlobalFlowSig { import Global<Config> } /** * Constructs a data flow computation using flow state. */ -module GlobalWithState<StateConfigSig Config> implements DataFlowSig { +module GlobalWithState<StateConfigSig Config> implements GlobalFlowSig { private module C implements FullStateConfigSig { import Config } @@ -250,7 +250,7 @@ module GlobalWithState<StateConfigSig Config> implements DataFlowSig { } /** DEPRECATED: Use `GlobalWithState` instead. */ -deprecated module MakeWithState<StateConfigSig Config> implements DataFlowSig { +deprecated module MakeWithState<StateConfigSig Config> implements GlobalFlowSig { import GlobalWithState<Config> } diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/tainttracking1/TaintTracking.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/tainttracking1/TaintTracking.qll index 192a52f44e3..3f8cef3698a 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/tainttracking1/TaintTracking.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/tainttracking1/TaintTracking.qll @@ -35,7 +35,7 @@ private module AddTaintDefaults<DataFlowInternal::FullStateConfigSig Config> imp /** * Constructs a standard taint tracking computation. */ -module Global<DataFlow::ConfigSig Config> implements DataFlow::DataFlowSig { +module Global<DataFlow::ConfigSig Config> implements DataFlow::GlobalFlowSig { private module Config0 implements DataFlowInternal::FullStateConfigSig { import DataFlowInternal::DefaultState<Config> import Config @@ -49,14 +49,14 @@ module Global<DataFlow::ConfigSig Config> implements DataFlow::DataFlowSig { } /** DEPRECATED: Use `Global` instead. */ -deprecated module Make<DataFlow::ConfigSig Config> implements DataFlow::DataFlowSig { +deprecated module Make<DataFlow::ConfigSig Config> implements DataFlow::GlobalFlowSig { import Global<Config> } /** * Constructs a taint tracking computation using flow state. */ -module GlobalWithState<DataFlow::StateConfigSig Config> implements DataFlow::DataFlowSig { +module GlobalWithState<DataFlow::StateConfigSig Config> implements DataFlow::GlobalFlowSig { private module Config0 implements DataFlowInternal::FullStateConfigSig { import Config } @@ -69,6 +69,6 @@ module GlobalWithState<DataFlow::StateConfigSig Config> implements DataFlow::Dat } /** DEPRECATED: Use `GlobalWithState` instead. */ -deprecated module MakeWithState<DataFlow::StateConfigSig Config> implements DataFlow::DataFlowSig { +deprecated module MakeWithState<DataFlow::StateConfigSig Config> implements DataFlow::GlobalFlowSig { import GlobalWithState<Config> } diff --git a/go/ql/lib/semmle/go/dataflow/internal/DataFlow.qll b/go/ql/lib/semmle/go/dataflow/internal/DataFlow.qll index 82714ed1af6..137612c52af 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/DataFlow.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/DataFlow.qll @@ -188,9 +188,9 @@ signature module StateConfigSig { signature int explorationLimitSig(); /** - * The output of a data flow computation. + * The output of a global data flow computation. */ -signature module DataFlowSig { +signature module GlobalFlowSig { /** * A `Node` augmented with a call context (except for sinks) and an access path. * Only those `PathNode`s that are reachable from a source, and which can reach a sink, are generated. @@ -224,7 +224,7 @@ signature module DataFlowSig { /** * Constructs a standard data flow computation. */ -module Global<ConfigSig Config> implements DataFlowSig { +module Global<ConfigSig Config> implements GlobalFlowSig { private module C implements FullStateConfigSig { import DefaultState<Config> import Config @@ -234,14 +234,14 @@ module Global<ConfigSig Config> implements DataFlowSig { } /** DEPRECATED: Use `Global` instead. */ -deprecated module Make<ConfigSig Config> implements DataFlowSig { +deprecated module Make<ConfigSig Config> implements GlobalFlowSig { import Global<Config> } /** * Constructs a data flow computation using flow state. */ -module GlobalWithState<StateConfigSig Config> implements DataFlowSig { +module GlobalWithState<StateConfigSig Config> implements GlobalFlowSig { private module C implements FullStateConfigSig { import Config } @@ -250,7 +250,7 @@ module GlobalWithState<StateConfigSig Config> implements DataFlowSig { } /** DEPRECATED: Use `GlobalWithState` instead. */ -deprecated module MakeWithState<StateConfigSig Config> implements DataFlowSig { +deprecated module MakeWithState<StateConfigSig Config> implements GlobalFlowSig { import GlobalWithState<Config> } diff --git a/go/ql/lib/semmle/go/dataflow/internal/tainttracking1/TaintTracking.qll b/go/ql/lib/semmle/go/dataflow/internal/tainttracking1/TaintTracking.qll index 192a52f44e3..3f8cef3698a 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/tainttracking1/TaintTracking.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/tainttracking1/TaintTracking.qll @@ -35,7 +35,7 @@ private module AddTaintDefaults<DataFlowInternal::FullStateConfigSig Config> imp /** * Constructs a standard taint tracking computation. */ -module Global<DataFlow::ConfigSig Config> implements DataFlow::DataFlowSig { +module Global<DataFlow::ConfigSig Config> implements DataFlow::GlobalFlowSig { private module Config0 implements DataFlowInternal::FullStateConfigSig { import DataFlowInternal::DefaultState<Config> import Config @@ -49,14 +49,14 @@ module Global<DataFlow::ConfigSig Config> implements DataFlow::DataFlowSig { } /** DEPRECATED: Use `Global` instead. */ -deprecated module Make<DataFlow::ConfigSig Config> implements DataFlow::DataFlowSig { +deprecated module Make<DataFlow::ConfigSig Config> implements DataFlow::GlobalFlowSig { import Global<Config> } /** * Constructs a taint tracking computation using flow state. */ -module GlobalWithState<DataFlow::StateConfigSig Config> implements DataFlow::DataFlowSig { +module GlobalWithState<DataFlow::StateConfigSig Config> implements DataFlow::GlobalFlowSig { private module Config0 implements DataFlowInternal::FullStateConfigSig { import Config } @@ -69,6 +69,6 @@ module GlobalWithState<DataFlow::StateConfigSig Config> implements DataFlow::Dat } /** DEPRECATED: Use `GlobalWithState` instead. */ -deprecated module MakeWithState<DataFlow::StateConfigSig Config> implements DataFlow::DataFlowSig { +deprecated module MakeWithState<DataFlow::StateConfigSig Config> implements DataFlow::GlobalFlowSig { import GlobalWithState<Config> } diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlow.qll b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlow.qll index 82714ed1af6..137612c52af 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlow.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlow.qll @@ -188,9 +188,9 @@ signature module StateConfigSig { signature int explorationLimitSig(); /** - * The output of a data flow computation. + * The output of a global data flow computation. */ -signature module DataFlowSig { +signature module GlobalFlowSig { /** * A `Node` augmented with a call context (except for sinks) and an access path. * Only those `PathNode`s that are reachable from a source, and which can reach a sink, are generated. @@ -224,7 +224,7 @@ signature module DataFlowSig { /** * Constructs a standard data flow computation. */ -module Global<ConfigSig Config> implements DataFlowSig { +module Global<ConfigSig Config> implements GlobalFlowSig { private module C implements FullStateConfigSig { import DefaultState<Config> import Config @@ -234,14 +234,14 @@ module Global<ConfigSig Config> implements DataFlowSig { } /** DEPRECATED: Use `Global` instead. */ -deprecated module Make<ConfigSig Config> implements DataFlowSig { +deprecated module Make<ConfigSig Config> implements GlobalFlowSig { import Global<Config> } /** * Constructs a data flow computation using flow state. */ -module GlobalWithState<StateConfigSig Config> implements DataFlowSig { +module GlobalWithState<StateConfigSig Config> implements GlobalFlowSig { private module C implements FullStateConfigSig { import Config } @@ -250,7 +250,7 @@ module GlobalWithState<StateConfigSig Config> implements DataFlowSig { } /** DEPRECATED: Use `GlobalWithState` instead. */ -deprecated module MakeWithState<StateConfigSig Config> implements DataFlowSig { +deprecated module MakeWithState<StateConfigSig Config> implements GlobalFlowSig { import GlobalWithState<Config> } diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/tainttracking1/TaintTracking.qll b/python/ql/lib/semmle/python/dataflow/new/internal/tainttracking1/TaintTracking.qll index 192a52f44e3..3f8cef3698a 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/tainttracking1/TaintTracking.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/tainttracking1/TaintTracking.qll @@ -35,7 +35,7 @@ private module AddTaintDefaults<DataFlowInternal::FullStateConfigSig Config> imp /** * Constructs a standard taint tracking computation. */ -module Global<DataFlow::ConfigSig Config> implements DataFlow::DataFlowSig { +module Global<DataFlow::ConfigSig Config> implements DataFlow::GlobalFlowSig { private module Config0 implements DataFlowInternal::FullStateConfigSig { import DataFlowInternal::DefaultState<Config> import Config @@ -49,14 +49,14 @@ module Global<DataFlow::ConfigSig Config> implements DataFlow::DataFlowSig { } /** DEPRECATED: Use `Global` instead. */ -deprecated module Make<DataFlow::ConfigSig Config> implements DataFlow::DataFlowSig { +deprecated module Make<DataFlow::ConfigSig Config> implements DataFlow::GlobalFlowSig { import Global<Config> } /** * Constructs a taint tracking computation using flow state. */ -module GlobalWithState<DataFlow::StateConfigSig Config> implements DataFlow::DataFlowSig { +module GlobalWithState<DataFlow::StateConfigSig Config> implements DataFlow::GlobalFlowSig { private module Config0 implements DataFlowInternal::FullStateConfigSig { import Config } @@ -69,6 +69,6 @@ module GlobalWithState<DataFlow::StateConfigSig Config> implements DataFlow::Dat } /** DEPRECATED: Use `GlobalWithState` instead. */ -deprecated module MakeWithState<DataFlow::StateConfigSig Config> implements DataFlow::DataFlowSig { +deprecated module MakeWithState<DataFlow::StateConfigSig Config> implements DataFlow::GlobalFlowSig { import GlobalWithState<Config> } diff --git a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlow.qll b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlow.qll index 82714ed1af6..137612c52af 100644 --- a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlow.qll +++ b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlow.qll @@ -188,9 +188,9 @@ signature module StateConfigSig { signature int explorationLimitSig(); /** - * The output of a data flow computation. + * The output of a global data flow computation. */ -signature module DataFlowSig { +signature module GlobalFlowSig { /** * A `Node` augmented with a call context (except for sinks) and an access path. * Only those `PathNode`s that are reachable from a source, and which can reach a sink, are generated. @@ -224,7 +224,7 @@ signature module DataFlowSig { /** * Constructs a standard data flow computation. */ -module Global<ConfigSig Config> implements DataFlowSig { +module Global<ConfigSig Config> implements GlobalFlowSig { private module C implements FullStateConfigSig { import DefaultState<Config> import Config @@ -234,14 +234,14 @@ module Global<ConfigSig Config> implements DataFlowSig { } /** DEPRECATED: Use `Global` instead. */ -deprecated module Make<ConfigSig Config> implements DataFlowSig { +deprecated module Make<ConfigSig Config> implements GlobalFlowSig { import Global<Config> } /** * Constructs a data flow computation using flow state. */ -module GlobalWithState<StateConfigSig Config> implements DataFlowSig { +module GlobalWithState<StateConfigSig Config> implements GlobalFlowSig { private module C implements FullStateConfigSig { import Config } @@ -250,7 +250,7 @@ module GlobalWithState<StateConfigSig Config> implements DataFlowSig { } /** DEPRECATED: Use `GlobalWithState` instead. */ -deprecated module MakeWithState<StateConfigSig Config> implements DataFlowSig { +deprecated module MakeWithState<StateConfigSig Config> implements GlobalFlowSig { import GlobalWithState<Config> } diff --git a/ruby/ql/lib/codeql/ruby/dataflow/internal/tainttracking1/TaintTracking.qll b/ruby/ql/lib/codeql/ruby/dataflow/internal/tainttracking1/TaintTracking.qll index 192a52f44e3..3f8cef3698a 100644 --- a/ruby/ql/lib/codeql/ruby/dataflow/internal/tainttracking1/TaintTracking.qll +++ b/ruby/ql/lib/codeql/ruby/dataflow/internal/tainttracking1/TaintTracking.qll @@ -35,7 +35,7 @@ private module AddTaintDefaults<DataFlowInternal::FullStateConfigSig Config> imp /** * Constructs a standard taint tracking computation. */ -module Global<DataFlow::ConfigSig Config> implements DataFlow::DataFlowSig { +module Global<DataFlow::ConfigSig Config> implements DataFlow::GlobalFlowSig { private module Config0 implements DataFlowInternal::FullStateConfigSig { import DataFlowInternal::DefaultState<Config> import Config @@ -49,14 +49,14 @@ module Global<DataFlow::ConfigSig Config> implements DataFlow::DataFlowSig { } /** DEPRECATED: Use `Global` instead. */ -deprecated module Make<DataFlow::ConfigSig Config> implements DataFlow::DataFlowSig { +deprecated module Make<DataFlow::ConfigSig Config> implements DataFlow::GlobalFlowSig { import Global<Config> } /** * Constructs a taint tracking computation using flow state. */ -module GlobalWithState<DataFlow::StateConfigSig Config> implements DataFlow::DataFlowSig { +module GlobalWithState<DataFlow::StateConfigSig Config> implements DataFlow::GlobalFlowSig { private module Config0 implements DataFlowInternal::FullStateConfigSig { import Config } @@ -69,6 +69,6 @@ module GlobalWithState<DataFlow::StateConfigSig Config> implements DataFlow::Dat } /** DEPRECATED: Use `GlobalWithState` instead. */ -deprecated module MakeWithState<DataFlow::StateConfigSig Config> implements DataFlow::DataFlowSig { +deprecated module MakeWithState<DataFlow::StateConfigSig Config> implements DataFlow::GlobalFlowSig { import GlobalWithState<Config> } diff --git a/swift/ql/lib/codeql/swift/dataflow/internal/DataFlow.qll b/swift/ql/lib/codeql/swift/dataflow/internal/DataFlow.qll index 82714ed1af6..137612c52af 100644 --- a/swift/ql/lib/codeql/swift/dataflow/internal/DataFlow.qll +++ b/swift/ql/lib/codeql/swift/dataflow/internal/DataFlow.qll @@ -188,9 +188,9 @@ signature module StateConfigSig { signature int explorationLimitSig(); /** - * The output of a data flow computation. + * The output of a global data flow computation. */ -signature module DataFlowSig { +signature module GlobalFlowSig { /** * A `Node` augmented with a call context (except for sinks) and an access path. * Only those `PathNode`s that are reachable from a source, and which can reach a sink, are generated. @@ -224,7 +224,7 @@ signature module DataFlowSig { /** * Constructs a standard data flow computation. */ -module Global<ConfigSig Config> implements DataFlowSig { +module Global<ConfigSig Config> implements GlobalFlowSig { private module C implements FullStateConfigSig { import DefaultState<Config> import Config @@ -234,14 +234,14 @@ module Global<ConfigSig Config> implements DataFlowSig { } /** DEPRECATED: Use `Global` instead. */ -deprecated module Make<ConfigSig Config> implements DataFlowSig { +deprecated module Make<ConfigSig Config> implements GlobalFlowSig { import Global<Config> } /** * Constructs a data flow computation using flow state. */ -module GlobalWithState<StateConfigSig Config> implements DataFlowSig { +module GlobalWithState<StateConfigSig Config> implements GlobalFlowSig { private module C implements FullStateConfigSig { import Config } @@ -250,7 +250,7 @@ module GlobalWithState<StateConfigSig Config> implements DataFlowSig { } /** DEPRECATED: Use `GlobalWithState` instead. */ -deprecated module MakeWithState<StateConfigSig Config> implements DataFlowSig { +deprecated module MakeWithState<StateConfigSig Config> implements GlobalFlowSig { import GlobalWithState<Config> } diff --git a/swift/ql/lib/codeql/swift/dataflow/internal/tainttracking1/TaintTracking.qll b/swift/ql/lib/codeql/swift/dataflow/internal/tainttracking1/TaintTracking.qll index 192a52f44e3..3f8cef3698a 100644 --- a/swift/ql/lib/codeql/swift/dataflow/internal/tainttracking1/TaintTracking.qll +++ b/swift/ql/lib/codeql/swift/dataflow/internal/tainttracking1/TaintTracking.qll @@ -35,7 +35,7 @@ private module AddTaintDefaults<DataFlowInternal::FullStateConfigSig Config> imp /** * Constructs a standard taint tracking computation. */ -module Global<DataFlow::ConfigSig Config> implements DataFlow::DataFlowSig { +module Global<DataFlow::ConfigSig Config> implements DataFlow::GlobalFlowSig { private module Config0 implements DataFlowInternal::FullStateConfigSig { import DataFlowInternal::DefaultState<Config> import Config @@ -49,14 +49,14 @@ module Global<DataFlow::ConfigSig Config> implements DataFlow::DataFlowSig { } /** DEPRECATED: Use `Global` instead. */ -deprecated module Make<DataFlow::ConfigSig Config> implements DataFlow::DataFlowSig { +deprecated module Make<DataFlow::ConfigSig Config> implements DataFlow::GlobalFlowSig { import Global<Config> } /** * Constructs a taint tracking computation using flow state. */ -module GlobalWithState<DataFlow::StateConfigSig Config> implements DataFlow::DataFlowSig { +module GlobalWithState<DataFlow::StateConfigSig Config> implements DataFlow::GlobalFlowSig { private module Config0 implements DataFlowInternal::FullStateConfigSig { import Config } @@ -69,6 +69,6 @@ module GlobalWithState<DataFlow::StateConfigSig Config> implements DataFlow::Dat } /** DEPRECATED: Use `GlobalWithState` instead. */ -deprecated module MakeWithState<DataFlow::StateConfigSig Config> implements DataFlow::DataFlowSig { +deprecated module MakeWithState<DataFlow::StateConfigSig Config> implements DataFlow::GlobalFlowSig { import GlobalWithState<Config> } From 61bafd358a5b2319aa4ba4d1eefb959980fd054a Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen <mathiasvp@github.com> Date: Thu, 23 Mar 2023 09:16:10 +0000 Subject: [PATCH 352/631] C++: Fix another place that assumed that 'Expr' was always 'Instruction'. --- .../test/library-tests/ir/modulus-analysis/ModulusAnalysis.ql | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cpp/ql/test/library-tests/ir/modulus-analysis/ModulusAnalysis.ql b/cpp/ql/test/library-tests/ir/modulus-analysis/ModulusAnalysis.ql index bae958e1076..e7c56c240df 100644 --- a/cpp/ql/test/library-tests/ir/modulus-analysis/ModulusAnalysis.ql +++ b/cpp/ql/test/library-tests/ir/modulus-analysis/ModulusAnalysis.ql @@ -5,6 +5,7 @@ import experimental.semmle.code.cpp.semantic.analysis.RangeUtils import experimental.semmle.code.cpp.semantic.analysis.FloatDelta import experimental.semmle.code.cpp.semantic.analysis.RangeAnalysisSpecific import experimental.semmle.code.cpp.semantic.analysis.RangeAnalysisImpl +import experimental.semmle.code.cpp.semantic.SemanticExprSpecific import semmle.code.cpp.ir.IR as IR import TestUtilities.InlineExpectationsTest @@ -18,7 +19,7 @@ class ModulusAnalysisTest extends InlineExpectationsTest { override predicate hasActualResult(Location location, string element, string tag, string value) { exists(SemExpr e, IR::CallInstruction call | - call.getArgument(0) = e and + getSemanticExpr(call.getArgument(0)) = e and call.getStaticCallTarget().hasName("mod") and tag = "mod" and element = e.toString() and From a59a404752ca30944353c31bfe2f7a42626ac3e8 Mon Sep 17 00:00:00 2001 From: Asger F <asgerf@github.com> Date: Thu, 23 Mar 2023 14:28:09 +0100 Subject: [PATCH 353/631] Ruby: redundant check is implied by isToplevel() --- ruby/ql/lib/codeql/ruby/ast/internal/Module.qll | 1 - 1 file changed, 1 deletion(-) diff --git a/ruby/ql/lib/codeql/ruby/ast/internal/Module.qll b/ruby/ql/lib/codeql/ruby/ast/internal/Module.qll index 7b8ab7acba3..b72d5ea2f9a 100644 --- a/ruby/ql/lib/codeql/ruby/ast/internal/Module.qll +++ b/ruby/ql/lib/codeql/ruby/ast/internal/Module.qll @@ -407,7 +407,6 @@ private module ResolveImpl { */ string getAnAssumedGlobalConst() { exists(ConstantAccess access | - not exists(access.getScopeExpr()) and result = access.getName() and isToplevel(access) ) From 0f7a1d283d765ced27179f461af1f112b0227a1b Mon Sep 17 00:00:00 2001 From: Joe Farebrother <joefarebrother@github.com> Date: Mon, 23 Jan 2023 16:22:31 +0000 Subject: [PATCH 354/631] Add Netty models --- java/ql/lib/ext/io.netty.buffer.model.yml | 25 +++++++++++++++++++ java/ql/lib/ext/io.netty.channel.model.yml | 5 ++++ .../lib/ext/io.netty.handler.codec.model.yml | 22 ++++++++++++++++ 3 files changed, 52 insertions(+) create mode 100644 java/ql/lib/ext/io.netty.buffer.model.yml create mode 100644 java/ql/lib/ext/io.netty.handler.codec.model.yml diff --git a/java/ql/lib/ext/io.netty.buffer.model.yml b/java/ql/lib/ext/io.netty.buffer.model.yml new file mode 100644 index 00000000000..2a842c67332 --- /dev/null +++ b/java/ql/lib/ext/io.netty.buffer.model.yml @@ -0,0 +1,25 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: summaryModel + data: + - ["io.netty.buffer", "ByteBuf", True, "getBuffer", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "getByte", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "getBytes", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "getChar", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "getCharSequence", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "getCharSequence", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "readBytes", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "readChar", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "readCharSequence", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "readSlice", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.buffer", "ByteBufHolder", True, "content", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "readBytes", "", "", "Argument[-1]", "Argument[0]", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "setByte", "", "", "Argument[1]", "Argument[-1]", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "setBytes", "", "", "Argument[1]", "Argument[-1]", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "setChar", "", "", "Argument[1]", "Argument[-1]", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "setCharSequence", "", "", "Argument[1]", "Argument[-1]", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "writeByte", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "writeBytes", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "writeChar", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "writeCharSequence", "", "", "Argument[1]", "Argument[-1]", "taint", "manual"] \ No newline at end of file diff --git a/java/ql/lib/ext/io.netty.channel.model.yml b/java/ql/lib/ext/io.netty.channel.model.yml index e1125013a63..0e788e093b2 100644 --- a/java/ql/lib/ext/io.netty.channel.model.yml +++ b/java/ql/lib/ext/io.netty.channel.model.yml @@ -12,3 +12,8 @@ extensions: - ["io.netty.channel", "DefaultChannelPipeline", False, "connect", "(SocketAddress,ChannelPromise)", "", "Argument[0]", "open-url", "ai-generated"] - ["io.netty.channel", "DefaultChannelPipeline", False, "connect", "(SocketAddress,SocketAddress,ChannelPromise)", "", "Argument[0]", "open-url", "ai-generated"] - ["io.netty.channel", "DefaultChannelPipeline", False, "connect", "(SocketAddress,SocketAddress)", "", "Argument[0]", "open-url", "ai-generated"] + - addsTo: + pack: codeql/java-all + extensible: sourceModel + data: + - ["io.netty.channel", "ChannelInboundHandler", True, "channelRead", "", "", "Parameter[1]", "remote", "manual"] diff --git a/java/ql/lib/ext/io.netty.handler.codec.model.yml b/java/ql/lib/ext/io.netty.handler.codec.model.yml new file mode 100644 index 00000000000..af971a66f5a --- /dev/null +++ b/java/ql/lib/ext/io.netty.handler.codec.model.yml @@ -0,0 +1,22 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: sourceModel + data: + - ["io.netty.handler.codec", "ByteToMessageDecoder", True, "callDecode", "", "", "Parameter[1]", "remote", "manual"] + - ["io.netty.handler.codec", "ByteToMessageDecoder", True, "decode", "", "", "Parameter[1]", "remote", "manual"] + - ["io.netty.handler.codec", "ByteToMessageDecoder", True, "decodeLast", "", "", "Parameter[1]", "remote", "manual"] + - addsTo: + pack: codeql/java-all + extensible: summaryModel + data: + - ["io.netty.handler.codec.http", "HttpHeaders", True, "entries", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http", "HttpHeaders", True, "get", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http", "HttpHeaders", True, "getAll", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http", "HttpHeaders", True, "getAllAsString", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http", "HttpHeaders", True, "getAsString", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http", "HttpHeaders", True, "getHeader", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http", "HttpHeaders", True, "valueCharSequenceIterator", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http", "HttpHeaders", True, "valueStringIterator", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http", "HttpMessage", True, "headers", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http", "HttpMessage", True, "trailingHeaders", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] \ No newline at end of file From d257e32ebad6476324f6b4e5b6acbddb741d5535 Mon Sep 17 00:00:00 2001 From: Joe Farebrother <joefarebrother@github.com> Date: Fri, 27 Jan 2023 14:03:01 +0000 Subject: [PATCH 355/631] Separate different packages into different files --- .../lib/ext/io.netty.handler.codec.http.model.yml | 10 ++++++++++ java/ql/lib/ext/io.netty.handler.codec.model.yml | 14 -------------- 2 files changed, 10 insertions(+), 14 deletions(-) diff --git a/java/ql/lib/ext/io.netty.handler.codec.http.model.yml b/java/ql/lib/ext/io.netty.handler.codec.http.model.yml index 6a4b0e7922e..3c2a3e4097e 100644 --- a/java/ql/lib/ext/io.netty.handler.codec.http.model.yml +++ b/java/ql/lib/ext/io.netty.handler.codec.http.model.yml @@ -10,3 +10,13 @@ extensions: extensible: summaryModel data: - ["io.netty.handler.codec.http", "QueryStringEncoder", True, "QueryStringEncoder", "(String)", "", "Argument[0]", "Argument[this]", "taint", "ai-generated"] + - ["io.netty.handler.codec.http", "HttpHeaders", True, "entries", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http", "HttpHeaders", True, "get", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http", "HttpHeaders", True, "getAll", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http", "HttpHeaders", True, "getAllAsString", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http", "HttpHeaders", True, "getAsString", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http", "HttpHeaders", True, "getHeader", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http", "HttpHeaders", True, "valueCharSequenceIterator", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http", "HttpHeaders", True, "valueStringIterator", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http", "HttpMessage", True, "headers", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http", "HttpMessage", True, "trailingHeaders", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] diff --git a/java/ql/lib/ext/io.netty.handler.codec.model.yml b/java/ql/lib/ext/io.netty.handler.codec.model.yml index af971a66f5a..a197ba70ff4 100644 --- a/java/ql/lib/ext/io.netty.handler.codec.model.yml +++ b/java/ql/lib/ext/io.netty.handler.codec.model.yml @@ -6,17 +6,3 @@ extensions: - ["io.netty.handler.codec", "ByteToMessageDecoder", True, "callDecode", "", "", "Parameter[1]", "remote", "manual"] - ["io.netty.handler.codec", "ByteToMessageDecoder", True, "decode", "", "", "Parameter[1]", "remote", "manual"] - ["io.netty.handler.codec", "ByteToMessageDecoder", True, "decodeLast", "", "", "Parameter[1]", "remote", "manual"] - - addsTo: - pack: codeql/java-all - extensible: summaryModel - data: - - ["io.netty.handler.codec.http", "HttpHeaders", True, "entries", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.handler.codec.http", "HttpHeaders", True, "get", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.handler.codec.http", "HttpHeaders", True, "getAll", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.handler.codec.http", "HttpHeaders", True, "getAllAsString", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.handler.codec.http", "HttpHeaders", True, "getAsString", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.handler.codec.http", "HttpHeaders", True, "getHeader", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.handler.codec.http", "HttpHeaders", True, "valueCharSequenceIterator", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.handler.codec.http", "HttpHeaders", True, "valueStringIterator", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.handler.codec.http", "HttpMessage", True, "headers", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.handler.codec.http", "HttpMessage", True, "trailingHeaders", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] \ No newline at end of file From f3882f92db174cf70f52138f795ad1ab6e66a019 Mon Sep 17 00:00:00 2001 From: Joe Farebrother <joefarebrother@github.com> Date: Tue, 31 Jan 2023 15:05:43 +0000 Subject: [PATCH 356/631] Add more netty modelling, mostly around http requests --- java/ql/lib/ext/io.netty.channel.model.yml | 1 + .../io.netty.handler.codec.base64.model.yml | 8 ++++++ ....netty.handler.codec.http.cookie.model.yml | 11 ++++++++ .../ext/io.netty.handler.codec.http.model.yml | 25 ++++++++++++++++- ...tty.handler.codec.http.multipart.model.yml | 28 +++++++++++++++++++ .../lib/ext/io.netty.handler.codec.model.yml | 8 ++++++ 6 files changed, 80 insertions(+), 1 deletion(-) create mode 100644 java/ql/lib/ext/io.netty.handler.codec.base64.model.yml create mode 100644 java/ql/lib/ext/io.netty.handler.codec.http.cookie.model.yml diff --git a/java/ql/lib/ext/io.netty.channel.model.yml b/java/ql/lib/ext/io.netty.channel.model.yml index 0e788e093b2..89bfd708360 100644 --- a/java/ql/lib/ext/io.netty.channel.model.yml +++ b/java/ql/lib/ext/io.netty.channel.model.yml @@ -17,3 +17,4 @@ extensions: extensible: sourceModel data: - ["io.netty.channel", "ChannelInboundHandler", True, "channelRead", "", "", "Parameter[1]", "remote", "manual"] + - ["io.netty.channel", "SimpleChannelInboundHandler", True, "channelRead0", "", "", "Parameter[1]", "remote", "manual"] diff --git a/java/ql/lib/ext/io.netty.handler.codec.base64.model.yml b/java/ql/lib/ext/io.netty.handler.codec.base64.model.yml new file mode 100644 index 00000000000..474ccbbed22 --- /dev/null +++ b/java/ql/lib/ext/io.netty.handler.codec.base64.model.yml @@ -0,0 +1,8 @@ + extensions: + - addsTo: + pack: codeql/java-all + extensible: summaryModel + data: + - ["io.netty.handler.codec.base64", "Base64", True, "decode", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.base64", "Base64", True, "encode", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + \ No newline at end of file diff --git a/java/ql/lib/ext/io.netty.handler.codec.http.cookie.model.yml b/java/ql/lib/ext/io.netty.handler.codec.http.cookie.model.yml new file mode 100644 index 00000000000..4128d83683b --- /dev/null +++ b/java/ql/lib/ext/io.netty.handler.codec.http.cookie.model.yml @@ -0,0 +1,11 @@ + extensions: + - addsTo: + pack: codeql/java-all + extensible: summaryModel + data: + - ["io.netty.handler.codec.http.cookie", "Cookie", True, "domain", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http.cookie", "Cookie", True, "name", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http.cookie", "Cookie", True, "path", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http.cookie", "Cookie", True, "value", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http.cookie", "ServerCookieDecoder", True, "decode", "(String)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http.cookie", "ServerCookieDecoder", True, "decodeAll", "(String)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] \ No newline at end of file diff --git a/java/ql/lib/ext/io.netty.handler.codec.http.model.yml b/java/ql/lib/ext/io.netty.handler.codec.http.model.yml index 3c2a3e4097e..e4eaaf38f90 100644 --- a/java/ql/lib/ext/io.netty.handler.codec.http.model.yml +++ b/java/ql/lib/ext/io.netty.handler.codec.http.model.yml @@ -10,13 +10,36 @@ extensions: extensible: summaryModel data: - ["io.netty.handler.codec.http", "QueryStringEncoder", True, "QueryStringEncoder", "(String)", "", "Argument[0]", "Argument[this]", "taint", "ai-generated"] + - ["io.netty.handler.codec.http", "HttpHeaders", True, "copy", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - ["io.netty.handler.codec.http", "HttpHeaders", True, "entries", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - ["io.netty.handler.codec.http", "HttpHeaders", True, "get", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http", "HttpHeaders", True, "get", "", "", "Argument[1]", "ReturnValue", "value", "manual"] - ["io.netty.handler.codec.http", "HttpHeaders", True, "getAll", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - ["io.netty.handler.codec.http", "HttpHeaders", True, "getAllAsString", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - ["io.netty.handler.codec.http", "HttpHeaders", True, "getAsString", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.handler.codec.http", "HttpHeaders", True, "getHeader", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http", "HttpHeaders", True, "getHeader", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http", "HttpHeaders", True, "getHeader", "", "", "Argument[2]", "ReturnValue", "value", "manual"] + - ["io.netty.handler.codec.http", "HttpHeaders", True, "getHost", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http", "HttpHeaders", True, "getHost", "", "", "Argument[2]", "ReturnValue", "value", "manual"] + - ["io.netty.handler.codec.http", "HttpHeaders", True, "iteratorAsString", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http", "HttpHeaders", True, "iteratorCharSequence", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http", "HttpHeaders", True, "names", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http", "HttpHeaders", True, "newEntity", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] - ["io.netty.handler.codec.http", "HttpHeaders", True, "valueCharSequenceIterator", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - ["io.netty.handler.codec.http", "HttpHeaders", True, "valueStringIterator", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http", "HttpHeaders", True, "toString", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - ["io.netty.handler.codec.http", "HttpMessage", True, "headers", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - ["io.netty.handler.codec.http", "HttpMessage", True, "trailingHeaders", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http", "LastHttpMessage", True, "trailingHeaders", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http", "HttpRequest", True, "getUri", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http", "HttpRequest", True, "uri", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http", "QueryStringDecoder", True, "QueryStringDecoder", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http", "QueryStringDecoder", True, "decodeComponent", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http", "QueryStringDecoder", True, "parameters", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http", "QueryStringDecoder", True, "path", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http", "QueryStringDecoder", True, "rawPath", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http", "QueryStringDecoder", True, "rawQuery", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http", "QueryStringDecoder", True, "toString", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http", "QueryStringDecoder", True, "uri", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + + diff --git a/java/ql/lib/ext/io.netty.handler.codec.http.multipart.model.yml b/java/ql/lib/ext/io.netty.handler.codec.http.multipart.model.yml index 5f0dceb85a0..5e19ad93861 100644 --- a/java/ql/lib/ext/io.netty.handler.codec.http.multipart.model.yml +++ b/java/ql/lib/ext/io.netty.handler.codec.http.multipart.model.yml @@ -4,3 +4,31 @@ extensions: extensible: sinkModel data: - ["io.netty.handler.codec.http.multipart", "HttpPostRequestEncoder", True, "addBodyFileUpload", "(String,File,String,boolean)", "", "Argument[1]", "read-file", "ai-generated"] + - addsTo: + pack: codeql/java-all + extensible: summaryModel + data: + - ["io.netty.handler.codec.http.multipart", "InterfaceHttpPostRequestDecoder", True, "getBodyHttpData", "(String)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http.multipart", "InterfaceHttpPostRequestDecoder", True, "getBodyHttpDatas", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http.multipart", "InterfaceHttpPostRequestDecoder", True, "getBodyHttpDatas", "(String)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http.multipart", "InterfaceHttpPostRequestDecoder", True, "next", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http.multipart", "InterfaceHttpPostRequestDecoder", True, "offer", "(HttpContent)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["io.netty.handler.codec.http.multipart", "HttpPostRequestDecoder", True, "HttpPostRequestDecoder", "(HttpRequest)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http.multipart", "HttpPostRequestDecoder", True, "HttpPostRequestDecoder", "(HttpDataFactory,HttpRequest)", "", "Argument[1]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http.multipart", "HttpPostRequestDecoder", True, "HttpPostRequestDecoder", "(HttpDataFactory,HttpRequest,Charset)", "", "Argument[1]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http.multipart", "HttpPostStandardRequestDecoder", True, "HttpPostStandardRequestDecoder", "(HttpRequest)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http.multipart", "HttpPostStandardRequestDecoder", True, "HttpPostStandardRequestDecoder", "(HttpDataFactory,HttpRequest)", "", "Argument[1]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http.multipart", "HttpPostStandardRequestDecoder", True, "HttpPostStandardRequestDecoder", "(HttpDataFactory,HttpRequest,Charset)", "", "Argument[1]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http.multipart", "HttpPostMultipartRequestDecoder", True, "HttpPostMultipartRequestDecoder", "(HttpRequest)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http.multipart", "HttpPostMultipartRequestDecoder", True, "HttpPostMultipartRequestDecoder", "(HttpDataFactory,HttpRequest)", "", "Argument[1]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http.multipart", "HttpPostMultipartRequestDecoder", True, "HttpPostMultipartRequestDecoder", "(HttpDataFactory,HttpRequest,Charset)", "", "Argument[1]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http.multipart", "InterfaceHttpData", True, "getName", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http.multipart", "HttpData", True, "get", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http.multipart", "HttpData", True, "getByteBuf", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http.multipart", "HttpData", True, "getChunk", "(int)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http.multipart", "HttpData", True, "getString", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http.multipart", "HttpData", True, "getString", "(Charset)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http.multipart", "Attribute", True, "getValue", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http.multipart", "FileUpload", True, "getContentTransferEncoding", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http.multipart", "FileUpload", True, "getContentType", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http.multipart", "FileUpload", True, "getFilename", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] diff --git a/java/ql/lib/ext/io.netty.handler.codec.model.yml b/java/ql/lib/ext/io.netty.handler.codec.model.yml index a197ba70ff4..4973e3a8376 100644 --- a/java/ql/lib/ext/io.netty.handler.codec.model.yml +++ b/java/ql/lib/ext/io.netty.handler.codec.model.yml @@ -6,3 +6,11 @@ extensions: - ["io.netty.handler.codec", "ByteToMessageDecoder", True, "callDecode", "", "", "Parameter[1]", "remote", "manual"] - ["io.netty.handler.codec", "ByteToMessageDecoder", True, "decode", "", "", "Parameter[1]", "remote", "manual"] - ["io.netty.handler.codec", "ByteToMessageDecoder", True, "decodeLast", "", "", "Parameter[1]", "remote", "manual"] + - ["io.netty.handler.codec", "ByteToMessageCodec", True, "decode", "", "", "Parameter[1]", "remote", "manual"] + - ["io.netty.handler.codec", "ByteToMessageCodec", True, "decodeLast", "", "", "Parameter[1]", "remote", "manual"] + - addsTo: + pack: codeql/java-all + extensible: summaryModel + data: + - ["io.netty.handler.codec, "HeadersUtils", False, "iteratorAsString", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec, "HeadersUtils", False, "toString", "", "", "Argument[1]", "ReturnValue", "taint", "manual"] From 24c59bb7e58d9382bb67acc9211c382ff5752a63 Mon Sep 17 00:00:00 2001 From: Joe Farebrother <joefarebrother@github.com> Date: Tue, 31 Jan 2023 16:09:57 +0000 Subject: [PATCH 357/631] Formatting fixes --- .../io.netty.handler.codec.base64.model.yml | 14 ++++++------ ....netty.handler.codec.http.cookie.model.yml | 22 +++++++++---------- .../lib/ext/io.netty.handler.codec.model.yml | 4 ++-- 3 files changed, 20 insertions(+), 20 deletions(-) diff --git a/java/ql/lib/ext/io.netty.handler.codec.base64.model.yml b/java/ql/lib/ext/io.netty.handler.codec.base64.model.yml index 474ccbbed22..01ebb7bbe54 100644 --- a/java/ql/lib/ext/io.netty.handler.codec.base64.model.yml +++ b/java/ql/lib/ext/io.netty.handler.codec.base64.model.yml @@ -1,8 +1,8 @@ - extensions: - - addsTo: - pack: codeql/java-all - extensible: summaryModel - data: - - ["io.netty.handler.codec.base64", "Base64", True, "decode", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] - - ["io.netty.handler.codec.base64", "Base64", True, "encode", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] +extensions: +- addsTo: + pack: codeql/java-all + extensible: summaryModel + data: + - ["io.netty.handler.codec.base64", "Base64", True, "decode", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.base64", "Base64", True, "encode", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] \ No newline at end of file diff --git a/java/ql/lib/ext/io.netty.handler.codec.http.cookie.model.yml b/java/ql/lib/ext/io.netty.handler.codec.http.cookie.model.yml index 4128d83683b..42a93a21638 100644 --- a/java/ql/lib/ext/io.netty.handler.codec.http.cookie.model.yml +++ b/java/ql/lib/ext/io.netty.handler.codec.http.cookie.model.yml @@ -1,11 +1,11 @@ - extensions: - - addsTo: - pack: codeql/java-all - extensible: summaryModel - data: - - ["io.netty.handler.codec.http.cookie", "Cookie", True, "domain", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.handler.codec.http.cookie", "Cookie", True, "name", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.handler.codec.http.cookie", "Cookie", True, "path", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.handler.codec.http.cookie", "Cookie", True, "value", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.handler.codec.http.cookie", "ServerCookieDecoder", True, "decode", "(String)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.handler.codec.http.cookie", "ServerCookieDecoder", True, "decodeAll", "(String)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] \ No newline at end of file +extensions: +- addsTo: + pack: codeql/java-all + extensible: summaryModel + data: + - ["io.netty.handler.codec.http.cookie", "Cookie", True, "domain", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http.cookie", "Cookie", True, "name", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http.cookie", "Cookie", True, "path", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http.cookie", "Cookie", True, "value", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http.cookie", "ServerCookieDecoder", True, "decode", "(String)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http.cookie", "ServerCookieDecoder", True, "decodeAll", "(String)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] \ No newline at end of file diff --git a/java/ql/lib/ext/io.netty.handler.codec.model.yml b/java/ql/lib/ext/io.netty.handler.codec.model.yml index 4973e3a8376..53b4409bc91 100644 --- a/java/ql/lib/ext/io.netty.handler.codec.model.yml +++ b/java/ql/lib/ext/io.netty.handler.codec.model.yml @@ -12,5 +12,5 @@ extensions: pack: codeql/java-all extensible: summaryModel data: - - ["io.netty.handler.codec, "HeadersUtils", False, "iteratorAsString", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] - - ["io.netty.handler.codec, "HeadersUtils", False, "toString", "", "", "Argument[1]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec", "HeadersUtils", False, "iteratorAsString", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec", "HeadersUtils", False, "toString", "", "", "Argument[1]", "ReturnValue", "taint", "manual"] From d8da4fb1f4447386b4df28a295fb10dd1ec16f6b Mon Sep 17 00:00:00 2001 From: Joe Farebrother <joefarebrother@github.com> Date: Tue, 31 Jan 2023 16:18:30 +0000 Subject: [PATCH 358/631] Add websocket models --- .../ext/io.netty.handler.codec.http.websocketx.model.yml | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 java/ql/lib/ext/io.netty.handler.codec.http.websocketx.model.yml diff --git a/java/ql/lib/ext/io.netty.handler.codec.http.websocketx.model.yml b/java/ql/lib/ext/io.netty.handler.codec.http.websocketx.model.yml new file mode 100644 index 00000000000..86d4c3c8240 --- /dev/null +++ b/java/ql/lib/ext/io.netty.handler.codec.http.websocketx.model.yml @@ -0,0 +1,8 @@ +extensions: +- addsTo: + pack: codeql/java-all + extensible: summaryModel + data: + - ["io.netty.handler.codec.http.websocketx", "CloseWebSocketFrame", True, "reasonText", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http.websocketx", "ContinuationWebSocketFrame", True, "text", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http.websocketx", "TextWebSocketFrame", True, "text", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] \ No newline at end of file From 63f0823a9b4787b7bb9ebd69ff9a1941ff3cd329 Mon Sep 17 00:00:00 2001 From: Joe Farebrother <joefarebrother@github.com> Date: Mon, 6 Feb 2023 14:34:20 +0000 Subject: [PATCH 359/631] Add more sources and flow steps for http2 types --- .../io.netty.handler.codec.http2.model.yml | 22 +++++++++++++++++++ .../lib/ext/io.netty.handler.codec.model.yml | 17 ++++++++++++-- 2 files changed, 37 insertions(+), 2 deletions(-) create mode 100644 java/ql/lib/ext/io.netty.handler.codec.http2.model.yml diff --git a/java/ql/lib/ext/io.netty.handler.codec.http2.model.yml b/java/ql/lib/ext/io.netty.handler.codec.http2.model.yml new file mode 100644 index 00000000000..be23441df49 --- /dev/null +++ b/java/ql/lib/ext/io.netty.handler.codec.http2.model.yml @@ -0,0 +1,22 @@ +extensions: +- addsTo: + pack: codeql/java-all + extensible: sourceModel + data: + - ["io.netty.handler.codec.http2", "Http2FrameListener", True, "onDataRead", "", "", "Parameter[2]", "remote", "manual"] + - ["io.netty.handler.codec.http2", "Http2FrameListener", True, "onHeadersRead", "", "", "Parameter[2]", "remote", "manual"] + - ["io.netty.handler.codec.http2", "Http2FrameListener", True, "onPushPromiseRead", "", "", "Parameter[3]", "remote", "manual"] + - ["io.netty.handler.codec.http2", "Http2FrameListener", True, "onUnknownFrame", "", "", "Parameter[4]", "remote", "manual"] +- addsTo: + pack: codeql/java-all + extensible: summaryModel + data: + - ["io.netty.handler.codec.http2", "Http2Headers", True, "authority", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http2", "Http2Headers", True, "iterator", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http2", "Http2Headers", True, "method", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http2", "Http2Headers", True, "path", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http2", "Http2Headers", True, "scheme", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http2", "Http2Headers", True, "status", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http2", "Http2Headers", True, "valueIterator", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http2", "Http2HeadersFrame", True, "headers", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http2", "Http2PushPromiseFrame", True, "http2Headers", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] diff --git a/java/ql/lib/ext/io.netty.handler.codec.model.yml b/java/ql/lib/ext/io.netty.handler.codec.model.yml index 53b4409bc91..e48986ad339 100644 --- a/java/ql/lib/ext/io.netty.handler.codec.model.yml +++ b/java/ql/lib/ext/io.netty.handler.codec.model.yml @@ -12,5 +12,18 @@ extensions: pack: codeql/java-all extensible: summaryModel data: - - ["io.netty.handler.codec", "HeadersUtils", False, "iteratorAsString", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] - - ["io.netty.handler.codec", "HeadersUtils", False, "toString", "", "", "Argument[1]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec", "HeadersUtils", False, "getAsString", "(Headers,Object)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec", "HeadersUtils", False, "getAllAsString", "(Headers,Object)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec", "HeadersUtils", False, "namesAsString", "(Headers)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec", "HeadersUtils", False, "iteratorAsString", "(Iterable)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec", "HeadersUtils", False, "toString", "(Class,Iterator,int)", "", "Argument[1]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec", "Headers", True, "get", "(Object)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec", "Headers", True, "get", "(Object,Object)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec", "Headers", True, "get", "(Object,Object)", "", "Argument[1]", "ReturnValue", "value", "manual"] + - ["io.netty.handler.codec", "Headers", True, "getAll", "(Object)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec", "Headers", True, "getAllAndRemove", "(Object)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec", "Headers", True, "getAndRemove", "(Object)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec", "Headers", True, "getAndRemove", "(Object)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec", "Headers", True, "getAndRemove", "(Object,Object)", "", "Argument[1]", "ReturnValue", "value", "manual"] + - ["io.netty.handler.codec", "Headers", True, "iterator", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec", "Headers", True, "names", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] From 6ea0cfc2af674bff429becd3b629219ce3727f2f Mon Sep 17 00:00:00 2001 From: Joe Farebrother <joefarebrother@github.com> Date: Thu, 9 Feb 2023 15:17:57 +0000 Subject: [PATCH 360/631] Add more models for byte buffer handling and http2 utils --- java/ql/lib/ext/io.netty.buffer.model.yml | 61 ++++++++++++++++++- .../io.netty.handler.codec.http2.model.yml | 11 ++++ java/ql/lib/ext/io.netty.util.model.yml | 7 +++ 3 files changed, 77 insertions(+), 2 deletions(-) create mode 100644 java/ql/lib/ext/io.netty.util.model.yml diff --git a/java/ql/lib/ext/io.netty.buffer.model.yml b/java/ql/lib/ext/io.netty.buffer.model.yml index 2a842c67332..fd203e2afb0 100644 --- a/java/ql/lib/ext/io.netty.buffer.model.yml +++ b/java/ql/lib/ext/io.netty.buffer.model.yml @@ -3,17 +3,74 @@ extensions: pack: codeql/java-all extensible: summaryModel data: - - ["io.netty.buffer", "ByteBuf", True, "getBuffer", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.buffer", "ByteBufConvertible", True, "asByteBuf", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "array", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "asReadOnly", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "capacity", "(int)", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "copy", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "discardReadBytes", "()", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "discardSomeReadBytes", "()", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "duplicate", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "ensureWritable", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] - ["io.netty.buffer", "ByteBuf", True, "getByte", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - ["io.netty.buffer", "ByteBuf", True, "getBytes", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - ["io.netty.buffer", "ByteBuf", True, "getChar", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - ["io.netty.buffer", "ByteBuf", True, "getCharSequence", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "getCharSequence", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "markReaderIndex", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "markWriterIndex", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "nioBuffer", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "nioBuffers", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "order", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - ["io.netty.buffer", "ByteBuf", True, "readBytes", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - ["io.netty.buffer", "ByteBuf", True, "readChar", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - ["io.netty.buffer", "ByteBuf", True, "readCharSequence", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - ["io.netty.buffer", "ByteBuf", True, "readSlice", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "resetReaderIndex", "()", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "resetWriterIndex", "()", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "retainedDuplicate", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "retainedSlice", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "setBoolean", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "setByte", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "setBytes", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "setChar", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "setCharSequence", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "setDouble", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "setDoubleLE", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "setFloat", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "setFloatLE", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "setIndex", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "setInt", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "setIntLE", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "setLong", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "setLongLE", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "setMedium", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "setMediumLE", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "setShort", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "setShortLE", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "slice", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "toString", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "unwrap", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "writeByte", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "writeBytes", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "writeChar", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "writeCharSequence", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "writeDouble", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "writeDoubleLE", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "writeFloat", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "writeFloatLE", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "writeInt", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "writeIntLE", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "writeLong", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "writeLongLE", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "writeMedium", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "writeMediumLE", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "writeShort", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "writeShortLE", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.buffer", "ByteBufHolder", True, "copy", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - ["io.netty.buffer", "ByteBufHolder", True, "content", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.buffer", "ByteBufHolder", True, "duplicate", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.buffer", "ByteBufHolder", True, "retainedDuplicate", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "getBytes", "", "", "Argument[-1]", "Argument[1]", "taint", "manual"] - ["io.netty.buffer", "ByteBuf", True, "readBytes", "", "", "Argument[-1]", "Argument[0]", "taint", "manual"] - ["io.netty.buffer", "ByteBuf", True, "setByte", "", "", "Argument[1]", "Argument[-1]", "taint", "manual"] - ["io.netty.buffer", "ByteBuf", True, "setBytes", "", "", "Argument[1]", "Argument[-1]", "taint", "manual"] diff --git a/java/ql/lib/ext/io.netty.handler.codec.http2.model.yml b/java/ql/lib/ext/io.netty.handler.codec.http2.model.yml index be23441df49..5ded6c38399 100644 --- a/java/ql/lib/ext/io.netty.handler.codec.http2.model.yml +++ b/java/ql/lib/ext/io.netty.handler.codec.http2.model.yml @@ -20,3 +20,14 @@ extensions: - ["io.netty.handler.codec.http2", "Http2Headers", True, "valueIterator", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - ["io.netty.handler.codec.http2", "Http2HeadersFrame", True, "headers", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - ["io.netty.handler.codec.http2", "Http2PushPromiseFrame", True, "http2Headers", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http2", "Http2ConversionUtil", False, "addHttp2ToHttpHeaders", "", "", "Argument[1]", "Argument[2]", "taint", "manual"] + - ["io.netty.handler.codec.http2", "Http2ConversionUtil", False, "toFullHttpRequest", "", "", "Argument[1]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http2", "Http2ConversionUtil", False, "toFullHttpRequest", "", "", "Argument[2]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http2", "Http2ConversionUtil", False, "toFullHttpResponse", "", "", "Argument[1]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http2", "Http2ConversionUtil", False, "toFullHttpResponse", "", "", "Argument[2]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http2", "Http2ConversionUtil", False, "toHttp2Headers", "(HttpHeaders,boolean)", "", "Argument[1]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http2", "Http2ConversionUtil", False, "toHttp2Headers", "(HttpHeaders,Http2Headers)", "", "Argument[1]", "Argument[2]", "taint", "manual"] + - ["io.netty.handler.codec.http2", "Http2ConversionUtil", False, "toHttpRequest", "", "", "Argument[1]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http2", "Http2ConversionUtil", False, "toHttpResponse", "", "", "Argument[1]", "ReturnValue", "taint", "manual"] + + diff --git a/java/ql/lib/ext/io.netty.util.model.yml b/java/ql/lib/ext/io.netty.util.model.yml new file mode 100644 index 00000000000..6e2e9194454 --- /dev/null +++ b/java/ql/lib/ext/io.netty.util.model.yml @@ -0,0 +1,7 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: summaryModel + data: + - ["io.netty.util", "ReferenceCounted", True, "retain", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["io.netty.util", "ReferenceCounted", True, "touch", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] \ No newline at end of file From 9a33c2a6110d43227d9c36eadba4ad1466746a10 Mon Sep 17 00:00:00 2001 From: Joe Farebrother <joefarebrother@github.com> Date: Mon, 13 Feb 2023 16:02:22 +0000 Subject: [PATCH 361/631] Generate netty stubs --- .../io/netty/buffer/AbstractByteBuf.java | 199 +++++++++++++++ .../AbstractReferenceCountedByteBuf.java | 22 ++ .../netty-4.1.x/io/netty/buffer/ByteBuf.java | 227 ++++++++++++++++-- .../io/netty/buffer/ByteBufAllocator.java | 31 +++ .../io/netty/buffer/ByteBufConvertible.java | 10 + .../io/netty/buffer/CompositeByteBuf.java | 158 ++++++++++++ .../io/netty/buffer/SwappedByteBuf.java | 206 ++++++++++++++++ .../netty-4.1.x/io/netty/channel/Channel.java | 58 +++++ .../io/netty/channel/ChannelConfig.java | 40 +++ .../io/netty/channel/ChannelFuture.java | 20 ++ .../io/netty/channel/ChannelHandler.java | 12 + .../netty/channel/ChannelHandlerAdapter.java | 16 ++ .../netty/channel/ChannelHandlerContext.java | 38 +++ .../io/netty/channel/ChannelId.java | 11 + .../netty/channel/ChannelInboundHandler.java | 19 ++ .../channel/ChannelInboundHandlerAdapter.java | 21 ++ .../netty/channel/ChannelInboundInvoker.java | 17 ++ .../io/netty/channel/ChannelMetadata.java | 13 + .../io/netty/channel/ChannelOption.java | 53 ++++ .../netty/channel/ChannelOutboundBuffer.java | 37 +++ .../netty/channel/ChannelOutboundInvoker.java | 35 +++ .../io/netty/channel/ChannelPipeline.java | 58 +++++ .../channel/ChannelProgressiveFuture.java | 19 ++ .../channel/ChannelProgressivePromise.java | 25 ++ .../io/netty/channel/ChannelPromise.java | 26 ++ .../io/netty/channel/EventLoop.java | 11 + .../io/netty/channel/EventLoopGroup.java | 17 ++ .../netty/channel/MessageSizeEstimator.java | 13 + .../netty/channel/RecvByteBufAllocator.java | 25 ++ .../netty/channel/WriteBufferWaterMark.java | 14 ++ .../io/netty/util/AbstractConstant.java | 17 ++ .../netty-4.1.x/io/netty/util/Attribute.java | 17 ++ .../io/netty/util/AttributeKey.java | 14 ++ .../io/netty/util/AttributeMap.java | 12 + .../io/netty/util/ByteProcessor.java | 22 ++ .../netty-4.1.x/io/netty/util/Constant.java | 10 + .../io/netty/util/ReferenceCounted.java | 15 ++ .../util/concurrent/OrderedEventExecutor.java | 9 + 38 files changed, 1550 insertions(+), 17 deletions(-) create mode 100644 java/ql/test/stubs/netty-4.1.x/io/netty/buffer/AbstractByteBuf.java create mode 100644 java/ql/test/stubs/netty-4.1.x/io/netty/buffer/AbstractReferenceCountedByteBuf.java create mode 100644 java/ql/test/stubs/netty-4.1.x/io/netty/buffer/ByteBufAllocator.java create mode 100644 java/ql/test/stubs/netty-4.1.x/io/netty/buffer/ByteBufConvertible.java create mode 100644 java/ql/test/stubs/netty-4.1.x/io/netty/buffer/CompositeByteBuf.java create mode 100644 java/ql/test/stubs/netty-4.1.x/io/netty/buffer/SwappedByteBuf.java create mode 100644 java/ql/test/stubs/netty-4.1.x/io/netty/channel/Channel.java create mode 100644 java/ql/test/stubs/netty-4.1.x/io/netty/channel/ChannelConfig.java create mode 100644 java/ql/test/stubs/netty-4.1.x/io/netty/channel/ChannelFuture.java create mode 100644 java/ql/test/stubs/netty-4.1.x/io/netty/channel/ChannelHandler.java create mode 100644 java/ql/test/stubs/netty-4.1.x/io/netty/channel/ChannelHandlerAdapter.java create mode 100644 java/ql/test/stubs/netty-4.1.x/io/netty/channel/ChannelHandlerContext.java create mode 100644 java/ql/test/stubs/netty-4.1.x/io/netty/channel/ChannelId.java create mode 100644 java/ql/test/stubs/netty-4.1.x/io/netty/channel/ChannelInboundHandler.java create mode 100644 java/ql/test/stubs/netty-4.1.x/io/netty/channel/ChannelInboundHandlerAdapter.java create mode 100644 java/ql/test/stubs/netty-4.1.x/io/netty/channel/ChannelInboundInvoker.java create mode 100644 java/ql/test/stubs/netty-4.1.x/io/netty/channel/ChannelMetadata.java create mode 100644 java/ql/test/stubs/netty-4.1.x/io/netty/channel/ChannelOption.java create mode 100644 java/ql/test/stubs/netty-4.1.x/io/netty/channel/ChannelOutboundBuffer.java create mode 100644 java/ql/test/stubs/netty-4.1.x/io/netty/channel/ChannelOutboundInvoker.java create mode 100644 java/ql/test/stubs/netty-4.1.x/io/netty/channel/ChannelPipeline.java create mode 100644 java/ql/test/stubs/netty-4.1.x/io/netty/channel/ChannelProgressiveFuture.java create mode 100644 java/ql/test/stubs/netty-4.1.x/io/netty/channel/ChannelProgressivePromise.java create mode 100644 java/ql/test/stubs/netty-4.1.x/io/netty/channel/ChannelPromise.java create mode 100644 java/ql/test/stubs/netty-4.1.x/io/netty/channel/EventLoop.java create mode 100644 java/ql/test/stubs/netty-4.1.x/io/netty/channel/EventLoopGroup.java create mode 100644 java/ql/test/stubs/netty-4.1.x/io/netty/channel/MessageSizeEstimator.java create mode 100644 java/ql/test/stubs/netty-4.1.x/io/netty/channel/RecvByteBufAllocator.java create mode 100644 java/ql/test/stubs/netty-4.1.x/io/netty/channel/WriteBufferWaterMark.java create mode 100644 java/ql/test/stubs/netty-4.1.x/io/netty/util/AbstractConstant.java create mode 100644 java/ql/test/stubs/netty-4.1.x/io/netty/util/Attribute.java create mode 100644 java/ql/test/stubs/netty-4.1.x/io/netty/util/AttributeKey.java create mode 100644 java/ql/test/stubs/netty-4.1.x/io/netty/util/AttributeMap.java create mode 100644 java/ql/test/stubs/netty-4.1.x/io/netty/util/ByteProcessor.java create mode 100644 java/ql/test/stubs/netty-4.1.x/io/netty/util/Constant.java create mode 100644 java/ql/test/stubs/netty-4.1.x/io/netty/util/ReferenceCounted.java create mode 100644 java/ql/test/stubs/netty-4.1.x/io/netty/util/concurrent/OrderedEventExecutor.java diff --git a/java/ql/test/stubs/netty-4.1.x/io/netty/buffer/AbstractByteBuf.java b/java/ql/test/stubs/netty-4.1.x/io/netty/buffer/AbstractByteBuf.java new file mode 100644 index 00000000000..368533e2f9b --- /dev/null +++ b/java/ql/test/stubs/netty-4.1.x/io/netty/buffer/AbstractByteBuf.java @@ -0,0 +1,199 @@ +// Generated automatically from io.netty.buffer.AbstractByteBuf for testing purposes + +package io.netty.buffer; + +import io.netty.buffer.ByteBuf; +import io.netty.buffer.SwappedByteBuf; +import io.netty.util.ByteProcessor; +import java.io.InputStream; +import java.io.OutputStream; +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.nio.channels.FileChannel; +import java.nio.channels.GatheringByteChannel; +import java.nio.channels.ScatteringByteChannel; +import java.nio.charset.Charset; + +abstract public class AbstractByteBuf extends ByteBuf +{ + protected AbstractByteBuf() {} + protected AbstractByteBuf(int p0){} + protected SwappedByteBuf newSwappedByteBuf(){ return null; } + protected abstract byte _getByte(int p0); + protected abstract int _getInt(int p0); + protected abstract int _getIntLE(int p0); + protected abstract int _getUnsignedMedium(int p0); + protected abstract int _getUnsignedMediumLE(int p0); + protected abstract long _getLong(int p0); + protected abstract long _getLongLE(int p0); + protected abstract short _getShort(int p0); + protected abstract short _getShortLE(int p0); + protected abstract void _setByte(int p0, int p1); + protected abstract void _setInt(int p0, int p1); + protected abstract void _setIntLE(int p0, int p1); + protected abstract void _setLong(int p0, long p1); + protected abstract void _setLongLE(int p0, long p1); + protected abstract void _setMedium(int p0, int p1); + protected abstract void _setMediumLE(int p0, int p1); + protected abstract void _setShort(int p0, int p1); + protected abstract void _setShortLE(int p0, int p1); + protected final void adjustMarkers(int p0){} + protected final void checkDstIndex(int p0, int p1, int p2){} + protected final void checkDstIndex(int p0, int p1, int p2, int p3){} + protected final void checkIndex(int p0){} + protected final void checkIndex(int p0, int p1){} + protected final void checkNewCapacity(int p0){} + protected final void checkReadableBytes(int p0){} + protected final void checkSrcIndex(int p0, int p1, int p2, int p3){} + protected final void ensureAccessible(){} + protected final void maxCapacity(int p0){} + protected final void trimIndicesToCapacity(int p0){} + public ByteBuf asReadOnly(){ return null; } + public ByteBuf clear(){ return null; } + public ByteBuf copy(){ return null; } + public ByteBuf discardReadBytes(){ return null; } + public ByteBuf discardSomeReadBytes(){ return null; } + public ByteBuf duplicate(){ return null; } + public ByteBuf ensureWritable(int p0){ return null; } + public ByteBuf getBytes(int p0, ByteBuf p1){ return null; } + public ByteBuf getBytes(int p0, ByteBuf p1, int p2){ return null; } + public ByteBuf getBytes(int p0, byte[] p1){ return null; } + public ByteBuf markReaderIndex(){ return null; } + public ByteBuf markWriterIndex(){ return null; } + public ByteBuf order(ByteOrder p0){ return null; } + public ByteBuf readBytes(ByteBuf p0){ return null; } + public ByteBuf readBytes(ByteBuf p0, int p1){ return null; } + public ByteBuf readBytes(ByteBuf p0, int p1, int p2){ return null; } + public ByteBuf readBytes(ByteBuffer p0){ return null; } + public ByteBuf readBytes(OutputStream p0, int p1){ return null; } + public ByteBuf readBytes(byte[] p0){ return null; } + public ByteBuf readBytes(byte[] p0, int p1, int p2){ return null; } + public ByteBuf readBytes(int p0){ return null; } + public ByteBuf readRetainedSlice(int p0){ return null; } + public ByteBuf readSlice(int p0){ return null; } + public ByteBuf readerIndex(int p0){ return null; } + public ByteBuf resetReaderIndex(){ return null; } + public ByteBuf resetWriterIndex(){ return null; } + public ByteBuf retainedDuplicate(){ return null; } + public ByteBuf retainedSlice(){ return null; } + public ByteBuf retainedSlice(int p0, int p1){ return null; } + public ByteBuf setBoolean(int p0, boolean p1){ return null; } + public ByteBuf setByte(int p0, int p1){ return null; } + public ByteBuf setBytes(int p0, ByteBuf p1){ return null; } + public ByteBuf setBytes(int p0, ByteBuf p1, int p2){ return null; } + public ByteBuf setBytes(int p0, byte[] p1){ return null; } + public ByteBuf setChar(int p0, int p1){ return null; } + public ByteBuf setDouble(int p0, double p1){ return null; } + public ByteBuf setFloat(int p0, float p1){ return null; } + public ByteBuf setIndex(int p0, int p1){ return null; } + public ByteBuf setInt(int p0, int p1){ return null; } + public ByteBuf setIntLE(int p0, int p1){ return null; } + public ByteBuf setLong(int p0, long p1){ return null; } + public ByteBuf setLongLE(int p0, long p1){ return null; } + public ByteBuf setMedium(int p0, int p1){ return null; } + public ByteBuf setMediumLE(int p0, int p1){ return null; } + public ByteBuf setShort(int p0, int p1){ return null; } + public ByteBuf setShortLE(int p0, int p1){ return null; } + public ByteBuf setZero(int p0, int p1){ return null; } + public ByteBuf skipBytes(int p0){ return null; } + public ByteBuf slice(){ return null; } + public ByteBuf slice(int p0, int p1){ return null; } + public ByteBuf writeBoolean(boolean p0){ return null; } + public ByteBuf writeByte(int p0){ return null; } + public ByteBuf writeBytes(ByteBuf p0){ return null; } + public ByteBuf writeBytes(ByteBuf p0, int p1){ return null; } + public ByteBuf writeBytes(ByteBuf p0, int p1, int p2){ return null; } + public ByteBuf writeBytes(ByteBuffer p0){ return null; } + public ByteBuf writeBytes(byte[] p0){ return null; } + public ByteBuf writeBytes(byte[] p0, int p1, int p2){ return null; } + public ByteBuf writeChar(int p0){ return null; } + public ByteBuf writeDouble(double p0){ return null; } + public ByteBuf writeFloat(float p0){ return null; } + public ByteBuf writeInt(int p0){ return null; } + public ByteBuf writeIntLE(int p0){ return null; } + public ByteBuf writeLong(long p0){ return null; } + public ByteBuf writeLongLE(long p0){ return null; } + public ByteBuf writeMedium(int p0){ return null; } + public ByteBuf writeMediumLE(int p0){ return null; } + public ByteBuf writeShort(int p0){ return null; } + public ByteBuf writeShortLE(int p0){ return null; } + public ByteBuf writeZero(int p0){ return null; } + public ByteBuf writerIndex(int p0){ return null; } + public ByteBuffer nioBuffer(){ return null; } + public ByteBuffer[] nioBuffers(){ return null; } + public CharSequence getCharSequence(int p0, int p1, Charset p2){ return null; } + public CharSequence readCharSequence(int p0, Charset p1){ return null; } + public String toString(){ return null; } + public String toString(Charset p0){ return null; } + public String toString(int p0, int p1, Charset p2){ return null; } + public boolean equals(Object p0){ return false; } + public boolean getBoolean(int p0){ return false; } + public boolean isReadOnly(){ return false; } + public boolean isReadable(){ return false; } + public boolean isReadable(int p0){ return false; } + public boolean isWritable(){ return false; } + public boolean isWritable(int p0){ return false; } + public boolean readBoolean(){ return false; } + public byte getByte(int p0){ return 0; } + public byte readByte(){ return 0; } + public char getChar(int p0){ return '0'; } + public char readChar(){ return '0'; } + public double getDouble(int p0){ return 0; } + public double readDouble(){ return 0; } + public float getFloat(int p0){ return 0; } + public float readFloat(){ return 0; } + public int bytesBefore(byte p0){ return 0; } + public int bytesBefore(int p0, byte p1){ return 0; } + public int bytesBefore(int p0, int p1, byte p2){ return 0; } + public int compareTo(ByteBuf p0){ return 0; } + public int ensureWritable(int p0, boolean p1){ return 0; } + public int forEachByte(ByteProcessor p0){ return 0; } + public int forEachByte(int p0, int p1, ByteProcessor p2){ return 0; } + public int forEachByteDesc(ByteProcessor p0){ return 0; } + public int forEachByteDesc(int p0, int p1, ByteProcessor p2){ return 0; } + public int getInt(int p0){ return 0; } + public int getIntLE(int p0){ return 0; } + public int getMedium(int p0){ return 0; } + public int getMediumLE(int p0){ return 0; } + public int getUnsignedMedium(int p0){ return 0; } + public int getUnsignedMediumLE(int p0){ return 0; } + public int getUnsignedShort(int p0){ return 0; } + public int getUnsignedShortLE(int p0){ return 0; } + public int hashCode(){ return 0; } + public int indexOf(int p0, int p1, byte p2){ return 0; } + public int maxCapacity(){ return 0; } + public int maxWritableBytes(){ return 0; } + public int readBytes(FileChannel p0, long p1, int p2){ return 0; } + public int readBytes(GatheringByteChannel p0, int p1){ return 0; } + public int readInt(){ return 0; } + public int readIntLE(){ return 0; } + public int readMedium(){ return 0; } + public int readMediumLE(){ return 0; } + public int readUnsignedMedium(){ return 0; } + public int readUnsignedMediumLE(){ return 0; } + public int readUnsignedShort(){ return 0; } + public int readUnsignedShortLE(){ return 0; } + public int readableBytes(){ return 0; } + public int readerIndex(){ return 0; } + public int setCharSequence(int p0, CharSequence p1, Charset p2){ return 0; } + public int writableBytes(){ return 0; } + public int writeBytes(FileChannel p0, long p1, int p2){ return 0; } + public int writeBytes(InputStream p0, int p1){ return 0; } + public int writeBytes(ScatteringByteChannel p0, int p1){ return 0; } + public int writeCharSequence(CharSequence p0, Charset p1){ return 0; } + public int writerIndex(){ return 0; } + public long getLong(int p0){ return 0; } + public long getLongLE(int p0){ return 0; } + public long getUnsignedInt(int p0){ return 0; } + public long getUnsignedIntLE(int p0){ return 0; } + public long readLong(){ return 0; } + public long readLongLE(){ return 0; } + public long readUnsignedInt(){ return 0; } + public long readUnsignedIntLE(){ return 0; } + public short getShort(int p0){ return 0; } + public short getShortLE(int p0){ return 0; } + public short getUnsignedByte(int p0){ return 0; } + public short readShort(){ return 0; } + public short readShortLE(){ return 0; } + public short readUnsignedByte(){ return 0; } +} diff --git a/java/ql/test/stubs/netty-4.1.x/io/netty/buffer/AbstractReferenceCountedByteBuf.java b/java/ql/test/stubs/netty-4.1.x/io/netty/buffer/AbstractReferenceCountedByteBuf.java new file mode 100644 index 00000000000..e5c1bf5be0a --- /dev/null +++ b/java/ql/test/stubs/netty-4.1.x/io/netty/buffer/AbstractReferenceCountedByteBuf.java @@ -0,0 +1,22 @@ +// Generated automatically from io.netty.buffer.AbstractReferenceCountedByteBuf for testing purposes + +package io.netty.buffer; + +import io.netty.buffer.AbstractByteBuf; +import io.netty.buffer.ByteBuf; + +abstract public class AbstractReferenceCountedByteBuf extends AbstractByteBuf +{ + protected AbstractReferenceCountedByteBuf() {} + protected AbstractReferenceCountedByteBuf(int p0){} + protected abstract void deallocate(); + protected final void resetRefCnt(){} + protected final void setRefCnt(int p0){} + public ByteBuf retain(){ return null; } + public ByteBuf retain(int p0){ return null; } + public ByteBuf touch(){ return null; } + public ByteBuf touch(Object p0){ return null; } + public boolean release(){ return false; } + public boolean release(int p0){ return false; } + public int refCnt(){ return 0; } +} diff --git a/java/ql/test/stubs/netty-4.1.x/io/netty/buffer/ByteBuf.java b/java/ql/test/stubs/netty-4.1.x/io/netty/buffer/ByteBuf.java index cb327fdf002..ab10df0c171 100644 --- a/java/ql/test/stubs/netty-4.1.x/io/netty/buffer/ByteBuf.java +++ b/java/ql/test/stubs/netty-4.1.x/io/netty/buffer/ByteBuf.java @@ -1,19 +1,212 @@ -/* - * Copyright 2012 The Netty Project - * - * The Netty Project licenses this file to you under the Apache License, - * version 2.0 (the "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at: - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - */ +// Generated automatically from io.netty.buffer.ByteBuf for testing purposes + package io.netty.buffer; -public abstract class ByteBuf implements Comparable<ByteBuf> { -} \ No newline at end of file +import io.netty.buffer.ByteBufAllocator; +import io.netty.buffer.ByteBufConvertible; +import io.netty.util.ByteProcessor; +import io.netty.util.ReferenceCounted; +import java.io.InputStream; +import java.io.OutputStream; +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.nio.channels.FileChannel; +import java.nio.channels.GatheringByteChannel; +import java.nio.channels.ScatteringByteChannel; +import java.nio.charset.Charset; + +abstract public class ByteBuf implements ByteBufConvertible, Comparable<ByteBuf>, ReferenceCounted +{ + public ByteBuf asByteBuf(){ return null; } + public ByteBuf setDoubleLE(int p0, double p1){ return null; } + public ByteBuf setFloatLE(int p0, float p1){ return null; } + public ByteBuf writeDoubleLE(double p0){ return null; } + public ByteBuf writeFloatLE(float p0){ return null; } + public ByteBuf(){} + public abstract ByteBuf asReadOnly(); + public abstract ByteBuf capacity(int p0); + public abstract ByteBuf clear(); + public abstract ByteBuf copy(); + public abstract ByteBuf copy(int p0, int p1); + public abstract ByteBuf discardReadBytes(); + public abstract ByteBuf discardSomeReadBytes(); + public abstract ByteBuf duplicate(); + public abstract ByteBuf ensureWritable(int p0); + public abstract ByteBuf getBytes(int p0, ByteBuf p1); + public abstract ByteBuf getBytes(int p0, ByteBuf p1, int p2); + public abstract ByteBuf getBytes(int p0, ByteBuf p1, int p2, int p3); + public abstract ByteBuf getBytes(int p0, ByteBuffer p1); + public abstract ByteBuf getBytes(int p0, OutputStream p1, int p2); + public abstract ByteBuf getBytes(int p0, byte[] p1); + public abstract ByteBuf getBytes(int p0, byte[] p1, int p2, int p3); + public abstract ByteBuf markReaderIndex(); + public abstract ByteBuf markWriterIndex(); + public abstract ByteBuf order(ByteOrder p0); + public abstract ByteBuf readBytes(ByteBuf p0); + public abstract ByteBuf readBytes(ByteBuf p0, int p1); + public abstract ByteBuf readBytes(ByteBuf p0, int p1, int p2); + public abstract ByteBuf readBytes(ByteBuffer p0); + public abstract ByteBuf readBytes(OutputStream p0, int p1); + public abstract ByteBuf readBytes(byte[] p0); + public abstract ByteBuf readBytes(byte[] p0, int p1, int p2); + public abstract ByteBuf readBytes(int p0); + public abstract ByteBuf readRetainedSlice(int p0); + public abstract ByteBuf readSlice(int p0); + public abstract ByteBuf readerIndex(int p0); + public abstract ByteBuf resetReaderIndex(); + public abstract ByteBuf resetWriterIndex(); + public abstract ByteBuf retain(); + public abstract ByteBuf retain(int p0); + public abstract ByteBuf retainedDuplicate(); + public abstract ByteBuf retainedSlice(); + public abstract ByteBuf retainedSlice(int p0, int p1); + public abstract ByteBuf setBoolean(int p0, boolean p1); + public abstract ByteBuf setByte(int p0, int p1); + public abstract ByteBuf setBytes(int p0, ByteBuf p1); + public abstract ByteBuf setBytes(int p0, ByteBuf p1, int p2); + public abstract ByteBuf setBytes(int p0, ByteBuf p1, int p2, int p3); + public abstract ByteBuf setBytes(int p0, ByteBuffer p1); + public abstract ByteBuf setBytes(int p0, byte[] p1); + public abstract ByteBuf setBytes(int p0, byte[] p1, int p2, int p3); + public abstract ByteBuf setChar(int p0, int p1); + public abstract ByteBuf setDouble(int p0, double p1); + public abstract ByteBuf setFloat(int p0, float p1); + public abstract ByteBuf setIndex(int p0, int p1); + public abstract ByteBuf setInt(int p0, int p1); + public abstract ByteBuf setIntLE(int p0, int p1); + public abstract ByteBuf setLong(int p0, long p1); + public abstract ByteBuf setLongLE(int p0, long p1); + public abstract ByteBuf setMedium(int p0, int p1); + public abstract ByteBuf setMediumLE(int p0, int p1); + public abstract ByteBuf setShort(int p0, int p1); + public abstract ByteBuf setShortLE(int p0, int p1); + public abstract ByteBuf setZero(int p0, int p1); + public abstract ByteBuf skipBytes(int p0); + public abstract ByteBuf slice(); + public abstract ByteBuf slice(int p0, int p1); + public abstract ByteBuf touch(); + public abstract ByteBuf touch(Object p0); + public abstract ByteBuf unwrap(); + public abstract ByteBuf writeBoolean(boolean p0); + public abstract ByteBuf writeByte(int p0); + public abstract ByteBuf writeBytes(ByteBuf p0); + public abstract ByteBuf writeBytes(ByteBuf p0, int p1); + public abstract ByteBuf writeBytes(ByteBuf p0, int p1, int p2); + public abstract ByteBuf writeBytes(ByteBuffer p0); + public abstract ByteBuf writeBytes(byte[] p0); + public abstract ByteBuf writeBytes(byte[] p0, int p1, int p2); + public abstract ByteBuf writeChar(int p0); + public abstract ByteBuf writeDouble(double p0); + public abstract ByteBuf writeFloat(float p0); + public abstract ByteBuf writeInt(int p0); + public abstract ByteBuf writeIntLE(int p0); + public abstract ByteBuf writeLong(long p0); + public abstract ByteBuf writeLongLE(long p0); + public abstract ByteBuf writeMedium(int p0); + public abstract ByteBuf writeMediumLE(int p0); + public abstract ByteBuf writeShort(int p0); + public abstract ByteBuf writeShortLE(int p0); + public abstract ByteBuf writeZero(int p0); + public abstract ByteBuf writerIndex(int p0); + public abstract ByteBufAllocator alloc(); + public abstract ByteBuffer internalNioBuffer(int p0, int p1); + public abstract ByteBuffer nioBuffer(); + public abstract ByteBuffer nioBuffer(int p0, int p1); + public abstract ByteBuffer[] nioBuffers(); + public abstract ByteBuffer[] nioBuffers(int p0, int p1); + public abstract ByteOrder order(); + public abstract CharSequence getCharSequence(int p0, int p1, Charset p2); + public abstract CharSequence readCharSequence(int p0, Charset p1); + public abstract String toString(); + public abstract String toString(Charset p0); + public abstract String toString(int p0, int p1, Charset p2); + public abstract boolean equals(Object p0); + public abstract boolean getBoolean(int p0); + public abstract boolean hasArray(); + public abstract boolean hasMemoryAddress(); + public abstract boolean isDirect(); + public abstract boolean isReadOnly(); + public abstract boolean isReadable(); + public abstract boolean isReadable(int p0); + public abstract boolean isWritable(); + public abstract boolean isWritable(int p0); + public abstract boolean readBoolean(); + public abstract byte getByte(int p0); + public abstract byte readByte(); + public abstract byte[] array(); + public abstract char getChar(int p0); + public abstract char readChar(); + public abstract double getDouble(int p0); + public abstract double readDouble(); + public abstract float getFloat(int p0); + public abstract float readFloat(); + public abstract int arrayOffset(); + public abstract int bytesBefore(byte p0); + public abstract int bytesBefore(int p0, byte p1); + public abstract int bytesBefore(int p0, int p1, byte p2); + public abstract int capacity(); + public abstract int compareTo(ByteBuf p0); + public abstract int ensureWritable(int p0, boolean p1); + public abstract int forEachByte(ByteProcessor p0); + public abstract int forEachByte(int p0, int p1, ByteProcessor p2); + public abstract int forEachByteDesc(ByteProcessor p0); + public abstract int forEachByteDesc(int p0, int p1, ByteProcessor p2); + public abstract int getBytes(int p0, FileChannel p1, long p2, int p3); + public abstract int getBytes(int p0, GatheringByteChannel p1, int p2); + public abstract int getInt(int p0); + public abstract int getIntLE(int p0); + public abstract int getMedium(int p0); + public abstract int getMediumLE(int p0); + public abstract int getUnsignedMedium(int p0); + public abstract int getUnsignedMediumLE(int p0); + public abstract int getUnsignedShort(int p0); + public abstract int getUnsignedShortLE(int p0); + public abstract int hashCode(); + public abstract int indexOf(int p0, int p1, byte p2); + public abstract int maxCapacity(); + public abstract int maxWritableBytes(); + public abstract int nioBufferCount(); + public abstract int readBytes(FileChannel p0, long p1, int p2); + public abstract int readBytes(GatheringByteChannel p0, int p1); + public abstract int readInt(); + public abstract int readIntLE(); + public abstract int readMedium(); + public abstract int readMediumLE(); + public abstract int readUnsignedMedium(); + public abstract int readUnsignedMediumLE(); + public abstract int readUnsignedShort(); + public abstract int readUnsignedShortLE(); + public abstract int readableBytes(); + public abstract int readerIndex(); + public abstract int setBytes(int p0, FileChannel p1, long p2, int p3); + public abstract int setBytes(int p0, InputStream p1, int p2); + public abstract int setBytes(int p0, ScatteringByteChannel p1, int p2); + public abstract int setCharSequence(int p0, CharSequence p1, Charset p2); + public abstract int writableBytes(); + public abstract int writeBytes(FileChannel p0, long p1, int p2); + public abstract int writeBytes(InputStream p0, int p1); + public abstract int writeBytes(ScatteringByteChannel p0, int p1); + public abstract int writeCharSequence(CharSequence p0, Charset p1); + public abstract int writerIndex(); + public abstract long getLong(int p0); + public abstract long getLongLE(int p0); + public abstract long getUnsignedInt(int p0); + public abstract long getUnsignedIntLE(int p0); + public abstract long memoryAddress(); + public abstract long readLong(); + public abstract long readLongLE(); + public abstract long readUnsignedInt(); + public abstract long readUnsignedIntLE(); + public abstract short getShort(int p0); + public abstract short getShortLE(int p0); + public abstract short getUnsignedByte(int p0); + public abstract short readShort(); + public abstract short readShortLE(); + public abstract short readUnsignedByte(); + public boolean isContiguous(){ return false; } + public double getDoubleLE(int p0){ return 0; } + public double readDoubleLE(){ return 0; } + public float getFloatLE(int p0){ return 0; } + public float readFloatLE(){ return 0; } + public int maxFastWritableBytes(){ return 0; } +} diff --git a/java/ql/test/stubs/netty-4.1.x/io/netty/buffer/ByteBufAllocator.java b/java/ql/test/stubs/netty-4.1.x/io/netty/buffer/ByteBufAllocator.java new file mode 100644 index 00000000000..490f4364b8d --- /dev/null +++ b/java/ql/test/stubs/netty-4.1.x/io/netty/buffer/ByteBufAllocator.java @@ -0,0 +1,31 @@ +// Generated automatically from io.netty.buffer.ByteBufAllocator for testing purposes + +package io.netty.buffer; + +import io.netty.buffer.ByteBuf; +import io.netty.buffer.CompositeByteBuf; + +public interface ByteBufAllocator +{ + ByteBuf buffer(); + ByteBuf buffer(int p0); + ByteBuf buffer(int p0, int p1); + ByteBuf directBuffer(); + ByteBuf directBuffer(int p0); + ByteBuf directBuffer(int p0, int p1); + ByteBuf heapBuffer(); + ByteBuf heapBuffer(int p0); + ByteBuf heapBuffer(int p0, int p1); + ByteBuf ioBuffer(); + ByteBuf ioBuffer(int p0); + ByteBuf ioBuffer(int p0, int p1); + CompositeByteBuf compositeBuffer(); + CompositeByteBuf compositeBuffer(int p0); + CompositeByteBuf compositeDirectBuffer(); + CompositeByteBuf compositeDirectBuffer(int p0); + CompositeByteBuf compositeHeapBuffer(); + CompositeByteBuf compositeHeapBuffer(int p0); + boolean isDirectBufferPooled(); + int calculateNewCapacity(int p0, int p1); + static ByteBufAllocator DEFAULT = null; +} diff --git a/java/ql/test/stubs/netty-4.1.x/io/netty/buffer/ByteBufConvertible.java b/java/ql/test/stubs/netty-4.1.x/io/netty/buffer/ByteBufConvertible.java new file mode 100644 index 00000000000..145e4f72565 --- /dev/null +++ b/java/ql/test/stubs/netty-4.1.x/io/netty/buffer/ByteBufConvertible.java @@ -0,0 +1,10 @@ +// Generated automatically from io.netty.buffer.ByteBufConvertible for testing purposes + +package io.netty.buffer; + +import io.netty.buffer.ByteBuf; + +public interface ByteBufConvertible +{ + ByteBuf asByteBuf(); +} diff --git a/java/ql/test/stubs/netty-4.1.x/io/netty/buffer/CompositeByteBuf.java b/java/ql/test/stubs/netty-4.1.x/io/netty/buffer/CompositeByteBuf.java new file mode 100644 index 00000000000..87d0f0c4190 --- /dev/null +++ b/java/ql/test/stubs/netty-4.1.x/io/netty/buffer/CompositeByteBuf.java @@ -0,0 +1,158 @@ +// Generated automatically from io.netty.buffer.CompositeByteBuf for testing purposes + +package io.netty.buffer; + +import io.netty.buffer.AbstractReferenceCountedByteBuf; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.ByteBufAllocator; +import io.netty.util.ByteProcessor; +import java.io.InputStream; +import java.io.OutputStream; +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.nio.channels.FileChannel; +import java.nio.channels.GatheringByteChannel; +import java.nio.channels.ScatteringByteChannel; +import java.util.Iterator; +import java.util.List; + +public class CompositeByteBuf extends AbstractReferenceCountedByteBuf implements Iterable<ByteBuf> +{ + protected CompositeByteBuf() {} + protected byte _getByte(int p0){ return 0; } + protected int _getInt(int p0){ return 0; } + protected int _getIntLE(int p0){ return 0; } + protected int _getUnsignedMedium(int p0){ return 0; } + protected int _getUnsignedMediumLE(int p0){ return 0; } + protected int forEachByteAsc0(int p0, int p1, ByteProcessor p2){ return 0; } + protected int forEachByteDesc0(int p0, int p1, ByteProcessor p2){ return 0; } + protected long _getLong(int p0){ return 0; } + protected long _getLongLE(int p0){ return 0; } + protected short _getShort(int p0){ return 0; } + protected short _getShortLE(int p0){ return 0; } + protected void _setByte(int p0, int p1){} + protected void _setInt(int p0, int p1){} + protected void _setIntLE(int p0, int p1){} + protected void _setLong(int p0, long p1){} + protected void _setLongLE(int p0, long p1){} + protected void _setMedium(int p0, int p1){} + protected void _setMediumLE(int p0, int p1){} + protected void _setShort(int p0, int p1){} + protected void _setShortLE(int p0, int p1){} + protected void deallocate(){} + public ByteBuf component(int p0){ return null; } + public ByteBuf componentAtOffset(int p0){ return null; } + public ByteBuf copy(int p0, int p1){ return null; } + public ByteBuf internalComponent(int p0){ return null; } + public ByteBuf internalComponentAtOffset(int p0){ return null; } + public ByteBuf unwrap(){ return null; } + public ByteBufAllocator alloc(){ return null; } + public ByteBuffer internalNioBuffer(int p0, int p1){ return null; } + public ByteBuffer nioBuffer(int p0, int p1){ return null; } + public ByteBuffer[] nioBuffers(){ return null; } + public ByteBuffer[] nioBuffers(int p0, int p1){ return null; } + public ByteOrder order(){ return null; } + public CompositeByteBuf addComponent(ByteBuf p0){ return null; } + public CompositeByteBuf addComponent(boolean p0, ByteBuf p1){ return null; } + public CompositeByteBuf addComponent(boolean p0, int p1, ByteBuf p2){ return null; } + public CompositeByteBuf addComponent(int p0, ByteBuf p1){ return null; } + public CompositeByteBuf addComponents(ByteBuf... p0){ return null; } + public CompositeByteBuf addComponents(Iterable<ByteBuf> p0){ return null; } + public CompositeByteBuf addComponents(boolean p0, ByteBuf... p1){ return null; } + public CompositeByteBuf addComponents(boolean p0, Iterable<ByteBuf> p1){ return null; } + public CompositeByteBuf addComponents(int p0, ByteBuf... p1){ return null; } + public CompositeByteBuf addComponents(int p0, Iterable<ByteBuf> p1){ return null; } + public CompositeByteBuf addFlattenedComponents(boolean p0, ByteBuf p1){ return null; } + public CompositeByteBuf capacity(int p0){ return null; } + public CompositeByteBuf clear(){ return null; } + public CompositeByteBuf consolidate(){ return null; } + public CompositeByteBuf consolidate(int p0, int p1){ return null; } + public CompositeByteBuf discardReadBytes(){ return null; } + public CompositeByteBuf discardReadComponents(){ return null; } + public CompositeByteBuf discardSomeReadBytes(){ return null; } + public CompositeByteBuf ensureWritable(int p0){ return null; } + public CompositeByteBuf getBytes(int p0, ByteBuf p1){ return null; } + public CompositeByteBuf getBytes(int p0, ByteBuf p1, int p2){ return null; } + public CompositeByteBuf getBytes(int p0, ByteBuf p1, int p2, int p3){ return null; } + public CompositeByteBuf getBytes(int p0, ByteBuffer p1){ return null; } + public CompositeByteBuf getBytes(int p0, OutputStream p1, int p2){ return null; } + public CompositeByteBuf getBytes(int p0, byte[] p1){ return null; } + public CompositeByteBuf getBytes(int p0, byte[] p1, int p2, int p3){ return null; } + public CompositeByteBuf markReaderIndex(){ return null; } + public CompositeByteBuf markWriterIndex(){ return null; } + public CompositeByteBuf readBytes(ByteBuf p0){ return null; } + public CompositeByteBuf readBytes(ByteBuf p0, int p1){ return null; } + public CompositeByteBuf readBytes(ByteBuf p0, int p1, int p2){ return null; } + public CompositeByteBuf readBytes(ByteBuffer p0){ return null; } + public CompositeByteBuf readBytes(OutputStream p0, int p1){ return null; } + public CompositeByteBuf readBytes(byte[] p0){ return null; } + public CompositeByteBuf readBytes(byte[] p0, int p1, int p2){ return null; } + public CompositeByteBuf readerIndex(int p0){ return null; } + public CompositeByteBuf removeComponent(int p0){ return null; } + public CompositeByteBuf removeComponents(int p0, int p1){ return null; } + public CompositeByteBuf resetReaderIndex(){ return null; } + public CompositeByteBuf resetWriterIndex(){ return null; } + public CompositeByteBuf retain(){ return null; } + public CompositeByteBuf retain(int p0){ return null; } + public CompositeByteBuf setBoolean(int p0, boolean p1){ return null; } + public CompositeByteBuf setByte(int p0, int p1){ return null; } + public CompositeByteBuf setBytes(int p0, ByteBuf p1){ return null; } + public CompositeByteBuf setBytes(int p0, ByteBuf p1, int p2){ return null; } + public CompositeByteBuf setBytes(int p0, ByteBuf p1, int p2, int p3){ return null; } + public CompositeByteBuf setBytes(int p0, ByteBuffer p1){ return null; } + public CompositeByteBuf setBytes(int p0, byte[] p1){ return null; } + public CompositeByteBuf setBytes(int p0, byte[] p1, int p2, int p3){ return null; } + public CompositeByteBuf setChar(int p0, int p1){ return null; } + public CompositeByteBuf setDouble(int p0, double p1){ return null; } + public CompositeByteBuf setFloat(int p0, float p1){ return null; } + public CompositeByteBuf setIndex(int p0, int p1){ return null; } + public CompositeByteBuf setInt(int p0, int p1){ return null; } + public CompositeByteBuf setLong(int p0, long p1){ return null; } + public CompositeByteBuf setMedium(int p0, int p1){ return null; } + public CompositeByteBuf setShort(int p0, int p1){ return null; } + public CompositeByteBuf setZero(int p0, int p1){ return null; } + public CompositeByteBuf skipBytes(int p0){ return null; } + public CompositeByteBuf touch(){ return null; } + public CompositeByteBuf touch(Object p0){ return null; } + public CompositeByteBuf writeBoolean(boolean p0){ return null; } + public CompositeByteBuf writeByte(int p0){ return null; } + public CompositeByteBuf writeBytes(ByteBuf p0){ return null; } + public CompositeByteBuf writeBytes(ByteBuf p0, int p1){ return null; } + public CompositeByteBuf writeBytes(ByteBuf p0, int p1, int p2){ return null; } + public CompositeByteBuf writeBytes(ByteBuffer p0){ return null; } + public CompositeByteBuf writeBytes(byte[] p0){ return null; } + public CompositeByteBuf writeBytes(byte[] p0, int p1, int p2){ return null; } + public CompositeByteBuf writeChar(int p0){ return null; } + public CompositeByteBuf writeDouble(double p0){ return null; } + public CompositeByteBuf writeFloat(float p0){ return null; } + public CompositeByteBuf writeInt(int p0){ return null; } + public CompositeByteBuf writeLong(long p0){ return null; } + public CompositeByteBuf writeMedium(int p0){ return null; } + public CompositeByteBuf writeShort(int p0){ return null; } + public CompositeByteBuf writeZero(int p0){ return null; } + public CompositeByteBuf writerIndex(int p0){ return null; } + public CompositeByteBuf(ByteBufAllocator p0, boolean p1, int p2){} + public CompositeByteBuf(ByteBufAllocator p0, boolean p1, int p2, ByteBuf... p3){} + public CompositeByteBuf(ByteBufAllocator p0, boolean p1, int p2, Iterable<ByteBuf> p3){} + public Iterator<ByteBuf> iterator(){ return null; } + public List<ByteBuf> decompose(int p0, int p1){ return null; } + public String toString(){ return null; } + public boolean hasArray(){ return false; } + public boolean hasMemoryAddress(){ return false; } + public boolean isDirect(){ return false; } + public byte getByte(int p0){ return 0; } + public byte[] array(){ return null; } + public int arrayOffset(){ return 0; } + public int capacity(){ return 0; } + public int getBytes(int p0, FileChannel p1, long p2, int p3){ return 0; } + public int getBytes(int p0, GatheringByteChannel p1, int p2){ return 0; } + public int maxNumComponents(){ return 0; } + public int nioBufferCount(){ return 0; } + public int numComponents(){ return 0; } + public int setBytes(int p0, FileChannel p1, long p2, int p3){ return 0; } + public int setBytes(int p0, InputStream p1, int p2){ return 0; } + public int setBytes(int p0, ScatteringByteChannel p1, int p2){ return 0; } + public int toByteIndex(int p0){ return 0; } + public int toComponentIndex(int p0){ return 0; } + public long memoryAddress(){ return 0; } +} diff --git a/java/ql/test/stubs/netty-4.1.x/io/netty/buffer/SwappedByteBuf.java b/java/ql/test/stubs/netty-4.1.x/io/netty/buffer/SwappedByteBuf.java new file mode 100644 index 00000000000..d16fd06663f --- /dev/null +++ b/java/ql/test/stubs/netty-4.1.x/io/netty/buffer/SwappedByteBuf.java @@ -0,0 +1,206 @@ +// Generated automatically from io.netty.buffer.SwappedByteBuf for testing purposes + +package io.netty.buffer; + +import io.netty.buffer.ByteBuf; +import io.netty.buffer.ByteBufAllocator; +import io.netty.util.ByteProcessor; +import java.io.InputStream; +import java.io.OutputStream; +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.nio.channels.FileChannel; +import java.nio.channels.GatheringByteChannel; +import java.nio.channels.ScatteringByteChannel; +import java.nio.charset.Charset; + +public class SwappedByteBuf extends ByteBuf +{ + protected SwappedByteBuf() {} + public ByteBuf asReadOnly(){ return null; } + public ByteBuf capacity(int p0){ return null; } + public ByteBuf clear(){ return null; } + public ByteBuf copy(){ return null; } + public ByteBuf copy(int p0, int p1){ return null; } + public ByteBuf discardReadBytes(){ return null; } + public ByteBuf discardSomeReadBytes(){ return null; } + public ByteBuf duplicate(){ return null; } + public ByteBuf ensureWritable(int p0){ return null; } + public ByteBuf getBytes(int p0, ByteBuf p1){ return null; } + public ByteBuf getBytes(int p0, ByteBuf p1, int p2){ return null; } + public ByteBuf getBytes(int p0, ByteBuf p1, int p2, int p3){ return null; } + public ByteBuf getBytes(int p0, ByteBuffer p1){ return null; } + public ByteBuf getBytes(int p0, OutputStream p1, int p2){ return null; } + public ByteBuf getBytes(int p0, byte[] p1){ return null; } + public ByteBuf getBytes(int p0, byte[] p1, int p2, int p3){ return null; } + public ByteBuf markReaderIndex(){ return null; } + public ByteBuf markWriterIndex(){ return null; } + public ByteBuf order(ByteOrder p0){ return null; } + public ByteBuf readBytes(ByteBuf p0){ return null; } + public ByteBuf readBytes(ByteBuf p0, int p1){ return null; } + public ByteBuf readBytes(ByteBuf p0, int p1, int p2){ return null; } + public ByteBuf readBytes(ByteBuffer p0){ return null; } + public ByteBuf readBytes(OutputStream p0, int p1){ return null; } + public ByteBuf readBytes(byte[] p0){ return null; } + public ByteBuf readBytes(byte[] p0, int p1, int p2){ return null; } + public ByteBuf readBytes(int p0){ return null; } + public ByteBuf readRetainedSlice(int p0){ return null; } + public ByteBuf readSlice(int p0){ return null; } + public ByteBuf readerIndex(int p0){ return null; } + public ByteBuf resetReaderIndex(){ return null; } + public ByteBuf resetWriterIndex(){ return null; } + public ByteBuf retain(){ return null; } + public ByteBuf retain(int p0){ return null; } + public ByteBuf retainedDuplicate(){ return null; } + public ByteBuf retainedSlice(){ return null; } + public ByteBuf retainedSlice(int p0, int p1){ return null; } + public ByteBuf setBoolean(int p0, boolean p1){ return null; } + public ByteBuf setByte(int p0, int p1){ return null; } + public ByteBuf setBytes(int p0, ByteBuf p1){ return null; } + public ByteBuf setBytes(int p0, ByteBuf p1, int p2){ return null; } + public ByteBuf setBytes(int p0, ByteBuf p1, int p2, int p3){ return null; } + public ByteBuf setBytes(int p0, ByteBuffer p1){ return null; } + public ByteBuf setBytes(int p0, byte[] p1){ return null; } + public ByteBuf setBytes(int p0, byte[] p1, int p2, int p3){ return null; } + public ByteBuf setChar(int p0, int p1){ return null; } + public ByteBuf setDouble(int p0, double p1){ return null; } + public ByteBuf setFloat(int p0, float p1){ return null; } + public ByteBuf setIndex(int p0, int p1){ return null; } + public ByteBuf setInt(int p0, int p1){ return null; } + public ByteBuf setIntLE(int p0, int p1){ return null; } + public ByteBuf setLong(int p0, long p1){ return null; } + public ByteBuf setLongLE(int p0, long p1){ return null; } + public ByteBuf setMedium(int p0, int p1){ return null; } + public ByteBuf setMediumLE(int p0, int p1){ return null; } + public ByteBuf setShort(int p0, int p1){ return null; } + public ByteBuf setShortLE(int p0, int p1){ return null; } + public ByteBuf setZero(int p0, int p1){ return null; } + public ByteBuf skipBytes(int p0){ return null; } + public ByteBuf slice(){ return null; } + public ByteBuf slice(int p0, int p1){ return null; } + public ByteBuf touch(){ return null; } + public ByteBuf touch(Object p0){ return null; } + public ByteBuf unwrap(){ return null; } + public ByteBuf writeBoolean(boolean p0){ return null; } + public ByteBuf writeByte(int p0){ return null; } + public ByteBuf writeBytes(ByteBuf p0){ return null; } + public ByteBuf writeBytes(ByteBuf p0, int p1){ return null; } + public ByteBuf writeBytes(ByteBuf p0, int p1, int p2){ return null; } + public ByteBuf writeBytes(ByteBuffer p0){ return null; } + public ByteBuf writeBytes(byte[] p0){ return null; } + public ByteBuf writeBytes(byte[] p0, int p1, int p2){ return null; } + public ByteBuf writeChar(int p0){ return null; } + public ByteBuf writeDouble(double p0){ return null; } + public ByteBuf writeFloat(float p0){ return null; } + public ByteBuf writeInt(int p0){ return null; } + public ByteBuf writeIntLE(int p0){ return null; } + public ByteBuf writeLong(long p0){ return null; } + public ByteBuf writeLongLE(long p0){ return null; } + public ByteBuf writeMedium(int p0){ return null; } + public ByteBuf writeMediumLE(int p0){ return null; } + public ByteBuf writeShort(int p0){ return null; } + public ByteBuf writeShortLE(int p0){ return null; } + public ByteBuf writeZero(int p0){ return null; } + public ByteBuf writerIndex(int p0){ return null; } + public ByteBufAllocator alloc(){ return null; } + public ByteBuffer internalNioBuffer(int p0, int p1){ return null; } + public ByteBuffer nioBuffer(){ return null; } + public ByteBuffer nioBuffer(int p0, int p1){ return null; } + public ByteBuffer[] nioBuffers(){ return null; } + public ByteBuffer[] nioBuffers(int p0, int p1){ return null; } + public ByteOrder order(){ return null; } + public CharSequence getCharSequence(int p0, int p1, Charset p2){ return null; } + public CharSequence readCharSequence(int p0, Charset p1){ return null; } + public String toString(){ return null; } + public String toString(Charset p0){ return null; } + public String toString(int p0, int p1, Charset p2){ return null; } + public SwappedByteBuf(ByteBuf p0){} + public boolean equals(Object p0){ return false; } + public boolean getBoolean(int p0){ return false; } + public boolean hasArray(){ return false; } + public boolean hasMemoryAddress(){ return false; } + public boolean isContiguous(){ return false; } + public boolean isDirect(){ return false; } + public boolean isReadOnly(){ return false; } + public boolean isReadable(){ return false; } + public boolean isReadable(int p0){ return false; } + public boolean isWritable(){ return false; } + public boolean isWritable(int p0){ return false; } + public boolean readBoolean(){ return false; } + public boolean release(){ return false; } + public boolean release(int p0){ return false; } + public byte getByte(int p0){ return 0; } + public byte readByte(){ return 0; } + public byte[] array(){ return null; } + public char getChar(int p0){ return '0'; } + public char readChar(){ return '0'; } + public double getDouble(int p0){ return 0; } + public double readDouble(){ return 0; } + public float getFloat(int p0){ return 0; } + public float readFloat(){ return 0; } + public int arrayOffset(){ return 0; } + public int bytesBefore(byte p0){ return 0; } + public int bytesBefore(int p0, byte p1){ return 0; } + public int bytesBefore(int p0, int p1, byte p2){ return 0; } + public int capacity(){ return 0; } + public int compareTo(ByteBuf p0){ return 0; } + public int ensureWritable(int p0, boolean p1){ return 0; } + public int forEachByte(ByteProcessor p0){ return 0; } + public int forEachByte(int p0, int p1, ByteProcessor p2){ return 0; } + public int forEachByteDesc(ByteProcessor p0){ return 0; } + public int forEachByteDesc(int p0, int p1, ByteProcessor p2){ return 0; } + public int getBytes(int p0, FileChannel p1, long p2, int p3){ return 0; } + public int getBytes(int p0, GatheringByteChannel p1, int p2){ return 0; } + public int getInt(int p0){ return 0; } + public int getIntLE(int p0){ return 0; } + public int getMedium(int p0){ return 0; } + public int getMediumLE(int p0){ return 0; } + public int getUnsignedMedium(int p0){ return 0; } + public int getUnsignedMediumLE(int p0){ return 0; } + public int getUnsignedShort(int p0){ return 0; } + public int getUnsignedShortLE(int p0){ return 0; } + public int hashCode(){ return 0; } + public int indexOf(int p0, int p1, byte p2){ return 0; } + public int maxCapacity(){ return 0; } + public int maxFastWritableBytes(){ return 0; } + public int maxWritableBytes(){ return 0; } + public int nioBufferCount(){ return 0; } + public int readBytes(FileChannel p0, long p1, int p2){ return 0; } + public int readBytes(GatheringByteChannel p0, int p1){ return 0; } + public int readInt(){ return 0; } + public int readIntLE(){ return 0; } + public int readMedium(){ return 0; } + public int readMediumLE(){ return 0; } + public int readUnsignedMedium(){ return 0; } + public int readUnsignedMediumLE(){ return 0; } + public int readUnsignedShort(){ return 0; } + public int readUnsignedShortLE(){ return 0; } + public int readableBytes(){ return 0; } + public int readerIndex(){ return 0; } + public int refCnt(){ return 0; } + public int setBytes(int p0, FileChannel p1, long p2, int p3){ return 0; } + public int setBytes(int p0, InputStream p1, int p2){ return 0; } + public int setBytes(int p0, ScatteringByteChannel p1, int p2){ return 0; } + public int setCharSequence(int p0, CharSequence p1, Charset p2){ return 0; } + public int writableBytes(){ return 0; } + public int writeBytes(FileChannel p0, long p1, int p2){ return 0; } + public int writeBytes(InputStream p0, int p1){ return 0; } + public int writeBytes(ScatteringByteChannel p0, int p1){ return 0; } + public int writeCharSequence(CharSequence p0, Charset p1){ return 0; } + public int writerIndex(){ return 0; } + public long getLong(int p0){ return 0; } + public long getLongLE(int p0){ return 0; } + public long getUnsignedInt(int p0){ return 0; } + public long getUnsignedIntLE(int p0){ return 0; } + public long memoryAddress(){ return 0; } + public long readLong(){ return 0; } + public long readLongLE(){ return 0; } + public long readUnsignedInt(){ return 0; } + public long readUnsignedIntLE(){ return 0; } + public short getShort(int p0){ return 0; } + public short getShortLE(int p0){ return 0; } + public short getUnsignedByte(int p0){ return 0; } + public short readShort(){ return 0; } + public short readShortLE(){ return 0; } + public short readUnsignedByte(){ return 0; } +} diff --git a/java/ql/test/stubs/netty-4.1.x/io/netty/channel/Channel.java b/java/ql/test/stubs/netty-4.1.x/io/netty/channel/Channel.java new file mode 100644 index 00000000000..e3252ed33c8 --- /dev/null +++ b/java/ql/test/stubs/netty-4.1.x/io/netty/channel/Channel.java @@ -0,0 +1,58 @@ +// Generated automatically from io.netty.channel.Channel for testing purposes + +package io.netty.channel; + +import io.netty.buffer.ByteBufAllocator; +import io.netty.channel.ChannelConfig; +import io.netty.channel.ChannelFuture; +import io.netty.channel.ChannelId; +import io.netty.channel.ChannelMetadata; +import io.netty.channel.ChannelOutboundBuffer; +import io.netty.channel.ChannelOutboundInvoker; +import io.netty.channel.ChannelPipeline; +import io.netty.channel.ChannelPromise; +import io.netty.channel.EventLoop; +import io.netty.channel.RecvByteBufAllocator; +import io.netty.util.AttributeMap; +import java.net.SocketAddress; + +public interface Channel extends AttributeMap, ChannelOutboundInvoker, Comparable<Channel> +{ + ByteBufAllocator alloc(); + Channel flush(); + Channel parent(); + Channel read(); + Channel.Unsafe unsafe(); + ChannelConfig config(); + ChannelFuture closeFuture(); + ChannelId id(); + ChannelMetadata metadata(); + ChannelPipeline pipeline(); + EventLoop eventLoop(); + SocketAddress localAddress(); + SocketAddress remoteAddress(); + boolean isActive(); + boolean isOpen(); + boolean isRegistered(); + boolean isWritable(); + long bytesBeforeUnwritable(); + long bytesBeforeWritable(); + static public interface Unsafe + { + ChannelOutboundBuffer outboundBuffer(); + ChannelPromise voidPromise(); + RecvByteBufAllocator.Handle recvBufAllocHandle(); + SocketAddress localAddress(); + SocketAddress remoteAddress(); + void beginRead(); + void bind(SocketAddress p0, ChannelPromise p1); + void close(ChannelPromise p0); + void closeForcibly(); + void connect(SocketAddress p0, SocketAddress p1, ChannelPromise p2); + void deregister(ChannelPromise p0); + void disconnect(ChannelPromise p0); + void flush(); + void register(EventLoop p0, ChannelPromise p1); + void write(Object p0, ChannelPromise p1); + } +} diff --git a/java/ql/test/stubs/netty-4.1.x/io/netty/channel/ChannelConfig.java b/java/ql/test/stubs/netty-4.1.x/io/netty/channel/ChannelConfig.java new file mode 100644 index 00000000000..b62888f8bb6 --- /dev/null +++ b/java/ql/test/stubs/netty-4.1.x/io/netty/channel/ChannelConfig.java @@ -0,0 +1,40 @@ +// Generated automatically from io.netty.channel.ChannelConfig for testing purposes + +package io.netty.channel; + +import io.netty.buffer.ByteBufAllocator; +import io.netty.channel.ChannelOption; +import io.netty.channel.MessageSizeEstimator; +import io.netty.channel.RecvByteBufAllocator; +import io.netty.channel.WriteBufferWaterMark; +import java.util.Map; + +public interface ChannelConfig +{ + <T extends RecvByteBufAllocator> T getRecvByteBufAllocator(); + <T> T getOption(io.netty.channel.ChannelOption<T> p0); + <T> boolean setOption(io.netty.channel.ChannelOption<T> p0, T p1); + ByteBufAllocator getAllocator(); + ChannelConfig setAllocator(ByteBufAllocator p0); + ChannelConfig setAutoClose(boolean p0); + ChannelConfig setAutoRead(boolean p0); + ChannelConfig setConnectTimeoutMillis(int p0); + ChannelConfig setMaxMessagesPerRead(int p0); + ChannelConfig setMessageSizeEstimator(MessageSizeEstimator p0); + ChannelConfig setRecvByteBufAllocator(RecvByteBufAllocator p0); + ChannelConfig setWriteBufferHighWaterMark(int p0); + ChannelConfig setWriteBufferLowWaterMark(int p0); + ChannelConfig setWriteBufferWaterMark(WriteBufferWaterMark p0); + ChannelConfig setWriteSpinCount(int p0); + Map<ChannelOption<? extends Object>, Object> getOptions(); + MessageSizeEstimator getMessageSizeEstimator(); + WriteBufferWaterMark getWriteBufferWaterMark(); + boolean isAutoClose(); + boolean isAutoRead(); + boolean setOptions(Map<ChannelOption<? extends Object>, ? extends Object> p0); + int getConnectTimeoutMillis(); + int getMaxMessagesPerRead(); + int getWriteBufferHighWaterMark(); + int getWriteBufferLowWaterMark(); + int getWriteSpinCount(); +} diff --git a/java/ql/test/stubs/netty-4.1.x/io/netty/channel/ChannelFuture.java b/java/ql/test/stubs/netty-4.1.x/io/netty/channel/ChannelFuture.java new file mode 100644 index 00000000000..d03340e6290 --- /dev/null +++ b/java/ql/test/stubs/netty-4.1.x/io/netty/channel/ChannelFuture.java @@ -0,0 +1,20 @@ +// Generated automatically from io.netty.channel.ChannelFuture for testing purposes + +package io.netty.channel; + +import io.netty.channel.Channel; +import io.netty.util.concurrent.GenericFutureListener; + +public interface ChannelFuture extends io.netty.util.concurrent.Future<Void> +{ + Channel channel(); + ChannelFuture addListener(GenericFutureListener<? extends io.netty.util.concurrent.Future<? super Void>> p0); + ChannelFuture addListeners(GenericFutureListener<? extends io.netty.util.concurrent.Future<? super Void>>... p0); + ChannelFuture await(); + ChannelFuture awaitUninterruptibly(); + ChannelFuture removeListener(GenericFutureListener<? extends io.netty.util.concurrent.Future<? super Void>> p0); + ChannelFuture removeListeners(GenericFutureListener<? extends io.netty.util.concurrent.Future<? super Void>>... p0); + ChannelFuture sync(); + ChannelFuture syncUninterruptibly(); + boolean isVoid(); +} diff --git a/java/ql/test/stubs/netty-4.1.x/io/netty/channel/ChannelHandler.java b/java/ql/test/stubs/netty-4.1.x/io/netty/channel/ChannelHandler.java new file mode 100644 index 00000000000..d82464df94b --- /dev/null +++ b/java/ql/test/stubs/netty-4.1.x/io/netty/channel/ChannelHandler.java @@ -0,0 +1,12 @@ +// Generated automatically from io.netty.channel.ChannelHandler for testing purposes + +package io.netty.channel; + +import io.netty.channel.ChannelHandlerContext; + +public interface ChannelHandler +{ + void exceptionCaught(ChannelHandlerContext p0, Throwable p1); + void handlerAdded(ChannelHandlerContext p0); + void handlerRemoved(ChannelHandlerContext p0); +} diff --git a/java/ql/test/stubs/netty-4.1.x/io/netty/channel/ChannelHandlerAdapter.java b/java/ql/test/stubs/netty-4.1.x/io/netty/channel/ChannelHandlerAdapter.java new file mode 100644 index 00000000000..1cf2749e183 --- /dev/null +++ b/java/ql/test/stubs/netty-4.1.x/io/netty/channel/ChannelHandlerAdapter.java @@ -0,0 +1,16 @@ +// Generated automatically from io.netty.channel.ChannelHandlerAdapter for testing purposes + +package io.netty.channel; + +import io.netty.channel.ChannelHandler; +import io.netty.channel.ChannelHandlerContext; + +abstract public class ChannelHandlerAdapter implements ChannelHandler +{ + protected void ensureNotSharable(){} + public ChannelHandlerAdapter(){} + public boolean isSharable(){ return false; } + public void exceptionCaught(ChannelHandlerContext p0, Throwable p1){} + public void handlerAdded(ChannelHandlerContext p0){} + public void handlerRemoved(ChannelHandlerContext p0){} +} diff --git a/java/ql/test/stubs/netty-4.1.x/io/netty/channel/ChannelHandlerContext.java b/java/ql/test/stubs/netty-4.1.x/io/netty/channel/ChannelHandlerContext.java new file mode 100644 index 00000000000..016f043a665 --- /dev/null +++ b/java/ql/test/stubs/netty-4.1.x/io/netty/channel/ChannelHandlerContext.java @@ -0,0 +1,38 @@ +// Generated automatically from io.netty.channel.ChannelHandlerContext for testing purposes + +package io.netty.channel; + +import io.netty.buffer.ByteBufAllocator; +import io.netty.channel.Channel; +import io.netty.channel.ChannelHandler; +import io.netty.channel.ChannelInboundInvoker; +import io.netty.channel.ChannelOutboundInvoker; +import io.netty.channel.ChannelPipeline; +import io.netty.util.Attribute; +import io.netty.util.AttributeKey; +import io.netty.util.AttributeMap; +import io.netty.util.concurrent.EventExecutor; + +public interface ChannelHandlerContext extends AttributeMap, ChannelInboundInvoker, ChannelOutboundInvoker +{ + <T> boolean hasAttr(io.netty.util.AttributeKey<T> p0); + <T> io.netty.util.Attribute<T> attr(io.netty.util.AttributeKey<T> p0); + ByteBufAllocator alloc(); + Channel channel(); + ChannelHandler handler(); + ChannelHandlerContext fireChannelActive(); + ChannelHandlerContext fireChannelInactive(); + ChannelHandlerContext fireChannelRead(Object p0); + ChannelHandlerContext fireChannelReadComplete(); + ChannelHandlerContext fireChannelRegistered(); + ChannelHandlerContext fireChannelUnregistered(); + ChannelHandlerContext fireChannelWritabilityChanged(); + ChannelHandlerContext fireExceptionCaught(Throwable p0); + ChannelHandlerContext fireUserEventTriggered(Object p0); + ChannelHandlerContext flush(); + ChannelHandlerContext read(); + ChannelPipeline pipeline(); + EventExecutor executor(); + String name(); + boolean isRemoved(); +} diff --git a/java/ql/test/stubs/netty-4.1.x/io/netty/channel/ChannelId.java b/java/ql/test/stubs/netty-4.1.x/io/netty/channel/ChannelId.java new file mode 100644 index 00000000000..88ecea3e327 --- /dev/null +++ b/java/ql/test/stubs/netty-4.1.x/io/netty/channel/ChannelId.java @@ -0,0 +1,11 @@ +// Generated automatically from io.netty.channel.ChannelId for testing purposes + +package io.netty.channel; + +import java.io.Serializable; + +public interface ChannelId extends Comparable<ChannelId>, Serializable +{ + String asLongText(); + String asShortText(); +} diff --git a/java/ql/test/stubs/netty-4.1.x/io/netty/channel/ChannelInboundHandler.java b/java/ql/test/stubs/netty-4.1.x/io/netty/channel/ChannelInboundHandler.java new file mode 100644 index 00000000000..485bcb0ba91 --- /dev/null +++ b/java/ql/test/stubs/netty-4.1.x/io/netty/channel/ChannelInboundHandler.java @@ -0,0 +1,19 @@ +// Generated automatically from io.netty.channel.ChannelInboundHandler for testing purposes + +package io.netty.channel; + +import io.netty.channel.ChannelHandler; +import io.netty.channel.ChannelHandlerContext; + +public interface ChannelInboundHandler extends ChannelHandler +{ + void channelActive(ChannelHandlerContext p0); + void channelInactive(ChannelHandlerContext p0); + void channelRead(ChannelHandlerContext p0, Object p1); + void channelReadComplete(ChannelHandlerContext p0); + void channelRegistered(ChannelHandlerContext p0); + void channelUnregistered(ChannelHandlerContext p0); + void channelWritabilityChanged(ChannelHandlerContext p0); + void exceptionCaught(ChannelHandlerContext p0, Throwable p1); + void userEventTriggered(ChannelHandlerContext p0, Object p1); +} diff --git a/java/ql/test/stubs/netty-4.1.x/io/netty/channel/ChannelInboundHandlerAdapter.java b/java/ql/test/stubs/netty-4.1.x/io/netty/channel/ChannelInboundHandlerAdapter.java new file mode 100644 index 00000000000..cc775515e6b --- /dev/null +++ b/java/ql/test/stubs/netty-4.1.x/io/netty/channel/ChannelInboundHandlerAdapter.java @@ -0,0 +1,21 @@ +// Generated automatically from io.netty.channel.ChannelInboundHandlerAdapter for testing purposes + +package io.netty.channel; + +import io.netty.channel.ChannelHandlerAdapter; +import io.netty.channel.ChannelHandlerContext; +import io.netty.channel.ChannelInboundHandler; + +public class ChannelInboundHandlerAdapter extends ChannelHandlerAdapter implements ChannelInboundHandler +{ + public ChannelInboundHandlerAdapter(){} + public void channelActive(ChannelHandlerContext p0){} + public void channelInactive(ChannelHandlerContext p0){} + public void channelRead(ChannelHandlerContext p0, Object p1){} + public void channelReadComplete(ChannelHandlerContext p0){} + public void channelRegistered(ChannelHandlerContext p0){} + public void channelUnregistered(ChannelHandlerContext p0){} + public void channelWritabilityChanged(ChannelHandlerContext p0){} + public void exceptionCaught(ChannelHandlerContext p0, Throwable p1){} + public void userEventTriggered(ChannelHandlerContext p0, Object p1){} +} diff --git a/java/ql/test/stubs/netty-4.1.x/io/netty/channel/ChannelInboundInvoker.java b/java/ql/test/stubs/netty-4.1.x/io/netty/channel/ChannelInboundInvoker.java new file mode 100644 index 00000000000..e0e73b5b871 --- /dev/null +++ b/java/ql/test/stubs/netty-4.1.x/io/netty/channel/ChannelInboundInvoker.java @@ -0,0 +1,17 @@ +// Generated automatically from io.netty.channel.ChannelInboundInvoker for testing purposes + +package io.netty.channel; + + +public interface ChannelInboundInvoker +{ + ChannelInboundInvoker fireChannelActive(); + ChannelInboundInvoker fireChannelInactive(); + ChannelInboundInvoker fireChannelRead(Object p0); + ChannelInboundInvoker fireChannelReadComplete(); + ChannelInboundInvoker fireChannelRegistered(); + ChannelInboundInvoker fireChannelUnregistered(); + ChannelInboundInvoker fireChannelWritabilityChanged(); + ChannelInboundInvoker fireExceptionCaught(Throwable p0); + ChannelInboundInvoker fireUserEventTriggered(Object p0); +} diff --git a/java/ql/test/stubs/netty-4.1.x/io/netty/channel/ChannelMetadata.java b/java/ql/test/stubs/netty-4.1.x/io/netty/channel/ChannelMetadata.java new file mode 100644 index 00000000000..5f21a3e3d95 --- /dev/null +++ b/java/ql/test/stubs/netty-4.1.x/io/netty/channel/ChannelMetadata.java @@ -0,0 +1,13 @@ +// Generated automatically from io.netty.channel.ChannelMetadata for testing purposes + +package io.netty.channel; + + +public class ChannelMetadata +{ + protected ChannelMetadata() {} + public ChannelMetadata(boolean p0){} + public ChannelMetadata(boolean p0, int p1){} + public boolean hasDisconnect(){ return false; } + public int defaultMaxMessagesPerRead(){ return 0; } +} diff --git a/java/ql/test/stubs/netty-4.1.x/io/netty/channel/ChannelOption.java b/java/ql/test/stubs/netty-4.1.x/io/netty/channel/ChannelOption.java new file mode 100644 index 00000000000..b47513d23f6 --- /dev/null +++ b/java/ql/test/stubs/netty-4.1.x/io/netty/channel/ChannelOption.java @@ -0,0 +1,53 @@ +// Generated automatically from io.netty.channel.ChannelOption for testing purposes + +package io.netty.channel; + +import io.netty.buffer.ByteBufAllocator; +import io.netty.channel.MessageSizeEstimator; +import io.netty.channel.RecvByteBufAllocator; +import io.netty.channel.WriteBufferWaterMark; +import io.netty.util.AbstractConstant; +import java.net.InetAddress; +import java.net.NetworkInterface; + +public class ChannelOption<T> extends AbstractConstant<ChannelOption<T>> +{ + protected ChannelOption() {} + protected ChannelOption(String p0){} + public static <T> io.netty.channel.ChannelOption<T> newInstance(String p0){ return null; } + public static <T> io.netty.channel.ChannelOption<T> valueOf(Class<? extends Object> p0, String p1){ return null; } + public static <T> io.netty.channel.ChannelOption<T> valueOf(String p0){ return null; } + public static ChannelOption<Boolean> ALLOW_HALF_CLOSURE = null; + public static ChannelOption<Boolean> AUTO_CLOSE = null; + public static ChannelOption<Boolean> AUTO_READ = null; + public static ChannelOption<Boolean> DATAGRAM_CHANNEL_ACTIVE_ON_REGISTRATION = null; + public static ChannelOption<Boolean> IP_MULTICAST_LOOP_DISABLED = null; + public static ChannelOption<Boolean> SINGLE_EVENTEXECUTOR_PER_GROUP = null; + public static ChannelOption<Boolean> SO_BROADCAST = null; + public static ChannelOption<Boolean> SO_KEEPALIVE = null; + public static ChannelOption<Boolean> SO_REUSEADDR = null; + public static ChannelOption<Boolean> TCP_FASTOPEN_CONNECT = null; + public static ChannelOption<Boolean> TCP_NODELAY = null; + public static ChannelOption<ByteBufAllocator> ALLOCATOR = null; + public static ChannelOption<InetAddress> IP_MULTICAST_ADDR = null; + public static ChannelOption<Integer> CONNECT_TIMEOUT_MILLIS = null; + public static ChannelOption<Integer> IP_MULTICAST_TTL = null; + public static ChannelOption<Integer> IP_TOS = null; + public static ChannelOption<Integer> MAX_MESSAGES_PER_READ = null; + public static ChannelOption<Integer> MAX_MESSAGES_PER_WRITE = null; + public static ChannelOption<Integer> SO_BACKLOG = null; + public static ChannelOption<Integer> SO_LINGER = null; + public static ChannelOption<Integer> SO_RCVBUF = null; + public static ChannelOption<Integer> SO_SNDBUF = null; + public static ChannelOption<Integer> SO_TIMEOUT = null; + public static ChannelOption<Integer> TCP_FASTOPEN = null; + public static ChannelOption<Integer> WRITE_BUFFER_HIGH_WATER_MARK = null; + public static ChannelOption<Integer> WRITE_BUFFER_LOW_WATER_MARK = null; + public static ChannelOption<Integer> WRITE_SPIN_COUNT = null; + public static ChannelOption<MessageSizeEstimator> MESSAGE_SIZE_ESTIMATOR = null; + public static ChannelOption<NetworkInterface> IP_MULTICAST_IF = null; + public static ChannelOption<RecvByteBufAllocator> RCVBUF_ALLOCATOR = null; + public static ChannelOption<WriteBufferWaterMark> WRITE_BUFFER_WATER_MARK = null; + public static boolean exists(String p0){ return false; } + public void validate(T p0){} +} diff --git a/java/ql/test/stubs/netty-4.1.x/io/netty/channel/ChannelOutboundBuffer.java b/java/ql/test/stubs/netty-4.1.x/io/netty/channel/ChannelOutboundBuffer.java new file mode 100644 index 00000000000..537b52f874c --- /dev/null +++ b/java/ql/test/stubs/netty-4.1.x/io/netty/channel/ChannelOutboundBuffer.java @@ -0,0 +1,37 @@ +// Generated automatically from io.netty.channel.ChannelOutboundBuffer for testing purposes + +package io.netty.channel; + +import io.netty.channel.ChannelPromise; +import java.nio.ByteBuffer; + +public class ChannelOutboundBuffer +{ + protected ChannelOutboundBuffer() {} + public ByteBuffer[] nioBuffers(){ return null; } + public ByteBuffer[] nioBuffers(int p0, long p1){ return null; } + public Object current(){ return null; } + public boolean getUserDefinedWritability(int p0){ return false; } + public boolean isEmpty(){ return false; } + public boolean isWritable(){ return false; } + public boolean remove(){ return false; } + public boolean remove(Throwable p0){ return false; } + public int nioBufferCount(){ return 0; } + public int size(){ return 0; } + public long bytesBeforeUnwritable(){ return 0; } + public long bytesBeforeWritable(){ return 0; } + public long currentProgress(){ return 0; } + public long nioBufferSize(){ return 0; } + public long totalPendingWriteBytes(){ return 0; } + public void addFlush(){} + public void addMessage(Object p0, int p1, ChannelPromise p2){} + public void forEachFlushedMessage(ChannelOutboundBuffer.MessageProcessor p0){} + public void progress(long p0){} + public void recycle(){} + public void removeBytes(long p0){} + public void setUserDefinedWritability(int p0, boolean p1){} + static public interface MessageProcessor + { + boolean processMessage(Object p0); + } +} diff --git a/java/ql/test/stubs/netty-4.1.x/io/netty/channel/ChannelOutboundInvoker.java b/java/ql/test/stubs/netty-4.1.x/io/netty/channel/ChannelOutboundInvoker.java new file mode 100644 index 00000000000..cd034b1ae63 --- /dev/null +++ b/java/ql/test/stubs/netty-4.1.x/io/netty/channel/ChannelOutboundInvoker.java @@ -0,0 +1,35 @@ +// Generated automatically from io.netty.channel.ChannelOutboundInvoker for testing purposes + +package io.netty.channel; + +import io.netty.channel.ChannelFuture; +import io.netty.channel.ChannelProgressivePromise; +import io.netty.channel.ChannelPromise; +import java.net.SocketAddress; + +public interface ChannelOutboundInvoker +{ + ChannelFuture bind(SocketAddress p0); + ChannelFuture bind(SocketAddress p0, ChannelPromise p1); + ChannelFuture close(); + ChannelFuture close(ChannelPromise p0); + ChannelFuture connect(SocketAddress p0); + ChannelFuture connect(SocketAddress p0, ChannelPromise p1); + ChannelFuture connect(SocketAddress p0, SocketAddress p1); + ChannelFuture connect(SocketAddress p0, SocketAddress p1, ChannelPromise p2); + ChannelFuture deregister(); + ChannelFuture deregister(ChannelPromise p0); + ChannelFuture disconnect(); + ChannelFuture disconnect(ChannelPromise p0); + ChannelFuture newFailedFuture(Throwable p0); + ChannelFuture newSucceededFuture(); + ChannelFuture write(Object p0); + ChannelFuture write(Object p0, ChannelPromise p1); + ChannelFuture writeAndFlush(Object p0); + ChannelFuture writeAndFlush(Object p0, ChannelPromise p1); + ChannelOutboundInvoker flush(); + ChannelOutboundInvoker read(); + ChannelProgressivePromise newProgressivePromise(); + ChannelPromise newPromise(); + ChannelPromise voidPromise(); +} diff --git a/java/ql/test/stubs/netty-4.1.x/io/netty/channel/ChannelPipeline.java b/java/ql/test/stubs/netty-4.1.x/io/netty/channel/ChannelPipeline.java new file mode 100644 index 00000000000..86ad380d93f --- /dev/null +++ b/java/ql/test/stubs/netty-4.1.x/io/netty/channel/ChannelPipeline.java @@ -0,0 +1,58 @@ +// Generated automatically from io.netty.channel.ChannelPipeline for testing purposes + +package io.netty.channel; + +import io.netty.channel.Channel; +import io.netty.channel.ChannelHandler; +import io.netty.channel.ChannelHandlerContext; +import io.netty.channel.ChannelInboundInvoker; +import io.netty.channel.ChannelOutboundInvoker; +import io.netty.util.concurrent.EventExecutorGroup; +import java.util.List; +import java.util.Map; + +public interface ChannelPipeline extends ChannelInboundInvoker, ChannelOutboundInvoker, Iterable<Map.Entry<String, ChannelHandler>> +{ + <T extends ChannelHandler> T get(java.lang.Class<T> p0); + <T extends ChannelHandler> T remove(java.lang.Class<T> p0); + <T extends ChannelHandler> T replace(java.lang.Class<T> p0, String p1, ChannelHandler p2); + Channel channel(); + ChannelHandler first(); + ChannelHandler get(String p0); + ChannelHandler last(); + ChannelHandler remove(String p0); + ChannelHandler removeFirst(); + ChannelHandler removeLast(); + ChannelHandler replace(String p0, String p1, ChannelHandler p2); + ChannelHandlerContext context(ChannelHandler p0); + ChannelHandlerContext context(Class<? extends ChannelHandler> p0); + ChannelHandlerContext context(String p0); + ChannelHandlerContext firstContext(); + ChannelHandlerContext lastContext(); + ChannelPipeline addAfter(EventExecutorGroup p0, String p1, String p2, ChannelHandler p3); + ChannelPipeline addAfter(String p0, String p1, ChannelHandler p2); + ChannelPipeline addBefore(EventExecutorGroup p0, String p1, String p2, ChannelHandler p3); + ChannelPipeline addBefore(String p0, String p1, ChannelHandler p2); + ChannelPipeline addFirst(ChannelHandler... p0); + ChannelPipeline addFirst(EventExecutorGroup p0, ChannelHandler... p1); + ChannelPipeline addFirst(EventExecutorGroup p0, String p1, ChannelHandler p2); + ChannelPipeline addFirst(String p0, ChannelHandler p1); + ChannelPipeline addLast(ChannelHandler... p0); + ChannelPipeline addLast(EventExecutorGroup p0, ChannelHandler... p1); + ChannelPipeline addLast(EventExecutorGroup p0, String p1, ChannelHandler p2); + ChannelPipeline addLast(String p0, ChannelHandler p1); + ChannelPipeline fireChannelActive(); + ChannelPipeline fireChannelInactive(); + ChannelPipeline fireChannelRead(Object p0); + ChannelPipeline fireChannelReadComplete(); + ChannelPipeline fireChannelRegistered(); + ChannelPipeline fireChannelUnregistered(); + ChannelPipeline fireChannelWritabilityChanged(); + ChannelPipeline fireExceptionCaught(Throwable p0); + ChannelPipeline fireUserEventTriggered(Object p0); + ChannelPipeline flush(); + ChannelPipeline remove(ChannelHandler p0); + ChannelPipeline replace(ChannelHandler p0, String p1, ChannelHandler p2); + List<String> names(); + Map<String, ChannelHandler> toMap(); +} diff --git a/java/ql/test/stubs/netty-4.1.x/io/netty/channel/ChannelProgressiveFuture.java b/java/ql/test/stubs/netty-4.1.x/io/netty/channel/ChannelProgressiveFuture.java new file mode 100644 index 00000000000..6306d8dfb89 --- /dev/null +++ b/java/ql/test/stubs/netty-4.1.x/io/netty/channel/ChannelProgressiveFuture.java @@ -0,0 +1,19 @@ +// Generated automatically from io.netty.channel.ChannelProgressiveFuture for testing purposes + +package io.netty.channel; + +import io.netty.channel.ChannelFuture; +import io.netty.util.concurrent.GenericFutureListener; +import io.netty.util.concurrent.ProgressiveFuture; + +public interface ChannelProgressiveFuture extends ChannelFuture, ProgressiveFuture<Void> +{ + ChannelProgressiveFuture addListener(GenericFutureListener<? extends io.netty.util.concurrent.Future<? super Void>> p0); + ChannelProgressiveFuture addListeners(GenericFutureListener<? extends io.netty.util.concurrent.Future<? super Void>>... p0); + ChannelProgressiveFuture await(); + ChannelProgressiveFuture awaitUninterruptibly(); + ChannelProgressiveFuture removeListener(GenericFutureListener<? extends io.netty.util.concurrent.Future<? super Void>> p0); + ChannelProgressiveFuture removeListeners(GenericFutureListener<? extends io.netty.util.concurrent.Future<? super Void>>... p0); + ChannelProgressiveFuture sync(); + ChannelProgressiveFuture syncUninterruptibly(); +} diff --git a/java/ql/test/stubs/netty-4.1.x/io/netty/channel/ChannelProgressivePromise.java b/java/ql/test/stubs/netty-4.1.x/io/netty/channel/ChannelProgressivePromise.java new file mode 100644 index 00000000000..c315415341e --- /dev/null +++ b/java/ql/test/stubs/netty-4.1.x/io/netty/channel/ChannelProgressivePromise.java @@ -0,0 +1,25 @@ +// Generated automatically from io.netty.channel.ChannelProgressivePromise for testing purposes + +package io.netty.channel; + +import io.netty.channel.ChannelProgressiveFuture; +import io.netty.channel.ChannelPromise; +import io.netty.util.concurrent.GenericFutureListener; +import io.netty.util.concurrent.ProgressivePromise; + +public interface ChannelProgressivePromise extends ChannelProgressiveFuture, ChannelPromise, ProgressivePromise<Void> +{ + ChannelProgressivePromise addListener(GenericFutureListener<? extends io.netty.util.concurrent.Future<? super Void>> p0); + ChannelProgressivePromise addListeners(GenericFutureListener<? extends io.netty.util.concurrent.Future<? super Void>>... p0); + ChannelProgressivePromise await(); + ChannelProgressivePromise awaitUninterruptibly(); + ChannelProgressivePromise removeListener(GenericFutureListener<? extends io.netty.util.concurrent.Future<? super Void>> p0); + ChannelProgressivePromise removeListeners(GenericFutureListener<? extends io.netty.util.concurrent.Future<? super Void>>... p0); + ChannelProgressivePromise setFailure(Throwable p0); + ChannelProgressivePromise setProgress(long p0, long p1); + ChannelProgressivePromise setSuccess(); + ChannelProgressivePromise setSuccess(Void p0); + ChannelProgressivePromise sync(); + ChannelProgressivePromise syncUninterruptibly(); + ChannelProgressivePromise unvoid(); +} diff --git a/java/ql/test/stubs/netty-4.1.x/io/netty/channel/ChannelPromise.java b/java/ql/test/stubs/netty-4.1.x/io/netty/channel/ChannelPromise.java new file mode 100644 index 00000000000..e5c632bc9c6 --- /dev/null +++ b/java/ql/test/stubs/netty-4.1.x/io/netty/channel/ChannelPromise.java @@ -0,0 +1,26 @@ +// Generated automatically from io.netty.channel.ChannelPromise for testing purposes + +package io.netty.channel; + +import io.netty.channel.Channel; +import io.netty.channel.ChannelFuture; +import io.netty.util.concurrent.GenericFutureListener; +import io.netty.util.concurrent.Promise; + +public interface ChannelPromise extends ChannelFuture, Promise<Void> +{ + Channel channel(); + ChannelPromise addListener(GenericFutureListener<? extends io.netty.util.concurrent.Future<? super Void>> p0); + ChannelPromise addListeners(GenericFutureListener<? extends io.netty.util.concurrent.Future<? super Void>>... p0); + ChannelPromise await(); + ChannelPromise awaitUninterruptibly(); + ChannelPromise removeListener(GenericFutureListener<? extends io.netty.util.concurrent.Future<? super Void>> p0); + ChannelPromise removeListeners(GenericFutureListener<? extends io.netty.util.concurrent.Future<? super Void>>... p0); + ChannelPromise setFailure(Throwable p0); + ChannelPromise setSuccess(); + ChannelPromise setSuccess(Void p0); + ChannelPromise sync(); + ChannelPromise syncUninterruptibly(); + ChannelPromise unvoid(); + boolean trySuccess(); +} diff --git a/java/ql/test/stubs/netty-4.1.x/io/netty/channel/EventLoop.java b/java/ql/test/stubs/netty-4.1.x/io/netty/channel/EventLoop.java new file mode 100644 index 00000000000..2260759717b --- /dev/null +++ b/java/ql/test/stubs/netty-4.1.x/io/netty/channel/EventLoop.java @@ -0,0 +1,11 @@ +// Generated automatically from io.netty.channel.EventLoop for testing purposes + +package io.netty.channel; + +import io.netty.channel.EventLoopGroup; +import io.netty.util.concurrent.OrderedEventExecutor; + +public interface EventLoop extends EventLoopGroup, OrderedEventExecutor +{ + EventLoopGroup parent(); +} diff --git a/java/ql/test/stubs/netty-4.1.x/io/netty/channel/EventLoopGroup.java b/java/ql/test/stubs/netty-4.1.x/io/netty/channel/EventLoopGroup.java new file mode 100644 index 00000000000..1e6da3111a0 --- /dev/null +++ b/java/ql/test/stubs/netty-4.1.x/io/netty/channel/EventLoopGroup.java @@ -0,0 +1,17 @@ +// Generated automatically from io.netty.channel.EventLoopGroup for testing purposes + +package io.netty.channel; + +import io.netty.channel.Channel; +import io.netty.channel.ChannelFuture; +import io.netty.channel.ChannelPromise; +import io.netty.channel.EventLoop; +import io.netty.util.concurrent.EventExecutorGroup; + +public interface EventLoopGroup extends EventExecutorGroup +{ + ChannelFuture register(Channel p0); + ChannelFuture register(Channel p0, ChannelPromise p1); + ChannelFuture register(ChannelPromise p0); + EventLoop next(); +} diff --git a/java/ql/test/stubs/netty-4.1.x/io/netty/channel/MessageSizeEstimator.java b/java/ql/test/stubs/netty-4.1.x/io/netty/channel/MessageSizeEstimator.java new file mode 100644 index 00000000000..e2f4267b189 --- /dev/null +++ b/java/ql/test/stubs/netty-4.1.x/io/netty/channel/MessageSizeEstimator.java @@ -0,0 +1,13 @@ +// Generated automatically from io.netty.channel.MessageSizeEstimator for testing purposes + +package io.netty.channel; + + +public interface MessageSizeEstimator +{ + MessageSizeEstimator.Handle newHandle(); + static public interface Handle + { + int size(Object p0); + } +} diff --git a/java/ql/test/stubs/netty-4.1.x/io/netty/channel/RecvByteBufAllocator.java b/java/ql/test/stubs/netty-4.1.x/io/netty/channel/RecvByteBufAllocator.java new file mode 100644 index 00000000000..062a9850b77 --- /dev/null +++ b/java/ql/test/stubs/netty-4.1.x/io/netty/channel/RecvByteBufAllocator.java @@ -0,0 +1,25 @@ +// Generated automatically from io.netty.channel.RecvByteBufAllocator for testing purposes + +package io.netty.channel; + +import io.netty.buffer.ByteBuf; +import io.netty.buffer.ByteBufAllocator; +import io.netty.channel.ChannelConfig; + +public interface RecvByteBufAllocator +{ + RecvByteBufAllocator.Handle newHandle(); + static public interface Handle + { + ByteBuf allocate(ByteBufAllocator p0); + boolean continueReading(); + int attemptedBytesRead(); + int guess(); + int lastBytesRead(); + void attemptedBytesRead(int p0); + void incMessagesRead(int p0); + void lastBytesRead(int p0); + void readComplete(); + void reset(ChannelConfig p0); + } +} diff --git a/java/ql/test/stubs/netty-4.1.x/io/netty/channel/WriteBufferWaterMark.java b/java/ql/test/stubs/netty-4.1.x/io/netty/channel/WriteBufferWaterMark.java new file mode 100644 index 00000000000..a2a98f482f7 --- /dev/null +++ b/java/ql/test/stubs/netty-4.1.x/io/netty/channel/WriteBufferWaterMark.java @@ -0,0 +1,14 @@ +// Generated automatically from io.netty.channel.WriteBufferWaterMark for testing purposes + +package io.netty.channel; + + +public class WriteBufferWaterMark +{ + protected WriteBufferWaterMark() {} + public String toString(){ return null; } + public WriteBufferWaterMark(int p0, int p1){} + public int high(){ return 0; } + public int low(){ return 0; } + public static WriteBufferWaterMark DEFAULT = null; +} diff --git a/java/ql/test/stubs/netty-4.1.x/io/netty/util/AbstractConstant.java b/java/ql/test/stubs/netty-4.1.x/io/netty/util/AbstractConstant.java new file mode 100644 index 00000000000..e658440075f --- /dev/null +++ b/java/ql/test/stubs/netty-4.1.x/io/netty/util/AbstractConstant.java @@ -0,0 +1,17 @@ +// Generated automatically from io.netty.util.AbstractConstant for testing purposes + +package io.netty.util; + +import io.netty.util.Constant; + +abstract public class AbstractConstant<T extends AbstractConstant<T>> implements Constant<T> +{ + protected AbstractConstant() {} + protected AbstractConstant(int p0, String p1){} + public final String name(){ return null; } + public final String toString(){ return null; } + public final boolean equals(Object p0){ return false; } + public final int compareTo(T p0){ return 0; } + public final int hashCode(){ return 0; } + public final int id(){ return 0; } +} diff --git a/java/ql/test/stubs/netty-4.1.x/io/netty/util/Attribute.java b/java/ql/test/stubs/netty-4.1.x/io/netty/util/Attribute.java new file mode 100644 index 00000000000..7ff2a84793f --- /dev/null +++ b/java/ql/test/stubs/netty-4.1.x/io/netty/util/Attribute.java @@ -0,0 +1,17 @@ +// Generated automatically from io.netty.util.Attribute for testing purposes + +package io.netty.util; + +import io.netty.util.AttributeKey; + +public interface Attribute<T> +{ + T get(); + T getAndRemove(); + T getAndSet(T p0); + T setIfAbsent(T p0); + boolean compareAndSet(T p0, T p1); + io.netty.util.AttributeKey<T> key(); + void remove(); + void set(T p0); +} diff --git a/java/ql/test/stubs/netty-4.1.x/io/netty/util/AttributeKey.java b/java/ql/test/stubs/netty-4.1.x/io/netty/util/AttributeKey.java new file mode 100644 index 00000000000..9b8eedd4eac --- /dev/null +++ b/java/ql/test/stubs/netty-4.1.x/io/netty/util/AttributeKey.java @@ -0,0 +1,14 @@ +// Generated automatically from io.netty.util.AttributeKey for testing purposes + +package io.netty.util; + +import io.netty.util.AbstractConstant; + +public class AttributeKey<T> extends AbstractConstant<AttributeKey<T>> +{ + protected AttributeKey() {} + public static <T> io.netty.util.AttributeKey<T> newInstance(String p0){ return null; } + public static <T> io.netty.util.AttributeKey<T> valueOf(Class<? extends Object> p0, String p1){ return null; } + public static <T> io.netty.util.AttributeKey<T> valueOf(String p0){ return null; } + public static boolean exists(String p0){ return false; } +} diff --git a/java/ql/test/stubs/netty-4.1.x/io/netty/util/AttributeMap.java b/java/ql/test/stubs/netty-4.1.x/io/netty/util/AttributeMap.java new file mode 100644 index 00000000000..ff1e835ca34 --- /dev/null +++ b/java/ql/test/stubs/netty-4.1.x/io/netty/util/AttributeMap.java @@ -0,0 +1,12 @@ +// Generated automatically from io.netty.util.AttributeMap for testing purposes + +package io.netty.util; + +import io.netty.util.Attribute; +import io.netty.util.AttributeKey; + +public interface AttributeMap +{ + <T> boolean hasAttr(io.netty.util.AttributeKey<T> p0); + <T> io.netty.util.Attribute<T> attr(io.netty.util.AttributeKey<T> p0); +} diff --git a/java/ql/test/stubs/netty-4.1.x/io/netty/util/ByteProcessor.java b/java/ql/test/stubs/netty-4.1.x/io/netty/util/ByteProcessor.java new file mode 100644 index 00000000000..197b5718d3e --- /dev/null +++ b/java/ql/test/stubs/netty-4.1.x/io/netty/util/ByteProcessor.java @@ -0,0 +1,22 @@ +// Generated automatically from io.netty.util.ByteProcessor for testing purposes + +package io.netty.util; + + +public interface ByteProcessor +{ + boolean process(byte p0); + static ByteProcessor FIND_ASCII_SPACE = null; + static ByteProcessor FIND_COMMA = null; + static ByteProcessor FIND_CR = null; + static ByteProcessor FIND_CRLF = null; + static ByteProcessor FIND_LF = null; + static ByteProcessor FIND_LINEAR_WHITESPACE = null; + static ByteProcessor FIND_NON_CR = null; + static ByteProcessor FIND_NON_CRLF = null; + static ByteProcessor FIND_NON_LF = null; + static ByteProcessor FIND_NON_LINEAR_WHITESPACE = null; + static ByteProcessor FIND_NON_NUL = null; + static ByteProcessor FIND_NUL = null; + static ByteProcessor FIND_SEMI_COLON = null; +} diff --git a/java/ql/test/stubs/netty-4.1.x/io/netty/util/Constant.java b/java/ql/test/stubs/netty-4.1.x/io/netty/util/Constant.java new file mode 100644 index 00000000000..81b3077356b --- /dev/null +++ b/java/ql/test/stubs/netty-4.1.x/io/netty/util/Constant.java @@ -0,0 +1,10 @@ +// Generated automatically from io.netty.util.Constant for testing purposes + +package io.netty.util; + + +public interface Constant<T extends Constant<T>> extends java.lang.Comparable<T> +{ + String name(); + int id(); +} diff --git a/java/ql/test/stubs/netty-4.1.x/io/netty/util/ReferenceCounted.java b/java/ql/test/stubs/netty-4.1.x/io/netty/util/ReferenceCounted.java new file mode 100644 index 00000000000..219a5523ed3 --- /dev/null +++ b/java/ql/test/stubs/netty-4.1.x/io/netty/util/ReferenceCounted.java @@ -0,0 +1,15 @@ +// Generated automatically from io.netty.util.ReferenceCounted for testing purposes + +package io.netty.util; + + +public interface ReferenceCounted +{ + ReferenceCounted retain(); + ReferenceCounted retain(int p0); + ReferenceCounted touch(); + ReferenceCounted touch(Object p0); + boolean release(); + boolean release(int p0); + int refCnt(); +} diff --git a/java/ql/test/stubs/netty-4.1.x/io/netty/util/concurrent/OrderedEventExecutor.java b/java/ql/test/stubs/netty-4.1.x/io/netty/util/concurrent/OrderedEventExecutor.java new file mode 100644 index 00000000000..273107cb6db --- /dev/null +++ b/java/ql/test/stubs/netty-4.1.x/io/netty/util/concurrent/OrderedEventExecutor.java @@ -0,0 +1,9 @@ +// Generated automatically from io.netty.util.concurrent.OrderedEventExecutor for testing purposes + +package io.netty.util.concurrent; + +import io.netty.util.concurrent.EventExecutor; + +public interface OrderedEventExecutor extends EventExecutor +{ +} From f88780cdd1eee07b62682178447e8b9d5c6606e6 Mon Sep 17 00:00:00 2001 From: Joe Farebrother <joefarebrother@github.com> Date: Tue, 14 Feb 2023 16:14:55 +0000 Subject: [PATCH 362/631] Add some tests; improve buffer models --- java/ql/lib/ext/io.netty.buffer.model.yml | 90 ++++++++++--------- .../frameworks/netty/manual/Test.java | 31 +++++++ .../frameworks/netty/manual/options | 1 + .../frameworks/netty/manual/test.expected | 0 .../frameworks/netty/manual/test.ql | 11 +++ 5 files changed, 91 insertions(+), 42 deletions(-) create mode 100644 java/ql/test/library-tests/frameworks/netty/manual/Test.java create mode 100644 java/ql/test/library-tests/frameworks/netty/manual/options create mode 100644 java/ql/test/library-tests/frameworks/netty/manual/test.expected create mode 100644 java/ql/test/library-tests/frameworks/netty/manual/test.ql diff --git a/java/ql/lib/ext/io.netty.buffer.model.yml b/java/ql/lib/ext/io.netty.buffer.model.yml index fd203e2afb0..86933215bd4 100644 --- a/java/ql/lib/ext/io.netty.buffer.model.yml +++ b/java/ql/lib/ext/io.netty.buffer.model.yml @@ -12,66 +12,72 @@ extensions: - ["io.netty.buffer", "ByteBuf", True, "discardSomeReadBytes", "()", "", "Argument[-1]", "ReturnValue", "value", "manual"] - ["io.netty.buffer", "ByteBuf", True, "duplicate", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - ["io.netty.buffer", "ByteBuf", True, "ensureWritable", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "getByte", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "getBytes", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "getChar", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "getCharSequence", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "getBytes", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] - ["io.netty.buffer", "ByteBuf", True, "markReaderIndex", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] - ["io.netty.buffer", "ByteBuf", True, "markWriterIndex", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] - ["io.netty.buffer", "ByteBuf", True, "nioBuffer", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - ["io.netty.buffer", "ByteBuf", True, "nioBuffers", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - ["io.netty.buffer", "ByteBuf", True, "order", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "readBytes", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "readChar", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "readCharSequence", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "readSlice", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "readBytes", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "readerIndex", "(int)", "", "Argument[-1]", "ReturnValue", "value", "manual"] - ["io.netty.buffer", "ByteBuf", True, "resetReaderIndex", "()", "", "Argument[-1]", "ReturnValue", "value", "manual"] - ["io.netty.buffer", "ByteBuf", True, "resetWriterIndex", "()", "", "Argument[-1]", "ReturnValue", "value", "manual"] - ["io.netty.buffer", "ByteBuf", True, "retainedDuplicate", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - ["io.netty.buffer", "ByteBuf", True, "retainedSlice", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "setBoolean", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "setByte", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "setBytes", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "setChar", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "setCharSequence", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "setDouble", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "setDoubleLE", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "setFloat", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "setFloatLE", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "setIndex", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "setInt", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "setIntLE", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "setLong", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "setLongLE", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "setMedium", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "setMediumLE", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "setShort", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "setShortLE", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "setBoolean", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "setByte", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "setBytes", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "setChar", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "setCharSequence", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "setDouble", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "setDoubleLE", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "setFloat", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "setFloatLE", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "setIndex", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "setInt", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "setIntLE", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "setLong", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "setLongLE", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "setMedium", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "setMediumLE", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "setShort", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "setShortLE", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "setZero", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "skipBytes", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] - ["io.netty.buffer", "ByteBuf", True, "slice", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - ["io.netty.buffer", "ByteBuf", True, "toString", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - ["io.netty.buffer", "ByteBuf", True, "unwrap", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "writeByte", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "writeBytes", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "writeChar", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "writeCharSequence", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "writeDouble", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "writeDoubleLE", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "writeFloat", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "writeFloatLE", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "writeInt", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "writeIntLE", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "writeLong", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "writeLongLE", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "writeMedium", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "writeMediumLE", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "writeShort", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "writeShortLE", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "writeByte", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "writeBytes", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "writeChar", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "writeCharSequence", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "writeDouble", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "writeDoubleLE", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "writeFloat", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "writeFloatLE", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "writeInt", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "writeIntLE", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "writeLong", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "writeLongLE", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "writeMedium", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "writeMediumLE", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "writeShort", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "writeShortLE", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "writeZero", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "writerIndex", "(int)", "", "Argument[-1]", "ReturnValue", "value", "manual"] - ["io.netty.buffer", "ByteBufHolder", True, "copy", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - ["io.netty.buffer", "ByteBufHolder", True, "content", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - ["io.netty.buffer", "ByteBufHolder", True, "duplicate", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - ["io.netty.buffer", "ByteBufHolder", True, "retainedDuplicate", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "getByte", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - ["io.netty.buffer", "ByteBuf", True, "getBytes", "", "", "Argument[-1]", "Argument[1]", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "getChar", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "getCharSequence", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "readByte", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - ["io.netty.buffer", "ByteBuf", True, "readBytes", "", "", "Argument[-1]", "Argument[0]", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "readChar", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "readCharSequence", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "readSlice", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - ["io.netty.buffer", "ByteBuf", True, "setByte", "", "", "Argument[1]", "Argument[-1]", "taint", "manual"] - ["io.netty.buffer", "ByteBuf", True, "setBytes", "", "", "Argument[1]", "Argument[-1]", "taint", "manual"] - ["io.netty.buffer", "ByteBuf", True, "setChar", "", "", "Argument[1]", "Argument[-1]", "taint", "manual"] diff --git a/java/ql/test/library-tests/frameworks/netty/manual/Test.java b/java/ql/test/library-tests/frameworks/netty/manual/Test.java new file mode 100644 index 00000000000..3a0f7c6406f --- /dev/null +++ b/java/ql/test/library-tests/frameworks/netty/manual/Test.java @@ -0,0 +1,31 @@ +import io.netty.channel.*; +import io.netty.buffer.ByteBuf; +// import io.netty.handler.codec.*; +// import io.netty.handler.codec.http.*; + +class Test { + static <T> T source() { return null; } + static void sink(Object s) {} + + class A extends ChannelInboundHandlerAdapter { + public void channelRead(ChannelHandlerContext ctx, Object msg) { + sink(msg); // $hasTaintFlow + } + } + + class B extends ChannelInboundHandlerAdapter { + public void channelRead(ChannelHandlerContext ctx, Object msg) { + ByteBuf bb = (ByteBuf) msg; + byte[] data = new byte[1024]; + bb.readBytes(data); + sink(data); // $hasTaintFlow + } + } + + void test(ByteBuf bb, byte[] x) { + byte[] src = source(); + bb.readBytes(x).setLong(3, 4).readerIndex(2).writeBytes(src).skipBytes(2); + sink(bb); // $ hasTaintFlow + sink(x); + } +} \ No newline at end of file diff --git a/java/ql/test/library-tests/frameworks/netty/manual/options b/java/ql/test/library-tests/frameworks/netty/manual/options new file mode 100644 index 00000000000..9c4517826cc --- /dev/null +++ b/java/ql/test/library-tests/frameworks/netty/manual/options @@ -0,0 +1 @@ +//semmle-extractor-options: --javac-args -cp ${testdir}/../../../../stubs/netty-4.1.x \ No newline at end of file diff --git a/java/ql/test/library-tests/frameworks/netty/manual/test.expected b/java/ql/test/library-tests/frameworks/netty/manual/test.expected new file mode 100644 index 00000000000..e69de29bb2d diff --git a/java/ql/test/library-tests/frameworks/netty/manual/test.ql b/java/ql/test/library-tests/frameworks/netty/manual/test.ql new file mode 100644 index 00000000000..10c5f909c2f --- /dev/null +++ b/java/ql/test/library-tests/frameworks/netty/manual/test.ql @@ -0,0 +1,11 @@ +import java +import semmle.code.java.dataflow.FlowSources +import TestUtilities.InlineFlowTest + +class Conf extends DefaultTaintFlowConf { + override predicate isSource(DataFlow::Node node) { + super.isSource(node) + or + node instanceof RemoteFlowSource + } +} From 43cfbb228a391c5d418adaed5c9f447a60ae9ece Mon Sep 17 00:00:00 2001 From: Joe Farebrother <joefarebrother@github.com> Date: Tue, 14 Feb 2023 17:22:32 +0000 Subject: [PATCH 363/631] Add additional tests for http stuff + corresponding stubs --- .../frameworks/netty/manual/Test.java | 49 +++++++- .../io/netty/buffer/ByteBufHolder.java | 19 +++ .../channel/SimpleChannelInboundHandler.java | 17 +++ .../handler/codec/ByteToMessageDecoder.java | 36 ++++++ .../io/netty/handler/codec/DecoderResult.java | 21 ++++ .../handler/codec/DecoderResultProvider.java | 11 ++ .../io/netty/handler/codec/Headers.java | 105 ++++++++++++++++ .../handler/codec/http/FullHttpMessage.java | 19 +++ .../handler/codec/http/FullHttpRequest.java | 24 ++++ .../netty/handler/codec/http/HttpContent.java | 19 +++ .../netty/handler/codec/http/HttpHeaders.java | 119 ++++++++++++++++++ .../netty/handler/codec/http/HttpMessage.java | 15 +++ .../netty/handler/codec/http/HttpMethod.java | 27 ++++ .../netty/handler/codec/http/HttpObject.java | 11 ++ .../netty/handler/codec/http/HttpRequest.java | 18 +++ .../netty/handler/codec/http/HttpVersion.java | 23 ++++ .../handler/codec/http/LastHttpContent.java | 21 ++++ .../netty/handler/codec/http2/Http2Flags.java | 33 +++++ .../codec/http2/Http2FrameAdapter.java | 28 +++++ .../codec/http2/Http2FrameListener.java | 26 ++++ .../handler/codec/http2/Http2Headers.java | 24 ++++ .../handler/codec/http2/Http2Settings.java | 29 +++++ .../io/netty/util/AsciiString.java | 119 ++++++++++++++++++ .../io/netty/util/HashingStrategy.java | 11 ++ .../netty-4.1.x/io/netty/util/Signal.java | 21 ++++ .../util/collection/CharObjectHashMap.java | 38 ++++++ .../netty/util/collection/CharObjectMap.java | 20 +++ 27 files changed, 901 insertions(+), 2 deletions(-) create mode 100644 java/ql/test/stubs/netty-4.1.x/io/netty/buffer/ByteBufHolder.java create mode 100644 java/ql/test/stubs/netty-4.1.x/io/netty/channel/SimpleChannelInboundHandler.java create mode 100644 java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/ByteToMessageDecoder.java create mode 100644 java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/DecoderResult.java create mode 100644 java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/DecoderResultProvider.java create mode 100644 java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/Headers.java create mode 100644 java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http/FullHttpMessage.java create mode 100644 java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http/FullHttpRequest.java create mode 100644 java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http/HttpContent.java create mode 100644 java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http/HttpHeaders.java create mode 100644 java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http/HttpMessage.java create mode 100644 java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http/HttpMethod.java create mode 100644 java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http/HttpObject.java create mode 100644 java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http/HttpRequest.java create mode 100644 java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http/HttpVersion.java create mode 100644 java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http/LastHttpContent.java create mode 100644 java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http2/Http2Flags.java create mode 100644 java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http2/Http2FrameAdapter.java create mode 100644 java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http2/Http2FrameListener.java create mode 100644 java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http2/Http2Headers.java create mode 100644 java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http2/Http2Settings.java create mode 100644 java/ql/test/stubs/netty-4.1.x/io/netty/util/AsciiString.java create mode 100644 java/ql/test/stubs/netty-4.1.x/io/netty/util/HashingStrategy.java create mode 100644 java/ql/test/stubs/netty-4.1.x/io/netty/util/Signal.java create mode 100644 java/ql/test/stubs/netty-4.1.x/io/netty/util/collection/CharObjectHashMap.java create mode 100644 java/ql/test/stubs/netty-4.1.x/io/netty/util/collection/CharObjectMap.java diff --git a/java/ql/test/library-tests/frameworks/netty/manual/Test.java b/java/ql/test/library-tests/frameworks/netty/manual/Test.java index 3a0f7c6406f..58150659712 100644 --- a/java/ql/test/library-tests/frameworks/netty/manual/Test.java +++ b/java/ql/test/library-tests/frameworks/netty/manual/Test.java @@ -1,7 +1,10 @@ import io.netty.channel.*; import io.netty.buffer.ByteBuf; -// import io.netty.handler.codec.*; -// import io.netty.handler.codec.http.*; +import io.netty.handler.codec.*; +import io.netty.handler.codec.http.*; +import io.netty.handler.codec.http2.*; + +import java.util.List; class Test { static <T> T source() { return null; } @@ -28,4 +31,46 @@ class Test { sink(bb); // $ hasTaintFlow sink(x); } + + class C extends ByteToMessageDecoder { + public void callDecode(ChannelHandlerContext ctx, ByteBuf msg, List<Object> out) { + sink(msg); // $ hasTaintFlow + } + + public void decode(ChannelHandlerContext ctx, ByteBuf msg, List<Object> out) { + sink(msg); // $ hasTaintFlow + } + + public void decodeLast(ChannelHandlerContext ctx, ByteBuf msg, List<Object> out) { + sink(msg); // $ hasTaintFlow + } + } + + class D extends SimpleChannelInboundHandler<FullHttpRequest> { + public void channelRead0(ChannelHandlerContext ctx, FullHttpRequest msg) { + sink(msg.uri()); // $ hasTaintFlow + sink(msg.headers().get("X-blah")); // $ hasTaintFlow + sink(msg.content()); // $ hasTaintFlow + } + } + + class E extends Http2FrameAdapter { + public int onDataRead(ChannelHandlerContext ctx, int streamId, ByteBuf data, int padding, boolean endOfStream) { + sink(data); // $ hasTaintFlow + return 0; + } + + public void onHeadersRead(ChannelHandlerContext ctx, int streamId, Http2Headers headers, int padding, boolean endStream) { + sink(headers.get("X-blah")); // $ hasTaintFlow + sink(headers.path()); // $ hasTaintFlow + } + + public void onPushPromiseRead(ChannelHandlerContext ctx, int streamId, int promisedStreamId, Http2Headers headers, int padding) { + sink(headers); // $ hasTaintFlow + } + + public void onUnknownFrame(ChannelHandlerContext ctx, byte frameType, int streamId, Http2Flags flags, ByteBuf payload) { + sink(payload); // $ hasTaintFlow + } + } } \ No newline at end of file diff --git a/java/ql/test/stubs/netty-4.1.x/io/netty/buffer/ByteBufHolder.java b/java/ql/test/stubs/netty-4.1.x/io/netty/buffer/ByteBufHolder.java new file mode 100644 index 00000000000..bed25be4032 --- /dev/null +++ b/java/ql/test/stubs/netty-4.1.x/io/netty/buffer/ByteBufHolder.java @@ -0,0 +1,19 @@ +// Generated automatically from io.netty.buffer.ByteBufHolder for testing purposes + +package io.netty.buffer; + +import io.netty.buffer.ByteBuf; +import io.netty.util.ReferenceCounted; + +public interface ByteBufHolder extends ReferenceCounted +{ + ByteBuf content(); + ByteBufHolder copy(); + ByteBufHolder duplicate(); + ByteBufHolder replace(ByteBuf p0); + ByteBufHolder retain(); + ByteBufHolder retain(int p0); + ByteBufHolder retainedDuplicate(); + ByteBufHolder touch(); + ByteBufHolder touch(Object p0); +} diff --git a/java/ql/test/stubs/netty-4.1.x/io/netty/channel/SimpleChannelInboundHandler.java b/java/ql/test/stubs/netty-4.1.x/io/netty/channel/SimpleChannelInboundHandler.java new file mode 100644 index 00000000000..f29b1ca2ebf --- /dev/null +++ b/java/ql/test/stubs/netty-4.1.x/io/netty/channel/SimpleChannelInboundHandler.java @@ -0,0 +1,17 @@ +// Generated automatically from io.netty.channel.SimpleChannelInboundHandler for testing purposes + +package io.netty.channel; + +import io.netty.channel.ChannelHandlerContext; +import io.netty.channel.ChannelInboundHandlerAdapter; + +abstract public class SimpleChannelInboundHandler<I> extends ChannelInboundHandlerAdapter +{ + protected SimpleChannelInboundHandler(){} + protected SimpleChannelInboundHandler(Class<? extends I> p0){} + protected SimpleChannelInboundHandler(Class<? extends I> p0, boolean p1){} + protected SimpleChannelInboundHandler(boolean p0){} + protected abstract void channelRead0(ChannelHandlerContext p0, I p1); + public boolean acceptInboundMessage(Object p0){ return false; } + public void channelRead(ChannelHandlerContext p0, Object p1){} +} diff --git a/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/ByteToMessageDecoder.java b/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/ByteToMessageDecoder.java new file mode 100644 index 00000000000..bc5b75fbeeb --- /dev/null +++ b/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/ByteToMessageDecoder.java @@ -0,0 +1,36 @@ +// Generated automatically from io.netty.handler.codec.ByteToMessageDecoder for testing purposes + +package io.netty.handler.codec; + +import io.netty.buffer.ByteBuf; +import io.netty.buffer.ByteBufAllocator; +import io.netty.channel.ChannelHandlerContext; +import io.netty.channel.ChannelInboundHandlerAdapter; +import java.util.List; + +abstract public class ByteToMessageDecoder extends ChannelInboundHandlerAdapter +{ + protected ByteBuf internalBuffer(){ return null; } + protected ByteToMessageDecoder(){} + protected abstract void decode(ChannelHandlerContext p0, ByteBuf p1, List<Object> p2); + protected final void discardSomeReadBytes(){} + protected int actualReadableBytes(){ return 0; } + protected void callDecode(ChannelHandlerContext p0, ByteBuf p1, List<Object> p2){} + protected void decodeLast(ChannelHandlerContext p0, ByteBuf p1, List<Object> p2){} + protected void handlerRemoved0(ChannelHandlerContext p0){} + public boolean isSingleDecode(){ return false; } + public final void handlerRemoved(ChannelHandlerContext p0){} + public static ByteToMessageDecoder.Cumulator COMPOSITE_CUMULATOR = null; + public static ByteToMessageDecoder.Cumulator MERGE_CUMULATOR = null; + public void channelInactive(ChannelHandlerContext p0){} + public void channelRead(ChannelHandlerContext p0, Object p1){} + public void channelReadComplete(ChannelHandlerContext p0){} + public void setCumulator(ByteToMessageDecoder.Cumulator p0){} + public void setDiscardAfterReads(int p0){} + public void setSingleDecode(boolean p0){} + public void userEventTriggered(ChannelHandlerContext p0, Object p1){} + static public interface Cumulator + { + ByteBuf cumulate(ByteBufAllocator p0, ByteBuf p1, ByteBuf p2); + } +} diff --git a/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/DecoderResult.java b/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/DecoderResult.java new file mode 100644 index 00000000000..50ef9ccb33d --- /dev/null +++ b/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/DecoderResult.java @@ -0,0 +1,21 @@ +// Generated automatically from io.netty.handler.codec.DecoderResult for testing purposes + +package io.netty.handler.codec; + +import io.netty.util.Signal; + +public class DecoderResult +{ + protected DecoderResult() {} + protected DecoderResult(Throwable p0){} + protected static Signal SIGNAL_SUCCESS = null; + protected static Signal SIGNAL_UNFINISHED = null; + public String toString(){ return null; } + public Throwable cause(){ return null; } + public boolean isFailure(){ return false; } + public boolean isFinished(){ return false; } + public boolean isSuccess(){ return false; } + public static DecoderResult SUCCESS = null; + public static DecoderResult UNFINISHED = null; + public static DecoderResult failure(Throwable p0){ return null; } +} diff --git a/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/DecoderResultProvider.java b/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/DecoderResultProvider.java new file mode 100644 index 00000000000..341fea20bc1 --- /dev/null +++ b/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/DecoderResultProvider.java @@ -0,0 +1,11 @@ +// Generated automatically from io.netty.handler.codec.DecoderResultProvider for testing purposes + +package io.netty.handler.codec; + +import io.netty.handler.codec.DecoderResult; + +public interface DecoderResultProvider +{ + DecoderResult decoderResult(); + void setDecoderResult(DecoderResult p0); +} diff --git a/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/Headers.java b/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/Headers.java new file mode 100644 index 00000000000..98830019ac1 --- /dev/null +++ b/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/Headers.java @@ -0,0 +1,105 @@ +// Generated automatically from io.netty.handler.codec.Headers for testing purposes + +package io.netty.handler.codec; + +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; + +public interface Headers<K, V, T extends Headers<K, V, T>> extends Iterable<Map.Entry<K, V>> +{ + Boolean getBoolean(K p0); + Boolean getBooleanAndRemove(K p0); + Byte getByte(K p0); + Byte getByteAndRemove(K p0); + Character getChar(K p0); + Character getCharAndRemove(K p0); + Double getDouble(K p0); + Double getDoubleAndRemove(K p0); + Float getFloat(K p0); + Float getFloatAndRemove(K p0); + Integer getInt(K p0); + Integer getIntAndRemove(K p0); + Iterator<Map.Entry<K, V>> iterator(); + List<V> getAll(K p0); + List<V> getAllAndRemove(K p0); + Long getLong(K p0); + Long getLongAndRemove(K p0); + Long getTimeMillis(K p0); + Long getTimeMillisAndRemove(K p0); + Set<K> names(); + Short getShort(K p0); + Short getShortAndRemove(K p0); + T add(Headers<? extends K, ? extends V, ? extends Object> p0); + T add(K p0, Iterable<? extends V> p1); + T add(K p0, V p1); + T add(K p0, V... p1); + T addBoolean(K p0, boolean p1); + T addByte(K p0, byte p1); + T addChar(K p0, char p1); + T addDouble(K p0, double p1); + T addFloat(K p0, float p1); + T addInt(K p0, int p1); + T addLong(K p0, long p1); + T addObject(K p0, Iterable<? extends Object> p1); + T addObject(K p0, Object p1); + T addObject(K p0, Object... p1); + T addShort(K p0, short p1); + T addTimeMillis(K p0, long p1); + T clear(); + T set(Headers<? extends K, ? extends V, ? extends Object> p0); + T set(K p0, Iterable<? extends V> p1); + T set(K p0, V p1); + T set(K p0, V... p1); + T setAll(Headers<? extends K, ? extends V, ? extends Object> p0); + T setBoolean(K p0, boolean p1); + T setByte(K p0, byte p1); + T setChar(K p0, char p1); + T setDouble(K p0, double p1); + T setFloat(K p0, float p1); + T setInt(K p0, int p1); + T setLong(K p0, long p1); + T setObject(K p0, Iterable<? extends Object> p1); + T setObject(K p0, Object p1); + T setObject(K p0, Object... p1); + T setShort(K p0, short p1); + T setTimeMillis(K p0, long p1); + V get(K p0); + V get(K p0, V p1); + V getAndRemove(K p0); + V getAndRemove(K p0, V p1); + boolean contains(K p0); + boolean contains(K p0, V p1); + boolean containsBoolean(K p0, boolean p1); + boolean containsByte(K p0, byte p1); + boolean containsChar(K p0, char p1); + boolean containsDouble(K p0, double p1); + boolean containsFloat(K p0, float p1); + boolean containsInt(K p0, int p1); + boolean containsLong(K p0, long p1); + boolean containsObject(K p0, Object p1); + boolean containsShort(K p0, short p1); + boolean containsTimeMillis(K p0, long p1); + boolean getBoolean(K p0, boolean p1); + boolean getBooleanAndRemove(K p0, boolean p1); + boolean isEmpty(); + boolean remove(K p0); + byte getByte(K p0, byte p1); + byte getByteAndRemove(K p0, byte p1); + char getChar(K p0, char p1); + char getCharAndRemove(K p0, char p1); + double getDouble(K p0, double p1); + double getDoubleAndRemove(K p0, double p1); + float getFloat(K p0, float p1); + float getFloatAndRemove(K p0, float p1); + int getInt(K p0, int p1); + int getIntAndRemove(K p0, int p1); + int size(); + long getLong(K p0, long p1); + long getLongAndRemove(K p0, long p1); + long getTimeMillis(K p0, long p1); + long getTimeMillisAndRemove(K p0, long p1); + short getShort(K p0, short p1); + short getShortAndRemove(K p0, short p1); +} diff --git a/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http/FullHttpMessage.java b/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http/FullHttpMessage.java new file mode 100644 index 00000000000..7ee11bc4b41 --- /dev/null +++ b/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http/FullHttpMessage.java @@ -0,0 +1,19 @@ +// Generated automatically from io.netty.handler.codec.http.FullHttpMessage for testing purposes + +package io.netty.handler.codec.http; + +import io.netty.buffer.ByteBuf; +import io.netty.handler.codec.http.HttpMessage; +import io.netty.handler.codec.http.LastHttpContent; + +public interface FullHttpMessage extends HttpMessage, LastHttpContent +{ + FullHttpMessage copy(); + FullHttpMessage duplicate(); + FullHttpMessage replace(ByteBuf p0); + FullHttpMessage retain(); + FullHttpMessage retain(int p0); + FullHttpMessage retainedDuplicate(); + FullHttpMessage touch(); + FullHttpMessage touch(Object p0); +} diff --git a/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http/FullHttpRequest.java b/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http/FullHttpRequest.java new file mode 100644 index 00000000000..5439e5179df --- /dev/null +++ b/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http/FullHttpRequest.java @@ -0,0 +1,24 @@ +// Generated automatically from io.netty.handler.codec.http.FullHttpRequest for testing purposes + +package io.netty.handler.codec.http; + +import io.netty.buffer.ByteBuf; +import io.netty.handler.codec.http.FullHttpMessage; +import io.netty.handler.codec.http.HttpMethod; +import io.netty.handler.codec.http.HttpRequest; +import io.netty.handler.codec.http.HttpVersion; + +public interface FullHttpRequest extends FullHttpMessage, HttpRequest +{ + FullHttpRequest copy(); + FullHttpRequest duplicate(); + FullHttpRequest replace(ByteBuf p0); + FullHttpRequest retain(); + FullHttpRequest retain(int p0); + FullHttpRequest retainedDuplicate(); + FullHttpRequest setMethod(HttpMethod p0); + FullHttpRequest setProtocolVersion(HttpVersion p0); + FullHttpRequest setUri(String p0); + FullHttpRequest touch(); + FullHttpRequest touch(Object p0); +} diff --git a/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http/HttpContent.java b/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http/HttpContent.java new file mode 100644 index 00000000000..36214511ffa --- /dev/null +++ b/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http/HttpContent.java @@ -0,0 +1,19 @@ +// Generated automatically from io.netty.handler.codec.http.HttpContent for testing purposes + +package io.netty.handler.codec.http; + +import io.netty.buffer.ByteBuf; +import io.netty.buffer.ByteBufHolder; +import io.netty.handler.codec.http.HttpObject; + +public interface HttpContent extends ByteBufHolder, HttpObject +{ + HttpContent copy(); + HttpContent duplicate(); + HttpContent replace(ByteBuf p0); + HttpContent retain(); + HttpContent retain(int p0); + HttpContent retainedDuplicate(); + HttpContent touch(); + HttpContent touch(Object p0); +} diff --git a/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http/HttpHeaders.java b/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http/HttpHeaders.java new file mode 100644 index 00000000000..0f436cf64cb --- /dev/null +++ b/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http/HttpHeaders.java @@ -0,0 +1,119 @@ +// Generated automatically from io.netty.handler.codec.http.HttpHeaders for testing purposes + +package io.netty.handler.codec.http; + +import io.netty.buffer.ByteBuf; +import io.netty.handler.codec.http.HttpMessage; +import java.util.Date; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; + +abstract public class HttpHeaders implements Iterable<Map.Entry<String, String>> +{ + protected HttpHeaders(){} + public HttpHeaders add(CharSequence p0, Iterable<? extends Object> p1){ return null; } + public HttpHeaders add(CharSequence p0, Object p1){ return null; } + public HttpHeaders add(HttpHeaders p0){ return null; } + public HttpHeaders copy(){ return null; } + public HttpHeaders remove(CharSequence p0){ return null; } + public HttpHeaders set(CharSequence p0, Iterable<? extends Object> p1){ return null; } + public HttpHeaders set(CharSequence p0, Object p1){ return null; } + public HttpHeaders set(HttpHeaders p0){ return null; } + public HttpHeaders setAll(HttpHeaders p0){ return null; } + public Iterator<? extends CharSequence> valueCharSequenceIterator(CharSequence p0){ return null; } + public Iterator<String> valueStringIterator(CharSequence p0){ return null; } + public List<String> getAll(CharSequence p0){ return null; } + public String get(CharSequence p0){ return null; } + public String get(CharSequence p0, String p1){ return null; } + public String toString(){ return null; } + public abstract HttpHeaders add(String p0, Iterable<? extends Object> p1); + public abstract HttpHeaders add(String p0, Object p1); + public abstract HttpHeaders addInt(CharSequence p0, int p1); + public abstract HttpHeaders addShort(CharSequence p0, short p1); + public abstract HttpHeaders clear(); + public abstract HttpHeaders remove(String p0); + public abstract HttpHeaders set(String p0, Iterable<? extends Object> p1); + public abstract HttpHeaders set(String p0, Object p1); + public abstract HttpHeaders setInt(CharSequence p0, int p1); + public abstract HttpHeaders setShort(CharSequence p0, short p1); + public abstract Integer getInt(CharSequence p0); + public abstract Iterator<Map.Entry<CharSequence, CharSequence>> iteratorCharSequence(); + public abstract Iterator<Map.Entry<String, String>> iterator(); + public abstract List<Map.Entry<String, String>> entries(); + public abstract List<String> getAll(String p0); + public abstract Long getTimeMillis(CharSequence p0); + public abstract Set<String> names(); + public abstract Short getShort(CharSequence p0); + public abstract String get(String p0); + public abstract boolean contains(String p0); + public abstract boolean isEmpty(); + public abstract int getInt(CharSequence p0, int p1); + public abstract int size(); + public abstract long getTimeMillis(CharSequence p0, long p1); + public abstract short getShort(CharSequence p0, short p1); + public boolean contains(CharSequence p0){ return false; } + public boolean contains(CharSequence p0, CharSequence p1, boolean p2){ return false; } + public boolean contains(String p0, String p1, boolean p2){ return false; } + public boolean containsValue(CharSequence p0, CharSequence p1, boolean p2){ return false; } + public final Iterator<Map.Entry<String, String>> iteratorAsString(){ return null; } + public final List<String> getAllAsString(CharSequence p0){ return null; } + public final String getAsString(CharSequence p0){ return null; } + public static CharSequence newEntity(String p0){ return null; } + public static Date getDate(HttpMessage p0){ return null; } + public static Date getDate(HttpMessage p0, Date p1){ return null; } + public static Date getDateHeader(HttpMessage p0, CharSequence p1){ return null; } + public static Date getDateHeader(HttpMessage p0, CharSequence p1, Date p2){ return null; } + public static Date getDateHeader(HttpMessage p0, String p1){ return null; } + public static Date getDateHeader(HttpMessage p0, String p1, Date p2){ return null; } + public static HttpHeaders EMPTY_HEADERS = null; + public static String getHeader(HttpMessage p0, CharSequence p1){ return null; } + public static String getHeader(HttpMessage p0, CharSequence p1, String p2){ return null; } + public static String getHeader(HttpMessage p0, String p1){ return null; } + public static String getHeader(HttpMessage p0, String p1, String p2){ return null; } + public static String getHost(HttpMessage p0){ return null; } + public static String getHost(HttpMessage p0, String p1){ return null; } + public static boolean equalsIgnoreCase(CharSequence p0, CharSequence p1){ return false; } + public static boolean is100ContinueExpected(HttpMessage p0){ return false; } + public static boolean isContentLengthSet(HttpMessage p0){ return false; } + public static boolean isKeepAlive(HttpMessage p0){ return false; } + public static boolean isTransferEncodingChunked(HttpMessage p0){ return false; } + public static int getIntHeader(HttpMessage p0, CharSequence p1){ return 0; } + public static int getIntHeader(HttpMessage p0, CharSequence p1, int p2){ return 0; } + public static int getIntHeader(HttpMessage p0, String p1){ return 0; } + public static int getIntHeader(HttpMessage p0, String p1, int p2){ return 0; } + public static long getContentLength(HttpMessage p0){ return 0; } + public static long getContentLength(HttpMessage p0, long p1){ return 0; } + public static void addDateHeader(HttpMessage p0, CharSequence p1, Date p2){} + public static void addDateHeader(HttpMessage p0, String p1, Date p2){} + public static void addHeader(HttpMessage p0, CharSequence p1, Object p2){} + public static void addHeader(HttpMessage p0, String p1, Object p2){} + public static void addIntHeader(HttpMessage p0, CharSequence p1, int p2){} + public static void addIntHeader(HttpMessage p0, String p1, int p2){} + public static void clearHeaders(HttpMessage p0){} + public static void encodeAscii(CharSequence p0, ByteBuf p1){} + public static void removeHeader(HttpMessage p0, CharSequence p1){} + public static void removeHeader(HttpMessage p0, String p1){} + public static void removeTransferEncodingChunked(HttpMessage p0){} + public static void set100ContinueExpected(HttpMessage p0){} + public static void set100ContinueExpected(HttpMessage p0, boolean p1){} + public static void setContentLength(HttpMessage p0, long p1){} + public static void setDate(HttpMessage p0, Date p1){} + public static void setDateHeader(HttpMessage p0, CharSequence p1, Date p2){} + public static void setDateHeader(HttpMessage p0, CharSequence p1, Iterable<Date> p2){} + public static void setDateHeader(HttpMessage p0, String p1, Date p2){} + public static void setDateHeader(HttpMessage p0, String p1, Iterable<Date> p2){} + public static void setHeader(HttpMessage p0, CharSequence p1, Iterable<? extends Object> p2){} + public static void setHeader(HttpMessage p0, CharSequence p1, Object p2){} + public static void setHeader(HttpMessage p0, String p1, Iterable<? extends Object> p2){} + public static void setHeader(HttpMessage p0, String p1, Object p2){} + public static void setHost(HttpMessage p0, CharSequence p1){} + public static void setHost(HttpMessage p0, String p1){} + public static void setIntHeader(HttpMessage p0, CharSequence p1, Iterable<Integer> p2){} + public static void setIntHeader(HttpMessage p0, CharSequence p1, int p2){} + public static void setIntHeader(HttpMessage p0, String p1, Iterable<Integer> p2){} + public static void setIntHeader(HttpMessage p0, String p1, int p2){} + public static void setKeepAlive(HttpMessage p0, boolean p1){} + public static void setTransferEncodingChunked(HttpMessage p0){} +} diff --git a/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http/HttpMessage.java b/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http/HttpMessage.java new file mode 100644 index 00000000000..7e57a70a5db --- /dev/null +++ b/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http/HttpMessage.java @@ -0,0 +1,15 @@ +// Generated automatically from io.netty.handler.codec.http.HttpMessage for testing purposes + +package io.netty.handler.codec.http; + +import io.netty.handler.codec.http.HttpHeaders; +import io.netty.handler.codec.http.HttpObject; +import io.netty.handler.codec.http.HttpVersion; + +public interface HttpMessage extends HttpObject +{ + HttpHeaders headers(); + HttpMessage setProtocolVersion(HttpVersion p0); + HttpVersion getProtocolVersion(); + HttpVersion protocolVersion(); +} diff --git a/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http/HttpMethod.java b/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http/HttpMethod.java new file mode 100644 index 00000000000..9ff2913feaf --- /dev/null +++ b/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http/HttpMethod.java @@ -0,0 +1,27 @@ +// Generated automatically from io.netty.handler.codec.http.HttpMethod for testing purposes + +package io.netty.handler.codec.http; + +import io.netty.util.AsciiString; + +public class HttpMethod implements Comparable<HttpMethod> +{ + protected HttpMethod() {} + public AsciiString asciiName(){ return null; } + public HttpMethod(String p0){} + public String name(){ return null; } + public String toString(){ return null; } + public boolean equals(Object p0){ return false; } + public int compareTo(HttpMethod p0){ return 0; } + public int hashCode(){ return 0; } + public static HttpMethod CONNECT = null; + public static HttpMethod DELETE = null; + public static HttpMethod GET = null; + public static HttpMethod HEAD = null; + public static HttpMethod OPTIONS = null; + public static HttpMethod PATCH = null; + public static HttpMethod POST = null; + public static HttpMethod PUT = null; + public static HttpMethod TRACE = null; + public static HttpMethod valueOf(String p0){ return null; } +} diff --git a/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http/HttpObject.java b/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http/HttpObject.java new file mode 100644 index 00000000000..6e38be4aa02 --- /dev/null +++ b/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http/HttpObject.java @@ -0,0 +1,11 @@ +// Generated automatically from io.netty.handler.codec.http.HttpObject for testing purposes + +package io.netty.handler.codec.http; + +import io.netty.handler.codec.DecoderResult; +import io.netty.handler.codec.DecoderResultProvider; + +public interface HttpObject extends DecoderResultProvider +{ + DecoderResult getDecoderResult(); +} diff --git a/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http/HttpRequest.java b/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http/HttpRequest.java new file mode 100644 index 00000000000..2c8f90ed109 --- /dev/null +++ b/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http/HttpRequest.java @@ -0,0 +1,18 @@ +// Generated automatically from io.netty.handler.codec.http.HttpRequest for testing purposes + +package io.netty.handler.codec.http; + +import io.netty.handler.codec.http.HttpMessage; +import io.netty.handler.codec.http.HttpMethod; +import io.netty.handler.codec.http.HttpVersion; + +public interface HttpRequest extends HttpMessage +{ + HttpMethod getMethod(); + HttpMethod method(); + HttpRequest setMethod(HttpMethod p0); + HttpRequest setProtocolVersion(HttpVersion p0); + HttpRequest setUri(String p0); + String getUri(); + String uri(); +} diff --git a/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http/HttpVersion.java b/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http/HttpVersion.java new file mode 100644 index 00000000000..50d133986c7 --- /dev/null +++ b/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http/HttpVersion.java @@ -0,0 +1,23 @@ +// Generated automatically from io.netty.handler.codec.http.HttpVersion for testing purposes + +package io.netty.handler.codec.http; + + +public class HttpVersion implements Comparable<HttpVersion> +{ + protected HttpVersion() {} + public HttpVersion(String p0, boolean p1){} + public HttpVersion(String p0, int p1, int p2, boolean p3){} + public String protocolName(){ return null; } + public String text(){ return null; } + public String toString(){ return null; } + public boolean equals(Object p0){ return false; } + public boolean isKeepAliveDefault(){ return false; } + public int compareTo(HttpVersion p0){ return 0; } + public int hashCode(){ return 0; } + public int majorVersion(){ return 0; } + public int minorVersion(){ return 0; } + public static HttpVersion HTTP_1_0 = null; + public static HttpVersion HTTP_1_1 = null; + public static HttpVersion valueOf(String p0){ return null; } +} diff --git a/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http/LastHttpContent.java b/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http/LastHttpContent.java new file mode 100644 index 00000000000..d5a6044926b --- /dev/null +++ b/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http/LastHttpContent.java @@ -0,0 +1,21 @@ +// Generated automatically from io.netty.handler.codec.http.LastHttpContent for testing purposes + +package io.netty.handler.codec.http; + +import io.netty.buffer.ByteBuf; +import io.netty.handler.codec.http.HttpContent; +import io.netty.handler.codec.http.HttpHeaders; + +public interface LastHttpContent extends HttpContent +{ + HttpHeaders trailingHeaders(); + LastHttpContent copy(); + LastHttpContent duplicate(); + LastHttpContent replace(ByteBuf p0); + LastHttpContent retain(); + LastHttpContent retain(int p0); + LastHttpContent retainedDuplicate(); + LastHttpContent touch(); + LastHttpContent touch(Object p0); + static LastHttpContent EMPTY_LAST_CONTENT = null; +} diff --git a/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http2/Http2Flags.java b/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http2/Http2Flags.java new file mode 100644 index 00000000000..5f3720ba581 --- /dev/null +++ b/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http2/Http2Flags.java @@ -0,0 +1,33 @@ +// Generated automatically from io.netty.handler.codec.http2.Http2Flags for testing purposes + +package io.netty.handler.codec.http2; + + +public class Http2Flags +{ + public Http2Flags ack(boolean p0){ return null; } + public Http2Flags endOfHeaders(boolean p0){ return null; } + public Http2Flags endOfStream(boolean p0){ return null; } + public Http2Flags paddingPresent(boolean p0){ return null; } + public Http2Flags priorityPresent(boolean p0){ return null; } + public Http2Flags setFlag(boolean p0, short p1){ return null; } + public Http2Flags(){} + public Http2Flags(short p0){} + public String toString(){ return null; } + public boolean ack(){ return false; } + public boolean endOfHeaders(){ return false; } + public boolean endOfStream(){ return false; } + public boolean equals(Object p0){ return false; } + public boolean isFlagSet(short p0){ return false; } + public boolean paddingPresent(){ return false; } + public boolean priorityPresent(){ return false; } + public int getNumPriorityBytes(){ return 0; } + public int getPaddingPresenceFieldLength(){ return 0; } + public int hashCode(){ return 0; } + public short value(){ return 0; } + public static short ACK = 0; + public static short END_HEADERS = 0; + public static short END_STREAM = 0; + public static short PADDED = 0; + public static short PRIORITY = 0; +} diff --git a/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http2/Http2FrameAdapter.java b/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http2/Http2FrameAdapter.java new file mode 100644 index 00000000000..b4a12ef3d48 --- /dev/null +++ b/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http2/Http2FrameAdapter.java @@ -0,0 +1,28 @@ +// Generated automatically from io.netty.handler.codec.http2.Http2FrameAdapter for testing purposes + +package io.netty.handler.codec.http2; + +import io.netty.buffer.ByteBuf; +import io.netty.channel.ChannelHandlerContext; +import io.netty.handler.codec.http2.Http2Flags; +import io.netty.handler.codec.http2.Http2FrameListener; +import io.netty.handler.codec.http2.Http2Headers; +import io.netty.handler.codec.http2.Http2Settings; + +public class Http2FrameAdapter implements Http2FrameListener +{ + public Http2FrameAdapter(){} + public int onDataRead(ChannelHandlerContext p0, int p1, ByteBuf p2, int p3, boolean p4){ return 0; } + public void onGoAwayRead(ChannelHandlerContext p0, int p1, long p2, ByteBuf p3){} + public void onHeadersRead(ChannelHandlerContext p0, int p1, Http2Headers p2, int p3, boolean p4){} + public void onHeadersRead(ChannelHandlerContext p0, int p1, Http2Headers p2, int p3, short p4, boolean p5, int p6, boolean p7){} + public void onPingAckRead(ChannelHandlerContext p0, long p1){} + public void onPingRead(ChannelHandlerContext p0, long p1){} + public void onPriorityRead(ChannelHandlerContext p0, int p1, int p2, short p3, boolean p4){} + public void onPushPromiseRead(ChannelHandlerContext p0, int p1, int p2, Http2Headers p3, int p4){} + public void onRstStreamRead(ChannelHandlerContext p0, int p1, long p2){} + public void onSettingsAckRead(ChannelHandlerContext p0){} + public void onSettingsRead(ChannelHandlerContext p0, Http2Settings p1){} + public void onUnknownFrame(ChannelHandlerContext p0, byte p1, int p2, Http2Flags p3, ByteBuf p4){} + public void onWindowUpdateRead(ChannelHandlerContext p0, int p1, int p2){} +} diff --git a/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http2/Http2FrameListener.java b/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http2/Http2FrameListener.java new file mode 100644 index 00000000000..5cdae13b92a --- /dev/null +++ b/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http2/Http2FrameListener.java @@ -0,0 +1,26 @@ +// Generated automatically from io.netty.handler.codec.http2.Http2FrameListener for testing purposes + +package io.netty.handler.codec.http2; + +import io.netty.buffer.ByteBuf; +import io.netty.channel.ChannelHandlerContext; +import io.netty.handler.codec.http2.Http2Flags; +import io.netty.handler.codec.http2.Http2Headers; +import io.netty.handler.codec.http2.Http2Settings; + +public interface Http2FrameListener +{ + int onDataRead(ChannelHandlerContext p0, int p1, ByteBuf p2, int p3, boolean p4); + void onGoAwayRead(ChannelHandlerContext p0, int p1, long p2, ByteBuf p3); + void onHeadersRead(ChannelHandlerContext p0, int p1, Http2Headers p2, int p3, boolean p4); + void onHeadersRead(ChannelHandlerContext p0, int p1, Http2Headers p2, int p3, short p4, boolean p5, int p6, boolean p7); + void onPingAckRead(ChannelHandlerContext p0, long p1); + void onPingRead(ChannelHandlerContext p0, long p1); + void onPriorityRead(ChannelHandlerContext p0, int p1, int p2, short p3, boolean p4); + void onPushPromiseRead(ChannelHandlerContext p0, int p1, int p2, Http2Headers p3, int p4); + void onRstStreamRead(ChannelHandlerContext p0, int p1, long p2); + void onSettingsAckRead(ChannelHandlerContext p0); + void onSettingsRead(ChannelHandlerContext p0, Http2Settings p1); + void onUnknownFrame(ChannelHandlerContext p0, byte p1, int p2, Http2Flags p3, ByteBuf p4); + void onWindowUpdateRead(ChannelHandlerContext p0, int p1, int p2); +} diff --git a/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http2/Http2Headers.java b/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http2/Http2Headers.java new file mode 100644 index 00000000000..0196b60df27 --- /dev/null +++ b/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http2/Http2Headers.java @@ -0,0 +1,24 @@ +// Generated automatically from io.netty.handler.codec.http2.Http2Headers for testing purposes + +package io.netty.handler.codec.http2; + +import io.netty.handler.codec.Headers; +import java.util.Iterator; +import java.util.Map; + +public interface Http2Headers extends Headers<CharSequence, CharSequence, Http2Headers> +{ + CharSequence authority(); + CharSequence method(); + CharSequence path(); + CharSequence scheme(); + CharSequence status(); + Http2Headers authority(CharSequence p0); + Http2Headers method(CharSequence p0); + Http2Headers path(CharSequence p0); + Http2Headers scheme(CharSequence p0); + Http2Headers status(CharSequence p0); + Iterator<CharSequence> valueIterator(CharSequence p0); + Iterator<Map.Entry<CharSequence, CharSequence>> iterator(); + boolean contains(CharSequence p0, CharSequence p1, boolean p2); +} diff --git a/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http2/Http2Settings.java b/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http2/Http2Settings.java new file mode 100644 index 00000000000..7aa14ef63bb --- /dev/null +++ b/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http2/Http2Settings.java @@ -0,0 +1,29 @@ +// Generated automatically from io.netty.handler.codec.http2.Http2Settings for testing purposes + +package io.netty.handler.codec.http2; + +import io.netty.util.collection.CharObjectHashMap; + +public class Http2Settings extends CharObjectHashMap<Long> +{ + protected String keyToString(char p0){ return null; } + public Boolean pushEnabled(){ return null; } + public Http2Settings copyFrom(Http2Settings p0){ return null; } + public Http2Settings headerTableSize(long p0){ return null; } + public Http2Settings initialWindowSize(int p0){ return null; } + public Http2Settings maxConcurrentStreams(long p0){ return null; } + public Http2Settings maxFrameSize(int p0){ return null; } + public Http2Settings maxHeaderListSize(long p0){ return null; } + public Http2Settings pushEnabled(boolean p0){ return null; } + public Http2Settings(){} + public Http2Settings(int p0){} + public Http2Settings(int p0, float p1){} + public Integer getIntValue(char p0){ return null; } + public Integer initialWindowSize(){ return null; } + public Integer maxFrameSize(){ return null; } + public Long headerTableSize(){ return null; } + public Long maxConcurrentStreams(){ return null; } + public Long maxHeaderListSize(){ return null; } + public Long put(char p0, Long p1){ return null; } + public static Http2Settings defaultSettings(){ return null; } +} diff --git a/java/ql/test/stubs/netty-4.1.x/io/netty/util/AsciiString.java b/java/ql/test/stubs/netty-4.1.x/io/netty/util/AsciiString.java new file mode 100644 index 00000000000..deff60c029b --- /dev/null +++ b/java/ql/test/stubs/netty-4.1.x/io/netty/util/AsciiString.java @@ -0,0 +1,119 @@ +// Generated automatically from io.netty.util.AsciiString for testing purposes + +package io.netty.util; + +import io.netty.util.ByteProcessor; +import io.netty.util.HashingStrategy; +import java.nio.ByteBuffer; +import java.nio.charset.Charset; +import java.util.Collection; + +public class AsciiString implements CharSequence, Comparable<CharSequence> +{ + protected AsciiString() {} + public AsciiString concat(CharSequence p0){ return null; } + public AsciiString replace(char p0, char p1){ return null; } + public AsciiString subSequence(int p0){ return null; } + public AsciiString subSequence(int p0, int p1){ return null; } + public AsciiString subSequence(int p0, int p1, boolean p2){ return null; } + public AsciiString toLowerCase(){ return null; } + public AsciiString toUpperCase(){ return null; } + public AsciiString trim(){ return null; } + public AsciiString(ByteBuffer p0){} + public AsciiString(ByteBuffer p0, boolean p1){} + public AsciiString(ByteBuffer p0, int p1, int p2, boolean p3){} + public AsciiString(CharSequence p0){} + public AsciiString(CharSequence p0, Charset p1){} + public AsciiString(CharSequence p0, Charset p1, int p2, int p3){} + public AsciiString(CharSequence p0, int p1, int p2){} + public AsciiString(byte[] p0){} + public AsciiString(byte[] p0, boolean p1){} + public AsciiString(byte[] p0, int p1, int p2, boolean p3){} + public AsciiString(char[] p0){} + public AsciiString(char[] p0, Charset p1){} + public AsciiString(char[] p0, Charset p1, int p2, int p3){} + public AsciiString(char[] p0, int p1, int p2){} + public AsciiString[] split(String p0, int p1){ return null; } + public AsciiString[] split(char p0){ return null; } + public String toString(){ return null; } + public String toString(int p0){ return null; } + public String toString(int p0, int p1){ return null; } + public boolean contains(CharSequence p0){ return false; } + public boolean contentEquals(CharSequence p0){ return false; } + public boolean contentEqualsIgnoreCase(CharSequence p0){ return false; } + public boolean endsWith(CharSequence p0){ return false; } + public boolean equals(Object p0){ return false; } + public boolean isEmpty(){ return false; } + public boolean isEntireArrayUsed(){ return false; } + public boolean matches(String p0){ return false; } + public boolean parseBoolean(){ return false; } + public boolean regionMatches(boolean p0, int p1, CharSequence p2, int p3, int p4){ return false; } + public boolean regionMatches(int p0, CharSequence p1, int p2, int p3){ return false; } + public boolean startsWith(CharSequence p0){ return false; } + public boolean startsWith(CharSequence p0, int p1){ return false; } + public byte byteAt(int p0){ return 0; } + public byte[] array(){ return null; } + public byte[] toByteArray(){ return null; } + public byte[] toByteArray(int p0, int p1){ return null; } + public char charAt(int p0){ return '0'; } + public char parseChar(){ return '0'; } + public char parseChar(int p0){ return '0'; } + public char[] toCharArray(){ return null; } + public char[] toCharArray(int p0, int p1){ return null; } + public double parseDouble(){ return 0; } + public double parseDouble(int p0, int p1){ return 0; } + public float parseFloat(){ return 0; } + public float parseFloat(int p0, int p1){ return 0; } + public int arrayOffset(){ return 0; } + public int compareTo(CharSequence p0){ return 0; } + public int forEachByte(ByteProcessor p0){ return 0; } + public int forEachByte(int p0, int p1, ByteProcessor p2){ return 0; } + public int forEachByteDesc(ByteProcessor p0){ return 0; } + public int forEachByteDesc(int p0, int p1, ByteProcessor p2){ return 0; } + public int hashCode(){ return 0; } + public int indexOf(CharSequence p0){ return 0; } + public int indexOf(CharSequence p0, int p1){ return 0; } + public int indexOf(char p0, int p1){ return 0; } + public int lastIndexOf(CharSequence p0){ return 0; } + public int lastIndexOf(CharSequence p0, int p1){ return 0; } + public int length(){ return 0; } + public int parseInt(){ return 0; } + public int parseInt(int p0){ return 0; } + public int parseInt(int p0, int p1){ return 0; } + public int parseInt(int p0, int p1, int p2){ return 0; } + public long parseLong(){ return 0; } + public long parseLong(int p0){ return 0; } + public long parseLong(int p0, int p1){ return 0; } + public long parseLong(int p0, int p1, int p2){ return 0; } + public short parseShort(){ return 0; } + public short parseShort(int p0){ return 0; } + public short parseShort(int p0, int p1){ return 0; } + public short parseShort(int p0, int p1, int p2){ return 0; } + public static AsciiString EMPTY_STRING = null; + public static AsciiString cached(String p0){ return null; } + public static AsciiString of(CharSequence p0){ return null; } + public static CharSequence trim(CharSequence p0){ return null; } + public static HashingStrategy<CharSequence> CASE_INSENSITIVE_HASHER = null; + public static HashingStrategy<CharSequence> CASE_SENSITIVE_HASHER = null; + public static boolean contains(CharSequence p0, CharSequence p1){ return false; } + public static boolean containsAllContentEqualsIgnoreCase(Collection<CharSequence> p0, Collection<CharSequence> p1){ return false; } + public static boolean containsContentEqualsIgnoreCase(Collection<CharSequence> p0, CharSequence p1){ return false; } + public static boolean containsIgnoreCase(CharSequence p0, CharSequence p1){ return false; } + public static boolean contentEquals(CharSequence p0, CharSequence p1){ return false; } + public static boolean contentEqualsIgnoreCase(CharSequence p0, CharSequence p1){ return false; } + public static boolean isUpperCase(byte p0){ return false; } + public static boolean isUpperCase(char p0){ return false; } + public static boolean regionMatches(CharSequence p0, boolean p1, int p2, CharSequence p3, int p4, int p5){ return false; } + public static boolean regionMatchesAscii(CharSequence p0, boolean p1, int p2, CharSequence p3, int p4, int p5){ return false; } + public static byte c2b(char p0){ return 0; } + public static char b2c(byte p0){ return '0'; } + public static char toLowerCase(char p0){ return '0'; } + public static int INDEX_NOT_FOUND = 0; + public static int hashCode(CharSequence p0){ return 0; } + public static int indexOf(CharSequence p0, char p1, int p2){ return 0; } + public static int indexOfIgnoreCase(CharSequence p0, CharSequence p1, int p2){ return 0; } + public static int indexOfIgnoreCaseAscii(CharSequence p0, CharSequence p1, int p2){ return 0; } + public void arrayChanged(){} + public void copy(int p0, byte[] p1, int p2, int p3){} + public void copy(int p0, char[] p1, int p2, int p3){} +} diff --git a/java/ql/test/stubs/netty-4.1.x/io/netty/util/HashingStrategy.java b/java/ql/test/stubs/netty-4.1.x/io/netty/util/HashingStrategy.java new file mode 100644 index 00000000000..ae15407bd09 --- /dev/null +++ b/java/ql/test/stubs/netty-4.1.x/io/netty/util/HashingStrategy.java @@ -0,0 +1,11 @@ +// Generated automatically from io.netty.util.HashingStrategy for testing purposes + +package io.netty.util; + + +public interface HashingStrategy<T> +{ + boolean equals(T p0, T p1); + int hashCode(T p0); + static HashingStrategy JAVA_HASHER = null; +} diff --git a/java/ql/test/stubs/netty-4.1.x/io/netty/util/Signal.java b/java/ql/test/stubs/netty-4.1.x/io/netty/util/Signal.java new file mode 100644 index 00000000000..1d6b4915b8e --- /dev/null +++ b/java/ql/test/stubs/netty-4.1.x/io/netty/util/Signal.java @@ -0,0 +1,21 @@ +// Generated automatically from io.netty.util.Signal for testing purposes + +package io.netty.util; + +import io.netty.util.Constant; + +public class Signal extends Error implements Constant<Signal> +{ + protected Signal() {} + public String name(){ return null; } + public String toString(){ return null; } + public Throwable fillInStackTrace(){ return null; } + public Throwable initCause(Throwable p0){ return null; } + public boolean equals(Object p0){ return false; } + public int compareTo(Signal p0){ return 0; } + public int hashCode(){ return 0; } + public int id(){ return 0; } + public static Signal valueOf(Class<? extends Object> p0, String p1){ return null; } + public static Signal valueOf(String p0){ return null; } + public void expect(Signal p0){} +} diff --git a/java/ql/test/stubs/netty-4.1.x/io/netty/util/collection/CharObjectHashMap.java b/java/ql/test/stubs/netty-4.1.x/io/netty/util/collection/CharObjectHashMap.java new file mode 100644 index 00000000000..f52d6279b15 --- /dev/null +++ b/java/ql/test/stubs/netty-4.1.x/io/netty/util/collection/CharObjectHashMap.java @@ -0,0 +1,38 @@ +// Generated automatically from io.netty.util.collection.CharObjectHashMap for testing purposes + +package io.netty.util.collection; + +import io.netty.util.collection.CharObjectMap; +import java.util.Collection; +import java.util.Map; +import java.util.Set; + +public class CharObjectHashMap<V> implements CharObjectMap<V> +{ + protected String keyToString(char p0){ return null; } + public CharObjectHashMap(){} + public CharObjectHashMap(int p0){} + public CharObjectHashMap(int p0, float p1){} + public Collection<V> values(){ return null; } + public Iterable<CharObjectMap.PrimitiveEntry<V>> entries(){ return null; } + public Set<Character> keySet(){ return null; } + public Set<Map.Entry<Character, V>> entrySet(){ return null; } + public String toString(){ return null; } + public V get(Object p0){ return null; } + public V get(char p0){ return null; } + public V put(Character p0, V p1){ return null; } + public V put(char p0, V p1){ return null; } + public V remove(Object p0){ return null; } + public V remove(char p0){ return null; } + public boolean containsKey(Object p0){ return false; } + public boolean containsKey(char p0){ return false; } + public boolean containsValue(Object p0){ return false; } + public boolean equals(Object p0){ return false; } + public boolean isEmpty(){ return false; } + public int hashCode(){ return 0; } + public int size(){ return 0; } + public static float DEFAULT_LOAD_FACTOR = 0; + public static int DEFAULT_CAPACITY = 0; + public void clear(){} + public void putAll(Map<? extends Character, ? extends V> p0){} +} diff --git a/java/ql/test/stubs/netty-4.1.x/io/netty/util/collection/CharObjectMap.java b/java/ql/test/stubs/netty-4.1.x/io/netty/util/collection/CharObjectMap.java new file mode 100644 index 00000000000..1bbb76a4dd5 --- /dev/null +++ b/java/ql/test/stubs/netty-4.1.x/io/netty/util/collection/CharObjectMap.java @@ -0,0 +1,20 @@ +// Generated automatically from io.netty.util.collection.CharObjectMap for testing purposes + +package io.netty.util.collection; + +import java.util.Map; + +public interface CharObjectMap<V> extends Map<Character, V> +{ + Iterable<CharObjectMap.PrimitiveEntry<V>> entries(); + V get(char p0); + V put(char p0, V p1); + V remove(char p0); + boolean containsKey(char p0); + static public interface PrimitiveEntry<V> + { + V value(); + char key(); + void setValue(V p0); + } +} From 39ed5038afe30a23147930c5d922383bbc0ee7cb Mon Sep 17 00:00:00 2001 From: Joe Farebrother <joefarebrother@github.com> Date: Wed, 15 Feb 2023 15:05:59 +0000 Subject: [PATCH 364/631] Generate test cases and fix some errors in models --- .../ext/io.netty.handler.codec.http.model.yml | 86 +- .../io.netty.handler.codec.http2.model.yml | 20 +- .../frameworks/netty/generated/Test.java | 5761 +++++++++++++++++ .../frameworks/netty/generated/options | 1 + .../frameworks/netty/generated/test.expected | 0 .../frameworks/netty/generated/test.ql | 2 + 6 files changed, 5816 insertions(+), 54 deletions(-) create mode 100644 java/ql/test/library-tests/frameworks/netty/generated/Test.java create mode 100644 java/ql/test/library-tests/frameworks/netty/generated/options create mode 100644 java/ql/test/library-tests/frameworks/netty/generated/test.expected create mode 100644 java/ql/test/library-tests/frameworks/netty/generated/test.ql diff --git a/java/ql/lib/ext/io.netty.handler.codec.http.model.yml b/java/ql/lib/ext/io.netty.handler.codec.http.model.yml index e4eaaf38f90..fd6c42685c8 100644 --- a/java/ql/lib/ext/io.netty.handler.codec.http.model.yml +++ b/java/ql/lib/ext/io.netty.handler.codec.http.model.yml @@ -1,45 +1,43 @@ extensions: - - addsTo: - pack: codeql/java-all - extensible: sinkModel - data: - - ["io.netty.handler.codec.http", "DefaultFullHttpRequest", True, "DefaultFullHttpRequest", "(HttpVersion,HttpMethod,String,ByteBuf)", "", "Argument[2]", "open-url", "ai-generated"] - - ["io.netty.handler.codec.http", "DefaultHttpRequest", True, "DefaultHttpRequest", "(HttpVersion,HttpMethod,String)", "", "Argument[2]", "open-url", "ai-generated"] - - addsTo: - pack: codeql/java-all - extensible: summaryModel - data: - - ["io.netty.handler.codec.http", "QueryStringEncoder", True, "QueryStringEncoder", "(String)", "", "Argument[0]", "Argument[this]", "taint", "ai-generated"] - - ["io.netty.handler.codec.http", "HttpHeaders", True, "copy", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.handler.codec.http", "HttpHeaders", True, "entries", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.handler.codec.http", "HttpHeaders", True, "get", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.handler.codec.http", "HttpHeaders", True, "get", "", "", "Argument[1]", "ReturnValue", "value", "manual"] - - ["io.netty.handler.codec.http", "HttpHeaders", True, "getAll", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.handler.codec.http", "HttpHeaders", True, "getAllAsString", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.handler.codec.http", "HttpHeaders", True, "getAsString", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.handler.codec.http", "HttpHeaders", True, "getHeader", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] - - ["io.netty.handler.codec.http", "HttpHeaders", True, "getHeader", "", "", "Argument[2]", "ReturnValue", "value", "manual"] - - ["io.netty.handler.codec.http", "HttpHeaders", True, "getHost", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] - - ["io.netty.handler.codec.http", "HttpHeaders", True, "getHost", "", "", "Argument[2]", "ReturnValue", "value", "manual"] - - ["io.netty.handler.codec.http", "HttpHeaders", True, "iteratorAsString", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.handler.codec.http", "HttpHeaders", True, "iteratorCharSequence", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.handler.codec.http", "HttpHeaders", True, "names", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.handler.codec.http", "HttpHeaders", True, "newEntity", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] - - ["io.netty.handler.codec.http", "HttpHeaders", True, "valueCharSequenceIterator", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.handler.codec.http", "HttpHeaders", True, "valueStringIterator", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.handler.codec.http", "HttpHeaders", True, "toString", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.handler.codec.http", "HttpMessage", True, "headers", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.handler.codec.http", "HttpMessage", True, "trailingHeaders", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.handler.codec.http", "LastHttpMessage", True, "trailingHeaders", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.handler.codec.http", "HttpRequest", True, "getUri", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.handler.codec.http", "HttpRequest", True, "uri", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.handler.codec.http", "QueryStringDecoder", True, "QueryStringDecoder", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] - - ["io.netty.handler.codec.http", "QueryStringDecoder", True, "decodeComponent", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.handler.codec.http", "QueryStringDecoder", True, "parameters", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.handler.codec.http", "QueryStringDecoder", True, "path", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.handler.codec.http", "QueryStringDecoder", True, "rawPath", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.handler.codec.http", "QueryStringDecoder", True, "rawQuery", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.handler.codec.http", "QueryStringDecoder", True, "toString", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.handler.codec.http", "QueryStringDecoder", True, "uri", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - +- addsTo: + pack: codeql/java-all + extensible: sinkModel + data: + - ["io.netty.handler.codec.http", "DefaultFullHttpRequest", True, "DefaultFullHttpRequest", "(HttpVersion,HttpMethod,String,ByteBuf)", "", "Argument[2]", "open-url", "ai-generated"] + - ["io.netty.handler.codec.http", "DefaultHttpRequest", True, "DefaultHttpRequest", "(HttpVersion,HttpMethod,String)", "", "Argument[2]", "open-url", "ai-generated"] +- addsTo: + pack: codeql/java-all + extensible: summaryModel + data: + - ["io.netty.handler.codec.http", "QueryStringEncoder", True, "QueryStringEncoder", "(String)", "", "Argument[0]", "Argument[this]", "taint", "ai-generated"] + - ["io.netty.handler.codec.http", "HttpHeaders", True, "copy", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http", "HttpHeaders", True, "entries", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http", "HttpHeaders", True, "get", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http", "HttpHeaders", True, "get", "", "", "Argument[1]", "ReturnValue", "value", "manual"] + - ["io.netty.handler.codec.http", "HttpHeaders", True, "getAll", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http", "HttpHeaders", True, "getAllAsString", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http", "HttpHeaders", True, "getAsString", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http", "HttpHeaders", True, "getHeader", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http", "HttpHeaders", True, "getHeader", "", "", "Argument[2]", "ReturnValue", "value", "manual"] + - ["io.netty.handler.codec.http", "HttpHeaders", True, "getHost", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http", "HttpHeaders", True, "getHost", "", "", "Argument[1]", "ReturnValue", "value", "manual"] + - ["io.netty.handler.codec.http", "HttpHeaders", True, "iteratorAsString", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http", "HttpHeaders", True, "iteratorCharSequence", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http", "HttpHeaders", True, "names", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http", "HttpHeaders", True, "newEntity", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http", "HttpHeaders", True, "valueCharSequenceIterator", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http", "HttpHeaders", True, "valueStringIterator", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http", "HttpHeaders", True, "toString", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http", "HttpMessage", True, "headers", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http", "LastHttpContent", True, "trailingHeaders", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http", "HttpRequest", True, "getUri", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http", "HttpRequest", True, "uri", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http", "QueryStringDecoder", True, "QueryStringDecoder", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http", "QueryStringDecoder", True, "decodeComponent", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http", "QueryStringDecoder", True, "parameters", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http", "QueryStringDecoder", True, "path", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http", "QueryStringDecoder", True, "rawPath", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http", "QueryStringDecoder", True, "rawQuery", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http", "QueryStringDecoder", True, "toString", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http", "QueryStringDecoder", True, "uri", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + diff --git a/java/ql/lib/ext/io.netty.handler.codec.http2.model.yml b/java/ql/lib/ext/io.netty.handler.codec.http2.model.yml index 5ded6c38399..7f4c3c515c7 100644 --- a/java/ql/lib/ext/io.netty.handler.codec.http2.model.yml +++ b/java/ql/lib/ext/io.netty.handler.codec.http2.model.yml @@ -17,17 +17,17 @@ extensions: - ["io.netty.handler.codec.http2", "Http2Headers", True, "path", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - ["io.netty.handler.codec.http2", "Http2Headers", True, "scheme", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - ["io.netty.handler.codec.http2", "Http2Headers", True, "status", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.handler.codec.http2", "Http2Headers", True, "valueIterator", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http2", "Http2Headers", True, "valueIterator", "(CharSequence)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - ["io.netty.handler.codec.http2", "Http2HeadersFrame", True, "headers", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - ["io.netty.handler.codec.http2", "Http2PushPromiseFrame", True, "http2Headers", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.handler.codec.http2", "Http2ConversionUtil", False, "addHttp2ToHttpHeaders", "", "", "Argument[1]", "Argument[2]", "taint", "manual"] - - ["io.netty.handler.codec.http2", "Http2ConversionUtil", False, "toFullHttpRequest", "", "", "Argument[1]", "ReturnValue", "taint", "manual"] - - ["io.netty.handler.codec.http2", "Http2ConversionUtil", False, "toFullHttpRequest", "", "", "Argument[2]", "ReturnValue", "taint", "manual"] - - ["io.netty.handler.codec.http2", "Http2ConversionUtil", False, "toFullHttpResponse", "", "", "Argument[1]", "ReturnValue", "taint", "manual"] - - ["io.netty.handler.codec.http2", "Http2ConversionUtil", False, "toFullHttpResponse", "", "", "Argument[2]", "ReturnValue", "taint", "manual"] - - ["io.netty.handler.codec.http2", "Http2ConversionUtil", False, "toHttp2Headers", "(HttpHeaders,boolean)", "", "Argument[1]", "ReturnValue", "taint", "manual"] - - ["io.netty.handler.codec.http2", "Http2ConversionUtil", False, "toHttp2Headers", "(HttpHeaders,Http2Headers)", "", "Argument[1]", "Argument[2]", "taint", "manual"] - - ["io.netty.handler.codec.http2", "Http2ConversionUtil", False, "toHttpRequest", "", "", "Argument[1]", "ReturnValue", "taint", "manual"] - - ["io.netty.handler.codec.http2", "Http2ConversionUtil", False, "toHttpResponse", "", "", "Argument[1]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http2", "HttpConversionUtil", False, "addHttp2ToHttpHeaders", "", "", "Argument[1]", "Argument[2]", "taint", "manual"] + - ["io.netty.handler.codec.http2", "HttpConversionUtil", False, "toFullHttpRequest", "", "", "Argument[1]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http2", "HttpConversionUtil", False, "toFullHttpRequest", "", "", "Argument[2]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http2", "HttpConversionUtil", False, "toFullHttpResponse", "", "", "Argument[1]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http2", "HttpConversionUtil", False, "toFullHttpResponse", "", "", "Argument[2]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http2", "HttpConversionUtil", False, "toHttp2Headers", "(HttpHeaders,boolean)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http2", "HttpConversionUtil", False, "toHttp2Headers", "(HttpHeaders,Http2Headers)", "", "Argument[0]", "Argument[1]", "taint", "manual"] + - ["io.netty.handler.codec.http2", "HttpConversionUtil", False, "toHttpRequest", "", "", "Argument[1]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http2", "HttpConversionUtil", False, "toHttpResponse", "", "", "Argument[1]", "ReturnValue", "taint", "manual"] diff --git a/java/ql/test/library-tests/frameworks/netty/generated/Test.java b/java/ql/test/library-tests/frameworks/netty/generated/Test.java new file mode 100644 index 00000000000..6f820c81656 --- /dev/null +++ b/java/ql/test/library-tests/frameworks/netty/generated/Test.java @@ -0,0 +1,5761 @@ +package generatedtest; + +import io.netty.buffer.AbstractByteBuf; +import io.netty.buffer.AbstractReferenceCountedByteBuf; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.ByteBufAllocator; +import io.netty.buffer.ByteBufConvertible; +import io.netty.buffer.ByteBufHolder; +import io.netty.buffer.CompositeByteBuf; +import io.netty.buffer.DefaultByteBufHolder; +import io.netty.buffer.SwappedByteBuf; +import io.netty.channel.DefaultFileRegion; +import io.netty.channel.FileRegion; +import io.netty.handler.codec.Headers; +import io.netty.handler.codec.HeadersUtils; +import io.netty.handler.codec.base64.Base64; +import io.netty.handler.codec.base64.Base64Dialect; +import io.netty.handler.codec.http.FullHttpMessage; +import io.netty.handler.codec.http.FullHttpRequest; +import io.netty.handler.codec.http.FullHttpResponse; +import io.netty.handler.codec.http.HttpContent; +import io.netty.handler.codec.http.HttpHeaders; +import io.netty.handler.codec.http.HttpMessage; +import io.netty.handler.codec.http.HttpRequest; +import io.netty.handler.codec.http.HttpResponse; +import io.netty.handler.codec.http.LastHttpContent; +import io.netty.handler.codec.http.QueryStringDecoder; +import io.netty.handler.codec.http.cookie.Cookie; +import io.netty.handler.codec.http.cookie.DefaultCookie; +import io.netty.handler.codec.http.cookie.ServerCookieDecoder; +import io.netty.handler.codec.http.multipart.Attribute; +import io.netty.handler.codec.http.multipart.FileUpload; +import io.netty.handler.codec.http.multipart.HttpData; +import io.netty.handler.codec.http.multipart.HttpPostMultipartRequestDecoder; +import io.netty.handler.codec.http.multipart.HttpPostRequestDecoder; +import io.netty.handler.codec.http.multipart.HttpPostStandardRequestDecoder; +import io.netty.handler.codec.http.multipart.InterfaceHttpData; +import io.netty.handler.codec.http.multipart.InterfaceHttpPostRequestDecoder; +import io.netty.handler.codec.http.websocketx.CloseWebSocketFrame; +import io.netty.handler.codec.http.websocketx.ContinuationWebSocketFrame; +import io.netty.handler.codec.http.websocketx.TextWebSocketFrame; +import io.netty.handler.codec.http.websocketx.WebSocketFrame; +import io.netty.handler.codec.http2.Http2Headers; +import io.netty.handler.codec.http2.Http2HeadersFrame; +import io.netty.handler.codec.http2.Http2PushPromiseFrame; +import io.netty.handler.codec.http2.HttpConversionUtil; +import io.netty.util.AbstractReferenceCounted; +import io.netty.util.ReferenceCounted; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.URI; +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.nio.channels.FileChannel; +import java.nio.channels.GatheringByteChannel; +import java.nio.channels.ScatteringByteChannel; +import java.nio.charset.Charset; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; + +// Test case generated by GenerateFlowTestCase.ql +public class Test { + + Object source() { return null; } + void sink(Object o) { } + + public void test() throws Exception { + + { + // "io.netty.buffer;ByteBuf;true;array;();;Argument[-1];ReturnValue;taint;manual" + byte[] out = null; + ByteBuf in = (ByteBuf)source(); + out = in.array(); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;array;();;Argument[-1];ReturnValue;taint;manual" + byte[] out = null; + CompositeByteBuf in = (CompositeByteBuf)source(); + out = in.array(); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;array;();;Argument[-1];ReturnValue;taint;manual" + byte[] out = null; + SwappedByteBuf in = (SwappedByteBuf)source(); + out = in.array(); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;asReadOnly;();;Argument[-1];ReturnValue;taint;manual" + ByteBuf out = null; + AbstractByteBuf in = (AbstractByteBuf)source(); + out = in.asReadOnly(); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;asReadOnly;();;Argument[-1];ReturnValue;taint;manual" + ByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out = in.asReadOnly(); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;asReadOnly;();;Argument[-1];ReturnValue;taint;manual" + ByteBuf out = null; + SwappedByteBuf in = (SwappedByteBuf)source(); + out = in.asReadOnly(); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;capacity;(int);;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out = in.capacity(0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;capacity;(int);;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + SwappedByteBuf in = (SwappedByteBuf)source(); + out = in.capacity(0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;capacity;(int);;Argument[-1];ReturnValue;value;manual" + CompositeByteBuf out = null; + CompositeByteBuf in = (CompositeByteBuf)source(); + out = in.capacity(0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;copy;;;Argument[-1];ReturnValue;taint;manual" + ByteBuf out = null; + AbstractByteBuf in = (AbstractByteBuf)source(); + out = in.copy(); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;copy;;;Argument[-1];ReturnValue;taint;manual" + ByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out = in.copy(); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;copy;;;Argument[-1];ReturnValue;taint;manual" + ByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out = in.copy(0, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;copy;;;Argument[-1];ReturnValue;taint;manual" + ByteBuf out = null; + CompositeByteBuf in = (CompositeByteBuf)source(); + out = in.copy(0, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;copy;;;Argument[-1];ReturnValue;taint;manual" + ByteBuf out = null; + SwappedByteBuf in = (SwappedByteBuf)source(); + out = in.copy(); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;copy;;;Argument[-1];ReturnValue;taint;manual" + ByteBuf out = null; + SwappedByteBuf in = (SwappedByteBuf)source(); + out = in.copy(0, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;discardReadBytes;();;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + AbstractByteBuf in = (AbstractByteBuf)source(); + out = in.discardReadBytes(); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;discardReadBytes;();;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out = in.discardReadBytes(); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;discardReadBytes;();;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + SwappedByteBuf in = (SwappedByteBuf)source(); + out = in.discardReadBytes(); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;discardReadBytes;();;Argument[-1];ReturnValue;value;manual" + CompositeByteBuf out = null; + CompositeByteBuf in = (CompositeByteBuf)source(); + out = in.discardReadBytes(); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;discardSomeReadBytes;();;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + AbstractByteBuf in = (AbstractByteBuf)source(); + out = in.discardSomeReadBytes(); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;discardSomeReadBytes;();;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out = in.discardSomeReadBytes(); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;discardSomeReadBytes;();;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + SwappedByteBuf in = (SwappedByteBuf)source(); + out = in.discardSomeReadBytes(); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;discardSomeReadBytes;();;Argument[-1];ReturnValue;value;manual" + CompositeByteBuf out = null; + CompositeByteBuf in = (CompositeByteBuf)source(); + out = in.discardSomeReadBytes(); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;duplicate;();;Argument[-1];ReturnValue;taint;manual" + ByteBuf out = null; + AbstractByteBuf in = (AbstractByteBuf)source(); + out = in.duplicate(); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;duplicate;();;Argument[-1];ReturnValue;taint;manual" + ByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out = in.duplicate(); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;duplicate;();;Argument[-1];ReturnValue;taint;manual" + ByteBuf out = null; + SwappedByteBuf in = (SwappedByteBuf)source(); + out = in.duplicate(); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;ensureWritable;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + AbstractByteBuf in = (AbstractByteBuf)source(); + out = in.ensureWritable(0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;ensureWritable;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out = in.ensureWritable(0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;ensureWritable;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + SwappedByteBuf in = (SwappedByteBuf)source(); + out = in.ensureWritable(0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;ensureWritable;;;Argument[-1];ReturnValue;value;manual" + CompositeByteBuf out = null; + CompositeByteBuf in = (CompositeByteBuf)source(); + out = in.ensureWritable(0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;ensureWritable;;;Argument[-1];ReturnValue;value;manual" + int out = null; + AbstractByteBuf in = (AbstractByteBuf)source(); + out = in.ensureWritable(0, false); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;ensureWritable;;;Argument[-1];ReturnValue;value;manual" + int out = null; + ByteBuf in = (ByteBuf)source(); + out = in.ensureWritable(0, false); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;ensureWritable;;;Argument[-1];ReturnValue;value;manual" + int out = null; + SwappedByteBuf in = (SwappedByteBuf)source(); + out = in.ensureWritable(0, false); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;getByte;;;Argument[-1];ReturnValue;taint;manual" + byte out = null; + AbstractByteBuf in = (AbstractByteBuf)source(); + out = in.getByte(0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;getByte;;;Argument[-1];ReturnValue;taint;manual" + byte out = null; + ByteBuf in = (ByteBuf)source(); + out = in.getByte(0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;getByte;;;Argument[-1];ReturnValue;taint;manual" + byte out = null; + CompositeByteBuf in = (CompositeByteBuf)source(); + out = in.getByte(0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;getByte;;;Argument[-1];ReturnValue;taint;manual" + byte out = null; + SwappedByteBuf in = (SwappedByteBuf)source(); + out = in.getByte(0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;getBytes;;;Argument[-1];Argument[1];taint;manual" + ByteBuf out = null; + AbstractByteBuf in = (AbstractByteBuf)source(); + in.getBytes(0, out); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;getBytes;;;Argument[-1];Argument[1];taint;manual" + ByteBuf out = null; + AbstractByteBuf in = (AbstractByteBuf)source(); + in.getBytes(0, out, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;getBytes;;;Argument[-1];Argument[1];taint;manual" + ByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + in.getBytes(0, out); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;getBytes;;;Argument[-1];Argument[1];taint;manual" + ByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + in.getBytes(0, out, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;getBytes;;;Argument[-1];Argument[1];taint;manual" + ByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + in.getBytes(0, out, 0, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;getBytes;;;Argument[-1];Argument[1];taint;manual" + ByteBuf out = null; + CompositeByteBuf in = (CompositeByteBuf)source(); + in.getBytes(0, out); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;getBytes;;;Argument[-1];Argument[1];taint;manual" + ByteBuf out = null; + CompositeByteBuf in = (CompositeByteBuf)source(); + in.getBytes(0, out, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;getBytes;;;Argument[-1];Argument[1];taint;manual" + ByteBuf out = null; + CompositeByteBuf in = (CompositeByteBuf)source(); + in.getBytes(0, out, 0, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;getBytes;;;Argument[-1];Argument[1];taint;manual" + ByteBuf out = null; + SwappedByteBuf in = (SwappedByteBuf)source(); + in.getBytes(0, out); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;getBytes;;;Argument[-1];Argument[1];taint;manual" + ByteBuf out = null; + SwappedByteBuf in = (SwappedByteBuf)source(); + in.getBytes(0, out, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;getBytes;;;Argument[-1];Argument[1];taint;manual" + ByteBuf out = null; + SwappedByteBuf in = (SwappedByteBuf)source(); + in.getBytes(0, out, 0, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;getBytes;;;Argument[-1];Argument[1];taint;manual" + ByteBuffer out = null; + ByteBuf in = (ByteBuf)source(); + in.getBytes(0, out); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;getBytes;;;Argument[-1];Argument[1];taint;manual" + ByteBuffer out = null; + CompositeByteBuf in = (CompositeByteBuf)source(); + in.getBytes(0, out); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;getBytes;;;Argument[-1];Argument[1];taint;manual" + ByteBuffer out = null; + SwappedByteBuf in = (SwappedByteBuf)source(); + in.getBytes(0, out); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;getBytes;;;Argument[-1];Argument[1];taint;manual" + FileChannel out = null; + ByteBuf in = (ByteBuf)source(); + in.getBytes(0, out, 0L, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;getBytes;;;Argument[-1];Argument[1];taint;manual" + FileChannel out = null; + CompositeByteBuf in = (CompositeByteBuf)source(); + in.getBytes(0, out, 0L, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;getBytes;;;Argument[-1];Argument[1];taint;manual" + FileChannel out = null; + SwappedByteBuf in = (SwappedByteBuf)source(); + in.getBytes(0, out, 0L, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;getBytes;;;Argument[-1];Argument[1];taint;manual" + GatheringByteChannel out = null; + ByteBuf in = (ByteBuf)source(); + in.getBytes(0, out, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;getBytes;;;Argument[-1];Argument[1];taint;manual" + GatheringByteChannel out = null; + CompositeByteBuf in = (CompositeByteBuf)source(); + in.getBytes(0, out, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;getBytes;;;Argument[-1];Argument[1];taint;manual" + GatheringByteChannel out = null; + SwappedByteBuf in = (SwappedByteBuf)source(); + in.getBytes(0, out, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;getBytes;;;Argument[-1];Argument[1];taint;manual" + OutputStream out = null; + ByteBuf in = (ByteBuf)source(); + in.getBytes(0, out, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;getBytes;;;Argument[-1];Argument[1];taint;manual" + OutputStream out = null; + CompositeByteBuf in = (CompositeByteBuf)source(); + in.getBytes(0, out, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;getBytes;;;Argument[-1];Argument[1];taint;manual" + OutputStream out = null; + SwappedByteBuf in = (SwappedByteBuf)source(); + in.getBytes(0, out, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;getBytes;;;Argument[-1];Argument[1];taint;manual" + byte[] out = null; + AbstractByteBuf in = (AbstractByteBuf)source(); + in.getBytes(0, out); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;getBytes;;;Argument[-1];Argument[1];taint;manual" + byte[] out = null; + ByteBuf in = (ByteBuf)source(); + in.getBytes(0, out); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;getBytes;;;Argument[-1];Argument[1];taint;manual" + byte[] out = null; + ByteBuf in = (ByteBuf)source(); + in.getBytes(0, out, 0, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;getBytes;;;Argument[-1];Argument[1];taint;manual" + byte[] out = null; + CompositeByteBuf in = (CompositeByteBuf)source(); + in.getBytes(0, out); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;getBytes;;;Argument[-1];Argument[1];taint;manual" + byte[] out = null; + CompositeByteBuf in = (CompositeByteBuf)source(); + in.getBytes(0, out, 0, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;getBytes;;;Argument[-1];Argument[1];taint;manual" + byte[] out = null; + SwappedByteBuf in = (SwappedByteBuf)source(); + in.getBytes(0, out); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;getBytes;;;Argument[-1];Argument[1];taint;manual" + byte[] out = null; + SwappedByteBuf in = (SwappedByteBuf)source(); + in.getBytes(0, out, 0, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;getBytes;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + AbstractByteBuf in = (AbstractByteBuf)source(); + out = in.getBytes(0, (ByteBuf)null); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;getBytes;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + AbstractByteBuf in = (AbstractByteBuf)source(); + out = in.getBytes(0, (byte[])null); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;getBytes;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + AbstractByteBuf in = (AbstractByteBuf)source(); + out = in.getBytes(0, null, 0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;getBytes;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out = in.getBytes(0, (ByteBuf)null); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;getBytes;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out = in.getBytes(0, (ByteBuf)null, 0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;getBytes;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out = in.getBytes(0, (ByteBuf)null, 0, 0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;getBytes;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out = in.getBytes(0, (ByteBuffer)null); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;getBytes;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out = in.getBytes(0, (OutputStream)null, 0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;getBytes;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out = in.getBytes(0, (byte[])null); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;getBytes;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out = in.getBytes(0, (byte[])null, 0, 0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;getBytes;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + SwappedByteBuf in = (SwappedByteBuf)source(); + out = in.getBytes(0, (ByteBuf)null); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;getBytes;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + SwappedByteBuf in = (SwappedByteBuf)source(); + out = in.getBytes(0, (ByteBuf)null, 0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;getBytes;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + SwappedByteBuf in = (SwappedByteBuf)source(); + out = in.getBytes(0, (ByteBuf)null, 0, 0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;getBytes;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + SwappedByteBuf in = (SwappedByteBuf)source(); + out = in.getBytes(0, (ByteBuffer)null); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;getBytes;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + SwappedByteBuf in = (SwappedByteBuf)source(); + out = in.getBytes(0, (OutputStream)null, 0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;getBytes;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + SwappedByteBuf in = (SwappedByteBuf)source(); + out = in.getBytes(0, (byte[])null); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;getBytes;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + SwappedByteBuf in = (SwappedByteBuf)source(); + out = in.getBytes(0, (byte[])null, 0, 0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;getBytes;;;Argument[-1];ReturnValue;value;manual" + CompositeByteBuf out = null; + CompositeByteBuf in = (CompositeByteBuf)source(); + out = in.getBytes(0, (ByteBuf)null); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;getBytes;;;Argument[-1];ReturnValue;value;manual" + CompositeByteBuf out = null; + CompositeByteBuf in = (CompositeByteBuf)source(); + out = in.getBytes(0, (ByteBuf)null, 0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;getBytes;;;Argument[-1];ReturnValue;value;manual" + CompositeByteBuf out = null; + CompositeByteBuf in = (CompositeByteBuf)source(); + out = in.getBytes(0, (ByteBuf)null, 0, 0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;getBytes;;;Argument[-1];ReturnValue;value;manual" + CompositeByteBuf out = null; + CompositeByteBuf in = (CompositeByteBuf)source(); + out = in.getBytes(0, (ByteBuffer)null); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;getBytes;;;Argument[-1];ReturnValue;value;manual" + CompositeByteBuf out = null; + CompositeByteBuf in = (CompositeByteBuf)source(); + out = in.getBytes(0, (OutputStream)null, 0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;getBytes;;;Argument[-1];ReturnValue;value;manual" + CompositeByteBuf out = null; + CompositeByteBuf in = (CompositeByteBuf)source(); + out = in.getBytes(0, (byte[])null); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;getBytes;;;Argument[-1];ReturnValue;value;manual" + CompositeByteBuf out = null; + CompositeByteBuf in = (CompositeByteBuf)source(); + out = in.getBytes(0, (byte[])null, 0, 0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;getBytes;;;Argument[-1];ReturnValue;value;manual" + int out = null; + ByteBuf in = (ByteBuf)source(); + out = in.getBytes(0, (FileChannel)null, 0L, 0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;getBytes;;;Argument[-1];ReturnValue;value;manual" + int out = null; + ByteBuf in = (ByteBuf)source(); + out = in.getBytes(0, (GatheringByteChannel)null, 0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;getBytes;;;Argument[-1];ReturnValue;value;manual" + int out = null; + CompositeByteBuf in = (CompositeByteBuf)source(); + out = in.getBytes(0, (FileChannel)null, 0L, 0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;getBytes;;;Argument[-1];ReturnValue;value;manual" + int out = null; + CompositeByteBuf in = (CompositeByteBuf)source(); + out = in.getBytes(0, (GatheringByteChannel)null, 0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;getBytes;;;Argument[-1];ReturnValue;value;manual" + int out = null; + SwappedByteBuf in = (SwappedByteBuf)source(); + out = in.getBytes(0, (FileChannel)null, 0L, 0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;getBytes;;;Argument[-1];ReturnValue;value;manual" + int out = null; + SwappedByteBuf in = (SwappedByteBuf)source(); + out = in.getBytes(0, (GatheringByteChannel)null, 0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;getChar;;;Argument[-1];ReturnValue;taint;manual" + char out = null; + AbstractByteBuf in = (AbstractByteBuf)source(); + out = in.getChar(0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;getChar;;;Argument[-1];ReturnValue;taint;manual" + char out = null; + ByteBuf in = (ByteBuf)source(); + out = in.getChar(0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;getChar;;;Argument[-1];ReturnValue;taint;manual" + char out = null; + SwappedByteBuf in = (SwappedByteBuf)source(); + out = in.getChar(0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;getCharSequence;;;Argument[-1];ReturnValue;taint;manual" + CharSequence out = null; + AbstractByteBuf in = (AbstractByteBuf)source(); + out = in.getCharSequence(0, 0, null); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;getCharSequence;;;Argument[-1];ReturnValue;taint;manual" + CharSequence out = null; + ByteBuf in = (ByteBuf)source(); + out = in.getCharSequence(0, 0, null); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;getCharSequence;;;Argument[-1];ReturnValue;taint;manual" + CharSequence out = null; + SwappedByteBuf in = (SwappedByteBuf)source(); + out = in.getCharSequence(0, 0, null); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;markReaderIndex;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + AbstractByteBuf in = (AbstractByteBuf)source(); + out = in.markReaderIndex(); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;markReaderIndex;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out = in.markReaderIndex(); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;markReaderIndex;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + SwappedByteBuf in = (SwappedByteBuf)source(); + out = in.markReaderIndex(); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;markReaderIndex;;;Argument[-1];ReturnValue;value;manual" + CompositeByteBuf out = null; + CompositeByteBuf in = (CompositeByteBuf)source(); + out = in.markReaderIndex(); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;markWriterIndex;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + AbstractByteBuf in = (AbstractByteBuf)source(); + out = in.markWriterIndex(); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;markWriterIndex;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out = in.markWriterIndex(); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;markWriterIndex;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + SwappedByteBuf in = (SwappedByteBuf)source(); + out = in.markWriterIndex(); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;markWriterIndex;;;Argument[-1];ReturnValue;value;manual" + CompositeByteBuf out = null; + CompositeByteBuf in = (CompositeByteBuf)source(); + out = in.markWriterIndex(); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;nioBuffer;;;Argument[-1];ReturnValue;taint;manual" + ByteBuffer out = null; + AbstractByteBuf in = (AbstractByteBuf)source(); + out = in.nioBuffer(); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;nioBuffer;;;Argument[-1];ReturnValue;taint;manual" + ByteBuffer out = null; + ByteBuf in = (ByteBuf)source(); + out = in.nioBuffer(); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;nioBuffer;;;Argument[-1];ReturnValue;taint;manual" + ByteBuffer out = null; + ByteBuf in = (ByteBuf)source(); + out = in.nioBuffer(0, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;nioBuffer;;;Argument[-1];ReturnValue;taint;manual" + ByteBuffer out = null; + CompositeByteBuf in = (CompositeByteBuf)source(); + out = in.nioBuffer(0, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;nioBuffer;;;Argument[-1];ReturnValue;taint;manual" + ByteBuffer out = null; + SwappedByteBuf in = (SwappedByteBuf)source(); + out = in.nioBuffer(); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;nioBuffer;;;Argument[-1];ReturnValue;taint;manual" + ByteBuffer out = null; + SwappedByteBuf in = (SwappedByteBuf)source(); + out = in.nioBuffer(0, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;nioBuffers;;;Argument[-1];ReturnValue;taint;manual" + ByteBuffer[] out = null; + AbstractByteBuf in = (AbstractByteBuf)source(); + out = in.nioBuffers(); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;nioBuffers;;;Argument[-1];ReturnValue;taint;manual" + ByteBuffer[] out = null; + ByteBuf in = (ByteBuf)source(); + out = in.nioBuffers(); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;nioBuffers;;;Argument[-1];ReturnValue;taint;manual" + ByteBuffer[] out = null; + ByteBuf in = (ByteBuf)source(); + out = in.nioBuffers(0, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;nioBuffers;;;Argument[-1];ReturnValue;taint;manual" + ByteBuffer[] out = null; + CompositeByteBuf in = (CompositeByteBuf)source(); + out = in.nioBuffers(); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;nioBuffers;;;Argument[-1];ReturnValue;taint;manual" + ByteBuffer[] out = null; + CompositeByteBuf in = (CompositeByteBuf)source(); + out = in.nioBuffers(0, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;nioBuffers;;;Argument[-1];ReturnValue;taint;manual" + ByteBuffer[] out = null; + SwappedByteBuf in = (SwappedByteBuf)source(); + out = in.nioBuffers(); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;nioBuffers;;;Argument[-1];ReturnValue;taint;manual" + ByteBuffer[] out = null; + SwappedByteBuf in = (SwappedByteBuf)source(); + out = in.nioBuffers(0, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;order;;;Argument[-1];ReturnValue;taint;manual" + ByteBuf out = null; + AbstractByteBuf in = (AbstractByteBuf)source(); + out = in.order(null); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;order;;;Argument[-1];ReturnValue;taint;manual" + ByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out = in.order(null); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;order;;;Argument[-1];ReturnValue;taint;manual" + ByteBuf out = null; + SwappedByteBuf in = (SwappedByteBuf)source(); + out = in.order(null); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;order;;;Argument[-1];ReturnValue;taint;manual" + ByteOrder out = null; + ByteBuf in = (ByteBuf)source(); + out = in.order(); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;order;;;Argument[-1];ReturnValue;taint;manual" + ByteOrder out = null; + CompositeByteBuf in = (CompositeByteBuf)source(); + out = in.order(); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;order;;;Argument[-1];ReturnValue;taint;manual" + ByteOrder out = null; + SwappedByteBuf in = (SwappedByteBuf)source(); + out = in.order(); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;readByte;;;Argument[-1];ReturnValue;taint;manual" + byte out = null; + AbstractByteBuf in = (AbstractByteBuf)source(); + out = in.readByte(); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;readByte;;;Argument[-1];ReturnValue;taint;manual" + byte out = null; + ByteBuf in = (ByteBuf)source(); + out = in.readByte(); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;readByte;;;Argument[-1];ReturnValue;taint;manual" + byte out = null; + SwappedByteBuf in = (SwappedByteBuf)source(); + out = in.readByte(); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;readBytes;;;Argument[-1];Argument[0];taint;manual" + ByteBuf out = null; + AbstractByteBuf in = (AbstractByteBuf)source(); + in.readBytes(out); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;readBytes;;;Argument[-1];Argument[0];taint;manual" + ByteBuf out = null; + AbstractByteBuf in = (AbstractByteBuf)source(); + in.readBytes(out, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;readBytes;;;Argument[-1];Argument[0];taint;manual" + ByteBuf out = null; + AbstractByteBuf in = (AbstractByteBuf)source(); + in.readBytes(out, 0, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;readBytes;;;Argument[-1];Argument[0];taint;manual" + ByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + in.readBytes(out); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;readBytes;;;Argument[-1];Argument[0];taint;manual" + ByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + in.readBytes(out, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;readBytes;;;Argument[-1];Argument[0];taint;manual" + ByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + in.readBytes(out, 0, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;readBytes;;;Argument[-1];Argument[0];taint;manual" + ByteBuf out = null; + CompositeByteBuf in = (CompositeByteBuf)source(); + in.readBytes(out); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;readBytes;;;Argument[-1];Argument[0];taint;manual" + ByteBuf out = null; + CompositeByteBuf in = (CompositeByteBuf)source(); + in.readBytes(out, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;readBytes;;;Argument[-1];Argument[0];taint;manual" + ByteBuf out = null; + CompositeByteBuf in = (CompositeByteBuf)source(); + in.readBytes(out, 0, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;readBytes;;;Argument[-1];Argument[0];taint;manual" + ByteBuf out = null; + SwappedByteBuf in = (SwappedByteBuf)source(); + in.readBytes(out); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;readBytes;;;Argument[-1];Argument[0];taint;manual" + ByteBuf out = null; + SwappedByteBuf in = (SwappedByteBuf)source(); + in.readBytes(out, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;readBytes;;;Argument[-1];Argument[0];taint;manual" + ByteBuf out = null; + SwappedByteBuf in = (SwappedByteBuf)source(); + in.readBytes(out, 0, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;readBytes;;;Argument[-1];Argument[0];taint;manual" + ByteBuffer out = null; + AbstractByteBuf in = (AbstractByteBuf)source(); + in.readBytes(out); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;readBytes;;;Argument[-1];Argument[0];taint;manual" + ByteBuffer out = null; + ByteBuf in = (ByteBuf)source(); + in.readBytes(out); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;readBytes;;;Argument[-1];Argument[0];taint;manual" + ByteBuffer out = null; + CompositeByteBuf in = (CompositeByteBuf)source(); + in.readBytes(out); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;readBytes;;;Argument[-1];Argument[0];taint;manual" + ByteBuffer out = null; + SwappedByteBuf in = (SwappedByteBuf)source(); + in.readBytes(out); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;readBytes;;;Argument[-1];Argument[0];taint;manual" + FileChannel out = null; + AbstractByteBuf in = (AbstractByteBuf)source(); + in.readBytes(out, 0L, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;readBytes;;;Argument[-1];Argument[0];taint;manual" + FileChannel out = null; + ByteBuf in = (ByteBuf)source(); + in.readBytes(out, 0L, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;readBytes;;;Argument[-1];Argument[0];taint;manual" + FileChannel out = null; + SwappedByteBuf in = (SwappedByteBuf)source(); + in.readBytes(out, 0L, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;readBytes;;;Argument[-1];Argument[0];taint;manual" + GatheringByteChannel out = null; + AbstractByteBuf in = (AbstractByteBuf)source(); + in.readBytes(out, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;readBytes;;;Argument[-1];Argument[0];taint;manual" + GatheringByteChannel out = null; + ByteBuf in = (ByteBuf)source(); + in.readBytes(out, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;readBytes;;;Argument[-1];Argument[0];taint;manual" + GatheringByteChannel out = null; + SwappedByteBuf in = (SwappedByteBuf)source(); + in.readBytes(out, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;readBytes;;;Argument[-1];Argument[0];taint;manual" + OutputStream out = null; + AbstractByteBuf in = (AbstractByteBuf)source(); + in.readBytes(out, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;readBytes;;;Argument[-1];Argument[0];taint;manual" + OutputStream out = null; + ByteBuf in = (ByteBuf)source(); + in.readBytes(out, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;readBytes;;;Argument[-1];Argument[0];taint;manual" + OutputStream out = null; + CompositeByteBuf in = (CompositeByteBuf)source(); + in.readBytes(out, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;readBytes;;;Argument[-1];Argument[0];taint;manual" + OutputStream out = null; + SwappedByteBuf in = (SwappedByteBuf)source(); + in.readBytes(out, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;readBytes;;;Argument[-1];Argument[0];taint;manual" + byte[] out = null; + AbstractByteBuf in = (AbstractByteBuf)source(); + in.readBytes(out); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;readBytes;;;Argument[-1];Argument[0];taint;manual" + byte[] out = null; + AbstractByteBuf in = (AbstractByteBuf)source(); + in.readBytes(out, 0, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;readBytes;;;Argument[-1];Argument[0];taint;manual" + byte[] out = null; + ByteBuf in = (ByteBuf)source(); + in.readBytes(out); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;readBytes;;;Argument[-1];Argument[0];taint;manual" + byte[] out = null; + ByteBuf in = (ByteBuf)source(); + in.readBytes(out, 0, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;readBytes;;;Argument[-1];Argument[0];taint;manual" + byte[] out = null; + CompositeByteBuf in = (CompositeByteBuf)source(); + in.readBytes(out); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;readBytes;;;Argument[-1];Argument[0];taint;manual" + byte[] out = null; + CompositeByteBuf in = (CompositeByteBuf)source(); + in.readBytes(out, 0, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;readBytes;;;Argument[-1];Argument[0];taint;manual" + byte[] out = null; + SwappedByteBuf in = (SwappedByteBuf)source(); + in.readBytes(out); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;readBytes;;;Argument[-1];Argument[0];taint;manual" + byte[] out = null; + SwappedByteBuf in = (SwappedByteBuf)source(); + in.readBytes(out, 0, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;readBytes;;;Argument[-1];Argument[0];taint;manual" + int out = null; + AbstractByteBuf in = (AbstractByteBuf)source(); + in.readBytes(out); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;readBytes;;;Argument[-1];Argument[0];taint;manual" + int out = null; + ByteBuf in = (ByteBuf)source(); + in.readBytes(out); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;readBytes;;;Argument[-1];Argument[0];taint;manual" + int out = null; + SwappedByteBuf in = (SwappedByteBuf)source(); + in.readBytes(out); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;readBytes;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + AbstractByteBuf in = (AbstractByteBuf)source(); + out = in.readBytes((ByteBuf)null); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;readBytes;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + AbstractByteBuf in = (AbstractByteBuf)source(); + out = in.readBytes((ByteBuf)null, 0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;readBytes;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + AbstractByteBuf in = (AbstractByteBuf)source(); + out = in.readBytes((ByteBuf)null, 0, 0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;readBytes;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + AbstractByteBuf in = (AbstractByteBuf)source(); + out = in.readBytes((ByteBuffer)null); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;readBytes;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + AbstractByteBuf in = (AbstractByteBuf)source(); + out = in.readBytes((OutputStream)null, 0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;readBytes;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + AbstractByteBuf in = (AbstractByteBuf)source(); + out = in.readBytes((byte[])null); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;readBytes;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + AbstractByteBuf in = (AbstractByteBuf)source(); + out = in.readBytes((byte[])null, 0, 0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;readBytes;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + AbstractByteBuf in = (AbstractByteBuf)source(); + out = in.readBytes(0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;readBytes;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out = in.readBytes((ByteBuf)null); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;readBytes;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out = in.readBytes((ByteBuf)null, 0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;readBytes;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out = in.readBytes((ByteBuf)null, 0, 0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;readBytes;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out = in.readBytes((ByteBuffer)null); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;readBytes;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out = in.readBytes((OutputStream)null, 0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;readBytes;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out = in.readBytes((byte[])null); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;readBytes;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out = in.readBytes((byte[])null, 0, 0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;readBytes;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out = in.readBytes(0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;readBytes;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + SwappedByteBuf in = (SwappedByteBuf)source(); + out = in.readBytes((ByteBuf)null); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;readBytes;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + SwappedByteBuf in = (SwappedByteBuf)source(); + out = in.readBytes((ByteBuf)null, 0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;readBytes;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + SwappedByteBuf in = (SwappedByteBuf)source(); + out = in.readBytes((ByteBuf)null, 0, 0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;readBytes;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + SwappedByteBuf in = (SwappedByteBuf)source(); + out = in.readBytes((ByteBuffer)null); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;readBytes;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + SwappedByteBuf in = (SwappedByteBuf)source(); + out = in.readBytes((OutputStream)null, 0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;readBytes;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + SwappedByteBuf in = (SwappedByteBuf)source(); + out = in.readBytes((byte[])null); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;readBytes;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + SwappedByteBuf in = (SwappedByteBuf)source(); + out = in.readBytes((byte[])null, 0, 0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;readBytes;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + SwappedByteBuf in = (SwappedByteBuf)source(); + out = in.readBytes(0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;readBytes;;;Argument[-1];ReturnValue;value;manual" + CompositeByteBuf out = null; + CompositeByteBuf in = (CompositeByteBuf)source(); + out = in.readBytes((ByteBuf)null); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;readBytes;;;Argument[-1];ReturnValue;value;manual" + CompositeByteBuf out = null; + CompositeByteBuf in = (CompositeByteBuf)source(); + out = in.readBytes((ByteBuf)null, 0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;readBytes;;;Argument[-1];ReturnValue;value;manual" + CompositeByteBuf out = null; + CompositeByteBuf in = (CompositeByteBuf)source(); + out = in.readBytes((ByteBuf)null, 0, 0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;readBytes;;;Argument[-1];ReturnValue;value;manual" + CompositeByteBuf out = null; + CompositeByteBuf in = (CompositeByteBuf)source(); + out = in.readBytes((ByteBuffer)null); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;readBytes;;;Argument[-1];ReturnValue;value;manual" + CompositeByteBuf out = null; + CompositeByteBuf in = (CompositeByteBuf)source(); + out = in.readBytes((OutputStream)null, 0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;readBytes;;;Argument[-1];ReturnValue;value;manual" + CompositeByteBuf out = null; + CompositeByteBuf in = (CompositeByteBuf)source(); + out = in.readBytes((byte[])null); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;readBytes;;;Argument[-1];ReturnValue;value;manual" + CompositeByteBuf out = null; + CompositeByteBuf in = (CompositeByteBuf)source(); + out = in.readBytes((byte[])null, 0, 0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;readBytes;;;Argument[-1];ReturnValue;value;manual" + int out = null; + AbstractByteBuf in = (AbstractByteBuf)source(); + out = in.readBytes((FileChannel)null, 0L, 0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;readBytes;;;Argument[-1];ReturnValue;value;manual" + int out = null; + AbstractByteBuf in = (AbstractByteBuf)source(); + out = in.readBytes((GatheringByteChannel)null, 0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;readBytes;;;Argument[-1];ReturnValue;value;manual" + int out = null; + ByteBuf in = (ByteBuf)source(); + out = in.readBytes((FileChannel)null, 0L, 0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;readBytes;;;Argument[-1];ReturnValue;value;manual" + int out = null; + ByteBuf in = (ByteBuf)source(); + out = in.readBytes((GatheringByteChannel)null, 0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;readBytes;;;Argument[-1];ReturnValue;value;manual" + int out = null; + SwappedByteBuf in = (SwappedByteBuf)source(); + out = in.readBytes((FileChannel)null, 0L, 0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;readBytes;;;Argument[-1];ReturnValue;value;manual" + int out = null; + SwappedByteBuf in = (SwappedByteBuf)source(); + out = in.readBytes((GatheringByteChannel)null, 0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;readChar;;;Argument[-1];ReturnValue;taint;manual" + char out = null; + AbstractByteBuf in = (AbstractByteBuf)source(); + out = in.readChar(); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;readChar;;;Argument[-1];ReturnValue;taint;manual" + char out = null; + ByteBuf in = (ByteBuf)source(); + out = in.readChar(); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;readChar;;;Argument[-1];ReturnValue;taint;manual" + char out = null; + SwappedByteBuf in = (SwappedByteBuf)source(); + out = in.readChar(); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;readCharSequence;;;Argument[-1];ReturnValue;taint;manual" + CharSequence out = null; + AbstractByteBuf in = (AbstractByteBuf)source(); + out = in.readCharSequence(0, null); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;readCharSequence;;;Argument[-1];ReturnValue;taint;manual" + CharSequence out = null; + ByteBuf in = (ByteBuf)source(); + out = in.readCharSequence(0, null); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;readCharSequence;;;Argument[-1];ReturnValue;taint;manual" + CharSequence out = null; + SwappedByteBuf in = (SwappedByteBuf)source(); + out = in.readCharSequence(0, null); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;readSlice;;;Argument[-1];ReturnValue;taint;manual" + ByteBuf out = null; + AbstractByteBuf in = (AbstractByteBuf)source(); + out = in.readSlice(0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;readSlice;;;Argument[-1];ReturnValue;taint;manual" + ByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out = in.readSlice(0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;readSlice;;;Argument[-1];ReturnValue;taint;manual" + ByteBuf out = null; + SwappedByteBuf in = (SwappedByteBuf)source(); + out = in.readSlice(0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;readerIndex;(int);;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + AbstractByteBuf in = (AbstractByteBuf)source(); + out = in.readerIndex(0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;readerIndex;(int);;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out = in.readerIndex(0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;readerIndex;(int);;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + SwappedByteBuf in = (SwappedByteBuf)source(); + out = in.readerIndex(0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;readerIndex;(int);;Argument[-1];ReturnValue;value;manual" + CompositeByteBuf out = null; + CompositeByteBuf in = (CompositeByteBuf)source(); + out = in.readerIndex(0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;resetReaderIndex;();;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + AbstractByteBuf in = (AbstractByteBuf)source(); + out = in.resetReaderIndex(); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;resetReaderIndex;();;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out = in.resetReaderIndex(); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;resetReaderIndex;();;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + SwappedByteBuf in = (SwappedByteBuf)source(); + out = in.resetReaderIndex(); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;resetReaderIndex;();;Argument[-1];ReturnValue;value;manual" + CompositeByteBuf out = null; + CompositeByteBuf in = (CompositeByteBuf)source(); + out = in.resetReaderIndex(); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;resetWriterIndex;();;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + AbstractByteBuf in = (AbstractByteBuf)source(); + out = in.resetWriterIndex(); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;resetWriterIndex;();;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out = in.resetWriterIndex(); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;resetWriterIndex;();;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + SwappedByteBuf in = (SwappedByteBuf)source(); + out = in.resetWriterIndex(); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;resetWriterIndex;();;Argument[-1];ReturnValue;value;manual" + CompositeByteBuf out = null; + CompositeByteBuf in = (CompositeByteBuf)source(); + out = in.resetWriterIndex(); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;retainedDuplicate;();;Argument[-1];ReturnValue;taint;manual" + ByteBuf out = null; + AbstractByteBuf in = (AbstractByteBuf)source(); + out = in.retainedDuplicate(); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;retainedDuplicate;();;Argument[-1];ReturnValue;taint;manual" + ByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out = in.retainedDuplicate(); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;retainedDuplicate;();;Argument[-1];ReturnValue;taint;manual" + ByteBuf out = null; + SwappedByteBuf in = (SwappedByteBuf)source(); + out = in.retainedDuplicate(); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;retainedSlice;;;Argument[-1];ReturnValue;taint;manual" + ByteBuf out = null; + AbstractByteBuf in = (AbstractByteBuf)source(); + out = in.retainedSlice(); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;retainedSlice;;;Argument[-1];ReturnValue;taint;manual" + ByteBuf out = null; + AbstractByteBuf in = (AbstractByteBuf)source(); + out = in.retainedSlice(0, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;retainedSlice;;;Argument[-1];ReturnValue;taint;manual" + ByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out = in.retainedSlice(); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;retainedSlice;;;Argument[-1];ReturnValue;taint;manual" + ByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out = in.retainedSlice(0, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;retainedSlice;;;Argument[-1];ReturnValue;taint;manual" + ByteBuf out = null; + SwappedByteBuf in = (SwappedByteBuf)source(); + out = in.retainedSlice(); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;retainedSlice;;;Argument[-1];ReturnValue;taint;manual" + ByteBuf out = null; + SwappedByteBuf in = (SwappedByteBuf)source(); + out = in.retainedSlice(0, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;setBoolean;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + AbstractByteBuf in = (AbstractByteBuf)source(); + out = in.setBoolean(0, false); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;setBoolean;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out = in.setBoolean(0, false); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;setBoolean;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + SwappedByteBuf in = (SwappedByteBuf)source(); + out = in.setBoolean(0, false); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;setBoolean;;;Argument[-1];ReturnValue;value;manual" + CompositeByteBuf out = null; + CompositeByteBuf in = (CompositeByteBuf)source(); + out = in.setBoolean(0, false); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;setByte;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + AbstractByteBuf in = (AbstractByteBuf)source(); + out = in.setByte(0, 0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;setByte;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out = in.setByte(0, 0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;setByte;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + SwappedByteBuf in = (SwappedByteBuf)source(); + out = in.setByte(0, 0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;setByte;;;Argument[-1];ReturnValue;value;manual" + CompositeByteBuf out = null; + CompositeByteBuf in = (CompositeByteBuf)source(); + out = in.setByte(0, 0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;setByte;;;Argument[1];Argument[-1];taint;manual" + AbstractByteBuf out = null; + int in = (int)source(); + out.setByte(0, in); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;setByte;;;Argument[1];Argument[-1];taint;manual" + ByteBuf out = null; + int in = (int)source(); + out.setByte(0, in); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;setByte;;;Argument[1];Argument[-1];taint;manual" + CompositeByteBuf out = null; + int in = (int)source(); + out.setByte(0, in); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;setByte;;;Argument[1];Argument[-1];taint;manual" + SwappedByteBuf out = null; + int in = (int)source(); + out.setByte(0, in); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;setBytes;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + AbstractByteBuf in = (AbstractByteBuf)source(); + out = in.setBytes(0, (ByteBuf)null); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;setBytes;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + AbstractByteBuf in = (AbstractByteBuf)source(); + out = in.setBytes(0, (byte[])null); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;setBytes;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + AbstractByteBuf in = (AbstractByteBuf)source(); + out = in.setBytes(0, null, 0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;setBytes;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out = in.setBytes(0, (ByteBuf)null); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;setBytes;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out = in.setBytes(0, (ByteBuf)null, 0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;setBytes;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out = in.setBytes(0, (ByteBuf)null, 0, 0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;setBytes;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out = in.setBytes(0, (ByteBuffer)null); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;setBytes;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out = in.setBytes(0, (byte[])null); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;setBytes;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out = in.setBytes(0, (byte[])null, 0, 0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;setBytes;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + SwappedByteBuf in = (SwappedByteBuf)source(); + out = in.setBytes(0, (ByteBuf)null); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;setBytes;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + SwappedByteBuf in = (SwappedByteBuf)source(); + out = in.setBytes(0, (ByteBuf)null, 0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;setBytes;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + SwappedByteBuf in = (SwappedByteBuf)source(); + out = in.setBytes(0, (ByteBuf)null, 0, 0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;setBytes;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + SwappedByteBuf in = (SwappedByteBuf)source(); + out = in.setBytes(0, (ByteBuffer)null); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;setBytes;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + SwappedByteBuf in = (SwappedByteBuf)source(); + out = in.setBytes(0, (byte[])null); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;setBytes;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + SwappedByteBuf in = (SwappedByteBuf)source(); + out = in.setBytes(0, (byte[])null, 0, 0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;setBytes;;;Argument[-1];ReturnValue;value;manual" + CompositeByteBuf out = null; + CompositeByteBuf in = (CompositeByteBuf)source(); + out = in.setBytes(0, (ByteBuf)null); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;setBytes;;;Argument[-1];ReturnValue;value;manual" + CompositeByteBuf out = null; + CompositeByteBuf in = (CompositeByteBuf)source(); + out = in.setBytes(0, (ByteBuf)null, 0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;setBytes;;;Argument[-1];ReturnValue;value;manual" + CompositeByteBuf out = null; + CompositeByteBuf in = (CompositeByteBuf)source(); + out = in.setBytes(0, (ByteBuf)null, 0, 0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;setBytes;;;Argument[-1];ReturnValue;value;manual" + CompositeByteBuf out = null; + CompositeByteBuf in = (CompositeByteBuf)source(); + out = in.setBytes(0, (ByteBuffer)null); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;setBytes;;;Argument[-1];ReturnValue;value;manual" + CompositeByteBuf out = null; + CompositeByteBuf in = (CompositeByteBuf)source(); + out = in.setBytes(0, (byte[])null); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;setBytes;;;Argument[-1];ReturnValue;value;manual" + CompositeByteBuf out = null; + CompositeByteBuf in = (CompositeByteBuf)source(); + out = in.setBytes(0, (byte[])null, 0, 0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;setBytes;;;Argument[-1];ReturnValue;value;manual" + int out = null; + ByteBuf in = (ByteBuf)source(); + out = in.setBytes(0, (FileChannel)null, 0L, 0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;setBytes;;;Argument[-1];ReturnValue;value;manual" + int out = null; + ByteBuf in = (ByteBuf)source(); + out = in.setBytes(0, (InputStream)null, 0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;setBytes;;;Argument[-1];ReturnValue;value;manual" + int out = null; + ByteBuf in = (ByteBuf)source(); + out = in.setBytes(0, (ScatteringByteChannel)null, 0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;setBytes;;;Argument[-1];ReturnValue;value;manual" + int out = null; + CompositeByteBuf in = (CompositeByteBuf)source(); + out = in.setBytes(0, (FileChannel)null, 0L, 0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;setBytes;;;Argument[-1];ReturnValue;value;manual" + int out = null; + CompositeByteBuf in = (CompositeByteBuf)source(); + out = in.setBytes(0, (InputStream)null, 0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;setBytes;;;Argument[-1];ReturnValue;value;manual" + int out = null; + CompositeByteBuf in = (CompositeByteBuf)source(); + out = in.setBytes(0, (ScatteringByteChannel)null, 0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;setBytes;;;Argument[-1];ReturnValue;value;manual" + int out = null; + SwappedByteBuf in = (SwappedByteBuf)source(); + out = in.setBytes(0, (FileChannel)null, 0L, 0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;setBytes;;;Argument[-1];ReturnValue;value;manual" + int out = null; + SwappedByteBuf in = (SwappedByteBuf)source(); + out = in.setBytes(0, (InputStream)null, 0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;setBytes;;;Argument[-1];ReturnValue;value;manual" + int out = null; + SwappedByteBuf in = (SwappedByteBuf)source(); + out = in.setBytes(0, (ScatteringByteChannel)null, 0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;setBytes;;;Argument[1];Argument[-1];taint;manual" + AbstractByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out.setBytes(0, in); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;setBytes;;;Argument[1];Argument[-1];taint;manual" + AbstractByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out.setBytes(0, in, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;setBytes;;;Argument[1];Argument[-1];taint;manual" + AbstractByteBuf out = null; + byte[] in = (byte[])source(); + out.setBytes(0, in); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;setBytes;;;Argument[1];Argument[-1];taint;manual" + ByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out.setBytes(0, in); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;setBytes;;;Argument[1];Argument[-1];taint;manual" + ByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out.setBytes(0, in, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;setBytes;;;Argument[1];Argument[-1];taint;manual" + ByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out.setBytes(0, in, 0, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;setBytes;;;Argument[1];Argument[-1];taint;manual" + ByteBuf out = null; + ByteBuffer in = (ByteBuffer)source(); + out.setBytes(0, in); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;setBytes;;;Argument[1];Argument[-1];taint;manual" + ByteBuf out = null; + FileChannel in = (FileChannel)source(); + out.setBytes(0, in, 0L, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;setBytes;;;Argument[1];Argument[-1];taint;manual" + ByteBuf out = null; + InputStream in = (InputStream)source(); + out.setBytes(0, in, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;setBytes;;;Argument[1];Argument[-1];taint;manual" + ByteBuf out = null; + ScatteringByteChannel in = (ScatteringByteChannel)source(); + out.setBytes(0, in, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;setBytes;;;Argument[1];Argument[-1];taint;manual" + ByteBuf out = null; + byte[] in = (byte[])source(); + out.setBytes(0, in); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;setBytes;;;Argument[1];Argument[-1];taint;manual" + ByteBuf out = null; + byte[] in = (byte[])source(); + out.setBytes(0, in, 0, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;setBytes;;;Argument[1];Argument[-1];taint;manual" + CompositeByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out.setBytes(0, in); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;setBytes;;;Argument[1];Argument[-1];taint;manual" + CompositeByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out.setBytes(0, in, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;setBytes;;;Argument[1];Argument[-1];taint;manual" + CompositeByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out.setBytes(0, in, 0, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;setBytes;;;Argument[1];Argument[-1];taint;manual" + CompositeByteBuf out = null; + ByteBuffer in = (ByteBuffer)source(); + out.setBytes(0, in); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;setBytes;;;Argument[1];Argument[-1];taint;manual" + CompositeByteBuf out = null; + FileChannel in = (FileChannel)source(); + out.setBytes(0, in, 0L, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;setBytes;;;Argument[1];Argument[-1];taint;manual" + CompositeByteBuf out = null; + InputStream in = (InputStream)source(); + out.setBytes(0, in, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;setBytes;;;Argument[1];Argument[-1];taint;manual" + CompositeByteBuf out = null; + ScatteringByteChannel in = (ScatteringByteChannel)source(); + out.setBytes(0, in, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;setBytes;;;Argument[1];Argument[-1];taint;manual" + CompositeByteBuf out = null; + byte[] in = (byte[])source(); + out.setBytes(0, in); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;setBytes;;;Argument[1];Argument[-1];taint;manual" + CompositeByteBuf out = null; + byte[] in = (byte[])source(); + out.setBytes(0, in, 0, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;setBytes;;;Argument[1];Argument[-1];taint;manual" + SwappedByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out.setBytes(0, in); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;setBytes;;;Argument[1];Argument[-1];taint;manual" + SwappedByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out.setBytes(0, in, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;setBytes;;;Argument[1];Argument[-1];taint;manual" + SwappedByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out.setBytes(0, in, 0, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;setBytes;;;Argument[1];Argument[-1];taint;manual" + SwappedByteBuf out = null; + ByteBuffer in = (ByteBuffer)source(); + out.setBytes(0, in); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;setBytes;;;Argument[1];Argument[-1];taint;manual" + SwappedByteBuf out = null; + FileChannel in = (FileChannel)source(); + out.setBytes(0, in, 0L, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;setBytes;;;Argument[1];Argument[-1];taint;manual" + SwappedByteBuf out = null; + InputStream in = (InputStream)source(); + out.setBytes(0, in, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;setBytes;;;Argument[1];Argument[-1];taint;manual" + SwappedByteBuf out = null; + ScatteringByteChannel in = (ScatteringByteChannel)source(); + out.setBytes(0, in, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;setBytes;;;Argument[1];Argument[-1];taint;manual" + SwappedByteBuf out = null; + byte[] in = (byte[])source(); + out.setBytes(0, in); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;setBytes;;;Argument[1];Argument[-1];taint;manual" + SwappedByteBuf out = null; + byte[] in = (byte[])source(); + out.setBytes(0, in, 0, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;setChar;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + AbstractByteBuf in = (AbstractByteBuf)source(); + out = in.setChar(0, 0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;setChar;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out = in.setChar(0, 0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;setChar;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + SwappedByteBuf in = (SwappedByteBuf)source(); + out = in.setChar(0, 0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;setChar;;;Argument[-1];ReturnValue;value;manual" + CompositeByteBuf out = null; + CompositeByteBuf in = (CompositeByteBuf)source(); + out = in.setChar(0, 0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;setChar;;;Argument[1];Argument[-1];taint;manual" + AbstractByteBuf out = null; + int in = (int)source(); + out.setChar(0, in); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;setChar;;;Argument[1];Argument[-1];taint;manual" + ByteBuf out = null; + int in = (int)source(); + out.setChar(0, in); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;setChar;;;Argument[1];Argument[-1];taint;manual" + CompositeByteBuf out = null; + int in = (int)source(); + out.setChar(0, in); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;setChar;;;Argument[1];Argument[-1];taint;manual" + SwappedByteBuf out = null; + int in = (int)source(); + out.setChar(0, in); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;setCharSequence;;;Argument[-1];ReturnValue;value;manual" + int out = null; + AbstractByteBuf in = (AbstractByteBuf)source(); + out = in.setCharSequence(0, null, null); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;setCharSequence;;;Argument[-1];ReturnValue;value;manual" + int out = null; + ByteBuf in = (ByteBuf)source(); + out = in.setCharSequence(0, null, null); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;setCharSequence;;;Argument[-1];ReturnValue;value;manual" + int out = null; + SwappedByteBuf in = (SwappedByteBuf)source(); + out = in.setCharSequence(0, null, null); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;setCharSequence;;;Argument[1];Argument[-1];taint;manual" + AbstractByteBuf out = null; + CharSequence in = (CharSequence)source(); + out.setCharSequence(0, in, null); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;setCharSequence;;;Argument[1];Argument[-1];taint;manual" + ByteBuf out = null; + CharSequence in = (CharSequence)source(); + out.setCharSequence(0, in, null); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;setCharSequence;;;Argument[1];Argument[-1];taint;manual" + SwappedByteBuf out = null; + CharSequence in = (CharSequence)source(); + out.setCharSequence(0, in, null); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;setDouble;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + AbstractByteBuf in = (AbstractByteBuf)source(); + out = in.setDouble(0, 0.0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;setDouble;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out = in.setDouble(0, 0.0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;setDouble;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + SwappedByteBuf in = (SwappedByteBuf)source(); + out = in.setDouble(0, 0.0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;setDouble;;;Argument[-1];ReturnValue;value;manual" + CompositeByteBuf out = null; + CompositeByteBuf in = (CompositeByteBuf)source(); + out = in.setDouble(0, 0.0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;setDoubleLE;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out = in.setDoubleLE(0, 0.0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;setFloat;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + AbstractByteBuf in = (AbstractByteBuf)source(); + out = in.setFloat(0, 0.0f); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;setFloat;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out = in.setFloat(0, 0.0f); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;setFloat;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + SwappedByteBuf in = (SwappedByteBuf)source(); + out = in.setFloat(0, 0.0f); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;setFloat;;;Argument[-1];ReturnValue;value;manual" + CompositeByteBuf out = null; + CompositeByteBuf in = (CompositeByteBuf)source(); + out = in.setFloat(0, 0.0f); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;setFloatLE;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out = in.setFloatLE(0, 0.0f); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;setIndex;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + AbstractByteBuf in = (AbstractByteBuf)source(); + out = in.setIndex(0, 0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;setIndex;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out = in.setIndex(0, 0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;setIndex;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + SwappedByteBuf in = (SwappedByteBuf)source(); + out = in.setIndex(0, 0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;setIndex;;;Argument[-1];ReturnValue;value;manual" + CompositeByteBuf out = null; + CompositeByteBuf in = (CompositeByteBuf)source(); + out = in.setIndex(0, 0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;setInt;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + AbstractByteBuf in = (AbstractByteBuf)source(); + out = in.setInt(0, 0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;setInt;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out = in.setInt(0, 0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;setInt;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + SwappedByteBuf in = (SwappedByteBuf)source(); + out = in.setInt(0, 0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;setInt;;;Argument[-1];ReturnValue;value;manual" + CompositeByteBuf out = null; + CompositeByteBuf in = (CompositeByteBuf)source(); + out = in.setInt(0, 0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;setIntLE;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + AbstractByteBuf in = (AbstractByteBuf)source(); + out = in.setIntLE(0, 0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;setIntLE;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out = in.setIntLE(0, 0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;setIntLE;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + SwappedByteBuf in = (SwappedByteBuf)source(); + out = in.setIntLE(0, 0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;setLong;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + AbstractByteBuf in = (AbstractByteBuf)source(); + out = in.setLong(0, 0L); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;setLong;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out = in.setLong(0, 0L); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;setLong;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + SwappedByteBuf in = (SwappedByteBuf)source(); + out = in.setLong(0, 0L); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;setLong;;;Argument[-1];ReturnValue;value;manual" + CompositeByteBuf out = null; + CompositeByteBuf in = (CompositeByteBuf)source(); + out = in.setLong(0, 0L); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;setLongLE;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + AbstractByteBuf in = (AbstractByteBuf)source(); + out = in.setLongLE(0, 0L); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;setLongLE;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out = in.setLongLE(0, 0L); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;setLongLE;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + SwappedByteBuf in = (SwappedByteBuf)source(); + out = in.setLongLE(0, 0L); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;setMedium;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + AbstractByteBuf in = (AbstractByteBuf)source(); + out = in.setMedium(0, 0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;setMedium;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out = in.setMedium(0, 0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;setMedium;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + SwappedByteBuf in = (SwappedByteBuf)source(); + out = in.setMedium(0, 0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;setMedium;;;Argument[-1];ReturnValue;value;manual" + CompositeByteBuf out = null; + CompositeByteBuf in = (CompositeByteBuf)source(); + out = in.setMedium(0, 0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;setMediumLE;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + AbstractByteBuf in = (AbstractByteBuf)source(); + out = in.setMediumLE(0, 0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;setMediumLE;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out = in.setMediumLE(0, 0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;setMediumLE;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + SwappedByteBuf in = (SwappedByteBuf)source(); + out = in.setMediumLE(0, 0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;setShort;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + AbstractByteBuf in = (AbstractByteBuf)source(); + out = in.setShort(0, 0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;setShort;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out = in.setShort(0, 0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;setShort;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + SwappedByteBuf in = (SwappedByteBuf)source(); + out = in.setShort(0, 0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;setShort;;;Argument[-1];ReturnValue;value;manual" + CompositeByteBuf out = null; + CompositeByteBuf in = (CompositeByteBuf)source(); + out = in.setShort(0, 0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;setShortLE;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + AbstractByteBuf in = (AbstractByteBuf)source(); + out = in.setShortLE(0, 0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;setShortLE;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out = in.setShortLE(0, 0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;setShortLE;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + SwappedByteBuf in = (SwappedByteBuf)source(); + out = in.setShortLE(0, 0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;setZero;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + AbstractByteBuf in = (AbstractByteBuf)source(); + out = in.setZero(0, 0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;setZero;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out = in.setZero(0, 0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;setZero;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + SwappedByteBuf in = (SwappedByteBuf)source(); + out = in.setZero(0, 0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;setZero;;;Argument[-1];ReturnValue;value;manual" + CompositeByteBuf out = null; + CompositeByteBuf in = (CompositeByteBuf)source(); + out = in.setZero(0, 0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;skipBytes;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + AbstractByteBuf in = (AbstractByteBuf)source(); + out = in.skipBytes(0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;skipBytes;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out = in.skipBytes(0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;skipBytes;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + SwappedByteBuf in = (SwappedByteBuf)source(); + out = in.skipBytes(0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;skipBytes;;;Argument[-1];ReturnValue;value;manual" + CompositeByteBuf out = null; + CompositeByteBuf in = (CompositeByteBuf)source(); + out = in.skipBytes(0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;slice;();;Argument[-1];ReturnValue;taint;manual" + ByteBuf out = null; + AbstractByteBuf in = (AbstractByteBuf)source(); + out = in.slice(); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;slice;();;Argument[-1];ReturnValue;taint;manual" + ByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out = in.slice(); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;slice;();;Argument[-1];ReturnValue;taint;manual" + ByteBuf out = null; + SwappedByteBuf in = (SwappedByteBuf)source(); + out = in.slice(); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;toString;;;Argument[-1];ReturnValue;taint;manual" + String out = null; + AbstractByteBuf in = (AbstractByteBuf)source(); + out = in.toString(); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;toString;;;Argument[-1];ReturnValue;taint;manual" + String out = null; + AbstractByteBuf in = (AbstractByteBuf)source(); + out = in.toString(0, 0, null); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;toString;;;Argument[-1];ReturnValue;taint;manual" + String out = null; + AbstractByteBuf in = (AbstractByteBuf)source(); + out = in.toString(null); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;toString;;;Argument[-1];ReturnValue;taint;manual" + String out = null; + ByteBuf in = (ByteBuf)source(); + out = in.toString(); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;toString;;;Argument[-1];ReturnValue;taint;manual" + String out = null; + ByteBuf in = (ByteBuf)source(); + out = in.toString(0, 0, null); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;toString;;;Argument[-1];ReturnValue;taint;manual" + String out = null; + ByteBuf in = (ByteBuf)source(); + out = in.toString(null); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;toString;;;Argument[-1];ReturnValue;taint;manual" + String out = null; + CompositeByteBuf in = (CompositeByteBuf)source(); + out = in.toString(); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;toString;;;Argument[-1];ReturnValue;taint;manual" + String out = null; + SwappedByteBuf in = (SwappedByteBuf)source(); + out = in.toString(); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;toString;;;Argument[-1];ReturnValue;taint;manual" + String out = null; + SwappedByteBuf in = (SwappedByteBuf)source(); + out = in.toString(0, 0, null); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;toString;;;Argument[-1];ReturnValue;taint;manual" + String out = null; + SwappedByteBuf in = (SwappedByteBuf)source(); + out = in.toString(null); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;unwrap;();;Argument[-1];ReturnValue;taint;manual" + ByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out = in.unwrap(); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;unwrap;();;Argument[-1];ReturnValue;taint;manual" + ByteBuf out = null; + CompositeByteBuf in = (CompositeByteBuf)source(); + out = in.unwrap(); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;unwrap;();;Argument[-1];ReturnValue;taint;manual" + ByteBuf out = null; + SwappedByteBuf in = (SwappedByteBuf)source(); + out = in.unwrap(); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeByte;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + AbstractByteBuf in = (AbstractByteBuf)source(); + out = in.writeByte(0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeByte;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out = in.writeByte(0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeByte;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + SwappedByteBuf in = (SwappedByteBuf)source(); + out = in.writeByte(0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeByte;;;Argument[-1];ReturnValue;value;manual" + CompositeByteBuf out = null; + CompositeByteBuf in = (CompositeByteBuf)source(); + out = in.writeByte(0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeByte;;;Argument[0];Argument[-1];taint;manual" + AbstractByteBuf out = null; + int in = (int)source(); + out.writeByte(in); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeByte;;;Argument[0];Argument[-1];taint;manual" + ByteBuf out = null; + int in = (int)source(); + out.writeByte(in); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeByte;;;Argument[0];Argument[-1];taint;manual" + CompositeByteBuf out = null; + int in = (int)source(); + out.writeByte(in); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeByte;;;Argument[0];Argument[-1];taint;manual" + SwappedByteBuf out = null; + int in = (int)source(); + out.writeByte(in); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeBytes;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + AbstractByteBuf in = (AbstractByteBuf)source(); + out = in.writeBytes((ByteBuf)null); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeBytes;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + AbstractByteBuf in = (AbstractByteBuf)source(); + out = in.writeBytes((ByteBuf)null, 0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeBytes;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + AbstractByteBuf in = (AbstractByteBuf)source(); + out = in.writeBytes((ByteBuf)null, 0, 0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeBytes;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + AbstractByteBuf in = (AbstractByteBuf)source(); + out = in.writeBytes((ByteBuffer)null); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeBytes;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + AbstractByteBuf in = (AbstractByteBuf)source(); + out = in.writeBytes((byte[])null); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeBytes;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + AbstractByteBuf in = (AbstractByteBuf)source(); + out = in.writeBytes((byte[])null, 0, 0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeBytes;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out = in.writeBytes((ByteBuf)null); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeBytes;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out = in.writeBytes((ByteBuf)null, 0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeBytes;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out = in.writeBytes((ByteBuf)null, 0, 0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeBytes;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out = in.writeBytes((ByteBuffer)null); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeBytes;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out = in.writeBytes((byte[])null); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeBytes;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out = in.writeBytes((byte[])null, 0, 0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeBytes;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + SwappedByteBuf in = (SwappedByteBuf)source(); + out = in.writeBytes((ByteBuf)null); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeBytes;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + SwappedByteBuf in = (SwappedByteBuf)source(); + out = in.writeBytes((ByteBuf)null, 0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeBytes;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + SwappedByteBuf in = (SwappedByteBuf)source(); + out = in.writeBytes((ByteBuf)null, 0, 0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeBytes;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + SwappedByteBuf in = (SwappedByteBuf)source(); + out = in.writeBytes((ByteBuffer)null); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeBytes;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + SwappedByteBuf in = (SwappedByteBuf)source(); + out = in.writeBytes((byte[])null); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeBytes;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + SwappedByteBuf in = (SwappedByteBuf)source(); + out = in.writeBytes((byte[])null, 0, 0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeBytes;;;Argument[-1];ReturnValue;value;manual" + CompositeByteBuf out = null; + CompositeByteBuf in = (CompositeByteBuf)source(); + out = in.writeBytes((ByteBuf)null); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeBytes;;;Argument[-1];ReturnValue;value;manual" + CompositeByteBuf out = null; + CompositeByteBuf in = (CompositeByteBuf)source(); + out = in.writeBytes((ByteBuf)null, 0, 0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeBytes;;;Argument[-1];ReturnValue;value;manual" + CompositeByteBuf out = null; + CompositeByteBuf in = (CompositeByteBuf)source(); + out = in.writeBytes((ByteBuffer)null); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeBytes;;;Argument[-1];ReturnValue;value;manual" + CompositeByteBuf out = null; + CompositeByteBuf in = (CompositeByteBuf)source(); + out = in.writeBytes((byte[])null); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeBytes;;;Argument[-1];ReturnValue;value;manual" + CompositeByteBuf out = null; + CompositeByteBuf in = (CompositeByteBuf)source(); + out = in.writeBytes((byte[])null, 0, 0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeBytes;;;Argument[-1];ReturnValue;value;manual" + CompositeByteBuf out = null; + CompositeByteBuf in = (CompositeByteBuf)source(); + out = in.writeBytes(null, 0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeBytes;;;Argument[-1];ReturnValue;value;manual" + int out = null; + AbstractByteBuf in = (AbstractByteBuf)source(); + out = in.writeBytes((FileChannel)null, 0L, 0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeBytes;;;Argument[-1];ReturnValue;value;manual" + int out = null; + AbstractByteBuf in = (AbstractByteBuf)source(); + out = in.writeBytes((InputStream)null, 0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeBytes;;;Argument[-1];ReturnValue;value;manual" + int out = null; + AbstractByteBuf in = (AbstractByteBuf)source(); + out = in.writeBytes((ScatteringByteChannel)null, 0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeBytes;;;Argument[-1];ReturnValue;value;manual" + int out = null; + ByteBuf in = (ByteBuf)source(); + out = in.writeBytes((FileChannel)null, 0L, 0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeBytes;;;Argument[-1];ReturnValue;value;manual" + int out = null; + ByteBuf in = (ByteBuf)source(); + out = in.writeBytes((InputStream)null, 0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeBytes;;;Argument[-1];ReturnValue;value;manual" + int out = null; + ByteBuf in = (ByteBuf)source(); + out = in.writeBytes((ScatteringByteChannel)null, 0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeBytes;;;Argument[-1];ReturnValue;value;manual" + int out = null; + SwappedByteBuf in = (SwappedByteBuf)source(); + out = in.writeBytes((FileChannel)null, 0L, 0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeBytes;;;Argument[-1];ReturnValue;value;manual" + int out = null; + SwappedByteBuf in = (SwappedByteBuf)source(); + out = in.writeBytes((InputStream)null, 0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeBytes;;;Argument[-1];ReturnValue;value;manual" + int out = null; + SwappedByteBuf in = (SwappedByteBuf)source(); + out = in.writeBytes((ScatteringByteChannel)null, 0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeBytes;;;Argument[0];Argument[-1];taint;manual" + AbstractByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out.writeBytes(in); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeBytes;;;Argument[0];Argument[-1];taint;manual" + AbstractByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out.writeBytes(in, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeBytes;;;Argument[0];Argument[-1];taint;manual" + AbstractByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out.writeBytes(in, 0, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeBytes;;;Argument[0];Argument[-1];taint;manual" + AbstractByteBuf out = null; + ByteBuffer in = (ByteBuffer)source(); + out.writeBytes(in); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeBytes;;;Argument[0];Argument[-1];taint;manual" + AbstractByteBuf out = null; + FileChannel in = (FileChannel)source(); + out.writeBytes(in, 0L, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeBytes;;;Argument[0];Argument[-1];taint;manual" + AbstractByteBuf out = null; + InputStream in = (InputStream)source(); + out.writeBytes(in, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeBytes;;;Argument[0];Argument[-1];taint;manual" + AbstractByteBuf out = null; + ScatteringByteChannel in = (ScatteringByteChannel)source(); + out.writeBytes(in, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeBytes;;;Argument[0];Argument[-1];taint;manual" + AbstractByteBuf out = null; + byte[] in = (byte[])source(); + out.writeBytes(in); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeBytes;;;Argument[0];Argument[-1];taint;manual" + AbstractByteBuf out = null; + byte[] in = (byte[])source(); + out.writeBytes(in, 0, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeBytes;;;Argument[0];Argument[-1];taint;manual" + ByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out.writeBytes(in); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeBytes;;;Argument[0];Argument[-1];taint;manual" + ByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out.writeBytes(in, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeBytes;;;Argument[0];Argument[-1];taint;manual" + ByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out.writeBytes(in, 0, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeBytes;;;Argument[0];Argument[-1];taint;manual" + ByteBuf out = null; + ByteBuffer in = (ByteBuffer)source(); + out.writeBytes(in); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeBytes;;;Argument[0];Argument[-1];taint;manual" + ByteBuf out = null; + FileChannel in = (FileChannel)source(); + out.writeBytes(in, 0L, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeBytes;;;Argument[0];Argument[-1];taint;manual" + ByteBuf out = null; + InputStream in = (InputStream)source(); + out.writeBytes(in, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeBytes;;;Argument[0];Argument[-1];taint;manual" + ByteBuf out = null; + ScatteringByteChannel in = (ScatteringByteChannel)source(); + out.writeBytes(in, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeBytes;;;Argument[0];Argument[-1];taint;manual" + ByteBuf out = null; + byte[] in = (byte[])source(); + out.writeBytes(in); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeBytes;;;Argument[0];Argument[-1];taint;manual" + ByteBuf out = null; + byte[] in = (byte[])source(); + out.writeBytes(in, 0, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeBytes;;;Argument[0];Argument[-1];taint;manual" + CompositeByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out.writeBytes(in); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeBytes;;;Argument[0];Argument[-1];taint;manual" + CompositeByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out.writeBytes(in, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeBytes;;;Argument[0];Argument[-1];taint;manual" + CompositeByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out.writeBytes(in, 0, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeBytes;;;Argument[0];Argument[-1];taint;manual" + CompositeByteBuf out = null; + ByteBuffer in = (ByteBuffer)source(); + out.writeBytes(in); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeBytes;;;Argument[0];Argument[-1];taint;manual" + CompositeByteBuf out = null; + byte[] in = (byte[])source(); + out.writeBytes(in); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeBytes;;;Argument[0];Argument[-1];taint;manual" + CompositeByteBuf out = null; + byte[] in = (byte[])source(); + out.writeBytes(in, 0, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeBytes;;;Argument[0];Argument[-1];taint;manual" + SwappedByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out.writeBytes(in); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeBytes;;;Argument[0];Argument[-1];taint;manual" + SwappedByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out.writeBytes(in, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeBytes;;;Argument[0];Argument[-1];taint;manual" + SwappedByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out.writeBytes(in, 0, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeBytes;;;Argument[0];Argument[-1];taint;manual" + SwappedByteBuf out = null; + ByteBuffer in = (ByteBuffer)source(); + out.writeBytes(in); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeBytes;;;Argument[0];Argument[-1];taint;manual" + SwappedByteBuf out = null; + FileChannel in = (FileChannel)source(); + out.writeBytes(in, 0L, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeBytes;;;Argument[0];Argument[-1];taint;manual" + SwappedByteBuf out = null; + InputStream in = (InputStream)source(); + out.writeBytes(in, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeBytes;;;Argument[0];Argument[-1];taint;manual" + SwappedByteBuf out = null; + ScatteringByteChannel in = (ScatteringByteChannel)source(); + out.writeBytes(in, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeBytes;;;Argument[0];Argument[-1];taint;manual" + SwappedByteBuf out = null; + byte[] in = (byte[])source(); + out.writeBytes(in); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeBytes;;;Argument[0];Argument[-1];taint;manual" + SwappedByteBuf out = null; + byte[] in = (byte[])source(); + out.writeBytes(in, 0, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeChar;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + AbstractByteBuf in = (AbstractByteBuf)source(); + out = in.writeChar(0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeChar;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out = in.writeChar(0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeChar;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + SwappedByteBuf in = (SwappedByteBuf)source(); + out = in.writeChar(0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeChar;;;Argument[-1];ReturnValue;value;manual" + CompositeByteBuf out = null; + CompositeByteBuf in = (CompositeByteBuf)source(); + out = in.writeChar(0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeChar;;;Argument[0];Argument[-1];taint;manual" + AbstractByteBuf out = null; + int in = (int)source(); + out.writeChar(in); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeChar;;;Argument[0];Argument[-1];taint;manual" + ByteBuf out = null; + int in = (int)source(); + out.writeChar(in); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeChar;;;Argument[0];Argument[-1];taint;manual" + CompositeByteBuf out = null; + int in = (int)source(); + out.writeChar(in); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeChar;;;Argument[0];Argument[-1];taint;manual" + SwappedByteBuf out = null; + int in = (int)source(); + out.writeChar(in); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeCharSequence;;;Argument[-1];ReturnValue;value;manual" + int out = null; + AbstractByteBuf in = (AbstractByteBuf)source(); + out = in.writeCharSequence(null, null); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeCharSequence;;;Argument[-1];ReturnValue;value;manual" + int out = null; + ByteBuf in = (ByteBuf)source(); + out = in.writeCharSequence(null, null); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeCharSequence;;;Argument[-1];ReturnValue;value;manual" + int out = null; + SwappedByteBuf in = (SwappedByteBuf)source(); + out = in.writeCharSequence(null, null); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeCharSequence;;;Argument[1];Argument[-1];taint;manual" + AbstractByteBuf out = null; + Charset in = (Charset)source(); + out.writeCharSequence(null, in); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeCharSequence;;;Argument[1];Argument[-1];taint;manual" + ByteBuf out = null; + Charset in = (Charset)source(); + out.writeCharSequence(null, in); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeCharSequence;;;Argument[1];Argument[-1];taint;manual" + SwappedByteBuf out = null; + Charset in = (Charset)source(); + out.writeCharSequence(null, in); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeDouble;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + AbstractByteBuf in = (AbstractByteBuf)source(); + out = in.writeDouble(0.0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeDouble;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out = in.writeDouble(0.0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeDouble;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + SwappedByteBuf in = (SwappedByteBuf)source(); + out = in.writeDouble(0.0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeDouble;;;Argument[-1];ReturnValue;value;manual" + CompositeByteBuf out = null; + CompositeByteBuf in = (CompositeByteBuf)source(); + out = in.writeDouble(0.0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeDoubleLE;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out = in.writeDoubleLE(0.0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeFloat;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + AbstractByteBuf in = (AbstractByteBuf)source(); + out = in.writeFloat(0.0f); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeFloat;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out = in.writeFloat(0.0f); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeFloat;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + SwappedByteBuf in = (SwappedByteBuf)source(); + out = in.writeFloat(0.0f); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeFloat;;;Argument[-1];ReturnValue;value;manual" + CompositeByteBuf out = null; + CompositeByteBuf in = (CompositeByteBuf)source(); + out = in.writeFloat(0.0f); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeFloatLE;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out = in.writeFloatLE(0.0f); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeInt;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + AbstractByteBuf in = (AbstractByteBuf)source(); + out = in.writeInt(0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeInt;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out = in.writeInt(0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeInt;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + SwappedByteBuf in = (SwappedByteBuf)source(); + out = in.writeInt(0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeInt;;;Argument[-1];ReturnValue;value;manual" + CompositeByteBuf out = null; + CompositeByteBuf in = (CompositeByteBuf)source(); + out = in.writeInt(0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeIntLE;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + AbstractByteBuf in = (AbstractByteBuf)source(); + out = in.writeIntLE(0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeIntLE;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out = in.writeIntLE(0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeIntLE;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + SwappedByteBuf in = (SwappedByteBuf)source(); + out = in.writeIntLE(0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeLong;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + AbstractByteBuf in = (AbstractByteBuf)source(); + out = in.writeLong(0L); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeLong;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out = in.writeLong(0L); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeLong;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + SwappedByteBuf in = (SwappedByteBuf)source(); + out = in.writeLong(0L); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeLong;;;Argument[-1];ReturnValue;value;manual" + CompositeByteBuf out = null; + CompositeByteBuf in = (CompositeByteBuf)source(); + out = in.writeLong(0L); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeLongLE;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + AbstractByteBuf in = (AbstractByteBuf)source(); + out = in.writeLongLE(0L); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeLongLE;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out = in.writeLongLE(0L); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeLongLE;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + SwappedByteBuf in = (SwappedByteBuf)source(); + out = in.writeLongLE(0L); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeMedium;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + AbstractByteBuf in = (AbstractByteBuf)source(); + out = in.writeMedium(0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeMedium;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out = in.writeMedium(0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeMedium;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + SwappedByteBuf in = (SwappedByteBuf)source(); + out = in.writeMedium(0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeMedium;;;Argument[-1];ReturnValue;value;manual" + CompositeByteBuf out = null; + CompositeByteBuf in = (CompositeByteBuf)source(); + out = in.writeMedium(0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeMediumLE;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + AbstractByteBuf in = (AbstractByteBuf)source(); + out = in.writeMediumLE(0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeMediumLE;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out = in.writeMediumLE(0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeMediumLE;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + SwappedByteBuf in = (SwappedByteBuf)source(); + out = in.writeMediumLE(0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeShort;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + AbstractByteBuf in = (AbstractByteBuf)source(); + out = in.writeShort(0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeShort;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out = in.writeShort(0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeShort;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + SwappedByteBuf in = (SwappedByteBuf)source(); + out = in.writeShort(0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeShort;;;Argument[-1];ReturnValue;value;manual" + CompositeByteBuf out = null; + CompositeByteBuf in = (CompositeByteBuf)source(); + out = in.writeShort(0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeShortLE;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + AbstractByteBuf in = (AbstractByteBuf)source(); + out = in.writeShortLE(0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeShortLE;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out = in.writeShortLE(0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeShortLE;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + SwappedByteBuf in = (SwappedByteBuf)source(); + out = in.writeShortLE(0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeZero;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + AbstractByteBuf in = (AbstractByteBuf)source(); + out = in.writeZero(0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeZero;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out = in.writeZero(0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeZero;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + SwappedByteBuf in = (SwappedByteBuf)source(); + out = in.writeZero(0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeZero;;;Argument[-1];ReturnValue;value;manual" + CompositeByteBuf out = null; + CompositeByteBuf in = (CompositeByteBuf)source(); + out = in.writeZero(0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;writerIndex;(int);;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + AbstractByteBuf in = (AbstractByteBuf)source(); + out = in.writerIndex(0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;writerIndex;(int);;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out = in.writerIndex(0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;writerIndex;(int);;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + SwappedByteBuf in = (SwappedByteBuf)source(); + out = in.writerIndex(0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;writerIndex;(int);;Argument[-1];ReturnValue;value;manual" + CompositeByteBuf out = null; + CompositeByteBuf in = (CompositeByteBuf)source(); + out = in.writerIndex(0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBufConvertible;true;asByteBuf;();;Argument[-1];ReturnValue;taint;manual" + ByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out = in.asByteBuf(); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBufConvertible;true;asByteBuf;();;Argument[-1];ReturnValue;taint;manual" + ByteBuf out = null; + ByteBufConvertible in = (ByteBufConvertible)source(); + out = in.asByteBuf(); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBufHolder;true;content;;;Argument[-1];ReturnValue;taint;manual" + ByteBuf out = null; + ByteBufHolder in = (ByteBufHolder)source(); + out = in.content(); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBufHolder;true;content;;;Argument[-1];ReturnValue;taint;manual" + ByteBuf out = null; + DefaultByteBufHolder in = (DefaultByteBufHolder)source(); + out = in.content(); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBufHolder;true;copy;;;Argument[-1];ReturnValue;taint;manual" + Attribute out = null; + Attribute in = (Attribute)source(); + out = in.copy(); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBufHolder;true;copy;;;Argument[-1];ReturnValue;taint;manual" + ByteBufHolder out = null; + ByteBufHolder in = (ByteBufHolder)source(); + out = in.copy(); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBufHolder;true;copy;;;Argument[-1];ReturnValue;taint;manual" + ByteBufHolder out = null; + DefaultByteBufHolder in = (DefaultByteBufHolder)source(); + out = in.copy(); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBufHolder;true;copy;;;Argument[-1];ReturnValue;taint;manual" + CloseWebSocketFrame out = null; + CloseWebSocketFrame in = (CloseWebSocketFrame)source(); + out = in.copy(); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBufHolder;true;copy;;;Argument[-1];ReturnValue;taint;manual" + ContinuationWebSocketFrame out = null; + ContinuationWebSocketFrame in = (ContinuationWebSocketFrame)source(); + out = in.copy(); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBufHolder;true;copy;;;Argument[-1];ReturnValue;taint;manual" + FileUpload out = null; + FileUpload in = (FileUpload)source(); + out = in.copy(); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBufHolder;true;copy;;;Argument[-1];ReturnValue;taint;manual" + FullHttpMessage out = null; + FullHttpMessage in = (FullHttpMessage)source(); + out = in.copy(); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBufHolder;true;copy;;;Argument[-1];ReturnValue;taint;manual" + FullHttpRequest out = null; + FullHttpRequest in = (FullHttpRequest)source(); + out = in.copy(); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBufHolder;true;copy;;;Argument[-1];ReturnValue;taint;manual" + FullHttpResponse out = null; + FullHttpResponse in = (FullHttpResponse)source(); + out = in.copy(); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBufHolder;true;copy;;;Argument[-1];ReturnValue;taint;manual" + HttpContent out = null; + HttpContent in = (HttpContent)source(); + out = in.copy(); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBufHolder;true;copy;;;Argument[-1];ReturnValue;taint;manual" + HttpData out = null; + HttpData in = (HttpData)source(); + out = in.copy(); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBufHolder;true;copy;;;Argument[-1];ReturnValue;taint;manual" + LastHttpContent out = null; + LastHttpContent in = (LastHttpContent)source(); + out = in.copy(); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBufHolder;true;copy;;;Argument[-1];ReturnValue;taint;manual" + TextWebSocketFrame out = null; + TextWebSocketFrame in = (TextWebSocketFrame)source(); + out = in.copy(); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBufHolder;true;copy;;;Argument[-1];ReturnValue;taint;manual" + WebSocketFrame out = null; + WebSocketFrame in = (WebSocketFrame)source(); + out = in.copy(); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBufHolder;true;duplicate;;;Argument[-1];ReturnValue;taint;manual" + Attribute out = null; + Attribute in = (Attribute)source(); + out = in.duplicate(); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBufHolder;true;duplicate;;;Argument[-1];ReturnValue;taint;manual" + ByteBufHolder out = null; + ByteBufHolder in = (ByteBufHolder)source(); + out = in.duplicate(); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBufHolder;true;duplicate;;;Argument[-1];ReturnValue;taint;manual" + ByteBufHolder out = null; + DefaultByteBufHolder in = (DefaultByteBufHolder)source(); + out = in.duplicate(); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBufHolder;true;duplicate;;;Argument[-1];ReturnValue;taint;manual" + CloseWebSocketFrame out = null; + CloseWebSocketFrame in = (CloseWebSocketFrame)source(); + out = in.duplicate(); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBufHolder;true;duplicate;;;Argument[-1];ReturnValue;taint;manual" + ContinuationWebSocketFrame out = null; + ContinuationWebSocketFrame in = (ContinuationWebSocketFrame)source(); + out = in.duplicate(); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBufHolder;true;duplicate;;;Argument[-1];ReturnValue;taint;manual" + FileUpload out = null; + FileUpload in = (FileUpload)source(); + out = in.duplicate(); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBufHolder;true;duplicate;;;Argument[-1];ReturnValue;taint;manual" + FullHttpMessage out = null; + FullHttpMessage in = (FullHttpMessage)source(); + out = in.duplicate(); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBufHolder;true;duplicate;;;Argument[-1];ReturnValue;taint;manual" + FullHttpRequest out = null; + FullHttpRequest in = (FullHttpRequest)source(); + out = in.duplicate(); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBufHolder;true;duplicate;;;Argument[-1];ReturnValue;taint;manual" + FullHttpResponse out = null; + FullHttpResponse in = (FullHttpResponse)source(); + out = in.duplicate(); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBufHolder;true;duplicate;;;Argument[-1];ReturnValue;taint;manual" + HttpContent out = null; + HttpContent in = (HttpContent)source(); + out = in.duplicate(); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBufHolder;true;duplicate;;;Argument[-1];ReturnValue;taint;manual" + HttpData out = null; + HttpData in = (HttpData)source(); + out = in.duplicate(); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBufHolder;true;duplicate;;;Argument[-1];ReturnValue;taint;manual" + LastHttpContent out = null; + LastHttpContent in = (LastHttpContent)source(); + out = in.duplicate(); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBufHolder;true;duplicate;;;Argument[-1];ReturnValue;taint;manual" + TextWebSocketFrame out = null; + TextWebSocketFrame in = (TextWebSocketFrame)source(); + out = in.duplicate(); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBufHolder;true;duplicate;;;Argument[-1];ReturnValue;taint;manual" + WebSocketFrame out = null; + WebSocketFrame in = (WebSocketFrame)source(); + out = in.duplicate(); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBufHolder;true;retainedDuplicate;;;Argument[-1];ReturnValue;taint;manual" + Attribute out = null; + Attribute in = (Attribute)source(); + out = in.retainedDuplicate(); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBufHolder;true;retainedDuplicate;;;Argument[-1];ReturnValue;taint;manual" + ByteBufHolder out = null; + ByteBufHolder in = (ByteBufHolder)source(); + out = in.retainedDuplicate(); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBufHolder;true;retainedDuplicate;;;Argument[-1];ReturnValue;taint;manual" + ByteBufHolder out = null; + DefaultByteBufHolder in = (DefaultByteBufHolder)source(); + out = in.retainedDuplicate(); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBufHolder;true;retainedDuplicate;;;Argument[-1];ReturnValue;taint;manual" + CloseWebSocketFrame out = null; + CloseWebSocketFrame in = (CloseWebSocketFrame)source(); + out = in.retainedDuplicate(); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBufHolder;true;retainedDuplicate;;;Argument[-1];ReturnValue;taint;manual" + ContinuationWebSocketFrame out = null; + ContinuationWebSocketFrame in = (ContinuationWebSocketFrame)source(); + out = in.retainedDuplicate(); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBufHolder;true;retainedDuplicate;;;Argument[-1];ReturnValue;taint;manual" + FileUpload out = null; + FileUpload in = (FileUpload)source(); + out = in.retainedDuplicate(); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBufHolder;true;retainedDuplicate;;;Argument[-1];ReturnValue;taint;manual" + FullHttpMessage out = null; + FullHttpMessage in = (FullHttpMessage)source(); + out = in.retainedDuplicate(); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBufHolder;true;retainedDuplicate;;;Argument[-1];ReturnValue;taint;manual" + FullHttpRequest out = null; + FullHttpRequest in = (FullHttpRequest)source(); + out = in.retainedDuplicate(); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBufHolder;true;retainedDuplicate;;;Argument[-1];ReturnValue;taint;manual" + FullHttpResponse out = null; + FullHttpResponse in = (FullHttpResponse)source(); + out = in.retainedDuplicate(); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBufHolder;true;retainedDuplicate;;;Argument[-1];ReturnValue;taint;manual" + HttpContent out = null; + HttpContent in = (HttpContent)source(); + out = in.retainedDuplicate(); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBufHolder;true;retainedDuplicate;;;Argument[-1];ReturnValue;taint;manual" + HttpData out = null; + HttpData in = (HttpData)source(); + out = in.retainedDuplicate(); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBufHolder;true;retainedDuplicate;;;Argument[-1];ReturnValue;taint;manual" + LastHttpContent out = null; + LastHttpContent in = (LastHttpContent)source(); + out = in.retainedDuplicate(); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBufHolder;true;retainedDuplicate;;;Argument[-1];ReturnValue;taint;manual" + TextWebSocketFrame out = null; + TextWebSocketFrame in = (TextWebSocketFrame)source(); + out = in.retainedDuplicate(); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBufHolder;true;retainedDuplicate;;;Argument[-1];ReturnValue;taint;manual" + WebSocketFrame out = null; + WebSocketFrame in = (WebSocketFrame)source(); + out = in.retainedDuplicate(); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.base64;Base64;true;decode;;;Argument[0];ReturnValue;taint;manual" + ByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out = Base64.decode(in); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.base64;Base64;true;decode;;;Argument[0];ReturnValue;taint;manual" + ByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out = Base64.decode(in, 0, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.base64;Base64;true;decode;;;Argument[0];ReturnValue;taint;manual" + ByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out = Base64.decode(in, 0, 0, null); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.base64;Base64;true;decode;;;Argument[0];ReturnValue;taint;manual" + ByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out = Base64.decode(in, 0, 0, null, null); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.base64;Base64;true;decode;;;Argument[0];ReturnValue;taint;manual" + ByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out = Base64.decode(in, null); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.base64;Base64;true;encode;;;Argument[0];ReturnValue;taint;manual" + ByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out = Base64.encode(in); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.base64;Base64;true;encode;;;Argument[0];ReturnValue;taint;manual" + ByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out = Base64.encode(in, (Base64Dialect)null); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.base64;Base64;true;encode;;;Argument[0];ReturnValue;taint;manual" + ByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out = Base64.encode(in, 0, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.base64;Base64;true;encode;;;Argument[0];ReturnValue;taint;manual" + ByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out = Base64.encode(in, 0, 0, (Base64Dialect)null); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.base64;Base64;true;encode;;;Argument[0];ReturnValue;taint;manual" + ByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out = Base64.encode(in, 0, 0, false); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.base64;Base64;true;encode;;;Argument[0];ReturnValue;taint;manual" + ByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out = Base64.encode(in, 0, 0, false, null); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.base64;Base64;true;encode;;;Argument[0];ReturnValue;taint;manual" + ByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out = Base64.encode(in, 0, 0, false, null, null); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.base64;Base64;true;encode;;;Argument[0];ReturnValue;taint;manual" + ByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out = Base64.encode(in, false); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.base64;Base64;true;encode;;;Argument[0];ReturnValue;taint;manual" + ByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out = Base64.encode(in, false, (Base64Dialect)null); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.http.cookie;Cookie;true;domain;();;Argument[-1];ReturnValue;taint;manual" + String out = null; + Cookie in = (Cookie)source(); + out = in.domain(); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.http.cookie;Cookie;true;domain;();;Argument[-1];ReturnValue;taint;manual" + String out = null; + DefaultCookie in = (DefaultCookie)source(); + out = in.domain(); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.http.cookie;Cookie;true;name;();;Argument[-1];ReturnValue;taint;manual" + String out = null; + Cookie in = (Cookie)source(); + out = in.name(); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.http.cookie;Cookie;true;name;();;Argument[-1];ReturnValue;taint;manual" + String out = null; + DefaultCookie in = (DefaultCookie)source(); + out = in.name(); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.http.cookie;Cookie;true;path;();;Argument[-1];ReturnValue;taint;manual" + String out = null; + Cookie in = (Cookie)source(); + out = in.path(); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.http.cookie;Cookie;true;path;();;Argument[-1];ReturnValue;taint;manual" + String out = null; + DefaultCookie in = (DefaultCookie)source(); + out = in.path(); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.http.cookie;Cookie;true;value;();;Argument[-1];ReturnValue;taint;manual" + String out = null; + Cookie in = (Cookie)source(); + out = in.value(); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.http.cookie;Cookie;true;value;();;Argument[-1];ReturnValue;taint;manual" + String out = null; + DefaultCookie in = (DefaultCookie)source(); + out = in.value(); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.http.cookie;ServerCookieDecoder;true;decode;(String);;Argument[-1];ReturnValue;taint;manual" + Set out = null; + ServerCookieDecoder in = (ServerCookieDecoder)source(); + out = in.decode(null); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.http.cookie;ServerCookieDecoder;true;decodeAll;(String);;Argument[-1];ReturnValue;taint;manual" + List out = null; + ServerCookieDecoder in = (ServerCookieDecoder)source(); + out = in.decodeAll(null); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.http.multipart;Attribute;true;getValue;();;Argument[-1];ReturnValue;taint;manual" + String out = null; + Attribute in = (Attribute)source(); + out = in.getValue(); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.http.multipart;FileUpload;true;getContentTransferEncoding;();;Argument[-1];ReturnValue;taint;manual" + String out = null; + FileUpload in = (FileUpload)source(); + out = in.getContentTransferEncoding(); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.http.multipart;FileUpload;true;getContentType;();;Argument[-1];ReturnValue;taint;manual" + String out = null; + FileUpload in = (FileUpload)source(); + out = in.getContentType(); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.http.multipart;FileUpload;true;getFilename;();;Argument[-1];ReturnValue;taint;manual" + String out = null; + FileUpload in = (FileUpload)source(); + out = in.getFilename(); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.http.multipart;HttpData;true;get;();;Argument[-1];ReturnValue;taint;manual" + byte[] out = null; + HttpData in = (HttpData)source(); + out = in.get(); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.http.multipart;HttpData;true;getByteBuf;();;Argument[-1];ReturnValue;taint;manual" + ByteBuf out = null; + HttpData in = (HttpData)source(); + out = in.getByteBuf(); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.http.multipart;HttpData;true;getChunk;(int);;Argument[-1];ReturnValue;taint;manual" + ByteBuf out = null; + HttpData in = (HttpData)source(); + out = in.getChunk(0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.http.multipart;HttpData;true;getString;();;Argument[-1];ReturnValue;taint;manual" + String out = null; + HttpData in = (HttpData)source(); + out = in.getString(); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.http.multipart;HttpData;true;getString;(Charset);;Argument[-1];ReturnValue;taint;manual" + String out = null; + HttpData in = (HttpData)source(); + out = in.getString(null); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.http.multipart;HttpPostMultipartRequestDecoder;true;HttpPostMultipartRequestDecoder;(HttpDataFactory,HttpRequest);;Argument[1];ReturnValue;taint;manual" + HttpPostMultipartRequestDecoder out = null; + HttpRequest in = (HttpRequest)source(); + out = new HttpPostMultipartRequestDecoder(null, in); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.http.multipart;HttpPostMultipartRequestDecoder;true;HttpPostMultipartRequestDecoder;(HttpDataFactory,HttpRequest,Charset);;Argument[1];ReturnValue;taint;manual" + HttpPostMultipartRequestDecoder out = null; + HttpRequest in = (HttpRequest)source(); + out = new HttpPostMultipartRequestDecoder(null, in, null); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.http.multipart;HttpPostMultipartRequestDecoder;true;HttpPostMultipartRequestDecoder;(HttpRequest);;Argument[0];ReturnValue;taint;manual" + HttpPostMultipartRequestDecoder out = null; + HttpRequest in = (HttpRequest)source(); + out = new HttpPostMultipartRequestDecoder(in); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.http.multipart;HttpPostRequestDecoder;true;HttpPostRequestDecoder;(HttpDataFactory,HttpRequest);;Argument[1];ReturnValue;taint;manual" + HttpPostRequestDecoder out = null; + HttpRequest in = (HttpRequest)source(); + out = new HttpPostRequestDecoder(null, in); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.http.multipart;HttpPostRequestDecoder;true;HttpPostRequestDecoder;(HttpDataFactory,HttpRequest,Charset);;Argument[1];ReturnValue;taint;manual" + HttpPostRequestDecoder out = null; + HttpRequest in = (HttpRequest)source(); + out = new HttpPostRequestDecoder(null, in, null); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.http.multipart;HttpPostRequestDecoder;true;HttpPostRequestDecoder;(HttpRequest);;Argument[0];ReturnValue;taint;manual" + HttpPostRequestDecoder out = null; + HttpRequest in = (HttpRequest)source(); + out = new HttpPostRequestDecoder(in); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.http.multipart;HttpPostStandardRequestDecoder;true;HttpPostStandardRequestDecoder;(HttpDataFactory,HttpRequest);;Argument[1];ReturnValue;taint;manual" + HttpPostStandardRequestDecoder out = null; + HttpRequest in = (HttpRequest)source(); + out = new HttpPostStandardRequestDecoder(null, in); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.http.multipart;HttpPostStandardRequestDecoder;true;HttpPostStandardRequestDecoder;(HttpDataFactory,HttpRequest,Charset);;Argument[1];ReturnValue;taint;manual" + HttpPostStandardRequestDecoder out = null; + HttpRequest in = (HttpRequest)source(); + out = new HttpPostStandardRequestDecoder(null, in, null); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.http.multipart;HttpPostStandardRequestDecoder;true;HttpPostStandardRequestDecoder;(HttpRequest);;Argument[0];ReturnValue;taint;manual" + HttpPostStandardRequestDecoder out = null; + HttpRequest in = (HttpRequest)source(); + out = new HttpPostStandardRequestDecoder(in); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.http.multipart;InterfaceHttpData;true;getName;();;Argument[-1];ReturnValue;taint;manual" + String out = null; + InterfaceHttpData in = (InterfaceHttpData)source(); + out = in.getName(); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.http.multipart;InterfaceHttpPostRequestDecoder;true;getBodyHttpData;(String);;Argument[-1];ReturnValue;taint;manual" + InterfaceHttpData out = null; + HttpPostMultipartRequestDecoder in = (HttpPostMultipartRequestDecoder)source(); + out = in.getBodyHttpData(null); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.http.multipart;InterfaceHttpPostRequestDecoder;true;getBodyHttpData;(String);;Argument[-1];ReturnValue;taint;manual" + InterfaceHttpData out = null; + HttpPostRequestDecoder in = (HttpPostRequestDecoder)source(); + out = in.getBodyHttpData(null); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.http.multipart;InterfaceHttpPostRequestDecoder;true;getBodyHttpData;(String);;Argument[-1];ReturnValue;taint;manual" + InterfaceHttpData out = null; + HttpPostStandardRequestDecoder in = (HttpPostStandardRequestDecoder)source(); + out = in.getBodyHttpData(null); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.http.multipart;InterfaceHttpPostRequestDecoder;true;getBodyHttpData;(String);;Argument[-1];ReturnValue;taint;manual" + InterfaceHttpData out = null; + InterfaceHttpPostRequestDecoder in = (InterfaceHttpPostRequestDecoder)source(); + out = in.getBodyHttpData(null); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.http.multipart;InterfaceHttpPostRequestDecoder;true;getBodyHttpDatas;();;Argument[-1];ReturnValue;taint;manual" + List out = null; + HttpPostMultipartRequestDecoder in = (HttpPostMultipartRequestDecoder)source(); + out = in.getBodyHttpDatas(); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.http.multipart;InterfaceHttpPostRequestDecoder;true;getBodyHttpDatas;();;Argument[-1];ReturnValue;taint;manual" + List out = null; + HttpPostRequestDecoder in = (HttpPostRequestDecoder)source(); + out = in.getBodyHttpDatas(); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.http.multipart;InterfaceHttpPostRequestDecoder;true;getBodyHttpDatas;();;Argument[-1];ReturnValue;taint;manual" + List out = null; + HttpPostStandardRequestDecoder in = (HttpPostStandardRequestDecoder)source(); + out = in.getBodyHttpDatas(); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.http.multipart;InterfaceHttpPostRequestDecoder;true;getBodyHttpDatas;();;Argument[-1];ReturnValue;taint;manual" + List out = null; + InterfaceHttpPostRequestDecoder in = (InterfaceHttpPostRequestDecoder)source(); + out = in.getBodyHttpDatas(); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.http.multipart;InterfaceHttpPostRequestDecoder;true;getBodyHttpDatas;(String);;Argument[-1];ReturnValue;taint;manual" + List out = null; + HttpPostMultipartRequestDecoder in = (HttpPostMultipartRequestDecoder)source(); + out = in.getBodyHttpDatas(null); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.http.multipart;InterfaceHttpPostRequestDecoder;true;getBodyHttpDatas;(String);;Argument[-1];ReturnValue;taint;manual" + List out = null; + HttpPostRequestDecoder in = (HttpPostRequestDecoder)source(); + out = in.getBodyHttpDatas(null); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.http.multipart;InterfaceHttpPostRequestDecoder;true;getBodyHttpDatas;(String);;Argument[-1];ReturnValue;taint;manual" + List out = null; + HttpPostStandardRequestDecoder in = (HttpPostStandardRequestDecoder)source(); + out = in.getBodyHttpDatas(null); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.http.multipart;InterfaceHttpPostRequestDecoder;true;getBodyHttpDatas;(String);;Argument[-1];ReturnValue;taint;manual" + List out = null; + InterfaceHttpPostRequestDecoder in = (InterfaceHttpPostRequestDecoder)source(); + out = in.getBodyHttpDatas(null); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.http.multipart;InterfaceHttpPostRequestDecoder;true;next;();;Argument[-1];ReturnValue;taint;manual" + InterfaceHttpData out = null; + HttpPostMultipartRequestDecoder in = (HttpPostMultipartRequestDecoder)source(); + out = in.next(); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.http.multipart;InterfaceHttpPostRequestDecoder;true;next;();;Argument[-1];ReturnValue;taint;manual" + InterfaceHttpData out = null; + HttpPostRequestDecoder in = (HttpPostRequestDecoder)source(); + out = in.next(); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.http.multipart;InterfaceHttpPostRequestDecoder;true;next;();;Argument[-1];ReturnValue;taint;manual" + InterfaceHttpData out = null; + HttpPostStandardRequestDecoder in = (HttpPostStandardRequestDecoder)source(); + out = in.next(); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.http.multipart;InterfaceHttpPostRequestDecoder;true;next;();;Argument[-1];ReturnValue;taint;manual" + InterfaceHttpData out = null; + InterfaceHttpPostRequestDecoder in = (InterfaceHttpPostRequestDecoder)source(); + out = in.next(); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.http.multipart;InterfaceHttpPostRequestDecoder;true;offer;(HttpContent);;Argument[0];Argument[-1];taint;manual" + HttpPostMultipartRequestDecoder out = null; + HttpContent in = (HttpContent)source(); + out.offer(in); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.http.multipart;InterfaceHttpPostRequestDecoder;true;offer;(HttpContent);;Argument[0];Argument[-1];taint;manual" + HttpPostRequestDecoder out = null; + HttpContent in = (HttpContent)source(); + out.offer(in); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.http.multipart;InterfaceHttpPostRequestDecoder;true;offer;(HttpContent);;Argument[0];Argument[-1];taint;manual" + HttpPostStandardRequestDecoder out = null; + HttpContent in = (HttpContent)source(); + out.offer(in); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.http.multipart;InterfaceHttpPostRequestDecoder;true;offer;(HttpContent);;Argument[0];Argument[-1];taint;manual" + InterfaceHttpPostRequestDecoder out = null; + HttpContent in = (HttpContent)source(); + out.offer(in); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.http.websocketx;CloseWebSocketFrame;true;reasonText;();;Argument[-1];ReturnValue;taint;manual" + String out = null; + CloseWebSocketFrame in = (CloseWebSocketFrame)source(); + out = in.reasonText(); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.http.websocketx;ContinuationWebSocketFrame;true;text;();;Argument[-1];ReturnValue;taint;manual" + String out = null; + ContinuationWebSocketFrame in = (ContinuationWebSocketFrame)source(); + out = in.text(); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.http.websocketx;TextWebSocketFrame;true;text;();;Argument[-1];ReturnValue;taint;manual" + String out = null; + TextWebSocketFrame in = (TextWebSocketFrame)source(); + out = in.text(); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.http2;Http2Headers;true;authority;();;Argument[-1];ReturnValue;taint;manual" + CharSequence out = null; + Http2Headers in = (Http2Headers)source(); + out = in.authority(); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.http2;Http2Headers;true;iterator;();;Argument[-1];ReturnValue;taint;manual" + Iterator out = null; + Http2Headers in = (Http2Headers)source(); + out = in.iterator(); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.http2;Http2Headers;true;method;();;Argument[-1];ReturnValue;taint;manual" + CharSequence out = null; + Http2Headers in = (Http2Headers)source(); + out = in.method(); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.http2;Http2Headers;true;path;();;Argument[-1];ReturnValue;taint;manual" + CharSequence out = null; + Http2Headers in = (Http2Headers)source(); + out = in.path(); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.http2;Http2Headers;true;scheme;();;Argument[-1];ReturnValue;taint;manual" + CharSequence out = null; + Http2Headers in = (Http2Headers)source(); + out = in.scheme(); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.http2;Http2Headers;true;status;();;Argument[-1];ReturnValue;taint;manual" + CharSequence out = null; + Http2Headers in = (Http2Headers)source(); + out = in.status(); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.http2;Http2Headers;true;valueIterator;(CharSequence);;Argument[-1];ReturnValue;taint;manual" + Iterator out = null; + Http2Headers in = (Http2Headers)source(); + out = in.valueIterator(null); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.http2;Http2HeadersFrame;true;headers;();;Argument[-1];ReturnValue;taint;manual" + Http2Headers out = null; + Http2HeadersFrame in = (Http2HeadersFrame)source(); + out = in.headers(); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.http2;Http2PushPromiseFrame;true;http2Headers;();;Argument[-1];ReturnValue;taint;manual" + Http2Headers out = null; + Http2PushPromiseFrame in = (Http2PushPromiseFrame)source(); + out = in.http2Headers(); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.http2;HttpConversionUtil;false;addHttp2ToHttpHeaders;;;Argument[1];Argument[2];taint;manual" + FullHttpMessage out = null; + Http2Headers in = (Http2Headers)source(); + HttpConversionUtil.addHttp2ToHttpHeaders(0, in, out, false); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.http2;HttpConversionUtil;false;addHttp2ToHttpHeaders;;;Argument[1];Argument[2];taint;manual" + HttpHeaders out = null; + Http2Headers in = (Http2Headers)source(); + HttpConversionUtil.addHttp2ToHttpHeaders(0, in, out, null, false, false); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.http2;HttpConversionUtil;false;toFullHttpRequest;;;Argument[1];ReturnValue;taint;manual" + FullHttpRequest out = null; + Http2Headers in = (Http2Headers)source(); + out = HttpConversionUtil.toFullHttpRequest(0, in, (ByteBuf)null, false); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.http2;HttpConversionUtil;false;toFullHttpRequest;;;Argument[1];ReturnValue;taint;manual" + FullHttpRequest out = null; + Http2Headers in = (Http2Headers)source(); + out = HttpConversionUtil.toFullHttpRequest(0, in, (ByteBufAllocator)null, false); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.http2;HttpConversionUtil;false;toFullHttpRequest;;;Argument[2];ReturnValue;taint;manual" + FullHttpRequest out = null; + ByteBuf in = (ByteBuf)source(); + out = HttpConversionUtil.toFullHttpRequest(0, (Http2Headers)null, in, false); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.http2;HttpConversionUtil;false;toFullHttpRequest;;;Argument[2];ReturnValue;taint;manual" + FullHttpRequest out = null; + ByteBufAllocator in = (ByteBufAllocator)source(); + out = HttpConversionUtil.toFullHttpRequest(0, (Http2Headers)null, in, false); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.http2;HttpConversionUtil;false;toFullHttpResponse;;;Argument[1];ReturnValue;taint;manual" + FullHttpResponse out = null; + Http2Headers in = (Http2Headers)source(); + out = HttpConversionUtil.toFullHttpResponse(0, in, (ByteBuf)null, false); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.http2;HttpConversionUtil;false;toFullHttpResponse;;;Argument[1];ReturnValue;taint;manual" + FullHttpResponse out = null; + Http2Headers in = (Http2Headers)source(); + out = HttpConversionUtil.toFullHttpResponse(0, in, (ByteBufAllocator)null, false); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.http2;HttpConversionUtil;false;toFullHttpResponse;;;Argument[2];ReturnValue;taint;manual" + FullHttpResponse out = null; + ByteBuf in = (ByteBuf)source(); + out = HttpConversionUtil.toFullHttpResponse(0, (Http2Headers)null, in, false); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.http2;HttpConversionUtil;false;toFullHttpResponse;;;Argument[2];ReturnValue;taint;manual" + FullHttpResponse out = null; + ByteBufAllocator in = (ByteBufAllocator)source(); + out = HttpConversionUtil.toFullHttpResponse(0, (Http2Headers)null, in, false); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.http2;HttpConversionUtil;false;toHttp2Headers;(HttpHeaders,Http2Headers);;Argument[0];Argument[1];taint;manual" + Http2Headers out = null; + HttpHeaders in = (HttpHeaders)source(); + HttpConversionUtil.toHttp2Headers(in, out); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.http2;HttpConversionUtil;false;toHttp2Headers;(HttpHeaders,boolean);;Argument[0];ReturnValue;taint;manual" + Http2Headers out = null; + HttpHeaders in = (HttpHeaders)source(); + out = HttpConversionUtil.toHttp2Headers(in, false); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.http2;HttpConversionUtil;false;toHttpRequest;;;Argument[1];ReturnValue;taint;manual" + HttpRequest out = null; + Http2Headers in = (Http2Headers)source(); + out = HttpConversionUtil.toHttpRequest(0, in, false); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.http2;HttpConversionUtil;false;toHttpResponse;;;Argument[1];ReturnValue;taint;manual" + HttpResponse out = null; + Http2Headers in = (Http2Headers)source(); + out = HttpConversionUtil.toHttpResponse(0, in, false); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.http;HttpHeaders;true;copy;;;Argument[-1];ReturnValue;taint;manual" + HttpHeaders out = null; + HttpHeaders in = (HttpHeaders)source(); + out = in.copy(); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.http;HttpHeaders;true;entries;;;Argument[-1];ReturnValue;taint;manual" + List out = null; + HttpHeaders in = (HttpHeaders)source(); + out = in.entries(); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.http;HttpHeaders;true;get;;;Argument[-1];ReturnValue;taint;manual" + String out = null; + HttpHeaders in = (HttpHeaders)source(); + out = in.get((CharSequence)null); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.http;HttpHeaders;true;get;;;Argument[-1];ReturnValue;taint;manual" + String out = null; + HttpHeaders in = (HttpHeaders)source(); + out = in.get((String)null); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.http;HttpHeaders;true;get;;;Argument[-1];ReturnValue;taint;manual" + String out = null; + HttpHeaders in = (HttpHeaders)source(); + out = in.get(null, null); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.http;HttpHeaders;true;get;;;Argument[1];ReturnValue;value;manual" + String out = null; + String in = (String)source(); + HttpHeaders instance = null; + out = instance.get(null, in); + sink(out); // $ hasValueFlow + } + { + // "io.netty.handler.codec.http;HttpHeaders;true;getAll;;;Argument[-1];ReturnValue;taint;manual" + List out = null; + HttpHeaders in = (HttpHeaders)source(); + out = in.getAll((CharSequence)null); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.http;HttpHeaders;true;getAll;;;Argument[-1];ReturnValue;taint;manual" + List out = null; + HttpHeaders in = (HttpHeaders)source(); + out = in.getAll((String)null); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.http;HttpHeaders;true;getAllAsString;;;Argument[-1];ReturnValue;taint;manual" + List out = null; + HttpHeaders in = (HttpHeaders)source(); + out = in.getAllAsString(null); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.http;HttpHeaders;true;getAsString;;;Argument[-1];ReturnValue;taint;manual" + String out = null; + HttpHeaders in = (HttpHeaders)source(); + out = in.getAsString(null); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.http;HttpHeaders;true;getHeader;;;Argument[0];ReturnValue;taint;manual" + String out = null; + HttpMessage in = (HttpMessage)source(); + out = HttpHeaders.getHeader(in, (CharSequence)null); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.http;HttpHeaders;true;getHeader;;;Argument[0];ReturnValue;taint;manual" + String out = null; + HttpMessage in = (HttpMessage)source(); + out = HttpHeaders.getHeader(in, (CharSequence)null, (String)null); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.http;HttpHeaders;true;getHeader;;;Argument[0];ReturnValue;taint;manual" + String out = null; + HttpMessage in = (HttpMessage)source(); + out = HttpHeaders.getHeader(in, (String)null); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.http;HttpHeaders;true;getHeader;;;Argument[0];ReturnValue;taint;manual" + String out = null; + HttpMessage in = (HttpMessage)source(); + out = HttpHeaders.getHeader(in, (String)null, (String)null); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.http;HttpHeaders;true;getHeader;;;Argument[2];ReturnValue;value;manual" + String out = null; + String in = (String)source(); + out = HttpHeaders.getHeader((HttpMessage)null, (CharSequence)null, in); + sink(out); // $ hasValueFlow + } + { + // "io.netty.handler.codec.http;HttpHeaders;true;getHeader;;;Argument[2];ReturnValue;value;manual" + String out = null; + String in = (String)source(); + out = HttpHeaders.getHeader((HttpMessage)null, (String)null, in); + sink(out); // $ hasValueFlow + } + { + // "io.netty.handler.codec.http;HttpHeaders;true;getHost;;;Argument[0];ReturnValue;taint;manual" + String out = null; + HttpMessage in = (HttpMessage)source(); + out = HttpHeaders.getHost(in); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.http;HttpHeaders;true;getHost;;;Argument[0];ReturnValue;taint;manual" + String out = null; + HttpMessage in = (HttpMessage)source(); + out = HttpHeaders.getHost(in, null); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.http;HttpHeaders;true;getHost;;;Argument[1];ReturnValue;value;manual" + String out = null; + String in = (String)source(); + out = HttpHeaders.getHost(null, in); + sink(out); // $ hasValueFlow + } + { + // "io.netty.handler.codec.http;HttpHeaders;true;iteratorAsString;;;Argument[-1];ReturnValue;taint;manual" + Iterator out = null; + HttpHeaders in = (HttpHeaders)source(); + out = in.iteratorAsString(); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.http;HttpHeaders;true;iteratorCharSequence;;;Argument[-1];ReturnValue;taint;manual" + Iterator out = null; + HttpHeaders in = (HttpHeaders)source(); + out = in.iteratorCharSequence(); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.http;HttpHeaders;true;names;;;Argument[-1];ReturnValue;taint;manual" + Set out = null; + HttpHeaders in = (HttpHeaders)source(); + out = in.names(); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.http;HttpHeaders;true;newEntity;;;Argument[0];ReturnValue;taint;manual" + CharSequence out = null; + String in = (String)source(); + out = HttpHeaders.newEntity(in); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.http;HttpHeaders;true;toString;;;Argument[-1];ReturnValue;taint;manual" + String out = null; + HttpHeaders in = (HttpHeaders)source(); + out = in.toString(); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.http;HttpHeaders;true;valueCharSequenceIterator;;;Argument[-1];ReturnValue;taint;manual" + Iterator out = null; + HttpHeaders in = (HttpHeaders)source(); + out = in.valueCharSequenceIterator(null); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.http;HttpHeaders;true;valueStringIterator;;;Argument[-1];ReturnValue;taint;manual" + Iterator out = null; + HttpHeaders in = (HttpHeaders)source(); + out = in.valueStringIterator(null); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.http;HttpMessage;true;headers;;;Argument[-1];ReturnValue;taint;manual" + HttpHeaders out = null; + HttpMessage in = (HttpMessage)source(); + out = in.headers(); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.http;HttpRequest;true;getUri;;;Argument[-1];ReturnValue;taint;manual" + String out = null; + HttpRequest in = (HttpRequest)source(); + out = in.getUri(); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.http;HttpRequest;true;uri;;;Argument[-1];ReturnValue;taint;manual" + String out = null; + HttpRequest in = (HttpRequest)source(); + out = in.uri(); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.http;LastHttpContent;true;trailingHeaders;;;Argument[-1];ReturnValue;taint;manual" + HttpHeaders out = null; + LastHttpContent in = (LastHttpContent)source(); + out = in.trailingHeaders(); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.http;QueryStringDecoder;true;QueryStringDecoder;;;Argument[0];ReturnValue;taint;manual" + QueryStringDecoder out = null; + String in = (String)source(); + out = new QueryStringDecoder(in); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.http;QueryStringDecoder;true;QueryStringDecoder;;;Argument[0];ReturnValue;taint;manual" + QueryStringDecoder out = null; + String in = (String)source(); + out = new QueryStringDecoder(in, (Charset)null); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.http;QueryStringDecoder;true;QueryStringDecoder;;;Argument[0];ReturnValue;taint;manual" + QueryStringDecoder out = null; + String in = (String)source(); + out = new QueryStringDecoder(in, (Charset)null, false); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.http;QueryStringDecoder;true;QueryStringDecoder;;;Argument[0];ReturnValue;taint;manual" + QueryStringDecoder out = null; + String in = (String)source(); + out = new QueryStringDecoder(in, (Charset)null, false, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.http;QueryStringDecoder;true;QueryStringDecoder;;;Argument[0];ReturnValue;taint;manual" + QueryStringDecoder out = null; + String in = (String)source(); + out = new QueryStringDecoder(in, false); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.http;QueryStringDecoder;true;QueryStringDecoder;;;Argument[0];ReturnValue;taint;manual" + QueryStringDecoder out = null; + String in = (String)source(); + out = new QueryStringDecoder(in, null, false, 0, false); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.http;QueryStringDecoder;true;QueryStringDecoder;;;Argument[0];ReturnValue;taint;manual" + QueryStringDecoder out = null; + URI in = (URI)source(); + out = new QueryStringDecoder(in); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.http;QueryStringDecoder;true;QueryStringDecoder;;;Argument[0];ReturnValue;taint;manual" + QueryStringDecoder out = null; + URI in = (URI)source(); + out = new QueryStringDecoder(in, (Charset)null); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.http;QueryStringDecoder;true;QueryStringDecoder;;;Argument[0];ReturnValue;taint;manual" + QueryStringDecoder out = null; + URI in = (URI)source(); + out = new QueryStringDecoder(in, (Charset)null, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.http;QueryStringDecoder;true;QueryStringDecoder;;;Argument[0];ReturnValue;taint;manual" + QueryStringDecoder out = null; + URI in = (URI)source(); + out = new QueryStringDecoder(in, (Charset)null, 0, false); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.http;QueryStringDecoder;true;decodeComponent;;;Argument[-1];ReturnValue;taint;manual" + String out = null; + QueryStringDecoder in = (QueryStringDecoder)source(); + out = QueryStringDecoder.decodeComponent(null); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.http;QueryStringDecoder;true;decodeComponent;;;Argument[-1];ReturnValue;taint;manual" + String out = null; + QueryStringDecoder in = (QueryStringDecoder)source(); + out = QueryStringDecoder.decodeComponent(null, null); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.http;QueryStringDecoder;true;parameters;;;Argument[-1];ReturnValue;taint;manual" + Map out = null; + QueryStringDecoder in = (QueryStringDecoder)source(); + out = in.parameters(); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.http;QueryStringDecoder;true;path;;;Argument[-1];ReturnValue;taint;manual" + String out = null; + QueryStringDecoder in = (QueryStringDecoder)source(); + out = in.path(); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.http;QueryStringDecoder;true;rawPath;;;Argument[-1];ReturnValue;taint;manual" + String out = null; + QueryStringDecoder in = (QueryStringDecoder)source(); + out = in.rawPath(); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.http;QueryStringDecoder;true;rawQuery;;;Argument[-1];ReturnValue;taint;manual" + String out = null; + QueryStringDecoder in = (QueryStringDecoder)source(); + out = in.rawQuery(); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.http;QueryStringDecoder;true;toString;;;Argument[-1];ReturnValue;taint;manual" + String out = null; + QueryStringDecoder in = (QueryStringDecoder)source(); + out = in.toString(); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.http;QueryStringDecoder;true;uri;;;Argument[-1];ReturnValue;taint;manual" + String out = null; + QueryStringDecoder in = (QueryStringDecoder)source(); + out = in.uri(); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec;Headers;true;get;(Object);;Argument[-1];ReturnValue;taint;manual" + Object out = null; + Headers in = (Headers)source(); + out = in.get(null); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec;Headers;true;get;(Object,Object);;Argument[-1];ReturnValue;taint;manual" + Object out = null; + Headers in = (Headers)source(); + out = in.get(null, null); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec;Headers;true;get;(Object,Object);;Argument[1];ReturnValue;value;manual" + Object out = null; + Object in = (Object)source(); + Headers instance = null; + out = instance.get(null, in); + sink(out); // $ hasValueFlow + } + { + // "io.netty.handler.codec;Headers;true;getAll;(Object);;Argument[-1];ReturnValue;taint;manual" + List out = null; + Headers in = (Headers)source(); + out = in.getAll(null); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec;Headers;true;getAllAndRemove;(Object);;Argument[-1];ReturnValue;taint;manual" + List out = null; + Headers in = (Headers)source(); + out = in.getAllAndRemove(null); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec;Headers;true;getAndRemove;(Object);;Argument[-1];ReturnValue;taint;manual" + Object out = null; + Headers in = (Headers)source(); + out = in.getAndRemove(null); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec;Headers;true;getAndRemove;(Object,Object);;Argument[1];ReturnValue;value;manual" + Object out = null; + Object in = (Object)source(); + Headers instance = null; + out = instance.getAndRemove(null, in); + sink(out); // $ hasValueFlow + } + { + // "io.netty.handler.codec;Headers;true;iterator;();;Argument[-1];ReturnValue;taint;manual" + Iterator out = null; + Headers in = (Headers)source(); + out = in.iterator(); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec;Headers;true;iterator;();;Argument[-1];ReturnValue;taint;manual" + Iterator out = null; + Http2Headers in = (Http2Headers)source(); + out = in.iterator(); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec;Headers;true;names;();;Argument[-1];ReturnValue;taint;manual" + Set out = null; + Headers in = (Headers)source(); + out = in.names(); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec;HeadersUtils;false;getAllAsString;(Headers,Object);;Argument[0];ReturnValue;taint;manual" + List out = null; + Headers in = (Headers)source(); + out = HeadersUtils.getAllAsString(in, null); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec;HeadersUtils;false;getAsString;(Headers,Object);;Argument[0];ReturnValue;taint;manual" + String out = null; + Headers in = (Headers)source(); + out = HeadersUtils.getAsString(in, null); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec;HeadersUtils;false;iteratorAsString;(Iterable);;Argument[0];ReturnValue;taint;manual" + Iterator out = null; + Iterable in = (Iterable)source(); + out = HeadersUtils.iteratorAsString(in); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec;HeadersUtils;false;namesAsString;(Headers);;Argument[0];ReturnValue;taint;manual" + Set out = null; + Headers in = (Headers)source(); + out = HeadersUtils.namesAsString(in); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec;HeadersUtils;false;toString;(Class,Iterator,int);;Argument[1];ReturnValue;taint;manual" + String out = null; + Iterator in = (Iterator)source(); + out = HeadersUtils.toString(null, in, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.util;ReferenceCounted;true;retain;;;Argument[-1];ReturnValue;value;manual" + Attribute out = null; + Attribute in = (Attribute)source(); + out = in.retain(); + sink(out); // $ hasValueFlow + } + { + // "io.netty.util;ReferenceCounted;true;retain;;;Argument[-1];ReturnValue;value;manual" + Attribute out = null; + Attribute in = (Attribute)source(); + out = in.retain(0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.util;ReferenceCounted;true;retain;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + AbstractReferenceCountedByteBuf in = (AbstractReferenceCountedByteBuf)source(); + out = in.retain(); + sink(out); // $ hasValueFlow + } + { + // "io.netty.util;ReferenceCounted;true;retain;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + AbstractReferenceCountedByteBuf in = (AbstractReferenceCountedByteBuf)source(); + out = in.retain(0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.util;ReferenceCounted;true;retain;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out = in.retain(); + sink(out); // $ hasValueFlow + } + { + // "io.netty.util;ReferenceCounted;true;retain;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out = in.retain(0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.util;ReferenceCounted;true;retain;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + SwappedByteBuf in = (SwappedByteBuf)source(); + out = in.retain(); + sink(out); // $ hasValueFlow + } + { + // "io.netty.util;ReferenceCounted;true;retain;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + SwappedByteBuf in = (SwappedByteBuf)source(); + out = in.retain(0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.util;ReferenceCounted;true;retain;;;Argument[-1];ReturnValue;value;manual" + ByteBufHolder out = null; + ByteBufHolder in = (ByteBufHolder)source(); + out = in.retain(); + sink(out); // $ hasValueFlow + } + { + // "io.netty.util;ReferenceCounted;true;retain;;;Argument[-1];ReturnValue;value;manual" + ByteBufHolder out = null; + ByteBufHolder in = (ByteBufHolder)source(); + out = in.retain(0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.util;ReferenceCounted;true;retain;;;Argument[-1];ReturnValue;value;manual" + ByteBufHolder out = null; + DefaultByteBufHolder in = (DefaultByteBufHolder)source(); + out = in.retain(); + sink(out); // $ hasValueFlow + } + { + // "io.netty.util;ReferenceCounted;true;retain;;;Argument[-1];ReturnValue;value;manual" + ByteBufHolder out = null; + DefaultByteBufHolder in = (DefaultByteBufHolder)source(); + out = in.retain(0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.util;ReferenceCounted;true;retain;;;Argument[-1];ReturnValue;value;manual" + CloseWebSocketFrame out = null; + CloseWebSocketFrame in = (CloseWebSocketFrame)source(); + out = in.retain(); + sink(out); // $ hasValueFlow + } + { + // "io.netty.util;ReferenceCounted;true;retain;;;Argument[-1];ReturnValue;value;manual" + CloseWebSocketFrame out = null; + CloseWebSocketFrame in = (CloseWebSocketFrame)source(); + out = in.retain(0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.util;ReferenceCounted;true;retain;;;Argument[-1];ReturnValue;value;manual" + CompositeByteBuf out = null; + CompositeByteBuf in = (CompositeByteBuf)source(); + out = in.retain(); + sink(out); // $ hasValueFlow + } + { + // "io.netty.util;ReferenceCounted;true;retain;;;Argument[-1];ReturnValue;value;manual" + CompositeByteBuf out = null; + CompositeByteBuf in = (CompositeByteBuf)source(); + out = in.retain(0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.util;ReferenceCounted;true;retain;;;Argument[-1];ReturnValue;value;manual" + ContinuationWebSocketFrame out = null; + ContinuationWebSocketFrame in = (ContinuationWebSocketFrame)source(); + out = in.retain(); + sink(out); // $ hasValueFlow + } + { + // "io.netty.util;ReferenceCounted;true;retain;;;Argument[-1];ReturnValue;value;manual" + ContinuationWebSocketFrame out = null; + ContinuationWebSocketFrame in = (ContinuationWebSocketFrame)source(); + out = in.retain(0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.util;ReferenceCounted;true;retain;;;Argument[-1];ReturnValue;value;manual" + FileRegion out = null; + DefaultFileRegion in = (DefaultFileRegion)source(); + out = in.retain(); + sink(out); // $ hasValueFlow + } + { + // "io.netty.util;ReferenceCounted;true;retain;;;Argument[-1];ReturnValue;value;manual" + FileRegion out = null; + DefaultFileRegion in = (DefaultFileRegion)source(); + out = in.retain(0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.util;ReferenceCounted;true;retain;;;Argument[-1];ReturnValue;value;manual" + FileRegion out = null; + FileRegion in = (FileRegion)source(); + out = in.retain(); + sink(out); // $ hasValueFlow + } + { + // "io.netty.util;ReferenceCounted;true;retain;;;Argument[-1];ReturnValue;value;manual" + FileRegion out = null; + FileRegion in = (FileRegion)source(); + out = in.retain(0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.util;ReferenceCounted;true;retain;;;Argument[-1];ReturnValue;value;manual" + FileUpload out = null; + FileUpload in = (FileUpload)source(); + out = in.retain(); + sink(out); // $ hasValueFlow + } + { + // "io.netty.util;ReferenceCounted;true;retain;;;Argument[-1];ReturnValue;value;manual" + FileUpload out = null; + FileUpload in = (FileUpload)source(); + out = in.retain(0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.util;ReferenceCounted;true;retain;;;Argument[-1];ReturnValue;value;manual" + FullHttpMessage out = null; + FullHttpMessage in = (FullHttpMessage)source(); + out = in.retain(); + sink(out); // $ hasValueFlow + } + { + // "io.netty.util;ReferenceCounted;true;retain;;;Argument[-1];ReturnValue;value;manual" + FullHttpMessage out = null; + FullHttpMessage in = (FullHttpMessage)source(); + out = in.retain(0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.util;ReferenceCounted;true;retain;;;Argument[-1];ReturnValue;value;manual" + FullHttpRequest out = null; + FullHttpRequest in = (FullHttpRequest)source(); + out = in.retain(); + sink(out); // $ hasValueFlow + } + { + // "io.netty.util;ReferenceCounted;true;retain;;;Argument[-1];ReturnValue;value;manual" + FullHttpRequest out = null; + FullHttpRequest in = (FullHttpRequest)source(); + out = in.retain(0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.util;ReferenceCounted;true;retain;;;Argument[-1];ReturnValue;value;manual" + FullHttpResponse out = null; + FullHttpResponse in = (FullHttpResponse)source(); + out = in.retain(); + sink(out); // $ hasValueFlow + } + { + // "io.netty.util;ReferenceCounted;true;retain;;;Argument[-1];ReturnValue;value;manual" + FullHttpResponse out = null; + FullHttpResponse in = (FullHttpResponse)source(); + out = in.retain(0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.util;ReferenceCounted;true;retain;;;Argument[-1];ReturnValue;value;manual" + HttpContent out = null; + HttpContent in = (HttpContent)source(); + out = in.retain(); + sink(out); // $ hasValueFlow + } + { + // "io.netty.util;ReferenceCounted;true;retain;;;Argument[-1];ReturnValue;value;manual" + HttpContent out = null; + HttpContent in = (HttpContent)source(); + out = in.retain(0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.util;ReferenceCounted;true;retain;;;Argument[-1];ReturnValue;value;manual" + HttpData out = null; + HttpData in = (HttpData)source(); + out = in.retain(); + sink(out); // $ hasValueFlow + } + { + // "io.netty.util;ReferenceCounted;true;retain;;;Argument[-1];ReturnValue;value;manual" + HttpData out = null; + HttpData in = (HttpData)source(); + out = in.retain(0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.util;ReferenceCounted;true;retain;;;Argument[-1];ReturnValue;value;manual" + InterfaceHttpData out = null; + InterfaceHttpData in = (InterfaceHttpData)source(); + out = in.retain(); + sink(out); // $ hasValueFlow + } + { + // "io.netty.util;ReferenceCounted;true;retain;;;Argument[-1];ReturnValue;value;manual" + InterfaceHttpData out = null; + InterfaceHttpData in = (InterfaceHttpData)source(); + out = in.retain(0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.util;ReferenceCounted;true;retain;;;Argument[-1];ReturnValue;value;manual" + LastHttpContent out = null; + LastHttpContent in = (LastHttpContent)source(); + out = in.retain(); + sink(out); // $ hasValueFlow + } + { + // "io.netty.util;ReferenceCounted;true;retain;;;Argument[-1];ReturnValue;value;manual" + LastHttpContent out = null; + LastHttpContent in = (LastHttpContent)source(); + out = in.retain(0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.util;ReferenceCounted;true;retain;;;Argument[-1];ReturnValue;value;manual" + ReferenceCounted out = null; + AbstractReferenceCounted in = (AbstractReferenceCounted)source(); + out = in.retain(); + sink(out); // $ hasValueFlow + } + { + // "io.netty.util;ReferenceCounted;true;retain;;;Argument[-1];ReturnValue;value;manual" + ReferenceCounted out = null; + AbstractReferenceCounted in = (AbstractReferenceCounted)source(); + out = in.retain(0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.util;ReferenceCounted;true;retain;;;Argument[-1];ReturnValue;value;manual" + ReferenceCounted out = null; + ReferenceCounted in = (ReferenceCounted)source(); + out = in.retain(); + sink(out); // $ hasValueFlow + } + { + // "io.netty.util;ReferenceCounted;true;retain;;;Argument[-1];ReturnValue;value;manual" + ReferenceCounted out = null; + ReferenceCounted in = (ReferenceCounted)source(); + out = in.retain(0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.util;ReferenceCounted;true;retain;;;Argument[-1];ReturnValue;value;manual" + TextWebSocketFrame out = null; + TextWebSocketFrame in = (TextWebSocketFrame)source(); + out = in.retain(); + sink(out); // $ hasValueFlow + } + { + // "io.netty.util;ReferenceCounted;true;retain;;;Argument[-1];ReturnValue;value;manual" + TextWebSocketFrame out = null; + TextWebSocketFrame in = (TextWebSocketFrame)source(); + out = in.retain(0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.util;ReferenceCounted;true;retain;;;Argument[-1];ReturnValue;value;manual" + WebSocketFrame out = null; + WebSocketFrame in = (WebSocketFrame)source(); + out = in.retain(); + sink(out); // $ hasValueFlow + } + { + // "io.netty.util;ReferenceCounted;true;retain;;;Argument[-1];ReturnValue;value;manual" + WebSocketFrame out = null; + WebSocketFrame in = (WebSocketFrame)source(); + out = in.retain(0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.util;ReferenceCounted;true;touch;;;Argument[-1];ReturnValue;value;manual" + Attribute out = null; + Attribute in = (Attribute)source(); + out = in.touch(); + sink(out); // $ hasValueFlow + } + { + // "io.netty.util;ReferenceCounted;true;touch;;;Argument[-1];ReturnValue;value;manual" + Attribute out = null; + Attribute in = (Attribute)source(); + out = in.touch(null); + sink(out); // $ hasValueFlow + } + { + // "io.netty.util;ReferenceCounted;true;touch;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + AbstractReferenceCountedByteBuf in = (AbstractReferenceCountedByteBuf)source(); + out = in.touch(); + sink(out); // $ hasValueFlow + } + { + // "io.netty.util;ReferenceCounted;true;touch;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + AbstractReferenceCountedByteBuf in = (AbstractReferenceCountedByteBuf)source(); + out = in.touch(null); + sink(out); // $ hasValueFlow + } + { + // "io.netty.util;ReferenceCounted;true;touch;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out = in.touch(); + sink(out); // $ hasValueFlow + } + { + // "io.netty.util;ReferenceCounted;true;touch;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out = in.touch(null); + sink(out); // $ hasValueFlow + } + { + // "io.netty.util;ReferenceCounted;true;touch;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + SwappedByteBuf in = (SwappedByteBuf)source(); + out = in.touch(); + sink(out); // $ hasValueFlow + } + { + // "io.netty.util;ReferenceCounted;true;touch;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + SwappedByteBuf in = (SwappedByteBuf)source(); + out = in.touch(null); + sink(out); // $ hasValueFlow + } + { + // "io.netty.util;ReferenceCounted;true;touch;;;Argument[-1];ReturnValue;value;manual" + ByteBufHolder out = null; + ByteBufHolder in = (ByteBufHolder)source(); + out = in.touch(); + sink(out); // $ hasValueFlow + } + { + // "io.netty.util;ReferenceCounted;true;touch;;;Argument[-1];ReturnValue;value;manual" + ByteBufHolder out = null; + ByteBufHolder in = (ByteBufHolder)source(); + out = in.touch(null); + sink(out); // $ hasValueFlow + } + { + // "io.netty.util;ReferenceCounted;true;touch;;;Argument[-1];ReturnValue;value;manual" + ByteBufHolder out = null; + DefaultByteBufHolder in = (DefaultByteBufHolder)source(); + out = in.touch(); + sink(out); // $ hasValueFlow + } + { + // "io.netty.util;ReferenceCounted;true;touch;;;Argument[-1];ReturnValue;value;manual" + ByteBufHolder out = null; + DefaultByteBufHolder in = (DefaultByteBufHolder)source(); + out = in.touch(null); + sink(out); // $ hasValueFlow + } + { + // "io.netty.util;ReferenceCounted;true;touch;;;Argument[-1];ReturnValue;value;manual" + CloseWebSocketFrame out = null; + CloseWebSocketFrame in = (CloseWebSocketFrame)source(); + out = in.touch(); + sink(out); // $ hasValueFlow + } + { + // "io.netty.util;ReferenceCounted;true;touch;;;Argument[-1];ReturnValue;value;manual" + CloseWebSocketFrame out = null; + CloseWebSocketFrame in = (CloseWebSocketFrame)source(); + out = in.touch(null); + sink(out); // $ hasValueFlow + } + { + // "io.netty.util;ReferenceCounted;true;touch;;;Argument[-1];ReturnValue;value;manual" + CompositeByteBuf out = null; + CompositeByteBuf in = (CompositeByteBuf)source(); + out = in.touch(); + sink(out); // $ hasValueFlow + } + { + // "io.netty.util;ReferenceCounted;true;touch;;;Argument[-1];ReturnValue;value;manual" + CompositeByteBuf out = null; + CompositeByteBuf in = (CompositeByteBuf)source(); + out = in.touch(null); + sink(out); // $ hasValueFlow + } + { + // "io.netty.util;ReferenceCounted;true;touch;;;Argument[-1];ReturnValue;value;manual" + ContinuationWebSocketFrame out = null; + ContinuationWebSocketFrame in = (ContinuationWebSocketFrame)source(); + out = in.touch(); + sink(out); // $ hasValueFlow + } + { + // "io.netty.util;ReferenceCounted;true;touch;;;Argument[-1];ReturnValue;value;manual" + ContinuationWebSocketFrame out = null; + ContinuationWebSocketFrame in = (ContinuationWebSocketFrame)source(); + out = in.touch(null); + sink(out); // $ hasValueFlow + } + { + // "io.netty.util;ReferenceCounted;true;touch;;;Argument[-1];ReturnValue;value;manual" + FileRegion out = null; + DefaultFileRegion in = (DefaultFileRegion)source(); + out = in.touch(); + sink(out); // $ hasValueFlow + } + { + // "io.netty.util;ReferenceCounted;true;touch;;;Argument[-1];ReturnValue;value;manual" + FileRegion out = null; + DefaultFileRegion in = (DefaultFileRegion)source(); + out = in.touch(null); + sink(out); // $ hasValueFlow + } + { + // "io.netty.util;ReferenceCounted;true;touch;;;Argument[-1];ReturnValue;value;manual" + FileRegion out = null; + FileRegion in = (FileRegion)source(); + out = in.touch(); + sink(out); // $ hasValueFlow + } + { + // "io.netty.util;ReferenceCounted;true;touch;;;Argument[-1];ReturnValue;value;manual" + FileRegion out = null; + FileRegion in = (FileRegion)source(); + out = in.touch(null); + sink(out); // $ hasValueFlow + } + { + // "io.netty.util;ReferenceCounted;true;touch;;;Argument[-1];ReturnValue;value;manual" + FileUpload out = null; + FileUpload in = (FileUpload)source(); + out = in.touch(); + sink(out); // $ hasValueFlow + } + { + // "io.netty.util;ReferenceCounted;true;touch;;;Argument[-1];ReturnValue;value;manual" + FileUpload out = null; + FileUpload in = (FileUpload)source(); + out = in.touch(null); + sink(out); // $ hasValueFlow + } + { + // "io.netty.util;ReferenceCounted;true;touch;;;Argument[-1];ReturnValue;value;manual" + FullHttpMessage out = null; + FullHttpMessage in = (FullHttpMessage)source(); + out = in.touch(); + sink(out); // $ hasValueFlow + } + { + // "io.netty.util;ReferenceCounted;true;touch;;;Argument[-1];ReturnValue;value;manual" + FullHttpMessage out = null; + FullHttpMessage in = (FullHttpMessage)source(); + out = in.touch(null); + sink(out); // $ hasValueFlow + } + { + // "io.netty.util;ReferenceCounted;true;touch;;;Argument[-1];ReturnValue;value;manual" + FullHttpRequest out = null; + FullHttpRequest in = (FullHttpRequest)source(); + out = in.touch(); + sink(out); // $ hasValueFlow + } + { + // "io.netty.util;ReferenceCounted;true;touch;;;Argument[-1];ReturnValue;value;manual" + FullHttpRequest out = null; + FullHttpRequest in = (FullHttpRequest)source(); + out = in.touch(null); + sink(out); // $ hasValueFlow + } + { + // "io.netty.util;ReferenceCounted;true;touch;;;Argument[-1];ReturnValue;value;manual" + FullHttpResponse out = null; + FullHttpResponse in = (FullHttpResponse)source(); + out = in.touch(); + sink(out); // $ hasValueFlow + } + { + // "io.netty.util;ReferenceCounted;true;touch;;;Argument[-1];ReturnValue;value;manual" + FullHttpResponse out = null; + FullHttpResponse in = (FullHttpResponse)source(); + out = in.touch(null); + sink(out); // $ hasValueFlow + } + { + // "io.netty.util;ReferenceCounted;true;touch;;;Argument[-1];ReturnValue;value;manual" + HttpContent out = null; + HttpContent in = (HttpContent)source(); + out = in.touch(); + sink(out); // $ hasValueFlow + } + { + // "io.netty.util;ReferenceCounted;true;touch;;;Argument[-1];ReturnValue;value;manual" + HttpContent out = null; + HttpContent in = (HttpContent)source(); + out = in.touch(null); + sink(out); // $ hasValueFlow + } + { + // "io.netty.util;ReferenceCounted;true;touch;;;Argument[-1];ReturnValue;value;manual" + HttpData out = null; + HttpData in = (HttpData)source(); + out = in.touch(); + sink(out); // $ hasValueFlow + } + { + // "io.netty.util;ReferenceCounted;true;touch;;;Argument[-1];ReturnValue;value;manual" + HttpData out = null; + HttpData in = (HttpData)source(); + out = in.touch(null); + sink(out); // $ hasValueFlow + } + { + // "io.netty.util;ReferenceCounted;true;touch;;;Argument[-1];ReturnValue;value;manual" + InterfaceHttpData out = null; + InterfaceHttpData in = (InterfaceHttpData)source(); + out = in.touch(); + sink(out); // $ hasValueFlow + } + { + // "io.netty.util;ReferenceCounted;true;touch;;;Argument[-1];ReturnValue;value;manual" + InterfaceHttpData out = null; + InterfaceHttpData in = (InterfaceHttpData)source(); + out = in.touch(null); + sink(out); // $ hasValueFlow + } + { + // "io.netty.util;ReferenceCounted;true;touch;;;Argument[-1];ReturnValue;value;manual" + LastHttpContent out = null; + LastHttpContent in = (LastHttpContent)source(); + out = in.touch(); + sink(out); // $ hasValueFlow + } + { + // "io.netty.util;ReferenceCounted;true;touch;;;Argument[-1];ReturnValue;value;manual" + LastHttpContent out = null; + LastHttpContent in = (LastHttpContent)source(); + out = in.touch(null); + sink(out); // $ hasValueFlow + } + { + // "io.netty.util;ReferenceCounted;true;touch;;;Argument[-1];ReturnValue;value;manual" + ReferenceCounted out = null; + AbstractReferenceCounted in = (AbstractReferenceCounted)source(); + out = in.touch(); + sink(out); // $ hasValueFlow + } + { + // "io.netty.util;ReferenceCounted;true;touch;;;Argument[-1];ReturnValue;value;manual" + ReferenceCounted out = null; + ReferenceCounted in = (ReferenceCounted)source(); + out = in.touch(); + sink(out); // $ hasValueFlow + } + { + // "io.netty.util;ReferenceCounted;true;touch;;;Argument[-1];ReturnValue;value;manual" + ReferenceCounted out = null; + ReferenceCounted in = (ReferenceCounted)source(); + out = in.touch(null); + sink(out); // $ hasValueFlow + } + { + // "io.netty.util;ReferenceCounted;true;touch;;;Argument[-1];ReturnValue;value;manual" + TextWebSocketFrame out = null; + TextWebSocketFrame in = (TextWebSocketFrame)source(); + out = in.touch(); + sink(out); // $ hasValueFlow + } + { + // "io.netty.util;ReferenceCounted;true;touch;;;Argument[-1];ReturnValue;value;manual" + TextWebSocketFrame out = null; + TextWebSocketFrame in = (TextWebSocketFrame)source(); + out = in.touch(null); + sink(out); // $ hasValueFlow + } + { + // "io.netty.util;ReferenceCounted;true;touch;;;Argument[-1];ReturnValue;value;manual" + WebSocketFrame out = null; + WebSocketFrame in = (WebSocketFrame)source(); + out = in.touch(); + sink(out); // $ hasValueFlow + } + { + // "io.netty.util;ReferenceCounted;true;touch;;;Argument[-1];ReturnValue;value;manual" + WebSocketFrame out = null; + WebSocketFrame in = (WebSocketFrame)source(); + out = in.touch(null); + sink(out); // $ hasValueFlow + } + + } + +} \ No newline at end of file diff --git a/java/ql/test/library-tests/frameworks/netty/generated/options b/java/ql/test/library-tests/frameworks/netty/generated/options new file mode 100644 index 00000000000..9c4517826cc --- /dev/null +++ b/java/ql/test/library-tests/frameworks/netty/generated/options @@ -0,0 +1 @@ +//semmle-extractor-options: --javac-args -cp ${testdir}/../../../../stubs/netty-4.1.x \ No newline at end of file diff --git a/java/ql/test/library-tests/frameworks/netty/generated/test.expected b/java/ql/test/library-tests/frameworks/netty/generated/test.expected new file mode 100644 index 00000000000..e69de29bb2d diff --git a/java/ql/test/library-tests/frameworks/netty/generated/test.ql b/java/ql/test/library-tests/frameworks/netty/generated/test.ql new file mode 100644 index 00000000000..5d91e4e8e26 --- /dev/null +++ b/java/ql/test/library-tests/frameworks/netty/generated/test.ql @@ -0,0 +1,2 @@ +import java +import TestUtilities.InlineFlowTest From f1c347d4e1de5c5fd106f9dc9d837fb99d3c9066 Mon Sep 17 00:00:00 2001 From: Joe Farebrother <joefarebrother@github.com> Date: Fri, 17 Feb 2023 15:05:20 +0000 Subject: [PATCH 365/631] Generate tests and stubs --- .../frameworks/netty/generated/Test.java | 3012 +++++++---------- .../io/netty/buffer/DefaultByteBufHolder.java | 28 + .../io/netty/channel/DefaultFileRegion.java | 28 + .../io/netty/channel/FileRegion.java | 19 + .../io/netty/handler/codec/Headers.java | 6 +- .../io/netty/handler/codec/HeadersUtils.java | 19 + .../io/netty/handler/codec/base64/Base64.java | 26 + .../handler/codec/base64/Base64Dialect.java | 10 + .../handler/codec/http/FullHttpResponse.java | 23 + .../handler/codec/http/HttpResponse.java | 15 + .../codec/http/HttpResponseStatus.java | 82 + .../handler/codec/http/HttpStatusClass.java | 11 + .../codec/http/QueryStringDecoder.java | 31 + .../handler/codec/http/cookie/Cookie.java | 158 +- .../codec/http/cookie/CookieDecoder.java | 12 + .../codec/http/cookie/CookieHeaderNames.java | 21 + .../codec/http/cookie/DefaultCookie.java | 34 + .../http/cookie/ServerCookieDecoder.java | 17 + .../codec/http/multipart/Attribute.java | 20 + .../codec/http/multipart/FileUpload.java | 24 + .../codec/http/multipart/HttpData.java | 43 + .../codec/http/multipart/HttpDataFactory.java | 23 + .../HttpPostMultipartRequestDecoder.java | 34 + .../multipart/HttpPostRequestDecoder.java | 34 + .../HttpPostStandardRequestDecoder.java | 33 + .../http/multipart/InterfaceHttpData.java | 20 + .../InterfaceHttpPostRequestDecoder.java | 24 + .../http/websocketx/CloseWebSocketFrame.java | 28 + .../ContinuationWebSocketFrame.java | 23 + .../http/websocketx/TextWebSocketFrame.java | 24 + .../http/websocketx/WebSocketCloseStatus.java | 34 + .../codec/http/websocketx/WebSocketFrame.java | 24 + .../handler/codec/http2/Http2Connection.java | 65 + .../handler/codec/http2/Http2DataWriter.java | 13 + .../codec/http2/Http2FlowController.java | 15 + .../netty/handler/codec/http2/Http2Frame.java | 9 + .../codec/http2/Http2FrameSizePolicy.java | 10 + .../handler/codec/http2/Http2FrameStream.java | 11 + .../handler/codec/http2/Http2FrameWriter.java | 37 + .../codec/http2/Http2HeadersEncoder.java | 25 + .../codec/http2/Http2HeadersFrame.java | 13 + .../codec/http2/Http2LocalFlowController.java | 17 + .../codec/http2/Http2PushPromiseFrame.java | 17 + .../http2/Http2RemoteFlowController.java | 31 + .../handler/codec/http2/Http2Stream.java | 35 + .../handler/codec/http2/Http2StreamFrame.java | 12 + .../codec/http2/Http2StreamVisitor.java | 10 + .../codec/http2/HttpConversionUtil.java | 37 + .../netty/util/AbstractReferenceCounted.java | 18 + .../util/collection/CharObjectHashMap.java | 8 +- .../netty/util/collection/CharObjectMap.java | 4 +- 51 files changed, 2437 insertions(+), 1890 deletions(-) create mode 100644 java/ql/test/stubs/netty-4.1.x/io/netty/buffer/DefaultByteBufHolder.java create mode 100644 java/ql/test/stubs/netty-4.1.x/io/netty/channel/DefaultFileRegion.java create mode 100644 java/ql/test/stubs/netty-4.1.x/io/netty/channel/FileRegion.java create mode 100644 java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/HeadersUtils.java create mode 100644 java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/base64/Base64.java create mode 100644 java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/base64/Base64Dialect.java create mode 100644 java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http/FullHttpResponse.java create mode 100644 java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http/HttpResponse.java create mode 100644 java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http/HttpResponseStatus.java create mode 100644 java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http/HttpStatusClass.java create mode 100644 java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http/QueryStringDecoder.java create mode 100644 java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http/cookie/CookieDecoder.java create mode 100644 java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http/cookie/CookieHeaderNames.java create mode 100644 java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http/cookie/DefaultCookie.java create mode 100644 java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http/cookie/ServerCookieDecoder.java create mode 100644 java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http/multipart/Attribute.java create mode 100644 java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http/multipart/FileUpload.java create mode 100644 java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http/multipart/HttpData.java create mode 100644 java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http/multipart/HttpDataFactory.java create mode 100644 java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http/multipart/HttpPostMultipartRequestDecoder.java create mode 100644 java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http/multipart/HttpPostRequestDecoder.java create mode 100644 java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http/multipart/HttpPostStandardRequestDecoder.java create mode 100644 java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http/multipart/InterfaceHttpData.java create mode 100644 java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http/multipart/InterfaceHttpPostRequestDecoder.java create mode 100644 java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http/websocketx/CloseWebSocketFrame.java create mode 100644 java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http/websocketx/ContinuationWebSocketFrame.java create mode 100644 java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http/websocketx/TextWebSocketFrame.java create mode 100644 java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http/websocketx/WebSocketCloseStatus.java create mode 100644 java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http/websocketx/WebSocketFrame.java create mode 100644 java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http2/Http2Connection.java create mode 100644 java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http2/Http2DataWriter.java create mode 100644 java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http2/Http2FlowController.java create mode 100644 java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http2/Http2Frame.java create mode 100644 java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http2/Http2FrameSizePolicy.java create mode 100644 java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http2/Http2FrameStream.java create mode 100644 java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http2/Http2FrameWriter.java create mode 100644 java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http2/Http2HeadersEncoder.java create mode 100644 java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http2/Http2HeadersFrame.java create mode 100644 java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http2/Http2LocalFlowController.java create mode 100644 java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http2/Http2PushPromiseFrame.java create mode 100644 java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http2/Http2RemoteFlowController.java create mode 100644 java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http2/Http2Stream.java create mode 100644 java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http2/Http2StreamFrame.java create mode 100644 java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http2/Http2StreamVisitor.java create mode 100644 java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http2/HttpConversionUtil.java create mode 100644 java/ql/test/stubs/netty-4.1.x/io/netty/util/AbstractReferenceCounted.java diff --git a/java/ql/test/library-tests/frameworks/netty/generated/Test.java b/java/ql/test/library-tests/frameworks/netty/generated/Test.java index 6f820c81656..5f1be7834be 100644 --- a/java/ql/test/library-tests/frameworks/netty/generated/Test.java +++ b/java/ql/test/library-tests/frameworks/netty/generated/Test.java @@ -50,7 +50,6 @@ import java.io.InputStream; import java.io.OutputStream; import java.net.URI; import java.nio.ByteBuffer; -import java.nio.ByteOrder; import java.nio.channels.FileChannel; import java.nio.channels.GatheringByteChannel; import java.nio.channels.ScatteringByteChannel; @@ -251,523 +250,411 @@ public class Test { sink(out); // $ hasTaintFlow } { - // "io.netty.buffer;ByteBuf;true;ensureWritable;;;Argument[-1];ReturnValue;value;manual" + // "io.netty.buffer;ByteBuf;true;ensureWritable;(int);;Argument[-1];ReturnValue;value;manual" ByteBuf out = null; AbstractByteBuf in = (AbstractByteBuf)source(); out = in.ensureWritable(0); sink(out); // $ hasValueFlow } { - // "io.netty.buffer;ByteBuf;true;ensureWritable;;;Argument[-1];ReturnValue;value;manual" + // "io.netty.buffer;ByteBuf;true;ensureWritable;(int);;Argument[-1];ReturnValue;value;manual" ByteBuf out = null; ByteBuf in = (ByteBuf)source(); out = in.ensureWritable(0); sink(out); // $ hasValueFlow } { - // "io.netty.buffer;ByteBuf;true;ensureWritable;;;Argument[-1];ReturnValue;value;manual" + // "io.netty.buffer;ByteBuf;true;ensureWritable;(int);;Argument[-1];ReturnValue;value;manual" ByteBuf out = null; SwappedByteBuf in = (SwappedByteBuf)source(); out = in.ensureWritable(0); sink(out); // $ hasValueFlow } { - // "io.netty.buffer;ByteBuf;true;ensureWritable;;;Argument[-1];ReturnValue;value;manual" + // "io.netty.buffer;ByteBuf;true;ensureWritable;(int);;Argument[-1];ReturnValue;value;manual" CompositeByteBuf out = null; CompositeByteBuf in = (CompositeByteBuf)source(); out = in.ensureWritable(0); sink(out); // $ hasValueFlow } { - // "io.netty.buffer;ByteBuf;true;ensureWritable;;;Argument[-1];ReturnValue;value;manual" - int out = null; - AbstractByteBuf in = (AbstractByteBuf)source(); - out = in.ensureWritable(0, false); - sink(out); // $ hasValueFlow - } - { - // "io.netty.buffer;ByteBuf;true;ensureWritable;;;Argument[-1];ReturnValue;value;manual" - int out = null; - ByteBuf in = (ByteBuf)source(); - out = in.ensureWritable(0, false); - sink(out); // $ hasValueFlow - } - { - // "io.netty.buffer;ByteBuf;true;ensureWritable;;;Argument[-1];ReturnValue;value;manual" - int out = null; - SwappedByteBuf in = (SwappedByteBuf)source(); - out = in.ensureWritable(0, false); - sink(out); // $ hasValueFlow - } - { - // "io.netty.buffer;ByteBuf;true;getByte;;;Argument[-1];ReturnValue;taint;manual" - byte out = null; - AbstractByteBuf in = (AbstractByteBuf)source(); - out = in.getByte(0); - sink(out); // $ hasTaintFlow - } - { - // "io.netty.buffer;ByteBuf;true;getByte;;;Argument[-1];ReturnValue;taint;manual" - byte out = null; - ByteBuf in = (ByteBuf)source(); - out = in.getByte(0); - sink(out); // $ hasTaintFlow - } - { - // "io.netty.buffer;ByteBuf;true;getByte;;;Argument[-1];ReturnValue;taint;manual" - byte out = null; - CompositeByteBuf in = (CompositeByteBuf)source(); - out = in.getByte(0); - sink(out); // $ hasTaintFlow - } - { - // "io.netty.buffer;ByteBuf;true;getByte;;;Argument[-1];ReturnValue;taint;manual" - byte out = null; - SwappedByteBuf in = (SwappedByteBuf)source(); - out = in.getByte(0); - sink(out); // $ hasTaintFlow - } - { - // "io.netty.buffer;ByteBuf;true;getBytes;;;Argument[-1];Argument[1];taint;manual" + // "io.netty.buffer;ByteBuf;true;getBytes;(int,ByteBuf);;Argument[-1];Argument[1];taint;manual" ByteBuf out = null; AbstractByteBuf in = (AbstractByteBuf)source(); in.getBytes(0, out); sink(out); // $ hasTaintFlow } { - // "io.netty.buffer;ByteBuf;true;getBytes;;;Argument[-1];Argument[1];taint;manual" - ByteBuf out = null; - AbstractByteBuf in = (AbstractByteBuf)source(); - in.getBytes(0, out, 0); - sink(out); // $ hasTaintFlow - } - { - // "io.netty.buffer;ByteBuf;true;getBytes;;;Argument[-1];Argument[1];taint;manual" + // "io.netty.buffer;ByteBuf;true;getBytes;(int,ByteBuf);;Argument[-1];Argument[1];taint;manual" ByteBuf out = null; ByteBuf in = (ByteBuf)source(); in.getBytes(0, out); sink(out); // $ hasTaintFlow } { - // "io.netty.buffer;ByteBuf;true;getBytes;;;Argument[-1];Argument[1];taint;manual" - ByteBuf out = null; - ByteBuf in = (ByteBuf)source(); - in.getBytes(0, out, 0); - sink(out); // $ hasTaintFlow - } - { - // "io.netty.buffer;ByteBuf;true;getBytes;;;Argument[-1];Argument[1];taint;manual" - ByteBuf out = null; - ByteBuf in = (ByteBuf)source(); - in.getBytes(0, out, 0, 0); - sink(out); // $ hasTaintFlow - } - { - // "io.netty.buffer;ByteBuf;true;getBytes;;;Argument[-1];Argument[1];taint;manual" + // "io.netty.buffer;ByteBuf;true;getBytes;(int,ByteBuf);;Argument[-1];Argument[1];taint;manual" ByteBuf out = null; CompositeByteBuf in = (CompositeByteBuf)source(); in.getBytes(0, out); sink(out); // $ hasTaintFlow } { - // "io.netty.buffer;ByteBuf;true;getBytes;;;Argument[-1];Argument[1];taint;manual" - ByteBuf out = null; - CompositeByteBuf in = (CompositeByteBuf)source(); - in.getBytes(0, out, 0); - sink(out); // $ hasTaintFlow - } - { - // "io.netty.buffer;ByteBuf;true;getBytes;;;Argument[-1];Argument[1];taint;manual" - ByteBuf out = null; - CompositeByteBuf in = (CompositeByteBuf)source(); - in.getBytes(0, out, 0, 0); - sink(out); // $ hasTaintFlow - } - { - // "io.netty.buffer;ByteBuf;true;getBytes;;;Argument[-1];Argument[1];taint;manual" + // "io.netty.buffer;ByteBuf;true;getBytes;(int,ByteBuf);;Argument[-1];Argument[1];taint;manual" ByteBuf out = null; SwappedByteBuf in = (SwappedByteBuf)source(); in.getBytes(0, out); sink(out); // $ hasTaintFlow } { - // "io.netty.buffer;ByteBuf;true;getBytes;;;Argument[-1];Argument[1];taint;manual" - ByteBuf out = null; - SwappedByteBuf in = (SwappedByteBuf)source(); - in.getBytes(0, out, 0); - sink(out); // $ hasTaintFlow - } - { - // "io.netty.buffer;ByteBuf;true;getBytes;;;Argument[-1];Argument[1];taint;manual" - ByteBuf out = null; - SwappedByteBuf in = (SwappedByteBuf)source(); - in.getBytes(0, out, 0, 0); - sink(out); // $ hasTaintFlow - } - { - // "io.netty.buffer;ByteBuf;true;getBytes;;;Argument[-1];Argument[1];taint;manual" - ByteBuffer out = null; - ByteBuf in = (ByteBuf)source(); - in.getBytes(0, out); - sink(out); // $ hasTaintFlow - } - { - // "io.netty.buffer;ByteBuf;true;getBytes;;;Argument[-1];Argument[1];taint;manual" - ByteBuffer out = null; - CompositeByteBuf in = (CompositeByteBuf)source(); - in.getBytes(0, out); - sink(out); // $ hasTaintFlow - } - { - // "io.netty.buffer;ByteBuf;true;getBytes;;;Argument[-1];Argument[1];taint;manual" - ByteBuffer out = null; - SwappedByteBuf in = (SwappedByteBuf)source(); - in.getBytes(0, out); - sink(out); // $ hasTaintFlow - } - { - // "io.netty.buffer;ByteBuf;true;getBytes;;;Argument[-1];Argument[1];taint;manual" - FileChannel out = null; - ByteBuf in = (ByteBuf)source(); - in.getBytes(0, out, 0L, 0); - sink(out); // $ hasTaintFlow - } - { - // "io.netty.buffer;ByteBuf;true;getBytes;;;Argument[-1];Argument[1];taint;manual" - FileChannel out = null; - CompositeByteBuf in = (CompositeByteBuf)source(); - in.getBytes(0, out, 0L, 0); - sink(out); // $ hasTaintFlow - } - { - // "io.netty.buffer;ByteBuf;true;getBytes;;;Argument[-1];Argument[1];taint;manual" - FileChannel out = null; - SwappedByteBuf in = (SwappedByteBuf)source(); - in.getBytes(0, out, 0L, 0); - sink(out); // $ hasTaintFlow - } - { - // "io.netty.buffer;ByteBuf;true;getBytes;;;Argument[-1];Argument[1];taint;manual" - GatheringByteChannel out = null; - ByteBuf in = (ByteBuf)source(); - in.getBytes(0, out, 0); - sink(out); // $ hasTaintFlow - } - { - // "io.netty.buffer;ByteBuf;true;getBytes;;;Argument[-1];Argument[1];taint;manual" - GatheringByteChannel out = null; - CompositeByteBuf in = (CompositeByteBuf)source(); - in.getBytes(0, out, 0); - sink(out); // $ hasTaintFlow - } - { - // "io.netty.buffer;ByteBuf;true;getBytes;;;Argument[-1];Argument[1];taint;manual" - GatheringByteChannel out = null; - SwappedByteBuf in = (SwappedByteBuf)source(); - in.getBytes(0, out, 0); - sink(out); // $ hasTaintFlow - } - { - // "io.netty.buffer;ByteBuf;true;getBytes;;;Argument[-1];Argument[1];taint;manual" - OutputStream out = null; - ByteBuf in = (ByteBuf)source(); - in.getBytes(0, out, 0); - sink(out); // $ hasTaintFlow - } - { - // "io.netty.buffer;ByteBuf;true;getBytes;;;Argument[-1];Argument[1];taint;manual" - OutputStream out = null; - CompositeByteBuf in = (CompositeByteBuf)source(); - in.getBytes(0, out, 0); - sink(out); // $ hasTaintFlow - } - { - // "io.netty.buffer;ByteBuf;true;getBytes;;;Argument[-1];Argument[1];taint;manual" - OutputStream out = null; - SwappedByteBuf in = (SwappedByteBuf)source(); - in.getBytes(0, out, 0); - sink(out); // $ hasTaintFlow - } - { - // "io.netty.buffer;ByteBuf;true;getBytes;;;Argument[-1];Argument[1];taint;manual" - byte[] out = null; - AbstractByteBuf in = (AbstractByteBuf)source(); - in.getBytes(0, out); - sink(out); // $ hasTaintFlow - } - { - // "io.netty.buffer;ByteBuf;true;getBytes;;;Argument[-1];Argument[1];taint;manual" - byte[] out = null; - ByteBuf in = (ByteBuf)source(); - in.getBytes(0, out); - sink(out); // $ hasTaintFlow - } - { - // "io.netty.buffer;ByteBuf;true;getBytes;;;Argument[-1];Argument[1];taint;manual" - byte[] out = null; - ByteBuf in = (ByteBuf)source(); - in.getBytes(0, out, 0, 0); - sink(out); // $ hasTaintFlow - } - { - // "io.netty.buffer;ByteBuf;true;getBytes;;;Argument[-1];Argument[1];taint;manual" - byte[] out = null; - CompositeByteBuf in = (CompositeByteBuf)source(); - in.getBytes(0, out); - sink(out); // $ hasTaintFlow - } - { - // "io.netty.buffer;ByteBuf;true;getBytes;;;Argument[-1];Argument[1];taint;manual" - byte[] out = null; - CompositeByteBuf in = (CompositeByteBuf)source(); - in.getBytes(0, out, 0, 0); - sink(out); // $ hasTaintFlow - } - { - // "io.netty.buffer;ByteBuf;true;getBytes;;;Argument[-1];Argument[1];taint;manual" - byte[] out = null; - SwappedByteBuf in = (SwappedByteBuf)source(); - in.getBytes(0, out); - sink(out); // $ hasTaintFlow - } - { - // "io.netty.buffer;ByteBuf;true;getBytes;;;Argument[-1];Argument[1];taint;manual" - byte[] out = null; - SwappedByteBuf in = (SwappedByteBuf)source(); - in.getBytes(0, out, 0, 0); - sink(out); // $ hasTaintFlow - } - { - // "io.netty.buffer;ByteBuf;true;getBytes;;;Argument[-1];ReturnValue;value;manual" + // "io.netty.buffer;ByteBuf;true;getBytes;(int,ByteBuf);;Argument[-1];ReturnValue;value;manual" ByteBuf out = null; AbstractByteBuf in = (AbstractByteBuf)source(); out = in.getBytes(0, (ByteBuf)null); sink(out); // $ hasValueFlow } { - // "io.netty.buffer;ByteBuf;true;getBytes;;;Argument[-1];ReturnValue;value;manual" - ByteBuf out = null; - AbstractByteBuf in = (AbstractByteBuf)source(); - out = in.getBytes(0, (byte[])null); - sink(out); // $ hasValueFlow - } - { - // "io.netty.buffer;ByteBuf;true;getBytes;;;Argument[-1];ReturnValue;value;manual" - ByteBuf out = null; - AbstractByteBuf in = (AbstractByteBuf)source(); - out = in.getBytes(0, null, 0); - sink(out); // $ hasValueFlow - } - { - // "io.netty.buffer;ByteBuf;true;getBytes;;;Argument[-1];ReturnValue;value;manual" + // "io.netty.buffer;ByteBuf;true;getBytes;(int,ByteBuf);;Argument[-1];ReturnValue;value;manual" ByteBuf out = null; ByteBuf in = (ByteBuf)source(); out = in.getBytes(0, (ByteBuf)null); sink(out); // $ hasValueFlow } { - // "io.netty.buffer;ByteBuf;true;getBytes;;;Argument[-1];ReturnValue;value;manual" + // "io.netty.buffer;ByteBuf;true;getBytes;(int,ByteBuf);;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + SwappedByteBuf in = (SwappedByteBuf)source(); + out = in.getBytes(0, (ByteBuf)null); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;getBytes;(int,ByteBuf);;Argument[-1];ReturnValue;value;manual" + CompositeByteBuf out = null; + CompositeByteBuf in = (CompositeByteBuf)source(); + out = in.getBytes(0, (ByteBuf)null); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;getBytes;(int,ByteBuf,int);;Argument[-1];Argument[1];taint;manual" + ByteBuf out = null; + AbstractByteBuf in = (AbstractByteBuf)source(); + in.getBytes(0, out, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;getBytes;(int,ByteBuf,int);;Argument[-1];Argument[1];taint;manual" + ByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + in.getBytes(0, out, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;getBytes;(int,ByteBuf,int);;Argument[-1];Argument[1];taint;manual" + ByteBuf out = null; + CompositeByteBuf in = (CompositeByteBuf)source(); + in.getBytes(0, out, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;getBytes;(int,ByteBuf,int);;Argument[-1];Argument[1];taint;manual" + ByteBuf out = null; + SwappedByteBuf in = (SwappedByteBuf)source(); + in.getBytes(0, out, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;getBytes;(int,ByteBuf,int);;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + AbstractByteBuf in = (AbstractByteBuf)source(); + out = in.getBytes(0, (ByteBuf)null, 0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;getBytes;(int,ByteBuf,int);;Argument[-1];ReturnValue;value;manual" ByteBuf out = null; ByteBuf in = (ByteBuf)source(); out = in.getBytes(0, (ByteBuf)null, 0); sink(out); // $ hasValueFlow } { - // "io.netty.buffer;ByteBuf;true;getBytes;;;Argument[-1];ReturnValue;value;manual" - ByteBuf out = null; - ByteBuf in = (ByteBuf)source(); - out = in.getBytes(0, (ByteBuf)null, 0, 0); - sink(out); // $ hasValueFlow - } - { - // "io.netty.buffer;ByteBuf;true;getBytes;;;Argument[-1];ReturnValue;value;manual" - ByteBuf out = null; - ByteBuf in = (ByteBuf)source(); - out = in.getBytes(0, (ByteBuffer)null); - sink(out); // $ hasValueFlow - } - { - // "io.netty.buffer;ByteBuf;true;getBytes;;;Argument[-1];ReturnValue;value;manual" - ByteBuf out = null; - ByteBuf in = (ByteBuf)source(); - out = in.getBytes(0, (OutputStream)null, 0); - sink(out); // $ hasValueFlow - } - { - // "io.netty.buffer;ByteBuf;true;getBytes;;;Argument[-1];ReturnValue;value;manual" - ByteBuf out = null; - ByteBuf in = (ByteBuf)source(); - out = in.getBytes(0, (byte[])null); - sink(out); // $ hasValueFlow - } - { - // "io.netty.buffer;ByteBuf;true;getBytes;;;Argument[-1];ReturnValue;value;manual" - ByteBuf out = null; - ByteBuf in = (ByteBuf)source(); - out = in.getBytes(0, (byte[])null, 0, 0); - sink(out); // $ hasValueFlow - } - { - // "io.netty.buffer;ByteBuf;true;getBytes;;;Argument[-1];ReturnValue;value;manual" - ByteBuf out = null; - SwappedByteBuf in = (SwappedByteBuf)source(); - out = in.getBytes(0, (ByteBuf)null); - sink(out); // $ hasValueFlow - } - { - // "io.netty.buffer;ByteBuf;true;getBytes;;;Argument[-1];ReturnValue;value;manual" + // "io.netty.buffer;ByteBuf;true;getBytes;(int,ByteBuf,int);;Argument[-1];ReturnValue;value;manual" ByteBuf out = null; SwappedByteBuf in = (SwappedByteBuf)source(); out = in.getBytes(0, (ByteBuf)null, 0); sink(out); // $ hasValueFlow } { - // "io.netty.buffer;ByteBuf;true;getBytes;;;Argument[-1];ReturnValue;value;manual" - ByteBuf out = null; - SwappedByteBuf in = (SwappedByteBuf)source(); - out = in.getBytes(0, (ByteBuf)null, 0, 0); - sink(out); // $ hasValueFlow - } - { - // "io.netty.buffer;ByteBuf;true;getBytes;;;Argument[-1];ReturnValue;value;manual" - ByteBuf out = null; - SwappedByteBuf in = (SwappedByteBuf)source(); - out = in.getBytes(0, (ByteBuffer)null); - sink(out); // $ hasValueFlow - } - { - // "io.netty.buffer;ByteBuf;true;getBytes;;;Argument[-1];ReturnValue;value;manual" - ByteBuf out = null; - SwappedByteBuf in = (SwappedByteBuf)source(); - out = in.getBytes(0, (OutputStream)null, 0); - sink(out); // $ hasValueFlow - } - { - // "io.netty.buffer;ByteBuf;true;getBytes;;;Argument[-1];ReturnValue;value;manual" - ByteBuf out = null; - SwappedByteBuf in = (SwappedByteBuf)source(); - out = in.getBytes(0, (byte[])null); - sink(out); // $ hasValueFlow - } - { - // "io.netty.buffer;ByteBuf;true;getBytes;;;Argument[-1];ReturnValue;value;manual" - ByteBuf out = null; - SwappedByteBuf in = (SwappedByteBuf)source(); - out = in.getBytes(0, (byte[])null, 0, 0); - sink(out); // $ hasValueFlow - } - { - // "io.netty.buffer;ByteBuf;true;getBytes;;;Argument[-1];ReturnValue;value;manual" - CompositeByteBuf out = null; - CompositeByteBuf in = (CompositeByteBuf)source(); - out = in.getBytes(0, (ByteBuf)null); - sink(out); // $ hasValueFlow - } - { - // "io.netty.buffer;ByteBuf;true;getBytes;;;Argument[-1];ReturnValue;value;manual" + // "io.netty.buffer;ByteBuf;true;getBytes;(int,ByteBuf,int);;Argument[-1];ReturnValue;value;manual" CompositeByteBuf out = null; CompositeByteBuf in = (CompositeByteBuf)source(); out = in.getBytes(0, (ByteBuf)null, 0); sink(out); // $ hasValueFlow } { - // "io.netty.buffer;ByteBuf;true;getBytes;;;Argument[-1];ReturnValue;value;manual" + // "io.netty.buffer;ByteBuf;true;getBytes;(int,ByteBuf,int,int);;Argument[-1];Argument[1];taint;manual" + ByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + in.getBytes(0, out, 0, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;getBytes;(int,ByteBuf,int,int);;Argument[-1];Argument[1];taint;manual" + ByteBuf out = null; + CompositeByteBuf in = (CompositeByteBuf)source(); + in.getBytes(0, out, 0, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;getBytes;(int,ByteBuf,int,int);;Argument[-1];Argument[1];taint;manual" + ByteBuf out = null; + SwappedByteBuf in = (SwappedByteBuf)source(); + in.getBytes(0, out, 0, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;getBytes;(int,ByteBuf,int,int);;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out = in.getBytes(0, (ByteBuf)null, 0, 0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;getBytes;(int,ByteBuf,int,int);;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + SwappedByteBuf in = (SwappedByteBuf)source(); + out = in.getBytes(0, (ByteBuf)null, 0, 0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;getBytes;(int,ByteBuf,int,int);;Argument[-1];ReturnValue;value;manual" CompositeByteBuf out = null; CompositeByteBuf in = (CompositeByteBuf)source(); out = in.getBytes(0, (ByteBuf)null, 0, 0); sink(out); // $ hasValueFlow } { - // "io.netty.buffer;ByteBuf;true;getBytes;;;Argument[-1];ReturnValue;value;manual" + // "io.netty.buffer;ByteBuf;true;getBytes;(int,ByteBuffer);;Argument[-1];Argument[1];taint;manual" + ByteBuffer out = null; + ByteBuf in = (ByteBuf)source(); + in.getBytes(0, out); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;getBytes;(int,ByteBuffer);;Argument[-1];Argument[1];taint;manual" + ByteBuffer out = null; + CompositeByteBuf in = (CompositeByteBuf)source(); + in.getBytes(0, out); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;getBytes;(int,ByteBuffer);;Argument[-1];Argument[1];taint;manual" + ByteBuffer out = null; + SwappedByteBuf in = (SwappedByteBuf)source(); + in.getBytes(0, out); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;getBytes;(int,ByteBuffer);;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out = in.getBytes(0, (ByteBuffer)null); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;getBytes;(int,ByteBuffer);;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + SwappedByteBuf in = (SwappedByteBuf)source(); + out = in.getBytes(0, (ByteBuffer)null); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;getBytes;(int,ByteBuffer);;Argument[-1];ReturnValue;value;manual" CompositeByteBuf out = null; CompositeByteBuf in = (CompositeByteBuf)source(); out = in.getBytes(0, (ByteBuffer)null); sink(out); // $ hasValueFlow } { - // "io.netty.buffer;ByteBuf;true;getBytes;;;Argument[-1];ReturnValue;value;manual" + // "io.netty.buffer;ByteBuf;true;getBytes;(int,FileChannel,long,int);;Argument[-1];Argument[1];taint;manual" + FileChannel out = null; + ByteBuf in = (ByteBuf)source(); + in.getBytes(0, out, 0L, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;getBytes;(int,FileChannel,long,int);;Argument[-1];Argument[1];taint;manual" + FileChannel out = null; + CompositeByteBuf in = (CompositeByteBuf)source(); + in.getBytes(0, out, 0L, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;getBytes;(int,FileChannel,long,int);;Argument[-1];Argument[1];taint;manual" + FileChannel out = null; + SwappedByteBuf in = (SwappedByteBuf)source(); + in.getBytes(0, out, 0L, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;getBytes;(int,GatheringByteChannel,int);;Argument[-1];Argument[1];taint;manual" + GatheringByteChannel out = null; + ByteBuf in = (ByteBuf)source(); + in.getBytes(0, out, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;getBytes;(int,GatheringByteChannel,int);;Argument[-1];Argument[1];taint;manual" + GatheringByteChannel out = null; + CompositeByteBuf in = (CompositeByteBuf)source(); + in.getBytes(0, out, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;getBytes;(int,GatheringByteChannel,int);;Argument[-1];Argument[1];taint;manual" + GatheringByteChannel out = null; + SwappedByteBuf in = (SwappedByteBuf)source(); + in.getBytes(0, out, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;getBytes;(int,OutputStream,int);;Argument[-1];Argument[1];taint;manual" + OutputStream out = null; + ByteBuf in = (ByteBuf)source(); + in.getBytes(0, out, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;getBytes;(int,OutputStream,int);;Argument[-1];Argument[1];taint;manual" + OutputStream out = null; + CompositeByteBuf in = (CompositeByteBuf)source(); + in.getBytes(0, out, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;getBytes;(int,OutputStream,int);;Argument[-1];Argument[1];taint;manual" + OutputStream out = null; + SwappedByteBuf in = (SwappedByteBuf)source(); + in.getBytes(0, out, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;getBytes;(int,OutputStream,int);;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out = in.getBytes(0, (OutputStream)null, 0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;getBytes;(int,OutputStream,int);;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + SwappedByteBuf in = (SwappedByteBuf)source(); + out = in.getBytes(0, (OutputStream)null, 0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;getBytes;(int,OutputStream,int);;Argument[-1];ReturnValue;value;manual" CompositeByteBuf out = null; CompositeByteBuf in = (CompositeByteBuf)source(); out = in.getBytes(0, (OutputStream)null, 0); sink(out); // $ hasValueFlow } { - // "io.netty.buffer;ByteBuf;true;getBytes;;;Argument[-1];ReturnValue;value;manual" - CompositeByteBuf out = null; - CompositeByteBuf in = (CompositeByteBuf)source(); - out = in.getBytes(0, (byte[])null); - sink(out); // $ hasValueFlow - } - { - // "io.netty.buffer;ByteBuf;true;getBytes;;;Argument[-1];ReturnValue;value;manual" - CompositeByteBuf out = null; - CompositeByteBuf in = (CompositeByteBuf)source(); - out = in.getBytes(0, (byte[])null, 0, 0); - sink(out); // $ hasValueFlow - } - { - // "io.netty.buffer;ByteBuf;true;getBytes;;;Argument[-1];ReturnValue;value;manual" - int out = null; - ByteBuf in = (ByteBuf)source(); - out = in.getBytes(0, (FileChannel)null, 0L, 0); - sink(out); // $ hasValueFlow - } - { - // "io.netty.buffer;ByteBuf;true;getBytes;;;Argument[-1];ReturnValue;value;manual" - int out = null; - ByteBuf in = (ByteBuf)source(); - out = in.getBytes(0, (GatheringByteChannel)null, 0); - sink(out); // $ hasValueFlow - } - { - // "io.netty.buffer;ByteBuf;true;getBytes;;;Argument[-1];ReturnValue;value;manual" - int out = null; - CompositeByteBuf in = (CompositeByteBuf)source(); - out = in.getBytes(0, (FileChannel)null, 0L, 0); - sink(out); // $ hasValueFlow - } - { - // "io.netty.buffer;ByteBuf;true;getBytes;;;Argument[-1];ReturnValue;value;manual" - int out = null; - CompositeByteBuf in = (CompositeByteBuf)source(); - out = in.getBytes(0, (GatheringByteChannel)null, 0); - sink(out); // $ hasValueFlow - } - { - // "io.netty.buffer;ByteBuf;true;getBytes;;;Argument[-1];ReturnValue;value;manual" - int out = null; - SwappedByteBuf in = (SwappedByteBuf)source(); - out = in.getBytes(0, (FileChannel)null, 0L, 0); - sink(out); // $ hasValueFlow - } - { - // "io.netty.buffer;ByteBuf;true;getBytes;;;Argument[-1];ReturnValue;value;manual" - int out = null; - SwappedByteBuf in = (SwappedByteBuf)source(); - out = in.getBytes(0, (GatheringByteChannel)null, 0); - sink(out); // $ hasValueFlow - } - { - // "io.netty.buffer;ByteBuf;true;getChar;;;Argument[-1];ReturnValue;taint;manual" - char out = null; + // "io.netty.buffer;ByteBuf;true;getBytes;(int,byte[]);;Argument[-1];Argument[1];taint;manual" + byte[] out = null; AbstractByteBuf in = (AbstractByteBuf)source(); - out = in.getChar(0); + in.getBytes(0, out); sink(out); // $ hasTaintFlow } { - // "io.netty.buffer;ByteBuf;true;getChar;;;Argument[-1];ReturnValue;taint;manual" - char out = null; + // "io.netty.buffer;ByteBuf;true;getBytes;(int,byte[]);;Argument[-1];Argument[1];taint;manual" + byte[] out = null; ByteBuf in = (ByteBuf)source(); - out = in.getChar(0); + in.getBytes(0, out); sink(out); // $ hasTaintFlow } { - // "io.netty.buffer;ByteBuf;true;getChar;;;Argument[-1];ReturnValue;taint;manual" - char out = null; - SwappedByteBuf in = (SwappedByteBuf)source(); - out = in.getChar(0); + // "io.netty.buffer;ByteBuf;true;getBytes;(int,byte[]);;Argument[-1];Argument[1];taint;manual" + byte[] out = null; + CompositeByteBuf in = (CompositeByteBuf)source(); + in.getBytes(0, out); sink(out); // $ hasTaintFlow } + { + // "io.netty.buffer;ByteBuf;true;getBytes;(int,byte[]);;Argument[-1];Argument[1];taint;manual" + byte[] out = null; + SwappedByteBuf in = (SwappedByteBuf)source(); + in.getBytes(0, out); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;getBytes;(int,byte[]);;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + AbstractByteBuf in = (AbstractByteBuf)source(); + out = in.getBytes(0, (byte[])null); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;getBytes;(int,byte[]);;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out = in.getBytes(0, (byte[])null); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;getBytes;(int,byte[]);;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + SwappedByteBuf in = (SwappedByteBuf)source(); + out = in.getBytes(0, (byte[])null); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;getBytes;(int,byte[]);;Argument[-1];ReturnValue;value;manual" + CompositeByteBuf out = null; + CompositeByteBuf in = (CompositeByteBuf)source(); + out = in.getBytes(0, (byte[])null); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;getBytes;(int,byte[],int,int);;Argument[-1];Argument[1];taint;manual" + byte[] out = null; + ByteBuf in = (ByteBuf)source(); + in.getBytes(0, out, 0, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;getBytes;(int,byte[],int,int);;Argument[-1];Argument[1];taint;manual" + byte[] out = null; + CompositeByteBuf in = (CompositeByteBuf)source(); + in.getBytes(0, out, 0, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;getBytes;(int,byte[],int,int);;Argument[-1];Argument[1];taint;manual" + byte[] out = null; + SwappedByteBuf in = (SwappedByteBuf)source(); + in.getBytes(0, out, 0, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;getBytes;(int,byte[],int,int);;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out = in.getBytes(0, (byte[])null, 0, 0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;getBytes;(int,byte[],int,int);;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + SwappedByteBuf in = (SwappedByteBuf)source(); + out = in.getBytes(0, (byte[])null, 0, 0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;getBytes;(int,byte[],int,int);;Argument[-1];ReturnValue;value;manual" + CompositeByteBuf out = null; + CompositeByteBuf in = (CompositeByteBuf)source(); + out = in.getBytes(0, (byte[])null, 0, 0); + sink(out); // $ hasValueFlow + } { // "io.netty.buffer;ByteBuf;true;getCharSequence;;;Argument[-1];ReturnValue;taint;manual" CharSequence out = null; @@ -790,56 +677,56 @@ public class Test { sink(out); // $ hasTaintFlow } { - // "io.netty.buffer;ByteBuf;true;markReaderIndex;;;Argument[-1];ReturnValue;value;manual" + // "io.netty.buffer;ByteBuf;true;markReaderIndex;();;Argument[-1];ReturnValue;value;manual" ByteBuf out = null; AbstractByteBuf in = (AbstractByteBuf)source(); out = in.markReaderIndex(); sink(out); // $ hasValueFlow } { - // "io.netty.buffer;ByteBuf;true;markReaderIndex;;;Argument[-1];ReturnValue;value;manual" + // "io.netty.buffer;ByteBuf;true;markReaderIndex;();;Argument[-1];ReturnValue;value;manual" ByteBuf out = null; ByteBuf in = (ByteBuf)source(); out = in.markReaderIndex(); sink(out); // $ hasValueFlow } { - // "io.netty.buffer;ByteBuf;true;markReaderIndex;;;Argument[-1];ReturnValue;value;manual" + // "io.netty.buffer;ByteBuf;true;markReaderIndex;();;Argument[-1];ReturnValue;value;manual" ByteBuf out = null; SwappedByteBuf in = (SwappedByteBuf)source(); out = in.markReaderIndex(); sink(out); // $ hasValueFlow } { - // "io.netty.buffer;ByteBuf;true;markReaderIndex;;;Argument[-1];ReturnValue;value;manual" + // "io.netty.buffer;ByteBuf;true;markReaderIndex;();;Argument[-1];ReturnValue;value;manual" CompositeByteBuf out = null; CompositeByteBuf in = (CompositeByteBuf)source(); out = in.markReaderIndex(); sink(out); // $ hasValueFlow } { - // "io.netty.buffer;ByteBuf;true;markWriterIndex;;;Argument[-1];ReturnValue;value;manual" + // "io.netty.buffer;ByteBuf;true;markWriterIndex;();;Argument[-1];ReturnValue;value;manual" ByteBuf out = null; AbstractByteBuf in = (AbstractByteBuf)source(); out = in.markWriterIndex(); sink(out); // $ hasValueFlow } { - // "io.netty.buffer;ByteBuf;true;markWriterIndex;;;Argument[-1];ReturnValue;value;manual" + // "io.netty.buffer;ByteBuf;true;markWriterIndex;();;Argument[-1];ReturnValue;value;manual" ByteBuf out = null; ByteBuf in = (ByteBuf)source(); out = in.markWriterIndex(); sink(out); // $ hasValueFlow } { - // "io.netty.buffer;ByteBuf;true;markWriterIndex;;;Argument[-1];ReturnValue;value;manual" + // "io.netty.buffer;ByteBuf;true;markWriterIndex;();;Argument[-1];ReturnValue;value;manual" ByteBuf out = null; SwappedByteBuf in = (SwappedByteBuf)source(); out = in.markWriterIndex(); sink(out); // $ hasValueFlow } { - // "io.netty.buffer;ByteBuf;true;markWriterIndex;;;Argument[-1];ReturnValue;value;manual" + // "io.netty.buffer;ByteBuf;true;markWriterIndex;();;Argument[-1];ReturnValue;value;manual" CompositeByteBuf out = null; CompositeByteBuf in = (CompositeByteBuf)source(); out = in.markWriterIndex(); @@ -937,605 +824,451 @@ public class Test { sink(out); // $ hasTaintFlow } { - // "io.netty.buffer;ByteBuf;true;order;;;Argument[-1];ReturnValue;taint;manual" + // "io.netty.buffer;ByteBuf;true;order;(ByteOrder);;Argument[-1];ReturnValue;taint;manual" ByteBuf out = null; AbstractByteBuf in = (AbstractByteBuf)source(); out = in.order(null); sink(out); // $ hasTaintFlow } { - // "io.netty.buffer;ByteBuf;true;order;;;Argument[-1];ReturnValue;taint;manual" + // "io.netty.buffer;ByteBuf;true;order;(ByteOrder);;Argument[-1];ReturnValue;taint;manual" ByteBuf out = null; ByteBuf in = (ByteBuf)source(); out = in.order(null); sink(out); // $ hasTaintFlow } { - // "io.netty.buffer;ByteBuf;true;order;;;Argument[-1];ReturnValue;taint;manual" + // "io.netty.buffer;ByteBuf;true;order;(ByteOrder);;Argument[-1];ReturnValue;taint;manual" ByteBuf out = null; SwappedByteBuf in = (SwappedByteBuf)source(); out = in.order(null); sink(out); // $ hasTaintFlow } { - // "io.netty.buffer;ByteBuf;true;order;;;Argument[-1];ReturnValue;taint;manual" - ByteOrder out = null; - ByteBuf in = (ByteBuf)source(); - out = in.order(); - sink(out); // $ hasTaintFlow - } - { - // "io.netty.buffer;ByteBuf;true;order;;;Argument[-1];ReturnValue;taint;manual" - ByteOrder out = null; - CompositeByteBuf in = (CompositeByteBuf)source(); - out = in.order(); - sink(out); // $ hasTaintFlow - } - { - // "io.netty.buffer;ByteBuf;true;order;;;Argument[-1];ReturnValue;taint;manual" - ByteOrder out = null; - SwappedByteBuf in = (SwappedByteBuf)source(); - out = in.order(); - sink(out); // $ hasTaintFlow - } - { - // "io.netty.buffer;ByteBuf;true;readByte;;;Argument[-1];ReturnValue;taint;manual" - byte out = null; - AbstractByteBuf in = (AbstractByteBuf)source(); - out = in.readByte(); - sink(out); // $ hasTaintFlow - } - { - // "io.netty.buffer;ByteBuf;true;readByte;;;Argument[-1];ReturnValue;taint;manual" - byte out = null; - ByteBuf in = (ByteBuf)source(); - out = in.readByte(); - sink(out); // $ hasTaintFlow - } - { - // "io.netty.buffer;ByteBuf;true;readByte;;;Argument[-1];ReturnValue;taint;manual" - byte out = null; - SwappedByteBuf in = (SwappedByteBuf)source(); - out = in.readByte(); - sink(out); // $ hasTaintFlow - } - { - // "io.netty.buffer;ByteBuf;true;readBytes;;;Argument[-1];Argument[0];taint;manual" + // "io.netty.buffer;ByteBuf;true;readBytes;(ByteBuf);;Argument[-1];Argument[0];taint;manual" ByteBuf out = null; AbstractByteBuf in = (AbstractByteBuf)source(); in.readBytes(out); sink(out); // $ hasTaintFlow } { - // "io.netty.buffer;ByteBuf;true;readBytes;;;Argument[-1];Argument[0];taint;manual" + // "io.netty.buffer;ByteBuf;true;readBytes;(ByteBuf);;Argument[-1];Argument[0];taint;manual" + ByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + in.readBytes(out); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;readBytes;(ByteBuf);;Argument[-1];Argument[0];taint;manual" + ByteBuf out = null; + CompositeByteBuf in = (CompositeByteBuf)source(); + in.readBytes(out); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;readBytes;(ByteBuf);;Argument[-1];Argument[0];taint;manual" + ByteBuf out = null; + SwappedByteBuf in = (SwappedByteBuf)source(); + in.readBytes(out); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;readBytes;(ByteBuf);;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + AbstractByteBuf in = (AbstractByteBuf)source(); + out = in.readBytes((ByteBuf)null); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;readBytes;(ByteBuf);;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out = in.readBytes((ByteBuf)null); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;readBytes;(ByteBuf);;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + SwappedByteBuf in = (SwappedByteBuf)source(); + out = in.readBytes((ByteBuf)null); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;readBytes;(ByteBuf);;Argument[-1];ReturnValue;value;manual" + CompositeByteBuf out = null; + CompositeByteBuf in = (CompositeByteBuf)source(); + out = in.readBytes((ByteBuf)null); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;readBytes;(ByteBuf,int);;Argument[-1];Argument[0];taint;manual" ByteBuf out = null; AbstractByteBuf in = (AbstractByteBuf)source(); in.readBytes(out, 0); sink(out); // $ hasTaintFlow } { - // "io.netty.buffer;ByteBuf;true;readBytes;;;Argument[-1];Argument[0];taint;manual" + // "io.netty.buffer;ByteBuf;true;readBytes;(ByteBuf,int);;Argument[-1];Argument[0];taint;manual" + ByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + in.readBytes(out, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;readBytes;(ByteBuf,int);;Argument[-1];Argument[0];taint;manual" + ByteBuf out = null; + CompositeByteBuf in = (CompositeByteBuf)source(); + in.readBytes(out, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;readBytes;(ByteBuf,int);;Argument[-1];Argument[0];taint;manual" + ByteBuf out = null; + SwappedByteBuf in = (SwappedByteBuf)source(); + in.readBytes(out, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;readBytes;(ByteBuf,int);;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + AbstractByteBuf in = (AbstractByteBuf)source(); + out = in.readBytes((ByteBuf)null, 0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;readBytes;(ByteBuf,int);;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out = in.readBytes((ByteBuf)null, 0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;readBytes;(ByteBuf,int);;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + SwappedByteBuf in = (SwappedByteBuf)source(); + out = in.readBytes((ByteBuf)null, 0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;readBytes;(ByteBuf,int);;Argument[-1];ReturnValue;value;manual" + CompositeByteBuf out = null; + CompositeByteBuf in = (CompositeByteBuf)source(); + out = in.readBytes((ByteBuf)null, 0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;readBytes;(ByteBuf,int,int);;Argument[-1];Argument[0];taint;manual" ByteBuf out = null; AbstractByteBuf in = (AbstractByteBuf)source(); in.readBytes(out, 0, 0); sink(out); // $ hasTaintFlow } { - // "io.netty.buffer;ByteBuf;true;readBytes;;;Argument[-1];Argument[0];taint;manual" - ByteBuf out = null; - ByteBuf in = (ByteBuf)source(); - in.readBytes(out); - sink(out); // $ hasTaintFlow - } - { - // "io.netty.buffer;ByteBuf;true;readBytes;;;Argument[-1];Argument[0];taint;manual" - ByteBuf out = null; - ByteBuf in = (ByteBuf)source(); - in.readBytes(out, 0); - sink(out); // $ hasTaintFlow - } - { - // "io.netty.buffer;ByteBuf;true;readBytes;;;Argument[-1];Argument[0];taint;manual" + // "io.netty.buffer;ByteBuf;true;readBytes;(ByteBuf,int,int);;Argument[-1];Argument[0];taint;manual" ByteBuf out = null; ByteBuf in = (ByteBuf)source(); in.readBytes(out, 0, 0); sink(out); // $ hasTaintFlow } { - // "io.netty.buffer;ByteBuf;true;readBytes;;;Argument[-1];Argument[0];taint;manual" - ByteBuf out = null; - CompositeByteBuf in = (CompositeByteBuf)source(); - in.readBytes(out); - sink(out); // $ hasTaintFlow - } - { - // "io.netty.buffer;ByteBuf;true;readBytes;;;Argument[-1];Argument[0];taint;manual" - ByteBuf out = null; - CompositeByteBuf in = (CompositeByteBuf)source(); - in.readBytes(out, 0); - sink(out); // $ hasTaintFlow - } - { - // "io.netty.buffer;ByteBuf;true;readBytes;;;Argument[-1];Argument[0];taint;manual" + // "io.netty.buffer;ByteBuf;true;readBytes;(ByteBuf,int,int);;Argument[-1];Argument[0];taint;manual" ByteBuf out = null; CompositeByteBuf in = (CompositeByteBuf)source(); in.readBytes(out, 0, 0); sink(out); // $ hasTaintFlow } { - // "io.netty.buffer;ByteBuf;true;readBytes;;;Argument[-1];Argument[0];taint;manual" - ByteBuf out = null; - SwappedByteBuf in = (SwappedByteBuf)source(); - in.readBytes(out); - sink(out); // $ hasTaintFlow - } - { - // "io.netty.buffer;ByteBuf;true;readBytes;;;Argument[-1];Argument[0];taint;manual" - ByteBuf out = null; - SwappedByteBuf in = (SwappedByteBuf)source(); - in.readBytes(out, 0); - sink(out); // $ hasTaintFlow - } - { - // "io.netty.buffer;ByteBuf;true;readBytes;;;Argument[-1];Argument[0];taint;manual" + // "io.netty.buffer;ByteBuf;true;readBytes;(ByteBuf,int,int);;Argument[-1];Argument[0];taint;manual" ByteBuf out = null; SwappedByteBuf in = (SwappedByteBuf)source(); in.readBytes(out, 0, 0); sink(out); // $ hasTaintFlow } { - // "io.netty.buffer;ByteBuf;true;readBytes;;;Argument[-1];Argument[0];taint;manual" + // "io.netty.buffer;ByteBuf;true;readBytes;(ByteBuf,int,int);;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + AbstractByteBuf in = (AbstractByteBuf)source(); + out = in.readBytes((ByteBuf)null, 0, 0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;readBytes;(ByteBuf,int,int);;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out = in.readBytes((ByteBuf)null, 0, 0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;readBytes;(ByteBuf,int,int);;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + SwappedByteBuf in = (SwappedByteBuf)source(); + out = in.readBytes((ByteBuf)null, 0, 0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;readBytes;(ByteBuf,int,int);;Argument[-1];ReturnValue;value;manual" + CompositeByteBuf out = null; + CompositeByteBuf in = (CompositeByteBuf)source(); + out = in.readBytes((ByteBuf)null, 0, 0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;readBytes;(ByteBuffer);;Argument[-1];Argument[0];taint;manual" ByteBuffer out = null; AbstractByteBuf in = (AbstractByteBuf)source(); in.readBytes(out); sink(out); // $ hasTaintFlow } { - // "io.netty.buffer;ByteBuf;true;readBytes;;;Argument[-1];Argument[0];taint;manual" + // "io.netty.buffer;ByteBuf;true;readBytes;(ByteBuffer);;Argument[-1];Argument[0];taint;manual" ByteBuffer out = null; ByteBuf in = (ByteBuf)source(); in.readBytes(out); sink(out); // $ hasTaintFlow } { - // "io.netty.buffer;ByteBuf;true;readBytes;;;Argument[-1];Argument[0];taint;manual" + // "io.netty.buffer;ByteBuf;true;readBytes;(ByteBuffer);;Argument[-1];Argument[0];taint;manual" ByteBuffer out = null; CompositeByteBuf in = (CompositeByteBuf)source(); in.readBytes(out); sink(out); // $ hasTaintFlow } { - // "io.netty.buffer;ByteBuf;true;readBytes;;;Argument[-1];Argument[0];taint;manual" + // "io.netty.buffer;ByteBuf;true;readBytes;(ByteBuffer);;Argument[-1];Argument[0];taint;manual" ByteBuffer out = null; SwappedByteBuf in = (SwappedByteBuf)source(); in.readBytes(out); sink(out); // $ hasTaintFlow } { - // "io.netty.buffer;ByteBuf;true;readBytes;;;Argument[-1];Argument[0];taint;manual" + // "io.netty.buffer;ByteBuf;true;readBytes;(ByteBuffer);;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + AbstractByteBuf in = (AbstractByteBuf)source(); + out = in.readBytes((ByteBuffer)null); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;readBytes;(ByteBuffer);;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out = in.readBytes((ByteBuffer)null); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;readBytes;(ByteBuffer);;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + SwappedByteBuf in = (SwappedByteBuf)source(); + out = in.readBytes((ByteBuffer)null); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;readBytes;(ByteBuffer);;Argument[-1];ReturnValue;value;manual" + CompositeByteBuf out = null; + CompositeByteBuf in = (CompositeByteBuf)source(); + out = in.readBytes((ByteBuffer)null); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;readBytes;(FileChannel,long,int);;Argument[-1];Argument[0];taint;manual" FileChannel out = null; AbstractByteBuf in = (AbstractByteBuf)source(); in.readBytes(out, 0L, 0); sink(out); // $ hasTaintFlow } { - // "io.netty.buffer;ByteBuf;true;readBytes;;;Argument[-1];Argument[0];taint;manual" + // "io.netty.buffer;ByteBuf;true;readBytes;(FileChannel,long,int);;Argument[-1];Argument[0];taint;manual" FileChannel out = null; ByteBuf in = (ByteBuf)source(); in.readBytes(out, 0L, 0); sink(out); // $ hasTaintFlow } { - // "io.netty.buffer;ByteBuf;true;readBytes;;;Argument[-1];Argument[0];taint;manual" + // "io.netty.buffer;ByteBuf;true;readBytes;(FileChannel,long,int);;Argument[-1];Argument[0];taint;manual" FileChannel out = null; SwappedByteBuf in = (SwappedByteBuf)source(); in.readBytes(out, 0L, 0); sink(out); // $ hasTaintFlow } { - // "io.netty.buffer;ByteBuf;true;readBytes;;;Argument[-1];Argument[0];taint;manual" + // "io.netty.buffer;ByteBuf;true;readBytes;(GatheringByteChannel,int);;Argument[-1];Argument[0];taint;manual" GatheringByteChannel out = null; AbstractByteBuf in = (AbstractByteBuf)source(); in.readBytes(out, 0); sink(out); // $ hasTaintFlow } { - // "io.netty.buffer;ByteBuf;true;readBytes;;;Argument[-1];Argument[0];taint;manual" + // "io.netty.buffer;ByteBuf;true;readBytes;(GatheringByteChannel,int);;Argument[-1];Argument[0];taint;manual" GatheringByteChannel out = null; ByteBuf in = (ByteBuf)source(); in.readBytes(out, 0); sink(out); // $ hasTaintFlow } { - // "io.netty.buffer;ByteBuf;true;readBytes;;;Argument[-1];Argument[0];taint;manual" + // "io.netty.buffer;ByteBuf;true;readBytes;(GatheringByteChannel,int);;Argument[-1];Argument[0];taint;manual" GatheringByteChannel out = null; SwappedByteBuf in = (SwappedByteBuf)source(); in.readBytes(out, 0); sink(out); // $ hasTaintFlow } { - // "io.netty.buffer;ByteBuf;true;readBytes;;;Argument[-1];Argument[0];taint;manual" - OutputStream out = null; - AbstractByteBuf in = (AbstractByteBuf)source(); - in.readBytes(out, 0); - sink(out); // $ hasTaintFlow - } - { - // "io.netty.buffer;ByteBuf;true;readBytes;;;Argument[-1];Argument[0];taint;manual" - OutputStream out = null; - ByteBuf in = (ByteBuf)source(); - in.readBytes(out, 0); - sink(out); // $ hasTaintFlow - } - { - // "io.netty.buffer;ByteBuf;true;readBytes;;;Argument[-1];Argument[0];taint;manual" - OutputStream out = null; - CompositeByteBuf in = (CompositeByteBuf)source(); - in.readBytes(out, 0); - sink(out); // $ hasTaintFlow - } - { - // "io.netty.buffer;ByteBuf;true;readBytes;;;Argument[-1];Argument[0];taint;manual" - OutputStream out = null; - SwappedByteBuf in = (SwappedByteBuf)source(); - in.readBytes(out, 0); - sink(out); // $ hasTaintFlow - } - { - // "io.netty.buffer;ByteBuf;true;readBytes;;;Argument[-1];Argument[0];taint;manual" - byte[] out = null; - AbstractByteBuf in = (AbstractByteBuf)source(); - in.readBytes(out); - sink(out); // $ hasTaintFlow - } - { - // "io.netty.buffer;ByteBuf;true;readBytes;;;Argument[-1];Argument[0];taint;manual" - byte[] out = null; - AbstractByteBuf in = (AbstractByteBuf)source(); - in.readBytes(out, 0, 0); - sink(out); // $ hasTaintFlow - } - { - // "io.netty.buffer;ByteBuf;true;readBytes;;;Argument[-1];Argument[0];taint;manual" - byte[] out = null; - ByteBuf in = (ByteBuf)source(); - in.readBytes(out); - sink(out); // $ hasTaintFlow - } - { - // "io.netty.buffer;ByteBuf;true;readBytes;;;Argument[-1];Argument[0];taint;manual" - byte[] out = null; - ByteBuf in = (ByteBuf)source(); - in.readBytes(out, 0, 0); - sink(out); // $ hasTaintFlow - } - { - // "io.netty.buffer;ByteBuf;true;readBytes;;;Argument[-1];Argument[0];taint;manual" - byte[] out = null; - CompositeByteBuf in = (CompositeByteBuf)source(); - in.readBytes(out); - sink(out); // $ hasTaintFlow - } - { - // "io.netty.buffer;ByteBuf;true;readBytes;;;Argument[-1];Argument[0];taint;manual" - byte[] out = null; - CompositeByteBuf in = (CompositeByteBuf)source(); - in.readBytes(out, 0, 0); - sink(out); // $ hasTaintFlow - } - { - // "io.netty.buffer;ByteBuf;true;readBytes;;;Argument[-1];Argument[0];taint;manual" - byte[] out = null; - SwappedByteBuf in = (SwappedByteBuf)source(); - in.readBytes(out); - sink(out); // $ hasTaintFlow - } - { - // "io.netty.buffer;ByteBuf;true;readBytes;;;Argument[-1];Argument[0];taint;manual" - byte[] out = null; - SwappedByteBuf in = (SwappedByteBuf)source(); - in.readBytes(out, 0, 0); - sink(out); // $ hasTaintFlow - } - { - // "io.netty.buffer;ByteBuf;true;readBytes;;;Argument[-1];Argument[0];taint;manual" - int out = null; - AbstractByteBuf in = (AbstractByteBuf)source(); - in.readBytes(out); - sink(out); // $ hasTaintFlow - } - { - // "io.netty.buffer;ByteBuf;true;readBytes;;;Argument[-1];Argument[0];taint;manual" - int out = null; - ByteBuf in = (ByteBuf)source(); - in.readBytes(out); - sink(out); // $ hasTaintFlow - } - { - // "io.netty.buffer;ByteBuf;true;readBytes;;;Argument[-1];Argument[0];taint;manual" - int out = null; - SwappedByteBuf in = (SwappedByteBuf)source(); - in.readBytes(out); - sink(out); // $ hasTaintFlow - } - { - // "io.netty.buffer;ByteBuf;true;readBytes;;;Argument[-1];ReturnValue;value;manual" - ByteBuf out = null; - AbstractByteBuf in = (AbstractByteBuf)source(); - out = in.readBytes((ByteBuf)null); - sink(out); // $ hasValueFlow - } - { - // "io.netty.buffer;ByteBuf;true;readBytes;;;Argument[-1];ReturnValue;value;manual" - ByteBuf out = null; - AbstractByteBuf in = (AbstractByteBuf)source(); - out = in.readBytes((ByteBuf)null, 0); - sink(out); // $ hasValueFlow - } - { - // "io.netty.buffer;ByteBuf;true;readBytes;;;Argument[-1];ReturnValue;value;manual" - ByteBuf out = null; - AbstractByteBuf in = (AbstractByteBuf)source(); - out = in.readBytes((ByteBuf)null, 0, 0); - sink(out); // $ hasValueFlow - } - { - // "io.netty.buffer;ByteBuf;true;readBytes;;;Argument[-1];ReturnValue;value;manual" - ByteBuf out = null; - AbstractByteBuf in = (AbstractByteBuf)source(); - out = in.readBytes((ByteBuffer)null); - sink(out); // $ hasValueFlow - } - { - // "io.netty.buffer;ByteBuf;true;readBytes;;;Argument[-1];ReturnValue;value;manual" + // "io.netty.buffer;ByteBuf;true;readBytes;(OutputStream,int);;Argument[-1];ReturnValue;value;manual" ByteBuf out = null; AbstractByteBuf in = (AbstractByteBuf)source(); out = in.readBytes((OutputStream)null, 0); sink(out); // $ hasValueFlow } { - // "io.netty.buffer;ByteBuf;true;readBytes;;;Argument[-1];ReturnValue;value;manual" + // "io.netty.buffer;ByteBuf;true;readBytes;(OutputStream,int);;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out = in.readBytes((OutputStream)null, 0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;readBytes;(OutputStream,int);;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + SwappedByteBuf in = (SwappedByteBuf)source(); + out = in.readBytes((OutputStream)null, 0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;readBytes;(OutputStream,int);;Argument[-1];ReturnValue;value;manual" + CompositeByteBuf out = null; + CompositeByteBuf in = (CompositeByteBuf)source(); + out = in.readBytes((OutputStream)null, 0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;readBytes;(byte[]);;Argument[-1];Argument[0];taint;manual" + byte[] out = null; + AbstractByteBuf in = (AbstractByteBuf)source(); + in.readBytes(out); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;readBytes;(byte[]);;Argument[-1];Argument[0];taint;manual" + byte[] out = null; + ByteBuf in = (ByteBuf)source(); + in.readBytes(out); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;readBytes;(byte[]);;Argument[-1];Argument[0];taint;manual" + byte[] out = null; + CompositeByteBuf in = (CompositeByteBuf)source(); + in.readBytes(out); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;readBytes;(byte[]);;Argument[-1];Argument[0];taint;manual" + byte[] out = null; + SwappedByteBuf in = (SwappedByteBuf)source(); + in.readBytes(out); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;readBytes;(byte[]);;Argument[-1];ReturnValue;value;manual" ByteBuf out = null; AbstractByteBuf in = (AbstractByteBuf)source(); out = in.readBytes((byte[])null); sink(out); // $ hasValueFlow } { - // "io.netty.buffer;ByteBuf;true;readBytes;;;Argument[-1];ReturnValue;value;manual" + // "io.netty.buffer;ByteBuf;true;readBytes;(byte[]);;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out = in.readBytes((byte[])null); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;readBytes;(byte[]);;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + SwappedByteBuf in = (SwappedByteBuf)source(); + out = in.readBytes((byte[])null); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;readBytes;(byte[]);;Argument[-1];ReturnValue;value;manual" + CompositeByteBuf out = null; + CompositeByteBuf in = (CompositeByteBuf)source(); + out = in.readBytes((byte[])null); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;readBytes;(byte[],int,int);;Argument[-1];Argument[0];taint;manual" + byte[] out = null; + AbstractByteBuf in = (AbstractByteBuf)source(); + in.readBytes(out, 0, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;readBytes;(byte[],int,int);;Argument[-1];Argument[0];taint;manual" + byte[] out = null; + ByteBuf in = (ByteBuf)source(); + in.readBytes(out, 0, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;readBytes;(byte[],int,int);;Argument[-1];Argument[0];taint;manual" + byte[] out = null; + CompositeByteBuf in = (CompositeByteBuf)source(); + in.readBytes(out, 0, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;readBytes;(byte[],int,int);;Argument[-1];Argument[0];taint;manual" + byte[] out = null; + SwappedByteBuf in = (SwappedByteBuf)source(); + in.readBytes(out, 0, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;readBytes;(byte[],int,int);;Argument[-1];ReturnValue;value;manual" ByteBuf out = null; AbstractByteBuf in = (AbstractByteBuf)source(); out = in.readBytes((byte[])null, 0, 0); sink(out); // $ hasValueFlow } { - // "io.netty.buffer;ByteBuf;true;readBytes;;;Argument[-1];ReturnValue;value;manual" + // "io.netty.buffer;ByteBuf;true;readBytes;(byte[],int,int);;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out = in.readBytes((byte[])null, 0, 0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;readBytes;(byte[],int,int);;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + SwappedByteBuf in = (SwappedByteBuf)source(); + out = in.readBytes((byte[])null, 0, 0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;readBytes;(byte[],int,int);;Argument[-1];ReturnValue;value;manual" + CompositeByteBuf out = null; + CompositeByteBuf in = (CompositeByteBuf)source(); + out = in.readBytes((byte[])null, 0, 0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;readBytes;(int);;Argument[-1];ReturnValue;taint;manual" ByteBuf out = null; AbstractByteBuf in = (AbstractByteBuf)source(); out = in.readBytes(0); - sink(out); // $ hasValueFlow - } - { - // "io.netty.buffer;ByteBuf;true;readBytes;;;Argument[-1];ReturnValue;value;manual" - ByteBuf out = null; - ByteBuf in = (ByteBuf)source(); - out = in.readBytes((ByteBuf)null); - sink(out); // $ hasValueFlow - } - { - // "io.netty.buffer;ByteBuf;true;readBytes;;;Argument[-1];ReturnValue;value;manual" - ByteBuf out = null; - ByteBuf in = (ByteBuf)source(); - out = in.readBytes((ByteBuf)null, 0); - sink(out); // $ hasValueFlow - } - { - // "io.netty.buffer;ByteBuf;true;readBytes;;;Argument[-1];ReturnValue;value;manual" - ByteBuf out = null; - ByteBuf in = (ByteBuf)source(); - out = in.readBytes((ByteBuf)null, 0, 0); - sink(out); // $ hasValueFlow - } - { - // "io.netty.buffer;ByteBuf;true;readBytes;;;Argument[-1];ReturnValue;value;manual" - ByteBuf out = null; - ByteBuf in = (ByteBuf)source(); - out = in.readBytes((ByteBuffer)null); - sink(out); // $ hasValueFlow - } - { - // "io.netty.buffer;ByteBuf;true;readBytes;;;Argument[-1];ReturnValue;value;manual" - ByteBuf out = null; - ByteBuf in = (ByteBuf)source(); - out = in.readBytes((OutputStream)null, 0); - sink(out); // $ hasValueFlow - } - { - // "io.netty.buffer;ByteBuf;true;readBytes;;;Argument[-1];ReturnValue;value;manual" - ByteBuf out = null; - ByteBuf in = (ByteBuf)source(); - out = in.readBytes((byte[])null); - sink(out); // $ hasValueFlow - } - { - // "io.netty.buffer;ByteBuf;true;readBytes;;;Argument[-1];ReturnValue;value;manual" - ByteBuf out = null; - ByteBuf in = (ByteBuf)source(); - out = in.readBytes((byte[])null, 0, 0); - sink(out); // $ hasValueFlow - } - { - // "io.netty.buffer;ByteBuf;true;readBytes;;;Argument[-1];ReturnValue;value;manual" - ByteBuf out = null; - ByteBuf in = (ByteBuf)source(); - out = in.readBytes(0); - sink(out); // $ hasValueFlow - } - { - // "io.netty.buffer;ByteBuf;true;readBytes;;;Argument[-1];ReturnValue;value;manual" - ByteBuf out = null; - SwappedByteBuf in = (SwappedByteBuf)source(); - out = in.readBytes((ByteBuf)null); - sink(out); // $ hasValueFlow - } - { - // "io.netty.buffer;ByteBuf;true;readBytes;;;Argument[-1];ReturnValue;value;manual" - ByteBuf out = null; - SwappedByteBuf in = (SwappedByteBuf)source(); - out = in.readBytes((ByteBuf)null, 0); - sink(out); // $ hasValueFlow - } - { - // "io.netty.buffer;ByteBuf;true;readBytes;;;Argument[-1];ReturnValue;value;manual" - ByteBuf out = null; - SwappedByteBuf in = (SwappedByteBuf)source(); - out = in.readBytes((ByteBuf)null, 0, 0); - sink(out); // $ hasValueFlow - } - { - // "io.netty.buffer;ByteBuf;true;readBytes;;;Argument[-1];ReturnValue;value;manual" - ByteBuf out = null; - SwappedByteBuf in = (SwappedByteBuf)source(); - out = in.readBytes((ByteBuffer)null); - sink(out); // $ hasValueFlow - } - { - // "io.netty.buffer;ByteBuf;true;readBytes;;;Argument[-1];ReturnValue;value;manual" - ByteBuf out = null; - SwappedByteBuf in = (SwappedByteBuf)source(); - out = in.readBytes((OutputStream)null, 0); - sink(out); // $ hasValueFlow - } - { - // "io.netty.buffer;ByteBuf;true;readBytes;;;Argument[-1];ReturnValue;value;manual" - ByteBuf out = null; - SwappedByteBuf in = (SwappedByteBuf)source(); - out = in.readBytes((byte[])null); - sink(out); // $ hasValueFlow - } - { - // "io.netty.buffer;ByteBuf;true;readBytes;;;Argument[-1];ReturnValue;value;manual" - ByteBuf out = null; - SwappedByteBuf in = (SwappedByteBuf)source(); - out = in.readBytes((byte[])null, 0, 0); - sink(out); // $ hasValueFlow - } - { - // "io.netty.buffer;ByteBuf;true;readBytes;;;Argument[-1];ReturnValue;value;manual" - ByteBuf out = null; - SwappedByteBuf in = (SwappedByteBuf)source(); - out = in.readBytes(0); - sink(out); // $ hasValueFlow - } - { - // "io.netty.buffer;ByteBuf;true;readBytes;;;Argument[-1];ReturnValue;value;manual" - CompositeByteBuf out = null; - CompositeByteBuf in = (CompositeByteBuf)source(); - out = in.readBytes((ByteBuf)null); - sink(out); // $ hasValueFlow - } - { - // "io.netty.buffer;ByteBuf;true;readBytes;;;Argument[-1];ReturnValue;value;manual" - CompositeByteBuf out = null; - CompositeByteBuf in = (CompositeByteBuf)source(); - out = in.readBytes((ByteBuf)null, 0); - sink(out); // $ hasValueFlow - } - { - // "io.netty.buffer;ByteBuf;true;readBytes;;;Argument[-1];ReturnValue;value;manual" - CompositeByteBuf out = null; - CompositeByteBuf in = (CompositeByteBuf)source(); - out = in.readBytes((ByteBuf)null, 0, 0); - sink(out); // $ hasValueFlow - } - { - // "io.netty.buffer;ByteBuf;true;readBytes;;;Argument[-1];ReturnValue;value;manual" - CompositeByteBuf out = null; - CompositeByteBuf in = (CompositeByteBuf)source(); - out = in.readBytes((ByteBuffer)null); - sink(out); // $ hasValueFlow - } - { - // "io.netty.buffer;ByteBuf;true;readBytes;;;Argument[-1];ReturnValue;value;manual" - CompositeByteBuf out = null; - CompositeByteBuf in = (CompositeByteBuf)source(); - out = in.readBytes((OutputStream)null, 0); - sink(out); // $ hasValueFlow - } - { - // "io.netty.buffer;ByteBuf;true;readBytes;;;Argument[-1];ReturnValue;value;manual" - CompositeByteBuf out = null; - CompositeByteBuf in = (CompositeByteBuf)source(); - out = in.readBytes((byte[])null); - sink(out); // $ hasValueFlow - } - { - // "io.netty.buffer;ByteBuf;true;readBytes;;;Argument[-1];ReturnValue;value;manual" - CompositeByteBuf out = null; - CompositeByteBuf in = (CompositeByteBuf)source(); - out = in.readBytes((byte[])null, 0, 0); - sink(out); // $ hasValueFlow - } - { - // "io.netty.buffer;ByteBuf;true;readBytes;;;Argument[-1];ReturnValue;value;manual" - int out = null; - AbstractByteBuf in = (AbstractByteBuf)source(); - out = in.readBytes((FileChannel)null, 0L, 0); - sink(out); // $ hasValueFlow - } - { - // "io.netty.buffer;ByteBuf;true;readBytes;;;Argument[-1];ReturnValue;value;manual" - int out = null; - AbstractByteBuf in = (AbstractByteBuf)source(); - out = in.readBytes((GatheringByteChannel)null, 0); - sink(out); // $ hasValueFlow - } - { - // "io.netty.buffer;ByteBuf;true;readBytes;;;Argument[-1];ReturnValue;value;manual" - int out = null; - ByteBuf in = (ByteBuf)source(); - out = in.readBytes((FileChannel)null, 0L, 0); - sink(out); // $ hasValueFlow - } - { - // "io.netty.buffer;ByteBuf;true;readBytes;;;Argument[-1];ReturnValue;value;manual" - int out = null; - ByteBuf in = (ByteBuf)source(); - out = in.readBytes((GatheringByteChannel)null, 0); - sink(out); // $ hasValueFlow - } - { - // "io.netty.buffer;ByteBuf;true;readBytes;;;Argument[-1];ReturnValue;value;manual" - int out = null; - SwappedByteBuf in = (SwappedByteBuf)source(); - out = in.readBytes((FileChannel)null, 0L, 0); - sink(out); // $ hasValueFlow - } - { - // "io.netty.buffer;ByteBuf;true;readBytes;;;Argument[-1];ReturnValue;value;manual" - int out = null; - SwappedByteBuf in = (SwappedByteBuf)source(); - out = in.readBytes((GatheringByteChannel)null, 0); - sink(out); // $ hasValueFlow - } - { - // "io.netty.buffer;ByteBuf;true;readChar;;;Argument[-1];ReturnValue;taint;manual" - char out = null; - AbstractByteBuf in = (AbstractByteBuf)source(); - out = in.readChar(); sink(out); // $ hasTaintFlow } { - // "io.netty.buffer;ByteBuf;true;readChar;;;Argument[-1];ReturnValue;taint;manual" - char out = null; + // "io.netty.buffer;ByteBuf;true;readBytes;(int);;Argument[-1];ReturnValue;taint;manual" + ByteBuf out = null; ByteBuf in = (ByteBuf)source(); - out = in.readChar(); + out = in.readBytes(0); sink(out); // $ hasTaintFlow } { - // "io.netty.buffer;ByteBuf;true;readChar;;;Argument[-1];ReturnValue;taint;manual" - char out = null; + // "io.netty.buffer;ByteBuf;true;readBytes;(int);;Argument[-1];ReturnValue;taint;manual" + ByteBuf out = null; SwappedByteBuf in = (SwappedByteBuf)source(); - out = in.readChar(); + out = in.readBytes(0); sink(out); // $ hasTaintFlow } { @@ -1784,448 +1517,357 @@ public class Test { sink(out); // $ hasValueFlow } { - // "io.netty.buffer;ByteBuf;true;setByte;;;Argument[1];Argument[-1];taint;manual" - AbstractByteBuf out = null; - int in = (int)source(); - out.setByte(0, in); - sink(out); // $ hasTaintFlow - } - { - // "io.netty.buffer;ByteBuf;true;setByte;;;Argument[1];Argument[-1];taint;manual" - ByteBuf out = null; - int in = (int)source(); - out.setByte(0, in); - sink(out); // $ hasTaintFlow - } - { - // "io.netty.buffer;ByteBuf;true;setByte;;;Argument[1];Argument[-1];taint;manual" - CompositeByteBuf out = null; - int in = (int)source(); - out.setByte(0, in); - sink(out); // $ hasTaintFlow - } - { - // "io.netty.buffer;ByteBuf;true;setByte;;;Argument[1];Argument[-1];taint;manual" - SwappedByteBuf out = null; - int in = (int)source(); - out.setByte(0, in); - sink(out); // $ hasTaintFlow - } - { - // "io.netty.buffer;ByteBuf;true;setBytes;;;Argument[-1];ReturnValue;value;manual" + // "io.netty.buffer;ByteBuf;true;setBytes;(int,ByteBuf);;Argument[-1];ReturnValue;value;manual" ByteBuf out = null; AbstractByteBuf in = (AbstractByteBuf)source(); out = in.setBytes(0, (ByteBuf)null); sink(out); // $ hasValueFlow } { - // "io.netty.buffer;ByteBuf;true;setBytes;;;Argument[-1];ReturnValue;value;manual" - ByteBuf out = null; - AbstractByteBuf in = (AbstractByteBuf)source(); - out = in.setBytes(0, (byte[])null); - sink(out); // $ hasValueFlow - } - { - // "io.netty.buffer;ByteBuf;true;setBytes;;;Argument[-1];ReturnValue;value;manual" - ByteBuf out = null; - AbstractByteBuf in = (AbstractByteBuf)source(); - out = in.setBytes(0, null, 0); - sink(out); // $ hasValueFlow - } - { - // "io.netty.buffer;ByteBuf;true;setBytes;;;Argument[-1];ReturnValue;value;manual" + // "io.netty.buffer;ByteBuf;true;setBytes;(int,ByteBuf);;Argument[-1];ReturnValue;value;manual" ByteBuf out = null; ByteBuf in = (ByteBuf)source(); out = in.setBytes(0, (ByteBuf)null); sink(out); // $ hasValueFlow } { - // "io.netty.buffer;ByteBuf;true;setBytes;;;Argument[-1];ReturnValue;value;manual" + // "io.netty.buffer;ByteBuf;true;setBytes;(int,ByteBuf);;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + SwappedByteBuf in = (SwappedByteBuf)source(); + out = in.setBytes(0, (ByteBuf)null); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;setBytes;(int,ByteBuf);;Argument[-1];ReturnValue;value;manual" + CompositeByteBuf out = null; + CompositeByteBuf in = (CompositeByteBuf)source(); + out = in.setBytes(0, (ByteBuf)null); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;setBytes;(int,ByteBuf);;Argument[1];Argument[-1];taint;manual" + AbstractByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out.setBytes(0, in); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;setBytes;(int,ByteBuf);;Argument[1];Argument[-1];taint;manual" + ByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out.setBytes(0, in); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;setBytes;(int,ByteBuf);;Argument[1];Argument[-1];taint;manual" + CompositeByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out.setBytes(0, in); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;setBytes;(int,ByteBuf);;Argument[1];Argument[-1];taint;manual" + SwappedByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out.setBytes(0, in); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;setBytes;(int,ByteBuf,int);;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + AbstractByteBuf in = (AbstractByteBuf)source(); + out = in.setBytes(0, (ByteBuf)null, 0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;setBytes;(int,ByteBuf,int);;Argument[-1];ReturnValue;value;manual" ByteBuf out = null; ByteBuf in = (ByteBuf)source(); out = in.setBytes(0, (ByteBuf)null, 0); sink(out); // $ hasValueFlow } { - // "io.netty.buffer;ByteBuf;true;setBytes;;;Argument[-1];ReturnValue;value;manual" - ByteBuf out = null; - ByteBuf in = (ByteBuf)source(); - out = in.setBytes(0, (ByteBuf)null, 0, 0); - sink(out); // $ hasValueFlow - } - { - // "io.netty.buffer;ByteBuf;true;setBytes;;;Argument[-1];ReturnValue;value;manual" - ByteBuf out = null; - ByteBuf in = (ByteBuf)source(); - out = in.setBytes(0, (ByteBuffer)null); - sink(out); // $ hasValueFlow - } - { - // "io.netty.buffer;ByteBuf;true;setBytes;;;Argument[-1];ReturnValue;value;manual" - ByteBuf out = null; - ByteBuf in = (ByteBuf)source(); - out = in.setBytes(0, (byte[])null); - sink(out); // $ hasValueFlow - } - { - // "io.netty.buffer;ByteBuf;true;setBytes;;;Argument[-1];ReturnValue;value;manual" - ByteBuf out = null; - ByteBuf in = (ByteBuf)source(); - out = in.setBytes(0, (byte[])null, 0, 0); - sink(out); // $ hasValueFlow - } - { - // "io.netty.buffer;ByteBuf;true;setBytes;;;Argument[-1];ReturnValue;value;manual" - ByteBuf out = null; - SwappedByteBuf in = (SwappedByteBuf)source(); - out = in.setBytes(0, (ByteBuf)null); - sink(out); // $ hasValueFlow - } - { - // "io.netty.buffer;ByteBuf;true;setBytes;;;Argument[-1];ReturnValue;value;manual" + // "io.netty.buffer;ByteBuf;true;setBytes;(int,ByteBuf,int);;Argument[-1];ReturnValue;value;manual" ByteBuf out = null; SwappedByteBuf in = (SwappedByteBuf)source(); out = in.setBytes(0, (ByteBuf)null, 0); sink(out); // $ hasValueFlow } { - // "io.netty.buffer;ByteBuf;true;setBytes;;;Argument[-1];ReturnValue;value;manual" - ByteBuf out = null; - SwappedByteBuf in = (SwappedByteBuf)source(); - out = in.setBytes(0, (ByteBuf)null, 0, 0); - sink(out); // $ hasValueFlow - } - { - // "io.netty.buffer;ByteBuf;true;setBytes;;;Argument[-1];ReturnValue;value;manual" - ByteBuf out = null; - SwappedByteBuf in = (SwappedByteBuf)source(); - out = in.setBytes(0, (ByteBuffer)null); - sink(out); // $ hasValueFlow - } - { - // "io.netty.buffer;ByteBuf;true;setBytes;;;Argument[-1];ReturnValue;value;manual" - ByteBuf out = null; - SwappedByteBuf in = (SwappedByteBuf)source(); - out = in.setBytes(0, (byte[])null); - sink(out); // $ hasValueFlow - } - { - // "io.netty.buffer;ByteBuf;true;setBytes;;;Argument[-1];ReturnValue;value;manual" - ByteBuf out = null; - SwappedByteBuf in = (SwappedByteBuf)source(); - out = in.setBytes(0, (byte[])null, 0, 0); - sink(out); // $ hasValueFlow - } - { - // "io.netty.buffer;ByteBuf;true;setBytes;;;Argument[-1];ReturnValue;value;manual" - CompositeByteBuf out = null; - CompositeByteBuf in = (CompositeByteBuf)source(); - out = in.setBytes(0, (ByteBuf)null); - sink(out); // $ hasValueFlow - } - { - // "io.netty.buffer;ByteBuf;true;setBytes;;;Argument[-1];ReturnValue;value;manual" + // "io.netty.buffer;ByteBuf;true;setBytes;(int,ByteBuf,int);;Argument[-1];ReturnValue;value;manual" CompositeByteBuf out = null; CompositeByteBuf in = (CompositeByteBuf)source(); out = in.setBytes(0, (ByteBuf)null, 0); sink(out); // $ hasValueFlow } { - // "io.netty.buffer;ByteBuf;true;setBytes;;;Argument[-1];ReturnValue;value;manual" + // "io.netty.buffer;ByteBuf;true;setBytes;(int,ByteBuf,int);;Argument[1];Argument[-1];taint;manual" + AbstractByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out.setBytes(0, in, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;setBytes;(int,ByteBuf,int);;Argument[1];Argument[-1];taint;manual" + ByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out.setBytes(0, in, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;setBytes;(int,ByteBuf,int);;Argument[1];Argument[-1];taint;manual" + CompositeByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out.setBytes(0, in, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;setBytes;(int,ByteBuf,int);;Argument[1];Argument[-1];taint;manual" + SwappedByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out.setBytes(0, in, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;setBytes;(int,ByteBuf,int,int);;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out = in.setBytes(0, (ByteBuf)null, 0, 0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;setBytes;(int,ByteBuf,int,int);;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + SwappedByteBuf in = (SwappedByteBuf)source(); + out = in.setBytes(0, (ByteBuf)null, 0, 0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;setBytes;(int,ByteBuf,int,int);;Argument[-1];ReturnValue;value;manual" CompositeByteBuf out = null; CompositeByteBuf in = (CompositeByteBuf)source(); out = in.setBytes(0, (ByteBuf)null, 0, 0); sink(out); // $ hasValueFlow } { - // "io.netty.buffer;ByteBuf;true;setBytes;;;Argument[-1];ReturnValue;value;manual" + // "io.netty.buffer;ByteBuf;true;setBytes;(int,ByteBuf,int,int);;Argument[1];Argument[-1];taint;manual" + ByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out.setBytes(0, in, 0, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;setBytes;(int,ByteBuf,int,int);;Argument[1];Argument[-1];taint;manual" + CompositeByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out.setBytes(0, in, 0, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;setBytes;(int,ByteBuf,int,int);;Argument[1];Argument[-1];taint;manual" + SwappedByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out.setBytes(0, in, 0, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;setBytes;(int,ByteBuffer);;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out = in.setBytes(0, (ByteBuffer)null); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;setBytes;(int,ByteBuffer);;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + SwappedByteBuf in = (SwappedByteBuf)source(); + out = in.setBytes(0, (ByteBuffer)null); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;setBytes;(int,ByteBuffer);;Argument[-1];ReturnValue;value;manual" CompositeByteBuf out = null; CompositeByteBuf in = (CompositeByteBuf)source(); out = in.setBytes(0, (ByteBuffer)null); sink(out); // $ hasValueFlow } { - // "io.netty.buffer;ByteBuf;true;setBytes;;;Argument[-1];ReturnValue;value;manual" + // "io.netty.buffer;ByteBuf;true;setBytes;(int,ByteBuffer);;Argument[1];Argument[-1];taint;manual" + ByteBuf out = null; + ByteBuffer in = (ByteBuffer)source(); + out.setBytes(0, in); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;setBytes;(int,ByteBuffer);;Argument[1];Argument[-1];taint;manual" + CompositeByteBuf out = null; + ByteBuffer in = (ByteBuffer)source(); + out.setBytes(0, in); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;setBytes;(int,ByteBuffer);;Argument[1];Argument[-1];taint;manual" + SwappedByteBuf out = null; + ByteBuffer in = (ByteBuffer)source(); + out.setBytes(0, in); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;setBytes;(int,FileChannel,long,int);;Argument[1];Argument[-1];taint;manual" + ByteBuf out = null; + FileChannel in = (FileChannel)source(); + out.setBytes(0, in, 0L, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;setBytes;(int,FileChannel,long,int);;Argument[1];Argument[-1];taint;manual" + CompositeByteBuf out = null; + FileChannel in = (FileChannel)source(); + out.setBytes(0, in, 0L, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;setBytes;(int,FileChannel,long,int);;Argument[1];Argument[-1];taint;manual" + SwappedByteBuf out = null; + FileChannel in = (FileChannel)source(); + out.setBytes(0, in, 0L, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;setBytes;(int,InputStream,int);;Argument[1];Argument[-1];taint;manual" + ByteBuf out = null; + InputStream in = (InputStream)source(); + out.setBytes(0, in, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;setBytes;(int,InputStream,int);;Argument[1];Argument[-1];taint;manual" + CompositeByteBuf out = null; + InputStream in = (InputStream)source(); + out.setBytes(0, in, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;setBytes;(int,InputStream,int);;Argument[1];Argument[-1];taint;manual" + SwappedByteBuf out = null; + InputStream in = (InputStream)source(); + out.setBytes(0, in, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;setBytes;(int,ScatteringByteChannel,int);;Argument[1];Argument[-1];taint;manual" + ByteBuf out = null; + ScatteringByteChannel in = (ScatteringByteChannel)source(); + out.setBytes(0, in, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;setBytes;(int,ScatteringByteChannel,int);;Argument[1];Argument[-1];taint;manual" + CompositeByteBuf out = null; + ScatteringByteChannel in = (ScatteringByteChannel)source(); + out.setBytes(0, in, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;setBytes;(int,ScatteringByteChannel,int);;Argument[1];Argument[-1];taint;manual" + SwappedByteBuf out = null; + ScatteringByteChannel in = (ScatteringByteChannel)source(); + out.setBytes(0, in, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;setBytes;(int,byte[]);;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + AbstractByteBuf in = (AbstractByteBuf)source(); + out = in.setBytes(0, (byte[])null); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;setBytes;(int,byte[]);;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out = in.setBytes(0, (byte[])null); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;setBytes;(int,byte[]);;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + SwappedByteBuf in = (SwappedByteBuf)source(); + out = in.setBytes(0, (byte[])null); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;setBytes;(int,byte[]);;Argument[-1];ReturnValue;value;manual" CompositeByteBuf out = null; CompositeByteBuf in = (CompositeByteBuf)source(); out = in.setBytes(0, (byte[])null); sink(out); // $ hasValueFlow } { - // "io.netty.buffer;ByteBuf;true;setBytes;;;Argument[-1];ReturnValue;value;manual" + // "io.netty.buffer;ByteBuf;true;setBytes;(int,byte[]);;Argument[1];Argument[-1];taint;manual" + AbstractByteBuf out = null; + byte[] in = (byte[])source(); + out.setBytes(0, in); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;setBytes;(int,byte[]);;Argument[1];Argument[-1];taint;manual" + ByteBuf out = null; + byte[] in = (byte[])source(); + out.setBytes(0, in); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;setBytes;(int,byte[]);;Argument[1];Argument[-1];taint;manual" + CompositeByteBuf out = null; + byte[] in = (byte[])source(); + out.setBytes(0, in); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;setBytes;(int,byte[]);;Argument[1];Argument[-1];taint;manual" + SwappedByteBuf out = null; + byte[] in = (byte[])source(); + out.setBytes(0, in); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;setBytes;(int,byte[],int,int);;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out = in.setBytes(0, (byte[])null, 0, 0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;setBytes;(int,byte[],int,int);;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + SwappedByteBuf in = (SwappedByteBuf)source(); + out = in.setBytes(0, (byte[])null, 0, 0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;setBytes;(int,byte[],int,int);;Argument[-1];ReturnValue;value;manual" CompositeByteBuf out = null; CompositeByteBuf in = (CompositeByteBuf)source(); out = in.setBytes(0, (byte[])null, 0, 0); sink(out); // $ hasValueFlow } { - // "io.netty.buffer;ByteBuf;true;setBytes;;;Argument[-1];ReturnValue;value;manual" - int out = null; - ByteBuf in = (ByteBuf)source(); - out = in.setBytes(0, (FileChannel)null, 0L, 0); - sink(out); // $ hasValueFlow - } - { - // "io.netty.buffer;ByteBuf;true;setBytes;;;Argument[-1];ReturnValue;value;manual" - int out = null; - ByteBuf in = (ByteBuf)source(); - out = in.setBytes(0, (InputStream)null, 0); - sink(out); // $ hasValueFlow - } - { - // "io.netty.buffer;ByteBuf;true;setBytes;;;Argument[-1];ReturnValue;value;manual" - int out = null; - ByteBuf in = (ByteBuf)source(); - out = in.setBytes(0, (ScatteringByteChannel)null, 0); - sink(out); // $ hasValueFlow - } - { - // "io.netty.buffer;ByteBuf;true;setBytes;;;Argument[-1];ReturnValue;value;manual" - int out = null; - CompositeByteBuf in = (CompositeByteBuf)source(); - out = in.setBytes(0, (FileChannel)null, 0L, 0); - sink(out); // $ hasValueFlow - } - { - // "io.netty.buffer;ByteBuf;true;setBytes;;;Argument[-1];ReturnValue;value;manual" - int out = null; - CompositeByteBuf in = (CompositeByteBuf)source(); - out = in.setBytes(0, (InputStream)null, 0); - sink(out); // $ hasValueFlow - } - { - // "io.netty.buffer;ByteBuf;true;setBytes;;;Argument[-1];ReturnValue;value;manual" - int out = null; - CompositeByteBuf in = (CompositeByteBuf)source(); - out = in.setBytes(0, (ScatteringByteChannel)null, 0); - sink(out); // $ hasValueFlow - } - { - // "io.netty.buffer;ByteBuf;true;setBytes;;;Argument[-1];ReturnValue;value;manual" - int out = null; - SwappedByteBuf in = (SwappedByteBuf)source(); - out = in.setBytes(0, (FileChannel)null, 0L, 0); - sink(out); // $ hasValueFlow - } - { - // "io.netty.buffer;ByteBuf;true;setBytes;;;Argument[-1];ReturnValue;value;manual" - int out = null; - SwappedByteBuf in = (SwappedByteBuf)source(); - out = in.setBytes(0, (InputStream)null, 0); - sink(out); // $ hasValueFlow - } - { - // "io.netty.buffer;ByteBuf;true;setBytes;;;Argument[-1];ReturnValue;value;manual" - int out = null; - SwappedByteBuf in = (SwappedByteBuf)source(); - out = in.setBytes(0, (ScatteringByteChannel)null, 0); - sink(out); // $ hasValueFlow - } - { - // "io.netty.buffer;ByteBuf;true;setBytes;;;Argument[1];Argument[-1];taint;manual" - AbstractByteBuf out = null; - ByteBuf in = (ByteBuf)source(); - out.setBytes(0, in); - sink(out); // $ hasTaintFlow - } - { - // "io.netty.buffer;ByteBuf;true;setBytes;;;Argument[1];Argument[-1];taint;manual" - AbstractByteBuf out = null; - ByteBuf in = (ByteBuf)source(); - out.setBytes(0, in, 0); - sink(out); // $ hasTaintFlow - } - { - // "io.netty.buffer;ByteBuf;true;setBytes;;;Argument[1];Argument[-1];taint;manual" - AbstractByteBuf out = null; - byte[] in = (byte[])source(); - out.setBytes(0, in); - sink(out); // $ hasTaintFlow - } - { - // "io.netty.buffer;ByteBuf;true;setBytes;;;Argument[1];Argument[-1];taint;manual" - ByteBuf out = null; - ByteBuf in = (ByteBuf)source(); - out.setBytes(0, in); - sink(out); // $ hasTaintFlow - } - { - // "io.netty.buffer;ByteBuf;true;setBytes;;;Argument[1];Argument[-1];taint;manual" - ByteBuf out = null; - ByteBuf in = (ByteBuf)source(); - out.setBytes(0, in, 0); - sink(out); // $ hasTaintFlow - } - { - // "io.netty.buffer;ByteBuf;true;setBytes;;;Argument[1];Argument[-1];taint;manual" - ByteBuf out = null; - ByteBuf in = (ByteBuf)source(); - out.setBytes(0, in, 0, 0); - sink(out); // $ hasTaintFlow - } - { - // "io.netty.buffer;ByteBuf;true;setBytes;;;Argument[1];Argument[-1];taint;manual" - ByteBuf out = null; - ByteBuffer in = (ByteBuffer)source(); - out.setBytes(0, in); - sink(out); // $ hasTaintFlow - } - { - // "io.netty.buffer;ByteBuf;true;setBytes;;;Argument[1];Argument[-1];taint;manual" - ByteBuf out = null; - FileChannel in = (FileChannel)source(); - out.setBytes(0, in, 0L, 0); - sink(out); // $ hasTaintFlow - } - { - // "io.netty.buffer;ByteBuf;true;setBytes;;;Argument[1];Argument[-1];taint;manual" - ByteBuf out = null; - InputStream in = (InputStream)source(); - out.setBytes(0, in, 0); - sink(out); // $ hasTaintFlow - } - { - // "io.netty.buffer;ByteBuf;true;setBytes;;;Argument[1];Argument[-1];taint;manual" - ByteBuf out = null; - ScatteringByteChannel in = (ScatteringByteChannel)source(); - out.setBytes(0, in, 0); - sink(out); // $ hasTaintFlow - } - { - // "io.netty.buffer;ByteBuf;true;setBytes;;;Argument[1];Argument[-1];taint;manual" - ByteBuf out = null; - byte[] in = (byte[])source(); - out.setBytes(0, in); - sink(out); // $ hasTaintFlow - } - { - // "io.netty.buffer;ByteBuf;true;setBytes;;;Argument[1];Argument[-1];taint;manual" + // "io.netty.buffer;ByteBuf;true;setBytes;(int,byte[],int,int);;Argument[1];Argument[-1];taint;manual" ByteBuf out = null; byte[] in = (byte[])source(); out.setBytes(0, in, 0, 0); sink(out); // $ hasTaintFlow } { - // "io.netty.buffer;ByteBuf;true;setBytes;;;Argument[1];Argument[-1];taint;manual" - CompositeByteBuf out = null; - ByteBuf in = (ByteBuf)source(); - out.setBytes(0, in); - sink(out); // $ hasTaintFlow - } - { - // "io.netty.buffer;ByteBuf;true;setBytes;;;Argument[1];Argument[-1];taint;manual" - CompositeByteBuf out = null; - ByteBuf in = (ByteBuf)source(); - out.setBytes(0, in, 0); - sink(out); // $ hasTaintFlow - } - { - // "io.netty.buffer;ByteBuf;true;setBytes;;;Argument[1];Argument[-1];taint;manual" - CompositeByteBuf out = null; - ByteBuf in = (ByteBuf)source(); - out.setBytes(0, in, 0, 0); - sink(out); // $ hasTaintFlow - } - { - // "io.netty.buffer;ByteBuf;true;setBytes;;;Argument[1];Argument[-1];taint;manual" - CompositeByteBuf out = null; - ByteBuffer in = (ByteBuffer)source(); - out.setBytes(0, in); - sink(out); // $ hasTaintFlow - } - { - // "io.netty.buffer;ByteBuf;true;setBytes;;;Argument[1];Argument[-1];taint;manual" - CompositeByteBuf out = null; - FileChannel in = (FileChannel)source(); - out.setBytes(0, in, 0L, 0); - sink(out); // $ hasTaintFlow - } - { - // "io.netty.buffer;ByteBuf;true;setBytes;;;Argument[1];Argument[-1];taint;manual" - CompositeByteBuf out = null; - InputStream in = (InputStream)source(); - out.setBytes(0, in, 0); - sink(out); // $ hasTaintFlow - } - { - // "io.netty.buffer;ByteBuf;true;setBytes;;;Argument[1];Argument[-1];taint;manual" - CompositeByteBuf out = null; - ScatteringByteChannel in = (ScatteringByteChannel)source(); - out.setBytes(0, in, 0); - sink(out); // $ hasTaintFlow - } - { - // "io.netty.buffer;ByteBuf;true;setBytes;;;Argument[1];Argument[-1];taint;manual" - CompositeByteBuf out = null; - byte[] in = (byte[])source(); - out.setBytes(0, in); - sink(out); // $ hasTaintFlow - } - { - // "io.netty.buffer;ByteBuf;true;setBytes;;;Argument[1];Argument[-1];taint;manual" + // "io.netty.buffer;ByteBuf;true;setBytes;(int,byte[],int,int);;Argument[1];Argument[-1];taint;manual" CompositeByteBuf out = null; byte[] in = (byte[])source(); out.setBytes(0, in, 0, 0); sink(out); // $ hasTaintFlow } { - // "io.netty.buffer;ByteBuf;true;setBytes;;;Argument[1];Argument[-1];taint;manual" - SwappedByteBuf out = null; - ByteBuf in = (ByteBuf)source(); - out.setBytes(0, in); - sink(out); // $ hasTaintFlow - } - { - // "io.netty.buffer;ByteBuf;true;setBytes;;;Argument[1];Argument[-1];taint;manual" - SwappedByteBuf out = null; - ByteBuf in = (ByteBuf)source(); - out.setBytes(0, in, 0); - sink(out); // $ hasTaintFlow - } - { - // "io.netty.buffer;ByteBuf;true;setBytes;;;Argument[1];Argument[-1];taint;manual" - SwappedByteBuf out = null; - ByteBuf in = (ByteBuf)source(); - out.setBytes(0, in, 0, 0); - sink(out); // $ hasTaintFlow - } - { - // "io.netty.buffer;ByteBuf;true;setBytes;;;Argument[1];Argument[-1];taint;manual" - SwappedByteBuf out = null; - ByteBuffer in = (ByteBuffer)source(); - out.setBytes(0, in); - sink(out); // $ hasTaintFlow - } - { - // "io.netty.buffer;ByteBuf;true;setBytes;;;Argument[1];Argument[-1];taint;manual" - SwappedByteBuf out = null; - FileChannel in = (FileChannel)source(); - out.setBytes(0, in, 0L, 0); - sink(out); // $ hasTaintFlow - } - { - // "io.netty.buffer;ByteBuf;true;setBytes;;;Argument[1];Argument[-1];taint;manual" - SwappedByteBuf out = null; - InputStream in = (InputStream)source(); - out.setBytes(0, in, 0); - sink(out); // $ hasTaintFlow - } - { - // "io.netty.buffer;ByteBuf;true;setBytes;;;Argument[1];Argument[-1];taint;manual" - SwappedByteBuf out = null; - ScatteringByteChannel in = (ScatteringByteChannel)source(); - out.setBytes(0, in, 0); - sink(out); // $ hasTaintFlow - } - { - // "io.netty.buffer;ByteBuf;true;setBytes;;;Argument[1];Argument[-1];taint;manual" - SwappedByteBuf out = null; - byte[] in = (byte[])source(); - out.setBytes(0, in); - sink(out); // $ hasTaintFlow - } - { - // "io.netty.buffer;ByteBuf;true;setBytes;;;Argument[1];Argument[-1];taint;manual" + // "io.netty.buffer;ByteBuf;true;setBytes;(int,byte[],int,int);;Argument[1];Argument[-1];taint;manual" SwappedByteBuf out = null; byte[] in = (byte[])source(); out.setBytes(0, in, 0, 0); @@ -2259,55 +1901,6 @@ public class Test { out = in.setChar(0, 0); sink(out); // $ hasValueFlow } - { - // "io.netty.buffer;ByteBuf;true;setChar;;;Argument[1];Argument[-1];taint;manual" - AbstractByteBuf out = null; - int in = (int)source(); - out.setChar(0, in); - sink(out); // $ hasTaintFlow - } - { - // "io.netty.buffer;ByteBuf;true;setChar;;;Argument[1];Argument[-1];taint;manual" - ByteBuf out = null; - int in = (int)source(); - out.setChar(0, in); - sink(out); // $ hasTaintFlow - } - { - // "io.netty.buffer;ByteBuf;true;setChar;;;Argument[1];Argument[-1];taint;manual" - CompositeByteBuf out = null; - int in = (int)source(); - out.setChar(0, in); - sink(out); // $ hasTaintFlow - } - { - // "io.netty.buffer;ByteBuf;true;setChar;;;Argument[1];Argument[-1];taint;manual" - SwappedByteBuf out = null; - int in = (int)source(); - out.setChar(0, in); - sink(out); // $ hasTaintFlow - } - { - // "io.netty.buffer;ByteBuf;true;setCharSequence;;;Argument[-1];ReturnValue;value;manual" - int out = null; - AbstractByteBuf in = (AbstractByteBuf)source(); - out = in.setCharSequence(0, null, null); - sink(out); // $ hasValueFlow - } - { - // "io.netty.buffer;ByteBuf;true;setCharSequence;;;Argument[-1];ReturnValue;value;manual" - int out = null; - ByteBuf in = (ByteBuf)source(); - out = in.setCharSequence(0, null, null); - sink(out); // $ hasValueFlow - } - { - // "io.netty.buffer;ByteBuf;true;setCharSequence;;;Argument[-1];ReturnValue;value;manual" - int out = null; - SwappedByteBuf in = (SwappedByteBuf)source(); - out = in.setCharSequence(0, null, null); - sink(out); // $ hasValueFlow - } { // "io.netty.buffer;ByteBuf;true;setCharSequence;;;Argument[1];Argument[-1];taint;manual" AbstractByteBuf out = null; @@ -2652,54 +2245,75 @@ public class Test { sink(out); // $ hasValueFlow } { - // "io.netty.buffer;ByteBuf;true;skipBytes;;;Argument[-1];ReturnValue;value;manual" + // "io.netty.buffer;ByteBuf;true;skipBytes;(int);;Argument[-1];ReturnValue;value;manual" ByteBuf out = null; AbstractByteBuf in = (AbstractByteBuf)source(); out = in.skipBytes(0); sink(out); // $ hasValueFlow } { - // "io.netty.buffer;ByteBuf;true;skipBytes;;;Argument[-1];ReturnValue;value;manual" + // "io.netty.buffer;ByteBuf;true;skipBytes;(int);;Argument[-1];ReturnValue;value;manual" ByteBuf out = null; ByteBuf in = (ByteBuf)source(); out = in.skipBytes(0); sink(out); // $ hasValueFlow } { - // "io.netty.buffer;ByteBuf;true;skipBytes;;;Argument[-1];ReturnValue;value;manual" + // "io.netty.buffer;ByteBuf;true;skipBytes;(int);;Argument[-1];ReturnValue;value;manual" ByteBuf out = null; SwappedByteBuf in = (SwappedByteBuf)source(); out = in.skipBytes(0); sink(out); // $ hasValueFlow } { - // "io.netty.buffer;ByteBuf;true;skipBytes;;;Argument[-1];ReturnValue;value;manual" + // "io.netty.buffer;ByteBuf;true;skipBytes;(int);;Argument[-1];ReturnValue;value;manual" CompositeByteBuf out = null; CompositeByteBuf in = (CompositeByteBuf)source(); out = in.skipBytes(0); sink(out); // $ hasValueFlow } { - // "io.netty.buffer;ByteBuf;true;slice;();;Argument[-1];ReturnValue;taint;manual" + // "io.netty.buffer;ByteBuf;true;slice;;;Argument[-1];ReturnValue;taint;manual" ByteBuf out = null; AbstractByteBuf in = (AbstractByteBuf)source(); out = in.slice(); sink(out); // $ hasTaintFlow } { - // "io.netty.buffer;ByteBuf;true;slice;();;Argument[-1];ReturnValue;taint;manual" + // "io.netty.buffer;ByteBuf;true;slice;;;Argument[-1];ReturnValue;taint;manual" + ByteBuf out = null; + AbstractByteBuf in = (AbstractByteBuf)source(); + out = in.slice(0, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;slice;;;Argument[-1];ReturnValue;taint;manual" ByteBuf out = null; ByteBuf in = (ByteBuf)source(); out = in.slice(); sink(out); // $ hasTaintFlow } { - // "io.netty.buffer;ByteBuf;true;slice;();;Argument[-1];ReturnValue;taint;manual" + // "io.netty.buffer;ByteBuf;true;slice;;;Argument[-1];ReturnValue;taint;manual" + ByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out = in.slice(0, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;slice;;;Argument[-1];ReturnValue;taint;manual" ByteBuf out = null; SwappedByteBuf in = (SwappedByteBuf)source(); out = in.slice(); sink(out); // $ hasTaintFlow } + { + // "io.netty.buffer;ByteBuf;true;slice;;;Argument[-1];ReturnValue;taint;manual" + ByteBuf out = null; + SwappedByteBuf in = (SwappedByteBuf)source(); + out = in.slice(0, 0); + sink(out); // $ hasTaintFlow + } { // "io.netty.buffer;ByteBuf;true;toString;;;Argument[-1];ReturnValue;taint;manual" String out = null; @@ -2848,462 +2462,399 @@ public class Test { sink(out); // $ hasTaintFlow } { - // "io.netty.buffer;ByteBuf;true;writeBytes;;;Argument[-1];ReturnValue;value;manual" + // "io.netty.buffer;ByteBuf;true;writeBytes;(ByteBuf);;Argument[-1];ReturnValue;value;manual" ByteBuf out = null; AbstractByteBuf in = (AbstractByteBuf)source(); out = in.writeBytes((ByteBuf)null); sink(out); // $ hasValueFlow } { - // "io.netty.buffer;ByteBuf;true;writeBytes;;;Argument[-1];ReturnValue;value;manual" + // "io.netty.buffer;ByteBuf;true;writeBytes;(ByteBuf);;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out = in.writeBytes((ByteBuf)null); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeBytes;(ByteBuf);;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + SwappedByteBuf in = (SwappedByteBuf)source(); + out = in.writeBytes((ByteBuf)null); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeBytes;(ByteBuf);;Argument[-1];ReturnValue;value;manual" + CompositeByteBuf out = null; + CompositeByteBuf in = (CompositeByteBuf)source(); + out = in.writeBytes((ByteBuf)null); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeBytes;(ByteBuf);;Argument[0];Argument[-1];taint;manual" + AbstractByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out.writeBytes(in); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeBytes;(ByteBuf);;Argument[0];Argument[-1];taint;manual" + ByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out.writeBytes(in); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeBytes;(ByteBuf);;Argument[0];Argument[-1];taint;manual" + CompositeByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out.writeBytes(in); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeBytes;(ByteBuf);;Argument[0];Argument[-1];taint;manual" + SwappedByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out.writeBytes(in); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeBytes;(ByteBuf,int);;Argument[-1];ReturnValue;value;manual" ByteBuf out = null; AbstractByteBuf in = (AbstractByteBuf)source(); out = in.writeBytes((ByteBuf)null, 0); sink(out); // $ hasValueFlow } { - // "io.netty.buffer;ByteBuf;true;writeBytes;;;Argument[-1];ReturnValue;value;manual" - ByteBuf out = null; - AbstractByteBuf in = (AbstractByteBuf)source(); - out = in.writeBytes((ByteBuf)null, 0, 0); - sink(out); // $ hasValueFlow - } - { - // "io.netty.buffer;ByteBuf;true;writeBytes;;;Argument[-1];ReturnValue;value;manual" - ByteBuf out = null; - AbstractByteBuf in = (AbstractByteBuf)source(); - out = in.writeBytes((ByteBuffer)null); - sink(out); // $ hasValueFlow - } - { - // "io.netty.buffer;ByteBuf;true;writeBytes;;;Argument[-1];ReturnValue;value;manual" - ByteBuf out = null; - AbstractByteBuf in = (AbstractByteBuf)source(); - out = in.writeBytes((byte[])null); - sink(out); // $ hasValueFlow - } - { - // "io.netty.buffer;ByteBuf;true;writeBytes;;;Argument[-1];ReturnValue;value;manual" - ByteBuf out = null; - AbstractByteBuf in = (AbstractByteBuf)source(); - out = in.writeBytes((byte[])null, 0, 0); - sink(out); // $ hasValueFlow - } - { - // "io.netty.buffer;ByteBuf;true;writeBytes;;;Argument[-1];ReturnValue;value;manual" - ByteBuf out = null; - ByteBuf in = (ByteBuf)source(); - out = in.writeBytes((ByteBuf)null); - sink(out); // $ hasValueFlow - } - { - // "io.netty.buffer;ByteBuf;true;writeBytes;;;Argument[-1];ReturnValue;value;manual" + // "io.netty.buffer;ByteBuf;true;writeBytes;(ByteBuf,int);;Argument[-1];ReturnValue;value;manual" ByteBuf out = null; ByteBuf in = (ByteBuf)source(); out = in.writeBytes((ByteBuf)null, 0); sink(out); // $ hasValueFlow } { - // "io.netty.buffer;ByteBuf;true;writeBytes;;;Argument[-1];ReturnValue;value;manual" - ByteBuf out = null; - ByteBuf in = (ByteBuf)source(); - out = in.writeBytes((ByteBuf)null, 0, 0); - sink(out); // $ hasValueFlow - } - { - // "io.netty.buffer;ByteBuf;true;writeBytes;;;Argument[-1];ReturnValue;value;manual" - ByteBuf out = null; - ByteBuf in = (ByteBuf)source(); - out = in.writeBytes((ByteBuffer)null); - sink(out); // $ hasValueFlow - } - { - // "io.netty.buffer;ByteBuf;true;writeBytes;;;Argument[-1];ReturnValue;value;manual" - ByteBuf out = null; - ByteBuf in = (ByteBuf)source(); - out = in.writeBytes((byte[])null); - sink(out); // $ hasValueFlow - } - { - // "io.netty.buffer;ByteBuf;true;writeBytes;;;Argument[-1];ReturnValue;value;manual" - ByteBuf out = null; - ByteBuf in = (ByteBuf)source(); - out = in.writeBytes((byte[])null, 0, 0); - sink(out); // $ hasValueFlow - } - { - // "io.netty.buffer;ByteBuf;true;writeBytes;;;Argument[-1];ReturnValue;value;manual" - ByteBuf out = null; - SwappedByteBuf in = (SwappedByteBuf)source(); - out = in.writeBytes((ByteBuf)null); - sink(out); // $ hasValueFlow - } - { - // "io.netty.buffer;ByteBuf;true;writeBytes;;;Argument[-1];ReturnValue;value;manual" + // "io.netty.buffer;ByteBuf;true;writeBytes;(ByteBuf,int);;Argument[-1];ReturnValue;value;manual" ByteBuf out = null; SwappedByteBuf in = (SwappedByteBuf)source(); out = in.writeBytes((ByteBuf)null, 0); sink(out); // $ hasValueFlow } { - // "io.netty.buffer;ByteBuf;true;writeBytes;;;Argument[-1];ReturnValue;value;manual" + // "io.netty.buffer;ByteBuf;true;writeBytes;(ByteBuf,int);;Argument[-1];ReturnValue;value;manual" + CompositeByteBuf out = null; + CompositeByteBuf in = (CompositeByteBuf)source(); + out = in.writeBytes((ByteBuf)null, 0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeBytes;(ByteBuf,int);;Argument[0];Argument[-1];taint;manual" + AbstractByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out.writeBytes(in, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeBytes;(ByteBuf,int);;Argument[0];Argument[-1];taint;manual" + ByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out.writeBytes(in, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeBytes;(ByteBuf,int);;Argument[0];Argument[-1];taint;manual" + CompositeByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out.writeBytes(in, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeBytes;(ByteBuf,int);;Argument[0];Argument[-1];taint;manual" + SwappedByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out.writeBytes(in, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeBytes;(ByteBuf,int,int);;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + AbstractByteBuf in = (AbstractByteBuf)source(); + out = in.writeBytes((ByteBuf)null, 0, 0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeBytes;(ByteBuf,int,int);;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out = in.writeBytes((ByteBuf)null, 0, 0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeBytes;(ByteBuf,int,int);;Argument[-1];ReturnValue;value;manual" ByteBuf out = null; SwappedByteBuf in = (SwappedByteBuf)source(); out = in.writeBytes((ByteBuf)null, 0, 0); sink(out); // $ hasValueFlow } { - // "io.netty.buffer;ByteBuf;true;writeBytes;;;Argument[-1];ReturnValue;value;manual" - ByteBuf out = null; - SwappedByteBuf in = (SwappedByteBuf)source(); - out = in.writeBytes((ByteBuffer)null); - sink(out); // $ hasValueFlow - } - { - // "io.netty.buffer;ByteBuf;true;writeBytes;;;Argument[-1];ReturnValue;value;manual" - ByteBuf out = null; - SwappedByteBuf in = (SwappedByteBuf)source(); - out = in.writeBytes((byte[])null); - sink(out); // $ hasValueFlow - } - { - // "io.netty.buffer;ByteBuf;true;writeBytes;;;Argument[-1];ReturnValue;value;manual" - ByteBuf out = null; - SwappedByteBuf in = (SwappedByteBuf)source(); - out = in.writeBytes((byte[])null, 0, 0); - sink(out); // $ hasValueFlow - } - { - // "io.netty.buffer;ByteBuf;true;writeBytes;;;Argument[-1];ReturnValue;value;manual" - CompositeByteBuf out = null; - CompositeByteBuf in = (CompositeByteBuf)source(); - out = in.writeBytes((ByteBuf)null); - sink(out); // $ hasValueFlow - } - { - // "io.netty.buffer;ByteBuf;true;writeBytes;;;Argument[-1];ReturnValue;value;manual" + // "io.netty.buffer;ByteBuf;true;writeBytes;(ByteBuf,int,int);;Argument[-1];ReturnValue;value;manual" CompositeByteBuf out = null; CompositeByteBuf in = (CompositeByteBuf)source(); out = in.writeBytes((ByteBuf)null, 0, 0); sink(out); // $ hasValueFlow } { - // "io.netty.buffer;ByteBuf;true;writeBytes;;;Argument[-1];ReturnValue;value;manual" + // "io.netty.buffer;ByteBuf;true;writeBytes;(ByteBuf,int,int);;Argument[0];Argument[-1];taint;manual" + AbstractByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out.writeBytes(in, 0, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeBytes;(ByteBuf,int,int);;Argument[0];Argument[-1];taint;manual" + ByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out.writeBytes(in, 0, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeBytes;(ByteBuf,int,int);;Argument[0];Argument[-1];taint;manual" + CompositeByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out.writeBytes(in, 0, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeBytes;(ByteBuf,int,int);;Argument[0];Argument[-1];taint;manual" + SwappedByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out.writeBytes(in, 0, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeBytes;(ByteBuffer);;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + AbstractByteBuf in = (AbstractByteBuf)source(); + out = in.writeBytes((ByteBuffer)null); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeBytes;(ByteBuffer);;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out = in.writeBytes((ByteBuffer)null); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeBytes;(ByteBuffer);;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + SwappedByteBuf in = (SwappedByteBuf)source(); + out = in.writeBytes((ByteBuffer)null); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeBytes;(ByteBuffer);;Argument[-1];ReturnValue;value;manual" CompositeByteBuf out = null; CompositeByteBuf in = (CompositeByteBuf)source(); out = in.writeBytes((ByteBuffer)null); sink(out); // $ hasValueFlow } { - // "io.netty.buffer;ByteBuf;true;writeBytes;;;Argument[-1];ReturnValue;value;manual" + // "io.netty.buffer;ByteBuf;true;writeBytes;(ByteBuffer);;Argument[0];Argument[-1];taint;manual" + AbstractByteBuf out = null; + ByteBuffer in = (ByteBuffer)source(); + out.writeBytes(in); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeBytes;(ByteBuffer);;Argument[0];Argument[-1];taint;manual" + ByteBuf out = null; + ByteBuffer in = (ByteBuffer)source(); + out.writeBytes(in); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeBytes;(ByteBuffer);;Argument[0];Argument[-1];taint;manual" + CompositeByteBuf out = null; + ByteBuffer in = (ByteBuffer)source(); + out.writeBytes(in); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeBytes;(ByteBuffer);;Argument[0];Argument[-1];taint;manual" + SwappedByteBuf out = null; + ByteBuffer in = (ByteBuffer)source(); + out.writeBytes(in); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeBytes;(FileChannel,long,int);;Argument[0];Argument[-1];taint;manual" + AbstractByteBuf out = null; + FileChannel in = (FileChannel)source(); + out.writeBytes(in, 0L, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeBytes;(FileChannel,long,int);;Argument[0];Argument[-1];taint;manual" + ByteBuf out = null; + FileChannel in = (FileChannel)source(); + out.writeBytes(in, 0L, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeBytes;(FileChannel,long,int);;Argument[0];Argument[-1];taint;manual" + SwappedByteBuf out = null; + FileChannel in = (FileChannel)source(); + out.writeBytes(in, 0L, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeBytes;(InputStream,int);;Argument[0];Argument[-1];taint;manual" + AbstractByteBuf out = null; + InputStream in = (InputStream)source(); + out.writeBytes(in, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeBytes;(InputStream,int);;Argument[0];Argument[-1];taint;manual" + ByteBuf out = null; + InputStream in = (InputStream)source(); + out.writeBytes(in, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeBytes;(InputStream,int);;Argument[0];Argument[-1];taint;manual" + SwappedByteBuf out = null; + InputStream in = (InputStream)source(); + out.writeBytes(in, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeBytes;(ScatteringByteChannel,int);;Argument[0];Argument[-1];taint;manual" + AbstractByteBuf out = null; + ScatteringByteChannel in = (ScatteringByteChannel)source(); + out.writeBytes(in, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeBytes;(ScatteringByteChannel,int);;Argument[0];Argument[-1];taint;manual" + ByteBuf out = null; + ScatteringByteChannel in = (ScatteringByteChannel)source(); + out.writeBytes(in, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeBytes;(ScatteringByteChannel,int);;Argument[0];Argument[-1];taint;manual" + SwappedByteBuf out = null; + ScatteringByteChannel in = (ScatteringByteChannel)source(); + out.writeBytes(in, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeBytes;(byte[]);;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + AbstractByteBuf in = (AbstractByteBuf)source(); + out = in.writeBytes((byte[])null); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeBytes;(byte[]);;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out = in.writeBytes((byte[])null); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeBytes;(byte[]);;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + SwappedByteBuf in = (SwappedByteBuf)source(); + out = in.writeBytes((byte[])null); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeBytes;(byte[]);;Argument[-1];ReturnValue;value;manual" CompositeByteBuf out = null; CompositeByteBuf in = (CompositeByteBuf)source(); out = in.writeBytes((byte[])null); sink(out); // $ hasValueFlow } { - // "io.netty.buffer;ByteBuf;true;writeBytes;;;Argument[-1];ReturnValue;value;manual" + // "io.netty.buffer;ByteBuf;true;writeBytes;(byte[]);;Argument[0];Argument[-1];taint;manual" + AbstractByteBuf out = null; + byte[] in = (byte[])source(); + out.writeBytes(in); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeBytes;(byte[]);;Argument[0];Argument[-1];taint;manual" + ByteBuf out = null; + byte[] in = (byte[])source(); + out.writeBytes(in); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeBytes;(byte[]);;Argument[0];Argument[-1];taint;manual" + CompositeByteBuf out = null; + byte[] in = (byte[])source(); + out.writeBytes(in); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeBytes;(byte[]);;Argument[0];Argument[-1];taint;manual" + SwappedByteBuf out = null; + byte[] in = (byte[])source(); + out.writeBytes(in); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeBytes;(byte[],int,int);;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + AbstractByteBuf in = (AbstractByteBuf)source(); + out = in.writeBytes((byte[])null, 0, 0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeBytes;(byte[],int,int);;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out = in.writeBytes((byte[])null, 0, 0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeBytes;(byte[],int,int);;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + SwappedByteBuf in = (SwappedByteBuf)source(); + out = in.writeBytes((byte[])null, 0, 0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeBytes;(byte[],int,int);;Argument[-1];ReturnValue;value;manual" CompositeByteBuf out = null; CompositeByteBuf in = (CompositeByteBuf)source(); out = in.writeBytes((byte[])null, 0, 0); sink(out); // $ hasValueFlow } { - // "io.netty.buffer;ByteBuf;true;writeBytes;;;Argument[-1];ReturnValue;value;manual" - CompositeByteBuf out = null; - CompositeByteBuf in = (CompositeByteBuf)source(); - out = in.writeBytes(null, 0); - sink(out); // $ hasValueFlow - } - { - // "io.netty.buffer;ByteBuf;true;writeBytes;;;Argument[-1];ReturnValue;value;manual" - int out = null; - AbstractByteBuf in = (AbstractByteBuf)source(); - out = in.writeBytes((FileChannel)null, 0L, 0); - sink(out); // $ hasValueFlow - } - { - // "io.netty.buffer;ByteBuf;true;writeBytes;;;Argument[-1];ReturnValue;value;manual" - int out = null; - AbstractByteBuf in = (AbstractByteBuf)source(); - out = in.writeBytes((InputStream)null, 0); - sink(out); // $ hasValueFlow - } - { - // "io.netty.buffer;ByteBuf;true;writeBytes;;;Argument[-1];ReturnValue;value;manual" - int out = null; - AbstractByteBuf in = (AbstractByteBuf)source(); - out = in.writeBytes((ScatteringByteChannel)null, 0); - sink(out); // $ hasValueFlow - } - { - // "io.netty.buffer;ByteBuf;true;writeBytes;;;Argument[-1];ReturnValue;value;manual" - int out = null; - ByteBuf in = (ByteBuf)source(); - out = in.writeBytes((FileChannel)null, 0L, 0); - sink(out); // $ hasValueFlow - } - { - // "io.netty.buffer;ByteBuf;true;writeBytes;;;Argument[-1];ReturnValue;value;manual" - int out = null; - ByteBuf in = (ByteBuf)source(); - out = in.writeBytes((InputStream)null, 0); - sink(out); // $ hasValueFlow - } - { - // "io.netty.buffer;ByteBuf;true;writeBytes;;;Argument[-1];ReturnValue;value;manual" - int out = null; - ByteBuf in = (ByteBuf)source(); - out = in.writeBytes((ScatteringByteChannel)null, 0); - sink(out); // $ hasValueFlow - } - { - // "io.netty.buffer;ByteBuf;true;writeBytes;;;Argument[-1];ReturnValue;value;manual" - int out = null; - SwappedByteBuf in = (SwappedByteBuf)source(); - out = in.writeBytes((FileChannel)null, 0L, 0); - sink(out); // $ hasValueFlow - } - { - // "io.netty.buffer;ByteBuf;true;writeBytes;;;Argument[-1];ReturnValue;value;manual" - int out = null; - SwappedByteBuf in = (SwappedByteBuf)source(); - out = in.writeBytes((InputStream)null, 0); - sink(out); // $ hasValueFlow - } - { - // "io.netty.buffer;ByteBuf;true;writeBytes;;;Argument[-1];ReturnValue;value;manual" - int out = null; - SwappedByteBuf in = (SwappedByteBuf)source(); - out = in.writeBytes((ScatteringByteChannel)null, 0); - sink(out); // $ hasValueFlow - } - { - // "io.netty.buffer;ByteBuf;true;writeBytes;;;Argument[0];Argument[-1];taint;manual" - AbstractByteBuf out = null; - ByteBuf in = (ByteBuf)source(); - out.writeBytes(in); - sink(out); // $ hasTaintFlow - } - { - // "io.netty.buffer;ByteBuf;true;writeBytes;;;Argument[0];Argument[-1];taint;manual" - AbstractByteBuf out = null; - ByteBuf in = (ByteBuf)source(); - out.writeBytes(in, 0); - sink(out); // $ hasTaintFlow - } - { - // "io.netty.buffer;ByteBuf;true;writeBytes;;;Argument[0];Argument[-1];taint;manual" - AbstractByteBuf out = null; - ByteBuf in = (ByteBuf)source(); - out.writeBytes(in, 0, 0); - sink(out); // $ hasTaintFlow - } - { - // "io.netty.buffer;ByteBuf;true;writeBytes;;;Argument[0];Argument[-1];taint;manual" - AbstractByteBuf out = null; - ByteBuffer in = (ByteBuffer)source(); - out.writeBytes(in); - sink(out); // $ hasTaintFlow - } - { - // "io.netty.buffer;ByteBuf;true;writeBytes;;;Argument[0];Argument[-1];taint;manual" - AbstractByteBuf out = null; - FileChannel in = (FileChannel)source(); - out.writeBytes(in, 0L, 0); - sink(out); // $ hasTaintFlow - } - { - // "io.netty.buffer;ByteBuf;true;writeBytes;;;Argument[0];Argument[-1];taint;manual" - AbstractByteBuf out = null; - InputStream in = (InputStream)source(); - out.writeBytes(in, 0); - sink(out); // $ hasTaintFlow - } - { - // "io.netty.buffer;ByteBuf;true;writeBytes;;;Argument[0];Argument[-1];taint;manual" - AbstractByteBuf out = null; - ScatteringByteChannel in = (ScatteringByteChannel)source(); - out.writeBytes(in, 0); - sink(out); // $ hasTaintFlow - } - { - // "io.netty.buffer;ByteBuf;true;writeBytes;;;Argument[0];Argument[-1];taint;manual" - AbstractByteBuf out = null; - byte[] in = (byte[])source(); - out.writeBytes(in); - sink(out); // $ hasTaintFlow - } - { - // "io.netty.buffer;ByteBuf;true;writeBytes;;;Argument[0];Argument[-1];taint;manual" + // "io.netty.buffer;ByteBuf;true;writeBytes;(byte[],int,int);;Argument[0];Argument[-1];taint;manual" AbstractByteBuf out = null; byte[] in = (byte[])source(); out.writeBytes(in, 0, 0); sink(out); // $ hasTaintFlow } { - // "io.netty.buffer;ByteBuf;true;writeBytes;;;Argument[0];Argument[-1];taint;manual" - ByteBuf out = null; - ByteBuf in = (ByteBuf)source(); - out.writeBytes(in); - sink(out); // $ hasTaintFlow - } - { - // "io.netty.buffer;ByteBuf;true;writeBytes;;;Argument[0];Argument[-1];taint;manual" - ByteBuf out = null; - ByteBuf in = (ByteBuf)source(); - out.writeBytes(in, 0); - sink(out); // $ hasTaintFlow - } - { - // "io.netty.buffer;ByteBuf;true;writeBytes;;;Argument[0];Argument[-1];taint;manual" - ByteBuf out = null; - ByteBuf in = (ByteBuf)source(); - out.writeBytes(in, 0, 0); - sink(out); // $ hasTaintFlow - } - { - // "io.netty.buffer;ByteBuf;true;writeBytes;;;Argument[0];Argument[-1];taint;manual" - ByteBuf out = null; - ByteBuffer in = (ByteBuffer)source(); - out.writeBytes(in); - sink(out); // $ hasTaintFlow - } - { - // "io.netty.buffer;ByteBuf;true;writeBytes;;;Argument[0];Argument[-1];taint;manual" - ByteBuf out = null; - FileChannel in = (FileChannel)source(); - out.writeBytes(in, 0L, 0); - sink(out); // $ hasTaintFlow - } - { - // "io.netty.buffer;ByteBuf;true;writeBytes;;;Argument[0];Argument[-1];taint;manual" - ByteBuf out = null; - InputStream in = (InputStream)source(); - out.writeBytes(in, 0); - sink(out); // $ hasTaintFlow - } - { - // "io.netty.buffer;ByteBuf;true;writeBytes;;;Argument[0];Argument[-1];taint;manual" - ByteBuf out = null; - ScatteringByteChannel in = (ScatteringByteChannel)source(); - out.writeBytes(in, 0); - sink(out); // $ hasTaintFlow - } - { - // "io.netty.buffer;ByteBuf;true;writeBytes;;;Argument[0];Argument[-1];taint;manual" - ByteBuf out = null; - byte[] in = (byte[])source(); - out.writeBytes(in); - sink(out); // $ hasTaintFlow - } - { - // "io.netty.buffer;ByteBuf;true;writeBytes;;;Argument[0];Argument[-1];taint;manual" + // "io.netty.buffer;ByteBuf;true;writeBytes;(byte[],int,int);;Argument[0];Argument[-1];taint;manual" ByteBuf out = null; byte[] in = (byte[])source(); out.writeBytes(in, 0, 0); sink(out); // $ hasTaintFlow } { - // "io.netty.buffer;ByteBuf;true;writeBytes;;;Argument[0];Argument[-1];taint;manual" - CompositeByteBuf out = null; - ByteBuf in = (ByteBuf)source(); - out.writeBytes(in); - sink(out); // $ hasTaintFlow - } - { - // "io.netty.buffer;ByteBuf;true;writeBytes;;;Argument[0];Argument[-1];taint;manual" - CompositeByteBuf out = null; - ByteBuf in = (ByteBuf)source(); - out.writeBytes(in, 0); - sink(out); // $ hasTaintFlow - } - { - // "io.netty.buffer;ByteBuf;true;writeBytes;;;Argument[0];Argument[-1];taint;manual" - CompositeByteBuf out = null; - ByteBuf in = (ByteBuf)source(); - out.writeBytes(in, 0, 0); - sink(out); // $ hasTaintFlow - } - { - // "io.netty.buffer;ByteBuf;true;writeBytes;;;Argument[0];Argument[-1];taint;manual" - CompositeByteBuf out = null; - ByteBuffer in = (ByteBuffer)source(); - out.writeBytes(in); - sink(out); // $ hasTaintFlow - } - { - // "io.netty.buffer;ByteBuf;true;writeBytes;;;Argument[0];Argument[-1];taint;manual" - CompositeByteBuf out = null; - byte[] in = (byte[])source(); - out.writeBytes(in); - sink(out); // $ hasTaintFlow - } - { - // "io.netty.buffer;ByteBuf;true;writeBytes;;;Argument[0];Argument[-1];taint;manual" + // "io.netty.buffer;ByteBuf;true;writeBytes;(byte[],int,int);;Argument[0];Argument[-1];taint;manual" CompositeByteBuf out = null; byte[] in = (byte[])source(); out.writeBytes(in, 0, 0); sink(out); // $ hasTaintFlow } { - // "io.netty.buffer;ByteBuf;true;writeBytes;;;Argument[0];Argument[-1];taint;manual" - SwappedByteBuf out = null; - ByteBuf in = (ByteBuf)source(); - out.writeBytes(in); - sink(out); // $ hasTaintFlow - } - { - // "io.netty.buffer;ByteBuf;true;writeBytes;;;Argument[0];Argument[-1];taint;manual" - SwappedByteBuf out = null; - ByteBuf in = (ByteBuf)source(); - out.writeBytes(in, 0); - sink(out); // $ hasTaintFlow - } - { - // "io.netty.buffer;ByteBuf;true;writeBytes;;;Argument[0];Argument[-1];taint;manual" - SwappedByteBuf out = null; - ByteBuf in = (ByteBuf)source(); - out.writeBytes(in, 0, 0); - sink(out); // $ hasTaintFlow - } - { - // "io.netty.buffer;ByteBuf;true;writeBytes;;;Argument[0];Argument[-1];taint;manual" - SwappedByteBuf out = null; - ByteBuffer in = (ByteBuffer)source(); - out.writeBytes(in); - sink(out); // $ hasTaintFlow - } - { - // "io.netty.buffer;ByteBuf;true;writeBytes;;;Argument[0];Argument[-1];taint;manual" - SwappedByteBuf out = null; - FileChannel in = (FileChannel)source(); - out.writeBytes(in, 0L, 0); - sink(out); // $ hasTaintFlow - } - { - // "io.netty.buffer;ByteBuf;true;writeBytes;;;Argument[0];Argument[-1];taint;manual" - SwappedByteBuf out = null; - InputStream in = (InputStream)source(); - out.writeBytes(in, 0); - sink(out); // $ hasTaintFlow - } - { - // "io.netty.buffer;ByteBuf;true;writeBytes;;;Argument[0];Argument[-1];taint;manual" - SwappedByteBuf out = null; - ScatteringByteChannel in = (ScatteringByteChannel)source(); - out.writeBytes(in, 0); - sink(out); // $ hasTaintFlow - } - { - // "io.netty.buffer;ByteBuf;true;writeBytes;;;Argument[0];Argument[-1];taint;manual" - SwappedByteBuf out = null; - byte[] in = (byte[])source(); - out.writeBytes(in); - sink(out); // $ hasTaintFlow - } - { - // "io.netty.buffer;ByteBuf;true;writeBytes;;;Argument[0];Argument[-1];taint;manual" + // "io.netty.buffer;ByteBuf;true;writeBytes;(byte[],int,int);;Argument[0];Argument[-1];taint;manual" SwappedByteBuf out = null; byte[] in = (byte[])source(); out.writeBytes(in, 0, 0); @@ -3366,45 +2917,24 @@ public class Test { sink(out); // $ hasTaintFlow } { - // "io.netty.buffer;ByteBuf;true;writeCharSequence;;;Argument[-1];ReturnValue;value;manual" - int out = null; - AbstractByteBuf in = (AbstractByteBuf)source(); - out = in.writeCharSequence(null, null); - sink(out); // $ hasValueFlow - } - { - // "io.netty.buffer;ByteBuf;true;writeCharSequence;;;Argument[-1];ReturnValue;value;manual" - int out = null; - ByteBuf in = (ByteBuf)source(); - out = in.writeCharSequence(null, null); - sink(out); // $ hasValueFlow - } - { - // "io.netty.buffer;ByteBuf;true;writeCharSequence;;;Argument[-1];ReturnValue;value;manual" - int out = null; - SwappedByteBuf in = (SwappedByteBuf)source(); - out = in.writeCharSequence(null, null); - sink(out); // $ hasValueFlow - } - { - // "io.netty.buffer;ByteBuf;true;writeCharSequence;;;Argument[1];Argument[-1];taint;manual" + // "io.netty.buffer;ByteBuf;true;writeCharSequence;;;Argument[0];Argument[-1];taint;manual" AbstractByteBuf out = null; - Charset in = (Charset)source(); - out.writeCharSequence(null, in); + CharSequence in = (CharSequence)source(); + out.writeCharSequence(in, null); sink(out); // $ hasTaintFlow } { - // "io.netty.buffer;ByteBuf;true;writeCharSequence;;;Argument[1];Argument[-1];taint;manual" + // "io.netty.buffer;ByteBuf;true;writeCharSequence;;;Argument[0];Argument[-1];taint;manual" ByteBuf out = null; - Charset in = (Charset)source(); - out.writeCharSequence(null, in); + CharSequence in = (CharSequence)source(); + out.writeCharSequence(in, null); sink(out); // $ hasTaintFlow } { - // "io.netty.buffer;ByteBuf;true;writeCharSequence;;;Argument[1];Argument[-1];taint;manual" + // "io.netty.buffer;ByteBuf;true;writeCharSequence;;;Argument[0];Argument[-1];taint;manual" SwappedByteBuf out = null; - Charset in = (Charset)source(); - out.writeCharSequence(null, in); + CharSequence in = (CharSequence)source(); + out.writeCharSequence(in, null); sink(out); // $ hasTaintFlow } { @@ -4283,63 +3813,63 @@ public class Test { sink(out); // $ hasTaintFlow } { - // "io.netty.handler.codec.http.multipart;HttpPostMultipartRequestDecoder;true;HttpPostMultipartRequestDecoder;(HttpDataFactory,HttpRequest);;Argument[1];ReturnValue;taint;manual" + // "io.netty.handler.codec.http.multipart;HttpPostMultipartRequestDecoder;true;HttpPostMultipartRequestDecoder;(HttpDataFactory,HttpRequest);;Argument[1];Argument[-1];taint;manual" HttpPostMultipartRequestDecoder out = null; HttpRequest in = (HttpRequest)source(); out = new HttpPostMultipartRequestDecoder(null, in); sink(out); // $ hasTaintFlow } { - // "io.netty.handler.codec.http.multipart;HttpPostMultipartRequestDecoder;true;HttpPostMultipartRequestDecoder;(HttpDataFactory,HttpRequest,Charset);;Argument[1];ReturnValue;taint;manual" + // "io.netty.handler.codec.http.multipart;HttpPostMultipartRequestDecoder;true;HttpPostMultipartRequestDecoder;(HttpDataFactory,HttpRequest,Charset);;Argument[1];Argument[-1];taint;manual" HttpPostMultipartRequestDecoder out = null; HttpRequest in = (HttpRequest)source(); out = new HttpPostMultipartRequestDecoder(null, in, null); sink(out); // $ hasTaintFlow } { - // "io.netty.handler.codec.http.multipart;HttpPostMultipartRequestDecoder;true;HttpPostMultipartRequestDecoder;(HttpRequest);;Argument[0];ReturnValue;taint;manual" + // "io.netty.handler.codec.http.multipart;HttpPostMultipartRequestDecoder;true;HttpPostMultipartRequestDecoder;(HttpRequest);;Argument[0];Argument[-1];taint;manual" HttpPostMultipartRequestDecoder out = null; HttpRequest in = (HttpRequest)source(); out = new HttpPostMultipartRequestDecoder(in); sink(out); // $ hasTaintFlow } { - // "io.netty.handler.codec.http.multipart;HttpPostRequestDecoder;true;HttpPostRequestDecoder;(HttpDataFactory,HttpRequest);;Argument[1];ReturnValue;taint;manual" + // "io.netty.handler.codec.http.multipart;HttpPostRequestDecoder;true;HttpPostRequestDecoder;(HttpDataFactory,HttpRequest);;Argument[1];Argument[-1];taint;manual" HttpPostRequestDecoder out = null; HttpRequest in = (HttpRequest)source(); out = new HttpPostRequestDecoder(null, in); sink(out); // $ hasTaintFlow } { - // "io.netty.handler.codec.http.multipart;HttpPostRequestDecoder;true;HttpPostRequestDecoder;(HttpDataFactory,HttpRequest,Charset);;Argument[1];ReturnValue;taint;manual" + // "io.netty.handler.codec.http.multipart;HttpPostRequestDecoder;true;HttpPostRequestDecoder;(HttpDataFactory,HttpRequest,Charset);;Argument[1];Argument[-1];taint;manual" HttpPostRequestDecoder out = null; HttpRequest in = (HttpRequest)source(); out = new HttpPostRequestDecoder(null, in, null); sink(out); // $ hasTaintFlow } { - // "io.netty.handler.codec.http.multipart;HttpPostRequestDecoder;true;HttpPostRequestDecoder;(HttpRequest);;Argument[0];ReturnValue;taint;manual" + // "io.netty.handler.codec.http.multipart;HttpPostRequestDecoder;true;HttpPostRequestDecoder;(HttpRequest);;Argument[0];Argument[-1];taint;manual" HttpPostRequestDecoder out = null; HttpRequest in = (HttpRequest)source(); out = new HttpPostRequestDecoder(in); sink(out); // $ hasTaintFlow } { - // "io.netty.handler.codec.http.multipart;HttpPostStandardRequestDecoder;true;HttpPostStandardRequestDecoder;(HttpDataFactory,HttpRequest);;Argument[1];ReturnValue;taint;manual" + // "io.netty.handler.codec.http.multipart;HttpPostStandardRequestDecoder;true;HttpPostStandardRequestDecoder;(HttpDataFactory,HttpRequest);;Argument[1];Argument[-1];taint;manual" HttpPostStandardRequestDecoder out = null; HttpRequest in = (HttpRequest)source(); out = new HttpPostStandardRequestDecoder(null, in); sink(out); // $ hasTaintFlow } { - // "io.netty.handler.codec.http.multipart;HttpPostStandardRequestDecoder;true;HttpPostStandardRequestDecoder;(HttpDataFactory,HttpRequest,Charset);;Argument[1];ReturnValue;taint;manual" + // "io.netty.handler.codec.http.multipart;HttpPostStandardRequestDecoder;true;HttpPostStandardRequestDecoder;(HttpDataFactory,HttpRequest,Charset);;Argument[1];Argument[-1];taint;manual" HttpPostStandardRequestDecoder out = null; HttpRequest in = (HttpRequest)source(); out = new HttpPostStandardRequestDecoder(null, in, null); sink(out); // $ hasTaintFlow } { - // "io.netty.handler.codec.http.multipart;HttpPostStandardRequestDecoder;true;HttpPostStandardRequestDecoder;(HttpRequest);;Argument[0];ReturnValue;taint;manual" + // "io.netty.handler.codec.http.multipart;HttpPostStandardRequestDecoder;true;HttpPostStandardRequestDecoder;(HttpRequest);;Argument[0];Argument[-1];taint;manual" HttpPostStandardRequestDecoder out = null; HttpRequest in = (HttpRequest)source(); out = new HttpPostStandardRequestDecoder(in); @@ -4886,70 +4416,70 @@ public class Test { sink(out); // $ hasTaintFlow } { - // "io.netty.handler.codec.http;QueryStringDecoder;true;QueryStringDecoder;;;Argument[0];ReturnValue;taint;manual" + // "io.netty.handler.codec.http;QueryStringDecoder;true;QueryStringDecoder;;;Argument[0];Argument[-1];taint;manual" QueryStringDecoder out = null; String in = (String)source(); out = new QueryStringDecoder(in); sink(out); // $ hasTaintFlow } { - // "io.netty.handler.codec.http;QueryStringDecoder;true;QueryStringDecoder;;;Argument[0];ReturnValue;taint;manual" + // "io.netty.handler.codec.http;QueryStringDecoder;true;QueryStringDecoder;;;Argument[0];Argument[-1];taint;manual" QueryStringDecoder out = null; String in = (String)source(); out = new QueryStringDecoder(in, (Charset)null); sink(out); // $ hasTaintFlow } { - // "io.netty.handler.codec.http;QueryStringDecoder;true;QueryStringDecoder;;;Argument[0];ReturnValue;taint;manual" + // "io.netty.handler.codec.http;QueryStringDecoder;true;QueryStringDecoder;;;Argument[0];Argument[-1];taint;manual" QueryStringDecoder out = null; String in = (String)source(); out = new QueryStringDecoder(in, (Charset)null, false); sink(out); // $ hasTaintFlow } { - // "io.netty.handler.codec.http;QueryStringDecoder;true;QueryStringDecoder;;;Argument[0];ReturnValue;taint;manual" + // "io.netty.handler.codec.http;QueryStringDecoder;true;QueryStringDecoder;;;Argument[0];Argument[-1];taint;manual" QueryStringDecoder out = null; String in = (String)source(); out = new QueryStringDecoder(in, (Charset)null, false, 0); sink(out); // $ hasTaintFlow } { - // "io.netty.handler.codec.http;QueryStringDecoder;true;QueryStringDecoder;;;Argument[0];ReturnValue;taint;manual" + // "io.netty.handler.codec.http;QueryStringDecoder;true;QueryStringDecoder;;;Argument[0];Argument[-1];taint;manual" QueryStringDecoder out = null; String in = (String)source(); out = new QueryStringDecoder(in, false); sink(out); // $ hasTaintFlow } { - // "io.netty.handler.codec.http;QueryStringDecoder;true;QueryStringDecoder;;;Argument[0];ReturnValue;taint;manual" + // "io.netty.handler.codec.http;QueryStringDecoder;true;QueryStringDecoder;;;Argument[0];Argument[-1];taint;manual" QueryStringDecoder out = null; String in = (String)source(); out = new QueryStringDecoder(in, null, false, 0, false); sink(out); // $ hasTaintFlow } { - // "io.netty.handler.codec.http;QueryStringDecoder;true;QueryStringDecoder;;;Argument[0];ReturnValue;taint;manual" + // "io.netty.handler.codec.http;QueryStringDecoder;true;QueryStringDecoder;;;Argument[0];Argument[-1];taint;manual" QueryStringDecoder out = null; URI in = (URI)source(); out = new QueryStringDecoder(in); sink(out); // $ hasTaintFlow } { - // "io.netty.handler.codec.http;QueryStringDecoder;true;QueryStringDecoder;;;Argument[0];ReturnValue;taint;manual" + // "io.netty.handler.codec.http;QueryStringDecoder;true;QueryStringDecoder;;;Argument[0];Argument[-1];taint;manual" QueryStringDecoder out = null; URI in = (URI)source(); out = new QueryStringDecoder(in, (Charset)null); sink(out); // $ hasTaintFlow } { - // "io.netty.handler.codec.http;QueryStringDecoder;true;QueryStringDecoder;;;Argument[0];ReturnValue;taint;manual" + // "io.netty.handler.codec.http;QueryStringDecoder;true;QueryStringDecoder;;;Argument[0];Argument[-1];taint;manual" QueryStringDecoder out = null; URI in = (URI)source(); out = new QueryStringDecoder(in, (Charset)null, 0); sink(out); // $ hasTaintFlow } { - // "io.netty.handler.codec.http;QueryStringDecoder;true;QueryStringDecoder;;;Argument[0];ReturnValue;taint;manual" + // "io.netty.handler.codec.http;QueryStringDecoder;true;QueryStringDecoder;;;Argument[0];Argument[-1];taint;manual" QueryStringDecoder out = null; URI in = (URI)source(); out = new QueryStringDecoder(in, (Charset)null, 0, false); diff --git a/java/ql/test/stubs/netty-4.1.x/io/netty/buffer/DefaultByteBufHolder.java b/java/ql/test/stubs/netty-4.1.x/io/netty/buffer/DefaultByteBufHolder.java new file mode 100644 index 00000000000..5da3e0ad3ce --- /dev/null +++ b/java/ql/test/stubs/netty-4.1.x/io/netty/buffer/DefaultByteBufHolder.java @@ -0,0 +1,28 @@ +// Generated automatically from io.netty.buffer.DefaultByteBufHolder for testing purposes + +package io.netty.buffer; + +import io.netty.buffer.ByteBuf; +import io.netty.buffer.ByteBufHolder; + +public class DefaultByteBufHolder implements ByteBufHolder +{ + protected DefaultByteBufHolder() {} + protected final String contentToString(){ return null; } + public ByteBuf content(){ return null; } + public ByteBufHolder copy(){ return null; } + public ByteBufHolder duplicate(){ return null; } + public ByteBufHolder replace(ByteBuf p0){ return null; } + public ByteBufHolder retain(){ return null; } + public ByteBufHolder retain(int p0){ return null; } + public ByteBufHolder retainedDuplicate(){ return null; } + public ByteBufHolder touch(){ return null; } + public ByteBufHolder touch(Object p0){ return null; } + public DefaultByteBufHolder(ByteBuf p0){} + public String toString(){ return null; } + public boolean equals(Object p0){ return false; } + public boolean release(){ return false; } + public boolean release(int p0){ return false; } + public int hashCode(){ return 0; } + public int refCnt(){ return 0; } +} diff --git a/java/ql/test/stubs/netty-4.1.x/io/netty/channel/DefaultFileRegion.java b/java/ql/test/stubs/netty-4.1.x/io/netty/channel/DefaultFileRegion.java new file mode 100644 index 00000000000..1532bcdb192 --- /dev/null +++ b/java/ql/test/stubs/netty-4.1.x/io/netty/channel/DefaultFileRegion.java @@ -0,0 +1,28 @@ +// Generated automatically from io.netty.channel.DefaultFileRegion for testing purposes + +package io.netty.channel; + +import io.netty.channel.FileRegion; +import io.netty.util.AbstractReferenceCounted; +import java.io.File; +import java.nio.channels.FileChannel; +import java.nio.channels.WritableByteChannel; + +public class DefaultFileRegion extends AbstractReferenceCounted implements FileRegion +{ + protected DefaultFileRegion() {} + protected void deallocate(){} + public DefaultFileRegion(File p0, long p1, long p2){} + public DefaultFileRegion(FileChannel p0, long p1, long p2){} + public FileRegion retain(){ return null; } + public FileRegion retain(int p0){ return null; } + public FileRegion touch(){ return null; } + public FileRegion touch(Object p0){ return null; } + public boolean isOpen(){ return false; } + public long count(){ return 0; } + public long position(){ return 0; } + public long transferTo(WritableByteChannel p0, long p1){ return 0; } + public long transfered(){ return 0; } + public long transferred(){ return 0; } + public void open(){} +} diff --git a/java/ql/test/stubs/netty-4.1.x/io/netty/channel/FileRegion.java b/java/ql/test/stubs/netty-4.1.x/io/netty/channel/FileRegion.java new file mode 100644 index 00000000000..36cce9c0547 --- /dev/null +++ b/java/ql/test/stubs/netty-4.1.x/io/netty/channel/FileRegion.java @@ -0,0 +1,19 @@ +// Generated automatically from io.netty.channel.FileRegion for testing purposes + +package io.netty.channel; + +import io.netty.util.ReferenceCounted; +import java.nio.channels.WritableByteChannel; + +public interface FileRegion extends ReferenceCounted +{ + FileRegion retain(); + FileRegion retain(int p0); + FileRegion touch(); + FileRegion touch(Object p0); + long count(); + long position(); + long transferTo(WritableByteChannel p0, long p1); + long transfered(); + long transferred(); +} diff --git a/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/Headers.java b/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/Headers.java index 98830019ac1..3362deafdb5 100644 --- a/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/Headers.java +++ b/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/Headers.java @@ -7,7 +7,7 @@ import java.util.List; import java.util.Map; import java.util.Set; -public interface Headers<K, V, T extends Headers<K, V, T>> extends Iterable<Map.Entry<K, V>> +public interface Headers<K, V, T extends Headers<K, V, T>> extends java.lang.Iterable<Map.Entry<K, V>> { Boolean getBoolean(K p0); Boolean getBooleanAndRemove(K p0); @@ -21,14 +21,12 @@ public interface Headers<K, V, T extends Headers<K, V, T>> extends Iterable<Map. Float getFloatAndRemove(K p0); Integer getInt(K p0); Integer getIntAndRemove(K p0); - Iterator<Map.Entry<K, V>> iterator(); List<V> getAll(K p0); List<V> getAllAndRemove(K p0); Long getLong(K p0); Long getLongAndRemove(K p0); Long getTimeMillis(K p0); Long getTimeMillisAndRemove(K p0); - Set<K> names(); Short getShort(K p0); Short getShortAndRemove(K p0); T add(Headers<? extends K, ? extends V, ? extends Object> p0); @@ -96,6 +94,8 @@ public interface Headers<K, V, T extends Headers<K, V, T>> extends Iterable<Map. int getInt(K p0, int p1); int getIntAndRemove(K p0, int p1); int size(); + java.util.Iterator<Map.Entry<K, V>> iterator(); + java.util.Set<K> names(); long getLong(K p0, long p1); long getLongAndRemove(K p0, long p1); long getTimeMillis(K p0, long p1); diff --git a/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/HeadersUtils.java b/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/HeadersUtils.java new file mode 100644 index 00000000000..7746d808d68 --- /dev/null +++ b/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/HeadersUtils.java @@ -0,0 +1,19 @@ +// Generated automatically from io.netty.handler.codec.HeadersUtils for testing purposes + +package io.netty.handler.codec; + +import io.netty.handler.codec.Headers; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; + +public class HeadersUtils +{ + protected HeadersUtils() {} + public static <K, V> List<String> getAllAsString(io.netty.handler.codec.Headers<K, V, ? extends Object> p0, K p1){ return null; } + public static <K, V> String getAsString(io.netty.handler.codec.Headers<K, V, ? extends Object> p0, K p1){ return null; } + public static <K, V> String toString(Class<? extends Object> p0, java.util.Iterator<Map.Entry<K, V>> p1, int p2){ return null; } + public static Iterator<Map.Entry<String, String>> iteratorAsString(Iterable<Map.Entry<CharSequence, CharSequence>> p0){ return null; } + public static Set<String> namesAsString(Headers<CharSequence, CharSequence, ? extends Object> p0){ return null; } +} diff --git a/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/base64/Base64.java b/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/base64/Base64.java new file mode 100644 index 00000000000..57b87267320 --- /dev/null +++ b/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/base64/Base64.java @@ -0,0 +1,26 @@ +// Generated automatically from io.netty.handler.codec.base64.Base64 for testing purposes + +package io.netty.handler.codec.base64; + +import io.netty.buffer.ByteBuf; +import io.netty.buffer.ByteBufAllocator; +import io.netty.handler.codec.base64.Base64Dialect; + +public class Base64 +{ + protected Base64() {} + public static ByteBuf decode(ByteBuf p0){ return null; } + public static ByteBuf decode(ByteBuf p0, Base64Dialect p1){ return null; } + public static ByteBuf decode(ByteBuf p0, int p1, int p2){ return null; } + public static ByteBuf decode(ByteBuf p0, int p1, int p2, Base64Dialect p3){ return null; } + public static ByteBuf decode(ByteBuf p0, int p1, int p2, Base64Dialect p3, ByteBufAllocator p4){ return null; } + public static ByteBuf encode(ByteBuf p0){ return null; } + public static ByteBuf encode(ByteBuf p0, Base64Dialect p1){ return null; } + public static ByteBuf encode(ByteBuf p0, boolean p1){ return null; } + public static ByteBuf encode(ByteBuf p0, boolean p1, Base64Dialect p2){ return null; } + public static ByteBuf encode(ByteBuf p0, int p1, int p2){ return null; } + public static ByteBuf encode(ByteBuf p0, int p1, int p2, Base64Dialect p3){ return null; } + public static ByteBuf encode(ByteBuf p0, int p1, int p2, boolean p3){ return null; } + public static ByteBuf encode(ByteBuf p0, int p1, int p2, boolean p3, Base64Dialect p4){ return null; } + public static ByteBuf encode(ByteBuf p0, int p1, int p2, boolean p3, Base64Dialect p4, ByteBufAllocator p5){ return null; } +} diff --git a/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/base64/Base64Dialect.java b/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/base64/Base64Dialect.java new file mode 100644 index 00000000000..3c2c5740384 --- /dev/null +++ b/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/base64/Base64Dialect.java @@ -0,0 +1,10 @@ +// Generated automatically from io.netty.handler.codec.base64.Base64Dialect for testing purposes + +package io.netty.handler.codec.base64; + + +public enum Base64Dialect +{ + ORDERED, STANDARD, URL_SAFE; + private Base64Dialect() {} +} diff --git a/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http/FullHttpResponse.java b/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http/FullHttpResponse.java new file mode 100644 index 00000000000..777c5f2b9b0 --- /dev/null +++ b/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http/FullHttpResponse.java @@ -0,0 +1,23 @@ +// Generated automatically from io.netty.handler.codec.http.FullHttpResponse for testing purposes + +package io.netty.handler.codec.http; + +import io.netty.buffer.ByteBuf; +import io.netty.handler.codec.http.FullHttpMessage; +import io.netty.handler.codec.http.HttpResponse; +import io.netty.handler.codec.http.HttpResponseStatus; +import io.netty.handler.codec.http.HttpVersion; + +public interface FullHttpResponse extends FullHttpMessage, HttpResponse +{ + FullHttpResponse copy(); + FullHttpResponse duplicate(); + FullHttpResponse replace(ByteBuf p0); + FullHttpResponse retain(); + FullHttpResponse retain(int p0); + FullHttpResponse retainedDuplicate(); + FullHttpResponse setProtocolVersion(HttpVersion p0); + FullHttpResponse setStatus(HttpResponseStatus p0); + FullHttpResponse touch(); + FullHttpResponse touch(Object p0); +} diff --git a/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http/HttpResponse.java b/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http/HttpResponse.java new file mode 100644 index 00000000000..8026bc00843 --- /dev/null +++ b/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http/HttpResponse.java @@ -0,0 +1,15 @@ +// Generated automatically from io.netty.handler.codec.http.HttpResponse for testing purposes + +package io.netty.handler.codec.http; + +import io.netty.handler.codec.http.HttpMessage; +import io.netty.handler.codec.http.HttpResponseStatus; +import io.netty.handler.codec.http.HttpVersion; + +public interface HttpResponse extends HttpMessage +{ + HttpResponse setProtocolVersion(HttpVersion p0); + HttpResponse setStatus(HttpResponseStatus p0); + HttpResponseStatus getStatus(); + HttpResponseStatus status(); +} diff --git a/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http/HttpResponseStatus.java b/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http/HttpResponseStatus.java new file mode 100644 index 00000000000..777d3a946e4 --- /dev/null +++ b/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http/HttpResponseStatus.java @@ -0,0 +1,82 @@ +// Generated automatically from io.netty.handler.codec.http.HttpResponseStatus for testing purposes + +package io.netty.handler.codec.http; + +import io.netty.handler.codec.http.HttpStatusClass; +import io.netty.util.AsciiString; + +public class HttpResponseStatus implements Comparable<HttpResponseStatus> +{ + protected HttpResponseStatus() {} + public AsciiString codeAsText(){ return null; } + public HttpResponseStatus(int p0, String p1){} + public HttpStatusClass codeClass(){ return null; } + public String reasonPhrase(){ return null; } + public String toString(){ return null; } + public boolean equals(Object p0){ return false; } + public int code(){ return 0; } + public int compareTo(HttpResponseStatus p0){ return 0; } + public int hashCode(){ return 0; } + public static HttpResponseStatus ACCEPTED = null; + public static HttpResponseStatus BAD_GATEWAY = null; + public static HttpResponseStatus BAD_REQUEST = null; + public static HttpResponseStatus CONFLICT = null; + public static HttpResponseStatus CONTINUE = null; + public static HttpResponseStatus CREATED = null; + public static HttpResponseStatus EARLY_HINTS = null; + public static HttpResponseStatus EXPECTATION_FAILED = null; + public static HttpResponseStatus FAILED_DEPENDENCY = null; + public static HttpResponseStatus FORBIDDEN = null; + public static HttpResponseStatus FOUND = null; + public static HttpResponseStatus GATEWAY_TIMEOUT = null; + public static HttpResponseStatus GONE = null; + public static HttpResponseStatus HTTP_VERSION_NOT_SUPPORTED = null; + public static HttpResponseStatus INSUFFICIENT_STORAGE = null; + public static HttpResponseStatus INTERNAL_SERVER_ERROR = null; + public static HttpResponseStatus LENGTH_REQUIRED = null; + public static HttpResponseStatus LOCKED = null; + public static HttpResponseStatus METHOD_NOT_ALLOWED = null; + public static HttpResponseStatus MISDIRECTED_REQUEST = null; + public static HttpResponseStatus MOVED_PERMANENTLY = null; + public static HttpResponseStatus MULTIPLE_CHOICES = null; + public static HttpResponseStatus MULTI_STATUS = null; + public static HttpResponseStatus NETWORK_AUTHENTICATION_REQUIRED = null; + public static HttpResponseStatus NON_AUTHORITATIVE_INFORMATION = null; + public static HttpResponseStatus NOT_ACCEPTABLE = null; + public static HttpResponseStatus NOT_EXTENDED = null; + public static HttpResponseStatus NOT_FOUND = null; + public static HttpResponseStatus NOT_IMPLEMENTED = null; + public static HttpResponseStatus NOT_MODIFIED = null; + public static HttpResponseStatus NO_CONTENT = null; + public static HttpResponseStatus OK = null; + public static HttpResponseStatus PARTIAL_CONTENT = null; + public static HttpResponseStatus PAYMENT_REQUIRED = null; + public static HttpResponseStatus PERMANENT_REDIRECT = null; + public static HttpResponseStatus PRECONDITION_FAILED = null; + public static HttpResponseStatus PRECONDITION_REQUIRED = null; + public static HttpResponseStatus PROCESSING = null; + public static HttpResponseStatus PROXY_AUTHENTICATION_REQUIRED = null; + public static HttpResponseStatus REQUESTED_RANGE_NOT_SATISFIABLE = null; + public static HttpResponseStatus REQUEST_ENTITY_TOO_LARGE = null; + public static HttpResponseStatus REQUEST_HEADER_FIELDS_TOO_LARGE = null; + public static HttpResponseStatus REQUEST_TIMEOUT = null; + public static HttpResponseStatus REQUEST_URI_TOO_LONG = null; + public static HttpResponseStatus RESET_CONTENT = null; + public static HttpResponseStatus SEE_OTHER = null; + public static HttpResponseStatus SERVICE_UNAVAILABLE = null; + public static HttpResponseStatus SWITCHING_PROTOCOLS = null; + public static HttpResponseStatus TEMPORARY_REDIRECT = null; + public static HttpResponseStatus TOO_MANY_REQUESTS = null; + public static HttpResponseStatus UNAUTHORIZED = null; + public static HttpResponseStatus UNORDERED_COLLECTION = null; + public static HttpResponseStatus UNPROCESSABLE_ENTITY = null; + public static HttpResponseStatus UNSUPPORTED_MEDIA_TYPE = null; + public static HttpResponseStatus UPGRADE_REQUIRED = null; + public static HttpResponseStatus USE_PROXY = null; + public static HttpResponseStatus VARIANT_ALSO_NEGOTIATES = null; + public static HttpResponseStatus parseLine(AsciiString p0){ return null; } + public static HttpResponseStatus parseLine(CharSequence p0){ return null; } + public static HttpResponseStatus parseLine(String p0){ return null; } + public static HttpResponseStatus valueOf(int p0){ return null; } + public static HttpResponseStatus valueOf(int p0, String p1){ return null; } +} diff --git a/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http/HttpStatusClass.java b/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http/HttpStatusClass.java new file mode 100644 index 00000000000..15516633bf2 --- /dev/null +++ b/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http/HttpStatusClass.java @@ -0,0 +1,11 @@ +// Generated automatically from io.netty.handler.codec.http.HttpStatusClass for testing purposes + +package io.netty.handler.codec.http; + + +public enum HttpStatusClass +{ + CLIENT_ERROR, INFORMATIONAL, REDIRECTION, SERVER_ERROR, SUCCESS, UNKNOWN; + private HttpStatusClass() {} + public boolean contains(int p0){ return false; } +} diff --git a/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http/QueryStringDecoder.java b/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http/QueryStringDecoder.java new file mode 100644 index 00000000000..f2d25b3b9f9 --- /dev/null +++ b/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http/QueryStringDecoder.java @@ -0,0 +1,31 @@ +// Generated automatically from io.netty.handler.codec.http.QueryStringDecoder for testing purposes + +package io.netty.handler.codec.http; + +import java.net.URI; +import java.nio.charset.Charset; +import java.util.List; +import java.util.Map; + +public class QueryStringDecoder +{ + protected QueryStringDecoder() {} + public Map<String, List<String>> parameters(){ return null; } + public QueryStringDecoder(String p0){} + public QueryStringDecoder(String p0, Charset p1){} + public QueryStringDecoder(String p0, Charset p1, boolean p2){} + public QueryStringDecoder(String p0, Charset p1, boolean p2, int p3){} + public QueryStringDecoder(String p0, Charset p1, boolean p2, int p3, boolean p4){} + public QueryStringDecoder(String p0, boolean p1){} + public QueryStringDecoder(URI p0){} + public QueryStringDecoder(URI p0, Charset p1){} + public QueryStringDecoder(URI p0, Charset p1, int p2){} + public QueryStringDecoder(URI p0, Charset p1, int p2, boolean p3){} + public String path(){ return null; } + public String rawPath(){ return null; } + public String rawQuery(){ return null; } + public String toString(){ return null; } + public String uri(){ return null; } + public static String decodeComponent(String p0){ return null; } + public static String decodeComponent(String p0, Charset p1){ return null; } +} diff --git a/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http/cookie/Cookie.java b/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http/cookie/Cookie.java index ecb0c689438..8bc8766fe18 100644 --- a/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http/cookie/Cookie.java +++ b/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http/cookie/Cookie.java @@ -1,146 +1,24 @@ -/* - * Copyright 2015 The Netty Project - * - * The Netty Project licenses this file to you under the Apache License, - * version 2.0 (the "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at: - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - */ +// Generated automatically from io.netty.handler.codec.http.cookie.Cookie for testing purposes + package io.netty.handler.codec.http.cookie; -/** - * An interface defining an - * <a href="https://en.wikipedia.org/wiki/HTTP_cookie">HTTP cookie</a>. - */ -public interface Cookie extends Comparable<Cookie> { - /** - * Constant for undefined MaxAge attribute value. - */ - long UNDEFINED_MAX_AGE = Long.MIN_VALUE; - - /** - * Returns the name of this {@link Cookie}. - * - * @return The name of this {@link Cookie} - */ - String name(); - - /** - * Returns the value of this {@link Cookie}. - * - * @return The value of this {@link Cookie} - */ - String value(); - - /** - * Sets the value of this {@link Cookie}. - * - * @param value The value to set - */ - void setValue(String value); - - /** - * Returns true if the raw value of this {@link Cookie}, - * was wrapped with double quotes in original Set-Cookie header. - * - * @return If the value of this {@link Cookie} is to be wrapped - */ - boolean wrap(); - - /** - * Sets true if the value of this {@link Cookie} - * is to be wrapped with double quotes. - * - * @param wrap true if wrap - */ - void setWrap(boolean wrap); - - /** - * Returns the domain of this {@link Cookie}. - * - * @return The domain of this {@link Cookie} - */ +public interface Cookie extends Comparable<Cookie> +{ String domain(); - - /** - * Sets the domain of this {@link Cookie}. - * - * @param domain The domain to use - */ - void setDomain(String domain); - - /** - * Returns the path of this {@link Cookie}. - * - * @return The {@link Cookie}'s path - */ + String name(); String path(); - - /** - * Sets the path of this {@link Cookie}. - * - * @param path The path to use for this {@link Cookie} - */ - void setPath(String path); - - /** - * Returns the maximum age of this {@link Cookie} in seconds or {@link Cookie#UNDEFINED_MAX_AGE} if unspecified - * - * @return The maximum age of this {@link Cookie} - */ - long maxAge(); - - /** - * Sets the maximum age of this {@link Cookie} in seconds. - * If an age of {@code 0} is specified, this {@link Cookie} will be - * automatically removed by browser because it will expire immediately. - * If {@link Cookie#UNDEFINED_MAX_AGE} is specified, this {@link Cookie} will be removed when the - * browser is closed. - * - * @param maxAge The maximum age of this {@link Cookie} in seconds - */ - void setMaxAge(long maxAge); - - /** - * Checks to see if this {@link Cookie} is secure - * - * @return True if this {@link Cookie} is secure, otherwise false - */ - boolean isSecure(); - - /** - * Sets the security getStatus of this {@link Cookie} - * - * @param secure True if this {@link Cookie} is to be secure, otherwise false - */ - void setSecure(boolean secure); - - /** - * Checks to see if this {@link Cookie} can only be accessed via HTTP. - * If this returns true, the {@link Cookie} cannot be accessed through - * client side script - But only if the browser supports it. - * For more information, please look <a href="https://owasp.org/www-community/HttpOnly">here</a> - * - * @return True if this {@link Cookie} is HTTP-only or false if it isn't - */ + String value(); boolean isHttpOnly(); - - /** - * Determines if this {@link Cookie} is HTTP only. - * If set to true, this {@link Cookie} cannot be accessed by a client - * side script. However, this works only if the browser supports it. - * For for information, please look - * <a href="https://owasp.org/www-community/HttpOnly">here</a>. - * - * @param httpOnly True if the {@link Cookie} is HTTP only, otherwise false. - */ - void setHttpOnly(boolean httpOnly); -} \ No newline at end of file + boolean isSecure(); + boolean wrap(); + long maxAge(); + static long UNDEFINED_MAX_AGE = 0; + void setDomain(String p0); + void setHttpOnly(boolean p0); + void setMaxAge(long p0); + void setPath(String p0); + void setSecure(boolean p0); + void setValue(String p0); + void setWrap(boolean p0); +} diff --git a/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http/cookie/CookieDecoder.java b/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http/cookie/CookieDecoder.java new file mode 100644 index 00000000000..294da25f15c --- /dev/null +++ b/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http/cookie/CookieDecoder.java @@ -0,0 +1,12 @@ +// Generated automatically from io.netty.handler.codec.http.cookie.CookieDecoder for testing purposes + +package io.netty.handler.codec.http.cookie; + +import io.netty.handler.codec.http.cookie.DefaultCookie; + +abstract public class CookieDecoder +{ + protected CookieDecoder() {} + protected CookieDecoder(boolean p0){} + protected DefaultCookie initCookie(String p0, int p1, int p2, int p3, int p4){ return null; } +} diff --git a/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http/cookie/CookieHeaderNames.java b/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http/cookie/CookieHeaderNames.java new file mode 100644 index 00000000000..432eb7e7ec0 --- /dev/null +++ b/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http/cookie/CookieHeaderNames.java @@ -0,0 +1,21 @@ +// Generated automatically from io.netty.handler.codec.http.cookie.CookieHeaderNames for testing purposes + +package io.netty.handler.codec.http.cookie; + + +public class CookieHeaderNames +{ + protected CookieHeaderNames() {} + public static String DOMAIN = null; + public static String EXPIRES = null; + public static String HTTPONLY = null; + public static String MAX_AGE = null; + public static String PATH = null; + public static String SAMESITE = null; + public static String SECURE = null; + static public enum SameSite + { + Lax, None, Strict; + private SameSite() {} + } +} diff --git a/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http/cookie/DefaultCookie.java b/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http/cookie/DefaultCookie.java new file mode 100644 index 00000000000..1a6ced92907 --- /dev/null +++ b/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http/cookie/DefaultCookie.java @@ -0,0 +1,34 @@ +// Generated automatically from io.netty.handler.codec.http.cookie.DefaultCookie for testing purposes + +package io.netty.handler.codec.http.cookie; + +import io.netty.handler.codec.http.cookie.Cookie; +import io.netty.handler.codec.http.cookie.CookieHeaderNames; + +public class DefaultCookie implements Cookie +{ + protected DefaultCookie() {} + protected String validateValue(String p0, String p1){ return null; } + public CookieHeaderNames.SameSite sameSite(){ return null; } + public DefaultCookie(String p0, String p1){} + public String domain(){ return null; } + public String name(){ return null; } + public String path(){ return null; } + public String toString(){ return null; } + public String value(){ return null; } + public boolean equals(Object p0){ return false; } + public boolean isHttpOnly(){ return false; } + public boolean isSecure(){ return false; } + public boolean wrap(){ return false; } + public int compareTo(Cookie p0){ return 0; } + public int hashCode(){ return 0; } + public long maxAge(){ return 0; } + public void setDomain(String p0){} + public void setHttpOnly(boolean p0){} + public void setMaxAge(long p0){} + public void setPath(String p0){} + public void setSameSite(CookieHeaderNames.SameSite p0){} + public void setSecure(boolean p0){} + public void setValue(String p0){} + public void setWrap(boolean p0){} +} diff --git a/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http/cookie/ServerCookieDecoder.java b/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http/cookie/ServerCookieDecoder.java new file mode 100644 index 00000000000..3621d83f597 --- /dev/null +++ b/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http/cookie/ServerCookieDecoder.java @@ -0,0 +1,17 @@ +// Generated automatically from io.netty.handler.codec.http.cookie.ServerCookieDecoder for testing purposes + +package io.netty.handler.codec.http.cookie; + +import io.netty.handler.codec.http.cookie.Cookie; +import io.netty.handler.codec.http.cookie.CookieDecoder; +import java.util.List; +import java.util.Set; + +public class ServerCookieDecoder extends CookieDecoder +{ + protected ServerCookieDecoder() {} + public List<Cookie> decodeAll(String p0){ return null; } + public Set<Cookie> decode(String p0){ return null; } + public static ServerCookieDecoder LAX = null; + public static ServerCookieDecoder STRICT = null; +} diff --git a/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http/multipart/Attribute.java b/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http/multipart/Attribute.java new file mode 100644 index 00000000000..b87dedf1a3f --- /dev/null +++ b/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http/multipart/Attribute.java @@ -0,0 +1,20 @@ +// Generated automatically from io.netty.handler.codec.http.multipart.Attribute for testing purposes + +package io.netty.handler.codec.http.multipart; + +import io.netty.buffer.ByteBuf; +import io.netty.handler.codec.http.multipart.HttpData; + +public interface Attribute extends HttpData +{ + Attribute copy(); + Attribute duplicate(); + Attribute replace(ByteBuf p0); + Attribute retain(); + Attribute retain(int p0); + Attribute retainedDuplicate(); + Attribute touch(); + Attribute touch(Object p0); + String getValue(); + void setValue(String p0); +} diff --git a/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http/multipart/FileUpload.java b/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http/multipart/FileUpload.java new file mode 100644 index 00000000000..5f8c20ad6bb --- /dev/null +++ b/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http/multipart/FileUpload.java @@ -0,0 +1,24 @@ +// Generated automatically from io.netty.handler.codec.http.multipart.FileUpload for testing purposes + +package io.netty.handler.codec.http.multipart; + +import io.netty.buffer.ByteBuf; +import io.netty.handler.codec.http.multipart.HttpData; + +public interface FileUpload extends HttpData +{ + FileUpload copy(); + FileUpload duplicate(); + FileUpload replace(ByteBuf p0); + FileUpload retain(); + FileUpload retain(int p0); + FileUpload retainedDuplicate(); + FileUpload touch(); + FileUpload touch(Object p0); + String getContentTransferEncoding(); + String getContentType(); + String getFilename(); + void setContentTransferEncoding(String p0); + void setContentType(String p0); + void setFilename(String p0); +} diff --git a/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http/multipart/HttpData.java b/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http/multipart/HttpData.java new file mode 100644 index 00000000000..c96054d9173 --- /dev/null +++ b/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http/multipart/HttpData.java @@ -0,0 +1,43 @@ +// Generated automatically from io.netty.handler.codec.http.multipart.HttpData for testing purposes + +package io.netty.handler.codec.http.multipart; + +import io.netty.buffer.ByteBuf; +import io.netty.buffer.ByteBufHolder; +import io.netty.handler.codec.http.multipart.InterfaceHttpData; +import java.io.File; +import java.io.InputStream; +import java.nio.charset.Charset; + +public interface HttpData extends ByteBufHolder, InterfaceHttpData +{ + ByteBuf getByteBuf(); + ByteBuf getChunk(int p0); + Charset getCharset(); + File getFile(); + HttpData copy(); + HttpData duplicate(); + HttpData replace(ByteBuf p0); + HttpData retain(); + HttpData retain(int p0); + HttpData retainedDuplicate(); + HttpData touch(); + HttpData touch(Object p0); + String getString(); + String getString(Charset p0); + boolean isCompleted(); + boolean isInMemory(); + boolean renameTo(File p0); + byte[] get(); + long definedLength(); + long getMaxSize(); + long length(); + void addContent(ByteBuf p0, boolean p1); + void checkSize(long p0); + void delete(); + void setCharset(Charset p0); + void setContent(ByteBuf p0); + void setContent(File p0); + void setContent(InputStream p0); + void setMaxSize(long p0); +} diff --git a/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http/multipart/HttpDataFactory.java b/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http/multipart/HttpDataFactory.java new file mode 100644 index 00000000000..70acdf0a0ff --- /dev/null +++ b/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http/multipart/HttpDataFactory.java @@ -0,0 +1,23 @@ +// Generated automatically from io.netty.handler.codec.http.multipart.HttpDataFactory for testing purposes + +package io.netty.handler.codec.http.multipart; + +import io.netty.handler.codec.http.HttpRequest; +import io.netty.handler.codec.http.multipart.Attribute; +import io.netty.handler.codec.http.multipart.FileUpload; +import io.netty.handler.codec.http.multipart.InterfaceHttpData; +import java.nio.charset.Charset; + +public interface HttpDataFactory +{ + Attribute createAttribute(HttpRequest p0, String p1); + Attribute createAttribute(HttpRequest p0, String p1, String p2); + Attribute createAttribute(HttpRequest p0, String p1, long p2); + FileUpload createFileUpload(HttpRequest p0, String p1, String p2, String p3, String p4, Charset p5, long p6); + void cleanAllHttpData(); + void cleanAllHttpDatas(); + void cleanRequestHttpData(HttpRequest p0); + void cleanRequestHttpDatas(HttpRequest p0); + void removeHttpDataFromClean(HttpRequest p0, InterfaceHttpData p1); + void setMaxLimit(long p0); +} diff --git a/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http/multipart/HttpPostMultipartRequestDecoder.java b/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http/multipart/HttpPostMultipartRequestDecoder.java new file mode 100644 index 00000000000..0b2013b55e6 --- /dev/null +++ b/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http/multipart/HttpPostMultipartRequestDecoder.java @@ -0,0 +1,34 @@ +// Generated automatically from io.netty.handler.codec.http.multipart.HttpPostMultipartRequestDecoder for testing purposes + +package io.netty.handler.codec.http.multipart; + +import io.netty.handler.codec.http.HttpContent; +import io.netty.handler.codec.http.HttpRequest; +import io.netty.handler.codec.http.multipart.HttpDataFactory; +import io.netty.handler.codec.http.multipart.InterfaceHttpData; +import io.netty.handler.codec.http.multipart.InterfaceHttpPostRequestDecoder; +import java.nio.charset.Charset; +import java.util.List; + +public class HttpPostMultipartRequestDecoder implements InterfaceHttpPostRequestDecoder +{ + protected HttpPostMultipartRequestDecoder() {} + protected InterfaceHttpData getFileUpload(String p0){ return null; } + protected void addHttpData(InterfaceHttpData p0){} + public HttpPostMultipartRequestDecoder offer(HttpContent p0){ return null; } + public HttpPostMultipartRequestDecoder(HttpDataFactory p0, HttpRequest p1){} + public HttpPostMultipartRequestDecoder(HttpDataFactory p0, HttpRequest p1, Charset p2){} + public HttpPostMultipartRequestDecoder(HttpRequest p0){} + public InterfaceHttpData currentPartialHttpData(){ return null; } + public InterfaceHttpData getBodyHttpData(String p0){ return null; } + public InterfaceHttpData next(){ return null; } + public List<InterfaceHttpData> getBodyHttpDatas(){ return null; } + public List<InterfaceHttpData> getBodyHttpDatas(String p0){ return null; } + public boolean hasNext(){ return false; } + public boolean isMultipart(){ return false; } + public int getDiscardThreshold(){ return 0; } + public void cleanFiles(){} + public void destroy(){} + public void removeHttpDataFromClean(InterfaceHttpData p0){} + public void setDiscardThreshold(int p0){} +} diff --git a/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http/multipart/HttpPostRequestDecoder.java b/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http/multipart/HttpPostRequestDecoder.java new file mode 100644 index 00000000000..a1b4d59817b --- /dev/null +++ b/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http/multipart/HttpPostRequestDecoder.java @@ -0,0 +1,34 @@ +// Generated automatically from io.netty.handler.codec.http.multipart.HttpPostRequestDecoder for testing purposes + +package io.netty.handler.codec.http.multipart; + +import io.netty.handler.codec.http.HttpContent; +import io.netty.handler.codec.http.HttpRequest; +import io.netty.handler.codec.http.multipart.HttpDataFactory; +import io.netty.handler.codec.http.multipart.InterfaceHttpData; +import io.netty.handler.codec.http.multipart.InterfaceHttpPostRequestDecoder; +import java.nio.charset.Charset; +import java.util.List; + +public class HttpPostRequestDecoder implements InterfaceHttpPostRequestDecoder +{ + protected HttpPostRequestDecoder() {} + protected static String[] getMultipartDataBoundary(String p0){ return null; } + public HttpPostRequestDecoder(HttpDataFactory p0, HttpRequest p1){} + public HttpPostRequestDecoder(HttpDataFactory p0, HttpRequest p1, Charset p2){} + public HttpPostRequestDecoder(HttpRequest p0){} + public InterfaceHttpData currentPartialHttpData(){ return null; } + public InterfaceHttpData getBodyHttpData(String p0){ return null; } + public InterfaceHttpData next(){ return null; } + public InterfaceHttpPostRequestDecoder offer(HttpContent p0){ return null; } + public List<InterfaceHttpData> getBodyHttpDatas(){ return null; } + public List<InterfaceHttpData> getBodyHttpDatas(String p0){ return null; } + public boolean hasNext(){ return false; } + public boolean isMultipart(){ return false; } + public int getDiscardThreshold(){ return 0; } + public static boolean isMultipart(HttpRequest p0){ return false; } + public void cleanFiles(){} + public void destroy(){} + public void removeHttpDataFromClean(InterfaceHttpData p0){} + public void setDiscardThreshold(int p0){} +} diff --git a/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http/multipart/HttpPostStandardRequestDecoder.java b/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http/multipart/HttpPostStandardRequestDecoder.java new file mode 100644 index 00000000000..7b228470faa --- /dev/null +++ b/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http/multipart/HttpPostStandardRequestDecoder.java @@ -0,0 +1,33 @@ +// Generated automatically from io.netty.handler.codec.http.multipart.HttpPostStandardRequestDecoder for testing purposes + +package io.netty.handler.codec.http.multipart; + +import io.netty.handler.codec.http.HttpContent; +import io.netty.handler.codec.http.HttpRequest; +import io.netty.handler.codec.http.multipart.HttpDataFactory; +import io.netty.handler.codec.http.multipart.InterfaceHttpData; +import io.netty.handler.codec.http.multipart.InterfaceHttpPostRequestDecoder; +import java.nio.charset.Charset; +import java.util.List; + +public class HttpPostStandardRequestDecoder implements InterfaceHttpPostRequestDecoder +{ + protected HttpPostStandardRequestDecoder() {} + protected void addHttpData(InterfaceHttpData p0){} + public HttpPostStandardRequestDecoder offer(HttpContent p0){ return null; } + public HttpPostStandardRequestDecoder(HttpDataFactory p0, HttpRequest p1){} + public HttpPostStandardRequestDecoder(HttpDataFactory p0, HttpRequest p1, Charset p2){} + public HttpPostStandardRequestDecoder(HttpRequest p0){} + public InterfaceHttpData currentPartialHttpData(){ return null; } + public InterfaceHttpData getBodyHttpData(String p0){ return null; } + public InterfaceHttpData next(){ return null; } + public List<InterfaceHttpData> getBodyHttpDatas(){ return null; } + public List<InterfaceHttpData> getBodyHttpDatas(String p0){ return null; } + public boolean hasNext(){ return false; } + public boolean isMultipart(){ return false; } + public int getDiscardThreshold(){ return 0; } + public void cleanFiles(){} + public void destroy(){} + public void removeHttpDataFromClean(InterfaceHttpData p0){} + public void setDiscardThreshold(int p0){} +} diff --git a/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http/multipart/InterfaceHttpData.java b/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http/multipart/InterfaceHttpData.java new file mode 100644 index 00000000000..3f46a06a085 --- /dev/null +++ b/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http/multipart/InterfaceHttpData.java @@ -0,0 +1,20 @@ +// Generated automatically from io.netty.handler.codec.http.multipart.InterfaceHttpData for testing purposes + +package io.netty.handler.codec.http.multipart; + +import io.netty.util.ReferenceCounted; + +public interface InterfaceHttpData extends Comparable<InterfaceHttpData>, ReferenceCounted +{ + InterfaceHttpData retain(); + InterfaceHttpData retain(int p0); + InterfaceHttpData touch(); + InterfaceHttpData touch(Object p0); + InterfaceHttpData.HttpDataType getHttpDataType(); + String getName(); + static public enum HttpDataType + { + Attribute, FileUpload, InternalAttribute; + private HttpDataType() {} + } +} diff --git a/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http/multipart/InterfaceHttpPostRequestDecoder.java b/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http/multipart/InterfaceHttpPostRequestDecoder.java new file mode 100644 index 00000000000..fa72ac7b57d --- /dev/null +++ b/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http/multipart/InterfaceHttpPostRequestDecoder.java @@ -0,0 +1,24 @@ +// Generated automatically from io.netty.handler.codec.http.multipart.InterfaceHttpPostRequestDecoder for testing purposes + +package io.netty.handler.codec.http.multipart; + +import io.netty.handler.codec.http.HttpContent; +import io.netty.handler.codec.http.multipart.InterfaceHttpData; +import java.util.List; + +public interface InterfaceHttpPostRequestDecoder +{ + InterfaceHttpData currentPartialHttpData(); + InterfaceHttpData getBodyHttpData(String p0); + InterfaceHttpData next(); + InterfaceHttpPostRequestDecoder offer(HttpContent p0); + List<InterfaceHttpData> getBodyHttpDatas(); + List<InterfaceHttpData> getBodyHttpDatas(String p0); + boolean hasNext(); + boolean isMultipart(); + int getDiscardThreshold(); + void cleanFiles(); + void destroy(); + void removeHttpDataFromClean(InterfaceHttpData p0); + void setDiscardThreshold(int p0); +} diff --git a/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http/websocketx/CloseWebSocketFrame.java b/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http/websocketx/CloseWebSocketFrame.java new file mode 100644 index 00000000000..e2262cee001 --- /dev/null +++ b/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http/websocketx/CloseWebSocketFrame.java @@ -0,0 +1,28 @@ +// Generated automatically from io.netty.handler.codec.http.websocketx.CloseWebSocketFrame for testing purposes + +package io.netty.handler.codec.http.websocketx; + +import io.netty.buffer.ByteBuf; +import io.netty.handler.codec.http.websocketx.WebSocketCloseStatus; +import io.netty.handler.codec.http.websocketx.WebSocketFrame; + +public class CloseWebSocketFrame extends WebSocketFrame +{ + public CloseWebSocketFrame copy(){ return null; } + public CloseWebSocketFrame duplicate(){ return null; } + public CloseWebSocketFrame replace(ByteBuf p0){ return null; } + public CloseWebSocketFrame retain(){ return null; } + public CloseWebSocketFrame retain(int p0){ return null; } + public CloseWebSocketFrame retainedDuplicate(){ return null; } + public CloseWebSocketFrame touch(){ return null; } + public CloseWebSocketFrame touch(Object p0){ return null; } + public CloseWebSocketFrame(){} + public CloseWebSocketFrame(WebSocketCloseStatus p0){} + public CloseWebSocketFrame(WebSocketCloseStatus p0, String p1){} + public CloseWebSocketFrame(boolean p0, int p1){} + public CloseWebSocketFrame(boolean p0, int p1, ByteBuf p2){} + public CloseWebSocketFrame(boolean p0, int p1, int p2, String p3){} + public CloseWebSocketFrame(int p0, String p1){} + public String reasonText(){ return null; } + public int statusCode(){ return 0; } +} diff --git a/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http/websocketx/ContinuationWebSocketFrame.java b/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http/websocketx/ContinuationWebSocketFrame.java new file mode 100644 index 00000000000..1712af49f0c --- /dev/null +++ b/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http/websocketx/ContinuationWebSocketFrame.java @@ -0,0 +1,23 @@ +// Generated automatically from io.netty.handler.codec.http.websocketx.ContinuationWebSocketFrame for testing purposes + +package io.netty.handler.codec.http.websocketx; + +import io.netty.buffer.ByteBuf; +import io.netty.handler.codec.http.websocketx.WebSocketFrame; + +public class ContinuationWebSocketFrame extends WebSocketFrame +{ + public ContinuationWebSocketFrame copy(){ return null; } + public ContinuationWebSocketFrame duplicate(){ return null; } + public ContinuationWebSocketFrame replace(ByteBuf p0){ return null; } + public ContinuationWebSocketFrame retain(){ return null; } + public ContinuationWebSocketFrame retain(int p0){ return null; } + public ContinuationWebSocketFrame retainedDuplicate(){ return null; } + public ContinuationWebSocketFrame touch(){ return null; } + public ContinuationWebSocketFrame touch(Object p0){ return null; } + public ContinuationWebSocketFrame(){} + public ContinuationWebSocketFrame(ByteBuf p0){} + public ContinuationWebSocketFrame(boolean p0, int p1, ByteBuf p2){} + public ContinuationWebSocketFrame(boolean p0, int p1, String p2){} + public String text(){ return null; } +} diff --git a/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http/websocketx/TextWebSocketFrame.java b/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http/websocketx/TextWebSocketFrame.java new file mode 100644 index 00000000000..f473d8e166a --- /dev/null +++ b/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http/websocketx/TextWebSocketFrame.java @@ -0,0 +1,24 @@ +// Generated automatically from io.netty.handler.codec.http.websocketx.TextWebSocketFrame for testing purposes + +package io.netty.handler.codec.http.websocketx; + +import io.netty.buffer.ByteBuf; +import io.netty.handler.codec.http.websocketx.WebSocketFrame; + +public class TextWebSocketFrame extends WebSocketFrame +{ + public String text(){ return null; } + public TextWebSocketFrame copy(){ return null; } + public TextWebSocketFrame duplicate(){ return null; } + public TextWebSocketFrame replace(ByteBuf p0){ return null; } + public TextWebSocketFrame retain(){ return null; } + public TextWebSocketFrame retain(int p0){ return null; } + public TextWebSocketFrame retainedDuplicate(){ return null; } + public TextWebSocketFrame touch(){ return null; } + public TextWebSocketFrame touch(Object p0){ return null; } + public TextWebSocketFrame(){} + public TextWebSocketFrame(ByteBuf p0){} + public TextWebSocketFrame(String p0){} + public TextWebSocketFrame(boolean p0, int p1, ByteBuf p2){} + public TextWebSocketFrame(boolean p0, int p1, String p2){} +} diff --git a/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http/websocketx/WebSocketCloseStatus.java b/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http/websocketx/WebSocketCloseStatus.java new file mode 100644 index 00000000000..20742532a32 --- /dev/null +++ b/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http/websocketx/WebSocketCloseStatus.java @@ -0,0 +1,34 @@ +// Generated automatically from io.netty.handler.codec.http.websocketx.WebSocketCloseStatus for testing purposes + +package io.netty.handler.codec.http.websocketx; + + +public class WebSocketCloseStatus implements Comparable<WebSocketCloseStatus> +{ + protected WebSocketCloseStatus() {} + public String reasonText(){ return null; } + public String toString(){ return null; } + public WebSocketCloseStatus(int p0, String p1){} + public WebSocketCloseStatus(int p0, String p1, boolean p2){} + public boolean equals(Object p0){ return false; } + public int code(){ return 0; } + public int compareTo(WebSocketCloseStatus p0){ return 0; } + public int hashCode(){ return 0; } + public static WebSocketCloseStatus ABNORMAL_CLOSURE = null; + public static WebSocketCloseStatus BAD_GATEWAY = null; + public static WebSocketCloseStatus EMPTY = null; + public static WebSocketCloseStatus ENDPOINT_UNAVAILABLE = null; + public static WebSocketCloseStatus INTERNAL_SERVER_ERROR = null; + public static WebSocketCloseStatus INVALID_MESSAGE_TYPE = null; + public static WebSocketCloseStatus INVALID_PAYLOAD_DATA = null; + public static WebSocketCloseStatus MANDATORY_EXTENSION = null; + public static WebSocketCloseStatus MESSAGE_TOO_BIG = null; + public static WebSocketCloseStatus NORMAL_CLOSURE = null; + public static WebSocketCloseStatus POLICY_VIOLATION = null; + public static WebSocketCloseStatus PROTOCOL_ERROR = null; + public static WebSocketCloseStatus SERVICE_RESTART = null; + public static WebSocketCloseStatus TLS_HANDSHAKE_FAILED = null; + public static WebSocketCloseStatus TRY_AGAIN_LATER = null; + public static WebSocketCloseStatus valueOf(int p0){ return null; } + public static boolean isValidStatusCode(int p0){ return false; } +} diff --git a/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http/websocketx/WebSocketFrame.java b/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http/websocketx/WebSocketFrame.java new file mode 100644 index 00000000000..4e18beee70f --- /dev/null +++ b/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http/websocketx/WebSocketFrame.java @@ -0,0 +1,24 @@ +// Generated automatically from io.netty.handler.codec.http.websocketx.WebSocketFrame for testing purposes + +package io.netty.handler.codec.http.websocketx; + +import io.netty.buffer.ByteBuf; +import io.netty.buffer.DefaultByteBufHolder; + +abstract public class WebSocketFrame extends DefaultByteBufHolder +{ + protected WebSocketFrame() {} + protected WebSocketFrame(ByteBuf p0){} + protected WebSocketFrame(boolean p0, int p1, ByteBuf p2){} + public String toString(){ return null; } + public WebSocketFrame copy(){ return null; } + public WebSocketFrame duplicate(){ return null; } + public WebSocketFrame retain(){ return null; } + public WebSocketFrame retain(int p0){ return null; } + public WebSocketFrame retainedDuplicate(){ return null; } + public WebSocketFrame touch(){ return null; } + public WebSocketFrame touch(Object p0){ return null; } + public abstract WebSocketFrame replace(ByteBuf p0); + public boolean isFinalFragment(){ return false; } + public int rsv(){ return 0; } +} diff --git a/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http2/Http2Connection.java b/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http2/Http2Connection.java new file mode 100644 index 00000000000..02aa022109c --- /dev/null +++ b/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http2/Http2Connection.java @@ -0,0 +1,65 @@ +// Generated automatically from io.netty.handler.codec.http2.Http2Connection for testing purposes + +package io.netty.handler.codec.http2; + +import io.netty.buffer.ByteBuf; +import io.netty.handler.codec.http2.Http2FlowController; +import io.netty.handler.codec.http2.Http2LocalFlowController; +import io.netty.handler.codec.http2.Http2RemoteFlowController; +import io.netty.handler.codec.http2.Http2Stream; +import io.netty.handler.codec.http2.Http2StreamVisitor; +import io.netty.util.concurrent.Promise; + +public interface Http2Connection +{ + Http2Connection.Endpoint<Http2LocalFlowController> local(); + Http2Connection.Endpoint<Http2RemoteFlowController> remote(); + Http2Connection.PropertyKey newKey(); + Http2Stream connectionStream(); + Http2Stream forEachActiveStream(Http2StreamVisitor p0); + Http2Stream stream(int p0); + boolean goAwayReceived(); + boolean goAwaySent(); + boolean goAwaySent(int p0, long p1, ByteBuf p2); + boolean isServer(); + boolean streamMayHaveExisted(int p0); + int numActiveStreams(); + io.netty.util.concurrent.Future<Void> close(Promise<Void> p0); + static public interface Endpoint<F extends Http2FlowController> + { + F flowController(); + Http2Connection.Endpoint<? extends Http2FlowController> opposite(); + Http2Stream createStream(int p0, boolean p1); + Http2Stream reservePushStream(int p0, Http2Stream p1); + boolean allowPushTo(); + boolean canOpenStream(); + boolean created(Http2Stream p0); + boolean isServer(); + boolean isValidStreamId(int p0); + boolean mayHaveCreatedStream(int p0); + int incrementAndGetNextStreamId(); + int lastStreamCreated(); + int lastStreamKnownByPeer(); + int maxActiveStreams(); + int numActiveStreams(); + void allowPushTo(boolean p0); + void flowController(F p0); + void maxActiveStreams(int p0); + } + static public interface Listener + { + void onGoAwayReceived(int p0, long p1, ByteBuf p2); + void onGoAwaySent(int p0, long p1, ByteBuf p2); + void onStreamActive(Http2Stream p0); + void onStreamAdded(Http2Stream p0); + void onStreamClosed(Http2Stream p0); + void onStreamHalfClosed(Http2Stream p0); + void onStreamRemoved(Http2Stream p0); + } + static public interface PropertyKey + { + } + void addListener(Http2Connection.Listener p0); + void goAwayReceived(int p0, long p1, ByteBuf p2); + void removeListener(Http2Connection.Listener p0); +} diff --git a/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http2/Http2DataWriter.java b/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http2/Http2DataWriter.java new file mode 100644 index 00000000000..545bb56c75c --- /dev/null +++ b/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http2/Http2DataWriter.java @@ -0,0 +1,13 @@ +// Generated automatically from io.netty.handler.codec.http2.Http2DataWriter for testing purposes + +package io.netty.handler.codec.http2; + +import io.netty.buffer.ByteBuf; +import io.netty.channel.ChannelFuture; +import io.netty.channel.ChannelHandlerContext; +import io.netty.channel.ChannelPromise; + +public interface Http2DataWriter +{ + ChannelFuture writeData(ChannelHandlerContext p0, int p1, ByteBuf p2, int p3, boolean p4, ChannelPromise p5); +} diff --git a/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http2/Http2FlowController.java b/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http2/Http2FlowController.java new file mode 100644 index 00000000000..28b89d0f24f --- /dev/null +++ b/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http2/Http2FlowController.java @@ -0,0 +1,15 @@ +// Generated automatically from io.netty.handler.codec.http2.Http2FlowController for testing purposes + +package io.netty.handler.codec.http2; + +import io.netty.channel.ChannelHandlerContext; +import io.netty.handler.codec.http2.Http2Stream; + +public interface Http2FlowController +{ + int initialWindowSize(); + int windowSize(Http2Stream p0); + void channelHandlerContext(ChannelHandlerContext p0); + void incrementWindowSize(Http2Stream p0, int p1); + void initialWindowSize(int p0); +} diff --git a/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http2/Http2Frame.java b/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http2/Http2Frame.java new file mode 100644 index 00000000000..51daf95b02f --- /dev/null +++ b/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http2/Http2Frame.java @@ -0,0 +1,9 @@ +// Generated automatically from io.netty.handler.codec.http2.Http2Frame for testing purposes + +package io.netty.handler.codec.http2; + + +public interface Http2Frame +{ + String name(); +} diff --git a/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http2/Http2FrameSizePolicy.java b/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http2/Http2FrameSizePolicy.java new file mode 100644 index 00000000000..494a505a5c5 --- /dev/null +++ b/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http2/Http2FrameSizePolicy.java @@ -0,0 +1,10 @@ +// Generated automatically from io.netty.handler.codec.http2.Http2FrameSizePolicy for testing purposes + +package io.netty.handler.codec.http2; + + +public interface Http2FrameSizePolicy +{ + int maxFrameSize(); + void maxFrameSize(int p0); +} diff --git a/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http2/Http2FrameStream.java b/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http2/Http2FrameStream.java new file mode 100644 index 00000000000..607f176998d --- /dev/null +++ b/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http2/Http2FrameStream.java @@ -0,0 +1,11 @@ +// Generated automatically from io.netty.handler.codec.http2.Http2FrameStream for testing purposes + +package io.netty.handler.codec.http2; + +import io.netty.handler.codec.http2.Http2Stream; + +public interface Http2FrameStream +{ + Http2Stream.State state(); + int id(); +} diff --git a/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http2/Http2FrameWriter.java b/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http2/Http2FrameWriter.java new file mode 100644 index 00000000000..de8626737c4 --- /dev/null +++ b/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http2/Http2FrameWriter.java @@ -0,0 +1,37 @@ +// Generated automatically from io.netty.handler.codec.http2.Http2FrameWriter for testing purposes + +package io.netty.handler.codec.http2; + +import io.netty.buffer.ByteBuf; +import io.netty.channel.ChannelFuture; +import io.netty.channel.ChannelHandlerContext; +import io.netty.channel.ChannelPromise; +import io.netty.handler.codec.http2.Http2DataWriter; +import io.netty.handler.codec.http2.Http2Flags; +import io.netty.handler.codec.http2.Http2FrameSizePolicy; +import io.netty.handler.codec.http2.Http2Headers; +import io.netty.handler.codec.http2.Http2HeadersEncoder; +import io.netty.handler.codec.http2.Http2Settings; +import java.io.Closeable; + +public interface Http2FrameWriter extends Closeable, Http2DataWriter +{ + ChannelFuture writeFrame(ChannelHandlerContext p0, byte p1, int p2, Http2Flags p3, ByteBuf p4, ChannelPromise p5); + ChannelFuture writeGoAway(ChannelHandlerContext p0, int p1, long p2, ByteBuf p3, ChannelPromise p4); + ChannelFuture writeHeaders(ChannelHandlerContext p0, int p1, Http2Headers p2, int p3, boolean p4, ChannelPromise p5); + ChannelFuture writeHeaders(ChannelHandlerContext p0, int p1, Http2Headers p2, int p3, short p4, boolean p5, int p6, boolean p7, ChannelPromise p8); + ChannelFuture writePing(ChannelHandlerContext p0, boolean p1, long p2, ChannelPromise p3); + ChannelFuture writePriority(ChannelHandlerContext p0, int p1, int p2, short p3, boolean p4, ChannelPromise p5); + ChannelFuture writePushPromise(ChannelHandlerContext p0, int p1, int p2, Http2Headers p3, int p4, ChannelPromise p5); + ChannelFuture writeRstStream(ChannelHandlerContext p0, int p1, long p2, ChannelPromise p3); + ChannelFuture writeSettings(ChannelHandlerContext p0, Http2Settings p1, ChannelPromise p2); + ChannelFuture writeSettingsAck(ChannelHandlerContext p0, ChannelPromise p1); + ChannelFuture writeWindowUpdate(ChannelHandlerContext p0, int p1, int p2, ChannelPromise p3); + Http2FrameWriter.Configuration configuration(); + static public interface Configuration + { + Http2FrameSizePolicy frameSizePolicy(); + Http2HeadersEncoder.Configuration headersConfiguration(); + } + void close(); +} diff --git a/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http2/Http2HeadersEncoder.java b/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http2/Http2HeadersEncoder.java new file mode 100644 index 00000000000..26d778433d3 --- /dev/null +++ b/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http2/Http2HeadersEncoder.java @@ -0,0 +1,25 @@ +// Generated automatically from io.netty.handler.codec.http2.Http2HeadersEncoder for testing purposes + +package io.netty.handler.codec.http2; + +import io.netty.buffer.ByteBuf; +import io.netty.handler.codec.http2.Http2Headers; + +public interface Http2HeadersEncoder +{ + Http2HeadersEncoder.Configuration configuration(); + static Http2HeadersEncoder.SensitivityDetector ALWAYS_SENSITIVE = null; + static Http2HeadersEncoder.SensitivityDetector NEVER_SENSITIVE = null; + static public interface Configuration + { + long maxHeaderListSize(); + long maxHeaderTableSize(); + void maxHeaderListSize(long p0); + void maxHeaderTableSize(long p0); + } + static public interface SensitivityDetector + { + boolean isSensitive(CharSequence p0, CharSequence p1); + } + void encodeHeaders(int p0, Http2Headers p1, ByteBuf p2); +} diff --git a/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http2/Http2HeadersFrame.java b/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http2/Http2HeadersFrame.java new file mode 100644 index 00000000000..1b4c1ebebb1 --- /dev/null +++ b/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http2/Http2HeadersFrame.java @@ -0,0 +1,13 @@ +// Generated automatically from io.netty.handler.codec.http2.Http2HeadersFrame for testing purposes + +package io.netty.handler.codec.http2; + +import io.netty.handler.codec.http2.Http2Headers; +import io.netty.handler.codec.http2.Http2StreamFrame; + +public interface Http2HeadersFrame extends Http2StreamFrame +{ + Http2Headers headers(); + boolean isEndStream(); + int padding(); +} diff --git a/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http2/Http2LocalFlowController.java b/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http2/Http2LocalFlowController.java new file mode 100644 index 00000000000..d60ab505ee0 --- /dev/null +++ b/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http2/Http2LocalFlowController.java @@ -0,0 +1,17 @@ +// Generated automatically from io.netty.handler.codec.http2.Http2LocalFlowController for testing purposes + +package io.netty.handler.codec.http2; + +import io.netty.buffer.ByteBuf; +import io.netty.handler.codec.http2.Http2FlowController; +import io.netty.handler.codec.http2.Http2FrameWriter; +import io.netty.handler.codec.http2.Http2Stream; + +public interface Http2LocalFlowController extends Http2FlowController +{ + Http2LocalFlowController frameWriter(Http2FrameWriter p0); + boolean consumeBytes(Http2Stream p0, int p1); + int initialWindowSize(Http2Stream p0); + int unconsumedBytes(Http2Stream p0); + void receiveFlowControlledFrame(Http2Stream p0, ByteBuf p1, int p2, boolean p3); +} diff --git a/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http2/Http2PushPromiseFrame.java b/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http2/Http2PushPromiseFrame.java new file mode 100644 index 00000000000..17025825958 --- /dev/null +++ b/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http2/Http2PushPromiseFrame.java @@ -0,0 +1,17 @@ +// Generated automatically from io.netty.handler.codec.http2.Http2PushPromiseFrame for testing purposes + +package io.netty.handler.codec.http2; + +import io.netty.handler.codec.http2.Http2FrameStream; +import io.netty.handler.codec.http2.Http2Headers; +import io.netty.handler.codec.http2.Http2StreamFrame; + +public interface Http2PushPromiseFrame extends Http2StreamFrame +{ + Http2FrameStream pushStream(); + Http2Headers http2Headers(); + Http2PushPromiseFrame stream(Http2FrameStream p0); + Http2StreamFrame pushStream(Http2FrameStream p0); + int padding(); + int promisedStreamId(); +} diff --git a/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http2/Http2RemoteFlowController.java b/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http2/Http2RemoteFlowController.java new file mode 100644 index 00000000000..f20af5c9790 --- /dev/null +++ b/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http2/Http2RemoteFlowController.java @@ -0,0 +1,31 @@ +// Generated automatically from io.netty.handler.codec.http2.Http2RemoteFlowController for testing purposes + +package io.netty.handler.codec.http2; + +import io.netty.channel.ChannelHandlerContext; +import io.netty.handler.codec.http2.Http2FlowController; +import io.netty.handler.codec.http2.Http2Stream; + +public interface Http2RemoteFlowController extends Http2FlowController +{ + ChannelHandlerContext channelHandlerContext(); + boolean hasFlowControlled(Http2Stream p0); + boolean isWritable(Http2Stream p0); + static public interface FlowControlled + { + boolean merge(ChannelHandlerContext p0, Http2RemoteFlowController.FlowControlled p1); + int size(); + void error(ChannelHandlerContext p0, Throwable p1); + void write(ChannelHandlerContext p0, int p1); + void writeComplete(); + } + static public interface Listener + { + void writabilityChanged(Http2Stream p0); + } + void addFlowControlled(Http2Stream p0, Http2RemoteFlowController.FlowControlled p1); + void channelWritabilityChanged(); + void listener(Http2RemoteFlowController.Listener p0); + void updateDependencyTree(int p0, int p1, short p2, boolean p3); + void writePendingBytes(); +} diff --git a/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http2/Http2Stream.java b/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http2/Http2Stream.java new file mode 100644 index 00000000000..83bd0496e26 --- /dev/null +++ b/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http2/Http2Stream.java @@ -0,0 +1,35 @@ +// Generated automatically from io.netty.handler.codec.http2.Http2Stream for testing purposes + +package io.netty.handler.codec.http2; + +import io.netty.handler.codec.http2.Http2Connection; + +public interface Http2Stream +{ + <V> V getProperty(Http2Connection.PropertyKey p0); + <V> V removeProperty(Http2Connection.PropertyKey p0); + <V> V setProperty(Http2Connection.PropertyKey p0, V p1); + Http2Stream close(); + Http2Stream closeLocalSide(); + Http2Stream closeRemoteSide(); + Http2Stream headersReceived(boolean p0); + Http2Stream headersSent(boolean p0); + Http2Stream open(boolean p0); + Http2Stream pushPromiseSent(); + Http2Stream resetSent(); + Http2Stream.State state(); + boolean isHeadersReceived(); + boolean isHeadersSent(); + boolean isPushPromiseSent(); + boolean isResetSent(); + boolean isTrailersReceived(); + boolean isTrailersSent(); + int id(); + static public enum State + { + CLOSED, HALF_CLOSED_LOCAL, HALF_CLOSED_REMOTE, IDLE, OPEN, RESERVED_LOCAL, RESERVED_REMOTE; + private State() {} + public boolean localSideOpen(){ return false; } + public boolean remoteSideOpen(){ return false; } + } +} diff --git a/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http2/Http2StreamFrame.java b/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http2/Http2StreamFrame.java new file mode 100644 index 00000000000..acad086e05f --- /dev/null +++ b/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http2/Http2StreamFrame.java @@ -0,0 +1,12 @@ +// Generated automatically from io.netty.handler.codec.http2.Http2StreamFrame for testing purposes + +package io.netty.handler.codec.http2; + +import io.netty.handler.codec.http2.Http2Frame; +import io.netty.handler.codec.http2.Http2FrameStream; + +public interface Http2StreamFrame extends Http2Frame +{ + Http2FrameStream stream(); + Http2StreamFrame stream(Http2FrameStream p0); +} diff --git a/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http2/Http2StreamVisitor.java b/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http2/Http2StreamVisitor.java new file mode 100644 index 00000000000..a3cb43954c9 --- /dev/null +++ b/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http2/Http2StreamVisitor.java @@ -0,0 +1,10 @@ +// Generated automatically from io.netty.handler.codec.http2.Http2StreamVisitor for testing purposes + +package io.netty.handler.codec.http2; + +import io.netty.handler.codec.http2.Http2Stream; + +public interface Http2StreamVisitor +{ + boolean visit(Http2Stream p0); +} diff --git a/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http2/HttpConversionUtil.java b/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http2/HttpConversionUtil.java new file mode 100644 index 00000000000..ce7244b42d3 --- /dev/null +++ b/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http2/HttpConversionUtil.java @@ -0,0 +1,37 @@ +// Generated automatically from io.netty.handler.codec.http2.HttpConversionUtil for testing purposes + +package io.netty.handler.codec.http2; + +import io.netty.buffer.ByteBuf; +import io.netty.buffer.ByteBufAllocator; +import io.netty.handler.codec.http.FullHttpMessage; +import io.netty.handler.codec.http.FullHttpRequest; +import io.netty.handler.codec.http.FullHttpResponse; +import io.netty.handler.codec.http.HttpHeaders; +import io.netty.handler.codec.http.HttpMessage; +import io.netty.handler.codec.http.HttpMethod; +import io.netty.handler.codec.http.HttpRequest; +import io.netty.handler.codec.http.HttpResponse; +import io.netty.handler.codec.http.HttpResponseStatus; +import io.netty.handler.codec.http.HttpVersion; +import io.netty.handler.codec.http2.Http2Headers; + +public class HttpConversionUtil +{ + protected HttpConversionUtil() {} + public static FullHttpRequest toFullHttpRequest(int p0, Http2Headers p1, ByteBuf p2, boolean p3){ return null; } + public static FullHttpRequest toFullHttpRequest(int p0, Http2Headers p1, ByteBufAllocator p2, boolean p3){ return null; } + public static FullHttpResponse toFullHttpResponse(int p0, Http2Headers p1, ByteBuf p2, boolean p3){ return null; } + public static FullHttpResponse toFullHttpResponse(int p0, Http2Headers p1, ByteBufAllocator p2, boolean p3){ return null; } + public static Http2Headers toHttp2Headers(HttpHeaders p0, boolean p1){ return null; } + public static Http2Headers toHttp2Headers(HttpMessage p0, boolean p1){ return null; } + public static HttpMethod OUT_OF_MESSAGE_SEQUENCE_METHOD = null; + public static HttpRequest toHttpRequest(int p0, Http2Headers p1, boolean p2){ return null; } + public static HttpResponse toHttpResponse(int p0, Http2Headers p1, boolean p2){ return null; } + public static HttpResponseStatus OUT_OF_MESSAGE_SEQUENCE_RETURN_CODE = null; + public static HttpResponseStatus parseStatus(CharSequence p0){ return null; } + public static String OUT_OF_MESSAGE_SEQUENCE_PATH = null; + public static void addHttp2ToHttpHeaders(int p0, Http2Headers p1, FullHttpMessage p2, boolean p3){} + public static void addHttp2ToHttpHeaders(int p0, Http2Headers p1, HttpHeaders p2, HttpVersion p3, boolean p4, boolean p5){} + public static void toHttp2Headers(HttpHeaders p0, Http2Headers p1){} +} diff --git a/java/ql/test/stubs/netty-4.1.x/io/netty/util/AbstractReferenceCounted.java b/java/ql/test/stubs/netty-4.1.x/io/netty/util/AbstractReferenceCounted.java new file mode 100644 index 00000000000..17241013a37 --- /dev/null +++ b/java/ql/test/stubs/netty-4.1.x/io/netty/util/AbstractReferenceCounted.java @@ -0,0 +1,18 @@ +// Generated automatically from io.netty.util.AbstractReferenceCounted for testing purposes + +package io.netty.util; + +import io.netty.util.ReferenceCounted; + +abstract public class AbstractReferenceCounted implements ReferenceCounted +{ + protected abstract void deallocate(); + protected final void setRefCnt(int p0){} + public AbstractReferenceCounted(){} + public ReferenceCounted retain(){ return null; } + public ReferenceCounted retain(int p0){ return null; } + public ReferenceCounted touch(){ return null; } + public boolean release(){ return false; } + public boolean release(int p0){ return false; } + public int refCnt(){ return 0; } +} diff --git a/java/ql/test/stubs/netty-4.1.x/io/netty/util/collection/CharObjectHashMap.java b/java/ql/test/stubs/netty-4.1.x/io/netty/util/collection/CharObjectHashMap.java index f52d6279b15..2c90b798889 100644 --- a/java/ql/test/stubs/netty-4.1.x/io/netty/util/collection/CharObjectHashMap.java +++ b/java/ql/test/stubs/netty-4.1.x/io/netty/util/collection/CharObjectHashMap.java @@ -13,10 +13,7 @@ public class CharObjectHashMap<V> implements CharObjectMap<V> public CharObjectHashMap(){} public CharObjectHashMap(int p0){} public CharObjectHashMap(int p0, float p1){} - public Collection<V> values(){ return null; } - public Iterable<CharObjectMap.PrimitiveEntry<V>> entries(){ return null; } public Set<Character> keySet(){ return null; } - public Set<Map.Entry<Character, V>> entrySet(){ return null; } public String toString(){ return null; } public V get(Object p0){ return null; } public V get(char p0){ return null; } @@ -31,8 +28,11 @@ public class CharObjectHashMap<V> implements CharObjectMap<V> public boolean isEmpty(){ return false; } public int hashCode(){ return 0; } public int size(){ return 0; } + public java.lang.Iterable<CharObjectMap.PrimitiveEntry<V>> entries(){ return null; } + public java.util.Collection<V> values(){ return null; } + public java.util.Set<Map.Entry<Character, V>> entrySet(){ return null; } public static float DEFAULT_LOAD_FACTOR = 0; public static int DEFAULT_CAPACITY = 0; public void clear(){} - public void putAll(Map<? extends Character, ? extends V> p0){} + public void putAll(java.util.Map<? extends Character, ? extends V> p0){} } diff --git a/java/ql/test/stubs/netty-4.1.x/io/netty/util/collection/CharObjectMap.java b/java/ql/test/stubs/netty-4.1.x/io/netty/util/collection/CharObjectMap.java index 1bbb76a4dd5..1627dad1d54 100644 --- a/java/ql/test/stubs/netty-4.1.x/io/netty/util/collection/CharObjectMap.java +++ b/java/ql/test/stubs/netty-4.1.x/io/netty/util/collection/CharObjectMap.java @@ -4,13 +4,13 @@ package io.netty.util.collection; import java.util.Map; -public interface CharObjectMap<V> extends Map<Character, V> +public interface CharObjectMap<V> extends java.util.Map<Character, V> { - Iterable<CharObjectMap.PrimitiveEntry<V>> entries(); V get(char p0); V put(char p0, V p1); V remove(char p0); boolean containsKey(char p0); + java.lang.Iterable<CharObjectMap.PrimitiveEntry<V>> entries(); static public interface PrimitiveEntry<V> { V value(); From f292e85c51ea8bbd5e05e3288ae07449c6871cb9 Mon Sep 17 00:00:00 2001 From: Joe Farebrother <joefarebrother@github.com> Date: Fri, 17 Feb 2023 15:06:06 +0000 Subject: [PATCH 366/631] Model fixes - remove ambiguity, correctly model constructors --- java/ql/lib/ext/io.netty.buffer.model.yml | 92 ++++++++++++++----- .../ext/io.netty.handler.codec.http.model.yml | 2 +- ...tty.handler.codec.http.multipart.model.yml | 18 ++-- 3 files changed, 79 insertions(+), 33 deletions(-) diff --git a/java/ql/lib/ext/io.netty.buffer.model.yml b/java/ql/lib/ext/io.netty.buffer.model.yml index 86933215bd4..350a7e0566c 100644 --- a/java/ql/lib/ext/io.netty.buffer.model.yml +++ b/java/ql/lib/ext/io.netty.buffer.model.yml @@ -11,14 +11,26 @@ extensions: - ["io.netty.buffer", "ByteBuf", True, "discardReadBytes", "()", "", "Argument[-1]", "ReturnValue", "value", "manual"] - ["io.netty.buffer", "ByteBuf", True, "discardSomeReadBytes", "()", "", "Argument[-1]", "ReturnValue", "value", "manual"] - ["io.netty.buffer", "ByteBuf", True, "duplicate", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "ensureWritable", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "getBytes", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "markReaderIndex", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "markWriterIndex", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "ensureWritable", "(int)", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "getBytes", "(int,byte[])", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "getBytes", "(int,byte[],int,int)", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "getBytes", "(int,ByteBuf)", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "getBytes", "(int,ByteBuffer)", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "getBytes", "(int,ByteBuf,int)", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "getBytes", "(int,ByteBuf,int,int)", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "getBytes", "(int,OutputStream,int)", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "markReaderIndex", "()", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "markWriterIndex", "()", "", "Argument[-1]", "ReturnValue", "value", "manual"] - ["io.netty.buffer", "ByteBuf", True, "nioBuffer", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - ["io.netty.buffer", "ByteBuf", True, "nioBuffers", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "order", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "readBytes", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "order", "(ByteOrder)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "readBytes", "(byte[])", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "readBytes", "(byte[],int,int)", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "readBytes", "(ByteBuf)", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "readBytes", "(ByteBuffer)", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "readBytes", "(ByteBuf,int)", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "readBytes", "(ByteBuf,int,int)", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "readBytes", "(OutputStream,int)", "", "Argument[-1]", "ReturnValue", "value", "manual"] - ["io.netty.buffer", "ByteBuf", True, "readerIndex", "(int)", "", "Argument[-1]", "ReturnValue", "value", "manual"] - ["io.netty.buffer", "ByteBuf", True, "resetReaderIndex", "()", "", "Argument[-1]", "ReturnValue", "value", "manual"] - ["io.netty.buffer", "ByteBuf", True, "resetWriterIndex", "()", "", "Argument[-1]", "ReturnValue", "value", "manual"] @@ -26,9 +38,13 @@ extensions: - ["io.netty.buffer", "ByteBuf", True, "retainedSlice", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - ["io.netty.buffer", "ByteBuf", True, "setBoolean", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] - ["io.netty.buffer", "ByteBuf", True, "setByte", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "setBytes", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "setBytes", "(int,byte[])", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "setBytes", "(int,byte[],int,int)", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "setBytes", "(int,ByteBuf)", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "setBytes", "(int,ByteBuffer)", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "setBytes", "(int,ByteBuf,int)", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "setBytes", "(int,ByteBuf,int,int)", "", "Argument[-1]", "ReturnValue", "value", "manual"] - ["io.netty.buffer", "ByteBuf", True, "setChar", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "setCharSequence", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] - ["io.netty.buffer", "ByteBuf", True, "setDouble", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] - ["io.netty.buffer", "ByteBuf", True, "setDoubleLE", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] - ["io.netty.buffer", "ByteBuf", True, "setFloat", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] @@ -43,14 +59,18 @@ extensions: - ["io.netty.buffer", "ByteBuf", True, "setShort", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] - ["io.netty.buffer", "ByteBuf", True, "setShortLE", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] - ["io.netty.buffer", "ByteBuf", True, "setZero", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "skipBytes", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "slice", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "skipBytes", "(int)", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "slice", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - ["io.netty.buffer", "ByteBuf", True, "toString", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - ["io.netty.buffer", "ByteBuf", True, "unwrap", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - ["io.netty.buffer", "ByteBuf", True, "writeByte", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "writeBytes", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "writeBytes", "(byte[])", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "writeBytes", "(byte[],int,int)", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "writeBytes", "(ByteBuf)", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "writeBytes", "(ByteBuffer)", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "writeBytes", "(ByteBuf,int)", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "writeBytes", "(ByteBuf,int,int)", "", "Argument[-1]", "ReturnValue", "value", "manual"] - ["io.netty.buffer", "ByteBuf", True, "writeChar", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "writeCharSequence", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] - ["io.netty.buffer", "ByteBuf", True, "writeDouble", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] - ["io.netty.buffer", "ByteBuf", True, "writeDoubleLE", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] - ["io.netty.buffer", "ByteBuf", True, "writeFloat", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] @@ -69,20 +89,46 @@ extensions: - ["io.netty.buffer", "ByteBufHolder", True, "content", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - ["io.netty.buffer", "ByteBufHolder", True, "duplicate", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - ["io.netty.buffer", "ByteBufHolder", True, "retainedDuplicate", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "getByte", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "getBytes", "", "", "Argument[-1]", "Argument[1]", "taint", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "getChar", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "getBytes", "(int,byte[])", "", "Argument[-1]", "Argument[1]", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "getBytes", "(int,byte[],int,int)", "", "Argument[-1]", "Argument[1]", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "getBytes", "(int,ByteBuf)", "", "Argument[-1]", "Argument[1]", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "getBytes", "(int,ByteBuffer)", "", "Argument[-1]", "Argument[1]", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "getBytes", "(int,ByteBuf,int)", "", "Argument[-1]", "Argument[1]", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "getBytes", "(int,ByteBuf,int,int)", "", "Argument[-1]", "Argument[1]", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "getBytes", "(int,FileChannel,long,int)", "", "Argument[-1]", "Argument[1]", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "getBytes", "(int,GatheringByteChannel,int)", "", "Argument[-1]", "Argument[1]", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "getBytes", "(int,OutputStream,int)", "", "Argument[-1]", "Argument[1]", "taint", "manual"] - ["io.netty.buffer", "ByteBuf", True, "getCharSequence", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "readByte", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "readBytes", "", "", "Argument[-1]", "Argument[0]", "taint", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "readChar", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "readBytes", "(byte[])", "", "Argument[-1]", "Argument[0]", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "readBytes", "(byte[],int,int)", "", "Argument[-1]", "Argument[0]", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "readBytes", "(ByteBuf)", "", "Argument[-1]", "Argument[0]", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "readBytes", "(ByteBuffer)", "", "Argument[-1]", "Argument[0]", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "readBytes", "(ByteBuf,int)", "", "Argument[-1]", "Argument[0]", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "readBytes", "(ByteBuf,int,int)", "", "Argument[-1]", "Argument[0]", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "readBytes", "(FileChannel,long,int)", "", "Argument[-1]", "Argument[0]", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "readBytes", "(GatheringByteChannel,int)", "", "Argument[-1]", "Argument[0]", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "readBytes", "(int)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - ["io.netty.buffer", "ByteBuf", True, "readCharSequence", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - ["io.netty.buffer", "ByteBuf", True, "readSlice", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "setByte", "", "", "Argument[1]", "Argument[-1]", "taint", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "setBytes", "", "", "Argument[1]", "Argument[-1]", "taint", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "setChar", "", "", "Argument[1]", "Argument[-1]", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "setBytes", "(int,byte[])", "", "Argument[1]", "Argument[-1]", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "setBytes", "(int,byte[],int,int)", "", "Argument[1]", "Argument[-1]", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "setBytes", "(int,ByteBuf)", "", "Argument[1]", "Argument[-1]", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "setBytes", "(int,ByteBuffer)", "", "Argument[1]", "Argument[-1]", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "setBytes", "(int,ByteBuf,int)", "", "Argument[1]", "Argument[-1]", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "setBytes", "(int,ByteBuf,int,int)", "", "Argument[1]", "Argument[-1]", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "setBytes", "(int,FileChannel,long,int)", "", "Argument[1]", "Argument[-1]", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "setBytes", "(int,ScatteringByteChannel,int)", "", "Argument[1]", "Argument[-1]", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "setBytes", "(int,InputStream,int)", "", "Argument[1]", "Argument[-1]", "taint", "manual"] - ["io.netty.buffer", "ByteBuf", True, "setCharSequence", "", "", "Argument[1]", "Argument[-1]", "taint", "manual"] - ["io.netty.buffer", "ByteBuf", True, "writeByte", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "writeBytes", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "writeBytes", "(byte[])", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "writeBytes", "(byte[],int,int)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "writeBytes", "(ByteBuf)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "writeBytes", "(ByteBuffer)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "writeBytes", "(ByteBuf,int)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "writeBytes", "(ByteBuf,int,int)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "writeBytes", "(FileChannel,long,int)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "writeBytes", "(ScatteringByteChannel,int)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "writeBytes", "(InputStream,int)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] - ["io.netty.buffer", "ByteBuf", True, "writeChar", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "writeCharSequence", "", "", "Argument[1]", "Argument[-1]", "taint", "manual"] \ No newline at end of file + - ["io.netty.buffer", "ByteBuf", True, "writeCharSequence", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] \ No newline at end of file diff --git a/java/ql/lib/ext/io.netty.handler.codec.http.model.yml b/java/ql/lib/ext/io.netty.handler.codec.http.model.yml index fd6c42685c8..a02b373d2e3 100644 --- a/java/ql/lib/ext/io.netty.handler.codec.http.model.yml +++ b/java/ql/lib/ext/io.netty.handler.codec.http.model.yml @@ -32,7 +32,7 @@ extensions: - ["io.netty.handler.codec.http", "LastHttpContent", True, "trailingHeaders", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - ["io.netty.handler.codec.http", "HttpRequest", True, "getUri", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - ["io.netty.handler.codec.http", "HttpRequest", True, "uri", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.handler.codec.http", "QueryStringDecoder", True, "QueryStringDecoder", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http", "QueryStringDecoder", True, "QueryStringDecoder", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] - ["io.netty.handler.codec.http", "QueryStringDecoder", True, "decodeComponent", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - ["io.netty.handler.codec.http", "QueryStringDecoder", True, "parameters", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - ["io.netty.handler.codec.http", "QueryStringDecoder", True, "path", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] diff --git a/java/ql/lib/ext/io.netty.handler.codec.http.multipart.model.yml b/java/ql/lib/ext/io.netty.handler.codec.http.multipart.model.yml index 5e19ad93861..afdec5cb05f 100644 --- a/java/ql/lib/ext/io.netty.handler.codec.http.multipart.model.yml +++ b/java/ql/lib/ext/io.netty.handler.codec.http.multipart.model.yml @@ -13,15 +13,15 @@ extensions: - ["io.netty.handler.codec.http.multipart", "InterfaceHttpPostRequestDecoder", True, "getBodyHttpDatas", "(String)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - ["io.netty.handler.codec.http.multipart", "InterfaceHttpPostRequestDecoder", True, "next", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - ["io.netty.handler.codec.http.multipart", "InterfaceHttpPostRequestDecoder", True, "offer", "(HttpContent)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] - - ["io.netty.handler.codec.http.multipart", "HttpPostRequestDecoder", True, "HttpPostRequestDecoder", "(HttpRequest)", "", "Argument[0]", "ReturnValue", "taint", "manual"] - - ["io.netty.handler.codec.http.multipart", "HttpPostRequestDecoder", True, "HttpPostRequestDecoder", "(HttpDataFactory,HttpRequest)", "", "Argument[1]", "ReturnValue", "taint", "manual"] - - ["io.netty.handler.codec.http.multipart", "HttpPostRequestDecoder", True, "HttpPostRequestDecoder", "(HttpDataFactory,HttpRequest,Charset)", "", "Argument[1]", "ReturnValue", "taint", "manual"] - - ["io.netty.handler.codec.http.multipart", "HttpPostStandardRequestDecoder", True, "HttpPostStandardRequestDecoder", "(HttpRequest)", "", "Argument[0]", "ReturnValue", "taint", "manual"] - - ["io.netty.handler.codec.http.multipart", "HttpPostStandardRequestDecoder", True, "HttpPostStandardRequestDecoder", "(HttpDataFactory,HttpRequest)", "", "Argument[1]", "ReturnValue", "taint", "manual"] - - ["io.netty.handler.codec.http.multipart", "HttpPostStandardRequestDecoder", True, "HttpPostStandardRequestDecoder", "(HttpDataFactory,HttpRequest,Charset)", "", "Argument[1]", "ReturnValue", "taint", "manual"] - - ["io.netty.handler.codec.http.multipart", "HttpPostMultipartRequestDecoder", True, "HttpPostMultipartRequestDecoder", "(HttpRequest)", "", "Argument[0]", "ReturnValue", "taint", "manual"] - - ["io.netty.handler.codec.http.multipart", "HttpPostMultipartRequestDecoder", True, "HttpPostMultipartRequestDecoder", "(HttpDataFactory,HttpRequest)", "", "Argument[1]", "ReturnValue", "taint", "manual"] - - ["io.netty.handler.codec.http.multipart", "HttpPostMultipartRequestDecoder", True, "HttpPostMultipartRequestDecoder", "(HttpDataFactory,HttpRequest,Charset)", "", "Argument[1]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http.multipart", "HttpPostRequestDecoder", True, "HttpPostRequestDecoder", "(HttpRequest)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["io.netty.handler.codec.http.multipart", "HttpPostRequestDecoder", True, "HttpPostRequestDecoder", "(HttpDataFactory,HttpRequest)", "", "Argument[1]", "Argument[-1]", "taint", "manual"] + - ["io.netty.handler.codec.http.multipart", "HttpPostRequestDecoder", True, "HttpPostRequestDecoder", "(HttpDataFactory,HttpRequest,Charset)", "", "Argument[1]", "Argument[-1]", "taint", "manual"] + - ["io.netty.handler.codec.http.multipart", "HttpPostStandardRequestDecoder", True, "HttpPostStandardRequestDecoder", "(HttpRequest)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["io.netty.handler.codec.http.multipart", "HttpPostStandardRequestDecoder", True, "HttpPostStandardRequestDecoder", "(HttpDataFactory,HttpRequest)", "", "Argument[1]", "Argument[-1]", "taint", "manual"] + - ["io.netty.handler.codec.http.multipart", "HttpPostStandardRequestDecoder", True, "HttpPostStandardRequestDecoder", "(HttpDataFactory,HttpRequest,Charset)", "", "Argument[1]", "Argument[-1]", "taint", "manual"] + - ["io.netty.handler.codec.http.multipart", "HttpPostMultipartRequestDecoder", True, "HttpPostMultipartRequestDecoder", "(HttpRequest)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["io.netty.handler.codec.http.multipart", "HttpPostMultipartRequestDecoder", True, "HttpPostMultipartRequestDecoder", "(HttpDataFactory,HttpRequest)", "", "Argument[1]", "Argument[-1]", "taint", "manual"] + - ["io.netty.handler.codec.http.multipart", "HttpPostMultipartRequestDecoder", True, "HttpPostMultipartRequestDecoder", "(HttpDataFactory,HttpRequest,Charset)", "", "Argument[1]", "Argument[-1]", "taint", "manual"] - ["io.netty.handler.codec.http.multipart", "InterfaceHttpData", True, "getName", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - ["io.netty.handler.codec.http.multipart", "HttpData", True, "get", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - ["io.netty.handler.codec.http.multipart", "HttpData", True, "getByteBuf", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] From 7b02616f3052fa12388154c8c3a764d42e392bad Mon Sep 17 00:00:00 2001 From: Joe Farebrother <joefarebrother@github.com> Date: Fri, 17 Feb 2023 15:27:56 +0000 Subject: [PATCH 367/631] Fix a model --- .../ql/lib/ext/io.netty.handler.codec.http.model.yml | 2 +- .../frameworks/netty/generated/Test.java | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/java/ql/lib/ext/io.netty.handler.codec.http.model.yml b/java/ql/lib/ext/io.netty.handler.codec.http.model.yml index a02b373d2e3..4ae2334b2e7 100644 --- a/java/ql/lib/ext/io.netty.handler.codec.http.model.yml +++ b/java/ql/lib/ext/io.netty.handler.codec.http.model.yml @@ -33,7 +33,7 @@ extensions: - ["io.netty.handler.codec.http", "HttpRequest", True, "getUri", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - ["io.netty.handler.codec.http", "HttpRequest", True, "uri", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - ["io.netty.handler.codec.http", "QueryStringDecoder", True, "QueryStringDecoder", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] - - ["io.netty.handler.codec.http", "QueryStringDecoder", True, "decodeComponent", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http", "QueryStringDecoder", True, "decodeComponent", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] - ["io.netty.handler.codec.http", "QueryStringDecoder", True, "parameters", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - ["io.netty.handler.codec.http", "QueryStringDecoder", True, "path", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - ["io.netty.handler.codec.http", "QueryStringDecoder", True, "rawPath", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] diff --git a/java/ql/test/library-tests/frameworks/netty/generated/Test.java b/java/ql/test/library-tests/frameworks/netty/generated/Test.java index 5f1be7834be..b664a1efe98 100644 --- a/java/ql/test/library-tests/frameworks/netty/generated/Test.java +++ b/java/ql/test/library-tests/frameworks/netty/generated/Test.java @@ -4486,17 +4486,17 @@ public class Test { sink(out); // $ hasTaintFlow } { - // "io.netty.handler.codec.http;QueryStringDecoder;true;decodeComponent;;;Argument[-1];ReturnValue;taint;manual" + // "io.netty.handler.codec.http;QueryStringDecoder;true;decodeComponent;;;Argument[0];ReturnValue;taint;manual" String out = null; - QueryStringDecoder in = (QueryStringDecoder)source(); - out = QueryStringDecoder.decodeComponent(null); + String in = (String)source(); + out = QueryStringDecoder.decodeComponent(in); sink(out); // $ hasTaintFlow } { - // "io.netty.handler.codec.http;QueryStringDecoder;true;decodeComponent;;;Argument[-1];ReturnValue;taint;manual" + // "io.netty.handler.codec.http;QueryStringDecoder;true;decodeComponent;;;Argument[0];ReturnValue;taint;manual" String out = null; - QueryStringDecoder in = (QueryStringDecoder)source(); - out = QueryStringDecoder.decodeComponent(null, null); + String in = (String)source(); + out = QueryStringDecoder.decodeComponent(in, null); sink(out); // $ hasTaintFlow } { From 5d6eab4f3aafc4ee865b5586e916e4f10e14fafb Mon Sep 17 00:00:00 2001 From: Joe Farebrother <joefarebrother@github.com> Date: Mon, 27 Feb 2023 17:07:24 +0000 Subject: [PATCH 368/631] Add models for more utility methods --- java/ql/lib/ext/io.netty.buffer.model.yml | 71 ++++++++++++++++++++++- java/ql/lib/ext/io.netty.util.model.yml | 24 +++++++- 2 files changed, 93 insertions(+), 2 deletions(-) diff --git a/java/ql/lib/ext/io.netty.buffer.model.yml b/java/ql/lib/ext/io.netty.buffer.model.yml index 350a7e0566c..fcd308d3aa5 100644 --- a/java/ql/lib/ext/io.netty.buffer.model.yml +++ b/java/ql/lib/ext/io.netty.buffer.model.yml @@ -131,4 +131,73 @@ extensions: - ["io.netty.buffer", "ByteBuf", True, "writeBytes", "(ScatteringByteChannel,int)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] - ["io.netty.buffer", "ByteBuf", True, "writeBytes", "(InputStream,int)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] - ["io.netty.buffer", "ByteBuf", True, "writeChar", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "writeCharSequence", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] \ No newline at end of file + - ["io.netty.buffer", "ByteBuf", True, "writeCharSequence", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["io.netty.buffer", "CompositeByteBuf", False, "CompositeByteBuf", "(ByteBufAllocator,boolean,int,ByteBuf[])", "", "Argument[3].ArrayElement", "Argument[-1]", "taint", "manual"] + - ["io.netty.buffer", "CompositeByteBuf", False, "CompositeByteBuf", "(ByteBufAllocator,boolean,int,Iterable)", "", "Argument[3].Element", "Argument[-1]", "taint", "manual"] + - ["io.netty.buffer", "CompositeByteBuf", True, "addComponent", "(ByteBuf)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["io.netty.buffer", "CompositeByteBuf", True, "addComponent", "(int,ByteBuf)", "", "Argument[1]", "Argument[-1]", "taint", "manual"] + - ["io.netty.buffer", "CompositeByteBuf", True, "addComponent", "(boolean,ByteBuf)", "", "Argument[1]", "Argument[-1]", "taint", "manual"] + - ["io.netty.buffer", "CompositeByteBuf", True, "addComponent", "(int,boolean,ByteBuf)", "", "Argument[2]", "Argument[-1]", "taint", "manual"] + - ["io.netty.buffer", "CompositeByteBuf", True, "addComponents", "(ByteBuf[])", "", "Argument[0].ArrayElement", "Argument[-1]", "taint", "manual"] + - ["io.netty.buffer", "CompositeByteBuf", True, "addComponents", "(int,ByteBuf[])", "", "Argument[1].ArrayElement", "Argument[-1]", "taint", "manual"] + - ["io.netty.buffer", "CompositeByteBuf", True, "addComponents", "(boolean,ByteBuf[])", "", "Argument[1].ArrayElement", "Argument[-1]", "taint", "manual"] + - ["io.netty.buffer", "CompositeByteBuf", True, "addComponents", "(Iterable)", "", "Argument[0].Element", "Argument[-1]", "taint", "manual"] + - ["io.netty.buffer", "CompositeByteBuf", True, "addComponents", "(int,Iterable)", "", "Argument[1].Element", "Argument[-1]", "taint", "manual"] + - ["io.netty.buffer", "CompositeByteBuf", True, "addComponents", "(boolean,Iterable)", "", "Argument[1].Element", "Argument[-1]", "taint", "manual"] + - ["io.netty.buffer", "CompositeByteBuf", True, "addFlattenedComponents", "(boolean,ByteBuf)", "", "Argument[1]", "Argument[-1]", "taint", "manual"] + - ["io.netty.buffer", "CompositeByteBuf", True, "component", "(int)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.buffer", "CompositeByteBuf", True, "componentAtOffset", "(int)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.buffer", "CompositeByteBuf", True, "consolidate", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.buffer", "CompositeByteBuf", True, "consolidate", "(int,int)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.buffer", "Unpooled", False, "copiedBuffer", "(byte[])", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["io.netty.buffer", "Unpooled", False, "copiedBuffer", "(byte[][])", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "manual"] + - ["io.netty.buffer", "Unpooled", False, "copiedBuffer", "(byte[],int,int)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["io.netty.buffer", "Unpooled", False, "copiedBuffer", "(ByteBuf)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["io.netty.buffer", "Unpooled", False, "copiedBuffer", "(ByteBuf[])", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "manual"] + - ["io.netty.buffer", "Unpooled", False, "copiedBuffer", "(ByteBuffer)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["io.netty.buffer", "Unpooled", False, "copiedBuffer", "(ByteBuffer[])", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "manual"] + - ["io.netty.buffer", "Unpooled", False, "copiedBuffer", "(char[],CharSet)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["io.netty.buffer", "Unpooled", False, "copiedBuffer", "(char[],int,int,CharSet)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["io.netty.buffer", "Unpooled", False, "copiedBuffer", "(CharSequence,CharSet)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["io.netty.buffer", "Unpooled", False, "copiedBuffer", "(CharSequence,int,int,CharSet)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["io.netty.buffer", "Unpooled", False, "unmodifiableBuffer", "(ByteBuf)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["io.netty.buffer", "Unpooled", False, "unmodifiableBuffer", "(ByteBuf[])", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "manual"] + - ["io.netty.buffer", "Unpooled", False, "unreleasableBuffer", "(ByteBuf)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["io.netty.buffer", "Unpooled", False, "wrappedBuffer", "(byte[])", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["io.netty.buffer", "Unpooled", False, "wrappedBuffer", "(byte[][])", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "manual"] + - ["io.netty.buffer", "Unpooled", False, "wrappedBuffer", "(byte[],int,int)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["io.netty.buffer", "Unpooled", False, "wrappedBuffer", "(ByteBuf)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["io.netty.buffer", "Unpooled", False, "wrappedBuffer", "(ByteBuf[])", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "manual"] + - ["io.netty.buffer", "Unpooled", False, "wrappedBuffer", "(ByteBuffer)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["io.netty.buffer", "Unpooled", False, "wrappedBuffer", "(ByteBuffer[])", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "manual"] + - ["io.netty.buffer", "Unpooled", False, "wrappedBuffer", "(int,byte[][])", "", "Argument[1].ArrayElement", "ReturnValue", "taint", "manual"] + - ["io.netty.buffer", "Unpooled", False, "wrappedBuffer", "(int,ByteBuf[])", "", "Argument[1].ArrayElement", "ReturnValue", "taint", "manual"] + - ["io.netty.buffer", "Unpooled", False, "wrappedBuffer", "(int,ByteBuffer[])", "", "Argument[1].ArrayElement", "ReturnValue", "taint", "manual"] + - ["io.netty.buffer", "Unpooled", False, "wrappedUnmodifiableBuffer", "(ByteBuf[])", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "manual"] + - ["io.netty.buffer", "ByteBufUtil", False, "copy", "(AsciiString,ByteBuf)", "", "Argument[0]", "Argument[1]", "taint", "manual"] + - ["io.netty.buffer", "ByteBufUtil", False, "copy", "(AsciiString,int,ByteBuf,int)", "", "Argument[0]", "Argument[2]", "taint", "manual"] + - ["io.netty.buffer", "ByteBufUtil", False, "copy", "(AsciiString,int,ByteBuf,int,int)", "", "Argument[0]", "Argument[2]", "taint", "manual"] + - ["io.netty.buffer", "ByteBufUtil", False, "decodeHexDump", "(CharSequence)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["io.netty.buffer", "ByteBufUtil", False, "decodeHexDump", "(CharSequence,int,int)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["io.netty.buffer", "ByteBufUtil", False, "encodeString", "(ByteBufAllocator,CharBuffer,CharSet)", "", "Argument[1]", "ReturnValue", "taint", "manual"] + - ["io.netty.buffer", "ByteBufUtil", False, "encodeString", "(ByteBufAllocator,CharBuffer,CharSet,int)", "", "Argument[1]", "ReturnValue", "taint", "manual"] + - ["io.netty.buffer", "ByteBufUtil", False, "ensureAccessible", "(ByteBuf)", "", "Argument[0]", "ReturnValue", "value", "manual"] + - ["io.netty.buffer", "ByteBufUtil", False, "getBytes", "(ByteBuf)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["io.netty.buffer", "ByteBufUtil", False, "getBytes", "(ByteBuf,int,int)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["io.netty.buffer", "ByteBufUtil", False, "getBytes", "(ByteBuf,int,int,boolean)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["io.netty.buffer", "ByteBufUtil", False, "readBytes", "(ByteBufAllocator,ByteBuf,int)", "", "Argument[1]", "ReturnValue", "taint", "manual"] + - ["io.netty.buffer", "ByteBufUtil", False, "reserveAndWriteUtf8", "(ByteBuf,CharSequence,int)", "", "Argument[1]", "Argument[0]", "taint", "manual"] + - ["io.netty.buffer", "ByteBufUtil", False, "reserveAndWriteUtf8", "(ByteBuf,CharSequence,int,int,int)", "", "Argument[1]", "Argument[0]", "taint", "manual"] + - ["io.netty.buffer", "ByteBufUtil", False, "writeAscii", "(ByteBuf,CharSequence)", "", "Argument[1]", "Argument[0]", "taint", "manual"] + - ["io.netty.buffer", "ByteBufUtil", False, "writeAscii", "(ByteBufAllocator,CharSequence)", "", "Argument[1]", "ReturnValue", "taint", "manual"] + - ["io.netty.buffer", "ByteBufUtil", False, "writeUtf8", "(ByteBuf,CharSequence)", "", "Argument[1]", "Argument[0]", "taint", "manual"] + - ["io.netty.buffer", "ByteBufUtil", False, "writeUtf8", "(ByteBuf,CharSequence,int,int)", "", "Argument[1]", "Argument[0]", "taint", "manual"] + - ["io.netty.buffer", "ByteBufUtil", False, "writeUtf8", "(ByteBufAllocator,CharSequence)", "", "Argument[1]", "ReturnValue", "taint", "manual"] + - ["io.netty.buffer", "ByteBufInputStream", True, "ByteBufInputStream", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["io.netty.buffer", "ByteBufOutputStream", True, "ByteBufInputStream", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["io.netty.buffer", "ByteBufOutputStream", True, "buffer", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + + + + + diff --git a/java/ql/lib/ext/io.netty.util.model.yml b/java/ql/lib/ext/io.netty.util.model.yml index 6e2e9194454..3ffaf740c07 100644 --- a/java/ql/lib/ext/io.netty.util.model.yml +++ b/java/ql/lib/ext/io.netty.util.model.yml @@ -4,4 +4,26 @@ extensions: extensible: summaryModel data: - ["io.netty.util", "ReferenceCounted", True, "retain", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] - - ["io.netty.util", "ReferenceCounted", True, "touch", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] \ No newline at end of file + - ["io.netty.util", "ReferenceCounted", True, "touch", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["io.netty.util", AsciiString", False, "AsciiString", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["io.netty.util", AsciiString", False, "array", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.util", AsciiString", False, "cached", "(String)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["io.netty.util", AsciiString", False, "concat", "(CharSequence)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.util", AsciiString", False, "concat", "(CharSequence)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["io.netty.util", AsciiString", False, "copy", "(int,byte[],int,int)", "", "Argument[-1]", "Argument[1]", "taint", "manual"] + - ["io.netty.util", AsciiString", False, "copy", "(int,char[],int,int)", "", "Argument[-1]", "Argument[1]", "taint", "manual"] + - ["io.netty.util", AsciiString", False, "of", "(ChrSequence)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["io.netty.util", AsciiString", False, "replace", "(char,char)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.util", AsciiString", False, "split", "(char)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.util", AsciiString", False, "split", "(String,int)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.util", AsciiString", False, "split", "(char)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.util", AsciiString", False, "subSequence", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.util", AsciiString", False, "toByteArray", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.util", AsciiString", False, "toCharArray", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.util", AsciiString", False, "toString", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.util", AsciiString", False, "toLowerCase", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.util", AsciiString", False, "toUpperCase", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.util", AsciiString", False, "trim", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + + + \ No newline at end of file From 2fb560a170eebd9c825e42d19e1e9b6e78d0e133 Mon Sep 17 00:00:00 2001 From: Joe Farebrother <joefarebrother@github.com> Date: Tue, 28 Feb 2023 17:02:08 +0000 Subject: [PATCH 369/631] Add more models for message decoder sources an headers fluent methods --- .../ext/io.netty.handler.codec.http.model.yml | 9 +++++- .../lib/ext/io.netty.handler.codec.model.yml | 29 +++++++++++++++++++ 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/java/ql/lib/ext/io.netty.handler.codec.http.model.yml b/java/ql/lib/ext/io.netty.handler.codec.http.model.yml index 4ae2334b2e7..25703f335cc 100644 --- a/java/ql/lib/ext/io.netty.handler.codec.http.model.yml +++ b/java/ql/lib/ext/io.netty.handler.codec.http.model.yml @@ -40,4 +40,11 @@ extensions: - ["io.netty.handler.codec.http", "QueryStringDecoder", True, "rawQuery", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - ["io.netty.handler.codec.http", "QueryStringDecoder", True, "toString", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - ["io.netty.handler.codec.http", "QueryStringDecoder", True, "uri", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - + - ["io.netty.handler.codec.http", "HttpHeaders", True, "add", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["io.netty.handler.codec.http", "HttpHeaders", True, "addInt", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["io.netty.handler.codec.http", "HttpHeaders", True, "addShort", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["io.netty.handler.codec.http", "HttpHeaders", True, "remove", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["io.netty.handler.codec.http", "HttpHeaders", True, "set", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["io.netty.handler.codec.http", "HttpHeaders", True, "setAll", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["io.netty.handler.codec.http", "HttpHeaders", True, "setInt", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["io.netty.handler.codec.http", "HttpHeaders", True, "setShort", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] diff --git a/java/ql/lib/ext/io.netty.handler.codec.model.yml b/java/ql/lib/ext/io.netty.handler.codec.model.yml index e48986ad339..6af0ae99e2d 100644 --- a/java/ql/lib/ext/io.netty.handler.codec.model.yml +++ b/java/ql/lib/ext/io.netty.handler.codec.model.yml @@ -8,10 +8,16 @@ extensions: - ["io.netty.handler.codec", "ByteToMessageDecoder", True, "decodeLast", "", "", "Parameter[1]", "remote", "manual"] - ["io.netty.handler.codec", "ByteToMessageCodec", True, "decode", "", "", "Parameter[1]", "remote", "manual"] - ["io.netty.handler.codec", "ByteToMessageCodec", True, "decodeLast", "", "", "Parameter[1]", "remote", "manual"] + - ["io.netty.handler.codec", "MessageToMessageDecoder", True, "acceptInboundMessage", "", "", "Parameter[0]", "remote", "manual"] + - ["io.netty.handler.codec", "MessageToMessageDecoder", True, "decode", "", "", "Parameter[1]", "remote", "manual"] + - ["io.netty.handler.codec", "MessageToMessageCodec", True, "acceptInboundMessage", "", "", "Parameter[0]", "remote", "manual"] + - ["io.netty.handler.codec", "MessageToMessageCodec", True, "decode", "", "", "Parameter[1]", "remote", "manual"] - addsTo: pack: codeql/java-all extensible: summaryModel data: + - ["io.netty.handler.codec", "ByteToMessageDecoder$Cumulator", True, "cumulate", "(ByteBufAllocator,ByteBuf,ByteBuf)", "", "Argument[1]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec", "ByteToMessageDecoder$Cumulator", True, "cumulate", "(ByteBufAllocator,ByteBuf,ByteBuf)", "", "Argument[2]", "ReturnValue", "taint", "manual"] - ["io.netty.handler.codec", "HeadersUtils", False, "getAsString", "(Headers,Object)", "", "Argument[0]", "ReturnValue", "taint", "manual"] - ["io.netty.handler.codec", "HeadersUtils", False, "getAllAsString", "(Headers,Object)", "", "Argument[0]", "ReturnValue", "taint", "manual"] - ["io.netty.handler.codec", "HeadersUtils", False, "namesAsString", "(Headers)", "", "Argument[0]", "ReturnValue", "taint", "manual"] @@ -27,3 +33,26 @@ extensions: - ["io.netty.handler.codec", "Headers", True, "getAndRemove", "(Object,Object)", "", "Argument[1]", "ReturnValue", "value", "manual"] - ["io.netty.handler.codec", "Headers", True, "iterator", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - ["io.netty.handler.codec", "Headers", True, "names", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec", "Headers", True, "add", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["io.netty.handler.codec", "Headers", True, "addBoolean", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["io.netty.handler.codec", "Headers", True, "addByte", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["io.netty.handler.codec", "Headers", True, "addChar", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["io.netty.handler.codec", "Headers", True, "addDouble", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["io.netty.handler.codec", "Headers", True, "addFloat", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["io.netty.handler.codec", "Headers", True, "addInt", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["io.netty.handler.codec", "Headers", True, "addLong", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["io.netty.handler.codec", "Headers", True, "addObject", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["io.netty.handler.codec", "Headers", True, "addShort", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["io.netty.handler.codec", "Headers", True, "addTimeMillis", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["io.netty.handler.codec", "Headers", True, "set", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["io.netty.handler.codec", "Headers", True, "setAll", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["io.netty.handler.codec", "Headers", True, "setBoolean", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["io.netty.handler.codec", "Headers", True, "setByte", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["io.netty.handler.codec", "Headers", True, "setChar", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["io.netty.handler.codec", "Headers", True, "setDouble", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["io.netty.handler.codec", "Headers", True, "setFloat", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["io.netty.handler.codec", "Headers", True, "setInt", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["io.netty.handler.codec", "Headers", True, "setLong", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["io.netty.handler.codec", "Headers", True, "setObject", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["io.netty.handler.codec", "Headers", True, "setShort", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["io.netty.handler.codec", "Headers", True, "setTimeMillis", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] From 0124d81145e6a50a9392062ff4c1293ad54deffb Mon Sep 17 00:00:00 2001 From: Joe Farebrother <joefarebrother@github.com> Date: Tue, 28 Feb 2023 17:29:34 +0000 Subject: [PATCH 370/631] Fix models --- java/ql/lib/ext/io.netty.buffer.model.yml | 16 +++++----- java/ql/lib/ext/io.netty.util.model.yml | 38 +++++++++++------------ 2 files changed, 27 insertions(+), 27 deletions(-) diff --git a/java/ql/lib/ext/io.netty.buffer.model.yml b/java/ql/lib/ext/io.netty.buffer.model.yml index fcd308d3aa5..33a098f85e4 100644 --- a/java/ql/lib/ext/io.netty.buffer.model.yml +++ b/java/ql/lib/ext/io.netty.buffer.model.yml @@ -137,7 +137,7 @@ extensions: - ["io.netty.buffer", "CompositeByteBuf", True, "addComponent", "(ByteBuf)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] - ["io.netty.buffer", "CompositeByteBuf", True, "addComponent", "(int,ByteBuf)", "", "Argument[1]", "Argument[-1]", "taint", "manual"] - ["io.netty.buffer", "CompositeByteBuf", True, "addComponent", "(boolean,ByteBuf)", "", "Argument[1]", "Argument[-1]", "taint", "manual"] - - ["io.netty.buffer", "CompositeByteBuf", True, "addComponent", "(int,boolean,ByteBuf)", "", "Argument[2]", "Argument[-1]", "taint", "manual"] + - ["io.netty.buffer", "CompositeByteBuf", True, "addComponent", "(boolean,int,ByteBuf)", "", "Argument[2]", "Argument[-1]", "taint", "manual"] - ["io.netty.buffer", "CompositeByteBuf", True, "addComponents", "(ByteBuf[])", "", "Argument[0].ArrayElement", "Argument[-1]", "taint", "manual"] - ["io.netty.buffer", "CompositeByteBuf", True, "addComponents", "(int,ByteBuf[])", "", "Argument[1].ArrayElement", "Argument[-1]", "taint", "manual"] - ["io.netty.buffer", "CompositeByteBuf", True, "addComponents", "(boolean,ByteBuf[])", "", "Argument[1].ArrayElement", "Argument[-1]", "taint", "manual"] @@ -156,10 +156,10 @@ extensions: - ["io.netty.buffer", "Unpooled", False, "copiedBuffer", "(ByteBuf[])", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "manual"] - ["io.netty.buffer", "Unpooled", False, "copiedBuffer", "(ByteBuffer)", "", "Argument[0]", "ReturnValue", "taint", "manual"] - ["io.netty.buffer", "Unpooled", False, "copiedBuffer", "(ByteBuffer[])", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "manual"] - - ["io.netty.buffer", "Unpooled", False, "copiedBuffer", "(char[],CharSet)", "", "Argument[0]", "ReturnValue", "taint", "manual"] - - ["io.netty.buffer", "Unpooled", False, "copiedBuffer", "(char[],int,int,CharSet)", "", "Argument[0]", "ReturnValue", "taint", "manual"] - - ["io.netty.buffer", "Unpooled", False, "copiedBuffer", "(CharSequence,CharSet)", "", "Argument[0]", "ReturnValue", "taint", "manual"] - - ["io.netty.buffer", "Unpooled", False, "copiedBuffer", "(CharSequence,int,int,CharSet)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["io.netty.buffer", "Unpooled", False, "copiedBuffer", "(char[],Charset)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["io.netty.buffer", "Unpooled", False, "copiedBuffer", "(char[],int,int,Charset)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["io.netty.buffer", "Unpooled", False, "copiedBuffer", "(CharSequence,Charset)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["io.netty.buffer", "Unpooled", False, "copiedBuffer", "(CharSequence,int,int,Charset)", "", "Argument[0]", "ReturnValue", "taint", "manual"] - ["io.netty.buffer", "Unpooled", False, "unmodifiableBuffer", "(ByteBuf)", "", "Argument[0]", "ReturnValue", "taint", "manual"] - ["io.netty.buffer", "Unpooled", False, "unmodifiableBuffer", "(ByteBuf[])", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "manual"] - ["io.netty.buffer", "Unpooled", False, "unreleasableBuffer", "(ByteBuf)", "", "Argument[0]", "ReturnValue", "taint", "manual"] @@ -179,8 +179,8 @@ extensions: - ["io.netty.buffer", "ByteBufUtil", False, "copy", "(AsciiString,int,ByteBuf,int,int)", "", "Argument[0]", "Argument[2]", "taint", "manual"] - ["io.netty.buffer", "ByteBufUtil", False, "decodeHexDump", "(CharSequence)", "", "Argument[0]", "ReturnValue", "taint", "manual"] - ["io.netty.buffer", "ByteBufUtil", False, "decodeHexDump", "(CharSequence,int,int)", "", "Argument[0]", "ReturnValue", "taint", "manual"] - - ["io.netty.buffer", "ByteBufUtil", False, "encodeString", "(ByteBufAllocator,CharBuffer,CharSet)", "", "Argument[1]", "ReturnValue", "taint", "manual"] - - ["io.netty.buffer", "ByteBufUtil", False, "encodeString", "(ByteBufAllocator,CharBuffer,CharSet,int)", "", "Argument[1]", "ReturnValue", "taint", "manual"] + - ["io.netty.buffer", "ByteBufUtil", False, "encodeString", "(ByteBufAllocator,CharBuffer,Charset)", "", "Argument[1]", "ReturnValue", "taint", "manual"] + - ["io.netty.buffer", "ByteBufUtil", False, "encodeString", "(ByteBufAllocator,CharBuffer,Charset,int)", "", "Argument[1]", "ReturnValue", "taint", "manual"] - ["io.netty.buffer", "ByteBufUtil", False, "ensureAccessible", "(ByteBuf)", "", "Argument[0]", "ReturnValue", "value", "manual"] - ["io.netty.buffer", "ByteBufUtil", False, "getBytes", "(ByteBuf)", "", "Argument[0]", "ReturnValue", "taint", "manual"] - ["io.netty.buffer", "ByteBufUtil", False, "getBytes", "(ByteBuf,int,int)", "", "Argument[0]", "ReturnValue", "taint", "manual"] @@ -194,7 +194,7 @@ extensions: - ["io.netty.buffer", "ByteBufUtil", False, "writeUtf8", "(ByteBuf,CharSequence,int,int)", "", "Argument[1]", "Argument[0]", "taint", "manual"] - ["io.netty.buffer", "ByteBufUtil", False, "writeUtf8", "(ByteBufAllocator,CharSequence)", "", "Argument[1]", "ReturnValue", "taint", "manual"] - ["io.netty.buffer", "ByteBufInputStream", True, "ByteBufInputStream", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] - - ["io.netty.buffer", "ByteBufOutputStream", True, "ByteBufInputStream", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["io.netty.buffer", "ByteBufOutputStream", True, "ByteBufOutputStream", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] - ["io.netty.buffer", "ByteBufOutputStream", True, "buffer", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] diff --git a/java/ql/lib/ext/io.netty.util.model.yml b/java/ql/lib/ext/io.netty.util.model.yml index 3ffaf740c07..8657e445434 100644 --- a/java/ql/lib/ext/io.netty.util.model.yml +++ b/java/ql/lib/ext/io.netty.util.model.yml @@ -5,25 +5,25 @@ extensions: data: - ["io.netty.util", "ReferenceCounted", True, "retain", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] - ["io.netty.util", "ReferenceCounted", True, "touch", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] - - ["io.netty.util", AsciiString", False, "AsciiString", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] - - ["io.netty.util", AsciiString", False, "array", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.util", AsciiString", False, "cached", "(String)", "", "Argument[0]", "ReturnValue", "taint", "manual"] - - ["io.netty.util", AsciiString", False, "concat", "(CharSequence)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.util", AsciiString", False, "concat", "(CharSequence)", "", "Argument[0]", "ReturnValue", "taint", "manual"] - - ["io.netty.util", AsciiString", False, "copy", "(int,byte[],int,int)", "", "Argument[-1]", "Argument[1]", "taint", "manual"] - - ["io.netty.util", AsciiString", False, "copy", "(int,char[],int,int)", "", "Argument[-1]", "Argument[1]", "taint", "manual"] - - ["io.netty.util", AsciiString", False, "of", "(ChrSequence)", "", "Argument[0]", "ReturnValue", "taint", "manual"] - - ["io.netty.util", AsciiString", False, "replace", "(char,char)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.util", AsciiString", False, "split", "(char)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.util", AsciiString", False, "split", "(String,int)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.util", AsciiString", False, "split", "(char)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.util", AsciiString", False, "subSequence", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.util", AsciiString", False, "toByteArray", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.util", AsciiString", False, "toCharArray", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.util", AsciiString", False, "toString", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.util", AsciiString", False, "toLowerCase", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.util", AsciiString", False, "toUpperCase", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.util", AsciiString", False, "trim", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.util", "AsciiString", False, "AsciiString", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["io.netty.util", "AsciiString", False, "array", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.util", "AsciiString", False, "cached", "(String)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["io.netty.util", "AsciiString", False, "concat", "(CharSequence)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.util", "AsciiString", False, "concat", "(CharSequence)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["io.netty.util", "AsciiString", False, "copy", "(int,byte[],int,int)", "", "Argument[-1]", "Argument[1]", "taint", "manual"] + - ["io.netty.util", "AsciiString", False, "copy", "(int,char[],int,int)", "", "Argument[-1]", "Argument[1]", "taint", "manual"] + - ["io.netty.util", "AsciiString", False, "of", "(CharSequence)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["io.netty.util", "AsciiString", False, "replace", "(char,char)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.util", "AsciiString", False, "split", "(char)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.util", "AsciiString", False, "split", "(String,int)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.util", "AsciiString", False, "split", "(char)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.util", "AsciiString", False, "subSequence", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.util", "AsciiString", False, "toByteArray", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.util", "AsciiString", False, "toCharArray", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.util", "AsciiString", False, "toString", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.util", "AsciiString", False, "toLowerCase", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.util", "AsciiString", False, "toUpperCase", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.util", "AsciiString", False, "trim", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] \ No newline at end of file From 312c3eae061b735b06386ae2769839009afdfc9a Mon Sep 17 00:00:00 2001 From: Joe Farebrother <joefarebrother@github.com> Date: Tue, 28 Feb 2023 17:57:56 +0000 Subject: [PATCH 371/631] Generate tests and stubs, fix an issue --- java/ql/lib/ext/io.netty.util.model.yml | 3 +- .../frameworks/netty/generated/Test.java | 1110 +++++++++++++++++ .../io/netty/buffer/ByteBufInputStream.java | 40 + .../io/netty/buffer/ByteBufOutputStream.java | 30 + .../io/netty/buffer/ByteBufUtil.java | 64 + .../netty-4.1.x/io/netty/buffer/Unpooled.java | 66 + 6 files changed, 1312 insertions(+), 1 deletion(-) create mode 100644 java/ql/test/stubs/netty-4.1.x/io/netty/buffer/ByteBufInputStream.java create mode 100644 java/ql/test/stubs/netty-4.1.x/io/netty/buffer/ByteBufOutputStream.java create mode 100644 java/ql/test/stubs/netty-4.1.x/io/netty/buffer/ByteBufUtil.java create mode 100644 java/ql/test/stubs/netty-4.1.x/io/netty/buffer/Unpooled.java diff --git a/java/ql/lib/ext/io.netty.util.model.yml b/java/ql/lib/ext/io.netty.util.model.yml index 8657e445434..d6333dc6009 100644 --- a/java/ql/lib/ext/io.netty.util.model.yml +++ b/java/ql/lib/ext/io.netty.util.model.yml @@ -23,7 +23,8 @@ extensions: - ["io.netty.util", "AsciiString", False, "toString", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - ["io.netty.util", "AsciiString", False, "toLowerCase", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - ["io.netty.util", "AsciiString", False, "toUpperCase", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.util", "AsciiString", False, "trim", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.util", "AsciiString", False, "trim", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.util", "AsciiString", False, "trim", "(CharSequence)", "", "Argument[0]", "ReturnValue", "taint", "manual"] \ No newline at end of file diff --git a/java/ql/test/library-tests/frameworks/netty/generated/Test.java b/java/ql/test/library-tests/frameworks/netty/generated/Test.java index b664a1efe98..9463d4c4fe1 100644 --- a/java/ql/test/library-tests/frameworks/netty/generated/Test.java +++ b/java/ql/test/library-tests/frameworks/netty/generated/Test.java @@ -6,13 +6,19 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBufAllocator; import io.netty.buffer.ByteBufConvertible; import io.netty.buffer.ByteBufHolder; +import io.netty.buffer.ByteBufInputStream; +import io.netty.buffer.ByteBufOutputStream; +import io.netty.buffer.ByteBufUtil; import io.netty.buffer.CompositeByteBuf; import io.netty.buffer.DefaultByteBufHolder; import io.netty.buffer.SwappedByteBuf; +import io.netty.buffer.Unpooled; import io.netty.channel.DefaultFileRegion; import io.netty.channel.FileRegion; +import io.netty.handler.codec.ByteToMessageDecoder; import io.netty.handler.codec.Headers; import io.netty.handler.codec.HeadersUtils; +// import io.netty.handler.codec.V; // testgen bug? import io.netty.handler.codec.base64.Base64; import io.netty.handler.codec.base64.Base64Dialect; import io.netty.handler.codec.http.FullHttpMessage; @@ -45,11 +51,13 @@ import io.netty.handler.codec.http2.Http2HeadersFrame; import io.netty.handler.codec.http2.Http2PushPromiseFrame; import io.netty.handler.codec.http2.HttpConversionUtil; import io.netty.util.AbstractReferenceCounted; +import io.netty.util.AsciiString; import io.netty.util.ReferenceCounted; import java.io.InputStream; import java.io.OutputStream; import java.net.URI; import java.nio.ByteBuffer; +import java.nio.CharBuffer; import java.nio.channels.FileChannel; import java.nio.channels.GatheringByteChannel; import java.nio.channels.ScatteringByteChannel; @@ -3581,6 +3589,475 @@ public class Test { out = in.retainedDuplicate(); sink(out); // $ hasTaintFlow } + { + // "io.netty.buffer;ByteBufInputStream;true;ByteBufInputStream;;;Argument[0];Argument[-1];taint;manual" + ByteBufInputStream out = null; + ByteBuf in = (ByteBuf)source(); + out = new ByteBufInputStream(in); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBufInputStream;true;ByteBufInputStream;;;Argument[0];Argument[-1];taint;manual" + ByteBufInputStream out = null; + ByteBuf in = (ByteBuf)source(); + out = new ByteBufInputStream(in, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBufInputStream;true;ByteBufInputStream;;;Argument[0];Argument[-1];taint;manual" + ByteBufInputStream out = null; + ByteBuf in = (ByteBuf)source(); + out = new ByteBufInputStream(in, 0, false); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBufInputStream;true;ByteBufInputStream;;;Argument[0];Argument[-1];taint;manual" + ByteBufInputStream out = null; + ByteBuf in = (ByteBuf)source(); + out = new ByteBufInputStream(in, false); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBufOutputStream;true;ByteBufOutputStream;;;Argument[0];Argument[-1];taint;manual" + ByteBufOutputStream out = null; + ByteBuf in = (ByteBuf)source(); + out = new ByteBufOutputStream(in); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBufOutputStream;true;buffer;();;Argument[-1];ReturnValue;taint;manual" + ByteBuf out = null; + ByteBufOutputStream in = (ByteBufOutputStream)source(); + out = in.buffer(); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBufUtil;false;copy;(AsciiString,ByteBuf);;Argument[0];Argument[1];taint;manual" + ByteBuf out = null; + AsciiString in = (AsciiString)source(); + ByteBufUtil.copy(in, out); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBufUtil;false;copy;(AsciiString,int,ByteBuf,int);;Argument[0];Argument[2];taint;manual" + ByteBuf out = null; + AsciiString in = (AsciiString)source(); + ByteBufUtil.copy(in, 0, out, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBufUtil;false;copy;(AsciiString,int,ByteBuf,int,int);;Argument[0];Argument[2];taint;manual" + ByteBuf out = null; + AsciiString in = (AsciiString)source(); + ByteBufUtil.copy(in, 0, out, 0, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBufUtil;false;decodeHexDump;(CharSequence);;Argument[0];ReturnValue;taint;manual" + byte[] out = null; + CharSequence in = (CharSequence)source(); + out = ByteBufUtil.decodeHexDump(in); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBufUtil;false;decodeHexDump;(CharSequence,int,int);;Argument[0];ReturnValue;taint;manual" + byte[] out = null; + CharSequence in = (CharSequence)source(); + out = ByteBufUtil.decodeHexDump(in, 0, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBufUtil;false;encodeString;(ByteBufAllocator,CharBuffer,Charset);;Argument[1];ReturnValue;taint;manual" + ByteBuf out = null; + CharBuffer in = (CharBuffer)source(); + out = ByteBufUtil.encodeString(null, in, null); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBufUtil;false;encodeString;(ByteBufAllocator,CharBuffer,Charset,int);;Argument[1];ReturnValue;taint;manual" + ByteBuf out = null; + CharBuffer in = (CharBuffer)source(); + out = ByteBufUtil.encodeString(null, in, null, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBufUtil;false;ensureAccessible;(ByteBuf);;Argument[0];ReturnValue;value;manual" + ByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out = ByteBufUtil.ensureAccessible(in); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBufUtil;false;getBytes;(ByteBuf);;Argument[0];ReturnValue;taint;manual" + byte[] out = null; + ByteBuf in = (ByteBuf)source(); + out = ByteBufUtil.getBytes(in); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBufUtil;false;getBytes;(ByteBuf,int,int);;Argument[0];ReturnValue;taint;manual" + byte[] out = null; + ByteBuf in = (ByteBuf)source(); + out = ByteBufUtil.getBytes(in, 0, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBufUtil;false;getBytes;(ByteBuf,int,int,boolean);;Argument[0];ReturnValue;taint;manual" + byte[] out = null; + ByteBuf in = (ByteBuf)source(); + out = ByteBufUtil.getBytes(in, 0, 0, false); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBufUtil;false;readBytes;(ByteBufAllocator,ByteBuf,int);;Argument[1];ReturnValue;taint;manual" + ByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out = ByteBufUtil.readBytes(null, in, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBufUtil;false;reserveAndWriteUtf8;(ByteBuf,CharSequence,int);;Argument[1];Argument[0];taint;manual" + ByteBuf out = null; + CharSequence in = (CharSequence)source(); + ByteBufUtil.reserveAndWriteUtf8(out, in, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBufUtil;false;reserveAndWriteUtf8;(ByteBuf,CharSequence,int,int,int);;Argument[1];Argument[0];taint;manual" + ByteBuf out = null; + CharSequence in = (CharSequence)source(); + ByteBufUtil.reserveAndWriteUtf8(out, in, 0, 0, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBufUtil;false;writeAscii;(ByteBuf,CharSequence);;Argument[1];Argument[0];taint;manual" + ByteBuf out = null; + CharSequence in = (CharSequence)source(); + ByteBufUtil.writeAscii(out, in); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBufUtil;false;writeAscii;(ByteBufAllocator,CharSequence);;Argument[1];ReturnValue;taint;manual" + ByteBuf out = null; + CharSequence in = (CharSequence)source(); + out = ByteBufUtil.writeAscii((ByteBufAllocator)null, in); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBufUtil;false;writeUtf8;(ByteBuf,CharSequence);;Argument[1];Argument[0];taint;manual" + ByteBuf out = null; + CharSequence in = (CharSequence)source(); + ByteBufUtil.writeUtf8(out, in); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBufUtil;false;writeUtf8;(ByteBuf,CharSequence,int,int);;Argument[1];Argument[0];taint;manual" + ByteBuf out = null; + CharSequence in = (CharSequence)source(); + ByteBufUtil.writeUtf8(out, in, 0, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBufUtil;false;writeUtf8;(ByteBufAllocator,CharSequence);;Argument[1];ReturnValue;taint;manual" + ByteBuf out = null; + CharSequence in = (CharSequence)source(); + out = ByteBufUtil.writeUtf8((ByteBufAllocator)null, in); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;CompositeByteBuf;false;CompositeByteBuf;(ByteBufAllocator,boolean,int,ByteBuf[]);;Argument[3].ArrayElement;Argument[-1];taint;manual" + CompositeByteBuf out = null; + ByteBuf[] in = (ByteBuf[])new ByteBuf[]{(ByteBuf)source()}; + out = new CompositeByteBuf((ByteBufAllocator)null, false, 0, in); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;CompositeByteBuf;false;CompositeByteBuf;(ByteBufAllocator,boolean,int,Iterable);;Argument[3].Element;Argument[-1];taint;manual" + CompositeByteBuf out = null; + Iterable in = (Iterable)List.of(source()); + out = new CompositeByteBuf((ByteBufAllocator)null, false, 0, in); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;CompositeByteBuf;true;addComponent;(ByteBuf);;Argument[0];Argument[-1];taint;manual" + CompositeByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out.addComponent(in); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;CompositeByteBuf;true;addComponent;(boolean,ByteBuf);;Argument[1];Argument[-1];taint;manual" + CompositeByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out.addComponent(false, in); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;CompositeByteBuf;true;addComponent;(boolean,int,ByteBuf);;Argument[2];Argument[-1];taint;manual" + CompositeByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out.addComponent(false, 0, in); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;CompositeByteBuf;true;addComponent;(int,ByteBuf);;Argument[1];Argument[-1];taint;manual" + CompositeByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out.addComponent(0, in); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;CompositeByteBuf;true;addComponents;(ByteBuf[]);;Argument[0].ArrayElement;Argument[-1];taint;manual" + CompositeByteBuf out = null; + ByteBuf[] in = (ByteBuf[])new ByteBuf[]{(ByteBuf)source()}; + out.addComponents(in); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;CompositeByteBuf;true;addComponents;(Iterable);;Argument[0].Element;Argument[-1];taint;manual" + CompositeByteBuf out = null; + Iterable in = (Iterable)List.of(source()); + out.addComponents(in); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;CompositeByteBuf;true;addComponents;(boolean,ByteBuf[]);;Argument[1].ArrayElement;Argument[-1];taint;manual" + CompositeByteBuf out = null; + ByteBuf[] in = (ByteBuf[])new ByteBuf[]{(ByteBuf)source()}; + out.addComponents(false, in); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;CompositeByteBuf;true;addComponents;(boolean,Iterable);;Argument[1].Element;Argument[-1];taint;manual" + CompositeByteBuf out = null; + Iterable in = (Iterable)List.of(source()); + out.addComponents(false, in); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;CompositeByteBuf;true;addComponents;(int,ByteBuf[]);;Argument[1].ArrayElement;Argument[-1];taint;manual" + CompositeByteBuf out = null; + ByteBuf[] in = (ByteBuf[])new ByteBuf[]{(ByteBuf)source()}; + out.addComponents(0, in); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;CompositeByteBuf;true;addComponents;(int,Iterable);;Argument[1].Element;Argument[-1];taint;manual" + CompositeByteBuf out = null; + Iterable in = (Iterable)List.of(source()); + out.addComponents(0, in); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;CompositeByteBuf;true;addFlattenedComponents;(boolean,ByteBuf);;Argument[1];Argument[-1];taint;manual" + CompositeByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out.addFlattenedComponents(false, in); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;CompositeByteBuf;true;component;(int);;Argument[-1];ReturnValue;taint;manual" + ByteBuf out = null; + CompositeByteBuf in = (CompositeByteBuf)source(); + out = in.component(0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;CompositeByteBuf;true;componentAtOffset;(int);;Argument[-1];ReturnValue;taint;manual" + ByteBuf out = null; + CompositeByteBuf in = (CompositeByteBuf)source(); + out = in.componentAtOffset(0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;CompositeByteBuf;true;consolidate;();;Argument[-1];ReturnValue;taint;manual" + CompositeByteBuf out = null; + CompositeByteBuf in = (CompositeByteBuf)source(); + out = in.consolidate(); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;CompositeByteBuf;true;consolidate;(int,int);;Argument[-1];ReturnValue;taint;manual" + CompositeByteBuf out = null; + CompositeByteBuf in = (CompositeByteBuf)source(); + out = in.consolidate(0, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;Unpooled;false;copiedBuffer;(ByteBuf);;Argument[0];ReturnValue;taint;manual" + ByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out = Unpooled.copiedBuffer(in); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;Unpooled;false;copiedBuffer;(ByteBuf[]);;Argument[0].ArrayElement;ReturnValue;taint;manual" + ByteBuf out = null; + ByteBuf[] in = (ByteBuf[])new ByteBuf[]{(ByteBuf)source()}; + out = Unpooled.copiedBuffer(in); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;Unpooled;false;copiedBuffer;(ByteBuffer);;Argument[0];ReturnValue;taint;manual" + ByteBuf out = null; + ByteBuffer in = (ByteBuffer)source(); + out = Unpooled.copiedBuffer(in); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;Unpooled;false;copiedBuffer;(ByteBuffer[]);;Argument[0].ArrayElement;ReturnValue;taint;manual" + ByteBuf out = null; + ByteBuffer[] in = (ByteBuffer[])new ByteBuffer[]{(ByteBuffer)source()}; + out = Unpooled.copiedBuffer(in); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;Unpooled;false;copiedBuffer;(CharSequence,Charset);;Argument[0];ReturnValue;taint;manual" + ByteBuf out = null; + CharSequence in = (CharSequence)source(); + out = Unpooled.copiedBuffer(in, (Charset)null); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;Unpooled;false;copiedBuffer;(CharSequence,int,int,Charset);;Argument[0];ReturnValue;taint;manual" + ByteBuf out = null; + CharSequence in = (CharSequence)source(); + out = Unpooled.copiedBuffer(in, 0, 0, (Charset)null); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;Unpooled;false;copiedBuffer;(byte[]);;Argument[0];ReturnValue;taint;manual" + ByteBuf out = null; + byte[] in = (byte[])source(); + out = Unpooled.copiedBuffer(in); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;Unpooled;false;copiedBuffer;(byte[],int,int);;Argument[0];ReturnValue;taint;manual" + ByteBuf out = null; + byte[] in = (byte[])source(); + out = Unpooled.copiedBuffer(in, 0, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;Unpooled;false;copiedBuffer;(byte[][]);;Argument[0].ArrayElement;ReturnValue;taint;manual" + ByteBuf out = null; + byte[][] in = (byte[][])new byte[][]{(byte[])source()}; + out = Unpooled.copiedBuffer(in); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;Unpooled;false;copiedBuffer;(char[],Charset);;Argument[0];ReturnValue;taint;manual" + ByteBuf out = null; + char[] in = (char[])source(); + out = Unpooled.copiedBuffer(in, (Charset)null); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;Unpooled;false;copiedBuffer;(char[],int,int,Charset);;Argument[0];ReturnValue;taint;manual" + ByteBuf out = null; + char[] in = (char[])source(); + out = Unpooled.copiedBuffer(in, 0, 0, (Charset)null); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;Unpooled;false;unmodifiableBuffer;(ByteBuf);;Argument[0];ReturnValue;taint;manual" + ByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out = Unpooled.unmodifiableBuffer(in); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;Unpooled;false;unmodifiableBuffer;(ByteBuf[]);;Argument[0].ArrayElement;ReturnValue;taint;manual" + ByteBuf out = null; + ByteBuf[] in = (ByteBuf[])new ByteBuf[]{(ByteBuf)source()}; + out = Unpooled.unmodifiableBuffer(in); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;Unpooled;false;unreleasableBuffer;(ByteBuf);;Argument[0];ReturnValue;taint;manual" + ByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out = Unpooled.unreleasableBuffer(in); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;Unpooled;false;wrappedBuffer;(ByteBuf);;Argument[0];ReturnValue;taint;manual" + ByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out = Unpooled.wrappedBuffer(in); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;Unpooled;false;wrappedBuffer;(ByteBuf[]);;Argument[0].ArrayElement;ReturnValue;taint;manual" + ByteBuf out = null; + ByteBuf[] in = (ByteBuf[])new ByteBuf[]{(ByteBuf)source()}; + out = Unpooled.wrappedBuffer(in); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;Unpooled;false;wrappedBuffer;(ByteBuffer);;Argument[0];ReturnValue;taint;manual" + ByteBuf out = null; + ByteBuffer in = (ByteBuffer)source(); + out = Unpooled.wrappedBuffer(in); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;Unpooled;false;wrappedBuffer;(ByteBuffer[]);;Argument[0].ArrayElement;ReturnValue;taint;manual" + ByteBuf out = null; + ByteBuffer[] in = (ByteBuffer[])new ByteBuffer[]{(ByteBuffer)source()}; + out = Unpooled.wrappedBuffer(in); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;Unpooled;false;wrappedBuffer;(byte[]);;Argument[0];ReturnValue;taint;manual" + ByteBuf out = null; + byte[] in = (byte[])source(); + out = Unpooled.wrappedBuffer(in); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;Unpooled;false;wrappedBuffer;(byte[],int,int);;Argument[0];ReturnValue;taint;manual" + ByteBuf out = null; + byte[] in = (byte[])source(); + out = Unpooled.wrappedBuffer(in, 0, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;Unpooled;false;wrappedBuffer;(byte[][]);;Argument[0].ArrayElement;ReturnValue;taint;manual" + ByteBuf out = null; + byte[][] in = (byte[][])new byte[][]{(byte[])source()}; + out = Unpooled.wrappedBuffer(in); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;Unpooled;false;wrappedBuffer;(int,ByteBuf[]);;Argument[1].ArrayElement;ReturnValue;taint;manual" + ByteBuf out = null; + ByteBuf[] in = (ByteBuf[])new ByteBuf[]{(ByteBuf)source()}; + out = Unpooled.wrappedBuffer(0, in); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;Unpooled;false;wrappedBuffer;(int,ByteBuffer[]);;Argument[1].ArrayElement;ReturnValue;taint;manual" + ByteBuf out = null; + ByteBuffer[] in = (ByteBuffer[])new ByteBuffer[]{(ByteBuffer)source()}; + out = Unpooled.wrappedBuffer(0, in); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;Unpooled;false;wrappedBuffer;(int,byte[][]);;Argument[1].ArrayElement;ReturnValue;taint;manual" + ByteBuf out = null; + byte[][] in = (byte[][])new byte[][]{(byte[])source()}; + out = Unpooled.wrappedBuffer(0, in); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;Unpooled;false;wrappedUnmodifiableBuffer;(ByteBuf[]);;Argument[0].ArrayElement;ReturnValue;taint;manual" + ByteBuf out = null; + ByteBuf[] in = (ByteBuf[])new ByteBuf[]{(ByteBuf)source()}; + out = Unpooled.wrappedUnmodifiableBuffer(in); + sink(out); // $ hasTaintFlow + } { // "io.netty.handler.codec.base64;Base64;true;decode;;;Argument[0];ReturnValue;taint;manual" ByteBuf out = null; @@ -4204,6 +4681,55 @@ public class Test { out = HttpConversionUtil.toHttpResponse(0, in, false); sink(out); // $ hasTaintFlow } + { + // "io.netty.handler.codec.http;HttpHeaders;true;add;;;Argument[-1];ReturnValue;value;manual" + HttpHeaders out = null; + HttpHeaders in = (HttpHeaders)source(); + out = in.add((CharSequence)null, (Iterable)null); + sink(out); // $ hasValueFlow + } + { + // "io.netty.handler.codec.http;HttpHeaders;true;add;;;Argument[-1];ReturnValue;value;manual" + HttpHeaders out = null; + HttpHeaders in = (HttpHeaders)source(); + out = in.add((CharSequence)null, (Object)null); + sink(out); // $ hasValueFlow + } + { + // "io.netty.handler.codec.http;HttpHeaders;true;add;;;Argument[-1];ReturnValue;value;manual" + HttpHeaders out = null; + HttpHeaders in = (HttpHeaders)source(); + out = in.add((String)null, (Iterable)null); + sink(out); // $ hasValueFlow + } + { + // "io.netty.handler.codec.http;HttpHeaders;true;add;;;Argument[-1];ReturnValue;value;manual" + HttpHeaders out = null; + HttpHeaders in = (HttpHeaders)source(); + out = in.add((String)null, (Object)null); + sink(out); // $ hasValueFlow + } + { + // "io.netty.handler.codec.http;HttpHeaders;true;add;;;Argument[-1];ReturnValue;value;manual" + HttpHeaders out = null; + HttpHeaders in = (HttpHeaders)source(); + out = in.add(null); + sink(out); // $ hasValueFlow + } + { + // "io.netty.handler.codec.http;HttpHeaders;true;addInt;;;Argument[-1];ReturnValue;value;manual" + HttpHeaders out = null; + HttpHeaders in = (HttpHeaders)source(); + out = in.addInt(null, 0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.handler.codec.http;HttpHeaders;true;addShort;;;Argument[-1];ReturnValue;value;manual" + HttpHeaders out = null; + HttpHeaders in = (HttpHeaders)source(); + out = in.addShort(null, (short)0); + sink(out); // $ hasValueFlow + } { // "io.netty.handler.codec.http;HttpHeaders;true;copy;;;Argument[-1];ReturnValue;taint;manual" HttpHeaders out = null; @@ -4366,6 +4892,76 @@ public class Test { out = HttpHeaders.newEntity(in); sink(out); // $ hasTaintFlow } + { + // "io.netty.handler.codec.http;HttpHeaders;true;remove;;;Argument[-1];ReturnValue;value;manual" + HttpHeaders out = null; + HttpHeaders in = (HttpHeaders)source(); + out = in.remove((CharSequence)null); + sink(out); // $ hasValueFlow + } + { + // "io.netty.handler.codec.http;HttpHeaders;true;remove;;;Argument[-1];ReturnValue;value;manual" + HttpHeaders out = null; + HttpHeaders in = (HttpHeaders)source(); + out = in.remove((String)null); + sink(out); // $ hasValueFlow + } + { + // "io.netty.handler.codec.http;HttpHeaders;true;set;;;Argument[-1];ReturnValue;value;manual" + HttpHeaders out = null; + HttpHeaders in = (HttpHeaders)source(); + out = in.set((CharSequence)null, (Iterable)null); + sink(out); // $ hasValueFlow + } + { + // "io.netty.handler.codec.http;HttpHeaders;true;set;;;Argument[-1];ReturnValue;value;manual" + HttpHeaders out = null; + HttpHeaders in = (HttpHeaders)source(); + out = in.set((CharSequence)null, (Object)null); + sink(out); // $ hasValueFlow + } + { + // "io.netty.handler.codec.http;HttpHeaders;true;set;;;Argument[-1];ReturnValue;value;manual" + HttpHeaders out = null; + HttpHeaders in = (HttpHeaders)source(); + out = in.set((String)null, (Iterable)null); + sink(out); // $ hasValueFlow + } + { + // "io.netty.handler.codec.http;HttpHeaders;true;set;;;Argument[-1];ReturnValue;value;manual" + HttpHeaders out = null; + HttpHeaders in = (HttpHeaders)source(); + out = in.set((String)null, (Object)null); + sink(out); // $ hasValueFlow + } + { + // "io.netty.handler.codec.http;HttpHeaders;true;set;;;Argument[-1];ReturnValue;value;manual" + HttpHeaders out = null; + HttpHeaders in = (HttpHeaders)source(); + out = in.set(null); + sink(out); // $ hasValueFlow + } + { + // "io.netty.handler.codec.http;HttpHeaders;true;setAll;;;Argument[-1];ReturnValue;value;manual" + HttpHeaders out = null; + HttpHeaders in = (HttpHeaders)source(); + out = in.setAll(null); + sink(out); // $ hasValueFlow + } + { + // "io.netty.handler.codec.http;HttpHeaders;true;setInt;;;Argument[-1];ReturnValue;value;manual" + HttpHeaders out = null; + HttpHeaders in = (HttpHeaders)source(); + out = in.setInt(null, 0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.handler.codec.http;HttpHeaders;true;setShort;;;Argument[-1];ReturnValue;value;manual" + HttpHeaders out = null; + HttpHeaders in = (HttpHeaders)source(); + out = in.setShort(null, (short)0); + sink(out); // $ hasValueFlow + } { // "io.netty.handler.codec.http;HttpHeaders;true;toString;;;Argument[-1];ReturnValue;taint;manual" String out = null; @@ -4541,6 +5137,134 @@ public class Test { out = in.uri(); sink(out); // $ hasTaintFlow } + { + // "io.netty.handler.codec;ByteToMessageDecoder$Cumulator;true;cumulate;(ByteBufAllocator,ByteBuf,ByteBuf);;Argument[1];ReturnValue;taint;manual" + ByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + ByteToMessageDecoder.Cumulator instance = null; + out = instance.cumulate(null, in, null); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec;ByteToMessageDecoder$Cumulator;true;cumulate;(ByteBufAllocator,ByteBuf,ByteBuf);;Argument[2];ReturnValue;taint;manual" + ByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + ByteToMessageDecoder.Cumulator instance = null; + out = instance.cumulate(null, null, in); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec;Headers;true;add;;;Argument[-1];ReturnValue;value;manual" + Headers out = null; + Headers in = (Headers)source(); + out = in.add((Object)null, (Iterable)null); + sink(out); // $ hasValueFlow + } + { + // "io.netty.handler.codec;Headers;true;add;;;Argument[-1];ReturnValue;value;manual" + Headers out = null; + Headers in = (Headers)source(); + out = in.add((Object)null, (Object)null); + sink(out); // $ hasValueFlow + } + { + // "io.netty.handler.codec;Headers;true;add;;;Argument[-1];ReturnValue;value;manual" + Headers out = null; + Headers in = (Headers)source(); + out = in.add((Object)null, (Object[])null); + sink(out); // $ hasValueFlow + } + { + // "io.netty.handler.codec;Headers;true;add;;;Argument[-1];ReturnValue;value;manual" + Headers out = null; + Headers in = (Headers)source(); + out = in.add(null); + sink(out); // $ hasValueFlow + } + { + // "io.netty.handler.codec;Headers;true;addBoolean;;;Argument[-1];ReturnValue;value;manual" + Headers out = null; + Headers in = (Headers)source(); + out = in.addBoolean(null, false); + sink(out); // $ hasValueFlow + } + { + // "io.netty.handler.codec;Headers;true;addByte;;;Argument[-1];ReturnValue;value;manual" + Headers out = null; + Headers in = (Headers)source(); + out = in.addByte(null, (byte)0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.handler.codec;Headers;true;addChar;;;Argument[-1];ReturnValue;value;manual" + Headers out = null; + Headers in = (Headers)source(); + out = in.addChar(null, '\0'); + sink(out); // $ hasValueFlow + } + { + // "io.netty.handler.codec;Headers;true;addDouble;;;Argument[-1];ReturnValue;value;manual" + Headers out = null; + Headers in = (Headers)source(); + out = in.addDouble(null, 0.0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.handler.codec;Headers;true;addFloat;;;Argument[-1];ReturnValue;value;manual" + Headers out = null; + Headers in = (Headers)source(); + out = in.addFloat(null, 0.0f); + sink(out); // $ hasValueFlow + } + { + // "io.netty.handler.codec;Headers;true;addInt;;;Argument[-1];ReturnValue;value;manual" + Headers out = null; + Headers in = (Headers)source(); + out = in.addInt(null, 0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.handler.codec;Headers;true;addLong;;;Argument[-1];ReturnValue;value;manual" + Headers out = null; + Headers in = (Headers)source(); + out = in.addLong(null, 0L); + sink(out); // $ hasValueFlow + } + { + // "io.netty.handler.codec;Headers;true;addObject;;;Argument[-1];ReturnValue;value;manual" + Headers out = null; + Headers in = (Headers)source(); + out = in.addObject((Object)null, (Iterable)null); + sink(out); // $ hasValueFlow + } + { + // "io.netty.handler.codec;Headers;true;addObject;;;Argument[-1];ReturnValue;value;manual" + Headers out = null; + Headers in = (Headers)source(); + out = in.addObject((Object)null, (Object)null); + sink(out); // $ hasValueFlow + } + { + // "io.netty.handler.codec;Headers;true;addObject;;;Argument[-1];ReturnValue;value;manual" + Headers out = null; + Headers in = (Headers)source(); + out = in.addObject((Object)null, (Object[])null); + sink(out); // $ hasValueFlow + } + { + // "io.netty.handler.codec;Headers;true;addShort;;;Argument[-1];ReturnValue;value;manual" + Headers out = null; + Headers in = (Headers)source(); + out = in.addShort(null, (short)0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.handler.codec;Headers;true;addTimeMillis;;;Argument[-1];ReturnValue;value;manual" + Headers out = null; + Headers in = (Headers)source(); + out = in.addTimeMillis(null, 0L); + sink(out); // $ hasValueFlow + } { // "io.netty.handler.codec;Headers;true;get;(Object);;Argument[-1];ReturnValue;taint;manual" Object out = null; @@ -4613,6 +5337,125 @@ public class Test { out = in.names(); sink(out); // $ hasTaintFlow } + { + // "io.netty.handler.codec;Headers;true;set;;;Argument[-1];ReturnValue;value;manual" + Headers out = null; + Headers in = (Headers)source(); + out = in.set((Object)null, (Iterable)null); + sink(out); // $ hasValueFlow + } + { + // "io.netty.handler.codec;Headers;true;set;;;Argument[-1];ReturnValue;value;manual" + Headers out = null; + Headers in = (Headers)source(); + out = in.set((Object)null, (Object)null); + sink(out); // $ hasValueFlow + } + { + // "io.netty.handler.codec;Headers;true;set;;;Argument[-1];ReturnValue;value;manual" + Headers out = null; + Headers in = (Headers)source(); + out = in.set((Object)null, (Object[])null); + sink(out); // $ hasValueFlow + } + { + // "io.netty.handler.codec;Headers;true;set;;;Argument[-1];ReturnValue;value;manual" + Headers out = null; + Headers in = (Headers)source(); + out = in.set(null); + sink(out); // $ hasValueFlow + } + { + // "io.netty.handler.codec;Headers;true;setAll;;;Argument[-1];ReturnValue;value;manual" + Headers out = null; + Headers in = (Headers)source(); + out = in.setAll(null); + sink(out); // $ hasValueFlow + } + { + // "io.netty.handler.codec;Headers;true;setBoolean;;;Argument[-1];ReturnValue;value;manual" + Headers out = null; + Headers in = (Headers)source(); + out = in.setBoolean(null, false); + sink(out); // $ hasValueFlow + } + { + // "io.netty.handler.codec;Headers;true;setByte;;;Argument[-1];ReturnValue;value;manual" + Headers out = null; + Headers in = (Headers)source(); + out = in.setByte(null, (byte)0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.handler.codec;Headers;true;setChar;;;Argument[-1];ReturnValue;value;manual" + Headers out = null; + Headers in = (Headers)source(); + out = in.setChar(null, '\0'); + sink(out); // $ hasValueFlow + } + { + // "io.netty.handler.codec;Headers;true;setDouble;;;Argument[-1];ReturnValue;value;manual" + Headers out = null; + Headers in = (Headers)source(); + out = in.setDouble(null, 0.0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.handler.codec;Headers;true;setFloat;;;Argument[-1];ReturnValue;value;manual" + Headers out = null; + Headers in = (Headers)source(); + out = in.setFloat(null, 0.0f); + sink(out); // $ hasValueFlow + } + { + // "io.netty.handler.codec;Headers;true;setInt;;;Argument[-1];ReturnValue;value;manual" + Headers out = null; + Headers in = (Headers)source(); + out = in.setInt(null, 0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.handler.codec;Headers;true;setLong;;;Argument[-1];ReturnValue;value;manual" + Headers out = null; + Headers in = (Headers)source(); + out = in.setLong(null, 0L); + sink(out); // $ hasValueFlow + } + { + // "io.netty.handler.codec;Headers;true;setObject;;;Argument[-1];ReturnValue;value;manual" + Headers out = null; + Headers in = (Headers)source(); + out = in.setObject((Object)null, (Iterable)null); + sink(out); // $ hasValueFlow + } + { + // "io.netty.handler.codec;Headers;true;setObject;;;Argument[-1];ReturnValue;value;manual" + Headers out = null; + Headers in = (Headers)source(); + out = in.setObject((Object)null, (Object)null); + sink(out); // $ hasValueFlow + } + { + // "io.netty.handler.codec;Headers;true;setObject;;;Argument[-1];ReturnValue;value;manual" + Headers out = null; + Headers in = (Headers)source(); + out = in.setObject((Object)null, (Object[])null); + sink(out); // $ hasValueFlow + } + { + // "io.netty.handler.codec;Headers;true;setShort;;;Argument[-1];ReturnValue;value;manual" + Headers out = null; + Headers in = (Headers)source(); + out = in.setShort(null, (short)0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.handler.codec;Headers;true;setTimeMillis;;;Argument[-1];ReturnValue;value;manual" + Headers out = null; + Headers in = (Headers)source(); + out = in.setTimeMillis(null, 0L); + sink(out); // $ hasValueFlow + } { // "io.netty.handler.codec;HeadersUtils;false;getAllAsString;(Headers,Object);;Argument[0];ReturnValue;taint;manual" List out = null; @@ -4648,6 +5491,273 @@ public class Test { out = HeadersUtils.toString(null, in, 0); sink(out); // $ hasTaintFlow } + { + // "io.netty.util;AsciiString;false;AsciiString;;;Argument[0];Argument[-1];taint;manual" + AsciiString out = null; + ByteBuffer in = (ByteBuffer)source(); + out = new AsciiString(in); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.util;AsciiString;false;AsciiString;;;Argument[0];Argument[-1];taint;manual" + AsciiString out = null; + ByteBuffer in = (ByteBuffer)source(); + out = new AsciiString(in, 0, 0, false); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.util;AsciiString;false;AsciiString;;;Argument[0];Argument[-1];taint;manual" + AsciiString out = null; + ByteBuffer in = (ByteBuffer)source(); + out = new AsciiString(in, false); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.util;AsciiString;false;AsciiString;;;Argument[0];Argument[-1];taint;manual" + AsciiString out = null; + CharSequence in = (CharSequence)source(); + out = new AsciiString(in); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.util;AsciiString;false;AsciiString;;;Argument[0];Argument[-1];taint;manual" + AsciiString out = null; + CharSequence in = (CharSequence)source(); + out = new AsciiString(in, (Charset)null); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.util;AsciiString;false;AsciiString;;;Argument[0];Argument[-1];taint;manual" + AsciiString out = null; + CharSequence in = (CharSequence)source(); + out = new AsciiString(in, (Charset)null, 0, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.util;AsciiString;false;AsciiString;;;Argument[0];Argument[-1];taint;manual" + AsciiString out = null; + CharSequence in = (CharSequence)source(); + out = new AsciiString(in, 0, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.util;AsciiString;false;AsciiString;;;Argument[0];Argument[-1];taint;manual" + AsciiString out = null; + byte[] in = (byte[])source(); + out = new AsciiString(in); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.util;AsciiString;false;AsciiString;;;Argument[0];Argument[-1];taint;manual" + AsciiString out = null; + byte[] in = (byte[])source(); + out = new AsciiString(in, 0, 0, false); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.util;AsciiString;false;AsciiString;;;Argument[0];Argument[-1];taint;manual" + AsciiString out = null; + byte[] in = (byte[])source(); + out = new AsciiString(in, false); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.util;AsciiString;false;AsciiString;;;Argument[0];Argument[-1];taint;manual" + AsciiString out = null; + char[] in = (char[])source(); + out = new AsciiString(in); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.util;AsciiString;false;AsciiString;;;Argument[0];Argument[-1];taint;manual" + AsciiString out = null; + char[] in = (char[])source(); + out = new AsciiString(in, (Charset)null); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.util;AsciiString;false;AsciiString;;;Argument[0];Argument[-1];taint;manual" + AsciiString out = null; + char[] in = (char[])source(); + out = new AsciiString(in, (Charset)null, 0, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.util;AsciiString;false;AsciiString;;;Argument[0];Argument[-1];taint;manual" + AsciiString out = null; + char[] in = (char[])source(); + out = new AsciiString(in, 0, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.util;AsciiString;false;array;();;Argument[-1];ReturnValue;taint;manual" + byte[] out = null; + AsciiString in = (AsciiString)source(); + out = in.array(); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.util;AsciiString;false;cached;(String);;Argument[0];ReturnValue;taint;manual" + AsciiString out = null; + String in = (String)source(); + out = AsciiString.cached(in); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.util;AsciiString;false;concat;(CharSequence);;Argument[-1];ReturnValue;taint;manual" + AsciiString out = null; + AsciiString in = (AsciiString)source(); + out = in.concat(null); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.util;AsciiString;false;concat;(CharSequence);;Argument[0];ReturnValue;taint;manual" + AsciiString out = null; + CharSequence in = (CharSequence)source(); + AsciiString instance = null; + out = instance.concat(in); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.util;AsciiString;false;copy;(int,byte[],int,int);;Argument[-1];Argument[1];taint;manual" + byte[] out = null; + AsciiString in = (AsciiString)source(); + in.copy(0, out, 0, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.util;AsciiString;false;copy;(int,char[],int,int);;Argument[-1];Argument[1];taint;manual" + char[] out = null; + AsciiString in = (AsciiString)source(); + in.copy(0, out, 0, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.util;AsciiString;false;of;(CharSequence);;Argument[0];ReturnValue;taint;manual" + AsciiString out = null; + CharSequence in = (CharSequence)source(); + out = AsciiString.of(in); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.util;AsciiString;false;replace;(char,char);;Argument[-1];ReturnValue;taint;manual" + AsciiString out = null; + AsciiString in = (AsciiString)source(); + out = in.replace('\0', '\0'); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.util;AsciiString;false;split;(String,int);;Argument[-1];ReturnValue;taint;manual" + AsciiString[] out = null; + AsciiString in = (AsciiString)source(); + out = in.split(null, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.util;AsciiString;false;split;(char);;Argument[-1];ReturnValue;taint;manual" + AsciiString[] out = null; + AsciiString in = (AsciiString)source(); + out = in.split('\0'); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.util;AsciiString;false;subSequence;;;Argument[-1];ReturnValue;taint;manual" + AsciiString out = null; + AsciiString in = (AsciiString)source(); + out = in.subSequence(0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.util;AsciiString;false;subSequence;;;Argument[-1];ReturnValue;taint;manual" + AsciiString out = null; + AsciiString in = (AsciiString)source(); + out = in.subSequence(0, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.util;AsciiString;false;subSequence;;;Argument[-1];ReturnValue;taint;manual" + AsciiString out = null; + AsciiString in = (AsciiString)source(); + out = in.subSequence(0, 0, false); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.util;AsciiString;false;toByteArray;;;Argument[-1];ReturnValue;taint;manual" + byte[] out = null; + AsciiString in = (AsciiString)source(); + out = in.toByteArray(); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.util;AsciiString;false;toByteArray;;;Argument[-1];ReturnValue;taint;manual" + byte[] out = null; + AsciiString in = (AsciiString)source(); + out = in.toByteArray(0, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.util;AsciiString;false;toCharArray;;;Argument[-1];ReturnValue;taint;manual" + char[] out = null; + AsciiString in = (AsciiString)source(); + out = in.toCharArray(); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.util;AsciiString;false;toCharArray;;;Argument[-1];ReturnValue;taint;manual" + char[] out = null; + AsciiString in = (AsciiString)source(); + out = in.toCharArray(0, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.util;AsciiString;false;toLowerCase;();;Argument[-1];ReturnValue;taint;manual" + AsciiString out = null; + AsciiString in = (AsciiString)source(); + out = in.toLowerCase(); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.util;AsciiString;false;toString;;;Argument[-1];ReturnValue;taint;manual" + String out = null; + AsciiString in = (AsciiString)source(); + out = in.toString(); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.util;AsciiString;false;toString;;;Argument[-1];ReturnValue;taint;manual" + String out = null; + AsciiString in = (AsciiString)source(); + out = in.toString(0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.util;AsciiString;false;toString;;;Argument[-1];ReturnValue;taint;manual" + String out = null; + AsciiString in = (AsciiString)source(); + out = in.toString(0, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.util;AsciiString;false;toUpperCase;();;Argument[-1];ReturnValue;taint;manual" + AsciiString out = null; + AsciiString in = (AsciiString)source(); + out = in.toUpperCase(); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.util;AsciiString;false;trim;();;Argument[-1];ReturnValue;taint;manual" + AsciiString out = null; + AsciiString in = (AsciiString)source(); + out = in.trim(); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.util;AsciiString;false;trim;(CharSequence);;Argument[0];ReturnValue;taint;manual" + CharSequence out = null; + CharSequence in = (CharSequence)source(); + out = AsciiString.trim(in); + sink(out); // $ hasTaintFlow + } { // "io.netty.util;ReferenceCounted;true;retain;;;Argument[-1];ReturnValue;value;manual" Attribute out = null; diff --git a/java/ql/test/stubs/netty-4.1.x/io/netty/buffer/ByteBufInputStream.java b/java/ql/test/stubs/netty-4.1.x/io/netty/buffer/ByteBufInputStream.java new file mode 100644 index 00000000000..cb01654d4e7 --- /dev/null +++ b/java/ql/test/stubs/netty-4.1.x/io/netty/buffer/ByteBufInputStream.java @@ -0,0 +1,40 @@ +// Generated automatically from io.netty.buffer.ByteBufInputStream for testing purposes + +package io.netty.buffer; + +import io.netty.buffer.ByteBuf; +import java.io.DataInput; +import java.io.InputStream; + +public class ByteBufInputStream extends InputStream implements DataInput +{ + protected ByteBufInputStream() {} + public ByteBufInputStream(ByteBuf p0){} + public ByteBufInputStream(ByteBuf p0, boolean p1){} + public ByteBufInputStream(ByteBuf p0, int p1){} + public ByteBufInputStream(ByteBuf p0, int p1, boolean p2){} + public String readLine(){ return null; } + public String readUTF(){ return null; } + public boolean markSupported(){ return false; } + public boolean readBoolean(){ return false; } + public byte readByte(){ return 0; } + public char readChar(){ return '0'; } + public double readDouble(){ return 0; } + public float readFloat(){ return 0; } + public int available(){ return 0; } + public int read(){ return 0; } + public int read(byte[] p0, int p1, int p2){ return 0; } + public int readBytes(){ return 0; } + public int readInt(){ return 0; } + public int readUnsignedByte(){ return 0; } + public int readUnsignedShort(){ return 0; } + public int skipBytes(int p0){ return 0; } + public long readLong(){ return 0; } + public long skip(long p0){ return 0; } + public short readShort(){ return 0; } + public void close(){} + public void mark(int p0){} + public void readFully(byte[] p0){} + public void readFully(byte[] p0, int p1, int p2){} + public void reset(){} +} diff --git a/java/ql/test/stubs/netty-4.1.x/io/netty/buffer/ByteBufOutputStream.java b/java/ql/test/stubs/netty-4.1.x/io/netty/buffer/ByteBufOutputStream.java new file mode 100644 index 00000000000..868e7bd78c3 --- /dev/null +++ b/java/ql/test/stubs/netty-4.1.x/io/netty/buffer/ByteBufOutputStream.java @@ -0,0 +1,30 @@ +// Generated automatically from io.netty.buffer.ByteBufOutputStream for testing purposes + +package io.netty.buffer; + +import io.netty.buffer.ByteBuf; +import java.io.DataOutput; +import java.io.OutputStream; + +public class ByteBufOutputStream extends OutputStream implements DataOutput +{ + protected ByteBufOutputStream() {} + public ByteBuf buffer(){ return null; } + public ByteBufOutputStream(ByteBuf p0){} + public int writtenBytes(){ return 0; } + public void close(){} + public void write(byte[] p0){} + public void write(byte[] p0, int p1, int p2){} + public void write(int p0){} + public void writeBoolean(boolean p0){} + public void writeByte(int p0){} + public void writeBytes(String p0){} + public void writeChar(int p0){} + public void writeChars(String p0){} + public void writeDouble(double p0){} + public void writeFloat(float p0){} + public void writeInt(int p0){} + public void writeLong(long p0){} + public void writeShort(int p0){} + public void writeUTF(String p0){} +} diff --git a/java/ql/test/stubs/netty-4.1.x/io/netty/buffer/ByteBufUtil.java b/java/ql/test/stubs/netty-4.1.x/io/netty/buffer/ByteBufUtil.java new file mode 100644 index 00000000000..e9287e530d6 --- /dev/null +++ b/java/ql/test/stubs/netty-4.1.x/io/netty/buffer/ByteBufUtil.java @@ -0,0 +1,64 @@ +// Generated automatically from io.netty.buffer.ByteBufUtil for testing purposes + +package io.netty.buffer; + +import io.netty.buffer.ByteBuf; +import io.netty.buffer.ByteBufAllocator; +import io.netty.util.AsciiString; +import java.nio.CharBuffer; +import java.nio.charset.Charset; + +public class ByteBufUtil +{ + protected ByteBufUtil() {} + public static ByteBuf encodeString(ByteBufAllocator p0, CharBuffer p1, Charset p2){ return null; } + public static ByteBuf encodeString(ByteBufAllocator p0, CharBuffer p1, Charset p2, int p3){ return null; } + public static ByteBuf ensureAccessible(ByteBuf p0){ return null; } + public static ByteBuf readBytes(ByteBufAllocator p0, ByteBuf p1, int p2){ return null; } + public static ByteBuf setShortBE(ByteBuf p0, int p1, int p2){ return null; } + public static ByteBuf threadLocalDirectBuffer(){ return null; } + public static ByteBuf writeAscii(ByteBufAllocator p0, CharSequence p1){ return null; } + public static ByteBuf writeMediumBE(ByteBuf p0, int p1){ return null; } + public static ByteBuf writeShortBE(ByteBuf p0, int p1){ return null; } + public static ByteBuf writeUtf8(ByteBufAllocator p0, CharSequence p1){ return null; } + public static String hexDump(ByteBuf p0){ return null; } + public static String hexDump(ByteBuf p0, int p1, int p2){ return null; } + public static String hexDump(byte[] p0){ return null; } + public static String hexDump(byte[] p0, int p1, int p2){ return null; } + public static String prettyHexDump(ByteBuf p0){ return null; } + public static String prettyHexDump(ByteBuf p0, int p1, int p2){ return null; } + public static boolean ensureWritableSuccess(int p0){ return false; } + public static boolean equals(ByteBuf p0, ByteBuf p1){ return false; } + public static boolean equals(ByteBuf p0, int p1, ByteBuf p2, int p3, int p4){ return false; } + public static boolean isAccessible(ByteBuf p0){ return false; } + public static boolean isText(ByteBuf p0, Charset p1){ return false; } + public static boolean isText(ByteBuf p0, int p1, int p2, Charset p3){ return false; } + public static byte decodeHexByte(CharSequence p0, int p1){ return 0; } + public static byte[] decodeHexDump(CharSequence p0){ return null; } + public static byte[] decodeHexDump(CharSequence p0, int p1, int p2){ return null; } + public static byte[] getBytes(ByteBuf p0){ return null; } + public static byte[] getBytes(ByteBuf p0, int p1, int p2){ return null; } + public static byte[] getBytes(ByteBuf p0, int p1, int p2, boolean p3){ return null; } + public static int compare(ByteBuf p0, ByteBuf p1){ return 0; } + public static int hashCode(ByteBuf p0){ return 0; } + public static int indexOf(ByteBuf p0, ByteBuf p1){ return 0; } + public static int indexOf(ByteBuf p0, int p1, int p2, byte p3){ return 0; } + public static int reserveAndWriteUtf8(ByteBuf p0, CharSequence p1, int p2){ return 0; } + public static int reserveAndWriteUtf8(ByteBuf p0, CharSequence p1, int p2, int p3, int p4){ return 0; } + public static int swapInt(int p0){ return 0; } + public static int swapMedium(int p0){ return 0; } + public static int utf8Bytes(CharSequence p0){ return 0; } + public static int utf8Bytes(CharSequence p0, int p1, int p2){ return 0; } + public static int utf8MaxBytes(CharSequence p0){ return 0; } + public static int utf8MaxBytes(int p0){ return 0; } + public static int writeAscii(ByteBuf p0, CharSequence p1){ return 0; } + public static int writeUtf8(ByteBuf p0, CharSequence p1){ return 0; } + public static int writeUtf8(ByteBuf p0, CharSequence p1, int p2, int p3){ return 0; } + public static long swapLong(long p0){ return 0; } + public static short swapShort(short p0){ return 0; } + public static void appendPrettyHexDump(StringBuilder p0, ByteBuf p1){} + public static void appendPrettyHexDump(StringBuilder p0, ByteBuf p1, int p2, int p3){} + public static void copy(AsciiString p0, ByteBuf p1){} + public static void copy(AsciiString p0, int p1, ByteBuf p2, int p3){} + public static void copy(AsciiString p0, int p1, ByteBuf p2, int p3, int p4){} +} diff --git a/java/ql/test/stubs/netty-4.1.x/io/netty/buffer/Unpooled.java b/java/ql/test/stubs/netty-4.1.x/io/netty/buffer/Unpooled.java new file mode 100644 index 00000000000..4d4c0c58dce --- /dev/null +++ b/java/ql/test/stubs/netty-4.1.x/io/netty/buffer/Unpooled.java @@ -0,0 +1,66 @@ +// Generated automatically from io.netty.buffer.Unpooled for testing purposes + +package io.netty.buffer; + +import io.netty.buffer.ByteBuf; +import io.netty.buffer.CompositeByteBuf; +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.nio.charset.Charset; + +public class Unpooled +{ + protected Unpooled() {} + public static ByteBuf EMPTY_BUFFER = null; + public static ByteBuf buffer(){ return null; } + public static ByteBuf buffer(int p0){ return null; } + public static ByteBuf buffer(int p0, int p1){ return null; } + public static ByteBuf copiedBuffer(ByteBuf p0){ return null; } + public static ByteBuf copiedBuffer(ByteBuf... p0){ return null; } + public static ByteBuf copiedBuffer(ByteBuffer p0){ return null; } + public static ByteBuf copiedBuffer(ByteBuffer... p0){ return null; } + public static ByteBuf copiedBuffer(CharSequence p0, Charset p1){ return null; } + public static ByteBuf copiedBuffer(CharSequence p0, int p1, int p2, Charset p3){ return null; } + public static ByteBuf copiedBuffer(byte[] p0){ return null; } + public static ByteBuf copiedBuffer(byte[] p0, int p1, int p2){ return null; } + public static ByteBuf copiedBuffer(byte[]... p0){ return null; } + public static ByteBuf copiedBuffer(char[] p0, Charset p1){ return null; } + public static ByteBuf copiedBuffer(char[] p0, int p1, int p2, Charset p3){ return null; } + public static ByteBuf copyBoolean(boolean p0){ return null; } + public static ByteBuf copyBoolean(boolean... p0){ return null; } + public static ByteBuf copyDouble(double p0){ return null; } + public static ByteBuf copyDouble(double... p0){ return null; } + public static ByteBuf copyFloat(float p0){ return null; } + public static ByteBuf copyFloat(float... p0){ return null; } + public static ByteBuf copyInt(int p0){ return null; } + public static ByteBuf copyInt(int... p0){ return null; } + public static ByteBuf copyLong(long p0){ return null; } + public static ByteBuf copyLong(long... p0){ return null; } + public static ByteBuf copyMedium(int p0){ return null; } + public static ByteBuf copyMedium(int... p0){ return null; } + public static ByteBuf copyShort(int p0){ return null; } + public static ByteBuf copyShort(int... p0){ return null; } + public static ByteBuf copyShort(short... p0){ return null; } + public static ByteBuf directBuffer(){ return null; } + public static ByteBuf directBuffer(int p0){ return null; } + public static ByteBuf directBuffer(int p0, int p1){ return null; } + public static ByteBuf unmodifiableBuffer(ByteBuf p0){ return null; } + public static ByteBuf unmodifiableBuffer(ByteBuf... p0){ return null; } + public static ByteBuf unreleasableBuffer(ByteBuf p0){ return null; } + public static ByteBuf wrappedBuffer(ByteBuf p0){ return null; } + public static ByteBuf wrappedBuffer(ByteBuf... p0){ return null; } + public static ByteBuf wrappedBuffer(ByteBuffer p0){ return null; } + public static ByteBuf wrappedBuffer(ByteBuffer... p0){ return null; } + public static ByteBuf wrappedBuffer(byte[] p0){ return null; } + public static ByteBuf wrappedBuffer(byte[] p0, int p1, int p2){ return null; } + public static ByteBuf wrappedBuffer(byte[]... p0){ return null; } + public static ByteBuf wrappedBuffer(int p0, ByteBuf... p1){ return null; } + public static ByteBuf wrappedBuffer(int p0, ByteBuffer... p1){ return null; } + public static ByteBuf wrappedBuffer(int p0, byte[]... p1){ return null; } + public static ByteBuf wrappedBuffer(long p0, int p1, boolean p2){ return null; } + public static ByteBuf wrappedUnmodifiableBuffer(ByteBuf... p0){ return null; } + public static ByteOrder BIG_ENDIAN = null; + public static ByteOrder LITTLE_ENDIAN = null; + public static CompositeByteBuf compositeBuffer(){ return null; } + public static CompositeByteBuf compositeBuffer(int p0){ return null; } +} From 76b92857c9f67b7fa50378dd1a7647239f92885e Mon Sep 17 00:00:00 2001 From: Joe Farebrother <joefarebrother@github.com> Date: Tue, 28 Feb 2023 18:00:32 +0000 Subject: [PATCH 372/631] Add change note --- java/ql/lib/change-notes/2023-02-28-netty.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 java/ql/lib/change-notes/2023-02-28-netty.md diff --git a/java/ql/lib/change-notes/2023-02-28-netty.md b/java/ql/lib/change-notes/2023-02-28-netty.md new file mode 100644 index 00000000000..18a2f4b211b --- /dev/null +++ b/java/ql/lib/change-notes/2023-02-28-netty.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* Added sources and flow step models for the Netty framework up to version 4.1. \ No newline at end of file From 28b0e7e0745f730a89dedefe4f47e0e1962e4ccc Mon Sep 17 00:00:00 2001 From: Joe Farebrother <joefarebrother@github.com> Date: Wed, 8 Mar 2023 14:56:30 +0000 Subject: [PATCH 373/631] Remove unneeded blank lines --- java/ql/lib/ext/io.netty.buffer.model.yml | 7 +------ java/ql/lib/ext/io.netty.handler.codec.http2.model.yml | 4 +--- java/ql/lib/ext/io.netty.util.model.yml | 5 +---- 3 files changed, 3 insertions(+), 13 deletions(-) diff --git a/java/ql/lib/ext/io.netty.buffer.model.yml b/java/ql/lib/ext/io.netty.buffer.model.yml index 33a098f85e4..ef985ccc688 100644 --- a/java/ql/lib/ext/io.netty.buffer.model.yml +++ b/java/ql/lib/ext/io.netty.buffer.model.yml @@ -195,9 +195,4 @@ extensions: - ["io.netty.buffer", "ByteBufUtil", False, "writeUtf8", "(ByteBufAllocator,CharSequence)", "", "Argument[1]", "ReturnValue", "taint", "manual"] - ["io.netty.buffer", "ByteBufInputStream", True, "ByteBufInputStream", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] - ["io.netty.buffer", "ByteBufOutputStream", True, "ByteBufOutputStream", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] - - ["io.netty.buffer", "ByteBufOutputStream", True, "buffer", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - - - - + - ["io.netty.buffer", "ByteBufOutputStream", True, "buffer", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] \ No newline at end of file diff --git a/java/ql/lib/ext/io.netty.handler.codec.http2.model.yml b/java/ql/lib/ext/io.netty.handler.codec.http2.model.yml index 7f4c3c515c7..3a47a2b2565 100644 --- a/java/ql/lib/ext/io.netty.handler.codec.http2.model.yml +++ b/java/ql/lib/ext/io.netty.handler.codec.http2.model.yml @@ -28,6 +28,4 @@ extensions: - ["io.netty.handler.codec.http2", "HttpConversionUtil", False, "toHttp2Headers", "(HttpHeaders,boolean)", "", "Argument[0]", "ReturnValue", "taint", "manual"] - ["io.netty.handler.codec.http2", "HttpConversionUtil", False, "toHttp2Headers", "(HttpHeaders,Http2Headers)", "", "Argument[0]", "Argument[1]", "taint", "manual"] - ["io.netty.handler.codec.http2", "HttpConversionUtil", False, "toHttpRequest", "", "", "Argument[1]", "ReturnValue", "taint", "manual"] - - ["io.netty.handler.codec.http2", "HttpConversionUtil", False, "toHttpResponse", "", "", "Argument[1]", "ReturnValue", "taint", "manual"] - - + - ["io.netty.handler.codec.http2", "HttpConversionUtil", False, "toHttpResponse", "", "", "Argument[1]", "ReturnValue", "taint", "manual"] \ No newline at end of file diff --git a/java/ql/lib/ext/io.netty.util.model.yml b/java/ql/lib/ext/io.netty.util.model.yml index d6333dc6009..93f0e26e083 100644 --- a/java/ql/lib/ext/io.netty.util.model.yml +++ b/java/ql/lib/ext/io.netty.util.model.yml @@ -24,7 +24,4 @@ extensions: - ["io.netty.util", "AsciiString", False, "toLowerCase", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - ["io.netty.util", "AsciiString", False, "toUpperCase", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - ["io.netty.util", "AsciiString", False, "trim", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.util", "AsciiString", False, "trim", "(CharSequence)", "", "Argument[0]", "ReturnValue", "taint", "manual"] - - - \ No newline at end of file + - ["io.netty.util", "AsciiString", False, "trim", "(CharSequence)", "", "Argument[0]", "ReturnValue", "taint", "manual"] \ No newline at end of file From 904102143ec72431b96ac31de91f3d96ec642378 Mon Sep 17 00:00:00 2001 From: Joe Farebrother <joefarebrother@github.com> Date: Thu, 9 Mar 2023 13:52:43 +0000 Subject: [PATCH 374/631] Add some missing models --- java/ql/lib/ext/io.netty.buffer.model.yml | 24 +++++++++++++++---- ...tty.handler.codec.http.multipart.model.yml | 2 ++ .../lib/ext/io.netty.handler.codec.model.yml | 3 +-- 3 files changed, 22 insertions(+), 7 deletions(-) diff --git a/java/ql/lib/ext/io.netty.buffer.model.yml b/java/ql/lib/ext/io.netty.buffer.model.yml index ef985ccc688..ae1074f6ddc 100644 --- a/java/ql/lib/ext/io.netty.buffer.model.yml +++ b/java/ql/lib/ext/io.netty.buffer.model.yml @@ -63,6 +63,7 @@ extensions: - ["io.netty.buffer", "ByteBuf", True, "slice", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - ["io.netty.buffer", "ByteBuf", True, "toString", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - ["io.netty.buffer", "ByteBuf", True, "unwrap", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "writeBoolean", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] - ["io.netty.buffer", "ByteBuf", True, "writeByte", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] - ["io.netty.buffer", "ByteBuf", True, "writeBytes", "(byte[])", "", "Argument[-1]", "ReturnValue", "value", "manual"] - ["io.netty.buffer", "ByteBuf", True, "writeBytes", "(byte[],int,int)", "", "Argument[-1]", "ReturnValue", "value", "manual"] @@ -85,10 +86,11 @@ extensions: - ["io.netty.buffer", "ByteBuf", True, "writeShortLE", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] - ["io.netty.buffer", "ByteBuf", True, "writeZero", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] - ["io.netty.buffer", "ByteBuf", True, "writerIndex", "(int)", "", "Argument[-1]", "ReturnValue", "value", "manual"] - - ["io.netty.buffer", "ByteBufHolder", True, "copy", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.buffer", "ByteBufHolder", True, "content", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.buffer", "ByteBufHolder", True, "duplicate", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.buffer", "ByteBufHolder", True, "retainedDuplicate", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.buffer", "ByteBufHolder", True, "copy", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.buffer", "ByteBufHolder", True, "content", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.buffer", "ByteBufHolder", True, "duplicate", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.buffer", "ByteBufHolder", True, "retainedDuplicate", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.buffer", "ByteBufHolder", True, "replace", "(ByteBuf)", "", "Argument[0]", "ReturnValue", "taint", "manual"] - ["io.netty.buffer", "ByteBuf", True, "getBytes", "(int,byte[])", "", "Argument[-1]", "Argument[1]", "taint", "manual"] - ["io.netty.buffer", "ByteBuf", True, "getBytes", "(int,byte[],int,int)", "", "Argument[-1]", "Argument[1]", "taint", "manual"] - ["io.netty.buffer", "ByteBuf", True, "getBytes", "(int,ByteBuf)", "", "Argument[-1]", "Argument[1]", "taint", "manual"] @@ -98,6 +100,7 @@ extensions: - ["io.netty.buffer", "ByteBuf", True, "getBytes", "(int,FileChannel,long,int)", "", "Argument[-1]", "Argument[1]", "taint", "manual"] - ["io.netty.buffer", "ByteBuf", True, "getBytes", "(int,GatheringByteChannel,int)", "", "Argument[-1]", "Argument[1]", "taint", "manual"] - ["io.netty.buffer", "ByteBuf", True, "getBytes", "(int,OutputStream,int)", "", "Argument[-1]", "Argument[1]", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "getChar", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - ["io.netty.buffer", "ByteBuf", True, "getCharSequence", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - ["io.netty.buffer", "ByteBuf", True, "readBytes", "(byte[])", "", "Argument[-1]", "Argument[0]", "taint", "manual"] - ["io.netty.buffer", "ByteBuf", True, "readBytes", "(byte[],int,int)", "", "Argument[-1]", "Argument[0]", "taint", "manual"] @@ -107,9 +110,12 @@ extensions: - ["io.netty.buffer", "ByteBuf", True, "readBytes", "(ByteBuf,int,int)", "", "Argument[-1]", "Argument[0]", "taint", "manual"] - ["io.netty.buffer", "ByteBuf", True, "readBytes", "(FileChannel,long,int)", "", "Argument[-1]", "Argument[0]", "taint", "manual"] - ["io.netty.buffer", "ByteBuf", True, "readBytes", "(GatheringByteChannel,int)", "", "Argument[-1]", "Argument[0]", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "readBytes", "(OutputStream,int)", "", "Argument[-1]", "Argument[0]", "taint", "manual"] - ["io.netty.buffer", "ByteBuf", True, "readBytes", "(int)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "readChar", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - ["io.netty.buffer", "ByteBuf", True, "readCharSequence", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "readSlice", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "readSlice", "(int)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "readRetainedSlice", "(int)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - ["io.netty.buffer", "ByteBuf", True, "setBytes", "(int,byte[])", "", "Argument[1]", "Argument[-1]", "taint", "manual"] - ["io.netty.buffer", "ByteBuf", True, "setBytes", "(int,byte[],int,int)", "", "Argument[1]", "Argument[-1]", "taint", "manual"] - ["io.netty.buffer", "ByteBuf", True, "setBytes", "(int,ByteBuf)", "", "Argument[1]", "Argument[-1]", "taint", "manual"] @@ -119,6 +125,7 @@ extensions: - ["io.netty.buffer", "ByteBuf", True, "setBytes", "(int,FileChannel,long,int)", "", "Argument[1]", "Argument[-1]", "taint", "manual"] - ["io.netty.buffer", "ByteBuf", True, "setBytes", "(int,ScatteringByteChannel,int)", "", "Argument[1]", "Argument[-1]", "taint", "manual"] - ["io.netty.buffer", "ByteBuf", True, "setBytes", "(int,InputStream,int)", "", "Argument[1]", "Argument[-1]", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "setChar", "", "", "Argument[1]", "Argument[-1]", "taint", "manual"] - ["io.netty.buffer", "ByteBuf", True, "setCharSequence", "", "", "Argument[1]", "Argument[-1]", "taint", "manual"] - ["io.netty.buffer", "ByteBuf", True, "writeByte", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] - ["io.netty.buffer", "ByteBuf", True, "writeBytes", "(byte[])", "", "Argument[0]", "Argument[-1]", "taint", "manual"] @@ -145,10 +152,14 @@ extensions: - ["io.netty.buffer", "CompositeByteBuf", True, "addComponents", "(int,Iterable)", "", "Argument[1].Element", "Argument[-1]", "taint", "manual"] - ["io.netty.buffer", "CompositeByteBuf", True, "addComponents", "(boolean,Iterable)", "", "Argument[1].Element", "Argument[-1]", "taint", "manual"] - ["io.netty.buffer", "CompositeByteBuf", True, "addFlattenedComponents", "(boolean,ByteBuf)", "", "Argument[1]", "Argument[-1]", "taint", "manual"] + - ["io.netty.buffer", "CompositeByteBuf", True, "addComponent", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["io.netty.buffer", "CompositeByteBuf", True, "addComponents", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["io.netty.buffer", "CompositeByteBuf", True, "addFlattenedComponents", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] - ["io.netty.buffer", "CompositeByteBuf", True, "component", "(int)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - ["io.netty.buffer", "CompositeByteBuf", True, "componentAtOffset", "(int)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - ["io.netty.buffer", "CompositeByteBuf", True, "consolidate", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - ["io.netty.buffer", "CompositeByteBuf", True, "consolidate", "(int,int)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.buffer", "CompositeByteBuf", True, "decompose", "(int,int)", "", "Argument[-1]", "ReturnValue.Element", "taint", "manual"] - ["io.netty.buffer", "Unpooled", False, "copiedBuffer", "(byte[])", "", "Argument[0]", "ReturnValue", "taint", "manual"] - ["io.netty.buffer", "Unpooled", False, "copiedBuffer", "(byte[][])", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "manual"] - ["io.netty.buffer", "Unpooled", False, "copiedBuffer", "(byte[],int,int)", "", "Argument[0]", "ReturnValue", "taint", "manual"] @@ -188,8 +199,11 @@ extensions: - ["io.netty.buffer", "ByteBufUtil", False, "readBytes", "(ByteBufAllocator,ByteBuf,int)", "", "Argument[1]", "ReturnValue", "taint", "manual"] - ["io.netty.buffer", "ByteBufUtil", False, "reserveAndWriteUtf8", "(ByteBuf,CharSequence,int)", "", "Argument[1]", "Argument[0]", "taint", "manual"] - ["io.netty.buffer", "ByteBufUtil", False, "reserveAndWriteUtf8", "(ByteBuf,CharSequence,int,int,int)", "", "Argument[1]", "Argument[0]", "taint", "manual"] + - ["io.netty.buffer", "ByteBufUtil", False, "setShortBE", "(ByteBuf,int,int)", "", "Argument[0]", "ReturnValue", "value", "manual"] - ["io.netty.buffer", "ByteBufUtil", False, "writeAscii", "(ByteBuf,CharSequence)", "", "Argument[1]", "Argument[0]", "taint", "manual"] - ["io.netty.buffer", "ByteBufUtil", False, "writeAscii", "(ByteBufAllocator,CharSequence)", "", "Argument[1]", "ReturnValue", "taint", "manual"] + - ["io.netty.buffer", "ByteBufUtil", False, "writeShortBE", "(ByteBuf,int)", "", "Argument[0]", "ReturnValue", "value", "manual"] + - ["io.netty.buffer", "ByteBufUtil", False, "writeMediumBE", "(ByteBuf,int)", "", "Argument[0]", "ReturnValue", "value", "manual"] - ["io.netty.buffer", "ByteBufUtil", False, "writeUtf8", "(ByteBuf,CharSequence)", "", "Argument[1]", "Argument[0]", "taint", "manual"] - ["io.netty.buffer", "ByteBufUtil", False, "writeUtf8", "(ByteBuf,CharSequence,int,int)", "", "Argument[1]", "Argument[0]", "taint", "manual"] - ["io.netty.buffer", "ByteBufUtil", False, "writeUtf8", "(ByteBufAllocator,CharSequence)", "", "Argument[1]", "ReturnValue", "taint", "manual"] diff --git a/java/ql/lib/ext/io.netty.handler.codec.http.multipart.model.yml b/java/ql/lib/ext/io.netty.handler.codec.http.multipart.model.yml index afdec5cb05f..f96583c4aa0 100644 --- a/java/ql/lib/ext/io.netty.handler.codec.http.multipart.model.yml +++ b/java/ql/lib/ext/io.netty.handler.codec.http.multipart.model.yml @@ -8,11 +8,13 @@ extensions: pack: codeql/java-all extensible: summaryModel data: + - ["io.netty.handler.codec.http.multipart", "InterfaceHttpPostRequestDecoder", True, "currentPartialHttpData", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - ["io.netty.handler.codec.http.multipart", "InterfaceHttpPostRequestDecoder", True, "getBodyHttpData", "(String)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - ["io.netty.handler.codec.http.multipart", "InterfaceHttpPostRequestDecoder", True, "getBodyHttpDatas", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - ["io.netty.handler.codec.http.multipart", "InterfaceHttpPostRequestDecoder", True, "getBodyHttpDatas", "(String)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - ["io.netty.handler.codec.http.multipart", "InterfaceHttpPostRequestDecoder", True, "next", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - ["io.netty.handler.codec.http.multipart", "InterfaceHttpPostRequestDecoder", True, "offer", "(HttpContent)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["io.netty.handler.codec.http.multipart", "InterfaceHttpPostRequestDecoder", True, "offer", "(HttpContent)", "", "Argument[-1]", "ReturnValue", "value", "manual"] - ["io.netty.handler.codec.http.multipart", "HttpPostRequestDecoder", True, "HttpPostRequestDecoder", "(HttpRequest)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] - ["io.netty.handler.codec.http.multipart", "HttpPostRequestDecoder", True, "HttpPostRequestDecoder", "(HttpDataFactory,HttpRequest)", "", "Argument[1]", "Argument[-1]", "taint", "manual"] - ["io.netty.handler.codec.http.multipart", "HttpPostRequestDecoder", True, "HttpPostRequestDecoder", "(HttpDataFactory,HttpRequest,Charset)", "", "Argument[1]", "Argument[-1]", "taint", "manual"] diff --git a/java/ql/lib/ext/io.netty.handler.codec.model.yml b/java/ql/lib/ext/io.netty.handler.codec.model.yml index 6af0ae99e2d..d2925bb6c0f 100644 --- a/java/ql/lib/ext/io.netty.handler.codec.model.yml +++ b/java/ql/lib/ext/io.netty.handler.codec.model.yml @@ -16,8 +16,7 @@ extensions: pack: codeql/java-all extensible: summaryModel data: - - ["io.netty.handler.codec", "ByteToMessageDecoder$Cumulator", True, "cumulate", "(ByteBufAllocator,ByteBuf,ByteBuf)", "", "Argument[1]", "ReturnValue", "taint", "manual"] - - ["io.netty.handler.codec", "ByteToMessageDecoder$Cumulator", True, "cumulate", "(ByteBufAllocator,ByteBuf,ByteBuf)", "", "Argument[2]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec", "ByteToMessageDecoder$Cumulator", True, "cumulate", "(ByteBufAllocator,ByteBuf,ByteBuf)", "", "Argument[1..2]", "ReturnValue", "taint", "manual"] - ["io.netty.handler.codec", "HeadersUtils", False, "getAsString", "(Headers,Object)", "", "Argument[0]", "ReturnValue", "taint", "manual"] - ["io.netty.handler.codec", "HeadersUtils", False, "getAllAsString", "(Headers,Object)", "", "Argument[0]", "ReturnValue", "taint", "manual"] - ["io.netty.handler.codec", "HeadersUtils", False, "namesAsString", "(Headers)", "", "Argument[0]", "ReturnValue", "taint", "manual"] From a476677b2b4076907673c5093729fea29e516c3d Mon Sep 17 00:00:00 2001 From: Joe Farebrother <joefarebrother@github.com> Date: Mon, 13 Mar 2023 13:44:39 +0000 Subject: [PATCH 375/631] Model more setters and constructors --- ...io.netty.handler.codec.http.cookie.model.yml | 12 ++++++++++-- .../ext/io.netty.handler.codec.http.model.yml | 3 +++ ...netty.handler.codec.http.multipart.model.yml | 9 ++++++++- ...etty.handler.codec.http.websocketx.model.yml | 17 +++++++++++++++++ .../ext/io.netty.handler.codec.http2.model.yml | 17 +++++++++++++---- .../ql/lib/ext/io.netty.handler.codec.model.yml | 1 + 6 files changed, 52 insertions(+), 7 deletions(-) diff --git a/java/ql/lib/ext/io.netty.handler.codec.http.cookie.model.yml b/java/ql/lib/ext/io.netty.handler.codec.http.cookie.model.yml index 42a93a21638..37abc4d0913 100644 --- a/java/ql/lib/ext/io.netty.handler.codec.http.cookie.model.yml +++ b/java/ql/lib/ext/io.netty.handler.codec.http.cookie.model.yml @@ -7,5 +7,13 @@ extensions: - ["io.netty.handler.codec.http.cookie", "Cookie", True, "name", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - ["io.netty.handler.codec.http.cookie", "Cookie", True, "path", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - ["io.netty.handler.codec.http.cookie", "Cookie", True, "value", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.handler.codec.http.cookie", "ServerCookieDecoder", True, "decode", "(String)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.handler.codec.http.cookie", "ServerCookieDecoder", True, "decodeAll", "(String)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] \ No newline at end of file + - ["io.netty.handler.codec.http.cookie", "Cookie", True, "setDomain", "()", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["io.netty.handler.codec.http.cookie", "Cookie", True, "setPath", "()", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["io.netty.handler.codec.http.cookie", "Cookie", True, "setValue", "()", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["io.netty.handler.codec.http.cookie", "ServerCookieDecoder", True, "decode", "(String)", "", "Argument[0]", "ReturnValue.Element", "taint", "manual"] + - ["io.netty.handler.codec.http.cookie", "ServerCookieDecoder", True, "decodeAll", "(String)", "", "Argument[0]", "ReturnValue.Element", "taint", "manual"] + - ["io.netty.handler.codec.http.cookie", "ServerCookieEncoder", True, "encode", "(Cookie)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http.cookie", "ServerCookieEncoder", True, "encode", "(Cookie[])", "", "Argument[0].ArrayElement", "ReturnValue.Element", "taint", "manual"] + - ["io.netty.handler.codec.http.cookie", "ServerCookieEncoder", True, "encode", "(Collection)", "", "Argument[0].Element", "ReturnValue.Element", "taint", "manual"] + - ["io.netty.handler.codec.http.cookie", "ServerCookieEncoder", True, "encode", "(Iterable)", "", "Argument[0].Element", "ReturnValue.Element", "taint", "manual"] + - ["io.netty.handler.codec.http.cookie", "ServerCookieEncoder", True, "encode", "(String,String)", "", "Argument[1..2]", "ReturnValue", "taint", "manual"] \ No newline at end of file diff --git a/java/ql/lib/ext/io.netty.handler.codec.http.model.yml b/java/ql/lib/ext/io.netty.handler.codec.http.model.yml index 25703f335cc..f905ded67b1 100644 --- a/java/ql/lib/ext/io.netty.handler.codec.http.model.yml +++ b/java/ql/lib/ext/io.netty.handler.codec.http.model.yml @@ -10,6 +10,7 @@ extensions: extensible: summaryModel data: - ["io.netty.handler.codec.http", "QueryStringEncoder", True, "QueryStringEncoder", "(String)", "", "Argument[0]", "Argument[this]", "taint", "ai-generated"] + # TODO: Use precise access paths. - ["io.netty.handler.codec.http", "HttpHeaders", True, "copy", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - ["io.netty.handler.codec.http", "HttpHeaders", True, "entries", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - ["io.netty.handler.codec.http", "HttpHeaders", True, "get", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] @@ -28,10 +29,12 @@ extensions: - ["io.netty.handler.codec.http", "HttpHeaders", True, "valueCharSequenceIterator", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - ["io.netty.handler.codec.http", "HttpHeaders", True, "valueStringIterator", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - ["io.netty.handler.codec.http", "HttpHeaders", True, "toString", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + # Currently all write steps to http messages are taint flow. It may reduce FPs to use synthetic field for headers instead. - ["io.netty.handler.codec.http", "HttpMessage", True, "headers", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - ["io.netty.handler.codec.http", "LastHttpContent", True, "trailingHeaders", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - ["io.netty.handler.codec.http", "HttpRequest", True, "getUri", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - ["io.netty.handler.codec.http", "HttpRequest", True, "uri", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http", "HttpRequest", True, "setUri", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] - ["io.netty.handler.codec.http", "QueryStringDecoder", True, "QueryStringDecoder", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] - ["io.netty.handler.codec.http", "QueryStringDecoder", True, "decodeComponent", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] - ["io.netty.handler.codec.http", "QueryStringDecoder", True, "parameters", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] diff --git a/java/ql/lib/ext/io.netty.handler.codec.http.multipart.model.yml b/java/ql/lib/ext/io.netty.handler.codec.http.multipart.model.yml index f96583c4aa0..00ef39795ee 100644 --- a/java/ql/lib/ext/io.netty.handler.codec.http.multipart.model.yml +++ b/java/ql/lib/ext/io.netty.handler.codec.http.multipart.model.yml @@ -25,12 +25,19 @@ extensions: - ["io.netty.handler.codec.http.multipart", "HttpPostMultipartRequestDecoder", True, "HttpPostMultipartRequestDecoder", "(HttpDataFactory,HttpRequest)", "", "Argument[1]", "Argument[-1]", "taint", "manual"] - ["io.netty.handler.codec.http.multipart", "HttpPostMultipartRequestDecoder", True, "HttpPostMultipartRequestDecoder", "(HttpDataFactory,HttpRequest,Charset)", "", "Argument[1]", "Argument[-1]", "taint", "manual"] - ["io.netty.handler.codec.http.multipart", "InterfaceHttpData", True, "getName", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http.multipart", "HttpData", True, "addContent", "(ByteBuf,boolean)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] - ["io.netty.handler.codec.http.multipart", "HttpData", True, "get", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - ["io.netty.handler.codec.http.multipart", "HttpData", True, "getByteBuf", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - ["io.netty.handler.codec.http.multipart", "HttpData", True, "getChunk", "(int)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - ["io.netty.handler.codec.http.multipart", "HttpData", True, "getString", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - ["io.netty.handler.codec.http.multipart", "HttpData", True, "getString", "(Charset)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - ["io.netty.handler.codec.http.multipart", "Attribute", True, "getValue", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http.multipart", "Attribute", True, "setValue", "(String)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] - ["io.netty.handler.codec.http.multipart", "FileUpload", True, "getContentTransferEncoding", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - ["io.netty.handler.codec.http.multipart", "FileUpload", True, "getContentType", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.handler.codec.http.multipart", "FileUpload", True, "getFilename", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http.multipart", "FileUpload", True, "getFilename", "(String)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http.multipart", "FileUpload", True, "setContentTransferEncoding", "(String)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["io.netty.handler.codec.http.multipart", "FileUpload", True, "setContentType", "(String)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["io.netty.handler.codec.http.multipart", "FileUpload", True, "setFilename", "(String)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["io.netty.handler.codec.http.multipart", "HttpData", True, "setContent", "(ByteBuf)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["io.netty.handler.codec.http.multipart", "HttpData", True, "setContent", "(InputStream)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] diff --git a/java/ql/lib/ext/io.netty.handler.codec.http.websocketx.model.yml b/java/ql/lib/ext/io.netty.handler.codec.http.websocketx.model.yml index 86d4c3c8240..89b7240097b 100644 --- a/java/ql/lib/ext/io.netty.handler.codec.http.websocketx.model.yml +++ b/java/ql/lib/ext/io.netty.handler.codec.http.websocketx.model.yml @@ -3,6 +3,23 @@ extensions: pack: codeql/java-all extensible: summaryModel data: + - ["io.netty.handler.codec.http.websocketx", "CloseWebSocketFrame", True, "CloseWebSocketFrame", "(boolean,int,ByteBuf)", "", "Argument[2]", "Argument[-1]", "taint", "manual"] + - ["io.netty.handler.codec.http.websocketx", "CloseWebSocketFrame", True, "CloseWebSocketFrame", "(boolean,int,int,String)", "", "Argument[3]", "Argument[-1]", "taint", "manual"] + - ["io.netty.handler.codec.http.websocketx", "CloseWebSocketFrame", True, "CloseWebSocketFrame", "(int,String)", "", "Argument[1]", "Argument[-1]", "taint", "manual"] + - ["io.netty.handler.codec.http.websocketx", "CloseWebSocketFrame", True, "CloseWebSocketFrame", "(WebSocketCloseStatus,String)", "", "Argument[2]", "Argument[-1]", "taint", "manual"] - ["io.netty.handler.codec.http.websocketx", "CloseWebSocketFrame", True, "reasonText", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http.websocketx", "BinaryWebSocketFrame", True, "BinaryWebSocketFrame", "(boolean,int,ByteBuf)", "", "Argument[2]", "Argument[-1]", "taint", "manual"] + - ["io.netty.handler.codec.http.websocketx", "BinaryWebSocketFrame", True, "BinaryWebSocketFrame", "(ByteBuf)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["io.netty.handler.codec.http.websocketx", "ContinuationWebSocketFrame", True, "ContinuationWebSocketFrame", "(boolean,int,ByteBuf)", "", "Argument[2]", "Argument[-1]", "taint", "manual"] + - ["io.netty.handler.codec.http.websocketx", "ContinuationWebSocketFrame", True, "ContinuationWebSocketFrame", "(boolean,int,String)", "", "Argument[2]", "Argument[-1]", "taint", "manual"] + - ["io.netty.handler.codec.http.websocketx", "ContinuationWebSocketFrame", True, "ContinuationWebSocketFrame", "(ByteBuf)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] - ["io.netty.handler.codec.http.websocketx", "ContinuationWebSocketFrame", True, "text", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http.websocketx", "PingWebSocketFrame", True, "PingWebSocketFrame", "(boolean,int,ByteBuf)", "", "Argument[2]", "Argument[-1]", "taint", "manual"] + - ["io.netty.handler.codec.http.websocketx", "PingWebSocketFrame", True, "PingWebSocketFrame", "(ByteBuf)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["io.netty.handler.codec.http.websocketx", "PongWebSocketFrame", True, "PongWebSocketFrame", "(boolean,int,ByteBuf)", "", "Argument[2]", "Argument[-1]", "taint", "manual"] + - ["io.netty.handler.codec.http.websocketx", "PongWebSocketFrame", True, "PongWebSocketFrame", "(ByteBuf)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["io.netty.handler.codec.http.websocketx", "TextWebSocketFrame", True, "TextWebSocketFrame", "(boolean,int,ByteBuf)", "", "Argument[2]", "Argument[-1]", "taint", "manual"] + - ["io.netty.handler.codec.http.websocketx", "TextWebSocketFrame", True, "TextWebSocketFrame", "(boolean,int,String)", "", "Argument[2]", "Argument[-1]", "taint", "manual"] + - ["io.netty.handler.codec.http.websocketx", "TextWebSocketFrame", True, "TextWebSocketFrame", "(String)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["io.netty.handler.codec.http.websocketx", "TextWebSocketFrame", True, "TextWebSocketFrame", "(ByteBuf)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] - ["io.netty.handler.codec.http.websocketx", "TextWebSocketFrame", True, "text", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] \ No newline at end of file diff --git a/java/ql/lib/ext/io.netty.handler.codec.http2.model.yml b/java/ql/lib/ext/io.netty.handler.codec.http2.model.yml index 3a47a2b2565..07757dac1d1 100644 --- a/java/ql/lib/ext/io.netty.handler.codec.http2.model.yml +++ b/java/ql/lib/ext/io.netty.handler.codec.http2.model.yml @@ -11,20 +11,29 @@ extensions: pack: codeql/java-all extensible: summaryModel data: + # TODO: Model more precise access paths - ["io.netty.handler.codec.http2", "Http2Headers", True, "authority", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http2", "Http2Headers", True, "authority", "(CharSequence)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["io.netty.handler.codec.http2", "Http2Headers", True, "authority", "(CharSequence)", "", "Argument[-1]", "ReturnValue", "value", "manual"] - ["io.netty.handler.codec.http2", "Http2Headers", True, "iterator", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - ["io.netty.handler.codec.http2", "Http2Headers", True, "method", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http2", "Http2Headers", True, "method", "(CharSequence)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["io.netty.handler.codec.http2", "Http2Headers", True, "method", "(CharSequence)", "", "Argument[-1]", "ReturnValue", "value", "manual"] - ["io.netty.handler.codec.http2", "Http2Headers", True, "path", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http2", "Http2Headers", True, "path", "(CharSequence)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["io.netty.handler.codec.http2", "Http2Headers", True, "path", "(CharSequence)", "", "Argument[-1]", "ReturnValue", "value", "manual"] - ["io.netty.handler.codec.http2", "Http2Headers", True, "scheme", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http2", "Http2Headers", True, "scheme", "(CharSequence)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["io.netty.handler.codec.http2", "Http2Headers", True, "scheme", "(CharSequence)", "", "Argument[-1]", "ReturnValue", "value", "manual"] - ["io.netty.handler.codec.http2", "Http2Headers", True, "status", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http2", "Http2Headers", True, "status", "(CharSequence)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["io.netty.handler.codec.http2", "Http2Headers", True, "status", "(CharSequence)", "", "Argument[-1]", "ReturnValue", "value", "manual"] - ["io.netty.handler.codec.http2", "Http2Headers", True, "valueIterator", "(CharSequence)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - ["io.netty.handler.codec.http2", "Http2HeadersFrame", True, "headers", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - ["io.netty.handler.codec.http2", "Http2PushPromiseFrame", True, "http2Headers", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - ["io.netty.handler.codec.http2", "HttpConversionUtil", False, "addHttp2ToHttpHeaders", "", "", "Argument[1]", "Argument[2]", "taint", "manual"] - - ["io.netty.handler.codec.http2", "HttpConversionUtil", False, "toFullHttpRequest", "", "", "Argument[1]", "ReturnValue", "taint", "manual"] - - ["io.netty.handler.codec.http2", "HttpConversionUtil", False, "toFullHttpRequest", "", "", "Argument[2]", "ReturnValue", "taint", "manual"] - - ["io.netty.handler.codec.http2", "HttpConversionUtil", False, "toFullHttpResponse", "", "", "Argument[1]", "ReturnValue", "taint", "manual"] - - ["io.netty.handler.codec.http2", "HttpConversionUtil", False, "toFullHttpResponse", "", "", "Argument[2]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http2", "HttpConversionUtil", False, "toFullHttpRequest", "", "", "Argument[1..2]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http2", "HttpConversionUtil", False, "toFullHttpResponse", "", "", "Argument[1..2]", "ReturnValue", "taint", "manual"] - ["io.netty.handler.codec.http2", "HttpConversionUtil", False, "toHttp2Headers", "(HttpHeaders,boolean)", "", "Argument[0]", "ReturnValue", "taint", "manual"] - ["io.netty.handler.codec.http2", "HttpConversionUtil", False, "toHttp2Headers", "(HttpHeaders,Http2Headers)", "", "Argument[0]", "Argument[1]", "taint", "manual"] - ["io.netty.handler.codec.http2", "HttpConversionUtil", False, "toHttpRequest", "", "", "Argument[1]", "ReturnValue", "taint", "manual"] diff --git a/java/ql/lib/ext/io.netty.handler.codec.model.yml b/java/ql/lib/ext/io.netty.handler.codec.model.yml index d2925bb6c0f..66877389897 100644 --- a/java/ql/lib/ext/io.netty.handler.codec.model.yml +++ b/java/ql/lib/ext/io.netty.handler.codec.model.yml @@ -17,6 +17,7 @@ extensions: extensible: summaryModel data: - ["io.netty.handler.codec", "ByteToMessageDecoder$Cumulator", True, "cumulate", "(ByteBufAllocator,ByteBuf,ByteBuf)", "", "Argument[1..2]", "ReturnValue", "taint", "manual"] + # TODO: Use precise access paths for headers - ["io.netty.handler.codec", "HeadersUtils", False, "getAsString", "(Headers,Object)", "", "Argument[0]", "ReturnValue", "taint", "manual"] - ["io.netty.handler.codec", "HeadersUtils", False, "getAllAsString", "(Headers,Object)", "", "Argument[0]", "ReturnValue", "taint", "manual"] - ["io.netty.handler.codec", "HeadersUtils", False, "namesAsString", "(Headers)", "", "Argument[0]", "ReturnValue", "taint", "manual"] From 14f753b8cf40dca26c6a1eec9cb8857820c464a5 Mon Sep 17 00:00:00 2001 From: Joe Farebrother <joefarebrother@github.com> Date: Mon, 13 Mar 2023 17:55:44 +0000 Subject: [PATCH 376/631] Use precise access paths for http headers models --- .../ext/io.netty.handler.codec.http.model.yml | 73 +++++++++++------ .../io.netty.handler.codec.http2.model.yml | 49 +++++++----- .../lib/ext/io.netty.handler.codec.model.yml | 79 +++++++++++++++---- 3 files changed, 142 insertions(+), 59 deletions(-) diff --git a/java/ql/lib/ext/io.netty.handler.codec.http.model.yml b/java/ql/lib/ext/io.netty.handler.codec.http.model.yml index f905ded67b1..c7b9678ad7d 100644 --- a/java/ql/lib/ext/io.netty.handler.codec.http.model.yml +++ b/java/ql/lib/ext/io.netty.handler.codec.http.model.yml @@ -10,26 +10,63 @@ extensions: extensible: summaryModel data: - ["io.netty.handler.codec.http", "QueryStringEncoder", True, "QueryStringEncoder", "(String)", "", "Argument[0]", "Argument[this]", "taint", "ai-generated"] - # TODO: Use precise access paths. - - ["io.netty.handler.codec.http", "HttpHeaders", True, "copy", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.handler.codec.http", "HttpHeaders", True, "entries", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.handler.codec.http", "HttpHeaders", True, "get", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http", "HttpHeaders", True, "add", "(CharSequence,Iterable)", "", "Argument[0]", "Argument[-1].Element.MapKey", "taint", "manual"] + - ["io.netty.handler.codec.http", "HttpHeaders", True, "add", "(CharSequence,Iterable)", "", "Argument[1].Element", "Argument[-1].Element.MapValue", "taint", "manual"] + - ["io.netty.handler.codec.http", "HttpHeaders", True, "add", "(CharSequence,Object)", "", "Argument[0]", "Argument[-1].Element.MapKey", "taint", "manual"] + - ["io.netty.handler.codec.http", "HttpHeaders", True, "add", "(CharSequence,Object)", "", "Argument[1]", "Argument[-1].Element.MapValue", "taint", "manual"] + - ["io.netty.handler.codec.http", "HttpHeaders", True, "add", "(String,Iterable)", "", "Argument[0]", "Argument[-1].Element.MapKey", "value", "manual"] + - ["io.netty.handler.codec.http", "HttpHeaders", True, "add", "(String,Iterable)", "", "Argument[1].Element", "Argument[-1].Element.MapValue", "taint", "manual"] + - ["io.netty.handler.codec.http", "HttpHeaders", True, "add", "(String,Object)", "", "Argument[0]", "Argument[-1].Element.MapKey", "value", "manual"] + - ["io.netty.handler.codec.http", "HttpHeaders", True, "add", "(String,Object)", "", "Argument[1]", "Argument[-1].Element.MapValue", "taint", "manual"] + - ["io.netty.handler.codec.http", "HttpHeaders", True, "add", "(HttpHeaders)", "", "Argument[0].Element.MapKey", "Argument[-1].Element.MapKey", "value", "manual"] + - ["io.netty.handler.codec.http", "HttpHeaders", True, "add", "(HttpHeaders)", "", "Argument[0].Element.MapValue", "Argument[-1].Element.MapValue", "taint", "manual"] + - ["io.netty.handler.codec.http", "HttpHeaders", True, "addInt", "(CharSequence,int)", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["io.netty.handler.codec.http", "HttpHeaders", True, "addInt", "(CharSequence,int)", "", "Argument[0]", "Argument[-1].Element.MapKey", "value", "manual"] + - ["io.netty.handler.codec.http", "HttpHeaders", True, "addShort", "(CharSequence,short)", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["io.netty.handler.codec.http", "HttpHeaders", True, "addShort", "(CharSequence,short)", "", "Argument[0]", "Argument[-1].Element.MapKey", "value", "manual"] + - ["io.netty.handler.codec.http", "HttpHeaders", True, "copy", "()", "", "Argument[-1].Element.MapKey", "ReturnValue.Element.MapKey", "value", "manual"] + - ["io.netty.handler.codec.http", "HttpHeaders", True, "copy", "()", "", "Argument[-1].Element.MapValue", "ReturnValue.Element.MapValue", "value", "manual"] + - ["io.netty.handler.codec.http", "HttpHeaders", True, "entries", "()", "", "Argument[-1].Element.MapKey", "ReturnValue.Element.MapKey", "value", "manual"] + - ["io.netty.handler.codec.http", "HttpHeaders", True, "entries", "()", "", "Argument[-1].Element.MapValue", "ReturnValue.Element.MapValue", "value", "manual"] + - ["io.netty.handler.codec.http", "HttpHeaders", True, "get", "", "", "Argument[-1].Element.MapValue", "ReturnValue", "value", "manual"] - ["io.netty.handler.codec.http", "HttpHeaders", True, "get", "", "", "Argument[1]", "ReturnValue", "value", "manual"] - - ["io.netty.handler.codec.http", "HttpHeaders", True, "getAll", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.handler.codec.http", "HttpHeaders", True, "getAllAsString", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.handler.codec.http", "HttpHeaders", True, "getAsString", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http", "HttpHeaders", True, "getAll", "", "", "Argument[-1].Element.MapValue", "ReturnValue.Element", "value", "manual"] + - ["io.netty.handler.codec.http", "HttpHeaders", True, "getAllAsString", "", "", "Argument[-1].Element.MapValue", "ReturnValue.Element", "value", "manual"] + - ["io.netty.handler.codec.http", "HttpHeaders", True, "getAsString", "", "", "Argument[-1].Element.MapValue", "ReturnValue", "value", "manual"] - ["io.netty.handler.codec.http", "HttpHeaders", True, "getHeader", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] - ["io.netty.handler.codec.http", "HttpHeaders", True, "getHeader", "", "", "Argument[2]", "ReturnValue", "value", "manual"] - ["io.netty.handler.codec.http", "HttpHeaders", True, "getHost", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] - ["io.netty.handler.codec.http", "HttpHeaders", True, "getHost", "", "", "Argument[1]", "ReturnValue", "value", "manual"] - - ["io.netty.handler.codec.http", "HttpHeaders", True, "iteratorAsString", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.handler.codec.http", "HttpHeaders", True, "iteratorCharSequence", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.handler.codec.http", "HttpHeaders", True, "names", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http", "HttpHeaders", True, "iteratorAsString", "()", "", "Argument[-1].Element.MapKey", "ReturnValue.Element.MapKey", "value", "manual"] + - ["io.netty.handler.codec.http", "HttpHeaders", True, "iteratorAsString", "()", "", "Argument[-1].Element.MapValue", "ReturnValue.Element.MapValue", "value", "manual"] + - ["io.netty.handler.codec.http", "HttpHeaders", True, "iteratorCharSequence", "()", "", "Argument[-1].Element.MapKey", "ReturnValue.Element.MapKey", "taint", "manual"] + - ["io.netty.handler.codec.http", "HttpHeaders", True, "iteratorCharSequence", "()", "", "Argument[-1].Element.MapValue", "ReturnValue.Element.MapValue", "taint", "manual"] + - ["io.netty.handler.codec.http", "HttpHeaders", True, "names", "()", "", "Argument[-1].Element.MapKey", "ReturnValue.Element", "value", "manual"] - ["io.netty.handler.codec.http", "HttpHeaders", True, "newEntity", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] - - ["io.netty.handler.codec.http", "HttpHeaders", True, "valueCharSequenceIterator", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.handler.codec.http", "HttpHeaders", True, "valueStringIterator", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.handler.codec.http", "HttpHeaders", True, "toString", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - # Currently all write steps to http messages are taint flow. It may reduce FPs to use synthetic field for headers instead. + - ["io.netty.handler.codec.http", "HttpHeaders", True, "remove", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["io.netty.handler.codec.http", "HttpHeaders", True, "set", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["io.netty.handler.codec.http", "HttpHeaders", True, "set", "(CharSequence,Iterable)", "", "Argument[0]", "Argument[-1].Element.MapKey", "taint", "manual"] + - ["io.netty.handler.codec.http", "HttpHeaders", True, "set", "(CharSequence,Iterable)", "", "Argument[1].Element", "Argument[-1].Element.MapValue", "taint", "manual"] + - ["io.netty.handler.codec.http", "HttpHeaders", True, "set", "(CharSequence,Object)", "", "Argument[0]", "Argument[-1].Element.MapKey", "taint", "manual"] + - ["io.netty.handler.codec.http", "HttpHeaders", True, "set", "(CharSequence,Object)", "", "Argument[1]", "Argument[-1].Element.MapValue", "taint", "manual"] + - ["io.netty.handler.codec.http", "HttpHeaders", True, "set", "(String,Iterable)", "", "Argument[0]", "Argument[-1].Element.MapKey", "value", "manual"] + - ["io.netty.handler.codec.http", "HttpHeaders", True, "set", "(String,Iterable)", "", "Argument[1].Element", "Argument[-1].Element.MapValue", "taint", "manual"] + - ["io.netty.handler.codec.http", "HttpHeaders", True, "set", "(String,Object)", "", "Argument[0]", "Argument[-1].Element.MapKey", "value", "manual"] + - ["io.netty.handler.codec.http", "HttpHeaders", True, "set", "(String,Object)", "", "Argument[1]", "Argument[-1].Element.MapValue", "taint", "manual"] + - ["io.netty.handler.codec.http", "HttpHeaders", True, "set", "(HttpHeaders)", "", "Argument[0].Element.MapKey", "Argument[-1].Element.MapKey", "value", "manual"] + - ["io.netty.handler.codec.http", "HttpHeaders", True, "set", "(HttpHeaders)", "", "Argument[0].Element.MapValue", "Argument[-1].Element.MapValue", "taint", "manual"] + - ["io.netty.handler.codec.http", "HttpHeaders", True, "setAll", "(HttpHeaders)", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["io.netty.handler.codec.http", "HttpHeaders", True, "setAll", "(HttpHeaders)", "", "Argument[0].Element.MapKey", "Argument[-1].Element.MapKey", "value", "manual"] + - ["io.netty.handler.codec.http", "HttpHeaders", True, "setAll", "(HttpHeaders)", "", "Argument[0].Element.MapValue", "Argument[-1].Element.MapValue", "taint", "manual"] + - ["io.netty.handler.codec.http", "HttpHeaders", True, "setInt", "(CharSequence,int)", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["io.netty.handler.codec.http", "HttpHeaders", True, "setInt", "(CharSequence,int)", "", "Argument[0]", "Argument[-1].Element.MapKey", "value", "manual"] + - ["io.netty.handler.codec.http", "HttpHeaders", True, "setShort", "(CharSequence,short)", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["io.netty.handler.codec.http", "HttpHeaders", True, "setShort", "(CharSequence,short)", "", "Argument[0]", "Argument[-1].Element.MapKey", "value", "manual"] + - ["io.netty.handler.codec.http", "HttpHeaders", True, "valueStringIterator", "()", "", "Argument[-1].Element.MapValue", "ReturnValue.Element", "value", "manual"] + - ["io.netty.handler.codec.http", "HttpHeaders", True, "valueCharSequenceIterator", "()", "", "Argument[-1].Element.MapValue", "ReturnValue.Element", "taint", "manual"] + - ["io.netty.handler.codec.http", "HttpHeaders", True, "toString", "", "", "Argument[-1].Element.MapKey", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http", "HttpHeaders", True, "toString", "", "", "Argument[-1].Element.MapValue", "ReturnValue", "taint", "manual"] + # Currently all write steps to http messages are taint flow. It may reduce FPs to use a synthetic field for headers instead. - ["io.netty.handler.codec.http", "HttpMessage", True, "headers", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - ["io.netty.handler.codec.http", "LastHttpContent", True, "trailingHeaders", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - ["io.netty.handler.codec.http", "HttpRequest", True, "getUri", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] @@ -43,11 +80,3 @@ extensions: - ["io.netty.handler.codec.http", "QueryStringDecoder", True, "rawQuery", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - ["io.netty.handler.codec.http", "QueryStringDecoder", True, "toString", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - ["io.netty.handler.codec.http", "QueryStringDecoder", True, "uri", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.handler.codec.http", "HttpHeaders", True, "add", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] - - ["io.netty.handler.codec.http", "HttpHeaders", True, "addInt", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] - - ["io.netty.handler.codec.http", "HttpHeaders", True, "addShort", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] - - ["io.netty.handler.codec.http", "HttpHeaders", True, "remove", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] - - ["io.netty.handler.codec.http", "HttpHeaders", True, "set", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] - - ["io.netty.handler.codec.http", "HttpHeaders", True, "setAll", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] - - ["io.netty.handler.codec.http", "HttpHeaders", True, "setInt", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] - - ["io.netty.handler.codec.http", "HttpHeaders", True, "setShort", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] diff --git a/java/ql/lib/ext/io.netty.handler.codec.http2.model.yml b/java/ql/lib/ext/io.netty.handler.codec.http2.model.yml index 07757dac1d1..2f34ed2fe77 100644 --- a/java/ql/lib/ext/io.netty.handler.codec.http2.model.yml +++ b/java/ql/lib/ext/io.netty.handler.codec.http2.model.yml @@ -11,30 +11,39 @@ extensions: pack: codeql/java-all extensible: summaryModel data: - # TODO: Model more precise access paths - - ["io.netty.handler.codec.http2", "Http2Headers", True, "authority", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.handler.codec.http2", "Http2Headers", True, "authority", "(CharSequence)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["io.netty.handler.codec.http2", "Http2Headers", True, "authority", "()", "", "Argument[-1].Element.MapValue", "ReturnValue", "value", "manual"] + - ["io.netty.handler.codec.http2", "Http2Headers", True, "authority", "(CharSequence)", "", "Argument[0]", "Argument[-1].Element.MapValue", "value", "manual"] - ["io.netty.handler.codec.http2", "Http2Headers", True, "authority", "(CharSequence)", "", "Argument[-1]", "ReturnValue", "value", "manual"] - - ["io.netty.handler.codec.http2", "Http2Headers", True, "iterator", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.handler.codec.http2", "Http2Headers", True, "method", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.handler.codec.http2", "Http2Headers", True, "method", "(CharSequence)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["io.netty.handler.codec.http2", "Http2Headers", True, "method", "()", "", "Argument[-1].Element.MapValue", "ReturnValue", "value", "manual"] + - ["io.netty.handler.codec.http2", "Http2Headers", True, "method", "(CharSequence)", "", "Argument[0]", "Argument[-1].Element.MapValue", "value", "manual"] - ["io.netty.handler.codec.http2", "Http2Headers", True, "method", "(CharSequence)", "", "Argument[-1]", "ReturnValue", "value", "manual"] - - ["io.netty.handler.codec.http2", "Http2Headers", True, "path", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.handler.codec.http2", "Http2Headers", True, "path", "(CharSequence)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["io.netty.handler.codec.http2", "Http2Headers", True, "path", "()", "", "Argument[-1].Element.MapValue", "ReturnValue", "value", "manual"] + - ["io.netty.handler.codec.http2", "Http2Headers", True, "path", "(CharSequence)", "", "Argument[0]", "Argument[-1].Element.MapValue", "value", "manual"] - ["io.netty.handler.codec.http2", "Http2Headers", True, "path", "(CharSequence)", "", "Argument[-1]", "ReturnValue", "value", "manual"] - - ["io.netty.handler.codec.http2", "Http2Headers", True, "scheme", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.handler.codec.http2", "Http2Headers", True, "scheme", "(CharSequence)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["io.netty.handler.codec.http2", "Http2Headers", True, "scheme", "()", "", "Argument[-1].Element.MapValue", "ReturnValue", "value", "manual"] + - ["io.netty.handler.codec.http2", "Http2Headers", True, "scheme", "(CharSequence)", "", "Argument[0]", "Argument[-1].Element.MapValue", "value", "manual"] - ["io.netty.handler.codec.http2", "Http2Headers", True, "scheme", "(CharSequence)", "", "Argument[-1]", "ReturnValue", "value", "manual"] - - ["io.netty.handler.codec.http2", "Http2Headers", True, "status", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.handler.codec.http2", "Http2Headers", True, "status", "(CharSequence)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["io.netty.handler.codec.http2", "Http2Headers", True, "status", "()", "", "Argument[-1].Element.MapValue", "ReturnValue", "value", "manual"] + - ["io.netty.handler.codec.http2", "Http2Headers", True, "status", "(CharSequence)", "", "Argument[0]", "Argument[-1].Element.MapValue", "value", "manual"] - ["io.netty.handler.codec.http2", "Http2Headers", True, "status", "(CharSequence)", "", "Argument[-1]", "ReturnValue", "value", "manual"] - - ["io.netty.handler.codec.http2", "Http2Headers", True, "valueIterator", "(CharSequence)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http2", "Http2Headers", True, "valueIterator", "(CharSequence)", "", "Argument[-1].Element.MapValue", "ReturnValue.Element", "value", "manual"] - ["io.netty.handler.codec.http2", "Http2HeadersFrame", True, "headers", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - ["io.netty.handler.codec.http2", "Http2PushPromiseFrame", True, "http2Headers", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.handler.codec.http2", "HttpConversionUtil", False, "addHttp2ToHttpHeaders", "", "", "Argument[1]", "Argument[2]", "taint", "manual"] - - ["io.netty.handler.codec.http2", "HttpConversionUtil", False, "toFullHttpRequest", "", "", "Argument[1..2]", "ReturnValue", "taint", "manual"] - - ["io.netty.handler.codec.http2", "HttpConversionUtil", False, "toFullHttpResponse", "", "", "Argument[1..2]", "ReturnValue", "taint", "manual"] - - ["io.netty.handler.codec.http2", "HttpConversionUtil", False, "toHttp2Headers", "(HttpHeaders,boolean)", "", "Argument[0]", "ReturnValue", "taint", "manual"] - - ["io.netty.handler.codec.http2", "HttpConversionUtil", False, "toHttp2Headers", "(HttpHeaders,Http2Headers)", "", "Argument[0]", "Argument[1]", "taint", "manual"] - - ["io.netty.handler.codec.http2", "HttpConversionUtil", False, "toHttpRequest", "", "", "Argument[1]", "ReturnValue", "taint", "manual"] - - ["io.netty.handler.codec.http2", "HttpConversionUtil", False, "toHttpResponse", "", "", "Argument[1]", "ReturnValue", "taint", "manual"] \ No newline at end of file + - ["io.netty.handler.codec.http2", "HttpConversionUtil", False, "addHttp2ToHttpHeaders", "(int,Http2Headers,FullHttpMessage,boolean)", "", "Argument[1].Element.MapKey", "Argument[2]", "taint", "manual"] + - ["io.netty.handler.codec.http2", "HttpConversionUtil", False, "addHttp2ToHttpHeaders", "(int,Http2Headers,FullHttpMessage,boolean)", "", "Argument[1].Element.MapValue", "Argument[2]", "taint", "manual"] + - ["io.netty.handler.codec.http2", "HttpConversionUtil", False, "addHttp2ToHttpHeaders", "(int,Http2Headers,HttpHeaders,HttpVersion,boolean,boolean)", "", "Argument[1].Element.MapKey", "Argument[2].Element.MapKey", "taint", "manual"] + - ["io.netty.handler.codec.http2", "HttpConversionUtil", False, "addHttp2ToHttpHeaders", "(int,Http2Headers,HttpHeaders,HttpVersion,boolean,boolean)", "", "Argument[1].Element.MapValue", "Argument[2].Element.MapValue", "taint", "manual"] + - ["io.netty.handler.codec.http2", "HttpConversionUtil", False, "toFullHttpRequest", "", "", "Argument[1].Element.MapKey", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http2", "HttpConversionUtil", False, "toFullHttpRequest", "", "", "Argument[1].Element.MapValue", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http2", "HttpConversionUtil", False, "toFullHttpRequest", "(int,HttpHeaders,ByteBuf,boolean)", "", "Argument[2]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http2", "HttpConversionUtil", False, "toFullHttpResponse", "", "", "Argument[1].Element.MapKey", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http2", "HttpConversionUtil", False, "toFullHttpResponse", "", "", "Argument[1].Element.MapValue", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http2", "HttpConversionUtil", False, "toFullHttpResponse", "(int,HttpHeaders,ByteBuf,boolean)", "", "Argument[2]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http2", "HttpConversionUtil", False, "toHttp2Headers", "(HttpHeaders,boolean)", "", "Argument[0].Element.MapKey", "ReturnValue.Element.MapKey", "taint", "manual"] + - ["io.netty.handler.codec.http2", "HttpConversionUtil", False, "toHttp2Headers", "(HttpHeaders,boolean)", "", "Argument[0].Element.MapValue", "ReturnValue.Element.MapValue", "taint", "manual"] + - ["io.netty.handler.codec.http2", "HttpConversionUtil", False, "toHttp2Headers", "(HttpHeaders,Http2Headers)", "", "Argument[0].Element.MapKey", "Argument[1].Element.MapKey", "taint", "manual"] + - ["io.netty.handler.codec.http2", "HttpConversionUtil", False, "toHttp2Headers", "(HttpHeaders,Http2Headers)", "", "Argument[0].Element.MapValue", "Argument[1].Element.MapValue", "taint", "manual"] + - ["io.netty.handler.codec.http2", "HttpConversionUtil", False, "toHttpRequest", "", "", "Argument[1].Element.MapKey", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http2", "HttpConversionUtil", False, "toHttpRequest", "", "", "Argument[1].Element.MapValue", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http2", "HttpConversionUtil", False, "toHttpResponse", "", "", "Argument[1].Element.MapKey", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http2", "HttpConversionUtil", False, "toHttpResponse", "", "", "Argument[1].Element.MapValue", "ReturnValue", "taint", "manual"] \ No newline at end of file diff --git a/java/ql/lib/ext/io.netty.handler.codec.model.yml b/java/ql/lib/ext/io.netty.handler.codec.model.yml index 66877389897..71849cf2c72 100644 --- a/java/ql/lib/ext/io.netty.handler.codec.model.yml +++ b/java/ql/lib/ext/io.netty.handler.codec.model.yml @@ -17,42 +17,87 @@ extensions: extensible: summaryModel data: - ["io.netty.handler.codec", "ByteToMessageDecoder$Cumulator", True, "cumulate", "(ByteBufAllocator,ByteBuf,ByteBuf)", "", "Argument[1..2]", "ReturnValue", "taint", "manual"] - # TODO: Use precise access paths for headers - - ["io.netty.handler.codec", "HeadersUtils", False, "getAsString", "(Headers,Object)", "", "Argument[0]", "ReturnValue", "taint", "manual"] - - ["io.netty.handler.codec", "HeadersUtils", False, "getAllAsString", "(Headers,Object)", "", "Argument[0]", "ReturnValue", "taint", "manual"] - - ["io.netty.handler.codec", "HeadersUtils", False, "namesAsString", "(Headers)", "", "Argument[0]", "ReturnValue", "taint", "manual"] - - ["io.netty.handler.codec", "HeadersUtils", False, "iteratorAsString", "(Iterable)", "", "Argument[0]", "ReturnValue", "taint", "manual"] - - ["io.netty.handler.codec", "HeadersUtils", False, "toString", "(Class,Iterator,int)", "", "Argument[1]", "ReturnValue", "taint", "manual"] - - ["io.netty.handler.codec", "Headers", True, "get", "(Object)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.handler.codec", "Headers", True, "get", "(Object,Object)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec", "HeadersUtils", False, "getAsString", "(Headers,Object)", "", "Argument[0].Element.MapValue", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec", "HeadersUtils", False, "getAllAsString", "(Headers,Object)", "", "Argument[0].Element.MapValue", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec", "HeadersUtils", False, "namesAsString", "(Headers)", "", "Argument[0].Element.MapKey", "ReturnValue.Element", "value", "manual"] + - ["io.netty.handler.codec", "HeadersUtils", False, "iteratorAsString", "(Iterable)", "", "Argument[0].Element.MapKey", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec", "HeadersUtils", False, "iteratorAsString", "(Iterable)", "", "Argument[0].Element.MapValue", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec", "HeadersUtils", False, "toString", "(Class,Iterator,int)", "", "Argument[1].Element.MapKey", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec", "HeadersUtils", False, "toString", "(Class,Iterator,int)", "", "Argument[1].Element.MapValue", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec", "Headers", True, "get", "(Object)", "", "Argument[-1].Element.MapValue", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec", "Headers", True, "get", "(Object,Object)", "", "Argument[-1].Element.MapValue", "ReturnValue", "taint", "manual"] - ["io.netty.handler.codec", "Headers", True, "get", "(Object,Object)", "", "Argument[1]", "ReturnValue", "value", "manual"] - - ["io.netty.handler.codec", "Headers", True, "getAll", "(Object)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.handler.codec", "Headers", True, "getAllAndRemove", "(Object)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.handler.codec", "Headers", True, "getAndRemove", "(Object)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.handler.codec", "Headers", True, "getAndRemove", "(Object)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec", "Headers", True, "getAll", "(Object)", "", "Argument[-1].Element.MapValue", "ReturnValue.Element", "taint", "manual"] + - ["io.netty.handler.codec", "Headers", True, "getAllAndRemove", "(Object)", "", "Argument[-1].Element.MapValue", "ReturnValue.Element", "taint", "manual"] + - ["io.netty.handler.codec", "Headers", True, "getAndRemove", "(Object)", "", "Argument[-1].Element.MapValue", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec", "Headers", True, "getAndRemove", "(Object)", "", "Argument[-1].Element.MapValue", "ReturnValue", "taint", "manual"] - ["io.netty.handler.codec", "Headers", True, "getAndRemove", "(Object,Object)", "", "Argument[1]", "ReturnValue", "value", "manual"] - - ["io.netty.handler.codec", "Headers", True, "iterator", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.handler.codec", "Headers", True, "names", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec", "Headers", True, "names", "()", "", "Argument[-1].Element.MapKey", "ReturnValue.Element", "taint", "manual"] - ["io.netty.handler.codec", "Headers", True, "add", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["io.netty.handler.codec", "Headers", True, "add", "(Headers)", "", "Argument[0].Element.MapKey", "Argument[-1].Element.MapKey", "value", "manual"] + - ["io.netty.handler.codec", "Headers", True, "add", "(Headers)", "", "Argument[0].Element.MapValue", "Argument[-1].Element.MapValue", "value", "manual"] + - ["io.netty.handler.codec", "Headers", True, "add", "(Object,Iterable)", "", "Argument[0]", "Argument[-1].Element.MapKey", "value", "manual"] + - ["io.netty.handler.codec", "Headers", True, "add", "(Object,Iterable)", "", "Argument[1].Element", "Argument[-1].Element.MapValue", "value", "manual"] + - ["io.netty.handler.codec", "Headers", True, "add", "(Object,Object[])", "", "Argument[0]", "Argument[-1].Element.MapKey", "value", "manual"] + - ["io.netty.handler.codec", "Headers", True, "add", "(Object,Object[])", "", "Argument[1].ArrayElement", "Argument[-1].Element.MapValue", "value", "manual"] + - ["io.netty.handler.codec", "Headers", True, "add", "(Object,Object)", "", "Argument[0]", "Argument[-1].Element.MapKey", "value", "manual"] + - ["io.netty.handler.codec", "Headers", True, "add", "(Object,Object)", "", "Argument[1]", "Argument[-1].Element.MapValue", "value", "manual"] + - ["io.netty.handler.codec", "Headers", True, "addObject", "(Object,Iterable)", "", "Argument[0]", "Argument[-1].Element.MapKey", "value", "manual"] + - ["io.netty.handler.codec", "Headers", True, "addObject", "(Object,Iterable)", "", "Argument[1].Element", "Argument[-1].Element.MapValue", "taint", "manual"] + - ["io.netty.handler.codec", "Headers", True, "addObject", "(Object,Object[])", "", "Argument[0]", "Argument[-1].Element.MapKey", "value", "manual"] + - ["io.netty.handler.codec", "Headers", True, "addObject", "(Object,Object[])", "", "Argument[1].ArrayElement", "Argument[-1].Element.MapValue", "taint", "manual"] + - ["io.netty.handler.codec", "Headers", True, "addObject", "(Object,Object)", "", "Argument[0]", "Argument[-1].Element.MapKey", "value", "manual"] + - ["io.netty.handler.codec", "Headers", True, "addObject", "(Object,Object)", "", "Argument[1]", "Argument[-1].Element.MapValue", "taint", "manual"] - ["io.netty.handler.codec", "Headers", True, "addBoolean", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["io.netty.handler.codec", "Headers", True, "addBoolean", "", "", "Argument[0]", "Argument[-1].Element.MapKey", "value", "manual"] - ["io.netty.handler.codec", "Headers", True, "addByte", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["io.netty.handler.codec", "Headers", True, "addByte", "", "", "Argument[0]", "Argument[-1].Element.MapKey", "value", "manual"] - ["io.netty.handler.codec", "Headers", True, "addChar", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["io.netty.handler.codec", "Headers", True, "addChar", "", "", "Argument[0]", "Argument[-1].Element.MapKey", "value", "manual"] - ["io.netty.handler.codec", "Headers", True, "addDouble", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["io.netty.handler.codec", "Headers", True, "addDouble", "", "", "Argument[0]", "Argument[-1].Element.MapKey", "value", "manual"] - ["io.netty.handler.codec", "Headers", True, "addFloat", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["io.netty.handler.codec", "Headers", True, "addFloat", "", "", "Argument[0]", "Argument[-1].Element.MapKey", "value", "manual"] - ["io.netty.handler.codec", "Headers", True, "addInt", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["io.netty.handler.codec", "Headers", True, "addInt", "", "", "Argument[0]", "Argument[-1].Element.MapKey", "value", "manual"] - ["io.netty.handler.codec", "Headers", True, "addLong", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] - - ["io.netty.handler.codec", "Headers", True, "addObject", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["io.netty.handler.codec", "Headers", True, "addLong", "", "", "Argument[0]", "Argument[-1].Element.MapKey", "value", "manual"] - ["io.netty.handler.codec", "Headers", True, "addShort", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["io.netty.handler.codec", "Headers", True, "addShort", "", "", "Argument[0]", "Argument[-1].Element.MapKey", "value", "manual"] - ["io.netty.handler.codec", "Headers", True, "addTimeMillis", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["io.netty.handler.codec", "Headers", True, "addTimeMillis", "", "", "Argument[0]", "Argument[-1].Element.MapKey", "value", "manual"] - ["io.netty.handler.codec", "Headers", True, "set", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] - - ["io.netty.handler.codec", "Headers", True, "setAll", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["io.netty.handler.codec", "Headers", True, "set", "(Headers)", "", "Argument[0].Element.MapKey", "Argument[-1].Element.MapKey", "value", "manual"] + - ["io.netty.handler.codec", "Headers", True, "set", "(Headers)", "", "Argument[0].Element.MapValue", "Argument[-1].Element.MapValue", "value", "manual"] + - ["io.netty.handler.codec", "Headers", True, "set", "(Object,Iterable)", "", "Argument[0]", "Argument[-1].Element.MapKey", "value", "manual"] + - ["io.netty.handler.codec", "Headers", True, "set", "(Object,Iterable)", "", "Argument[1].Element", "Argument[-1].Element.MapValue", "value", "manual"] + - ["io.netty.handler.codec", "Headers", True, "set", "(Object,Object[])", "", "Argument[0]", "Argument[-1].Element.MapKey", "value", "manual"] + - ["io.netty.handler.codec", "Headers", True, "set", "(Object,Object[])", "", "Argument[1].ArrayElement", "Argument[-1].Element.MapValue", "value", "manual"] + - ["io.netty.handler.codec", "Headers", True, "set", "(Object,Object)", "", "Argument[0]", "Argument[-1].Element.MapKey", "value", "manual"] + - ["io.netty.handler.codec", "Headers", True, "set", "(Object,Object)", "", "Argument[1]", "Argument[-1].Element.MapValue", "value", "manual"] + - ["io.netty.handler.codec", "Headers", True, "setAll", "(Headers)", "", "Argument[0].Element.MapKey", "Argument[-1].Element.MapKey", "value", "manual"] + - ["io.netty.handler.codec", "Headers", True, "setAll", "(Headers)", "", "Argument[0].Element.MapValue", "Argument[-1].Element.MapValue", "value", "manual"] + - ["io.netty.handler.codec", "Headers", True, "setObject", "(Object,Iterable)", "", "Argument[0]", "Argument[-1].Element.MapKey", "value", "manual"] + - ["io.netty.handler.codec", "Headers", True, "setObject", "(Object,Iterable)", "", "Argument[1].Element", "Argument[-1].Element.MapValue", "taint", "manual"] + - ["io.netty.handler.codec", "Headers", True, "setObject", "(Object,Object[])", "", "Argument[0]", "Argument[-1].Element.MapKey", "value", "manual"] + - ["io.netty.handler.codec", "Headers", True, "setObject", "(Object,Object[])", "", "Argument[1].ArrayElement", "Argument[-1].Element.MapValue", "taint", "manual"] + - ["io.netty.handler.codec", "Headers", True, "setObject", "(Object,Object)", "", "Argument[0]", "Argument[-1].Element.MapKey", "value", "manual"] + - ["io.netty.handler.codec", "Headers", True, "setObject", "(Object,Object)", "", "Argument[1]", "Argument[-1].Element.MapValue", "taint", "manual"] - ["io.netty.handler.codec", "Headers", True, "setBoolean", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["io.netty.handler.codec", "Headers", True, "setBoolean", "", "", "Argument[0]", "Argument[-1].Element.MapKey", "value", "manual"] - ["io.netty.handler.codec", "Headers", True, "setByte", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["io.netty.handler.codec", "Headers", True, "setByte", "", "", "Argument[0]", "Argument[-1].Element.MapKey", "value", "manual"] - ["io.netty.handler.codec", "Headers", True, "setChar", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["io.netty.handler.codec", "Headers", True, "setChar", "", "", "Argument[0]", "Argument[-1].Element.MapKey", "value", "manual"] - ["io.netty.handler.codec", "Headers", True, "setDouble", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["io.netty.handler.codec", "Headers", True, "setDouble", "", "", "Argument[0]", "Argument[-1].Element.MapKey", "value", "manual"] - ["io.netty.handler.codec", "Headers", True, "setFloat", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["io.netty.handler.codec", "Headers", True, "setFloat", "", "", "Argument[0]", "Argument[-1].Element.MapKey", "value", "manual"] - ["io.netty.handler.codec", "Headers", True, "setInt", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["io.netty.handler.codec", "Headers", True, "setInt", "", "", "Argument[0]", "Argument[-1].Element.MapKey", "value", "manual"] - ["io.netty.handler.codec", "Headers", True, "setLong", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] - - ["io.netty.handler.codec", "Headers", True, "setObject", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["io.netty.handler.codec", "Headers", True, "setLong", "", "", "Argument[0]", "Argument[-1].Element.MapKey", "value", "manual"] - ["io.netty.handler.codec", "Headers", True, "setShort", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["io.netty.handler.codec", "Headers", True, "setShort", "", "", "Argument[0]", "Argument[-1].Element.MapKey", "value", "manual"] - ["io.netty.handler.codec", "Headers", True, "setTimeMillis", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["io.netty.handler.codec", "Headers", True, "setTimeMillis", "", "", "Argument[0]", "Argument[-1].Element.MapKey", "value", "manual"] From 9287549e932ab340f960d69109bd0ec775603a86 Mon Sep 17 00:00:00 2001 From: Joe Farebrother <joefarebrother@github.com> Date: Tue, 14 Mar 2023 14:29:49 +0000 Subject: [PATCH 377/631] Generate tests; fix models --- ....netty.handler.codec.http.cookie.model.yml | 6 +- .../ext/io.netty.handler.codec.http.model.yml | 4 +- ...tty.handler.codec.http.multipart.model.yml | 2 +- ...ty.handler.codec.http.websocketx.model.yml | 2 +- .../io.netty.handler.codec.http2.model.yml | 4 +- .../frameworks/netty/generated/Test.java | 1962 +++++++++++++++-- .../frameworks/netty/generated/test.ext.yml | 11 + .../codec/http/cookie/CookieEncoder.java | 12 + .../http/cookie/ServerCookieEncoder.java | 20 + .../http/websocketx/BinaryWebSocketFrame.java | 21 + .../http/websocketx/PingWebSocketFrame.java | 21 + .../http/websocketx/PongWebSocketFrame.java | 21 + 12 files changed, 1843 insertions(+), 243 deletions(-) create mode 100644 java/ql/test/library-tests/frameworks/netty/generated/test.ext.yml create mode 100644 java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http/cookie/CookieEncoder.java create mode 100644 java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http/cookie/ServerCookieEncoder.java create mode 100644 java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http/websocketx/BinaryWebSocketFrame.java create mode 100644 java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http/websocketx/PingWebSocketFrame.java create mode 100644 java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http/websocketx/PongWebSocketFrame.java diff --git a/java/ql/lib/ext/io.netty.handler.codec.http.cookie.model.yml b/java/ql/lib/ext/io.netty.handler.codec.http.cookie.model.yml index 37abc4d0913..c770d95a2bf 100644 --- a/java/ql/lib/ext/io.netty.handler.codec.http.cookie.model.yml +++ b/java/ql/lib/ext/io.netty.handler.codec.http.cookie.model.yml @@ -7,9 +7,9 @@ extensions: - ["io.netty.handler.codec.http.cookie", "Cookie", True, "name", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - ["io.netty.handler.codec.http.cookie", "Cookie", True, "path", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - ["io.netty.handler.codec.http.cookie", "Cookie", True, "value", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.handler.codec.http.cookie", "Cookie", True, "setDomain", "()", "", "Argument[0]", "Argument[-1]", "taint", "manual"] - - ["io.netty.handler.codec.http.cookie", "Cookie", True, "setPath", "()", "", "Argument[0]", "Argument[-1]", "taint", "manual"] - - ["io.netty.handler.codec.http.cookie", "Cookie", True, "setValue", "()", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["io.netty.handler.codec.http.cookie", "Cookie", True, "setDomain", "(String)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["io.netty.handler.codec.http.cookie", "Cookie", True, "setPath", "(String)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["io.netty.handler.codec.http.cookie", "Cookie", True, "setValue", "(String)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] - ["io.netty.handler.codec.http.cookie", "ServerCookieDecoder", True, "decode", "(String)", "", "Argument[0]", "ReturnValue.Element", "taint", "manual"] - ["io.netty.handler.codec.http.cookie", "ServerCookieDecoder", True, "decodeAll", "(String)", "", "Argument[0]", "ReturnValue.Element", "taint", "manual"] - ["io.netty.handler.codec.http.cookie", "ServerCookieEncoder", True, "encode", "(Cookie)", "", "Argument[0]", "ReturnValue", "taint", "manual"] diff --git a/java/ql/lib/ext/io.netty.handler.codec.http.model.yml b/java/ql/lib/ext/io.netty.handler.codec.http.model.yml index c7b9678ad7d..53cd74eb0b3 100644 --- a/java/ql/lib/ext/io.netty.handler.codec.http.model.yml +++ b/java/ql/lib/ext/io.netty.handler.codec.http.model.yml @@ -62,8 +62,8 @@ extensions: - ["io.netty.handler.codec.http", "HttpHeaders", True, "setInt", "(CharSequence,int)", "", "Argument[0]", "Argument[-1].Element.MapKey", "value", "manual"] - ["io.netty.handler.codec.http", "HttpHeaders", True, "setShort", "(CharSequence,short)", "", "Argument[-1]", "ReturnValue", "value", "manual"] - ["io.netty.handler.codec.http", "HttpHeaders", True, "setShort", "(CharSequence,short)", "", "Argument[0]", "Argument[-1].Element.MapKey", "value", "manual"] - - ["io.netty.handler.codec.http", "HttpHeaders", True, "valueStringIterator", "()", "", "Argument[-1].Element.MapValue", "ReturnValue.Element", "value", "manual"] - - ["io.netty.handler.codec.http", "HttpHeaders", True, "valueCharSequenceIterator", "()", "", "Argument[-1].Element.MapValue", "ReturnValue.Element", "taint", "manual"] + - ["io.netty.handler.codec.http", "HttpHeaders", True, "valueStringIterator", "(CharSequence)", "", "Argument[-1].Element.MapValue", "ReturnValue.Element", "value", "manual"] + - ["io.netty.handler.codec.http", "HttpHeaders", True, "valueCharSequenceIterator", "(CharSequence)", "", "Argument[-1].Element.MapValue", "ReturnValue.Element", "taint", "manual"] - ["io.netty.handler.codec.http", "HttpHeaders", True, "toString", "", "", "Argument[-1].Element.MapKey", "ReturnValue", "taint", "manual"] - ["io.netty.handler.codec.http", "HttpHeaders", True, "toString", "", "", "Argument[-1].Element.MapValue", "ReturnValue", "taint", "manual"] # Currently all write steps to http messages are taint flow. It may reduce FPs to use a synthetic field for headers instead. diff --git a/java/ql/lib/ext/io.netty.handler.codec.http.multipart.model.yml b/java/ql/lib/ext/io.netty.handler.codec.http.multipart.model.yml index 00ef39795ee..3d098271929 100644 --- a/java/ql/lib/ext/io.netty.handler.codec.http.multipart.model.yml +++ b/java/ql/lib/ext/io.netty.handler.codec.http.multipart.model.yml @@ -35,7 +35,7 @@ extensions: - ["io.netty.handler.codec.http.multipart", "Attribute", True, "setValue", "(String)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] - ["io.netty.handler.codec.http.multipart", "FileUpload", True, "getContentTransferEncoding", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - ["io.netty.handler.codec.http.multipart", "FileUpload", True, "getContentType", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.handler.codec.http.multipart", "FileUpload", True, "getFilename", "(String)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http.multipart", "FileUpload", True, "getFilename", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - ["io.netty.handler.codec.http.multipart", "FileUpload", True, "setContentTransferEncoding", "(String)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] - ["io.netty.handler.codec.http.multipart", "FileUpload", True, "setContentType", "(String)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] - ["io.netty.handler.codec.http.multipart", "FileUpload", True, "setFilename", "(String)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] diff --git a/java/ql/lib/ext/io.netty.handler.codec.http.websocketx.model.yml b/java/ql/lib/ext/io.netty.handler.codec.http.websocketx.model.yml index 89b7240097b..9bdd00f8663 100644 --- a/java/ql/lib/ext/io.netty.handler.codec.http.websocketx.model.yml +++ b/java/ql/lib/ext/io.netty.handler.codec.http.websocketx.model.yml @@ -6,7 +6,7 @@ extensions: - ["io.netty.handler.codec.http.websocketx", "CloseWebSocketFrame", True, "CloseWebSocketFrame", "(boolean,int,ByteBuf)", "", "Argument[2]", "Argument[-1]", "taint", "manual"] - ["io.netty.handler.codec.http.websocketx", "CloseWebSocketFrame", True, "CloseWebSocketFrame", "(boolean,int,int,String)", "", "Argument[3]", "Argument[-1]", "taint", "manual"] - ["io.netty.handler.codec.http.websocketx", "CloseWebSocketFrame", True, "CloseWebSocketFrame", "(int,String)", "", "Argument[1]", "Argument[-1]", "taint", "manual"] - - ["io.netty.handler.codec.http.websocketx", "CloseWebSocketFrame", True, "CloseWebSocketFrame", "(WebSocketCloseStatus,String)", "", "Argument[2]", "Argument[-1]", "taint", "manual"] + - ["io.netty.handler.codec.http.websocketx", "CloseWebSocketFrame", True, "CloseWebSocketFrame", "(WebSocketCloseStatus,String)", "", "Argument[1]", "Argument[-1]", "taint", "manual"] - ["io.netty.handler.codec.http.websocketx", "CloseWebSocketFrame", True, "reasonText", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - ["io.netty.handler.codec.http.websocketx", "BinaryWebSocketFrame", True, "BinaryWebSocketFrame", "(boolean,int,ByteBuf)", "", "Argument[2]", "Argument[-1]", "taint", "manual"] - ["io.netty.handler.codec.http.websocketx", "BinaryWebSocketFrame", True, "BinaryWebSocketFrame", "(ByteBuf)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] diff --git a/java/ql/lib/ext/io.netty.handler.codec.http2.model.yml b/java/ql/lib/ext/io.netty.handler.codec.http2.model.yml index 2f34ed2fe77..0b4229fac41 100644 --- a/java/ql/lib/ext/io.netty.handler.codec.http2.model.yml +++ b/java/ql/lib/ext/io.netty.handler.codec.http2.model.yml @@ -35,10 +35,10 @@ extensions: - ["io.netty.handler.codec.http2", "HttpConversionUtil", False, "addHttp2ToHttpHeaders", "(int,Http2Headers,HttpHeaders,HttpVersion,boolean,boolean)", "", "Argument[1].Element.MapValue", "Argument[2].Element.MapValue", "taint", "manual"] - ["io.netty.handler.codec.http2", "HttpConversionUtil", False, "toFullHttpRequest", "", "", "Argument[1].Element.MapKey", "ReturnValue", "taint", "manual"] - ["io.netty.handler.codec.http2", "HttpConversionUtil", False, "toFullHttpRequest", "", "", "Argument[1].Element.MapValue", "ReturnValue", "taint", "manual"] - - ["io.netty.handler.codec.http2", "HttpConversionUtil", False, "toFullHttpRequest", "(int,HttpHeaders,ByteBuf,boolean)", "", "Argument[2]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http2", "HttpConversionUtil", False, "toFullHttpRequest", "(int,Http2Headers,ByteBuf,boolean)", "", "Argument[2]", "ReturnValue", "taint", "manual"] - ["io.netty.handler.codec.http2", "HttpConversionUtil", False, "toFullHttpResponse", "", "", "Argument[1].Element.MapKey", "ReturnValue", "taint", "manual"] - ["io.netty.handler.codec.http2", "HttpConversionUtil", False, "toFullHttpResponse", "", "", "Argument[1].Element.MapValue", "ReturnValue", "taint", "manual"] - - ["io.netty.handler.codec.http2", "HttpConversionUtil", False, "toFullHttpResponse", "(int,HttpHeaders,ByteBuf,boolean)", "", "Argument[2]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http2", "HttpConversionUtil", False, "toFullHttpResponse", "(int,Http2Headers,ByteBuf,boolean)", "", "Argument[2]", "ReturnValue", "taint", "manual"] - ["io.netty.handler.codec.http2", "HttpConversionUtil", False, "toHttp2Headers", "(HttpHeaders,boolean)", "", "Argument[0].Element.MapKey", "ReturnValue.Element.MapKey", "taint", "manual"] - ["io.netty.handler.codec.http2", "HttpConversionUtil", False, "toHttp2Headers", "(HttpHeaders,boolean)", "", "Argument[0].Element.MapValue", "ReturnValue.Element.MapValue", "taint", "manual"] - ["io.netty.handler.codec.http2", "HttpConversionUtil", False, "toHttp2Headers", "(HttpHeaders,Http2Headers)", "", "Argument[0].Element.MapKey", "Argument[1].Element.MapKey", "taint", "manual"] diff --git a/java/ql/test/library-tests/frameworks/netty/generated/Test.java b/java/ql/test/library-tests/frameworks/netty/generated/Test.java index 9463d4c4fe1..ab38ecbe53c 100644 --- a/java/ql/test/library-tests/frameworks/netty/generated/Test.java +++ b/java/ql/test/library-tests/frameworks/netty/generated/Test.java @@ -34,6 +34,7 @@ import io.netty.handler.codec.http.QueryStringDecoder; import io.netty.handler.codec.http.cookie.Cookie; import io.netty.handler.codec.http.cookie.DefaultCookie; import io.netty.handler.codec.http.cookie.ServerCookieDecoder; +import io.netty.handler.codec.http.cookie.ServerCookieEncoder; import io.netty.handler.codec.http.multipart.Attribute; import io.netty.handler.codec.http.multipart.FileUpload; import io.netty.handler.codec.http.multipart.HttpData; @@ -42,9 +43,13 @@ import io.netty.handler.codec.http.multipart.HttpPostRequestDecoder; import io.netty.handler.codec.http.multipart.HttpPostStandardRequestDecoder; import io.netty.handler.codec.http.multipart.InterfaceHttpData; import io.netty.handler.codec.http.multipart.InterfaceHttpPostRequestDecoder; +import io.netty.handler.codec.http.websocketx.BinaryWebSocketFrame; import io.netty.handler.codec.http.websocketx.CloseWebSocketFrame; import io.netty.handler.codec.http.websocketx.ContinuationWebSocketFrame; +import io.netty.handler.codec.http.websocketx.PingWebSocketFrame; +import io.netty.handler.codec.http.websocketx.PongWebSocketFrame; import io.netty.handler.codec.http.websocketx.TextWebSocketFrame; +import io.netty.handler.codec.http.websocketx.WebSocketCloseStatus; import io.netty.handler.codec.http.websocketx.WebSocketFrame; import io.netty.handler.codec.http2.Http2Headers; import io.netty.handler.codec.http2.Http2HeadersFrame; @@ -62,6 +67,7 @@ import java.nio.channels.FileChannel; import java.nio.channels.GatheringByteChannel; import java.nio.channels.ScatteringByteChannel; import java.nio.charset.Charset; +import java.util.Collection; import java.util.Iterator; import java.util.List; import java.util.Map; @@ -70,6 +76,14 @@ import java.util.Set; // Test case generated by GenerateFlowTestCase.ql public class Test { + <T> T getElement(Iterable<T> it) { return it.iterator().next(); } + <T> T getElement(Iterator<T> it) { return it.next(); } + Object getElementDefault(Object container) { return null; } + Object getMapKeyDefault(Object container) { return null; } + Object getMapValueDefault(Object container) { return null; } + Object newWithElementDefault(Object element) { return null; } + Object newWithMapKeyDefault(Object element) { return null; } + Object newWithMapValueDefault(Object element) { return null; } Object source() { return null; } void sink(Object o) { } @@ -663,6 +677,27 @@ public class Test { out = in.getBytes(0, (byte[])null, 0, 0); sink(out); // $ hasValueFlow } + { + // "io.netty.buffer;ByteBuf;true;getChar;;;Argument[-1];ReturnValue;taint;manual" + char out = 'a'; + AbstractByteBuf in = (AbstractByteBuf)source(); + out = in.getChar(0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;getChar;;;Argument[-1];ReturnValue;taint;manual" + char out = 'a'; + ByteBuf in = (ByteBuf)source(); + out = in.getChar(0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;getChar;;;Argument[-1];ReturnValue;taint;manual" + char out = 'a'; + SwappedByteBuf in = (SwappedByteBuf)source(); + out = in.getChar(0); + sink(out); // $ hasTaintFlow + } { // "io.netty.buffer;ByteBuf;true;getCharSequence;;;Argument[-1];ReturnValue;taint;manual" CharSequence out = null; @@ -1118,6 +1153,34 @@ public class Test { in.readBytes(out, 0); sink(out); // $ hasTaintFlow } + { + // "io.netty.buffer;ByteBuf;true;readBytes;(OutputStream,int);;Argument[-1];Argument[0];taint;manual" + OutputStream out = null; + AbstractByteBuf in = (AbstractByteBuf)source(); + in.readBytes(out, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;readBytes;(OutputStream,int);;Argument[-1];Argument[0];taint;manual" + OutputStream out = null; + ByteBuf in = (ByteBuf)source(); + in.readBytes(out, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;readBytes;(OutputStream,int);;Argument[-1];Argument[0];taint;manual" + OutputStream out = null; + CompositeByteBuf in = (CompositeByteBuf)source(); + in.readBytes(out, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;readBytes;(OutputStream,int);;Argument[-1];Argument[0];taint;manual" + OutputStream out = null; + SwappedByteBuf in = (SwappedByteBuf)source(); + in.readBytes(out, 0); + sink(out); // $ hasTaintFlow + } { // "io.netty.buffer;ByteBuf;true;readBytes;(OutputStream,int);;Argument[-1];ReturnValue;value;manual" ByteBuf out = null; @@ -1279,6 +1342,27 @@ public class Test { out = in.readBytes(0); sink(out); // $ hasTaintFlow } + { + // "io.netty.buffer;ByteBuf;true;readChar;;;Argument[-1];ReturnValue;taint;manual" + char out = 'a'; + AbstractByteBuf in = (AbstractByteBuf)source(); + out = in.readChar(); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;readChar;;;Argument[-1];ReturnValue;taint;manual" + char out = 'a'; + ByteBuf in = (ByteBuf)source(); + out = in.readChar(); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;readChar;;;Argument[-1];ReturnValue;taint;manual" + char out = 'a'; + SwappedByteBuf in = (SwappedByteBuf)source(); + out = in.readChar(); + sink(out); // $ hasTaintFlow + } { // "io.netty.buffer;ByteBuf;true;readCharSequence;;;Argument[-1];ReturnValue;taint;manual" CharSequence out = null; @@ -1301,21 +1385,42 @@ public class Test { sink(out); // $ hasTaintFlow } { - // "io.netty.buffer;ByteBuf;true;readSlice;;;Argument[-1];ReturnValue;taint;manual" + // "io.netty.buffer;ByteBuf;true;readRetainedSlice;(int);;Argument[-1];ReturnValue;taint;manual" + ByteBuf out = null; + AbstractByteBuf in = (AbstractByteBuf)source(); + out = in.readRetainedSlice(0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;readRetainedSlice;(int);;Argument[-1];ReturnValue;taint;manual" + ByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out = in.readRetainedSlice(0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;readRetainedSlice;(int);;Argument[-1];ReturnValue;taint;manual" + ByteBuf out = null; + SwappedByteBuf in = (SwappedByteBuf)source(); + out = in.readRetainedSlice(0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;readSlice;(int);;Argument[-1];ReturnValue;taint;manual" ByteBuf out = null; AbstractByteBuf in = (AbstractByteBuf)source(); out = in.readSlice(0); sink(out); // $ hasTaintFlow } { - // "io.netty.buffer;ByteBuf;true;readSlice;;;Argument[-1];ReturnValue;taint;manual" + // "io.netty.buffer;ByteBuf;true;readSlice;(int);;Argument[-1];ReturnValue;taint;manual" ByteBuf out = null; ByteBuf in = (ByteBuf)source(); out = in.readSlice(0); sink(out); // $ hasTaintFlow } { - // "io.netty.buffer;ByteBuf;true;readSlice;;;Argument[-1];ReturnValue;taint;manual" + // "io.netty.buffer;ByteBuf;true;readSlice;(int);;Argument[-1];ReturnValue;taint;manual" ByteBuf out = null; SwappedByteBuf in = (SwappedByteBuf)source(); out = in.readSlice(0); @@ -1909,6 +2014,34 @@ public class Test { out = in.setChar(0, 0); sink(out); // $ hasValueFlow } + { + // "io.netty.buffer;ByteBuf;true;setChar;;;Argument[1];Argument[-1];taint;manual" + AbstractByteBuf out = null; + int in = (int)source(); + out.setChar(0, in); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;setChar;;;Argument[1];Argument[-1];taint;manual" + ByteBuf out = null; + int in = (int)source(); + out.setChar(0, in); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;setChar;;;Argument[1];Argument[-1];taint;manual" + CompositeByteBuf out = null; + int in = (int)source(); + out.setChar(0, in); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBuf;true;setChar;;;Argument[1];Argument[-1];taint;manual" + SwappedByteBuf out = null; + int in = (int)source(); + out.setChar(0, in); + sink(out); // $ hasTaintFlow + } { // "io.netty.buffer;ByteBuf;true;setCharSequence;;;Argument[1];Argument[-1];taint;manual" AbstractByteBuf out = null; @@ -2413,6 +2546,34 @@ public class Test { out = in.unwrap(); sink(out); // $ hasTaintFlow } + { + // "io.netty.buffer;ByteBuf;true;writeBoolean;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + AbstractByteBuf in = (AbstractByteBuf)source(); + out = in.writeBoolean(false); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeBoolean;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out = in.writeBoolean(false); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeBoolean;;;Argument[-1];ReturnValue;value;manual" + ByteBuf out = null; + SwappedByteBuf in = (SwappedByteBuf)source(); + out = in.writeBoolean(false); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBuf;true;writeBoolean;;;Argument[-1];ReturnValue;value;manual" + CompositeByteBuf out = null; + CompositeByteBuf in = (CompositeByteBuf)source(); + out = in.writeBoolean(false); + sink(out); // $ hasValueFlow + } { // "io.netty.buffer;ByteBuf;true;writeByte;;;Argument[-1];ReturnValue;value;manual" ByteBuf out = null; @@ -3282,308 +3443,507 @@ public class Test { sink(out); // $ hasTaintFlow } { - // "io.netty.buffer;ByteBufHolder;true;content;;;Argument[-1];ReturnValue;taint;manual" + // "io.netty.buffer;ByteBufHolder;true;content;();;Argument[-1];ReturnValue;taint;manual" ByteBuf out = null; ByteBufHolder in = (ByteBufHolder)source(); out = in.content(); sink(out); // $ hasTaintFlow } { - // "io.netty.buffer;ByteBufHolder;true;content;;;Argument[-1];ReturnValue;taint;manual" + // "io.netty.buffer;ByteBufHolder;true;content;();;Argument[-1];ReturnValue;taint;manual" ByteBuf out = null; DefaultByteBufHolder in = (DefaultByteBufHolder)source(); out = in.content(); sink(out); // $ hasTaintFlow } { - // "io.netty.buffer;ByteBufHolder;true;copy;;;Argument[-1];ReturnValue;taint;manual" + // "io.netty.buffer;ByteBufHolder;true;copy;();;Argument[-1];ReturnValue;taint;manual" Attribute out = null; Attribute in = (Attribute)source(); out = in.copy(); sink(out); // $ hasTaintFlow } { - // "io.netty.buffer;ByteBufHolder;true;copy;;;Argument[-1];ReturnValue;taint;manual" + // "io.netty.buffer;ByteBufHolder;true;copy;();;Argument[-1];ReturnValue;taint;manual" + BinaryWebSocketFrame out = null; + BinaryWebSocketFrame in = (BinaryWebSocketFrame)source(); + out = in.copy(); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBufHolder;true;copy;();;Argument[-1];ReturnValue;taint;manual" ByteBufHolder out = null; ByteBufHolder in = (ByteBufHolder)source(); out = in.copy(); sink(out); // $ hasTaintFlow } { - // "io.netty.buffer;ByteBufHolder;true;copy;;;Argument[-1];ReturnValue;taint;manual" + // "io.netty.buffer;ByteBufHolder;true;copy;();;Argument[-1];ReturnValue;taint;manual" ByteBufHolder out = null; DefaultByteBufHolder in = (DefaultByteBufHolder)source(); out = in.copy(); sink(out); // $ hasTaintFlow } { - // "io.netty.buffer;ByteBufHolder;true;copy;;;Argument[-1];ReturnValue;taint;manual" + // "io.netty.buffer;ByteBufHolder;true;copy;();;Argument[-1];ReturnValue;taint;manual" CloseWebSocketFrame out = null; CloseWebSocketFrame in = (CloseWebSocketFrame)source(); out = in.copy(); sink(out); // $ hasTaintFlow } { - // "io.netty.buffer;ByteBufHolder;true;copy;;;Argument[-1];ReturnValue;taint;manual" + // "io.netty.buffer;ByteBufHolder;true;copy;();;Argument[-1];ReturnValue;taint;manual" ContinuationWebSocketFrame out = null; ContinuationWebSocketFrame in = (ContinuationWebSocketFrame)source(); out = in.copy(); sink(out); // $ hasTaintFlow } { - // "io.netty.buffer;ByteBufHolder;true;copy;;;Argument[-1];ReturnValue;taint;manual" + // "io.netty.buffer;ByteBufHolder;true;copy;();;Argument[-1];ReturnValue;taint;manual" FileUpload out = null; FileUpload in = (FileUpload)source(); out = in.copy(); sink(out); // $ hasTaintFlow } { - // "io.netty.buffer;ByteBufHolder;true;copy;;;Argument[-1];ReturnValue;taint;manual" + // "io.netty.buffer;ByteBufHolder;true;copy;();;Argument[-1];ReturnValue;taint;manual" FullHttpMessage out = null; FullHttpMessage in = (FullHttpMessage)source(); out = in.copy(); sink(out); // $ hasTaintFlow } { - // "io.netty.buffer;ByteBufHolder;true;copy;;;Argument[-1];ReturnValue;taint;manual" + // "io.netty.buffer;ByteBufHolder;true;copy;();;Argument[-1];ReturnValue;taint;manual" FullHttpRequest out = null; FullHttpRequest in = (FullHttpRequest)source(); out = in.copy(); sink(out); // $ hasTaintFlow } { - // "io.netty.buffer;ByteBufHolder;true;copy;;;Argument[-1];ReturnValue;taint;manual" + // "io.netty.buffer;ByteBufHolder;true;copy;();;Argument[-1];ReturnValue;taint;manual" FullHttpResponse out = null; FullHttpResponse in = (FullHttpResponse)source(); out = in.copy(); sink(out); // $ hasTaintFlow } { - // "io.netty.buffer;ByteBufHolder;true;copy;;;Argument[-1];ReturnValue;taint;manual" + // "io.netty.buffer;ByteBufHolder;true;copy;();;Argument[-1];ReturnValue;taint;manual" HttpContent out = null; HttpContent in = (HttpContent)source(); out = in.copy(); sink(out); // $ hasTaintFlow } { - // "io.netty.buffer;ByteBufHolder;true;copy;;;Argument[-1];ReturnValue;taint;manual" + // "io.netty.buffer;ByteBufHolder;true;copy;();;Argument[-1];ReturnValue;taint;manual" HttpData out = null; HttpData in = (HttpData)source(); out = in.copy(); sink(out); // $ hasTaintFlow } { - // "io.netty.buffer;ByteBufHolder;true;copy;;;Argument[-1];ReturnValue;taint;manual" + // "io.netty.buffer;ByteBufHolder;true;copy;();;Argument[-1];ReturnValue;taint;manual" LastHttpContent out = null; LastHttpContent in = (LastHttpContent)source(); out = in.copy(); sink(out); // $ hasTaintFlow } { - // "io.netty.buffer;ByteBufHolder;true;copy;;;Argument[-1];ReturnValue;taint;manual" + // "io.netty.buffer;ByteBufHolder;true;copy;();;Argument[-1];ReturnValue;taint;manual" + PingWebSocketFrame out = null; + PingWebSocketFrame in = (PingWebSocketFrame)source(); + out = in.copy(); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBufHolder;true;copy;();;Argument[-1];ReturnValue;taint;manual" + PongWebSocketFrame out = null; + PongWebSocketFrame in = (PongWebSocketFrame)source(); + out = in.copy(); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBufHolder;true;copy;();;Argument[-1];ReturnValue;taint;manual" TextWebSocketFrame out = null; TextWebSocketFrame in = (TextWebSocketFrame)source(); out = in.copy(); sink(out); // $ hasTaintFlow } { - // "io.netty.buffer;ByteBufHolder;true;copy;;;Argument[-1];ReturnValue;taint;manual" + // "io.netty.buffer;ByteBufHolder;true;copy;();;Argument[-1];ReturnValue;taint;manual" WebSocketFrame out = null; WebSocketFrame in = (WebSocketFrame)source(); out = in.copy(); sink(out); // $ hasTaintFlow } { - // "io.netty.buffer;ByteBufHolder;true;duplicate;;;Argument[-1];ReturnValue;taint;manual" + // "io.netty.buffer;ByteBufHolder;true;duplicate;();;Argument[-1];ReturnValue;taint;manual" Attribute out = null; Attribute in = (Attribute)source(); out = in.duplicate(); sink(out); // $ hasTaintFlow } { - // "io.netty.buffer;ByteBufHolder;true;duplicate;;;Argument[-1];ReturnValue;taint;manual" + // "io.netty.buffer;ByteBufHolder;true;duplicate;();;Argument[-1];ReturnValue;taint;manual" + BinaryWebSocketFrame out = null; + BinaryWebSocketFrame in = (BinaryWebSocketFrame)source(); + out = in.duplicate(); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBufHolder;true;duplicate;();;Argument[-1];ReturnValue;taint;manual" ByteBufHolder out = null; ByteBufHolder in = (ByteBufHolder)source(); out = in.duplicate(); sink(out); // $ hasTaintFlow } { - // "io.netty.buffer;ByteBufHolder;true;duplicate;;;Argument[-1];ReturnValue;taint;manual" + // "io.netty.buffer;ByteBufHolder;true;duplicate;();;Argument[-1];ReturnValue;taint;manual" ByteBufHolder out = null; DefaultByteBufHolder in = (DefaultByteBufHolder)source(); out = in.duplicate(); sink(out); // $ hasTaintFlow } { - // "io.netty.buffer;ByteBufHolder;true;duplicate;;;Argument[-1];ReturnValue;taint;manual" + // "io.netty.buffer;ByteBufHolder;true;duplicate;();;Argument[-1];ReturnValue;taint;manual" CloseWebSocketFrame out = null; CloseWebSocketFrame in = (CloseWebSocketFrame)source(); out = in.duplicate(); sink(out); // $ hasTaintFlow } { - // "io.netty.buffer;ByteBufHolder;true;duplicate;;;Argument[-1];ReturnValue;taint;manual" + // "io.netty.buffer;ByteBufHolder;true;duplicate;();;Argument[-1];ReturnValue;taint;manual" ContinuationWebSocketFrame out = null; ContinuationWebSocketFrame in = (ContinuationWebSocketFrame)source(); out = in.duplicate(); sink(out); // $ hasTaintFlow } { - // "io.netty.buffer;ByteBufHolder;true;duplicate;;;Argument[-1];ReturnValue;taint;manual" + // "io.netty.buffer;ByteBufHolder;true;duplicate;();;Argument[-1];ReturnValue;taint;manual" FileUpload out = null; FileUpload in = (FileUpload)source(); out = in.duplicate(); sink(out); // $ hasTaintFlow } { - // "io.netty.buffer;ByteBufHolder;true;duplicate;;;Argument[-1];ReturnValue;taint;manual" + // "io.netty.buffer;ByteBufHolder;true;duplicate;();;Argument[-1];ReturnValue;taint;manual" FullHttpMessage out = null; FullHttpMessage in = (FullHttpMessage)source(); out = in.duplicate(); sink(out); // $ hasTaintFlow } { - // "io.netty.buffer;ByteBufHolder;true;duplicate;;;Argument[-1];ReturnValue;taint;manual" + // "io.netty.buffer;ByteBufHolder;true;duplicate;();;Argument[-1];ReturnValue;taint;manual" FullHttpRequest out = null; FullHttpRequest in = (FullHttpRequest)source(); out = in.duplicate(); sink(out); // $ hasTaintFlow } { - // "io.netty.buffer;ByteBufHolder;true;duplicate;;;Argument[-1];ReturnValue;taint;manual" + // "io.netty.buffer;ByteBufHolder;true;duplicate;();;Argument[-1];ReturnValue;taint;manual" FullHttpResponse out = null; FullHttpResponse in = (FullHttpResponse)source(); out = in.duplicate(); sink(out); // $ hasTaintFlow } { - // "io.netty.buffer;ByteBufHolder;true;duplicate;;;Argument[-1];ReturnValue;taint;manual" + // "io.netty.buffer;ByteBufHolder;true;duplicate;();;Argument[-1];ReturnValue;taint;manual" HttpContent out = null; HttpContent in = (HttpContent)source(); out = in.duplicate(); sink(out); // $ hasTaintFlow } { - // "io.netty.buffer;ByteBufHolder;true;duplicate;;;Argument[-1];ReturnValue;taint;manual" + // "io.netty.buffer;ByteBufHolder;true;duplicate;();;Argument[-1];ReturnValue;taint;manual" HttpData out = null; HttpData in = (HttpData)source(); out = in.duplicate(); sink(out); // $ hasTaintFlow } { - // "io.netty.buffer;ByteBufHolder;true;duplicate;;;Argument[-1];ReturnValue;taint;manual" + // "io.netty.buffer;ByteBufHolder;true;duplicate;();;Argument[-1];ReturnValue;taint;manual" LastHttpContent out = null; LastHttpContent in = (LastHttpContent)source(); out = in.duplicate(); sink(out); // $ hasTaintFlow } { - // "io.netty.buffer;ByteBufHolder;true;duplicate;;;Argument[-1];ReturnValue;taint;manual" + // "io.netty.buffer;ByteBufHolder;true;duplicate;();;Argument[-1];ReturnValue;taint;manual" + PingWebSocketFrame out = null; + PingWebSocketFrame in = (PingWebSocketFrame)source(); + out = in.duplicate(); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBufHolder;true;duplicate;();;Argument[-1];ReturnValue;taint;manual" + PongWebSocketFrame out = null; + PongWebSocketFrame in = (PongWebSocketFrame)source(); + out = in.duplicate(); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBufHolder;true;duplicate;();;Argument[-1];ReturnValue;taint;manual" TextWebSocketFrame out = null; TextWebSocketFrame in = (TextWebSocketFrame)source(); out = in.duplicate(); sink(out); // $ hasTaintFlow } { - // "io.netty.buffer;ByteBufHolder;true;duplicate;;;Argument[-1];ReturnValue;taint;manual" + // "io.netty.buffer;ByteBufHolder;true;duplicate;();;Argument[-1];ReturnValue;taint;manual" WebSocketFrame out = null; WebSocketFrame in = (WebSocketFrame)source(); out = in.duplicate(); sink(out); // $ hasTaintFlow } { - // "io.netty.buffer;ByteBufHolder;true;retainedDuplicate;;;Argument[-1];ReturnValue;taint;manual" + // "io.netty.buffer;ByteBufHolder;true;replace;(ByteBuf);;Argument[0];ReturnValue;taint;manual" + Attribute out = null; + ByteBuf in = (ByteBuf)source(); + Attribute instance = null; + out = instance.replace(in); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBufHolder;true;replace;(ByteBuf);;Argument[0];ReturnValue;taint;manual" + BinaryWebSocketFrame out = null; + ByteBuf in = (ByteBuf)source(); + BinaryWebSocketFrame instance = null; + out = instance.replace(in); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBufHolder;true;replace;(ByteBuf);;Argument[0];ReturnValue;taint;manual" + ByteBufHolder out = null; + ByteBuf in = (ByteBuf)source(); + ByteBufHolder instance = null; + out = instance.replace(in); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBufHolder;true;replace;(ByteBuf);;Argument[0];ReturnValue;taint;manual" + ByteBufHolder out = null; + ByteBuf in = (ByteBuf)source(); + DefaultByteBufHolder instance = null; + out = instance.replace(in); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBufHolder;true;replace;(ByteBuf);;Argument[0];ReturnValue;taint;manual" + CloseWebSocketFrame out = null; + ByteBuf in = (ByteBuf)source(); + CloseWebSocketFrame instance = null; + out = instance.replace(in); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBufHolder;true;replace;(ByteBuf);;Argument[0];ReturnValue;taint;manual" + ContinuationWebSocketFrame out = null; + ByteBuf in = (ByteBuf)source(); + ContinuationWebSocketFrame instance = null; + out = instance.replace(in); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBufHolder;true;replace;(ByteBuf);;Argument[0];ReturnValue;taint;manual" + FileUpload out = null; + ByteBuf in = (ByteBuf)source(); + FileUpload instance = null; + out = instance.replace(in); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBufHolder;true;replace;(ByteBuf);;Argument[0];ReturnValue;taint;manual" + FullHttpMessage out = null; + ByteBuf in = (ByteBuf)source(); + FullHttpMessage instance = null; + out = instance.replace(in); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBufHolder;true;replace;(ByteBuf);;Argument[0];ReturnValue;taint;manual" + FullHttpRequest out = null; + ByteBuf in = (ByteBuf)source(); + FullHttpRequest instance = null; + out = instance.replace(in); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBufHolder;true;replace;(ByteBuf);;Argument[0];ReturnValue;taint;manual" + FullHttpResponse out = null; + ByteBuf in = (ByteBuf)source(); + FullHttpResponse instance = null; + out = instance.replace(in); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBufHolder;true;replace;(ByteBuf);;Argument[0];ReturnValue;taint;manual" + HttpContent out = null; + ByteBuf in = (ByteBuf)source(); + HttpContent instance = null; + out = instance.replace(in); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBufHolder;true;replace;(ByteBuf);;Argument[0];ReturnValue;taint;manual" + HttpData out = null; + ByteBuf in = (ByteBuf)source(); + HttpData instance = null; + out = instance.replace(in); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBufHolder;true;replace;(ByteBuf);;Argument[0];ReturnValue;taint;manual" + LastHttpContent out = null; + ByteBuf in = (ByteBuf)source(); + LastHttpContent instance = null; + out = instance.replace(in); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBufHolder;true;replace;(ByteBuf);;Argument[0];ReturnValue;taint;manual" + PingWebSocketFrame out = null; + ByteBuf in = (ByteBuf)source(); + PingWebSocketFrame instance = null; + out = instance.replace(in); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBufHolder;true;replace;(ByteBuf);;Argument[0];ReturnValue;taint;manual" + PongWebSocketFrame out = null; + ByteBuf in = (ByteBuf)source(); + PongWebSocketFrame instance = null; + out = instance.replace(in); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBufHolder;true;replace;(ByteBuf);;Argument[0];ReturnValue;taint;manual" + TextWebSocketFrame out = null; + ByteBuf in = (ByteBuf)source(); + TextWebSocketFrame instance = null; + out = instance.replace(in); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBufHolder;true;replace;(ByteBuf);;Argument[0];ReturnValue;taint;manual" + WebSocketFrame out = null; + ByteBuf in = (ByteBuf)source(); + WebSocketFrame instance = null; + out = instance.replace(in); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBufHolder;true;retainedDuplicate;();;Argument[-1];ReturnValue;taint;manual" Attribute out = null; Attribute in = (Attribute)source(); out = in.retainedDuplicate(); sink(out); // $ hasTaintFlow } { - // "io.netty.buffer;ByteBufHolder;true;retainedDuplicate;;;Argument[-1];ReturnValue;taint;manual" + // "io.netty.buffer;ByteBufHolder;true;retainedDuplicate;();;Argument[-1];ReturnValue;taint;manual" + BinaryWebSocketFrame out = null; + BinaryWebSocketFrame in = (BinaryWebSocketFrame)source(); + out = in.retainedDuplicate(); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBufHolder;true;retainedDuplicate;();;Argument[-1];ReturnValue;taint;manual" ByteBufHolder out = null; ByteBufHolder in = (ByteBufHolder)source(); out = in.retainedDuplicate(); sink(out); // $ hasTaintFlow } { - // "io.netty.buffer;ByteBufHolder;true;retainedDuplicate;;;Argument[-1];ReturnValue;taint;manual" + // "io.netty.buffer;ByteBufHolder;true;retainedDuplicate;();;Argument[-1];ReturnValue;taint;manual" ByteBufHolder out = null; DefaultByteBufHolder in = (DefaultByteBufHolder)source(); out = in.retainedDuplicate(); sink(out); // $ hasTaintFlow } { - // "io.netty.buffer;ByteBufHolder;true;retainedDuplicate;;;Argument[-1];ReturnValue;taint;manual" + // "io.netty.buffer;ByteBufHolder;true;retainedDuplicate;();;Argument[-1];ReturnValue;taint;manual" CloseWebSocketFrame out = null; CloseWebSocketFrame in = (CloseWebSocketFrame)source(); out = in.retainedDuplicate(); sink(out); // $ hasTaintFlow } { - // "io.netty.buffer;ByteBufHolder;true;retainedDuplicate;;;Argument[-1];ReturnValue;taint;manual" + // "io.netty.buffer;ByteBufHolder;true;retainedDuplicate;();;Argument[-1];ReturnValue;taint;manual" ContinuationWebSocketFrame out = null; ContinuationWebSocketFrame in = (ContinuationWebSocketFrame)source(); out = in.retainedDuplicate(); sink(out); // $ hasTaintFlow } { - // "io.netty.buffer;ByteBufHolder;true;retainedDuplicate;;;Argument[-1];ReturnValue;taint;manual" + // "io.netty.buffer;ByteBufHolder;true;retainedDuplicate;();;Argument[-1];ReturnValue;taint;manual" FileUpload out = null; FileUpload in = (FileUpload)source(); out = in.retainedDuplicate(); sink(out); // $ hasTaintFlow } { - // "io.netty.buffer;ByteBufHolder;true;retainedDuplicate;;;Argument[-1];ReturnValue;taint;manual" + // "io.netty.buffer;ByteBufHolder;true;retainedDuplicate;();;Argument[-1];ReturnValue;taint;manual" FullHttpMessage out = null; FullHttpMessage in = (FullHttpMessage)source(); out = in.retainedDuplicate(); sink(out); // $ hasTaintFlow } { - // "io.netty.buffer;ByteBufHolder;true;retainedDuplicate;;;Argument[-1];ReturnValue;taint;manual" + // "io.netty.buffer;ByteBufHolder;true;retainedDuplicate;();;Argument[-1];ReturnValue;taint;manual" FullHttpRequest out = null; FullHttpRequest in = (FullHttpRequest)source(); out = in.retainedDuplicate(); sink(out); // $ hasTaintFlow } { - // "io.netty.buffer;ByteBufHolder;true;retainedDuplicate;;;Argument[-1];ReturnValue;taint;manual" + // "io.netty.buffer;ByteBufHolder;true;retainedDuplicate;();;Argument[-1];ReturnValue;taint;manual" FullHttpResponse out = null; FullHttpResponse in = (FullHttpResponse)source(); out = in.retainedDuplicate(); sink(out); // $ hasTaintFlow } { - // "io.netty.buffer;ByteBufHolder;true;retainedDuplicate;;;Argument[-1];ReturnValue;taint;manual" + // "io.netty.buffer;ByteBufHolder;true;retainedDuplicate;();;Argument[-1];ReturnValue;taint;manual" HttpContent out = null; HttpContent in = (HttpContent)source(); out = in.retainedDuplicate(); sink(out); // $ hasTaintFlow } { - // "io.netty.buffer;ByteBufHolder;true;retainedDuplicate;;;Argument[-1];ReturnValue;taint;manual" + // "io.netty.buffer;ByteBufHolder;true;retainedDuplicate;();;Argument[-1];ReturnValue;taint;manual" HttpData out = null; HttpData in = (HttpData)source(); out = in.retainedDuplicate(); sink(out); // $ hasTaintFlow } { - // "io.netty.buffer;ByteBufHolder;true;retainedDuplicate;;;Argument[-1];ReturnValue;taint;manual" + // "io.netty.buffer;ByteBufHolder;true;retainedDuplicate;();;Argument[-1];ReturnValue;taint;manual" LastHttpContent out = null; LastHttpContent in = (LastHttpContent)source(); out = in.retainedDuplicate(); sink(out); // $ hasTaintFlow } { - // "io.netty.buffer;ByteBufHolder;true;retainedDuplicate;;;Argument[-1];ReturnValue;taint;manual" + // "io.netty.buffer;ByteBufHolder;true;retainedDuplicate;();;Argument[-1];ReturnValue;taint;manual" + PingWebSocketFrame out = null; + PingWebSocketFrame in = (PingWebSocketFrame)source(); + out = in.retainedDuplicate(); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBufHolder;true;retainedDuplicate;();;Argument[-1];ReturnValue;taint;manual" + PongWebSocketFrame out = null; + PongWebSocketFrame in = (PongWebSocketFrame)source(); + out = in.retainedDuplicate(); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.buffer;ByteBufHolder;true;retainedDuplicate;();;Argument[-1];ReturnValue;taint;manual" TextWebSocketFrame out = null; TextWebSocketFrame in = (TextWebSocketFrame)source(); out = in.retainedDuplicate(); sink(out); // $ hasTaintFlow } { - // "io.netty.buffer;ByteBufHolder;true;retainedDuplicate;;;Argument[-1];ReturnValue;taint;manual" + // "io.netty.buffer;ByteBufHolder;true;retainedDuplicate;();;Argument[-1];ReturnValue;taint;manual" WebSocketFrame out = null; WebSocketFrame in = (WebSocketFrame)source(); out = in.retainedDuplicate(); @@ -3729,6 +4089,13 @@ public class Test { ByteBufUtil.reserveAndWriteUtf8(out, in, 0, 0, 0); sink(out); // $ hasTaintFlow } + { + // "io.netty.buffer;ByteBufUtil;false;setShortBE;(ByteBuf,int,int);;Argument[0];ReturnValue;value;manual" + ByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out = ByteBufUtil.setShortBE(in, 0, 0); + sink(out); // $ hasValueFlow + } { // "io.netty.buffer;ByteBufUtil;false;writeAscii;(ByteBuf,CharSequence);;Argument[1];Argument[0];taint;manual" ByteBuf out = null; @@ -3743,6 +4110,20 @@ public class Test { out = ByteBufUtil.writeAscii((ByteBufAllocator)null, in); sink(out); // $ hasTaintFlow } + { + // "io.netty.buffer;ByteBufUtil;false;writeMediumBE;(ByteBuf,int);;Argument[0];ReturnValue;value;manual" + ByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out = ByteBufUtil.writeMediumBE(in, 0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;ByteBufUtil;false;writeShortBE;(ByteBuf,int);;Argument[0];ReturnValue;value;manual" + ByteBuf out = null; + ByteBuf in = (ByteBuf)source(); + out = ByteBufUtil.writeShortBE(in, 0); + sink(out); // $ hasValueFlow + } { // "io.netty.buffer;ByteBufUtil;false;writeUtf8;(ByteBuf,CharSequence);;Argument[1];Argument[0];taint;manual" ByteBuf out = null; @@ -3806,6 +4187,34 @@ public class Test { out.addComponent(0, in); sink(out); // $ hasTaintFlow } + { + // "io.netty.buffer;CompositeByteBuf;true;addComponent;;;Argument[-1];ReturnValue;value;manual" + CompositeByteBuf out = null; + CompositeByteBuf in = (CompositeByteBuf)source(); + out = in.addComponent(0, (ByteBuf)null); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;CompositeByteBuf;true;addComponent;;;Argument[-1];ReturnValue;value;manual" + CompositeByteBuf out = null; + CompositeByteBuf in = (CompositeByteBuf)source(); + out = in.addComponent(false, (ByteBuf)null); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;CompositeByteBuf;true;addComponent;;;Argument[-1];ReturnValue;value;manual" + CompositeByteBuf out = null; + CompositeByteBuf in = (CompositeByteBuf)source(); + out = in.addComponent(false, 0, null); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;CompositeByteBuf;true;addComponent;;;Argument[-1];ReturnValue;value;manual" + CompositeByteBuf out = null; + CompositeByteBuf in = (CompositeByteBuf)source(); + out = in.addComponent(null); + sink(out); // $ hasValueFlow + } { // "io.netty.buffer;CompositeByteBuf;true;addComponents;(ByteBuf[]);;Argument[0].ArrayElement;Argument[-1];taint;manual" CompositeByteBuf out = null; @@ -3848,6 +4257,48 @@ public class Test { out.addComponents(0, in); sink(out); // $ hasTaintFlow } + { + // "io.netty.buffer;CompositeByteBuf;true;addComponents;;;Argument[-1];ReturnValue;value;manual" + CompositeByteBuf out = null; + CompositeByteBuf in = (CompositeByteBuf)source(); + out = in.addComponents((ByteBuf[])null); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;CompositeByteBuf;true;addComponents;;;Argument[-1];ReturnValue;value;manual" + CompositeByteBuf out = null; + CompositeByteBuf in = (CompositeByteBuf)source(); + out = in.addComponents((Iterable)null); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;CompositeByteBuf;true;addComponents;;;Argument[-1];ReturnValue;value;manual" + CompositeByteBuf out = null; + CompositeByteBuf in = (CompositeByteBuf)source(); + out = in.addComponents(0, (ByteBuf[])null); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;CompositeByteBuf;true;addComponents;;;Argument[-1];ReturnValue;value;manual" + CompositeByteBuf out = null; + CompositeByteBuf in = (CompositeByteBuf)source(); + out = in.addComponents(0, (Iterable)null); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;CompositeByteBuf;true;addComponents;;;Argument[-1];ReturnValue;value;manual" + CompositeByteBuf out = null; + CompositeByteBuf in = (CompositeByteBuf)source(); + out = in.addComponents(false, (ByteBuf[])null); + sink(out); // $ hasValueFlow + } + { + // "io.netty.buffer;CompositeByteBuf;true;addComponents;;;Argument[-1];ReturnValue;value;manual" + CompositeByteBuf out = null; + CompositeByteBuf in = (CompositeByteBuf)source(); + out = in.addComponents(false, (Iterable)null); + sink(out); // $ hasValueFlow + } { // "io.netty.buffer;CompositeByteBuf;true;addFlattenedComponents;(boolean,ByteBuf);;Argument[1];Argument[-1];taint;manual" CompositeByteBuf out = null; @@ -3855,6 +4306,13 @@ public class Test { out.addFlattenedComponents(false, in); sink(out); // $ hasTaintFlow } + { + // "io.netty.buffer;CompositeByteBuf;true;addFlattenedComponents;;;Argument[-1];ReturnValue;value;manual" + CompositeByteBuf out = null; + CompositeByteBuf in = (CompositeByteBuf)source(); + out = in.addFlattenedComponents(false, null); + sink(out); // $ hasValueFlow + } { // "io.netty.buffer;CompositeByteBuf;true;component;(int);;Argument[-1];ReturnValue;taint;manual" ByteBuf out = null; @@ -3883,6 +4341,13 @@ public class Test { out = in.consolidate(0, 0); sink(out); // $ hasTaintFlow } + { + // "io.netty.buffer;CompositeByteBuf;true;decompose;(int,int);;Argument[-1];ReturnValue.Element;taint;manual" + List out = null; + CompositeByteBuf in = (CompositeByteBuf)source(); + out = in.decompose(0, 0); + sink(getElement(out)); // $ hasTaintFlow + } { // "io.netty.buffer;Unpooled;false;copiedBuffer;(ByteBuf);;Argument[0];ReturnValue;taint;manual" ByteBuf out = null; @@ -4198,6 +4663,48 @@ public class Test { out = in.path(); sink(out); // $ hasTaintFlow } + { + // "io.netty.handler.codec.http.cookie;Cookie;true;setDomain;(String);;Argument[0];Argument[-1];taint;manual" + Cookie out = null; + String in = (String)source(); + out.setDomain(in); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.http.cookie;Cookie;true;setDomain;(String);;Argument[0];Argument[-1];taint;manual" + DefaultCookie out = null; + String in = (String)source(); + out.setDomain(in); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.http.cookie;Cookie;true;setPath;(String);;Argument[0];Argument[-1];taint;manual" + Cookie out = null; + String in = (String)source(); + out.setPath(in); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.http.cookie;Cookie;true;setPath;(String);;Argument[0];Argument[-1];taint;manual" + DefaultCookie out = null; + String in = (String)source(); + out.setPath(in); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.http.cookie;Cookie;true;setValue;(String);;Argument[0];Argument[-1];taint;manual" + Cookie out = null; + String in = (String)source(); + out.setValue(in); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.http.cookie;Cookie;true;setValue;(String);;Argument[0];Argument[-1];taint;manual" + DefaultCookie out = null; + String in = (String)source(); + out.setValue(in); + sink(out); // $ hasTaintFlow + } { // "io.netty.handler.codec.http.cookie;Cookie;true;value;();;Argument[-1];ReturnValue;taint;manual" String out = null; @@ -4213,17 +4720,59 @@ public class Test { sink(out); // $ hasTaintFlow } { - // "io.netty.handler.codec.http.cookie;ServerCookieDecoder;true;decode;(String);;Argument[-1];ReturnValue;taint;manual" + // "io.netty.handler.codec.http.cookie;ServerCookieDecoder;true;decode;(String);;Argument[0];ReturnValue.Element;taint;manual" Set out = null; - ServerCookieDecoder in = (ServerCookieDecoder)source(); - out = in.decode(null); + String in = (String)source(); + ServerCookieDecoder instance = null; + out = instance.decode(in); + sink(getElement(out)); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.http.cookie;ServerCookieDecoder;true;decodeAll;(String);;Argument[0];ReturnValue.Element;taint;manual" + List out = null; + String in = (String)source(); + ServerCookieDecoder instance = null; + out = instance.decodeAll(in); + sink(getElement(out)); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.http.cookie;ServerCookieEncoder;true;encode;(Collection);;Argument[0].Element;ReturnValue.Element;taint;manual" + List out = null; + Collection in = (Collection)List.of(source()); + ServerCookieEncoder instance = null; + out = instance.encode(in); + sink(getElement(out)); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.http.cookie;ServerCookieEncoder;true;encode;(Cookie);;Argument[0];ReturnValue;taint;manual" + String out = null; + Cookie in = (Cookie)source(); + ServerCookieEncoder instance = null; + out = instance.encode(in); sink(out); // $ hasTaintFlow } { - // "io.netty.handler.codec.http.cookie;ServerCookieDecoder;true;decodeAll;(String);;Argument[-1];ReturnValue;taint;manual" + // "io.netty.handler.codec.http.cookie;ServerCookieEncoder;true;encode;(Cookie[]);;Argument[0].ArrayElement;ReturnValue.Element;taint;manual" List out = null; - ServerCookieDecoder in = (ServerCookieDecoder)source(); - out = in.decodeAll(null); + Cookie[] in = (Cookie[])new Cookie[]{(Cookie)source()}; + ServerCookieEncoder instance = null; + out = instance.encode(in); + sink(getElement(out)); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.http.cookie;ServerCookieEncoder;true;encode;(Iterable);;Argument[0].Element;ReturnValue.Element;taint;manual" + List out = null; + Iterable in = (Iterable)List.of(source()); + ServerCookieEncoder instance = null; + out = instance.encode(in); + sink(getElement(out)); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.http.cookie;ServerCookieEncoder;true;encode;(String,String);;Argument[1..2];ReturnValue;taint;manual" + String out = null; + String in = (String)source(); + ServerCookieEncoder instance = null; + out = instance.encode(null, in); sink(out); // $ hasTaintFlow } { @@ -4233,6 +4782,13 @@ public class Test { out = in.getValue(); sink(out); // $ hasTaintFlow } + { + // "io.netty.handler.codec.http.multipart;Attribute;true;setValue;(String);;Argument[0];Argument[-1];taint;manual" + Attribute out = null; + String in = (String)source(); + out.setValue(in); + sink(out); // $ hasTaintFlow + } { // "io.netty.handler.codec.http.multipart;FileUpload;true;getContentTransferEncoding;();;Argument[-1];ReturnValue;taint;manual" String out = null; @@ -4254,6 +4810,34 @@ public class Test { out = in.getFilename(); sink(out); // $ hasTaintFlow } + { + // "io.netty.handler.codec.http.multipart;FileUpload;true;setContentTransferEncoding;(String);;Argument[0];Argument[-1];taint;manual" + FileUpload out = null; + String in = (String)source(); + out.setContentTransferEncoding(in); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.http.multipart;FileUpload;true;setContentType;(String);;Argument[0];Argument[-1];taint;manual" + FileUpload out = null; + String in = (String)source(); + out.setContentType(in); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.http.multipart;FileUpload;true;setFilename;(String);;Argument[0];Argument[-1];taint;manual" + FileUpload out = null; + String in = (String)source(); + out.setFilename(in); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.http.multipart;HttpData;true;addContent;(ByteBuf,boolean);;Argument[0];Argument[-1];taint;manual" + HttpData out = null; + ByteBuf in = (ByteBuf)source(); + out.addContent(in, false); + sink(out); // $ hasTaintFlow + } { // "io.netty.handler.codec.http.multipart;HttpData;true;get;();;Argument[-1];ReturnValue;taint;manual" byte[] out = null; @@ -4289,6 +4873,20 @@ public class Test { out = in.getString(null); sink(out); // $ hasTaintFlow } + { + // "io.netty.handler.codec.http.multipart;HttpData;true;setContent;(ByteBuf);;Argument[0];Argument[-1];taint;manual" + HttpData out = null; + ByteBuf in = (ByteBuf)source(); + out.setContent(in); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.http.multipart;HttpData;true;setContent;(InputStream);;Argument[0];Argument[-1];taint;manual" + HttpData out = null; + InputStream in = (InputStream)source(); + out.setContent(in); + sink(out); // $ hasTaintFlow + } { // "io.netty.handler.codec.http.multipart;HttpPostMultipartRequestDecoder;true;HttpPostMultipartRequestDecoder;(HttpDataFactory,HttpRequest);;Argument[1];Argument[-1];taint;manual" HttpPostMultipartRequestDecoder out = null; @@ -4359,6 +4957,34 @@ public class Test { out = in.getName(); sink(out); // $ hasTaintFlow } + { + // "io.netty.handler.codec.http.multipart;InterfaceHttpPostRequestDecoder;true;currentPartialHttpData;();;Argument[-1];ReturnValue;taint;manual" + InterfaceHttpData out = null; + HttpPostMultipartRequestDecoder in = (HttpPostMultipartRequestDecoder)source(); + out = in.currentPartialHttpData(); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.http.multipart;InterfaceHttpPostRequestDecoder;true;currentPartialHttpData;();;Argument[-1];ReturnValue;taint;manual" + InterfaceHttpData out = null; + HttpPostRequestDecoder in = (HttpPostRequestDecoder)source(); + out = in.currentPartialHttpData(); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.http.multipart;InterfaceHttpPostRequestDecoder;true;currentPartialHttpData;();;Argument[-1];ReturnValue;taint;manual" + InterfaceHttpData out = null; + HttpPostStandardRequestDecoder in = (HttpPostStandardRequestDecoder)source(); + out = in.currentPartialHttpData(); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.http.multipart;InterfaceHttpPostRequestDecoder;true;currentPartialHttpData;();;Argument[-1];ReturnValue;taint;manual" + InterfaceHttpData out = null; + InterfaceHttpPostRequestDecoder in = (InterfaceHttpPostRequestDecoder)source(); + out = in.currentPartialHttpData(); + sink(out); // $ hasTaintFlow + } { // "io.netty.handler.codec.http.multipart;InterfaceHttpPostRequestDecoder;true;getBodyHttpData;(String);;Argument[-1];ReturnValue;taint;manual" InterfaceHttpData out = null; @@ -4471,6 +5097,34 @@ public class Test { out = in.next(); sink(out); // $ hasTaintFlow } + { + // "io.netty.handler.codec.http.multipart;InterfaceHttpPostRequestDecoder;true;offer;(HttpContent);;Argument[-1];ReturnValue;value;manual" + HttpPostMultipartRequestDecoder out = null; + HttpPostMultipartRequestDecoder in = (HttpPostMultipartRequestDecoder)source(); + out = in.offer(null); + sink(out); // $ hasValueFlow + } + { + // "io.netty.handler.codec.http.multipart;InterfaceHttpPostRequestDecoder;true;offer;(HttpContent);;Argument[-1];ReturnValue;value;manual" + HttpPostStandardRequestDecoder out = null; + HttpPostStandardRequestDecoder in = (HttpPostStandardRequestDecoder)source(); + out = in.offer(null); + sink(out); // $ hasValueFlow + } + { + // "io.netty.handler.codec.http.multipart;InterfaceHttpPostRequestDecoder;true;offer;(HttpContent);;Argument[-1];ReturnValue;value;manual" + InterfaceHttpPostRequestDecoder out = null; + HttpPostRequestDecoder in = (HttpPostRequestDecoder)source(); + out = in.offer(null); + sink(out); // $ hasValueFlow + } + { + // "io.netty.handler.codec.http.multipart;InterfaceHttpPostRequestDecoder;true;offer;(HttpContent);;Argument[-1];ReturnValue;value;manual" + InterfaceHttpPostRequestDecoder out = null; + InterfaceHttpPostRequestDecoder in = (InterfaceHttpPostRequestDecoder)source(); + out = in.offer(null); + sink(out); // $ hasValueFlow + } { // "io.netty.handler.codec.http.multipart;InterfaceHttpPostRequestDecoder;true;offer;(HttpContent);;Argument[0];Argument[-1];taint;manual" HttpPostMultipartRequestDecoder out = null; @@ -4499,6 +5153,48 @@ public class Test { out.offer(in); sink(out); // $ hasTaintFlow } + { + // "io.netty.handler.codec.http.websocketx;BinaryWebSocketFrame;true;BinaryWebSocketFrame;(ByteBuf);;Argument[0];Argument[-1];taint;manual" + BinaryWebSocketFrame out = null; + ByteBuf in = (ByteBuf)source(); + out = new BinaryWebSocketFrame(in); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.http.websocketx;BinaryWebSocketFrame;true;BinaryWebSocketFrame;(boolean,int,ByteBuf);;Argument[2];Argument[-1];taint;manual" + BinaryWebSocketFrame out = null; + ByteBuf in = (ByteBuf)source(); + out = new BinaryWebSocketFrame(false, 0, in); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.http.websocketx;CloseWebSocketFrame;true;CloseWebSocketFrame;(WebSocketCloseStatus,String);;Argument[1];Argument[-1];taint;manual" + CloseWebSocketFrame out = null; + String in = (String)source(); + out = new CloseWebSocketFrame((WebSocketCloseStatus)null, in); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.http.websocketx;CloseWebSocketFrame;true;CloseWebSocketFrame;(boolean,int,ByteBuf);;Argument[2];Argument[-1];taint;manual" + CloseWebSocketFrame out = null; + ByteBuf in = (ByteBuf)source(); + out = new CloseWebSocketFrame(false, 0, in); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.http.websocketx;CloseWebSocketFrame;true;CloseWebSocketFrame;(boolean,int,int,String);;Argument[3];Argument[-1];taint;manual" + CloseWebSocketFrame out = null; + String in = (String)source(); + out = new CloseWebSocketFrame(false, 0, 0, in); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.http.websocketx;CloseWebSocketFrame;true;CloseWebSocketFrame;(int,String);;Argument[1];Argument[-1];taint;manual" + CloseWebSocketFrame out = null; + String in = (String)source(); + out = new CloseWebSocketFrame(0, in); + sink(out); // $ hasTaintFlow + } { // "io.netty.handler.codec.http.websocketx;CloseWebSocketFrame;true;reasonText;();;Argument[-1];ReturnValue;taint;manual" String out = null; @@ -4506,6 +5202,27 @@ public class Test { out = in.reasonText(); sink(out); // $ hasTaintFlow } + { + // "io.netty.handler.codec.http.websocketx;ContinuationWebSocketFrame;true;ContinuationWebSocketFrame;(ByteBuf);;Argument[0];Argument[-1];taint;manual" + ContinuationWebSocketFrame out = null; + ByteBuf in = (ByteBuf)source(); + out = new ContinuationWebSocketFrame(in); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.http.websocketx;ContinuationWebSocketFrame;true;ContinuationWebSocketFrame;(boolean,int,ByteBuf);;Argument[2];Argument[-1];taint;manual" + ContinuationWebSocketFrame out = null; + ByteBuf in = (ByteBuf)source(); + out = new ContinuationWebSocketFrame(false, 0, in); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.http.websocketx;ContinuationWebSocketFrame;true;ContinuationWebSocketFrame;(boolean,int,String);;Argument[2];Argument[-1];taint;manual" + ContinuationWebSocketFrame out = null; + String in = (String)source(); + out = new ContinuationWebSocketFrame(false, 0, in); + sink(out); // $ hasTaintFlow + } { // "io.netty.handler.codec.http.websocketx;ContinuationWebSocketFrame;true;text;();;Argument[-1];ReturnValue;taint;manual" String out = null; @@ -4513,6 +5230,62 @@ public class Test { out = in.text(); sink(out); // $ hasTaintFlow } + { + // "io.netty.handler.codec.http.websocketx;PingWebSocketFrame;true;PingWebSocketFrame;(ByteBuf);;Argument[0];Argument[-1];taint;manual" + PingWebSocketFrame out = null; + ByteBuf in = (ByteBuf)source(); + out = new PingWebSocketFrame(in); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.http.websocketx;PingWebSocketFrame;true;PingWebSocketFrame;(boolean,int,ByteBuf);;Argument[2];Argument[-1];taint;manual" + PingWebSocketFrame out = null; + ByteBuf in = (ByteBuf)source(); + out = new PingWebSocketFrame(false, 0, in); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.http.websocketx;PongWebSocketFrame;true;PongWebSocketFrame;(ByteBuf);;Argument[0];Argument[-1];taint;manual" + PongWebSocketFrame out = null; + ByteBuf in = (ByteBuf)source(); + out = new PongWebSocketFrame(in); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.http.websocketx;PongWebSocketFrame;true;PongWebSocketFrame;(boolean,int,ByteBuf);;Argument[2];Argument[-1];taint;manual" + PongWebSocketFrame out = null; + ByteBuf in = (ByteBuf)source(); + out = new PongWebSocketFrame(false, 0, in); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.http.websocketx;TextWebSocketFrame;true;TextWebSocketFrame;(ByteBuf);;Argument[0];Argument[-1];taint;manual" + TextWebSocketFrame out = null; + ByteBuf in = (ByteBuf)source(); + out = new TextWebSocketFrame(in); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.http.websocketx;TextWebSocketFrame;true;TextWebSocketFrame;(String);;Argument[0];Argument[-1];taint;manual" + TextWebSocketFrame out = null; + String in = (String)source(); + out = new TextWebSocketFrame(in); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.http.websocketx;TextWebSocketFrame;true;TextWebSocketFrame;(boolean,int,ByteBuf);;Argument[2];Argument[-1];taint;manual" + TextWebSocketFrame out = null; + ByteBuf in = (ByteBuf)source(); + out = new TextWebSocketFrame(false, 0, in); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.http.websocketx;TextWebSocketFrame;true;TextWebSocketFrame;(boolean,int,String);;Argument[2];Argument[-1];taint;manual" + TextWebSocketFrame out = null; + String in = (String)source(); + out = new TextWebSocketFrame(false, 0, in); + sink(out); // $ hasTaintFlow + } { // "io.netty.handler.codec.http.websocketx;TextWebSocketFrame;true;text;();;Argument[-1];ReturnValue;taint;manual" String out = null; @@ -4521,53 +5294,116 @@ public class Test { sink(out); // $ hasTaintFlow } { - // "io.netty.handler.codec.http2;Http2Headers;true;authority;();;Argument[-1];ReturnValue;taint;manual" + // "io.netty.handler.codec.http2;Http2Headers;true;authority;();;Argument[-1].Element.MapValue;ReturnValue;value;manual" CharSequence out = null; - Http2Headers in = (Http2Headers)source(); + Http2Headers in = (Http2Headers)newWithElementDefault(newWithMapValueDefault(source())); out = in.authority(); - sink(out); // $ hasTaintFlow + sink(out); // $ hasValueFlow } { - // "io.netty.handler.codec.http2;Http2Headers;true;iterator;();;Argument[-1];ReturnValue;taint;manual" - Iterator out = null; + // "io.netty.handler.codec.http2;Http2Headers;true;authority;(CharSequence);;Argument[-1];ReturnValue;value;manual" + Http2Headers out = null; Http2Headers in = (Http2Headers)source(); - out = in.iterator(); - sink(out); // $ hasTaintFlow + out = in.authority(null); + sink(out); // $ hasValueFlow } { - // "io.netty.handler.codec.http2;Http2Headers;true;method;();;Argument[-1];ReturnValue;taint;manual" + // "io.netty.handler.codec.http2;Http2Headers;true;authority;(CharSequence);;Argument[0];Argument[-1].Element.MapValue;value;manual" + Http2Headers out = null; + CharSequence in = (CharSequence)source(); + out.authority(in); + sink(getMapValueDefault(getElement(out))); // $ hasValueFlow + } + { + // "io.netty.handler.codec.http2;Http2Headers;true;method;();;Argument[-1].Element.MapValue;ReturnValue;value;manual" CharSequence out = null; - Http2Headers in = (Http2Headers)source(); + Http2Headers in = (Http2Headers)newWithElementDefault(newWithMapValueDefault(source())); out = in.method(); - sink(out); // $ hasTaintFlow + sink(out); // $ hasValueFlow } { - // "io.netty.handler.codec.http2;Http2Headers;true;path;();;Argument[-1];ReturnValue;taint;manual" - CharSequence out = null; + // "io.netty.handler.codec.http2;Http2Headers;true;method;(CharSequence);;Argument[-1];ReturnValue;value;manual" + Http2Headers out = null; Http2Headers in = (Http2Headers)source(); + out = in.method(null); + sink(out); // $ hasValueFlow + } + { + // "io.netty.handler.codec.http2;Http2Headers;true;method;(CharSequence);;Argument[0];Argument[-1].Element.MapValue;value;manual" + Http2Headers out = null; + CharSequence in = (CharSequence)source(); + out.method(in); + sink(getMapValueDefault(getElement(out))); // $ hasValueFlow + } + { + // "io.netty.handler.codec.http2;Http2Headers;true;path;();;Argument[-1].Element.MapValue;ReturnValue;value;manual" + CharSequence out = null; + Http2Headers in = (Http2Headers)newWithElementDefault(newWithMapValueDefault(source())); out = in.path(); - sink(out); // $ hasTaintFlow + sink(out); // $ hasValueFlow } { - // "io.netty.handler.codec.http2;Http2Headers;true;scheme;();;Argument[-1];ReturnValue;taint;manual" - CharSequence out = null; + // "io.netty.handler.codec.http2;Http2Headers;true;path;(CharSequence);;Argument[-1];ReturnValue;value;manual" + Http2Headers out = null; Http2Headers in = (Http2Headers)source(); + out = in.path(null); + sink(out); // $ hasValueFlow + } + { + // "io.netty.handler.codec.http2;Http2Headers;true;path;(CharSequence);;Argument[0];Argument[-1].Element.MapValue;value;manual" + Http2Headers out = null; + CharSequence in = (CharSequence)source(); + out.path(in); + sink(getMapValueDefault(getElement(out))); // $ hasValueFlow + } + { + // "io.netty.handler.codec.http2;Http2Headers;true;scheme;();;Argument[-1].Element.MapValue;ReturnValue;value;manual" + CharSequence out = null; + Http2Headers in = (Http2Headers)newWithElementDefault(newWithMapValueDefault(source())); out = in.scheme(); - sink(out); // $ hasTaintFlow + sink(out); // $ hasValueFlow } { - // "io.netty.handler.codec.http2;Http2Headers;true;status;();;Argument[-1];ReturnValue;taint;manual" + // "io.netty.handler.codec.http2;Http2Headers;true;scheme;(CharSequence);;Argument[-1];ReturnValue;value;manual" + Http2Headers out = null; + Http2Headers in = (Http2Headers)source(); + out = in.scheme(null); + sink(out); // $ hasValueFlow + } + { + // "io.netty.handler.codec.http2;Http2Headers;true;scheme;(CharSequence);;Argument[0];Argument[-1].Element.MapValue;value;manual" + Http2Headers out = null; + CharSequence in = (CharSequence)source(); + out.scheme(in); + sink(getMapValueDefault(getElement(out))); // $ hasValueFlow + } + { + // "io.netty.handler.codec.http2;Http2Headers;true;status;();;Argument[-1].Element.MapValue;ReturnValue;value;manual" CharSequence out = null; - Http2Headers in = (Http2Headers)source(); + Http2Headers in = (Http2Headers)newWithElementDefault(newWithMapValueDefault(source())); out = in.status(); - sink(out); // $ hasTaintFlow + sink(out); // $ hasValueFlow } { - // "io.netty.handler.codec.http2;Http2Headers;true;valueIterator;(CharSequence);;Argument[-1];ReturnValue;taint;manual" - Iterator out = null; + // "io.netty.handler.codec.http2;Http2Headers;true;status;(CharSequence);;Argument[-1];ReturnValue;value;manual" + Http2Headers out = null; Http2Headers in = (Http2Headers)source(); + out = in.status(null); + sink(out); // $ hasValueFlow + } + { + // "io.netty.handler.codec.http2;Http2Headers;true;status;(CharSequence);;Argument[0];Argument[-1].Element.MapValue;value;manual" + Http2Headers out = null; + CharSequence in = (CharSequence)source(); + out.status(in); + sink(getMapValueDefault(getElement(out))); // $ hasValueFlow + } + { + // "io.netty.handler.codec.http2;Http2Headers;true;valueIterator;(CharSequence);;Argument[-1].Element.MapValue;ReturnValue.Element;value;manual" + Iterator out = null; + Http2Headers in = (Http2Headers)newWithElementDefault(newWithMapValueDefault(source())); out = in.valueIterator(null); - sink(out); // $ hasTaintFlow + sink(getElement(out)); // $ hasValueFlow } { // "io.netty.handler.codec.http2;Http2HeadersFrame;true;headers;();;Argument[-1];ReturnValue;taint;manual" @@ -4584,103 +5420,229 @@ public class Test { sink(out); // $ hasTaintFlow } { - // "io.netty.handler.codec.http2;HttpConversionUtil;false;addHttp2ToHttpHeaders;;;Argument[1];Argument[2];taint;manual" + // "io.netty.handler.codec.http2;HttpConversionUtil;false;addHttp2ToHttpHeaders;(int,Http2Headers,FullHttpMessage,boolean);;Argument[1].Element.MapKey;Argument[2];taint;manual" FullHttpMessage out = null; - Http2Headers in = (Http2Headers)source(); + Http2Headers in = (Http2Headers)newWithElementDefault(newWithMapKeyDefault(source())); HttpConversionUtil.addHttp2ToHttpHeaders(0, in, out, false); sink(out); // $ hasTaintFlow } { - // "io.netty.handler.codec.http2;HttpConversionUtil;false;addHttp2ToHttpHeaders;;;Argument[1];Argument[2];taint;manual" - HttpHeaders out = null; - Http2Headers in = (Http2Headers)source(); - HttpConversionUtil.addHttp2ToHttpHeaders(0, in, out, null, false, false); + // "io.netty.handler.codec.http2;HttpConversionUtil;false;addHttp2ToHttpHeaders;(int,Http2Headers,FullHttpMessage,boolean);;Argument[1].Element.MapValue;Argument[2];taint;manual" + FullHttpMessage out = null; + Http2Headers in = (Http2Headers)newWithElementDefault(newWithMapValueDefault(source())); + HttpConversionUtil.addHttp2ToHttpHeaders(0, in, out, false); sink(out); // $ hasTaintFlow } { - // "io.netty.handler.codec.http2;HttpConversionUtil;false;toFullHttpRequest;;;Argument[1];ReturnValue;taint;manual" + // "io.netty.handler.codec.http2;HttpConversionUtil;false;addHttp2ToHttpHeaders;(int,Http2Headers,HttpHeaders,HttpVersion,boolean,boolean);;Argument[1].Element.MapKey;Argument[2].Element.MapKey;taint;manual" + HttpHeaders out = null; + Http2Headers in = (Http2Headers)newWithElementDefault(newWithMapKeyDefault(source())); + HttpConversionUtil.addHttp2ToHttpHeaders(0, in, out, null, false, false); + sink(getMapKeyDefault(getElement(out))); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.http2;HttpConversionUtil;false;addHttp2ToHttpHeaders;(int,Http2Headers,HttpHeaders,HttpVersion,boolean,boolean);;Argument[1].Element.MapValue;Argument[2].Element.MapValue;taint;manual" + HttpHeaders out = null; + Http2Headers in = (Http2Headers)newWithElementDefault(newWithMapValueDefault(source())); + HttpConversionUtil.addHttp2ToHttpHeaders(0, in, out, null, false, false); + sink(getMapValueDefault(getElement(out))); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.http2;HttpConversionUtil;false;toFullHttpRequest;(int,Http2Headers,ByteBuf,boolean);;Argument[2];ReturnValue;taint;manual" FullHttpRequest out = null; - Http2Headers in = (Http2Headers)source(); + ByteBuf in = (ByteBuf)source(); + out = HttpConversionUtil.toFullHttpRequest(0, (Http2Headers)null, in, false); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.http2;HttpConversionUtil;false;toFullHttpRequest;;;Argument[1].Element.MapKey;ReturnValue;taint;manual" + FullHttpRequest out = null; + Http2Headers in = (Http2Headers)newWithElementDefault(newWithMapKeyDefault(source())); out = HttpConversionUtil.toFullHttpRequest(0, in, (ByteBuf)null, false); sink(out); // $ hasTaintFlow } { - // "io.netty.handler.codec.http2;HttpConversionUtil;false;toFullHttpRequest;;;Argument[1];ReturnValue;taint;manual" + // "io.netty.handler.codec.http2;HttpConversionUtil;false;toFullHttpRequest;;;Argument[1].Element.MapKey;ReturnValue;taint;manual" FullHttpRequest out = null; - Http2Headers in = (Http2Headers)source(); + Http2Headers in = (Http2Headers)newWithElementDefault(newWithMapKeyDefault(source())); out = HttpConversionUtil.toFullHttpRequest(0, in, (ByteBufAllocator)null, false); sink(out); // $ hasTaintFlow } { - // "io.netty.handler.codec.http2;HttpConversionUtil;false;toFullHttpRequest;;;Argument[2];ReturnValue;taint;manual" + // "io.netty.handler.codec.http2;HttpConversionUtil;false;toFullHttpRequest;;;Argument[1].Element.MapValue;ReturnValue;taint;manual" FullHttpRequest out = null; - ByteBuf in = (ByteBuf)source(); - out = HttpConversionUtil.toFullHttpRequest(0, (Http2Headers)null, in, false); + Http2Headers in = (Http2Headers)newWithElementDefault(newWithMapValueDefault(source())); + out = HttpConversionUtil.toFullHttpRequest(0, in, (ByteBuf)null, false); sink(out); // $ hasTaintFlow } { - // "io.netty.handler.codec.http2;HttpConversionUtil;false;toFullHttpRequest;;;Argument[2];ReturnValue;taint;manual" + // "io.netty.handler.codec.http2;HttpConversionUtil;false;toFullHttpRequest;;;Argument[1].Element.MapValue;ReturnValue;taint;manual" FullHttpRequest out = null; - ByteBufAllocator in = (ByteBufAllocator)source(); - out = HttpConversionUtil.toFullHttpRequest(0, (Http2Headers)null, in, false); + Http2Headers in = (Http2Headers)newWithElementDefault(newWithMapValueDefault(source())); + out = HttpConversionUtil.toFullHttpRequest(0, in, (ByteBufAllocator)null, false); sink(out); // $ hasTaintFlow } { - // "io.netty.handler.codec.http2;HttpConversionUtil;false;toFullHttpResponse;;;Argument[1];ReturnValue;taint;manual" + // "io.netty.handler.codec.http2;HttpConversionUtil;false;toFullHttpResponse;(int,Http2Headers,ByteBuf,boolean);;Argument[2];ReturnValue;taint;manual" FullHttpResponse out = null; - Http2Headers in = (Http2Headers)source(); + ByteBuf in = (ByteBuf)source(); + out = HttpConversionUtil.toFullHttpResponse(0, (Http2Headers)null, in, false); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.http2;HttpConversionUtil;false;toFullHttpResponse;;;Argument[1].Element.MapKey;ReturnValue;taint;manual" + FullHttpResponse out = null; + Http2Headers in = (Http2Headers)newWithElementDefault(newWithMapKeyDefault(source())); out = HttpConversionUtil.toFullHttpResponse(0, in, (ByteBuf)null, false); sink(out); // $ hasTaintFlow } { - // "io.netty.handler.codec.http2;HttpConversionUtil;false;toFullHttpResponse;;;Argument[1];ReturnValue;taint;manual" + // "io.netty.handler.codec.http2;HttpConversionUtil;false;toFullHttpResponse;;;Argument[1].Element.MapKey;ReturnValue;taint;manual" FullHttpResponse out = null; - Http2Headers in = (Http2Headers)source(); + Http2Headers in = (Http2Headers)newWithElementDefault(newWithMapKeyDefault(source())); out = HttpConversionUtil.toFullHttpResponse(0, in, (ByteBufAllocator)null, false); sink(out); // $ hasTaintFlow } { - // "io.netty.handler.codec.http2;HttpConversionUtil;false;toFullHttpResponse;;;Argument[2];ReturnValue;taint;manual" + // "io.netty.handler.codec.http2;HttpConversionUtil;false;toFullHttpResponse;;;Argument[1].Element.MapValue;ReturnValue;taint;manual" FullHttpResponse out = null; - ByteBuf in = (ByteBuf)source(); - out = HttpConversionUtil.toFullHttpResponse(0, (Http2Headers)null, in, false); + Http2Headers in = (Http2Headers)newWithElementDefault(newWithMapValueDefault(source())); + out = HttpConversionUtil.toFullHttpResponse(0, in, (ByteBuf)null, false); sink(out); // $ hasTaintFlow } { - // "io.netty.handler.codec.http2;HttpConversionUtil;false;toFullHttpResponse;;;Argument[2];ReturnValue;taint;manual" + // "io.netty.handler.codec.http2;HttpConversionUtil;false;toFullHttpResponse;;;Argument[1].Element.MapValue;ReturnValue;taint;manual" FullHttpResponse out = null; - ByteBufAllocator in = (ByteBufAllocator)source(); - out = HttpConversionUtil.toFullHttpResponse(0, (Http2Headers)null, in, false); + Http2Headers in = (Http2Headers)newWithElementDefault(newWithMapValueDefault(source())); + out = HttpConversionUtil.toFullHttpResponse(0, in, (ByteBufAllocator)null, false); sink(out); // $ hasTaintFlow } { - // "io.netty.handler.codec.http2;HttpConversionUtil;false;toHttp2Headers;(HttpHeaders,Http2Headers);;Argument[0];Argument[1];taint;manual" + // "io.netty.handler.codec.http2;HttpConversionUtil;false;toHttp2Headers;(HttpHeaders,Http2Headers);;Argument[0].Element.MapKey;Argument[1].Element.MapKey;taint;manual" Http2Headers out = null; - HttpHeaders in = (HttpHeaders)source(); + HttpHeaders in = (HttpHeaders)newWithElementDefault(newWithMapKeyDefault(source())); HttpConversionUtil.toHttp2Headers(in, out); - sink(out); // $ hasTaintFlow + sink(getMapKeyDefault(getElement(out))); // $ hasTaintFlow } { - // "io.netty.handler.codec.http2;HttpConversionUtil;false;toHttp2Headers;(HttpHeaders,boolean);;Argument[0];ReturnValue;taint;manual" + // "io.netty.handler.codec.http2;HttpConversionUtil;false;toHttp2Headers;(HttpHeaders,Http2Headers);;Argument[0].Element.MapValue;Argument[1].Element.MapValue;taint;manual" Http2Headers out = null; - HttpHeaders in = (HttpHeaders)source(); - out = HttpConversionUtil.toHttp2Headers(in, false); - sink(out); // $ hasTaintFlow + HttpHeaders in = (HttpHeaders)newWithElementDefault(newWithMapValueDefault(source())); + HttpConversionUtil.toHttp2Headers(in, out); + sink(getMapValueDefault(getElement(out))); // $ hasTaintFlow } { - // "io.netty.handler.codec.http2;HttpConversionUtil;false;toHttpRequest;;;Argument[1];ReturnValue;taint;manual" + // "io.netty.handler.codec.http2;HttpConversionUtil;false;toHttp2Headers;(HttpHeaders,boolean);;Argument[0].Element.MapKey;ReturnValue.Element.MapKey;taint;manual" + Http2Headers out = null; + HttpHeaders in = (HttpHeaders)newWithElementDefault(newWithMapKeyDefault(source())); + out = HttpConversionUtil.toHttp2Headers(in, false); + sink(getMapKeyDefault(getElement(out))); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.http2;HttpConversionUtil;false;toHttp2Headers;(HttpHeaders,boolean);;Argument[0].Element.MapValue;ReturnValue.Element.MapValue;taint;manual" + Http2Headers out = null; + HttpHeaders in = (HttpHeaders)newWithElementDefault(newWithMapValueDefault(source())); + out = HttpConversionUtil.toHttp2Headers(in, false); + sink(getMapValueDefault(getElement(out))); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.http2;HttpConversionUtil;false;toHttpRequest;;;Argument[1].Element.MapKey;ReturnValue;taint;manual" HttpRequest out = null; - Http2Headers in = (Http2Headers)source(); + Http2Headers in = (Http2Headers)newWithElementDefault(newWithMapKeyDefault(source())); out = HttpConversionUtil.toHttpRequest(0, in, false); sink(out); // $ hasTaintFlow } { - // "io.netty.handler.codec.http2;HttpConversionUtil;false;toHttpResponse;;;Argument[1];ReturnValue;taint;manual" + // "io.netty.handler.codec.http2;HttpConversionUtil;false;toHttpRequest;;;Argument[1].Element.MapValue;ReturnValue;taint;manual" + HttpRequest out = null; + Http2Headers in = (Http2Headers)newWithElementDefault(newWithMapValueDefault(source())); + out = HttpConversionUtil.toHttpRequest(0, in, false); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.http2;HttpConversionUtil;false;toHttpResponse;;;Argument[1].Element.MapKey;ReturnValue;taint;manual" HttpResponse out = null; - Http2Headers in = (Http2Headers)source(); + Http2Headers in = (Http2Headers)newWithElementDefault(newWithMapKeyDefault(source())); out = HttpConversionUtil.toHttpResponse(0, in, false); sink(out); // $ hasTaintFlow } + { + // "io.netty.handler.codec.http2;HttpConversionUtil;false;toHttpResponse;;;Argument[1].Element.MapValue;ReturnValue;taint;manual" + HttpResponse out = null; + Http2Headers in = (Http2Headers)newWithElementDefault(newWithMapValueDefault(source())); + out = HttpConversionUtil.toHttpResponse(0, in, false); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.http;HttpHeaders;true;add;(CharSequence,Iterable);;Argument[0];Argument[-1].Element.MapKey;taint;manual" + HttpHeaders out = null; + CharSequence in = (CharSequence)source(); + out.add(in, (Iterable)null); + sink(getMapKeyDefault(getElement(out))); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.http;HttpHeaders;true;add;(CharSequence,Iterable);;Argument[1].Element;Argument[-1].Element.MapValue;taint;manual" + HttpHeaders out = null; + Iterable in = (Iterable)List.of(source()); + out.add((CharSequence)null, in); + sink(getMapValueDefault(getElement(out))); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.http;HttpHeaders;true;add;(CharSequence,Object);;Argument[0];Argument[-1].Element.MapKey;taint;manual" + HttpHeaders out = null; + CharSequence in = (CharSequence)source(); + out.add(in, (Object)null); + sink(getMapKeyDefault(getElement(out))); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.http;HttpHeaders;true;add;(CharSequence,Object);;Argument[1];Argument[-1].Element.MapValue;taint;manual" + HttpHeaders out = null; + Object in = (Object)source(); + out.add((CharSequence)null, in); + sink(getMapValueDefault(getElement(out))); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.http;HttpHeaders;true;add;(HttpHeaders);;Argument[0].Element.MapKey;Argument[-1].Element.MapKey;value;manual" + HttpHeaders out = null; + HttpHeaders in = (HttpHeaders)newWithElementDefault(newWithMapKeyDefault(source())); + out.add(in); + sink(getMapKeyDefault(getElement(out))); // $ hasValueFlow + } + { + // "io.netty.handler.codec.http;HttpHeaders;true;add;(HttpHeaders);;Argument[0].Element.MapValue;Argument[-1].Element.MapValue;taint;manual" + HttpHeaders out = null; + HttpHeaders in = (HttpHeaders)newWithElementDefault(newWithMapValueDefault(source())); + out.add(in); + sink(getMapValueDefault(getElement(out))); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.http;HttpHeaders;true;add;(String,Iterable);;Argument[0];Argument[-1].Element.MapKey;value;manual" + HttpHeaders out = null; + String in = (String)source(); + out.add(in, (Iterable)null); + sink(getMapKeyDefault(getElement(out))); // $ hasValueFlow + } + { + // "io.netty.handler.codec.http;HttpHeaders;true;add;(String,Iterable);;Argument[1].Element;Argument[-1].Element.MapValue;taint;manual" + HttpHeaders out = null; + Iterable in = (Iterable)List.of(source()); + out.add((String)null, in); + sink(getMapValueDefault(getElement(out))); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.http;HttpHeaders;true;add;(String,Object);;Argument[0];Argument[-1].Element.MapKey;value;manual" + HttpHeaders out = null; + String in = (String)source(); + out.add(in, (Object)null); + sink(getMapKeyDefault(getElement(out))); // $ hasValueFlow + } + { + // "io.netty.handler.codec.http;HttpHeaders;true;add;(String,Object);;Argument[1];Argument[-1].Element.MapValue;taint;manual" + HttpHeaders out = null; + Object in = (Object)source(); + out.add((String)null, in); + sink(getMapValueDefault(getElement(out))); // $ hasTaintFlow + } { // "io.netty.handler.codec.http;HttpHeaders;true;add;;;Argument[-1];ReturnValue;value;manual" HttpHeaders out = null; @@ -4717,53 +5679,81 @@ public class Test { sink(out); // $ hasValueFlow } { - // "io.netty.handler.codec.http;HttpHeaders;true;addInt;;;Argument[-1];ReturnValue;value;manual" + // "io.netty.handler.codec.http;HttpHeaders;true;addInt;(CharSequence,int);;Argument[-1];ReturnValue;value;manual" HttpHeaders out = null; HttpHeaders in = (HttpHeaders)source(); out = in.addInt(null, 0); sink(out); // $ hasValueFlow } { - // "io.netty.handler.codec.http;HttpHeaders;true;addShort;;;Argument[-1];ReturnValue;value;manual" + // "io.netty.handler.codec.http;HttpHeaders;true;addInt;(CharSequence,int);;Argument[0];Argument[-1].Element.MapKey;value;manual" + HttpHeaders out = null; + CharSequence in = (CharSequence)source(); + out.addInt(in, 0); + sink(getMapKeyDefault(getElement(out))); // $ hasValueFlow + } + { + // "io.netty.handler.codec.http;HttpHeaders;true;addShort;(CharSequence,short);;Argument[-1];ReturnValue;value;manual" HttpHeaders out = null; HttpHeaders in = (HttpHeaders)source(); out = in.addShort(null, (short)0); sink(out); // $ hasValueFlow } { - // "io.netty.handler.codec.http;HttpHeaders;true;copy;;;Argument[-1];ReturnValue;taint;manual" + // "io.netty.handler.codec.http;HttpHeaders;true;addShort;(CharSequence,short);;Argument[0];Argument[-1].Element.MapKey;value;manual" HttpHeaders out = null; - HttpHeaders in = (HttpHeaders)source(); + CharSequence in = (CharSequence)source(); + out.addShort(in, (short)0); + sink(getMapKeyDefault(getElement(out))); // $ hasValueFlow + } + { + // "io.netty.handler.codec.http;HttpHeaders;true;copy;();;Argument[-1].Element.MapKey;ReturnValue.Element.MapKey;value;manual" + HttpHeaders out = null; + HttpHeaders in = (HttpHeaders)newWithElementDefault(newWithMapKeyDefault(source())); out = in.copy(); - sink(out); // $ hasTaintFlow + sink(getMapKeyDefault(getElement(out))); // $ hasValueFlow } { - // "io.netty.handler.codec.http;HttpHeaders;true;entries;;;Argument[-1];ReturnValue;taint;manual" + // "io.netty.handler.codec.http;HttpHeaders;true;copy;();;Argument[-1].Element.MapValue;ReturnValue.Element.MapValue;value;manual" + HttpHeaders out = null; + HttpHeaders in = (HttpHeaders)newWithElementDefault(newWithMapValueDefault(source())); + out = in.copy(); + sink(getMapValueDefault(getElement(out))); // $ hasValueFlow + } + { + // "io.netty.handler.codec.http;HttpHeaders;true;entries;();;Argument[-1].Element.MapKey;ReturnValue.Element.MapKey;value;manual" List out = null; - HttpHeaders in = (HttpHeaders)source(); + HttpHeaders in = (HttpHeaders)newWithElementDefault(newWithMapKeyDefault(source())); out = in.entries(); - sink(out); // $ hasTaintFlow + sink(getMapKeyDefault(getElement(out))); // $ hasValueFlow } { - // "io.netty.handler.codec.http;HttpHeaders;true;get;;;Argument[-1];ReturnValue;taint;manual" + // "io.netty.handler.codec.http;HttpHeaders;true;entries;();;Argument[-1].Element.MapValue;ReturnValue.Element.MapValue;value;manual" + List out = null; + HttpHeaders in = (HttpHeaders)newWithElementDefault(newWithMapValueDefault(source())); + out = in.entries(); + sink(getMapValueDefault(getElement(out))); // $ hasValueFlow + } + { + // "io.netty.handler.codec.http;HttpHeaders;true;get;;;Argument[-1].Element.MapValue;ReturnValue;value;manual" String out = null; - HttpHeaders in = (HttpHeaders)source(); + HttpHeaders in = (HttpHeaders)newWithElementDefault(newWithMapValueDefault(source())); out = in.get((CharSequence)null); - sink(out); // $ hasTaintFlow + sink(out); // $ hasValueFlow } { - // "io.netty.handler.codec.http;HttpHeaders;true;get;;;Argument[-1];ReturnValue;taint;manual" + // "io.netty.handler.codec.http;HttpHeaders;true;get;;;Argument[-1].Element.MapValue;ReturnValue;value;manual" String out = null; - HttpHeaders in = (HttpHeaders)source(); + HttpHeaders in = (HttpHeaders)newWithElementDefault(newWithMapValueDefault(source())); out = in.get((String)null); - sink(out); // $ hasTaintFlow + sink(out); // $ hasValueFlow } { - // "io.netty.handler.codec.http;HttpHeaders;true;get;;;Argument[-1];ReturnValue;taint;manual" + // "io.netty.handler.codec.http;HttpHeaders;true;get;;;Argument[-1].Element.MapValue;ReturnValue;value;manual" String out = null; - HttpHeaders in = (HttpHeaders)source(); + HttpHeaders in = (HttpHeaders)newWithElementDefault(newWithMapValueDefault(source())); out = in.get(null, null); - sink(out); // $ hasTaintFlow + sink(out); // $ hasValueFlow } { // "io.netty.handler.codec.http;HttpHeaders;true;get;;;Argument[1];ReturnValue;value;manual" @@ -4774,32 +5764,32 @@ public class Test { sink(out); // $ hasValueFlow } { - // "io.netty.handler.codec.http;HttpHeaders;true;getAll;;;Argument[-1];ReturnValue;taint;manual" + // "io.netty.handler.codec.http;HttpHeaders;true;getAll;;;Argument[-1].Element.MapValue;ReturnValue.Element;value;manual" List out = null; - HttpHeaders in = (HttpHeaders)source(); + HttpHeaders in = (HttpHeaders)newWithElementDefault(newWithMapValueDefault(source())); out = in.getAll((CharSequence)null); - sink(out); // $ hasTaintFlow + sink(getElement(out)); // $ hasValueFlow } { - // "io.netty.handler.codec.http;HttpHeaders;true;getAll;;;Argument[-1];ReturnValue;taint;manual" + // "io.netty.handler.codec.http;HttpHeaders;true;getAll;;;Argument[-1].Element.MapValue;ReturnValue.Element;value;manual" List out = null; - HttpHeaders in = (HttpHeaders)source(); + HttpHeaders in = (HttpHeaders)newWithElementDefault(newWithMapValueDefault(source())); out = in.getAll((String)null); - sink(out); // $ hasTaintFlow + sink(getElement(out)); // $ hasValueFlow } { - // "io.netty.handler.codec.http;HttpHeaders;true;getAllAsString;;;Argument[-1];ReturnValue;taint;manual" + // "io.netty.handler.codec.http;HttpHeaders;true;getAllAsString;;;Argument[-1].Element.MapValue;ReturnValue.Element;value;manual" List out = null; - HttpHeaders in = (HttpHeaders)source(); + HttpHeaders in = (HttpHeaders)newWithElementDefault(newWithMapValueDefault(source())); out = in.getAllAsString(null); - sink(out); // $ hasTaintFlow + sink(getElement(out)); // $ hasValueFlow } { - // "io.netty.handler.codec.http;HttpHeaders;true;getAsString;;;Argument[-1];ReturnValue;taint;manual" + // "io.netty.handler.codec.http;HttpHeaders;true;getAsString;;;Argument[-1].Element.MapValue;ReturnValue;value;manual" String out = null; - HttpHeaders in = (HttpHeaders)source(); + HttpHeaders in = (HttpHeaders)newWithElementDefault(newWithMapValueDefault(source())); out = in.getAsString(null); - sink(out); // $ hasTaintFlow + sink(out); // $ hasValueFlow } { // "io.netty.handler.codec.http;HttpHeaders;true;getHeader;;;Argument[0];ReturnValue;taint;manual" @@ -4865,25 +5855,39 @@ public class Test { sink(out); // $ hasValueFlow } { - // "io.netty.handler.codec.http;HttpHeaders;true;iteratorAsString;;;Argument[-1];ReturnValue;taint;manual" + // "io.netty.handler.codec.http;HttpHeaders;true;iteratorAsString;();;Argument[-1].Element.MapKey;ReturnValue.Element.MapKey;value;manual" Iterator out = null; - HttpHeaders in = (HttpHeaders)source(); + HttpHeaders in = (HttpHeaders)newWithElementDefault(newWithMapKeyDefault(source())); out = in.iteratorAsString(); - sink(out); // $ hasTaintFlow + sink(getMapKeyDefault(getElement(out))); // $ hasValueFlow } { - // "io.netty.handler.codec.http;HttpHeaders;true;iteratorCharSequence;;;Argument[-1];ReturnValue;taint;manual" + // "io.netty.handler.codec.http;HttpHeaders;true;iteratorAsString;();;Argument[-1].Element.MapValue;ReturnValue.Element.MapValue;value;manual" Iterator out = null; - HttpHeaders in = (HttpHeaders)source(); - out = in.iteratorCharSequence(); - sink(out); // $ hasTaintFlow + HttpHeaders in = (HttpHeaders)newWithElementDefault(newWithMapValueDefault(source())); + out = in.iteratorAsString(); + sink(getMapValueDefault(getElement(out))); // $ hasValueFlow } { - // "io.netty.handler.codec.http;HttpHeaders;true;names;;;Argument[-1];ReturnValue;taint;manual" + // "io.netty.handler.codec.http;HttpHeaders;true;iteratorCharSequence;();;Argument[-1].Element.MapKey;ReturnValue.Element.MapKey;taint;manual" + Iterator out = null; + HttpHeaders in = (HttpHeaders)newWithElementDefault(newWithMapKeyDefault(source())); + out = in.iteratorCharSequence(); + sink(getMapKeyDefault(getElement(out))); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.http;HttpHeaders;true;iteratorCharSequence;();;Argument[-1].Element.MapValue;ReturnValue.Element.MapValue;taint;manual" + Iterator out = null; + HttpHeaders in = (HttpHeaders)newWithElementDefault(newWithMapValueDefault(source())); + out = in.iteratorCharSequence(); + sink(getMapValueDefault(getElement(out))); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.http;HttpHeaders;true;names;();;Argument[-1].Element.MapKey;ReturnValue.Element;value;manual" Set out = null; - HttpHeaders in = (HttpHeaders)source(); + HttpHeaders in = (HttpHeaders)newWithElementDefault(newWithMapKeyDefault(source())); out = in.names(); - sink(out); // $ hasTaintFlow + sink(getElement(out)); // $ hasValueFlow } { // "io.netty.handler.codec.http;HttpHeaders;true;newEntity;;;Argument[0];ReturnValue;taint;manual" @@ -4906,6 +5910,76 @@ public class Test { out = in.remove((String)null); sink(out); // $ hasValueFlow } + { + // "io.netty.handler.codec.http;HttpHeaders;true;set;(CharSequence,Iterable);;Argument[0];Argument[-1].Element.MapKey;taint;manual" + HttpHeaders out = null; + CharSequence in = (CharSequence)source(); + out.set(in, (Iterable)null); + sink(getMapKeyDefault(getElement(out))); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.http;HttpHeaders;true;set;(CharSequence,Iterable);;Argument[1].Element;Argument[-1].Element.MapValue;taint;manual" + HttpHeaders out = null; + Iterable in = (Iterable)List.of(source()); + out.set((CharSequence)null, in); + sink(getMapValueDefault(getElement(out))); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.http;HttpHeaders;true;set;(CharSequence,Object);;Argument[0];Argument[-1].Element.MapKey;taint;manual" + HttpHeaders out = null; + CharSequence in = (CharSequence)source(); + out.set(in, (Object)null); + sink(getMapKeyDefault(getElement(out))); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.http;HttpHeaders;true;set;(CharSequence,Object);;Argument[1];Argument[-1].Element.MapValue;taint;manual" + HttpHeaders out = null; + Object in = (Object)source(); + out.set((CharSequence)null, in); + sink(getMapValueDefault(getElement(out))); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.http;HttpHeaders;true;set;(HttpHeaders);;Argument[0].Element.MapKey;Argument[-1].Element.MapKey;value;manual" + HttpHeaders out = null; + HttpHeaders in = (HttpHeaders)newWithElementDefault(newWithMapKeyDefault(source())); + out.set(in); + sink(getMapKeyDefault(getElement(out))); // $ hasValueFlow + } + { + // "io.netty.handler.codec.http;HttpHeaders;true;set;(HttpHeaders);;Argument[0].Element.MapValue;Argument[-1].Element.MapValue;taint;manual" + HttpHeaders out = null; + HttpHeaders in = (HttpHeaders)newWithElementDefault(newWithMapValueDefault(source())); + out.set(in); + sink(getMapValueDefault(getElement(out))); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.http;HttpHeaders;true;set;(String,Iterable);;Argument[0];Argument[-1].Element.MapKey;value;manual" + HttpHeaders out = null; + String in = (String)source(); + out.set(in, (Iterable)null); + sink(getMapKeyDefault(getElement(out))); // $ hasValueFlow + } + { + // "io.netty.handler.codec.http;HttpHeaders;true;set;(String,Iterable);;Argument[1].Element;Argument[-1].Element.MapValue;taint;manual" + HttpHeaders out = null; + Iterable in = (Iterable)List.of(source()); + out.set((String)null, in); + sink(getMapValueDefault(getElement(out))); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.http;HttpHeaders;true;set;(String,Object);;Argument[0];Argument[-1].Element.MapKey;value;manual" + HttpHeaders out = null; + String in = (String)source(); + out.set(in, (Object)null); + sink(getMapKeyDefault(getElement(out))); // $ hasValueFlow + } + { + // "io.netty.handler.codec.http;HttpHeaders;true;set;(String,Object);;Argument[1];Argument[-1].Element.MapValue;taint;manual" + HttpHeaders out = null; + Object in = (Object)source(); + out.set((String)null, in); + sink(getMapValueDefault(getElement(out))); // $ hasTaintFlow + } { // "io.netty.handler.codec.http;HttpHeaders;true;set;;;Argument[-1];ReturnValue;value;manual" HttpHeaders out = null; @@ -4942,46 +6016,81 @@ public class Test { sink(out); // $ hasValueFlow } { - // "io.netty.handler.codec.http;HttpHeaders;true;setAll;;;Argument[-1];ReturnValue;value;manual" + // "io.netty.handler.codec.http;HttpHeaders;true;setAll;(HttpHeaders);;Argument[-1];ReturnValue;value;manual" HttpHeaders out = null; HttpHeaders in = (HttpHeaders)source(); out = in.setAll(null); sink(out); // $ hasValueFlow } { - // "io.netty.handler.codec.http;HttpHeaders;true;setInt;;;Argument[-1];ReturnValue;value;manual" + // "io.netty.handler.codec.http;HttpHeaders;true;setAll;(HttpHeaders);;Argument[0].Element.MapKey;Argument[-1].Element.MapKey;value;manual" + HttpHeaders out = null; + HttpHeaders in = (HttpHeaders)newWithElementDefault(newWithMapKeyDefault(source())); + out.setAll(in); + sink(getMapKeyDefault(getElement(out))); // $ hasValueFlow + } + { + // "io.netty.handler.codec.http;HttpHeaders;true;setAll;(HttpHeaders);;Argument[0].Element.MapValue;Argument[-1].Element.MapValue;taint;manual" + HttpHeaders out = null; + HttpHeaders in = (HttpHeaders)newWithElementDefault(newWithMapValueDefault(source())); + out.setAll(in); + sink(getMapValueDefault(getElement(out))); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.http;HttpHeaders;true;setInt;(CharSequence,int);;Argument[-1];ReturnValue;value;manual" HttpHeaders out = null; HttpHeaders in = (HttpHeaders)source(); out = in.setInt(null, 0); sink(out); // $ hasValueFlow } { - // "io.netty.handler.codec.http;HttpHeaders;true;setShort;;;Argument[-1];ReturnValue;value;manual" + // "io.netty.handler.codec.http;HttpHeaders;true;setInt;(CharSequence,int);;Argument[0];Argument[-1].Element.MapKey;value;manual" + HttpHeaders out = null; + CharSequence in = (CharSequence)source(); + out.setInt(in, 0); + sink(getMapKeyDefault(getElement(out))); // $ hasValueFlow + } + { + // "io.netty.handler.codec.http;HttpHeaders;true;setShort;(CharSequence,short);;Argument[-1];ReturnValue;value;manual" HttpHeaders out = null; HttpHeaders in = (HttpHeaders)source(); out = in.setShort(null, (short)0); sink(out); // $ hasValueFlow } { - // "io.netty.handler.codec.http;HttpHeaders;true;toString;;;Argument[-1];ReturnValue;taint;manual" + // "io.netty.handler.codec.http;HttpHeaders;true;setShort;(CharSequence,short);;Argument[0];Argument[-1].Element.MapKey;value;manual" + HttpHeaders out = null; + CharSequence in = (CharSequence)source(); + out.setShort(in, (short)0); + sink(getMapKeyDefault(getElement(out))); // $ hasValueFlow + } + { + // "io.netty.handler.codec.http;HttpHeaders;true;toString;;;Argument[-1].Element.MapKey;ReturnValue;taint;manual" String out = null; - HttpHeaders in = (HttpHeaders)source(); + HttpHeaders in = (HttpHeaders)newWithElementDefault(newWithMapKeyDefault(source())); out = in.toString(); sink(out); // $ hasTaintFlow } { - // "io.netty.handler.codec.http;HttpHeaders;true;valueCharSequenceIterator;;;Argument[-1];ReturnValue;taint;manual" - Iterator out = null; - HttpHeaders in = (HttpHeaders)source(); - out = in.valueCharSequenceIterator(null); + // "io.netty.handler.codec.http;HttpHeaders;true;toString;;;Argument[-1].Element.MapValue;ReturnValue;taint;manual" + String out = null; + HttpHeaders in = (HttpHeaders)newWithElementDefault(newWithMapValueDefault(source())); + out = in.toString(); sink(out); // $ hasTaintFlow } { - // "io.netty.handler.codec.http;HttpHeaders;true;valueStringIterator;;;Argument[-1];ReturnValue;taint;manual" + // "io.netty.handler.codec.http;HttpHeaders;true;valueCharSequenceIterator;(CharSequence);;Argument[-1].Element.MapValue;ReturnValue.Element;taint;manual" Iterator out = null; - HttpHeaders in = (HttpHeaders)source(); + HttpHeaders in = (HttpHeaders)newWithElementDefault(newWithMapValueDefault(source())); + out = in.valueCharSequenceIterator(null); + sink(getElement(out)); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.http;HttpHeaders;true;valueStringIterator;(CharSequence);;Argument[-1].Element.MapValue;ReturnValue.Element;value;manual" + Iterator out = null; + HttpHeaders in = (HttpHeaders)newWithElementDefault(newWithMapValueDefault(source())); out = in.valueStringIterator(null); - sink(out); // $ hasTaintFlow + sink(getElement(out)); // $ hasValueFlow } { // "io.netty.handler.codec.http;HttpMessage;true;headers;;;Argument[-1];ReturnValue;taint;manual" @@ -4997,6 +6106,20 @@ public class Test { out = in.getUri(); sink(out); // $ hasTaintFlow } + { + // "io.netty.handler.codec.http;HttpRequest;true;setUri;;;Argument[0];Argument[-1];taint;manual" + FullHttpRequest out = null; + String in = (String)source(); + out.setUri(in); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec.http;HttpRequest;true;setUri;;;Argument[0];Argument[-1];taint;manual" + HttpRequest out = null; + String in = (String)source(); + out.setUri(in); + sink(out); // $ hasTaintFlow + } { // "io.netty.handler.codec.http;HttpRequest;true;uri;;;Argument[-1];ReturnValue;taint;manual" String out = null; @@ -5138,7 +6261,7 @@ public class Test { sink(out); // $ hasTaintFlow } { - // "io.netty.handler.codec;ByteToMessageDecoder$Cumulator;true;cumulate;(ByteBufAllocator,ByteBuf,ByteBuf);;Argument[1];ReturnValue;taint;manual" + // "io.netty.handler.codec;ByteToMessageDecoder$Cumulator;true;cumulate;(ByteBufAllocator,ByteBuf,ByteBuf);;Argument[1..2];ReturnValue;taint;manual" ByteBuf out = null; ByteBuf in = (ByteBuf)source(); ByteToMessageDecoder.Cumulator instance = null; @@ -5146,13 +6269,69 @@ public class Test { sink(out); // $ hasTaintFlow } { - // "io.netty.handler.codec;ByteToMessageDecoder$Cumulator;true;cumulate;(ByteBufAllocator,ByteBuf,ByteBuf);;Argument[2];ReturnValue;taint;manual" + // "io.netty.handler.codec;ByteToMessageDecoder$Cumulator;true;cumulate;(ByteBufAllocator,ByteBuf,ByteBuf);;Argument[1..2];ReturnValue;taint;manual" ByteBuf out = null; ByteBuf in = (ByteBuf)source(); ByteToMessageDecoder.Cumulator instance = null; out = instance.cumulate(null, null, in); sink(out); // $ hasTaintFlow } + { + // "io.netty.handler.codec;Headers;true;add;(Headers);;Argument[0].Element.MapKey;Argument[-1].Element.MapKey;value;manual" + Headers out = null; + Headers in = (Headers)newWithElementDefault(newWithMapKeyDefault(source())); + out.add(in); + sink(getMapKeyDefault(getElement(out))); // $ hasValueFlow + } + { + // "io.netty.handler.codec;Headers;true;add;(Headers);;Argument[0].Element.MapValue;Argument[-1].Element.MapValue;value;manual" + Headers out = null; + Headers in = (Headers)newWithElementDefault(newWithMapValueDefault(source())); + out.add(in); + sink(getMapValueDefault(getElement(out))); // $ hasValueFlow + } + { + // "io.netty.handler.codec;Headers;true;add;(Object,Iterable);;Argument[0];Argument[-1].Element.MapKey;value;manual" + Headers out = null; + Object in = (Object)source(); + out.add(in, (Iterable)null); + sink(getMapKeyDefault(getElement(out))); // $ hasValueFlow + } + { + // "io.netty.handler.codec;Headers;true;add;(Object,Iterable);;Argument[1].Element;Argument[-1].Element.MapValue;value;manual" + Headers out = null; + Iterable in = (Iterable)List.of(source()); + out.add((Object)null, in); + sink(getMapValueDefault(getElement(out))); // $ hasValueFlow + } + { + // "io.netty.handler.codec;Headers;true;add;(Object,Object);;Argument[0];Argument[-1].Element.MapKey;value;manual" + Headers out = null; + Object in = (Object)source(); + out.add(in, (Object)null); + sink(getMapKeyDefault(getElement(out))); // $ hasValueFlow + } + { + // "io.netty.handler.codec;Headers;true;add;(Object,Object);;Argument[1];Argument[-1].Element.MapValue;value;manual" + Headers out = null; + Object in = (Object)source(); + out.add((Object)null, in); + sink(getMapValueDefault(getElement(out))); // $ hasValueFlow + } + { + // "io.netty.handler.codec;Headers;true;add;(Object,Object[]);;Argument[0];Argument[-1].Element.MapKey;value;manual" + Headers out = null; + Object in = (Object)source(); + out.add(in, (Object[])null); + sink(getMapKeyDefault(getElement(out))); // $ hasValueFlow + } + { + // "io.netty.handler.codec;Headers;true;add;(Object,Object[]);;Argument[1].ArrayElement;Argument[-1].Element.MapValue;value;manual" + Headers out = null; + Object[] in = (Object[])new Object[]{source()}; + out.add((Object)null, in); + sink(getMapValueDefault(getElement(out))); // $ hasValueFlow + } { // "io.netty.handler.codec;Headers;true;add;;;Argument[-1];ReturnValue;value;manual" Headers out = null; @@ -5188,6 +6367,13 @@ public class Test { out = in.addBoolean(null, false); sink(out); // $ hasValueFlow } + { + // "io.netty.handler.codec;Headers;true;addBoolean;;;Argument[0];Argument[-1].Element.MapKey;value;manual" + Headers out = null; + Object in = (Object)source(); + out.addBoolean(in, false); + sink(getMapKeyDefault(getElement(out))); // $ hasValueFlow + } { // "io.netty.handler.codec;Headers;true;addByte;;;Argument[-1];ReturnValue;value;manual" Headers out = null; @@ -5195,6 +6381,13 @@ public class Test { out = in.addByte(null, (byte)0); sink(out); // $ hasValueFlow } + { + // "io.netty.handler.codec;Headers;true;addByte;;;Argument[0];Argument[-1].Element.MapKey;value;manual" + Headers out = null; + Object in = (Object)source(); + out.addByte(in, (byte)0); + sink(getMapKeyDefault(getElement(out))); // $ hasValueFlow + } { // "io.netty.handler.codec;Headers;true;addChar;;;Argument[-1];ReturnValue;value;manual" Headers out = null; @@ -5202,6 +6395,13 @@ public class Test { out = in.addChar(null, '\0'); sink(out); // $ hasValueFlow } + { + // "io.netty.handler.codec;Headers;true;addChar;;;Argument[0];Argument[-1].Element.MapKey;value;manual" + Headers out = null; + Object in = (Object)source(); + out.addChar(in, '\0'); + sink(getMapKeyDefault(getElement(out))); // $ hasValueFlow + } { // "io.netty.handler.codec;Headers;true;addDouble;;;Argument[-1];ReturnValue;value;manual" Headers out = null; @@ -5209,6 +6409,13 @@ public class Test { out = in.addDouble(null, 0.0); sink(out); // $ hasValueFlow } + { + // "io.netty.handler.codec;Headers;true;addDouble;;;Argument[0];Argument[-1].Element.MapKey;value;manual" + Headers out = null; + Object in = (Object)source(); + out.addDouble(in, 0.0); + sink(getMapKeyDefault(getElement(out))); // $ hasValueFlow + } { // "io.netty.handler.codec;Headers;true;addFloat;;;Argument[-1];ReturnValue;value;manual" Headers out = null; @@ -5216,6 +6423,13 @@ public class Test { out = in.addFloat(null, 0.0f); sink(out); // $ hasValueFlow } + { + // "io.netty.handler.codec;Headers;true;addFloat;;;Argument[0];Argument[-1].Element.MapKey;value;manual" + Headers out = null; + Object in = (Object)source(); + out.addFloat(in, 0.0f); + sink(getMapKeyDefault(getElement(out))); // $ hasValueFlow + } { // "io.netty.handler.codec;Headers;true;addInt;;;Argument[-1];ReturnValue;value;manual" Headers out = null; @@ -5223,6 +6437,13 @@ public class Test { out = in.addInt(null, 0); sink(out); // $ hasValueFlow } + { + // "io.netty.handler.codec;Headers;true;addInt;;;Argument[0];Argument[-1].Element.MapKey;value;manual" + Headers out = null; + Object in = (Object)source(); + out.addInt(in, 0); + sink(getMapKeyDefault(getElement(out))); // $ hasValueFlow + } { // "io.netty.handler.codec;Headers;true;addLong;;;Argument[-1];ReturnValue;value;manual" Headers out = null; @@ -5231,25 +6452,53 @@ public class Test { sink(out); // $ hasValueFlow } { - // "io.netty.handler.codec;Headers;true;addObject;;;Argument[-1];ReturnValue;value;manual" + // "io.netty.handler.codec;Headers;true;addLong;;;Argument[0];Argument[-1].Element.MapKey;value;manual" Headers out = null; - Headers in = (Headers)source(); - out = in.addObject((Object)null, (Iterable)null); - sink(out); // $ hasValueFlow + Object in = (Object)source(); + out.addLong(in, 0L); + sink(getMapKeyDefault(getElement(out))); // $ hasValueFlow } { - // "io.netty.handler.codec;Headers;true;addObject;;;Argument[-1];ReturnValue;value;manual" + // "io.netty.handler.codec;Headers;true;addObject;(Object,Iterable);;Argument[0];Argument[-1].Element.MapKey;value;manual" Headers out = null; - Headers in = (Headers)source(); - out = in.addObject((Object)null, (Object)null); - sink(out); // $ hasValueFlow + Object in = (Object)source(); + out.addObject(in, (Iterable)null); + sink(getMapKeyDefault(getElement(out))); // $ hasValueFlow } { - // "io.netty.handler.codec;Headers;true;addObject;;;Argument[-1];ReturnValue;value;manual" + // "io.netty.handler.codec;Headers;true;addObject;(Object,Iterable);;Argument[1].Element;Argument[-1].Element.MapValue;taint;manual" Headers out = null; - Headers in = (Headers)source(); - out = in.addObject((Object)null, (Object[])null); - sink(out); // $ hasValueFlow + Iterable in = (Iterable)List.of(source()); + out.addObject((Object)null, in); + sink(getMapValueDefault(getElement(out))); // $ hasTaintFlow + } + { + // "io.netty.handler.codec;Headers;true;addObject;(Object,Object);;Argument[0];Argument[-1].Element.MapKey;value;manual" + Headers out = null; + Object in = (Object)source(); + out.addObject(in, (Object)null); + sink(getMapKeyDefault(getElement(out))); // $ hasValueFlow + } + { + // "io.netty.handler.codec;Headers;true;addObject;(Object,Object);;Argument[1];Argument[-1].Element.MapValue;taint;manual" + Headers out = null; + Object in = (Object)source(); + out.addObject((Object)null, in); + sink(getMapValueDefault(getElement(out))); // $ hasTaintFlow + } + { + // "io.netty.handler.codec;Headers;true;addObject;(Object,Object[]);;Argument[0];Argument[-1].Element.MapKey;value;manual" + Headers out = null; + Object in = (Object)source(); + out.addObject(in, (Object[])null); + sink(getMapKeyDefault(getElement(out))); // $ hasValueFlow + } + { + // "io.netty.handler.codec;Headers;true;addObject;(Object,Object[]);;Argument[1].ArrayElement;Argument[-1].Element.MapValue;taint;manual" + Headers out = null; + Object[] in = (Object[])new Object[]{source()}; + out.addObject((Object)null, in); + sink(getMapValueDefault(getElement(out))); // $ hasTaintFlow } { // "io.netty.handler.codec;Headers;true;addShort;;;Argument[-1];ReturnValue;value;manual" @@ -5258,6 +6507,13 @@ public class Test { out = in.addShort(null, (short)0); sink(out); // $ hasValueFlow } + { + // "io.netty.handler.codec;Headers;true;addShort;;;Argument[0];Argument[-1].Element.MapKey;value;manual" + Headers out = null; + Object in = (Object)source(); + out.addShort(in, (short)0); + sink(getMapKeyDefault(getElement(out))); // $ hasValueFlow + } { // "io.netty.handler.codec;Headers;true;addTimeMillis;;;Argument[-1];ReturnValue;value;manual" Headers out = null; @@ -5266,16 +6522,23 @@ public class Test { sink(out); // $ hasValueFlow } { - // "io.netty.handler.codec;Headers;true;get;(Object);;Argument[-1];ReturnValue;taint;manual" + // "io.netty.handler.codec;Headers;true;addTimeMillis;;;Argument[0];Argument[-1].Element.MapKey;value;manual" + Headers out = null; + Object in = (Object)source(); + out.addTimeMillis(in, 0L); + sink(getMapKeyDefault(getElement(out))); // $ hasValueFlow + } + { + // "io.netty.handler.codec;Headers;true;get;(Object);;Argument[-1].Element.MapValue;ReturnValue;taint;manual" Object out = null; - Headers in = (Headers)source(); + Headers in = (Headers)newWithElementDefault(newWithMapValueDefault(source())); out = in.get(null); sink(out); // $ hasTaintFlow } { - // "io.netty.handler.codec;Headers;true;get;(Object,Object);;Argument[-1];ReturnValue;taint;manual" + // "io.netty.handler.codec;Headers;true;get;(Object,Object);;Argument[-1].Element.MapValue;ReturnValue;taint;manual" Object out = null; - Headers in = (Headers)source(); + Headers in = (Headers)newWithElementDefault(newWithMapValueDefault(source())); out = in.get(null, null); sink(out); // $ hasTaintFlow } @@ -5288,23 +6551,23 @@ public class Test { sink(out); // $ hasValueFlow } { - // "io.netty.handler.codec;Headers;true;getAll;(Object);;Argument[-1];ReturnValue;taint;manual" + // "io.netty.handler.codec;Headers;true;getAll;(Object);;Argument[-1].Element.MapValue;ReturnValue.Element;taint;manual" List out = null; - Headers in = (Headers)source(); + Headers in = (Headers)newWithElementDefault(newWithMapValueDefault(source())); out = in.getAll(null); - sink(out); // $ hasTaintFlow + sink(getElement(out)); // $ hasTaintFlow } { - // "io.netty.handler.codec;Headers;true;getAllAndRemove;(Object);;Argument[-1];ReturnValue;taint;manual" + // "io.netty.handler.codec;Headers;true;getAllAndRemove;(Object);;Argument[-1].Element.MapValue;ReturnValue.Element;taint;manual" List out = null; - Headers in = (Headers)source(); + Headers in = (Headers)newWithElementDefault(newWithMapValueDefault(source())); out = in.getAllAndRemove(null); - sink(out); // $ hasTaintFlow + sink(getElement(out)); // $ hasTaintFlow } { - // "io.netty.handler.codec;Headers;true;getAndRemove;(Object);;Argument[-1];ReturnValue;taint;manual" + // "io.netty.handler.codec;Headers;true;getAndRemove;(Object);;Argument[-1].Element.MapValue;ReturnValue;taint;manual" Object out = null; - Headers in = (Headers)source(); + Headers in = (Headers)newWithElementDefault(newWithMapValueDefault(source())); out = in.getAndRemove(null); sink(out); // $ hasTaintFlow } @@ -5317,25 +6580,67 @@ public class Test { sink(out); // $ hasValueFlow } { - // "io.netty.handler.codec;Headers;true;iterator;();;Argument[-1];ReturnValue;taint;manual" - Iterator out = null; - Headers in = (Headers)source(); - out = in.iterator(); - sink(out); // $ hasTaintFlow - } - { - // "io.netty.handler.codec;Headers;true;iterator;();;Argument[-1];ReturnValue;taint;manual" - Iterator out = null; - Http2Headers in = (Http2Headers)source(); - out = in.iterator(); - sink(out); // $ hasTaintFlow - } - { - // "io.netty.handler.codec;Headers;true;names;();;Argument[-1];ReturnValue;taint;manual" + // "io.netty.handler.codec;Headers;true;names;();;Argument[-1].Element.MapKey;ReturnValue.Element;taint;manual" Set out = null; - Headers in = (Headers)source(); + Headers in = (Headers)newWithElementDefault(newWithMapKeyDefault(source())); out = in.names(); - sink(out); // $ hasTaintFlow + sink(getElement(out)); // $ hasTaintFlow + } + { + // "io.netty.handler.codec;Headers;true;set;(Headers);;Argument[0].Element.MapKey;Argument[-1].Element.MapKey;value;manual" + Headers out = null; + Headers in = (Headers)newWithElementDefault(newWithMapKeyDefault(source())); + out.set(in); + sink(getMapKeyDefault(getElement(out))); // $ hasValueFlow + } + { + // "io.netty.handler.codec;Headers;true;set;(Headers);;Argument[0].Element.MapValue;Argument[-1].Element.MapValue;value;manual" + Headers out = null; + Headers in = (Headers)newWithElementDefault(newWithMapValueDefault(source())); + out.set(in); + sink(getMapValueDefault(getElement(out))); // $ hasValueFlow + } + { + // "io.netty.handler.codec;Headers;true;set;(Object,Iterable);;Argument[0];Argument[-1].Element.MapKey;value;manual" + Headers out = null; + Object in = (Object)source(); + out.set(in, (Iterable)null); + sink(getMapKeyDefault(getElement(out))); // $ hasValueFlow + } + { + // "io.netty.handler.codec;Headers;true;set;(Object,Iterable);;Argument[1].Element;Argument[-1].Element.MapValue;value;manual" + Headers out = null; + Iterable in = (Iterable)List.of(source()); + out.set((Object)null, in); + sink(getMapValueDefault(getElement(out))); // $ hasValueFlow + } + { + // "io.netty.handler.codec;Headers;true;set;(Object,Object);;Argument[0];Argument[-1].Element.MapKey;value;manual" + Headers out = null; + Object in = (Object)source(); + out.set(in, (Object)null); + sink(getMapKeyDefault(getElement(out))); // $ hasValueFlow + } + { + // "io.netty.handler.codec;Headers;true;set;(Object,Object);;Argument[1];Argument[-1].Element.MapValue;value;manual" + Headers out = null; + Object in = (Object)source(); + out.set((Object)null, in); + sink(getMapValueDefault(getElement(out))); // $ hasValueFlow + } + { + // "io.netty.handler.codec;Headers;true;set;(Object,Object[]);;Argument[0];Argument[-1].Element.MapKey;value;manual" + Headers out = null; + Object in = (Object)source(); + out.set(in, (Object[])null); + sink(getMapKeyDefault(getElement(out))); // $ hasValueFlow + } + { + // "io.netty.handler.codec;Headers;true;set;(Object,Object[]);;Argument[1].ArrayElement;Argument[-1].Element.MapValue;value;manual" + Headers out = null; + Object[] in = (Object[])new Object[]{source()}; + out.set((Object)null, in); + sink(getMapValueDefault(getElement(out))); // $ hasValueFlow } { // "io.netty.handler.codec;Headers;true;set;;;Argument[-1];ReturnValue;value;manual" @@ -5366,11 +6671,18 @@ public class Test { sink(out); // $ hasValueFlow } { - // "io.netty.handler.codec;Headers;true;setAll;;;Argument[-1];ReturnValue;value;manual" + // "io.netty.handler.codec;Headers;true;setAll;(Headers);;Argument[0].Element.MapKey;Argument[-1].Element.MapKey;value;manual" Headers out = null; - Headers in = (Headers)source(); - out = in.setAll(null); - sink(out); // $ hasValueFlow + Headers in = (Headers)newWithElementDefault(newWithMapKeyDefault(source())); + out.setAll(in); + sink(getMapKeyDefault(getElement(out))); // $ hasValueFlow + } + { + // "io.netty.handler.codec;Headers;true;setAll;(Headers);;Argument[0].Element.MapValue;Argument[-1].Element.MapValue;value;manual" + Headers out = null; + Headers in = (Headers)newWithElementDefault(newWithMapValueDefault(source())); + out.setAll(in); + sink(getMapValueDefault(getElement(out))); // $ hasValueFlow } { // "io.netty.handler.codec;Headers;true;setBoolean;;;Argument[-1];ReturnValue;value;manual" @@ -5379,6 +6691,13 @@ public class Test { out = in.setBoolean(null, false); sink(out); // $ hasValueFlow } + { + // "io.netty.handler.codec;Headers;true;setBoolean;;;Argument[0];Argument[-1].Element.MapKey;value;manual" + Headers out = null; + Object in = (Object)source(); + out.setBoolean(in, false); + sink(getMapKeyDefault(getElement(out))); // $ hasValueFlow + } { // "io.netty.handler.codec;Headers;true;setByte;;;Argument[-1];ReturnValue;value;manual" Headers out = null; @@ -5386,6 +6705,13 @@ public class Test { out = in.setByte(null, (byte)0); sink(out); // $ hasValueFlow } + { + // "io.netty.handler.codec;Headers;true;setByte;;;Argument[0];Argument[-1].Element.MapKey;value;manual" + Headers out = null; + Object in = (Object)source(); + out.setByte(in, (byte)0); + sink(getMapKeyDefault(getElement(out))); // $ hasValueFlow + } { // "io.netty.handler.codec;Headers;true;setChar;;;Argument[-1];ReturnValue;value;manual" Headers out = null; @@ -5393,6 +6719,13 @@ public class Test { out = in.setChar(null, '\0'); sink(out); // $ hasValueFlow } + { + // "io.netty.handler.codec;Headers;true;setChar;;;Argument[0];Argument[-1].Element.MapKey;value;manual" + Headers out = null; + Object in = (Object)source(); + out.setChar(in, '\0'); + sink(getMapKeyDefault(getElement(out))); // $ hasValueFlow + } { // "io.netty.handler.codec;Headers;true;setDouble;;;Argument[-1];ReturnValue;value;manual" Headers out = null; @@ -5400,6 +6733,13 @@ public class Test { out = in.setDouble(null, 0.0); sink(out); // $ hasValueFlow } + { + // "io.netty.handler.codec;Headers;true;setDouble;;;Argument[0];Argument[-1].Element.MapKey;value;manual" + Headers out = null; + Object in = (Object)source(); + out.setDouble(in, 0.0); + sink(getMapKeyDefault(getElement(out))); // $ hasValueFlow + } { // "io.netty.handler.codec;Headers;true;setFloat;;;Argument[-1];ReturnValue;value;manual" Headers out = null; @@ -5407,6 +6747,13 @@ public class Test { out = in.setFloat(null, 0.0f); sink(out); // $ hasValueFlow } + { + // "io.netty.handler.codec;Headers;true;setFloat;;;Argument[0];Argument[-1].Element.MapKey;value;manual" + Headers out = null; + Object in = (Object)source(); + out.setFloat(in, 0.0f); + sink(getMapKeyDefault(getElement(out))); // $ hasValueFlow + } { // "io.netty.handler.codec;Headers;true;setInt;;;Argument[-1];ReturnValue;value;manual" Headers out = null; @@ -5414,6 +6761,13 @@ public class Test { out = in.setInt(null, 0); sink(out); // $ hasValueFlow } + { + // "io.netty.handler.codec;Headers;true;setInt;;;Argument[0];Argument[-1].Element.MapKey;value;manual" + Headers out = null; + Object in = (Object)source(); + out.setInt(in, 0); + sink(getMapKeyDefault(getElement(out))); // $ hasValueFlow + } { // "io.netty.handler.codec;Headers;true;setLong;;;Argument[-1];ReturnValue;value;manual" Headers out = null; @@ -5422,25 +6776,53 @@ public class Test { sink(out); // $ hasValueFlow } { - // "io.netty.handler.codec;Headers;true;setObject;;;Argument[-1];ReturnValue;value;manual" + // "io.netty.handler.codec;Headers;true;setLong;;;Argument[0];Argument[-1].Element.MapKey;value;manual" Headers out = null; - Headers in = (Headers)source(); - out = in.setObject((Object)null, (Iterable)null); - sink(out); // $ hasValueFlow + Object in = (Object)source(); + out.setLong(in, 0L); + sink(getMapKeyDefault(getElement(out))); // $ hasValueFlow } { - // "io.netty.handler.codec;Headers;true;setObject;;;Argument[-1];ReturnValue;value;manual" + // "io.netty.handler.codec;Headers;true;setObject;(Object,Iterable);;Argument[0];Argument[-1].Element.MapKey;value;manual" Headers out = null; - Headers in = (Headers)source(); - out = in.setObject((Object)null, (Object)null); - sink(out); // $ hasValueFlow + Object in = (Object)source(); + out.setObject(in, (Iterable)null); + sink(getMapKeyDefault(getElement(out))); // $ hasValueFlow } { - // "io.netty.handler.codec;Headers;true;setObject;;;Argument[-1];ReturnValue;value;manual" + // "io.netty.handler.codec;Headers;true;setObject;(Object,Iterable);;Argument[1].Element;Argument[-1].Element.MapValue;taint;manual" Headers out = null; - Headers in = (Headers)source(); - out = in.setObject((Object)null, (Object[])null); - sink(out); // $ hasValueFlow + Iterable in = (Iterable)List.of(source()); + out.setObject((Object)null, in); + sink(getMapValueDefault(getElement(out))); // $ hasTaintFlow + } + { + // "io.netty.handler.codec;Headers;true;setObject;(Object,Object);;Argument[0];Argument[-1].Element.MapKey;value;manual" + Headers out = null; + Object in = (Object)source(); + out.setObject(in, (Object)null); + sink(getMapKeyDefault(getElement(out))); // $ hasValueFlow + } + { + // "io.netty.handler.codec;Headers;true;setObject;(Object,Object);;Argument[1];Argument[-1].Element.MapValue;taint;manual" + Headers out = null; + Object in = (Object)source(); + out.setObject((Object)null, in); + sink(getMapValueDefault(getElement(out))); // $ hasTaintFlow + } + { + // "io.netty.handler.codec;Headers;true;setObject;(Object,Object[]);;Argument[0];Argument[-1].Element.MapKey;value;manual" + Headers out = null; + Object in = (Object)source(); + out.setObject(in, (Object[])null); + sink(getMapKeyDefault(getElement(out))); // $ hasValueFlow + } + { + // "io.netty.handler.codec;Headers;true;setObject;(Object,Object[]);;Argument[1].ArrayElement;Argument[-1].Element.MapValue;taint;manual" + Headers out = null; + Object[] in = (Object[])new Object[]{source()}; + out.setObject((Object)null, in); + sink(getMapValueDefault(getElement(out))); // $ hasTaintFlow } { // "io.netty.handler.codec;Headers;true;setShort;;;Argument[-1];ReturnValue;value;manual" @@ -5449,6 +6831,13 @@ public class Test { out = in.setShort(null, (short)0); sink(out); // $ hasValueFlow } + { + // "io.netty.handler.codec;Headers;true;setShort;;;Argument[0];Argument[-1].Element.MapKey;value;manual" + Headers out = null; + Object in = (Object)source(); + out.setShort(in, (short)0); + sink(getMapKeyDefault(getElement(out))); // $ hasValueFlow + } { // "io.netty.handler.codec;Headers;true;setTimeMillis;;;Argument[-1];ReturnValue;value;manual" Headers out = null; @@ -5457,37 +6846,58 @@ public class Test { sink(out); // $ hasValueFlow } { - // "io.netty.handler.codec;HeadersUtils;false;getAllAsString;(Headers,Object);;Argument[0];ReturnValue;taint;manual" + // "io.netty.handler.codec;Headers;true;setTimeMillis;;;Argument[0];Argument[-1].Element.MapKey;value;manual" + Headers out = null; + Object in = (Object)source(); + out.setTimeMillis(in, 0L); + sink(getMapKeyDefault(getElement(out))); // $ hasValueFlow + } + { + // "io.netty.handler.codec;HeadersUtils;false;getAllAsString;(Headers,Object);;Argument[0].Element.MapValue;ReturnValue;taint;manual" List out = null; - Headers in = (Headers)source(); + Headers in = (Headers)newWithElementDefault(newWithMapValueDefault(source())); out = HeadersUtils.getAllAsString(in, null); sink(out); // $ hasTaintFlow } { - // "io.netty.handler.codec;HeadersUtils;false;getAsString;(Headers,Object);;Argument[0];ReturnValue;taint;manual" + // "io.netty.handler.codec;HeadersUtils;false;getAsString;(Headers,Object);;Argument[0].Element.MapValue;ReturnValue;taint;manual" String out = null; - Headers in = (Headers)source(); + Headers in = (Headers)newWithElementDefault(newWithMapValueDefault(source())); out = HeadersUtils.getAsString(in, null); sink(out); // $ hasTaintFlow } { - // "io.netty.handler.codec;HeadersUtils;false;iteratorAsString;(Iterable);;Argument[0];ReturnValue;taint;manual" + // "io.netty.handler.codec;HeadersUtils;false;iteratorAsString;(Iterable);;Argument[0].Element.MapKey;ReturnValue;taint;manual" Iterator out = null; - Iterable in = (Iterable)source(); + Iterable in = (Iterable)List.of(newWithMapKeyDefault(source())); out = HeadersUtils.iteratorAsString(in); sink(out); // $ hasTaintFlow } { - // "io.netty.handler.codec;HeadersUtils;false;namesAsString;(Headers);;Argument[0];ReturnValue;taint;manual" - Set out = null; - Headers in = (Headers)source(); - out = HeadersUtils.namesAsString(in); + // "io.netty.handler.codec;HeadersUtils;false;iteratorAsString;(Iterable);;Argument[0].Element.MapValue;ReturnValue;taint;manual" + Iterator out = null; + Iterable in = (Iterable)List.of(newWithMapValueDefault(source())); + out = HeadersUtils.iteratorAsString(in); sink(out); // $ hasTaintFlow } { - // "io.netty.handler.codec;HeadersUtils;false;toString;(Class,Iterator,int);;Argument[1];ReturnValue;taint;manual" + // "io.netty.handler.codec;HeadersUtils;false;namesAsString;(Headers);;Argument[0].Element.MapKey;ReturnValue.Element;value;manual" + Set out = null; + Headers in = (Headers)newWithElementDefault(newWithMapKeyDefault(source())); + out = HeadersUtils.namesAsString(in); + sink(getElement(out)); // $ hasValueFlow + } + { + // "io.netty.handler.codec;HeadersUtils;false;toString;(Class,Iterator,int);;Argument[1].Element.MapKey;ReturnValue;taint;manual" String out = null; - Iterator in = (Iterator)source(); + Iterator in = (Iterator)List.of(newWithMapKeyDefault(source())).iterator(); + out = HeadersUtils.toString(null, in, 0); + sink(out); // $ hasTaintFlow + } + { + // "io.netty.handler.codec;HeadersUtils;false;toString;(Class,Iterator,int);;Argument[1].Element.MapValue;ReturnValue;taint;manual" + String out = null; + Iterator in = (Iterator)List.of(newWithMapValueDefault(source())).iterator(); out = HeadersUtils.toString(null, in, 0); sink(out); // $ hasTaintFlow } @@ -5772,6 +7182,20 @@ public class Test { out = in.retain(0); sink(out); // $ hasValueFlow } + { + // "io.netty.util;ReferenceCounted;true;retain;;;Argument[-1];ReturnValue;value;manual" + BinaryWebSocketFrame out = null; + BinaryWebSocketFrame in = (BinaryWebSocketFrame)source(); + out = in.retain(); + sink(out); // $ hasValueFlow + } + { + // "io.netty.util;ReferenceCounted;true;retain;;;Argument[-1];ReturnValue;value;manual" + BinaryWebSocketFrame out = null; + BinaryWebSocketFrame in = (BinaryWebSocketFrame)source(); + out = in.retain(0); + sink(out); // $ hasValueFlow + } { // "io.netty.util;ReferenceCounted;true;retain;;;Argument[-1];ReturnValue;value;manual" ByteBuf out = null; @@ -6024,6 +7448,34 @@ public class Test { out = in.retain(0); sink(out); // $ hasValueFlow } + { + // "io.netty.util;ReferenceCounted;true;retain;;;Argument[-1];ReturnValue;value;manual" + PingWebSocketFrame out = null; + PingWebSocketFrame in = (PingWebSocketFrame)source(); + out = in.retain(); + sink(out); // $ hasValueFlow + } + { + // "io.netty.util;ReferenceCounted;true;retain;;;Argument[-1];ReturnValue;value;manual" + PingWebSocketFrame out = null; + PingWebSocketFrame in = (PingWebSocketFrame)source(); + out = in.retain(0); + sink(out); // $ hasValueFlow + } + { + // "io.netty.util;ReferenceCounted;true;retain;;;Argument[-1];ReturnValue;value;manual" + PongWebSocketFrame out = null; + PongWebSocketFrame in = (PongWebSocketFrame)source(); + out = in.retain(); + sink(out); // $ hasValueFlow + } + { + // "io.netty.util;ReferenceCounted;true;retain;;;Argument[-1];ReturnValue;value;manual" + PongWebSocketFrame out = null; + PongWebSocketFrame in = (PongWebSocketFrame)source(); + out = in.retain(0); + sink(out); // $ hasValueFlow + } { // "io.netty.util;ReferenceCounted;true;retain;;;Argument[-1];ReturnValue;value;manual" ReferenceCounted out = null; @@ -6094,6 +7546,20 @@ public class Test { out = in.touch(null); sink(out); // $ hasValueFlow } + { + // "io.netty.util;ReferenceCounted;true;touch;;;Argument[-1];ReturnValue;value;manual" + BinaryWebSocketFrame out = null; + BinaryWebSocketFrame in = (BinaryWebSocketFrame)source(); + out = in.touch(); + sink(out); // $ hasValueFlow + } + { + // "io.netty.util;ReferenceCounted;true;touch;;;Argument[-1];ReturnValue;value;manual" + BinaryWebSocketFrame out = null; + BinaryWebSocketFrame in = (BinaryWebSocketFrame)source(); + out = in.touch(null); + sink(out); // $ hasValueFlow + } { // "io.netty.util;ReferenceCounted;true;touch;;;Argument[-1];ReturnValue;value;manual" ByteBuf out = null; @@ -6346,6 +7812,34 @@ public class Test { out = in.touch(null); sink(out); // $ hasValueFlow } + { + // "io.netty.util;ReferenceCounted;true;touch;;;Argument[-1];ReturnValue;value;manual" + PingWebSocketFrame out = null; + PingWebSocketFrame in = (PingWebSocketFrame)source(); + out = in.touch(); + sink(out); // $ hasValueFlow + } + { + // "io.netty.util;ReferenceCounted;true;touch;;;Argument[-1];ReturnValue;value;manual" + PingWebSocketFrame out = null; + PingWebSocketFrame in = (PingWebSocketFrame)source(); + out = in.touch(null); + sink(out); // $ hasValueFlow + } + { + // "io.netty.util;ReferenceCounted;true;touch;;;Argument[-1];ReturnValue;value;manual" + PongWebSocketFrame out = null; + PongWebSocketFrame in = (PongWebSocketFrame)source(); + out = in.touch(); + sink(out); // $ hasValueFlow + } + { + // "io.netty.util;ReferenceCounted;true;touch;;;Argument[-1];ReturnValue;value;manual" + PongWebSocketFrame out = null; + PongWebSocketFrame in = (PongWebSocketFrame)source(); + out = in.touch(null); + sink(out); // $ hasValueFlow + } { // "io.netty.util;ReferenceCounted;true;touch;;;Argument[-1];ReturnValue;value;manual" ReferenceCounted out = null; diff --git a/java/ql/test/library-tests/frameworks/netty/generated/test.ext.yml b/java/ql/test/library-tests/frameworks/netty/generated/test.ext.yml new file mode 100644 index 00000000000..f6b69f08632 --- /dev/null +++ b/java/ql/test/library-tests/frameworks/netty/generated/test.ext.yml @@ -0,0 +1,11 @@ +extensions: + - addsTo: + pack: codeql/java-tests + extensible: summaryModel + 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, "newWithElementDefault", "(Object)", "", "Argument[0]", "ReturnValue.Element", "value", "manual"] + - ["generatedtest", "Test", False, "getMapValueDefault", "(Object)", "", "Argument[0].MapValue", "ReturnValue", "value", "manual"] + - ["generatedtest", "Test", False, "getMapKeyDefault", "(Object)", "", "Argument[0].MapKey", "ReturnValue", "value", "manual"] + - ["generatedtest", "Test", False, "getElementDefault", "(Object)", "", "Argument[0].Element", "ReturnValue", "value", "manual"] diff --git a/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http/cookie/CookieEncoder.java b/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http/cookie/CookieEncoder.java new file mode 100644 index 00000000000..0f0b2b414b7 --- /dev/null +++ b/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http/cookie/CookieEncoder.java @@ -0,0 +1,12 @@ +// Generated automatically from io.netty.handler.codec.http.cookie.CookieEncoder for testing purposes + +package io.netty.handler.codec.http.cookie; + + +abstract public class CookieEncoder +{ + protected CookieEncoder() {} + protected CookieEncoder(boolean p0){} + protected final boolean strict = false; + protected void validateCookie(String p0, String p1){} +} diff --git a/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http/cookie/ServerCookieEncoder.java b/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http/cookie/ServerCookieEncoder.java new file mode 100644 index 00000000000..21c0dfd7c8e --- /dev/null +++ b/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http/cookie/ServerCookieEncoder.java @@ -0,0 +1,20 @@ +// Generated automatically from io.netty.handler.codec.http.cookie.ServerCookieEncoder for testing purposes + +package io.netty.handler.codec.http.cookie; + +import io.netty.handler.codec.http.cookie.Cookie; +import io.netty.handler.codec.http.cookie.CookieEncoder; +import java.util.Collection; +import java.util.List; + +public class ServerCookieEncoder extends CookieEncoder +{ + protected ServerCookieEncoder() {} + public List<String> encode(Collection<? extends Cookie> p0){ return null; } + public List<String> encode(Cookie... p0){ return null; } + public List<String> encode(Iterable<? extends Cookie> p0){ return null; } + public String encode(Cookie p0){ return null; } + public String encode(String p0, String p1){ return null; } + public static ServerCookieEncoder LAX = null; + public static ServerCookieEncoder STRICT = null; +} diff --git a/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http/websocketx/BinaryWebSocketFrame.java b/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http/websocketx/BinaryWebSocketFrame.java new file mode 100644 index 00000000000..8ca9ea4ad93 --- /dev/null +++ b/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http/websocketx/BinaryWebSocketFrame.java @@ -0,0 +1,21 @@ +// Generated automatically from io.netty.handler.codec.http.websocketx.BinaryWebSocketFrame for testing purposes + +package io.netty.handler.codec.http.websocketx; + +import io.netty.buffer.ByteBuf; +import io.netty.handler.codec.http.websocketx.WebSocketFrame; + +public class BinaryWebSocketFrame extends WebSocketFrame +{ + public BinaryWebSocketFrame copy(){ return null; } + public BinaryWebSocketFrame duplicate(){ return null; } + public BinaryWebSocketFrame replace(ByteBuf p0){ return null; } + public BinaryWebSocketFrame retain(){ return null; } + public BinaryWebSocketFrame retain(int p0){ return null; } + public BinaryWebSocketFrame retainedDuplicate(){ return null; } + public BinaryWebSocketFrame touch(){ return null; } + public BinaryWebSocketFrame touch(Object p0){ return null; } + public BinaryWebSocketFrame(){} + public BinaryWebSocketFrame(ByteBuf p0){} + public BinaryWebSocketFrame(boolean p0, int p1, ByteBuf p2){} +} diff --git a/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http/websocketx/PingWebSocketFrame.java b/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http/websocketx/PingWebSocketFrame.java new file mode 100644 index 00000000000..f860f0ee9a2 --- /dev/null +++ b/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http/websocketx/PingWebSocketFrame.java @@ -0,0 +1,21 @@ +// Generated automatically from io.netty.handler.codec.http.websocketx.PingWebSocketFrame for testing purposes + +package io.netty.handler.codec.http.websocketx; + +import io.netty.buffer.ByteBuf; +import io.netty.handler.codec.http.websocketx.WebSocketFrame; + +public class PingWebSocketFrame extends WebSocketFrame +{ + public PingWebSocketFrame copy(){ return null; } + public PingWebSocketFrame duplicate(){ return null; } + public PingWebSocketFrame replace(ByteBuf p0){ return null; } + public PingWebSocketFrame retain(){ return null; } + public PingWebSocketFrame retain(int p0){ return null; } + public PingWebSocketFrame retainedDuplicate(){ return null; } + public PingWebSocketFrame touch(){ return null; } + public PingWebSocketFrame touch(Object p0){ return null; } + public PingWebSocketFrame(){} + public PingWebSocketFrame(ByteBuf p0){} + public PingWebSocketFrame(boolean p0, int p1, ByteBuf p2){} +} diff --git a/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http/websocketx/PongWebSocketFrame.java b/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http/websocketx/PongWebSocketFrame.java new file mode 100644 index 00000000000..548ebf5abb9 --- /dev/null +++ b/java/ql/test/stubs/netty-4.1.x/io/netty/handler/codec/http/websocketx/PongWebSocketFrame.java @@ -0,0 +1,21 @@ +// Generated automatically from io.netty.handler.codec.http.websocketx.PongWebSocketFrame for testing purposes + +package io.netty.handler.codec.http.websocketx; + +import io.netty.buffer.ByteBuf; +import io.netty.handler.codec.http.websocketx.WebSocketFrame; + +public class PongWebSocketFrame extends WebSocketFrame +{ + public PongWebSocketFrame copy(){ return null; } + public PongWebSocketFrame duplicate(){ return null; } + public PongWebSocketFrame replace(ByteBuf p0){ return null; } + public PongWebSocketFrame retain(){ return null; } + public PongWebSocketFrame retain(int p0){ return null; } + public PongWebSocketFrame retainedDuplicate(){ return null; } + public PongWebSocketFrame touch(){ return null; } + public PongWebSocketFrame touch(Object p0){ return null; } + public PongWebSocketFrame(){} + public PongWebSocketFrame(ByteBuf p0){} + public PongWebSocketFrame(boolean p0, int p1, ByteBuf p2){} +} From 56fb3d23ff202385aed059d7e4f0e5470c06097e Mon Sep 17 00:00:00 2001 From: Joe Farebrother <joefarebrother@github.com> Date: Tue, 21 Mar 2023 11:53:49 +0000 Subject: [PATCH 378/631] Argument[-1] -> Argument[this] --- java/ql/lib/ext/io.netty.buffer.model.yml | 318 +++++++++--------- ....netty.handler.codec.http.cookie.model.yml | 14 +- .../ext/io.netty.handler.codec.http.model.yml | 124 +++---- ...tty.handler.codec.http.multipart.model.yml | 66 ++-- ...ty.handler.codec.http.websocketx.model.yml | 40 +-- .../io.netty.handler.codec.http2.model.yml | 36 +- .../lib/ext/io.netty.handler.codec.model.yml | 150 ++++----- java/ql/lib/ext/io.netty.util.model.yml | 36 +- 8 files changed, 392 insertions(+), 392 deletions(-) diff --git a/java/ql/lib/ext/io.netty.buffer.model.yml b/java/ql/lib/ext/io.netty.buffer.model.yml index ae1074f6ddc..81474a784f2 100644 --- a/java/ql/lib/ext/io.netty.buffer.model.yml +++ b/java/ql/lib/ext/io.netty.buffer.model.yml @@ -3,163 +3,163 @@ extensions: pack: codeql/java-all extensible: summaryModel data: - - ["io.netty.buffer", "ByteBufConvertible", True, "asByteBuf", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "array", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "asReadOnly", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "capacity", "(int)", "", "Argument[-1]", "ReturnValue", "value", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "copy", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "discardReadBytes", "()", "", "Argument[-1]", "ReturnValue", "value", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "discardSomeReadBytes", "()", "", "Argument[-1]", "ReturnValue", "value", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "duplicate", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "ensureWritable", "(int)", "", "Argument[-1]", "ReturnValue", "value", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "getBytes", "(int,byte[])", "", "Argument[-1]", "ReturnValue", "value", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "getBytes", "(int,byte[],int,int)", "", "Argument[-1]", "ReturnValue", "value", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "getBytes", "(int,ByteBuf)", "", "Argument[-1]", "ReturnValue", "value", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "getBytes", "(int,ByteBuffer)", "", "Argument[-1]", "ReturnValue", "value", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "getBytes", "(int,ByteBuf,int)", "", "Argument[-1]", "ReturnValue", "value", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "getBytes", "(int,ByteBuf,int,int)", "", "Argument[-1]", "ReturnValue", "value", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "getBytes", "(int,OutputStream,int)", "", "Argument[-1]", "ReturnValue", "value", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "markReaderIndex", "()", "", "Argument[-1]", "ReturnValue", "value", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "markWriterIndex", "()", "", "Argument[-1]", "ReturnValue", "value", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "nioBuffer", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "nioBuffers", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "order", "(ByteOrder)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "readBytes", "(byte[])", "", "Argument[-1]", "ReturnValue", "value", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "readBytes", "(byte[],int,int)", "", "Argument[-1]", "ReturnValue", "value", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "readBytes", "(ByteBuf)", "", "Argument[-1]", "ReturnValue", "value", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "readBytes", "(ByteBuffer)", "", "Argument[-1]", "ReturnValue", "value", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "readBytes", "(ByteBuf,int)", "", "Argument[-1]", "ReturnValue", "value", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "readBytes", "(ByteBuf,int,int)", "", "Argument[-1]", "ReturnValue", "value", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "readBytes", "(OutputStream,int)", "", "Argument[-1]", "ReturnValue", "value", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "readerIndex", "(int)", "", "Argument[-1]", "ReturnValue", "value", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "resetReaderIndex", "()", "", "Argument[-1]", "ReturnValue", "value", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "resetWriterIndex", "()", "", "Argument[-1]", "ReturnValue", "value", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "retainedDuplicate", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "retainedSlice", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "setBoolean", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "setByte", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "setBytes", "(int,byte[])", "", "Argument[-1]", "ReturnValue", "value", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "setBytes", "(int,byte[],int,int)", "", "Argument[-1]", "ReturnValue", "value", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "setBytes", "(int,ByteBuf)", "", "Argument[-1]", "ReturnValue", "value", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "setBytes", "(int,ByteBuffer)", "", "Argument[-1]", "ReturnValue", "value", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "setBytes", "(int,ByteBuf,int)", "", "Argument[-1]", "ReturnValue", "value", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "setBytes", "(int,ByteBuf,int,int)", "", "Argument[-1]", "ReturnValue", "value", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "setChar", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "setDouble", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "setDoubleLE", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "setFloat", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "setFloatLE", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "setIndex", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "setInt", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "setIntLE", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "setLong", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "setLongLE", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "setMedium", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "setMediumLE", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "setShort", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "setShortLE", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "setZero", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "skipBytes", "(int)", "", "Argument[-1]", "ReturnValue", "value", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "slice", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "toString", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "unwrap", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "writeBoolean", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "writeByte", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "writeBytes", "(byte[])", "", "Argument[-1]", "ReturnValue", "value", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "writeBytes", "(byte[],int,int)", "", "Argument[-1]", "ReturnValue", "value", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "writeBytes", "(ByteBuf)", "", "Argument[-1]", "ReturnValue", "value", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "writeBytes", "(ByteBuffer)", "", "Argument[-1]", "ReturnValue", "value", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "writeBytes", "(ByteBuf,int)", "", "Argument[-1]", "ReturnValue", "value", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "writeBytes", "(ByteBuf,int,int)", "", "Argument[-1]", "ReturnValue", "value", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "writeChar", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "writeDouble", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "writeDoubleLE", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "writeFloat", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "writeFloatLE", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "writeInt", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "writeIntLE", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "writeLong", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "writeLongLE", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "writeMedium", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "writeMediumLE", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "writeShort", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "writeShortLE", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "writeZero", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "writerIndex", "(int)", "", "Argument[-1]", "ReturnValue", "value", "manual"] - - ["io.netty.buffer", "ByteBufHolder", True, "copy", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.buffer", "ByteBufHolder", True, "content", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.buffer", "ByteBufHolder", True, "duplicate", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.buffer", "ByteBufHolder", True, "retainedDuplicate", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.buffer", "ByteBufConvertible", True, "asByteBuf", "()", "", "Argument[this]", "ReturnValue", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "array", "()", "", "Argument[this]", "ReturnValue", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "asReadOnly", "()", "", "Argument[this]", "ReturnValue", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "capacity", "(int)", "", "Argument[this]", "ReturnValue", "value", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "copy", "", "", "Argument[this]", "ReturnValue", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "discardReadBytes", "()", "", "Argument[this]", "ReturnValue", "value", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "discardSomeReadBytes", "()", "", "Argument[this]", "ReturnValue", "value", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "duplicate", "()", "", "Argument[this]", "ReturnValue", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "ensureWritable", "(int)", "", "Argument[this]", "ReturnValue", "value", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "getBytes", "(int,byte[])", "", "Argument[this]", "ReturnValue", "value", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "getBytes", "(int,byte[],int,int)", "", "Argument[this]", "ReturnValue", "value", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "getBytes", "(int,ByteBuf)", "", "Argument[this]", "ReturnValue", "value", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "getBytes", "(int,ByteBuffer)", "", "Argument[this]", "ReturnValue", "value", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "getBytes", "(int,ByteBuf,int)", "", "Argument[this]", "ReturnValue", "value", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "getBytes", "(int,ByteBuf,int,int)", "", "Argument[this]", "ReturnValue", "value", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "getBytes", "(int,OutputStream,int)", "", "Argument[this]", "ReturnValue", "value", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "markReaderIndex", "()", "", "Argument[this]", "ReturnValue", "value", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "markWriterIndex", "()", "", "Argument[this]", "ReturnValue", "value", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "nioBuffer", "", "", "Argument[this]", "ReturnValue", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "nioBuffers", "", "", "Argument[this]", "ReturnValue", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "order", "(ByteOrder)", "", "Argument[this]", "ReturnValue", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "readBytes", "(byte[])", "", "Argument[this]", "ReturnValue", "value", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "readBytes", "(byte[],int,int)", "", "Argument[this]", "ReturnValue", "value", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "readBytes", "(ByteBuf)", "", "Argument[this]", "ReturnValue", "value", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "readBytes", "(ByteBuffer)", "", "Argument[this]", "ReturnValue", "value", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "readBytes", "(ByteBuf,int)", "", "Argument[this]", "ReturnValue", "value", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "readBytes", "(ByteBuf,int,int)", "", "Argument[this]", "ReturnValue", "value", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "readBytes", "(OutputStream,int)", "", "Argument[this]", "ReturnValue", "value", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "readerIndex", "(int)", "", "Argument[this]", "ReturnValue", "value", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "resetReaderIndex", "()", "", "Argument[this]", "ReturnValue", "value", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "resetWriterIndex", "()", "", "Argument[this]", "ReturnValue", "value", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "retainedDuplicate", "()", "", "Argument[this]", "ReturnValue", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "retainedSlice", "", "", "Argument[this]", "ReturnValue", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "setBoolean", "", "", "Argument[this]", "ReturnValue", "value", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "setByte", "", "", "Argument[this]", "ReturnValue", "value", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "setBytes", "(int,byte[])", "", "Argument[this]", "ReturnValue", "value", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "setBytes", "(int,byte[],int,int)", "", "Argument[this]", "ReturnValue", "value", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "setBytes", "(int,ByteBuf)", "", "Argument[this]", "ReturnValue", "value", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "setBytes", "(int,ByteBuffer)", "", "Argument[this]", "ReturnValue", "value", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "setBytes", "(int,ByteBuf,int)", "", "Argument[this]", "ReturnValue", "value", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "setBytes", "(int,ByteBuf,int,int)", "", "Argument[this]", "ReturnValue", "value", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "setChar", "", "", "Argument[this]", "ReturnValue", "value", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "setDouble", "", "", "Argument[this]", "ReturnValue", "value", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "setDoubleLE", "", "", "Argument[this]", "ReturnValue", "value", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "setFloat", "", "", "Argument[this]", "ReturnValue", "value", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "setFloatLE", "", "", "Argument[this]", "ReturnValue", "value", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "setIndex", "", "", "Argument[this]", "ReturnValue", "value", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "setInt", "", "", "Argument[this]", "ReturnValue", "value", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "setIntLE", "", "", "Argument[this]", "ReturnValue", "value", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "setLong", "", "", "Argument[this]", "ReturnValue", "value", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "setLongLE", "", "", "Argument[this]", "ReturnValue", "value", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "setMedium", "", "", "Argument[this]", "ReturnValue", "value", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "setMediumLE", "", "", "Argument[this]", "ReturnValue", "value", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "setShort", "", "", "Argument[this]", "ReturnValue", "value", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "setShortLE", "", "", "Argument[this]", "ReturnValue", "value", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "setZero", "", "", "Argument[this]", "ReturnValue", "value", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "skipBytes", "(int)", "", "Argument[this]", "ReturnValue", "value", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "slice", "", "", "Argument[this]", "ReturnValue", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "toString", "", "", "Argument[this]", "ReturnValue", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "unwrap", "()", "", "Argument[this]", "ReturnValue", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "writeBoolean", "", "", "Argument[this]", "ReturnValue", "value", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "writeByte", "", "", "Argument[this]", "ReturnValue", "value", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "writeBytes", "(byte[])", "", "Argument[this]", "ReturnValue", "value", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "writeBytes", "(byte[],int,int)", "", "Argument[this]", "ReturnValue", "value", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "writeBytes", "(ByteBuf)", "", "Argument[this]", "ReturnValue", "value", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "writeBytes", "(ByteBuffer)", "", "Argument[this]", "ReturnValue", "value", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "writeBytes", "(ByteBuf,int)", "", "Argument[this]", "ReturnValue", "value", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "writeBytes", "(ByteBuf,int,int)", "", "Argument[this]", "ReturnValue", "value", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "writeChar", "", "", "Argument[this]", "ReturnValue", "value", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "writeDouble", "", "", "Argument[this]", "ReturnValue", "value", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "writeDoubleLE", "", "", "Argument[this]", "ReturnValue", "value", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "writeFloat", "", "", "Argument[this]", "ReturnValue", "value", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "writeFloatLE", "", "", "Argument[this]", "ReturnValue", "value", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "writeInt", "", "", "Argument[this]", "ReturnValue", "value", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "writeIntLE", "", "", "Argument[this]", "ReturnValue", "value", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "writeLong", "", "", "Argument[this]", "ReturnValue", "value", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "writeLongLE", "", "", "Argument[this]", "ReturnValue", "value", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "writeMedium", "", "", "Argument[this]", "ReturnValue", "value", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "writeMediumLE", "", "", "Argument[this]", "ReturnValue", "value", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "writeShort", "", "", "Argument[this]", "ReturnValue", "value", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "writeShortLE", "", "", "Argument[this]", "ReturnValue", "value", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "writeZero", "", "", "Argument[this]", "ReturnValue", "value", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "writerIndex", "(int)", "", "Argument[this]", "ReturnValue", "value", "manual"] + - ["io.netty.buffer", "ByteBufHolder", True, "copy", "()", "", "Argument[this]", "ReturnValue", "taint", "manual"] + - ["io.netty.buffer", "ByteBufHolder", True, "content", "()", "", "Argument[this]", "ReturnValue", "taint", "manual"] + - ["io.netty.buffer", "ByteBufHolder", True, "duplicate", "()", "", "Argument[this]", "ReturnValue", "taint", "manual"] + - ["io.netty.buffer", "ByteBufHolder", True, "retainedDuplicate", "()", "", "Argument[this]", "ReturnValue", "taint", "manual"] - ["io.netty.buffer", "ByteBufHolder", True, "replace", "(ByteBuf)", "", "Argument[0]", "ReturnValue", "taint", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "getBytes", "(int,byte[])", "", "Argument[-1]", "Argument[1]", "taint", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "getBytes", "(int,byte[],int,int)", "", "Argument[-1]", "Argument[1]", "taint", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "getBytes", "(int,ByteBuf)", "", "Argument[-1]", "Argument[1]", "taint", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "getBytes", "(int,ByteBuffer)", "", "Argument[-1]", "Argument[1]", "taint", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "getBytes", "(int,ByteBuf,int)", "", "Argument[-1]", "Argument[1]", "taint", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "getBytes", "(int,ByteBuf,int,int)", "", "Argument[-1]", "Argument[1]", "taint", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "getBytes", "(int,FileChannel,long,int)", "", "Argument[-1]", "Argument[1]", "taint", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "getBytes", "(int,GatheringByteChannel,int)", "", "Argument[-1]", "Argument[1]", "taint", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "getBytes", "(int,OutputStream,int)", "", "Argument[-1]", "Argument[1]", "taint", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "getChar", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "getCharSequence", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "readBytes", "(byte[])", "", "Argument[-1]", "Argument[0]", "taint", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "readBytes", "(byte[],int,int)", "", "Argument[-1]", "Argument[0]", "taint", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "readBytes", "(ByteBuf)", "", "Argument[-1]", "Argument[0]", "taint", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "readBytes", "(ByteBuffer)", "", "Argument[-1]", "Argument[0]", "taint", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "readBytes", "(ByteBuf,int)", "", "Argument[-1]", "Argument[0]", "taint", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "readBytes", "(ByteBuf,int,int)", "", "Argument[-1]", "Argument[0]", "taint", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "readBytes", "(FileChannel,long,int)", "", "Argument[-1]", "Argument[0]", "taint", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "readBytes", "(GatheringByteChannel,int)", "", "Argument[-1]", "Argument[0]", "taint", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "readBytes", "(OutputStream,int)", "", "Argument[-1]", "Argument[0]", "taint", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "readBytes", "(int)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "readChar", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "readCharSequence", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "readSlice", "(int)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "readRetainedSlice", "(int)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "setBytes", "(int,byte[])", "", "Argument[1]", "Argument[-1]", "taint", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "setBytes", "(int,byte[],int,int)", "", "Argument[1]", "Argument[-1]", "taint", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "setBytes", "(int,ByteBuf)", "", "Argument[1]", "Argument[-1]", "taint", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "setBytes", "(int,ByteBuffer)", "", "Argument[1]", "Argument[-1]", "taint", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "setBytes", "(int,ByteBuf,int)", "", "Argument[1]", "Argument[-1]", "taint", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "setBytes", "(int,ByteBuf,int,int)", "", "Argument[1]", "Argument[-1]", "taint", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "setBytes", "(int,FileChannel,long,int)", "", "Argument[1]", "Argument[-1]", "taint", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "setBytes", "(int,ScatteringByteChannel,int)", "", "Argument[1]", "Argument[-1]", "taint", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "setBytes", "(int,InputStream,int)", "", "Argument[1]", "Argument[-1]", "taint", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "setChar", "", "", "Argument[1]", "Argument[-1]", "taint", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "setCharSequence", "", "", "Argument[1]", "Argument[-1]", "taint", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "writeByte", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "writeBytes", "(byte[])", "", "Argument[0]", "Argument[-1]", "taint", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "writeBytes", "(byte[],int,int)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "writeBytes", "(ByteBuf)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "writeBytes", "(ByteBuffer)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "writeBytes", "(ByteBuf,int)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "writeBytes", "(ByteBuf,int,int)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "writeBytes", "(FileChannel,long,int)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "writeBytes", "(ScatteringByteChannel,int)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "writeBytes", "(InputStream,int)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "writeChar", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] - - ["io.netty.buffer", "ByteBuf", True, "writeCharSequence", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] - - ["io.netty.buffer", "CompositeByteBuf", False, "CompositeByteBuf", "(ByteBufAllocator,boolean,int,ByteBuf[])", "", "Argument[3].ArrayElement", "Argument[-1]", "taint", "manual"] - - ["io.netty.buffer", "CompositeByteBuf", False, "CompositeByteBuf", "(ByteBufAllocator,boolean,int,Iterable)", "", "Argument[3].Element", "Argument[-1]", "taint", "manual"] - - ["io.netty.buffer", "CompositeByteBuf", True, "addComponent", "(ByteBuf)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] - - ["io.netty.buffer", "CompositeByteBuf", True, "addComponent", "(int,ByteBuf)", "", "Argument[1]", "Argument[-1]", "taint", "manual"] - - ["io.netty.buffer", "CompositeByteBuf", True, "addComponent", "(boolean,ByteBuf)", "", "Argument[1]", "Argument[-1]", "taint", "manual"] - - ["io.netty.buffer", "CompositeByteBuf", True, "addComponent", "(boolean,int,ByteBuf)", "", "Argument[2]", "Argument[-1]", "taint", "manual"] - - ["io.netty.buffer", "CompositeByteBuf", True, "addComponents", "(ByteBuf[])", "", "Argument[0].ArrayElement", "Argument[-1]", "taint", "manual"] - - ["io.netty.buffer", "CompositeByteBuf", True, "addComponents", "(int,ByteBuf[])", "", "Argument[1].ArrayElement", "Argument[-1]", "taint", "manual"] - - ["io.netty.buffer", "CompositeByteBuf", True, "addComponents", "(boolean,ByteBuf[])", "", "Argument[1].ArrayElement", "Argument[-1]", "taint", "manual"] - - ["io.netty.buffer", "CompositeByteBuf", True, "addComponents", "(Iterable)", "", "Argument[0].Element", "Argument[-1]", "taint", "manual"] - - ["io.netty.buffer", "CompositeByteBuf", True, "addComponents", "(int,Iterable)", "", "Argument[1].Element", "Argument[-1]", "taint", "manual"] - - ["io.netty.buffer", "CompositeByteBuf", True, "addComponents", "(boolean,Iterable)", "", "Argument[1].Element", "Argument[-1]", "taint", "manual"] - - ["io.netty.buffer", "CompositeByteBuf", True, "addFlattenedComponents", "(boolean,ByteBuf)", "", "Argument[1]", "Argument[-1]", "taint", "manual"] - - ["io.netty.buffer", "CompositeByteBuf", True, "addComponent", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] - - ["io.netty.buffer", "CompositeByteBuf", True, "addComponents", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] - - ["io.netty.buffer", "CompositeByteBuf", True, "addFlattenedComponents", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] - - ["io.netty.buffer", "CompositeByteBuf", True, "component", "(int)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.buffer", "CompositeByteBuf", True, "componentAtOffset", "(int)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.buffer", "CompositeByteBuf", True, "consolidate", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.buffer", "CompositeByteBuf", True, "consolidate", "(int,int)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.buffer", "CompositeByteBuf", True, "decompose", "(int,int)", "", "Argument[-1]", "ReturnValue.Element", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "getBytes", "(int,byte[])", "", "Argument[this]", "Argument[1]", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "getBytes", "(int,byte[],int,int)", "", "Argument[this]", "Argument[1]", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "getBytes", "(int,ByteBuf)", "", "Argument[this]", "Argument[1]", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "getBytes", "(int,ByteBuffer)", "", "Argument[this]", "Argument[1]", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "getBytes", "(int,ByteBuf,int)", "", "Argument[this]", "Argument[1]", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "getBytes", "(int,ByteBuf,int,int)", "", "Argument[this]", "Argument[1]", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "getBytes", "(int,FileChannel,long,int)", "", "Argument[this]", "Argument[1]", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "getBytes", "(int,GatheringByteChannel,int)", "", "Argument[this]", "Argument[1]", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "getBytes", "(int,OutputStream,int)", "", "Argument[this]", "Argument[1]", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "getChar", "", "", "Argument[this]", "ReturnValue", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "getCharSequence", "", "", "Argument[this]", "ReturnValue", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "readBytes", "(byte[])", "", "Argument[this]", "Argument[0]", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "readBytes", "(byte[],int,int)", "", "Argument[this]", "Argument[0]", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "readBytes", "(ByteBuf)", "", "Argument[this]", "Argument[0]", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "readBytes", "(ByteBuffer)", "", "Argument[this]", "Argument[0]", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "readBytes", "(ByteBuf,int)", "", "Argument[this]", "Argument[0]", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "readBytes", "(ByteBuf,int,int)", "", "Argument[this]", "Argument[0]", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "readBytes", "(FileChannel,long,int)", "", "Argument[this]", "Argument[0]", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "readBytes", "(GatheringByteChannel,int)", "", "Argument[this]", "Argument[0]", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "readBytes", "(OutputStream,int)", "", "Argument[this]", "Argument[0]", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "readBytes", "(int)", "", "Argument[this]", "ReturnValue", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "readChar", "", "", "Argument[this]", "ReturnValue", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "readCharSequence", "", "", "Argument[this]", "ReturnValue", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "readSlice", "(int)", "", "Argument[this]", "ReturnValue", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "readRetainedSlice", "(int)", "", "Argument[this]", "ReturnValue", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "setBytes", "(int,byte[])", "", "Argument[1]", "Argument[this]", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "setBytes", "(int,byte[],int,int)", "", "Argument[1]", "Argument[this]", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "setBytes", "(int,ByteBuf)", "", "Argument[1]", "Argument[this]", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "setBytes", "(int,ByteBuffer)", "", "Argument[1]", "Argument[this]", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "setBytes", "(int,ByteBuf,int)", "", "Argument[1]", "Argument[this]", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "setBytes", "(int,ByteBuf,int,int)", "", "Argument[1]", "Argument[this]", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "setBytes", "(int,FileChannel,long,int)", "", "Argument[1]", "Argument[this]", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "setBytes", "(int,ScatteringByteChannel,int)", "", "Argument[1]", "Argument[this]", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "setBytes", "(int,InputStream,int)", "", "Argument[1]", "Argument[this]", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "setChar", "", "", "Argument[1]", "Argument[this]", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "setCharSequence", "", "", "Argument[1]", "Argument[this]", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "writeByte", "", "", "Argument[0]", "Argument[this]", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "writeBytes", "(byte[])", "", "Argument[0]", "Argument[this]", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "writeBytes", "(byte[],int,int)", "", "Argument[0]", "Argument[this]", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "writeBytes", "(ByteBuf)", "", "Argument[0]", "Argument[this]", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "writeBytes", "(ByteBuffer)", "", "Argument[0]", "Argument[this]", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "writeBytes", "(ByteBuf,int)", "", "Argument[0]", "Argument[this]", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "writeBytes", "(ByteBuf,int,int)", "", "Argument[0]", "Argument[this]", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "writeBytes", "(FileChannel,long,int)", "", "Argument[0]", "Argument[this]", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "writeBytes", "(ScatteringByteChannel,int)", "", "Argument[0]", "Argument[this]", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "writeBytes", "(InputStream,int)", "", "Argument[0]", "Argument[this]", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "writeChar", "", "", "Argument[0]", "Argument[this]", "taint", "manual"] + - ["io.netty.buffer", "ByteBuf", True, "writeCharSequence", "", "", "Argument[0]", "Argument[this]", "taint", "manual"] + - ["io.netty.buffer", "CompositeByteBuf", False, "CompositeByteBuf", "(ByteBufAllocator,boolean,int,ByteBuf[])", "", "Argument[3].ArrayElement", "Argument[this]", "taint", "manual"] + - ["io.netty.buffer", "CompositeByteBuf", False, "CompositeByteBuf", "(ByteBufAllocator,boolean,int,Iterable)", "", "Argument[3].Element", "Argument[this]", "taint", "manual"] + - ["io.netty.buffer", "CompositeByteBuf", True, "addComponent", "(ByteBuf)", "", "Argument[0]", "Argument[this]", "taint", "manual"] + - ["io.netty.buffer", "CompositeByteBuf", True, "addComponent", "(int,ByteBuf)", "", "Argument[1]", "Argument[this]", "taint", "manual"] + - ["io.netty.buffer", "CompositeByteBuf", True, "addComponent", "(boolean,ByteBuf)", "", "Argument[1]", "Argument[this]", "taint", "manual"] + - ["io.netty.buffer", "CompositeByteBuf", True, "addComponent", "(boolean,int,ByteBuf)", "", "Argument[2]", "Argument[this]", "taint", "manual"] + - ["io.netty.buffer", "CompositeByteBuf", True, "addComponents", "(ByteBuf[])", "", "Argument[0].ArrayElement", "Argument[this]", "taint", "manual"] + - ["io.netty.buffer", "CompositeByteBuf", True, "addComponents", "(int,ByteBuf[])", "", "Argument[1].ArrayElement", "Argument[this]", "taint", "manual"] + - ["io.netty.buffer", "CompositeByteBuf", True, "addComponents", "(boolean,ByteBuf[])", "", "Argument[1].ArrayElement", "Argument[this]", "taint", "manual"] + - ["io.netty.buffer", "CompositeByteBuf", True, "addComponents", "(Iterable)", "", "Argument[0].Element", "Argument[this]", "taint", "manual"] + - ["io.netty.buffer", "CompositeByteBuf", True, "addComponents", "(int,Iterable)", "", "Argument[1].Element", "Argument[this]", "taint", "manual"] + - ["io.netty.buffer", "CompositeByteBuf", True, "addComponents", "(boolean,Iterable)", "", "Argument[1].Element", "Argument[this]", "taint", "manual"] + - ["io.netty.buffer", "CompositeByteBuf", True, "addFlattenedComponents", "(boolean,ByteBuf)", "", "Argument[1]", "Argument[this]", "taint", "manual"] + - ["io.netty.buffer", "CompositeByteBuf", True, "addComponent", "", "", "Argument[this]", "ReturnValue", "value", "manual"] + - ["io.netty.buffer", "CompositeByteBuf", True, "addComponents", "", "", "Argument[this]", "ReturnValue", "value", "manual"] + - ["io.netty.buffer", "CompositeByteBuf", True, "addFlattenedComponents", "", "", "Argument[this]", "ReturnValue", "value", "manual"] + - ["io.netty.buffer", "CompositeByteBuf", True, "component", "(int)", "", "Argument[this]", "ReturnValue", "taint", "manual"] + - ["io.netty.buffer", "CompositeByteBuf", True, "componentAtOffset", "(int)", "", "Argument[this]", "ReturnValue", "taint", "manual"] + - ["io.netty.buffer", "CompositeByteBuf", True, "consolidate", "()", "", "Argument[this]", "ReturnValue", "taint", "manual"] + - ["io.netty.buffer", "CompositeByteBuf", True, "consolidate", "(int,int)", "", "Argument[this]", "ReturnValue", "taint", "manual"] + - ["io.netty.buffer", "CompositeByteBuf", True, "decompose", "(int,int)", "", "Argument[this]", "ReturnValue.Element", "taint", "manual"] - ["io.netty.buffer", "Unpooled", False, "copiedBuffer", "(byte[])", "", "Argument[0]", "ReturnValue", "taint", "manual"] - ["io.netty.buffer", "Unpooled", False, "copiedBuffer", "(byte[][])", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "manual"] - ["io.netty.buffer", "Unpooled", False, "copiedBuffer", "(byte[],int,int)", "", "Argument[0]", "ReturnValue", "taint", "manual"] @@ -207,6 +207,6 @@ extensions: - ["io.netty.buffer", "ByteBufUtil", False, "writeUtf8", "(ByteBuf,CharSequence)", "", "Argument[1]", "Argument[0]", "taint", "manual"] - ["io.netty.buffer", "ByteBufUtil", False, "writeUtf8", "(ByteBuf,CharSequence,int,int)", "", "Argument[1]", "Argument[0]", "taint", "manual"] - ["io.netty.buffer", "ByteBufUtil", False, "writeUtf8", "(ByteBufAllocator,CharSequence)", "", "Argument[1]", "ReturnValue", "taint", "manual"] - - ["io.netty.buffer", "ByteBufInputStream", True, "ByteBufInputStream", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] - - ["io.netty.buffer", "ByteBufOutputStream", True, "ByteBufOutputStream", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] - - ["io.netty.buffer", "ByteBufOutputStream", True, "buffer", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] \ No newline at end of file + - ["io.netty.buffer", "ByteBufInputStream", True, "ByteBufInputStream", "", "", "Argument[0]", "Argument[this]", "taint", "manual"] + - ["io.netty.buffer", "ByteBufOutputStream", True, "ByteBufOutputStream", "", "", "Argument[0]", "Argument[this]", "taint", "manual"] + - ["io.netty.buffer", "ByteBufOutputStream", True, "buffer", "()", "", "Argument[this]", "ReturnValue", "taint", "manual"] \ No newline at end of file diff --git a/java/ql/lib/ext/io.netty.handler.codec.http.cookie.model.yml b/java/ql/lib/ext/io.netty.handler.codec.http.cookie.model.yml index c770d95a2bf..f8b189be18d 100644 --- a/java/ql/lib/ext/io.netty.handler.codec.http.cookie.model.yml +++ b/java/ql/lib/ext/io.netty.handler.codec.http.cookie.model.yml @@ -3,13 +3,13 @@ extensions: pack: codeql/java-all extensible: summaryModel data: - - ["io.netty.handler.codec.http.cookie", "Cookie", True, "domain", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.handler.codec.http.cookie", "Cookie", True, "name", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.handler.codec.http.cookie", "Cookie", True, "path", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.handler.codec.http.cookie", "Cookie", True, "value", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.handler.codec.http.cookie", "Cookie", True, "setDomain", "(String)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] - - ["io.netty.handler.codec.http.cookie", "Cookie", True, "setPath", "(String)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] - - ["io.netty.handler.codec.http.cookie", "Cookie", True, "setValue", "(String)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["io.netty.handler.codec.http.cookie", "Cookie", True, "domain", "()", "", "Argument[this]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http.cookie", "Cookie", True, "name", "()", "", "Argument[this]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http.cookie", "Cookie", True, "path", "()", "", "Argument[this]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http.cookie", "Cookie", True, "value", "()", "", "Argument[this]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http.cookie", "Cookie", True, "setDomain", "(String)", "", "Argument[0]", "Argument[this]", "taint", "manual"] + - ["io.netty.handler.codec.http.cookie", "Cookie", True, "setPath", "(String)", "", "Argument[0]", "Argument[this]", "taint", "manual"] + - ["io.netty.handler.codec.http.cookie", "Cookie", True, "setValue", "(String)", "", "Argument[0]", "Argument[this]", "taint", "manual"] - ["io.netty.handler.codec.http.cookie", "ServerCookieDecoder", True, "decode", "(String)", "", "Argument[0]", "ReturnValue.Element", "taint", "manual"] - ["io.netty.handler.codec.http.cookie", "ServerCookieDecoder", True, "decodeAll", "(String)", "", "Argument[0]", "ReturnValue.Element", "taint", "manual"] - ["io.netty.handler.codec.http.cookie", "ServerCookieEncoder", True, "encode", "(Cookie)", "", "Argument[0]", "ReturnValue", "taint", "manual"] diff --git a/java/ql/lib/ext/io.netty.handler.codec.http.model.yml b/java/ql/lib/ext/io.netty.handler.codec.http.model.yml index 53cd74eb0b3..657ae39f44c 100644 --- a/java/ql/lib/ext/io.netty.handler.codec.http.model.yml +++ b/java/ql/lib/ext/io.netty.handler.codec.http.model.yml @@ -10,73 +10,73 @@ extensions: extensible: summaryModel data: - ["io.netty.handler.codec.http", "QueryStringEncoder", True, "QueryStringEncoder", "(String)", "", "Argument[0]", "Argument[this]", "taint", "ai-generated"] - - ["io.netty.handler.codec.http", "HttpHeaders", True, "add", "(CharSequence,Iterable)", "", "Argument[0]", "Argument[-1].Element.MapKey", "taint", "manual"] - - ["io.netty.handler.codec.http", "HttpHeaders", True, "add", "(CharSequence,Iterable)", "", "Argument[1].Element", "Argument[-1].Element.MapValue", "taint", "manual"] - - ["io.netty.handler.codec.http", "HttpHeaders", True, "add", "(CharSequence,Object)", "", "Argument[0]", "Argument[-1].Element.MapKey", "taint", "manual"] - - ["io.netty.handler.codec.http", "HttpHeaders", True, "add", "(CharSequence,Object)", "", "Argument[1]", "Argument[-1].Element.MapValue", "taint", "manual"] - - ["io.netty.handler.codec.http", "HttpHeaders", True, "add", "(String,Iterable)", "", "Argument[0]", "Argument[-1].Element.MapKey", "value", "manual"] - - ["io.netty.handler.codec.http", "HttpHeaders", True, "add", "(String,Iterable)", "", "Argument[1].Element", "Argument[-1].Element.MapValue", "taint", "manual"] - - ["io.netty.handler.codec.http", "HttpHeaders", True, "add", "(String,Object)", "", "Argument[0]", "Argument[-1].Element.MapKey", "value", "manual"] - - ["io.netty.handler.codec.http", "HttpHeaders", True, "add", "(String,Object)", "", "Argument[1]", "Argument[-1].Element.MapValue", "taint", "manual"] - - ["io.netty.handler.codec.http", "HttpHeaders", True, "add", "(HttpHeaders)", "", "Argument[0].Element.MapKey", "Argument[-1].Element.MapKey", "value", "manual"] - - ["io.netty.handler.codec.http", "HttpHeaders", True, "add", "(HttpHeaders)", "", "Argument[0].Element.MapValue", "Argument[-1].Element.MapValue", "taint", "manual"] - - ["io.netty.handler.codec.http", "HttpHeaders", True, "addInt", "(CharSequence,int)", "", "Argument[-1]", "ReturnValue", "value", "manual"] - - ["io.netty.handler.codec.http", "HttpHeaders", True, "addInt", "(CharSequence,int)", "", "Argument[0]", "Argument[-1].Element.MapKey", "value", "manual"] - - ["io.netty.handler.codec.http", "HttpHeaders", True, "addShort", "(CharSequence,short)", "", "Argument[-1]", "ReturnValue", "value", "manual"] - - ["io.netty.handler.codec.http", "HttpHeaders", True, "addShort", "(CharSequence,short)", "", "Argument[0]", "Argument[-1].Element.MapKey", "value", "manual"] - - ["io.netty.handler.codec.http", "HttpHeaders", True, "copy", "()", "", "Argument[-1].Element.MapKey", "ReturnValue.Element.MapKey", "value", "manual"] - - ["io.netty.handler.codec.http", "HttpHeaders", True, "copy", "()", "", "Argument[-1].Element.MapValue", "ReturnValue.Element.MapValue", "value", "manual"] - - ["io.netty.handler.codec.http", "HttpHeaders", True, "entries", "()", "", "Argument[-1].Element.MapKey", "ReturnValue.Element.MapKey", "value", "manual"] - - ["io.netty.handler.codec.http", "HttpHeaders", True, "entries", "()", "", "Argument[-1].Element.MapValue", "ReturnValue.Element.MapValue", "value", "manual"] - - ["io.netty.handler.codec.http", "HttpHeaders", True, "get", "", "", "Argument[-1].Element.MapValue", "ReturnValue", "value", "manual"] + - ["io.netty.handler.codec.http", "HttpHeaders", True, "add", "(CharSequence,Iterable)", "", "Argument[0]", "Argument[this].Element.MapKey", "taint", "manual"] + - ["io.netty.handler.codec.http", "HttpHeaders", True, "add", "(CharSequence,Iterable)", "", "Argument[1].Element", "Argument[this].Element.MapValue", "taint", "manual"] + - ["io.netty.handler.codec.http", "HttpHeaders", True, "add", "(CharSequence,Object)", "", "Argument[0]", "Argument[this].Element.MapKey", "taint", "manual"] + - ["io.netty.handler.codec.http", "HttpHeaders", True, "add", "(CharSequence,Object)", "", "Argument[1]", "Argument[this].Element.MapValue", "taint", "manual"] + - ["io.netty.handler.codec.http", "HttpHeaders", True, "add", "(String,Iterable)", "", "Argument[0]", "Argument[this].Element.MapKey", "value", "manual"] + - ["io.netty.handler.codec.http", "HttpHeaders", True, "add", "(String,Iterable)", "", "Argument[1].Element", "Argument[this].Element.MapValue", "taint", "manual"] + - ["io.netty.handler.codec.http", "HttpHeaders", True, "add", "(String,Object)", "", "Argument[0]", "Argument[this].Element.MapKey", "value", "manual"] + - ["io.netty.handler.codec.http", "HttpHeaders", True, "add", "(String,Object)", "", "Argument[1]", "Argument[this].Element.MapValue", "taint", "manual"] + - ["io.netty.handler.codec.http", "HttpHeaders", True, "add", "(HttpHeaders)", "", "Argument[0].Element.MapKey", "Argument[this].Element.MapKey", "value", "manual"] + - ["io.netty.handler.codec.http", "HttpHeaders", True, "add", "(HttpHeaders)", "", "Argument[0].Element.MapValue", "Argument[this].Element.MapValue", "taint", "manual"] + - ["io.netty.handler.codec.http", "HttpHeaders", True, "addInt", "(CharSequence,int)", "", "Argument[this]", "ReturnValue", "value", "manual"] + - ["io.netty.handler.codec.http", "HttpHeaders", True, "addInt", "(CharSequence,int)", "", "Argument[0]", "Argument[this].Element.MapKey", "value", "manual"] + - ["io.netty.handler.codec.http", "HttpHeaders", True, "addShort", "(CharSequence,short)", "", "Argument[this]", "ReturnValue", "value", "manual"] + - ["io.netty.handler.codec.http", "HttpHeaders", True, "addShort", "(CharSequence,short)", "", "Argument[0]", "Argument[this].Element.MapKey", "value", "manual"] + - ["io.netty.handler.codec.http", "HttpHeaders", True, "copy", "()", "", "Argument[this].Element.MapKey", "ReturnValue.Element.MapKey", "value", "manual"] + - ["io.netty.handler.codec.http", "HttpHeaders", True, "copy", "()", "", "Argument[this].Element.MapValue", "ReturnValue.Element.MapValue", "value", "manual"] + - ["io.netty.handler.codec.http", "HttpHeaders", True, "entries", "()", "", "Argument[this].Element.MapKey", "ReturnValue.Element.MapKey", "value", "manual"] + - ["io.netty.handler.codec.http", "HttpHeaders", True, "entries", "()", "", "Argument[this].Element.MapValue", "ReturnValue.Element.MapValue", "value", "manual"] + - ["io.netty.handler.codec.http", "HttpHeaders", True, "get", "", "", "Argument[this].Element.MapValue", "ReturnValue", "value", "manual"] - ["io.netty.handler.codec.http", "HttpHeaders", True, "get", "", "", "Argument[1]", "ReturnValue", "value", "manual"] - - ["io.netty.handler.codec.http", "HttpHeaders", True, "getAll", "", "", "Argument[-1].Element.MapValue", "ReturnValue.Element", "value", "manual"] - - ["io.netty.handler.codec.http", "HttpHeaders", True, "getAllAsString", "", "", "Argument[-1].Element.MapValue", "ReturnValue.Element", "value", "manual"] - - ["io.netty.handler.codec.http", "HttpHeaders", True, "getAsString", "", "", "Argument[-1].Element.MapValue", "ReturnValue", "value", "manual"] + - ["io.netty.handler.codec.http", "HttpHeaders", True, "getAll", "", "", "Argument[this].Element.MapValue", "ReturnValue.Element", "value", "manual"] + - ["io.netty.handler.codec.http", "HttpHeaders", True, "getAllAsString", "", "", "Argument[this].Element.MapValue", "ReturnValue.Element", "value", "manual"] + - ["io.netty.handler.codec.http", "HttpHeaders", True, "getAsString", "", "", "Argument[this].Element.MapValue", "ReturnValue", "value", "manual"] - ["io.netty.handler.codec.http", "HttpHeaders", True, "getHeader", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] - ["io.netty.handler.codec.http", "HttpHeaders", True, "getHeader", "", "", "Argument[2]", "ReturnValue", "value", "manual"] - ["io.netty.handler.codec.http", "HttpHeaders", True, "getHost", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] - ["io.netty.handler.codec.http", "HttpHeaders", True, "getHost", "", "", "Argument[1]", "ReturnValue", "value", "manual"] - - ["io.netty.handler.codec.http", "HttpHeaders", True, "iteratorAsString", "()", "", "Argument[-1].Element.MapKey", "ReturnValue.Element.MapKey", "value", "manual"] - - ["io.netty.handler.codec.http", "HttpHeaders", True, "iteratorAsString", "()", "", "Argument[-1].Element.MapValue", "ReturnValue.Element.MapValue", "value", "manual"] - - ["io.netty.handler.codec.http", "HttpHeaders", True, "iteratorCharSequence", "()", "", "Argument[-1].Element.MapKey", "ReturnValue.Element.MapKey", "taint", "manual"] - - ["io.netty.handler.codec.http", "HttpHeaders", True, "iteratorCharSequence", "()", "", "Argument[-1].Element.MapValue", "ReturnValue.Element.MapValue", "taint", "manual"] - - ["io.netty.handler.codec.http", "HttpHeaders", True, "names", "()", "", "Argument[-1].Element.MapKey", "ReturnValue.Element", "value", "manual"] + - ["io.netty.handler.codec.http", "HttpHeaders", True, "iteratorAsString", "()", "", "Argument[this].Element.MapKey", "ReturnValue.Element.MapKey", "value", "manual"] + - ["io.netty.handler.codec.http", "HttpHeaders", True, "iteratorAsString", "()", "", "Argument[this].Element.MapValue", "ReturnValue.Element.MapValue", "value", "manual"] + - ["io.netty.handler.codec.http", "HttpHeaders", True, "iteratorCharSequence", "()", "", "Argument[this].Element.MapKey", "ReturnValue.Element.MapKey", "taint", "manual"] + - ["io.netty.handler.codec.http", "HttpHeaders", True, "iteratorCharSequence", "()", "", "Argument[this].Element.MapValue", "ReturnValue.Element.MapValue", "taint", "manual"] + - ["io.netty.handler.codec.http", "HttpHeaders", True, "names", "()", "", "Argument[this].Element.MapKey", "ReturnValue.Element", "value", "manual"] - ["io.netty.handler.codec.http", "HttpHeaders", True, "newEntity", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] - - ["io.netty.handler.codec.http", "HttpHeaders", True, "remove", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] - - ["io.netty.handler.codec.http", "HttpHeaders", True, "set", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] - - ["io.netty.handler.codec.http", "HttpHeaders", True, "set", "(CharSequence,Iterable)", "", "Argument[0]", "Argument[-1].Element.MapKey", "taint", "manual"] - - ["io.netty.handler.codec.http", "HttpHeaders", True, "set", "(CharSequence,Iterable)", "", "Argument[1].Element", "Argument[-1].Element.MapValue", "taint", "manual"] - - ["io.netty.handler.codec.http", "HttpHeaders", True, "set", "(CharSequence,Object)", "", "Argument[0]", "Argument[-1].Element.MapKey", "taint", "manual"] - - ["io.netty.handler.codec.http", "HttpHeaders", True, "set", "(CharSequence,Object)", "", "Argument[1]", "Argument[-1].Element.MapValue", "taint", "manual"] - - ["io.netty.handler.codec.http", "HttpHeaders", True, "set", "(String,Iterable)", "", "Argument[0]", "Argument[-1].Element.MapKey", "value", "manual"] - - ["io.netty.handler.codec.http", "HttpHeaders", True, "set", "(String,Iterable)", "", "Argument[1].Element", "Argument[-1].Element.MapValue", "taint", "manual"] - - ["io.netty.handler.codec.http", "HttpHeaders", True, "set", "(String,Object)", "", "Argument[0]", "Argument[-1].Element.MapKey", "value", "manual"] - - ["io.netty.handler.codec.http", "HttpHeaders", True, "set", "(String,Object)", "", "Argument[1]", "Argument[-1].Element.MapValue", "taint", "manual"] - - ["io.netty.handler.codec.http", "HttpHeaders", True, "set", "(HttpHeaders)", "", "Argument[0].Element.MapKey", "Argument[-1].Element.MapKey", "value", "manual"] - - ["io.netty.handler.codec.http", "HttpHeaders", True, "set", "(HttpHeaders)", "", "Argument[0].Element.MapValue", "Argument[-1].Element.MapValue", "taint", "manual"] - - ["io.netty.handler.codec.http", "HttpHeaders", True, "setAll", "(HttpHeaders)", "", "Argument[-1]", "ReturnValue", "value", "manual"] - - ["io.netty.handler.codec.http", "HttpHeaders", True, "setAll", "(HttpHeaders)", "", "Argument[0].Element.MapKey", "Argument[-1].Element.MapKey", "value", "manual"] - - ["io.netty.handler.codec.http", "HttpHeaders", True, "setAll", "(HttpHeaders)", "", "Argument[0].Element.MapValue", "Argument[-1].Element.MapValue", "taint", "manual"] - - ["io.netty.handler.codec.http", "HttpHeaders", True, "setInt", "(CharSequence,int)", "", "Argument[-1]", "ReturnValue", "value", "manual"] - - ["io.netty.handler.codec.http", "HttpHeaders", True, "setInt", "(CharSequence,int)", "", "Argument[0]", "Argument[-1].Element.MapKey", "value", "manual"] - - ["io.netty.handler.codec.http", "HttpHeaders", True, "setShort", "(CharSequence,short)", "", "Argument[-1]", "ReturnValue", "value", "manual"] - - ["io.netty.handler.codec.http", "HttpHeaders", True, "setShort", "(CharSequence,short)", "", "Argument[0]", "Argument[-1].Element.MapKey", "value", "manual"] - - ["io.netty.handler.codec.http", "HttpHeaders", True, "valueStringIterator", "(CharSequence)", "", "Argument[-1].Element.MapValue", "ReturnValue.Element", "value", "manual"] - - ["io.netty.handler.codec.http", "HttpHeaders", True, "valueCharSequenceIterator", "(CharSequence)", "", "Argument[-1].Element.MapValue", "ReturnValue.Element", "taint", "manual"] - - ["io.netty.handler.codec.http", "HttpHeaders", True, "toString", "", "", "Argument[-1].Element.MapKey", "ReturnValue", "taint", "manual"] - - ["io.netty.handler.codec.http", "HttpHeaders", True, "toString", "", "", "Argument[-1].Element.MapValue", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http", "HttpHeaders", True, "remove", "", "", "Argument[this]", "ReturnValue", "value", "manual"] + - ["io.netty.handler.codec.http", "HttpHeaders", True, "set", "", "", "Argument[this]", "ReturnValue", "value", "manual"] + - ["io.netty.handler.codec.http", "HttpHeaders", True, "set", "(CharSequence,Iterable)", "", "Argument[0]", "Argument[this].Element.MapKey", "taint", "manual"] + - ["io.netty.handler.codec.http", "HttpHeaders", True, "set", "(CharSequence,Iterable)", "", "Argument[1].Element", "Argument[this].Element.MapValue", "taint", "manual"] + - ["io.netty.handler.codec.http", "HttpHeaders", True, "set", "(CharSequence,Object)", "", "Argument[0]", "Argument[this].Element.MapKey", "taint", "manual"] + - ["io.netty.handler.codec.http", "HttpHeaders", True, "set", "(CharSequence,Object)", "", "Argument[1]", "Argument[this].Element.MapValue", "taint", "manual"] + - ["io.netty.handler.codec.http", "HttpHeaders", True, "set", "(String,Iterable)", "", "Argument[0]", "Argument[this].Element.MapKey", "value", "manual"] + - ["io.netty.handler.codec.http", "HttpHeaders", True, "set", "(String,Iterable)", "", "Argument[1].Element", "Argument[this].Element.MapValue", "taint", "manual"] + - ["io.netty.handler.codec.http", "HttpHeaders", True, "set", "(String,Object)", "", "Argument[0]", "Argument[this].Element.MapKey", "value", "manual"] + - ["io.netty.handler.codec.http", "HttpHeaders", True, "set", "(String,Object)", "", "Argument[1]", "Argument[this].Element.MapValue", "taint", "manual"] + - ["io.netty.handler.codec.http", "HttpHeaders", True, "set", "(HttpHeaders)", "", "Argument[0].Element.MapKey", "Argument[this].Element.MapKey", "value", "manual"] + - ["io.netty.handler.codec.http", "HttpHeaders", True, "set", "(HttpHeaders)", "", "Argument[0].Element.MapValue", "Argument[this].Element.MapValue", "taint", "manual"] + - ["io.netty.handler.codec.http", "HttpHeaders", True, "setAll", "(HttpHeaders)", "", "Argument[this]", "ReturnValue", "value", "manual"] + - ["io.netty.handler.codec.http", "HttpHeaders", True, "setAll", "(HttpHeaders)", "", "Argument[0].Element.MapKey", "Argument[this].Element.MapKey", "value", "manual"] + - ["io.netty.handler.codec.http", "HttpHeaders", True, "setAll", "(HttpHeaders)", "", "Argument[0].Element.MapValue", "Argument[this].Element.MapValue", "taint", "manual"] + - ["io.netty.handler.codec.http", "HttpHeaders", True, "setInt", "(CharSequence,int)", "", "Argument[this]", "ReturnValue", "value", "manual"] + - ["io.netty.handler.codec.http", "HttpHeaders", True, "setInt", "(CharSequence,int)", "", "Argument[0]", "Argument[this].Element.MapKey", "value", "manual"] + - ["io.netty.handler.codec.http", "HttpHeaders", True, "setShort", "(CharSequence,short)", "", "Argument[this]", "ReturnValue", "value", "manual"] + - ["io.netty.handler.codec.http", "HttpHeaders", True, "setShort", "(CharSequence,short)", "", "Argument[0]", "Argument[this].Element.MapKey", "value", "manual"] + - ["io.netty.handler.codec.http", "HttpHeaders", True, "valueStringIterator", "(CharSequence)", "", "Argument[this].Element.MapValue", "ReturnValue.Element", "value", "manual"] + - ["io.netty.handler.codec.http", "HttpHeaders", True, "valueCharSequenceIterator", "(CharSequence)", "", "Argument[this].Element.MapValue", "ReturnValue.Element", "taint", "manual"] + - ["io.netty.handler.codec.http", "HttpHeaders", True, "toString", "", "", "Argument[this].Element.MapKey", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http", "HttpHeaders", True, "toString", "", "", "Argument[this].Element.MapValue", "ReturnValue", "taint", "manual"] # Currently all write steps to http messages are taint flow. It may reduce FPs to use a synthetic field for headers instead. - - ["io.netty.handler.codec.http", "HttpMessage", True, "headers", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.handler.codec.http", "LastHttpContent", True, "trailingHeaders", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.handler.codec.http", "HttpRequest", True, "getUri", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.handler.codec.http", "HttpRequest", True, "uri", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.handler.codec.http", "HttpRequest", True, "setUri", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] - - ["io.netty.handler.codec.http", "QueryStringDecoder", True, "QueryStringDecoder", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["io.netty.handler.codec.http", "HttpMessage", True, "headers", "", "", "Argument[this]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http", "LastHttpContent", True, "trailingHeaders", "", "", "Argument[this]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http", "HttpRequest", True, "getUri", "", "", "Argument[this]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http", "HttpRequest", True, "uri", "", "", "Argument[this]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http", "HttpRequest", True, "setUri", "", "", "Argument[0]", "Argument[this]", "taint", "manual"] + - ["io.netty.handler.codec.http", "QueryStringDecoder", True, "QueryStringDecoder", "", "", "Argument[0]", "Argument[this]", "taint", "manual"] - ["io.netty.handler.codec.http", "QueryStringDecoder", True, "decodeComponent", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] - - ["io.netty.handler.codec.http", "QueryStringDecoder", True, "parameters", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.handler.codec.http", "QueryStringDecoder", True, "path", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.handler.codec.http", "QueryStringDecoder", True, "rawPath", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.handler.codec.http", "QueryStringDecoder", True, "rawQuery", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.handler.codec.http", "QueryStringDecoder", True, "toString", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.handler.codec.http", "QueryStringDecoder", True, "uri", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http", "QueryStringDecoder", True, "parameters", "", "", "Argument[this]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http", "QueryStringDecoder", True, "path", "", "", "Argument[this]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http", "QueryStringDecoder", True, "rawPath", "", "", "Argument[this]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http", "QueryStringDecoder", True, "rawQuery", "", "", "Argument[this]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http", "QueryStringDecoder", True, "toString", "", "", "Argument[this]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http", "QueryStringDecoder", True, "uri", "", "", "Argument[this]", "ReturnValue", "taint", "manual"] diff --git a/java/ql/lib/ext/io.netty.handler.codec.http.multipart.model.yml b/java/ql/lib/ext/io.netty.handler.codec.http.multipart.model.yml index 3d098271929..3335994dec0 100644 --- a/java/ql/lib/ext/io.netty.handler.codec.http.multipart.model.yml +++ b/java/ql/lib/ext/io.netty.handler.codec.http.multipart.model.yml @@ -8,36 +8,36 @@ extensions: pack: codeql/java-all extensible: summaryModel data: - - ["io.netty.handler.codec.http.multipart", "InterfaceHttpPostRequestDecoder", True, "currentPartialHttpData", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.handler.codec.http.multipart", "InterfaceHttpPostRequestDecoder", True, "getBodyHttpData", "(String)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.handler.codec.http.multipart", "InterfaceHttpPostRequestDecoder", True, "getBodyHttpDatas", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.handler.codec.http.multipart", "InterfaceHttpPostRequestDecoder", True, "getBodyHttpDatas", "(String)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.handler.codec.http.multipart", "InterfaceHttpPostRequestDecoder", True, "next", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.handler.codec.http.multipart", "InterfaceHttpPostRequestDecoder", True, "offer", "(HttpContent)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] - - ["io.netty.handler.codec.http.multipart", "InterfaceHttpPostRequestDecoder", True, "offer", "(HttpContent)", "", "Argument[-1]", "ReturnValue", "value", "manual"] - - ["io.netty.handler.codec.http.multipart", "HttpPostRequestDecoder", True, "HttpPostRequestDecoder", "(HttpRequest)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] - - ["io.netty.handler.codec.http.multipart", "HttpPostRequestDecoder", True, "HttpPostRequestDecoder", "(HttpDataFactory,HttpRequest)", "", "Argument[1]", "Argument[-1]", "taint", "manual"] - - ["io.netty.handler.codec.http.multipart", "HttpPostRequestDecoder", True, "HttpPostRequestDecoder", "(HttpDataFactory,HttpRequest,Charset)", "", "Argument[1]", "Argument[-1]", "taint", "manual"] - - ["io.netty.handler.codec.http.multipart", "HttpPostStandardRequestDecoder", True, "HttpPostStandardRequestDecoder", "(HttpRequest)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] - - ["io.netty.handler.codec.http.multipart", "HttpPostStandardRequestDecoder", True, "HttpPostStandardRequestDecoder", "(HttpDataFactory,HttpRequest)", "", "Argument[1]", "Argument[-1]", "taint", "manual"] - - ["io.netty.handler.codec.http.multipart", "HttpPostStandardRequestDecoder", True, "HttpPostStandardRequestDecoder", "(HttpDataFactory,HttpRequest,Charset)", "", "Argument[1]", "Argument[-1]", "taint", "manual"] - - ["io.netty.handler.codec.http.multipart", "HttpPostMultipartRequestDecoder", True, "HttpPostMultipartRequestDecoder", "(HttpRequest)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] - - ["io.netty.handler.codec.http.multipart", "HttpPostMultipartRequestDecoder", True, "HttpPostMultipartRequestDecoder", "(HttpDataFactory,HttpRequest)", "", "Argument[1]", "Argument[-1]", "taint", "manual"] - - ["io.netty.handler.codec.http.multipart", "HttpPostMultipartRequestDecoder", True, "HttpPostMultipartRequestDecoder", "(HttpDataFactory,HttpRequest,Charset)", "", "Argument[1]", "Argument[-1]", "taint", "manual"] - - ["io.netty.handler.codec.http.multipart", "InterfaceHttpData", True, "getName", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.handler.codec.http.multipart", "HttpData", True, "addContent", "(ByteBuf,boolean)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] - - ["io.netty.handler.codec.http.multipart", "HttpData", True, "get", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.handler.codec.http.multipart", "HttpData", True, "getByteBuf", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.handler.codec.http.multipart", "HttpData", True, "getChunk", "(int)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.handler.codec.http.multipart", "HttpData", True, "getString", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.handler.codec.http.multipart", "HttpData", True, "getString", "(Charset)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.handler.codec.http.multipart", "Attribute", True, "getValue", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.handler.codec.http.multipart", "Attribute", True, "setValue", "(String)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] - - ["io.netty.handler.codec.http.multipart", "FileUpload", True, "getContentTransferEncoding", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.handler.codec.http.multipart", "FileUpload", True, "getContentType", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.handler.codec.http.multipart", "FileUpload", True, "getFilename", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.handler.codec.http.multipart", "FileUpload", True, "setContentTransferEncoding", "(String)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] - - ["io.netty.handler.codec.http.multipart", "FileUpload", True, "setContentType", "(String)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] - - ["io.netty.handler.codec.http.multipart", "FileUpload", True, "setFilename", "(String)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] - - ["io.netty.handler.codec.http.multipart", "HttpData", True, "setContent", "(ByteBuf)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] - - ["io.netty.handler.codec.http.multipart", "HttpData", True, "setContent", "(InputStream)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["io.netty.handler.codec.http.multipart", "InterfaceHttpPostRequestDecoder", True, "currentPartialHttpData", "()", "", "Argument[this]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http.multipart", "InterfaceHttpPostRequestDecoder", True, "getBodyHttpData", "(String)", "", "Argument[this]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http.multipart", "InterfaceHttpPostRequestDecoder", True, "getBodyHttpDatas", "()", "", "Argument[this]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http.multipart", "InterfaceHttpPostRequestDecoder", True, "getBodyHttpDatas", "(String)", "", "Argument[this]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http.multipart", "InterfaceHttpPostRequestDecoder", True, "next", "()", "", "Argument[this]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http.multipart", "InterfaceHttpPostRequestDecoder", True, "offer", "(HttpContent)", "", "Argument[0]", "Argument[this]", "taint", "manual"] + - ["io.netty.handler.codec.http.multipart", "InterfaceHttpPostRequestDecoder", True, "offer", "(HttpContent)", "", "Argument[this]", "ReturnValue", "value", "manual"] + - ["io.netty.handler.codec.http.multipart", "HttpPostRequestDecoder", True, "HttpPostRequestDecoder", "(HttpRequest)", "", "Argument[0]", "Argument[this]", "taint", "manual"] + - ["io.netty.handler.codec.http.multipart", "HttpPostRequestDecoder", True, "HttpPostRequestDecoder", "(HttpDataFactory,HttpRequest)", "", "Argument[1]", "Argument[this]", "taint", "manual"] + - ["io.netty.handler.codec.http.multipart", "HttpPostRequestDecoder", True, "HttpPostRequestDecoder", "(HttpDataFactory,HttpRequest,Charset)", "", "Argument[1]", "Argument[this]", "taint", "manual"] + - ["io.netty.handler.codec.http.multipart", "HttpPostStandardRequestDecoder", True, "HttpPostStandardRequestDecoder", "(HttpRequest)", "", "Argument[0]", "Argument[this]", "taint", "manual"] + - ["io.netty.handler.codec.http.multipart", "HttpPostStandardRequestDecoder", True, "HttpPostStandardRequestDecoder", "(HttpDataFactory,HttpRequest)", "", "Argument[1]", "Argument[this]", "taint", "manual"] + - ["io.netty.handler.codec.http.multipart", "HttpPostStandardRequestDecoder", True, "HttpPostStandardRequestDecoder", "(HttpDataFactory,HttpRequest,Charset)", "", "Argument[1]", "Argument[this]", "taint", "manual"] + - ["io.netty.handler.codec.http.multipart", "HttpPostMultipartRequestDecoder", True, "HttpPostMultipartRequestDecoder", "(HttpRequest)", "", "Argument[0]", "Argument[this]", "taint", "manual"] + - ["io.netty.handler.codec.http.multipart", "HttpPostMultipartRequestDecoder", True, "HttpPostMultipartRequestDecoder", "(HttpDataFactory,HttpRequest)", "", "Argument[1]", "Argument[this]", "taint", "manual"] + - ["io.netty.handler.codec.http.multipart", "HttpPostMultipartRequestDecoder", True, "HttpPostMultipartRequestDecoder", "(HttpDataFactory,HttpRequest,Charset)", "", "Argument[1]", "Argument[this]", "taint", "manual"] + - ["io.netty.handler.codec.http.multipart", "InterfaceHttpData", True, "getName", "()", "", "Argument[this]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http.multipart", "HttpData", True, "addContent", "(ByteBuf,boolean)", "", "Argument[0]", "Argument[this]", "taint", "manual"] + - ["io.netty.handler.codec.http.multipart", "HttpData", True, "get", "()", "", "Argument[this]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http.multipart", "HttpData", True, "getByteBuf", "()", "", "Argument[this]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http.multipart", "HttpData", True, "getChunk", "(int)", "", "Argument[this]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http.multipart", "HttpData", True, "getString", "()", "", "Argument[this]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http.multipart", "HttpData", True, "getString", "(Charset)", "", "Argument[this]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http.multipart", "Attribute", True, "getValue", "()", "", "Argument[this]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http.multipart", "Attribute", True, "setValue", "(String)", "", "Argument[0]", "Argument[this]", "taint", "manual"] + - ["io.netty.handler.codec.http.multipart", "FileUpload", True, "getContentTransferEncoding", "()", "", "Argument[this]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http.multipart", "FileUpload", True, "getContentType", "()", "", "Argument[this]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http.multipart", "FileUpload", True, "getFilename", "()", "", "Argument[this]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http.multipart", "FileUpload", True, "setContentTransferEncoding", "(String)", "", "Argument[0]", "Argument[this]", "taint", "manual"] + - ["io.netty.handler.codec.http.multipart", "FileUpload", True, "setContentType", "(String)", "", "Argument[0]", "Argument[this]", "taint", "manual"] + - ["io.netty.handler.codec.http.multipart", "FileUpload", True, "setFilename", "(String)", "", "Argument[0]", "Argument[this]", "taint", "manual"] + - ["io.netty.handler.codec.http.multipart", "HttpData", True, "setContent", "(ByteBuf)", "", "Argument[0]", "Argument[this]", "taint", "manual"] + - ["io.netty.handler.codec.http.multipart", "HttpData", True, "setContent", "(InputStream)", "", "Argument[0]", "Argument[this]", "taint", "manual"] diff --git a/java/ql/lib/ext/io.netty.handler.codec.http.websocketx.model.yml b/java/ql/lib/ext/io.netty.handler.codec.http.websocketx.model.yml index 9bdd00f8663..2ea3414c125 100644 --- a/java/ql/lib/ext/io.netty.handler.codec.http.websocketx.model.yml +++ b/java/ql/lib/ext/io.netty.handler.codec.http.websocketx.model.yml @@ -3,23 +3,23 @@ extensions: pack: codeql/java-all extensible: summaryModel data: - - ["io.netty.handler.codec.http.websocketx", "CloseWebSocketFrame", True, "CloseWebSocketFrame", "(boolean,int,ByteBuf)", "", "Argument[2]", "Argument[-1]", "taint", "manual"] - - ["io.netty.handler.codec.http.websocketx", "CloseWebSocketFrame", True, "CloseWebSocketFrame", "(boolean,int,int,String)", "", "Argument[3]", "Argument[-1]", "taint", "manual"] - - ["io.netty.handler.codec.http.websocketx", "CloseWebSocketFrame", True, "CloseWebSocketFrame", "(int,String)", "", "Argument[1]", "Argument[-1]", "taint", "manual"] - - ["io.netty.handler.codec.http.websocketx", "CloseWebSocketFrame", True, "CloseWebSocketFrame", "(WebSocketCloseStatus,String)", "", "Argument[1]", "Argument[-1]", "taint", "manual"] - - ["io.netty.handler.codec.http.websocketx", "CloseWebSocketFrame", True, "reasonText", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.handler.codec.http.websocketx", "BinaryWebSocketFrame", True, "BinaryWebSocketFrame", "(boolean,int,ByteBuf)", "", "Argument[2]", "Argument[-1]", "taint", "manual"] - - ["io.netty.handler.codec.http.websocketx", "BinaryWebSocketFrame", True, "BinaryWebSocketFrame", "(ByteBuf)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] - - ["io.netty.handler.codec.http.websocketx", "ContinuationWebSocketFrame", True, "ContinuationWebSocketFrame", "(boolean,int,ByteBuf)", "", "Argument[2]", "Argument[-1]", "taint", "manual"] - - ["io.netty.handler.codec.http.websocketx", "ContinuationWebSocketFrame", True, "ContinuationWebSocketFrame", "(boolean,int,String)", "", "Argument[2]", "Argument[-1]", "taint", "manual"] - - ["io.netty.handler.codec.http.websocketx", "ContinuationWebSocketFrame", True, "ContinuationWebSocketFrame", "(ByteBuf)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] - - ["io.netty.handler.codec.http.websocketx", "ContinuationWebSocketFrame", True, "text", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.handler.codec.http.websocketx", "PingWebSocketFrame", True, "PingWebSocketFrame", "(boolean,int,ByteBuf)", "", "Argument[2]", "Argument[-1]", "taint", "manual"] - - ["io.netty.handler.codec.http.websocketx", "PingWebSocketFrame", True, "PingWebSocketFrame", "(ByteBuf)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] - - ["io.netty.handler.codec.http.websocketx", "PongWebSocketFrame", True, "PongWebSocketFrame", "(boolean,int,ByteBuf)", "", "Argument[2]", "Argument[-1]", "taint", "manual"] - - ["io.netty.handler.codec.http.websocketx", "PongWebSocketFrame", True, "PongWebSocketFrame", "(ByteBuf)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] - - ["io.netty.handler.codec.http.websocketx", "TextWebSocketFrame", True, "TextWebSocketFrame", "(boolean,int,ByteBuf)", "", "Argument[2]", "Argument[-1]", "taint", "manual"] - - ["io.netty.handler.codec.http.websocketx", "TextWebSocketFrame", True, "TextWebSocketFrame", "(boolean,int,String)", "", "Argument[2]", "Argument[-1]", "taint", "manual"] - - ["io.netty.handler.codec.http.websocketx", "TextWebSocketFrame", True, "TextWebSocketFrame", "(String)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] - - ["io.netty.handler.codec.http.websocketx", "TextWebSocketFrame", True, "TextWebSocketFrame", "(ByteBuf)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] - - ["io.netty.handler.codec.http.websocketx", "TextWebSocketFrame", True, "text", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] \ No newline at end of file + - ["io.netty.handler.codec.http.websocketx", "CloseWebSocketFrame", True, "CloseWebSocketFrame", "(boolean,int,ByteBuf)", "", "Argument[2]", "Argument[this]", "taint", "manual"] + - ["io.netty.handler.codec.http.websocketx", "CloseWebSocketFrame", True, "CloseWebSocketFrame", "(boolean,int,int,String)", "", "Argument[3]", "Argument[this]", "taint", "manual"] + - ["io.netty.handler.codec.http.websocketx", "CloseWebSocketFrame", True, "CloseWebSocketFrame", "(int,String)", "", "Argument[1]", "Argument[this]", "taint", "manual"] + - ["io.netty.handler.codec.http.websocketx", "CloseWebSocketFrame", True, "CloseWebSocketFrame", "(WebSocketCloseStatus,String)", "", "Argument[1]", "Argument[this]", "taint", "manual"] + - ["io.netty.handler.codec.http.websocketx", "CloseWebSocketFrame", True, "reasonText", "()", "", "Argument[this]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http.websocketx", "BinaryWebSocketFrame", True, "BinaryWebSocketFrame", "(boolean,int,ByteBuf)", "", "Argument[2]", "Argument[this]", "taint", "manual"] + - ["io.netty.handler.codec.http.websocketx", "BinaryWebSocketFrame", True, "BinaryWebSocketFrame", "(ByteBuf)", "", "Argument[0]", "Argument[this]", "taint", "manual"] + - ["io.netty.handler.codec.http.websocketx", "ContinuationWebSocketFrame", True, "ContinuationWebSocketFrame", "(boolean,int,ByteBuf)", "", "Argument[2]", "Argument[this]", "taint", "manual"] + - ["io.netty.handler.codec.http.websocketx", "ContinuationWebSocketFrame", True, "ContinuationWebSocketFrame", "(boolean,int,String)", "", "Argument[2]", "Argument[this]", "taint", "manual"] + - ["io.netty.handler.codec.http.websocketx", "ContinuationWebSocketFrame", True, "ContinuationWebSocketFrame", "(ByteBuf)", "", "Argument[0]", "Argument[this]", "taint", "manual"] + - ["io.netty.handler.codec.http.websocketx", "ContinuationWebSocketFrame", True, "text", "()", "", "Argument[this]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http.websocketx", "PingWebSocketFrame", True, "PingWebSocketFrame", "(boolean,int,ByteBuf)", "", "Argument[2]", "Argument[this]", "taint", "manual"] + - ["io.netty.handler.codec.http.websocketx", "PingWebSocketFrame", True, "PingWebSocketFrame", "(ByteBuf)", "", "Argument[0]", "Argument[this]", "taint", "manual"] + - ["io.netty.handler.codec.http.websocketx", "PongWebSocketFrame", True, "PongWebSocketFrame", "(boolean,int,ByteBuf)", "", "Argument[2]", "Argument[this]", "taint", "manual"] + - ["io.netty.handler.codec.http.websocketx", "PongWebSocketFrame", True, "PongWebSocketFrame", "(ByteBuf)", "", "Argument[0]", "Argument[this]", "taint", "manual"] + - ["io.netty.handler.codec.http.websocketx", "TextWebSocketFrame", True, "TextWebSocketFrame", "(boolean,int,ByteBuf)", "", "Argument[2]", "Argument[this]", "taint", "manual"] + - ["io.netty.handler.codec.http.websocketx", "TextWebSocketFrame", True, "TextWebSocketFrame", "(boolean,int,String)", "", "Argument[2]", "Argument[this]", "taint", "manual"] + - ["io.netty.handler.codec.http.websocketx", "TextWebSocketFrame", True, "TextWebSocketFrame", "(String)", "", "Argument[0]", "Argument[this]", "taint", "manual"] + - ["io.netty.handler.codec.http.websocketx", "TextWebSocketFrame", True, "TextWebSocketFrame", "(ByteBuf)", "", "Argument[0]", "Argument[this]", "taint", "manual"] + - ["io.netty.handler.codec.http.websocketx", "TextWebSocketFrame", True, "text", "()", "", "Argument[this]", "ReturnValue", "taint", "manual"] \ No newline at end of file diff --git a/java/ql/lib/ext/io.netty.handler.codec.http2.model.yml b/java/ql/lib/ext/io.netty.handler.codec.http2.model.yml index 0b4229fac41..bb84e7e43e2 100644 --- a/java/ql/lib/ext/io.netty.handler.codec.http2.model.yml +++ b/java/ql/lib/ext/io.netty.handler.codec.http2.model.yml @@ -11,24 +11,24 @@ extensions: pack: codeql/java-all extensible: summaryModel data: - - ["io.netty.handler.codec.http2", "Http2Headers", True, "authority", "()", "", "Argument[-1].Element.MapValue", "ReturnValue", "value", "manual"] - - ["io.netty.handler.codec.http2", "Http2Headers", True, "authority", "(CharSequence)", "", "Argument[0]", "Argument[-1].Element.MapValue", "value", "manual"] - - ["io.netty.handler.codec.http2", "Http2Headers", True, "authority", "(CharSequence)", "", "Argument[-1]", "ReturnValue", "value", "manual"] - - ["io.netty.handler.codec.http2", "Http2Headers", True, "method", "()", "", "Argument[-1].Element.MapValue", "ReturnValue", "value", "manual"] - - ["io.netty.handler.codec.http2", "Http2Headers", True, "method", "(CharSequence)", "", "Argument[0]", "Argument[-1].Element.MapValue", "value", "manual"] - - ["io.netty.handler.codec.http2", "Http2Headers", True, "method", "(CharSequence)", "", "Argument[-1]", "ReturnValue", "value", "manual"] - - ["io.netty.handler.codec.http2", "Http2Headers", True, "path", "()", "", "Argument[-1].Element.MapValue", "ReturnValue", "value", "manual"] - - ["io.netty.handler.codec.http2", "Http2Headers", True, "path", "(CharSequence)", "", "Argument[0]", "Argument[-1].Element.MapValue", "value", "manual"] - - ["io.netty.handler.codec.http2", "Http2Headers", True, "path", "(CharSequence)", "", "Argument[-1]", "ReturnValue", "value", "manual"] - - ["io.netty.handler.codec.http2", "Http2Headers", True, "scheme", "()", "", "Argument[-1].Element.MapValue", "ReturnValue", "value", "manual"] - - ["io.netty.handler.codec.http2", "Http2Headers", True, "scheme", "(CharSequence)", "", "Argument[0]", "Argument[-1].Element.MapValue", "value", "manual"] - - ["io.netty.handler.codec.http2", "Http2Headers", True, "scheme", "(CharSequence)", "", "Argument[-1]", "ReturnValue", "value", "manual"] - - ["io.netty.handler.codec.http2", "Http2Headers", True, "status", "()", "", "Argument[-1].Element.MapValue", "ReturnValue", "value", "manual"] - - ["io.netty.handler.codec.http2", "Http2Headers", True, "status", "(CharSequence)", "", "Argument[0]", "Argument[-1].Element.MapValue", "value", "manual"] - - ["io.netty.handler.codec.http2", "Http2Headers", True, "status", "(CharSequence)", "", "Argument[-1]", "ReturnValue", "value", "manual"] - - ["io.netty.handler.codec.http2", "Http2Headers", True, "valueIterator", "(CharSequence)", "", "Argument[-1].Element.MapValue", "ReturnValue.Element", "value", "manual"] - - ["io.netty.handler.codec.http2", "Http2HeadersFrame", True, "headers", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.handler.codec.http2", "Http2PushPromiseFrame", True, "http2Headers", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http2", "Http2Headers", True, "authority", "()", "", "Argument[this].Element.MapValue", "ReturnValue", "value", "manual"] + - ["io.netty.handler.codec.http2", "Http2Headers", True, "authority", "(CharSequence)", "", "Argument[0]", "Argument[this].Element.MapValue", "value", "manual"] + - ["io.netty.handler.codec.http2", "Http2Headers", True, "authority", "(CharSequence)", "", "Argument[this]", "ReturnValue", "value", "manual"] + - ["io.netty.handler.codec.http2", "Http2Headers", True, "method", "()", "", "Argument[this].Element.MapValue", "ReturnValue", "value", "manual"] + - ["io.netty.handler.codec.http2", "Http2Headers", True, "method", "(CharSequence)", "", "Argument[0]", "Argument[this].Element.MapValue", "value", "manual"] + - ["io.netty.handler.codec.http2", "Http2Headers", True, "method", "(CharSequence)", "", "Argument[this]", "ReturnValue", "value", "manual"] + - ["io.netty.handler.codec.http2", "Http2Headers", True, "path", "()", "", "Argument[this].Element.MapValue", "ReturnValue", "value", "manual"] + - ["io.netty.handler.codec.http2", "Http2Headers", True, "path", "(CharSequence)", "", "Argument[0]", "Argument[this].Element.MapValue", "value", "manual"] + - ["io.netty.handler.codec.http2", "Http2Headers", True, "path", "(CharSequence)", "", "Argument[this]", "ReturnValue", "value", "manual"] + - ["io.netty.handler.codec.http2", "Http2Headers", True, "scheme", "()", "", "Argument[this].Element.MapValue", "ReturnValue", "value", "manual"] + - ["io.netty.handler.codec.http2", "Http2Headers", True, "scheme", "(CharSequence)", "", "Argument[0]", "Argument[this].Element.MapValue", "value", "manual"] + - ["io.netty.handler.codec.http2", "Http2Headers", True, "scheme", "(CharSequence)", "", "Argument[this]", "ReturnValue", "value", "manual"] + - ["io.netty.handler.codec.http2", "Http2Headers", True, "status", "()", "", "Argument[this].Element.MapValue", "ReturnValue", "value", "manual"] + - ["io.netty.handler.codec.http2", "Http2Headers", True, "status", "(CharSequence)", "", "Argument[0]", "Argument[this].Element.MapValue", "value", "manual"] + - ["io.netty.handler.codec.http2", "Http2Headers", True, "status", "(CharSequence)", "", "Argument[this]", "ReturnValue", "value", "manual"] + - ["io.netty.handler.codec.http2", "Http2Headers", True, "valueIterator", "(CharSequence)", "", "Argument[this].Element.MapValue", "ReturnValue.Element", "value", "manual"] + - ["io.netty.handler.codec.http2", "Http2HeadersFrame", True, "headers", "()", "", "Argument[this]", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec.http2", "Http2PushPromiseFrame", True, "http2Headers", "()", "", "Argument[this]", "ReturnValue", "taint", "manual"] - ["io.netty.handler.codec.http2", "HttpConversionUtil", False, "addHttp2ToHttpHeaders", "(int,Http2Headers,FullHttpMessage,boolean)", "", "Argument[1].Element.MapKey", "Argument[2]", "taint", "manual"] - ["io.netty.handler.codec.http2", "HttpConversionUtil", False, "addHttp2ToHttpHeaders", "(int,Http2Headers,FullHttpMessage,boolean)", "", "Argument[1].Element.MapValue", "Argument[2]", "taint", "manual"] - ["io.netty.handler.codec.http2", "HttpConversionUtil", False, "addHttp2ToHttpHeaders", "(int,Http2Headers,HttpHeaders,HttpVersion,boolean,boolean)", "", "Argument[1].Element.MapKey", "Argument[2].Element.MapKey", "taint", "manual"] diff --git a/java/ql/lib/ext/io.netty.handler.codec.model.yml b/java/ql/lib/ext/io.netty.handler.codec.model.yml index 71849cf2c72..b458fc09f8a 100644 --- a/java/ql/lib/ext/io.netty.handler.codec.model.yml +++ b/java/ql/lib/ext/io.netty.handler.codec.model.yml @@ -24,80 +24,80 @@ extensions: - ["io.netty.handler.codec", "HeadersUtils", False, "iteratorAsString", "(Iterable)", "", "Argument[0].Element.MapValue", "ReturnValue", "taint", "manual"] - ["io.netty.handler.codec", "HeadersUtils", False, "toString", "(Class,Iterator,int)", "", "Argument[1].Element.MapKey", "ReturnValue", "taint", "manual"] - ["io.netty.handler.codec", "HeadersUtils", False, "toString", "(Class,Iterator,int)", "", "Argument[1].Element.MapValue", "ReturnValue", "taint", "manual"] - - ["io.netty.handler.codec", "Headers", True, "get", "(Object)", "", "Argument[-1].Element.MapValue", "ReturnValue", "taint", "manual"] - - ["io.netty.handler.codec", "Headers", True, "get", "(Object,Object)", "", "Argument[-1].Element.MapValue", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec", "Headers", True, "get", "(Object)", "", "Argument[this].Element.MapValue", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec", "Headers", True, "get", "(Object,Object)", "", "Argument[this].Element.MapValue", "ReturnValue", "taint", "manual"] - ["io.netty.handler.codec", "Headers", True, "get", "(Object,Object)", "", "Argument[1]", "ReturnValue", "value", "manual"] - - ["io.netty.handler.codec", "Headers", True, "getAll", "(Object)", "", "Argument[-1].Element.MapValue", "ReturnValue.Element", "taint", "manual"] - - ["io.netty.handler.codec", "Headers", True, "getAllAndRemove", "(Object)", "", "Argument[-1].Element.MapValue", "ReturnValue.Element", "taint", "manual"] - - ["io.netty.handler.codec", "Headers", True, "getAndRemove", "(Object)", "", "Argument[-1].Element.MapValue", "ReturnValue", "taint", "manual"] - - ["io.netty.handler.codec", "Headers", True, "getAndRemove", "(Object)", "", "Argument[-1].Element.MapValue", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec", "Headers", True, "getAll", "(Object)", "", "Argument[this].Element.MapValue", "ReturnValue.Element", "taint", "manual"] + - ["io.netty.handler.codec", "Headers", True, "getAllAndRemove", "(Object)", "", "Argument[this].Element.MapValue", "ReturnValue.Element", "taint", "manual"] + - ["io.netty.handler.codec", "Headers", True, "getAndRemove", "(Object)", "", "Argument[this].Element.MapValue", "ReturnValue", "taint", "manual"] + - ["io.netty.handler.codec", "Headers", True, "getAndRemove", "(Object)", "", "Argument[this].Element.MapValue", "ReturnValue", "taint", "manual"] - ["io.netty.handler.codec", "Headers", True, "getAndRemove", "(Object,Object)", "", "Argument[1]", "ReturnValue", "value", "manual"] - - ["io.netty.handler.codec", "Headers", True, "names", "()", "", "Argument[-1].Element.MapKey", "ReturnValue.Element", "taint", "manual"] - - ["io.netty.handler.codec", "Headers", True, "add", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] - - ["io.netty.handler.codec", "Headers", True, "add", "(Headers)", "", "Argument[0].Element.MapKey", "Argument[-1].Element.MapKey", "value", "manual"] - - ["io.netty.handler.codec", "Headers", True, "add", "(Headers)", "", "Argument[0].Element.MapValue", "Argument[-1].Element.MapValue", "value", "manual"] - - ["io.netty.handler.codec", "Headers", True, "add", "(Object,Iterable)", "", "Argument[0]", "Argument[-1].Element.MapKey", "value", "manual"] - - ["io.netty.handler.codec", "Headers", True, "add", "(Object,Iterable)", "", "Argument[1].Element", "Argument[-1].Element.MapValue", "value", "manual"] - - ["io.netty.handler.codec", "Headers", True, "add", "(Object,Object[])", "", "Argument[0]", "Argument[-1].Element.MapKey", "value", "manual"] - - ["io.netty.handler.codec", "Headers", True, "add", "(Object,Object[])", "", "Argument[1].ArrayElement", "Argument[-1].Element.MapValue", "value", "manual"] - - ["io.netty.handler.codec", "Headers", True, "add", "(Object,Object)", "", "Argument[0]", "Argument[-1].Element.MapKey", "value", "manual"] - - ["io.netty.handler.codec", "Headers", True, "add", "(Object,Object)", "", "Argument[1]", "Argument[-1].Element.MapValue", "value", "manual"] - - ["io.netty.handler.codec", "Headers", True, "addObject", "(Object,Iterable)", "", "Argument[0]", "Argument[-1].Element.MapKey", "value", "manual"] - - ["io.netty.handler.codec", "Headers", True, "addObject", "(Object,Iterable)", "", "Argument[1].Element", "Argument[-1].Element.MapValue", "taint", "manual"] - - ["io.netty.handler.codec", "Headers", True, "addObject", "(Object,Object[])", "", "Argument[0]", "Argument[-1].Element.MapKey", "value", "manual"] - - ["io.netty.handler.codec", "Headers", True, "addObject", "(Object,Object[])", "", "Argument[1].ArrayElement", "Argument[-1].Element.MapValue", "taint", "manual"] - - ["io.netty.handler.codec", "Headers", True, "addObject", "(Object,Object)", "", "Argument[0]", "Argument[-1].Element.MapKey", "value", "manual"] - - ["io.netty.handler.codec", "Headers", True, "addObject", "(Object,Object)", "", "Argument[1]", "Argument[-1].Element.MapValue", "taint", "manual"] - - ["io.netty.handler.codec", "Headers", True, "addBoolean", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] - - ["io.netty.handler.codec", "Headers", True, "addBoolean", "", "", "Argument[0]", "Argument[-1].Element.MapKey", "value", "manual"] - - ["io.netty.handler.codec", "Headers", True, "addByte", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] - - ["io.netty.handler.codec", "Headers", True, "addByte", "", "", "Argument[0]", "Argument[-1].Element.MapKey", "value", "manual"] - - ["io.netty.handler.codec", "Headers", True, "addChar", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] - - ["io.netty.handler.codec", "Headers", True, "addChar", "", "", "Argument[0]", "Argument[-1].Element.MapKey", "value", "manual"] - - ["io.netty.handler.codec", "Headers", True, "addDouble", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] - - ["io.netty.handler.codec", "Headers", True, "addDouble", "", "", "Argument[0]", "Argument[-1].Element.MapKey", "value", "manual"] - - ["io.netty.handler.codec", "Headers", True, "addFloat", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] - - ["io.netty.handler.codec", "Headers", True, "addFloat", "", "", "Argument[0]", "Argument[-1].Element.MapKey", "value", "manual"] - - ["io.netty.handler.codec", "Headers", True, "addInt", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] - - ["io.netty.handler.codec", "Headers", True, "addInt", "", "", "Argument[0]", "Argument[-1].Element.MapKey", "value", "manual"] - - ["io.netty.handler.codec", "Headers", True, "addLong", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] - - ["io.netty.handler.codec", "Headers", True, "addLong", "", "", "Argument[0]", "Argument[-1].Element.MapKey", "value", "manual"] - - ["io.netty.handler.codec", "Headers", True, "addShort", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] - - ["io.netty.handler.codec", "Headers", True, "addShort", "", "", "Argument[0]", "Argument[-1].Element.MapKey", "value", "manual"] - - ["io.netty.handler.codec", "Headers", True, "addTimeMillis", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] - - ["io.netty.handler.codec", "Headers", True, "addTimeMillis", "", "", "Argument[0]", "Argument[-1].Element.MapKey", "value", "manual"] - - ["io.netty.handler.codec", "Headers", True, "set", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] - - ["io.netty.handler.codec", "Headers", True, "set", "(Headers)", "", "Argument[0].Element.MapKey", "Argument[-1].Element.MapKey", "value", "manual"] - - ["io.netty.handler.codec", "Headers", True, "set", "(Headers)", "", "Argument[0].Element.MapValue", "Argument[-1].Element.MapValue", "value", "manual"] - - ["io.netty.handler.codec", "Headers", True, "set", "(Object,Iterable)", "", "Argument[0]", "Argument[-1].Element.MapKey", "value", "manual"] - - ["io.netty.handler.codec", "Headers", True, "set", "(Object,Iterable)", "", "Argument[1].Element", "Argument[-1].Element.MapValue", "value", "manual"] - - ["io.netty.handler.codec", "Headers", True, "set", "(Object,Object[])", "", "Argument[0]", "Argument[-1].Element.MapKey", "value", "manual"] - - ["io.netty.handler.codec", "Headers", True, "set", "(Object,Object[])", "", "Argument[1].ArrayElement", "Argument[-1].Element.MapValue", "value", "manual"] - - ["io.netty.handler.codec", "Headers", True, "set", "(Object,Object)", "", "Argument[0]", "Argument[-1].Element.MapKey", "value", "manual"] - - ["io.netty.handler.codec", "Headers", True, "set", "(Object,Object)", "", "Argument[1]", "Argument[-1].Element.MapValue", "value", "manual"] - - ["io.netty.handler.codec", "Headers", True, "setAll", "(Headers)", "", "Argument[0].Element.MapKey", "Argument[-1].Element.MapKey", "value", "manual"] - - ["io.netty.handler.codec", "Headers", True, "setAll", "(Headers)", "", "Argument[0].Element.MapValue", "Argument[-1].Element.MapValue", "value", "manual"] - - ["io.netty.handler.codec", "Headers", True, "setObject", "(Object,Iterable)", "", "Argument[0]", "Argument[-1].Element.MapKey", "value", "manual"] - - ["io.netty.handler.codec", "Headers", True, "setObject", "(Object,Iterable)", "", "Argument[1].Element", "Argument[-1].Element.MapValue", "taint", "manual"] - - ["io.netty.handler.codec", "Headers", True, "setObject", "(Object,Object[])", "", "Argument[0]", "Argument[-1].Element.MapKey", "value", "manual"] - - ["io.netty.handler.codec", "Headers", True, "setObject", "(Object,Object[])", "", "Argument[1].ArrayElement", "Argument[-1].Element.MapValue", "taint", "manual"] - - ["io.netty.handler.codec", "Headers", True, "setObject", "(Object,Object)", "", "Argument[0]", "Argument[-1].Element.MapKey", "value", "manual"] - - ["io.netty.handler.codec", "Headers", True, "setObject", "(Object,Object)", "", "Argument[1]", "Argument[-1].Element.MapValue", "taint", "manual"] - - ["io.netty.handler.codec", "Headers", True, "setBoolean", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] - - ["io.netty.handler.codec", "Headers", True, "setBoolean", "", "", "Argument[0]", "Argument[-1].Element.MapKey", "value", "manual"] - - ["io.netty.handler.codec", "Headers", True, "setByte", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] - - ["io.netty.handler.codec", "Headers", True, "setByte", "", "", "Argument[0]", "Argument[-1].Element.MapKey", "value", "manual"] - - ["io.netty.handler.codec", "Headers", True, "setChar", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] - - ["io.netty.handler.codec", "Headers", True, "setChar", "", "", "Argument[0]", "Argument[-1].Element.MapKey", "value", "manual"] - - ["io.netty.handler.codec", "Headers", True, "setDouble", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] - - ["io.netty.handler.codec", "Headers", True, "setDouble", "", "", "Argument[0]", "Argument[-1].Element.MapKey", "value", "manual"] - - ["io.netty.handler.codec", "Headers", True, "setFloat", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] - - ["io.netty.handler.codec", "Headers", True, "setFloat", "", "", "Argument[0]", "Argument[-1].Element.MapKey", "value", "manual"] - - ["io.netty.handler.codec", "Headers", True, "setInt", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] - - ["io.netty.handler.codec", "Headers", True, "setInt", "", "", "Argument[0]", "Argument[-1].Element.MapKey", "value", "manual"] - - ["io.netty.handler.codec", "Headers", True, "setLong", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] - - ["io.netty.handler.codec", "Headers", True, "setLong", "", "", "Argument[0]", "Argument[-1].Element.MapKey", "value", "manual"] - - ["io.netty.handler.codec", "Headers", True, "setShort", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] - - ["io.netty.handler.codec", "Headers", True, "setShort", "", "", "Argument[0]", "Argument[-1].Element.MapKey", "value", "manual"] - - ["io.netty.handler.codec", "Headers", True, "setTimeMillis", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] - - ["io.netty.handler.codec", "Headers", True, "setTimeMillis", "", "", "Argument[0]", "Argument[-1].Element.MapKey", "value", "manual"] + - ["io.netty.handler.codec", "Headers", True, "names", "()", "", "Argument[this].Element.MapKey", "ReturnValue.Element", "taint", "manual"] + - ["io.netty.handler.codec", "Headers", True, "add", "", "", "Argument[this]", "ReturnValue", "value", "manual"] + - ["io.netty.handler.codec", "Headers", True, "add", "(Headers)", "", "Argument[0].Element.MapKey", "Argument[this].Element.MapKey", "value", "manual"] + - ["io.netty.handler.codec", "Headers", True, "add", "(Headers)", "", "Argument[0].Element.MapValue", "Argument[this].Element.MapValue", "value", "manual"] + - ["io.netty.handler.codec", "Headers", True, "add", "(Object,Iterable)", "", "Argument[0]", "Argument[this].Element.MapKey", "value", "manual"] + - ["io.netty.handler.codec", "Headers", True, "add", "(Object,Iterable)", "", "Argument[1].Element", "Argument[this].Element.MapValue", "value", "manual"] + - ["io.netty.handler.codec", "Headers", True, "add", "(Object,Object[])", "", "Argument[0]", "Argument[this].Element.MapKey", "value", "manual"] + - ["io.netty.handler.codec", "Headers", True, "add", "(Object,Object[])", "", "Argument[1].ArrayElement", "Argument[this].Element.MapValue", "value", "manual"] + - ["io.netty.handler.codec", "Headers", True, "add", "(Object,Object)", "", "Argument[0]", "Argument[this].Element.MapKey", "value", "manual"] + - ["io.netty.handler.codec", "Headers", True, "add", "(Object,Object)", "", "Argument[1]", "Argument[this].Element.MapValue", "value", "manual"] + - ["io.netty.handler.codec", "Headers", True, "addObject", "(Object,Iterable)", "", "Argument[0]", "Argument[this].Element.MapKey", "value", "manual"] + - ["io.netty.handler.codec", "Headers", True, "addObject", "(Object,Iterable)", "", "Argument[1].Element", "Argument[this].Element.MapValue", "taint", "manual"] + - ["io.netty.handler.codec", "Headers", True, "addObject", "(Object,Object[])", "", "Argument[0]", "Argument[this].Element.MapKey", "value", "manual"] + - ["io.netty.handler.codec", "Headers", True, "addObject", "(Object,Object[])", "", "Argument[1].ArrayElement", "Argument[this].Element.MapValue", "taint", "manual"] + - ["io.netty.handler.codec", "Headers", True, "addObject", "(Object,Object)", "", "Argument[0]", "Argument[this].Element.MapKey", "value", "manual"] + - ["io.netty.handler.codec", "Headers", True, "addObject", "(Object,Object)", "", "Argument[1]", "Argument[this].Element.MapValue", "taint", "manual"] + - ["io.netty.handler.codec", "Headers", True, "addBoolean", "", "", "Argument[this]", "ReturnValue", "value", "manual"] + - ["io.netty.handler.codec", "Headers", True, "addBoolean", "", "", "Argument[0]", "Argument[this].Element.MapKey", "value", "manual"] + - ["io.netty.handler.codec", "Headers", True, "addByte", "", "", "Argument[this]", "ReturnValue", "value", "manual"] + - ["io.netty.handler.codec", "Headers", True, "addByte", "", "", "Argument[0]", "Argument[this].Element.MapKey", "value", "manual"] + - ["io.netty.handler.codec", "Headers", True, "addChar", "", "", "Argument[this]", "ReturnValue", "value", "manual"] + - ["io.netty.handler.codec", "Headers", True, "addChar", "", "", "Argument[0]", "Argument[this].Element.MapKey", "value", "manual"] + - ["io.netty.handler.codec", "Headers", True, "addDouble", "", "", "Argument[this]", "ReturnValue", "value", "manual"] + - ["io.netty.handler.codec", "Headers", True, "addDouble", "", "", "Argument[0]", "Argument[this].Element.MapKey", "value", "manual"] + - ["io.netty.handler.codec", "Headers", True, "addFloat", "", "", "Argument[this]", "ReturnValue", "value", "manual"] + - ["io.netty.handler.codec", "Headers", True, "addFloat", "", "", "Argument[0]", "Argument[this].Element.MapKey", "value", "manual"] + - ["io.netty.handler.codec", "Headers", True, "addInt", "", "", "Argument[this]", "ReturnValue", "value", "manual"] + - ["io.netty.handler.codec", "Headers", True, "addInt", "", "", "Argument[0]", "Argument[this].Element.MapKey", "value", "manual"] + - ["io.netty.handler.codec", "Headers", True, "addLong", "", "", "Argument[this]", "ReturnValue", "value", "manual"] + - ["io.netty.handler.codec", "Headers", True, "addLong", "", "", "Argument[0]", "Argument[this].Element.MapKey", "value", "manual"] + - ["io.netty.handler.codec", "Headers", True, "addShort", "", "", "Argument[this]", "ReturnValue", "value", "manual"] + - ["io.netty.handler.codec", "Headers", True, "addShort", "", "", "Argument[0]", "Argument[this].Element.MapKey", "value", "manual"] + - ["io.netty.handler.codec", "Headers", True, "addTimeMillis", "", "", "Argument[this]", "ReturnValue", "value", "manual"] + - ["io.netty.handler.codec", "Headers", True, "addTimeMillis", "", "", "Argument[0]", "Argument[this].Element.MapKey", "value", "manual"] + - ["io.netty.handler.codec", "Headers", True, "set", "", "", "Argument[this]", "ReturnValue", "value", "manual"] + - ["io.netty.handler.codec", "Headers", True, "set", "(Headers)", "", "Argument[0].Element.MapKey", "Argument[this].Element.MapKey", "value", "manual"] + - ["io.netty.handler.codec", "Headers", True, "set", "(Headers)", "", "Argument[0].Element.MapValue", "Argument[this].Element.MapValue", "value", "manual"] + - ["io.netty.handler.codec", "Headers", True, "set", "(Object,Iterable)", "", "Argument[0]", "Argument[this].Element.MapKey", "value", "manual"] + - ["io.netty.handler.codec", "Headers", True, "set", "(Object,Iterable)", "", "Argument[1].Element", "Argument[this].Element.MapValue", "value", "manual"] + - ["io.netty.handler.codec", "Headers", True, "set", "(Object,Object[])", "", "Argument[0]", "Argument[this].Element.MapKey", "value", "manual"] + - ["io.netty.handler.codec", "Headers", True, "set", "(Object,Object[])", "", "Argument[1].ArrayElement", "Argument[this].Element.MapValue", "value", "manual"] + - ["io.netty.handler.codec", "Headers", True, "set", "(Object,Object)", "", "Argument[0]", "Argument[this].Element.MapKey", "value", "manual"] + - ["io.netty.handler.codec", "Headers", True, "set", "(Object,Object)", "", "Argument[1]", "Argument[this].Element.MapValue", "value", "manual"] + - ["io.netty.handler.codec", "Headers", True, "setAll", "(Headers)", "", "Argument[0].Element.MapKey", "Argument[this].Element.MapKey", "value", "manual"] + - ["io.netty.handler.codec", "Headers", True, "setAll", "(Headers)", "", "Argument[0].Element.MapValue", "Argument[this].Element.MapValue", "value", "manual"] + - ["io.netty.handler.codec", "Headers", True, "setObject", "(Object,Iterable)", "", "Argument[0]", "Argument[this].Element.MapKey", "value", "manual"] + - ["io.netty.handler.codec", "Headers", True, "setObject", "(Object,Iterable)", "", "Argument[1].Element", "Argument[this].Element.MapValue", "taint", "manual"] + - ["io.netty.handler.codec", "Headers", True, "setObject", "(Object,Object[])", "", "Argument[0]", "Argument[this].Element.MapKey", "value", "manual"] + - ["io.netty.handler.codec", "Headers", True, "setObject", "(Object,Object[])", "", "Argument[1].ArrayElement", "Argument[this].Element.MapValue", "taint", "manual"] + - ["io.netty.handler.codec", "Headers", True, "setObject", "(Object,Object)", "", "Argument[0]", "Argument[this].Element.MapKey", "value", "manual"] + - ["io.netty.handler.codec", "Headers", True, "setObject", "(Object,Object)", "", "Argument[1]", "Argument[this].Element.MapValue", "taint", "manual"] + - ["io.netty.handler.codec", "Headers", True, "setBoolean", "", "", "Argument[this]", "ReturnValue", "value", "manual"] + - ["io.netty.handler.codec", "Headers", True, "setBoolean", "", "", "Argument[0]", "Argument[this].Element.MapKey", "value", "manual"] + - ["io.netty.handler.codec", "Headers", True, "setByte", "", "", "Argument[this]", "ReturnValue", "value", "manual"] + - ["io.netty.handler.codec", "Headers", True, "setByte", "", "", "Argument[0]", "Argument[this].Element.MapKey", "value", "manual"] + - ["io.netty.handler.codec", "Headers", True, "setChar", "", "", "Argument[this]", "ReturnValue", "value", "manual"] + - ["io.netty.handler.codec", "Headers", True, "setChar", "", "", "Argument[0]", "Argument[this].Element.MapKey", "value", "manual"] + - ["io.netty.handler.codec", "Headers", True, "setDouble", "", "", "Argument[this]", "ReturnValue", "value", "manual"] + - ["io.netty.handler.codec", "Headers", True, "setDouble", "", "", "Argument[0]", "Argument[this].Element.MapKey", "value", "manual"] + - ["io.netty.handler.codec", "Headers", True, "setFloat", "", "", "Argument[this]", "ReturnValue", "value", "manual"] + - ["io.netty.handler.codec", "Headers", True, "setFloat", "", "", "Argument[0]", "Argument[this].Element.MapKey", "value", "manual"] + - ["io.netty.handler.codec", "Headers", True, "setInt", "", "", "Argument[this]", "ReturnValue", "value", "manual"] + - ["io.netty.handler.codec", "Headers", True, "setInt", "", "", "Argument[0]", "Argument[this].Element.MapKey", "value", "manual"] + - ["io.netty.handler.codec", "Headers", True, "setLong", "", "", "Argument[this]", "ReturnValue", "value", "manual"] + - ["io.netty.handler.codec", "Headers", True, "setLong", "", "", "Argument[0]", "Argument[this].Element.MapKey", "value", "manual"] + - ["io.netty.handler.codec", "Headers", True, "setShort", "", "", "Argument[this]", "ReturnValue", "value", "manual"] + - ["io.netty.handler.codec", "Headers", True, "setShort", "", "", "Argument[0]", "Argument[this].Element.MapKey", "value", "manual"] + - ["io.netty.handler.codec", "Headers", True, "setTimeMillis", "", "", "Argument[this]", "ReturnValue", "value", "manual"] + - ["io.netty.handler.codec", "Headers", True, "setTimeMillis", "", "", "Argument[0]", "Argument[this].Element.MapKey", "value", "manual"] diff --git a/java/ql/lib/ext/io.netty.util.model.yml b/java/ql/lib/ext/io.netty.util.model.yml index 93f0e26e083..9b9b0be3f5a 100644 --- a/java/ql/lib/ext/io.netty.util.model.yml +++ b/java/ql/lib/ext/io.netty.util.model.yml @@ -3,25 +3,25 @@ extensions: pack: codeql/java-all extensible: summaryModel data: - - ["io.netty.util", "ReferenceCounted", True, "retain", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] - - ["io.netty.util", "ReferenceCounted", True, "touch", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] - - ["io.netty.util", "AsciiString", False, "AsciiString", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"] - - ["io.netty.util", "AsciiString", False, "array", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.util", "ReferenceCounted", True, "retain", "", "", "Argument[this]", "ReturnValue", "value", "manual"] + - ["io.netty.util", "ReferenceCounted", True, "touch", "", "", "Argument[this]", "ReturnValue", "value", "manual"] + - ["io.netty.util", "AsciiString", False, "AsciiString", "", "", "Argument[0]", "Argument[this]", "taint", "manual"] + - ["io.netty.util", "AsciiString", False, "array", "()", "", "Argument[this]", "ReturnValue", "taint", "manual"] - ["io.netty.util", "AsciiString", False, "cached", "(String)", "", "Argument[0]", "ReturnValue", "taint", "manual"] - - ["io.netty.util", "AsciiString", False, "concat", "(CharSequence)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.util", "AsciiString", False, "concat", "(CharSequence)", "", "Argument[this]", "ReturnValue", "taint", "manual"] - ["io.netty.util", "AsciiString", False, "concat", "(CharSequence)", "", "Argument[0]", "ReturnValue", "taint", "manual"] - - ["io.netty.util", "AsciiString", False, "copy", "(int,byte[],int,int)", "", "Argument[-1]", "Argument[1]", "taint", "manual"] - - ["io.netty.util", "AsciiString", False, "copy", "(int,char[],int,int)", "", "Argument[-1]", "Argument[1]", "taint", "manual"] + - ["io.netty.util", "AsciiString", False, "copy", "(int,byte[],int,int)", "", "Argument[this]", "Argument[1]", "taint", "manual"] + - ["io.netty.util", "AsciiString", False, "copy", "(int,char[],int,int)", "", "Argument[this]", "Argument[1]", "taint", "manual"] - ["io.netty.util", "AsciiString", False, "of", "(CharSequence)", "", "Argument[0]", "ReturnValue", "taint", "manual"] - - ["io.netty.util", "AsciiString", False, "replace", "(char,char)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.util", "AsciiString", False, "split", "(char)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.util", "AsciiString", False, "split", "(String,int)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.util", "AsciiString", False, "split", "(char)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.util", "AsciiString", False, "subSequence", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.util", "AsciiString", False, "toByteArray", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.util", "AsciiString", False, "toCharArray", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.util", "AsciiString", False, "toString", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.util", "AsciiString", False, "toLowerCase", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.util", "AsciiString", False, "toUpperCase", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["io.netty.util", "AsciiString", False, "trim", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["io.netty.util", "AsciiString", False, "replace", "(char,char)", "", "Argument[this]", "ReturnValue", "taint", "manual"] + - ["io.netty.util", "AsciiString", False, "split", "(char)", "", "Argument[this]", "ReturnValue", "taint", "manual"] + - ["io.netty.util", "AsciiString", False, "split", "(String,int)", "", "Argument[this]", "ReturnValue", "taint", "manual"] + - ["io.netty.util", "AsciiString", False, "split", "(char)", "", "Argument[this]", "ReturnValue", "taint", "manual"] + - ["io.netty.util", "AsciiString", False, "subSequence", "", "", "Argument[this]", "ReturnValue", "taint", "manual"] + - ["io.netty.util", "AsciiString", False, "toByteArray", "", "", "Argument[this]", "ReturnValue", "taint", "manual"] + - ["io.netty.util", "AsciiString", False, "toCharArray", "", "", "Argument[this]", "ReturnValue", "taint", "manual"] + - ["io.netty.util", "AsciiString", False, "toString", "", "", "Argument[this]", "ReturnValue", "taint", "manual"] + - ["io.netty.util", "AsciiString", False, "toLowerCase", "()", "", "Argument[this]", "ReturnValue", "taint", "manual"] + - ["io.netty.util", "AsciiString", False, "toUpperCase", "()", "", "Argument[this]", "ReturnValue", "taint", "manual"] + - ["io.netty.util", "AsciiString", False, "trim", "()", "", "Argument[this]", "ReturnValue", "taint", "manual"] - ["io.netty.util", "AsciiString", False, "trim", "(CharSequence)", "", "Argument[0]", "ReturnValue", "taint", "manual"] \ No newline at end of file From 48823aec7579dd26c22efe26f7db8dd1bb58225b Mon Sep 17 00:00:00 2001 From: Joe Farebrother <joefarebrother@github.com> Date: Tue, 21 Mar 2023 15:31:21 +0000 Subject: [PATCH 379/631] Fix tests and missing model after rebase --- java/ql/lib/ext/io.netty.handler.codec.http.model.yml | 1 + .../frameworks/netty/{Test.java => generated/TestA.java} | 2 +- java/ql/test/library-tests/frameworks/netty/manual/test.ql | 4 ++++ java/ql/test/library-tests/frameworks/netty/options | 1 - java/ql/test/library-tests/frameworks/netty/test.expected | 0 java/ql/test/library-tests/frameworks/netty/test.ql | 2 -- 6 files changed, 6 insertions(+), 4 deletions(-) rename java/ql/test/library-tests/frameworks/netty/{Test.java => generated/TestA.java} (96%) delete mode 100644 java/ql/test/library-tests/frameworks/netty/options delete mode 100644 java/ql/test/library-tests/frameworks/netty/test.expected delete mode 100644 java/ql/test/library-tests/frameworks/netty/test.ql diff --git a/java/ql/lib/ext/io.netty.handler.codec.http.model.yml b/java/ql/lib/ext/io.netty.handler.codec.http.model.yml index 657ae39f44c..fb283479dec 100644 --- a/java/ql/lib/ext/io.netty.handler.codec.http.model.yml +++ b/java/ql/lib/ext/io.netty.handler.codec.http.model.yml @@ -10,6 +10,7 @@ extensions: extensible: summaryModel data: - ["io.netty.handler.codec.http", "QueryStringEncoder", True, "QueryStringEncoder", "(String)", "", "Argument[0]", "Argument[this]", "taint", "ai-generated"] + - ["io.netty.handler.codec.http", "HttpHeaders", True, "add", "", "", "Argument[this]", "ReturnValue", "value", "manual"] - ["io.netty.handler.codec.http", "HttpHeaders", True, "add", "(CharSequence,Iterable)", "", "Argument[0]", "Argument[this].Element.MapKey", "taint", "manual"] - ["io.netty.handler.codec.http", "HttpHeaders", True, "add", "(CharSequence,Iterable)", "", "Argument[1].Element", "Argument[this].Element.MapValue", "taint", "manual"] - ["io.netty.handler.codec.http", "HttpHeaders", True, "add", "(CharSequence,Object)", "", "Argument[0]", "Argument[this].Element.MapKey", "taint", "manual"] diff --git a/java/ql/test/library-tests/frameworks/netty/Test.java b/java/ql/test/library-tests/frameworks/netty/generated/TestA.java similarity index 96% rename from java/ql/test/library-tests/frameworks/netty/Test.java rename to java/ql/test/library-tests/frameworks/netty/generated/TestA.java index 938c9a9e468..4c70d32d39d 100644 --- a/java/ql/test/library-tests/frameworks/netty/Test.java +++ b/java/ql/test/library-tests/frameworks/netty/generated/TestA.java @@ -4,7 +4,7 @@ import io.netty.resolver.SimpleNameResolver; import io.netty.util.concurrent.Future; // Test case generated by GenerateFlowTestCase.ql -public class Test { +public class TestA { Object source() { return null; diff --git a/java/ql/test/library-tests/frameworks/netty/manual/test.ql b/java/ql/test/library-tests/frameworks/netty/manual/test.ql index 10c5f909c2f..1f707c18e10 100644 --- a/java/ql/test/library-tests/frameworks/netty/manual/test.ql +++ b/java/ql/test/library-tests/frameworks/netty/manual/test.ql @@ -9,3 +9,7 @@ class Conf extends DefaultTaintFlowConf { node instanceof RemoteFlowSource } } + +class LegacyConfig extends EnableLegacyConfiguration { + LegacyConfig() { this instanceof Unit } +} diff --git a/java/ql/test/library-tests/frameworks/netty/options b/java/ql/test/library-tests/frameworks/netty/options deleted file mode 100644 index 84eb569be33..00000000000 --- a/java/ql/test/library-tests/frameworks/netty/options +++ /dev/null @@ -1 +0,0 @@ -//semmle-extractor-options: --javac-args -cp ${testdir}/../../../stubs/netty-4.1.x diff --git a/java/ql/test/library-tests/frameworks/netty/test.expected b/java/ql/test/library-tests/frameworks/netty/test.expected deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/java/ql/test/library-tests/frameworks/netty/test.ql b/java/ql/test/library-tests/frameworks/netty/test.ql deleted file mode 100644 index 5d91e4e8e26..00000000000 --- a/java/ql/test/library-tests/frameworks/netty/test.ql +++ /dev/null @@ -1,2 +0,0 @@ -import java -import TestUtilities.InlineFlowTest From 3eed4b418695c9442ffc14a5e0d8ee799e54c443 Mon Sep 17 00:00:00 2001 From: Tony Torralba <atorralba@users.noreply.github.com> Date: Thu, 23 Mar 2023 17:05:53 +0100 Subject: [PATCH 380/631] Move JndiInjectionSanitizer to importable file Add change note --- java/ql/lib/change-notes/2023-03-23-jndi-sanitizer.md | 4 ++++ .../ql/lib/semmle/code/java/security/JndiInjection.qll | 3 +++ .../semmle/code/java/security/JndiInjectionQuery.qll | 10 ++-------- 3 files changed, 9 insertions(+), 8 deletions(-) create mode 100644 java/ql/lib/change-notes/2023-03-23-jndi-sanitizer.md diff --git a/java/ql/lib/change-notes/2023-03-23-jndi-sanitizer.md b/java/ql/lib/change-notes/2023-03-23-jndi-sanitizer.md new file mode 100644 index 00000000000..20738f07c05 --- /dev/null +++ b/java/ql/lib/change-notes/2023-03-23-jndi-sanitizer.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* Added the extensible abstract class `JndiInjectionSanitizer`. Now this class can be extended to add more sanitizers to the `java/jndi-injection` query. diff --git a/java/ql/lib/semmle/code/java/security/JndiInjection.qll b/java/ql/lib/semmle/code/java/security/JndiInjection.qll index cacf725cc99..6a05bbfdc2c 100644 --- a/java/ql/lib/semmle/code/java/security/JndiInjection.qll +++ b/java/ql/lib/semmle/code/java/security/JndiInjection.qll @@ -9,6 +9,9 @@ private import semmle.code.java.frameworks.SpringLdap /** A data flow sink for unvalidated user input that is used in JNDI lookup. */ abstract class JndiInjectionSink extends DataFlow::Node { } +/** A sanitizer for JNDI injection vulnerabilities. */ +abstract class JndiInjectionSanitizer extends DataFlow::Node { } + /** * A unit class for adding additional taint steps. * diff --git a/java/ql/lib/semmle/code/java/security/JndiInjectionQuery.qll b/java/ql/lib/semmle/code/java/security/JndiInjectionQuery.qll index 1c8ef38c7ea..970b8a65cef 100644 --- a/java/ql/lib/semmle/code/java/security/JndiInjectionQuery.qll +++ b/java/ql/lib/semmle/code/java/security/JndiInjectionQuery.qll @@ -17,8 +17,8 @@ class JndiInjectionFlowConfig extends TaintTracking::Configuration { override predicate isSink(DataFlow::Node sink) { sink instanceof JndiInjectionSink } override predicate isSanitizer(DataFlow::Node node) { - node.getType() instanceof PrimitiveType or node.getType() instanceof BoxedType - or + node.getType() instanceof PrimitiveType or + node.getType() instanceof BoxedType or node instanceof JndiInjectionSanitizer } @@ -27,12 +27,6 @@ class JndiInjectionFlowConfig extends TaintTracking::Configuration { } } -/** - * A Class to be extended for Sanitizer Customizations - */ - -abstract class JndiInjectionSanitizer extends DataFlow::Node { } - /** * A method that does a JNDI lookup when it receives a `SearchControls` argument with `setReturningObjFlag` = `true` */ From a6b775f769003b945d13e255626fba8a225baa32 Mon Sep 17 00:00:00 2001 From: Jami Cogswell <jcogs33@Jamis-MacBook-Pro.local> Date: Tue, 17 Jan 2023 10:34:23 -0500 Subject: [PATCH 381/631] Java: update TopJdkApis test case for top-300 --- java/ql/test/ext/TopJdkApis/TopJdkApis.qll | 55 ++++++++++++++++++- .../test/ext/TopJdkApis/TopJdkApisTest.java | 8 +++ 2 files changed, 62 insertions(+), 1 deletion(-) diff --git a/java/ql/test/ext/TopJdkApis/TopJdkApis.qll b/java/ql/test/ext/TopJdkApis/TopJdkApis.qll index 9bd5e1f9623..aa13db92d8e 100644 --- a/java/ql/test/ext/TopJdkApis/TopJdkApis.qll +++ b/java/ql/test/ext/TopJdkApis/TopJdkApis.qll @@ -111,7 +111,60 @@ predicate topJdkApiName(string apiName) { "java.util.Collection#iterator()", "java.util.Map#computeIfAbsent(Object,Function)", "java.text.SimpleDateFormat#SimpleDateFormat(String)", "java.util.StringJoiner#add(CharSequence)", "java.lang.Long#longValue()", - "java.util.stream.Collectors#joining(CharSequence)" + "java.util.stream.Collectors#joining(CharSequence)", + // top 300 JDK APIs + "java.lang.Math#max(int,int)", "java.util.Map#of(Object,Object)", + "java.lang.Long#valueOf(long)", "java.util.Random#nextInt(int)", + "java.lang.Long#valueOf(String)", "java.util.concurrent.CountDownLatch#await(long,TimeUnit)", + "java.util.Properties#getProperty(String)", "java.util.Optional#isEmpty()", + "java.util.concurrent.CompletableFuture#get()", "java.util.Objects#isNull(Object)", + "java.lang.StringBuilder#append(long)", "java.awt.Container#add(Component,Object)", + "java.math.BigDecimal#add(BigDecimal)", "java.sql.PreparedStatement#executeQuery()", + "java.lang.StringBuilder#StringBuilder(int)", "java.util.Map#forEach(BiConsumer)", + "java.math.BigDecimal#BigDecimal(int)", "java.util.Collections#unmodifiableList(List)", + "java.util.Properties#put(Object,Object)", "java.sql.Timestamp#Timestamp(long)", + "java.util.List#equals(Object)", "java.lang.String#indexOf(int)", + "java.lang.Long#toString(long)", "java.lang.Integer#Integer(int)", + "java.util.concurrent.atomic.AtomicBoolean#get()", + "java.lang.System#setProperty(String,String)", "java.util.concurrent.Future#get()", + "java.lang.Thread#start()", "java.util.Set#of(Object)", "java.util.Calendar#set(int,int)", + "java.time.Duration#ofSeconds(long)", "java.lang.System#arraycopy(Object,int,Object,int,int)", + "java.net.URI#toString()", "java.util.concurrent.atomic.AtomicInteger#incrementAndGet()", + "java.util.Set#remove(Object)", "java.lang.Boolean#parseBoolean(String)", + "java.util.Calendar#getTime()", "java.nio.charset.Charset#name()", + "java.lang.ThreadLocal#get()", "java.lang.Class#getCanonicalName()", + "java.util.List#remove(Object)", "java.lang.Throwable#toString()", + "java.util.stream.Stream#toList()", "java.io.ByteArrayOutputStream#toByteArray()", + "java.util.concurrent.atomic.AtomicLong#get()", + "java.lang.NullPointerException#NullPointerException(String)", "java.util.List#of()", + "java.util.Calendar#getInstance()", "java.util.Calendar#get(int)", + "java.util.Optional#orElseThrow()", "java.lang.System#lineSeparator()", + "java.lang.Boolean#booleanValue()", "java.util.logging.Logger#isLoggable(Level)", + "java.lang.Enum#hashCode()", "java.util.List#hashCode()", + "java.lang.reflect.Method#invoke(Object,Object[])", "java.lang.String#String(byte[],Charset)", + "java.util.Comparator#comparing(Function)", "java.util.Arrays#toString(Object[])", + "java.time.LocalDate#now()", "java.util.function.Function#identity()", + "java.io.OutputStream#write(byte[])", "java.lang.Integer#equals(Object)", + "java.io.BufferedReader#BufferedReader(Reader)", "java.io.DataInput#readInt()", + "java.io.BufferedReader#readLine()", "java.util.Map#entry(Object,Object)", + "java.lang.Runnable#run()", "java.util.ResourceBundle#getString(String)", + "java.util.Iterator#remove()", "java.lang.String#join(CharSequence,Iterable)", + "java.util.concurrent.atomic.AtomicBoolean#set(boolean)", "java.time.LocalDateTime#now()", + "java.sql.ResultSet#getLong(String)", "java.text.DateFormat#parse(String)", + "java.lang.String#toString()", "java.lang.Integer#valueOf(String)", + "java.util.regex.Matcher#find()", "java.io.DataOutput#writeInt(int)", + "java.util.HashMap#HashMap(int)", "java.util.stream.Stream#sorted(Comparator)", + "java.lang.String#toCharArray()", + "java.util.concurrent.atomic.AtomicInteger#AtomicInteger(int)", + "java.lang.String#String(byte[])", "java.lang.reflect.Method#getName()", + "java.sql.ResultSet#getString(int)", "java.net.URI#create(String)", + "java.lang.Enum#ordinal()", "java.util.concurrent.atomic.AtomicReference#set(Object)", + "java.util.concurrent.CompletableFuture#join()", + "java.io.FileInputStream#FileInputStream(File)", "java.io.File#delete()", + "java.util.concurrent.TimeUnit#toMillis(long)", "java.util.List#of(Object,Object,Object)", + "java.lang.String#compareTo(String)", "java.util.stream.IntStream#range(int,int)", + "java.math.BigInteger#valueOf(long)", "java.util.List#remove(int)", + "java.util.HashMap#HashMap(Map)", "java.util.function.BiConsumer#accept(Object,Object)" ] } diff --git a/java/ql/test/ext/TopJdkApis/TopJdkApisTest.java b/java/ql/test/ext/TopJdkApis/TopJdkApisTest.java index 49a7396ad64..6ef7d70d118 100644 --- a/java/ql/test/ext/TopJdkApis/TopJdkApisTest.java +++ b/java/ql/test/ext/TopJdkApis/TopJdkApisTest.java @@ -1,6 +1,10 @@ +import java.awt.Container; +import java.io.BufferedReader; import java.io.ByteArrayInputStream; +import java.io.FileInputStream; import java.lang.IllegalStateException; import java.lang.IndexOutOfBoundsException; +import java.lang.NullPointerException; import java.lang.Math; import java.lang.System; import java.math.BigDecimal; @@ -17,9 +21,13 @@ import java.util.Map; import java.util.Objects; import java.util.StringJoiner; import java.util.UUID; +import java.util.concurrent.CompletableFuture; import java.util.concurrent.CountDownLatch; +import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicLong; import java.util.concurrent.atomic.AtomicReference; +import java.util.logging.Logger; import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.stream.Collectors; From 971b0e88141dfbe7d9feefe0f7c28457b36d482b Mon Sep 17 00:00:00 2001 From: Jami Cogswell <jcogs33@Jamis-MacBook-Pro.local> Date: Thu, 23 Mar 2023 17:50:08 -0400 Subject: [PATCH 382/631] Java: -1 to this conflict --- java/ql/lib/ext/java.awt.model.yml | 6 +++ java/ql/lib/ext/java.io.model.yml | 4 ++ java/ql/lib/ext/java.lang.model.yml | 40 ++++++++++++++----- java/ql/lib/ext/java.lang.reflect.model.yml | 12 ++++++ java/ql/lib/ext/java.math.model.yml | 3 ++ java/ql/lib/ext/java.nio.charset.model.yml | 6 +++ java/ql/lib/ext/java.sql.model.yml | 4 ++ java/ql/lib/ext/java.text.model.yml | 6 +++ java/ql/lib/ext/java.time.model.yml | 8 ++++ .../ext/java.util.concurrent.atomic.model.yml | 6 +++ .../ql/lib/ext/java.util.concurrent.model.yml | 5 +++ java/ql/lib/ext/java.util.function.model.yml | 7 ++++ java/ql/lib/ext/java.util.logging.model.yml | 6 +++ java/ql/lib/ext/java.util.model.yml | 21 +++++++++- java/ql/lib/ext/java.util.regex.model.yml | 6 +++ java/ql/lib/ext/java.util.stream.model.yml | 1 + java/ql/test/ext/TopJdkApis/TopJdkApis.qll | 1 + .../ext/TopJdkApis/TopJdkApisTest.expected | 1 + 18 files changed, 131 insertions(+), 12 deletions(-) create mode 100644 java/ql/lib/ext/java.awt.model.yml create mode 100644 java/ql/lib/ext/java.lang.reflect.model.yml create mode 100644 java/ql/lib/ext/java.nio.charset.model.yml diff --git a/java/ql/lib/ext/java.awt.model.yml b/java/ql/lib/ext/java.awt.model.yml new file mode 100644 index 00000000000..a8dd6f1ca1a --- /dev/null +++ b/java/ql/lib/ext/java.awt.model.yml @@ -0,0 +1,6 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: summaryModel + data: + - ["java.awt", "Container", True, "add", "(Component,Object)", "", "Argument[0]", "Argument[-1].Element", "value", "manual"] diff --git a/java/ql/lib/ext/java.io.model.yml b/java/ql/lib/ext/java.io.model.yml index 4ba64033fa4..e94f2dd882d 100644 --- a/java/ql/lib/ext/java.io.model.yml +++ b/java/ql/lib/ext/java.io.model.yml @@ -59,9 +59,11 @@ extensions: - ["java.io", "CharArrayReader", False, "CharArrayReader", "", "", "Argument[0]", "Argument[this]", "taint", "manual"] - ["java.io", "CharArrayWriter", True, "toCharArray", "", "", "Argument[this]", "ReturnValue", "taint", "manual"] - ["java.io", "DataInput", True, "readFully", "", "", "Argument[this]", "Argument[0]", "taint", "manual"] + - ["java.io", "DataInput", True, "readInt", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - ["java.io", "DataInput", True, "readLine", "()", "", "Argument[this]", "ReturnValue", "taint", "manual"] - ["java.io", "DataInput", True, "readUTF", "()", "", "Argument[this]", "ReturnValue", "taint", "manual"] - ["java.io", "DataInputStream", False, "DataInputStream", "", "", "Argument[0]", "Argument[this]", "taint", "manual"] + - ["java.io", "DataOutput", True, "writeInt", "(int)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] - ["java.io", "File", False, "File", "", "", "Argument[0]", "Argument[this]", "taint", "manual"] - ["java.io", "File", False, "File", "", "", "Argument[1]", "Argument[this]", "taint", "manual"] - ["java.io", "File", True, "getAbsoluteFile", "", "", "Argument[this]", "ReturnValue", "taint", "manual"] @@ -72,6 +74,7 @@ extensions: - ["java.io", "File", True, "toPath", "", "", "Argument[this]", "ReturnValue", "taint", "manual"] - ["java.io", "File", True, "toString", "", "", "Argument[this]", "ReturnValue", "taint", "manual"] - ["java.io", "File", True, "toURI", "", "", "Argument[this]", "ReturnValue", "taint", "manual"] + - ["java.io", "FileInputStream", False, "FileInputStream", "(File)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] - ["java.io", "FilterOutputStream", True, "FilterOutputStream", "(OutputStream)", "", "Argument[0]", "Argument[this]", "taint", "manual"] - ["java.io", "InputStream", True, "read", "(byte[])", "", "Argument[this]", "Argument[0]", "taint", "manual"] - ["java.io", "InputStream", True, "read", "(byte[],int,int)", "", "Argument[this]", "Argument[0]", "taint", "manual"] @@ -93,4 +96,5 @@ extensions: pack: codeql/java-all extensible: neutralModel data: + - ["java.io", "File", "delete", "()", "manual"] - ["java.io", "File", "exists", "()", "manual"] diff --git a/java/ql/lib/ext/java.lang.model.yml b/java/ql/lib/ext/java.lang.model.yml index 774cf751a13..a53337d2f87 100644 --- a/java/ql/lib/ext/java.lang.model.yml +++ b/java/ql/lib/ext/java.lang.model.yml @@ -58,6 +58,7 @@ extensions: - ["java.lang", "Iterable", True, "forEach", "(Consumer)", "", "Argument[this].Element", "Argument[0].Parameter[0]", "value", "manual"] - ["java.lang", "Iterable", True, "iterator", "()", "", "Argument[this].Element", "ReturnValue.Element", "value", "manual"] - ["java.lang", "Iterable", True, "spliterator", "()", "", "Argument[this].Element", "ReturnValue.Element", "value", "manual"] + - ["java.lang", "NullPointerException", False, "NullPointerException", "(String)", "", "Argument[0]", "Argument[-1].SyntheticField[java.lang.Throwable.message]", "value", "manual"] - ["java.lang", "Object", True, "clone", "", "", "Argument[this].Element", "ReturnValue.Element", "value", "manual"] - ["java.lang", "Object", True, "clone", "", "", "Argument[this].MapKey", "ReturnValue.MapKey", "value", "manual"] - ["java.lang", "Object", True, "clone", "", "", "Argument[this].MapValue", "ReturnValue.MapValue", "value", "manual"] @@ -107,50 +108,69 @@ extensions: - ["java.lang", "StringBuffer", True, "StringBuffer", "(String)", "", "Argument[0]", "Argument[this]", "taint", "manual"] - ["java.lang", "StringBuilder", True, "StringBuilder", "", "", "Argument[0]", "Argument[this]", "taint", "manual"] - ["java.lang", "System", False, "arraycopy", "", "", "Argument[0]", "Argument[2]", "taint", "manual"] + - ["java.lang", "ThreadLocal", True, "get", "()", "", "Argument[-1].SyntheticField[java.lang.ThreadLocal.value]", "ReturnValue", "value", "manual"] # ! not sure if this model is correct, and if should be neutral model instead - ["java.lang", "Throwable", False, "Throwable", "(Throwable)", "", "Argument[0]", "Argument[this].SyntheticField[java.lang.Throwable.cause]", "value", "manual"] - ["java.lang", "Throwable", True, "getCause", "()", "", "Argument[this].SyntheticField[java.lang.Throwable.cause]", "ReturnValue", "value", "manual"] - ["java.lang", "Throwable", True, "getMessage", "()", "", "Argument[this].SyntheticField[java.lang.Throwable.message]", "ReturnValue", "value", "manual"] + - ["java.lang", "Throwable", True, "toString", "()", "", "Argument[-1].SyntheticField[java.lang.Throwable.message]", "ReturnValue", "taint", "manual"] # ! little unsure about this one... - addsTo: pack: codeql/java-all extensible: neutralModel data: - ["java.lang", "AbstractStringBuilder", "length", "()", "manual"] - ["java.lang", "Boolean", "equals", "(Object)", "manual"] + - ["java.lang", "Class", "getCanonicalName", "()", "manual"] - ["java.lang", "Class", "getClassLoader", "()", "manual"] - ["java.lang", "Class", "getName", "()", "manual"] - ["java.lang", "Class", "getSimpleName", "()", "manual"] - ["java.lang", "Class", "isAssignableFrom", "(Class)", "manual"] - ["java.lang", "Enum", "Enum", "(String,int)", "manual"] - ["java.lang", "Enum", "equals", "(Object)", "manual"] + - ["java.lang", "Enum", "hashCode", "()", "manual"] - ["java.lang", "Enum", "name", "()", "manual"] + - ["java.lang", "Enum", "ordinal", "()", "manual"] - ["java.lang", "Enum", "toString", "()", "manual"] + - ["java.lang", "Integer", "equals", "(Object)", "manual"] - ["java.lang", "Long", "equals", "(Object)", "manual"] - ["java.lang", "Object", "equals", "(Object)", "manual"] - ["java.lang", "Object", "getClass", "()", "manual"] - ["java.lang", "Object", "hashCode", "()", "manual"] - ["java.lang", "Object", "toString", "()", "manual"] + - ["java.lang", "Runnable", "run", "()", "manual"] + - ["java.lang", "String", "compareTo", "(String)", "manual"] - ["java.lang", "String", "contains", "(CharSequence)", "manual"] - ["java.lang", "String", "endsWith", "(String)", "manual"] - ["java.lang", "String", "equals", "(Object)", "manual"] - ["java.lang", "String", "equalsIgnoreCase", "(String)", "manual"] - ["java.lang", "String", "hashCode", "()", "manual"] + - ["java.lang", "String", "indexOf", "(int)", "manual"] - ["java.lang", "String", "indexOf", "(String)", "manual"] - ["java.lang", "String", "isEmpty", "()", "manual"] - ["java.lang", "String", "length", "()", "manual"] - ["java.lang", "String", "startsWith", "(String)", "manual"] - ["java.lang", "System", "currentTimeMillis", "()", "manual"] + - ["java.lang", "System", "lineSeparator", "()", "manual"] # ! double-check... - ["java.lang", "System", "nanoTime", "()", "manual"] - ["java.lang", "Thread", "currentThread", "()", "manual"] - ["java.lang", "Thread", "sleep", "(long)", "manual"] + - ["java.lang", "Thread", "start", "()", "manual"] # The below APIs have numeric flow and are currently being stored as neutral models. # These may be changed to summary models with kinds "value-numeric" and "taint-numeric" (or similar) in the future. - - ["java.lang", "Integer", "intValue", "()", "manual"] # taint-numeric - - ["java.lang", "Integer", "parseInt", "(String)", "manual"] # taint-numeric - - ["java.lang", "Integer", "toString", "(int)", "manual"] # taint-numeric - - ["java.lang", "Integer", "valueOf", "(int)", "manual"] # taint-numeric - - ["java.lang", "Long", "longValue", "()", "manual"] # taint-numeric - - ["java.lang", "Long", "parseLong", "(String)", "manual"] # taint-numeric - - ["java.lang", "Long", "toString", "()", "manual"] # taint-numeric - - ["java.lang", "Math", "min", "(int,int)", "manual"] # value-numeric - - ["java.lang", "String", "valueOf", "(int)", "manual"] # taint-numeric - - ["java.lang", "String", "valueOf", "(long)", "manual"] # taint-numeric + - ["java.lang", "Boolean", "booleanValue", "()", "manual"] # taint-numeric + - ["java.lang", "Boolean", "parseBoolean", "(String)", "manual"] # taint-numeric + - ["java.lang", "Integer", "Integer", "(int)", "manual"] # taint-numeric + - ["java.lang", "Integer", "intValue", "()", "manual"] # taint-numeric + - ["java.lang", "Integer", "parseInt", "(String)", "manual"] # taint-numeric + - ["java.lang", "Integer", "toString", "(int)", "manual"] # taint-numeric + - ["java.lang", "Integer", "valueOf", "(int)", "manual"] # taint-numeric + - ["java.lang", "Integer", "valueOf", "(String)", "manual"] # taint-numeric # ! should probably make this and others like it have a "" signature instead... + - ["java.lang", "Long", "longValue", "()", "manual"] # taint-numeric + - ["java.lang", "Long", "parseLong", "(String)", "manual"] # taint-numeric + - ["java.lang", "Long", "toString", "()", "manual"] # taint-numeric + - ["java.lang", "Long", "toString", "(long)", "manual"] # taint-numeric + - ["java.lang", "Long", "valueOf", "(long)", "manual"] # taint-numeric + - ["java.lang", "Long", "valueOf", "(String)", "manual"] # taint-numeric + - ["java.lang", "Math", "max", "(int,int)", "manual"] # value-numeric + - ["java.lang", "Math", "min", "(int,int)", "manual"] # value-numeric + - ["java.lang", "String", "valueOf", "(int)", "manual"] # taint-numeric + - ["java.lang", "String", "valueOf", "(long)", "manual"] # taint-numeric diff --git a/java/ql/lib/ext/java.lang.reflect.model.yml b/java/ql/lib/ext/java.lang.reflect.model.yml new file mode 100644 index 00000000000..6de65bc46b9 --- /dev/null +++ b/java/ql/lib/ext/java.lang.reflect.model.yml @@ -0,0 +1,12 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: summaryModel + data: + - ["java.lang.reflect", "Method", False, "invoke", "(Object,Object[])", "", "Argument[1].ArrayElement", "Argument[-1].Parameter[0]", "value", "manual"] # ! very unsure if this model is correct... + + - addsTo: + pack: codeql/java-all + extensible: neutralModel + data: + - ["java.lang.reflect", "Method", "getName", "()", "manual"] # ! seems uninteresting flow to me, but maybe double-check diff --git a/java/ql/lib/ext/java.math.model.yml b/java/ql/lib/ext/java.math.model.yml index 1d45a4076bf..944b23e0535 100644 --- a/java/ql/lib/ext/java.math.model.yml +++ b/java/ql/lib/ext/java.math.model.yml @@ -7,6 +7,9 @@ extensions: # The below APIs have numeric flow and are currently being stored as neutral models. # These may be changed to summary models with kinds "value-numeric" and "taint-numeric" (or similar) in the future. + - ["java.math", "BigDecimal", "BigDecimal", "(int)", "manual"] # taint-numeric - ["java.math", "BigDecimal", "BigDecimal", "(String)", "manual"] # taint-numeric + - ["java.math", "BigDecimal", "add", "(BigDecimal)", "manual"] # taint-numeric - ["java.math", "BigDecimal", "valueOf", "(double)", "manual"] # taint-numeric - ["java.math", "BigDecimal", "valueOf", "(long)", "manual"] # taint-numeric + - ["java.math", "BigInteger", "valueOf", "(long)", "manual"] # taint-numeric diff --git a/java/ql/lib/ext/java.nio.charset.model.yml b/java/ql/lib/ext/java.nio.charset.model.yml new file mode 100644 index 00000000000..e961a06256e --- /dev/null +++ b/java/ql/lib/ext/java.nio.charset.model.yml @@ -0,0 +1,6 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: summaryModel + data: + - ["java.nio.charset", "Charset", False, "name", "()", "", "Argument[-1].SyntheticField[java.nio.charset.Charset.canonicalName]", "ReturnValue", "value", "manual"] diff --git a/java/ql/lib/ext/java.sql.model.yml b/java/ql/lib/ext/java.sql.model.yml index def9f5d1863..14b3c7c3685 100644 --- a/java/ql/lib/ext/java.sql.model.yml +++ b/java/ql/lib/ext/java.sql.model.yml @@ -21,6 +21,7 @@ extensions: extensible: summaryModel data: - ["java.sql", "Connection", True, "nativeSQL", "(String)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["java.sql", "PreparedStatement", True, "executeQuery", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] # ! this should maybe be a neutral model, not sure if this really counts as "flow through"... - ["java.sql", "PreparedStatement", True, "setString", "(int,String)", "", "Argument[1]", "Argument[this]", "value", "manual"] - ["java.sql", "ResultSet", True, "getString", "(String)", "", "Argument[this]", "ReturnValue", "taint", "manual"] - addsTo: @@ -32,3 +33,6 @@ extensions: # These may be changed to summary models with kinds "value-numeric" and "taint-numeric" (or similar) in the future. - ["java.sql", "PreparedStatement", "setInt", "(int,int)", "manual"] # value-numeric - ["java.sql", "ResultSet", "getInt", "(String)", "manual"] # taint-numeric + - ["java.sql", "ResultSet", "getLong", "(String)", "manual"] # taint-numeric + - ["java.sql", "ResultSet", "getString", "(int)", "manual"] # taint-numeric + - ["java.sql", "Timestamp", "Timestamp", "(long)", "manual"] # taint-numeric diff --git a/java/ql/lib/ext/java.text.model.yml b/java/ql/lib/ext/java.text.model.yml index bbb01596f17..4a087ec34b2 100644 --- a/java/ql/lib/ext/java.text.model.yml +++ b/java/ql/lib/ext/java.text.model.yml @@ -1,4 +1,10 @@ extensions: + - addsTo: + pack: codeql/java-all + extensible: summaryModel + data: + - ["java.text", "DateFormat", True, "parse", "(String)", "", "Argument[0]", "ReturnValue", "taint", "manual"] # ! maybe not interesting flow and should be neutral model? + - addsTo: pack: codeql/java-all extensible: neutralModel diff --git a/java/ql/lib/ext/java.time.model.yml b/java/ql/lib/ext/java.time.model.yml index 002240c6488..ae5b8bc0e63 100644 --- a/java/ql/lib/ext/java.time.model.yml +++ b/java/ql/lib/ext/java.time.model.yml @@ -1,9 +1,17 @@ extensions: + - addsTo: + pack: codeql/java-all + extensible: summaryModel + data: + - ["java.time", "Duration", False, "ofSeconds", "(long)", "", "Argument[0]", "ReturnValue", "taint", "manual"] # ! maybe not interesting flow and should be neutral model? + - addsTo: pack: codeql/java-all extensible: neutralModel data: - ["java.time", "Instant", "now", "()", "manual"] + - ["java.time", "LocalDate", "now", "()", "manual"] + - ["java.time", "LocalDateTime", "now", "()", "manual"] - ["java.time", "ZonedDateTime", "now", "()", "manual"] # The below APIs have numeric flow and are currently being stored as neutral models. diff --git a/java/ql/lib/ext/java.util.concurrent.atomic.model.yml b/java/ql/lib/ext/java.util.concurrent.atomic.model.yml index b4b49273790..1e563a76d0f 100644 --- a/java/ql/lib/ext/java.util.concurrent.atomic.model.yml +++ b/java/ql/lib/ext/java.util.concurrent.atomic.model.yml @@ -5,12 +5,18 @@ extensions: data: - ["java.util.concurrent.atomic", "AtomicReference", False, "AtomicReference", "(Object)", "", "Argument[0]", "Argument[this].SyntheticField[java.util.concurrent.atomic.AtomicReference.value]", "value", "manual"] - ["java.util.concurrent.atomic", "AtomicReference", False, "get", "()", "", "Argument[this].SyntheticField[java.util.concurrent.atomic.AtomicReference.value]", "ReturnValue", "value", "manual"] + - ["java.util.concurrent.atomic", "AtomicReference", False, "set", "(Object)", "", "Argument[0]", "Argument[-1].SyntheticField[java.util.concurrent.atomic.AtomicReference.value]", "value", "manual"] - addsTo: pack: codeql/java-all extensible: neutralModel data: + - ["java.util.concurrent.atomic", "AtomicBoolean", "get", "()", "manual"] + - ["java.util.concurrent.atomic", "AtomicBoolean", "set", "(boolean)", "manual"] + # The below APIs have numeric flow and are currently being stored as neutral models. # These may be changed to summary models with kinds "value-numeric" and "taint-numeric" (or similar) in the future. - ["java.util.concurrent.atomic", "AtomicInteger", "AtomicInteger", "(int)", "manual"] # value-numeric - ["java.util.concurrent.atomic", "AtomicInteger", "get", "()", "manual"] # value-numeric + - ["java.util.concurrent.atomic", "AtomicInteger", "incrementAndGet", "()", "manual"] # taint-numeric + - ["java.util.concurrent.atomic", "AtomicLong", "get", "()", "manual"] # value-numeric diff --git a/java/ql/lib/ext/java.util.concurrent.model.yml b/java/ql/lib/ext/java.util.concurrent.model.yml index dd0c6b75754..1f8d4d01350 100644 --- a/java/ql/lib/ext/java.util.concurrent.model.yml +++ b/java/ql/lib/ext/java.util.concurrent.model.yml @@ -17,7 +17,10 @@ extensions: - ["java.util.concurrent", "BlockingQueue", True, "poll", "(long,TimeUnit)", "", "Argument[this].Element", "ReturnValue", "value", "manual"] - ["java.util.concurrent", "BlockingQueue", True, "put", "(Object)", "", "Argument[0]", "Argument[this].Element", "value", "manual"] - ["java.util.concurrent", "BlockingQueue", True, "take", "()", "", "Argument[this].Element", "ReturnValue", "value", "manual"] + - ["java.util.concurrent", "CompletableFuture", False, "get", "()", "", "Argument[-1].SyntheticField[java.util.concurrent.CompletableFuture.value]", "ReturnValue", "value", "manual"] # ! not sure if using SyntheticField is correct here; also, should prbly remove this for `Future.get` below's subtyping to handle. + - ["java.util.concurrent", "CompletableFuture", False, "join", "()", "", "Argument[-1].SyntheticField[java.util.concurrent.CompletableFuture.value]", "ReturnValue", "value", "manual"] # ! not sure if using SyntheticField is correct here - ["java.util.concurrent", "ConcurrentHashMap", True, "elements", "()", "", "Argument[this].MapValue", "ReturnValue.Element", "value", "manual"] + - ["java.util.concurrent", "Future", True, "get", "()", "", "Argument[-1].SyntheticField[java.util.concurrent.Future.value]", "ReturnValue", "value", "manual"] # ! not sure if using SyntheticField is correct here - ["java.util.concurrent", "TransferQueue", True, "transfer", "(Object)", "", "Argument[0]", "Argument[this].Element", "value", "manual"] - ["java.util.concurrent", "TransferQueue", True, "tryTransfer", "(Object)", "", "Argument[0]", "Argument[this].Element", "value", "manual"] - ["java.util.concurrent", "TransferQueue", True, "tryTransfer", "(Object,long,TimeUnit)", "", "Argument[0]", "Argument[this].Element", "value", "manual"] @@ -26,9 +29,11 @@ extensions: pack: codeql/java-all extensible: neutralModel data: + - ["java.util.concurrent", "CountDownLatch", "await", "(long,TimeUnit)", "manual"] - ["java.util.concurrent", "CountDownLatch", "countDown", "()", "manual"] # The below APIs have numeric flow and are currently being stored as neutral models. # These may be changed to summary models with kinds "value-numeric" and "taint-numeric" (or similar) in the future. - ["java.util.concurrent", "CountDownLatch", "CountDownLatch", "(int)", "manual"] # value-numeric - ["java.util.concurrent", "CountDownLatch", "getCount", "()", "manual"] # value-numeric + - ["java.util.concurrent", "TimeUnit", "toMillis", "(long)", "manual"] # taint-numeric diff --git a/java/ql/lib/ext/java.util.function.model.yml b/java/ql/lib/ext/java.util.function.model.yml index 90ed9c1b9ab..d81882b70c0 100644 --- a/java/ql/lib/ext/java.util.function.model.yml +++ b/java/ql/lib/ext/java.util.function.model.yml @@ -4,3 +4,10 @@ extensions: extensible: sinkModel data: - ["java.util.function", "Predicate", False, "test", "(Object)", "", "Argument[this]", "regex-use[0]", "manual"] + + - addsTo: + pack: codeql/java-all + extensible: neutralModel + data: + - ["java.util.function", "BiConsumer", "accept", "(Object,Object)", "manual"] # ! remove this model? + - ["java.util.function", "Function", "identity", "()", "manual"] # ! remove this model? diff --git a/java/ql/lib/ext/java.util.logging.model.yml b/java/ql/lib/ext/java.util.logging.model.yml index 41a59ceee3a..2d5421e2f47 100644 --- a/java/ql/lib/ext/java.util.logging.model.yml +++ b/java/ql/lib/ext/java.util.logging.model.yml @@ -42,3 +42,9 @@ extensions: extensible: summaryModel data: - ["java.util.logging", "LogRecord", False, "LogRecord", "", "", "Argument[1]", "Argument[this]", "taint", "manual"] + + - addsTo: + pack: codeql/java-all + extensible: neutralModel + data: + - ["java.util.logging", "Logger", "isLoggable", "(Level)", "manual"] diff --git a/java/ql/lib/ext/java.util.model.yml b/java/ql/lib/ext/java.util.model.yml index 5f3dad67c37..dec98781db4 100644 --- a/java/ql/lib/ext/java.util.model.yml +++ b/java/ql/lib/ext/java.util.model.yml @@ -290,6 +290,7 @@ extensions: - ["java.util", "Queue", True, "peek", "()", "", "Argument[this].Element", "ReturnValue", "value", "manual"] - ["java.util", "Queue", True, "poll", "()", "", "Argument[this].Element", "ReturnValue", "value", "manual"] - ["java.util", "Queue", True, "remove", "()", "", "Argument[this].Element", "ReturnValue", "value", "manual"] + - ["java.util", "ResourceBundle", True, "getString", "(String)", "", "Argument[-1].MapValue", "ReturnValue", "value", "manual"] - ["java.util", "Scanner", True, "Scanner", "", "", "Argument[0]", "Argument[this]", "taint", "manual"] - ["java.util", "Scanner", True, "findInLine", "", "", "Argument[this]", "ReturnValue", "taint", "manual"] - ["java.util", "Scanner", True, "findWithinHorizon", "", "", "Argument[this]", "ReturnValue", "taint", "manual"] @@ -364,25 +365,38 @@ extensions: data: - ["java.util", "ArrayList", "ArrayList", "(int)", "manual"] - ["java.util", "ArrayList", "size", "()", "manual"] + - ["java.util", "Arrays", "toString", "(Object[])", "manual"] # ! should this have a summary model after all? (or unwanted model due to too much FP flow?) + - ["java.util", "Calendar", "getInstance", "()", "manual"] - ["java.util", "Collection", "isEmpty", "()", "manual"] - ["java.util", "Collection", "size", "()", "manual"] - ["java.util", "Collections", "emptyList", "()", "manual"] - ["java.util", "Collections", "emptyMap", "()", "manual"] - ["java.util", "Collections", "emptySet", "()", "manual"] + - ["java.util", "Comparator", "comparing", "(Function)", "manual"] # ! seems complex (functional interface), should maybe not have any model? + - ["java.util", "HashMap", "HashMap", "(int)", "manual"] - ["java.util", "Iterator", "hasNext", "()", "manual"] + - ["java.util", "Iterator", "remove", "()", "manual"] # ! WithoutElement comment? (double-check if it returns anything, etc.) - ["java.util", "List", "contains", "(Object)", "manual"] + - ["java.util", "List", "equals", "(Object)", "manual"] + - ["java.util", "List", "hashCode", "()", "manual"] - ["java.util", "List", "isEmpty", "()", "manual"] + - ["java.util", "List", "of", "()", "manual"] + - ["java.util", "List", "remove", "(Object)", "manual"] # ! WithoutElement comment? (actually, see above, is this already modeled for a different signature?) - ["java.util", "List", "size", "()", "manual"] - ["java.util", "Map", "containsKey", "(Object)", "manual"] - ["java.util", "Map", "isEmpty", "()", "manual"] - ["java.util", "Map", "size", "()", "manual"] - ["java.util", "Objects", "equals", "(Object,Object)", "manual"] - ["java.util", "Objects", "hash", "(Object[])", "manual"] + - ["java.util", "Objects", "isNull", "(Object)", "manual"] - ["java.util", "Objects", "nonNull", "(Object)", "manual"] - ["java.util", "Optional", "empty", "()", "manual"] + - ["java.util", "Optional", "isEmpty", "()", "manual"] - ["java.util", "Optional", "isPresent", "()", "manual"] + - ["java.util", "Random", "nextInt", "(int)", "manual"] - ["java.util", "Set", "contains", "(Object)", "manual"] - ["java.util", "Set", "isEmpty", "()", "manual"] + - ["java.util", "Set", "remove", "(Object)", "manual"] # ! WithoutElement comment? (double-check if it returns anything, etc.) - ["java.util", "Set", "size", "()", "manual"] - ["java.util", "UUID", "randomUUID", "()", "manual"] - ["java.util", "UUID", "toString", "()", "manual"] @@ -394,5 +408,8 @@ extensions: # The below APIs have numeric flow and are currently being stored as neutral models. # These may be changed to summary models with kinds "value-numeric" and "taint-numeric" (or similar) in the future. - - ["java.util", "Date", "Date", "(long)", "manual"] # taint-numeric - - ["java.util", "Date", "getTime", "()", "manual"] # taint-numeric + - ["java.util", "Calendar", "get", "(int)", "manual"] # value-numeric + - ["java.util", "Calendar", "getTime", "()", "manual"] # taint-numeric + - ["java.util", "Calendar", "set", "(int,int)", "manual"] # value-numeric + - ["java.util", "Date", "Date", "(long)", "manual"] # taint-numeric + - ["java.util", "Date", "getTime", "()", "manual"] # taint-numeric diff --git a/java/ql/lib/ext/java.util.regex.model.yml b/java/ql/lib/ext/java.util.regex.model.yml index d002fd93419..ac8667de757 100644 --- a/java/ql/lib/ext/java.util.regex.model.yml +++ b/java/ql/lib/ext/java.util.regex.model.yml @@ -24,3 +24,9 @@ extensions: - ["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"] + + - addsTo: + pack: codeql/java-all + extensible: neutralModel + data: + - ["java.util.regex", "Matcher", "find", "()", "manual"] diff --git a/java/ql/lib/ext/java.util.stream.model.yml b/java/ql/lib/ext/java.util.stream.model.yml index 1fafd506185..f4e158d9a20 100644 --- a/java/ql/lib/ext/java.util.stream.model.yml +++ b/java/ql/lib/ext/java.util.stream.model.yml @@ -9,6 +9,7 @@ extensions: - ["java.util.stream", "BaseStream", True, "sequential", "()", "", "Argument[this].Element", "ReturnValue.Element", "value", "manual"] - ["java.util.stream", "BaseStream", True, "spliterator", "()", "", "Argument[this].Element", "ReturnValue.Element", "value", "manual"] - ["java.util.stream", "BaseStream", True, "unordered", "()", "", "Argument[this].Element", "ReturnValue.Element", "value", "manual"] + - ["java.util.stream", "IntStream", False, "range", "(int,int)", "", "Argument[0..1]", "ReturnValue.Element", "value", "manual"] # ! this one is a bit odd, is it correct to have it as a summary model? - ["java.util.stream", "Stream", True, "allMatch", "(Predicate)", "", "Argument[this].Element", "Argument[0].Parameter[0]", "value", "manual"] - ["java.util.stream", "Stream", True, "anyMatch", "(Predicate)", "", "Argument[this].Element", "Argument[0].Parameter[0]", "value", "manual"] - ["java.util.stream", "Stream", True, "collect", "(Supplier,BiConsumer,BiConsumer)", "", "Argument[this].Element", "Argument[1].Parameter[1]", "value", "manual"] diff --git a/java/ql/test/ext/TopJdkApis/TopJdkApis.qll b/java/ql/test/ext/TopJdkApis/TopJdkApis.qll index aa13db92d8e..1da376ff81a 100644 --- a/java/ql/test/ext/TopJdkApis/TopJdkApis.qll +++ b/java/ql/test/ext/TopJdkApis/TopJdkApis.qll @@ -198,6 +198,7 @@ class TopJdkApi extends SummarizedCallableBase { * Note: the following top JDK APIs are not modeled with MaD: * `java.lang.String#valueOf(Object)`: a complex case; an alias for `Object.toString`, except the dispatch is hidden * `java.lang.System#getProperty(String)`: needs to be modeled by regular CodeQL matching the get and set keys to reduce FPs + * `java.lang.System#setProperty(String,String)`: needs to be modeled by regular CodeQL matching the get and set keys to reduce FPs * `java.lang.Throwable#printStackTrace()`: should probably not be a general step, but there might be specialised queries that care * `java.util.function.Consumer#accept(Object)`: specialized lambda flow * `java.util.function.Function#apply(Object)`: specialized lambda flow diff --git a/java/ql/test/ext/TopJdkApis/TopJdkApisTest.expected b/java/ql/test/ext/TopJdkApis/TopJdkApisTest.expected index 3ef93396b3b..abf8d09a27f 100644 --- a/java/ql/test/ext/TopJdkApis/TopJdkApisTest.expected +++ b/java/ql/test/ext/TopJdkApis/TopJdkApisTest.expected @@ -1,5 +1,6 @@ | java.lang.String#valueOf(Object) | no manual model | | java.lang.System#getProperty(String) | no manual model | +| java.lang.System#setProperty(String,String) | no manual model | | java.lang.Throwable#printStackTrace() | no manual model | | java.util.function.Consumer#accept(Object) | no manual model | | java.util.function.Function#apply(Object) | no manual model | From d6c071d2b744276d9cfee6aca459275429cbfd73 Mon Sep 17 00:00:00 2001 From: Jami Cogswell <jcogs33@Jamis-MacBook-Pro.local> Date: Tue, 17 Jan 2023 12:33:17 -0500 Subject: [PATCH 383/631] Java: update TopJdkApis test case for top-400 --- java/ql/test/ext/TopJdkApis/TopJdkApis.qll | 57 ++++++++++++++++++- .../test/ext/TopJdkApis/TopJdkApisTest.java | 7 +++ 2 files changed, 63 insertions(+), 1 deletion(-) diff --git a/java/ql/test/ext/TopJdkApis/TopJdkApis.qll b/java/ql/test/ext/TopJdkApis/TopJdkApis.qll index 1da376ff81a..8bc5b77130b 100644 --- a/java/ql/test/ext/TopJdkApis/TopJdkApis.qll +++ b/java/ql/test/ext/TopJdkApis/TopJdkApis.qll @@ -164,7 +164,62 @@ predicate topJdkApiName(string apiName) { "java.util.concurrent.TimeUnit#toMillis(long)", "java.util.List#of(Object,Object,Object)", "java.lang.String#compareTo(String)", "java.util.stream.IntStream#range(int,int)", "java.math.BigInteger#valueOf(long)", "java.util.List#remove(int)", - "java.util.HashMap#HashMap(Map)", "java.util.function.BiConsumer#accept(Object,Object)" + "java.util.HashMap#HashMap(Map)", "java.util.function.BiConsumer#accept(Object,Object)", + // top 400 JDK APIs + "java.util.HashMap#containsKey(Object)", "java.util.Collection#contains(Object)", + "java.lang.Double#parseDouble(String)", "java.lang.Thread#interrupt()", + "java.awt.Container#add(Component)", "java.time.chrono.ChronoZonedDateTime#toInstant()", + "java.util.List#subList(int,int)", "java.util.concurrent.ConcurrentHashMap#get(Object)", + "java.lang.System#getenv(String)", "java.time.Duration#ofMillis(long)", + "java.lang.Integer#toString()", "java.lang.reflect.Constructor#newInstance(Object[])", + "java.util.Hashtable#get(Object)", "java.lang.Class#toString()", + "java.util.Vector#add(Object)", "java.io.StringReader#StringReader(String)", + "java.io.File#getPath()", "java.lang.System#identityHashCode(Object)", + "java.util.stream.Stream#count()", "java.util.concurrent.CompletableFuture#complete(Object)", + "java.nio.file.Files#exists(Path,LinkOption[])", "java.util.List#set(int,Object)", + "java.util.concurrent.atomic.AtomicLong#AtomicLong(long)", + "java.util.Optional#orElseGet(Supplier)", "java.lang.Class#forName(String)", + "java.lang.String#replace(char,char)", "java.util.Enumeration#nextElement()", + "java.lang.Class#getMethod(String,Class[])", "java.nio.file.Path#toAbsolutePath()", + "java.util.Enumeration#hasMoreElements()", "java.lang.Class#cast(Object)", + "java.util.concurrent.atomic.AtomicBoolean#AtomicBoolean(boolean)", + "java.math.BigDecimal#doubleValue()", "java.util.UUID#fromString(String)", + "java.lang.System#exit(int)", "java.util.List#add(int,Object)", + "java.lang.Boolean#valueOf(boolean)", "java.sql.Timestamp#getTime()", + "java.nio.Buffer#remaining()", "java.net.URL#URL(String)", "java.net.URI#URI(String)", + "java.util.Objects#hashCode(Object)", "java.util.Set#clear()", "java.io.File#isDirectory()", + "java.time.Duration#toMillis()", "java.nio.ByteBuffer#allocate(int)", + "java.math.BigDecimal#toString()", "java.lang.Class#getResourceAsStream(String)", + "java.util.logging.Logger#getLogger(String)", "java.lang.String#toLowerCase(Locale)", + "java.util.concurrent.CompletableFuture#completeExceptionally(Throwable)", + "java.util.stream.Stream#findAny()", + "java.util.concurrent.CompletableFuture#completedFuture(Object)", + "java.util.stream.Stream#of(Object)", "java.util.Map#of(Object,Object,Object,Object)", + "java.util.Collections#sort(List,Comparator)", "java.lang.Thread#Thread(Runnable)", + "java.lang.String#lastIndexOf(int)", + "java.io.UncheckedIOException#UncheckedIOException(IOException)", + "java.util.LinkedHashSet#LinkedHashSet(Collection)", + "java.sql.PreparedStatement#executeUpdate()", "java.time.ZoneId#of(String)", + "java.util.concurrent.atomic.AtomicLong#addAndGet(long)", "java.nio.ByteBuffer#wrap(byte[])", + "java.util.List#indexOf(Object)", "java.util.Collections#unmodifiableMap(Map)", + "java.lang.Long#Long(long)", "java.util.StringTokenizer#nextToken()", + "java.lang.String#join(CharSequence,CharSequence[])", "java.io.StringWriter#toString()", + "java.lang.Integer#toHexString(int)", "java.lang.Long#intValue()", + "java.text.MessageFormat#format(String,Object[])", + "java.lang.Exception#Exception(String,Throwable)", + "java.util.stream.Stream#toArray(IntFunction)", "java.util.List#sort(Comparator)", + "java.util.LinkedHashMap#get(Object)", "java.sql.PreparedStatement#setLong(int,long)", + "java.lang.Iterable#iterator()", "java.math.BigInteger#or(BigInteger)", + "java.time.LocalDateTime#of(int,int,int,int,int,int)", "java.time.Instant#toEpochMilli()", + "java.math.BigDecimal#setScale(int,RoundingMode)", "java.lang.Class#isInstance(Object)", + "java.util.regex.Pattern#compile(String)", "java.util.Calendar#getTimeInMillis()", + "java.lang.Class#getResource(String)", "java.util.concurrent.Executor#execute(Runnable)", + "java.util.concurrent.locks.Lock#unlock()", "java.lang.AssertionError#AssertionError(Object)", + "java.util.ArrayList#addAll(Collection)", "java.io.File#mkdirs()", + "java.time.Duration#ofMinutes(long)", "java.time.format.DateTimeFormatter#ofPattern(String)", + "java.lang.Throwable#getLocalizedMessage()", "java.lang.StringBuilder#delete(int,int)", + "java.util.Vector#size()", "java.lang.String#String(String)", "java.util.ArrayList#isEmpty()", + "java.util.Collection#removeIf(Predicate)" ] } diff --git a/java/ql/test/ext/TopJdkApis/TopJdkApisTest.java b/java/ql/test/ext/TopJdkApis/TopJdkApisTest.java index 6ef7d70d118..0bd7bab64c6 100644 --- a/java/ql/test/ext/TopJdkApis/TopJdkApisTest.java +++ b/java/ql/test/ext/TopJdkApis/TopJdkApisTest.java @@ -2,15 +2,21 @@ import java.awt.Container; import java.io.BufferedReader; import java.io.ByteArrayInputStream; import java.io.FileInputStream; +import java.io.StringReader; +import java.io.StringWriter; +import java.io.UncheckedIOException; +import java.lang.AssertionError; import java.lang.IllegalStateException; import java.lang.IndexOutOfBoundsException; import java.lang.NullPointerException; import java.lang.Math; import java.lang.System; import java.math.BigDecimal; +import java.nio.file.Files; import java.nio.file.Paths; import java.sql.ResultSet; import java.text.DateFormat; +import java.text.MessageFormat; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Arrays; @@ -20,6 +26,7 @@ import java.util.HashSet; import java.util.Map; import java.util.Objects; import java.util.StringJoiner; +import java.util.StringTokenizer; import java.util.UUID; import java.util.concurrent.CompletableFuture; import java.util.concurrent.CountDownLatch; From 44c3a41194e61f4b62ef33790414148a84f37b95 Mon Sep 17 00:00:00 2001 From: Jami Cogswell <jcogs33@Jamis-MacBook-Pro.local> Date: Thu, 23 Mar 2023 17:53:27 -0400 Subject: [PATCH 384/631] Java: resolve more -1 to this conflicts --- java/ql/lib/ext/java.awt.model.yml | 1 + java/ql/lib/ext/java.io.model.yml | 5 ++++ java/ql/lib/ext/java.lang.model.yml | 26 +++++++++++++++++++ java/ql/lib/ext/java.lang.reflect.model.yml | 1 + java/ql/lib/ext/java.math.model.yml | 16 +++++++----- java/ql/lib/ext/java.nio.file.model.yml | 6 +++++ java/ql/lib/ext/java.nio.model.yml | 7 +++++ java/ql/lib/ext/java.sql.model.yml | 13 ++++++---- java/ql/lib/ext/java.text.model.yml | 2 ++ java/ql/lib/ext/java.time.chrono.model.yml | 6 +++++ java/ql/lib/ext/java.time.format.model.yml | 6 +++++ java/ql/lib/ext/java.time.model.yml | 8 +++++- .../ext/java.util.concurrent.atomic.model.yml | 3 +++ .../ext/java.util.concurrent.locks.model.yml | 6 +++++ .../ql/lib/ext/java.util.concurrent.model.yml | 4 +++ java/ql/lib/ext/java.util.logging.model.yml | 1 + java/ql/lib/ext/java.util.model.yml | 24 +++++++++++++---- java/ql/lib/ext/java.util.regex.model.yml | 1 + java/ql/lib/ext/java.util.stream.model.yml | 1 + 19 files changed, 120 insertions(+), 17 deletions(-) create mode 100644 java/ql/lib/ext/java.time.chrono.model.yml create mode 100644 java/ql/lib/ext/java.time.format.model.yml create mode 100644 java/ql/lib/ext/java.util.concurrent.locks.model.yml diff --git a/java/ql/lib/ext/java.awt.model.yml b/java/ql/lib/ext/java.awt.model.yml index a8dd6f1ca1a..97776d26e93 100644 --- a/java/ql/lib/ext/java.awt.model.yml +++ b/java/ql/lib/ext/java.awt.model.yml @@ -3,4 +3,5 @@ extensions: pack: codeql/java-all extensible: summaryModel data: + - ["java.awt", "Container", True, "add", "(Component)", "", "Argument[0]", "Argument[-1].Element", "value", "manual"] # ! signature as "" instead? - ["java.awt", "Container", True, "add", "(Component,Object)", "", "Argument[0]", "Argument[-1].Element", "value", "manual"] diff --git a/java/ql/lib/ext/java.io.model.yml b/java/ql/lib/ext/java.io.model.yml index e94f2dd882d..58ddfc1f523 100644 --- a/java/ql/lib/ext/java.io.model.yml +++ b/java/ql/lib/ext/java.io.model.yml @@ -71,6 +71,7 @@ extensions: - ["java.io", "File", True, "getCanonicalFile", "", "", "Argument[this]", "ReturnValue", "taint", "manual"] - ["java.io", "File", True, "getCanonicalPath", "", "", "Argument[this]", "ReturnValue", "taint", "manual"] - ["java.io", "File", True, "getName", "()", "", "Argument[this]", "ReturnValue", "taint", "manual"] + - ["java.io", "File", False, "getPath", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] # ! True versus False (maybe it's private/hidden?).. (and neutral instead?) - ["java.io", "File", True, "toPath", "", "", "Argument[this]", "ReturnValue", "taint", "manual"] - ["java.io", "File", True, "toString", "", "", "Argument[this]", "ReturnValue", "taint", "manual"] - ["java.io", "File", True, "toURI", "", "", "Argument[this]", "ReturnValue", "taint", "manual"] @@ -91,6 +92,8 @@ extensions: - ["java.io", "OutputStream", True, "write", "(int)", "", "Argument[0]", "Argument[this]", "taint", "manual"] - ["java.io", "Reader", True, "read", "", "", "Argument[this]", "Argument[0]", "taint", "manual"] - ["java.io", "StringReader", False, "StringReader", "", "", "Argument[0]", "Argument[this]", "taint", "manual"] + - ["java.io", "StringWriter", False, "toString", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] # ! currently supported by taintPreservingQualifierToMethod? + - ["java.io", "UncheckedIOException", False, "UncheckedIOException", "(IOException)", "", "Argument[0]", "Argument[-1].SyntheticField[java.lang.Throwable.cause]", "value", "manual"] - ["java.io", "Writer", True, "write", "", "", "Argument[0]", "Argument[this]", "taint", "manual"] - addsTo: pack: codeql/java-all @@ -98,3 +101,5 @@ extensions: data: - ["java.io", "File", "delete", "()", "manual"] - ["java.io", "File", "exists", "()", "manual"] + - ["java.io", "File", "isDirectory", "()", "manual"] + - ["java.io", "File", "mkdirs", "()", "manual"] diff --git a/java/ql/lib/ext/java.lang.model.yml b/java/ql/lib/ext/java.lang.model.yml index a53337d2f87..ff4edca5a5c 100644 --- a/java/ql/lib/ext/java.lang.model.yml +++ b/java/ql/lib/ext/java.lang.model.yml @@ -48,10 +48,14 @@ extensions: - ["java.lang", "AbstractStringBuilder", True, "toString", "", "", "Argument[this]", "ReturnValue", "taint", "manual"] - ["java.lang", "Appendable", True, "append", "", "", "Argument[this]", "ReturnValue", "value", "manual"] - ["java.lang", "Appendable", True, "append", "", "", "Argument[0]", "Argument[this]", "taint", "manual"] + - ["java.lang", "AssertionError", False, "AssertionError", "(Object)", "", "Argument[0]", "Argument[-1].SyntheticField[java.lang.Throwable.message]", "value", "manual"] - ["java.lang", "CharSequence", True, "charAt", "", "", "Argument[this]", "ReturnValue", "taint", "manual"] - ["java.lang", "CharSequence", True, "subSequence", "", "", "Argument[this]", "ReturnValue", "taint", "manual"] - ["java.lang", "CharSequence", True, "toString", "", "", "Argument[this]", "ReturnValue", "taint", "manual"] + - ["java.lang", "Class", False, "cast", "(Object)", "", "Argument[0]", "ReturnValue", "taint", "manual"] - ["java.lang", "Exception", False, "Exception", "(String)", "", "Argument[0]", "Argument[this].SyntheticField[java.lang.Throwable.message]", "value", "manual"] + - ["java.lang", "Exception", False, "Exception", "(String,Throwable)", "", "Argument[0]", "Argument[-1].SyntheticField[java.lang.Throwable.message]", "value", "manual"] + - ["java.lang", "Exception", False, "Exception", "(String,Throwable)", "", "Argument[1]", "Argument[-1].SyntheticField[java.lang.Throwable.cause]", "value", "manual"] - ["java.lang", "IllegalArgumentException", False, "IllegalArgumentException", "(String)", "", "Argument[0]", "Argument[this].SyntheticField[java.lang.Throwable.message]", "value", "manual"] - ["java.lang", "IllegalStateException", False, "IllegalStateException", "(String)", "", "Argument[0]", "Argument[this].SyntheticField[java.lang.Throwable.message]", "value", "manual"] - ["java.lang", "IndexOutOfBoundsException", False, "IndexOutOfBoundsException", "(String)", "", "Argument[0]", "Argument[this].SyntheticField[java.lang.Throwable.message]", "value", "manual"] @@ -104,14 +108,20 @@ extensions: - ["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"] + # ! why do below have subtype=True for constructors? - ["java.lang", "StringBuffer", True, "StringBuffer", "(CharSequence)", "", "Argument[0]", "Argument[this]", "taint", "manual"] - ["java.lang", "StringBuffer", True, "StringBuffer", "(String)", "", "Argument[0]", "Argument[this]", "taint", "manual"] - ["java.lang", "StringBuilder", True, "StringBuilder", "", "", "Argument[0]", "Argument[this]", "taint", "manual"] + - ["java.lang", "StringBuilder", False, "delete", "(int,int)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - ["java.lang", "System", False, "arraycopy", "", "", "Argument[0]", "Argument[2]", "taint", "manual"] + - ["java.lang", "System", False, "getenv", "(String)", "", "Argument[-1].MapValue", "ReturnValue", "value", "manual"] # ! neutral instead? + - ["java.lang", "System", False, "getenv", "(String)", "", "Argument[0]", "ReturnValue", "taint", "manual"] # ! really unsure about this...; neutral instead? -- or unmodelled + - ["java.lang", "Thread", False, "Thread", "(Runnable)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] # ! neutral instead? - ["java.lang", "ThreadLocal", True, "get", "()", "", "Argument[-1].SyntheticField[java.lang.ThreadLocal.value]", "ReturnValue", "value", "manual"] # ! not sure if this model is correct, and if should be neutral model instead - ["java.lang", "Throwable", False, "Throwable", "(Throwable)", "", "Argument[0]", "Argument[this].SyntheticField[java.lang.Throwable.cause]", "value", "manual"] - ["java.lang", "Throwable", True, "getCause", "()", "", "Argument[this].SyntheticField[java.lang.Throwable.cause]", "ReturnValue", "value", "manual"] - ["java.lang", "Throwable", True, "getMessage", "()", "", "Argument[this].SyntheticField[java.lang.Throwable.message]", "ReturnValue", "value", "manual"] + - ["java.lang", "Throwable", True, "getLocalizedMessage", "()", "", "Argument[-1].SyntheticField[java.lang.Throwable.message]", "ReturnValue", "value", "manual"] # ! should the field used be different? - ["java.lang", "Throwable", True, "toString", "()", "", "Argument[-1].SyntheticField[java.lang.Throwable.message]", "ReturnValue", "taint", "manual"] # ! little unsure about this one... - addsTo: pack: codeql/java-all @@ -119,11 +129,18 @@ extensions: data: - ["java.lang", "AbstractStringBuilder", "length", "()", "manual"] - ["java.lang", "Boolean", "equals", "(Object)", "manual"] + - ["java.lang", "Boolean", "valueOf", "(boolean)", "manual"] + - ["java.lang", "Class", "forName", "(String)", "manual"] - ["java.lang", "Class", "getCanonicalName", "()", "manual"] - ["java.lang", "Class", "getClassLoader", "()", "manual"] + - ["java.lang", "Class", "getMethod", "(String,Class[])", "manual"] - ["java.lang", "Class", "getName", "()", "manual"] + - ["java.lang", "Class", "getResource", "(String)", "manual"] + - ["java.lang", "Class", "getResourceAsStream", "(String)", "manual"] - ["java.lang", "Class", "getSimpleName", "()", "manual"] - ["java.lang", "Class", "isAssignableFrom", "(Class)", "manual"] + - ["java.lang", "Class", "isInstance", "(Object)", "manual"] + - ["java.lang", "Class", "toString", "()", "manual"] - ["java.lang", "Enum", "Enum", "(String,int)", "manual"] - ["java.lang", "Enum", "equals", "(Object)", "manual"] - ["java.lang", "Enum", "hashCode", "()", "manual"] @@ -146,24 +163,33 @@ extensions: - ["java.lang", "String", "indexOf", "(int)", "manual"] - ["java.lang", "String", "indexOf", "(String)", "manual"] - ["java.lang", "String", "isEmpty", "()", "manual"] + - ["java.lang", "String", "lastIndexOf", "(int)", "manual"] - ["java.lang", "String", "length", "()", "manual"] - ["java.lang", "String", "startsWith", "(String)", "manual"] - ["java.lang", "System", "currentTimeMillis", "()", "manual"] + - ["java.lang", "System", "exit", "(int)", "manual"] + - ["java.lang", "System", "identityHashCode", "(Object)", "manual"] - ["java.lang", "System", "lineSeparator", "()", "manual"] # ! double-check... - ["java.lang", "System", "nanoTime", "()", "manual"] - ["java.lang", "Thread", "currentThread", "()", "manual"] + - ["java.lang", "Thread", "interrupt", "()", "manual"] - ["java.lang", "Thread", "sleep", "(long)", "manual"] - ["java.lang", "Thread", "start", "()", "manual"] # The below APIs have numeric flow and are currently being stored as neutral models. # These may be changed to summary models with kinds "value-numeric" and "taint-numeric" (or similar) in the future. - ["java.lang", "Boolean", "booleanValue", "()", "manual"] # taint-numeric - ["java.lang", "Boolean", "parseBoolean", "(String)", "manual"] # taint-numeric + - ["java.lang", "Double", "parseDouble", "(String)", "manual"] # taint-numeric - ["java.lang", "Integer", "Integer", "(int)", "manual"] # taint-numeric - ["java.lang", "Integer", "intValue", "()", "manual"] # taint-numeric - ["java.lang", "Integer", "parseInt", "(String)", "manual"] # taint-numeric + - ["java.lang", "Integer", "toHexString", "(int)", "manual"] # taint-numeric + - ["java.lang", "Integer", "toString", "()", "manual"] # taint-numeric - ["java.lang", "Integer", "toString", "(int)", "manual"] # taint-numeric - ["java.lang", "Integer", "valueOf", "(int)", "manual"] # taint-numeric - ["java.lang", "Integer", "valueOf", "(String)", "manual"] # taint-numeric # ! should probably make this and others like it have a "" signature instead... + - ["java.lang", "Long", "Long", "(long)", "manual"] # taint-numeric + - ["java.lang", "Long", "intValue", "()", "manual"] # taint-numeric - ["java.lang", "Long", "longValue", "()", "manual"] # taint-numeric - ["java.lang", "Long", "parseLong", "(String)", "manual"] # taint-numeric - ["java.lang", "Long", "toString", "()", "manual"] # taint-numeric diff --git a/java/ql/lib/ext/java.lang.reflect.model.yml b/java/ql/lib/ext/java.lang.reflect.model.yml index 6de65bc46b9..b4f8ab4054d 100644 --- a/java/ql/lib/ext/java.lang.reflect.model.yml +++ b/java/ql/lib/ext/java.lang.reflect.model.yml @@ -3,6 +3,7 @@ extensions: pack: codeql/java-all extensible: summaryModel data: + - ["java.lang.reflect", "Constructor", False, "newInstance", "(Object[])", "", "Argument[0].ArrayElement", "ReturnValue.Parameter", "value", "manual"] # ! unsure about input/output - ["java.lang.reflect", "Method", False, "invoke", "(Object,Object[])", "", "Argument[1].ArrayElement", "Argument[-1].Parameter[0]", "value", "manual"] # ! very unsure if this model is correct... - addsTo: diff --git a/java/ql/lib/ext/java.math.model.yml b/java/ql/lib/ext/java.math.model.yml index 944b23e0535..f071e5d4678 100644 --- a/java/ql/lib/ext/java.math.model.yml +++ b/java/ql/lib/ext/java.math.model.yml @@ -7,9 +7,13 @@ extensions: # The below APIs have numeric flow and are currently being stored as neutral models. # These may be changed to summary models with kinds "value-numeric" and "taint-numeric" (or similar) in the future. - - ["java.math", "BigDecimal", "BigDecimal", "(int)", "manual"] # taint-numeric - - ["java.math", "BigDecimal", "BigDecimal", "(String)", "manual"] # taint-numeric - - ["java.math", "BigDecimal", "add", "(BigDecimal)", "manual"] # taint-numeric - - ["java.math", "BigDecimal", "valueOf", "(double)", "manual"] # taint-numeric - - ["java.math", "BigDecimal", "valueOf", "(long)", "manual"] # taint-numeric - - ["java.math", "BigInteger", "valueOf", "(long)", "manual"] # taint-numeric + - ["java.math", "BigDecimal", "BigDecimal", "(int)", "manual"] # taint-numeric + - ["java.math", "BigDecimal", "BigDecimal", "(String)", "manual"] # taint-numeric + - ["java.math", "BigDecimal", "add", "(BigDecimal)", "manual"] # taint-numeric + - ["java.math", "BigDecimal", "doubleValue", "()", "manual"] # taint-numeric + - ["java.math", "BigDecimal", "setScale", "(int,RoundingMode)", "manual"] # taint-numeric + - ["java.math", "BigDecimal", "toString", "()", "manual"] # taint-numeric + - ["java.math", "BigDecimal", "valueOf", "(double)", "manual"] # taint-numeric + - ["java.math", "BigDecimal", "valueOf", "(long)", "manual"] # taint-numeric + - ["java.math", "BigInteger", "or", "(BigInteger)", "manual"] # taint-numeric + - ["java.math", "BigInteger", "valueOf", "(long)", "manual"] # taint-numeric diff --git a/java/ql/lib/ext/java.nio.file.model.yml b/java/ql/lib/ext/java.nio.file.model.yml index cca00413c33..b2ad2e0660a 100644 --- a/java/ql/lib/ext/java.nio.file.model.yml +++ b/java/ql/lib/ext/java.nio.file.model.yml @@ -61,3 +61,9 @@ extensions: # - ["java.nio.file", "Files", True, "walkFileTree", "(Path,FileVisitor)", "", "Argument[0]", "Argument[1].Method[preVisitDirectory(Path,BasicFileAttributes)].Parameter[0]", "taint", "ai-generated"] # - ["java.nio.file", "Files", True, "walkFileTree", "(Path,FileVisitor)", "", "Argument[0]" "Argument[1].Method[visitFile(Path,BasicFileAttributes)].Parameter[0]", "taint", "ai-generated"] # - ["java.nio.file", "Files", True, "walkFileTree", "(Path,FileVisitor)", "", "Argument[0]", "Argument[1].Method[visitFileFailed(Path,IOException)].Parameter[0]", "taint", "ai-generated"] + + - addsTo: + pack: codeql/java-all + extensible: neutralModel + data: + - ["java.nio.file", "Files", "exists", "(Path,LinkOption[])", "manual"] diff --git a/java/ql/lib/ext/java.nio.model.yml b/java/ql/lib/ext/java.nio.model.yml index 675b85bf766..1192599f762 100644 --- a/java/ql/lib/ext/java.nio.model.yml +++ b/java/ql/lib/ext/java.nio.model.yml @@ -6,3 +6,10 @@ extensions: - ["java.nio", "ByteBuffer", False, "array", "()", "", "Argument[this]", "ReturnValue", "taint", "manual"] - ["java.nio", "ByteBuffer", False, "get", "", "", "Argument[this]", "ReturnValue", "taint", "manual"] - ["java.nio", "ByteBuffer", False, "wrap", "(byte[])", "", "Argument[0]", "ReturnValue", "taint", "manual"] + + - addsTo: + pack: codeql/java-all + extensible: neutralModel + data: + - ["java.nio", "Buffer", "remaining", "()", "manual"] + - ["java.nio", "ByteBuffer", "allocate", "(int)", "manual"] diff --git a/java/ql/lib/ext/java.sql.model.yml b/java/ql/lib/ext/java.sql.model.yml index 14b3c7c3685..6a801095c4f 100644 --- a/java/ql/lib/ext/java.sql.model.yml +++ b/java/ql/lib/ext/java.sql.model.yml @@ -28,11 +28,14 @@ extensions: pack: codeql/java-all extensible: neutralModel data: + - ["java.sql", "PreparedStatement", "executeUpdate", "()", "manual"] - ["java.sql", "ResultSet", "next", "()", "manual"] # The below APIs have numeric flow and are currently being stored as neutral models. # These may be changed to summary models with kinds "value-numeric" and "taint-numeric" (or similar) in the future. - - ["java.sql", "PreparedStatement", "setInt", "(int,int)", "manual"] # value-numeric - - ["java.sql", "ResultSet", "getInt", "(String)", "manual"] # taint-numeric - - ["java.sql", "ResultSet", "getLong", "(String)", "manual"] # taint-numeric - - ["java.sql", "ResultSet", "getString", "(int)", "manual"] # taint-numeric - - ["java.sql", "Timestamp", "Timestamp", "(long)", "manual"] # taint-numeric + - ["java.sql", "PreparedStatement", "setInt", "(int,int)", "manual"] # value-numeric + - ["java.sql", "PreparedStatement", "setLong", "(int,long)", "manual"] # value-numeric + - ["java.sql", "ResultSet", "getInt", "(String)", "manual"] # taint-numeric + - ["java.sql", "ResultSet", "getLong", "(String)", "manual"] # taint-numeric + - ["java.sql", "ResultSet", "getString", "(int)", "manual"] # taint-numeric + - ["java.sql", "Timestamp", "Timestamp", "(long)", "manual"] # taint-numeric + - ["java.sql", "Timestamp", "getTime", "()", "manual"] # taint-numeric diff --git a/java/ql/lib/ext/java.text.model.yml b/java/ql/lib/ext/java.text.model.yml index 4a087ec34b2..b2237825e5a 100644 --- a/java/ql/lib/ext/java.text.model.yml +++ b/java/ql/lib/ext/java.text.model.yml @@ -4,6 +4,8 @@ extensions: extensible: summaryModel data: - ["java.text", "DateFormat", True, "parse", "(String)", "", "Argument[0]", "ReturnValue", "taint", "manual"] # ! maybe not interesting flow and should be neutral model? + - ["java.text", "MessageFormat", False, "format", "(String,Object[])", "", "Argument[0]", "ReturnValue", "taint", "manual"] # ! not sure I did this right + - ["java.text", "MessageFormat", False, "format", "(String,Object[])", "", "Argument[1].ArrayElement", "ReturnValue", "taint", "manual"] # ! not sure I did this right - addsTo: pack: codeql/java-all diff --git a/java/ql/lib/ext/java.time.chrono.model.yml b/java/ql/lib/ext/java.time.chrono.model.yml new file mode 100644 index 00000000000..9dd5ca401d3 --- /dev/null +++ b/java/ql/lib/ext/java.time.chrono.model.yml @@ -0,0 +1,6 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: summaryModel + data: + - ["java.time.chrono", "ChronoZonedDateTime", False, "toInstant", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] # ! neutral? diff --git a/java/ql/lib/ext/java.time.format.model.yml b/java/ql/lib/ext/java.time.format.model.yml new file mode 100644 index 00000000000..8d782400089 --- /dev/null +++ b/java/ql/lib/ext/java.time.format.model.yml @@ -0,0 +1,6 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: summaryModel + data: + - ["java.time.format", "DateTimeFormatter", False, "ofPattern", "(String)", "", "Argument[0]", "ReturnValue", "taint", "manual"] # ! neutral? diff --git a/java/ql/lib/ext/java.time.model.yml b/java/ql/lib/ext/java.time.model.yml index ae5b8bc0e63..8298b25ee3b 100644 --- a/java/ql/lib/ext/java.time.model.yml +++ b/java/ql/lib/ext/java.time.model.yml @@ -13,7 +13,13 @@ extensions: - ["java.time", "LocalDate", "now", "()", "manual"] - ["java.time", "LocalDateTime", "now", "()", "manual"] - ["java.time", "ZonedDateTime", "now", "()", "manual"] + - ["java.time", "ZoneId", "of", "(String)", "manual"] # The below APIs have numeric flow and are currently being stored as neutral models. # These may be changed to summary models with kinds "value-numeric" and "taint-numeric" (or similar) in the future. - - ["java.time", "LocalDate", "of", "(int,int,int)", "manual"] # taint-numeric + - ["java.time", "Duration", "ofMillis", "(long)", "manual"] # taint-numeric + - ["java.time", "Duration", "ofMinutes", "(long)", "manual"] # taint-numeric + - ["java.time", "Duration", "toMillis", "()", "manual"] # taint-numeric + - ["java.time", "Instant", "toEpochMilli", "()", "manual"] # taint-numeric + - ["java.time", "LocalDate", "of", "(int,int,int)", "manual"] # taint-numeric + - ["java.time", "LocalDateTime", "of", "(int,int,int,int,int,int)", "manual"] # taint-numeric diff --git a/java/ql/lib/ext/java.util.concurrent.atomic.model.yml b/java/ql/lib/ext/java.util.concurrent.atomic.model.yml index 1e563a76d0f..f6a0edc2b63 100644 --- a/java/ql/lib/ext/java.util.concurrent.atomic.model.yml +++ b/java/ql/lib/ext/java.util.concurrent.atomic.model.yml @@ -11,6 +11,7 @@ extensions: pack: codeql/java-all extensible: neutralModel data: + - ["java.util.concurrent.atomic", "AtomicBoolean", "AtomicBoolean", "(boolean)", "manual"] - ["java.util.concurrent.atomic", "AtomicBoolean", "get", "()", "manual"] - ["java.util.concurrent.atomic", "AtomicBoolean", "set", "(boolean)", "manual"] @@ -19,4 +20,6 @@ extensions: - ["java.util.concurrent.atomic", "AtomicInteger", "AtomicInteger", "(int)", "manual"] # value-numeric - ["java.util.concurrent.atomic", "AtomicInteger", "get", "()", "manual"] # value-numeric - ["java.util.concurrent.atomic", "AtomicInteger", "incrementAndGet", "()", "manual"] # taint-numeric + - ["java.util.concurrent.atomic", "AtomicLong", "AtomicLong", "(long)", "manual"] # value-numeric # ! this is supposedly already supported per the telemetry query, LOOK INTO WHY/HOW + - ["java.util.concurrent.atomic", "AtomicLong", "addAndGet", "(long)", "manual"] # taint-numeric - ["java.util.concurrent.atomic", "AtomicLong", "get", "()", "manual"] # value-numeric diff --git a/java/ql/lib/ext/java.util.concurrent.locks.model.yml b/java/ql/lib/ext/java.util.concurrent.locks.model.yml new file mode 100644 index 00000000000..0a248e01262 --- /dev/null +++ b/java/ql/lib/ext/java.util.concurrent.locks.model.yml @@ -0,0 +1,6 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: neutralModel + data: + - ["java.util.concurrent.locks", "Lock", "unlock", "()", "manual"] diff --git a/java/ql/lib/ext/java.util.concurrent.model.yml b/java/ql/lib/ext/java.util.concurrent.model.yml index 1f8d4d01350..8fdd29bb262 100644 --- a/java/ql/lib/ext/java.util.concurrent.model.yml +++ b/java/ql/lib/ext/java.util.concurrent.model.yml @@ -17,6 +17,8 @@ extensions: - ["java.util.concurrent", "BlockingQueue", True, "poll", "(long,TimeUnit)", "", "Argument[this].Element", "ReturnValue", "value", "manual"] - ["java.util.concurrent", "BlockingQueue", True, "put", "(Object)", "", "Argument[0]", "Argument[this].Element", "value", "manual"] - ["java.util.concurrent", "BlockingQueue", True, "take", "()", "", "Argument[this].Element", "ReturnValue", "value", "manual"] + - ["java.util.concurrent", "CompletableFuture", False, "complete", "(Object)", "", "Argument[0]", "Argument[-1].SyntheticField[java.util.concurrent.CompletableFuture.value]", "value", "manual"] # ! not sure about CompleteableFuture ones + - ["java.util.concurrent", "CompletableFuture", False, "completedFuture", "(Object)", "", "Argument[0]", "ReturnValue.SyntheticField[java.util.concurrent.CompletableFuture.value]", "value", "manual"] - ["java.util.concurrent", "CompletableFuture", False, "get", "()", "", "Argument[-1].SyntheticField[java.util.concurrent.CompletableFuture.value]", "ReturnValue", "value", "manual"] # ! not sure if using SyntheticField is correct here; also, should prbly remove this for `Future.get` below's subtyping to handle. - ["java.util.concurrent", "CompletableFuture", False, "join", "()", "", "Argument[-1].SyntheticField[java.util.concurrent.CompletableFuture.value]", "ReturnValue", "value", "manual"] # ! not sure if using SyntheticField is correct here - ["java.util.concurrent", "ConcurrentHashMap", True, "elements", "()", "", "Argument[this].MapValue", "ReturnValue.Element", "value", "manual"] @@ -29,8 +31,10 @@ extensions: pack: codeql/java-all extensible: neutralModel data: + - ["java.util.concurrent", "CompletableFuture", "completeExceptionally", "(Throwable)", "manual"] # ! summary? - ["java.util.concurrent", "CountDownLatch", "await", "(long,TimeUnit)", "manual"] - ["java.util.concurrent", "CountDownLatch", "countDown", "()", "manual"] + - ["java.util.concurrent", "Executor", "execute", "(Runnable)", "manual"] # The below APIs have numeric flow and are currently being stored as neutral models. # These may be changed to summary models with kinds "value-numeric" and "taint-numeric" (or similar) in the future. diff --git a/java/ql/lib/ext/java.util.logging.model.yml b/java/ql/lib/ext/java.util.logging.model.yml index 2d5421e2f47..45afcb2bfa8 100644 --- a/java/ql/lib/ext/java.util.logging.model.yml +++ b/java/ql/lib/ext/java.util.logging.model.yml @@ -41,6 +41,7 @@ extensions: pack: codeql/java-all extensible: summaryModel data: + - ["java.util.logging", "Logger", False, "getLogger", "(String)", "", "Argument[0]", "ReturnValue.SyntheticField[java.util.logging.Logger.name]", "value", "manual"] # ! not sure if using SyntheticField here is correct... - ["java.util.logging", "LogRecord", False, "LogRecord", "", "", "Argument[1]", "Argument[this]", "taint", "manual"] - addsTo: diff --git a/java/ql/lib/ext/java.util.model.yml b/java/ql/lib/ext/java.util.model.yml index dec98781db4..8df603bfdda 100644 --- a/java/ql/lib/ext/java.util.model.yml +++ b/java/ql/lib/ext/java.util.model.yml @@ -176,6 +176,7 @@ extensions: - ["java.util", "Map", True, "getOrDefault", "", "", "Argument[1]", "ReturnValue", "value", "manual"] - ["java.util", "Map", True, "keySet", "()", "", "Argument[this].MapKey", "ReturnValue.Element", "value", "manual"] - ["java.util", "Map", True, "merge", "(Object,Object,BiFunction)", "", "Argument[1]", "Argument[this].MapValue", "value", "manual"] + # ! difference between formatting of below versus `List.of` above? - ["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"] @@ -347,6 +348,7 @@ extensions: - ["java.util", "TreeMap", False, "TreeMap", "(SortedMap)", "", "Argument[0].MapValue", "Argument[this].MapValue", "value", "manual"] - ["java.util", "TreeSet", False, "TreeSet", "(Collection)", "", "Argument[0].Element", "Argument[this].Element", "value", "manual"] - ["java.util", "TreeSet", False, "TreeSet", "(SortedSet)", "", "Argument[0].Element", "Argument[this].Element", "value", "manual"] + - ["java.util", "UUID", False, "fromString", "(String)", "", "Argument[0]", "ReturnValue", "taint", "manual"] - ["java.util", "Vector", False, "Vector", "(Collection)", "", "Argument[0].Element", "Argument[this].Element", "value", "manual"] - ["java.util", "Vector", True, "addElement", "(Object)", "", "Argument[0]", "Argument[this].Element", "value", "manual"] - ["java.util", "Vector", True, "copyInto", "(Object[])", "", "Argument[this].Element", "Argument[0].ArrayElement", "value", "manual"] @@ -364,23 +366,31 @@ extensions: extensible: neutralModel data: - ["java.util", "ArrayList", "ArrayList", "(int)", "manual"] + - ["java.util", "ArrayList", "isEmpty", "()", "manual"] - ["java.util", "ArrayList", "size", "()", "manual"] - ["java.util", "Arrays", "toString", "(Object[])", "manual"] # ! should this have a summary model after all? (or unwanted model due to too much FP flow?) - ["java.util", "Calendar", "getInstance", "()", "manual"] + - ["java.util", "Collection", "contains", "(Object)", "manual"] - ["java.util", "Collection", "isEmpty", "()", "manual"] + - ["java.util", "Collection", "removeIf", "(Predicate)", "manual"] # ! WithoutElement comment? (double-check if it returns anything, etc.) - ["java.util", "Collection", "size", "()", "manual"] - ["java.util", "Collections", "emptyList", "()", "manual"] - ["java.util", "Collections", "emptyMap", "()", "manual"] - ["java.util", "Collections", "emptySet", "()", "manual"] + - ["java.util", "Collections", "sort", "(List,Comparator)", "manual"] # ! summary model instead? - ["java.util", "Comparator", "comparing", "(Function)", "manual"] # ! seems complex (functional interface), should maybe not have any model? + - ["java.util", "Enumeration", "hasMoreElements", "()", "manual"] + - ["java.util", "HashMap", "containsKey", "(Object)", "manual"] - ["java.util", "HashMap", "HashMap", "(int)", "manual"] - ["java.util", "Iterator", "hasNext", "()", "manual"] - ["java.util", "Iterator", "remove", "()", "manual"] # ! WithoutElement comment? (double-check if it returns anything, etc.) - ["java.util", "List", "contains", "(Object)", "manual"] - ["java.util", "List", "equals", "(Object)", "manual"] - ["java.util", "List", "hashCode", "()", "manual"] + - ["java.util", "List", "indexOf", "(Object)", "manual"] - ["java.util", "List", "isEmpty", "()", "manual"] - ["java.util", "List", "of", "()", "manual"] + - ["java.util", "List", "sort", "(Comparator)", "manual"] # ! summary model instead? - ["java.util", "List", "remove", "(Object)", "manual"] # ! WithoutElement comment? (actually, see above, is this already modeled for a different signature?) - ["java.util", "List", "size", "()", "manual"] - ["java.util", "Map", "containsKey", "(Object)", "manual"] @@ -388,6 +398,7 @@ extensions: - ["java.util", "Map", "size", "()", "manual"] - ["java.util", "Objects", "equals", "(Object,Object)", "manual"] - ["java.util", "Objects", "hash", "(Object[])", "manual"] + - ["java.util", "Objects", "hashCode", "(Object)", "manual"] - ["java.util", "Objects", "isNull", "(Object)", "manual"] - ["java.util", "Objects", "nonNull", "(Object)", "manual"] - ["java.util", "Optional", "empty", "()", "manual"] @@ -400,16 +411,19 @@ extensions: - ["java.util", "Set", "size", "()", "manual"] - ["java.util", "UUID", "randomUUID", "()", "manual"] - ["java.util", "UUID", "toString", "()", "manual"] + - ["java.util", "Vector", "size", "()", "manual"] # The below APIs are currently being stored as neutral models since `WithoutElement` has not yet been implemented for Java. # When `WithoutElement` is implemented, these should be changed to summary models of the form `Argument[this].WithoutElement -> Argument[this]`. - ["java.util", "List", "clear", "()", "manual"] - ["java.util", "Map", "clear", "()", "manual"] + - ["java.util", "Set", "clear", "()", "manual"] # The below APIs have numeric flow and are currently being stored as neutral models. # These may be changed to summary models with kinds "value-numeric" and "taint-numeric" (or similar) in the future. - - ["java.util", "Calendar", "get", "(int)", "manual"] # value-numeric - - ["java.util", "Calendar", "getTime", "()", "manual"] # taint-numeric - - ["java.util", "Calendar", "set", "(int,int)", "manual"] # value-numeric - - ["java.util", "Date", "Date", "(long)", "manual"] # taint-numeric - - ["java.util", "Date", "getTime", "()", "manual"] # taint-numeric + - ["java.util", "Calendar", "get", "(int)", "manual"] # value-numeric + - ["java.util", "Calendar", "getTime", "()", "manual"] # taint-numeric + - ["java.util", "Calendar", "getTimeInMillis", "()", "manual"] # taint-numeric + - ["java.util", "Calendar", "set", "(int,int)", "manual"] # value-numeric + - ["java.util", "Date", "Date", "(long)", "manual"] # taint-numeric + - ["java.util", "Date", "getTime", "()", "manual"] # taint-numeric diff --git a/java/ql/lib/ext/java.util.regex.model.yml b/java/ql/lib/ext/java.util.regex.model.yml index ac8667de757..8be0c3105ae 100644 --- a/java/ql/lib/ext/java.util.regex.model.yml +++ b/java/ql/lib/ext/java.util.regex.model.yml @@ -21,6 +21,7 @@ extensions: - ["java.util.regex", "Matcher", False, "replaceAll", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] - ["java.util.regex", "Matcher", False, "replaceFirst", "", "", "Argument[this]", "ReturnValue", "taint", "manual"] - ["java.util.regex", "Matcher", False, "replaceFirst", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["java.util.regex", "Pattern", False, "compile", "(String)", "", "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 index f4e158d9a20..01786c37b7e 100644 --- a/java/ql/lib/ext/java.util.stream.model.yml +++ b/java/ql/lib/ext/java.util.stream.model.yml @@ -95,3 +95,4 @@ extensions: data: - ["java.util.stream", "Collectors", "toList", "()", "manual"] - ["java.util.stream", "Collectors", "toSet", "()", "manual"] + - ["java.util.stream", "Stream", "count", "()", "manual"] From 9103e5c5dd4733ca249a9e51541198f2cf23da56 Mon Sep 17 00:00:00 2001 From: Jami Cogswell <jcogs33@Jamis-MacBook-Pro.local> Date: Tue, 17 Jan 2023 15:02:14 -0500 Subject: [PATCH 385/631] Java: update TopJdkApis test case for top-500 --- java/ql/test/ext/TopJdkApis/TopJdkApis.qll | 57 ++++++++++++++++++- .../test/ext/TopJdkApis/TopJdkApisTest.java | 3 + 2 files changed, 59 insertions(+), 1 deletion(-) diff --git a/java/ql/test/ext/TopJdkApis/TopJdkApis.qll b/java/ql/test/ext/TopJdkApis/TopJdkApis.qll index 8bc5b77130b..8f71c8a88f3 100644 --- a/java/ql/test/ext/TopJdkApis/TopJdkApis.qll +++ b/java/ql/test/ext/TopJdkApis/TopJdkApis.qll @@ -219,7 +219,62 @@ predicate topJdkApiName(string apiName) { "java.time.Duration#ofMinutes(long)", "java.time.format.DateTimeFormatter#ofPattern(String)", "java.lang.Throwable#getLocalizedMessage()", "java.lang.StringBuilder#delete(int,int)", "java.util.Vector#size()", "java.lang.String#String(String)", "java.util.ArrayList#isEmpty()", - "java.util.Collection#removeIf(Predicate)" + "java.util.Collection#removeIf(Predicate)", + // top 500 JDK APIs + "java.util.HashSet#HashSet(int)", "java.util.Set#of(Object,Object)", + "java.util.Collections#unmodifiableSet(Set)", "java.sql.Connection#createStatement()", + "java.math.BigDecimal#subtract(BigDecimal)", "java.util.Date#from(Instant)", + "java.lang.StringBuffer#append(char)", "java.util.Locale#forLanguageTag(String)", + "java.io.DataInput#readLong()", "java.util.Collections#sort(List)", + "java.io.DataOutput#writeLong(long)", "java.util.function.BiFunction#apply(Object,Object)", + "java.lang.String#lastIndexOf(String)", "java.util.Optional#filter(Predicate)", + "java.lang.StringBuilder#append(ObjectString)", "java.lang.StringBuffer#append(Object)", + "java.io.File#getParentFile()", "java.util.stream.Stream#allMatch(Predicate)", + "java.sql.ResultSet#getTimestamp(String)", "java.util.Calendar#setTime(Date)", + "java.util.concurrent.CompletionStage#toCompletableFuture()", + "java.util.concurrent.locks.Lock#lock()", "java.lang.reflect.Field#get(Object)", + "java.io.InputStream#close()", "java.math.BigInteger#BigInteger(String)", + "java.lang.Class#getDeclaredField(String)", + "java.io.InputStreamReader#InputStreamReader(InputStream)", "java.lang.Runtime#getRuntime()", + "java.lang.Class#getDeclaredConstructor(Class[])", + "java.lang.AbstractStringBuilder#setLength(int)", "java.nio.Buffer#position()", + "java.nio.file.Path#getFileName()", "java.util.List#toArray()", + "java.lang.CharSequence#length()", "java.util.stream.Stream#distinct()", + "java.lang.String#format(ObjectString,Object[])", "java.net.URL#toURI()", + "java.util.Queue#poll()", "java.lang.Thread#getContextClassLoader()", + "java.lang.String#valueOf(boolean)", "java.util.Calendar#add(int,int)", + "java.util.HashMap#entrySet()", "java.util.stream.IntStream#mapToObj(IntFunction)", + "java.util.concurrent.atomic.AtomicLong#incrementAndGet()", + "java.util.concurrent.ExecutorService#shutdown()", + "java.util.concurrent.ExecutorService#submit(Runnable)", "java.math.BigDecimal#intValue()", + "java.math.BigDecimal#toBigInteger()", "java.util.LinkedList#add(Object)", + "java.lang.AbstractStringBuilder#charAt(int)", "java.lang.Thread#getName()", + "java.lang.Math#max(long,long)", "java.util.HashMap#size()", + "java.time.LocalDate#plusDays(long)", "java.nio.ByteBuffer#array()", + "java.lang.StringBuilder#append(CharSequence)", "java.util.Vector#addElement(Object)", + "java.lang.ClassLoader#getResource(String)", "java.awt.Insets#Insets(int,int,int,int)", + "java.util.TimeZone#getTimeZone(String)", "java.time.ZoneId#systemDefault()", + "java.lang.Number#doubleValue()", "java.util.stream.Stream#reduce(Object,BinaryOperator)", + "java.lang.CharSequence#toString()", "java.time.Instant#parse(CharSequence)", + "java.text.Format#format(Object)", "java.io.File#toURI()", "java.sql.ResultSet#getInt(int)", + "java.lang.Number#longValue()", "java.lang.Double#doubleToLongBits(double)", + "java.lang.Math#min(long,long)", "java.lang.Double#valueOf(double)", + "java.lang.invoke.MethodHandles#lookup()", "java.util.concurrent.CompletableFuture#isDone()", + "java.time.LocalDate#parse(CharSequence)", "java.lang.StringBuilder#append(boolean)", + "java.util.concurrent.CountDownLatch#await()", + "java.util.concurrent.ConcurrentHashMap#put(Object,Object)", + "java.util.stream.Stream#mapToInt(ToIntFunction)", + "java.math.BigDecimal#multiply(BigDecimal)", "java.util.stream.Stream#concat(Stream,Stream)", + "java.time.Instant#ofEpochMilli(long)", "java.nio.file.Path#getParent()", + "java.util.stream.Stream#sorted()", + "java.util.concurrent.atomic.AtomicBoolean#compareAndSet(boolean,boolean)", + "java.util.UUID#equals(Object)", "java.io.OutputStream#flush()", + "java.time.format.DateTimeFormatter#format(TemporalAccessor)", "java.io.Closeable#close()", + "java.util.EventObject#getSource()", "java.io.File#File(String,String)", + "java.lang.Number#intValue()", "java.io.File#length()", + "java.lang.AbstractStringBuilder#setCharAt(int,char)", "java.util.Set#removeAll(Collection)", + "java.io.File#listFiles()", "java.lang.ClassLoader#getResourceAsStream(String)", + "java.util.Date#toInstant()", "java.util.Queue#add(Object)", "java.io.File#isFile()" ] } diff --git a/java/ql/test/ext/TopJdkApis/TopJdkApisTest.java b/java/ql/test/ext/TopJdkApis/TopJdkApisTest.java index 0bd7bab64c6..90797502198 100644 --- a/java/ql/test/ext/TopJdkApis/TopJdkApisTest.java +++ b/java/ql/test/ext/TopJdkApis/TopJdkApisTest.java @@ -2,6 +2,7 @@ import java.awt.Container; import java.io.BufferedReader; import java.io.ByteArrayInputStream; import java.io.FileInputStream; +import java.io.InputStreamReader; import java.io.StringReader; import java.io.StringWriter; import java.io.UncheckedIOException; @@ -10,6 +11,7 @@ import java.lang.IllegalStateException; import java.lang.IndexOutOfBoundsException; import java.lang.NullPointerException; import java.lang.Math; +import java.lang.Runtime; import java.lang.System; import java.math.BigDecimal; import java.nio.file.Files; @@ -23,6 +25,7 @@ import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; +import java.util.LinkedList; import java.util.Map; import java.util.Objects; import java.util.StringJoiner; From c213d56d2cbbad29b685d1d6bbfcc7a3f948909f Mon Sep 17 00:00:00 2001 From: Jami Cogswell <jcogs33@Jamis-MacBook-Pro.local> Date: Thu, 23 Mar 2023 17:56:46 -0400 Subject: [PATCH 386/631] Java: resolve some more -1 to this conflicts --- java/ql/lib/ext/java.awt.model.yml | 8 +++ java/ql/lib/ext/java.io.model.yml | 16 ++++- java/ql/lib/ext/java.lang.invoke.model.yml | 6 ++ java/ql/lib/ext/java.lang.model.yml | 65 ++++++++++++------- java/ql/lib/ext/java.lang.reflect.model.yml | 1 + java/ql/lib/ext/java.math.model.yml | 5 ++ java/ql/lib/ext/java.nio.file.model.yml | 2 + java/ql/lib/ext/java.nio.model.yml | 1 + java/ql/lib/ext/java.sql.model.yml | 4 ++ java/ql/lib/ext/java.text.model.yml | 1 + java/ql/lib/ext/java.time.format.model.yml | 1 + java/ql/lib/ext/java.time.model.yml | 5 ++ .../ext/java.util.concurrent.atomic.model.yml | 2 + .../ext/java.util.concurrent.locks.model.yml | 1 + .../ql/lib/ext/java.util.concurrent.model.yml | 5 ++ java/ql/lib/ext/java.util.function.model.yml | 1 + java/ql/lib/ext/java.util.model.yml | 12 ++++ java/ql/lib/ext/java.util.stream.model.yml | 5 +- 18 files changed, 114 insertions(+), 27 deletions(-) create mode 100644 java/ql/lib/ext/java.lang.invoke.model.yml diff --git a/java/ql/lib/ext/java.awt.model.yml b/java/ql/lib/ext/java.awt.model.yml index 97776d26e93..30cabdcf8e5 100644 --- a/java/ql/lib/ext/java.awt.model.yml +++ b/java/ql/lib/ext/java.awt.model.yml @@ -5,3 +5,11 @@ extensions: data: - ["java.awt", "Container", True, "add", "(Component)", "", "Argument[0]", "Argument[-1].Element", "value", "manual"] # ! signature as "" instead? - ["java.awt", "Container", True, "add", "(Component,Object)", "", "Argument[0]", "Argument[-1].Element", "value", "manual"] + + - addsTo: + pack: codeql/java-all + extensible: neutralModel + data: + # The below APIs have numeric flow and are currently being stored as neutral models. + # These may be changed to summary models with kinds "value-numeric" and "taint-numeric" (or similar) in the future. + - ["java.awt", "Insets", "Insets", "(int,int,int,int)", "manual"] # value-numeric diff --git a/java/ql/lib/ext/java.io.model.yml b/java/ql/lib/ext/java.io.model.yml index 58ddfc1f523..4c500236fa0 100644 --- a/java/ql/lib/ext/java.io.model.yml +++ b/java/ql/lib/ext/java.io.model.yml @@ -59,11 +59,9 @@ extensions: - ["java.io", "CharArrayReader", False, "CharArrayReader", "", "", "Argument[0]", "Argument[this]", "taint", "manual"] - ["java.io", "CharArrayWriter", True, "toCharArray", "", "", "Argument[this]", "ReturnValue", "taint", "manual"] - ["java.io", "DataInput", True, "readFully", "", "", "Argument[this]", "Argument[0]", "taint", "manual"] - - ["java.io", "DataInput", True, "readInt", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - ["java.io", "DataInput", True, "readLine", "()", "", "Argument[this]", "ReturnValue", "taint", "manual"] - ["java.io", "DataInput", True, "readUTF", "()", "", "Argument[this]", "ReturnValue", "taint", "manual"] - ["java.io", "DataInputStream", False, "DataInputStream", "", "", "Argument[0]", "Argument[this]", "taint", "manual"] - - ["java.io", "DataOutput", True, "writeInt", "(int)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] - ["java.io", "File", False, "File", "", "", "Argument[0]", "Argument[this]", "taint", "manual"] - ["java.io", "File", False, "File", "", "", "Argument[1]", "Argument[this]", "taint", "manual"] - ["java.io", "File", True, "getAbsoluteFile", "", "", "Argument[this]", "ReturnValue", "taint", "manual"] @@ -99,7 +97,21 @@ extensions: pack: codeql/java-all extensible: neutralModel data: + - ["java.io", "Closeable", "close", "()", "manual"] - ["java.io", "File", "delete", "()", "manual"] - ["java.io", "File", "exists", "()", "manual"] + - ["java.io", "File", "getParentFile", "()", "manual"] # ! little unsure about this as a neutral + - ["java.io", "File", "isFile", "()", "manual"] + - ["java.io", "File", "length", "()", "manual"] + - ["java.io", "File", "listFiles", "()", "manual"] # ! little unsure about this as a neutral - ["java.io", "File", "isDirectory", "()", "manual"] - ["java.io", "File", "mkdirs", "()", "manual"] + - ["java.io", "InputStream", "close", "()", "manual"] + - ["java.io", "OutputStream", "flush", "()", "manual"] # ! little unsure about this as a neutral, but not sure how to represent output if summary model... + + # The below APIs have numeric flow and are currently being stored as neutral models. + # These may be changed to summary models with kinds "value-numeric" and "taint-numeric" (or similar) in the future. + - ["java.io", "DataInput", "readInt", "()", "manual"] # taint-numeric + - ["java.io", "DataInput", "readLong", "()", "manual"] # taint-numeric + - ["java.io", "DataOutput", "writeInt", "(int)", "manual"] # taint-numeric + - ["java.io", "DataOutput", "writeLong", "(long)", "manual"] # taint-numeric diff --git a/java/ql/lib/ext/java.lang.invoke.model.yml b/java/ql/lib/ext/java.lang.invoke.model.yml new file mode 100644 index 00000000000..16259190a02 --- /dev/null +++ b/java/ql/lib/ext/java.lang.invoke.model.yml @@ -0,0 +1,6 @@ +extensions: + - addsTo: + pack: codeql/java-all + extensible: neutralModel + data: + - ["java.lang.invoke", "MethodHandles", "lookup", "()", "manual"] diff --git a/java/ql/lib/ext/java.lang.model.yml b/java/ql/lib/ext/java.lang.model.yml index ff4edca5a5c..6a581ff12a6 100644 --- a/java/ql/lib/ext/java.lang.model.yml +++ b/java/ql/lib/ext/java.lang.model.yml @@ -117,6 +117,7 @@ extensions: - ["java.lang", "System", False, "getenv", "(String)", "", "Argument[-1].MapValue", "ReturnValue", "value", "manual"] # ! neutral instead? - ["java.lang", "System", False, "getenv", "(String)", "", "Argument[0]", "ReturnValue", "taint", "manual"] # ! really unsure about this...; neutral instead? -- or unmodelled - ["java.lang", "Thread", False, "Thread", "(Runnable)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] # ! neutral instead? + - ["java.lang", "Thread", True, "getName", "()", "", "Argument[-1].SyntheticField[java.lang.Thread.name]", "ReturnValue", "value", "manual"] - ["java.lang", "ThreadLocal", True, "get", "()", "", "Argument[-1].SyntheticField[java.lang.ThreadLocal.value]", "ReturnValue", "value", "manual"] # ! not sure if this model is correct, and if should be neutral model instead - ["java.lang", "Throwable", False, "Throwable", "(Throwable)", "", "Argument[0]", "Argument[this].SyntheticField[java.lang.Throwable.cause]", "value", "manual"] - ["java.lang", "Throwable", True, "getCause", "()", "", "Argument[this].SyntheticField[java.lang.Throwable.cause]", "ReturnValue", "value", "manual"] @@ -128,11 +129,16 @@ extensions: extensible: neutralModel data: - ["java.lang", "AbstractStringBuilder", "length", "()", "manual"] + - ["java.lang", "AbstractStringBuilder", "setCharAt", "(int,char)", "manual"] # ! char manipulation not interesting? (or interesting since could set many chars... prbly switch to summary model) + - ["java.lang", "AbstractStringBuilder", "setLength", "(int)", "manual"] # ! summary? - ["java.lang", "Boolean", "equals", "(Object)", "manual"] - ["java.lang", "Boolean", "valueOf", "(boolean)", "manual"] + - ["java.lang", "CharSequence", "length", "()", "manual"] - ["java.lang", "Class", "forName", "(String)", "manual"] - ["java.lang", "Class", "getCanonicalName", "()", "manual"] - ["java.lang", "Class", "getClassLoader", "()", "manual"] + - ["java.lang", "Class", "getDeclaredConstructor", "(Class[])", "manual"] + - ["java.lang", "Class", "getDeclaredField", "(String)", "manual"] - ["java.lang", "Class", "getMethod", "(String,Class[])", "manual"] - ["java.lang", "Class", "getName", "()", "manual"] - ["java.lang", "Class", "getResource", "(String)", "manual"] @@ -141,6 +147,8 @@ extensions: - ["java.lang", "Class", "isAssignableFrom", "(Class)", "manual"] - ["java.lang", "Class", "isInstance", "(Object)", "manual"] - ["java.lang", "Class", "toString", "()", "manual"] + - ["java.lang", "ClassLoader", "getResource", "(String)", "manual"] + - ["java.lang", "ClassLoader", "getResourceAsStream", "(String)", "manual"] - ["java.lang", "Enum", "Enum", "(String,int)", "manual"] - ["java.lang", "Enum", "equals", "(Object)", "manual"] - ["java.lang", "Enum", "hashCode", "()", "manual"] @@ -154,6 +162,7 @@ extensions: - ["java.lang", "Object", "hashCode", "()", "manual"] - ["java.lang", "Object", "toString", "()", "manual"] - ["java.lang", "Runnable", "run", "()", "manual"] + - ["java.lang", "Runtime", "getRuntime", "()", "manual"] - ["java.lang", "String", "compareTo", "(String)", "manual"] - ["java.lang", "String", "contains", "(CharSequence)", "manual"] - ["java.lang", "String", "endsWith", "(String)", "manual"] @@ -164,39 +173,49 @@ extensions: - ["java.lang", "String", "indexOf", "(String)", "manual"] - ["java.lang", "String", "isEmpty", "()", "manual"] - ["java.lang", "String", "lastIndexOf", "(int)", "manual"] + - ["java.lang", "String", "lastIndexOf", "(String)", "manual"] - ["java.lang", "String", "length", "()", "manual"] - ["java.lang", "String", "startsWith", "(String)", "manual"] + - ["java.lang", "String", "valueOf", "(boolean)", "manual"] - ["java.lang", "System", "currentTimeMillis", "()", "manual"] - ["java.lang", "System", "exit", "(int)", "manual"] - ["java.lang", "System", "identityHashCode", "(Object)", "manual"] - ["java.lang", "System", "lineSeparator", "()", "manual"] # ! double-check... - ["java.lang", "System", "nanoTime", "()", "manual"] - ["java.lang", "Thread", "currentThread", "()", "manual"] + - ["java.lang", "Thread", "getContextClassLoader", "()", "manual"] # ! summary instead? - ["java.lang", "Thread", "interrupt", "()", "manual"] - ["java.lang", "Thread", "sleep", "(long)", "manual"] - ["java.lang", "Thread", "start", "()", "manual"] # The below APIs have numeric flow and are currently being stored as neutral models. # These may be changed to summary models with kinds "value-numeric" and "taint-numeric" (or similar) in the future. - - ["java.lang", "Boolean", "booleanValue", "()", "manual"] # taint-numeric - - ["java.lang", "Boolean", "parseBoolean", "(String)", "manual"] # taint-numeric - - ["java.lang", "Double", "parseDouble", "(String)", "manual"] # taint-numeric - - ["java.lang", "Integer", "Integer", "(int)", "manual"] # taint-numeric - - ["java.lang", "Integer", "intValue", "()", "manual"] # taint-numeric - - ["java.lang", "Integer", "parseInt", "(String)", "manual"] # taint-numeric - - ["java.lang", "Integer", "toHexString", "(int)", "manual"] # taint-numeric - - ["java.lang", "Integer", "toString", "()", "manual"] # taint-numeric - - ["java.lang", "Integer", "toString", "(int)", "manual"] # taint-numeric - - ["java.lang", "Integer", "valueOf", "(int)", "manual"] # taint-numeric - - ["java.lang", "Integer", "valueOf", "(String)", "manual"] # taint-numeric # ! should probably make this and others like it have a "" signature instead... - - ["java.lang", "Long", "Long", "(long)", "manual"] # taint-numeric - - ["java.lang", "Long", "intValue", "()", "manual"] # taint-numeric - - ["java.lang", "Long", "longValue", "()", "manual"] # taint-numeric - - ["java.lang", "Long", "parseLong", "(String)", "manual"] # taint-numeric - - ["java.lang", "Long", "toString", "()", "manual"] # taint-numeric - - ["java.lang", "Long", "toString", "(long)", "manual"] # taint-numeric - - ["java.lang", "Long", "valueOf", "(long)", "manual"] # taint-numeric - - ["java.lang", "Long", "valueOf", "(String)", "manual"] # taint-numeric - - ["java.lang", "Math", "max", "(int,int)", "manual"] # value-numeric - - ["java.lang", "Math", "min", "(int,int)", "manual"] # value-numeric - - ["java.lang", "String", "valueOf", "(int)", "manual"] # taint-numeric - - ["java.lang", "String", "valueOf", "(long)", "manual"] # taint-numeric + - ["java.lang", "Boolean", "booleanValue", "()", "manual"] # taint-numeric + - ["java.lang", "Boolean", "parseBoolean", "(String)", "manual"] # taint-numeric + - ["java.lang", "Double", "doubleToLongBits", "(double)", "manual"] # taint-numeric + - ["java.lang", "Double", "parseDouble", "(String)", "manual"] # taint-numeric + - ["java.lang", "Double", "valueOf", "(double)", "manual"] # taint-numeric + - ["java.lang", "Integer", "Integer", "(int)", "manual"] # taint-numeric + - ["java.lang", "Integer", "intValue", "()", "manual"] # taint-numeric + - ["java.lang", "Integer", "parseInt", "(String)", "manual"] # taint-numeric + - ["java.lang", "Integer", "toHexString", "(int)", "manual"] # taint-numeric + - ["java.lang", "Integer", "toString", "()", "manual"] # taint-numeric + - ["java.lang", "Integer", "toString", "(int)", "manual"] # taint-numeric + - ["java.lang", "Integer", "valueOf", "(int)", "manual"] # taint-numeric + - ["java.lang", "Integer", "valueOf", "(String)", "manual"] # taint-numeric # ! should probably make this and others like it have a "" signature instead... + - ["java.lang", "Long", "Long", "(long)", "manual"] # taint-numeric + - ["java.lang", "Long", "intValue", "()", "manual"] # taint-numeric + - ["java.lang", "Long", "longValue", "()", "manual"] # taint-numeric + - ["java.lang", "Long", "parseLong", "(String)", "manual"] # taint-numeric + - ["java.lang", "Long", "toString", "()", "manual"] # taint-numeric + - ["java.lang", "Long", "toString", "(long)", "manual"] # taint-numeric + - ["java.lang", "Long", "valueOf", "(long)", "manual"] # taint-numeric + - ["java.lang", "Long", "valueOf", "(String)", "manual"] # taint-numeric + - ["java.lang", "Math", "max", "(int,int)", "manual"] # value-numeric + - ["java.lang", "Math", "max", "(long,long)", "manual"] # value-numeric + - ["java.lang", "Math", "min", "(int,int)", "manual"] # value-numeric + - ["java.lang", "Math", "min", "(long,long)", "manual"] # value-numeric + - ["java.lang", "Number", "doubleValue", "()", "manual"] # taint-numeric # ! remove others that could rely on subtyping through Number instead? (e.g. Double, Integer, etc.) + - ["java.lang", "Number", "intValue", "()", "manual"] # taint-numeric + - ["java.lang", "Number", "longValue", "()", "manual"] # taint-numeric + - ["java.lang", "String", "valueOf", "(int)", "manual"] # taint-numeric + - ["java.lang", "String", "valueOf", "(long)", "manual"] # taint-numeric diff --git a/java/ql/lib/ext/java.lang.reflect.model.yml b/java/ql/lib/ext/java.lang.reflect.model.yml index b4f8ab4054d..97df7cde61e 100644 --- a/java/ql/lib/ext/java.lang.reflect.model.yml +++ b/java/ql/lib/ext/java.lang.reflect.model.yml @@ -4,6 +4,7 @@ extensions: extensible: summaryModel data: - ["java.lang.reflect", "Constructor", False, "newInstance", "(Object[])", "", "Argument[0].ArrayElement", "ReturnValue.Parameter", "value", "manual"] # ! unsure about input/output + - ["java.lang.reflect", "Field", False, "get", "(Object)", "", "Argument[0].Field", "ReturnValue", "value", "manual"] # ! very unsure about - ["java.lang.reflect", "Method", False, "invoke", "(Object,Object[])", "", "Argument[1].ArrayElement", "Argument[-1].Parameter[0]", "value", "manual"] # ! very unsure if this model is correct... - addsTo: diff --git a/java/ql/lib/ext/java.math.model.yml b/java/ql/lib/ext/java.math.model.yml index f071e5d4678..c80f9c87031 100644 --- a/java/ql/lib/ext/java.math.model.yml +++ b/java/ql/lib/ext/java.math.model.yml @@ -11,9 +11,14 @@ extensions: - ["java.math", "BigDecimal", "BigDecimal", "(String)", "manual"] # taint-numeric - ["java.math", "BigDecimal", "add", "(BigDecimal)", "manual"] # taint-numeric - ["java.math", "BigDecimal", "doubleValue", "()", "manual"] # taint-numeric + - ["java.math", "BigDecimal", "intValue", "()", "manual"] # taint-numeric + - ["java.math", "BigDecimal", "multiply", "(BigDecimal)", "manual"] # taint-numeric - ["java.math", "BigDecimal", "setScale", "(int,RoundingMode)", "manual"] # taint-numeric + - ["java.math", "BigDecimal", "subtract", "(BigDecimal)", "manual"] # taint-numeric + - ["java.math", "BigDecimal", "toBigInteger", "()", "manual"] # taint-numeric - ["java.math", "BigDecimal", "toString", "()", "manual"] # taint-numeric - ["java.math", "BigDecimal", "valueOf", "(double)", "manual"] # taint-numeric - ["java.math", "BigDecimal", "valueOf", "(long)", "manual"] # taint-numeric + - ["java.math", "BigInteger", "BigInteger", "(String)", "manual"] # taint-numeric - ["java.math", "BigInteger", "or", "(BigInteger)", "manual"] # taint-numeric - ["java.math", "BigInteger", "valueOf", "(long)", "manual"] # taint-numeric diff --git a/java/ql/lib/ext/java.nio.file.model.yml b/java/ql/lib/ext/java.nio.file.model.yml index b2ad2e0660a..690121f849d 100644 --- a/java/ql/lib/ext/java.nio.file.model.yml +++ b/java/ql/lib/ext/java.nio.file.model.yml @@ -44,7 +44,9 @@ extensions: - ["java.nio.file", "FileSystem", True, "getPathMatcher", "(String)", "", "Argument[0]", "ReturnValue", "taint", "ai-generated"] - ["java.nio.file", "FileSystem", True, "getRootDirectories", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] - ["java.nio.file", "Path", True, "getParent", "", "", "Argument[this]", "ReturnValue", "taint", "manual"] + # ! should Path have subtyping of False for all methods instead? Why is `toFile` different? - ["java.nio.file", "Path", True, "normalize", "", "", "Argument[this]", "ReturnValue", "taint", "manual"] + - ["java.nio.file", "Path", False, "getFileName", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] # ! maybe need more field flow? - ["java.nio.file", "Path", True, "of", "(String,String[])", "", "Argument[0]", "ReturnValue", "taint", "ai-generated"] - ["java.nio.file", "Path", True, "of", "(String,String[])", "", "Argument[1]", "ReturnValue", "taint", "ai-generated"] - ["java.nio.file", "Path", True, "of", "(URI)", "", "Argument[0]", "ReturnValue", "taint", "ai-generated"] diff --git a/java/ql/lib/ext/java.nio.model.yml b/java/ql/lib/ext/java.nio.model.yml index 1192599f762..cc90940c122 100644 --- a/java/ql/lib/ext/java.nio.model.yml +++ b/java/ql/lib/ext/java.nio.model.yml @@ -11,5 +11,6 @@ extensions: pack: codeql/java-all extensible: neutralModel data: + - ["java.nio", "Buffer", "position", "()", "manual"] # ! maybe should be summary? - ["java.nio", "Buffer", "remaining", "()", "manual"] - ["java.nio", "ByteBuffer", "allocate", "(int)", "manual"] diff --git a/java/ql/lib/ext/java.sql.model.yml b/java/ql/lib/ext/java.sql.model.yml index 6a801095c4f..47874a3333d 100644 --- a/java/ql/lib/ext/java.sql.model.yml +++ b/java/ql/lib/ext/java.sql.model.yml @@ -24,16 +24,20 @@ extensions: - ["java.sql", "PreparedStatement", True, "executeQuery", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] # ! this should maybe be a neutral model, not sure if this really counts as "flow through"... - ["java.sql", "PreparedStatement", True, "setString", "(int,String)", "", "Argument[1]", "Argument[this]", "value", "manual"] - ["java.sql", "ResultSet", True, "getString", "(String)", "", "Argument[this]", "ReturnValue", "taint", "manual"] + - ["java.sql", "ResultSet", True, "getTimestamp", "(String)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - addsTo: pack: codeql/java-all extensible: neutralModel data: + - ["java.sql", "Connection", "createStatement", "()", "manual"] - ["java.sql", "PreparedStatement", "executeUpdate", "()", "manual"] - ["java.sql", "ResultSet", "next", "()", "manual"] # The below APIs have numeric flow and are currently being stored as neutral models. # These may be changed to summary models with kinds "value-numeric" and "taint-numeric" (or similar) in the future. - ["java.sql", "PreparedStatement", "setInt", "(int,int)", "manual"] # value-numeric - ["java.sql", "PreparedStatement", "setLong", "(int,long)", "manual"] # value-numeric + - ["java.sql", "ResultSet", "getInt", "(int)", "manual"] # taint-numeric - ["java.sql", "ResultSet", "getInt", "(String)", "manual"] # taint-numeric - ["java.sql", "ResultSet", "getLong", "(String)", "manual"] # taint-numeric - ["java.sql", "ResultSet", "getString", "(int)", "manual"] # taint-numeric diff --git a/java/ql/lib/ext/java.text.model.yml b/java/ql/lib/ext/java.text.model.yml index b2237825e5a..4056b4d0c7a 100644 --- a/java/ql/lib/ext/java.text.model.yml +++ b/java/ql/lib/ext/java.text.model.yml @@ -4,6 +4,7 @@ extensions: extensible: summaryModel data: - ["java.text", "DateFormat", True, "parse", "(String)", "", "Argument[0]", "ReturnValue", "taint", "manual"] # ! maybe not interesting flow and should be neutral model? + - ["java.text", "Format", True, "format", "(Object)", "", "Argument[0]", "ReturnValue", "taint", "manual"] # ! would cover DateFormat.format below through subtyping... - ["java.text", "MessageFormat", False, "format", "(String,Object[])", "", "Argument[0]", "ReturnValue", "taint", "manual"] # ! not sure I did this right - ["java.text", "MessageFormat", False, "format", "(String,Object[])", "", "Argument[1].ArrayElement", "ReturnValue", "taint", "manual"] # ! not sure I did this right diff --git a/java/ql/lib/ext/java.time.format.model.yml b/java/ql/lib/ext/java.time.format.model.yml index 8d782400089..083e811ebb9 100644 --- a/java/ql/lib/ext/java.time.format.model.yml +++ b/java/ql/lib/ext/java.time.format.model.yml @@ -3,4 +3,5 @@ extensions: pack: codeql/java-all extensible: summaryModel data: + - ["java.time.format", "DateTimeFormatter", False, "format", "(TemporalAccessor)", "", "Argument[0]", "ReturnValue", "taint", "manual"] # ! neutral? - ["java.time.format", "DateTimeFormatter", False, "ofPattern", "(String)", "", "Argument[0]", "ReturnValue", "taint", "manual"] # ! neutral? diff --git a/java/ql/lib/ext/java.time.model.yml b/java/ql/lib/ext/java.time.model.yml index 8298b25ee3b..456c1d593a0 100644 --- a/java/ql/lib/ext/java.time.model.yml +++ b/java/ql/lib/ext/java.time.model.yml @@ -4,6 +4,8 @@ extensions: extensible: summaryModel data: - ["java.time", "Duration", False, "ofSeconds", "(long)", "", "Argument[0]", "ReturnValue", "taint", "manual"] # ! maybe not interesting flow and should be neutral model? + - ["java.time", "Instant", False, "parse", "(CharSequence)", "", "Argument[0]", "ReturnValue", "taint", "manual"] # ! mmaybe should be neutral since time-related? + - ["java.time", "LocalDate", False, "parse", "(CharSequence)", "", "Argument[0]", "ReturnValue", "taint", "manual"] - addsTo: pack: codeql/java-all @@ -14,12 +16,15 @@ extensions: - ["java.time", "LocalDateTime", "now", "()", "manual"] - ["java.time", "ZonedDateTime", "now", "()", "manual"] - ["java.time", "ZoneId", "of", "(String)", "manual"] + - ["java.time", "ZoneId", "systemDefault", "()", "manual"] # The below APIs have numeric flow and are currently being stored as neutral models. # These may be changed to summary models with kinds "value-numeric" and "taint-numeric" (or similar) in the future. - ["java.time", "Duration", "ofMillis", "(long)", "manual"] # taint-numeric - ["java.time", "Duration", "ofMinutes", "(long)", "manual"] # taint-numeric - ["java.time", "Duration", "toMillis", "()", "manual"] # taint-numeric + - ["java.time", "Instant", "ofEpochMilli", "(long)", "manual"] # taint-numeric - ["java.time", "Instant", "toEpochMilli", "()", "manual"] # taint-numeric + - ["java.time", "LocalDate", "plusDays", "(long)", "manual"] # taint-numeric - ["java.time", "LocalDate", "of", "(int,int,int)", "manual"] # taint-numeric - ["java.time", "LocalDateTime", "of", "(int,int,int,int,int,int)", "manual"] # taint-numeric diff --git a/java/ql/lib/ext/java.util.concurrent.atomic.model.yml b/java/ql/lib/ext/java.util.concurrent.atomic.model.yml index f6a0edc2b63..b2da86b1aa5 100644 --- a/java/ql/lib/ext/java.util.concurrent.atomic.model.yml +++ b/java/ql/lib/ext/java.util.concurrent.atomic.model.yml @@ -12,6 +12,7 @@ extensions: extensible: neutralModel data: - ["java.util.concurrent.atomic", "AtomicBoolean", "AtomicBoolean", "(boolean)", "manual"] + - ["java.util.concurrent.atomic", "AtomicBoolean", "compareAndSet", "(boolean,boolean)", "manual"] - ["java.util.concurrent.atomic", "AtomicBoolean", "get", "()", "manual"] - ["java.util.concurrent.atomic", "AtomicBoolean", "set", "(boolean)", "manual"] @@ -23,3 +24,4 @@ extensions: - ["java.util.concurrent.atomic", "AtomicLong", "AtomicLong", "(long)", "manual"] # value-numeric # ! this is supposedly already supported per the telemetry query, LOOK INTO WHY/HOW - ["java.util.concurrent.atomic", "AtomicLong", "addAndGet", "(long)", "manual"] # taint-numeric - ["java.util.concurrent.atomic", "AtomicLong", "get", "()", "manual"] # value-numeric + - ["java.util.concurrent.atomic", "AtomicLong", "incrementAndGet", "()", "manual"] # taint-numeric diff --git a/java/ql/lib/ext/java.util.concurrent.locks.model.yml b/java/ql/lib/ext/java.util.concurrent.locks.model.yml index 0a248e01262..54a86493fc1 100644 --- a/java/ql/lib/ext/java.util.concurrent.locks.model.yml +++ b/java/ql/lib/ext/java.util.concurrent.locks.model.yml @@ -3,4 +3,5 @@ extensions: pack: codeql/java-all extensible: neutralModel data: + - ["java.util.concurrent.locks", "Lock", "lock", "()", "manual"] - ["java.util.concurrent.locks", "Lock", "unlock", "()", "manual"] diff --git a/java/ql/lib/ext/java.util.concurrent.model.yml b/java/ql/lib/ext/java.util.concurrent.model.yml index 8fdd29bb262..c5598039074 100644 --- a/java/ql/lib/ext/java.util.concurrent.model.yml +++ b/java/ql/lib/ext/java.util.concurrent.model.yml @@ -21,7 +21,9 @@ extensions: - ["java.util.concurrent", "CompletableFuture", False, "completedFuture", "(Object)", "", "Argument[0]", "ReturnValue.SyntheticField[java.util.concurrent.CompletableFuture.value]", "value", "manual"] - ["java.util.concurrent", "CompletableFuture", False, "get", "()", "", "Argument[-1].SyntheticField[java.util.concurrent.CompletableFuture.value]", "ReturnValue", "value", "manual"] # ! not sure if using SyntheticField is correct here; also, should prbly remove this for `Future.get` below's subtyping to handle. - ["java.util.concurrent", "CompletableFuture", False, "join", "()", "", "Argument[-1].SyntheticField[java.util.concurrent.CompletableFuture.value]", "ReturnValue", "value", "manual"] # ! not sure if using SyntheticField is correct here + - ["java.util.concurrent", "CompletionStage", False, "toCompletableFuture", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - ["java.util.concurrent", "ConcurrentHashMap", True, "elements", "()", "", "Argument[this].MapValue", "ReturnValue.Element", "value", "manual"] + - ["java.util.concurrent", "ExecutorService", True, "submit", "(Runnable)", "", "Argument[0]", "ReturnValue", "taint", "manual"] - ["java.util.concurrent", "Future", True, "get", "()", "", "Argument[-1].SyntheticField[java.util.concurrent.Future.value]", "ReturnValue", "value", "manual"] # ! not sure if using SyntheticField is correct here - ["java.util.concurrent", "TransferQueue", True, "transfer", "(Object)", "", "Argument[0]", "Argument[this].Element", "value", "manual"] - ["java.util.concurrent", "TransferQueue", True, "tryTransfer", "(Object)", "", "Argument[0]", "Argument[this].Element", "value", "manual"] @@ -32,9 +34,12 @@ extensions: extensible: neutralModel data: - ["java.util.concurrent", "CompletableFuture", "completeExceptionally", "(Throwable)", "manual"] # ! summary? + - ["java.util.concurrent", "CompletableFuture", "isDone", "()", "manual"] + - ["java.util.concurrent", "CountDownLatch", "await", "()", "manual"] # ! combine with below, "" as signature - ["java.util.concurrent", "CountDownLatch", "await", "(long,TimeUnit)", "manual"] - ["java.util.concurrent", "CountDownLatch", "countDown", "()", "manual"] - ["java.util.concurrent", "Executor", "execute", "(Runnable)", "manual"] + - ["java.util.concurrent", "ExecutorService", "shutdown", "()", "manual"] # The below APIs have numeric flow and are currently being stored as neutral models. # These may be changed to summary models with kinds "value-numeric" and "taint-numeric" (or similar) in the future. diff --git a/java/ql/lib/ext/java.util.function.model.yml b/java/ql/lib/ext/java.util.function.model.yml index d81882b70c0..d28b699f1b8 100644 --- a/java/ql/lib/ext/java.util.function.model.yml +++ b/java/ql/lib/ext/java.util.function.model.yml @@ -10,4 +10,5 @@ extensions: extensible: neutralModel data: - ["java.util.function", "BiConsumer", "accept", "(Object,Object)", "manual"] # ! remove this model? + - ["java.util.function", "BiFunction", "apply", "(Object,Object)", "manual"] # ! remove this model? - ["java.util.function", "Function", "identity", "()", "manual"] # ! remove this model? diff --git a/java/ql/lib/ext/java.util.model.yml b/java/ql/lib/ext/java.util.model.yml index 8df603bfdda..6cd77031325 100644 --- a/java/ql/lib/ext/java.util.model.yml +++ b/java/ql/lib/ext/java.util.model.yml @@ -124,6 +124,7 @@ extensions: - ["java.util", "EnumMap", False, "EnumMap", "(Map)", "", "Argument[0].MapValue", "Argument[this].MapValue", "value", "manual"] - ["java.util", "Enumeration", True, "asIterator", "", "", "Argument[this].Element", "ReturnValue.Element", "value", "manual"] - ["java.util", "Enumeration", True, "nextElement", "", "", "Argument[this].Element", "ReturnValue", "value", "manual"] + - ["java.util", "EventObject", True, "getSource", "()", "", "Argument[-1].Field[java.util.EventObject.source]", "ReturnValue", "value", "manual"] # ! double-check - ["java.util", "HashMap", False, "HashMap", "(Map)", "", "Argument[0].MapKey", "Argument[this].MapKey", "value", "manual"] - ["java.util", "HashMap", False, "HashMap", "(Map)", "", "Argument[0].MapValue", "Argument[this].MapValue", "value", "manual"] - ["java.util", "HashSet", False, "HashSet", "(Collection)", "", "Argument[0].Element", "Argument[this].Element", "value", "manual"] @@ -160,6 +161,7 @@ extensions: - ["java.util", "ListIterator", True, "add", "(Object)", "", "Argument[0]", "Argument[this].Element", "value", "manual"] - ["java.util", "ListIterator", True, "previous", "", "", "Argument[this].Element", "ReturnValue", "value", "manual"] - ["java.util", "ListIterator", True, "set", "(Object)", "", "Argument[0]", "Argument[this].Element", "value", "manual"] + - ["java.util", "Locale", False, "forLanguageTag", "(String)", "", "Argument[0]", "ReturnValue", "taint", "manual"] # ! neutral? - ["java.util", "Map", True, "computeIfAbsent", "", "", "Argument[this].MapValue", "ReturnValue", "value", "manual"] - ["java.util", "Map", True, "computeIfAbsent", "", "", "Argument[1].ReturnValue", "Argument[this].MapValue", "value", "manual"] - ["java.util", "Map", True, "computeIfAbsent", "", "", "Argument[1].ReturnValue", "ReturnValue", "value", "manual"] @@ -377,11 +379,14 @@ extensions: - ["java.util", "Collections", "emptyList", "()", "manual"] - ["java.util", "Collections", "emptyMap", "()", "manual"] - ["java.util", "Collections", "emptySet", "()", "manual"] + - ["java.util", "Collections", "sort", "(List)", "manual"] # ! summary model instead? - ["java.util", "Collections", "sort", "(List,Comparator)", "manual"] # ! summary model instead? - ["java.util", "Comparator", "comparing", "(Function)", "manual"] # ! seems complex (functional interface), should maybe not have any model? - ["java.util", "Enumeration", "hasMoreElements", "()", "manual"] - ["java.util", "HashMap", "containsKey", "(Object)", "manual"] - ["java.util", "HashMap", "HashMap", "(int)", "manual"] + - ["java.util", "HashMap", "size", "()", "manual"] + - ["java.util", "HashSet", "HashSet", "(int)", "manual"] - ["java.util", "Iterator", "hasNext", "()", "manual"] - ["java.util", "Iterator", "remove", "()", "manual"] # ! WithoutElement comment? (double-check if it returns anything, etc.) - ["java.util", "List", "contains", "(Object)", "manual"] @@ -408,9 +413,12 @@ extensions: - ["java.util", "Set", "contains", "(Object)", "manual"] - ["java.util", "Set", "isEmpty", "()", "manual"] - ["java.util", "Set", "remove", "(Object)", "manual"] # ! WithoutElement comment? (double-check if it returns anything, etc.) + - ["java.util", "Set", "removeAll", "(Collection)", "manual"] # ! WithoutElement comment? (double-check if it returns anything, etc.) - ["java.util", "Set", "size", "()", "manual"] + - ["java.util", "UUID", "equals", "(Object)", "manual"] - ["java.util", "UUID", "randomUUID", "()", "manual"] - ["java.util", "UUID", "toString", "()", "manual"] + - ["java.util", "TimeZone", "getTimeZone", "(String)", "manual"] - ["java.util", "Vector", "size", "()", "manual"] # The below APIs are currently being stored as neutral models since `WithoutElement` has not yet been implemented for Java. @@ -421,9 +429,13 @@ extensions: # The below APIs have numeric flow and are currently being stored as neutral models. # These may be changed to summary models with kinds "value-numeric" and "taint-numeric" (or similar) in the future. + - ["java.util", "Calendar", "add", "(int,int)", "manual"] # taint-numeric - ["java.util", "Calendar", "get", "(int)", "manual"] # value-numeric - ["java.util", "Calendar", "getTime", "()", "manual"] # taint-numeric - ["java.util", "Calendar", "getTimeInMillis", "()", "manual"] # taint-numeric - ["java.util", "Calendar", "set", "(int,int)", "manual"] # value-numeric + - ["java.util", "Calendar", "setTime", "(Date)", "manual"] # taint-numeric - ["java.util", "Date", "Date", "(long)", "manual"] # taint-numeric - ["java.util", "Date", "getTime", "()", "manual"] # taint-numeric + - ["java.util", "Date", "from", "(Instant)", "manual"] # taint-numeric + - ["java.util", "Date", "toInstant", "()", "manual"] # taint-numeric diff --git a/java/ql/lib/ext/java.util.stream.model.yml b/java/ql/lib/ext/java.util.stream.model.yml index 01786c37b7e..f6a37dcd4ee 100644 --- a/java/ql/lib/ext/java.util.stream.model.yml +++ b/java/ql/lib/ext/java.util.stream.model.yml @@ -9,8 +9,8 @@ extensions: - ["java.util.stream", "BaseStream", True, "sequential", "()", "", "Argument[this].Element", "ReturnValue.Element", "value", "manual"] - ["java.util.stream", "BaseStream", True, "spliterator", "()", "", "Argument[this].Element", "ReturnValue.Element", "value", "manual"] - ["java.util.stream", "BaseStream", True, "unordered", "()", "", "Argument[this].Element", "ReturnValue.Element", "value", "manual"] - - ["java.util.stream", "IntStream", False, "range", "(int,int)", "", "Argument[0..1]", "ReturnValue.Element", "value", "manual"] # ! this one is a bit odd, is it correct to have it as a summary model? - - ["java.util.stream", "Stream", True, "allMatch", "(Predicate)", "", "Argument[this].Element", "Argument[0].Parameter[0]", "value", "manual"] + - ["java.util.stream", "IntStream", False, "range", "(int,int)", "", "Argument[0..1]", "ReturnValue.Element", "value", "manual"] # ! this one is a bit odd, is it correct to have it as a summary model?; not interesting because Int stream?=neutral? + - ["java.util.stream", "Stream", True, "allMatch", "(Predicate)", "", "Argument[this].Element", "Argument[0].Parameter[0]", "value", "manual"] # ! neutral instead? - ["java.util.stream", "Stream", True, "anyMatch", "(Predicate)", "", "Argument[this].Element", "Argument[0].Parameter[0]", "value", "manual"] - ["java.util.stream", "Stream", True, "collect", "(Supplier,BiConsumer,BiConsumer)", "", "Argument[this].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"] @@ -95,4 +95,5 @@ extensions: data: - ["java.util.stream", "Collectors", "toList", "()", "manual"] - ["java.util.stream", "Collectors", "toSet", "()", "manual"] + - ["java.util.stream", "IntStream", "mapToObj", "(IntFunction)", "manual"] - ["java.util.stream", "Stream", "count", "()", "manual"] From 275634e907e183d24f329e45d7f0fe6b217fc386 Mon Sep 17 00:00:00 2001 From: Jami Cogswell <jcogs33@Jamis-MacBook-Pro.local> Date: Tue, 17 Jan 2023 16:44:52 -0500 Subject: [PATCH 387/631] Java: remove apis with ObjectString param type --- java/ql/test/ext/TopJdkApis/TopJdkApis.qll | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/java/ql/test/ext/TopJdkApis/TopJdkApis.qll b/java/ql/test/ext/TopJdkApis/TopJdkApis.qll index 8f71c8a88f3..2ec75f59c20 100644 --- a/java/ql/test/ext/TopJdkApis/TopJdkApis.qll +++ b/java/ql/test/ext/TopJdkApis/TopJdkApis.qll @@ -228,9 +228,9 @@ predicate topJdkApiName(string apiName) { "java.io.DataInput#readLong()", "java.util.Collections#sort(List)", "java.io.DataOutput#writeLong(long)", "java.util.function.BiFunction#apply(Object,Object)", "java.lang.String#lastIndexOf(String)", "java.util.Optional#filter(Predicate)", - "java.lang.StringBuilder#append(ObjectString)", "java.lang.StringBuffer#append(Object)", - "java.io.File#getParentFile()", "java.util.stream.Stream#allMatch(Predicate)", - "java.sql.ResultSet#getTimestamp(String)", "java.util.Calendar#setTime(Date)", + "java.lang.StringBuffer#append(Object)", "java.io.File#getParentFile()", + "java.util.stream.Stream#allMatch(Predicate)", "java.sql.ResultSet#getTimestamp(String)", + "java.util.Calendar#setTime(Date)", "java.util.concurrent.CompletionStage#toCompletableFuture()", "java.util.concurrent.locks.Lock#lock()", "java.lang.reflect.Field#get(Object)", "java.io.InputStream#close()", "java.math.BigInteger#BigInteger(String)", @@ -240,8 +240,7 @@ predicate topJdkApiName(string apiName) { "java.lang.AbstractStringBuilder#setLength(int)", "java.nio.Buffer#position()", "java.nio.file.Path#getFileName()", "java.util.List#toArray()", "java.lang.CharSequence#length()", "java.util.stream.Stream#distinct()", - "java.lang.String#format(ObjectString,Object[])", "java.net.URL#toURI()", - "java.util.Queue#poll()", "java.lang.Thread#getContextClassLoader()", + "java.net.URL#toURI()", "java.util.Queue#poll()", "java.lang.Thread#getContextClassLoader()", "java.lang.String#valueOf(boolean)", "java.util.Calendar#add(int,int)", "java.util.HashMap#entrySet()", "java.util.stream.IntStream#mapToObj(IntFunction)", "java.util.concurrent.atomic.AtomicLong#incrementAndGet()", From 17e09203250eae4b5fabd97bc747ed9283ecc1f2 Mon Sep 17 00:00:00 2001 From: Jami Cogswell <jcogs33@Jamis-MacBook-Pro.local> Date: Thu, 23 Mar 2023 18:00:14 -0400 Subject: [PATCH 388/631] Java: resolve more conflicts --- java/ql/lib/ext/java.awt.model.yml | 3 +- java/ql/lib/ext/java.io.model.yml | 11 +- java/ql/lib/ext/java.lang.model.yml | 48 ++++--- java/ql/lib/ext/java.lang.reflect.model.yml | 13 +- java/ql/lib/ext/java.math.model.yml | 6 +- java/ql/lib/ext/java.nio.charset.model.yml | 4 +- java/ql/lib/ext/java.nio.file.model.yml | 3 +- java/ql/lib/ext/java.nio.model.yml | 2 +- java/ql/lib/ext/java.sql.model.yml | 6 +- java/ql/lib/ext/java.text.model.yml | 8 +- java/ql/lib/ext/java.time.chrono.model.yml | 4 +- java/ql/lib/ext/java.time.format.model.yml | 6 +- java/ql/lib/ext/java.time.model.yml | 11 +- .../ext/java.util.concurrent.atomic.model.yml | 2 +- .../ql/lib/ext/java.util.concurrent.model.yml | 14 +- java/ql/lib/ext/java.util.function.model.yml | 4 +- java/ql/lib/ext/java.util.logging.model.yml | 3 +- java/ql/lib/ext/java.util.model.yml | 26 ++-- java/ql/lib/ext/java.util.stream.model.yml | 9 +- java/ql/test/ext/TestModels/Test.java | 124 +++++++++++++++++- java/ql/test/ext/TopJdkApis/TopJdkApis.qll | 6 +- .../ext/TopJdkApis/TopJdkApisTest.expected | 3 + 22 files changed, 214 insertions(+), 102 deletions(-) diff --git a/java/ql/lib/ext/java.awt.model.yml b/java/ql/lib/ext/java.awt.model.yml index 30cabdcf8e5..40b8b196e8f 100644 --- a/java/ql/lib/ext/java.awt.model.yml +++ b/java/ql/lib/ext/java.awt.model.yml @@ -3,7 +3,8 @@ extensions: pack: codeql/java-all extensible: summaryModel data: - - ["java.awt", "Container", True, "add", "(Component)", "", "Argument[0]", "Argument[-1].Element", "value", "manual"] # ! signature as "" instead? + - ["java.awt", "Container", True, "add", "(Component)", "", "Argument[0]", "Argument[-1].Element", "value", "manual"] + - ["java.awt", "Container", True, "add", "(Component)", "", "Argument[0]", "ReturnValue", "value", "manual"] - ["java.awt", "Container", True, "add", "(Component,Object)", "", "Argument[0]", "Argument[-1].Element", "value", "manual"] - addsTo: diff --git a/java/ql/lib/ext/java.io.model.yml b/java/ql/lib/ext/java.io.model.yml index 4c500236fa0..eed26f37299 100644 --- a/java/ql/lib/ext/java.io.model.yml +++ b/java/ql/lib/ext/java.io.model.yml @@ -69,7 +69,9 @@ extensions: - ["java.io", "File", True, "getCanonicalFile", "", "", "Argument[this]", "ReturnValue", "taint", "manual"] - ["java.io", "File", True, "getCanonicalPath", "", "", "Argument[this]", "ReturnValue", "taint", "manual"] - ["java.io", "File", True, "getName", "()", "", "Argument[this]", "ReturnValue", "taint", "manual"] - - ["java.io", "File", False, "getPath", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] # ! True versus False (maybe it's private/hidden?).. (and neutral instead?) + - ["java.io", "File", True, "getParentFile", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["java.io", "File", True, "getPath", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["java.io", "File", True, "listFiles", "()", "", "Argument[-1]", "ReturnValue.ArrayElement", "taint", "manual"] - ["java.io", "File", True, "toPath", "", "", "Argument[this]", "ReturnValue", "taint", "manual"] - ["java.io", "File", True, "toString", "", "", "Argument[this]", "ReturnValue", "taint", "manual"] - ["java.io", "File", True, "toURI", "", "", "Argument[this]", "ReturnValue", "taint", "manual"] @@ -90,7 +92,7 @@ extensions: - ["java.io", "OutputStream", True, "write", "(int)", "", "Argument[0]", "Argument[this]", "taint", "manual"] - ["java.io", "Reader", True, "read", "", "", "Argument[this]", "Argument[0]", "taint", "manual"] - ["java.io", "StringReader", False, "StringReader", "", "", "Argument[0]", "Argument[this]", "taint", "manual"] - - ["java.io", "StringWriter", False, "toString", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] # ! currently supported by taintPreservingQualifierToMethod? + - ["java.io", "StringWriter", False, "toString", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] # ! keep an eye on this one for FP flow, already modeled in `taintPreservingQualifierToMethod` predicate? - ["java.io", "UncheckedIOException", False, "UncheckedIOException", "(IOException)", "", "Argument[0]", "Argument[-1].SyntheticField[java.lang.Throwable.cause]", "value", "manual"] - ["java.io", "Writer", True, "write", "", "", "Argument[0]", "Argument[this]", "taint", "manual"] - addsTo: @@ -98,16 +100,15 @@ extensions: extensible: neutralModel data: - ["java.io", "Closeable", "close", "()", "manual"] + - ["java.io", "DataOutput", "writeBoolean", "(boolean)", "manual"] - ["java.io", "File", "delete", "()", "manual"] - ["java.io", "File", "exists", "()", "manual"] - - ["java.io", "File", "getParentFile", "()", "manual"] # ! little unsure about this as a neutral - ["java.io", "File", "isFile", "()", "manual"] - ["java.io", "File", "length", "()", "manual"] - - ["java.io", "File", "listFiles", "()", "manual"] # ! little unsure about this as a neutral - ["java.io", "File", "isDirectory", "()", "manual"] - ["java.io", "File", "mkdirs", "()", "manual"] - ["java.io", "InputStream", "close", "()", "manual"] - - ["java.io", "OutputStream", "flush", "()", "manual"] # ! little unsure about this as a neutral, but not sure how to represent output if summary model... + - ["java.io", "OutputStream", "flush", "()", "manual"] # The below APIs have numeric flow and are currently being stored as neutral models. # These may be changed to summary models with kinds "value-numeric" and "taint-numeric" (or similar) in the future. diff --git a/java/ql/lib/ext/java.lang.model.yml b/java/ql/lib/ext/java.lang.model.yml index 6a581ff12a6..7cfc9ce68bc 100644 --- a/java/ql/lib/ext/java.lang.model.yml +++ b/java/ql/lib/ext/java.lang.model.yml @@ -108,30 +108,33 @@ extensions: - ["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"] - # ! why do below have subtype=True for constructors? - ["java.lang", "StringBuffer", True, "StringBuffer", "(CharSequence)", "", "Argument[0]", "Argument[this]", "taint", "manual"] - ["java.lang", "StringBuffer", True, "StringBuffer", "(String)", "", "Argument[0]", "Argument[this]", "taint", "manual"] - ["java.lang", "StringBuilder", True, "StringBuilder", "", "", "Argument[0]", "Argument[this]", "taint", "manual"] - ["java.lang", "StringBuilder", False, "delete", "(int,int)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - ["java.lang", "System", False, "arraycopy", "", "", "Argument[0]", "Argument[2]", "taint", "manual"] - - ["java.lang", "System", False, "getenv", "(String)", "", "Argument[-1].MapValue", "ReturnValue", "value", "manual"] # ! neutral instead? - - ["java.lang", "System", False, "getenv", "(String)", "", "Argument[0]", "ReturnValue", "taint", "manual"] # ! really unsure about this...; neutral instead? -- or unmodelled - - ["java.lang", "Thread", False, "Thread", "(Runnable)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] # ! neutral instead? + - ["java.lang", "Thread", False, "Thread", "(Runnable)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] + - ["java.lang", "Thread", False, "Thread", "(String)", "", "Argument[0]", "Argument[-1].SyntheticField[java.lang.Thread.name]", "value", "manual"] - ["java.lang", "Thread", True, "getName", "()", "", "Argument[-1].SyntheticField[java.lang.Thread.name]", "ReturnValue", "value", "manual"] - - ["java.lang", "ThreadLocal", True, "get", "()", "", "Argument[-1].SyntheticField[java.lang.ThreadLocal.value]", "ReturnValue", "value", "manual"] # ! not sure if this model is correct, and if should be neutral model instead + - ["java.lang", "ThreadLocal", True, "get", "()", "", "Argument[-1].SyntheticField[java.lang.ThreadLocal.value]", "ReturnValue", "value", "manual"] + - ["java.lang", "ThreadLocal", True, "set", "(Object)", "", "Argument[0]", "Argument[-1].SyntheticField[java.lang.ThreadLocal.value]", "value", "manual"] - ["java.lang", "Throwable", False, "Throwable", "(Throwable)", "", "Argument[0]", "Argument[this].SyntheticField[java.lang.Throwable.cause]", "value", "manual"] + - ["java.lang", "Throwable", False, "Throwable", "(String)", "", "Argument[0]", "Argument[-1].SyntheticField[java.lang.Throwable.message]", "value", "manual"] - ["java.lang", "Throwable", True, "getCause", "()", "", "Argument[this].SyntheticField[java.lang.Throwable.cause]", "ReturnValue", "value", "manual"] - ["java.lang", "Throwable", True, "getMessage", "()", "", "Argument[this].SyntheticField[java.lang.Throwable.message]", "ReturnValue", "value", "manual"] - - ["java.lang", "Throwable", True, "getLocalizedMessage", "()", "", "Argument[-1].SyntheticField[java.lang.Throwable.message]", "ReturnValue", "value", "manual"] # ! should the field used be different? - - ["java.lang", "Throwable", True, "toString", "()", "", "Argument[-1].SyntheticField[java.lang.Throwable.message]", "ReturnValue", "taint", "manual"] # ! little unsure about this one... + - ["java.lang", "Throwable", True, "getLocalizedMessage", "()", "", "Argument[-1].SyntheticField[java.lang.Throwable.message]", "ReturnValue", "value", "manual"] + - ["java.lang", "Throwable", True, "toString", "()", "", "Argument[-1].SyntheticField[java.lang.Throwable.message]", "ReturnValue", "taint", "manual"] # ! watch for FPs + - addsTo: pack: codeql/java-all extensible: neutralModel data: - ["java.lang", "AbstractStringBuilder", "length", "()", "manual"] - - ["java.lang", "AbstractStringBuilder", "setCharAt", "(int,char)", "manual"] # ! char manipulation not interesting? (or interesting since could set many chars... prbly switch to summary model) - - ["java.lang", "AbstractStringBuilder", "setLength", "(int)", "manual"] # ! summary? + - ["java.lang", "AbstractStringBuilder", "setCharAt", "(int,char)", "manual"] + - ["java.lang", "AbstractStringBuilder", "setLength", "(int)", "manual"] + - ["java.lang", "Boolean", "booleanValue", "()", "manual"] - ["java.lang", "Boolean", "equals", "(Object)", "manual"] + - ["java.lang", "Boolean", "parseBoolean", "(String)", "manual"] - ["java.lang", "Boolean", "valueOf", "(boolean)", "manual"] - ["java.lang", "CharSequence", "length", "()", "manual"] - ["java.lang", "Class", "forName", "(String)", "manual"] @@ -179,18 +182,17 @@ extensions: - ["java.lang", "String", "valueOf", "(boolean)", "manual"] - ["java.lang", "System", "currentTimeMillis", "()", "manual"] - ["java.lang", "System", "exit", "(int)", "manual"] + - ["java.lang", "System", "getenv", "(String)", "manual"] - ["java.lang", "System", "identityHashCode", "(Object)", "manual"] - - ["java.lang", "System", "lineSeparator", "()", "manual"] # ! double-check... + - ["java.lang", "System", "lineSeparator", "()", "manual"] - ["java.lang", "System", "nanoTime", "()", "manual"] - ["java.lang", "Thread", "currentThread", "()", "manual"] - - ["java.lang", "Thread", "getContextClassLoader", "()", "manual"] # ! summary instead? + - ["java.lang", "Thread", "getContextClassLoader", "()", "manual"] - ["java.lang", "Thread", "interrupt", "()", "manual"] - ["java.lang", "Thread", "sleep", "(long)", "manual"] - ["java.lang", "Thread", "start", "()", "manual"] # The below APIs have numeric flow and are currently being stored as neutral models. # These may be changed to summary models with kinds "value-numeric" and "taint-numeric" (or similar) in the future. - - ["java.lang", "Boolean", "booleanValue", "()", "manual"] # taint-numeric - - ["java.lang", "Boolean", "parseBoolean", "(String)", "manual"] # taint-numeric - ["java.lang", "Double", "doubleToLongBits", "(double)", "manual"] # taint-numeric - ["java.lang", "Double", "parseDouble", "(String)", "manual"] # taint-numeric - ["java.lang", "Double", "valueOf", "(double)", "manual"] # taint-numeric @@ -198,23 +200,17 @@ extensions: - ["java.lang", "Integer", "intValue", "()", "manual"] # taint-numeric - ["java.lang", "Integer", "parseInt", "(String)", "manual"] # taint-numeric - ["java.lang", "Integer", "toHexString", "(int)", "manual"] # taint-numeric - - ["java.lang", "Integer", "toString", "()", "manual"] # taint-numeric - - ["java.lang", "Integer", "toString", "(int)", "manual"] # taint-numeric - - ["java.lang", "Integer", "valueOf", "(int)", "manual"] # taint-numeric - - ["java.lang", "Integer", "valueOf", "(String)", "manual"] # taint-numeric # ! should probably make this and others like it have a "" signature instead... + - ["java.lang", "Integer", "toString", "", "manual"] # taint-numeric + - ["java.lang", "Integer", "valueOf", "", "manual"] # taint-numeric - ["java.lang", "Long", "Long", "(long)", "manual"] # taint-numeric - ["java.lang", "Long", "intValue", "()", "manual"] # taint-numeric - ["java.lang", "Long", "longValue", "()", "manual"] # taint-numeric - ["java.lang", "Long", "parseLong", "(String)", "manual"] # taint-numeric - - ["java.lang", "Long", "toString", "()", "manual"] # taint-numeric - - ["java.lang", "Long", "toString", "(long)", "manual"] # taint-numeric - - ["java.lang", "Long", "valueOf", "(long)", "manual"] # taint-numeric - - ["java.lang", "Long", "valueOf", "(String)", "manual"] # taint-numeric - - ["java.lang", "Math", "max", "(int,int)", "manual"] # value-numeric - - ["java.lang", "Math", "max", "(long,long)", "manual"] # value-numeric - - ["java.lang", "Math", "min", "(int,int)", "manual"] # value-numeric - - ["java.lang", "Math", "min", "(long,long)", "manual"] # value-numeric - - ["java.lang", "Number", "doubleValue", "()", "manual"] # taint-numeric # ! remove others that could rely on subtyping through Number instead? (e.g. Double, Integer, etc.) + - ["java.lang", "Long", "toString", "", "manual"] # taint-numeric + - ["java.lang", "Long", "valueOf", "", "manual"] # taint-numeric + - ["java.lang", "Math", "max", "", "manual"] # value-numeric + - ["java.lang", "Math", "min", "", "manual"] # value-numeric + - ["java.lang", "Number", "doubleValue", "()", "manual"] # taint-numeric - ["java.lang", "Number", "intValue", "()", "manual"] # taint-numeric - ["java.lang", "Number", "longValue", "()", "manual"] # taint-numeric - ["java.lang", "String", "valueOf", "(int)", "manual"] # taint-numeric diff --git a/java/ql/lib/ext/java.lang.reflect.model.yml b/java/ql/lib/ext/java.lang.reflect.model.yml index 97df7cde61e..a709a0fc8b6 100644 --- a/java/ql/lib/ext/java.lang.reflect.model.yml +++ b/java/ql/lib/ext/java.lang.reflect.model.yml @@ -1,14 +1,9 @@ extensions: - - addsTo: - pack: codeql/java-all - extensible: summaryModel - data: - - ["java.lang.reflect", "Constructor", False, "newInstance", "(Object[])", "", "Argument[0].ArrayElement", "ReturnValue.Parameter", "value", "manual"] # ! unsure about input/output - - ["java.lang.reflect", "Field", False, "get", "(Object)", "", "Argument[0].Field", "ReturnValue", "value", "manual"] # ! very unsure about - - ["java.lang.reflect", "Method", False, "invoke", "(Object,Object[])", "", "Argument[1].ArrayElement", "Argument[-1].Parameter[0]", "value", "manual"] # ! very unsure if this model is correct... - - addsTo: pack: codeql/java-all extensible: neutralModel data: - - ["java.lang.reflect", "Method", "getName", "()", "manual"] # ! seems uninteresting flow to me, but maybe double-check + - ["java.lang.reflect", "Constructor", "newInstance", "(Object[])", "manual"] + - ["java.lang.reflect", "Field", "get", "(Object)", "manual"] + - ["java.lang.reflect", "Method", "getName", "()", "manual"] + - ["java.lang.reflect", "Method", "invoke", "(Object,Object[])", "manual"] diff --git a/java/ql/lib/ext/java.math.model.yml b/java/ql/lib/ext/java.math.model.yml index c80f9c87031..b3ee529339f 100644 --- a/java/ql/lib/ext/java.math.model.yml +++ b/java/ql/lib/ext/java.math.model.yml @@ -7,8 +7,7 @@ extensions: # The below APIs have numeric flow and are currently being stored as neutral models. # These may be changed to summary models with kinds "value-numeric" and "taint-numeric" (or similar) in the future. - - ["java.math", "BigDecimal", "BigDecimal", "(int)", "manual"] # taint-numeric - - ["java.math", "BigDecimal", "BigDecimal", "(String)", "manual"] # taint-numeric + - ["java.math", "BigDecimal", "BigDecimal", "", "manual"] # taint-numeric - ["java.math", "BigDecimal", "add", "(BigDecimal)", "manual"] # taint-numeric - ["java.math", "BigDecimal", "doubleValue", "()", "manual"] # taint-numeric - ["java.math", "BigDecimal", "intValue", "()", "manual"] # taint-numeric @@ -17,8 +16,7 @@ extensions: - ["java.math", "BigDecimal", "subtract", "(BigDecimal)", "manual"] # taint-numeric - ["java.math", "BigDecimal", "toBigInteger", "()", "manual"] # taint-numeric - ["java.math", "BigDecimal", "toString", "()", "manual"] # taint-numeric - - ["java.math", "BigDecimal", "valueOf", "(double)", "manual"] # taint-numeric - - ["java.math", "BigDecimal", "valueOf", "(long)", "manual"] # taint-numeric + - ["java.math", "BigDecimal", "valueOf", "", "manual"] # taint-numeric - ["java.math", "BigInteger", "BigInteger", "(String)", "manual"] # taint-numeric - ["java.math", "BigInteger", "or", "(BigInteger)", "manual"] # taint-numeric - ["java.math", "BigInteger", "valueOf", "(long)", "manual"] # taint-numeric diff --git a/java/ql/lib/ext/java.nio.charset.model.yml b/java/ql/lib/ext/java.nio.charset.model.yml index e961a06256e..16e8943f99c 100644 --- a/java/ql/lib/ext/java.nio.charset.model.yml +++ b/java/ql/lib/ext/java.nio.charset.model.yml @@ -1,6 +1,6 @@ extensions: - addsTo: pack: codeql/java-all - extensible: summaryModel + extensible: neutralModel data: - - ["java.nio.charset", "Charset", False, "name", "()", "", "Argument[-1].SyntheticField[java.nio.charset.Charset.canonicalName]", "ReturnValue", "value", "manual"] + - ["java.nio.charset", "Charset", "name", "()", "manual"] diff --git a/java/ql/lib/ext/java.nio.file.model.yml b/java/ql/lib/ext/java.nio.file.model.yml index 690121f849d..ce955985e28 100644 --- a/java/ql/lib/ext/java.nio.file.model.yml +++ b/java/ql/lib/ext/java.nio.file.model.yml @@ -44,9 +44,8 @@ extensions: - ["java.nio.file", "FileSystem", True, "getPathMatcher", "(String)", "", "Argument[0]", "ReturnValue", "taint", "ai-generated"] - ["java.nio.file", "FileSystem", True, "getRootDirectories", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] - ["java.nio.file", "Path", True, "getParent", "", "", "Argument[this]", "ReturnValue", "taint", "manual"] - # ! should Path have subtyping of False for all methods instead? Why is `toFile` different? - ["java.nio.file", "Path", True, "normalize", "", "", "Argument[this]", "ReturnValue", "taint", "manual"] - - ["java.nio.file", "Path", False, "getFileName", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] # ! maybe need more field flow? + - ["java.nio.file", "Path", True, "getFileName", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - ["java.nio.file", "Path", True, "of", "(String,String[])", "", "Argument[0]", "ReturnValue", "taint", "ai-generated"] - ["java.nio.file", "Path", True, "of", "(String,String[])", "", "Argument[1]", "ReturnValue", "taint", "ai-generated"] - ["java.nio.file", "Path", True, "of", "(URI)", "", "Argument[0]", "ReturnValue", "taint", "ai-generated"] diff --git a/java/ql/lib/ext/java.nio.model.yml b/java/ql/lib/ext/java.nio.model.yml index cc90940c122..d64d4809c5c 100644 --- a/java/ql/lib/ext/java.nio.model.yml +++ b/java/ql/lib/ext/java.nio.model.yml @@ -11,6 +11,6 @@ extensions: pack: codeql/java-all extensible: neutralModel data: - - ["java.nio", "Buffer", "position", "()", "manual"] # ! maybe should be summary? + - ["java.nio", "Buffer", "position", "()", "manual"] - ["java.nio", "Buffer", "remaining", "()", "manual"] - ["java.nio", "ByteBuffer", "allocate", "(int)", "manual"] diff --git a/java/ql/lib/ext/java.sql.model.yml b/java/ql/lib/ext/java.sql.model.yml index 47874a3333d..f5b15706476 100644 --- a/java/ql/lib/ext/java.sql.model.yml +++ b/java/ql/lib/ext/java.sql.model.yml @@ -21,10 +21,8 @@ extensions: extensible: summaryModel data: - ["java.sql", "Connection", True, "nativeSQL", "(String)", "", "Argument[0]", "ReturnValue", "taint", "manual"] - - ["java.sql", "PreparedStatement", True, "executeQuery", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] # ! this should maybe be a neutral model, not sure if this really counts as "flow through"... - ["java.sql", "PreparedStatement", True, "setString", "(int,String)", "", "Argument[1]", "Argument[this]", "value", "manual"] - ["java.sql", "ResultSet", True, "getString", "(String)", "", "Argument[this]", "ReturnValue", "taint", "manual"] - - ["java.sql", "ResultSet", True, "getTimestamp", "(String)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - addsTo: pack: codeql/java-all @@ -32,7 +30,10 @@ extensions: data: - ["java.sql", "Connection", "createStatement", "()", "manual"] - ["java.sql", "PreparedStatement", "executeUpdate", "()", "manual"] + - ["java.sql", "PreparedStatement", "executeQuery", "()", "manual"] - ["java.sql", "ResultSet", "next", "()", "manual"] + - ["java.sql", "Statement", "close", "()", "manual"] + # The below APIs have numeric flow and are currently being stored as neutral models. # These may be changed to summary models with kinds "value-numeric" and "taint-numeric" (or similar) in the future. - ["java.sql", "PreparedStatement", "setInt", "(int,int)", "manual"] # value-numeric @@ -41,5 +42,6 @@ extensions: - ["java.sql", "ResultSet", "getInt", "(String)", "manual"] # taint-numeric - ["java.sql", "ResultSet", "getLong", "(String)", "manual"] # taint-numeric - ["java.sql", "ResultSet", "getString", "(int)", "manual"] # taint-numeric + - ["java.sql", "ResultSet", "getTimestamp", "(String)", "manual"] # taint-numeric - ["java.sql", "Timestamp", "Timestamp", "(long)", "manual"] # taint-numeric - ["java.sql", "Timestamp", "getTime", "()", "manual"] # taint-numeric diff --git a/java/ql/lib/ext/java.text.model.yml b/java/ql/lib/ext/java.text.model.yml index 4056b4d0c7a..e179f9f5d6f 100644 --- a/java/ql/lib/ext/java.text.model.yml +++ b/java/ql/lib/ext/java.text.model.yml @@ -3,10 +3,9 @@ extensions: pack: codeql/java-all extensible: summaryModel data: - - ["java.text", "DateFormat", True, "parse", "(String)", "", "Argument[0]", "ReturnValue", "taint", "manual"] # ! maybe not interesting flow and should be neutral model? - - ["java.text", "Format", True, "format", "(Object)", "", "Argument[0]", "ReturnValue", "taint", "manual"] # ! would cover DateFormat.format below through subtyping... - - ["java.text", "MessageFormat", False, "format", "(String,Object[])", "", "Argument[0]", "ReturnValue", "taint", "manual"] # ! not sure I did this right - - ["java.text", "MessageFormat", False, "format", "(String,Object[])", "", "Argument[1].ArrayElement", "ReturnValue", "taint", "manual"] # ! not sure I did this right + - ["java.text", "Format", True, "format", "(Object)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["java.text", "MessageFormat", False, "format", "(String,Object[])", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["java.text", "MessageFormat", False, "format", "(String,Object[])", "", "Argument[1].ArrayElement", "ReturnValue", "taint", "manual"] - addsTo: pack: codeql/java-all @@ -15,4 +14,5 @@ extensions: # The below APIs have numeric flow and are currently being stored as neutral models. # These may be changed to summary models with kinds "value-numeric" and "taint-numeric" (or similar) in the future. - ["java.text", "DateFormat", "format", "(Date)", "manual"] # taint-numeric + - ["java.text", "DateFormat", "parse", "(String)", "manual"] # taint-numeric - ["java.text", "SimpleDateFormat", "SimpleDateFormat", "(String)", "manual"] # taint-numeric diff --git a/java/ql/lib/ext/java.time.chrono.model.yml b/java/ql/lib/ext/java.time.chrono.model.yml index 9dd5ca401d3..b222058d932 100644 --- a/java/ql/lib/ext/java.time.chrono.model.yml +++ b/java/ql/lib/ext/java.time.chrono.model.yml @@ -1,6 +1,6 @@ extensions: - addsTo: pack: codeql/java-all - extensible: summaryModel + extensible: neutralModel data: - - ["java.time.chrono", "ChronoZonedDateTime", False, "toInstant", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] # ! neutral? + - ["java.time.chrono", "ChronoZonedDateTime", "toInstant", "()", "manual"] diff --git a/java/ql/lib/ext/java.time.format.model.yml b/java/ql/lib/ext/java.time.format.model.yml index 083e811ebb9..5cfb255733c 100644 --- a/java/ql/lib/ext/java.time.format.model.yml +++ b/java/ql/lib/ext/java.time.format.model.yml @@ -1,7 +1,7 @@ extensions: - addsTo: pack: codeql/java-all - extensible: summaryModel + extensible: neutralModel data: - - ["java.time.format", "DateTimeFormatter", False, "format", "(TemporalAccessor)", "", "Argument[0]", "ReturnValue", "taint", "manual"] # ! neutral? - - ["java.time.format", "DateTimeFormatter", False, "ofPattern", "(String)", "", "Argument[0]", "ReturnValue", "taint", "manual"] # ! neutral? + - ["java.time.format", "DateTimeFormatter", "format", "(TemporalAccessor)", "manual"] + - ["java.time.format", "DateTimeFormatter", "ofPattern", "(String)", "manual"] diff --git a/java/ql/lib/ext/java.time.model.yml b/java/ql/lib/ext/java.time.model.yml index 456c1d593a0..7f12490964d 100644 --- a/java/ql/lib/ext/java.time.model.yml +++ b/java/ql/lib/ext/java.time.model.yml @@ -1,12 +1,4 @@ extensions: - - addsTo: - pack: codeql/java-all - extensible: summaryModel - data: - - ["java.time", "Duration", False, "ofSeconds", "(long)", "", "Argument[0]", "ReturnValue", "taint", "manual"] # ! maybe not interesting flow and should be neutral model? - - ["java.time", "Instant", False, "parse", "(CharSequence)", "", "Argument[0]", "ReturnValue", "taint", "manual"] # ! mmaybe should be neutral since time-related? - - ["java.time", "LocalDate", False, "parse", "(CharSequence)", "", "Argument[0]", "ReturnValue", "taint", "manual"] - - addsTo: pack: codeql/java-all extensible: neutralModel @@ -22,9 +14,12 @@ extensions: # These may be changed to summary models with kinds "value-numeric" and "taint-numeric" (or similar) in the future. - ["java.time", "Duration", "ofMillis", "(long)", "manual"] # taint-numeric - ["java.time", "Duration", "ofMinutes", "(long)", "manual"] # taint-numeric + - ["java.time", "Duration", "ofSeconds", "(long)", "manual"] # taint-numeric - ["java.time", "Duration", "toMillis", "()", "manual"] # taint-numeric - ["java.time", "Instant", "ofEpochMilli", "(long)", "manual"] # taint-numeric + - ["java.time", "Instant", "parse", "(CharSequence)", "manual"] # taint-numeric - ["java.time", "Instant", "toEpochMilli", "()", "manual"] # taint-numeric - ["java.time", "LocalDate", "plusDays", "(long)", "manual"] # taint-numeric - ["java.time", "LocalDate", "of", "(int,int,int)", "manual"] # taint-numeric + - ["java.time", "LocalDate", "parse", "(CharSequence)", "manual"] # taint-numeric - ["java.time", "LocalDateTime", "of", "(int,int,int,int,int,int)", "manual"] # taint-numeric diff --git a/java/ql/lib/ext/java.util.concurrent.atomic.model.yml b/java/ql/lib/ext/java.util.concurrent.atomic.model.yml index b2da86b1aa5..fcfa403d5e5 100644 --- a/java/ql/lib/ext/java.util.concurrent.atomic.model.yml +++ b/java/ql/lib/ext/java.util.concurrent.atomic.model.yml @@ -21,7 +21,7 @@ extensions: - ["java.util.concurrent.atomic", "AtomicInteger", "AtomicInteger", "(int)", "manual"] # value-numeric - ["java.util.concurrent.atomic", "AtomicInteger", "get", "()", "manual"] # value-numeric - ["java.util.concurrent.atomic", "AtomicInteger", "incrementAndGet", "()", "manual"] # taint-numeric - - ["java.util.concurrent.atomic", "AtomicLong", "AtomicLong", "(long)", "manual"] # value-numeric # ! this is supposedly already supported per the telemetry query, LOOK INTO WHY/HOW + - ["java.util.concurrent.atomic", "AtomicLong", "AtomicLong", "(long)", "manual"] # value-numeric - ["java.util.concurrent.atomic", "AtomicLong", "addAndGet", "(long)", "manual"] # taint-numeric - ["java.util.concurrent.atomic", "AtomicLong", "get", "()", "manual"] # value-numeric - ["java.util.concurrent.atomic", "AtomicLong", "incrementAndGet", "()", "manual"] # taint-numeric diff --git a/java/ql/lib/ext/java.util.concurrent.model.yml b/java/ql/lib/ext/java.util.concurrent.model.yml index c5598039074..b050467260e 100644 --- a/java/ql/lib/ext/java.util.concurrent.model.yml +++ b/java/ql/lib/ext/java.util.concurrent.model.yml @@ -17,14 +17,13 @@ extensions: - ["java.util.concurrent", "BlockingQueue", True, "poll", "(long,TimeUnit)", "", "Argument[this].Element", "ReturnValue", "value", "manual"] - ["java.util.concurrent", "BlockingQueue", True, "put", "(Object)", "", "Argument[0]", "Argument[this].Element", "value", "manual"] - ["java.util.concurrent", "BlockingQueue", True, "take", "()", "", "Argument[this].Element", "ReturnValue", "value", "manual"] - - ["java.util.concurrent", "CompletableFuture", False, "complete", "(Object)", "", "Argument[0]", "Argument[-1].SyntheticField[java.util.concurrent.CompletableFuture.value]", "value", "manual"] # ! not sure about CompleteableFuture ones - - ["java.util.concurrent", "CompletableFuture", False, "completedFuture", "(Object)", "", "Argument[0]", "ReturnValue.SyntheticField[java.util.concurrent.CompletableFuture.value]", "value", "manual"] - - ["java.util.concurrent", "CompletableFuture", False, "get", "()", "", "Argument[-1].SyntheticField[java.util.concurrent.CompletableFuture.value]", "ReturnValue", "value", "manual"] # ! not sure if using SyntheticField is correct here; also, should prbly remove this for `Future.get` below's subtyping to handle. - - ["java.util.concurrent", "CompletableFuture", False, "join", "()", "", "Argument[-1].SyntheticField[java.util.concurrent.CompletableFuture.value]", "ReturnValue", "value", "manual"] # ! not sure if using SyntheticField is correct here + - ["java.util.concurrent", "CompletableFuture", False, "complete", "(Object)", "", "Argument[0]", "Argument[-1].SyntheticField[java.util.concurrent.Future.value]", "value", "manual"] + - ["java.util.concurrent", "CompletableFuture", False, "completedFuture", "(Object)", "", "Argument[0]", "ReturnValue.SyntheticField[java.util.concurrent.Future.value]", "value", "manual"] + - ["java.util.concurrent", "CompletableFuture", False, "join", "()", "", "Argument[-1].SyntheticField[java.util.concurrent.Future.value]", "ReturnValue", "value", "manual"] - ["java.util.concurrent", "CompletionStage", False, "toCompletableFuture", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - ["java.util.concurrent", "ConcurrentHashMap", True, "elements", "()", "", "Argument[this].MapValue", "ReturnValue.Element", "value", "manual"] - ["java.util.concurrent", "ExecutorService", True, "submit", "(Runnable)", "", "Argument[0]", "ReturnValue", "taint", "manual"] - - ["java.util.concurrent", "Future", True, "get", "()", "", "Argument[-1].SyntheticField[java.util.concurrent.Future.value]", "ReturnValue", "value", "manual"] # ! not sure if using SyntheticField is correct here + - ["java.util.concurrent", "Future", True, "get", "()", "", "Argument[-1].SyntheticField[java.util.concurrent.Future.value]", "ReturnValue", "value", "manual"] - ["java.util.concurrent", "TransferQueue", True, "transfer", "(Object)", "", "Argument[0]", "Argument[this].Element", "value", "manual"] - ["java.util.concurrent", "TransferQueue", True, "tryTransfer", "(Object)", "", "Argument[0]", "Argument[this].Element", "value", "manual"] - ["java.util.concurrent", "TransferQueue", True, "tryTransfer", "(Object,long,TimeUnit)", "", "Argument[0]", "Argument[this].Element", "value", "manual"] @@ -33,10 +32,9 @@ extensions: pack: codeql/java-all extensible: neutralModel data: - - ["java.util.concurrent", "CompletableFuture", "completeExceptionally", "(Throwable)", "manual"] # ! summary? + - ["java.util.concurrent", "CompletableFuture", "completeExceptionally", "(Throwable)", "manual"] - ["java.util.concurrent", "CompletableFuture", "isDone", "()", "manual"] - - ["java.util.concurrent", "CountDownLatch", "await", "()", "manual"] # ! combine with below, "" as signature - - ["java.util.concurrent", "CountDownLatch", "await", "(long,TimeUnit)", "manual"] + - ["java.util.concurrent", "CountDownLatch", "await", "", "manual"] - ["java.util.concurrent", "CountDownLatch", "countDown", "()", "manual"] - ["java.util.concurrent", "Executor", "execute", "(Runnable)", "manual"] - ["java.util.concurrent", "ExecutorService", "shutdown", "()", "manual"] diff --git a/java/ql/lib/ext/java.util.function.model.yml b/java/ql/lib/ext/java.util.function.model.yml index d28b699f1b8..8cdab4149cd 100644 --- a/java/ql/lib/ext/java.util.function.model.yml +++ b/java/ql/lib/ext/java.util.function.model.yml @@ -9,6 +9,4 @@ extensions: pack: codeql/java-all extensible: neutralModel data: - - ["java.util.function", "BiConsumer", "accept", "(Object,Object)", "manual"] # ! remove this model? - - ["java.util.function", "BiFunction", "apply", "(Object,Object)", "manual"] # ! remove this model? - - ["java.util.function", "Function", "identity", "()", "manual"] # ! remove this model? + - ["java.util.function", "Function", "identity", "()", "manual"] diff --git a/java/ql/lib/ext/java.util.logging.model.yml b/java/ql/lib/ext/java.util.logging.model.yml index 45afcb2bfa8..58f80d47c18 100644 --- a/java/ql/lib/ext/java.util.logging.model.yml +++ b/java/ql/lib/ext/java.util.logging.model.yml @@ -41,7 +41,8 @@ extensions: pack: codeql/java-all extensible: summaryModel data: - - ["java.util.logging", "Logger", False, "getLogger", "(String)", "", "Argument[0]", "ReturnValue.SyntheticField[java.util.logging.Logger.name]", "value", "manual"] # ! not sure if using SyntheticField here is correct... + - ["java.util.logging", "Logger", False, "getLogger", "(String)", "", "Argument[0]", "ReturnValue.SyntheticField[java.util.logging.Logger.name]", "value", "manual"] + - ["java.util.logging", "Logger", False, "getName", "()", "", "Argument[-1].SyntheticField[java.util.logging.Logger.name]", "ReturnValue", "value", "manual"] - ["java.util.logging", "LogRecord", False, "LogRecord", "", "", "Argument[1]", "Argument[this]", "taint", "manual"] - addsTo: diff --git a/java/ql/lib/ext/java.util.model.yml b/java/ql/lib/ext/java.util.model.yml index 6cd77031325..30b5964baed 100644 --- a/java/ql/lib/ext/java.util.model.yml +++ b/java/ql/lib/ext/java.util.model.yml @@ -124,7 +124,8 @@ extensions: - ["java.util", "EnumMap", False, "EnumMap", "(Map)", "", "Argument[0].MapValue", "Argument[this].MapValue", "value", "manual"] - ["java.util", "Enumeration", True, "asIterator", "", "", "Argument[this].Element", "ReturnValue.Element", "value", "manual"] - ["java.util", "Enumeration", True, "nextElement", "", "", "Argument[this].Element", "ReturnValue", "value", "manual"] - - ["java.util", "EventObject", True, "getSource", "()", "", "Argument[-1].Field[java.util.EventObject.source]", "ReturnValue", "value", "manual"] # ! double-check + - ["java.util", "EventObject", False, "EventObject", "(Object)", "", "Argument[0]", "Argument[-1].Field[java.util.EventObject.source]", "value", "manual"] + - ["java.util", "EventObject", True, "getSource", "()", "", "Argument[-1].Field[java.util.EventObject.source]", "ReturnValue", "value", "manual"] - ["java.util", "HashMap", False, "HashMap", "(Map)", "", "Argument[0].MapKey", "Argument[this].MapKey", "value", "manual"] - ["java.util", "HashMap", False, "HashMap", "(Map)", "", "Argument[0].MapValue", "Argument[this].MapValue", "value", "manual"] - ["java.util", "HashSet", False, "HashSet", "(Collection)", "", "Argument[0].Element", "Argument[this].Element", "value", "manual"] @@ -161,7 +162,6 @@ extensions: - ["java.util", "ListIterator", True, "add", "(Object)", "", "Argument[0]", "Argument[this].Element", "value", "manual"] - ["java.util", "ListIterator", True, "previous", "", "", "Argument[this].Element", "ReturnValue", "value", "manual"] - ["java.util", "ListIterator", True, "set", "(Object)", "", "Argument[0]", "Argument[this].Element", "value", "manual"] - - ["java.util", "Locale", False, "forLanguageTag", "(String)", "", "Argument[0]", "ReturnValue", "taint", "manual"] # ! neutral? - ["java.util", "Map", True, "computeIfAbsent", "", "", "Argument[this].MapValue", "ReturnValue", "value", "manual"] - ["java.util", "Map", True, "computeIfAbsent", "", "", "Argument[1].ReturnValue", "Argument[this].MapValue", "value", "manual"] - ["java.util", "Map", True, "computeIfAbsent", "", "", "Argument[1].ReturnValue", "ReturnValue", "value", "manual"] @@ -178,7 +178,6 @@ extensions: - ["java.util", "Map", True, "getOrDefault", "", "", "Argument[1]", "ReturnValue", "value", "manual"] - ["java.util", "Map", True, "keySet", "()", "", "Argument[this].MapKey", "ReturnValue.Element", "value", "manual"] - ["java.util", "Map", True, "merge", "(Object,Object,BiFunction)", "", "Argument[1]", "Argument[this].MapValue", "value", "manual"] - # ! difference between formatting of below versus `List.of` above? - ["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"] @@ -350,7 +349,6 @@ extensions: - ["java.util", "TreeMap", False, "TreeMap", "(SortedMap)", "", "Argument[0].MapValue", "Argument[this].MapValue", "value", "manual"] - ["java.util", "TreeSet", False, "TreeSet", "(Collection)", "", "Argument[0].Element", "Argument[this].Element", "value", "manual"] - ["java.util", "TreeSet", False, "TreeSet", "(SortedSet)", "", "Argument[0].Element", "Argument[this].Element", "value", "manual"] - - ["java.util", "UUID", False, "fromString", "(String)", "", "Argument[0]", "ReturnValue", "taint", "manual"] - ["java.util", "Vector", False, "Vector", "(Collection)", "", "Argument[0].Element", "Argument[this].Element", "value", "manual"] - ["java.util", "Vector", True, "addElement", "(Object)", "", "Argument[0]", "Argument[this].Element", "value", "manual"] - ["java.util", "Vector", True, "copyInto", "(Object[])", "", "Argument[this].Element", "Argument[0].ArrayElement", "value", "manual"] @@ -370,34 +368,30 @@ extensions: - ["java.util", "ArrayList", "ArrayList", "(int)", "manual"] - ["java.util", "ArrayList", "isEmpty", "()", "manual"] - ["java.util", "ArrayList", "size", "()", "manual"] - - ["java.util", "Arrays", "toString", "(Object[])", "manual"] # ! should this have a summary model after all? (or unwanted model due to too much FP flow?) + - ["java.util", "Arrays", "toString", "(Object[])", "manual"] - ["java.util", "Calendar", "getInstance", "()", "manual"] - ["java.util", "Collection", "contains", "(Object)", "manual"] - ["java.util", "Collection", "isEmpty", "()", "manual"] - - ["java.util", "Collection", "removeIf", "(Predicate)", "manual"] # ! WithoutElement comment? (double-check if it returns anything, etc.) - ["java.util", "Collection", "size", "()", "manual"] - ["java.util", "Collections", "emptyList", "()", "manual"] - ["java.util", "Collections", "emptyMap", "()", "manual"] - ["java.util", "Collections", "emptySet", "()", "manual"] - - ["java.util", "Collections", "sort", "(List)", "manual"] # ! summary model instead? - - ["java.util", "Collections", "sort", "(List,Comparator)", "manual"] # ! summary model instead? - - ["java.util", "Comparator", "comparing", "(Function)", "manual"] # ! seems complex (functional interface), should maybe not have any model? + - ["java.util", "Collections", "sort", "", "manual"] - ["java.util", "Enumeration", "hasMoreElements", "()", "manual"] - ["java.util", "HashMap", "containsKey", "(Object)", "manual"] - ["java.util", "HashMap", "HashMap", "(int)", "manual"] - ["java.util", "HashMap", "size", "()", "manual"] - ["java.util", "HashSet", "HashSet", "(int)", "manual"] - ["java.util", "Iterator", "hasNext", "()", "manual"] - - ["java.util", "Iterator", "remove", "()", "manual"] # ! WithoutElement comment? (double-check if it returns anything, etc.) - ["java.util", "List", "contains", "(Object)", "manual"] - ["java.util", "List", "equals", "(Object)", "manual"] - ["java.util", "List", "hashCode", "()", "manual"] - ["java.util", "List", "indexOf", "(Object)", "manual"] - ["java.util", "List", "isEmpty", "()", "manual"] - ["java.util", "List", "of", "()", "manual"] - - ["java.util", "List", "sort", "(Comparator)", "manual"] # ! summary model instead? - - ["java.util", "List", "remove", "(Object)", "manual"] # ! WithoutElement comment? (actually, see above, is this already modeled for a different signature?) + - ["java.util", "List", "sort", "(Comparator)", "manual"] - ["java.util", "List", "size", "()", "manual"] + - ["java.util", "Locale", "forLanguageTag", "(String)", "manual"] - ["java.util", "Map", "containsKey", "(Object)", "manual"] - ["java.util", "Map", "isEmpty", "()", "manual"] - ["java.util", "Map", "size", "()", "manual"] @@ -412,10 +406,9 @@ extensions: - ["java.util", "Random", "nextInt", "(int)", "manual"] - ["java.util", "Set", "contains", "(Object)", "manual"] - ["java.util", "Set", "isEmpty", "()", "manual"] - - ["java.util", "Set", "remove", "(Object)", "manual"] # ! WithoutElement comment? (double-check if it returns anything, etc.) - - ["java.util", "Set", "removeAll", "(Collection)", "manual"] # ! WithoutElement comment? (double-check if it returns anything, etc.) - ["java.util", "Set", "size", "()", "manual"] - ["java.util", "UUID", "equals", "(Object)", "manual"] + - ["java.util", "UUID", "fromString", "(String)", "manual"] - ["java.util", "UUID", "randomUUID", "()", "manual"] - ["java.util", "UUID", "toString", "()", "manual"] - ["java.util", "TimeZone", "getTimeZone", "(String)", "manual"] @@ -423,9 +416,14 @@ extensions: # The below APIs are currently being stored as neutral models since `WithoutElement` has not yet been implemented for Java. # When `WithoutElement` is implemented, these should be changed to summary models of the form `Argument[this].WithoutElement -> Argument[this]`. + - ["java.util", "Collection", "removeIf", "(Predicate)", "manual"] + - ["java.util", "Iterator", "remove", "()", "manual"] - ["java.util", "List", "clear", "()", "manual"] + - ["java.util", "List", "remove", "(Object)", "manual"] - ["java.util", "Map", "clear", "()", "manual"] - ["java.util", "Set", "clear", "()", "manual"] + - ["java.util", "Set", "remove", "(Object)", "manual"] + - ["java.util", "Set", "removeAll", "(Collection)", "manual"] # The below APIs have numeric flow and are currently being stored as neutral models. # These may be changed to summary models with kinds "value-numeric" and "taint-numeric" (or similar) in the future. diff --git a/java/ql/lib/ext/java.util.stream.model.yml b/java/ql/lib/ext/java.util.stream.model.yml index f6a37dcd4ee..7ef65fd8a83 100644 --- a/java/ql/lib/ext/java.util.stream.model.yml +++ b/java/ql/lib/ext/java.util.stream.model.yml @@ -9,8 +9,7 @@ extensions: - ["java.util.stream", "BaseStream", True, "sequential", "()", "", "Argument[this].Element", "ReturnValue.Element", "value", "manual"] - ["java.util.stream", "BaseStream", True, "spliterator", "()", "", "Argument[this].Element", "ReturnValue.Element", "value", "manual"] - ["java.util.stream", "BaseStream", True, "unordered", "()", "", "Argument[this].Element", "ReturnValue.Element", "value", "manual"] - - ["java.util.stream", "IntStream", False, "range", "(int,int)", "", "Argument[0..1]", "ReturnValue.Element", "value", "manual"] # ! this one is a bit odd, is it correct to have it as a summary model?; not interesting because Int stream?=neutral? - - ["java.util.stream", "Stream", True, "allMatch", "(Predicate)", "", "Argument[this].Element", "Argument[0].Parameter[0]", "value", "manual"] # ! neutral instead? + - ["java.util.stream", "Stream", True, "allMatch", "(Predicate)", "", "Argument[this].Element", "Argument[0].Parameter[0]", "value", "manual"] - ["java.util.stream", "Stream", True, "anyMatch", "(Predicate)", "", "Argument[this].Element", "Argument[0].Parameter[0]", "value", "manual"] - ["java.util.stream", "Stream", True, "collect", "(Supplier,BiConsumer,BiConsumer)", "", "Argument[this].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"] @@ -95,5 +94,9 @@ extensions: data: - ["java.util.stream", "Collectors", "toList", "()", "manual"] - ["java.util.stream", "Collectors", "toSet", "()", "manual"] - - ["java.util.stream", "IntStream", "mapToObj", "(IntFunction)", "manual"] - ["java.util.stream", "Stream", "count", "()", "manual"] + + # The below APIs have numeric flow and are currently being stored as neutral models. + # These may be changed to summary models with kinds "value-numeric" and "taint-numeric" (or similar) in the future. + - ["java.util.stream", "IntStream", "mapToObj", "(IntFunction)", "manual"] # taint-numeric + - ["java.util.stream", "IntStream", "range", "(int,int)", "manual"] # taint-numeric diff --git a/java/ql/test/ext/TestModels/Test.java b/java/ql/test/ext/TestModels/Test.java index a64f4ec71c0..8b510971e5d 100644 --- a/java/ql/test/ext/TestModels/Test.java +++ b/java/ql/test/ext/TestModels/Test.java @@ -1,14 +1,24 @@ -import java.io.IOException; -import java.io.File; +import java.awt.*; +import java.io.*; import java.math.BigDecimal; +import java.net.URL; +import java.nio.file.Path; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; +import java.text.Format; +import java.text.MessageFormat; +import java.util.EventObject; +import java.util.Locale; +import java.util.ResourceBundle; import java.util.StringJoiner; +import java.util.concurrent.*; import java.util.concurrent.atomic.AtomicReference; import java.util.function.Function; import java.util.function.Supplier; +import java.util.logging.Logger; +import java.util.regex.Pattern; import java.util.stream.Collectors; public class Test { @@ -81,5 +91,115 @@ public class Test { StringJoiner sj2 = (StringJoiner)source(); sink(sj2.add("test")); // $hasTaintFlow } + + // top 300-500 JDK APIs tests + { + + // java.awt + Container container = new Container(); + sink(container.add((Component)source())); // $hasValueFlow + + // java.io + File f1 = (File)source(); + sink(f1.getParentFile()); // $hasTaintFlow + + File f2 = (File)source(); + sink(f2.getPath()); // $hasTaintFlow + + File f3 = (File)source(); + sink(f3.listFiles()); // $hasTaintFlow + + FileInputStream fis = new FileInputStream((File)source()); + sink(fis); // $hasTaintFlow + + StringWriter sw = (StringWriter)source(); + sink(sw.toString()); // $hasTaintFlow + + Exception e = new UncheckedIOException((IOException)source()); + sink((Throwable)e.getCause()); // $hasValueFlow + + // java.net + URL url = (URL)source(); + sink(url.toURI()); // $hasTaintFlow + + // java.nio.file + Path p = (Path)source(); + sink(p.getFileName()); // $hasTaintFlow + + // java.util.concurrent.atomic + AtomicReference ar = new AtomicReference(); + ar.set(source()); + sink(ar.get()); // $hasValueFlow + + // java.util.concurrent + // `ThreadPoolExecutor` implements the `java.util.concurrent.ExecutorService` interface + ThreadPoolExecutor tpe = new ThreadPoolExecutor(0, 0, 0, null, null); + sink(tpe.submit((Runnable)source())); // $hasTaintFlow + + CompletionStage cs = (CompletionStage)source(); + sink(cs.toCompletableFuture()); // $hasTaintFlow + + CompletableFuture cf1 = new CompletableFuture(); + cf1.complete(source()); + sink(cf1.get()); // $hasValueFlow + sink(cf1.join()); // $hasValueFlow + + CompletableFuture cf2 = CompletableFuture.completedFuture(source()); + sink(cf2.get()); // $hasValueFlow + sink(cf2.join()); // $hasValueFlow + + // java.util.logging + Logger logger = Logger.getLogger((String)source()); + sink(logger.getName()); // $hasValueFlow + + // java.util.regex + Pattern pattern = Pattern.compile((String)source()); + sink(pattern); // $hasTaintFlow + + // java.util + EventObject eventObj = new EventObject(source()); + sink(eventObj.getSource()); // $hasValueFlow + + // java.text + Format mf1 = new MessageFormat("test"); + sink(mf1.format(source())); // $hasTaintFlow + + String mf2 = MessageFormat.format((String)source(), null); + sink(mf2); // $hasTaintFlow + + String mf3 = MessageFormat.format("test", source()); + sink(mf3); // $hasTaintFlow + + // java.lang + AssertionError assertErr = new AssertionError(source()); + sink((String)assertErr.getMessage()); // $hasValueFlow + + sink(Test.class.cast(source())); // $hasTaintFlow + + Exception excep1 = new Exception((String)source(), (Throwable)source()); + sink((String)excep1.getMessage()); // $hasValueFlow + sink((Throwable)excep1.getCause()); // $hasValueFlow + + Exception excep2 = new NullPointerException((String)source()); + sink((String)excep2.getMessage()); // $hasValueFlow + + StringBuilder sb = (StringBuilder)source(); + sink(sb.delete(0, 1)); // $hasTaintFlow + + Thread thread1 = new Thread((Runnable)source()); + sink(thread1); // $hasTaintFlow + + Thread thread2 = new Thread((String)source()); + sink(thread2.getName()); // $hasValueFlow + + ThreadLocal threadloc = new ThreadLocal(); + threadloc.set(source()); + sink(threadloc.get()); // $hasValueFlow + + Throwable th = new Throwable((String)source()); + sink((String)th.getLocalizedMessage()); // $hasValueFlow + sink(th.toString()); // $hasTaintFlow + } } + } diff --git a/java/ql/test/ext/TopJdkApis/TopJdkApis.qll b/java/ql/test/ext/TopJdkApis/TopJdkApis.qll index 2ec75f59c20..14fd65a75bd 100644 --- a/java/ql/test/ext/TopJdkApis/TopJdkApis.qll +++ b/java/ql/test/ext/TopJdkApis/TopJdkApis.qll @@ -273,7 +273,8 @@ predicate topJdkApiName(string apiName) { "java.lang.Number#intValue()", "java.io.File#length()", "java.lang.AbstractStringBuilder#setCharAt(int,char)", "java.util.Set#removeAll(Collection)", "java.io.File#listFiles()", "java.lang.ClassLoader#getResourceAsStream(String)", - "java.util.Date#toInstant()", "java.util.Queue#add(Object)", "java.io.File#isFile()" + "java.util.Date#toInstant()", "java.util.Queue#add(Object)", "java.io.File#isFile()", + "java.sql.Statement#close()", "java.io.DataOutput#writeBoolean(boolean)" ] } @@ -309,6 +310,9 @@ class TopJdkApi extends SummarizedCallableBase { * `java.lang.System#getProperty(String)`: needs to be modeled by regular CodeQL matching the get and set keys to reduce FPs * `java.lang.System#setProperty(String,String)`: needs to be modeled by regular CodeQL matching the get and set keys to reduce FPs * `java.lang.Throwable#printStackTrace()`: should probably not be a general step, but there might be specialised queries that care + * `java.util.Comparator#comparing(Function)`: lambda flow + * `java.util.function.BiConsumer#accept(Object,Object)`: specialized lambda flow + * `java.util.function.BiFunction#apply(Object,Object)`: specialized lambda flow * `java.util.function.Consumer#accept(Object)`: specialized lambda flow * `java.util.function.Function#apply(Object)`: specialized lambda flow * `java.util.function.Supplier#get()`: lambda flow diff --git a/java/ql/test/ext/TopJdkApis/TopJdkApisTest.expected b/java/ql/test/ext/TopJdkApis/TopJdkApisTest.expected index abf8d09a27f..45dbe5a2b4d 100644 --- a/java/ql/test/ext/TopJdkApis/TopJdkApisTest.expected +++ b/java/ql/test/ext/TopJdkApis/TopJdkApisTest.expected @@ -2,6 +2,9 @@ | java.lang.System#getProperty(String) | no manual model | | java.lang.System#setProperty(String,String) | no manual model | | java.lang.Throwable#printStackTrace() | no manual model | +| java.util.Comparator#comparing(Function) | no manual model | +| java.util.function.BiConsumer#accept(Object,Object) | no manual model | +| java.util.function.BiFunction#apply(Object,Object) | no manual model | | java.util.function.Consumer#accept(Object) | no manual model | | java.util.function.Function#apply(Object) | no manual model | | java.util.function.Supplier#get() | no manual model | From ab4ab7812d742f2ced1005fd448597dbd985996e Mon Sep 17 00:00:00 2001 From: Jami Cogswell <jcogs33@Jamis-MacBook-Pro.local> Date: Mon, 23 Jan 2023 15:51:33 -0500 Subject: [PATCH 389/631] Java: add change note --- java/ql/lib/change-notes/2023-01-23-add-top-jdk-models.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 java/ql/lib/change-notes/2023-01-23-add-top-jdk-models.md diff --git a/java/ql/lib/change-notes/2023-01-23-add-top-jdk-models.md b/java/ql/lib/change-notes/2023-01-23-add-top-jdk-models.md new file mode 100644 index 00000000000..a74fb161e58 --- /dev/null +++ b/java/ql/lib/change-notes/2023-01-23-add-top-jdk-models.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* Added more dataflow models for frequently-used JDK APIs. From bdd7f18e35043672efa45cbbe4e362d51e5ef902 Mon Sep 17 00:00:00 2001 From: Jami Cogswell <jcogs33@Jamis-MacBook-Pro.local> Date: Mon, 20 Mar 2023 14:34:07 -0400 Subject: [PATCH 390/631] Java: remove some comments --- java/ql/lib/ext/java.io.model.yml | 2 +- java/ql/lib/ext/java.lang.model.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/java/ql/lib/ext/java.io.model.yml b/java/ql/lib/ext/java.io.model.yml index eed26f37299..ea8e7331267 100644 --- a/java/ql/lib/ext/java.io.model.yml +++ b/java/ql/lib/ext/java.io.model.yml @@ -92,7 +92,7 @@ extensions: - ["java.io", "OutputStream", True, "write", "(int)", "", "Argument[0]", "Argument[this]", "taint", "manual"] - ["java.io", "Reader", True, "read", "", "", "Argument[this]", "Argument[0]", "taint", "manual"] - ["java.io", "StringReader", False, "StringReader", "", "", "Argument[0]", "Argument[this]", "taint", "manual"] - - ["java.io", "StringWriter", False, "toString", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] # ! keep an eye on this one for FP flow, already modeled in `taintPreservingQualifierToMethod` predicate? + - ["java.io", "StringWriter", False, "toString", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - ["java.io", "UncheckedIOException", False, "UncheckedIOException", "(IOException)", "", "Argument[0]", "Argument[-1].SyntheticField[java.lang.Throwable.cause]", "value", "manual"] - ["java.io", "Writer", True, "write", "", "", "Argument[0]", "Argument[this]", "taint", "manual"] - addsTo: diff --git a/java/ql/lib/ext/java.lang.model.yml b/java/ql/lib/ext/java.lang.model.yml index 7cfc9ce68bc..58846dfa8b3 100644 --- a/java/ql/lib/ext/java.lang.model.yml +++ b/java/ql/lib/ext/java.lang.model.yml @@ -123,7 +123,7 @@ extensions: - ["java.lang", "Throwable", True, "getCause", "()", "", "Argument[this].SyntheticField[java.lang.Throwable.cause]", "ReturnValue", "value", "manual"] - ["java.lang", "Throwable", True, "getMessage", "()", "", "Argument[this].SyntheticField[java.lang.Throwable.message]", "ReturnValue", "value", "manual"] - ["java.lang", "Throwable", True, "getLocalizedMessage", "()", "", "Argument[-1].SyntheticField[java.lang.Throwable.message]", "ReturnValue", "value", "manual"] - - ["java.lang", "Throwable", True, "toString", "()", "", "Argument[-1].SyntheticField[java.lang.Throwable.message]", "ReturnValue", "taint", "manual"] # ! watch for FPs + - ["java.lang", "Throwable", True, "toString", "()", "", "Argument[-1].SyntheticField[java.lang.Throwable.message]", "ReturnValue", "taint", "manual"] - addsTo: pack: codeql/java-all From 882237e13e79be62c86a84dd105797722a89bc3d Mon Sep 17 00:00:00 2001 From: Jami Cogswell <jcogs33@Jamis-MacBook-Pro.local> Date: Mon, 23 Jan 2023 21:33:07 -0500 Subject: [PATCH 391/631] Java: update test cases affected by Duration.ofMillis and AtomicReference.set models --- .../SupportedExternalApis/SupportedExternalApis.expected | 1 + .../SupportedExternalApis/SupportedExternalApis.java | 4 ++-- .../Telemetry/UnsupportedExternalAPIs/Test.java | 7 ++++--- .../UnsupportedExternalAPIs.expected | 3 +-- 4 files changed, 8 insertions(+), 7 deletions(-) diff --git a/java/ql/test/query-tests/Telemetry/SupportedExternalApis/SupportedExternalApis.expected b/java/ql/test/query-tests/Telemetry/SupportedExternalApis/SupportedExternalApis.expected index 8a20a6c6c7b..3f5b3663281 100644 --- a/java/ql/test/query-tests/Telemetry/SupportedExternalApis/SupportedExternalApis.expected +++ b/java/ql/test/query-tests/Telemetry/SupportedExternalApis/SupportedExternalApis.expected @@ -6,5 +6,6 @@ | java.net.URL#openConnection() | 1 | | java.net.URL#openStream() | 1 | | java.net.URLConnection#getInputStream() | 1 | +| java.time.Duration#ofMillis(long) | 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 7dd289acbaa..6445e97b473 100644 --- a/java/ql/test/query-tests/Telemetry/SupportedExternalApis/SupportedExternalApis.java +++ b/java/ql/test/query-tests/Telemetry/SupportedExternalApis/SupportedExternalApis.java @@ -16,7 +16,7 @@ class SupportedExternalApis { Map<String, Object> map = new HashMap<>(); // uninteresting (parameterless constructor) map.put("foo", new Object()); // supported summary - Duration d = java.time.Duration.ofMillis(1000); // not supported + Duration d = java.time.Duration.ofMillis(1000); // supported neutral URL github = new URL("https://www.github.com/"); // supported summary InputStream stream = github.openConnection().getInputStream(); // supported source (getInputStream), supported sink (openConnection) @@ -24,6 +24,6 @@ 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) + FileUtils.deleteDirectory(new File("foo")); // supported neutral (deleteDirectory), supported summary (File) } } diff --git a/java/ql/test/query-tests/Telemetry/UnsupportedExternalAPIs/Test.java b/java/ql/test/query-tests/Telemetry/UnsupportedExternalAPIs/Test.java index f0e3926c7e9..b398a791836 100644 --- a/java/ql/test/query-tests/Telemetry/UnsupportedExternalAPIs/Test.java +++ b/java/ql/test/query-tests/Telemetry/UnsupportedExternalAPIs/Test.java @@ -11,12 +11,13 @@ class ExternalApiUsage { Map<String, Object> map = new HashMap<>(); map.put("foo", new Object()); - Duration d = java.time.Duration.ofMillis(1000); // not supported + Duration d = java.time.Duration.ofMillis(1000); // supported as a neutral model long l = "foo".length(); // supported as a neutral model - AtomicReference<String> ref = new AtomicReference<>(); // not supported - ref.set("foo"); + AtomicReference<String> ref = new AtomicReference<>(); // uninteresting (parameterless constructor) + ref.set("foo"); // supported as a summary model + ref.toString(); // not supported String.class.isAssignableFrom(Object.class); // parameter with generic type, supported as a neutral model diff --git a/java/ql/test/query-tests/Telemetry/UnsupportedExternalAPIs/UnsupportedExternalAPIs.expected b/java/ql/test/query-tests/Telemetry/UnsupportedExternalAPIs/UnsupportedExternalAPIs.expected index 7bab3b2d75a..6419b137690 100644 --- a/java/ql/test/query-tests/Telemetry/UnsupportedExternalAPIs/UnsupportedExternalAPIs.expected +++ b/java/ql/test/query-tests/Telemetry/UnsupportedExternalAPIs/UnsupportedExternalAPIs.expected @@ -1,2 +1 @@ -| java.time.Duration#ofMillis(long) | 1 | -| java.util.concurrent.atomic.AtomicReference#set(Object) | 1 | +| java.util.concurrent.atomic.AtomicReference#toString() | 1 | From 79ce46a22115f467b693dafa9a76d99c568c2dc9 Mon Sep 17 00:00:00 2001 From: Jami Cogswell <jcogs33@Jamis-MacBook-Pro.local> Date: Mon, 20 Mar 2023 14:35:30 -0400 Subject: [PATCH 392/631] Java: remove FileInputStream summary model since causing issues in DCA --- java/ql/lib/ext/java.io.model.yml | 2 +- java/ql/test/ext/TestModels/Test.java | 3 --- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/java/ql/lib/ext/java.io.model.yml b/java/ql/lib/ext/java.io.model.yml index ea8e7331267..cc4855dcef8 100644 --- a/java/ql/lib/ext/java.io.model.yml +++ b/java/ql/lib/ext/java.io.model.yml @@ -75,7 +75,6 @@ extensions: - ["java.io", "File", True, "toPath", "", "", "Argument[this]", "ReturnValue", "taint", "manual"] - ["java.io", "File", True, "toString", "", "", "Argument[this]", "ReturnValue", "taint", "manual"] - ["java.io", "File", True, "toURI", "", "", "Argument[this]", "ReturnValue", "taint", "manual"] - - ["java.io", "FileInputStream", False, "FileInputStream", "(File)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] - ["java.io", "FilterOutputStream", True, "FilterOutputStream", "(OutputStream)", "", "Argument[0]", "Argument[this]", "taint", "manual"] - ["java.io", "InputStream", True, "read", "(byte[])", "", "Argument[this]", "Argument[0]", "taint", "manual"] - ["java.io", "InputStream", True, "read", "(byte[],int,int)", "", "Argument[this]", "Argument[0]", "taint", "manual"] @@ -107,6 +106,7 @@ extensions: - ["java.io", "File", "length", "()", "manual"] - ["java.io", "File", "isDirectory", "()", "manual"] - ["java.io", "File", "mkdirs", "()", "manual"] + - ["java.io", "FileInputStream", "FileInputStream", "(File)", "manual"] - ["java.io", "InputStream", "close", "()", "manual"] - ["java.io", "OutputStream", "flush", "()", "manual"] diff --git a/java/ql/test/ext/TestModels/Test.java b/java/ql/test/ext/TestModels/Test.java index 8b510971e5d..fe9c64666a0 100644 --- a/java/ql/test/ext/TestModels/Test.java +++ b/java/ql/test/ext/TestModels/Test.java @@ -109,9 +109,6 @@ public class Test { File f3 = (File)source(); sink(f3.listFiles()); // $hasTaintFlow - FileInputStream fis = new FileInputStream((File)source()); - sink(fis); // $hasTaintFlow - StringWriter sw = (StringWriter)source(); sink(sw.toString()); // $hasTaintFlow From 170d9e35bef14f1286bede9b3deadb70e9f826f9 Mon Sep 17 00:00:00 2001 From: Jami Cogswell <jcogs33@Jamis-MacBook-Pro.local> Date: Wed, 15 Feb 2023 17:58:20 -0500 Subject: [PATCH 393/631] Java: update change note date --- ...-23-add-top-jdk-models.md => 2023-02-15-add-top-jdk-models.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename java/ql/lib/change-notes/{2023-01-23-add-top-jdk-models.md => 2023-02-15-add-top-jdk-models.md} (100%) diff --git a/java/ql/lib/change-notes/2023-01-23-add-top-jdk-models.md b/java/ql/lib/change-notes/2023-02-15-add-top-jdk-models.md similarity index 100% rename from java/ql/lib/change-notes/2023-01-23-add-top-jdk-models.md rename to java/ql/lib/change-notes/2023-02-15-add-top-jdk-models.md From 56d14820e42008765a8e2a8c4afe2945b5b0d47b Mon Sep 17 00:00:00 2001 From: Jami Cogswell <jcogs33@Jamis-MacBook-Pro.local> Date: Mon, 20 Mar 2023 14:36:55 -0400 Subject: [PATCH 394/631] Java: change taint to value for Class.cast --- java/ql/lib/ext/java.lang.model.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/ql/lib/ext/java.lang.model.yml b/java/ql/lib/ext/java.lang.model.yml index 58846dfa8b3..be215b25c6e 100644 --- a/java/ql/lib/ext/java.lang.model.yml +++ b/java/ql/lib/ext/java.lang.model.yml @@ -52,7 +52,7 @@ extensions: - ["java.lang", "CharSequence", True, "charAt", "", "", "Argument[this]", "ReturnValue", "taint", "manual"] - ["java.lang", "CharSequence", True, "subSequence", "", "", "Argument[this]", "ReturnValue", "taint", "manual"] - ["java.lang", "CharSequence", True, "toString", "", "", "Argument[this]", "ReturnValue", "taint", "manual"] - - ["java.lang", "Class", False, "cast", "(Object)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["java.lang", "Class", False, "cast", "(Object)", "", "Argument[0]", "ReturnValue", "value", "manual"] - ["java.lang", "Exception", False, "Exception", "(String)", "", "Argument[0]", "Argument[this].SyntheticField[java.lang.Throwable.message]", "value", "manual"] - ["java.lang", "Exception", False, "Exception", "(String,Throwable)", "", "Argument[0]", "Argument[-1].SyntheticField[java.lang.Throwable.message]", "value", "manual"] - ["java.lang", "Exception", False, "Exception", "(String,Throwable)", "", "Argument[1]", "Argument[-1].SyntheticField[java.lang.Throwable.cause]", "value", "manual"] From db545e4981f7d198a196296d90bf249aaf6fb67f Mon Sep 17 00:00:00 2001 From: Jami Cogswell <jcogs33@Jamis-MacBook-Pro.local> Date: Mon, 20 Mar 2023 14:38:06 -0400 Subject: [PATCH 395/631] Java: switch StringBuilder.delete to AbstractStringBuilder.delete --- java/ql/lib/ext/java.lang.model.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/ql/lib/ext/java.lang.model.yml b/java/ql/lib/ext/java.lang.model.yml index be215b25c6e..52b4aa248aa 100644 --- a/java/ql/lib/ext/java.lang.model.yml +++ b/java/ql/lib/ext/java.lang.model.yml @@ -37,6 +37,7 @@ extensions: - ["java.lang", "AbstractStringBuilder", True, "AbstractStringBuilder", "(String)", "", "Argument[0]", "Argument[this]", "taint", "manual"] - ["java.lang", "AbstractStringBuilder", True, "append", "", "", "Argument[this]", "ReturnValue", "value", "manual"] - ["java.lang", "AbstractStringBuilder", True, "append", "", "", "Argument[0]", "Argument[this]", "taint", "manual"] + - ["java.lang", "AbstractStringBuilder", True, "delete", "(int,int)", "", "Argument[-1]", "ReturnValue", "value", "manual"] - ["java.lang", "AbstractStringBuilder", True, "getChars", "", "", "Argument[this]", "Argument[2]", "taint", "manual"] - ["java.lang", "AbstractStringBuilder", True, "insert", "", "", "Argument[this]", "ReturnValue", "value", "manual"] - ["java.lang", "AbstractStringBuilder", True, "insert", "", "", "Argument[1]", "Argument[this]", "taint", "manual"] @@ -111,7 +112,6 @@ extensions: - ["java.lang", "StringBuffer", True, "StringBuffer", "(CharSequence)", "", "Argument[0]", "Argument[this]", "taint", "manual"] - ["java.lang", "StringBuffer", True, "StringBuffer", "(String)", "", "Argument[0]", "Argument[this]", "taint", "manual"] - ["java.lang", "StringBuilder", True, "StringBuilder", "", "", "Argument[0]", "Argument[this]", "taint", "manual"] - - ["java.lang", "StringBuilder", False, "delete", "(int,int)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - ["java.lang", "System", False, "arraycopy", "", "", "Argument[0]", "Argument[2]", "taint", "manual"] - ["java.lang", "Thread", False, "Thread", "(Runnable)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] - ["java.lang", "Thread", False, "Thread", "(String)", "", "Argument[0]", "Argument[-1].SyntheticField[java.lang.Thread.name]", "value", "manual"] From a7da6c802998507c1520298fc148326fafe13dfd Mon Sep 17 00:00:00 2001 From: Jami Cogswell <jcogs33@Jamis-MacBook-Pro.local> Date: Tue, 14 Mar 2023 22:01:42 -0400 Subject: [PATCH 396/631] Java: update cast and delete tests --- java/ql/test/ext/TestModels/Test.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/java/ql/test/ext/TestModels/Test.java b/java/ql/test/ext/TestModels/Test.java index fe9c64666a0..6c33b9f2310 100644 --- a/java/ql/test/ext/TestModels/Test.java +++ b/java/ql/test/ext/TestModels/Test.java @@ -171,7 +171,7 @@ public class Test { AssertionError assertErr = new AssertionError(source()); sink((String)assertErr.getMessage()); // $hasValueFlow - sink(Test.class.cast(source())); // $hasTaintFlow + sink(Test.class.cast(source())); // $hasValueFlow Exception excep1 = new Exception((String)source(), (Throwable)source()); sink((String)excep1.getMessage()); // $hasValueFlow @@ -181,7 +181,7 @@ public class Test { sink((String)excep2.getMessage()); // $hasValueFlow StringBuilder sb = (StringBuilder)source(); - sink(sb.delete(0, 1)); // $hasTaintFlow + sink(sb.delete(0, 1)); // $hasValueFlow Thread thread1 = new Thread((Runnable)source()); sink(thread1); // $hasTaintFlow From 702ca19c3c93c7b3fc2cfbca6db9795f15e11928 Mon Sep 17 00:00:00 2001 From: Jami Cogswell <jcogs33@Jamis-MacBook-Pro.local> Date: Tue, 14 Mar 2023 22:20:19 -0400 Subject: [PATCH 397/631] Java: added comment about second order sql injection --- java/ql/lib/ext/java.sql.model.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/ql/lib/ext/java.sql.model.yml b/java/ql/lib/ext/java.sql.model.yml index f5b15706476..7c8174fca43 100644 --- a/java/ql/lib/ext/java.sql.model.yml +++ b/java/ql/lib/ext/java.sql.model.yml @@ -41,7 +41,7 @@ extensions: - ["java.sql", "ResultSet", "getInt", "(int)", "manual"] # taint-numeric - ["java.sql", "ResultSet", "getInt", "(String)", "manual"] # taint-numeric - ["java.sql", "ResultSet", "getLong", "(String)", "manual"] # taint-numeric - - ["java.sql", "ResultSet", "getString", "(int)", "manual"] # taint-numeric + - ["java.sql", "ResultSet", "getString", "(int)", "manual"] # taint-numeric, potentially interesting for second order SQL injection - ["java.sql", "ResultSet", "getTimestamp", "(String)", "manual"] # taint-numeric - ["java.sql", "Timestamp", "Timestamp", "(long)", "manual"] # taint-numeric - ["java.sql", "Timestamp", "getTime", "()", "manual"] # taint-numeric From e0c0c973a7e35cf7ad45c6cc2a77d9825b9c8d34 Mon Sep 17 00:00:00 2001 From: Jami Cogswell <jcogs33@Jamis-MacBook-Pro.local> Date: Tue, 14 Mar 2023 22:40:23 -0400 Subject: [PATCH 398/631] Java: remove Format and MessageFormat --- java/ql/lib/ext/java.text.model.yml | 8 -------- java/ql/test/ext/TestModels/Test.java | 12 ------------ java/ql/test/ext/TopJdkApis/TopJdkApis.qll | 2 ++ java/ql/test/ext/TopJdkApis/TopJdkApisTest.expected | 2 ++ 4 files changed, 4 insertions(+), 20 deletions(-) diff --git a/java/ql/lib/ext/java.text.model.yml b/java/ql/lib/ext/java.text.model.yml index e179f9f5d6f..86099195f46 100644 --- a/java/ql/lib/ext/java.text.model.yml +++ b/java/ql/lib/ext/java.text.model.yml @@ -1,12 +1,4 @@ extensions: - - addsTo: - pack: codeql/java-all - extensible: summaryModel - data: - - ["java.text", "Format", True, "format", "(Object)", "", "Argument[0]", "ReturnValue", "taint", "manual"] - - ["java.text", "MessageFormat", False, "format", "(String,Object[])", "", "Argument[0]", "ReturnValue", "taint", "manual"] - - ["java.text", "MessageFormat", False, "format", "(String,Object[])", "", "Argument[1].ArrayElement", "ReturnValue", "taint", "manual"] - - addsTo: pack: codeql/java-all extensible: neutralModel diff --git a/java/ql/test/ext/TestModels/Test.java b/java/ql/test/ext/TestModels/Test.java index 6c33b9f2310..305ef30d797 100644 --- a/java/ql/test/ext/TestModels/Test.java +++ b/java/ql/test/ext/TestModels/Test.java @@ -7,8 +7,6 @@ import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; -import java.text.Format; -import java.text.MessageFormat; import java.util.EventObject; import java.util.Locale; import java.util.ResourceBundle; @@ -157,16 +155,6 @@ public class Test { EventObject eventObj = new EventObject(source()); sink(eventObj.getSource()); // $hasValueFlow - // java.text - Format mf1 = new MessageFormat("test"); - sink(mf1.format(source())); // $hasTaintFlow - - String mf2 = MessageFormat.format((String)source(), null); - sink(mf2); // $hasTaintFlow - - String mf3 = MessageFormat.format("test", source()); - sink(mf3); // $hasTaintFlow - // java.lang AssertionError assertErr = new AssertionError(source()); sink((String)assertErr.getMessage()); // $hasValueFlow diff --git a/java/ql/test/ext/TopJdkApis/TopJdkApis.qll b/java/ql/test/ext/TopJdkApis/TopJdkApis.qll index 14fd65a75bd..b0a8902b12b 100644 --- a/java/ql/test/ext/TopJdkApis/TopJdkApis.qll +++ b/java/ql/test/ext/TopJdkApis/TopJdkApis.qll @@ -310,6 +310,8 @@ class TopJdkApi extends SummarizedCallableBase { * `java.lang.System#getProperty(String)`: needs to be modeled by regular CodeQL matching the get and set keys to reduce FPs * `java.lang.System#setProperty(String,String)`: needs to be modeled by regular CodeQL matching the get and set keys to reduce FPs * `java.lang.Throwable#printStackTrace()`: should probably not be a general step, but there might be specialised queries that care + * `java.text.Format#format(Object)`: similar issue as `Object.toString`; depends on the object being passed as the argument + * `java.text.MessageFormat#format(String,Object[])`: similar issue as `Object.toString`; depends on the object being passed as the argument * `java.util.Comparator#comparing(Function)`: lambda flow * `java.util.function.BiConsumer#accept(Object,Object)`: specialized lambda flow * `java.util.function.BiFunction#apply(Object,Object)`: specialized lambda flow diff --git a/java/ql/test/ext/TopJdkApis/TopJdkApisTest.expected b/java/ql/test/ext/TopJdkApis/TopJdkApisTest.expected index 45dbe5a2b4d..2e0ace91209 100644 --- a/java/ql/test/ext/TopJdkApis/TopJdkApisTest.expected +++ b/java/ql/test/ext/TopJdkApis/TopJdkApisTest.expected @@ -2,6 +2,8 @@ | java.lang.System#getProperty(String) | no manual model | | java.lang.System#setProperty(String,String) | no manual model | | java.lang.Throwable#printStackTrace() | no manual model | +| java.text.Format#format(Object) | no manual model | +| java.text.MessageFormat#format(String,Object[]) | no manual model | | java.util.Comparator#comparing(Function) | no manual model | | java.util.function.BiConsumer#accept(Object,Object) | no manual model | | java.util.function.BiFunction#apply(Object,Object) | no manual model | From 62d64d5828f4eafffe4a34c1f8da431343fca65f Mon Sep 17 00:00:00 2001 From: Jami Cogswell <jcogs33@Jamis-MacBook-Pro.local> Date: Tue, 14 Mar 2023 23:02:22 -0400 Subject: [PATCH 399/631] Java: add comments for reflection-related models --- java/ql/lib/ext/java.lang.model.yml | 6 +++--- java/ql/lib/ext/java.lang.reflect.model.yml | 1 + 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/java/ql/lib/ext/java.lang.model.yml b/java/ql/lib/ext/java.lang.model.yml index 52b4aa248aa..f22abab705f 100644 --- a/java/ql/lib/ext/java.lang.model.yml +++ b/java/ql/lib/ext/java.lang.model.yml @@ -140,9 +140,9 @@ extensions: - ["java.lang", "Class", "forName", "(String)", "manual"] - ["java.lang", "Class", "getCanonicalName", "()", "manual"] - ["java.lang", "Class", "getClassLoader", "()", "manual"] - - ["java.lang", "Class", "getDeclaredConstructor", "(Class[])", "manual"] - - ["java.lang", "Class", "getDeclaredField", "(String)", "manual"] - - ["java.lang", "Class", "getMethod", "(String,Class[])", "manual"] + - ["java.lang", "Class", "getDeclaredConstructor", "(Class[])", "manual"] # This model may be changed to a taint step for an unsafe reflection query in the future. + - ["java.lang", "Class", "getDeclaredField", "(String)", "manual"] # This model may be changed to a taint step for an unsafe reflection query in the future. + - ["java.lang", "Class", "getMethod", "(String,Class[])", "manual"] # This model may be changed to a taint step for an unsafe reflection query in the future. - ["java.lang", "Class", "getName", "()", "manual"] - ["java.lang", "Class", "getResource", "(String)", "manual"] - ["java.lang", "Class", "getResourceAsStream", "(String)", "manual"] diff --git a/java/ql/lib/ext/java.lang.reflect.model.yml b/java/ql/lib/ext/java.lang.reflect.model.yml index a709a0fc8b6..9430807d00b 100644 --- a/java/ql/lib/ext/java.lang.reflect.model.yml +++ b/java/ql/lib/ext/java.lang.reflect.model.yml @@ -3,6 +3,7 @@ extensions: pack: codeql/java-all extensible: neutralModel data: + # The below models may be changed to taint steps for an unsafe reflection query in the future. - ["java.lang.reflect", "Constructor", "newInstance", "(Object[])", "manual"] - ["java.lang.reflect", "Field", "get", "(Object)", "manual"] - ["java.lang.reflect", "Method", "getName", "()", "manual"] From 29999d7bc8972eb03a086f4073264162495bb6a6 Mon Sep 17 00:00:00 2001 From: Jami Cogswell <jcogs33@Jamis-MacBook-Pro.local> Date: Mon, 20 Mar 2023 14:39:11 -0400 Subject: [PATCH 400/631] Java: add WithoutElement comment --- java/ql/lib/ext/java.lang.model.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/java/ql/lib/ext/java.lang.model.yml b/java/ql/lib/ext/java.lang.model.yml index f22abab705f..d5e263f6f0b 100644 --- a/java/ql/lib/ext/java.lang.model.yml +++ b/java/ql/lib/ext/java.lang.model.yml @@ -37,6 +37,7 @@ extensions: - ["java.lang", "AbstractStringBuilder", True, "AbstractStringBuilder", "(String)", "", "Argument[0]", "Argument[this]", "taint", "manual"] - ["java.lang", "AbstractStringBuilder", True, "append", "", "", "Argument[this]", "ReturnValue", "value", "manual"] - ["java.lang", "AbstractStringBuilder", True, "append", "", "", "Argument[0]", "Argument[this]", "taint", "manual"] + # When `WithoutElement` is implemented for Java, `java.lang.AbstractStringBuilder#delete` might require a `taint` step of the form `Argument[-1].WithoutElement -> Argument[-1]` in addition to the below `value` step. - ["java.lang", "AbstractStringBuilder", True, "delete", "(int,int)", "", "Argument[-1]", "ReturnValue", "value", "manual"] - ["java.lang", "AbstractStringBuilder", True, "getChars", "", "", "Argument[this]", "Argument[2]", "taint", "manual"] - ["java.lang", "AbstractStringBuilder", True, "insert", "", "", "Argument[this]", "ReturnValue", "value", "manual"] From 0f3a0a1e81fdd7669aff53f42f355aa5674df03c Mon Sep 17 00:00:00 2001 From: Jami Cogswell <jcogs33@Jamis-MacBook-Pro.local> Date: Mon, 20 Mar 2023 14:40:12 -0400 Subject: [PATCH 401/631] Java: remove ArrayElement from listFiles --- java/ql/lib/ext/java.io.model.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/ql/lib/ext/java.io.model.yml b/java/ql/lib/ext/java.io.model.yml index cc4855dcef8..b11e732a6d7 100644 --- a/java/ql/lib/ext/java.io.model.yml +++ b/java/ql/lib/ext/java.io.model.yml @@ -71,7 +71,7 @@ extensions: - ["java.io", "File", True, "getName", "()", "", "Argument[this]", "ReturnValue", "taint", "manual"] - ["java.io", "File", True, "getParentFile", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - ["java.io", "File", True, "getPath", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["java.io", "File", True, "listFiles", "()", "", "Argument[-1]", "ReturnValue.ArrayElement", "taint", "manual"] + - ["java.io", "File", True, "listFiles", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - ["java.io", "File", True, "toPath", "", "", "Argument[this]", "ReturnValue", "taint", "manual"] - ["java.io", "File", True, "toString", "", "", "Argument[this]", "ReturnValue", "taint", "manual"] - ["java.io", "File", True, "toURI", "", "", "Argument[this]", "ReturnValue", "taint", "manual"] From 3d0d4111c0bdde11f746b225baff6cd9382f5a7a Mon Sep 17 00:00:00 2001 From: Jami Cogswell <jcogs33@Jamis-MacBook-Pro.local> Date: Mon, 20 Mar 2023 11:10:52 -0400 Subject: [PATCH 402/631] Java: add test for ResourceBundle.getString --- java/ql/test/ext/TestModels/Test.java | 12 ++++++++++-- java/ql/test/ext/TestModels/test.ext.yml | 6 ++++++ 2 files changed, 16 insertions(+), 2 deletions(-) create mode 100644 java/ql/test/ext/TestModels/test.ext.yml diff --git a/java/ql/test/ext/TestModels/Test.java b/java/ql/test/ext/TestModels/Test.java index 305ef30d797..0f52da636e6 100644 --- a/java/ql/test/ext/TestModels/Test.java +++ b/java/ql/test/ext/TestModels/Test.java @@ -1,3 +1,5 @@ +package generatedtest; // for java.util.ResourceBundle.getString test + import java.awt.*; import java.io.*; import java.math.BigDecimal; @@ -8,7 +10,6 @@ import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.util.EventObject; -import java.util.Locale; import java.util.ResourceBundle; import java.util.StringJoiner; import java.util.concurrent.*; @@ -25,6 +26,8 @@ public class Test { Object source() { return null; } + Object newWithMapValueDefault(Object element) { return null; } // for java.util.ResourceBundle.getString test + public void test() throws Exception { // top 100 JDK APIs tests @@ -155,6 +158,12 @@ public class Test { EventObject eventObj = new EventObject(source()); sink(eventObj.getSource()); // $hasValueFlow + // "java.util;ResourceBundle;true;getString;(String);;Argument[-1].MapValue;ReturnValue;value;manual" + String out = null; + ResourceBundle in = (ResourceBundle)newWithMapValueDefault(source()); + out = in.getString(null); + sink(out); // $ hasValueFlow + // java.lang AssertionError assertErr = new AssertionError(source()); sink((String)assertErr.getMessage()); // $hasValueFlow @@ -186,5 +195,4 @@ public class Test { sink(th.toString()); // $hasTaintFlow } } - } diff --git a/java/ql/test/ext/TestModels/test.ext.yml b/java/ql/test/ext/TestModels/test.ext.yml new file mode 100644 index 00000000000..4fff7d575a3 --- /dev/null +++ b/java/ql/test/ext/TestModels/test.ext.yml @@ -0,0 +1,6 @@ +extensions: + - addsTo: + pack: codeql/java-tests + extensible: summaryModel + data: + - ["generatedtest", "Test", False, "newWithMapValueDefault", "(Object)", "", "Argument[0]", "ReturnValue.MapValue", "value", "manual"] From 8046ec2f78aaec76d55515ebbeed6d27f26341e1 Mon Sep 17 00:00:00 2001 From: Jami Cogswell <jcogs33@Jamis-MacBook-Pro.local> Date: Thu, 23 Mar 2023 18:01:28 -0400 Subject: [PATCH 403/631] Java: update -1 to this --- java/ql/lib/ext/java.awt.model.yml | 4 +-- java/ql/lib/ext/java.io.model.yml | 10 +++---- java/ql/lib/ext/java.lang.model.yml | 28 +++++++++---------- java/ql/lib/ext/java.nio.file.model.yml | 2 +- .../ext/java.util.concurrent.atomic.model.yml | 2 +- .../ql/lib/ext/java.util.concurrent.model.yml | 8 +++--- java/ql/lib/ext/java.util.logging.model.yml | 2 +- java/ql/lib/ext/java.util.model.yml | 6 ++-- 8 files changed, 31 insertions(+), 31 deletions(-) diff --git a/java/ql/lib/ext/java.awt.model.yml b/java/ql/lib/ext/java.awt.model.yml index 40b8b196e8f..4bbbc3738cf 100644 --- a/java/ql/lib/ext/java.awt.model.yml +++ b/java/ql/lib/ext/java.awt.model.yml @@ -3,9 +3,9 @@ extensions: pack: codeql/java-all extensible: summaryModel data: - - ["java.awt", "Container", True, "add", "(Component)", "", "Argument[0]", "Argument[-1].Element", "value", "manual"] + - ["java.awt", "Container", True, "add", "(Component)", "", "Argument[0]", "Argument[this].Element", "value", "manual"] - ["java.awt", "Container", True, "add", "(Component)", "", "Argument[0]", "ReturnValue", "value", "manual"] - - ["java.awt", "Container", True, "add", "(Component,Object)", "", "Argument[0]", "Argument[-1].Element", "value", "manual"] + - ["java.awt", "Container", True, "add", "(Component,Object)", "", "Argument[0]", "Argument[this].Element", "value", "manual"] - addsTo: pack: codeql/java-all diff --git a/java/ql/lib/ext/java.io.model.yml b/java/ql/lib/ext/java.io.model.yml index b11e732a6d7..a14f4fe7782 100644 --- a/java/ql/lib/ext/java.io.model.yml +++ b/java/ql/lib/ext/java.io.model.yml @@ -69,9 +69,9 @@ extensions: - ["java.io", "File", True, "getCanonicalFile", "", "", "Argument[this]", "ReturnValue", "taint", "manual"] - ["java.io", "File", True, "getCanonicalPath", "", "", "Argument[this]", "ReturnValue", "taint", "manual"] - ["java.io", "File", True, "getName", "()", "", "Argument[this]", "ReturnValue", "taint", "manual"] - - ["java.io", "File", True, "getParentFile", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["java.io", "File", True, "getPath", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["java.io", "File", True, "listFiles", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["java.io", "File", True, "getParentFile", "()", "", "Argument[this]", "ReturnValue", "taint", "manual"] + - ["java.io", "File", True, "getPath", "()", "", "Argument[this]", "ReturnValue", "taint", "manual"] + - ["java.io", "File", True, "listFiles", "()", "", "Argument[this]", "ReturnValue", "taint", "manual"] - ["java.io", "File", True, "toPath", "", "", "Argument[this]", "ReturnValue", "taint", "manual"] - ["java.io", "File", True, "toString", "", "", "Argument[this]", "ReturnValue", "taint", "manual"] - ["java.io", "File", True, "toURI", "", "", "Argument[this]", "ReturnValue", "taint", "manual"] @@ -91,8 +91,8 @@ extensions: - ["java.io", "OutputStream", True, "write", "(int)", "", "Argument[0]", "Argument[this]", "taint", "manual"] - ["java.io", "Reader", True, "read", "", "", "Argument[this]", "Argument[0]", "taint", "manual"] - ["java.io", "StringReader", False, "StringReader", "", "", "Argument[0]", "Argument[this]", "taint", "manual"] - - ["java.io", "StringWriter", False, "toString", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["java.io", "UncheckedIOException", False, "UncheckedIOException", "(IOException)", "", "Argument[0]", "Argument[-1].SyntheticField[java.lang.Throwable.cause]", "value", "manual"] + - ["java.io", "StringWriter", False, "toString", "()", "", "Argument[this]", "ReturnValue", "taint", "manual"] + - ["java.io", "UncheckedIOException", False, "UncheckedIOException", "(IOException)", "", "Argument[0]", "Argument[this].SyntheticField[java.lang.Throwable.cause]", "value", "manual"] - ["java.io", "Writer", True, "write", "", "", "Argument[0]", "Argument[this]", "taint", "manual"] - addsTo: pack: codeql/java-all diff --git a/java/ql/lib/ext/java.lang.model.yml b/java/ql/lib/ext/java.lang.model.yml index d5e263f6f0b..f1b84ae70b6 100644 --- a/java/ql/lib/ext/java.lang.model.yml +++ b/java/ql/lib/ext/java.lang.model.yml @@ -37,8 +37,8 @@ extensions: - ["java.lang", "AbstractStringBuilder", True, "AbstractStringBuilder", "(String)", "", "Argument[0]", "Argument[this]", "taint", "manual"] - ["java.lang", "AbstractStringBuilder", True, "append", "", "", "Argument[this]", "ReturnValue", "value", "manual"] - ["java.lang", "AbstractStringBuilder", True, "append", "", "", "Argument[0]", "Argument[this]", "taint", "manual"] - # When `WithoutElement` is implemented for Java, `java.lang.AbstractStringBuilder#delete` might require a `taint` step of the form `Argument[-1].WithoutElement -> Argument[-1]` in addition to the below `value` step. - - ["java.lang", "AbstractStringBuilder", True, "delete", "(int,int)", "", "Argument[-1]", "ReturnValue", "value", "manual"] + # When `WithoutElement` is implemented for Java, `java.lang.AbstractStringBuilder#delete` might require a `taint` step of the form `Argument[this].WithoutElement -> Argument[this]` in addition to the below `value` step. + - ["java.lang", "AbstractStringBuilder", True, "delete", "(int,int)", "", "Argument[this]", "ReturnValue", "value", "manual"] - ["java.lang", "AbstractStringBuilder", True, "getChars", "", "", "Argument[this]", "Argument[2]", "taint", "manual"] - ["java.lang", "AbstractStringBuilder", True, "insert", "", "", "Argument[this]", "ReturnValue", "value", "manual"] - ["java.lang", "AbstractStringBuilder", True, "insert", "", "", "Argument[1]", "Argument[this]", "taint", "manual"] @@ -50,21 +50,21 @@ extensions: - ["java.lang", "AbstractStringBuilder", True, "toString", "", "", "Argument[this]", "ReturnValue", "taint", "manual"] - ["java.lang", "Appendable", True, "append", "", "", "Argument[this]", "ReturnValue", "value", "manual"] - ["java.lang", "Appendable", True, "append", "", "", "Argument[0]", "Argument[this]", "taint", "manual"] - - ["java.lang", "AssertionError", False, "AssertionError", "(Object)", "", "Argument[0]", "Argument[-1].SyntheticField[java.lang.Throwable.message]", "value", "manual"] + - ["java.lang", "AssertionError", False, "AssertionError", "(Object)", "", "Argument[0]", "Argument[this].SyntheticField[java.lang.Throwable.message]", "value", "manual"] - ["java.lang", "CharSequence", True, "charAt", "", "", "Argument[this]", "ReturnValue", "taint", "manual"] - ["java.lang", "CharSequence", True, "subSequence", "", "", "Argument[this]", "ReturnValue", "taint", "manual"] - ["java.lang", "CharSequence", True, "toString", "", "", "Argument[this]", "ReturnValue", "taint", "manual"] - ["java.lang", "Class", False, "cast", "(Object)", "", "Argument[0]", "ReturnValue", "value", "manual"] - ["java.lang", "Exception", False, "Exception", "(String)", "", "Argument[0]", "Argument[this].SyntheticField[java.lang.Throwable.message]", "value", "manual"] - - ["java.lang", "Exception", False, "Exception", "(String,Throwable)", "", "Argument[0]", "Argument[-1].SyntheticField[java.lang.Throwable.message]", "value", "manual"] - - ["java.lang", "Exception", False, "Exception", "(String,Throwable)", "", "Argument[1]", "Argument[-1].SyntheticField[java.lang.Throwable.cause]", "value", "manual"] + - ["java.lang", "Exception", False, "Exception", "(String,Throwable)", "", "Argument[0]", "Argument[this].SyntheticField[java.lang.Throwable.message]", "value", "manual"] + - ["java.lang", "Exception", False, "Exception", "(String,Throwable)", "", "Argument[1]", "Argument[this].SyntheticField[java.lang.Throwable.cause]", "value", "manual"] - ["java.lang", "IllegalArgumentException", False, "IllegalArgumentException", "(String)", "", "Argument[0]", "Argument[this].SyntheticField[java.lang.Throwable.message]", "value", "manual"] - ["java.lang", "IllegalStateException", False, "IllegalStateException", "(String)", "", "Argument[0]", "Argument[this].SyntheticField[java.lang.Throwable.message]", "value", "manual"] - ["java.lang", "IndexOutOfBoundsException", False, "IndexOutOfBoundsException", "(String)", "", "Argument[0]", "Argument[this].SyntheticField[java.lang.Throwable.message]", "value", "manual"] - ["java.lang", "Iterable", True, "forEach", "(Consumer)", "", "Argument[this].Element", "Argument[0].Parameter[0]", "value", "manual"] - ["java.lang", "Iterable", True, "iterator", "()", "", "Argument[this].Element", "ReturnValue.Element", "value", "manual"] - ["java.lang", "Iterable", True, "spliterator", "()", "", "Argument[this].Element", "ReturnValue.Element", "value", "manual"] - - ["java.lang", "NullPointerException", False, "NullPointerException", "(String)", "", "Argument[0]", "Argument[-1].SyntheticField[java.lang.Throwable.message]", "value", "manual"] + - ["java.lang", "NullPointerException", False, "NullPointerException", "(String)", "", "Argument[0]", "Argument[this].SyntheticField[java.lang.Throwable.message]", "value", "manual"] - ["java.lang", "Object", True, "clone", "", "", "Argument[this].Element", "ReturnValue.Element", "value", "manual"] - ["java.lang", "Object", True, "clone", "", "", "Argument[this].MapKey", "ReturnValue.MapKey", "value", "manual"] - ["java.lang", "Object", True, "clone", "", "", "Argument[this].MapValue", "ReturnValue.MapValue", "value", "manual"] @@ -114,17 +114,17 @@ extensions: - ["java.lang", "StringBuffer", True, "StringBuffer", "(String)", "", "Argument[0]", "Argument[this]", "taint", "manual"] - ["java.lang", "StringBuilder", True, "StringBuilder", "", "", "Argument[0]", "Argument[this]", "taint", "manual"] - ["java.lang", "System", False, "arraycopy", "", "", "Argument[0]", "Argument[2]", "taint", "manual"] - - ["java.lang", "Thread", False, "Thread", "(Runnable)", "", "Argument[0]", "Argument[-1]", "taint", "manual"] - - ["java.lang", "Thread", False, "Thread", "(String)", "", "Argument[0]", "Argument[-1].SyntheticField[java.lang.Thread.name]", "value", "manual"] - - ["java.lang", "Thread", True, "getName", "()", "", "Argument[-1].SyntheticField[java.lang.Thread.name]", "ReturnValue", "value", "manual"] - - ["java.lang", "ThreadLocal", True, "get", "()", "", "Argument[-1].SyntheticField[java.lang.ThreadLocal.value]", "ReturnValue", "value", "manual"] - - ["java.lang", "ThreadLocal", True, "set", "(Object)", "", "Argument[0]", "Argument[-1].SyntheticField[java.lang.ThreadLocal.value]", "value", "manual"] + - ["java.lang", "Thread", False, "Thread", "(Runnable)", "", "Argument[0]", "Argument[this]", "taint", "manual"] + - ["java.lang", "Thread", False, "Thread", "(String)", "", "Argument[0]", "Argument[this].SyntheticField[java.lang.Thread.name]", "value", "manual"] + - ["java.lang", "Thread", True, "getName", "()", "", "Argument[this].SyntheticField[java.lang.Thread.name]", "ReturnValue", "value", "manual"] + - ["java.lang", "ThreadLocal", True, "get", "()", "", "Argument[this].SyntheticField[java.lang.ThreadLocal.value]", "ReturnValue", "value", "manual"] + - ["java.lang", "ThreadLocal", True, "set", "(Object)", "", "Argument[0]", "Argument[this].SyntheticField[java.lang.ThreadLocal.value]", "value", "manual"] - ["java.lang", "Throwable", False, "Throwable", "(Throwable)", "", "Argument[0]", "Argument[this].SyntheticField[java.lang.Throwable.cause]", "value", "manual"] - - ["java.lang", "Throwable", False, "Throwable", "(String)", "", "Argument[0]", "Argument[-1].SyntheticField[java.lang.Throwable.message]", "value", "manual"] + - ["java.lang", "Throwable", False, "Throwable", "(String)", "", "Argument[0]", "Argument[this].SyntheticField[java.lang.Throwable.message]", "value", "manual"] - ["java.lang", "Throwable", True, "getCause", "()", "", "Argument[this].SyntheticField[java.lang.Throwable.cause]", "ReturnValue", "value", "manual"] - ["java.lang", "Throwable", True, "getMessage", "()", "", "Argument[this].SyntheticField[java.lang.Throwable.message]", "ReturnValue", "value", "manual"] - - ["java.lang", "Throwable", True, "getLocalizedMessage", "()", "", "Argument[-1].SyntheticField[java.lang.Throwable.message]", "ReturnValue", "value", "manual"] - - ["java.lang", "Throwable", True, "toString", "()", "", "Argument[-1].SyntheticField[java.lang.Throwable.message]", "ReturnValue", "taint", "manual"] + - ["java.lang", "Throwable", True, "getLocalizedMessage", "()", "", "Argument[this].SyntheticField[java.lang.Throwable.message]", "ReturnValue", "value", "manual"] + - ["java.lang", "Throwable", True, "toString", "()", "", "Argument[this].SyntheticField[java.lang.Throwable.message]", "ReturnValue", "taint", "manual"] - addsTo: pack: codeql/java-all diff --git a/java/ql/lib/ext/java.nio.file.model.yml b/java/ql/lib/ext/java.nio.file.model.yml index ce955985e28..2991c20a6b3 100644 --- a/java/ql/lib/ext/java.nio.file.model.yml +++ b/java/ql/lib/ext/java.nio.file.model.yml @@ -45,7 +45,7 @@ extensions: - ["java.nio.file", "FileSystem", True, "getRootDirectories", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] - ["java.nio.file", "Path", True, "getParent", "", "", "Argument[this]", "ReturnValue", "taint", "manual"] - ["java.nio.file", "Path", True, "normalize", "", "", "Argument[this]", "ReturnValue", "taint", "manual"] - - ["java.nio.file", "Path", True, "getFileName", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["java.nio.file", "Path", True, "getFileName", "", "", "Argument[this]", "ReturnValue", "taint", "manual"] - ["java.nio.file", "Path", True, "of", "(String,String[])", "", "Argument[0]", "ReturnValue", "taint", "ai-generated"] - ["java.nio.file", "Path", True, "of", "(String,String[])", "", "Argument[1]", "ReturnValue", "taint", "ai-generated"] - ["java.nio.file", "Path", True, "of", "(URI)", "", "Argument[0]", "ReturnValue", "taint", "ai-generated"] diff --git a/java/ql/lib/ext/java.util.concurrent.atomic.model.yml b/java/ql/lib/ext/java.util.concurrent.atomic.model.yml index fcfa403d5e5..b92ed441ade 100644 --- a/java/ql/lib/ext/java.util.concurrent.atomic.model.yml +++ b/java/ql/lib/ext/java.util.concurrent.atomic.model.yml @@ -5,7 +5,7 @@ extensions: data: - ["java.util.concurrent.atomic", "AtomicReference", False, "AtomicReference", "(Object)", "", "Argument[0]", "Argument[this].SyntheticField[java.util.concurrent.atomic.AtomicReference.value]", "value", "manual"] - ["java.util.concurrent.atomic", "AtomicReference", False, "get", "()", "", "Argument[this].SyntheticField[java.util.concurrent.atomic.AtomicReference.value]", "ReturnValue", "value", "manual"] - - ["java.util.concurrent.atomic", "AtomicReference", False, "set", "(Object)", "", "Argument[0]", "Argument[-1].SyntheticField[java.util.concurrent.atomic.AtomicReference.value]", "value", "manual"] + - ["java.util.concurrent.atomic", "AtomicReference", False, "set", "(Object)", "", "Argument[0]", "Argument[this].SyntheticField[java.util.concurrent.atomic.AtomicReference.value]", "value", "manual"] - addsTo: pack: codeql/java-all diff --git a/java/ql/lib/ext/java.util.concurrent.model.yml b/java/ql/lib/ext/java.util.concurrent.model.yml index b050467260e..723035f408e 100644 --- a/java/ql/lib/ext/java.util.concurrent.model.yml +++ b/java/ql/lib/ext/java.util.concurrent.model.yml @@ -17,13 +17,13 @@ extensions: - ["java.util.concurrent", "BlockingQueue", True, "poll", "(long,TimeUnit)", "", "Argument[this].Element", "ReturnValue", "value", "manual"] - ["java.util.concurrent", "BlockingQueue", True, "put", "(Object)", "", "Argument[0]", "Argument[this].Element", "value", "manual"] - ["java.util.concurrent", "BlockingQueue", True, "take", "()", "", "Argument[this].Element", "ReturnValue", "value", "manual"] - - ["java.util.concurrent", "CompletableFuture", False, "complete", "(Object)", "", "Argument[0]", "Argument[-1].SyntheticField[java.util.concurrent.Future.value]", "value", "manual"] + - ["java.util.concurrent", "CompletableFuture", False, "complete", "(Object)", "", "Argument[0]", "Argument[this].SyntheticField[java.util.concurrent.Future.value]", "value", "manual"] - ["java.util.concurrent", "CompletableFuture", False, "completedFuture", "(Object)", "", "Argument[0]", "ReturnValue.SyntheticField[java.util.concurrent.Future.value]", "value", "manual"] - - ["java.util.concurrent", "CompletableFuture", False, "join", "()", "", "Argument[-1].SyntheticField[java.util.concurrent.Future.value]", "ReturnValue", "value", "manual"] - - ["java.util.concurrent", "CompletionStage", False, "toCompletableFuture", "()", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["java.util.concurrent", "CompletableFuture", False, "join", "()", "", "Argument[this].SyntheticField[java.util.concurrent.Future.value]", "ReturnValue", "value", "manual"] + - ["java.util.concurrent", "CompletionStage", False, "toCompletableFuture", "()", "", "Argument[this]", "ReturnValue", "taint", "manual"] - ["java.util.concurrent", "ConcurrentHashMap", True, "elements", "()", "", "Argument[this].MapValue", "ReturnValue.Element", "value", "manual"] - ["java.util.concurrent", "ExecutorService", True, "submit", "(Runnable)", "", "Argument[0]", "ReturnValue", "taint", "manual"] - - ["java.util.concurrent", "Future", True, "get", "()", "", "Argument[-1].SyntheticField[java.util.concurrent.Future.value]", "ReturnValue", "value", "manual"] + - ["java.util.concurrent", "Future", True, "get", "()", "", "Argument[this].SyntheticField[java.util.concurrent.Future.value]", "ReturnValue", "value", "manual"] - ["java.util.concurrent", "TransferQueue", True, "transfer", "(Object)", "", "Argument[0]", "Argument[this].Element", "value", "manual"] - ["java.util.concurrent", "TransferQueue", True, "tryTransfer", "(Object)", "", "Argument[0]", "Argument[this].Element", "value", "manual"] - ["java.util.concurrent", "TransferQueue", True, "tryTransfer", "(Object,long,TimeUnit)", "", "Argument[0]", "Argument[this].Element", "value", "manual"] diff --git a/java/ql/lib/ext/java.util.logging.model.yml b/java/ql/lib/ext/java.util.logging.model.yml index 58f80d47c18..b3f4188ed97 100644 --- a/java/ql/lib/ext/java.util.logging.model.yml +++ b/java/ql/lib/ext/java.util.logging.model.yml @@ -42,7 +42,7 @@ extensions: extensible: summaryModel data: - ["java.util.logging", "Logger", False, "getLogger", "(String)", "", "Argument[0]", "ReturnValue.SyntheticField[java.util.logging.Logger.name]", "value", "manual"] - - ["java.util.logging", "Logger", False, "getName", "()", "", "Argument[-1].SyntheticField[java.util.logging.Logger.name]", "ReturnValue", "value", "manual"] + - ["java.util.logging", "Logger", False, "getName", "()", "", "Argument[this].SyntheticField[java.util.logging.Logger.name]", "ReturnValue", "value", "manual"] - ["java.util.logging", "LogRecord", False, "LogRecord", "", "", "Argument[1]", "Argument[this]", "taint", "manual"] - addsTo: diff --git a/java/ql/lib/ext/java.util.model.yml b/java/ql/lib/ext/java.util.model.yml index 30b5964baed..5df5b1bf4bc 100644 --- a/java/ql/lib/ext/java.util.model.yml +++ b/java/ql/lib/ext/java.util.model.yml @@ -124,8 +124,8 @@ extensions: - ["java.util", "EnumMap", False, "EnumMap", "(Map)", "", "Argument[0].MapValue", "Argument[this].MapValue", "value", "manual"] - ["java.util", "Enumeration", True, "asIterator", "", "", "Argument[this].Element", "ReturnValue.Element", "value", "manual"] - ["java.util", "Enumeration", True, "nextElement", "", "", "Argument[this].Element", "ReturnValue", "value", "manual"] - - ["java.util", "EventObject", False, "EventObject", "(Object)", "", "Argument[0]", "Argument[-1].Field[java.util.EventObject.source]", "value", "manual"] - - ["java.util", "EventObject", True, "getSource", "()", "", "Argument[-1].Field[java.util.EventObject.source]", "ReturnValue", "value", "manual"] + - ["java.util", "EventObject", False, "EventObject", "(Object)", "", "Argument[0]", "Argument[this].Field[java.util.EventObject.source]", "value", "manual"] + - ["java.util", "EventObject", True, "getSource", "()", "", "Argument[this].Field[java.util.EventObject.source]", "ReturnValue", "value", "manual"] - ["java.util", "HashMap", False, "HashMap", "(Map)", "", "Argument[0].MapKey", "Argument[this].MapKey", "value", "manual"] - ["java.util", "HashMap", False, "HashMap", "(Map)", "", "Argument[0].MapValue", "Argument[this].MapValue", "value", "manual"] - ["java.util", "HashSet", False, "HashSet", "(Collection)", "", "Argument[0].Element", "Argument[this].Element", "value", "manual"] @@ -292,7 +292,7 @@ extensions: - ["java.util", "Queue", True, "peek", "()", "", "Argument[this].Element", "ReturnValue", "value", "manual"] - ["java.util", "Queue", True, "poll", "()", "", "Argument[this].Element", "ReturnValue", "value", "manual"] - ["java.util", "Queue", True, "remove", "()", "", "Argument[this].Element", "ReturnValue", "value", "manual"] - - ["java.util", "ResourceBundle", True, "getString", "(String)", "", "Argument[-1].MapValue", "ReturnValue", "value", "manual"] + - ["java.util", "ResourceBundle", True, "getString", "(String)", "", "Argument[this].MapValue", "ReturnValue", "value", "manual"] - ["java.util", "Scanner", True, "Scanner", "", "", "Argument[0]", "Argument[this]", "taint", "manual"] - ["java.util", "Scanner", True, "findInLine", "", "", "Argument[this]", "ReturnValue", "taint", "manual"] - ["java.util", "Scanner", True, "findWithinHorizon", "", "", "Argument[this]", "ReturnValue", "taint", "manual"] From 128a6a39516fecf72af549eeed7cb272aa4e6dcb Mon Sep 17 00:00:00 2001 From: Jami Cogswell <jcogs33@Jamis-MacBook-Pro.local> Date: Tue, 21 Mar 2023 10:22:02 -0400 Subject: [PATCH 404/631] Java: temp revert of neutral filtering --- java/ql/lib/semmle/code/java/dataflow/FlowSummary.qll | 3 +-- .../code/java/dataflow/internal/DataFlowDispatch.qll | 4 ++-- java/ql/lib/semmle/code/java/dispatch/ObjFlow.qll | 11 +++++------ .../lib/semmle/code/java/dispatch/VirtualDispatch.qll | 4 ++-- 4 files changed, 10 insertions(+), 12 deletions(-) diff --git a/java/ql/lib/semmle/code/java/dataflow/FlowSummary.qll b/java/ql/lib/semmle/code/java/dataflow/FlowSummary.qll index 6d6af4f82b4..90f1e91a9cf 100644 --- a/java/ql/lib/semmle/code/java/dataflow/FlowSummary.qll +++ b/java/ql/lib/semmle/code/java/dataflow/FlowSummary.qll @@ -171,8 +171,7 @@ class SummarizedCallableBase extends TSummarizedCallableBase { class SummarizedCallable = Impl::Public::SummarizedCallable; -class NeutralCallable = Impl::Public::NeutralCallable; - +// class NeutralCallable = Impl::Public::NeutralCallable; /** * An adapter class to add the flow summaries specified on `SyntheticCallable` * to `SummarizedCallable`. diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowDispatch.qll b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowDispatch.qll index 875fbd43921..a90ea1ece3e 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowDispatch.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowDispatch.qll @@ -11,8 +11,8 @@ private module DispatchImpl { private predicate hasHighConfidenceTarget(Call c) { exists(SummarizedCallable sc | sc.getACall() = c and not sc.isAutoGenerated()) or - exists(NeutralCallable nc | nc.getACall() = c and nc.isManual()) - or + // exists(NeutralCallable nc | nc.getACall() = c and nc.isManual()) + // or exists(Callable srcTgt | srcTgt = VirtualDispatch::viableCallable(c) and not VirtualDispatch::lowConfidenceDispatchTarget(c, srcTgt) diff --git a/java/ql/lib/semmle/code/java/dispatch/ObjFlow.qll b/java/ql/lib/semmle/code/java/dispatch/ObjFlow.qll index d4c0d7e5ab5..29a71855c04 100644 --- a/java/ql/lib/semmle/code/java/dispatch/ObjFlow.qll +++ b/java/ql/lib/semmle/code/java/dispatch/ObjFlow.qll @@ -236,12 +236,11 @@ private VirtualMethodAccess objectToString(ObjNode n) { result.getQualifier() = n.asExpr() and sink(n) } -/** - * Holds if `ma` is an `Object.toString()` call taking possibly improved type - * bounds into account. - */ -predicate objectToStringCall(VirtualMethodAccess ma) { ma = objectToString(_) } - +// /** +// * Holds if `ma` is an `Object.toString()` call taking possibly improved type +// * bounds into account. +// */ +// predicate objectToStringCall(VirtualMethodAccess ma) { ma = objectToString(_) } /** * Holds if the qualifier of the `Object.toString()` call `ma` might have type `t`. */ diff --git a/java/ql/lib/semmle/code/java/dispatch/VirtualDispatch.qll b/java/ql/lib/semmle/code/java/dispatch/VirtualDispatch.qll index 4b880542229..b429a6689ef 100644 --- a/java/ql/lib/semmle/code/java/dispatch/VirtualDispatch.qll +++ b/java/ql/lib/semmle/code/java/dispatch/VirtualDispatch.qll @@ -93,8 +93,8 @@ private module Dispatch { exists(RefType t | qualUnionType(ma, t, false) | lowConfidenceDispatchType(t.getSourceDeclaration()) ) - ) and - not ObjFlow::objectToStringCall(ma) + ) //and + //not ObjFlow::objectToStringCall(ma) } private predicate lowConfidenceDispatchType(SrcRefType t) { From 222e6f0b8234d5111bb365a65b6998d9488cf230 Mon Sep 17 00:00:00 2001 From: Jami Cogswell <jcogs33@Jamis-MacBook-Pro.local> Date: Thu, 23 Mar 2023 17:42:35 -0400 Subject: [PATCH 405/631] Java: undo temp revert of neutral filtering --- java/ql/lib/semmle/code/java/dataflow/FlowSummary.qll | 3 ++- .../code/java/dataflow/internal/DataFlowDispatch.qll | 4 ++-- java/ql/lib/semmle/code/java/dispatch/ObjFlow.qll | 11 ++++++----- .../lib/semmle/code/java/dispatch/VirtualDispatch.qll | 4 ++-- 4 files changed, 12 insertions(+), 10 deletions(-) diff --git a/java/ql/lib/semmle/code/java/dataflow/FlowSummary.qll b/java/ql/lib/semmle/code/java/dataflow/FlowSummary.qll index 90f1e91a9cf..6d6af4f82b4 100644 --- a/java/ql/lib/semmle/code/java/dataflow/FlowSummary.qll +++ b/java/ql/lib/semmle/code/java/dataflow/FlowSummary.qll @@ -171,7 +171,8 @@ class SummarizedCallableBase extends TSummarizedCallableBase { class SummarizedCallable = Impl::Public::SummarizedCallable; -// class NeutralCallable = Impl::Public::NeutralCallable; +class NeutralCallable = Impl::Public::NeutralCallable; + /** * An adapter class to add the flow summaries specified on `SyntheticCallable` * to `SummarizedCallable`. diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowDispatch.qll b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowDispatch.qll index a90ea1ece3e..875fbd43921 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowDispatch.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowDispatch.qll @@ -11,8 +11,8 @@ private module DispatchImpl { private predicate hasHighConfidenceTarget(Call c) { exists(SummarizedCallable sc | sc.getACall() = c and not sc.isAutoGenerated()) or - // exists(NeutralCallable nc | nc.getACall() = c and nc.isManual()) - // or + exists(NeutralCallable nc | nc.getACall() = c and nc.isManual()) + or exists(Callable srcTgt | srcTgt = VirtualDispatch::viableCallable(c) and not VirtualDispatch::lowConfidenceDispatchTarget(c, srcTgt) diff --git a/java/ql/lib/semmle/code/java/dispatch/ObjFlow.qll b/java/ql/lib/semmle/code/java/dispatch/ObjFlow.qll index 29a71855c04..d4c0d7e5ab5 100644 --- a/java/ql/lib/semmle/code/java/dispatch/ObjFlow.qll +++ b/java/ql/lib/semmle/code/java/dispatch/ObjFlow.qll @@ -236,11 +236,12 @@ private VirtualMethodAccess objectToString(ObjNode n) { result.getQualifier() = n.asExpr() and sink(n) } -// /** -// * Holds if `ma` is an `Object.toString()` call taking possibly improved type -// * bounds into account. -// */ -// predicate objectToStringCall(VirtualMethodAccess ma) { ma = objectToString(_) } +/** + * Holds if `ma` is an `Object.toString()` call taking possibly improved type + * bounds into account. + */ +predicate objectToStringCall(VirtualMethodAccess ma) { ma = objectToString(_) } + /** * Holds if the qualifier of the `Object.toString()` call `ma` might have type `t`. */ diff --git a/java/ql/lib/semmle/code/java/dispatch/VirtualDispatch.qll b/java/ql/lib/semmle/code/java/dispatch/VirtualDispatch.qll index b429a6689ef..4b880542229 100644 --- a/java/ql/lib/semmle/code/java/dispatch/VirtualDispatch.qll +++ b/java/ql/lib/semmle/code/java/dispatch/VirtualDispatch.qll @@ -93,8 +93,8 @@ private module Dispatch { exists(RefType t | qualUnionType(ma, t, false) | lowConfidenceDispatchType(t.getSourceDeclaration()) ) - ) //and - //not ObjFlow::objectToStringCall(ma) + ) and + not ObjFlow::objectToStringCall(ma) } private predicate lowConfidenceDispatchType(SrcRefType t) { From b8ceb7112d9835e0f41bf4c4ac5b9938dbb56323 Mon Sep 17 00:00:00 2001 From: Jami Cogswell <jcogs33@Jamis-MacBook-Pro.local> Date: Thu, 23 Mar 2023 18:07:06 -0400 Subject: [PATCH 406/631] Java: update ordering of Path.getFileName model --- java/ql/lib/ext/java.nio.file.model.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/ql/lib/ext/java.nio.file.model.yml b/java/ql/lib/ext/java.nio.file.model.yml index 2991c20a6b3..6c5c2d13f96 100644 --- a/java/ql/lib/ext/java.nio.file.model.yml +++ b/java/ql/lib/ext/java.nio.file.model.yml @@ -43,9 +43,9 @@ extensions: - ["java.nio.file", "FileSystem", True, "getPath", "(String,String[])", "", "Argument[1]", "ReturnValue", "taint", "ai-generated"] - ["java.nio.file", "FileSystem", True, "getPathMatcher", "(String)", "", "Argument[0]", "ReturnValue", "taint", "ai-generated"] - ["java.nio.file", "FileSystem", True, "getRootDirectories", "", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - ["java.nio.file", "Path", True, "getFileName", "", "", "Argument[this]", "ReturnValue", "taint", "manual"] - ["java.nio.file", "Path", True, "getParent", "", "", "Argument[this]", "ReturnValue", "taint", "manual"] - ["java.nio.file", "Path", True, "normalize", "", "", "Argument[this]", "ReturnValue", "taint", "manual"] - - ["java.nio.file", "Path", True, "getFileName", "", "", "Argument[this]", "ReturnValue", "taint", "manual"] - ["java.nio.file", "Path", True, "of", "(String,String[])", "", "Argument[0]", "ReturnValue", "taint", "ai-generated"] - ["java.nio.file", "Path", True, "of", "(String,String[])", "", "Argument[1]", "ReturnValue", "taint", "ai-generated"] - ["java.nio.file", "Path", True, "of", "(URI)", "", "Argument[0]", "ReturnValue", "taint", "ai-generated"] From 32468b68de78b7084315110b275e0735a7cba149 Mon Sep 17 00:00:00 2001 From: Harry Maclean <hmac@github.com> Date: Thu, 23 Mar 2023 13:05:08 +1300 Subject: [PATCH 407/631] Ruby: Use correct binary for linux build --- .github/workflows/ruby-build.yml | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ruby-build.yml b/.github/workflows/ruby-build.yml index 3c9ee5bcf92..7fc13d828af 100644 --- a/.github/workflows/ruby-build.yml +++ b/.github/workflows/ruby-build.yml @@ -60,8 +60,10 @@ jobs: path: | ruby/extractor/target/release/autobuilder ruby/extractor/target/release/autobuilder.exe + ruby/extractor/target/x86_64-unknown-linux-gnu/release/autobuilder ruby/extractor/target/release/extractor ruby/extractor/target/release/extractor.exe + ruby/extractor/target/x86_64-unknown-linux-gnu/release/extractor ruby/extractor/ql/lib/codeql/ruby/ast/internal/TreeSitter.qll key: ${{ runner.os }}-${{ steps.os_version.outputs.version }}-ruby-extractor-${{ hashFiles('ruby/extractor/rust-toolchain.toml', 'ruby/extractor/Cargo.lock') }}--${{ hashFiles('ruby/extractor/**/*.rs') }} - uses: actions/cache@v3 @@ -85,7 +87,12 @@ jobs: # This ensures we don't depend on glibc > 2.17. - name: Release build (linux) if: steps.cache-extractor.outputs.cache-hit != 'true' && runner.os == 'Linux' - run: cd extractor && cross build --release + run: | + cd extractor + cross build --release + mv target/x86_64-unknown-linux-gnu/release/extractor target/release/ + mv target/x86_64-unknown-linux-gnu/release/autobuilder target/release/ + mv target/x86_64-unknown-linux-gnu/release/generator target/release/ - name: Release build (windows and macos) if: steps.cache-extractor.outputs.cache-hit != 'true' && runner.os != 'Linux' run: cd extractor && cargo build --release From 30eacd03d83362e6a3775309714d9d5056c1f02d Mon Sep 17 00:00:00 2001 From: Harry Maclean <hmac@github.com> Date: Fri, 24 Mar 2023 10:43:21 +1300 Subject: [PATCH 408/631] Ruby: Whitespace change to bust extractor cache --- ruby/extractor/src/bin/extractor.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ruby/extractor/src/bin/extractor.rs b/ruby/extractor/src/bin/extractor.rs index f2a764262d4..b6fda52f4fb 100644 --- a/ruby/extractor/src/bin/extractor.rs +++ b/ruby/extractor/src/bin/extractor.rs @@ -280,8 +280,10 @@ fn scan_erb( } } } + if result.is_empty() { let root = tree.root_node(); + // Add an empty range at the end of the file result.push(Range { start_byte: root.end_byte(), From fbda6dc5c6f2a2aa89f7f62e838ef246694514bf Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 24 Mar 2023 04:01:51 +0000 Subject: [PATCH 409/631] Bump actions/stale from 7 to 8 Bumps [actions/stale](https://github.com/actions/stale) from 7 to 8. - [Release notes](https://github.com/actions/stale/releases) - [Changelog](https://github.com/actions/stale/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/stale/compare/v7...v8) --- updated-dependencies: - dependency-name: actions/stale dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] <support@github.com> --- .github/workflows/close-stale.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/close-stale.yml b/.github/workflows/close-stale.yml index 6bdee05d6a1..9805fb44f48 100644 --- a/.github/workflows/close-stale.yml +++ b/.github/workflows/close-stale.yml @@ -12,7 +12,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/stale@v7 + - uses: actions/stale@v8 with: repo-token: ${{ secrets.GITHUB_TOKEN }} stale-issue-message: 'This issue is stale because it has been open 14 days with no activity. Comment or remove the `Stale` label in order to avoid having this issue closed in 7 days.' From 3e4f35151a4327119b449dc7e985c41d0afd13a8 Mon Sep 17 00:00:00 2001 From: Jeroen Ketema <jketema@github.com> Date: Fri, 24 Mar 2023 09:02:31 +0100 Subject: [PATCH 410/631] C++: Rename `SslContextCallMake` to `SslContextCallGlobal` This is in line with changes made to the dataflow library --- ...boost-deprecated-dataflow-configurations.md | 2 +- .../cpp/security/boostorg/asio/protocols.qll | 18 ++++++++++++------ 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/cpp/ql/lib/change-notes/2023-03-20-boost-deprecated-dataflow-configurations.md b/cpp/ql/lib/change-notes/2023-03-20-boost-deprecated-dataflow-configurations.md index b4389ba5b59..a9d2a4d2c80 100644 --- a/cpp/ql/lib/change-notes/2023-03-20-boost-deprecated-dataflow-configurations.md +++ b/cpp/ql/lib/change-notes/2023-03-20-boost-deprecated-dataflow-configurations.md @@ -1,4 +1,4 @@ --- category: deprecated --- -* The `SslContextCallAbstractConfig`, `SslContextCallConfig`, `SslContextCallBannedProtocolConfig`, `SslContextCallTls12ProtocolConfig`, `SslContextCallTls13ProtocolConfig`, `SslContextCallTlsProtocolConfig`, `SslContextFlowsToSetOptionConfig`, `SslOptionConfig` dataflow configurations from `BoostorgAsio` have been deprecated. Please use `SslContextCallConfigSig`, `SslContextCallMake`, `SslContextCallFlow`, `SslContextCallBannedProtocolFlow`, `SslContextCallTls12ProtocolFlow`, `SslContextCallTls13ProtocolFlow`, `SslContextCallTlsProtocolFlow`, `SslContextFlowsToSetOptionFlow`. +* The `SslContextCallAbstractConfig`, `SslContextCallConfig`, `SslContextCallBannedProtocolConfig`, `SslContextCallTls12ProtocolConfig`, `SslContextCallTls13ProtocolConfig`, `SslContextCallTlsProtocolConfig`, `SslContextFlowsToSetOptionConfig`, `SslOptionConfig` dataflow configurations from `BoostorgAsio` have been deprecated. Please use `SslContextCallConfigSig`, `SslContextCallGlobal`, `SslContextCallFlow`, `SslContextCallBannedProtocolFlow`, `SslContextCallTls12ProtocolFlow`, `SslContextCallTls13ProtocolFlow`, `SslContextCallTlsProtocolFlow`, `SslContextFlowsToSetOptionFlow`. diff --git a/cpp/ql/lib/semmle/code/cpp/security/boostorg/asio/protocols.qll b/cpp/ql/lib/semmle/code/cpp/security/boostorg/asio/protocols.qll index e53be5980b1..63b11597487 100644 --- a/cpp/ql/lib/semmle/code/cpp/security/boostorg/asio/protocols.qll +++ b/cpp/ql/lib/semmle/code/cpp/security/boostorg/asio/protocols.qll @@ -394,7 +394,7 @@ module BoostorgAsio { * Constructs a standard data flow computation for protocol values to the first argument * of a context constructor. */ - module SslContextCallMake<SslContextCallConfigSig Config> { + module SslContextCallGlobal<SslContextCallConfigSig Config> { private module C implements DataFlow::ConfigSig { import Config } @@ -402,6 +402,11 @@ module BoostorgAsio { import DataFlow::Global<C> } + /** DEPRECATED: Use `SslContextCallGlobal` instead. */ + deprecated module SslContextCallMake<SslContextCallConfigSig Config> { + import SslContextCallGlobal<Config> + } + /** * Any protocol value that flows to the first argument of a context constructor. */ @@ -428,7 +433,7 @@ module BoostorgAsio { } } - module SslContextCallFlow = SslContextCallMake<SslContextCallConfig>; + module SslContextCallFlow = SslContextCallGlobal<SslContextCallConfig>; /** * A banned protocol value that flows to the first argument of a context constructor. @@ -458,7 +463,8 @@ module BoostorgAsio { } } - module SslContextCallBannedProtocolFlow = SslContextCallMake<SslContextCallBannedProtocolConfig>; + module SslContextCallBannedProtocolFlow = + SslContextCallGlobal<SslContextCallBannedProtocolConfig>; /** * A TLS 1.2 protocol value that flows to the first argument of a context constructor. @@ -488,7 +494,7 @@ module BoostorgAsio { } } - module SslContextCallTls12ProtocolFlow = SslContextCallMake<SslContextCallTls12ProtocolConfig>; + module SslContextCallTls12ProtocolFlow = SslContextCallGlobal<SslContextCallTls12ProtocolConfig>; /** * A TLS 1.3 protocol value that flows to the first argument of a context constructor. @@ -518,7 +524,7 @@ module BoostorgAsio { } } - module SslContextCallTls13ProtocolFlow = SslContextCallMake<SslContextCallTls13ProtocolConfig>; + module SslContextCallTls13ProtocolFlow = SslContextCallGlobal<SslContextCallTls13ProtocolConfig>; /** * A generic TLS protocol value that flows to the first argument of a context constructor. @@ -548,7 +554,7 @@ module BoostorgAsio { } } - module SslContextCallTlsProtocolFlow = SslContextCallMake<SslContextCallTlsProtocolConfig>; + module SslContextCallTlsProtocolFlow = SslContextCallGlobal<SslContextCallTlsProtocolConfig>; /** * A context constructor call that flows to a call to `SetOptions()`. From 690b39420e339d8672d1f4454a8685f01c42a887 Mon Sep 17 00:00:00 2001 From: Michael Nebel <michaelnebel@github.com> Date: Mon, 6 Mar 2023 15:36:36 +0100 Subject: [PATCH 411/631] Java: Add initial documentation for MaD using data extensions for Java. --- .../customizing-library-models-for-java.rst | 94 +++++++++++++++++++ .../beta-note-customizing-library-models.rst | 7 ++ 2 files changed, 101 insertions(+) create mode 100644 docs/codeql/codeql-language-guides/customizing-library-models-for-java.rst create mode 100644 docs/codeql/reusables/beta-note-customizing-library-models.rst diff --git a/docs/codeql/codeql-language-guides/customizing-library-models-for-java.rst b/docs/codeql/codeql-language-guides/customizing-library-models-for-java.rst new file mode 100644 index 00000000000..e329b7135d6 --- /dev/null +++ b/docs/codeql/codeql-language-guides/customizing-library-models-for-java.rst @@ -0,0 +1,94 @@ +.. _customizing-library-models-for-java: + +Customizing Library Models for Java +=================================== + +.. include:: ../reusables/beta-note-customizing-library-models.rst + +The Java analysis can be customized by adding library models (summaries, sinks and sources) in data extensions files. + +A data extension file for Java is a YAML file in the form: + +.. code-block:: yaml + + extensions: + - addsTo: + pack: codeql/java-all + extensible: <name of extension point> + data: + - <tuple1> + - <tuple2> + - ... + +The data extension can contribute to the following extension points: + +- **sourceModel**\(package, type, subtypes, name, signature, ext, output, kind, provenance) +- **sinkModel**\(package, type, subtypes, name, signature, ext, input, kind, provenance) +- **summaryModel**\(package, type, subtypes, name, signature, ext, input, output, kind, provenance) +- **neutralModel**\(package, type, name, signature, provenance) + +TODO: Link or inline documentation on how to add dataextensions. +Are we going for extensions packs as the recommended default? +If yes, then we probably need to elaborate with a concrete example. + +In the sections below, we will go through the different extension points using concrete examples. + +Example: Taint sink in the **java.sql** package. +------------------------------------------------ + +In this example we will see, how to define the argument passed to the **execute** method as a SQL injection sink. +This is the **execute** method in the **Statement** class, which is located in the 'java.sql' package. +Please note that this sink is already added to the CodeQL Java analysis. + +.. code-block:: java + + public static void tainted(Connection conn, String query) throws SQLException { + Statement stmt = conn.createStatement(); + stmt.execute(query); + } + +This can be achieved by adding the following data extensions. + +.. code-block:: yaml + + extensions: + - addsTo: + pack: codeql/java-all + extensible: sinkModel + data: + - ["java.sql", "Statement", True, "execute", "(String)", "", "Argument[0]", "sql", "manual"] + +Reasoning: + +Since we are adding a new sink, we need to add a tuple to the **sinkModel** extension point. +The first five values are used to identify the method (callable) which we are defining a sink on. + +- The first value **java.sql** is the package name. +- The second value **Statement** is the class (type) name. +- The third value **True** is flag indicating, whether the sink also applies to all overrides of the method. +- The fourth value **execute** is the method name. +- The fifth value **(String)** is the method input type signature. + +For most practical purposes the six value is not relevant. +The remaining values are used to define the **access path**, the **kind**, and the **provenance** (origin) of the sink. + +- The seventh value **Argument[0]** is the access path to the first argument passed to the method, which means that this is the location of the sink. +- The eighth value **sql** is the kind of the sink. The sink kind is used to define for which queries the sink is in scope. +- The ninth value **manual** is the provenance of the sink, which is used to identify the origin of the sink. + +Example: Taint source from the '<TODO>' package. +------------------------------------------------ + + +Example: Adding flow through '<TODO>' methods. +---------------------------------------------- + +Example: Adding **neutral** methods. +------------------------------------ +This is purely for consistency and has no impact on the analysis. + +Reference material +------------------ + +The following sections provide reference material for extension points. +This includins descriptions of each of the arguments (eg. access paths, types, and kinds). \ No newline at end of file diff --git a/docs/codeql/reusables/beta-note-customizing-library-models.rst b/docs/codeql/reusables/beta-note-customizing-library-models.rst new file mode 100644 index 00000000000..e026d5a083e --- /dev/null +++ b/docs/codeql/reusables/beta-note-customizing-library-models.rst @@ -0,0 +1,7 @@ +.. pull-quote:: + + Beta Notice - Unstable API + + Library customization using data extensions is currently in beta and subject to change. + + Breaking changes to this format may occur while in beta. \ No newline at end of file From 1fd28445e3b0aaa1ded2ff1a555c37c65dd26120 Mon Sep 17 00:00:00 2001 From: Michael Nebel <michaelnebel@github.com> Date: Mon, 6 Mar 2023 15:37:10 +0100 Subject: [PATCH 412/631] Java: Add link to the library customization page. --- docs/codeql/codeql-language-guides/codeql-for-java.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/codeql/codeql-language-guides/codeql-for-java.rst b/docs/codeql/codeql-language-guides/codeql-for-java.rst index aa10f481592..031f1b07220 100644 --- a/docs/codeql/codeql-language-guides/codeql-for-java.rst +++ b/docs/codeql/codeql-language-guides/codeql-for-java.rst @@ -25,6 +25,7 @@ Experiment and learn how to write effective and efficient queries for CodeQL dat javadoc working-with-source-locations abstract-syntax-tree-classes-for-working-with-java-programs + customizing-library-models-for-java - :doc:`Basic query for Java code <basic-query-for-java-code>`: Learn to write and run a simple CodeQL query. @@ -46,3 +47,4 @@ Experiment and learn how to write effective and efficient queries for CodeQL dat - :doc:`Abstract syntax tree classes for working with Java programs <abstract-syntax-tree-classes-for-working-with-java-programs>`: CodeQL has a large selection of classes for representing the abstract syntax tree of Java programs. +- :doc:`Customizing library models for Java <customizing-library-models-for-java>`: You can customize the CodeQL library for Java to model the behavior of your own Java libraries using data extensions. \ No newline at end of file From f6ef55881d28b8d3f82d35df141b736aed195f11 Mon Sep 17 00:00:00 2001 From: Michael Nebel <michaelnebel@github.com> Date: Tue, 7 Mar 2023 13:24:12 +0100 Subject: [PATCH 413/631] Java: Add source example. --- .../customizing-library-models-for-java.rst | 50 +++++++++++++++++-- 1 file changed, 45 insertions(+), 5 deletions(-) diff --git a/docs/codeql/codeql-language-guides/customizing-library-models-for-java.rst b/docs/codeql/codeql-language-guides/customizing-library-models-for-java.rst index e329b7135d6..bb37e6e4e3d 100644 --- a/docs/codeql/codeql-language-guides/customizing-library-models-for-java.rst +++ b/docs/codeql/codeql-language-guides/customizing-library-models-for-java.rst @@ -32,6 +32,7 @@ Are we going for extensions packs as the recommended default? If yes, then we probably need to elaborate with a concrete example. In the sections below, we will go through the different extension points using concrete examples. +The **Reference material** section will in more detail describe the *mini DSLs* that are used to comprise a model definition. Example: Taint sink in the **java.sql** package. ------------------------------------------------ @@ -42,12 +43,12 @@ Please note that this sink is already added to the CodeQL Java analysis. .. code-block:: java - public static void tainted(Connection conn, String query) throws SQLException { + public static void taintsink(Connection conn, String query) throws SQLException { Statement stmt = conn.createStatement(); stmt.execute(query); } -This can be achieved by adding the following data extensions. +This can be achieved by adding the following data extension. .. code-block:: yaml @@ -69,20 +70,59 @@ The first five values are used to identify the method (callable) which we are de - The fourth value **execute** is the method name. - The fifth value **(String)** is the method input type signature. -For most practical purposes the six value is not relevant. +For most practical purposes the sixth value is not relevant. The remaining values are used to define the **access path**, the **kind**, and the **provenance** (origin) of the sink. - The seventh value **Argument[0]** is the access path to the first argument passed to the method, which means that this is the location of the sink. - The eighth value **sql** is the kind of the sink. The sink kind is used to define for which queries the sink is in scope. - The ninth value **manual** is the provenance of the sink, which is used to identify the origin of the sink. -Example: Taint source from the '<TODO>' package. ------------------------------------------------- +Example: Taint source from the **java.net** package. +---------------------------------------------------- +In this example we will see, how to define the return value from the **getInputStream** method as a remote source. +This is the **getInputStream** method in the **Socket** class, which is located in the 'java.net' package. +Please note that this source is already added to the CodeQL Java analysis. +.. code-block:: java + + public static InputStream tainted(Socket socket) throws IOException { + InputStream stream = socket.getInputStream(); + return stream; + } + +This can be achieved by adding the following data extension. + +.. code-block:: yaml + + extensions: + - addsTo: + pack: codeql/java-all + extensible: sourceModel + data: + - ["java.net", "Socket", False, "getInputStream", "()", "", "ReturnValue", "remote", "manual"] + +Reasoning: + +Since we are adding a new source, we need to add a tuple to the **sourceModel** extension point. +The first five values are used to identify the method (callable) which we are defining a source on. + +- The first value **java.net** is the package name. +- The second value **Socket** is the class (type) name. +- The third value **False** is flag indicating, whether the source also applies to all overrides of the method. +- The fourth value **getInputStream** is the method name. +- The fifth value **()** is the method input type signature. + +For most practical purposes the sixth value is not relevant. +The remaining values are used to define the **access path**, the **kind**, and the **provenance** (origin) of the source. + +- The seventh value **ReturnValue** is the access path to the return of the method, which means that it is the return value that should be considered a tainted source. +- The eighth value **remote** is the kind of the source. The source kind is used to define for which queries the source is in scope. **remote** applies to many of security related queries as it means a remote source of untrusted data. As an example the SQL injection query uses **remote** sources. +- The ninth value **manual** is the provenance of the source, which is used to identify the origin of the source. Example: Adding flow through '<TODO>' methods. ---------------------------------------------- + Example: Adding **neutral** methods. ------------------------------------ This is purely for consistency and has no impact on the analysis. From 7ef4cc4bb9cc7a2fe1f8274d6fc0b6ebd5b1a4d4 Mon Sep 17 00:00:00 2001 From: Michael Nebel <michaelnebel@github.com> Date: Tue, 7 Mar 2023 14:46:17 +0100 Subject: [PATCH 414/631] Java: Add flow through examples. --- .../customizing-library-models-for-java.rst | 107 +++++++++++++++++- 1 file changed, 103 insertions(+), 4 deletions(-) diff --git a/docs/codeql/codeql-language-guides/customizing-library-models-for-java.rst b/docs/codeql/codeql-language-guides/customizing-library-models-for-java.rst index bb37e6e4e3d..b76be95c234 100644 --- a/docs/codeql/codeql-language-guides/customizing-library-models-for-java.rst +++ b/docs/codeql/codeql-language-guides/customizing-library-models-for-java.rst @@ -45,7 +45,7 @@ Please note that this sink is already added to the CodeQL Java analysis. public static void taintsink(Connection conn, String query) throws SQLException { Statement stmt = conn.createStatement(); - stmt.execute(query); + stmt.execute(query); // The argument passed to this method is a SQL injection sink. } This can be achieved by adding the following data extension. @@ -86,7 +86,7 @@ Please note that this source is already added to the CodeQL Java analysis. .. code-block:: java public static InputStream tainted(Socket socket) throws IOException { - InputStream stream = socket.getInputStream(); + InputStream stream = socket.getInputStream(); // The return value of this method is a remote source. return stream; } @@ -119,9 +119,108 @@ The remaining values are used to define the **access path**, the **kind**, and t - The eighth value **remote** is the kind of the source. The source kind is used to define for which queries the source is in scope. **remote** applies to many of security related queries as it means a remote source of untrusted data. As an example the SQL injection query uses **remote** sources. - The ninth value **manual** is the provenance of the source, which is used to identify the origin of the source. -Example: Adding flow through '<TODO>' methods. ----------------------------------------------- +Example: Adding flow through the **concat** method. +--------------------------------------------------- +In this example we will see, how to define flow through a method for a simple case. +This pattern covers many of the cases where we need to define flow through a method. +Please note that the flow through the **concat** method is already added to the CodeQL Java analysis. +.. code-block:: java + + public static String taintflow(String s1, String s2) { + String t = s1.concat(s2); // There is taint flow from s1 and s2 to t. + return t; + } + +This can be achieved by adding the following data extension. +These are widely known as summary models. + +.. code-block:: yaml + + extensions: + - addsTo: + pack: codeql/java-all + extensible: summaryModel + data: + - ["java.lang", "String", False, "concat", "(String)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["java.lang", "String", False, "concat", "(String)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + +Reasoning: + +Since we are adding flow through a method, we need to add tuples to the **summaryModel** extension point. +Each tuple defines flow from one argument to the return value. +The first five values are used to identify the method (callable) which we are defining a source on. +These are the same for both of the rows above. + +- The first value **java.lang** is the package name. +- The second value **String** is the class (type) name. +- The third value **False** is flag indicating, whether the source also applies to all overrides of the method. +- The fourth value **concat** is the method name. +- The fifth value **(String)** is the method input type signature. + +For most practical purposes the sixth value is not relevant. +The remaining values are used to define the **access path**, the **kind**, and the **provenance** (origin) of the source. + +- The seventh value is the access path to the input where data flows from. **Argument[-1]** is the access path to the qualifier (**s1** in the example) and **Argument[0]** is the access path to the first argument (**s2** in the example). +- The eighth value **ReturnValue** is the access path to the output where data flows too, in this case **ReturnValue**, which means that the input flows to the return value. +- The ninth value **taint** is the kind of the flow. **taint** means that taint is propagated through the flow. +- The tenth value **manual** is the provenance of the source, which is used to identify the origin of the summary. + +Example: Add flow through the **map** method. +--------------------------------------------- +In this example will will see a more complex example of modelling flow through a method. +This pattern shows how to model flow through higher order methods and collection types. +Please note that the flow through the **map** method is already added to the CodeQL Java analysis. + +.. code-block:: java + + public static Stream<String> taintflow(Stream<String> s) { + Stream<String> l = s.map(e -> e.concat("\n")); + return l; + } + +This can be achieved by adding the following data extension. + +.. code-block:: yaml + + extensions: + - addsTo: + pack: codeql/java-all + extensible: summaryModel + data: + - ["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"] + +Reasoning: + +Since we are adding flow through a method, we need to add tuples to the **summaryModel** extension point. +Each tuple defines part of the flow that comprises the total flow through the method. +The first five values are used to identify the method (callable) which we are defining a source on. +These are the same for both of the rows above. + +- The first value **java.util.stream** is the package name. +- The second value **Stream** is the class (type) name. +- The third value **True** is flag indicating, whether the source also applies to all overrides of the method. +- The fourth value **map** is the method name. +- The fifth value **Function** is the method input type signature. + +For most practical purposes the sixth value is not relevant. +The remaining values are used to define the **access path**, the **kind**, and the **provenance** (origin) of the source. +- The seventh value is the access path to the **input** where data flows from. +- The eighth value **ReturnValue** is the access path to the **output** where data flows too. + +For the first row the +- The seventh value is **Argument[-1].Element**, which is the access path to the elements of the qualifier (the elements of the stream **s** in the example). +- The eight value is **Argument[0].Paramter[0]**, which is the access path the first parameter of the **Function** argument of **map** (the lambda parameter **e** in the example). + +For the second row the +- The seventh value is **Argument[0].ReturnValue**, which is the access path to the return value of the **Function** argument of **map** (the return value of the lambda in the example). +- The eighth value is **ReturnValue.Element**, which is the access path to the elements of the return value of **map** (the elements of the stream **l** in the example). + +- The ninth value **value** is the kind of the flow. **value** means that the value is propagated. +- The tenth value **manual** is the provenance of the source, which is used to identify the origin of the summary. + +That is, the first row models that there is value flow from the elements of qualifier stream into the first argument of the Function provided to **map** and the second row models that there is value flow from the return value of the Function to the elements of the stream returned from **map**. Example: Adding **neutral** methods. ------------------------------------ From 3a1d6420dbb8a2fbac26343183190ac1665cb51b Mon Sep 17 00:00:00 2001 From: Michael Nebel <michaelnebel@github.com> Date: Wed, 8 Mar 2023 09:45:52 +0100 Subject: [PATCH 415/631] Java: Add neutral example. --- .../customizing-library-models-for-java.rst | 35 +++++++++++++++++-- 1 file changed, 33 insertions(+), 2 deletions(-) diff --git a/docs/codeql/codeql-language-guides/customizing-library-models-for-java.rst b/docs/codeql/codeql-language-guides/customizing-library-models-for-java.rst index b76be95c234..68b786876ca 100644 --- a/docs/codeql/codeql-language-guides/customizing-library-models-for-java.rst +++ b/docs/codeql/codeql-language-guides/customizing-library-models-for-java.rst @@ -32,7 +32,8 @@ Are we going for extensions packs as the recommended default? If yes, then we probably need to elaborate with a concrete example. In the sections below, we will go through the different extension points using concrete examples. -The **Reference material** section will in more detail describe the *mini DSLs* that are used to comprise a model definition. +The extension points are used to customize and improve the existing dataflow queries, by providing sources, sinks and flow through for library methods. +The **Reference material** section will in more detail describe the *mini DSLs* that are used to comprise a model definition for each extension point. Example: Taint sink in the **java.sql** package. ------------------------------------------------ @@ -224,10 +225,40 @@ That is, the first row models that there is value flow from the elements of qual Example: Adding **neutral** methods. ------------------------------------ +In this example we will see, how to define the **now** method as being neutral. This is purely for consistency and has no impact on the analysis. +A neutral model is used to define that there is no flow through a method. +Please note that the neutral model for the **now** method is already added. + +.. code-block:: java + + public static Instant taintflow() { + Instant t = Instant.now(); // There is no flow from now to t. + return t; + } + +.. code-block:: yaml + + extensions: + - addsTo: + pack: codeql/java-all + extensible: neutralModel + data: + - ["java.time", "Instant", "now", "()", "manual"] + +Reasoning: + +Since we are adding a neutral model, we need to add tuples to the **neutralModel** extension point. +The first four values are used to identify the method (callable) which we are defining as a neutral and the fifth value is the provenance (origin) of the neutral. + +- The first value **java.time** is the package name. +- The second value **Instant** is the class (type) name. +- The third value **now** is the method name. +- The fourth value **()** is the method input type signature. +- The fifth value **manual** is the provenance of the neutral. Reference material ------------------ The following sections provide reference material for extension points. -This includins descriptions of each of the arguments (eg. access paths, types, and kinds). \ No newline at end of file +This includes descriptions of each of the arguments (eg. access paths, types, and kinds). \ No newline at end of file From 0f03605b08906dee9bae6a107d23f05300f7aa49 Mon Sep 17 00:00:00 2001 From: Michael Nebel <michaelnebel@github.com> Date: Wed, 8 Mar 2023 11:20:51 +0100 Subject: [PATCH 416/631] Java: Add reference material docs for source and sink models. --- .../customizing-library-models-for-java.rst | 88 ++++++++++++++++++- 1 file changed, 87 insertions(+), 1 deletion(-) diff --git a/docs/codeql/codeql-language-guides/customizing-library-models-for-java.rst b/docs/codeql/codeql-language-guides/customizing-library-models-for-java.rst index 68b786876ca..6e5201522f2 100644 --- a/docs/codeql/codeql-language-guides/customizing-library-models-for-java.rst +++ b/docs/codeql/codeql-language-guides/customizing-library-models-for-java.rst @@ -261,4 +261,90 @@ Reference material ------------------ The following sections provide reference material for extension points. -This includes descriptions of each of the arguments (eg. access paths, types, and kinds). \ No newline at end of file +This includes descriptions of each of the arguments (eg. access paths, types, and kinds). + +Extension points +---------------- + +Below is a description of the tuple values for each extension point. +The section Access paths describes in more detail, how access paths are composed. +This is the most complicated part of the extension points and the **mini DSL** for access paths is shared accross the extension points. + +sourceModel(package, type, subtypes, name, signature, ext, output, kind, provenance) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Taint source. Most taint tracking queries will use the sources added to this extensions point. + +- **package**: Name of the package where the source resides. +- **type**: Name of the type where the source resides. +- **subtypes**: Whether the source should also apply to all overrides of the method. +- **name**: Name of the method where the source resides. +- **signature**: Type signature of the method where the source resides. +- **ext**: Specifies additional API-graph-like edges (mostly empty). +- **output**: Access path to the source, where the possibly tainted data flows from. +- **kind**: Kind of the source. +- **provenance**: Provenance (origin) of the source. + +As most sources are used by all taint tracking queries there are only a few different source kinds. +The following source kinds are supported: + +- **remote**: A remote source is tainted data. This is the most common kind of source and sources of this kind is used for almost all taint tracking queries. +- **contentprovider**: ? +- **android-widget**: ? +- **android-external-storage-dir**: ? + +sinkModel(package, type, subtypes, name, signature, ext, input, kind, provenance) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Taint sink. As opposed to source kinds, there are many different kinds of sinks as these tend to be more query specific. + +- **package**: Name of the package where the sink resides. +- **type**: Name of the type where the sink resides. +- **subtypes**: Whether the sink should also apply to all overrides of the method. +- **name**: Name of the method where the sink resides. +- **signature**: Type signature of the method where the sink resides. +- **ext**: Specifies additional API-graph-like edges (mostly empty). +- **input**: Access path to the sink, where we want to check if possibly tainted data flows too. +- **kind**: Kind of the sink. +- **provenance**: Provenance (origin) of the sink. + +The following sink kinds are supported: + +- **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**: ? +- **read-file**: ? +- **write-file**: ? +- **set-hostname-verifier**: ? +- **header-splitting**: ? +- **information-leak**: ? +- **xslt**: ? +- **jexl**: ? +- **bean-validation**: ? +- **ssti**: ? +- **fragment-injection**: ? + +summaryModel(package, type, subtypes, name, signature, ext, input, output, kind, provenance) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +neutralModel(package, type, name, signature, provenance) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Access paths +------------ + +Provenance +---------- \ No newline at end of file From c6245360976608e4b6949cd2bfaaaeb091b17c5d Mon Sep 17 00:00:00 2001 From: Michael Nebel <michaelnebel@github.com> Date: Wed, 8 Mar 2023 11:43:03 +0100 Subject: [PATCH 417/631] Java: Summary flow reference material. --- .../customizing-library-models-for-java.rst | 41 +++++++++++++++---- 1 file changed, 32 insertions(+), 9 deletions(-) diff --git a/docs/codeql/codeql-language-guides/customizing-library-models-for-java.rst b/docs/codeql/codeql-language-guides/customizing-library-models-for-java.rst index 6e5201522f2..ffed10aa20c 100644 --- a/docs/codeql/codeql-language-guides/customizing-library-models-for-java.rst +++ b/docs/codeql/codeql-language-guides/customizing-library-models-for-java.rst @@ -38,7 +38,7 @@ The **Reference material** section will in more detail describe the *mini DSLs* Example: Taint sink in the **java.sql** package. ------------------------------------------------ -In this example we will see, how to define the argument passed to the **execute** method as a SQL injection sink. +In this example we will see, how to define the argument of the **execute** method as a SQL injection sink. This is the **execute** method in the **Statement** class, which is located in the 'java.sql' package. Please note that this sink is already added to the CodeQL Java analysis. @@ -46,7 +46,7 @@ Please note that this sink is already added to the CodeQL Java analysis. public static void taintsink(Connection conn, String query) throws SQLException { Statement stmt = conn.createStatement(); - stmt.execute(query); // The argument passed to this method is a SQL injection sink. + stmt.execute(query); // The argument to this method is a SQL injection sink. } This can be achieved by adding the following data extension. @@ -74,20 +74,20 @@ The first five values are used to identify the method (callable) which we are de For most practical purposes the sixth value is not relevant. The remaining values are used to define the **access path**, the **kind**, and the **provenance** (origin) of the sink. -- The seventh value **Argument[0]** is the access path to the first argument passed to the method, which means that this is the location of the sink. -- The eighth value **sql** is the kind of the sink. The sink kind is used to define for which queries the sink is in scope. +- The seventh value **Argument[0]** is the **access path** to the first argument passed to the method, which means that this is the location of the sink. +- The eighth value **sql** is the kind of the sink. The sink kind is used to define for which queries the sink is in scope. In this case SQL injection queries. - The ninth value **manual** is the provenance of the sink, which is used to identify the origin of the sink. Example: Taint source from the **java.net** package. ---------------------------------------------------- -In this example we will see, how to define the return value from the **getInputStream** method as a remote source. -This is the **getInputStream** method in the **Socket** class, which is located in the 'java.net' package. +In this example we will see, how to define the return value from the **getInputStream** method as a **remote** source. +This is the **getInputStream** method in the **Socket** class, which is located in the **java.net** package. Please note that this source is already added to the CodeQL Java analysis. .. code-block:: java public static InputStream tainted(Socket socket) throws IOException { - InputStream stream = socket.getInputStream(); // The return value of this method is a remote source. + InputStream stream = socket.getInputStream(); // The return value of this method is a remote source of taint. return stream; } @@ -207,17 +207,22 @@ These are the same for both of the rows above. For most practical purposes the sixth value is not relevant. The remaining values are used to define the **access path**, the **kind**, and the **provenance** (origin) of the source. + - The seventh value is the access path to the **input** where data flows from. - The eighth value **ReturnValue** is the access path to the **output** where data flows too. For the first row the + - The seventh value is **Argument[-1].Element**, which is the access path to the elements of the qualifier (the elements of the stream **s** in the example). - The eight value is **Argument[0].Paramter[0]**, which is the access path the first parameter of the **Function** argument of **map** (the lambda parameter **e** in the example). For the second row the + - The seventh value is **Argument[0].ReturnValue**, which is the access path to the return value of the **Function** argument of **map** (the return value of the lambda in the example). - The eighth value is **ReturnValue.Element**, which is the access path to the elements of the return value of **map** (the elements of the stream **l** in the example). +The remaining values for both rows + - The ninth value **value** is the kind of the flow. **value** means that the value is propagated. - The tenth value **manual** is the provenance of the source, which is used to identify the origin of the summary. @@ -283,7 +288,7 @@ Taint source. Most taint tracking queries will use the sources added to this ext - **ext**: Specifies additional API-graph-like edges (mostly empty). - **output**: Access path to the source, where the possibly tainted data flows from. - **kind**: Kind of the source. -- **provenance**: Provenance (origin) of the source. +- **provenance**: Provenance (origin) of the source definition. As most sources are used by all taint tracking queries there are only a few different source kinds. The following source kinds are supported: @@ -306,7 +311,7 @@ Taint sink. As opposed to source kinds, there are many different kinds of sinks - **ext**: Specifies additional API-graph-like edges (mostly empty). - **input**: Access path to the sink, where we want to check if possibly tainted data flows too. - **kind**: Kind of the sink. -- **provenance**: Provenance (origin) of the sink. +- **provenance**: Provenance (origin) of the sink definition. The following sink kinds are supported: @@ -340,6 +345,24 @@ The following sink kinds are supported: summaryModel(package, type, subtypes, name, signature, ext, input, output, kind, provenance) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Flow through. This extension point is used to model flow through methods. + +- **package**: Name of the package where the method resides. +- **type**: Name of the type where the method resides. +- **subtypes**: Whether the method should also apply to all overrides of the method. +- **name**: Name of the method where we are defining flow through. +- **signature**: Type signature of the method where we are defining flow through. +- **ext**: Specifies additional API-graph-like edges (mostly empty). +- **input**: Access path to the input of the method where data will flow to the output. +- **output**: Access path to the output of the method where data will flow from the input. +- **kind**: Kind of the flow through. +- **provenance**: Provenance (origin) of the flow through. + +The following kinds are supported: + +- **taint**: This means the output is not necessarily equal to the input, but it was derived from the input in an unrestrictive way. An attacker who controls the input will have significant control over the output as well. +- **value**: This means that the output equals the input or a copy of the input such that all of its properties are preserved. + neutralModel(package, type, name, signature, provenance) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ From 396e24cca780bb63236e21e37eb63481f63ed94e Mon Sep 17 00:00:00 2001 From: Michael Nebel <michaelnebel@github.com> Date: Wed, 8 Mar 2023 13:51:36 +0100 Subject: [PATCH 418/631] Java: Add documentation for access paths and provenance. --- .../customizing-library-models-for-java.rst | 71 +++++++++++++------ 1 file changed, 50 insertions(+), 21 deletions(-) diff --git a/docs/codeql/codeql-language-guides/customizing-library-models-for-java.rst b/docs/codeql/codeql-language-guides/customizing-library-models-for-java.rst index ffed10aa20c..200ec43c744 100644 --- a/docs/codeql/codeql-language-guides/customizing-library-models-for-java.rst +++ b/docs/codeql/codeql-language-guides/customizing-library-models-for-java.rst @@ -271,7 +271,23 @@ This includes descriptions of each of the arguments (eg. access paths, types, an Extension points ---------------- -Below is a description of the tuple values for each extension point. +Below is a description of the columns for each extension point. +Sources, Sinks, Summaries and Neutrals are commonly known as Models. +The semantics of many of the columns of the extension points are shared. + + +The shared columns are: + +- **package**: Name of the package. +- **type**: Name of the type. +- **subtypes**: A flag indicating whether the model should also apply to all overrides of the selected method(s). +- **name**: Name of the method (optional). If left blank, it means all methods matching the previous selction criteria. +- **signature**: Type signature of the method where the source resides (optional). If this is left blank it means all methods matching the previous selction criteria. +- **ext**: Specifies additional API-graph-like edges (mostly empty). +- **provenance**: Provenance (origin) of the model definition. + +The columns **package**, **type**, **subtypes**, **name**, and **signature** are used to select the method(s) that the model applies to. + The section Access paths describes in more detail, how access paths are composed. This is the most complicated part of the extension points and the **mini DSL** for access paths is shared accross the extension points. @@ -280,12 +296,6 @@ sourceModel(package, type, subtypes, name, signature, ext, output, kind, provena Taint source. Most taint tracking queries will use the sources added to this extensions point. -- **package**: Name of the package where the source resides. -- **type**: Name of the type where the source resides. -- **subtypes**: Whether the source should also apply to all overrides of the method. -- **name**: Name of the method where the source resides. -- **signature**: Type signature of the method where the source resides. -- **ext**: Specifies additional API-graph-like edges (mostly empty). - **output**: Access path to the source, where the possibly tainted data flows from. - **kind**: Kind of the source. - **provenance**: Provenance (origin) of the source definition. @@ -303,15 +313,8 @@ sinkModel(package, type, subtypes, name, signature, ext, input, kind, provenance Taint sink. As opposed to source kinds, there are many different kinds of sinks as these tend to be more query specific. -- **package**: Name of the package where the sink resides. -- **type**: Name of the type where the sink resides. -- **subtypes**: Whether the sink should also apply to all overrides of the method. -- **name**: Name of the method where the sink resides. -- **signature**: Type signature of the method where the sink resides. -- **ext**: Specifies additional API-graph-like edges (mostly empty). - **input**: Access path to the sink, where we want to check if possibly tainted data flows too. - **kind**: Kind of the sink. -- **provenance**: Provenance (origin) of the sink definition. The following sink kinds are supported: @@ -347,12 +350,6 @@ summaryModel(package, type, subtypes, name, signature, ext, input, output, kind, Flow through. This extension point is used to model flow through methods. -- **package**: Name of the package where the method resides. -- **type**: Name of the type where the method resides. -- **subtypes**: Whether the method should also apply to all overrides of the method. -- **name**: Name of the method where we are defining flow through. -- **signature**: Type signature of the method where we are defining flow through. -- **ext**: Specifies additional API-graph-like edges (mostly empty). - **input**: Access path to the input of the method where data will flow to the output. - **output**: Access path to the output of the method where data will flow from the input. - **kind**: Kind of the flow through. @@ -368,6 +365,38 @@ neutralModel(package, type, name, signature, provenance) Access paths ------------ +The **input**, and **output** columns consist of a **.**-separated list of components, which is evaluted from left to right, with each step selecting a new set of values derived from the previous set of values. + +The following components are supported: + +- **Argument[**\ `n`\ **]** selects the argument at index `n` (zero-indexed). +- **Argument[**\ `-1`\ **]** selects the qualifier of the call. +- **Argument[**\ `n1..n2`\ **]** selects the arguments in the given range (both ends included). +- **Parameter[**\ `n`\ **]** selects the parameter at index `n` (zero-indexed). +- **Parameter[**\ `n1..n2`\ **]** selects the parameters in the given range (both ends included). +- **ReturnValue** selects the return value. +- **Field[**\ `name`\ **]** selects the field with the fully qualified name `name`. +- **SyntheticField[**\ `name`\ **]** selects the synthetic field with name `name`. +- **ArrayElement** selects the elements of an array. +- **Element** selects the elements of a collection-like container. +- **MapKey** selects the element keys of a map. +- **MapValue** selects the element values of a map. Provenance ----------- \ No newline at end of file +---------- + +The **provenance** column is used to specify the provenance (origin) of the model definition. + +The following values are supported: + +- **manual**: The model was manually created (or verified by a human) and added to the extension point. +- **generated**: The model was generated by the model generator and added to the extension point. +- **ai-generated**: The model was generated by AI and added to the extension point. + +The provenance is used to distinguish between models that are manually added to the extension point and models that are automatically generated. +Furthermore, it impacts the dataflow analysis in the following way + +- A **manual** model takes precedence over **generated** models. If a **manual** model exist for a method then all generated models are ignored. +- A **generated** or **ai-generated** model is ignored during analysis, if the source code of the method they are modelling is available. + +That is, generated models are less trusted than manual models. From 68a7fc964608c7ac6e18fdb316eab76d4b8a1fca Mon Sep 17 00:00:00 2001 From: Michael Nebel <michaelnebel@github.com> Date: Wed, 8 Mar 2023 16:42:43 +0100 Subject: [PATCH 419/631] Java: Minor improvements on wording. --- .../customizing-library-models-for-java.rst | 93 ++++++++++--------- 1 file changed, 47 insertions(+), 46 deletions(-) diff --git a/docs/codeql/codeql-language-guides/customizing-library-models-for-java.rst b/docs/codeql/codeql-language-guides/customizing-library-models-for-java.rst index 200ec43c744..c168be6c879 100644 --- a/docs/codeql/codeql-language-guides/customizing-library-models-for-java.rst +++ b/docs/codeql/codeql-language-guides/customizing-library-models-for-java.rst @@ -5,7 +5,7 @@ Customizing Library Models for Java .. include:: ../reusables/beta-note-customizing-library-models.rst -The Java analysis can be customized by adding library models (summaries, sinks and sources) in data extensions files. +The Java analysis can be customized by adding library models (summaries, sinks and sources) in data extension files. A data extension file for Java is a YAML file in the form: @@ -31,15 +31,15 @@ TODO: Link or inline documentation on how to add dataextensions. Are we going for extensions packs as the recommended default? If yes, then we probably need to elaborate with a concrete example. -In the sections below, we will go through the different extension points using concrete examples. -The extension points are used to customize and improve the existing dataflow queries, by providing sources, sinks and flow through for library methods. +In the sections below, we will show by example how to add tuples to the different extension points. +The extension points are used to customize and improve the existing dataflow queries, by providing sources, sinks, and flow through for library elements. The **Reference material** section will in more detail describe the *mini DSLs* that are used to comprise a model definition for each extension point. Example: Taint sink in the **java.sql** package. ------------------------------------------------ In this example we will see, how to define the argument of the **execute** method as a SQL injection sink. -This is the **execute** method in the **Statement** class, which is located in the 'java.sql' package. +This is the **execute** method in the **Statement** class, which is located in the **java.sql** package. Please note that this sink is already added to the CodeQL Java analysis. .. code-block:: java @@ -75,7 +75,7 @@ For most practical purposes the sixth value is not relevant. The remaining values are used to define the **access path**, the **kind**, and the **provenance** (origin) of the sink. - The seventh value **Argument[0]** is the **access path** to the first argument passed to the method, which means that this is the location of the sink. -- The eighth value **sql** is the kind of the sink. The sink kind is used to define for which queries the sink is in scope. In this case SQL injection queries. +- The eighth value **sql** is the kind of the sink. The sink kind is used to define the queries where the sink is in scope. In this case - the SQL injection queries. - The ninth value **manual** is the provenance of the sink, which is used to identify the origin of the sink. Example: Taint source from the **java.net** package. @@ -116,12 +116,12 @@ The first five values are used to identify the method (callable) which we are de For most practical purposes the sixth value is not relevant. The remaining values are used to define the **access path**, the **kind**, and the **provenance** (origin) of the source. -- The seventh value **ReturnValue** is the access path to the return of the method, which means that it is the return value that should be considered a tainted source. -- The eighth value **remote** is the kind of the source. The source kind is used to define for which queries the source is in scope. **remote** applies to many of security related queries as it means a remote source of untrusted data. As an example the SQL injection query uses **remote** sources. +- The seventh value **ReturnValue** is the access path to the return of the method, which means that it is the return value that should be considered a source of tainted input. +- The eighth value **remote** is the kind of the source. The source kind is used to define the queries where the source is in scope. **remote** applies to many of security related queries as it means a remote source of untrusted data. As an example the SQL injection query uses **remote** sources. - The ninth value **manual** is the provenance of the source, which is used to identify the origin of the source. -Example: Adding flow through the **concat** method. ---------------------------------------------------- +Example: Add flow through the **concat** method. +------------------------------------------------ In this example we will see, how to define flow through a method for a simple case. This pattern covers many of the cases where we need to define flow through a method. Please note that the flow through the **concat** method is already added to the CodeQL Java analysis. @@ -150,26 +150,28 @@ Reasoning: Since we are adding flow through a method, we need to add tuples to the **summaryModel** extension point. Each tuple defines flow from one argument to the return value. -The first five values are used to identify the method (callable) which we are defining a source on. -These are the same for both of the rows above. +The first row defines flow from the qualifier (**s1** in the example) to the return value (**t** in the example) and the second row defines flow from the first argument (**s2** in the example) to the return value (**t** in the example). + +The first five values are used to identify the method (callable) which we are defining a summary for. +These are the same for both of the rows above as we are adding two summaries for the same method. - The first value **java.lang** is the package name. - The second value **String** is the class (type) name. -- The third value **False** is flag indicating, whether the source also applies to all overrides of the method. +- The third value **False** is flag indicating, whether the summary also applies to all overrides of the method. - The fourth value **concat** is the method name. - The fifth value **(String)** is the method input type signature. For most practical purposes the sixth value is not relevant. -The remaining values are used to define the **access path**, the **kind**, and the **provenance** (origin) of the source. +The remaining values are used to define the **access path**, the **kind**, and the **provenance** (origin) of the summary. -- The seventh value is the access path to the input where data flows from. **Argument[-1]** is the access path to the qualifier (**s1** in the example) and **Argument[0]** is the access path to the first argument (**s2** in the example). -- The eighth value **ReturnValue** is the access path to the output where data flows too, in this case **ReturnValue**, which means that the input flows to the return value. +- The seventh value is the access path to the input (where data flows from). **Argument[-1]** is the access path to the qualifier (**s1** in the example) and **Argument[0]** is the access path to the first argument (**s2** in the example). +- The eighth value **ReturnValue** is the access path to the output (where data flows to), in this case **ReturnValue**, which means that the input flows to the return value. - The ninth value **taint** is the kind of the flow. **taint** means that taint is propagated through the flow. -- The tenth value **manual** is the provenance of the source, which is used to identify the origin of the summary. +- The tenth value **manual** is the provenance of the summary, which is used to identify the origin of the summary. Example: Add flow through the **map** method. --------------------------------------------- -In this example will will see a more complex example of modelling flow through a method. +In this example, we will see a more complex example of modelling flow through a method. This pattern shows how to model flow through higher order methods and collection types. Please note that the flow through the **map** method is already added to the CodeQL Java analysis. @@ -195,21 +197,21 @@ This can be achieved by adding the following data extension. Reasoning: Since we are adding flow through a method, we need to add tuples to the **summaryModel** extension point. -Each tuple defines part of the flow that comprises the total flow through the method. -The first five values are used to identify the method (callable) which we are defining a source on. -These are the same for both of the rows above. +Each tuple defines part of the flow that comprises the total flow through the **map** method. +The first five values are used to identify the method (callable) which we are defining a summary for. +These are the same for both of the rows above as we are adding two summaries for the same method. - The first value **java.util.stream** is the package name. - The second value **Stream** is the class (type) name. -- The third value **True** is flag indicating, whether the source also applies to all overrides of the method. +- The third value **True** is flag indicating, whether the summary also applies to all overrides of the method. - The fourth value **map** is the method name. - The fifth value **Function** is the method input type signature. For most practical purposes the sixth value is not relevant. -The remaining values are used to define the **access path**, the **kind**, and the **provenance** (origin) of the source. +The remaining values are used to define the **access path**, the **kind**, and the **provenance** (origin) of the summary definition. -- The seventh value is the access path to the **input** where data flows from. -- The eighth value **ReturnValue** is the access path to the **output** where data flows too. +- The seventh value is the access path to the **input** (where data flows from). +- The eighth value **ReturnValue** is the access path to the **output** (where data flows to). For the first row the @@ -223,13 +225,13 @@ For the second row the The remaining values for both rows -- The ninth value **value** is the kind of the flow. **value** means that the value is propagated. -- The tenth value **manual** is the provenance of the source, which is used to identify the origin of the summary. +- The ninth value **value** is the kind of the flow. **value** means that the value is preserved. +- The tenth value **manual** is the provenance of the summary, which is used to identify the origin of the summary. -That is, the first row models that there is value flow from the elements of qualifier stream into the first argument of the Function provided to **map** and the second row models that there is value flow from the return value of the Function to the elements of the stream returned from **map**. +That is, the first row models that there is value flow from the elements of the qualifier stream into the first argument of the Function provided to **map** and the second row models that there is value flow from the return value of the Function to the elements of the stream returned from **map**. -Example: Adding **neutral** methods. ------------------------------------- +Example: Add a **neutral** method. +---------------------------------- In this example we will see, how to define the **now** method as being neutral. This is purely for consistency and has no impact on the analysis. A neutral model is used to define that there is no flow through a method. @@ -266,7 +268,7 @@ Reference material ------------------ The following sections provide reference material for extension points. -This includes descriptions of each of the arguments (eg. access paths, types, and kinds). +This includes descriptions of each of the arguments (eg. access paths, kinds and provenance). Extension points ---------------- @@ -275,18 +277,17 @@ Below is a description of the columns for each extension point. Sources, Sinks, Summaries and Neutrals are commonly known as Models. The semantics of many of the columns of the extension points are shared. - The shared columns are: - **package**: Name of the package. - **type**: Name of the type. -- **subtypes**: A flag indicating whether the model should also apply to all overrides of the selected method(s). -- **name**: Name of the method (optional). If left blank, it means all methods matching the previous selction criteria. -- **signature**: Type signature of the method where the source resides (optional). If this is left blank it means all methods matching the previous selction criteria. -- **ext**: Specifies additional API-graph-like edges (mostly empty). +- **subtypes**: A flag indicating whether the model should also apply to all overrides of the selected element(s). +- **name**: Name of the element (optional). If this is left blank, it means all elements matching the previous selection criteria. +- **signature**: Type signature of the selected element (optional). If this is left blank it means all elements matching the previous selection criteria. +- **ext**: Specifies additional API-graph-like edges (mostly empty) and out of scope for this document. - **provenance**: Provenance (origin) of the model definition. -The columns **package**, **type**, **subtypes**, **name**, and **signature** are used to select the method(s) that the model applies to. +The columns **package**, **type**, **subtypes**, **name**, and **signature** are used to select the element(s) that the model applies to. The section Access paths describes in more detail, how access paths are composed. This is the most complicated part of the extension points and the **mini DSL** for access paths is shared accross the extension points. @@ -294,7 +295,7 @@ This is the most complicated part of the extension points and the **mini DSL** f sourceModel(package, type, subtypes, name, signature, ext, output, kind, provenance) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Taint source. Most taint tracking queries will use the sources added to this extensions point. +Taint source. Most taint tracking queries will use the all sources added to this extensions point regardless of their kind. - **output**: Access path to the source, where the possibly tainted data flows from. - **kind**: Kind of the source. @@ -303,7 +304,7 @@ Taint source. Most taint tracking queries will use the sources added to this ext As most sources are used by all taint tracking queries there are only a few different source kinds. The following source kinds are supported: -- **remote**: A remote source is tainted data. This is the most common kind of source and sources of this kind is used for almost all taint tracking queries. +- **remote**: A remote source of possibly tainted data. This is the most common kind for a source. Sources of this kind is used for almost all taint tracking queries. - **contentprovider**: ? - **android-widget**: ? - **android-external-storage-dir**: ? @@ -313,7 +314,7 @@ sinkModel(package, type, subtypes, name, signature, ext, input, kind, provenance Taint sink. As opposed to source kinds, there are many different kinds of sinks as these tend to be more query specific. -- **input**: Access path to the sink, where we want to check if possibly tainted data flows too. +- **input**: Access path to the sink, where we want to check if tainted data can flow to. - **kind**: Kind of the sink. The following sink kinds are supported: @@ -348,10 +349,10 @@ The following sink kinds are supported: summaryModel(package, type, subtypes, name, signature, ext, input, output, kind, provenance) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Flow through. This extension point is used to model flow through methods. +Flow through. This extension point is used to model flow through elements. -- **input**: Access path to the input of the method where data will flow to the output. -- **output**: Access path to the output of the method where data will flow from the input. +- **input**: Access path to the input of the element (where data will flow to the output). +- **output**: Access path to the output of the element (where data will flow from the input). - **kind**: Kind of the flow through. - **provenance**: Provenance (origin) of the flow through. @@ -370,7 +371,7 @@ The **input**, and **output** columns consist of a **.**-separated list of compo The following components are supported: - **Argument[**\ `n`\ **]** selects the argument at index `n` (zero-indexed). -- **Argument[**\ `-1`\ **]** selects the qualifier of the call. +- **Argument[**\ `-1`\ **]** selects the qualifier. - **Argument[**\ `n1..n2`\ **]** selects the arguments in the given range (both ends included). - **Parameter[**\ `n`\ **]** selects the parameter at index `n` (zero-indexed). - **Parameter[**\ `n1..n2`\ **]** selects the parameters in the given range (both ends included). @@ -396,7 +397,7 @@ The following values are supported: The provenance is used to distinguish between models that are manually added to the extension point and models that are automatically generated. Furthermore, it impacts the dataflow analysis in the following way -- A **manual** model takes precedence over **generated** models. If a **manual** model exist for a method then all generated models are ignored. -- A **generated** or **ai-generated** model is ignored during analysis, if the source code of the method they are modelling is available. +- A **manual** model takes precedence over **generated** models. If a **manual** model exist for an element then all generated models are ignored. +- A **generated** or **ai-generated** model is ignored during analysis, if the source code of the element it is modelling is available. -That is, generated models are less trusted than manual models. +That is, generated models are less trusted than manual models and only used if neither source code or a manual model is available. From 9e49daa57a474027ade6162e9791018b7eedb803 Mon Sep 17 00:00:00 2001 From: Michael Nebel <michaelnebel@github.com> Date: Thu, 9 Mar 2023 10:23:30 +0100 Subject: [PATCH 420/631] Apply suggestions from code review Co-authored-by: Andrew Eisenberg <aeisenberg@github.com> --- .../codeql-for-java.rst | 1 - .../customizing-library-models-for-java.rst | 39 +++++++++++-------- 2 files changed, 22 insertions(+), 18 deletions(-) diff --git a/docs/codeql/codeql-language-guides/codeql-for-java.rst b/docs/codeql/codeql-language-guides/codeql-for-java.rst index 031f1b07220..adbffe1f347 100644 --- a/docs/codeql/codeql-language-guides/codeql-for-java.rst +++ b/docs/codeql/codeql-language-guides/codeql-for-java.rst @@ -25,7 +25,6 @@ Experiment and learn how to write effective and efficient queries for CodeQL dat javadoc working-with-source-locations abstract-syntax-tree-classes-for-working-with-java-programs - customizing-library-models-for-java - :doc:`Basic query for Java code <basic-query-for-java-code>`: Learn to write and run a simple CodeQL query. diff --git a/docs/codeql/codeql-language-guides/customizing-library-models-for-java.rst b/docs/codeql/codeql-language-guides/customizing-library-models-for-java.rst index c168be6c879..b2a35a8ab8f 100644 --- a/docs/codeql/codeql-language-guides/customizing-library-models-for-java.rst +++ b/docs/codeql/codeql-language-guides/customizing-library-models-for-java.rst @@ -1,5 +1,8 @@ .. _customizing-library-models-for-java: +:orphan: +:nosearch: + Customizing Library Models for Java =================================== @@ -14,13 +17,15 @@ A data extension file for Java is a YAML file in the form: extensions: - addsTo: pack: codeql/java-all - extensible: <name of extension point> + extensible: <name of extensible predicate> data: - <tuple1> - <tuple2> - ... -The data extension can contribute to the following extension points: +Data extensions contribute to extensible predicates defined CodeQL libraries. For more information on how to define data extensions and extensible predicates as well as how to wire them up, see the following documentation... + +The CodeQL libraries for Java expose the following extensible predicates: - **sourceModel**\(package, type, subtypes, name, signature, ext, output, kind, provenance) - **sinkModel**\(package, type, subtypes, name, signature, ext, input, kind, provenance) @@ -31,14 +36,14 @@ TODO: Link or inline documentation on how to add dataextensions. Are we going for extensions packs as the recommended default? If yes, then we probably need to elaborate with a concrete example. -In the sections below, we will show by example how to add tuples to the different extension points. +In the sections below, we will show by example how to add tuples to the different extensible predicates. The extension points are used to customize and improve the existing dataflow queries, by providing sources, sinks, and flow through for library elements. -The **Reference material** section will in more detail describe the *mini DSLs* that are used to comprise a model definition for each extension point. +The **Reference material** section will provide details on the *mini DSLs* that define models for each extensible predicate. Example: Taint sink in the **java.sql** package. ------------------------------------------------ -In this example we will see, how to define the argument of the **execute** method as a SQL injection sink. +In this example we will show how to model the argument of the **execute** method as a SQL injection sink. This is the **execute** method in the **Statement** class, which is located in the **java.sql** package. Please note that this sink is already added to the CodeQL Java analysis. @@ -49,7 +54,7 @@ Please note that this sink is already added to the CodeQL Java analysis. stmt.execute(query); // The argument to this method is a SQL injection sink. } -This can be achieved by adding the following data extension. +This can be achieved by adding the following row to a data extension file: .. code-block:: yaml @@ -63,11 +68,11 @@ This can be achieved by adding the following data extension. Reasoning: Since we are adding a new sink, we need to add a tuple to the **sinkModel** extension point. -The first five values are used to identify the method (callable) which we are defining a sink on. +The first five values identify the callable (in this case a method) to be modeled as a sink. - The first value **java.sql** is the package name. -- The second value **Statement** is the class (type) name. -- The third value **True** is flag indicating, whether the sink also applies to all overrides of the method. +- The second value **Statement** is the name of the class (type) that contains the method. +- The third value **True** is a flag that indicates, whether or not the sink also applies to all overrides of the method. - The fourth value **execute** is the method name. - The fifth value **(String)** is the method input type signature. @@ -80,7 +85,7 @@ The remaining values are used to define the **access path**, the **kind**, and t Example: Taint source from the **java.net** package. ---------------------------------------------------- -In this example we will see, how to define the return value from the **getInputStream** method as a **remote** source. +In this example we show how to model the return value from the **getInputStream** method as a **remote** source. This is the **getInputStream** method in the **Socket** class, which is located in the **java.net** package. Please note that this source is already added to the CodeQL Java analysis. @@ -108,8 +113,8 @@ Since we are adding a new source, we need to add a tuple to the **sourceModel** The first five values are used to identify the method (callable) which we are defining a source on. - The first value **java.net** is the package name. -- The second value **Socket** is the class (type) name. -- The third value **False** is flag indicating, whether the source also applies to all overrides of the method. +- The second value **Socket** is the name of the class (type) that contains the source. +- The third value **False** flag indicates, whether or not the source also applies to all overrides of the method. - The fourth value **getInputStream** is the method name. - The fifth value **()** is the method input type signature. @@ -122,7 +127,7 @@ The remaining values are used to define the **access path**, the **kind**, and t Example: Add flow through the **concat** method. ------------------------------------------------ -In this example we will see, how to define flow through a method for a simple case. +In this example we show how to model flow through a method for a simple case. This pattern covers many of the cases where we need to define flow through a method. Please note that the flow through the **concat** method is already added to the CodeQL Java analysis. @@ -280,8 +285,8 @@ The semantics of many of the columns of the extension points are shared. The shared columns are: - **package**: Name of the package. -- **type**: Name of the type. -- **subtypes**: A flag indicating whether the model should also apply to all overrides of the selected element(s). +- **type**: Name of the type containing the element to be modeled. +- **subtypes**: A boolean flag indicating whether the model should also apply to all overrides of the selected element(s). - **name**: Name of the element (optional). If this is left blank, it means all elements matching the previous selection criteria. - **signature**: Type signature of the selected element (optional). If this is left blank it means all elements matching the previous selection criteria. - **ext**: Specifies additional API-graph-like edges (mostly empty) and out of scope for this document. @@ -289,8 +294,8 @@ The shared columns are: The columns **package**, **type**, **subtypes**, **name**, and **signature** are used to select the element(s) that the model applies to. -The section Access paths describes in more detail, how access paths are composed. -This is the most complicated part of the extension points and the **mini DSL** for access paths is shared accross the extension points. +The Access Paths section describes how access paths are composed. +This is the most complicated part of the extension points and the **mini DSL** for access paths is shared across all extension points. sourceModel(package, type, subtypes, name, signature, ext, output, kind, provenance) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ From ce162ce5d49c5353a5035fea819c911b86ea8480 Mon Sep 17 00:00:00 2001 From: Michael Nebel <michaelnebel@github.com> Date: Thu, 9 Mar 2023 10:38:03 +0100 Subject: [PATCH 421/631] Java: Address review comments. --- .../customizing-library-models-for-java.rst | 155 +++++++++--------- docs/codeql/reusables/data-extensions.rst | 4 + 2 files changed, 86 insertions(+), 73 deletions(-) create mode 100644 docs/codeql/reusables/data-extensions.rst diff --git a/docs/codeql/codeql-language-guides/customizing-library-models-for-java.rst b/docs/codeql/codeql-language-guides/customizing-library-models-for-java.rst index b2a35a8ab8f..531a9a8691c 100644 --- a/docs/codeql/codeql-language-guides/customizing-library-models-for-java.rst +++ b/docs/codeql/codeql-language-guides/customizing-library-models-for-java.rst @@ -23,7 +23,7 @@ A data extension file for Java is a YAML file in the form: - <tuple2> - ... -Data extensions contribute to extensible predicates defined CodeQL libraries. For more information on how to define data extensions and extensible predicates as well as how to wire them up, see the following documentation... +Data extensions contribute to extensible predicates defined CodeQL libraries. For more information on how to define data extensions and extensible predicates as well as how to wire them up, see the :ref:`data-extensions` documentation. The CodeQL libraries for Java expose the following extensible predicates: @@ -32,13 +32,11 @@ The CodeQL libraries for Java expose the following extensible predicates: - **summaryModel**\(package, type, subtypes, name, signature, ext, input, output, kind, provenance) - **neutralModel**\(package, type, name, signature, provenance) -TODO: Link or inline documentation on how to add dataextensions. -Are we going for extensions packs as the recommended default? -If yes, then we probably need to elaborate with a concrete example. +The extensible predicates are populated using data extensions specified in YAML files. In the sections below, we will show by example how to add tuples to the different extensible predicates. -The extension points are used to customize and improve the existing dataflow queries, by providing sources, sinks, and flow through for library elements. -The **Reference material** section will provide details on the *mini DSLs* that define models for each extensible predicate. +The extensible predicates are used to customize and improve the existing data flow queries, by providing sources, sinks, and flow through (summaries) for library elements. +The :ref:`reference-material` section will provide details on the *mini DSLs* that define models for each extensible predicate. Example: Taint sink in the **java.sql** package. ------------------------------------------------ @@ -67,12 +65,12 @@ This can be achieved by adding the following row to a data extension file: Reasoning: -Since we are adding a new sink, we need to add a tuple to the **sinkModel** extension point. +Since we are adding a new sink, we need to add a tuple to the **sinkModel** extensible predicate. The first five values identify the callable (in this case a method) to be modeled as a sink. - The first value **java.sql** is the package name. - The second value **Statement** is the name of the class (type) that contains the method. -- The third value **True** is a flag that indicates, whether or not the sink also applies to all overrides of the method. +- The third value **True** is a flag that indicates whether or not the sink also applies to all overrides of the method. - The fourth value **execute** is the method name. - The fifth value **(String)** is the method input type signature. @@ -91,30 +89,30 @@ Please note that this source is already added to the CodeQL Java analysis. .. code-block:: java - public static InputStream tainted(Socket socket) throws IOException { + public static void tainted(Socket socket) throws IOException { InputStream stream = socket.getInputStream(); // The return value of this method is a remote source of taint. - return stream; + ... } This can be achieved by adding the following data extension. .. code-block:: yaml - extensions: - - addsTo: - pack: codeql/java-all - extensible: sourceModel - data: - - ["java.net", "Socket", False, "getInputStream", "()", "", "ReturnValue", "remote", "manual"] + extensions: + - addsTo: + pack: codeql/java-all + extensible: sourceModel + data: + - ["java.net", "Socket", False, "getInputStream", "()", "", "ReturnValue", "remote", "manual"] Reasoning: -Since we are adding a new source, we need to add a tuple to the **sourceModel** extension point. -The first five values are used to identify the method (callable) which we are defining a source on. +Since we are adding a new source, we need to add a tuple to the **sourceModel** extensible predicate. +The first five values identify the callable (in this case a method) to be modeled as a source. - The first value **java.net** is the package name. - The second value **Socket** is the name of the class (type) that contains the source. -- The third value **False** flag indicates, whether or not the source also applies to all overrides of the method. +- The third value **False** flag indicates whether or not the source also applies to all overrides of the method. - The fourth value **getInputStream** is the method name. - The fifth value **()** is the method input type signature. @@ -122,7 +120,7 @@ For most practical purposes the sixth value is not relevant. The remaining values are used to define the **access path**, the **kind**, and the **provenance** (origin) of the source. - The seventh value **ReturnValue** is the access path to the return of the method, which means that it is the return value that should be considered a source of tainted input. -- The eighth value **remote** is the kind of the source. The source kind is used to define the queries where the source is in scope. **remote** applies to many of security related queries as it means a remote source of untrusted data. As an example the SQL injection query uses **remote** sources. +- The eighth value **remote** is the kind of the source. The source kind is used to define the queries where the source is in scope. **remote** applies to many of the security related queries as it means a remote source of untrusted data. As an example the SQL injection query uses **remote** sources. - The ninth value **manual** is the provenance of the source, which is used to identify the origin of the source. Example: Add flow through the **concat** method. @@ -133,9 +131,9 @@ Please note that the flow through the **concat** method is already added to the .. code-block:: java - public static String taintflow(String s1, String s2) { + public static void taintflow(String s1, String s2) { String t = s1.concat(s2); // There is taint flow from s1 and s2 to t. - return t; + ... } This can be achieved by adding the following data extension. @@ -144,25 +142,25 @@ These are widely known as summary models. .. code-block:: yaml extensions: - - addsTo: - pack: codeql/java-all - extensible: summaryModel - data: - - ["java.lang", "String", False, "concat", "(String)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] - - ["java.lang", "String", False, "concat", "(String)", "", "Argument[0]", "ReturnValue", "taint", "manual"] + - addsTo: + pack: codeql/java-all + extensible: summaryModel + data: + - ["java.lang", "String", False, "concat", "(String)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["java.lang", "String", False, "concat", "(String)", "", "Argument[0]", "ReturnValue", "taint", "manual"] Reasoning: -Since we are adding flow through a method, we need to add tuples to the **summaryModel** extension point. +Since we are adding flow through a method, we need to add tuples to the **summaryModel** extensible predicate. Each tuple defines flow from one argument to the return value. The first row defines flow from the qualifier (**s1** in the example) to the return value (**t** in the example) and the second row defines flow from the first argument (**s2** in the example) to the return value (**t** in the example). -The first five values are used to identify the method (callable) which we are defining a summary for. +The first five values are used to identify the callable (in this case a method) which we are defining a summary for. These are the same for both of the rows above as we are adding two summaries for the same method. - The first value **java.lang** is the package name. - The second value **String** is the class (type) name. -- The third value **False** is flag indicating, whether the summary also applies to all overrides of the method. +- The third value **False** is a flag indicating whether the summary also applies to all overrides of the method. - The fourth value **concat** is the method name. - The fifth value **(String)** is the method input type signature. @@ -171,7 +169,7 @@ The remaining values are used to define the **access path**, the **kind**, and t - The seventh value is the access path to the input (where data flows from). **Argument[-1]** is the access path to the qualifier (**s1** in the example) and **Argument[0]** is the access path to the first argument (**s2** in the example). - The eighth value **ReturnValue** is the access path to the output (where data flows to), in this case **ReturnValue**, which means that the input flows to the return value. -- The ninth value **taint** is the kind of the flow. **taint** means that taint is propagated through the flow. +- The ninth value **taint** is the kind of the flow. **taint** means that taint is propagated through the call. - The tenth value **manual** is the provenance of the summary, which is used to identify the origin of the summary. Example: Add flow through the **map** method. @@ -182,9 +180,9 @@ Please note that the flow through the **map** method is already added to the Cod .. code-block:: java - public static Stream<String> taintflow(Stream<String> s) { + public static void taintflow(Stream<String> s) { Stream<String> l = s.map(e -> e.concat("\n")); - return l; + ... } This can be achieved by adding the following data extension. @@ -192,23 +190,23 @@ This can be achieved by adding the following data extension. .. code-block:: yaml extensions: - - addsTo: - pack: codeql/java-all - extensible: summaryModel - data: - - ["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"] + - addsTo: + pack: codeql/java-all + extensible: summaryModel + data: + - ["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"] Reasoning: -Since we are adding flow through a method, we need to add tuples to the **summaryModel** extension point. +Since we are adding flow through a method, we need to add tuples to the **summaryModel** extensible predicate. Each tuple defines part of the flow that comprises the total flow through the **map** method. -The first five values are used to identify the method (callable) which we are defining a summary for. +The first five values identify the callable (in this case a method) to be modeled as a summary. These are the same for both of the rows above as we are adding two summaries for the same method. - The first value **java.util.stream** is the package name. - The second value **Stream** is the class (type) name. -- The third value **True** is flag indicating, whether the summary also applies to all overrides of the method. +- The third value **True** is a flag indicating whether the summary also applies to all overrides of the method. - The fourth value **map** is the method name. - The fifth value **Function** is the method input type signature. @@ -216,12 +214,12 @@ For most practical purposes the sixth value is not relevant. The remaining values are used to define the **access path**, the **kind**, and the **provenance** (origin) of the summary definition. - The seventh value is the access path to the **input** (where data flows from). -- The eighth value **ReturnValue** is the access path to the **output** (where data flows to). +- The eighth value is the access path to the **output** (where data flows to). For the first row the - The seventh value is **Argument[-1].Element**, which is the access path to the elements of the qualifier (the elements of the stream **s** in the example). -- The eight value is **Argument[0].Paramter[0]**, which is the access path the first parameter of the **Function** argument of **map** (the lambda parameter **e** in the example). +- The eight value is **Argument[0].Parameter[0]**, which is the access path to the first parameter of the **Function** argument of **map** (the lambda parameter **e** in the example). For the second row the @@ -237,16 +235,16 @@ That is, the first row models that there is value flow from the elements of the Example: Add a **neutral** method. ---------------------------------- -In this example we will see, how to define the **now** method as being neutral. +In this example we will show how to model the **now** method as being neutral. This is purely for consistency and has no impact on the analysis. A neutral model is used to define that there is no flow through a method. Please note that the neutral model for the **now** method is already added. .. code-block:: java - public static Instant taintflow() { + public static void taintflow() { Instant t = Instant.now(); // There is no flow from now to t. - return t; + ... } .. code-block:: yaml @@ -260,8 +258,8 @@ Please note that the neutral model for the **now** method is already added. Reasoning: -Since we are adding a neutral model, we need to add tuples to the **neutralModel** extension point. -The first four values are used to identify the method (callable) which we are defining as a neutral and the fifth value is the provenance (origin) of the neutral. +Since we are adding a neutral model, we need to add tuples to the **neutralModel** extensible predicate. +The first five values identify the callable (in this case a method) to be modeled as a neutral and the fifth value is the provenance (origin) of the neutral. - The first value **java.time** is the package name. - The second value **Instant** is the class (type) name. @@ -269,23 +267,25 @@ The first four values are used to identify the method (callable) which we are de - The fourth value **()** is the method input type signature. - The fifth value **manual** is the provenance of the neutral. +.. _reference-material: + Reference material ------------------ -The following sections provide reference material for extension points. +The following sections provide reference material for extensible predicates. This includes descriptions of each of the arguments (eg. access paths, kinds and provenance). -Extension points ----------------- +Extensible predicates +--------------------- -Below is a description of the columns for each extension point. +Below is a description of the columns for each extensible predicate. Sources, Sinks, Summaries and Neutrals are commonly known as Models. -The semantics of many of the columns of the extension points are shared. +The semantics of many of the columns of the extensible predicates are shared. The shared columns are: -- **package**: Name of the package. -- **type**: Name of the type containing the element to be modeled. +- **package**: Name of the package containing the element(s) to be modeled. +- **type**: Name of the type containing the element(s) to be modeled. - **subtypes**: A boolean flag indicating whether the model should also apply to all overrides of the selected element(s). - **name**: Name of the element (optional). If this is left blank, it means all elements matching the previous selection criteria. - **signature**: Type signature of the selected element (optional). If this is left blank it means all elements matching the previous selection criteria. @@ -294,13 +294,13 @@ The shared columns are: The columns **package**, **type**, **subtypes**, **name**, and **signature** are used to select the element(s) that the model applies to. -The Access Paths section describes how access paths are composed. -This is the most complicated part of the extension points and the **mini DSL** for access paths is shared across all extension points. +The :ref:`access-paths` section describes how access paths are composed. +This is the most complicated part of the extensible predicates and the **mini DSL** for access paths is shared across all extensible predicates. sourceModel(package, type, subtypes, name, signature, ext, output, kind, provenance) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Taint source. Most taint tracking queries will use the all sources added to this extensions point regardless of their kind. +Taint source. Most taint tracking queries will use all sources added to this extensible predicate regardless of their kind. - **output**: Access path to the source, where the possibly tainted data flows from. - **kind**: Kind of the source. @@ -309,7 +309,7 @@ Taint source. Most taint tracking queries will use the all sources added to this As most sources are used by all taint tracking queries there are only a few different source kinds. The following source kinds are supported: -- **remote**: A remote source of possibly tainted data. This is the most common kind for a source. Sources of this kind is used for almost all taint tracking queries. +- **remote**: A remote source of possibly tainted data. This is the most common kind for a source. Sources of this kind are used for almost all taint tracking queries. - **contentprovider**: ? - **android-widget**: ? - **android-external-storage-dir**: ? @@ -319,7 +319,7 @@ sinkModel(package, type, subtypes, name, signature, ext, input, kind, provenance Taint sink. As opposed to source kinds, there are many different kinds of sinks as these tend to be more query specific. -- **input**: Access path to the sink, where we want to check if tainted data can flow to. +- **input**: Access path to the sink, where we want to check if tainted data can flow into. - **kind**: Kind of the sink. The following sink kinds are supported: @@ -354,10 +354,10 @@ The following sink kinds are supported: summaryModel(package, type, subtypes, name, signature, ext, input, output, kind, provenance) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Flow through. This extension point is used to model flow through elements. +Flow through (summary). This extensible predicate is used to model flow through elements. -- **input**: Access path to the input of the element (where data will flow to the output). -- **output**: Access path to the output of the element (where data will flow from the input). +- **input**: Access path to the input of the element (where data will flow from to the output). +- **output**: Access path to the output of the element (where data will flow to from the input). - **kind**: Kind of the flow through. - **provenance**: Provenance (origin) of the flow through. @@ -369,14 +369,20 @@ The following kinds are supported: neutralModel(package, type, name, signature, provenance) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +No flow. This extensible predicate is used to model elements without flow. + +- **provenance**: Provenance (origin) of the flow through. + +.. _access-paths: + Access paths ------------ -The **input**, and **output** columns consist of a **.**-separated list of components, which is evaluted from left to right, with each step selecting a new set of values derived from the previous set of values. +The **input**, and **output** columns consist of a **.**-separated list of components, which is evaluated from left to right, with each step selecting a new set of values derived from the previous set of values. The following components are supported: - **Argument[**\ `n`\ **]** selects the argument at index `n` (zero-indexed). -- **Argument[**\ `-1`\ **]** selects the qualifier. +- **Argument[**\ `-1`\ **]** selects the qualifier (instance parameter). - **Argument[**\ `n1..n2`\ **]** selects the arguments in the given range (both ends included). - **Parameter[**\ `n`\ **]** selects the parameter at index `n` (zero-indexed). - **Parameter[**\ `n1..n2`\ **]** selects the parameters in the given range (both ends included). @@ -395,14 +401,17 @@ The **provenance** column is used to specify the provenance (origin) of the mode The following values are supported: -- **manual**: The model was manually created (or verified by a human) and added to the extension point. -- **generated**: The model was generated by the model generator and added to the extension point. -- **ai-generated**: The model was generated by AI and added to the extension point. +- **manual**: The model was manually created (or verified by a human) and added to the extensible predicate. +- **generated**: The model was generated by the model generator and added to the extensible predicate. +- **ai-generated**: The model was generated by AI and added to the extensible predicate. -The provenance is used to distinguish between models that are manually added to the extension point and models that are automatically generated. -Furthermore, it impacts the dataflow analysis in the following way +The provenance is used to distinguish between models that are manually added to the extensible predicate and models that are automatically generated. +Furthermore, it impacts the data flow analysis in the following way -- A **manual** model takes precedence over **generated** models. If a **manual** model exist for an element then all generated models are ignored. +- A **manual** model takes precedence over **generated** models. If a **manual** model exists for an element then all generated models are ignored. - A **generated** or **ai-generated** model is ignored during analysis, if the source code of the element it is modelling is available. That is, generated models are less trusted than manual models and only used if neither source code or a manual model is available. + + +.. include:: ../reusables/data-extensions.rst \ No newline at end of file diff --git a/docs/codeql/reusables/data-extensions.rst b/docs/codeql/reusables/data-extensions.rst new file mode 100644 index 00000000000..ad46738036c --- /dev/null +++ b/docs/codeql/reusables/data-extensions.rst @@ -0,0 +1,4 @@ +.. _data-extensions: + +Data Extensions +=============== \ No newline at end of file From 5659b5899f07f185a89e4d045d5a44e5d7fb3e87 Mon Sep 17 00:00:00 2001 From: Michael Nebel <michaelnebel@github.com> Date: Fri, 10 Mar 2023 12:46:10 +0100 Subject: [PATCH 422/631] Java: Extend the description of models. --- .../customizing-library-models-for-java.rst | 31 +++++++++++++------ 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/docs/codeql/codeql-language-guides/customizing-library-models-for-java.rst b/docs/codeql/codeql-language-guides/customizing-library-models-for-java.rst index 531a9a8691c..24496f804c6 100644 --- a/docs/codeql/codeql-language-guides/customizing-library-models-for-java.rst +++ b/docs/codeql/codeql-language-guides/customizing-library-models-for-java.rst @@ -9,7 +9,17 @@ Customizing Library Models for Java .. include:: ../reusables/beta-note-customizing-library-models.rst The Java analysis can be customized by adding library models (summaries, sinks and sources) in data extension files. +A model is a definition of a behavior of a library element, such as a method, that is used to improve the data flow analysis precision by identifying more results. +Most of the security related queries are *taint tracking* queries that tries to find paths from a *source* of untrusted input to a *sink* that represents a vulnerability. +Furthermore, the taint tracking queries also need to know how data can flow through elements that are not included in the source code - these are named *summaries*. +That is + +- **sources** are the starting points of a taint tracking data flow analysis. +- **sinks** are the end points of a taint tracking data flow analysis. +- **summaries** are models of elements that allows us to synthesize the elements flow behavior without having them in the source code. This is especially helpful when using a third party (or the standard) library. + +The models are defined using data extensions where each tuple constitutes a model. A data extension file for Java is a YAML file in the form: .. code-block:: yaml @@ -23,14 +33,14 @@ A data extension file for Java is a YAML file in the form: - <tuple2> - ... -Data extensions contribute to extensible predicates defined CodeQL libraries. For more information on how to define data extensions and extensible predicates as well as how to wire them up, see the :ref:`data-extensions` documentation. +Data extensions contribute to the extensible predicates defined in the CodeQL library. For more information on how to define data extensions and extensible predicates as well as how to wire them up, see the :ref:`data-extensions` documentation. -The CodeQL libraries for Java expose the following extensible predicates: +The CodeQL library for Java expose the following extensible predicates: -- **sourceModel**\(package, type, subtypes, name, signature, ext, output, kind, provenance) -- **sinkModel**\(package, type, subtypes, name, signature, ext, input, kind, provenance) -- **summaryModel**\(package, type, subtypes, name, signature, ext, input, output, kind, provenance) -- **neutralModel**\(package, type, name, signature, provenance) +- **sourceModel**\(package, type, subtypes, name, signature, ext, output, kind, provenance). This is used for **source** models. +- **sinkModel**\(package, type, subtypes, name, signature, ext, input, kind, provenance). This is used for **sink** models. +- **summaryModel**\(package, type, subtypes, name, signature, ext, input, output, kind, provenance). This is used for **summary** models. +- **neutralModel**\(package, type, name, signature, provenance). This is used for **neutral** models, which does not impact the data flow analysis, but it is included here for completeness. The extensible predicates are populated using data extensions specified in YAML files. @@ -52,7 +62,7 @@ Please note that this sink is already added to the CodeQL Java analysis. stmt.execute(query); // The argument to this method is a SQL injection sink. } -This can be achieved by adding the following row to a data extension file: +This means that we want to add a tuple to the **sinkModel**\(package, type, subtypes, name, signature, ext, input, kind, provenance) extensible predicate, which can be achieved by adding the following to a data extension file: .. code-block:: yaml @@ -94,7 +104,7 @@ Please note that this source is already added to the CodeQL Java analysis. ... } -This can be achieved by adding the following data extension. +This means that we want to add a tuple to the **sourceModel**\(package, type, subtypes, name, signature, ext, output, kind, provenance) extensible predicate, which can be achieved by adding the following to a data extension file: .. code-block:: yaml @@ -136,8 +146,7 @@ Please note that the flow through the **concat** method is already added to the ... } -This can be achieved by adding the following data extension. -These are widely known as summary models. +This means that we want to add tuples to the **summaryModel**\(package, type, subtypes, name, signature, ext, input, output, kind, provenance) extensible predicate, which can be achieved by adding the following to a data extension file: .. code-block:: yaml @@ -247,6 +256,8 @@ Please note that the neutral model for the **now** method is already added. ... } +This means that we want to add a tuple to the **neutralModel**\(package, type, name, signature, provenance) extensible predicate, which can be achieved by adding the following to a data extension file: + .. code-block:: yaml extensions: From aba7d846867c15aecc317775933e862226c9eb67 Mon Sep 17 00:00:00 2001 From: Michael Nebel <michaelnebel@github.com> Date: Tue, 14 Mar 2023 09:53:54 +0100 Subject: [PATCH 423/631] Apply suggestions from code review Co-authored-by: Andrew Eisenberg <aeisenberg@github.com> Co-authored-by: Jami <57204504+jcogs33@users.noreply.github.com> --- .../codeql-for-java.rst | 2 - .../customizing-library-models-for-java.rst | 40 +++++++++---------- 2 files changed, 20 insertions(+), 22 deletions(-) diff --git a/docs/codeql/codeql-language-guides/codeql-for-java.rst b/docs/codeql/codeql-language-guides/codeql-for-java.rst index adbffe1f347..dc486b828a9 100644 --- a/docs/codeql/codeql-language-guides/codeql-for-java.rst +++ b/docs/codeql/codeql-language-guides/codeql-for-java.rst @@ -45,5 +45,3 @@ Experiment and learn how to write effective and efficient queries for CodeQL dat - :doc:`Working with source locations <working-with-source-locations>`: You can use the location of entities within Java code to look for potential errors. Locations allow you to deduce the presence, or absence, of white space which, in some cases, may indicate a problem. - :doc:`Abstract syntax tree classes for working with Java programs <abstract-syntax-tree-classes-for-working-with-java-programs>`: CodeQL has a large selection of classes for representing the abstract syntax tree of Java programs. - -- :doc:`Customizing library models for Java <customizing-library-models-for-java>`: You can customize the CodeQL library for Java to model the behavior of your own Java libraries using data extensions. \ No newline at end of file diff --git a/docs/codeql/codeql-language-guides/customizing-library-models-for-java.rst b/docs/codeql/codeql-language-guides/customizing-library-models-for-java.rst index 24496f804c6..f5370828687 100644 --- a/docs/codeql/codeql-language-guides/customizing-library-models-for-java.rst +++ b/docs/codeql/codeql-language-guides/customizing-library-models-for-java.rst @@ -10,14 +10,14 @@ Customizing Library Models for Java The Java analysis can be customized by adding library models (summaries, sinks and sources) in data extension files. A model is a definition of a behavior of a library element, such as a method, that is used to improve the data flow analysis precision by identifying more results. -Most of the security related queries are *taint tracking* queries that tries to find paths from a *source* of untrusted input to a *sink* that represents a vulnerability. +Most of the security related queries are *taint tracking* queries that try to find paths from a *source* of untrusted input to a *sink* that represents a vulnerability. Furthermore, the taint tracking queries also need to know how data can flow through elements that are not included in the source code - these are named *summaries*. -That is +That is: - **sources** are the starting points of a taint tracking data flow analysis. - **sinks** are the end points of a taint tracking data flow analysis. -- **summaries** are models of elements that allows us to synthesize the elements flow behavior without having them in the source code. This is especially helpful when using a third party (or the standard) library. +- **summaries** are models of elements that allow us to synthesize the elements flow behavior without having them in the source code. This is especially helpful when using a third party (or the standard) library. The models are defined using data extensions where each tuple constitutes a model. A data extension file for Java is a YAML file in the form: @@ -35,7 +35,7 @@ A data extension file for Java is a YAML file in the form: Data extensions contribute to the extensible predicates defined in the CodeQL library. For more information on how to define data extensions and extensible predicates as well as how to wire them up, see the :ref:`data-extensions` documentation. -The CodeQL library for Java expose the following extensible predicates: +The CodeQL library for Java exposes the following extensible predicates: - **sourceModel**\(package, type, subtypes, name, signature, ext, output, kind, provenance). This is used for **source** models. - **sinkModel**\(package, type, subtypes, name, signature, ext, input, kind, provenance). This is used for **sink** models. @@ -44,9 +44,9 @@ The CodeQL library for Java expose the following extensible predicates: The extensible predicates are populated using data extensions specified in YAML files. -In the sections below, we will show by example how to add tuples to the different extensible predicates. +In the sections below, we will provide examples of how to add tuples to the different extensible predicates. The extensible predicates are used to customize and improve the existing data flow queries, by providing sources, sinks, and flow through (summaries) for library elements. -The :ref:`reference-material` section will provide details on the *mini DSLs* that define models for each extensible predicate. +The :ref:`reference-material` section will provide details on the *mini DSLs* that defines models for each extensible predicate. Example: Taint sink in the **java.sql** package. ------------------------------------------------ @@ -84,11 +84,11 @@ The first five values identify the callable (in this case a method) to be modele - The fourth value **execute** is the method name. - The fifth value **(String)** is the method input type signature. -For most practical purposes the sixth value is not relevant. +The sixth value is only relevant internally and can be omitted in most use cases. The remaining values are used to define the **access path**, the **kind**, and the **provenance** (origin) of the sink. - The seventh value **Argument[0]** is the **access path** to the first argument passed to the method, which means that this is the location of the sink. -- The eighth value **sql** is the kind of the sink. The sink kind is used to define the queries where the sink is in scope. In this case - the SQL injection queries. +- The eighth value **sql** is the kind of the sink. The sink kind is used to define the queries where the sink is in scope. In this case - the SQL injection queries. - The ninth value **manual** is the provenance of the sink, which is used to identify the origin of the sink. Example: Taint source from the **java.net** package. @@ -122,7 +122,7 @@ The first five values identify the callable (in this case a method) to be modele - The first value **java.net** is the package name. - The second value **Socket** is the name of the class (type) that contains the source. -- The third value **False** flag indicates whether or not the source also applies to all overrides of the method. +- The third value **False** is a flag that indicates whether or not the source also applies to all overrides of the method. - The fourth value **getInputStream** is the method name. - The fifth value **()** is the method input type signature. @@ -164,12 +164,12 @@ Since we are adding flow through a method, we need to add tuples to the **summar Each tuple defines flow from one argument to the return value. The first row defines flow from the qualifier (**s1** in the example) to the return value (**t** in the example) and the second row defines flow from the first argument (**s2** in the example) to the return value (**t** in the example). -The first five values are used to identify the callable (in this case a method) which we are defining a summary for. +The first five values identify the callable (in this case a method) to be modeled as a summary. These are the same for both of the rows above as we are adding two summaries for the same method. - The first value **java.lang** is the package name. - The second value **String** is the class (type) name. -- The third value **False** is a flag indicating whether the summary also applies to all overrides of the method. +- The third value **False** is a flag that indicates whether or not the summary also applies to all overrides of the method. - The fourth value **concat** is the method name. - The fifth value **(String)** is the method input type signature. @@ -183,7 +183,7 @@ The remaining values are used to define the **access path**, the **kind**, and t Example: Add flow through the **map** method. --------------------------------------------- -In this example, we will see a more complex example of modelling flow through a method. +In this example, we will see a more complex example of modeling flow through a method. This pattern shows how to model flow through higher order methods and collection types. Please note that the flow through the **map** method is already added to the CodeQL Java analysis. @@ -194,7 +194,7 @@ Please note that the flow through the **map** method is already added to the Cod ... } -This can be achieved by adding the following data extension. +This can be achieved by adding the following to a data extension file: .. code-block:: yaml @@ -215,7 +215,7 @@ These are the same for both of the rows above as we are adding two summaries for - The first value **java.util.stream** is the package name. - The second value **Stream** is the class (type) name. -- The third value **True** is a flag indicating whether the summary also applies to all overrides of the method. +- The third value **True** is a flag that indicates whether or not the summary also applies to all overrides of the method. - The fourth value **map** is the method name. - The fifth value **Function** is the method input type signature. @@ -245,7 +245,7 @@ That is, the first row models that there is value flow from the elements of the Example: Add a **neutral** method. ---------------------------------- In this example we will show how to model the **now** method as being neutral. -This is purely for consistency and has no impact on the analysis. +This is purely for completeness and has no impact on the analysis. A neutral model is used to define that there is no flow through a method. Please note that the neutral model for the **now** method is already added. @@ -284,7 +284,7 @@ Reference material ------------------ The following sections provide reference material for extensible predicates. -This includes descriptions of each of the arguments (eg. access paths, kinds and provenance). +This includes descriptions of each of the arguments (e.g. access paths, kinds and provenance). Extensible predicates --------------------- @@ -299,7 +299,7 @@ The shared columns are: - **type**: Name of the type containing the element(s) to be modeled. - **subtypes**: A boolean flag indicating whether the model should also apply to all overrides of the selected element(s). - **name**: Name of the element (optional). If this is left blank, it means all elements matching the previous selection criteria. -- **signature**: Type signature of the selected element (optional). If this is left blank it means all elements matching the previous selection criteria. +- **signature**: Type signature of the selected element (optional). If this is left blank, it means all elements matching the previous selection criteria. - **ext**: Specifies additional API-graph-like edges (mostly empty) and out of scope for this document. - **provenance**: Provenance (origin) of the model definition. @@ -417,12 +417,12 @@ The following values are supported: - **ai-generated**: The model was generated by AI and added to the extensible predicate. The provenance is used to distinguish between models that are manually added to the extensible predicate and models that are automatically generated. -Furthermore, it impacts the data flow analysis in the following way +Furthermore, it impacts the data flow analysis in the following way: - A **manual** model takes precedence over **generated** models. If a **manual** model exists for an element then all generated models are ignored. -- A **generated** or **ai-generated** model is ignored during analysis, if the source code of the element it is modelling is available. +- A **generated** or **ai-generated** model is ignored during analysis, if the source code of the element it is modeling is available. -That is, generated models are less trusted than manual models and only used if neither source code or a manual model is available. +That is, generated models are less trusted than manual models and only used if neither source code nor a manual model is available. .. include:: ../reusables/data-extensions.rst \ No newline at end of file From 6afdaa3ee1310b48905574f92b9d45f2e9872a38 Mon Sep 17 00:00:00 2001 From: Michael Nebel <michaelnebel@github.com> Date: Tue, 14 Mar 2023 11:04:38 +0100 Subject: [PATCH 424/631] Java: Address review comments. --- .../customizing-library-models-for-java.rst | 10 ++++++---- docs/codeql/reusables/data-extensions.rst | 8 +++++++- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/docs/codeql/codeql-language-guides/customizing-library-models-for-java.rst b/docs/codeql/codeql-language-guides/customizing-library-models-for-java.rst index f5370828687..aa1090e52e4 100644 --- a/docs/codeql/codeql-language-guides/customizing-library-models-for-java.rst +++ b/docs/codeql/codeql-language-guides/customizing-library-models-for-java.rst @@ -126,7 +126,7 @@ The first five values identify the callable (in this case a method) to be modele - The fourth value **getInputStream** is the method name. - The fifth value **()** is the method input type signature. -For most practical purposes the sixth value is not relevant. +The sixth value is only relevant internally and can be omitted in most use cases. The remaining values are used to define the **access path**, the **kind**, and the **provenance** (origin) of the source. - The seventh value **ReturnValue** is the access path to the return of the method, which means that it is the return value that should be considered a source of tainted input. @@ -173,7 +173,7 @@ These are the same for both of the rows above as we are adding two summaries for - The fourth value **concat** is the method name. - The fifth value **(String)** is the method input type signature. -For most practical purposes the sixth value is not relevant. +The sixth value is only relevant internally and can be omitted in most use cases. The remaining values are used to define the **access path**, the **kind**, and the **provenance** (origin) of the summary. - The seventh value is the access path to the input (where data flows from). **Argument[-1]** is the access path to the qualifier (**s1** in the example) and **Argument[0]** is the access path to the first argument (**s2** in the example). @@ -219,7 +219,7 @@ These are the same for both of the rows above as we are adding two summaries for - The fourth value **map** is the method name. - The fifth value **Function** is the method input type signature. -For most practical purposes the sixth value is not relevant. +The sixth value is only relevant internally and can be omitted in most use cases. The remaining values are used to define the **access path**, the **kind**, and the **provenance** (origin) of the summary definition. - The seventh value is the access path to the **input** (where data flows from). @@ -361,6 +361,7 @@ The following sink kinds are supported: - **bean-validation**: ? - **ssti**: ? - **fragment-injection**: ? +- **regex-use[**\ `arg`\ **]**: ? summaryModel(package, type, subtypes, name, signature, ext, input, output, kind, provenance) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -380,7 +381,7 @@ The following kinds are supported: neutralModel(package, type, name, signature, provenance) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -No flow. This extensible predicate is used to model elements without flow. +This extensible predicate is not typically needed externally, but included here for completeness. - **provenance**: Provenance (origin) of the flow through. @@ -400,6 +401,7 @@ The following components are supported: - **ReturnValue** selects the return value. - **Field[**\ `name`\ **]** selects the field with the fully qualified name `name`. - **SyntheticField[**\ `name`\ **]** selects the synthetic field with name `name`. +- **SyntheticGlobal[**\ `name`\ **]** selects the synthetic global with name `name`. - **ArrayElement** selects the elements of an array. - **Element** selects the elements of a collection-like container. - **MapKey** selects the element keys of a map. diff --git a/docs/codeql/reusables/data-extensions.rst b/docs/codeql/reusables/data-extensions.rst index ad46738036c..5a1fa223347 100644 --- a/docs/codeql/reusables/data-extensions.rst +++ b/docs/codeql/reusables/data-extensions.rst @@ -1,4 +1,10 @@ .. _data-extensions: Data Extensions -=============== \ No newline at end of file +=============== + +.. pull-quote:: + + Beta Notice - Internal documentation + + Data extensions are documented internally in a Google doc. \ No newline at end of file From a73f73c6e0a059c9e3a0e1209bdc1af8e7ce86cb Mon Sep 17 00:00:00 2001 From: Michael Nebel <michaelnebel@github.com> Date: Mon, 20 Mar 2023 11:21:17 +0100 Subject: [PATCH 425/631] Java: The qualifier is selected using this instead of -1. --- .../customizing-library-models-for-java.rst | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/codeql/codeql-language-guides/customizing-library-models-for-java.rst b/docs/codeql/codeql-language-guides/customizing-library-models-for-java.rst index aa1090e52e4..ce48b25fa86 100644 --- a/docs/codeql/codeql-language-guides/customizing-library-models-for-java.rst +++ b/docs/codeql/codeql-language-guides/customizing-library-models-for-java.rst @@ -155,7 +155,7 @@ This means that we want to add tuples to the **summaryModel**\(package, type, su pack: codeql/java-all extensible: summaryModel data: - - ["java.lang", "String", False, "concat", "(String)", "", "Argument[-1]", "ReturnValue", "taint", "manual"] + - ["java.lang", "String", False, "concat", "(String)", "", "Argument[this]", "ReturnValue", "taint", "manual"] - ["java.lang", "String", False, "concat", "(String)", "", "Argument[0]", "ReturnValue", "taint", "manual"] Reasoning: @@ -176,7 +176,7 @@ These are the same for both of the rows above as we are adding two summaries for The sixth value is only relevant internally and can be omitted in most use cases. The remaining values are used to define the **access path**, the **kind**, and the **provenance** (origin) of the summary. -- The seventh value is the access path to the input (where data flows from). **Argument[-1]** is the access path to the qualifier (**s1** in the example) and **Argument[0]** is the access path to the first argument (**s2** in the example). +- The seventh value is the access path to the input (where data flows from). **Argument[this]** is the access path to the qualifier (**s1** in the example) and **Argument[0]** is the access path to the first argument (**s2** in the example). - The eighth value **ReturnValue** is the access path to the output (where data flows to), in this case **ReturnValue**, which means that the input flows to the return value. - The ninth value **taint** is the kind of the flow. **taint** means that taint is propagated through the call. - The tenth value **manual** is the provenance of the summary, which is used to identify the origin of the summary. @@ -203,7 +203,7 @@ This can be achieved by adding the following to a data extension file: pack: codeql/java-all extensible: summaryModel data: - - ["java.util.stream", "Stream", True, "map", "(Function)", "", "Argument[-1].Element", "Argument[0].Parameter[0]", "value", "manual"] + - ["java.util.stream", "Stream", True, "map", "(Function)", "", "Argument[this].Element", "Argument[0].Parameter[0]", "value", "manual"] - ["java.util.stream", "Stream", True, "map", "(Function)", "", "Argument[0].ReturnValue", "ReturnValue.Element", "value", "manual"] Reasoning: @@ -227,7 +227,7 @@ The remaining values are used to define the **access path**, the **kind**, and t For the first row the -- The seventh value is **Argument[-1].Element**, which is the access path to the elements of the qualifier (the elements of the stream **s** in the example). +- The seventh value is **Argument[this].Element**, which is the access path to the elements of the qualifier (the elements of the stream **s** in the example). - The eight value is **Argument[0].Parameter[0]**, which is the access path to the first parameter of the **Function** argument of **map** (the lambda parameter **e** in the example). For the second row the @@ -394,7 +394,7 @@ The **input**, and **output** columns consist of a **.**-separated list of compo The following components are supported: - **Argument[**\ `n`\ **]** selects the argument at index `n` (zero-indexed). -- **Argument[**\ `-1`\ **]** selects the qualifier (instance parameter). +- **Argument[**\ `this`\ **]** selects the qualifier (instance parameter). - **Argument[**\ `n1..n2`\ **]** selects the arguments in the given range (both ends included). - **Parameter[**\ `n`\ **]** selects the parameter at index `n` (zero-indexed). - **Parameter[**\ `n1..n2`\ **]** selects the parameters in the given range (both ends included). From ad42f7d5ba85626c75d99c6a10552a3ba04d598c Mon Sep 17 00:00:00 2001 From: Michael Nebel <michaelnebel@github.com> Date: Thu, 23 Mar 2023 11:14:08 +0100 Subject: [PATCH 426/631] Java: Update provenance description to prepare for the upcoming changes. --- .../customizing-library-models-for-java.rst | 25 +++++++++++++------ 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/docs/codeql/codeql-language-guides/customizing-library-models-for-java.rst b/docs/codeql/codeql-language-guides/customizing-library-models-for-java.rst index ce48b25fa86..214329d6fbf 100644 --- a/docs/codeql/codeql-language-guides/customizing-library-models-for-java.rst +++ b/docs/codeql/codeql-language-guides/customizing-library-models-for-java.rst @@ -410,19 +410,28 @@ The following components are supported: Provenance ---------- -The **provenance** column is used to specify the provenance (origin) of the model definition. - +The **provenance** column is used to specify the provenance (origin) of the model definition and how the model was verified. The following values are supported: -- **manual**: The model was manually created (or verified by a human) and added to the extensible predicate. -- **generated**: The model was generated by the model generator and added to the extensible predicate. -- **ai-generated**: The model was generated by AI and added to the extensible predicate. +- **manual**: The model was manually created and added to the extensible predicate. -The provenance is used to distinguish between models that are manually added to the extensible predicate and models that are automatically generated. +or values in the form **origin-verification**, where origin is one of: + +- **ai**: The model was generated by AI. +- **df**: The model was generated by the dataflow model generator. +- **tb**: The model was generated by the type based model generator. +- **hq**: The model was generated using a heuristic query. + +and verification is one of: + +- **manual**: The model was verified by a human. +- **generated**: The model was generated, but not verified by a human. + +The provenance is used to distinguish between models that are manually added (or verified) to the extensible predicate and models that are automatically generated. Furthermore, it impacts the data flow analysis in the following way: -- A **manual** model takes precedence over **generated** models. If a **manual** model exists for an element then all generated models are ignored. -- A **generated** or **ai-generated** model is ignored during analysis, if the source code of the element it is modeling is available. +- A **manual** model takes precedence over **generated** models. If a **manual** model exists for an element then all **generated** models are ignored. +- A **generated** model is ignored during analysis, if the source code of the element it is modeling is available. That is, generated models are less trusted than manual models and only used if neither source code nor a manual model is available. From 43fd342119422ccd21d5d9168d8d4405c7cc195a Mon Sep 17 00:00:00 2001 From: Michael Nebel <michaelnebel@github.com> Date: Fri, 24 Mar 2023 09:03:38 +0100 Subject: [PATCH 427/631] Apply suggestions from code review Co-authored-by: Ben Ahmady <32935794+subatoi@users.noreply.github.com> --- .../customizing-library-models-for-java.rst | 45 ++++++++----------- 1 file changed, 18 insertions(+), 27 deletions(-) diff --git a/docs/codeql/codeql-language-guides/customizing-library-models-for-java.rst b/docs/codeql/codeql-language-guides/customizing-library-models-for-java.rst index 214329d6fbf..4d378ae2854 100644 --- a/docs/codeql/codeql-language-guides/customizing-library-models-for-java.rst +++ b/docs/codeql/codeql-language-guides/customizing-library-models-for-java.rst @@ -10,14 +10,9 @@ Customizing Library Models for Java The Java analysis can be customized by adding library models (summaries, sinks and sources) in data extension files. A model is a definition of a behavior of a library element, such as a method, that is used to improve the data flow analysis precision by identifying more results. -Most of the security related queries are *taint tracking* queries that try to find paths from a *source* of untrusted input to a *sink* that represents a vulnerability. -Furthermore, the taint tracking queries also need to know how data can flow through elements that are not included in the source code - these are named *summaries*. +Most of the security related queries are taint tracking queries that try to find paths from a source of untrusted input to a sink that represents a vulnerability. Sources are the starting points of a taint tracking data flow analysis, and sinks are the end points of a taint tracking data flow analysis. -That is: - -- **sources** are the starting points of a taint tracking data flow analysis. -- **sinks** are the end points of a taint tracking data flow analysis. -- **summaries** are models of elements that allow us to synthesize the elements flow behavior without having them in the source code. This is especially helpful when using a third party (or the standard) library. +Furthermore, the taint tracking queries also need to know how data can flow through elements that are not included in the source code. These are named summaries: they are models of elements that allow us to synthesize the elements flow behavior without having them in the source code. This is especially helpful when using a third party (or the standard) library. The models are defined using data extensions where each tuple constitutes a model. A data extension file for Java is a YAML file in the form: @@ -46,9 +41,9 @@ The extensible predicates are populated using data extensions specified in YAML In the sections below, we will provide examples of how to add tuples to the different extensible predicates. The extensible predicates are used to customize and improve the existing data flow queries, by providing sources, sinks, and flow through (summaries) for library elements. -The :ref:`reference-material` section will provide details on the *mini DSLs* that defines models for each extensible predicate. +The :ref:`reference-material` section will provide details on the *mini DSLs* that define models for each extensible predicate. -Example: Taint sink in the **java.sql** package. +Example: Taint sink in the **java.sql** package ------------------------------------------------ In this example we will show how to model the argument of the **execute** method as a SQL injection sink. @@ -62,7 +57,7 @@ Please note that this sink is already added to the CodeQL Java analysis. stmt.execute(query); // The argument to this method is a SQL injection sink. } -This means that we want to add a tuple to the **sinkModel**\(package, type, subtypes, name, signature, ext, input, kind, provenance) extensible predicate, which can be achieved by adding the following to a data extension file: +We need to add a tuple to the **sinkModel**\(package, type, subtypes, name, signature, ext, input, kind, provenance) extensible predicate. To do this, add the following to a data extension file: .. code-block:: yaml @@ -73,7 +68,6 @@ This means that we want to add a tuple to the **sinkModel**\(package, type, subt data: - ["java.sql", "Statement", True, "execute", "(String)", "", "Argument[0]", "sql", "manual"] -Reasoning: Since we are adding a new sink, we need to add a tuple to the **sinkModel** extensible predicate. The first five values identify the callable (in this case a method) to be modeled as a sink. @@ -91,7 +85,7 @@ The remaining values are used to define the **access path**, the **kind**, and t - The eighth value **sql** is the kind of the sink. The sink kind is used to define the queries where the sink is in scope. In this case - the SQL injection queries. - The ninth value **manual** is the provenance of the sink, which is used to identify the origin of the sink. -Example: Taint source from the **java.net** package. +Example: Taint source from the **java.net** package ---------------------------------------------------- In this example we show how to model the return value from the **getInputStream** method as a **remote** source. This is the **getInputStream** method in the **Socket** class, which is located in the **java.net** package. @@ -104,7 +98,7 @@ Please note that this source is already added to the CodeQL Java analysis. ... } -This means that we want to add a tuple to the **sourceModel**\(package, type, subtypes, name, signature, ext, output, kind, provenance) extensible predicate, which can be achieved by adding the following to a data extension file: +We need to add a tuple to the **sourceModel**\(package, type, subtypes, name, signature, ext, output, kind, provenance) extensible predicate. To do this, add the following to a data extension file: .. code-block:: yaml @@ -115,7 +109,6 @@ This means that we want to add a tuple to the **sourceModel**\(package, type, su data: - ["java.net", "Socket", False, "getInputStream", "()", "", "ReturnValue", "remote", "manual"] -Reasoning: Since we are adding a new source, we need to add a tuple to the **sourceModel** extensible predicate. The first five values identify the callable (in this case a method) to be modeled as a source. @@ -133,7 +126,7 @@ The remaining values are used to define the **access path**, the **kind**, and t - The eighth value **remote** is the kind of the source. The source kind is used to define the queries where the source is in scope. **remote** applies to many of the security related queries as it means a remote source of untrusted data. As an example the SQL injection query uses **remote** sources. - The ninth value **manual** is the provenance of the source, which is used to identify the origin of the source. -Example: Add flow through the **concat** method. +Example: Add flow through the **concat** method ------------------------------------------------ In this example we show how to model flow through a method for a simple case. This pattern covers many of the cases where we need to define flow through a method. @@ -146,7 +139,7 @@ Please note that the flow through the **concat** method is already added to the ... } -This means that we want to add tuples to the **summaryModel**\(package, type, subtypes, name, signature, ext, input, output, kind, provenance) extensible predicate, which can be achieved by adding the following to a data extension file: +We need to add tuples to the **summaryModel**\(package, type, subtypes, name, signature, ext, input, output, kind, provenance) extensible predicate. To do this, add the following to a data extension file: .. code-block:: yaml @@ -181,7 +174,7 @@ The remaining values are used to define the **access path**, the **kind**, and t - The ninth value **taint** is the kind of the flow. **taint** means that taint is propagated through the call. - The tenth value **manual** is the provenance of the summary, which is used to identify the origin of the summary. -Example: Add flow through the **map** method. +Example: Add flow through the **map** method --------------------------------------------- In this example, we will see a more complex example of modeling flow through a method. This pattern shows how to model flow through higher order methods and collection types. @@ -194,7 +187,7 @@ Please note that the flow through the **map** method is already added to the Cod ... } -This can be achieved by adding the following to a data extension file: +To do this, add the following to a data extension file: .. code-block:: yaml @@ -206,7 +199,6 @@ This can be achieved by adding the following to a data extension file: - ["java.util.stream", "Stream", True, "map", "(Function)", "", "Argument[this].Element", "Argument[0].Parameter[0]", "value", "manual"] - ["java.util.stream", "Stream", True, "map", "(Function)", "", "Argument[0].ReturnValue", "ReturnValue.Element", "value", "manual"] -Reasoning: Since we are adding flow through a method, we need to add tuples to the **summaryModel** extensible predicate. Each tuple defines part of the flow that comprises the total flow through the **map** method. @@ -225,24 +217,24 @@ The remaining values are used to define the **access path**, the **kind**, and t - The seventh value is the access path to the **input** (where data flows from). - The eighth value is the access path to the **output** (where data flows to). -For the first row the +For the first row: - The seventh value is **Argument[this].Element**, which is the access path to the elements of the qualifier (the elements of the stream **s** in the example). - The eight value is **Argument[0].Parameter[0]**, which is the access path to the first parameter of the **Function** argument of **map** (the lambda parameter **e** in the example). -For the second row the +For the second row: - The seventh value is **Argument[0].ReturnValue**, which is the access path to the return value of the **Function** argument of **map** (the return value of the lambda in the example). - The eighth value is **ReturnValue.Element**, which is the access path to the elements of the return value of **map** (the elements of the stream **l** in the example). -The remaining values for both rows +For the remaining values for both rows: - The ninth value **value** is the kind of the flow. **value** means that the value is preserved. - The tenth value **manual** is the provenance of the summary, which is used to identify the origin of the summary. -That is, the first row models that there is value flow from the elements of the qualifier stream into the first argument of the Function provided to **map** and the second row models that there is value flow from the return value of the Function to the elements of the stream returned from **map**. +That is, the first row models that there is value flow from the elements of the qualifier stream into the first argument of the function provided to **map** and the second row models that there is value flow from the return value of the function to the elements of the stream returned from **map**. -Example: Add a **neutral** method. +Example: Add a **neutral** method ---------------------------------- In this example we will show how to model the **now** method as being neutral. This is purely for completeness and has no impact on the analysis. @@ -256,7 +248,7 @@ Please note that the neutral model for the **now** method is already added. ... } -This means that we want to add a tuple to the **neutralModel**\(package, type, name, signature, provenance) extensible predicate, which can be achieved by adding the following to a data extension file: +We need to add a tuple to the **neutralModel**\(package, type, name, signature, provenance) extensible predicate. To do this, add the following to a data extension file: .. code-block:: yaml @@ -267,7 +259,6 @@ This means that we want to add a tuple to the **neutralModel**\(package, type, n data: - ["java.time", "Instant", "now", "()", "manual"] -Reasoning: Since we are adding a neutral model, we need to add tuples to the **neutralModel** extensible predicate. The first five values identify the callable (in this case a method) to be modeled as a neutral and the fifth value is the provenance (origin) of the neutral. @@ -290,7 +281,7 @@ Extensible predicates --------------------- Below is a description of the columns for each extensible predicate. -Sources, Sinks, Summaries and Neutrals are commonly known as Models. +Sources, sinks, summaries and neutrals are commonly known as models. The semantics of many of the columns of the extensible predicates are shared. The shared columns are: From e5637876b24b355ac1c7f1bea4df5949759f23f6 Mon Sep 17 00:00:00 2001 From: Michael Nebel <michaelnebel@github.com> Date: Fri, 24 Mar 2023 10:00:58 +0100 Subject: [PATCH 428/631] Address review comments related to neutrals and ext. --- .../customizing-library-models-for-java.rst | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/docs/codeql/codeql-language-guides/customizing-library-models-for-java.rst b/docs/codeql/codeql-language-guides/customizing-library-models-for-java.rst index 4d378ae2854..2fa9f9bb8f2 100644 --- a/docs/codeql/codeql-language-guides/customizing-library-models-for-java.rst +++ b/docs/codeql/codeql-language-guides/customizing-library-models-for-java.rst @@ -35,7 +35,7 @@ The CodeQL library for Java exposes the following extensible predicates: - **sourceModel**\(package, type, subtypes, name, signature, ext, output, kind, provenance). This is used for **source** models. - **sinkModel**\(package, type, subtypes, name, signature, ext, input, kind, provenance). This is used for **sink** models. - **summaryModel**\(package, type, subtypes, name, signature, ext, input, output, kind, provenance). This is used for **summary** models. -- **neutralModel**\(package, type, name, signature, provenance). This is used for **neutral** models, which does not impact the data flow analysis, but it is included here for completeness. +- **neutralModel**\(package, type, name, signature, provenance). This is used for **neutral** models, which only have minor impact on the data flow analysis. The extensible predicates are populated using data extensions specified in YAML files. @@ -78,7 +78,7 @@ The first five values identify the callable (in this case a method) to be modele - The fourth value **execute** is the method name. - The fifth value **(String)** is the method input type signature. -The sixth value is only relevant internally and can be omitted in most use cases. +The sixth value should be left empty and is out of scope for this documentation. The remaining values are used to define the **access path**, the **kind**, and the **provenance** (origin) of the sink. - The seventh value **Argument[0]** is the **access path** to the first argument passed to the method, which means that this is the location of the sink. @@ -119,7 +119,7 @@ The first five values identify the callable (in this case a method) to be modele - The fourth value **getInputStream** is the method name. - The fifth value **()** is the method input type signature. -The sixth value is only relevant internally and can be omitted in most use cases. +The sixth value should be left empty and is out of scope for this documentation. The remaining values are used to define the **access path**, the **kind**, and the **provenance** (origin) of the source. - The seventh value **ReturnValue** is the access path to the return of the method, which means that it is the return value that should be considered a source of tainted input. @@ -166,7 +166,7 @@ These are the same for both of the rows above as we are adding two summaries for - The fourth value **concat** is the method name. - The fifth value **(String)** is the method input type signature. -The sixth value is only relevant internally and can be omitted in most use cases. +The sixth value should be left empty and is out of scope for this documentation. The remaining values are used to define the **access path**, the **kind**, and the **provenance** (origin) of the summary. - The seventh value is the access path to the input (where data flows from). **Argument[this]** is the access path to the qualifier (**s1** in the example) and **Argument[0]** is the access path to the first argument (**s2** in the example). @@ -211,7 +211,7 @@ These are the same for both of the rows above as we are adding two summaries for - The fourth value **map** is the method name. - The fifth value **Function** is the method input type signature. -The sixth value is only relevant internally and can be omitted in most use cases. +The sixth value should be left empty and is out of scope for this documentation. The remaining values are used to define the **access path**, the **kind**, and the **provenance** (origin) of the summary definition. - The seventh value is the access path to the **input** (where data flows from). @@ -237,9 +237,8 @@ That is, the first row models that there is value flow from the elements of the Example: Add a **neutral** method ---------------------------------- In this example we will show how to model the **now** method as being neutral. -This is purely for completeness and has no impact on the analysis. A neutral model is used to define that there is no flow through a method. -Please note that the neutral model for the **now** method is already added. +Please note that the neutral model for the **now** method is already added to the CodeQL Java analysis. .. code-block:: java @@ -373,6 +372,8 @@ neutralModel(package, type, name, signature, provenance) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ This extensible predicate is not typically needed externally, but included here for completeness. +It only has minor impact on the data flow analysis. +Manual neutrals are considered high confidence dispatch call targets and can reduce the number of dispatch call targets during data flow analysis (a performance optimization). - **provenance**: Provenance (origin) of the flow through. From b816c79248531a7e6a9c95afb1cfd10dee81c691 Mon Sep 17 00:00:00 2001 From: Tom Hvitved <hvitved@github.com> Date: Fri, 17 Mar 2023 10:49:27 +0100 Subject: [PATCH 429/631] Ruby: Include all assignments in data flow paths --- ruby/ql/lib/codeql/ruby/dataflow/SSA.qll | 4 +- .../dataflow/internal/DataFlowPrivate.qll | 15 +- .../dataflow/array-flow/array-flow.expected | 3980 ++++++++++++----- .../flow-summaries/semantics.expected | 526 ++- .../dataflow/global/Flow.expected | 16 +- .../dataflow/hash-flow/hash-flow.expected | 840 +++- .../dataflow/local/DataflowStep.expected | 264 +- .../dataflow/local/InlineFlowTest.expected | 116 +- .../dataflow/local/TaintStep.expected | 264 +- .../dataflow/params/params-flow.expected | 20 +- .../pathname-flow/pathame-flow.expected | 160 +- .../dataflow/string-flow/string-flow.expected | 400 +- .../dataflow/summaries/Summaries.expected | 196 +- .../type-tracker/TypeTracker.expected | 30 +- .../active_record/ActiveRecord.expected | 10 +- .../active_resource/ActiveResource.expected | 10 +- .../active_storage/ActiveStorage.expected | 4 +- .../ActiveSupportDataFlow.expected | 720 ++- .../frameworks/files/Files.expected | 12 +- .../frameworks/pathname/Pathname.expected | 20 +- .../test/library-tests/variables/ssa.expected | 360 +- .../TemplateInjection.expected | 28 +- .../cwe-022-ZipSlip/ZipSlip.expected | 20 +- .../ManuallyCheckHttpVerb.expected | 20 +- .../security/cwe-022/PathInjection.expected | 60 +- .../CommandInjection.expected | 30 +- .../cwe-078/KernelOpen/KernelOpen.expected | 22 +- .../security/cwe-079/ReflectedXSS.expected | 10 +- .../security/cwe-079/StoredXSS.expected | 6 +- .../security/cwe-089/SqlInjection.expected | 22 +- .../CodeInjection/CodeInjection.expected | 40 +- .../UnsafeCodeConstruction.expected | 12 +- .../security/cwe-117/LogInjection.expected | 24 +- .../PolynomialReDoS.expected | 58 +- .../RegExpInjection.expected | 20 +- .../cwe-209/StackTraceExposure.expected | 4 +- .../cwe-312/CleartextLogging.expected | 60 +- .../cwe-312/CleartextStorage.expected | 56 +- .../UnsafeDeserialization.expected | 4 +- .../UnsafeDeserialization.expected | 38 +- .../HardcodedDataInterpretedAsCode.expected | 8 +- .../cwe-598/SensitiveGetQuery.expected | 4 +- .../cwe-611/libxml-backend/Xxe.expected | 10 +- .../security/cwe-611/xxe/Xxe.expected | 50 +- .../cwe-732/WeakFilePermissions.expected | 14 +- .../cwe-798/HardcodedCredentials.expected | 10 +- .../ConditionalBypass.expected | 8 +- .../cwe-829/InsecureDownload.expected | 8 +- .../cwe-912/HttpToFileAccess.expected | 8 +- .../cwe-918/ServerSideRequestForgery.expected | 4 +- .../DecompressionApi.expected | 4 +- 51 files changed, 5859 insertions(+), 2770 deletions(-) diff --git a/ruby/ql/lib/codeql/ruby/dataflow/SSA.qll b/ruby/ql/lib/codeql/ruby/dataflow/SSA.qll index 241b2bb763a..97bb3407b57 100644 --- a/ruby/ql/lib/codeql/ruby/dataflow/SSA.qll +++ b/ruby/ql/lib/codeql/ruby/dataflow/SSA.qll @@ -216,9 +216,9 @@ module Ssa { ) } - final override string toString() { result = Definition.super.toString() } + final override string toString() { result = write.toString() } - final override Location getLocation() { result = this.getControlFlowNode().getLocation() } + final override Location getLocation() { result = write.getLocation() } } /** diff --git a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowPrivate.qll b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowPrivate.qll index cfce508e706..cd84298c41a 100644 --- a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowPrivate.qll +++ b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowPrivate.qll @@ -528,10 +528,7 @@ import Cached /** Holds if `n` should be hidden from path explanations. */ predicate nodeIsHidden(Node n) { exists(SsaImpl::DefinitionExt def | def = n.(SsaDefinitionExtNode).getDefinitionExt() | - def instanceof Ssa::PhiNode or - def instanceof SsaImpl::PhiReadNode or - def instanceof Ssa::CapturedEntryDefinition or - def instanceof Ssa::CapturedCallDefinition + not def instanceof Ssa::WriteDefinition ) or n = LocalFlow::getParameterDefNode(_) @@ -1333,7 +1330,15 @@ private module PostUpdateNodes { private import PostUpdateNodes /** A node that performs a type cast. */ -class CastNode extends Node instanceof ReturningNode { } +class CastNode extends Node { + CastNode() { + // ensure that actual return nodes are included in the path graph + this instanceof ReturningNode + or + // ensure that all variable assignments are included in the path graph + this.(SsaDefinitionExtNode).getDefinitionExt() instanceof Ssa::WriteDefinition + } +} class DataFlowExpr = CfgNodes::ExprCfgNode; diff --git a/ruby/ql/test/library-tests/dataflow/array-flow/array-flow.expected b/ruby/ql/test/library-tests/dataflow/array-flow/array-flow.expected index 399a65de525..2e813207b6a 100644 --- a/ruby/ql/test/library-tests/dataflow/array-flow/array-flow.expected +++ b/ruby/ql/test/library-tests/dataflow/array-flow/array-flow.expected @@ -1,103 +1,135 @@ failures edges -| array_flow.rb:2:9:2:20 | * ... [element 0] : | array_flow.rb:3:10:3:10 | a [element 0] : | -| array_flow.rb:2:9:2:20 | * ... [element 0] : | array_flow.rb:3:10:3:10 | a [element 0] : | -| array_flow.rb:2:9:2:20 | * ... [element 0] : | array_flow.rb:5:10:5:10 | a [element 0] : | -| array_flow.rb:2:9:2:20 | * ... [element 0] : | array_flow.rb:5:10:5:10 | a [element 0] : | +| array_flow.rb:2:5:2:5 | a [element 0] : | array_flow.rb:3:10:3:10 | a [element 0] : | +| array_flow.rb:2:5:2:5 | a [element 0] : | array_flow.rb:3:10:3:10 | a [element 0] : | +| array_flow.rb:2:5:2:5 | a [element 0] : | array_flow.rb:5:10:5:10 | a [element 0] : | +| array_flow.rb:2:5:2:5 | a [element 0] : | array_flow.rb:5:10:5:10 | a [element 0] : | +| array_flow.rb:2:9:2:20 | * ... [element 0] : | array_flow.rb:2:5:2:5 | a [element 0] : | +| array_flow.rb:2:9:2:20 | * ... [element 0] : | array_flow.rb:2:5:2:5 | a [element 0] : | | array_flow.rb:2:10:2:20 | call to source : | array_flow.rb:2:9:2:20 | * ... [element 0] : | | array_flow.rb:2:10:2:20 | call to source : | array_flow.rb:2:9:2:20 | * ... [element 0] : | | array_flow.rb:3:10:3:10 | a [element 0] : | array_flow.rb:3:10:3:13 | ...[...] | | array_flow.rb:3:10:3:10 | a [element 0] : | array_flow.rb:3:10:3:13 | ...[...] | | array_flow.rb:5:10:5:10 | a [element 0] : | array_flow.rb:5:10:5:13 | ...[...] | | array_flow.rb:5:10:5:10 | a [element 0] : | array_flow.rb:5:10:5:13 | ...[...] | -| array_flow.rb:9:13:9:21 | call to source : | array_flow.rb:11:10:11:10 | a [element 1] : | -| array_flow.rb:9:13:9:21 | call to source : | array_flow.rb:11:10:11:10 | a [element 1] : | -| array_flow.rb:9:13:9:21 | call to source : | array_flow.rb:13:10:13:10 | a [element 1] : | -| array_flow.rb:9:13:9:21 | call to source : | array_flow.rb:13:10:13:10 | a [element 1] : | +| array_flow.rb:9:5:9:5 | a [element 1] : | array_flow.rb:11:10:11:10 | a [element 1] : | +| array_flow.rb:9:5:9:5 | a [element 1] : | array_flow.rb:11:10:11:10 | a [element 1] : | +| array_flow.rb:9:5:9:5 | a [element 1] : | array_flow.rb:13:10:13:10 | a [element 1] : | +| array_flow.rb:9:5:9:5 | a [element 1] : | array_flow.rb:13:10:13:10 | a [element 1] : | +| array_flow.rb:9:13:9:21 | call to source : | array_flow.rb:9:5:9:5 | a [element 1] : | +| array_flow.rb:9:13:9:21 | call to source : | array_flow.rb:9:5:9:5 | a [element 1] : | | array_flow.rb:11:10:11:10 | a [element 1] : | array_flow.rb:11:10:11:13 | ...[...] | | array_flow.rb:11:10:11:10 | a [element 1] : | array_flow.rb:11:10:11:13 | ...[...] | | array_flow.rb:13:10:13:10 | a [element 1] : | array_flow.rb:13:10:13:13 | ...[...] | | array_flow.rb:13:10:13:10 | a [element 1] : | array_flow.rb:13:10:13:13 | ...[...] | -| array_flow.rb:17:9:17:33 | call to new [element] : | array_flow.rb:18:10:18:10 | a [element] : | -| array_flow.rb:17:9:17:33 | call to new [element] : | array_flow.rb:18:10:18:10 | a [element] : | -| array_flow.rb:17:9:17:33 | call to new [element] : | array_flow.rb:19:10:19:10 | a [element] : | -| array_flow.rb:17:9:17:33 | call to new [element] : | array_flow.rb:19:10:19:10 | a [element] : | -| array_flow.rb:17:9:17:33 | call to new [element] : | array_flow.rb:21:19:21:19 | a [element] : | -| array_flow.rb:17:9:17:33 | call to new [element] : | array_flow.rb:21:19:21:19 | a [element] : | +| array_flow.rb:17:5:17:5 | a [element] : | array_flow.rb:18:10:18:10 | a [element] : | +| array_flow.rb:17:5:17:5 | a [element] : | array_flow.rb:18:10:18:10 | a [element] : | +| array_flow.rb:17:5:17:5 | a [element] : | array_flow.rb:19:10:19:10 | a [element] : | +| array_flow.rb:17:5:17:5 | a [element] : | array_flow.rb:19:10:19:10 | a [element] : | +| array_flow.rb:17:5:17:5 | a [element] : | array_flow.rb:21:19:21:19 | a [element] : | +| array_flow.rb:17:5:17:5 | a [element] : | array_flow.rb:21:19:21:19 | a [element] : | +| array_flow.rb:17:9:17:33 | call to new [element] : | array_flow.rb:17:5:17:5 | a [element] : | +| array_flow.rb:17:9:17:33 | call to new [element] : | array_flow.rb:17:5:17:5 | a [element] : | | array_flow.rb:17:22:17:32 | call to source : | array_flow.rb:17:9:17:33 | call to new [element] : | | array_flow.rb:17:22:17:32 | call to source : | array_flow.rb:17:9:17:33 | call to new [element] : | | array_flow.rb:18:10:18:10 | a [element] : | array_flow.rb:18:10:18:13 | ...[...] | | array_flow.rb:18:10:18:10 | a [element] : | array_flow.rb:18:10:18:13 | ...[...] | | array_flow.rb:19:10:19:10 | a [element] : | array_flow.rb:19:10:19:13 | ...[...] | | array_flow.rb:19:10:19:10 | a [element] : | array_flow.rb:19:10:19:13 | ...[...] | -| array_flow.rb:21:9:21:20 | call to new [element] : | array_flow.rb:22:10:22:10 | b [element] : | -| array_flow.rb:21:9:21:20 | call to new [element] : | array_flow.rb:22:10:22:10 | b [element] : | -| array_flow.rb:21:9:21:20 | call to new [element] : | array_flow.rb:23:10:23:10 | b [element] : | -| array_flow.rb:21:9:21:20 | call to new [element] : | array_flow.rb:23:10:23:10 | b [element] : | +| array_flow.rb:21:5:21:5 | b [element] : | array_flow.rb:22:10:22:10 | b [element] : | +| array_flow.rb:21:5:21:5 | b [element] : | array_flow.rb:22:10:22:10 | b [element] : | +| array_flow.rb:21:5:21:5 | b [element] : | array_flow.rb:23:10:23:10 | b [element] : | +| array_flow.rb:21:5:21:5 | b [element] : | array_flow.rb:23:10:23:10 | b [element] : | +| array_flow.rb:21:9:21:20 | call to new [element] : | array_flow.rb:21:5:21:5 | b [element] : | +| array_flow.rb:21:9:21:20 | call to new [element] : | array_flow.rb:21:5:21:5 | b [element] : | | array_flow.rb:21:19:21:19 | a [element] : | array_flow.rb:21:9:21:20 | call to new [element] : | | array_flow.rb:21:19:21:19 | a [element] : | array_flow.rb:21:9:21:20 | call to new [element] : | | array_flow.rb:22:10:22:10 | b [element] : | array_flow.rb:22:10:22:13 | ...[...] | | array_flow.rb:22:10:22:10 | b [element] : | array_flow.rb:22:10:22:13 | ...[...] | | array_flow.rb:23:10:23:10 | b [element] : | array_flow.rb:23:10:23:13 | ...[...] | | array_flow.rb:23:10:23:10 | b [element] : | array_flow.rb:23:10:23:13 | ...[...] | -| array_flow.rb:25:9:27:7 | call to new [element] : | array_flow.rb:28:10:28:10 | c [element] : | -| array_flow.rb:25:9:27:7 | call to new [element] : | array_flow.rb:28:10:28:10 | c [element] : | -| array_flow.rb:25:9:27:7 | call to new [element] : | array_flow.rb:29:10:29:10 | c [element] : | -| array_flow.rb:25:9:27:7 | call to new [element] : | array_flow.rb:29:10:29:10 | c [element] : | +| array_flow.rb:25:5:25:5 | c [element] : | array_flow.rb:28:10:28:10 | c [element] : | +| array_flow.rb:25:5:25:5 | c [element] : | array_flow.rb:28:10:28:10 | c [element] : | +| array_flow.rb:25:5:25:5 | c [element] : | array_flow.rb:29:10:29:10 | c [element] : | +| array_flow.rb:25:5:25:5 | c [element] : | array_flow.rb:29:10:29:10 | c [element] : | +| array_flow.rb:25:9:27:7 | call to new [element] : | array_flow.rb:25:5:25:5 | c [element] : | +| array_flow.rb:25:9:27:7 | call to new [element] : | array_flow.rb:25:5:25:5 | c [element] : | | array_flow.rb:26:9:26:19 | call to source : | array_flow.rb:25:9:27:7 | call to new [element] : | | array_flow.rb:26:9:26:19 | call to source : | array_flow.rb:25:9:27:7 | call to new [element] : | | array_flow.rb:28:10:28:10 | c [element] : | array_flow.rb:28:10:28:13 | ...[...] | | array_flow.rb:28:10:28:10 | c [element] : | array_flow.rb:28:10:28:13 | ...[...] | | array_flow.rb:29:10:29:10 | c [element] : | array_flow.rb:29:10:29:13 | ...[...] | | array_flow.rb:29:10:29:10 | c [element] : | array_flow.rb:29:10:29:13 | ...[...] | -| array_flow.rb:33:10:33:18 | call to source : | array_flow.rb:34:27:34:27 | a [element 0] : | -| array_flow.rb:33:10:33:18 | call to source : | array_flow.rb:34:27:34:27 | a [element 0] : | -| array_flow.rb:34:9:34:28 | call to try_convert [element 0] : | array_flow.rb:35:10:35:10 | b [element 0] : | -| array_flow.rb:34:9:34:28 | call to try_convert [element 0] : | array_flow.rb:35:10:35:10 | b [element 0] : | +| array_flow.rb:33:5:33:5 | a [element 0] : | array_flow.rb:34:27:34:27 | a [element 0] : | +| array_flow.rb:33:5:33:5 | a [element 0] : | array_flow.rb:34:27:34:27 | a [element 0] : | +| array_flow.rb:33:10:33:18 | call to source : | array_flow.rb:33:5:33:5 | a [element 0] : | +| array_flow.rb:33:10:33:18 | call to source : | array_flow.rb:33:5:33:5 | a [element 0] : | +| array_flow.rb:34:5:34:5 | b [element 0] : | array_flow.rb:35:10:35:10 | b [element 0] : | +| array_flow.rb:34:5:34:5 | b [element 0] : | array_flow.rb:35:10:35:10 | b [element 0] : | +| array_flow.rb:34:9:34:28 | call to try_convert [element 0] : | array_flow.rb:34:5:34:5 | b [element 0] : | +| array_flow.rb:34:9:34:28 | call to try_convert [element 0] : | array_flow.rb:34:5:34:5 | b [element 0] : | | array_flow.rb:34:27:34:27 | a [element 0] : | array_flow.rb:34:9:34:28 | call to try_convert [element 0] : | | array_flow.rb:34:27:34:27 | a [element 0] : | array_flow.rb:34:9:34:28 | call to try_convert [element 0] : | | array_flow.rb:35:10:35:10 | b [element 0] : | array_flow.rb:35:10:35:13 | ...[...] | | array_flow.rb:35:10:35:10 | b [element 0] : | array_flow.rb:35:10:35:13 | ...[...] | -| array_flow.rb:40:10:40:20 | call to source : | array_flow.rb:42:9:42:9 | a [element 0] : | -| array_flow.rb:40:10:40:20 | call to source : | array_flow.rb:42:9:42:9 | a [element 0] : | -| array_flow.rb:41:16:41:26 | call to source : | array_flow.rb:42:13:42:13 | b [element 2] : | -| array_flow.rb:41:16:41:26 | call to source : | array_flow.rb:42:13:42:13 | b [element 2] : | +| array_flow.rb:40:5:40:5 | a [element 0] : | array_flow.rb:42:9:42:9 | a [element 0] : | +| array_flow.rb:40:5:40:5 | a [element 0] : | array_flow.rb:42:9:42:9 | a [element 0] : | +| array_flow.rb:40:10:40:20 | call to source : | array_flow.rb:40:5:40:5 | a [element 0] : | +| array_flow.rb:40:10:40:20 | call to source : | array_flow.rb:40:5:40:5 | a [element 0] : | +| array_flow.rb:41:5:41:5 | b [element 2] : | array_flow.rb:42:13:42:13 | b [element 2] : | +| array_flow.rb:41:5:41:5 | b [element 2] : | array_flow.rb:42:13:42:13 | b [element 2] : | +| array_flow.rb:41:16:41:26 | call to source : | array_flow.rb:41:5:41:5 | b [element 2] : | +| array_flow.rb:41:16:41:26 | call to source : | array_flow.rb:41:5:41:5 | b [element 2] : | +| array_flow.rb:42:5:42:5 | c [element] : | array_flow.rb:43:10:43:10 | c [element] : | +| array_flow.rb:42:5:42:5 | c [element] : | array_flow.rb:43:10:43:10 | c [element] : | +| array_flow.rb:42:5:42:5 | c [element] : | array_flow.rb:44:10:44:10 | c [element] : | +| array_flow.rb:42:5:42:5 | c [element] : | array_flow.rb:44:10:44:10 | c [element] : | | array_flow.rb:42:9:42:9 | a [element 0] : | array_flow.rb:42:9:42:13 | ... & ... [element] : | | array_flow.rb:42:9:42:9 | a [element 0] : | array_flow.rb:42:9:42:13 | ... & ... [element] : | -| array_flow.rb:42:9:42:13 | ... & ... [element] : | array_flow.rb:43:10:43:10 | c [element] : | -| array_flow.rb:42:9:42:13 | ... & ... [element] : | array_flow.rb:43:10:43:10 | c [element] : | -| array_flow.rb:42:9:42:13 | ... & ... [element] : | array_flow.rb:44:10:44:10 | c [element] : | -| array_flow.rb:42:9:42:13 | ... & ... [element] : | array_flow.rb:44:10:44:10 | c [element] : | +| array_flow.rb:42:9:42:13 | ... & ... [element] : | array_flow.rb:42:5:42:5 | c [element] : | +| array_flow.rb:42:9:42:13 | ... & ... [element] : | array_flow.rb:42:5:42:5 | c [element] : | | array_flow.rb:42:13:42:13 | b [element 2] : | array_flow.rb:42:9:42:13 | ... & ... [element] : | | array_flow.rb:42:13:42:13 | b [element 2] : | array_flow.rb:42:9:42:13 | ... & ... [element] : | | array_flow.rb:43:10:43:10 | c [element] : | array_flow.rb:43:10:43:13 | ...[...] | | array_flow.rb:43:10:43:10 | c [element] : | array_flow.rb:43:10:43:13 | ...[...] | | array_flow.rb:44:10:44:10 | c [element] : | array_flow.rb:44:10:44:13 | ...[...] | | array_flow.rb:44:10:44:10 | c [element] : | array_flow.rb:44:10:44:13 | ...[...] | -| array_flow.rb:48:10:48:18 | call to source : | array_flow.rb:49:9:49:9 | a [element 0] : | -| array_flow.rb:48:10:48:18 | call to source : | array_flow.rb:49:9:49:9 | a [element 0] : | +| array_flow.rb:48:5:48:5 | a [element 0] : | array_flow.rb:49:9:49:9 | a [element 0] : | +| array_flow.rb:48:5:48:5 | a [element 0] : | array_flow.rb:49:9:49:9 | a [element 0] : | +| array_flow.rb:48:10:48:18 | call to source : | array_flow.rb:48:5:48:5 | a [element 0] : | +| array_flow.rb:48:10:48:18 | call to source : | array_flow.rb:48:5:48:5 | a [element 0] : | +| array_flow.rb:49:5:49:5 | b [element] : | array_flow.rb:50:10:50:10 | b [element] : | +| array_flow.rb:49:5:49:5 | b [element] : | array_flow.rb:50:10:50:10 | b [element] : | +| array_flow.rb:49:5:49:5 | b [element] : | array_flow.rb:51:10:51:10 | b [element] : | +| array_flow.rb:49:5:49:5 | b [element] : | array_flow.rb:51:10:51:10 | b [element] : | | array_flow.rb:49:9:49:9 | a [element 0] : | array_flow.rb:49:9:49:13 | ... * ... [element] : | | array_flow.rb:49:9:49:9 | a [element 0] : | array_flow.rb:49:9:49:13 | ... * ... [element] : | -| array_flow.rb:49:9:49:13 | ... * ... [element] : | array_flow.rb:50:10:50:10 | b [element] : | -| array_flow.rb:49:9:49:13 | ... * ... [element] : | array_flow.rb:50:10:50:10 | b [element] : | -| array_flow.rb:49:9:49:13 | ... * ... [element] : | array_flow.rb:51:10:51:10 | b [element] : | -| array_flow.rb:49:9:49:13 | ... * ... [element] : | array_flow.rb:51:10:51:10 | b [element] : | +| array_flow.rb:49:9:49:13 | ... * ... [element] : | array_flow.rb:49:5:49:5 | b [element] : | +| array_flow.rb:49:9:49:13 | ... * ... [element] : | array_flow.rb:49:5:49:5 | b [element] : | | array_flow.rb:50:10:50:10 | b [element] : | array_flow.rb:50:10:50:13 | ...[...] | | array_flow.rb:50:10:50:10 | b [element] : | array_flow.rb:50:10:50:13 | ...[...] | | array_flow.rb:51:10:51:10 | b [element] : | array_flow.rb:51:10:51:13 | ...[...] | | array_flow.rb:51:10:51:10 | b [element] : | array_flow.rb:51:10:51:13 | ...[...] | -| array_flow.rb:55:10:55:20 | call to source : | array_flow.rb:57:9:57:9 | a [element 0] : | -| array_flow.rb:55:10:55:20 | call to source : | array_flow.rb:57:9:57:9 | a [element 0] : | -| array_flow.rb:56:13:56:23 | call to source : | array_flow.rb:57:13:57:13 | b [element 1] : | -| array_flow.rb:56:13:56:23 | call to source : | array_flow.rb:57:13:57:13 | b [element 1] : | +| array_flow.rb:55:5:55:5 | a [element 0] : | array_flow.rb:57:9:57:9 | a [element 0] : | +| array_flow.rb:55:5:55:5 | a [element 0] : | array_flow.rb:57:9:57:9 | a [element 0] : | +| array_flow.rb:55:10:55:20 | call to source : | array_flow.rb:55:5:55:5 | a [element 0] : | +| array_flow.rb:55:10:55:20 | call to source : | array_flow.rb:55:5:55:5 | a [element 0] : | +| array_flow.rb:56:5:56:5 | b [element 1] : | array_flow.rb:57:13:57:13 | b [element 1] : | +| array_flow.rb:56:5:56:5 | b [element 1] : | array_flow.rb:57:13:57:13 | b [element 1] : | +| array_flow.rb:56:13:56:23 | call to source : | array_flow.rb:56:5:56:5 | b [element 1] : | +| array_flow.rb:56:13:56:23 | call to source : | array_flow.rb:56:5:56:5 | b [element 1] : | +| array_flow.rb:57:5:57:5 | c [element 0] : | array_flow.rb:58:10:58:10 | c [element 0] : | +| array_flow.rb:57:5:57:5 | c [element 0] : | array_flow.rb:58:10:58:10 | c [element 0] : | +| array_flow.rb:57:5:57:5 | c [element] : | array_flow.rb:58:10:58:10 | c [element] : | +| array_flow.rb:57:5:57:5 | c [element] : | array_flow.rb:58:10:58:10 | c [element] : | +| array_flow.rb:57:5:57:5 | c [element] : | array_flow.rb:59:10:59:10 | c [element] : | +| array_flow.rb:57:5:57:5 | c [element] : | array_flow.rb:59:10:59:10 | c [element] : | | array_flow.rb:57:9:57:9 | a [element 0] : | array_flow.rb:57:9:57:13 | ... + ... [element 0] : | | array_flow.rb:57:9:57:9 | a [element 0] : | array_flow.rb:57:9:57:13 | ... + ... [element 0] : | -| array_flow.rb:57:9:57:13 | ... + ... [element 0] : | array_flow.rb:58:10:58:10 | c [element 0] : | -| array_flow.rb:57:9:57:13 | ... + ... [element 0] : | array_flow.rb:58:10:58:10 | c [element 0] : | -| array_flow.rb:57:9:57:13 | ... + ... [element] : | array_flow.rb:58:10:58:10 | c [element] : | -| array_flow.rb:57:9:57:13 | ... + ... [element] : | array_flow.rb:58:10:58:10 | c [element] : | -| array_flow.rb:57:9:57:13 | ... + ... [element] : | array_flow.rb:59:10:59:10 | c [element] : | -| array_flow.rb:57:9:57:13 | ... + ... [element] : | array_flow.rb:59:10:59:10 | c [element] : | +| array_flow.rb:57:9:57:13 | ... + ... [element 0] : | array_flow.rb:57:5:57:5 | c [element 0] : | +| array_flow.rb:57:9:57:13 | ... + ... [element 0] : | array_flow.rb:57:5:57:5 | c [element 0] : | +| array_flow.rb:57:9:57:13 | ... + ... [element] : | array_flow.rb:57:5:57:5 | c [element] : | +| array_flow.rb:57:9:57:13 | ... + ... [element] : | array_flow.rb:57:5:57:5 | c [element] : | | array_flow.rb:57:13:57:13 | b [element 1] : | array_flow.rb:57:9:57:13 | ... + ... [element] : | | array_flow.rb:57:13:57:13 | b [element 1] : | array_flow.rb:57:9:57:13 | ... + ... [element] : | | array_flow.rb:58:10:58:10 | c [element 0] : | array_flow.rb:58:10:58:13 | ...[...] | @@ -106,40 +138,51 @@ edges | array_flow.rb:58:10:58:10 | c [element] : | array_flow.rb:58:10:58:13 | ...[...] | | array_flow.rb:59:10:59:10 | c [element] : | array_flow.rb:59:10:59:13 | ...[...] | | array_flow.rb:59:10:59:10 | c [element] : | array_flow.rb:59:10:59:13 | ...[...] | -| array_flow.rb:63:10:63:20 | call to source : | array_flow.rb:65:9:65:9 | a [element 0] : | -| array_flow.rb:63:10:63:20 | call to source : | array_flow.rb:65:9:65:9 | a [element 0] : | +| array_flow.rb:63:5:63:5 | a [element 0] : | array_flow.rb:65:9:65:9 | a [element 0] : | +| array_flow.rb:63:5:63:5 | a [element 0] : | array_flow.rb:65:9:65:9 | a [element 0] : | +| array_flow.rb:63:10:63:20 | call to source : | array_flow.rb:63:5:63:5 | a [element 0] : | +| array_flow.rb:63:10:63:20 | call to source : | array_flow.rb:63:5:63:5 | a [element 0] : | +| array_flow.rb:65:5:65:5 | c [element] : | array_flow.rb:66:10:66:10 | c [element] : | +| array_flow.rb:65:5:65:5 | c [element] : | array_flow.rb:66:10:66:10 | c [element] : | +| array_flow.rb:65:5:65:5 | c [element] : | array_flow.rb:67:10:67:10 | c [element] : | +| array_flow.rb:65:5:65:5 | c [element] : | array_flow.rb:67:10:67:10 | c [element] : | | array_flow.rb:65:9:65:9 | a [element 0] : | array_flow.rb:65:9:65:13 | ... - ... [element] : | | array_flow.rb:65:9:65:9 | a [element 0] : | array_flow.rb:65:9:65:13 | ... - ... [element] : | -| array_flow.rb:65:9:65:13 | ... - ... [element] : | array_flow.rb:66:10:66:10 | c [element] : | -| array_flow.rb:65:9:65:13 | ... - ... [element] : | array_flow.rb:66:10:66:10 | c [element] : | -| array_flow.rb:65:9:65:13 | ... - ... [element] : | array_flow.rb:67:10:67:10 | c [element] : | -| array_flow.rb:65:9:65:13 | ... - ... [element] : | array_flow.rb:67:10:67:10 | c [element] : | +| array_flow.rb:65:9:65:13 | ... - ... [element] : | array_flow.rb:65:5:65:5 | c [element] : | +| array_flow.rb:65:9:65:13 | ... - ... [element] : | array_flow.rb:65:5:65:5 | c [element] : | | array_flow.rb:66:10:66:10 | c [element] : | array_flow.rb:66:10:66:13 | ...[...] | | array_flow.rb:66:10:66:10 | c [element] : | array_flow.rb:66:10:66:13 | ...[...] | | array_flow.rb:67:10:67:10 | c [element] : | array_flow.rb:67:10:67:13 | ...[...] | | array_flow.rb:67:10:67:10 | c [element] : | array_flow.rb:67:10:67:13 | ...[...] | -| array_flow.rb:71:10:71:20 | call to source : | array_flow.rb:72:9:72:9 | a [element 0] : | -| array_flow.rb:71:10:71:20 | call to source : | array_flow.rb:72:9:72:9 | a [element 0] : | -| array_flow.rb:71:10:71:20 | call to source : | array_flow.rb:73:10:73:10 | a [element 0] : | -| array_flow.rb:71:10:71:20 | call to source : | array_flow.rb:73:10:73:10 | a [element 0] : | +| array_flow.rb:71:5:71:5 | a [element 0] : | array_flow.rb:72:9:72:9 | a [element 0] : | +| array_flow.rb:71:5:71:5 | a [element 0] : | array_flow.rb:72:9:72:9 | a [element 0] : | +| array_flow.rb:71:5:71:5 | a [element 0] : | array_flow.rb:73:10:73:10 | a [element 0] : | +| array_flow.rb:71:5:71:5 | a [element 0] : | array_flow.rb:73:10:73:10 | a [element 0] : | +| array_flow.rb:71:10:71:20 | call to source : | array_flow.rb:71:5:71:5 | a [element 0] : | +| array_flow.rb:71:10:71:20 | call to source : | array_flow.rb:71:5:71:5 | a [element 0] : | +| array_flow.rb:72:5:72:5 | b : | array_flow.rb:75:10:75:10 | b : | +| array_flow.rb:72:5:72:5 | b : | array_flow.rb:76:10:76:10 | b : | +| array_flow.rb:72:5:72:5 | b [element 0] : | array_flow.rb:75:10:75:10 | b [element 0] : | +| array_flow.rb:72:5:72:5 | b [element 0] : | array_flow.rb:75:10:75:10 | b [element 0] : | +| array_flow.rb:72:5:72:5 | b [element] : | array_flow.rb:75:10:75:10 | b [element] : | +| array_flow.rb:72:5:72:5 | b [element] : | array_flow.rb:75:10:75:10 | b [element] : | +| array_flow.rb:72:5:72:5 | b [element] : | array_flow.rb:76:10:76:10 | b [element] : | +| array_flow.rb:72:5:72:5 | b [element] : | array_flow.rb:76:10:76:10 | b [element] : | | array_flow.rb:72:9:72:9 | [post] a [element] : | array_flow.rb:73:10:73:10 | a [element] : | | array_flow.rb:72:9:72:9 | [post] a [element] : | array_flow.rb:73:10:73:10 | a [element] : | | array_flow.rb:72:9:72:9 | [post] a [element] : | array_flow.rb:74:10:74:10 | a [element] : | | array_flow.rb:72:9:72:9 | [post] a [element] : | array_flow.rb:74:10:74:10 | a [element] : | | array_flow.rb:72:9:72:9 | a [element 0] : | array_flow.rb:72:9:72:24 | ... << ... [element 0] : | | array_flow.rb:72:9:72:9 | a [element 0] : | array_flow.rb:72:9:72:24 | ... << ... [element 0] : | -| array_flow.rb:72:9:72:24 | ... << ... [element 0] : | array_flow.rb:75:10:75:10 | b [element 0] : | -| array_flow.rb:72:9:72:24 | ... << ... [element 0] : | array_flow.rb:75:10:75:10 | b [element 0] : | -| array_flow.rb:72:9:72:24 | ... << ... [element] : | array_flow.rb:75:10:75:10 | b [element] : | -| array_flow.rb:72:9:72:24 | ... << ... [element] : | array_flow.rb:75:10:75:10 | b [element] : | -| array_flow.rb:72:9:72:24 | ... << ... [element] : | array_flow.rb:76:10:76:10 | b [element] : | -| array_flow.rb:72:9:72:24 | ... << ... [element] : | array_flow.rb:76:10:76:10 | b [element] : | +| array_flow.rb:72:9:72:24 | ... << ... [element 0] : | array_flow.rb:72:5:72:5 | b [element 0] : | +| array_flow.rb:72:9:72:24 | ... << ... [element 0] : | array_flow.rb:72:5:72:5 | b [element 0] : | +| array_flow.rb:72:9:72:24 | ... << ... [element] : | array_flow.rb:72:5:72:5 | b [element] : | +| array_flow.rb:72:9:72:24 | ... << ... [element] : | array_flow.rb:72:5:72:5 | b [element] : | +| array_flow.rb:72:14:72:24 | call to source : | array_flow.rb:72:5:72:5 | b : | | array_flow.rb:72:14:72:24 | call to source : | array_flow.rb:72:9:72:9 | [post] a [element] : | | array_flow.rb:72:14:72:24 | call to source : | array_flow.rb:72:9:72:9 | [post] a [element] : | | array_flow.rb:72:14:72:24 | call to source : | array_flow.rb:72:9:72:24 | ... << ... [element] : | | array_flow.rb:72:14:72:24 | call to source : | array_flow.rb:72:9:72:24 | ... << ... [element] : | -| array_flow.rb:72:14:72:24 | call to source : | array_flow.rb:75:10:75:10 | b : | -| array_flow.rb:72:14:72:24 | call to source : | array_flow.rb:76:10:76:10 | b : | | array_flow.rb:73:10:73:10 | a [element 0] : | array_flow.rb:73:10:73:13 | ...[...] | | array_flow.rb:73:10:73:10 | a [element 0] : | array_flow.rb:73:10:73:13 | ...[...] | | array_flow.rb:73:10:73:10 | a [element] : | array_flow.rb:73:10:73:13 | ...[...] | @@ -154,70 +197,96 @@ edges | array_flow.rb:76:10:76:10 | b : | array_flow.rb:76:10:76:13 | ...[...] | | array_flow.rb:76:10:76:10 | b [element] : | array_flow.rb:76:10:76:13 | ...[...] | | array_flow.rb:76:10:76:10 | b [element] : | array_flow.rb:76:10:76:13 | ...[...] | -| array_flow.rb:80:13:80:21 | call to source : | array_flow.rb:81:15:81:15 | a [element 1] : | -| array_flow.rb:80:13:80:21 | call to source : | array_flow.rb:81:15:81:15 | a [element 1] : | -| array_flow.rb:81:15:81:15 | a [element 1] : | array_flow.rb:83:10:83:10 | c | -| array_flow.rb:81:15:81:15 | a [element 1] : | array_flow.rb:83:10:83:10 | c | -| array_flow.rb:88:13:88:22 | call to source : | array_flow.rb:89:9:89:9 | a [element 1] : | -| array_flow.rb:88:13:88:22 | call to source : | array_flow.rb:89:9:89:9 | a [element 1] : | +| array_flow.rb:80:5:80:5 | a [element 1] : | array_flow.rb:81:15:81:15 | a [element 1] : | +| array_flow.rb:80:5:80:5 | a [element 1] : | array_flow.rb:81:15:81:15 | a [element 1] : | +| array_flow.rb:80:13:80:21 | call to source : | array_flow.rb:80:5:80:5 | a [element 1] : | +| array_flow.rb:80:13:80:21 | call to source : | array_flow.rb:80:5:80:5 | a [element 1] : | +| array_flow.rb:81:8:81:8 | c : | array_flow.rb:83:10:83:10 | c | +| array_flow.rb:81:8:81:8 | c : | array_flow.rb:83:10:83:10 | c | +| array_flow.rb:81:15:81:15 | __synth__0 [element 1] : | array_flow.rb:81:8:81:8 | c : | +| array_flow.rb:81:15:81:15 | __synth__0 [element 1] : | array_flow.rb:81:8:81:8 | c : | +| array_flow.rb:81:15:81:15 | a [element 1] : | array_flow.rb:81:15:81:15 | __synth__0 [element 1] : | +| array_flow.rb:81:15:81:15 | a [element 1] : | array_flow.rb:81:15:81:15 | __synth__0 [element 1] : | +| array_flow.rb:88:5:88:5 | a [element 1] : | array_flow.rb:89:9:89:9 | a [element 1] : | +| array_flow.rb:88:5:88:5 | a [element 1] : | array_flow.rb:89:9:89:9 | a [element 1] : | +| array_flow.rb:88:13:88:22 | call to source : | array_flow.rb:88:5:88:5 | a [element 1] : | +| array_flow.rb:88:13:88:22 | call to source : | array_flow.rb:88:5:88:5 | a [element 1] : | +| array_flow.rb:89:5:89:5 | b [element 1] : | array_flow.rb:91:10:91:10 | b [element 1] : | +| array_flow.rb:89:5:89:5 | b [element 1] : | array_flow.rb:91:10:91:10 | b [element 1] : | +| array_flow.rb:89:5:89:5 | b [element 1] : | array_flow.rb:92:10:92:10 | b [element 1] : | +| array_flow.rb:89:5:89:5 | b [element 1] : | array_flow.rb:92:10:92:10 | b [element 1] : | | array_flow.rb:89:9:89:9 | a [element 1] : | array_flow.rb:89:9:89:15 | ...[...] [element 1] : | | array_flow.rb:89:9:89:9 | a [element 1] : | array_flow.rb:89:9:89:15 | ...[...] [element 1] : | -| array_flow.rb:89:9:89:15 | ...[...] [element 1] : | array_flow.rb:91:10:91:10 | b [element 1] : | -| array_flow.rb:89:9:89:15 | ...[...] [element 1] : | array_flow.rb:91:10:91:10 | b [element 1] : | -| array_flow.rb:89:9:89:15 | ...[...] [element 1] : | array_flow.rb:92:10:92:10 | b [element 1] : | -| array_flow.rb:89:9:89:15 | ...[...] [element 1] : | array_flow.rb:92:10:92:10 | b [element 1] : | +| array_flow.rb:89:9:89:15 | ...[...] [element 1] : | array_flow.rb:89:5:89:5 | b [element 1] : | +| array_flow.rb:89:9:89:15 | ...[...] [element 1] : | array_flow.rb:89:5:89:5 | b [element 1] : | | array_flow.rb:91:10:91:10 | b [element 1] : | array_flow.rb:91:10:91:13 | ...[...] | | array_flow.rb:91:10:91:10 | b [element 1] : | array_flow.rb:91:10:91:13 | ...[...] | | array_flow.rb:92:10:92:10 | b [element 1] : | array_flow.rb:92:10:92:13 | ...[...] | | array_flow.rb:92:10:92:10 | b [element 1] : | array_flow.rb:92:10:92:13 | ...[...] | -| array_flow.rb:96:13:96:22 | call to source : | array_flow.rb:97:9:97:9 | a [element 1] : | -| array_flow.rb:96:13:96:22 | call to source : | array_flow.rb:97:9:97:9 | a [element 1] : | +| array_flow.rb:96:5:96:5 | a [element 1] : | array_flow.rb:97:9:97:9 | a [element 1] : | +| array_flow.rb:96:5:96:5 | a [element 1] : | array_flow.rb:97:9:97:9 | a [element 1] : | +| array_flow.rb:96:13:96:22 | call to source : | array_flow.rb:96:5:96:5 | a [element 1] : | +| array_flow.rb:96:13:96:22 | call to source : | array_flow.rb:96:5:96:5 | a [element 1] : | +| array_flow.rb:97:5:97:5 | b [element 1] : | array_flow.rb:99:10:99:10 | b [element 1] : | +| array_flow.rb:97:5:97:5 | b [element 1] : | array_flow.rb:99:10:99:10 | b [element 1] : | +| array_flow.rb:97:5:97:5 | b [element 1] : | array_flow.rb:101:10:101:10 | b [element 1] : | +| array_flow.rb:97:5:97:5 | b [element 1] : | array_flow.rb:101:10:101:10 | b [element 1] : | | array_flow.rb:97:9:97:9 | a [element 1] : | array_flow.rb:97:9:97:15 | ...[...] [element 1] : | | array_flow.rb:97:9:97:9 | a [element 1] : | array_flow.rb:97:9:97:15 | ...[...] [element 1] : | -| array_flow.rb:97:9:97:15 | ...[...] [element 1] : | array_flow.rb:99:10:99:10 | b [element 1] : | -| array_flow.rb:97:9:97:15 | ...[...] [element 1] : | array_flow.rb:99:10:99:10 | b [element 1] : | -| array_flow.rb:97:9:97:15 | ...[...] [element 1] : | array_flow.rb:101:10:101:10 | b [element 1] : | -| array_flow.rb:97:9:97:15 | ...[...] [element 1] : | array_flow.rb:101:10:101:10 | b [element 1] : | +| array_flow.rb:97:9:97:15 | ...[...] [element 1] : | array_flow.rb:97:5:97:5 | b [element 1] : | +| array_flow.rb:97:9:97:15 | ...[...] [element 1] : | array_flow.rb:97:5:97:5 | b [element 1] : | | array_flow.rb:99:10:99:10 | b [element 1] : | array_flow.rb:99:10:99:13 | ...[...] | | array_flow.rb:99:10:99:10 | b [element 1] : | array_flow.rb:99:10:99:13 | ...[...] | | array_flow.rb:101:10:101:10 | b [element 1] : | array_flow.rb:101:10:101:13 | ...[...] | | array_flow.rb:101:10:101:10 | b [element 1] : | array_flow.rb:101:10:101:13 | ...[...] | -| array_flow.rb:103:13:103:24 | call to source : | array_flow.rb:104:9:104:9 | a [element 1] : | -| array_flow.rb:103:13:103:24 | call to source : | array_flow.rb:104:9:104:9 | a [element 1] : | +| array_flow.rb:103:5:103:5 | a [element 1] : | array_flow.rb:104:9:104:9 | a [element 1] : | +| array_flow.rb:103:5:103:5 | a [element 1] : | array_flow.rb:104:9:104:9 | a [element 1] : | +| array_flow.rb:103:13:103:24 | call to source : | array_flow.rb:103:5:103:5 | a [element 1] : | +| array_flow.rb:103:13:103:24 | call to source : | array_flow.rb:103:5:103:5 | a [element 1] : | +| array_flow.rb:104:5:104:5 | b [element 1] : | array_flow.rb:106:10:106:10 | b [element 1] : | +| array_flow.rb:104:5:104:5 | b [element 1] : | array_flow.rb:106:10:106:10 | b [element 1] : | | array_flow.rb:104:9:104:9 | a [element 1] : | array_flow.rb:104:9:104:16 | ...[...] [element 1] : | | array_flow.rb:104:9:104:9 | a [element 1] : | array_flow.rb:104:9:104:16 | ...[...] [element 1] : | -| array_flow.rb:104:9:104:16 | ...[...] [element 1] : | array_flow.rb:106:10:106:10 | b [element 1] : | -| array_flow.rb:104:9:104:16 | ...[...] [element 1] : | array_flow.rb:106:10:106:10 | b [element 1] : | +| array_flow.rb:104:9:104:16 | ...[...] [element 1] : | array_flow.rb:104:5:104:5 | b [element 1] : | +| array_flow.rb:104:9:104:16 | ...[...] [element 1] : | array_flow.rb:104:5:104:5 | b [element 1] : | | array_flow.rb:106:10:106:10 | b [element 1] : | array_flow.rb:106:10:106:13 | ...[...] | | array_flow.rb:106:10:106:10 | b [element 1] : | array_flow.rb:106:10:106:13 | ...[...] | -| array_flow.rb:109:13:109:24 | call to source : | array_flow.rb:110:9:110:9 | a [element 1] : | -| array_flow.rb:109:13:109:24 | call to source : | array_flow.rb:110:9:110:9 | a [element 1] : | -| array_flow.rb:109:13:109:24 | call to source : | array_flow.rb:114:9:114:9 | a [element 1] : | -| array_flow.rb:109:13:109:24 | call to source : | array_flow.rb:114:9:114:9 | a [element 1] : | -| array_flow.rb:109:30:109:41 | call to source : | array_flow.rb:110:9:110:9 | a [element 3] : | -| array_flow.rb:109:30:109:41 | call to source : | array_flow.rb:110:9:110:9 | a [element 3] : | -| array_flow.rb:109:30:109:41 | call to source : | array_flow.rb:114:9:114:9 | a [element 3] : | -| array_flow.rb:109:30:109:41 | call to source : | array_flow.rb:114:9:114:9 | a [element 3] : | +| array_flow.rb:109:5:109:5 | a [element 1] : | array_flow.rb:110:9:110:9 | a [element 1] : | +| array_flow.rb:109:5:109:5 | a [element 1] : | array_flow.rb:110:9:110:9 | a [element 1] : | +| array_flow.rb:109:5:109:5 | a [element 1] : | array_flow.rb:114:9:114:9 | a [element 1] : | +| array_flow.rb:109:5:109:5 | a [element 1] : | array_flow.rb:114:9:114:9 | a [element 1] : | +| array_flow.rb:109:5:109:5 | a [element 3] : | array_flow.rb:110:9:110:9 | a [element 3] : | +| array_flow.rb:109:5:109:5 | a [element 3] : | array_flow.rb:110:9:110:9 | a [element 3] : | +| array_flow.rb:109:5:109:5 | a [element 3] : | array_flow.rb:114:9:114:9 | a [element 3] : | +| array_flow.rb:109:5:109:5 | a [element 3] : | array_flow.rb:114:9:114:9 | a [element 3] : | +| array_flow.rb:109:13:109:24 | call to source : | array_flow.rb:109:5:109:5 | a [element 1] : | +| array_flow.rb:109:13:109:24 | call to source : | array_flow.rb:109:5:109:5 | a [element 1] : | +| array_flow.rb:109:30:109:41 | call to source : | array_flow.rb:109:5:109:5 | a [element 3] : | +| array_flow.rb:109:30:109:41 | call to source : | array_flow.rb:109:5:109:5 | a [element 3] : | +| array_flow.rb:110:5:110:5 | b [element] : | array_flow.rb:111:10:111:10 | b [element] : | +| array_flow.rb:110:5:110:5 | b [element] : | array_flow.rb:111:10:111:10 | b [element] : | +| array_flow.rb:110:5:110:5 | b [element] : | array_flow.rb:112:10:112:10 | b [element] : | +| array_flow.rb:110:5:110:5 | b [element] : | array_flow.rb:112:10:112:10 | b [element] : | | array_flow.rb:110:9:110:9 | a [element 1] : | array_flow.rb:110:9:110:18 | ...[...] [element] : | | array_flow.rb:110:9:110:9 | a [element 1] : | array_flow.rb:110:9:110:18 | ...[...] [element] : | | array_flow.rb:110:9:110:9 | a [element 3] : | array_flow.rb:110:9:110:18 | ...[...] [element] : | | array_flow.rb:110:9:110:9 | a [element 3] : | array_flow.rb:110:9:110:18 | ...[...] [element] : | -| array_flow.rb:110:9:110:18 | ...[...] [element] : | array_flow.rb:111:10:111:10 | b [element] : | -| array_flow.rb:110:9:110:18 | ...[...] [element] : | array_flow.rb:111:10:111:10 | b [element] : | -| array_flow.rb:110:9:110:18 | ...[...] [element] : | array_flow.rb:112:10:112:10 | b [element] : | -| array_flow.rb:110:9:110:18 | ...[...] [element] : | array_flow.rb:112:10:112:10 | b [element] : | +| array_flow.rb:110:9:110:18 | ...[...] [element] : | array_flow.rb:110:5:110:5 | b [element] : | +| array_flow.rb:110:9:110:18 | ...[...] [element] : | array_flow.rb:110:5:110:5 | b [element] : | | array_flow.rb:111:10:111:10 | b [element] : | array_flow.rb:111:10:111:13 | ...[...] | | array_flow.rb:111:10:111:10 | b [element] : | array_flow.rb:111:10:111:13 | ...[...] | | array_flow.rb:112:10:112:10 | b [element] : | array_flow.rb:112:10:112:13 | ...[...] | | array_flow.rb:112:10:112:10 | b [element] : | array_flow.rb:112:10:112:13 | ...[...] | +| array_flow.rb:114:5:114:5 | b [element] : | array_flow.rb:115:10:115:10 | b [element] : | +| array_flow.rb:114:5:114:5 | b [element] : | array_flow.rb:115:10:115:10 | b [element] : | +| array_flow.rb:114:5:114:5 | b [element] : | array_flow.rb:116:10:116:10 | b [element] : | +| array_flow.rb:114:5:114:5 | b [element] : | array_flow.rb:116:10:116:10 | b [element] : | | array_flow.rb:114:9:114:9 | a [element 1] : | array_flow.rb:114:9:114:19 | ...[...] [element] : | | array_flow.rb:114:9:114:9 | a [element 1] : | array_flow.rb:114:9:114:19 | ...[...] [element] : | | array_flow.rb:114:9:114:9 | a [element 3] : | array_flow.rb:114:9:114:19 | ...[...] [element] : | | array_flow.rb:114:9:114:9 | a [element 3] : | array_flow.rb:114:9:114:19 | ...[...] [element] : | -| array_flow.rb:114:9:114:19 | ...[...] [element] : | array_flow.rb:115:10:115:10 | b [element] : | -| array_flow.rb:114:9:114:19 | ...[...] [element] : | array_flow.rb:115:10:115:10 | b [element] : | -| array_flow.rb:114:9:114:19 | ...[...] [element] : | array_flow.rb:116:10:116:10 | b [element] : | -| array_flow.rb:114:9:114:19 | ...[...] [element] : | array_flow.rb:116:10:116:10 | b [element] : | +| array_flow.rb:114:9:114:19 | ...[...] [element] : | array_flow.rb:114:5:114:5 | b [element] : | +| array_flow.rb:114:9:114:19 | ...[...] [element] : | array_flow.rb:114:5:114:5 | b [element] : | | array_flow.rb:115:10:115:10 | b [element] : | array_flow.rb:115:10:115:13 | ...[...] | | array_flow.rb:115:10:115:10 | b [element] : | array_flow.rb:115:10:115:13 | ...[...] | | array_flow.rb:116:10:116:10 | b [element] : | array_flow.rb:116:10:116:13 | ...[...] | @@ -278,34 +347,44 @@ edges | array_flow.rb:147:10:147:10 | a [element] : | array_flow.rb:147:10:147:13 | ...[...] | | array_flow.rb:148:10:148:10 | a [element] : | array_flow.rb:148:10:148:13 | ...[...] | | array_flow.rb:148:10:148:10 | a [element] : | array_flow.rb:148:10:148:13 | ...[...] | -| array_flow.rb:152:16:152:25 | call to source : | array_flow.rb:153:5:153:5 | a [element 2] : | -| array_flow.rb:152:16:152:25 | call to source : | array_flow.rb:153:5:153:5 | a [element 2] : | +| array_flow.rb:152:5:152:5 | a [element 2] : | array_flow.rb:153:5:153:5 | a [element 2] : | +| array_flow.rb:152:5:152:5 | a [element 2] : | array_flow.rb:153:5:153:5 | a [element 2] : | +| array_flow.rb:152:16:152:25 | call to source : | array_flow.rb:152:5:152:5 | a [element 2] : | +| array_flow.rb:152:16:152:25 | call to source : | array_flow.rb:152:5:152:5 | a [element 2] : | | array_flow.rb:153:5:153:5 | a [element 2] : | array_flow.rb:153:16:153:16 | x : | | array_flow.rb:153:5:153:5 | a [element 2] : | array_flow.rb:153:16:153:16 | x : | | array_flow.rb:153:16:153:16 | x : | array_flow.rb:154:14:154:14 | x | | array_flow.rb:153:16:153:16 | x : | array_flow.rb:154:14:154:14 | x | -| array_flow.rb:159:16:159:25 | call to source : | array_flow.rb:160:5:160:5 | a [element 2] : | -| array_flow.rb:159:16:159:25 | call to source : | array_flow.rb:160:5:160:5 | a [element 2] : | +| array_flow.rb:159:5:159:5 | a [element 2] : | array_flow.rb:160:5:160:5 | a [element 2] : | +| array_flow.rb:159:5:159:5 | a [element 2] : | array_flow.rb:160:5:160:5 | a [element 2] : | +| array_flow.rb:159:16:159:25 | call to source : | array_flow.rb:159:5:159:5 | a [element 2] : | +| array_flow.rb:159:16:159:25 | call to source : | array_flow.rb:159:5:159:5 | a [element 2] : | | array_flow.rb:160:5:160:5 | a [element 2] : | array_flow.rb:160:16:160:16 | x : | | array_flow.rb:160:5:160:5 | a [element 2] : | array_flow.rb:160:16:160:16 | x : | | array_flow.rb:160:16:160:16 | x : | array_flow.rb:161:14:161:14 | x | | array_flow.rb:160:16:160:16 | x : | array_flow.rb:161:14:161:14 | x | -| array_flow.rb:166:10:166:21 | call to source : | array_flow.rb:167:9:167:9 | a [element 0] : | -| array_flow.rb:166:10:166:21 | call to source : | array_flow.rb:167:9:167:9 | a [element 0] : | -| array_flow.rb:166:10:166:21 | call to source : | array_flow.rb:168:10:168:10 | a [element 0] : | -| array_flow.rb:166:10:166:21 | call to source : | array_flow.rb:168:10:168:10 | a [element 0] : | +| array_flow.rb:166:5:166:5 | a [element 0] : | array_flow.rb:167:9:167:9 | a [element 0] : | +| array_flow.rb:166:5:166:5 | a [element 0] : | array_flow.rb:167:9:167:9 | a [element 0] : | +| array_flow.rb:166:5:166:5 | a [element 0] : | array_flow.rb:168:10:168:10 | a [element 0] : | +| array_flow.rb:166:5:166:5 | a [element 0] : | array_flow.rb:168:10:168:10 | a [element 0] : | +| array_flow.rb:166:10:166:21 | call to source : | array_flow.rb:166:5:166:5 | a [element 0] : | +| array_flow.rb:166:10:166:21 | call to source : | array_flow.rb:166:5:166:5 | a [element 0] : | +| array_flow.rb:167:5:167:5 | b [element 0] : | array_flow.rb:170:10:170:10 | b [element 0] : | +| array_flow.rb:167:5:167:5 | b [element 0] : | array_flow.rb:170:10:170:10 | b [element 0] : | +| array_flow.rb:167:5:167:5 | b [element] : | array_flow.rb:170:10:170:10 | b [element] : | +| array_flow.rb:167:5:167:5 | b [element] : | array_flow.rb:170:10:170:10 | b [element] : | +| array_flow.rb:167:5:167:5 | b [element] : | array_flow.rb:171:10:171:10 | b [element] : | +| array_flow.rb:167:5:167:5 | b [element] : | array_flow.rb:171:10:171:10 | b [element] : | | array_flow.rb:167:9:167:9 | [post] a [element] : | array_flow.rb:168:10:168:10 | a [element] : | | array_flow.rb:167:9:167:9 | [post] a [element] : | array_flow.rb:168:10:168:10 | a [element] : | | array_flow.rb:167:9:167:9 | [post] a [element] : | array_flow.rb:169:10:169:10 | a [element] : | | array_flow.rb:167:9:167:9 | [post] a [element] : | array_flow.rb:169:10:169:10 | a [element] : | | array_flow.rb:167:9:167:9 | a [element 0] : | array_flow.rb:167:9:167:44 | call to append [element 0] : | | array_flow.rb:167:9:167:9 | a [element 0] : | array_flow.rb:167:9:167:44 | call to append [element 0] : | -| array_flow.rb:167:9:167:44 | call to append [element 0] : | array_flow.rb:170:10:170:10 | b [element 0] : | -| array_flow.rb:167:9:167:44 | call to append [element 0] : | array_flow.rb:170:10:170:10 | b [element 0] : | -| array_flow.rb:167:9:167:44 | call to append [element] : | array_flow.rb:170:10:170:10 | b [element] : | -| array_flow.rb:167:9:167:44 | call to append [element] : | array_flow.rb:170:10:170:10 | b [element] : | -| array_flow.rb:167:9:167:44 | call to append [element] : | array_flow.rb:171:10:171:10 | b [element] : | -| array_flow.rb:167:9:167:44 | call to append [element] : | array_flow.rb:171:10:171:10 | b [element] : | +| array_flow.rb:167:9:167:44 | call to append [element 0] : | array_flow.rb:167:5:167:5 | b [element 0] : | +| array_flow.rb:167:9:167:44 | call to append [element 0] : | array_flow.rb:167:5:167:5 | b [element 0] : | +| array_flow.rb:167:9:167:44 | call to append [element] : | array_flow.rb:167:5:167:5 | b [element] : | +| array_flow.rb:167:9:167:44 | call to append [element] : | array_flow.rb:167:5:167:5 | b [element] : | | array_flow.rb:167:18:167:29 | call to source : | array_flow.rb:167:9:167:9 | [post] a [element] : | | array_flow.rb:167:18:167:29 | call to source : | array_flow.rb:167:9:167:9 | [post] a [element] : | | array_flow.rb:167:18:167:29 | call to source : | array_flow.rb:167:9:167:44 | call to append [element] : | @@ -326,12 +405,16 @@ edges | array_flow.rb:170:10:170:10 | b [element] : | array_flow.rb:170:10:170:13 | ...[...] | | array_flow.rb:171:10:171:10 | b [element] : | array_flow.rb:171:10:171:13 | ...[...] | | array_flow.rb:171:10:171:10 | b [element] : | array_flow.rb:171:10:171:13 | ...[...] | -| array_flow.rb:177:15:177:24 | call to source : | array_flow.rb:178:16:178:16 | c [element 1] : | -| array_flow.rb:177:15:177:24 | call to source : | array_flow.rb:178:16:178:16 | c [element 1] : | -| array_flow.rb:178:16:178:16 | c [element 1] : | array_flow.rb:179:11:179:11 | d [element 2, element 1] : | -| array_flow.rb:178:16:178:16 | c [element 1] : | array_flow.rb:179:11:179:11 | d [element 2, element 1] : | -| array_flow.rb:178:16:178:16 | c [element 1] : | array_flow.rb:180:11:180:11 | d [element 2, element 1] : | -| array_flow.rb:178:16:178:16 | c [element 1] : | array_flow.rb:180:11:180:11 | d [element 2, element 1] : | +| array_flow.rb:177:5:177:5 | c [element 1] : | array_flow.rb:178:16:178:16 | c [element 1] : | +| array_flow.rb:177:5:177:5 | c [element 1] : | array_flow.rb:178:16:178:16 | c [element 1] : | +| array_flow.rb:177:15:177:24 | call to source : | array_flow.rb:177:5:177:5 | c [element 1] : | +| array_flow.rb:177:15:177:24 | call to source : | array_flow.rb:177:5:177:5 | c [element 1] : | +| array_flow.rb:178:5:178:5 | d [element 2, element 1] : | array_flow.rb:179:11:179:11 | d [element 2, element 1] : | +| array_flow.rb:178:5:178:5 | d [element 2, element 1] : | array_flow.rb:179:11:179:11 | d [element 2, element 1] : | +| array_flow.rb:178:5:178:5 | d [element 2, element 1] : | array_flow.rb:180:11:180:11 | d [element 2, element 1] : | +| array_flow.rb:178:5:178:5 | d [element 2, element 1] : | array_flow.rb:180:11:180:11 | d [element 2, element 1] : | +| array_flow.rb:178:16:178:16 | c [element 1] : | array_flow.rb:178:5:178:5 | d [element 2, element 1] : | +| array_flow.rb:178:16:178:16 | c [element 1] : | array_flow.rb:178:5:178:5 | d [element 2, element 1] : | | array_flow.rb:179:11:179:11 | d [element 2, element 1] : | array_flow.rb:179:11:179:22 | call to assoc [element 1] : | | array_flow.rb:179:11:179:11 | d [element 2, element 1] : | array_flow.rb:179:11:179:22 | call to assoc [element 1] : | | array_flow.rb:179:11:179:22 | call to assoc [element 1] : | array_flow.rb:179:11:179:25 | ...[...] : | @@ -344,40 +427,54 @@ edges | array_flow.rb:180:11:180:22 | call to assoc [element 1] : | array_flow.rb:180:11:180:25 | ...[...] : | | array_flow.rb:180:11:180:25 | ...[...] : | array_flow.rb:180:10:180:26 | ( ... ) | | array_flow.rb:180:11:180:25 | ...[...] : | array_flow.rb:180:10:180:26 | ( ... ) | -| array_flow.rb:184:13:184:22 | call to source : | array_flow.rb:186:10:186:10 | a [element 1] : | -| array_flow.rb:184:13:184:22 | call to source : | array_flow.rb:186:10:186:10 | a [element 1] : | -| array_flow.rb:184:13:184:22 | call to source : | array_flow.rb:188:10:188:10 | a [element 1] : | -| array_flow.rb:184:13:184:22 | call to source : | array_flow.rb:188:10:188:10 | a [element 1] : | +| array_flow.rb:184:5:184:5 | a [element 1] : | array_flow.rb:186:10:186:10 | a [element 1] : | +| array_flow.rb:184:5:184:5 | a [element 1] : | array_flow.rb:186:10:186:10 | a [element 1] : | +| array_flow.rb:184:5:184:5 | a [element 1] : | array_flow.rb:188:10:188:10 | a [element 1] : | +| array_flow.rb:184:5:184:5 | a [element 1] : | array_flow.rb:188:10:188:10 | a [element 1] : | +| array_flow.rb:184:13:184:22 | call to source : | array_flow.rb:184:5:184:5 | a [element 1] : | +| array_flow.rb:184:13:184:22 | call to source : | array_flow.rb:184:5:184:5 | a [element 1] : | | array_flow.rb:186:10:186:10 | a [element 1] : | array_flow.rb:186:10:186:16 | call to at | | array_flow.rb:186:10:186:10 | a [element 1] : | array_flow.rb:186:10:186:16 | call to at | | array_flow.rb:188:10:188:10 | a [element 1] : | array_flow.rb:188:10:188:16 | call to at | | array_flow.rb:188:10:188:10 | a [element 1] : | array_flow.rb:188:10:188:16 | call to at | -| array_flow.rb:192:16:192:25 | call to source : | array_flow.rb:193:9:193:9 | a [element 2] : | -| array_flow.rb:192:16:192:25 | call to source : | array_flow.rb:193:9:193:9 | a [element 2] : | +| array_flow.rb:192:5:192:5 | a [element 2] : | array_flow.rb:193:9:193:9 | a [element 2] : | +| array_flow.rb:192:5:192:5 | a [element 2] : | array_flow.rb:193:9:193:9 | a [element 2] : | +| array_flow.rb:192:16:192:25 | call to source : | array_flow.rb:192:5:192:5 | a [element 2] : | +| array_flow.rb:192:16:192:25 | call to source : | array_flow.rb:192:5:192:5 | a [element 2] : | +| array_flow.rb:193:5:193:5 | b : | array_flow.rb:196:10:196:10 | b | +| array_flow.rb:193:5:193:5 | b : | array_flow.rb:196:10:196:10 | b | | array_flow.rb:193:9:193:9 | a [element 2] : | array_flow.rb:193:9:195:7 | call to bsearch : | | array_flow.rb:193:9:193:9 | a [element 2] : | array_flow.rb:193:9:195:7 | call to bsearch : | | array_flow.rb:193:9:193:9 | a [element 2] : | array_flow.rb:193:23:193:23 | x : | | array_flow.rb:193:9:193:9 | a [element 2] : | array_flow.rb:193:23:193:23 | x : | -| array_flow.rb:193:9:195:7 | call to bsearch : | array_flow.rb:196:10:196:10 | b | -| array_flow.rb:193:9:195:7 | call to bsearch : | array_flow.rb:196:10:196:10 | b | +| array_flow.rb:193:9:195:7 | call to bsearch : | array_flow.rb:193:5:193:5 | b : | +| array_flow.rb:193:9:195:7 | call to bsearch : | array_flow.rb:193:5:193:5 | b : | | array_flow.rb:193:23:193:23 | x : | array_flow.rb:194:14:194:14 | x | | array_flow.rb:193:23:193:23 | x : | array_flow.rb:194:14:194:14 | x | -| array_flow.rb:200:16:200:25 | call to source : | array_flow.rb:201:9:201:9 | a [element 2] : | -| array_flow.rb:200:16:200:25 | call to source : | array_flow.rb:201:9:201:9 | a [element 2] : | +| array_flow.rb:200:5:200:5 | a [element 2] : | array_flow.rb:201:9:201:9 | a [element 2] : | +| array_flow.rb:200:5:200:5 | a [element 2] : | array_flow.rb:201:9:201:9 | a [element 2] : | +| array_flow.rb:200:16:200:25 | call to source : | array_flow.rb:200:5:200:5 | a [element 2] : | +| array_flow.rb:200:16:200:25 | call to source : | array_flow.rb:200:5:200:5 | a [element 2] : | | array_flow.rb:201:9:201:9 | a [element 2] : | array_flow.rb:201:29:201:29 | x : | | array_flow.rb:201:9:201:9 | a [element 2] : | array_flow.rb:201:29:201:29 | x : | | array_flow.rb:201:29:201:29 | x : | array_flow.rb:202:14:202:14 | x | | array_flow.rb:201:29:201:29 | x : | array_flow.rb:202:14:202:14 | x | -| array_flow.rb:208:16:208:25 | call to source : | array_flow.rb:209:5:209:5 | a [element 2] : | -| array_flow.rb:208:16:208:25 | call to source : | array_flow.rb:209:5:209:5 | a [element 2] : | +| array_flow.rb:208:5:208:5 | a [element 2] : | array_flow.rb:209:5:209:5 | a [element 2] : | +| array_flow.rb:208:5:208:5 | a [element 2] : | array_flow.rb:209:5:209:5 | a [element 2] : | +| array_flow.rb:208:16:208:25 | call to source : | array_flow.rb:208:5:208:5 | a [element 2] : | +| array_flow.rb:208:16:208:25 | call to source : | array_flow.rb:208:5:208:5 | a [element 2] : | | array_flow.rb:209:5:209:5 | a [element 2] : | array_flow.rb:209:17:209:17 | x : | | array_flow.rb:209:5:209:5 | a [element 2] : | array_flow.rb:209:17:209:17 | x : | | array_flow.rb:209:17:209:17 | x : | array_flow.rb:210:14:210:14 | x | | array_flow.rb:209:17:209:17 | x : | array_flow.rb:210:14:210:14 | x | -| array_flow.rb:215:16:215:27 | call to source : | array_flow.rb:216:9:216:9 | a [element 2] : | -| array_flow.rb:215:16:215:27 | call to source : | array_flow.rb:216:9:216:9 | a [element 2] : | -| array_flow.rb:215:30:215:41 | call to source : | array_flow.rb:216:9:216:9 | a [element 3] : | -| array_flow.rb:215:30:215:41 | call to source : | array_flow.rb:216:9:216:9 | a [element 3] : | +| array_flow.rb:215:5:215:5 | a [element 2] : | array_flow.rb:216:9:216:9 | a [element 2] : | +| array_flow.rb:215:5:215:5 | a [element 2] : | array_flow.rb:216:9:216:9 | a [element 2] : | +| array_flow.rb:215:5:215:5 | a [element 3] : | array_flow.rb:216:9:216:9 | a [element 3] : | +| array_flow.rb:215:5:215:5 | a [element 3] : | array_flow.rb:216:9:216:9 | a [element 3] : | +| array_flow.rb:215:16:215:27 | call to source : | array_flow.rb:215:5:215:5 | a [element 2] : | +| array_flow.rb:215:16:215:27 | call to source : | array_flow.rb:215:5:215:5 | a [element 2] : | +| array_flow.rb:215:30:215:41 | call to source : | array_flow.rb:215:5:215:5 | a [element 3] : | +| array_flow.rb:215:30:215:41 | call to source : | array_flow.rb:215:5:215:5 | a [element 3] : | | array_flow.rb:216:9:216:9 | a [element 2] : | array_flow.rb:216:27:216:27 | x : | | array_flow.rb:216:9:216:9 | a [element 2] : | array_flow.rb:216:27:216:27 | x : | | array_flow.rb:216:9:216:9 | a [element 2] : | array_flow.rb:216:30:216:30 | y : | @@ -390,26 +487,34 @@ edges | array_flow.rb:216:27:216:27 | x : | array_flow.rb:217:14:217:14 | x | | array_flow.rb:216:30:216:30 | y : | array_flow.rb:218:14:218:14 | y | | array_flow.rb:216:30:216:30 | y : | array_flow.rb:218:14:218:14 | y | -| array_flow.rb:231:16:231:27 | call to source : | array_flow.rb:232:9:232:9 | a [element 2] : | -| array_flow.rb:231:16:231:27 | call to source : | array_flow.rb:232:9:232:9 | a [element 2] : | +| array_flow.rb:231:5:231:5 | a [element 2] : | array_flow.rb:232:9:232:9 | a [element 2] : | +| array_flow.rb:231:5:231:5 | a [element 2] : | array_flow.rb:232:9:232:9 | a [element 2] : | +| array_flow.rb:231:16:231:27 | call to source : | array_flow.rb:231:5:231:5 | a [element 2] : | +| array_flow.rb:231:16:231:27 | call to source : | array_flow.rb:231:5:231:5 | a [element 2] : | +| array_flow.rb:232:5:232:5 | b [element] : | array_flow.rb:236:10:236:10 | b [element] : | +| array_flow.rb:232:5:232:5 | b [element] : | array_flow.rb:236:10:236:10 | b [element] : | | array_flow.rb:232:9:232:9 | a [element 2] : | array_flow.rb:232:23:232:23 | x : | | array_flow.rb:232:9:232:9 | a [element 2] : | array_flow.rb:232:23:232:23 | x : | -| array_flow.rb:232:9:235:7 | call to collect [element] : | array_flow.rb:236:10:236:10 | b [element] : | -| array_flow.rb:232:9:235:7 | call to collect [element] : | array_flow.rb:236:10:236:10 | b [element] : | +| array_flow.rb:232:9:235:7 | call to collect [element] : | array_flow.rb:232:5:232:5 | b [element] : | +| array_flow.rb:232:9:235:7 | call to collect [element] : | array_flow.rb:232:5:232:5 | b [element] : | | array_flow.rb:232:23:232:23 | x : | array_flow.rb:233:14:233:14 | x | | array_flow.rb:232:23:232:23 | x : | array_flow.rb:233:14:233:14 | x | | array_flow.rb:234:9:234:19 | call to source : | array_flow.rb:232:9:235:7 | call to collect [element] : | | array_flow.rb:234:9:234:19 | call to source : | array_flow.rb:232:9:235:7 | call to collect [element] : | | array_flow.rb:236:10:236:10 | b [element] : | array_flow.rb:236:10:236:13 | ...[...] | | array_flow.rb:236:10:236:10 | b [element] : | array_flow.rb:236:10:236:13 | ...[...] | -| array_flow.rb:240:16:240:27 | call to source : | array_flow.rb:241:9:241:9 | a [element 2] : | -| array_flow.rb:240:16:240:27 | call to source : | array_flow.rb:241:9:241:9 | a [element 2] : | +| array_flow.rb:240:5:240:5 | a [element 2] : | array_flow.rb:241:9:241:9 | a [element 2] : | +| array_flow.rb:240:5:240:5 | a [element 2] : | array_flow.rb:241:9:241:9 | a [element 2] : | +| array_flow.rb:240:16:240:27 | call to source : | array_flow.rb:240:5:240:5 | a [element 2] : | +| array_flow.rb:240:16:240:27 | call to source : | array_flow.rb:240:5:240:5 | a [element 2] : | +| array_flow.rb:241:5:241:5 | b [element] : | array_flow.rb:246:10:246:10 | b [element] : | +| array_flow.rb:241:5:241:5 | b [element] : | array_flow.rb:246:10:246:10 | b [element] : | | array_flow.rb:241:9:241:9 | [post] a [element] : | array_flow.rb:245:10:245:10 | a [element] : | | array_flow.rb:241:9:241:9 | [post] a [element] : | array_flow.rb:245:10:245:10 | a [element] : | | array_flow.rb:241:9:241:9 | a [element 2] : | array_flow.rb:241:24:241:24 | x : | | array_flow.rb:241:9:241:9 | a [element 2] : | array_flow.rb:241:24:241:24 | x : | -| array_flow.rb:241:9:244:7 | call to collect! [element] : | array_flow.rb:246:10:246:10 | b [element] : | -| array_flow.rb:241:9:244:7 | call to collect! [element] : | array_flow.rb:246:10:246:10 | b [element] : | +| array_flow.rb:241:9:244:7 | call to collect! [element] : | array_flow.rb:241:5:241:5 | b [element] : | +| array_flow.rb:241:9:244:7 | call to collect! [element] : | array_flow.rb:241:5:241:5 | b [element] : | | array_flow.rb:241:24:241:24 | x : | array_flow.rb:242:14:242:14 | x | | array_flow.rb:241:24:241:24 | x : | array_flow.rb:242:14:242:14 | x | | array_flow.rb:243:9:243:19 | call to source : | array_flow.rb:241:9:241:9 | [post] a [element] : | @@ -420,72 +525,94 @@ edges | array_flow.rb:245:10:245:10 | a [element] : | array_flow.rb:245:10:245:13 | ...[...] | | array_flow.rb:246:10:246:10 | b [element] : | array_flow.rb:246:10:246:13 | ...[...] | | array_flow.rb:246:10:246:10 | b [element] : | array_flow.rb:246:10:246:13 | ...[...] | -| array_flow.rb:250:16:250:27 | call to source : | array_flow.rb:251:9:251:9 | a [element 2] : | -| array_flow.rb:250:16:250:27 | call to source : | array_flow.rb:251:9:251:9 | a [element 2] : | -| array_flow.rb:250:16:250:27 | call to source : | array_flow.rb:256:9:256:9 | a [element 2] : | -| array_flow.rb:250:16:250:27 | call to source : | array_flow.rb:256:9:256:9 | a [element 2] : | +| array_flow.rb:250:5:250:5 | a [element 2] : | array_flow.rb:251:9:251:9 | a [element 2] : | +| array_flow.rb:250:5:250:5 | a [element 2] : | array_flow.rb:251:9:251:9 | a [element 2] : | +| array_flow.rb:250:5:250:5 | a [element 2] : | array_flow.rb:256:9:256:9 | a [element 2] : | +| array_flow.rb:250:5:250:5 | a [element 2] : | array_flow.rb:256:9:256:9 | a [element 2] : | +| array_flow.rb:250:16:250:27 | call to source : | array_flow.rb:250:5:250:5 | a [element 2] : | +| array_flow.rb:250:16:250:27 | call to source : | array_flow.rb:250:5:250:5 | a [element 2] : | +| array_flow.rb:251:5:251:5 | b [element] : | array_flow.rb:255:10:255:10 | b [element] : | +| array_flow.rb:251:5:251:5 | b [element] : | array_flow.rb:255:10:255:10 | b [element] : | | array_flow.rb:251:9:251:9 | a [element 2] : | array_flow.rb:251:9:254:7 | call to collect_concat [element] : | | array_flow.rb:251:9:251:9 | a [element 2] : | array_flow.rb:251:9:254:7 | call to collect_concat [element] : | | array_flow.rb:251:9:251:9 | a [element 2] : | array_flow.rb:251:30:251:30 | x : | | array_flow.rb:251:9:251:9 | a [element 2] : | array_flow.rb:251:30:251:30 | x : | -| array_flow.rb:251:9:254:7 | call to collect_concat [element] : | array_flow.rb:255:10:255:10 | b [element] : | -| array_flow.rb:251:9:254:7 | call to collect_concat [element] : | array_flow.rb:255:10:255:10 | b [element] : | +| array_flow.rb:251:9:254:7 | call to collect_concat [element] : | array_flow.rb:251:5:251:5 | b [element] : | +| array_flow.rb:251:9:254:7 | call to collect_concat [element] : | array_flow.rb:251:5:251:5 | b [element] : | | array_flow.rb:251:30:251:30 | x : | array_flow.rb:252:14:252:14 | x | | array_flow.rb:251:30:251:30 | x : | array_flow.rb:252:14:252:14 | x | | array_flow.rb:253:13:253:24 | call to source : | array_flow.rb:251:9:254:7 | call to collect_concat [element] : | | array_flow.rb:253:13:253:24 | call to source : | array_flow.rb:251:9:254:7 | call to collect_concat [element] : | | array_flow.rb:255:10:255:10 | b [element] : | array_flow.rb:255:10:255:13 | ...[...] | | array_flow.rb:255:10:255:10 | b [element] : | array_flow.rb:255:10:255:13 | ...[...] | +| array_flow.rb:256:5:256:5 | b [element] : | array_flow.rb:260:10:260:10 | b [element] : | +| array_flow.rb:256:5:256:5 | b [element] : | array_flow.rb:260:10:260:10 | b [element] : | | array_flow.rb:256:9:256:9 | a [element 2] : | array_flow.rb:256:30:256:30 | x : | | array_flow.rb:256:9:256:9 | a [element 2] : | array_flow.rb:256:30:256:30 | x : | -| array_flow.rb:256:9:259:7 | call to collect_concat [element] : | array_flow.rb:260:10:260:10 | b [element] : | -| array_flow.rb:256:9:259:7 | call to collect_concat [element] : | array_flow.rb:260:10:260:10 | b [element] : | +| array_flow.rb:256:9:259:7 | call to collect_concat [element] : | array_flow.rb:256:5:256:5 | b [element] : | +| array_flow.rb:256:9:259:7 | call to collect_concat [element] : | array_flow.rb:256:5:256:5 | b [element] : | | array_flow.rb:256:30:256:30 | x : | array_flow.rb:257:14:257:14 | x | | array_flow.rb:256:30:256:30 | x : | array_flow.rb:257:14:257:14 | x | | array_flow.rb:258:9:258:20 | call to source : | array_flow.rb:256:9:259:7 | call to collect_concat [element] : | | array_flow.rb:258:9:258:20 | call to source : | array_flow.rb:256:9:259:7 | call to collect_concat [element] : | | array_flow.rb:260:10:260:10 | b [element] : | array_flow.rb:260:10:260:13 | ...[...] | | array_flow.rb:260:10:260:10 | b [element] : | array_flow.rb:260:10:260:13 | ...[...] | -| array_flow.rb:264:16:264:25 | call to source : | array_flow.rb:265:9:265:9 | a [element 2] : | -| array_flow.rb:264:16:264:25 | call to source : | array_flow.rb:265:9:265:9 | a [element 2] : | +| array_flow.rb:264:5:264:5 | a [element 2] : | array_flow.rb:265:9:265:9 | a [element 2] : | +| array_flow.rb:264:5:264:5 | a [element 2] : | array_flow.rb:265:9:265:9 | a [element 2] : | +| array_flow.rb:264:16:264:25 | call to source : | array_flow.rb:264:5:264:5 | a [element 2] : | +| array_flow.rb:264:16:264:25 | call to source : | array_flow.rb:264:5:264:5 | a [element 2] : | +| array_flow.rb:265:5:265:5 | b [element 2] : | array_flow.rb:269:10:269:10 | b [element 2] : | +| array_flow.rb:265:5:265:5 | b [element 2] : | array_flow.rb:269:10:269:10 | b [element 2] : | | array_flow.rb:265:9:265:9 | a [element 2] : | array_flow.rb:265:9:267:7 | call to combination [element 2] : | | array_flow.rb:265:9:265:9 | a [element 2] : | array_flow.rb:265:9:267:7 | call to combination [element 2] : | | array_flow.rb:265:9:265:9 | a [element 2] : | array_flow.rb:265:30:265:30 | x [element] : | | array_flow.rb:265:9:265:9 | a [element 2] : | array_flow.rb:265:30:265:30 | x [element] : | -| array_flow.rb:265:9:267:7 | call to combination [element 2] : | array_flow.rb:269:10:269:10 | b [element 2] : | -| array_flow.rb:265:9:267:7 | call to combination [element 2] : | array_flow.rb:269:10:269:10 | b [element 2] : | +| array_flow.rb:265:9:267:7 | call to combination [element 2] : | array_flow.rb:265:5:265:5 | b [element 2] : | +| array_flow.rb:265:9:267:7 | call to combination [element 2] : | array_flow.rb:265:5:265:5 | b [element 2] : | | array_flow.rb:265:30:265:30 | x [element] : | array_flow.rb:266:14:266:14 | x [element] : | | array_flow.rb:265:30:265:30 | x [element] : | array_flow.rb:266:14:266:14 | x [element] : | | array_flow.rb:266:14:266:14 | x [element] : | array_flow.rb:266:14:266:17 | ...[...] | | array_flow.rb:266:14:266:14 | x [element] : | array_flow.rb:266:14:266:17 | ...[...] | | array_flow.rb:269:10:269:10 | b [element 2] : | array_flow.rb:269:10:269:13 | ...[...] | | array_flow.rb:269:10:269:10 | b [element 2] : | array_flow.rb:269:10:269:13 | ...[...] | -| array_flow.rb:273:16:273:25 | call to source : | array_flow.rb:274:9:274:9 | a [element 2] : | -| array_flow.rb:273:16:273:25 | call to source : | array_flow.rb:274:9:274:9 | a [element 2] : | +| array_flow.rb:273:5:273:5 | a [element 2] : | array_flow.rb:274:9:274:9 | a [element 2] : | +| array_flow.rb:273:5:273:5 | a [element 2] : | array_flow.rb:274:9:274:9 | a [element 2] : | +| array_flow.rb:273:16:273:25 | call to source : | array_flow.rb:273:5:273:5 | a [element 2] : | +| array_flow.rb:273:16:273:25 | call to source : | array_flow.rb:273:5:273:5 | a [element 2] : | +| array_flow.rb:274:5:274:5 | b [element] : | array_flow.rb:275:10:275:10 | b [element] : | +| array_flow.rb:274:5:274:5 | b [element] : | array_flow.rb:275:10:275:10 | b [element] : | | array_flow.rb:274:9:274:9 | a [element 2] : | array_flow.rb:274:9:274:17 | call to compact [element] : | | array_flow.rb:274:9:274:9 | a [element 2] : | array_flow.rb:274:9:274:17 | call to compact [element] : | -| array_flow.rb:274:9:274:17 | call to compact [element] : | array_flow.rb:275:10:275:10 | b [element] : | -| array_flow.rb:274:9:274:17 | call to compact [element] : | array_flow.rb:275:10:275:10 | b [element] : | +| array_flow.rb:274:9:274:17 | call to compact [element] : | array_flow.rb:274:5:274:5 | b [element] : | +| array_flow.rb:274:9:274:17 | call to compact [element] : | array_flow.rb:274:5:274:5 | b [element] : | | array_flow.rb:275:10:275:10 | b [element] : | array_flow.rb:275:10:275:13 | ...[...] | | array_flow.rb:275:10:275:10 | b [element] : | array_flow.rb:275:10:275:13 | ...[...] | -| array_flow.rb:279:16:279:25 | call to source : | array_flow.rb:280:9:280:9 | a [element 2] : | -| array_flow.rb:279:16:279:25 | call to source : | array_flow.rb:280:9:280:9 | a [element 2] : | +| array_flow.rb:279:5:279:5 | a [element 2] : | array_flow.rb:280:9:280:9 | a [element 2] : | +| array_flow.rb:279:5:279:5 | a [element 2] : | array_flow.rb:280:9:280:9 | a [element 2] : | +| array_flow.rb:279:16:279:25 | call to source : | array_flow.rb:279:5:279:5 | a [element 2] : | +| array_flow.rb:279:16:279:25 | call to source : | array_flow.rb:279:5:279:5 | a [element 2] : | +| array_flow.rb:280:5:280:5 | b [element] : | array_flow.rb:282:10:282:10 | b [element] : | +| array_flow.rb:280:5:280:5 | b [element] : | array_flow.rb:282:10:282:10 | b [element] : | | array_flow.rb:280:9:280:9 | [post] a [element] : | array_flow.rb:281:10:281:10 | a [element] : | | array_flow.rb:280:9:280:9 | [post] a [element] : | array_flow.rb:281:10:281:10 | a [element] : | | array_flow.rb:280:9:280:9 | a [element 2] : | array_flow.rb:280:9:280:9 | [post] a [element] : | | array_flow.rb:280:9:280:9 | a [element 2] : | array_flow.rb:280:9:280:9 | [post] a [element] : | | array_flow.rb:280:9:280:9 | a [element 2] : | array_flow.rb:280:9:280:18 | call to compact! [element] : | | array_flow.rb:280:9:280:9 | a [element 2] : | array_flow.rb:280:9:280:18 | call to compact! [element] : | -| array_flow.rb:280:9:280:18 | call to compact! [element] : | array_flow.rb:282:10:282:10 | b [element] : | -| array_flow.rb:280:9:280:18 | call to compact! [element] : | array_flow.rb:282:10:282:10 | b [element] : | +| array_flow.rb:280:9:280:18 | call to compact! [element] : | array_flow.rb:280:5:280:5 | b [element] : | +| array_flow.rb:280:9:280:18 | call to compact! [element] : | array_flow.rb:280:5:280:5 | b [element] : | | array_flow.rb:281:10:281:10 | a [element] : | array_flow.rb:281:10:281:13 | ...[...] | | array_flow.rb:281:10:281:10 | a [element] : | array_flow.rb:281:10:281:13 | ...[...] | | array_flow.rb:282:10:282:10 | b [element] : | array_flow.rb:282:10:282:13 | ...[...] | | array_flow.rb:282:10:282:10 | b [element] : | array_flow.rb:282:10:282:13 | ...[...] | -| array_flow.rb:286:16:286:27 | call to source : | array_flow.rb:290:10:290:10 | a [element 2] : | -| array_flow.rb:286:16:286:27 | call to source : | array_flow.rb:290:10:290:10 | a [element 2] : | -| array_flow.rb:287:16:287:27 | call to source : | array_flow.rb:288:14:288:14 | b [element 2] : | -| array_flow.rb:287:16:287:27 | call to source : | array_flow.rb:288:14:288:14 | b [element 2] : | +| array_flow.rb:286:5:286:5 | a [element 2] : | array_flow.rb:290:10:290:10 | a [element 2] : | +| array_flow.rb:286:5:286:5 | a [element 2] : | array_flow.rb:290:10:290:10 | a [element 2] : | +| array_flow.rb:286:16:286:27 | call to source : | array_flow.rb:286:5:286:5 | a [element 2] : | +| array_flow.rb:286:16:286:27 | call to source : | array_flow.rb:286:5:286:5 | a [element 2] : | +| array_flow.rb:287:5:287:5 | b [element 2] : | array_flow.rb:288:14:288:14 | b [element 2] : | +| array_flow.rb:287:5:287:5 | b [element 2] : | array_flow.rb:288:14:288:14 | b [element 2] : | +| array_flow.rb:287:16:287:27 | call to source : | array_flow.rb:287:5:287:5 | b [element 2] : | +| array_flow.rb:287:16:287:27 | call to source : | array_flow.rb:287:5:287:5 | b [element 2] : | | array_flow.rb:288:5:288:5 | [post] a [element] : | array_flow.rb:289:10:289:10 | a [element] : | | array_flow.rb:288:5:288:5 | [post] a [element] : | array_flow.rb:289:10:289:10 | a [element] : | | array_flow.rb:288:5:288:5 | [post] a [element] : | array_flow.rb:290:10:290:10 | a [element] : | @@ -498,52 +625,76 @@ edges | array_flow.rb:290:10:290:10 | a [element 2] : | array_flow.rb:290:10:290:13 | ...[...] | | array_flow.rb:290:10:290:10 | a [element] : | array_flow.rb:290:10:290:13 | ...[...] | | array_flow.rb:290:10:290:10 | a [element] : | array_flow.rb:290:10:290:13 | ...[...] | -| array_flow.rb:294:16:294:25 | call to source : | array_flow.rb:295:5:295:5 | a [element 2] : | -| array_flow.rb:294:16:294:25 | call to source : | array_flow.rb:295:5:295:5 | a [element 2] : | +| array_flow.rb:294:5:294:5 | a [element 2] : | array_flow.rb:295:5:295:5 | a [element 2] : | +| array_flow.rb:294:5:294:5 | a [element 2] : | array_flow.rb:295:5:295:5 | a [element 2] : | +| array_flow.rb:294:16:294:25 | call to source : | array_flow.rb:294:5:294:5 | a [element 2] : | +| array_flow.rb:294:16:294:25 | call to source : | array_flow.rb:294:5:294:5 | a [element 2] : | | array_flow.rb:295:5:295:5 | a [element 2] : | array_flow.rb:295:17:295:17 | x : | | array_flow.rb:295:5:295:5 | a [element 2] : | array_flow.rb:295:17:295:17 | x : | | array_flow.rb:295:17:295:17 | x : | array_flow.rb:296:14:296:14 | x | | array_flow.rb:295:17:295:17 | x : | array_flow.rb:296:14:296:14 | x | -| array_flow.rb:301:16:301:25 | call to source : | array_flow.rb:302:5:302:5 | a [element 2] : | -| array_flow.rb:301:16:301:25 | call to source : | array_flow.rb:302:5:302:5 | a [element 2] : | +| array_flow.rb:301:5:301:5 | a [element 2] : | array_flow.rb:302:5:302:5 | a [element 2] : | +| array_flow.rb:301:5:301:5 | a [element 2] : | array_flow.rb:302:5:302:5 | a [element 2] : | +| array_flow.rb:301:16:301:25 | call to source : | array_flow.rb:301:5:301:5 | a [element 2] : | +| array_flow.rb:301:16:301:25 | call to source : | array_flow.rb:301:5:301:5 | a [element 2] : | | array_flow.rb:302:5:302:5 | a [element 2] : | array_flow.rb:302:20:302:20 | x : | | array_flow.rb:302:5:302:5 | a [element 2] : | array_flow.rb:302:20:302:20 | x : | | array_flow.rb:302:20:302:20 | x : | array_flow.rb:303:14:303:14 | x | | array_flow.rb:302:20:302:20 | x : | array_flow.rb:303:14:303:14 | x | -| array_flow.rb:308:16:308:25 | call to source : | array_flow.rb:309:9:309:9 | a [element 2] : | -| array_flow.rb:308:16:308:25 | call to source : | array_flow.rb:309:9:309:9 | a [element 2] : | +| array_flow.rb:308:5:308:5 | a [element 2] : | array_flow.rb:309:9:309:9 | a [element 2] : | +| array_flow.rb:308:5:308:5 | a [element 2] : | array_flow.rb:309:9:309:9 | a [element 2] : | +| array_flow.rb:308:16:308:25 | call to source : | array_flow.rb:308:5:308:5 | a [element 2] : | +| array_flow.rb:308:16:308:25 | call to source : | array_flow.rb:308:5:308:5 | a [element 2] : | +| array_flow.rb:309:5:309:5 | b [element 2] : | array_flow.rb:312:10:312:10 | b [element 2] : | +| array_flow.rb:309:5:309:5 | b [element 2] : | array_flow.rb:312:10:312:10 | b [element 2] : | | array_flow.rb:309:9:309:9 | a [element 2] : | array_flow.rb:309:9:309:21 | call to deconstruct [element 2] : | | array_flow.rb:309:9:309:9 | a [element 2] : | array_flow.rb:309:9:309:21 | call to deconstruct [element 2] : | -| array_flow.rb:309:9:309:21 | call to deconstruct [element 2] : | array_flow.rb:312:10:312:10 | b [element 2] : | -| array_flow.rb:309:9:309:21 | call to deconstruct [element 2] : | array_flow.rb:312:10:312:10 | b [element 2] : | +| array_flow.rb:309:9:309:21 | call to deconstruct [element 2] : | array_flow.rb:309:5:309:5 | b [element 2] : | +| array_flow.rb:309:9:309:21 | call to deconstruct [element 2] : | array_flow.rb:309:5:309:5 | b [element 2] : | | array_flow.rb:312:10:312:10 | b [element 2] : | array_flow.rb:312:10:312:13 | ...[...] | | array_flow.rb:312:10:312:10 | b [element 2] : | array_flow.rb:312:10:312:13 | ...[...] | -| array_flow.rb:316:16:316:27 | call to source : | array_flow.rb:317:9:317:9 | a [element 2] : | -| array_flow.rb:316:16:316:27 | call to source : | array_flow.rb:317:9:317:9 | a [element 2] : | +| array_flow.rb:316:5:316:5 | a [element 2] : | array_flow.rb:317:9:317:9 | a [element 2] : | +| array_flow.rb:316:5:316:5 | a [element 2] : | array_flow.rb:317:9:317:9 | a [element 2] : | +| array_flow.rb:316:16:316:27 | call to source : | array_flow.rb:316:5:316:5 | a [element 2] : | +| array_flow.rb:316:16:316:27 | call to source : | array_flow.rb:316:5:316:5 | a [element 2] : | +| array_flow.rb:317:5:317:5 | b : | array_flow.rb:318:10:318:10 | b | +| array_flow.rb:317:5:317:5 | b : | array_flow.rb:318:10:318:10 | b | | array_flow.rb:317:9:317:9 | a [element 2] : | array_flow.rb:317:9:317:36 | call to delete : | | array_flow.rb:317:9:317:9 | a [element 2] : | array_flow.rb:317:9:317:36 | call to delete : | -| array_flow.rb:317:9:317:36 | call to delete : | array_flow.rb:318:10:318:10 | b | -| array_flow.rb:317:9:317:36 | call to delete : | array_flow.rb:318:10:318:10 | b | +| array_flow.rb:317:9:317:36 | call to delete : | array_flow.rb:317:5:317:5 | b : | +| array_flow.rb:317:9:317:36 | call to delete : | array_flow.rb:317:5:317:5 | b : | | array_flow.rb:317:23:317:34 | call to source : | array_flow.rb:317:9:317:36 | call to delete : | | array_flow.rb:317:23:317:34 | call to source : | array_flow.rb:317:9:317:36 | call to delete : | -| array_flow.rb:325:16:325:27 | call to source : | array_flow.rb:326:9:326:9 | a [element 2] : | -| array_flow.rb:325:16:325:27 | call to source : | array_flow.rb:326:9:326:9 | a [element 2] : | -| array_flow.rb:325:30:325:41 | call to source : | array_flow.rb:326:9:326:9 | a [element 3] : | -| array_flow.rb:325:30:325:41 | call to source : | array_flow.rb:326:9:326:9 | a [element 3] : | +| array_flow.rb:325:5:325:5 | a [element 2] : | array_flow.rb:326:9:326:9 | a [element 2] : | +| array_flow.rb:325:5:325:5 | a [element 2] : | array_flow.rb:326:9:326:9 | a [element 2] : | +| array_flow.rb:325:5:325:5 | a [element 3] : | array_flow.rb:326:9:326:9 | a [element 3] : | +| array_flow.rb:325:5:325:5 | a [element 3] : | array_flow.rb:326:9:326:9 | a [element 3] : | +| array_flow.rb:325:16:325:27 | call to source : | array_flow.rb:325:5:325:5 | a [element 2] : | +| array_flow.rb:325:16:325:27 | call to source : | array_flow.rb:325:5:325:5 | a [element 2] : | +| array_flow.rb:325:30:325:41 | call to source : | array_flow.rb:325:5:325:5 | a [element 3] : | +| array_flow.rb:325:30:325:41 | call to source : | array_flow.rb:325:5:325:5 | a [element 3] : | +| array_flow.rb:326:5:326:5 | b : | array_flow.rb:327:10:327:10 | b | +| array_flow.rb:326:5:326:5 | b : | array_flow.rb:327:10:327:10 | b | | array_flow.rb:326:9:326:9 | [post] a [element 2] : | array_flow.rb:328:10:328:10 | a [element 2] : | | array_flow.rb:326:9:326:9 | [post] a [element 2] : | array_flow.rb:328:10:328:10 | a [element 2] : | | array_flow.rb:326:9:326:9 | a [element 2] : | array_flow.rb:326:9:326:22 | call to delete_at : | | array_flow.rb:326:9:326:9 | a [element 2] : | array_flow.rb:326:9:326:22 | call to delete_at : | | array_flow.rb:326:9:326:9 | a [element 3] : | array_flow.rb:326:9:326:9 | [post] a [element 2] : | | array_flow.rb:326:9:326:9 | a [element 3] : | array_flow.rb:326:9:326:9 | [post] a [element 2] : | -| array_flow.rb:326:9:326:22 | call to delete_at : | array_flow.rb:327:10:327:10 | b | -| array_flow.rb:326:9:326:22 | call to delete_at : | array_flow.rb:327:10:327:10 | b | +| array_flow.rb:326:9:326:22 | call to delete_at : | array_flow.rb:326:5:326:5 | b : | +| array_flow.rb:326:9:326:22 | call to delete_at : | array_flow.rb:326:5:326:5 | b : | | array_flow.rb:328:10:328:10 | a [element 2] : | array_flow.rb:328:10:328:13 | ...[...] | | array_flow.rb:328:10:328:10 | a [element 2] : | array_flow.rb:328:10:328:13 | ...[...] | -| array_flow.rb:330:16:330:27 | call to source : | array_flow.rb:331:9:331:9 | a [element 2] : | -| array_flow.rb:330:16:330:27 | call to source : | array_flow.rb:331:9:331:9 | a [element 2] : | -| array_flow.rb:330:30:330:41 | call to source : | array_flow.rb:331:9:331:9 | a [element 3] : | -| array_flow.rb:330:30:330:41 | call to source : | array_flow.rb:331:9:331:9 | a [element 3] : | +| array_flow.rb:330:5:330:5 | a [element 2] : | array_flow.rb:331:9:331:9 | a [element 2] : | +| array_flow.rb:330:5:330:5 | a [element 2] : | array_flow.rb:331:9:331:9 | a [element 2] : | +| array_flow.rb:330:5:330:5 | a [element 3] : | array_flow.rb:331:9:331:9 | a [element 3] : | +| array_flow.rb:330:5:330:5 | a [element 3] : | array_flow.rb:331:9:331:9 | a [element 3] : | +| array_flow.rb:330:16:330:27 | call to source : | array_flow.rb:330:5:330:5 | a [element 2] : | +| array_flow.rb:330:16:330:27 | call to source : | array_flow.rb:330:5:330:5 | a [element 2] : | +| array_flow.rb:330:30:330:41 | call to source : | array_flow.rb:330:5:330:5 | a [element 3] : | +| array_flow.rb:330:30:330:41 | call to source : | array_flow.rb:330:5:330:5 | a [element 3] : | +| array_flow.rb:331:5:331:5 | b : | array_flow.rb:332:10:332:10 | b | +| array_flow.rb:331:5:331:5 | b : | array_flow.rb:332:10:332:10 | b | | array_flow.rb:331:9:331:9 | [post] a [element] : | array_flow.rb:333:10:333:10 | a [element] : | | array_flow.rb:331:9:331:9 | [post] a [element] : | array_flow.rb:333:10:333:10 | a [element] : | | array_flow.rb:331:9:331:9 | [post] a [element] : | array_flow.rb:334:10:334:10 | a [element] : | @@ -556,14 +707,18 @@ edges | array_flow.rb:331:9:331:9 | a [element 3] : | array_flow.rb:331:9:331:9 | [post] a [element] : | | array_flow.rb:331:9:331:9 | a [element 3] : | array_flow.rb:331:9:331:22 | call to delete_at : | | array_flow.rb:331:9:331:9 | a [element 3] : | array_flow.rb:331:9:331:22 | call to delete_at : | -| array_flow.rb:331:9:331:22 | call to delete_at : | array_flow.rb:332:10:332:10 | b | -| array_flow.rb:331:9:331:22 | call to delete_at : | array_flow.rb:332:10:332:10 | b | +| array_flow.rb:331:9:331:22 | call to delete_at : | array_flow.rb:331:5:331:5 | b : | +| array_flow.rb:331:9:331:22 | call to delete_at : | array_flow.rb:331:5:331:5 | b : | | array_flow.rb:333:10:333:10 | a [element] : | array_flow.rb:333:10:333:13 | ...[...] | | array_flow.rb:333:10:333:10 | a [element] : | array_flow.rb:333:10:333:13 | ...[...] | | array_flow.rb:334:10:334:10 | a [element] : | array_flow.rb:334:10:334:13 | ...[...] | | array_flow.rb:334:10:334:10 | a [element] : | array_flow.rb:334:10:334:13 | ...[...] | -| array_flow.rb:338:16:338:25 | call to source : | array_flow.rb:339:9:339:9 | a [element 2] : | -| array_flow.rb:338:16:338:25 | call to source : | array_flow.rb:339:9:339:9 | a [element 2] : | +| array_flow.rb:338:5:338:5 | a [element 2] : | array_flow.rb:339:9:339:9 | a [element 2] : | +| array_flow.rb:338:5:338:5 | a [element 2] : | array_flow.rb:339:9:339:9 | a [element 2] : | +| array_flow.rb:338:16:338:25 | call to source : | array_flow.rb:338:5:338:5 | a [element 2] : | +| array_flow.rb:338:16:338:25 | call to source : | array_flow.rb:338:5:338:5 | a [element 2] : | +| array_flow.rb:339:5:339:5 | b [element] : | array_flow.rb:342:10:342:10 | b [element] : | +| array_flow.rb:339:5:339:5 | b [element] : | array_flow.rb:342:10:342:10 | b [element] : | | array_flow.rb:339:9:339:9 | [post] a [element] : | array_flow.rb:343:10:343:10 | a [element] : | | array_flow.rb:339:9:339:9 | [post] a [element] : | array_flow.rb:343:10:343:10 | a [element] : | | array_flow.rb:339:9:339:9 | [post] a [element] : | array_flow.rb:344:10:344:10 | a [element] : | @@ -576,8 +731,8 @@ edges | array_flow.rb:339:9:339:9 | a [element 2] : | array_flow.rb:339:9:341:7 | call to delete_if [element] : | | array_flow.rb:339:9:339:9 | a [element 2] : | array_flow.rb:339:25:339:25 | x : | | array_flow.rb:339:9:339:9 | a [element 2] : | array_flow.rb:339:25:339:25 | x : | -| array_flow.rb:339:9:341:7 | call to delete_if [element] : | array_flow.rb:342:10:342:10 | b [element] : | -| array_flow.rb:339:9:341:7 | call to delete_if [element] : | array_flow.rb:342:10:342:10 | b [element] : | +| array_flow.rb:339:9:341:7 | call to delete_if [element] : | array_flow.rb:339:5:339:5 | b [element] : | +| array_flow.rb:339:9:341:7 | call to delete_if [element] : | array_flow.rb:339:5:339:5 | b [element] : | | array_flow.rb:339:25:339:25 | x : | array_flow.rb:340:14:340:14 | x | | array_flow.rb:339:25:339:25 | x : | array_flow.rb:340:14:340:14 | x | | array_flow.rb:342:10:342:10 | b [element] : | array_flow.rb:342:10:342:13 | ...[...] | @@ -588,66 +743,88 @@ edges | array_flow.rb:344:10:344:10 | a [element] : | array_flow.rb:344:10:344:13 | ...[...] | | array_flow.rb:345:10:345:10 | a [element] : | array_flow.rb:345:10:345:13 | ...[...] | | array_flow.rb:345:10:345:10 | a [element] : | array_flow.rb:345:10:345:13 | ...[...] | -| array_flow.rb:349:16:349:25 | call to source : | array_flow.rb:350:9:350:9 | a [element 2] : | -| array_flow.rb:349:16:349:25 | call to source : | array_flow.rb:350:9:350:9 | a [element 2] : | +| array_flow.rb:349:5:349:5 | a [element 2] : | array_flow.rb:350:9:350:9 | a [element 2] : | +| array_flow.rb:349:5:349:5 | a [element 2] : | array_flow.rb:350:9:350:9 | a [element 2] : | +| array_flow.rb:349:16:349:25 | call to source : | array_flow.rb:349:5:349:5 | a [element 2] : | +| array_flow.rb:349:16:349:25 | call to source : | array_flow.rb:349:5:349:5 | a [element 2] : | +| array_flow.rb:350:5:350:5 | b [element] : | array_flow.rb:351:10:351:10 | b [element] : | +| array_flow.rb:350:5:350:5 | b [element] : | array_flow.rb:351:10:351:10 | b [element] : | | array_flow.rb:350:9:350:9 | a [element 2] : | array_flow.rb:350:9:350:25 | call to difference [element] : | | array_flow.rb:350:9:350:9 | a [element 2] : | array_flow.rb:350:9:350:25 | call to difference [element] : | -| array_flow.rb:350:9:350:25 | call to difference [element] : | array_flow.rb:351:10:351:10 | b [element] : | -| array_flow.rb:350:9:350:25 | call to difference [element] : | array_flow.rb:351:10:351:10 | b [element] : | +| array_flow.rb:350:9:350:25 | call to difference [element] : | array_flow.rb:350:5:350:5 | b [element] : | +| array_flow.rb:350:9:350:25 | call to difference [element] : | array_flow.rb:350:5:350:5 | b [element] : | | array_flow.rb:351:10:351:10 | b [element] : | array_flow.rb:351:10:351:13 | ...[...] | | array_flow.rb:351:10:351:10 | b [element] : | array_flow.rb:351:10:351:13 | ...[...] | -| array_flow.rb:355:16:355:27 | call to source : | array_flow.rb:357:10:357:10 | a [element 2] : | -| array_flow.rb:355:16:355:27 | call to source : | array_flow.rb:357:10:357:10 | a [element 2] : | -| array_flow.rb:355:16:355:27 | call to source : | array_flow.rb:358:10:358:10 | a [element 2] : | -| array_flow.rb:355:16:355:27 | call to source : | array_flow.rb:358:10:358:10 | a [element 2] : | -| array_flow.rb:355:34:355:45 | call to source : | array_flow.rb:360:10:360:10 | a [element 3, element 1] : | -| array_flow.rb:355:34:355:45 | call to source : | array_flow.rb:360:10:360:10 | a [element 3, element 1] : | +| array_flow.rb:355:5:355:5 | a [element 2] : | array_flow.rb:357:10:357:10 | a [element 2] : | +| array_flow.rb:355:5:355:5 | a [element 2] : | array_flow.rb:357:10:357:10 | a [element 2] : | +| array_flow.rb:355:5:355:5 | a [element 2] : | array_flow.rb:358:10:358:10 | a [element 2] : | +| array_flow.rb:355:5:355:5 | a [element 2] : | array_flow.rb:358:10:358:10 | a [element 2] : | +| array_flow.rb:355:5:355:5 | a [element 3, element 1] : | array_flow.rb:360:10:360:10 | a [element 3, element 1] : | +| array_flow.rb:355:5:355:5 | a [element 3, element 1] : | array_flow.rb:360:10:360:10 | a [element 3, element 1] : | +| array_flow.rb:355:16:355:27 | call to source : | array_flow.rb:355:5:355:5 | a [element 2] : | +| array_flow.rb:355:16:355:27 | call to source : | array_flow.rb:355:5:355:5 | a [element 2] : | +| array_flow.rb:355:34:355:45 | call to source : | array_flow.rb:355:5:355:5 | a [element 3, element 1] : | +| array_flow.rb:355:34:355:45 | call to source : | array_flow.rb:355:5:355:5 | a [element 3, element 1] : | | array_flow.rb:357:10:357:10 | a [element 2] : | array_flow.rb:357:10:357:17 | call to dig | | array_flow.rb:357:10:357:10 | a [element 2] : | array_flow.rb:357:10:357:17 | call to dig | | array_flow.rb:358:10:358:10 | a [element 2] : | array_flow.rb:358:10:358:17 | call to dig | | array_flow.rb:358:10:358:10 | a [element 2] : | array_flow.rb:358:10:358:17 | call to dig | | array_flow.rb:360:10:360:10 | a [element 3, element 1] : | array_flow.rb:360:10:360:19 | call to dig | | array_flow.rb:360:10:360:10 | a [element 3, element 1] : | array_flow.rb:360:10:360:19 | call to dig | -| array_flow.rb:364:16:364:27 | call to source : | array_flow.rb:365:9:365:9 | a [element 2] : | -| array_flow.rb:364:16:364:27 | call to source : | array_flow.rb:365:9:365:9 | a [element 2] : | +| array_flow.rb:364:5:364:5 | a [element 2] : | array_flow.rb:365:9:365:9 | a [element 2] : | +| array_flow.rb:364:5:364:5 | a [element 2] : | array_flow.rb:365:9:365:9 | a [element 2] : | +| array_flow.rb:364:16:364:27 | call to source : | array_flow.rb:364:5:364:5 | a [element 2] : | +| array_flow.rb:364:16:364:27 | call to source : | array_flow.rb:364:5:364:5 | a [element 2] : | +| array_flow.rb:365:5:365:5 | b : | array_flow.rb:368:10:368:10 | b | +| array_flow.rb:365:5:365:5 | b : | array_flow.rb:368:10:368:10 | b | | array_flow.rb:365:9:365:9 | a [element 2] : | array_flow.rb:365:9:367:7 | call to detect : | | array_flow.rb:365:9:365:9 | a [element 2] : | array_flow.rb:365:9:367:7 | call to detect : | | array_flow.rb:365:9:365:9 | a [element 2] : | array_flow.rb:365:43:365:43 | x : | | array_flow.rb:365:9:365:9 | a [element 2] : | array_flow.rb:365:43:365:43 | x : | -| array_flow.rb:365:9:367:7 | call to detect : | array_flow.rb:368:10:368:10 | b | -| array_flow.rb:365:9:367:7 | call to detect : | array_flow.rb:368:10:368:10 | b | +| array_flow.rb:365:9:367:7 | call to detect : | array_flow.rb:365:5:365:5 | b : | +| array_flow.rb:365:9:367:7 | call to detect : | array_flow.rb:365:5:365:5 | b : | | array_flow.rb:365:23:365:34 | call to source : | array_flow.rb:365:9:367:7 | call to detect : | | array_flow.rb:365:23:365:34 | call to source : | array_flow.rb:365:9:367:7 | call to detect : | | array_flow.rb:365:43:365:43 | x : | array_flow.rb:366:14:366:14 | x | | array_flow.rb:365:43:365:43 | x : | array_flow.rb:366:14:366:14 | x | -| array_flow.rb:372:16:372:27 | call to source : | array_flow.rb:373:9:373:9 | a [element 2] : | -| array_flow.rb:372:16:372:27 | call to source : | array_flow.rb:373:9:373:9 | a [element 2] : | -| array_flow.rb:372:16:372:27 | call to source : | array_flow.rb:375:9:375:9 | a [element 2] : | -| array_flow.rb:372:16:372:27 | call to source : | array_flow.rb:375:9:375:9 | a [element 2] : | -| array_flow.rb:372:16:372:27 | call to source : | array_flow.rb:380:9:380:9 | a [element 2] : | -| array_flow.rb:372:16:372:27 | call to source : | array_flow.rb:380:9:380:9 | a [element 2] : | -| array_flow.rb:372:30:372:41 | call to source : | array_flow.rb:373:9:373:9 | a [element 3] : | -| array_flow.rb:372:30:372:41 | call to source : | array_flow.rb:373:9:373:9 | a [element 3] : | -| array_flow.rb:372:30:372:41 | call to source : | array_flow.rb:375:9:375:9 | a [element 3] : | -| array_flow.rb:372:30:372:41 | call to source : | array_flow.rb:375:9:375:9 | a [element 3] : | +| array_flow.rb:372:5:372:5 | a [element 2] : | array_flow.rb:373:9:373:9 | a [element 2] : | +| array_flow.rb:372:5:372:5 | a [element 2] : | array_flow.rb:373:9:373:9 | a [element 2] : | +| array_flow.rb:372:5:372:5 | a [element 2] : | array_flow.rb:375:9:375:9 | a [element 2] : | +| array_flow.rb:372:5:372:5 | a [element 2] : | array_flow.rb:375:9:375:9 | a [element 2] : | +| array_flow.rb:372:5:372:5 | a [element 2] : | array_flow.rb:380:9:380:9 | a [element 2] : | +| array_flow.rb:372:5:372:5 | a [element 2] : | array_flow.rb:380:9:380:9 | a [element 2] : | +| array_flow.rb:372:5:372:5 | a [element 3] : | array_flow.rb:373:9:373:9 | a [element 3] : | +| array_flow.rb:372:5:372:5 | a [element 3] : | array_flow.rb:373:9:373:9 | a [element 3] : | +| array_flow.rb:372:5:372:5 | a [element 3] : | array_flow.rb:375:9:375:9 | a [element 3] : | +| array_flow.rb:372:5:372:5 | a [element 3] : | array_flow.rb:375:9:375:9 | a [element 3] : | +| array_flow.rb:372:16:372:27 | call to source : | array_flow.rb:372:5:372:5 | a [element 2] : | +| array_flow.rb:372:16:372:27 | call to source : | array_flow.rb:372:5:372:5 | a [element 2] : | +| array_flow.rb:372:30:372:41 | call to source : | array_flow.rb:372:5:372:5 | a [element 3] : | +| array_flow.rb:372:30:372:41 | call to source : | array_flow.rb:372:5:372:5 | a [element 3] : | +| array_flow.rb:373:5:373:5 | b [element] : | array_flow.rb:374:10:374:10 | b [element] : | +| array_flow.rb:373:5:373:5 | b [element] : | array_flow.rb:374:10:374:10 | b [element] : | | array_flow.rb:373:9:373:9 | a [element 2] : | array_flow.rb:373:9:373:17 | call to drop [element] : | | array_flow.rb:373:9:373:9 | a [element 2] : | array_flow.rb:373:9:373:17 | call to drop [element] : | | array_flow.rb:373:9:373:9 | a [element 3] : | array_flow.rb:373:9:373:17 | call to drop [element] : | | array_flow.rb:373:9:373:9 | a [element 3] : | array_flow.rb:373:9:373:17 | call to drop [element] : | -| array_flow.rb:373:9:373:17 | call to drop [element] : | array_flow.rb:374:10:374:10 | b [element] : | -| array_flow.rb:373:9:373:17 | call to drop [element] : | array_flow.rb:374:10:374:10 | b [element] : | +| array_flow.rb:373:9:373:17 | call to drop [element] : | array_flow.rb:373:5:373:5 | b [element] : | +| array_flow.rb:373:9:373:17 | call to drop [element] : | array_flow.rb:373:5:373:5 | b [element] : | | array_flow.rb:374:10:374:10 | b [element] : | array_flow.rb:374:10:374:13 | ...[...] | | array_flow.rb:374:10:374:10 | b [element] : | array_flow.rb:374:10:374:13 | ...[...] | +| array_flow.rb:375:5:375:5 | b [element 1] : | array_flow.rb:377:10:377:10 | b [element 1] : | +| array_flow.rb:375:5:375:5 | b [element 1] : | array_flow.rb:377:10:377:10 | b [element 1] : | +| array_flow.rb:375:5:375:5 | b [element 1] : | array_flow.rb:378:10:378:10 | b [element 1] : | +| array_flow.rb:375:5:375:5 | b [element 1] : | array_flow.rb:378:10:378:10 | b [element 1] : | +| array_flow.rb:375:5:375:5 | b [element 2] : | array_flow.rb:378:10:378:10 | b [element 2] : | +| array_flow.rb:375:5:375:5 | b [element 2] : | array_flow.rb:378:10:378:10 | b [element 2] : | | array_flow.rb:375:9:375:9 | a [element 2] : | array_flow.rb:375:9:375:17 | call to drop [element 1] : | | array_flow.rb:375:9:375:9 | a [element 2] : | array_flow.rb:375:9:375:17 | call to drop [element 1] : | | array_flow.rb:375:9:375:9 | a [element 3] : | array_flow.rb:375:9:375:17 | call to drop [element 2] : | | array_flow.rb:375:9:375:9 | a [element 3] : | array_flow.rb:375:9:375:17 | call to drop [element 2] : | -| array_flow.rb:375:9:375:17 | call to drop [element 1] : | array_flow.rb:377:10:377:10 | b [element 1] : | -| array_flow.rb:375:9:375:17 | call to drop [element 1] : | array_flow.rb:377:10:377:10 | b [element 1] : | -| array_flow.rb:375:9:375:17 | call to drop [element 1] : | array_flow.rb:378:10:378:10 | b [element 1] : | -| array_flow.rb:375:9:375:17 | call to drop [element 1] : | array_flow.rb:378:10:378:10 | b [element 1] : | -| array_flow.rb:375:9:375:17 | call to drop [element 2] : | array_flow.rb:378:10:378:10 | b [element 2] : | -| array_flow.rb:375:9:375:17 | call to drop [element 2] : | array_flow.rb:378:10:378:10 | b [element 2] : | +| array_flow.rb:375:9:375:17 | call to drop [element 1] : | array_flow.rb:375:5:375:5 | b [element 1] : | +| array_flow.rb:375:9:375:17 | call to drop [element 1] : | array_flow.rb:375:5:375:5 | b [element 1] : | +| array_flow.rb:375:9:375:17 | call to drop [element 2] : | array_flow.rb:375:5:375:5 | b [element 2] : | +| array_flow.rb:375:9:375:17 | call to drop [element 2] : | array_flow.rb:375:5:375:5 | b [element 2] : | | array_flow.rb:377:10:377:10 | b [element 1] : | array_flow.rb:377:10:377:13 | ...[...] | | array_flow.rb:377:10:377:10 | b [element 1] : | array_flow.rb:377:10:377:13 | ...[...] | | array_flow.rb:378:10:378:10 | b [element 1] : | array_flow.rb:378:10:378:13 | ...[...] | @@ -658,30 +835,42 @@ edges | array_flow.rb:379:5:379:5 | [post] a [element] : | array_flow.rb:380:9:380:9 | a [element] : | | array_flow.rb:379:12:379:23 | call to source : | array_flow.rb:379:5:379:5 | [post] a [element] : | | array_flow.rb:379:12:379:23 | call to source : | array_flow.rb:379:5:379:5 | [post] a [element] : | +| array_flow.rb:380:5:380:5 | b [element 1] : | array_flow.rb:381:10:381:10 | b [element 1] : | +| array_flow.rb:380:5:380:5 | b [element 1] : | array_flow.rb:381:10:381:10 | b [element 1] : | +| array_flow.rb:380:5:380:5 | b [element] : | array_flow.rb:381:10:381:10 | b [element] : | +| array_flow.rb:380:5:380:5 | b [element] : | array_flow.rb:381:10:381:10 | b [element] : | +| array_flow.rb:380:5:380:5 | b [element] : | array_flow.rb:382:9:382:9 | b [element] : | +| array_flow.rb:380:5:380:5 | b [element] : | array_flow.rb:382:9:382:9 | b [element] : | | array_flow.rb:380:9:380:9 | a [element 2] : | array_flow.rb:380:9:380:17 | call to drop [element 1] : | | array_flow.rb:380:9:380:9 | a [element 2] : | array_flow.rb:380:9:380:17 | call to drop [element 1] : | | array_flow.rb:380:9:380:9 | a [element] : | array_flow.rb:380:9:380:17 | call to drop [element] : | | array_flow.rb:380:9:380:9 | a [element] : | array_flow.rb:380:9:380:17 | call to drop [element] : | -| array_flow.rb:380:9:380:17 | call to drop [element 1] : | array_flow.rb:381:10:381:10 | b [element 1] : | -| array_flow.rb:380:9:380:17 | call to drop [element 1] : | array_flow.rb:381:10:381:10 | b [element 1] : | -| array_flow.rb:380:9:380:17 | call to drop [element] : | array_flow.rb:381:10:381:10 | b [element] : | -| array_flow.rb:380:9:380:17 | call to drop [element] : | array_flow.rb:381:10:381:10 | b [element] : | -| array_flow.rb:380:9:380:17 | call to drop [element] : | array_flow.rb:382:9:382:9 | b [element] : | -| array_flow.rb:380:9:380:17 | call to drop [element] : | array_flow.rb:382:9:382:9 | b [element] : | +| array_flow.rb:380:9:380:17 | call to drop [element 1] : | array_flow.rb:380:5:380:5 | b [element 1] : | +| array_flow.rb:380:9:380:17 | call to drop [element 1] : | array_flow.rb:380:5:380:5 | b [element 1] : | +| array_flow.rb:380:9:380:17 | call to drop [element] : | array_flow.rb:380:5:380:5 | b [element] : | +| array_flow.rb:380:9:380:17 | call to drop [element] : | array_flow.rb:380:5:380:5 | b [element] : | | array_flow.rb:381:10:381:10 | b [element 1] : | array_flow.rb:381:10:381:13 | ...[...] | | array_flow.rb:381:10:381:10 | b [element 1] : | array_flow.rb:381:10:381:13 | ...[...] | | array_flow.rb:381:10:381:10 | b [element] : | array_flow.rb:381:10:381:13 | ...[...] | | array_flow.rb:381:10:381:10 | b [element] : | array_flow.rb:381:10:381:13 | ...[...] | +| array_flow.rb:382:5:382:5 | c [element] : | array_flow.rb:383:10:383:10 | c [element] : | +| array_flow.rb:382:5:382:5 | c [element] : | array_flow.rb:383:10:383:10 | c [element] : | | array_flow.rb:382:9:382:9 | b [element] : | array_flow.rb:382:9:382:19 | call to drop [element] : | | array_flow.rb:382:9:382:9 | b [element] : | array_flow.rb:382:9:382:19 | call to drop [element] : | -| array_flow.rb:382:9:382:19 | call to drop [element] : | array_flow.rb:383:10:383:10 | c [element] : | -| array_flow.rb:382:9:382:19 | call to drop [element] : | array_flow.rb:383:10:383:10 | c [element] : | +| array_flow.rb:382:9:382:19 | call to drop [element] : | array_flow.rb:382:5:382:5 | c [element] : | +| array_flow.rb:382:9:382:19 | call to drop [element] : | array_flow.rb:382:5:382:5 | c [element] : | | array_flow.rb:383:10:383:10 | c [element] : | array_flow.rb:383:10:383:13 | ...[...] | | array_flow.rb:383:10:383:10 | c [element] : | array_flow.rb:383:10:383:13 | ...[...] | -| array_flow.rb:387:16:387:27 | call to source : | array_flow.rb:388:9:388:9 | a [element 2] : | -| array_flow.rb:387:16:387:27 | call to source : | array_flow.rb:388:9:388:9 | a [element 2] : | -| array_flow.rb:387:30:387:41 | call to source : | array_flow.rb:388:9:388:9 | a [element 3] : | -| array_flow.rb:387:30:387:41 | call to source : | array_flow.rb:388:9:388:9 | a [element 3] : | +| array_flow.rb:387:5:387:5 | a [element 2] : | array_flow.rb:388:9:388:9 | a [element 2] : | +| array_flow.rb:387:5:387:5 | a [element 2] : | array_flow.rb:388:9:388:9 | a [element 2] : | +| array_flow.rb:387:5:387:5 | a [element 3] : | array_flow.rb:388:9:388:9 | a [element 3] : | +| array_flow.rb:387:5:387:5 | a [element 3] : | array_flow.rb:388:9:388:9 | a [element 3] : | +| array_flow.rb:387:16:387:27 | call to source : | array_flow.rb:387:5:387:5 | a [element 2] : | +| array_flow.rb:387:16:387:27 | call to source : | array_flow.rb:387:5:387:5 | a [element 2] : | +| array_flow.rb:387:30:387:41 | call to source : | array_flow.rb:387:5:387:5 | a [element 3] : | +| array_flow.rb:387:30:387:41 | call to source : | array_flow.rb:387:5:387:5 | a [element 3] : | +| array_flow.rb:388:5:388:5 | b [element] : | array_flow.rb:391:10:391:10 | b [element] : | +| array_flow.rb:388:5:388:5 | b [element] : | array_flow.rb:391:10:391:10 | b [element] : | | array_flow.rb:388:9:388:9 | a [element 2] : | array_flow.rb:388:9:390:7 | call to drop_while [element] : | | array_flow.rb:388:9:388:9 | a [element 2] : | array_flow.rb:388:9:390:7 | call to drop_while [element] : | | array_flow.rb:388:9:388:9 | a [element 2] : | array_flow.rb:388:26:388:26 | x : | @@ -690,40 +879,50 @@ edges | array_flow.rb:388:9:388:9 | a [element 3] : | array_flow.rb:388:9:390:7 | call to drop_while [element] : | | array_flow.rb:388:9:388:9 | a [element 3] : | array_flow.rb:388:26:388:26 | x : | | array_flow.rb:388:9:388:9 | a [element 3] : | array_flow.rb:388:26:388:26 | x : | -| array_flow.rb:388:9:390:7 | call to drop_while [element] : | array_flow.rb:391:10:391:10 | b [element] : | -| array_flow.rb:388:9:390:7 | call to drop_while [element] : | array_flow.rb:391:10:391:10 | b [element] : | +| array_flow.rb:388:9:390:7 | call to drop_while [element] : | array_flow.rb:388:5:388:5 | b [element] : | +| array_flow.rb:388:9:390:7 | call to drop_while [element] : | array_flow.rb:388:5:388:5 | b [element] : | | array_flow.rb:388:26:388:26 | x : | array_flow.rb:389:14:389:14 | x | | array_flow.rb:388:26:388:26 | x : | array_flow.rb:389:14:389:14 | x | | array_flow.rb:391:10:391:10 | b [element] : | array_flow.rb:391:10:391:13 | ...[...] | | array_flow.rb:391:10:391:10 | b [element] : | array_flow.rb:391:10:391:13 | ...[...] | -| array_flow.rb:395:16:395:25 | call to source : | array_flow.rb:396:9:396:9 | a [element 2] : | -| array_flow.rb:395:16:395:25 | call to source : | array_flow.rb:396:9:396:9 | a [element 2] : | +| array_flow.rb:395:5:395:5 | a [element 2] : | array_flow.rb:396:9:396:9 | a [element 2] : | +| array_flow.rb:395:5:395:5 | a [element 2] : | array_flow.rb:396:9:396:9 | a [element 2] : | +| array_flow.rb:395:16:395:25 | call to source : | array_flow.rb:395:5:395:5 | a [element 2] : | +| array_flow.rb:395:16:395:25 | call to source : | array_flow.rb:395:5:395:5 | a [element 2] : | +| array_flow.rb:396:5:396:5 | b [element 2] : | array_flow.rb:399:10:399:10 | b [element 2] : | +| array_flow.rb:396:5:396:5 | b [element 2] : | array_flow.rb:399:10:399:10 | b [element 2] : | | array_flow.rb:396:9:396:9 | a [element 2] : | array_flow.rb:396:9:398:7 | call to each [element 2] : | | array_flow.rb:396:9:396:9 | a [element 2] : | array_flow.rb:396:9:398:7 | call to each [element 2] : | | array_flow.rb:396:9:396:9 | a [element 2] : | array_flow.rb:396:20:396:20 | x : | | array_flow.rb:396:9:396:9 | a [element 2] : | array_flow.rb:396:20:396:20 | x : | -| array_flow.rb:396:9:398:7 | call to each [element 2] : | array_flow.rb:399:10:399:10 | b [element 2] : | -| array_flow.rb:396:9:398:7 | call to each [element 2] : | array_flow.rb:399:10:399:10 | b [element 2] : | +| array_flow.rb:396:9:398:7 | call to each [element 2] : | array_flow.rb:396:5:396:5 | b [element 2] : | +| array_flow.rb:396:9:398:7 | call to each [element 2] : | array_flow.rb:396:5:396:5 | b [element 2] : | | array_flow.rb:396:20:396:20 | x : | array_flow.rb:397:14:397:14 | x | | array_flow.rb:396:20:396:20 | x : | array_flow.rb:397:14:397:14 | x | | array_flow.rb:399:10:399:10 | b [element 2] : | array_flow.rb:399:10:399:13 | ...[...] | | array_flow.rb:399:10:399:10 | b [element 2] : | array_flow.rb:399:10:399:13 | ...[...] | -| array_flow.rb:403:16:403:25 | call to source : | array_flow.rb:404:18:404:18 | a [element 2] : | -| array_flow.rb:403:16:403:25 | call to source : | array_flow.rb:404:18:404:18 | a [element 2] : | -| array_flow.rb:404:9:406:7 | ... = ... : | array_flow.rb:407:10:407:10 | x | -| array_flow.rb:404:9:406:7 | ... = ... : | array_flow.rb:407:10:407:10 | x | -| array_flow.rb:404:9:406:7 | __synth__0__1 : | array_flow.rb:404:9:406:7 | ... = ... : | -| array_flow.rb:404:9:406:7 | __synth__0__1 : | array_flow.rb:404:9:406:7 | ... = ... : | -| array_flow.rb:404:9:406:7 | __synth__0__1 : | array_flow.rb:405:14:405:14 | x | -| array_flow.rb:404:9:406:7 | __synth__0__1 : | array_flow.rb:405:14:405:14 | x | +| array_flow.rb:403:5:403:5 | a [element 2] : | array_flow.rb:404:18:404:18 | a [element 2] : | +| array_flow.rb:403:5:403:5 | a [element 2] : | array_flow.rb:404:18:404:18 | a [element 2] : | +| array_flow.rb:403:16:403:25 | call to source : | array_flow.rb:403:5:403:5 | a [element 2] : | +| array_flow.rb:403:16:403:25 | call to source : | array_flow.rb:403:5:403:5 | a [element 2] : | +| array_flow.rb:404:5:404:5 | b [element 2] : | array_flow.rb:408:10:408:10 | b [element 2] : | +| array_flow.rb:404:5:404:5 | b [element 2] : | array_flow.rb:408:10:408:10 | b [element 2] : | +| array_flow.rb:404:9:406:7 | __synth__0__1 : | array_flow.rb:404:13:404:13 | x : | +| array_flow.rb:404:9:406:7 | __synth__0__1 : | array_flow.rb:404:13:404:13 | x : | +| array_flow.rb:404:13:404:13 | x : | array_flow.rb:405:14:405:14 | x | +| array_flow.rb:404:13:404:13 | x : | array_flow.rb:405:14:405:14 | x | +| array_flow.rb:404:13:404:13 | x : | array_flow.rb:407:10:407:10 | x | +| array_flow.rb:404:13:404:13 | x : | array_flow.rb:407:10:407:10 | x | +| array_flow.rb:404:18:404:18 | a [element 2] : | array_flow.rb:404:5:404:5 | b [element 2] : | +| array_flow.rb:404:18:404:18 | a [element 2] : | array_flow.rb:404:5:404:5 | b [element 2] : | | array_flow.rb:404:18:404:18 | a [element 2] : | array_flow.rb:404:9:406:7 | __synth__0__1 : | | array_flow.rb:404:18:404:18 | a [element 2] : | array_flow.rb:404:9:406:7 | __synth__0__1 : | -| array_flow.rb:404:18:404:18 | a [element 2] : | array_flow.rb:408:10:408:10 | b [element 2] : | -| array_flow.rb:404:18:404:18 | a [element 2] : | array_flow.rb:408:10:408:10 | b [element 2] : | | array_flow.rb:408:10:408:10 | b [element 2] : | array_flow.rb:408:10:408:13 | ...[...] | | array_flow.rb:408:10:408:10 | b [element 2] : | array_flow.rb:408:10:408:13 | ...[...] | -| array_flow.rb:412:16:412:25 | call to source : | array_flow.rb:413:5:413:5 | a [element 2] : | -| array_flow.rb:412:16:412:25 | call to source : | array_flow.rb:413:5:413:5 | a [element 2] : | +| array_flow.rb:412:5:412:5 | a [element 2] : | array_flow.rb:413:5:413:5 | a [element 2] : | +| array_flow.rb:412:5:412:5 | a [element 2] : | array_flow.rb:413:5:413:5 | a [element 2] : | +| array_flow.rb:412:16:412:25 | call to source : | array_flow.rb:412:5:412:5 | a [element 2] : | +| array_flow.rb:412:16:412:25 | call to source : | array_flow.rb:412:5:412:5 | a [element 2] : | | array_flow.rb:413:5:413:5 | a [element 2] : | array_flow.rb:413:24:413:24 | x [element] : | | array_flow.rb:413:5:413:5 | a [element 2] : | array_flow.rb:413:24:413:24 | x [element] : | | array_flow.rb:413:24:413:24 | x [element] : | array_flow.rb:414:15:414:15 | x [element] : | @@ -732,52 +931,70 @@ edges | array_flow.rb:414:15:414:15 | x [element] : | array_flow.rb:414:15:414:18 | ...[...] : | | array_flow.rb:414:15:414:18 | ...[...] : | array_flow.rb:414:14:414:19 | ( ... ) | | array_flow.rb:414:15:414:18 | ...[...] : | array_flow.rb:414:14:414:19 | ( ... ) | -| array_flow.rb:419:16:419:25 | call to source : | array_flow.rb:420:9:420:9 | a [element 2] : | -| array_flow.rb:419:16:419:25 | call to source : | array_flow.rb:420:9:420:9 | a [element 2] : | +| array_flow.rb:419:5:419:5 | a [element 2] : | array_flow.rb:420:9:420:9 | a [element 2] : | +| array_flow.rb:419:5:419:5 | a [element 2] : | array_flow.rb:420:9:420:9 | a [element 2] : | +| array_flow.rb:419:16:419:25 | call to source : | array_flow.rb:419:5:419:5 | a [element 2] : | +| array_flow.rb:419:16:419:25 | call to source : | array_flow.rb:419:5:419:5 | a [element 2] : | +| array_flow.rb:420:5:420:5 | b [element 2] : | array_flow.rb:423:10:423:10 | b [element 2] : | +| array_flow.rb:420:5:420:5 | b [element 2] : | array_flow.rb:423:10:423:10 | b [element 2] : | | array_flow.rb:420:9:420:9 | a [element 2] : | array_flow.rb:420:9:422:7 | call to each_entry [element 2] : | | array_flow.rb:420:9:420:9 | a [element 2] : | array_flow.rb:420:9:422:7 | call to each_entry [element 2] : | | array_flow.rb:420:9:420:9 | a [element 2] : | array_flow.rb:420:26:420:26 | x : | | array_flow.rb:420:9:420:9 | a [element 2] : | array_flow.rb:420:26:420:26 | x : | -| array_flow.rb:420:9:422:7 | call to each_entry [element 2] : | array_flow.rb:423:10:423:10 | b [element 2] : | -| array_flow.rb:420:9:422:7 | call to each_entry [element 2] : | array_flow.rb:423:10:423:10 | b [element 2] : | +| array_flow.rb:420:9:422:7 | call to each_entry [element 2] : | array_flow.rb:420:5:420:5 | b [element 2] : | +| array_flow.rb:420:9:422:7 | call to each_entry [element 2] : | array_flow.rb:420:5:420:5 | b [element 2] : | | array_flow.rb:420:26:420:26 | x : | array_flow.rb:421:14:421:14 | x | | array_flow.rb:420:26:420:26 | x : | array_flow.rb:421:14:421:14 | x | | array_flow.rb:423:10:423:10 | b [element 2] : | array_flow.rb:423:10:423:13 | ...[...] | | array_flow.rb:423:10:423:10 | b [element 2] : | array_flow.rb:423:10:423:13 | ...[...] | -| array_flow.rb:427:16:427:25 | call to source : | array_flow.rb:428:9:428:9 | a [element 2] : | -| array_flow.rb:427:16:427:25 | call to source : | array_flow.rb:428:9:428:9 | a [element 2] : | +| array_flow.rb:427:5:427:5 | a [element 2] : | array_flow.rb:428:9:428:9 | a [element 2] : | +| array_flow.rb:427:5:427:5 | a [element 2] : | array_flow.rb:428:9:428:9 | a [element 2] : | +| array_flow.rb:427:16:427:25 | call to source : | array_flow.rb:427:5:427:5 | a [element 2] : | +| array_flow.rb:427:16:427:25 | call to source : | array_flow.rb:427:5:427:5 | a [element 2] : | +| array_flow.rb:428:5:428:5 | b [element 2] : | array_flow.rb:431:10:431:10 | b [element 2] : | +| array_flow.rb:428:5:428:5 | b [element 2] : | array_flow.rb:431:10:431:10 | b [element 2] : | | array_flow.rb:428:9:428:9 | a [element 2] : | array_flow.rb:428:9:430:7 | call to each_index [element 2] : | | array_flow.rb:428:9:428:9 | a [element 2] : | array_flow.rb:428:9:430:7 | call to each_index [element 2] : | -| array_flow.rb:428:9:430:7 | call to each_index [element 2] : | array_flow.rb:431:10:431:10 | b [element 2] : | -| array_flow.rb:428:9:430:7 | call to each_index [element 2] : | array_flow.rb:431:10:431:10 | b [element 2] : | +| array_flow.rb:428:9:430:7 | call to each_index [element 2] : | array_flow.rb:428:5:428:5 | b [element 2] : | +| array_flow.rb:428:9:430:7 | call to each_index [element 2] : | array_flow.rb:428:5:428:5 | b [element 2] : | | array_flow.rb:431:10:431:10 | b [element 2] : | array_flow.rb:431:10:431:13 | ...[...] | | array_flow.rb:431:10:431:10 | b [element 2] : | array_flow.rb:431:10:431:13 | ...[...] | -| array_flow.rb:435:19:435:28 | call to source : | array_flow.rb:436:5:436:5 | a [element 3] : | -| array_flow.rb:435:19:435:28 | call to source : | array_flow.rb:436:5:436:5 | a [element 3] : | +| array_flow.rb:435:5:435:5 | a [element 3] : | array_flow.rb:436:5:436:5 | a [element 3] : | +| array_flow.rb:435:5:435:5 | a [element 3] : | array_flow.rb:436:5:436:5 | a [element 3] : | +| array_flow.rb:435:19:435:28 | call to source : | array_flow.rb:435:5:435:5 | a [element 3] : | +| array_flow.rb:435:19:435:28 | call to source : | array_flow.rb:435:5:435:5 | a [element 3] : | | array_flow.rb:436:5:436:5 | a [element 3] : | array_flow.rb:436:25:436:25 | x [element] : | | array_flow.rb:436:5:436:5 | a [element 3] : | array_flow.rb:436:25:436:25 | x [element] : | | array_flow.rb:436:25:436:25 | x [element] : | array_flow.rb:437:14:437:14 | x [element] : | | array_flow.rb:436:25:436:25 | x [element] : | array_flow.rb:437:14:437:14 | x [element] : | | array_flow.rb:437:14:437:14 | x [element] : | array_flow.rb:437:14:437:17 | ...[...] | | array_flow.rb:437:14:437:14 | x [element] : | array_flow.rb:437:14:437:17 | ...[...] | -| array_flow.rb:442:19:442:28 | call to source : | array_flow.rb:443:9:443:9 | a [element 3] : | -| array_flow.rb:442:19:442:28 | call to source : | array_flow.rb:443:9:443:9 | a [element 3] : | +| array_flow.rb:442:5:442:5 | a [element 3] : | array_flow.rb:443:9:443:9 | a [element 3] : | +| array_flow.rb:442:5:442:5 | a [element 3] : | array_flow.rb:443:9:443:9 | a [element 3] : | +| array_flow.rb:442:19:442:28 | call to source : | array_flow.rb:442:5:442:5 | a [element 3] : | +| array_flow.rb:442:19:442:28 | call to source : | array_flow.rb:442:5:442:5 | a [element 3] : | +| array_flow.rb:443:5:443:5 | b [element 3] : | array_flow.rb:447:10:447:10 | b [element 3] : | +| array_flow.rb:443:5:443:5 | b [element 3] : | array_flow.rb:447:10:447:10 | b [element 3] : | | array_flow.rb:443:9:443:9 | a [element 3] : | array_flow.rb:443:9:446:7 | call to each_with_index [element 3] : | | array_flow.rb:443:9:443:9 | a [element 3] : | array_flow.rb:443:9:446:7 | call to each_with_index [element 3] : | | array_flow.rb:443:9:443:9 | a [element 3] : | array_flow.rb:443:31:443:31 | x : | | array_flow.rb:443:9:443:9 | a [element 3] : | array_flow.rb:443:31:443:31 | x : | -| array_flow.rb:443:9:446:7 | call to each_with_index [element 3] : | array_flow.rb:447:10:447:10 | b [element 3] : | -| array_flow.rb:443:9:446:7 | call to each_with_index [element 3] : | array_flow.rb:447:10:447:10 | b [element 3] : | +| array_flow.rb:443:9:446:7 | call to each_with_index [element 3] : | array_flow.rb:443:5:443:5 | b [element 3] : | +| array_flow.rb:443:9:446:7 | call to each_with_index [element 3] : | array_flow.rb:443:5:443:5 | b [element 3] : | | array_flow.rb:443:31:443:31 | x : | array_flow.rb:444:14:444:14 | x | | array_flow.rb:443:31:443:31 | x : | array_flow.rb:444:14:444:14 | x | | array_flow.rb:447:10:447:10 | b [element 3] : | array_flow.rb:447:10:447:13 | ...[...] | | array_flow.rb:447:10:447:10 | b [element 3] : | array_flow.rb:447:10:447:13 | ...[...] | -| array_flow.rb:451:19:451:30 | call to source : | array_flow.rb:452:9:452:9 | a [element 3] : | -| array_flow.rb:451:19:451:30 | call to source : | array_flow.rb:452:9:452:9 | a [element 3] : | +| array_flow.rb:451:5:451:5 | a [element 3] : | array_flow.rb:452:9:452:9 | a [element 3] : | +| array_flow.rb:451:5:451:5 | a [element 3] : | array_flow.rb:452:9:452:9 | a [element 3] : | +| array_flow.rb:451:19:451:30 | call to source : | array_flow.rb:451:5:451:5 | a [element 3] : | +| array_flow.rb:451:19:451:30 | call to source : | array_flow.rb:451:5:451:5 | a [element 3] : | +| array_flow.rb:452:5:452:5 | b : | array_flow.rb:456:10:456:10 | b | +| array_flow.rb:452:5:452:5 | b : | array_flow.rb:456:10:456:10 | b | | array_flow.rb:452:9:452:9 | a [element 3] : | array_flow.rb:452:46:452:46 | x : | | array_flow.rb:452:9:452:9 | a [element 3] : | array_flow.rb:452:46:452:46 | x : | -| array_flow.rb:452:9:455:7 | call to each_with_object : | array_flow.rb:456:10:456:10 | b | -| array_flow.rb:452:9:455:7 | call to each_with_object : | array_flow.rb:456:10:456:10 | b | +| array_flow.rb:452:9:455:7 | call to each_with_object : | array_flow.rb:452:5:452:5 | b : | +| array_flow.rb:452:9:455:7 | call to each_with_object : | array_flow.rb:452:5:452:5 | b : | | array_flow.rb:452:28:452:39 | call to source : | array_flow.rb:452:9:455:7 | call to each_with_object : | | array_flow.rb:452:28:452:39 | call to source : | array_flow.rb:452:9:455:7 | call to each_with_object : | | array_flow.rb:452:28:452:39 | call to source : | array_flow.rb:452:48:452:48 | a : | @@ -786,60 +1003,80 @@ edges | array_flow.rb:452:46:452:46 | x : | array_flow.rb:453:14:453:14 | x | | array_flow.rb:452:48:452:48 | a : | array_flow.rb:454:14:454:14 | a | | array_flow.rb:452:48:452:48 | a : | array_flow.rb:454:14:454:14 | a | -| array_flow.rb:460:19:460:28 | call to source : | array_flow.rb:461:9:461:9 | a [element 3] : | -| array_flow.rb:460:19:460:28 | call to source : | array_flow.rb:461:9:461:9 | a [element 3] : | +| array_flow.rb:460:5:460:5 | a [element 3] : | array_flow.rb:461:9:461:9 | a [element 3] : | +| array_flow.rb:460:5:460:5 | a [element 3] : | array_flow.rb:461:9:461:9 | a [element 3] : | +| array_flow.rb:460:19:460:28 | call to source : | array_flow.rb:460:5:460:5 | a [element 3] : | +| array_flow.rb:460:19:460:28 | call to source : | array_flow.rb:460:5:460:5 | a [element 3] : | +| array_flow.rb:461:5:461:5 | b [element 3] : | array_flow.rb:462:10:462:10 | b [element 3] : | +| array_flow.rb:461:5:461:5 | b [element 3] : | array_flow.rb:462:10:462:10 | b [element 3] : | | array_flow.rb:461:9:461:9 | a [element 3] : | array_flow.rb:461:9:461:17 | call to entries [element 3] : | | array_flow.rb:461:9:461:9 | a [element 3] : | array_flow.rb:461:9:461:17 | call to entries [element 3] : | -| array_flow.rb:461:9:461:17 | call to entries [element 3] : | array_flow.rb:462:10:462:10 | b [element 3] : | -| array_flow.rb:461:9:461:17 | call to entries [element 3] : | array_flow.rb:462:10:462:10 | b [element 3] : | +| array_flow.rb:461:9:461:17 | call to entries [element 3] : | array_flow.rb:461:5:461:5 | b [element 3] : | +| array_flow.rb:461:9:461:17 | call to entries [element 3] : | array_flow.rb:461:5:461:5 | b [element 3] : | | array_flow.rb:462:10:462:10 | b [element 3] : | array_flow.rb:462:10:462:13 | ...[...] | | array_flow.rb:462:10:462:10 | b [element 3] : | array_flow.rb:462:10:462:13 | ...[...] | -| array_flow.rb:466:19:466:30 | call to source : | array_flow.rb:467:9:467:9 | a [element 3] : | -| array_flow.rb:466:19:466:30 | call to source : | array_flow.rb:467:9:467:9 | a [element 3] : | -| array_flow.rb:466:19:466:30 | call to source : | array_flow.rb:471:9:471:9 | a [element 3] : | -| array_flow.rb:466:19:466:30 | call to source : | array_flow.rb:471:9:471:9 | a [element 3] : | -| array_flow.rb:466:19:466:30 | call to source : | array_flow.rb:473:9:473:9 | a [element 3] : | -| array_flow.rb:466:19:466:30 | call to source : | array_flow.rb:473:9:473:9 | a [element 3] : | -| array_flow.rb:466:19:466:30 | call to source : | array_flow.rb:477:9:477:9 | a [element 3] : | -| array_flow.rb:466:19:466:30 | call to source : | array_flow.rb:477:9:477:9 | a [element 3] : | -| array_flow.rb:466:33:466:44 | call to source : | array_flow.rb:467:9:467:9 | a [element 4] : | -| array_flow.rb:466:33:466:44 | call to source : | array_flow.rb:467:9:467:9 | a [element 4] : | -| array_flow.rb:466:33:466:44 | call to source : | array_flow.rb:477:9:477:9 | a [element 4] : | -| array_flow.rb:466:33:466:44 | call to source : | array_flow.rb:477:9:477:9 | a [element 4] : | +| array_flow.rb:466:5:466:5 | a [element 3] : | array_flow.rb:467:9:467:9 | a [element 3] : | +| array_flow.rb:466:5:466:5 | a [element 3] : | array_flow.rb:467:9:467:9 | a [element 3] : | +| array_flow.rb:466:5:466:5 | a [element 3] : | array_flow.rb:471:9:471:9 | a [element 3] : | +| array_flow.rb:466:5:466:5 | a [element 3] : | array_flow.rb:471:9:471:9 | a [element 3] : | +| array_flow.rb:466:5:466:5 | a [element 3] : | array_flow.rb:473:9:473:9 | a [element 3] : | +| array_flow.rb:466:5:466:5 | a [element 3] : | array_flow.rb:473:9:473:9 | a [element 3] : | +| array_flow.rb:466:5:466:5 | a [element 3] : | array_flow.rb:477:9:477:9 | a [element 3] : | +| array_flow.rb:466:5:466:5 | a [element 3] : | array_flow.rb:477:9:477:9 | a [element 3] : | +| array_flow.rb:466:5:466:5 | a [element 4] : | array_flow.rb:467:9:467:9 | a [element 4] : | +| array_flow.rb:466:5:466:5 | a [element 4] : | array_flow.rb:467:9:467:9 | a [element 4] : | +| array_flow.rb:466:5:466:5 | a [element 4] : | array_flow.rb:477:9:477:9 | a [element 4] : | +| array_flow.rb:466:5:466:5 | a [element 4] : | array_flow.rb:477:9:477:9 | a [element 4] : | +| array_flow.rb:466:19:466:30 | call to source : | array_flow.rb:466:5:466:5 | a [element 3] : | +| array_flow.rb:466:19:466:30 | call to source : | array_flow.rb:466:5:466:5 | a [element 3] : | +| array_flow.rb:466:33:466:44 | call to source : | array_flow.rb:466:5:466:5 | a [element 4] : | +| array_flow.rb:466:33:466:44 | call to source : | array_flow.rb:466:5:466:5 | a [element 4] : | +| array_flow.rb:467:5:467:5 | b : | array_flow.rb:470:10:470:10 | b | +| array_flow.rb:467:5:467:5 | b : | array_flow.rb:470:10:470:10 | b | | array_flow.rb:467:9:467:9 | a [element 3] : | array_flow.rb:467:9:469:7 | call to fetch : | | array_flow.rb:467:9:467:9 | a [element 3] : | array_flow.rb:467:9:469:7 | call to fetch : | | array_flow.rb:467:9:467:9 | a [element 4] : | array_flow.rb:467:9:469:7 | call to fetch : | | array_flow.rb:467:9:467:9 | a [element 4] : | array_flow.rb:467:9:469:7 | call to fetch : | -| array_flow.rb:467:9:469:7 | call to fetch : | array_flow.rb:470:10:470:10 | b | -| array_flow.rb:467:9:469:7 | call to fetch : | array_flow.rb:470:10:470:10 | b | +| array_flow.rb:467:9:469:7 | call to fetch : | array_flow.rb:467:5:467:5 | b : | +| array_flow.rb:467:9:469:7 | call to fetch : | array_flow.rb:467:5:467:5 | b : | | array_flow.rb:467:17:467:28 | call to source : | array_flow.rb:467:35:467:35 | x : | | array_flow.rb:467:17:467:28 | call to source : | array_flow.rb:467:35:467:35 | x : | | array_flow.rb:467:35:467:35 | x : | array_flow.rb:468:14:468:14 | x | | array_flow.rb:467:35:467:35 | x : | array_flow.rb:468:14:468:14 | x | +| array_flow.rb:471:5:471:5 | b : | array_flow.rb:472:10:472:10 | b | +| array_flow.rb:471:5:471:5 | b : | array_flow.rb:472:10:472:10 | b | | array_flow.rb:471:9:471:9 | a [element 3] : | array_flow.rb:471:9:471:18 | call to fetch : | | array_flow.rb:471:9:471:9 | a [element 3] : | array_flow.rb:471:9:471:18 | call to fetch : | -| array_flow.rb:471:9:471:18 | call to fetch : | array_flow.rb:472:10:472:10 | b | -| array_flow.rb:471:9:471:18 | call to fetch : | array_flow.rb:472:10:472:10 | b | +| array_flow.rb:471:9:471:18 | call to fetch : | array_flow.rb:471:5:471:5 | b : | +| array_flow.rb:471:9:471:18 | call to fetch : | array_flow.rb:471:5:471:5 | b : | +| array_flow.rb:473:5:473:5 | b : | array_flow.rb:474:10:474:10 | b | +| array_flow.rb:473:5:473:5 | b : | array_flow.rb:474:10:474:10 | b | | array_flow.rb:473:9:473:9 | a [element 3] : | array_flow.rb:473:9:473:32 | call to fetch : | | array_flow.rb:473:9:473:9 | a [element 3] : | array_flow.rb:473:9:473:32 | call to fetch : | -| array_flow.rb:473:9:473:32 | call to fetch : | array_flow.rb:474:10:474:10 | b | -| array_flow.rb:473:9:473:32 | call to fetch : | array_flow.rb:474:10:474:10 | b | +| array_flow.rb:473:9:473:32 | call to fetch : | array_flow.rb:473:5:473:5 | b : | +| array_flow.rb:473:9:473:32 | call to fetch : | array_flow.rb:473:5:473:5 | b : | | array_flow.rb:473:20:473:31 | call to source : | array_flow.rb:473:9:473:32 | call to fetch : | | array_flow.rb:473:20:473:31 | call to source : | array_flow.rb:473:9:473:32 | call to fetch : | -| array_flow.rb:475:9:475:34 | call to fetch : | array_flow.rb:476:10:476:10 | b | -| array_flow.rb:475:9:475:34 | call to fetch : | array_flow.rb:476:10:476:10 | b | +| array_flow.rb:475:5:475:5 | b : | array_flow.rb:476:10:476:10 | b | +| array_flow.rb:475:5:475:5 | b : | array_flow.rb:476:10:476:10 | b | +| array_flow.rb:475:9:475:34 | call to fetch : | array_flow.rb:475:5:475:5 | b : | +| array_flow.rb:475:9:475:34 | call to fetch : | array_flow.rb:475:5:475:5 | b : | | array_flow.rb:475:22:475:33 | call to source : | array_flow.rb:475:9:475:34 | call to fetch : | | array_flow.rb:475:22:475:33 | call to source : | array_flow.rb:475:9:475:34 | call to fetch : | +| array_flow.rb:477:5:477:5 | b : | array_flow.rb:478:10:478:10 | b | +| array_flow.rb:477:5:477:5 | b : | array_flow.rb:478:10:478:10 | b | | array_flow.rb:477:9:477:9 | a [element 3] : | array_flow.rb:477:9:477:32 | call to fetch : | | array_flow.rb:477:9:477:9 | a [element 3] : | array_flow.rb:477:9:477:32 | call to fetch : | | array_flow.rb:477:9:477:9 | a [element 4] : | array_flow.rb:477:9:477:32 | call to fetch : | | array_flow.rb:477:9:477:9 | a [element 4] : | array_flow.rb:477:9:477:32 | call to fetch : | -| array_flow.rb:477:9:477:32 | call to fetch : | array_flow.rb:478:10:478:10 | b | -| array_flow.rb:477:9:477:32 | call to fetch : | array_flow.rb:478:10:478:10 | b | +| array_flow.rb:477:9:477:32 | call to fetch : | array_flow.rb:477:5:477:5 | b : | +| array_flow.rb:477:9:477:32 | call to fetch : | array_flow.rb:477:5:477:5 | b : | | array_flow.rb:477:20:477:31 | call to source : | array_flow.rb:477:9:477:32 | call to fetch : | | array_flow.rb:477:20:477:31 | call to source : | array_flow.rb:477:9:477:32 | call to fetch : | -| array_flow.rb:482:19:482:30 | call to source : | array_flow.rb:484:10:484:10 | a [element 3] : | -| array_flow.rb:482:19:482:30 | call to source : | array_flow.rb:484:10:484:10 | a [element 3] : | +| array_flow.rb:482:5:482:5 | a [element 3] : | array_flow.rb:484:10:484:10 | a [element 3] : | +| array_flow.rb:482:5:482:5 | a [element 3] : | array_flow.rb:484:10:484:10 | a [element 3] : | +| array_flow.rb:482:19:482:30 | call to source : | array_flow.rb:482:5:482:5 | a [element 3] : | +| array_flow.rb:482:19:482:30 | call to source : | array_flow.rb:482:5:482:5 | a [element 3] : | | array_flow.rb:483:5:483:5 | [post] a [element] : | array_flow.rb:484:10:484:10 | a [element] : | | array_flow.rb:483:5:483:5 | [post] a [element] : | array_flow.rb:484:10:484:10 | a [element] : | | array_flow.rb:483:12:483:23 | call to source : | array_flow.rb:483:5:483:5 | [post] a [element] : | @@ -868,32 +1105,44 @@ edges | array_flow.rb:492:9:492:20 | call to source : | array_flow.rb:491:5:491:5 | [post] a [element] : | | array_flow.rb:494:10:494:10 | a [element] : | array_flow.rb:494:10:494:13 | ...[...] | | array_flow.rb:494:10:494:10 | a [element] : | array_flow.rb:494:10:494:13 | ...[...] | -| array_flow.rb:498:19:498:28 | call to source : | array_flow.rb:499:9:499:9 | a [element 3] : | -| array_flow.rb:498:19:498:28 | call to source : | array_flow.rb:499:9:499:9 | a [element 3] : | +| array_flow.rb:498:5:498:5 | a [element 3] : | array_flow.rb:499:9:499:9 | a [element 3] : | +| array_flow.rb:498:5:498:5 | a [element 3] : | array_flow.rb:499:9:499:9 | a [element 3] : | +| array_flow.rb:498:19:498:28 | call to source : | array_flow.rb:498:5:498:5 | a [element 3] : | +| array_flow.rb:498:19:498:28 | call to source : | array_flow.rb:498:5:498:5 | a [element 3] : | +| array_flow.rb:499:5:499:5 | b [element] : | array_flow.rb:502:10:502:10 | b [element] : | +| array_flow.rb:499:5:499:5 | b [element] : | array_flow.rb:502:10:502:10 | b [element] : | | array_flow.rb:499:9:499:9 | a [element 3] : | array_flow.rb:499:9:501:7 | call to filter [element] : | | array_flow.rb:499:9:499:9 | a [element 3] : | array_flow.rb:499:9:501:7 | call to filter [element] : | | array_flow.rb:499:9:499:9 | a [element 3] : | array_flow.rb:499:22:499:22 | x : | | array_flow.rb:499:9:499:9 | a [element 3] : | array_flow.rb:499:22:499:22 | x : | -| array_flow.rb:499:9:501:7 | call to filter [element] : | array_flow.rb:502:10:502:10 | b [element] : | -| array_flow.rb:499:9:501:7 | call to filter [element] : | array_flow.rb:502:10:502:10 | b [element] : | +| array_flow.rb:499:9:501:7 | call to filter [element] : | array_flow.rb:499:5:499:5 | b [element] : | +| array_flow.rb:499:9:501:7 | call to filter [element] : | array_flow.rb:499:5:499:5 | b [element] : | | array_flow.rb:499:22:499:22 | x : | array_flow.rb:500:14:500:14 | x | | array_flow.rb:499:22:499:22 | x : | array_flow.rb:500:14:500:14 | x | | array_flow.rb:502:10:502:10 | b [element] : | array_flow.rb:502:10:502:13 | ...[...] | | array_flow.rb:502:10:502:10 | b [element] : | array_flow.rb:502:10:502:13 | ...[...] | -| array_flow.rb:506:19:506:28 | call to source : | array_flow.rb:507:9:507:9 | a [element 3] : | -| array_flow.rb:506:19:506:28 | call to source : | array_flow.rb:507:9:507:9 | a [element 3] : | +| array_flow.rb:506:5:506:5 | a [element 3] : | array_flow.rb:507:9:507:9 | a [element 3] : | +| array_flow.rb:506:5:506:5 | a [element 3] : | array_flow.rb:507:9:507:9 | a [element 3] : | +| array_flow.rb:506:19:506:28 | call to source : | array_flow.rb:506:5:506:5 | a [element 3] : | +| array_flow.rb:506:19:506:28 | call to source : | array_flow.rb:506:5:506:5 | a [element 3] : | +| array_flow.rb:507:5:507:5 | b [element] : | array_flow.rb:510:10:510:10 | b [element] : | +| array_flow.rb:507:5:507:5 | b [element] : | array_flow.rb:510:10:510:10 | b [element] : | | array_flow.rb:507:9:507:9 | a [element 3] : | array_flow.rb:507:9:509:7 | call to filter_map [element] : | | array_flow.rb:507:9:507:9 | a [element 3] : | array_flow.rb:507:9:509:7 | call to filter_map [element] : | | array_flow.rb:507:9:507:9 | a [element 3] : | array_flow.rb:507:26:507:26 | x : | | array_flow.rb:507:9:507:9 | a [element 3] : | array_flow.rb:507:26:507:26 | x : | -| array_flow.rb:507:9:509:7 | call to filter_map [element] : | array_flow.rb:510:10:510:10 | b [element] : | -| array_flow.rb:507:9:509:7 | call to filter_map [element] : | array_flow.rb:510:10:510:10 | b [element] : | +| array_flow.rb:507:9:509:7 | call to filter_map [element] : | array_flow.rb:507:5:507:5 | b [element] : | +| array_flow.rb:507:9:509:7 | call to filter_map [element] : | array_flow.rb:507:5:507:5 | b [element] : | | array_flow.rb:507:26:507:26 | x : | array_flow.rb:508:14:508:14 | x | | array_flow.rb:507:26:507:26 | x : | array_flow.rb:508:14:508:14 | x | | array_flow.rb:510:10:510:10 | b [element] : | array_flow.rb:510:10:510:13 | ...[...] | | array_flow.rb:510:10:510:10 | b [element] : | array_flow.rb:510:10:510:13 | ...[...] | -| array_flow.rb:514:19:514:28 | call to source : | array_flow.rb:515:9:515:9 | a [element 3] : | -| array_flow.rb:514:19:514:28 | call to source : | array_flow.rb:515:9:515:9 | a [element 3] : | +| array_flow.rb:514:5:514:5 | a [element 3] : | array_flow.rb:515:9:515:9 | a [element 3] : | +| array_flow.rb:514:5:514:5 | a [element 3] : | array_flow.rb:515:9:515:9 | a [element 3] : | +| array_flow.rb:514:19:514:28 | call to source : | array_flow.rb:514:5:514:5 | a [element 3] : | +| array_flow.rb:514:19:514:28 | call to source : | array_flow.rb:514:5:514:5 | a [element 3] : | +| array_flow.rb:515:5:515:5 | b [element] : | array_flow.rb:520:10:520:10 | b [element] : | +| array_flow.rb:515:5:515:5 | b [element] : | array_flow.rb:520:10:520:10 | b [element] : | | array_flow.rb:515:9:515:9 | [post] a [element] : | array_flow.rb:519:10:519:10 | a [element] : | | array_flow.rb:515:9:515:9 | [post] a [element] : | array_flow.rb:519:10:519:10 | a [element] : | | array_flow.rb:515:9:515:9 | a [element 3] : | array_flow.rb:515:9:515:9 | [post] a [element] : | @@ -902,52 +1151,66 @@ edges | array_flow.rb:515:9:515:9 | a [element 3] : | array_flow.rb:515:9:518:7 | call to filter! [element] : | | array_flow.rb:515:9:515:9 | a [element 3] : | array_flow.rb:515:23:515:23 | x : | | array_flow.rb:515:9:515:9 | a [element 3] : | array_flow.rb:515:23:515:23 | x : | -| array_flow.rb:515:9:518:7 | call to filter! [element] : | array_flow.rb:520:10:520:10 | b [element] : | -| array_flow.rb:515:9:518:7 | call to filter! [element] : | array_flow.rb:520:10:520:10 | b [element] : | +| array_flow.rb:515:9:518:7 | call to filter! [element] : | array_flow.rb:515:5:515:5 | b [element] : | +| array_flow.rb:515:9:518:7 | call to filter! [element] : | array_flow.rb:515:5:515:5 | b [element] : | | array_flow.rb:515:23:515:23 | x : | array_flow.rb:516:14:516:14 | x | | array_flow.rb:515:23:515:23 | x : | array_flow.rb:516:14:516:14 | x | | array_flow.rb:519:10:519:10 | a [element] : | array_flow.rb:519:10:519:13 | ...[...] | | array_flow.rb:519:10:519:10 | a [element] : | array_flow.rb:519:10:519:13 | ...[...] | | array_flow.rb:520:10:520:10 | b [element] : | array_flow.rb:520:10:520:13 | ...[...] | | array_flow.rb:520:10:520:10 | b [element] : | array_flow.rb:520:10:520:13 | ...[...] | -| array_flow.rb:524:19:524:30 | call to source : | array_flow.rb:525:9:525:9 | a [element 3] : | -| array_flow.rb:524:19:524:30 | call to source : | array_flow.rb:525:9:525:9 | a [element 3] : | +| array_flow.rb:524:5:524:5 | a [element 3] : | array_flow.rb:525:9:525:9 | a [element 3] : | +| array_flow.rb:524:5:524:5 | a [element 3] : | array_flow.rb:525:9:525:9 | a [element 3] : | +| array_flow.rb:524:19:524:30 | call to source : | array_flow.rb:524:5:524:5 | a [element 3] : | +| array_flow.rb:524:19:524:30 | call to source : | array_flow.rb:524:5:524:5 | a [element 3] : | +| array_flow.rb:525:5:525:5 | b : | array_flow.rb:528:10:528:10 | b | +| array_flow.rb:525:5:525:5 | b : | array_flow.rb:528:10:528:10 | b | | array_flow.rb:525:9:525:9 | a [element 3] : | array_flow.rb:525:9:527:7 | call to find : | | array_flow.rb:525:9:525:9 | a [element 3] : | array_flow.rb:525:9:527:7 | call to find : | | array_flow.rb:525:9:525:9 | a [element 3] : | array_flow.rb:525:41:525:41 | x : | | array_flow.rb:525:9:525:9 | a [element 3] : | array_flow.rb:525:41:525:41 | x : | -| array_flow.rb:525:9:527:7 | call to find : | array_flow.rb:528:10:528:10 | b | -| array_flow.rb:525:9:527:7 | call to find : | array_flow.rb:528:10:528:10 | b | +| array_flow.rb:525:9:527:7 | call to find : | array_flow.rb:525:5:525:5 | b : | +| array_flow.rb:525:9:527:7 | call to find : | array_flow.rb:525:5:525:5 | b : | | array_flow.rb:525:21:525:32 | call to source : | array_flow.rb:525:9:527:7 | call to find : | | array_flow.rb:525:21:525:32 | call to source : | array_flow.rb:525:9:527:7 | call to find : | | array_flow.rb:525:41:525:41 | x : | array_flow.rb:526:14:526:14 | x | | array_flow.rb:525:41:525:41 | x : | array_flow.rb:526:14:526:14 | x | -| array_flow.rb:532:19:532:28 | call to source : | array_flow.rb:533:9:533:9 | a [element 3] : | -| array_flow.rb:532:19:532:28 | call to source : | array_flow.rb:533:9:533:9 | a [element 3] : | +| array_flow.rb:532:5:532:5 | a [element 3] : | array_flow.rb:533:9:533:9 | a [element 3] : | +| array_flow.rb:532:5:532:5 | a [element 3] : | array_flow.rb:533:9:533:9 | a [element 3] : | +| array_flow.rb:532:19:532:28 | call to source : | array_flow.rb:532:5:532:5 | a [element 3] : | +| array_flow.rb:532:19:532:28 | call to source : | array_flow.rb:532:5:532:5 | a [element 3] : | +| array_flow.rb:533:5:533:5 | b [element] : | array_flow.rb:536:10:536:10 | b [element] : | +| array_flow.rb:533:5:533:5 | b [element] : | array_flow.rb:536:10:536:10 | b [element] : | | array_flow.rb:533:9:533:9 | a [element 3] : | array_flow.rb:533:9:535:7 | call to find_all [element] : | | array_flow.rb:533:9:533:9 | a [element 3] : | array_flow.rb:533:9:535:7 | call to find_all [element] : | | array_flow.rb:533:9:533:9 | a [element 3] : | array_flow.rb:533:24:533:24 | x : | | array_flow.rb:533:9:533:9 | a [element 3] : | array_flow.rb:533:24:533:24 | x : | -| array_flow.rb:533:9:535:7 | call to find_all [element] : | array_flow.rb:536:10:536:10 | b [element] : | -| array_flow.rb:533:9:535:7 | call to find_all [element] : | array_flow.rb:536:10:536:10 | b [element] : | +| array_flow.rb:533:9:535:7 | call to find_all [element] : | array_flow.rb:533:5:533:5 | b [element] : | +| array_flow.rb:533:9:535:7 | call to find_all [element] : | array_flow.rb:533:5:533:5 | b [element] : | | array_flow.rb:533:24:533:24 | x : | array_flow.rb:534:14:534:14 | x | | array_flow.rb:533:24:533:24 | x : | array_flow.rb:534:14:534:14 | x | | array_flow.rb:536:10:536:10 | b [element] : | array_flow.rb:536:10:536:13 | ...[...] | | array_flow.rb:536:10:536:10 | b [element] : | array_flow.rb:536:10:536:13 | ...[...] | -| array_flow.rb:540:19:540:28 | call to source : | array_flow.rb:541:5:541:5 | a [element 3] : | -| array_flow.rb:540:19:540:28 | call to source : | array_flow.rb:541:5:541:5 | a [element 3] : | +| array_flow.rb:540:5:540:5 | a [element 3] : | array_flow.rb:541:5:541:5 | a [element 3] : | +| array_flow.rb:540:5:540:5 | a [element 3] : | array_flow.rb:541:5:541:5 | a [element 3] : | +| array_flow.rb:540:19:540:28 | call to source : | array_flow.rb:540:5:540:5 | a [element 3] : | +| array_flow.rb:540:19:540:28 | call to source : | array_flow.rb:540:5:540:5 | a [element 3] : | | array_flow.rb:541:5:541:5 | a [element 3] : | array_flow.rb:541:22:541:22 | x : | | array_flow.rb:541:5:541:5 | a [element 3] : | array_flow.rb:541:22:541:22 | x : | | array_flow.rb:541:22:541:22 | x : | array_flow.rb:542:14:542:14 | x | | array_flow.rb:541:22:541:22 | x : | array_flow.rb:542:14:542:14 | x | -| array_flow.rb:547:10:547:21 | call to source : | array_flow.rb:549:10:549:10 | a [element 0] : | -| array_flow.rb:547:10:547:21 | call to source : | array_flow.rb:549:10:549:10 | a [element 0] : | -| array_flow.rb:547:10:547:21 | call to source : | array_flow.rb:550:9:550:9 | a [element 0] : | -| array_flow.rb:547:10:547:21 | call to source : | array_flow.rb:550:9:550:9 | a [element 0] : | -| array_flow.rb:547:10:547:21 | call to source : | array_flow.rb:553:9:553:9 | a [element 0] : | -| array_flow.rb:547:10:547:21 | call to source : | array_flow.rb:553:9:553:9 | a [element 0] : | -| array_flow.rb:547:30:547:41 | call to source : | array_flow.rb:553:9:553:9 | a [element 3] : | -| array_flow.rb:547:30:547:41 | call to source : | array_flow.rb:553:9:553:9 | a [element 3] : | +| array_flow.rb:547:5:547:5 | a [element 0] : | array_flow.rb:549:10:549:10 | a [element 0] : | +| array_flow.rb:547:5:547:5 | a [element 0] : | array_flow.rb:549:10:549:10 | a [element 0] : | +| array_flow.rb:547:5:547:5 | a [element 0] : | array_flow.rb:550:9:550:9 | a [element 0] : | +| array_flow.rb:547:5:547:5 | a [element 0] : | array_flow.rb:550:9:550:9 | a [element 0] : | +| array_flow.rb:547:5:547:5 | a [element 0] : | array_flow.rb:553:9:553:9 | a [element 0] : | +| array_flow.rb:547:5:547:5 | a [element 0] : | array_flow.rb:553:9:553:9 | a [element 0] : | +| array_flow.rb:547:5:547:5 | a [element 3] : | array_flow.rb:553:9:553:9 | a [element 3] : | +| array_flow.rb:547:5:547:5 | a [element 3] : | array_flow.rb:553:9:553:9 | a [element 3] : | +| array_flow.rb:547:10:547:21 | call to source : | array_flow.rb:547:5:547:5 | a [element 0] : | +| array_flow.rb:547:10:547:21 | call to source : | array_flow.rb:547:5:547:5 | a [element 0] : | +| array_flow.rb:547:30:547:41 | call to source : | array_flow.rb:547:5:547:5 | a [element 3] : | +| array_flow.rb:547:30:547:41 | call to source : | array_flow.rb:547:5:547:5 | a [element 3] : | | array_flow.rb:548:5:548:5 | [post] a [element] : | array_flow.rb:549:10:549:10 | a [element] : | | array_flow.rb:548:5:548:5 | [post] a [element] : | array_flow.rb:549:10:549:10 | a [element] : | | array_flow.rb:548:5:548:5 | [post] a [element] : | array_flow.rb:550:9:550:9 | a [element] : | @@ -960,36 +1223,46 @@ edges | array_flow.rb:549:10:549:10 | a [element 0] : | array_flow.rb:549:10:549:16 | call to first | | array_flow.rb:549:10:549:10 | a [element] : | array_flow.rb:549:10:549:16 | call to first | | array_flow.rb:549:10:549:10 | a [element] : | array_flow.rb:549:10:549:16 | call to first | +| array_flow.rb:550:5:550:5 | b [element 0] : | array_flow.rb:551:10:551:10 | b [element 0] : | +| array_flow.rb:550:5:550:5 | b [element 0] : | array_flow.rb:551:10:551:10 | b [element 0] : | +| array_flow.rb:550:5:550:5 | b [element] : | array_flow.rb:551:10:551:10 | b [element] : | +| array_flow.rb:550:5:550:5 | b [element] : | array_flow.rb:551:10:551:10 | b [element] : | +| array_flow.rb:550:5:550:5 | b [element] : | array_flow.rb:552:10:552:10 | b [element] : | +| array_flow.rb:550:5:550:5 | b [element] : | array_flow.rb:552:10:552:10 | b [element] : | | array_flow.rb:550:9:550:9 | a [element 0] : | array_flow.rb:550:9:550:18 | call to first [element 0] : | | array_flow.rb:550:9:550:9 | a [element 0] : | array_flow.rb:550:9:550:18 | call to first [element 0] : | | array_flow.rb:550:9:550:9 | a [element] : | array_flow.rb:550:9:550:18 | call to first [element] : | | array_flow.rb:550:9:550:9 | a [element] : | array_flow.rb:550:9:550:18 | call to first [element] : | -| array_flow.rb:550:9:550:18 | call to first [element 0] : | array_flow.rb:551:10:551:10 | b [element 0] : | -| array_flow.rb:550:9:550:18 | call to first [element 0] : | array_flow.rb:551:10:551:10 | b [element 0] : | -| array_flow.rb:550:9:550:18 | call to first [element] : | array_flow.rb:551:10:551:10 | b [element] : | -| array_flow.rb:550:9:550:18 | call to first [element] : | array_flow.rb:551:10:551:10 | b [element] : | -| array_flow.rb:550:9:550:18 | call to first [element] : | array_flow.rb:552:10:552:10 | b [element] : | -| array_flow.rb:550:9:550:18 | call to first [element] : | array_flow.rb:552:10:552:10 | b [element] : | +| array_flow.rb:550:9:550:18 | call to first [element 0] : | array_flow.rb:550:5:550:5 | b [element 0] : | +| array_flow.rb:550:9:550:18 | call to first [element 0] : | array_flow.rb:550:5:550:5 | b [element 0] : | +| array_flow.rb:550:9:550:18 | call to first [element] : | array_flow.rb:550:5:550:5 | b [element] : | +| array_flow.rb:550:9:550:18 | call to first [element] : | array_flow.rb:550:5:550:5 | b [element] : | | array_flow.rb:551:10:551:10 | b [element 0] : | array_flow.rb:551:10:551:13 | ...[...] | | array_flow.rb:551:10:551:10 | b [element 0] : | array_flow.rb:551:10:551:13 | ...[...] | | array_flow.rb:551:10:551:10 | b [element] : | array_flow.rb:551:10:551:13 | ...[...] | | array_flow.rb:551:10:551:10 | b [element] : | array_flow.rb:551:10:551:13 | ...[...] | | array_flow.rb:552:10:552:10 | b [element] : | array_flow.rb:552:10:552:13 | ...[...] | | array_flow.rb:552:10:552:10 | b [element] : | array_flow.rb:552:10:552:13 | ...[...] | +| array_flow.rb:553:5:553:5 | c [element 0] : | array_flow.rb:554:10:554:10 | c [element 0] : | +| array_flow.rb:553:5:553:5 | c [element 0] : | array_flow.rb:554:10:554:10 | c [element 0] : | +| array_flow.rb:553:5:553:5 | c [element 3] : | array_flow.rb:555:10:555:10 | c [element 3] : | +| array_flow.rb:553:5:553:5 | c [element 3] : | array_flow.rb:555:10:555:10 | c [element 3] : | +| array_flow.rb:553:5:553:5 | c [element] : | array_flow.rb:554:10:554:10 | c [element] : | +| array_flow.rb:553:5:553:5 | c [element] : | array_flow.rb:554:10:554:10 | c [element] : | +| array_flow.rb:553:5:553:5 | c [element] : | array_flow.rb:555:10:555:10 | c [element] : | +| array_flow.rb:553:5:553:5 | c [element] : | array_flow.rb:555:10:555:10 | c [element] : | | array_flow.rb:553:9:553:9 | a [element 0] : | array_flow.rb:553:9:553:18 | call to first [element 0] : | | array_flow.rb:553:9:553:9 | a [element 0] : | array_flow.rb:553:9:553:18 | call to first [element 0] : | | array_flow.rb:553:9:553:9 | a [element 3] : | array_flow.rb:553:9:553:18 | call to first [element 3] : | | array_flow.rb:553:9:553:9 | a [element 3] : | array_flow.rb:553:9:553:18 | call to first [element 3] : | | array_flow.rb:553:9:553:9 | a [element] : | array_flow.rb:553:9:553:18 | call to first [element] : | | array_flow.rb:553:9:553:9 | a [element] : | array_flow.rb:553:9:553:18 | call to first [element] : | -| array_flow.rb:553:9:553:18 | call to first [element 0] : | array_flow.rb:554:10:554:10 | c [element 0] : | -| array_flow.rb:553:9:553:18 | call to first [element 0] : | array_flow.rb:554:10:554:10 | c [element 0] : | -| array_flow.rb:553:9:553:18 | call to first [element 3] : | array_flow.rb:555:10:555:10 | c [element 3] : | -| array_flow.rb:553:9:553:18 | call to first [element 3] : | array_flow.rb:555:10:555:10 | c [element 3] : | -| array_flow.rb:553:9:553:18 | call to first [element] : | array_flow.rb:554:10:554:10 | c [element] : | -| array_flow.rb:553:9:553:18 | call to first [element] : | array_flow.rb:554:10:554:10 | c [element] : | -| array_flow.rb:553:9:553:18 | call to first [element] : | array_flow.rb:555:10:555:10 | c [element] : | -| array_flow.rb:553:9:553:18 | call to first [element] : | array_flow.rb:555:10:555:10 | c [element] : | +| array_flow.rb:553:9:553:18 | call to first [element 0] : | array_flow.rb:553:5:553:5 | c [element 0] : | +| array_flow.rb:553:9:553:18 | call to first [element 0] : | array_flow.rb:553:5:553:5 | c [element 0] : | +| array_flow.rb:553:9:553:18 | call to first [element 3] : | array_flow.rb:553:5:553:5 | c [element 3] : | +| array_flow.rb:553:9:553:18 | call to first [element 3] : | array_flow.rb:553:5:553:5 | c [element 3] : | +| array_flow.rb:553:9:553:18 | call to first [element] : | array_flow.rb:553:5:553:5 | c [element] : | +| array_flow.rb:553:9:553:18 | call to first [element] : | array_flow.rb:553:5:553:5 | c [element] : | | array_flow.rb:554:10:554:10 | c [element 0] : | array_flow.rb:554:10:554:13 | ...[...] | | array_flow.rb:554:10:554:10 | c [element 0] : | array_flow.rb:554:10:554:13 | ...[...] | | array_flow.rb:554:10:554:10 | c [element] : | array_flow.rb:554:10:554:13 | ...[...] | @@ -998,48 +1271,65 @@ edges | array_flow.rb:555:10:555:10 | c [element 3] : | array_flow.rb:555:10:555:13 | ...[...] | | array_flow.rb:555:10:555:10 | c [element] : | array_flow.rb:555:10:555:13 | ...[...] | | array_flow.rb:555:10:555:10 | c [element] : | array_flow.rb:555:10:555:13 | ...[...] | -| array_flow.rb:559:16:559:27 | call to source : | array_flow.rb:560:9:560:9 | a [element 2] : | -| array_flow.rb:559:16:559:27 | call to source : | array_flow.rb:560:9:560:9 | a [element 2] : | -| array_flow.rb:559:16:559:27 | call to source : | array_flow.rb:565:9:565:9 | a [element 2] : | -| array_flow.rb:559:16:559:27 | call to source : | array_flow.rb:565:9:565:9 | a [element 2] : | +| array_flow.rb:559:5:559:5 | a [element 2] : | array_flow.rb:560:9:560:9 | a [element 2] : | +| array_flow.rb:559:5:559:5 | a [element 2] : | array_flow.rb:560:9:560:9 | a [element 2] : | +| array_flow.rb:559:5:559:5 | a [element 2] : | array_flow.rb:565:9:565:9 | a [element 2] : | +| array_flow.rb:559:5:559:5 | a [element 2] : | array_flow.rb:565:9:565:9 | a [element 2] : | +| array_flow.rb:559:16:559:27 | call to source : | array_flow.rb:559:5:559:5 | a [element 2] : | +| array_flow.rb:559:16:559:27 | call to source : | array_flow.rb:559:5:559:5 | a [element 2] : | +| array_flow.rb:560:5:560:5 | b [element] : | array_flow.rb:564:10:564:10 | b [element] : | +| array_flow.rb:560:5:560:5 | b [element] : | array_flow.rb:564:10:564:10 | b [element] : | | array_flow.rb:560:9:560:9 | a [element 2] : | array_flow.rb:560:9:563:7 | call to flat_map [element] : | | array_flow.rb:560:9:560:9 | a [element 2] : | array_flow.rb:560:9:563:7 | call to flat_map [element] : | | array_flow.rb:560:9:560:9 | a [element 2] : | array_flow.rb:560:24:560:24 | x : | | array_flow.rb:560:9:560:9 | a [element 2] : | array_flow.rb:560:24:560:24 | x : | -| array_flow.rb:560:9:563:7 | call to flat_map [element] : | array_flow.rb:564:10:564:10 | b [element] : | -| array_flow.rb:560:9:563:7 | call to flat_map [element] : | array_flow.rb:564:10:564:10 | b [element] : | +| array_flow.rb:560:9:563:7 | call to flat_map [element] : | array_flow.rb:560:5:560:5 | b [element] : | +| array_flow.rb:560:9:563:7 | call to flat_map [element] : | array_flow.rb:560:5:560:5 | b [element] : | | array_flow.rb:560:24:560:24 | x : | array_flow.rb:561:14:561:14 | x | | array_flow.rb:560:24:560:24 | x : | array_flow.rb:561:14:561:14 | x | | array_flow.rb:562:13:562:24 | call to source : | array_flow.rb:560:9:563:7 | call to flat_map [element] : | | array_flow.rb:562:13:562:24 | call to source : | array_flow.rb:560:9:563:7 | call to flat_map [element] : | | array_flow.rb:564:10:564:10 | b [element] : | array_flow.rb:564:10:564:13 | ...[...] | | array_flow.rb:564:10:564:10 | b [element] : | array_flow.rb:564:10:564:13 | ...[...] | +| array_flow.rb:565:5:565:5 | b [element] : | array_flow.rb:569:10:569:10 | b [element] : | +| array_flow.rb:565:5:565:5 | b [element] : | array_flow.rb:569:10:569:10 | b [element] : | | array_flow.rb:565:9:565:9 | a [element 2] : | array_flow.rb:565:24:565:24 | x : | | array_flow.rb:565:9:565:9 | a [element 2] : | array_flow.rb:565:24:565:24 | x : | -| array_flow.rb:565:9:568:7 | call to flat_map [element] : | array_flow.rb:569:10:569:10 | b [element] : | -| array_flow.rb:565:9:568:7 | call to flat_map [element] : | array_flow.rb:569:10:569:10 | b [element] : | +| array_flow.rb:565:9:568:7 | call to flat_map [element] : | array_flow.rb:565:5:565:5 | b [element] : | +| array_flow.rb:565:9:568:7 | call to flat_map [element] : | array_flow.rb:565:5:565:5 | b [element] : | | array_flow.rb:565:24:565:24 | x : | array_flow.rb:566:14:566:14 | x | | array_flow.rb:565:24:565:24 | x : | array_flow.rb:566:14:566:14 | x | | array_flow.rb:567:9:567:20 | call to source : | array_flow.rb:565:9:568:7 | call to flat_map [element] : | | array_flow.rb:567:9:567:20 | call to source : | array_flow.rb:565:9:568:7 | call to flat_map [element] : | | array_flow.rb:569:10:569:10 | b [element] : | array_flow.rb:569:10:569:13 | ...[...] | | array_flow.rb:569:10:569:10 | b [element] : | array_flow.rb:569:10:569:13 | ...[...] | -| array_flow.rb:573:20:573:29 | call to source : | array_flow.rb:574:9:574:9 | a [element 2, element 1] : | -| array_flow.rb:573:20:573:29 | call to source : | array_flow.rb:574:9:574:9 | a [element 2, element 1] : | +| array_flow.rb:573:5:573:5 | a [element 2, element 1] : | array_flow.rb:574:9:574:9 | a [element 2, element 1] : | +| array_flow.rb:573:5:573:5 | a [element 2, element 1] : | array_flow.rb:574:9:574:9 | a [element 2, element 1] : | +| array_flow.rb:573:20:573:29 | call to source : | array_flow.rb:573:5:573:5 | a [element 2, element 1] : | +| array_flow.rb:573:20:573:29 | call to source : | array_flow.rb:573:5:573:5 | a [element 2, element 1] : | +| array_flow.rb:574:5:574:5 | b [element] : | array_flow.rb:575:10:575:10 | b [element] : | +| array_flow.rb:574:5:574:5 | b [element] : | array_flow.rb:575:10:575:10 | b [element] : | | array_flow.rb:574:9:574:9 | a [element 2, element 1] : | array_flow.rb:574:9:574:17 | call to flatten [element] : | | array_flow.rb:574:9:574:9 | a [element 2, element 1] : | array_flow.rb:574:9:574:17 | call to flatten [element] : | -| array_flow.rb:574:9:574:17 | call to flatten [element] : | array_flow.rb:575:10:575:10 | b [element] : | -| array_flow.rb:574:9:574:17 | call to flatten [element] : | array_flow.rb:575:10:575:10 | b [element] : | +| array_flow.rb:574:9:574:17 | call to flatten [element] : | array_flow.rb:574:5:574:5 | b [element] : | +| array_flow.rb:574:9:574:17 | call to flatten [element] : | array_flow.rb:574:5:574:5 | b [element] : | | array_flow.rb:575:10:575:10 | b [element] : | array_flow.rb:575:10:575:13 | ...[...] | | array_flow.rb:575:10:575:10 | b [element] : | array_flow.rb:575:10:575:13 | ...[...] | -| array_flow.rb:579:20:579:29 | call to source : | array_flow.rb:580:10:580:10 | a [element 2, element 1] : | -| array_flow.rb:579:20:579:29 | call to source : | array_flow.rb:580:10:580:10 | a [element 2, element 1] : | -| array_flow.rb:579:20:579:29 | call to source : | array_flow.rb:581:9:581:9 | a [element 2, element 1] : | -| array_flow.rb:579:20:579:29 | call to source : | array_flow.rb:581:9:581:9 | a [element 2, element 1] : | +| array_flow.rb:579:5:579:5 | a [element 2, element 1] : | array_flow.rb:580:10:580:10 | a [element 2, element 1] : | +| array_flow.rb:579:5:579:5 | a [element 2, element 1] : | array_flow.rb:580:10:580:10 | a [element 2, element 1] : | +| array_flow.rb:579:5:579:5 | a [element 2, element 1] : | array_flow.rb:581:9:581:9 | a [element 2, element 1] : | +| array_flow.rb:579:5:579:5 | a [element 2, element 1] : | array_flow.rb:581:9:581:9 | a [element 2, element 1] : | +| array_flow.rb:579:20:579:29 | call to source : | array_flow.rb:579:5:579:5 | a [element 2, element 1] : | +| array_flow.rb:579:20:579:29 | call to source : | array_flow.rb:579:5:579:5 | a [element 2, element 1] : | | array_flow.rb:580:10:580:10 | a [element 2, element 1] : | array_flow.rb:580:10:580:13 | ...[...] [element 1] : | | array_flow.rb:580:10:580:10 | a [element 2, element 1] : | array_flow.rb:580:10:580:13 | ...[...] [element 1] : | | array_flow.rb:580:10:580:13 | ...[...] [element 1] : | array_flow.rb:580:10:580:16 | ...[...] | | array_flow.rb:580:10:580:13 | ...[...] [element 1] : | array_flow.rb:580:10:580:16 | ...[...] | +| array_flow.rb:581:5:581:5 | b [element, element 1] : | array_flow.rb:585:10:585:10 | b [element, element 1] : | +| array_flow.rb:581:5:581:5 | b [element, element 1] : | array_flow.rb:585:10:585:10 | b [element, element 1] : | +| array_flow.rb:581:5:581:5 | b [element] : | array_flow.rb:584:10:584:10 | b [element] : | +| array_flow.rb:581:5:581:5 | b [element] : | array_flow.rb:584:10:584:10 | b [element] : | +| array_flow.rb:581:5:581:5 | b [element] : | array_flow.rb:585:10:585:10 | b [element] : | | array_flow.rb:581:9:581:9 | [post] a [element, element 1] : | array_flow.rb:583:10:583:10 | a [element, element 1] : | | array_flow.rb:581:9:581:9 | [post] a [element, element 1] : | array_flow.rb:583:10:583:10 | a [element, element 1] : | | array_flow.rb:581:9:581:9 | [post] a [element] : | array_flow.rb:582:10:582:10 | a [element] : | @@ -1053,11 +1343,10 @@ edges | array_flow.rb:581:9:581:9 | a [element 2, element 1] : | array_flow.rb:581:9:581:18 | call to flatten! [element, element 1] : | | array_flow.rb:581:9:581:9 | a [element 2, element 1] : | array_flow.rb:581:9:581:18 | call to flatten! [element] : | | array_flow.rb:581:9:581:9 | a [element 2, element 1] : | array_flow.rb:581:9:581:18 | call to flatten! [element] : | -| array_flow.rb:581:9:581:18 | call to flatten! [element, element 1] : | array_flow.rb:585:10:585:10 | b [element, element 1] : | -| array_flow.rb:581:9:581:18 | call to flatten! [element, element 1] : | array_flow.rb:585:10:585:10 | b [element, element 1] : | -| array_flow.rb:581:9:581:18 | call to flatten! [element] : | array_flow.rb:584:10:584:10 | b [element] : | -| array_flow.rb:581:9:581:18 | call to flatten! [element] : | array_flow.rb:584:10:584:10 | b [element] : | -| array_flow.rb:581:9:581:18 | call to flatten! [element] : | array_flow.rb:585:10:585:10 | b [element] : | +| array_flow.rb:581:9:581:18 | call to flatten! [element, element 1] : | array_flow.rb:581:5:581:5 | b [element, element 1] : | +| array_flow.rb:581:9:581:18 | call to flatten! [element, element 1] : | array_flow.rb:581:5:581:5 | b [element, element 1] : | +| array_flow.rb:581:9:581:18 | call to flatten! [element] : | array_flow.rb:581:5:581:5 | b [element] : | +| array_flow.rb:581:9:581:18 | call to flatten! [element] : | array_flow.rb:581:5:581:5 | b [element] : | | array_flow.rb:582:10:582:10 | a [element] : | array_flow.rb:582:10:582:13 | ...[...] | | array_flow.rb:582:10:582:10 | a [element] : | array_flow.rb:582:10:582:13 | ...[...] | | array_flow.rb:583:10:583:10 | a [element, element 1] : | array_flow.rb:583:10:583:13 | ...[...] [element 1] : | @@ -1074,90 +1363,122 @@ edges | array_flow.rb:585:10:585:13 | ...[...] : | array_flow.rb:585:10:585:16 | ...[...] | | array_flow.rb:585:10:585:13 | ...[...] [element 1] : | array_flow.rb:585:10:585:16 | ...[...] | | array_flow.rb:585:10:585:13 | ...[...] [element 1] : | array_flow.rb:585:10:585:16 | ...[...] | -| array_flow.rb:589:19:589:30 | call to source : | array_flow.rb:590:9:590:9 | a [element 3] : | -| array_flow.rb:589:19:589:30 | call to source : | array_flow.rb:590:9:590:9 | a [element 3] : | -| array_flow.rb:589:19:589:30 | call to source : | array_flow.rb:592:9:592:9 | a [element 3] : | -| array_flow.rb:589:19:589:30 | call to source : | array_flow.rb:592:9:592:9 | a [element 3] : | +| array_flow.rb:589:5:589:5 | a [element 3] : | array_flow.rb:590:9:590:9 | a [element 3] : | +| array_flow.rb:589:5:589:5 | a [element 3] : | array_flow.rb:590:9:590:9 | a [element 3] : | +| array_flow.rb:589:5:589:5 | a [element 3] : | array_flow.rb:592:9:592:9 | a [element 3] : | +| array_flow.rb:589:5:589:5 | a [element 3] : | array_flow.rb:592:9:592:9 | a [element 3] : | +| array_flow.rb:589:19:589:30 | call to source : | array_flow.rb:589:5:589:5 | a [element 3] : | +| array_flow.rb:589:19:589:30 | call to source : | array_flow.rb:589:5:589:5 | a [element 3] : | +| array_flow.rb:590:5:590:5 | b [element] : | array_flow.rb:591:10:591:10 | b [element] : | +| array_flow.rb:590:5:590:5 | b [element] : | array_flow.rb:591:10:591:10 | b [element] : | | array_flow.rb:590:9:590:9 | a [element 3] : | array_flow.rb:590:9:590:20 | call to grep [element] : | | array_flow.rb:590:9:590:9 | a [element 3] : | array_flow.rb:590:9:590:20 | call to grep [element] : | -| array_flow.rb:590:9:590:20 | call to grep [element] : | array_flow.rb:591:10:591:10 | b [element] : | -| array_flow.rb:590:9:590:20 | call to grep [element] : | array_flow.rb:591:10:591:10 | b [element] : | +| array_flow.rb:590:9:590:20 | call to grep [element] : | array_flow.rb:590:5:590:5 | b [element] : | +| array_flow.rb:590:9:590:20 | call to grep [element] : | array_flow.rb:590:5:590:5 | b [element] : | | array_flow.rb:591:10:591:10 | b [element] : | array_flow.rb:591:10:591:13 | ...[...] | | array_flow.rb:591:10:591:10 | b [element] : | array_flow.rb:591:10:591:13 | ...[...] | +| array_flow.rb:592:5:592:5 | b [element] : | array_flow.rb:596:10:596:10 | b [element] : | +| array_flow.rb:592:5:592:5 | b [element] : | array_flow.rb:596:10:596:10 | b [element] : | | array_flow.rb:592:9:592:9 | a [element 3] : | array_flow.rb:592:26:592:26 | x : | | array_flow.rb:592:9:592:9 | a [element 3] : | array_flow.rb:592:26:592:26 | x : | -| array_flow.rb:592:9:595:7 | call to grep [element] : | array_flow.rb:596:10:596:10 | b [element] : | -| array_flow.rb:592:9:595:7 | call to grep [element] : | array_flow.rb:596:10:596:10 | b [element] : | +| array_flow.rb:592:9:595:7 | call to grep [element] : | array_flow.rb:592:5:592:5 | b [element] : | +| array_flow.rb:592:9:595:7 | call to grep [element] : | array_flow.rb:592:5:592:5 | b [element] : | | array_flow.rb:592:26:592:26 | x : | array_flow.rb:593:14:593:14 | x | | array_flow.rb:592:26:592:26 | x : | array_flow.rb:593:14:593:14 | x | | array_flow.rb:594:9:594:20 | call to source : | array_flow.rb:592:9:595:7 | call to grep [element] : | | array_flow.rb:594:9:594:20 | call to source : | array_flow.rb:592:9:595:7 | call to grep [element] : | | array_flow.rb:596:10:596:10 | b [element] : | array_flow.rb:596:10:596:13 | ...[...] | | array_flow.rb:596:10:596:10 | b [element] : | array_flow.rb:596:10:596:13 | ...[...] | -| array_flow.rb:600:19:600:30 | call to source : | array_flow.rb:601:9:601:9 | a [element 3] : | -| array_flow.rb:600:19:600:30 | call to source : | array_flow.rb:601:9:601:9 | a [element 3] : | -| array_flow.rb:600:19:600:30 | call to source : | array_flow.rb:603:9:603:9 | a [element 3] : | -| array_flow.rb:600:19:600:30 | call to source : | array_flow.rb:603:9:603:9 | a [element 3] : | +| array_flow.rb:600:5:600:5 | a [element 3] : | array_flow.rb:601:9:601:9 | a [element 3] : | +| array_flow.rb:600:5:600:5 | a [element 3] : | array_flow.rb:601:9:601:9 | a [element 3] : | +| array_flow.rb:600:5:600:5 | a [element 3] : | array_flow.rb:603:9:603:9 | a [element 3] : | +| array_flow.rb:600:5:600:5 | a [element 3] : | array_flow.rb:603:9:603:9 | a [element 3] : | +| array_flow.rb:600:19:600:30 | call to source : | array_flow.rb:600:5:600:5 | a [element 3] : | +| array_flow.rb:600:19:600:30 | call to source : | array_flow.rb:600:5:600:5 | a [element 3] : | +| array_flow.rb:601:5:601:5 | b [element] : | array_flow.rb:602:10:602:10 | b [element] : | +| array_flow.rb:601:5:601:5 | b [element] : | array_flow.rb:602:10:602:10 | b [element] : | | array_flow.rb:601:9:601:9 | a [element 3] : | array_flow.rb:601:9:601:21 | call to grep_v [element] : | | array_flow.rb:601:9:601:9 | a [element 3] : | array_flow.rb:601:9:601:21 | call to grep_v [element] : | -| array_flow.rb:601:9:601:21 | call to grep_v [element] : | array_flow.rb:602:10:602:10 | b [element] : | -| array_flow.rb:601:9:601:21 | call to grep_v [element] : | array_flow.rb:602:10:602:10 | b [element] : | +| array_flow.rb:601:9:601:21 | call to grep_v [element] : | array_flow.rb:601:5:601:5 | b [element] : | +| array_flow.rb:601:9:601:21 | call to grep_v [element] : | array_flow.rb:601:5:601:5 | b [element] : | | array_flow.rb:602:10:602:10 | b [element] : | array_flow.rb:602:10:602:13 | ...[...] | | array_flow.rb:602:10:602:10 | b [element] : | array_flow.rb:602:10:602:13 | ...[...] | +| array_flow.rb:603:5:603:5 | b [element] : | array_flow.rb:607:10:607:10 | b [element] : | +| array_flow.rb:603:5:603:5 | b [element] : | array_flow.rb:607:10:607:10 | b [element] : | | array_flow.rb:603:9:603:9 | a [element 3] : | array_flow.rb:603:27:603:27 | x : | | array_flow.rb:603:9:603:9 | a [element 3] : | array_flow.rb:603:27:603:27 | x : | -| array_flow.rb:603:9:606:7 | call to grep_v [element] : | array_flow.rb:607:10:607:10 | b [element] : | -| array_flow.rb:603:9:606:7 | call to grep_v [element] : | array_flow.rb:607:10:607:10 | b [element] : | +| array_flow.rb:603:9:606:7 | call to grep_v [element] : | array_flow.rb:603:5:603:5 | b [element] : | +| array_flow.rb:603:9:606:7 | call to grep_v [element] : | array_flow.rb:603:5:603:5 | b [element] : | | array_flow.rb:603:27:603:27 | x : | array_flow.rb:604:14:604:14 | x | | array_flow.rb:603:27:603:27 | x : | array_flow.rb:604:14:604:14 | x | | array_flow.rb:605:9:605:20 | call to source : | array_flow.rb:603:9:606:7 | call to grep_v [element] : | | array_flow.rb:605:9:605:20 | call to source : | array_flow.rb:603:9:606:7 | call to grep_v [element] : | | array_flow.rb:607:10:607:10 | b [element] : | array_flow.rb:607:10:607:13 | ...[...] | | array_flow.rb:607:10:607:10 | b [element] : | array_flow.rb:607:10:607:13 | ...[...] | -| array_flow.rb:611:19:611:30 | call to source : | array_flow.rb:612:9:612:9 | a [element 3] : | -| array_flow.rb:611:19:611:30 | call to source : | array_flow.rb:612:9:612:9 | a [element 3] : | +| array_flow.rb:611:5:611:5 | a [element 3] : | array_flow.rb:612:9:612:9 | a [element 3] : | +| array_flow.rb:611:5:611:5 | a [element 3] : | array_flow.rb:612:9:612:9 | a [element 3] : | +| array_flow.rb:611:19:611:30 | call to source : | array_flow.rb:611:5:611:5 | a [element 3] : | +| array_flow.rb:611:19:611:30 | call to source : | array_flow.rb:611:5:611:5 | a [element 3] : | | array_flow.rb:612:9:612:9 | a [element 3] : | array_flow.rb:612:24:612:24 | x : | | array_flow.rb:612:9:612:9 | a [element 3] : | array_flow.rb:612:24:612:24 | x : | | array_flow.rb:612:24:612:24 | x : | array_flow.rb:613:14:613:14 | x | | array_flow.rb:612:24:612:24 | x : | array_flow.rb:613:14:613:14 | x | -| array_flow.rb:620:19:620:28 | call to source : | array_flow.rb:621:5:621:5 | a [element 3] : | -| array_flow.rb:620:19:620:28 | call to source : | array_flow.rb:621:5:621:5 | a [element 3] : | +| array_flow.rb:620:5:620:5 | a [element 3] : | array_flow.rb:621:5:621:5 | a [element 3] : | +| array_flow.rb:620:5:620:5 | a [element 3] : | array_flow.rb:621:5:621:5 | a [element 3] : | +| array_flow.rb:620:19:620:28 | call to source : | array_flow.rb:620:5:620:5 | a [element 3] : | +| array_flow.rb:620:19:620:28 | call to source : | array_flow.rb:620:5:620:5 | a [element 3] : | | array_flow.rb:621:5:621:5 | a [element 3] : | array_flow.rb:621:17:621:17 | x : | | array_flow.rb:621:5:621:5 | a [element 3] : | array_flow.rb:621:17:621:17 | x : | | array_flow.rb:621:17:621:17 | x : | array_flow.rb:622:14:622:14 | x | | array_flow.rb:621:17:621:17 | x : | array_flow.rb:622:14:622:14 | x | -| array_flow.rb:627:10:627:21 | call to source : | array_flow.rb:628:9:628:9 | a [element 0] : | -| array_flow.rb:627:10:627:21 | call to source : | array_flow.rb:628:9:628:9 | a [element 0] : | -| array_flow.rb:627:10:627:21 | call to source : | array_flow.rb:634:9:634:9 | a [element 0] : | -| array_flow.rb:627:10:627:21 | call to source : | array_flow.rb:634:9:634:9 | a [element 0] : | -| array_flow.rb:627:27:627:38 | call to source : | array_flow.rb:628:9:628:9 | a [element 2] : | -| array_flow.rb:627:27:627:38 | call to source : | array_flow.rb:628:9:628:9 | a [element 2] : | -| array_flow.rb:627:27:627:38 | call to source : | array_flow.rb:634:9:634:9 | a [element 2] : | -| array_flow.rb:627:27:627:38 | call to source : | array_flow.rb:634:9:634:9 | a [element 2] : | +| array_flow.rb:627:5:627:5 | a [element 0] : | array_flow.rb:628:9:628:9 | a [element 0] : | +| array_flow.rb:627:5:627:5 | a [element 0] : | array_flow.rb:628:9:628:9 | a [element 0] : | +| array_flow.rb:627:5:627:5 | a [element 0] : | array_flow.rb:634:9:634:9 | a [element 0] : | +| array_flow.rb:627:5:627:5 | a [element 0] : | array_flow.rb:634:9:634:9 | a [element 0] : | +| array_flow.rb:627:5:627:5 | a [element 2] : | array_flow.rb:628:9:628:9 | a [element 2] : | +| array_flow.rb:627:5:627:5 | a [element 2] : | array_flow.rb:628:9:628:9 | a [element 2] : | +| array_flow.rb:627:5:627:5 | a [element 2] : | array_flow.rb:634:9:634:9 | a [element 2] : | +| array_flow.rb:627:5:627:5 | a [element 2] : | array_flow.rb:634:9:634:9 | a [element 2] : | +| array_flow.rb:627:10:627:21 | call to source : | array_flow.rb:627:5:627:5 | a [element 0] : | +| array_flow.rb:627:10:627:21 | call to source : | array_flow.rb:627:5:627:5 | a [element 0] : | +| array_flow.rb:627:27:627:38 | call to source : | array_flow.rb:627:5:627:5 | a [element 2] : | +| array_flow.rb:627:27:627:38 | call to source : | array_flow.rb:627:5:627:5 | a [element 2] : | +| array_flow.rb:628:5:628:5 | b : | array_flow.rb:633:10:633:10 | b | +| array_flow.rb:628:5:628:5 | b : | array_flow.rb:633:10:633:10 | b | | array_flow.rb:628:9:628:9 | a [element 0] : | array_flow.rb:628:22:628:22 | x : | | array_flow.rb:628:9:628:9 | a [element 0] : | array_flow.rb:628:22:628:22 | x : | | array_flow.rb:628:9:628:9 | a [element 2] : | array_flow.rb:628:25:628:25 | y : | | array_flow.rb:628:9:628:9 | a [element 2] : | array_flow.rb:628:25:628:25 | y : | -| array_flow.rb:628:9:632:7 | call to inject : | array_flow.rb:633:10:633:10 | b | -| array_flow.rb:628:9:632:7 | call to inject : | array_flow.rb:633:10:633:10 | b | +| array_flow.rb:628:9:632:7 | call to inject : | array_flow.rb:628:5:628:5 | b : | +| array_flow.rb:628:9:632:7 | call to inject : | array_flow.rb:628:5:628:5 | b : | | array_flow.rb:628:22:628:22 | x : | array_flow.rb:629:14:629:14 | x | | array_flow.rb:628:22:628:22 | x : | array_flow.rb:629:14:629:14 | x | | array_flow.rb:628:25:628:25 | y : | array_flow.rb:630:14:630:14 | y | | array_flow.rb:628:25:628:25 | y : | array_flow.rb:630:14:630:14 | y | | array_flow.rb:631:9:631:19 | call to source : | array_flow.rb:628:9:632:7 | call to inject : | | array_flow.rb:631:9:631:19 | call to source : | array_flow.rb:628:9:632:7 | call to inject : | +| array_flow.rb:634:5:634:5 | c : | array_flow.rb:639:10:639:10 | c | +| array_flow.rb:634:5:634:5 | c : | array_flow.rb:639:10:639:10 | c | | array_flow.rb:634:9:634:9 | a [element 0] : | array_flow.rb:634:28:634:28 | y : | | array_flow.rb:634:9:634:9 | a [element 0] : | array_flow.rb:634:28:634:28 | y : | | array_flow.rb:634:9:634:9 | a [element 2] : | array_flow.rb:634:28:634:28 | y : | | array_flow.rb:634:9:634:9 | a [element 2] : | array_flow.rb:634:28:634:28 | y : | -| array_flow.rb:634:9:638:7 | call to inject : | array_flow.rb:639:10:639:10 | c | -| array_flow.rb:634:9:638:7 | call to inject : | array_flow.rb:639:10:639:10 | c | +| array_flow.rb:634:9:638:7 | call to inject : | array_flow.rb:634:5:634:5 | c : | +| array_flow.rb:634:9:638:7 | call to inject : | array_flow.rb:634:5:634:5 | c : | | array_flow.rb:634:28:634:28 | y : | array_flow.rb:636:14:636:14 | y | | array_flow.rb:634:28:634:28 | y : | array_flow.rb:636:14:636:14 | y | | array_flow.rb:637:9:637:19 | call to source : | array_flow.rb:634:9:638:7 | call to inject : | | array_flow.rb:637:9:637:19 | call to source : | array_flow.rb:634:9:638:7 | call to inject : | -| array_flow.rb:644:16:644:27 | call to source : | array_flow.rb:645:9:645:9 | a [element 2] : | -| array_flow.rb:644:16:644:27 | call to source : | array_flow.rb:645:9:645:9 | a [element 2] : | +| array_flow.rb:644:5:644:5 | a [element 2] : | array_flow.rb:645:9:645:9 | a [element 2] : | +| array_flow.rb:644:5:644:5 | a [element 2] : | array_flow.rb:645:9:645:9 | a [element 2] : | +| array_flow.rb:644:16:644:27 | call to source : | array_flow.rb:644:5:644:5 | a [element 2] : | +| array_flow.rb:644:16:644:27 | call to source : | array_flow.rb:644:5:644:5 | a [element 2] : | +| array_flow.rb:645:5:645:5 | b [element 1] : | array_flow.rb:652:10:652:10 | b [element 1] : | +| array_flow.rb:645:5:645:5 | b [element 1] : | array_flow.rb:652:10:652:10 | b [element 1] : | +| array_flow.rb:645:5:645:5 | b [element 2] : | array_flow.rb:653:10:653:10 | b [element 2] : | +| array_flow.rb:645:5:645:5 | b [element 2] : | array_flow.rb:653:10:653:10 | b [element 2] : | +| array_flow.rb:645:5:645:5 | b [element 4] : | array_flow.rb:655:10:655:10 | b [element 4] : | +| array_flow.rb:645:5:645:5 | b [element 4] : | array_flow.rb:655:10:655:10 | b [element 4] : | | array_flow.rb:645:9:645:9 | [post] a [element 1] : | array_flow.rb:647:10:647:10 | a [element 1] : | | array_flow.rb:645:9:645:9 | [post] a [element 1] : | array_flow.rb:647:10:647:10 | a [element 1] : | | array_flow.rb:645:9:645:9 | [post] a [element 2] : | array_flow.rb:648:10:648:10 | a [element 2] : | @@ -1168,12 +1489,12 @@ edges | array_flow.rb:645:9:645:9 | a [element 2] : | array_flow.rb:645:9:645:9 | [post] a [element 4] : | | array_flow.rb:645:9:645:9 | a [element 2] : | array_flow.rb:645:9:645:47 | call to insert [element 4] : | | array_flow.rb:645:9:645:9 | a [element 2] : | array_flow.rb:645:9:645:47 | call to insert [element 4] : | -| array_flow.rb:645:9:645:47 | call to insert [element 1] : | array_flow.rb:652:10:652:10 | b [element 1] : | -| array_flow.rb:645:9:645:47 | call to insert [element 1] : | array_flow.rb:652:10:652:10 | b [element 1] : | -| array_flow.rb:645:9:645:47 | call to insert [element 2] : | array_flow.rb:653:10:653:10 | b [element 2] : | -| array_flow.rb:645:9:645:47 | call to insert [element 2] : | array_flow.rb:653:10:653:10 | b [element 2] : | -| array_flow.rb:645:9:645:47 | call to insert [element 4] : | array_flow.rb:655:10:655:10 | b [element 4] : | -| array_flow.rb:645:9:645:47 | call to insert [element 4] : | array_flow.rb:655:10:655:10 | b [element 4] : | +| array_flow.rb:645:9:645:47 | call to insert [element 1] : | array_flow.rb:645:5:645:5 | b [element 1] : | +| array_flow.rb:645:9:645:47 | call to insert [element 1] : | array_flow.rb:645:5:645:5 | b [element 1] : | +| array_flow.rb:645:9:645:47 | call to insert [element 2] : | array_flow.rb:645:5:645:5 | b [element 2] : | +| array_flow.rb:645:9:645:47 | call to insert [element 2] : | array_flow.rb:645:5:645:5 | b [element 2] : | +| array_flow.rb:645:9:645:47 | call to insert [element 4] : | array_flow.rb:645:5:645:5 | b [element 4] : | +| array_flow.rb:645:9:645:47 | call to insert [element 4] : | array_flow.rb:645:5:645:5 | b [element 4] : | | array_flow.rb:645:21:645:32 | call to source : | array_flow.rb:645:9:645:9 | [post] a [element 1] : | | array_flow.rb:645:21:645:32 | call to source : | array_flow.rb:645:9:645:9 | [post] a [element 1] : | | array_flow.rb:645:21:645:32 | call to source : | array_flow.rb:645:9:645:47 | call to insert [element 1] : | @@ -1194,16 +1515,20 @@ edges | array_flow.rb:653:10:653:10 | b [element 2] : | array_flow.rb:653:10:653:13 | ...[...] | | array_flow.rb:655:10:655:10 | b [element 4] : | array_flow.rb:655:10:655:13 | ...[...] | | array_flow.rb:655:10:655:10 | b [element 4] : | array_flow.rb:655:10:655:13 | ...[...] | -| array_flow.rb:658:16:658:27 | call to source : | array_flow.rb:659:9:659:9 | c [element 2] : | -| array_flow.rb:658:16:658:27 | call to source : | array_flow.rb:659:9:659:9 | c [element 2] : | +| array_flow.rb:658:5:658:5 | c [element 2] : | array_flow.rb:659:9:659:9 | c [element 2] : | +| array_flow.rb:658:5:658:5 | c [element 2] : | array_flow.rb:659:9:659:9 | c [element 2] : | +| array_flow.rb:658:16:658:27 | call to source : | array_flow.rb:658:5:658:5 | c [element 2] : | +| array_flow.rb:658:16:658:27 | call to source : | array_flow.rb:658:5:658:5 | c [element 2] : | +| array_flow.rb:659:5:659:5 | d [element] : | array_flow.rb:661:10:661:10 | d [element] : | +| array_flow.rb:659:5:659:5 | d [element] : | array_flow.rb:661:10:661:10 | d [element] : | | array_flow.rb:659:9:659:9 | [post] c [element] : | array_flow.rb:660:10:660:10 | c [element] : | | array_flow.rb:659:9:659:9 | [post] c [element] : | array_flow.rb:660:10:660:10 | c [element] : | | array_flow.rb:659:9:659:9 | c [element 2] : | array_flow.rb:659:9:659:9 | [post] c [element] : | | array_flow.rb:659:9:659:9 | c [element 2] : | array_flow.rb:659:9:659:9 | [post] c [element] : | | array_flow.rb:659:9:659:9 | c [element 2] : | array_flow.rb:659:9:659:47 | call to insert [element] : | | array_flow.rb:659:9:659:9 | c [element 2] : | array_flow.rb:659:9:659:47 | call to insert [element] : | -| array_flow.rb:659:9:659:47 | call to insert [element] : | array_flow.rb:661:10:661:10 | d [element] : | -| array_flow.rb:659:9:659:47 | call to insert [element] : | array_flow.rb:661:10:661:10 | d [element] : | +| array_flow.rb:659:9:659:47 | call to insert [element] : | array_flow.rb:659:5:659:5 | d [element] : | +| array_flow.rb:659:9:659:47 | call to insert [element] : | array_flow.rb:659:5:659:5 | d [element] : | | array_flow.rb:659:21:659:32 | call to source : | array_flow.rb:659:9:659:9 | [post] c [element] : | | array_flow.rb:659:21:659:32 | call to source : | array_flow.rb:659:9:659:9 | [post] c [element] : | | array_flow.rb:659:21:659:32 | call to source : | array_flow.rb:659:9:659:47 | call to insert [element] : | @@ -1216,20 +1541,28 @@ edges | array_flow.rb:660:10:660:10 | c [element] : | array_flow.rb:660:10:660:13 | ...[...] | | array_flow.rb:661:10:661:10 | d [element] : | array_flow.rb:661:10:661:13 | ...[...] | | array_flow.rb:661:10:661:10 | d [element] : | array_flow.rb:661:10:661:13 | ...[...] | -| array_flow.rb:672:16:672:27 | call to source : | array_flow.rb:673:9:673:9 | a [element 2] : | -| array_flow.rb:672:16:672:27 | call to source : | array_flow.rb:673:9:673:9 | a [element 2] : | +| array_flow.rb:672:5:672:5 | a [element 2] : | array_flow.rb:673:9:673:9 | a [element 2] : | +| array_flow.rb:672:5:672:5 | a [element 2] : | array_flow.rb:673:9:673:9 | a [element 2] : | +| array_flow.rb:672:16:672:27 | call to source : | array_flow.rb:672:5:672:5 | a [element 2] : | +| array_flow.rb:672:16:672:27 | call to source : | array_flow.rb:672:5:672:5 | a [element 2] : | +| array_flow.rb:673:5:673:5 | b [element] : | array_flow.rb:674:10:674:10 | b [element] : | +| array_flow.rb:673:5:673:5 | b [element] : | array_flow.rb:674:10:674:10 | b [element] : | | array_flow.rb:673:9:673:9 | a [element 2] : | array_flow.rb:673:9:673:60 | call to intersection [element] : | | array_flow.rb:673:9:673:9 | a [element 2] : | array_flow.rb:673:9:673:60 | call to intersection [element] : | -| array_flow.rb:673:9:673:60 | call to intersection [element] : | array_flow.rb:674:10:674:10 | b [element] : | -| array_flow.rb:673:9:673:60 | call to intersection [element] : | array_flow.rb:674:10:674:10 | b [element] : | +| array_flow.rb:673:9:673:60 | call to intersection [element] : | array_flow.rb:673:5:673:5 | b [element] : | +| array_flow.rb:673:9:673:60 | call to intersection [element] : | array_flow.rb:673:5:673:5 | b [element] : | | array_flow.rb:673:31:673:42 | call to source : | array_flow.rb:673:9:673:60 | call to intersection [element] : | | array_flow.rb:673:31:673:42 | call to source : | array_flow.rb:673:9:673:60 | call to intersection [element] : | | array_flow.rb:673:47:673:58 | call to source : | array_flow.rb:673:9:673:60 | call to intersection [element] : | | array_flow.rb:673:47:673:58 | call to source : | array_flow.rb:673:9:673:60 | call to intersection [element] : | | array_flow.rb:674:10:674:10 | b [element] : | array_flow.rb:674:10:674:13 | ...[...] | | array_flow.rb:674:10:674:10 | b [element] : | array_flow.rb:674:10:674:13 | ...[...] | -| array_flow.rb:678:16:678:25 | call to source : | array_flow.rb:679:9:679:9 | a [element 2] : | -| array_flow.rb:678:16:678:25 | call to source : | array_flow.rb:679:9:679:9 | a [element 2] : | +| array_flow.rb:678:5:678:5 | a [element 2] : | array_flow.rb:679:9:679:9 | a [element 2] : | +| array_flow.rb:678:5:678:5 | a [element 2] : | array_flow.rb:679:9:679:9 | a [element 2] : | +| array_flow.rb:678:16:678:25 | call to source : | array_flow.rb:678:5:678:5 | a [element 2] : | +| array_flow.rb:678:16:678:25 | call to source : | array_flow.rb:678:5:678:5 | a [element 2] : | +| array_flow.rb:679:5:679:5 | b [element] : | array_flow.rb:684:10:684:10 | b [element] : | +| array_flow.rb:679:5:679:5 | b [element] : | array_flow.rb:684:10:684:10 | b [element] : | | array_flow.rb:679:9:679:9 | [post] a [element] : | array_flow.rb:683:10:683:10 | a [element] : | | array_flow.rb:679:9:679:9 | [post] a [element] : | array_flow.rb:683:10:683:10 | a [element] : | | array_flow.rb:679:9:679:9 | a [element 2] : | array_flow.rb:679:9:679:9 | [post] a [element] : | @@ -1238,18 +1571,20 @@ edges | array_flow.rb:679:9:679:9 | a [element 2] : | array_flow.rb:679:9:682:7 | call to keep_if [element] : | | array_flow.rb:679:9:679:9 | a [element 2] : | array_flow.rb:679:23:679:23 | x : | | array_flow.rb:679:9:679:9 | a [element 2] : | array_flow.rb:679:23:679:23 | x : | -| array_flow.rb:679:9:682:7 | call to keep_if [element] : | array_flow.rb:684:10:684:10 | b [element] : | -| array_flow.rb:679:9:682:7 | call to keep_if [element] : | array_flow.rb:684:10:684:10 | b [element] : | +| array_flow.rb:679:9:682:7 | call to keep_if [element] : | array_flow.rb:679:5:679:5 | b [element] : | +| array_flow.rb:679:9:682:7 | call to keep_if [element] : | array_flow.rb:679:5:679:5 | b [element] : | | array_flow.rb:679:23:679:23 | x : | array_flow.rb:680:14:680:14 | x | | array_flow.rb:679:23:679:23 | x : | array_flow.rb:680:14:680:14 | x | | array_flow.rb:683:10:683:10 | a [element] : | array_flow.rb:683:10:683:13 | ...[...] | | array_flow.rb:683:10:683:10 | a [element] : | array_flow.rb:683:10:683:13 | ...[...] | | array_flow.rb:684:10:684:10 | b [element] : | array_flow.rb:684:10:684:13 | ...[...] | | array_flow.rb:684:10:684:10 | b [element] : | array_flow.rb:684:10:684:13 | ...[...] | -| array_flow.rb:688:16:688:27 | call to source : | array_flow.rb:690:10:690:10 | a [element 2] : | -| array_flow.rb:688:16:688:27 | call to source : | array_flow.rb:690:10:690:10 | a [element 2] : | -| array_flow.rb:688:16:688:27 | call to source : | array_flow.rb:691:9:691:9 | a [element 2] : | -| array_flow.rb:688:16:688:27 | call to source : | array_flow.rb:691:9:691:9 | a [element 2] : | +| array_flow.rb:688:5:688:5 | a [element 2] : | array_flow.rb:690:10:690:10 | a [element 2] : | +| array_flow.rb:688:5:688:5 | a [element 2] : | array_flow.rb:690:10:690:10 | a [element 2] : | +| array_flow.rb:688:5:688:5 | a [element 2] : | array_flow.rb:691:9:691:9 | a [element 2] : | +| array_flow.rb:688:5:688:5 | a [element 2] : | array_flow.rb:691:9:691:9 | a [element 2] : | +| array_flow.rb:688:16:688:27 | call to source : | array_flow.rb:688:5:688:5 | a [element 2] : | +| array_flow.rb:688:16:688:27 | call to source : | array_flow.rb:688:5:688:5 | a [element 2] : | | array_flow.rb:689:5:689:5 | [post] a [element] : | array_flow.rb:690:10:690:10 | a [element] : | | array_flow.rb:689:5:689:5 | [post] a [element] : | array_flow.rb:690:10:690:10 | a [element] : | | array_flow.rb:689:5:689:5 | [post] a [element] : | array_flow.rb:691:9:691:9 | a [element] : | @@ -1260,198 +1595,246 @@ edges | array_flow.rb:690:10:690:10 | a [element 2] : | array_flow.rb:690:10:690:15 | call to last | | array_flow.rb:690:10:690:10 | a [element] : | array_flow.rb:690:10:690:15 | call to last | | array_flow.rb:690:10:690:10 | a [element] : | array_flow.rb:690:10:690:15 | call to last | +| array_flow.rb:691:5:691:5 | b [element] : | array_flow.rb:692:10:692:10 | b [element] : | +| array_flow.rb:691:5:691:5 | b [element] : | array_flow.rb:692:10:692:10 | b [element] : | +| array_flow.rb:691:5:691:5 | b [element] : | array_flow.rb:693:10:693:10 | b [element] : | +| array_flow.rb:691:5:691:5 | b [element] : | array_flow.rb:693:10:693:10 | b [element] : | | array_flow.rb:691:9:691:9 | a [element 2] : | array_flow.rb:691:9:691:17 | call to last [element] : | | array_flow.rb:691:9:691:9 | a [element 2] : | array_flow.rb:691:9:691:17 | call to last [element] : | | array_flow.rb:691:9:691:9 | a [element] : | array_flow.rb:691:9:691:17 | call to last [element] : | | array_flow.rb:691:9:691:9 | a [element] : | array_flow.rb:691:9:691:17 | call to last [element] : | -| array_flow.rb:691:9:691:17 | call to last [element] : | array_flow.rb:692:10:692:10 | b [element] : | -| array_flow.rb:691:9:691:17 | call to last [element] : | array_flow.rb:692:10:692:10 | b [element] : | -| array_flow.rb:691:9:691:17 | call to last [element] : | array_flow.rb:693:10:693:10 | b [element] : | -| array_flow.rb:691:9:691:17 | call to last [element] : | array_flow.rb:693:10:693:10 | b [element] : | +| array_flow.rb:691:9:691:17 | call to last [element] : | array_flow.rb:691:5:691:5 | b [element] : | +| array_flow.rb:691:9:691:17 | call to last [element] : | array_flow.rb:691:5:691:5 | b [element] : | | array_flow.rb:692:10:692:10 | b [element] : | array_flow.rb:692:10:692:13 | ...[...] | | array_flow.rb:692:10:692:10 | b [element] : | array_flow.rb:692:10:692:13 | ...[...] | | array_flow.rb:693:10:693:10 | b [element] : | array_flow.rb:693:10:693:13 | ...[...] | | array_flow.rb:693:10:693:10 | b [element] : | array_flow.rb:693:10:693:13 | ...[...] | -| array_flow.rb:697:16:697:27 | call to source : | array_flow.rb:698:9:698:9 | a [element 2] : | -| array_flow.rb:697:16:697:27 | call to source : | array_flow.rb:698:9:698:9 | a [element 2] : | +| array_flow.rb:697:5:697:5 | a [element 2] : | array_flow.rb:698:9:698:9 | a [element 2] : | +| array_flow.rb:697:5:697:5 | a [element 2] : | array_flow.rb:698:9:698:9 | a [element 2] : | +| array_flow.rb:697:16:697:27 | call to source : | array_flow.rb:697:5:697:5 | a [element 2] : | +| array_flow.rb:697:16:697:27 | call to source : | array_flow.rb:697:5:697:5 | a [element 2] : | +| array_flow.rb:698:5:698:5 | b [element] : | array_flow.rb:702:10:702:10 | b [element] : | +| array_flow.rb:698:5:698:5 | b [element] : | array_flow.rb:702:10:702:10 | b [element] : | | array_flow.rb:698:9:698:9 | a [element 2] : | array_flow.rb:698:19:698:19 | x : | | array_flow.rb:698:9:698:9 | a [element 2] : | array_flow.rb:698:19:698:19 | x : | -| array_flow.rb:698:9:701:7 | call to map [element] : | array_flow.rb:702:10:702:10 | b [element] : | -| array_flow.rb:698:9:701:7 | call to map [element] : | array_flow.rb:702:10:702:10 | b [element] : | +| array_flow.rb:698:9:701:7 | call to map [element] : | array_flow.rb:698:5:698:5 | b [element] : | +| array_flow.rb:698:9:701:7 | call to map [element] : | array_flow.rb:698:5:698:5 | b [element] : | | array_flow.rb:698:19:698:19 | x : | array_flow.rb:699:14:699:14 | x | | array_flow.rb:698:19:698:19 | x : | array_flow.rb:699:14:699:14 | x | | array_flow.rb:700:9:700:19 | call to source : | array_flow.rb:698:9:701:7 | call to map [element] : | | array_flow.rb:700:9:700:19 | call to source : | array_flow.rb:698:9:701:7 | call to map [element] : | | array_flow.rb:702:10:702:10 | b [element] : | array_flow.rb:702:10:702:13 | ...[...] | | array_flow.rb:702:10:702:10 | b [element] : | array_flow.rb:702:10:702:13 | ...[...] | -| array_flow.rb:706:16:706:27 | call to source : | array_flow.rb:707:9:707:9 | a [element 2] : | -| array_flow.rb:706:16:706:27 | call to source : | array_flow.rb:707:9:707:9 | a [element 2] : | +| array_flow.rb:706:5:706:5 | a [element 2] : | array_flow.rb:707:9:707:9 | a [element 2] : | +| array_flow.rb:706:5:706:5 | a [element 2] : | array_flow.rb:707:9:707:9 | a [element 2] : | +| array_flow.rb:706:16:706:27 | call to source : | array_flow.rb:706:5:706:5 | a [element 2] : | +| array_flow.rb:706:16:706:27 | call to source : | array_flow.rb:706:5:706:5 | a [element 2] : | +| array_flow.rb:707:5:707:5 | b [element] : | array_flow.rb:711:10:711:10 | b [element] : | +| array_flow.rb:707:5:707:5 | b [element] : | array_flow.rb:711:10:711:10 | b [element] : | | array_flow.rb:707:9:707:9 | a [element 2] : | array_flow.rb:707:20:707:20 | x : | | array_flow.rb:707:9:707:9 | a [element 2] : | array_flow.rb:707:20:707:20 | x : | -| array_flow.rb:707:9:710:7 | call to map! [element] : | array_flow.rb:711:10:711:10 | b [element] : | -| array_flow.rb:707:9:710:7 | call to map! [element] : | array_flow.rb:711:10:711:10 | b [element] : | +| array_flow.rb:707:9:710:7 | call to map! [element] : | array_flow.rb:707:5:707:5 | b [element] : | +| array_flow.rb:707:9:710:7 | call to map! [element] : | array_flow.rb:707:5:707:5 | b [element] : | | array_flow.rb:707:20:707:20 | x : | array_flow.rb:708:14:708:14 | x | | array_flow.rb:707:20:707:20 | x : | array_flow.rb:708:14:708:14 | x | | array_flow.rb:709:9:709:19 | call to source : | array_flow.rb:707:9:710:7 | call to map! [element] : | | array_flow.rb:709:9:709:19 | call to source : | array_flow.rb:707:9:710:7 | call to map! [element] : | | array_flow.rb:711:10:711:10 | b [element] : | array_flow.rb:711:10:711:13 | ...[...] | | array_flow.rb:711:10:711:10 | b [element] : | array_flow.rb:711:10:711:13 | ...[...] | -| array_flow.rb:715:16:715:25 | call to source : | array_flow.rb:718:9:718:9 | a [element 2] : | -| array_flow.rb:715:16:715:25 | call to source : | array_flow.rb:718:9:718:9 | a [element 2] : | -| array_flow.rb:715:16:715:25 | call to source : | array_flow.rb:722:9:722:9 | a [element 2] : | -| array_flow.rb:715:16:715:25 | call to source : | array_flow.rb:722:9:722:9 | a [element 2] : | -| array_flow.rb:715:16:715:25 | call to source : | array_flow.rb:726:9:726:9 | a [element 2] : | -| array_flow.rb:715:16:715:25 | call to source : | array_flow.rb:726:9:726:9 | a [element 2] : | -| array_flow.rb:715:16:715:25 | call to source : | array_flow.rb:734:9:734:9 | a [element 2] : | -| array_flow.rb:715:16:715:25 | call to source : | array_flow.rb:734:9:734:9 | a [element 2] : | +| array_flow.rb:715:5:715:5 | a [element 2] : | array_flow.rb:718:9:718:9 | a [element 2] : | +| array_flow.rb:715:5:715:5 | a [element 2] : | array_flow.rb:718:9:718:9 | a [element 2] : | +| array_flow.rb:715:5:715:5 | a [element 2] : | array_flow.rb:722:9:722:9 | a [element 2] : | +| array_flow.rb:715:5:715:5 | a [element 2] : | array_flow.rb:722:9:722:9 | a [element 2] : | +| array_flow.rb:715:5:715:5 | a [element 2] : | array_flow.rb:726:9:726:9 | a [element 2] : | +| array_flow.rb:715:5:715:5 | a [element 2] : | array_flow.rb:726:9:726:9 | a [element 2] : | +| array_flow.rb:715:5:715:5 | a [element 2] : | array_flow.rb:734:9:734:9 | a [element 2] : | +| array_flow.rb:715:5:715:5 | a [element 2] : | array_flow.rb:734:9:734:9 | a [element 2] : | +| array_flow.rb:715:16:715:25 | call to source : | array_flow.rb:715:5:715:5 | a [element 2] : | +| array_flow.rb:715:16:715:25 | call to source : | array_flow.rb:715:5:715:5 | a [element 2] : | +| array_flow.rb:718:5:718:5 | b : | array_flow.rb:719:10:719:10 | b | +| array_flow.rb:718:5:718:5 | b : | array_flow.rb:719:10:719:10 | b | | array_flow.rb:718:9:718:9 | a [element 2] : | array_flow.rb:718:9:718:13 | call to max : | | array_flow.rb:718:9:718:9 | a [element 2] : | array_flow.rb:718:9:718:13 | call to max : | -| array_flow.rb:718:9:718:13 | call to max : | array_flow.rb:719:10:719:10 | b | -| array_flow.rb:718:9:718:13 | call to max : | array_flow.rb:719:10:719:10 | b | +| array_flow.rb:718:9:718:13 | call to max : | array_flow.rb:718:5:718:5 | b : | +| array_flow.rb:718:9:718:13 | call to max : | array_flow.rb:718:5:718:5 | b : | +| array_flow.rb:722:5:722:5 | c [element] : | array_flow.rb:723:10:723:10 | c [element] : | +| array_flow.rb:722:5:722:5 | c [element] : | array_flow.rb:723:10:723:10 | c [element] : | | array_flow.rb:722:9:722:9 | a [element 2] : | array_flow.rb:722:9:722:16 | call to max [element] : | | array_flow.rb:722:9:722:9 | a [element 2] : | array_flow.rb:722:9:722:16 | call to max [element] : | -| array_flow.rb:722:9:722:16 | call to max [element] : | array_flow.rb:723:10:723:10 | c [element] : | -| array_flow.rb:722:9:722:16 | call to max [element] : | array_flow.rb:723:10:723:10 | c [element] : | +| array_flow.rb:722:9:722:16 | call to max [element] : | array_flow.rb:722:5:722:5 | c [element] : | +| array_flow.rb:722:9:722:16 | call to max [element] : | array_flow.rb:722:5:722:5 | c [element] : | | array_flow.rb:723:10:723:10 | c [element] : | array_flow.rb:723:10:723:13 | ...[...] | | array_flow.rb:723:10:723:10 | c [element] : | array_flow.rb:723:10:723:13 | ...[...] | +| array_flow.rb:726:5:726:5 | d : | array_flow.rb:731:10:731:10 | d | +| array_flow.rb:726:5:726:5 | d : | array_flow.rb:731:10:731:10 | d | | array_flow.rb:726:9:726:9 | a [element 2] : | array_flow.rb:726:9:730:7 | call to max : | | array_flow.rb:726:9:726:9 | a [element 2] : | array_flow.rb:726:9:730:7 | call to max : | | array_flow.rb:726:9:726:9 | a [element 2] : | array_flow.rb:726:19:726:19 | x : | | array_flow.rb:726:9:726:9 | a [element 2] : | array_flow.rb:726:19:726:19 | x : | | array_flow.rb:726:9:726:9 | a [element 2] : | array_flow.rb:726:22:726:22 | y : | | array_flow.rb:726:9:726:9 | a [element 2] : | array_flow.rb:726:22:726:22 | y : | -| array_flow.rb:726:9:730:7 | call to max : | array_flow.rb:731:10:731:10 | d | -| array_flow.rb:726:9:730:7 | call to max : | array_flow.rb:731:10:731:10 | d | +| array_flow.rb:726:9:730:7 | call to max : | array_flow.rb:726:5:726:5 | d : | +| array_flow.rb:726:9:730:7 | call to max : | array_flow.rb:726:5:726:5 | d : | | array_flow.rb:726:19:726:19 | x : | array_flow.rb:727:14:727:14 | x | | array_flow.rb:726:19:726:19 | x : | array_flow.rb:727:14:727:14 | x | | array_flow.rb:726:22:726:22 | y : | array_flow.rb:728:14:728:14 | y | | array_flow.rb:726:22:726:22 | y : | array_flow.rb:728:14:728:14 | y | +| array_flow.rb:734:5:734:5 | e [element] : | array_flow.rb:739:10:739:10 | e [element] : | +| array_flow.rb:734:5:734:5 | e [element] : | array_flow.rb:739:10:739:10 | e [element] : | | array_flow.rb:734:9:734:9 | a [element 2] : | array_flow.rb:734:9:738:7 | call to max [element] : | | array_flow.rb:734:9:734:9 | a [element 2] : | array_flow.rb:734:9:738:7 | call to max [element] : | | array_flow.rb:734:9:734:9 | a [element 2] : | array_flow.rb:734:22:734:22 | x : | | array_flow.rb:734:9:734:9 | a [element 2] : | array_flow.rb:734:22:734:22 | x : | | array_flow.rb:734:9:734:9 | a [element 2] : | array_flow.rb:734:25:734:25 | y : | | array_flow.rb:734:9:734:9 | a [element 2] : | array_flow.rb:734:25:734:25 | y : | -| array_flow.rb:734:9:738:7 | call to max [element] : | array_flow.rb:739:10:739:10 | e [element] : | -| array_flow.rb:734:9:738:7 | call to max [element] : | array_flow.rb:739:10:739:10 | e [element] : | +| array_flow.rb:734:9:738:7 | call to max [element] : | array_flow.rb:734:5:734:5 | e [element] : | +| array_flow.rb:734:9:738:7 | call to max [element] : | array_flow.rb:734:5:734:5 | e [element] : | | array_flow.rb:734:22:734:22 | x : | array_flow.rb:735:14:735:14 | x | | array_flow.rb:734:22:734:22 | x : | array_flow.rb:735:14:735:14 | x | | array_flow.rb:734:25:734:25 | y : | array_flow.rb:736:14:736:14 | y | | array_flow.rb:734:25:734:25 | y : | array_flow.rb:736:14:736:14 | y | | array_flow.rb:739:10:739:10 | e [element] : | array_flow.rb:739:10:739:13 | ...[...] | | array_flow.rb:739:10:739:10 | e [element] : | array_flow.rb:739:10:739:13 | ...[...] | -| array_flow.rb:743:16:743:25 | call to source : | array_flow.rb:746:9:746:9 | a [element 2] : | -| array_flow.rb:743:16:743:25 | call to source : | array_flow.rb:746:9:746:9 | a [element 2] : | -| array_flow.rb:743:16:743:25 | call to source : | array_flow.rb:753:9:753:9 | a [element 2] : | -| array_flow.rb:743:16:743:25 | call to source : | array_flow.rb:753:9:753:9 | a [element 2] : | +| array_flow.rb:743:5:743:5 | a [element 2] : | array_flow.rb:746:9:746:9 | a [element 2] : | +| array_flow.rb:743:5:743:5 | a [element 2] : | array_flow.rb:746:9:746:9 | a [element 2] : | +| array_flow.rb:743:5:743:5 | a [element 2] : | array_flow.rb:753:9:753:9 | a [element 2] : | +| array_flow.rb:743:5:743:5 | a [element 2] : | array_flow.rb:753:9:753:9 | a [element 2] : | +| array_flow.rb:743:16:743:25 | call to source : | array_flow.rb:743:5:743:5 | a [element 2] : | +| array_flow.rb:743:16:743:25 | call to source : | array_flow.rb:743:5:743:5 | a [element 2] : | +| array_flow.rb:746:5:746:5 | b : | array_flow.rb:750:10:750:10 | b | +| array_flow.rb:746:5:746:5 | b : | array_flow.rb:750:10:750:10 | b | | array_flow.rb:746:9:746:9 | a [element 2] : | array_flow.rb:746:9:749:7 | call to max_by : | | array_flow.rb:746:9:746:9 | a [element 2] : | array_flow.rb:746:9:749:7 | call to max_by : | | array_flow.rb:746:9:746:9 | a [element 2] : | array_flow.rb:746:22:746:22 | x : | | array_flow.rb:746:9:746:9 | a [element 2] : | array_flow.rb:746:22:746:22 | x : | -| array_flow.rb:746:9:749:7 | call to max_by : | array_flow.rb:750:10:750:10 | b | -| array_flow.rb:746:9:749:7 | call to max_by : | array_flow.rb:750:10:750:10 | b | +| array_flow.rb:746:9:749:7 | call to max_by : | array_flow.rb:746:5:746:5 | b : | +| array_flow.rb:746:9:749:7 | call to max_by : | array_flow.rb:746:5:746:5 | b : | | array_flow.rb:746:22:746:22 | x : | array_flow.rb:747:14:747:14 | x | | array_flow.rb:746:22:746:22 | x : | array_flow.rb:747:14:747:14 | x | +| array_flow.rb:753:5:753:5 | c [element] : | array_flow.rb:757:10:757:10 | c [element] : | +| array_flow.rb:753:5:753:5 | c [element] : | array_flow.rb:757:10:757:10 | c [element] : | | array_flow.rb:753:9:753:9 | a [element 2] : | array_flow.rb:753:9:756:7 | call to max_by [element] : | | array_flow.rb:753:9:753:9 | a [element 2] : | array_flow.rb:753:9:756:7 | call to max_by [element] : | | array_flow.rb:753:9:753:9 | a [element 2] : | array_flow.rb:753:25:753:25 | x : | | array_flow.rb:753:9:753:9 | a [element 2] : | array_flow.rb:753:25:753:25 | x : | -| array_flow.rb:753:9:756:7 | call to max_by [element] : | array_flow.rb:757:10:757:10 | c [element] : | -| array_flow.rb:753:9:756:7 | call to max_by [element] : | array_flow.rb:757:10:757:10 | c [element] : | +| array_flow.rb:753:9:756:7 | call to max_by [element] : | array_flow.rb:753:5:753:5 | c [element] : | +| array_flow.rb:753:9:756:7 | call to max_by [element] : | array_flow.rb:753:5:753:5 | c [element] : | | array_flow.rb:753:25:753:25 | x : | array_flow.rb:754:14:754:14 | x | | array_flow.rb:753:25:753:25 | x : | array_flow.rb:754:14:754:14 | x | | array_flow.rb:757:10:757:10 | c [element] : | array_flow.rb:757:10:757:13 | ...[...] | | array_flow.rb:757:10:757:10 | c [element] : | array_flow.rb:757:10:757:13 | ...[...] | -| array_flow.rb:761:16:761:25 | call to source : | array_flow.rb:764:9:764:9 | a [element 2] : | -| array_flow.rb:761:16:761:25 | call to source : | array_flow.rb:764:9:764:9 | a [element 2] : | -| array_flow.rb:761:16:761:25 | call to source : | array_flow.rb:768:9:768:9 | a [element 2] : | -| array_flow.rb:761:16:761:25 | call to source : | array_flow.rb:768:9:768:9 | a [element 2] : | -| array_flow.rb:761:16:761:25 | call to source : | array_flow.rb:772:9:772:9 | a [element 2] : | -| array_flow.rb:761:16:761:25 | call to source : | array_flow.rb:772:9:772:9 | a [element 2] : | -| array_flow.rb:761:16:761:25 | call to source : | array_flow.rb:780:9:780:9 | a [element 2] : | -| array_flow.rb:761:16:761:25 | call to source : | array_flow.rb:780:9:780:9 | a [element 2] : | +| array_flow.rb:761:5:761:5 | a [element 2] : | array_flow.rb:764:9:764:9 | a [element 2] : | +| array_flow.rb:761:5:761:5 | a [element 2] : | array_flow.rb:764:9:764:9 | a [element 2] : | +| array_flow.rb:761:5:761:5 | a [element 2] : | array_flow.rb:768:9:768:9 | a [element 2] : | +| array_flow.rb:761:5:761:5 | a [element 2] : | array_flow.rb:768:9:768:9 | a [element 2] : | +| array_flow.rb:761:5:761:5 | a [element 2] : | array_flow.rb:772:9:772:9 | a [element 2] : | +| array_flow.rb:761:5:761:5 | a [element 2] : | array_flow.rb:772:9:772:9 | a [element 2] : | +| array_flow.rb:761:5:761:5 | a [element 2] : | array_flow.rb:780:9:780:9 | a [element 2] : | +| array_flow.rb:761:5:761:5 | a [element 2] : | array_flow.rb:780:9:780:9 | a [element 2] : | +| array_flow.rb:761:16:761:25 | call to source : | array_flow.rb:761:5:761:5 | a [element 2] : | +| array_flow.rb:761:16:761:25 | call to source : | array_flow.rb:761:5:761:5 | a [element 2] : | +| array_flow.rb:764:5:764:5 | b : | array_flow.rb:765:10:765:10 | b | +| array_flow.rb:764:5:764:5 | b : | array_flow.rb:765:10:765:10 | b | | array_flow.rb:764:9:764:9 | a [element 2] : | array_flow.rb:764:9:764:13 | call to min : | | array_flow.rb:764:9:764:9 | a [element 2] : | array_flow.rb:764:9:764:13 | call to min : | -| array_flow.rb:764:9:764:13 | call to min : | array_flow.rb:765:10:765:10 | b | -| array_flow.rb:764:9:764:13 | call to min : | array_flow.rb:765:10:765:10 | b | +| array_flow.rb:764:9:764:13 | call to min : | array_flow.rb:764:5:764:5 | b : | +| array_flow.rb:764:9:764:13 | call to min : | array_flow.rb:764:5:764:5 | b : | +| array_flow.rb:768:5:768:5 | c [element] : | array_flow.rb:769:10:769:10 | c [element] : | +| array_flow.rb:768:5:768:5 | c [element] : | array_flow.rb:769:10:769:10 | c [element] : | | array_flow.rb:768:9:768:9 | a [element 2] : | array_flow.rb:768:9:768:16 | call to min [element] : | | array_flow.rb:768:9:768:9 | a [element 2] : | array_flow.rb:768:9:768:16 | call to min [element] : | -| array_flow.rb:768:9:768:16 | call to min [element] : | array_flow.rb:769:10:769:10 | c [element] : | -| array_flow.rb:768:9:768:16 | call to min [element] : | array_flow.rb:769:10:769:10 | c [element] : | +| array_flow.rb:768:9:768:16 | call to min [element] : | array_flow.rb:768:5:768:5 | c [element] : | +| array_flow.rb:768:9:768:16 | call to min [element] : | array_flow.rb:768:5:768:5 | c [element] : | | array_flow.rb:769:10:769:10 | c [element] : | array_flow.rb:769:10:769:13 | ...[...] | | array_flow.rb:769:10:769:10 | c [element] : | array_flow.rb:769:10:769:13 | ...[...] | +| array_flow.rb:772:5:772:5 | d : | array_flow.rb:777:10:777:10 | d | +| array_flow.rb:772:5:772:5 | d : | array_flow.rb:777:10:777:10 | d | | array_flow.rb:772:9:772:9 | a [element 2] : | array_flow.rb:772:9:776:7 | call to min : | | array_flow.rb:772:9:772:9 | a [element 2] : | array_flow.rb:772:9:776:7 | call to min : | | array_flow.rb:772:9:772:9 | a [element 2] : | array_flow.rb:772:19:772:19 | x : | | array_flow.rb:772:9:772:9 | a [element 2] : | array_flow.rb:772:19:772:19 | x : | | array_flow.rb:772:9:772:9 | a [element 2] : | array_flow.rb:772:22:772:22 | y : | | array_flow.rb:772:9:772:9 | a [element 2] : | array_flow.rb:772:22:772:22 | y : | -| array_flow.rb:772:9:776:7 | call to min : | array_flow.rb:777:10:777:10 | d | -| array_flow.rb:772:9:776:7 | call to min : | array_flow.rb:777:10:777:10 | d | +| array_flow.rb:772:9:776:7 | call to min : | array_flow.rb:772:5:772:5 | d : | +| array_flow.rb:772:9:776:7 | call to min : | array_flow.rb:772:5:772:5 | d : | | array_flow.rb:772:19:772:19 | x : | array_flow.rb:773:14:773:14 | x | | array_flow.rb:772:19:772:19 | x : | array_flow.rb:773:14:773:14 | x | | array_flow.rb:772:22:772:22 | y : | array_flow.rb:774:14:774:14 | y | | array_flow.rb:772:22:772:22 | y : | array_flow.rb:774:14:774:14 | y | +| array_flow.rb:780:5:780:5 | e [element] : | array_flow.rb:785:10:785:10 | e [element] : | +| array_flow.rb:780:5:780:5 | e [element] : | array_flow.rb:785:10:785:10 | e [element] : | | array_flow.rb:780:9:780:9 | a [element 2] : | array_flow.rb:780:9:784:7 | call to min [element] : | | array_flow.rb:780:9:780:9 | a [element 2] : | array_flow.rb:780:9:784:7 | call to min [element] : | | array_flow.rb:780:9:780:9 | a [element 2] : | array_flow.rb:780:22:780:22 | x : | | array_flow.rb:780:9:780:9 | a [element 2] : | array_flow.rb:780:22:780:22 | x : | | array_flow.rb:780:9:780:9 | a [element 2] : | array_flow.rb:780:25:780:25 | y : | | array_flow.rb:780:9:780:9 | a [element 2] : | array_flow.rb:780:25:780:25 | y : | -| array_flow.rb:780:9:784:7 | call to min [element] : | array_flow.rb:785:10:785:10 | e [element] : | -| array_flow.rb:780:9:784:7 | call to min [element] : | array_flow.rb:785:10:785:10 | e [element] : | +| array_flow.rb:780:9:784:7 | call to min [element] : | array_flow.rb:780:5:780:5 | e [element] : | +| array_flow.rb:780:9:784:7 | call to min [element] : | array_flow.rb:780:5:780:5 | e [element] : | | array_flow.rb:780:22:780:22 | x : | array_flow.rb:781:14:781:14 | x | | array_flow.rb:780:22:780:22 | x : | array_flow.rb:781:14:781:14 | x | | array_flow.rb:780:25:780:25 | y : | array_flow.rb:782:14:782:14 | y | | array_flow.rb:780:25:780:25 | y : | array_flow.rb:782:14:782:14 | y | | array_flow.rb:785:10:785:10 | e [element] : | array_flow.rb:785:10:785:13 | ...[...] | | array_flow.rb:785:10:785:10 | e [element] : | array_flow.rb:785:10:785:13 | ...[...] | -| array_flow.rb:789:16:789:25 | call to source : | array_flow.rb:792:9:792:9 | a [element 2] : | -| array_flow.rb:789:16:789:25 | call to source : | array_flow.rb:792:9:792:9 | a [element 2] : | -| array_flow.rb:789:16:789:25 | call to source : | array_flow.rb:799:9:799:9 | a [element 2] : | -| array_flow.rb:789:16:789:25 | call to source : | array_flow.rb:799:9:799:9 | a [element 2] : | +| array_flow.rb:789:5:789:5 | a [element 2] : | array_flow.rb:792:9:792:9 | a [element 2] : | +| array_flow.rb:789:5:789:5 | a [element 2] : | array_flow.rb:792:9:792:9 | a [element 2] : | +| array_flow.rb:789:5:789:5 | a [element 2] : | array_flow.rb:799:9:799:9 | a [element 2] : | +| array_flow.rb:789:5:789:5 | a [element 2] : | array_flow.rb:799:9:799:9 | a [element 2] : | +| array_flow.rb:789:16:789:25 | call to source : | array_flow.rb:789:5:789:5 | a [element 2] : | +| array_flow.rb:789:16:789:25 | call to source : | array_flow.rb:789:5:789:5 | a [element 2] : | +| array_flow.rb:792:5:792:5 | b : | array_flow.rb:796:10:796:10 | b | +| array_flow.rb:792:5:792:5 | b : | array_flow.rb:796:10:796:10 | b | | array_flow.rb:792:9:792:9 | a [element 2] : | array_flow.rb:792:9:795:7 | call to min_by : | | array_flow.rb:792:9:792:9 | a [element 2] : | array_flow.rb:792:9:795:7 | call to min_by : | | array_flow.rb:792:9:792:9 | a [element 2] : | array_flow.rb:792:22:792:22 | x : | | array_flow.rb:792:9:792:9 | a [element 2] : | array_flow.rb:792:22:792:22 | x : | -| array_flow.rb:792:9:795:7 | call to min_by : | array_flow.rb:796:10:796:10 | b | -| array_flow.rb:792:9:795:7 | call to min_by : | array_flow.rb:796:10:796:10 | b | +| array_flow.rb:792:9:795:7 | call to min_by : | array_flow.rb:792:5:792:5 | b : | +| array_flow.rb:792:9:795:7 | call to min_by : | array_flow.rb:792:5:792:5 | b : | | array_flow.rb:792:22:792:22 | x : | array_flow.rb:793:14:793:14 | x | | array_flow.rb:792:22:792:22 | x : | array_flow.rb:793:14:793:14 | x | +| array_flow.rb:799:5:799:5 | c [element] : | array_flow.rb:803:10:803:10 | c [element] : | +| array_flow.rb:799:5:799:5 | c [element] : | array_flow.rb:803:10:803:10 | c [element] : | | array_flow.rb:799:9:799:9 | a [element 2] : | array_flow.rb:799:9:802:7 | call to min_by [element] : | | array_flow.rb:799:9:799:9 | a [element 2] : | array_flow.rb:799:9:802:7 | call to min_by [element] : | | array_flow.rb:799:9:799:9 | a [element 2] : | array_flow.rb:799:25:799:25 | x : | | array_flow.rb:799:9:799:9 | a [element 2] : | array_flow.rb:799:25:799:25 | x : | -| array_flow.rb:799:9:802:7 | call to min_by [element] : | array_flow.rb:803:10:803:10 | c [element] : | -| array_flow.rb:799:9:802:7 | call to min_by [element] : | array_flow.rb:803:10:803:10 | c [element] : | +| array_flow.rb:799:9:802:7 | call to min_by [element] : | array_flow.rb:799:5:799:5 | c [element] : | +| array_flow.rb:799:9:802:7 | call to min_by [element] : | array_flow.rb:799:5:799:5 | c [element] : | | array_flow.rb:799:25:799:25 | x : | array_flow.rb:800:14:800:14 | x | | array_flow.rb:799:25:799:25 | x : | array_flow.rb:800:14:800:14 | x | | array_flow.rb:803:10:803:10 | c [element] : | array_flow.rb:803:10:803:13 | ...[...] | | array_flow.rb:803:10:803:10 | c [element] : | array_flow.rb:803:10:803:13 | ...[...] | -| array_flow.rb:807:16:807:25 | call to source : | array_flow.rb:809:9:809:9 | a [element 2] : | -| array_flow.rb:807:16:807:25 | call to source : | array_flow.rb:809:9:809:9 | a [element 2] : | -| array_flow.rb:807:16:807:25 | call to source : | array_flow.rb:813:9:813:9 | a [element 2] : | -| array_flow.rb:807:16:807:25 | call to source : | array_flow.rb:813:9:813:9 | a [element 2] : | +| array_flow.rb:807:5:807:5 | a [element 2] : | array_flow.rb:809:9:809:9 | a [element 2] : | +| array_flow.rb:807:5:807:5 | a [element 2] : | array_flow.rb:809:9:809:9 | a [element 2] : | +| array_flow.rb:807:5:807:5 | a [element 2] : | array_flow.rb:813:9:813:9 | a [element 2] : | +| array_flow.rb:807:5:807:5 | a [element 2] : | array_flow.rb:813:9:813:9 | a [element 2] : | +| array_flow.rb:807:16:807:25 | call to source : | array_flow.rb:807:5:807:5 | a [element 2] : | +| array_flow.rb:807:16:807:25 | call to source : | array_flow.rb:807:5:807:5 | a [element 2] : | +| array_flow.rb:809:5:809:5 | b [element] : | array_flow.rb:810:10:810:10 | b [element] : | +| array_flow.rb:809:5:809:5 | b [element] : | array_flow.rb:810:10:810:10 | b [element] : | +| array_flow.rb:809:5:809:5 | b [element] : | array_flow.rb:811:10:811:10 | b [element] : | +| array_flow.rb:809:5:809:5 | b [element] : | array_flow.rb:811:10:811:10 | b [element] : | | array_flow.rb:809:9:809:9 | a [element 2] : | array_flow.rb:809:9:809:16 | call to minmax [element] : | | array_flow.rb:809:9:809:9 | a [element 2] : | array_flow.rb:809:9:809:16 | call to minmax [element] : | -| array_flow.rb:809:9:809:16 | call to minmax [element] : | array_flow.rb:810:10:810:10 | b [element] : | -| array_flow.rb:809:9:809:16 | call to minmax [element] : | array_flow.rb:810:10:810:10 | b [element] : | -| array_flow.rb:809:9:809:16 | call to minmax [element] : | array_flow.rb:811:10:811:10 | b [element] : | -| array_flow.rb:809:9:809:16 | call to minmax [element] : | array_flow.rb:811:10:811:10 | b [element] : | +| array_flow.rb:809:9:809:16 | call to minmax [element] : | array_flow.rb:809:5:809:5 | b [element] : | +| array_flow.rb:809:9:809:16 | call to minmax [element] : | array_flow.rb:809:5:809:5 | b [element] : | | array_flow.rb:810:10:810:10 | b [element] : | array_flow.rb:810:10:810:13 | ...[...] | | array_flow.rb:810:10:810:10 | b [element] : | array_flow.rb:810:10:810:13 | ...[...] | | array_flow.rb:811:10:811:10 | b [element] : | array_flow.rb:811:10:811:13 | ...[...] | | array_flow.rb:811:10:811:10 | b [element] : | array_flow.rb:811:10:811:13 | ...[...] | +| array_flow.rb:813:5:813:5 | c [element] : | array_flow.rb:818:10:818:10 | c [element] : | +| array_flow.rb:813:5:813:5 | c [element] : | array_flow.rb:818:10:818:10 | c [element] : | +| array_flow.rb:813:5:813:5 | c [element] : | array_flow.rb:819:10:819:10 | c [element] : | +| array_flow.rb:813:5:813:5 | c [element] : | array_flow.rb:819:10:819:10 | c [element] : | | array_flow.rb:813:9:813:9 | a [element 2] : | array_flow.rb:813:9:817:7 | call to minmax [element] : | | array_flow.rb:813:9:813:9 | a [element 2] : | array_flow.rb:813:9:817:7 | call to minmax [element] : | | array_flow.rb:813:9:813:9 | a [element 2] : | array_flow.rb:813:22:813:22 | x : | | array_flow.rb:813:9:813:9 | a [element 2] : | array_flow.rb:813:22:813:22 | x : | | array_flow.rb:813:9:813:9 | a [element 2] : | array_flow.rb:813:25:813:25 | y : | | array_flow.rb:813:9:813:9 | a [element 2] : | array_flow.rb:813:25:813:25 | y : | -| array_flow.rb:813:9:817:7 | call to minmax [element] : | array_flow.rb:818:10:818:10 | c [element] : | -| array_flow.rb:813:9:817:7 | call to minmax [element] : | array_flow.rb:818:10:818:10 | c [element] : | -| array_flow.rb:813:9:817:7 | call to minmax [element] : | array_flow.rb:819:10:819:10 | c [element] : | -| array_flow.rb:813:9:817:7 | call to minmax [element] : | array_flow.rb:819:10:819:10 | c [element] : | +| array_flow.rb:813:9:817:7 | call to minmax [element] : | array_flow.rb:813:5:813:5 | c [element] : | +| array_flow.rb:813:9:817:7 | call to minmax [element] : | array_flow.rb:813:5:813:5 | c [element] : | | array_flow.rb:813:22:813:22 | x : | array_flow.rb:814:14:814:14 | x | | array_flow.rb:813:22:813:22 | x : | array_flow.rb:814:14:814:14 | x | | array_flow.rb:813:25:813:25 | y : | array_flow.rb:815:14:815:14 | y | @@ -1460,47 +1843,61 @@ edges | array_flow.rb:818:10:818:10 | c [element] : | array_flow.rb:818:10:818:13 | ...[...] | | array_flow.rb:819:10:819:10 | c [element] : | array_flow.rb:819:10:819:13 | ...[...] | | array_flow.rb:819:10:819:10 | c [element] : | array_flow.rb:819:10:819:13 | ...[...] | -| array_flow.rb:823:16:823:25 | call to source : | array_flow.rb:824:9:824:9 | a [element 2] : | -| array_flow.rb:823:16:823:25 | call to source : | array_flow.rb:824:9:824:9 | a [element 2] : | +| array_flow.rb:823:5:823:5 | a [element 2] : | array_flow.rb:824:9:824:9 | a [element 2] : | +| array_flow.rb:823:5:823:5 | a [element 2] : | array_flow.rb:824:9:824:9 | a [element 2] : | +| array_flow.rb:823:16:823:25 | call to source : | array_flow.rb:823:5:823:5 | a [element 2] : | +| array_flow.rb:823:16:823:25 | call to source : | array_flow.rb:823:5:823:5 | a [element 2] : | +| array_flow.rb:824:5:824:5 | b [element] : | array_flow.rb:828:10:828:10 | b [element] : | +| array_flow.rb:824:5:824:5 | b [element] : | array_flow.rb:828:10:828:10 | b [element] : | +| array_flow.rb:824:5:824:5 | b [element] : | array_flow.rb:829:10:829:10 | b [element] : | +| array_flow.rb:824:5:824:5 | b [element] : | array_flow.rb:829:10:829:10 | b [element] : | | array_flow.rb:824:9:824:9 | a [element 2] : | array_flow.rb:824:9:827:7 | call to minmax_by [element] : | | array_flow.rb:824:9:824:9 | a [element 2] : | array_flow.rb:824:9:827:7 | call to minmax_by [element] : | | array_flow.rb:824:9:824:9 | a [element 2] : | array_flow.rb:824:25:824:25 | x : | | array_flow.rb:824:9:824:9 | a [element 2] : | array_flow.rb:824:25:824:25 | x : | -| array_flow.rb:824:9:827:7 | call to minmax_by [element] : | array_flow.rb:828:10:828:10 | b [element] : | -| array_flow.rb:824:9:827:7 | call to minmax_by [element] : | array_flow.rb:828:10:828:10 | b [element] : | -| array_flow.rb:824:9:827:7 | call to minmax_by [element] : | array_flow.rb:829:10:829:10 | b [element] : | -| array_flow.rb:824:9:827:7 | call to minmax_by [element] : | array_flow.rb:829:10:829:10 | b [element] : | +| array_flow.rb:824:9:827:7 | call to minmax_by [element] : | array_flow.rb:824:5:824:5 | b [element] : | +| array_flow.rb:824:9:827:7 | call to minmax_by [element] : | array_flow.rb:824:5:824:5 | b [element] : | | array_flow.rb:824:25:824:25 | x : | array_flow.rb:825:14:825:14 | x | | array_flow.rb:824:25:824:25 | x : | array_flow.rb:825:14:825:14 | x | | array_flow.rb:828:10:828:10 | b [element] : | array_flow.rb:828:10:828:13 | ...[...] | | array_flow.rb:828:10:828:10 | b [element] : | array_flow.rb:828:10:828:13 | ...[...] | | array_flow.rb:829:10:829:10 | b [element] : | array_flow.rb:829:10:829:13 | ...[...] | | array_flow.rb:829:10:829:10 | b [element] : | array_flow.rb:829:10:829:13 | ...[...] | -| array_flow.rb:833:16:833:25 | call to source : | array_flow.rb:834:5:834:5 | a [element 2] : | -| array_flow.rb:833:16:833:25 | call to source : | array_flow.rb:834:5:834:5 | a [element 2] : | +| array_flow.rb:833:5:833:5 | a [element 2] : | array_flow.rb:834:5:834:5 | a [element 2] : | +| array_flow.rb:833:5:833:5 | a [element 2] : | array_flow.rb:834:5:834:5 | a [element 2] : | +| array_flow.rb:833:16:833:25 | call to source : | array_flow.rb:833:5:833:5 | a [element 2] : | +| array_flow.rb:833:16:833:25 | call to source : | array_flow.rb:833:5:833:5 | a [element 2] : | | array_flow.rb:834:5:834:5 | a [element 2] : | array_flow.rb:834:17:834:17 | x : | | array_flow.rb:834:5:834:5 | a [element 2] : | array_flow.rb:834:17:834:17 | x : | | array_flow.rb:834:17:834:17 | x : | array_flow.rb:835:14:835:14 | x | | array_flow.rb:834:17:834:17 | x : | array_flow.rb:835:14:835:14 | x | -| array_flow.rb:842:16:842:25 | call to source : | array_flow.rb:843:5:843:5 | a [element 2] : | -| array_flow.rb:842:16:842:25 | call to source : | array_flow.rb:843:5:843:5 | a [element 2] : | +| array_flow.rb:842:5:842:5 | a [element 2] : | array_flow.rb:843:5:843:5 | a [element 2] : | +| array_flow.rb:842:5:842:5 | a [element 2] : | array_flow.rb:843:5:843:5 | a [element 2] : | +| array_flow.rb:842:16:842:25 | call to source : | array_flow.rb:842:5:842:5 | a [element 2] : | +| array_flow.rb:842:16:842:25 | call to source : | array_flow.rb:842:5:842:5 | a [element 2] : | | array_flow.rb:843:5:843:5 | a [element 2] : | array_flow.rb:843:16:843:16 | x : | | array_flow.rb:843:5:843:5 | a [element 2] : | array_flow.rb:843:16:843:16 | x : | | array_flow.rb:843:16:843:16 | x : | array_flow.rb:844:14:844:14 | x | | array_flow.rb:843:16:843:16 | x : | array_flow.rb:844:14:844:14 | x | -| array_flow.rb:849:16:849:25 | call to source : | array_flow.rb:850:9:850:9 | a [element 2] : | +| array_flow.rb:849:5:849:5 | a [element 2] : | array_flow.rb:850:9:850:9 | a [element 2] : | +| array_flow.rb:849:16:849:25 | call to source : | array_flow.rb:849:5:849:5 | a [element 2] : | +| array_flow.rb:850:5:850:5 | b : | array_flow.rb:851:10:851:10 | b | | array_flow.rb:850:9:850:9 | a [element 2] : | array_flow.rb:850:9:850:20 | call to pack : | -| array_flow.rb:850:9:850:20 | call to pack : | array_flow.rb:851:10:851:10 | b | -| array_flow.rb:855:16:855:25 | call to source : | array_flow.rb:856:9:856:9 | a [element 2] : | -| array_flow.rb:855:16:855:25 | call to source : | array_flow.rb:856:9:856:9 | a [element 2] : | +| array_flow.rb:850:9:850:20 | call to pack : | array_flow.rb:850:5:850:5 | b : | +| array_flow.rb:855:5:855:5 | a [element 2] : | array_flow.rb:856:9:856:9 | a [element 2] : | +| array_flow.rb:855:5:855:5 | a [element 2] : | array_flow.rb:856:9:856:9 | a [element 2] : | +| array_flow.rb:855:16:855:25 | call to source : | array_flow.rb:855:5:855:5 | a [element 2] : | +| array_flow.rb:855:16:855:25 | call to source : | array_flow.rb:855:5:855:5 | a [element 2] : | +| array_flow.rb:856:5:856:5 | b [element, element] : | array_flow.rb:860:10:860:10 | b [element, element] : | +| array_flow.rb:856:5:856:5 | b [element, element] : | array_flow.rb:860:10:860:10 | b [element, element] : | +| array_flow.rb:856:5:856:5 | b [element, element] : | array_flow.rb:861:10:861:10 | b [element, element] : | +| array_flow.rb:856:5:856:5 | b [element, element] : | array_flow.rb:861:10:861:10 | b [element, element] : | | array_flow.rb:856:9:856:9 | a [element 2] : | array_flow.rb:856:9:859:7 | call to partition [element, element] : | | array_flow.rb:856:9:856:9 | a [element 2] : | array_flow.rb:856:9:859:7 | call to partition [element, element] : | | array_flow.rb:856:9:856:9 | a [element 2] : | array_flow.rb:856:25:856:25 | x : | | array_flow.rb:856:9:856:9 | a [element 2] : | array_flow.rb:856:25:856:25 | x : | -| array_flow.rb:856:9:859:7 | call to partition [element, element] : | array_flow.rb:860:10:860:10 | b [element, element] : | -| array_flow.rb:856:9:859:7 | call to partition [element, element] : | array_flow.rb:860:10:860:10 | b [element, element] : | -| array_flow.rb:856:9:859:7 | call to partition [element, element] : | array_flow.rb:861:10:861:10 | b [element, element] : | -| array_flow.rb:856:9:859:7 | call to partition [element, element] : | array_flow.rb:861:10:861:10 | b [element, element] : | +| array_flow.rb:856:9:859:7 | call to partition [element, element] : | array_flow.rb:856:5:856:5 | b [element, element] : | +| array_flow.rb:856:9:859:7 | call to partition [element, element] : | array_flow.rb:856:5:856:5 | b [element, element] : | | array_flow.rb:856:25:856:25 | x : | array_flow.rb:857:14:857:14 | x | | array_flow.rb:856:25:856:25 | x : | array_flow.rb:857:14:857:14 | x | | array_flow.rb:860:10:860:10 | b [element, element] : | array_flow.rb:860:10:860:13 | ...[...] [element] : | @@ -1511,18 +1908,22 @@ edges | array_flow.rb:861:10:861:10 | b [element, element] : | array_flow.rb:861:10:861:13 | ...[...] [element] : | | array_flow.rb:861:10:861:13 | ...[...] [element] : | array_flow.rb:861:10:861:16 | ...[...] | | array_flow.rb:861:10:861:13 | ...[...] [element] : | array_flow.rb:861:10:861:16 | ...[...] | -| array_flow.rb:865:16:865:25 | call to source : | array_flow.rb:867:9:867:9 | a [element 2] : | -| array_flow.rb:865:16:865:25 | call to source : | array_flow.rb:867:9:867:9 | a [element 2] : | -| array_flow.rb:865:16:865:25 | call to source : | array_flow.rb:875:9:875:9 | a [element 2] : | -| array_flow.rb:865:16:865:25 | call to source : | array_flow.rb:875:9:875:9 | a [element 2] : | -| array_flow.rb:865:16:865:25 | call to source : | array_flow.rb:882:9:882:9 | a [element 2] : | -| array_flow.rb:865:16:865:25 | call to source : | array_flow.rb:882:9:882:9 | a [element 2] : | +| array_flow.rb:865:5:865:5 | a [element 2] : | array_flow.rb:867:9:867:9 | a [element 2] : | +| array_flow.rb:865:5:865:5 | a [element 2] : | array_flow.rb:867:9:867:9 | a [element 2] : | +| array_flow.rb:865:5:865:5 | a [element 2] : | array_flow.rb:875:9:875:9 | a [element 2] : | +| array_flow.rb:865:5:865:5 | a [element 2] : | array_flow.rb:875:9:875:9 | a [element 2] : | +| array_flow.rb:865:5:865:5 | a [element 2] : | array_flow.rb:882:9:882:9 | a [element 2] : | +| array_flow.rb:865:5:865:5 | a [element 2] : | array_flow.rb:882:9:882:9 | a [element 2] : | +| array_flow.rb:865:16:865:25 | call to source : | array_flow.rb:865:5:865:5 | a [element 2] : | +| array_flow.rb:865:16:865:25 | call to source : | array_flow.rb:865:5:865:5 | a [element 2] : | +| array_flow.rb:867:5:867:5 | b [element 2] : | array_flow.rb:873:10:873:10 | b [element 2] : | +| array_flow.rb:867:5:867:5 | b [element 2] : | array_flow.rb:873:10:873:10 | b [element 2] : | | array_flow.rb:867:9:867:9 | a [element 2] : | array_flow.rb:867:9:871:7 | call to permutation [element 2] : | | array_flow.rb:867:9:867:9 | a [element 2] : | array_flow.rb:867:9:871:7 | call to permutation [element 2] : | | array_flow.rb:867:9:867:9 | a [element 2] : | array_flow.rb:867:27:867:27 | x [element] : | | array_flow.rb:867:9:867:9 | a [element 2] : | array_flow.rb:867:27:867:27 | x [element] : | -| array_flow.rb:867:9:871:7 | call to permutation [element 2] : | array_flow.rb:873:10:873:10 | b [element 2] : | -| array_flow.rb:867:9:871:7 | call to permutation [element 2] : | array_flow.rb:873:10:873:10 | b [element 2] : | +| array_flow.rb:867:9:871:7 | call to permutation [element 2] : | array_flow.rb:867:5:867:5 | b [element 2] : | +| array_flow.rb:867:9:871:7 | call to permutation [element 2] : | array_flow.rb:867:5:867:5 | b [element 2] : | | array_flow.rb:867:27:867:27 | x [element] : | array_flow.rb:868:14:868:14 | x [element] : | | array_flow.rb:867:27:867:27 | x [element] : | array_flow.rb:868:14:868:14 | x [element] : | | array_flow.rb:867:27:867:27 | x [element] : | array_flow.rb:869:14:869:14 | x [element] : | @@ -1537,14 +1938,16 @@ edges | array_flow.rb:870:14:870:14 | x [element] : | array_flow.rb:870:14:870:17 | ...[...] | | array_flow.rb:873:10:873:10 | b [element 2] : | array_flow.rb:873:10:873:13 | ...[...] | | array_flow.rb:873:10:873:10 | b [element 2] : | array_flow.rb:873:10:873:13 | ...[...] | +| array_flow.rb:875:5:875:5 | c [element 2] : | array_flow.rb:880:10:880:10 | c [element 2] : | +| array_flow.rb:875:5:875:5 | c [element 2] : | array_flow.rb:880:10:880:10 | c [element 2] : | +| array_flow.rb:875:5:875:5 | c [element 2] : | array_flow.rb:887:10:887:10 | c [element 2] : | +| array_flow.rb:875:5:875:5 | c [element 2] : | array_flow.rb:887:10:887:10 | c [element 2] : | | array_flow.rb:875:9:875:9 | a [element 2] : | array_flow.rb:875:9:878:7 | call to permutation [element 2] : | | array_flow.rb:875:9:875:9 | a [element 2] : | array_flow.rb:875:9:878:7 | call to permutation [element 2] : | | array_flow.rb:875:9:875:9 | a [element 2] : | array_flow.rb:875:30:875:30 | x [element] : | | array_flow.rb:875:9:875:9 | a [element 2] : | array_flow.rb:875:30:875:30 | x [element] : | -| array_flow.rb:875:9:878:7 | call to permutation [element 2] : | array_flow.rb:880:10:880:10 | c [element 2] : | -| array_flow.rb:875:9:878:7 | call to permutation [element 2] : | array_flow.rb:880:10:880:10 | c [element 2] : | -| array_flow.rb:875:9:878:7 | call to permutation [element 2] : | array_flow.rb:887:10:887:10 | c [element 2] : | -| array_flow.rb:875:9:878:7 | call to permutation [element 2] : | array_flow.rb:887:10:887:10 | c [element 2] : | +| array_flow.rb:875:9:878:7 | call to permutation [element 2] : | array_flow.rb:875:5:875:5 | c [element 2] : | +| array_flow.rb:875:9:878:7 | call to permutation [element 2] : | array_flow.rb:875:5:875:5 | c [element 2] : | | array_flow.rb:875:30:875:30 | x [element] : | array_flow.rb:876:14:876:14 | x [element] : | | array_flow.rb:875:30:875:30 | x [element] : | array_flow.rb:876:14:876:14 | x [element] : | | array_flow.rb:875:30:875:30 | x [element] : | array_flow.rb:877:14:877:14 | x [element] : | @@ -1567,40 +1970,52 @@ edges | array_flow.rb:884:14:884:14 | x [element] : | array_flow.rb:884:14:884:17 | ...[...] | | array_flow.rb:887:10:887:10 | c [element 2] : | array_flow.rb:887:10:887:13 | ...[...] | | array_flow.rb:887:10:887:10 | c [element 2] : | array_flow.rb:887:10:887:13 | ...[...] | -| array_flow.rb:894:13:894:24 | call to source : | array_flow.rb:895:9:895:9 | a [element 1] : | -| array_flow.rb:894:13:894:24 | call to source : | array_flow.rb:895:9:895:9 | a [element 1] : | -| array_flow.rb:894:13:894:24 | call to source : | array_flow.rb:898:10:898:10 | a [element 1] : | -| array_flow.rb:894:13:894:24 | call to source : | array_flow.rb:898:10:898:10 | a [element 1] : | -| array_flow.rb:894:30:894:41 | call to source : | array_flow.rb:895:9:895:9 | a [element 3] : | -| array_flow.rb:894:30:894:41 | call to source : | array_flow.rb:895:9:895:9 | a [element 3] : | -| array_flow.rb:894:30:894:41 | call to source : | array_flow.rb:900:10:900:10 | a [element 3] : | -| array_flow.rb:894:30:894:41 | call to source : | array_flow.rb:900:10:900:10 | a [element 3] : | +| array_flow.rb:894:5:894:5 | a [element 1] : | array_flow.rb:895:9:895:9 | a [element 1] : | +| array_flow.rb:894:5:894:5 | a [element 1] : | array_flow.rb:895:9:895:9 | a [element 1] : | +| array_flow.rb:894:5:894:5 | a [element 1] : | array_flow.rb:898:10:898:10 | a [element 1] : | +| array_flow.rb:894:5:894:5 | a [element 1] : | array_flow.rb:898:10:898:10 | a [element 1] : | +| array_flow.rb:894:5:894:5 | a [element 3] : | array_flow.rb:895:9:895:9 | a [element 3] : | +| array_flow.rb:894:5:894:5 | a [element 3] : | array_flow.rb:895:9:895:9 | a [element 3] : | +| array_flow.rb:894:5:894:5 | a [element 3] : | array_flow.rb:900:10:900:10 | a [element 3] : | +| array_flow.rb:894:5:894:5 | a [element 3] : | array_flow.rb:900:10:900:10 | a [element 3] : | +| array_flow.rb:894:13:894:24 | call to source : | array_flow.rb:894:5:894:5 | a [element 1] : | +| array_flow.rb:894:13:894:24 | call to source : | array_flow.rb:894:5:894:5 | a [element 1] : | +| array_flow.rb:894:30:894:41 | call to source : | array_flow.rb:894:5:894:5 | a [element 3] : | +| array_flow.rb:894:30:894:41 | call to source : | array_flow.rb:894:5:894:5 | a [element 3] : | +| array_flow.rb:895:5:895:5 | b : | array_flow.rb:896:10:896:10 | b | +| array_flow.rb:895:5:895:5 | b : | array_flow.rb:896:10:896:10 | b | | array_flow.rb:895:9:895:9 | a [element 1] : | array_flow.rb:895:9:895:13 | call to pop : | | array_flow.rb:895:9:895:9 | a [element 1] : | array_flow.rb:895:9:895:13 | call to pop : | | array_flow.rb:895:9:895:9 | a [element 3] : | array_flow.rb:895:9:895:13 | call to pop : | | array_flow.rb:895:9:895:9 | a [element 3] : | array_flow.rb:895:9:895:13 | call to pop : | -| array_flow.rb:895:9:895:13 | call to pop : | array_flow.rb:896:10:896:10 | b | -| array_flow.rb:895:9:895:13 | call to pop : | array_flow.rb:896:10:896:10 | b | +| array_flow.rb:895:9:895:13 | call to pop : | array_flow.rb:895:5:895:5 | b : | +| array_flow.rb:895:9:895:13 | call to pop : | array_flow.rb:895:5:895:5 | b : | | array_flow.rb:898:10:898:10 | a [element 1] : | array_flow.rb:898:10:898:13 | ...[...] | | array_flow.rb:898:10:898:10 | a [element 1] : | array_flow.rb:898:10:898:13 | ...[...] | | array_flow.rb:900:10:900:10 | a [element 3] : | array_flow.rb:900:10:900:13 | ...[...] | | array_flow.rb:900:10:900:10 | a [element 3] : | array_flow.rb:900:10:900:13 | ...[...] | -| array_flow.rb:902:13:902:24 | call to source : | array_flow.rb:903:9:903:9 | a [element 1] : | -| array_flow.rb:902:13:902:24 | call to source : | array_flow.rb:903:9:903:9 | a [element 1] : | -| array_flow.rb:902:13:902:24 | call to source : | array_flow.rb:907:10:907:10 | a [element 1] : | -| array_flow.rb:902:13:902:24 | call to source : | array_flow.rb:907:10:907:10 | a [element 1] : | -| array_flow.rb:902:30:902:41 | call to source : | array_flow.rb:903:9:903:9 | a [element 3] : | -| array_flow.rb:902:30:902:41 | call to source : | array_flow.rb:903:9:903:9 | a [element 3] : | -| array_flow.rb:902:30:902:41 | call to source : | array_flow.rb:909:10:909:10 | a [element 3] : | -| array_flow.rb:902:30:902:41 | call to source : | array_flow.rb:909:10:909:10 | a [element 3] : | +| array_flow.rb:902:5:902:5 | a [element 1] : | array_flow.rb:903:9:903:9 | a [element 1] : | +| array_flow.rb:902:5:902:5 | a [element 1] : | array_flow.rb:903:9:903:9 | a [element 1] : | +| array_flow.rb:902:5:902:5 | a [element 1] : | array_flow.rb:907:10:907:10 | a [element 1] : | +| array_flow.rb:902:5:902:5 | a [element 1] : | array_flow.rb:907:10:907:10 | a [element 1] : | +| array_flow.rb:902:5:902:5 | a [element 3] : | array_flow.rb:903:9:903:9 | a [element 3] : | +| array_flow.rb:902:5:902:5 | a [element 3] : | array_flow.rb:903:9:903:9 | a [element 3] : | +| array_flow.rb:902:5:902:5 | a [element 3] : | array_flow.rb:909:10:909:10 | a [element 3] : | +| array_flow.rb:902:5:902:5 | a [element 3] : | array_flow.rb:909:10:909:10 | a [element 3] : | +| array_flow.rb:902:13:902:24 | call to source : | array_flow.rb:902:5:902:5 | a [element 1] : | +| array_flow.rb:902:13:902:24 | call to source : | array_flow.rb:902:5:902:5 | a [element 1] : | +| array_flow.rb:902:30:902:41 | call to source : | array_flow.rb:902:5:902:5 | a [element 3] : | +| array_flow.rb:902:30:902:41 | call to source : | array_flow.rb:902:5:902:5 | a [element 3] : | +| array_flow.rb:903:5:903:5 | b [element] : | array_flow.rb:904:10:904:10 | b [element] : | +| array_flow.rb:903:5:903:5 | b [element] : | array_flow.rb:904:10:904:10 | b [element] : | +| array_flow.rb:903:5:903:5 | b [element] : | array_flow.rb:905:10:905:10 | b [element] : | +| array_flow.rb:903:5:903:5 | b [element] : | array_flow.rb:905:10:905:10 | b [element] : | | array_flow.rb:903:9:903:9 | a [element 1] : | array_flow.rb:903:9:903:16 | call to pop [element] : | | array_flow.rb:903:9:903:9 | a [element 1] : | array_flow.rb:903:9:903:16 | call to pop [element] : | | array_flow.rb:903:9:903:9 | a [element 3] : | array_flow.rb:903:9:903:16 | call to pop [element] : | | array_flow.rb:903:9:903:9 | a [element 3] : | array_flow.rb:903:9:903:16 | call to pop [element] : | -| array_flow.rb:903:9:903:16 | call to pop [element] : | array_flow.rb:904:10:904:10 | b [element] : | -| array_flow.rb:903:9:903:16 | call to pop [element] : | array_flow.rb:904:10:904:10 | b [element] : | -| array_flow.rb:903:9:903:16 | call to pop [element] : | array_flow.rb:905:10:905:10 | b [element] : | -| array_flow.rb:903:9:903:16 | call to pop [element] : | array_flow.rb:905:10:905:10 | b [element] : | +| array_flow.rb:903:9:903:16 | call to pop [element] : | array_flow.rb:903:5:903:5 | b [element] : | +| array_flow.rb:903:9:903:16 | call to pop [element] : | array_flow.rb:903:5:903:5 | b [element] : | | array_flow.rb:904:10:904:10 | b [element] : | array_flow.rb:904:10:904:13 | ...[...] | | array_flow.rb:904:10:904:10 | b [element] : | array_flow.rb:904:10:904:13 | ...[...] | | array_flow.rb:905:10:905:10 | b [element] : | array_flow.rb:905:10:905:13 | ...[...] | @@ -1609,8 +2024,10 @@ edges | array_flow.rb:907:10:907:10 | a [element 1] : | array_flow.rb:907:10:907:13 | ...[...] | | array_flow.rb:909:10:909:10 | a [element 3] : | array_flow.rb:909:10:909:13 | ...[...] | | array_flow.rb:909:10:909:10 | a [element 3] : | array_flow.rb:909:10:909:13 | ...[...] | -| array_flow.rb:913:16:913:27 | call to source : | array_flow.rb:914:5:914:5 | a [element 2] : | -| array_flow.rb:913:16:913:27 | call to source : | array_flow.rb:914:5:914:5 | a [element 2] : | +| array_flow.rb:913:5:913:5 | a [element 2] : | array_flow.rb:914:5:914:5 | a [element 2] : | +| array_flow.rb:913:5:913:5 | a [element 2] : | array_flow.rb:914:5:914:5 | a [element 2] : | +| array_flow.rb:913:16:913:27 | call to source : | array_flow.rb:913:5:913:5 | a [element 2] : | +| array_flow.rb:913:16:913:27 | call to source : | array_flow.rb:913:5:913:5 | a [element 2] : | | array_flow.rb:914:5:914:5 | [post] a [element 2] : | array_flow.rb:917:10:917:10 | a [element 2] : | | array_flow.rb:914:5:914:5 | [post] a [element 2] : | array_flow.rb:917:10:917:10 | a [element 2] : | | array_flow.rb:914:5:914:5 | [post] a [element 5] : | array_flow.rb:920:10:920:10 | a [element 5] : | @@ -1623,18 +2040,26 @@ edges | array_flow.rb:917:10:917:10 | a [element 2] : | array_flow.rb:917:10:917:13 | ...[...] | | array_flow.rb:920:10:920:10 | a [element 5] : | array_flow.rb:920:10:920:13 | ...[...] | | array_flow.rb:920:10:920:10 | a [element 5] : | array_flow.rb:920:10:920:13 | ...[...] | -| array_flow.rb:924:16:924:27 | call to source : | array_flow.rb:927:9:927:9 | a [element 2] : | -| array_flow.rb:924:16:924:27 | call to source : | array_flow.rb:927:9:927:9 | a [element 2] : | -| array_flow.rb:925:13:925:24 | call to source : | array_flow.rb:927:19:927:19 | b [element 1] : | -| array_flow.rb:925:13:925:24 | call to source : | array_flow.rb:927:19:927:19 | b [element 1] : | -| array_flow.rb:926:10:926:21 | call to source : | array_flow.rb:927:22:927:22 | c [element 0] : | -| array_flow.rb:926:10:926:21 | call to source : | array_flow.rb:927:22:927:22 | c [element 0] : | +| array_flow.rb:924:5:924:5 | a [element 2] : | array_flow.rb:927:9:927:9 | a [element 2] : | +| array_flow.rb:924:5:924:5 | a [element 2] : | array_flow.rb:927:9:927:9 | a [element 2] : | +| array_flow.rb:924:16:924:27 | call to source : | array_flow.rb:924:5:924:5 | a [element 2] : | +| array_flow.rb:924:16:924:27 | call to source : | array_flow.rb:924:5:924:5 | a [element 2] : | +| array_flow.rb:925:5:925:5 | b [element 1] : | array_flow.rb:927:19:927:19 | b [element 1] : | +| array_flow.rb:925:5:925:5 | b [element 1] : | array_flow.rb:927:19:927:19 | b [element 1] : | +| array_flow.rb:925:13:925:24 | call to source : | array_flow.rb:925:5:925:5 | b [element 1] : | +| array_flow.rb:925:13:925:24 | call to source : | array_flow.rb:925:5:925:5 | b [element 1] : | +| array_flow.rb:926:5:926:5 | c [element 0] : | array_flow.rb:927:22:927:22 | c [element 0] : | +| array_flow.rb:926:5:926:5 | c [element 0] : | array_flow.rb:927:22:927:22 | c [element 0] : | +| array_flow.rb:926:10:926:21 | call to source : | array_flow.rb:926:5:926:5 | c [element 0] : | +| array_flow.rb:926:10:926:21 | call to source : | array_flow.rb:926:5:926:5 | c [element 0] : | +| array_flow.rb:927:5:927:5 | d [element, element] : | array_flow.rb:928:10:928:10 | d [element, element] : | +| array_flow.rb:927:5:927:5 | d [element, element] : | array_flow.rb:928:10:928:10 | d [element, element] : | +| array_flow.rb:927:5:927:5 | d [element, element] : | array_flow.rb:929:10:929:10 | d [element, element] : | +| array_flow.rb:927:5:927:5 | d [element, element] : | array_flow.rb:929:10:929:10 | d [element, element] : | | array_flow.rb:927:9:927:9 | a [element 2] : | array_flow.rb:927:9:927:22 | call to product [element, element] : | | array_flow.rb:927:9:927:9 | a [element 2] : | array_flow.rb:927:9:927:22 | call to product [element, element] : | -| array_flow.rb:927:9:927:22 | call to product [element, element] : | array_flow.rb:928:10:928:10 | d [element, element] : | -| array_flow.rb:927:9:927:22 | call to product [element, element] : | array_flow.rb:928:10:928:10 | d [element, element] : | -| array_flow.rb:927:9:927:22 | call to product [element, element] : | array_flow.rb:929:10:929:10 | d [element, element] : | -| array_flow.rb:927:9:927:22 | call to product [element, element] : | array_flow.rb:929:10:929:10 | d [element, element] : | +| array_flow.rb:927:9:927:22 | call to product [element, element] : | array_flow.rb:927:5:927:5 | d [element, element] : | +| array_flow.rb:927:9:927:22 | call to product [element, element] : | array_flow.rb:927:5:927:5 | d [element, element] : | | array_flow.rb:927:19:927:19 | b [element 1] : | array_flow.rb:927:9:927:22 | call to product [element, element] : | | array_flow.rb:927:19:927:19 | b [element 1] : | array_flow.rb:927:9:927:22 | call to product [element, element] : | | array_flow.rb:927:22:927:22 | c [element 0] : | array_flow.rb:927:9:927:22 | call to product [element, element] : | @@ -1647,22 +2072,28 @@ edges | array_flow.rb:929:10:929:10 | d [element, element] : | array_flow.rb:929:10:929:13 | ...[...] [element] : | | array_flow.rb:929:10:929:13 | ...[...] [element] : | array_flow.rb:929:10:929:16 | ...[...] | | array_flow.rb:929:10:929:13 | ...[...] [element] : | array_flow.rb:929:10:929:16 | ...[...] | -| array_flow.rb:933:10:933:21 | call to source : | array_flow.rb:934:9:934:9 | a [element 0] : | -| array_flow.rb:933:10:933:21 | call to source : | array_flow.rb:934:9:934:9 | a [element 0] : | -| array_flow.rb:933:10:933:21 | call to source : | array_flow.rb:935:10:935:10 | a [element 0] : | -| array_flow.rb:933:10:933:21 | call to source : | array_flow.rb:935:10:935:10 | a [element 0] : | +| array_flow.rb:933:5:933:5 | a [element 0] : | array_flow.rb:934:9:934:9 | a [element 0] : | +| array_flow.rb:933:5:933:5 | a [element 0] : | array_flow.rb:934:9:934:9 | a [element 0] : | +| array_flow.rb:933:5:933:5 | a [element 0] : | array_flow.rb:935:10:935:10 | a [element 0] : | +| array_flow.rb:933:5:933:5 | a [element 0] : | array_flow.rb:935:10:935:10 | a [element 0] : | +| array_flow.rb:933:10:933:21 | call to source : | array_flow.rb:933:5:933:5 | a [element 0] : | +| array_flow.rb:933:10:933:21 | call to source : | array_flow.rb:933:5:933:5 | a [element 0] : | +| array_flow.rb:934:5:934:5 | b [element 0] : | array_flow.rb:937:10:937:10 | b [element 0] : | +| array_flow.rb:934:5:934:5 | b [element 0] : | array_flow.rb:937:10:937:10 | b [element 0] : | +| array_flow.rb:934:5:934:5 | b [element] : | array_flow.rb:937:10:937:10 | b [element] : | +| array_flow.rb:934:5:934:5 | b [element] : | array_flow.rb:937:10:937:10 | b [element] : | +| array_flow.rb:934:5:934:5 | b [element] : | array_flow.rb:938:10:938:10 | b [element] : | +| array_flow.rb:934:5:934:5 | b [element] : | array_flow.rb:938:10:938:10 | b [element] : | | array_flow.rb:934:9:934:9 | [post] a [element] : | array_flow.rb:935:10:935:10 | a [element] : | | array_flow.rb:934:9:934:9 | [post] a [element] : | array_flow.rb:935:10:935:10 | a [element] : | | array_flow.rb:934:9:934:9 | [post] a [element] : | array_flow.rb:936:10:936:10 | a [element] : | | array_flow.rb:934:9:934:9 | [post] a [element] : | array_flow.rb:936:10:936:10 | a [element] : | | array_flow.rb:934:9:934:9 | a [element 0] : | array_flow.rb:934:9:934:44 | call to append [element 0] : | | array_flow.rb:934:9:934:9 | a [element 0] : | array_flow.rb:934:9:934:44 | call to append [element 0] : | -| array_flow.rb:934:9:934:44 | call to append [element 0] : | array_flow.rb:937:10:937:10 | b [element 0] : | -| array_flow.rb:934:9:934:44 | call to append [element 0] : | array_flow.rb:937:10:937:10 | b [element 0] : | -| array_flow.rb:934:9:934:44 | call to append [element] : | array_flow.rb:937:10:937:10 | b [element] : | -| array_flow.rb:934:9:934:44 | call to append [element] : | array_flow.rb:937:10:937:10 | b [element] : | -| array_flow.rb:934:9:934:44 | call to append [element] : | array_flow.rb:938:10:938:10 | b [element] : | -| array_flow.rb:934:9:934:44 | call to append [element] : | array_flow.rb:938:10:938:10 | b [element] : | +| array_flow.rb:934:9:934:44 | call to append [element 0] : | array_flow.rb:934:5:934:5 | b [element 0] : | +| array_flow.rb:934:9:934:44 | call to append [element 0] : | array_flow.rb:934:5:934:5 | b [element 0] : | +| array_flow.rb:934:9:934:44 | call to append [element] : | array_flow.rb:934:5:934:5 | b [element] : | +| array_flow.rb:934:9:934:44 | call to append [element] : | array_flow.rb:934:5:934:5 | b [element] : | | array_flow.rb:934:18:934:29 | call to source : | array_flow.rb:934:9:934:9 | [post] a [element] : | | array_flow.rb:934:18:934:29 | call to source : | array_flow.rb:934:9:934:9 | [post] a [element] : | | array_flow.rb:934:18:934:29 | call to source : | array_flow.rb:934:9:934:44 | call to append [element] : | @@ -1683,12 +2114,16 @@ edges | array_flow.rb:937:10:937:10 | b [element] : | array_flow.rb:937:10:937:13 | ...[...] | | array_flow.rb:938:10:938:10 | b [element] : | array_flow.rb:938:10:938:13 | ...[...] | | array_flow.rb:938:10:938:10 | b [element] : | array_flow.rb:938:10:938:13 | ...[...] | -| array_flow.rb:944:10:944:19 | call to source : | array_flow.rb:945:16:945:16 | c [element 0] : | -| array_flow.rb:944:10:944:19 | call to source : | array_flow.rb:945:16:945:16 | c [element 0] : | -| array_flow.rb:945:16:945:16 | c [element 0] : | array_flow.rb:946:10:946:10 | d [element 2, element 0] : | -| array_flow.rb:945:16:945:16 | c [element 0] : | array_flow.rb:946:10:946:10 | d [element 2, element 0] : | -| array_flow.rb:945:16:945:16 | c [element 0] : | array_flow.rb:947:10:947:10 | d [element 2, element 0] : | -| array_flow.rb:945:16:945:16 | c [element 0] : | array_flow.rb:947:10:947:10 | d [element 2, element 0] : | +| array_flow.rb:944:5:944:5 | c [element 0] : | array_flow.rb:945:16:945:16 | c [element 0] : | +| array_flow.rb:944:5:944:5 | c [element 0] : | array_flow.rb:945:16:945:16 | c [element 0] : | +| array_flow.rb:944:10:944:19 | call to source : | array_flow.rb:944:5:944:5 | c [element 0] : | +| array_flow.rb:944:10:944:19 | call to source : | array_flow.rb:944:5:944:5 | c [element 0] : | +| array_flow.rb:945:5:945:5 | d [element 2, element 0] : | array_flow.rb:946:10:946:10 | d [element 2, element 0] : | +| array_flow.rb:945:5:945:5 | d [element 2, element 0] : | array_flow.rb:946:10:946:10 | d [element 2, element 0] : | +| array_flow.rb:945:5:945:5 | d [element 2, element 0] : | array_flow.rb:947:10:947:10 | d [element 2, element 0] : | +| array_flow.rb:945:5:945:5 | d [element 2, element 0] : | array_flow.rb:947:10:947:10 | d [element 2, element 0] : | +| array_flow.rb:945:16:945:16 | c [element 0] : | array_flow.rb:945:5:945:5 | d [element 2, element 0] : | +| array_flow.rb:945:16:945:16 | c [element 0] : | array_flow.rb:945:5:945:5 | d [element 2, element 0] : | | array_flow.rb:946:10:946:10 | d [element 2, element 0] : | array_flow.rb:946:10:946:22 | call to rassoc [element 0] : | | array_flow.rb:946:10:946:10 | d [element 2, element 0] : | array_flow.rb:946:10:946:22 | call to rassoc [element 0] : | | array_flow.rb:946:10:946:22 | call to rassoc [element 0] : | array_flow.rb:946:10:946:25 | ...[...] | @@ -1697,14 +2132,18 @@ edges | array_flow.rb:947:10:947:10 | d [element 2, element 0] : | array_flow.rb:947:10:947:22 | call to rassoc [element 0] : | | array_flow.rb:947:10:947:22 | call to rassoc [element 0] : | array_flow.rb:947:10:947:25 | ...[...] | | array_flow.rb:947:10:947:22 | call to rassoc [element 0] : | array_flow.rb:947:10:947:25 | ...[...] | -| array_flow.rb:951:10:951:21 | call to source : | array_flow.rb:952:9:952:9 | a [element 0] : | -| array_flow.rb:951:10:951:21 | call to source : | array_flow.rb:952:9:952:9 | a [element 0] : | -| array_flow.rb:951:10:951:21 | call to source : | array_flow.rb:957:9:957:9 | a [element 0] : | -| array_flow.rb:951:10:951:21 | call to source : | array_flow.rb:957:9:957:9 | a [element 0] : | -| array_flow.rb:951:27:951:38 | call to source : | array_flow.rb:952:9:952:9 | a [element 2] : | -| array_flow.rb:951:27:951:38 | call to source : | array_flow.rb:952:9:952:9 | a [element 2] : | -| array_flow.rb:951:27:951:38 | call to source : | array_flow.rb:957:9:957:9 | a [element 2] : | -| array_flow.rb:951:27:951:38 | call to source : | array_flow.rb:957:9:957:9 | a [element 2] : | +| array_flow.rb:951:5:951:5 | a [element 0] : | array_flow.rb:952:9:952:9 | a [element 0] : | +| array_flow.rb:951:5:951:5 | a [element 0] : | array_flow.rb:952:9:952:9 | a [element 0] : | +| array_flow.rb:951:5:951:5 | a [element 0] : | array_flow.rb:957:9:957:9 | a [element 0] : | +| array_flow.rb:951:5:951:5 | a [element 0] : | array_flow.rb:957:9:957:9 | a [element 0] : | +| array_flow.rb:951:5:951:5 | a [element 2] : | array_flow.rb:952:9:952:9 | a [element 2] : | +| array_flow.rb:951:5:951:5 | a [element 2] : | array_flow.rb:952:9:952:9 | a [element 2] : | +| array_flow.rb:951:5:951:5 | a [element 2] : | array_flow.rb:957:9:957:9 | a [element 2] : | +| array_flow.rb:951:5:951:5 | a [element 2] : | array_flow.rb:957:9:957:9 | a [element 2] : | +| array_flow.rb:951:10:951:21 | call to source : | array_flow.rb:951:5:951:5 | a [element 0] : | +| array_flow.rb:951:10:951:21 | call to source : | array_flow.rb:951:5:951:5 | a [element 0] : | +| array_flow.rb:951:27:951:38 | call to source : | array_flow.rb:951:5:951:5 | a [element 2] : | +| array_flow.rb:951:27:951:38 | call to source : | array_flow.rb:951:5:951:5 | a [element 2] : | | array_flow.rb:952:9:952:9 | a [element 0] : | array_flow.rb:952:22:952:22 | x : | | array_flow.rb:952:9:952:9 | a [element 0] : | array_flow.rb:952:22:952:22 | x : | | array_flow.rb:952:9:952:9 | a [element 2] : | array_flow.rb:952:25:952:25 | y : | @@ -1719,20 +2158,28 @@ edges | array_flow.rb:957:9:957:9 | a [element 2] : | array_flow.rb:957:28:957:28 | y : | | array_flow.rb:957:28:957:28 | y : | array_flow.rb:959:14:959:14 | y | | array_flow.rb:957:28:957:28 | y : | array_flow.rb:959:14:959:14 | y | -| array_flow.rb:965:16:965:25 | call to source : | array_flow.rb:966:9:966:9 | a [element 2] : | -| array_flow.rb:965:16:965:25 | call to source : | array_flow.rb:966:9:966:9 | a [element 2] : | +| array_flow.rb:965:5:965:5 | a [element 2] : | array_flow.rb:966:9:966:9 | a [element 2] : | +| array_flow.rb:965:5:965:5 | a [element 2] : | array_flow.rb:966:9:966:9 | a [element 2] : | +| array_flow.rb:965:16:965:25 | call to source : | array_flow.rb:965:5:965:5 | a [element 2] : | +| array_flow.rb:965:16:965:25 | call to source : | array_flow.rb:965:5:965:5 | a [element 2] : | +| array_flow.rb:966:5:966:5 | b [element] : | array_flow.rb:970:10:970:10 | b [element] : | +| array_flow.rb:966:5:966:5 | b [element] : | array_flow.rb:970:10:970:10 | b [element] : | | array_flow.rb:966:9:966:9 | a [element 2] : | array_flow.rb:966:9:969:7 | call to reject [element] : | | array_flow.rb:966:9:966:9 | a [element 2] : | array_flow.rb:966:9:969:7 | call to reject [element] : | | array_flow.rb:966:9:966:9 | a [element 2] : | array_flow.rb:966:22:966:22 | x : | | array_flow.rb:966:9:966:9 | a [element 2] : | array_flow.rb:966:22:966:22 | x : | -| array_flow.rb:966:9:969:7 | call to reject [element] : | array_flow.rb:970:10:970:10 | b [element] : | -| array_flow.rb:966:9:969:7 | call to reject [element] : | array_flow.rb:970:10:970:10 | b [element] : | +| array_flow.rb:966:9:969:7 | call to reject [element] : | array_flow.rb:966:5:966:5 | b [element] : | +| array_flow.rb:966:9:969:7 | call to reject [element] : | array_flow.rb:966:5:966:5 | b [element] : | | array_flow.rb:966:22:966:22 | x : | array_flow.rb:967:14:967:14 | x | | array_flow.rb:966:22:966:22 | x : | array_flow.rb:967:14:967:14 | x | | array_flow.rb:970:10:970:10 | b [element] : | array_flow.rb:970:10:970:13 | ...[...] | | array_flow.rb:970:10:970:10 | b [element] : | array_flow.rb:970:10:970:13 | ...[...] | -| array_flow.rb:974:16:974:25 | call to source : | array_flow.rb:975:9:975:9 | a [element 2] : | -| array_flow.rb:974:16:974:25 | call to source : | array_flow.rb:975:9:975:9 | a [element 2] : | +| array_flow.rb:974:5:974:5 | a [element 2] : | array_flow.rb:975:9:975:9 | a [element 2] : | +| array_flow.rb:974:5:974:5 | a [element 2] : | array_flow.rb:975:9:975:9 | a [element 2] : | +| array_flow.rb:974:16:974:25 | call to source : | array_flow.rb:974:5:974:5 | a [element 2] : | +| array_flow.rb:974:16:974:25 | call to source : | array_flow.rb:974:5:974:5 | a [element 2] : | +| array_flow.rb:975:5:975:5 | b [element] : | array_flow.rb:980:10:980:10 | b [element] : | +| array_flow.rb:975:5:975:5 | b [element] : | array_flow.rb:980:10:980:10 | b [element] : | | array_flow.rb:975:9:975:9 | [post] a [element] : | array_flow.rb:979:10:979:10 | a [element] : | | array_flow.rb:975:9:975:9 | [post] a [element] : | array_flow.rb:979:10:979:10 | a [element] : | | array_flow.rb:975:9:975:9 | a [element 2] : | array_flow.rb:975:9:975:9 | [post] a [element] : | @@ -1741,22 +2188,26 @@ edges | array_flow.rb:975:9:975:9 | a [element 2] : | array_flow.rb:975:9:978:7 | call to reject! [element] : | | array_flow.rb:975:9:975:9 | a [element 2] : | array_flow.rb:975:23:975:23 | x : | | array_flow.rb:975:9:975:9 | a [element 2] : | array_flow.rb:975:23:975:23 | x : | -| array_flow.rb:975:9:978:7 | call to reject! [element] : | array_flow.rb:980:10:980:10 | b [element] : | -| array_flow.rb:975:9:978:7 | call to reject! [element] : | array_flow.rb:980:10:980:10 | b [element] : | +| array_flow.rb:975:9:978:7 | call to reject! [element] : | array_flow.rb:975:5:975:5 | b [element] : | +| array_flow.rb:975:9:978:7 | call to reject! [element] : | array_flow.rb:975:5:975:5 | b [element] : | | array_flow.rb:975:23:975:23 | x : | array_flow.rb:976:14:976:14 | x | | array_flow.rb:975:23:975:23 | x : | array_flow.rb:976:14:976:14 | x | | array_flow.rb:979:10:979:10 | a [element] : | array_flow.rb:979:10:979:13 | ...[...] | | array_flow.rb:979:10:979:10 | a [element] : | array_flow.rb:979:10:979:13 | ...[...] | | array_flow.rb:980:10:980:10 | b [element] : | array_flow.rb:980:10:980:13 | ...[...] | | array_flow.rb:980:10:980:10 | b [element] : | array_flow.rb:980:10:980:13 | ...[...] | -| array_flow.rb:984:16:984:25 | call to source : | array_flow.rb:985:9:985:9 | a [element 2] : | -| array_flow.rb:984:16:984:25 | call to source : | array_flow.rb:985:9:985:9 | a [element 2] : | +| array_flow.rb:984:5:984:5 | a [element 2] : | array_flow.rb:985:9:985:9 | a [element 2] : | +| array_flow.rb:984:5:984:5 | a [element 2] : | array_flow.rb:985:9:985:9 | a [element 2] : | +| array_flow.rb:984:16:984:25 | call to source : | array_flow.rb:984:5:984:5 | a [element 2] : | +| array_flow.rb:984:16:984:25 | call to source : | array_flow.rb:984:5:984:5 | a [element 2] : | +| array_flow.rb:985:5:985:5 | b [element 2] : | array_flow.rb:990:10:990:10 | b [element 2] : | +| array_flow.rb:985:5:985:5 | b [element 2] : | array_flow.rb:990:10:990:10 | b [element 2] : | | array_flow.rb:985:9:985:9 | a [element 2] : | array_flow.rb:985:9:988:7 | call to repeated_combination [element 2] : | | array_flow.rb:985:9:985:9 | a [element 2] : | array_flow.rb:985:9:988:7 | call to repeated_combination [element 2] : | | array_flow.rb:985:9:985:9 | a [element 2] : | array_flow.rb:985:39:985:39 | x [element] : | | array_flow.rb:985:9:985:9 | a [element 2] : | array_flow.rb:985:39:985:39 | x [element] : | -| array_flow.rb:985:9:988:7 | call to repeated_combination [element 2] : | array_flow.rb:990:10:990:10 | b [element 2] : | -| array_flow.rb:985:9:988:7 | call to repeated_combination [element 2] : | array_flow.rb:990:10:990:10 | b [element 2] : | +| array_flow.rb:985:9:988:7 | call to repeated_combination [element 2] : | array_flow.rb:985:5:985:5 | b [element 2] : | +| array_flow.rb:985:9:988:7 | call to repeated_combination [element 2] : | array_flow.rb:985:5:985:5 | b [element 2] : | | array_flow.rb:985:39:985:39 | x [element] : | array_flow.rb:986:14:986:14 | x [element] : | | array_flow.rb:985:39:985:39 | x [element] : | array_flow.rb:986:14:986:14 | x [element] : | | array_flow.rb:985:39:985:39 | x [element] : | array_flow.rb:987:14:987:14 | x [element] : | @@ -1767,14 +2218,18 @@ edges | array_flow.rb:987:14:987:14 | x [element] : | array_flow.rb:987:14:987:17 | ...[...] | | array_flow.rb:990:10:990:10 | b [element 2] : | array_flow.rb:990:10:990:13 | ...[...] | | array_flow.rb:990:10:990:10 | b [element 2] : | array_flow.rb:990:10:990:13 | ...[...] | -| array_flow.rb:994:16:994:25 | call to source : | array_flow.rb:995:9:995:9 | a [element 2] : | -| array_flow.rb:994:16:994:25 | call to source : | array_flow.rb:995:9:995:9 | a [element 2] : | +| array_flow.rb:994:5:994:5 | a [element 2] : | array_flow.rb:995:9:995:9 | a [element 2] : | +| array_flow.rb:994:5:994:5 | a [element 2] : | array_flow.rb:995:9:995:9 | a [element 2] : | +| array_flow.rb:994:16:994:25 | call to source : | array_flow.rb:994:5:994:5 | a [element 2] : | +| array_flow.rb:994:16:994:25 | call to source : | array_flow.rb:994:5:994:5 | a [element 2] : | +| array_flow.rb:995:5:995:5 | b [element 2] : | array_flow.rb:1000:10:1000:10 | b [element 2] : | +| array_flow.rb:995:5:995:5 | b [element 2] : | array_flow.rb:1000:10:1000:10 | b [element 2] : | | array_flow.rb:995:9:995:9 | a [element 2] : | array_flow.rb:995:9:998:7 | call to repeated_permutation [element 2] : | | array_flow.rb:995:9:995:9 | a [element 2] : | array_flow.rb:995:9:998:7 | call to repeated_permutation [element 2] : | | array_flow.rb:995:9:995:9 | a [element 2] : | array_flow.rb:995:39:995:39 | x [element] : | | array_flow.rb:995:9:995:9 | a [element 2] : | array_flow.rb:995:39:995:39 | x [element] : | -| array_flow.rb:995:9:998:7 | call to repeated_permutation [element 2] : | array_flow.rb:1000:10:1000:10 | b [element 2] : | -| array_flow.rb:995:9:998:7 | call to repeated_permutation [element 2] : | array_flow.rb:1000:10:1000:10 | b [element 2] : | +| array_flow.rb:995:9:998:7 | call to repeated_permutation [element 2] : | array_flow.rb:995:5:995:5 | b [element 2] : | +| array_flow.rb:995:9:998:7 | call to repeated_permutation [element 2] : | array_flow.rb:995:5:995:5 | b [element 2] : | | array_flow.rb:995:39:995:39 | x [element] : | array_flow.rb:996:14:996:14 | x [element] : | | array_flow.rb:995:39:995:39 | x [element] : | array_flow.rb:996:14:996:14 | x [element] : | | array_flow.rb:995:39:995:39 | x [element] : | array_flow.rb:997:14:997:14 | x [element] : | @@ -1785,10 +2240,12 @@ edges | array_flow.rb:997:14:997:14 | x [element] : | array_flow.rb:997:14:997:17 | ...[...] | | array_flow.rb:1000:10:1000:10 | b [element 2] : | array_flow.rb:1000:10:1000:13 | ...[...] | | array_flow.rb:1000:10:1000:10 | b [element 2] : | array_flow.rb:1000:10:1000:13 | ...[...] | +| array_flow.rb:1006:5:1006:5 | b [element 0] : | array_flow.rb:1008:10:1008:10 | b [element 0] : | +| array_flow.rb:1006:5:1006:5 | b [element 0] : | array_flow.rb:1008:10:1008:10 | b [element 0] : | | array_flow.rb:1006:9:1006:9 | [post] a [element 0] : | array_flow.rb:1007:10:1007:10 | a [element 0] : | | array_flow.rb:1006:9:1006:9 | [post] a [element 0] : | array_flow.rb:1007:10:1007:10 | a [element 0] : | -| array_flow.rb:1006:9:1006:33 | call to replace [element 0] : | array_flow.rb:1008:10:1008:10 | b [element 0] : | -| array_flow.rb:1006:9:1006:33 | call to replace [element 0] : | array_flow.rb:1008:10:1008:10 | b [element 0] : | +| array_flow.rb:1006:9:1006:33 | call to replace [element 0] : | array_flow.rb:1006:5:1006:5 | b [element 0] : | +| array_flow.rb:1006:9:1006:33 | call to replace [element 0] : | array_flow.rb:1006:5:1006:5 | b [element 0] : | | array_flow.rb:1006:20:1006:31 | call to source : | array_flow.rb:1006:9:1006:9 | [post] a [element 0] : | | array_flow.rb:1006:20:1006:31 | call to source : | array_flow.rb:1006:9:1006:9 | [post] a [element 0] : | | array_flow.rb:1006:20:1006:31 | call to source : | array_flow.rb:1006:9:1006:33 | call to replace [element 0] : | @@ -1797,24 +2254,30 @@ edges | array_flow.rb:1007:10:1007:10 | a [element 0] : | array_flow.rb:1007:10:1007:13 | ...[...] | | array_flow.rb:1008:10:1008:10 | b [element 0] : | array_flow.rb:1008:10:1008:13 | ...[...] | | array_flow.rb:1008:10:1008:10 | b [element 0] : | array_flow.rb:1008:10:1008:13 | ...[...] | -| array_flow.rb:1012:16:1012:28 | call to source : | array_flow.rb:1013:9:1013:9 | a [element 2] : | -| array_flow.rb:1012:16:1012:28 | call to source : | array_flow.rb:1013:9:1013:9 | a [element 2] : | -| array_flow.rb:1012:16:1012:28 | call to source : | array_flow.rb:1018:10:1018:10 | a [element 2] : | -| array_flow.rb:1012:16:1012:28 | call to source : | array_flow.rb:1018:10:1018:10 | a [element 2] : | -| array_flow.rb:1012:31:1012:43 | call to source : | array_flow.rb:1013:9:1013:9 | a [element 3] : | -| array_flow.rb:1012:31:1012:43 | call to source : | array_flow.rb:1013:9:1013:9 | a [element 3] : | -| array_flow.rb:1012:31:1012:43 | call to source : | array_flow.rb:1019:10:1019:10 | a [element 3] : | -| array_flow.rb:1012:31:1012:43 | call to source : | array_flow.rb:1019:10:1019:10 | a [element 3] : | +| array_flow.rb:1012:5:1012:5 | a [element 2] : | array_flow.rb:1013:9:1013:9 | a [element 2] : | +| array_flow.rb:1012:5:1012:5 | a [element 2] : | array_flow.rb:1013:9:1013:9 | a [element 2] : | +| array_flow.rb:1012:5:1012:5 | a [element 2] : | array_flow.rb:1018:10:1018:10 | a [element 2] : | +| array_flow.rb:1012:5:1012:5 | a [element 2] : | array_flow.rb:1018:10:1018:10 | a [element 2] : | +| array_flow.rb:1012:5:1012:5 | a [element 3] : | array_flow.rb:1013:9:1013:9 | a [element 3] : | +| array_flow.rb:1012:5:1012:5 | a [element 3] : | array_flow.rb:1013:9:1013:9 | a [element 3] : | +| array_flow.rb:1012:5:1012:5 | a [element 3] : | array_flow.rb:1019:10:1019:10 | a [element 3] : | +| array_flow.rb:1012:5:1012:5 | a [element 3] : | array_flow.rb:1019:10:1019:10 | a [element 3] : | +| array_flow.rb:1012:16:1012:28 | call to source : | array_flow.rb:1012:5:1012:5 | a [element 2] : | +| array_flow.rb:1012:16:1012:28 | call to source : | array_flow.rb:1012:5:1012:5 | a [element 2] : | +| array_flow.rb:1012:31:1012:43 | call to source : | array_flow.rb:1012:5:1012:5 | a [element 3] : | +| array_flow.rb:1012:31:1012:43 | call to source : | array_flow.rb:1012:5:1012:5 | a [element 3] : | +| array_flow.rb:1013:5:1013:5 | b [element] : | array_flow.rb:1014:10:1014:10 | b [element] : | +| array_flow.rb:1013:5:1013:5 | b [element] : | array_flow.rb:1014:10:1014:10 | b [element] : | +| array_flow.rb:1013:5:1013:5 | b [element] : | array_flow.rb:1015:10:1015:10 | b [element] : | +| array_flow.rb:1013:5:1013:5 | b [element] : | array_flow.rb:1015:10:1015:10 | b [element] : | +| array_flow.rb:1013:5:1013:5 | b [element] : | array_flow.rb:1016:10:1016:10 | b [element] : | +| array_flow.rb:1013:5:1013:5 | b [element] : | array_flow.rb:1016:10:1016:10 | b [element] : | | array_flow.rb:1013:9:1013:9 | a [element 2] : | array_flow.rb:1013:9:1013:17 | call to reverse [element] : | | array_flow.rb:1013:9:1013:9 | a [element 2] : | array_flow.rb:1013:9:1013:17 | call to reverse [element] : | | array_flow.rb:1013:9:1013:9 | a [element 3] : | array_flow.rb:1013:9:1013:17 | call to reverse [element] : | | array_flow.rb:1013:9:1013:9 | a [element 3] : | array_flow.rb:1013:9:1013:17 | call to reverse [element] : | -| array_flow.rb:1013:9:1013:17 | call to reverse [element] : | array_flow.rb:1014:10:1014:10 | b [element] : | -| array_flow.rb:1013:9:1013:17 | call to reverse [element] : | array_flow.rb:1014:10:1014:10 | b [element] : | -| array_flow.rb:1013:9:1013:17 | call to reverse [element] : | array_flow.rb:1015:10:1015:10 | b [element] : | -| array_flow.rb:1013:9:1013:17 | call to reverse [element] : | array_flow.rb:1015:10:1015:10 | b [element] : | -| array_flow.rb:1013:9:1013:17 | call to reverse [element] : | array_flow.rb:1016:10:1016:10 | b [element] : | -| array_flow.rb:1013:9:1013:17 | call to reverse [element] : | array_flow.rb:1016:10:1016:10 | b [element] : | +| array_flow.rb:1013:9:1013:17 | call to reverse [element] : | array_flow.rb:1013:5:1013:5 | b [element] : | +| array_flow.rb:1013:9:1013:17 | call to reverse [element] : | array_flow.rb:1013:5:1013:5 | b [element] : | | array_flow.rb:1014:10:1014:10 | b [element] : | array_flow.rb:1014:10:1014:13 | ...[...] | | array_flow.rb:1014:10:1014:10 | b [element] : | array_flow.rb:1014:10:1014:13 | ...[...] | | array_flow.rb:1015:10:1015:10 | b [element] : | array_flow.rb:1015:10:1015:13 | ...[...] | @@ -1825,14 +2288,24 @@ edges | array_flow.rb:1018:10:1018:10 | a [element 2] : | array_flow.rb:1018:10:1018:13 | ...[...] | | array_flow.rb:1019:10:1019:10 | a [element 3] : | array_flow.rb:1019:10:1019:13 | ...[...] | | array_flow.rb:1019:10:1019:10 | a [element 3] : | array_flow.rb:1019:10:1019:13 | ...[...] | -| array_flow.rb:1023:16:1023:28 | call to source : | array_flow.rb:1024:9:1024:9 | a [element 2] : | -| array_flow.rb:1023:16:1023:28 | call to source : | array_flow.rb:1024:9:1024:9 | a [element 2] : | -| array_flow.rb:1023:16:1023:28 | call to source : | array_flow.rb:1029:10:1029:10 | a [element 2] : | -| array_flow.rb:1023:16:1023:28 | call to source : | array_flow.rb:1029:10:1029:10 | a [element 2] : | -| array_flow.rb:1023:31:1023:43 | call to source : | array_flow.rb:1024:9:1024:9 | a [element 3] : | -| array_flow.rb:1023:31:1023:43 | call to source : | array_flow.rb:1024:9:1024:9 | a [element 3] : | -| array_flow.rb:1023:31:1023:43 | call to source : | array_flow.rb:1030:10:1030:10 | a [element 3] : | -| array_flow.rb:1023:31:1023:43 | call to source : | array_flow.rb:1030:10:1030:10 | a [element 3] : | +| array_flow.rb:1023:5:1023:5 | a [element 2] : | array_flow.rb:1024:9:1024:9 | a [element 2] : | +| array_flow.rb:1023:5:1023:5 | a [element 2] : | array_flow.rb:1024:9:1024:9 | a [element 2] : | +| array_flow.rb:1023:5:1023:5 | a [element 2] : | array_flow.rb:1029:10:1029:10 | a [element 2] : | +| array_flow.rb:1023:5:1023:5 | a [element 2] : | array_flow.rb:1029:10:1029:10 | a [element 2] : | +| array_flow.rb:1023:5:1023:5 | a [element 3] : | array_flow.rb:1024:9:1024:9 | a [element 3] : | +| array_flow.rb:1023:5:1023:5 | a [element 3] : | array_flow.rb:1024:9:1024:9 | a [element 3] : | +| array_flow.rb:1023:5:1023:5 | a [element 3] : | array_flow.rb:1030:10:1030:10 | a [element 3] : | +| array_flow.rb:1023:5:1023:5 | a [element 3] : | array_flow.rb:1030:10:1030:10 | a [element 3] : | +| array_flow.rb:1023:16:1023:28 | call to source : | array_flow.rb:1023:5:1023:5 | a [element 2] : | +| array_flow.rb:1023:16:1023:28 | call to source : | array_flow.rb:1023:5:1023:5 | a [element 2] : | +| array_flow.rb:1023:31:1023:43 | call to source : | array_flow.rb:1023:5:1023:5 | a [element 3] : | +| array_flow.rb:1023:31:1023:43 | call to source : | array_flow.rb:1023:5:1023:5 | a [element 3] : | +| array_flow.rb:1024:5:1024:5 | b [element] : | array_flow.rb:1025:10:1025:10 | b [element] : | +| array_flow.rb:1024:5:1024:5 | b [element] : | array_flow.rb:1025:10:1025:10 | b [element] : | +| array_flow.rb:1024:5:1024:5 | b [element] : | array_flow.rb:1026:10:1026:10 | b [element] : | +| array_flow.rb:1024:5:1024:5 | b [element] : | array_flow.rb:1026:10:1026:10 | b [element] : | +| array_flow.rb:1024:5:1024:5 | b [element] : | array_flow.rb:1027:10:1027:10 | b [element] : | +| array_flow.rb:1024:5:1024:5 | b [element] : | array_flow.rb:1027:10:1027:10 | b [element] : | | array_flow.rb:1024:9:1024:9 | [post] a [element] : | array_flow.rb:1028:10:1028:10 | a [element] : | | array_flow.rb:1024:9:1024:9 | [post] a [element] : | array_flow.rb:1028:10:1028:10 | a [element] : | | array_flow.rb:1024:9:1024:9 | [post] a [element] : | array_flow.rb:1029:10:1029:10 | a [element] : | @@ -1847,12 +2320,8 @@ edges | array_flow.rb:1024:9:1024:9 | a [element 3] : | array_flow.rb:1024:9:1024:9 | [post] a [element] : | | array_flow.rb:1024:9:1024:9 | a [element 3] : | array_flow.rb:1024:9:1024:18 | call to reverse! [element] : | | array_flow.rb:1024:9:1024:9 | a [element 3] : | array_flow.rb:1024:9:1024:18 | call to reverse! [element] : | -| array_flow.rb:1024:9:1024:18 | call to reverse! [element] : | array_flow.rb:1025:10:1025:10 | b [element] : | -| array_flow.rb:1024:9:1024:18 | call to reverse! [element] : | array_flow.rb:1025:10:1025:10 | b [element] : | -| array_flow.rb:1024:9:1024:18 | call to reverse! [element] : | array_flow.rb:1026:10:1026:10 | b [element] : | -| array_flow.rb:1024:9:1024:18 | call to reverse! [element] : | array_flow.rb:1026:10:1026:10 | b [element] : | -| array_flow.rb:1024:9:1024:18 | call to reverse! [element] : | array_flow.rb:1027:10:1027:10 | b [element] : | -| array_flow.rb:1024:9:1024:18 | call to reverse! [element] : | array_flow.rb:1027:10:1027:10 | b [element] : | +| array_flow.rb:1024:9:1024:18 | call to reverse! [element] : | array_flow.rb:1024:5:1024:5 | b [element] : | +| array_flow.rb:1024:9:1024:18 | call to reverse! [element] : | array_flow.rb:1024:5:1024:5 | b [element] : | | array_flow.rb:1025:10:1025:10 | b [element] : | array_flow.rb:1025:10:1025:13 | ...[...] | | array_flow.rb:1025:10:1025:10 | b [element] : | array_flow.rb:1025:10:1025:13 | ...[...] | | array_flow.rb:1026:10:1026:10 | b [element] : | array_flow.rb:1026:10:1026:13 | ...[...] | @@ -1869,66 +2338,84 @@ edges | array_flow.rb:1030:10:1030:10 | a [element 3] : | array_flow.rb:1030:10:1030:13 | ...[...] | | array_flow.rb:1030:10:1030:10 | a [element] : | array_flow.rb:1030:10:1030:13 | ...[...] | | array_flow.rb:1030:10:1030:10 | a [element] : | array_flow.rb:1030:10:1030:13 | ...[...] | -| array_flow.rb:1034:16:1034:26 | call to source : | array_flow.rb:1035:9:1035:9 | a [element 2] : | -| array_flow.rb:1034:16:1034:26 | call to source : | array_flow.rb:1035:9:1035:9 | a [element 2] : | +| array_flow.rb:1034:5:1034:5 | a [element 2] : | array_flow.rb:1035:9:1035:9 | a [element 2] : | +| array_flow.rb:1034:5:1034:5 | a [element 2] : | array_flow.rb:1035:9:1035:9 | a [element 2] : | +| array_flow.rb:1034:16:1034:26 | call to source : | array_flow.rb:1034:5:1034:5 | a [element 2] : | +| array_flow.rb:1034:16:1034:26 | call to source : | array_flow.rb:1034:5:1034:5 | a [element 2] : | +| array_flow.rb:1035:5:1035:5 | b [element 2] : | array_flow.rb:1038:10:1038:10 | b [element 2] : | +| array_flow.rb:1035:5:1035:5 | b [element 2] : | array_flow.rb:1038:10:1038:10 | b [element 2] : | | array_flow.rb:1035:9:1035:9 | a [element 2] : | array_flow.rb:1035:9:1037:7 | call to reverse_each [element 2] : | | array_flow.rb:1035:9:1035:9 | a [element 2] : | array_flow.rb:1035:9:1037:7 | call to reverse_each [element 2] : | | array_flow.rb:1035:9:1035:9 | a [element 2] : | array_flow.rb:1035:28:1035:28 | x : | | array_flow.rb:1035:9:1035:9 | a [element 2] : | array_flow.rb:1035:28:1035:28 | x : | -| array_flow.rb:1035:9:1037:7 | call to reverse_each [element 2] : | array_flow.rb:1038:10:1038:10 | b [element 2] : | -| array_flow.rb:1035:9:1037:7 | call to reverse_each [element 2] : | array_flow.rb:1038:10:1038:10 | b [element 2] : | +| array_flow.rb:1035:9:1037:7 | call to reverse_each [element 2] : | array_flow.rb:1035:5:1035:5 | b [element 2] : | +| array_flow.rb:1035:9:1037:7 | call to reverse_each [element 2] : | array_flow.rb:1035:5:1035:5 | b [element 2] : | | array_flow.rb:1035:28:1035:28 | x : | array_flow.rb:1036:14:1036:14 | x | | array_flow.rb:1035:28:1035:28 | x : | array_flow.rb:1036:14:1036:14 | x | | array_flow.rb:1038:10:1038:10 | b [element 2] : | array_flow.rb:1038:10:1038:13 | ...[...] | | array_flow.rb:1038:10:1038:10 | b [element 2] : | array_flow.rb:1038:10:1038:13 | ...[...] | -| array_flow.rb:1042:16:1042:26 | call to source : | array_flow.rb:1043:5:1043:5 | a [element 2] : | -| array_flow.rb:1042:16:1042:26 | call to source : | array_flow.rb:1043:5:1043:5 | a [element 2] : | +| array_flow.rb:1042:5:1042:5 | a [element 2] : | array_flow.rb:1043:5:1043:5 | a [element 2] : | +| array_flow.rb:1042:5:1042:5 | a [element 2] : | array_flow.rb:1043:5:1043:5 | a [element 2] : | +| array_flow.rb:1042:16:1042:26 | call to source : | array_flow.rb:1042:5:1042:5 | a [element 2] : | +| array_flow.rb:1042:16:1042:26 | call to source : | array_flow.rb:1042:5:1042:5 | a [element 2] : | | array_flow.rb:1043:5:1043:5 | a [element 2] : | array_flow.rb:1043:18:1043:18 | x : | | array_flow.rb:1043:5:1043:5 | a [element 2] : | array_flow.rb:1043:18:1043:18 | x : | | array_flow.rb:1043:18:1043:18 | x : | array_flow.rb:1044:14:1044:14 | x | | array_flow.rb:1043:18:1043:18 | x : | array_flow.rb:1044:14:1044:14 | x | -| array_flow.rb:1052:10:1052:22 | call to source : | array_flow.rb:1054:9:1054:9 | a [element 0] : | -| array_flow.rb:1052:10:1052:22 | call to source : | array_flow.rb:1054:9:1054:9 | a [element 0] : | -| array_flow.rb:1052:10:1052:22 | call to source : | array_flow.rb:1060:9:1060:9 | a [element 0] : | -| array_flow.rb:1052:10:1052:22 | call to source : | array_flow.rb:1060:9:1060:9 | a [element 0] : | -| array_flow.rb:1052:10:1052:22 | call to source : | array_flow.rb:1066:9:1066:9 | a [element 0] : | -| array_flow.rb:1052:10:1052:22 | call to source : | array_flow.rb:1066:9:1066:9 | a [element 0] : | -| array_flow.rb:1052:10:1052:22 | call to source : | array_flow.rb:1072:9:1072:9 | a [element 0] : | -| array_flow.rb:1052:10:1052:22 | call to source : | array_flow.rb:1072:9:1072:9 | a [element 0] : | -| array_flow.rb:1052:28:1052:40 | call to source : | array_flow.rb:1054:9:1054:9 | a [element 2] : | -| array_flow.rb:1052:28:1052:40 | call to source : | array_flow.rb:1054:9:1054:9 | a [element 2] : | -| array_flow.rb:1052:28:1052:40 | call to source : | array_flow.rb:1060:9:1060:9 | a [element 2] : | -| array_flow.rb:1052:28:1052:40 | call to source : | array_flow.rb:1060:9:1060:9 | a [element 2] : | -| array_flow.rb:1052:28:1052:40 | call to source : | array_flow.rb:1066:9:1066:9 | a [element 2] : | -| array_flow.rb:1052:28:1052:40 | call to source : | array_flow.rb:1066:9:1066:9 | a [element 2] : | -| array_flow.rb:1052:28:1052:40 | call to source : | array_flow.rb:1072:9:1072:9 | a [element 2] : | -| array_flow.rb:1052:28:1052:40 | call to source : | array_flow.rb:1072:9:1072:9 | a [element 2] : | -| array_flow.rb:1052:43:1052:55 | call to source : | array_flow.rb:1054:9:1054:9 | a [element 3] : | -| array_flow.rb:1052:43:1052:55 | call to source : | array_flow.rb:1054:9:1054:9 | a [element 3] : | -| array_flow.rb:1052:43:1052:55 | call to source : | array_flow.rb:1060:9:1060:9 | a [element 3] : | -| array_flow.rb:1052:43:1052:55 | call to source : | array_flow.rb:1060:9:1060:9 | a [element 3] : | -| array_flow.rb:1052:43:1052:55 | call to source : | array_flow.rb:1066:9:1066:9 | a [element 3] : | -| array_flow.rb:1052:43:1052:55 | call to source : | array_flow.rb:1066:9:1066:9 | a [element 3] : | -| array_flow.rb:1052:43:1052:55 | call to source : | array_flow.rb:1072:9:1072:9 | a [element 3] : | -| array_flow.rb:1052:43:1052:55 | call to source : | array_flow.rb:1072:9:1072:9 | a [element 3] : | +| array_flow.rb:1052:5:1052:5 | a [element 0] : | array_flow.rb:1054:9:1054:9 | a [element 0] : | +| array_flow.rb:1052:5:1052:5 | a [element 0] : | array_flow.rb:1054:9:1054:9 | a [element 0] : | +| array_flow.rb:1052:5:1052:5 | a [element 0] : | array_flow.rb:1060:9:1060:9 | a [element 0] : | +| array_flow.rb:1052:5:1052:5 | a [element 0] : | array_flow.rb:1060:9:1060:9 | a [element 0] : | +| array_flow.rb:1052:5:1052:5 | a [element 0] : | array_flow.rb:1066:9:1066:9 | a [element 0] : | +| array_flow.rb:1052:5:1052:5 | a [element 0] : | array_flow.rb:1066:9:1066:9 | a [element 0] : | +| array_flow.rb:1052:5:1052:5 | a [element 0] : | array_flow.rb:1072:9:1072:9 | a [element 0] : | +| array_flow.rb:1052:5:1052:5 | a [element 0] : | array_flow.rb:1072:9:1072:9 | a [element 0] : | +| array_flow.rb:1052:5:1052:5 | a [element 2] : | array_flow.rb:1054:9:1054:9 | a [element 2] : | +| array_flow.rb:1052:5:1052:5 | a [element 2] : | array_flow.rb:1054:9:1054:9 | a [element 2] : | +| array_flow.rb:1052:5:1052:5 | a [element 2] : | array_flow.rb:1060:9:1060:9 | a [element 2] : | +| array_flow.rb:1052:5:1052:5 | a [element 2] : | array_flow.rb:1060:9:1060:9 | a [element 2] : | +| array_flow.rb:1052:5:1052:5 | a [element 2] : | array_flow.rb:1066:9:1066:9 | a [element 2] : | +| array_flow.rb:1052:5:1052:5 | a [element 2] : | array_flow.rb:1066:9:1066:9 | a [element 2] : | +| array_flow.rb:1052:5:1052:5 | a [element 2] : | array_flow.rb:1072:9:1072:9 | a [element 2] : | +| array_flow.rb:1052:5:1052:5 | a [element 2] : | array_flow.rb:1072:9:1072:9 | a [element 2] : | +| array_flow.rb:1052:5:1052:5 | a [element 3] : | array_flow.rb:1054:9:1054:9 | a [element 3] : | +| array_flow.rb:1052:5:1052:5 | a [element 3] : | array_flow.rb:1054:9:1054:9 | a [element 3] : | +| array_flow.rb:1052:5:1052:5 | a [element 3] : | array_flow.rb:1060:9:1060:9 | a [element 3] : | +| array_flow.rb:1052:5:1052:5 | a [element 3] : | array_flow.rb:1060:9:1060:9 | a [element 3] : | +| array_flow.rb:1052:5:1052:5 | a [element 3] : | array_flow.rb:1066:9:1066:9 | a [element 3] : | +| array_flow.rb:1052:5:1052:5 | a [element 3] : | array_flow.rb:1066:9:1066:9 | a [element 3] : | +| array_flow.rb:1052:5:1052:5 | a [element 3] : | array_flow.rb:1072:9:1072:9 | a [element 3] : | +| array_flow.rb:1052:5:1052:5 | a [element 3] : | array_flow.rb:1072:9:1072:9 | a [element 3] : | +| array_flow.rb:1052:10:1052:22 | call to source : | array_flow.rb:1052:5:1052:5 | a [element 0] : | +| array_flow.rb:1052:10:1052:22 | call to source : | array_flow.rb:1052:5:1052:5 | a [element 0] : | +| array_flow.rb:1052:28:1052:40 | call to source : | array_flow.rb:1052:5:1052:5 | a [element 2] : | +| array_flow.rb:1052:28:1052:40 | call to source : | array_flow.rb:1052:5:1052:5 | a [element 2] : | +| array_flow.rb:1052:43:1052:55 | call to source : | array_flow.rb:1052:5:1052:5 | a [element 3] : | +| array_flow.rb:1052:43:1052:55 | call to source : | array_flow.rb:1052:5:1052:5 | a [element 3] : | +| array_flow.rb:1054:5:1054:5 | b [element 1] : | array_flow.rb:1056:10:1056:10 | b [element 1] : | +| array_flow.rb:1054:5:1054:5 | b [element 1] : | array_flow.rb:1056:10:1056:10 | b [element 1] : | +| array_flow.rb:1054:5:1054:5 | b [element 2] : | array_flow.rb:1057:10:1057:10 | b [element 2] : | +| array_flow.rb:1054:5:1054:5 | b [element 2] : | array_flow.rb:1057:10:1057:10 | b [element 2] : | +| array_flow.rb:1054:5:1054:5 | b [element] : | array_flow.rb:1055:10:1055:10 | b [element] : | +| array_flow.rb:1054:5:1054:5 | b [element] : | array_flow.rb:1055:10:1055:10 | b [element] : | +| array_flow.rb:1054:5:1054:5 | b [element] : | array_flow.rb:1056:10:1056:10 | b [element] : | +| array_flow.rb:1054:5:1054:5 | b [element] : | array_flow.rb:1056:10:1056:10 | b [element] : | +| array_flow.rb:1054:5:1054:5 | b [element] : | array_flow.rb:1057:10:1057:10 | b [element] : | +| array_flow.rb:1054:5:1054:5 | b [element] : | array_flow.rb:1057:10:1057:10 | b [element] : | +| array_flow.rb:1054:5:1054:5 | b [element] : | array_flow.rb:1058:10:1058:10 | b [element] : | +| array_flow.rb:1054:5:1054:5 | b [element] : | array_flow.rb:1058:10:1058:10 | b [element] : | | array_flow.rb:1054:9:1054:9 | a [element 0] : | array_flow.rb:1054:9:1054:16 | call to rotate [element] : | | array_flow.rb:1054:9:1054:9 | a [element 0] : | array_flow.rb:1054:9:1054:16 | call to rotate [element] : | | array_flow.rb:1054:9:1054:9 | a [element 2] : | array_flow.rb:1054:9:1054:16 | call to rotate [element 1] : | | array_flow.rb:1054:9:1054:9 | a [element 2] : | array_flow.rb:1054:9:1054:16 | call to rotate [element 1] : | | array_flow.rb:1054:9:1054:9 | a [element 3] : | array_flow.rb:1054:9:1054:16 | call to rotate [element 2] : | | array_flow.rb:1054:9:1054:9 | a [element 3] : | array_flow.rb:1054:9:1054:16 | call to rotate [element 2] : | -| array_flow.rb:1054:9:1054:16 | call to rotate [element 1] : | array_flow.rb:1056:10:1056:10 | b [element 1] : | -| array_flow.rb:1054:9:1054:16 | call to rotate [element 1] : | array_flow.rb:1056:10:1056:10 | b [element 1] : | -| array_flow.rb:1054:9:1054:16 | call to rotate [element 2] : | array_flow.rb:1057:10:1057:10 | b [element 2] : | -| array_flow.rb:1054:9:1054:16 | call to rotate [element 2] : | array_flow.rb:1057:10:1057:10 | b [element 2] : | -| array_flow.rb:1054:9:1054:16 | call to rotate [element] : | array_flow.rb:1055:10:1055:10 | b [element] : | -| array_flow.rb:1054:9:1054:16 | call to rotate [element] : | array_flow.rb:1055:10:1055:10 | b [element] : | -| array_flow.rb:1054:9:1054:16 | call to rotate [element] : | array_flow.rb:1056:10:1056:10 | b [element] : | -| array_flow.rb:1054:9:1054:16 | call to rotate [element] : | array_flow.rb:1056:10:1056:10 | b [element] : | -| array_flow.rb:1054:9:1054:16 | call to rotate [element] : | array_flow.rb:1057:10:1057:10 | b [element] : | -| array_flow.rb:1054:9:1054:16 | call to rotate [element] : | array_flow.rb:1057:10:1057:10 | b [element] : | -| array_flow.rb:1054:9:1054:16 | call to rotate [element] : | array_flow.rb:1058:10:1058:10 | b [element] : | -| array_flow.rb:1054:9:1054:16 | call to rotate [element] : | array_flow.rb:1058:10:1058:10 | b [element] : | +| array_flow.rb:1054:9:1054:16 | call to rotate [element 1] : | array_flow.rb:1054:5:1054:5 | b [element 1] : | +| array_flow.rb:1054:9:1054:16 | call to rotate [element 1] : | array_flow.rb:1054:5:1054:5 | b [element 1] : | +| array_flow.rb:1054:9:1054:16 | call to rotate [element 2] : | array_flow.rb:1054:5:1054:5 | b [element 2] : | +| array_flow.rb:1054:9:1054:16 | call to rotate [element 2] : | array_flow.rb:1054:5:1054:5 | b [element 2] : | +| array_flow.rb:1054:9:1054:16 | call to rotate [element] : | array_flow.rb:1054:5:1054:5 | b [element] : | +| array_flow.rb:1054:9:1054:16 | call to rotate [element] : | array_flow.rb:1054:5:1054:5 | b [element] : | | array_flow.rb:1055:10:1055:10 | b [element] : | array_flow.rb:1055:10:1055:13 | ...[...] | | array_flow.rb:1055:10:1055:10 | b [element] : | array_flow.rb:1055:10:1055:13 | ...[...] | | array_flow.rb:1056:10:1056:10 | b [element 1] : | array_flow.rb:1056:10:1056:13 | ...[...] | @@ -1941,24 +2428,30 @@ edges | array_flow.rb:1057:10:1057:10 | b [element] : | array_flow.rb:1057:10:1057:13 | ...[...] | | array_flow.rb:1058:10:1058:10 | b [element] : | array_flow.rb:1058:10:1058:13 | ...[...] | | array_flow.rb:1058:10:1058:10 | b [element] : | array_flow.rb:1058:10:1058:13 | ...[...] | +| array_flow.rb:1060:5:1060:5 | b [element 0] : | array_flow.rb:1061:10:1061:10 | b [element 0] : | +| array_flow.rb:1060:5:1060:5 | b [element 0] : | array_flow.rb:1061:10:1061:10 | b [element 0] : | +| array_flow.rb:1060:5:1060:5 | b [element 1] : | array_flow.rb:1062:10:1062:10 | b [element 1] : | +| array_flow.rb:1060:5:1060:5 | b [element 1] : | array_flow.rb:1062:10:1062:10 | b [element 1] : | +| array_flow.rb:1060:5:1060:5 | b [element] : | array_flow.rb:1061:10:1061:10 | b [element] : | +| array_flow.rb:1060:5:1060:5 | b [element] : | array_flow.rb:1061:10:1061:10 | b [element] : | +| array_flow.rb:1060:5:1060:5 | b [element] : | array_flow.rb:1062:10:1062:10 | b [element] : | +| array_flow.rb:1060:5:1060:5 | b [element] : | array_flow.rb:1062:10:1062:10 | b [element] : | +| array_flow.rb:1060:5:1060:5 | b [element] : | array_flow.rb:1063:10:1063:10 | b [element] : | +| array_flow.rb:1060:5:1060:5 | b [element] : | array_flow.rb:1063:10:1063:10 | b [element] : | +| array_flow.rb:1060:5:1060:5 | b [element] : | array_flow.rb:1064:10:1064:10 | b [element] : | +| array_flow.rb:1060:5:1060:5 | b [element] : | array_flow.rb:1064:10:1064:10 | b [element] : | | array_flow.rb:1060:9:1060:9 | a [element 0] : | array_flow.rb:1060:9:1060:19 | call to rotate [element] : | | array_flow.rb:1060:9:1060:9 | a [element 0] : | array_flow.rb:1060:9:1060:19 | call to rotate [element] : | | array_flow.rb:1060:9:1060:9 | a [element 2] : | array_flow.rb:1060:9:1060:19 | call to rotate [element 0] : | | array_flow.rb:1060:9:1060:9 | a [element 2] : | array_flow.rb:1060:9:1060:19 | call to rotate [element 0] : | | array_flow.rb:1060:9:1060:9 | a [element 3] : | array_flow.rb:1060:9:1060:19 | call to rotate [element 1] : | | array_flow.rb:1060:9:1060:9 | a [element 3] : | array_flow.rb:1060:9:1060:19 | call to rotate [element 1] : | -| array_flow.rb:1060:9:1060:19 | call to rotate [element 0] : | array_flow.rb:1061:10:1061:10 | b [element 0] : | -| array_flow.rb:1060:9:1060:19 | call to rotate [element 0] : | array_flow.rb:1061:10:1061:10 | b [element 0] : | -| array_flow.rb:1060:9:1060:19 | call to rotate [element 1] : | array_flow.rb:1062:10:1062:10 | b [element 1] : | -| array_flow.rb:1060:9:1060:19 | call to rotate [element 1] : | array_flow.rb:1062:10:1062:10 | b [element 1] : | -| array_flow.rb:1060:9:1060:19 | call to rotate [element] : | array_flow.rb:1061:10:1061:10 | b [element] : | -| array_flow.rb:1060:9:1060:19 | call to rotate [element] : | array_flow.rb:1061:10:1061:10 | b [element] : | -| array_flow.rb:1060:9:1060:19 | call to rotate [element] : | array_flow.rb:1062:10:1062:10 | b [element] : | -| array_flow.rb:1060:9:1060:19 | call to rotate [element] : | array_flow.rb:1062:10:1062:10 | b [element] : | -| array_flow.rb:1060:9:1060:19 | call to rotate [element] : | array_flow.rb:1063:10:1063:10 | b [element] : | -| array_flow.rb:1060:9:1060:19 | call to rotate [element] : | array_flow.rb:1063:10:1063:10 | b [element] : | -| array_flow.rb:1060:9:1060:19 | call to rotate [element] : | array_flow.rb:1064:10:1064:10 | b [element] : | -| array_flow.rb:1060:9:1060:19 | call to rotate [element] : | array_flow.rb:1064:10:1064:10 | b [element] : | +| array_flow.rb:1060:9:1060:19 | call to rotate [element 0] : | array_flow.rb:1060:5:1060:5 | b [element 0] : | +| array_flow.rb:1060:9:1060:19 | call to rotate [element 0] : | array_flow.rb:1060:5:1060:5 | b [element 0] : | +| array_flow.rb:1060:9:1060:19 | call to rotate [element 1] : | array_flow.rb:1060:5:1060:5 | b [element 1] : | +| array_flow.rb:1060:9:1060:19 | call to rotate [element 1] : | array_flow.rb:1060:5:1060:5 | b [element 1] : | +| array_flow.rb:1060:9:1060:19 | call to rotate [element] : | array_flow.rb:1060:5:1060:5 | b [element] : | +| array_flow.rb:1060:9:1060:19 | call to rotate [element] : | array_flow.rb:1060:5:1060:5 | b [element] : | | array_flow.rb:1061:10:1061:10 | b [element 0] : | array_flow.rb:1061:10:1061:13 | ...[...] | | array_flow.rb:1061:10:1061:10 | b [element 0] : | array_flow.rb:1061:10:1061:13 | ...[...] | | array_flow.rb:1061:10:1061:10 | b [element] : | array_flow.rb:1061:10:1061:13 | ...[...] | @@ -1971,38 +2464,46 @@ edges | array_flow.rb:1063:10:1063:10 | b [element] : | array_flow.rb:1063:10:1063:13 | ...[...] | | array_flow.rb:1064:10:1064:10 | b [element] : | array_flow.rb:1064:10:1064:13 | ...[...] | | array_flow.rb:1064:10:1064:10 | b [element] : | array_flow.rb:1064:10:1064:13 | ...[...] | +| array_flow.rb:1066:5:1066:5 | b [element 0] : | array_flow.rb:1067:10:1067:10 | b [element 0] : | +| array_flow.rb:1066:5:1066:5 | b [element 0] : | array_flow.rb:1067:10:1067:10 | b [element 0] : | +| array_flow.rb:1066:5:1066:5 | b [element 2] : | array_flow.rb:1069:10:1069:10 | b [element 2] : | +| array_flow.rb:1066:5:1066:5 | b [element 2] : | array_flow.rb:1069:10:1069:10 | b [element 2] : | +| array_flow.rb:1066:5:1066:5 | b [element 3] : | array_flow.rb:1070:10:1070:10 | b [element 3] : | +| array_flow.rb:1066:5:1066:5 | b [element 3] : | array_flow.rb:1070:10:1070:10 | b [element 3] : | | array_flow.rb:1066:9:1066:9 | a [element 0] : | array_flow.rb:1066:9:1066:19 | call to rotate [element 0] : | | array_flow.rb:1066:9:1066:9 | a [element 0] : | array_flow.rb:1066:9:1066:19 | call to rotate [element 0] : | | array_flow.rb:1066:9:1066:9 | a [element 2] : | array_flow.rb:1066:9:1066:19 | call to rotate [element 2] : | | array_flow.rb:1066:9:1066:9 | a [element 2] : | array_flow.rb:1066:9:1066:19 | call to rotate [element 2] : | | array_flow.rb:1066:9:1066:9 | a [element 3] : | array_flow.rb:1066:9:1066:19 | call to rotate [element 3] : | | array_flow.rb:1066:9:1066:9 | a [element 3] : | array_flow.rb:1066:9:1066:19 | call to rotate [element 3] : | -| array_flow.rb:1066:9:1066:19 | call to rotate [element 0] : | array_flow.rb:1067:10:1067:10 | b [element 0] : | -| array_flow.rb:1066:9:1066:19 | call to rotate [element 0] : | array_flow.rb:1067:10:1067:10 | b [element 0] : | -| array_flow.rb:1066:9:1066:19 | call to rotate [element 2] : | array_flow.rb:1069:10:1069:10 | b [element 2] : | -| array_flow.rb:1066:9:1066:19 | call to rotate [element 2] : | array_flow.rb:1069:10:1069:10 | b [element 2] : | -| array_flow.rb:1066:9:1066:19 | call to rotate [element 3] : | array_flow.rb:1070:10:1070:10 | b [element 3] : | -| array_flow.rb:1066:9:1066:19 | call to rotate [element 3] : | array_flow.rb:1070:10:1070:10 | b [element 3] : | +| array_flow.rb:1066:9:1066:19 | call to rotate [element 0] : | array_flow.rb:1066:5:1066:5 | b [element 0] : | +| array_flow.rb:1066:9:1066:19 | call to rotate [element 0] : | array_flow.rb:1066:5:1066:5 | b [element 0] : | +| array_flow.rb:1066:9:1066:19 | call to rotate [element 2] : | array_flow.rb:1066:5:1066:5 | b [element 2] : | +| array_flow.rb:1066:9:1066:19 | call to rotate [element 2] : | array_flow.rb:1066:5:1066:5 | b [element 2] : | +| array_flow.rb:1066:9:1066:19 | call to rotate [element 3] : | array_flow.rb:1066:5:1066:5 | b [element 3] : | +| array_flow.rb:1066:9:1066:19 | call to rotate [element 3] : | array_flow.rb:1066:5:1066:5 | b [element 3] : | | array_flow.rb:1067:10:1067:10 | b [element 0] : | array_flow.rb:1067:10:1067:13 | ...[...] | | array_flow.rb:1067:10:1067:10 | b [element 0] : | array_flow.rb:1067:10:1067:13 | ...[...] | | array_flow.rb:1069:10:1069:10 | b [element 2] : | array_flow.rb:1069:10:1069:13 | ...[...] | | array_flow.rb:1069:10:1069:10 | b [element 2] : | array_flow.rb:1069:10:1069:13 | ...[...] | | array_flow.rb:1070:10:1070:10 | b [element 3] : | array_flow.rb:1070:10:1070:13 | ...[...] | | array_flow.rb:1070:10:1070:10 | b [element 3] : | array_flow.rb:1070:10:1070:13 | ...[...] | +| array_flow.rb:1072:5:1072:5 | b [element] : | array_flow.rb:1073:10:1073:10 | b [element] : | +| array_flow.rb:1072:5:1072:5 | b [element] : | array_flow.rb:1073:10:1073:10 | b [element] : | +| array_flow.rb:1072:5:1072:5 | b [element] : | array_flow.rb:1074:10:1074:10 | b [element] : | +| array_flow.rb:1072:5:1072:5 | b [element] : | array_flow.rb:1074:10:1074:10 | b [element] : | +| array_flow.rb:1072:5:1072:5 | b [element] : | array_flow.rb:1075:10:1075:10 | b [element] : | +| array_flow.rb:1072:5:1072:5 | b [element] : | array_flow.rb:1075:10:1075:10 | b [element] : | +| array_flow.rb:1072:5:1072:5 | b [element] : | array_flow.rb:1076:10:1076:10 | b [element] : | +| array_flow.rb:1072:5:1072:5 | b [element] : | array_flow.rb:1076:10:1076:10 | b [element] : | | array_flow.rb:1072:9:1072:9 | a [element 0] : | array_flow.rb:1072:9:1072:19 | call to rotate [element] : | | array_flow.rb:1072:9:1072:9 | a [element 0] : | array_flow.rb:1072:9:1072:19 | call to rotate [element] : | | array_flow.rb:1072:9:1072:9 | a [element 2] : | array_flow.rb:1072:9:1072:19 | call to rotate [element] : | | array_flow.rb:1072:9:1072:9 | a [element 2] : | array_flow.rb:1072:9:1072:19 | call to rotate [element] : | | array_flow.rb:1072:9:1072:9 | a [element 3] : | array_flow.rb:1072:9:1072:19 | call to rotate [element] : | | array_flow.rb:1072:9:1072:9 | a [element 3] : | array_flow.rb:1072:9:1072:19 | call to rotate [element] : | -| array_flow.rb:1072:9:1072:19 | call to rotate [element] : | array_flow.rb:1073:10:1073:10 | b [element] : | -| array_flow.rb:1072:9:1072:19 | call to rotate [element] : | array_flow.rb:1073:10:1073:10 | b [element] : | -| array_flow.rb:1072:9:1072:19 | call to rotate [element] : | array_flow.rb:1074:10:1074:10 | b [element] : | -| array_flow.rb:1072:9:1072:19 | call to rotate [element] : | array_flow.rb:1074:10:1074:10 | b [element] : | -| array_flow.rb:1072:9:1072:19 | call to rotate [element] : | array_flow.rb:1075:10:1075:10 | b [element] : | -| array_flow.rb:1072:9:1072:19 | call to rotate [element] : | array_flow.rb:1075:10:1075:10 | b [element] : | -| array_flow.rb:1072:9:1072:19 | call to rotate [element] : | array_flow.rb:1076:10:1076:10 | b [element] : | -| array_flow.rb:1072:9:1072:19 | call to rotate [element] : | array_flow.rb:1076:10:1076:10 | b [element] : | +| array_flow.rb:1072:9:1072:19 | call to rotate [element] : | array_flow.rb:1072:5:1072:5 | b [element] : | +| array_flow.rb:1072:9:1072:19 | call to rotate [element] : | array_flow.rb:1072:5:1072:5 | b [element] : | | array_flow.rb:1073:10:1073:10 | b [element] : | array_flow.rb:1073:10:1073:13 | ...[...] | | array_flow.rb:1073:10:1073:10 | b [element] : | array_flow.rb:1073:10:1073:13 | ...[...] | | array_flow.rb:1074:10:1074:10 | b [element] : | array_flow.rb:1074:10:1074:13 | ...[...] | @@ -2011,12 +2512,30 @@ edges | array_flow.rb:1075:10:1075:10 | b [element] : | array_flow.rb:1075:10:1075:13 | ...[...] | | array_flow.rb:1076:10:1076:10 | b [element] : | array_flow.rb:1076:10:1076:13 | ...[...] | | array_flow.rb:1076:10:1076:10 | b [element] : | array_flow.rb:1076:10:1076:13 | ...[...] | -| array_flow.rb:1084:10:1084:22 | call to source : | array_flow.rb:1085:9:1085:9 | a [element 0] : | -| array_flow.rb:1084:10:1084:22 | call to source : | array_flow.rb:1085:9:1085:9 | a [element 0] : | -| array_flow.rb:1084:28:1084:40 | call to source : | array_flow.rb:1085:9:1085:9 | a [element 2] : | -| array_flow.rb:1084:28:1084:40 | call to source : | array_flow.rb:1085:9:1085:9 | a [element 2] : | -| array_flow.rb:1084:43:1084:55 | call to source : | array_flow.rb:1085:9:1085:9 | a [element 3] : | -| array_flow.rb:1084:43:1084:55 | call to source : | array_flow.rb:1085:9:1085:9 | a [element 3] : | +| array_flow.rb:1084:5:1084:5 | a [element 0] : | array_flow.rb:1085:9:1085:9 | a [element 0] : | +| array_flow.rb:1084:5:1084:5 | a [element 0] : | array_flow.rb:1085:9:1085:9 | a [element 0] : | +| array_flow.rb:1084:5:1084:5 | a [element 2] : | array_flow.rb:1085:9:1085:9 | a [element 2] : | +| array_flow.rb:1084:5:1084:5 | a [element 2] : | array_flow.rb:1085:9:1085:9 | a [element 2] : | +| array_flow.rb:1084:5:1084:5 | a [element 3] : | array_flow.rb:1085:9:1085:9 | a [element 3] : | +| array_flow.rb:1084:5:1084:5 | a [element 3] : | array_flow.rb:1085:9:1085:9 | a [element 3] : | +| array_flow.rb:1084:10:1084:22 | call to source : | array_flow.rb:1084:5:1084:5 | a [element 0] : | +| array_flow.rb:1084:10:1084:22 | call to source : | array_flow.rb:1084:5:1084:5 | a [element 0] : | +| array_flow.rb:1084:28:1084:40 | call to source : | array_flow.rb:1084:5:1084:5 | a [element 2] : | +| array_flow.rb:1084:28:1084:40 | call to source : | array_flow.rb:1084:5:1084:5 | a [element 2] : | +| array_flow.rb:1084:43:1084:55 | call to source : | array_flow.rb:1084:5:1084:5 | a [element 3] : | +| array_flow.rb:1084:43:1084:55 | call to source : | array_flow.rb:1084:5:1084:5 | a [element 3] : | +| array_flow.rb:1085:5:1085:5 | b [element 1] : | array_flow.rb:1091:10:1091:10 | b [element 1] : | +| array_flow.rb:1085:5:1085:5 | b [element 1] : | array_flow.rb:1091:10:1091:10 | b [element 1] : | +| array_flow.rb:1085:5:1085:5 | b [element 2] : | array_flow.rb:1092:10:1092:10 | b [element 2] : | +| array_flow.rb:1085:5:1085:5 | b [element 2] : | array_flow.rb:1092:10:1092:10 | b [element 2] : | +| array_flow.rb:1085:5:1085:5 | b [element] : | array_flow.rb:1090:10:1090:10 | b [element] : | +| array_flow.rb:1085:5:1085:5 | b [element] : | array_flow.rb:1090:10:1090:10 | b [element] : | +| array_flow.rb:1085:5:1085:5 | b [element] : | array_flow.rb:1091:10:1091:10 | b [element] : | +| array_flow.rb:1085:5:1085:5 | b [element] : | array_flow.rb:1091:10:1091:10 | b [element] : | +| array_flow.rb:1085:5:1085:5 | b [element] : | array_flow.rb:1092:10:1092:10 | b [element] : | +| array_flow.rb:1085:5:1085:5 | b [element] : | array_flow.rb:1092:10:1092:10 | b [element] : | +| array_flow.rb:1085:5:1085:5 | b [element] : | array_flow.rb:1093:10:1093:10 | b [element] : | +| array_flow.rb:1085:5:1085:5 | b [element] : | array_flow.rb:1093:10:1093:10 | b [element] : | | array_flow.rb:1085:9:1085:9 | [post] a [element 1] : | array_flow.rb:1087:10:1087:10 | a [element 1] : | | array_flow.rb:1085:9:1085:9 | [post] a [element 1] : | array_flow.rb:1087:10:1087:10 | a [element 1] : | | array_flow.rb:1085:9:1085:9 | [post] a [element 2] : | array_flow.rb:1088:10:1088:10 | a [element 2] : | @@ -2041,18 +2560,12 @@ edges | array_flow.rb:1085:9:1085:9 | a [element 3] : | array_flow.rb:1085:9:1085:9 | [post] a [element 2] : | | array_flow.rb:1085:9:1085:9 | a [element 3] : | array_flow.rb:1085:9:1085:17 | call to rotate! [element 2] : | | array_flow.rb:1085:9:1085:9 | a [element 3] : | array_flow.rb:1085:9:1085:17 | call to rotate! [element 2] : | -| array_flow.rb:1085:9:1085:17 | call to rotate! [element 1] : | array_flow.rb:1091:10:1091:10 | b [element 1] : | -| array_flow.rb:1085:9:1085:17 | call to rotate! [element 1] : | array_flow.rb:1091:10:1091:10 | b [element 1] : | -| array_flow.rb:1085:9:1085:17 | call to rotate! [element 2] : | array_flow.rb:1092:10:1092:10 | b [element 2] : | -| array_flow.rb:1085:9:1085:17 | call to rotate! [element 2] : | array_flow.rb:1092:10:1092:10 | b [element 2] : | -| array_flow.rb:1085:9:1085:17 | call to rotate! [element] : | array_flow.rb:1090:10:1090:10 | b [element] : | -| array_flow.rb:1085:9:1085:17 | call to rotate! [element] : | array_flow.rb:1090:10:1090:10 | b [element] : | -| array_flow.rb:1085:9:1085:17 | call to rotate! [element] : | array_flow.rb:1091:10:1091:10 | b [element] : | -| array_flow.rb:1085:9:1085:17 | call to rotate! [element] : | array_flow.rb:1091:10:1091:10 | b [element] : | -| array_flow.rb:1085:9:1085:17 | call to rotate! [element] : | array_flow.rb:1092:10:1092:10 | b [element] : | -| array_flow.rb:1085:9:1085:17 | call to rotate! [element] : | array_flow.rb:1092:10:1092:10 | b [element] : | -| array_flow.rb:1085:9:1085:17 | call to rotate! [element] : | array_flow.rb:1093:10:1093:10 | b [element] : | -| array_flow.rb:1085:9:1085:17 | call to rotate! [element] : | array_flow.rb:1093:10:1093:10 | b [element] : | +| array_flow.rb:1085:9:1085:17 | call to rotate! [element 1] : | array_flow.rb:1085:5:1085:5 | b [element 1] : | +| array_flow.rb:1085:9:1085:17 | call to rotate! [element 1] : | array_flow.rb:1085:5:1085:5 | b [element 1] : | +| array_flow.rb:1085:9:1085:17 | call to rotate! [element 2] : | array_flow.rb:1085:5:1085:5 | b [element 2] : | +| array_flow.rb:1085:9:1085:17 | call to rotate! [element 2] : | array_flow.rb:1085:5:1085:5 | b [element 2] : | +| array_flow.rb:1085:9:1085:17 | call to rotate! [element] : | array_flow.rb:1085:5:1085:5 | b [element] : | +| array_flow.rb:1085:9:1085:17 | call to rotate! [element] : | array_flow.rb:1085:5:1085:5 | b [element] : | | array_flow.rb:1086:10:1086:10 | a [element] : | array_flow.rb:1086:10:1086:13 | ...[...] | | array_flow.rb:1086:10:1086:10 | a [element] : | array_flow.rb:1086:10:1086:13 | ...[...] | | array_flow.rb:1087:10:1087:10 | a [element 1] : | array_flow.rb:1087:10:1087:13 | ...[...] | @@ -2077,12 +2590,30 @@ edges | array_flow.rb:1092:10:1092:10 | b [element] : | array_flow.rb:1092:10:1092:13 | ...[...] | | array_flow.rb:1093:10:1093:10 | b [element] : | array_flow.rb:1093:10:1093:13 | ...[...] | | array_flow.rb:1093:10:1093:10 | b [element] : | array_flow.rb:1093:10:1093:13 | ...[...] | -| array_flow.rb:1095:10:1095:22 | call to source : | array_flow.rb:1096:9:1096:9 | a [element 0] : | -| array_flow.rb:1095:10:1095:22 | call to source : | array_flow.rb:1096:9:1096:9 | a [element 0] : | -| array_flow.rb:1095:28:1095:40 | call to source : | array_flow.rb:1096:9:1096:9 | a [element 2] : | -| array_flow.rb:1095:28:1095:40 | call to source : | array_flow.rb:1096:9:1096:9 | a [element 2] : | -| array_flow.rb:1095:43:1095:55 | call to source : | array_flow.rb:1096:9:1096:9 | a [element 3] : | -| array_flow.rb:1095:43:1095:55 | call to source : | array_flow.rb:1096:9:1096:9 | a [element 3] : | +| array_flow.rb:1095:5:1095:5 | a [element 0] : | array_flow.rb:1096:9:1096:9 | a [element 0] : | +| array_flow.rb:1095:5:1095:5 | a [element 0] : | array_flow.rb:1096:9:1096:9 | a [element 0] : | +| array_flow.rb:1095:5:1095:5 | a [element 2] : | array_flow.rb:1096:9:1096:9 | a [element 2] : | +| array_flow.rb:1095:5:1095:5 | a [element 2] : | array_flow.rb:1096:9:1096:9 | a [element 2] : | +| array_flow.rb:1095:5:1095:5 | a [element 3] : | array_flow.rb:1096:9:1096:9 | a [element 3] : | +| array_flow.rb:1095:5:1095:5 | a [element 3] : | array_flow.rb:1096:9:1096:9 | a [element 3] : | +| array_flow.rb:1095:10:1095:22 | call to source : | array_flow.rb:1095:5:1095:5 | a [element 0] : | +| array_flow.rb:1095:10:1095:22 | call to source : | array_flow.rb:1095:5:1095:5 | a [element 0] : | +| array_flow.rb:1095:28:1095:40 | call to source : | array_flow.rb:1095:5:1095:5 | a [element 2] : | +| array_flow.rb:1095:28:1095:40 | call to source : | array_flow.rb:1095:5:1095:5 | a [element 2] : | +| array_flow.rb:1095:43:1095:55 | call to source : | array_flow.rb:1095:5:1095:5 | a [element 3] : | +| array_flow.rb:1095:43:1095:55 | call to source : | array_flow.rb:1095:5:1095:5 | a [element 3] : | +| array_flow.rb:1096:5:1096:5 | b [element 0] : | array_flow.rb:1101:10:1101:10 | b [element 0] : | +| array_flow.rb:1096:5:1096:5 | b [element 0] : | array_flow.rb:1101:10:1101:10 | b [element 0] : | +| array_flow.rb:1096:5:1096:5 | b [element 1] : | array_flow.rb:1102:10:1102:10 | b [element 1] : | +| array_flow.rb:1096:5:1096:5 | b [element 1] : | array_flow.rb:1102:10:1102:10 | b [element 1] : | +| array_flow.rb:1096:5:1096:5 | b [element] : | array_flow.rb:1101:10:1101:10 | b [element] : | +| array_flow.rb:1096:5:1096:5 | b [element] : | array_flow.rb:1101:10:1101:10 | b [element] : | +| array_flow.rb:1096:5:1096:5 | b [element] : | array_flow.rb:1102:10:1102:10 | b [element] : | +| array_flow.rb:1096:5:1096:5 | b [element] : | array_flow.rb:1102:10:1102:10 | b [element] : | +| array_flow.rb:1096:5:1096:5 | b [element] : | array_flow.rb:1103:10:1103:10 | b [element] : | +| array_flow.rb:1096:5:1096:5 | b [element] : | array_flow.rb:1103:10:1103:10 | b [element] : | +| array_flow.rb:1096:5:1096:5 | b [element] : | array_flow.rb:1104:10:1104:10 | b [element] : | +| array_flow.rb:1096:5:1096:5 | b [element] : | array_flow.rb:1104:10:1104:10 | b [element] : | | array_flow.rb:1096:9:1096:9 | [post] a [element 0] : | array_flow.rb:1097:10:1097:10 | a [element 0] : | | array_flow.rb:1096:9:1096:9 | [post] a [element 0] : | array_flow.rb:1097:10:1097:10 | a [element 0] : | | array_flow.rb:1096:9:1096:9 | [post] a [element 1] : | array_flow.rb:1098:10:1098:10 | a [element 1] : | @@ -2107,18 +2638,12 @@ edges | array_flow.rb:1096:9:1096:9 | a [element 3] : | array_flow.rb:1096:9:1096:9 | [post] a [element 1] : | | array_flow.rb:1096:9:1096:9 | a [element 3] : | array_flow.rb:1096:9:1096:20 | call to rotate! [element 1] : | | array_flow.rb:1096:9:1096:9 | a [element 3] : | array_flow.rb:1096:9:1096:20 | call to rotate! [element 1] : | -| array_flow.rb:1096:9:1096:20 | call to rotate! [element 0] : | array_flow.rb:1101:10:1101:10 | b [element 0] : | -| array_flow.rb:1096:9:1096:20 | call to rotate! [element 0] : | array_flow.rb:1101:10:1101:10 | b [element 0] : | -| array_flow.rb:1096:9:1096:20 | call to rotate! [element 1] : | array_flow.rb:1102:10:1102:10 | b [element 1] : | -| array_flow.rb:1096:9:1096:20 | call to rotate! [element 1] : | array_flow.rb:1102:10:1102:10 | b [element 1] : | -| array_flow.rb:1096:9:1096:20 | call to rotate! [element] : | array_flow.rb:1101:10:1101:10 | b [element] : | -| array_flow.rb:1096:9:1096:20 | call to rotate! [element] : | array_flow.rb:1101:10:1101:10 | b [element] : | -| array_flow.rb:1096:9:1096:20 | call to rotate! [element] : | array_flow.rb:1102:10:1102:10 | b [element] : | -| array_flow.rb:1096:9:1096:20 | call to rotate! [element] : | array_flow.rb:1102:10:1102:10 | b [element] : | -| array_flow.rb:1096:9:1096:20 | call to rotate! [element] : | array_flow.rb:1103:10:1103:10 | b [element] : | -| array_flow.rb:1096:9:1096:20 | call to rotate! [element] : | array_flow.rb:1103:10:1103:10 | b [element] : | -| array_flow.rb:1096:9:1096:20 | call to rotate! [element] : | array_flow.rb:1104:10:1104:10 | b [element] : | -| array_flow.rb:1096:9:1096:20 | call to rotate! [element] : | array_flow.rb:1104:10:1104:10 | b [element] : | +| array_flow.rb:1096:9:1096:20 | call to rotate! [element 0] : | array_flow.rb:1096:5:1096:5 | b [element 0] : | +| array_flow.rb:1096:9:1096:20 | call to rotate! [element 0] : | array_flow.rb:1096:5:1096:5 | b [element 0] : | +| array_flow.rb:1096:9:1096:20 | call to rotate! [element 1] : | array_flow.rb:1096:5:1096:5 | b [element 1] : | +| array_flow.rb:1096:9:1096:20 | call to rotate! [element 1] : | array_flow.rb:1096:5:1096:5 | b [element 1] : | +| array_flow.rb:1096:9:1096:20 | call to rotate! [element] : | array_flow.rb:1096:5:1096:5 | b [element] : | +| array_flow.rb:1096:9:1096:20 | call to rotate! [element] : | array_flow.rb:1096:5:1096:5 | b [element] : | | array_flow.rb:1097:10:1097:10 | a [element 0] : | array_flow.rb:1097:10:1097:13 | ...[...] | | array_flow.rb:1097:10:1097:10 | a [element 0] : | array_flow.rb:1097:10:1097:13 | ...[...] | | array_flow.rb:1097:10:1097:10 | a [element] : | array_flow.rb:1097:10:1097:13 | ...[...] | @@ -2143,12 +2668,24 @@ edges | array_flow.rb:1103:10:1103:10 | b [element] : | array_flow.rb:1103:10:1103:13 | ...[...] | | array_flow.rb:1104:10:1104:10 | b [element] : | array_flow.rb:1104:10:1104:13 | ...[...] | | array_flow.rb:1104:10:1104:10 | b [element] : | array_flow.rb:1104:10:1104:13 | ...[...] | -| array_flow.rb:1106:10:1106:22 | call to source : | array_flow.rb:1107:9:1107:9 | a [element 0] : | -| array_flow.rb:1106:10:1106:22 | call to source : | array_flow.rb:1107:9:1107:9 | a [element 0] : | -| array_flow.rb:1106:28:1106:40 | call to source : | array_flow.rb:1107:9:1107:9 | a [element 2] : | -| array_flow.rb:1106:28:1106:40 | call to source : | array_flow.rb:1107:9:1107:9 | a [element 2] : | -| array_flow.rb:1106:43:1106:55 | call to source : | array_flow.rb:1107:9:1107:9 | a [element 3] : | -| array_flow.rb:1106:43:1106:55 | call to source : | array_flow.rb:1107:9:1107:9 | a [element 3] : | +| array_flow.rb:1106:5:1106:5 | a [element 0] : | array_flow.rb:1107:9:1107:9 | a [element 0] : | +| array_flow.rb:1106:5:1106:5 | a [element 0] : | array_flow.rb:1107:9:1107:9 | a [element 0] : | +| array_flow.rb:1106:5:1106:5 | a [element 2] : | array_flow.rb:1107:9:1107:9 | a [element 2] : | +| array_flow.rb:1106:5:1106:5 | a [element 2] : | array_flow.rb:1107:9:1107:9 | a [element 2] : | +| array_flow.rb:1106:5:1106:5 | a [element 3] : | array_flow.rb:1107:9:1107:9 | a [element 3] : | +| array_flow.rb:1106:5:1106:5 | a [element 3] : | array_flow.rb:1107:9:1107:9 | a [element 3] : | +| array_flow.rb:1106:10:1106:22 | call to source : | array_flow.rb:1106:5:1106:5 | a [element 0] : | +| array_flow.rb:1106:10:1106:22 | call to source : | array_flow.rb:1106:5:1106:5 | a [element 0] : | +| array_flow.rb:1106:28:1106:40 | call to source : | array_flow.rb:1106:5:1106:5 | a [element 2] : | +| array_flow.rb:1106:28:1106:40 | call to source : | array_flow.rb:1106:5:1106:5 | a [element 2] : | +| array_flow.rb:1106:43:1106:55 | call to source : | array_flow.rb:1106:5:1106:5 | a [element 3] : | +| array_flow.rb:1106:43:1106:55 | call to source : | array_flow.rb:1106:5:1106:5 | a [element 3] : | +| array_flow.rb:1107:5:1107:5 | b [element 0] : | array_flow.rb:1112:10:1112:10 | b [element 0] : | +| array_flow.rb:1107:5:1107:5 | b [element 0] : | array_flow.rb:1112:10:1112:10 | b [element 0] : | +| array_flow.rb:1107:5:1107:5 | b [element 2] : | array_flow.rb:1114:10:1114:10 | b [element 2] : | +| array_flow.rb:1107:5:1107:5 | b [element 2] : | array_flow.rb:1114:10:1114:10 | b [element 2] : | +| array_flow.rb:1107:5:1107:5 | b [element 3] : | array_flow.rb:1115:10:1115:10 | b [element 3] : | +| array_flow.rb:1107:5:1107:5 | b [element 3] : | array_flow.rb:1115:10:1115:10 | b [element 3] : | | array_flow.rb:1107:9:1107:9 | [post] a [element 0] : | array_flow.rb:1108:10:1108:10 | a [element 0] : | | array_flow.rb:1107:9:1107:9 | [post] a [element 0] : | array_flow.rb:1108:10:1108:10 | a [element 0] : | | array_flow.rb:1107:9:1107:9 | [post] a [element 2] : | array_flow.rb:1110:10:1110:10 | a [element 2] : | @@ -2167,12 +2704,12 @@ edges | array_flow.rb:1107:9:1107:9 | a [element 3] : | array_flow.rb:1107:9:1107:9 | [post] a [element 3] : | | array_flow.rb:1107:9:1107:9 | a [element 3] : | array_flow.rb:1107:9:1107:20 | call to rotate! [element 3] : | | array_flow.rb:1107:9:1107:9 | a [element 3] : | array_flow.rb:1107:9:1107:20 | call to rotate! [element 3] : | -| array_flow.rb:1107:9:1107:20 | call to rotate! [element 0] : | array_flow.rb:1112:10:1112:10 | b [element 0] : | -| array_flow.rb:1107:9:1107:20 | call to rotate! [element 0] : | array_flow.rb:1112:10:1112:10 | b [element 0] : | -| array_flow.rb:1107:9:1107:20 | call to rotate! [element 2] : | array_flow.rb:1114:10:1114:10 | b [element 2] : | -| array_flow.rb:1107:9:1107:20 | call to rotate! [element 2] : | array_flow.rb:1114:10:1114:10 | b [element 2] : | -| array_flow.rb:1107:9:1107:20 | call to rotate! [element 3] : | array_flow.rb:1115:10:1115:10 | b [element 3] : | -| array_flow.rb:1107:9:1107:20 | call to rotate! [element 3] : | array_flow.rb:1115:10:1115:10 | b [element 3] : | +| array_flow.rb:1107:9:1107:20 | call to rotate! [element 0] : | array_flow.rb:1107:5:1107:5 | b [element 0] : | +| array_flow.rb:1107:9:1107:20 | call to rotate! [element 0] : | array_flow.rb:1107:5:1107:5 | b [element 0] : | +| array_flow.rb:1107:9:1107:20 | call to rotate! [element 2] : | array_flow.rb:1107:5:1107:5 | b [element 2] : | +| array_flow.rb:1107:9:1107:20 | call to rotate! [element 2] : | array_flow.rb:1107:5:1107:5 | b [element 2] : | +| array_flow.rb:1107:9:1107:20 | call to rotate! [element 3] : | array_flow.rb:1107:5:1107:5 | b [element 3] : | +| array_flow.rb:1107:9:1107:20 | call to rotate! [element 3] : | array_flow.rb:1107:5:1107:5 | b [element 3] : | | array_flow.rb:1108:10:1108:10 | a [element 0] : | array_flow.rb:1108:10:1108:13 | ...[...] | | array_flow.rb:1108:10:1108:10 | a [element 0] : | array_flow.rb:1108:10:1108:13 | ...[...] | | array_flow.rb:1110:10:1110:10 | a [element 2] : | array_flow.rb:1110:10:1110:13 | ...[...] | @@ -2185,12 +2722,26 @@ edges | array_flow.rb:1114:10:1114:10 | b [element 2] : | array_flow.rb:1114:10:1114:13 | ...[...] | | array_flow.rb:1115:10:1115:10 | b [element 3] : | array_flow.rb:1115:10:1115:13 | ...[...] | | array_flow.rb:1115:10:1115:10 | b [element 3] : | array_flow.rb:1115:10:1115:13 | ...[...] | -| array_flow.rb:1117:10:1117:22 | call to source : | array_flow.rb:1118:9:1118:9 | a [element 0] : | -| array_flow.rb:1117:10:1117:22 | call to source : | array_flow.rb:1118:9:1118:9 | a [element 0] : | -| array_flow.rb:1117:28:1117:40 | call to source : | array_flow.rb:1118:9:1118:9 | a [element 2] : | -| array_flow.rb:1117:28:1117:40 | call to source : | array_flow.rb:1118:9:1118:9 | a [element 2] : | -| array_flow.rb:1117:43:1117:55 | call to source : | array_flow.rb:1118:9:1118:9 | a [element 3] : | -| array_flow.rb:1117:43:1117:55 | call to source : | array_flow.rb:1118:9:1118:9 | a [element 3] : | +| array_flow.rb:1117:5:1117:5 | a [element 0] : | array_flow.rb:1118:9:1118:9 | a [element 0] : | +| array_flow.rb:1117:5:1117:5 | a [element 0] : | array_flow.rb:1118:9:1118:9 | a [element 0] : | +| array_flow.rb:1117:5:1117:5 | a [element 2] : | array_flow.rb:1118:9:1118:9 | a [element 2] : | +| array_flow.rb:1117:5:1117:5 | a [element 2] : | array_flow.rb:1118:9:1118:9 | a [element 2] : | +| array_flow.rb:1117:5:1117:5 | a [element 3] : | array_flow.rb:1118:9:1118:9 | a [element 3] : | +| array_flow.rb:1117:5:1117:5 | a [element 3] : | array_flow.rb:1118:9:1118:9 | a [element 3] : | +| array_flow.rb:1117:10:1117:22 | call to source : | array_flow.rb:1117:5:1117:5 | a [element 0] : | +| array_flow.rb:1117:10:1117:22 | call to source : | array_flow.rb:1117:5:1117:5 | a [element 0] : | +| array_flow.rb:1117:28:1117:40 | call to source : | array_flow.rb:1117:5:1117:5 | a [element 2] : | +| array_flow.rb:1117:28:1117:40 | call to source : | array_flow.rb:1117:5:1117:5 | a [element 2] : | +| array_flow.rb:1117:43:1117:55 | call to source : | array_flow.rb:1117:5:1117:5 | a [element 3] : | +| array_flow.rb:1117:43:1117:55 | call to source : | array_flow.rb:1117:5:1117:5 | a [element 3] : | +| array_flow.rb:1118:5:1118:5 | b [element] : | array_flow.rb:1123:10:1123:10 | b [element] : | +| array_flow.rb:1118:5:1118:5 | b [element] : | array_flow.rb:1123:10:1123:10 | b [element] : | +| array_flow.rb:1118:5:1118:5 | b [element] : | array_flow.rb:1124:10:1124:10 | b [element] : | +| array_flow.rb:1118:5:1118:5 | b [element] : | array_flow.rb:1124:10:1124:10 | b [element] : | +| array_flow.rb:1118:5:1118:5 | b [element] : | array_flow.rb:1125:10:1125:10 | b [element] : | +| array_flow.rb:1118:5:1118:5 | b [element] : | array_flow.rb:1125:10:1125:10 | b [element] : | +| array_flow.rb:1118:5:1118:5 | b [element] : | array_flow.rb:1126:10:1126:10 | b [element] : | +| array_flow.rb:1118:5:1118:5 | b [element] : | array_flow.rb:1126:10:1126:10 | b [element] : | | array_flow.rb:1118:9:1118:9 | [post] a [element] : | array_flow.rb:1119:10:1119:10 | a [element] : | | array_flow.rb:1118:9:1118:9 | [post] a [element] : | array_flow.rb:1119:10:1119:10 | a [element] : | | array_flow.rb:1118:9:1118:9 | [post] a [element] : | array_flow.rb:1120:10:1120:10 | a [element] : | @@ -2211,14 +2762,8 @@ edges | array_flow.rb:1118:9:1118:9 | a [element 3] : | array_flow.rb:1118:9:1118:9 | [post] a [element] : | | array_flow.rb:1118:9:1118:9 | a [element 3] : | array_flow.rb:1118:9:1118:20 | call to rotate! [element] : | | array_flow.rb:1118:9:1118:9 | a [element 3] : | array_flow.rb:1118:9:1118:20 | call to rotate! [element] : | -| array_flow.rb:1118:9:1118:20 | call to rotate! [element] : | array_flow.rb:1123:10:1123:10 | b [element] : | -| array_flow.rb:1118:9:1118:20 | call to rotate! [element] : | array_flow.rb:1123:10:1123:10 | b [element] : | -| array_flow.rb:1118:9:1118:20 | call to rotate! [element] : | array_flow.rb:1124:10:1124:10 | b [element] : | -| array_flow.rb:1118:9:1118:20 | call to rotate! [element] : | array_flow.rb:1124:10:1124:10 | b [element] : | -| array_flow.rb:1118:9:1118:20 | call to rotate! [element] : | array_flow.rb:1125:10:1125:10 | b [element] : | -| array_flow.rb:1118:9:1118:20 | call to rotate! [element] : | array_flow.rb:1125:10:1125:10 | b [element] : | -| array_flow.rb:1118:9:1118:20 | call to rotate! [element] : | array_flow.rb:1126:10:1126:10 | b [element] : | -| array_flow.rb:1118:9:1118:20 | call to rotate! [element] : | array_flow.rb:1126:10:1126:10 | b [element] : | +| array_flow.rb:1118:9:1118:20 | call to rotate! [element] : | array_flow.rb:1118:5:1118:5 | b [element] : | +| array_flow.rb:1118:9:1118:20 | call to rotate! [element] : | array_flow.rb:1118:5:1118:5 | b [element] : | | array_flow.rb:1119:10:1119:10 | a [element] : | array_flow.rb:1119:10:1119:13 | ...[...] | | array_flow.rb:1119:10:1119:10 | a [element] : | array_flow.rb:1119:10:1119:13 | ...[...] | | array_flow.rb:1120:10:1120:10 | a [element] : | array_flow.rb:1120:10:1120:13 | ...[...] | @@ -2235,20 +2780,28 @@ edges | array_flow.rb:1125:10:1125:10 | b [element] : | array_flow.rb:1125:10:1125:13 | ...[...] | | array_flow.rb:1126:10:1126:10 | b [element] : | array_flow.rb:1126:10:1126:13 | ...[...] | | array_flow.rb:1126:10:1126:10 | b [element] : | array_flow.rb:1126:10:1126:13 | ...[...] | -| array_flow.rb:1130:19:1130:29 | call to source : | array_flow.rb:1131:9:1131:9 | a [element 3] : | -| array_flow.rb:1130:19:1130:29 | call to source : | array_flow.rb:1131:9:1131:9 | a [element 3] : | +| array_flow.rb:1130:5:1130:5 | a [element 3] : | array_flow.rb:1131:9:1131:9 | a [element 3] : | +| array_flow.rb:1130:5:1130:5 | a [element 3] : | array_flow.rb:1131:9:1131:9 | a [element 3] : | +| array_flow.rb:1130:19:1130:29 | call to source : | array_flow.rb:1130:5:1130:5 | a [element 3] : | +| array_flow.rb:1130:19:1130:29 | call to source : | array_flow.rb:1130:5:1130:5 | a [element 3] : | +| array_flow.rb:1131:5:1131:5 | b [element] : | array_flow.rb:1134:10:1134:10 | b [element] : | +| array_flow.rb:1131:5:1131:5 | b [element] : | array_flow.rb:1134:10:1134:10 | b [element] : | | array_flow.rb:1131:9:1131:9 | a [element 3] : | array_flow.rb:1131:9:1133:7 | call to select [element] : | | array_flow.rb:1131:9:1131:9 | a [element 3] : | array_flow.rb:1131:9:1133:7 | call to select [element] : | | array_flow.rb:1131:9:1131:9 | a [element 3] : | array_flow.rb:1131:22:1131:22 | x : | | array_flow.rb:1131:9:1131:9 | a [element 3] : | array_flow.rb:1131:22:1131:22 | x : | -| array_flow.rb:1131:9:1133:7 | call to select [element] : | array_flow.rb:1134:10:1134:10 | b [element] : | -| array_flow.rb:1131:9:1133:7 | call to select [element] : | array_flow.rb:1134:10:1134:10 | b [element] : | +| array_flow.rb:1131:9:1133:7 | call to select [element] : | array_flow.rb:1131:5:1131:5 | b [element] : | +| array_flow.rb:1131:9:1133:7 | call to select [element] : | array_flow.rb:1131:5:1131:5 | b [element] : | | array_flow.rb:1131:22:1131:22 | x : | array_flow.rb:1132:14:1132:14 | x | | array_flow.rb:1131:22:1131:22 | x : | array_flow.rb:1132:14:1132:14 | x | | array_flow.rb:1134:10:1134:10 | b [element] : | array_flow.rb:1134:10:1134:13 | ...[...] | | array_flow.rb:1134:10:1134:10 | b [element] : | array_flow.rb:1134:10:1134:13 | ...[...] | -| array_flow.rb:1138:16:1138:26 | call to source : | array_flow.rb:1139:9:1139:9 | a [element 2] : | -| array_flow.rb:1138:16:1138:26 | call to source : | array_flow.rb:1139:9:1139:9 | a [element 2] : | +| array_flow.rb:1138:5:1138:5 | a [element 2] : | array_flow.rb:1139:9:1139:9 | a [element 2] : | +| array_flow.rb:1138:5:1138:5 | a [element 2] : | array_flow.rb:1139:9:1139:9 | a [element 2] : | +| array_flow.rb:1138:16:1138:26 | call to source : | array_flow.rb:1138:5:1138:5 | a [element 2] : | +| array_flow.rb:1138:16:1138:26 | call to source : | array_flow.rb:1138:5:1138:5 | a [element 2] : | +| array_flow.rb:1139:5:1139:5 | b [element] : | array_flow.rb:1144:10:1144:10 | b [element] : | +| array_flow.rb:1139:5:1139:5 | b [element] : | array_flow.rb:1144:10:1144:10 | b [element] : | | array_flow.rb:1139:9:1139:9 | [post] a [element] : | array_flow.rb:1143:10:1143:10 | a [element] : | | array_flow.rb:1139:9:1139:9 | [post] a [element] : | array_flow.rb:1143:10:1143:10 | a [element] : | | array_flow.rb:1139:9:1139:9 | a [element 2] : | array_flow.rb:1139:9:1139:9 | [post] a [element] : | @@ -2257,52 +2810,72 @@ edges | array_flow.rb:1139:9:1139:9 | a [element 2] : | array_flow.rb:1139:9:1142:7 | call to select! [element] : | | array_flow.rb:1139:9:1139:9 | a [element 2] : | array_flow.rb:1139:23:1139:23 | x : | | array_flow.rb:1139:9:1139:9 | a [element 2] : | array_flow.rb:1139:23:1139:23 | x : | -| array_flow.rb:1139:9:1142:7 | call to select! [element] : | array_flow.rb:1144:10:1144:10 | b [element] : | -| array_flow.rb:1139:9:1142:7 | call to select! [element] : | array_flow.rb:1144:10:1144:10 | b [element] : | +| array_flow.rb:1139:9:1142:7 | call to select! [element] : | array_flow.rb:1139:5:1139:5 | b [element] : | +| array_flow.rb:1139:9:1142:7 | call to select! [element] : | array_flow.rb:1139:5:1139:5 | b [element] : | | array_flow.rb:1139:23:1139:23 | x : | array_flow.rb:1140:14:1140:14 | x | | array_flow.rb:1139:23:1139:23 | x : | array_flow.rb:1140:14:1140:14 | x | | array_flow.rb:1143:10:1143:10 | a [element] : | array_flow.rb:1143:10:1143:13 | ...[...] | | array_flow.rb:1143:10:1143:10 | a [element] : | array_flow.rb:1143:10:1143:13 | ...[...] | | array_flow.rb:1144:10:1144:10 | b [element] : | array_flow.rb:1144:10:1144:13 | ...[...] | | array_flow.rb:1144:10:1144:10 | b [element] : | array_flow.rb:1144:10:1144:13 | ...[...] | -| array_flow.rb:1148:10:1148:22 | call to source : | array_flow.rb:1149:9:1149:9 | a [element 0] : | -| array_flow.rb:1148:10:1148:22 | call to source : | array_flow.rb:1149:9:1149:9 | a [element 0] : | -| array_flow.rb:1148:28:1148:40 | call to source : | array_flow.rb:1149:9:1149:9 | a [element 2] : | -| array_flow.rb:1148:28:1148:40 | call to source : | array_flow.rb:1149:9:1149:9 | a [element 2] : | +| array_flow.rb:1148:5:1148:5 | a [element 0] : | array_flow.rb:1149:9:1149:9 | a [element 0] : | +| array_flow.rb:1148:5:1148:5 | a [element 0] : | array_flow.rb:1149:9:1149:9 | a [element 0] : | +| array_flow.rb:1148:5:1148:5 | a [element 2] : | array_flow.rb:1149:9:1149:9 | a [element 2] : | +| array_flow.rb:1148:5:1148:5 | a [element 2] : | array_flow.rb:1149:9:1149:9 | a [element 2] : | +| array_flow.rb:1148:10:1148:22 | call to source : | array_flow.rb:1148:5:1148:5 | a [element 0] : | +| array_flow.rb:1148:10:1148:22 | call to source : | array_flow.rb:1148:5:1148:5 | a [element 0] : | +| array_flow.rb:1148:28:1148:40 | call to source : | array_flow.rb:1148:5:1148:5 | a [element 2] : | +| array_flow.rb:1148:28:1148:40 | call to source : | array_flow.rb:1148:5:1148:5 | a [element 2] : | +| array_flow.rb:1149:5:1149:5 | b : | array_flow.rb:1150:10:1150:10 | b | +| array_flow.rb:1149:5:1149:5 | b : | array_flow.rb:1150:10:1150:10 | b | | array_flow.rb:1149:9:1149:9 | [post] a [element 1] : | array_flow.rb:1152:10:1152:10 | a [element 1] : | | array_flow.rb:1149:9:1149:9 | [post] a [element 1] : | array_flow.rb:1152:10:1152:10 | a [element 1] : | | array_flow.rb:1149:9:1149:9 | a [element 0] : | array_flow.rb:1149:9:1149:15 | call to shift : | | array_flow.rb:1149:9:1149:9 | a [element 0] : | array_flow.rb:1149:9:1149:15 | call to shift : | | array_flow.rb:1149:9:1149:9 | a [element 2] : | array_flow.rb:1149:9:1149:9 | [post] a [element 1] : | | array_flow.rb:1149:9:1149:9 | a [element 2] : | array_flow.rb:1149:9:1149:9 | [post] a [element 1] : | -| array_flow.rb:1149:9:1149:15 | call to shift : | array_flow.rb:1150:10:1150:10 | b | -| array_flow.rb:1149:9:1149:15 | call to shift : | array_flow.rb:1150:10:1150:10 | b | +| array_flow.rb:1149:9:1149:15 | call to shift : | array_flow.rb:1149:5:1149:5 | b : | +| array_flow.rb:1149:9:1149:15 | call to shift : | array_flow.rb:1149:5:1149:5 | b : | | array_flow.rb:1152:10:1152:10 | a [element 1] : | array_flow.rb:1152:10:1152:13 | ...[...] | | array_flow.rb:1152:10:1152:10 | a [element 1] : | array_flow.rb:1152:10:1152:13 | ...[...] | -| array_flow.rb:1155:10:1155:22 | call to source : | array_flow.rb:1156:9:1156:9 | a [element 0] : | -| array_flow.rb:1155:10:1155:22 | call to source : | array_flow.rb:1156:9:1156:9 | a [element 0] : | -| array_flow.rb:1155:28:1155:40 | call to source : | array_flow.rb:1156:9:1156:9 | a [element 2] : | -| array_flow.rb:1155:28:1155:40 | call to source : | array_flow.rb:1156:9:1156:9 | a [element 2] : | +| array_flow.rb:1155:5:1155:5 | a [element 0] : | array_flow.rb:1156:9:1156:9 | a [element 0] : | +| array_flow.rb:1155:5:1155:5 | a [element 0] : | array_flow.rb:1156:9:1156:9 | a [element 0] : | +| array_flow.rb:1155:5:1155:5 | a [element 2] : | array_flow.rb:1156:9:1156:9 | a [element 2] : | +| array_flow.rb:1155:5:1155:5 | a [element 2] : | array_flow.rb:1156:9:1156:9 | a [element 2] : | +| array_flow.rb:1155:10:1155:22 | call to source : | array_flow.rb:1155:5:1155:5 | a [element 0] : | +| array_flow.rb:1155:10:1155:22 | call to source : | array_flow.rb:1155:5:1155:5 | a [element 0] : | +| array_flow.rb:1155:28:1155:40 | call to source : | array_flow.rb:1155:5:1155:5 | a [element 2] : | +| array_flow.rb:1155:28:1155:40 | call to source : | array_flow.rb:1155:5:1155:5 | a [element 2] : | +| array_flow.rb:1156:5:1156:5 | b [element 0] : | array_flow.rb:1157:10:1157:10 | b [element 0] : | +| array_flow.rb:1156:5:1156:5 | b [element 0] : | array_flow.rb:1157:10:1157:10 | b [element 0] : | | array_flow.rb:1156:9:1156:9 | [post] a [element 0] : | array_flow.rb:1159:10:1159:10 | a [element 0] : | | array_flow.rb:1156:9:1156:9 | [post] a [element 0] : | array_flow.rb:1159:10:1159:10 | a [element 0] : | | array_flow.rb:1156:9:1156:9 | a [element 0] : | array_flow.rb:1156:9:1156:18 | call to shift [element 0] : | | array_flow.rb:1156:9:1156:9 | a [element 0] : | array_flow.rb:1156:9:1156:18 | call to shift [element 0] : | | array_flow.rb:1156:9:1156:9 | a [element 2] : | array_flow.rb:1156:9:1156:9 | [post] a [element 0] : | | array_flow.rb:1156:9:1156:9 | a [element 2] : | array_flow.rb:1156:9:1156:9 | [post] a [element 0] : | -| array_flow.rb:1156:9:1156:18 | call to shift [element 0] : | array_flow.rb:1157:10:1157:10 | b [element 0] : | -| array_flow.rb:1156:9:1156:18 | call to shift [element 0] : | array_flow.rb:1157:10:1157:10 | b [element 0] : | +| array_flow.rb:1156:9:1156:18 | call to shift [element 0] : | array_flow.rb:1156:5:1156:5 | b [element 0] : | +| array_flow.rb:1156:9:1156:18 | call to shift [element 0] : | array_flow.rb:1156:5:1156:5 | b [element 0] : | | array_flow.rb:1157:10:1157:10 | b [element 0] : | array_flow.rb:1157:10:1157:13 | ...[...] | | array_flow.rb:1157:10:1157:10 | b [element 0] : | array_flow.rb:1157:10:1157:13 | ...[...] | | array_flow.rb:1159:10:1159:10 | a [element 0] : | array_flow.rb:1159:10:1159:13 | ...[...] | | array_flow.rb:1159:10:1159:10 | a [element 0] : | array_flow.rb:1159:10:1159:13 | ...[...] | -| array_flow.rb:1163:10:1163:22 | call to source : | array_flow.rb:1164:9:1164:9 | a [element 0] : | -| array_flow.rb:1163:10:1163:22 | call to source : | array_flow.rb:1164:9:1164:9 | a [element 0] : | -| array_flow.rb:1163:10:1163:22 | call to source : | array_flow.rb:1167:10:1167:10 | a [element 0] : | -| array_flow.rb:1163:10:1163:22 | call to source : | array_flow.rb:1167:10:1167:10 | a [element 0] : | -| array_flow.rb:1163:28:1163:40 | call to source : | array_flow.rb:1164:9:1164:9 | a [element 2] : | -| array_flow.rb:1163:28:1163:40 | call to source : | array_flow.rb:1164:9:1164:9 | a [element 2] : | -| array_flow.rb:1163:28:1163:40 | call to source : | array_flow.rb:1169:10:1169:10 | a [element 2] : | -| array_flow.rb:1163:28:1163:40 | call to source : | array_flow.rb:1169:10:1169:10 | a [element 2] : | +| array_flow.rb:1163:5:1163:5 | a [element 0] : | array_flow.rb:1164:9:1164:9 | a [element 0] : | +| array_flow.rb:1163:5:1163:5 | a [element 0] : | array_flow.rb:1164:9:1164:9 | a [element 0] : | +| array_flow.rb:1163:5:1163:5 | a [element 0] : | array_flow.rb:1167:10:1167:10 | a [element 0] : | +| array_flow.rb:1163:5:1163:5 | a [element 0] : | array_flow.rb:1167:10:1167:10 | a [element 0] : | +| array_flow.rb:1163:5:1163:5 | a [element 2] : | array_flow.rb:1164:9:1164:9 | a [element 2] : | +| array_flow.rb:1163:5:1163:5 | a [element 2] : | array_flow.rb:1164:9:1164:9 | a [element 2] : | +| array_flow.rb:1163:5:1163:5 | a [element 2] : | array_flow.rb:1169:10:1169:10 | a [element 2] : | +| array_flow.rb:1163:5:1163:5 | a [element 2] : | array_flow.rb:1169:10:1169:10 | a [element 2] : | +| array_flow.rb:1163:10:1163:22 | call to source : | array_flow.rb:1163:5:1163:5 | a [element 0] : | +| array_flow.rb:1163:10:1163:22 | call to source : | array_flow.rb:1163:5:1163:5 | a [element 0] : | +| array_flow.rb:1163:28:1163:40 | call to source : | array_flow.rb:1163:5:1163:5 | a [element 2] : | +| array_flow.rb:1163:28:1163:40 | call to source : | array_flow.rb:1163:5:1163:5 | a [element 2] : | +| array_flow.rb:1164:5:1164:5 | b [element] : | array_flow.rb:1165:10:1165:10 | b [element] : | +| array_flow.rb:1164:5:1164:5 | b [element] : | array_flow.rb:1165:10:1165:10 | b [element] : | +| array_flow.rb:1164:5:1164:5 | b [element] : | array_flow.rb:1166:10:1166:10 | b [element] : | +| array_flow.rb:1164:5:1164:5 | b [element] : | array_flow.rb:1166:10:1166:10 | b [element] : | | array_flow.rb:1164:9:1164:9 | [post] a [element] : | array_flow.rb:1167:10:1167:10 | a [element] : | | array_flow.rb:1164:9:1164:9 | [post] a [element] : | array_flow.rb:1167:10:1167:10 | a [element] : | | array_flow.rb:1164:9:1164:9 | [post] a [element] : | array_flow.rb:1168:10:1168:10 | a [element] : | @@ -2317,10 +2890,8 @@ edges | array_flow.rb:1164:9:1164:9 | a [element 2] : | array_flow.rb:1164:9:1164:9 | [post] a [element] : | | array_flow.rb:1164:9:1164:9 | a [element 2] : | array_flow.rb:1164:9:1164:18 | call to shift [element] : | | array_flow.rb:1164:9:1164:9 | a [element 2] : | array_flow.rb:1164:9:1164:18 | call to shift [element] : | -| array_flow.rb:1164:9:1164:18 | call to shift [element] : | array_flow.rb:1165:10:1165:10 | b [element] : | -| array_flow.rb:1164:9:1164:18 | call to shift [element] : | array_flow.rb:1165:10:1165:10 | b [element] : | -| array_flow.rb:1164:9:1164:18 | call to shift [element] : | array_flow.rb:1166:10:1166:10 | b [element] : | -| array_flow.rb:1164:9:1164:18 | call to shift [element] : | array_flow.rb:1166:10:1166:10 | b [element] : | +| array_flow.rb:1164:9:1164:18 | call to shift [element] : | array_flow.rb:1164:5:1164:5 | b [element] : | +| array_flow.rb:1164:9:1164:18 | call to shift [element] : | array_flow.rb:1164:5:1164:5 | b [element] : | | array_flow.rb:1165:10:1165:10 | b [element] : | array_flow.rb:1165:10:1165:13 | ...[...] | | array_flow.rb:1165:10:1165:10 | b [element] : | array_flow.rb:1165:10:1165:13 | ...[...] | | array_flow.rb:1166:10:1166:10 | b [element] : | array_flow.rb:1166:10:1166:13 | ...[...] | @@ -2335,18 +2906,22 @@ edges | array_flow.rb:1169:10:1169:10 | a [element 2] : | array_flow.rb:1169:10:1169:13 | ...[...] | | array_flow.rb:1169:10:1169:10 | a [element] : | array_flow.rb:1169:10:1169:13 | ...[...] | | array_flow.rb:1169:10:1169:10 | a [element] : | array_flow.rb:1169:10:1169:13 | ...[...] | -| array_flow.rb:1173:16:1173:26 | call to source : | array_flow.rb:1174:9:1174:9 | a [element 2] : | -| array_flow.rb:1173:16:1173:26 | call to source : | array_flow.rb:1174:9:1174:9 | a [element 2] : | -| array_flow.rb:1173:16:1173:26 | call to source : | array_flow.rb:1177:10:1177:10 | a [element 2] : | -| array_flow.rb:1173:16:1173:26 | call to source : | array_flow.rb:1177:10:1177:10 | a [element 2] : | +| array_flow.rb:1173:5:1173:5 | a [element 2] : | array_flow.rb:1174:9:1174:9 | a [element 2] : | +| array_flow.rb:1173:5:1173:5 | a [element 2] : | array_flow.rb:1174:9:1174:9 | a [element 2] : | +| array_flow.rb:1173:5:1173:5 | a [element 2] : | array_flow.rb:1177:10:1177:10 | a [element 2] : | +| array_flow.rb:1173:5:1173:5 | a [element 2] : | array_flow.rb:1177:10:1177:10 | a [element 2] : | +| array_flow.rb:1173:16:1173:26 | call to source : | array_flow.rb:1173:5:1173:5 | a [element 2] : | +| array_flow.rb:1173:16:1173:26 | call to source : | array_flow.rb:1173:5:1173:5 | a [element 2] : | +| array_flow.rb:1174:5:1174:5 | b [element] : | array_flow.rb:1178:10:1178:10 | b [element] : | +| array_flow.rb:1174:5:1174:5 | b [element] : | array_flow.rb:1178:10:1178:10 | b [element] : | +| array_flow.rb:1174:5:1174:5 | b [element] : | array_flow.rb:1179:10:1179:10 | b [element] : | +| array_flow.rb:1174:5:1174:5 | b [element] : | array_flow.rb:1179:10:1179:10 | b [element] : | +| array_flow.rb:1174:5:1174:5 | b [element] : | array_flow.rb:1180:10:1180:10 | b [element] : | +| array_flow.rb:1174:5:1174:5 | b [element] : | array_flow.rb:1180:10:1180:10 | b [element] : | | array_flow.rb:1174:9:1174:9 | a [element 2] : | array_flow.rb:1174:9:1174:17 | call to shuffle [element] : | | array_flow.rb:1174:9:1174:9 | a [element 2] : | array_flow.rb:1174:9:1174:17 | call to shuffle [element] : | -| array_flow.rb:1174:9:1174:17 | call to shuffle [element] : | array_flow.rb:1178:10:1178:10 | b [element] : | -| array_flow.rb:1174:9:1174:17 | call to shuffle [element] : | array_flow.rb:1178:10:1178:10 | b [element] : | -| array_flow.rb:1174:9:1174:17 | call to shuffle [element] : | array_flow.rb:1179:10:1179:10 | b [element] : | -| array_flow.rb:1174:9:1174:17 | call to shuffle [element] : | array_flow.rb:1179:10:1179:10 | b [element] : | -| array_flow.rb:1174:9:1174:17 | call to shuffle [element] : | array_flow.rb:1180:10:1180:10 | b [element] : | -| array_flow.rb:1174:9:1174:17 | call to shuffle [element] : | array_flow.rb:1180:10:1180:10 | b [element] : | +| array_flow.rb:1174:9:1174:17 | call to shuffle [element] : | array_flow.rb:1174:5:1174:5 | b [element] : | +| array_flow.rb:1174:9:1174:17 | call to shuffle [element] : | array_flow.rb:1174:5:1174:5 | b [element] : | | array_flow.rb:1177:10:1177:10 | a [element 2] : | array_flow.rb:1177:10:1177:13 | ...[...] | | array_flow.rb:1177:10:1177:10 | a [element 2] : | array_flow.rb:1177:10:1177:13 | ...[...] | | array_flow.rb:1178:10:1178:10 | b [element] : | array_flow.rb:1178:10:1178:13 | ...[...] | @@ -2355,10 +2930,18 @@ edges | array_flow.rb:1179:10:1179:10 | b [element] : | array_flow.rb:1179:10:1179:13 | ...[...] | | array_flow.rb:1180:10:1180:10 | b [element] : | array_flow.rb:1180:10:1180:13 | ...[...] | | array_flow.rb:1180:10:1180:10 | b [element] : | array_flow.rb:1180:10:1180:13 | ...[...] | -| array_flow.rb:1184:16:1184:26 | call to source : | array_flow.rb:1185:9:1185:9 | a [element 2] : | -| array_flow.rb:1184:16:1184:26 | call to source : | array_flow.rb:1185:9:1185:9 | a [element 2] : | -| array_flow.rb:1184:16:1184:26 | call to source : | array_flow.rb:1188:10:1188:10 | a [element 2] : | -| array_flow.rb:1184:16:1184:26 | call to source : | array_flow.rb:1188:10:1188:10 | a [element 2] : | +| array_flow.rb:1184:5:1184:5 | a [element 2] : | array_flow.rb:1185:9:1185:9 | a [element 2] : | +| array_flow.rb:1184:5:1184:5 | a [element 2] : | array_flow.rb:1185:9:1185:9 | a [element 2] : | +| array_flow.rb:1184:5:1184:5 | a [element 2] : | array_flow.rb:1188:10:1188:10 | a [element 2] : | +| array_flow.rb:1184:5:1184:5 | a [element 2] : | array_flow.rb:1188:10:1188:10 | a [element 2] : | +| array_flow.rb:1184:16:1184:26 | call to source : | array_flow.rb:1184:5:1184:5 | a [element 2] : | +| array_flow.rb:1184:16:1184:26 | call to source : | array_flow.rb:1184:5:1184:5 | a [element 2] : | +| array_flow.rb:1185:5:1185:5 | b [element] : | array_flow.rb:1189:10:1189:10 | b [element] : | +| array_flow.rb:1185:5:1185:5 | b [element] : | array_flow.rb:1189:10:1189:10 | b [element] : | +| array_flow.rb:1185:5:1185:5 | b [element] : | array_flow.rb:1190:10:1190:10 | b [element] : | +| array_flow.rb:1185:5:1185:5 | b [element] : | array_flow.rb:1190:10:1190:10 | b [element] : | +| array_flow.rb:1185:5:1185:5 | b [element] : | array_flow.rb:1191:10:1191:10 | b [element] : | +| array_flow.rb:1185:5:1185:5 | b [element] : | array_flow.rb:1191:10:1191:10 | b [element] : | | array_flow.rb:1185:9:1185:9 | [post] a [element] : | array_flow.rb:1186:10:1186:10 | a [element] : | | array_flow.rb:1185:9:1185:9 | [post] a [element] : | array_flow.rb:1186:10:1186:10 | a [element] : | | array_flow.rb:1185:9:1185:9 | [post] a [element] : | array_flow.rb:1187:10:1187:10 | a [element] : | @@ -2369,12 +2952,8 @@ edges | array_flow.rb:1185:9:1185:9 | a [element 2] : | array_flow.rb:1185:9:1185:9 | [post] a [element] : | | array_flow.rb:1185:9:1185:9 | a [element 2] : | array_flow.rb:1185:9:1185:18 | call to shuffle! [element] : | | array_flow.rb:1185:9:1185:9 | a [element 2] : | array_flow.rb:1185:9:1185:18 | call to shuffle! [element] : | -| array_flow.rb:1185:9:1185:18 | call to shuffle! [element] : | array_flow.rb:1189:10:1189:10 | b [element] : | -| array_flow.rb:1185:9:1185:18 | call to shuffle! [element] : | array_flow.rb:1189:10:1189:10 | b [element] : | -| array_flow.rb:1185:9:1185:18 | call to shuffle! [element] : | array_flow.rb:1190:10:1190:10 | b [element] : | -| array_flow.rb:1185:9:1185:18 | call to shuffle! [element] : | array_flow.rb:1190:10:1190:10 | b [element] : | -| array_flow.rb:1185:9:1185:18 | call to shuffle! [element] : | array_flow.rb:1191:10:1191:10 | b [element] : | -| array_flow.rb:1185:9:1185:18 | call to shuffle! [element] : | array_flow.rb:1191:10:1191:10 | b [element] : | +| array_flow.rb:1185:9:1185:18 | call to shuffle! [element] : | array_flow.rb:1185:5:1185:5 | b [element] : | +| array_flow.rb:1185:9:1185:18 | call to shuffle! [element] : | array_flow.rb:1185:5:1185:5 | b [element] : | | array_flow.rb:1186:10:1186:10 | a [element] : | array_flow.rb:1186:10:1186:13 | ...[...] | | array_flow.rb:1186:10:1186:10 | a [element] : | array_flow.rb:1186:10:1186:13 | ...[...] | | array_flow.rb:1187:10:1187:10 | a [element] : | array_flow.rb:1187:10:1187:13 | ...[...] | @@ -2389,52 +2968,65 @@ edges | array_flow.rb:1190:10:1190:10 | b [element] : | array_flow.rb:1190:10:1190:13 | ...[...] | | array_flow.rb:1191:10:1191:10 | b [element] : | array_flow.rb:1191:10:1191:13 | ...[...] | | array_flow.rb:1191:10:1191:10 | b [element] : | array_flow.rb:1191:10:1191:13 | ...[...] | -| array_flow.rb:1195:16:1195:28 | call to source : | array_flow.rb:1200:9:1200:9 | a [element 2] : | -| array_flow.rb:1195:16:1195:28 | call to source : | array_flow.rb:1200:9:1200:9 | a [element 2] : | -| array_flow.rb:1195:16:1195:28 | call to source : | array_flow.rb:1203:9:1203:9 | a [element 2] : | -| array_flow.rb:1195:16:1195:28 | call to source : | array_flow.rb:1203:9:1203:9 | a [element 2] : | -| array_flow.rb:1195:16:1195:28 | call to source : | array_flow.rb:1209:9:1209:9 | a [element 2] : | -| array_flow.rb:1195:16:1195:28 | call to source : | array_flow.rb:1209:9:1209:9 | a [element 2] : | -| array_flow.rb:1195:16:1195:28 | call to source : | array_flow.rb:1214:9:1214:9 | a [element 2] : | -| array_flow.rb:1195:16:1195:28 | call to source : | array_flow.rb:1214:9:1214:9 | a [element 2] : | -| array_flow.rb:1195:16:1195:28 | call to source : | array_flow.rb:1218:9:1218:9 | a [element 2] : | -| array_flow.rb:1195:16:1195:28 | call to source : | array_flow.rb:1218:9:1218:9 | a [element 2] : | -| array_flow.rb:1195:16:1195:28 | call to source : | array_flow.rb:1223:9:1223:9 | a [element 2] : | -| array_flow.rb:1195:16:1195:28 | call to source : | array_flow.rb:1223:9:1223:9 | a [element 2] : | -| array_flow.rb:1195:16:1195:28 | call to source : | array_flow.rb:1228:9:1228:9 | a [element 2] : | -| array_flow.rb:1195:16:1195:28 | call to source : | array_flow.rb:1228:9:1228:9 | a [element 2] : | -| array_flow.rb:1195:16:1195:28 | call to source : | array_flow.rb:1232:9:1232:9 | a [element 2] : | -| array_flow.rb:1195:16:1195:28 | call to source : | array_flow.rb:1232:9:1232:9 | a [element 2] : | -| array_flow.rb:1195:16:1195:28 | call to source : | array_flow.rb:1236:9:1236:9 | a [element 2] : | -| array_flow.rb:1195:16:1195:28 | call to source : | array_flow.rb:1236:9:1236:9 | a [element 2] : | -| array_flow.rb:1195:16:1195:28 | call to source : | array_flow.rb:1241:9:1241:9 | a [element 2] : | -| array_flow.rb:1195:16:1195:28 | call to source : | array_flow.rb:1241:9:1241:9 | a [element 2] : | -| array_flow.rb:1195:34:1195:46 | call to source : | array_flow.rb:1197:9:1197:9 | a [element 4] : | -| array_flow.rb:1195:34:1195:46 | call to source : | array_flow.rb:1197:9:1197:9 | a [element 4] : | -| array_flow.rb:1195:34:1195:46 | call to source : | array_flow.rb:1200:9:1200:9 | a [element 4] : | -| array_flow.rb:1195:34:1195:46 | call to source : | array_flow.rb:1200:9:1200:9 | a [element 4] : | -| array_flow.rb:1195:34:1195:46 | call to source : | array_flow.rb:1203:9:1203:9 | a [element 4] : | -| array_flow.rb:1195:34:1195:46 | call to source : | array_flow.rb:1203:9:1203:9 | a [element 4] : | -| array_flow.rb:1195:34:1195:46 | call to source : | array_flow.rb:1209:9:1209:9 | a [element 4] : | -| array_flow.rb:1195:34:1195:46 | call to source : | array_flow.rb:1209:9:1209:9 | a [element 4] : | -| array_flow.rb:1195:34:1195:46 | call to source : | array_flow.rb:1214:9:1214:9 | a [element 4] : | -| array_flow.rb:1195:34:1195:46 | call to source : | array_flow.rb:1214:9:1214:9 | a [element 4] : | -| array_flow.rb:1195:34:1195:46 | call to source : | array_flow.rb:1228:9:1228:9 | a [element 4] : | -| array_flow.rb:1195:34:1195:46 | call to source : | array_flow.rb:1228:9:1228:9 | a [element 4] : | -| array_flow.rb:1195:34:1195:46 | call to source : | array_flow.rb:1232:9:1232:9 | a [element 4] : | -| array_flow.rb:1195:34:1195:46 | call to source : | array_flow.rb:1232:9:1232:9 | a [element 4] : | -| array_flow.rb:1195:34:1195:46 | call to source : | array_flow.rb:1241:9:1241:9 | a [element 4] : | -| array_flow.rb:1195:34:1195:46 | call to source : | array_flow.rb:1241:9:1241:9 | a [element 4] : | +| array_flow.rb:1195:5:1195:5 | a [element 2] : | array_flow.rb:1200:9:1200:9 | a [element 2] : | +| array_flow.rb:1195:5:1195:5 | a [element 2] : | array_flow.rb:1200:9:1200:9 | a [element 2] : | +| array_flow.rb:1195:5:1195:5 | a [element 2] : | array_flow.rb:1203:9:1203:9 | a [element 2] : | +| array_flow.rb:1195:5:1195:5 | a [element 2] : | array_flow.rb:1203:9:1203:9 | a [element 2] : | +| array_flow.rb:1195:5:1195:5 | a [element 2] : | array_flow.rb:1209:9:1209:9 | a [element 2] : | +| array_flow.rb:1195:5:1195:5 | a [element 2] : | array_flow.rb:1209:9:1209:9 | a [element 2] : | +| array_flow.rb:1195:5:1195:5 | a [element 2] : | array_flow.rb:1214:9:1214:9 | a [element 2] : | +| array_flow.rb:1195:5:1195:5 | a [element 2] : | array_flow.rb:1214:9:1214:9 | a [element 2] : | +| array_flow.rb:1195:5:1195:5 | a [element 2] : | array_flow.rb:1218:9:1218:9 | a [element 2] : | +| array_flow.rb:1195:5:1195:5 | a [element 2] : | array_flow.rb:1218:9:1218:9 | a [element 2] : | +| array_flow.rb:1195:5:1195:5 | a [element 2] : | array_flow.rb:1223:9:1223:9 | a [element 2] : | +| array_flow.rb:1195:5:1195:5 | a [element 2] : | array_flow.rb:1223:9:1223:9 | a [element 2] : | +| array_flow.rb:1195:5:1195:5 | a [element 2] : | array_flow.rb:1228:9:1228:9 | a [element 2] : | +| array_flow.rb:1195:5:1195:5 | a [element 2] : | array_flow.rb:1228:9:1228:9 | a [element 2] : | +| array_flow.rb:1195:5:1195:5 | a [element 2] : | array_flow.rb:1232:9:1232:9 | a [element 2] : | +| array_flow.rb:1195:5:1195:5 | a [element 2] : | array_flow.rb:1232:9:1232:9 | a [element 2] : | +| array_flow.rb:1195:5:1195:5 | a [element 2] : | array_flow.rb:1236:9:1236:9 | a [element 2] : | +| array_flow.rb:1195:5:1195:5 | a [element 2] : | array_flow.rb:1236:9:1236:9 | a [element 2] : | +| array_flow.rb:1195:5:1195:5 | a [element 2] : | array_flow.rb:1241:9:1241:9 | a [element 2] : | +| array_flow.rb:1195:5:1195:5 | a [element 2] : | array_flow.rb:1241:9:1241:9 | a [element 2] : | +| array_flow.rb:1195:5:1195:5 | a [element 4] : | array_flow.rb:1197:9:1197:9 | a [element 4] : | +| array_flow.rb:1195:5:1195:5 | a [element 4] : | array_flow.rb:1197:9:1197:9 | a [element 4] : | +| array_flow.rb:1195:5:1195:5 | a [element 4] : | array_flow.rb:1200:9:1200:9 | a [element 4] : | +| array_flow.rb:1195:5:1195:5 | a [element 4] : | array_flow.rb:1200:9:1200:9 | a [element 4] : | +| array_flow.rb:1195:5:1195:5 | a [element 4] : | array_flow.rb:1203:9:1203:9 | a [element 4] : | +| array_flow.rb:1195:5:1195:5 | a [element 4] : | array_flow.rb:1203:9:1203:9 | a [element 4] : | +| array_flow.rb:1195:5:1195:5 | a [element 4] : | array_flow.rb:1209:9:1209:9 | a [element 4] : | +| array_flow.rb:1195:5:1195:5 | a [element 4] : | array_flow.rb:1209:9:1209:9 | a [element 4] : | +| array_flow.rb:1195:5:1195:5 | a [element 4] : | array_flow.rb:1214:9:1214:9 | a [element 4] : | +| array_flow.rb:1195:5:1195:5 | a [element 4] : | array_flow.rb:1214:9:1214:9 | a [element 4] : | +| array_flow.rb:1195:5:1195:5 | a [element 4] : | array_flow.rb:1228:9:1228:9 | a [element 4] : | +| array_flow.rb:1195:5:1195:5 | a [element 4] : | array_flow.rb:1228:9:1228:9 | a [element 4] : | +| array_flow.rb:1195:5:1195:5 | a [element 4] : | array_flow.rb:1232:9:1232:9 | a [element 4] : | +| array_flow.rb:1195:5:1195:5 | a [element 4] : | array_flow.rb:1232:9:1232:9 | a [element 4] : | +| array_flow.rb:1195:5:1195:5 | a [element 4] : | array_flow.rb:1241:9:1241:9 | a [element 4] : | +| array_flow.rb:1195:5:1195:5 | a [element 4] : | array_flow.rb:1241:9:1241:9 | a [element 4] : | +| array_flow.rb:1195:16:1195:28 | call to source : | array_flow.rb:1195:5:1195:5 | a [element 2] : | +| array_flow.rb:1195:16:1195:28 | call to source : | array_flow.rb:1195:5:1195:5 | a [element 2] : | +| array_flow.rb:1195:34:1195:46 | call to source : | array_flow.rb:1195:5:1195:5 | a [element 4] : | +| array_flow.rb:1195:34:1195:46 | call to source : | array_flow.rb:1195:5:1195:5 | a [element 4] : | +| array_flow.rb:1197:5:1197:5 | b : | array_flow.rb:1198:10:1198:10 | b | +| array_flow.rb:1197:5:1197:5 | b : | array_flow.rb:1198:10:1198:10 | b | | array_flow.rb:1197:9:1197:9 | a [element 4] : | array_flow.rb:1197:9:1197:17 | call to slice : | | array_flow.rb:1197:9:1197:9 | a [element 4] : | array_flow.rb:1197:9:1197:17 | call to slice : | -| array_flow.rb:1197:9:1197:17 | call to slice : | array_flow.rb:1198:10:1198:10 | b | -| array_flow.rb:1197:9:1197:17 | call to slice : | array_flow.rb:1198:10:1198:10 | b | +| array_flow.rb:1197:9:1197:17 | call to slice : | array_flow.rb:1197:5:1197:5 | b : | +| array_flow.rb:1197:9:1197:17 | call to slice : | array_flow.rb:1197:5:1197:5 | b : | +| array_flow.rb:1200:5:1200:5 | b : | array_flow.rb:1201:10:1201:10 | b | +| array_flow.rb:1200:5:1200:5 | b : | array_flow.rb:1201:10:1201:10 | b | | array_flow.rb:1200:9:1200:9 | a [element 2] : | array_flow.rb:1200:9:1200:19 | call to slice : | | array_flow.rb:1200:9:1200:9 | a [element 2] : | array_flow.rb:1200:9:1200:19 | call to slice : | | array_flow.rb:1200:9:1200:9 | a [element 4] : | array_flow.rb:1200:9:1200:19 | call to slice : | | array_flow.rb:1200:9:1200:9 | a [element 4] : | array_flow.rb:1200:9:1200:19 | call to slice : | -| array_flow.rb:1200:9:1200:19 | call to slice : | array_flow.rb:1201:10:1201:10 | b | -| array_flow.rb:1200:9:1200:19 | call to slice : | array_flow.rb:1201:10:1201:10 | b | +| array_flow.rb:1200:9:1200:19 | call to slice : | array_flow.rb:1200:5:1200:5 | b : | +| array_flow.rb:1200:9:1200:19 | call to slice : | array_flow.rb:1200:5:1200:5 | b : | +| array_flow.rb:1203:5:1203:5 | b : | array_flow.rb:1205:10:1205:10 | b | +| array_flow.rb:1203:5:1203:5 | b : | array_flow.rb:1205:10:1205:10 | b | +| array_flow.rb:1203:5:1203:5 | b : | array_flow.rb:1207:10:1207:10 | b : | +| array_flow.rb:1203:5:1203:5 | b [element] : | array_flow.rb:1207:10:1207:10 | b [element] : | +| array_flow.rb:1203:5:1203:5 | b [element] : | array_flow.rb:1207:10:1207:10 | b [element] : | | array_flow.rb:1203:9:1203:9 | a [element 2] : | array_flow.rb:1203:9:1203:17 | call to slice : | | array_flow.rb:1203:9:1203:9 | a [element 2] : | array_flow.rb:1203:9:1203:17 | call to slice : | | array_flow.rb:1203:9:1203:9 | a [element 2] : | array_flow.rb:1203:9:1203:17 | call to slice [element] : | @@ -2443,114 +3035,146 @@ edges | array_flow.rb:1203:9:1203:9 | a [element 4] : | array_flow.rb:1203:9:1203:17 | call to slice : | | array_flow.rb:1203:9:1203:9 | a [element 4] : | array_flow.rb:1203:9:1203:17 | call to slice [element] : | | array_flow.rb:1203:9:1203:9 | a [element 4] : | array_flow.rb:1203:9:1203:17 | call to slice [element] : | -| array_flow.rb:1203:9:1203:17 | call to slice : | array_flow.rb:1205:10:1205:10 | b | -| array_flow.rb:1203:9:1203:17 | call to slice : | array_flow.rb:1205:10:1205:10 | b | -| array_flow.rb:1203:9:1203:17 | call to slice : | array_flow.rb:1207:10:1207:10 | b : | -| array_flow.rb:1203:9:1203:17 | call to slice [element] : | array_flow.rb:1207:10:1207:10 | b [element] : | -| array_flow.rb:1203:9:1203:17 | call to slice [element] : | array_flow.rb:1207:10:1207:10 | b [element] : | +| array_flow.rb:1203:9:1203:17 | call to slice : | array_flow.rb:1203:5:1203:5 | b : | +| array_flow.rb:1203:9:1203:17 | call to slice : | array_flow.rb:1203:5:1203:5 | b : | +| array_flow.rb:1203:9:1203:17 | call to slice [element] : | array_flow.rb:1203:5:1203:5 | b [element] : | +| array_flow.rb:1203:9:1203:17 | call to slice [element] : | array_flow.rb:1203:5:1203:5 | b [element] : | | array_flow.rb:1207:10:1207:10 | b : | array_flow.rb:1207:10:1207:13 | ...[...] | | array_flow.rb:1207:10:1207:10 | b [element] : | array_flow.rb:1207:10:1207:13 | ...[...] | | array_flow.rb:1207:10:1207:10 | b [element] : | array_flow.rb:1207:10:1207:13 | ...[...] | +| array_flow.rb:1209:5:1209:5 | b [element 0] : | array_flow.rb:1210:10:1210:10 | b [element 0] : | +| array_flow.rb:1209:5:1209:5 | b [element 0] : | array_flow.rb:1210:10:1210:10 | b [element 0] : | +| array_flow.rb:1209:5:1209:5 | b [element 2] : | array_flow.rb:1212:10:1212:10 | b [element 2] : | +| array_flow.rb:1209:5:1209:5 | b [element 2] : | array_flow.rb:1212:10:1212:10 | b [element 2] : | | array_flow.rb:1209:9:1209:9 | a [element 2] : | array_flow.rb:1209:9:1209:21 | call to slice [element 0] : | | array_flow.rb:1209:9:1209:9 | a [element 2] : | array_flow.rb:1209:9:1209:21 | call to slice [element 0] : | | array_flow.rb:1209:9:1209:9 | a [element 4] : | array_flow.rb:1209:9:1209:21 | call to slice [element 2] : | | array_flow.rb:1209:9:1209:9 | a [element 4] : | array_flow.rb:1209:9:1209:21 | call to slice [element 2] : | -| array_flow.rb:1209:9:1209:21 | call to slice [element 0] : | array_flow.rb:1210:10:1210:10 | b [element 0] : | -| array_flow.rb:1209:9:1209:21 | call to slice [element 0] : | array_flow.rb:1210:10:1210:10 | b [element 0] : | -| array_flow.rb:1209:9:1209:21 | call to slice [element 2] : | array_flow.rb:1212:10:1212:10 | b [element 2] : | -| array_flow.rb:1209:9:1209:21 | call to slice [element 2] : | array_flow.rb:1212:10:1212:10 | b [element 2] : | +| array_flow.rb:1209:9:1209:21 | call to slice [element 0] : | array_flow.rb:1209:5:1209:5 | b [element 0] : | +| array_flow.rb:1209:9:1209:21 | call to slice [element 0] : | array_flow.rb:1209:5:1209:5 | b [element 0] : | +| array_flow.rb:1209:9:1209:21 | call to slice [element 2] : | array_flow.rb:1209:5:1209:5 | b [element 2] : | +| array_flow.rb:1209:9:1209:21 | call to slice [element 2] : | array_flow.rb:1209:5:1209:5 | b [element 2] : | | array_flow.rb:1210:10:1210:10 | b [element 0] : | array_flow.rb:1210:10:1210:13 | ...[...] | | array_flow.rb:1210:10:1210:10 | b [element 0] : | array_flow.rb:1210:10:1210:13 | ...[...] | | array_flow.rb:1212:10:1212:10 | b [element 2] : | array_flow.rb:1212:10:1212:13 | ...[...] | | array_flow.rb:1212:10:1212:10 | b [element 2] : | array_flow.rb:1212:10:1212:13 | ...[...] | +| array_flow.rb:1214:5:1214:5 | b [element] : | array_flow.rb:1215:10:1215:10 | b [element] : | +| array_flow.rb:1214:5:1214:5 | b [element] : | array_flow.rb:1215:10:1215:10 | b [element] : | +| array_flow.rb:1214:5:1214:5 | b [element] : | array_flow.rb:1216:10:1216:10 | b [element] : | +| array_flow.rb:1214:5:1214:5 | b [element] : | array_flow.rb:1216:10:1216:10 | b [element] : | | array_flow.rb:1214:9:1214:9 | a [element 2] : | array_flow.rb:1214:9:1214:21 | call to slice [element] : | | array_flow.rb:1214:9:1214:9 | a [element 2] : | array_flow.rb:1214:9:1214:21 | call to slice [element] : | | array_flow.rb:1214:9:1214:9 | a [element 4] : | array_flow.rb:1214:9:1214:21 | call to slice [element] : | | array_flow.rb:1214:9:1214:9 | a [element 4] : | array_flow.rb:1214:9:1214:21 | call to slice [element] : | -| array_flow.rb:1214:9:1214:21 | call to slice [element] : | array_flow.rb:1215:10:1215:10 | b [element] : | -| array_flow.rb:1214:9:1214:21 | call to slice [element] : | array_flow.rb:1215:10:1215:10 | b [element] : | -| array_flow.rb:1214:9:1214:21 | call to slice [element] : | array_flow.rb:1216:10:1216:10 | b [element] : | -| array_flow.rb:1214:9:1214:21 | call to slice [element] : | array_flow.rb:1216:10:1216:10 | b [element] : | +| array_flow.rb:1214:9:1214:21 | call to slice [element] : | array_flow.rb:1214:5:1214:5 | b [element] : | +| array_flow.rb:1214:9:1214:21 | call to slice [element] : | array_flow.rb:1214:5:1214:5 | b [element] : | | array_flow.rb:1215:10:1215:10 | b [element] : | array_flow.rb:1215:10:1215:13 | ...[...] | | array_flow.rb:1215:10:1215:10 | b [element] : | array_flow.rb:1215:10:1215:13 | ...[...] | | array_flow.rb:1216:10:1216:10 | b [element] : | array_flow.rb:1216:10:1216:13 | ...[...] | | array_flow.rb:1216:10:1216:10 | b [element] : | array_flow.rb:1216:10:1216:13 | ...[...] | +| array_flow.rb:1218:5:1218:5 | b [element 0] : | array_flow.rb:1219:10:1219:10 | b [element 0] : | +| array_flow.rb:1218:5:1218:5 | b [element 0] : | array_flow.rb:1219:10:1219:10 | b [element 0] : | | array_flow.rb:1218:9:1218:9 | a [element 2] : | array_flow.rb:1218:9:1218:21 | call to slice [element 0] : | | array_flow.rb:1218:9:1218:9 | a [element 2] : | array_flow.rb:1218:9:1218:21 | call to slice [element 0] : | -| array_flow.rb:1218:9:1218:21 | call to slice [element 0] : | array_flow.rb:1219:10:1219:10 | b [element 0] : | -| array_flow.rb:1218:9:1218:21 | call to slice [element 0] : | array_flow.rb:1219:10:1219:10 | b [element 0] : | +| array_flow.rb:1218:9:1218:21 | call to slice [element 0] : | array_flow.rb:1218:5:1218:5 | b [element 0] : | +| array_flow.rb:1218:9:1218:21 | call to slice [element 0] : | array_flow.rb:1218:5:1218:5 | b [element 0] : | | array_flow.rb:1219:10:1219:10 | b [element 0] : | array_flow.rb:1219:10:1219:13 | ...[...] | | array_flow.rb:1219:10:1219:10 | b [element 0] : | array_flow.rb:1219:10:1219:13 | ...[...] | +| array_flow.rb:1223:5:1223:5 | b [element 0] : | array_flow.rb:1224:10:1224:10 | b [element 0] : | +| array_flow.rb:1223:5:1223:5 | b [element 0] : | array_flow.rb:1224:10:1224:10 | b [element 0] : | | array_flow.rb:1223:9:1223:9 | a [element 2] : | array_flow.rb:1223:9:1223:22 | call to slice [element 0] : | | array_flow.rb:1223:9:1223:9 | a [element 2] : | array_flow.rb:1223:9:1223:22 | call to slice [element 0] : | -| array_flow.rb:1223:9:1223:22 | call to slice [element 0] : | array_flow.rb:1224:10:1224:10 | b [element 0] : | -| array_flow.rb:1223:9:1223:22 | call to slice [element 0] : | array_flow.rb:1224:10:1224:10 | b [element 0] : | +| array_flow.rb:1223:9:1223:22 | call to slice [element 0] : | array_flow.rb:1223:5:1223:5 | b [element 0] : | +| array_flow.rb:1223:9:1223:22 | call to slice [element 0] : | array_flow.rb:1223:5:1223:5 | b [element 0] : | | array_flow.rb:1224:10:1224:10 | b [element 0] : | array_flow.rb:1224:10:1224:13 | ...[...] | | array_flow.rb:1224:10:1224:10 | b [element 0] : | array_flow.rb:1224:10:1224:13 | ...[...] | +| array_flow.rb:1228:5:1228:5 | b [element] : | array_flow.rb:1229:10:1229:10 | b [element] : | +| array_flow.rb:1228:5:1228:5 | b [element] : | array_flow.rb:1229:10:1229:10 | b [element] : | +| array_flow.rb:1228:5:1228:5 | b [element] : | array_flow.rb:1230:10:1230:10 | b [element] : | +| array_flow.rb:1228:5:1228:5 | b [element] : | array_flow.rb:1230:10:1230:10 | b [element] : | | array_flow.rb:1228:9:1228:9 | a [element 2] : | array_flow.rb:1228:9:1228:21 | call to slice [element] : | | array_flow.rb:1228:9:1228:9 | a [element 2] : | array_flow.rb:1228:9:1228:21 | call to slice [element] : | | array_flow.rb:1228:9:1228:9 | a [element 4] : | array_flow.rb:1228:9:1228:21 | call to slice [element] : | | array_flow.rb:1228:9:1228:9 | a [element 4] : | array_flow.rb:1228:9:1228:21 | call to slice [element] : | -| array_flow.rb:1228:9:1228:21 | call to slice [element] : | array_flow.rb:1229:10:1229:10 | b [element] : | -| array_flow.rb:1228:9:1228:21 | call to slice [element] : | array_flow.rb:1229:10:1229:10 | b [element] : | -| array_flow.rb:1228:9:1228:21 | call to slice [element] : | array_flow.rb:1230:10:1230:10 | b [element] : | -| array_flow.rb:1228:9:1228:21 | call to slice [element] : | array_flow.rb:1230:10:1230:10 | b [element] : | +| array_flow.rb:1228:9:1228:21 | call to slice [element] : | array_flow.rb:1228:5:1228:5 | b [element] : | +| array_flow.rb:1228:9:1228:21 | call to slice [element] : | array_flow.rb:1228:5:1228:5 | b [element] : | | array_flow.rb:1229:10:1229:10 | b [element] : | array_flow.rb:1229:10:1229:13 | ...[...] | | array_flow.rb:1229:10:1229:10 | b [element] : | array_flow.rb:1229:10:1229:13 | ...[...] | | array_flow.rb:1230:10:1230:10 | b [element] : | array_flow.rb:1230:10:1230:13 | ...[...] | | array_flow.rb:1230:10:1230:10 | b [element] : | array_flow.rb:1230:10:1230:13 | ...[...] | +| array_flow.rb:1232:5:1232:5 | b [element] : | array_flow.rb:1233:10:1233:10 | b [element] : | +| array_flow.rb:1232:5:1232:5 | b [element] : | array_flow.rb:1233:10:1233:10 | b [element] : | +| array_flow.rb:1232:5:1232:5 | b [element] : | array_flow.rb:1234:10:1234:10 | b [element] : | +| array_flow.rb:1232:5:1232:5 | b [element] : | array_flow.rb:1234:10:1234:10 | b [element] : | | array_flow.rb:1232:9:1232:9 | a [element 2] : | array_flow.rb:1232:9:1232:24 | call to slice [element] : | | array_flow.rb:1232:9:1232:9 | a [element 2] : | array_flow.rb:1232:9:1232:24 | call to slice [element] : | | array_flow.rb:1232:9:1232:9 | a [element 4] : | array_flow.rb:1232:9:1232:24 | call to slice [element] : | | array_flow.rb:1232:9:1232:9 | a [element 4] : | array_flow.rb:1232:9:1232:24 | call to slice [element] : | -| array_flow.rb:1232:9:1232:24 | call to slice [element] : | array_flow.rb:1233:10:1233:10 | b [element] : | -| array_flow.rb:1232:9:1232:24 | call to slice [element] : | array_flow.rb:1233:10:1233:10 | b [element] : | -| array_flow.rb:1232:9:1232:24 | call to slice [element] : | array_flow.rb:1234:10:1234:10 | b [element] : | -| array_flow.rb:1232:9:1232:24 | call to slice [element] : | array_flow.rb:1234:10:1234:10 | b [element] : | +| array_flow.rb:1232:9:1232:24 | call to slice [element] : | array_flow.rb:1232:5:1232:5 | b [element] : | +| array_flow.rb:1232:9:1232:24 | call to slice [element] : | array_flow.rb:1232:5:1232:5 | b [element] : | | array_flow.rb:1233:10:1233:10 | b [element] : | array_flow.rb:1233:10:1233:13 | ...[...] | | array_flow.rb:1233:10:1233:10 | b [element] : | array_flow.rb:1233:10:1233:13 | ...[...] | | array_flow.rb:1234:10:1234:10 | b [element] : | array_flow.rb:1234:10:1234:13 | ...[...] | | array_flow.rb:1234:10:1234:10 | b [element] : | array_flow.rb:1234:10:1234:13 | ...[...] | +| array_flow.rb:1236:5:1236:5 | b [element 2] : | array_flow.rb:1239:10:1239:10 | b [element 2] : | +| array_flow.rb:1236:5:1236:5 | b [element 2] : | array_flow.rb:1239:10:1239:10 | b [element 2] : | | array_flow.rb:1236:9:1236:9 | a [element 2] : | array_flow.rb:1236:9:1236:20 | call to slice [element 2] : | | array_flow.rb:1236:9:1236:9 | a [element 2] : | array_flow.rb:1236:9:1236:20 | call to slice [element 2] : | -| array_flow.rb:1236:9:1236:20 | call to slice [element 2] : | array_flow.rb:1239:10:1239:10 | b [element 2] : | -| array_flow.rb:1236:9:1236:20 | call to slice [element 2] : | array_flow.rb:1239:10:1239:10 | b [element 2] : | +| array_flow.rb:1236:9:1236:20 | call to slice [element 2] : | array_flow.rb:1236:5:1236:5 | b [element 2] : | +| array_flow.rb:1236:9:1236:20 | call to slice [element 2] : | array_flow.rb:1236:5:1236:5 | b [element 2] : | | array_flow.rb:1239:10:1239:10 | b [element 2] : | array_flow.rb:1239:10:1239:13 | ...[...] | | array_flow.rb:1239:10:1239:10 | b [element 2] : | array_flow.rb:1239:10:1239:13 | ...[...] | +| array_flow.rb:1241:5:1241:5 | b [element] : | array_flow.rb:1242:10:1242:10 | b [element] : | +| array_flow.rb:1241:5:1241:5 | b [element] : | array_flow.rb:1242:10:1242:10 | b [element] : | +| array_flow.rb:1241:5:1241:5 | b [element] : | array_flow.rb:1243:10:1243:10 | b [element] : | +| array_flow.rb:1241:5:1241:5 | b [element] : | array_flow.rb:1243:10:1243:10 | b [element] : | +| array_flow.rb:1241:5:1241:5 | b [element] : | array_flow.rb:1244:10:1244:10 | b [element] : | +| array_flow.rb:1241:5:1241:5 | b [element] : | array_flow.rb:1244:10:1244:10 | b [element] : | | array_flow.rb:1241:9:1241:9 | a [element 2] : | array_flow.rb:1241:9:1241:20 | call to slice [element] : | | array_flow.rb:1241:9:1241:9 | a [element 2] : | array_flow.rb:1241:9:1241:20 | call to slice [element] : | | array_flow.rb:1241:9:1241:9 | a [element 4] : | array_flow.rb:1241:9:1241:20 | call to slice [element] : | | array_flow.rb:1241:9:1241:9 | a [element 4] : | array_flow.rb:1241:9:1241:20 | call to slice [element] : | -| array_flow.rb:1241:9:1241:20 | call to slice [element] : | array_flow.rb:1242:10:1242:10 | b [element] : | -| array_flow.rb:1241:9:1241:20 | call to slice [element] : | array_flow.rb:1242:10:1242:10 | b [element] : | -| array_flow.rb:1241:9:1241:20 | call to slice [element] : | array_flow.rb:1243:10:1243:10 | b [element] : | -| array_flow.rb:1241:9:1241:20 | call to slice [element] : | array_flow.rb:1243:10:1243:10 | b [element] : | -| array_flow.rb:1241:9:1241:20 | call to slice [element] : | array_flow.rb:1244:10:1244:10 | b [element] : | -| array_flow.rb:1241:9:1241:20 | call to slice [element] : | array_flow.rb:1244:10:1244:10 | b [element] : | +| array_flow.rb:1241:9:1241:20 | call to slice [element] : | array_flow.rb:1241:5:1241:5 | b [element] : | +| array_flow.rb:1241:9:1241:20 | call to slice [element] : | array_flow.rb:1241:5:1241:5 | b [element] : | | array_flow.rb:1242:10:1242:10 | b [element] : | array_flow.rb:1242:10:1242:13 | ...[...] | | array_flow.rb:1242:10:1242:10 | b [element] : | array_flow.rb:1242:10:1242:13 | ...[...] | | array_flow.rb:1243:10:1243:10 | b [element] : | array_flow.rb:1243:10:1243:13 | ...[...] | | array_flow.rb:1243:10:1243:10 | b [element] : | array_flow.rb:1243:10:1243:13 | ...[...] | | array_flow.rb:1244:10:1244:10 | b [element] : | array_flow.rb:1244:10:1244:13 | ...[...] | | array_flow.rb:1244:10:1244:10 | b [element] : | array_flow.rb:1244:10:1244:13 | ...[...] | -| array_flow.rb:1248:16:1248:28 | call to source : | array_flow.rb:1249:9:1249:9 | a [element 2] : | -| array_flow.rb:1248:16:1248:28 | call to source : | array_flow.rb:1249:9:1249:9 | a [element 2] : | -| array_flow.rb:1248:34:1248:46 | call to source : | array_flow.rb:1249:9:1249:9 | a [element 4] : | -| array_flow.rb:1248:34:1248:46 | call to source : | array_flow.rb:1249:9:1249:9 | a [element 4] : | +| array_flow.rb:1248:5:1248:5 | a [element 2] : | array_flow.rb:1249:9:1249:9 | a [element 2] : | +| array_flow.rb:1248:5:1248:5 | a [element 2] : | array_flow.rb:1249:9:1249:9 | a [element 2] : | +| array_flow.rb:1248:5:1248:5 | a [element 4] : | array_flow.rb:1249:9:1249:9 | a [element 4] : | +| array_flow.rb:1248:5:1248:5 | a [element 4] : | array_flow.rb:1249:9:1249:9 | a [element 4] : | +| array_flow.rb:1248:16:1248:28 | call to source : | array_flow.rb:1248:5:1248:5 | a [element 2] : | +| array_flow.rb:1248:16:1248:28 | call to source : | array_flow.rb:1248:5:1248:5 | a [element 2] : | +| array_flow.rb:1248:34:1248:46 | call to source : | array_flow.rb:1248:5:1248:5 | a [element 4] : | +| array_flow.rb:1248:34:1248:46 | call to source : | array_flow.rb:1248:5:1248:5 | a [element 4] : | +| array_flow.rb:1249:5:1249:5 | b : | array_flow.rb:1250:10:1250:10 | b | +| array_flow.rb:1249:5:1249:5 | b : | array_flow.rb:1250:10:1250:10 | b | | array_flow.rb:1249:9:1249:9 | [post] a [element 3] : | array_flow.rb:1254:10:1254:10 | a [element 3] : | | array_flow.rb:1249:9:1249:9 | [post] a [element 3] : | array_flow.rb:1254:10:1254:10 | a [element 3] : | | array_flow.rb:1249:9:1249:9 | a [element 2] : | array_flow.rb:1249:9:1249:19 | call to slice! : | | array_flow.rb:1249:9:1249:9 | a [element 2] : | array_flow.rb:1249:9:1249:19 | call to slice! : | | array_flow.rb:1249:9:1249:9 | a [element 4] : | array_flow.rb:1249:9:1249:9 | [post] a [element 3] : | | array_flow.rb:1249:9:1249:9 | a [element 4] : | array_flow.rb:1249:9:1249:9 | [post] a [element 3] : | -| array_flow.rb:1249:9:1249:19 | call to slice! : | array_flow.rb:1250:10:1250:10 | b | -| array_flow.rb:1249:9:1249:19 | call to slice! : | array_flow.rb:1250:10:1250:10 | b | +| array_flow.rb:1249:9:1249:19 | call to slice! : | array_flow.rb:1249:5:1249:5 | b : | +| array_flow.rb:1249:9:1249:19 | call to slice! : | array_flow.rb:1249:5:1249:5 | b : | | array_flow.rb:1254:10:1254:10 | a [element 3] : | array_flow.rb:1254:10:1254:13 | ...[...] | | array_flow.rb:1254:10:1254:10 | a [element 3] : | array_flow.rb:1254:10:1254:13 | ...[...] | -| array_flow.rb:1256:16:1256:28 | call to source : | array_flow.rb:1257:9:1257:9 | a [element 2] : | -| array_flow.rb:1256:16:1256:28 | call to source : | array_flow.rb:1257:9:1257:9 | a [element 2] : | -| array_flow.rb:1256:34:1256:46 | call to source : | array_flow.rb:1257:9:1257:9 | a [element 4] : | -| array_flow.rb:1256:34:1256:46 | call to source : | array_flow.rb:1257:9:1257:9 | a [element 4] : | +| array_flow.rb:1256:5:1256:5 | a [element 2] : | array_flow.rb:1257:9:1257:9 | a [element 2] : | +| array_flow.rb:1256:5:1256:5 | a [element 2] : | array_flow.rb:1257:9:1257:9 | a [element 2] : | +| array_flow.rb:1256:5:1256:5 | a [element 4] : | array_flow.rb:1257:9:1257:9 | a [element 4] : | +| array_flow.rb:1256:5:1256:5 | a [element 4] : | array_flow.rb:1257:9:1257:9 | a [element 4] : | +| array_flow.rb:1256:16:1256:28 | call to source : | array_flow.rb:1256:5:1256:5 | a [element 2] : | +| array_flow.rb:1256:16:1256:28 | call to source : | array_flow.rb:1256:5:1256:5 | a [element 2] : | +| array_flow.rb:1256:34:1256:46 | call to source : | array_flow.rb:1256:5:1256:5 | a [element 4] : | +| array_flow.rb:1256:34:1256:46 | call to source : | array_flow.rb:1256:5:1256:5 | a [element 4] : | +| array_flow.rb:1257:5:1257:5 | b : | array_flow.rb:1263:10:1263:10 | b | +| array_flow.rb:1257:5:1257:5 | b : | array_flow.rb:1263:10:1263:10 | b | +| array_flow.rb:1257:5:1257:5 | b : | array_flow.rb:1265:10:1265:10 | b : | +| array_flow.rb:1257:5:1257:5 | b [element] : | array_flow.rb:1265:10:1265:10 | b [element] : | +| array_flow.rb:1257:5:1257:5 | b [element] : | array_flow.rb:1265:10:1265:10 | b [element] : | | array_flow.rb:1257:9:1257:9 | [post] a [element] : | array_flow.rb:1258:10:1258:10 | a [element] : | | array_flow.rb:1257:9:1257:9 | [post] a [element] : | array_flow.rb:1258:10:1258:10 | a [element] : | | array_flow.rb:1257:9:1257:9 | [post] a [element] : | array_flow.rb:1259:10:1259:10 | a [element] : | @@ -2571,11 +3195,10 @@ edges | array_flow.rb:1257:9:1257:9 | a [element 4] : | array_flow.rb:1257:9:1257:19 | call to slice! : | | array_flow.rb:1257:9:1257:9 | a [element 4] : | array_flow.rb:1257:9:1257:19 | call to slice! [element] : | | array_flow.rb:1257:9:1257:9 | a [element 4] : | array_flow.rb:1257:9:1257:19 | call to slice! [element] : | -| array_flow.rb:1257:9:1257:19 | call to slice! : | array_flow.rb:1263:10:1263:10 | b | -| array_flow.rb:1257:9:1257:19 | call to slice! : | array_flow.rb:1263:10:1263:10 | b | -| array_flow.rb:1257:9:1257:19 | call to slice! : | array_flow.rb:1265:10:1265:10 | b : | -| array_flow.rb:1257:9:1257:19 | call to slice! [element] : | array_flow.rb:1265:10:1265:10 | b [element] : | -| array_flow.rb:1257:9:1257:19 | call to slice! [element] : | array_flow.rb:1265:10:1265:10 | b [element] : | +| array_flow.rb:1257:9:1257:19 | call to slice! : | array_flow.rb:1257:5:1257:5 | b : | +| array_flow.rb:1257:9:1257:19 | call to slice! : | array_flow.rb:1257:5:1257:5 | b : | +| array_flow.rb:1257:9:1257:19 | call to slice! [element] : | array_flow.rb:1257:5:1257:5 | b [element] : | +| array_flow.rb:1257:9:1257:19 | call to slice! [element] : | array_flow.rb:1257:5:1257:5 | b [element] : | | array_flow.rb:1258:10:1258:10 | a [element] : | array_flow.rb:1258:10:1258:13 | ...[...] | | array_flow.rb:1258:10:1258:10 | a [element] : | array_flow.rb:1258:10:1258:13 | ...[...] | | array_flow.rb:1259:10:1259:10 | a [element] : | array_flow.rb:1259:10:1259:13 | ...[...] | @@ -2587,58 +3210,88 @@ edges | array_flow.rb:1265:10:1265:10 | b : | array_flow.rb:1265:10:1265:13 | ...[...] | | array_flow.rb:1265:10:1265:10 | b [element] : | array_flow.rb:1265:10:1265:13 | ...[...] | | array_flow.rb:1265:10:1265:10 | b [element] : | array_flow.rb:1265:10:1265:13 | ...[...] | -| array_flow.rb:1267:16:1267:28 | call to source : | array_flow.rb:1268:9:1268:9 | a [element 2] : | -| array_flow.rb:1267:16:1267:28 | call to source : | array_flow.rb:1268:9:1268:9 | a [element 2] : | -| array_flow.rb:1267:34:1267:46 | call to source : | array_flow.rb:1268:9:1268:9 | a [element 4] : | -| array_flow.rb:1267:34:1267:46 | call to source : | array_flow.rb:1268:9:1268:9 | a [element 4] : | +| array_flow.rb:1267:5:1267:5 | a [element 2] : | array_flow.rb:1268:9:1268:9 | a [element 2] : | +| array_flow.rb:1267:5:1267:5 | a [element 2] : | array_flow.rb:1268:9:1268:9 | a [element 2] : | +| array_flow.rb:1267:5:1267:5 | a [element 4] : | array_flow.rb:1268:9:1268:9 | a [element 4] : | +| array_flow.rb:1267:5:1267:5 | a [element 4] : | array_flow.rb:1268:9:1268:9 | a [element 4] : | +| array_flow.rb:1267:16:1267:28 | call to source : | array_flow.rb:1267:5:1267:5 | a [element 2] : | +| array_flow.rb:1267:16:1267:28 | call to source : | array_flow.rb:1267:5:1267:5 | a [element 2] : | +| array_flow.rb:1267:34:1267:46 | call to source : | array_flow.rb:1267:5:1267:5 | a [element 4] : | +| array_flow.rb:1267:34:1267:46 | call to source : | array_flow.rb:1267:5:1267:5 | a [element 4] : | +| array_flow.rb:1268:5:1268:5 | b [element 0] : | array_flow.rb:1269:10:1269:10 | b [element 0] : | +| array_flow.rb:1268:5:1268:5 | b [element 0] : | array_flow.rb:1269:10:1269:10 | b [element 0] : | +| array_flow.rb:1268:5:1268:5 | b [element 2] : | array_flow.rb:1271:10:1271:10 | b [element 2] : | +| array_flow.rb:1268:5:1268:5 | b [element 2] : | array_flow.rb:1271:10:1271:10 | b [element 2] : | | array_flow.rb:1268:9:1268:9 | a [element 2] : | array_flow.rb:1268:9:1268:22 | call to slice! [element 0] : | | array_flow.rb:1268:9:1268:9 | a [element 2] : | array_flow.rb:1268:9:1268:22 | call to slice! [element 0] : | | array_flow.rb:1268:9:1268:9 | a [element 4] : | array_flow.rb:1268:9:1268:22 | call to slice! [element 2] : | | array_flow.rb:1268:9:1268:9 | a [element 4] : | array_flow.rb:1268:9:1268:22 | call to slice! [element 2] : | -| array_flow.rb:1268:9:1268:22 | call to slice! [element 0] : | array_flow.rb:1269:10:1269:10 | b [element 0] : | -| array_flow.rb:1268:9:1268:22 | call to slice! [element 0] : | array_flow.rb:1269:10:1269:10 | b [element 0] : | -| array_flow.rb:1268:9:1268:22 | call to slice! [element 2] : | array_flow.rb:1271:10:1271:10 | b [element 2] : | -| array_flow.rb:1268:9:1268:22 | call to slice! [element 2] : | array_flow.rb:1271:10:1271:10 | b [element 2] : | +| array_flow.rb:1268:9:1268:22 | call to slice! [element 0] : | array_flow.rb:1268:5:1268:5 | b [element 0] : | +| array_flow.rb:1268:9:1268:22 | call to slice! [element 0] : | array_flow.rb:1268:5:1268:5 | b [element 0] : | +| array_flow.rb:1268:9:1268:22 | call to slice! [element 2] : | array_flow.rb:1268:5:1268:5 | b [element 2] : | +| array_flow.rb:1268:9:1268:22 | call to slice! [element 2] : | array_flow.rb:1268:5:1268:5 | b [element 2] : | | array_flow.rb:1269:10:1269:10 | b [element 0] : | array_flow.rb:1269:10:1269:13 | ...[...] | | array_flow.rb:1269:10:1269:10 | b [element 0] : | array_flow.rb:1269:10:1269:13 | ...[...] | | array_flow.rb:1271:10:1271:10 | b [element 2] : | array_flow.rb:1271:10:1271:13 | ...[...] | | array_flow.rb:1271:10:1271:10 | b [element 2] : | array_flow.rb:1271:10:1271:13 | ...[...] | -| array_flow.rb:1278:16:1278:28 | call to source : | array_flow.rb:1279:9:1279:9 | a [element 2] : | -| array_flow.rb:1278:16:1278:28 | call to source : | array_flow.rb:1279:9:1279:9 | a [element 2] : | -| array_flow.rb:1278:34:1278:46 | call to source : | array_flow.rb:1279:9:1279:9 | a [element 4] : | -| array_flow.rb:1278:34:1278:46 | call to source : | array_flow.rb:1279:9:1279:9 | a [element 4] : | +| array_flow.rb:1278:5:1278:5 | a [element 2] : | array_flow.rb:1279:9:1279:9 | a [element 2] : | +| array_flow.rb:1278:5:1278:5 | a [element 2] : | array_flow.rb:1279:9:1279:9 | a [element 2] : | +| array_flow.rb:1278:5:1278:5 | a [element 4] : | array_flow.rb:1279:9:1279:9 | a [element 4] : | +| array_flow.rb:1278:5:1278:5 | a [element 4] : | array_flow.rb:1279:9:1279:9 | a [element 4] : | +| array_flow.rb:1278:16:1278:28 | call to source : | array_flow.rb:1278:5:1278:5 | a [element 2] : | +| array_flow.rb:1278:16:1278:28 | call to source : | array_flow.rb:1278:5:1278:5 | a [element 2] : | +| array_flow.rb:1278:34:1278:46 | call to source : | array_flow.rb:1278:5:1278:5 | a [element 4] : | +| array_flow.rb:1278:34:1278:46 | call to source : | array_flow.rb:1278:5:1278:5 | a [element 4] : | +| array_flow.rb:1279:5:1279:5 | b [element 0] : | array_flow.rb:1280:10:1280:10 | b [element 0] : | +| array_flow.rb:1279:5:1279:5 | b [element 0] : | array_flow.rb:1280:10:1280:10 | b [element 0] : | | array_flow.rb:1279:9:1279:9 | [post] a [element 2] : | array_flow.rb:1285:10:1285:10 | a [element 2] : | | array_flow.rb:1279:9:1279:9 | [post] a [element 2] : | array_flow.rb:1285:10:1285:10 | a [element 2] : | | array_flow.rb:1279:9:1279:9 | a [element 2] : | array_flow.rb:1279:9:1279:22 | call to slice! [element 0] : | | array_flow.rb:1279:9:1279:9 | a [element 2] : | array_flow.rb:1279:9:1279:22 | call to slice! [element 0] : | | array_flow.rb:1279:9:1279:9 | a [element 4] : | array_flow.rb:1279:9:1279:9 | [post] a [element 2] : | | array_flow.rb:1279:9:1279:9 | a [element 4] : | array_flow.rb:1279:9:1279:9 | [post] a [element 2] : | -| array_flow.rb:1279:9:1279:22 | call to slice! [element 0] : | array_flow.rb:1280:10:1280:10 | b [element 0] : | -| array_flow.rb:1279:9:1279:22 | call to slice! [element 0] : | array_flow.rb:1280:10:1280:10 | b [element 0] : | +| array_flow.rb:1279:9:1279:22 | call to slice! [element 0] : | array_flow.rb:1279:5:1279:5 | b [element 0] : | +| array_flow.rb:1279:9:1279:22 | call to slice! [element 0] : | array_flow.rb:1279:5:1279:5 | b [element 0] : | | array_flow.rb:1280:10:1280:10 | b [element 0] : | array_flow.rb:1280:10:1280:13 | ...[...] | | array_flow.rb:1280:10:1280:10 | b [element 0] : | array_flow.rb:1280:10:1280:13 | ...[...] | | array_flow.rb:1285:10:1285:10 | a [element 2] : | array_flow.rb:1285:10:1285:13 | ...[...] | | array_flow.rb:1285:10:1285:10 | a [element 2] : | array_flow.rb:1285:10:1285:13 | ...[...] | -| array_flow.rb:1289:16:1289:28 | call to source : | array_flow.rb:1290:9:1290:9 | a [element 2] : | -| array_flow.rb:1289:16:1289:28 | call to source : | array_flow.rb:1290:9:1290:9 | a [element 2] : | -| array_flow.rb:1289:34:1289:46 | call to source : | array_flow.rb:1290:9:1290:9 | a [element 4] : | -| array_flow.rb:1289:34:1289:46 | call to source : | array_flow.rb:1290:9:1290:9 | a [element 4] : | +| array_flow.rb:1289:5:1289:5 | a [element 2] : | array_flow.rb:1290:9:1290:9 | a [element 2] : | +| array_flow.rb:1289:5:1289:5 | a [element 2] : | array_flow.rb:1290:9:1290:9 | a [element 2] : | +| array_flow.rb:1289:5:1289:5 | a [element 4] : | array_flow.rb:1290:9:1290:9 | a [element 4] : | +| array_flow.rb:1289:5:1289:5 | a [element 4] : | array_flow.rb:1290:9:1290:9 | a [element 4] : | +| array_flow.rb:1289:16:1289:28 | call to source : | array_flow.rb:1289:5:1289:5 | a [element 2] : | +| array_flow.rb:1289:16:1289:28 | call to source : | array_flow.rb:1289:5:1289:5 | a [element 2] : | +| array_flow.rb:1289:34:1289:46 | call to source : | array_flow.rb:1289:5:1289:5 | a [element 4] : | +| array_flow.rb:1289:34:1289:46 | call to source : | array_flow.rb:1289:5:1289:5 | a [element 4] : | +| array_flow.rb:1290:5:1290:5 | b [element 0] : | array_flow.rb:1291:10:1291:10 | b [element 0] : | +| array_flow.rb:1290:5:1290:5 | b [element 0] : | array_flow.rb:1291:10:1291:10 | b [element 0] : | | array_flow.rb:1290:9:1290:9 | [post] a [element 2] : | array_flow.rb:1296:10:1296:10 | a [element 2] : | | array_flow.rb:1290:9:1290:9 | [post] a [element 2] : | array_flow.rb:1296:10:1296:10 | a [element 2] : | | array_flow.rb:1290:9:1290:9 | a [element 2] : | array_flow.rb:1290:9:1290:23 | call to slice! [element 0] : | | array_flow.rb:1290:9:1290:9 | a [element 2] : | array_flow.rb:1290:9:1290:23 | call to slice! [element 0] : | | array_flow.rb:1290:9:1290:9 | a [element 4] : | array_flow.rb:1290:9:1290:9 | [post] a [element 2] : | | array_flow.rb:1290:9:1290:9 | a [element 4] : | array_flow.rb:1290:9:1290:9 | [post] a [element 2] : | -| array_flow.rb:1290:9:1290:23 | call to slice! [element 0] : | array_flow.rb:1291:10:1291:10 | b [element 0] : | -| array_flow.rb:1290:9:1290:23 | call to slice! [element 0] : | array_flow.rb:1291:10:1291:10 | b [element 0] : | +| array_flow.rb:1290:9:1290:23 | call to slice! [element 0] : | array_flow.rb:1290:5:1290:5 | b [element 0] : | +| array_flow.rb:1290:9:1290:23 | call to slice! [element 0] : | array_flow.rb:1290:5:1290:5 | b [element 0] : | | array_flow.rb:1291:10:1291:10 | b [element 0] : | array_flow.rb:1291:10:1291:13 | ...[...] | | array_flow.rb:1291:10:1291:10 | b [element 0] : | array_flow.rb:1291:10:1291:13 | ...[...] | | array_flow.rb:1296:10:1296:10 | a [element 2] : | array_flow.rb:1296:10:1296:13 | ...[...] | | array_flow.rb:1296:10:1296:10 | a [element 2] : | array_flow.rb:1296:10:1296:13 | ...[...] | -| array_flow.rb:1300:16:1300:28 | call to source : | array_flow.rb:1301:9:1301:9 | a [element 2] : | -| array_flow.rb:1300:16:1300:28 | call to source : | array_flow.rb:1301:9:1301:9 | a [element 2] : | -| array_flow.rb:1300:34:1300:46 | call to source : | array_flow.rb:1301:9:1301:9 | a [element 4] : | -| array_flow.rb:1300:34:1300:46 | call to source : | array_flow.rb:1301:9:1301:9 | a [element 4] : | +| array_flow.rb:1300:5:1300:5 | a [element 2] : | array_flow.rb:1301:9:1301:9 | a [element 2] : | +| array_flow.rb:1300:5:1300:5 | a [element 2] : | array_flow.rb:1301:9:1301:9 | a [element 2] : | +| array_flow.rb:1300:5:1300:5 | a [element 4] : | array_flow.rb:1301:9:1301:9 | a [element 4] : | +| array_flow.rb:1300:5:1300:5 | a [element 4] : | array_flow.rb:1301:9:1301:9 | a [element 4] : | +| array_flow.rb:1300:16:1300:28 | call to source : | array_flow.rb:1300:5:1300:5 | a [element 2] : | +| array_flow.rb:1300:16:1300:28 | call to source : | array_flow.rb:1300:5:1300:5 | a [element 2] : | +| array_flow.rb:1300:34:1300:46 | call to source : | array_flow.rb:1300:5:1300:5 | a [element 4] : | +| array_flow.rb:1300:34:1300:46 | call to source : | array_flow.rb:1300:5:1300:5 | a [element 4] : | +| array_flow.rb:1301:5:1301:5 | b [element] : | array_flow.rb:1302:10:1302:10 | b [element] : | +| array_flow.rb:1301:5:1301:5 | b [element] : | array_flow.rb:1302:10:1302:10 | b [element] : | +| array_flow.rb:1301:5:1301:5 | b [element] : | array_flow.rb:1303:10:1303:10 | b [element] : | +| array_flow.rb:1301:5:1301:5 | b [element] : | array_flow.rb:1303:10:1303:10 | b [element] : | +| array_flow.rb:1301:5:1301:5 | b [element] : | array_flow.rb:1304:10:1304:10 | b [element] : | +| array_flow.rb:1301:5:1301:5 | b [element] : | array_flow.rb:1304:10:1304:10 | b [element] : | | array_flow.rb:1301:9:1301:9 | [post] a [element] : | array_flow.rb:1305:10:1305:10 | a [element] : | | array_flow.rb:1301:9:1301:9 | [post] a [element] : | array_flow.rb:1305:10:1305:10 | a [element] : | | array_flow.rb:1301:9:1301:9 | [post] a [element] : | array_flow.rb:1306:10:1306:10 | a [element] : | @@ -2653,12 +3306,8 @@ edges | array_flow.rb:1301:9:1301:9 | a [element 4] : | array_flow.rb:1301:9:1301:9 | [post] a [element] : | | array_flow.rb:1301:9:1301:9 | a [element 4] : | array_flow.rb:1301:9:1301:22 | call to slice! [element] : | | array_flow.rb:1301:9:1301:9 | a [element 4] : | array_flow.rb:1301:9:1301:22 | call to slice! [element] : | -| array_flow.rb:1301:9:1301:22 | call to slice! [element] : | array_flow.rb:1302:10:1302:10 | b [element] : | -| array_flow.rb:1301:9:1301:22 | call to slice! [element] : | array_flow.rb:1302:10:1302:10 | b [element] : | -| array_flow.rb:1301:9:1301:22 | call to slice! [element] : | array_flow.rb:1303:10:1303:10 | b [element] : | -| array_flow.rb:1301:9:1301:22 | call to slice! [element] : | array_flow.rb:1303:10:1303:10 | b [element] : | -| array_flow.rb:1301:9:1301:22 | call to slice! [element] : | array_flow.rb:1304:10:1304:10 | b [element] : | -| array_flow.rb:1301:9:1301:22 | call to slice! [element] : | array_flow.rb:1304:10:1304:10 | b [element] : | +| array_flow.rb:1301:9:1301:22 | call to slice! [element] : | array_flow.rb:1301:5:1301:5 | b [element] : | +| array_flow.rb:1301:9:1301:22 | call to slice! [element] : | array_flow.rb:1301:5:1301:5 | b [element] : | | array_flow.rb:1302:10:1302:10 | b [element] : | array_flow.rb:1302:10:1302:13 | ...[...] | | array_flow.rb:1302:10:1302:10 | b [element] : | array_flow.rb:1302:10:1302:13 | ...[...] | | array_flow.rb:1303:10:1303:10 | b [element] : | array_flow.rb:1303:10:1303:13 | ...[...] | @@ -2671,10 +3320,20 @@ edges | array_flow.rb:1306:10:1306:10 | a [element] : | array_flow.rb:1306:10:1306:13 | ...[...] | | array_flow.rb:1307:10:1307:10 | a [element] : | array_flow.rb:1307:10:1307:13 | ...[...] | | array_flow.rb:1307:10:1307:10 | a [element] : | array_flow.rb:1307:10:1307:13 | ...[...] | -| array_flow.rb:1309:16:1309:28 | call to source : | array_flow.rb:1310:9:1310:9 | a [element 2] : | -| array_flow.rb:1309:16:1309:28 | call to source : | array_flow.rb:1310:9:1310:9 | a [element 2] : | -| array_flow.rb:1309:34:1309:46 | call to source : | array_flow.rb:1310:9:1310:9 | a [element 4] : | -| array_flow.rb:1309:34:1309:46 | call to source : | array_flow.rb:1310:9:1310:9 | a [element 4] : | +| array_flow.rb:1309:5:1309:5 | a [element 2] : | array_flow.rb:1310:9:1310:9 | a [element 2] : | +| array_flow.rb:1309:5:1309:5 | a [element 2] : | array_flow.rb:1310:9:1310:9 | a [element 2] : | +| array_flow.rb:1309:5:1309:5 | a [element 4] : | array_flow.rb:1310:9:1310:9 | a [element 4] : | +| array_flow.rb:1309:5:1309:5 | a [element 4] : | array_flow.rb:1310:9:1310:9 | a [element 4] : | +| array_flow.rb:1309:16:1309:28 | call to source : | array_flow.rb:1309:5:1309:5 | a [element 2] : | +| array_flow.rb:1309:16:1309:28 | call to source : | array_flow.rb:1309:5:1309:5 | a [element 2] : | +| array_flow.rb:1309:34:1309:46 | call to source : | array_flow.rb:1309:5:1309:5 | a [element 4] : | +| array_flow.rb:1309:34:1309:46 | call to source : | array_flow.rb:1309:5:1309:5 | a [element 4] : | +| array_flow.rb:1310:5:1310:5 | b [element] : | array_flow.rb:1311:10:1311:10 | b [element] : | +| array_flow.rb:1310:5:1310:5 | b [element] : | array_flow.rb:1311:10:1311:10 | b [element] : | +| array_flow.rb:1310:5:1310:5 | b [element] : | array_flow.rb:1312:10:1312:10 | b [element] : | +| array_flow.rb:1310:5:1310:5 | b [element] : | array_flow.rb:1312:10:1312:10 | b [element] : | +| array_flow.rb:1310:5:1310:5 | b [element] : | array_flow.rb:1313:10:1313:10 | b [element] : | +| array_flow.rb:1310:5:1310:5 | b [element] : | array_flow.rb:1313:10:1313:10 | b [element] : | | array_flow.rb:1310:9:1310:9 | [post] a [element] : | array_flow.rb:1314:10:1314:10 | a [element] : | | array_flow.rb:1310:9:1310:9 | [post] a [element] : | array_flow.rb:1314:10:1314:10 | a [element] : | | array_flow.rb:1310:9:1310:9 | [post] a [element] : | array_flow.rb:1315:10:1315:10 | a [element] : | @@ -2689,12 +3348,8 @@ edges | array_flow.rb:1310:9:1310:9 | a [element 4] : | array_flow.rb:1310:9:1310:9 | [post] a [element] : | | array_flow.rb:1310:9:1310:9 | a [element 4] : | array_flow.rb:1310:9:1310:22 | call to slice! [element] : | | array_flow.rb:1310:9:1310:9 | a [element 4] : | array_flow.rb:1310:9:1310:22 | call to slice! [element] : | -| array_flow.rb:1310:9:1310:22 | call to slice! [element] : | array_flow.rb:1311:10:1311:10 | b [element] : | -| array_flow.rb:1310:9:1310:22 | call to slice! [element] : | array_flow.rb:1311:10:1311:10 | b [element] : | -| array_flow.rb:1310:9:1310:22 | call to slice! [element] : | array_flow.rb:1312:10:1312:10 | b [element] : | -| array_flow.rb:1310:9:1310:22 | call to slice! [element] : | array_flow.rb:1312:10:1312:10 | b [element] : | -| array_flow.rb:1310:9:1310:22 | call to slice! [element] : | array_flow.rb:1313:10:1313:10 | b [element] : | -| array_flow.rb:1310:9:1310:22 | call to slice! [element] : | array_flow.rb:1313:10:1313:10 | b [element] : | +| array_flow.rb:1310:9:1310:22 | call to slice! [element] : | array_flow.rb:1310:5:1310:5 | b [element] : | +| array_flow.rb:1310:9:1310:22 | call to slice! [element] : | array_flow.rb:1310:5:1310:5 | b [element] : | | array_flow.rb:1311:10:1311:10 | b [element] : | array_flow.rb:1311:10:1311:13 | ...[...] | | array_flow.rb:1311:10:1311:10 | b [element] : | array_flow.rb:1311:10:1311:13 | ...[...] | | array_flow.rb:1312:10:1312:10 | b [element] : | array_flow.rb:1312:10:1312:13 | ...[...] | @@ -2707,10 +3362,20 @@ edges | array_flow.rb:1315:10:1315:10 | a [element] : | array_flow.rb:1315:10:1315:13 | ...[...] | | array_flow.rb:1316:10:1316:10 | a [element] : | array_flow.rb:1316:10:1316:13 | ...[...] | | array_flow.rb:1316:10:1316:10 | a [element] : | array_flow.rb:1316:10:1316:13 | ...[...] | -| array_flow.rb:1318:16:1318:28 | call to source : | array_flow.rb:1319:9:1319:9 | a [element 2] : | -| array_flow.rb:1318:16:1318:28 | call to source : | array_flow.rb:1319:9:1319:9 | a [element 2] : | -| array_flow.rb:1318:34:1318:46 | call to source : | array_flow.rb:1319:9:1319:9 | a [element 4] : | -| array_flow.rb:1318:34:1318:46 | call to source : | array_flow.rb:1319:9:1319:9 | a [element 4] : | +| array_flow.rb:1318:5:1318:5 | a [element 2] : | array_flow.rb:1319:9:1319:9 | a [element 2] : | +| array_flow.rb:1318:5:1318:5 | a [element 2] : | array_flow.rb:1319:9:1319:9 | a [element 2] : | +| array_flow.rb:1318:5:1318:5 | a [element 4] : | array_flow.rb:1319:9:1319:9 | a [element 4] : | +| array_flow.rb:1318:5:1318:5 | a [element 4] : | array_flow.rb:1319:9:1319:9 | a [element 4] : | +| array_flow.rb:1318:16:1318:28 | call to source : | array_flow.rb:1318:5:1318:5 | a [element 2] : | +| array_flow.rb:1318:16:1318:28 | call to source : | array_flow.rb:1318:5:1318:5 | a [element 2] : | +| array_flow.rb:1318:34:1318:46 | call to source : | array_flow.rb:1318:5:1318:5 | a [element 4] : | +| array_flow.rb:1318:34:1318:46 | call to source : | array_flow.rb:1318:5:1318:5 | a [element 4] : | +| array_flow.rb:1319:5:1319:5 | b [element] : | array_flow.rb:1320:10:1320:10 | b [element] : | +| array_flow.rb:1319:5:1319:5 | b [element] : | array_flow.rb:1320:10:1320:10 | b [element] : | +| array_flow.rb:1319:5:1319:5 | b [element] : | array_flow.rb:1321:10:1321:10 | b [element] : | +| array_flow.rb:1319:5:1319:5 | b [element] : | array_flow.rb:1321:10:1321:10 | b [element] : | +| array_flow.rb:1319:5:1319:5 | b [element] : | array_flow.rb:1322:10:1322:10 | b [element] : | +| array_flow.rb:1319:5:1319:5 | b [element] : | array_flow.rb:1322:10:1322:10 | b [element] : | | array_flow.rb:1319:9:1319:9 | [post] a [element] : | array_flow.rb:1323:10:1323:10 | a [element] : | | array_flow.rb:1319:9:1319:9 | [post] a [element] : | array_flow.rb:1323:10:1323:10 | a [element] : | | array_flow.rb:1319:9:1319:9 | [post] a [element] : | array_flow.rb:1324:10:1324:10 | a [element] : | @@ -2725,12 +3390,8 @@ edges | array_flow.rb:1319:9:1319:9 | a [element 4] : | array_flow.rb:1319:9:1319:9 | [post] a [element] : | | array_flow.rb:1319:9:1319:9 | a [element 4] : | array_flow.rb:1319:9:1319:25 | call to slice! [element] : | | array_flow.rb:1319:9:1319:9 | a [element 4] : | array_flow.rb:1319:9:1319:25 | call to slice! [element] : | -| array_flow.rb:1319:9:1319:25 | call to slice! [element] : | array_flow.rb:1320:10:1320:10 | b [element] : | -| array_flow.rb:1319:9:1319:25 | call to slice! [element] : | array_flow.rb:1320:10:1320:10 | b [element] : | -| array_flow.rb:1319:9:1319:25 | call to slice! [element] : | array_flow.rb:1321:10:1321:10 | b [element] : | -| array_flow.rb:1319:9:1319:25 | call to slice! [element] : | array_flow.rb:1321:10:1321:10 | b [element] : | -| array_flow.rb:1319:9:1319:25 | call to slice! [element] : | array_flow.rb:1322:10:1322:10 | b [element] : | -| array_flow.rb:1319:9:1319:25 | call to slice! [element] : | array_flow.rb:1322:10:1322:10 | b [element] : | +| array_flow.rb:1319:9:1319:25 | call to slice! [element] : | array_flow.rb:1319:5:1319:5 | b [element] : | +| array_flow.rb:1319:9:1319:25 | call to slice! [element] : | array_flow.rb:1319:5:1319:5 | b [element] : | | array_flow.rb:1320:10:1320:10 | b [element] : | array_flow.rb:1320:10:1320:13 | ...[...] | | array_flow.rb:1320:10:1320:10 | b [element] : | array_flow.rb:1320:10:1320:13 | ...[...] | | array_flow.rb:1321:10:1321:10 | b [element] : | array_flow.rb:1321:10:1321:13 | ...[...] | @@ -2743,26 +3404,42 @@ edges | array_flow.rb:1324:10:1324:10 | a [element] : | array_flow.rb:1324:10:1324:13 | ...[...] | | array_flow.rb:1325:10:1325:10 | a [element] : | array_flow.rb:1325:10:1325:13 | ...[...] | | array_flow.rb:1325:10:1325:10 | a [element] : | array_flow.rb:1325:10:1325:13 | ...[...] | -| array_flow.rb:1327:16:1327:28 | call to source : | array_flow.rb:1328:9:1328:9 | a [element 2] : | -| array_flow.rb:1327:16:1327:28 | call to source : | array_flow.rb:1328:9:1328:9 | a [element 2] : | -| array_flow.rb:1327:34:1327:46 | call to source : | array_flow.rb:1328:9:1328:9 | a [element 4] : | -| array_flow.rb:1327:34:1327:46 | call to source : | array_flow.rb:1328:9:1328:9 | a [element 4] : | +| array_flow.rb:1327:5:1327:5 | a [element 2] : | array_flow.rb:1328:9:1328:9 | a [element 2] : | +| array_flow.rb:1327:5:1327:5 | a [element 2] : | array_flow.rb:1328:9:1328:9 | a [element 2] : | +| array_flow.rb:1327:5:1327:5 | a [element 4] : | array_flow.rb:1328:9:1328:9 | a [element 4] : | +| array_flow.rb:1327:5:1327:5 | a [element 4] : | array_flow.rb:1328:9:1328:9 | a [element 4] : | +| array_flow.rb:1327:16:1327:28 | call to source : | array_flow.rb:1327:5:1327:5 | a [element 2] : | +| array_flow.rb:1327:16:1327:28 | call to source : | array_flow.rb:1327:5:1327:5 | a [element 2] : | +| array_flow.rb:1327:34:1327:46 | call to source : | array_flow.rb:1327:5:1327:5 | a [element 4] : | +| array_flow.rb:1327:34:1327:46 | call to source : | array_flow.rb:1327:5:1327:5 | a [element 4] : | +| array_flow.rb:1328:5:1328:5 | b [element 2] : | array_flow.rb:1331:10:1331:10 | b [element 2] : | +| array_flow.rb:1328:5:1328:5 | b [element 2] : | array_flow.rb:1331:10:1331:10 | b [element 2] : | | array_flow.rb:1328:9:1328:9 | [post] a [element 1] : | array_flow.rb:1333:10:1333:10 | a [element 1] : | | array_flow.rb:1328:9:1328:9 | [post] a [element 1] : | array_flow.rb:1333:10:1333:10 | a [element 1] : | | array_flow.rb:1328:9:1328:9 | a [element 2] : | array_flow.rb:1328:9:1328:21 | call to slice! [element 2] : | | array_flow.rb:1328:9:1328:9 | a [element 2] : | array_flow.rb:1328:9:1328:21 | call to slice! [element 2] : | | array_flow.rb:1328:9:1328:9 | a [element 4] : | array_flow.rb:1328:9:1328:9 | [post] a [element 1] : | | array_flow.rb:1328:9:1328:9 | a [element 4] : | array_flow.rb:1328:9:1328:9 | [post] a [element 1] : | -| array_flow.rb:1328:9:1328:21 | call to slice! [element 2] : | array_flow.rb:1331:10:1331:10 | b [element 2] : | -| array_flow.rb:1328:9:1328:21 | call to slice! [element 2] : | array_flow.rb:1331:10:1331:10 | b [element 2] : | +| array_flow.rb:1328:9:1328:21 | call to slice! [element 2] : | array_flow.rb:1328:5:1328:5 | b [element 2] : | +| array_flow.rb:1328:9:1328:21 | call to slice! [element 2] : | array_flow.rb:1328:5:1328:5 | b [element 2] : | | array_flow.rb:1331:10:1331:10 | b [element 2] : | array_flow.rb:1331:10:1331:13 | ...[...] | | array_flow.rb:1331:10:1331:10 | b [element 2] : | array_flow.rb:1331:10:1331:13 | ...[...] | | array_flow.rb:1333:10:1333:10 | a [element 1] : | array_flow.rb:1333:10:1333:13 | ...[...] | | array_flow.rb:1333:10:1333:10 | a [element 1] : | array_flow.rb:1333:10:1333:13 | ...[...] | -| array_flow.rb:1336:16:1336:28 | call to source : | array_flow.rb:1337:9:1337:9 | a [element 2] : | -| array_flow.rb:1336:16:1336:28 | call to source : | array_flow.rb:1337:9:1337:9 | a [element 2] : | -| array_flow.rb:1336:34:1336:46 | call to source : | array_flow.rb:1337:9:1337:9 | a [element 4] : | -| array_flow.rb:1336:34:1336:46 | call to source : | array_flow.rb:1337:9:1337:9 | a [element 4] : | +| array_flow.rb:1336:5:1336:5 | a [element 2] : | array_flow.rb:1337:9:1337:9 | a [element 2] : | +| array_flow.rb:1336:5:1336:5 | a [element 2] : | array_flow.rb:1337:9:1337:9 | a [element 2] : | +| array_flow.rb:1336:5:1336:5 | a [element 4] : | array_flow.rb:1337:9:1337:9 | a [element 4] : | +| array_flow.rb:1336:5:1336:5 | a [element 4] : | array_flow.rb:1337:9:1337:9 | a [element 4] : | +| array_flow.rb:1336:16:1336:28 | call to source : | array_flow.rb:1336:5:1336:5 | a [element 2] : | +| array_flow.rb:1336:16:1336:28 | call to source : | array_flow.rb:1336:5:1336:5 | a [element 2] : | +| array_flow.rb:1336:34:1336:46 | call to source : | array_flow.rb:1336:5:1336:5 | a [element 4] : | +| array_flow.rb:1336:34:1336:46 | call to source : | array_flow.rb:1336:5:1336:5 | a [element 4] : | +| array_flow.rb:1337:5:1337:5 | b [element] : | array_flow.rb:1338:10:1338:10 | b [element] : | +| array_flow.rb:1337:5:1337:5 | b [element] : | array_flow.rb:1338:10:1338:10 | b [element] : | +| array_flow.rb:1337:5:1337:5 | b [element] : | array_flow.rb:1339:10:1339:10 | b [element] : | +| array_flow.rb:1337:5:1337:5 | b [element] : | array_flow.rb:1339:10:1339:10 | b [element] : | +| array_flow.rb:1337:5:1337:5 | b [element] : | array_flow.rb:1340:10:1340:10 | b [element] : | +| array_flow.rb:1337:5:1337:5 | b [element] : | array_flow.rb:1340:10:1340:10 | b [element] : | | array_flow.rb:1337:9:1337:9 | [post] a [element] : | array_flow.rb:1341:10:1341:10 | a [element] : | | array_flow.rb:1337:9:1337:9 | [post] a [element] : | array_flow.rb:1341:10:1341:10 | a [element] : | | array_flow.rb:1337:9:1337:9 | [post] a [element] : | array_flow.rb:1342:10:1342:10 | a [element] : | @@ -2777,12 +3454,8 @@ edges | array_flow.rb:1337:9:1337:9 | a [element 4] : | array_flow.rb:1337:9:1337:9 | [post] a [element] : | | array_flow.rb:1337:9:1337:9 | a [element 4] : | array_flow.rb:1337:9:1337:21 | call to slice! [element] : | | array_flow.rb:1337:9:1337:9 | a [element 4] : | array_flow.rb:1337:9:1337:21 | call to slice! [element] : | -| array_flow.rb:1337:9:1337:21 | call to slice! [element] : | array_flow.rb:1338:10:1338:10 | b [element] : | -| array_flow.rb:1337:9:1337:21 | call to slice! [element] : | array_flow.rb:1338:10:1338:10 | b [element] : | -| array_flow.rb:1337:9:1337:21 | call to slice! [element] : | array_flow.rb:1339:10:1339:10 | b [element] : | -| array_flow.rb:1337:9:1337:21 | call to slice! [element] : | array_flow.rb:1339:10:1339:10 | b [element] : | -| array_flow.rb:1337:9:1337:21 | call to slice! [element] : | array_flow.rb:1340:10:1340:10 | b [element] : | -| array_flow.rb:1337:9:1337:21 | call to slice! [element] : | array_flow.rb:1340:10:1340:10 | b [element] : | +| array_flow.rb:1337:9:1337:21 | call to slice! [element] : | array_flow.rb:1337:5:1337:5 | b [element] : | +| array_flow.rb:1337:9:1337:21 | call to slice! [element] : | array_flow.rb:1337:5:1337:5 | b [element] : | | array_flow.rb:1338:10:1338:10 | b [element] : | array_flow.rb:1338:10:1338:13 | ...[...] | | array_flow.rb:1338:10:1338:10 | b [element] : | array_flow.rb:1338:10:1338:13 | ...[...] | | array_flow.rb:1339:10:1339:10 | b [element] : | array_flow.rb:1339:10:1339:13 | ...[...] | @@ -2795,20 +3468,26 @@ edges | array_flow.rb:1342:10:1342:10 | a [element] : | array_flow.rb:1342:10:1342:13 | ...[...] | | array_flow.rb:1343:10:1343:10 | a [element] : | array_flow.rb:1343:10:1343:13 | ...[...] | | array_flow.rb:1343:10:1343:10 | a [element] : | array_flow.rb:1343:10:1343:13 | ...[...] | -| array_flow.rb:1347:16:1347:26 | call to source : | array_flow.rb:1348:9:1348:9 | a [element 2] : | -| array_flow.rb:1347:16:1347:26 | call to source : | array_flow.rb:1348:9:1348:9 | a [element 2] : | +| array_flow.rb:1347:5:1347:5 | a [element 2] : | array_flow.rb:1348:9:1348:9 | a [element 2] : | +| array_flow.rb:1347:5:1347:5 | a [element 2] : | array_flow.rb:1348:9:1348:9 | a [element 2] : | +| array_flow.rb:1347:16:1347:26 | call to source : | array_flow.rb:1347:5:1347:5 | a [element 2] : | +| array_flow.rb:1347:16:1347:26 | call to source : | array_flow.rb:1347:5:1347:5 | a [element 2] : | | array_flow.rb:1348:9:1348:9 | a [element 2] : | array_flow.rb:1348:27:1348:27 | x : | | array_flow.rb:1348:9:1348:9 | a [element 2] : | array_flow.rb:1348:27:1348:27 | x : | | array_flow.rb:1348:27:1348:27 | x : | array_flow.rb:1349:14:1349:14 | x | | array_flow.rb:1348:27:1348:27 | x : | array_flow.rb:1349:14:1349:14 | x | -| array_flow.rb:1355:16:1355:26 | call to source : | array_flow.rb:1356:9:1356:9 | a [element 2] : | -| array_flow.rb:1355:16:1355:26 | call to source : | array_flow.rb:1356:9:1356:9 | a [element 2] : | +| array_flow.rb:1355:5:1355:5 | a [element 2] : | array_flow.rb:1356:9:1356:9 | a [element 2] : | +| array_flow.rb:1355:5:1355:5 | a [element 2] : | array_flow.rb:1356:9:1356:9 | a [element 2] : | +| array_flow.rb:1355:16:1355:26 | call to source : | array_flow.rb:1355:5:1355:5 | a [element 2] : | +| array_flow.rb:1355:16:1355:26 | call to source : | array_flow.rb:1355:5:1355:5 | a [element 2] : | | array_flow.rb:1356:9:1356:9 | a [element 2] : | array_flow.rb:1356:28:1356:28 | x : | | array_flow.rb:1356:9:1356:9 | a [element 2] : | array_flow.rb:1356:28:1356:28 | x : | | array_flow.rb:1356:28:1356:28 | x : | array_flow.rb:1357:14:1357:14 | x | | array_flow.rb:1356:28:1356:28 | x : | array_flow.rb:1357:14:1357:14 | x | -| array_flow.rb:1363:16:1363:26 | call to source : | array_flow.rb:1364:9:1364:9 | a [element 2] : | -| array_flow.rb:1363:16:1363:26 | call to source : | array_flow.rb:1364:9:1364:9 | a [element 2] : | +| array_flow.rb:1363:5:1363:5 | a [element 2] : | array_flow.rb:1364:9:1364:9 | a [element 2] : | +| array_flow.rb:1363:5:1363:5 | a [element 2] : | array_flow.rb:1364:9:1364:9 | a [element 2] : | +| array_flow.rb:1363:16:1363:26 | call to source : | array_flow.rb:1363:5:1363:5 | a [element 2] : | +| array_flow.rb:1363:16:1363:26 | call to source : | array_flow.rb:1363:5:1363:5 | a [element 2] : | | array_flow.rb:1364:9:1364:9 | a [element 2] : | array_flow.rb:1364:26:1364:26 | x : | | array_flow.rb:1364:9:1364:9 | a [element 2] : | array_flow.rb:1364:26:1364:26 | x : | | array_flow.rb:1364:9:1364:9 | a [element 2] : | array_flow.rb:1364:29:1364:29 | y : | @@ -2817,30 +3496,36 @@ edges | array_flow.rb:1364:26:1364:26 | x : | array_flow.rb:1365:14:1365:14 | x | | array_flow.rb:1364:29:1364:29 | y : | array_flow.rb:1366:14:1366:14 | y | | array_flow.rb:1364:29:1364:29 | y : | array_flow.rb:1366:14:1366:14 | y | -| array_flow.rb:1371:16:1371:26 | call to source : | array_flow.rb:1372:9:1372:9 | a [element 2] : | -| array_flow.rb:1371:16:1371:26 | call to source : | array_flow.rb:1372:9:1372:9 | a [element 2] : | -| array_flow.rb:1371:16:1371:26 | call to source : | array_flow.rb:1375:9:1375:9 | a [element 2] : | -| array_flow.rb:1371:16:1371:26 | call to source : | array_flow.rb:1375:9:1375:9 | a [element 2] : | +| array_flow.rb:1371:5:1371:5 | a [element 2] : | array_flow.rb:1372:9:1372:9 | a [element 2] : | +| array_flow.rb:1371:5:1371:5 | a [element 2] : | array_flow.rb:1372:9:1372:9 | a [element 2] : | +| array_flow.rb:1371:5:1371:5 | a [element 2] : | array_flow.rb:1375:9:1375:9 | a [element 2] : | +| array_flow.rb:1371:5:1371:5 | a [element 2] : | array_flow.rb:1375:9:1375:9 | a [element 2] : | +| array_flow.rb:1371:16:1371:26 | call to source : | array_flow.rb:1371:5:1371:5 | a [element 2] : | +| array_flow.rb:1371:16:1371:26 | call to source : | array_flow.rb:1371:5:1371:5 | a [element 2] : | +| array_flow.rb:1372:5:1372:5 | b [element] : | array_flow.rb:1373:10:1373:10 | b [element] : | +| array_flow.rb:1372:5:1372:5 | b [element] : | array_flow.rb:1373:10:1373:10 | b [element] : | +| array_flow.rb:1372:5:1372:5 | b [element] : | array_flow.rb:1374:10:1374:10 | b [element] : | +| array_flow.rb:1372:5:1372:5 | b [element] : | array_flow.rb:1374:10:1374:10 | b [element] : | | array_flow.rb:1372:9:1372:9 | a [element 2] : | array_flow.rb:1372:9:1372:14 | call to sort [element] : | | array_flow.rb:1372:9:1372:9 | a [element 2] : | array_flow.rb:1372:9:1372:14 | call to sort [element] : | -| array_flow.rb:1372:9:1372:14 | call to sort [element] : | array_flow.rb:1373:10:1373:10 | b [element] : | -| array_flow.rb:1372:9:1372:14 | call to sort [element] : | array_flow.rb:1373:10:1373:10 | b [element] : | -| array_flow.rb:1372:9:1372:14 | call to sort [element] : | array_flow.rb:1374:10:1374:10 | b [element] : | -| array_flow.rb:1372:9:1372:14 | call to sort [element] : | array_flow.rb:1374:10:1374:10 | b [element] : | +| array_flow.rb:1372:9:1372:14 | call to sort [element] : | array_flow.rb:1372:5:1372:5 | b [element] : | +| array_flow.rb:1372:9:1372:14 | call to sort [element] : | array_flow.rb:1372:5:1372:5 | b [element] : | | array_flow.rb:1373:10:1373:10 | b [element] : | array_flow.rb:1373:10:1373:13 | ...[...] | | array_flow.rb:1373:10:1373:10 | b [element] : | array_flow.rb:1373:10:1373:13 | ...[...] | | array_flow.rb:1374:10:1374:10 | b [element] : | array_flow.rb:1374:10:1374:13 | ...[...] | | array_flow.rb:1374:10:1374:10 | b [element] : | array_flow.rb:1374:10:1374:13 | ...[...] | +| array_flow.rb:1375:5:1375:5 | c [element] : | array_flow.rb:1380:10:1380:10 | c [element] : | +| array_flow.rb:1375:5:1375:5 | c [element] : | array_flow.rb:1380:10:1380:10 | c [element] : | +| array_flow.rb:1375:5:1375:5 | c [element] : | array_flow.rb:1381:10:1381:10 | c [element] : | +| array_flow.rb:1375:5:1375:5 | c [element] : | array_flow.rb:1381:10:1381:10 | c [element] : | | array_flow.rb:1375:9:1375:9 | a [element 2] : | array_flow.rb:1375:9:1379:7 | call to sort [element] : | | array_flow.rb:1375:9:1375:9 | a [element 2] : | array_flow.rb:1375:9:1379:7 | call to sort [element] : | | array_flow.rb:1375:9:1375:9 | a [element 2] : | array_flow.rb:1375:20:1375:20 | x : | | array_flow.rb:1375:9:1375:9 | a [element 2] : | array_flow.rb:1375:20:1375:20 | x : | | array_flow.rb:1375:9:1375:9 | a [element 2] : | array_flow.rb:1375:23:1375:23 | y : | | array_flow.rb:1375:9:1375:9 | a [element 2] : | array_flow.rb:1375:23:1375:23 | y : | -| array_flow.rb:1375:9:1379:7 | call to sort [element] : | array_flow.rb:1380:10:1380:10 | c [element] : | -| array_flow.rb:1375:9:1379:7 | call to sort [element] : | array_flow.rb:1380:10:1380:10 | c [element] : | -| array_flow.rb:1375:9:1379:7 | call to sort [element] : | array_flow.rb:1381:10:1381:10 | c [element] : | -| array_flow.rb:1375:9:1379:7 | call to sort [element] : | array_flow.rb:1381:10:1381:10 | c [element] : | +| array_flow.rb:1375:9:1379:7 | call to sort [element] : | array_flow.rb:1375:5:1375:5 | c [element] : | +| array_flow.rb:1375:9:1379:7 | call to sort [element] : | array_flow.rb:1375:5:1375:5 | c [element] : | | array_flow.rb:1375:20:1375:20 | x : | array_flow.rb:1376:14:1376:14 | x | | array_flow.rb:1375:20:1375:20 | x : | array_flow.rb:1376:14:1376:14 | x | | array_flow.rb:1375:23:1375:23 | y : | array_flow.rb:1377:14:1377:14 | y | @@ -2849,8 +3534,14 @@ edges | array_flow.rb:1380:10:1380:10 | c [element] : | array_flow.rb:1380:10:1380:13 | ...[...] | | array_flow.rb:1381:10:1381:10 | c [element] : | array_flow.rb:1381:10:1381:13 | ...[...] | | array_flow.rb:1381:10:1381:10 | c [element] : | array_flow.rb:1381:10:1381:13 | ...[...] | -| array_flow.rb:1385:16:1385:26 | call to source : | array_flow.rb:1386:9:1386:9 | a [element 2] : | -| array_flow.rb:1385:16:1385:26 | call to source : | array_flow.rb:1386:9:1386:9 | a [element 2] : | +| array_flow.rb:1385:5:1385:5 | a [element 2] : | array_flow.rb:1386:9:1386:9 | a [element 2] : | +| array_flow.rb:1385:5:1385:5 | a [element 2] : | array_flow.rb:1386:9:1386:9 | a [element 2] : | +| array_flow.rb:1385:16:1385:26 | call to source : | array_flow.rb:1385:5:1385:5 | a [element 2] : | +| array_flow.rb:1385:16:1385:26 | call to source : | array_flow.rb:1385:5:1385:5 | a [element 2] : | +| array_flow.rb:1386:5:1386:5 | b [element] : | array_flow.rb:1387:10:1387:10 | b [element] : | +| array_flow.rb:1386:5:1386:5 | b [element] : | array_flow.rb:1387:10:1387:10 | b [element] : | +| array_flow.rb:1386:5:1386:5 | b [element] : | array_flow.rb:1388:10:1388:10 | b [element] : | +| array_flow.rb:1386:5:1386:5 | b [element] : | array_flow.rb:1388:10:1388:10 | b [element] : | | array_flow.rb:1386:9:1386:9 | [post] a [element] : | array_flow.rb:1389:10:1389:10 | a [element] : | | array_flow.rb:1386:9:1386:9 | [post] a [element] : | array_flow.rb:1389:10:1389:10 | a [element] : | | array_flow.rb:1386:9:1386:9 | [post] a [element] : | array_flow.rb:1390:10:1390:10 | a [element] : | @@ -2859,10 +3550,8 @@ edges | array_flow.rb:1386:9:1386:9 | a [element 2] : | array_flow.rb:1386:9:1386:9 | [post] a [element] : | | array_flow.rb:1386:9:1386:9 | a [element 2] : | array_flow.rb:1386:9:1386:15 | call to sort! [element] : | | array_flow.rb:1386:9:1386:9 | a [element 2] : | array_flow.rb:1386:9:1386:15 | call to sort! [element] : | -| array_flow.rb:1386:9:1386:15 | call to sort! [element] : | array_flow.rb:1387:10:1387:10 | b [element] : | -| array_flow.rb:1386:9:1386:15 | call to sort! [element] : | array_flow.rb:1387:10:1387:10 | b [element] : | -| array_flow.rb:1386:9:1386:15 | call to sort! [element] : | array_flow.rb:1388:10:1388:10 | b [element] : | -| array_flow.rb:1386:9:1386:15 | call to sort! [element] : | array_flow.rb:1388:10:1388:10 | b [element] : | +| array_flow.rb:1386:9:1386:15 | call to sort! [element] : | array_flow.rb:1386:5:1386:5 | b [element] : | +| array_flow.rb:1386:9:1386:15 | call to sort! [element] : | array_flow.rb:1386:5:1386:5 | b [element] : | | array_flow.rb:1387:10:1387:10 | b [element] : | array_flow.rb:1387:10:1387:13 | ...[...] | | array_flow.rb:1387:10:1387:10 | b [element] : | array_flow.rb:1387:10:1387:13 | ...[...] | | array_flow.rb:1388:10:1388:10 | b [element] : | array_flow.rb:1388:10:1388:13 | ...[...] | @@ -2871,8 +3560,14 @@ edges | array_flow.rb:1389:10:1389:10 | a [element] : | array_flow.rb:1389:10:1389:13 | ...[...] | | array_flow.rb:1390:10:1390:10 | a [element] : | array_flow.rb:1390:10:1390:13 | ...[...] | | array_flow.rb:1390:10:1390:10 | a [element] : | array_flow.rb:1390:10:1390:13 | ...[...] | -| array_flow.rb:1392:16:1392:26 | call to source : | array_flow.rb:1393:9:1393:9 | a [element 2] : | -| array_flow.rb:1392:16:1392:26 | call to source : | array_flow.rb:1393:9:1393:9 | a [element 2] : | +| array_flow.rb:1392:5:1392:5 | a [element 2] : | array_flow.rb:1393:9:1393:9 | a [element 2] : | +| array_flow.rb:1392:5:1392:5 | a [element 2] : | array_flow.rb:1393:9:1393:9 | a [element 2] : | +| array_flow.rb:1392:16:1392:26 | call to source : | array_flow.rb:1392:5:1392:5 | a [element 2] : | +| array_flow.rb:1392:16:1392:26 | call to source : | array_flow.rb:1392:5:1392:5 | a [element 2] : | +| array_flow.rb:1393:5:1393:5 | b [element] : | array_flow.rb:1398:10:1398:10 | b [element] : | +| array_flow.rb:1393:5:1393:5 | b [element] : | array_flow.rb:1398:10:1398:10 | b [element] : | +| array_flow.rb:1393:5:1393:5 | b [element] : | array_flow.rb:1399:10:1399:10 | b [element] : | +| array_flow.rb:1393:5:1393:5 | b [element] : | array_flow.rb:1399:10:1399:10 | b [element] : | | array_flow.rb:1393:9:1393:9 | [post] a [element] : | array_flow.rb:1400:10:1400:10 | a [element] : | | array_flow.rb:1393:9:1393:9 | [post] a [element] : | array_flow.rb:1400:10:1400:10 | a [element] : | | array_flow.rb:1393:9:1393:9 | [post] a [element] : | array_flow.rb:1401:10:1401:10 | a [element] : | @@ -2885,10 +3580,8 @@ edges | array_flow.rb:1393:9:1393:9 | a [element 2] : | array_flow.rb:1393:21:1393:21 | x : | | array_flow.rb:1393:9:1393:9 | a [element 2] : | array_flow.rb:1393:24:1393:24 | y : | | array_flow.rb:1393:9:1393:9 | a [element 2] : | array_flow.rb:1393:24:1393:24 | y : | -| array_flow.rb:1393:9:1397:7 | call to sort! [element] : | array_flow.rb:1398:10:1398:10 | b [element] : | -| array_flow.rb:1393:9:1397:7 | call to sort! [element] : | array_flow.rb:1398:10:1398:10 | b [element] : | -| array_flow.rb:1393:9:1397:7 | call to sort! [element] : | array_flow.rb:1399:10:1399:10 | b [element] : | -| array_flow.rb:1393:9:1397:7 | call to sort! [element] : | array_flow.rb:1399:10:1399:10 | b [element] : | +| array_flow.rb:1393:9:1397:7 | call to sort! [element] : | array_flow.rb:1393:5:1393:5 | b [element] : | +| array_flow.rb:1393:9:1397:7 | call to sort! [element] : | array_flow.rb:1393:5:1393:5 | b [element] : | | array_flow.rb:1393:21:1393:21 | x : | array_flow.rb:1394:14:1394:14 | x | | array_flow.rb:1393:21:1393:21 | x : | array_flow.rb:1394:14:1394:14 | x | | array_flow.rb:1393:24:1393:24 | y : | array_flow.rb:1395:14:1395:14 | y | @@ -2901,24 +3594,34 @@ edges | array_flow.rb:1400:10:1400:10 | a [element] : | array_flow.rb:1400:10:1400:13 | ...[...] | | array_flow.rb:1401:10:1401:10 | a [element] : | array_flow.rb:1401:10:1401:13 | ...[...] | | array_flow.rb:1401:10:1401:10 | a [element] : | array_flow.rb:1401:10:1401:13 | ...[...] | -| array_flow.rb:1405:16:1405:26 | call to source : | array_flow.rb:1406:9:1406:9 | a [element 2] : | -| array_flow.rb:1405:16:1405:26 | call to source : | array_flow.rb:1406:9:1406:9 | a [element 2] : | +| array_flow.rb:1405:5:1405:5 | a [element 2] : | array_flow.rb:1406:9:1406:9 | a [element 2] : | +| array_flow.rb:1405:5:1405:5 | a [element 2] : | array_flow.rb:1406:9:1406:9 | a [element 2] : | +| array_flow.rb:1405:16:1405:26 | call to source : | array_flow.rb:1405:5:1405:5 | a [element 2] : | +| array_flow.rb:1405:16:1405:26 | call to source : | array_flow.rb:1405:5:1405:5 | a [element 2] : | +| array_flow.rb:1406:5:1406:5 | b [element] : | array_flow.rb:1410:10:1410:10 | b [element] : | +| array_flow.rb:1406:5:1406:5 | b [element] : | array_flow.rb:1410:10:1410:10 | b [element] : | +| array_flow.rb:1406:5:1406:5 | b [element] : | array_flow.rb:1411:10:1411:10 | b [element] : | +| array_flow.rb:1406:5:1406:5 | b [element] : | array_flow.rb:1411:10:1411:10 | b [element] : | | array_flow.rb:1406:9:1406:9 | a [element 2] : | array_flow.rb:1406:9:1409:7 | call to sort_by [element] : | | array_flow.rb:1406:9:1406:9 | a [element 2] : | array_flow.rb:1406:9:1409:7 | call to sort_by [element] : | | array_flow.rb:1406:9:1406:9 | a [element 2] : | array_flow.rb:1406:23:1406:23 | x : | | array_flow.rb:1406:9:1406:9 | a [element 2] : | array_flow.rb:1406:23:1406:23 | x : | -| array_flow.rb:1406:9:1409:7 | call to sort_by [element] : | array_flow.rb:1410:10:1410:10 | b [element] : | -| array_flow.rb:1406:9:1409:7 | call to sort_by [element] : | array_flow.rb:1410:10:1410:10 | b [element] : | -| array_flow.rb:1406:9:1409:7 | call to sort_by [element] : | array_flow.rb:1411:10:1411:10 | b [element] : | -| array_flow.rb:1406:9:1409:7 | call to sort_by [element] : | array_flow.rb:1411:10:1411:10 | b [element] : | +| array_flow.rb:1406:9:1409:7 | call to sort_by [element] : | array_flow.rb:1406:5:1406:5 | b [element] : | +| array_flow.rb:1406:9:1409:7 | call to sort_by [element] : | array_flow.rb:1406:5:1406:5 | b [element] : | | array_flow.rb:1406:23:1406:23 | x : | array_flow.rb:1407:14:1407:14 | x | | array_flow.rb:1406:23:1406:23 | x : | array_flow.rb:1407:14:1407:14 | x | | array_flow.rb:1410:10:1410:10 | b [element] : | array_flow.rb:1410:10:1410:13 | ...[...] | | array_flow.rb:1410:10:1410:10 | b [element] : | array_flow.rb:1410:10:1410:13 | ...[...] | | array_flow.rb:1411:10:1411:10 | b [element] : | array_flow.rb:1411:10:1411:13 | ...[...] | | array_flow.rb:1411:10:1411:10 | b [element] : | array_flow.rb:1411:10:1411:13 | ...[...] | -| array_flow.rb:1415:16:1415:26 | call to source : | array_flow.rb:1416:9:1416:9 | a [element 2] : | -| array_flow.rb:1415:16:1415:26 | call to source : | array_flow.rb:1416:9:1416:9 | a [element 2] : | +| array_flow.rb:1415:5:1415:5 | a [element 2] : | array_flow.rb:1416:9:1416:9 | a [element 2] : | +| array_flow.rb:1415:5:1415:5 | a [element 2] : | array_flow.rb:1416:9:1416:9 | a [element 2] : | +| array_flow.rb:1415:16:1415:26 | call to source : | array_flow.rb:1415:5:1415:5 | a [element 2] : | +| array_flow.rb:1415:16:1415:26 | call to source : | array_flow.rb:1415:5:1415:5 | a [element 2] : | +| array_flow.rb:1416:5:1416:5 | b [element] : | array_flow.rb:1422:10:1422:10 | b [element] : | +| array_flow.rb:1416:5:1416:5 | b [element] : | array_flow.rb:1422:10:1422:10 | b [element] : | +| array_flow.rb:1416:5:1416:5 | b [element] : | array_flow.rb:1423:10:1423:10 | b [element] : | +| array_flow.rb:1416:5:1416:5 | b [element] : | array_flow.rb:1423:10:1423:10 | b [element] : | | array_flow.rb:1416:9:1416:9 | [post] a [element] : | array_flow.rb:1420:10:1420:10 | a [element] : | | array_flow.rb:1416:9:1416:9 | [post] a [element] : | array_flow.rb:1420:10:1420:10 | a [element] : | | array_flow.rb:1416:9:1416:9 | [post] a [element] : | array_flow.rb:1421:10:1421:10 | a [element] : | @@ -2929,10 +3632,8 @@ edges | array_flow.rb:1416:9:1416:9 | a [element 2] : | array_flow.rb:1416:9:1419:7 | call to sort_by! [element] : | | array_flow.rb:1416:9:1416:9 | a [element 2] : | array_flow.rb:1416:24:1416:24 | x : | | array_flow.rb:1416:9:1416:9 | a [element 2] : | array_flow.rb:1416:24:1416:24 | x : | -| array_flow.rb:1416:9:1419:7 | call to sort_by! [element] : | array_flow.rb:1422:10:1422:10 | b [element] : | -| array_flow.rb:1416:9:1419:7 | call to sort_by! [element] : | array_flow.rb:1422:10:1422:10 | b [element] : | -| array_flow.rb:1416:9:1419:7 | call to sort_by! [element] : | array_flow.rb:1423:10:1423:10 | b [element] : | -| array_flow.rb:1416:9:1419:7 | call to sort_by! [element] : | array_flow.rb:1423:10:1423:10 | b [element] : | +| array_flow.rb:1416:9:1419:7 | call to sort_by! [element] : | array_flow.rb:1416:5:1416:5 | b [element] : | +| array_flow.rb:1416:9:1419:7 | call to sort_by! [element] : | array_flow.rb:1416:5:1416:5 | b [element] : | | array_flow.rb:1416:24:1416:24 | x : | array_flow.rb:1417:14:1417:14 | x | | array_flow.rb:1416:24:1416:24 | x : | array_flow.rb:1417:14:1417:14 | x | | array_flow.rb:1420:10:1420:10 | a [element] : | array_flow.rb:1420:10:1420:13 | ...[...] | @@ -2943,58 +3644,74 @@ edges | array_flow.rb:1422:10:1422:10 | b [element] : | array_flow.rb:1422:10:1422:13 | ...[...] | | array_flow.rb:1423:10:1423:10 | b [element] : | array_flow.rb:1423:10:1423:13 | ...[...] | | array_flow.rb:1423:10:1423:10 | b [element] : | array_flow.rb:1423:10:1423:13 | ...[...] | -| array_flow.rb:1427:16:1427:26 | call to source : | array_flow.rb:1428:9:1428:9 | a [element 2] : | -| array_flow.rb:1427:16:1427:26 | call to source : | array_flow.rb:1428:9:1428:9 | a [element 2] : | +| array_flow.rb:1427:5:1427:5 | a [element 2] : | array_flow.rb:1428:9:1428:9 | a [element 2] : | +| array_flow.rb:1427:5:1427:5 | a [element 2] : | array_flow.rb:1428:9:1428:9 | a [element 2] : | +| array_flow.rb:1427:16:1427:26 | call to source : | array_flow.rb:1427:5:1427:5 | a [element 2] : | +| array_flow.rb:1427:16:1427:26 | call to source : | array_flow.rb:1427:5:1427:5 | a [element 2] : | | array_flow.rb:1428:9:1428:9 | a [element 2] : | array_flow.rb:1428:19:1428:19 | x : | | array_flow.rb:1428:9:1428:9 | a [element 2] : | array_flow.rb:1428:19:1428:19 | x : | | array_flow.rb:1428:19:1428:19 | x : | array_flow.rb:1429:14:1429:14 | x | | array_flow.rb:1428:19:1428:19 | x : | array_flow.rb:1429:14:1429:14 | x | -| array_flow.rb:1435:16:1435:28 | call to source : | array_flow.rb:1436:9:1436:9 | a [element 2] : | -| array_flow.rb:1435:16:1435:28 | call to source : | array_flow.rb:1436:9:1436:9 | a [element 2] : | -| array_flow.rb:1435:16:1435:28 | call to source : | array_flow.rb:1441:9:1441:9 | a [element 2] : | -| array_flow.rb:1435:16:1435:28 | call to source : | array_flow.rb:1441:9:1441:9 | a [element 2] : | -| array_flow.rb:1435:16:1435:28 | call to source : | array_flow.rb:1447:9:1447:9 | a [element 2] : | -| array_flow.rb:1435:16:1435:28 | call to source : | array_flow.rb:1447:9:1447:9 | a [element 2] : | -| array_flow.rb:1435:16:1435:28 | call to source : | array_flow.rb:1454:9:1454:9 | a [element 2] : | -| array_flow.rb:1435:16:1435:28 | call to source : | array_flow.rb:1454:9:1454:9 | a [element 2] : | -| array_flow.rb:1435:31:1435:43 | call to source : | array_flow.rb:1436:9:1436:9 | a [element 3] : | -| array_flow.rb:1435:31:1435:43 | call to source : | array_flow.rb:1436:9:1436:9 | a [element 3] : | -| array_flow.rb:1435:31:1435:43 | call to source : | array_flow.rb:1447:9:1447:9 | a [element 3] : | -| array_flow.rb:1435:31:1435:43 | call to source : | array_flow.rb:1447:9:1447:9 | a [element 3] : | +| array_flow.rb:1435:5:1435:5 | a [element 2] : | array_flow.rb:1436:9:1436:9 | a [element 2] : | +| array_flow.rb:1435:5:1435:5 | a [element 2] : | array_flow.rb:1436:9:1436:9 | a [element 2] : | +| array_flow.rb:1435:5:1435:5 | a [element 2] : | array_flow.rb:1441:9:1441:9 | a [element 2] : | +| array_flow.rb:1435:5:1435:5 | a [element 2] : | array_flow.rb:1441:9:1441:9 | a [element 2] : | +| array_flow.rb:1435:5:1435:5 | a [element 2] : | array_flow.rb:1447:9:1447:9 | a [element 2] : | +| array_flow.rb:1435:5:1435:5 | a [element 2] : | array_flow.rb:1447:9:1447:9 | a [element 2] : | +| array_flow.rb:1435:5:1435:5 | a [element 2] : | array_flow.rb:1454:9:1454:9 | a [element 2] : | +| array_flow.rb:1435:5:1435:5 | a [element 2] : | array_flow.rb:1454:9:1454:9 | a [element 2] : | +| array_flow.rb:1435:5:1435:5 | a [element 3] : | array_flow.rb:1436:9:1436:9 | a [element 3] : | +| array_flow.rb:1435:5:1435:5 | a [element 3] : | array_flow.rb:1436:9:1436:9 | a [element 3] : | +| array_flow.rb:1435:5:1435:5 | a [element 3] : | array_flow.rb:1447:9:1447:9 | a [element 3] : | +| array_flow.rb:1435:5:1435:5 | a [element 3] : | array_flow.rb:1447:9:1447:9 | a [element 3] : | +| array_flow.rb:1435:16:1435:28 | call to source : | array_flow.rb:1435:5:1435:5 | a [element 2] : | +| array_flow.rb:1435:16:1435:28 | call to source : | array_flow.rb:1435:5:1435:5 | a [element 2] : | +| array_flow.rb:1435:31:1435:43 | call to source : | array_flow.rb:1435:5:1435:5 | a [element 3] : | +| array_flow.rb:1435:31:1435:43 | call to source : | array_flow.rb:1435:5:1435:5 | a [element 3] : | +| array_flow.rb:1436:5:1436:5 | b [element 2] : | array_flow.rb:1439:10:1439:10 | b [element 2] : | +| array_flow.rb:1436:5:1436:5 | b [element 2] : | array_flow.rb:1439:10:1439:10 | b [element 2] : | +| array_flow.rb:1436:5:1436:5 | b [element 3] : | array_flow.rb:1440:10:1440:10 | b [element 3] : | +| array_flow.rb:1436:5:1436:5 | b [element 3] : | array_flow.rb:1440:10:1440:10 | b [element 3] : | | array_flow.rb:1436:9:1436:9 | a [element 2] : | array_flow.rb:1436:9:1436:17 | call to take [element 2] : | | array_flow.rb:1436:9:1436:9 | a [element 2] : | array_flow.rb:1436:9:1436:17 | call to take [element 2] : | | array_flow.rb:1436:9:1436:9 | a [element 3] : | array_flow.rb:1436:9:1436:17 | call to take [element 3] : | | array_flow.rb:1436:9:1436:9 | a [element 3] : | array_flow.rb:1436:9:1436:17 | call to take [element 3] : | -| array_flow.rb:1436:9:1436:17 | call to take [element 2] : | array_flow.rb:1439:10:1439:10 | b [element 2] : | -| array_flow.rb:1436:9:1436:17 | call to take [element 2] : | array_flow.rb:1439:10:1439:10 | b [element 2] : | -| array_flow.rb:1436:9:1436:17 | call to take [element 3] : | array_flow.rb:1440:10:1440:10 | b [element 3] : | -| array_flow.rb:1436:9:1436:17 | call to take [element 3] : | array_flow.rb:1440:10:1440:10 | b [element 3] : | +| array_flow.rb:1436:9:1436:17 | call to take [element 2] : | array_flow.rb:1436:5:1436:5 | b [element 2] : | +| array_flow.rb:1436:9:1436:17 | call to take [element 2] : | array_flow.rb:1436:5:1436:5 | b [element 2] : | +| array_flow.rb:1436:9:1436:17 | call to take [element 3] : | array_flow.rb:1436:5:1436:5 | b [element 3] : | +| array_flow.rb:1436:9:1436:17 | call to take [element 3] : | array_flow.rb:1436:5:1436:5 | b [element 3] : | | array_flow.rb:1439:10:1439:10 | b [element 2] : | array_flow.rb:1439:10:1439:13 | ...[...] | | array_flow.rb:1439:10:1439:10 | b [element 2] : | array_flow.rb:1439:10:1439:13 | ...[...] | | array_flow.rb:1440:10:1440:10 | b [element 3] : | array_flow.rb:1440:10:1440:13 | ...[...] | | array_flow.rb:1440:10:1440:10 | b [element 3] : | array_flow.rb:1440:10:1440:13 | ...[...] | +| array_flow.rb:1441:5:1441:5 | b [element 2] : | array_flow.rb:1444:10:1444:10 | b [element 2] : | +| array_flow.rb:1441:5:1441:5 | b [element 2] : | array_flow.rb:1444:10:1444:10 | b [element 2] : | +| array_flow.rb:1441:5:1441:5 | b [element 2] : | array_flow.rb:1446:10:1446:10 | b [element 2] : | +| array_flow.rb:1441:5:1441:5 | b [element 2] : | array_flow.rb:1446:10:1446:10 | b [element 2] : | | array_flow.rb:1441:9:1441:9 | a [element 2] : | array_flow.rb:1441:9:1441:17 | call to take [element 2] : | | array_flow.rb:1441:9:1441:9 | a [element 2] : | array_flow.rb:1441:9:1441:17 | call to take [element 2] : | -| array_flow.rb:1441:9:1441:17 | call to take [element 2] : | array_flow.rb:1444:10:1444:10 | b [element 2] : | -| array_flow.rb:1441:9:1441:17 | call to take [element 2] : | array_flow.rb:1444:10:1444:10 | b [element 2] : | -| array_flow.rb:1441:9:1441:17 | call to take [element 2] : | array_flow.rb:1446:10:1446:10 | b [element 2] : | -| array_flow.rb:1441:9:1441:17 | call to take [element 2] : | array_flow.rb:1446:10:1446:10 | b [element 2] : | +| array_flow.rb:1441:9:1441:17 | call to take [element 2] : | array_flow.rb:1441:5:1441:5 | b [element 2] : | +| array_flow.rb:1441:9:1441:17 | call to take [element 2] : | array_flow.rb:1441:5:1441:5 | b [element 2] : | | array_flow.rb:1444:10:1444:10 | b [element 2] : | array_flow.rb:1444:10:1444:13 | ...[...] | | array_flow.rb:1444:10:1444:10 | b [element 2] : | array_flow.rb:1444:10:1444:13 | ...[...] | | array_flow.rb:1446:10:1446:10 | b [element 2] : | array_flow.rb:1446:10:1446:13 | ...[...] | | array_flow.rb:1446:10:1446:10 | b [element 2] : | array_flow.rb:1446:10:1446:13 | ...[...] | +| array_flow.rb:1447:5:1447:5 | b [element 2] : | array_flow.rb:1450:10:1450:10 | b [element 2] : | +| array_flow.rb:1447:5:1447:5 | b [element 2] : | array_flow.rb:1450:10:1450:10 | b [element 2] : | +| array_flow.rb:1447:5:1447:5 | b [element 2] : | array_flow.rb:1452:10:1452:10 | b [element 2] : | +| array_flow.rb:1447:5:1447:5 | b [element 2] : | array_flow.rb:1452:10:1452:10 | b [element 2] : | +| array_flow.rb:1447:5:1447:5 | b [element 3] : | array_flow.rb:1451:10:1451:10 | b [element 3] : | +| array_flow.rb:1447:5:1447:5 | b [element 3] : | array_flow.rb:1451:10:1451:10 | b [element 3] : | +| array_flow.rb:1447:5:1447:5 | b [element 3] : | array_flow.rb:1452:10:1452:10 | b [element 3] : | +| array_flow.rb:1447:5:1447:5 | b [element 3] : | array_flow.rb:1452:10:1452:10 | b [element 3] : | | array_flow.rb:1447:9:1447:9 | a [element 2] : | array_flow.rb:1447:9:1447:19 | call to take [element 2] : | | array_flow.rb:1447:9:1447:9 | a [element 2] : | array_flow.rb:1447:9:1447:19 | call to take [element 2] : | | array_flow.rb:1447:9:1447:9 | a [element 3] : | array_flow.rb:1447:9:1447:19 | call to take [element 3] : | | array_flow.rb:1447:9:1447:9 | a [element 3] : | array_flow.rb:1447:9:1447:19 | call to take [element 3] : | -| array_flow.rb:1447:9:1447:19 | call to take [element 2] : | array_flow.rb:1450:10:1450:10 | b [element 2] : | -| array_flow.rb:1447:9:1447:19 | call to take [element 2] : | array_flow.rb:1450:10:1450:10 | b [element 2] : | -| array_flow.rb:1447:9:1447:19 | call to take [element 2] : | array_flow.rb:1452:10:1452:10 | b [element 2] : | -| array_flow.rb:1447:9:1447:19 | call to take [element 2] : | array_flow.rb:1452:10:1452:10 | b [element 2] : | -| array_flow.rb:1447:9:1447:19 | call to take [element 3] : | array_flow.rb:1451:10:1451:10 | b [element 3] : | -| array_flow.rb:1447:9:1447:19 | call to take [element 3] : | array_flow.rb:1451:10:1451:10 | b [element 3] : | -| array_flow.rb:1447:9:1447:19 | call to take [element 3] : | array_flow.rb:1452:10:1452:10 | b [element 3] : | -| array_flow.rb:1447:9:1447:19 | call to take [element 3] : | array_flow.rb:1452:10:1452:10 | b [element 3] : | +| array_flow.rb:1447:9:1447:19 | call to take [element 2] : | array_flow.rb:1447:5:1447:5 | b [element 2] : | +| array_flow.rb:1447:9:1447:19 | call to take [element 2] : | array_flow.rb:1447:5:1447:5 | b [element 2] : | +| array_flow.rb:1447:9:1447:19 | call to take [element 3] : | array_flow.rb:1447:5:1447:5 | b [element 3] : | +| array_flow.rb:1447:9:1447:19 | call to take [element 3] : | array_flow.rb:1447:5:1447:5 | b [element 3] : | | array_flow.rb:1450:10:1450:10 | b [element 2] : | array_flow.rb:1450:10:1450:13 | ...[...] | | array_flow.rb:1450:10:1450:10 | b [element 2] : | array_flow.rb:1450:10:1450:13 | ...[...] | | array_flow.rb:1451:10:1451:10 | b [element 3] : | array_flow.rb:1451:10:1451:13 | ...[...] | @@ -3007,64 +3724,92 @@ edges | array_flow.rb:1453:5:1453:5 | [post] a [element] : | array_flow.rb:1454:9:1454:9 | a [element] : | | array_flow.rb:1453:12:1453:24 | call to source : | array_flow.rb:1453:5:1453:5 | [post] a [element] : | | array_flow.rb:1453:12:1453:24 | call to source : | array_flow.rb:1453:5:1453:5 | [post] a [element] : | +| array_flow.rb:1454:5:1454:5 | b [element 2] : | array_flow.rb:1455:10:1455:10 | b [element 2] : | +| array_flow.rb:1454:5:1454:5 | b [element 2] : | array_flow.rb:1455:10:1455:10 | b [element 2] : | +| array_flow.rb:1454:5:1454:5 | b [element] : | array_flow.rb:1455:10:1455:10 | b [element] : | +| array_flow.rb:1454:5:1454:5 | b [element] : | array_flow.rb:1455:10:1455:10 | b [element] : | | array_flow.rb:1454:9:1454:9 | a [element 2] : | array_flow.rb:1454:9:1454:17 | call to take [element 2] : | | array_flow.rb:1454:9:1454:9 | a [element 2] : | array_flow.rb:1454:9:1454:17 | call to take [element 2] : | | array_flow.rb:1454:9:1454:9 | a [element] : | array_flow.rb:1454:9:1454:17 | call to take [element] : | | array_flow.rb:1454:9:1454:9 | a [element] : | array_flow.rb:1454:9:1454:17 | call to take [element] : | -| array_flow.rb:1454:9:1454:17 | call to take [element 2] : | array_flow.rb:1455:10:1455:10 | b [element 2] : | -| array_flow.rb:1454:9:1454:17 | call to take [element 2] : | array_flow.rb:1455:10:1455:10 | b [element 2] : | -| array_flow.rb:1454:9:1454:17 | call to take [element] : | array_flow.rb:1455:10:1455:10 | b [element] : | -| array_flow.rb:1454:9:1454:17 | call to take [element] : | array_flow.rb:1455:10:1455:10 | b [element] : | +| array_flow.rb:1454:9:1454:17 | call to take [element 2] : | array_flow.rb:1454:5:1454:5 | b [element 2] : | +| array_flow.rb:1454:9:1454:17 | call to take [element 2] : | array_flow.rb:1454:5:1454:5 | b [element 2] : | +| array_flow.rb:1454:9:1454:17 | call to take [element] : | array_flow.rb:1454:5:1454:5 | b [element] : | +| array_flow.rb:1454:9:1454:17 | call to take [element] : | array_flow.rb:1454:5:1454:5 | b [element] : | | array_flow.rb:1455:10:1455:10 | b [element 2] : | array_flow.rb:1455:10:1455:13 | ...[...] | | array_flow.rb:1455:10:1455:10 | b [element 2] : | array_flow.rb:1455:10:1455:13 | ...[...] | | array_flow.rb:1455:10:1455:10 | b [element] : | array_flow.rb:1455:10:1455:13 | ...[...] | | array_flow.rb:1455:10:1455:10 | b [element] : | array_flow.rb:1455:10:1455:13 | ...[...] | -| array_flow.rb:1459:16:1459:26 | call to source : | array_flow.rb:1460:9:1460:9 | a [element 2] : | -| array_flow.rb:1459:16:1459:26 | call to source : | array_flow.rb:1460:9:1460:9 | a [element 2] : | +| array_flow.rb:1459:5:1459:5 | a [element 2] : | array_flow.rb:1460:9:1460:9 | a [element 2] : | +| array_flow.rb:1459:5:1459:5 | a [element 2] : | array_flow.rb:1460:9:1460:9 | a [element 2] : | +| array_flow.rb:1459:16:1459:26 | call to source : | array_flow.rb:1459:5:1459:5 | a [element 2] : | +| array_flow.rb:1459:16:1459:26 | call to source : | array_flow.rb:1459:5:1459:5 | a [element 2] : | +| array_flow.rb:1460:5:1460:5 | b [element 2] : | array_flow.rb:1466:10:1466:10 | b [element 2] : | +| array_flow.rb:1460:5:1460:5 | b [element 2] : | array_flow.rb:1466:10:1466:10 | b [element 2] : | | array_flow.rb:1460:9:1460:9 | a [element 2] : | array_flow.rb:1460:9:1463:7 | call to take_while [element 2] : | | array_flow.rb:1460:9:1460:9 | a [element 2] : | array_flow.rb:1460:9:1463:7 | call to take_while [element 2] : | | array_flow.rb:1460:9:1460:9 | a [element 2] : | array_flow.rb:1460:26:1460:26 | x : | | array_flow.rb:1460:9:1460:9 | a [element 2] : | array_flow.rb:1460:26:1460:26 | x : | -| array_flow.rb:1460:9:1463:7 | call to take_while [element 2] : | array_flow.rb:1466:10:1466:10 | b [element 2] : | -| array_flow.rb:1460:9:1463:7 | call to take_while [element 2] : | array_flow.rb:1466:10:1466:10 | b [element 2] : | +| array_flow.rb:1460:9:1463:7 | call to take_while [element 2] : | array_flow.rb:1460:5:1460:5 | b [element 2] : | +| array_flow.rb:1460:9:1463:7 | call to take_while [element 2] : | array_flow.rb:1460:5:1460:5 | b [element 2] : | | array_flow.rb:1460:26:1460:26 | x : | array_flow.rb:1461:14:1461:14 | x | | array_flow.rb:1460:26:1460:26 | x : | array_flow.rb:1461:14:1461:14 | x | | array_flow.rb:1466:10:1466:10 | b [element 2] : | array_flow.rb:1466:10:1466:13 | ...[...] | | array_flow.rb:1466:10:1466:10 | b [element 2] : | array_flow.rb:1466:10:1466:13 | ...[...] | -| array_flow.rb:1472:19:1472:29 | call to source : | array_flow.rb:1473:9:1473:9 | a [element 3] : | -| array_flow.rb:1472:19:1472:29 | call to source : | array_flow.rb:1473:9:1473:9 | a [element 3] : | +| array_flow.rb:1472:5:1472:5 | a [element 3] : | array_flow.rb:1473:9:1473:9 | a [element 3] : | +| array_flow.rb:1472:5:1472:5 | a [element 3] : | array_flow.rb:1473:9:1473:9 | a [element 3] : | +| array_flow.rb:1472:19:1472:29 | call to source : | array_flow.rb:1472:5:1472:5 | a [element 3] : | +| array_flow.rb:1472:19:1472:29 | call to source : | array_flow.rb:1472:5:1472:5 | a [element 3] : | +| array_flow.rb:1473:5:1473:5 | b [element 3] : | array_flow.rb:1474:10:1474:10 | b [element 3] : | +| array_flow.rb:1473:5:1473:5 | b [element 3] : | array_flow.rb:1474:10:1474:10 | b [element 3] : | | array_flow.rb:1473:9:1473:9 | a [element 3] : | array_flow.rb:1473:9:1473:14 | call to to_a [element 3] : | | array_flow.rb:1473:9:1473:9 | a [element 3] : | array_flow.rb:1473:9:1473:14 | call to to_a [element 3] : | -| array_flow.rb:1473:9:1473:14 | call to to_a [element 3] : | array_flow.rb:1474:10:1474:10 | b [element 3] : | -| array_flow.rb:1473:9:1473:14 | call to to_a [element 3] : | array_flow.rb:1474:10:1474:10 | b [element 3] : | +| array_flow.rb:1473:9:1473:14 | call to to_a [element 3] : | array_flow.rb:1473:5:1473:5 | b [element 3] : | +| array_flow.rb:1473:9:1473:14 | call to to_a [element 3] : | array_flow.rb:1473:5:1473:5 | b [element 3] : | | array_flow.rb:1474:10:1474:10 | b [element 3] : | array_flow.rb:1474:10:1474:13 | ...[...] | | array_flow.rb:1474:10:1474:10 | b [element 3] : | array_flow.rb:1474:10:1474:13 | ...[...] | -| array_flow.rb:1478:16:1478:26 | call to source : | array_flow.rb:1479:9:1479:9 | a [element 2] : | -| array_flow.rb:1478:16:1478:26 | call to source : | array_flow.rb:1479:9:1479:9 | a [element 2] : | +| array_flow.rb:1478:5:1478:5 | a [element 2] : | array_flow.rb:1479:9:1479:9 | a [element 2] : | +| array_flow.rb:1478:5:1478:5 | a [element 2] : | array_flow.rb:1479:9:1479:9 | a [element 2] : | +| array_flow.rb:1478:16:1478:26 | call to source : | array_flow.rb:1478:5:1478:5 | a [element 2] : | +| array_flow.rb:1478:16:1478:26 | call to source : | array_flow.rb:1478:5:1478:5 | a [element 2] : | +| array_flow.rb:1479:5:1479:5 | b [element 2] : | array_flow.rb:1482:10:1482:10 | b [element 2] : | +| array_flow.rb:1479:5:1479:5 | b [element 2] : | array_flow.rb:1482:10:1482:10 | b [element 2] : | | array_flow.rb:1479:9:1479:9 | a [element 2] : | array_flow.rb:1479:9:1479:16 | call to to_ary [element 2] : | | array_flow.rb:1479:9:1479:9 | a [element 2] : | array_flow.rb:1479:9:1479:16 | call to to_ary [element 2] : | -| array_flow.rb:1479:9:1479:16 | call to to_ary [element 2] : | array_flow.rb:1482:10:1482:10 | b [element 2] : | -| array_flow.rb:1479:9:1479:16 | call to to_ary [element 2] : | array_flow.rb:1482:10:1482:10 | b [element 2] : | +| array_flow.rb:1479:9:1479:16 | call to to_ary [element 2] : | array_flow.rb:1479:5:1479:5 | b [element 2] : | +| array_flow.rb:1479:9:1479:16 | call to to_ary [element 2] : | array_flow.rb:1479:5:1479:5 | b [element 2] : | | array_flow.rb:1482:10:1482:10 | b [element 2] : | array_flow.rb:1482:10:1482:13 | ...[...] | | array_flow.rb:1482:10:1482:10 | b [element 2] : | array_flow.rb:1482:10:1482:13 | ...[...] | -| array_flow.rb:1495:14:1495:26 | call to source : | array_flow.rb:1496:9:1496:9 | a [element 0, element 1] : | -| array_flow.rb:1495:14:1495:26 | call to source : | array_flow.rb:1496:9:1496:9 | a [element 0, element 1] : | -| array_flow.rb:1495:34:1495:46 | call to source : | array_flow.rb:1496:9:1496:9 | a [element 1, element 1] : | -| array_flow.rb:1495:34:1495:46 | call to source : | array_flow.rb:1496:9:1496:9 | a [element 1, element 1] : | -| array_flow.rb:1495:54:1495:66 | call to source : | array_flow.rb:1496:9:1496:9 | a [element 2, element 1] : | -| array_flow.rb:1495:54:1495:66 | call to source : | array_flow.rb:1496:9:1496:9 | a [element 2, element 1] : | +| array_flow.rb:1495:5:1495:5 | a [element 0, element 1] : | array_flow.rb:1496:9:1496:9 | a [element 0, element 1] : | +| array_flow.rb:1495:5:1495:5 | a [element 0, element 1] : | array_flow.rb:1496:9:1496:9 | a [element 0, element 1] : | +| array_flow.rb:1495:5:1495:5 | a [element 1, element 1] : | array_flow.rb:1496:9:1496:9 | a [element 1, element 1] : | +| array_flow.rb:1495:5:1495:5 | a [element 1, element 1] : | array_flow.rb:1496:9:1496:9 | a [element 1, element 1] : | +| array_flow.rb:1495:5:1495:5 | a [element 2, element 1] : | array_flow.rb:1496:9:1496:9 | a [element 2, element 1] : | +| array_flow.rb:1495:5:1495:5 | a [element 2, element 1] : | array_flow.rb:1496:9:1496:9 | a [element 2, element 1] : | +| array_flow.rb:1495:14:1495:26 | call to source : | array_flow.rb:1495:5:1495:5 | a [element 0, element 1] : | +| array_flow.rb:1495:14:1495:26 | call to source : | array_flow.rb:1495:5:1495:5 | a [element 0, element 1] : | +| array_flow.rb:1495:34:1495:46 | call to source : | array_flow.rb:1495:5:1495:5 | a [element 1, element 1] : | +| array_flow.rb:1495:34:1495:46 | call to source : | array_flow.rb:1495:5:1495:5 | a [element 1, element 1] : | +| array_flow.rb:1495:54:1495:66 | call to source : | array_flow.rb:1495:5:1495:5 | a [element 2, element 1] : | +| array_flow.rb:1495:54:1495:66 | call to source : | array_flow.rb:1495:5:1495:5 | a [element 2, element 1] : | +| array_flow.rb:1496:5:1496:5 | b [element 1, element 0] : | array_flow.rb:1500:10:1500:10 | b [element 1, element 0] : | +| array_flow.rb:1496:5:1496:5 | b [element 1, element 0] : | array_flow.rb:1500:10:1500:10 | b [element 1, element 0] : | +| array_flow.rb:1496:5:1496:5 | b [element 1, element 1] : | array_flow.rb:1501:10:1501:10 | b [element 1, element 1] : | +| array_flow.rb:1496:5:1496:5 | b [element 1, element 1] : | array_flow.rb:1501:10:1501:10 | b [element 1, element 1] : | +| array_flow.rb:1496:5:1496:5 | b [element 1, element 2] : | array_flow.rb:1502:10:1502:10 | b [element 1, element 2] : | +| array_flow.rb:1496:5:1496:5 | b [element 1, element 2] : | array_flow.rb:1502:10:1502:10 | b [element 1, element 2] : | | array_flow.rb:1496:9:1496:9 | a [element 0, element 1] : | array_flow.rb:1496:9:1496:19 | call to transpose [element 1, element 0] : | | array_flow.rb:1496:9:1496:9 | a [element 0, element 1] : | array_flow.rb:1496:9:1496:19 | call to transpose [element 1, element 0] : | | array_flow.rb:1496:9:1496:9 | a [element 1, element 1] : | array_flow.rb:1496:9:1496:19 | call to transpose [element 1, element 1] : | | array_flow.rb:1496:9:1496:9 | a [element 1, element 1] : | array_flow.rb:1496:9:1496:19 | call to transpose [element 1, element 1] : | | array_flow.rb:1496:9:1496:9 | a [element 2, element 1] : | array_flow.rb:1496:9:1496:19 | call to transpose [element 1, element 2] : | | array_flow.rb:1496:9:1496:9 | a [element 2, element 1] : | array_flow.rb:1496:9:1496:19 | call to transpose [element 1, element 2] : | -| array_flow.rb:1496:9:1496:19 | call to transpose [element 1, element 0] : | array_flow.rb:1500:10:1500:10 | b [element 1, element 0] : | -| array_flow.rb:1496:9:1496:19 | call to transpose [element 1, element 0] : | array_flow.rb:1500:10:1500:10 | b [element 1, element 0] : | -| array_flow.rb:1496:9:1496:19 | call to transpose [element 1, element 1] : | array_flow.rb:1501:10:1501:10 | b [element 1, element 1] : | -| array_flow.rb:1496:9:1496:19 | call to transpose [element 1, element 1] : | array_flow.rb:1501:10:1501:10 | b [element 1, element 1] : | -| array_flow.rb:1496:9:1496:19 | call to transpose [element 1, element 2] : | array_flow.rb:1502:10:1502:10 | b [element 1, element 2] : | -| array_flow.rb:1496:9:1496:19 | call to transpose [element 1, element 2] : | array_flow.rb:1502:10:1502:10 | b [element 1, element 2] : | +| array_flow.rb:1496:9:1496:19 | call to transpose [element 1, element 0] : | array_flow.rb:1496:5:1496:5 | b [element 1, element 0] : | +| array_flow.rb:1496:9:1496:19 | call to transpose [element 1, element 0] : | array_flow.rb:1496:5:1496:5 | b [element 1, element 0] : | +| array_flow.rb:1496:9:1496:19 | call to transpose [element 1, element 1] : | array_flow.rb:1496:5:1496:5 | b [element 1, element 1] : | +| array_flow.rb:1496:9:1496:19 | call to transpose [element 1, element 1] : | array_flow.rb:1496:5:1496:5 | b [element 1, element 1] : | +| array_flow.rb:1496:9:1496:19 | call to transpose [element 1, element 2] : | array_flow.rb:1496:5:1496:5 | b [element 1, element 2] : | +| array_flow.rb:1496:9:1496:19 | call to transpose [element 1, element 2] : | array_flow.rb:1496:5:1496:5 | b [element 1, element 2] : | | array_flow.rb:1500:10:1500:10 | b [element 1, element 0] : | array_flow.rb:1500:10:1500:13 | ...[...] [element 0] : | | array_flow.rb:1500:10:1500:10 | b [element 1, element 0] : | array_flow.rb:1500:10:1500:13 | ...[...] [element 0] : | | array_flow.rb:1500:10:1500:13 | ...[...] [element 0] : | array_flow.rb:1500:10:1500:16 | ...[...] | @@ -3077,20 +3822,28 @@ edges | array_flow.rb:1502:10:1502:10 | b [element 1, element 2] : | array_flow.rb:1502:10:1502:13 | ...[...] [element 2] : | | array_flow.rb:1502:10:1502:13 | ...[...] [element 2] : | array_flow.rb:1502:10:1502:16 | ...[...] | | array_flow.rb:1502:10:1502:13 | ...[...] [element 2] : | array_flow.rb:1502:10:1502:16 | ...[...] | -| array_flow.rb:1506:16:1506:28 | call to source : | array_flow.rb:1509:9:1509:9 | a [element 2] : | -| array_flow.rb:1506:16:1506:28 | call to source : | array_flow.rb:1509:9:1509:9 | a [element 2] : | -| array_flow.rb:1507:13:1507:25 | call to source : | array_flow.rb:1509:17:1509:17 | b [element 1] : | -| array_flow.rb:1507:13:1507:25 | call to source : | array_flow.rb:1509:17:1509:17 | b [element 1] : | -| array_flow.rb:1508:13:1508:25 | call to source : | array_flow.rb:1509:20:1509:20 | c [element 1] : | -| array_flow.rb:1508:13:1508:25 | call to source : | array_flow.rb:1509:20:1509:20 | c [element 1] : | +| array_flow.rb:1506:5:1506:5 | a [element 2] : | array_flow.rb:1509:9:1509:9 | a [element 2] : | +| array_flow.rb:1506:5:1506:5 | a [element 2] : | array_flow.rb:1509:9:1509:9 | a [element 2] : | +| array_flow.rb:1506:16:1506:28 | call to source : | array_flow.rb:1506:5:1506:5 | a [element 2] : | +| array_flow.rb:1506:16:1506:28 | call to source : | array_flow.rb:1506:5:1506:5 | a [element 2] : | +| array_flow.rb:1507:5:1507:5 | b [element 1] : | array_flow.rb:1509:17:1509:17 | b [element 1] : | +| array_flow.rb:1507:5:1507:5 | b [element 1] : | array_flow.rb:1509:17:1509:17 | b [element 1] : | +| array_flow.rb:1507:13:1507:25 | call to source : | array_flow.rb:1507:5:1507:5 | b [element 1] : | +| array_flow.rb:1507:13:1507:25 | call to source : | array_flow.rb:1507:5:1507:5 | b [element 1] : | +| array_flow.rb:1508:5:1508:5 | c [element 1] : | array_flow.rb:1509:20:1509:20 | c [element 1] : | +| array_flow.rb:1508:5:1508:5 | c [element 1] : | array_flow.rb:1509:20:1509:20 | c [element 1] : | +| array_flow.rb:1508:13:1508:25 | call to source : | array_flow.rb:1508:5:1508:5 | c [element 1] : | +| array_flow.rb:1508:13:1508:25 | call to source : | array_flow.rb:1508:5:1508:5 | c [element 1] : | +| array_flow.rb:1509:5:1509:5 | d [element] : | array_flow.rb:1510:10:1510:10 | d [element] : | +| array_flow.rb:1509:5:1509:5 | d [element] : | array_flow.rb:1510:10:1510:10 | d [element] : | +| array_flow.rb:1509:5:1509:5 | d [element] : | array_flow.rb:1511:10:1511:10 | d [element] : | +| array_flow.rb:1509:5:1509:5 | d [element] : | array_flow.rb:1511:10:1511:10 | d [element] : | +| array_flow.rb:1509:5:1509:5 | d [element] : | array_flow.rb:1512:10:1512:10 | d [element] : | +| array_flow.rb:1509:5:1509:5 | d [element] : | array_flow.rb:1512:10:1512:10 | d [element] : | | array_flow.rb:1509:9:1509:9 | a [element 2] : | array_flow.rb:1509:9:1509:21 | call to union [element] : | | array_flow.rb:1509:9:1509:9 | a [element 2] : | array_flow.rb:1509:9:1509:21 | call to union [element] : | -| array_flow.rb:1509:9:1509:21 | call to union [element] : | array_flow.rb:1510:10:1510:10 | d [element] : | -| array_flow.rb:1509:9:1509:21 | call to union [element] : | array_flow.rb:1510:10:1510:10 | d [element] : | -| array_flow.rb:1509:9:1509:21 | call to union [element] : | array_flow.rb:1511:10:1511:10 | d [element] : | -| array_flow.rb:1509:9:1509:21 | call to union [element] : | array_flow.rb:1511:10:1511:10 | d [element] : | -| array_flow.rb:1509:9:1509:21 | call to union [element] : | array_flow.rb:1512:10:1512:10 | d [element] : | -| array_flow.rb:1509:9:1509:21 | call to union [element] : | array_flow.rb:1512:10:1512:10 | d [element] : | +| array_flow.rb:1509:9:1509:21 | call to union [element] : | array_flow.rb:1509:5:1509:5 | d [element] : | +| array_flow.rb:1509:9:1509:21 | call to union [element] : | array_flow.rb:1509:5:1509:5 | d [element] : | | array_flow.rb:1509:17:1509:17 | b [element 1] : | array_flow.rb:1509:9:1509:21 | call to union [element] : | | array_flow.rb:1509:17:1509:17 | b [element 1] : | array_flow.rb:1509:9:1509:21 | call to union [element] : | | array_flow.rb:1509:20:1509:20 | c [element 1] : | array_flow.rb:1509:9:1509:21 | call to union [element] : | @@ -3101,26 +3854,34 @@ edges | array_flow.rb:1511:10:1511:10 | d [element] : | array_flow.rb:1511:10:1511:13 | ...[...] | | array_flow.rb:1512:10:1512:10 | d [element] : | array_flow.rb:1512:10:1512:13 | ...[...] | | array_flow.rb:1512:10:1512:10 | d [element] : | array_flow.rb:1512:10:1512:13 | ...[...] | -| array_flow.rb:1516:19:1516:31 | call to source : | array_flow.rb:1518:9:1518:9 | a [element 3] : | -| array_flow.rb:1516:19:1516:31 | call to source : | array_flow.rb:1518:9:1518:9 | a [element 3] : | -| array_flow.rb:1516:19:1516:31 | call to source : | array_flow.rb:1522:9:1522:9 | a [element 3] : | -| array_flow.rb:1516:19:1516:31 | call to source : | array_flow.rb:1522:9:1522:9 | a [element 3] : | -| array_flow.rb:1516:34:1516:46 | call to source : | array_flow.rb:1518:9:1518:9 | a [element 4] : | -| array_flow.rb:1516:34:1516:46 | call to source : | array_flow.rb:1518:9:1518:9 | a [element 4] : | -| array_flow.rb:1516:34:1516:46 | call to source : | array_flow.rb:1522:9:1522:9 | a [element 4] : | -| array_flow.rb:1516:34:1516:46 | call to source : | array_flow.rb:1522:9:1522:9 | a [element 4] : | +| array_flow.rb:1516:5:1516:5 | a [element 3] : | array_flow.rb:1518:9:1518:9 | a [element 3] : | +| array_flow.rb:1516:5:1516:5 | a [element 3] : | array_flow.rb:1518:9:1518:9 | a [element 3] : | +| array_flow.rb:1516:5:1516:5 | a [element 3] : | array_flow.rb:1522:9:1522:9 | a [element 3] : | +| array_flow.rb:1516:5:1516:5 | a [element 3] : | array_flow.rb:1522:9:1522:9 | a [element 3] : | +| array_flow.rb:1516:5:1516:5 | a [element 4] : | array_flow.rb:1518:9:1518:9 | a [element 4] : | +| array_flow.rb:1516:5:1516:5 | a [element 4] : | array_flow.rb:1518:9:1518:9 | a [element 4] : | +| array_flow.rb:1516:5:1516:5 | a [element 4] : | array_flow.rb:1522:9:1522:9 | a [element 4] : | +| array_flow.rb:1516:5:1516:5 | a [element 4] : | array_flow.rb:1522:9:1522:9 | a [element 4] : | +| array_flow.rb:1516:19:1516:31 | call to source : | array_flow.rb:1516:5:1516:5 | a [element 3] : | +| array_flow.rb:1516:19:1516:31 | call to source : | array_flow.rb:1516:5:1516:5 | a [element 3] : | +| array_flow.rb:1516:34:1516:46 | call to source : | array_flow.rb:1516:5:1516:5 | a [element 4] : | +| array_flow.rb:1516:34:1516:46 | call to source : | array_flow.rb:1516:5:1516:5 | a [element 4] : | +| array_flow.rb:1518:5:1518:5 | b [element] : | array_flow.rb:1519:10:1519:10 | b [element] : | +| array_flow.rb:1518:5:1518:5 | b [element] : | array_flow.rb:1519:10:1519:10 | b [element] : | +| array_flow.rb:1518:5:1518:5 | b [element] : | array_flow.rb:1520:10:1520:10 | b [element] : | +| array_flow.rb:1518:5:1518:5 | b [element] : | array_flow.rb:1520:10:1520:10 | b [element] : | | array_flow.rb:1518:9:1518:9 | a [element 3] : | array_flow.rb:1518:9:1518:14 | call to uniq [element] : | | array_flow.rb:1518:9:1518:9 | a [element 3] : | array_flow.rb:1518:9:1518:14 | call to uniq [element] : | | array_flow.rb:1518:9:1518:9 | a [element 4] : | array_flow.rb:1518:9:1518:14 | call to uniq [element] : | | array_flow.rb:1518:9:1518:9 | a [element 4] : | array_flow.rb:1518:9:1518:14 | call to uniq [element] : | -| array_flow.rb:1518:9:1518:14 | call to uniq [element] : | array_flow.rb:1519:10:1519:10 | b [element] : | -| array_flow.rb:1518:9:1518:14 | call to uniq [element] : | array_flow.rb:1519:10:1519:10 | b [element] : | -| array_flow.rb:1518:9:1518:14 | call to uniq [element] : | array_flow.rb:1520:10:1520:10 | b [element] : | -| array_flow.rb:1518:9:1518:14 | call to uniq [element] : | array_flow.rb:1520:10:1520:10 | b [element] : | +| array_flow.rb:1518:9:1518:14 | call to uniq [element] : | array_flow.rb:1518:5:1518:5 | b [element] : | +| array_flow.rb:1518:9:1518:14 | call to uniq [element] : | array_flow.rb:1518:5:1518:5 | b [element] : | | array_flow.rb:1519:10:1519:10 | b [element] : | array_flow.rb:1519:10:1519:13 | ...[...] | | array_flow.rb:1519:10:1519:10 | b [element] : | array_flow.rb:1519:10:1519:13 | ...[...] | | array_flow.rb:1520:10:1520:10 | b [element] : | array_flow.rb:1520:10:1520:13 | ...[...] | | array_flow.rb:1520:10:1520:10 | b [element] : | array_flow.rb:1520:10:1520:13 | ...[...] | +| array_flow.rb:1522:5:1522:5 | c [element] : | array_flow.rb:1526:10:1526:10 | c [element] : | +| array_flow.rb:1522:5:1522:5 | c [element] : | array_flow.rb:1526:10:1526:10 | c [element] : | | array_flow.rb:1522:9:1522:9 | a [element 3] : | array_flow.rb:1522:9:1525:7 | call to uniq [element] : | | array_flow.rb:1522:9:1522:9 | a [element 3] : | array_flow.rb:1522:9:1525:7 | call to uniq [element] : | | array_flow.rb:1522:9:1522:9 | a [element 3] : | array_flow.rb:1522:20:1522:20 | x : | @@ -3129,16 +3890,24 @@ edges | array_flow.rb:1522:9:1522:9 | a [element 4] : | array_flow.rb:1522:9:1525:7 | call to uniq [element] : | | array_flow.rb:1522:9:1522:9 | a [element 4] : | array_flow.rb:1522:20:1522:20 | x : | | array_flow.rb:1522:9:1522:9 | a [element 4] : | array_flow.rb:1522:20:1522:20 | x : | -| array_flow.rb:1522:9:1525:7 | call to uniq [element] : | array_flow.rb:1526:10:1526:10 | c [element] : | -| array_flow.rb:1522:9:1525:7 | call to uniq [element] : | array_flow.rb:1526:10:1526:10 | c [element] : | +| array_flow.rb:1522:9:1525:7 | call to uniq [element] : | array_flow.rb:1522:5:1522:5 | c [element] : | +| array_flow.rb:1522:9:1525:7 | call to uniq [element] : | array_flow.rb:1522:5:1522:5 | c [element] : | | array_flow.rb:1522:20:1522:20 | x : | array_flow.rb:1523:14:1523:14 | x | | array_flow.rb:1522:20:1522:20 | x : | array_flow.rb:1523:14:1523:14 | x | | array_flow.rb:1526:10:1526:10 | c [element] : | array_flow.rb:1526:10:1526:13 | ...[...] | | array_flow.rb:1526:10:1526:10 | c [element] : | array_flow.rb:1526:10:1526:13 | ...[...] | -| array_flow.rb:1530:16:1530:28 | call to source : | array_flow.rb:1531:9:1531:9 | a [element 2] : | -| array_flow.rb:1530:16:1530:28 | call to source : | array_flow.rb:1531:9:1531:9 | a [element 2] : | -| array_flow.rb:1530:31:1530:43 | call to source : | array_flow.rb:1531:9:1531:9 | a [element 3] : | -| array_flow.rb:1530:31:1530:43 | call to source : | array_flow.rb:1531:9:1531:9 | a [element 3] : | +| array_flow.rb:1530:5:1530:5 | a [element 2] : | array_flow.rb:1531:9:1531:9 | a [element 2] : | +| array_flow.rb:1530:5:1530:5 | a [element 2] : | array_flow.rb:1531:9:1531:9 | a [element 2] : | +| array_flow.rb:1530:5:1530:5 | a [element 3] : | array_flow.rb:1531:9:1531:9 | a [element 3] : | +| array_flow.rb:1530:5:1530:5 | a [element 3] : | array_flow.rb:1531:9:1531:9 | a [element 3] : | +| array_flow.rb:1530:16:1530:28 | call to source : | array_flow.rb:1530:5:1530:5 | a [element 2] : | +| array_flow.rb:1530:16:1530:28 | call to source : | array_flow.rb:1530:5:1530:5 | a [element 2] : | +| array_flow.rb:1530:31:1530:43 | call to source : | array_flow.rb:1530:5:1530:5 | a [element 3] : | +| array_flow.rb:1530:31:1530:43 | call to source : | array_flow.rb:1530:5:1530:5 | a [element 3] : | +| array_flow.rb:1531:5:1531:5 | b [element] : | array_flow.rb:1532:10:1532:10 | b [element] : | +| array_flow.rb:1531:5:1531:5 | b [element] : | array_flow.rb:1532:10:1532:10 | b [element] : | +| array_flow.rb:1531:5:1531:5 | b [element] : | array_flow.rb:1533:10:1533:10 | b [element] : | +| array_flow.rb:1531:5:1531:5 | b [element] : | array_flow.rb:1533:10:1533:10 | b [element] : | | array_flow.rb:1531:9:1531:9 | [post] a [element] : | array_flow.rb:1534:10:1534:10 | a [element] : | | array_flow.rb:1531:9:1531:9 | [post] a [element] : | array_flow.rb:1534:10:1534:10 | a [element] : | | array_flow.rb:1531:9:1531:9 | [post] a [element] : | array_flow.rb:1535:10:1535:10 | a [element] : | @@ -3151,10 +3920,8 @@ edges | array_flow.rb:1531:9:1531:9 | a [element 3] : | array_flow.rb:1531:9:1531:9 | [post] a [element] : | | array_flow.rb:1531:9:1531:9 | a [element 3] : | array_flow.rb:1531:9:1531:15 | call to uniq! [element] : | | array_flow.rb:1531:9:1531:9 | a [element 3] : | array_flow.rb:1531:9:1531:15 | call to uniq! [element] : | -| array_flow.rb:1531:9:1531:15 | call to uniq! [element] : | array_flow.rb:1532:10:1532:10 | b [element] : | -| array_flow.rb:1531:9:1531:15 | call to uniq! [element] : | array_flow.rb:1532:10:1532:10 | b [element] : | -| array_flow.rb:1531:9:1531:15 | call to uniq! [element] : | array_flow.rb:1533:10:1533:10 | b [element] : | -| array_flow.rb:1531:9:1531:15 | call to uniq! [element] : | array_flow.rb:1533:10:1533:10 | b [element] : | +| array_flow.rb:1531:9:1531:15 | call to uniq! [element] : | array_flow.rb:1531:5:1531:5 | b [element] : | +| array_flow.rb:1531:9:1531:15 | call to uniq! [element] : | array_flow.rb:1531:5:1531:5 | b [element] : | | array_flow.rb:1532:10:1532:10 | b [element] : | array_flow.rb:1532:10:1532:13 | ...[...] | | array_flow.rb:1532:10:1532:10 | b [element] : | array_flow.rb:1532:10:1532:13 | ...[...] | | array_flow.rb:1533:10:1533:10 | b [element] : | array_flow.rb:1533:10:1533:13 | ...[...] | @@ -3163,10 +3930,18 @@ edges | array_flow.rb:1534:10:1534:10 | a [element] : | array_flow.rb:1534:10:1534:13 | ...[...] | | array_flow.rb:1535:10:1535:10 | a [element] : | array_flow.rb:1535:10:1535:13 | ...[...] | | array_flow.rb:1535:10:1535:10 | a [element] : | array_flow.rb:1535:10:1535:13 | ...[...] | -| array_flow.rb:1537:16:1537:28 | call to source : | array_flow.rb:1538:9:1538:9 | a [element 2] : | -| array_flow.rb:1537:16:1537:28 | call to source : | array_flow.rb:1538:9:1538:9 | a [element 2] : | -| array_flow.rb:1537:31:1537:43 | call to source : | array_flow.rb:1538:9:1538:9 | a [element 3] : | -| array_flow.rb:1537:31:1537:43 | call to source : | array_flow.rb:1538:9:1538:9 | a [element 3] : | +| array_flow.rb:1537:5:1537:5 | a [element 2] : | array_flow.rb:1538:9:1538:9 | a [element 2] : | +| array_flow.rb:1537:5:1537:5 | a [element 2] : | array_flow.rb:1538:9:1538:9 | a [element 2] : | +| array_flow.rb:1537:5:1537:5 | a [element 3] : | array_flow.rb:1538:9:1538:9 | a [element 3] : | +| array_flow.rb:1537:5:1537:5 | a [element 3] : | array_flow.rb:1538:9:1538:9 | a [element 3] : | +| array_flow.rb:1537:16:1537:28 | call to source : | array_flow.rb:1537:5:1537:5 | a [element 2] : | +| array_flow.rb:1537:16:1537:28 | call to source : | array_flow.rb:1537:5:1537:5 | a [element 2] : | +| array_flow.rb:1537:31:1537:43 | call to source : | array_flow.rb:1537:5:1537:5 | a [element 3] : | +| array_flow.rb:1537:31:1537:43 | call to source : | array_flow.rb:1537:5:1537:5 | a [element 3] : | +| array_flow.rb:1538:5:1538:5 | b [element] : | array_flow.rb:1542:10:1542:10 | b [element] : | +| array_flow.rb:1538:5:1538:5 | b [element] : | array_flow.rb:1542:10:1542:10 | b [element] : | +| array_flow.rb:1538:5:1538:5 | b [element] : | array_flow.rb:1543:10:1543:10 | b [element] : | +| array_flow.rb:1538:5:1538:5 | b [element] : | array_flow.rb:1543:10:1543:10 | b [element] : | | array_flow.rb:1538:9:1538:9 | [post] a [element] : | array_flow.rb:1544:10:1544:10 | a [element] : | | array_flow.rb:1538:9:1538:9 | [post] a [element] : | array_flow.rb:1544:10:1544:10 | a [element] : | | array_flow.rb:1538:9:1538:9 | [post] a [element] : | array_flow.rb:1545:10:1545:10 | a [element] : | @@ -3183,10 +3958,8 @@ edges | array_flow.rb:1538:9:1538:9 | a [element 3] : | array_flow.rb:1538:9:1541:7 | call to uniq! [element] : | | array_flow.rb:1538:9:1538:9 | a [element 3] : | array_flow.rb:1538:21:1538:21 | x : | | array_flow.rb:1538:9:1538:9 | a [element 3] : | array_flow.rb:1538:21:1538:21 | x : | -| array_flow.rb:1538:9:1541:7 | call to uniq! [element] : | array_flow.rb:1542:10:1542:10 | b [element] : | -| array_flow.rb:1538:9:1541:7 | call to uniq! [element] : | array_flow.rb:1542:10:1542:10 | b [element] : | -| array_flow.rb:1538:9:1541:7 | call to uniq! [element] : | array_flow.rb:1543:10:1543:10 | b [element] : | -| array_flow.rb:1538:9:1541:7 | call to uniq! [element] : | array_flow.rb:1543:10:1543:10 | b [element] : | +| array_flow.rb:1538:9:1541:7 | call to uniq! [element] : | array_flow.rb:1538:5:1538:5 | b [element] : | +| array_flow.rb:1538:9:1541:7 | call to uniq! [element] : | array_flow.rb:1538:5:1538:5 | b [element] : | | array_flow.rb:1538:21:1538:21 | x : | array_flow.rb:1539:14:1539:14 | x | | array_flow.rb:1538:21:1538:21 | x : | array_flow.rb:1539:14:1539:14 | x | | array_flow.rb:1542:10:1542:10 | b [element] : | array_flow.rb:1542:10:1542:13 | ...[...] | @@ -3197,8 +3970,10 @@ edges | array_flow.rb:1544:10:1544:10 | a [element] : | array_flow.rb:1544:10:1544:13 | ...[...] | | array_flow.rb:1545:10:1545:10 | a [element] : | array_flow.rb:1545:10:1545:13 | ...[...] | | array_flow.rb:1545:10:1545:10 | a [element] : | array_flow.rb:1545:10:1545:13 | ...[...] | -| array_flow.rb:1549:16:1549:28 | call to source : | array_flow.rb:1550:5:1550:5 | a [element 2] : | -| array_flow.rb:1549:16:1549:28 | call to source : | array_flow.rb:1550:5:1550:5 | a [element 2] : | +| array_flow.rb:1549:5:1549:5 | a [element 2] : | array_flow.rb:1550:5:1550:5 | a [element 2] : | +| array_flow.rb:1549:5:1549:5 | a [element 2] : | array_flow.rb:1550:5:1550:5 | a [element 2] : | +| array_flow.rb:1549:16:1549:28 | call to source : | array_flow.rb:1549:5:1549:5 | a [element 2] : | +| array_flow.rb:1549:16:1549:28 | call to source : | array_flow.rb:1549:5:1549:5 | a [element 2] : | | array_flow.rb:1550:5:1550:5 | [post] a [element 2] : | array_flow.rb:1553:10:1553:10 | a [element 2] : | | array_flow.rb:1550:5:1550:5 | [post] a [element 2] : | array_flow.rb:1553:10:1553:10 | a [element 2] : | | array_flow.rb:1550:5:1550:5 | [post] a [element 5] : | array_flow.rb:1556:10:1556:10 | a [element 5] : | @@ -3211,72 +3986,88 @@ edges | array_flow.rb:1553:10:1553:10 | a [element 2] : | array_flow.rb:1553:10:1553:13 | ...[...] | | array_flow.rb:1556:10:1556:10 | a [element 5] : | array_flow.rb:1556:10:1556:13 | ...[...] | | array_flow.rb:1556:10:1556:10 | a [element 5] : | array_flow.rb:1556:10:1556:13 | ...[...] | -| array_flow.rb:1560:13:1560:25 | call to source : | array_flow.rb:1562:9:1562:9 | a [element 1] : | -| array_flow.rb:1560:13:1560:25 | call to source : | array_flow.rb:1562:9:1562:9 | a [element 1] : | -| array_flow.rb:1560:13:1560:25 | call to source : | array_flow.rb:1568:9:1568:9 | a [element 1] : | -| array_flow.rb:1560:13:1560:25 | call to source : | array_flow.rb:1568:9:1568:9 | a [element 1] : | -| array_flow.rb:1560:13:1560:25 | call to source : | array_flow.rb:1572:9:1572:9 | a [element 1] : | -| array_flow.rb:1560:13:1560:25 | call to source : | array_flow.rb:1572:9:1572:9 | a [element 1] : | -| array_flow.rb:1560:13:1560:25 | call to source : | array_flow.rb:1576:9:1576:9 | a [element 1] : | -| array_flow.rb:1560:13:1560:25 | call to source : | array_flow.rb:1576:9:1576:9 | a [element 1] : | -| array_flow.rb:1560:31:1560:43 | call to source : | array_flow.rb:1568:9:1568:9 | a [element 3] : | -| array_flow.rb:1560:31:1560:43 | call to source : | array_flow.rb:1568:9:1568:9 | a [element 3] : | -| array_flow.rb:1560:31:1560:43 | call to source : | array_flow.rb:1572:9:1572:9 | a [element 3] : | -| array_flow.rb:1560:31:1560:43 | call to source : | array_flow.rb:1572:9:1572:9 | a [element 3] : | -| array_flow.rb:1560:31:1560:43 | call to source : | array_flow.rb:1576:9:1576:9 | a [element 3] : | -| array_flow.rb:1560:31:1560:43 | call to source : | array_flow.rb:1576:9:1576:9 | a [element 3] : | +| array_flow.rb:1560:5:1560:5 | a [element 1] : | array_flow.rb:1562:9:1562:9 | a [element 1] : | +| array_flow.rb:1560:5:1560:5 | a [element 1] : | array_flow.rb:1562:9:1562:9 | a [element 1] : | +| array_flow.rb:1560:5:1560:5 | a [element 1] : | array_flow.rb:1568:9:1568:9 | a [element 1] : | +| array_flow.rb:1560:5:1560:5 | a [element 1] : | array_flow.rb:1568:9:1568:9 | a [element 1] : | +| array_flow.rb:1560:5:1560:5 | a [element 1] : | array_flow.rb:1572:9:1572:9 | a [element 1] : | +| array_flow.rb:1560:5:1560:5 | a [element 1] : | array_flow.rb:1572:9:1572:9 | a [element 1] : | +| array_flow.rb:1560:5:1560:5 | a [element 1] : | array_flow.rb:1576:9:1576:9 | a [element 1] : | +| array_flow.rb:1560:5:1560:5 | a [element 1] : | array_flow.rb:1576:9:1576:9 | a [element 1] : | +| array_flow.rb:1560:5:1560:5 | a [element 3] : | array_flow.rb:1568:9:1568:9 | a [element 3] : | +| array_flow.rb:1560:5:1560:5 | a [element 3] : | array_flow.rb:1568:9:1568:9 | a [element 3] : | +| array_flow.rb:1560:5:1560:5 | a [element 3] : | array_flow.rb:1572:9:1572:9 | a [element 3] : | +| array_flow.rb:1560:5:1560:5 | a [element 3] : | array_flow.rb:1572:9:1572:9 | a [element 3] : | +| array_flow.rb:1560:5:1560:5 | a [element 3] : | array_flow.rb:1576:9:1576:9 | a [element 3] : | +| array_flow.rb:1560:5:1560:5 | a [element 3] : | array_flow.rb:1576:9:1576:9 | a [element 3] : | +| array_flow.rb:1560:13:1560:25 | call to source : | array_flow.rb:1560:5:1560:5 | a [element 1] : | +| array_flow.rb:1560:13:1560:25 | call to source : | array_flow.rb:1560:5:1560:5 | a [element 1] : | +| array_flow.rb:1560:31:1560:43 | call to source : | array_flow.rb:1560:5:1560:5 | a [element 3] : | +| array_flow.rb:1560:31:1560:43 | call to source : | array_flow.rb:1560:5:1560:5 | a [element 3] : | +| array_flow.rb:1562:5:1562:5 | b [element 1] : | array_flow.rb:1564:10:1564:10 | b [element 1] : | +| array_flow.rb:1562:5:1562:5 | b [element 1] : | array_flow.rb:1564:10:1564:10 | b [element 1] : | +| array_flow.rb:1562:5:1562:5 | b [element 3] : | array_flow.rb:1566:10:1566:10 | b [element 3] : | +| array_flow.rb:1562:5:1562:5 | b [element 3] : | array_flow.rb:1566:10:1566:10 | b [element 3] : | | array_flow.rb:1562:9:1562:9 | a [element 1] : | array_flow.rb:1562:9:1562:31 | call to values_at [element 1] : | | array_flow.rb:1562:9:1562:9 | a [element 1] : | array_flow.rb:1562:9:1562:31 | call to values_at [element 1] : | | array_flow.rb:1562:9:1562:9 | a [element 1] : | array_flow.rb:1562:9:1562:31 | call to values_at [element 3] : | | array_flow.rb:1562:9:1562:9 | a [element 1] : | array_flow.rb:1562:9:1562:31 | call to values_at [element 3] : | -| array_flow.rb:1562:9:1562:31 | call to values_at [element 1] : | array_flow.rb:1564:10:1564:10 | b [element 1] : | -| array_flow.rb:1562:9:1562:31 | call to values_at [element 1] : | array_flow.rb:1564:10:1564:10 | b [element 1] : | -| array_flow.rb:1562:9:1562:31 | call to values_at [element 3] : | array_flow.rb:1566:10:1566:10 | b [element 3] : | -| array_flow.rb:1562:9:1562:31 | call to values_at [element 3] : | array_flow.rb:1566:10:1566:10 | b [element 3] : | +| array_flow.rb:1562:9:1562:31 | call to values_at [element 1] : | array_flow.rb:1562:5:1562:5 | b [element 1] : | +| array_flow.rb:1562:9:1562:31 | call to values_at [element 1] : | array_flow.rb:1562:5:1562:5 | b [element 1] : | +| array_flow.rb:1562:9:1562:31 | call to values_at [element 3] : | array_flow.rb:1562:5:1562:5 | b [element 3] : | +| array_flow.rb:1562:9:1562:31 | call to values_at [element 3] : | array_flow.rb:1562:5:1562:5 | b [element 3] : | | array_flow.rb:1564:10:1564:10 | b [element 1] : | array_flow.rb:1564:10:1564:13 | ...[...] | | array_flow.rb:1564:10:1564:10 | b [element 1] : | array_flow.rb:1564:10:1564:13 | ...[...] | | array_flow.rb:1566:10:1566:10 | b [element 3] : | array_flow.rb:1566:10:1566:13 | ...[...] | | array_flow.rb:1566:10:1566:10 | b [element 3] : | array_flow.rb:1566:10:1566:13 | ...[...] | +| array_flow.rb:1568:5:1568:5 | b [element] : | array_flow.rb:1569:10:1569:10 | b [element] : | +| array_flow.rb:1568:5:1568:5 | b [element] : | array_flow.rb:1569:10:1569:10 | b [element] : | +| array_flow.rb:1568:5:1568:5 | b [element] : | array_flow.rb:1570:10:1570:10 | b [element] : | +| array_flow.rb:1568:5:1568:5 | b [element] : | array_flow.rb:1570:10:1570:10 | b [element] : | | array_flow.rb:1568:9:1568:9 | a [element 1] : | array_flow.rb:1568:9:1568:25 | call to values_at [element] : | | array_flow.rb:1568:9:1568:9 | a [element 1] : | array_flow.rb:1568:9:1568:25 | call to values_at [element] : | | array_flow.rb:1568:9:1568:9 | a [element 3] : | array_flow.rb:1568:9:1568:25 | call to values_at [element] : | | array_flow.rb:1568:9:1568:9 | a [element 3] : | array_flow.rb:1568:9:1568:25 | call to values_at [element] : | -| array_flow.rb:1568:9:1568:25 | call to values_at [element] : | array_flow.rb:1569:10:1569:10 | b [element] : | -| array_flow.rb:1568:9:1568:25 | call to values_at [element] : | array_flow.rb:1569:10:1569:10 | b [element] : | -| array_flow.rb:1568:9:1568:25 | call to values_at [element] : | array_flow.rb:1570:10:1570:10 | b [element] : | -| array_flow.rb:1568:9:1568:25 | call to values_at [element] : | array_flow.rb:1570:10:1570:10 | b [element] : | +| array_flow.rb:1568:9:1568:25 | call to values_at [element] : | array_flow.rb:1568:5:1568:5 | b [element] : | +| array_flow.rb:1568:9:1568:25 | call to values_at [element] : | array_flow.rb:1568:5:1568:5 | b [element] : | | array_flow.rb:1569:10:1569:10 | b [element] : | array_flow.rb:1569:10:1569:13 | ...[...] | | array_flow.rb:1569:10:1569:10 | b [element] : | array_flow.rb:1569:10:1569:13 | ...[...] | | array_flow.rb:1570:10:1570:10 | b [element] : | array_flow.rb:1570:10:1570:13 | ...[...] | | array_flow.rb:1570:10:1570:10 | b [element] : | array_flow.rb:1570:10:1570:13 | ...[...] | +| array_flow.rb:1572:5:1572:5 | b [element] : | array_flow.rb:1573:10:1573:10 | b [element] : | +| array_flow.rb:1572:5:1572:5 | b [element] : | array_flow.rb:1573:10:1573:10 | b [element] : | +| array_flow.rb:1572:5:1572:5 | b [element] : | array_flow.rb:1574:10:1574:10 | b [element] : | +| array_flow.rb:1572:5:1572:5 | b [element] : | array_flow.rb:1574:10:1574:10 | b [element] : | | array_flow.rb:1572:9:1572:9 | a [element 1] : | array_flow.rb:1572:9:1572:26 | call to values_at [element] : | | array_flow.rb:1572:9:1572:9 | a [element 1] : | array_flow.rb:1572:9:1572:26 | call to values_at [element] : | | array_flow.rb:1572:9:1572:9 | a [element 3] : | array_flow.rb:1572:9:1572:26 | call to values_at [element] : | | array_flow.rb:1572:9:1572:9 | a [element 3] : | array_flow.rb:1572:9:1572:26 | call to values_at [element] : | -| array_flow.rb:1572:9:1572:26 | call to values_at [element] : | array_flow.rb:1573:10:1573:10 | b [element] : | -| array_flow.rb:1572:9:1572:26 | call to values_at [element] : | array_flow.rb:1573:10:1573:10 | b [element] : | -| array_flow.rb:1572:9:1572:26 | call to values_at [element] : | array_flow.rb:1574:10:1574:10 | b [element] : | -| array_flow.rb:1572:9:1572:26 | call to values_at [element] : | array_flow.rb:1574:10:1574:10 | b [element] : | +| array_flow.rb:1572:9:1572:26 | call to values_at [element] : | array_flow.rb:1572:5:1572:5 | b [element] : | +| array_flow.rb:1572:9:1572:26 | call to values_at [element] : | array_flow.rb:1572:5:1572:5 | b [element] : | | array_flow.rb:1573:10:1573:10 | b [element] : | array_flow.rb:1573:10:1573:13 | ...[...] | | array_flow.rb:1573:10:1573:10 | b [element] : | array_flow.rb:1573:10:1573:13 | ...[...] | | array_flow.rb:1574:10:1574:10 | b [element] : | array_flow.rb:1574:10:1574:13 | ...[...] | | array_flow.rb:1574:10:1574:10 | b [element] : | array_flow.rb:1574:10:1574:13 | ...[...] | +| array_flow.rb:1576:5:1576:5 | b [element 1] : | array_flow.rb:1578:10:1578:10 | b [element 1] : | +| array_flow.rb:1576:5:1576:5 | b [element 1] : | array_flow.rb:1578:10:1578:10 | b [element 1] : | +| array_flow.rb:1576:5:1576:5 | b [element] : | array_flow.rb:1577:10:1577:10 | b [element] : | +| array_flow.rb:1576:5:1576:5 | b [element] : | array_flow.rb:1577:10:1577:10 | b [element] : | +| array_flow.rb:1576:5:1576:5 | b [element] : | array_flow.rb:1578:10:1578:10 | b [element] : | +| array_flow.rb:1576:5:1576:5 | b [element] : | array_flow.rb:1578:10:1578:10 | b [element] : | +| array_flow.rb:1576:5:1576:5 | b [element] : | array_flow.rb:1579:10:1579:10 | b [element] : | +| array_flow.rb:1576:5:1576:5 | b [element] : | array_flow.rb:1579:10:1579:10 | b [element] : | +| array_flow.rb:1576:5:1576:5 | b [element] : | array_flow.rb:1580:10:1580:10 | b [element] : | +| array_flow.rb:1576:5:1576:5 | b [element] : | array_flow.rb:1580:10:1580:10 | b [element] : | | array_flow.rb:1576:9:1576:9 | a [element 1] : | array_flow.rb:1576:9:1576:28 | call to values_at [element] : | | array_flow.rb:1576:9:1576:9 | a [element 1] : | array_flow.rb:1576:9:1576:28 | call to values_at [element] : | | array_flow.rb:1576:9:1576:9 | a [element 3] : | array_flow.rb:1576:9:1576:28 | call to values_at [element 1] : | | array_flow.rb:1576:9:1576:9 | a [element 3] : | array_flow.rb:1576:9:1576:28 | call to values_at [element 1] : | | array_flow.rb:1576:9:1576:9 | a [element 3] : | array_flow.rb:1576:9:1576:28 | call to values_at [element] : | | array_flow.rb:1576:9:1576:9 | a [element 3] : | array_flow.rb:1576:9:1576:28 | call to values_at [element] : | -| array_flow.rb:1576:9:1576:28 | call to values_at [element 1] : | array_flow.rb:1578:10:1578:10 | b [element 1] : | -| array_flow.rb:1576:9:1576:28 | call to values_at [element 1] : | array_flow.rb:1578:10:1578:10 | b [element 1] : | -| array_flow.rb:1576:9:1576:28 | call to values_at [element] : | array_flow.rb:1577:10:1577:10 | b [element] : | -| array_flow.rb:1576:9:1576:28 | call to values_at [element] : | array_flow.rb:1577:10:1577:10 | b [element] : | -| array_flow.rb:1576:9:1576:28 | call to values_at [element] : | array_flow.rb:1578:10:1578:10 | b [element] : | -| array_flow.rb:1576:9:1576:28 | call to values_at [element] : | array_flow.rb:1578:10:1578:10 | b [element] : | -| array_flow.rb:1576:9:1576:28 | call to values_at [element] : | array_flow.rb:1579:10:1579:10 | b [element] : | -| array_flow.rb:1576:9:1576:28 | call to values_at [element] : | array_flow.rb:1579:10:1579:10 | b [element] : | -| array_flow.rb:1576:9:1576:28 | call to values_at [element] : | array_flow.rb:1580:10:1580:10 | b [element] : | -| array_flow.rb:1576:9:1576:28 | call to values_at [element] : | array_flow.rb:1580:10:1580:10 | b [element] : | +| array_flow.rb:1576:9:1576:28 | call to values_at [element 1] : | array_flow.rb:1576:5:1576:5 | b [element 1] : | +| array_flow.rb:1576:9:1576:28 | call to values_at [element 1] : | array_flow.rb:1576:5:1576:5 | b [element 1] : | +| array_flow.rb:1576:9:1576:28 | call to values_at [element] : | array_flow.rb:1576:5:1576:5 | b [element] : | +| array_flow.rb:1576:9:1576:28 | call to values_at [element] : | array_flow.rb:1576:5:1576:5 | b [element] : | | array_flow.rb:1577:10:1577:10 | b [element] : | array_flow.rb:1577:10:1577:13 | ...[...] | | array_flow.rb:1577:10:1577:10 | b [element] : | array_flow.rb:1577:10:1577:13 | ...[...] | | array_flow.rb:1578:10:1578:10 | b [element 1] : | array_flow.rb:1578:10:1578:13 | ...[...] | @@ -3287,26 +4078,38 @@ edges | array_flow.rb:1579:10:1579:10 | b [element] : | array_flow.rb:1579:10:1579:13 | ...[...] | | array_flow.rb:1580:10:1580:10 | b [element] : | array_flow.rb:1580:10:1580:13 | ...[...] | | array_flow.rb:1580:10:1580:10 | b [element] : | array_flow.rb:1580:10:1580:13 | ...[...] | -| array_flow.rb:1584:16:1584:28 | call to source : | array_flow.rb:1587:9:1587:9 | a [element 2] : | -| array_flow.rb:1584:16:1584:28 | call to source : | array_flow.rb:1587:9:1587:9 | a [element 2] : | -| array_flow.rb:1584:16:1584:28 | call to source : | array_flow.rb:1592:5:1592:5 | a [element 2] : | -| array_flow.rb:1584:16:1584:28 | call to source : | array_flow.rb:1592:5:1592:5 | a [element 2] : | -| array_flow.rb:1585:13:1585:25 | call to source : | array_flow.rb:1587:15:1587:15 | b [element 1] : | -| array_flow.rb:1585:13:1585:25 | call to source : | array_flow.rb:1587:15:1587:15 | b [element 1] : | -| array_flow.rb:1585:13:1585:25 | call to source : | array_flow.rb:1592:11:1592:11 | b [element 1] : | -| array_flow.rb:1585:13:1585:25 | call to source : | array_flow.rb:1592:11:1592:11 | b [element 1] : | -| array_flow.rb:1586:10:1586:22 | call to source : | array_flow.rb:1587:18:1587:18 | c [element 0] : | -| array_flow.rb:1586:10:1586:22 | call to source : | array_flow.rb:1587:18:1587:18 | c [element 0] : | -| array_flow.rb:1586:10:1586:22 | call to source : | array_flow.rb:1592:14:1592:14 | c [element 0] : | -| array_flow.rb:1586:10:1586:22 | call to source : | array_flow.rb:1592:14:1592:14 | c [element 0] : | +| array_flow.rb:1584:5:1584:5 | a [element 2] : | array_flow.rb:1587:9:1587:9 | a [element 2] : | +| array_flow.rb:1584:5:1584:5 | a [element 2] : | array_flow.rb:1587:9:1587:9 | a [element 2] : | +| array_flow.rb:1584:5:1584:5 | a [element 2] : | array_flow.rb:1592:5:1592:5 | a [element 2] : | +| array_flow.rb:1584:5:1584:5 | a [element 2] : | array_flow.rb:1592:5:1592:5 | a [element 2] : | +| array_flow.rb:1584:16:1584:28 | call to source : | array_flow.rb:1584:5:1584:5 | a [element 2] : | +| array_flow.rb:1584:16:1584:28 | call to source : | array_flow.rb:1584:5:1584:5 | a [element 2] : | +| array_flow.rb:1585:5:1585:5 | b [element 1] : | array_flow.rb:1587:15:1587:15 | b [element 1] : | +| array_flow.rb:1585:5:1585:5 | b [element 1] : | array_flow.rb:1587:15:1587:15 | b [element 1] : | +| array_flow.rb:1585:5:1585:5 | b [element 1] : | array_flow.rb:1592:11:1592:11 | b [element 1] : | +| array_flow.rb:1585:5:1585:5 | b [element 1] : | array_flow.rb:1592:11:1592:11 | b [element 1] : | +| array_flow.rb:1585:13:1585:25 | call to source : | array_flow.rb:1585:5:1585:5 | b [element 1] : | +| array_flow.rb:1585:13:1585:25 | call to source : | array_flow.rb:1585:5:1585:5 | b [element 1] : | +| array_flow.rb:1586:5:1586:5 | c [element 0] : | array_flow.rb:1587:18:1587:18 | c [element 0] : | +| array_flow.rb:1586:5:1586:5 | c [element 0] : | array_flow.rb:1587:18:1587:18 | c [element 0] : | +| array_flow.rb:1586:5:1586:5 | c [element 0] : | array_flow.rb:1592:14:1592:14 | c [element 0] : | +| array_flow.rb:1586:5:1586:5 | c [element 0] : | array_flow.rb:1592:14:1592:14 | c [element 0] : | +| array_flow.rb:1586:10:1586:22 | call to source : | array_flow.rb:1586:5:1586:5 | c [element 0] : | +| array_flow.rb:1586:10:1586:22 | call to source : | array_flow.rb:1586:5:1586:5 | c [element 0] : | +| array_flow.rb:1587:5:1587:5 | d [element 0, element 2] : | array_flow.rb:1589:10:1589:10 | d [element 0, element 2] : | +| array_flow.rb:1587:5:1587:5 | d [element 0, element 2] : | array_flow.rb:1589:10:1589:10 | d [element 0, element 2] : | +| array_flow.rb:1587:5:1587:5 | d [element 1, element 1] : | array_flow.rb:1590:10:1590:10 | d [element 1, element 1] : | +| array_flow.rb:1587:5:1587:5 | d [element 1, element 1] : | array_flow.rb:1590:10:1590:10 | d [element 1, element 1] : | +| array_flow.rb:1587:5:1587:5 | d [element 2, element 0] : | array_flow.rb:1591:10:1591:10 | d [element 2, element 0] : | +| array_flow.rb:1587:5:1587:5 | d [element 2, element 0] : | array_flow.rb:1591:10:1591:10 | d [element 2, element 0] : | | array_flow.rb:1587:9:1587:9 | a [element 2] : | array_flow.rb:1587:9:1587:19 | call to zip [element 2, element 0] : | | array_flow.rb:1587:9:1587:9 | a [element 2] : | array_flow.rb:1587:9:1587:19 | call to zip [element 2, element 0] : | -| array_flow.rb:1587:9:1587:19 | call to zip [element 0, element 2] : | array_flow.rb:1589:10:1589:10 | d [element 0, element 2] : | -| array_flow.rb:1587:9:1587:19 | call to zip [element 0, element 2] : | array_flow.rb:1589:10:1589:10 | d [element 0, element 2] : | -| array_flow.rb:1587:9:1587:19 | call to zip [element 1, element 1] : | array_flow.rb:1590:10:1590:10 | d [element 1, element 1] : | -| array_flow.rb:1587:9:1587:19 | call to zip [element 1, element 1] : | array_flow.rb:1590:10:1590:10 | d [element 1, element 1] : | -| array_flow.rb:1587:9:1587:19 | call to zip [element 2, element 0] : | array_flow.rb:1591:10:1591:10 | d [element 2, element 0] : | -| array_flow.rb:1587:9:1587:19 | call to zip [element 2, element 0] : | array_flow.rb:1591:10:1591:10 | d [element 2, element 0] : | +| array_flow.rb:1587:9:1587:19 | call to zip [element 0, element 2] : | array_flow.rb:1587:5:1587:5 | d [element 0, element 2] : | +| array_flow.rb:1587:9:1587:19 | call to zip [element 0, element 2] : | array_flow.rb:1587:5:1587:5 | d [element 0, element 2] : | +| array_flow.rb:1587:9:1587:19 | call to zip [element 1, element 1] : | array_flow.rb:1587:5:1587:5 | d [element 1, element 1] : | +| array_flow.rb:1587:9:1587:19 | call to zip [element 1, element 1] : | array_flow.rb:1587:5:1587:5 | d [element 1, element 1] : | +| array_flow.rb:1587:9:1587:19 | call to zip [element 2, element 0] : | array_flow.rb:1587:5:1587:5 | d [element 2, element 0] : | +| array_flow.rb:1587:9:1587:19 | call to zip [element 2, element 0] : | array_flow.rb:1587:5:1587:5 | d [element 2, element 0] : | | array_flow.rb:1587:15:1587:15 | b [element 1] : | array_flow.rb:1587:9:1587:19 | call to zip [element 1, element 1] : | | array_flow.rb:1587:15:1587:15 | b [element 1] : | array_flow.rb:1587:9:1587:19 | call to zip [element 1, element 1] : | | array_flow.rb:1587:18:1587:18 | c [element 0] : | array_flow.rb:1587:9:1587:19 | call to zip [element 0, element 2] : | @@ -3341,18 +4144,24 @@ edges | array_flow.rb:1594:14:1594:14 | x [element 1] : | array_flow.rb:1594:14:1594:17 | ...[...] | | array_flow.rb:1595:14:1595:14 | x [element 2] : | array_flow.rb:1595:14:1595:17 | ...[...] | | array_flow.rb:1595:14:1595:14 | x [element 2] : | array_flow.rb:1595:14:1595:17 | ...[...] | -| array_flow.rb:1600:16:1600:28 | call to source : | array_flow.rb:1602:9:1602:9 | a [element 2] : | -| array_flow.rb:1600:16:1600:28 | call to source : | array_flow.rb:1602:9:1602:9 | a [element 2] : | -| array_flow.rb:1601:13:1601:25 | call to source : | array_flow.rb:1602:13:1602:13 | b [element 1] : | -| array_flow.rb:1601:13:1601:25 | call to source : | array_flow.rb:1602:13:1602:13 | b [element 1] : | +| array_flow.rb:1600:5:1600:5 | a [element 2] : | array_flow.rb:1602:9:1602:9 | a [element 2] : | +| array_flow.rb:1600:5:1600:5 | a [element 2] : | array_flow.rb:1602:9:1602:9 | a [element 2] : | +| array_flow.rb:1600:16:1600:28 | call to source : | array_flow.rb:1600:5:1600:5 | a [element 2] : | +| array_flow.rb:1600:16:1600:28 | call to source : | array_flow.rb:1600:5:1600:5 | a [element 2] : | +| array_flow.rb:1601:5:1601:5 | b [element 1] : | array_flow.rb:1602:13:1602:13 | b [element 1] : | +| array_flow.rb:1601:5:1601:5 | b [element 1] : | array_flow.rb:1602:13:1602:13 | b [element 1] : | +| array_flow.rb:1601:13:1601:25 | call to source : | array_flow.rb:1601:5:1601:5 | b [element 1] : | +| array_flow.rb:1601:13:1601:25 | call to source : | array_flow.rb:1601:5:1601:5 | b [element 1] : | +| array_flow.rb:1602:5:1602:5 | c [element] : | array_flow.rb:1603:10:1603:10 | c [element] : | +| array_flow.rb:1602:5:1602:5 | c [element] : | array_flow.rb:1603:10:1603:10 | c [element] : | +| array_flow.rb:1602:5:1602:5 | c [element] : | array_flow.rb:1604:10:1604:10 | c [element] : | +| array_flow.rb:1602:5:1602:5 | c [element] : | array_flow.rb:1604:10:1604:10 | c [element] : | +| array_flow.rb:1602:5:1602:5 | c [element] : | array_flow.rb:1605:10:1605:10 | c [element] : | +| array_flow.rb:1602:5:1602:5 | c [element] : | array_flow.rb:1605:10:1605:10 | c [element] : | | array_flow.rb:1602:9:1602:9 | a [element 2] : | array_flow.rb:1602:9:1602:13 | ... \| ... [element] : | | array_flow.rb:1602:9:1602:9 | a [element 2] : | array_flow.rb:1602:9:1602:13 | ... \| ... [element] : | -| array_flow.rb:1602:9:1602:13 | ... \| ... [element] : | array_flow.rb:1603:10:1603:10 | c [element] : | -| array_flow.rb:1602:9:1602:13 | ... \| ... [element] : | array_flow.rb:1603:10:1603:10 | c [element] : | -| array_flow.rb:1602:9:1602:13 | ... \| ... [element] : | array_flow.rb:1604:10:1604:10 | c [element] : | -| array_flow.rb:1602:9:1602:13 | ... \| ... [element] : | array_flow.rb:1604:10:1604:10 | c [element] : | -| array_flow.rb:1602:9:1602:13 | ... \| ... [element] : | array_flow.rb:1605:10:1605:10 | c [element] : | -| array_flow.rb:1602:9:1602:13 | ... \| ... [element] : | array_flow.rb:1605:10:1605:10 | c [element] : | +| array_flow.rb:1602:9:1602:13 | ... \| ... [element] : | array_flow.rb:1602:5:1602:5 | c [element] : | +| array_flow.rb:1602:9:1602:13 | ... \| ... [element] : | array_flow.rb:1602:5:1602:5 | c [element] : | | array_flow.rb:1602:13:1602:13 | b [element 1] : | array_flow.rb:1602:9:1602:13 | ... \| ... [element] : | | array_flow.rb:1602:13:1602:13 | b [element 1] : | array_flow.rb:1602:9:1602:13 | ... \| ... [element] : | | array_flow.rb:1603:10:1603:10 | c [element] : | array_flow.rb:1603:10:1603:13 | ...[...] | @@ -3432,6 +4241,8 @@ edges | array_flow.rb:1631:10:1631:10 | a [element] : | array_flow.rb:1631:10:1631:15 | ...[...] | | array_flow.rb:1631:10:1631:10 | a [element] : | array_flow.rb:1631:10:1631:15 | ...[...] | nodes +| array_flow.rb:2:5:2:5 | a [element 0] : | semmle.label | a [element 0] : | +| array_flow.rb:2:5:2:5 | a [element 0] : | semmle.label | a [element 0] : | | array_flow.rb:2:9:2:20 | * ... [element 0] : | semmle.label | * ... [element 0] : | | array_flow.rb:2:9:2:20 | * ... [element 0] : | semmle.label | * ... [element 0] : | | array_flow.rb:2:10:2:20 | call to source : | semmle.label | call to source : | @@ -3444,6 +4255,8 @@ nodes | array_flow.rb:5:10:5:10 | a [element 0] : | semmle.label | a [element 0] : | | array_flow.rb:5:10:5:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:5:10:5:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:9:5:9:5 | a [element 1] : | semmle.label | a [element 1] : | +| array_flow.rb:9:5:9:5 | a [element 1] : | semmle.label | a [element 1] : | | array_flow.rb:9:13:9:21 | call to source : | semmle.label | call to source : | | array_flow.rb:9:13:9:21 | call to source : | semmle.label | call to source : | | array_flow.rb:11:10:11:10 | a [element 1] : | semmle.label | a [element 1] : | @@ -3454,6 +4267,8 @@ nodes | array_flow.rb:13:10:13:10 | a [element 1] : | semmle.label | a [element 1] : | | array_flow.rb:13:10:13:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:13:10:13:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:17:5:17:5 | a [element] : | semmle.label | a [element] : | +| array_flow.rb:17:5:17:5 | a [element] : | semmle.label | a [element] : | | array_flow.rb:17:9:17:33 | call to new [element] : | semmle.label | call to new [element] : | | array_flow.rb:17:9:17:33 | call to new [element] : | semmle.label | call to new [element] : | | array_flow.rb:17:22:17:32 | call to source : | semmle.label | call to source : | @@ -3466,6 +4281,8 @@ nodes | array_flow.rb:19:10:19:10 | a [element] : | semmle.label | a [element] : | | array_flow.rb:19:10:19:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:19:10:19:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:21:5:21:5 | b [element] : | semmle.label | b [element] : | +| array_flow.rb:21:5:21:5 | b [element] : | semmle.label | b [element] : | | array_flow.rb:21:9:21:20 | call to new [element] : | semmle.label | call to new [element] : | | array_flow.rb:21:9:21:20 | call to new [element] : | semmle.label | call to new [element] : | | array_flow.rb:21:19:21:19 | a [element] : | semmle.label | a [element] : | @@ -3478,6 +4295,8 @@ nodes | array_flow.rb:23:10:23:10 | b [element] : | semmle.label | b [element] : | | array_flow.rb:23:10:23:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:23:10:23:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:25:5:25:5 | c [element] : | semmle.label | c [element] : | +| array_flow.rb:25:5:25:5 | c [element] : | semmle.label | c [element] : | | array_flow.rb:25:9:27:7 | call to new [element] : | semmle.label | call to new [element] : | | array_flow.rb:25:9:27:7 | call to new [element] : | semmle.label | call to new [element] : | | array_flow.rb:26:9:26:19 | call to source : | semmle.label | call to source : | @@ -3490,8 +4309,12 @@ nodes | array_flow.rb:29:10:29:10 | c [element] : | semmle.label | c [element] : | | array_flow.rb:29:10:29:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:29:10:29:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:33:5:33:5 | a [element 0] : | semmle.label | a [element 0] : | +| array_flow.rb:33:5:33:5 | a [element 0] : | semmle.label | a [element 0] : | | array_flow.rb:33:10:33:18 | call to source : | semmle.label | call to source : | | array_flow.rb:33:10:33:18 | call to source : | semmle.label | call to source : | +| array_flow.rb:34:5:34:5 | b [element 0] : | semmle.label | b [element 0] : | +| array_flow.rb:34:5:34:5 | b [element 0] : | semmle.label | b [element 0] : | | array_flow.rb:34:9:34:28 | call to try_convert [element 0] : | semmle.label | call to try_convert [element 0] : | | array_flow.rb:34:9:34:28 | call to try_convert [element 0] : | semmle.label | call to try_convert [element 0] : | | array_flow.rb:34:27:34:27 | a [element 0] : | semmle.label | a [element 0] : | @@ -3500,10 +4323,16 @@ nodes | array_flow.rb:35:10:35:10 | b [element 0] : | semmle.label | b [element 0] : | | array_flow.rb:35:10:35:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:35:10:35:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:40:5:40:5 | a [element 0] : | semmle.label | a [element 0] : | +| array_flow.rb:40:5:40:5 | a [element 0] : | semmle.label | a [element 0] : | | array_flow.rb:40:10:40:20 | call to source : | semmle.label | call to source : | | array_flow.rb:40:10:40:20 | call to source : | semmle.label | call to source : | +| array_flow.rb:41:5:41:5 | b [element 2] : | semmle.label | b [element 2] : | +| array_flow.rb:41:5:41:5 | b [element 2] : | semmle.label | b [element 2] : | | array_flow.rb:41:16:41:26 | call to source : | semmle.label | call to source : | | array_flow.rb:41:16:41:26 | call to source : | semmle.label | call to source : | +| array_flow.rb:42:5:42:5 | c [element] : | semmle.label | c [element] : | +| array_flow.rb:42:5:42:5 | c [element] : | semmle.label | c [element] : | | array_flow.rb:42:9:42:9 | a [element 0] : | semmle.label | a [element 0] : | | array_flow.rb:42:9:42:9 | a [element 0] : | semmle.label | a [element 0] : | | array_flow.rb:42:9:42:13 | ... & ... [element] : | semmle.label | ... & ... [element] : | @@ -3518,8 +4347,12 @@ nodes | array_flow.rb:44:10:44:10 | c [element] : | semmle.label | c [element] : | | array_flow.rb:44:10:44:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:44:10:44:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:48:5:48:5 | a [element 0] : | semmle.label | a [element 0] : | +| array_flow.rb:48:5:48:5 | a [element 0] : | semmle.label | a [element 0] : | | array_flow.rb:48:10:48:18 | call to source : | semmle.label | call to source : | | array_flow.rb:48:10:48:18 | call to source : | semmle.label | call to source : | +| array_flow.rb:49:5:49:5 | b [element] : | semmle.label | b [element] : | +| array_flow.rb:49:5:49:5 | b [element] : | semmle.label | b [element] : | | array_flow.rb:49:9:49:9 | a [element 0] : | semmle.label | a [element 0] : | | array_flow.rb:49:9:49:9 | a [element 0] : | semmle.label | a [element 0] : | | array_flow.rb:49:9:49:13 | ... * ... [element] : | semmle.label | ... * ... [element] : | @@ -3532,10 +4365,18 @@ nodes | array_flow.rb:51:10:51:10 | b [element] : | semmle.label | b [element] : | | array_flow.rb:51:10:51:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:51:10:51:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:55:5:55:5 | a [element 0] : | semmle.label | a [element 0] : | +| array_flow.rb:55:5:55:5 | a [element 0] : | semmle.label | a [element 0] : | | array_flow.rb:55:10:55:20 | call to source : | semmle.label | call to source : | | array_flow.rb:55:10:55:20 | call to source : | semmle.label | call to source : | +| array_flow.rb:56:5:56:5 | b [element 1] : | semmle.label | b [element 1] : | +| array_flow.rb:56:5:56:5 | b [element 1] : | semmle.label | b [element 1] : | | array_flow.rb:56:13:56:23 | call to source : | semmle.label | call to source : | | array_flow.rb:56:13:56:23 | call to source : | semmle.label | call to source : | +| array_flow.rb:57:5:57:5 | c [element 0] : | semmle.label | c [element 0] : | +| array_flow.rb:57:5:57:5 | c [element 0] : | semmle.label | c [element 0] : | +| array_flow.rb:57:5:57:5 | c [element] : | semmle.label | c [element] : | +| array_flow.rb:57:5:57:5 | c [element] : | semmle.label | c [element] : | | array_flow.rb:57:9:57:9 | a [element 0] : | semmle.label | a [element 0] : | | array_flow.rb:57:9:57:9 | a [element 0] : | semmle.label | a [element 0] : | | array_flow.rb:57:9:57:13 | ... + ... [element 0] : | semmle.label | ... + ... [element 0] : | @@ -3554,8 +4395,12 @@ nodes | array_flow.rb:59:10:59:10 | c [element] : | semmle.label | c [element] : | | array_flow.rb:59:10:59:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:59:10:59:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:63:5:63:5 | a [element 0] : | semmle.label | a [element 0] : | +| array_flow.rb:63:5:63:5 | a [element 0] : | semmle.label | a [element 0] : | | array_flow.rb:63:10:63:20 | call to source : | semmle.label | call to source : | | array_flow.rb:63:10:63:20 | call to source : | semmle.label | call to source : | +| array_flow.rb:65:5:65:5 | c [element] : | semmle.label | c [element] : | +| array_flow.rb:65:5:65:5 | c [element] : | semmle.label | c [element] : | | array_flow.rb:65:9:65:9 | a [element 0] : | semmle.label | a [element 0] : | | array_flow.rb:65:9:65:9 | a [element 0] : | semmle.label | a [element 0] : | | array_flow.rb:65:9:65:13 | ... - ... [element] : | semmle.label | ... - ... [element] : | @@ -3568,8 +4413,15 @@ nodes | array_flow.rb:67:10:67:10 | c [element] : | semmle.label | c [element] : | | array_flow.rb:67:10:67:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:67:10:67:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:71:5:71:5 | a [element 0] : | semmle.label | a [element 0] : | +| array_flow.rb:71:5:71:5 | a [element 0] : | semmle.label | a [element 0] : | | array_flow.rb:71:10:71:20 | call to source : | semmle.label | call to source : | | array_flow.rb:71:10:71:20 | call to source : | semmle.label | call to source : | +| array_flow.rb:72:5:72:5 | b : | semmle.label | b : | +| array_flow.rb:72:5:72:5 | b [element 0] : | semmle.label | b [element 0] : | +| array_flow.rb:72:5:72:5 | b [element 0] : | semmle.label | b [element 0] : | +| array_flow.rb:72:5:72:5 | b [element] : | semmle.label | b [element] : | +| array_flow.rb:72:5:72:5 | b [element] : | semmle.label | b [element] : | | array_flow.rb:72:9:72:9 | [post] a [element] : | semmle.label | [post] a [element] : | | array_flow.rb:72:9:72:9 | [post] a [element] : | semmle.label | [post] a [element] : | | array_flow.rb:72:9:72:9 | a [element 0] : | semmle.label | a [element 0] : | @@ -3602,14 +4454,24 @@ nodes | array_flow.rb:76:10:76:10 | b [element] : | semmle.label | b [element] : | | array_flow.rb:76:10:76:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:76:10:76:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:80:5:80:5 | a [element 1] : | semmle.label | a [element 1] : | +| array_flow.rb:80:5:80:5 | a [element 1] : | semmle.label | a [element 1] : | | array_flow.rb:80:13:80:21 | call to source : | semmle.label | call to source : | | array_flow.rb:80:13:80:21 | call to source : | semmle.label | call to source : | +| array_flow.rb:81:8:81:8 | c : | semmle.label | c : | +| array_flow.rb:81:8:81:8 | c : | semmle.label | c : | +| array_flow.rb:81:15:81:15 | __synth__0 [element 1] : | semmle.label | __synth__0 [element 1] : | +| array_flow.rb:81:15:81:15 | __synth__0 [element 1] : | semmle.label | __synth__0 [element 1] : | | array_flow.rb:81:15:81:15 | a [element 1] : | semmle.label | a [element 1] : | | array_flow.rb:81:15:81:15 | a [element 1] : | semmle.label | a [element 1] : | | array_flow.rb:83:10:83:10 | c | semmle.label | c | | array_flow.rb:83:10:83:10 | c | semmle.label | c | +| array_flow.rb:88:5:88:5 | a [element 1] : | semmle.label | a [element 1] : | +| array_flow.rb:88:5:88:5 | a [element 1] : | semmle.label | a [element 1] : | | array_flow.rb:88:13:88:22 | call to source : | semmle.label | call to source : | | array_flow.rb:88:13:88:22 | call to source : | semmle.label | call to source : | +| array_flow.rb:89:5:89:5 | b [element 1] : | semmle.label | b [element 1] : | +| array_flow.rb:89:5:89:5 | b [element 1] : | semmle.label | b [element 1] : | | array_flow.rb:89:9:89:9 | a [element 1] : | semmle.label | a [element 1] : | | array_flow.rb:89:9:89:9 | a [element 1] : | semmle.label | a [element 1] : | | array_flow.rb:89:9:89:15 | ...[...] [element 1] : | semmle.label | ...[...] [element 1] : | @@ -3622,8 +4484,12 @@ nodes | array_flow.rb:92:10:92:10 | b [element 1] : | semmle.label | b [element 1] : | | array_flow.rb:92:10:92:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:92:10:92:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:96:5:96:5 | a [element 1] : | semmle.label | a [element 1] : | +| array_flow.rb:96:5:96:5 | a [element 1] : | semmle.label | a [element 1] : | | array_flow.rb:96:13:96:22 | call to source : | semmle.label | call to source : | | array_flow.rb:96:13:96:22 | call to source : | semmle.label | call to source : | +| array_flow.rb:97:5:97:5 | b [element 1] : | semmle.label | b [element 1] : | +| array_flow.rb:97:5:97:5 | b [element 1] : | semmle.label | b [element 1] : | | array_flow.rb:97:9:97:9 | a [element 1] : | semmle.label | a [element 1] : | | array_flow.rb:97:9:97:9 | a [element 1] : | semmle.label | a [element 1] : | | array_flow.rb:97:9:97:15 | ...[...] [element 1] : | semmle.label | ...[...] [element 1] : | @@ -3636,8 +4502,12 @@ nodes | array_flow.rb:101:10:101:10 | b [element 1] : | semmle.label | b [element 1] : | | array_flow.rb:101:10:101:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:101:10:101:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:103:5:103:5 | a [element 1] : | semmle.label | a [element 1] : | +| array_flow.rb:103:5:103:5 | a [element 1] : | semmle.label | a [element 1] : | | array_flow.rb:103:13:103:24 | call to source : | semmle.label | call to source : | | array_flow.rb:103:13:103:24 | call to source : | semmle.label | call to source : | +| array_flow.rb:104:5:104:5 | b [element 1] : | semmle.label | b [element 1] : | +| array_flow.rb:104:5:104:5 | b [element 1] : | semmle.label | b [element 1] : | | array_flow.rb:104:9:104:9 | a [element 1] : | semmle.label | a [element 1] : | | array_flow.rb:104:9:104:9 | a [element 1] : | semmle.label | a [element 1] : | | array_flow.rb:104:9:104:16 | ...[...] [element 1] : | semmle.label | ...[...] [element 1] : | @@ -3646,10 +4516,16 @@ nodes | array_flow.rb:106:10:106:10 | b [element 1] : | semmle.label | b [element 1] : | | array_flow.rb:106:10:106:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:106:10:106:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:109:5:109:5 | a [element 1] : | semmle.label | a [element 1] : | +| array_flow.rb:109:5:109:5 | a [element 1] : | semmle.label | a [element 1] : | +| array_flow.rb:109:5:109:5 | a [element 3] : | semmle.label | a [element 3] : | +| array_flow.rb:109:5:109:5 | a [element 3] : | semmle.label | a [element 3] : | | array_flow.rb:109:13:109:24 | call to source : | semmle.label | call to source : | | array_flow.rb:109:13:109:24 | call to source : | semmle.label | call to source : | | array_flow.rb:109:30:109:41 | call to source : | semmle.label | call to source : | | array_flow.rb:109:30:109:41 | call to source : | semmle.label | call to source : | +| array_flow.rb:110:5:110:5 | b [element] : | semmle.label | b [element] : | +| array_flow.rb:110:5:110:5 | b [element] : | semmle.label | b [element] : | | array_flow.rb:110:9:110:9 | a [element 1] : | semmle.label | a [element 1] : | | array_flow.rb:110:9:110:9 | a [element 1] : | semmle.label | a [element 1] : | | array_flow.rb:110:9:110:9 | a [element 3] : | semmle.label | a [element 3] : | @@ -3664,6 +4540,8 @@ nodes | array_flow.rb:112:10:112:10 | b [element] : | semmle.label | b [element] : | | array_flow.rb:112:10:112:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:112:10:112:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:114:5:114:5 | b [element] : | semmle.label | b [element] : | +| array_flow.rb:114:5:114:5 | b [element] : | semmle.label | b [element] : | | array_flow.rb:114:9:114:9 | a [element 1] : | semmle.label | a [element 1] : | | array_flow.rb:114:9:114:9 | a [element 1] : | semmle.label | a [element 1] : | | array_flow.rb:114:9:114:9 | a [element 3] : | semmle.label | a [element 3] : | @@ -3742,6 +4620,8 @@ nodes | array_flow.rb:148:10:148:10 | a [element] : | semmle.label | a [element] : | | array_flow.rb:148:10:148:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:148:10:148:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:152:5:152:5 | a [element 2] : | semmle.label | a [element 2] : | +| array_flow.rb:152:5:152:5 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:152:16:152:25 | call to source : | semmle.label | call to source : | | array_flow.rb:152:16:152:25 | call to source : | semmle.label | call to source : | | array_flow.rb:153:5:153:5 | a [element 2] : | semmle.label | a [element 2] : | @@ -3750,6 +4630,8 @@ nodes | array_flow.rb:153:16:153:16 | x : | semmle.label | x : | | array_flow.rb:154:14:154:14 | x | semmle.label | x | | array_flow.rb:154:14:154:14 | x | semmle.label | x | +| array_flow.rb:159:5:159:5 | a [element 2] : | semmle.label | a [element 2] : | +| array_flow.rb:159:5:159:5 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:159:16:159:25 | call to source : | semmle.label | call to source : | | array_flow.rb:159:16:159:25 | call to source : | semmle.label | call to source : | | array_flow.rb:160:5:160:5 | a [element 2] : | semmle.label | a [element 2] : | @@ -3758,8 +4640,14 @@ nodes | array_flow.rb:160:16:160:16 | x : | semmle.label | x : | | array_flow.rb:161:14:161:14 | x | semmle.label | x | | array_flow.rb:161:14:161:14 | x | semmle.label | x | +| array_flow.rb:166:5:166:5 | a [element 0] : | semmle.label | a [element 0] : | +| array_flow.rb:166:5:166:5 | a [element 0] : | semmle.label | a [element 0] : | | array_flow.rb:166:10:166:21 | call to source : | semmle.label | call to source : | | array_flow.rb:166:10:166:21 | call to source : | semmle.label | call to source : | +| array_flow.rb:167:5:167:5 | b [element 0] : | semmle.label | b [element 0] : | +| array_flow.rb:167:5:167:5 | b [element 0] : | semmle.label | b [element 0] : | +| array_flow.rb:167:5:167:5 | b [element] : | semmle.label | b [element] : | +| array_flow.rb:167:5:167:5 | b [element] : | semmle.label | b [element] : | | array_flow.rb:167:9:167:9 | [post] a [element] : | semmle.label | [post] a [element] : | | array_flow.rb:167:9:167:9 | [post] a [element] : | semmle.label | [post] a [element] : | | array_flow.rb:167:9:167:9 | a [element 0] : | semmle.label | a [element 0] : | @@ -3792,8 +4680,12 @@ nodes | array_flow.rb:171:10:171:10 | b [element] : | semmle.label | b [element] : | | array_flow.rb:171:10:171:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:171:10:171:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:177:5:177:5 | c [element 1] : | semmle.label | c [element 1] : | +| array_flow.rb:177:5:177:5 | c [element 1] : | semmle.label | c [element 1] : | | array_flow.rb:177:15:177:24 | call to source : | semmle.label | call to source : | | array_flow.rb:177:15:177:24 | call to source : | semmle.label | call to source : | +| array_flow.rb:178:5:178:5 | d [element 2, element 1] : | semmle.label | d [element 2, element 1] : | +| array_flow.rb:178:5:178:5 | d [element 2, element 1] : | semmle.label | d [element 2, element 1] : | | array_flow.rb:178:16:178:16 | c [element 1] : | semmle.label | c [element 1] : | | array_flow.rb:178:16:178:16 | c [element 1] : | semmle.label | c [element 1] : | | array_flow.rb:179:10:179:26 | ( ... ) | semmle.label | ( ... ) | @@ -3812,6 +4704,8 @@ nodes | array_flow.rb:180:11:180:22 | call to assoc [element 1] : | semmle.label | call to assoc [element 1] : | | array_flow.rb:180:11:180:25 | ...[...] : | semmle.label | ...[...] : | | array_flow.rb:180:11:180:25 | ...[...] : | semmle.label | ...[...] : | +| array_flow.rb:184:5:184:5 | a [element 1] : | semmle.label | a [element 1] : | +| array_flow.rb:184:5:184:5 | a [element 1] : | semmle.label | a [element 1] : | | array_flow.rb:184:13:184:22 | call to source : | semmle.label | call to source : | | array_flow.rb:184:13:184:22 | call to source : | semmle.label | call to source : | | array_flow.rb:186:10:186:10 | a [element 1] : | semmle.label | a [element 1] : | @@ -3822,8 +4716,12 @@ nodes | array_flow.rb:188:10:188:10 | a [element 1] : | semmle.label | a [element 1] : | | array_flow.rb:188:10:188:16 | call to at | semmle.label | call to at | | array_flow.rb:188:10:188:16 | call to at | semmle.label | call to at | +| array_flow.rb:192:5:192:5 | a [element 2] : | semmle.label | a [element 2] : | +| array_flow.rb:192:5:192:5 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:192:16:192:25 | call to source : | semmle.label | call to source : | | array_flow.rb:192:16:192:25 | call to source : | semmle.label | call to source : | +| array_flow.rb:193:5:193:5 | b : | semmle.label | b : | +| array_flow.rb:193:5:193:5 | b : | semmle.label | b : | | array_flow.rb:193:9:193:9 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:193:9:193:9 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:193:9:195:7 | call to bsearch : | semmle.label | call to bsearch : | @@ -3834,6 +4732,8 @@ nodes | array_flow.rb:194:14:194:14 | x | semmle.label | x | | array_flow.rb:196:10:196:10 | b | semmle.label | b | | array_flow.rb:196:10:196:10 | b | semmle.label | b | +| array_flow.rb:200:5:200:5 | a [element 2] : | semmle.label | a [element 2] : | +| array_flow.rb:200:5:200:5 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:200:16:200:25 | call to source : | semmle.label | call to source : | | array_flow.rb:200:16:200:25 | call to source : | semmle.label | call to source : | | array_flow.rb:201:9:201:9 | a [element 2] : | semmle.label | a [element 2] : | @@ -3842,6 +4742,8 @@ nodes | array_flow.rb:201:29:201:29 | x : | semmle.label | x : | | array_flow.rb:202:14:202:14 | x | semmle.label | x | | array_flow.rb:202:14:202:14 | x | semmle.label | x | +| array_flow.rb:208:5:208:5 | a [element 2] : | semmle.label | a [element 2] : | +| array_flow.rb:208:5:208:5 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:208:16:208:25 | call to source : | semmle.label | call to source : | | array_flow.rb:208:16:208:25 | call to source : | semmle.label | call to source : | | array_flow.rb:209:5:209:5 | a [element 2] : | semmle.label | a [element 2] : | @@ -3850,6 +4752,10 @@ nodes | array_flow.rb:209:17:209:17 | x : | semmle.label | x : | | array_flow.rb:210:14:210:14 | x | semmle.label | x | | array_flow.rb:210:14:210:14 | x | semmle.label | x | +| array_flow.rb:215:5:215:5 | a [element 2] : | semmle.label | a [element 2] : | +| array_flow.rb:215:5:215:5 | a [element 2] : | semmle.label | a [element 2] : | +| array_flow.rb:215:5:215:5 | a [element 3] : | semmle.label | a [element 3] : | +| array_flow.rb:215:5:215:5 | a [element 3] : | semmle.label | a [element 3] : | | array_flow.rb:215:16:215:27 | call to source : | semmle.label | call to source : | | array_flow.rb:215:16:215:27 | call to source : | semmle.label | call to source : | | array_flow.rb:215:30:215:41 | call to source : | semmle.label | call to source : | @@ -3866,8 +4772,12 @@ nodes | array_flow.rb:217:14:217:14 | x | semmle.label | x | | array_flow.rb:218:14:218:14 | y | semmle.label | y | | array_flow.rb:218:14:218:14 | y | semmle.label | y | +| array_flow.rb:231:5:231:5 | a [element 2] : | semmle.label | a [element 2] : | +| array_flow.rb:231:5:231:5 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:231:16:231:27 | call to source : | semmle.label | call to source : | | array_flow.rb:231:16:231:27 | call to source : | semmle.label | call to source : | +| array_flow.rb:232:5:232:5 | b [element] : | semmle.label | b [element] : | +| array_flow.rb:232:5:232:5 | b [element] : | semmle.label | b [element] : | | array_flow.rb:232:9:232:9 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:232:9:232:9 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:232:9:235:7 | call to collect [element] : | semmle.label | call to collect [element] : | @@ -3882,8 +4792,12 @@ nodes | array_flow.rb:236:10:236:10 | b [element] : | semmle.label | b [element] : | | array_flow.rb:236:10:236:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:236:10:236:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:240:5:240:5 | a [element 2] : | semmle.label | a [element 2] : | +| array_flow.rb:240:5:240:5 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:240:16:240:27 | call to source : | semmle.label | call to source : | | array_flow.rb:240:16:240:27 | call to source : | semmle.label | call to source : | +| array_flow.rb:241:5:241:5 | b [element] : | semmle.label | b [element] : | +| array_flow.rb:241:5:241:5 | b [element] : | semmle.label | b [element] : | | array_flow.rb:241:9:241:9 | [post] a [element] : | semmle.label | [post] a [element] : | | array_flow.rb:241:9:241:9 | [post] a [element] : | semmle.label | [post] a [element] : | | array_flow.rb:241:9:241:9 | a [element 2] : | semmle.label | a [element 2] : | @@ -3904,8 +4818,12 @@ nodes | array_flow.rb:246:10:246:10 | b [element] : | semmle.label | b [element] : | | array_flow.rb:246:10:246:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:246:10:246:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:250:5:250:5 | a [element 2] : | semmle.label | a [element 2] : | +| array_flow.rb:250:5:250:5 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:250:16:250:27 | call to source : | semmle.label | call to source : | | array_flow.rb:250:16:250:27 | call to source : | semmle.label | call to source : | +| array_flow.rb:251:5:251:5 | b [element] : | semmle.label | b [element] : | +| array_flow.rb:251:5:251:5 | b [element] : | semmle.label | b [element] : | | array_flow.rb:251:9:251:9 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:251:9:251:9 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:251:9:254:7 | call to collect_concat [element] : | semmle.label | call to collect_concat [element] : | @@ -3920,6 +4838,8 @@ nodes | array_flow.rb:255:10:255:10 | b [element] : | semmle.label | b [element] : | | array_flow.rb:255:10:255:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:255:10:255:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:256:5:256:5 | b [element] : | semmle.label | b [element] : | +| array_flow.rb:256:5:256:5 | b [element] : | semmle.label | b [element] : | | array_flow.rb:256:9:256:9 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:256:9:256:9 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:256:9:259:7 | call to collect_concat [element] : | semmle.label | call to collect_concat [element] : | @@ -3934,8 +4854,12 @@ nodes | array_flow.rb:260:10:260:10 | b [element] : | semmle.label | b [element] : | | array_flow.rb:260:10:260:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:260:10:260:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:264:5:264:5 | a [element 2] : | semmle.label | a [element 2] : | +| array_flow.rb:264:5:264:5 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:264:16:264:25 | call to source : | semmle.label | call to source : | | array_flow.rb:264:16:264:25 | call to source : | semmle.label | call to source : | +| array_flow.rb:265:5:265:5 | b [element 2] : | semmle.label | b [element 2] : | +| array_flow.rb:265:5:265:5 | b [element 2] : | semmle.label | b [element 2] : | | array_flow.rb:265:9:265:9 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:265:9:265:9 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:265:9:267:7 | call to combination [element 2] : | semmle.label | call to combination [element 2] : | @@ -3950,8 +4874,12 @@ nodes | array_flow.rb:269:10:269:10 | b [element 2] : | semmle.label | b [element 2] : | | array_flow.rb:269:10:269:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:269:10:269:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:273:5:273:5 | a [element 2] : | semmle.label | a [element 2] : | +| array_flow.rb:273:5:273:5 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:273:16:273:25 | call to source : | semmle.label | call to source : | | array_flow.rb:273:16:273:25 | call to source : | semmle.label | call to source : | +| array_flow.rb:274:5:274:5 | b [element] : | semmle.label | b [element] : | +| array_flow.rb:274:5:274:5 | b [element] : | semmle.label | b [element] : | | array_flow.rb:274:9:274:9 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:274:9:274:9 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:274:9:274:17 | call to compact [element] : | semmle.label | call to compact [element] : | @@ -3960,8 +4888,12 @@ nodes | array_flow.rb:275:10:275:10 | b [element] : | semmle.label | b [element] : | | array_flow.rb:275:10:275:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:275:10:275:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:279:5:279:5 | a [element 2] : | semmle.label | a [element 2] : | +| array_flow.rb:279:5:279:5 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:279:16:279:25 | call to source : | semmle.label | call to source : | | array_flow.rb:279:16:279:25 | call to source : | semmle.label | call to source : | +| array_flow.rb:280:5:280:5 | b [element] : | semmle.label | b [element] : | +| array_flow.rb:280:5:280:5 | b [element] : | semmle.label | b [element] : | | array_flow.rb:280:9:280:9 | [post] a [element] : | semmle.label | [post] a [element] : | | array_flow.rb:280:9:280:9 | [post] a [element] : | semmle.label | [post] a [element] : | | array_flow.rb:280:9:280:9 | a [element 2] : | semmle.label | a [element 2] : | @@ -3976,8 +4908,12 @@ nodes | array_flow.rb:282:10:282:10 | b [element] : | semmle.label | b [element] : | | array_flow.rb:282:10:282:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:282:10:282:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:286:5:286:5 | a [element 2] : | semmle.label | a [element 2] : | +| array_flow.rb:286:5:286:5 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:286:16:286:27 | call to source : | semmle.label | call to source : | | array_flow.rb:286:16:286:27 | call to source : | semmle.label | call to source : | +| array_flow.rb:287:5:287:5 | b [element 2] : | semmle.label | b [element 2] : | +| array_flow.rb:287:5:287:5 | b [element 2] : | semmle.label | b [element 2] : | | array_flow.rb:287:16:287:27 | call to source : | semmle.label | call to source : | | array_flow.rb:287:16:287:27 | call to source : | semmle.label | call to source : | | array_flow.rb:288:5:288:5 | [post] a [element] : | semmle.label | [post] a [element] : | @@ -3994,6 +4930,8 @@ nodes | array_flow.rb:290:10:290:10 | a [element] : | semmle.label | a [element] : | | array_flow.rb:290:10:290:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:290:10:290:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:294:5:294:5 | a [element 2] : | semmle.label | a [element 2] : | +| array_flow.rb:294:5:294:5 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:294:16:294:25 | call to source : | semmle.label | call to source : | | array_flow.rb:294:16:294:25 | call to source : | semmle.label | call to source : | | array_flow.rb:295:5:295:5 | a [element 2] : | semmle.label | a [element 2] : | @@ -4002,6 +4940,8 @@ nodes | array_flow.rb:295:17:295:17 | x : | semmle.label | x : | | array_flow.rb:296:14:296:14 | x | semmle.label | x | | array_flow.rb:296:14:296:14 | x | semmle.label | x | +| array_flow.rb:301:5:301:5 | a [element 2] : | semmle.label | a [element 2] : | +| array_flow.rb:301:5:301:5 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:301:16:301:25 | call to source : | semmle.label | call to source : | | array_flow.rb:301:16:301:25 | call to source : | semmle.label | call to source : | | array_flow.rb:302:5:302:5 | a [element 2] : | semmle.label | a [element 2] : | @@ -4010,8 +4950,12 @@ nodes | array_flow.rb:302:20:302:20 | x : | semmle.label | x : | | array_flow.rb:303:14:303:14 | x | semmle.label | x | | array_flow.rb:303:14:303:14 | x | semmle.label | x | +| array_flow.rb:308:5:308:5 | a [element 2] : | semmle.label | a [element 2] : | +| array_flow.rb:308:5:308:5 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:308:16:308:25 | call to source : | semmle.label | call to source : | | array_flow.rb:308:16:308:25 | call to source : | semmle.label | call to source : | +| array_flow.rb:309:5:309:5 | b [element 2] : | semmle.label | b [element 2] : | +| array_flow.rb:309:5:309:5 | b [element 2] : | semmle.label | b [element 2] : | | array_flow.rb:309:9:309:9 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:309:9:309:9 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:309:9:309:21 | call to deconstruct [element 2] : | semmle.label | call to deconstruct [element 2] : | @@ -4020,8 +4964,12 @@ nodes | array_flow.rb:312:10:312:10 | b [element 2] : | semmle.label | b [element 2] : | | array_flow.rb:312:10:312:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:312:10:312:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:316:5:316:5 | a [element 2] : | semmle.label | a [element 2] : | +| array_flow.rb:316:5:316:5 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:316:16:316:27 | call to source : | semmle.label | call to source : | | array_flow.rb:316:16:316:27 | call to source : | semmle.label | call to source : | +| array_flow.rb:317:5:317:5 | b : | semmle.label | b : | +| array_flow.rb:317:5:317:5 | b : | semmle.label | b : | | array_flow.rb:317:9:317:9 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:317:9:317:9 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:317:9:317:36 | call to delete : | semmle.label | call to delete : | @@ -4030,10 +4978,16 @@ nodes | array_flow.rb:317:23:317:34 | call to source : | semmle.label | call to source : | | array_flow.rb:318:10:318:10 | b | semmle.label | b | | array_flow.rb:318:10:318:10 | b | semmle.label | b | +| array_flow.rb:325:5:325:5 | a [element 2] : | semmle.label | a [element 2] : | +| array_flow.rb:325:5:325:5 | a [element 2] : | semmle.label | a [element 2] : | +| array_flow.rb:325:5:325:5 | a [element 3] : | semmle.label | a [element 3] : | +| array_flow.rb:325:5:325:5 | a [element 3] : | semmle.label | a [element 3] : | | array_flow.rb:325:16:325:27 | call to source : | semmle.label | call to source : | | array_flow.rb:325:16:325:27 | call to source : | semmle.label | call to source : | | array_flow.rb:325:30:325:41 | call to source : | semmle.label | call to source : | | array_flow.rb:325:30:325:41 | call to source : | semmle.label | call to source : | +| array_flow.rb:326:5:326:5 | b : | semmle.label | b : | +| array_flow.rb:326:5:326:5 | b : | semmle.label | b : | | array_flow.rb:326:9:326:9 | [post] a [element 2] : | semmle.label | [post] a [element 2] : | | array_flow.rb:326:9:326:9 | [post] a [element 2] : | semmle.label | [post] a [element 2] : | | array_flow.rb:326:9:326:9 | a [element 2] : | semmle.label | a [element 2] : | @@ -4048,10 +5002,16 @@ nodes | array_flow.rb:328:10:328:10 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:328:10:328:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:328:10:328:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:330:5:330:5 | a [element 2] : | semmle.label | a [element 2] : | +| array_flow.rb:330:5:330:5 | a [element 2] : | semmle.label | a [element 2] : | +| array_flow.rb:330:5:330:5 | a [element 3] : | semmle.label | a [element 3] : | +| array_flow.rb:330:5:330:5 | a [element 3] : | semmle.label | a [element 3] : | | array_flow.rb:330:16:330:27 | call to source : | semmle.label | call to source : | | array_flow.rb:330:16:330:27 | call to source : | semmle.label | call to source : | | array_flow.rb:330:30:330:41 | call to source : | semmle.label | call to source : | | array_flow.rb:330:30:330:41 | call to source : | semmle.label | call to source : | +| array_flow.rb:331:5:331:5 | b : | semmle.label | b : | +| array_flow.rb:331:5:331:5 | b : | semmle.label | b : | | array_flow.rb:331:9:331:9 | [post] a [element] : | semmle.label | [post] a [element] : | | array_flow.rb:331:9:331:9 | [post] a [element] : | semmle.label | [post] a [element] : | | array_flow.rb:331:9:331:9 | a [element 2] : | semmle.label | a [element 2] : | @@ -4070,8 +5030,12 @@ nodes | array_flow.rb:334:10:334:10 | a [element] : | semmle.label | a [element] : | | array_flow.rb:334:10:334:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:334:10:334:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:338:5:338:5 | a [element 2] : | semmle.label | a [element 2] : | +| array_flow.rb:338:5:338:5 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:338:16:338:25 | call to source : | semmle.label | call to source : | | array_flow.rb:338:16:338:25 | call to source : | semmle.label | call to source : | +| array_flow.rb:339:5:339:5 | b [element] : | semmle.label | b [element] : | +| array_flow.rb:339:5:339:5 | b [element] : | semmle.label | b [element] : | | array_flow.rb:339:9:339:9 | [post] a [element] : | semmle.label | [post] a [element] : | | array_flow.rb:339:9:339:9 | [post] a [element] : | semmle.label | [post] a [element] : | | array_flow.rb:339:9:339:9 | a [element 2] : | semmle.label | a [element 2] : | @@ -4098,8 +5062,12 @@ nodes | array_flow.rb:345:10:345:10 | a [element] : | semmle.label | a [element] : | | array_flow.rb:345:10:345:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:345:10:345:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:349:5:349:5 | a [element 2] : | semmle.label | a [element 2] : | +| array_flow.rb:349:5:349:5 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:349:16:349:25 | call to source : | semmle.label | call to source : | | array_flow.rb:349:16:349:25 | call to source : | semmle.label | call to source : | +| array_flow.rb:350:5:350:5 | b [element] : | semmle.label | b [element] : | +| array_flow.rb:350:5:350:5 | b [element] : | semmle.label | b [element] : | | array_flow.rb:350:9:350:9 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:350:9:350:9 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:350:9:350:25 | call to difference [element] : | semmle.label | call to difference [element] : | @@ -4108,6 +5076,10 @@ nodes | array_flow.rb:351:10:351:10 | b [element] : | semmle.label | b [element] : | | array_flow.rb:351:10:351:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:351:10:351:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:355:5:355:5 | a [element 2] : | semmle.label | a [element 2] : | +| array_flow.rb:355:5:355:5 | a [element 2] : | semmle.label | a [element 2] : | +| array_flow.rb:355:5:355:5 | a [element 3, element 1] : | semmle.label | a [element 3, element 1] : | +| array_flow.rb:355:5:355:5 | a [element 3, element 1] : | semmle.label | a [element 3, element 1] : | | array_flow.rb:355:16:355:27 | call to source : | semmle.label | call to source : | | array_flow.rb:355:16:355:27 | call to source : | semmle.label | call to source : | | array_flow.rb:355:34:355:45 | call to source : | semmle.label | call to source : | @@ -4124,8 +5096,12 @@ nodes | array_flow.rb:360:10:360:10 | a [element 3, element 1] : | semmle.label | a [element 3, element 1] : | | array_flow.rb:360:10:360:19 | call to dig | semmle.label | call to dig | | array_flow.rb:360:10:360:19 | call to dig | semmle.label | call to dig | +| array_flow.rb:364:5:364:5 | a [element 2] : | semmle.label | a [element 2] : | +| array_flow.rb:364:5:364:5 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:364:16:364:27 | call to source : | semmle.label | call to source : | | array_flow.rb:364:16:364:27 | call to source : | semmle.label | call to source : | +| array_flow.rb:365:5:365:5 | b : | semmle.label | b : | +| array_flow.rb:365:5:365:5 | b : | semmle.label | b : | | array_flow.rb:365:9:365:9 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:365:9:365:9 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:365:9:367:7 | call to detect : | semmle.label | call to detect : | @@ -4138,10 +5114,16 @@ nodes | array_flow.rb:366:14:366:14 | x | semmle.label | x | | array_flow.rb:368:10:368:10 | b | semmle.label | b | | array_flow.rb:368:10:368:10 | b | semmle.label | b | +| array_flow.rb:372:5:372:5 | a [element 2] : | semmle.label | a [element 2] : | +| array_flow.rb:372:5:372:5 | a [element 2] : | semmle.label | a [element 2] : | +| array_flow.rb:372:5:372:5 | a [element 3] : | semmle.label | a [element 3] : | +| array_flow.rb:372:5:372:5 | a [element 3] : | semmle.label | a [element 3] : | | array_flow.rb:372:16:372:27 | call to source : | semmle.label | call to source : | | array_flow.rb:372:16:372:27 | call to source : | semmle.label | call to source : | | array_flow.rb:372:30:372:41 | call to source : | semmle.label | call to source : | | array_flow.rb:372:30:372:41 | call to source : | semmle.label | call to source : | +| array_flow.rb:373:5:373:5 | b [element] : | semmle.label | b [element] : | +| array_flow.rb:373:5:373:5 | b [element] : | semmle.label | b [element] : | | array_flow.rb:373:9:373:9 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:373:9:373:9 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:373:9:373:9 | a [element 3] : | semmle.label | a [element 3] : | @@ -4152,6 +5134,10 @@ nodes | array_flow.rb:374:10:374:10 | b [element] : | semmle.label | b [element] : | | array_flow.rb:374:10:374:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:374:10:374:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:375:5:375:5 | b [element 1] : | semmle.label | b [element 1] : | +| array_flow.rb:375:5:375:5 | b [element 1] : | semmle.label | b [element 1] : | +| array_flow.rb:375:5:375:5 | b [element 2] : | semmle.label | b [element 2] : | +| array_flow.rb:375:5:375:5 | b [element 2] : | semmle.label | b [element 2] : | | array_flow.rb:375:9:375:9 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:375:9:375:9 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:375:9:375:9 | a [element 3] : | semmle.label | a [element 3] : | @@ -4174,6 +5160,10 @@ nodes | array_flow.rb:379:5:379:5 | [post] a [element] : | semmle.label | [post] a [element] : | | array_flow.rb:379:12:379:23 | call to source : | semmle.label | call to source : | | array_flow.rb:379:12:379:23 | call to source : | semmle.label | call to source : | +| array_flow.rb:380:5:380:5 | b [element 1] : | semmle.label | b [element 1] : | +| array_flow.rb:380:5:380:5 | b [element 1] : | semmle.label | b [element 1] : | +| array_flow.rb:380:5:380:5 | b [element] : | semmle.label | b [element] : | +| array_flow.rb:380:5:380:5 | b [element] : | semmle.label | b [element] : | | array_flow.rb:380:9:380:9 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:380:9:380:9 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:380:9:380:9 | a [element] : | semmle.label | a [element] : | @@ -4188,6 +5178,8 @@ nodes | array_flow.rb:381:10:381:10 | b [element] : | semmle.label | b [element] : | | array_flow.rb:381:10:381:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:381:10:381:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:382:5:382:5 | c [element] : | semmle.label | c [element] : | +| array_flow.rb:382:5:382:5 | c [element] : | semmle.label | c [element] : | | array_flow.rb:382:9:382:9 | b [element] : | semmle.label | b [element] : | | array_flow.rb:382:9:382:9 | b [element] : | semmle.label | b [element] : | | array_flow.rb:382:9:382:19 | call to drop [element] : | semmle.label | call to drop [element] : | @@ -4196,10 +5188,16 @@ nodes | array_flow.rb:383:10:383:10 | c [element] : | semmle.label | c [element] : | | array_flow.rb:383:10:383:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:383:10:383:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:387:5:387:5 | a [element 2] : | semmle.label | a [element 2] : | +| array_flow.rb:387:5:387:5 | a [element 2] : | semmle.label | a [element 2] : | +| array_flow.rb:387:5:387:5 | a [element 3] : | semmle.label | a [element 3] : | +| array_flow.rb:387:5:387:5 | a [element 3] : | semmle.label | a [element 3] : | | array_flow.rb:387:16:387:27 | call to source : | semmle.label | call to source : | | array_flow.rb:387:16:387:27 | call to source : | semmle.label | call to source : | | array_flow.rb:387:30:387:41 | call to source : | semmle.label | call to source : | | array_flow.rb:387:30:387:41 | call to source : | semmle.label | call to source : | +| array_flow.rb:388:5:388:5 | b [element] : | semmle.label | b [element] : | +| array_flow.rb:388:5:388:5 | b [element] : | semmle.label | b [element] : | | array_flow.rb:388:9:388:9 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:388:9:388:9 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:388:9:388:9 | a [element 3] : | semmle.label | a [element 3] : | @@ -4214,8 +5212,12 @@ nodes | array_flow.rb:391:10:391:10 | b [element] : | semmle.label | b [element] : | | array_flow.rb:391:10:391:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:391:10:391:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:395:5:395:5 | a [element 2] : | semmle.label | a [element 2] : | +| array_flow.rb:395:5:395:5 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:395:16:395:25 | call to source : | semmle.label | call to source : | | array_flow.rb:395:16:395:25 | call to source : | semmle.label | call to source : | +| array_flow.rb:396:5:396:5 | b [element 2] : | semmle.label | b [element 2] : | +| array_flow.rb:396:5:396:5 | b [element 2] : | semmle.label | b [element 2] : | | array_flow.rb:396:9:396:9 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:396:9:396:9 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:396:9:398:7 | call to each [element 2] : | semmle.label | call to each [element 2] : | @@ -4228,12 +5230,16 @@ nodes | array_flow.rb:399:10:399:10 | b [element 2] : | semmle.label | b [element 2] : | | array_flow.rb:399:10:399:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:399:10:399:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:403:5:403:5 | a [element 2] : | semmle.label | a [element 2] : | +| array_flow.rb:403:5:403:5 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:403:16:403:25 | call to source : | semmle.label | call to source : | | array_flow.rb:403:16:403:25 | call to source : | semmle.label | call to source : | -| array_flow.rb:404:9:406:7 | ... = ... : | semmle.label | ... = ... : | -| array_flow.rb:404:9:406:7 | ... = ... : | semmle.label | ... = ... : | +| array_flow.rb:404:5:404:5 | b [element 2] : | semmle.label | b [element 2] : | +| array_flow.rb:404:5:404:5 | b [element 2] : | semmle.label | b [element 2] : | | array_flow.rb:404:9:406:7 | __synth__0__1 : | semmle.label | __synth__0__1 : | | array_flow.rb:404:9:406:7 | __synth__0__1 : | semmle.label | __synth__0__1 : | +| array_flow.rb:404:13:404:13 | x : | semmle.label | x : | +| array_flow.rb:404:13:404:13 | x : | semmle.label | x : | | array_flow.rb:404:18:404:18 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:404:18:404:18 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:405:14:405:14 | x | semmle.label | x | @@ -4244,6 +5250,8 @@ nodes | array_flow.rb:408:10:408:10 | b [element 2] : | semmle.label | b [element 2] : | | array_flow.rb:408:10:408:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:408:10:408:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:412:5:412:5 | a [element 2] : | semmle.label | a [element 2] : | +| array_flow.rb:412:5:412:5 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:412:16:412:25 | call to source : | semmle.label | call to source : | | array_flow.rb:412:16:412:25 | call to source : | semmle.label | call to source : | | array_flow.rb:413:5:413:5 | a [element 2] : | semmle.label | a [element 2] : | @@ -4256,8 +5264,12 @@ nodes | array_flow.rb:414:15:414:15 | x [element] : | semmle.label | x [element] : | | array_flow.rb:414:15:414:18 | ...[...] : | semmle.label | ...[...] : | | array_flow.rb:414:15:414:18 | ...[...] : | semmle.label | ...[...] : | +| array_flow.rb:419:5:419:5 | a [element 2] : | semmle.label | a [element 2] : | +| array_flow.rb:419:5:419:5 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:419:16:419:25 | call to source : | semmle.label | call to source : | | array_flow.rb:419:16:419:25 | call to source : | semmle.label | call to source : | +| array_flow.rb:420:5:420:5 | b [element 2] : | semmle.label | b [element 2] : | +| array_flow.rb:420:5:420:5 | b [element 2] : | semmle.label | b [element 2] : | | array_flow.rb:420:9:420:9 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:420:9:420:9 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:420:9:422:7 | call to each_entry [element 2] : | semmle.label | call to each_entry [element 2] : | @@ -4270,8 +5282,12 @@ nodes | array_flow.rb:423:10:423:10 | b [element 2] : | semmle.label | b [element 2] : | | array_flow.rb:423:10:423:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:423:10:423:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:427:5:427:5 | a [element 2] : | semmle.label | a [element 2] : | +| array_flow.rb:427:5:427:5 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:427:16:427:25 | call to source : | semmle.label | call to source : | | array_flow.rb:427:16:427:25 | call to source : | semmle.label | call to source : | +| array_flow.rb:428:5:428:5 | b [element 2] : | semmle.label | b [element 2] : | +| array_flow.rb:428:5:428:5 | b [element 2] : | semmle.label | b [element 2] : | | array_flow.rb:428:9:428:9 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:428:9:428:9 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:428:9:430:7 | call to each_index [element 2] : | semmle.label | call to each_index [element 2] : | @@ -4280,6 +5296,8 @@ nodes | array_flow.rb:431:10:431:10 | b [element 2] : | semmle.label | b [element 2] : | | array_flow.rb:431:10:431:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:431:10:431:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:435:5:435:5 | a [element 3] : | semmle.label | a [element 3] : | +| array_flow.rb:435:5:435:5 | a [element 3] : | semmle.label | a [element 3] : | | array_flow.rb:435:19:435:28 | call to source : | semmle.label | call to source : | | array_flow.rb:435:19:435:28 | call to source : | semmle.label | call to source : | | array_flow.rb:436:5:436:5 | a [element 3] : | semmle.label | a [element 3] : | @@ -4290,8 +5308,12 @@ nodes | array_flow.rb:437:14:437:14 | x [element] : | semmle.label | x [element] : | | array_flow.rb:437:14:437:17 | ...[...] | semmle.label | ...[...] | | array_flow.rb:437:14:437:17 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:442:5:442:5 | a [element 3] : | semmle.label | a [element 3] : | +| array_flow.rb:442:5:442:5 | a [element 3] : | semmle.label | a [element 3] : | | array_flow.rb:442:19:442:28 | call to source : | semmle.label | call to source : | | array_flow.rb:442:19:442:28 | call to source : | semmle.label | call to source : | +| array_flow.rb:443:5:443:5 | b [element 3] : | semmle.label | b [element 3] : | +| array_flow.rb:443:5:443:5 | b [element 3] : | semmle.label | b [element 3] : | | array_flow.rb:443:9:443:9 | a [element 3] : | semmle.label | a [element 3] : | | array_flow.rb:443:9:443:9 | a [element 3] : | semmle.label | a [element 3] : | | array_flow.rb:443:9:446:7 | call to each_with_index [element 3] : | semmle.label | call to each_with_index [element 3] : | @@ -4304,8 +5326,12 @@ nodes | array_flow.rb:447:10:447:10 | b [element 3] : | semmle.label | b [element 3] : | | array_flow.rb:447:10:447:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:447:10:447:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:451:5:451:5 | a [element 3] : | semmle.label | a [element 3] : | +| array_flow.rb:451:5:451:5 | a [element 3] : | semmle.label | a [element 3] : | | array_flow.rb:451:19:451:30 | call to source : | semmle.label | call to source : | | array_flow.rb:451:19:451:30 | call to source : | semmle.label | call to source : | +| array_flow.rb:452:5:452:5 | b : | semmle.label | b : | +| array_flow.rb:452:5:452:5 | b : | semmle.label | b : | | array_flow.rb:452:9:452:9 | a [element 3] : | semmle.label | a [element 3] : | | array_flow.rb:452:9:452:9 | a [element 3] : | semmle.label | a [element 3] : | | array_flow.rb:452:9:455:7 | call to each_with_object : | semmle.label | call to each_with_object : | @@ -4322,8 +5348,12 @@ nodes | array_flow.rb:454:14:454:14 | a | semmle.label | a | | array_flow.rb:456:10:456:10 | b | semmle.label | b | | array_flow.rb:456:10:456:10 | b | semmle.label | b | +| array_flow.rb:460:5:460:5 | a [element 3] : | semmle.label | a [element 3] : | +| array_flow.rb:460:5:460:5 | a [element 3] : | semmle.label | a [element 3] : | | array_flow.rb:460:19:460:28 | call to source : | semmle.label | call to source : | | array_flow.rb:460:19:460:28 | call to source : | semmle.label | call to source : | +| array_flow.rb:461:5:461:5 | b [element 3] : | semmle.label | b [element 3] : | +| array_flow.rb:461:5:461:5 | b [element 3] : | semmle.label | b [element 3] : | | array_flow.rb:461:9:461:9 | a [element 3] : | semmle.label | a [element 3] : | | array_flow.rb:461:9:461:9 | a [element 3] : | semmle.label | a [element 3] : | | array_flow.rb:461:9:461:17 | call to entries [element 3] : | semmle.label | call to entries [element 3] : | @@ -4332,10 +5362,16 @@ nodes | array_flow.rb:462:10:462:10 | b [element 3] : | semmle.label | b [element 3] : | | array_flow.rb:462:10:462:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:462:10:462:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:466:5:466:5 | a [element 3] : | semmle.label | a [element 3] : | +| array_flow.rb:466:5:466:5 | a [element 3] : | semmle.label | a [element 3] : | +| array_flow.rb:466:5:466:5 | a [element 4] : | semmle.label | a [element 4] : | +| array_flow.rb:466:5:466:5 | a [element 4] : | semmle.label | a [element 4] : | | array_flow.rb:466:19:466:30 | call to source : | semmle.label | call to source : | | array_flow.rb:466:19:466:30 | call to source : | semmle.label | call to source : | | array_flow.rb:466:33:466:44 | call to source : | semmle.label | call to source : | | array_flow.rb:466:33:466:44 | call to source : | semmle.label | call to source : | +| array_flow.rb:467:5:467:5 | b : | semmle.label | b : | +| array_flow.rb:467:5:467:5 | b : | semmle.label | b : | | array_flow.rb:467:9:467:9 | a [element 3] : | semmle.label | a [element 3] : | | array_flow.rb:467:9:467:9 | a [element 3] : | semmle.label | a [element 3] : | | array_flow.rb:467:9:467:9 | a [element 4] : | semmle.label | a [element 4] : | @@ -4350,12 +5386,16 @@ nodes | array_flow.rb:468:14:468:14 | x | semmle.label | x | | array_flow.rb:470:10:470:10 | b | semmle.label | b | | array_flow.rb:470:10:470:10 | b | semmle.label | b | +| array_flow.rb:471:5:471:5 | b : | semmle.label | b : | +| array_flow.rb:471:5:471:5 | b : | semmle.label | b : | | array_flow.rb:471:9:471:9 | a [element 3] : | semmle.label | a [element 3] : | | array_flow.rb:471:9:471:9 | a [element 3] : | semmle.label | a [element 3] : | | array_flow.rb:471:9:471:18 | call to fetch : | semmle.label | call to fetch : | | array_flow.rb:471:9:471:18 | call to fetch : | semmle.label | call to fetch : | | array_flow.rb:472:10:472:10 | b | semmle.label | b | | array_flow.rb:472:10:472:10 | b | semmle.label | b | +| array_flow.rb:473:5:473:5 | b : | semmle.label | b : | +| array_flow.rb:473:5:473:5 | b : | semmle.label | b : | | array_flow.rb:473:9:473:9 | a [element 3] : | semmle.label | a [element 3] : | | array_flow.rb:473:9:473:9 | a [element 3] : | semmle.label | a [element 3] : | | array_flow.rb:473:9:473:32 | call to fetch : | semmle.label | call to fetch : | @@ -4364,12 +5404,16 @@ nodes | array_flow.rb:473:20:473:31 | call to source : | semmle.label | call to source : | | array_flow.rb:474:10:474:10 | b | semmle.label | b | | array_flow.rb:474:10:474:10 | b | semmle.label | b | +| array_flow.rb:475:5:475:5 | b : | semmle.label | b : | +| array_flow.rb:475:5:475:5 | b : | semmle.label | b : | | array_flow.rb:475:9:475:34 | call to fetch : | semmle.label | call to fetch : | | array_flow.rb:475:9:475:34 | call to fetch : | semmle.label | call to fetch : | | array_flow.rb:475:22:475:33 | call to source : | semmle.label | call to source : | | array_flow.rb:475:22:475:33 | call to source : | semmle.label | call to source : | | array_flow.rb:476:10:476:10 | b | semmle.label | b | | array_flow.rb:476:10:476:10 | b | semmle.label | b | +| array_flow.rb:477:5:477:5 | b : | semmle.label | b : | +| array_flow.rb:477:5:477:5 | b : | semmle.label | b : | | array_flow.rb:477:9:477:9 | a [element 3] : | semmle.label | a [element 3] : | | array_flow.rb:477:9:477:9 | a [element 3] : | semmle.label | a [element 3] : | | array_flow.rb:477:9:477:9 | a [element 4] : | semmle.label | a [element 4] : | @@ -4380,6 +5424,8 @@ nodes | array_flow.rb:477:20:477:31 | call to source : | semmle.label | call to source : | | array_flow.rb:478:10:478:10 | b | semmle.label | b | | array_flow.rb:478:10:478:10 | b | semmle.label | b | +| array_flow.rb:482:5:482:5 | a [element 3] : | semmle.label | a [element 3] : | +| array_flow.rb:482:5:482:5 | a [element 3] : | semmle.label | a [element 3] : | | array_flow.rb:482:19:482:30 | call to source : | semmle.label | call to source : | | array_flow.rb:482:19:482:30 | call to source : | semmle.label | call to source : | | array_flow.rb:483:5:483:5 | [post] a [element] : | semmle.label | [post] a [element] : | @@ -4416,8 +5462,12 @@ nodes | array_flow.rb:494:10:494:10 | a [element] : | semmle.label | a [element] : | | array_flow.rb:494:10:494:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:494:10:494:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:498:5:498:5 | a [element 3] : | semmle.label | a [element 3] : | +| array_flow.rb:498:5:498:5 | a [element 3] : | semmle.label | a [element 3] : | | array_flow.rb:498:19:498:28 | call to source : | semmle.label | call to source : | | array_flow.rb:498:19:498:28 | call to source : | semmle.label | call to source : | +| array_flow.rb:499:5:499:5 | b [element] : | semmle.label | b [element] : | +| array_flow.rb:499:5:499:5 | b [element] : | semmle.label | b [element] : | | array_flow.rb:499:9:499:9 | a [element 3] : | semmle.label | a [element 3] : | | array_flow.rb:499:9:499:9 | a [element 3] : | semmle.label | a [element 3] : | | array_flow.rb:499:9:501:7 | call to filter [element] : | semmle.label | call to filter [element] : | @@ -4430,8 +5480,12 @@ nodes | array_flow.rb:502:10:502:10 | b [element] : | semmle.label | b [element] : | | array_flow.rb:502:10:502:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:502:10:502:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:506:5:506:5 | a [element 3] : | semmle.label | a [element 3] : | +| array_flow.rb:506:5:506:5 | a [element 3] : | semmle.label | a [element 3] : | | array_flow.rb:506:19:506:28 | call to source : | semmle.label | call to source : | | array_flow.rb:506:19:506:28 | call to source : | semmle.label | call to source : | +| array_flow.rb:507:5:507:5 | b [element] : | semmle.label | b [element] : | +| array_flow.rb:507:5:507:5 | b [element] : | semmle.label | b [element] : | | array_flow.rb:507:9:507:9 | a [element 3] : | semmle.label | a [element 3] : | | array_flow.rb:507:9:507:9 | a [element 3] : | semmle.label | a [element 3] : | | array_flow.rb:507:9:509:7 | call to filter_map [element] : | semmle.label | call to filter_map [element] : | @@ -4444,8 +5498,12 @@ nodes | array_flow.rb:510:10:510:10 | b [element] : | semmle.label | b [element] : | | array_flow.rb:510:10:510:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:510:10:510:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:514:5:514:5 | a [element 3] : | semmle.label | a [element 3] : | +| array_flow.rb:514:5:514:5 | a [element 3] : | semmle.label | a [element 3] : | | array_flow.rb:514:19:514:28 | call to source : | semmle.label | call to source : | | array_flow.rb:514:19:514:28 | call to source : | semmle.label | call to source : | +| array_flow.rb:515:5:515:5 | b [element] : | semmle.label | b [element] : | +| array_flow.rb:515:5:515:5 | b [element] : | semmle.label | b [element] : | | array_flow.rb:515:9:515:9 | [post] a [element] : | semmle.label | [post] a [element] : | | array_flow.rb:515:9:515:9 | [post] a [element] : | semmle.label | [post] a [element] : | | array_flow.rb:515:9:515:9 | a [element 3] : | semmle.label | a [element 3] : | @@ -4464,8 +5522,12 @@ nodes | array_flow.rb:520:10:520:10 | b [element] : | semmle.label | b [element] : | | array_flow.rb:520:10:520:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:520:10:520:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:524:5:524:5 | a [element 3] : | semmle.label | a [element 3] : | +| array_flow.rb:524:5:524:5 | a [element 3] : | semmle.label | a [element 3] : | | array_flow.rb:524:19:524:30 | call to source : | semmle.label | call to source : | | array_flow.rb:524:19:524:30 | call to source : | semmle.label | call to source : | +| array_flow.rb:525:5:525:5 | b : | semmle.label | b : | +| array_flow.rb:525:5:525:5 | b : | semmle.label | b : | | array_flow.rb:525:9:525:9 | a [element 3] : | semmle.label | a [element 3] : | | array_flow.rb:525:9:525:9 | a [element 3] : | semmle.label | a [element 3] : | | array_flow.rb:525:9:527:7 | call to find : | semmle.label | call to find : | @@ -4478,8 +5540,12 @@ nodes | array_flow.rb:526:14:526:14 | x | semmle.label | x | | array_flow.rb:528:10:528:10 | b | semmle.label | b | | array_flow.rb:528:10:528:10 | b | semmle.label | b | +| array_flow.rb:532:5:532:5 | a [element 3] : | semmle.label | a [element 3] : | +| array_flow.rb:532:5:532:5 | a [element 3] : | semmle.label | a [element 3] : | | array_flow.rb:532:19:532:28 | call to source : | semmle.label | call to source : | | array_flow.rb:532:19:532:28 | call to source : | semmle.label | call to source : | +| array_flow.rb:533:5:533:5 | b [element] : | semmle.label | b [element] : | +| array_flow.rb:533:5:533:5 | b [element] : | semmle.label | b [element] : | | array_flow.rb:533:9:533:9 | a [element 3] : | semmle.label | a [element 3] : | | array_flow.rb:533:9:533:9 | a [element 3] : | semmle.label | a [element 3] : | | array_flow.rb:533:9:535:7 | call to find_all [element] : | semmle.label | call to find_all [element] : | @@ -4492,6 +5558,8 @@ nodes | array_flow.rb:536:10:536:10 | b [element] : | semmle.label | b [element] : | | array_flow.rb:536:10:536:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:536:10:536:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:540:5:540:5 | a [element 3] : | semmle.label | a [element 3] : | +| array_flow.rb:540:5:540:5 | a [element 3] : | semmle.label | a [element 3] : | | array_flow.rb:540:19:540:28 | call to source : | semmle.label | call to source : | | array_flow.rb:540:19:540:28 | call to source : | semmle.label | call to source : | | array_flow.rb:541:5:541:5 | a [element 3] : | semmle.label | a [element 3] : | @@ -4500,6 +5568,10 @@ nodes | array_flow.rb:541:22:541:22 | x : | semmle.label | x : | | array_flow.rb:542:14:542:14 | x | semmle.label | x | | array_flow.rb:542:14:542:14 | x | semmle.label | x | +| array_flow.rb:547:5:547:5 | a [element 0] : | semmle.label | a [element 0] : | +| array_flow.rb:547:5:547:5 | a [element 0] : | semmle.label | a [element 0] : | +| array_flow.rb:547:5:547:5 | a [element 3] : | semmle.label | a [element 3] : | +| array_flow.rb:547:5:547:5 | a [element 3] : | semmle.label | a [element 3] : | | array_flow.rb:547:10:547:21 | call to source : | semmle.label | call to source : | | array_flow.rb:547:10:547:21 | call to source : | semmle.label | call to source : | | array_flow.rb:547:30:547:41 | call to source : | semmle.label | call to source : | @@ -4514,6 +5586,10 @@ nodes | array_flow.rb:549:10:549:10 | a [element] : | semmle.label | a [element] : | | array_flow.rb:549:10:549:16 | call to first | semmle.label | call to first | | array_flow.rb:549:10:549:16 | call to first | semmle.label | call to first | +| array_flow.rb:550:5:550:5 | b [element 0] : | semmle.label | b [element 0] : | +| array_flow.rb:550:5:550:5 | b [element 0] : | semmle.label | b [element 0] : | +| array_flow.rb:550:5:550:5 | b [element] : | semmle.label | b [element] : | +| array_flow.rb:550:5:550:5 | b [element] : | semmle.label | b [element] : | | array_flow.rb:550:9:550:9 | a [element 0] : | semmle.label | a [element 0] : | | array_flow.rb:550:9:550:9 | a [element 0] : | semmle.label | a [element 0] : | | array_flow.rb:550:9:550:9 | a [element] : | semmle.label | a [element] : | @@ -4532,6 +5608,12 @@ nodes | array_flow.rb:552:10:552:10 | b [element] : | semmle.label | b [element] : | | array_flow.rb:552:10:552:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:552:10:552:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:553:5:553:5 | c [element 0] : | semmle.label | c [element 0] : | +| array_flow.rb:553:5:553:5 | c [element 0] : | semmle.label | c [element 0] : | +| array_flow.rb:553:5:553:5 | c [element 3] : | semmle.label | c [element 3] : | +| array_flow.rb:553:5:553:5 | c [element 3] : | semmle.label | c [element 3] : | +| array_flow.rb:553:5:553:5 | c [element] : | semmle.label | c [element] : | +| array_flow.rb:553:5:553:5 | c [element] : | semmle.label | c [element] : | | array_flow.rb:553:9:553:9 | a [element 0] : | semmle.label | a [element 0] : | | array_flow.rb:553:9:553:9 | a [element 0] : | semmle.label | a [element 0] : | | array_flow.rb:553:9:553:9 | a [element 3] : | semmle.label | a [element 3] : | @@ -4556,8 +5638,12 @@ nodes | array_flow.rb:555:10:555:10 | c [element] : | semmle.label | c [element] : | | array_flow.rb:555:10:555:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:555:10:555:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:559:5:559:5 | a [element 2] : | semmle.label | a [element 2] : | +| array_flow.rb:559:5:559:5 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:559:16:559:27 | call to source : | semmle.label | call to source : | | array_flow.rb:559:16:559:27 | call to source : | semmle.label | call to source : | +| array_flow.rb:560:5:560:5 | b [element] : | semmle.label | b [element] : | +| array_flow.rb:560:5:560:5 | b [element] : | semmle.label | b [element] : | | array_flow.rb:560:9:560:9 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:560:9:560:9 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:560:9:563:7 | call to flat_map [element] : | semmle.label | call to flat_map [element] : | @@ -4572,6 +5658,8 @@ nodes | array_flow.rb:564:10:564:10 | b [element] : | semmle.label | b [element] : | | array_flow.rb:564:10:564:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:564:10:564:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:565:5:565:5 | b [element] : | semmle.label | b [element] : | +| array_flow.rb:565:5:565:5 | b [element] : | semmle.label | b [element] : | | array_flow.rb:565:9:565:9 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:565:9:565:9 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:565:9:568:7 | call to flat_map [element] : | semmle.label | call to flat_map [element] : | @@ -4586,8 +5674,12 @@ nodes | array_flow.rb:569:10:569:10 | b [element] : | semmle.label | b [element] : | | array_flow.rb:569:10:569:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:569:10:569:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:573:5:573:5 | a [element 2, element 1] : | semmle.label | a [element 2, element 1] : | +| array_flow.rb:573:5:573:5 | a [element 2, element 1] : | semmle.label | a [element 2, element 1] : | | array_flow.rb:573:20:573:29 | call to source : | semmle.label | call to source : | | array_flow.rb:573:20:573:29 | call to source : | semmle.label | call to source : | +| array_flow.rb:574:5:574:5 | b [element] : | semmle.label | b [element] : | +| array_flow.rb:574:5:574:5 | b [element] : | semmle.label | b [element] : | | array_flow.rb:574:9:574:9 | a [element 2, element 1] : | semmle.label | a [element 2, element 1] : | | array_flow.rb:574:9:574:9 | a [element 2, element 1] : | semmle.label | a [element 2, element 1] : | | array_flow.rb:574:9:574:17 | call to flatten [element] : | semmle.label | call to flatten [element] : | @@ -4596,6 +5688,8 @@ nodes | array_flow.rb:575:10:575:10 | b [element] : | semmle.label | b [element] : | | array_flow.rb:575:10:575:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:575:10:575:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:579:5:579:5 | a [element 2, element 1] : | semmle.label | a [element 2, element 1] : | +| array_flow.rb:579:5:579:5 | a [element 2, element 1] : | semmle.label | a [element 2, element 1] : | | array_flow.rb:579:20:579:29 | call to source : | semmle.label | call to source : | | array_flow.rb:579:20:579:29 | call to source : | semmle.label | call to source : | | array_flow.rb:580:10:580:10 | a [element 2, element 1] : | semmle.label | a [element 2, element 1] : | @@ -4604,6 +5698,10 @@ nodes | array_flow.rb:580:10:580:13 | ...[...] [element 1] : | semmle.label | ...[...] [element 1] : | | array_flow.rb:580:10:580:16 | ...[...] | semmle.label | ...[...] | | array_flow.rb:580:10:580:16 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:581:5:581:5 | b [element, element 1] : | semmle.label | b [element, element 1] : | +| array_flow.rb:581:5:581:5 | b [element, element 1] : | semmle.label | b [element, element 1] : | +| array_flow.rb:581:5:581:5 | b [element] : | semmle.label | b [element] : | +| array_flow.rb:581:5:581:5 | b [element] : | semmle.label | b [element] : | | array_flow.rb:581:9:581:9 | [post] a [element, element 1] : | semmle.label | [post] a [element, element 1] : | | array_flow.rb:581:9:581:9 | [post] a [element, element 1] : | semmle.label | [post] a [element, element 1] : | | array_flow.rb:581:9:581:9 | [post] a [element] : | semmle.label | [post] a [element] : | @@ -4638,8 +5736,12 @@ nodes | array_flow.rb:585:10:585:13 | ...[...] [element 1] : | semmle.label | ...[...] [element 1] : | | array_flow.rb:585:10:585:16 | ...[...] | semmle.label | ...[...] | | array_flow.rb:585:10:585:16 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:589:5:589:5 | a [element 3] : | semmle.label | a [element 3] : | +| array_flow.rb:589:5:589:5 | a [element 3] : | semmle.label | a [element 3] : | | array_flow.rb:589:19:589:30 | call to source : | semmle.label | call to source : | | array_flow.rb:589:19:589:30 | call to source : | semmle.label | call to source : | +| array_flow.rb:590:5:590:5 | b [element] : | semmle.label | b [element] : | +| array_flow.rb:590:5:590:5 | b [element] : | semmle.label | b [element] : | | array_flow.rb:590:9:590:9 | a [element 3] : | semmle.label | a [element 3] : | | array_flow.rb:590:9:590:9 | a [element 3] : | semmle.label | a [element 3] : | | array_flow.rb:590:9:590:20 | call to grep [element] : | semmle.label | call to grep [element] : | @@ -4648,6 +5750,8 @@ nodes | array_flow.rb:591:10:591:10 | b [element] : | semmle.label | b [element] : | | array_flow.rb:591:10:591:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:591:10:591:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:592:5:592:5 | b [element] : | semmle.label | b [element] : | +| array_flow.rb:592:5:592:5 | b [element] : | semmle.label | b [element] : | | array_flow.rb:592:9:592:9 | a [element 3] : | semmle.label | a [element 3] : | | array_flow.rb:592:9:592:9 | a [element 3] : | semmle.label | a [element 3] : | | array_flow.rb:592:9:595:7 | call to grep [element] : | semmle.label | call to grep [element] : | @@ -4662,8 +5766,12 @@ nodes | array_flow.rb:596:10:596:10 | b [element] : | semmle.label | b [element] : | | array_flow.rb:596:10:596:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:596:10:596:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:600:5:600:5 | a [element 3] : | semmle.label | a [element 3] : | +| array_flow.rb:600:5:600:5 | a [element 3] : | semmle.label | a [element 3] : | | array_flow.rb:600:19:600:30 | call to source : | semmle.label | call to source : | | array_flow.rb:600:19:600:30 | call to source : | semmle.label | call to source : | +| array_flow.rb:601:5:601:5 | b [element] : | semmle.label | b [element] : | +| array_flow.rb:601:5:601:5 | b [element] : | semmle.label | b [element] : | | array_flow.rb:601:9:601:9 | a [element 3] : | semmle.label | a [element 3] : | | array_flow.rb:601:9:601:9 | a [element 3] : | semmle.label | a [element 3] : | | array_flow.rb:601:9:601:21 | call to grep_v [element] : | semmle.label | call to grep_v [element] : | @@ -4672,6 +5780,8 @@ nodes | array_flow.rb:602:10:602:10 | b [element] : | semmle.label | b [element] : | | array_flow.rb:602:10:602:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:602:10:602:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:603:5:603:5 | b [element] : | semmle.label | b [element] : | +| array_flow.rb:603:5:603:5 | b [element] : | semmle.label | b [element] : | | array_flow.rb:603:9:603:9 | a [element 3] : | semmle.label | a [element 3] : | | array_flow.rb:603:9:603:9 | a [element 3] : | semmle.label | a [element 3] : | | array_flow.rb:603:9:606:7 | call to grep_v [element] : | semmle.label | call to grep_v [element] : | @@ -4686,6 +5796,8 @@ nodes | array_flow.rb:607:10:607:10 | b [element] : | semmle.label | b [element] : | | array_flow.rb:607:10:607:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:607:10:607:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:611:5:611:5 | a [element 3] : | semmle.label | a [element 3] : | +| array_flow.rb:611:5:611:5 | a [element 3] : | semmle.label | a [element 3] : | | array_flow.rb:611:19:611:30 | call to source : | semmle.label | call to source : | | array_flow.rb:611:19:611:30 | call to source : | semmle.label | call to source : | | array_flow.rb:612:9:612:9 | a [element 3] : | semmle.label | a [element 3] : | @@ -4694,6 +5806,8 @@ nodes | array_flow.rb:612:24:612:24 | x : | semmle.label | x : | | array_flow.rb:613:14:613:14 | x | semmle.label | x | | array_flow.rb:613:14:613:14 | x | semmle.label | x | +| array_flow.rb:620:5:620:5 | a [element 3] : | semmle.label | a [element 3] : | +| array_flow.rb:620:5:620:5 | a [element 3] : | semmle.label | a [element 3] : | | array_flow.rb:620:19:620:28 | call to source : | semmle.label | call to source : | | array_flow.rb:620:19:620:28 | call to source : | semmle.label | call to source : | | array_flow.rb:621:5:621:5 | a [element 3] : | semmle.label | a [element 3] : | @@ -4702,10 +5816,16 @@ nodes | array_flow.rb:621:17:621:17 | x : | semmle.label | x : | | array_flow.rb:622:14:622:14 | x | semmle.label | x | | array_flow.rb:622:14:622:14 | x | semmle.label | x | +| array_flow.rb:627:5:627:5 | a [element 0] : | semmle.label | a [element 0] : | +| array_flow.rb:627:5:627:5 | a [element 0] : | semmle.label | a [element 0] : | +| array_flow.rb:627:5:627:5 | a [element 2] : | semmle.label | a [element 2] : | +| array_flow.rb:627:5:627:5 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:627:10:627:21 | call to source : | semmle.label | call to source : | | array_flow.rb:627:10:627:21 | call to source : | semmle.label | call to source : | | array_flow.rb:627:27:627:38 | call to source : | semmle.label | call to source : | | array_flow.rb:627:27:627:38 | call to source : | semmle.label | call to source : | +| array_flow.rb:628:5:628:5 | b : | semmle.label | b : | +| array_flow.rb:628:5:628:5 | b : | semmle.label | b : | | array_flow.rb:628:9:628:9 | a [element 0] : | semmle.label | a [element 0] : | | array_flow.rb:628:9:628:9 | a [element 0] : | semmle.label | a [element 0] : | | array_flow.rb:628:9:628:9 | a [element 2] : | semmle.label | a [element 2] : | @@ -4724,6 +5844,8 @@ nodes | array_flow.rb:631:9:631:19 | call to source : | semmle.label | call to source : | | array_flow.rb:633:10:633:10 | b | semmle.label | b | | array_flow.rb:633:10:633:10 | b | semmle.label | b | +| array_flow.rb:634:5:634:5 | c : | semmle.label | c : | +| array_flow.rb:634:5:634:5 | c : | semmle.label | c : | | array_flow.rb:634:9:634:9 | a [element 0] : | semmle.label | a [element 0] : | | array_flow.rb:634:9:634:9 | a [element 0] : | semmle.label | a [element 0] : | | array_flow.rb:634:9:634:9 | a [element 2] : | semmle.label | a [element 2] : | @@ -4738,8 +5860,16 @@ nodes | array_flow.rb:637:9:637:19 | call to source : | semmle.label | call to source : | | array_flow.rb:639:10:639:10 | c | semmle.label | c | | array_flow.rb:639:10:639:10 | c | semmle.label | c | +| array_flow.rb:644:5:644:5 | a [element 2] : | semmle.label | a [element 2] : | +| array_flow.rb:644:5:644:5 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:644:16:644:27 | call to source : | semmle.label | call to source : | | array_flow.rb:644:16:644:27 | call to source : | semmle.label | call to source : | +| array_flow.rb:645:5:645:5 | b [element 1] : | semmle.label | b [element 1] : | +| array_flow.rb:645:5:645:5 | b [element 1] : | semmle.label | b [element 1] : | +| array_flow.rb:645:5:645:5 | b [element 2] : | semmle.label | b [element 2] : | +| array_flow.rb:645:5:645:5 | b [element 2] : | semmle.label | b [element 2] : | +| array_flow.rb:645:5:645:5 | b [element 4] : | semmle.label | b [element 4] : | +| array_flow.rb:645:5:645:5 | b [element 4] : | semmle.label | b [element 4] : | | array_flow.rb:645:9:645:9 | [post] a [element 1] : | semmle.label | [post] a [element 1] : | | array_flow.rb:645:9:645:9 | [post] a [element 1] : | semmle.label | [post] a [element 1] : | | array_flow.rb:645:9:645:9 | [post] a [element 2] : | semmle.label | [post] a [element 2] : | @@ -4782,8 +5912,12 @@ nodes | array_flow.rb:655:10:655:10 | b [element 4] : | semmle.label | b [element 4] : | | array_flow.rb:655:10:655:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:655:10:655:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:658:5:658:5 | c [element 2] : | semmle.label | c [element 2] : | +| array_flow.rb:658:5:658:5 | c [element 2] : | semmle.label | c [element 2] : | | array_flow.rb:658:16:658:27 | call to source : | semmle.label | call to source : | | array_flow.rb:658:16:658:27 | call to source : | semmle.label | call to source : | +| array_flow.rb:659:5:659:5 | d [element] : | semmle.label | d [element] : | +| array_flow.rb:659:5:659:5 | d [element] : | semmle.label | d [element] : | | array_flow.rb:659:9:659:9 | [post] c [element] : | semmle.label | [post] c [element] : | | array_flow.rb:659:9:659:9 | [post] c [element] : | semmle.label | [post] c [element] : | | array_flow.rb:659:9:659:9 | c [element 2] : | semmle.label | c [element 2] : | @@ -4802,8 +5936,12 @@ nodes | array_flow.rb:661:10:661:10 | d [element] : | semmle.label | d [element] : | | array_flow.rb:661:10:661:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:661:10:661:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:672:5:672:5 | a [element 2] : | semmle.label | a [element 2] : | +| array_flow.rb:672:5:672:5 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:672:16:672:27 | call to source : | semmle.label | call to source : | | array_flow.rb:672:16:672:27 | call to source : | semmle.label | call to source : | +| array_flow.rb:673:5:673:5 | b [element] : | semmle.label | b [element] : | +| array_flow.rb:673:5:673:5 | b [element] : | semmle.label | b [element] : | | array_flow.rb:673:9:673:9 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:673:9:673:9 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:673:9:673:60 | call to intersection [element] : | semmle.label | call to intersection [element] : | @@ -4816,8 +5954,12 @@ nodes | array_flow.rb:674:10:674:10 | b [element] : | semmle.label | b [element] : | | array_flow.rb:674:10:674:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:674:10:674:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:678:5:678:5 | a [element 2] : | semmle.label | a [element 2] : | +| array_flow.rb:678:5:678:5 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:678:16:678:25 | call to source : | semmle.label | call to source : | | array_flow.rb:678:16:678:25 | call to source : | semmle.label | call to source : | +| array_flow.rb:679:5:679:5 | b [element] : | semmle.label | b [element] : | +| array_flow.rb:679:5:679:5 | b [element] : | semmle.label | b [element] : | | array_flow.rb:679:9:679:9 | [post] a [element] : | semmle.label | [post] a [element] : | | array_flow.rb:679:9:679:9 | [post] a [element] : | semmle.label | [post] a [element] : | | array_flow.rb:679:9:679:9 | a [element 2] : | semmle.label | a [element 2] : | @@ -4836,6 +5978,8 @@ nodes | array_flow.rb:684:10:684:10 | b [element] : | semmle.label | b [element] : | | array_flow.rb:684:10:684:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:684:10:684:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:688:5:688:5 | a [element 2] : | semmle.label | a [element 2] : | +| array_flow.rb:688:5:688:5 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:688:16:688:27 | call to source : | semmle.label | call to source : | | array_flow.rb:688:16:688:27 | call to source : | semmle.label | call to source : | | array_flow.rb:689:5:689:5 | [post] a [element] : | semmle.label | [post] a [element] : | @@ -4848,6 +5992,8 @@ nodes | array_flow.rb:690:10:690:10 | a [element] : | semmle.label | a [element] : | | array_flow.rb:690:10:690:15 | call to last | semmle.label | call to last | | array_flow.rb:690:10:690:15 | call to last | semmle.label | call to last | +| array_flow.rb:691:5:691:5 | b [element] : | semmle.label | b [element] : | +| array_flow.rb:691:5:691:5 | b [element] : | semmle.label | b [element] : | | array_flow.rb:691:9:691:9 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:691:9:691:9 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:691:9:691:9 | a [element] : | semmle.label | a [element] : | @@ -4862,8 +6008,12 @@ nodes | array_flow.rb:693:10:693:10 | b [element] : | semmle.label | b [element] : | | array_flow.rb:693:10:693:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:693:10:693:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:697:5:697:5 | a [element 2] : | semmle.label | a [element 2] : | +| array_flow.rb:697:5:697:5 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:697:16:697:27 | call to source : | semmle.label | call to source : | | array_flow.rb:697:16:697:27 | call to source : | semmle.label | call to source : | +| array_flow.rb:698:5:698:5 | b [element] : | semmle.label | b [element] : | +| array_flow.rb:698:5:698:5 | b [element] : | semmle.label | b [element] : | | array_flow.rb:698:9:698:9 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:698:9:698:9 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:698:9:701:7 | call to map [element] : | semmle.label | call to map [element] : | @@ -4878,8 +6028,12 @@ nodes | array_flow.rb:702:10:702:10 | b [element] : | semmle.label | b [element] : | | array_flow.rb:702:10:702:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:702:10:702:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:706:5:706:5 | a [element 2] : | semmle.label | a [element 2] : | +| array_flow.rb:706:5:706:5 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:706:16:706:27 | call to source : | semmle.label | call to source : | | array_flow.rb:706:16:706:27 | call to source : | semmle.label | call to source : | +| array_flow.rb:707:5:707:5 | b [element] : | semmle.label | b [element] : | +| array_flow.rb:707:5:707:5 | b [element] : | semmle.label | b [element] : | | array_flow.rb:707:9:707:9 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:707:9:707:9 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:707:9:710:7 | call to map! [element] : | semmle.label | call to map! [element] : | @@ -4894,14 +6048,20 @@ nodes | array_flow.rb:711:10:711:10 | b [element] : | semmle.label | b [element] : | | array_flow.rb:711:10:711:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:711:10:711:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:715:5:715:5 | a [element 2] : | semmle.label | a [element 2] : | +| array_flow.rb:715:5:715:5 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:715:16:715:25 | call to source : | semmle.label | call to source : | | array_flow.rb:715:16:715:25 | call to source : | semmle.label | call to source : | +| array_flow.rb:718:5:718:5 | b : | semmle.label | b : | +| array_flow.rb:718:5:718:5 | b : | semmle.label | b : | | array_flow.rb:718:9:718:9 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:718:9:718:9 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:718:9:718:13 | call to max : | semmle.label | call to max : | | array_flow.rb:718:9:718:13 | call to max : | semmle.label | call to max : | | array_flow.rb:719:10:719:10 | b | semmle.label | b | | array_flow.rb:719:10:719:10 | b | semmle.label | b | +| array_flow.rb:722:5:722:5 | c [element] : | semmle.label | c [element] : | +| array_flow.rb:722:5:722:5 | c [element] : | semmle.label | c [element] : | | array_flow.rb:722:9:722:9 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:722:9:722:9 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:722:9:722:16 | call to max [element] : | semmle.label | call to max [element] : | @@ -4910,6 +6070,8 @@ nodes | array_flow.rb:723:10:723:10 | c [element] : | semmle.label | c [element] : | | array_flow.rb:723:10:723:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:723:10:723:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:726:5:726:5 | d : | semmle.label | d : | +| array_flow.rb:726:5:726:5 | d : | semmle.label | d : | | array_flow.rb:726:9:726:9 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:726:9:726:9 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:726:9:730:7 | call to max : | semmle.label | call to max : | @@ -4924,6 +6086,8 @@ nodes | array_flow.rb:728:14:728:14 | y | semmle.label | y | | array_flow.rb:731:10:731:10 | d | semmle.label | d | | array_flow.rb:731:10:731:10 | d | semmle.label | d | +| array_flow.rb:734:5:734:5 | e [element] : | semmle.label | e [element] : | +| array_flow.rb:734:5:734:5 | e [element] : | semmle.label | e [element] : | | array_flow.rb:734:9:734:9 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:734:9:734:9 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:734:9:738:7 | call to max [element] : | semmle.label | call to max [element] : | @@ -4940,8 +6104,12 @@ nodes | array_flow.rb:739:10:739:10 | e [element] : | semmle.label | e [element] : | | array_flow.rb:739:10:739:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:739:10:739:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:743:5:743:5 | a [element 2] : | semmle.label | a [element 2] : | +| array_flow.rb:743:5:743:5 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:743:16:743:25 | call to source : | semmle.label | call to source : | | array_flow.rb:743:16:743:25 | call to source : | semmle.label | call to source : | +| array_flow.rb:746:5:746:5 | b : | semmle.label | b : | +| array_flow.rb:746:5:746:5 | b : | semmle.label | b : | | array_flow.rb:746:9:746:9 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:746:9:746:9 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:746:9:749:7 | call to max_by : | semmle.label | call to max_by : | @@ -4952,6 +6120,8 @@ nodes | array_flow.rb:747:14:747:14 | x | semmle.label | x | | array_flow.rb:750:10:750:10 | b | semmle.label | b | | array_flow.rb:750:10:750:10 | b | semmle.label | b | +| array_flow.rb:753:5:753:5 | c [element] : | semmle.label | c [element] : | +| array_flow.rb:753:5:753:5 | c [element] : | semmle.label | c [element] : | | array_flow.rb:753:9:753:9 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:753:9:753:9 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:753:9:756:7 | call to max_by [element] : | semmle.label | call to max_by [element] : | @@ -4964,14 +6134,20 @@ nodes | array_flow.rb:757:10:757:10 | c [element] : | semmle.label | c [element] : | | array_flow.rb:757:10:757:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:757:10:757:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:761:5:761:5 | a [element 2] : | semmle.label | a [element 2] : | +| array_flow.rb:761:5:761:5 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:761:16:761:25 | call to source : | semmle.label | call to source : | | array_flow.rb:761:16:761:25 | call to source : | semmle.label | call to source : | +| array_flow.rb:764:5:764:5 | b : | semmle.label | b : | +| array_flow.rb:764:5:764:5 | b : | semmle.label | b : | | array_flow.rb:764:9:764:9 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:764:9:764:9 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:764:9:764:13 | call to min : | semmle.label | call to min : | | array_flow.rb:764:9:764:13 | call to min : | semmle.label | call to min : | | array_flow.rb:765:10:765:10 | b | semmle.label | b | | array_flow.rb:765:10:765:10 | b | semmle.label | b | +| array_flow.rb:768:5:768:5 | c [element] : | semmle.label | c [element] : | +| array_flow.rb:768:5:768:5 | c [element] : | semmle.label | c [element] : | | array_flow.rb:768:9:768:9 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:768:9:768:9 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:768:9:768:16 | call to min [element] : | semmle.label | call to min [element] : | @@ -4980,6 +6156,8 @@ nodes | array_flow.rb:769:10:769:10 | c [element] : | semmle.label | c [element] : | | array_flow.rb:769:10:769:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:769:10:769:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:772:5:772:5 | d : | semmle.label | d : | +| array_flow.rb:772:5:772:5 | d : | semmle.label | d : | | array_flow.rb:772:9:772:9 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:772:9:772:9 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:772:9:776:7 | call to min : | semmle.label | call to min : | @@ -4994,6 +6172,8 @@ nodes | array_flow.rb:774:14:774:14 | y | semmle.label | y | | array_flow.rb:777:10:777:10 | d | semmle.label | d | | array_flow.rb:777:10:777:10 | d | semmle.label | d | +| array_flow.rb:780:5:780:5 | e [element] : | semmle.label | e [element] : | +| array_flow.rb:780:5:780:5 | e [element] : | semmle.label | e [element] : | | array_flow.rb:780:9:780:9 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:780:9:780:9 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:780:9:784:7 | call to min [element] : | semmle.label | call to min [element] : | @@ -5010,8 +6190,12 @@ nodes | array_flow.rb:785:10:785:10 | e [element] : | semmle.label | e [element] : | | array_flow.rb:785:10:785:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:785:10:785:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:789:5:789:5 | a [element 2] : | semmle.label | a [element 2] : | +| array_flow.rb:789:5:789:5 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:789:16:789:25 | call to source : | semmle.label | call to source : | | array_flow.rb:789:16:789:25 | call to source : | semmle.label | call to source : | +| array_flow.rb:792:5:792:5 | b : | semmle.label | b : | +| array_flow.rb:792:5:792:5 | b : | semmle.label | b : | | array_flow.rb:792:9:792:9 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:792:9:792:9 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:792:9:795:7 | call to min_by : | semmle.label | call to min_by : | @@ -5022,6 +6206,8 @@ nodes | array_flow.rb:793:14:793:14 | x | semmle.label | x | | array_flow.rb:796:10:796:10 | b | semmle.label | b | | array_flow.rb:796:10:796:10 | b | semmle.label | b | +| array_flow.rb:799:5:799:5 | c [element] : | semmle.label | c [element] : | +| array_flow.rb:799:5:799:5 | c [element] : | semmle.label | c [element] : | | array_flow.rb:799:9:799:9 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:799:9:799:9 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:799:9:802:7 | call to min_by [element] : | semmle.label | call to min_by [element] : | @@ -5034,8 +6220,12 @@ nodes | array_flow.rb:803:10:803:10 | c [element] : | semmle.label | c [element] : | | array_flow.rb:803:10:803:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:803:10:803:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:807:5:807:5 | a [element 2] : | semmle.label | a [element 2] : | +| array_flow.rb:807:5:807:5 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:807:16:807:25 | call to source : | semmle.label | call to source : | | array_flow.rb:807:16:807:25 | call to source : | semmle.label | call to source : | +| array_flow.rb:809:5:809:5 | b [element] : | semmle.label | b [element] : | +| array_flow.rb:809:5:809:5 | b [element] : | semmle.label | b [element] : | | array_flow.rb:809:9:809:9 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:809:9:809:9 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:809:9:809:16 | call to minmax [element] : | semmle.label | call to minmax [element] : | @@ -5048,6 +6238,8 @@ nodes | array_flow.rb:811:10:811:10 | b [element] : | semmle.label | b [element] : | | array_flow.rb:811:10:811:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:811:10:811:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:813:5:813:5 | c [element] : | semmle.label | c [element] : | +| array_flow.rb:813:5:813:5 | c [element] : | semmle.label | c [element] : | | array_flow.rb:813:9:813:9 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:813:9:813:9 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:813:9:817:7 | call to minmax [element] : | semmle.label | call to minmax [element] : | @@ -5068,8 +6260,12 @@ nodes | array_flow.rb:819:10:819:10 | c [element] : | semmle.label | c [element] : | | array_flow.rb:819:10:819:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:819:10:819:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:823:5:823:5 | a [element 2] : | semmle.label | a [element 2] : | +| array_flow.rb:823:5:823:5 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:823:16:823:25 | call to source : | semmle.label | call to source : | | array_flow.rb:823:16:823:25 | call to source : | semmle.label | call to source : | +| array_flow.rb:824:5:824:5 | b [element] : | semmle.label | b [element] : | +| array_flow.rb:824:5:824:5 | b [element] : | semmle.label | b [element] : | | array_flow.rb:824:9:824:9 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:824:9:824:9 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:824:9:827:7 | call to minmax_by [element] : | semmle.label | call to minmax_by [element] : | @@ -5086,6 +6282,8 @@ nodes | array_flow.rb:829:10:829:10 | b [element] : | semmle.label | b [element] : | | array_flow.rb:829:10:829:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:829:10:829:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:833:5:833:5 | a [element 2] : | semmle.label | a [element 2] : | +| array_flow.rb:833:5:833:5 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:833:16:833:25 | call to source : | semmle.label | call to source : | | array_flow.rb:833:16:833:25 | call to source : | semmle.label | call to source : | | array_flow.rb:834:5:834:5 | a [element 2] : | semmle.label | a [element 2] : | @@ -5094,6 +6292,8 @@ nodes | array_flow.rb:834:17:834:17 | x : | semmle.label | x : | | array_flow.rb:835:14:835:14 | x | semmle.label | x | | array_flow.rb:835:14:835:14 | x | semmle.label | x | +| array_flow.rb:842:5:842:5 | a [element 2] : | semmle.label | a [element 2] : | +| array_flow.rb:842:5:842:5 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:842:16:842:25 | call to source : | semmle.label | call to source : | | array_flow.rb:842:16:842:25 | call to source : | semmle.label | call to source : | | array_flow.rb:843:5:843:5 | a [element 2] : | semmle.label | a [element 2] : | @@ -5102,12 +6302,18 @@ nodes | array_flow.rb:843:16:843:16 | x : | semmle.label | x : | | array_flow.rb:844:14:844:14 | x | semmle.label | x | | array_flow.rb:844:14:844:14 | x | semmle.label | x | +| array_flow.rb:849:5:849:5 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:849:16:849:25 | call to source : | semmle.label | call to source : | +| array_flow.rb:850:5:850:5 | b : | semmle.label | b : | | array_flow.rb:850:9:850:9 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:850:9:850:20 | call to pack : | semmle.label | call to pack : | | array_flow.rb:851:10:851:10 | b | semmle.label | b | +| array_flow.rb:855:5:855:5 | a [element 2] : | semmle.label | a [element 2] : | +| array_flow.rb:855:5:855:5 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:855:16:855:25 | call to source : | semmle.label | call to source : | | array_flow.rb:855:16:855:25 | call to source : | semmle.label | call to source : | +| array_flow.rb:856:5:856:5 | b [element, element] : | semmle.label | b [element, element] : | +| array_flow.rb:856:5:856:5 | b [element, element] : | semmle.label | b [element, element] : | | array_flow.rb:856:9:856:9 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:856:9:856:9 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:856:9:859:7 | call to partition [element, element] : | semmle.label | call to partition [element, element] : | @@ -5128,8 +6334,12 @@ nodes | array_flow.rb:861:10:861:13 | ...[...] [element] : | semmle.label | ...[...] [element] : | | array_flow.rb:861:10:861:16 | ...[...] | semmle.label | ...[...] | | array_flow.rb:861:10:861:16 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:865:5:865:5 | a [element 2] : | semmle.label | a [element 2] : | +| array_flow.rb:865:5:865:5 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:865:16:865:25 | call to source : | semmle.label | call to source : | | array_flow.rb:865:16:865:25 | call to source : | semmle.label | call to source : | +| array_flow.rb:867:5:867:5 | b [element 2] : | semmle.label | b [element 2] : | +| array_flow.rb:867:5:867:5 | b [element 2] : | semmle.label | b [element 2] : | | array_flow.rb:867:9:867:9 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:867:9:867:9 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:867:9:871:7 | call to permutation [element 2] : | semmle.label | call to permutation [element 2] : | @@ -5152,6 +6362,8 @@ nodes | array_flow.rb:873:10:873:10 | b [element 2] : | semmle.label | b [element 2] : | | array_flow.rb:873:10:873:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:873:10:873:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:875:5:875:5 | c [element 2] : | semmle.label | c [element 2] : | +| array_flow.rb:875:5:875:5 | c [element 2] : | semmle.label | c [element 2] : | | array_flow.rb:875:9:875:9 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:875:9:875:9 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:875:9:878:7 | call to permutation [element 2] : | semmle.label | call to permutation [element 2] : | @@ -5186,10 +6398,16 @@ nodes | array_flow.rb:887:10:887:10 | c [element 2] : | semmle.label | c [element 2] : | | array_flow.rb:887:10:887:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:887:10:887:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:894:5:894:5 | a [element 1] : | semmle.label | a [element 1] : | +| array_flow.rb:894:5:894:5 | a [element 1] : | semmle.label | a [element 1] : | +| array_flow.rb:894:5:894:5 | a [element 3] : | semmle.label | a [element 3] : | +| array_flow.rb:894:5:894:5 | a [element 3] : | semmle.label | a [element 3] : | | array_flow.rb:894:13:894:24 | call to source : | semmle.label | call to source : | | array_flow.rb:894:13:894:24 | call to source : | semmle.label | call to source : | | array_flow.rb:894:30:894:41 | call to source : | semmle.label | call to source : | | array_flow.rb:894:30:894:41 | call to source : | semmle.label | call to source : | +| array_flow.rb:895:5:895:5 | b : | semmle.label | b : | +| array_flow.rb:895:5:895:5 | b : | semmle.label | b : | | array_flow.rb:895:9:895:9 | a [element 1] : | semmle.label | a [element 1] : | | array_flow.rb:895:9:895:9 | a [element 1] : | semmle.label | a [element 1] : | | array_flow.rb:895:9:895:9 | a [element 3] : | semmle.label | a [element 3] : | @@ -5206,10 +6424,16 @@ nodes | array_flow.rb:900:10:900:10 | a [element 3] : | semmle.label | a [element 3] : | | array_flow.rb:900:10:900:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:900:10:900:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:902:5:902:5 | a [element 1] : | semmle.label | a [element 1] : | +| array_flow.rb:902:5:902:5 | a [element 1] : | semmle.label | a [element 1] : | +| array_flow.rb:902:5:902:5 | a [element 3] : | semmle.label | a [element 3] : | +| array_flow.rb:902:5:902:5 | a [element 3] : | semmle.label | a [element 3] : | | array_flow.rb:902:13:902:24 | call to source : | semmle.label | call to source : | | array_flow.rb:902:13:902:24 | call to source : | semmle.label | call to source : | | array_flow.rb:902:30:902:41 | call to source : | semmle.label | call to source : | | array_flow.rb:902:30:902:41 | call to source : | semmle.label | call to source : | +| array_flow.rb:903:5:903:5 | b [element] : | semmle.label | b [element] : | +| array_flow.rb:903:5:903:5 | b [element] : | semmle.label | b [element] : | | array_flow.rb:903:9:903:9 | a [element 1] : | semmle.label | a [element 1] : | | array_flow.rb:903:9:903:9 | a [element 1] : | semmle.label | a [element 1] : | | array_flow.rb:903:9:903:9 | a [element 3] : | semmle.label | a [element 3] : | @@ -5232,6 +6456,8 @@ nodes | array_flow.rb:909:10:909:10 | a [element 3] : | semmle.label | a [element 3] : | | array_flow.rb:909:10:909:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:909:10:909:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:913:5:913:5 | a [element 2] : | semmle.label | a [element 2] : | +| array_flow.rb:913:5:913:5 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:913:16:913:27 | call to source : | semmle.label | call to source : | | array_flow.rb:913:16:913:27 | call to source : | semmle.label | call to source : | | array_flow.rb:914:5:914:5 | [post] a [element 2] : | semmle.label | [post] a [element 2] : | @@ -5250,12 +6476,20 @@ nodes | array_flow.rb:920:10:920:10 | a [element 5] : | semmle.label | a [element 5] : | | array_flow.rb:920:10:920:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:920:10:920:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:924:5:924:5 | a [element 2] : | semmle.label | a [element 2] : | +| array_flow.rb:924:5:924:5 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:924:16:924:27 | call to source : | semmle.label | call to source : | | array_flow.rb:924:16:924:27 | call to source : | semmle.label | call to source : | +| array_flow.rb:925:5:925:5 | b [element 1] : | semmle.label | b [element 1] : | +| array_flow.rb:925:5:925:5 | b [element 1] : | semmle.label | b [element 1] : | | array_flow.rb:925:13:925:24 | call to source : | semmle.label | call to source : | | array_flow.rb:925:13:925:24 | call to source : | semmle.label | call to source : | +| array_flow.rb:926:5:926:5 | c [element 0] : | semmle.label | c [element 0] : | +| array_flow.rb:926:5:926:5 | c [element 0] : | semmle.label | c [element 0] : | | array_flow.rb:926:10:926:21 | call to source : | semmle.label | call to source : | | array_flow.rb:926:10:926:21 | call to source : | semmle.label | call to source : | +| array_flow.rb:927:5:927:5 | d [element, element] : | semmle.label | d [element, element] : | +| array_flow.rb:927:5:927:5 | d [element, element] : | semmle.label | d [element, element] : | | array_flow.rb:927:9:927:9 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:927:9:927:9 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:927:9:927:22 | call to product [element, element] : | semmle.label | call to product [element, element] : | @@ -5276,8 +6510,14 @@ nodes | array_flow.rb:929:10:929:13 | ...[...] [element] : | semmle.label | ...[...] [element] : | | array_flow.rb:929:10:929:16 | ...[...] | semmle.label | ...[...] | | array_flow.rb:929:10:929:16 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:933:5:933:5 | a [element 0] : | semmle.label | a [element 0] : | +| array_flow.rb:933:5:933:5 | a [element 0] : | semmle.label | a [element 0] : | | array_flow.rb:933:10:933:21 | call to source : | semmle.label | call to source : | | array_flow.rb:933:10:933:21 | call to source : | semmle.label | call to source : | +| array_flow.rb:934:5:934:5 | b [element 0] : | semmle.label | b [element 0] : | +| array_flow.rb:934:5:934:5 | b [element 0] : | semmle.label | b [element 0] : | +| array_flow.rb:934:5:934:5 | b [element] : | semmle.label | b [element] : | +| array_flow.rb:934:5:934:5 | b [element] : | semmle.label | b [element] : | | array_flow.rb:934:9:934:9 | [post] a [element] : | semmle.label | [post] a [element] : | | array_flow.rb:934:9:934:9 | [post] a [element] : | semmle.label | [post] a [element] : | | array_flow.rb:934:9:934:9 | a [element 0] : | semmle.label | a [element 0] : | @@ -5310,8 +6550,12 @@ nodes | array_flow.rb:938:10:938:10 | b [element] : | semmle.label | b [element] : | | array_flow.rb:938:10:938:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:938:10:938:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:944:5:944:5 | c [element 0] : | semmle.label | c [element 0] : | +| array_flow.rb:944:5:944:5 | c [element 0] : | semmle.label | c [element 0] : | | array_flow.rb:944:10:944:19 | call to source : | semmle.label | call to source : | | array_flow.rb:944:10:944:19 | call to source : | semmle.label | call to source : | +| array_flow.rb:945:5:945:5 | d [element 2, element 0] : | semmle.label | d [element 2, element 0] : | +| array_flow.rb:945:5:945:5 | d [element 2, element 0] : | semmle.label | d [element 2, element 0] : | | array_flow.rb:945:16:945:16 | c [element 0] : | semmle.label | c [element 0] : | | array_flow.rb:945:16:945:16 | c [element 0] : | semmle.label | c [element 0] : | | array_flow.rb:946:10:946:10 | d [element 2, element 0] : | semmle.label | d [element 2, element 0] : | @@ -5326,6 +6570,10 @@ nodes | array_flow.rb:947:10:947:22 | call to rassoc [element 0] : | semmle.label | call to rassoc [element 0] : | | array_flow.rb:947:10:947:25 | ...[...] | semmle.label | ...[...] | | array_flow.rb:947:10:947:25 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:951:5:951:5 | a [element 0] : | semmle.label | a [element 0] : | +| array_flow.rb:951:5:951:5 | a [element 0] : | semmle.label | a [element 0] : | +| array_flow.rb:951:5:951:5 | a [element 2] : | semmle.label | a [element 2] : | +| array_flow.rb:951:5:951:5 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:951:10:951:21 | call to source : | semmle.label | call to source : | | array_flow.rb:951:10:951:21 | call to source : | semmle.label | call to source : | | array_flow.rb:951:27:951:38 | call to source : | semmle.label | call to source : | @@ -5350,8 +6598,12 @@ nodes | array_flow.rb:957:28:957:28 | y : | semmle.label | y : | | array_flow.rb:959:14:959:14 | y | semmle.label | y | | array_flow.rb:959:14:959:14 | y | semmle.label | y | +| array_flow.rb:965:5:965:5 | a [element 2] : | semmle.label | a [element 2] : | +| array_flow.rb:965:5:965:5 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:965:16:965:25 | call to source : | semmle.label | call to source : | | array_flow.rb:965:16:965:25 | call to source : | semmle.label | call to source : | +| array_flow.rb:966:5:966:5 | b [element] : | semmle.label | b [element] : | +| array_flow.rb:966:5:966:5 | b [element] : | semmle.label | b [element] : | | array_flow.rb:966:9:966:9 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:966:9:966:9 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:966:9:969:7 | call to reject [element] : | semmle.label | call to reject [element] : | @@ -5364,8 +6616,12 @@ nodes | array_flow.rb:970:10:970:10 | b [element] : | semmle.label | b [element] : | | array_flow.rb:970:10:970:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:970:10:970:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:974:5:974:5 | a [element 2] : | semmle.label | a [element 2] : | +| array_flow.rb:974:5:974:5 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:974:16:974:25 | call to source : | semmle.label | call to source : | | array_flow.rb:974:16:974:25 | call to source : | semmle.label | call to source : | +| array_flow.rb:975:5:975:5 | b [element] : | semmle.label | b [element] : | +| array_flow.rb:975:5:975:5 | b [element] : | semmle.label | b [element] : | | array_flow.rb:975:9:975:9 | [post] a [element] : | semmle.label | [post] a [element] : | | array_flow.rb:975:9:975:9 | [post] a [element] : | semmle.label | [post] a [element] : | | array_flow.rb:975:9:975:9 | a [element 2] : | semmle.label | a [element 2] : | @@ -5384,8 +6640,12 @@ nodes | array_flow.rb:980:10:980:10 | b [element] : | semmle.label | b [element] : | | array_flow.rb:980:10:980:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:980:10:980:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:984:5:984:5 | a [element 2] : | semmle.label | a [element 2] : | +| array_flow.rb:984:5:984:5 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:984:16:984:25 | call to source : | semmle.label | call to source : | | array_flow.rb:984:16:984:25 | call to source : | semmle.label | call to source : | +| array_flow.rb:985:5:985:5 | b [element 2] : | semmle.label | b [element 2] : | +| array_flow.rb:985:5:985:5 | b [element 2] : | semmle.label | b [element 2] : | | array_flow.rb:985:9:985:9 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:985:9:985:9 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:985:9:988:7 | call to repeated_combination [element 2] : | semmle.label | call to repeated_combination [element 2] : | @@ -5404,8 +6664,12 @@ nodes | array_flow.rb:990:10:990:10 | b [element 2] : | semmle.label | b [element 2] : | | array_flow.rb:990:10:990:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:990:10:990:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:994:5:994:5 | a [element 2] : | semmle.label | a [element 2] : | +| array_flow.rb:994:5:994:5 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:994:16:994:25 | call to source : | semmle.label | call to source : | | array_flow.rb:994:16:994:25 | call to source : | semmle.label | call to source : | +| array_flow.rb:995:5:995:5 | b [element 2] : | semmle.label | b [element 2] : | +| array_flow.rb:995:5:995:5 | b [element 2] : | semmle.label | b [element 2] : | | array_flow.rb:995:9:995:9 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:995:9:995:9 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:995:9:998:7 | call to repeated_permutation [element 2] : | semmle.label | call to repeated_permutation [element 2] : | @@ -5424,6 +6688,8 @@ nodes | array_flow.rb:1000:10:1000:10 | b [element 2] : | semmle.label | b [element 2] : | | array_flow.rb:1000:10:1000:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:1000:10:1000:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1006:5:1006:5 | b [element 0] : | semmle.label | b [element 0] : | +| array_flow.rb:1006:5:1006:5 | b [element 0] : | semmle.label | b [element 0] : | | array_flow.rb:1006:9:1006:9 | [post] a [element 0] : | semmle.label | [post] a [element 0] : | | array_flow.rb:1006:9:1006:9 | [post] a [element 0] : | semmle.label | [post] a [element 0] : | | array_flow.rb:1006:9:1006:33 | call to replace [element 0] : | semmle.label | call to replace [element 0] : | @@ -5438,10 +6704,16 @@ nodes | array_flow.rb:1008:10:1008:10 | b [element 0] : | semmle.label | b [element 0] : | | array_flow.rb:1008:10:1008:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:1008:10:1008:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1012:5:1012:5 | a [element 2] : | semmle.label | a [element 2] : | +| array_flow.rb:1012:5:1012:5 | a [element 2] : | semmle.label | a [element 2] : | +| array_flow.rb:1012:5:1012:5 | a [element 3] : | semmle.label | a [element 3] : | +| array_flow.rb:1012:5:1012:5 | a [element 3] : | semmle.label | a [element 3] : | | array_flow.rb:1012:16:1012:28 | call to source : | semmle.label | call to source : | | array_flow.rb:1012:16:1012:28 | call to source : | semmle.label | call to source : | | array_flow.rb:1012:31:1012:43 | call to source : | semmle.label | call to source : | | array_flow.rb:1012:31:1012:43 | call to source : | semmle.label | call to source : | +| array_flow.rb:1013:5:1013:5 | b [element] : | semmle.label | b [element] : | +| array_flow.rb:1013:5:1013:5 | b [element] : | semmle.label | b [element] : | | array_flow.rb:1013:9:1013:9 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:1013:9:1013:9 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:1013:9:1013:9 | a [element 3] : | semmle.label | a [element 3] : | @@ -5468,10 +6740,16 @@ nodes | array_flow.rb:1019:10:1019:10 | a [element 3] : | semmle.label | a [element 3] : | | array_flow.rb:1019:10:1019:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:1019:10:1019:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1023:5:1023:5 | a [element 2] : | semmle.label | a [element 2] : | +| array_flow.rb:1023:5:1023:5 | a [element 2] : | semmle.label | a [element 2] : | +| array_flow.rb:1023:5:1023:5 | a [element 3] : | semmle.label | a [element 3] : | +| array_flow.rb:1023:5:1023:5 | a [element 3] : | semmle.label | a [element 3] : | | array_flow.rb:1023:16:1023:28 | call to source : | semmle.label | call to source : | | array_flow.rb:1023:16:1023:28 | call to source : | semmle.label | call to source : | | array_flow.rb:1023:31:1023:43 | call to source : | semmle.label | call to source : | | array_flow.rb:1023:31:1023:43 | call to source : | semmle.label | call to source : | +| array_flow.rb:1024:5:1024:5 | b [element] : | semmle.label | b [element] : | +| array_flow.rb:1024:5:1024:5 | b [element] : | semmle.label | b [element] : | | array_flow.rb:1024:9:1024:9 | [post] a [element] : | semmle.label | [post] a [element] : | | array_flow.rb:1024:9:1024:9 | [post] a [element] : | semmle.label | [post] a [element] : | | array_flow.rb:1024:9:1024:9 | a [element 2] : | semmle.label | a [element 2] : | @@ -5508,8 +6786,12 @@ nodes | array_flow.rb:1030:10:1030:10 | a [element] : | semmle.label | a [element] : | | array_flow.rb:1030:10:1030:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:1030:10:1030:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1034:5:1034:5 | a [element 2] : | semmle.label | a [element 2] : | +| array_flow.rb:1034:5:1034:5 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:1034:16:1034:26 | call to source : | semmle.label | call to source : | | array_flow.rb:1034:16:1034:26 | call to source : | semmle.label | call to source : | +| array_flow.rb:1035:5:1035:5 | b [element 2] : | semmle.label | b [element 2] : | +| array_flow.rb:1035:5:1035:5 | b [element 2] : | semmle.label | b [element 2] : | | array_flow.rb:1035:9:1035:9 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:1035:9:1035:9 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:1035:9:1037:7 | call to reverse_each [element 2] : | semmle.label | call to reverse_each [element 2] : | @@ -5522,6 +6804,8 @@ nodes | array_flow.rb:1038:10:1038:10 | b [element 2] : | semmle.label | b [element 2] : | | array_flow.rb:1038:10:1038:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:1038:10:1038:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1042:5:1042:5 | a [element 2] : | semmle.label | a [element 2] : | +| array_flow.rb:1042:5:1042:5 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:1042:16:1042:26 | call to source : | semmle.label | call to source : | | array_flow.rb:1042:16:1042:26 | call to source : | semmle.label | call to source : | | array_flow.rb:1043:5:1043:5 | a [element 2] : | semmle.label | a [element 2] : | @@ -5530,12 +6814,24 @@ nodes | array_flow.rb:1043:18:1043:18 | x : | semmle.label | x : | | array_flow.rb:1044:14:1044:14 | x | semmle.label | x | | array_flow.rb:1044:14:1044:14 | x | semmle.label | x | +| array_flow.rb:1052:5:1052:5 | a [element 0] : | semmle.label | a [element 0] : | +| array_flow.rb:1052:5:1052:5 | a [element 0] : | semmle.label | a [element 0] : | +| array_flow.rb:1052:5:1052:5 | a [element 2] : | semmle.label | a [element 2] : | +| array_flow.rb:1052:5:1052:5 | a [element 2] : | semmle.label | a [element 2] : | +| array_flow.rb:1052:5:1052:5 | a [element 3] : | semmle.label | a [element 3] : | +| array_flow.rb:1052:5:1052:5 | a [element 3] : | semmle.label | a [element 3] : | | array_flow.rb:1052:10:1052:22 | call to source : | semmle.label | call to source : | | array_flow.rb:1052:10:1052:22 | call to source : | semmle.label | call to source : | | array_flow.rb:1052:28:1052:40 | call to source : | semmle.label | call to source : | | array_flow.rb:1052:28:1052:40 | call to source : | semmle.label | call to source : | | array_flow.rb:1052:43:1052:55 | call to source : | semmle.label | call to source : | | array_flow.rb:1052:43:1052:55 | call to source : | semmle.label | call to source : | +| array_flow.rb:1054:5:1054:5 | b [element 1] : | semmle.label | b [element 1] : | +| array_flow.rb:1054:5:1054:5 | b [element 1] : | semmle.label | b [element 1] : | +| array_flow.rb:1054:5:1054:5 | b [element 2] : | semmle.label | b [element 2] : | +| array_flow.rb:1054:5:1054:5 | b [element 2] : | semmle.label | b [element 2] : | +| array_flow.rb:1054:5:1054:5 | b [element] : | semmle.label | b [element] : | +| array_flow.rb:1054:5:1054:5 | b [element] : | semmle.label | b [element] : | | array_flow.rb:1054:9:1054:9 | a [element 0] : | semmle.label | a [element 0] : | | array_flow.rb:1054:9:1054:9 | a [element 0] : | semmle.label | a [element 0] : | | array_flow.rb:1054:9:1054:9 | a [element 2] : | semmle.label | a [element 2] : | @@ -5568,6 +6864,12 @@ nodes | array_flow.rb:1058:10:1058:10 | b [element] : | semmle.label | b [element] : | | array_flow.rb:1058:10:1058:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:1058:10:1058:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1060:5:1060:5 | b [element 0] : | semmle.label | b [element 0] : | +| array_flow.rb:1060:5:1060:5 | b [element 0] : | semmle.label | b [element 0] : | +| array_flow.rb:1060:5:1060:5 | b [element 1] : | semmle.label | b [element 1] : | +| array_flow.rb:1060:5:1060:5 | b [element 1] : | semmle.label | b [element 1] : | +| array_flow.rb:1060:5:1060:5 | b [element] : | semmle.label | b [element] : | +| array_flow.rb:1060:5:1060:5 | b [element] : | semmle.label | b [element] : | | array_flow.rb:1060:9:1060:9 | a [element 0] : | semmle.label | a [element 0] : | | array_flow.rb:1060:9:1060:9 | a [element 0] : | semmle.label | a [element 0] : | | array_flow.rb:1060:9:1060:9 | a [element 2] : | semmle.label | a [element 2] : | @@ -5600,6 +6902,12 @@ nodes | array_flow.rb:1064:10:1064:10 | b [element] : | semmle.label | b [element] : | | array_flow.rb:1064:10:1064:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:1064:10:1064:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1066:5:1066:5 | b [element 0] : | semmle.label | b [element 0] : | +| array_flow.rb:1066:5:1066:5 | b [element 0] : | semmle.label | b [element 0] : | +| array_flow.rb:1066:5:1066:5 | b [element 2] : | semmle.label | b [element 2] : | +| array_flow.rb:1066:5:1066:5 | b [element 2] : | semmle.label | b [element 2] : | +| array_flow.rb:1066:5:1066:5 | b [element 3] : | semmle.label | b [element 3] : | +| array_flow.rb:1066:5:1066:5 | b [element 3] : | semmle.label | b [element 3] : | | array_flow.rb:1066:9:1066:9 | a [element 0] : | semmle.label | a [element 0] : | | array_flow.rb:1066:9:1066:9 | a [element 0] : | semmle.label | a [element 0] : | | array_flow.rb:1066:9:1066:9 | a [element 2] : | semmle.label | a [element 2] : | @@ -5624,6 +6932,8 @@ nodes | array_flow.rb:1070:10:1070:10 | b [element 3] : | semmle.label | b [element 3] : | | array_flow.rb:1070:10:1070:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:1070:10:1070:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1072:5:1072:5 | b [element] : | semmle.label | b [element] : | +| array_flow.rb:1072:5:1072:5 | b [element] : | semmle.label | b [element] : | | array_flow.rb:1072:9:1072:9 | a [element 0] : | semmle.label | a [element 0] : | | array_flow.rb:1072:9:1072:9 | a [element 0] : | semmle.label | a [element 0] : | | array_flow.rb:1072:9:1072:9 | a [element 2] : | semmle.label | a [element 2] : | @@ -5648,12 +6958,24 @@ nodes | array_flow.rb:1076:10:1076:10 | b [element] : | semmle.label | b [element] : | | array_flow.rb:1076:10:1076:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:1076:10:1076:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1084:5:1084:5 | a [element 0] : | semmle.label | a [element 0] : | +| array_flow.rb:1084:5:1084:5 | a [element 0] : | semmle.label | a [element 0] : | +| array_flow.rb:1084:5:1084:5 | a [element 2] : | semmle.label | a [element 2] : | +| array_flow.rb:1084:5:1084:5 | a [element 2] : | semmle.label | a [element 2] : | +| array_flow.rb:1084:5:1084:5 | a [element 3] : | semmle.label | a [element 3] : | +| array_flow.rb:1084:5:1084:5 | a [element 3] : | semmle.label | a [element 3] : | | array_flow.rb:1084:10:1084:22 | call to source : | semmle.label | call to source : | | array_flow.rb:1084:10:1084:22 | call to source : | semmle.label | call to source : | | array_flow.rb:1084:28:1084:40 | call to source : | semmle.label | call to source : | | array_flow.rb:1084:28:1084:40 | call to source : | semmle.label | call to source : | | array_flow.rb:1084:43:1084:55 | call to source : | semmle.label | call to source : | | array_flow.rb:1084:43:1084:55 | call to source : | semmle.label | call to source : | +| array_flow.rb:1085:5:1085:5 | b [element 1] : | semmle.label | b [element 1] : | +| array_flow.rb:1085:5:1085:5 | b [element 1] : | semmle.label | b [element 1] : | +| array_flow.rb:1085:5:1085:5 | b [element 2] : | semmle.label | b [element 2] : | +| array_flow.rb:1085:5:1085:5 | b [element 2] : | semmle.label | b [element 2] : | +| array_flow.rb:1085:5:1085:5 | b [element] : | semmle.label | b [element] : | +| array_flow.rb:1085:5:1085:5 | b [element] : | semmle.label | b [element] : | | array_flow.rb:1085:9:1085:9 | [post] a [element 1] : | semmle.label | [post] a [element 1] : | | array_flow.rb:1085:9:1085:9 | [post] a [element 1] : | semmle.label | [post] a [element 1] : | | array_flow.rb:1085:9:1085:9 | [post] a [element 2] : | semmle.label | [post] a [element 2] : | @@ -5712,12 +7034,24 @@ nodes | array_flow.rb:1093:10:1093:10 | b [element] : | semmle.label | b [element] : | | array_flow.rb:1093:10:1093:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:1093:10:1093:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1095:5:1095:5 | a [element 0] : | semmle.label | a [element 0] : | +| array_flow.rb:1095:5:1095:5 | a [element 0] : | semmle.label | a [element 0] : | +| array_flow.rb:1095:5:1095:5 | a [element 2] : | semmle.label | a [element 2] : | +| array_flow.rb:1095:5:1095:5 | a [element 2] : | semmle.label | a [element 2] : | +| array_flow.rb:1095:5:1095:5 | a [element 3] : | semmle.label | a [element 3] : | +| array_flow.rb:1095:5:1095:5 | a [element 3] : | semmle.label | a [element 3] : | | array_flow.rb:1095:10:1095:22 | call to source : | semmle.label | call to source : | | array_flow.rb:1095:10:1095:22 | call to source : | semmle.label | call to source : | | array_flow.rb:1095:28:1095:40 | call to source : | semmle.label | call to source : | | array_flow.rb:1095:28:1095:40 | call to source : | semmle.label | call to source : | | array_flow.rb:1095:43:1095:55 | call to source : | semmle.label | call to source : | | array_flow.rb:1095:43:1095:55 | call to source : | semmle.label | call to source : | +| array_flow.rb:1096:5:1096:5 | b [element 0] : | semmle.label | b [element 0] : | +| array_flow.rb:1096:5:1096:5 | b [element 0] : | semmle.label | b [element 0] : | +| array_flow.rb:1096:5:1096:5 | b [element 1] : | semmle.label | b [element 1] : | +| array_flow.rb:1096:5:1096:5 | b [element 1] : | semmle.label | b [element 1] : | +| array_flow.rb:1096:5:1096:5 | b [element] : | semmle.label | b [element] : | +| array_flow.rb:1096:5:1096:5 | b [element] : | semmle.label | b [element] : | | array_flow.rb:1096:9:1096:9 | [post] a [element 0] : | semmle.label | [post] a [element 0] : | | array_flow.rb:1096:9:1096:9 | [post] a [element 0] : | semmle.label | [post] a [element 0] : | | array_flow.rb:1096:9:1096:9 | [post] a [element 1] : | semmle.label | [post] a [element 1] : | @@ -5776,12 +7110,24 @@ nodes | array_flow.rb:1104:10:1104:10 | b [element] : | semmle.label | b [element] : | | array_flow.rb:1104:10:1104:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:1104:10:1104:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1106:5:1106:5 | a [element 0] : | semmle.label | a [element 0] : | +| array_flow.rb:1106:5:1106:5 | a [element 0] : | semmle.label | a [element 0] : | +| array_flow.rb:1106:5:1106:5 | a [element 2] : | semmle.label | a [element 2] : | +| array_flow.rb:1106:5:1106:5 | a [element 2] : | semmle.label | a [element 2] : | +| array_flow.rb:1106:5:1106:5 | a [element 3] : | semmle.label | a [element 3] : | +| array_flow.rb:1106:5:1106:5 | a [element 3] : | semmle.label | a [element 3] : | | array_flow.rb:1106:10:1106:22 | call to source : | semmle.label | call to source : | | array_flow.rb:1106:10:1106:22 | call to source : | semmle.label | call to source : | | array_flow.rb:1106:28:1106:40 | call to source : | semmle.label | call to source : | | array_flow.rb:1106:28:1106:40 | call to source : | semmle.label | call to source : | | array_flow.rb:1106:43:1106:55 | call to source : | semmle.label | call to source : | | array_flow.rb:1106:43:1106:55 | call to source : | semmle.label | call to source : | +| array_flow.rb:1107:5:1107:5 | b [element 0] : | semmle.label | b [element 0] : | +| array_flow.rb:1107:5:1107:5 | b [element 0] : | semmle.label | b [element 0] : | +| array_flow.rb:1107:5:1107:5 | b [element 2] : | semmle.label | b [element 2] : | +| array_flow.rb:1107:5:1107:5 | b [element 2] : | semmle.label | b [element 2] : | +| array_flow.rb:1107:5:1107:5 | b [element 3] : | semmle.label | b [element 3] : | +| array_flow.rb:1107:5:1107:5 | b [element 3] : | semmle.label | b [element 3] : | | array_flow.rb:1107:9:1107:9 | [post] a [element 0] : | semmle.label | [post] a [element 0] : | | array_flow.rb:1107:9:1107:9 | [post] a [element 0] : | semmle.label | [post] a [element 0] : | | array_flow.rb:1107:9:1107:9 | [post] a [element 2] : | semmle.label | [post] a [element 2] : | @@ -5824,12 +7170,20 @@ nodes | array_flow.rb:1115:10:1115:10 | b [element 3] : | semmle.label | b [element 3] : | | array_flow.rb:1115:10:1115:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:1115:10:1115:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1117:5:1117:5 | a [element 0] : | semmle.label | a [element 0] : | +| array_flow.rb:1117:5:1117:5 | a [element 0] : | semmle.label | a [element 0] : | +| array_flow.rb:1117:5:1117:5 | a [element 2] : | semmle.label | a [element 2] : | +| array_flow.rb:1117:5:1117:5 | a [element 2] : | semmle.label | a [element 2] : | +| array_flow.rb:1117:5:1117:5 | a [element 3] : | semmle.label | a [element 3] : | +| array_flow.rb:1117:5:1117:5 | a [element 3] : | semmle.label | a [element 3] : | | array_flow.rb:1117:10:1117:22 | call to source : | semmle.label | call to source : | | array_flow.rb:1117:10:1117:22 | call to source : | semmle.label | call to source : | | array_flow.rb:1117:28:1117:40 | call to source : | semmle.label | call to source : | | array_flow.rb:1117:28:1117:40 | call to source : | semmle.label | call to source : | | array_flow.rb:1117:43:1117:55 | call to source : | semmle.label | call to source : | | array_flow.rb:1117:43:1117:55 | call to source : | semmle.label | call to source : | +| array_flow.rb:1118:5:1118:5 | b [element] : | semmle.label | b [element] : | +| array_flow.rb:1118:5:1118:5 | b [element] : | semmle.label | b [element] : | | array_flow.rb:1118:9:1118:9 | [post] a [element] : | semmle.label | [post] a [element] : | | array_flow.rb:1118:9:1118:9 | [post] a [element] : | semmle.label | [post] a [element] : | | array_flow.rb:1118:9:1118:9 | a [element 0] : | semmle.label | a [element 0] : | @@ -5872,8 +7226,12 @@ nodes | array_flow.rb:1126:10:1126:10 | b [element] : | semmle.label | b [element] : | | array_flow.rb:1126:10:1126:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:1126:10:1126:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1130:5:1130:5 | a [element 3] : | semmle.label | a [element 3] : | +| array_flow.rb:1130:5:1130:5 | a [element 3] : | semmle.label | a [element 3] : | | array_flow.rb:1130:19:1130:29 | call to source : | semmle.label | call to source : | | array_flow.rb:1130:19:1130:29 | call to source : | semmle.label | call to source : | +| array_flow.rb:1131:5:1131:5 | b [element] : | semmle.label | b [element] : | +| array_flow.rb:1131:5:1131:5 | b [element] : | semmle.label | b [element] : | | array_flow.rb:1131:9:1131:9 | a [element 3] : | semmle.label | a [element 3] : | | array_flow.rb:1131:9:1131:9 | a [element 3] : | semmle.label | a [element 3] : | | array_flow.rb:1131:9:1133:7 | call to select [element] : | semmle.label | call to select [element] : | @@ -5886,8 +7244,12 @@ nodes | array_flow.rb:1134:10:1134:10 | b [element] : | semmle.label | b [element] : | | array_flow.rb:1134:10:1134:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:1134:10:1134:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1138:5:1138:5 | a [element 2] : | semmle.label | a [element 2] : | +| array_flow.rb:1138:5:1138:5 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:1138:16:1138:26 | call to source : | semmle.label | call to source : | | array_flow.rb:1138:16:1138:26 | call to source : | semmle.label | call to source : | +| array_flow.rb:1139:5:1139:5 | b [element] : | semmle.label | b [element] : | +| array_flow.rb:1139:5:1139:5 | b [element] : | semmle.label | b [element] : | | array_flow.rb:1139:9:1139:9 | [post] a [element] : | semmle.label | [post] a [element] : | | array_flow.rb:1139:9:1139:9 | [post] a [element] : | semmle.label | [post] a [element] : | | array_flow.rb:1139:9:1139:9 | a [element 2] : | semmle.label | a [element 2] : | @@ -5906,10 +7268,16 @@ nodes | array_flow.rb:1144:10:1144:10 | b [element] : | semmle.label | b [element] : | | array_flow.rb:1144:10:1144:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:1144:10:1144:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1148:5:1148:5 | a [element 0] : | semmle.label | a [element 0] : | +| array_flow.rb:1148:5:1148:5 | a [element 0] : | semmle.label | a [element 0] : | +| array_flow.rb:1148:5:1148:5 | a [element 2] : | semmle.label | a [element 2] : | +| array_flow.rb:1148:5:1148:5 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:1148:10:1148:22 | call to source : | semmle.label | call to source : | | array_flow.rb:1148:10:1148:22 | call to source : | semmle.label | call to source : | | array_flow.rb:1148:28:1148:40 | call to source : | semmle.label | call to source : | | array_flow.rb:1148:28:1148:40 | call to source : | semmle.label | call to source : | +| array_flow.rb:1149:5:1149:5 | b : | semmle.label | b : | +| array_flow.rb:1149:5:1149:5 | b : | semmle.label | b : | | array_flow.rb:1149:9:1149:9 | [post] a [element 1] : | semmle.label | [post] a [element 1] : | | array_flow.rb:1149:9:1149:9 | [post] a [element 1] : | semmle.label | [post] a [element 1] : | | array_flow.rb:1149:9:1149:9 | a [element 0] : | semmle.label | a [element 0] : | @@ -5924,10 +7292,16 @@ nodes | array_flow.rb:1152:10:1152:10 | a [element 1] : | semmle.label | a [element 1] : | | array_flow.rb:1152:10:1152:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:1152:10:1152:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1155:5:1155:5 | a [element 0] : | semmle.label | a [element 0] : | +| array_flow.rb:1155:5:1155:5 | a [element 0] : | semmle.label | a [element 0] : | +| array_flow.rb:1155:5:1155:5 | a [element 2] : | semmle.label | a [element 2] : | +| array_flow.rb:1155:5:1155:5 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:1155:10:1155:22 | call to source : | semmle.label | call to source : | | array_flow.rb:1155:10:1155:22 | call to source : | semmle.label | call to source : | | array_flow.rb:1155:28:1155:40 | call to source : | semmle.label | call to source : | | array_flow.rb:1155:28:1155:40 | call to source : | semmle.label | call to source : | +| array_flow.rb:1156:5:1156:5 | b [element 0] : | semmle.label | b [element 0] : | +| array_flow.rb:1156:5:1156:5 | b [element 0] : | semmle.label | b [element 0] : | | array_flow.rb:1156:9:1156:9 | [post] a [element 0] : | semmle.label | [post] a [element 0] : | | array_flow.rb:1156:9:1156:9 | [post] a [element 0] : | semmle.label | [post] a [element 0] : | | array_flow.rb:1156:9:1156:9 | a [element 0] : | semmle.label | a [element 0] : | @@ -5944,10 +7318,16 @@ nodes | array_flow.rb:1159:10:1159:10 | a [element 0] : | semmle.label | a [element 0] : | | array_flow.rb:1159:10:1159:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:1159:10:1159:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1163:5:1163:5 | a [element 0] : | semmle.label | a [element 0] : | +| array_flow.rb:1163:5:1163:5 | a [element 0] : | semmle.label | a [element 0] : | +| array_flow.rb:1163:5:1163:5 | a [element 2] : | semmle.label | a [element 2] : | +| array_flow.rb:1163:5:1163:5 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:1163:10:1163:22 | call to source : | semmle.label | call to source : | | array_flow.rb:1163:10:1163:22 | call to source : | semmle.label | call to source : | | array_flow.rb:1163:28:1163:40 | call to source : | semmle.label | call to source : | | array_flow.rb:1163:28:1163:40 | call to source : | semmle.label | call to source : | +| array_flow.rb:1164:5:1164:5 | b [element] : | semmle.label | b [element] : | +| array_flow.rb:1164:5:1164:5 | b [element] : | semmle.label | b [element] : | | array_flow.rb:1164:9:1164:9 | [post] a [element] : | semmle.label | [post] a [element] : | | array_flow.rb:1164:9:1164:9 | [post] a [element] : | semmle.label | [post] a [element] : | | array_flow.rb:1164:9:1164:9 | a [element 0] : | semmle.label | a [element 0] : | @@ -5980,8 +7360,12 @@ nodes | array_flow.rb:1169:10:1169:10 | a [element] : | semmle.label | a [element] : | | array_flow.rb:1169:10:1169:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:1169:10:1169:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1173:5:1173:5 | a [element 2] : | semmle.label | a [element 2] : | +| array_flow.rb:1173:5:1173:5 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:1173:16:1173:26 | call to source : | semmle.label | call to source : | | array_flow.rb:1173:16:1173:26 | call to source : | semmle.label | call to source : | +| array_flow.rb:1174:5:1174:5 | b [element] : | semmle.label | b [element] : | +| array_flow.rb:1174:5:1174:5 | b [element] : | semmle.label | b [element] : | | array_flow.rb:1174:9:1174:9 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:1174:9:1174:9 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:1174:9:1174:17 | call to shuffle [element] : | semmle.label | call to shuffle [element] : | @@ -6002,8 +7386,12 @@ nodes | array_flow.rb:1180:10:1180:10 | b [element] : | semmle.label | b [element] : | | array_flow.rb:1180:10:1180:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:1180:10:1180:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1184:5:1184:5 | a [element 2] : | semmle.label | a [element 2] : | +| array_flow.rb:1184:5:1184:5 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:1184:16:1184:26 | call to source : | semmle.label | call to source : | | array_flow.rb:1184:16:1184:26 | call to source : | semmle.label | call to source : | +| array_flow.rb:1185:5:1185:5 | b [element] : | semmle.label | b [element] : | +| array_flow.rb:1185:5:1185:5 | b [element] : | semmle.label | b [element] : | | array_flow.rb:1185:9:1185:9 | [post] a [element] : | semmle.label | [post] a [element] : | | array_flow.rb:1185:9:1185:9 | [post] a [element] : | semmle.label | [post] a [element] : | | array_flow.rb:1185:9:1185:9 | a [element 2] : | semmle.label | a [element 2] : | @@ -6036,16 +7424,24 @@ nodes | array_flow.rb:1191:10:1191:10 | b [element] : | semmle.label | b [element] : | | array_flow.rb:1191:10:1191:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:1191:10:1191:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1195:5:1195:5 | a [element 2] : | semmle.label | a [element 2] : | +| array_flow.rb:1195:5:1195:5 | a [element 2] : | semmle.label | a [element 2] : | +| array_flow.rb:1195:5:1195:5 | a [element 4] : | semmle.label | a [element 4] : | +| array_flow.rb:1195:5:1195:5 | a [element 4] : | semmle.label | a [element 4] : | | array_flow.rb:1195:16:1195:28 | call to source : | semmle.label | call to source : | | array_flow.rb:1195:16:1195:28 | call to source : | semmle.label | call to source : | | array_flow.rb:1195:34:1195:46 | call to source : | semmle.label | call to source : | | array_flow.rb:1195:34:1195:46 | call to source : | semmle.label | call to source : | +| array_flow.rb:1197:5:1197:5 | b : | semmle.label | b : | +| array_flow.rb:1197:5:1197:5 | b : | semmle.label | b : | | array_flow.rb:1197:9:1197:9 | a [element 4] : | semmle.label | a [element 4] : | | array_flow.rb:1197:9:1197:9 | a [element 4] : | semmle.label | a [element 4] : | | array_flow.rb:1197:9:1197:17 | call to slice : | semmle.label | call to slice : | | array_flow.rb:1197:9:1197:17 | call to slice : | semmle.label | call to slice : | | array_flow.rb:1198:10:1198:10 | b | semmle.label | b | | array_flow.rb:1198:10:1198:10 | b | semmle.label | b | +| array_flow.rb:1200:5:1200:5 | b : | semmle.label | b : | +| array_flow.rb:1200:5:1200:5 | b : | semmle.label | b : | | array_flow.rb:1200:9:1200:9 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:1200:9:1200:9 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:1200:9:1200:9 | a [element 4] : | semmle.label | a [element 4] : | @@ -6054,6 +7450,10 @@ nodes | array_flow.rb:1200:9:1200:19 | call to slice : | semmle.label | call to slice : | | array_flow.rb:1201:10:1201:10 | b | semmle.label | b | | array_flow.rb:1201:10:1201:10 | b | semmle.label | b | +| array_flow.rb:1203:5:1203:5 | b : | semmle.label | b : | +| array_flow.rb:1203:5:1203:5 | b : | semmle.label | b : | +| array_flow.rb:1203:5:1203:5 | b [element] : | semmle.label | b [element] : | +| array_flow.rb:1203:5:1203:5 | b [element] : | semmle.label | b [element] : | | array_flow.rb:1203:9:1203:9 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:1203:9:1203:9 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:1203:9:1203:9 | a [element 4] : | semmle.label | a [element 4] : | @@ -6069,6 +7469,10 @@ nodes | array_flow.rb:1207:10:1207:10 | b [element] : | semmle.label | b [element] : | | array_flow.rb:1207:10:1207:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:1207:10:1207:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1209:5:1209:5 | b [element 0] : | semmle.label | b [element 0] : | +| array_flow.rb:1209:5:1209:5 | b [element 0] : | semmle.label | b [element 0] : | +| array_flow.rb:1209:5:1209:5 | b [element 2] : | semmle.label | b [element 2] : | +| array_flow.rb:1209:5:1209:5 | b [element 2] : | semmle.label | b [element 2] : | | array_flow.rb:1209:9:1209:9 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:1209:9:1209:9 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:1209:9:1209:9 | a [element 4] : | semmle.label | a [element 4] : | @@ -6085,6 +7489,8 @@ nodes | array_flow.rb:1212:10:1212:10 | b [element 2] : | semmle.label | b [element 2] : | | array_flow.rb:1212:10:1212:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:1212:10:1212:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1214:5:1214:5 | b [element] : | semmle.label | b [element] : | +| array_flow.rb:1214:5:1214:5 | b [element] : | semmle.label | b [element] : | | array_flow.rb:1214:9:1214:9 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:1214:9:1214:9 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:1214:9:1214:9 | a [element 4] : | semmle.label | a [element 4] : | @@ -6099,6 +7505,8 @@ nodes | array_flow.rb:1216:10:1216:10 | b [element] : | semmle.label | b [element] : | | array_flow.rb:1216:10:1216:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:1216:10:1216:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1218:5:1218:5 | b [element 0] : | semmle.label | b [element 0] : | +| array_flow.rb:1218:5:1218:5 | b [element 0] : | semmle.label | b [element 0] : | | array_flow.rb:1218:9:1218:9 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:1218:9:1218:9 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:1218:9:1218:21 | call to slice [element 0] : | semmle.label | call to slice [element 0] : | @@ -6107,6 +7515,8 @@ nodes | array_flow.rb:1219:10:1219:10 | b [element 0] : | semmle.label | b [element 0] : | | array_flow.rb:1219:10:1219:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:1219:10:1219:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1223:5:1223:5 | b [element 0] : | semmle.label | b [element 0] : | +| array_flow.rb:1223:5:1223:5 | b [element 0] : | semmle.label | b [element 0] : | | array_flow.rb:1223:9:1223:9 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:1223:9:1223:9 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:1223:9:1223:22 | call to slice [element 0] : | semmle.label | call to slice [element 0] : | @@ -6115,6 +7525,8 @@ nodes | array_flow.rb:1224:10:1224:10 | b [element 0] : | semmle.label | b [element 0] : | | array_flow.rb:1224:10:1224:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:1224:10:1224:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1228:5:1228:5 | b [element] : | semmle.label | b [element] : | +| array_flow.rb:1228:5:1228:5 | b [element] : | semmle.label | b [element] : | | array_flow.rb:1228:9:1228:9 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:1228:9:1228:9 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:1228:9:1228:9 | a [element 4] : | semmle.label | a [element 4] : | @@ -6129,6 +7541,8 @@ nodes | array_flow.rb:1230:10:1230:10 | b [element] : | semmle.label | b [element] : | | array_flow.rb:1230:10:1230:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:1230:10:1230:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1232:5:1232:5 | b [element] : | semmle.label | b [element] : | +| array_flow.rb:1232:5:1232:5 | b [element] : | semmle.label | b [element] : | | array_flow.rb:1232:9:1232:9 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:1232:9:1232:9 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:1232:9:1232:9 | a [element 4] : | semmle.label | a [element 4] : | @@ -6143,6 +7557,8 @@ nodes | array_flow.rb:1234:10:1234:10 | b [element] : | semmle.label | b [element] : | | array_flow.rb:1234:10:1234:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:1234:10:1234:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1236:5:1236:5 | b [element 2] : | semmle.label | b [element 2] : | +| array_flow.rb:1236:5:1236:5 | b [element 2] : | semmle.label | b [element 2] : | | array_flow.rb:1236:9:1236:9 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:1236:9:1236:9 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:1236:9:1236:20 | call to slice [element 2] : | semmle.label | call to slice [element 2] : | @@ -6151,6 +7567,8 @@ nodes | array_flow.rb:1239:10:1239:10 | b [element 2] : | semmle.label | b [element 2] : | | array_flow.rb:1239:10:1239:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:1239:10:1239:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1241:5:1241:5 | b [element] : | semmle.label | b [element] : | +| array_flow.rb:1241:5:1241:5 | b [element] : | semmle.label | b [element] : | | array_flow.rb:1241:9:1241:9 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:1241:9:1241:9 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:1241:9:1241:9 | a [element 4] : | semmle.label | a [element 4] : | @@ -6169,10 +7587,16 @@ nodes | array_flow.rb:1244:10:1244:10 | b [element] : | semmle.label | b [element] : | | array_flow.rb:1244:10:1244:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:1244:10:1244:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1248:5:1248:5 | a [element 2] : | semmle.label | a [element 2] : | +| array_flow.rb:1248:5:1248:5 | a [element 2] : | semmle.label | a [element 2] : | +| array_flow.rb:1248:5:1248:5 | a [element 4] : | semmle.label | a [element 4] : | +| array_flow.rb:1248:5:1248:5 | a [element 4] : | semmle.label | a [element 4] : | | array_flow.rb:1248:16:1248:28 | call to source : | semmle.label | call to source : | | array_flow.rb:1248:16:1248:28 | call to source : | semmle.label | call to source : | | array_flow.rb:1248:34:1248:46 | call to source : | semmle.label | call to source : | | array_flow.rb:1248:34:1248:46 | call to source : | semmle.label | call to source : | +| array_flow.rb:1249:5:1249:5 | b : | semmle.label | b : | +| array_flow.rb:1249:5:1249:5 | b : | semmle.label | b : | | array_flow.rb:1249:9:1249:9 | [post] a [element 3] : | semmle.label | [post] a [element 3] : | | array_flow.rb:1249:9:1249:9 | [post] a [element 3] : | semmle.label | [post] a [element 3] : | | array_flow.rb:1249:9:1249:9 | a [element 2] : | semmle.label | a [element 2] : | @@ -6187,10 +7611,18 @@ nodes | array_flow.rb:1254:10:1254:10 | a [element 3] : | semmle.label | a [element 3] : | | array_flow.rb:1254:10:1254:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:1254:10:1254:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1256:5:1256:5 | a [element 2] : | semmle.label | a [element 2] : | +| array_flow.rb:1256:5:1256:5 | a [element 2] : | semmle.label | a [element 2] : | +| array_flow.rb:1256:5:1256:5 | a [element 4] : | semmle.label | a [element 4] : | +| array_flow.rb:1256:5:1256:5 | a [element 4] : | semmle.label | a [element 4] : | | array_flow.rb:1256:16:1256:28 | call to source : | semmle.label | call to source : | | array_flow.rb:1256:16:1256:28 | call to source : | semmle.label | call to source : | | array_flow.rb:1256:34:1256:46 | call to source : | semmle.label | call to source : | | array_flow.rb:1256:34:1256:46 | call to source : | semmle.label | call to source : | +| array_flow.rb:1257:5:1257:5 | b : | semmle.label | b : | +| array_flow.rb:1257:5:1257:5 | b : | semmle.label | b : | +| array_flow.rb:1257:5:1257:5 | b [element] : | semmle.label | b [element] : | +| array_flow.rb:1257:5:1257:5 | b [element] : | semmle.label | b [element] : | | array_flow.rb:1257:9:1257:9 | [post] a [element] : | semmle.label | [post] a [element] : | | array_flow.rb:1257:9:1257:9 | [post] a [element] : | semmle.label | [post] a [element] : | | array_flow.rb:1257:9:1257:9 | a [element 2] : | semmle.label | a [element 2] : | @@ -6224,10 +7656,18 @@ nodes | array_flow.rb:1265:10:1265:10 | b [element] : | semmle.label | b [element] : | | array_flow.rb:1265:10:1265:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:1265:10:1265:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1267:5:1267:5 | a [element 2] : | semmle.label | a [element 2] : | +| array_flow.rb:1267:5:1267:5 | a [element 2] : | semmle.label | a [element 2] : | +| array_flow.rb:1267:5:1267:5 | a [element 4] : | semmle.label | a [element 4] : | +| array_flow.rb:1267:5:1267:5 | a [element 4] : | semmle.label | a [element 4] : | | array_flow.rb:1267:16:1267:28 | call to source : | semmle.label | call to source : | | array_flow.rb:1267:16:1267:28 | call to source : | semmle.label | call to source : | | array_flow.rb:1267:34:1267:46 | call to source : | semmle.label | call to source : | | array_flow.rb:1267:34:1267:46 | call to source : | semmle.label | call to source : | +| array_flow.rb:1268:5:1268:5 | b [element 0] : | semmle.label | b [element 0] : | +| array_flow.rb:1268:5:1268:5 | b [element 0] : | semmle.label | b [element 0] : | +| array_flow.rb:1268:5:1268:5 | b [element 2] : | semmle.label | b [element 2] : | +| array_flow.rb:1268:5:1268:5 | b [element 2] : | semmle.label | b [element 2] : | | array_flow.rb:1268:9:1268:9 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:1268:9:1268:9 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:1268:9:1268:9 | a [element 4] : | semmle.label | a [element 4] : | @@ -6244,10 +7684,16 @@ nodes | array_flow.rb:1271:10:1271:10 | b [element 2] : | semmle.label | b [element 2] : | | array_flow.rb:1271:10:1271:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:1271:10:1271:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1278:5:1278:5 | a [element 2] : | semmle.label | a [element 2] : | +| array_flow.rb:1278:5:1278:5 | a [element 2] : | semmle.label | a [element 2] : | +| array_flow.rb:1278:5:1278:5 | a [element 4] : | semmle.label | a [element 4] : | +| array_flow.rb:1278:5:1278:5 | a [element 4] : | semmle.label | a [element 4] : | | array_flow.rb:1278:16:1278:28 | call to source : | semmle.label | call to source : | | array_flow.rb:1278:16:1278:28 | call to source : | semmle.label | call to source : | | array_flow.rb:1278:34:1278:46 | call to source : | semmle.label | call to source : | | array_flow.rb:1278:34:1278:46 | call to source : | semmle.label | call to source : | +| array_flow.rb:1279:5:1279:5 | b [element 0] : | semmle.label | b [element 0] : | +| array_flow.rb:1279:5:1279:5 | b [element 0] : | semmle.label | b [element 0] : | | array_flow.rb:1279:9:1279:9 | [post] a [element 2] : | semmle.label | [post] a [element 2] : | | array_flow.rb:1279:9:1279:9 | [post] a [element 2] : | semmle.label | [post] a [element 2] : | | array_flow.rb:1279:9:1279:9 | a [element 2] : | semmle.label | a [element 2] : | @@ -6264,10 +7710,16 @@ nodes | array_flow.rb:1285:10:1285:10 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:1285:10:1285:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:1285:10:1285:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1289:5:1289:5 | a [element 2] : | semmle.label | a [element 2] : | +| array_flow.rb:1289:5:1289:5 | a [element 2] : | semmle.label | a [element 2] : | +| array_flow.rb:1289:5:1289:5 | a [element 4] : | semmle.label | a [element 4] : | +| array_flow.rb:1289:5:1289:5 | a [element 4] : | semmle.label | a [element 4] : | | array_flow.rb:1289:16:1289:28 | call to source : | semmle.label | call to source : | | array_flow.rb:1289:16:1289:28 | call to source : | semmle.label | call to source : | | array_flow.rb:1289:34:1289:46 | call to source : | semmle.label | call to source : | | array_flow.rb:1289:34:1289:46 | call to source : | semmle.label | call to source : | +| array_flow.rb:1290:5:1290:5 | b [element 0] : | semmle.label | b [element 0] : | +| array_flow.rb:1290:5:1290:5 | b [element 0] : | semmle.label | b [element 0] : | | array_flow.rb:1290:9:1290:9 | [post] a [element 2] : | semmle.label | [post] a [element 2] : | | array_flow.rb:1290:9:1290:9 | [post] a [element 2] : | semmle.label | [post] a [element 2] : | | array_flow.rb:1290:9:1290:9 | a [element 2] : | semmle.label | a [element 2] : | @@ -6284,10 +7736,16 @@ nodes | array_flow.rb:1296:10:1296:10 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:1296:10:1296:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:1296:10:1296:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1300:5:1300:5 | a [element 2] : | semmle.label | a [element 2] : | +| array_flow.rb:1300:5:1300:5 | a [element 2] : | semmle.label | a [element 2] : | +| array_flow.rb:1300:5:1300:5 | a [element 4] : | semmle.label | a [element 4] : | +| array_flow.rb:1300:5:1300:5 | a [element 4] : | semmle.label | a [element 4] : | | array_flow.rb:1300:16:1300:28 | call to source : | semmle.label | call to source : | | array_flow.rb:1300:16:1300:28 | call to source : | semmle.label | call to source : | | array_flow.rb:1300:34:1300:46 | call to source : | semmle.label | call to source : | | array_flow.rb:1300:34:1300:46 | call to source : | semmle.label | call to source : | +| array_flow.rb:1301:5:1301:5 | b [element] : | semmle.label | b [element] : | +| array_flow.rb:1301:5:1301:5 | b [element] : | semmle.label | b [element] : | | array_flow.rb:1301:9:1301:9 | [post] a [element] : | semmle.label | [post] a [element] : | | array_flow.rb:1301:9:1301:9 | [post] a [element] : | semmle.label | [post] a [element] : | | array_flow.rb:1301:9:1301:9 | a [element 2] : | semmle.label | a [element 2] : | @@ -6320,10 +7778,16 @@ nodes | array_flow.rb:1307:10:1307:10 | a [element] : | semmle.label | a [element] : | | array_flow.rb:1307:10:1307:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:1307:10:1307:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1309:5:1309:5 | a [element 2] : | semmle.label | a [element 2] : | +| array_flow.rb:1309:5:1309:5 | a [element 2] : | semmle.label | a [element 2] : | +| array_flow.rb:1309:5:1309:5 | a [element 4] : | semmle.label | a [element 4] : | +| array_flow.rb:1309:5:1309:5 | a [element 4] : | semmle.label | a [element 4] : | | array_flow.rb:1309:16:1309:28 | call to source : | semmle.label | call to source : | | array_flow.rb:1309:16:1309:28 | call to source : | semmle.label | call to source : | | array_flow.rb:1309:34:1309:46 | call to source : | semmle.label | call to source : | | array_flow.rb:1309:34:1309:46 | call to source : | semmle.label | call to source : | +| array_flow.rb:1310:5:1310:5 | b [element] : | semmle.label | b [element] : | +| array_flow.rb:1310:5:1310:5 | b [element] : | semmle.label | b [element] : | | array_flow.rb:1310:9:1310:9 | [post] a [element] : | semmle.label | [post] a [element] : | | array_flow.rb:1310:9:1310:9 | [post] a [element] : | semmle.label | [post] a [element] : | | array_flow.rb:1310:9:1310:9 | a [element 2] : | semmle.label | a [element 2] : | @@ -6356,10 +7820,16 @@ nodes | array_flow.rb:1316:10:1316:10 | a [element] : | semmle.label | a [element] : | | array_flow.rb:1316:10:1316:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:1316:10:1316:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1318:5:1318:5 | a [element 2] : | semmle.label | a [element 2] : | +| array_flow.rb:1318:5:1318:5 | a [element 2] : | semmle.label | a [element 2] : | +| array_flow.rb:1318:5:1318:5 | a [element 4] : | semmle.label | a [element 4] : | +| array_flow.rb:1318:5:1318:5 | a [element 4] : | semmle.label | a [element 4] : | | array_flow.rb:1318:16:1318:28 | call to source : | semmle.label | call to source : | | array_flow.rb:1318:16:1318:28 | call to source : | semmle.label | call to source : | | array_flow.rb:1318:34:1318:46 | call to source : | semmle.label | call to source : | | array_flow.rb:1318:34:1318:46 | call to source : | semmle.label | call to source : | +| array_flow.rb:1319:5:1319:5 | b [element] : | semmle.label | b [element] : | +| array_flow.rb:1319:5:1319:5 | b [element] : | semmle.label | b [element] : | | array_flow.rb:1319:9:1319:9 | [post] a [element] : | semmle.label | [post] a [element] : | | array_flow.rb:1319:9:1319:9 | [post] a [element] : | semmle.label | [post] a [element] : | | array_flow.rb:1319:9:1319:9 | a [element 2] : | semmle.label | a [element 2] : | @@ -6392,10 +7862,16 @@ nodes | array_flow.rb:1325:10:1325:10 | a [element] : | semmle.label | a [element] : | | array_flow.rb:1325:10:1325:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:1325:10:1325:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1327:5:1327:5 | a [element 2] : | semmle.label | a [element 2] : | +| array_flow.rb:1327:5:1327:5 | a [element 2] : | semmle.label | a [element 2] : | +| array_flow.rb:1327:5:1327:5 | a [element 4] : | semmle.label | a [element 4] : | +| array_flow.rb:1327:5:1327:5 | a [element 4] : | semmle.label | a [element 4] : | | array_flow.rb:1327:16:1327:28 | call to source : | semmle.label | call to source : | | array_flow.rb:1327:16:1327:28 | call to source : | semmle.label | call to source : | | array_flow.rb:1327:34:1327:46 | call to source : | semmle.label | call to source : | | array_flow.rb:1327:34:1327:46 | call to source : | semmle.label | call to source : | +| array_flow.rb:1328:5:1328:5 | b [element 2] : | semmle.label | b [element 2] : | +| array_flow.rb:1328:5:1328:5 | b [element 2] : | semmle.label | b [element 2] : | | array_flow.rb:1328:9:1328:9 | [post] a [element 1] : | semmle.label | [post] a [element 1] : | | array_flow.rb:1328:9:1328:9 | [post] a [element 1] : | semmle.label | [post] a [element 1] : | | array_flow.rb:1328:9:1328:9 | a [element 2] : | semmle.label | a [element 2] : | @@ -6412,10 +7888,16 @@ nodes | array_flow.rb:1333:10:1333:10 | a [element 1] : | semmle.label | a [element 1] : | | array_flow.rb:1333:10:1333:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:1333:10:1333:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1336:5:1336:5 | a [element 2] : | semmle.label | a [element 2] : | +| array_flow.rb:1336:5:1336:5 | a [element 2] : | semmle.label | a [element 2] : | +| array_flow.rb:1336:5:1336:5 | a [element 4] : | semmle.label | a [element 4] : | +| array_flow.rb:1336:5:1336:5 | a [element 4] : | semmle.label | a [element 4] : | | array_flow.rb:1336:16:1336:28 | call to source : | semmle.label | call to source : | | array_flow.rb:1336:16:1336:28 | call to source : | semmle.label | call to source : | | array_flow.rb:1336:34:1336:46 | call to source : | semmle.label | call to source : | | array_flow.rb:1336:34:1336:46 | call to source : | semmle.label | call to source : | +| array_flow.rb:1337:5:1337:5 | b [element] : | semmle.label | b [element] : | +| array_flow.rb:1337:5:1337:5 | b [element] : | semmle.label | b [element] : | | array_flow.rb:1337:9:1337:9 | [post] a [element] : | semmle.label | [post] a [element] : | | array_flow.rb:1337:9:1337:9 | [post] a [element] : | semmle.label | [post] a [element] : | | array_flow.rb:1337:9:1337:9 | a [element 2] : | semmle.label | a [element 2] : | @@ -6448,6 +7930,8 @@ nodes | array_flow.rb:1343:10:1343:10 | a [element] : | semmle.label | a [element] : | | array_flow.rb:1343:10:1343:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:1343:10:1343:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1347:5:1347:5 | a [element 2] : | semmle.label | a [element 2] : | +| array_flow.rb:1347:5:1347:5 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:1347:16:1347:26 | call to source : | semmle.label | call to source : | | array_flow.rb:1347:16:1347:26 | call to source : | semmle.label | call to source : | | array_flow.rb:1348:9:1348:9 | a [element 2] : | semmle.label | a [element 2] : | @@ -6456,6 +7940,8 @@ nodes | array_flow.rb:1348:27:1348:27 | x : | semmle.label | x : | | array_flow.rb:1349:14:1349:14 | x | semmle.label | x | | array_flow.rb:1349:14:1349:14 | x | semmle.label | x | +| array_flow.rb:1355:5:1355:5 | a [element 2] : | semmle.label | a [element 2] : | +| array_flow.rb:1355:5:1355:5 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:1355:16:1355:26 | call to source : | semmle.label | call to source : | | array_flow.rb:1355:16:1355:26 | call to source : | semmle.label | call to source : | | array_flow.rb:1356:9:1356:9 | a [element 2] : | semmle.label | a [element 2] : | @@ -6464,6 +7950,8 @@ nodes | array_flow.rb:1356:28:1356:28 | x : | semmle.label | x : | | array_flow.rb:1357:14:1357:14 | x | semmle.label | x | | array_flow.rb:1357:14:1357:14 | x | semmle.label | x | +| array_flow.rb:1363:5:1363:5 | a [element 2] : | semmle.label | a [element 2] : | +| array_flow.rb:1363:5:1363:5 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:1363:16:1363:26 | call to source : | semmle.label | call to source : | | array_flow.rb:1363:16:1363:26 | call to source : | semmle.label | call to source : | | array_flow.rb:1364:9:1364:9 | a [element 2] : | semmle.label | a [element 2] : | @@ -6476,8 +7964,12 @@ nodes | array_flow.rb:1365:14:1365:14 | x | semmle.label | x | | array_flow.rb:1366:14:1366:14 | y | semmle.label | y | | array_flow.rb:1366:14:1366:14 | y | semmle.label | y | +| array_flow.rb:1371:5:1371:5 | a [element 2] : | semmle.label | a [element 2] : | +| array_flow.rb:1371:5:1371:5 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:1371:16:1371:26 | call to source : | semmle.label | call to source : | | array_flow.rb:1371:16:1371:26 | call to source : | semmle.label | call to source : | +| array_flow.rb:1372:5:1372:5 | b [element] : | semmle.label | b [element] : | +| array_flow.rb:1372:5:1372:5 | b [element] : | semmle.label | b [element] : | | array_flow.rb:1372:9:1372:9 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:1372:9:1372:9 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:1372:9:1372:14 | call to sort [element] : | semmle.label | call to sort [element] : | @@ -6490,6 +7982,8 @@ nodes | array_flow.rb:1374:10:1374:10 | b [element] : | semmle.label | b [element] : | | array_flow.rb:1374:10:1374:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:1374:10:1374:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1375:5:1375:5 | c [element] : | semmle.label | c [element] : | +| array_flow.rb:1375:5:1375:5 | c [element] : | semmle.label | c [element] : | | array_flow.rb:1375:9:1375:9 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:1375:9:1375:9 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:1375:9:1379:7 | call to sort [element] : | semmle.label | call to sort [element] : | @@ -6510,8 +8004,12 @@ nodes | array_flow.rb:1381:10:1381:10 | c [element] : | semmle.label | c [element] : | | array_flow.rb:1381:10:1381:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:1381:10:1381:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1385:5:1385:5 | a [element 2] : | semmle.label | a [element 2] : | +| array_flow.rb:1385:5:1385:5 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:1385:16:1385:26 | call to source : | semmle.label | call to source : | | array_flow.rb:1385:16:1385:26 | call to source : | semmle.label | call to source : | +| array_flow.rb:1386:5:1386:5 | b [element] : | semmle.label | b [element] : | +| array_flow.rb:1386:5:1386:5 | b [element] : | semmle.label | b [element] : | | array_flow.rb:1386:9:1386:9 | [post] a [element] : | semmle.label | [post] a [element] : | | array_flow.rb:1386:9:1386:9 | [post] a [element] : | semmle.label | [post] a [element] : | | array_flow.rb:1386:9:1386:9 | a [element 2] : | semmle.label | a [element 2] : | @@ -6534,8 +8032,12 @@ nodes | array_flow.rb:1390:10:1390:10 | a [element] : | semmle.label | a [element] : | | array_flow.rb:1390:10:1390:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:1390:10:1390:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1392:5:1392:5 | a [element 2] : | semmle.label | a [element 2] : | +| array_flow.rb:1392:5:1392:5 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:1392:16:1392:26 | call to source : | semmle.label | call to source : | | array_flow.rb:1392:16:1392:26 | call to source : | semmle.label | call to source : | +| array_flow.rb:1393:5:1393:5 | b [element] : | semmle.label | b [element] : | +| array_flow.rb:1393:5:1393:5 | b [element] : | semmle.label | b [element] : | | array_flow.rb:1393:9:1393:9 | [post] a [element] : | semmle.label | [post] a [element] : | | array_flow.rb:1393:9:1393:9 | [post] a [element] : | semmle.label | [post] a [element] : | | array_flow.rb:1393:9:1393:9 | a [element 2] : | semmle.label | a [element 2] : | @@ -6566,8 +8068,12 @@ nodes | array_flow.rb:1401:10:1401:10 | a [element] : | semmle.label | a [element] : | | array_flow.rb:1401:10:1401:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:1401:10:1401:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1405:5:1405:5 | a [element 2] : | semmle.label | a [element 2] : | +| array_flow.rb:1405:5:1405:5 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:1405:16:1405:26 | call to source : | semmle.label | call to source : | | array_flow.rb:1405:16:1405:26 | call to source : | semmle.label | call to source : | +| array_flow.rb:1406:5:1406:5 | b [element] : | semmle.label | b [element] : | +| array_flow.rb:1406:5:1406:5 | b [element] : | semmle.label | b [element] : | | array_flow.rb:1406:9:1406:9 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:1406:9:1406:9 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:1406:9:1409:7 | call to sort_by [element] : | semmle.label | call to sort_by [element] : | @@ -6584,8 +8090,12 @@ nodes | array_flow.rb:1411:10:1411:10 | b [element] : | semmle.label | b [element] : | | array_flow.rb:1411:10:1411:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:1411:10:1411:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1415:5:1415:5 | a [element 2] : | semmle.label | a [element 2] : | +| array_flow.rb:1415:5:1415:5 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:1415:16:1415:26 | call to source : | semmle.label | call to source : | | array_flow.rb:1415:16:1415:26 | call to source : | semmle.label | call to source : | +| array_flow.rb:1416:5:1416:5 | b [element] : | semmle.label | b [element] : | +| array_flow.rb:1416:5:1416:5 | b [element] : | semmle.label | b [element] : | | array_flow.rb:1416:9:1416:9 | [post] a [element] : | semmle.label | [post] a [element] : | | array_flow.rb:1416:9:1416:9 | [post] a [element] : | semmle.label | [post] a [element] : | | array_flow.rb:1416:9:1416:9 | a [element 2] : | semmle.label | a [element 2] : | @@ -6612,6 +8122,8 @@ nodes | array_flow.rb:1423:10:1423:10 | b [element] : | semmle.label | b [element] : | | array_flow.rb:1423:10:1423:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:1423:10:1423:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1427:5:1427:5 | a [element 2] : | semmle.label | a [element 2] : | +| array_flow.rb:1427:5:1427:5 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:1427:16:1427:26 | call to source : | semmle.label | call to source : | | array_flow.rb:1427:16:1427:26 | call to source : | semmle.label | call to source : | | array_flow.rb:1428:9:1428:9 | a [element 2] : | semmle.label | a [element 2] : | @@ -6620,10 +8132,18 @@ nodes | array_flow.rb:1428:19:1428:19 | x : | semmle.label | x : | | array_flow.rb:1429:14:1429:14 | x | semmle.label | x | | array_flow.rb:1429:14:1429:14 | x | semmle.label | x | +| array_flow.rb:1435:5:1435:5 | a [element 2] : | semmle.label | a [element 2] : | +| array_flow.rb:1435:5:1435:5 | a [element 2] : | semmle.label | a [element 2] : | +| array_flow.rb:1435:5:1435:5 | a [element 3] : | semmle.label | a [element 3] : | +| array_flow.rb:1435:5:1435:5 | a [element 3] : | semmle.label | a [element 3] : | | array_flow.rb:1435:16:1435:28 | call to source : | semmle.label | call to source : | | array_flow.rb:1435:16:1435:28 | call to source : | semmle.label | call to source : | | array_flow.rb:1435:31:1435:43 | call to source : | semmle.label | call to source : | | array_flow.rb:1435:31:1435:43 | call to source : | semmle.label | call to source : | +| array_flow.rb:1436:5:1436:5 | b [element 2] : | semmle.label | b [element 2] : | +| array_flow.rb:1436:5:1436:5 | b [element 2] : | semmle.label | b [element 2] : | +| array_flow.rb:1436:5:1436:5 | b [element 3] : | semmle.label | b [element 3] : | +| array_flow.rb:1436:5:1436:5 | b [element 3] : | semmle.label | b [element 3] : | | array_flow.rb:1436:9:1436:9 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:1436:9:1436:9 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:1436:9:1436:9 | a [element 3] : | semmle.label | a [element 3] : | @@ -6640,6 +8160,8 @@ nodes | array_flow.rb:1440:10:1440:10 | b [element 3] : | semmle.label | b [element 3] : | | array_flow.rb:1440:10:1440:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:1440:10:1440:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1441:5:1441:5 | b [element 2] : | semmle.label | b [element 2] : | +| array_flow.rb:1441:5:1441:5 | b [element 2] : | semmle.label | b [element 2] : | | array_flow.rb:1441:9:1441:9 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:1441:9:1441:9 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:1441:9:1441:17 | call to take [element 2] : | semmle.label | call to take [element 2] : | @@ -6652,6 +8174,10 @@ nodes | array_flow.rb:1446:10:1446:10 | b [element 2] : | semmle.label | b [element 2] : | | array_flow.rb:1446:10:1446:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:1446:10:1446:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1447:5:1447:5 | b [element 2] : | semmle.label | b [element 2] : | +| array_flow.rb:1447:5:1447:5 | b [element 2] : | semmle.label | b [element 2] : | +| array_flow.rb:1447:5:1447:5 | b [element 3] : | semmle.label | b [element 3] : | +| array_flow.rb:1447:5:1447:5 | b [element 3] : | semmle.label | b [element 3] : | | array_flow.rb:1447:9:1447:9 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:1447:9:1447:9 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:1447:9:1447:9 | a [element 3] : | semmle.label | a [element 3] : | @@ -6678,6 +8204,10 @@ nodes | array_flow.rb:1453:5:1453:5 | [post] a [element] : | semmle.label | [post] a [element] : | | array_flow.rb:1453:12:1453:24 | call to source : | semmle.label | call to source : | | array_flow.rb:1453:12:1453:24 | call to source : | semmle.label | call to source : | +| array_flow.rb:1454:5:1454:5 | b [element 2] : | semmle.label | b [element 2] : | +| array_flow.rb:1454:5:1454:5 | b [element 2] : | semmle.label | b [element 2] : | +| array_flow.rb:1454:5:1454:5 | b [element] : | semmle.label | b [element] : | +| array_flow.rb:1454:5:1454:5 | b [element] : | semmle.label | b [element] : | | array_flow.rb:1454:9:1454:9 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:1454:9:1454:9 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:1454:9:1454:9 | a [element] : | semmle.label | a [element] : | @@ -6692,8 +8222,12 @@ nodes | array_flow.rb:1455:10:1455:10 | b [element] : | semmle.label | b [element] : | | array_flow.rb:1455:10:1455:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:1455:10:1455:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1459:5:1459:5 | a [element 2] : | semmle.label | a [element 2] : | +| array_flow.rb:1459:5:1459:5 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:1459:16:1459:26 | call to source : | semmle.label | call to source : | | array_flow.rb:1459:16:1459:26 | call to source : | semmle.label | call to source : | +| array_flow.rb:1460:5:1460:5 | b [element 2] : | semmle.label | b [element 2] : | +| array_flow.rb:1460:5:1460:5 | b [element 2] : | semmle.label | b [element 2] : | | array_flow.rb:1460:9:1460:9 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:1460:9:1460:9 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:1460:9:1463:7 | call to take_while [element 2] : | semmle.label | call to take_while [element 2] : | @@ -6706,8 +8240,12 @@ nodes | array_flow.rb:1466:10:1466:10 | b [element 2] : | semmle.label | b [element 2] : | | array_flow.rb:1466:10:1466:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:1466:10:1466:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1472:5:1472:5 | a [element 3] : | semmle.label | a [element 3] : | +| array_flow.rb:1472:5:1472:5 | a [element 3] : | semmle.label | a [element 3] : | | array_flow.rb:1472:19:1472:29 | call to source : | semmle.label | call to source : | | array_flow.rb:1472:19:1472:29 | call to source : | semmle.label | call to source : | +| array_flow.rb:1473:5:1473:5 | b [element 3] : | semmle.label | b [element 3] : | +| array_flow.rb:1473:5:1473:5 | b [element 3] : | semmle.label | b [element 3] : | | array_flow.rb:1473:9:1473:9 | a [element 3] : | semmle.label | a [element 3] : | | array_flow.rb:1473:9:1473:9 | a [element 3] : | semmle.label | a [element 3] : | | array_flow.rb:1473:9:1473:14 | call to to_a [element 3] : | semmle.label | call to to_a [element 3] : | @@ -6716,8 +8254,12 @@ nodes | array_flow.rb:1474:10:1474:10 | b [element 3] : | semmle.label | b [element 3] : | | array_flow.rb:1474:10:1474:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:1474:10:1474:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1478:5:1478:5 | a [element 2] : | semmle.label | a [element 2] : | +| array_flow.rb:1478:5:1478:5 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:1478:16:1478:26 | call to source : | semmle.label | call to source : | | array_flow.rb:1478:16:1478:26 | call to source : | semmle.label | call to source : | +| array_flow.rb:1479:5:1479:5 | b [element 2] : | semmle.label | b [element 2] : | +| array_flow.rb:1479:5:1479:5 | b [element 2] : | semmle.label | b [element 2] : | | array_flow.rb:1479:9:1479:9 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:1479:9:1479:9 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:1479:9:1479:16 | call to to_ary [element 2] : | semmle.label | call to to_ary [element 2] : | @@ -6726,12 +8268,24 @@ nodes | array_flow.rb:1482:10:1482:10 | b [element 2] : | semmle.label | b [element 2] : | | array_flow.rb:1482:10:1482:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:1482:10:1482:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1495:5:1495:5 | a [element 0, element 1] : | semmle.label | a [element 0, element 1] : | +| array_flow.rb:1495:5:1495:5 | a [element 0, element 1] : | semmle.label | a [element 0, element 1] : | +| array_flow.rb:1495:5:1495:5 | a [element 1, element 1] : | semmle.label | a [element 1, element 1] : | +| array_flow.rb:1495:5:1495:5 | a [element 1, element 1] : | semmle.label | a [element 1, element 1] : | +| array_flow.rb:1495:5:1495:5 | a [element 2, element 1] : | semmle.label | a [element 2, element 1] : | +| array_flow.rb:1495:5:1495:5 | a [element 2, element 1] : | semmle.label | a [element 2, element 1] : | | array_flow.rb:1495:14:1495:26 | call to source : | semmle.label | call to source : | | array_flow.rb:1495:14:1495:26 | call to source : | semmle.label | call to source : | | array_flow.rb:1495:34:1495:46 | call to source : | semmle.label | call to source : | | array_flow.rb:1495:34:1495:46 | call to source : | semmle.label | call to source : | | array_flow.rb:1495:54:1495:66 | call to source : | semmle.label | call to source : | | array_flow.rb:1495:54:1495:66 | call to source : | semmle.label | call to source : | +| array_flow.rb:1496:5:1496:5 | b [element 1, element 0] : | semmle.label | b [element 1, element 0] : | +| array_flow.rb:1496:5:1496:5 | b [element 1, element 0] : | semmle.label | b [element 1, element 0] : | +| array_flow.rb:1496:5:1496:5 | b [element 1, element 1] : | semmle.label | b [element 1, element 1] : | +| array_flow.rb:1496:5:1496:5 | b [element 1, element 1] : | semmle.label | b [element 1, element 1] : | +| array_flow.rb:1496:5:1496:5 | b [element 1, element 2] : | semmle.label | b [element 1, element 2] : | +| array_flow.rb:1496:5:1496:5 | b [element 1, element 2] : | semmle.label | b [element 1, element 2] : | | array_flow.rb:1496:9:1496:9 | a [element 0, element 1] : | semmle.label | a [element 0, element 1] : | | array_flow.rb:1496:9:1496:9 | a [element 0, element 1] : | semmle.label | a [element 0, element 1] : | | array_flow.rb:1496:9:1496:9 | a [element 1, element 1] : | semmle.label | a [element 1, element 1] : | @@ -6762,12 +8316,20 @@ nodes | array_flow.rb:1502:10:1502:13 | ...[...] [element 2] : | semmle.label | ...[...] [element 2] : | | array_flow.rb:1502:10:1502:16 | ...[...] | semmle.label | ...[...] | | array_flow.rb:1502:10:1502:16 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1506:5:1506:5 | a [element 2] : | semmle.label | a [element 2] : | +| array_flow.rb:1506:5:1506:5 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:1506:16:1506:28 | call to source : | semmle.label | call to source : | | array_flow.rb:1506:16:1506:28 | call to source : | semmle.label | call to source : | +| array_flow.rb:1507:5:1507:5 | b [element 1] : | semmle.label | b [element 1] : | +| array_flow.rb:1507:5:1507:5 | b [element 1] : | semmle.label | b [element 1] : | | array_flow.rb:1507:13:1507:25 | call to source : | semmle.label | call to source : | | array_flow.rb:1507:13:1507:25 | call to source : | semmle.label | call to source : | +| array_flow.rb:1508:5:1508:5 | c [element 1] : | semmle.label | c [element 1] : | +| array_flow.rb:1508:5:1508:5 | c [element 1] : | semmle.label | c [element 1] : | | array_flow.rb:1508:13:1508:25 | call to source : | semmle.label | call to source : | | array_flow.rb:1508:13:1508:25 | call to source : | semmle.label | call to source : | +| array_flow.rb:1509:5:1509:5 | d [element] : | semmle.label | d [element] : | +| array_flow.rb:1509:5:1509:5 | d [element] : | semmle.label | d [element] : | | array_flow.rb:1509:9:1509:9 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:1509:9:1509:9 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:1509:9:1509:21 | call to union [element] : | semmle.label | call to union [element] : | @@ -6788,10 +8350,16 @@ nodes | array_flow.rb:1512:10:1512:10 | d [element] : | semmle.label | d [element] : | | array_flow.rb:1512:10:1512:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:1512:10:1512:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1516:5:1516:5 | a [element 3] : | semmle.label | a [element 3] : | +| array_flow.rb:1516:5:1516:5 | a [element 3] : | semmle.label | a [element 3] : | +| array_flow.rb:1516:5:1516:5 | a [element 4] : | semmle.label | a [element 4] : | +| array_flow.rb:1516:5:1516:5 | a [element 4] : | semmle.label | a [element 4] : | | array_flow.rb:1516:19:1516:31 | call to source : | semmle.label | call to source : | | array_flow.rb:1516:19:1516:31 | call to source : | semmle.label | call to source : | | array_flow.rb:1516:34:1516:46 | call to source : | semmle.label | call to source : | | array_flow.rb:1516:34:1516:46 | call to source : | semmle.label | call to source : | +| array_flow.rb:1518:5:1518:5 | b [element] : | semmle.label | b [element] : | +| array_flow.rb:1518:5:1518:5 | b [element] : | semmle.label | b [element] : | | array_flow.rb:1518:9:1518:9 | a [element 3] : | semmle.label | a [element 3] : | | array_flow.rb:1518:9:1518:9 | a [element 3] : | semmle.label | a [element 3] : | | array_flow.rb:1518:9:1518:9 | a [element 4] : | semmle.label | a [element 4] : | @@ -6806,6 +8374,8 @@ nodes | array_flow.rb:1520:10:1520:10 | b [element] : | semmle.label | b [element] : | | array_flow.rb:1520:10:1520:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:1520:10:1520:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1522:5:1522:5 | c [element] : | semmle.label | c [element] : | +| array_flow.rb:1522:5:1522:5 | c [element] : | semmle.label | c [element] : | | array_flow.rb:1522:9:1522:9 | a [element 3] : | semmle.label | a [element 3] : | | array_flow.rb:1522:9:1522:9 | a [element 3] : | semmle.label | a [element 3] : | | array_flow.rb:1522:9:1522:9 | a [element 4] : | semmle.label | a [element 4] : | @@ -6820,10 +8390,16 @@ nodes | array_flow.rb:1526:10:1526:10 | c [element] : | semmle.label | c [element] : | | array_flow.rb:1526:10:1526:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:1526:10:1526:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1530:5:1530:5 | a [element 2] : | semmle.label | a [element 2] : | +| array_flow.rb:1530:5:1530:5 | a [element 2] : | semmle.label | a [element 2] : | +| array_flow.rb:1530:5:1530:5 | a [element 3] : | semmle.label | a [element 3] : | +| array_flow.rb:1530:5:1530:5 | a [element 3] : | semmle.label | a [element 3] : | | array_flow.rb:1530:16:1530:28 | call to source : | semmle.label | call to source : | | array_flow.rb:1530:16:1530:28 | call to source : | semmle.label | call to source : | | array_flow.rb:1530:31:1530:43 | call to source : | semmle.label | call to source : | | array_flow.rb:1530:31:1530:43 | call to source : | semmle.label | call to source : | +| array_flow.rb:1531:5:1531:5 | b [element] : | semmle.label | b [element] : | +| array_flow.rb:1531:5:1531:5 | b [element] : | semmle.label | b [element] : | | array_flow.rb:1531:9:1531:9 | [post] a [element] : | semmle.label | [post] a [element] : | | array_flow.rb:1531:9:1531:9 | [post] a [element] : | semmle.label | [post] a [element] : | | array_flow.rb:1531:9:1531:9 | a [element 2] : | semmle.label | a [element 2] : | @@ -6848,10 +8424,16 @@ nodes | array_flow.rb:1535:10:1535:10 | a [element] : | semmle.label | a [element] : | | array_flow.rb:1535:10:1535:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:1535:10:1535:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1537:5:1537:5 | a [element 2] : | semmle.label | a [element 2] : | +| array_flow.rb:1537:5:1537:5 | a [element 2] : | semmle.label | a [element 2] : | +| array_flow.rb:1537:5:1537:5 | a [element 3] : | semmle.label | a [element 3] : | +| array_flow.rb:1537:5:1537:5 | a [element 3] : | semmle.label | a [element 3] : | | array_flow.rb:1537:16:1537:28 | call to source : | semmle.label | call to source : | | array_flow.rb:1537:16:1537:28 | call to source : | semmle.label | call to source : | | array_flow.rb:1537:31:1537:43 | call to source : | semmle.label | call to source : | | array_flow.rb:1537:31:1537:43 | call to source : | semmle.label | call to source : | +| array_flow.rb:1538:5:1538:5 | b [element] : | semmle.label | b [element] : | +| array_flow.rb:1538:5:1538:5 | b [element] : | semmle.label | b [element] : | | array_flow.rb:1538:9:1538:9 | [post] a [element] : | semmle.label | [post] a [element] : | | array_flow.rb:1538:9:1538:9 | [post] a [element] : | semmle.label | [post] a [element] : | | array_flow.rb:1538:9:1538:9 | a [element 2] : | semmle.label | a [element 2] : | @@ -6880,6 +8462,8 @@ nodes | array_flow.rb:1545:10:1545:10 | a [element] : | semmle.label | a [element] : | | array_flow.rb:1545:10:1545:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:1545:10:1545:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1549:5:1549:5 | a [element 2] : | semmle.label | a [element 2] : | +| array_flow.rb:1549:5:1549:5 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:1549:16:1549:28 | call to source : | semmle.label | call to source : | | array_flow.rb:1549:16:1549:28 | call to source : | semmle.label | call to source : | | array_flow.rb:1550:5:1550:5 | [post] a [element 2] : | semmle.label | [post] a [element 2] : | @@ -6898,10 +8482,18 @@ nodes | array_flow.rb:1556:10:1556:10 | a [element 5] : | semmle.label | a [element 5] : | | array_flow.rb:1556:10:1556:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:1556:10:1556:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1560:5:1560:5 | a [element 1] : | semmle.label | a [element 1] : | +| array_flow.rb:1560:5:1560:5 | a [element 1] : | semmle.label | a [element 1] : | +| array_flow.rb:1560:5:1560:5 | a [element 3] : | semmle.label | a [element 3] : | +| array_flow.rb:1560:5:1560:5 | a [element 3] : | semmle.label | a [element 3] : | | array_flow.rb:1560:13:1560:25 | call to source : | semmle.label | call to source : | | array_flow.rb:1560:13:1560:25 | call to source : | semmle.label | call to source : | | array_flow.rb:1560:31:1560:43 | call to source : | semmle.label | call to source : | | array_flow.rb:1560:31:1560:43 | call to source : | semmle.label | call to source : | +| array_flow.rb:1562:5:1562:5 | b [element 1] : | semmle.label | b [element 1] : | +| array_flow.rb:1562:5:1562:5 | b [element 1] : | semmle.label | b [element 1] : | +| array_flow.rb:1562:5:1562:5 | b [element 3] : | semmle.label | b [element 3] : | +| array_flow.rb:1562:5:1562:5 | b [element 3] : | semmle.label | b [element 3] : | | array_flow.rb:1562:9:1562:9 | a [element 1] : | semmle.label | a [element 1] : | | array_flow.rb:1562:9:1562:9 | a [element 1] : | semmle.label | a [element 1] : | | array_flow.rb:1562:9:1562:31 | call to values_at [element 1] : | semmle.label | call to values_at [element 1] : | @@ -6916,6 +8508,8 @@ nodes | array_flow.rb:1566:10:1566:10 | b [element 3] : | semmle.label | b [element 3] : | | array_flow.rb:1566:10:1566:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:1566:10:1566:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1568:5:1568:5 | b [element] : | semmle.label | b [element] : | +| array_flow.rb:1568:5:1568:5 | b [element] : | semmle.label | b [element] : | | array_flow.rb:1568:9:1568:9 | a [element 1] : | semmle.label | a [element 1] : | | array_flow.rb:1568:9:1568:9 | a [element 1] : | semmle.label | a [element 1] : | | array_flow.rb:1568:9:1568:9 | a [element 3] : | semmle.label | a [element 3] : | @@ -6930,6 +8524,8 @@ nodes | array_flow.rb:1570:10:1570:10 | b [element] : | semmle.label | b [element] : | | array_flow.rb:1570:10:1570:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:1570:10:1570:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1572:5:1572:5 | b [element] : | semmle.label | b [element] : | +| array_flow.rb:1572:5:1572:5 | b [element] : | semmle.label | b [element] : | | array_flow.rb:1572:9:1572:9 | a [element 1] : | semmle.label | a [element 1] : | | array_flow.rb:1572:9:1572:9 | a [element 1] : | semmle.label | a [element 1] : | | array_flow.rb:1572:9:1572:9 | a [element 3] : | semmle.label | a [element 3] : | @@ -6944,6 +8540,10 @@ nodes | array_flow.rb:1574:10:1574:10 | b [element] : | semmle.label | b [element] : | | array_flow.rb:1574:10:1574:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:1574:10:1574:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1576:5:1576:5 | b [element 1] : | semmle.label | b [element 1] : | +| array_flow.rb:1576:5:1576:5 | b [element 1] : | semmle.label | b [element 1] : | +| array_flow.rb:1576:5:1576:5 | b [element] : | semmle.label | b [element] : | +| array_flow.rb:1576:5:1576:5 | b [element] : | semmle.label | b [element] : | | array_flow.rb:1576:9:1576:9 | a [element 1] : | semmle.label | a [element 1] : | | array_flow.rb:1576:9:1576:9 | a [element 1] : | semmle.label | a [element 1] : | | array_flow.rb:1576:9:1576:9 | a [element 3] : | semmle.label | a [element 3] : | @@ -6970,12 +8570,24 @@ nodes | array_flow.rb:1580:10:1580:10 | b [element] : | semmle.label | b [element] : | | array_flow.rb:1580:10:1580:13 | ...[...] | semmle.label | ...[...] | | array_flow.rb:1580:10:1580:13 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1584:5:1584:5 | a [element 2] : | semmle.label | a [element 2] : | +| array_flow.rb:1584:5:1584:5 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:1584:16:1584:28 | call to source : | semmle.label | call to source : | | array_flow.rb:1584:16:1584:28 | call to source : | semmle.label | call to source : | +| array_flow.rb:1585:5:1585:5 | b [element 1] : | semmle.label | b [element 1] : | +| array_flow.rb:1585:5:1585:5 | b [element 1] : | semmle.label | b [element 1] : | | array_flow.rb:1585:13:1585:25 | call to source : | semmle.label | call to source : | | array_flow.rb:1585:13:1585:25 | call to source : | semmle.label | call to source : | +| array_flow.rb:1586:5:1586:5 | c [element 0] : | semmle.label | c [element 0] : | +| array_flow.rb:1586:5:1586:5 | c [element 0] : | semmle.label | c [element 0] : | | array_flow.rb:1586:10:1586:22 | call to source : | semmle.label | call to source : | | array_flow.rb:1586:10:1586:22 | call to source : | semmle.label | call to source : | +| array_flow.rb:1587:5:1587:5 | d [element 0, element 2] : | semmle.label | d [element 0, element 2] : | +| array_flow.rb:1587:5:1587:5 | d [element 0, element 2] : | semmle.label | d [element 0, element 2] : | +| array_flow.rb:1587:5:1587:5 | d [element 1, element 1] : | semmle.label | d [element 1, element 1] : | +| array_flow.rb:1587:5:1587:5 | d [element 1, element 1] : | semmle.label | d [element 1, element 1] : | +| array_flow.rb:1587:5:1587:5 | d [element 2, element 0] : | semmle.label | d [element 2, element 0] : | +| array_flow.rb:1587:5:1587:5 | d [element 2, element 0] : | semmle.label | d [element 2, element 0] : | | array_flow.rb:1587:9:1587:9 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:1587:9:1587:9 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:1587:9:1587:19 | call to zip [element 0, element 2] : | semmle.label | call to zip [element 0, element 2] : | @@ -7030,10 +8642,16 @@ nodes | array_flow.rb:1595:14:1595:14 | x [element 2] : | semmle.label | x [element 2] : | | array_flow.rb:1595:14:1595:17 | ...[...] | semmle.label | ...[...] | | array_flow.rb:1595:14:1595:17 | ...[...] | semmle.label | ...[...] | +| array_flow.rb:1600:5:1600:5 | a [element 2] : | semmle.label | a [element 2] : | +| array_flow.rb:1600:5:1600:5 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:1600:16:1600:28 | call to source : | semmle.label | call to source : | | array_flow.rb:1600:16:1600:28 | call to source : | semmle.label | call to source : | +| array_flow.rb:1601:5:1601:5 | b [element 1] : | semmle.label | b [element 1] : | +| array_flow.rb:1601:5:1601:5 | b [element 1] : | semmle.label | b [element 1] : | | array_flow.rb:1601:13:1601:25 | call to source : | semmle.label | call to source : | | array_flow.rb:1601:13:1601:25 | call to source : | semmle.label | call to source : | +| array_flow.rb:1602:5:1602:5 | c [element] : | semmle.label | c [element] : | +| array_flow.rb:1602:5:1602:5 | c [element] : | semmle.label | c [element] : | | array_flow.rb:1602:9:1602:9 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:1602:9:1602:9 | a [element 2] : | semmle.label | a [element 2] : | | array_flow.rb:1602:9:1602:13 | ... \| ... [element] : | semmle.label | ... \| ... [element] : | diff --git a/ruby/ql/test/library-tests/dataflow/flow-summaries/semantics.expected b/ruby/ql/test/library-tests/dataflow/flow-summaries/semantics.expected index 4ef45d2ae92..db759c1f86a 100644 --- a/ruby/ql/test/library-tests/dataflow/flow-summaries/semantics.expected +++ b/ruby/ql/test/library-tests/dataflow/flow-summaries/semantics.expected @@ -1,19 +1,27 @@ failures edges -| semantics.rb:2:9:2:18 | call to source : | semantics.rb:3:9:3:9 | a : | -| semantics.rb:2:9:2:18 | call to source : | semantics.rb:3:9:3:9 | a : | +| semantics.rb:2:5:2:5 | a : | semantics.rb:3:9:3:9 | a : | +| semantics.rb:2:5:2:5 | a : | semantics.rb:3:9:3:9 | a : | +| semantics.rb:2:9:2:18 | call to source : | semantics.rb:2:5:2:5 | a : | +| semantics.rb:2:9:2:18 | call to source : | semantics.rb:2:5:2:5 | a : | +| semantics.rb:3:5:3:5 | x : | semantics.rb:4:10:4:10 | x | +| semantics.rb:3:5:3:5 | x : | semantics.rb:4:10:4:10 | x | | semantics.rb:3:9:3:9 | a : | semantics.rb:3:9:3:14 | call to s1 : | | semantics.rb:3:9:3:9 | a : | semantics.rb:3:9:3:14 | call to s1 : | -| semantics.rb:3:9:3:14 | call to s1 : | semantics.rb:4:10:4:10 | x | -| semantics.rb:3:9:3:14 | call to s1 : | semantics.rb:4:10:4:10 | x | -| semantics.rb:8:9:8:18 | call to source : | semantics.rb:9:10:9:10 | a : | -| semantics.rb:8:9:8:18 | call to source : | semantics.rb:9:10:9:10 | a : | +| semantics.rb:3:9:3:14 | call to s1 : | semantics.rb:3:5:3:5 | x : | +| semantics.rb:3:9:3:14 | call to s1 : | semantics.rb:3:5:3:5 | x : | +| semantics.rb:8:5:8:5 | a : | semantics.rb:9:10:9:10 | a : | +| semantics.rb:8:5:8:5 | a : | semantics.rb:9:10:9:10 | a : | +| semantics.rb:8:9:8:18 | call to source : | semantics.rb:8:5:8:5 | a : | +| semantics.rb:8:9:8:18 | call to source : | semantics.rb:8:5:8:5 | a : | | semantics.rb:9:5:9:5 | [post] x : | semantics.rb:10:10:10:10 | x | | semantics.rb:9:5:9:5 | [post] x : | semantics.rb:10:10:10:10 | x | | semantics.rb:9:10:9:10 | a : | semantics.rb:9:5:9:5 | [post] x : | | semantics.rb:9:10:9:10 | a : | semantics.rb:9:5:9:5 | [post] x : | -| semantics.rb:14:9:14:18 | call to source : | semantics.rb:15:8:15:8 | a : | -| semantics.rb:14:9:14:18 | call to source : | semantics.rb:15:8:15:8 | a : | +| semantics.rb:14:5:14:5 | a : | semantics.rb:15:8:15:8 | a : | +| semantics.rb:14:5:14:5 | a : | semantics.rb:15:8:15:8 | a : | +| semantics.rb:14:9:14:18 | call to source : | semantics.rb:14:5:14:5 | a : | +| semantics.rb:14:9:14:18 | call to source : | semantics.rb:14:5:14:5 | a : | | semantics.rb:15:8:15:8 | a : | semantics.rb:15:11:15:11 | [post] x : | | semantics.rb:15:8:15:8 | a : | semantics.rb:15:11:15:11 | [post] x : | | semantics.rb:15:11:15:11 | [post] x : | semantics.rb:16:10:16:10 | x | @@ -22,8 +30,10 @@ edges | semantics.rb:22:18:22:32 | call to source : | semantics.rb:22:10:22:33 | call to s4 | | semantics.rb:23:23:23:32 | call to source : | semantics.rb:23:10:23:33 | call to s4 | | semantics.rb:23:23:23:32 | call to source : | semantics.rb:23:10:23:33 | call to s4 | -| semantics.rb:28:9:28:18 | call to source : | semantics.rb:29:8:29:8 | a : | -| semantics.rb:28:9:28:18 | call to source : | semantics.rb:29:8:29:8 | a : | +| semantics.rb:28:5:28:5 | a : | semantics.rb:29:8:29:8 | a : | +| semantics.rb:28:5:28:5 | a : | semantics.rb:29:8:29:8 | a : | +| semantics.rb:28:9:28:18 | call to source : | semantics.rb:28:5:28:5 | a : | +| semantics.rb:28:9:28:18 | call to source : | semantics.rb:28:5:28:5 | a : | | semantics.rb:29:8:29:8 | a : | semantics.rb:29:14:29:14 | [post] y : | | semantics.rb:29:8:29:8 | a : | semantics.rb:29:14:29:14 | [post] y : | | semantics.rb:29:8:29:8 | a : | semantics.rb:29:17:29:17 | [post] z : | @@ -32,8 +42,10 @@ edges | semantics.rb:29:14:29:14 | [post] y : | semantics.rb:31:10:31:10 | y | | semantics.rb:29:17:29:17 | [post] z : | semantics.rb:32:10:32:10 | z | | semantics.rb:29:17:29:17 | [post] z : | semantics.rb:32:10:32:10 | z | -| semantics.rb:40:9:40:18 | call to source : | semantics.rb:41:8:41:8 | a : | -| semantics.rb:40:9:40:18 | call to source : | semantics.rb:41:8:41:8 | a : | +| semantics.rb:40:5:40:5 | a : | semantics.rb:41:8:41:8 | a : | +| semantics.rb:40:5:40:5 | a : | semantics.rb:41:8:41:8 | a : | +| semantics.rb:40:9:40:18 | call to source : | semantics.rb:40:5:40:5 | a : | +| semantics.rb:40:9:40:18 | call to source : | semantics.rb:40:5:40:5 | a : | | semantics.rb:41:8:41:8 | a : | semantics.rb:41:16:41:16 | [post] x : | | semantics.rb:41:8:41:8 | a : | semantics.rb:41:16:41:16 | [post] x : | | semantics.rb:41:16:41:16 | [post] x : | semantics.rb:42:10:42:10 | x | @@ -50,16 +62,18 @@ edges | semantics.rb:54:8:54:17 | call to source : | semantics.rb:54:24:54:24 | x : | | semantics.rb:54:24:54:24 | x : | semantics.rb:55:14:55:14 | x | | semantics.rb:54:24:54:24 | x : | semantics.rb:55:14:55:14 | x | -| semantics.rb:60:9:60:18 | call to source : | semantics.rb:61:14:61:14 | a : | -| semantics.rb:60:9:60:18 | call to source : | semantics.rb:61:14:61:14 | a : | -| semantics.rb:60:9:60:18 | call to source : | semantics.rb:62:17:62:17 | a : | -| semantics.rb:60:9:60:18 | call to source : | semantics.rb:62:17:62:17 | a : | -| semantics.rb:60:9:60:18 | call to source : | semantics.rb:63:19:63:19 | a : | -| semantics.rb:60:9:60:18 | call to source : | semantics.rb:63:19:63:19 | a : | -| semantics.rb:60:9:60:18 | call to source : | semantics.rb:64:27:64:27 | a : | -| semantics.rb:60:9:60:18 | call to source : | semantics.rb:64:27:64:27 | a : | -| semantics.rb:60:9:60:18 | call to source : | semantics.rb:66:14:66:15 | &... : | -| semantics.rb:60:9:60:18 | call to source : | semantics.rb:66:14:66:15 | &... : | +| semantics.rb:60:5:60:5 | a : | semantics.rb:61:14:61:14 | a : | +| semantics.rb:60:5:60:5 | a : | semantics.rb:61:14:61:14 | a : | +| semantics.rb:60:5:60:5 | a : | semantics.rb:62:17:62:17 | a : | +| semantics.rb:60:5:60:5 | a : | semantics.rb:62:17:62:17 | a : | +| semantics.rb:60:5:60:5 | a : | semantics.rb:63:19:63:19 | a : | +| semantics.rb:60:5:60:5 | a : | semantics.rb:63:19:63:19 | a : | +| semantics.rb:60:5:60:5 | a : | semantics.rb:64:27:64:27 | a : | +| semantics.rb:60:5:60:5 | a : | semantics.rb:64:27:64:27 | a : | +| semantics.rb:60:5:60:5 | a : | semantics.rb:66:14:66:15 | &... : | +| semantics.rb:60:5:60:5 | a : | semantics.rb:66:14:66:15 | &... : | +| semantics.rb:60:9:60:18 | call to source : | semantics.rb:60:5:60:5 | a : | +| semantics.rb:60:9:60:18 | call to source : | semantics.rb:60:5:60:5 | a : | | semantics.rb:61:14:61:14 | a : | semantics.rb:61:10:61:15 | call to s10 | | semantics.rb:61:14:61:14 | a : | semantics.rb:61:10:61:15 | call to s10 | | semantics.rb:62:17:62:17 | a : | semantics.rb:62:10:62:18 | call to s10 | @@ -70,8 +84,10 @@ edges | semantics.rb:64:27:64:27 | a : | semantics.rb:64:10:64:28 | call to s10 | | semantics.rb:66:14:66:15 | &... : | semantics.rb:66:10:66:16 | call to s10 | | semantics.rb:66:14:66:15 | &... : | semantics.rb:66:10:66:16 | call to s10 | -| semantics.rb:80:9:80:18 | call to source : | semantics.rb:81:5:81:5 | a : | -| semantics.rb:80:9:80:18 | call to source : | semantics.rb:81:5:81:5 | a : | +| semantics.rb:80:5:80:5 | a : | semantics.rb:81:5:81:5 | a : | +| semantics.rb:80:5:80:5 | a : | semantics.rb:81:5:81:5 | a : | +| semantics.rb:80:9:80:18 | call to source : | semantics.rb:80:5:80:5 | a : | +| semantics.rb:80:9:80:18 | call to source : | semantics.rb:80:5:80:5 | a : | | semantics.rb:81:5:81:5 | a : | semantics.rb:81:11:81:11 | [post] x : | | semantics.rb:81:5:81:5 | a : | semantics.rb:81:11:81:11 | [post] x : | | semantics.rb:81:5:81:5 | a : | semantics.rb:81:14:81:14 | [post] y : | @@ -84,18 +100,22 @@ edges | semantics.rb:81:14:81:14 | [post] y : | semantics.rb:83:10:83:10 | y | | semantics.rb:81:22:81:22 | [post] z : | semantics.rb:84:10:84:10 | z | | semantics.rb:81:22:81:22 | [post] z : | semantics.rb:84:10:84:10 | z | -| semantics.rb:89:9:89:18 | call to source : | semantics.rb:91:19:91:19 | a : | -| semantics.rb:89:9:89:18 | call to source : | semantics.rb:91:19:91:19 | a : | -| semantics.rb:89:9:89:18 | call to source : | semantics.rb:92:27:92:27 | a : | -| semantics.rb:89:9:89:18 | call to source : | semantics.rb:92:27:92:27 | a : | +| semantics.rb:89:5:89:5 | a : | semantics.rb:91:19:91:19 | a : | +| semantics.rb:89:5:89:5 | a : | semantics.rb:91:19:91:19 | a : | +| semantics.rb:89:5:89:5 | a : | semantics.rb:92:27:92:27 | a : | +| semantics.rb:89:5:89:5 | a : | semantics.rb:92:27:92:27 | a : | +| semantics.rb:89:9:89:18 | call to source : | semantics.rb:89:5:89:5 | a : | +| semantics.rb:89:9:89:18 | call to source : | semantics.rb:89:5:89:5 | a : | | semantics.rb:91:19:91:19 | a : | semantics.rb:91:10:91:20 | call to s13 | | semantics.rb:91:19:91:19 | a : | semantics.rb:91:10:91:20 | call to s13 | | semantics.rb:92:27:92:27 | a : | semantics.rb:92:10:92:28 | call to s13 | | semantics.rb:92:27:92:27 | a : | semantics.rb:92:10:92:28 | call to s13 | -| semantics.rb:97:9:97:18 | call to source : | semantics.rb:98:5:98:5 | a : | -| semantics.rb:97:9:97:18 | call to source : | semantics.rb:98:5:98:5 | a : | -| semantics.rb:97:9:97:18 | call to source : | semantics.rb:99:5:99:5 | a : | -| semantics.rb:97:9:97:18 | call to source : | semantics.rb:99:5:99:5 | a : | +| semantics.rb:97:5:97:5 | a : | semantics.rb:98:5:98:5 | a : | +| semantics.rb:97:5:97:5 | a : | semantics.rb:98:5:98:5 | a : | +| semantics.rb:97:5:97:5 | a : | semantics.rb:99:5:99:5 | a : | +| semantics.rb:97:5:97:5 | a : | semantics.rb:99:5:99:5 | a : | +| semantics.rb:97:9:97:18 | call to source : | semantics.rb:97:5:97:5 | a : | +| semantics.rb:97:9:97:18 | call to source : | semantics.rb:97:5:97:5 | a : | | semantics.rb:98:5:98:5 | a : | semantics.rb:98:19:98:19 | [post] x : | | semantics.rb:98:5:98:5 | a : | semantics.rb:98:19:98:19 | [post] x : | | semantics.rb:98:19:98:19 | [post] x : | semantics.rb:101:10:101:10 | x | @@ -108,20 +128,27 @@ edges | semantics.rb:99:16:99:16 | [post] y : | semantics.rb:102:10:102:10 | y | | semantics.rb:99:24:99:24 | [post] z : | semantics.rb:103:10:103:10 | z | | semantics.rb:99:24:99:24 | [post] z : | semantics.rb:103:10:103:10 | z | -| semantics.rb:107:9:107:18 | call to source : | semantics.rb:109:14:109:16 | ** ... : | -| semantics.rb:107:9:107:18 | call to source : | semantics.rb:110:28:110:30 | ** ... : | +| semantics.rb:107:5:107:5 | a : | semantics.rb:109:14:109:16 | ** ... : | +| semantics.rb:107:5:107:5 | a : | semantics.rb:110:28:110:30 | ** ... : | +| semantics.rb:107:9:107:18 | call to source : | semantics.rb:107:5:107:5 | a : | | semantics.rb:109:14:109:16 | ** ... : | semantics.rb:109:10:109:17 | call to s15 | | semantics.rb:110:28:110:30 | ** ... : | semantics.rb:110:10:110:31 | call to s15 | -| semantics.rb:114:9:114:18 | call to source : | semantics.rb:116:14:116:14 | a : | -| semantics.rb:114:9:114:18 | call to source : | semantics.rb:116:14:116:14 | a : | -| semantics.rb:114:9:114:18 | call to source : | semantics.rb:119:17:119:17 | a : | -| semantics.rb:114:9:114:18 | call to source : | semantics.rb:119:17:119:17 | a : | -| semantics.rb:115:9:115:18 | call to source : | semantics.rb:121:17:121:17 | b : | -| semantics.rb:115:9:115:18 | call to source : | semantics.rb:121:17:121:17 | b : | -| semantics.rb:116:14:116:14 | a : | semantics.rb:117:16:117:16 | h [element :a] : | -| semantics.rb:116:14:116:14 | a : | semantics.rb:117:16:117:16 | h [element :a] : | -| semantics.rb:116:14:116:14 | a : | semantics.rb:121:22:121:22 | h [element :a] : | -| semantics.rb:116:14:116:14 | a : | semantics.rb:121:22:121:22 | h [element :a] : | +| semantics.rb:114:5:114:5 | a : | semantics.rb:116:14:116:14 | a : | +| semantics.rb:114:5:114:5 | a : | semantics.rb:116:14:116:14 | a : | +| semantics.rb:114:5:114:5 | a : | semantics.rb:119:17:119:17 | a : | +| semantics.rb:114:5:114:5 | a : | semantics.rb:119:17:119:17 | a : | +| semantics.rb:114:9:114:18 | call to source : | semantics.rb:114:5:114:5 | a : | +| semantics.rb:114:9:114:18 | call to source : | semantics.rb:114:5:114:5 | a : | +| semantics.rb:115:5:115:5 | b : | semantics.rb:121:17:121:17 | b : | +| semantics.rb:115:5:115:5 | b : | semantics.rb:121:17:121:17 | b : | +| semantics.rb:115:9:115:18 | call to source : | semantics.rb:115:5:115:5 | b : | +| semantics.rb:115:9:115:18 | call to source : | semantics.rb:115:5:115:5 | b : | +| semantics.rb:116:5:116:5 | h [element :a] : | semantics.rb:117:16:117:16 | h [element :a] : | +| semantics.rb:116:5:116:5 | h [element :a] : | semantics.rb:117:16:117:16 | h [element :a] : | +| semantics.rb:116:5:116:5 | h [element :a] : | semantics.rb:121:22:121:22 | h [element :a] : | +| semantics.rb:116:5:116:5 | h [element :a] : | semantics.rb:121:22:121:22 | h [element :a] : | +| semantics.rb:116:14:116:14 | a : | semantics.rb:116:5:116:5 | h [element :a] : | +| semantics.rb:116:14:116:14 | a : | semantics.rb:116:5:116:5 | h [element :a] : | | semantics.rb:117:14:117:16 | ** ... [element :a] : | semantics.rb:117:10:117:17 | call to s16 | | semantics.rb:117:14:117:16 | ** ... [element :a] : | semantics.rb:117:10:117:17 | call to s16 | | semantics.rb:117:16:117:16 | h [element :a] : | semantics.rb:117:14:117:16 | ** ... [element :a] : | @@ -134,34 +161,46 @@ edges | semantics.rb:121:20:121:22 | ** ... [element :a] : | semantics.rb:121:10:121:23 | call to s16 | | semantics.rb:121:22:121:22 | h [element :a] : | semantics.rb:121:20:121:22 | ** ... [element :a] : | | semantics.rb:121:22:121:22 | h [element :a] : | semantics.rb:121:20:121:22 | ** ... [element :a] : | -| semantics.rb:125:9:125:18 | call to source : | semantics.rb:126:9:126:9 | a : | -| semantics.rb:125:9:125:18 | call to source : | semantics.rb:126:9:126:9 | a : | +| semantics.rb:125:5:125:5 | a : | semantics.rb:126:9:126:9 | a : | +| semantics.rb:125:5:125:5 | a : | semantics.rb:126:9:126:9 | a : | +| semantics.rb:125:9:125:18 | call to source : | semantics.rb:125:5:125:5 | a : | +| semantics.rb:125:9:125:18 | call to source : | semantics.rb:125:5:125:5 | a : | | semantics.rb:126:9:126:9 | a : | semantics.rb:126:12:126:14 | [post] ** ... : | | semantics.rb:126:9:126:9 | a : | semantics.rb:126:12:126:14 | [post] ** ... : | | semantics.rb:126:12:126:14 | [post] ** ... : | semantics.rb:127:10:127:10 | h | | semantics.rb:126:12:126:14 | [post] ** ... : | semantics.rb:127:10:127:10 | h | -| semantics.rb:141:9:141:18 | call to source : | semantics.rb:145:5:145:5 | [post] h [element] : | -| semantics.rb:141:9:141:18 | call to source : | semantics.rb:145:5:145:5 | [post] h [element] : | +| semantics.rb:141:5:141:5 | b : | semantics.rb:145:5:145:5 | [post] h [element] : | +| semantics.rb:141:5:141:5 | b : | semantics.rb:145:5:145:5 | [post] h [element] : | +| semantics.rb:141:9:141:18 | call to source : | semantics.rb:141:5:141:5 | b : | +| semantics.rb:141:9:141:18 | call to source : | semantics.rb:141:5:141:5 | b : | | semantics.rb:145:5:145:5 | [post] h [element] : | semantics.rb:147:14:147:14 | h [element] : | | semantics.rb:145:5:145:5 | [post] h [element] : | semantics.rb:147:14:147:14 | h [element] : | | semantics.rb:147:14:147:14 | h [element] : | semantics.rb:147:10:147:15 | call to s19 | | semantics.rb:147:14:147:14 | h [element] : | semantics.rb:147:10:147:15 | call to s19 | -| semantics.rb:151:9:151:18 | call to source : | semantics.rb:152:13:152:13 | a : | -| semantics.rb:151:9:151:18 | call to source : | semantics.rb:152:13:152:13 | a : | -| semantics.rb:152:9:152:14 | call to s20 [element] : | semantics.rb:153:10:153:10 | x [element] : | -| semantics.rb:152:9:152:14 | call to s20 [element] : | semantics.rb:153:10:153:10 | x [element] : | -| semantics.rb:152:9:152:14 | call to s20 [element] : | semantics.rb:154:10:154:10 | x [element] : | -| semantics.rb:152:9:152:14 | call to s20 [element] : | semantics.rb:154:10:154:10 | x [element] : | +| semantics.rb:151:5:151:5 | a : | semantics.rb:152:13:152:13 | a : | +| semantics.rb:151:5:151:5 | a : | semantics.rb:152:13:152:13 | a : | +| semantics.rb:151:9:151:18 | call to source : | semantics.rb:151:5:151:5 | a : | +| semantics.rb:151:9:151:18 | call to source : | semantics.rb:151:5:151:5 | a : | +| semantics.rb:152:5:152:5 | x [element] : | semantics.rb:153:10:153:10 | x [element] : | +| semantics.rb:152:5:152:5 | x [element] : | semantics.rb:153:10:153:10 | x [element] : | +| semantics.rb:152:5:152:5 | x [element] : | semantics.rb:154:10:154:10 | x [element] : | +| semantics.rb:152:5:152:5 | x [element] : | semantics.rb:154:10:154:10 | x [element] : | +| semantics.rb:152:9:152:14 | call to s20 [element] : | semantics.rb:152:5:152:5 | x [element] : | +| semantics.rb:152:9:152:14 | call to s20 [element] : | semantics.rb:152:5:152:5 | x [element] : | | semantics.rb:152:13:152:13 | a : | semantics.rb:152:9:152:14 | call to s20 [element] : | | semantics.rb:152:13:152:13 | a : | semantics.rb:152:9:152:14 | call to s20 [element] : | | semantics.rb:153:10:153:10 | x [element] : | semantics.rb:153:10:153:13 | ...[...] | | semantics.rb:153:10:153:10 | x [element] : | semantics.rb:153:10:153:13 | ...[...] | | semantics.rb:154:10:154:10 | x [element] : | semantics.rb:154:10:154:13 | ...[...] | | semantics.rb:154:10:154:10 | x [element] : | semantics.rb:154:10:154:13 | ...[...] | -| semantics.rb:158:9:158:18 | call to source : | semantics.rb:162:5:162:5 | [post] h [element 0] : | -| semantics.rb:158:9:158:18 | call to source : | semantics.rb:162:5:162:5 | [post] h [element 0] : | -| semantics.rb:159:9:159:18 | call to source : | semantics.rb:163:5:163:5 | [post] h [element] : | -| semantics.rb:159:9:159:18 | call to source : | semantics.rb:163:5:163:5 | [post] h [element] : | +| semantics.rb:158:5:158:5 | a : | semantics.rb:162:5:162:5 | [post] h [element 0] : | +| semantics.rb:158:5:158:5 | a : | semantics.rb:162:5:162:5 | [post] h [element 0] : | +| semantics.rb:158:9:158:18 | call to source : | semantics.rb:158:5:158:5 | a : | +| semantics.rb:158:9:158:18 | call to source : | semantics.rb:158:5:158:5 | a : | +| semantics.rb:159:5:159:5 | b : | semantics.rb:163:5:163:5 | [post] h [element] : | +| semantics.rb:159:5:159:5 | b : | semantics.rb:163:5:163:5 | [post] h [element] : | +| semantics.rb:159:9:159:18 | call to source : | semantics.rb:159:5:159:5 | b : | +| semantics.rb:159:9:159:18 | call to source : | semantics.rb:159:5:159:5 | b : | | semantics.rb:162:5:162:5 | [post] h [element 0] : | semantics.rb:165:14:165:14 | h [element 0] : | | semantics.rb:162:5:162:5 | [post] h [element 0] : | semantics.rb:165:14:165:14 | h [element 0] : | | semantics.rb:163:5:163:5 | [post] h [element] : | semantics.rb:165:14:165:14 | h [element] : | @@ -170,20 +209,26 @@ edges | semantics.rb:165:14:165:14 | h [element 0] : | semantics.rb:165:10:165:15 | call to s21 | | semantics.rb:165:14:165:14 | h [element] : | semantics.rb:165:10:165:15 | call to s21 | | semantics.rb:165:14:165:14 | h [element] : | semantics.rb:165:10:165:15 | call to s21 | -| semantics.rb:169:9:169:18 | call to source : | semantics.rb:170:13:170:13 | a : | -| semantics.rb:169:9:169:18 | call to source : | semantics.rb:170:13:170:13 | a : | -| semantics.rb:170:9:170:14 | call to s22 [element] : | semantics.rb:171:10:171:10 | x [element] : | -| semantics.rb:170:9:170:14 | call to s22 [element] : | semantics.rb:171:10:171:10 | x [element] : | -| semantics.rb:170:9:170:14 | call to s22 [element] : | semantics.rb:172:10:172:10 | x [element] : | -| semantics.rb:170:9:170:14 | call to s22 [element] : | semantics.rb:172:10:172:10 | x [element] : | +| semantics.rb:169:5:169:5 | a : | semantics.rb:170:13:170:13 | a : | +| semantics.rb:169:5:169:5 | a : | semantics.rb:170:13:170:13 | a : | +| semantics.rb:169:9:169:18 | call to source : | semantics.rb:169:5:169:5 | a : | +| semantics.rb:169:9:169:18 | call to source : | semantics.rb:169:5:169:5 | a : | +| semantics.rb:170:5:170:5 | x [element] : | semantics.rb:171:10:171:10 | x [element] : | +| semantics.rb:170:5:170:5 | x [element] : | semantics.rb:171:10:171:10 | x [element] : | +| semantics.rb:170:5:170:5 | x [element] : | semantics.rb:172:10:172:10 | x [element] : | +| semantics.rb:170:5:170:5 | x [element] : | semantics.rb:172:10:172:10 | x [element] : | +| semantics.rb:170:9:170:14 | call to s22 [element] : | semantics.rb:170:5:170:5 | x [element] : | +| semantics.rb:170:9:170:14 | call to s22 [element] : | semantics.rb:170:5:170:5 | x [element] : | | semantics.rb:170:13:170:13 | a : | semantics.rb:170:9:170:14 | call to s22 [element] : | | semantics.rb:170:13:170:13 | a : | semantics.rb:170:9:170:14 | call to s22 [element] : | | semantics.rb:171:10:171:10 | x [element] : | semantics.rb:171:10:171:13 | ...[...] | | semantics.rb:171:10:171:10 | x [element] : | semantics.rb:171:10:171:13 | ...[...] | | semantics.rb:172:10:172:10 | x [element] : | semantics.rb:172:10:172:13 | ...[...] | | semantics.rb:172:10:172:10 | x [element] : | semantics.rb:172:10:172:13 | ...[...] | -| semantics.rb:176:9:176:18 | call to source : | semantics.rb:179:5:179:5 | [post] h [element 0] : | -| semantics.rb:176:9:176:18 | call to source : | semantics.rb:179:5:179:5 | [post] h [element 0] : | +| semantics.rb:176:5:176:5 | a : | semantics.rb:179:5:179:5 | [post] h [element 0] : | +| semantics.rb:176:5:176:5 | a : | semantics.rb:179:5:179:5 | [post] h [element 0] : | +| semantics.rb:176:9:176:18 | call to source : | semantics.rb:176:5:176:5 | a : | +| semantics.rb:176:9:176:18 | call to source : | semantics.rb:176:5:176:5 | a : | | semantics.rb:179:5:179:5 | [post] h [element 0] : | semantics.rb:180:5:180:5 | h [element 0] : | | semantics.rb:179:5:179:5 | [post] h [element 0] : | semantics.rb:180:5:180:5 | h [element 0] : | | semantics.rb:180:5:180:5 | [post] h [element 0] : | semantics.rb:181:14:181:14 | h [element 0] : | @@ -192,20 +237,26 @@ edges | semantics.rb:180:5:180:5 | h [element 0] : | semantics.rb:180:5:180:5 | [post] h [element 0] : | | semantics.rb:181:14:181:14 | h [element 0] : | semantics.rb:181:10:181:15 | call to s23 | | semantics.rb:181:14:181:14 | h [element 0] : | semantics.rb:181:10:181:15 | call to s23 | -| semantics.rb:185:9:185:18 | call to source : | semantics.rb:186:13:186:13 | a : | -| semantics.rb:185:9:185:18 | call to source : | semantics.rb:186:13:186:13 | a : | -| semantics.rb:186:9:186:14 | call to s24 [element 0] : | semantics.rb:187:10:187:10 | x [element 0] : | -| semantics.rb:186:9:186:14 | call to s24 [element 0] : | semantics.rb:187:10:187:10 | x [element 0] : | -| semantics.rb:186:9:186:14 | call to s24 [element 0] : | semantics.rb:189:10:189:10 | x [element 0] : | -| semantics.rb:186:9:186:14 | call to s24 [element 0] : | semantics.rb:189:10:189:10 | x [element 0] : | +| semantics.rb:185:5:185:5 | a : | semantics.rb:186:13:186:13 | a : | +| semantics.rb:185:5:185:5 | a : | semantics.rb:186:13:186:13 | a : | +| semantics.rb:185:9:185:18 | call to source : | semantics.rb:185:5:185:5 | a : | +| semantics.rb:185:9:185:18 | call to source : | semantics.rb:185:5:185:5 | a : | +| semantics.rb:186:5:186:5 | x [element 0] : | semantics.rb:187:10:187:10 | x [element 0] : | +| semantics.rb:186:5:186:5 | x [element 0] : | semantics.rb:187:10:187:10 | x [element 0] : | +| semantics.rb:186:5:186:5 | x [element 0] : | semantics.rb:189:10:189:10 | x [element 0] : | +| semantics.rb:186:5:186:5 | x [element 0] : | semantics.rb:189:10:189:10 | x [element 0] : | +| semantics.rb:186:9:186:14 | call to s24 [element 0] : | semantics.rb:186:5:186:5 | x [element 0] : | +| semantics.rb:186:9:186:14 | call to s24 [element 0] : | semantics.rb:186:5:186:5 | x [element 0] : | | semantics.rb:186:13:186:13 | a : | semantics.rb:186:9:186:14 | call to s24 [element 0] : | | semantics.rb:186:13:186:13 | a : | semantics.rb:186:9:186:14 | call to s24 [element 0] : | | semantics.rb:187:10:187:10 | x [element 0] : | semantics.rb:187:10:187:13 | ...[...] | | semantics.rb:187:10:187:10 | x [element 0] : | semantics.rb:187:10:187:13 | ...[...] | | semantics.rb:189:10:189:10 | x [element 0] : | semantics.rb:189:10:189:13 | ...[...] | | semantics.rb:189:10:189:10 | x [element 0] : | semantics.rb:189:10:189:13 | ...[...] | -| semantics.rb:193:9:193:18 | call to source : | semantics.rb:196:5:196:5 | [post] h [element 0] : | -| semantics.rb:193:9:193:18 | call to source : | semantics.rb:196:5:196:5 | [post] h [element 0] : | +| semantics.rb:193:5:193:5 | a : | semantics.rb:196:5:196:5 | [post] h [element 0] : | +| semantics.rb:193:5:193:5 | a : | semantics.rb:196:5:196:5 | [post] h [element 0] : | +| semantics.rb:193:9:193:18 | call to source : | semantics.rb:193:5:193:5 | a : | +| semantics.rb:193:9:193:18 | call to source : | semantics.rb:193:5:193:5 | a : | | semantics.rb:196:5:196:5 | [post] h [element 0] : | semantics.rb:197:5:197:5 | h [element 0] : | | semantics.rb:196:5:196:5 | [post] h [element 0] : | semantics.rb:197:5:197:5 | h [element 0] : | | semantics.rb:197:5:197:5 | [post] h [element 0] : | semantics.rb:198:14:198:14 | h [element 0] : | @@ -214,24 +265,34 @@ edges | semantics.rb:197:5:197:5 | h [element 0] : | semantics.rb:197:5:197:5 | [post] h [element 0] : | | semantics.rb:198:14:198:14 | h [element 0] : | semantics.rb:198:10:198:15 | call to s25 | | semantics.rb:198:14:198:14 | h [element 0] : | semantics.rb:198:10:198:15 | call to s25 | -| semantics.rb:202:9:202:18 | call to source : | semantics.rb:203:13:203:13 | a : | -| semantics.rb:202:9:202:18 | call to source : | semantics.rb:203:13:203:13 | a : | -| semantics.rb:203:9:203:14 | call to s26 [element 0] : | semantics.rb:204:10:204:10 | x [element 0] : | -| semantics.rb:203:9:203:14 | call to s26 [element 0] : | semantics.rb:204:10:204:10 | x [element 0] : | -| semantics.rb:203:9:203:14 | call to s26 [element 0] : | semantics.rb:206:10:206:10 | x [element 0] : | -| semantics.rb:203:9:203:14 | call to s26 [element 0] : | semantics.rb:206:10:206:10 | x [element 0] : | +| semantics.rb:202:5:202:5 | a : | semantics.rb:203:13:203:13 | a : | +| semantics.rb:202:5:202:5 | a : | semantics.rb:203:13:203:13 | a : | +| semantics.rb:202:9:202:18 | call to source : | semantics.rb:202:5:202:5 | a : | +| semantics.rb:202:9:202:18 | call to source : | semantics.rb:202:5:202:5 | a : | +| semantics.rb:203:5:203:5 | x [element 0] : | semantics.rb:204:10:204:10 | x [element 0] : | +| semantics.rb:203:5:203:5 | x [element 0] : | semantics.rb:204:10:204:10 | x [element 0] : | +| semantics.rb:203:5:203:5 | x [element 0] : | semantics.rb:206:10:206:10 | x [element 0] : | +| semantics.rb:203:5:203:5 | x [element 0] : | semantics.rb:206:10:206:10 | x [element 0] : | +| semantics.rb:203:9:203:14 | call to s26 [element 0] : | semantics.rb:203:5:203:5 | x [element 0] : | +| semantics.rb:203:9:203:14 | call to s26 [element 0] : | semantics.rb:203:5:203:5 | x [element 0] : | | semantics.rb:203:13:203:13 | a : | semantics.rb:203:9:203:14 | call to s26 [element 0] : | | semantics.rb:203:13:203:13 | a : | semantics.rb:203:9:203:14 | call to s26 [element 0] : | | semantics.rb:204:10:204:10 | x [element 0] : | semantics.rb:204:10:204:13 | ...[...] | | semantics.rb:204:10:204:10 | x [element 0] : | semantics.rb:204:10:204:13 | ...[...] | | semantics.rb:206:10:206:10 | x [element 0] : | semantics.rb:206:10:206:13 | ...[...] | | semantics.rb:206:10:206:10 | x [element 0] : | semantics.rb:206:10:206:13 | ...[...] | -| semantics.rb:211:9:211:18 | call to source : | semantics.rb:217:5:217:5 | [post] h [element 1] : | -| semantics.rb:211:9:211:18 | call to source : | semantics.rb:217:5:217:5 | [post] h [element 1] : | -| semantics.rb:212:9:212:18 | call to source : | semantics.rb:218:5:218:5 | [post] h [element 2] : | -| semantics.rb:212:9:212:18 | call to source : | semantics.rb:218:5:218:5 | [post] h [element 2] : | -| semantics.rb:213:9:213:18 | call to source : | semantics.rb:219:5:219:5 | [post] h [element] : | -| semantics.rb:213:9:213:18 | call to source : | semantics.rb:219:5:219:5 | [post] h [element] : | +| semantics.rb:211:5:211:5 | b : | semantics.rb:217:5:217:5 | [post] h [element 1] : | +| semantics.rb:211:5:211:5 | b : | semantics.rb:217:5:217:5 | [post] h [element 1] : | +| semantics.rb:211:9:211:18 | call to source : | semantics.rb:211:5:211:5 | b : | +| semantics.rb:211:9:211:18 | call to source : | semantics.rb:211:5:211:5 | b : | +| semantics.rb:212:5:212:5 | c : | semantics.rb:218:5:218:5 | [post] h [element 2] : | +| semantics.rb:212:5:212:5 | c : | semantics.rb:218:5:218:5 | [post] h [element 2] : | +| semantics.rb:212:9:212:18 | call to source : | semantics.rb:212:5:212:5 | c : | +| semantics.rb:212:9:212:18 | call to source : | semantics.rb:212:5:212:5 | c : | +| semantics.rb:213:5:213:5 | d : | semantics.rb:219:5:219:5 | [post] h [element] : | +| semantics.rb:213:5:213:5 | d : | semantics.rb:219:5:219:5 | [post] h [element] : | +| semantics.rb:213:9:213:18 | call to source : | semantics.rb:213:5:213:5 | d : | +| semantics.rb:213:9:213:18 | call to source : | semantics.rb:213:5:213:5 | d : | | semantics.rb:217:5:217:5 | [post] h [element 1] : | semantics.rb:218:5:218:5 | h [element 1] : | | semantics.rb:217:5:217:5 | [post] h [element 1] : | semantics.rb:218:5:218:5 | h [element 1] : | | semantics.rb:218:5:218:5 | [post] h [element 1] : | semantics.rb:221:14:221:14 | h [element 1] : | @@ -248,16 +309,20 @@ edges | semantics.rb:221:14:221:14 | h [element 2] : | semantics.rb:221:10:221:15 | call to s27 | | semantics.rb:221:14:221:14 | h [element] : | semantics.rb:221:10:221:15 | call to s27 | | semantics.rb:221:14:221:14 | h [element] : | semantics.rb:221:10:221:15 | call to s27 | -| semantics.rb:225:9:225:18 | call to source : | semantics.rb:226:13:226:13 | a : | -| semantics.rb:225:9:225:18 | call to source : | semantics.rb:226:13:226:13 | a : | -| semantics.rb:226:9:226:14 | call to s28 [element] : | semantics.rb:227:10:227:10 | x [element] : | -| semantics.rb:226:9:226:14 | call to s28 [element] : | semantics.rb:227:10:227:10 | x [element] : | -| semantics.rb:226:9:226:14 | call to s28 [element] : | semantics.rb:228:10:228:10 | x [element] : | -| semantics.rb:226:9:226:14 | call to s28 [element] : | semantics.rb:228:10:228:10 | x [element] : | -| semantics.rb:226:9:226:14 | call to s28 [element] : | semantics.rb:229:10:229:10 | x [element] : | -| semantics.rb:226:9:226:14 | call to s28 [element] : | semantics.rb:229:10:229:10 | x [element] : | -| semantics.rb:226:9:226:14 | call to s28 [element] : | semantics.rb:230:10:230:10 | x [element] : | -| semantics.rb:226:9:226:14 | call to s28 [element] : | semantics.rb:230:10:230:10 | x [element] : | +| semantics.rb:225:5:225:5 | a : | semantics.rb:226:13:226:13 | a : | +| semantics.rb:225:5:225:5 | a : | semantics.rb:226:13:226:13 | a : | +| semantics.rb:225:9:225:18 | call to source : | semantics.rb:225:5:225:5 | a : | +| semantics.rb:225:9:225:18 | call to source : | semantics.rb:225:5:225:5 | a : | +| semantics.rb:226:5:226:5 | x [element] : | semantics.rb:227:10:227:10 | x [element] : | +| semantics.rb:226:5:226:5 | x [element] : | semantics.rb:227:10:227:10 | x [element] : | +| semantics.rb:226:5:226:5 | x [element] : | semantics.rb:228:10:228:10 | x [element] : | +| semantics.rb:226:5:226:5 | x [element] : | semantics.rb:228:10:228:10 | x [element] : | +| semantics.rb:226:5:226:5 | x [element] : | semantics.rb:229:10:229:10 | x [element] : | +| semantics.rb:226:5:226:5 | x [element] : | semantics.rb:229:10:229:10 | x [element] : | +| semantics.rb:226:5:226:5 | x [element] : | semantics.rb:230:10:230:10 | x [element] : | +| semantics.rb:226:5:226:5 | x [element] : | semantics.rb:230:10:230:10 | x [element] : | +| semantics.rb:226:9:226:14 | call to s28 [element] : | semantics.rb:226:5:226:5 | x [element] : | +| semantics.rb:226:9:226:14 | call to s28 [element] : | semantics.rb:226:5:226:5 | x [element] : | | semantics.rb:226:13:226:13 | a : | semantics.rb:226:9:226:14 | call to s28 [element] : | | semantics.rb:226:13:226:13 | a : | semantics.rb:226:9:226:14 | call to s28 [element] : | | semantics.rb:227:10:227:10 | x [element] : | semantics.rb:227:10:227:13 | ...[...] | @@ -268,10 +333,14 @@ edges | semantics.rb:229:10:229:10 | x [element] : | semantics.rb:229:10:229:13 | ...[...] | | semantics.rb:230:10:230:10 | x [element] : | semantics.rb:230:10:230:13 | ...[...] | | semantics.rb:230:10:230:10 | x [element] : | semantics.rb:230:10:230:13 | ...[...] | -| semantics.rb:235:9:235:18 | call to source : | semantics.rb:240:5:240:5 | [post] h [element 1] : | -| semantics.rb:235:9:235:18 | call to source : | semantics.rb:240:5:240:5 | [post] h [element 1] : | -| semantics.rb:236:9:236:18 | call to source : | semantics.rb:241:5:241:5 | [post] h [element 2] : | -| semantics.rb:236:9:236:18 | call to source : | semantics.rb:241:5:241:5 | [post] h [element 2] : | +| semantics.rb:235:5:235:5 | b : | semantics.rb:240:5:240:5 | [post] h [element 1] : | +| semantics.rb:235:5:235:5 | b : | semantics.rb:240:5:240:5 | [post] h [element 1] : | +| semantics.rb:235:9:235:18 | call to source : | semantics.rb:235:5:235:5 | b : | +| semantics.rb:235:9:235:18 | call to source : | semantics.rb:235:5:235:5 | b : | +| semantics.rb:236:5:236:5 | c : | semantics.rb:241:5:241:5 | [post] h [element 2] : | +| semantics.rb:236:5:236:5 | c : | semantics.rb:241:5:241:5 | [post] h [element 2] : | +| semantics.rb:236:9:236:18 | call to source : | semantics.rb:236:5:236:5 | c : | +| semantics.rb:236:9:236:18 | call to source : | semantics.rb:236:5:236:5 | c : | | semantics.rb:240:5:240:5 | [post] h [element 1] : | semantics.rb:241:5:241:5 | h [element 1] : | | semantics.rb:240:5:240:5 | [post] h [element 1] : | semantics.rb:241:5:241:5 | h [element 1] : | | semantics.rb:241:5:241:5 | [post] h [element 1] : | semantics.rb:244:14:244:14 | h [element 1] : | @@ -284,16 +353,20 @@ edges | semantics.rb:244:14:244:14 | h [element 1] : | semantics.rb:244:10:244:15 | call to s29 | | semantics.rb:244:14:244:14 | h [element 2] : | semantics.rb:244:10:244:15 | call to s29 | | semantics.rb:244:14:244:14 | h [element 2] : | semantics.rb:244:10:244:15 | call to s29 | -| semantics.rb:248:9:248:18 | call to source : | semantics.rb:249:13:249:13 | a : | -| semantics.rb:248:9:248:18 | call to source : | semantics.rb:249:13:249:13 | a : | -| semantics.rb:249:9:249:14 | call to s30 [element] : | semantics.rb:250:10:250:10 | x [element] : | -| semantics.rb:249:9:249:14 | call to s30 [element] : | semantics.rb:250:10:250:10 | x [element] : | -| semantics.rb:249:9:249:14 | call to s30 [element] : | semantics.rb:251:10:251:10 | x [element] : | -| semantics.rb:249:9:249:14 | call to s30 [element] : | semantics.rb:251:10:251:10 | x [element] : | -| semantics.rb:249:9:249:14 | call to s30 [element] : | semantics.rb:252:10:252:10 | x [element] : | -| semantics.rb:249:9:249:14 | call to s30 [element] : | semantics.rb:252:10:252:10 | x [element] : | -| semantics.rb:249:9:249:14 | call to s30 [element] : | semantics.rb:253:10:253:10 | x [element] : | -| semantics.rb:249:9:249:14 | call to s30 [element] : | semantics.rb:253:10:253:10 | x [element] : | +| semantics.rb:248:5:248:5 | a : | semantics.rb:249:13:249:13 | a : | +| semantics.rb:248:5:248:5 | a : | semantics.rb:249:13:249:13 | a : | +| semantics.rb:248:9:248:18 | call to source : | semantics.rb:248:5:248:5 | a : | +| semantics.rb:248:9:248:18 | call to source : | semantics.rb:248:5:248:5 | a : | +| semantics.rb:249:5:249:5 | x [element] : | semantics.rb:250:10:250:10 | x [element] : | +| semantics.rb:249:5:249:5 | x [element] : | semantics.rb:250:10:250:10 | x [element] : | +| semantics.rb:249:5:249:5 | x [element] : | semantics.rb:251:10:251:10 | x [element] : | +| semantics.rb:249:5:249:5 | x [element] : | semantics.rb:251:10:251:10 | x [element] : | +| semantics.rb:249:5:249:5 | x [element] : | semantics.rb:252:10:252:10 | x [element] : | +| semantics.rb:249:5:249:5 | x [element] : | semantics.rb:252:10:252:10 | x [element] : | +| semantics.rb:249:5:249:5 | x [element] : | semantics.rb:253:10:253:10 | x [element] : | +| semantics.rb:249:5:249:5 | x [element] : | semantics.rb:253:10:253:10 | x [element] : | +| semantics.rb:249:9:249:14 | call to s30 [element] : | semantics.rb:249:5:249:5 | x [element] : | +| semantics.rb:249:9:249:14 | call to s30 [element] : | semantics.rb:249:5:249:5 | x [element] : | | semantics.rb:249:13:249:13 | a : | semantics.rb:249:9:249:14 | call to s30 [element] : | | semantics.rb:249:13:249:13 | a : | semantics.rb:249:9:249:14 | call to s30 [element] : | | semantics.rb:250:10:250:10 | x [element] : | semantics.rb:250:10:250:13 | ...[...] | @@ -392,30 +465,36 @@ edges | semantics.rb:285:14:285:14 | h [element true] : | semantics.rb:285:10:285:15 | call to s33 | | semantics.rb:285:14:285:14 | h [element] : | semantics.rb:285:10:285:15 | call to s33 | | semantics.rb:285:14:285:14 | h [element] : | semantics.rb:285:10:285:15 | call to s33 | -| semantics.rb:289:9:289:24 | call to s35 [element :foo] : | semantics.rb:290:10:290:10 | x [element :foo] : | -| semantics.rb:289:9:289:24 | call to s35 [element :foo] : | semantics.rb:290:10:290:10 | x [element :foo] : | -| semantics.rb:289:9:289:24 | call to s35 [element :foo] : | semantics.rb:292:10:292:10 | x [element :foo] : | -| semantics.rb:289:9:289:24 | call to s35 [element :foo] : | semantics.rb:292:10:292:10 | x [element :foo] : | +| semantics.rb:289:5:289:5 | x [element :foo] : | semantics.rb:290:10:290:10 | x [element :foo] : | +| semantics.rb:289:5:289:5 | x [element :foo] : | semantics.rb:290:10:290:10 | x [element :foo] : | +| semantics.rb:289:5:289:5 | x [element :foo] : | semantics.rb:292:10:292:10 | x [element :foo] : | +| semantics.rb:289:5:289:5 | x [element :foo] : | semantics.rb:292:10:292:10 | x [element :foo] : | +| semantics.rb:289:9:289:24 | call to s35 [element :foo] : | semantics.rb:289:5:289:5 | x [element :foo] : | +| semantics.rb:289:9:289:24 | call to s35 [element :foo] : | semantics.rb:289:5:289:5 | x [element :foo] : | | semantics.rb:289:13:289:23 | call to source : | semantics.rb:289:9:289:24 | call to s35 [element :foo] : | | semantics.rb:289:13:289:23 | call to source : | semantics.rb:289:9:289:24 | call to s35 [element :foo] : | | semantics.rb:290:10:290:10 | x [element :foo] : | semantics.rb:290:10:290:16 | ...[...] | | semantics.rb:290:10:290:10 | x [element :foo] : | semantics.rb:290:10:290:16 | ...[...] | | semantics.rb:292:10:292:10 | x [element :foo] : | semantics.rb:292:10:292:13 | ...[...] | | semantics.rb:292:10:292:10 | x [element :foo] : | semantics.rb:292:10:292:13 | ...[...] | -| semantics.rb:296:9:296:24 | call to s36 [element foo] : | semantics.rb:298:10:298:10 | x [element foo] : | -| semantics.rb:296:9:296:24 | call to s36 [element foo] : | semantics.rb:298:10:298:10 | x [element foo] : | -| semantics.rb:296:9:296:24 | call to s36 [element foo] : | semantics.rb:300:10:300:10 | x [element foo] : | -| semantics.rb:296:9:296:24 | call to s36 [element foo] : | semantics.rb:300:10:300:10 | x [element foo] : | +| semantics.rb:296:5:296:5 | x [element foo] : | semantics.rb:298:10:298:10 | x [element foo] : | +| semantics.rb:296:5:296:5 | x [element foo] : | semantics.rb:298:10:298:10 | x [element foo] : | +| semantics.rb:296:5:296:5 | x [element foo] : | semantics.rb:300:10:300:10 | x [element foo] : | +| semantics.rb:296:5:296:5 | x [element foo] : | semantics.rb:300:10:300:10 | x [element foo] : | +| semantics.rb:296:9:296:24 | call to s36 [element foo] : | semantics.rb:296:5:296:5 | x [element foo] : | +| semantics.rb:296:9:296:24 | call to s36 [element foo] : | semantics.rb:296:5:296:5 | x [element foo] : | | semantics.rb:296:13:296:23 | call to source : | semantics.rb:296:9:296:24 | call to s36 [element foo] : | | semantics.rb:296:13:296:23 | call to source : | semantics.rb:296:9:296:24 | call to s36 [element foo] : | | semantics.rb:298:10:298:10 | x [element foo] : | semantics.rb:298:10:298:17 | ...[...] | | semantics.rb:298:10:298:10 | x [element foo] : | semantics.rb:298:10:298:17 | ...[...] | | semantics.rb:300:10:300:10 | x [element foo] : | semantics.rb:300:10:300:13 | ...[...] | | semantics.rb:300:10:300:10 | x [element foo] : | semantics.rb:300:10:300:13 | ...[...] | -| semantics.rb:304:9:304:24 | call to s37 [element true] : | semantics.rb:306:10:306:10 | x [element true] : | -| semantics.rb:304:9:304:24 | call to s37 [element true] : | semantics.rb:306:10:306:10 | x [element true] : | -| semantics.rb:304:9:304:24 | call to s37 [element true] : | semantics.rb:308:10:308:10 | x [element true] : | -| semantics.rb:304:9:304:24 | call to s37 [element true] : | semantics.rb:308:10:308:10 | x [element true] : | +| semantics.rb:304:5:304:5 | x [element true] : | semantics.rb:306:10:306:10 | x [element true] : | +| semantics.rb:304:5:304:5 | x [element true] : | semantics.rb:306:10:306:10 | x [element true] : | +| semantics.rb:304:5:304:5 | x [element true] : | semantics.rb:308:10:308:10 | x [element true] : | +| semantics.rb:304:5:304:5 | x [element true] : | semantics.rb:308:10:308:10 | x [element true] : | +| semantics.rb:304:9:304:24 | call to s37 [element true] : | semantics.rb:304:5:304:5 | x [element true] : | +| semantics.rb:304:9:304:24 | call to s37 [element true] : | semantics.rb:304:5:304:5 | x [element true] : | | semantics.rb:304:13:304:23 | call to source : | semantics.rb:304:9:304:24 | call to s37 [element true] : | | semantics.rb:304:13:304:23 | call to source : | semantics.rb:304:9:304:24 | call to s37 [element true] : | | semantics.rb:306:10:306:10 | x [element true] : | semantics.rb:306:10:306:16 | ...[...] | @@ -428,10 +507,12 @@ edges | semantics.rb:312:16:312:26 | call to source : | semantics.rb:312:5:312:5 | [post] h [element foo] : | | semantics.rb:315:14:315:14 | h [element foo] : | semantics.rb:315:10:315:15 | call to s38 | | semantics.rb:315:14:315:14 | h [element foo] : | semantics.rb:315:10:315:15 | call to s38 | -| semantics.rb:319:9:319:24 | call to s39 [element :foo] : | semantics.rb:321:10:321:10 | x [element :foo] : | -| semantics.rb:319:9:319:24 | call to s39 [element :foo] : | semantics.rb:321:10:321:10 | x [element :foo] : | -| semantics.rb:319:9:319:24 | call to s39 [element :foo] : | semantics.rb:322:10:322:10 | x [element :foo] : | -| semantics.rb:319:9:319:24 | call to s39 [element :foo] : | semantics.rb:322:10:322:10 | x [element :foo] : | +| semantics.rb:319:5:319:5 | x [element :foo] : | semantics.rb:321:10:321:10 | x [element :foo] : | +| semantics.rb:319:5:319:5 | x [element :foo] : | semantics.rb:321:10:321:10 | x [element :foo] : | +| semantics.rb:319:5:319:5 | x [element :foo] : | semantics.rb:322:10:322:10 | x [element :foo] : | +| semantics.rb:319:5:319:5 | x [element :foo] : | semantics.rb:322:10:322:10 | x [element :foo] : | +| semantics.rb:319:9:319:24 | call to s39 [element :foo] : | semantics.rb:319:5:319:5 | x [element :foo] : | +| semantics.rb:319:9:319:24 | call to s39 [element :foo] : | semantics.rb:319:5:319:5 | x [element :foo] : | | semantics.rb:319:13:319:23 | call to source : | semantics.rb:319:9:319:24 | call to s39 [element :foo] : | | semantics.rb:319:13:319:23 | call to source : | semantics.rb:319:9:319:24 | call to s39 [element :foo] : | | semantics.rb:321:10:321:10 | x [element :foo] : | semantics.rb:321:10:321:16 | ...[...] | @@ -444,8 +525,10 @@ edges | semantics.rb:327:13:327:23 | call to source : | semantics.rb:327:5:327:5 | [post] x [@foo] : | | semantics.rb:329:14:329:14 | x [@foo] : | semantics.rb:329:10:329:15 | call to s40 | | semantics.rb:329:14:329:14 | x [@foo] : | semantics.rb:329:10:329:15 | call to s40 | -| semantics.rb:333:9:333:24 | call to s41 [@foo] : | semantics.rb:334:10:334:10 | x [@foo] : | -| semantics.rb:333:9:333:24 | call to s41 [@foo] : | semantics.rb:334:10:334:10 | x [@foo] : | +| semantics.rb:333:5:333:5 | x [@foo] : | semantics.rb:334:10:334:10 | x [@foo] : | +| semantics.rb:333:5:333:5 | x [@foo] : | semantics.rb:334:10:334:10 | x [@foo] : | +| semantics.rb:333:9:333:24 | call to s41 [@foo] : | semantics.rb:333:5:333:5 | x [@foo] : | +| semantics.rb:333:9:333:24 | call to s41 [@foo] : | semantics.rb:333:5:333:5 | x [@foo] : | | semantics.rb:333:13:333:23 | call to source : | semantics.rb:333:9:333:24 | call to s41 [@foo] : | | semantics.rb:333:13:333:23 | call to source : | semantics.rb:333:9:333:24 | call to s41 [@foo] : | | semantics.rb:334:10:334:10 | x [@foo] : | semantics.rb:334:10:334:14 | call to foo | @@ -458,16 +541,20 @@ edges | semantics.rb:340:5:340:5 | [post] h [element] : | semantics.rb:342:13:342:13 | h [element] : | | semantics.rb:340:12:340:22 | call to source : | semantics.rb:340:5:340:5 | [post] h [element] : | | semantics.rb:340:12:340:22 | call to source : | semantics.rb:340:5:340:5 | [post] h [element] : | -| semantics.rb:342:9:342:14 | call to s42 [element 0] : | semantics.rb:344:10:344:10 | x [element 0] : | -| semantics.rb:342:9:342:14 | call to s42 [element 0] : | semantics.rb:344:10:344:10 | x [element 0] : | -| semantics.rb:342:9:342:14 | call to s42 [element 0] : | semantics.rb:346:10:346:10 | x [element 0] : | -| semantics.rb:342:9:342:14 | call to s42 [element 0] : | semantics.rb:346:10:346:10 | x [element 0] : | -| semantics.rb:342:9:342:14 | call to s42 [element] : | semantics.rb:344:10:344:10 | x [element] : | -| semantics.rb:342:9:342:14 | call to s42 [element] : | semantics.rb:344:10:344:10 | x [element] : | -| semantics.rb:342:9:342:14 | call to s42 [element] : | semantics.rb:345:10:345:10 | x [element] : | -| semantics.rb:342:9:342:14 | call to s42 [element] : | semantics.rb:345:10:345:10 | x [element] : | -| semantics.rb:342:9:342:14 | call to s42 [element] : | semantics.rb:346:10:346:10 | x [element] : | -| semantics.rb:342:9:342:14 | call to s42 [element] : | semantics.rb:346:10:346:10 | x [element] : | +| semantics.rb:342:5:342:5 | x [element 0] : | semantics.rb:344:10:344:10 | x [element 0] : | +| semantics.rb:342:5:342:5 | x [element 0] : | semantics.rb:344:10:344:10 | x [element 0] : | +| semantics.rb:342:5:342:5 | x [element 0] : | semantics.rb:346:10:346:10 | x [element 0] : | +| semantics.rb:342:5:342:5 | x [element 0] : | semantics.rb:346:10:346:10 | x [element 0] : | +| semantics.rb:342:5:342:5 | x [element] : | semantics.rb:344:10:344:10 | x [element] : | +| semantics.rb:342:5:342:5 | x [element] : | semantics.rb:344:10:344:10 | x [element] : | +| semantics.rb:342:5:342:5 | x [element] : | semantics.rb:345:10:345:10 | x [element] : | +| semantics.rb:342:5:342:5 | x [element] : | semantics.rb:345:10:345:10 | x [element] : | +| semantics.rb:342:5:342:5 | x [element] : | semantics.rb:346:10:346:10 | x [element] : | +| semantics.rb:342:5:342:5 | x [element] : | semantics.rb:346:10:346:10 | x [element] : | +| semantics.rb:342:9:342:14 | call to s42 [element 0] : | semantics.rb:342:5:342:5 | x [element 0] : | +| semantics.rb:342:9:342:14 | call to s42 [element 0] : | semantics.rb:342:5:342:5 | x [element 0] : | +| semantics.rb:342:9:342:14 | call to s42 [element] : | semantics.rb:342:5:342:5 | x [element] : | +| semantics.rb:342:9:342:14 | call to s42 [element] : | semantics.rb:342:5:342:5 | x [element] : | | semantics.rb:342:13:342:13 | h [element 0] : | semantics.rb:342:9:342:14 | call to s42 [element 0] : | | semantics.rb:342:13:342:13 | h [element 0] : | semantics.rb:342:9:342:14 | call to s42 [element 0] : | | semantics.rb:342:13:342:13 | h [element] : | semantics.rb:342:9:342:14 | call to s42 [element] : | @@ -486,10 +573,12 @@ edges | semantics.rb:350:5:350:5 | [post] h [element 0] : | semantics.rb:353:13:353:13 | h [element 0] : | | semantics.rb:350:12:350:22 | call to source : | semantics.rb:350:5:350:5 | [post] h [element 0] : | | semantics.rb:350:12:350:22 | call to source : | semantics.rb:350:5:350:5 | [post] h [element 0] : | -| semantics.rb:353:9:353:14 | call to s43 [element 0] : | semantics.rb:355:10:355:10 | x [element 0] : | -| semantics.rb:353:9:353:14 | call to s43 [element 0] : | semantics.rb:355:10:355:10 | x [element 0] : | -| semantics.rb:353:9:353:14 | call to s43 [element 0] : | semantics.rb:357:10:357:10 | x [element 0] : | -| semantics.rb:353:9:353:14 | call to s43 [element 0] : | semantics.rb:357:10:357:10 | x [element 0] : | +| semantics.rb:353:5:353:5 | x [element 0] : | semantics.rb:355:10:355:10 | x [element 0] : | +| semantics.rb:353:5:353:5 | x [element 0] : | semantics.rb:355:10:355:10 | x [element 0] : | +| semantics.rb:353:5:353:5 | x [element 0] : | semantics.rb:357:10:357:10 | x [element 0] : | +| semantics.rb:353:5:353:5 | x [element 0] : | semantics.rb:357:10:357:10 | x [element 0] : | +| semantics.rb:353:9:353:14 | call to s43 [element 0] : | semantics.rb:353:5:353:5 | x [element 0] : | +| semantics.rb:353:9:353:14 | call to s43 [element 0] : | semantics.rb:353:5:353:5 | x [element 0] : | | semantics.rb:353:13:353:13 | h [element 0] : | semantics.rb:353:9:353:14 | call to s43 [element 0] : | | semantics.rb:353:13:353:13 | h [element 0] : | semantics.rb:353:9:353:14 | call to s43 [element 0] : | | semantics.rb:355:10:355:10 | x [element 0] : | semantics.rb:355:10:355:13 | ...[...] | @@ -616,10 +705,12 @@ edges | semantics.rb:395:10:395:10 | h [element 1] : | semantics.rb:395:10:395:13 | ...[...] | | semantics.rb:395:10:395:10 | h [element] : | semantics.rb:395:10:395:13 | ...[...] | | semantics.rb:395:10:395:10 | h [element] : | semantics.rb:395:10:395:13 | ...[...] | -| semantics.rb:397:9:397:14 | call to s46 [element 1] : | semantics.rb:400:10:400:10 | x [element 1] : | -| semantics.rb:397:9:397:14 | call to s46 [element 1] : | semantics.rb:400:10:400:10 | x [element 1] : | -| semantics.rb:397:9:397:14 | call to s46 [element 1] : | semantics.rb:401:10:401:10 | x [element 1] : | -| semantics.rb:397:9:397:14 | call to s46 [element 1] : | semantics.rb:401:10:401:10 | x [element 1] : | +| semantics.rb:397:5:397:5 | x [element 1] : | semantics.rb:400:10:400:10 | x [element 1] : | +| semantics.rb:397:5:397:5 | x [element 1] : | semantics.rb:400:10:400:10 | x [element 1] : | +| semantics.rb:397:5:397:5 | x [element 1] : | semantics.rb:401:10:401:10 | x [element 1] : | +| semantics.rb:397:5:397:5 | x [element 1] : | semantics.rb:401:10:401:10 | x [element 1] : | +| semantics.rb:397:9:397:14 | call to s46 [element 1] : | semantics.rb:397:5:397:5 | x [element 1] : | +| semantics.rb:397:9:397:14 | call to s46 [element 1] : | semantics.rb:397:5:397:5 | x [element 1] : | | semantics.rb:397:13:397:13 | h [element 1] : | semantics.rb:397:9:397:14 | call to s46 [element 1] : | | semantics.rb:397:13:397:13 | h [element 1] : | semantics.rb:397:9:397:14 | call to s46 [element 1] : | | semantics.rb:400:10:400:10 | x [element 1] : | semantics.rb:400:10:400:13 | ...[...] | @@ -654,8 +745,10 @@ edges | semantics.rb:410:10:410:10 | h [element :bar] : | semantics.rb:410:10:410:16 | ...[...] | | semantics.rb:410:10:410:10 | h [element] : | semantics.rb:410:10:410:16 | ...[...] | | semantics.rb:410:10:410:10 | h [element] : | semantics.rb:410:10:410:16 | ...[...] | -| semantics.rb:412:9:412:14 | call to s47 [element :bar] : | semantics.rb:415:10:415:10 | x [element :bar] : | -| semantics.rb:412:9:412:14 | call to s47 [element :bar] : | semantics.rb:415:10:415:10 | x [element :bar] : | +| semantics.rb:412:5:412:5 | x [element :bar] : | semantics.rb:415:10:415:10 | x [element :bar] : | +| semantics.rb:412:5:412:5 | x [element :bar] : | semantics.rb:415:10:415:10 | x [element :bar] : | +| semantics.rb:412:9:412:14 | call to s47 [element :bar] : | semantics.rb:412:5:412:5 | x [element :bar] : | +| semantics.rb:412:9:412:14 | call to s47 [element :bar] : | semantics.rb:412:5:412:5 | x [element :bar] : | | semantics.rb:412:13:412:13 | h [element :bar] : | semantics.rb:412:9:412:14 | call to s47 [element :bar] : | | semantics.rb:412:13:412:13 | h [element :bar] : | semantics.rb:412:9:412:14 | call to s47 [element :bar] : | | semantics.rb:415:10:415:10 | x [element :bar] : | semantics.rb:415:10:415:16 | ...[...] | @@ -688,8 +781,10 @@ edges | semantics.rb:424:10:424:10 | h [element :bar] : | semantics.rb:424:10:424:16 | ...[...] | | semantics.rb:424:10:424:10 | h [element] : | semantics.rb:424:10:424:16 | ...[...] | | semantics.rb:424:10:424:10 | h [element] : | semantics.rb:424:10:424:16 | ...[...] | -| semantics.rb:426:9:426:14 | call to s48 [element :bar] : | semantics.rb:429:10:429:10 | x [element :bar] : | -| semantics.rb:426:9:426:14 | call to s48 [element :bar] : | semantics.rb:429:10:429:10 | x [element :bar] : | +| semantics.rb:426:5:426:5 | x [element :bar] : | semantics.rb:429:10:429:10 | x [element :bar] : | +| semantics.rb:426:5:426:5 | x [element :bar] : | semantics.rb:429:10:429:10 | x [element :bar] : | +| semantics.rb:426:9:426:14 | call to s48 [element :bar] : | semantics.rb:426:5:426:5 | x [element :bar] : | +| semantics.rb:426:9:426:14 | call to s48 [element :bar] : | semantics.rb:426:5:426:5 | x [element :bar] : | | semantics.rb:426:13:426:13 | h [element :bar] : | semantics.rb:426:9:426:14 | call to s48 [element :bar] : | | semantics.rb:426:13:426:13 | h [element :bar] : | semantics.rb:426:9:426:14 | call to s48 [element :bar] : | | semantics.rb:429:10:429:10 | x [element :bar] : | semantics.rb:429:10:429:16 | ...[...] | @@ -724,12 +819,16 @@ edges | semantics.rb:438:10:438:10 | h [element :bar] : | semantics.rb:438:10:438:16 | ...[...] | | semantics.rb:438:10:438:10 | h [element] : | semantics.rb:438:10:438:16 | ...[...] | | semantics.rb:438:10:438:10 | h [element] : | semantics.rb:438:10:438:16 | ...[...] | -| semantics.rb:440:9:440:14 | call to s49 [element :bar] : | semantics.rb:443:10:443:10 | x [element :bar] : | -| semantics.rb:440:9:440:14 | call to s49 [element :bar] : | semantics.rb:443:10:443:10 | x [element :bar] : | -| semantics.rb:440:9:440:14 | call to s49 [element] : | semantics.rb:442:10:442:10 | x [element] : | -| semantics.rb:440:9:440:14 | call to s49 [element] : | semantics.rb:442:10:442:10 | x [element] : | -| semantics.rb:440:9:440:14 | call to s49 [element] : | semantics.rb:443:10:443:10 | x [element] : | -| semantics.rb:440:9:440:14 | call to s49 [element] : | semantics.rb:443:10:443:10 | x [element] : | +| semantics.rb:440:5:440:5 | x [element :bar] : | semantics.rb:443:10:443:10 | x [element :bar] : | +| semantics.rb:440:5:440:5 | x [element :bar] : | semantics.rb:443:10:443:10 | x [element :bar] : | +| semantics.rb:440:5:440:5 | x [element] : | semantics.rb:442:10:442:10 | x [element] : | +| semantics.rb:440:5:440:5 | x [element] : | semantics.rb:442:10:442:10 | x [element] : | +| semantics.rb:440:5:440:5 | x [element] : | semantics.rb:443:10:443:10 | x [element] : | +| semantics.rb:440:5:440:5 | x [element] : | semantics.rb:443:10:443:10 | x [element] : | +| semantics.rb:440:9:440:14 | call to s49 [element :bar] : | semantics.rb:440:5:440:5 | x [element :bar] : | +| semantics.rb:440:9:440:14 | call to s49 [element :bar] : | semantics.rb:440:5:440:5 | x [element :bar] : | +| semantics.rb:440:9:440:14 | call to s49 [element] : | semantics.rb:440:5:440:5 | x [element] : | +| semantics.rb:440:9:440:14 | call to s49 [element] : | semantics.rb:440:5:440:5 | x [element] : | | semantics.rb:440:13:440:13 | h [element :bar] : | semantics.rb:440:9:440:14 | call to s49 [element :bar] : | | semantics.rb:440:13:440:13 | h [element :bar] : | semantics.rb:440:9:440:14 | call to s49 [element :bar] : | | semantics.rb:440:13:440:13 | h [element] : | semantics.rb:440:9:440:14 | call to s49 [element] : | @@ -882,10 +981,12 @@ edges | semantics.rb:494:10:494:10 | h [element :bar] : | semantics.rb:494:10:494:16 | ...[...] | | semantics.rb:494:10:494:10 | h [element] : | semantics.rb:494:10:494:16 | ...[...] | | semantics.rb:494:10:494:10 | h [element] : | semantics.rb:494:10:494:16 | ...[...] | +| semantics.rb:496:5:496:5 | x [element :bar] : | semantics.rb:499:10:499:10 | x [element :bar] : | +| semantics.rb:496:5:496:5 | x [element :bar] : | semantics.rb:499:10:499:10 | x [element :bar] : | | semantics.rb:496:9:496:9 | h [element :bar] : | semantics.rb:496:9:496:15 | call to s53 [element :bar] : | | semantics.rb:496:9:496:9 | h [element :bar] : | semantics.rb:496:9:496:15 | call to s53 [element :bar] : | -| semantics.rb:496:9:496:15 | call to s53 [element :bar] : | semantics.rb:499:10:499:10 | x [element :bar] : | -| semantics.rb:496:9:496:15 | call to s53 [element :bar] : | semantics.rb:499:10:499:10 | x [element :bar] : | +| semantics.rb:496:9:496:15 | call to s53 [element :bar] : | semantics.rb:496:5:496:5 | x [element :bar] : | +| semantics.rb:496:9:496:15 | call to s53 [element :bar] : | semantics.rb:496:5:496:5 | x [element :bar] : | | semantics.rb:499:10:499:10 | x [element :bar] : | semantics.rb:499:10:499:16 | ...[...] | | semantics.rb:499:10:499:10 | x [element :bar] : | semantics.rb:499:10:499:16 | ...[...] | | semantics.rb:501:10:501:20 | call to source : | semantics.rb:501:10:501:26 | call to s53 | @@ -918,21 +1019,29 @@ edges | semantics.rb:510:10:510:10 | h [element :bar] : | semantics.rb:510:10:510:16 | ...[...] | | semantics.rb:510:10:510:10 | h [element] : | semantics.rb:510:10:510:16 | ...[...] | | semantics.rb:510:10:510:10 | h [element] : | semantics.rb:510:10:510:16 | ...[...] | +| semantics.rb:512:5:512:5 | x [element :bar] : | semantics.rb:515:10:515:10 | x [element :bar] : | +| semantics.rb:512:5:512:5 | x [element :bar] : | semantics.rb:515:10:515:10 | x [element :bar] : | | semantics.rb:512:9:512:9 | h [element :bar] : | semantics.rb:512:9:512:15 | call to s54 [element :bar] : | | semantics.rb:512:9:512:9 | h [element :bar] : | semantics.rb:512:9:512:15 | call to s54 [element :bar] : | -| semantics.rb:512:9:512:15 | call to s54 [element :bar] : | semantics.rb:515:10:515:10 | x [element :bar] : | -| semantics.rb:512:9:512:15 | call to s54 [element :bar] : | semantics.rb:515:10:515:10 | x [element :bar] : | +| semantics.rb:512:9:512:15 | call to s54 [element :bar] : | semantics.rb:512:5:512:5 | x [element :bar] : | +| semantics.rb:512:9:512:15 | call to s54 [element :bar] : | semantics.rb:512:5:512:5 | x [element :bar] : | | semantics.rb:515:10:515:10 | x [element :bar] : | semantics.rb:515:10:515:16 | ...[...] | | semantics.rb:515:10:515:10 | x [element :bar] : | semantics.rb:515:10:515:16 | ...[...] | nodes +| semantics.rb:2:5:2:5 | a : | semmle.label | a : | +| semantics.rb:2:5:2:5 | a : | semmle.label | a : | | semantics.rb:2:9:2:18 | call to source : | semmle.label | call to source : | | semantics.rb:2:9:2:18 | call to source : | semmle.label | call to source : | +| semantics.rb:3:5:3:5 | x : | semmle.label | x : | +| semantics.rb:3:5:3:5 | x : | semmle.label | x : | | semantics.rb:3:9:3:9 | a : | semmle.label | a : | | semantics.rb:3:9:3:9 | a : | semmle.label | a : | | semantics.rb:3:9:3:14 | call to s1 : | semmle.label | call to s1 : | | semantics.rb:3:9:3:14 | call to s1 : | semmle.label | call to s1 : | | semantics.rb:4:10:4:10 | x | semmle.label | x | | semantics.rb:4:10:4:10 | x | semmle.label | x | +| semantics.rb:8:5:8:5 | a : | semmle.label | a : | +| semantics.rb:8:5:8:5 | a : | semmle.label | a : | | semantics.rb:8:9:8:18 | call to source : | semmle.label | call to source : | | semantics.rb:8:9:8:18 | call to source : | semmle.label | call to source : | | semantics.rb:9:5:9:5 | [post] x : | semmle.label | [post] x : | @@ -941,6 +1050,8 @@ nodes | semantics.rb:9:10:9:10 | a : | semmle.label | a : | | semantics.rb:10:10:10:10 | x | semmle.label | x | | semantics.rb:10:10:10:10 | x | semmle.label | x | +| semantics.rb:14:5:14:5 | a : | semmle.label | a : | +| semantics.rb:14:5:14:5 | a : | semmle.label | a : | | semantics.rb:14:9:14:18 | call to source : | semmle.label | call to source : | | semantics.rb:14:9:14:18 | call to source : | semmle.label | call to source : | | semantics.rb:15:8:15:8 | a : | semmle.label | a : | @@ -957,6 +1068,8 @@ nodes | semantics.rb:23:10:23:33 | call to s4 | semmle.label | call to s4 | | semantics.rb:23:23:23:32 | call to source : | semmle.label | call to source : | | semantics.rb:23:23:23:32 | call to source : | semmle.label | call to source : | +| semantics.rb:28:5:28:5 | a : | semmle.label | a : | +| semantics.rb:28:5:28:5 | a : | semmle.label | a : | | semantics.rb:28:9:28:18 | call to source : | semmle.label | call to source : | | semantics.rb:28:9:28:18 | call to source : | semmle.label | call to source : | | semantics.rb:29:8:29:8 | a : | semmle.label | a : | @@ -969,6 +1082,8 @@ nodes | semantics.rb:31:10:31:10 | y | semmle.label | y | | semantics.rb:32:10:32:10 | z | semmle.label | z | | semantics.rb:32:10:32:10 | z | semmle.label | z | +| semantics.rb:40:5:40:5 | a : | semmle.label | a : | +| semantics.rb:40:5:40:5 | a : | semmle.label | a : | | semantics.rb:40:9:40:18 | call to source : | semmle.label | call to source : | | semantics.rb:40:9:40:18 | call to source : | semmle.label | call to source : | | semantics.rb:41:8:41:8 | a : | semmle.label | a : | @@ -997,6 +1112,8 @@ nodes | semantics.rb:54:24:54:24 | x : | semmle.label | x : | | semantics.rb:55:14:55:14 | x | semmle.label | x | | semantics.rb:55:14:55:14 | x | semmle.label | x | +| semantics.rb:60:5:60:5 | a : | semmle.label | a : | +| semantics.rb:60:5:60:5 | a : | semmle.label | a : | | semantics.rb:60:9:60:18 | call to source : | semmle.label | call to source : | | semantics.rb:60:9:60:18 | call to source : | semmle.label | call to source : | | semantics.rb:61:10:61:15 | call to s10 | semmle.label | call to s10 | @@ -1019,6 +1136,8 @@ nodes | semantics.rb:66:10:66:16 | call to s10 | semmle.label | call to s10 | | semantics.rb:66:14:66:15 | &... : | semmle.label | &... : | | semantics.rb:66:14:66:15 | &... : | semmle.label | &... : | +| semantics.rb:80:5:80:5 | a : | semmle.label | a : | +| semantics.rb:80:5:80:5 | a : | semmle.label | a : | | semantics.rb:80:9:80:18 | call to source : | semmle.label | call to source : | | semantics.rb:80:9:80:18 | call to source : | semmle.label | call to source : | | semantics.rb:81:5:81:5 | a : | semmle.label | a : | @@ -1035,6 +1154,8 @@ nodes | semantics.rb:83:10:83:10 | y | semmle.label | y | | semantics.rb:84:10:84:10 | z | semmle.label | z | | semantics.rb:84:10:84:10 | z | semmle.label | z | +| semantics.rb:89:5:89:5 | a : | semmle.label | a : | +| semantics.rb:89:5:89:5 | a : | semmle.label | a : | | semantics.rb:89:9:89:18 | call to source : | semmle.label | call to source : | | semantics.rb:89:9:89:18 | call to source : | semmle.label | call to source : | | semantics.rb:91:10:91:20 | call to s13 | semmle.label | call to s13 | @@ -1045,6 +1166,8 @@ nodes | semantics.rb:92:10:92:28 | call to s13 | semmle.label | call to s13 | | semantics.rb:92:27:92:27 | a : | semmle.label | a : | | semantics.rb:92:27:92:27 | a : | semmle.label | a : | +| semantics.rb:97:5:97:5 | a : | semmle.label | a : | +| semantics.rb:97:5:97:5 | a : | semmle.label | a : | | semantics.rb:97:9:97:18 | call to source : | semmle.label | call to source : | | semantics.rb:97:9:97:18 | call to source : | semmle.label | call to source : | | semantics.rb:98:5:98:5 | a : | semmle.label | a : | @@ -1063,15 +1186,22 @@ nodes | semantics.rb:102:10:102:10 | y | semmle.label | y | | semantics.rb:103:10:103:10 | z | semmle.label | z | | semantics.rb:103:10:103:10 | z | semmle.label | z | +| semantics.rb:107:5:107:5 | a : | semmle.label | a : | | semantics.rb:107:9:107:18 | call to source : | semmle.label | call to source : | | semantics.rb:109:10:109:17 | call to s15 | semmle.label | call to s15 | | semantics.rb:109:14:109:16 | ** ... : | semmle.label | ** ... : | | semantics.rb:110:10:110:31 | call to s15 | semmle.label | call to s15 | | semantics.rb:110:28:110:30 | ** ... : | semmle.label | ** ... : | +| semantics.rb:114:5:114:5 | a : | semmle.label | a : | +| semantics.rb:114:5:114:5 | a : | semmle.label | a : | | semantics.rb:114:9:114:18 | call to source : | semmle.label | call to source : | | semantics.rb:114:9:114:18 | call to source : | semmle.label | call to source : | +| semantics.rb:115:5:115:5 | b : | semmle.label | b : | +| semantics.rb:115:5:115:5 | b : | semmle.label | b : | | semantics.rb:115:9:115:18 | call to source : | semmle.label | call to source : | | semantics.rb:115:9:115:18 | call to source : | semmle.label | call to source : | +| semantics.rb:116:5:116:5 | h [element :a] : | semmle.label | h [element :a] : | +| semantics.rb:116:5:116:5 | h [element :a] : | semmle.label | h [element :a] : | | semantics.rb:116:14:116:14 | a : | semmle.label | a : | | semantics.rb:116:14:116:14 | a : | semmle.label | a : | | semantics.rb:117:10:117:17 | call to s16 | semmle.label | call to s16 | @@ -1092,6 +1222,8 @@ nodes | semantics.rb:121:20:121:22 | ** ... [element :a] : | semmle.label | ** ... [element :a] : | | semantics.rb:121:22:121:22 | h [element :a] : | semmle.label | h [element :a] : | | semantics.rb:121:22:121:22 | h [element :a] : | semmle.label | h [element :a] : | +| semantics.rb:125:5:125:5 | a : | semmle.label | a : | +| semantics.rb:125:5:125:5 | a : | semmle.label | a : | | semantics.rb:125:9:125:18 | call to source : | semmle.label | call to source : | | semantics.rb:125:9:125:18 | call to source : | semmle.label | call to source : | | semantics.rb:126:9:126:9 | a : | semmle.label | a : | @@ -1100,6 +1232,8 @@ nodes | semantics.rb:126:12:126:14 | [post] ** ... : | semmle.label | [post] ** ... : | | semantics.rb:127:10:127:10 | h | semmle.label | h | | semantics.rb:127:10:127:10 | h | semmle.label | h | +| semantics.rb:141:5:141:5 | b : | semmle.label | b : | +| semantics.rb:141:5:141:5 | b : | semmle.label | b : | | semantics.rb:141:9:141:18 | call to source : | semmle.label | call to source : | | semantics.rb:141:9:141:18 | call to source : | semmle.label | call to source : | | semantics.rb:145:5:145:5 | [post] h [element] : | semmle.label | [post] h [element] : | @@ -1108,8 +1242,12 @@ nodes | semantics.rb:147:10:147:15 | call to s19 | semmle.label | call to s19 | | semantics.rb:147:14:147:14 | h [element] : | semmle.label | h [element] : | | semantics.rb:147:14:147:14 | h [element] : | semmle.label | h [element] : | +| semantics.rb:151:5:151:5 | a : | semmle.label | a : | +| semantics.rb:151:5:151:5 | a : | semmle.label | a : | | semantics.rb:151:9:151:18 | call to source : | semmle.label | call to source : | | semantics.rb:151:9:151:18 | call to source : | semmle.label | call to source : | +| semantics.rb:152:5:152:5 | x [element] : | semmle.label | x [element] : | +| semantics.rb:152:5:152:5 | x [element] : | semmle.label | x [element] : | | semantics.rb:152:9:152:14 | call to s20 [element] : | semmle.label | call to s20 [element] : | | semantics.rb:152:9:152:14 | call to s20 [element] : | semmle.label | call to s20 [element] : | | semantics.rb:152:13:152:13 | a : | semmle.label | a : | @@ -1122,8 +1260,12 @@ nodes | semantics.rb:154:10:154:10 | x [element] : | semmle.label | x [element] : | | semantics.rb:154:10:154:13 | ...[...] | semmle.label | ...[...] | | semantics.rb:154:10:154:13 | ...[...] | semmle.label | ...[...] | +| semantics.rb:158:5:158:5 | a : | semmle.label | a : | +| semantics.rb:158:5:158:5 | a : | semmle.label | a : | | semantics.rb:158:9:158:18 | call to source : | semmle.label | call to source : | | semantics.rb:158:9:158:18 | call to source : | semmle.label | call to source : | +| semantics.rb:159:5:159:5 | b : | semmle.label | b : | +| semantics.rb:159:5:159:5 | b : | semmle.label | b : | | semantics.rb:159:9:159:18 | call to source : | semmle.label | call to source : | | semantics.rb:159:9:159:18 | call to source : | semmle.label | call to source : | | semantics.rb:162:5:162:5 | [post] h [element 0] : | semmle.label | [post] h [element 0] : | @@ -1136,8 +1278,12 @@ nodes | semantics.rb:165:14:165:14 | h [element 0] : | semmle.label | h [element 0] : | | semantics.rb:165:14:165:14 | h [element] : | semmle.label | h [element] : | | semantics.rb:165:14:165:14 | h [element] : | semmle.label | h [element] : | +| semantics.rb:169:5:169:5 | a : | semmle.label | a : | +| semantics.rb:169:5:169:5 | a : | semmle.label | a : | | semantics.rb:169:9:169:18 | call to source : | semmle.label | call to source : | | semantics.rb:169:9:169:18 | call to source : | semmle.label | call to source : | +| semantics.rb:170:5:170:5 | x [element] : | semmle.label | x [element] : | +| semantics.rb:170:5:170:5 | x [element] : | semmle.label | x [element] : | | semantics.rb:170:9:170:14 | call to s22 [element] : | semmle.label | call to s22 [element] : | | semantics.rb:170:9:170:14 | call to s22 [element] : | semmle.label | call to s22 [element] : | | semantics.rb:170:13:170:13 | a : | semmle.label | a : | @@ -1150,6 +1296,8 @@ nodes | semantics.rb:172:10:172:10 | x [element] : | semmle.label | x [element] : | | semantics.rb:172:10:172:13 | ...[...] | semmle.label | ...[...] | | semantics.rb:172:10:172:13 | ...[...] | semmle.label | ...[...] | +| semantics.rb:176:5:176:5 | a : | semmle.label | a : | +| semantics.rb:176:5:176:5 | a : | semmle.label | a : | | semantics.rb:176:9:176:18 | call to source : | semmle.label | call to source : | | semantics.rb:176:9:176:18 | call to source : | semmle.label | call to source : | | semantics.rb:179:5:179:5 | [post] h [element 0] : | semmle.label | [post] h [element 0] : | @@ -1162,8 +1310,12 @@ nodes | semantics.rb:181:10:181:15 | call to s23 | semmle.label | call to s23 | | semantics.rb:181:14:181:14 | h [element 0] : | semmle.label | h [element 0] : | | semantics.rb:181:14:181:14 | h [element 0] : | semmle.label | h [element 0] : | +| semantics.rb:185:5:185:5 | a : | semmle.label | a : | +| semantics.rb:185:5:185:5 | a : | semmle.label | a : | | semantics.rb:185:9:185:18 | call to source : | semmle.label | call to source : | | semantics.rb:185:9:185:18 | call to source : | semmle.label | call to source : | +| semantics.rb:186:5:186:5 | x [element 0] : | semmle.label | x [element 0] : | +| semantics.rb:186:5:186:5 | x [element 0] : | semmle.label | x [element 0] : | | semantics.rb:186:9:186:14 | call to s24 [element 0] : | semmle.label | call to s24 [element 0] : | | semantics.rb:186:9:186:14 | call to s24 [element 0] : | semmle.label | call to s24 [element 0] : | | semantics.rb:186:13:186:13 | a : | semmle.label | a : | @@ -1176,6 +1328,8 @@ nodes | semantics.rb:189:10:189:10 | x [element 0] : | semmle.label | x [element 0] : | | semantics.rb:189:10:189:13 | ...[...] | semmle.label | ...[...] | | semantics.rb:189:10:189:13 | ...[...] | semmle.label | ...[...] | +| semantics.rb:193:5:193:5 | a : | semmle.label | a : | +| semantics.rb:193:5:193:5 | a : | semmle.label | a : | | semantics.rb:193:9:193:18 | call to source : | semmle.label | call to source : | | semantics.rb:193:9:193:18 | call to source : | semmle.label | call to source : | | semantics.rb:196:5:196:5 | [post] h [element 0] : | semmle.label | [post] h [element 0] : | @@ -1188,8 +1342,12 @@ nodes | semantics.rb:198:10:198:15 | call to s25 | semmle.label | call to s25 | | semantics.rb:198:14:198:14 | h [element 0] : | semmle.label | h [element 0] : | | semantics.rb:198:14:198:14 | h [element 0] : | semmle.label | h [element 0] : | +| semantics.rb:202:5:202:5 | a : | semmle.label | a : | +| semantics.rb:202:5:202:5 | a : | semmle.label | a : | | semantics.rb:202:9:202:18 | call to source : | semmle.label | call to source : | | semantics.rb:202:9:202:18 | call to source : | semmle.label | call to source : | +| semantics.rb:203:5:203:5 | x [element 0] : | semmle.label | x [element 0] : | +| semantics.rb:203:5:203:5 | x [element 0] : | semmle.label | x [element 0] : | | semantics.rb:203:9:203:14 | call to s26 [element 0] : | semmle.label | call to s26 [element 0] : | | semantics.rb:203:9:203:14 | call to s26 [element 0] : | semmle.label | call to s26 [element 0] : | | semantics.rb:203:13:203:13 | a : | semmle.label | a : | @@ -1202,10 +1360,16 @@ nodes | semantics.rb:206:10:206:10 | x [element 0] : | semmle.label | x [element 0] : | | semantics.rb:206:10:206:13 | ...[...] | semmle.label | ...[...] | | semantics.rb:206:10:206:13 | ...[...] | semmle.label | ...[...] | +| semantics.rb:211:5:211:5 | b : | semmle.label | b : | +| semantics.rb:211:5:211:5 | b : | semmle.label | b : | | semantics.rb:211:9:211:18 | call to source : | semmle.label | call to source : | | semantics.rb:211:9:211:18 | call to source : | semmle.label | call to source : | +| semantics.rb:212:5:212:5 | c : | semmle.label | c : | +| semantics.rb:212:5:212:5 | c : | semmle.label | c : | | semantics.rb:212:9:212:18 | call to source : | semmle.label | call to source : | | semantics.rb:212:9:212:18 | call to source : | semmle.label | call to source : | +| semantics.rb:213:5:213:5 | d : | semmle.label | d : | +| semantics.rb:213:5:213:5 | d : | semmle.label | d : | | semantics.rb:213:9:213:18 | call to source : | semmle.label | call to source : | | semantics.rb:213:9:213:18 | call to source : | semmle.label | call to source : | | semantics.rb:217:5:217:5 | [post] h [element 1] : | semmle.label | [post] h [element 1] : | @@ -1226,8 +1390,12 @@ nodes | semantics.rb:221:14:221:14 | h [element 2] : | semmle.label | h [element 2] : | | semantics.rb:221:14:221:14 | h [element] : | semmle.label | h [element] : | | semantics.rb:221:14:221:14 | h [element] : | semmle.label | h [element] : | +| semantics.rb:225:5:225:5 | a : | semmle.label | a : | +| semantics.rb:225:5:225:5 | a : | semmle.label | a : | | semantics.rb:225:9:225:18 | call to source : | semmle.label | call to source : | | semantics.rb:225:9:225:18 | call to source : | semmle.label | call to source : | +| semantics.rb:226:5:226:5 | x [element] : | semmle.label | x [element] : | +| semantics.rb:226:5:226:5 | x [element] : | semmle.label | x [element] : | | semantics.rb:226:9:226:14 | call to s28 [element] : | semmle.label | call to s28 [element] : | | semantics.rb:226:9:226:14 | call to s28 [element] : | semmle.label | call to s28 [element] : | | semantics.rb:226:13:226:13 | a : | semmle.label | a : | @@ -1248,8 +1416,12 @@ nodes | semantics.rb:230:10:230:10 | x [element] : | semmle.label | x [element] : | | semantics.rb:230:10:230:13 | ...[...] | semmle.label | ...[...] | | semantics.rb:230:10:230:13 | ...[...] | semmle.label | ...[...] | +| semantics.rb:235:5:235:5 | b : | semmle.label | b : | +| semantics.rb:235:5:235:5 | b : | semmle.label | b : | | semantics.rb:235:9:235:18 | call to source : | semmle.label | call to source : | | semantics.rb:235:9:235:18 | call to source : | semmle.label | call to source : | +| semantics.rb:236:5:236:5 | c : | semmle.label | c : | +| semantics.rb:236:5:236:5 | c : | semmle.label | c : | | semantics.rb:236:9:236:18 | call to source : | semmle.label | call to source : | | semantics.rb:236:9:236:18 | call to source : | semmle.label | call to source : | | semantics.rb:240:5:240:5 | [post] h [element 1] : | semmle.label | [post] h [element 1] : | @@ -1266,8 +1438,12 @@ nodes | semantics.rb:244:14:244:14 | h [element 1] : | semmle.label | h [element 1] : | | semantics.rb:244:14:244:14 | h [element 2] : | semmle.label | h [element 2] : | | semantics.rb:244:14:244:14 | h [element 2] : | semmle.label | h [element 2] : | +| semantics.rb:248:5:248:5 | a : | semmle.label | a : | +| semantics.rb:248:5:248:5 | a : | semmle.label | a : | | semantics.rb:248:9:248:18 | call to source : | semmle.label | call to source : | | semantics.rb:248:9:248:18 | call to source : | semmle.label | call to source : | +| semantics.rb:249:5:249:5 | x [element] : | semmle.label | x [element] : | +| semantics.rb:249:5:249:5 | x [element] : | semmle.label | x [element] : | | semantics.rb:249:9:249:14 | call to s30 [element] : | semmle.label | call to s30 [element] : | | semantics.rb:249:9:249:14 | call to s30 [element] : | semmle.label | call to s30 [element] : | | semantics.rb:249:13:249:13 | a : | semmle.label | a : | @@ -1382,6 +1558,8 @@ nodes | semantics.rb:285:14:285:14 | h [element true] : | semmle.label | h [element true] : | | semantics.rb:285:14:285:14 | h [element] : | semmle.label | h [element] : | | semantics.rb:285:14:285:14 | h [element] : | semmle.label | h [element] : | +| semantics.rb:289:5:289:5 | x [element :foo] : | semmle.label | x [element :foo] : | +| semantics.rb:289:5:289:5 | x [element :foo] : | semmle.label | x [element :foo] : | | semantics.rb:289:9:289:24 | call to s35 [element :foo] : | semmle.label | call to s35 [element :foo] : | | semantics.rb:289:9:289:24 | call to s35 [element :foo] : | semmle.label | call to s35 [element :foo] : | | semantics.rb:289:13:289:23 | call to source : | semmle.label | call to source : | @@ -1394,6 +1572,8 @@ nodes | semantics.rb:292:10:292:10 | x [element :foo] : | semmle.label | x [element :foo] : | | semantics.rb:292:10:292:13 | ...[...] | semmle.label | ...[...] | | semantics.rb:292:10:292:13 | ...[...] | semmle.label | ...[...] | +| semantics.rb:296:5:296:5 | x [element foo] : | semmle.label | x [element foo] : | +| semantics.rb:296:5:296:5 | x [element foo] : | semmle.label | x [element foo] : | | semantics.rb:296:9:296:24 | call to s36 [element foo] : | semmle.label | call to s36 [element foo] : | | semantics.rb:296:9:296:24 | call to s36 [element foo] : | semmle.label | call to s36 [element foo] : | | semantics.rb:296:13:296:23 | call to source : | semmle.label | call to source : | @@ -1406,6 +1586,8 @@ nodes | semantics.rb:300:10:300:10 | x [element foo] : | semmle.label | x [element foo] : | | semantics.rb:300:10:300:13 | ...[...] | semmle.label | ...[...] | | semantics.rb:300:10:300:13 | ...[...] | semmle.label | ...[...] | +| semantics.rb:304:5:304:5 | x [element true] : | semmle.label | x [element true] : | +| semantics.rb:304:5:304:5 | x [element true] : | semmle.label | x [element true] : | | semantics.rb:304:9:304:24 | call to s37 [element true] : | semmle.label | call to s37 [element true] : | | semantics.rb:304:9:304:24 | call to s37 [element true] : | semmle.label | call to s37 [element true] : | | semantics.rb:304:13:304:23 | call to source : | semmle.label | call to source : | @@ -1426,6 +1608,8 @@ nodes | semantics.rb:315:10:315:15 | call to s38 | semmle.label | call to s38 | | semantics.rb:315:14:315:14 | h [element foo] : | semmle.label | h [element foo] : | | semantics.rb:315:14:315:14 | h [element foo] : | semmle.label | h [element foo] : | +| semantics.rb:319:5:319:5 | x [element :foo] : | semmle.label | x [element :foo] : | +| semantics.rb:319:5:319:5 | x [element :foo] : | semmle.label | x [element :foo] : | | semantics.rb:319:9:319:24 | call to s39 [element :foo] : | semmle.label | call to s39 [element :foo] : | | semantics.rb:319:9:319:24 | call to s39 [element :foo] : | semmle.label | call to s39 [element :foo] : | | semantics.rb:319:13:319:23 | call to source : | semmle.label | call to source : | @@ -1446,6 +1630,8 @@ nodes | semantics.rb:329:10:329:15 | call to s40 | semmle.label | call to s40 | | semantics.rb:329:14:329:14 | x [@foo] : | semmle.label | x [@foo] : | | semantics.rb:329:14:329:14 | x [@foo] : | semmle.label | x [@foo] : | +| semantics.rb:333:5:333:5 | x [@foo] : | semmle.label | x [@foo] : | +| semantics.rb:333:5:333:5 | x [@foo] : | semmle.label | x [@foo] : | | semantics.rb:333:9:333:24 | call to s41 [@foo] : | semmle.label | call to s41 [@foo] : | | semantics.rb:333:9:333:24 | call to s41 [@foo] : | semmle.label | call to s41 [@foo] : | | semantics.rb:333:13:333:23 | call to source : | semmle.label | call to source : | @@ -1462,6 +1648,10 @@ nodes | semantics.rb:340:5:340:5 | [post] h [element] : | semmle.label | [post] h [element] : | | semantics.rb:340:12:340:22 | call to source : | semmle.label | call to source : | | semantics.rb:340:12:340:22 | call to source : | semmle.label | call to source : | +| semantics.rb:342:5:342:5 | x [element 0] : | semmle.label | x [element 0] : | +| semantics.rb:342:5:342:5 | x [element 0] : | semmle.label | x [element 0] : | +| semantics.rb:342:5:342:5 | x [element] : | semmle.label | x [element] : | +| semantics.rb:342:5:342:5 | x [element] : | semmle.label | x [element] : | | semantics.rb:342:9:342:14 | call to s42 [element 0] : | semmle.label | call to s42 [element 0] : | | semantics.rb:342:9:342:14 | call to s42 [element 0] : | semmle.label | call to s42 [element 0] : | | semantics.rb:342:9:342:14 | call to s42 [element] : | semmle.label | call to s42 [element] : | @@ -1490,6 +1680,8 @@ nodes | semantics.rb:350:5:350:5 | [post] h [element 0] : | semmle.label | [post] h [element 0] : | | semantics.rb:350:12:350:22 | call to source : | semmle.label | call to source : | | semantics.rb:350:12:350:22 | call to source : | semmle.label | call to source : | +| semantics.rb:353:5:353:5 | x [element 0] : | semmle.label | x [element 0] : | +| semantics.rb:353:5:353:5 | x [element 0] : | semmle.label | x [element 0] : | | semantics.rb:353:9:353:14 | call to s43 [element 0] : | semmle.label | call to s43 [element 0] : | | semantics.rb:353:9:353:14 | call to s43 [element 0] : | semmle.label | call to s43 [element 0] : | | semantics.rb:353:13:353:13 | h [element 0] : | semmle.label | h [element 0] : | @@ -1614,6 +1806,8 @@ nodes | semantics.rb:395:10:395:10 | h [element] : | semmle.label | h [element] : | | semantics.rb:395:10:395:13 | ...[...] | semmle.label | ...[...] | | semantics.rb:395:10:395:13 | ...[...] | semmle.label | ...[...] | +| semantics.rb:397:5:397:5 | x [element 1] : | semmle.label | x [element 1] : | +| semantics.rb:397:5:397:5 | x [element 1] : | semmle.label | x [element 1] : | | semantics.rb:397:9:397:14 | call to s46 [element 1] : | semmle.label | call to s46 [element 1] : | | semantics.rb:397:9:397:14 | call to s46 [element 1] : | semmle.label | call to s46 [element 1] : | | semantics.rb:397:13:397:13 | h [element 1] : | semmle.label | h [element 1] : | @@ -1654,6 +1848,8 @@ nodes | semantics.rb:410:10:410:10 | h [element] : | semmle.label | h [element] : | | semantics.rb:410:10:410:16 | ...[...] | semmle.label | ...[...] | | semantics.rb:410:10:410:16 | ...[...] | semmle.label | ...[...] | +| semantics.rb:412:5:412:5 | x [element :bar] : | semmle.label | x [element :bar] : | +| semantics.rb:412:5:412:5 | x [element :bar] : | semmle.label | x [element :bar] : | | semantics.rb:412:9:412:14 | call to s47 [element :bar] : | semmle.label | call to s47 [element :bar] : | | semantics.rb:412:9:412:14 | call to s47 [element :bar] : | semmle.label | call to s47 [element :bar] : | | semantics.rb:412:13:412:13 | h [element :bar] : | semmle.label | h [element :bar] : | @@ -1690,6 +1886,8 @@ nodes | semantics.rb:424:10:424:10 | h [element] : | semmle.label | h [element] : | | semantics.rb:424:10:424:16 | ...[...] | semmle.label | ...[...] | | semantics.rb:424:10:424:16 | ...[...] | semmle.label | ...[...] | +| semantics.rb:426:5:426:5 | x [element :bar] : | semmle.label | x [element :bar] : | +| semantics.rb:426:5:426:5 | x [element :bar] : | semmle.label | x [element :bar] : | | semantics.rb:426:9:426:14 | call to s48 [element :bar] : | semmle.label | call to s48 [element :bar] : | | semantics.rb:426:9:426:14 | call to s48 [element :bar] : | semmle.label | call to s48 [element :bar] : | | semantics.rb:426:13:426:13 | h [element :bar] : | semmle.label | h [element :bar] : | @@ -1726,6 +1924,10 @@ nodes | semantics.rb:438:10:438:10 | h [element] : | semmle.label | h [element] : | | semantics.rb:438:10:438:16 | ...[...] | semmle.label | ...[...] | | semantics.rb:438:10:438:16 | ...[...] | semmle.label | ...[...] | +| semantics.rb:440:5:440:5 | x [element :bar] : | semmle.label | x [element :bar] : | +| semantics.rb:440:5:440:5 | x [element :bar] : | semmle.label | x [element :bar] : | +| semantics.rb:440:5:440:5 | x [element] : | semmle.label | x [element] : | +| semantics.rb:440:5:440:5 | x [element] : | semmle.label | x [element] : | | semantics.rb:440:9:440:14 | call to s49 [element :bar] : | semmle.label | call to s49 [element :bar] : | | semantics.rb:440:9:440:14 | call to s49 [element :bar] : | semmle.label | call to s49 [element :bar] : | | semantics.rb:440:9:440:14 | call to s49 [element] : | semmle.label | call to s49 [element] : | @@ -1890,6 +2092,8 @@ nodes | semantics.rb:494:10:494:10 | h [element] : | semmle.label | h [element] : | | semantics.rb:494:10:494:16 | ...[...] | semmle.label | ...[...] | | semantics.rb:494:10:494:16 | ...[...] | semmle.label | ...[...] | +| semantics.rb:496:5:496:5 | x [element :bar] : | semmle.label | x [element :bar] : | +| semantics.rb:496:5:496:5 | x [element :bar] : | semmle.label | x [element :bar] : | | semantics.rb:496:9:496:9 | h [element :bar] : | semmle.label | h [element :bar] : | | semantics.rb:496:9:496:9 | h [element :bar] : | semmle.label | h [element :bar] : | | semantics.rb:496:9:496:15 | call to s53 [element :bar] : | semmle.label | call to s53 [element :bar] : | @@ -1930,6 +2134,8 @@ nodes | semantics.rb:510:10:510:10 | h [element] : | semmle.label | h [element] : | | semantics.rb:510:10:510:16 | ...[...] | semmle.label | ...[...] | | semantics.rb:510:10:510:16 | ...[...] | semmle.label | ...[...] | +| semantics.rb:512:5:512:5 | x [element :bar] : | semmle.label | x [element :bar] : | +| semantics.rb:512:5:512:5 | x [element :bar] : | semmle.label | x [element :bar] : | | semantics.rb:512:9:512:9 | h [element :bar] : | semmle.label | h [element :bar] : | | semantics.rb:512:9:512:9 | h [element :bar] : | semmle.label | h [element :bar] : | | semantics.rb:512:9:512:15 | call to s54 [element :bar] : | semmle.label | call to s54 [element :bar] : | diff --git a/ruby/ql/test/library-tests/dataflow/global/Flow.expected b/ruby/ql/test/library-tests/dataflow/global/Flow.expected index a6dd85ee0a1..ef1eb189de9 100644 --- a/ruby/ql/test/library-tests/dataflow/global/Flow.expected +++ b/ruby/ql/test/library-tests/dataflow/global/Flow.expected @@ -207,8 +207,10 @@ edges | instance_variables.rb:114:6:114:10 | foo13 [@field] : | instance_variables.rb:13:5:15:7 | self in get_field [@field] : | | instance_variables.rb:114:6:114:10 | foo13 [@field] : | instance_variables.rb:114:6:114:20 | call to get_field | | instance_variables.rb:114:6:114:10 | foo13 [@field] : | instance_variables.rb:114:6:114:20 | call to get_field | -| instance_variables.rb:116:9:116:26 | call to new [@field] : | instance_variables.rb:117:6:117:10 | foo15 [@field] : | -| instance_variables.rb:116:9:116:26 | call to new [@field] : | instance_variables.rb:117:6:117:10 | foo15 [@field] : | +| instance_variables.rb:116:1:116:5 | foo15 [@field] : | instance_variables.rb:117:6:117:10 | foo15 [@field] : | +| instance_variables.rb:116:1:116:5 | foo15 [@field] : | instance_variables.rb:117:6:117:10 | foo15 [@field] : | +| instance_variables.rb:116:9:116:26 | call to new [@field] : | instance_variables.rb:116:1:116:5 | foo15 [@field] : | +| instance_variables.rb:116:9:116:26 | call to new [@field] : | instance_variables.rb:116:1:116:5 | foo15 [@field] : | | instance_variables.rb:116:17:116:25 | call to taint : | instance_variables.rb:22:20:22:24 | field : | | instance_variables.rb:116:17:116:25 | call to taint : | instance_variables.rb:22:20:22:24 | field : | | instance_variables.rb:116:17:116:25 | call to taint : | instance_variables.rb:116:9:116:26 | call to new [@field] : | @@ -227,8 +229,10 @@ edges | instance_variables.rb:120:6:120:10 | foo16 [@field] : | instance_variables.rb:13:5:15:7 | self in get_field [@field] : | | instance_variables.rb:120:6:120:10 | foo16 [@field] : | instance_variables.rb:120:6:120:20 | call to get_field | | instance_variables.rb:120:6:120:10 | foo16 [@field] : | instance_variables.rb:120:6:120:20 | call to get_field | -| instance_variables.rb:121:7:121:24 | call to new : | instance_variables.rb:122:6:122:8 | bar | -| instance_variables.rb:121:7:121:24 | call to new : | instance_variables.rb:122:6:122:8 | bar | +| instance_variables.rb:121:1:121:3 | bar : | instance_variables.rb:122:6:122:8 | bar | +| instance_variables.rb:121:1:121:3 | bar : | instance_variables.rb:122:6:122:8 | bar | +| instance_variables.rb:121:7:121:24 | call to new : | instance_variables.rb:121:1:121:3 | bar : | +| instance_variables.rb:121:7:121:24 | call to new : | instance_variables.rb:121:1:121:3 | bar : | nodes | captured_variables.rb:1:24:1:24 | x : | semmle.label | x : | | captured_variables.rb:1:24:1:24 | x : | semmle.label | x : | @@ -424,6 +428,8 @@ nodes | instance_variables.rb:114:6:114:10 | foo13 [@field] : | semmle.label | foo13 [@field] : | | instance_variables.rb:114:6:114:20 | call to get_field | semmle.label | call to get_field | | instance_variables.rb:114:6:114:20 | call to get_field | semmle.label | call to get_field | +| instance_variables.rb:116:1:116:5 | foo15 [@field] : | semmle.label | foo15 [@field] : | +| instance_variables.rb:116:1:116:5 | foo15 [@field] : | semmle.label | foo15 [@field] : | | instance_variables.rb:116:9:116:26 | call to new [@field] : | semmle.label | call to new [@field] : | | instance_variables.rb:116:9:116:26 | call to new [@field] : | semmle.label | call to new [@field] : | | instance_variables.rb:116:17:116:25 | call to taint : | semmle.label | call to taint : | @@ -442,6 +448,8 @@ nodes | instance_variables.rb:120:6:120:10 | foo16 [@field] : | semmle.label | foo16 [@field] : | | instance_variables.rb:120:6:120:20 | call to get_field | semmle.label | call to get_field | | instance_variables.rb:120:6:120:20 | call to get_field | semmle.label | call to get_field | +| instance_variables.rb:121:1:121:3 | bar : | semmle.label | bar : | +| instance_variables.rb:121:1:121:3 | bar : | semmle.label | bar : | | instance_variables.rb:121:7:121:24 | call to new : | semmle.label | call to new : | | instance_variables.rb:121:7:121:24 | call to new : | semmle.label | call to new : | | instance_variables.rb:122:6:122:8 | bar | semmle.label | bar | diff --git a/ruby/ql/test/library-tests/dataflow/hash-flow/hash-flow.expected b/ruby/ql/test/library-tests/dataflow/hash-flow/hash-flow.expected index 2dc14a20525..57c6d4c0627 100644 --- a/ruby/ql/test/library-tests/dataflow/hash-flow/hash-flow.expected +++ b/ruby/ql/test/library-tests/dataflow/hash-flow/hash-flow.expected @@ -1,10 +1,15 @@ failures edges -| hash_flow.rb:11:15:11:24 | call to taint : | hash_flow.rb:22:10:22:13 | hash [element :a] : | -| hash_flow.rb:13:12:13:21 | call to taint : | hash_flow.rb:24:10:24:13 | hash [element :c] : | -| hash_flow.rb:15:14:15:23 | call to taint : | hash_flow.rb:26:10:26:13 | hash [element e] : | -| hash_flow.rb:17:16:17:25 | call to taint : | hash_flow.rb:28:10:28:13 | hash [element g] : | -| hash_flow.rb:19:14:19:23 | call to taint : | hash_flow.rb:30:10:30:13 | hash [element 0] : | +| hash_flow.rb:10:5:10:8 | hash [element 0] : | hash_flow.rb:30:10:30:13 | hash [element 0] : | +| hash_flow.rb:10:5:10:8 | hash [element :a] : | hash_flow.rb:22:10:22:13 | hash [element :a] : | +| hash_flow.rb:10:5:10:8 | hash [element :c] : | hash_flow.rb:24:10:24:13 | hash [element :c] : | +| hash_flow.rb:10:5:10:8 | hash [element e] : | hash_flow.rb:26:10:26:13 | hash [element e] : | +| hash_flow.rb:10:5:10:8 | hash [element g] : | hash_flow.rb:28:10:28:13 | hash [element g] : | +| hash_flow.rb:11:15:11:24 | call to taint : | hash_flow.rb:10:5:10:8 | hash [element :a] : | +| hash_flow.rb:13:12:13:21 | call to taint : | hash_flow.rb:10:5:10:8 | hash [element :c] : | +| hash_flow.rb:15:14:15:23 | call to taint : | hash_flow.rb:10:5:10:8 | hash [element e] : | +| hash_flow.rb:17:16:17:25 | call to taint : | hash_flow.rb:10:5:10:8 | hash [element g] : | +| hash_flow.rb:19:14:19:23 | call to taint : | hash_flow.rb:10:5:10:8 | hash [element 0] : | | hash_flow.rb:22:10:22:13 | hash [element :a] : | hash_flow.rb:22:10:22:17 | ...[...] | | hash_flow.rb:24:10:24:13 | hash [element :c] : | hash_flow.rb:24:10:24:17 | ...[...] | | hash_flow.rb:26:10:26:13 | hash [element e] : | hash_flow.rb:26:10:26:18 | ...[...] | @@ -37,161 +42,214 @@ edges | hash_flow.rb:44:10:44:13 | hash [element 0] : | hash_flow.rb:44:10:44:16 | ...[...] | | hash_flow.rb:46:10:46:13 | hash [element :a] : | hash_flow.rb:46:10:46:17 | ...[...] | | hash_flow.rb:48:10:48:13 | hash [element a] : | hash_flow.rb:48:10:48:18 | ...[...] | -| hash_flow.rb:55:13:55:37 | ...[...] [element :a] : | hash_flow.rb:56:10:56:14 | hash1 [element :a] : | +| hash_flow.rb:55:5:55:9 | hash1 [element :a] : | hash_flow.rb:56:10:56:14 | hash1 [element :a] : | +| hash_flow.rb:55:13:55:37 | ...[...] [element :a] : | hash_flow.rb:55:5:55:9 | hash1 [element :a] : | | hash_flow.rb:55:21:55:30 | call to taint : | hash_flow.rb:55:13:55:37 | ...[...] [element :a] : | | hash_flow.rb:56:10:56:14 | hash1 [element :a] : | hash_flow.rb:56:10:56:18 | ...[...] | -| hash_flow.rb:59:13:59:22 | call to taint : | hash_flow.rb:60:18:60:18 | x [element :a] : | -| hash_flow.rb:60:13:60:19 | ...[...] [element :a] : | hash_flow.rb:61:10:61:14 | hash2 [element :a] : | +| hash_flow.rb:59:5:59:5 | x [element :a] : | hash_flow.rb:60:18:60:18 | x [element :a] : | +| hash_flow.rb:59:13:59:22 | call to taint : | hash_flow.rb:59:5:59:5 | x [element :a] : | +| hash_flow.rb:60:5:60:9 | hash2 [element :a] : | hash_flow.rb:61:10:61:14 | hash2 [element :a] : | +| hash_flow.rb:60:13:60:19 | ...[...] [element :a] : | hash_flow.rb:60:5:60:9 | hash2 [element :a] : | | hash_flow.rb:60:18:60:18 | x [element :a] : | hash_flow.rb:60:13:60:19 | ...[...] [element :a] : | | hash_flow.rb:61:10:61:14 | hash2 [element :a] : | hash_flow.rb:61:10:61:18 | ...[...] | -| hash_flow.rb:64:13:64:45 | ...[...] [element] : | hash_flow.rb:65:10:65:14 | hash3 [element] : | -| hash_flow.rb:64:13:64:45 | ...[...] [element] : | hash_flow.rb:66:10:66:14 | hash3 [element] : | +| hash_flow.rb:64:5:64:9 | hash3 [element] : | hash_flow.rb:65:10:65:14 | hash3 [element] : | +| hash_flow.rb:64:5:64:9 | hash3 [element] : | hash_flow.rb:66:10:66:14 | hash3 [element] : | +| hash_flow.rb:64:13:64:45 | ...[...] [element] : | hash_flow.rb:64:5:64:9 | hash3 [element] : | | hash_flow.rb:64:24:64:33 | call to taint : | hash_flow.rb:64:13:64:45 | ...[...] [element] : | | hash_flow.rb:65:10:65:14 | hash3 [element] : | hash_flow.rb:65:10:65:18 | ...[...] | | hash_flow.rb:66:10:66:14 | hash3 [element] : | hash_flow.rb:66:10:66:18 | ...[...] | -| hash_flow.rb:68:13:68:39 | ...[...] [element :a] : | hash_flow.rb:69:10:69:14 | hash4 [element :a] : | +| hash_flow.rb:68:5:68:9 | hash4 [element :a] : | hash_flow.rb:69:10:69:14 | hash4 [element :a] : | +| hash_flow.rb:68:13:68:39 | ...[...] [element :a] : | hash_flow.rb:68:5:68:9 | hash4 [element :a] : | | hash_flow.rb:68:22:68:31 | call to taint : | hash_flow.rb:68:13:68:39 | ...[...] [element :a] : | | hash_flow.rb:69:10:69:14 | hash4 [element :a] : | hash_flow.rb:69:10:69:18 | ...[...] | -| hash_flow.rb:72:13:72:45 | ...[...] [element a] : | hash_flow.rb:73:10:73:14 | hash5 [element a] : | +| hash_flow.rb:72:5:72:9 | hash5 [element a] : | hash_flow.rb:73:10:73:14 | hash5 [element a] : | +| hash_flow.rb:72:13:72:45 | ...[...] [element a] : | hash_flow.rb:72:5:72:9 | hash5 [element a] : | | hash_flow.rb:72:25:72:34 | call to taint : | hash_flow.rb:72:13:72:45 | ...[...] [element a] : | | hash_flow.rb:73:10:73:14 | hash5 [element a] : | hash_flow.rb:73:10:73:19 | ...[...] | -| hash_flow.rb:76:13:76:47 | ...[...] [element a] : | hash_flow.rb:77:10:77:14 | hash6 [element a] : | +| hash_flow.rb:76:5:76:9 | hash6 [element a] : | hash_flow.rb:77:10:77:14 | hash6 [element a] : | +| hash_flow.rb:76:13:76:47 | ...[...] [element a] : | hash_flow.rb:76:5:76:9 | hash6 [element a] : | | hash_flow.rb:76:26:76:35 | call to taint : | hash_flow.rb:76:13:76:47 | ...[...] [element a] : | | hash_flow.rb:77:10:77:14 | hash6 [element a] : | hash_flow.rb:77:10:77:19 | ...[...] | -| hash_flow.rb:84:13:84:42 | call to [] [element :a] : | hash_flow.rb:85:10:85:14 | hash1 [element :a] : | +| hash_flow.rb:84:5:84:9 | hash1 [element :a] : | hash_flow.rb:85:10:85:14 | hash1 [element :a] : | +| hash_flow.rb:84:13:84:42 | call to [] [element :a] : | hash_flow.rb:84:5:84:9 | hash1 [element :a] : | | hash_flow.rb:84:26:84:35 | call to taint : | hash_flow.rb:84:13:84:42 | call to [] [element :a] : | | hash_flow.rb:85:10:85:14 | hash1 [element :a] : | hash_flow.rb:85:10:85:18 | ...[...] | -| hash_flow.rb:93:15:93:24 | call to taint : | hash_flow.rb:96:30:96:33 | hash [element :a] : | -| hash_flow.rb:96:13:96:34 | call to try_convert [element :a] : | hash_flow.rb:97:10:97:14 | hash2 [element :a] : | +| hash_flow.rb:92:5:92:8 | hash [element :a] : | hash_flow.rb:96:30:96:33 | hash [element :a] : | +| hash_flow.rb:93:15:93:24 | call to taint : | hash_flow.rb:92:5:92:8 | hash [element :a] : | +| hash_flow.rb:96:5:96:9 | hash2 [element :a] : | hash_flow.rb:97:10:97:14 | hash2 [element :a] : | +| hash_flow.rb:96:13:96:34 | call to try_convert [element :a] : | hash_flow.rb:96:5:96:9 | hash2 [element :a] : | | hash_flow.rb:96:30:96:33 | hash [element :a] : | hash_flow.rb:96:13:96:34 | call to try_convert [element :a] : | | hash_flow.rb:97:10:97:14 | hash2 [element :a] : | hash_flow.rb:97:10:97:18 | ...[...] | -| hash_flow.rb:105:21:105:30 | call to taint : | hash_flow.rb:106:10:106:10 | b | +| hash_flow.rb:105:5:105:5 | b : | hash_flow.rb:106:10:106:10 | b | +| hash_flow.rb:105:21:105:30 | __synth__0 : | hash_flow.rb:105:5:105:5 | b : | +| hash_flow.rb:105:21:105:30 | call to taint : | hash_flow.rb:105:21:105:30 | __synth__0 : | +| hash_flow.rb:113:5:113:5 | b : | hash_flow.rb:115:10:115:10 | b | | hash_flow.rb:113:9:113:12 | [post] hash [element :a] : | hash_flow.rb:114:10:114:13 | hash [element :a] : | -| hash_flow.rb:113:9:113:34 | call to store : | hash_flow.rb:115:10:115:10 | b | +| hash_flow.rb:113:9:113:34 | call to store : | hash_flow.rb:113:5:113:5 | b : | | hash_flow.rb:113:24:113:33 | call to taint : | hash_flow.rb:113:9:113:12 | [post] hash [element :a] : | | hash_flow.rb:113:24:113:33 | call to taint : | hash_flow.rb:113:9:113:34 | call to store : | | hash_flow.rb:114:10:114:13 | hash [element :a] : | hash_flow.rb:114:10:114:17 | ...[...] | +| hash_flow.rb:118:5:118:5 | c : | hash_flow.rb:121:10:121:10 | c | | hash_flow.rb:118:9:118:12 | [post] hash [element] : | hash_flow.rb:119:10:119:13 | hash [element] : | | hash_flow.rb:118:9:118:12 | [post] hash [element] : | hash_flow.rb:120:10:120:13 | hash [element] : | -| hash_flow.rb:118:9:118:33 | call to store : | hash_flow.rb:121:10:121:10 | c | +| hash_flow.rb:118:9:118:33 | call to store : | hash_flow.rb:118:5:118:5 | c : | | hash_flow.rb:118:23:118:32 | call to taint : | hash_flow.rb:118:9:118:12 | [post] hash [element] : | | hash_flow.rb:118:23:118:32 | call to taint : | hash_flow.rb:118:9:118:33 | call to store : | | hash_flow.rb:119:10:119:13 | hash [element] : | hash_flow.rb:119:10:119:17 | ...[...] | | hash_flow.rb:120:10:120:13 | hash [element] : | hash_flow.rb:120:10:120:17 | ...[...] | -| hash_flow.rb:128:15:128:24 | call to taint : | hash_flow.rb:131:5:131:8 | hash [element :a] : | -| hash_flow.rb:128:15:128:24 | call to taint : | hash_flow.rb:134:5:134:8 | hash [element :a] : | +| hash_flow.rb:127:5:127:8 | hash [element :a] : | hash_flow.rb:131:5:131:8 | hash [element :a] : | +| hash_flow.rb:127:5:127:8 | hash [element :a] : | hash_flow.rb:134:5:134:8 | hash [element :a] : | +| hash_flow.rb:128:15:128:24 | call to taint : | hash_flow.rb:127:5:127:8 | hash [element :a] : | | hash_flow.rb:131:5:131:8 | hash [element :a] : | hash_flow.rb:131:18:131:29 | key_or_value : | | hash_flow.rb:131:18:131:29 | key_or_value : | hash_flow.rb:132:14:132:25 | key_or_value | | hash_flow.rb:134:5:134:8 | hash [element :a] : | hash_flow.rb:134:22:134:26 | value : | | hash_flow.rb:134:22:134:26 | value : | hash_flow.rb:136:14:136:18 | value | -| hash_flow.rb:144:15:144:25 | call to taint : | hash_flow.rb:147:9:147:12 | hash [element :a] : | -| hash_flow.rb:144:15:144:25 | call to taint : | hash_flow.rb:151:9:151:12 | hash [element :a] : | +| hash_flow.rb:143:5:143:8 | hash [element :a] : | hash_flow.rb:147:9:147:12 | hash [element :a] : | +| hash_flow.rb:143:5:143:8 | hash [element :a] : | hash_flow.rb:151:9:151:12 | hash [element :a] : | +| hash_flow.rb:144:15:144:25 | call to taint : | hash_flow.rb:143:5:143:8 | hash [element :a] : | +| hash_flow.rb:147:5:147:5 | b [element 1] : | hash_flow.rb:149:10:149:10 | b [element 1] : | +| hash_flow.rb:147:5:147:5 | b [element 1] : | hash_flow.rb:150:10:150:10 | b [element 1] : | | hash_flow.rb:147:9:147:12 | hash [element :a] : | hash_flow.rb:147:9:147:22 | call to assoc [element 1] : | -| hash_flow.rb:147:9:147:22 | call to assoc [element 1] : | hash_flow.rb:149:10:149:10 | b [element 1] : | -| hash_flow.rb:147:9:147:22 | call to assoc [element 1] : | hash_flow.rb:150:10:150:10 | b [element 1] : | +| hash_flow.rb:147:9:147:22 | call to assoc [element 1] : | hash_flow.rb:147:5:147:5 | b [element 1] : | | hash_flow.rb:149:10:149:10 | b [element 1] : | hash_flow.rb:149:10:149:13 | ...[...] | | hash_flow.rb:150:10:150:10 | b [element 1] : | hash_flow.rb:150:10:150:13 | ...[...] | +| hash_flow.rb:151:5:151:5 | c [element 1] : | hash_flow.rb:152:10:152:10 | c [element 1] : | | hash_flow.rb:151:9:151:12 | hash [element :a] : | hash_flow.rb:151:9:151:21 | call to assoc [element 1] : | -| hash_flow.rb:151:9:151:21 | call to assoc [element 1] : | hash_flow.rb:152:10:152:10 | c [element 1] : | +| hash_flow.rb:151:9:151:21 | call to assoc [element 1] : | hash_flow.rb:151:5:151:5 | c [element 1] : | | hash_flow.rb:152:10:152:10 | c [element 1] : | hash_flow.rb:152:10:152:13 | ...[...] | -| hash_flow.rb:170:15:170:25 | call to taint : | hash_flow.rb:173:9:173:12 | hash [element :a] : | +| hash_flow.rb:169:5:169:8 | hash [element :a] : | hash_flow.rb:173:9:173:12 | hash [element :a] : | +| hash_flow.rb:170:15:170:25 | call to taint : | hash_flow.rb:169:5:169:8 | hash [element :a] : | +| hash_flow.rb:173:5:173:5 | a [element :a] : | hash_flow.rb:174:10:174:10 | a [element :a] : | | hash_flow.rb:173:9:173:12 | hash [element :a] : | hash_flow.rb:173:9:173:20 | call to compact [element :a] : | -| hash_flow.rb:173:9:173:20 | call to compact [element :a] : | hash_flow.rb:174:10:174:10 | a [element :a] : | +| hash_flow.rb:173:9:173:20 | call to compact [element :a] : | hash_flow.rb:173:5:173:5 | a [element :a] : | | hash_flow.rb:174:10:174:10 | a [element :a] : | hash_flow.rb:174:10:174:14 | ...[...] | -| hash_flow.rb:182:15:182:25 | call to taint : | hash_flow.rb:185:9:185:12 | hash [element :a] : | +| hash_flow.rb:181:5:181:8 | hash [element :a] : | hash_flow.rb:185:9:185:12 | hash [element :a] : | +| hash_flow.rb:182:15:182:25 | call to taint : | hash_flow.rb:181:5:181:8 | hash [element :a] : | +| hash_flow.rb:185:5:185:5 | a : | hash_flow.rb:186:10:186:10 | a | | hash_flow.rb:185:9:185:12 | hash [element :a] : | hash_flow.rb:185:9:185:23 | call to delete : | -| hash_flow.rb:185:9:185:23 | call to delete : | hash_flow.rb:186:10:186:10 | a | -| hash_flow.rb:194:15:194:25 | call to taint : | hash_flow.rb:197:9:197:12 | hash [element :a] : | +| hash_flow.rb:185:9:185:23 | call to delete : | hash_flow.rb:185:5:185:5 | a : | +| hash_flow.rb:193:5:193:8 | hash [element :a] : | hash_flow.rb:197:9:197:12 | hash [element :a] : | +| hash_flow.rb:194:15:194:25 | call to taint : | hash_flow.rb:193:5:193:8 | hash [element :a] : | +| hash_flow.rb:197:5:197:5 | a [element :a] : | hash_flow.rb:201:10:201:10 | a [element :a] : | | hash_flow.rb:197:9:197:12 | [post] hash [element :a] : | hash_flow.rb:202:10:202:13 | hash [element :a] : | | hash_flow.rb:197:9:197:12 | hash [element :a] : | hash_flow.rb:197:9:197:12 | [post] hash [element :a] : | | hash_flow.rb:197:9:197:12 | hash [element :a] : | hash_flow.rb:197:9:200:7 | call to delete_if [element :a] : | | hash_flow.rb:197:9:197:12 | hash [element :a] : | hash_flow.rb:197:33:197:37 | value : | -| hash_flow.rb:197:9:200:7 | call to delete_if [element :a] : | hash_flow.rb:201:10:201:10 | a [element :a] : | +| hash_flow.rb:197:9:200:7 | call to delete_if [element :a] : | hash_flow.rb:197:5:197:5 | a [element :a] : | | hash_flow.rb:197:33:197:37 | value : | hash_flow.rb:199:14:199:18 | value | | hash_flow.rb:201:10:201:10 | a [element :a] : | hash_flow.rb:201:10:201:14 | ...[...] | | hash_flow.rb:202:10:202:13 | hash [element :a] : | hash_flow.rb:202:10:202:17 | ...[...] | -| hash_flow.rb:210:15:210:25 | call to taint : | hash_flow.rb:217:10:217:13 | hash [element :a] : | -| hash_flow.rb:213:19:213:29 | call to taint : | hash_flow.rb:219:10:219:13 | hash [element :c, element :d] : | +| hash_flow.rb:209:5:209:8 | hash [element :a] : | hash_flow.rb:217:10:217:13 | hash [element :a] : | +| hash_flow.rb:209:5:209:8 | hash [element :c, element :d] : | hash_flow.rb:219:10:219:13 | hash [element :c, element :d] : | +| hash_flow.rb:210:15:210:25 | call to taint : | hash_flow.rb:209:5:209:8 | hash [element :a] : | +| hash_flow.rb:213:19:213:29 | call to taint : | hash_flow.rb:209:5:209:8 | hash [element :c, element :d] : | | hash_flow.rb:217:10:217:13 | hash [element :a] : | hash_flow.rb:217:10:217:21 | call to dig | | hash_flow.rb:219:10:219:13 | hash [element :c, element :d] : | hash_flow.rb:219:10:219:24 | call to dig | -| hash_flow.rb:227:15:227:25 | call to taint : | hash_flow.rb:230:9:230:12 | hash [element :a] : | +| hash_flow.rb:226:5:226:8 | hash [element :a] : | hash_flow.rb:230:9:230:12 | hash [element :a] : | +| hash_flow.rb:227:15:227:25 | call to taint : | hash_flow.rb:226:5:226:8 | hash [element :a] : | +| hash_flow.rb:230:5:230:5 | x [element :a] : | hash_flow.rb:234:10:234:10 | x [element :a] : | | hash_flow.rb:230:9:230:12 | hash [element :a] : | hash_flow.rb:230:9:233:7 | call to each [element :a] : | | hash_flow.rb:230:9:230:12 | hash [element :a] : | hash_flow.rb:230:28:230:32 | value : | -| hash_flow.rb:230:9:233:7 | call to each [element :a] : | hash_flow.rb:234:10:234:10 | x [element :a] : | +| hash_flow.rb:230:9:233:7 | call to each [element :a] : | hash_flow.rb:230:5:230:5 | x [element :a] : | | hash_flow.rb:230:28:230:32 | value : | hash_flow.rb:232:14:232:18 | value | | hash_flow.rb:234:10:234:10 | x [element :a] : | hash_flow.rb:234:10:234:14 | ...[...] | -| hash_flow.rb:242:15:242:25 | call to taint : | hash_flow.rb:245:9:245:12 | hash [element :a] : | +| hash_flow.rb:241:5:241:8 | hash [element :a] : | hash_flow.rb:245:9:245:12 | hash [element :a] : | +| hash_flow.rb:242:15:242:25 | call to taint : | hash_flow.rb:241:5:241:8 | hash [element :a] : | +| hash_flow.rb:245:5:245:5 | x [element :a] : | hash_flow.rb:248:10:248:10 | x [element :a] : | | hash_flow.rb:245:9:245:12 | hash [element :a] : | hash_flow.rb:245:9:247:7 | call to each_key [element :a] : | -| hash_flow.rb:245:9:247:7 | call to each_key [element :a] : | hash_flow.rb:248:10:248:10 | x [element :a] : | +| hash_flow.rb:245:9:247:7 | call to each_key [element :a] : | hash_flow.rb:245:5:245:5 | x [element :a] : | | hash_flow.rb:248:10:248:10 | x [element :a] : | hash_flow.rb:248:10:248:14 | ...[...] | -| hash_flow.rb:256:15:256:25 | call to taint : | hash_flow.rb:259:9:259:12 | hash [element :a] : | +| hash_flow.rb:255:5:255:8 | hash [element :a] : | hash_flow.rb:259:9:259:12 | hash [element :a] : | +| hash_flow.rb:256:15:256:25 | call to taint : | hash_flow.rb:255:5:255:8 | hash [element :a] : | +| hash_flow.rb:259:5:259:5 | x [element :a] : | hash_flow.rb:263:10:263:10 | x [element :a] : | | hash_flow.rb:259:9:259:12 | hash [element :a] : | hash_flow.rb:259:9:262:7 | call to each_pair [element :a] : | | hash_flow.rb:259:9:259:12 | hash [element :a] : | hash_flow.rb:259:33:259:37 | value : | -| hash_flow.rb:259:9:262:7 | call to each_pair [element :a] : | hash_flow.rb:263:10:263:10 | x [element :a] : | +| hash_flow.rb:259:9:262:7 | call to each_pair [element :a] : | hash_flow.rb:259:5:259:5 | x [element :a] : | | hash_flow.rb:259:33:259:37 | value : | hash_flow.rb:261:14:261:18 | value | | hash_flow.rb:263:10:263:10 | x [element :a] : | hash_flow.rb:263:10:263:14 | ...[...] | -| hash_flow.rb:271:15:271:25 | call to taint : | hash_flow.rb:274:9:274:12 | hash [element :a] : | +| hash_flow.rb:270:5:270:8 | hash [element :a] : | hash_flow.rb:274:9:274:12 | hash [element :a] : | +| hash_flow.rb:271:15:271:25 | call to taint : | hash_flow.rb:270:5:270:8 | hash [element :a] : | +| hash_flow.rb:274:5:274:5 | x [element :a] : | hash_flow.rb:277:10:277:10 | x [element :a] : | | hash_flow.rb:274:9:274:12 | hash [element :a] : | hash_flow.rb:274:9:276:7 | call to each_value [element :a] : | | hash_flow.rb:274:9:274:12 | hash [element :a] : | hash_flow.rb:274:29:274:33 | value : | -| hash_flow.rb:274:9:276:7 | call to each_value [element :a] : | hash_flow.rb:277:10:277:10 | x [element :a] : | +| hash_flow.rb:274:9:276:7 | call to each_value [element :a] : | hash_flow.rb:274:5:274:5 | x [element :a] : | | hash_flow.rb:274:29:274:33 | value : | hash_flow.rb:275:14:275:18 | value | | hash_flow.rb:277:10:277:10 | x [element :a] : | hash_flow.rb:277:10:277:14 | ...[...] | -| hash_flow.rb:287:15:287:25 | call to taint : | hash_flow.rb:290:9:290:12 | hash [element :c] : | +| hash_flow.rb:284:5:284:8 | hash [element :c] : | hash_flow.rb:290:9:290:12 | hash [element :c] : | +| hash_flow.rb:287:15:287:25 | call to taint : | hash_flow.rb:284:5:284:8 | hash [element :c] : | +| hash_flow.rb:290:5:290:5 | x [element :c] : | hash_flow.rb:293:10:293:10 | x [element :c] : | | hash_flow.rb:290:9:290:12 | hash [element :c] : | hash_flow.rb:290:9:290:28 | call to except [element :c] : | -| hash_flow.rb:290:9:290:28 | call to except [element :c] : | hash_flow.rb:293:10:293:10 | x [element :c] : | +| hash_flow.rb:290:9:290:28 | call to except [element :c] : | hash_flow.rb:290:5:290:5 | x [element :c] : | | hash_flow.rb:293:10:293:10 | x [element :c] : | hash_flow.rb:293:10:293:14 | ...[...] | -| hash_flow.rb:301:15:301:25 | call to taint : | hash_flow.rb:305:9:305:12 | hash [element :a] : | -| hash_flow.rb:301:15:301:25 | call to taint : | hash_flow.rb:309:9:309:12 | hash [element :a] : | -| hash_flow.rb:301:15:301:25 | call to taint : | hash_flow.rb:311:9:311:12 | hash [element :a] : | -| hash_flow.rb:301:15:301:25 | call to taint : | hash_flow.rb:315:9:315:12 | hash [element :a] : | -| hash_flow.rb:303:15:303:25 | call to taint : | hash_flow.rb:305:9:305:12 | hash [element :c] : | -| hash_flow.rb:303:15:303:25 | call to taint : | hash_flow.rb:315:9:315:12 | hash [element :c] : | +| hash_flow.rb:300:5:300:8 | hash [element :a] : | hash_flow.rb:305:9:305:12 | hash [element :a] : | +| hash_flow.rb:300:5:300:8 | hash [element :a] : | hash_flow.rb:309:9:309:12 | hash [element :a] : | +| hash_flow.rb:300:5:300:8 | hash [element :a] : | hash_flow.rb:311:9:311:12 | hash [element :a] : | +| hash_flow.rb:300:5:300:8 | hash [element :a] : | hash_flow.rb:315:9:315:12 | hash [element :a] : | +| hash_flow.rb:300:5:300:8 | hash [element :c] : | hash_flow.rb:305:9:305:12 | hash [element :c] : | +| hash_flow.rb:300:5:300:8 | hash [element :c] : | hash_flow.rb:315:9:315:12 | hash [element :c] : | +| hash_flow.rb:301:15:301:25 | call to taint : | hash_flow.rb:300:5:300:8 | hash [element :a] : | +| hash_flow.rb:303:15:303:25 | call to taint : | hash_flow.rb:300:5:300:8 | hash [element :c] : | +| hash_flow.rb:305:5:305:5 | b : | hash_flow.rb:308:10:308:10 | b | | hash_flow.rb:305:9:305:12 | hash [element :a] : | hash_flow.rb:305:9:307:7 | call to fetch : | | hash_flow.rb:305:9:305:12 | hash [element :c] : | hash_flow.rb:305:9:307:7 | call to fetch : | -| hash_flow.rb:305:9:307:7 | call to fetch : | hash_flow.rb:308:10:308:10 | b | +| hash_flow.rb:305:9:307:7 | call to fetch : | hash_flow.rb:305:5:305:5 | b : | | hash_flow.rb:305:20:305:30 | call to taint : | hash_flow.rb:305:37:305:37 | x : | | hash_flow.rb:305:37:305:37 | x : | hash_flow.rb:306:14:306:14 | x | +| hash_flow.rb:309:5:309:5 | b : | hash_flow.rb:310:10:310:10 | b | | hash_flow.rb:309:9:309:12 | hash [element :a] : | hash_flow.rb:309:9:309:22 | call to fetch : | -| hash_flow.rb:309:9:309:22 | call to fetch : | hash_flow.rb:310:10:310:10 | b | +| hash_flow.rb:309:9:309:22 | call to fetch : | hash_flow.rb:309:5:309:5 | b : | +| hash_flow.rb:311:5:311:5 | b : | hash_flow.rb:312:10:312:10 | b | | hash_flow.rb:311:9:311:12 | hash [element :a] : | hash_flow.rb:311:9:311:35 | call to fetch : | -| hash_flow.rb:311:9:311:35 | call to fetch : | hash_flow.rb:312:10:312:10 | b | +| hash_flow.rb:311:9:311:35 | call to fetch : | hash_flow.rb:311:5:311:5 | b : | | hash_flow.rb:311:24:311:34 | call to taint : | hash_flow.rb:311:9:311:35 | call to fetch : | -| hash_flow.rb:313:9:313:35 | call to fetch : | hash_flow.rb:314:10:314:10 | b | +| hash_flow.rb:313:5:313:5 | b : | hash_flow.rb:314:10:314:10 | b | +| hash_flow.rb:313:9:313:35 | call to fetch : | hash_flow.rb:313:5:313:5 | b : | | hash_flow.rb:313:24:313:34 | call to taint : | hash_flow.rb:313:9:313:35 | call to fetch : | +| hash_flow.rb:315:5:315:5 | b : | hash_flow.rb:316:10:316:10 | b | | hash_flow.rb:315:9:315:12 | hash [element :a] : | hash_flow.rb:315:9:315:34 | call to fetch : | | hash_flow.rb:315:9:315:12 | hash [element :c] : | hash_flow.rb:315:9:315:34 | call to fetch : | -| hash_flow.rb:315:9:315:34 | call to fetch : | hash_flow.rb:316:10:316:10 | b | +| hash_flow.rb:315:9:315:34 | call to fetch : | hash_flow.rb:315:5:315:5 | b : | | hash_flow.rb:315:23:315:33 | call to taint : | hash_flow.rb:315:9:315:34 | call to fetch : | -| hash_flow.rb:323:15:323:25 | call to taint : | hash_flow.rb:327:9:327:12 | hash [element :a] : | -| hash_flow.rb:323:15:323:25 | call to taint : | hash_flow.rb:332:9:332:12 | hash [element :a] : | -| hash_flow.rb:323:15:323:25 | call to taint : | hash_flow.rb:334:9:334:12 | hash [element :a] : | -| hash_flow.rb:325:15:325:25 | call to taint : | hash_flow.rb:327:9:327:12 | hash [element :c] : | -| hash_flow.rb:325:15:325:25 | call to taint : | hash_flow.rb:334:9:334:12 | hash [element :c] : | +| hash_flow.rb:322:5:322:8 | hash [element :a] : | hash_flow.rb:327:9:327:12 | hash [element :a] : | +| hash_flow.rb:322:5:322:8 | hash [element :a] : | hash_flow.rb:332:9:332:12 | hash [element :a] : | +| hash_flow.rb:322:5:322:8 | hash [element :a] : | hash_flow.rb:334:9:334:12 | hash [element :a] : | +| hash_flow.rb:322:5:322:8 | hash [element :c] : | hash_flow.rb:327:9:327:12 | hash [element :c] : | +| hash_flow.rb:322:5:322:8 | hash [element :c] : | hash_flow.rb:334:9:334:12 | hash [element :c] : | +| hash_flow.rb:323:15:323:25 | call to taint : | hash_flow.rb:322:5:322:8 | hash [element :a] : | +| hash_flow.rb:325:15:325:25 | call to taint : | hash_flow.rb:322:5:322:8 | hash [element :c] : | +| hash_flow.rb:327:5:327:5 | b [element] : | hash_flow.rb:331:10:331:10 | b [element] : | | hash_flow.rb:327:9:327:12 | hash [element :a] : | hash_flow.rb:327:9:330:7 | call to fetch_values [element] : | | hash_flow.rb:327:9:327:12 | hash [element :c] : | hash_flow.rb:327:9:330:7 | call to fetch_values [element] : | -| hash_flow.rb:327:9:330:7 | call to fetch_values [element] : | hash_flow.rb:331:10:331:10 | b [element] : | +| hash_flow.rb:327:9:330:7 | call to fetch_values [element] : | hash_flow.rb:327:5:327:5 | b [element] : | | hash_flow.rb:327:27:327:37 | call to taint : | hash_flow.rb:327:44:327:44 | x : | | hash_flow.rb:327:44:327:44 | x : | hash_flow.rb:328:14:328:14 | x | | hash_flow.rb:329:9:329:19 | call to taint : | hash_flow.rb:327:9:330:7 | call to fetch_values [element] : | | hash_flow.rb:331:10:331:10 | b [element] : | hash_flow.rb:331:10:331:13 | ...[...] | +| hash_flow.rb:332:5:332:5 | b [element] : | hash_flow.rb:333:10:333:10 | b [element] : | | hash_flow.rb:332:9:332:12 | hash [element :a] : | hash_flow.rb:332:9:332:29 | call to fetch_values [element] : | -| hash_flow.rb:332:9:332:29 | call to fetch_values [element] : | hash_flow.rb:333:10:333:10 | b [element] : | +| hash_flow.rb:332:9:332:29 | call to fetch_values [element] : | hash_flow.rb:332:5:332:5 | b [element] : | | hash_flow.rb:333:10:333:10 | b [element] : | hash_flow.rb:333:10:333:13 | ...[...] | +| hash_flow.rb:334:5:334:5 | b [element] : | hash_flow.rb:335:10:335:10 | b [element] : | | hash_flow.rb:334:9:334:12 | hash [element :a] : | hash_flow.rb:334:9:334:31 | call to fetch_values [element] : | | hash_flow.rb:334:9:334:12 | hash [element :c] : | hash_flow.rb:334:9:334:31 | call to fetch_values [element] : | -| hash_flow.rb:334:9:334:31 | call to fetch_values [element] : | hash_flow.rb:335:10:335:10 | b [element] : | +| hash_flow.rb:334:9:334:31 | call to fetch_values [element] : | hash_flow.rb:334:5:334:5 | b [element] : | | hash_flow.rb:335:10:335:10 | b [element] : | hash_flow.rb:335:10:335:13 | ...[...] | -| hash_flow.rb:342:15:342:25 | call to taint : | hash_flow.rb:346:9:346:12 | hash [element :a] : | -| hash_flow.rb:344:15:344:25 | call to taint : | hash_flow.rb:346:9:346:12 | hash [element :c] : | +| hash_flow.rb:341:5:341:8 | hash [element :a] : | hash_flow.rb:346:9:346:12 | hash [element :a] : | +| hash_flow.rb:341:5:341:8 | hash [element :c] : | hash_flow.rb:346:9:346:12 | hash [element :c] : | +| hash_flow.rb:342:15:342:25 | call to taint : | hash_flow.rb:341:5:341:8 | hash [element :a] : | +| hash_flow.rb:344:15:344:25 | call to taint : | hash_flow.rb:341:5:341:8 | hash [element :c] : | +| hash_flow.rb:346:5:346:5 | b [element :a] : | hash_flow.rb:351:11:351:11 | b [element :a] : | | hash_flow.rb:346:9:346:12 | hash [element :a] : | hash_flow.rb:346:9:350:7 | call to filter [element :a] : | | hash_flow.rb:346:9:346:12 | hash [element :a] : | hash_flow.rb:346:30:346:34 | value : | | hash_flow.rb:346:9:346:12 | hash [element :c] : | hash_flow.rb:346:30:346:34 | value : | -| hash_flow.rb:346:9:350:7 | call to filter [element :a] : | hash_flow.rb:351:11:351:11 | b [element :a] : | +| hash_flow.rb:346:9:350:7 | call to filter [element :a] : | hash_flow.rb:346:5:346:5 | b [element :a] : | | hash_flow.rb:346:30:346:34 | value : | hash_flow.rb:348:14:348:18 | value | | hash_flow.rb:351:11:351:11 | b [element :a] : | hash_flow.rb:351:11:351:15 | ...[...] : | | hash_flow.rb:351:11:351:15 | ...[...] : | hash_flow.rb:351:10:351:16 | ( ... ) | -| hash_flow.rb:358:15:358:25 | call to taint : | hash_flow.rb:362:5:362:8 | hash [element :a] : | -| hash_flow.rb:360:15:360:25 | call to taint : | hash_flow.rb:362:5:362:8 | hash [element :c] : | +| hash_flow.rb:357:5:357:8 | hash [element :a] : | hash_flow.rb:362:5:362:8 | hash [element :a] : | +| hash_flow.rb:357:5:357:8 | hash [element :c] : | hash_flow.rb:362:5:362:8 | hash [element :c] : | +| hash_flow.rb:358:15:358:25 | call to taint : | hash_flow.rb:357:5:357:8 | hash [element :a] : | +| hash_flow.rb:360:15:360:25 | call to taint : | hash_flow.rb:357:5:357:8 | hash [element :c] : | | hash_flow.rb:362:5:362:8 | [post] hash [element :a] : | hash_flow.rb:367:11:367:14 | hash [element :a] : | | hash_flow.rb:362:5:362:8 | hash [element :a] : | hash_flow.rb:362:5:362:8 | [post] hash [element :a] : | | hash_flow.rb:362:5:362:8 | hash [element :a] : | hash_flow.rb:362:27:362:31 | value : | @@ -199,40 +257,54 @@ edges | hash_flow.rb:362:27:362:31 | value : | hash_flow.rb:364:14:364:18 | value | | hash_flow.rb:367:11:367:14 | hash [element :a] : | hash_flow.rb:367:11:367:18 | ...[...] : | | hash_flow.rb:367:11:367:18 | ...[...] : | hash_flow.rb:367:10:367:19 | ( ... ) | -| hash_flow.rb:374:15:374:25 | call to taint : | hash_flow.rb:378:9:378:12 | hash [element :a] : | -| hash_flow.rb:376:15:376:25 | call to taint : | hash_flow.rb:378:9:378:12 | hash [element :c] : | +| hash_flow.rb:373:5:373:8 | hash [element :a] : | hash_flow.rb:378:9:378:12 | hash [element :a] : | +| hash_flow.rb:373:5:373:8 | hash [element :c] : | hash_flow.rb:378:9:378:12 | hash [element :c] : | +| hash_flow.rb:374:15:374:25 | call to taint : | hash_flow.rb:373:5:373:8 | hash [element :a] : | +| hash_flow.rb:376:15:376:25 | call to taint : | hash_flow.rb:373:5:373:8 | hash [element :c] : | +| hash_flow.rb:378:5:378:5 | b [element] : | hash_flow.rb:379:11:379:11 | b [element] : | | hash_flow.rb:378:9:378:12 | hash [element :a] : | hash_flow.rb:378:9:378:20 | call to flatten [element] : | | hash_flow.rb:378:9:378:12 | hash [element :c] : | hash_flow.rb:378:9:378:20 | call to flatten [element] : | -| hash_flow.rb:378:9:378:20 | call to flatten [element] : | hash_flow.rb:379:11:379:11 | b [element] : | +| hash_flow.rb:378:9:378:20 | call to flatten [element] : | hash_flow.rb:378:5:378:5 | b [element] : | | hash_flow.rb:379:11:379:11 | b [element] : | hash_flow.rb:379:11:379:14 | ...[...] : | | hash_flow.rb:379:11:379:14 | ...[...] : | hash_flow.rb:379:10:379:15 | ( ... ) | -| hash_flow.rb:386:15:386:25 | call to taint : | hash_flow.rb:390:9:390:12 | hash [element :a] : | -| hash_flow.rb:388:15:388:25 | call to taint : | hash_flow.rb:390:9:390:12 | hash [element :c] : | +| hash_flow.rb:385:5:385:8 | hash [element :a] : | hash_flow.rb:390:9:390:12 | hash [element :a] : | +| hash_flow.rb:385:5:385:8 | hash [element :c] : | hash_flow.rb:390:9:390:12 | hash [element :c] : | +| hash_flow.rb:386:15:386:25 | call to taint : | hash_flow.rb:385:5:385:8 | hash [element :a] : | +| hash_flow.rb:388:15:388:25 | call to taint : | hash_flow.rb:385:5:385:8 | hash [element :c] : | +| hash_flow.rb:390:5:390:5 | b [element :a] : | hash_flow.rb:396:11:396:11 | b [element :a] : | | hash_flow.rb:390:9:390:12 | [post] hash [element :a] : | hash_flow.rb:395:11:395:14 | hash [element :a] : | | hash_flow.rb:390:9:390:12 | hash [element :a] : | hash_flow.rb:390:9:390:12 | [post] hash [element :a] : | | hash_flow.rb:390:9:390:12 | hash [element :a] : | hash_flow.rb:390:9:394:7 | call to keep_if [element :a] : | | hash_flow.rb:390:9:390:12 | hash [element :a] : | hash_flow.rb:390:31:390:35 | value : | | hash_flow.rb:390:9:390:12 | hash [element :c] : | hash_flow.rb:390:31:390:35 | value : | -| hash_flow.rb:390:9:394:7 | call to keep_if [element :a] : | hash_flow.rb:396:11:396:11 | b [element :a] : | +| hash_flow.rb:390:9:394:7 | call to keep_if [element :a] : | hash_flow.rb:390:5:390:5 | b [element :a] : | | hash_flow.rb:390:31:390:35 | value : | hash_flow.rb:392:14:392:18 | value | | hash_flow.rb:395:11:395:14 | hash [element :a] : | hash_flow.rb:395:11:395:18 | ...[...] : | | hash_flow.rb:395:11:395:18 | ...[...] : | hash_flow.rb:395:10:395:19 | ( ... ) | | hash_flow.rb:396:11:396:11 | b [element :a] : | hash_flow.rb:396:11:396:15 | ...[...] : | | hash_flow.rb:396:11:396:15 | ...[...] : | hash_flow.rb:396:10:396:16 | ( ... ) | -| hash_flow.rb:403:15:403:25 | call to taint : | hash_flow.rb:412:12:412:16 | hash1 [element :a] : | -| hash_flow.rb:405:15:405:25 | call to taint : | hash_flow.rb:412:12:412:16 | hash1 [element :c] : | -| hash_flow.rb:408:15:408:25 | call to taint : | hash_flow.rb:412:24:412:28 | hash2 [element :d] : | -| hash_flow.rb:410:15:410:25 | call to taint : | hash_flow.rb:412:24:412:28 | hash2 [element :f] : | +| hash_flow.rb:402:5:402:9 | hash1 [element :a] : | hash_flow.rb:412:12:412:16 | hash1 [element :a] : | +| hash_flow.rb:402:5:402:9 | hash1 [element :c] : | hash_flow.rb:412:12:412:16 | hash1 [element :c] : | +| hash_flow.rb:403:15:403:25 | call to taint : | hash_flow.rb:402:5:402:9 | hash1 [element :a] : | +| hash_flow.rb:405:15:405:25 | call to taint : | hash_flow.rb:402:5:402:9 | hash1 [element :c] : | +| hash_flow.rb:407:5:407:9 | hash2 [element :d] : | hash_flow.rb:412:24:412:28 | hash2 [element :d] : | +| hash_flow.rb:407:5:407:9 | hash2 [element :f] : | hash_flow.rb:412:24:412:28 | hash2 [element :f] : | +| hash_flow.rb:408:15:408:25 | call to taint : | hash_flow.rb:407:5:407:9 | hash2 [element :d] : | +| hash_flow.rb:410:15:410:25 | call to taint : | hash_flow.rb:407:5:407:9 | hash2 [element :f] : | +| hash_flow.rb:412:5:412:8 | hash [element :a] : | hash_flow.rb:417:11:417:14 | hash [element :a] : | +| hash_flow.rb:412:5:412:8 | hash [element :c] : | hash_flow.rb:419:11:419:14 | hash [element :c] : | +| hash_flow.rb:412:5:412:8 | hash [element :d] : | hash_flow.rb:420:11:420:14 | hash [element :d] : | +| hash_flow.rb:412:5:412:8 | hash [element :f] : | hash_flow.rb:422:11:422:14 | hash [element :f] : | | hash_flow.rb:412:12:412:16 | hash1 [element :a] : | hash_flow.rb:412:12:416:7 | call to merge [element :a] : | | hash_flow.rb:412:12:412:16 | hash1 [element :a] : | hash_flow.rb:412:40:412:48 | old_value : | | hash_flow.rb:412:12:412:16 | hash1 [element :a] : | hash_flow.rb:412:51:412:59 | new_value : | | hash_flow.rb:412:12:412:16 | hash1 [element :c] : | hash_flow.rb:412:12:416:7 | call to merge [element :c] : | | hash_flow.rb:412:12:412:16 | hash1 [element :c] : | hash_flow.rb:412:40:412:48 | old_value : | | hash_flow.rb:412:12:412:16 | hash1 [element :c] : | hash_flow.rb:412:51:412:59 | new_value : | -| hash_flow.rb:412:12:416:7 | call to merge [element :a] : | hash_flow.rb:417:11:417:14 | hash [element :a] : | -| hash_flow.rb:412:12:416:7 | call to merge [element :c] : | hash_flow.rb:419:11:419:14 | hash [element :c] : | -| hash_flow.rb:412:12:416:7 | call to merge [element :d] : | hash_flow.rb:420:11:420:14 | hash [element :d] : | -| hash_flow.rb:412:12:416:7 | call to merge [element :f] : | hash_flow.rb:422:11:422:14 | hash [element :f] : | +| hash_flow.rb:412:12:416:7 | call to merge [element :a] : | hash_flow.rb:412:5:412:8 | hash [element :a] : | +| hash_flow.rb:412:12:416:7 | call to merge [element :c] : | hash_flow.rb:412:5:412:8 | hash [element :c] : | +| hash_flow.rb:412:12:416:7 | call to merge [element :d] : | hash_flow.rb:412:5:412:8 | hash [element :d] : | +| hash_flow.rb:412:12:416:7 | call to merge [element :f] : | hash_flow.rb:412:5:412:8 | hash [element :f] : | | hash_flow.rb:412:24:412:28 | hash2 [element :d] : | hash_flow.rb:412:12:416:7 | call to merge [element :d] : | | hash_flow.rb:412:24:412:28 | hash2 [element :d] : | hash_flow.rb:412:40:412:48 | old_value : | | hash_flow.rb:412:24:412:28 | hash2 [element :d] : | hash_flow.rb:412:51:412:59 | new_value : | @@ -249,10 +321,18 @@ edges | hash_flow.rb:420:11:420:18 | ...[...] : | hash_flow.rb:420:10:420:19 | ( ... ) | | hash_flow.rb:422:11:422:14 | hash [element :f] : | hash_flow.rb:422:11:422:18 | ...[...] : | | hash_flow.rb:422:11:422:18 | ...[...] : | hash_flow.rb:422:10:422:19 | ( ... ) | -| hash_flow.rb:429:15:429:25 | call to taint : | hash_flow.rb:438:12:438:16 | hash1 [element :a] : | -| hash_flow.rb:431:15:431:25 | call to taint : | hash_flow.rb:438:12:438:16 | hash1 [element :c] : | -| hash_flow.rb:434:15:434:25 | call to taint : | hash_flow.rb:438:25:438:29 | hash2 [element :d] : | -| hash_flow.rb:436:15:436:25 | call to taint : | hash_flow.rb:438:25:438:29 | hash2 [element :f] : | +| hash_flow.rb:428:5:428:9 | hash1 [element :a] : | hash_flow.rb:438:12:438:16 | hash1 [element :a] : | +| hash_flow.rb:428:5:428:9 | hash1 [element :c] : | hash_flow.rb:438:12:438:16 | hash1 [element :c] : | +| hash_flow.rb:429:15:429:25 | call to taint : | hash_flow.rb:428:5:428:9 | hash1 [element :a] : | +| hash_flow.rb:431:15:431:25 | call to taint : | hash_flow.rb:428:5:428:9 | hash1 [element :c] : | +| hash_flow.rb:433:5:433:9 | hash2 [element :d] : | hash_flow.rb:438:25:438:29 | hash2 [element :d] : | +| hash_flow.rb:433:5:433:9 | hash2 [element :f] : | hash_flow.rb:438:25:438:29 | hash2 [element :f] : | +| hash_flow.rb:434:15:434:25 | call to taint : | hash_flow.rb:433:5:433:9 | hash2 [element :d] : | +| hash_flow.rb:436:15:436:25 | call to taint : | hash_flow.rb:433:5:433:9 | hash2 [element :f] : | +| hash_flow.rb:438:5:438:8 | hash [element :a] : | hash_flow.rb:443:11:443:14 | hash [element :a] : | +| hash_flow.rb:438:5:438:8 | hash [element :c] : | hash_flow.rb:445:11:445:14 | hash [element :c] : | +| hash_flow.rb:438:5:438:8 | hash [element :d] : | hash_flow.rb:446:11:446:14 | hash [element :d] : | +| hash_flow.rb:438:5:438:8 | hash [element :f] : | hash_flow.rb:448:11:448:14 | hash [element :f] : | | hash_flow.rb:438:12:438:16 | [post] hash1 [element :a] : | hash_flow.rb:450:11:450:15 | hash1 [element :a] : | | hash_flow.rb:438:12:438:16 | [post] hash1 [element :c] : | hash_flow.rb:452:11:452:15 | hash1 [element :c] : | | hash_flow.rb:438:12:438:16 | [post] hash1 [element :d] : | hash_flow.rb:453:11:453:15 | hash1 [element :d] : | @@ -265,10 +345,10 @@ edges | hash_flow.rb:438:12:438:16 | hash1 [element :c] : | hash_flow.rb:438:12:442:7 | call to merge! [element :c] : | | hash_flow.rb:438:12:438:16 | hash1 [element :c] : | hash_flow.rb:438:41:438:49 | old_value : | | hash_flow.rb:438:12:438:16 | hash1 [element :c] : | hash_flow.rb:438:52:438:60 | new_value : | -| hash_flow.rb:438:12:442:7 | call to merge! [element :a] : | hash_flow.rb:443:11:443:14 | hash [element :a] : | -| hash_flow.rb:438:12:442:7 | call to merge! [element :c] : | hash_flow.rb:445:11:445:14 | hash [element :c] : | -| hash_flow.rb:438:12:442:7 | call to merge! [element :d] : | hash_flow.rb:446:11:446:14 | hash [element :d] : | -| hash_flow.rb:438:12:442:7 | call to merge! [element :f] : | hash_flow.rb:448:11:448:14 | hash [element :f] : | +| hash_flow.rb:438:12:442:7 | call to merge! [element :a] : | hash_flow.rb:438:5:438:8 | hash [element :a] : | +| hash_flow.rb:438:12:442:7 | call to merge! [element :c] : | hash_flow.rb:438:5:438:8 | hash [element :c] : | +| hash_flow.rb:438:12:442:7 | call to merge! [element :d] : | hash_flow.rb:438:5:438:8 | hash [element :d] : | +| hash_flow.rb:438:12:442:7 | call to merge! [element :f] : | hash_flow.rb:438:5:438:8 | hash [element :f] : | | hash_flow.rb:438:25:438:29 | hash2 [element :d] : | hash_flow.rb:438:12:438:16 | [post] hash1 [element :d] : | | hash_flow.rb:438:25:438:29 | hash2 [element :d] : | hash_flow.rb:438:12:442:7 | call to merge! [element :d] : | | hash_flow.rb:438:25:438:29 | hash2 [element :d] : | hash_flow.rb:438:41:438:49 | old_value : | @@ -295,27 +375,35 @@ edges | hash_flow.rb:453:11:453:19 | ...[...] : | hash_flow.rb:453:10:453:20 | ( ... ) | | hash_flow.rb:455:11:455:15 | hash1 [element :f] : | hash_flow.rb:455:11:455:19 | ...[...] : | | hash_flow.rb:455:11:455:19 | ...[...] : | hash_flow.rb:455:10:455:20 | ( ... ) | -| hash_flow.rb:462:15:462:25 | call to taint : | hash_flow.rb:465:9:465:12 | hash [element :a] : | +| hash_flow.rb:461:5:461:8 | hash [element :a] : | hash_flow.rb:465:9:465:12 | hash [element :a] : | +| hash_flow.rb:462:15:462:25 | call to taint : | hash_flow.rb:461:5:461:8 | hash [element :a] : | +| hash_flow.rb:465:5:465:5 | b [element 1] : | hash_flow.rb:467:10:467:10 | b [element 1] : | | hash_flow.rb:465:9:465:12 | hash [element :a] : | hash_flow.rb:465:9:465:22 | call to rassoc [element 1] : | -| hash_flow.rb:465:9:465:22 | call to rassoc [element 1] : | hash_flow.rb:467:10:467:10 | b [element 1] : | +| hash_flow.rb:465:9:465:22 | call to rassoc [element 1] : | hash_flow.rb:465:5:465:5 | b [element 1] : | | hash_flow.rb:467:10:467:10 | b [element 1] : | hash_flow.rb:467:10:467:13 | ...[...] | -| hash_flow.rb:474:15:474:25 | call to taint : | hash_flow.rb:477:9:477:12 | hash [element :a] : | +| hash_flow.rb:473:5:473:8 | hash [element :a] : | hash_flow.rb:477:9:477:12 | hash [element :a] : | +| hash_flow.rb:474:15:474:25 | call to taint : | hash_flow.rb:473:5:473:8 | hash [element :a] : | +| hash_flow.rb:477:5:477:5 | b [element :a] : | hash_flow.rb:482:10:482:10 | b [element :a] : | | hash_flow.rb:477:9:477:12 | hash [element :a] : | hash_flow.rb:477:9:481:7 | call to reject [element :a] : | | hash_flow.rb:477:9:477:12 | hash [element :a] : | hash_flow.rb:477:29:477:33 | value : | -| hash_flow.rb:477:9:481:7 | call to reject [element :a] : | hash_flow.rb:482:10:482:10 | b [element :a] : | +| hash_flow.rb:477:9:481:7 | call to reject [element :a] : | hash_flow.rb:477:5:477:5 | b [element :a] : | | hash_flow.rb:477:29:477:33 | value : | hash_flow.rb:479:14:479:18 | value | | hash_flow.rb:482:10:482:10 | b [element :a] : | hash_flow.rb:482:10:482:14 | ...[...] | -| hash_flow.rb:489:15:489:25 | call to taint : | hash_flow.rb:492:9:492:12 | hash [element :a] : | +| hash_flow.rb:488:5:488:8 | hash [element :a] : | hash_flow.rb:492:9:492:12 | hash [element :a] : | +| hash_flow.rb:489:15:489:25 | call to taint : | hash_flow.rb:488:5:488:8 | hash [element :a] : | +| hash_flow.rb:492:5:492:5 | b [element :a] : | hash_flow.rb:497:10:497:10 | b [element :a] : | | hash_flow.rb:492:9:492:12 | [post] hash [element :a] : | hash_flow.rb:498:10:498:13 | hash [element :a] : | | hash_flow.rb:492:9:492:12 | hash [element :a] : | hash_flow.rb:492:9:492:12 | [post] hash [element :a] : | | hash_flow.rb:492:9:492:12 | hash [element :a] : | hash_flow.rb:492:9:496:7 | call to reject! [element :a] : | | hash_flow.rb:492:9:492:12 | hash [element :a] : | hash_flow.rb:492:30:492:34 | value : | -| hash_flow.rb:492:9:496:7 | call to reject! [element :a] : | hash_flow.rb:497:10:497:10 | b [element :a] : | +| hash_flow.rb:492:9:496:7 | call to reject! [element :a] : | hash_flow.rb:492:5:492:5 | b [element :a] : | | hash_flow.rb:492:30:492:34 | value : | hash_flow.rb:494:14:494:18 | value | | hash_flow.rb:497:10:497:10 | b [element :a] : | hash_flow.rb:497:10:497:14 | ...[...] | | hash_flow.rb:498:10:498:13 | hash [element :a] : | hash_flow.rb:498:10:498:17 | ...[...] | -| hash_flow.rb:505:15:505:25 | call to taint : | hash_flow.rb:512:19:512:22 | hash [element :a] : | -| hash_flow.rb:507:15:507:25 | call to taint : | hash_flow.rb:512:19:512:22 | hash [element :c] : | +| hash_flow.rb:504:5:504:8 | hash [element :a] : | hash_flow.rb:512:19:512:22 | hash [element :a] : | +| hash_flow.rb:504:5:504:8 | hash [element :c] : | hash_flow.rb:512:19:512:22 | hash [element :c] : | +| hash_flow.rb:505:15:505:25 | call to taint : | hash_flow.rb:504:5:504:8 | hash [element :a] : | +| hash_flow.rb:507:15:507:25 | call to taint : | hash_flow.rb:504:5:504:8 | hash [element :c] : | | hash_flow.rb:512:5:512:9 | [post] hash2 [element :a] : | hash_flow.rb:513:11:513:15 | hash2 [element :a] : | | hash_flow.rb:512:5:512:9 | [post] hash2 [element :c] : | hash_flow.rb:515:11:515:15 | hash2 [element :c] : | | hash_flow.rb:512:19:512:22 | hash [element :a] : | hash_flow.rb:512:5:512:9 | [post] hash2 [element :a] : | @@ -324,17 +412,22 @@ edges | hash_flow.rb:513:11:513:19 | ...[...] : | hash_flow.rb:513:10:513:20 | ( ... ) | | hash_flow.rb:515:11:515:15 | hash2 [element :c] : | hash_flow.rb:515:11:515:19 | ...[...] : | | hash_flow.rb:515:11:515:19 | ...[...] : | hash_flow.rb:515:10:515:20 | ( ... ) | -| hash_flow.rb:520:15:520:25 | call to taint : | hash_flow.rb:524:9:524:12 | hash [element :a] : | -| hash_flow.rb:522:15:522:25 | call to taint : | hash_flow.rb:524:9:524:12 | hash [element :c] : | +| hash_flow.rb:519:5:519:8 | hash [element :a] : | hash_flow.rb:524:9:524:12 | hash [element :a] : | +| hash_flow.rb:519:5:519:8 | hash [element :c] : | hash_flow.rb:524:9:524:12 | hash [element :c] : | +| hash_flow.rb:520:15:520:25 | call to taint : | hash_flow.rb:519:5:519:8 | hash [element :a] : | +| hash_flow.rb:522:15:522:25 | call to taint : | hash_flow.rb:519:5:519:8 | hash [element :c] : | +| hash_flow.rb:524:5:524:5 | b [element :a] : | hash_flow.rb:529:11:529:11 | b [element :a] : | | hash_flow.rb:524:9:524:12 | hash [element :a] : | hash_flow.rb:524:9:528:7 | call to select [element :a] : | | hash_flow.rb:524:9:524:12 | hash [element :a] : | hash_flow.rb:524:30:524:34 | value : | | hash_flow.rb:524:9:524:12 | hash [element :c] : | hash_flow.rb:524:30:524:34 | value : | -| hash_flow.rb:524:9:528:7 | call to select [element :a] : | hash_flow.rb:529:11:529:11 | b [element :a] : | +| hash_flow.rb:524:9:528:7 | call to select [element :a] : | hash_flow.rb:524:5:524:5 | b [element :a] : | | hash_flow.rb:524:30:524:34 | value : | hash_flow.rb:526:14:526:18 | value | | hash_flow.rb:529:11:529:11 | b [element :a] : | hash_flow.rb:529:11:529:15 | ...[...] : | | hash_flow.rb:529:11:529:15 | ...[...] : | hash_flow.rb:529:10:529:16 | ( ... ) | -| hash_flow.rb:536:15:536:25 | call to taint : | hash_flow.rb:540:5:540:8 | hash [element :a] : | -| hash_flow.rb:538:15:538:25 | call to taint : | hash_flow.rb:540:5:540:8 | hash [element :c] : | +| hash_flow.rb:535:5:535:8 | hash [element :a] : | hash_flow.rb:540:5:540:8 | hash [element :a] : | +| hash_flow.rb:535:5:535:8 | hash [element :c] : | hash_flow.rb:540:5:540:8 | hash [element :c] : | +| hash_flow.rb:536:15:536:25 | call to taint : | hash_flow.rb:535:5:535:8 | hash [element :a] : | +| hash_flow.rb:538:15:538:25 | call to taint : | hash_flow.rb:535:5:535:8 | hash [element :c] : | | hash_flow.rb:540:5:540:8 | [post] hash [element :a] : | hash_flow.rb:545:11:545:14 | hash [element :a] : | | hash_flow.rb:540:5:540:8 | hash [element :a] : | hash_flow.rb:540:5:540:8 | [post] hash [element :a] : | | hash_flow.rb:540:5:540:8 | hash [element :a] : | hash_flow.rb:540:27:540:31 | value : | @@ -342,74 +435,95 @@ edges | hash_flow.rb:540:27:540:31 | value : | hash_flow.rb:542:14:542:18 | value | | hash_flow.rb:545:11:545:14 | hash [element :a] : | hash_flow.rb:545:11:545:18 | ...[...] : | | hash_flow.rb:545:11:545:18 | ...[...] : | hash_flow.rb:545:10:545:19 | ( ... ) | -| hash_flow.rb:552:15:552:25 | call to taint : | hash_flow.rb:556:9:556:12 | hash [element :a] : | -| hash_flow.rb:554:15:554:25 | call to taint : | hash_flow.rb:556:9:556:12 | hash [element :c] : | +| hash_flow.rb:551:5:551:8 | hash [element :a] : | hash_flow.rb:556:9:556:12 | hash [element :a] : | +| hash_flow.rb:551:5:551:8 | hash [element :c] : | hash_flow.rb:556:9:556:12 | hash [element :c] : | +| hash_flow.rb:552:15:552:25 | call to taint : | hash_flow.rb:551:5:551:8 | hash [element :a] : | +| hash_flow.rb:554:15:554:25 | call to taint : | hash_flow.rb:551:5:551:8 | hash [element :c] : | +| hash_flow.rb:556:5:556:5 | b [element 1] : | hash_flow.rb:559:11:559:11 | b [element 1] : | | hash_flow.rb:556:9:556:12 | [post] hash [element :a] : | hash_flow.rb:557:11:557:14 | hash [element :a] : | | hash_flow.rb:556:9:556:12 | hash [element :a] : | hash_flow.rb:556:9:556:12 | [post] hash [element :a] : | | hash_flow.rb:556:9:556:12 | hash [element :a] : | hash_flow.rb:556:9:556:18 | call to shift [element 1] : | | hash_flow.rb:556:9:556:12 | hash [element :c] : | hash_flow.rb:556:9:556:18 | call to shift [element 1] : | -| hash_flow.rb:556:9:556:18 | call to shift [element 1] : | hash_flow.rb:559:11:559:11 | b [element 1] : | +| hash_flow.rb:556:9:556:18 | call to shift [element 1] : | hash_flow.rb:556:5:556:5 | b [element 1] : | | hash_flow.rb:557:11:557:14 | hash [element :a] : | hash_flow.rb:557:11:557:18 | ...[...] : | | hash_flow.rb:557:11:557:18 | ...[...] : | hash_flow.rb:557:10:557:19 | ( ... ) | | hash_flow.rb:559:11:559:11 | b [element 1] : | hash_flow.rb:559:11:559:14 | ...[...] : | | hash_flow.rb:559:11:559:14 | ...[...] : | hash_flow.rb:559:10:559:15 | ( ... ) | -| hash_flow.rb:566:15:566:25 | call to taint : | hash_flow.rb:570:9:570:12 | hash [element :a] : | -| hash_flow.rb:566:15:566:25 | call to taint : | hash_flow.rb:575:9:575:12 | hash [element :a] : | -| hash_flow.rb:568:15:568:25 | call to taint : | hash_flow.rb:575:9:575:12 | hash [element :c] : | +| hash_flow.rb:565:5:565:8 | hash [element :a] : | hash_flow.rb:570:9:570:12 | hash [element :a] : | +| hash_flow.rb:565:5:565:8 | hash [element :a] : | hash_flow.rb:575:9:575:12 | hash [element :a] : | +| hash_flow.rb:565:5:565:8 | hash [element :c] : | hash_flow.rb:575:9:575:12 | hash [element :c] : | +| hash_flow.rb:566:15:566:25 | call to taint : | hash_flow.rb:565:5:565:8 | hash [element :a] : | +| hash_flow.rb:568:15:568:25 | call to taint : | hash_flow.rb:565:5:565:8 | hash [element :c] : | +| hash_flow.rb:570:5:570:5 | b [element :a] : | hash_flow.rb:571:11:571:11 | b [element :a] : | | hash_flow.rb:570:9:570:12 | hash [element :a] : | hash_flow.rb:570:9:570:26 | call to slice [element :a] : | -| hash_flow.rb:570:9:570:26 | call to slice [element :a] : | hash_flow.rb:571:11:571:11 | b [element :a] : | +| hash_flow.rb:570:9:570:26 | call to slice [element :a] : | hash_flow.rb:570:5:570:5 | b [element :a] : | | hash_flow.rb:571:11:571:11 | b [element :a] : | hash_flow.rb:571:11:571:15 | ...[...] : | | hash_flow.rb:571:11:571:15 | ...[...] : | hash_flow.rb:571:10:571:16 | ( ... ) | +| hash_flow.rb:575:5:575:5 | c [element :a] : | hash_flow.rb:576:11:576:11 | c [element :a] : | +| hash_flow.rb:575:5:575:5 | c [element :c] : | hash_flow.rb:578:11:578:11 | c [element :c] : | | hash_flow.rb:575:9:575:12 | hash [element :a] : | hash_flow.rb:575:9:575:25 | call to slice [element :a] : | | hash_flow.rb:575:9:575:12 | hash [element :c] : | hash_flow.rb:575:9:575:25 | call to slice [element :c] : | -| hash_flow.rb:575:9:575:25 | call to slice [element :a] : | hash_flow.rb:576:11:576:11 | c [element :a] : | -| hash_flow.rb:575:9:575:25 | call to slice [element :c] : | hash_flow.rb:578:11:578:11 | c [element :c] : | +| hash_flow.rb:575:9:575:25 | call to slice [element :a] : | hash_flow.rb:575:5:575:5 | c [element :a] : | +| hash_flow.rb:575:9:575:25 | call to slice [element :c] : | hash_flow.rb:575:5:575:5 | c [element :c] : | | hash_flow.rb:576:11:576:11 | c [element :a] : | hash_flow.rb:576:11:576:15 | ...[...] : | | hash_flow.rb:576:11:576:15 | ...[...] : | hash_flow.rb:576:10:576:16 | ( ... ) | | hash_flow.rb:578:11:578:11 | c [element :c] : | hash_flow.rb:578:11:578:15 | ...[...] : | | hash_flow.rb:578:11:578:15 | ...[...] : | hash_flow.rb:578:10:578:16 | ( ... ) | -| hash_flow.rb:585:15:585:25 | call to taint : | hash_flow.rb:589:9:589:12 | hash [element :a] : | -| hash_flow.rb:587:15:587:25 | call to taint : | hash_flow.rb:589:9:589:12 | hash [element :c] : | +| hash_flow.rb:584:5:584:8 | hash [element :a] : | hash_flow.rb:589:9:589:12 | hash [element :a] : | +| hash_flow.rb:584:5:584:8 | hash [element :c] : | hash_flow.rb:589:9:589:12 | hash [element :c] : | +| hash_flow.rb:585:15:585:25 | call to taint : | hash_flow.rb:584:5:584:8 | hash [element :a] : | +| hash_flow.rb:587:15:587:25 | call to taint : | hash_flow.rb:584:5:584:8 | hash [element :c] : | +| hash_flow.rb:589:5:589:5 | a [element, element 1] : | hash_flow.rb:591:11:591:11 | a [element, element 1] : | | hash_flow.rb:589:9:589:12 | hash [element :a] : | hash_flow.rb:589:9:589:17 | call to to_a [element, element 1] : | | hash_flow.rb:589:9:589:12 | hash [element :c] : | hash_flow.rb:589:9:589:17 | call to to_a [element, element 1] : | -| hash_flow.rb:589:9:589:17 | call to to_a [element, element 1] : | hash_flow.rb:591:11:591:11 | a [element, element 1] : | +| hash_flow.rb:589:9:589:17 | call to to_a [element, element 1] : | hash_flow.rb:589:5:589:5 | a [element, element 1] : | | hash_flow.rb:591:11:591:11 | a [element, element 1] : | hash_flow.rb:591:11:591:14 | ...[...] [element 1] : | | hash_flow.rb:591:11:591:14 | ...[...] [element 1] : | hash_flow.rb:591:11:591:17 | ...[...] : | | hash_flow.rb:591:11:591:17 | ...[...] : | hash_flow.rb:591:10:591:18 | ( ... ) | -| hash_flow.rb:598:15:598:25 | call to taint : | hash_flow.rb:602:9:602:12 | hash [element :a] : | -| hash_flow.rb:598:15:598:25 | call to taint : | hash_flow.rb:607:9:607:12 | hash [element :a] : | -| hash_flow.rb:600:15:600:25 | call to taint : | hash_flow.rb:602:9:602:12 | hash [element :c] : | -| hash_flow.rb:600:15:600:25 | call to taint : | hash_flow.rb:607:9:607:12 | hash [element :c] : | +| hash_flow.rb:597:5:597:8 | hash [element :a] : | hash_flow.rb:602:9:602:12 | hash [element :a] : | +| hash_flow.rb:597:5:597:8 | hash [element :a] : | hash_flow.rb:607:9:607:12 | hash [element :a] : | +| hash_flow.rb:597:5:597:8 | hash [element :c] : | hash_flow.rb:602:9:602:12 | hash [element :c] : | +| hash_flow.rb:597:5:597:8 | hash [element :c] : | hash_flow.rb:607:9:607:12 | hash [element :c] : | +| hash_flow.rb:598:15:598:25 | call to taint : | hash_flow.rb:597:5:597:8 | hash [element :a] : | +| hash_flow.rb:600:15:600:25 | call to taint : | hash_flow.rb:597:5:597:8 | hash [element :c] : | +| hash_flow.rb:602:5:602:5 | a [element :a] : | hash_flow.rb:603:11:603:11 | a [element :a] : | +| hash_flow.rb:602:5:602:5 | a [element :c] : | hash_flow.rb:605:11:605:11 | a [element :c] : | | hash_flow.rb:602:9:602:12 | hash [element :a] : | hash_flow.rb:602:9:602:17 | call to to_h [element :a] : | | hash_flow.rb:602:9:602:12 | hash [element :c] : | hash_flow.rb:602:9:602:17 | call to to_h [element :c] : | -| hash_flow.rb:602:9:602:17 | call to to_h [element :a] : | hash_flow.rb:603:11:603:11 | a [element :a] : | -| hash_flow.rb:602:9:602:17 | call to to_h [element :c] : | hash_flow.rb:605:11:605:11 | a [element :c] : | +| hash_flow.rb:602:9:602:17 | call to to_h [element :a] : | hash_flow.rb:602:5:602:5 | a [element :a] : | +| hash_flow.rb:602:9:602:17 | call to to_h [element :c] : | hash_flow.rb:602:5:602:5 | a [element :c] : | | hash_flow.rb:603:11:603:11 | a [element :a] : | hash_flow.rb:603:11:603:15 | ...[...] : | | hash_flow.rb:603:11:603:15 | ...[...] : | hash_flow.rb:603:10:603:16 | ( ... ) | | hash_flow.rb:605:11:605:11 | a [element :c] : | hash_flow.rb:605:11:605:15 | ...[...] : | | hash_flow.rb:605:11:605:15 | ...[...] : | hash_flow.rb:605:10:605:16 | ( ... ) | +| hash_flow.rb:607:5:607:5 | b [element] : | hash_flow.rb:612:11:612:11 | b [element] : | | hash_flow.rb:607:9:607:12 | hash [element :a] : | hash_flow.rb:607:28:607:32 | value : | | hash_flow.rb:607:9:607:12 | hash [element :c] : | hash_flow.rb:607:28:607:32 | value : | -| hash_flow.rb:607:9:611:7 | call to to_h [element] : | hash_flow.rb:612:11:612:11 | b [element] : | +| hash_flow.rb:607:9:611:7 | call to to_h [element] : | hash_flow.rb:607:5:607:5 | b [element] : | | hash_flow.rb:607:28:607:32 | value : | hash_flow.rb:609:14:609:18 | value | | hash_flow.rb:610:14:610:24 | call to taint : | hash_flow.rb:607:9:611:7 | call to to_h [element] : | | hash_flow.rb:612:11:612:11 | b [element] : | hash_flow.rb:612:11:612:15 | ...[...] : | | hash_flow.rb:612:11:612:15 | ...[...] : | hash_flow.rb:612:10:612:16 | ( ... ) | -| hash_flow.rb:619:15:619:25 | call to taint : | hash_flow.rb:623:9:623:12 | hash [element :a] : | -| hash_flow.rb:621:15:621:25 | call to taint : | hash_flow.rb:623:9:623:12 | hash [element :c] : | +| hash_flow.rb:618:5:618:8 | hash [element :a] : | hash_flow.rb:623:9:623:12 | hash [element :a] : | +| hash_flow.rb:618:5:618:8 | hash [element :c] : | hash_flow.rb:623:9:623:12 | hash [element :c] : | +| hash_flow.rb:619:15:619:25 | call to taint : | hash_flow.rb:618:5:618:8 | hash [element :a] : | +| hash_flow.rb:621:15:621:25 | call to taint : | hash_flow.rb:618:5:618:8 | hash [element :c] : | +| hash_flow.rb:623:5:623:5 | a [element] : | hash_flow.rb:624:11:624:11 | a [element] : | +| hash_flow.rb:623:5:623:5 | a [element] : | hash_flow.rb:625:11:625:11 | a [element] : | +| hash_flow.rb:623:5:623:5 | a [element] : | hash_flow.rb:626:11:626:11 | a [element] : | | hash_flow.rb:623:9:623:12 | hash [element :a] : | hash_flow.rb:623:9:623:45 | call to transform_keys [element] : | | hash_flow.rb:623:9:623:12 | hash [element :c] : | hash_flow.rb:623:9:623:45 | call to transform_keys [element] : | -| hash_flow.rb:623:9:623:45 | call to transform_keys [element] : | hash_flow.rb:624:11:624:11 | a [element] : | -| hash_flow.rb:623:9:623:45 | call to transform_keys [element] : | hash_flow.rb:625:11:625:11 | a [element] : | -| hash_flow.rb:623:9:623:45 | call to transform_keys [element] : | hash_flow.rb:626:11:626:11 | a [element] : | +| hash_flow.rb:623:9:623:45 | call to transform_keys [element] : | hash_flow.rb:623:5:623:5 | a [element] : | | hash_flow.rb:624:11:624:11 | a [element] : | hash_flow.rb:624:11:624:16 | ...[...] : | | hash_flow.rb:624:11:624:16 | ...[...] : | hash_flow.rb:624:10:624:17 | ( ... ) | | hash_flow.rb:625:11:625:11 | a [element] : | hash_flow.rb:625:11:625:16 | ...[...] : | | hash_flow.rb:625:11:625:16 | ...[...] : | hash_flow.rb:625:10:625:17 | ( ... ) | | hash_flow.rb:626:11:626:11 | a [element] : | hash_flow.rb:626:11:626:16 | ...[...] : | | hash_flow.rb:626:11:626:16 | ...[...] : | hash_flow.rb:626:10:626:17 | ( ... ) | -| hash_flow.rb:633:15:633:25 | call to taint : | hash_flow.rb:639:5:639:8 | hash [element :a] : | -| hash_flow.rb:635:15:635:25 | call to taint : | hash_flow.rb:639:5:639:8 | hash [element :c] : | +| hash_flow.rb:632:5:632:8 | hash [element :a] : | hash_flow.rb:639:5:639:8 | hash [element :a] : | +| hash_flow.rb:632:5:632:8 | hash [element :c] : | hash_flow.rb:639:5:639:8 | hash [element :c] : | +| hash_flow.rb:633:15:633:25 | call to taint : | hash_flow.rb:632:5:632:8 | hash [element :a] : | +| hash_flow.rb:635:15:635:25 | call to taint : | hash_flow.rb:632:5:632:8 | hash [element :c] : | | hash_flow.rb:637:5:637:8 | [post] hash [element] : | hash_flow.rb:639:5:639:8 | hash [element] : | | hash_flow.rb:637:5:637:8 | [post] hash [element] : | hash_flow.rb:640:11:640:14 | hash [element] : | | hash_flow.rb:637:5:637:8 | [post] hash [element] : | hash_flow.rb:641:11:641:14 | hash [element] : | @@ -427,20 +541,25 @@ edges | hash_flow.rb:641:11:641:19 | ...[...] : | hash_flow.rb:641:10:641:20 | ( ... ) | | hash_flow.rb:642:11:642:14 | hash [element] : | hash_flow.rb:642:11:642:19 | ...[...] : | | hash_flow.rb:642:11:642:19 | ...[...] : | hash_flow.rb:642:10:642:20 | ( ... ) | -| hash_flow.rb:649:15:649:25 | call to taint : | hash_flow.rb:653:9:653:12 | hash [element :a] : | -| hash_flow.rb:649:15:649:25 | call to taint : | hash_flow.rb:657:11:657:14 | hash [element :a] : | -| hash_flow.rb:651:15:651:25 | call to taint : | hash_flow.rb:653:9:653:12 | hash [element :c] : | +| hash_flow.rb:648:5:648:8 | hash [element :a] : | hash_flow.rb:653:9:653:12 | hash [element :a] : | +| hash_flow.rb:648:5:648:8 | hash [element :a] : | hash_flow.rb:657:11:657:14 | hash [element :a] : | +| hash_flow.rb:648:5:648:8 | hash [element :c] : | hash_flow.rb:653:9:653:12 | hash [element :c] : | +| hash_flow.rb:649:15:649:25 | call to taint : | hash_flow.rb:648:5:648:8 | hash [element :a] : | +| hash_flow.rb:651:15:651:25 | call to taint : | hash_flow.rb:648:5:648:8 | hash [element :c] : | +| hash_flow.rb:653:5:653:5 | b [element] : | hash_flow.rb:658:11:658:11 | b [element] : | | hash_flow.rb:653:9:653:12 | hash [element :a] : | hash_flow.rb:653:35:653:39 | value : | | hash_flow.rb:653:9:653:12 | hash [element :c] : | hash_flow.rb:653:35:653:39 | value : | -| hash_flow.rb:653:9:656:7 | call to transform_values [element] : | hash_flow.rb:658:11:658:11 | b [element] : | +| hash_flow.rb:653:9:656:7 | call to transform_values [element] : | hash_flow.rb:653:5:653:5 | b [element] : | | hash_flow.rb:653:35:653:39 | value : | hash_flow.rb:654:14:654:18 | value | | hash_flow.rb:655:9:655:19 | call to taint : | hash_flow.rb:653:9:656:7 | call to transform_values [element] : | | hash_flow.rb:657:11:657:14 | hash [element :a] : | hash_flow.rb:657:11:657:18 | ...[...] : | | hash_flow.rb:657:11:657:18 | ...[...] : | hash_flow.rb:657:10:657:19 | ( ... ) | | hash_flow.rb:658:11:658:11 | b [element] : | hash_flow.rb:658:11:658:15 | ...[...] : | | hash_flow.rb:658:11:658:15 | ...[...] : | hash_flow.rb:658:10:658:16 | ( ... ) | -| hash_flow.rb:665:15:665:25 | call to taint : | hash_flow.rb:669:5:669:8 | hash [element :a] : | -| hash_flow.rb:667:15:667:25 | call to taint : | hash_flow.rb:669:5:669:8 | hash [element :c] : | +| hash_flow.rb:664:5:664:8 | hash [element :a] : | hash_flow.rb:669:5:669:8 | hash [element :a] : | +| hash_flow.rb:664:5:664:8 | hash [element :c] : | hash_flow.rb:669:5:669:8 | hash [element :c] : | +| hash_flow.rb:665:15:665:25 | call to taint : | hash_flow.rb:664:5:664:8 | hash [element :a] : | +| hash_flow.rb:667:15:667:25 | call to taint : | hash_flow.rb:664:5:664:8 | hash [element :c] : | | hash_flow.rb:669:5:669:8 | [post] hash [element] : | hash_flow.rb:673:11:673:14 | hash [element] : | | hash_flow.rb:669:5:669:8 | hash [element :a] : | hash_flow.rb:669:32:669:36 | value : | | hash_flow.rb:669:5:669:8 | hash [element :c] : | hash_flow.rb:669:32:669:36 | value : | @@ -448,10 +567,18 @@ edges | hash_flow.rb:671:9:671:19 | call to taint : | hash_flow.rb:669:5:669:8 | [post] hash [element] : | | hash_flow.rb:673:11:673:14 | hash [element] : | hash_flow.rb:673:11:673:18 | ...[...] : | | hash_flow.rb:673:11:673:18 | ...[...] : | hash_flow.rb:673:10:673:19 | ( ... ) | -| hash_flow.rb:680:15:680:25 | call to taint : | hash_flow.rb:689:12:689:16 | hash1 [element :a] : | -| hash_flow.rb:682:15:682:25 | call to taint : | hash_flow.rb:689:12:689:16 | hash1 [element :c] : | -| hash_flow.rb:685:15:685:25 | call to taint : | hash_flow.rb:689:25:689:29 | hash2 [element :d] : | -| hash_flow.rb:687:15:687:25 | call to taint : | hash_flow.rb:689:25:689:29 | hash2 [element :f] : | +| hash_flow.rb:679:5:679:9 | hash1 [element :a] : | hash_flow.rb:689:12:689:16 | hash1 [element :a] : | +| hash_flow.rb:679:5:679:9 | hash1 [element :c] : | hash_flow.rb:689:12:689:16 | hash1 [element :c] : | +| hash_flow.rb:680:15:680:25 | call to taint : | hash_flow.rb:679:5:679:9 | hash1 [element :a] : | +| hash_flow.rb:682:15:682:25 | call to taint : | hash_flow.rb:679:5:679:9 | hash1 [element :c] : | +| hash_flow.rb:684:5:684:9 | hash2 [element :d] : | hash_flow.rb:689:25:689:29 | hash2 [element :d] : | +| hash_flow.rb:684:5:684:9 | hash2 [element :f] : | hash_flow.rb:689:25:689:29 | hash2 [element :f] : | +| hash_flow.rb:685:15:685:25 | call to taint : | hash_flow.rb:684:5:684:9 | hash2 [element :d] : | +| hash_flow.rb:687:15:687:25 | call to taint : | hash_flow.rb:684:5:684:9 | hash2 [element :f] : | +| hash_flow.rb:689:5:689:8 | hash [element :a] : | hash_flow.rb:694:11:694:14 | hash [element :a] : | +| hash_flow.rb:689:5:689:8 | hash [element :c] : | hash_flow.rb:696:11:696:14 | hash [element :c] : | +| hash_flow.rb:689:5:689:8 | hash [element :d] : | hash_flow.rb:697:11:697:14 | hash [element :d] : | +| hash_flow.rb:689:5:689:8 | hash [element :f] : | hash_flow.rb:699:11:699:14 | hash [element :f] : | | hash_flow.rb:689:12:689:16 | [post] hash1 [element :a] : | hash_flow.rb:701:11:701:15 | hash1 [element :a] : | | hash_flow.rb:689:12:689:16 | [post] hash1 [element :c] : | hash_flow.rb:703:11:703:15 | hash1 [element :c] : | | hash_flow.rb:689:12:689:16 | [post] hash1 [element :d] : | hash_flow.rb:704:11:704:15 | hash1 [element :d] : | @@ -464,10 +591,10 @@ edges | hash_flow.rb:689:12:689:16 | hash1 [element :c] : | hash_flow.rb:689:12:693:7 | call to update [element :c] : | | hash_flow.rb:689:12:689:16 | hash1 [element :c] : | hash_flow.rb:689:41:689:49 | old_value : | | hash_flow.rb:689:12:689:16 | hash1 [element :c] : | hash_flow.rb:689:52:689:60 | new_value : | -| hash_flow.rb:689:12:693:7 | call to update [element :a] : | hash_flow.rb:694:11:694:14 | hash [element :a] : | -| hash_flow.rb:689:12:693:7 | call to update [element :c] : | hash_flow.rb:696:11:696:14 | hash [element :c] : | -| hash_flow.rb:689:12:693:7 | call to update [element :d] : | hash_flow.rb:697:11:697:14 | hash [element :d] : | -| hash_flow.rb:689:12:693:7 | call to update [element :f] : | hash_flow.rb:699:11:699:14 | hash [element :f] : | +| hash_flow.rb:689:12:693:7 | call to update [element :a] : | hash_flow.rb:689:5:689:8 | hash [element :a] : | +| hash_flow.rb:689:12:693:7 | call to update [element :c] : | hash_flow.rb:689:5:689:8 | hash [element :c] : | +| hash_flow.rb:689:12:693:7 | call to update [element :d] : | hash_flow.rb:689:5:689:8 | hash [element :d] : | +| hash_flow.rb:689:12:693:7 | call to update [element :f] : | hash_flow.rb:689:5:689:8 | hash [element :f] : | | hash_flow.rb:689:25:689:29 | hash2 [element :d] : | hash_flow.rb:689:12:689:16 | [post] hash1 [element :d] : | | hash_flow.rb:689:25:689:29 | hash2 [element :d] : | hash_flow.rb:689:12:693:7 | call to update [element :d] : | | hash_flow.rb:689:25:689:29 | hash2 [element :d] : | hash_flow.rb:689:41:689:49 | old_value : | @@ -494,34 +621,50 @@ edges | hash_flow.rb:704:11:704:19 | ...[...] : | hash_flow.rb:704:10:704:20 | ( ... ) | | hash_flow.rb:706:11:706:15 | hash1 [element :f] : | hash_flow.rb:706:11:706:19 | ...[...] : | | hash_flow.rb:706:11:706:19 | ...[...] : | hash_flow.rb:706:10:706:20 | ( ... ) | -| hash_flow.rb:713:15:713:25 | call to taint : | hash_flow.rb:717:9:717:12 | hash [element :a] : | -| hash_flow.rb:715:15:715:25 | call to taint : | hash_flow.rb:717:9:717:12 | hash [element :c] : | +| hash_flow.rb:712:5:712:8 | hash [element :a] : | hash_flow.rb:717:9:717:12 | hash [element :a] : | +| hash_flow.rb:712:5:712:8 | hash [element :c] : | hash_flow.rb:717:9:717:12 | hash [element :c] : | +| hash_flow.rb:713:15:713:25 | call to taint : | hash_flow.rb:712:5:712:8 | hash [element :a] : | +| hash_flow.rb:715:15:715:25 | call to taint : | hash_flow.rb:712:5:712:8 | hash [element :c] : | +| hash_flow.rb:717:5:717:5 | a [element] : | hash_flow.rb:718:11:718:11 | a [element] : | | hash_flow.rb:717:9:717:12 | hash [element :a] : | hash_flow.rb:717:9:717:19 | call to values [element] : | | hash_flow.rb:717:9:717:12 | hash [element :c] : | hash_flow.rb:717:9:717:19 | call to values [element] : | -| hash_flow.rb:717:9:717:19 | call to values [element] : | hash_flow.rb:718:11:718:11 | a [element] : | +| hash_flow.rb:717:9:717:19 | call to values [element] : | hash_flow.rb:717:5:717:5 | a [element] : | | hash_flow.rb:718:11:718:11 | a [element] : | hash_flow.rb:718:11:718:14 | ...[...] : | | hash_flow.rb:718:11:718:14 | ...[...] : | hash_flow.rb:718:10:718:15 | ( ... ) | -| hash_flow.rb:725:15:725:25 | call to taint : | hash_flow.rb:729:9:729:12 | hash [element :a] : | -| hash_flow.rb:725:15:725:25 | call to taint : | hash_flow.rb:731:9:731:12 | hash [element :a] : | -| hash_flow.rb:727:15:727:25 | call to taint : | hash_flow.rb:731:9:731:12 | hash [element :c] : | +| hash_flow.rb:724:5:724:8 | hash [element :a] : | hash_flow.rb:729:9:729:12 | hash [element :a] : | +| hash_flow.rb:724:5:724:8 | hash [element :a] : | hash_flow.rb:731:9:731:12 | hash [element :a] : | +| hash_flow.rb:724:5:724:8 | hash [element :c] : | hash_flow.rb:731:9:731:12 | hash [element :c] : | +| hash_flow.rb:725:15:725:25 | call to taint : | hash_flow.rb:724:5:724:8 | hash [element :a] : | +| hash_flow.rb:727:15:727:25 | call to taint : | hash_flow.rb:724:5:724:8 | hash [element :c] : | +| hash_flow.rb:729:5:729:5 | b [element 0] : | hash_flow.rb:730:10:730:10 | b [element 0] : | | hash_flow.rb:729:9:729:12 | hash [element :a] : | hash_flow.rb:729:9:729:26 | call to values_at [element 0] : | -| hash_flow.rb:729:9:729:26 | call to values_at [element 0] : | hash_flow.rb:730:10:730:10 | b [element 0] : | +| hash_flow.rb:729:9:729:26 | call to values_at [element 0] : | hash_flow.rb:729:5:729:5 | b [element 0] : | | hash_flow.rb:730:10:730:10 | b [element 0] : | hash_flow.rb:730:10:730:13 | ...[...] | +| hash_flow.rb:731:5:731:5 | b [element] : | hash_flow.rb:732:10:732:10 | b [element] : | | hash_flow.rb:731:9:731:12 | hash [element :a] : | hash_flow.rb:731:9:731:31 | call to fetch_values [element] : | | hash_flow.rb:731:9:731:12 | hash [element :c] : | hash_flow.rb:731:9:731:31 | call to fetch_values [element] : | -| hash_flow.rb:731:9:731:31 | call to fetch_values [element] : | hash_flow.rb:732:10:732:10 | b [element] : | +| hash_flow.rb:731:9:731:31 | call to fetch_values [element] : | hash_flow.rb:731:5:731:5 | b [element] : | | hash_flow.rb:732:10:732:10 | b [element] : | hash_flow.rb:732:10:732:13 | ...[...] | -| hash_flow.rb:739:15:739:25 | call to taint : | hash_flow.rb:748:16:748:20 | hash1 [element :a] : | -| hash_flow.rb:741:15:741:25 | call to taint : | hash_flow.rb:748:16:748:20 | hash1 [element :c] : | -| hash_flow.rb:744:15:744:25 | call to taint : | hash_flow.rb:748:44:748:48 | hash2 [element :d] : | -| hash_flow.rb:746:15:746:25 | call to taint : | hash_flow.rb:748:44:748:48 | hash2 [element :f] : | -| hash_flow.rb:748:14:748:20 | ** ... [element :a] : | hash_flow.rb:749:10:749:13 | hash [element :a] : | -| hash_flow.rb:748:14:748:20 | ** ... [element :c] : | hash_flow.rb:751:10:751:13 | hash [element :c] : | +| hash_flow.rb:738:5:738:9 | hash1 [element :a] : | hash_flow.rb:748:16:748:20 | hash1 [element :a] : | +| hash_flow.rb:738:5:738:9 | hash1 [element :c] : | hash_flow.rb:748:16:748:20 | hash1 [element :c] : | +| hash_flow.rb:739:15:739:25 | call to taint : | hash_flow.rb:738:5:738:9 | hash1 [element :a] : | +| hash_flow.rb:741:15:741:25 | call to taint : | hash_flow.rb:738:5:738:9 | hash1 [element :c] : | +| hash_flow.rb:743:5:743:9 | hash2 [element :d] : | hash_flow.rb:748:44:748:48 | hash2 [element :d] : | +| hash_flow.rb:743:5:743:9 | hash2 [element :f] : | hash_flow.rb:748:44:748:48 | hash2 [element :f] : | +| hash_flow.rb:744:15:744:25 | call to taint : | hash_flow.rb:743:5:743:9 | hash2 [element :d] : | +| hash_flow.rb:746:15:746:25 | call to taint : | hash_flow.rb:743:5:743:9 | hash2 [element :f] : | +| hash_flow.rb:748:5:748:8 | hash [element :a] : | hash_flow.rb:749:10:749:13 | hash [element :a] : | +| hash_flow.rb:748:5:748:8 | hash [element :c] : | hash_flow.rb:751:10:751:13 | hash [element :c] : | +| hash_flow.rb:748:5:748:8 | hash [element :d] : | hash_flow.rb:752:10:752:13 | hash [element :d] : | +| hash_flow.rb:748:5:748:8 | hash [element :f] : | hash_flow.rb:754:10:754:13 | hash [element :f] : | +| hash_flow.rb:748:5:748:8 | hash [element :g] : | hash_flow.rb:755:10:755:13 | hash [element :g] : | +| hash_flow.rb:748:14:748:20 | ** ... [element :a] : | hash_flow.rb:748:5:748:8 | hash [element :a] : | +| hash_flow.rb:748:14:748:20 | ** ... [element :c] : | hash_flow.rb:748:5:748:8 | hash [element :c] : | | hash_flow.rb:748:16:748:20 | hash1 [element :a] : | hash_flow.rb:748:14:748:20 | ** ... [element :a] : | | hash_flow.rb:748:16:748:20 | hash1 [element :c] : | hash_flow.rb:748:14:748:20 | ** ... [element :c] : | -| hash_flow.rb:748:29:748:39 | call to taint : | hash_flow.rb:755:10:755:13 | hash [element :g] : | -| hash_flow.rb:748:42:748:48 | ** ... [element :d] : | hash_flow.rb:752:10:752:13 | hash [element :d] : | -| hash_flow.rb:748:42:748:48 | ** ... [element :f] : | hash_flow.rb:754:10:754:13 | hash [element :f] : | +| hash_flow.rb:748:29:748:39 | call to taint : | hash_flow.rb:748:5:748:8 | hash [element :g] : | +| hash_flow.rb:748:42:748:48 | ** ... [element :d] : | hash_flow.rb:748:5:748:8 | hash [element :d] : | +| hash_flow.rb:748:42:748:48 | ** ... [element :f] : | hash_flow.rb:748:5:748:8 | hash [element :f] : | | hash_flow.rb:748:44:748:48 | hash2 [element :d] : | hash_flow.rb:748:42:748:48 | ** ... [element :d] : | | hash_flow.rb:748:44:748:48 | hash2 [element :f] : | hash_flow.rb:748:42:748:48 | ** ... [element :f] : | | hash_flow.rb:749:10:749:13 | hash [element :a] : | hash_flow.rb:749:10:749:17 | ...[...] | @@ -529,33 +672,45 @@ edges | hash_flow.rb:752:10:752:13 | hash [element :d] : | hash_flow.rb:752:10:752:17 | ...[...] | | hash_flow.rb:754:10:754:13 | hash [element :f] : | hash_flow.rb:754:10:754:17 | ...[...] | | hash_flow.rb:755:10:755:13 | hash [element :g] : | hash_flow.rb:755:10:755:17 | ...[...] | -| hash_flow.rb:763:15:763:25 | call to taint : | hash_flow.rb:769:10:769:13 | hash [element :a] : | -| hash_flow.rb:765:15:765:25 | call to taint : | hash_flow.rb:771:10:771:13 | hash [element :c] : | -| hash_flow.rb:765:15:765:25 | call to taint : | hash_flow.rb:774:9:774:12 | hash [element :c] : | -| hash_flow.rb:766:15:766:25 | call to taint : | hash_flow.rb:772:10:772:13 | hash [element :d] : | +| hash_flow.rb:762:5:762:8 | hash [element :a] : | hash_flow.rb:769:10:769:13 | hash [element :a] : | +| hash_flow.rb:762:5:762:8 | hash [element :c] : | hash_flow.rb:771:10:771:13 | hash [element :c] : | +| hash_flow.rb:762:5:762:8 | hash [element :c] : | hash_flow.rb:774:9:774:12 | hash [element :c] : | +| hash_flow.rb:762:5:762:8 | hash [element :d] : | hash_flow.rb:772:10:772:13 | hash [element :d] : | +| hash_flow.rb:763:15:763:25 | call to taint : | hash_flow.rb:762:5:762:8 | hash [element :a] : | +| hash_flow.rb:765:15:765:25 | call to taint : | hash_flow.rb:762:5:762:8 | hash [element :c] : | +| hash_flow.rb:766:15:766:25 | call to taint : | hash_flow.rb:762:5:762:8 | hash [element :d] : | | hash_flow.rb:769:10:769:13 | hash [element :a] : | hash_flow.rb:769:10:769:17 | ...[...] | | hash_flow.rb:771:10:771:13 | hash [element :c] : | hash_flow.rb:771:10:771:17 | ...[...] | | hash_flow.rb:772:10:772:13 | hash [element :d] : | hash_flow.rb:772:10:772:17 | ...[...] | +| hash_flow.rb:774:5:774:5 | x [element :c] : | hash_flow.rb:778:10:778:10 | x [element :c] : | | hash_flow.rb:774:9:774:12 | [post] hash [element :c] : | hash_flow.rb:783:10:783:13 | hash [element :c] : | | hash_flow.rb:774:9:774:12 | hash [element :c] : | hash_flow.rb:774:9:774:12 | [post] hash [element :c] : | | hash_flow.rb:774:9:774:12 | hash [element :c] : | hash_flow.rb:774:9:774:31 | call to except! [element :c] : | -| hash_flow.rb:774:9:774:31 | call to except! [element :c] : | hash_flow.rb:778:10:778:10 | x [element :c] : | +| hash_flow.rb:774:9:774:31 | call to except! [element :c] : | hash_flow.rb:774:5:774:5 | x [element :c] : | | hash_flow.rb:778:10:778:10 | x [element :c] : | hash_flow.rb:778:10:778:14 | ...[...] | | hash_flow.rb:783:10:783:13 | hash [element :c] : | hash_flow.rb:783:10:783:17 | ...[...] | -| hash_flow.rb:791:15:791:25 | call to taint : | hash_flow.rb:800:12:800:16 | hash1 [element :a] : | -| hash_flow.rb:793:15:793:25 | call to taint : | hash_flow.rb:800:12:800:16 | hash1 [element :c] : | -| hash_flow.rb:796:15:796:25 | call to taint : | hash_flow.rb:800:29:800:33 | hash2 [element :d] : | -| hash_flow.rb:798:15:798:25 | call to taint : | hash_flow.rb:800:29:800:33 | hash2 [element :f] : | +| hash_flow.rb:790:5:790:9 | hash1 [element :a] : | hash_flow.rb:800:12:800:16 | hash1 [element :a] : | +| hash_flow.rb:790:5:790:9 | hash1 [element :c] : | hash_flow.rb:800:12:800:16 | hash1 [element :c] : | +| hash_flow.rb:791:15:791:25 | call to taint : | hash_flow.rb:790:5:790:9 | hash1 [element :a] : | +| hash_flow.rb:793:15:793:25 | call to taint : | hash_flow.rb:790:5:790:9 | hash1 [element :c] : | +| hash_flow.rb:795:5:795:9 | hash2 [element :d] : | hash_flow.rb:800:29:800:33 | hash2 [element :d] : | +| hash_flow.rb:795:5:795:9 | hash2 [element :f] : | hash_flow.rb:800:29:800:33 | hash2 [element :f] : | +| hash_flow.rb:796:15:796:25 | call to taint : | hash_flow.rb:795:5:795:9 | hash2 [element :d] : | +| hash_flow.rb:798:15:798:25 | call to taint : | hash_flow.rb:795:5:795:9 | hash2 [element :f] : | +| hash_flow.rb:800:5:800:8 | hash [element :a] : | hash_flow.rb:805:11:805:14 | hash [element :a] : | +| hash_flow.rb:800:5:800:8 | hash [element :c] : | hash_flow.rb:807:11:807:14 | hash [element :c] : | +| hash_flow.rb:800:5:800:8 | hash [element :d] : | hash_flow.rb:808:11:808:14 | hash [element :d] : | +| hash_flow.rb:800:5:800:8 | hash [element :f] : | hash_flow.rb:810:11:810:14 | hash [element :f] : | | hash_flow.rb:800:12:800:16 | hash1 [element :a] : | hash_flow.rb:800:12:804:7 | call to deep_merge [element :a] : | | hash_flow.rb:800:12:800:16 | hash1 [element :a] : | hash_flow.rb:800:45:800:53 | old_value : | | hash_flow.rb:800:12:800:16 | hash1 [element :a] : | hash_flow.rb:800:56:800:64 | new_value : | | hash_flow.rb:800:12:800:16 | hash1 [element :c] : | hash_flow.rb:800:12:804:7 | call to deep_merge [element :c] : | | hash_flow.rb:800:12:800:16 | hash1 [element :c] : | hash_flow.rb:800:45:800:53 | old_value : | | hash_flow.rb:800:12:800:16 | hash1 [element :c] : | hash_flow.rb:800:56:800:64 | new_value : | -| hash_flow.rb:800:12:804:7 | call to deep_merge [element :a] : | hash_flow.rb:805:11:805:14 | hash [element :a] : | -| hash_flow.rb:800:12:804:7 | call to deep_merge [element :c] : | hash_flow.rb:807:11:807:14 | hash [element :c] : | -| hash_flow.rb:800:12:804:7 | call to deep_merge [element :d] : | hash_flow.rb:808:11:808:14 | hash [element :d] : | -| hash_flow.rb:800:12:804:7 | call to deep_merge [element :f] : | hash_flow.rb:810:11:810:14 | hash [element :f] : | +| hash_flow.rb:800:12:804:7 | call to deep_merge [element :a] : | hash_flow.rb:800:5:800:8 | hash [element :a] : | +| hash_flow.rb:800:12:804:7 | call to deep_merge [element :c] : | hash_flow.rb:800:5:800:8 | hash [element :c] : | +| hash_flow.rb:800:12:804:7 | call to deep_merge [element :d] : | hash_flow.rb:800:5:800:8 | hash [element :d] : | +| hash_flow.rb:800:12:804:7 | call to deep_merge [element :f] : | hash_flow.rb:800:5:800:8 | hash [element :f] : | | hash_flow.rb:800:29:800:33 | hash2 [element :d] : | hash_flow.rb:800:12:804:7 | call to deep_merge [element :d] : | | hash_flow.rb:800:29:800:33 | hash2 [element :d] : | hash_flow.rb:800:45:800:53 | old_value : | | hash_flow.rb:800:29:800:33 | hash2 [element :d] : | hash_flow.rb:800:56:800:64 | new_value : | @@ -572,10 +727,18 @@ edges | hash_flow.rb:808:11:808:18 | ...[...] : | hash_flow.rb:808:10:808:19 | ( ... ) | | hash_flow.rb:810:11:810:14 | hash [element :f] : | hash_flow.rb:810:11:810:18 | ...[...] : | | hash_flow.rb:810:11:810:18 | ...[...] : | hash_flow.rb:810:10:810:19 | ( ... ) | -| hash_flow.rb:817:15:817:25 | call to taint : | hash_flow.rb:826:12:826:16 | hash1 [element :a] : | -| hash_flow.rb:819:15:819:25 | call to taint : | hash_flow.rb:826:12:826:16 | hash1 [element :c] : | -| hash_flow.rb:822:15:822:25 | call to taint : | hash_flow.rb:826:30:826:34 | hash2 [element :d] : | -| hash_flow.rb:824:15:824:25 | call to taint : | hash_flow.rb:826:30:826:34 | hash2 [element :f] : | +| hash_flow.rb:816:5:816:9 | hash1 [element :a] : | hash_flow.rb:826:12:826:16 | hash1 [element :a] : | +| hash_flow.rb:816:5:816:9 | hash1 [element :c] : | hash_flow.rb:826:12:826:16 | hash1 [element :c] : | +| hash_flow.rb:817:15:817:25 | call to taint : | hash_flow.rb:816:5:816:9 | hash1 [element :a] : | +| hash_flow.rb:819:15:819:25 | call to taint : | hash_flow.rb:816:5:816:9 | hash1 [element :c] : | +| hash_flow.rb:821:5:821:9 | hash2 [element :d] : | hash_flow.rb:826:30:826:34 | hash2 [element :d] : | +| hash_flow.rb:821:5:821:9 | hash2 [element :f] : | hash_flow.rb:826:30:826:34 | hash2 [element :f] : | +| hash_flow.rb:822:15:822:25 | call to taint : | hash_flow.rb:821:5:821:9 | hash2 [element :d] : | +| hash_flow.rb:824:15:824:25 | call to taint : | hash_flow.rb:821:5:821:9 | hash2 [element :f] : | +| hash_flow.rb:826:5:826:8 | hash [element :a] : | hash_flow.rb:831:11:831:14 | hash [element :a] : | +| hash_flow.rb:826:5:826:8 | hash [element :c] : | hash_flow.rb:833:11:833:14 | hash [element :c] : | +| hash_flow.rb:826:5:826:8 | hash [element :d] : | hash_flow.rb:834:11:834:14 | hash [element :d] : | +| hash_flow.rb:826:5:826:8 | hash [element :f] : | hash_flow.rb:836:11:836:14 | hash [element :f] : | | hash_flow.rb:826:12:826:16 | [post] hash1 [element :a] : | hash_flow.rb:838:11:838:15 | hash1 [element :a] : | | hash_flow.rb:826:12:826:16 | [post] hash1 [element :c] : | hash_flow.rb:840:11:840:15 | hash1 [element :c] : | | hash_flow.rb:826:12:826:16 | [post] hash1 [element :d] : | hash_flow.rb:841:11:841:15 | hash1 [element :d] : | @@ -588,10 +751,10 @@ edges | hash_flow.rb:826:12:826:16 | hash1 [element :c] : | hash_flow.rb:826:12:830:7 | call to deep_merge! [element :c] : | | hash_flow.rb:826:12:826:16 | hash1 [element :c] : | hash_flow.rb:826:46:826:54 | old_value : | | hash_flow.rb:826:12:826:16 | hash1 [element :c] : | hash_flow.rb:826:57:826:65 | new_value : | -| hash_flow.rb:826:12:830:7 | call to deep_merge! [element :a] : | hash_flow.rb:831:11:831:14 | hash [element :a] : | -| hash_flow.rb:826:12:830:7 | call to deep_merge! [element :c] : | hash_flow.rb:833:11:833:14 | hash [element :c] : | -| hash_flow.rb:826:12:830:7 | call to deep_merge! [element :d] : | hash_flow.rb:834:11:834:14 | hash [element :d] : | -| hash_flow.rb:826:12:830:7 | call to deep_merge! [element :f] : | hash_flow.rb:836:11:836:14 | hash [element :f] : | +| hash_flow.rb:826:12:830:7 | call to deep_merge! [element :a] : | hash_flow.rb:826:5:826:8 | hash [element :a] : | +| hash_flow.rb:826:12:830:7 | call to deep_merge! [element :c] : | hash_flow.rb:826:5:826:8 | hash [element :c] : | +| hash_flow.rb:826:12:830:7 | call to deep_merge! [element :d] : | hash_flow.rb:826:5:826:8 | hash [element :d] : | +| hash_flow.rb:826:12:830:7 | call to deep_merge! [element :f] : | hash_flow.rb:826:5:826:8 | hash [element :f] : | | hash_flow.rb:826:30:826:34 | hash2 [element :d] : | hash_flow.rb:826:12:826:16 | [post] hash1 [element :d] : | | hash_flow.rb:826:30:826:34 | hash2 [element :d] : | hash_flow.rb:826:12:830:7 | call to deep_merge! [element :d] : | | hash_flow.rb:826:30:826:34 | hash2 [element :d] : | hash_flow.rb:826:46:826:54 | old_value : | @@ -618,20 +781,28 @@ edges | hash_flow.rb:841:11:841:19 | ...[...] : | hash_flow.rb:841:10:841:20 | ( ... ) | | hash_flow.rb:843:11:843:15 | hash1 [element :f] : | hash_flow.rb:843:11:843:19 | ...[...] : | | hash_flow.rb:843:11:843:19 | ...[...] : | hash_flow.rb:843:10:843:20 | ( ... ) | -| hash_flow.rb:850:12:850:22 | call to taint : | hash_flow.rb:860:13:860:17 | hash1 [element :a] : | -| hash_flow.rb:850:12:850:22 | call to taint : | hash_flow.rb:869:13:869:17 | hash1 [element :a] : | -| hash_flow.rb:852:12:852:22 | call to taint : | hash_flow.rb:860:13:860:17 | hash1 [element :c] : | -| hash_flow.rb:852:12:852:22 | call to taint : | hash_flow.rb:869:13:869:17 | hash1 [element :c] : | -| hash_flow.rb:855:12:855:22 | call to taint : | hash_flow.rb:860:33:860:37 | hash2 [element :d] : | -| hash_flow.rb:855:12:855:22 | call to taint : | hash_flow.rb:869:33:869:37 | hash2 [element :d] : | -| hash_flow.rb:857:12:857:22 | call to taint : | hash_flow.rb:860:33:860:37 | hash2 [element :f] : | -| hash_flow.rb:857:12:857:22 | call to taint : | hash_flow.rb:869:33:869:37 | hash2 [element :f] : | +| hash_flow.rb:849:5:849:9 | hash1 [element :a] : | hash_flow.rb:860:13:860:17 | hash1 [element :a] : | +| hash_flow.rb:849:5:849:9 | hash1 [element :a] : | hash_flow.rb:869:13:869:17 | hash1 [element :a] : | +| hash_flow.rb:849:5:849:9 | hash1 [element :c] : | hash_flow.rb:860:13:860:17 | hash1 [element :c] : | +| hash_flow.rb:849:5:849:9 | hash1 [element :c] : | hash_flow.rb:869:13:869:17 | hash1 [element :c] : | +| hash_flow.rb:850:12:850:22 | call to taint : | hash_flow.rb:849:5:849:9 | hash1 [element :a] : | +| hash_flow.rb:852:12:852:22 | call to taint : | hash_flow.rb:849:5:849:9 | hash1 [element :c] : | +| hash_flow.rb:854:5:854:9 | hash2 [element :d] : | hash_flow.rb:860:33:860:37 | hash2 [element :d] : | +| hash_flow.rb:854:5:854:9 | hash2 [element :d] : | hash_flow.rb:869:33:869:37 | hash2 [element :d] : | +| hash_flow.rb:854:5:854:9 | hash2 [element :f] : | hash_flow.rb:860:33:860:37 | hash2 [element :f] : | +| hash_flow.rb:854:5:854:9 | hash2 [element :f] : | hash_flow.rb:869:33:869:37 | hash2 [element :f] : | +| hash_flow.rb:855:12:855:22 | call to taint : | hash_flow.rb:854:5:854:9 | hash2 [element :d] : | +| hash_flow.rb:857:12:857:22 | call to taint : | hash_flow.rb:854:5:854:9 | hash2 [element :f] : | +| hash_flow.rb:860:5:860:9 | hash3 [element :a] : | hash_flow.rb:861:11:861:15 | hash3 [element :a] : | +| hash_flow.rb:860:5:860:9 | hash3 [element :c] : | hash_flow.rb:863:11:863:15 | hash3 [element :c] : | +| hash_flow.rb:860:5:860:9 | hash3 [element :d] : | hash_flow.rb:864:11:864:15 | hash3 [element :d] : | +| hash_flow.rb:860:5:860:9 | hash3 [element :f] : | hash_flow.rb:866:11:866:15 | hash3 [element :f] : | | hash_flow.rb:860:13:860:17 | hash1 [element :a] : | hash_flow.rb:860:13:860:38 | call to reverse_merge [element :a] : | | hash_flow.rb:860:13:860:17 | hash1 [element :c] : | hash_flow.rb:860:13:860:38 | call to reverse_merge [element :c] : | -| hash_flow.rb:860:13:860:38 | call to reverse_merge [element :a] : | hash_flow.rb:861:11:861:15 | hash3 [element :a] : | -| hash_flow.rb:860:13:860:38 | call to reverse_merge [element :c] : | hash_flow.rb:863:11:863:15 | hash3 [element :c] : | -| hash_flow.rb:860:13:860:38 | call to reverse_merge [element :d] : | hash_flow.rb:864:11:864:15 | hash3 [element :d] : | -| hash_flow.rb:860:13:860:38 | call to reverse_merge [element :f] : | hash_flow.rb:866:11:866:15 | hash3 [element :f] : | +| hash_flow.rb:860:13:860:38 | call to reverse_merge [element :a] : | hash_flow.rb:860:5:860:9 | hash3 [element :a] : | +| hash_flow.rb:860:13:860:38 | call to reverse_merge [element :c] : | hash_flow.rb:860:5:860:9 | hash3 [element :c] : | +| hash_flow.rb:860:13:860:38 | call to reverse_merge [element :d] : | hash_flow.rb:860:5:860:9 | hash3 [element :d] : | +| hash_flow.rb:860:13:860:38 | call to reverse_merge [element :f] : | hash_flow.rb:860:5:860:9 | hash3 [element :f] : | | hash_flow.rb:860:33:860:37 | hash2 [element :d] : | hash_flow.rb:860:13:860:38 | call to reverse_merge [element :d] : | | hash_flow.rb:860:33:860:37 | hash2 [element :f] : | hash_flow.rb:860:13:860:38 | call to reverse_merge [element :f] : | | hash_flow.rb:861:11:861:15 | hash3 [element :a] : | hash_flow.rb:861:11:861:19 | ...[...] : | @@ -642,12 +813,16 @@ edges | hash_flow.rb:864:11:864:19 | ...[...] : | hash_flow.rb:864:10:864:20 | ( ... ) | | hash_flow.rb:866:11:866:15 | hash3 [element :f] : | hash_flow.rb:866:11:866:19 | ...[...] : | | hash_flow.rb:866:11:866:19 | ...[...] : | hash_flow.rb:866:10:866:20 | ( ... ) | +| hash_flow.rb:869:5:869:9 | hash4 [element :a] : | hash_flow.rb:870:11:870:15 | hash4 [element :a] : | +| hash_flow.rb:869:5:869:9 | hash4 [element :c] : | hash_flow.rb:872:11:872:15 | hash4 [element :c] : | +| hash_flow.rb:869:5:869:9 | hash4 [element :d] : | hash_flow.rb:873:11:873:15 | hash4 [element :d] : | +| hash_flow.rb:869:5:869:9 | hash4 [element :f] : | hash_flow.rb:875:11:875:15 | hash4 [element :f] : | | hash_flow.rb:869:13:869:17 | hash1 [element :a] : | hash_flow.rb:869:13:869:38 | call to with_defaults [element :a] : | | hash_flow.rb:869:13:869:17 | hash1 [element :c] : | hash_flow.rb:869:13:869:38 | call to with_defaults [element :c] : | -| hash_flow.rb:869:13:869:38 | call to with_defaults [element :a] : | hash_flow.rb:870:11:870:15 | hash4 [element :a] : | -| hash_flow.rb:869:13:869:38 | call to with_defaults [element :c] : | hash_flow.rb:872:11:872:15 | hash4 [element :c] : | -| hash_flow.rb:869:13:869:38 | call to with_defaults [element :d] : | hash_flow.rb:873:11:873:15 | hash4 [element :d] : | -| hash_flow.rb:869:13:869:38 | call to with_defaults [element :f] : | hash_flow.rb:875:11:875:15 | hash4 [element :f] : | +| hash_flow.rb:869:13:869:38 | call to with_defaults [element :a] : | hash_flow.rb:869:5:869:9 | hash4 [element :a] : | +| hash_flow.rb:869:13:869:38 | call to with_defaults [element :c] : | hash_flow.rb:869:5:869:9 | hash4 [element :c] : | +| hash_flow.rb:869:13:869:38 | call to with_defaults [element :d] : | hash_flow.rb:869:5:869:9 | hash4 [element :d] : | +| hash_flow.rb:869:13:869:38 | call to with_defaults [element :f] : | hash_flow.rb:869:5:869:9 | hash4 [element :f] : | | hash_flow.rb:869:33:869:37 | hash2 [element :d] : | hash_flow.rb:869:13:869:38 | call to with_defaults [element :d] : | | hash_flow.rb:869:33:869:37 | hash2 [element :f] : | hash_flow.rb:869:13:869:38 | call to with_defaults [element :f] : | | hash_flow.rb:870:11:870:15 | hash4 [element :a] : | hash_flow.rb:870:11:870:19 | ...[...] : | @@ -658,10 +833,18 @@ edges | hash_flow.rb:873:11:873:19 | ...[...] : | hash_flow.rb:873:10:873:20 | ( ... ) | | hash_flow.rb:875:11:875:15 | hash4 [element :f] : | hash_flow.rb:875:11:875:19 | ...[...] : | | hash_flow.rb:875:11:875:19 | ...[...] : | hash_flow.rb:875:10:875:20 | ( ... ) | -| hash_flow.rb:882:12:882:22 | call to taint : | hash_flow.rb:892:12:892:16 | hash1 [element :a] : | -| hash_flow.rb:884:12:884:22 | call to taint : | hash_flow.rb:892:12:892:16 | hash1 [element :c] : | -| hash_flow.rb:887:12:887:22 | call to taint : | hash_flow.rb:892:33:892:37 | hash2 [element :d] : | -| hash_flow.rb:889:12:889:22 | call to taint : | hash_flow.rb:892:33:892:37 | hash2 [element :f] : | +| hash_flow.rb:881:5:881:9 | hash1 [element :a] : | hash_flow.rb:892:12:892:16 | hash1 [element :a] : | +| hash_flow.rb:881:5:881:9 | hash1 [element :c] : | hash_flow.rb:892:12:892:16 | hash1 [element :c] : | +| hash_flow.rb:882:12:882:22 | call to taint : | hash_flow.rb:881:5:881:9 | hash1 [element :a] : | +| hash_flow.rb:884:12:884:22 | call to taint : | hash_flow.rb:881:5:881:9 | hash1 [element :c] : | +| hash_flow.rb:886:5:886:9 | hash2 [element :d] : | hash_flow.rb:892:33:892:37 | hash2 [element :d] : | +| hash_flow.rb:886:5:886:9 | hash2 [element :f] : | hash_flow.rb:892:33:892:37 | hash2 [element :f] : | +| hash_flow.rb:887:12:887:22 | call to taint : | hash_flow.rb:886:5:886:9 | hash2 [element :d] : | +| hash_flow.rb:889:12:889:22 | call to taint : | hash_flow.rb:886:5:886:9 | hash2 [element :f] : | +| hash_flow.rb:892:5:892:8 | hash [element :a] : | hash_flow.rb:893:11:893:14 | hash [element :a] : | +| hash_flow.rb:892:5:892:8 | hash [element :c] : | hash_flow.rb:895:11:895:14 | hash [element :c] : | +| hash_flow.rb:892:5:892:8 | hash [element :d] : | hash_flow.rb:896:11:896:14 | hash [element :d] : | +| hash_flow.rb:892:5:892:8 | hash [element :f] : | hash_flow.rb:898:11:898:14 | hash [element :f] : | | hash_flow.rb:892:12:892:16 | [post] hash1 [element :a] : | hash_flow.rb:900:11:900:15 | hash1 [element :a] : | | hash_flow.rb:892:12:892:16 | [post] hash1 [element :c] : | hash_flow.rb:902:11:902:15 | hash1 [element :c] : | | hash_flow.rb:892:12:892:16 | [post] hash1 [element :d] : | hash_flow.rb:903:11:903:15 | hash1 [element :d] : | @@ -670,10 +853,10 @@ edges | hash_flow.rb:892:12:892:16 | hash1 [element :a] : | hash_flow.rb:892:12:892:38 | call to reverse_merge! [element :a] : | | hash_flow.rb:892:12:892:16 | hash1 [element :c] : | hash_flow.rb:892:12:892:16 | [post] hash1 [element :c] : | | hash_flow.rb:892:12:892:16 | hash1 [element :c] : | hash_flow.rb:892:12:892:38 | call to reverse_merge! [element :c] : | -| hash_flow.rb:892:12:892:38 | call to reverse_merge! [element :a] : | hash_flow.rb:893:11:893:14 | hash [element :a] : | -| hash_flow.rb:892:12:892:38 | call to reverse_merge! [element :c] : | hash_flow.rb:895:11:895:14 | hash [element :c] : | -| hash_flow.rb:892:12:892:38 | call to reverse_merge! [element :d] : | hash_flow.rb:896:11:896:14 | hash [element :d] : | -| hash_flow.rb:892:12:892:38 | call to reverse_merge! [element :f] : | hash_flow.rb:898:11:898:14 | hash [element :f] : | +| hash_flow.rb:892:12:892:38 | call to reverse_merge! [element :a] : | hash_flow.rb:892:5:892:8 | hash [element :a] : | +| hash_flow.rb:892:12:892:38 | call to reverse_merge! [element :c] : | hash_flow.rb:892:5:892:8 | hash [element :c] : | +| hash_flow.rb:892:12:892:38 | call to reverse_merge! [element :d] : | hash_flow.rb:892:5:892:8 | hash [element :d] : | +| hash_flow.rb:892:12:892:38 | call to reverse_merge! [element :f] : | hash_flow.rb:892:5:892:8 | hash [element :f] : | | hash_flow.rb:892:33:892:37 | hash2 [element :d] : | hash_flow.rb:892:12:892:16 | [post] hash1 [element :d] : | | hash_flow.rb:892:33:892:37 | hash2 [element :d] : | hash_flow.rb:892:12:892:38 | call to reverse_merge! [element :d] : | | hash_flow.rb:892:33:892:37 | hash2 [element :f] : | hash_flow.rb:892:12:892:16 | [post] hash1 [element :f] : | @@ -694,10 +877,18 @@ edges | hash_flow.rb:903:11:903:19 | ...[...] : | hash_flow.rb:903:10:903:20 | ( ... ) | | hash_flow.rb:905:11:905:15 | hash1 [element :f] : | hash_flow.rb:905:11:905:19 | ...[...] : | | hash_flow.rb:905:11:905:19 | ...[...] : | hash_flow.rb:905:10:905:20 | ( ... ) | -| hash_flow.rb:912:12:912:22 | call to taint : | hash_flow.rb:922:12:922:16 | hash1 [element :a] : | -| hash_flow.rb:914:12:914:22 | call to taint : | hash_flow.rb:922:12:922:16 | hash1 [element :c] : | -| hash_flow.rb:917:12:917:22 | call to taint : | hash_flow.rb:922:33:922:37 | hash2 [element :d] : | -| hash_flow.rb:919:12:919:22 | call to taint : | hash_flow.rb:922:33:922:37 | hash2 [element :f] : | +| hash_flow.rb:911:5:911:9 | hash1 [element :a] : | hash_flow.rb:922:12:922:16 | hash1 [element :a] : | +| hash_flow.rb:911:5:911:9 | hash1 [element :c] : | hash_flow.rb:922:12:922:16 | hash1 [element :c] : | +| hash_flow.rb:912:12:912:22 | call to taint : | hash_flow.rb:911:5:911:9 | hash1 [element :a] : | +| hash_flow.rb:914:12:914:22 | call to taint : | hash_flow.rb:911:5:911:9 | hash1 [element :c] : | +| hash_flow.rb:916:5:916:9 | hash2 [element :d] : | hash_flow.rb:922:33:922:37 | hash2 [element :d] : | +| hash_flow.rb:916:5:916:9 | hash2 [element :f] : | hash_flow.rb:922:33:922:37 | hash2 [element :f] : | +| hash_flow.rb:917:12:917:22 | call to taint : | hash_flow.rb:916:5:916:9 | hash2 [element :d] : | +| hash_flow.rb:919:12:919:22 | call to taint : | hash_flow.rb:916:5:916:9 | hash2 [element :f] : | +| hash_flow.rb:922:5:922:8 | hash [element :a] : | hash_flow.rb:923:11:923:14 | hash [element :a] : | +| hash_flow.rb:922:5:922:8 | hash [element :c] : | hash_flow.rb:925:11:925:14 | hash [element :c] : | +| hash_flow.rb:922:5:922:8 | hash [element :d] : | hash_flow.rb:926:11:926:14 | hash [element :d] : | +| hash_flow.rb:922:5:922:8 | hash [element :f] : | hash_flow.rb:928:11:928:14 | hash [element :f] : | | hash_flow.rb:922:12:922:16 | [post] hash1 [element :a] : | hash_flow.rb:930:11:930:15 | hash1 [element :a] : | | hash_flow.rb:922:12:922:16 | [post] hash1 [element :c] : | hash_flow.rb:932:11:932:15 | hash1 [element :c] : | | hash_flow.rb:922:12:922:16 | [post] hash1 [element :d] : | hash_flow.rb:933:11:933:15 | hash1 [element :d] : | @@ -706,10 +897,10 @@ edges | hash_flow.rb:922:12:922:16 | hash1 [element :a] : | hash_flow.rb:922:12:922:38 | call to with_defaults! [element :a] : | | hash_flow.rb:922:12:922:16 | hash1 [element :c] : | hash_flow.rb:922:12:922:16 | [post] hash1 [element :c] : | | hash_flow.rb:922:12:922:16 | hash1 [element :c] : | hash_flow.rb:922:12:922:38 | call to with_defaults! [element :c] : | -| hash_flow.rb:922:12:922:38 | call to with_defaults! [element :a] : | hash_flow.rb:923:11:923:14 | hash [element :a] : | -| hash_flow.rb:922:12:922:38 | call to with_defaults! [element :c] : | hash_flow.rb:925:11:925:14 | hash [element :c] : | -| hash_flow.rb:922:12:922:38 | call to with_defaults! [element :d] : | hash_flow.rb:926:11:926:14 | hash [element :d] : | -| hash_flow.rb:922:12:922:38 | call to with_defaults! [element :f] : | hash_flow.rb:928:11:928:14 | hash [element :f] : | +| hash_flow.rb:922:12:922:38 | call to with_defaults! [element :a] : | hash_flow.rb:922:5:922:8 | hash [element :a] : | +| hash_flow.rb:922:12:922:38 | call to with_defaults! [element :c] : | hash_flow.rb:922:5:922:8 | hash [element :c] : | +| hash_flow.rb:922:12:922:38 | call to with_defaults! [element :d] : | hash_flow.rb:922:5:922:8 | hash [element :d] : | +| hash_flow.rb:922:12:922:38 | call to with_defaults! [element :f] : | hash_flow.rb:922:5:922:8 | hash [element :f] : | | hash_flow.rb:922:33:922:37 | hash2 [element :d] : | hash_flow.rb:922:12:922:16 | [post] hash1 [element :d] : | | hash_flow.rb:922:33:922:37 | hash2 [element :d] : | hash_flow.rb:922:12:922:38 | call to with_defaults! [element :d] : | | hash_flow.rb:922:33:922:37 | hash2 [element :f] : | hash_flow.rb:922:12:922:16 | [post] hash1 [element :f] : | @@ -730,10 +921,18 @@ edges | hash_flow.rb:933:11:933:19 | ...[...] : | hash_flow.rb:933:10:933:20 | ( ... ) | | hash_flow.rb:935:11:935:15 | hash1 [element :f] : | hash_flow.rb:935:11:935:19 | ...[...] : | | hash_flow.rb:935:11:935:19 | ...[...] : | hash_flow.rb:935:10:935:20 | ( ... ) | -| hash_flow.rb:942:12:942:22 | call to taint : | hash_flow.rb:952:12:952:16 | hash1 [element :a] : | -| hash_flow.rb:944:12:944:22 | call to taint : | hash_flow.rb:952:12:952:16 | hash1 [element :c] : | -| hash_flow.rb:947:12:947:22 | call to taint : | hash_flow.rb:952:33:952:37 | hash2 [element :d] : | -| hash_flow.rb:949:12:949:22 | call to taint : | hash_flow.rb:952:33:952:37 | hash2 [element :f] : | +| hash_flow.rb:941:5:941:9 | hash1 [element :a] : | hash_flow.rb:952:12:952:16 | hash1 [element :a] : | +| hash_flow.rb:941:5:941:9 | hash1 [element :c] : | hash_flow.rb:952:12:952:16 | hash1 [element :c] : | +| hash_flow.rb:942:12:942:22 | call to taint : | hash_flow.rb:941:5:941:9 | hash1 [element :a] : | +| hash_flow.rb:944:12:944:22 | call to taint : | hash_flow.rb:941:5:941:9 | hash1 [element :c] : | +| hash_flow.rb:946:5:946:9 | hash2 [element :d] : | hash_flow.rb:952:33:952:37 | hash2 [element :d] : | +| hash_flow.rb:946:5:946:9 | hash2 [element :f] : | hash_flow.rb:952:33:952:37 | hash2 [element :f] : | +| hash_flow.rb:947:12:947:22 | call to taint : | hash_flow.rb:946:5:946:9 | hash2 [element :d] : | +| hash_flow.rb:949:12:949:22 | call to taint : | hash_flow.rb:946:5:946:9 | hash2 [element :f] : | +| hash_flow.rb:952:5:952:8 | hash [element :a] : | hash_flow.rb:953:11:953:14 | hash [element :a] : | +| hash_flow.rb:952:5:952:8 | hash [element :c] : | hash_flow.rb:955:11:955:14 | hash [element :c] : | +| hash_flow.rb:952:5:952:8 | hash [element :d] : | hash_flow.rb:956:11:956:14 | hash [element :d] : | +| hash_flow.rb:952:5:952:8 | hash [element :f] : | hash_flow.rb:958:11:958:14 | hash [element :f] : | | hash_flow.rb:952:12:952:16 | [post] hash1 [element :a] : | hash_flow.rb:960:11:960:15 | hash1 [element :a] : | | hash_flow.rb:952:12:952:16 | [post] hash1 [element :c] : | hash_flow.rb:962:11:962:15 | hash1 [element :c] : | | hash_flow.rb:952:12:952:16 | [post] hash1 [element :d] : | hash_flow.rb:963:11:963:15 | hash1 [element :d] : | @@ -742,10 +941,10 @@ edges | hash_flow.rb:952:12:952:16 | hash1 [element :a] : | hash_flow.rb:952:12:952:38 | call to with_defaults! [element :a] : | | hash_flow.rb:952:12:952:16 | hash1 [element :c] : | hash_flow.rb:952:12:952:16 | [post] hash1 [element :c] : | | hash_flow.rb:952:12:952:16 | hash1 [element :c] : | hash_flow.rb:952:12:952:38 | call to with_defaults! [element :c] : | -| hash_flow.rb:952:12:952:38 | call to with_defaults! [element :a] : | hash_flow.rb:953:11:953:14 | hash [element :a] : | -| hash_flow.rb:952:12:952:38 | call to with_defaults! [element :c] : | hash_flow.rb:955:11:955:14 | hash [element :c] : | -| hash_flow.rb:952:12:952:38 | call to with_defaults! [element :d] : | hash_flow.rb:956:11:956:14 | hash [element :d] : | -| hash_flow.rb:952:12:952:38 | call to with_defaults! [element :f] : | hash_flow.rb:958:11:958:14 | hash [element :f] : | +| hash_flow.rb:952:12:952:38 | call to with_defaults! [element :a] : | hash_flow.rb:952:5:952:8 | hash [element :a] : | +| hash_flow.rb:952:12:952:38 | call to with_defaults! [element :c] : | hash_flow.rb:952:5:952:8 | hash [element :c] : | +| hash_flow.rb:952:12:952:38 | call to with_defaults! [element :d] : | hash_flow.rb:952:5:952:8 | hash [element :d] : | +| hash_flow.rb:952:12:952:38 | call to with_defaults! [element :f] : | hash_flow.rb:952:5:952:8 | hash [element :f] : | | hash_flow.rb:952:33:952:37 | hash2 [element :d] : | hash_flow.rb:952:12:952:16 | [post] hash1 [element :d] : | | hash_flow.rb:952:33:952:37 | hash2 [element :d] : | hash_flow.rb:952:12:952:38 | call to with_defaults! [element :d] : | | hash_flow.rb:952:33:952:37 | hash2 [element :f] : | hash_flow.rb:952:12:952:16 | [post] hash1 [element :f] : | @@ -767,6 +966,11 @@ edges | hash_flow.rb:965:11:965:15 | hash1 [element :f] : | hash_flow.rb:965:11:965:19 | ...[...] : | | hash_flow.rb:965:11:965:19 | ...[...] : | hash_flow.rb:965:10:965:20 | ( ... ) | nodes +| hash_flow.rb:10:5:10:8 | hash [element 0] : | semmle.label | hash [element 0] : | +| hash_flow.rb:10:5:10:8 | hash [element :a] : | semmle.label | hash [element :a] : | +| hash_flow.rb:10:5:10:8 | hash [element :c] : | semmle.label | hash [element :c] : | +| hash_flow.rb:10:5:10:8 | hash [element e] : | semmle.label | hash [element e] : | +| hash_flow.rb:10:5:10:8 | hash [element g] : | semmle.label | hash [element g] : | | hash_flow.rb:11:15:11:24 | call to taint : | semmle.label | call to taint : | | hash_flow.rb:13:12:13:21 | call to taint : | semmle.label | call to taint : | | hash_flow.rb:15:14:15:23 | call to taint : | semmle.label | call to taint : | @@ -812,50 +1016,64 @@ nodes | hash_flow.rb:46:10:46:17 | ...[...] | semmle.label | ...[...] | | hash_flow.rb:48:10:48:13 | hash [element a] : | semmle.label | hash [element a] : | | hash_flow.rb:48:10:48:18 | ...[...] | semmle.label | ...[...] | +| hash_flow.rb:55:5:55:9 | hash1 [element :a] : | semmle.label | hash1 [element :a] : | | hash_flow.rb:55:13:55:37 | ...[...] [element :a] : | semmle.label | ...[...] [element :a] : | | hash_flow.rb:55:21:55:30 | call to taint : | semmle.label | call to taint : | | hash_flow.rb:56:10:56:14 | hash1 [element :a] : | semmle.label | hash1 [element :a] : | | hash_flow.rb:56:10:56:18 | ...[...] | semmle.label | ...[...] | +| hash_flow.rb:59:5:59:5 | x [element :a] : | semmle.label | x [element :a] : | | hash_flow.rb:59:13:59:22 | call to taint : | semmle.label | call to taint : | +| hash_flow.rb:60:5:60:9 | hash2 [element :a] : | semmle.label | hash2 [element :a] : | | hash_flow.rb:60:13:60:19 | ...[...] [element :a] : | semmle.label | ...[...] [element :a] : | | hash_flow.rb:60:18:60:18 | x [element :a] : | semmle.label | x [element :a] : | | hash_flow.rb:61:10:61:14 | hash2 [element :a] : | semmle.label | hash2 [element :a] : | | hash_flow.rb:61:10:61:18 | ...[...] | semmle.label | ...[...] | +| hash_flow.rb:64:5:64:9 | hash3 [element] : | semmle.label | hash3 [element] : | | hash_flow.rb:64:13:64:45 | ...[...] [element] : | semmle.label | ...[...] [element] : | | hash_flow.rb:64:24:64:33 | call to taint : | semmle.label | call to taint : | | hash_flow.rb:65:10:65:14 | hash3 [element] : | semmle.label | hash3 [element] : | | hash_flow.rb:65:10:65:18 | ...[...] | semmle.label | ...[...] | | hash_flow.rb:66:10:66:14 | hash3 [element] : | semmle.label | hash3 [element] : | | hash_flow.rb:66:10:66:18 | ...[...] | semmle.label | ...[...] | +| hash_flow.rb:68:5:68:9 | hash4 [element :a] : | semmle.label | hash4 [element :a] : | | hash_flow.rb:68:13:68:39 | ...[...] [element :a] : | semmle.label | ...[...] [element :a] : | | hash_flow.rb:68:22:68:31 | call to taint : | semmle.label | call to taint : | | hash_flow.rb:69:10:69:14 | hash4 [element :a] : | semmle.label | hash4 [element :a] : | | hash_flow.rb:69:10:69:18 | ...[...] | semmle.label | ...[...] | +| hash_flow.rb:72:5:72:9 | hash5 [element a] : | semmle.label | hash5 [element a] : | | hash_flow.rb:72:13:72:45 | ...[...] [element a] : | semmle.label | ...[...] [element a] : | | hash_flow.rb:72:25:72:34 | call to taint : | semmle.label | call to taint : | | hash_flow.rb:73:10:73:14 | hash5 [element a] : | semmle.label | hash5 [element a] : | | hash_flow.rb:73:10:73:19 | ...[...] | semmle.label | ...[...] | +| hash_flow.rb:76:5:76:9 | hash6 [element a] : | semmle.label | hash6 [element a] : | | hash_flow.rb:76:13:76:47 | ...[...] [element a] : | semmle.label | ...[...] [element a] : | | hash_flow.rb:76:26:76:35 | call to taint : | semmle.label | call to taint : | | hash_flow.rb:77:10:77:14 | hash6 [element a] : | semmle.label | hash6 [element a] : | | hash_flow.rb:77:10:77:19 | ...[...] | semmle.label | ...[...] | +| hash_flow.rb:84:5:84:9 | hash1 [element :a] : | semmle.label | hash1 [element :a] : | | hash_flow.rb:84:13:84:42 | call to [] [element :a] : | semmle.label | call to [] [element :a] : | | hash_flow.rb:84:26:84:35 | call to taint : | semmle.label | call to taint : | | hash_flow.rb:85:10:85:14 | hash1 [element :a] : | semmle.label | hash1 [element :a] : | | hash_flow.rb:85:10:85:18 | ...[...] | semmle.label | ...[...] | +| hash_flow.rb:92:5:92:8 | hash [element :a] : | semmle.label | hash [element :a] : | | hash_flow.rb:93:15:93:24 | call to taint : | semmle.label | call to taint : | +| hash_flow.rb:96:5:96:9 | hash2 [element :a] : | semmle.label | hash2 [element :a] : | | hash_flow.rb:96:13:96:34 | call to try_convert [element :a] : | semmle.label | call to try_convert [element :a] : | | hash_flow.rb:96:30:96:33 | hash [element :a] : | semmle.label | hash [element :a] : | | hash_flow.rb:97:10:97:14 | hash2 [element :a] : | semmle.label | hash2 [element :a] : | | hash_flow.rb:97:10:97:18 | ...[...] | semmle.label | ...[...] | +| hash_flow.rb:105:5:105:5 | b : | semmle.label | b : | +| hash_flow.rb:105:21:105:30 | __synth__0 : | semmle.label | __synth__0 : | | hash_flow.rb:105:21:105:30 | call to taint : | semmle.label | call to taint : | | hash_flow.rb:106:10:106:10 | b | semmle.label | b | +| hash_flow.rb:113:5:113:5 | b : | semmle.label | b : | | hash_flow.rb:113:9:113:12 | [post] hash [element :a] : | semmle.label | [post] hash [element :a] : | | hash_flow.rb:113:9:113:34 | call to store : | semmle.label | call to store : | | hash_flow.rb:113:24:113:33 | call to taint : | semmle.label | call to taint : | | hash_flow.rb:114:10:114:13 | hash [element :a] : | semmle.label | hash [element :a] : | | hash_flow.rb:114:10:114:17 | ...[...] | semmle.label | ...[...] | | hash_flow.rb:115:10:115:10 | b | semmle.label | b | +| hash_flow.rb:118:5:118:5 | c : | semmle.label | c : | | hash_flow.rb:118:9:118:12 | [post] hash [element] : | semmle.label | [post] hash [element] : | | hash_flow.rb:118:9:118:33 | call to store : | semmle.label | call to store : | | hash_flow.rb:118:23:118:32 | call to taint : | semmle.label | call to taint : | @@ -864,6 +1082,7 @@ nodes | hash_flow.rb:120:10:120:13 | hash [element] : | semmle.label | hash [element] : | | hash_flow.rb:120:10:120:17 | ...[...] | semmle.label | ...[...] | | hash_flow.rb:121:10:121:10 | c | semmle.label | c | +| hash_flow.rb:127:5:127:8 | hash [element :a] : | semmle.label | hash [element :a] : | | hash_flow.rb:128:15:128:24 | call to taint : | semmle.label | call to taint : | | hash_flow.rb:131:5:131:8 | hash [element :a] : | semmle.label | hash [element :a] : | | hash_flow.rb:131:18:131:29 | key_or_value : | semmle.label | key_or_value : | @@ -871,27 +1090,36 @@ nodes | hash_flow.rb:134:5:134:8 | hash [element :a] : | semmle.label | hash [element :a] : | | hash_flow.rb:134:22:134:26 | value : | semmle.label | value : | | hash_flow.rb:136:14:136:18 | value | semmle.label | value | +| hash_flow.rb:143:5:143:8 | hash [element :a] : | semmle.label | hash [element :a] : | | hash_flow.rb:144:15:144:25 | call to taint : | semmle.label | call to taint : | +| hash_flow.rb:147:5:147:5 | b [element 1] : | semmle.label | b [element 1] : | | hash_flow.rb:147:9:147:12 | hash [element :a] : | semmle.label | hash [element :a] : | | hash_flow.rb:147:9:147:22 | call to assoc [element 1] : | semmle.label | call to assoc [element 1] : | | hash_flow.rb:149:10:149:10 | b [element 1] : | semmle.label | b [element 1] : | | hash_flow.rb:149:10:149:13 | ...[...] | semmle.label | ...[...] | | hash_flow.rb:150:10:150:10 | b [element 1] : | semmle.label | b [element 1] : | | hash_flow.rb:150:10:150:13 | ...[...] | semmle.label | ...[...] | +| hash_flow.rb:151:5:151:5 | c [element 1] : | semmle.label | c [element 1] : | | hash_flow.rb:151:9:151:12 | hash [element :a] : | semmle.label | hash [element :a] : | | hash_flow.rb:151:9:151:21 | call to assoc [element 1] : | semmle.label | call to assoc [element 1] : | | hash_flow.rb:152:10:152:10 | c [element 1] : | semmle.label | c [element 1] : | | hash_flow.rb:152:10:152:13 | ...[...] | semmle.label | ...[...] | +| hash_flow.rb:169:5:169:8 | hash [element :a] : | semmle.label | hash [element :a] : | | hash_flow.rb:170:15:170:25 | call to taint : | semmle.label | call to taint : | +| hash_flow.rb:173:5:173:5 | a [element :a] : | semmle.label | a [element :a] : | | hash_flow.rb:173:9:173:12 | hash [element :a] : | semmle.label | hash [element :a] : | | hash_flow.rb:173:9:173:20 | call to compact [element :a] : | semmle.label | call to compact [element :a] : | | hash_flow.rb:174:10:174:10 | a [element :a] : | semmle.label | a [element :a] : | | hash_flow.rb:174:10:174:14 | ...[...] | semmle.label | ...[...] | +| hash_flow.rb:181:5:181:8 | hash [element :a] : | semmle.label | hash [element :a] : | | hash_flow.rb:182:15:182:25 | call to taint : | semmle.label | call to taint : | +| hash_flow.rb:185:5:185:5 | a : | semmle.label | a : | | hash_flow.rb:185:9:185:12 | hash [element :a] : | semmle.label | hash [element :a] : | | hash_flow.rb:185:9:185:23 | call to delete : | semmle.label | call to delete : | | hash_flow.rb:186:10:186:10 | a | semmle.label | a | +| hash_flow.rb:193:5:193:8 | hash [element :a] : | semmle.label | hash [element :a] : | | hash_flow.rb:194:15:194:25 | call to taint : | semmle.label | call to taint : | +| hash_flow.rb:197:5:197:5 | a [element :a] : | semmle.label | a [element :a] : | | hash_flow.rb:197:9:197:12 | [post] hash [element :a] : | semmle.label | [post] hash [element :a] : | | hash_flow.rb:197:9:197:12 | hash [element :a] : | semmle.label | hash [element :a] : | | hash_flow.rb:197:9:200:7 | call to delete_if [element :a] : | semmle.label | call to delete_if [element :a] : | @@ -901,45 +1129,60 @@ nodes | hash_flow.rb:201:10:201:14 | ...[...] | semmle.label | ...[...] | | hash_flow.rb:202:10:202:13 | hash [element :a] : | semmle.label | hash [element :a] : | | hash_flow.rb:202:10:202:17 | ...[...] | semmle.label | ...[...] | +| hash_flow.rb:209:5:209:8 | hash [element :a] : | semmle.label | hash [element :a] : | +| hash_flow.rb:209:5:209:8 | hash [element :c, element :d] : | semmle.label | hash [element :c, element :d] : | | hash_flow.rb:210:15:210:25 | call to taint : | semmle.label | call to taint : | | hash_flow.rb:213:19:213:29 | call to taint : | semmle.label | call to taint : | | hash_flow.rb:217:10:217:13 | hash [element :a] : | semmle.label | hash [element :a] : | | hash_flow.rb:217:10:217:21 | call to dig | semmle.label | call to dig | | hash_flow.rb:219:10:219:13 | hash [element :c, element :d] : | semmle.label | hash [element :c, element :d] : | | hash_flow.rb:219:10:219:24 | call to dig | semmle.label | call to dig | +| hash_flow.rb:226:5:226:8 | hash [element :a] : | semmle.label | hash [element :a] : | | hash_flow.rb:227:15:227:25 | call to taint : | semmle.label | call to taint : | +| hash_flow.rb:230:5:230:5 | x [element :a] : | semmle.label | x [element :a] : | | hash_flow.rb:230:9:230:12 | hash [element :a] : | semmle.label | hash [element :a] : | | hash_flow.rb:230:9:233:7 | call to each [element :a] : | semmle.label | call to each [element :a] : | | hash_flow.rb:230:28:230:32 | value : | semmle.label | value : | | hash_flow.rb:232:14:232:18 | value | semmle.label | value | | hash_flow.rb:234:10:234:10 | x [element :a] : | semmle.label | x [element :a] : | | hash_flow.rb:234:10:234:14 | ...[...] | semmle.label | ...[...] | +| hash_flow.rb:241:5:241:8 | hash [element :a] : | semmle.label | hash [element :a] : | | hash_flow.rb:242:15:242:25 | call to taint : | semmle.label | call to taint : | +| hash_flow.rb:245:5:245:5 | x [element :a] : | semmle.label | x [element :a] : | | hash_flow.rb:245:9:245:12 | hash [element :a] : | semmle.label | hash [element :a] : | | hash_flow.rb:245:9:247:7 | call to each_key [element :a] : | semmle.label | call to each_key [element :a] : | | hash_flow.rb:248:10:248:10 | x [element :a] : | semmle.label | x [element :a] : | | hash_flow.rb:248:10:248:14 | ...[...] | semmle.label | ...[...] | +| hash_flow.rb:255:5:255:8 | hash [element :a] : | semmle.label | hash [element :a] : | | hash_flow.rb:256:15:256:25 | call to taint : | semmle.label | call to taint : | +| hash_flow.rb:259:5:259:5 | x [element :a] : | semmle.label | x [element :a] : | | hash_flow.rb:259:9:259:12 | hash [element :a] : | semmle.label | hash [element :a] : | | hash_flow.rb:259:9:262:7 | call to each_pair [element :a] : | semmle.label | call to each_pair [element :a] : | | hash_flow.rb:259:33:259:37 | value : | semmle.label | value : | | hash_flow.rb:261:14:261:18 | value | semmle.label | value | | hash_flow.rb:263:10:263:10 | x [element :a] : | semmle.label | x [element :a] : | | hash_flow.rb:263:10:263:14 | ...[...] | semmle.label | ...[...] | +| hash_flow.rb:270:5:270:8 | hash [element :a] : | semmle.label | hash [element :a] : | | hash_flow.rb:271:15:271:25 | call to taint : | semmle.label | call to taint : | +| hash_flow.rb:274:5:274:5 | x [element :a] : | semmle.label | x [element :a] : | | hash_flow.rb:274:9:274:12 | hash [element :a] : | semmle.label | hash [element :a] : | | hash_flow.rb:274:9:276:7 | call to each_value [element :a] : | semmle.label | call to each_value [element :a] : | | hash_flow.rb:274:29:274:33 | value : | semmle.label | value : | | hash_flow.rb:275:14:275:18 | value | semmle.label | value | | hash_flow.rb:277:10:277:10 | x [element :a] : | semmle.label | x [element :a] : | | hash_flow.rb:277:10:277:14 | ...[...] | semmle.label | ...[...] | +| hash_flow.rb:284:5:284:8 | hash [element :c] : | semmle.label | hash [element :c] : | | hash_flow.rb:287:15:287:25 | call to taint : | semmle.label | call to taint : | +| hash_flow.rb:290:5:290:5 | x [element :c] : | semmle.label | x [element :c] : | | hash_flow.rb:290:9:290:12 | hash [element :c] : | semmle.label | hash [element :c] : | | hash_flow.rb:290:9:290:28 | call to except [element :c] : | semmle.label | call to except [element :c] : | | hash_flow.rb:293:10:293:10 | x [element :c] : | semmle.label | x [element :c] : | | hash_flow.rb:293:10:293:14 | ...[...] | semmle.label | ...[...] | +| hash_flow.rb:300:5:300:8 | hash [element :a] : | semmle.label | hash [element :a] : | +| hash_flow.rb:300:5:300:8 | hash [element :c] : | semmle.label | hash [element :c] : | | hash_flow.rb:301:15:301:25 | call to taint : | semmle.label | call to taint : | | hash_flow.rb:303:15:303:25 | call to taint : | semmle.label | call to taint : | +| hash_flow.rb:305:5:305:5 | b : | semmle.label | b : | | hash_flow.rb:305:9:305:12 | hash [element :a] : | semmle.label | hash [element :a] : | | hash_flow.rb:305:9:305:12 | hash [element :c] : | semmle.label | hash [element :c] : | | hash_flow.rb:305:9:307:7 | call to fetch : | semmle.label | call to fetch : | @@ -947,23 +1190,30 @@ nodes | hash_flow.rb:305:37:305:37 | x : | semmle.label | x : | | hash_flow.rb:306:14:306:14 | x | semmle.label | x | | hash_flow.rb:308:10:308:10 | b | semmle.label | b | +| hash_flow.rb:309:5:309:5 | b : | semmle.label | b : | | hash_flow.rb:309:9:309:12 | hash [element :a] : | semmle.label | hash [element :a] : | | hash_flow.rb:309:9:309:22 | call to fetch : | semmle.label | call to fetch : | | hash_flow.rb:310:10:310:10 | b | semmle.label | b | +| hash_flow.rb:311:5:311:5 | b : | semmle.label | b : | | hash_flow.rb:311:9:311:12 | hash [element :a] : | semmle.label | hash [element :a] : | | hash_flow.rb:311:9:311:35 | call to fetch : | semmle.label | call to fetch : | | hash_flow.rb:311:24:311:34 | call to taint : | semmle.label | call to taint : | | hash_flow.rb:312:10:312:10 | b | semmle.label | b | +| hash_flow.rb:313:5:313:5 | b : | semmle.label | b : | | hash_flow.rb:313:9:313:35 | call to fetch : | semmle.label | call to fetch : | | hash_flow.rb:313:24:313:34 | call to taint : | semmle.label | call to taint : | | hash_flow.rb:314:10:314:10 | b | semmle.label | b | +| hash_flow.rb:315:5:315:5 | b : | semmle.label | b : | | hash_flow.rb:315:9:315:12 | hash [element :a] : | semmle.label | hash [element :a] : | | hash_flow.rb:315:9:315:12 | hash [element :c] : | semmle.label | hash [element :c] : | | hash_flow.rb:315:9:315:34 | call to fetch : | semmle.label | call to fetch : | | hash_flow.rb:315:23:315:33 | call to taint : | semmle.label | call to taint : | | hash_flow.rb:316:10:316:10 | b | semmle.label | b | +| hash_flow.rb:322:5:322:8 | hash [element :a] : | semmle.label | hash [element :a] : | +| hash_flow.rb:322:5:322:8 | hash [element :c] : | semmle.label | hash [element :c] : | | hash_flow.rb:323:15:323:25 | call to taint : | semmle.label | call to taint : | | hash_flow.rb:325:15:325:25 | call to taint : | semmle.label | call to taint : | +| hash_flow.rb:327:5:327:5 | b [element] : | semmle.label | b [element] : | | hash_flow.rb:327:9:327:12 | hash [element :a] : | semmle.label | hash [element :a] : | | hash_flow.rb:327:9:327:12 | hash [element :c] : | semmle.label | hash [element :c] : | | hash_flow.rb:327:9:330:7 | call to fetch_values [element] : | semmle.label | call to fetch_values [element] : | @@ -973,17 +1223,22 @@ nodes | hash_flow.rb:329:9:329:19 | call to taint : | semmle.label | call to taint : | | hash_flow.rb:331:10:331:10 | b [element] : | semmle.label | b [element] : | | hash_flow.rb:331:10:331:13 | ...[...] | semmle.label | ...[...] | +| hash_flow.rb:332:5:332:5 | b [element] : | semmle.label | b [element] : | | hash_flow.rb:332:9:332:12 | hash [element :a] : | semmle.label | hash [element :a] : | | hash_flow.rb:332:9:332:29 | call to fetch_values [element] : | semmle.label | call to fetch_values [element] : | | hash_flow.rb:333:10:333:10 | b [element] : | semmle.label | b [element] : | | hash_flow.rb:333:10:333:13 | ...[...] | semmle.label | ...[...] | +| hash_flow.rb:334:5:334:5 | b [element] : | semmle.label | b [element] : | | hash_flow.rb:334:9:334:12 | hash [element :a] : | semmle.label | hash [element :a] : | | hash_flow.rb:334:9:334:12 | hash [element :c] : | semmle.label | hash [element :c] : | | hash_flow.rb:334:9:334:31 | call to fetch_values [element] : | semmle.label | call to fetch_values [element] : | | hash_flow.rb:335:10:335:10 | b [element] : | semmle.label | b [element] : | | hash_flow.rb:335:10:335:13 | ...[...] | semmle.label | ...[...] | +| hash_flow.rb:341:5:341:8 | hash [element :a] : | semmle.label | hash [element :a] : | +| hash_flow.rb:341:5:341:8 | hash [element :c] : | semmle.label | hash [element :c] : | | hash_flow.rb:342:15:342:25 | call to taint : | semmle.label | call to taint : | | hash_flow.rb:344:15:344:25 | call to taint : | semmle.label | call to taint : | +| hash_flow.rb:346:5:346:5 | b [element :a] : | semmle.label | b [element :a] : | | hash_flow.rb:346:9:346:12 | hash [element :a] : | semmle.label | hash [element :a] : | | hash_flow.rb:346:9:346:12 | hash [element :c] : | semmle.label | hash [element :c] : | | hash_flow.rb:346:9:350:7 | call to filter [element :a] : | semmle.label | call to filter [element :a] : | @@ -992,6 +1247,8 @@ nodes | hash_flow.rb:351:10:351:16 | ( ... ) | semmle.label | ( ... ) | | hash_flow.rb:351:11:351:11 | b [element :a] : | semmle.label | b [element :a] : | | hash_flow.rb:351:11:351:15 | ...[...] : | semmle.label | ...[...] : | +| hash_flow.rb:357:5:357:8 | hash [element :a] : | semmle.label | hash [element :a] : | +| hash_flow.rb:357:5:357:8 | hash [element :c] : | semmle.label | hash [element :c] : | | hash_flow.rb:358:15:358:25 | call to taint : | semmle.label | call to taint : | | hash_flow.rb:360:15:360:25 | call to taint : | semmle.label | call to taint : | | hash_flow.rb:362:5:362:8 | [post] hash [element :a] : | semmle.label | [post] hash [element :a] : | @@ -1002,16 +1259,22 @@ nodes | hash_flow.rb:367:10:367:19 | ( ... ) | semmle.label | ( ... ) | | hash_flow.rb:367:11:367:14 | hash [element :a] : | semmle.label | hash [element :a] : | | hash_flow.rb:367:11:367:18 | ...[...] : | semmle.label | ...[...] : | +| hash_flow.rb:373:5:373:8 | hash [element :a] : | semmle.label | hash [element :a] : | +| hash_flow.rb:373:5:373:8 | hash [element :c] : | semmle.label | hash [element :c] : | | hash_flow.rb:374:15:374:25 | call to taint : | semmle.label | call to taint : | | hash_flow.rb:376:15:376:25 | call to taint : | semmle.label | call to taint : | +| hash_flow.rb:378:5:378:5 | b [element] : | semmle.label | b [element] : | | hash_flow.rb:378:9:378:12 | hash [element :a] : | semmle.label | hash [element :a] : | | hash_flow.rb:378:9:378:12 | hash [element :c] : | semmle.label | hash [element :c] : | | hash_flow.rb:378:9:378:20 | call to flatten [element] : | semmle.label | call to flatten [element] : | | hash_flow.rb:379:10:379:15 | ( ... ) | semmle.label | ( ... ) | | hash_flow.rb:379:11:379:11 | b [element] : | semmle.label | b [element] : | | hash_flow.rb:379:11:379:14 | ...[...] : | semmle.label | ...[...] : | +| hash_flow.rb:385:5:385:8 | hash [element :a] : | semmle.label | hash [element :a] : | +| hash_flow.rb:385:5:385:8 | hash [element :c] : | semmle.label | hash [element :c] : | | hash_flow.rb:386:15:386:25 | call to taint : | semmle.label | call to taint : | | hash_flow.rb:388:15:388:25 | call to taint : | semmle.label | call to taint : | +| hash_flow.rb:390:5:390:5 | b [element :a] : | semmle.label | b [element :a] : | | hash_flow.rb:390:9:390:12 | [post] hash [element :a] : | semmle.label | [post] hash [element :a] : | | hash_flow.rb:390:9:390:12 | hash [element :a] : | semmle.label | hash [element :a] : | | hash_flow.rb:390:9:390:12 | hash [element :c] : | semmle.label | hash [element :c] : | @@ -1024,10 +1287,18 @@ nodes | hash_flow.rb:396:10:396:16 | ( ... ) | semmle.label | ( ... ) | | hash_flow.rb:396:11:396:11 | b [element :a] : | semmle.label | b [element :a] : | | hash_flow.rb:396:11:396:15 | ...[...] : | semmle.label | ...[...] : | +| hash_flow.rb:402:5:402:9 | hash1 [element :a] : | semmle.label | hash1 [element :a] : | +| hash_flow.rb:402:5:402:9 | hash1 [element :c] : | semmle.label | hash1 [element :c] : | | hash_flow.rb:403:15:403:25 | call to taint : | semmle.label | call to taint : | | hash_flow.rb:405:15:405:25 | call to taint : | semmle.label | call to taint : | +| hash_flow.rb:407:5:407:9 | hash2 [element :d] : | semmle.label | hash2 [element :d] : | +| hash_flow.rb:407:5:407:9 | hash2 [element :f] : | semmle.label | hash2 [element :f] : | | hash_flow.rb:408:15:408:25 | call to taint : | semmle.label | call to taint : | | hash_flow.rb:410:15:410:25 | call to taint : | semmle.label | call to taint : | +| hash_flow.rb:412:5:412:8 | hash [element :a] : | semmle.label | hash [element :a] : | +| hash_flow.rb:412:5:412:8 | hash [element :c] : | semmle.label | hash [element :c] : | +| hash_flow.rb:412:5:412:8 | hash [element :d] : | semmle.label | hash [element :d] : | +| hash_flow.rb:412:5:412:8 | hash [element :f] : | semmle.label | hash [element :f] : | | hash_flow.rb:412:12:412:16 | hash1 [element :a] : | semmle.label | hash1 [element :a] : | | hash_flow.rb:412:12:412:16 | hash1 [element :c] : | semmle.label | hash1 [element :c] : | | hash_flow.rb:412:12:416:7 | call to merge [element :a] : | semmle.label | call to merge [element :a] : | @@ -1052,10 +1323,18 @@ nodes | hash_flow.rb:422:10:422:19 | ( ... ) | semmle.label | ( ... ) | | hash_flow.rb:422:11:422:14 | hash [element :f] : | semmle.label | hash [element :f] : | | hash_flow.rb:422:11:422:18 | ...[...] : | semmle.label | ...[...] : | +| hash_flow.rb:428:5:428:9 | hash1 [element :a] : | semmle.label | hash1 [element :a] : | +| hash_flow.rb:428:5:428:9 | hash1 [element :c] : | semmle.label | hash1 [element :c] : | | hash_flow.rb:429:15:429:25 | call to taint : | semmle.label | call to taint : | | hash_flow.rb:431:15:431:25 | call to taint : | semmle.label | call to taint : | +| hash_flow.rb:433:5:433:9 | hash2 [element :d] : | semmle.label | hash2 [element :d] : | +| hash_flow.rb:433:5:433:9 | hash2 [element :f] : | semmle.label | hash2 [element :f] : | | hash_flow.rb:434:15:434:25 | call to taint : | semmle.label | call to taint : | | hash_flow.rb:436:15:436:25 | call to taint : | semmle.label | call to taint : | +| hash_flow.rb:438:5:438:8 | hash [element :a] : | semmle.label | hash [element :a] : | +| hash_flow.rb:438:5:438:8 | hash [element :c] : | semmle.label | hash [element :c] : | +| hash_flow.rb:438:5:438:8 | hash [element :d] : | semmle.label | hash [element :d] : | +| hash_flow.rb:438:5:438:8 | hash [element :f] : | semmle.label | hash [element :f] : | | hash_flow.rb:438:12:438:16 | [post] hash1 [element :a] : | semmle.label | [post] hash1 [element :a] : | | hash_flow.rb:438:12:438:16 | [post] hash1 [element :c] : | semmle.label | [post] hash1 [element :c] : | | hash_flow.rb:438:12:438:16 | [post] hash1 [element :d] : | semmle.label | [post] hash1 [element :d] : | @@ -1096,19 +1375,25 @@ nodes | hash_flow.rb:455:10:455:20 | ( ... ) | semmle.label | ( ... ) | | hash_flow.rb:455:11:455:15 | hash1 [element :f] : | semmle.label | hash1 [element :f] : | | hash_flow.rb:455:11:455:19 | ...[...] : | semmle.label | ...[...] : | +| hash_flow.rb:461:5:461:8 | hash [element :a] : | semmle.label | hash [element :a] : | | hash_flow.rb:462:15:462:25 | call to taint : | semmle.label | call to taint : | +| hash_flow.rb:465:5:465:5 | b [element 1] : | semmle.label | b [element 1] : | | hash_flow.rb:465:9:465:12 | hash [element :a] : | semmle.label | hash [element :a] : | | hash_flow.rb:465:9:465:22 | call to rassoc [element 1] : | semmle.label | call to rassoc [element 1] : | | hash_flow.rb:467:10:467:10 | b [element 1] : | semmle.label | b [element 1] : | | hash_flow.rb:467:10:467:13 | ...[...] | semmle.label | ...[...] | +| hash_flow.rb:473:5:473:8 | hash [element :a] : | semmle.label | hash [element :a] : | | hash_flow.rb:474:15:474:25 | call to taint : | semmle.label | call to taint : | +| hash_flow.rb:477:5:477:5 | b [element :a] : | semmle.label | b [element :a] : | | hash_flow.rb:477:9:477:12 | hash [element :a] : | semmle.label | hash [element :a] : | | hash_flow.rb:477:9:481:7 | call to reject [element :a] : | semmle.label | call to reject [element :a] : | | hash_flow.rb:477:29:477:33 | value : | semmle.label | value : | | hash_flow.rb:479:14:479:18 | value | semmle.label | value | | hash_flow.rb:482:10:482:10 | b [element :a] : | semmle.label | b [element :a] : | | hash_flow.rb:482:10:482:14 | ...[...] | semmle.label | ...[...] | +| hash_flow.rb:488:5:488:8 | hash [element :a] : | semmle.label | hash [element :a] : | | hash_flow.rb:489:15:489:25 | call to taint : | semmle.label | call to taint : | +| hash_flow.rb:492:5:492:5 | b [element :a] : | semmle.label | b [element :a] : | | hash_flow.rb:492:9:492:12 | [post] hash [element :a] : | semmle.label | [post] hash [element :a] : | | hash_flow.rb:492:9:492:12 | hash [element :a] : | semmle.label | hash [element :a] : | | hash_flow.rb:492:9:496:7 | call to reject! [element :a] : | semmle.label | call to reject! [element :a] : | @@ -1118,6 +1403,8 @@ nodes | hash_flow.rb:497:10:497:14 | ...[...] | semmle.label | ...[...] | | hash_flow.rb:498:10:498:13 | hash [element :a] : | semmle.label | hash [element :a] : | | hash_flow.rb:498:10:498:17 | ...[...] | semmle.label | ...[...] | +| hash_flow.rb:504:5:504:8 | hash [element :a] : | semmle.label | hash [element :a] : | +| hash_flow.rb:504:5:504:8 | hash [element :c] : | semmle.label | hash [element :c] : | | hash_flow.rb:505:15:505:25 | call to taint : | semmle.label | call to taint : | | hash_flow.rb:507:15:507:25 | call to taint : | semmle.label | call to taint : | | hash_flow.rb:512:5:512:9 | [post] hash2 [element :a] : | semmle.label | [post] hash2 [element :a] : | @@ -1130,8 +1417,11 @@ nodes | hash_flow.rb:515:10:515:20 | ( ... ) | semmle.label | ( ... ) | | hash_flow.rb:515:11:515:15 | hash2 [element :c] : | semmle.label | hash2 [element :c] : | | hash_flow.rb:515:11:515:19 | ...[...] : | semmle.label | ...[...] : | +| hash_flow.rb:519:5:519:8 | hash [element :a] : | semmle.label | hash [element :a] : | +| hash_flow.rb:519:5:519:8 | hash [element :c] : | semmle.label | hash [element :c] : | | hash_flow.rb:520:15:520:25 | call to taint : | semmle.label | call to taint : | | hash_flow.rb:522:15:522:25 | call to taint : | semmle.label | call to taint : | +| hash_flow.rb:524:5:524:5 | b [element :a] : | semmle.label | b [element :a] : | | hash_flow.rb:524:9:524:12 | hash [element :a] : | semmle.label | hash [element :a] : | | hash_flow.rb:524:9:524:12 | hash [element :c] : | semmle.label | hash [element :c] : | | hash_flow.rb:524:9:528:7 | call to select [element :a] : | semmle.label | call to select [element :a] : | @@ -1140,6 +1430,8 @@ nodes | hash_flow.rb:529:10:529:16 | ( ... ) | semmle.label | ( ... ) | | hash_flow.rb:529:11:529:11 | b [element :a] : | semmle.label | b [element :a] : | | hash_flow.rb:529:11:529:15 | ...[...] : | semmle.label | ...[...] : | +| hash_flow.rb:535:5:535:8 | hash [element :a] : | semmle.label | hash [element :a] : | +| hash_flow.rb:535:5:535:8 | hash [element :c] : | semmle.label | hash [element :c] : | | hash_flow.rb:536:15:536:25 | call to taint : | semmle.label | call to taint : | | hash_flow.rb:538:15:538:25 | call to taint : | semmle.label | call to taint : | | hash_flow.rb:540:5:540:8 | [post] hash [element :a] : | semmle.label | [post] hash [element :a] : | @@ -1150,8 +1442,11 @@ nodes | hash_flow.rb:545:10:545:19 | ( ... ) | semmle.label | ( ... ) | | hash_flow.rb:545:11:545:14 | hash [element :a] : | semmle.label | hash [element :a] : | | hash_flow.rb:545:11:545:18 | ...[...] : | semmle.label | ...[...] : | +| hash_flow.rb:551:5:551:8 | hash [element :a] : | semmle.label | hash [element :a] : | +| hash_flow.rb:551:5:551:8 | hash [element :c] : | semmle.label | hash [element :c] : | | hash_flow.rb:552:15:552:25 | call to taint : | semmle.label | call to taint : | | hash_flow.rb:554:15:554:25 | call to taint : | semmle.label | call to taint : | +| hash_flow.rb:556:5:556:5 | b [element 1] : | semmle.label | b [element 1] : | | hash_flow.rb:556:9:556:12 | [post] hash [element :a] : | semmle.label | [post] hash [element :a] : | | hash_flow.rb:556:9:556:12 | hash [element :a] : | semmle.label | hash [element :a] : | | hash_flow.rb:556:9:556:12 | hash [element :c] : | semmle.label | hash [element :c] : | @@ -1162,13 +1457,18 @@ nodes | hash_flow.rb:559:10:559:15 | ( ... ) | semmle.label | ( ... ) | | hash_flow.rb:559:11:559:11 | b [element 1] : | semmle.label | b [element 1] : | | hash_flow.rb:559:11:559:14 | ...[...] : | semmle.label | ...[...] : | +| hash_flow.rb:565:5:565:8 | hash [element :a] : | semmle.label | hash [element :a] : | +| hash_flow.rb:565:5:565:8 | hash [element :c] : | semmle.label | hash [element :c] : | | hash_flow.rb:566:15:566:25 | call to taint : | semmle.label | call to taint : | | hash_flow.rb:568:15:568:25 | call to taint : | semmle.label | call to taint : | +| hash_flow.rb:570:5:570:5 | b [element :a] : | semmle.label | b [element :a] : | | hash_flow.rb:570:9:570:12 | hash [element :a] : | semmle.label | hash [element :a] : | | hash_flow.rb:570:9:570:26 | call to slice [element :a] : | semmle.label | call to slice [element :a] : | | hash_flow.rb:571:10:571:16 | ( ... ) | semmle.label | ( ... ) | | hash_flow.rb:571:11:571:11 | b [element :a] : | semmle.label | b [element :a] : | | hash_flow.rb:571:11:571:15 | ...[...] : | semmle.label | ...[...] : | +| hash_flow.rb:575:5:575:5 | c [element :a] : | semmle.label | c [element :a] : | +| hash_flow.rb:575:5:575:5 | c [element :c] : | semmle.label | c [element :c] : | | hash_flow.rb:575:9:575:12 | hash [element :a] : | semmle.label | hash [element :a] : | | hash_flow.rb:575:9:575:12 | hash [element :c] : | semmle.label | hash [element :c] : | | hash_flow.rb:575:9:575:25 | call to slice [element :a] : | semmle.label | call to slice [element :a] : | @@ -1179,8 +1479,11 @@ nodes | hash_flow.rb:578:10:578:16 | ( ... ) | semmle.label | ( ... ) | | hash_flow.rb:578:11:578:11 | c [element :c] : | semmle.label | c [element :c] : | | hash_flow.rb:578:11:578:15 | ...[...] : | semmle.label | ...[...] : | +| hash_flow.rb:584:5:584:8 | hash [element :a] : | semmle.label | hash [element :a] : | +| hash_flow.rb:584:5:584:8 | hash [element :c] : | semmle.label | hash [element :c] : | | hash_flow.rb:585:15:585:25 | call to taint : | semmle.label | call to taint : | | hash_flow.rb:587:15:587:25 | call to taint : | semmle.label | call to taint : | +| hash_flow.rb:589:5:589:5 | a [element, element 1] : | semmle.label | a [element, element 1] : | | hash_flow.rb:589:9:589:12 | hash [element :a] : | semmle.label | hash [element :a] : | | hash_flow.rb:589:9:589:12 | hash [element :c] : | semmle.label | hash [element :c] : | | hash_flow.rb:589:9:589:17 | call to to_a [element, element 1] : | semmle.label | call to to_a [element, element 1] : | @@ -1188,8 +1491,12 @@ nodes | hash_flow.rb:591:11:591:11 | a [element, element 1] : | semmle.label | a [element, element 1] : | | hash_flow.rb:591:11:591:14 | ...[...] [element 1] : | semmle.label | ...[...] [element 1] : | | hash_flow.rb:591:11:591:17 | ...[...] : | semmle.label | ...[...] : | +| hash_flow.rb:597:5:597:8 | hash [element :a] : | semmle.label | hash [element :a] : | +| hash_flow.rb:597:5:597:8 | hash [element :c] : | semmle.label | hash [element :c] : | | hash_flow.rb:598:15:598:25 | call to taint : | semmle.label | call to taint : | | hash_flow.rb:600:15:600:25 | call to taint : | semmle.label | call to taint : | +| hash_flow.rb:602:5:602:5 | a [element :a] : | semmle.label | a [element :a] : | +| hash_flow.rb:602:5:602:5 | a [element :c] : | semmle.label | a [element :c] : | | hash_flow.rb:602:9:602:12 | hash [element :a] : | semmle.label | hash [element :a] : | | hash_flow.rb:602:9:602:12 | hash [element :c] : | semmle.label | hash [element :c] : | | hash_flow.rb:602:9:602:17 | call to to_h [element :a] : | semmle.label | call to to_h [element :a] : | @@ -1200,6 +1507,7 @@ nodes | hash_flow.rb:605:10:605:16 | ( ... ) | semmle.label | ( ... ) | | hash_flow.rb:605:11:605:11 | a [element :c] : | semmle.label | a [element :c] : | | hash_flow.rb:605:11:605:15 | ...[...] : | semmle.label | ...[...] : | +| hash_flow.rb:607:5:607:5 | b [element] : | semmle.label | b [element] : | | hash_flow.rb:607:9:607:12 | hash [element :a] : | semmle.label | hash [element :a] : | | hash_flow.rb:607:9:607:12 | hash [element :c] : | semmle.label | hash [element :c] : | | hash_flow.rb:607:9:611:7 | call to to_h [element] : | semmle.label | call to to_h [element] : | @@ -1209,8 +1517,11 @@ nodes | hash_flow.rb:612:10:612:16 | ( ... ) | semmle.label | ( ... ) | | hash_flow.rb:612:11:612:11 | b [element] : | semmle.label | b [element] : | | hash_flow.rb:612:11:612:15 | ...[...] : | semmle.label | ...[...] : | +| hash_flow.rb:618:5:618:8 | hash [element :a] : | semmle.label | hash [element :a] : | +| hash_flow.rb:618:5:618:8 | hash [element :c] : | semmle.label | hash [element :c] : | | hash_flow.rb:619:15:619:25 | call to taint : | semmle.label | call to taint : | | hash_flow.rb:621:15:621:25 | call to taint : | semmle.label | call to taint : | +| hash_flow.rb:623:5:623:5 | a [element] : | semmle.label | a [element] : | | hash_flow.rb:623:9:623:12 | hash [element :a] : | semmle.label | hash [element :a] : | | hash_flow.rb:623:9:623:12 | hash [element :c] : | semmle.label | hash [element :c] : | | hash_flow.rb:623:9:623:45 | call to transform_keys [element] : | semmle.label | call to transform_keys [element] : | @@ -1223,6 +1534,8 @@ nodes | hash_flow.rb:626:10:626:17 | ( ... ) | semmle.label | ( ... ) | | hash_flow.rb:626:11:626:11 | a [element] : | semmle.label | a [element] : | | hash_flow.rb:626:11:626:16 | ...[...] : | semmle.label | ...[...] : | +| hash_flow.rb:632:5:632:8 | hash [element :a] : | semmle.label | hash [element :a] : | +| hash_flow.rb:632:5:632:8 | hash [element :c] : | semmle.label | hash [element :c] : | | hash_flow.rb:633:15:633:25 | call to taint : | semmle.label | call to taint : | | hash_flow.rb:635:15:635:25 | call to taint : | semmle.label | call to taint : | | hash_flow.rb:637:5:637:8 | [post] hash [element] : | semmle.label | [post] hash [element] : | @@ -1240,8 +1553,11 @@ nodes | hash_flow.rb:642:10:642:20 | ( ... ) | semmle.label | ( ... ) | | hash_flow.rb:642:11:642:14 | hash [element] : | semmle.label | hash [element] : | | hash_flow.rb:642:11:642:19 | ...[...] : | semmle.label | ...[...] : | +| hash_flow.rb:648:5:648:8 | hash [element :a] : | semmle.label | hash [element :a] : | +| hash_flow.rb:648:5:648:8 | hash [element :c] : | semmle.label | hash [element :c] : | | hash_flow.rb:649:15:649:25 | call to taint : | semmle.label | call to taint : | | hash_flow.rb:651:15:651:25 | call to taint : | semmle.label | call to taint : | +| hash_flow.rb:653:5:653:5 | b [element] : | semmle.label | b [element] : | | hash_flow.rb:653:9:653:12 | hash [element :a] : | semmle.label | hash [element :a] : | | hash_flow.rb:653:9:653:12 | hash [element :c] : | semmle.label | hash [element :c] : | | hash_flow.rb:653:9:656:7 | call to transform_values [element] : | semmle.label | call to transform_values [element] : | @@ -1254,6 +1570,8 @@ nodes | hash_flow.rb:658:10:658:16 | ( ... ) | semmle.label | ( ... ) | | hash_flow.rb:658:11:658:11 | b [element] : | semmle.label | b [element] : | | hash_flow.rb:658:11:658:15 | ...[...] : | semmle.label | ...[...] : | +| hash_flow.rb:664:5:664:8 | hash [element :a] : | semmle.label | hash [element :a] : | +| hash_flow.rb:664:5:664:8 | hash [element :c] : | semmle.label | hash [element :c] : | | hash_flow.rb:665:15:665:25 | call to taint : | semmle.label | call to taint : | | hash_flow.rb:667:15:667:25 | call to taint : | semmle.label | call to taint : | | hash_flow.rb:669:5:669:8 | [post] hash [element] : | semmle.label | [post] hash [element] : | @@ -1265,10 +1583,18 @@ nodes | hash_flow.rb:673:10:673:19 | ( ... ) | semmle.label | ( ... ) | | hash_flow.rb:673:11:673:14 | hash [element] : | semmle.label | hash [element] : | | hash_flow.rb:673:11:673:18 | ...[...] : | semmle.label | ...[...] : | +| hash_flow.rb:679:5:679:9 | hash1 [element :a] : | semmle.label | hash1 [element :a] : | +| hash_flow.rb:679:5:679:9 | hash1 [element :c] : | semmle.label | hash1 [element :c] : | | hash_flow.rb:680:15:680:25 | call to taint : | semmle.label | call to taint : | | hash_flow.rb:682:15:682:25 | call to taint : | semmle.label | call to taint : | +| hash_flow.rb:684:5:684:9 | hash2 [element :d] : | semmle.label | hash2 [element :d] : | +| hash_flow.rb:684:5:684:9 | hash2 [element :f] : | semmle.label | hash2 [element :f] : | | hash_flow.rb:685:15:685:25 | call to taint : | semmle.label | call to taint : | | hash_flow.rb:687:15:687:25 | call to taint : | semmle.label | call to taint : | +| hash_flow.rb:689:5:689:8 | hash [element :a] : | semmle.label | hash [element :a] : | +| hash_flow.rb:689:5:689:8 | hash [element :c] : | semmle.label | hash [element :c] : | +| hash_flow.rb:689:5:689:8 | hash [element :d] : | semmle.label | hash [element :d] : | +| hash_flow.rb:689:5:689:8 | hash [element :f] : | semmle.label | hash [element :f] : | | hash_flow.rb:689:12:689:16 | [post] hash1 [element :a] : | semmle.label | [post] hash1 [element :a] : | | hash_flow.rb:689:12:689:16 | [post] hash1 [element :c] : | semmle.label | [post] hash1 [element :c] : | | hash_flow.rb:689:12:689:16 | [post] hash1 [element :d] : | semmle.label | [post] hash1 [element :d] : | @@ -1309,29 +1635,45 @@ nodes | hash_flow.rb:706:10:706:20 | ( ... ) | semmle.label | ( ... ) | | hash_flow.rb:706:11:706:15 | hash1 [element :f] : | semmle.label | hash1 [element :f] : | | hash_flow.rb:706:11:706:19 | ...[...] : | semmle.label | ...[...] : | +| hash_flow.rb:712:5:712:8 | hash [element :a] : | semmle.label | hash [element :a] : | +| hash_flow.rb:712:5:712:8 | hash [element :c] : | semmle.label | hash [element :c] : | | hash_flow.rb:713:15:713:25 | call to taint : | semmle.label | call to taint : | | hash_flow.rb:715:15:715:25 | call to taint : | semmle.label | call to taint : | +| hash_flow.rb:717:5:717:5 | a [element] : | semmle.label | a [element] : | | hash_flow.rb:717:9:717:12 | hash [element :a] : | semmle.label | hash [element :a] : | | hash_flow.rb:717:9:717:12 | hash [element :c] : | semmle.label | hash [element :c] : | | hash_flow.rb:717:9:717:19 | call to values [element] : | semmle.label | call to values [element] : | | hash_flow.rb:718:10:718:15 | ( ... ) | semmle.label | ( ... ) | | hash_flow.rb:718:11:718:11 | a [element] : | semmle.label | a [element] : | | hash_flow.rb:718:11:718:14 | ...[...] : | semmle.label | ...[...] : | +| hash_flow.rb:724:5:724:8 | hash [element :a] : | semmle.label | hash [element :a] : | +| hash_flow.rb:724:5:724:8 | hash [element :c] : | semmle.label | hash [element :c] : | | hash_flow.rb:725:15:725:25 | call to taint : | semmle.label | call to taint : | | hash_flow.rb:727:15:727:25 | call to taint : | semmle.label | call to taint : | +| hash_flow.rb:729:5:729:5 | b [element 0] : | semmle.label | b [element 0] : | | hash_flow.rb:729:9:729:12 | hash [element :a] : | semmle.label | hash [element :a] : | | hash_flow.rb:729:9:729:26 | call to values_at [element 0] : | semmle.label | call to values_at [element 0] : | | hash_flow.rb:730:10:730:10 | b [element 0] : | semmle.label | b [element 0] : | | hash_flow.rb:730:10:730:13 | ...[...] | semmle.label | ...[...] | +| hash_flow.rb:731:5:731:5 | b [element] : | semmle.label | b [element] : | | hash_flow.rb:731:9:731:12 | hash [element :a] : | semmle.label | hash [element :a] : | | hash_flow.rb:731:9:731:12 | hash [element :c] : | semmle.label | hash [element :c] : | | hash_flow.rb:731:9:731:31 | call to fetch_values [element] : | semmle.label | call to fetch_values [element] : | | hash_flow.rb:732:10:732:10 | b [element] : | semmle.label | b [element] : | | hash_flow.rb:732:10:732:13 | ...[...] | semmle.label | ...[...] | +| hash_flow.rb:738:5:738:9 | hash1 [element :a] : | semmle.label | hash1 [element :a] : | +| hash_flow.rb:738:5:738:9 | hash1 [element :c] : | semmle.label | hash1 [element :c] : | | hash_flow.rb:739:15:739:25 | call to taint : | semmle.label | call to taint : | | hash_flow.rb:741:15:741:25 | call to taint : | semmle.label | call to taint : | +| hash_flow.rb:743:5:743:9 | hash2 [element :d] : | semmle.label | hash2 [element :d] : | +| hash_flow.rb:743:5:743:9 | hash2 [element :f] : | semmle.label | hash2 [element :f] : | | hash_flow.rb:744:15:744:25 | call to taint : | semmle.label | call to taint : | | hash_flow.rb:746:15:746:25 | call to taint : | semmle.label | call to taint : | +| hash_flow.rb:748:5:748:8 | hash [element :a] : | semmle.label | hash [element :a] : | +| hash_flow.rb:748:5:748:8 | hash [element :c] : | semmle.label | hash [element :c] : | +| hash_flow.rb:748:5:748:8 | hash [element :d] : | semmle.label | hash [element :d] : | +| hash_flow.rb:748:5:748:8 | hash [element :f] : | semmle.label | hash [element :f] : | +| hash_flow.rb:748:5:748:8 | hash [element :g] : | semmle.label | hash [element :g] : | | hash_flow.rb:748:14:748:20 | ** ... [element :a] : | semmle.label | ** ... [element :a] : | | hash_flow.rb:748:14:748:20 | ** ... [element :c] : | semmle.label | ** ... [element :c] : | | hash_flow.rb:748:16:748:20 | hash1 [element :a] : | semmle.label | hash1 [element :a] : | @@ -1351,6 +1693,9 @@ nodes | hash_flow.rb:754:10:754:17 | ...[...] | semmle.label | ...[...] | | hash_flow.rb:755:10:755:13 | hash [element :g] : | semmle.label | hash [element :g] : | | hash_flow.rb:755:10:755:17 | ...[...] | semmle.label | ...[...] | +| hash_flow.rb:762:5:762:8 | hash [element :a] : | semmle.label | hash [element :a] : | +| hash_flow.rb:762:5:762:8 | hash [element :c] : | semmle.label | hash [element :c] : | +| hash_flow.rb:762:5:762:8 | hash [element :d] : | semmle.label | hash [element :d] : | | hash_flow.rb:763:15:763:25 | call to taint : | semmle.label | call to taint : | | hash_flow.rb:765:15:765:25 | call to taint : | semmle.label | call to taint : | | hash_flow.rb:766:15:766:25 | call to taint : | semmle.label | call to taint : | @@ -1360,6 +1705,7 @@ nodes | hash_flow.rb:771:10:771:17 | ...[...] | semmle.label | ...[...] | | hash_flow.rb:772:10:772:13 | hash [element :d] : | semmle.label | hash [element :d] : | | hash_flow.rb:772:10:772:17 | ...[...] | semmle.label | ...[...] | +| hash_flow.rb:774:5:774:5 | x [element :c] : | semmle.label | x [element :c] : | | hash_flow.rb:774:9:774:12 | [post] hash [element :c] : | semmle.label | [post] hash [element :c] : | | hash_flow.rb:774:9:774:12 | hash [element :c] : | semmle.label | hash [element :c] : | | hash_flow.rb:774:9:774:31 | call to except! [element :c] : | semmle.label | call to except! [element :c] : | @@ -1367,10 +1713,18 @@ nodes | hash_flow.rb:778:10:778:14 | ...[...] | semmle.label | ...[...] | | hash_flow.rb:783:10:783:13 | hash [element :c] : | semmle.label | hash [element :c] : | | hash_flow.rb:783:10:783:17 | ...[...] | semmle.label | ...[...] | +| hash_flow.rb:790:5:790:9 | hash1 [element :a] : | semmle.label | hash1 [element :a] : | +| hash_flow.rb:790:5:790:9 | hash1 [element :c] : | semmle.label | hash1 [element :c] : | | hash_flow.rb:791:15:791:25 | call to taint : | semmle.label | call to taint : | | hash_flow.rb:793:15:793:25 | call to taint : | semmle.label | call to taint : | +| hash_flow.rb:795:5:795:9 | hash2 [element :d] : | semmle.label | hash2 [element :d] : | +| hash_flow.rb:795:5:795:9 | hash2 [element :f] : | semmle.label | hash2 [element :f] : | | hash_flow.rb:796:15:796:25 | call to taint : | semmle.label | call to taint : | | hash_flow.rb:798:15:798:25 | call to taint : | semmle.label | call to taint : | +| hash_flow.rb:800:5:800:8 | hash [element :a] : | semmle.label | hash [element :a] : | +| hash_flow.rb:800:5:800:8 | hash [element :c] : | semmle.label | hash [element :c] : | +| hash_flow.rb:800:5:800:8 | hash [element :d] : | semmle.label | hash [element :d] : | +| hash_flow.rb:800:5:800:8 | hash [element :f] : | semmle.label | hash [element :f] : | | hash_flow.rb:800:12:800:16 | hash1 [element :a] : | semmle.label | hash1 [element :a] : | | hash_flow.rb:800:12:800:16 | hash1 [element :c] : | semmle.label | hash1 [element :c] : | | hash_flow.rb:800:12:804:7 | call to deep_merge [element :a] : | semmle.label | call to deep_merge [element :a] : | @@ -1395,10 +1749,18 @@ nodes | hash_flow.rb:810:10:810:19 | ( ... ) | semmle.label | ( ... ) | | hash_flow.rb:810:11:810:14 | hash [element :f] : | semmle.label | hash [element :f] : | | hash_flow.rb:810:11:810:18 | ...[...] : | semmle.label | ...[...] : | +| hash_flow.rb:816:5:816:9 | hash1 [element :a] : | semmle.label | hash1 [element :a] : | +| hash_flow.rb:816:5:816:9 | hash1 [element :c] : | semmle.label | hash1 [element :c] : | | hash_flow.rb:817:15:817:25 | call to taint : | semmle.label | call to taint : | | hash_flow.rb:819:15:819:25 | call to taint : | semmle.label | call to taint : | +| hash_flow.rb:821:5:821:9 | hash2 [element :d] : | semmle.label | hash2 [element :d] : | +| hash_flow.rb:821:5:821:9 | hash2 [element :f] : | semmle.label | hash2 [element :f] : | | hash_flow.rb:822:15:822:25 | call to taint : | semmle.label | call to taint : | | hash_flow.rb:824:15:824:25 | call to taint : | semmle.label | call to taint : | +| hash_flow.rb:826:5:826:8 | hash [element :a] : | semmle.label | hash [element :a] : | +| hash_flow.rb:826:5:826:8 | hash [element :c] : | semmle.label | hash [element :c] : | +| hash_flow.rb:826:5:826:8 | hash [element :d] : | semmle.label | hash [element :d] : | +| hash_flow.rb:826:5:826:8 | hash [element :f] : | semmle.label | hash [element :f] : | | hash_flow.rb:826:12:826:16 | [post] hash1 [element :a] : | semmle.label | [post] hash1 [element :a] : | | hash_flow.rb:826:12:826:16 | [post] hash1 [element :c] : | semmle.label | [post] hash1 [element :c] : | | hash_flow.rb:826:12:826:16 | [post] hash1 [element :d] : | semmle.label | [post] hash1 [element :d] : | @@ -1439,10 +1801,18 @@ nodes | hash_flow.rb:843:10:843:20 | ( ... ) | semmle.label | ( ... ) | | hash_flow.rb:843:11:843:15 | hash1 [element :f] : | semmle.label | hash1 [element :f] : | | hash_flow.rb:843:11:843:19 | ...[...] : | semmle.label | ...[...] : | +| hash_flow.rb:849:5:849:9 | hash1 [element :a] : | semmle.label | hash1 [element :a] : | +| hash_flow.rb:849:5:849:9 | hash1 [element :c] : | semmle.label | hash1 [element :c] : | | hash_flow.rb:850:12:850:22 | call to taint : | semmle.label | call to taint : | | hash_flow.rb:852:12:852:22 | call to taint : | semmle.label | call to taint : | +| hash_flow.rb:854:5:854:9 | hash2 [element :d] : | semmle.label | hash2 [element :d] : | +| hash_flow.rb:854:5:854:9 | hash2 [element :f] : | semmle.label | hash2 [element :f] : | | hash_flow.rb:855:12:855:22 | call to taint : | semmle.label | call to taint : | | hash_flow.rb:857:12:857:22 | call to taint : | semmle.label | call to taint : | +| hash_flow.rb:860:5:860:9 | hash3 [element :a] : | semmle.label | hash3 [element :a] : | +| hash_flow.rb:860:5:860:9 | hash3 [element :c] : | semmle.label | hash3 [element :c] : | +| hash_flow.rb:860:5:860:9 | hash3 [element :d] : | semmle.label | hash3 [element :d] : | +| hash_flow.rb:860:5:860:9 | hash3 [element :f] : | semmle.label | hash3 [element :f] : | | hash_flow.rb:860:13:860:17 | hash1 [element :a] : | semmle.label | hash1 [element :a] : | | hash_flow.rb:860:13:860:17 | hash1 [element :c] : | semmle.label | hash1 [element :c] : | | hash_flow.rb:860:13:860:38 | call to reverse_merge [element :a] : | semmle.label | call to reverse_merge [element :a] : | @@ -1463,6 +1833,10 @@ nodes | hash_flow.rb:866:10:866:20 | ( ... ) | semmle.label | ( ... ) | | hash_flow.rb:866:11:866:15 | hash3 [element :f] : | semmle.label | hash3 [element :f] : | | hash_flow.rb:866:11:866:19 | ...[...] : | semmle.label | ...[...] : | +| hash_flow.rb:869:5:869:9 | hash4 [element :a] : | semmle.label | hash4 [element :a] : | +| hash_flow.rb:869:5:869:9 | hash4 [element :c] : | semmle.label | hash4 [element :c] : | +| hash_flow.rb:869:5:869:9 | hash4 [element :d] : | semmle.label | hash4 [element :d] : | +| hash_flow.rb:869:5:869:9 | hash4 [element :f] : | semmle.label | hash4 [element :f] : | | hash_flow.rb:869:13:869:17 | hash1 [element :a] : | semmle.label | hash1 [element :a] : | | hash_flow.rb:869:13:869:17 | hash1 [element :c] : | semmle.label | hash1 [element :c] : | | hash_flow.rb:869:13:869:38 | call to with_defaults [element :a] : | semmle.label | call to with_defaults [element :a] : | @@ -1483,10 +1857,18 @@ nodes | hash_flow.rb:875:10:875:20 | ( ... ) | semmle.label | ( ... ) | | hash_flow.rb:875:11:875:15 | hash4 [element :f] : | semmle.label | hash4 [element :f] : | | hash_flow.rb:875:11:875:19 | ...[...] : | semmle.label | ...[...] : | +| hash_flow.rb:881:5:881:9 | hash1 [element :a] : | semmle.label | hash1 [element :a] : | +| hash_flow.rb:881:5:881:9 | hash1 [element :c] : | semmle.label | hash1 [element :c] : | | hash_flow.rb:882:12:882:22 | call to taint : | semmle.label | call to taint : | | hash_flow.rb:884:12:884:22 | call to taint : | semmle.label | call to taint : | +| hash_flow.rb:886:5:886:9 | hash2 [element :d] : | semmle.label | hash2 [element :d] : | +| hash_flow.rb:886:5:886:9 | hash2 [element :f] : | semmle.label | hash2 [element :f] : | | hash_flow.rb:887:12:887:22 | call to taint : | semmle.label | call to taint : | | hash_flow.rb:889:12:889:22 | call to taint : | semmle.label | call to taint : | +| hash_flow.rb:892:5:892:8 | hash [element :a] : | semmle.label | hash [element :a] : | +| hash_flow.rb:892:5:892:8 | hash [element :c] : | semmle.label | hash [element :c] : | +| hash_flow.rb:892:5:892:8 | hash [element :d] : | semmle.label | hash [element :d] : | +| hash_flow.rb:892:5:892:8 | hash [element :f] : | semmle.label | hash [element :f] : | | hash_flow.rb:892:12:892:16 | [post] hash1 [element :a] : | semmle.label | [post] hash1 [element :a] : | | hash_flow.rb:892:12:892:16 | [post] hash1 [element :c] : | semmle.label | [post] hash1 [element :c] : | | hash_flow.rb:892:12:892:16 | [post] hash1 [element :d] : | semmle.label | [post] hash1 [element :d] : | @@ -1523,10 +1905,18 @@ nodes | hash_flow.rb:905:10:905:20 | ( ... ) | semmle.label | ( ... ) | | hash_flow.rb:905:11:905:15 | hash1 [element :f] : | semmle.label | hash1 [element :f] : | | hash_flow.rb:905:11:905:19 | ...[...] : | semmle.label | ...[...] : | +| hash_flow.rb:911:5:911:9 | hash1 [element :a] : | semmle.label | hash1 [element :a] : | +| hash_flow.rb:911:5:911:9 | hash1 [element :c] : | semmle.label | hash1 [element :c] : | | hash_flow.rb:912:12:912:22 | call to taint : | semmle.label | call to taint : | | hash_flow.rb:914:12:914:22 | call to taint : | semmle.label | call to taint : | +| hash_flow.rb:916:5:916:9 | hash2 [element :d] : | semmle.label | hash2 [element :d] : | +| hash_flow.rb:916:5:916:9 | hash2 [element :f] : | semmle.label | hash2 [element :f] : | | hash_flow.rb:917:12:917:22 | call to taint : | semmle.label | call to taint : | | hash_flow.rb:919:12:919:22 | call to taint : | semmle.label | call to taint : | +| hash_flow.rb:922:5:922:8 | hash [element :a] : | semmle.label | hash [element :a] : | +| hash_flow.rb:922:5:922:8 | hash [element :c] : | semmle.label | hash [element :c] : | +| hash_flow.rb:922:5:922:8 | hash [element :d] : | semmle.label | hash [element :d] : | +| hash_flow.rb:922:5:922:8 | hash [element :f] : | semmle.label | hash [element :f] : | | hash_flow.rb:922:12:922:16 | [post] hash1 [element :a] : | semmle.label | [post] hash1 [element :a] : | | hash_flow.rb:922:12:922:16 | [post] hash1 [element :c] : | semmle.label | [post] hash1 [element :c] : | | hash_flow.rb:922:12:922:16 | [post] hash1 [element :d] : | semmle.label | [post] hash1 [element :d] : | @@ -1563,10 +1953,18 @@ nodes | hash_flow.rb:935:10:935:20 | ( ... ) | semmle.label | ( ... ) | | hash_flow.rb:935:11:935:15 | hash1 [element :f] : | semmle.label | hash1 [element :f] : | | hash_flow.rb:935:11:935:19 | ...[...] : | semmle.label | ...[...] : | +| hash_flow.rb:941:5:941:9 | hash1 [element :a] : | semmle.label | hash1 [element :a] : | +| hash_flow.rb:941:5:941:9 | hash1 [element :c] : | semmle.label | hash1 [element :c] : | | hash_flow.rb:942:12:942:22 | call to taint : | semmle.label | call to taint : | | hash_flow.rb:944:12:944:22 | call to taint : | semmle.label | call to taint : | +| hash_flow.rb:946:5:946:9 | hash2 [element :d] : | semmle.label | hash2 [element :d] : | +| hash_flow.rb:946:5:946:9 | hash2 [element :f] : | semmle.label | hash2 [element :f] : | | hash_flow.rb:947:12:947:22 | call to taint : | semmle.label | call to taint : | | hash_flow.rb:949:12:949:22 | call to taint : | semmle.label | call to taint : | +| hash_flow.rb:952:5:952:8 | hash [element :a] : | semmle.label | hash [element :a] : | +| hash_flow.rb:952:5:952:8 | hash [element :c] : | semmle.label | hash [element :c] : | +| hash_flow.rb:952:5:952:8 | hash [element :d] : | semmle.label | hash [element :d] : | +| hash_flow.rb:952:5:952:8 | hash [element :f] : | semmle.label | hash [element :f] : | | hash_flow.rb:952:12:952:16 | [post] hash1 [element :a] : | semmle.label | [post] hash1 [element :a] : | | hash_flow.rb:952:12:952:16 | [post] hash1 [element :c] : | semmle.label | [post] hash1 [element :c] : | | hash_flow.rb:952:12:952:16 | [post] hash1 [element :d] : | semmle.label | [post] hash1 [element :d] : | diff --git a/ruby/ql/test/library-tests/dataflow/local/DataflowStep.expected b/ruby/ql/test/library-tests/dataflow/local/DataflowStep.expected index 2e1948ff2d7..60f62362f75 100644 --- a/ruby/ql/test/library-tests/dataflow/local/DataflowStep.expected +++ b/ruby/ql/test/library-tests/dataflow/local/DataflowStep.expected @@ -1,107 +1,107 @@ | UseUseExplosion.rb:18:5:22:7 | self (m) | UseUseExplosion.rb:20:13:20:17 | self | | UseUseExplosion.rb:18:5:22:7 | self in m | UseUseExplosion.rb:18:5:22:7 | self (m) | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:2081:20:2116 | SSA phi read(x) | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:2111:20:2111 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:2127:20:2127 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:2143:20:2143 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:2159:20:2159 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:2175:20:2175 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:2191:20:2191 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:2207:20:2207 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:2223:20:2223 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:2239:20:2239 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:2255:20:2255 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:2271:20:2271 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:2287:20:2287 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:2303:20:2303 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:2319:20:2319 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:2335:20:2335 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:2351:20:2351 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:2367:20:2367 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:2383:20:2383 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:2399:20:2399 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:2415:20:2415 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:2431:20:2431 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:2447:20:2447 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:2463:20:2463 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:2479:20:2479 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:2495:20:2495 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:2511:20:2511 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:2527:20:2527 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:2543:20:2543 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:2559:20:2559 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:2575:20:2575 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:2591:20:2591 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:2607:20:2607 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:2623:20:2623 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:2639:20:2639 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:2655:20:2655 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:2671:20:2671 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:2687:20:2687 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:2703:20:2703 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:2719:20:2719 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:2735:20:2735 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:2751:20:2751 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:2767:20:2767 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:2783:20:2783 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:2799:20:2799 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:2815:20:2815 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:2831:20:2831 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:2847:20:2847 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:2863:20:2863 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:2879:20:2879 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:2895:20:2895 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:2911:20:2911 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:2927:20:2927 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:2943:20:2943 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:2959:20:2959 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:2975:20:2975 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:2991:20:2991 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:3007:20:3007 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:3023:20:3023 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:3039:20:3039 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:3055:20:3055 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:3071:20:3071 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:3087:20:3087 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:3103:20:3103 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:3119:20:3119 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:3135:20:3135 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:3151:20:3151 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:3167:20:3167 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:3183:20:3183 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:3199:20:3199 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:3215:20:3215 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:3231:20:3231 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:3247:20:3247 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:3263:20:3263 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:3279:20:3279 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:3295:20:3295 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:3311:20:3311 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:3327:20:3327 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:3343:20:3343 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:3359:20:3359 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:3375:20:3375 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:3391:20:3391 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:3407:20:3407 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:3423:20:3423 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:3439:20:3439 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:3455:20:3455 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:3471:20:3471 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:3487:20:3487 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:3503:20:3503 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:3519:20:3519 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:3535:20:3535 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:3551:20:3551 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:3567:20:3567 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:3583:20:3583 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:3599:20:3599 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:3615:20:3615 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:3631:20:3631 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:3647:20:3647 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:3663:20:3663 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:3679:20:3679 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:3695:20:3695 | x | -| UseUseExplosion.rb:19:13:19:13 | 0 | UseUseExplosion.rb:19:9:19:13 | ... = ... | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:2081:20:2116 | SSA phi read(x) | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:2111:20:2111 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:2127:20:2127 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:2143:20:2143 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:2159:20:2159 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:2175:20:2175 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:2191:20:2191 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:2207:20:2207 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:2223:20:2223 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:2239:20:2239 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:2255:20:2255 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:2271:20:2271 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:2287:20:2287 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:2303:20:2303 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:2319:20:2319 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:2335:20:2335 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:2351:20:2351 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:2367:20:2367 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:2383:20:2383 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:2399:20:2399 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:2415:20:2415 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:2431:20:2431 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:2447:20:2447 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:2463:20:2463 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:2479:20:2479 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:2495:20:2495 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:2511:20:2511 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:2527:20:2527 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:2543:20:2543 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:2559:20:2559 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:2575:20:2575 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:2591:20:2591 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:2607:20:2607 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:2623:20:2623 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:2639:20:2639 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:2655:20:2655 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:2671:20:2671 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:2687:20:2687 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:2703:20:2703 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:2719:20:2719 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:2735:20:2735 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:2751:20:2751 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:2767:20:2767 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:2783:20:2783 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:2799:20:2799 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:2815:20:2815 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:2831:20:2831 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:2847:20:2847 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:2863:20:2863 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:2879:20:2879 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:2895:20:2895 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:2911:20:2911 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:2927:20:2927 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:2943:20:2943 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:2959:20:2959 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:2975:20:2975 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:2991:20:2991 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:3007:20:3007 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:3023:20:3023 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:3039:20:3039 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:3055:20:3055 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:3071:20:3071 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:3087:20:3087 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:3103:20:3103 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:3119:20:3119 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:3135:20:3135 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:3151:20:3151 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:3167:20:3167 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:3183:20:3183 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:3199:20:3199 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:3215:20:3215 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:3231:20:3231 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:3247:20:3247 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:3263:20:3263 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:3279:20:3279 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:3295:20:3295 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:3311:20:3311 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:3327:20:3327 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:3343:20:3343 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:3359:20:3359 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:3375:20:3375 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:3391:20:3391 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:3407:20:3407 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:3423:20:3423 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:3439:20:3439 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:3455:20:3455 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:3471:20:3471 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:3487:20:3487 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:3503:20:3503 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:3519:20:3519 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:3535:20:3535 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:3551:20:3551 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:3567:20:3567 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:3583:20:3583 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:3599:20:3599 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:3615:20:3615 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:3631:20:3631 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:3647:20:3647 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:3663:20:3663 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:3679:20:3679 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:3695:20:3695 | x | +| UseUseExplosion.rb:19:13:19:13 | 0 | UseUseExplosion.rb:19:9:19:9 | x | | UseUseExplosion.rb:19:13:19:13 | 0 | UseUseExplosion.rb:19:9:19:13 | ... = ... | | UseUseExplosion.rb:20:9:20:3700 | SSA phi read(self) | UseUseExplosion.rb:21:13:21:17 | self | | UseUseExplosion.rb:20:9:20:3700 | SSA phi read(x) | UseUseExplosion.rb:21:2111:21:2111 | x | @@ -2402,8 +2402,8 @@ | 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 | -| local_dataflow.rb:2:7:2:7 | a | local_dataflow.rb:2:3:2:7 | ... = ... | +| local_dataflow.rb:2:3:2:3 | b | local_dataflow.rb:3:13:3:13 | b | +| local_dataflow.rb:2:7:2:7 | a | local_dataflow.rb:2:3:2:3 | b | | local_dataflow.rb:2:7:2:7 | a | local_dataflow.rb:2:3:2:7 | ... = ... | | local_dataflow.rb:2:7:2:7 | a | local_dataflow.rb:3:10:3:10 | a | | local_dataflow.rb:3:7:3:14 | ( ... ) | local_dataflow.rb:3:3:3:14 | ... = ... | @@ -2421,39 +2421,39 @@ | local_dataflow.rb:6:7:6:14 | ( ... ) | local_dataflow.rb:6:3:6:14 | ... = ... | | local_dataflow.rb:6:8:6:13 | ... = ... | local_dataflow.rb:6:7:6:14 | ( ... ) | | local_dataflow.rb:6:10:6:11 | ... + ... | local_dataflow.rb:6:8:6:13 | ... = ... | -| local_dataflow.rb:9:1:9:15 | ... = ... | local_dataflow.rb:10:14:10:18 | array | +| local_dataflow.rb:9:1:9:5 | array | local_dataflow.rb:10:14:10:18 | array | +| local_dataflow.rb:9:9:9:15 | call to [] | local_dataflow.rb:9:1:9:5 | array | | local_dataflow.rb:9:9:9:15 | call to [] | local_dataflow.rb:9:1:9:15 | ... = ... | -| local_dataflow.rb:9:9:9:15 | call to [] | local_dataflow.rb:9:1:9:15 | ... = ... | -| local_dataflow.rb:10:5:13:3 | ... = ... | local_dataflow.rb:12:5:12:5 | x | | local_dataflow.rb:10:5:13:3 | <captured entry> self | local_dataflow.rb:11:1:11:2 | self | | local_dataflow.rb:10:5:13:3 | __synth__0__1 | local_dataflow.rb:10:5:13:3 | ... = ... | -| local_dataflow.rb:10:5:13:3 | __synth__0__1 | local_dataflow.rb:10:5:13:3 | ... = ... | | local_dataflow.rb:10:5:13:3 | __synth__0__1 | local_dataflow.rb:10:5:13:3 | __synth__0__1 | | local_dataflow.rb:10:5:13:3 | __synth__0__1 | local_dataflow.rb:10:5:13:3 | __synth__0__1 | +| local_dataflow.rb:10:5:13:3 | __synth__0__1 | local_dataflow.rb:10:9:10:9 | x | | local_dataflow.rb:10:5:13:3 | call to each | local_dataflow.rb:10:1:13:3 | ... = ... | +| local_dataflow.rb:10:9:10:9 | x | local_dataflow.rb:12:5:12:5 | x | | local_dataflow.rb:10:14:10:18 | [post] array | local_dataflow.rb:15:10:15:14 | array | | local_dataflow.rb:10:14:10:18 | array | local_dataflow.rb:15:10:15:14 | array | | local_dataflow.rb:11:1:11:2 | [post] self | local_dataflow.rb:12:3:12:5 | self | | local_dataflow.rb:11:1:11:2 | self | local_dataflow.rb:12:3:12:5 | self | | local_dataflow.rb:15:1:17:3 | __synth__0__1 | local_dataflow.rb:15:1:17:3 | ... = ... | -| local_dataflow.rb:15:1:17:3 | __synth__0__1 | local_dataflow.rb:15:1:17:3 | ... = ... | | local_dataflow.rb:15:1:17:3 | __synth__0__1 | local_dataflow.rb:15:1:17:3 | __synth__0__1 | | local_dataflow.rb:15:1:17:3 | __synth__0__1 | local_dataflow.rb:15:1:17:3 | __synth__0__1 | +| local_dataflow.rb:15:1:17:3 | __synth__0__1 | local_dataflow.rb:15:5:15:5 | x | | local_dataflow.rb:15:10:15:14 | [post] array | local_dataflow.rb:19:10:19:14 | array | | local_dataflow.rb:15:10:15:14 | array | local_dataflow.rb:19:10:19:14 | array | | local_dataflow.rb:16:9:16:10 | 10 | local_dataflow.rb:16:3:16:10 | break | -| local_dataflow.rb:19:1:21:3 | ... = ... | local_dataflow.rb:20:6:20:6 | x | -| local_dataflow.rb:19:1:21:3 | __synth__0__1 | local_dataflow.rb:19:1:21:3 | ... = ... | | local_dataflow.rb:19:1:21:3 | __synth__0__1 | local_dataflow.rb:19:1:21:3 | ... = ... | | local_dataflow.rb:19:1:21:3 | __synth__0__1 | local_dataflow.rb:19:1:21:3 | __synth__0__1 | | local_dataflow.rb:19:1:21:3 | __synth__0__1 | local_dataflow.rb:19:1:21:3 | __synth__0__1 | +| local_dataflow.rb:19:1:21:3 | __synth__0__1 | local_dataflow.rb:19:5:19:5 | x | +| local_dataflow.rb:19:5:19:5 | x | local_dataflow.rb:20:6:20:6 | x | | local_dataflow.rb:24:2:24:8 | break | local_dataflow.rb:23:1:25:3 | while ... | | local_dataflow.rb:24:8:24:8 | 5 | local_dataflow.rb:24:2:24:8 | break | | local_dataflow.rb:28:5:28:26 | M | local_dataflow.rb:28:1:28:26 | ... = ... | | local_dataflow.rb:28:15:28:22 | "module" | local_dataflow.rb:28:5:28:26 | M | | local_dataflow.rb:30:5:30:24 | C | local_dataflow.rb:30:1:30:24 | ... = ... | | local_dataflow.rb:30:14:30:20 | "class" | local_dataflow.rb:30:5:30:24 | C | -| local_dataflow.rb:32:5:32:25 | bar | local_dataflow.rb:32:1:32:25 | ... = ... | +| local_dataflow.rb:32:5:32:25 | bar | local_dataflow.rb:32:1:32:1 | x | | local_dataflow.rb:32:5:32:25 | bar | local_dataflow.rb:32:1:32:25 | ... = ... | | local_dataflow.rb:34:7:34:7 | x | local_dataflow.rb:34:7:34:7 | x | | local_dataflow.rb:34:7:34:7 | x | local_dataflow.rb:35:6:35:6 | x | @@ -2498,9 +2498,9 @@ | local_dataflow.rb:73:7:73:7 | x | local_dataflow.rb:72:7:73:7 | then ... | | local_dataflow.rb:74:3:75:6 | else ... | local_dataflow.rb:69:7:76:5 | case ... | | local_dataflow.rb:75:6:75:6 | x | local_dataflow.rb:74:3:75:6 | else ... | -| local_dataflow.rb:78:3:88:5 | ... = ... | local_dataflow.rb:89:8:89:8 | z | +| local_dataflow.rb:78:3:78:3 | z | local_dataflow.rb:89:8:89:8 | z | | local_dataflow.rb:78:7:88:5 | SSA phi read(self) | local_dataflow.rb:89:3:89:9 | self | -| local_dataflow.rb:78:7:88:5 | case ... | local_dataflow.rb:78:3:88:5 | ... = ... | +| local_dataflow.rb:78:7:88:5 | case ... | local_dataflow.rb:78:3:78:3 | z | | local_dataflow.rb:78:7:88:5 | case ... | local_dataflow.rb:78:3:88:5 | ... = ... | | local_dataflow.rb:78:12:78:20 | [post] self | local_dataflow.rb:79:20:79:26 | self | | local_dataflow.rb:78:12:78:20 | [post] self | local_dataflow.rb:80:24:80:30 | self | @@ -2544,18 +2544,18 @@ | local_dataflow.rb:87:29:87:29 | x | local_dataflow.rb:87:15:87:48 | then ... | | local_dataflow.rb:92:1:109:3 | self (and_or) | local_dataflow.rb:93:7:93:15 | self | | local_dataflow.rb:92:1:109:3 | self in and_or | local_dataflow.rb:92:1:109:3 | self (and_or) | -| local_dataflow.rb:93:3:93:28 | ... = ... | local_dataflow.rb:94:8:94:8 | a | +| local_dataflow.rb:93:3:93:3 | a | local_dataflow.rb:94:8:94:8 | a | | local_dataflow.rb:93:7:93:15 | [post] self | local_dataflow.rb:93:20:93:28 | self | | local_dataflow.rb:93:7:93:15 | call to source | local_dataflow.rb:93:7:93:28 | ... \|\| ... | | local_dataflow.rb:93:7:93:15 | self | local_dataflow.rb:93:20:93:28 | self | -| local_dataflow.rb:93:7:93:28 | ... \|\| ... | local_dataflow.rb:93:3:93:28 | ... = ... | +| local_dataflow.rb:93:7:93:28 | ... \|\| ... | local_dataflow.rb:93:3:93:3 | a | | local_dataflow.rb:93:7:93:28 | ... \|\| ... | local_dataflow.rb:93:3:93:28 | ... = ... | | local_dataflow.rb:93:7:93:28 | SSA phi read(self) | local_dataflow.rb:94:3:94:9 | self | | local_dataflow.rb:93:20:93:28 | call to source | local_dataflow.rb:93:7:93:28 | ... \|\| ... | | local_dataflow.rb:94:3:94:9 | [post] self | local_dataflow.rb:95:8:95:16 | self | | local_dataflow.rb:94:3:94:9 | self | local_dataflow.rb:95:8:95:16 | self | -| local_dataflow.rb:95:3:95:30 | ... = ... | local_dataflow.rb:96:8:96:8 | b | -| local_dataflow.rb:95:7:95:30 | ( ... ) | local_dataflow.rb:95:3:95:30 | ... = ... | +| local_dataflow.rb:95:3:95:3 | b | local_dataflow.rb:96:8:96:8 | b | +| local_dataflow.rb:95:7:95:30 | ( ... ) | local_dataflow.rb:95:3:95:3 | b | | local_dataflow.rb:95:7:95:30 | ( ... ) | local_dataflow.rb:95:3:95:30 | ... = ... | | local_dataflow.rb:95:8:95:16 | [post] self | local_dataflow.rb:95:21:95:29 | self | | local_dataflow.rb:95:8:95:16 | call to source | local_dataflow.rb:95:8:95:29 | ... or ... | @@ -2565,18 +2565,18 @@ | local_dataflow.rb:95:21:95:29 | call to source | local_dataflow.rb:95:8:95:29 | ... or ... | | local_dataflow.rb:96:3:96:9 | [post] self | local_dataflow.rb:98:7:98:15 | self | | local_dataflow.rb:96:3:96:9 | self | local_dataflow.rb:98:7:98:15 | self | -| local_dataflow.rb:98:3:98:28 | ... = ... | local_dataflow.rb:99:8:99:8 | a | +| local_dataflow.rb:98:3:98:3 | a | local_dataflow.rb:99:8:99:8 | a | | local_dataflow.rb:98:7:98:15 | [post] self | local_dataflow.rb:98:20:98:28 | self | | local_dataflow.rb:98:7:98:15 | call to source | local_dataflow.rb:98:7:98:28 | ... && ... | | local_dataflow.rb:98:7:98:15 | self | local_dataflow.rb:98:20:98:28 | self | -| local_dataflow.rb:98:7:98:28 | ... && ... | local_dataflow.rb:98:3:98:28 | ... = ... | +| local_dataflow.rb:98:7:98:28 | ... && ... | local_dataflow.rb:98:3:98:3 | a | | local_dataflow.rb:98:7:98:28 | ... && ... | local_dataflow.rb:98:3:98:28 | ... = ... | | local_dataflow.rb:98:7:98:28 | SSA phi read(self) | local_dataflow.rb:99:3:99:9 | self | | local_dataflow.rb:98:20:98:28 | call to source | local_dataflow.rb:98:7:98:28 | ... && ... | | local_dataflow.rb:99:3:99:9 | [post] self | local_dataflow.rb:100:8:100:16 | self | | local_dataflow.rb:99:3:99:9 | self | local_dataflow.rb:100:8:100:16 | self | -| local_dataflow.rb:100:3:100:31 | ... = ... | local_dataflow.rb:101:8:101:8 | b | -| local_dataflow.rb:100:7:100:31 | ( ... ) | local_dataflow.rb:100:3:100:31 | ... = ... | +| local_dataflow.rb:100:3:100:3 | b | local_dataflow.rb:101:8:101:8 | b | +| local_dataflow.rb:100:7:100:31 | ( ... ) | local_dataflow.rb:100:3:100:3 | b | | local_dataflow.rb:100:7:100:31 | ( ... ) | local_dataflow.rb:100:3:100:31 | ... = ... | | local_dataflow.rb:100:8:100:16 | [post] self | local_dataflow.rb:100:22:100:30 | self | | local_dataflow.rb:100:8:100:16 | call to source | local_dataflow.rb:100:8:100:30 | ... and ... | @@ -2586,27 +2586,27 @@ | local_dataflow.rb:100:22:100:30 | call to source | local_dataflow.rb:100:8:100:30 | ... and ... | | local_dataflow.rb:101:3:101:9 | [post] self | local_dataflow.rb:103:7:103:15 | self | | local_dataflow.rb:101:3:101:9 | self | local_dataflow.rb:103:7:103:15 | self | -| local_dataflow.rb:103:3:103:15 | ... = ... | local_dataflow.rb:104:3:104:3 | a | +| local_dataflow.rb:103:3:103:3 | a | local_dataflow.rb:104:3:104:3 | a | | local_dataflow.rb:103:7:103:15 | [post] self | local_dataflow.rb:104:9:104:17 | self | -| local_dataflow.rb:103:7:103:15 | call to source | local_dataflow.rb:103:3:103:15 | ... = ... | +| local_dataflow.rb:103:7:103:15 | call to source | local_dataflow.rb:103:3:103:3 | a | | local_dataflow.rb:103:7:103:15 | call to source | local_dataflow.rb:103:3:103:15 | ... = ... | | local_dataflow.rb:103:7:103:15 | self | local_dataflow.rb:104:9:104:17 | self | | local_dataflow.rb:104:3:104:3 | a | local_dataflow.rb:104:5:104:7 | ... \|\| ... | -| local_dataflow.rb:104:3:104:17 | ... = ... | local_dataflow.rb:105:8:105:8 | a | -| local_dataflow.rb:104:5:104:7 | ... \|\| ... | local_dataflow.rb:104:3:104:17 | ... = ... | +| local_dataflow.rb:104:3:104:3 | a | local_dataflow.rb:105:8:105:8 | a | +| local_dataflow.rb:104:5:104:7 | ... \|\| ... | local_dataflow.rb:104:3:104:3 | a | | local_dataflow.rb:104:5:104:7 | ... \|\| ... | local_dataflow.rb:104:3:104:17 | ... = ... | | local_dataflow.rb:104:5:104:7 | SSA phi read(self) | local_dataflow.rb:105:3:105:9 | self | | local_dataflow.rb:104:9:104:17 | call to source | local_dataflow.rb:104:5:104:7 | ... \|\| ... | | local_dataflow.rb:105:3:105:9 | [post] self | local_dataflow.rb:106:7:106:15 | self | | local_dataflow.rb:105:3:105:9 | self | local_dataflow.rb:106:7:106:15 | self | -| local_dataflow.rb:106:3:106:15 | ... = ... | local_dataflow.rb:107:3:107:3 | b | +| local_dataflow.rb:106:3:106:3 | b | local_dataflow.rb:107:3:107:3 | b | | local_dataflow.rb:106:7:106:15 | [post] self | local_dataflow.rb:107:9:107:17 | self | -| local_dataflow.rb:106:7:106:15 | call to source | local_dataflow.rb:106:3:106:15 | ... = ... | +| local_dataflow.rb:106:7:106:15 | call to source | local_dataflow.rb:106:3:106:3 | b | | local_dataflow.rb:106:7:106:15 | call to source | local_dataflow.rb:106:3:106:15 | ... = ... | | local_dataflow.rb:106:7:106:15 | self | local_dataflow.rb:107:9:107:17 | self | | local_dataflow.rb:107:3:107:3 | b | local_dataflow.rb:107:5:107:7 | ... && ... | -| local_dataflow.rb:107:3:107:17 | ... = ... | local_dataflow.rb:108:8:108:8 | b | -| local_dataflow.rb:107:5:107:7 | ... && ... | local_dataflow.rb:107:3:107:17 | ... = ... | +| local_dataflow.rb:107:3:107:3 | b | local_dataflow.rb:108:8:108:8 | b | +| local_dataflow.rb:107:5:107:7 | ... && ... | local_dataflow.rb:107:3:107:3 | b | | local_dataflow.rb:107:5:107:7 | ... && ... | local_dataflow.rb:107:3:107:17 | ... = ... | | local_dataflow.rb:107:5:107:7 | SSA phi read(self) | local_dataflow.rb:108:3:108:9 | self | | local_dataflow.rb:107:9:107:17 | call to source | local_dataflow.rb:107:5:107:7 | ... && ... | @@ -2650,8 +2650,8 @@ | 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:3:131:3 | x | local_dataflow.rb:132:10:132:10 | x | +| local_dataflow.rb:131:7:131:8 | "" | local_dataflow.rb:131:3:131:3 | x | | 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 | diff --git a/ruby/ql/test/library-tests/dataflow/local/InlineFlowTest.expected b/ruby/ql/test/library-tests/dataflow/local/InlineFlowTest.expected index 762fc9a70f1..b824d6d37a1 100644 --- a/ruby/ql/test/library-tests/dataflow/local/InlineFlowTest.expected +++ b/ruby/ql/test/library-tests/dataflow/local/InlineFlowTest.expected @@ -1,38 +1,63 @@ failures edges -| local_dataflow.rb:78:12:78:20 | call to source : | local_dataflow.rb:79:25:79:25 | b | -| local_dataflow.rb:78:12:78:20 | call to source : | local_dataflow.rb:80:29:80:29 | a | -| local_dataflow.rb:78:12:78:20 | call to source : | local_dataflow.rb:82:12:82:12 | c | -| local_dataflow.rb:78:12:78:20 | call to source : | local_dataflow.rb:83:12:83:12 | d | -| local_dataflow.rb:78:12:78:20 | call to source : | local_dataflow.rb:84:12:84:12 | e | -| local_dataflow.rb:78:12:78:20 | call to source : | local_dataflow.rb:85:27:85:27 | f | -| local_dataflow.rb:78:12:78:20 | call to source : | local_dataflow.rb:86:33:86:33 | g | -| local_dataflow.rb:78:12:78:20 | call to source : | local_dataflow.rb:87:25:87:25 | x | -| local_dataflow.rb:78:12:78:20 | call to source : | local_dataflow.rb:89:8:89:8 | z | -| local_dataflow.rb:93:7:93:15 | call to source : | local_dataflow.rb:94:8:94:8 | a | -| local_dataflow.rb:93:7:93:15 | call to source : | local_dataflow.rb:94:8:94:8 | a | -| local_dataflow.rb:93:20:93:28 | call to source : | local_dataflow.rb:94:8:94:8 | a | -| local_dataflow.rb:93:20:93:28 | call to source : | local_dataflow.rb:94:8:94:8 | a | -| local_dataflow.rb:95:8:95:16 | call to source : | local_dataflow.rb:96:8:96:8 | b | -| local_dataflow.rb:95:8:95:16 | call to source : | local_dataflow.rb:96:8:96:8 | b | -| local_dataflow.rb:95:21:95:29 | call to source : | local_dataflow.rb:96:8:96:8 | b | -| local_dataflow.rb:95:21:95:29 | call to source : | local_dataflow.rb:96:8:96:8 | b | -| local_dataflow.rb:98:7:98:15 | call to source : | local_dataflow.rb:99:8:99:8 | a | -| local_dataflow.rb:98:7:98:15 | call to source : | local_dataflow.rb:99:8:99:8 | a | -| local_dataflow.rb:98:20:98:28 | call to source : | local_dataflow.rb:99:8:99:8 | a | -| local_dataflow.rb:98:20:98:28 | call to source : | local_dataflow.rb:99:8:99:8 | a | -| local_dataflow.rb:100:8:100:16 | call to source : | local_dataflow.rb:101:8:101:8 | b | -| local_dataflow.rb:100:8:100:16 | call to source : | local_dataflow.rb:101:8:101:8 | b | -| local_dataflow.rb:100:22:100:30 | call to source : | local_dataflow.rb:101:8:101:8 | b | -| local_dataflow.rb:100:22:100:30 | call to source : | local_dataflow.rb:101:8:101:8 | b | -| local_dataflow.rb:103:7:103:15 | call to source : | local_dataflow.rb:105:8:105:8 | a | -| local_dataflow.rb:103:7:103:15 | call to source : | local_dataflow.rb:105:8:105:8 | a | -| local_dataflow.rb:104:9:104:17 | call to source : | local_dataflow.rb:105:8:105:8 | a | -| local_dataflow.rb:104:9:104:17 | call to source : | local_dataflow.rb:105:8:105:8 | a | -| local_dataflow.rb:106:7:106:15 | call to source : | local_dataflow.rb:108:8:108:8 | b | -| local_dataflow.rb:106:7:106:15 | call to source : | local_dataflow.rb:108:8:108:8 | b | -| local_dataflow.rb:107:9:107:17 | call to source : | local_dataflow.rb:108:8:108:8 | b | -| local_dataflow.rb:107:9:107:17 | call to source : | local_dataflow.rb:108:8:108:8 | b | +| local_dataflow.rb:78:3:78:3 | z : | local_dataflow.rb:89:8:89:8 | z | +| local_dataflow.rb:78:12:78:20 | call to source : | local_dataflow.rb:79:13:79:13 | b : | +| local_dataflow.rb:78:12:78:20 | call to source : | local_dataflow.rb:80:8:80:8 | a : | +| local_dataflow.rb:78:12:78:20 | call to source : | local_dataflow.rb:81:9:81:9 | c : | +| local_dataflow.rb:78:12:78:20 | call to source : | local_dataflow.rb:81:13:81:13 | d : | +| local_dataflow.rb:78:12:78:20 | call to source : | local_dataflow.rb:81:16:81:16 | e : | +| local_dataflow.rb:78:12:78:20 | call to source : | local_dataflow.rb:85:13:85:13 | f : | +| local_dataflow.rb:78:12:78:20 | call to source : | local_dataflow.rb:86:18:86:18 | g : | +| local_dataflow.rb:78:12:78:20 | call to source : | local_dataflow.rb:87:10:87:10 | x : | +| local_dataflow.rb:79:13:79:13 | b : | local_dataflow.rb:79:25:79:25 | b | +| local_dataflow.rb:80:8:80:8 | a : | local_dataflow.rb:80:29:80:29 | a | +| local_dataflow.rb:81:9:81:9 | c : | local_dataflow.rb:82:12:82:12 | c | +| local_dataflow.rb:81:13:81:13 | d : | local_dataflow.rb:83:12:83:12 | d | +| local_dataflow.rb:81:16:81:16 | e : | local_dataflow.rb:84:12:84:12 | e | +| local_dataflow.rb:85:13:85:13 | f : | local_dataflow.rb:85:27:85:27 | f | +| local_dataflow.rb:86:18:86:18 | g : | local_dataflow.rb:86:33:86:33 | g | +| local_dataflow.rb:87:10:87:10 | x : | local_dataflow.rb:78:3:78:3 | z : | +| local_dataflow.rb:87:10:87:10 | x : | local_dataflow.rb:87:25:87:25 | x | +| local_dataflow.rb:93:3:93:3 | a : | local_dataflow.rb:94:8:94:8 | a | +| local_dataflow.rb:93:3:93:3 | a : | local_dataflow.rb:94:8:94:8 | a | +| local_dataflow.rb:93:7:93:15 | call to source : | local_dataflow.rb:93:3:93:3 | a : | +| local_dataflow.rb:93:7:93:15 | call to source : | local_dataflow.rb:93:3:93:3 | a : | +| local_dataflow.rb:93:20:93:28 | call to source : | local_dataflow.rb:93:3:93:3 | a : | +| local_dataflow.rb:93:20:93:28 | call to source : | local_dataflow.rb:93:3:93:3 | a : | +| local_dataflow.rb:95:3:95:3 | b : | local_dataflow.rb:96:8:96:8 | b | +| local_dataflow.rb:95:3:95:3 | b : | local_dataflow.rb:96:8:96:8 | b | +| local_dataflow.rb:95:8:95:16 | call to source : | local_dataflow.rb:95:3:95:3 | b : | +| local_dataflow.rb:95:8:95:16 | call to source : | local_dataflow.rb:95:3:95:3 | b : | +| local_dataflow.rb:95:21:95:29 | call to source : | local_dataflow.rb:95:3:95:3 | b : | +| local_dataflow.rb:95:21:95:29 | call to source : | local_dataflow.rb:95:3:95:3 | b : | +| local_dataflow.rb:98:3:98:3 | a : | local_dataflow.rb:99:8:99:8 | a | +| local_dataflow.rb:98:3:98:3 | a : | local_dataflow.rb:99:8:99:8 | a | +| local_dataflow.rb:98:7:98:15 | call to source : | local_dataflow.rb:98:3:98:3 | a : | +| local_dataflow.rb:98:7:98:15 | call to source : | local_dataflow.rb:98:3:98:3 | a : | +| local_dataflow.rb:98:20:98:28 | call to source : | local_dataflow.rb:98:3:98:3 | a : | +| local_dataflow.rb:98:20:98:28 | call to source : | local_dataflow.rb:98:3:98:3 | a : | +| local_dataflow.rb:100:3:100:3 | b : | local_dataflow.rb:101:8:101:8 | b | +| local_dataflow.rb:100:3:100:3 | b : | local_dataflow.rb:101:8:101:8 | b | +| local_dataflow.rb:100:8:100:16 | call to source : | local_dataflow.rb:100:3:100:3 | b : | +| local_dataflow.rb:100:8:100:16 | call to source : | local_dataflow.rb:100:3:100:3 | b : | +| local_dataflow.rb:100:22:100:30 | call to source : | local_dataflow.rb:100:3:100:3 | b : | +| local_dataflow.rb:100:22:100:30 | call to source : | local_dataflow.rb:100:3:100:3 | b : | +| local_dataflow.rb:103:3:103:3 | a : | local_dataflow.rb:104:3:104:3 | a : | +| local_dataflow.rb:103:3:103:3 | a : | local_dataflow.rb:104:3:104:3 | a : | +| local_dataflow.rb:103:7:103:15 | call to source : | local_dataflow.rb:103:3:103:3 | a : | +| local_dataflow.rb:103:7:103:15 | call to source : | local_dataflow.rb:103:3:103:3 | a : | +| local_dataflow.rb:104:3:104:3 | a : | local_dataflow.rb:105:8:105:8 | a | +| local_dataflow.rb:104:3:104:3 | a : | local_dataflow.rb:105:8:105:8 | a | +| local_dataflow.rb:104:9:104:17 | call to source : | local_dataflow.rb:104:3:104:3 | a : | +| local_dataflow.rb:104:9:104:17 | call to source : | local_dataflow.rb:104:3:104:3 | a : | +| local_dataflow.rb:106:3:106:3 | b : | local_dataflow.rb:107:3:107:3 | b : | +| local_dataflow.rb:106:3:106:3 | b : | local_dataflow.rb:107:3:107:3 | b : | +| local_dataflow.rb:106:7:106:15 | call to source : | local_dataflow.rb:106:3:106:3 | b : | +| local_dataflow.rb:106:7:106:15 | call to source : | local_dataflow.rb:106:3:106:3 | b : | +| local_dataflow.rb:107:3:107:3 | b : | local_dataflow.rb:108:8:108:8 | b | +| local_dataflow.rb:107:3:107:3 | b : | local_dataflow.rb:108:8:108:8 | b | +| local_dataflow.rb:107:9:107:17 | call to source : | local_dataflow.rb:107:3:107:3 | b : | +| local_dataflow.rb:107:9:107:17 | call to source : | local_dataflow.rb:107:3:107:3 | b : | | local_dataflow.rb:112:8:112:16 | call to source : | local_dataflow.rb:112:8:112:20 | call to dup | | local_dataflow.rb:112:8:112:16 | call to source : | local_dataflow.rb:112:8:112:20 | call to dup | | local_dataflow.rb:113:8:113:16 | call to source : | local_dataflow.rb:113:8:113:20 | call to dup : | @@ -56,48 +81,73 @@ edges | local_dataflow.rb:123:8:123:45 | call to tap : | local_dataflow.rb:123:8:123:49 | call to dup | | local_dataflow.rb:123:8:123:45 | call to tap : | local_dataflow.rb:123:8:123:49 | call to dup | nodes +| local_dataflow.rb:78:3:78:3 | z : | semmle.label | z : | | local_dataflow.rb:78:12:78:20 | call to source : | semmle.label | call to source : | +| local_dataflow.rb:79:13:79:13 | b : | semmle.label | b : | | local_dataflow.rb:79:25:79:25 | b | semmle.label | b | +| local_dataflow.rb:80:8:80:8 | a : | semmle.label | a : | | local_dataflow.rb:80:29:80:29 | a | semmle.label | a | +| local_dataflow.rb:81:9:81:9 | c : | semmle.label | c : | +| local_dataflow.rb:81:13:81:13 | d : | semmle.label | d : | +| local_dataflow.rb:81:16:81:16 | e : | semmle.label | e : | | local_dataflow.rb:82:12:82:12 | c | semmle.label | c | | local_dataflow.rb:83:12:83:12 | d | semmle.label | d | | local_dataflow.rb:84:12:84:12 | e | semmle.label | e | +| local_dataflow.rb:85:13:85:13 | f : | semmle.label | f : | | local_dataflow.rb:85:27:85:27 | f | semmle.label | f | +| local_dataflow.rb:86:18:86:18 | g : | semmle.label | g : | | local_dataflow.rb:86:33:86:33 | g | semmle.label | g | +| local_dataflow.rb:87:10:87:10 | x : | semmle.label | x : | | local_dataflow.rb:87:25:87:25 | x | semmle.label | x | | local_dataflow.rb:89:8:89:8 | z | semmle.label | z | +| local_dataflow.rb:93:3:93:3 | a : | semmle.label | a : | +| local_dataflow.rb:93:3:93:3 | a : | semmle.label | a : | | local_dataflow.rb:93:7:93:15 | call to source : | semmle.label | call to source : | | local_dataflow.rb:93:7:93:15 | call to source : | semmle.label | call to source : | | local_dataflow.rb:93:20:93:28 | call to source : | semmle.label | call to source : | | local_dataflow.rb:93:20:93:28 | call to source : | semmle.label | call to source : | | local_dataflow.rb:94:8:94:8 | a | semmle.label | a | | local_dataflow.rb:94:8:94:8 | a | semmle.label | a | +| local_dataflow.rb:95:3:95:3 | b : | semmle.label | b : | +| local_dataflow.rb:95:3:95:3 | b : | semmle.label | b : | | local_dataflow.rb:95:8:95:16 | call to source : | semmle.label | call to source : | | local_dataflow.rb:95:8:95:16 | call to source : | semmle.label | call to source : | | local_dataflow.rb:95:21:95:29 | call to source : | semmle.label | call to source : | | local_dataflow.rb:95:21:95:29 | call to source : | semmle.label | call to source : | | local_dataflow.rb:96:8:96:8 | b | semmle.label | b | | local_dataflow.rb:96:8:96:8 | b | semmle.label | b | +| local_dataflow.rb:98:3:98:3 | a : | semmle.label | a : | +| local_dataflow.rb:98:3:98:3 | a : | semmle.label | a : | | local_dataflow.rb:98:7:98:15 | call to source : | semmle.label | call to source : | | local_dataflow.rb:98:7:98:15 | call to source : | semmle.label | call to source : | | local_dataflow.rb:98:20:98:28 | call to source : | semmle.label | call to source : | | local_dataflow.rb:98:20:98:28 | call to source : | semmle.label | call to source : | | local_dataflow.rb:99:8:99:8 | a | semmle.label | a | | local_dataflow.rb:99:8:99:8 | a | semmle.label | a | +| local_dataflow.rb:100:3:100:3 | b : | semmle.label | b : | +| local_dataflow.rb:100:3:100:3 | b : | semmle.label | b : | | local_dataflow.rb:100:8:100:16 | call to source : | semmle.label | call to source : | | local_dataflow.rb:100:8:100:16 | call to source : | semmle.label | call to source : | | local_dataflow.rb:100:22:100:30 | call to source : | semmle.label | call to source : | | local_dataflow.rb:100:22:100:30 | call to source : | semmle.label | call to source : | | local_dataflow.rb:101:8:101:8 | b | semmle.label | b | | local_dataflow.rb:101:8:101:8 | b | semmle.label | b | +| local_dataflow.rb:103:3:103:3 | a : | semmle.label | a : | +| local_dataflow.rb:103:3:103:3 | a : | semmle.label | a : | | local_dataflow.rb:103:7:103:15 | call to source : | semmle.label | call to source : | | local_dataflow.rb:103:7:103:15 | call to source : | semmle.label | call to source : | +| local_dataflow.rb:104:3:104:3 | a : | semmle.label | a : | +| local_dataflow.rb:104:3:104:3 | a : | semmle.label | a : | | local_dataflow.rb:104:9:104:17 | call to source : | semmle.label | call to source : | | local_dataflow.rb:104:9:104:17 | call to source : | semmle.label | call to source : | | local_dataflow.rb:105:8:105:8 | a | semmle.label | a | | local_dataflow.rb:105:8:105:8 | a | semmle.label | a | +| local_dataflow.rb:106:3:106:3 | b : | semmle.label | b : | +| local_dataflow.rb:106:3:106:3 | b : | semmle.label | b : | | local_dataflow.rb:106:7:106:15 | call to source : | semmle.label | call to source : | | local_dataflow.rb:106:7:106:15 | call to source : | semmle.label | call to source : | +| local_dataflow.rb:107:3:107:3 | b : | semmle.label | b : | +| local_dataflow.rb:107:3:107:3 | b : | semmle.label | b : | | local_dataflow.rb:107:9:107:17 | call to source : | semmle.label | call to source : | | local_dataflow.rb:107:9:107:17 | call to source : | semmle.label | call to source : | | local_dataflow.rb:108:8:108:8 | b | semmle.label | b | diff --git a/ruby/ql/test/library-tests/dataflow/local/TaintStep.expected b/ruby/ql/test/library-tests/dataflow/local/TaintStep.expected index da8b1b82747..890bef5720e 100644 --- a/ruby/ql/test/library-tests/dataflow/local/TaintStep.expected +++ b/ruby/ql/test/library-tests/dataflow/local/TaintStep.expected @@ -1,107 +1,107 @@ | UseUseExplosion.rb:18:5:22:7 | self (m) | UseUseExplosion.rb:20:13:20:17 | self | | UseUseExplosion.rb:18:5:22:7 | self in m | UseUseExplosion.rb:18:5:22:7 | self (m) | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:2081:20:2116 | SSA phi read(x) | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:2111:20:2111 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:2127:20:2127 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:2143:20:2143 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:2159:20:2159 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:2175:20:2175 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:2191:20:2191 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:2207:20:2207 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:2223:20:2223 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:2239:20:2239 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:2255:20:2255 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:2271:20:2271 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:2287:20:2287 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:2303:20:2303 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:2319:20:2319 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:2335:20:2335 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:2351:20:2351 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:2367:20:2367 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:2383:20:2383 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:2399:20:2399 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:2415:20:2415 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:2431:20:2431 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:2447:20:2447 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:2463:20:2463 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:2479:20:2479 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:2495:20:2495 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:2511:20:2511 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:2527:20:2527 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:2543:20:2543 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:2559:20:2559 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:2575:20:2575 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:2591:20:2591 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:2607:20:2607 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:2623:20:2623 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:2639:20:2639 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:2655:20:2655 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:2671:20:2671 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:2687:20:2687 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:2703:20:2703 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:2719:20:2719 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:2735:20:2735 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:2751:20:2751 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:2767:20:2767 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:2783:20:2783 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:2799:20:2799 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:2815:20:2815 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:2831:20:2831 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:2847:20:2847 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:2863:20:2863 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:2879:20:2879 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:2895:20:2895 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:2911:20:2911 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:2927:20:2927 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:2943:20:2943 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:2959:20:2959 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:2975:20:2975 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:2991:20:2991 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:3007:20:3007 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:3023:20:3023 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:3039:20:3039 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:3055:20:3055 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:3071:20:3071 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:3087:20:3087 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:3103:20:3103 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:3119:20:3119 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:3135:20:3135 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:3151:20:3151 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:3167:20:3167 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:3183:20:3183 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:3199:20:3199 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:3215:20:3215 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:3231:20:3231 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:3247:20:3247 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:3263:20:3263 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:3279:20:3279 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:3295:20:3295 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:3311:20:3311 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:3327:20:3327 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:3343:20:3343 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:3359:20:3359 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:3375:20:3375 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:3391:20:3391 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:3407:20:3407 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:3423:20:3423 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:3439:20:3439 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:3455:20:3455 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:3471:20:3471 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:3487:20:3487 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:3503:20:3503 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:3519:20:3519 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:3535:20:3535 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:3551:20:3551 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:3567:20:3567 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:3583:20:3583 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:3599:20:3599 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:3615:20:3615 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:3631:20:3631 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:3647:20:3647 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:3663:20:3663 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:3679:20:3679 | x | -| UseUseExplosion.rb:19:9:19:13 | ... = ... | UseUseExplosion.rb:20:3695:20:3695 | x | -| UseUseExplosion.rb:19:13:19:13 | 0 | UseUseExplosion.rb:19:9:19:13 | ... = ... | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:2081:20:2116 | SSA phi read(x) | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:2111:20:2111 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:2127:20:2127 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:2143:20:2143 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:2159:20:2159 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:2175:20:2175 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:2191:20:2191 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:2207:20:2207 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:2223:20:2223 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:2239:20:2239 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:2255:20:2255 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:2271:20:2271 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:2287:20:2287 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:2303:20:2303 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:2319:20:2319 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:2335:20:2335 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:2351:20:2351 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:2367:20:2367 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:2383:20:2383 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:2399:20:2399 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:2415:20:2415 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:2431:20:2431 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:2447:20:2447 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:2463:20:2463 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:2479:20:2479 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:2495:20:2495 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:2511:20:2511 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:2527:20:2527 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:2543:20:2543 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:2559:20:2559 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:2575:20:2575 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:2591:20:2591 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:2607:20:2607 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:2623:20:2623 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:2639:20:2639 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:2655:20:2655 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:2671:20:2671 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:2687:20:2687 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:2703:20:2703 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:2719:20:2719 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:2735:20:2735 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:2751:20:2751 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:2767:20:2767 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:2783:20:2783 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:2799:20:2799 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:2815:20:2815 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:2831:20:2831 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:2847:20:2847 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:2863:20:2863 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:2879:20:2879 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:2895:20:2895 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:2911:20:2911 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:2927:20:2927 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:2943:20:2943 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:2959:20:2959 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:2975:20:2975 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:2991:20:2991 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:3007:20:3007 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:3023:20:3023 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:3039:20:3039 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:3055:20:3055 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:3071:20:3071 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:3087:20:3087 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:3103:20:3103 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:3119:20:3119 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:3135:20:3135 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:3151:20:3151 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:3167:20:3167 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:3183:20:3183 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:3199:20:3199 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:3215:20:3215 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:3231:20:3231 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:3247:20:3247 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:3263:20:3263 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:3279:20:3279 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:3295:20:3295 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:3311:20:3311 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:3327:20:3327 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:3343:20:3343 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:3359:20:3359 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:3375:20:3375 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:3391:20:3391 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:3407:20:3407 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:3423:20:3423 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:3439:20:3439 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:3455:20:3455 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:3471:20:3471 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:3487:20:3487 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:3503:20:3503 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:3519:20:3519 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:3535:20:3535 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:3551:20:3551 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:3567:20:3567 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:3583:20:3583 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:3599:20:3599 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:3615:20:3615 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:3631:20:3631 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:3647:20:3647 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:3663:20:3663 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:3679:20:3679 | x | +| UseUseExplosion.rb:19:9:19:9 | x | UseUseExplosion.rb:20:3695:20:3695 | x | +| UseUseExplosion.rb:19:13:19:13 | 0 | UseUseExplosion.rb:19:9:19:9 | x | | UseUseExplosion.rb:19:13:19:13 | 0 | UseUseExplosion.rb:19:9:19:13 | ... = ... | | UseUseExplosion.rb:20:9:20:3700 | SSA phi read(self) | UseUseExplosion.rb:21:13:21:17 | self | | UseUseExplosion.rb:20:9:20:3700 | SSA phi read(x) | UseUseExplosion.rb:21:2111:21:2111 | x | @@ -2833,8 +2833,8 @@ | 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 | -| local_dataflow.rb:2:7:2:7 | a | local_dataflow.rb:2:3:2:7 | ... = ... | +| local_dataflow.rb:2:3:2:3 | b | local_dataflow.rb:3:13:3:13 | b | +| local_dataflow.rb:2:7:2:7 | a | local_dataflow.rb:2:3:2:3 | b | | local_dataflow.rb:2:7:2:7 | a | local_dataflow.rb:2:3:2:7 | ... = ... | | local_dataflow.rb:2:7:2:7 | a | local_dataflow.rb:3:10:3:10 | a | | local_dataflow.rb:3:7:3:14 | ( ... ) | local_dataflow.rb:3:3:3:14 | ... = ... | @@ -2854,33 +2854,33 @@ | local_dataflow.rb:6:8:6:13 | ... = ... | local_dataflow.rb:6:7:6:14 | ( ... ) | | local_dataflow.rb:6:10:6:11 | ... + ... | local_dataflow.rb:6:8:6:13 | ... = ... | | local_dataflow.rb:6:13:6:13 | b | local_dataflow.rb:6:10:6:11 | ... + ... | -| local_dataflow.rb:9:1:9:15 | ... = ... | local_dataflow.rb:10:14:10:18 | array | +| local_dataflow.rb:9:1:9:5 | array | local_dataflow.rb:10:14:10:18 | array | | local_dataflow.rb:9:9:9:15 | Array | local_dataflow.rb:9:9:9:15 | call to [] | +| local_dataflow.rb:9:9:9:15 | call to [] | local_dataflow.rb:9:1:9:5 | array | | local_dataflow.rb:9:9:9:15 | call to [] | local_dataflow.rb:9:1:9:15 | ... = ... | -| local_dataflow.rb:9:9:9:15 | call to [] | local_dataflow.rb:9:1:9:15 | ... = ... | -| local_dataflow.rb:10:5:13:3 | ... = ... | local_dataflow.rb:12:5:12:5 | x | | local_dataflow.rb:10:5:13:3 | <captured entry> self | local_dataflow.rb:11:1:11:2 | self | | local_dataflow.rb:10:5:13:3 | __synth__0__1 | local_dataflow.rb:10:5:13:3 | ... = ... | -| local_dataflow.rb:10:5:13:3 | __synth__0__1 | local_dataflow.rb:10:5:13:3 | ... = ... | | local_dataflow.rb:10:5:13:3 | __synth__0__1 | local_dataflow.rb:10:5:13:3 | __synth__0__1 | | local_dataflow.rb:10:5:13:3 | __synth__0__1 | local_dataflow.rb:10:5:13:3 | __synth__0__1 | +| local_dataflow.rb:10:5:13:3 | __synth__0__1 | local_dataflow.rb:10:9:10:9 | x | | local_dataflow.rb:10:5:13:3 | call to each | local_dataflow.rb:10:1:13:3 | ... = ... | +| local_dataflow.rb:10:9:10:9 | x | local_dataflow.rb:12:5:12:5 | x | | local_dataflow.rb:10:14:10:18 | [post] array | local_dataflow.rb:15:10:15:14 | array | | local_dataflow.rb:10:14:10:18 | array | local_dataflow.rb:15:10:15:14 | array | | local_dataflow.rb:11:1:11:2 | [post] self | local_dataflow.rb:12:3:12:5 | self | | local_dataflow.rb:11:1:11:2 | self | local_dataflow.rb:12:3:12:5 | self | | local_dataflow.rb:15:1:17:3 | __synth__0__1 | local_dataflow.rb:15:1:17:3 | ... = ... | -| local_dataflow.rb:15:1:17:3 | __synth__0__1 | local_dataflow.rb:15:1:17:3 | ... = ... | | local_dataflow.rb:15:1:17:3 | __synth__0__1 | local_dataflow.rb:15:1:17:3 | __synth__0__1 | | local_dataflow.rb:15:1:17:3 | __synth__0__1 | local_dataflow.rb:15:1:17:3 | __synth__0__1 | +| local_dataflow.rb:15:1:17:3 | __synth__0__1 | local_dataflow.rb:15:5:15:5 | x | | local_dataflow.rb:15:10:15:14 | [post] array | local_dataflow.rb:19:10:19:14 | array | | local_dataflow.rb:15:10:15:14 | array | local_dataflow.rb:19:10:19:14 | array | | local_dataflow.rb:16:9:16:10 | 10 | local_dataflow.rb:16:3:16:10 | break | -| local_dataflow.rb:19:1:21:3 | ... = ... | local_dataflow.rb:20:6:20:6 | x | -| local_dataflow.rb:19:1:21:3 | __synth__0__1 | local_dataflow.rb:19:1:21:3 | ... = ... | | local_dataflow.rb:19:1:21:3 | __synth__0__1 | local_dataflow.rb:19:1:21:3 | ... = ... | | local_dataflow.rb:19:1:21:3 | __synth__0__1 | local_dataflow.rb:19:1:21:3 | __synth__0__1 | | local_dataflow.rb:19:1:21:3 | __synth__0__1 | local_dataflow.rb:19:1:21:3 | __synth__0__1 | +| local_dataflow.rb:19:1:21:3 | __synth__0__1 | local_dataflow.rb:19:5:19:5 | x | +| local_dataflow.rb:19:5:19:5 | x | local_dataflow.rb:20:6:20:6 | x | | local_dataflow.rb:20:6:20:6 | x | local_dataflow.rb:20:6:20:10 | ... > ... | | local_dataflow.rb:20:10:20:10 | 1 | local_dataflow.rb:20:6:20:10 | ... > ... | | local_dataflow.rb:24:2:24:8 | break | local_dataflow.rb:23:1:25:3 | while ... | @@ -2889,7 +2889,7 @@ | local_dataflow.rb:28:15:28:22 | "module" | local_dataflow.rb:28:5:28:26 | M | | local_dataflow.rb:30:5:30:24 | C | local_dataflow.rb:30:1:30:24 | ... = ... | | local_dataflow.rb:30:14:30:20 | "class" | local_dataflow.rb:30:5:30:24 | C | -| local_dataflow.rb:32:5:32:25 | bar | local_dataflow.rb:32:1:32:25 | ... = ... | +| local_dataflow.rb:32:5:32:25 | bar | local_dataflow.rb:32:1:32:1 | x | | local_dataflow.rb:32:5:32:25 | bar | local_dataflow.rb:32:1:32:25 | ... = ... | | local_dataflow.rb:34:7:34:7 | x | local_dataflow.rb:34:7:34:7 | x | | local_dataflow.rb:34:7:34:7 | x | local_dataflow.rb:35:6:35:6 | x | @@ -2943,9 +2943,9 @@ | local_dataflow.rb:73:7:73:7 | x | local_dataflow.rb:72:7:73:7 | then ... | | local_dataflow.rb:74:3:75:6 | else ... | local_dataflow.rb:69:7:76:5 | case ... | | local_dataflow.rb:75:6:75:6 | x | local_dataflow.rb:74:3:75:6 | else ... | -| local_dataflow.rb:78:3:88:5 | ... = ... | local_dataflow.rb:89:8:89:8 | z | +| local_dataflow.rb:78:3:78:3 | z | local_dataflow.rb:89:8:89:8 | z | | local_dataflow.rb:78:7:88:5 | SSA phi read(self) | local_dataflow.rb:89:3:89:9 | self | -| local_dataflow.rb:78:7:88:5 | case ... | local_dataflow.rb:78:3:88:5 | ... = ... | +| local_dataflow.rb:78:7:88:5 | case ... | local_dataflow.rb:78:3:78:3 | z | | local_dataflow.rb:78:7:88:5 | case ... | local_dataflow.rb:78:3:88:5 | ... = ... | | local_dataflow.rb:78:12:78:20 | [post] self | local_dataflow.rb:79:20:79:26 | self | | local_dataflow.rb:78:12:78:20 | [post] self | local_dataflow.rb:80:24:80:30 | self | @@ -3000,18 +3000,18 @@ | local_dataflow.rb:87:29:87:29 | x | local_dataflow.rb:87:15:87:48 | then ... | | local_dataflow.rb:92:1:109:3 | self (and_or) | local_dataflow.rb:93:7:93:15 | self | | local_dataflow.rb:92:1:109:3 | self in and_or | local_dataflow.rb:92:1:109:3 | self (and_or) | -| local_dataflow.rb:93:3:93:28 | ... = ... | local_dataflow.rb:94:8:94:8 | a | +| local_dataflow.rb:93:3:93:3 | a | local_dataflow.rb:94:8:94:8 | a | | local_dataflow.rb:93:7:93:15 | [post] self | local_dataflow.rb:93:20:93:28 | self | | local_dataflow.rb:93:7:93:15 | call to source | local_dataflow.rb:93:7:93:28 | ... \|\| ... | | local_dataflow.rb:93:7:93:15 | self | local_dataflow.rb:93:20:93:28 | self | -| local_dataflow.rb:93:7:93:28 | ... \|\| ... | local_dataflow.rb:93:3:93:28 | ... = ... | +| local_dataflow.rb:93:7:93:28 | ... \|\| ... | local_dataflow.rb:93:3:93:3 | a | | local_dataflow.rb:93:7:93:28 | ... \|\| ... | local_dataflow.rb:93:3:93:28 | ... = ... | | local_dataflow.rb:93:7:93:28 | SSA phi read(self) | local_dataflow.rb:94:3:94:9 | self | | local_dataflow.rb:93:20:93:28 | call to source | local_dataflow.rb:93:7:93:28 | ... \|\| ... | | local_dataflow.rb:94:3:94:9 | [post] self | local_dataflow.rb:95:8:95:16 | self | | local_dataflow.rb:94:3:94:9 | self | local_dataflow.rb:95:8:95:16 | self | -| local_dataflow.rb:95:3:95:30 | ... = ... | local_dataflow.rb:96:8:96:8 | b | -| local_dataflow.rb:95:7:95:30 | ( ... ) | local_dataflow.rb:95:3:95:30 | ... = ... | +| local_dataflow.rb:95:3:95:3 | b | local_dataflow.rb:96:8:96:8 | b | +| local_dataflow.rb:95:7:95:30 | ( ... ) | local_dataflow.rb:95:3:95:3 | b | | local_dataflow.rb:95:7:95:30 | ( ... ) | local_dataflow.rb:95:3:95:30 | ... = ... | | local_dataflow.rb:95:8:95:16 | [post] self | local_dataflow.rb:95:21:95:29 | self | | local_dataflow.rb:95:8:95:16 | call to source | local_dataflow.rb:95:8:95:29 | ... or ... | @@ -3021,18 +3021,18 @@ | local_dataflow.rb:95:21:95:29 | call to source | local_dataflow.rb:95:8:95:29 | ... or ... | | local_dataflow.rb:96:3:96:9 | [post] self | local_dataflow.rb:98:7:98:15 | self | | local_dataflow.rb:96:3:96:9 | self | local_dataflow.rb:98:7:98:15 | self | -| local_dataflow.rb:98:3:98:28 | ... = ... | local_dataflow.rb:99:8:99:8 | a | +| local_dataflow.rb:98:3:98:3 | a | local_dataflow.rb:99:8:99:8 | a | | local_dataflow.rb:98:7:98:15 | [post] self | local_dataflow.rb:98:20:98:28 | self | | local_dataflow.rb:98:7:98:15 | call to source | local_dataflow.rb:98:7:98:28 | ... && ... | | local_dataflow.rb:98:7:98:15 | self | local_dataflow.rb:98:20:98:28 | self | -| local_dataflow.rb:98:7:98:28 | ... && ... | local_dataflow.rb:98:3:98:28 | ... = ... | +| local_dataflow.rb:98:7:98:28 | ... && ... | local_dataflow.rb:98:3:98:3 | a | | local_dataflow.rb:98:7:98:28 | ... && ... | local_dataflow.rb:98:3:98:28 | ... = ... | | local_dataflow.rb:98:7:98:28 | SSA phi read(self) | local_dataflow.rb:99:3:99:9 | self | | local_dataflow.rb:98:20:98:28 | call to source | local_dataflow.rb:98:7:98:28 | ... && ... | | local_dataflow.rb:99:3:99:9 | [post] self | local_dataflow.rb:100:8:100:16 | self | | local_dataflow.rb:99:3:99:9 | self | local_dataflow.rb:100:8:100:16 | self | -| local_dataflow.rb:100:3:100:31 | ... = ... | local_dataflow.rb:101:8:101:8 | b | -| local_dataflow.rb:100:7:100:31 | ( ... ) | local_dataflow.rb:100:3:100:31 | ... = ... | +| local_dataflow.rb:100:3:100:3 | b | local_dataflow.rb:101:8:101:8 | b | +| local_dataflow.rb:100:7:100:31 | ( ... ) | local_dataflow.rb:100:3:100:3 | b | | local_dataflow.rb:100:7:100:31 | ( ... ) | local_dataflow.rb:100:3:100:31 | ... = ... | | local_dataflow.rb:100:8:100:16 | [post] self | local_dataflow.rb:100:22:100:30 | self | | local_dataflow.rb:100:8:100:16 | call to source | local_dataflow.rb:100:8:100:30 | ... and ... | @@ -3042,27 +3042,27 @@ | local_dataflow.rb:100:22:100:30 | call to source | local_dataflow.rb:100:8:100:30 | ... and ... | | local_dataflow.rb:101:3:101:9 | [post] self | local_dataflow.rb:103:7:103:15 | self | | local_dataflow.rb:101:3:101:9 | self | local_dataflow.rb:103:7:103:15 | self | -| local_dataflow.rb:103:3:103:15 | ... = ... | local_dataflow.rb:104:3:104:3 | a | +| local_dataflow.rb:103:3:103:3 | a | local_dataflow.rb:104:3:104:3 | a | | local_dataflow.rb:103:7:103:15 | [post] self | local_dataflow.rb:104:9:104:17 | self | -| local_dataflow.rb:103:7:103:15 | call to source | local_dataflow.rb:103:3:103:15 | ... = ... | +| local_dataflow.rb:103:7:103:15 | call to source | local_dataflow.rb:103:3:103:3 | a | | local_dataflow.rb:103:7:103:15 | call to source | local_dataflow.rb:103:3:103:15 | ... = ... | | local_dataflow.rb:103:7:103:15 | self | local_dataflow.rb:104:9:104:17 | self | | local_dataflow.rb:104:3:104:3 | a | local_dataflow.rb:104:5:104:7 | ... \|\| ... | -| local_dataflow.rb:104:3:104:17 | ... = ... | local_dataflow.rb:105:8:105:8 | a | -| local_dataflow.rb:104:5:104:7 | ... \|\| ... | local_dataflow.rb:104:3:104:17 | ... = ... | +| local_dataflow.rb:104:3:104:3 | a | local_dataflow.rb:105:8:105:8 | a | +| local_dataflow.rb:104:5:104:7 | ... \|\| ... | local_dataflow.rb:104:3:104:3 | a | | local_dataflow.rb:104:5:104:7 | ... \|\| ... | local_dataflow.rb:104:3:104:17 | ... = ... | | local_dataflow.rb:104:5:104:7 | SSA phi read(self) | local_dataflow.rb:105:3:105:9 | self | | local_dataflow.rb:104:9:104:17 | call to source | local_dataflow.rb:104:5:104:7 | ... \|\| ... | | local_dataflow.rb:105:3:105:9 | [post] self | local_dataflow.rb:106:7:106:15 | self | | local_dataflow.rb:105:3:105:9 | self | local_dataflow.rb:106:7:106:15 | self | -| local_dataflow.rb:106:3:106:15 | ... = ... | local_dataflow.rb:107:3:107:3 | b | +| local_dataflow.rb:106:3:106:3 | b | local_dataflow.rb:107:3:107:3 | b | | local_dataflow.rb:106:7:106:15 | [post] self | local_dataflow.rb:107:9:107:17 | self | -| local_dataflow.rb:106:7:106:15 | call to source | local_dataflow.rb:106:3:106:15 | ... = ... | +| local_dataflow.rb:106:7:106:15 | call to source | local_dataflow.rb:106:3:106:3 | b | | local_dataflow.rb:106:7:106:15 | call to source | local_dataflow.rb:106:3:106:15 | ... = ... | | local_dataflow.rb:106:7:106:15 | self | local_dataflow.rb:107:9:107:17 | self | | local_dataflow.rb:107:3:107:3 | b | local_dataflow.rb:107:5:107:7 | ... && ... | -| local_dataflow.rb:107:3:107:17 | ... = ... | local_dataflow.rb:108:8:108:8 | b | -| local_dataflow.rb:107:5:107:7 | ... && ... | local_dataflow.rb:107:3:107:17 | ... = ... | +| local_dataflow.rb:107:3:107:3 | b | local_dataflow.rb:108:8:108:8 | b | +| local_dataflow.rb:107:5:107:7 | ... && ... | local_dataflow.rb:107:3:107:3 | b | | local_dataflow.rb:107:5:107:7 | ... && ... | local_dataflow.rb:107:3:107:17 | ... = ... | | local_dataflow.rb:107:5:107:7 | SSA phi read(self) | local_dataflow.rb:108:3:108:9 | self | | local_dataflow.rb:107:9:107:17 | call to source | local_dataflow.rb:107:5:107:7 | ... && ... | @@ -3106,8 +3106,8 @@ | 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:3:131:3 | x | local_dataflow.rb:132:10:132:10 | x | +| local_dataflow.rb:131:7:131:8 | "" | local_dataflow.rb:131:3:131:3 | x | | 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 | 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 12db100a968..3b459c4a3e6 100644 --- a/ruby/ql/test/library-tests/dataflow/params/params-flow.expected +++ b/ruby/ql/test/library-tests/dataflow/params/params-flow.expected @@ -22,17 +22,21 @@ edges | params_flow.rb:33:12:33:19 | call to taint : | params_flow.rb:25:12:25:13 | p1 : | | params_flow.rb:33:26:33:34 | call to taint : | params_flow.rb:25:17:25:24 | **kwargs [element :p2] : | | params_flow.rb:33:41:33:49 | call to taint : | params_flow.rb:25:17:25:24 | **kwargs [element :p3] : | -| params_flow.rb:34:14:34:22 | call to taint : | params_flow.rb:35:25:35:28 | args [element :p3] : | +| params_flow.rb:34:1:34:4 | args [element :p3] : | params_flow.rb:35:25:35:28 | args [element :p3] : | +| params_flow.rb:34:14:34:22 | call to taint : | params_flow.rb:34:1:34:4 | args [element :p3] : | | params_flow.rb:35:12:35:20 | call to taint : | params_flow.rb:25:12:25:13 | p1 : | | params_flow.rb:35:23:35:28 | ** ... [element :p3] : | params_flow.rb:25:17:25:24 | **kwargs [element :p3] : | | params_flow.rb:35:25:35:28 | args [element :p3] : | params_flow.rb:35:23:35:28 | ** ... [element :p3] : | -| params_flow.rb:37:16:37:24 | call to taint : | params_flow.rb:38:10:38:13 | args [element :p1] : | -| params_flow.rb:37:34:37:42 | call to taint : | params_flow.rb:38:10:38:13 | args [element :p2] : | +| params_flow.rb:37:1:37:4 | args [element :p1] : | params_flow.rb:38:10:38:13 | args [element :p1] : | +| params_flow.rb:37:1:37:4 | args [element :p2] : | params_flow.rb:38:10:38:13 | args [element :p2] : | +| params_flow.rb:37:16:37:24 | call to taint : | params_flow.rb:37:1:37:4 | args [element :p1] : | +| params_flow.rb:37:34:37:42 | call to taint : | params_flow.rb:37:1:37:4 | args [element :p2] : | | params_flow.rb:38:8:38:13 | ** ... [element :p1] : | params_flow.rb:25:12:25:13 | p1 : | | params_flow.rb:38:8:38:13 | ** ... [element :p2] : | params_flow.rb:25:17:25:24 | **kwargs [element :p2] : | | params_flow.rb:38:10:38:13 | args [element :p1] : | params_flow.rb:38:8:38:13 | ** ... [element :p1] : | | params_flow.rb:38:10:38:13 | args [element :p2] : | params_flow.rb:38:8:38:13 | ** ... [element :p2] : | -| params_flow.rb:40:16:40:24 | call to taint : | params_flow.rb:41:26:41:29 | args [element :p1] : | +| params_flow.rb:40:1:40:4 | args [element :p1] : | params_flow.rb:41:26:41:29 | args [element :p1] : | +| params_flow.rb:40:16:40:24 | call to taint : | params_flow.rb:40:1:40:4 | args [element :p1] : | | params_flow.rb:41:13:41:21 | call to taint : | params_flow.rb:16:18:16:19 | p2 : | | params_flow.rb:41:24:41:29 | ** ... [element :p1] : | params_flow.rb:16:13:16:14 | p1 : | | params_flow.rb:41:26:41:29 | args [element :p1] : | params_flow.rb:41:24:41:29 | ** ... [element :p1] : | @@ -40,7 +44,8 @@ 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:62:1:62:4 | args : | params_flow.rb:66:13:66:16 | args : | +| params_flow.rb:62:8:62:16 | call to taint : | params_flow.rb:62:1:62:4 | 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] : | @@ -75,16 +80,20 @@ nodes | params_flow.rb:33:12:33:19 | call to taint : | semmle.label | call to taint : | | params_flow.rb:33:26:33:34 | call to taint : | semmle.label | call to taint : | | params_flow.rb:33:41:33:49 | call to taint : | semmle.label | call to taint : | +| params_flow.rb:34:1:34:4 | args [element :p3] : | semmle.label | args [element :p3] : | | params_flow.rb:34:14:34:22 | call to taint : | semmle.label | call to taint : | | params_flow.rb:35:12:35:20 | call to taint : | semmle.label | call to taint : | | params_flow.rb:35:23:35:28 | ** ... [element :p3] : | semmle.label | ** ... [element :p3] : | | params_flow.rb:35:25:35:28 | args [element :p3] : | semmle.label | args [element :p3] : | +| params_flow.rb:37:1:37:4 | args [element :p1] : | semmle.label | args [element :p1] : | +| params_flow.rb:37:1:37:4 | args [element :p2] : | semmle.label | args [element :p2] : | | params_flow.rb:37:16:37:24 | call to taint : | semmle.label | call to taint : | | params_flow.rb:37:34:37:42 | call to taint : | semmle.label | call to taint : | | params_flow.rb:38:8:38:13 | ** ... [element :p1] : | semmle.label | ** ... [element :p1] : | | params_flow.rb:38:8:38:13 | ** ... [element :p2] : | semmle.label | ** ... [element :p2] : | | params_flow.rb:38:10:38:13 | args [element :p1] : | semmle.label | args [element :p1] : | | params_flow.rb:38:10:38:13 | args [element :p2] : | semmle.label | args [element :p2] : | +| params_flow.rb:40:1:40:4 | args [element :p1] : | semmle.label | args [element :p1] : | | params_flow.rb:40:16:40:24 | call to taint : | semmle.label | call to taint : | | params_flow.rb:41:13:41:21 | call to taint : | semmle.label | call to taint : | | params_flow.rb:41:24:41:29 | ** ... [element :p1] : | semmle.label | ** ... [element :p1] : | @@ -94,6 +103,7 @@ 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:1:62:4 | args : | semmle.label | args : | | 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] : | diff --git a/ruby/ql/test/library-tests/dataflow/pathname-flow/pathame-flow.expected b/ruby/ql/test/library-tests/dataflow/pathname-flow/pathame-flow.expected index a13e860bd04..b248ef21157 100644 --- a/ruby/ql/test/library-tests/dataflow/pathname-flow/pathame-flow.expected +++ b/ruby/ql/test/library-tests/dataflow/pathname-flow/pathame-flow.expected @@ -1,216 +1,290 @@ failures edges -| pathname_flow.rb:4:10:4:33 | call to new : | pathname_flow.rb:5:10:5:11 | pn | +| pathname_flow.rb:4:5:4:6 | pn : | pathname_flow.rb:5:10:5:11 | pn | +| pathname_flow.rb:4:10:4:33 | call to new : | pathname_flow.rb:4:5:4:6 | pn : | | pathname_flow.rb:4:23:4:32 | call to source : | pathname_flow.rb:4:10:4:33 | call to new : | -| pathname_flow.rb:9:7:9:30 | call to new : | pathname_flow.rb:11:8:11:12 | ... + ... | +| pathname_flow.rb:9:3:9:3 | a : | pathname_flow.rb:11:8:11:12 | ... + ... | +| pathname_flow.rb:9:7:9:30 | call to new : | pathname_flow.rb:9:3:9:3 | a : | | pathname_flow.rb:9:20:9:29 | call to source : | pathname_flow.rb:9:7:9:30 | call to new : | -| pathname_flow.rb:10:7:10:30 | call to new : | pathname_flow.rb:11:8:11:12 | ... + ... | +| pathname_flow.rb:10:3:10:3 | b : | pathname_flow.rb:11:8:11:12 | ... + ... | +| pathname_flow.rb:10:7:10:30 | call to new : | pathname_flow.rb:10:3:10:3 | b : | | pathname_flow.rb:10:20:10:29 | call to source : | pathname_flow.rb:10:7:10:30 | call to new : | -| pathname_flow.rb:15:8:15:31 | call to new : | pathname_flow.rb:16:8:16:9 | pn : | +| pathname_flow.rb:15:3:15:4 | pn : | pathname_flow.rb:16:8:16:9 | pn : | +| pathname_flow.rb:15:8:15:31 | call to new : | pathname_flow.rb:15:3:15:4 | pn : | | pathname_flow.rb:15:21:15:30 | call to source : | pathname_flow.rb:15:8:15:31 | call to new : | | pathname_flow.rb:16:8:16:9 | pn : | pathname_flow.rb:16:8:16:17 | call to dirname | -| pathname_flow.rb:20:7:20:30 | call to new : | pathname_flow.rb:21:3:21:3 | a : | +| pathname_flow.rb:20:3:20:3 | a : | pathname_flow.rb:21:3:21:3 | a : | +| pathname_flow.rb:20:7:20:30 | call to new : | pathname_flow.rb:20:3:20:3 | a : | | pathname_flow.rb:20:20:20:29 | call to source : | pathname_flow.rb:20:7:20:30 | call to new : | | pathname_flow.rb:21:3:21:3 | a : | pathname_flow.rb:21:23:21:23 | x : | | pathname_flow.rb:21:23:21:23 | x : | pathname_flow.rb:22:10:22:10 | x | -| pathname_flow.rb:27:7:27:30 | call to new : | pathname_flow.rb:28:8:28:8 | a : | +| pathname_flow.rb:27:3:27:3 | a : | pathname_flow.rb:28:8:28:8 | a : | +| pathname_flow.rb:27:7:27:30 | call to new : | pathname_flow.rb:27:3:27:3 | a : | | pathname_flow.rb:27:20:27:29 | call to source : | pathname_flow.rb:27:7:27:30 | call to new : | | pathname_flow.rb:28:8:28:8 | a : | pathname_flow.rb:28:8:28:22 | call to expand_path | -| pathname_flow.rb:32:7:32:30 | call to new : | pathname_flow.rb:35:8:35:8 | a : | +| pathname_flow.rb:32:3:32:3 | a : | pathname_flow.rb:35:8:35:8 | a : | +| pathname_flow.rb:32:7:32:30 | call to new : | pathname_flow.rb:32:3:32:3 | a : | | pathname_flow.rb:32:20:32:29 | call to source : | pathname_flow.rb:32:7:32:30 | call to new : | -| pathname_flow.rb:34:7:34:30 | call to new : | pathname_flow.rb:35:18:35:18 | c : | +| pathname_flow.rb:34:3:34:3 | c : | pathname_flow.rb:35:18:35:18 | c : | +| pathname_flow.rb:34:7:34:30 | call to new : | pathname_flow.rb:34:3:34:3 | c : | | pathname_flow.rb:34:20:34:29 | call to source : | pathname_flow.rb:34:7:34:30 | call to new : | | pathname_flow.rb:35:8:35:8 | a : | pathname_flow.rb:35:8:35:19 | call to join | | pathname_flow.rb:35:18:35:18 | c : | pathname_flow.rb:35:8:35:19 | call to join | -| pathname_flow.rb:39:7:39:30 | call to new : | pathname_flow.rb:40:8:40:8 | a : | +| pathname_flow.rb:39:3:39:3 | a : | pathname_flow.rb:40:8:40:8 | a : | +| pathname_flow.rb:39:7:39:30 | call to new : | pathname_flow.rb:39:3:39:3 | a : | | pathname_flow.rb:39:20:39:29 | call to source : | pathname_flow.rb:39:7:39:30 | call to new : | | pathname_flow.rb:40:8:40:8 | a : | pathname_flow.rb:40:8:40:17 | call to parent | -| pathname_flow.rb:44:7:44:30 | call to new : | pathname_flow.rb:45:8:45:8 | a : | +| pathname_flow.rb:44:3:44:3 | a : | pathname_flow.rb:45:8:45:8 | a : | +| pathname_flow.rb:44:7:44:30 | call to new : | pathname_flow.rb:44:3:44:3 | a : | | pathname_flow.rb:44:20:44:29 | call to source : | pathname_flow.rb:44:7:44:30 | call to new : | | pathname_flow.rb:45:8:45:8 | a : | pathname_flow.rb:45:8:45:19 | call to realpath | -| pathname_flow.rb:49:7:49:30 | call to new : | pathname_flow.rb:50:8:50:8 | a : | +| pathname_flow.rb:49:3:49:3 | a : | pathname_flow.rb:50:8:50:8 | a : | +| pathname_flow.rb:49:7:49:30 | call to new : | pathname_flow.rb:49:3:49:3 | a : | | pathname_flow.rb:49:20:49:29 | call to source : | pathname_flow.rb:49:7:49:30 | call to new : | | pathname_flow.rb:50:8:50:8 | a : | pathname_flow.rb:50:8:50:39 | call to relative_path_from | -| pathname_flow.rb:54:7:54:30 | call to new : | pathname_flow.rb:55:8:55:8 | a : | +| pathname_flow.rb:54:3:54:3 | a : | pathname_flow.rb:55:8:55:8 | a : | +| pathname_flow.rb:54:7:54:30 | call to new : | pathname_flow.rb:54:3:54:3 | a : | | pathname_flow.rb:54:20:54:29 | call to source : | pathname_flow.rb:54:7:54:30 | call to new : | | pathname_flow.rb:55:8:55:8 | a : | pathname_flow.rb:55:8:55:16 | call to to_path | -| pathname_flow.rb:59:7:59:30 | call to new : | pathname_flow.rb:60:8:60:8 | a : | +| pathname_flow.rb:59:3:59:3 | a : | pathname_flow.rb:60:8:60:8 | a : | +| pathname_flow.rb:59:7:59:30 | call to new : | pathname_flow.rb:59:3:59:3 | a : | | pathname_flow.rb:59:20:59:29 | call to source : | pathname_flow.rb:59:7:59:30 | call to new : | | pathname_flow.rb:60:8:60:8 | a : | pathname_flow.rb:60:8:60:13 | call to to_s | -| pathname_flow.rb:64:7:64:30 | call to new : | pathname_flow.rb:66:8:66:8 | b | +| pathname_flow.rb:64:3:64:3 | a : | pathname_flow.rb:65:3:65:3 | b : | +| pathname_flow.rb:64:7:64:30 | call to new : | pathname_flow.rb:64:3:64:3 | a : | | pathname_flow.rb:64:20:64:29 | call to source : | pathname_flow.rb:64:7:64:30 | call to new : | -| pathname_flow.rb:70:7:70:30 | call to new : | pathname_flow.rb:72:8:72:8 | b | +| pathname_flow.rb:65:3:65:3 | b : | pathname_flow.rb:66:8:66:8 | b | +| pathname_flow.rb:70:3:70:3 | a : | pathname_flow.rb:71:3:71:3 | b : | +| pathname_flow.rb:70:7:70:30 | call to new : | pathname_flow.rb:70:3:70:3 | a : | | pathname_flow.rb:70:20:70:29 | call to source : | pathname_flow.rb:70:7:70:30 | call to new : | -| pathname_flow.rb:76:7:76:30 | call to new : | pathname_flow.rb:77:7:77:7 | a : | +| pathname_flow.rb:71:3:71:3 | b : | pathname_flow.rb:72:8:72:8 | b | +| pathname_flow.rb:76:3:76:3 | a : | pathname_flow.rb:77:7:77:7 | a : | +| pathname_flow.rb:76:7:76:30 | call to new : | pathname_flow.rb:76:3:76:3 | a : | | pathname_flow.rb:76:20:76:29 | call to source : | pathname_flow.rb:76:7:76:30 | call to new : | +| pathname_flow.rb:77:3:77:3 | b : | pathname_flow.rb:78:8:78:8 | b | | pathname_flow.rb:77:7:77:7 | a : | pathname_flow.rb:77:7:77:16 | call to basename : | -| pathname_flow.rb:77:7:77:16 | call to basename : | pathname_flow.rb:78:8:78:8 | b | -| pathname_flow.rb:82:7:82:30 | call to new : | pathname_flow.rb:83:7:83:7 | a : | +| pathname_flow.rb:77:7:77:16 | call to basename : | pathname_flow.rb:77:3:77:3 | b : | +| pathname_flow.rb:82:3:82:3 | a : | pathname_flow.rb:83:7:83:7 | a : | +| pathname_flow.rb:82:7:82:30 | call to new : | pathname_flow.rb:82:3:82:3 | a : | | pathname_flow.rb:82:20:82:29 | call to source : | pathname_flow.rb:82:7:82:30 | call to new : | +| pathname_flow.rb:83:3:83:3 | b : | pathname_flow.rb:84:8:84:8 | b | | pathname_flow.rb:83:7:83:7 | a : | pathname_flow.rb:83:7:83:17 | call to cleanpath : | -| pathname_flow.rb:83:7:83:17 | call to cleanpath : | pathname_flow.rb:84:8:84:8 | b | -| pathname_flow.rb:88:7:88:30 | call to new : | pathname_flow.rb:89:7:89:7 | a : | +| pathname_flow.rb:83:7:83:17 | call to cleanpath : | pathname_flow.rb:83:3:83:3 | b : | +| pathname_flow.rb:88:3:88:3 | a : | pathname_flow.rb:89:7:89:7 | a : | +| pathname_flow.rb:88:7:88:30 | call to new : | pathname_flow.rb:88:3:88:3 | a : | | pathname_flow.rb:88:20:88:29 | call to source : | pathname_flow.rb:88:7:88:30 | call to new : | +| pathname_flow.rb:89:3:89:3 | b : | pathname_flow.rb:90:8:90:8 | b | | pathname_flow.rb:89:7:89:7 | a : | pathname_flow.rb:89:7:89:25 | call to sub : | -| pathname_flow.rb:89:7:89:25 | call to sub : | pathname_flow.rb:90:8:90:8 | b | -| pathname_flow.rb:94:7:94:30 | call to new : | pathname_flow.rb:95:7:95:7 | a : | +| pathname_flow.rb:89:7:89:25 | call to sub : | pathname_flow.rb:89:3:89:3 | b : | +| pathname_flow.rb:94:3:94:3 | a : | pathname_flow.rb:95:7:95:7 | a : | +| pathname_flow.rb:94:7:94:30 | call to new : | pathname_flow.rb:94:3:94:3 | a : | | pathname_flow.rb:94:20:94:29 | call to source : | pathname_flow.rb:94:7:94:30 | call to new : | +| pathname_flow.rb:95:3:95:3 | b : | pathname_flow.rb:96:8:96:8 | b | | pathname_flow.rb:95:7:95:7 | a : | pathname_flow.rb:95:7:95:23 | call to sub_ext : | -| pathname_flow.rb:95:7:95:23 | call to sub_ext : | pathname_flow.rb:96:8:96:8 | b | -| pathname_flow.rb:101:7:101:30 | call to new : | pathname_flow.rb:104:8:104:8 | b : | -| pathname_flow.rb:101:7:101:30 | call to new : | pathname_flow.rb:107:8:107:8 | c : | -| pathname_flow.rb:101:7:101:30 | call to new : | pathname_flow.rb:109:7:109:7 | a : | -| pathname_flow.rb:101:7:101:30 | call to new : | pathname_flow.rb:112:7:112:7 | a : | -| pathname_flow.rb:101:7:101:30 | call to new : | pathname_flow.rb:115:7:115:7 | a : | -| pathname_flow.rb:101:7:101:30 | call to new : | pathname_flow.rb:118:7:118:7 | a : | -| pathname_flow.rb:101:7:101:30 | call to new : | pathname_flow.rb:121:7:121:7 | a : | -| pathname_flow.rb:101:7:101:30 | call to new : | pathname_flow.rb:124:7:124:7 | a : | -| pathname_flow.rb:101:7:101:30 | call to new : | pathname_flow.rb:127:7:127:7 | a : | -| pathname_flow.rb:101:7:101:30 | call to new : | pathname_flow.rb:130:7:130:7 | a : | -| pathname_flow.rb:101:7:101:30 | call to new : | pathname_flow.rb:133:7:133:7 | a : | +| pathname_flow.rb:95:7:95:23 | call to sub_ext : | pathname_flow.rb:95:3:95:3 | b : | +| pathname_flow.rb:101:3:101:3 | a : | pathname_flow.rb:103:3:103:3 | b : | +| pathname_flow.rb:101:3:101:3 | a : | pathname_flow.rb:106:3:106:3 | c : | +| pathname_flow.rb:101:3:101:3 | a : | pathname_flow.rb:109:7:109:7 | a : | +| pathname_flow.rb:101:3:101:3 | a : | pathname_flow.rb:112:7:112:7 | a : | +| pathname_flow.rb:101:3:101:3 | a : | pathname_flow.rb:115:7:115:7 | a : | +| pathname_flow.rb:101:3:101:3 | a : | pathname_flow.rb:118:7:118:7 | a : | +| pathname_flow.rb:101:3:101:3 | a : | pathname_flow.rb:121:7:121:7 | a : | +| pathname_flow.rb:101:3:101:3 | a : | pathname_flow.rb:124:7:124:7 | a : | +| pathname_flow.rb:101:3:101:3 | a : | pathname_flow.rb:127:7:127:7 | a : | +| pathname_flow.rb:101:3:101:3 | a : | pathname_flow.rb:130:7:130:7 | a : | +| pathname_flow.rb:101:3:101:3 | a : | pathname_flow.rb:133:7:133:7 | a : | +| pathname_flow.rb:101:7:101:30 | call to new : | pathname_flow.rb:101:3:101:3 | a : | | pathname_flow.rb:101:20:101:29 | call to source : | pathname_flow.rb:101:7:101:30 | call to new : | +| pathname_flow.rb:103:3:103:3 | b : | pathname_flow.rb:104:8:104:8 | b : | | pathname_flow.rb:104:8:104:8 | b : | pathname_flow.rb:104:8:104:17 | call to realpath | +| pathname_flow.rb:106:3:106:3 | c : | pathname_flow.rb:107:8:107:8 | c : | | pathname_flow.rb:107:8:107:8 | c : | pathname_flow.rb:107:8:107:17 | call to realpath | +| pathname_flow.rb:109:3:109:3 | d : | pathname_flow.rb:110:8:110:8 | d : | | pathname_flow.rb:109:7:109:7 | a : | pathname_flow.rb:109:7:109:16 | call to basename : | -| pathname_flow.rb:109:7:109:16 | call to basename : | pathname_flow.rb:110:8:110:8 | d : | +| pathname_flow.rb:109:7:109:16 | call to basename : | pathname_flow.rb:109:3:109:3 | d : | | pathname_flow.rb:110:8:110:8 | d : | pathname_flow.rb:110:8:110:17 | call to realpath | +| pathname_flow.rb:112:3:112:3 | e : | pathname_flow.rb:113:8:113:8 | e : | | pathname_flow.rb:112:7:112:7 | a : | pathname_flow.rb:112:7:112:17 | call to cleanpath : | -| pathname_flow.rb:112:7:112:17 | call to cleanpath : | pathname_flow.rb:113:8:113:8 | e : | +| pathname_flow.rb:112:7:112:17 | call to cleanpath : | pathname_flow.rb:112:3:112:3 | e : | | pathname_flow.rb:113:8:113:8 | e : | pathname_flow.rb:113:8:113:17 | call to realpath | +| pathname_flow.rb:115:3:115:3 | f : | pathname_flow.rb:116:8:116:8 | f : | | pathname_flow.rb:115:7:115:7 | a : | pathname_flow.rb:115:7:115:19 | call to expand_path : | -| pathname_flow.rb:115:7:115:19 | call to expand_path : | pathname_flow.rb:116:8:116:8 | f : | +| pathname_flow.rb:115:7:115:19 | call to expand_path : | pathname_flow.rb:115:3:115:3 | f : | | pathname_flow.rb:116:8:116:8 | f : | pathname_flow.rb:116:8:116:17 | call to realpath | +| pathname_flow.rb:118:3:118:3 | g : | pathname_flow.rb:119:8:119:8 | g : | | pathname_flow.rb:118:7:118:7 | a : | pathname_flow.rb:118:7:118:19 | call to join : | -| pathname_flow.rb:118:7:118:19 | call to join : | pathname_flow.rb:119:8:119:8 | g : | +| pathname_flow.rb:118:7:118:19 | call to join : | pathname_flow.rb:118:3:118:3 | g : | | pathname_flow.rb:119:8:119:8 | g : | pathname_flow.rb:119:8:119:17 | call to realpath | +| pathname_flow.rb:121:3:121:3 | h : | pathname_flow.rb:122:8:122:8 | h : | | pathname_flow.rb:121:7:121:7 | a : | pathname_flow.rb:121:7:121:16 | call to realpath : | -| pathname_flow.rb:121:7:121:16 | call to realpath : | pathname_flow.rb:122:8:122:8 | h : | +| pathname_flow.rb:121:7:121:16 | call to realpath : | pathname_flow.rb:121:3:121:3 | h : | | pathname_flow.rb:122:8:122:8 | h : | pathname_flow.rb:122:8:122:17 | call to realpath | +| pathname_flow.rb:124:3:124:3 | i : | pathname_flow.rb:125:8:125:8 | i : | | pathname_flow.rb:124:7:124:7 | a : | pathname_flow.rb:124:7:124:38 | call to relative_path_from : | -| pathname_flow.rb:124:7:124:38 | call to relative_path_from : | pathname_flow.rb:125:8:125:8 | i : | +| pathname_flow.rb:124:7:124:38 | call to relative_path_from : | pathname_flow.rb:124:3:124:3 | i : | | pathname_flow.rb:125:8:125:8 | i : | pathname_flow.rb:125:8:125:17 | call to realpath | +| pathname_flow.rb:127:3:127:3 | j : | pathname_flow.rb:128:8:128:8 | j : | | pathname_flow.rb:127:7:127:7 | a : | pathname_flow.rb:127:7:127:25 | call to sub : | -| pathname_flow.rb:127:7:127:25 | call to sub : | pathname_flow.rb:128:8:128:8 | j : | +| pathname_flow.rb:127:7:127:25 | call to sub : | pathname_flow.rb:127:3:127:3 | j : | | pathname_flow.rb:128:8:128:8 | j : | pathname_flow.rb:128:8:128:17 | call to realpath | +| pathname_flow.rb:130:3:130:3 | k : | pathname_flow.rb:131:8:131:8 | k : | | pathname_flow.rb:130:7:130:7 | a : | pathname_flow.rb:130:7:130:23 | call to sub_ext : | -| pathname_flow.rb:130:7:130:23 | call to sub_ext : | pathname_flow.rb:131:8:131:8 | k : | +| pathname_flow.rb:130:7:130:23 | call to sub_ext : | pathname_flow.rb:130:3:130:3 | k : | | pathname_flow.rb:131:8:131:8 | k : | pathname_flow.rb:131:8:131:17 | call to realpath | +| pathname_flow.rb:133:3:133:3 | l : | pathname_flow.rb:134:8:134:8 | l : | | pathname_flow.rb:133:7:133:7 | a : | pathname_flow.rb:133:7:133:15 | call to to_path : | -| pathname_flow.rb:133:7:133:15 | call to to_path : | pathname_flow.rb:134:8:134:8 | l : | +| pathname_flow.rb:133:7:133:15 | call to to_path : | pathname_flow.rb:133:3:133:3 | l : | | pathname_flow.rb:134:8:134:8 | l : | pathname_flow.rb:134:8:134:17 | call to realpath | nodes +| pathname_flow.rb:4:5:4:6 | pn : | semmle.label | pn : | | pathname_flow.rb:4:10:4:33 | call to new : | semmle.label | call to new : | | pathname_flow.rb:4:23:4:32 | call to source : | semmle.label | call to source : | | pathname_flow.rb:5:10:5:11 | pn | semmle.label | pn | +| pathname_flow.rb:9:3:9:3 | a : | semmle.label | a : | | pathname_flow.rb:9:7:9:30 | call to new : | semmle.label | call to new : | | pathname_flow.rb:9:20:9:29 | call to source : | semmle.label | call to source : | +| pathname_flow.rb:10:3:10:3 | b : | semmle.label | b : | | pathname_flow.rb:10:7:10:30 | call to new : | semmle.label | call to new : | | pathname_flow.rb:10:20:10:29 | call to source : | semmle.label | call to source : | | pathname_flow.rb:11:8:11:12 | ... + ... | semmle.label | ... + ... | +| pathname_flow.rb:15:3:15:4 | pn : | semmle.label | pn : | | pathname_flow.rb:15:8:15:31 | call to new : | semmle.label | call to new : | | pathname_flow.rb:15:21:15:30 | call to source : | semmle.label | call to source : | | pathname_flow.rb:16:8:16:9 | pn : | semmle.label | pn : | | pathname_flow.rb:16:8:16:17 | call to dirname | semmle.label | call to dirname | +| pathname_flow.rb:20:3:20:3 | a : | semmle.label | a : | | pathname_flow.rb:20:7:20:30 | call to new : | semmle.label | call to new : | | pathname_flow.rb:20:20:20:29 | call to source : | semmle.label | call to source : | | pathname_flow.rb:21:3:21:3 | a : | semmle.label | a : | | pathname_flow.rb:21:23:21:23 | x : | semmle.label | x : | | pathname_flow.rb:22:10:22:10 | x | semmle.label | x | +| pathname_flow.rb:27:3:27:3 | a : | semmle.label | a : | | pathname_flow.rb:27:7:27:30 | call to new : | semmle.label | call to new : | | pathname_flow.rb:27:20:27:29 | call to source : | semmle.label | call to source : | | pathname_flow.rb:28:8:28:8 | a : | semmle.label | a : | | pathname_flow.rb:28:8:28:22 | call to expand_path | semmle.label | call to expand_path | +| pathname_flow.rb:32:3:32:3 | a : | semmle.label | a : | | pathname_flow.rb:32:7:32:30 | call to new : | semmle.label | call to new : | | pathname_flow.rb:32:20:32:29 | call to source : | semmle.label | call to source : | +| pathname_flow.rb:34:3:34:3 | c : | semmle.label | c : | | pathname_flow.rb:34:7:34:30 | call to new : | semmle.label | call to new : | | pathname_flow.rb:34:20:34:29 | call to source : | semmle.label | call to source : | | pathname_flow.rb:35:8:35:8 | a : | semmle.label | a : | | pathname_flow.rb:35:8:35:19 | call to join | semmle.label | call to join | | pathname_flow.rb:35:18:35:18 | c : | semmle.label | c : | +| pathname_flow.rb:39:3:39:3 | a : | semmle.label | a : | | pathname_flow.rb:39:7:39:30 | call to new : | semmle.label | call to new : | | pathname_flow.rb:39:20:39:29 | call to source : | semmle.label | call to source : | | pathname_flow.rb:40:8:40:8 | a : | semmle.label | a : | | pathname_flow.rb:40:8:40:17 | call to parent | semmle.label | call to parent | +| pathname_flow.rb:44:3:44:3 | a : | semmle.label | a : | | pathname_flow.rb:44:7:44:30 | call to new : | semmle.label | call to new : | | pathname_flow.rb:44:20:44:29 | call to source : | semmle.label | call to source : | | pathname_flow.rb:45:8:45:8 | a : | semmle.label | a : | | pathname_flow.rb:45:8:45:19 | call to realpath | semmle.label | call to realpath | +| pathname_flow.rb:49:3:49:3 | a : | semmle.label | a : | | pathname_flow.rb:49:7:49:30 | call to new : | semmle.label | call to new : | | pathname_flow.rb:49:20:49:29 | call to source : | semmle.label | call to source : | | pathname_flow.rb:50:8:50:8 | a : | semmle.label | a : | | pathname_flow.rb:50:8:50:39 | call to relative_path_from | semmle.label | call to relative_path_from | +| pathname_flow.rb:54:3:54:3 | a : | semmle.label | a : | | pathname_flow.rb:54:7:54:30 | call to new : | semmle.label | call to new : | | pathname_flow.rb:54:20:54:29 | call to source : | semmle.label | call to source : | | pathname_flow.rb:55:8:55:8 | a : | semmle.label | a : | | pathname_flow.rb:55:8:55:16 | call to to_path | semmle.label | call to to_path | +| pathname_flow.rb:59:3:59:3 | a : | semmle.label | a : | | pathname_flow.rb:59:7:59:30 | call to new : | semmle.label | call to new : | | pathname_flow.rb:59:20:59:29 | call to source : | semmle.label | call to source : | | pathname_flow.rb:60:8:60:8 | a : | semmle.label | a : | | pathname_flow.rb:60:8:60:13 | call to to_s | semmle.label | call to to_s | +| pathname_flow.rb:64:3:64:3 | a : | semmle.label | a : | | pathname_flow.rb:64:7:64:30 | call to new : | semmle.label | call to new : | | pathname_flow.rb:64:20:64:29 | call to source : | semmle.label | call to source : | +| pathname_flow.rb:65:3:65:3 | b : | semmle.label | b : | | pathname_flow.rb:66:8:66:8 | b | semmle.label | b | +| pathname_flow.rb:70:3:70:3 | a : | semmle.label | a : | | pathname_flow.rb:70:7:70:30 | call to new : | semmle.label | call to new : | | pathname_flow.rb:70:20:70:29 | call to source : | semmle.label | call to source : | +| pathname_flow.rb:71:3:71:3 | b : | semmle.label | b : | | pathname_flow.rb:72:8:72:8 | b | semmle.label | b | +| pathname_flow.rb:76:3:76:3 | a : | semmle.label | a : | | pathname_flow.rb:76:7:76:30 | call to new : | semmle.label | call to new : | | pathname_flow.rb:76:20:76:29 | call to source : | semmle.label | call to source : | +| pathname_flow.rb:77:3:77:3 | b : | semmle.label | b : | | pathname_flow.rb:77:7:77:7 | a : | semmle.label | a : | | pathname_flow.rb:77:7:77:16 | call to basename : | semmle.label | call to basename : | | pathname_flow.rb:78:8:78:8 | b | semmle.label | b | +| pathname_flow.rb:82:3:82:3 | a : | semmle.label | a : | | pathname_flow.rb:82:7:82:30 | call to new : | semmle.label | call to new : | | pathname_flow.rb:82:20:82:29 | call to source : | semmle.label | call to source : | +| pathname_flow.rb:83:3:83:3 | b : | semmle.label | b : | | pathname_flow.rb:83:7:83:7 | a : | semmle.label | a : | | pathname_flow.rb:83:7:83:17 | call to cleanpath : | semmle.label | call to cleanpath : | | pathname_flow.rb:84:8:84:8 | b | semmle.label | b | +| pathname_flow.rb:88:3:88:3 | a : | semmle.label | a : | | pathname_flow.rb:88:7:88:30 | call to new : | semmle.label | call to new : | | pathname_flow.rb:88:20:88:29 | call to source : | semmle.label | call to source : | +| pathname_flow.rb:89:3:89:3 | b : | semmle.label | b : | | pathname_flow.rb:89:7:89:7 | a : | semmle.label | a : | | pathname_flow.rb:89:7:89:25 | call to sub : | semmle.label | call to sub : | | pathname_flow.rb:90:8:90:8 | b | semmle.label | b | +| pathname_flow.rb:94:3:94:3 | a : | semmle.label | a : | | pathname_flow.rb:94:7:94:30 | call to new : | semmle.label | call to new : | | pathname_flow.rb:94:20:94:29 | call to source : | semmle.label | call to source : | +| pathname_flow.rb:95:3:95:3 | b : | semmle.label | b : | | pathname_flow.rb:95:7:95:7 | a : | semmle.label | a : | | pathname_flow.rb:95:7:95:23 | call to sub_ext : | semmle.label | call to sub_ext : | | pathname_flow.rb:96:8:96:8 | b | semmle.label | b | +| pathname_flow.rb:101:3:101:3 | a : | semmle.label | a : | | pathname_flow.rb:101:7:101:30 | call to new : | semmle.label | call to new : | | pathname_flow.rb:101:20:101:29 | call to source : | semmle.label | call to source : | +| pathname_flow.rb:103:3:103:3 | b : | semmle.label | b : | | pathname_flow.rb:104:8:104:8 | b : | semmle.label | b : | | pathname_flow.rb:104:8:104:17 | call to realpath | semmle.label | call to realpath | +| pathname_flow.rb:106:3:106:3 | c : | semmle.label | c : | | pathname_flow.rb:107:8:107:8 | c : | semmle.label | c : | | pathname_flow.rb:107:8:107:17 | call to realpath | semmle.label | call to realpath | +| pathname_flow.rb:109:3:109:3 | d : | semmle.label | d : | | pathname_flow.rb:109:7:109:7 | a : | semmle.label | a : | | pathname_flow.rb:109:7:109:16 | call to basename : | semmle.label | call to basename : | | pathname_flow.rb:110:8:110:8 | d : | semmle.label | d : | | pathname_flow.rb:110:8:110:17 | call to realpath | semmle.label | call to realpath | +| pathname_flow.rb:112:3:112:3 | e : | semmle.label | e : | | pathname_flow.rb:112:7:112:7 | a : | semmle.label | a : | | pathname_flow.rb:112:7:112:17 | call to cleanpath : | semmle.label | call to cleanpath : | | pathname_flow.rb:113:8:113:8 | e : | semmle.label | e : | | pathname_flow.rb:113:8:113:17 | call to realpath | semmle.label | call to realpath | +| pathname_flow.rb:115:3:115:3 | f : | semmle.label | f : | | pathname_flow.rb:115:7:115:7 | a : | semmle.label | a : | | pathname_flow.rb:115:7:115:19 | call to expand_path : | semmle.label | call to expand_path : | | pathname_flow.rb:116:8:116:8 | f : | semmle.label | f : | | pathname_flow.rb:116:8:116:17 | call to realpath | semmle.label | call to realpath | +| pathname_flow.rb:118:3:118:3 | g : | semmle.label | g : | | pathname_flow.rb:118:7:118:7 | a : | semmle.label | a : | | pathname_flow.rb:118:7:118:19 | call to join : | semmle.label | call to join : | | pathname_flow.rb:119:8:119:8 | g : | semmle.label | g : | | pathname_flow.rb:119:8:119:17 | call to realpath | semmle.label | call to realpath | +| pathname_flow.rb:121:3:121:3 | h : | semmle.label | h : | | pathname_flow.rb:121:7:121:7 | a : | semmle.label | a : | | pathname_flow.rb:121:7:121:16 | call to realpath : | semmle.label | call to realpath : | | pathname_flow.rb:122:8:122:8 | h : | semmle.label | h : | | pathname_flow.rb:122:8:122:17 | call to realpath | semmle.label | call to realpath | +| pathname_flow.rb:124:3:124:3 | i : | semmle.label | i : | | pathname_flow.rb:124:7:124:7 | a : | semmle.label | a : | | pathname_flow.rb:124:7:124:38 | call to relative_path_from : | semmle.label | call to relative_path_from : | | pathname_flow.rb:125:8:125:8 | i : | semmle.label | i : | | pathname_flow.rb:125:8:125:17 | call to realpath | semmle.label | call to realpath | +| pathname_flow.rb:127:3:127:3 | j : | semmle.label | j : | | pathname_flow.rb:127:7:127:7 | a : | semmle.label | a : | | pathname_flow.rb:127:7:127:25 | call to sub : | semmle.label | call to sub : | | pathname_flow.rb:128:8:128:8 | j : | semmle.label | j : | | pathname_flow.rb:128:8:128:17 | call to realpath | semmle.label | call to realpath | +| pathname_flow.rb:130:3:130:3 | k : | semmle.label | k : | | pathname_flow.rb:130:7:130:7 | a : | semmle.label | a : | | pathname_flow.rb:130:7:130:23 | call to sub_ext : | semmle.label | call to sub_ext : | | pathname_flow.rb:131:8:131:8 | k : | semmle.label | k : | | pathname_flow.rb:131:8:131:17 | call to realpath | semmle.label | call to realpath | +| pathname_flow.rb:133:3:133:3 | l : | semmle.label | l : | | pathname_flow.rb:133:7:133:7 | a : | semmle.label | a : | | pathname_flow.rb:133:7:133:15 | call to to_path : | semmle.label | call to to_path : | | pathname_flow.rb:134:8:134:8 | l : | semmle.label | l : | 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 122a1d8eb1f..651a6affec7 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 @@ -2,126 +2,161 @@ failures | string_flow.rb:85:10:85:10 | a | Unexpected result: hasValueFlow=a | | string_flow.rb:227:10:227:10 | a | Unexpected result: hasValueFlow=a | edges -| string_flow.rb:2:9:2:18 | call to source : | string_flow.rb:3:21:3:21 | a : | -| string_flow.rb:2:9:2:18 | call to source : | string_flow.rb:3:21:3:21 | a : | +| string_flow.rb:2:5:2:5 | a : | string_flow.rb:3:21:3:21 | a : | +| string_flow.rb:2:5:2:5 | a : | string_flow.rb:3:21:3:21 | a : | +| string_flow.rb:2:9:2:18 | call to source : | string_flow.rb:2:5:2:5 | a : | +| string_flow.rb:2:9:2:18 | call to source : | string_flow.rb:2:5:2:5 | a : | | string_flow.rb:3:21:3:21 | a : | string_flow.rb:3:10:3:22 | call to new | | string_flow.rb:3:21:3:21 | a : | string_flow.rb:3:10:3:22 | call to new | -| string_flow.rb:7:9:7:18 | call to source : | string_flow.rb:9:29:9:29 | a : | -| string_flow.rb:8:9:8:16 | call to source : | string_flow.rb:10:29:10:29 | b : | +| string_flow.rb:7:5:7:5 | a : | string_flow.rb:9:29:9:29 | a : | +| string_flow.rb:7:9:7:18 | call to source : | string_flow.rb:7:5:7:5 | a : | +| string_flow.rb:8:5:8:5 | b : | string_flow.rb:10:29:10:29 | b : | +| string_flow.rb:8:9:8:16 | call to source : | string_flow.rb:8:5:8:5 | b : | | string_flow.rb:9:29:9:29 | a : | string_flow.rb:9:10:9:30 | call to try_convert | | 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 | ... % ... | +| string_flow.rb:14:5:14:5 | a : | string_flow.rb:15:10:15:17 | ... % ... | +| string_flow.rb:14:5:14:5 | a : | string_flow.rb:15:17:15:17 | a : | +| string_flow.rb:14:5:14:5 | a : | string_flow.rb:16:10:16:29 | ... % ... | +| string_flow.rb:14:5:14:5 | a : | string_flow.rb:16:28:16:28 | a : | +| string_flow.rb:14:5:14:5 | a : | string_flow.rb:17:10:17:10 | a : | +| string_flow.rb:14:5:14:5 | a : | string_flow.rb:17:10:17:18 | ... % ... | +| string_flow.rb:14:9:14:18 | call to source : | string_flow.rb:14:5:14:5 | a : | | string_flow.rb:15:17:15:17 | a : | string_flow.rb:15:10:15:17 | ... % ... | | string_flow.rb:16:28:16:28 | a : | string_flow.rb:16:10:16:29 | ... % ... | | string_flow.rb:17:10:17:10 | a : | string_flow.rb:17:10:17:18 | ... % ... | -| string_flow.rb:21:9:21:18 | call to source : | string_flow.rb:23:10:23:10 | b | -| string_flow.rb:27:9:27:18 | call to source : | string_flow.rb:29:10:29:10 | b | -| string_flow.rb:33:9:33:18 | call to source : | string_flow.rb:35:10:35:10 | b | -| string_flow.rb:33:9:33:18 | call to source : | string_flow.rb:37:10:37:10 | c | -| string_flow.rb:41:9:41:18 | call to source : | string_flow.rb:42:10:42:10 | a : | +| string_flow.rb:21:5:21:5 | a : | string_flow.rb:22:5:22:5 | b : | +| string_flow.rb:21:9:21:18 | call to source : | string_flow.rb:21:5:21:5 | a : | +| string_flow.rb:22:5:22:5 | b : | string_flow.rb:23:10:23:10 | b | +| string_flow.rb:27:5:27:5 | a : | string_flow.rb:28:5:28:5 | b : | +| string_flow.rb:27:9:27:18 | call to source : | string_flow.rb:27:5:27:5 | a : | +| string_flow.rb:28:5:28:5 | b : | string_flow.rb:29:10:29:10 | b | +| string_flow.rb:33:5:33:5 | a : | string_flow.rb:34:5:34:5 | b : | +| string_flow.rb:33:5:33:5 | a : | string_flow.rb:36:5:36:5 | c : | +| string_flow.rb:33:9:33:18 | call to source : | string_flow.rb:33:5:33:5 | a : | +| string_flow.rb:34:5:34:5 | b : | string_flow.rb:35:10:35:10 | b | +| string_flow.rb:36:5:36:5 | c : | string_flow.rb:37:10:37:10 | c | +| string_flow.rb:41:5:41:5 | a : | string_flow.rb:42:10:42:10 | a : | +| string_flow.rb:41:9:41:18 | call to source : | string_flow.rb:41:5:41:5 | a : | | string_flow.rb:42:10:42:10 | a : | string_flow.rb:42:10:42:12 | call to b | -| string_flow.rb:46:9:46:18 | call to source : | string_flow.rb:47:10:47:10 | a : | -| string_flow.rb:46:9:46:18 | call to source : | string_flow.rb:48:10:48:10 | a : | -| string_flow.rb:46:9:46:18 | call to source : | string_flow.rb:49:10:49:10 | a : | +| string_flow.rb:46:5:46:5 | a : | string_flow.rb:47:10:47:10 | a : | +| string_flow.rb:46:5:46:5 | a : | string_flow.rb:48:10:48:10 | a : | +| string_flow.rb:46:5:46:5 | a : | string_flow.rb:49:10:49:10 | a : | +| string_flow.rb:46:9:46:18 | call to source : | string_flow.rb:46:5:46:5 | a : | | string_flow.rb:47:10:47:10 | a : | string_flow.rb:47:10:47:23 | call to byteslice | | string_flow.rb:48:10:48:10 | a : | string_flow.rb:48:10:48:26 | call to byteslice | | string_flow.rb:49:10:49:10 | a : | string_flow.rb:49:10:49:26 | call to byteslice | -| string_flow.rb:53:9:53:18 | call to source : | string_flow.rb:54:10:54:10 | a : | -| string_flow.rb:53:9:53:18 | call to source : | string_flow.rb:55:10:55:10 | a : | +| string_flow.rb:53:5:53:5 | a : | string_flow.rb:54:10:54:10 | a : | +| string_flow.rb:53:5:53:5 | a : | string_flow.rb:55:10:55:10 | a : | +| string_flow.rb:53:9:53:18 | call to source : | string_flow.rb:53:5:53:5 | a : | | string_flow.rb:54:10:54:10 | a : | string_flow.rb:54:10:54:21 | call to capitalize | | string_flow.rb:55:10:55:10 | a : | string_flow.rb:55:10:55:22 | call to capitalize! | -| string_flow.rb:59:9:59:18 | call to source : | string_flow.rb:60:10:60:10 | a : | -| string_flow.rb:59:9:59:18 | call to source : | string_flow.rb:61:27:61:27 | a : | -| string_flow.rb:59:9:59:18 | call to source : | string_flow.rb:62:10:62:10 | a : | -| string_flow.rb:59:9:59:18 | call to source : | string_flow.rb:63:26:63:26 | a : | -| string_flow.rb:59:9:59:18 | call to source : | string_flow.rb:64:10:64:10 | a : | -| string_flow.rb:59:9:59:18 | call to source : | string_flow.rb:65:26:65:26 | a : | +| string_flow.rb:59:5:59:5 | a : | string_flow.rb:60:10:60:10 | a : | +| string_flow.rb:59:5:59:5 | a : | string_flow.rb:61:27:61:27 | a : | +| string_flow.rb:59:5:59:5 | a : | string_flow.rb:62:10:62:10 | a : | +| string_flow.rb:59:5:59:5 | a : | string_flow.rb:63:26:63:26 | a : | +| string_flow.rb:59:5:59:5 | a : | string_flow.rb:64:10:64:10 | a : | +| string_flow.rb:59:5:59:5 | a : | string_flow.rb:65:26:65:26 | a : | +| string_flow.rb:59:9:59:18 | call to source : | string_flow.rb:59:5:59:5 | a : | | string_flow.rb:60:10:60:10 | a : | string_flow.rb:60:10:60:21 | call to center | | string_flow.rb:61:27:61:27 | a : | string_flow.rb:61:10:61:28 | call to center | | string_flow.rb:62:10:62:10 | a : | string_flow.rb:62:10:62:20 | call to ljust | | string_flow.rb:63:26:63:26 | a : | string_flow.rb:63:10:63:27 | call to ljust | | string_flow.rb:64:10:64:10 | a : | string_flow.rb:64:10:64:20 | call to rjust | | string_flow.rb:65:26:65:26 | a : | string_flow.rb:65:10:65:27 | call to rjust | -| string_flow.rb:69:9:69:18 | call to source : | string_flow.rb:70:10:70:10 | a : | -| string_flow.rb:69:9:69:18 | call to source : | string_flow.rb:71:10:71:10 | a : | +| string_flow.rb:69:5:69:5 | a : | string_flow.rb:70:10:70:10 | a : | +| string_flow.rb:69:5:69:5 | a : | string_flow.rb:71:10:71:10 | a : | +| string_flow.rb:69:9:69:18 | call to source : | string_flow.rb:69:5:69:5 | a : | | string_flow.rb:70:10:70:10 | a : | string_flow.rb:70:10:70:16 | call to chomp | | string_flow.rb:71:10:71:10 | a : | string_flow.rb:71:10:71:17 | call to chomp! | -| string_flow.rb:75:9:75:18 | call to source : | string_flow.rb:76:10:76:10 | a : | -| string_flow.rb:75:9:75:18 | call to source : | string_flow.rb:77:10:77:10 | a : | +| string_flow.rb:75:5:75:5 | a : | string_flow.rb:76:10:76:10 | a : | +| string_flow.rb:75:5:75:5 | a : | string_flow.rb:77:10:77:10 | a : | +| string_flow.rb:75:9:75:18 | call to source : | string_flow.rb:75:5:75:5 | a : | | string_flow.rb:76:10:76:10 | a : | string_flow.rb:76:10:76:15 | call to chop | | string_flow.rb:77:10:77:10 | a : | string_flow.rb:77:10:77:16 | call to chop! | -| string_flow.rb:83:9:83:18 | call to source : | string_flow.rb:84:5:84:5 | a : | -| string_flow.rb:83:9:83:18 | call to source : | string_flow.rb:84:5:84:5 | a : | +| string_flow.rb:83:5:83:5 | a : | string_flow.rb:84:5:84:5 | a : | +| string_flow.rb:83:5:83:5 | a : | string_flow.rb:84:5:84:5 | a : | +| string_flow.rb:83:9:83:18 | call to source : | string_flow.rb:83:5:83:5 | a : | +| string_flow.rb:83:9:83:18 | call to source : | string_flow.rb:83:5:83:5 | a : | | string_flow.rb:84:5:84:5 | [post] a : | string_flow.rb:85:10:85:10 | a | | string_flow.rb:84:5:84:5 | [post] a : | string_flow.rb:85:10:85:10 | a | | string_flow.rb:84:5:84:5 | a : | string_flow.rb:84:5:84:5 | [post] a : | | string_flow.rb:84:5:84:5 | a : | string_flow.rb:84:5:84:5 | [post] a : | -| string_flow.rb:108:9:108:18 | call to source : | string_flow.rb:109:10:109:10 | a : | +| string_flow.rb:108:5:108:5 | a : | string_flow.rb:109:10:109:10 | a : | +| string_flow.rb:108:9:108:18 | call to source : | string_flow.rb:108:5:108:5 | a : | | string_flow.rb:109:10:109:10 | [post] a : | string_flow.rb:110:10:110:10 | a : | | string_flow.rb:109:10:109:10 | [post] a : | string_flow.rb:111:10:111:10 | a : | | string_flow.rb:109:10:109:10 | a : | string_flow.rb:109:10:109:10 | [post] a : | | string_flow.rb:109:10:109:10 | a : | string_flow.rb:109:10:109:22 | call to delete | | string_flow.rb:110:10:110:10 | a : | string_flow.rb:110:10:110:29 | call to delete_prefix | | string_flow.rb:111:10:111:10 | a : | string_flow.rb:111:10:111:29 | call to delete_suffix | -| string_flow.rb:115:9:115:18 | call to source : | string_flow.rb:116:10:116:10 | a : | -| string_flow.rb:115:9:115:18 | call to source : | string_flow.rb:117:10:117:10 | a : | -| string_flow.rb:115:9:115:18 | call to source : | string_flow.rb:118:10:118:10 | a : | -| string_flow.rb:115:9:115:18 | call to source : | string_flow.rb:119:10:119:10 | a : | -| string_flow.rb:115:9:115:18 | call to source : | string_flow.rb:120:10:120:10 | a : | -| string_flow.rb:115:9:115:18 | call to source : | string_flow.rb:121:10:121:10 | a : | +| string_flow.rb:115:5:115:5 | a : | string_flow.rb:116:10:116:10 | a : | +| string_flow.rb:115:5:115:5 | a : | string_flow.rb:117:10:117:10 | a : | +| string_flow.rb:115:5:115:5 | a : | string_flow.rb:118:10:118:10 | a : | +| string_flow.rb:115:5:115:5 | a : | string_flow.rb:119:10:119:10 | a : | +| string_flow.rb:115:5:115:5 | a : | string_flow.rb:120:10:120:10 | a : | +| string_flow.rb:115:5:115:5 | a : | string_flow.rb:121:10:121:10 | a : | +| string_flow.rb:115:9:115:18 | call to source : | string_flow.rb:115:5:115:5 | a : | | string_flow.rb:116:10:116:10 | a : | string_flow.rb:116:10:116:19 | call to downcase | | string_flow.rb:117:10:117:10 | a : | string_flow.rb:117:10:117:20 | call to downcase! | | string_flow.rb:118:10:118:10 | a : | string_flow.rb:118:10:118:19 | call to swapcase | | string_flow.rb:119:10:119:10 | a : | string_flow.rb:119:10:119:20 | call to swapcase! | | string_flow.rb:120:10:120:10 | a : | string_flow.rb:120:10:120:17 | call to upcase | | string_flow.rb:121:10:121:10 | a : | string_flow.rb:121:10:121:18 | call to upcase! | -| string_flow.rb:125:9:125:18 | call to source : | string_flow.rb:126:9:126:9 | a : | +| string_flow.rb:125:5:125:5 | a : | string_flow.rb:126:9:126:9 | a : | +| string_flow.rb:125:9:125:18 | call to source : | string_flow.rb:125:5:125:5 | a : | +| string_flow.rb:126:5:126:5 | b : | string_flow.rb:127:10:127:10 | b | +| string_flow.rb:126:5:126:5 | b : | string_flow.rb:128:10:128:10 | b : | | string_flow.rb:126:9:126:9 | a : | string_flow.rb:126:9:126:14 | call to dump : | -| string_flow.rb:126:9:126:14 | call to dump : | string_flow.rb:127:10:127:10 | b | -| string_flow.rb:126:9:126:14 | call to dump : | string_flow.rb:128:10:128:10 | b : | +| string_flow.rb:126:9:126:14 | call to dump : | string_flow.rb:126:5:126:5 | b : | | string_flow.rb:128:10:128:10 | b : | string_flow.rb:128:10:128:17 | call to undump | -| string_flow.rb:132:9:132:18 | call to source : | string_flow.rb:133:9:133:9 | a : | -| string_flow.rb:132:9:132:18 | call to source : | string_flow.rb:135:9:135:9 | a : | +| string_flow.rb:132:5:132:5 | a : | string_flow.rb:133:9:133:9 | a : | +| string_flow.rb:132:5:132:5 | a : | string_flow.rb:135:9:135:9 | a : | +| string_flow.rb:132:9:132:18 | call to source : | string_flow.rb:132:5:132:5 | a : | +| string_flow.rb:133:5:133:5 | b : | string_flow.rb:134:10:134:10 | b | | string_flow.rb:133:9:133:9 | a : | string_flow.rb:133:9:133:40 | call to each_line : | | string_flow.rb:133:9:133:9 | a : | string_flow.rb:133:24:133:27 | line : | -| string_flow.rb:133:9:133:40 | call to each_line : | string_flow.rb:134:10:134:10 | b | +| string_flow.rb:133:9:133:40 | call to each_line : | string_flow.rb:133:5:133:5 | b : | | string_flow.rb:133:24:133:27 | line : | string_flow.rb:133:35:133:38 | line | +| string_flow.rb:135:5:135:5 | c [element] : | string_flow.rb:136:10:136:10 | c [element] : | | string_flow.rb:135:9:135:9 | a : | string_flow.rb:135:9:135:19 | call to each_line [element] : | -| string_flow.rb:135:9:135:19 | call to each_line [element] : | string_flow.rb:136:10:136:10 | c [element] : | +| string_flow.rb:135:9:135:19 | call to each_line [element] : | string_flow.rb:135:5:135:5 | c [element] : | | string_flow.rb:136:10:136:10 | c [element] : | string_flow.rb:136:10:136:15 | call to to_a [element] : | | string_flow.rb:136:10:136:15 | call to to_a [element] : | string_flow.rb:136:10:136:18 | ...[...] | -| string_flow.rb:140:9:140:18 | call to source : | string_flow.rb:141:9:141:9 | a : | -| string_flow.rb:140:9:140:18 | call to source : | string_flow.rb:143:9:143:9 | a : | +| string_flow.rb:140:5:140:5 | a : | string_flow.rb:141:9:141:9 | a : | +| string_flow.rb:140:5:140:5 | a : | string_flow.rb:143:9:143:9 | a : | +| string_flow.rb:140:9:140:18 | call to source : | string_flow.rb:140:5:140:5 | a : | +| string_flow.rb:141:5:141:5 | b : | string_flow.rb:142:10:142:10 | b | | string_flow.rb:141:9:141:9 | a : | string_flow.rb:141:9:141:36 | call to lines : | | string_flow.rb:141:9:141:9 | a : | string_flow.rb:141:20:141:23 | line : | -| string_flow.rb:141:9:141:36 | call to lines : | string_flow.rb:142:10:142:10 | b | +| string_flow.rb:141:9:141:36 | call to lines : | string_flow.rb:141:5:141:5 | b : | | string_flow.rb:141:20:141:23 | line : | string_flow.rb:141:31:141:34 | line | +| string_flow.rb:143:5:143:5 | c [element] : | string_flow.rb:144:10:144:10 | c [element] : | | string_flow.rb:143:9:143:9 | a : | string_flow.rb:143:9:143:15 | call to lines [element] : | -| string_flow.rb:143:9:143:15 | call to lines [element] : | string_flow.rb:144:10:144:10 | c [element] : | +| string_flow.rb:143:9:143:15 | call to lines [element] : | string_flow.rb:143:5:143:5 | c [element] : | | string_flow.rb:144:10:144:10 | c [element] : | string_flow.rb:144:10:144:13 | ...[...] | -| string_flow.rb:148:9:148:18 | call to source : | string_flow.rb:149:10:149:10 | a : | -| string_flow.rb:148:9:148:18 | call to source : | string_flow.rb:150:10:150:10 | a : | -| string_flow.rb:148:9:148:18 | call to source : | string_flow.rb:151:10:151:10 | a : | -| string_flow.rb:148:9:148:18 | call to source : | string_flow.rb:152:10:152:10 | a : | +| string_flow.rb:148:5:148:5 | a : | string_flow.rb:149:10:149:10 | a : | +| string_flow.rb:148:5:148:5 | a : | string_flow.rb:150:10:150:10 | a : | +| string_flow.rb:148:5:148:5 | a : | string_flow.rb:151:10:151:10 | a : | +| string_flow.rb:148:5:148:5 | a : | string_flow.rb:152:10:152:10 | a : | +| string_flow.rb:148:9:148:18 | call to source : | string_flow.rb:148:5:148:5 | a : | | string_flow.rb:149:10:149:10 | a : | string_flow.rb:149:10:149:26 | call to encode | | string_flow.rb:150:10:150:10 | a : | string_flow.rb:150:10:150:27 | call to encode! | | string_flow.rb:151:10:151:10 | a : | string_flow.rb:151:10:151:28 | call to unicode_normalize | | string_flow.rb:152:10:152:10 | a : | string_flow.rb:152:10:152:29 | call to unicode_normalize! | -| string_flow.rb:156:9:156:18 | call to source : | string_flow.rb:157:10:157:10 | a : | +| string_flow.rb:156:5:156:5 | a : | string_flow.rb:157:10:157:10 | a : | +| string_flow.rb:156:9:156:18 | call to source : | string_flow.rb:156:5:156:5 | a : | | string_flow.rb:157:10:157:10 | a : | string_flow.rb:157:10:157:34 | call to force_encoding | -| string_flow.rb:161:9:161:18 | call to source : | string_flow.rb:162:10:162:10 | a : | +| string_flow.rb:161:5:161:5 | a : | string_flow.rb:162:10:162:10 | a : | +| string_flow.rb:161:9:161:18 | call to source : | string_flow.rb:161:5:161:5 | a : | | string_flow.rb:162:10:162:10 | a : | string_flow.rb:162:10:162:17 | call to freeze | -| string_flow.rb:166:9:166:18 | call to source : | string_flow.rb:168:10:168:10 | a : | -| string_flow.rb:166:9:166:18 | call to source : | string_flow.rb:169:10:169:10 | a : | -| string_flow.rb:166:9:166:18 | call to source : | string_flow.rb:170:10:170:10 | a : | -| string_flow.rb:166:9:166:18 | call to source : | string_flow.rb:171:10:171:10 | a : | -| string_flow.rb:167:9:167:18 | call to source : | string_flow.rb:168:22:168:22 | c : | -| string_flow.rb:167:9:167:18 | call to source : | string_flow.rb:169:23:169:23 | c : | +| string_flow.rb:166:5:166:5 | a : | string_flow.rb:168:10:168:10 | a : | +| string_flow.rb:166:5:166:5 | a : | string_flow.rb:169:10:169:10 | a : | +| string_flow.rb:166:5:166:5 | a : | string_flow.rb:170:10:170:10 | a : | +| string_flow.rb:166:5:166:5 | a : | string_flow.rb:171:10:171:10 | a : | +| string_flow.rb:166:9:166:18 | call to source : | string_flow.rb:166:5:166:5 | a : | +| string_flow.rb:167:5:167:5 | c : | string_flow.rb:168:22:168:22 | c : | +| string_flow.rb:167:5:167:5 | c : | string_flow.rb:169:23:169:23 | c : | +| string_flow.rb:167:9:167:18 | call to source : | string_flow.rb:167:5:167:5 | c : | | string_flow.rb:168:10:168:10 | a : | string_flow.rb:168:10:168:23 | call to gsub | | string_flow.rb:168:22:168:22 | c : | string_flow.rb:168:10:168:23 | call to gsub | | string_flow.rb:169:10:169:10 | a : | string_flow.rb:169:10:169:24 | call to gsub! | @@ -130,12 +165,14 @@ edges | string_flow.rb:170:32:170:41 | call to source : | string_flow.rb:170:10:170:43 | call to gsub | | string_flow.rb:171:10:171:10 | a : | string_flow.rb:171:10:171:44 | call to gsub! | | string_flow.rb:171:33:171:42 | call to source : | string_flow.rb:171:10:171:44 | call to gsub! | -| string_flow.rb:175:9:175:18 | call to source : | string_flow.rb:177:10:177:10 | a : | -| string_flow.rb:175:9:175:18 | call to source : | string_flow.rb:178:10:178:10 | a : | -| string_flow.rb:175:9:175:18 | call to source : | string_flow.rb:179:10:179:10 | a : | -| string_flow.rb:175:9:175:18 | call to source : | string_flow.rb:180:10:180:10 | a : | -| string_flow.rb:176:9:176:18 | call to source : | string_flow.rb:177:21:177:21 | c : | -| string_flow.rb:176:9:176:18 | call to source : | string_flow.rb:178:22:178:22 | c : | +| string_flow.rb:175:5:175:5 | a : | string_flow.rb:177:10:177:10 | a : | +| string_flow.rb:175:5:175:5 | a : | string_flow.rb:178:10:178:10 | a : | +| string_flow.rb:175:5:175:5 | a : | string_flow.rb:179:10:179:10 | a : | +| string_flow.rb:175:5:175:5 | a : | string_flow.rb:180:10:180:10 | a : | +| string_flow.rb:175:9:175:18 | call to source : | string_flow.rb:175:5:175:5 | a : | +| string_flow.rb:176:5:176:5 | c : | string_flow.rb:177:21:177:21 | c : | +| string_flow.rb:176:5:176:5 | c : | string_flow.rb:178:22:178:22 | c : | +| string_flow.rb:176:9:176:18 | call to source : | string_flow.rb:176:5:176:5 | c : | | string_flow.rb:177:10:177:10 | a : | string_flow.rb:177:10:177:22 | call to sub | | string_flow.rb:177:21:177:21 | c : | string_flow.rb:177:10:177:22 | call to sub | | string_flow.rb:178:10:178:10 | a : | string_flow.rb:178:10:178:23 | call to sub! | @@ -144,70 +181,84 @@ edges | string_flow.rb:179:31:179:40 | call to source : | string_flow.rb:179:10:179:42 | call to sub | | string_flow.rb:180:10:180:10 | a : | string_flow.rb:180:10:180:43 | call to sub! | | string_flow.rb:180:32:180:41 | call to source : | string_flow.rb:180:10:180:43 | call to sub! | -| string_flow.rb:191:9:191:18 | call to source : | string_flow.rb:192:10:192:10 | a : | +| string_flow.rb:191:5:191:5 | a : | string_flow.rb:192:10:192:10 | a : | +| string_flow.rb:191:9:191:18 | call to source : | string_flow.rb:191:5:191:5 | a : | | string_flow.rb:192:10:192:10 | a : | string_flow.rb:192:10:192:18 | call to inspect | -| string_flow.rb:196:9:196:18 | call to source : | string_flow.rb:197:10:197:10 | a : | -| string_flow.rb:196:9:196:18 | call to source : | string_flow.rb:198:10:198:10 | a : | -| string_flow.rb:196:9:196:18 | call to source : | string_flow.rb:199:10:199:10 | a : | -| string_flow.rb:196:9:196:18 | call to source : | string_flow.rb:200:10:200:10 | a : | -| string_flow.rb:196:9:196:18 | call to source : | string_flow.rb:201:10:201:10 | a : | -| string_flow.rb:196:9:196:18 | call to source : | string_flow.rb:202:10:202:10 | a : | +| string_flow.rb:196:5:196:5 | a : | string_flow.rb:197:10:197:10 | a : | +| string_flow.rb:196:5:196:5 | a : | string_flow.rb:198:10:198:10 | a : | +| string_flow.rb:196:5:196:5 | a : | string_flow.rb:199:10:199:10 | a : | +| string_flow.rb:196:5:196:5 | a : | string_flow.rb:200:10:200:10 | a : | +| string_flow.rb:196:5:196:5 | a : | string_flow.rb:201:10:201:10 | a : | +| string_flow.rb:196:5:196:5 | a : | string_flow.rb:202:10:202:10 | a : | +| string_flow.rb:196:9:196:18 | call to source : | string_flow.rb:196:5:196:5 | a : | | string_flow.rb:197:10:197:10 | a : | string_flow.rb:197:10:197:16 | call to strip | | string_flow.rb:198:10:198:10 | a : | string_flow.rb:198:10:198:17 | call to strip! | | string_flow.rb:199:10:199:10 | a : | string_flow.rb:199:10:199:17 | call to lstrip | | string_flow.rb:200:10:200:10 | a : | string_flow.rb:200:10:200:18 | call to lstrip! | | string_flow.rb:201:10:201:10 | a : | string_flow.rb:201:10:201:17 | call to rstrip | | string_flow.rb:202:10:202:10 | a : | string_flow.rb:202:10:202:18 | call to rstrip! | -| string_flow.rb:206:9:206:18 | call to source : | string_flow.rb:207:10:207:10 | a : | -| string_flow.rb:206:9:206:18 | call to source : | string_flow.rb:208:10:208:10 | a : | -| string_flow.rb:206:9:206:18 | call to source : | string_flow.rb:209:10:209:10 | a : | -| string_flow.rb:206:9:206:18 | call to source : | string_flow.rb:210:10:210:10 | a : | +| string_flow.rb:206:5:206:5 | a : | string_flow.rb:207:10:207:10 | a : | +| string_flow.rb:206:5:206:5 | a : | string_flow.rb:208:10:208:10 | a : | +| string_flow.rb:206:5:206:5 | a : | string_flow.rb:209:10:209:10 | a : | +| string_flow.rb:206:5:206:5 | a : | string_flow.rb:210:10:210:10 | a : | +| string_flow.rb:206:9:206:18 | call to source : | string_flow.rb:206:5:206:5 | a : | | string_flow.rb:207:10:207:10 | a : | string_flow.rb:207:10:207:15 | call to next | | string_flow.rb:208:10:208:10 | a : | string_flow.rb:208:10:208:16 | call to next! | | string_flow.rb:209:10:209:10 | a : | string_flow.rb:209:10:209:15 | call to succ | | string_flow.rb:210:10:210:10 | a : | string_flow.rb:210:10:210:16 | call to succ! | -| string_flow.rb:214:9:214:18 | call to source : | string_flow.rb:215:9:215:9 | a : | +| string_flow.rb:214:5:214:5 | a : | string_flow.rb:215:9:215:9 | a : | +| string_flow.rb:214:9:214:18 | call to source : | string_flow.rb:214:5:214:5 | a : | +| string_flow.rb:215:5:215:5 | b [element 0] : | string_flow.rb:216:10:216:10 | b [element 0] : | +| string_flow.rb:215:5:215:5 | b [element 1] : | string_flow.rb:217:10:217:10 | b [element 1] : | +| string_flow.rb:215:5:215:5 | b [element 2] : | string_flow.rb:218:10:218:10 | b [element 2] : | | string_flow.rb:215:9:215:9 | a : | string_flow.rb:215:9:215:24 | call to partition [element 0] : | | string_flow.rb:215:9:215:9 | a : | string_flow.rb:215:9:215:24 | call to partition [element 1] : | | string_flow.rb:215:9:215:9 | a : | string_flow.rb:215:9:215:24 | call to partition [element 2] : | -| string_flow.rb:215:9:215:24 | call to partition [element 0] : | string_flow.rb:216:10:216:10 | b [element 0] : | -| string_flow.rb:215:9:215:24 | call to partition [element 1] : | string_flow.rb:217:10:217:10 | b [element 1] : | -| string_flow.rb:215:9:215:24 | call to partition [element 2] : | string_flow.rb:218:10:218:10 | b [element 2] : | +| string_flow.rb:215:9:215:24 | call to partition [element 0] : | string_flow.rb:215:5:215:5 | b [element 0] : | +| string_flow.rb:215:9:215:24 | call to partition [element 1] : | string_flow.rb:215:5:215:5 | b [element 1] : | +| string_flow.rb:215:9:215:24 | call to partition [element 2] : | string_flow.rb:215:5:215:5 | b [element 2] : | | string_flow.rb:216:10:216:10 | b [element 0] : | string_flow.rb:216:10:216:13 | ...[...] | | string_flow.rb:217:10:217:10 | b [element 1] : | string_flow.rb:217:10:217:13 | ...[...] | | string_flow.rb:218:10:218:10 | b [element 2] : | string_flow.rb:218:10:218:13 | ...[...] | -| string_flow.rb:223:9:223:18 | call to source : | string_flow.rb:225:10:225:10 | a : | -| string_flow.rb:223:9:223:18 | call to source : | string_flow.rb:225:10:225:10 | a : | -| string_flow.rb:224:9:224:18 | call to source : | string_flow.rb:225:20:225:20 | b : | +| string_flow.rb:223:5:223:5 | a : | string_flow.rb:225:10:225:10 | a : | +| string_flow.rb:223:5:223:5 | a : | string_flow.rb:225:10:225:10 | a : | +| string_flow.rb:223:9:223:18 | call to source : | string_flow.rb:223:5:223:5 | a : | +| string_flow.rb:223:9:223:18 | call to source : | string_flow.rb:223:5:223:5 | a : | +| string_flow.rb:224:5:224:5 | b : | string_flow.rb:225:20:225:20 | b : | +| string_flow.rb:224:9:224:18 | call to source : | string_flow.rb:224:5:224:5 | b : | | string_flow.rb:225:10:225:10 | [post] a : | string_flow.rb:227:10:227:10 | a | | string_flow.rb:225:10:225:10 | [post] a : | string_flow.rb:227:10:227:10 | a | | string_flow.rb:225:10:225:10 | a : | string_flow.rb:225:10:225:10 | [post] a : | | string_flow.rb:225:10:225:10 | a : | string_flow.rb:225:10:225:10 | [post] a : | | string_flow.rb:225:20:225:20 | b : | string_flow.rb:225:10:225:10 | [post] a : | | string_flow.rb:225:20:225:20 | b : | string_flow.rb:225:10:225:21 | call to replace | -| string_flow.rb:231:9:231:18 | call to source : | string_flow.rb:232:10:232:10 | a : | +| string_flow.rb:231:5:231:5 | a : | string_flow.rb:232:10:232:10 | a : | +| string_flow.rb:231:9:231:18 | call to source : | string_flow.rb:231:5:231:5 | a : | | string_flow.rb:232:10:232:10 | a : | string_flow.rb:232:10:232:18 | call to reverse | -| string_flow.rb:236:9:236:18 | call to source : | string_flow.rb:237:9:237:9 | a : | -| string_flow.rb:236:9:236:18 | call to source : | string_flow.rb:238:9:238:9 | a : | -| string_flow.rb:236:9:236:18 | call to source : | string_flow.rb:240:9:240:9 | a : | +| string_flow.rb:236:5:236:5 | a : | string_flow.rb:237:9:237:9 | a : | +| string_flow.rb:236:5:236:5 | a : | string_flow.rb:238:9:238:9 | a : | +| string_flow.rb:236:5:236:5 | a : | string_flow.rb:240:9:240:9 | a : | +| string_flow.rb:236:9:236:18 | call to source : | string_flow.rb:236:5:236:5 | a : | | string_flow.rb:237:9:237:9 | a : | string_flow.rb:237:24:237:24 | x : | | string_flow.rb:237:24:237:24 | x : | string_flow.rb:237:35:237:35 | x | +| string_flow.rb:238:5:238:5 | b : | string_flow.rb:239:10:239:10 | b | | string_flow.rb:238:9:238:9 | a : | string_flow.rb:238:9:238:37 | call to scan : | | string_flow.rb:238:9:238:9 | a : | string_flow.rb:238:27:238:27 | y : | -| string_flow.rb:238:9:238:37 | call to scan : | string_flow.rb:239:10:239:10 | b | +| string_flow.rb:238:9:238:37 | call to scan : | string_flow.rb:238:5:238:5 | b : | | string_flow.rb:238:27:238:27 | y : | string_flow.rb:238:35:238:35 | y | +| string_flow.rb:240:5:240:5 | b [element] : | string_flow.rb:241:10:241:10 | b [element] : | +| string_flow.rb:240:5:240:5 | b [element] : | string_flow.rb:242:10:242:10 | b [element] : | | string_flow.rb:240:9:240:9 | a : | string_flow.rb:240:9:240:19 | call to scan [element] : | -| string_flow.rb:240:9:240:19 | call to scan [element] : | string_flow.rb:241:10:241:10 | b [element] : | -| string_flow.rb:240:9:240:19 | call to scan [element] : | string_flow.rb:242:10:242:10 | b [element] : | +| string_flow.rb:240:9:240:19 | call to scan [element] : | string_flow.rb:240:5:240:5 | b [element] : | | string_flow.rb:241:10:241:10 | b [element] : | string_flow.rb:241:10:241:13 | ...[...] | | string_flow.rb:242:10:242:10 | b [element] : | string_flow.rb:242:10:242:13 | ...[...] | -| string_flow.rb:246:5:246:18 | ... = ... : | string_flow.rb:250:26:250:26 | a : | -| string_flow.rb:246:9:246:18 | call to source : | string_flow.rb:246:5:246:18 | ... = ... : | -| string_flow.rb:246:9:246:18 | call to source : | string_flow.rb:247:10:247:10 | a : | -| string_flow.rb:246:9:246:18 | call to source : | string_flow.rb:248:20:248:20 | a : | -| string_flow.rb:246:9:246:18 | call to source : | string_flow.rb:249:5:249:5 | a : | -| string_flow.rb:246:9:246:18 | call to source : | string_flow.rb:252:10:252:10 | a : | -| string_flow.rb:246:9:246:18 | call to source : | string_flow.rb:253:21:253:21 | a : | +| string_flow.rb:246:5:246:5 | a : | string_flow.rb:247:10:247:10 | a : | +| string_flow.rb:246:5:246:5 | a : | string_flow.rb:248:20:248:20 | a : | +| string_flow.rb:246:5:246:5 | a : | string_flow.rb:249:5:249:5 | a : | +| string_flow.rb:246:5:246:5 | a : | string_flow.rb:250:26:250:26 | a : | +| string_flow.rb:246:5:246:5 | a : | string_flow.rb:252:10:252:10 | a : | +| string_flow.rb:246:5:246:5 | a : | string_flow.rb:253:21:253:21 | a : | +| string_flow.rb:246:9:246:18 | call to source : | string_flow.rb:246:5:246:5 | a : | | string_flow.rb:247:10:247:10 | a : | string_flow.rb:247:10:247:21 | call to scrub | | string_flow.rb:248:20:248:20 | a : | string_flow.rb:248:10:248:21 | call to scrub | | string_flow.rb:249:5:249:5 | a : | string_flow.rb:249:16:249:16 | x : | @@ -215,23 +266,29 @@ edges | string_flow.rb:250:26:250:26 | a : | string_flow.rb:250:10:250:28 | call to scrub | | string_flow.rb:252:10:252:10 | a : | string_flow.rb:252:10:252:22 | call to scrub! | | string_flow.rb:253:21:253:21 | a : | string_flow.rb:253:10:253:22 | call to scrub! | -| string_flow.rb:255:5:255:18 | ... = ... : | string_flow.rb:258:27:258:27 | a : | -| string_flow.rb:255:9:255:18 | call to source : | string_flow.rb:255:5:255:18 | ... = ... : | -| string_flow.rb:255:9:255:18 | call to source : | string_flow.rb:256:5:256:5 | a : | +| string_flow.rb:255:5:255:5 | a : | string_flow.rb:256:5:256:5 | a : | +| string_flow.rb:255:5:255:5 | a : | string_flow.rb:258:27:258:27 | a : | +| string_flow.rb:255:9:255:18 | call to source : | string_flow.rb:255:5:255:5 | a : | | string_flow.rb:256:5:256:5 | a : | string_flow.rb:256:17:256:17 | x : | | string_flow.rb:256:17:256:17 | x : | string_flow.rb:256:25:256:25 | x | | string_flow.rb:258:27:258:27 | a : | string_flow.rb:258:10:258:29 | call to scrub! | -| string_flow.rb:262:9:262:18 | call to source : | string_flow.rb:263:10:263:10 | a : | +| string_flow.rb:262:5:262:5 | a : | string_flow.rb:263:10:263:10 | a : | +| string_flow.rb:262:9:262:18 | call to source : | string_flow.rb:262:5:262:5 | a : | | string_flow.rb:263:10:263:10 | a : | string_flow.rb:263:10:263:22 | call to shellescape | -| string_flow.rb:267:9:267:18 | call to source : | string_flow.rb:268:9:268:9 | a : | +| string_flow.rb:267:5:267:5 | a : | string_flow.rb:268:9:268:9 | a : | +| string_flow.rb:267:9:267:18 | call to source : | string_flow.rb:267:5:267:5 | a : | +| string_flow.rb:268:5:268:5 | b [element] : | string_flow.rb:269:10:269:10 | b [element] : | | string_flow.rb:268:9:268:9 | a : | string_flow.rb:268:9:268:20 | call to shellsplit [element] : | -| string_flow.rb:268:9:268:20 | call to shellsplit [element] : | string_flow.rb:269:10:269:10 | b [element] : | +| string_flow.rb:268:9:268:20 | call to shellsplit [element] : | string_flow.rb:268:5:268:5 | b [element] : | | string_flow.rb:269:10:269:10 | b [element] : | string_flow.rb:269:10:269:13 | ...[...] | -| string_flow.rb:273:9:273:18 | call to source : | string_flow.rb:274:9:274:9 | a : | -| string_flow.rb:273:9:273:18 | call to source : | string_flow.rb:277:9:277:9 | a : | +| string_flow.rb:273:5:273:5 | a : | string_flow.rb:274:9:274:9 | a : | +| string_flow.rb:273:5:273:5 | a : | string_flow.rb:277:9:277:9 | a : | +| string_flow.rb:273:9:273:18 | call to source : | string_flow.rb:273:5:273:5 | a : | +| string_flow.rb:274:5:274:5 | b : | string_flow.rb:275:10:275:10 | b : | | string_flow.rb:274:9:274:9 | a : | string_flow.rb:274:9:274:18 | call to slice : | -| string_flow.rb:274:9:274:18 | call to slice : | string_flow.rb:275:10:275:10 | b : | +| string_flow.rb:274:9:274:18 | call to slice : | string_flow.rb:274:5:274:5 | b : | | string_flow.rb:275:10:275:10 | b : | string_flow.rb:275:10:275:13 | ...[...] | +| string_flow.rb:277:5:277:5 | b : | string_flow.rb:278:10:278:10 | b : | | string_flow.rb:277:9:277:9 | [post] a : | string_flow.rb:280:9:280:9 | a : | | string_flow.rb:277:9:277:9 | [post] a : | string_flow.rb:283:9:283:9 | a : | | string_flow.rb:277:9:277:9 | [post] a [element 1] : | string_flow.rb:283:9:283:9 | a [element 1] : | @@ -242,45 +299,53 @@ edges | string_flow.rb:277:9:277:9 | a : | string_flow.rb:277:9:277:9 | [post] a [element 2] : | | string_flow.rb:277:9:277:9 | a : | string_flow.rb:277:9:277:9 | [post] a [element] : | | string_flow.rb:277:9:277:9 | a : | string_flow.rb:277:9:277:19 | call to slice! : | -| string_flow.rb:277:9:277:19 | call to slice! : | string_flow.rb:278:10:278:10 | b : | +| string_flow.rb:277:9:277:19 | call to slice! : | string_flow.rb:277:5:277:5 | b : | | string_flow.rb:278:10:278:10 | b : | string_flow.rb:278:10:278:13 | ...[...] | +| string_flow.rb:280:5:280:5 | b : | string_flow.rb:281:10:281:10 | b : | | string_flow.rb:280:9:280:9 | a : | string_flow.rb:280:9:280:20 | call to split : | -| string_flow.rb:280:9:280:20 | call to split : | string_flow.rb:281:10:281:10 | b : | +| string_flow.rb:280:9:280:20 | call to split : | string_flow.rb:280:5:280:5 | b : | | string_flow.rb:281:10:281:10 | b : | string_flow.rb:281:10:281:13 | ...[...] | +| string_flow.rb:283:5:283:5 | b : | string_flow.rb:284:10:284:10 | b : | +| string_flow.rb:283:5:283:5 | b [element 0] : | string_flow.rb:284:10:284:10 | b [element 0] : | +| string_flow.rb:283:5:283:5 | b [element 1] : | string_flow.rb:284:10:284:10 | b [element 1] : | +| string_flow.rb:283:5:283:5 | b [element] : | string_flow.rb:284:10:284:10 | b [element] : | | string_flow.rb:283:9:283:9 | a : | string_flow.rb:283:9:283:14 | ...[...] : | | string_flow.rb:283:9:283:9 | a : | string_flow.rb:283:9:283:14 | ...[...] [element 0] : | | string_flow.rb:283:9:283:9 | a : | string_flow.rb:283:9:283:14 | ...[...] [element 1] : | | string_flow.rb:283:9:283:9 | a [element 1] : | string_flow.rb:283:9:283:14 | ...[...] [element 0] : | | string_flow.rb:283:9:283:9 | a [element 2] : | string_flow.rb:283:9:283:14 | ...[...] [element 1] : | | string_flow.rb:283:9:283:9 | a [element] : | string_flow.rb:283:9:283:14 | ...[...] [element] : | -| string_flow.rb:283:9:283:14 | ...[...] : | string_flow.rb:284:10:284:10 | b : | -| string_flow.rb:283:9:283:14 | ...[...] [element 0] : | string_flow.rb:284:10:284:10 | b [element 0] : | -| string_flow.rb:283:9:283:14 | ...[...] [element 1] : | string_flow.rb:284:10:284:10 | b [element 1] : | -| string_flow.rb:283:9:283:14 | ...[...] [element] : | string_flow.rb:284:10:284:10 | b [element] : | +| string_flow.rb:283:9:283:14 | ...[...] : | string_flow.rb:283:5:283:5 | b : | +| string_flow.rb:283:9:283:14 | ...[...] [element 0] : | string_flow.rb:283:5:283:5 | b [element 0] : | +| string_flow.rb:283:9:283:14 | ...[...] [element 1] : | string_flow.rb:283:5:283:5 | b [element 1] : | +| string_flow.rb:283:9:283:14 | ...[...] [element] : | string_flow.rb:283:5:283:5 | b [element] : | | string_flow.rb:284:10:284:10 | b : | string_flow.rb:284:10:284:13 | ...[...] | | string_flow.rb:284:10:284:10 | b [element 0] : | string_flow.rb:284:10:284:13 | ...[...] | | string_flow.rb:284:10:284:10 | b [element 1] : | string_flow.rb:284:10:284:13 | ...[...] | | string_flow.rb:284:10:284:10 | b [element] : | string_flow.rb:284:10:284:13 | ...[...] | -| string_flow.rb:288:9:288:18 | call to source : | string_flow.rb:289:10:289:10 | a : | -| string_flow.rb:288:9:288:18 | call to source : | string_flow.rb:290:10:290:10 | a : | -| string_flow.rb:288:9:288:18 | call to source : | string_flow.rb:291:10:291:10 | a : | -| string_flow.rb:288:9:288:18 | call to source : | string_flow.rb:292:10:292:10 | a : | +| string_flow.rb:288:5:288:5 | a : | string_flow.rb:289:10:289:10 | a : | +| string_flow.rb:288:5:288:5 | a : | string_flow.rb:290:10:290:10 | a : | +| string_flow.rb:288:5:288:5 | a : | string_flow.rb:291:10:291:10 | a : | +| string_flow.rb:288:5:288:5 | a : | string_flow.rb:292:10:292:10 | a : | +| string_flow.rb:288:9:288:18 | call to source : | string_flow.rb:288:5:288:5 | a : | | string_flow.rb:289:10:289:10 | a : | string_flow.rb:289:10:289:18 | call to squeeze | | string_flow.rb:290:10:290:10 | a : | string_flow.rb:290:10:290:23 | call to squeeze | | string_flow.rb:291:10:291:10 | a : | string_flow.rb:291:10:291:19 | call to squeeze! | | string_flow.rb:292:10:292:10 | a : | string_flow.rb:292:10:292:24 | call to squeeze! | -| string_flow.rb:296:9:296:18 | call to source : | string_flow.rb:297:10:297:10 | a : | -| string_flow.rb:296:9:296:18 | call to source : | string_flow.rb:298:10:298:10 | a : | +| string_flow.rb:296:5:296:5 | a : | string_flow.rb:297:10:297:10 | a : | +| string_flow.rb:296:5:296:5 | a : | string_flow.rb:298:10:298:10 | a : | +| string_flow.rb:296:9:296:18 | call to source : | string_flow.rb:296:5:296:5 | a : | | string_flow.rb:297:10:297:10 | a : | string_flow.rb:297:10:297:17 | call to to_str | | string_flow.rb:298:10:298:10 | a : | string_flow.rb:298:10:298:15 | call to to_s | -| string_flow.rb:302:9:302:18 | call to source : | string_flow.rb:303:10:303:10 | a : | -| string_flow.rb:302:9:302:18 | call to source : | string_flow.rb:304:22:304:22 | a : | -| string_flow.rb:302:9:302:18 | call to source : | string_flow.rb:305:10:305:10 | a : | -| string_flow.rb:302:9:302:18 | call to source : | string_flow.rb:306:23:306:23 | a : | -| string_flow.rb:302:9:302:18 | call to source : | string_flow.rb:307:10:307:10 | a : | -| string_flow.rb:302:9:302:18 | call to source : | string_flow.rb:308:24:308:24 | a : | -| string_flow.rb:302:9:302:18 | call to source : | string_flow.rb:309:10:309:10 | a : | -| string_flow.rb:302:9:302:18 | call to source : | string_flow.rb:310:25:310:25 | a : | +| string_flow.rb:302:5:302:5 | a : | string_flow.rb:303:10:303:10 | a : | +| string_flow.rb:302:5:302:5 | a : | string_flow.rb:304:22:304:22 | a : | +| string_flow.rb:302:5:302:5 | a : | string_flow.rb:305:10:305:10 | a : | +| string_flow.rb:302:5:302:5 | a : | string_flow.rb:306:23:306:23 | a : | +| string_flow.rb:302:5:302:5 | a : | string_flow.rb:307:10:307:10 | a : | +| string_flow.rb:302:5:302:5 | a : | string_flow.rb:308:24:308:24 | a : | +| string_flow.rb:302:5:302:5 | a : | string_flow.rb:309:10:309:10 | a : | +| string_flow.rb:302:5:302:5 | a : | string_flow.rb:310:25:310:25 | a : | +| string_flow.rb:302:9:302:18 | call to source : | string_flow.rb:302:5:302:5 | a : | | string_flow.rb:303:10:303:10 | a : | string_flow.rb:303:10:303:23 | call to tr | | string_flow.rb:304:22:304:22 | a : | string_flow.rb:304:10:304:23 | call to tr | | string_flow.rb:305:10:305:10 | a : | string_flow.rb:305:10:305:24 | call to tr! | @@ -289,9 +354,10 @@ edges | string_flow.rb:308:24:308:24 | a : | string_flow.rb:308:10:308:25 | call to tr_s | | string_flow.rb:309:10:309:10 | a : | string_flow.rb:309:10:309:26 | call to tr_s! | | string_flow.rb:310:25:310:25 | a : | string_flow.rb:310:10:310:26 | call to tr_s! | -| string_flow.rb:314:9:314:18 | call to source : | string_flow.rb:315:5:315:5 | a : | -| string_flow.rb:314:9:314:18 | call to source : | string_flow.rb:316:5:316:5 | a : | -| string_flow.rb:314:9:314:18 | call to source : | string_flow.rb:317:14:317:14 | a : | +| string_flow.rb:314:5:314:5 | a : | string_flow.rb:315:5:315:5 | a : | +| string_flow.rb:314:5:314:5 | a : | string_flow.rb:316:5:316:5 | a : | +| string_flow.rb:314:5:314:5 | a : | string_flow.rb:317:14:317:14 | a : | +| string_flow.rb:314:9:314:18 | call to source : | string_flow.rb:314:5:314:5 | a : | | string_flow.rb:315:5:315:5 | a : | string_flow.rb:315:20:315:20 | x : | | string_flow.rb:315:20:315:20 | x : | string_flow.rb:315:28:315:28 | x | | string_flow.rb:316:5:316:5 | a : | string_flow.rb:316:26:316:26 | x : | @@ -299,18 +365,23 @@ edges | string_flow.rb:317:14:317:14 | a : | string_flow.rb:317:20:317:20 | x : | | string_flow.rb:317:20:317:20 | x : | string_flow.rb:317:28:317:28 | x | nodes +| string_flow.rb:2:5:2:5 | a : | semmle.label | a : | +| string_flow.rb:2:5:2:5 | a : | semmle.label | a : | | string_flow.rb:2:9:2:18 | call to source : | semmle.label | call to source : | | string_flow.rb:2:9:2:18 | call to source : | semmle.label | call to source : | | string_flow.rb:3:10:3:22 | call to new | semmle.label | call to new | | string_flow.rb:3:10:3:22 | call to new | semmle.label | call to new | | string_flow.rb:3:21:3:21 | a : | semmle.label | a : | | string_flow.rb:3:21:3:21 | a : | semmle.label | a : | +| string_flow.rb:7:5:7:5 | a : | semmle.label | a : | | string_flow.rb:7:9:7:18 | call to source : | semmle.label | call to source : | +| string_flow.rb:8:5:8:5 | b : | semmle.label | b : | | string_flow.rb:8:9:8:16 | call to source : | semmle.label | call to source : | | string_flow.rb:9:10:9:30 | call to try_convert | semmle.label | call to try_convert | | string_flow.rb:9:29:9:29 | a : | semmle.label | a : | | string_flow.rb:10:10:10:30 | call to try_convert | semmle.label | call to try_convert | | string_flow.rb:10:29:10:29 | b : | semmle.label | b : | +| string_flow.rb:14:5:14:5 | a : | semmle.label | a : | | string_flow.rb:14:9:14:18 | call to source : | semmle.label | call to source : | | string_flow.rb:15:10:15:17 | ... % ... | semmle.label | ... % ... | | string_flow.rb:15:17:15:17 | a : | semmle.label | a : | @@ -318,16 +389,25 @@ nodes | string_flow.rb:16:28:16:28 | a : | semmle.label | a : | | string_flow.rb:17:10:17:10 | a : | semmle.label | a : | | string_flow.rb:17:10:17:18 | ... % ... | semmle.label | ... % ... | +| string_flow.rb:21:5:21:5 | a : | semmle.label | a : | | string_flow.rb:21:9:21:18 | call to source : | semmle.label | call to source : | +| string_flow.rb:22:5:22:5 | b : | semmle.label | b : | | string_flow.rb:23:10:23:10 | b | semmle.label | b | +| string_flow.rb:27:5:27:5 | a : | semmle.label | a : | | string_flow.rb:27:9:27:18 | call to source : | semmle.label | call to source : | +| string_flow.rb:28:5:28:5 | b : | semmle.label | b : | | string_flow.rb:29:10:29:10 | b | semmle.label | b | +| string_flow.rb:33:5:33:5 | a : | semmle.label | a : | | string_flow.rb:33:9:33:18 | call to source : | semmle.label | call to source : | +| string_flow.rb:34:5:34:5 | b : | semmle.label | b : | | string_flow.rb:35:10:35:10 | b | semmle.label | b | +| string_flow.rb:36:5:36:5 | c : | semmle.label | c : | | string_flow.rb:37:10:37:10 | c | semmle.label | c | +| string_flow.rb:41:5:41:5 | a : | semmle.label | a : | | string_flow.rb:41:9:41:18 | call to source : | semmle.label | call to source : | | string_flow.rb:42:10:42:10 | a : | semmle.label | a : | | string_flow.rb:42:10:42:12 | call to b | semmle.label | call to b | +| string_flow.rb:46:5:46:5 | a : | semmle.label | a : | | string_flow.rb:46:9:46:18 | call to source : | semmle.label | call to source : | | string_flow.rb:47:10:47:10 | a : | semmle.label | a : | | string_flow.rb:47:10:47:23 | call to byteslice | semmle.label | call to byteslice | @@ -335,11 +415,13 @@ nodes | string_flow.rb:48:10:48:26 | call to byteslice | semmle.label | call to byteslice | | string_flow.rb:49:10:49:10 | a : | semmle.label | a : | | string_flow.rb:49:10:49:26 | call to byteslice | semmle.label | call to byteslice | +| string_flow.rb:53:5:53:5 | a : | semmle.label | a : | | string_flow.rb:53:9:53:18 | call to source : | semmle.label | call to source : | | string_flow.rb:54:10:54:10 | a : | semmle.label | a : | | string_flow.rb:54:10:54:21 | call to capitalize | semmle.label | call to capitalize | | string_flow.rb:55:10:55:10 | a : | semmle.label | a : | | string_flow.rb:55:10:55:22 | call to capitalize! | semmle.label | call to capitalize! | +| string_flow.rb:59:5:59:5 | a : | semmle.label | a : | | string_flow.rb:59:9:59:18 | call to source : | semmle.label | call to source : | | string_flow.rb:60:10:60:10 | a : | semmle.label | a : | | string_flow.rb:60:10:60:21 | call to center | semmle.label | call to center | @@ -353,16 +435,20 @@ nodes | string_flow.rb:64:10:64:20 | call to rjust | semmle.label | call to rjust | | string_flow.rb:65:10:65:27 | call to rjust | semmle.label | call to rjust | | string_flow.rb:65:26:65:26 | a : | semmle.label | a : | +| string_flow.rb:69:5:69:5 | a : | semmle.label | a : | | string_flow.rb:69:9:69:18 | call to source : | semmle.label | call to source : | | string_flow.rb:70:10:70:10 | a : | semmle.label | a : | | string_flow.rb:70:10:70:16 | call to chomp | semmle.label | call to chomp | | string_flow.rb:71:10:71:10 | a : | semmle.label | a : | | string_flow.rb:71:10:71:17 | call to chomp! | semmle.label | call to chomp! | +| string_flow.rb:75:5:75:5 | a : | semmle.label | a : | | string_flow.rb:75:9:75:18 | call to source : | semmle.label | call to source : | | string_flow.rb:76:10:76:10 | a : | semmle.label | a : | | string_flow.rb:76:10:76:15 | call to chop | semmle.label | call to chop | | string_flow.rb:77:10:77:10 | a : | semmle.label | a : | | string_flow.rb:77:10:77:16 | call to chop! | semmle.label | call to chop! | +| string_flow.rb:83:5:83:5 | a : | semmle.label | a : | +| string_flow.rb:83:5:83:5 | a : | semmle.label | a : | | string_flow.rb:83:9:83:18 | call to source : | semmle.label | call to source : | | string_flow.rb:83:9:83:18 | call to source : | semmle.label | call to source : | | string_flow.rb:84:5:84:5 | [post] a : | semmle.label | [post] a : | @@ -371,6 +457,7 @@ nodes | string_flow.rb:84:5:84:5 | a : | semmle.label | a : | | string_flow.rb:85:10:85:10 | a | semmle.label | a | | string_flow.rb:85:10:85:10 | a | semmle.label | a | +| string_flow.rb:108:5:108:5 | a : | semmle.label | a : | | string_flow.rb:108:9:108:18 | call to source : | semmle.label | call to source : | | string_flow.rb:109:10:109:10 | [post] a : | semmle.label | [post] a : | | string_flow.rb:109:10:109:10 | a : | semmle.label | a : | @@ -379,6 +466,7 @@ nodes | string_flow.rb:110:10:110:29 | call to delete_prefix | semmle.label | call to delete_prefix | | string_flow.rb:111:10:111:10 | a : | semmle.label | a : | | string_flow.rb:111:10:111:29 | call to delete_suffix | semmle.label | call to delete_suffix | +| string_flow.rb:115:5:115:5 | a : | semmle.label | a : | | string_flow.rb:115:9:115:18 | call to source : | semmle.label | call to source : | | string_flow.rb:116:10:116:10 | a : | semmle.label | a : | | string_flow.rb:116:10:116:19 | call to downcase | semmle.label | call to downcase | @@ -392,33 +480,42 @@ nodes | string_flow.rb:120:10:120:17 | call to upcase | semmle.label | call to upcase | | string_flow.rb:121:10:121:10 | a : | semmle.label | a : | | string_flow.rb:121:10:121:18 | call to upcase! | semmle.label | call to upcase! | +| string_flow.rb:125:5:125:5 | a : | semmle.label | a : | | string_flow.rb:125:9:125:18 | call to source : | semmle.label | call to source : | +| string_flow.rb:126:5:126:5 | b : | semmle.label | b : | | string_flow.rb:126:9:126:9 | a : | semmle.label | a : | | string_flow.rb:126:9:126:14 | call to dump : | semmle.label | call to dump : | | string_flow.rb:127:10:127:10 | b | semmle.label | b | | string_flow.rb:128:10:128:10 | b : | semmle.label | b : | | string_flow.rb:128:10:128:17 | call to undump | semmle.label | call to undump | +| string_flow.rb:132:5:132:5 | a : | semmle.label | a : | | string_flow.rb:132:9:132:18 | call to source : | semmle.label | call to source : | +| string_flow.rb:133:5:133:5 | b : | semmle.label | b : | | string_flow.rb:133:9:133:9 | a : | semmle.label | a : | | string_flow.rb:133:9:133:40 | call to each_line : | semmle.label | call to each_line : | | string_flow.rb:133:24:133:27 | line : | semmle.label | line : | | string_flow.rb:133:35:133:38 | line | semmle.label | line | | string_flow.rb:134:10:134:10 | b | semmle.label | b | +| string_flow.rb:135:5:135:5 | c [element] : | semmle.label | c [element] : | | string_flow.rb:135:9:135:9 | a : | semmle.label | a : | | string_flow.rb:135:9:135:19 | call to each_line [element] : | semmle.label | call to each_line [element] : | | string_flow.rb:136:10:136:10 | c [element] : | semmle.label | c [element] : | | string_flow.rb:136:10:136:15 | call to to_a [element] : | semmle.label | call to to_a [element] : | | string_flow.rb:136:10:136:18 | ...[...] | semmle.label | ...[...] | +| string_flow.rb:140:5:140:5 | a : | semmle.label | a : | | string_flow.rb:140:9:140:18 | call to source : | semmle.label | call to source : | +| string_flow.rb:141:5:141:5 | b : | semmle.label | b : | | string_flow.rb:141:9:141:9 | a : | semmle.label | a : | | string_flow.rb:141:9:141:36 | call to lines : | semmle.label | call to lines : | | string_flow.rb:141:20:141:23 | line : | semmle.label | line : | | string_flow.rb:141:31:141:34 | line | semmle.label | line | | string_flow.rb:142:10:142:10 | b | semmle.label | b | +| string_flow.rb:143:5:143:5 | c [element] : | semmle.label | c [element] : | | string_flow.rb:143:9:143:9 | a : | semmle.label | a : | | string_flow.rb:143:9:143:15 | call to lines [element] : | semmle.label | call to lines [element] : | | string_flow.rb:144:10:144:10 | c [element] : | semmle.label | c [element] : | | string_flow.rb:144:10:144:13 | ...[...] | semmle.label | ...[...] | +| string_flow.rb:148:5:148:5 | a : | semmle.label | a : | | string_flow.rb:148:9:148:18 | call to source : | semmle.label | call to source : | | string_flow.rb:149:10:149:10 | a : | semmle.label | a : | | string_flow.rb:149:10:149:26 | call to encode | semmle.label | call to encode | @@ -428,13 +525,17 @@ nodes | string_flow.rb:151:10:151:28 | call to unicode_normalize | semmle.label | call to unicode_normalize | | string_flow.rb:152:10:152:10 | a : | semmle.label | a : | | string_flow.rb:152:10:152:29 | call to unicode_normalize! | semmle.label | call to unicode_normalize! | +| string_flow.rb:156:5:156:5 | a : | semmle.label | a : | | string_flow.rb:156:9:156:18 | call to source : | semmle.label | call to source : | | string_flow.rb:157:10:157:10 | a : | semmle.label | a : | | string_flow.rb:157:10:157:34 | call to force_encoding | semmle.label | call to force_encoding | +| string_flow.rb:161:5:161:5 | a : | semmle.label | a : | | string_flow.rb:161:9:161:18 | call to source : | semmle.label | call to source : | | string_flow.rb:162:10:162:10 | a : | semmle.label | a : | | string_flow.rb:162:10:162:17 | call to freeze | semmle.label | call to freeze | +| string_flow.rb:166:5:166:5 | a : | semmle.label | a : | | string_flow.rb:166:9:166:18 | call to source : | semmle.label | call to source : | +| string_flow.rb:167:5:167:5 | c : | semmle.label | c : | | string_flow.rb:167:9:167:18 | call to source : | semmle.label | call to source : | | string_flow.rb:168:10:168:10 | a : | semmle.label | a : | | string_flow.rb:168:10:168:23 | call to gsub | semmle.label | call to gsub | @@ -448,7 +549,9 @@ nodes | string_flow.rb:171:10:171:10 | a : | semmle.label | a : | | string_flow.rb:171:10:171:44 | call to gsub! | semmle.label | call to gsub! | | string_flow.rb:171:33:171:42 | call to source : | semmle.label | call to source : | +| string_flow.rb:175:5:175:5 | a : | semmle.label | a : | | string_flow.rb:175:9:175:18 | call to source : | semmle.label | call to source : | +| string_flow.rb:176:5:176:5 | c : | semmle.label | c : | | string_flow.rb:176:9:176:18 | call to source : | semmle.label | call to source : | | string_flow.rb:177:10:177:10 | a : | semmle.label | a : | | string_flow.rb:177:10:177:22 | call to sub | semmle.label | call to sub | @@ -462,9 +565,11 @@ nodes | string_flow.rb:180:10:180:10 | a : | semmle.label | a : | | string_flow.rb:180:10:180:43 | call to sub! | semmle.label | call to sub! | | string_flow.rb:180:32:180:41 | call to source : | semmle.label | call to source : | +| string_flow.rb:191:5:191:5 | a : | semmle.label | a : | | string_flow.rb:191:9:191:18 | call to source : | semmle.label | call to source : | | string_flow.rb:192:10:192:10 | a : | semmle.label | a : | | string_flow.rb:192:10:192:18 | call to inspect | semmle.label | call to inspect | +| string_flow.rb:196:5:196:5 | a : | semmle.label | a : | | string_flow.rb:196:9:196:18 | call to source : | semmle.label | call to source : | | string_flow.rb:197:10:197:10 | a : | semmle.label | a : | | string_flow.rb:197:10:197:16 | call to strip | semmle.label | call to strip | @@ -478,6 +583,7 @@ nodes | string_flow.rb:201:10:201:17 | call to rstrip | semmle.label | call to rstrip | | string_flow.rb:202:10:202:10 | a : | semmle.label | a : | | string_flow.rb:202:10:202:18 | call to rstrip! | semmle.label | call to rstrip! | +| string_flow.rb:206:5:206:5 | a : | semmle.label | a : | | string_flow.rb:206:9:206:18 | call to source : | semmle.label | call to source : | | string_flow.rb:207:10:207:10 | a : | semmle.label | a : | | string_flow.rb:207:10:207:15 | call to next | semmle.label | call to next | @@ -487,7 +593,11 @@ nodes | string_flow.rb:209:10:209:15 | call to succ | semmle.label | call to succ | | string_flow.rb:210:10:210:10 | a : | semmle.label | a : | | string_flow.rb:210:10:210:16 | call to succ! | semmle.label | call to succ! | +| string_flow.rb:214:5:214:5 | a : | semmle.label | a : | | string_flow.rb:214:9:214:18 | call to source : | semmle.label | call to source : | +| string_flow.rb:215:5:215:5 | b [element 0] : | semmle.label | b [element 0] : | +| string_flow.rb:215:5:215:5 | b [element 1] : | semmle.label | b [element 1] : | +| string_flow.rb:215:5:215:5 | b [element 2] : | semmle.label | b [element 2] : | | string_flow.rb:215:9:215:9 | a : | semmle.label | a : | | string_flow.rb:215:9:215:24 | call to partition [element 0] : | semmle.label | call to partition [element 0] : | | string_flow.rb:215:9:215:24 | call to partition [element 1] : | semmle.label | call to partition [element 1] : | @@ -498,8 +608,11 @@ nodes | string_flow.rb:217:10:217:13 | ...[...] | semmle.label | ...[...] | | string_flow.rb:218:10:218:10 | b [element 2] : | semmle.label | b [element 2] : | | string_flow.rb:218:10:218:13 | ...[...] | semmle.label | ...[...] | +| string_flow.rb:223:5:223:5 | a : | semmle.label | a : | +| string_flow.rb:223:5:223:5 | a : | semmle.label | a : | | string_flow.rb:223:9:223:18 | call to source : | semmle.label | call to source : | | string_flow.rb:223:9:223:18 | call to source : | semmle.label | call to source : | +| string_flow.rb:224:5:224:5 | b : | semmle.label | b : | | string_flow.rb:224:9:224:18 | call to source : | semmle.label | call to source : | | string_flow.rb:225:10:225:10 | [post] a : | semmle.label | [post] a : | | string_flow.rb:225:10:225:10 | [post] a : | semmle.label | [post] a : | @@ -509,25 +622,29 @@ nodes | string_flow.rb:225:20:225:20 | b : | semmle.label | b : | | string_flow.rb:227:10:227:10 | a | semmle.label | a | | string_flow.rb:227:10:227:10 | a | semmle.label | a | +| string_flow.rb:231:5:231:5 | a : | semmle.label | a : | | string_flow.rb:231:9:231:18 | call to source : | semmle.label | call to source : | | string_flow.rb:232:10:232:10 | a : | semmle.label | a : | | string_flow.rb:232:10:232:18 | call to reverse | semmle.label | call to reverse | +| string_flow.rb:236:5:236:5 | a : | semmle.label | a : | | string_flow.rb:236:9:236:18 | call to source : | semmle.label | call to source : | | string_flow.rb:237:9:237:9 | a : | semmle.label | a : | | string_flow.rb:237:24:237:24 | x : | semmle.label | x : | | string_flow.rb:237:35:237:35 | x | semmle.label | x | +| string_flow.rb:238:5:238:5 | b : | semmle.label | b : | | string_flow.rb:238:9:238:9 | a : | semmle.label | a : | | string_flow.rb:238:9:238:37 | call to scan : | semmle.label | call to scan : | | string_flow.rb:238:27:238:27 | y : | semmle.label | y : | | string_flow.rb:238:35:238:35 | y | semmle.label | y | | string_flow.rb:239:10:239:10 | b | semmle.label | b | +| string_flow.rb:240:5:240:5 | b [element] : | semmle.label | b [element] : | | string_flow.rb:240:9:240:9 | a : | semmle.label | a : | | string_flow.rb:240:9:240:19 | call to scan [element] : | semmle.label | call to scan [element] : | | string_flow.rb:241:10:241:10 | b [element] : | semmle.label | b [element] : | | string_flow.rb:241:10:241:13 | ...[...] | semmle.label | ...[...] | | string_flow.rb:242:10:242:10 | b [element] : | semmle.label | b [element] : | | string_flow.rb:242:10:242:13 | ...[...] | semmle.label | ...[...] | -| string_flow.rb:246:5:246:18 | ... = ... : | semmle.label | ... = ... : | +| string_flow.rb:246:5:246:5 | a : | semmle.label | a : | | string_flow.rb:246:9:246:18 | call to source : | semmle.label | call to source : | | string_flow.rb:247:10:247:10 | a : | semmle.label | a : | | string_flow.rb:247:10:247:21 | call to scrub | semmle.label | call to scrub | @@ -542,26 +659,32 @@ nodes | string_flow.rb:252:10:252:22 | call to scrub! | semmle.label | call to scrub! | | string_flow.rb:253:10:253:22 | call to scrub! | semmle.label | call to scrub! | | string_flow.rb:253:21:253:21 | a : | semmle.label | a : | -| string_flow.rb:255:5:255:18 | ... = ... : | semmle.label | ... = ... : | +| string_flow.rb:255:5:255:5 | a : | semmle.label | a : | | string_flow.rb:255:9:255:18 | call to source : | semmle.label | call to source : | | string_flow.rb:256:5:256:5 | a : | semmle.label | a : | | string_flow.rb:256:17:256:17 | x : | semmle.label | x : | | string_flow.rb:256:25:256:25 | x | semmle.label | x | | string_flow.rb:258:10:258:29 | call to scrub! | semmle.label | call to scrub! | | string_flow.rb:258:27:258:27 | a : | semmle.label | a : | +| string_flow.rb:262:5:262:5 | a : | semmle.label | a : | | string_flow.rb:262:9:262:18 | call to source : | semmle.label | call to source : | | string_flow.rb:263:10:263:10 | a : | semmle.label | a : | | string_flow.rb:263:10:263:22 | call to shellescape | semmle.label | call to shellescape | +| string_flow.rb:267:5:267:5 | a : | semmle.label | a : | | string_flow.rb:267:9:267:18 | call to source : | semmle.label | call to source : | +| string_flow.rb:268:5:268:5 | b [element] : | semmle.label | b [element] : | | string_flow.rb:268:9:268:9 | a : | semmle.label | a : | | string_flow.rb:268:9:268:20 | call to shellsplit [element] : | semmle.label | call to shellsplit [element] : | | string_flow.rb:269:10:269:10 | b [element] : | semmle.label | b [element] : | | string_flow.rb:269:10:269:13 | ...[...] | semmle.label | ...[...] | +| string_flow.rb:273:5:273:5 | a : | semmle.label | a : | | string_flow.rb:273:9:273:18 | call to source : | semmle.label | call to source : | +| string_flow.rb:274:5:274:5 | b : | semmle.label | b : | | string_flow.rb:274:9:274:9 | a : | semmle.label | a : | | string_flow.rb:274:9:274:18 | call to slice : | semmle.label | call to slice : | | string_flow.rb:275:10:275:10 | b : | semmle.label | b : | | string_flow.rb:275:10:275:13 | ...[...] | semmle.label | ...[...] | +| string_flow.rb:277:5:277:5 | b : | semmle.label | b : | | string_flow.rb:277:9:277:9 | [post] a : | semmle.label | [post] a : | | string_flow.rb:277:9:277:9 | [post] a [element 1] : | semmle.label | [post] a [element 1] : | | string_flow.rb:277:9:277:9 | [post] a [element 2] : | semmle.label | [post] a [element 2] : | @@ -570,10 +693,15 @@ nodes | string_flow.rb:277:9:277:19 | call to slice! : | semmle.label | call to slice! : | | string_flow.rb:278:10:278:10 | b : | semmle.label | b : | | string_flow.rb:278:10:278:13 | ...[...] | semmle.label | ...[...] | +| string_flow.rb:280:5:280:5 | b : | semmle.label | b : | | string_flow.rb:280:9:280:9 | a : | semmle.label | a : | | string_flow.rb:280:9:280:20 | call to split : | semmle.label | call to split : | | string_flow.rb:281:10:281:10 | b : | semmle.label | b : | | string_flow.rb:281:10:281:13 | ...[...] | semmle.label | ...[...] | +| string_flow.rb:283:5:283:5 | b : | semmle.label | b : | +| string_flow.rb:283:5:283:5 | b [element 0] : | semmle.label | b [element 0] : | +| string_flow.rb:283:5:283:5 | b [element 1] : | semmle.label | b [element 1] : | +| string_flow.rb:283:5:283:5 | b [element] : | semmle.label | b [element] : | | string_flow.rb:283:9:283:9 | a : | semmle.label | a : | | string_flow.rb:283:9:283:9 | a [element 1] : | semmle.label | a [element 1] : | | string_flow.rb:283:9:283:9 | a [element 2] : | semmle.label | a [element 2] : | @@ -587,6 +715,7 @@ nodes | string_flow.rb:284:10:284:10 | b [element 1] : | semmle.label | b [element 1] : | | string_flow.rb:284:10:284:10 | b [element] : | semmle.label | b [element] : | | string_flow.rb:284:10:284:13 | ...[...] | semmle.label | ...[...] | +| string_flow.rb:288:5:288:5 | a : | semmle.label | a : | | string_flow.rb:288:9:288:18 | call to source : | semmle.label | call to source : | | string_flow.rb:289:10:289:10 | a : | semmle.label | a : | | string_flow.rb:289:10:289:18 | call to squeeze | semmle.label | call to squeeze | @@ -596,11 +725,13 @@ nodes | string_flow.rb:291:10:291:19 | call to squeeze! | semmle.label | call to squeeze! | | string_flow.rb:292:10:292:10 | a : | semmle.label | a : | | string_flow.rb:292:10:292:24 | call to squeeze! | semmle.label | call to squeeze! | +| string_flow.rb:296:5:296:5 | a : | semmle.label | a : | | string_flow.rb:296:9:296:18 | call to source : | semmle.label | call to source : | | string_flow.rb:297:10:297:10 | a : | semmle.label | a : | | string_flow.rb:297:10:297:17 | call to to_str | semmle.label | call to to_str | | string_flow.rb:298:10:298:10 | a : | semmle.label | a : | | string_flow.rb:298:10:298:15 | call to to_s | semmle.label | call to to_s | +| string_flow.rb:302:5:302:5 | a : | semmle.label | a : | | string_flow.rb:302:9:302:18 | call to source : | semmle.label | call to source : | | string_flow.rb:303:10:303:10 | a : | semmle.label | a : | | string_flow.rb:303:10:303:23 | call to tr | semmle.label | call to tr | @@ -618,6 +749,7 @@ nodes | string_flow.rb:309:10:309:26 | call to tr_s! | semmle.label | call to tr_s! | | string_flow.rb:310:10:310:26 | call to tr_s! | semmle.label | call to tr_s! | | string_flow.rb:310:25:310:25 | a : | semmle.label | a : | +| string_flow.rb:314:5:314:5 | a : | semmle.label | a : | | string_flow.rb:314:9:314:18 | call to source : | semmle.label | call to source : | | string_flow.rb:315:5:315:5 | a : | semmle.label | a : | | string_flow.rb:315:20:315:20 | x : | semmle.label | x : | diff --git a/ruby/ql/test/library-tests/dataflow/summaries/Summaries.expected b/ruby/ql/test/library-tests/dataflow/summaries/Summaries.expected index f916520c8ce..a69c52963cb 100644 --- a/ruby/ql/test/library-tests/dataflow/summaries/Summaries.expected +++ b/ruby/ql/test/library-tests/dataflow/summaries/Summaries.expected @@ -1,53 +1,57 @@ failures edges -| summaries.rb:1:11:1:36 | call to identity : | summaries.rb:2:6:2:12 | tainted | -| summaries.rb:1:11:1:36 | call to identity : | summaries.rb:2:6:2:12 | tainted | -| summaries.rb:1:11:1:36 | call to identity : | summaries.rb:4:24:4:30 | tainted : | -| summaries.rb:1:11:1:36 | call to identity : | summaries.rb:4:24:4:30 | tainted : | -| summaries.rb:1:11:1:36 | call to identity : | summaries.rb:16:36:16:42 | tainted : | -| summaries.rb:1:11:1:36 | call to identity : | summaries.rb:16:36:16:42 | tainted : | -| summaries.rb:1:11:1:36 | call to identity : | summaries.rb:20:25:20:31 | tainted : | -| summaries.rb:1:11:1:36 | call to identity : | summaries.rb:26:31:26:37 | tainted : | -| summaries.rb:1:11:1:36 | call to identity : | summaries.rb:30:24:30:30 | tainted : | -| summaries.rb:1:11:1:36 | call to identity : | summaries.rb:31:27:31:33 | tainted : | -| summaries.rb:1:11:1:36 | call to identity : | summaries.rb:34:16:34:22 | tainted | -| summaries.rb:1:11:1:36 | call to identity : | summaries.rb:34:16:34:22 | tainted | -| summaries.rb:1:11:1:36 | call to identity : | summaries.rb:35:16:35:22 | tainted | -| summaries.rb:1:11:1:36 | call to identity : | summaries.rb:35:16:35:22 | tainted | -| summaries.rb:1:11:1:36 | call to identity : | summaries.rb:36:21:36:27 | tainted | -| summaries.rb:1:11:1:36 | call to identity : | summaries.rb:36:21:36:27 | tainted | -| summaries.rb:1:11:1:36 | call to identity : | summaries.rb:37:36:37:42 | tainted | -| summaries.rb:1:11:1:36 | call to identity : | summaries.rb:37:36:37:42 | tainted | -| summaries.rb:1:11:1:36 | call to identity : | summaries.rb:51:24:51:30 | tainted : | -| summaries.rb:1:11:1:36 | call to identity : | summaries.rb:56:22:56:28 | tainted : | -| summaries.rb:1:11:1:36 | call to identity : | summaries.rb:57:17:57:23 | tainted : | -| summaries.rb:1:11:1:36 | call to identity : | summaries.rb:59:27:59:33 | tainted : | -| summaries.rb:1:11:1:36 | call to identity : | summaries.rb:63:32:63:38 | tainted : | -| summaries.rb:1:11:1:36 | call to identity : | summaries.rb:65:23:65:29 | tainted : | -| summaries.rb:1:11:1:36 | call to identity : | summaries.rb:122:16:122:22 | tainted : | -| summaries.rb:1:11:1:36 | call to identity : | summaries.rb:128:14:128:20 | tainted : | -| summaries.rb:1:11:1:36 | call to identity : | summaries.rb:131:16:131:22 | tainted | -| summaries.rb:1:11:1:36 | call to identity : | summaries.rb:131:16:131:22 | tainted | -| summaries.rb:1:11:1:36 | call to identity : | summaries.rb:132:21:132:27 | tainted | -| summaries.rb:1:11:1:36 | call to identity : | summaries.rb:132:21:132:27 | tainted | -| summaries.rb:1:11:1:36 | call to identity : | summaries.rb:135:26:135:32 | tainted | -| summaries.rb:1:11:1:36 | call to identity : | summaries.rb:135:26:135:32 | tainted | -| summaries.rb:1:11:1:36 | call to identity : | summaries.rb:137:23:137:29 | tainted | -| summaries.rb:1:11:1:36 | call to identity : | summaries.rb:137:23:137:29 | tainted | -| summaries.rb:1:11:1:36 | call to identity : | summaries.rb:140:19:140:25 | tainted | -| summaries.rb:1:11:1:36 | call to identity : | summaries.rb:140:19:140:25 | tainted | -| summaries.rb:1:11:1:36 | call to identity : | summaries.rb:141:19:141:25 | tainted | -| summaries.rb:1:11:1:36 | call to identity : | summaries.rb:141:19:141:25 | tainted | -| summaries.rb:1:11:1:36 | call to identity : | summaries.rb:145:26:145:32 | tainted | -| summaries.rb:1:11:1:36 | call to identity : | summaries.rb:145:26:145:32 | tainted | -| summaries.rb:1:11:1:36 | call to identity : | summaries.rb:147:16:147:22 | tainted | -| summaries.rb:1:11:1:36 | call to identity : | summaries.rb:147:16:147:22 | tainted | -| summaries.rb:1:11:1:36 | call to identity : | summaries.rb:150:39:150:45 | tainted | -| summaries.rb:1:11:1:36 | call to identity : | summaries.rb:150:39:150:45 | tainted | +| summaries.rb:1:1:1:7 | tainted : | summaries.rb:2:6:2:12 | tainted | +| summaries.rb:1:1:1:7 | tainted : | summaries.rb:2:6:2:12 | tainted | +| summaries.rb:1:1:1:7 | tainted : | summaries.rb:4:24:4:30 | tainted : | +| summaries.rb:1:1:1:7 | tainted : | summaries.rb:4:24:4:30 | tainted : | +| summaries.rb:1:1:1:7 | tainted : | summaries.rb:16:36:16:42 | tainted : | +| summaries.rb:1:1:1:7 | tainted : | summaries.rb:16:36:16:42 | tainted : | +| summaries.rb:1:1:1:7 | tainted : | summaries.rb:20:25:20:31 | tainted : | +| summaries.rb:1:1:1:7 | tainted : | summaries.rb:26:31:26:37 | tainted : | +| summaries.rb:1:1:1:7 | tainted : | summaries.rb:30:24:30:30 | tainted : | +| summaries.rb:1:1:1:7 | tainted : | summaries.rb:31:27:31:33 | tainted : | +| summaries.rb:1:1:1:7 | tainted : | summaries.rb:34:16:34:22 | tainted | +| summaries.rb:1:1:1:7 | tainted : | summaries.rb:34:16:34:22 | tainted | +| summaries.rb:1:1:1:7 | tainted : | summaries.rb:35:16:35:22 | tainted | +| summaries.rb:1:1:1:7 | tainted : | summaries.rb:35:16:35:22 | tainted | +| summaries.rb:1:1:1:7 | tainted : | summaries.rb:36:21:36:27 | tainted | +| summaries.rb:1:1:1:7 | tainted : | summaries.rb:36:21:36:27 | tainted | +| summaries.rb:1:1:1:7 | tainted : | summaries.rb:37:36:37:42 | tainted | +| summaries.rb:1:1:1:7 | tainted : | summaries.rb:37:36:37:42 | tainted | +| summaries.rb:1:1:1:7 | tainted : | summaries.rb:51:24:51:30 | tainted : | +| summaries.rb:1:1:1:7 | tainted : | summaries.rb:56:22:56:28 | tainted : | +| summaries.rb:1:1:1:7 | tainted : | summaries.rb:57:17:57:23 | tainted : | +| summaries.rb:1:1:1:7 | tainted : | summaries.rb:59:27:59:33 | tainted : | +| summaries.rb:1:1:1:7 | tainted : | summaries.rb:63:32:63:38 | tainted : | +| summaries.rb:1:1:1:7 | tainted : | summaries.rb:65:23:65:29 | tainted : | +| summaries.rb:1:1:1:7 | tainted : | summaries.rb:122:16:122:22 | tainted : | +| summaries.rb:1:1:1:7 | tainted : | summaries.rb:128:14:128:20 | tainted : | +| summaries.rb:1:1:1:7 | tainted : | summaries.rb:131:16:131:22 | tainted | +| summaries.rb:1:1:1:7 | tainted : | summaries.rb:131:16:131:22 | tainted | +| summaries.rb:1:1:1:7 | tainted : | summaries.rb:132:21:132:27 | tainted | +| summaries.rb:1:1:1:7 | tainted : | summaries.rb:132:21:132:27 | tainted | +| summaries.rb:1:1:1:7 | tainted : | summaries.rb:135:26:135:32 | tainted | +| summaries.rb:1:1:1:7 | tainted : | summaries.rb:135:26:135:32 | tainted | +| summaries.rb:1:1:1:7 | tainted : | summaries.rb:137:23:137:29 | tainted | +| summaries.rb:1:1:1:7 | tainted : | summaries.rb:137:23:137:29 | tainted | +| summaries.rb:1:1:1:7 | tainted : | summaries.rb:140:19:140:25 | tainted | +| summaries.rb:1:1:1:7 | tainted : | summaries.rb:140:19:140:25 | tainted | +| summaries.rb:1:1:1:7 | tainted : | summaries.rb:141:19:141:25 | tainted | +| summaries.rb:1:1:1:7 | tainted : | summaries.rb:141:19:141:25 | tainted | +| summaries.rb:1:1:1:7 | tainted : | summaries.rb:145:26:145:32 | tainted | +| summaries.rb:1:1:1:7 | tainted : | summaries.rb:145:26:145:32 | tainted | +| summaries.rb:1:1:1:7 | tainted : | summaries.rb:147:16:147:22 | tainted | +| summaries.rb:1:1:1:7 | tainted : | summaries.rb:147:16:147:22 | tainted | +| summaries.rb:1:1:1:7 | tainted : | summaries.rb:150:39:150:45 | tainted | +| summaries.rb:1:1:1:7 | tainted : | summaries.rb:150:39:150:45 | tainted | +| summaries.rb:1:11:1:36 | call to identity : | summaries.rb:1:1:1:7 | tainted : | +| summaries.rb:1:11:1:36 | call to identity : | summaries.rb:1:1:1:7 | tainted : | | summaries.rb:1:20:1:36 | call to source : | summaries.rb:1:11:1:36 | call to identity : | | summaries.rb:1:20:1:36 | call to source : | summaries.rb:1:11:1:36 | call to identity : | -| summaries.rb:4:12:7:3 | call to apply_block : | summaries.rb:9:6:9:13 | tainted2 | -| summaries.rb:4:12:7:3 | call to apply_block : | summaries.rb:9:6:9:13 | tainted2 | +| summaries.rb:4:1:4:8 | tainted2 : | summaries.rb:9:6:9:13 | tainted2 | +| summaries.rb:4:1:4:8 | tainted2 : | summaries.rb:9:6:9:13 | tainted2 | +| summaries.rb:4:12:7:3 | call to apply_block : | summaries.rb:4:1:4:8 | tainted2 : | +| summaries.rb:4:12:7:3 | call to apply_block : | summaries.rb:4:1:4:8 | tainted2 : | | summaries.rb:4:24:4:30 | tainted : | summaries.rb:4:12:7:3 | call to apply_block : | | summaries.rb:4:24:4:30 | tainted : | summaries.rb:4:12:7:3 | call to apply_block : | | summaries.rb:4:24:4:30 | tainted : | summaries.rb:4:36:4:36 | x : | @@ -56,27 +60,33 @@ edges | summaries.rb:4:36:4:36 | x : | summaries.rb:5:8:5:8 | x | | summaries.rb:11:17:11:17 | x : | summaries.rb:12:8:12:8 | x | | summaries.rb:11:17:11:17 | x : | summaries.rb:12:8:12:8 | x | -| summaries.rb:16:12:16:43 | call to apply_lambda : | summaries.rb:18:6:18:13 | tainted3 | -| summaries.rb:16:12:16:43 | call to apply_lambda : | summaries.rb:18:6:18:13 | tainted3 | +| summaries.rb:16:1:16:8 | tainted3 : | summaries.rb:18:6:18:13 | tainted3 | +| summaries.rb:16:1:16:8 | tainted3 : | summaries.rb:18:6:18:13 | tainted3 | +| summaries.rb:16:12:16:43 | call to apply_lambda : | summaries.rb:16:1:16:8 | tainted3 : | +| summaries.rb:16:12:16:43 | call to apply_lambda : | summaries.rb:16:1:16:8 | tainted3 : | | summaries.rb:16:36:16:42 | tainted : | summaries.rb:11:17:11:17 | x : | | summaries.rb:16:36:16:42 | tainted : | summaries.rb:11:17:11:17 | x : | | summaries.rb:16:36:16:42 | tainted : | summaries.rb:16:12:16:43 | call to apply_lambda : | | summaries.rb:16:36:16:42 | tainted : | summaries.rb:16:12:16:43 | call to apply_lambda : | -| summaries.rb:20:12:20:32 | call to firstArg : | summaries.rb:21:6:21:13 | tainted4 | +| summaries.rb:20:1:20:8 | tainted4 : | summaries.rb:21:6:21:13 | tainted4 | +| summaries.rb:20:12:20:32 | call to firstArg : | summaries.rb:20:1:20:8 | tainted4 : | | summaries.rb:20:25:20:31 | tainted : | summaries.rb:20:12:20:32 | call to firstArg : | -| summaries.rb:26:12:26:38 | call to secondArg : | summaries.rb:27:6:27:13 | tainted5 | +| summaries.rb:26:1:26:8 | tainted5 : | summaries.rb:27:6:27:13 | tainted5 | +| summaries.rb:26:12:26:38 | call to secondArg : | summaries.rb:26:1:26:8 | tainted5 : | | summaries.rb:26:31:26:37 | tainted : | summaries.rb:26:12:26:38 | call to secondArg : | | summaries.rb:30:24:30:30 | tainted : | summaries.rb:30:6:30:42 | call to onlyWithBlock | | summaries.rb:31:27:31:33 | tainted : | summaries.rb:31:6:31:34 | call to onlyWithoutBlock | -| summaries.rb:40:7:40:17 | call to source : | summaries.rb:41:24:41:24 | t : | -| summaries.rb:40:7:40:17 | call to source : | summaries.rb:42:24:42:24 | t : | -| summaries.rb:40:7:40:17 | call to source : | summaries.rb:44:8:44:8 | t : | +| summaries.rb:40:3:40:3 | t : | summaries.rb:41:24:41:24 | t : | +| summaries.rb:40:3:40:3 | t : | summaries.rb:42:24:42:24 | t : | +| summaries.rb:40:3:40:3 | t : | summaries.rb:44:8:44:8 | t : | +| summaries.rb:40:7:40:17 | call to source : | summaries.rb:40:3:40:3 | t : | | summaries.rb:41:24:41:24 | t : | summaries.rb:41:8:41:25 | call to matchedByName | | summaries.rb:42:24:42:24 | t : | summaries.rb:42:8:42:25 | call to matchedByName | | summaries.rb:44:8:44:8 | t : | summaries.rb:44:8:44:27 | call to matchedByNameRcv | | summaries.rb:48:24:48:41 | call to source : | summaries.rb:48:8:48:42 | call to preserveTaint | | summaries.rb:51:24:51:30 | tainted : | summaries.rb:51:6:51:31 | call to namedArg | -| summaries.rb:53:15:53:31 | call to source : | summaries.rb:54:21:54:24 | args [element :foo] : | +| summaries.rb:53:1:53:4 | args [element :foo] : | summaries.rb:54:21:54:24 | args [element :foo] : | +| summaries.rb:53:15:53:31 | call to source : | summaries.rb:53:1:53:4 | args [element :foo] : | | summaries.rb:54:19:54:24 | ** ... [element :foo] : | summaries.rb:54:6:54:25 | call to namedArg | | summaries.rb:54:21:54:24 | args [element :foo] : | summaries.rb:54:19:54:24 | ** ... [element :foo] : | | summaries.rb:56:22:56:28 | tainted : | summaries.rb:56:6:56:29 | call to anyArg | @@ -87,20 +97,24 @@ edges | summaries.rb:65:40:65:40 | x : | summaries.rb:66:8:66:8 | x | | summaries.rb:73:24:73:53 | call to source : | summaries.rb:73:8:73:54 | call to preserveTaint | | summaries.rb:76:26:76:56 | call to source : | summaries.rb:76:8:76:57 | call to preserveTaint | -| summaries.rb:79:15:79:29 | call to source : | summaries.rb:82:6:82:6 | a [element 1] : | -| summaries.rb:79:15:79:29 | call to source : | summaries.rb:82:6:82:6 | a [element 1] : | -| summaries.rb:79:15:79:29 | call to source : | summaries.rb:83:6:83:6 | a [element 1] : | -| summaries.rb:79:15:79:29 | call to source : | summaries.rb:83:6:83:6 | a [element 1] : | -| summaries.rb:79:15:79:29 | call to source : | summaries.rb:85:6:85:6 | a [element 1] : | -| summaries.rb:79:15:79:29 | call to source : | summaries.rb:85:6:85:6 | a [element 1] : | -| summaries.rb:79:15:79:29 | call to source : | summaries.rb:87:5:87:5 | a [element 1] : | -| summaries.rb:79:15:79:29 | call to source : | summaries.rb:87:5:87:5 | a [element 1] : | -| summaries.rb:79:15:79:29 | call to source : | summaries.rb:91:5:91:5 | a [element 1] : | -| summaries.rb:79:15:79:29 | call to source : | summaries.rb:91:5:91:5 | a [element 1] : | -| summaries.rb:79:32:79:46 | call to source : | summaries.rb:86:6:86:6 | a [element 2] : | -| summaries.rb:79:32:79:46 | call to source : | summaries.rb:86:6:86:6 | a [element 2] : | -| summaries.rb:79:32:79:46 | call to source : | summaries.rb:95:1:95:1 | a [element 2] : | -| summaries.rb:79:32:79:46 | call to source : | summaries.rb:95:1:95:1 | a [element 2] : | +| summaries.rb:79:1:79:1 | a [element 1] : | summaries.rb:82:6:82:6 | a [element 1] : | +| summaries.rb:79:1:79:1 | a [element 1] : | summaries.rb:82:6:82:6 | a [element 1] : | +| summaries.rb:79:1:79:1 | a [element 1] : | summaries.rb:83:6:83:6 | a [element 1] : | +| summaries.rb:79:1:79:1 | a [element 1] : | summaries.rb:83:6:83:6 | a [element 1] : | +| summaries.rb:79:1:79:1 | a [element 1] : | summaries.rb:85:6:85:6 | a [element 1] : | +| summaries.rb:79:1:79:1 | a [element 1] : | summaries.rb:85:6:85:6 | a [element 1] : | +| summaries.rb:79:1:79:1 | a [element 1] : | summaries.rb:87:5:87:5 | a [element 1] : | +| summaries.rb:79:1:79:1 | a [element 1] : | summaries.rb:87:5:87:5 | a [element 1] : | +| summaries.rb:79:1:79:1 | a [element 1] : | summaries.rb:91:5:91:5 | a [element 1] : | +| summaries.rb:79:1:79:1 | a [element 1] : | summaries.rb:91:5:91:5 | a [element 1] : | +| summaries.rb:79:1:79:1 | a [element 2] : | summaries.rb:86:6:86:6 | a [element 2] : | +| summaries.rb:79:1:79:1 | a [element 2] : | summaries.rb:86:6:86:6 | a [element 2] : | +| summaries.rb:79:1:79:1 | a [element 2] : | summaries.rb:95:1:95:1 | a [element 2] : | +| summaries.rb:79:1:79:1 | a [element 2] : | summaries.rb:95:1:95:1 | a [element 2] : | +| summaries.rb:79:15:79:29 | call to source : | summaries.rb:79:1:79:1 | a [element 1] : | +| summaries.rb:79:15:79:29 | call to source : | summaries.rb:79:1:79:1 | a [element 1] : | +| summaries.rb:79:32:79:46 | call to source : | summaries.rb:79:1:79:1 | a [element 2] : | +| summaries.rb:79:32:79:46 | call to source : | summaries.rb:79:1:79:1 | a [element 2] : | | summaries.rb:81:1:81:1 | [post] a [element] : | summaries.rb:82:6:82:6 | a [element] : | | summaries.rb:81:1:81:1 | [post] a [element] : | summaries.rb:82:6:82:6 | a [element] : | | summaries.rb:81:1:81:1 | [post] a [element] : | summaries.rb:84:6:84:6 | a [element] : | @@ -131,18 +145,22 @@ edges | summaries.rb:86:6:86:6 | a [element 2] : | summaries.rb:86:6:86:9 | ...[...] | | summaries.rb:86:6:86:6 | a [element] : | summaries.rb:86:6:86:9 | ...[...] | | summaries.rb:86:6:86:6 | a [element] : | summaries.rb:86:6:86:9 | ...[...] | +| summaries.rb:87:1:87:1 | b [element 1] : | summaries.rb:89:6:89:6 | b [element 1] : | +| summaries.rb:87:1:87:1 | b [element 1] : | summaries.rb:89:6:89:6 | b [element 1] : | +| summaries.rb:87:1:87:1 | b [element] : | summaries.rb:88:6:88:6 | b [element] : | +| summaries.rb:87:1:87:1 | b [element] : | summaries.rb:88:6:88:6 | b [element] : | +| summaries.rb:87:1:87:1 | b [element] : | summaries.rb:89:6:89:6 | b [element] : | +| summaries.rb:87:1:87:1 | b [element] : | summaries.rb:89:6:89:6 | b [element] : | +| summaries.rb:87:1:87:1 | b [element] : | summaries.rb:90:6:90:6 | b [element] : | +| summaries.rb:87:1:87:1 | b [element] : | summaries.rb:90:6:90:6 | b [element] : | | summaries.rb:87:5:87:5 | a [element 1] : | summaries.rb:87:5:87:22 | call to withElementOne [element 1] : | | summaries.rb:87:5:87:5 | a [element 1] : | summaries.rb:87:5:87:22 | call to withElementOne [element 1] : | | summaries.rb:87:5:87:5 | a [element] : | summaries.rb:87:5:87:22 | call to withElementOne [element] : | | summaries.rb:87:5:87:5 | a [element] : | summaries.rb:87:5:87:22 | call to withElementOne [element] : | -| summaries.rb:87:5:87:22 | call to withElementOne [element 1] : | summaries.rb:89:6:89:6 | b [element 1] : | -| summaries.rb:87:5:87:22 | call to withElementOne [element 1] : | summaries.rb:89:6:89:6 | b [element 1] : | -| summaries.rb:87:5:87:22 | call to withElementOne [element] : | summaries.rb:88:6:88:6 | b [element] : | -| summaries.rb:87:5:87:22 | call to withElementOne [element] : | summaries.rb:88:6:88:6 | b [element] : | -| summaries.rb:87:5:87:22 | call to withElementOne [element] : | summaries.rb:89:6:89:6 | b [element] : | -| summaries.rb:87:5:87:22 | call to withElementOne [element] : | summaries.rb:89:6:89:6 | b [element] : | -| summaries.rb:87:5:87:22 | call to withElementOne [element] : | summaries.rb:90:6:90:6 | b [element] : | -| summaries.rb:87:5:87:22 | call to withElementOne [element] : | summaries.rb:90:6:90:6 | b [element] : | +| summaries.rb:87:5:87:22 | call to withElementOne [element 1] : | summaries.rb:87:1:87:1 | b [element 1] : | +| summaries.rb:87:5:87:22 | call to withElementOne [element 1] : | summaries.rb:87:1:87:1 | b [element 1] : | +| summaries.rb:87:5:87:22 | call to withElementOne [element] : | summaries.rb:87:1:87:1 | b [element] : | +| summaries.rb:87:5:87:22 | call to withElementOne [element] : | summaries.rb:87:1:87:1 | b [element] : | | summaries.rb:88:6:88:6 | b [element] : | summaries.rb:88:6:88:9 | ...[...] | | summaries.rb:88:6:88:6 | b [element] : | summaries.rb:88:6:88:9 | ...[...] | | summaries.rb:89:6:89:6 | b [element 1] : | summaries.rb:89:6:89:9 | ...[...] | @@ -151,10 +169,12 @@ edges | summaries.rb:89:6:89:6 | b [element] : | summaries.rb:89:6:89:9 | ...[...] | | summaries.rb:90:6:90:6 | b [element] : | summaries.rb:90:6:90:9 | ...[...] | | summaries.rb:90:6:90:6 | b [element] : | summaries.rb:90:6:90:9 | ...[...] | +| summaries.rb:91:1:91:1 | c [element 1] : | summaries.rb:93:6:93:6 | c [element 1] : | +| summaries.rb:91:1:91:1 | c [element 1] : | summaries.rb:93:6:93:6 | c [element 1] : | | summaries.rb:91:5:91:5 | a [element 1] : | summaries.rb:91:5:91:29 | call to withExactlyElementOne [element 1] : | | summaries.rb:91:5:91:5 | a [element 1] : | summaries.rb:91:5:91:29 | call to withExactlyElementOne [element 1] : | -| summaries.rb:91:5:91:29 | call to withExactlyElementOne [element 1] : | summaries.rb:93:6:93:6 | c [element 1] : | -| summaries.rb:91:5:91:29 | call to withExactlyElementOne [element 1] : | summaries.rb:93:6:93:6 | c [element 1] : | +| summaries.rb:91:5:91:29 | call to withExactlyElementOne [element 1] : | summaries.rb:91:1:91:1 | c [element 1] : | +| summaries.rb:91:5:91:29 | call to withExactlyElementOne [element 1] : | summaries.rb:91:1:91:1 | c [element 1] : | | summaries.rb:93:6:93:6 | c [element 1] : | summaries.rb:93:6:93:9 | ...[...] | | summaries.rb:93:6:93:6 | c [element 1] : | summaries.rb:93:6:93:9 | ...[...] | | summaries.rb:95:1:95:1 | [post] a [element 2] : | summaries.rb:98:6:98:6 | a [element 2] : | @@ -219,12 +239,16 @@ edges | summaries.rb:128:1:128:1 | [post] x : | summaries.rb:129:6:129:6 | x | | summaries.rb:128:14:128:20 | tainted : | summaries.rb:128:1:128:1 | [post] x : | nodes +| summaries.rb:1:1:1:7 | tainted : | semmle.label | tainted : | +| summaries.rb:1:1:1:7 | tainted : | semmle.label | tainted : | | summaries.rb:1:11:1:36 | call to identity : | semmle.label | call to identity : | | summaries.rb:1:11:1:36 | call to identity : | semmle.label | call to identity : | | summaries.rb:1:20:1:36 | call to source : | semmle.label | call to source : | | summaries.rb:1:20:1:36 | call to source : | semmle.label | call to source : | | summaries.rb:2:6:2:12 | tainted | semmle.label | tainted | | summaries.rb:2:6:2:12 | tainted | semmle.label | tainted | +| summaries.rb:4:1:4:8 | tainted2 : | semmle.label | tainted2 : | +| summaries.rb:4:1:4:8 | tainted2 : | semmle.label | tainted2 : | | summaries.rb:4:12:7:3 | call to apply_block : | semmle.label | call to apply_block : | | summaries.rb:4:12:7:3 | call to apply_block : | semmle.label | call to apply_block : | | summaries.rb:4:24:4:30 | tainted : | semmle.label | tainted : | @@ -239,15 +263,19 @@ nodes | summaries.rb:11:17:11:17 | x : | semmle.label | x : | | summaries.rb:12:8:12:8 | x | semmle.label | x | | summaries.rb:12:8:12:8 | x | semmle.label | x | +| summaries.rb:16:1:16:8 | tainted3 : | semmle.label | tainted3 : | +| summaries.rb:16:1:16:8 | tainted3 : | semmle.label | tainted3 : | | summaries.rb:16:12:16:43 | call to apply_lambda : | semmle.label | call to apply_lambda : | | summaries.rb:16:12:16:43 | call to apply_lambda : | semmle.label | call to apply_lambda : | | summaries.rb:16:36:16:42 | tainted : | semmle.label | tainted : | | summaries.rb:16:36:16:42 | tainted : | semmle.label | tainted : | | summaries.rb:18:6:18:13 | tainted3 | semmle.label | tainted3 | | summaries.rb:18:6:18:13 | tainted3 | semmle.label | tainted3 | +| summaries.rb:20:1:20:8 | tainted4 : | semmle.label | tainted4 : | | summaries.rb:20:12:20:32 | call to firstArg : | semmle.label | call to firstArg : | | summaries.rb:20:25:20:31 | tainted : | semmle.label | tainted : | | summaries.rb:21:6:21:13 | tainted4 | semmle.label | tainted4 | +| summaries.rb:26:1:26:8 | tainted5 : | semmle.label | tainted5 : | | summaries.rb:26:12:26:38 | call to secondArg : | semmle.label | call to secondArg : | | summaries.rb:26:31:26:37 | tainted : | semmle.label | tainted : | | summaries.rb:27:6:27:13 | tainted5 | semmle.label | tainted5 | @@ -263,6 +291,7 @@ nodes | summaries.rb:36:21:36:27 | tainted | semmle.label | tainted | | summaries.rb:37:36:37:42 | tainted | semmle.label | tainted | | summaries.rb:37:36:37:42 | tainted | semmle.label | tainted | +| summaries.rb:40:3:40:3 | t : | semmle.label | t : | | summaries.rb:40:7:40:17 | call to source : | semmle.label | call to source : | | summaries.rb:41:8:41:25 | call to matchedByName | semmle.label | call to matchedByName | | summaries.rb:41:24:41:24 | t : | semmle.label | t : | @@ -274,6 +303,7 @@ nodes | summaries.rb:48:24:48:41 | call to source : | semmle.label | call to source : | | summaries.rb:51:6:51:31 | call to namedArg | semmle.label | call to namedArg | | summaries.rb:51:24:51:30 | tainted : | semmle.label | tainted : | +| summaries.rb:53:1:53:4 | args [element :foo] : | semmle.label | args [element :foo] : | | summaries.rb:53:15:53:31 | call to source : | semmle.label | call to source : | | summaries.rb:54:6:54:25 | call to namedArg | semmle.label | call to namedArg | | summaries.rb:54:19:54:24 | ** ... [element :foo] : | semmle.label | ** ... [element :foo] : | @@ -293,6 +323,10 @@ nodes | summaries.rb:73:24:73:53 | call to source : | semmle.label | call to source : | | summaries.rb:76:8:76:57 | call to preserveTaint | semmle.label | call to preserveTaint | | summaries.rb:76:26:76:56 | call to source : | semmle.label | call to source : | +| summaries.rb:79:1:79:1 | a [element 1] : | semmle.label | a [element 1] : | +| summaries.rb:79:1:79:1 | a [element 1] : | semmle.label | a [element 1] : | +| summaries.rb:79:1:79:1 | a [element 2] : | semmle.label | a [element 2] : | +| summaries.rb:79:1:79:1 | a [element 2] : | semmle.label | a [element 2] : | | summaries.rb:79:15:79:29 | call to source : | semmle.label | call to source : | | summaries.rb:79:15:79:29 | call to source : | semmle.label | call to source : | | summaries.rb:79:32:79:46 | call to source : | semmle.label | call to source : | @@ -327,6 +361,10 @@ nodes | summaries.rb:86:6:86:6 | a [element] : | semmle.label | a [element] : | | summaries.rb:86:6:86:9 | ...[...] | semmle.label | ...[...] | | summaries.rb:86:6:86:9 | ...[...] | semmle.label | ...[...] | +| summaries.rb:87:1:87:1 | b [element 1] : | semmle.label | b [element 1] : | +| summaries.rb:87:1:87:1 | b [element 1] : | semmle.label | b [element 1] : | +| summaries.rb:87:1:87:1 | b [element] : | semmle.label | b [element] : | +| summaries.rb:87:1:87:1 | b [element] : | semmle.label | b [element] : | | summaries.rb:87:5:87:5 | a [element 1] : | semmle.label | a [element 1] : | | summaries.rb:87:5:87:5 | a [element 1] : | semmle.label | a [element 1] : | | summaries.rb:87:5:87:5 | a [element] : | semmle.label | a [element] : | @@ -349,6 +387,8 @@ nodes | summaries.rb:90:6:90:6 | b [element] : | semmle.label | b [element] : | | summaries.rb:90:6:90:9 | ...[...] | semmle.label | ...[...] | | summaries.rb:90:6:90:9 | ...[...] | semmle.label | ...[...] | +| summaries.rb:91:1:91:1 | c [element 1] : | semmle.label | c [element 1] : | +| summaries.rb:91:1:91:1 | c [element 1] : | semmle.label | c [element 1] : | | summaries.rb:91:5:91:5 | a [element 1] : | semmle.label | a [element 1] : | | summaries.rb:91:5:91:5 | a [element 1] : | semmle.label | a [element 1] : | | summaries.rb:91:5:91:29 | call to withExactlyElementOne [element 1] : | semmle.label | call to withExactlyElementOne [element 1] : | diff --git a/ruby/ql/test/library-tests/dataflow/type-tracker/TypeTracker.expected b/ruby/ql/test/library-tests/dataflow/type-tracker/TypeTracker.expected index 0c35a350c41..bc7b35eb941 100644 --- a/ruby/ql/test/library-tests/dataflow/type-tracker/TypeTracker.expected +++ b/ruby/ql/test/library-tests/dataflow/type-tracker/TypeTracker.expected @@ -446,7 +446,7 @@ trackEnd | type_tracker.rb:13:11:13:23 | call to new | type_tracker.rb:7:5:9:7 | self (field) | | type_tracker.rb:13:11:13:23 | call to new | type_tracker.rb:7:5:9:7 | self in field | | type_tracker.rb:13:11:13:23 | call to new | type_tracker.rb:8:9:8:14 | self | -| type_tracker.rb:13:11:13:23 | call to new | type_tracker.rb:13:5:13:23 | ... = ... | +| type_tracker.rb:13:11:13:23 | call to new | type_tracker.rb:13:5:13:7 | var | | type_tracker.rb:13:11:13:23 | call to new | type_tracker.rb:13:5:13:23 | ... = ... | | type_tracker.rb:13:11:13:23 | call to new | type_tracker.rb:13:11:13:23 | call to new | | type_tracker.rb:13:11:13:23 | call to new | type_tracker.rb:14:5:14:7 | var | @@ -467,7 +467,7 @@ trackEnd | type_tracker.rb:14:17:14:23 | "hello" | type_tracker.rb:14:5:14:23 | ... | | type_tracker.rb:14:17:14:23 | "hello" | type_tracker.rb:14:17:14:23 | "hello" | | type_tracker.rb:14:17:14:23 | "hello" | type_tracker.rb:14:17:14:23 | ... = ... | -| type_tracker.rb:14:17:14:23 | "hello" | type_tracker.rb:14:17:14:23 | ... = ... | +| type_tracker.rb:14:17:14:23 | "hello" | type_tracker.rb:14:17:14:23 | __synth__0 | | type_tracker.rb:14:17:14:23 | "hello" | type_tracker.rb:15:10:15:18 | call to field | | type_tracker.rb:14:17:14:23 | __synth__0 | type_tracker.rb:14:17:14:23 | __synth__0 | | type_tracker.rb:15:5:15:18 | call to puts | type_tracker.rb:12:1:16:3 | return return in m | @@ -606,8 +606,8 @@ trackEnd | type_tracker.rb:34:18:34:20 | obj | type_tracker.rb:39:5:39:18 | ... | | type_tracker.rb:34:18:34:20 | obj | type_tracker.rb:39:16:39:18 | ... = ... | | type_tracker.rb:34:18:34:20 | obj | type_tracker.rb:39:16:39:18 | ... = ... | -| type_tracker.rb:34:18:34:20 | obj | type_tracker.rb:39:16:39:18 | ... = ... | -| type_tracker.rb:34:18:34:20 | obj | type_tracker.rb:39:16:39:18 | ... = ... | +| type_tracker.rb:34:18:34:20 | obj | type_tracker.rb:39:16:39:18 | __synth__0 | +| type_tracker.rb:34:18:34:20 | obj | type_tracker.rb:39:16:39:18 | __synth__0 | | type_tracker.rb:34:18:34:20 | obj | type_tracker.rb:39:16:39:18 | obj | | type_tracker.rb:34:18:34:20 | obj | type_tracker.rb:39:16:39:18 | obj | | type_tracker.rb:34:18:34:20 | obj | type_tracker.rb:40:5:40:12 | ...[...] | @@ -618,8 +618,8 @@ trackEnd | type_tracker.rb:34:18:34:20 | obj | type_tracker.rb:43:5:43:19 | ... | | type_tracker.rb:34:18:34:20 | obj | type_tracker.rb:43:17:43:19 | ... = ... | | type_tracker.rb:34:18:34:20 | obj | type_tracker.rb:43:17:43:19 | ... = ... | -| type_tracker.rb:34:18:34:20 | obj | type_tracker.rb:43:17:43:19 | ... = ... | -| type_tracker.rb:34:18:34:20 | obj | type_tracker.rb:43:17:43:19 | ... = ... | +| type_tracker.rb:34:18:34:20 | obj | type_tracker.rb:43:17:43:19 | __synth__0 | +| type_tracker.rb:34:18:34:20 | obj | type_tracker.rb:43:17:43:19 | __synth__0 | | type_tracker.rb:34:18:34:20 | obj | type_tracker.rb:43:17:43:19 | obj | | type_tracker.rb:34:18:34:20 | obj | type_tracker.rb:43:17:43:19 | obj | | type_tracker.rb:34:18:34:20 | obj | type_tracker.rb:44:5:44:13 | ...[...] | @@ -630,8 +630,8 @@ trackEnd | type_tracker.rb:34:18:34:20 | obj | type_tracker.rb:47:5:47:19 | ... | | type_tracker.rb:34:18:34:20 | obj | type_tracker.rb:47:17:47:19 | ... = ... | | type_tracker.rb:34:18:34:20 | obj | type_tracker.rb:47:17:47:19 | ... = ... | -| type_tracker.rb:34:18:34:20 | obj | type_tracker.rb:47:17:47:19 | ... = ... | -| type_tracker.rb:34:18:34:20 | obj | type_tracker.rb:47:17:47:19 | ... = ... | +| type_tracker.rb:34:18:34:20 | obj | type_tracker.rb:47:17:47:19 | __synth__0 | +| type_tracker.rb:34:18:34:20 | obj | type_tracker.rb:47:17:47:19 | __synth__0 | | type_tracker.rb:34:18:34:20 | obj | type_tracker.rb:47:17:47:19 | obj | | type_tracker.rb:34:18:34:20 | obj | type_tracker.rb:47:17:47:19 | obj | | type_tracker.rb:34:18:34:20 | obj | type_tracker.rb:51:5:51:13 | __synth__0 | @@ -640,8 +640,8 @@ trackEnd | type_tracker.rb:34:18:34:20 | obj | type_tracker.rb:51:5:51:19 | ... | | type_tracker.rb:34:18:34:20 | obj | type_tracker.rb:51:17:51:19 | ... = ... | | type_tracker.rb:34:18:34:20 | obj | type_tracker.rb:51:17:51:19 | ... = ... | -| type_tracker.rb:34:18:34:20 | obj | type_tracker.rb:51:17:51:19 | ... = ... | -| type_tracker.rb:34:18:34:20 | obj | type_tracker.rb:51:17:51:19 | ... = ... | +| type_tracker.rb:34:18:34:20 | obj | type_tracker.rb:51:17:51:19 | __synth__0 | +| type_tracker.rb:34:18:34:20 | obj | type_tracker.rb:51:17:51:19 | __synth__0 | | type_tracker.rb:34:18:34:20 | obj | type_tracker.rb:51:17:51:19 | obj | | type_tracker.rb:34:18:34:20 | obj | type_tracker.rb:51:17:51:19 | obj | | type_tracker.rb:34:18:34:20 | obj | type_tracker.rb:52:5:52:13 | ...[...] | @@ -664,7 +664,7 @@ trackEnd | type_tracker.rb:34:26:34:26 | z | type_tracker.rb:52:12:52:12 | z | | type_tracker.rb:35:5:35:7 | tmp | type_tracker.rb:35:5:35:7 | tmp | | type_tracker.rb:35:11:35:15 | Array | type_tracker.rb:35:11:35:15 | Array | -| type_tracker.rb:35:11:35:15 | call to [] | type_tracker.rb:35:5:35:15 | ... = ... | +| type_tracker.rb:35:11:35:15 | call to [] | type_tracker.rb:35:5:35:7 | tmp | | type_tracker.rb:35:11:35:15 | call to [] | type_tracker.rb:35:5:35:15 | ... = ... | | type_tracker.rb:35:11:35:15 | call to [] | type_tracker.rb:35:11:35:15 | call to [] | | type_tracker.rb:35:11:35:15 | call to [] | type_tracker.rb:36:5:36:7 | tmp | @@ -672,7 +672,7 @@ trackEnd | type_tracker.rb:36:9:36:9 | 0 | type_tracker.rb:36:9:36:9 | 0 | | type_tracker.rb:38:5:38:9 | array | type_tracker.rb:38:5:38:9 | array | | type_tracker.rb:38:13:38:25 | Array | type_tracker.rb:38:13:38:25 | Array | -| type_tracker.rb:38:13:38:25 | call to [] | type_tracker.rb:38:5:38:25 | ... = ... | +| type_tracker.rb:38:13:38:25 | call to [] | type_tracker.rb:38:5:38:9 | array | | type_tracker.rb:38:13:38:25 | call to [] | type_tracker.rb:38:5:38:25 | ... = ... | | type_tracker.rb:38:13:38:25 | call to [] | type_tracker.rb:38:13:38:25 | call to [] | | type_tracker.rb:38:13:38:25 | call to [] | type_tracker.rb:39:5:39:9 | array | @@ -692,7 +692,7 @@ trackEnd | type_tracker.rb:40:11:40:11 | 0 | type_tracker.rb:40:11:40:11 | 0 | | type_tracker.rb:42:5:42:10 | array2 | type_tracker.rb:42:5:42:10 | array2 | | type_tracker.rb:42:14:42:26 | Array | type_tracker.rb:42:14:42:26 | Array | -| type_tracker.rb:42:14:42:26 | call to [] | type_tracker.rb:42:5:42:26 | ... = ... | +| type_tracker.rb:42:14:42:26 | call to [] | type_tracker.rb:42:5:42:10 | array2 | | type_tracker.rb:42:14:42:26 | call to [] | type_tracker.rb:42:5:42:26 | ... = ... | | type_tracker.rb:42:14:42:26 | call to [] | type_tracker.rb:42:14:42:26 | call to [] | | type_tracker.rb:42:14:42:26 | call to [] | type_tracker.rb:43:5:43:10 | array2 | @@ -717,7 +717,7 @@ trackEnd | type_tracker.rb:44:5:44:13 | ...[...] | type_tracker.rb:44:5:44:13 | ...[...] | | type_tracker.rb:46:5:46:10 | array3 | type_tracker.rb:46:5:46:10 | array3 | | type_tracker.rb:46:14:46:26 | Array | type_tracker.rb:46:14:46:26 | Array | -| type_tracker.rb:46:14:46:26 | call to [] | type_tracker.rb:46:5:46:26 | ... = ... | +| type_tracker.rb:46:14:46:26 | call to [] | type_tracker.rb:46:5:46:10 | array3 | | type_tracker.rb:46:14:46:26 | call to [] | type_tracker.rb:46:5:46:26 | ... = ... | | type_tracker.rb:46:14:46:26 | call to [] | type_tracker.rb:46:14:46:26 | call to [] | | type_tracker.rb:46:14:46:26 | call to [] | type_tracker.rb:47:5:47:10 | array3 | @@ -738,7 +738,7 @@ trackEnd | type_tracker.rb:48:12:48:12 | 1 | type_tracker.rb:48:12:48:12 | 1 | | type_tracker.rb:50:5:50:10 | array4 | type_tracker.rb:50:5:50:10 | array4 | | type_tracker.rb:50:14:50:26 | Array | type_tracker.rb:50:14:50:26 | Array | -| type_tracker.rb:50:14:50:26 | call to [] | type_tracker.rb:50:5:50:26 | ... = ... | +| type_tracker.rb:50:14:50:26 | call to [] | type_tracker.rb:50:5:50:10 | array4 | | type_tracker.rb:50:14:50:26 | call to [] | type_tracker.rb:50:5:50:26 | ... = ... | | type_tracker.rb:50:14:50:26 | call to [] | type_tracker.rb:50:14:50:26 | call to [] | | type_tracker.rb:50:14:50:26 | call to [] | type_tracker.rb:51:5:51:10 | array4 | diff --git a/ruby/ql/test/library-tests/frameworks/active_record/ActiveRecord.expected b/ruby/ql/test/library-tests/frameworks/active_record/ActiveRecord.expected index 918bd5c19ea..0374a54c0c1 100644 --- a/ruby/ql/test/library-tests/frameworks/active_record/ActiveRecord.expected +++ b/ruby/ql/test/library-tests/frameworks/active_record/ActiveRecord.expected @@ -20,10 +20,10 @@ activeRecordInstances | ActiveRecord.rb:76:5:76:66 | call to create | | ActiveRecord.rb:80:5:80:68 | call to create | | ActiveRecord.rb:84:5:84:16 | call to create | -| associations.rb:19:1:19:20 | ... = ... | +| associations.rb:19:1:19:7 | author1 | | associations.rb:19:1:19:20 | ... = ... | | associations.rb:19:11:19:20 | call to new | -| associations.rb:21:1:21:28 | ... = ... | +| associations.rb:21:1:21:5 | post1 | | associations.rb:21:1:21:28 | ... = ... | | associations.rb:21:9:21:15 | author1 | | associations.rb:21:9:21:21 | call to posts | @@ -32,11 +32,11 @@ activeRecordInstances | associations.rb:23:12:23:16 | post1 | | associations.rb:23:12:23:25 | call to comments | | associations.rb:23:12:23:32 | call to create | -| associations.rb:25:1:25:22 | ... = ... | +| associations.rb:25:1:25:7 | author2 | | associations.rb:25:1:25:22 | ... = ... | | associations.rb:25:11:25:15 | post1 | | associations.rb:25:11:25:22 | call to author | -| associations.rb:27:1:27:28 | ... = ... | +| associations.rb:27:1:27:5 | post2 | | associations.rb:27:1:27:28 | ... = ... | | associations.rb:27:9:27:15 | author2 | | associations.rb:27:9:27:21 | call to posts | @@ -50,7 +50,7 @@ activeRecordInstances | associations.rb:31:1:31:12 | call to author= | | associations.rb:31:1:31:22 | ... | | associations.rb:31:16:31:22 | ... = ... | -| associations.rb:31:16:31:22 | ... = ... | +| associations.rb:31:16:31:22 | __synth__0 | | associations.rb:31:16:31:22 | author2 | | associations.rb:35:1:35:5 | post2 | | associations.rb:35:1:35:14 | call to comments | diff --git a/ruby/ql/test/library-tests/frameworks/active_resource/ActiveResource.expected b/ruby/ql/test/library-tests/frameworks/active_resource/ActiveResource.expected index 3cb31c4c12c..a55946c1852 100644 --- a/ruby/ql/test/library-tests/frameworks/active_resource/ActiveResource.expected +++ b/ruby/ql/test/library-tests/frameworks/active_resource/ActiveResource.expected @@ -11,11 +11,11 @@ modelClassMethodCalls | active_resource.rb:24:10:24:26 | call to find | | active_resource.rb:30:3:30:11 | call to site= | modelInstances -| active_resource.rb:5:1:5:33 | ... = ... | +| active_resource.rb:5:1:5:5 | alice | | active_resource.rb:5:1:5:33 | ... = ... | | active_resource.rb:5:9:5:33 | call to new | | active_resource.rb:6:1:6:5 | alice | -| active_resource.rb:8:1:8:22 | ... = ... | +| active_resource.rb:8:1:8:5 | alice | | active_resource.rb:8:1:8:22 | ... = ... | | active_resource.rb:8:9:8:22 | call to find | | active_resource.rb:9:1:9:5 | alice | @@ -25,10 +25,10 @@ modelInstances | active_resource.rb:17:1:17:5 | alice | | active_resource.rb:18:1:18:22 | call to get | | active_resource.rb:19:1:19:5 | alice | -| active_resource.rb:24:1:24:26 | ... = ... | +| active_resource.rb:24:1:24:6 | people | | active_resource.rb:24:1:24:26 | ... = ... | | active_resource.rb:24:10:24:26 | call to find | -| active_resource.rb:26:1:26:20 | ... = ... | +| active_resource.rb:26:1:26:5 | alice | | active_resource.rb:26:1:26:20 | ... = ... | | active_resource.rb:26:9:26:14 | people | | active_resource.rb:26:9:26:20 | call to first | @@ -46,7 +46,7 @@ modelInstanceMethodCalls collections | active_resource.rb:23:1:23:19 | ... = ... | | active_resource.rb:23:10:23:19 | call to all | -| active_resource.rb:24:1:24:26 | ... = ... | +| active_resource.rb:24:1:24:6 | people | | active_resource.rb:24:1:24:26 | ... = ... | | active_resource.rb:24:10:24:26 | call to find | | active_resource.rb:26:9:26:14 | people | diff --git a/ruby/ql/test/library-tests/frameworks/active_storage/ActiveStorage.expected b/ruby/ql/test/library-tests/frameworks/active_storage/ActiveStorage.expected index 8c788bda20d..cd2c9c57cc7 100644 --- a/ruby/ql/test/library-tests/frameworks/active_storage/ActiveStorage.expected +++ b/ruby/ql/test/library-tests/frameworks/active_storage/ActiveStorage.expected @@ -1,12 +1,12 @@ attachmentInstances -| active_storage.rb:11:1:11:25 | ... = ... | +| active_storage.rb:11:1:11:11 | user_avatar | | active_storage.rb:11:1:11:25 | ... = ... | | active_storage.rb:11:15:11:25 | call to avatar | | active_storage.rb:13:1:13:11 | user_avatar | | active_storage.rb:14:1:14:11 | user_avatar | | active_storage.rb:15:1:15:11 | user_avatar | | active_storage.rb:17:1:17:11 | call to avatar | -| active_storage.rb:19:1:19:42 | ... = ... | +| active_storage.rb:19:1:19:10 | attachment | | active_storage.rb:19:1:19:42 | ... = ... | | active_storage.rb:19:14:19:42 | call to new | | active_storage.rb:23:11:23:20 | attachment | 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 b84d576ad19..e10e038a7cc 100644 --- a/ruby/ql/test/library-tests/frameworks/active_support/ActiveSupportDataFlow.expected +++ b/ruby/ql/test/library-tests/frameworks/active_support/ActiveSupportDataFlow.expected @@ -1,122 +1,178 @@ 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:10:5:10:5 | x : | active_support.rb:11:10:11:10 | x : | +| active_support.rb:10:9:10:18 | call to source : | active_support.rb:10:5:10:5 | x : | | active_support.rb:11:10:11:10 | x : | active_support.rb:11:10:11:19 | call to at | -| active_support.rb:15:9:15:18 | call to source : | active_support.rb:16:10:16:10 | x : | +| active_support.rb:15:5:15:5 | x : | active_support.rb:16:10:16:10 | x : | +| active_support.rb:15:9:15:18 | call to source : | active_support.rb:15:5:15:5 | x : | | active_support.rb:16:10:16:10 | x : | active_support.rb:16:10:16:19 | call to camelize | -| active_support.rb:20:9:20:18 | call to source : | active_support.rb:21:10:21:10 | x : | +| active_support.rb:20:5:20:5 | x : | active_support.rb:21:10:21:10 | x : | +| active_support.rb:20:9:20:18 | call to source : | active_support.rb:20:5:20:5 | x : | | active_support.rb:21:10:21:10 | x : | active_support.rb:21:10:21:20 | call to camelcase | -| active_support.rb:25:9:25:18 | call to source : | active_support.rb:26:10:26:10 | x : | +| active_support.rb:25:5:25:5 | x : | active_support.rb:26:10:26:10 | x : | +| active_support.rb:25:9:25:18 | call to source : | active_support.rb:25:5:25:5 | x : | | active_support.rb:26:10:26:10 | x : | active_support.rb:26:10:26:19 | call to classify | -| active_support.rb:30:9:30:18 | call to source : | active_support.rb:31:10:31:10 | x : | +| active_support.rb:30:5:30:5 | x : | active_support.rb:31:10:31:10 | x : | +| active_support.rb:30:9:30:18 | call to source : | active_support.rb:30:5:30:5 | x : | | active_support.rb:31:10:31:10 | x : | active_support.rb:31:10:31:20 | call to dasherize | -| active_support.rb:35:9:35:18 | call to source : | active_support.rb:36:10:36:10 | x : | +| active_support.rb:35:5:35:5 | x : | active_support.rb:36:10:36:10 | x : | +| active_support.rb:35:9:35:18 | call to source : | active_support.rb:35:5:35:5 | x : | | active_support.rb:36:10:36:10 | x : | active_support.rb:36:10:36:24 | call to deconstantize | -| active_support.rb:40:9:40:18 | call to source : | active_support.rb:41:10:41:10 | x : | +| active_support.rb:40:5:40:5 | x : | active_support.rb:41:10:41:10 | x : | +| active_support.rb:40:9:40:18 | call to source : | active_support.rb:40:5:40:5 | x : | | active_support.rb:41:10:41:10 | x : | active_support.rb:41:10:41:21 | call to demodulize | -| active_support.rb:45:9:45:18 | call to source : | active_support.rb:46:10:46:10 | x : | +| active_support.rb:45:5:45:5 | x : | active_support.rb:46:10:46:10 | x : | +| active_support.rb:45:9:45:18 | call to source : | active_support.rb:45:5:45:5 | x : | | active_support.rb:46:10:46:10 | x : | active_support.rb:46:10:46:19 | call to first | -| active_support.rb:50:9:50:18 | call to source : | active_support.rb:51:10:51:10 | x : | +| active_support.rb:50:5:50:5 | x : | active_support.rb:51:10:51:10 | x : | +| active_support.rb:50:9:50:18 | call to source : | active_support.rb:50:5:50:5 | x : | | active_support.rb:51:10:51:10 | x : | active_support.rb:51:10:51:22 | call to foreign_key | -| active_support.rb:55:9:55:18 | call to source : | active_support.rb:56:10:56:10 | x : | +| active_support.rb:55:5:55:5 | x : | active_support.rb:56:10:56:10 | x : | +| active_support.rb:55:9:55:18 | call to source : | active_support.rb:55:5:55:5 | x : | | active_support.rb:56:10:56:10 | x : | active_support.rb:56:10:56:18 | call to from | -| active_support.rb:60:9:60:18 | call to source : | active_support.rb:61:10:61:10 | x : | +| active_support.rb:60:5:60:5 | x : | active_support.rb:61:10:61:10 | x : | +| active_support.rb:60:9:60:18 | call to source : | active_support.rb:60:5:60:5 | x : | | active_support.rb:61:10:61:10 | x : | active_support.rb:61:10:61:20 | call to html_safe | -| active_support.rb:65:9:65:18 | call to source : | active_support.rb:66:10:66:10 | x : | +| active_support.rb:65:5:65:5 | x : | active_support.rb:66:10:66:10 | x : | +| active_support.rb:65:9:65:18 | call to source : | active_support.rb:65:5:65:5 | x : | | active_support.rb:66:10:66:10 | x : | active_support.rb:66:10:66:19 | call to humanize | -| active_support.rb:70:9:70:18 | call to source : | active_support.rb:71:10:71:10 | x : | +| active_support.rb:70:5:70:5 | x : | active_support.rb:71:10:71:10 | x : | +| active_support.rb:70:9:70:18 | call to source : | active_support.rb:70:5:70:5 | x : | | active_support.rb:71:10:71:10 | x : | active_support.rb:71:10:71:20 | call to indent | -| active_support.rb:75:9:75:18 | call to source : | active_support.rb:76:10:76:10 | x : | +| active_support.rb:75:5:75:5 | x : | active_support.rb:76:10:76:10 | x : | +| active_support.rb:75:9:75:18 | call to source : | active_support.rb:75:5:75:5 | x : | | active_support.rb:76:10:76:10 | x : | active_support.rb:76:10:76:21 | call to indent! | -| active_support.rb:80:9:80:18 | call to source : | active_support.rb:81:10:81:10 | x : | +| active_support.rb:80:5:80:5 | x : | active_support.rb:81:10:81:10 | x : | +| active_support.rb:80:9:80:18 | call to source : | active_support.rb:80:5:80:5 | x : | | active_support.rb:81:10:81:10 | x : | active_support.rb:81:10:81:18 | call to inquiry | -| active_support.rb:85:9:85:18 | call to source : | active_support.rb:86:10:86:10 | x : | +| active_support.rb:85:5:85:5 | x : | active_support.rb:86:10:86:10 | x : | +| active_support.rb:85:9:85:18 | call to source : | active_support.rb:85:5:85:5 | x : | | active_support.rb:86:10:86:10 | x : | active_support.rb:86:10:86:18 | call to last | -| active_support.rb:90:9:90:18 | call to source : | active_support.rb:91:10:91:10 | x : | +| active_support.rb:90:5:90:5 | x : | active_support.rb:91:10:91:10 | x : | +| active_support.rb:90:9:90:18 | call to source : | active_support.rb:90:5:90:5 | x : | | active_support.rb:91:10:91:10 | x : | active_support.rb:91:10:91:19 | call to mb_chars | -| active_support.rb:95:9:95:18 | call to source : | active_support.rb:96:10:96:10 | x : | +| active_support.rb:95:5:95:5 | x : | active_support.rb:96:10:96:10 | x : | +| active_support.rb:95:9:95:18 | call to source : | active_support.rb:95:5:95:5 | x : | | active_support.rb:96:10:96:10 | x : | active_support.rb:96:10:96:23 | call to parameterize | -| active_support.rb:100:9:100:18 | call to source : | active_support.rb:101:10:101:10 | x : | +| active_support.rb:100:5:100:5 | x : | active_support.rb:101:10:101:10 | x : | +| active_support.rb:100:9:100:18 | call to source : | active_support.rb:100:5:100:5 | x : | | active_support.rb:101:10:101:10 | x : | active_support.rb:101:10:101:20 | call to pluralize | -| active_support.rb:105:9:105:18 | call to source : | active_support.rb:106:10:106:10 | x : | +| active_support.rb:105:5:105:5 | x : | active_support.rb:106:10:106:10 | x : | +| active_support.rb:105:9:105:18 | call to source : | active_support.rb:105:5:105:5 | x : | | active_support.rb:106:10:106:10 | x : | active_support.rb:106:10:106:24 | call to remove | -| active_support.rb:110:9:110:18 | call to source : | active_support.rb:111:10:111:10 | x : | +| active_support.rb:110:5:110:5 | x : | active_support.rb:111:10:111:10 | x : | +| active_support.rb:110:9:110:18 | call to source : | active_support.rb:110:5:110:5 | x : | | active_support.rb:111:10:111:10 | x : | active_support.rb:111:10:111:25 | call to remove! | -| active_support.rb:115:9:115:18 | call to source : | active_support.rb:116:10:116:10 | x : | +| active_support.rb:115:5:115:5 | x : | active_support.rb:116:10:116:10 | x : | +| active_support.rb:115:9:115:18 | call to source : | active_support.rb:115:5:115:5 | x : | | active_support.rb:116:10:116:10 | x : | active_support.rb:116:10:116:22 | call to singularize | -| active_support.rb:120:9:120:18 | call to source : | active_support.rb:121:10:121:10 | x : | +| active_support.rb:120:5:120:5 | x : | active_support.rb:121:10:121:10 | x : | +| active_support.rb:120:9:120:18 | call to source : | active_support.rb:120:5:120:5 | x : | | active_support.rb:121:10:121:10 | x : | active_support.rb:121:10:121:17 | call to squish | -| active_support.rb:125:9:125:18 | call to source : | active_support.rb:126:10:126:10 | x : | +| active_support.rb:125:5:125:5 | x : | active_support.rb:126:10:126:10 | x : | +| active_support.rb:125:9:125:18 | call to source : | active_support.rb:125:5:125:5 | x : | | active_support.rb:126:10:126:10 | x : | active_support.rb:126:10:126:18 | call to squish! | -| active_support.rb:130:9:130:18 | call to source : | active_support.rb:131:10:131:10 | x : | +| active_support.rb:130:5:130:5 | x : | active_support.rb:131:10:131:10 | x : | +| active_support.rb:130:9:130:18 | call to source : | active_support.rb:130:5:130:5 | x : | | active_support.rb:131:10:131:10 | x : | active_support.rb:131:10:131:24 | call to strip_heredoc | -| active_support.rb:135:9:135:18 | call to source : | active_support.rb:136:10:136:10 | x : | +| active_support.rb:135:5:135:5 | x : | active_support.rb:136:10:136:10 | x : | +| active_support.rb:135:9:135:18 | call to source : | active_support.rb:135:5:135:5 | x : | | active_support.rb:136:10:136:10 | x : | active_support.rb:136:10:136:19 | call to tableize | -| active_support.rb:140:9:140:18 | call to source : | active_support.rb:141:10:141:10 | x : | +| active_support.rb:140:5:140:5 | x : | active_support.rb:141:10:141:10 | x : | +| active_support.rb:140:9:140:18 | call to source : | active_support.rb:140:5:140:5 | x : | | active_support.rb:141:10:141:10 | x : | active_support.rb:141:10:141:20 | call to titlecase | -| active_support.rb:145:9:145:18 | call to source : | active_support.rb:146:10:146:10 | x : | +| active_support.rb:145:5:145:5 | x : | active_support.rb:146:10:146:10 | x : | +| active_support.rb:145:9:145:18 | call to source : | active_support.rb:145:5:145:5 | x : | | active_support.rb:146:10:146:10 | x : | active_support.rb:146:10:146:19 | call to titleize | -| active_support.rb:150:9:150:18 | call to source : | active_support.rb:151:10:151:10 | x : | +| active_support.rb:150:5:150:5 | x : | active_support.rb:151:10:151:10 | x : | +| active_support.rb:150:9:150:18 | call to source : | active_support.rb:150:5:150:5 | x : | | active_support.rb:151:10:151:10 | x : | active_support.rb:151:10:151:16 | call to to | -| active_support.rb:155:9:155:18 | call to source : | active_support.rb:156:10:156:10 | x : | +| active_support.rb:155:5:155:5 | x : | active_support.rb:156:10:156:10 | x : | +| active_support.rb:155:9:155:18 | call to source : | active_support.rb:155:5:155:5 | x : | | active_support.rb:156:10:156:10 | x : | active_support.rb:156:10:156:22 | call to truncate | -| active_support.rb:160:9:160:18 | call to source : | active_support.rb:161:10:161:10 | x : | +| active_support.rb:160:5:160:5 | x : | active_support.rb:161:10:161:10 | x : | +| active_support.rb:160:9:160:18 | call to source : | active_support.rb:160:5:160:5 | x : | | active_support.rb:161:10:161:10 | x : | active_support.rb:161:10:161:28 | call to truncate_bytes | -| active_support.rb:165:9:165:18 | call to source : | active_support.rb:166:10:166:10 | x : | +| active_support.rb:165:5:165:5 | x : | active_support.rb:166:10:166:10 | x : | +| active_support.rb:165:9:165:18 | call to source : | active_support.rb:165:5:165:5 | x : | | active_support.rb:166:10:166:10 | x : | active_support.rb:166:10:166:28 | call to truncate_words | -| active_support.rb:170:9:170:18 | call to source : | active_support.rb:171:10:171:10 | x : | +| active_support.rb:170:5:170:5 | x : | active_support.rb:171:10:171:10 | x : | +| active_support.rb:170:9:170:18 | call to source : | active_support.rb:170:5:170:5 | x : | | active_support.rb:171:10:171:10 | x : | active_support.rb:171:10:171:21 | call to underscore | -| active_support.rb:175:9:175:18 | call to source : | active_support.rb:176:10:176:10 | x : | +| active_support.rb:175:5:175:5 | x : | active_support.rb:176:10:176:10 | x : | +| active_support.rb:175:9:175:18 | call to source : | active_support.rb:175:5:175:5 | x : | | active_support.rb:176:10:176:10 | x : | active_support.rb:176:10:176:23 | call to upcase_first | -| active_support.rb:180:10:180:17 | call to source : | active_support.rb:181:9:181:9 | x [element 0] : | -| active_support.rb:180:10:180:17 | call to source : | active_support.rb:181:9:181:9 | x [element 0] : | +| active_support.rb:180:5:180:5 | x [element 0] : | active_support.rb:181:9:181:9 | x [element 0] : | +| active_support.rb:180:5:180:5 | x [element 0] : | active_support.rb:181:9:181:9 | x [element 0] : | +| active_support.rb:180:10:180:17 | call to source : | active_support.rb:180:5:180:5 | x [element 0] : | +| active_support.rb:180:10:180:17 | call to source : | active_support.rb:180:5:180:5 | x [element 0] : | +| active_support.rb:181:5:181:5 | y [element] : | active_support.rb:182:10:182:10 | y [element] : | +| active_support.rb:181:5:181:5 | y [element] : | active_support.rb:182:10:182:10 | y [element] : | | active_support.rb:181:9:181:9 | x [element 0] : | active_support.rb:181:9:181:23 | call to compact_blank [element] : | | active_support.rb:181:9:181:9 | x [element 0] : | active_support.rb:181:9:181:23 | call to compact_blank [element] : | -| active_support.rb:181:9:181:23 | call to compact_blank [element] : | active_support.rb:182:10:182:10 | y [element] : | -| active_support.rb:181:9:181:23 | call to compact_blank [element] : | active_support.rb:182:10:182:10 | y [element] : | +| active_support.rb:181:9:181:23 | call to compact_blank [element] : | active_support.rb:181:5:181:5 | y [element] : | +| active_support.rb:181:9:181:23 | call to compact_blank [element] : | active_support.rb:181:5:181:5 | y [element] : | | active_support.rb:182:10:182:10 | y [element] : | active_support.rb:182:10:182:13 | ...[...] | | active_support.rb:182:10:182:10 | y [element] : | active_support.rb:182:10:182:13 | ...[...] | -| active_support.rb:186:10:186:18 | call to source : | active_support.rb:187:9:187:9 | x [element 0] : | -| active_support.rb:186:10:186:18 | call to source : | active_support.rb:187:9:187:9 | x [element 0] : | +| active_support.rb:186:5:186:5 | x [element 0] : | active_support.rb:187:9:187:9 | x [element 0] : | +| active_support.rb:186:5:186:5 | x [element 0] : | active_support.rb:187:9:187:9 | x [element 0] : | +| active_support.rb:186:10:186:18 | call to source : | active_support.rb:186:5:186:5 | x [element 0] : | +| active_support.rb:186:10:186:18 | call to source : | active_support.rb:186:5:186:5 | x [element 0] : | +| active_support.rb:187:5:187:5 | y [element] : | active_support.rb:188:10:188:10 | y [element] : | +| active_support.rb:187:5:187:5 | y [element] : | active_support.rb:188:10:188:10 | y [element] : | | active_support.rb:187:9:187:9 | x [element 0] : | active_support.rb:187:9:187:21 | call to excluding [element] : | | active_support.rb:187:9:187:9 | x [element 0] : | active_support.rb:187:9:187:21 | call to excluding [element] : | -| active_support.rb:187:9:187:21 | call to excluding [element] : | active_support.rb:188:10:188:10 | y [element] : | -| active_support.rb:187:9:187:21 | call to excluding [element] : | active_support.rb:188:10:188:10 | y [element] : | +| active_support.rb:187:9:187:21 | call to excluding [element] : | active_support.rb:187:5:187:5 | y [element] : | +| active_support.rb:187:9:187:21 | call to excluding [element] : | active_support.rb:187:5:187:5 | y [element] : | | active_support.rb:188:10:188:10 | y [element] : | active_support.rb:188:10:188:13 | ...[...] | | active_support.rb:188:10:188:10 | y [element] : | active_support.rb:188:10:188:13 | ...[...] | -| active_support.rb:192:10:192:18 | call to source : | active_support.rb:193:9:193:9 | x [element 0] : | -| active_support.rb:192:10:192:18 | call to source : | active_support.rb:193:9:193:9 | x [element 0] : | +| active_support.rb:192:5:192:5 | x [element 0] : | active_support.rb:193:9:193:9 | x [element 0] : | +| active_support.rb:192:5:192:5 | x [element 0] : | active_support.rb:193:9:193:9 | x [element 0] : | +| active_support.rb:192:10:192:18 | call to source : | active_support.rb:192:5:192:5 | x [element 0] : | +| active_support.rb:192:10:192:18 | call to source : | active_support.rb:192:5:192:5 | x [element 0] : | +| active_support.rb:193:5:193:5 | y [element] : | active_support.rb:194:10:194:10 | y [element] : | +| active_support.rb:193:5:193:5 | y [element] : | active_support.rb:194:10:194:10 | y [element] : | | active_support.rb:193:9:193:9 | x [element 0] : | active_support.rb:193:9:193:19 | call to without [element] : | | active_support.rb:193:9:193:9 | x [element 0] : | active_support.rb:193:9:193:19 | call to without [element] : | -| active_support.rb:193:9:193:19 | call to without [element] : | active_support.rb:194:10:194:10 | y [element] : | -| active_support.rb:193:9:193:19 | call to without [element] : | active_support.rb:194:10:194:10 | y [element] : | +| active_support.rb:193:9:193:19 | call to without [element] : | active_support.rb:193:5:193:5 | y [element] : | +| active_support.rb:193:9:193:19 | call to without [element] : | active_support.rb:193:5:193:5 | y [element] : | | active_support.rb:194:10:194:10 | y [element] : | active_support.rb:194:10:194:13 | ...[...] | | active_support.rb:194:10:194:10 | y [element] : | active_support.rb:194:10:194:13 | ...[...] | -| active_support.rb:198:10:198:18 | call to source : | active_support.rb:199:9:199:9 | x [element 0] : | -| active_support.rb:198:10:198:18 | call to source : | active_support.rb:199:9:199:9 | x [element 0] : | +| active_support.rb:198:5:198:5 | x [element 0] : | active_support.rb:199:9:199:9 | x [element 0] : | +| active_support.rb:198:5:198:5 | x [element 0] : | active_support.rb:199:9:199:9 | x [element 0] : | +| active_support.rb:198:10:198:18 | call to source : | active_support.rb:198:5:198:5 | x [element 0] : | +| active_support.rb:198:10:198:18 | call to source : | active_support.rb:198:5:198:5 | x [element 0] : | +| active_support.rb:199:5:199:5 | y [element] : | active_support.rb:200:10:200:10 | y [element] : | +| active_support.rb:199:5:199:5 | y [element] : | active_support.rb:200:10:200:10 | y [element] : | | active_support.rb:199:9:199:9 | x [element 0] : | active_support.rb:199:9:199:37 | call to in_order_of [element] : | | active_support.rb:199:9:199:9 | x [element 0] : | active_support.rb:199:9:199:37 | call to in_order_of [element] : | -| active_support.rb:199:9:199:37 | call to in_order_of [element] : | active_support.rb:200:10:200:10 | y [element] : | -| active_support.rb:199:9:199:37 | call to in_order_of [element] : | active_support.rb:200:10:200:10 | y [element] : | +| active_support.rb:199:9:199:37 | call to in_order_of [element] : | active_support.rb:199:5:199:5 | y [element] : | +| active_support.rb:199:9:199:37 | call to in_order_of [element] : | active_support.rb:199:5:199:5 | y [element] : | | active_support.rb:200:10:200:10 | y [element] : | active_support.rb:200:10:200:13 | ...[...] | | active_support.rb:200:10:200:10 | y [element] : | active_support.rb:200:10:200:13 | ...[...] | -| active_support.rb:204:10:204:18 | call to source : | active_support.rb:205:9:205:9 | a [element 0] : | -| active_support.rb:204:10:204:18 | call to source : | active_support.rb:205:9:205:9 | a [element 0] : | -| active_support.rb:204:10:204:18 | call to source : | active_support.rb:206:10:206:10 | a [element 0] : | -| active_support.rb:204:10:204:18 | call to source : | active_support.rb:206:10:206:10 | a [element 0] : | +| active_support.rb:204:5:204:5 | a [element 0] : | active_support.rb:205:9:205:9 | a [element 0] : | +| active_support.rb:204:5:204:5 | a [element 0] : | active_support.rb:205:9:205:9 | a [element 0] : | +| active_support.rb:204:5:204:5 | a [element 0] : | active_support.rb:206:10:206:10 | a [element 0] : | +| active_support.rb:204:5:204:5 | a [element 0] : | active_support.rb:206:10:206:10 | a [element 0] : | +| active_support.rb:204:10:204:18 | call to source : | active_support.rb:204:5:204:5 | a [element 0] : | +| active_support.rb:204:10:204:18 | call to source : | active_support.rb:204:5:204:5 | a [element 0] : | +| active_support.rb:205:5:205:5 | b [element 0] : | active_support.rb:208:10:208:10 | b [element 0] : | +| active_support.rb:205:5:205:5 | b [element 0] : | active_support.rb:208:10:208:10 | b [element 0] : | +| active_support.rb:205:5:205:5 | b [element] : | active_support.rb:208:10:208:10 | b [element] : | +| active_support.rb:205:5:205:5 | b [element] : | active_support.rb:208:10:208:10 | b [element] : | +| active_support.rb:205:5:205:5 | b [element] : | active_support.rb:209:10:209:10 | b [element] : | +| active_support.rb:205:5:205:5 | b [element] : | active_support.rb:209:10:209:10 | b [element] : | +| active_support.rb:205:5:205:5 | b [element] : | active_support.rb:210:10:210:10 | b [element] : | +| active_support.rb:205:5:205:5 | b [element] : | active_support.rb:210:10:210:10 | b [element] : | +| active_support.rb:205:5:205:5 | b [element] : | active_support.rb:211:10:211:10 | b [element] : | +| active_support.rb:205:5:205:5 | b [element] : | active_support.rb:211:10:211:10 | b [element] : | | active_support.rb:205:9:205:9 | a [element 0] : | active_support.rb:205:9:205:41 | call to including [element 0] : | | active_support.rb:205:9:205:9 | a [element 0] : | active_support.rb:205:9:205:41 | call to including [element 0] : | -| active_support.rb:205:9:205:41 | call to including [element 0] : | active_support.rb:208:10:208:10 | b [element 0] : | -| active_support.rb:205:9:205:41 | call to including [element 0] : | active_support.rb:208:10:208:10 | b [element 0] : | -| active_support.rb:205:9:205:41 | call to including [element] : | active_support.rb:208:10:208:10 | b [element] : | -| active_support.rb:205:9:205:41 | call to including [element] : | active_support.rb:208:10:208:10 | b [element] : | -| active_support.rb:205:9:205:41 | call to including [element] : | active_support.rb:209:10:209:10 | b [element] : | -| active_support.rb:205:9:205:41 | call to including [element] : | active_support.rb:209:10:209:10 | b [element] : | -| active_support.rb:205:9:205:41 | call to including [element] : | active_support.rb:210:10:210:10 | b [element] : | -| active_support.rb:205:9:205:41 | call to including [element] : | active_support.rb:210:10:210:10 | b [element] : | -| active_support.rb:205:9:205:41 | call to including [element] : | active_support.rb:211:10:211:10 | b [element] : | -| active_support.rb:205:9:205:41 | call to including [element] : | active_support.rb:211:10:211:10 | b [element] : | +| active_support.rb:205:9:205:41 | call to including [element 0] : | active_support.rb:205:5:205:5 | b [element 0] : | +| active_support.rb:205:9:205:41 | call to including [element 0] : | active_support.rb:205:5:205:5 | b [element 0] : | +| active_support.rb:205:9:205:41 | call to including [element] : | active_support.rb:205:5:205:5 | b [element] : | +| active_support.rb:205:9:205:41 | call to including [element] : | active_support.rb:205:5:205:5 | b [element] : | | active_support.rb:205:21:205:29 | call to source : | active_support.rb:205:9:205:41 | call to including [element] : | | active_support.rb:205:21:205:29 | call to source : | active_support.rb:205:9:205:41 | call to including [element] : | | active_support.rb:205:32:205:40 | call to source : | active_support.rb:205:9:205:41 | call to including [element] : | @@ -133,130 +189,202 @@ edges | active_support.rb:210:10:210:10 | b [element] : | active_support.rb:210:10:210:13 | ...[...] | | active_support.rb:211:10:211:10 | b [element] : | active_support.rb:211:10:211:13 | ...[...] | | active_support.rb:211:10:211:10 | b [element] : | active_support.rb:211:10:211:13 | ...[...] | -| active_support.rb:215:7:215:16 | call to source : | active_support.rb:216:34:216:34 | x : | -| active_support.rb:216:7:216:35 | call to new : | active_support.rb:217:8:217:8 | y | +| active_support.rb:215:3:215:3 | x : | active_support.rb:216:34:216:34 | x : | +| active_support.rb:215:7:215:16 | call to source : | active_support.rb:215:3:215:3 | x : | +| active_support.rb:216:3:216:3 | y : | active_support.rb:217:8:217:8 | y | +| active_support.rb:216:7:216:35 | call to new : | active_support.rb:216:3:216:3 | y : | | active_support.rb:216:34:216:34 | x : | active_support.rb:216:7:216:35 | call to new : | -| active_support.rb:222:7:222:16 | call to source : | active_support.rb:223:21:223:21 | b : | -| active_support.rb:223:7:223:22 | call to safe_concat : | active_support.rb:224:8:224:8 | y | +| active_support.rb:222:3:222:3 | b : | active_support.rb:223:21:223:21 | b : | +| active_support.rb:222:7:222:16 | call to source : | active_support.rb:222:3:222:3 | b : | +| active_support.rb:223:3:223:3 | y : | active_support.rb:224:8:224:8 | y | +| active_support.rb:223:7:223:22 | call to safe_concat : | active_support.rb:223:3:223:3 | y : | | active_support.rb:223:21:223:21 | b : | active_support.rb:223:7:223:22 | call to safe_concat : | -| active_support.rb:229:7:229:16 | call to source : | active_support.rb:230:17:230:17 | b : | +| active_support.rb:229:3:229:3 | b : | active_support.rb:230:17:230:17 | b : | +| active_support.rb:229:7:229:16 | call to source : | active_support.rb:229:3:229:3 | b : | | active_support.rb:230:3:230:3 | [post] x : | active_support.rb:231:8:231:8 | x | | active_support.rb:230:17:230:17 | b : | active_support.rb:230:3:230:3 | [post] x : | -| active_support.rb:235:7:235:16 | call to source : | active_support.rb:237:34:237:34 | a : | -| active_support.rb:237:7:237:35 | call to new : | active_support.rb:238:7:238:7 | x : | +| active_support.rb:235:3:235:3 | a : | active_support.rb:237:34:237:34 | a : | +| active_support.rb:235:7:235:16 | call to source : | active_support.rb:235:3:235:3 | a : | +| active_support.rb:237:3:237:3 | x : | active_support.rb:238:7:238:7 | x : | +| active_support.rb:237:7:237:35 | call to new : | active_support.rb:237:3:237:3 | x : | | active_support.rb:237:34:237:34 | a : | active_support.rb:237:7:237:35 | call to new : | +| active_support.rb:238:3:238:3 | y : | active_support.rb:239:8:239:8 | y | | active_support.rb:238:7:238:7 | x : | active_support.rb:238:7:238:17 | call to concat : | -| active_support.rb:238:7:238:17 | call to concat : | active_support.rb:239:8:239:8 | y | -| active_support.rb:243:7:243:16 | call to source : | active_support.rb:245:34:245:34 | a : | -| active_support.rb:245:7:245:35 | call to new : | active_support.rb:246:7:246:7 | x : | +| active_support.rb:238:7:238:17 | call to concat : | active_support.rb:238:3:238:3 | y : | +| active_support.rb:243:3:243:3 | a : | active_support.rb:245:34:245:34 | a : | +| active_support.rb:243:7:243:16 | call to source : | active_support.rb:243:3:243:3 | a : | +| active_support.rb:245:3:245:3 | x : | active_support.rb:246:7:246:7 | x : | +| active_support.rb:245:7:245:35 | call to new : | active_support.rb:245:3:245:3 | x : | | active_support.rb:245:34:245:34 | a : | active_support.rb:245:7:245:35 | call to new : | +| active_support.rb:246:3:246:3 | y : | active_support.rb:247:8:247:8 | y | | active_support.rb:246:7:246:7 | x : | active_support.rb:246:7:246:20 | call to insert : | -| active_support.rb:246:7:246:20 | call to insert : | active_support.rb:247:8:247:8 | y | -| active_support.rb:251:7:251:16 | call to source : | active_support.rb:253:34:253:34 | a : | -| active_support.rb:253:7:253:35 | call to new : | active_support.rb:254:7:254:7 | x : | +| active_support.rb:246:7:246:20 | call to insert : | active_support.rb:246:3:246:3 | y : | +| active_support.rb:251:3:251:3 | a : | active_support.rb:253:34:253:34 | a : | +| active_support.rb:251:7:251:16 | call to source : | active_support.rb:251:3:251:3 | a : | +| active_support.rb:253:3:253:3 | x : | active_support.rb:254:7:254:7 | x : | +| active_support.rb:253:7:253:35 | call to new : | active_support.rb:253:3:253:3 | x : | | active_support.rb:253:34:253:34 | a : | active_support.rb:253:7:253:35 | call to new : | +| active_support.rb:254:3:254:3 | y : | active_support.rb:255:8:255:8 | y | | active_support.rb:254:7:254:7 | x : | active_support.rb:254:7:254:18 | call to prepend : | -| active_support.rb:254:7:254:18 | call to prepend : | active_support.rb:255:8:255:8 | y | -| active_support.rb:259:7:259:16 | call to source : | active_support.rb:260:34:260:34 | a : | -| active_support.rb:260:7:260:35 | call to new : | active_support.rb:261:7:261:7 | x : | +| active_support.rb:254:7:254:18 | call to prepend : | active_support.rb:254:3:254:3 | y : | +| active_support.rb:259:3:259:3 | a : | active_support.rb:260:34:260:34 | a : | +| active_support.rb:259:7:259:16 | call to source : | active_support.rb:259:3:259:3 | a : | +| active_support.rb:260:3:260:3 | x : | active_support.rb:261:7:261:7 | x : | +| active_support.rb:260:7:260:35 | call to new : | active_support.rb:260:3:260:3 | x : | | active_support.rb:260:34:260:34 | a : | active_support.rb:260:7:260:35 | call to new : | +| active_support.rb:261:3:261:3 | y : | active_support.rb:262:8:262:8 | y | | active_support.rb:261:7:261:7 | x : | active_support.rb:261:7:261:12 | call to to_s : | -| active_support.rb:261:7:261:12 | call to to_s : | active_support.rb:262:8:262:8 | y | -| active_support.rb:266:7:266:16 | call to source : | active_support.rb:267:34:267:34 | a : | -| active_support.rb:267:7:267:35 | call to new : | active_support.rb:268:7:268:7 | x : | +| active_support.rb:261:7:261:12 | call to to_s : | active_support.rb:261:3:261:3 | y : | +| active_support.rb:266:3:266:3 | a : | active_support.rb:267:34:267:34 | a : | +| active_support.rb:266:7:266:16 | call to source : | active_support.rb:266:3:266:3 | a : | +| active_support.rb:267:3:267:3 | x : | active_support.rb:268:7:268:7 | x : | +| active_support.rb:267:7:267:35 | call to new : | active_support.rb:267:3:267:3 | x : | | active_support.rb:267:34:267:34 | a : | active_support.rb:267:7:267:35 | call to new : | +| active_support.rb:268:3:268:3 | y : | active_support.rb:269:8:269:8 | y | | active_support.rb:268:7:268:7 | x : | active_support.rb:268:7:268:16 | call to to_param : | -| active_support.rb:268:7:268:16 | call to to_param : | active_support.rb:269:8:269:8 | y | -| active_support.rb:273:7:273:16 | call to source : | active_support.rb:274:20:274:20 | a : | -| active_support.rb:274:7:274:21 | call to new : | active_support.rb:275:7:275:7 | x : | +| active_support.rb:268:7:268:16 | call to to_param : | active_support.rb:268:3:268:3 | y : | +| active_support.rb:273:3:273:3 | a : | active_support.rb:274:20:274:20 | a : | +| active_support.rb:273:7:273:16 | call to source : | active_support.rb:273:3:273:3 | a : | +| active_support.rb:274:3:274:3 | x : | active_support.rb:275:7:275:7 | x : | +| active_support.rb:274:7:274:21 | call to new : | active_support.rb:274:3:274:3 | x : | | active_support.rb:274:20:274:20 | a : | active_support.rb:274:7:274:21 | call to new : | +| active_support.rb:275:3:275:3 | y : | active_support.rb:276:8:276:8 | y | +| active_support.rb:275:3:275:3 | y : | active_support.rb:277:7:277:7 | y : | | active_support.rb:275:7:275:7 | x : | active_support.rb:275:7:275:17 | call to existence : | -| active_support.rb:275:7:275:17 | call to existence : | active_support.rb:276:8:276:8 | y | -| active_support.rb:275:7:275:17 | call to existence : | active_support.rb:277:7:277:7 | y : | +| active_support.rb:275:7:275:17 | call to existence : | active_support.rb:275:3:275:3 | y : | +| active_support.rb:277:3:277:3 | z : | active_support.rb:278:8:278:8 | z | | active_support.rb:277:7:277:7 | y : | active_support.rb:277:7:277:17 | call to existence : | -| active_support.rb:277:7:277:17 | call to existence : | active_support.rb:278:8:278:8 | z | -| active_support.rb:282:7:282:16 | call to source : | active_support.rb:283:8:283:8 | x : | -| active_support.rb:282:7:282:16 | call to source : | active_support.rb:283:8:283:8 | x : | +| active_support.rb:277:7:277:17 | call to existence : | active_support.rb:277:3:277:3 | z : | +| active_support.rb:282:3:282:3 | x : | active_support.rb:283:8:283:8 | x : | +| active_support.rb:282:3:282:3 | x : | active_support.rb:283:8:283:8 | x : | +| active_support.rb:282:7:282:16 | call to source : | active_support.rb:282:3:282:3 | x : | +| active_support.rb:282:7:282:16 | call to source : | active_support.rb:282:3:282:3 | x : | | active_support.rb:283:8:283:8 | x : | active_support.rb:283:8:283:17 | call to presence | | active_support.rb:283:8:283:8 | x : | active_support.rb:283:8:283:17 | call to presence | -| active_support.rb:285:7:285:16 | call to source : | active_support.rb:286:8:286:8 | y : | -| active_support.rb:285:7:285:16 | call to source : | active_support.rb:286:8:286:8 | y : | +| active_support.rb:285:3:285:3 | y : | active_support.rb:286:8:286:8 | y : | +| active_support.rb:285:3:285:3 | y : | active_support.rb:286:8:286:8 | y : | +| active_support.rb:285:7:285:16 | call to source : | active_support.rb:285:3:285:3 | y : | +| active_support.rb:285:7:285:16 | call to source : | active_support.rb:285:3:285:3 | y : | | active_support.rb:286:8:286:8 | y : | active_support.rb:286:8:286:17 | call to presence | | active_support.rb:286:8:286:8 | y : | active_support.rb:286:8:286:17 | call to presence | -| active_support.rb:290:7:290:16 | call to source : | active_support.rb:291:8:291:8 | x : | -| active_support.rb:290:7:290:16 | call to source : | active_support.rb:291:8:291:8 | x : | +| active_support.rb:290:3:290:3 | x : | active_support.rb:291:8:291:8 | x : | +| active_support.rb:290:3:290:3 | x : | active_support.rb:291:8:291:8 | x : | +| active_support.rb:290:7:290:16 | call to source : | active_support.rb:290:3:290:3 | x : | +| active_support.rb:290:7:290:16 | call to source : | active_support.rb:290:3:290:3 | 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:303:3:303:3 | a : | active_support.rb:304:19:304:19 | a : | +| active_support.rb:303:7:303:16 | call to source : | active_support.rb:303:3:303:3 | a : | +| active_support.rb:304:3:304:3 | b : | active_support.rb:305:8:305:8 | b | +| active_support.rb:304:7:304:19 | call to json_escape : | active_support.rb:304:3:304:3 | 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:309:5:309:5 | x : | active_support.rb:310:37:310:37 | x : | +| active_support.rb:309:9:309:18 | call to source : | active_support.rb:309:5:309:5 | 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:314:5:314:5 | x : | active_support.rb:315:37:315:37 | x : | +| active_support.rb:314:9:314:18 | call to source : | active_support.rb:314:5:314:5 | 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:319:5:319:5 | x : | active_support.rb:320:35:320:35 | x : | +| active_support.rb:319:9:319:18 | call to source : | active_support.rb:319:5:319:5 | 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:324:5:324:5 | x : | active_support.rb:325:35:325:35 | x : | +| active_support.rb:324:9:324:18 | call to source : | active_support.rb:324:5:324:5 | 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:329:5:329:5 | x : | active_support.rb:330:10:330:10 | x : | +| active_support.rb:329:5:329:5 | x : | active_support.rb:331:10:331:10 | x : | +| active_support.rb:329:9:329:18 | call to source : | active_support.rb:329:5:329:5 | x : | +| active_support.rb:330:5:330:5 | y [element 0] : | active_support.rb:332:10:332:10 | y [element 0] : | +| active_support.rb:330:10:330:10 | x : | active_support.rb:330:5:330:5 | 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:2:5:2:5 | h [element :a] : | hash_extensions.rb:3:9:3:9 | h [element :a] : | +| hash_extensions.rb:2:5:2:5 | h [element :a] : | hash_extensions.rb:3:9:3:9 | h [element :a] : | +| hash_extensions.rb:2:14:2:24 | call to source : | hash_extensions.rb:2:5:2:5 | h [element :a] : | +| hash_extensions.rb:2:14:2:24 | call to source : | hash_extensions.rb:2:5:2:5 | h [element :a] : | +| hash_extensions.rb:3:5:3:5 | x [element] : | hash_extensions.rb:4:10:4:10 | x [element] : | +| hash_extensions.rb:3:5:3:5 | x [element] : | hash_extensions.rb:4:10:4:10 | x [element] : | | hash_extensions.rb:3:9:3:9 | h [element :a] : | hash_extensions.rb:3:9:3:24 | call to stringify_keys [element] : | | hash_extensions.rb:3:9:3:9 | h [element :a] : | hash_extensions.rb:3:9:3:24 | call to stringify_keys [element] : | -| hash_extensions.rb:3:9:3:24 | call to stringify_keys [element] : | hash_extensions.rb:4:10:4:10 | x [element] : | -| hash_extensions.rb:3:9:3:24 | call to stringify_keys [element] : | hash_extensions.rb:4:10:4:10 | x [element] : | +| hash_extensions.rb:3:9:3:24 | call to stringify_keys [element] : | hash_extensions.rb:3:5:3:5 | x [element] : | +| hash_extensions.rb:3:9:3:24 | call to stringify_keys [element] : | hash_extensions.rb:3:5:3:5 | x [element] : | | hash_extensions.rb:4:10:4:10 | x [element] : | hash_extensions.rb:4:10:4:14 | ...[...] | | hash_extensions.rb:4:10:4:10 | x [element] : | hash_extensions.rb:4:10:4:14 | ...[...] | -| hash_extensions.rb:10:14:10:24 | call to source : | hash_extensions.rb:11:9:11:9 | h [element :a] : | -| hash_extensions.rb:10:14:10:24 | call to source : | hash_extensions.rb:11:9:11:9 | h [element :a] : | +| hash_extensions.rb:10:5:10:5 | h [element :a] : | hash_extensions.rb:11:9:11:9 | h [element :a] : | +| hash_extensions.rb:10:5:10:5 | h [element :a] : | hash_extensions.rb:11:9:11:9 | h [element :a] : | +| hash_extensions.rb:10:14:10:24 | call to source : | hash_extensions.rb:10:5:10:5 | h [element :a] : | +| hash_extensions.rb:10:14:10:24 | call to source : | hash_extensions.rb:10:5:10:5 | h [element :a] : | +| hash_extensions.rb:11:5:11:5 | x [element] : | hash_extensions.rb:12:10:12:10 | x [element] : | +| hash_extensions.rb:11:5:11:5 | x [element] : | hash_extensions.rb:12:10:12:10 | x [element] : | | hash_extensions.rb:11:9:11:9 | h [element :a] : | hash_extensions.rb:11:9:11:20 | call to to_options [element] : | | hash_extensions.rb:11:9:11:9 | h [element :a] : | hash_extensions.rb:11:9:11:20 | call to to_options [element] : | -| hash_extensions.rb:11:9:11:20 | call to to_options [element] : | hash_extensions.rb:12:10:12:10 | x [element] : | -| hash_extensions.rb:11:9:11:20 | call to to_options [element] : | hash_extensions.rb:12:10:12:10 | x [element] : | +| hash_extensions.rb:11:9:11:20 | call to to_options [element] : | hash_extensions.rb:11:5:11:5 | x [element] : | +| hash_extensions.rb:11:9:11:20 | call to to_options [element] : | hash_extensions.rb:11:5:11:5 | x [element] : | | hash_extensions.rb:12:10:12:10 | x [element] : | hash_extensions.rb:12:10:12:14 | ...[...] | | hash_extensions.rb:12:10:12:10 | x [element] : | hash_extensions.rb:12:10:12:14 | ...[...] | -| hash_extensions.rb:18:14:18:24 | call to source : | hash_extensions.rb:19:9:19:9 | h [element :a] : | -| hash_extensions.rb:18:14:18:24 | call to source : | hash_extensions.rb:19:9:19:9 | h [element :a] : | +| hash_extensions.rb:18:5:18:5 | h [element :a] : | hash_extensions.rb:19:9:19:9 | h [element :a] : | +| hash_extensions.rb:18:5:18:5 | h [element :a] : | hash_extensions.rb:19:9:19:9 | h [element :a] : | +| hash_extensions.rb:18:14:18:24 | call to source : | hash_extensions.rb:18:5:18:5 | h [element :a] : | +| hash_extensions.rb:18:14:18:24 | call to source : | hash_extensions.rb:18:5:18:5 | h [element :a] : | +| hash_extensions.rb:19:5:19:5 | x [element] : | hash_extensions.rb:20:10:20:10 | x [element] : | +| hash_extensions.rb:19:5:19:5 | x [element] : | hash_extensions.rb:20:10:20:10 | x [element] : | | hash_extensions.rb:19:9:19:9 | h [element :a] : | hash_extensions.rb:19:9:19:24 | call to symbolize_keys [element] : | | hash_extensions.rb:19:9:19:9 | h [element :a] : | hash_extensions.rb:19:9:19:24 | call to symbolize_keys [element] : | -| hash_extensions.rb:19:9:19:24 | call to symbolize_keys [element] : | hash_extensions.rb:20:10:20:10 | x [element] : | -| hash_extensions.rb:19:9:19:24 | call to symbolize_keys [element] : | hash_extensions.rb:20:10:20:10 | x [element] : | +| hash_extensions.rb:19:9:19:24 | call to symbolize_keys [element] : | hash_extensions.rb:19:5:19:5 | x [element] : | +| hash_extensions.rb:19:9:19:24 | call to symbolize_keys [element] : | hash_extensions.rb:19:5:19:5 | x [element] : | | hash_extensions.rb:20:10:20:10 | x [element] : | hash_extensions.rb:20:10:20:14 | ...[...] | | hash_extensions.rb:20:10:20:10 | x [element] : | hash_extensions.rb:20:10:20:14 | ...[...] | -| hash_extensions.rb:26:14:26:24 | call to source : | hash_extensions.rb:27:9:27:9 | h [element :a] : | -| hash_extensions.rb:26:14:26:24 | call to source : | hash_extensions.rb:27:9:27:9 | h [element :a] : | +| hash_extensions.rb:26:5:26:5 | h [element :a] : | hash_extensions.rb:27:9:27:9 | h [element :a] : | +| hash_extensions.rb:26:5:26:5 | h [element :a] : | hash_extensions.rb:27:9:27:9 | h [element :a] : | +| hash_extensions.rb:26:14:26:24 | call to source : | hash_extensions.rb:26:5:26:5 | h [element :a] : | +| hash_extensions.rb:26:14:26:24 | call to source : | hash_extensions.rb:26:5:26:5 | h [element :a] : | +| hash_extensions.rb:27:5:27:5 | x [element] : | hash_extensions.rb:28:10:28:10 | x [element] : | +| hash_extensions.rb:27:5:27:5 | x [element] : | hash_extensions.rb:28:10:28:10 | x [element] : | | hash_extensions.rb:27:9:27:9 | h [element :a] : | hash_extensions.rb:27:9:27:29 | call to deep_stringify_keys [element] : | | hash_extensions.rb:27:9:27:9 | h [element :a] : | hash_extensions.rb:27:9:27:29 | call to deep_stringify_keys [element] : | -| hash_extensions.rb:27:9:27:29 | call to deep_stringify_keys [element] : | hash_extensions.rb:28:10:28:10 | x [element] : | -| hash_extensions.rb:27:9:27:29 | call to deep_stringify_keys [element] : | hash_extensions.rb:28:10:28:10 | x [element] : | +| hash_extensions.rb:27:9:27:29 | call to deep_stringify_keys [element] : | hash_extensions.rb:27:5:27:5 | x [element] : | +| hash_extensions.rb:27:9:27:29 | call to deep_stringify_keys [element] : | hash_extensions.rb:27:5:27:5 | x [element] : | | hash_extensions.rb:28:10:28:10 | x [element] : | hash_extensions.rb:28:10:28:14 | ...[...] | | hash_extensions.rb:28:10:28:10 | x [element] : | hash_extensions.rb:28:10:28:14 | ...[...] | -| hash_extensions.rb:34:14:34:24 | call to source : | hash_extensions.rb:35:9:35:9 | h [element :a] : | -| hash_extensions.rb:34:14:34:24 | call to source : | hash_extensions.rb:35:9:35:9 | h [element :a] : | +| hash_extensions.rb:34:5:34:5 | h [element :a] : | hash_extensions.rb:35:9:35:9 | h [element :a] : | +| hash_extensions.rb:34:5:34:5 | h [element :a] : | hash_extensions.rb:35:9:35:9 | h [element :a] : | +| hash_extensions.rb:34:14:34:24 | call to source : | hash_extensions.rb:34:5:34:5 | h [element :a] : | +| hash_extensions.rb:34:14:34:24 | call to source : | hash_extensions.rb:34:5:34:5 | h [element :a] : | +| hash_extensions.rb:35:5:35:5 | x [element] : | hash_extensions.rb:36:10:36:10 | x [element] : | +| hash_extensions.rb:35:5:35:5 | x [element] : | hash_extensions.rb:36:10:36:10 | x [element] : | | hash_extensions.rb:35:9:35:9 | h [element :a] : | hash_extensions.rb:35:9:35:29 | call to deep_symbolize_keys [element] : | | hash_extensions.rb:35:9:35:9 | h [element :a] : | hash_extensions.rb:35:9:35:29 | call to deep_symbolize_keys [element] : | -| hash_extensions.rb:35:9:35:29 | call to deep_symbolize_keys [element] : | hash_extensions.rb:36:10:36:10 | x [element] : | -| hash_extensions.rb:35:9:35:29 | call to deep_symbolize_keys [element] : | hash_extensions.rb:36:10:36:10 | x [element] : | +| hash_extensions.rb:35:9:35:29 | call to deep_symbolize_keys [element] : | hash_extensions.rb:35:5:35:5 | x [element] : | +| hash_extensions.rb:35:9:35:29 | call to deep_symbolize_keys [element] : | hash_extensions.rb:35:5:35:5 | x [element] : | | hash_extensions.rb:36:10:36:10 | x [element] : | hash_extensions.rb:36:10:36:14 | ...[...] | | hash_extensions.rb:36:10:36:10 | x [element] : | hash_extensions.rb:36:10:36:14 | ...[...] | -| hash_extensions.rb:42:14:42:24 | call to source : | hash_extensions.rb:43:9:43:9 | h [element :a] : | -| hash_extensions.rb:42:14:42:24 | call to source : | hash_extensions.rb:43:9:43:9 | h [element :a] : | +| hash_extensions.rb:42:5:42:5 | h [element :a] : | hash_extensions.rb:43:9:43:9 | h [element :a] : | +| hash_extensions.rb:42:5:42:5 | h [element :a] : | hash_extensions.rb:43:9:43:9 | h [element :a] : | +| hash_extensions.rb:42:14:42:24 | call to source : | hash_extensions.rb:42:5:42:5 | h [element :a] : | +| hash_extensions.rb:42:14:42:24 | call to source : | hash_extensions.rb:42:5:42:5 | h [element :a] : | +| hash_extensions.rb:43:5:43:5 | x [element] : | hash_extensions.rb:44:10:44:10 | x [element] : | +| hash_extensions.rb:43:5:43:5 | x [element] : | hash_extensions.rb:44:10:44:10 | x [element] : | | hash_extensions.rb:43:9:43:9 | h [element :a] : | hash_extensions.rb:43:9:43:33 | call to with_indifferent_access [element] : | | hash_extensions.rb:43:9:43:9 | h [element :a] : | hash_extensions.rb:43:9:43:33 | call to with_indifferent_access [element] : | -| hash_extensions.rb:43:9:43:33 | call to with_indifferent_access [element] : | hash_extensions.rb:44:10:44:10 | x [element] : | -| hash_extensions.rb:43:9:43:33 | call to with_indifferent_access [element] : | hash_extensions.rb:44:10:44:10 | x [element] : | +| hash_extensions.rb:43:9:43:33 | call to with_indifferent_access [element] : | hash_extensions.rb:43:5:43:5 | x [element] : | +| hash_extensions.rb:43:9:43:33 | call to with_indifferent_access [element] : | hash_extensions.rb:43:5:43:5 | x [element] : | | hash_extensions.rb:44:10:44:10 | x [element] : | hash_extensions.rb:44:10:44:14 | ...[...] | | hash_extensions.rb:44:10:44:10 | x [element] : | hash_extensions.rb:44:10:44:14 | ...[...] | -| hash_extensions.rb:50:14:50:23 | call to taint : | hash_extensions.rb:51:9:51:9 | h [element :a] : | -| hash_extensions.rb:50:14:50:23 | call to taint : | hash_extensions.rb:51:9:51:9 | h [element :a] : | -| hash_extensions.rb:50:29:50:38 | call to taint : | hash_extensions.rb:51:9:51:9 | h [element :b] : | -| hash_extensions.rb:50:29:50:38 | call to taint : | hash_extensions.rb:51:9:51:9 | h [element :b] : | -| hash_extensions.rb:50:52:50:61 | call to taint : | hash_extensions.rb:51:9:51:9 | h [element :d] : | -| hash_extensions.rb:50:52:50:61 | call to taint : | hash_extensions.rb:51:9:51:9 | h [element :d] : | +| hash_extensions.rb:50:5:50:5 | h [element :a] : | hash_extensions.rb:51:9:51:9 | h [element :a] : | +| hash_extensions.rb:50:5:50:5 | h [element :a] : | hash_extensions.rb:51:9:51:9 | h [element :a] : | +| hash_extensions.rb:50:5:50:5 | h [element :b] : | hash_extensions.rb:51:9:51:9 | h [element :b] : | +| hash_extensions.rb:50:5:50:5 | h [element :b] : | hash_extensions.rb:51:9:51:9 | h [element :b] : | +| hash_extensions.rb:50:5:50:5 | h [element :d] : | hash_extensions.rb:51:9:51:9 | h [element :d] : | +| hash_extensions.rb:50:5:50:5 | h [element :d] : | hash_extensions.rb:51:9:51:9 | h [element :d] : | +| hash_extensions.rb:50:14:50:23 | call to taint : | hash_extensions.rb:50:5:50:5 | h [element :a] : | +| hash_extensions.rb:50:14:50:23 | call to taint : | hash_extensions.rb:50:5:50:5 | h [element :a] : | +| hash_extensions.rb:50:29:50:38 | call to taint : | hash_extensions.rb:50:5:50:5 | h [element :b] : | +| hash_extensions.rb:50:29:50:38 | call to taint : | hash_extensions.rb:50:5:50:5 | h [element :b] : | +| hash_extensions.rb:50:52:50:61 | call to taint : | hash_extensions.rb:50:5:50:5 | h [element :d] : | +| hash_extensions.rb:50:52:50:61 | call to taint : | hash_extensions.rb:50:5:50:5 | h [element :d] : | +| hash_extensions.rb:51:5:51:5 | x [element :a] : | hash_extensions.rb:58:10:58:10 | x [element :a] : | +| hash_extensions.rb:51:5:51:5 | x [element :a] : | hash_extensions.rb:58:10:58:10 | x [element :a] : | +| hash_extensions.rb:51:5:51:5 | x [element :b] : | hash_extensions.rb:59:10:59:10 | x [element :b] : | +| hash_extensions.rb:51:5:51:5 | x [element :b] : | hash_extensions.rb:59:10:59:10 | x [element :b] : | | hash_extensions.rb:51:9:51:9 | [post] h [element :d] : | hash_extensions.rb:56:10:56:10 | h [element :d] : | | hash_extensions.rb:51:9:51:9 | [post] h [element :d] : | hash_extensions.rb:56:10:56:10 | h [element :d] : | | hash_extensions.rb:51:9:51:9 | h [element :a] : | hash_extensions.rb:51:9:51:29 | call to extract! [element :a] : | @@ -265,22 +393,32 @@ edges | hash_extensions.rb:51:9:51:9 | h [element :b] : | hash_extensions.rb:51:9:51:29 | call to extract! [element :b] : | | hash_extensions.rb:51:9:51:9 | h [element :d] : | hash_extensions.rb:51:9:51:9 | [post] h [element :d] : | | hash_extensions.rb:51:9:51:9 | h [element :d] : | hash_extensions.rb:51:9:51:9 | [post] h [element :d] : | -| hash_extensions.rb:51:9:51:29 | call to extract! [element :a] : | hash_extensions.rb:58:10:58:10 | x [element :a] : | -| hash_extensions.rb:51:9:51:29 | call to extract! [element :a] : | hash_extensions.rb:58:10:58:10 | x [element :a] : | -| hash_extensions.rb:51:9:51:29 | call to extract! [element :b] : | hash_extensions.rb:59:10:59:10 | x [element :b] : | -| hash_extensions.rb:51:9:51:29 | call to extract! [element :b] : | hash_extensions.rb:59:10:59:10 | x [element :b] : | +| hash_extensions.rb:51:9:51:29 | call to extract! [element :a] : | hash_extensions.rb:51:5:51:5 | x [element :a] : | +| hash_extensions.rb:51:9:51:29 | call to extract! [element :a] : | hash_extensions.rb:51:5:51:5 | x [element :a] : | +| hash_extensions.rb:51:9:51:29 | call to extract! [element :b] : | hash_extensions.rb:51:5:51:5 | x [element :b] : | +| hash_extensions.rb:51:9:51:29 | call to extract! [element :b] : | hash_extensions.rb:51:5:51:5 | x [element :b] : | | hash_extensions.rb:56:10:56:10 | h [element :d] : | hash_extensions.rb:56:10:56:14 | ...[...] | | hash_extensions.rb:56:10:56:10 | h [element :d] : | hash_extensions.rb:56:10:56:14 | ...[...] | | hash_extensions.rb:58:10:58:10 | x [element :a] : | hash_extensions.rb:58:10:58:14 | ...[...] | | 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:67:5:67:10 | values [element 0] : | hash_extensions.rb:68:9:68:14 | values [element 0] : | +| hash_extensions.rb:67:5:67:10 | values [element 0] : | hash_extensions.rb:68:9:68:14 | values [element 0] : | +| hash_extensions.rb:67:5:67:10 | values [element 1] : | hash_extensions.rb:68:9:68:14 | values [element 1] : | +| hash_extensions.rb:67:5:67:10 | values [element 1] : | hash_extensions.rb:68:9:68:14 | values [element 1] : | +| hash_extensions.rb:67:5:67:10 | values [element 2] : | hash_extensions.rb:68:9:68:14 | values [element 2] : | +| hash_extensions.rb:67:5:67:10 | values [element 2] : | hash_extensions.rb:68:9:68:14 | values [element 2] : | +| hash_extensions.rb:67:15:67:25 | call to source : | hash_extensions.rb:67:5:67:10 | values [element 0] : | +| hash_extensions.rb:67:15:67:25 | call to source : | hash_extensions.rb:67:5:67:10 | values [element 0] : | +| hash_extensions.rb:67:28:67:38 | call to source : | hash_extensions.rb:67:5:67:10 | values [element 1] : | +| hash_extensions.rb:67:28:67:38 | call to source : | hash_extensions.rb:67:5:67:10 | values [element 1] : | +| hash_extensions.rb:67:41:67:51 | call to source : | hash_extensions.rb:67:5:67:10 | values [element 2] : | +| hash_extensions.rb:67:41:67:51 | call to source : | hash_extensions.rb:67:5:67:10 | values [element 2] : | +| hash_extensions.rb:68:5:68:5 | h [element] : | hash_extensions.rb:73:10:73:10 | h [element] : | +| hash_extensions.rb:68:5:68:5 | h [element] : | hash_extensions.rb:73:10:73:10 | h [element] : | +| hash_extensions.rb:68:5:68:5 | h [element] : | hash_extensions.rb:74:10:74:10 | h [element] : | +| hash_extensions.rb:68:5:68:5 | h [element] : | hash_extensions.rb:74:10:74:10 | h [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: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 : | @@ -293,32 +431,38 @@ edges | 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:9:71:7 | call to index_by [element] : | hash_extensions.rb:68:5:68:5 | h [element] : | +| hash_extensions.rb:68:9:71:7 | call to index_by [element] : | hash_extensions.rb:68:5:68:5 | 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 | ...[...] | -| 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:80:5:80:10 | values [element 0] : | hash_extensions.rb:81:9:81:14 | values [element 0] : | +| hash_extensions.rb:80:5:80:10 | values [element 0] : | hash_extensions.rb:81:9:81:14 | values [element 0] : | +| hash_extensions.rb:80:5:80:10 | values [element 1] : | hash_extensions.rb:81:9:81:14 | values [element 1] : | +| hash_extensions.rb:80:5:80:10 | values [element 1] : | hash_extensions.rb:81:9:81:14 | values [element 1] : | +| hash_extensions.rb:80:5:80:10 | values [element 2] : | hash_extensions.rb:81:9:81:14 | values [element 2] : | +| hash_extensions.rb:80:5:80:10 | values [element 2] : | hash_extensions.rb:81:9:81:14 | values [element 2] : | +| hash_extensions.rb:80:15:80:25 | call to source : | hash_extensions.rb:80:5:80:10 | values [element 0] : | +| hash_extensions.rb:80:15:80:25 | call to source : | hash_extensions.rb:80:5:80:10 | values [element 0] : | +| hash_extensions.rb:80:28:80:38 | call to source : | hash_extensions.rb:80:5:80:10 | values [element 1] : | +| hash_extensions.rb:80:28:80:38 | call to source : | hash_extensions.rb:80:5:80:10 | values [element 1] : | +| hash_extensions.rb:80:41:80:51 | call to source : | hash_extensions.rb:80:5:80:10 | values [element 2] : | +| hash_extensions.rb:80:41:80:51 | call to source : | hash_extensions.rb:80:5:80:10 | values [element 2] : | +| hash_extensions.rb:81:5:81:5 | h [element] : | hash_extensions.rb:86:10:86:10 | h [element] : | +| hash_extensions.rb:81:5:81:5 | h [element] : | hash_extensions.rb:86:10:86:10 | h [element] : | +| hash_extensions.rb:81:5:81:5 | h [element] : | hash_extensions.rb:87:10:87:10 | h [element] : | +| hash_extensions.rb:81:5:81:5 | h [element] : | hash_extensions.rb:87:10:87:10 | h [element] : | | 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:9:84:7 | call to index_with [element] : | hash_extensions.rb:81:5:81:5 | h [element] : | +| hash_extensions.rb:81:9:84:7 | call to index_with [element] : | hash_extensions.rb:81:5:81:5 | 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] : | @@ -327,28 +471,34 @@ edges | 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:5:89:5 | j [element] : | hash_extensions.rb:91:10:91:10 | j [element] : | +| hash_extensions.rb:89:5:89:5 | j [element] : | hash_extensions.rb:91:10:91:10 | j [element] : | +| hash_extensions.rb:89:5:89:5 | j [element] : | hash_extensions.rb:92:10:92:10 | j [element] : | +| hash_extensions.rb:89:5:89:5 | j [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:89:5:89:5 | j [element] : | +| hash_extensions.rb:89:9:89:38 | call to index_with [element] : | hash_extensions.rb:89:5:89:5 | 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 | ...[...] | -| 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:98:5:98:10 | values [element 0, element :id] : | hash_extensions.rb:99:10:99:15 | values [element 0, element :id] : | +| hash_extensions.rb:98:5:98:10 | values [element 0, element :id] : | hash_extensions.rb:99:10:99:15 | values [element 0, element :id] : | +| hash_extensions.rb:98:5:98:10 | values [element 0, element :id] : | hash_extensions.rb:101:10:101:15 | values [element 0, element :id] : | +| hash_extensions.rb:98:5:98:10 | values [element 0, element :id] : | hash_extensions.rb:101:10:101:15 | values [element 0, element :id] : | +| hash_extensions.rb:98:5:98:10 | values [element 0, element :id] : | hash_extensions.rb:104:10:104:15 | values [element 0, element :id] : | +| hash_extensions.rb:98:5:98:10 | values [element 0, element :id] : | hash_extensions.rb:104:10:104:15 | values [element 0, element :id] : | +| hash_extensions.rb:98:5:98:10 | values [element 0, element :name] : | hash_extensions.rb:100:10:100:15 | values [element 0, element :name] : | +| hash_extensions.rb:98:5:98:10 | values [element 0, element :name] : | hash_extensions.rb:100:10:100:15 | values [element 0, element :name] : | +| hash_extensions.rb:98:5:98:10 | values [element 0, element :name] : | hash_extensions.rb:102:10:102:15 | values [element 0, element :name] : | +| hash_extensions.rb:98:5:98:10 | values [element 0, element :name] : | hash_extensions.rb:102:10:102:15 | values [element 0, element :name] : | +| hash_extensions.rb:98:5:98:10 | values [element 0, element :name] : | hash_extensions.rb:103:10:103:15 | values [element 0, element :name] : | +| hash_extensions.rb:98:5:98:10 | values [element 0, element :name] : | hash_extensions.rb:103:10:103:15 | values [element 0, element :name] : | +| hash_extensions.rb:98:21:98:31 | call to source : | hash_extensions.rb:98:5:98:10 | values [element 0, element :id] : | +| hash_extensions.rb:98:21:98:31 | call to source : | hash_extensions.rb:98:5:98:10 | values [element 0, element :id] : | +| hash_extensions.rb:98:40:98:54 | call to source : | hash_extensions.rb:98:5:98:10 | values [element 0, element :name] : | +| hash_extensions.rb:98:40:98:54 | call to source : | hash_extensions.rb:98:5:98:10 | 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 | @@ -369,26 +519,34 @@ 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:110:5:110:10 | values [element 0, element :id] : | hash_extensions.rb:112:10:112:15 | values [element 0, element :id] : | +| hash_extensions.rb:110:5:110:10 | values [element 0, element :id] : | hash_extensions.rb:112:10:112:15 | values [element 0, element :id] : | +| hash_extensions.rb:110:5:110:10 | values [element 0, element :id] : | hash_extensions.rb:115:10:115:15 | values [element 0, element :id] : | +| hash_extensions.rb:110:5:110:10 | values [element 0, element :id] : | hash_extensions.rb:115:10:115:15 | values [element 0, element :id] : | +| hash_extensions.rb:110:5:110:10 | values [element 0, element :name] : | hash_extensions.rb:111:10:111:15 | values [element 0, element :name] : | +| hash_extensions.rb:110:5:110:10 | values [element 0, element :name] : | hash_extensions.rb:111:10:111:15 | values [element 0, element :name] : | +| hash_extensions.rb:110:5:110:10 | values [element 0, element :name] : | hash_extensions.rb:113:10:113:15 | values [element 0, element :name] : | +| hash_extensions.rb:110:5:110:10 | values [element 0, element :name] : | hash_extensions.rb:113:10:113:15 | values [element 0, element :name] : | +| hash_extensions.rb:110:5:110:10 | values [element 0, element :name] : | hash_extensions.rb:114:10:114:15 | values [element 0, element :name] : | +| hash_extensions.rb:110:5:110:10 | values [element 0, element :name] : | hash_extensions.rb:114:10:114:15 | values [element 0, element :name] : | +| hash_extensions.rb:110:5:110:10 | values [element 1, element :id] : | hash_extensions.rb:112:10:112:15 | values [element 1, element :id] : | +| hash_extensions.rb:110:5:110:10 | values [element 1, element :id] : | hash_extensions.rb:112:10:112:15 | values [element 1, element :id] : | +| hash_extensions.rb:110:5:110:10 | values [element 1, element :id] : | hash_extensions.rb:115:10:115:15 | values [element 1, element :id] : | +| hash_extensions.rb:110:5:110:10 | values [element 1, element :id] : | hash_extensions.rb:115:10:115:15 | values [element 1, element :id] : | +| hash_extensions.rb:110:5:110:10 | values [element 1, element :name] : | hash_extensions.rb:111:10:111:15 | values [element 1, element :name] : | +| hash_extensions.rb:110:5:110:10 | values [element 1, element :name] : | hash_extensions.rb:111:10:111:15 | values [element 1, element :name] : | +| hash_extensions.rb:110:5:110:10 | values [element 1, element :name] : | hash_extensions.rb:113:10:113:15 | values [element 1, element :name] : | +| hash_extensions.rb:110:5:110:10 | values [element 1, element :name] : | hash_extensions.rb:113:10:113:15 | values [element 1, element :name] : | +| hash_extensions.rb:110:5:110:10 | values [element 1, element :name] : | hash_extensions.rb:114:10:114:15 | values [element 1, element :name] : | +| hash_extensions.rb:110:5:110:10 | values [element 1, element :name] : | hash_extensions.rb:114:10:114:15 | values [element 1, element :name] : | +| hash_extensions.rb:110:21:110:31 | call to source : | hash_extensions.rb:110:5:110:10 | values [element 0, element :id] : | +| hash_extensions.rb:110:21:110:31 | call to source : | hash_extensions.rb:110:5:110:10 | values [element 0, element :id] : | +| hash_extensions.rb:110:40:110:54 | call to source : | hash_extensions.rb:110:5:110:10 | values [element 0, element :name] : | +| hash_extensions.rb:110:40:110:54 | call to source : | hash_extensions.rb:110:5:110:10 | values [element 0, element :name] : | +| hash_extensions.rb:110:65:110:75 | call to source : | hash_extensions.rb:110:5:110:10 | values [element 1, element :id] : | +| hash_extensions.rb:110:65:110:75 | call to source : | hash_extensions.rb:110:5:110:10 | values [element 1, element :id] : | +| hash_extensions.rb:110:84:110:99 | call to source : | hash_extensions.rb:110:5:110:10 | values [element 1, element :name] : | +| hash_extensions.rb:110:84:110:99 | call to source : | hash_extensions.rb:110:5:110:10 | 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] : | @@ -427,119 +585,161 @@ 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:122:5:122:10 | single [element 0] : | hash_extensions.rb:125:10:125:15 | single [element 0] : | +| hash_extensions.rb:122:5:122:10 | single [element 0] : | hash_extensions.rb:125:10:125:15 | single [element 0] : | +| hash_extensions.rb:122:15:122:25 | call to source : | hash_extensions.rb:122:5:122:10 | single [element 0] : | +| hash_extensions.rb:122:15:122:25 | call to source : | hash_extensions.rb:122:5:122:10 | single [element 0] : | +| hash_extensions.rb:123:5:123:9 | multi [element 0] : | hash_extensions.rb:126:10:126:14 | multi [element 0] : | +| hash_extensions.rb:123:5:123:9 | multi [element 0] : | hash_extensions.rb:126:10:126:14 | multi [element 0] : | +| hash_extensions.rb:123:14:123:24 | call to source : | hash_extensions.rb:123:5:123:9 | multi [element 0] : | +| hash_extensions.rb:123:14:123:24 | call to source : | hash_extensions.rb:123:5:123:9 | 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:5:10:5 | x : | semmle.label | x : | | 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 : | | active_support.rb:11:10:11:19 | call to at | semmle.label | call to at | +| active_support.rb:15:5:15:5 | x : | semmle.label | x : | | active_support.rb:15:9:15:18 | call to source : | semmle.label | call to source : | | active_support.rb:16:10:16:10 | x : | semmle.label | x : | | active_support.rb:16:10:16:19 | call to camelize | semmle.label | call to camelize | +| active_support.rb:20:5:20:5 | x : | semmle.label | x : | | active_support.rb:20:9:20:18 | call to source : | semmle.label | call to source : | | active_support.rb:21:10:21:10 | x : | semmle.label | x : | | active_support.rb:21:10:21:20 | call to camelcase | semmle.label | call to camelcase | +| active_support.rb:25:5:25:5 | x : | semmle.label | x : | | active_support.rb:25:9:25:18 | call to source : | semmle.label | call to source : | | active_support.rb:26:10:26:10 | x : | semmle.label | x : | | active_support.rb:26:10:26:19 | call to classify | semmle.label | call to classify | +| active_support.rb:30:5:30:5 | x : | semmle.label | x : | | active_support.rb:30:9:30:18 | call to source : | semmle.label | call to source : | | active_support.rb:31:10:31:10 | x : | semmle.label | x : | | active_support.rb:31:10:31:20 | call to dasherize | semmle.label | call to dasherize | +| active_support.rb:35:5:35:5 | x : | semmle.label | x : | | active_support.rb:35:9:35:18 | call to source : | semmle.label | call to source : | | active_support.rb:36:10:36:10 | x : | semmle.label | x : | | active_support.rb:36:10:36:24 | call to deconstantize | semmle.label | call to deconstantize | +| active_support.rb:40:5:40:5 | x : | semmle.label | x : | | active_support.rb:40:9:40:18 | call to source : | semmle.label | call to source : | | active_support.rb:41:10:41:10 | x : | semmle.label | x : | | active_support.rb:41:10:41:21 | call to demodulize | semmle.label | call to demodulize | +| active_support.rb:45:5:45:5 | x : | semmle.label | x : | | active_support.rb:45:9:45:18 | call to source : | semmle.label | call to source : | | active_support.rb:46:10:46:10 | x : | semmle.label | x : | | active_support.rb:46:10:46:19 | call to first | semmle.label | call to first | +| active_support.rb:50:5:50:5 | x : | semmle.label | x : | | active_support.rb:50:9:50:18 | call to source : | semmle.label | call to source : | | active_support.rb:51:10:51:10 | x : | semmle.label | x : | | active_support.rb:51:10:51:22 | call to foreign_key | semmle.label | call to foreign_key | +| active_support.rb:55:5:55:5 | x : | semmle.label | x : | | active_support.rb:55:9:55:18 | call to source : | semmle.label | call to source : | | active_support.rb:56:10:56:10 | x : | semmle.label | x : | | active_support.rb:56:10:56:18 | call to from | semmle.label | call to from | +| active_support.rb:60:5:60:5 | x : | semmle.label | x : | | active_support.rb:60:9:60:18 | call to source : | semmle.label | call to source : | | active_support.rb:61:10:61:10 | x : | semmle.label | x : | | active_support.rb:61:10:61:20 | call to html_safe | semmle.label | call to html_safe | +| active_support.rb:65:5:65:5 | x : | semmle.label | x : | | active_support.rb:65:9:65:18 | call to source : | semmle.label | call to source : | | active_support.rb:66:10:66:10 | x : | semmle.label | x : | | active_support.rb:66:10:66:19 | call to humanize | semmle.label | call to humanize | +| active_support.rb:70:5:70:5 | x : | semmle.label | x : | | active_support.rb:70:9:70:18 | call to source : | semmle.label | call to source : | | active_support.rb:71:10:71:10 | x : | semmle.label | x : | | active_support.rb:71:10:71:20 | call to indent | semmle.label | call to indent | +| active_support.rb:75:5:75:5 | x : | semmle.label | x : | | active_support.rb:75:9:75:18 | call to source : | semmle.label | call to source : | | active_support.rb:76:10:76:10 | x : | semmle.label | x : | | active_support.rb:76:10:76:21 | call to indent! | semmle.label | call to indent! | +| active_support.rb:80:5:80:5 | x : | semmle.label | x : | | active_support.rb:80:9:80:18 | call to source : | semmle.label | call to source : | | active_support.rb:81:10:81:10 | x : | semmle.label | x : | | active_support.rb:81:10:81:18 | call to inquiry | semmle.label | call to inquiry | +| active_support.rb:85:5:85:5 | x : | semmle.label | x : | | active_support.rb:85:9:85:18 | call to source : | semmle.label | call to source : | | active_support.rb:86:10:86:10 | x : | semmle.label | x : | | active_support.rb:86:10:86:18 | call to last | semmle.label | call to last | +| active_support.rb:90:5:90:5 | x : | semmle.label | x : | | active_support.rb:90:9:90:18 | call to source : | semmle.label | call to source : | | active_support.rb:91:10:91:10 | x : | semmle.label | x : | | active_support.rb:91:10:91:19 | call to mb_chars | semmle.label | call to mb_chars | +| active_support.rb:95:5:95:5 | x : | semmle.label | x : | | active_support.rb:95:9:95:18 | call to source : | semmle.label | call to source : | | active_support.rb:96:10:96:10 | x : | semmle.label | x : | | active_support.rb:96:10:96:23 | call to parameterize | semmle.label | call to parameterize | +| active_support.rb:100:5:100:5 | x : | semmle.label | x : | | active_support.rb:100:9:100:18 | call to source : | semmle.label | call to source : | | active_support.rb:101:10:101:10 | x : | semmle.label | x : | | active_support.rb:101:10:101:20 | call to pluralize | semmle.label | call to pluralize | +| active_support.rb:105:5:105:5 | x : | semmle.label | x : | | active_support.rb:105:9:105:18 | call to source : | semmle.label | call to source : | | active_support.rb:106:10:106:10 | x : | semmle.label | x : | | active_support.rb:106:10:106:24 | call to remove | semmle.label | call to remove | +| active_support.rb:110:5:110:5 | x : | semmle.label | x : | | active_support.rb:110:9:110:18 | call to source : | semmle.label | call to source : | | active_support.rb:111:10:111:10 | x : | semmle.label | x : | | active_support.rb:111:10:111:25 | call to remove! | semmle.label | call to remove! | +| active_support.rb:115:5:115:5 | x : | semmle.label | x : | | active_support.rb:115:9:115:18 | call to source : | semmle.label | call to source : | | active_support.rb:116:10:116:10 | x : | semmle.label | x : | | active_support.rb:116:10:116:22 | call to singularize | semmle.label | call to singularize | +| active_support.rb:120:5:120:5 | x : | semmle.label | x : | | active_support.rb:120:9:120:18 | call to source : | semmle.label | call to source : | | active_support.rb:121:10:121:10 | x : | semmle.label | x : | | active_support.rb:121:10:121:17 | call to squish | semmle.label | call to squish | +| active_support.rb:125:5:125:5 | x : | semmle.label | x : | | active_support.rb:125:9:125:18 | call to source : | semmle.label | call to source : | | active_support.rb:126:10:126:10 | x : | semmle.label | x : | | active_support.rb:126:10:126:18 | call to squish! | semmle.label | call to squish! | +| active_support.rb:130:5:130:5 | x : | semmle.label | x : | | active_support.rb:130:9:130:18 | call to source : | semmle.label | call to source : | | active_support.rb:131:10:131:10 | x : | semmle.label | x : | | active_support.rb:131:10:131:24 | call to strip_heredoc | semmle.label | call to strip_heredoc | +| active_support.rb:135:5:135:5 | x : | semmle.label | x : | | active_support.rb:135:9:135:18 | call to source : | semmle.label | call to source : | | active_support.rb:136:10:136:10 | x : | semmle.label | x : | | active_support.rb:136:10:136:19 | call to tableize | semmle.label | call to tableize | +| active_support.rb:140:5:140:5 | x : | semmle.label | x : | | active_support.rb:140:9:140:18 | call to source : | semmle.label | call to source : | | active_support.rb:141:10:141:10 | x : | semmle.label | x : | | active_support.rb:141:10:141:20 | call to titlecase | semmle.label | call to titlecase | +| active_support.rb:145:5:145:5 | x : | semmle.label | x : | | active_support.rb:145:9:145:18 | call to source : | semmle.label | call to source : | | active_support.rb:146:10:146:10 | x : | semmle.label | x : | | active_support.rb:146:10:146:19 | call to titleize | semmle.label | call to titleize | +| active_support.rb:150:5:150:5 | x : | semmle.label | x : | | active_support.rb:150:9:150:18 | call to source : | semmle.label | call to source : | | active_support.rb:151:10:151:10 | x : | semmle.label | x : | | active_support.rb:151:10:151:16 | call to to | semmle.label | call to to | +| active_support.rb:155:5:155:5 | x : | semmle.label | x : | | active_support.rb:155:9:155:18 | call to source : | semmle.label | call to source : | | active_support.rb:156:10:156:10 | x : | semmle.label | x : | | active_support.rb:156:10:156:22 | call to truncate | semmle.label | call to truncate | +| active_support.rb:160:5:160:5 | x : | semmle.label | x : | | active_support.rb:160:9:160:18 | call to source : | semmle.label | call to source : | | active_support.rb:161:10:161:10 | x : | semmle.label | x : | | active_support.rb:161:10:161:28 | call to truncate_bytes | semmle.label | call to truncate_bytes | +| active_support.rb:165:5:165:5 | x : | semmle.label | x : | | active_support.rb:165:9:165:18 | call to source : | semmle.label | call to source : | | active_support.rb:166:10:166:10 | x : | semmle.label | x : | | active_support.rb:166:10:166:28 | call to truncate_words | semmle.label | call to truncate_words | +| active_support.rb:170:5:170:5 | x : | semmle.label | x : | | active_support.rb:170:9:170:18 | call to source : | semmle.label | call to source : | | active_support.rb:171:10:171:10 | x : | semmle.label | x : | | active_support.rb:171:10:171:21 | call to underscore | semmle.label | call to underscore | +| active_support.rb:175:5:175:5 | x : | semmle.label | x : | | active_support.rb:175:9:175:18 | call to source : | semmle.label | call to source : | | active_support.rb:176:10:176:10 | x : | semmle.label | x : | | active_support.rb:176:10:176:23 | call to upcase_first | semmle.label | call to upcase_first | +| active_support.rb:180:5:180:5 | x [element 0] : | semmle.label | x [element 0] : | +| active_support.rb:180:5:180:5 | x [element 0] : | semmle.label | x [element 0] : | | active_support.rb:180:10:180:17 | call to source : | semmle.label | call to source : | | active_support.rb:180:10:180:17 | call to source : | semmle.label | call to source : | +| active_support.rb:181:5:181:5 | y [element] : | semmle.label | y [element] : | +| active_support.rb:181:5:181:5 | y [element] : | semmle.label | y [element] : | | active_support.rb:181:9:181:9 | x [element 0] : | semmle.label | x [element 0] : | | active_support.rb:181:9:181:9 | x [element 0] : | semmle.label | x [element 0] : | | active_support.rb:181:9:181:23 | call to compact_blank [element] : | semmle.label | call to compact_blank [element] : | @@ -548,8 +748,12 @@ nodes | active_support.rb:182:10:182:10 | y [element] : | semmle.label | y [element] : | | active_support.rb:182:10:182:13 | ...[...] | semmle.label | ...[...] | | active_support.rb:182:10:182:13 | ...[...] | semmle.label | ...[...] | +| active_support.rb:186:5:186:5 | x [element 0] : | semmle.label | x [element 0] : | +| active_support.rb:186:5:186:5 | x [element 0] : | semmle.label | x [element 0] : | | active_support.rb:186:10:186:18 | call to source : | semmle.label | call to source : | | active_support.rb:186:10:186:18 | call to source : | semmle.label | call to source : | +| active_support.rb:187:5:187:5 | y [element] : | semmle.label | y [element] : | +| active_support.rb:187:5:187:5 | y [element] : | semmle.label | y [element] : | | active_support.rb:187:9:187:9 | x [element 0] : | semmle.label | x [element 0] : | | active_support.rb:187:9:187:9 | x [element 0] : | semmle.label | x [element 0] : | | active_support.rb:187:9:187:21 | call to excluding [element] : | semmle.label | call to excluding [element] : | @@ -558,8 +762,12 @@ nodes | active_support.rb:188:10:188:10 | y [element] : | semmle.label | y [element] : | | active_support.rb:188:10:188:13 | ...[...] | semmle.label | ...[...] | | active_support.rb:188:10:188:13 | ...[...] | semmle.label | ...[...] | +| active_support.rb:192:5:192:5 | x [element 0] : | semmle.label | x [element 0] : | +| active_support.rb:192:5:192:5 | x [element 0] : | semmle.label | x [element 0] : | | active_support.rb:192:10:192:18 | call to source : | semmle.label | call to source : | | active_support.rb:192:10:192:18 | call to source : | semmle.label | call to source : | +| active_support.rb:193:5:193:5 | y [element] : | semmle.label | y [element] : | +| active_support.rb:193:5:193:5 | y [element] : | semmle.label | y [element] : | | active_support.rb:193:9:193:9 | x [element 0] : | semmle.label | x [element 0] : | | active_support.rb:193:9:193:9 | x [element 0] : | semmle.label | x [element 0] : | | active_support.rb:193:9:193:19 | call to without [element] : | semmle.label | call to without [element] : | @@ -568,8 +776,12 @@ nodes | active_support.rb:194:10:194:10 | y [element] : | semmle.label | y [element] : | | active_support.rb:194:10:194:13 | ...[...] | semmle.label | ...[...] | | active_support.rb:194:10:194:13 | ...[...] | semmle.label | ...[...] | +| active_support.rb:198:5:198:5 | x [element 0] : | semmle.label | x [element 0] : | +| active_support.rb:198:5:198:5 | x [element 0] : | semmle.label | x [element 0] : | | active_support.rb:198:10:198:18 | call to source : | semmle.label | call to source : | | active_support.rb:198:10:198:18 | call to source : | semmle.label | call to source : | +| active_support.rb:199:5:199:5 | y [element] : | semmle.label | y [element] : | +| active_support.rb:199:5:199:5 | y [element] : | semmle.label | y [element] : | | active_support.rb:199:9:199:9 | x [element 0] : | semmle.label | x [element 0] : | | active_support.rb:199:9:199:9 | x [element 0] : | semmle.label | x [element 0] : | | active_support.rb:199:9:199:37 | call to in_order_of [element] : | semmle.label | call to in_order_of [element] : | @@ -578,8 +790,14 @@ nodes | active_support.rb:200:10:200:10 | y [element] : | semmle.label | y [element] : | | active_support.rb:200:10:200:13 | ...[...] | semmle.label | ...[...] | | active_support.rb:200:10:200:13 | ...[...] | semmle.label | ...[...] | +| active_support.rb:204:5:204:5 | a [element 0] : | semmle.label | a [element 0] : | +| active_support.rb:204:5:204:5 | a [element 0] : | semmle.label | a [element 0] : | | active_support.rb:204:10:204:18 | call to source : | semmle.label | call to source : | | active_support.rb:204:10:204:18 | call to source : | semmle.label | call to source : | +| active_support.rb:205:5:205:5 | b [element 0] : | semmle.label | b [element 0] : | +| active_support.rb:205:5:205:5 | b [element 0] : | semmle.label | b [element 0] : | +| active_support.rb:205:5:205:5 | b [element] : | semmle.label | b [element] : | +| active_support.rb:205:5:205:5 | b [element] : | semmle.label | b [element] : | | active_support.rb:205:9:205:9 | a [element 0] : | semmle.label | a [element 0] : | | active_support.rb:205:9:205:9 | a [element 0] : | semmle.label | a [element 0] : | | active_support.rb:205:9:205:41 | call to including [element 0] : | semmle.label | call to including [element 0] : | @@ -612,99 +830,141 @@ nodes | active_support.rb:211:10:211:10 | b [element] : | semmle.label | b [element] : | | active_support.rb:211:10:211:13 | ...[...] | semmle.label | ...[...] | | active_support.rb:211:10:211:13 | ...[...] | semmle.label | ...[...] | +| active_support.rb:215:3:215:3 | x : | semmle.label | x : | | active_support.rb:215:7:215:16 | call to source : | semmle.label | call to source : | +| active_support.rb:216:3:216:3 | y : | semmle.label | y : | | active_support.rb:216:7:216:35 | call to new : | semmle.label | call to new : | | active_support.rb:216:34:216:34 | x : | semmle.label | x : | | active_support.rb:217:8:217:8 | y | semmle.label | y | +| active_support.rb:222:3:222:3 | b : | semmle.label | b : | | active_support.rb:222:7:222:16 | call to source : | semmle.label | call to source : | +| active_support.rb:223:3:223:3 | y : | semmle.label | y : | | active_support.rb:223:7:223:22 | call to safe_concat : | semmle.label | call to safe_concat : | | active_support.rb:223:21:223:21 | b : | semmle.label | b : | | active_support.rb:224:8:224:8 | y | semmle.label | y | +| active_support.rb:229:3:229:3 | b : | semmle.label | b : | | active_support.rb:229:7:229:16 | call to source : | semmle.label | call to source : | | active_support.rb:230:3:230:3 | [post] x : | semmle.label | [post] x : | | active_support.rb:230:17:230:17 | b : | semmle.label | b : | | active_support.rb:231:8:231:8 | x | semmle.label | x | +| active_support.rb:235:3:235:3 | a : | semmle.label | a : | | active_support.rb:235:7:235:16 | call to source : | semmle.label | call to source : | +| active_support.rb:237:3:237:3 | x : | semmle.label | x : | | active_support.rb:237:7:237:35 | call to new : | semmle.label | call to new : | | active_support.rb:237:34:237:34 | a : | semmle.label | a : | +| active_support.rb:238:3:238:3 | y : | semmle.label | y : | | active_support.rb:238:7:238:7 | x : | semmle.label | x : | | active_support.rb:238:7:238:17 | call to concat : | semmle.label | call to concat : | | active_support.rb:239:8:239:8 | y | semmle.label | y | +| active_support.rb:243:3:243:3 | a : | semmle.label | a : | | active_support.rb:243:7:243:16 | call to source : | semmle.label | call to source : | +| active_support.rb:245:3:245:3 | x : | semmle.label | x : | | active_support.rb:245:7:245:35 | call to new : | semmle.label | call to new : | | active_support.rb:245:34:245:34 | a : | semmle.label | a : | +| active_support.rb:246:3:246:3 | y : | semmle.label | y : | | active_support.rb:246:7:246:7 | x : | semmle.label | x : | | active_support.rb:246:7:246:20 | call to insert : | semmle.label | call to insert : | | active_support.rb:247:8:247:8 | y | semmle.label | y | +| active_support.rb:251:3:251:3 | a : | semmle.label | a : | | active_support.rb:251:7:251:16 | call to source : | semmle.label | call to source : | +| active_support.rb:253:3:253:3 | x : | semmle.label | x : | | active_support.rb:253:7:253:35 | call to new : | semmle.label | call to new : | | active_support.rb:253:34:253:34 | a : | semmle.label | a : | +| active_support.rb:254:3:254:3 | y : | semmle.label | y : | | active_support.rb:254:7:254:7 | x : | semmle.label | x : | | active_support.rb:254:7:254:18 | call to prepend : | semmle.label | call to prepend : | | active_support.rb:255:8:255:8 | y | semmle.label | y | +| active_support.rb:259:3:259:3 | a : | semmle.label | a : | | active_support.rb:259:7:259:16 | call to source : | semmle.label | call to source : | +| active_support.rb:260:3:260:3 | x : | semmle.label | x : | | active_support.rb:260:7:260:35 | call to new : | semmle.label | call to new : | | active_support.rb:260:34:260:34 | a : | semmle.label | a : | +| active_support.rb:261:3:261:3 | y : | semmle.label | y : | | active_support.rb:261:7:261:7 | x : | semmle.label | x : | | active_support.rb:261:7:261:12 | call to to_s : | semmle.label | call to to_s : | | active_support.rb:262:8:262:8 | y | semmle.label | y | +| active_support.rb:266:3:266:3 | a : | semmle.label | a : | | active_support.rb:266:7:266:16 | call to source : | semmle.label | call to source : | +| active_support.rb:267:3:267:3 | x : | semmle.label | x : | | active_support.rb:267:7:267:35 | call to new : | semmle.label | call to new : | | active_support.rb:267:34:267:34 | a : | semmle.label | a : | +| active_support.rb:268:3:268:3 | y : | semmle.label | y : | | active_support.rb:268:7:268:7 | x : | semmle.label | x : | | active_support.rb:268:7:268:16 | call to to_param : | semmle.label | call to to_param : | | active_support.rb:269:8:269:8 | y | semmle.label | y | +| active_support.rb:273:3:273:3 | a : | semmle.label | a : | | active_support.rb:273:7:273:16 | call to source : | semmle.label | call to source : | +| active_support.rb:274:3:274:3 | x : | semmle.label | x : | | active_support.rb:274:7:274:21 | call to new : | semmle.label | call to new : | | active_support.rb:274:20:274:20 | a : | semmle.label | a : | +| active_support.rb:275:3:275:3 | y : | semmle.label | y : | | active_support.rb:275:7:275:7 | x : | semmle.label | x : | | active_support.rb:275:7:275:17 | call to existence : | semmle.label | call to existence : | | active_support.rb:276:8:276:8 | y | semmle.label | y | +| active_support.rb:277:3:277:3 | z : | semmle.label | z : | | active_support.rb:277:7:277:7 | y : | semmle.label | y : | | active_support.rb:277:7:277:17 | call to existence : | semmle.label | call to existence : | | active_support.rb:278:8:278:8 | z | semmle.label | z | +| active_support.rb:282:3:282:3 | x : | semmle.label | x : | +| active_support.rb:282:3:282:3 | x : | semmle.label | x : | | active_support.rb:282:7:282:16 | call to source : | semmle.label | call to source : | | active_support.rb:282:7:282:16 | call to source : | semmle.label | call to source : | | active_support.rb:283:8:283:8 | x : | semmle.label | x : | | active_support.rb:283:8:283:8 | x : | semmle.label | x : | | active_support.rb:283:8:283:17 | call to presence | semmle.label | call to presence | | active_support.rb:283:8:283:17 | call to presence | semmle.label | call to presence | +| active_support.rb:285:3:285:3 | y : | semmle.label | y : | +| active_support.rb:285:3:285:3 | y : | semmle.label | y : | | active_support.rb:285:7:285:16 | call to source : | semmle.label | call to source : | | active_support.rb:285:7:285:16 | call to source : | semmle.label | call to source : | | active_support.rb:286:8:286:8 | y : | semmle.label | y : | | active_support.rb:286:8:286:8 | y : | semmle.label | y : | | active_support.rb:286:8:286:17 | call to presence | semmle.label | call to presence | | active_support.rb:286:8:286:17 | call to presence | semmle.label | call to presence | +| active_support.rb:290:3:290:3 | x : | semmle.label | x : | +| active_support.rb:290:3:290:3 | x : | semmle.label | x : | | active_support.rb:290:7:290:16 | call to source : | semmle.label | call to source : | | active_support.rb:290:7:290:16 | call to source : | semmle.label | call to source : | | active_support.rb:291:8:291:8 | x : | semmle.label | x : | | 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:3:303:3 | a : | semmle.label | a : | | active_support.rb:303:7:303:16 | call to source : | semmle.label | call to source : | +| active_support.rb:304:3:304:3 | b : | semmle.label | b : | | 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:5:309:5 | x : | semmle.label | x : | | 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:5:314:5 | 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:5:319:5 | 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:5:324:5 | 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 : | +| active_support.rb:329:5:329:5 | x : | semmle.label | x : | | active_support.rb:329:9:329:18 | call to source : | semmle.label | call to source : | +| active_support.rb:330:5:330:5 | y [element 0] : | semmle.label | y [element 0] : | | 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:5:2:5 | h [element :a] : | semmle.label | h [element :a] : | +| hash_extensions.rb:2:5:2:5 | h [element :a] : | semmle.label | h [element :a] : | | 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:5:3:5 | x [element] : | semmle.label | x [element] : | +| hash_extensions.rb:3:5:3:5 | x [element] : | semmle.label | x [element] : | | hash_extensions.rb:3:9:3:9 | h [element :a] : | semmle.label | h [element :a] : | | hash_extensions.rb:3:9:3:9 | h [element :a] : | semmle.label | h [element :a] : | | hash_extensions.rb:3:9:3:24 | call to stringify_keys [element] : | semmle.label | call to stringify_keys [element] : | @@ -713,8 +973,12 @@ nodes | hash_extensions.rb:4:10:4:10 | x [element] : | semmle.label | x [element] : | | hash_extensions.rb:4:10:4:14 | ...[...] | semmle.label | ...[...] | | hash_extensions.rb:4:10:4:14 | ...[...] | semmle.label | ...[...] | +| hash_extensions.rb:10:5:10:5 | h [element :a] : | semmle.label | h [element :a] : | +| hash_extensions.rb:10:5:10:5 | h [element :a] : | semmle.label | h [element :a] : | | hash_extensions.rb:10:14:10:24 | call to source : | semmle.label | call to source : | | hash_extensions.rb:10:14:10:24 | call to source : | semmle.label | call to source : | +| hash_extensions.rb:11:5:11:5 | x [element] : | semmle.label | x [element] : | +| hash_extensions.rb:11:5:11:5 | x [element] : | semmle.label | x [element] : | | hash_extensions.rb:11:9:11:9 | h [element :a] : | semmle.label | h [element :a] : | | hash_extensions.rb:11:9:11:9 | h [element :a] : | semmle.label | h [element :a] : | | hash_extensions.rb:11:9:11:20 | call to to_options [element] : | semmle.label | call to to_options [element] : | @@ -723,8 +987,12 @@ nodes | hash_extensions.rb:12:10:12:10 | x [element] : | semmle.label | x [element] : | | hash_extensions.rb:12:10:12:14 | ...[...] | semmle.label | ...[...] | | hash_extensions.rb:12:10:12:14 | ...[...] | semmle.label | ...[...] | +| hash_extensions.rb:18:5:18:5 | h [element :a] : | semmle.label | h [element :a] : | +| hash_extensions.rb:18:5:18:5 | h [element :a] : | semmle.label | h [element :a] : | | hash_extensions.rb:18:14:18:24 | call to source : | semmle.label | call to source : | | hash_extensions.rb:18:14:18:24 | call to source : | semmle.label | call to source : | +| hash_extensions.rb:19:5:19:5 | x [element] : | semmle.label | x [element] : | +| hash_extensions.rb:19:5:19:5 | x [element] : | semmle.label | x [element] : | | hash_extensions.rb:19:9:19:9 | h [element :a] : | semmle.label | h [element :a] : | | hash_extensions.rb:19:9:19:9 | h [element :a] : | semmle.label | h [element :a] : | | hash_extensions.rb:19:9:19:24 | call to symbolize_keys [element] : | semmle.label | call to symbolize_keys [element] : | @@ -733,8 +1001,12 @@ nodes | hash_extensions.rb:20:10:20:10 | x [element] : | semmle.label | x [element] : | | hash_extensions.rb:20:10:20:14 | ...[...] | semmle.label | ...[...] | | hash_extensions.rb:20:10:20:14 | ...[...] | semmle.label | ...[...] | +| hash_extensions.rb:26:5:26:5 | h [element :a] : | semmle.label | h [element :a] : | +| hash_extensions.rb:26:5:26:5 | h [element :a] : | semmle.label | h [element :a] : | | hash_extensions.rb:26:14:26:24 | call to source : | semmle.label | call to source : | | hash_extensions.rb:26:14:26:24 | call to source : | semmle.label | call to source : | +| hash_extensions.rb:27:5:27:5 | x [element] : | semmle.label | x [element] : | +| hash_extensions.rb:27:5:27:5 | x [element] : | semmle.label | x [element] : | | hash_extensions.rb:27:9:27:9 | h [element :a] : | semmle.label | h [element :a] : | | hash_extensions.rb:27:9:27:9 | h [element :a] : | semmle.label | h [element :a] : | | hash_extensions.rb:27:9:27:29 | call to deep_stringify_keys [element] : | semmle.label | call to deep_stringify_keys [element] : | @@ -743,8 +1015,12 @@ nodes | hash_extensions.rb:28:10:28:10 | x [element] : | semmle.label | x [element] : | | hash_extensions.rb:28:10:28:14 | ...[...] | semmle.label | ...[...] | | hash_extensions.rb:28:10:28:14 | ...[...] | semmle.label | ...[...] | +| hash_extensions.rb:34:5:34:5 | h [element :a] : | semmle.label | h [element :a] : | +| hash_extensions.rb:34:5:34:5 | h [element :a] : | semmle.label | h [element :a] : | | hash_extensions.rb:34:14:34:24 | call to source : | semmle.label | call to source : | | hash_extensions.rb:34:14:34:24 | call to source : | semmle.label | call to source : | +| hash_extensions.rb:35:5:35:5 | x [element] : | semmle.label | x [element] : | +| hash_extensions.rb:35:5:35:5 | x [element] : | semmle.label | x [element] : | | hash_extensions.rb:35:9:35:9 | h [element :a] : | semmle.label | h [element :a] : | | hash_extensions.rb:35:9:35:9 | h [element :a] : | semmle.label | h [element :a] : | | hash_extensions.rb:35:9:35:29 | call to deep_symbolize_keys [element] : | semmle.label | call to deep_symbolize_keys [element] : | @@ -753,8 +1029,12 @@ nodes | hash_extensions.rb:36:10:36:10 | x [element] : | semmle.label | x [element] : | | hash_extensions.rb:36:10:36:14 | ...[...] | semmle.label | ...[...] | | hash_extensions.rb:36:10:36:14 | ...[...] | semmle.label | ...[...] | +| hash_extensions.rb:42:5:42:5 | h [element :a] : | semmle.label | h [element :a] : | +| hash_extensions.rb:42:5:42:5 | h [element :a] : | semmle.label | h [element :a] : | | hash_extensions.rb:42:14:42:24 | call to source : | semmle.label | call to source : | | hash_extensions.rb:42:14:42:24 | call to source : | semmle.label | call to source : | +| hash_extensions.rb:43:5:43:5 | x [element] : | semmle.label | x [element] : | +| hash_extensions.rb:43:5:43:5 | x [element] : | semmle.label | x [element] : | | hash_extensions.rb:43:9:43:9 | h [element :a] : | semmle.label | h [element :a] : | | hash_extensions.rb:43:9:43:9 | h [element :a] : | semmle.label | h [element :a] : | | hash_extensions.rb:43:9:43:33 | call to with_indifferent_access [element] : | semmle.label | call to with_indifferent_access [element] : | @@ -763,12 +1043,22 @@ nodes | hash_extensions.rb:44:10:44:10 | x [element] : | semmle.label | x [element] : | | hash_extensions.rb:44:10:44:14 | ...[...] | semmle.label | ...[...] | | hash_extensions.rb:44:10:44:14 | ...[...] | semmle.label | ...[...] | +| hash_extensions.rb:50:5:50:5 | h [element :a] : | semmle.label | h [element :a] : | +| hash_extensions.rb:50:5:50:5 | h [element :a] : | semmle.label | h [element :a] : | +| hash_extensions.rb:50:5:50:5 | h [element :b] : | semmle.label | h [element :b] : | +| hash_extensions.rb:50:5:50:5 | h [element :b] : | semmle.label | h [element :b] : | +| hash_extensions.rb:50:5:50:5 | h [element :d] : | semmle.label | h [element :d] : | +| hash_extensions.rb:50:5:50:5 | h [element :d] : | semmle.label | h [element :d] : | | hash_extensions.rb:50:14:50:23 | call to taint : | semmle.label | call to taint : | | hash_extensions.rb:50:14:50:23 | call to taint : | semmle.label | call to taint : | | hash_extensions.rb:50:29:50:38 | call to taint : | semmle.label | call to taint : | | hash_extensions.rb:50:29:50:38 | call to taint : | semmle.label | call to taint : | | hash_extensions.rb:50:52:50:61 | call to taint : | semmle.label | call to taint : | | hash_extensions.rb:50:52:50:61 | call to taint : | semmle.label | call to taint : | +| hash_extensions.rb:51:5:51:5 | x [element :a] : | semmle.label | x [element :a] : | +| hash_extensions.rb:51:5:51:5 | x [element :a] : | semmle.label | x [element :a] : | +| hash_extensions.rb:51:5:51:5 | x [element :b] : | semmle.label | x [element :b] : | +| hash_extensions.rb:51:5:51:5 | x [element :b] : | semmle.label | x [element :b] : | | hash_extensions.rb:51:9:51:9 | [post] h [element :d] : | semmle.label | [post] h [element :d] : | | hash_extensions.rb:51:9:51:9 | [post] h [element :d] : | semmle.label | [post] h [element :d] : | | hash_extensions.rb:51:9:51:9 | h [element :a] : | semmle.label | h [element :a] : | @@ -793,12 +1083,20 @@ 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:5:67:10 | values [element 0] : | semmle.label | values [element 0] : | +| hash_extensions.rb:67:5:67:10 | values [element 0] : | semmle.label | values [element 0] : | +| hash_extensions.rb:67:5:67:10 | values [element 1] : | semmle.label | values [element 1] : | +| hash_extensions.rb:67:5:67:10 | values [element 1] : | semmle.label | values [element 1] : | +| hash_extensions.rb:67:5:67:10 | values [element 2] : | semmle.label | values [element 2] : | +| hash_extensions.rb:67:5:67:10 | values [element 2] : | semmle.label | values [element 2] : | | 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:5:68:5 | h [element] : | semmle.label | h [element] : | +| hash_extensions.rb:68:5:68:5 | h [element] : | semmle.label | h [element] : | | 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] : | @@ -819,12 +1117,20 @@ 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:5:80:10 | values [element 0] : | semmle.label | values [element 0] : | +| hash_extensions.rb:80:5:80:10 | values [element 0] : | semmle.label | values [element 0] : | +| hash_extensions.rb:80:5:80:10 | values [element 1] : | semmle.label | values [element 1] : | +| hash_extensions.rb:80:5:80:10 | values [element 1] : | semmle.label | values [element 1] : | +| hash_extensions.rb:80:5:80:10 | values [element 2] : | semmle.label | values [element 2] : | +| hash_extensions.rb:80:5:80:10 | values [element 2] : | semmle.label | values [element 2] : | | 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:5:81:5 | h [element] : | semmle.label | h [element] : | +| hash_extensions.rb:81:5:81:5 | h [element] : | semmle.label | h [element] : | | 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] : | @@ -847,6 +1153,8 @@ nodes | 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:5:89:5 | j [element] : | semmle.label | j [element] : | +| hash_extensions.rb:89:5:89:5 | j [element] : | semmle.label | j [element] : | | 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 : | @@ -859,6 +1167,10 @@ 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:5:98:10 | values [element 0, element :id] : | semmle.label | values [element 0, element :id] : | +| hash_extensions.rb:98:5:98:10 | values [element 0, element :id] : | semmle.label | values [element 0, element :id] : | +| hash_extensions.rb:98:5:98:10 | values [element 0, element :name] : | semmle.label | values [element 0, element :name] : | +| hash_extensions.rb:98:5:98:10 | values [element 0, element :name] : | semmle.label | values [element 0, element :name] : | | 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 : | @@ -895,6 +1207,14 @@ 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:5:110:10 | values [element 0, element :id] : | semmle.label | values [element 0, element :id] : | +| hash_extensions.rb:110:5:110:10 | values [element 0, element :id] : | semmle.label | values [element 0, element :id] : | +| hash_extensions.rb:110:5:110:10 | values [element 0, element :name] : | semmle.label | values [element 0, element :name] : | +| hash_extensions.rb:110:5:110:10 | values [element 0, element :name] : | semmle.label | values [element 0, element :name] : | +| hash_extensions.rb:110:5:110:10 | values [element 1, element :id] : | semmle.label | values [element 1, element :id] : | +| hash_extensions.rb:110:5:110:10 | values [element 1, element :id] : | semmle.label | values [element 1, element :id] : | +| hash_extensions.rb:110:5:110:10 | values [element 1, element :name] : | semmle.label | values [element 1, element :name] : | +| hash_extensions.rb:110:5:110:10 | values [element 1, element :name] : | semmle.label | values [element 1, element :name] : | | 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 : | @@ -951,8 +1271,12 @@ 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:5:122:10 | single [element 0] : | semmle.label | single [element 0] : | +| hash_extensions.rb:122:5:122:10 | single [element 0] : | semmle.label | single [element 0] : | | 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:5:123:9 | multi [element 0] : | semmle.label | multi [element 0] : | +| hash_extensions.rb:123:5:123:9 | multi [element 0] : | semmle.label | multi [element 0] : | | 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] : | diff --git a/ruby/ql/test/library-tests/frameworks/files/Files.expected b/ruby/ql/test/library-tests/frameworks/files/Files.expected index bebb93ef371..b75acc54c5b 100644 --- a/ruby/ql/test/library-tests/frameworks/files/Files.expected +++ b/ruby/ql/test/library-tests/frameworks/files/Files.expected @@ -1,8 +1,8 @@ fileInstances -| Files.rb:2:1:2:36 | ... = ... | +| Files.rb:2:1:2:8 | foo_file | | Files.rb:2:1:2:36 | ... = ... | | Files.rb:2:12:2:36 | call to new | -| Files.rb:3:1:3:21 | ... = ... | +| Files.rb:3:1:3:10 | foo_file_2 | | Files.rb:3:1:3:21 | ... = ... | | Files.rb:3:14:3:21 | foo_file | | Files.rb:4:1:4:8 | foo_file | @@ -18,17 +18,17 @@ fileInstances | Files.rb:40:1:40:8 | foo_file | | Files.rb:41:1:41:26 | call to open | ioInstances -| Files.rb:2:1:2:36 | ... = ... | +| Files.rb:2:1:2:8 | foo_file | | Files.rb:2:1:2:36 | ... = ... | | Files.rb:2:12:2:36 | call to new | -| Files.rb:3:1:3:21 | ... = ... | +| Files.rb:3:1:3:10 | foo_file_2 | | Files.rb:3:1:3:21 | ... = ... | | Files.rb:3:14:3:21 | foo_file | | Files.rb:4:1:4:8 | foo_file | | Files.rb:7:13:7:22 | foo_file_2 | | Files.rb:10:6:10:13 | foo_file | | Files.rb:11:6:11:13 | foo_file | -| Files.rb:17:1:17:50 | ... = ... | +| Files.rb:17:1:17:4 | rand | | Files.rb:17:1:17:50 | ... = ... | | Files.rb:17:8:17:50 | call to new | | Files.rb:18:1:18:13 | ... = ... | @@ -44,7 +44,7 @@ ioInstances | Files.rb:37:14:37:33 | call to open | | Files.rb:40:1:40:8 | foo_file | | Files.rb:41:1:41:26 | call to open | -| Files.rb:44:1:44:45 | ... = ... | +| Files.rb:44:1:44:7 | io_file | | Files.rb:44:1:44:45 | ... = ... | | Files.rb:44:11:44:45 | call to open | | Files.rb:48:1:48:7 | io_file | diff --git a/ruby/ql/test/library-tests/frameworks/pathname/Pathname.expected b/ruby/ql/test/library-tests/frameworks/pathname/Pathname.expected index c69247ae5f8..d082076be69 100644 --- a/ruby/ql/test/library-tests/frameworks/pathname/Pathname.expected +++ b/ruby/ql/test/library-tests/frameworks/pathname/Pathname.expected @@ -1,21 +1,21 @@ pathnameInstances -| Pathname.rb:2:1:2:33 | ... = ... | +| Pathname.rb:2:1:2:8 | foo_path | | Pathname.rb:2:1:2:33 | ... = ... | | Pathname.rb:2:12:2:33 | call to new | | Pathname.rb:3:1:3:20 | ... = ... | | Pathname.rb:3:13:3:20 | foo_path | | Pathname.rb:4:1:4:8 | foo_path | -| Pathname.rb:6:1:6:29 | ... = ... | +| Pathname.rb:6:1:6:8 | bar_path | | Pathname.rb:6:1:6:29 | ... = ... | | Pathname.rb:6:12:6:29 | call to new | -| Pathname.rb:9:1:9:21 | ... = ... | +| Pathname.rb:9:1:9:4 | pwd1 | | Pathname.rb:9:1:9:21 | ... = ... | | Pathname.rb:9:8:9:21 | call to getwd | | Pathname.rb:10:1:10:21 | ... = ... | | Pathname.rb:10:7:10:10 | pwd1 | | Pathname.rb:10:7:10:21 | ... + ... | | Pathname.rb:10:14:10:21 | foo_path | -| Pathname.rb:11:1:11:21 | ... = ... | +| Pathname.rb:11:1:11:3 | p01 | | Pathname.rb:11:1:11:21 | ... = ... | | Pathname.rb:11:7:11:10 | pwd1 | | Pathname.rb:11:7:11:21 | ... / ... | @@ -38,7 +38,7 @@ pathnameInstances | Pathname.rb:17:1:17:59 | ... = ... | | Pathname.rb:17:7:17:33 | call to new | | Pathname.rb:17:7:17:59 | call to relative_path_from | -| Pathname.rb:18:1:18:33 | ... = ... | +| Pathname.rb:18:1:18:3 | p08 | | Pathname.rb:18:1:18:33 | ... = ... | | Pathname.rb:18:7:18:10 | pwd1 | | Pathname.rb:18:7:18:33 | call to sub | @@ -75,23 +75,23 @@ fileSystemAccesses | Pathname.rb:35:1:35:23 | call to write | Pathname.rb:35:1:35:8 | foo_path | | Pathname.rb:39:12:39:34 | call to open | Pathname.rb:39:12:39:19 | foo_path | fileNameSources -| Pathname.rb:2:1:2:33 | ... = ... | +| Pathname.rb:2:1:2:8 | foo_path | | Pathname.rb:2:1:2:33 | ... = ... | | Pathname.rb:2:12:2:33 | call to new | | Pathname.rb:3:1:3:20 | ... = ... | | Pathname.rb:3:13:3:20 | foo_path | | Pathname.rb:4:1:4:8 | foo_path | -| Pathname.rb:6:1:6:29 | ... = ... | +| Pathname.rb:6:1:6:8 | bar_path | | Pathname.rb:6:1:6:29 | ... = ... | | Pathname.rb:6:12:6:29 | call to new | -| Pathname.rb:9:1:9:21 | ... = ... | +| Pathname.rb:9:1:9:4 | pwd1 | | Pathname.rb:9:1:9:21 | ... = ... | | Pathname.rb:9:8:9:21 | call to getwd | | Pathname.rb:10:1:10:21 | ... = ... | | Pathname.rb:10:7:10:10 | pwd1 | | Pathname.rb:10:7:10:21 | ... + ... | | Pathname.rb:10:14:10:21 | foo_path | -| Pathname.rb:11:1:11:21 | ... = ... | +| Pathname.rb:11:1:11:3 | p01 | | Pathname.rb:11:1:11:21 | ... = ... | | Pathname.rb:11:7:11:10 | pwd1 | | Pathname.rb:11:7:11:21 | ... / ... | @@ -114,7 +114,7 @@ fileNameSources | Pathname.rb:17:1:17:59 | ... = ... | | Pathname.rb:17:7:17:33 | call to new | | Pathname.rb:17:7:17:59 | call to relative_path_from | -| Pathname.rb:18:1:18:33 | ... = ... | +| Pathname.rb:18:1:18:3 | p08 | | Pathname.rb:18:1:18:33 | ... = ... | | Pathname.rb:18:7:18:10 | pwd1 | | Pathname.rb:18:7:18:33 | call to sub | diff --git a/ruby/ql/test/library-tests/variables/ssa.expected b/ruby/ql/test/library-tests/variables/ssa.expected index 2f6d07b9915..a285f5f8cc4 100644 --- a/ruby/ql/test/library-tests/variables/ssa.expected +++ b/ruby/ql/test/library-tests/variables/ssa.expected @@ -22,29 +22,29 @@ definition | instance_variables.rb:38:4:40:6 | self (y) | instance_variables.rb:38:4:40:6 | self | | nested_scopes.rb:1:1:3:3 | self (a) | nested_scopes.rb:1:1:3:3 | self | | nested_scopes.rb:4:1:39:3 | self (C) | nested_scopes.rb:4:1:39:3 | self | -| nested_scopes.rb:5:3:5:7 | ... = ... | nested_scopes.rb:5:3:5:3 | a | +| nested_scopes.rb:5:3:5:3 | a | nested_scopes.rb:5:3:5:3 | a | | nested_scopes.rb:6:3:37:5 | self (M) | nested_scopes.rb:6:3:37:5 | self | -| nested_scopes.rb:7:5:7:9 | ... = ... | nested_scopes.rb:7:5:7:5 | a | +| nested_scopes.rb:7:5:7:5 | a | nested_scopes.rb:7:5:7:5 | a | | nested_scopes.rb:8:5:35:7 | self (N) | nested_scopes.rb:8:5:35:7 | self | -| nested_scopes.rb:9:7:9:11 | ... = ... | nested_scopes.rb:9:7:9:7 | a | +| nested_scopes.rb:9:7:9:7 | a | nested_scopes.rb:9:7:9:7 | a | | nested_scopes.rb:10:7:26:9 | self (D) | nested_scopes.rb:10:7:26:9 | self | -| nested_scopes.rb:11:9:11:13 | ... = ... | nested_scopes.rb:11:9:11:9 | a | +| nested_scopes.rb:11:9:11:9 | a | nested_scopes.rb:11:9:11:9 | a | | nested_scopes.rb:12:9:21:11 | self (show_a) | nested_scopes.rb:12:9:21:11 | self | -| nested_scopes.rb:13:11:13:15 | ... = ... | nested_scopes.rb:13:11:13:11 | a | +| nested_scopes.rb:13:11:13:11 | a | nested_scopes.rb:13:11:13:11 | a | | nested_scopes.rb:15:23:15:23 | a | nested_scopes.rb:15:23:15:23 | a | -| nested_scopes.rb:17:15:17:19 | ... = ... | nested_scopes.rb:16:29:16:29 | a | +| nested_scopes.rb:17:15:17:15 | a | nested_scopes.rb:16:29:16:29 | a | | nested_scopes.rb:18:23:18:36 | <captured entry> a | nested_scopes.rb:16:29:16:29 | a | | nested_scopes.rb:18:23:18:36 | <captured entry> self | nested_scopes.rb:12:9:21:11 | self | | nested_scopes.rb:22:9:24:11 | self (show_a2) | nested_scopes.rb:22:9:24:11 | self | | nested_scopes.rb:22:21:22:21 | a | nested_scopes.rb:22:21:22:21 | a | | nested_scopes.rb:27:7:29:9 | self (show) | nested_scopes.rb:27:7:29:9 | self | | nested_scopes.rb:30:16:30:19 | self (class << ...) | nested_scopes.rb:30:7:33:9 | self | -| nested_scopes.rb:31:11:31:16 | ... = ... | nested_scopes.rb:31:11:31:11 | a | -| nested_scopes.rb:40:1:40:18 | ... = ... | nested_scopes.rb:40:1:40:1 | d | +| nested_scopes.rb:31:11:31:11 | a | nested_scopes.rb:31:11:31:11 | a | +| nested_scopes.rb:40:1:40:1 | d | nested_scopes.rb:40:1:40:1 | d | | parameters.rb:1:1:62:1 | self (parameters.rb) | parameters.rb:1:1:62:1 | self | | parameters.rb:1:9:5:3 | <captured entry> self | parameters.rb:1:1:62:1 | self | | parameters.rb:1:14:1:14 | x | parameters.rb:1:14:1:14 | x | -| parameters.rb:2:4:2:8 | ... = ... | parameters.rb:1:18:1:18 | y | +| parameters.rb:2:4:2:4 | y | parameters.rb:1:18:1:18 | y | | parameters.rb:7:1:13:3 | self (order_pizza) | parameters.rb:7:1:13:3 | self | | parameters.rb:7:17:7:22 | client | parameters.rb:7:17:7:22 | client | | parameters.rb:7:26:7:31 | pizzas | parameters.rb:7:26:7:31 | pizzas | @@ -64,23 +64,23 @@ definition | parameters.rb:35:1:38:3 | <uninitialized> | parameters.rb:35:16:35:16 | b | | parameters.rb:35:1:38:3 | self (multi) | parameters.rb:35:1:38:3 | self | | parameters.rb:35:11:35:11 | a | parameters.rb:35:11:35:11 | a | -| parameters.rb:35:16:35:20 | ... = ... | parameters.rb:35:16:35:16 | b | +| parameters.rb:35:16:35:16 | b | parameters.rb:35:16:35:16 | b | | parameters.rb:37:3:37:18 | phi | parameters.rb:35:16:35:16 | b | | parameters.rb:40:1:43:3 | <uninitialized> | parameters.rb:40:15:40:15 | e | | parameters.rb:40:1:43:3 | self (multi2) | parameters.rb:40:1:43:3 | self | | parameters.rb:40:12:40:12 | d | parameters.rb:40:12:40:12 | d | -| parameters.rb:40:15:40:19 | ... = ... | parameters.rb:40:15:40:15 | e | +| parameters.rb:40:15:40:15 | e | parameters.rb:40:15:40:15 | e | | parameters.rb:42:3:42:18 | phi | parameters.rb:40:15:40:15 | e | | parameters.rb:45:1:47:3 | self (dup_underscore) | parameters.rb:45:1:47:3 | self | | parameters.rb:45:20:45:20 | _ | parameters.rb:45:20:45:20 | _ | | parameters.rb:49:1:51:3 | self (tuples) | parameters.rb:49:1:51:3 | self | | parameters.rb:49:13:49:13 | a | parameters.rb:49:13:49:13 | a | | parameters.rb:49:15:49:15 | b | parameters.rb:49:15:49:15 | b | -| parameters.rb:53:1:53:6 | ... = ... | parameters.rb:53:1:53:1 | x | +| parameters.rb:53:1:53:1 | x | parameters.rb:53:1:53:1 | x | | parameters.rb:54:9:57:3 | <captured entry> self | parameters.rb:1:1:62:1 | self | | parameters.rb:54:9:57:3 | <captured entry> x | parameters.rb:53:1:53:1 | x | | parameters.rb:54:14:54:14 | y | parameters.rb:54:14:54:14 | y | -| parameters.rb:54:19:54:23 | ... = ... | parameters.rb:53:1:53:1 | x | +| parameters.rb:54:19:54:19 | x | parameters.rb:53:1:53:1 | x | | parameters.rb:55:4:55:9 | phi | parameters.rb:53:1:53:1 | x | | parameters.rb:59:1:61:3 | self (tuples_nested) | parameters.rb:59:1:61:3 | self | | parameters.rb:59:20:59:20 | a | parameters.rb:59:20:59:20 | a | @@ -88,80 +88,80 @@ definition | parameters.rb:59:25:59:25 | c | parameters.rb:59:25:59:25 | c | | scopes.rb:1:1:49:4 | self (scopes.rb) | scopes.rb:1:1:49:4 | self | | scopes.rb:2:9:6:3 | <captured entry> self | scopes.rb:1:1:49:4 | self | -| scopes.rb:4:4:4:8 | ... = ... | scopes.rb:4:4:4:4 | a | -| scopes.rb:7:1:7:5 | ... = ... | scopes.rb:7:1:7:1 | a | +| scopes.rb:4:4:4:4 | a | scopes.rb:4:4:4:4 | a | +| scopes.rb:7:1:7:1 | a | scopes.rb:7:1:7:1 | a | | scopes.rb:9:1:18:3 | <captured exit> a | scopes.rb:7:1:7:1 | a | | scopes.rb:9:9:18:3 | <captured entry> a | scopes.rb:7:1:7:1 | a | | scopes.rb:9:9:18:3 | <captured entry> self | scopes.rb:1:1:49:4 | self | -| scopes.rb:11:4:11:9 | ... = ... | scopes.rb:7:1:7:1 | a | -| scopes.rb:13:4:13:4 | ... = ... | scopes.rb:7:1:7:1 | a | -| scopes.rb:13:7:13:7 | ... = ... | scopes.rb:13:7:13:7 | b | -| scopes.rb:13:10:13:15 | ... = ... | scopes.rb:13:10:13:15 | __synth__0__1 | -| scopes.rb:13:11:13:11 | ... = ... | scopes.rb:13:11:13:11 | c | -| scopes.rb:13:14:13:14 | ... = ... | scopes.rb:13:14:13:14 | d | -| scopes.rb:13:19:13:32 | ... = ... | scopes.rb:13:4:13:32 | __synth__0 | +| scopes.rb:11:4:11:4 | a | scopes.rb:7:1:7:1 | a | +| scopes.rb:13:4:13:4 | a | scopes.rb:7:1:7:1 | a | +| scopes.rb:13:7:13:7 | b | scopes.rb:13:7:13:7 | b | +| scopes.rb:13:10:13:15 | __synth__0__1 | scopes.rb:13:10:13:15 | __synth__0__1 | +| scopes.rb:13:11:13:11 | c | scopes.rb:13:11:13:11 | c | +| scopes.rb:13:14:13:14 | d | scopes.rb:13:14:13:14 | d | +| scopes.rb:13:19:13:32 | __synth__0 | scopes.rb:13:4:13:32 | __synth__0 | | scopes.rb:26:1:26:12 | self (A) | scopes.rb:26:1:26:12 | self | -| scopes.rb:27:1:27:5 | ... = ... | scopes.rb:27:1:27:1 | x | +| scopes.rb:27:1:27:1 | x | scopes.rb:27:1:27:1 | x | | scopes.rb:28:1:30:3 | self (B) | scopes.rb:28:1:30:3 | self | -| scopes.rb:29:3:29:7 | ... = ... | scopes.rb:29:3:29:3 | x | -| scopes.rb:32:3:32:7 | ... = ... | scopes.rb:32:3:32:3 | x | +| scopes.rb:29:3:29:3 | x | scopes.rb:29:3:29:3 | x | +| scopes.rb:32:3:32:3 | x | scopes.rb:32:3:32:3 | x | | scopes.rb:34:1:36:3 | self (C) | scopes.rb:34:1:36:3 | self | -| scopes.rb:35:3:35:7 | ... = ... | scopes.rb:35:3:35:3 | x | +| scopes.rb:35:3:35:3 | x | scopes.rb:35:3:35:3 | x | | scopes.rb:41:1:49:3 | self (M) | scopes.rb:41:1:49:3 | self | -| scopes.rb:42:2:42:9 | ... = ... | scopes.rb:42:2:42:4 | var | -| scopes.rb:43:2:43:13 | ... = ... | scopes.rb:43:2:43:4 | foo | -| scopes.rb:46:5:46:13 | ... = ... | scopes.rb:46:5:46:8 | var2 | +| scopes.rb:42:2:42:4 | var | scopes.rb:42:2:42:4 | var | +| scopes.rb:43:2:43:4 | foo | scopes.rb:43:2:43:4 | foo | +| scopes.rb:46:5:46:8 | var2 | scopes.rb:46:5:46:8 | var2 | | ssa.rb:1:1:16:3 | self (m) | ssa.rb:1:1:16:3 | self | | ssa.rb:1:7:1:7 | b | ssa.rb:1:7:1:7 | b | -| ssa.rb:2:3:2:7 | ... = ... | ssa.rb:2:3:2:3 | i | +| ssa.rb:2:3:2:3 | i | ssa.rb:2:3:2:3 | i | | ssa.rb:5:3:13:5 | phi | ssa.rb:2:3:2:3 | i | -| ssa.rb:6:5:6:9 | ... = ... | ssa.rb:2:3:2:3 | i | -| ssa.rb:10:5:10:9 | ... = ... | ssa.rb:2:3:2:3 | i | +| ssa.rb:6:5:6:5 | i | ssa.rb:2:3:2:3 | i | +| ssa.rb:10:5:10:5 | i | ssa.rb:2:3:2:3 | i | | ssa.rb:18:1:23:3 | self (m1) | ssa.rb:18:1:23:3 | self | | ssa.rb:18:8:18:8 | x | ssa.rb:18:8:18:8 | x | | ssa.rb:19:9:19:9 | phi | ssa.rb:18:8:18:8 | x | -| ssa.rb:21:5:21:10 | ... = ... | ssa.rb:18:8:18:8 | x | +| ssa.rb:21:5:21:5 | x | ssa.rb:18:8:18:8 | x | | ssa.rb:25:1:30:3 | <uninitialized> | ssa.rb:26:7:26:10 | elem | | ssa.rb:25:1:30:3 | self (m2) | ssa.rb:25:1:30:3 | self | | ssa.rb:25:8:25:15 | elements | ssa.rb:25:8:25:15 | elements | -| ssa.rb:26:3:28:5 | ... = ... | ssa.rb:26:7:26:10 | elem | | ssa.rb:26:3:28:5 | <captured entry> self | ssa.rb:25:1:30:3 | self | | ssa.rb:26:3:28:5 | <captured exit> elem | ssa.rb:26:7:26:10 | elem | | ssa.rb:26:3:28:5 | __synth__0__1 | ssa.rb:26:3:28:5 | __synth__0__1 | +| ssa.rb:26:7:26:10 | elem | ssa.rb:26:7:26:10 | elem | | ssa.rb:32:1:36:3 | self (m3) | ssa.rb:32:1:36:3 | self | | ssa.rb:33:16:35:5 | <captured entry> self | ssa.rb:32:1:36:3 | self | | ssa.rb:33:20:33:20 | x | ssa.rb:33:20:33:20 | x | | ssa.rb:38:1:42:3 | self (m4) | ssa.rb:38:1:42:3 | self | -| ssa.rb:40:3:40:9 | ... = ... | ssa.rb:40:3:40:4 | m3 | +| ssa.rb:40:3:40:4 | m3 | ssa.rb:40:3:40:4 | m3 | | ssa.rb:44:1:47:3 | <uninitialized> | ssa.rb:45:3:45:3 | x | | ssa.rb:44:1:47:3 | self (m5) | ssa.rb:44:1:47:3 | self | | ssa.rb:44:8:44:8 | b | ssa.rb:44:8:44:8 | b | -| ssa.rb:45:3:45:7 | ... = ... | ssa.rb:45:3:45:3 | x | +| ssa.rb:45:3:45:3 | x | ssa.rb:45:3:45:3 | x | | ssa.rb:45:3:45:12 | phi | ssa.rb:45:3:45:3 | x | | ssa.rb:49:1:51:3 | <uninitialized> | ssa.rb:49:14:49:14 | y | | ssa.rb:49:1:51:3 | self (m6) | ssa.rb:49:1:51:3 | self | -| ssa.rb:49:14:49:19 | ... = ... | ssa.rb:49:14:49:14 | y | +| ssa.rb:49:14:49:14 | y | ssa.rb:49:14:49:14 | y | | ssa.rb:50:3:50:8 | phi | ssa.rb:49:14:49:14 | y | | ssa.rb:53:1:56:3 | self (m7) | ssa.rb:53:1:56:3 | self | | ssa.rb:53:8:53:10 | foo | ssa.rb:53:8:53:10 | foo | -| ssa.rb:54:3:54:11 | ... = ... | ssa.rb:54:3:54:3 | x | +| ssa.rb:54:3:54:3 | x | ssa.rb:54:3:54:3 | x | | ssa.rb:58:1:62:3 | self (m8) | ssa.rb:58:1:62:3 | self | -| ssa.rb:59:3:59:8 | ... = ... | ssa.rb:59:3:59:3 | x | -| ssa.rb:60:3:60:9 | ... = ... | ssa.rb:59:3:59:3 | x | +| ssa.rb:59:3:59:3 | x | ssa.rb:59:3:59:3 | x | +| ssa.rb:60:3:60:3 | x | ssa.rb:59:3:59:3 | x | | ssa.rb:64:1:72:3 | self (m9) | ssa.rb:64:1:72:3 | self | | ssa.rb:64:8:64:8 | a | ssa.rb:64:8:64:8 | a | -| ssa.rb:65:3:65:15 | ... = ... | ssa.rb:65:3:65:10 | captured | +| ssa.rb:65:3:65:10 | captured | ssa.rb:65:3:65:10 | captured | | ssa.rb:66:3:70:5 | <captured exit> captured | ssa.rb:65:3:65:10 | captured | | ssa.rb:66:11:70:5 | <captured entry> captured | ssa.rb:65:3:65:10 | captured | | ssa.rb:66:11:70:5 | <captured entry> self | ssa.rb:64:1:72:3 | self | | ssa.rb:66:15:66:15 | a | ssa.rb:66:15:66:15 | a | -| ssa.rb:69:5:69:17 | ... = ... | ssa.rb:65:3:65:10 | captured | +| ssa.rb:69:5:69:12 | captured | ssa.rb:65:3:65:10 | captured | | ssa.rb:74:1:79:3 | self (m10) | ssa.rb:74:1:79:3 | self | -| ssa.rb:75:3:75:14 | ... = ... | ssa.rb:75:3:75:10 | captured | +| ssa.rb:75:3:75:10 | captured | ssa.rb:75:3:75:10 | captured | | ssa.rb:76:7:78:5 | <captured entry> captured | ssa.rb:75:3:75:10 | captured | | ssa.rb:76:7:78:5 | <captured entry> self | ssa.rb:74:1:79:3 | self | | ssa.rb:81:1:88:3 | self (m11) | ssa.rb:81:1:88:3 | self | -| ssa.rb:82:3:82:14 | ... = ... | ssa.rb:82:3:82:10 | captured | +| ssa.rb:82:3:82:10 | captured | ssa.rb:82:3:82:10 | captured | | ssa.rb:83:7:87:5 | <captured entry> self | ssa.rb:81:1:88:3 | self | | ssa.rb:84:10:86:8 | <captured entry> captured | ssa.rb:82:3:82:10 | captured | | ssa.rb:84:10:86:8 | <captured entry> self | ssa.rb:81:1:88:3 | self | @@ -170,7 +170,7 @@ definition | 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 | +| ssa.rb:91:3:91:3 | x | 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 | @@ -199,20 +199,20 @@ read | instance_variables.rb:38:4:40:6 | self (y) | instance_variables.rb:38:4:40:6 | self | instance_variables.rb:39:6:39:7 | self | | nested_scopes.rb:1:1:3:3 | self (a) | nested_scopes.rb:1:1:3:3 | self | nested_scopes.rb:2:3:2:17 | self | | nested_scopes.rb:4:1:39:3 | self (C) | nested_scopes.rb:4:1:39:3 | self | nested_scopes.rb:38:3:38:8 | self | -| nested_scopes.rb:5:3:5:7 | ... = ... | nested_scopes.rb:5:3:5:3 | a | nested_scopes.rb:38:8:38:8 | a | +| nested_scopes.rb:5:3:5:3 | a | nested_scopes.rb:5:3:5:3 | a | nested_scopes.rb:38:8:38:8 | a | | nested_scopes.rb:6:3:37:5 | self (M) | nested_scopes.rb:6:3:37:5 | self | nested_scopes.rb:36:5:36:10 | self | -| nested_scopes.rb:7:5:7:9 | ... = ... | nested_scopes.rb:7:5:7:5 | a | nested_scopes.rb:36:10:36:10 | a | +| nested_scopes.rb:7:5:7:5 | a | nested_scopes.rb:7:5:7:5 | a | nested_scopes.rb:36:10:36:10 | a | | nested_scopes.rb:8:5:35:7 | self (N) | nested_scopes.rb:8:5:35:7 | self | nested_scopes.rb:27:11:27:14 | self | | nested_scopes.rb:8:5:35:7 | self (N) | nested_scopes.rb:8:5:35:7 | self | nested_scopes.rb:30:16:30:19 | self | | nested_scopes.rb:8:5:35:7 | self (N) | nested_scopes.rb:8:5:35:7 | self | nested_scopes.rb:34:7:34:12 | self | -| nested_scopes.rb:9:7:9:11 | ... = ... | nested_scopes.rb:9:7:9:7 | a | nested_scopes.rb:34:12:34:12 | a | +| nested_scopes.rb:9:7:9:7 | a | nested_scopes.rb:9:7:9:7 | a | nested_scopes.rb:34:12:34:12 | a | | nested_scopes.rb:10:7:26:9 | self (D) | nested_scopes.rb:10:7:26:9 | self | nested_scopes.rb:25:9:25:14 | self | -| nested_scopes.rb:11:9:11:13 | ... = ... | nested_scopes.rb:11:9:11:9 | a | nested_scopes.rb:25:14:25:14 | a | +| nested_scopes.rb:11:9:11:9 | a | nested_scopes.rb:11:9:11:9 | a | nested_scopes.rb:25:14:25:14 | a | | nested_scopes.rb:12:9:21:11 | self (show_a) | nested_scopes.rb:12:9:21:11 | self | nested_scopes.rb:14:11:14:16 | self | -| nested_scopes.rb:13:11:13:15 | ... = ... | nested_scopes.rb:13:11:13:11 | a | nested_scopes.rb:14:16:14:16 | a | -| nested_scopes.rb:13:11:13:15 | ... = ... | nested_scopes.rb:13:11:13:11 | a | nested_scopes.rb:15:11:15:11 | a | +| nested_scopes.rb:13:11:13:11 | a | nested_scopes.rb:13:11:13:11 | a | nested_scopes.rb:14:16:14:16 | a | +| nested_scopes.rb:13:11:13:11 | a | nested_scopes.rb:13:11:13:11 | a | nested_scopes.rb:15:11:15:11 | a | | nested_scopes.rb:15:23:15:23 | a | nested_scopes.rb:15:23:15:23 | a | nested_scopes.rb:16:13:16:13 | a | -| nested_scopes.rb:17:15:17:19 | ... = ... | nested_scopes.rb:16:29:16:29 | a | nested_scopes.rb:18:15:18:15 | a | +| nested_scopes.rb:17:15:17:15 | a | nested_scopes.rb:16:29:16:29 | a | nested_scopes.rb:18:15:18:15 | a | | nested_scopes.rb:18:23:18:36 | <captured entry> a | nested_scopes.rb:16:29:16:29 | a | nested_scopes.rb:18:34:18:34 | a | | nested_scopes.rb:18:23:18:36 | <captured entry> self | nested_scopes.rb:12:9:21:11 | self | nested_scopes.rb:18:29:18:34 | self | | nested_scopes.rb:22:9:24:11 | self (show_a2) | nested_scopes.rb:22:9:24:11 | self | nested_scopes.rb:23:11:23:16 | self | @@ -220,12 +220,12 @@ read | nested_scopes.rb:27:7:29:9 | self (show) | nested_scopes.rb:27:7:29:9 | self | nested_scopes.rb:28:11:28:16 | self | | nested_scopes.rb:27:7:29:9 | self (show) | nested_scopes.rb:27:7:29:9 | self | nested_scopes.rb:28:16:28:16 | self | | nested_scopes.rb:30:16:30:19 | self (class << ...) | nested_scopes.rb:30:7:33:9 | self | nested_scopes.rb:32:11:32:16 | self | -| nested_scopes.rb:31:11:31:16 | ... = ... | nested_scopes.rb:31:11:31:11 | a | nested_scopes.rb:32:16:32:16 | a | -| nested_scopes.rb:40:1:40:18 | ... = ... | nested_scopes.rb:40:1:40:1 | d | nested_scopes.rb:41:1:41:1 | d | +| nested_scopes.rb:31:11:31:11 | a | nested_scopes.rb:31:11:31:11 | a | nested_scopes.rb:32:16:32:16 | a | +| nested_scopes.rb:40:1:40:1 | d | nested_scopes.rb:40:1:40:1 | d | nested_scopes.rb:41:1:41:1 | d | | parameters.rb:1:9:5:3 | <captured entry> self | parameters.rb:1:1:62:1 | self | parameters.rb:3:4:3:9 | self | | parameters.rb:1:9:5:3 | <captured entry> self | parameters.rb:1:1:62:1 | self | parameters.rb:4:4:4:9 | self | | parameters.rb:1:14:1:14 | x | parameters.rb:1:14:1:14 | x | parameters.rb:3:9:3:9 | x | -| parameters.rb:2:4:2:8 | ... = ... | parameters.rb:1:18:1:18 | y | parameters.rb:4:9:4:9 | y | +| parameters.rb:2:4:2:4 | y | parameters.rb:1:18:1:18 | y | parameters.rb:4:9:4:9 | y | | parameters.rb:7:1:13:3 | self (order_pizza) | parameters.rb:7:1:13:3 | self | parameters.rb:9:5:9:33 | self | | parameters.rb:7:1:13:3 | self (order_pizza) | parameters.rb:7:1:13:3 | self | parameters.rb:11:5:11:49 | self | | parameters.rb:7:17:7:22 | client | parameters.rb:7:17:7:22 | client | parameters.rb:9:25:9:30 | client | @@ -269,8 +269,8 @@ read | scopes.rb:2:9:6:3 | <captured entry> self | scopes.rb:1:1:49:4 | self | scopes.rb:3:4:3:9 | self | | scopes.rb:2:9:6:3 | <captured entry> self | scopes.rb:1:1:49:4 | self | scopes.rb:3:9:3:9 | self | | scopes.rb:2:9:6:3 | <captured entry> self | scopes.rb:1:1:49:4 | self | scopes.rb:5:4:5:9 | self | -| scopes.rb:4:4:4:8 | ... = ... | scopes.rb:4:4:4:4 | a | scopes.rb:5:9:5:9 | a | -| scopes.rb:7:1:7:5 | ... = ... | scopes.rb:7:1:7:1 | a | scopes.rb:8:6:8:6 | a | +| scopes.rb:4:4:4:4 | a | scopes.rb:4:4:4:4 | a | scopes.rb:5:9:5:9 | a | +| scopes.rb:7:1:7:1 | a | scopes.rb:7:1:7:1 | a | scopes.rb:8:6:8:6 | a | | scopes.rb:9:9:18:3 | <captured entry> a | scopes.rb:7:1:7:1 | a | scopes.rb:10:9:10:9 | a | | scopes.rb:9:9:18:3 | <captured entry> a | scopes.rb:7:1:7:1 | a | scopes.rb:11:4:11:4 | a | | scopes.rb:9:9:18:3 | <captured entry> self | scopes.rb:1:1:49:4 | self | scopes.rb:10:4:10:9 | self | @@ -279,24 +279,24 @@ read | scopes.rb:9:9:18:3 | <captured entry> self | scopes.rb:1:1:49:4 | self | scopes.rb:15:4:15:9 | self | | scopes.rb:9:9:18:3 | <captured entry> self | scopes.rb:1:1:49:4 | self | scopes.rb:16:4:16:9 | self | | scopes.rb:9:9:18:3 | <captured entry> self | scopes.rb:1:1:49:4 | self | scopes.rb:17:4:17:9 | self | -| scopes.rb:11:4:11:9 | ... = ... | scopes.rb:7:1:7:1 | a | scopes.rb:12:9:12:9 | a | -| scopes.rb:13:4:13:4 | ... = ... | scopes.rb:7:1:7:1 | a | scopes.rb:14:9:14:9 | a | -| scopes.rb:13:7:13:7 | ... = ... | scopes.rb:13:7:13:7 | b | scopes.rb:15:9:15:9 | b | -| scopes.rb:13:10:13:15 | ... = ... | scopes.rb:13:10:13:15 | __synth__0__1 | scopes.rb:13:11:13:11 | __synth__0__1 | -| scopes.rb:13:10:13:15 | ... = ... | scopes.rb:13:10:13:15 | __synth__0__1 | scopes.rb:13:14:13:14 | __synth__0__1 | -| scopes.rb:13:11:13:11 | ... = ... | scopes.rb:13:11:13:11 | c | scopes.rb:16:9:16:9 | c | -| scopes.rb:13:14:13:14 | ... = ... | scopes.rb:13:14:13:14 | d | scopes.rb:17:9:17:9 | d | -| scopes.rb:13:19:13:32 | ... = ... | scopes.rb:13:4:13:32 | __synth__0 | scopes.rb:13:4:13:4 | __synth__0 | -| scopes.rb:13:19:13:32 | ... = ... | scopes.rb:13:4:13:32 | __synth__0 | scopes.rb:13:7:13:7 | __synth__0 | -| scopes.rb:13:19:13:32 | ... = ... | scopes.rb:13:4:13:32 | __synth__0 | scopes.rb:13:10:13:15 | __synth__0 | -| scopes.rb:27:1:27:5 | ... = ... | scopes.rb:27:1:27:1 | x | scopes.rb:28:8:28:8 | x | -| scopes.rb:27:1:27:5 | ... = ... | scopes.rb:27:1:27:1 | x | scopes.rb:31:10:31:10 | x | -| scopes.rb:27:1:27:5 | ... = ... | scopes.rb:27:1:27:1 | x | scopes.rb:34:7:34:7 | x | -| scopes.rb:27:1:27:5 | ... = ... | scopes.rb:27:1:27:1 | x | scopes.rb:34:14:34:14 | x | -| scopes.rb:27:1:27:5 | ... = ... | scopes.rb:27:1:27:1 | x | scopes.rb:37:5:37:5 | x | +| scopes.rb:11:4:11:4 | a | scopes.rb:7:1:7:1 | a | scopes.rb:12:9:12:9 | a | +| scopes.rb:13:4:13:4 | a | scopes.rb:7:1:7:1 | a | scopes.rb:14:9:14:9 | a | +| scopes.rb:13:7:13:7 | b | scopes.rb:13:7:13:7 | b | scopes.rb:15:9:15:9 | b | +| scopes.rb:13:10:13:15 | __synth__0__1 | scopes.rb:13:10:13:15 | __synth__0__1 | scopes.rb:13:11:13:11 | __synth__0__1 | +| scopes.rb:13:10:13:15 | __synth__0__1 | scopes.rb:13:10:13:15 | __synth__0__1 | scopes.rb:13:14:13:14 | __synth__0__1 | +| scopes.rb:13:11:13:11 | c | scopes.rb:13:11:13:11 | c | scopes.rb:16:9:16:9 | c | +| scopes.rb:13:14:13:14 | d | scopes.rb:13:14:13:14 | d | scopes.rb:17:9:17:9 | d | +| scopes.rb:13:19:13:32 | __synth__0 | scopes.rb:13:4:13:32 | __synth__0 | scopes.rb:13:4:13:4 | __synth__0 | +| scopes.rb:13:19:13:32 | __synth__0 | scopes.rb:13:4:13:32 | __synth__0 | scopes.rb:13:7:13:7 | __synth__0 | +| scopes.rb:13:19:13:32 | __synth__0 | scopes.rb:13:4:13:32 | __synth__0 | scopes.rb:13:10:13:15 | __synth__0 | +| scopes.rb:27:1:27:1 | x | scopes.rb:27:1:27:1 | x | scopes.rb:28:8:28:8 | x | +| scopes.rb:27:1:27:1 | x | scopes.rb:27:1:27:1 | x | scopes.rb:31:10:31:10 | x | +| scopes.rb:27:1:27:1 | x | scopes.rb:27:1:27:1 | x | scopes.rb:34:7:34:7 | x | +| scopes.rb:27:1:27:1 | x | scopes.rb:27:1:27:1 | x | scopes.rb:34:14:34:14 | x | +| scopes.rb:27:1:27:1 | x | scopes.rb:27:1:27:1 | x | scopes.rb:37:5:37:5 | x | | scopes.rb:41:1:49:3 | self (M) | scopes.rb:41:1:49:3 | self | scopes.rb:45:5:45:7 | self | -| scopes.rb:42:2:42:9 | ... = ... | scopes.rb:42:2:42:4 | var | scopes.rb:44:5:44:7 | var | -| scopes.rb:46:5:46:13 | ... = ... | scopes.rb:46:5:46:8 | var2 | scopes.rb:47:5:47:8 | var2 | +| scopes.rb:42:2:42:4 | var | scopes.rb:42:2:42:4 | var | scopes.rb:44:5:44:7 | var | +| scopes.rb:46:5:46:8 | var2 | scopes.rb:46:5:46:8 | var2 | scopes.rb:47:5:47:8 | var2 | | ssa.rb:1:1:16:3 | self (m) | ssa.rb:1:1:16:3 | self | ssa.rb:3:3:3:8 | self | | ssa.rb:1:1:16:3 | self (m) | ssa.rb:1:1:16:3 | self | ssa.rb:4:3:4:12 | self | | ssa.rb:1:1:16:3 | self (m) | ssa.rb:1:1:16:3 | self | ssa.rb:7:5:7:10 | self | @@ -305,29 +305,29 @@ read | ssa.rb:1:1:16:3 | self (m) | ssa.rb:1:1:16:3 | self | ssa.rb:12:5:12:14 | self | | ssa.rb:1:1:16:3 | self (m) | ssa.rb:1:1:16:3 | self | ssa.rb:15:3:15:8 | self | | ssa.rb:1:7:1:7 | b | ssa.rb:1:7:1:7 | b | ssa.rb:5:6:5:6 | b | -| ssa.rb:2:3:2:7 | ... = ... | ssa.rb:2:3:2:3 | i | ssa.rb:3:8:3:8 | i | -| ssa.rb:2:3:2:7 | ... = ... | ssa.rb:2:3:2:3 | i | ssa.rb:4:8:4:8 | i | +| ssa.rb:2:3:2:3 | i | ssa.rb:2:3:2:3 | i | ssa.rb:3:8:3:8 | i | +| ssa.rb:2:3:2:3 | i | ssa.rb:2:3:2:3 | i | ssa.rb:4:8:4:8 | i | | ssa.rb:5:3:13:5 | phi | ssa.rb:2:3:2:3 | i | ssa.rb:15:8:15:8 | i | -| ssa.rb:6:5:6:9 | ... = ... | ssa.rb:2:3:2:3 | i | ssa.rb:7:10:7:10 | i | -| ssa.rb:6:5:6:9 | ... = ... | ssa.rb:2:3:2:3 | i | ssa.rb:8:10:8:10 | i | -| ssa.rb:10:5:10:9 | ... = ... | ssa.rb:2:3:2:3 | i | ssa.rb:11:10:11:10 | i | -| ssa.rb:10:5:10:9 | ... = ... | ssa.rb:2:3:2:3 | i | ssa.rb:12:10:12:10 | i | +| ssa.rb:6:5:6:5 | i | ssa.rb:2:3:2:3 | i | ssa.rb:7:10:7:10 | i | +| ssa.rb:6:5:6:5 | i | ssa.rb:2:3:2:3 | i | ssa.rb:8:10:8:10 | i | +| ssa.rb:10:5:10:5 | i | ssa.rb:2:3:2:3 | i | ssa.rb:11:10:11:10 | i | +| ssa.rb:10:5:10:5 | i | ssa.rb:2:3:2:3 | i | ssa.rb:12:10:12:10 | i | | ssa.rb:18:1:23:3 | self (m1) | ssa.rb:18:1:23:3 | self | ssa.rb:20:5:20:10 | self | | ssa.rb:19:9:19:9 | phi | ssa.rb:18:8:18:8 | x | ssa.rb:19:9:19:9 | x | | ssa.rb:19:9:19:9 | phi | ssa.rb:18:8:18:8 | x | ssa.rb:20:10:20:10 | x | | ssa.rb:19:9:19:9 | phi | ssa.rb:18:8:18:8 | x | ssa.rb:21:5:21:5 | x | | ssa.rb:25:1:30:3 | self (m2) | ssa.rb:25:1:30:3 | self | ssa.rb:29:3:29:11 | self | | ssa.rb:25:8:25:15 | elements | ssa.rb:25:8:25:15 | elements | ssa.rb:26:15:26:22 | elements | -| ssa.rb:26:3:28:5 | ... = ... | ssa.rb:26:7:26:10 | elem | ssa.rb:27:10:27:13 | elem | | ssa.rb:26:3:28:5 | <captured entry> self | ssa.rb:25:1:30:3 | self | ssa.rb:27:5:27:13 | self | | ssa.rb:26:3:28:5 | <captured exit> elem | ssa.rb:26:7:26:10 | elem | ssa.rb:29:8:29:11 | elem | | ssa.rb:26:3:28:5 | __synth__0__1 | ssa.rb:26:3:28:5 | __synth__0__1 | ssa.rb:26:3:28:5 | __synth__0__1 | +| ssa.rb:26:7:26:10 | elem | ssa.rb:26:7:26:10 | elem | ssa.rb:27:10:27:13 | elem | | ssa.rb:33:16:35:5 | <captured entry> self | ssa.rb:32:1:36:3 | self | ssa.rb:34:5:34:10 | self | | ssa.rb:33:20:33:20 | x | ssa.rb:33:20:33:20 | x | ssa.rb:34:10:34:10 | x | | ssa.rb:38:1:42:3 | self (m4) | ssa.rb:38:1:42:3 | self | ssa.rb:39:3:39:9 | self | | ssa.rb:38:1:42:3 | self (m4) | ssa.rb:38:1:42:3 | self | ssa.rb:39:8:39:9 | self | | ssa.rb:38:1:42:3 | self (m4) | ssa.rb:38:1:42:3 | self | ssa.rb:41:3:41:13 | self | -| ssa.rb:40:3:40:9 | ... = ... | ssa.rb:40:3:40:4 | m3 | ssa.rb:41:8:41:9 | m3 | +| ssa.rb:40:3:40:4 | m3 | ssa.rb:40:3:40:4 | m3 | ssa.rb:41:8:41:9 | m3 | | ssa.rb:44:1:47:3 | self (m5) | ssa.rb:44:1:47:3 | self | ssa.rb:46:3:46:8 | self | | ssa.rb:44:8:44:8 | b | ssa.rb:44:8:44:8 | b | ssa.rb:45:12:45:12 | b | | ssa.rb:45:3:45:12 | phi | ssa.rb:45:3:45:3 | x | ssa.rb:46:8:46:8 | x | @@ -335,10 +335,10 @@ read | ssa.rb:50:3:50:8 | phi | ssa.rb:49:14:49:14 | y | ssa.rb:50:8:50:8 | y | | ssa.rb:53:1:56:3 | self (m7) | ssa.rb:53:1:56:3 | self | ssa.rb:55:3:55:8 | self | | ssa.rb:53:8:53:10 | foo | ssa.rb:53:8:53:10 | foo | ssa.rb:54:7:54:9 | foo | -| ssa.rb:54:3:54:11 | ... = ... | ssa.rb:54:3:54:3 | x | ssa.rb:55:8:55:8 | x | +| ssa.rb:54:3:54:3 | x | ssa.rb:54:3:54:3 | x | ssa.rb:55:8:55:8 | x | | ssa.rb:58:1:62:3 | self (m8) | ssa.rb:58:1:62:3 | self | ssa.rb:61:3:61:8 | self | -| ssa.rb:59:3:59:8 | ... = ... | ssa.rb:59:3:59:3 | x | ssa.rb:60:3:60:3 | x | -| ssa.rb:60:3:60:9 | ... = ... | ssa.rb:59:3:59:3 | x | ssa.rb:61:8:61:8 | x | +| ssa.rb:59:3:59:3 | x | ssa.rb:59:3:59:3 | x | ssa.rb:60:3:60:3 | x | +| ssa.rb:60:3:60:3 | x | ssa.rb:59:3:59:3 | x | ssa.rb:61:8:61:8 | x | | ssa.rb:64:1:72:3 | self (m9) | ssa.rb:64:1:72:3 | self | ssa.rb:71:3:71:15 | self | | ssa.rb:64:8:64:8 | a | ssa.rb:64:8:64:8 | a | ssa.rb:66:3:66:3 | a | | ssa.rb:66:3:70:5 | <captured exit> captured | ssa.rb:65:3:65:10 | captured | ssa.rb:71:8:71:15 | captured | @@ -362,10 +362,10 @@ read | 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 | +| ssa.rb:91:3:91:3 | x | ssa.rb:91:3:91:3 | x | ssa.rb:93:10:93:10 | x | +| ssa.rb:91:3:91:3 | x | ssa.rb:91:3:91:3 | x | ssa.rb:95:10:95:10 | x | +| ssa.rb:91:3:91:3 | x | ssa.rb:91:3:91:3 | x | ssa.rb:99:10:99:10 | x | +| ssa.rb:91:3:91:3 | x | 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 | @@ -387,28 +387,28 @@ firstRead | instance_variables.rb:38:4:40:6 | self (y) | instance_variables.rb:38:4:40:6 | self | instance_variables.rb:39:6:39:7 | self | | nested_scopes.rb:1:1:3:3 | self (a) | nested_scopes.rb:1:1:3:3 | self | nested_scopes.rb:2:3:2:17 | self | | nested_scopes.rb:4:1:39:3 | self (C) | nested_scopes.rb:4:1:39:3 | self | nested_scopes.rb:38:3:38:8 | self | -| nested_scopes.rb:5:3:5:7 | ... = ... | nested_scopes.rb:5:3:5:3 | a | nested_scopes.rb:38:8:38:8 | a | +| nested_scopes.rb:5:3:5:3 | a | nested_scopes.rb:5:3:5:3 | a | nested_scopes.rb:38:8:38:8 | a | | nested_scopes.rb:6:3:37:5 | self (M) | nested_scopes.rb:6:3:37:5 | self | nested_scopes.rb:36:5:36:10 | self | -| nested_scopes.rb:7:5:7:9 | ... = ... | nested_scopes.rb:7:5:7:5 | a | nested_scopes.rb:36:10:36:10 | a | +| nested_scopes.rb:7:5:7:5 | a | nested_scopes.rb:7:5:7:5 | a | nested_scopes.rb:36:10:36:10 | a | | nested_scopes.rb:8:5:35:7 | self (N) | nested_scopes.rb:8:5:35:7 | self | nested_scopes.rb:27:11:27:14 | self | -| nested_scopes.rb:9:7:9:11 | ... = ... | nested_scopes.rb:9:7:9:7 | a | nested_scopes.rb:34:12:34:12 | a | +| nested_scopes.rb:9:7:9:7 | a | nested_scopes.rb:9:7:9:7 | a | nested_scopes.rb:34:12:34:12 | a | | nested_scopes.rb:10:7:26:9 | self (D) | nested_scopes.rb:10:7:26:9 | self | nested_scopes.rb:25:9:25:14 | self | -| nested_scopes.rb:11:9:11:13 | ... = ... | nested_scopes.rb:11:9:11:9 | a | nested_scopes.rb:25:14:25:14 | a | +| nested_scopes.rb:11:9:11:9 | a | nested_scopes.rb:11:9:11:9 | a | nested_scopes.rb:25:14:25:14 | a | | nested_scopes.rb:12:9:21:11 | self (show_a) | nested_scopes.rb:12:9:21:11 | self | nested_scopes.rb:14:11:14:16 | self | -| nested_scopes.rb:13:11:13:15 | ... = ... | nested_scopes.rb:13:11:13:11 | a | nested_scopes.rb:14:16:14:16 | a | +| nested_scopes.rb:13:11:13:11 | a | nested_scopes.rb:13:11:13:11 | a | nested_scopes.rb:14:16:14:16 | a | | nested_scopes.rb:15:23:15:23 | a | nested_scopes.rb:15:23:15:23 | a | nested_scopes.rb:16:13:16:13 | a | -| nested_scopes.rb:17:15:17:19 | ... = ... | nested_scopes.rb:16:29:16:29 | a | nested_scopes.rb:18:15:18:15 | a | +| nested_scopes.rb:17:15:17:15 | a | nested_scopes.rb:16:29:16:29 | a | nested_scopes.rb:18:15:18:15 | a | | nested_scopes.rb:18:23:18:36 | <captured entry> a | nested_scopes.rb:16:29:16:29 | a | nested_scopes.rb:18:34:18:34 | a | | nested_scopes.rb:18:23:18:36 | <captured entry> self | nested_scopes.rb:12:9:21:11 | self | nested_scopes.rb:18:29:18:34 | self | | nested_scopes.rb:22:9:24:11 | self (show_a2) | nested_scopes.rb:22:9:24:11 | self | nested_scopes.rb:23:11:23:16 | self | | nested_scopes.rb:22:21:22:21 | a | nested_scopes.rb:22:21:22:21 | a | nested_scopes.rb:23:16:23:16 | a | | nested_scopes.rb:27:7:29:9 | self (show) | nested_scopes.rb:27:7:29:9 | self | nested_scopes.rb:28:11:28:16 | self | | nested_scopes.rb:30:16:30:19 | self (class << ...) | nested_scopes.rb:30:7:33:9 | self | nested_scopes.rb:32:11:32:16 | self | -| nested_scopes.rb:31:11:31:16 | ... = ... | nested_scopes.rb:31:11:31:11 | a | nested_scopes.rb:32:16:32:16 | a | -| nested_scopes.rb:40:1:40:18 | ... = ... | nested_scopes.rb:40:1:40:1 | d | nested_scopes.rb:41:1:41:1 | d | +| nested_scopes.rb:31:11:31:11 | a | nested_scopes.rb:31:11:31:11 | a | nested_scopes.rb:32:16:32:16 | a | +| nested_scopes.rb:40:1:40:1 | d | nested_scopes.rb:40:1:40:1 | d | nested_scopes.rb:41:1:41:1 | d | | parameters.rb:1:9:5:3 | <captured entry> self | parameters.rb:1:1:62:1 | self | parameters.rb:3:4:3:9 | self | | parameters.rb:1:14:1:14 | x | parameters.rb:1:14:1:14 | x | parameters.rb:3:9:3:9 | x | -| parameters.rb:2:4:2:8 | ... = ... | parameters.rb:1:18:1:18 | y | parameters.rb:4:9:4:9 | y | +| parameters.rb:2:4:2:4 | y | parameters.rb:1:18:1:18 | y | parameters.rb:4:9:4:9 | y | | parameters.rb:7:1:13:3 | self (order_pizza) | parameters.rb:7:1:13:3 | self | parameters.rb:9:5:9:33 | self | | parameters.rb:7:1:13:3 | self (order_pizza) | parameters.rb:7:1:13:3 | self | parameters.rb:11:5:11:49 | self | | parameters.rb:7:17:7:22 | client | parameters.rb:7:17:7:22 | client | parameters.rb:9:25:9:30 | client | @@ -447,39 +447,39 @@ firstRead | parameters.rb:59:25:59:25 | c | parameters.rb:59:25:59:25 | c | parameters.rb:60:21:60:21 | c | | scopes.rb:1:1:49:4 | self (scopes.rb) | scopes.rb:1:1:49:4 | self | scopes.rb:8:1:8:6 | self | | scopes.rb:2:9:6:3 | <captured entry> self | scopes.rb:1:1:49:4 | self | scopes.rb:3:4:3:9 | self | -| scopes.rb:4:4:4:8 | ... = ... | scopes.rb:4:4:4:4 | a | scopes.rb:5:9:5:9 | a | -| scopes.rb:7:1:7:5 | ... = ... | scopes.rb:7:1:7:1 | a | scopes.rb:8:6:8:6 | a | +| scopes.rb:4:4:4:4 | a | scopes.rb:4:4:4:4 | a | scopes.rb:5:9:5:9 | a | +| scopes.rb:7:1:7:1 | a | scopes.rb:7:1:7:1 | a | scopes.rb:8:6:8:6 | a | | scopes.rb:9:9:18:3 | <captured entry> a | scopes.rb:7:1:7:1 | a | scopes.rb:10:9:10:9 | a | | scopes.rb:9:9:18:3 | <captured entry> self | scopes.rb:1:1:49:4 | self | scopes.rb:10:4:10:9 | self | -| scopes.rb:11:4:11:9 | ... = ... | scopes.rb:7:1:7:1 | a | scopes.rb:12:9:12:9 | a | -| scopes.rb:13:4:13:4 | ... = ... | scopes.rb:7:1:7:1 | a | scopes.rb:14:9:14:9 | a | -| scopes.rb:13:7:13:7 | ... = ... | scopes.rb:13:7:13:7 | b | scopes.rb:15:9:15:9 | b | -| scopes.rb:13:10:13:15 | ... = ... | scopes.rb:13:10:13:15 | __synth__0__1 | scopes.rb:13:11:13:11 | __synth__0__1 | -| scopes.rb:13:11:13:11 | ... = ... | scopes.rb:13:11:13:11 | c | scopes.rb:16:9:16:9 | c | -| scopes.rb:13:14:13:14 | ... = ... | scopes.rb:13:14:13:14 | d | scopes.rb:17:9:17:9 | d | -| scopes.rb:13:19:13:32 | ... = ... | scopes.rb:13:4:13:32 | __synth__0 | scopes.rb:13:4:13:4 | __synth__0 | -| scopes.rb:27:1:27:5 | ... = ... | scopes.rb:27:1:27:1 | x | scopes.rb:28:8:28:8 | x | +| scopes.rb:11:4:11:4 | a | scopes.rb:7:1:7:1 | a | scopes.rb:12:9:12:9 | a | +| scopes.rb:13:4:13:4 | a | scopes.rb:7:1:7:1 | a | scopes.rb:14:9:14:9 | a | +| scopes.rb:13:7:13:7 | b | scopes.rb:13:7:13:7 | b | scopes.rb:15:9:15:9 | b | +| scopes.rb:13:10:13:15 | __synth__0__1 | scopes.rb:13:10:13:15 | __synth__0__1 | scopes.rb:13:11:13:11 | __synth__0__1 | +| scopes.rb:13:11:13:11 | c | scopes.rb:13:11:13:11 | c | scopes.rb:16:9:16:9 | c | +| scopes.rb:13:14:13:14 | d | scopes.rb:13:14:13:14 | d | scopes.rb:17:9:17:9 | d | +| scopes.rb:13:19:13:32 | __synth__0 | scopes.rb:13:4:13:32 | __synth__0 | scopes.rb:13:4:13:4 | __synth__0 | +| scopes.rb:27:1:27:1 | x | scopes.rb:27:1:27:1 | x | scopes.rb:28:8:28:8 | x | | scopes.rb:41:1:49:3 | self (M) | scopes.rb:41:1:49:3 | self | scopes.rb:45:5:45:7 | self | -| scopes.rb:42:2:42:9 | ... = ... | scopes.rb:42:2:42:4 | var | scopes.rb:44:5:44:7 | var | -| scopes.rb:46:5:46:13 | ... = ... | scopes.rb:46:5:46:8 | var2 | scopes.rb:47:5:47:8 | var2 | +| scopes.rb:42:2:42:4 | var | scopes.rb:42:2:42:4 | var | scopes.rb:44:5:44:7 | var | +| scopes.rb:46:5:46:8 | var2 | scopes.rb:46:5:46:8 | var2 | scopes.rb:47:5:47:8 | var2 | | ssa.rb:1:1:16:3 | self (m) | ssa.rb:1:1:16:3 | self | ssa.rb:3:3:3:8 | self | | ssa.rb:1:7:1:7 | b | ssa.rb:1:7:1:7 | b | ssa.rb:5:6:5:6 | b | -| ssa.rb:2:3:2:7 | ... = ... | ssa.rb:2:3:2:3 | i | ssa.rb:3:8:3:8 | i | +| ssa.rb:2:3:2:3 | i | ssa.rb:2:3:2:3 | i | ssa.rb:3:8:3:8 | i | | ssa.rb:5:3:13:5 | phi | ssa.rb:2:3:2:3 | i | ssa.rb:15:8:15:8 | i | -| ssa.rb:6:5:6:9 | ... = ... | ssa.rb:2:3:2:3 | i | ssa.rb:7:10:7:10 | i | -| ssa.rb:10:5:10:9 | ... = ... | ssa.rb:2:3:2:3 | i | ssa.rb:11:10:11:10 | i | +| ssa.rb:6:5:6:5 | i | ssa.rb:2:3:2:3 | i | ssa.rb:7:10:7:10 | i | +| ssa.rb:10:5:10:5 | i | ssa.rb:2:3:2:3 | i | ssa.rb:11:10:11:10 | i | | ssa.rb:18:1:23:3 | self (m1) | ssa.rb:18:1:23:3 | self | ssa.rb:20:5:20:10 | self | | ssa.rb:19:9:19:9 | phi | ssa.rb:18:8:18:8 | x | ssa.rb:19:9:19:9 | x | | ssa.rb:25:1:30:3 | self (m2) | ssa.rb:25:1:30:3 | self | ssa.rb:29:3:29:11 | self | | ssa.rb:25:8:25:15 | elements | ssa.rb:25:8:25:15 | elements | ssa.rb:26:15:26:22 | elements | -| ssa.rb:26:3:28:5 | ... = ... | ssa.rb:26:7:26:10 | elem | ssa.rb:27:10:27:13 | elem | | ssa.rb:26:3:28:5 | <captured entry> self | ssa.rb:25:1:30:3 | self | ssa.rb:27:5:27:13 | self | | ssa.rb:26:3:28:5 | <captured exit> elem | ssa.rb:26:7:26:10 | elem | ssa.rb:29:8:29:11 | elem | | ssa.rb:26:3:28:5 | __synth__0__1 | ssa.rb:26:3:28:5 | __synth__0__1 | ssa.rb:26:3:28:5 | __synth__0__1 | +| ssa.rb:26:7:26:10 | elem | ssa.rb:26:7:26:10 | elem | ssa.rb:27:10:27:13 | elem | | ssa.rb:33:16:35:5 | <captured entry> self | ssa.rb:32:1:36:3 | self | ssa.rb:34:5:34:10 | self | | ssa.rb:33:20:33:20 | x | ssa.rb:33:20:33:20 | x | ssa.rb:34:10:34:10 | x | | ssa.rb:38:1:42:3 | self (m4) | ssa.rb:38:1:42:3 | self | ssa.rb:39:3:39:9 | self | -| ssa.rb:40:3:40:9 | ... = ... | ssa.rb:40:3:40:4 | m3 | ssa.rb:41:8:41:9 | m3 | +| ssa.rb:40:3:40:4 | m3 | ssa.rb:40:3:40:4 | m3 | ssa.rb:41:8:41:9 | m3 | | ssa.rb:44:1:47:3 | self (m5) | ssa.rb:44:1:47:3 | self | ssa.rb:46:3:46:8 | self | | ssa.rb:44:8:44:8 | b | ssa.rb:44:8:44:8 | b | ssa.rb:45:12:45:12 | b | | ssa.rb:45:3:45:12 | phi | ssa.rb:45:3:45:3 | x | ssa.rb:46:8:46:8 | x | @@ -487,10 +487,10 @@ firstRead | ssa.rb:50:3:50:8 | phi | ssa.rb:49:14:49:14 | y | ssa.rb:50:8:50:8 | y | | ssa.rb:53:1:56:3 | self (m7) | ssa.rb:53:1:56:3 | self | ssa.rb:55:3:55:8 | self | | ssa.rb:53:8:53:10 | foo | ssa.rb:53:8:53:10 | foo | ssa.rb:54:7:54:9 | foo | -| ssa.rb:54:3:54:11 | ... = ... | ssa.rb:54:3:54:3 | x | ssa.rb:55:8:55:8 | x | +| ssa.rb:54:3:54:3 | x | ssa.rb:54:3:54:3 | x | ssa.rb:55:8:55:8 | x | | ssa.rb:58:1:62:3 | self (m8) | ssa.rb:58:1:62:3 | self | ssa.rb:61:3:61:8 | self | -| ssa.rb:59:3:59:8 | ... = ... | ssa.rb:59:3:59:3 | x | ssa.rb:60:3:60:3 | x | -| ssa.rb:60:3:60:9 | ... = ... | ssa.rb:59:3:59:3 | x | ssa.rb:61:8:61:8 | x | +| ssa.rb:59:3:59:3 | x | ssa.rb:59:3:59:3 | x | ssa.rb:60:3:60:3 | x | +| ssa.rb:60:3:60:3 | x | ssa.rb:59:3:59:3 | x | ssa.rb:61:8:61:8 | x | | ssa.rb:64:1:72:3 | self (m9) | ssa.rb:64:1:72:3 | self | ssa.rb:71:3:71:15 | self | | ssa.rb:64:8:64:8 | a | ssa.rb:64:8:64:8 | a | ssa.rb:66:3:66:3 | a | | ssa.rb:66:3:70:5 | <captured exit> captured | ssa.rb:65:3:65:10 | captured | ssa.rb:71:8:71:15 | captured | @@ -512,10 +512,10 @@ firstRead | 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 | +| ssa.rb:91:3:91:3 | x | ssa.rb:91:3:91:3 | x | ssa.rb:93:10:93:10 | x | +| ssa.rb:91:3:91:3 | x | ssa.rb:91:3:91:3 | x | ssa.rb:95:10:95:10 | x | +| ssa.rb:91:3:91:3 | x | ssa.rb:91:3:91:3 | x | ssa.rb:99:10:99:10 | x | +| ssa.rb:91:3:91:3 | x | 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 | @@ -537,28 +537,28 @@ lastRead | instance_variables.rb:38:4:40:6 | self (y) | instance_variables.rb:38:4:40:6 | self | instance_variables.rb:39:6:39:7 | self | | nested_scopes.rb:1:1:3:3 | self (a) | nested_scopes.rb:1:1:3:3 | self | nested_scopes.rb:2:3:2:17 | self | | nested_scopes.rb:4:1:39:3 | self (C) | nested_scopes.rb:4:1:39:3 | self | nested_scopes.rb:38:3:38:8 | self | -| nested_scopes.rb:5:3:5:7 | ... = ... | nested_scopes.rb:5:3:5:3 | a | nested_scopes.rb:38:8:38:8 | a | +| nested_scopes.rb:5:3:5:3 | a | nested_scopes.rb:5:3:5:3 | a | nested_scopes.rb:38:8:38:8 | a | | nested_scopes.rb:6:3:37:5 | self (M) | nested_scopes.rb:6:3:37:5 | self | nested_scopes.rb:36:5:36:10 | self | -| nested_scopes.rb:7:5:7:9 | ... = ... | nested_scopes.rb:7:5:7:5 | a | nested_scopes.rb:36:10:36:10 | a | +| nested_scopes.rb:7:5:7:5 | a | nested_scopes.rb:7:5:7:5 | a | nested_scopes.rb:36:10:36:10 | a | | nested_scopes.rb:8:5:35:7 | self (N) | nested_scopes.rb:8:5:35:7 | self | nested_scopes.rb:34:7:34:12 | self | -| nested_scopes.rb:9:7:9:11 | ... = ... | nested_scopes.rb:9:7:9:7 | a | nested_scopes.rb:34:12:34:12 | a | +| nested_scopes.rb:9:7:9:7 | a | nested_scopes.rb:9:7:9:7 | a | nested_scopes.rb:34:12:34:12 | a | | nested_scopes.rb:10:7:26:9 | self (D) | nested_scopes.rb:10:7:26:9 | self | nested_scopes.rb:25:9:25:14 | self | -| nested_scopes.rb:11:9:11:13 | ... = ... | nested_scopes.rb:11:9:11:9 | a | nested_scopes.rb:25:14:25:14 | a | +| nested_scopes.rb:11:9:11:9 | a | nested_scopes.rb:11:9:11:9 | a | nested_scopes.rb:25:14:25:14 | a | | nested_scopes.rb:12:9:21:11 | self (show_a) | nested_scopes.rb:12:9:21:11 | self | nested_scopes.rb:14:11:14:16 | self | -| nested_scopes.rb:13:11:13:15 | ... = ... | nested_scopes.rb:13:11:13:11 | a | nested_scopes.rb:15:11:15:11 | a | +| nested_scopes.rb:13:11:13:11 | a | nested_scopes.rb:13:11:13:11 | a | nested_scopes.rb:15:11:15:11 | a | | nested_scopes.rb:15:23:15:23 | a | nested_scopes.rb:15:23:15:23 | a | nested_scopes.rb:16:13:16:13 | a | -| nested_scopes.rb:17:15:17:19 | ... = ... | nested_scopes.rb:16:29:16:29 | a | nested_scopes.rb:18:15:18:15 | a | +| nested_scopes.rb:17:15:17:15 | a | nested_scopes.rb:16:29:16:29 | a | nested_scopes.rb:18:15:18:15 | a | | nested_scopes.rb:18:23:18:36 | <captured entry> a | nested_scopes.rb:16:29:16:29 | a | nested_scopes.rb:18:34:18:34 | a | | nested_scopes.rb:18:23:18:36 | <captured entry> self | nested_scopes.rb:12:9:21:11 | self | nested_scopes.rb:18:29:18:34 | self | | nested_scopes.rb:22:9:24:11 | self (show_a2) | nested_scopes.rb:22:9:24:11 | self | nested_scopes.rb:23:11:23:16 | self | | nested_scopes.rb:22:21:22:21 | a | nested_scopes.rb:22:21:22:21 | a | nested_scopes.rb:23:16:23:16 | a | | nested_scopes.rb:27:7:29:9 | self (show) | nested_scopes.rb:27:7:29:9 | self | nested_scopes.rb:28:16:28:16 | self | | nested_scopes.rb:30:16:30:19 | self (class << ...) | nested_scopes.rb:30:7:33:9 | self | nested_scopes.rb:32:11:32:16 | self | -| nested_scopes.rb:31:11:31:16 | ... = ... | nested_scopes.rb:31:11:31:11 | a | nested_scopes.rb:32:16:32:16 | a | -| nested_scopes.rb:40:1:40:18 | ... = ... | nested_scopes.rb:40:1:40:1 | d | nested_scopes.rb:41:1:41:1 | d | +| nested_scopes.rb:31:11:31:11 | a | nested_scopes.rb:31:11:31:11 | a | nested_scopes.rb:32:16:32:16 | a | +| nested_scopes.rb:40:1:40:1 | d | nested_scopes.rb:40:1:40:1 | d | nested_scopes.rb:41:1:41:1 | d | | parameters.rb:1:9:5:3 | <captured entry> self | parameters.rb:1:1:62:1 | self | parameters.rb:4:4:4:9 | self | | parameters.rb:1:14:1:14 | x | parameters.rb:1:14:1:14 | x | parameters.rb:3:9:3:9 | x | -| parameters.rb:2:4:2:8 | ... = ... | parameters.rb:1:18:1:18 | y | parameters.rb:4:9:4:9 | y | +| parameters.rb:2:4:2:4 | y | parameters.rb:1:18:1:18 | y | parameters.rb:4:9:4:9 | y | | parameters.rb:7:1:13:3 | self (order_pizza) | parameters.rb:7:1:13:3 | self | parameters.rb:9:5:9:33 | self | | parameters.rb:7:1:13:3 | self (order_pizza) | parameters.rb:7:1:13:3 | self | parameters.rb:11:5:11:49 | self | | parameters.rb:7:17:7:22 | client | parameters.rb:7:17:7:22 | client | parameters.rb:9:25:9:30 | client | @@ -597,40 +597,40 @@ lastRead | parameters.rb:59:25:59:25 | c | parameters.rb:59:25:59:25 | c | parameters.rb:60:21:60:21 | c | | scopes.rb:1:1:49:4 | self (scopes.rb) | scopes.rb:1:1:49:4 | self | scopes.rb:8:1:8:6 | self | | scopes.rb:2:9:6:3 | <captured entry> self | scopes.rb:1:1:49:4 | self | scopes.rb:5:4:5:9 | self | -| scopes.rb:4:4:4:8 | ... = ... | scopes.rb:4:4:4:4 | a | scopes.rb:5:9:5:9 | a | -| scopes.rb:7:1:7:5 | ... = ... | scopes.rb:7:1:7:1 | a | scopes.rb:8:6:8:6 | a | +| scopes.rb:4:4:4:4 | a | scopes.rb:4:4:4:4 | a | scopes.rb:5:9:5:9 | a | +| scopes.rb:7:1:7:1 | a | scopes.rb:7:1:7:1 | a | scopes.rb:8:6:8:6 | a | | scopes.rb:9:9:18:3 | <captured entry> a | scopes.rb:7:1:7:1 | a | scopes.rb:11:4:11:4 | a | | scopes.rb:9:9:18:3 | <captured entry> self | scopes.rb:1:1:49:4 | self | scopes.rb:17:4:17:9 | self | -| scopes.rb:11:4:11:9 | ... = ... | scopes.rb:7:1:7:1 | a | scopes.rb:12:9:12:9 | a | -| scopes.rb:13:4:13:4 | ... = ... | scopes.rb:7:1:7:1 | a | scopes.rb:14:9:14:9 | a | -| scopes.rb:13:7:13:7 | ... = ... | scopes.rb:13:7:13:7 | b | scopes.rb:15:9:15:9 | b | -| scopes.rb:13:10:13:15 | ... = ... | scopes.rb:13:10:13:15 | __synth__0__1 | scopes.rb:13:14:13:14 | __synth__0__1 | -| scopes.rb:13:11:13:11 | ... = ... | scopes.rb:13:11:13:11 | c | scopes.rb:16:9:16:9 | c | -| scopes.rb:13:14:13:14 | ... = ... | scopes.rb:13:14:13:14 | d | scopes.rb:17:9:17:9 | d | -| scopes.rb:13:19:13:32 | ... = ... | scopes.rb:13:4:13:32 | __synth__0 | scopes.rb:13:10:13:15 | __synth__0 | -| scopes.rb:27:1:27:5 | ... = ... | scopes.rb:27:1:27:1 | x | scopes.rb:37:5:37:5 | x | +| scopes.rb:11:4:11:4 | a | scopes.rb:7:1:7:1 | a | scopes.rb:12:9:12:9 | a | +| scopes.rb:13:4:13:4 | a | scopes.rb:7:1:7:1 | a | scopes.rb:14:9:14:9 | a | +| scopes.rb:13:7:13:7 | b | scopes.rb:13:7:13:7 | b | scopes.rb:15:9:15:9 | b | +| scopes.rb:13:10:13:15 | __synth__0__1 | scopes.rb:13:10:13:15 | __synth__0__1 | scopes.rb:13:14:13:14 | __synth__0__1 | +| scopes.rb:13:11:13:11 | c | scopes.rb:13:11:13:11 | c | scopes.rb:16:9:16:9 | c | +| scopes.rb:13:14:13:14 | d | scopes.rb:13:14:13:14 | d | scopes.rb:17:9:17:9 | d | +| scopes.rb:13:19:13:32 | __synth__0 | scopes.rb:13:4:13:32 | __synth__0 | scopes.rb:13:10:13:15 | __synth__0 | +| scopes.rb:27:1:27:1 | x | scopes.rb:27:1:27:1 | x | scopes.rb:37:5:37:5 | x | | scopes.rb:41:1:49:3 | self (M) | scopes.rb:41:1:49:3 | self | scopes.rb:45:5:45:7 | self | -| scopes.rb:42:2:42:9 | ... = ... | scopes.rb:42:2:42:4 | var | scopes.rb:44:5:44:7 | var | -| scopes.rb:46:5:46:13 | ... = ... | scopes.rb:46:5:46:8 | var2 | scopes.rb:47:5:47:8 | var2 | +| scopes.rb:42:2:42:4 | var | scopes.rb:42:2:42:4 | var | scopes.rb:44:5:44:7 | var | +| scopes.rb:46:5:46:8 | var2 | scopes.rb:46:5:46:8 | var2 | scopes.rb:47:5:47:8 | var2 | | ssa.rb:1:1:16:3 | self (m) | ssa.rb:1:1:16:3 | self | ssa.rb:15:3:15:8 | self | | ssa.rb:1:7:1:7 | b | ssa.rb:1:7:1:7 | b | ssa.rb:5:6:5:6 | b | -| ssa.rb:2:3:2:7 | ... = ... | ssa.rb:2:3:2:3 | i | ssa.rb:4:8:4:8 | i | +| ssa.rb:2:3:2:3 | i | ssa.rb:2:3:2:3 | i | ssa.rb:4:8:4:8 | i | | ssa.rb:5:3:13:5 | phi | ssa.rb:2:3:2:3 | i | ssa.rb:15:8:15:8 | i | -| ssa.rb:6:5:6:9 | ... = ... | ssa.rb:2:3:2:3 | i | ssa.rb:8:10:8:10 | i | -| ssa.rb:10:5:10:9 | ... = ... | ssa.rb:2:3:2:3 | i | ssa.rb:12:10:12:10 | i | +| ssa.rb:6:5:6:5 | i | ssa.rb:2:3:2:3 | i | ssa.rb:8:10:8:10 | i | +| ssa.rb:10:5:10:5 | i | ssa.rb:2:3:2:3 | i | ssa.rb:12:10:12:10 | i | | ssa.rb:18:1:23:3 | self (m1) | ssa.rb:18:1:23:3 | self | ssa.rb:20:5:20:10 | self | | ssa.rb:19:9:19:9 | phi | ssa.rb:18:8:18:8 | x | ssa.rb:19:9:19:9 | x | | ssa.rb:19:9:19:9 | phi | ssa.rb:18:8:18:8 | x | ssa.rb:21:5:21:5 | x | | ssa.rb:25:1:30:3 | self (m2) | ssa.rb:25:1:30:3 | self | ssa.rb:29:3:29:11 | self | | ssa.rb:25:8:25:15 | elements | ssa.rb:25:8:25:15 | elements | ssa.rb:26:15:26:22 | elements | -| ssa.rb:26:3:28:5 | ... = ... | ssa.rb:26:7:26:10 | elem | ssa.rb:27:10:27:13 | elem | | ssa.rb:26:3:28:5 | <captured entry> self | ssa.rb:25:1:30:3 | self | ssa.rb:27:5:27:13 | self | | ssa.rb:26:3:28:5 | <captured exit> elem | ssa.rb:26:7:26:10 | elem | ssa.rb:29:8:29:11 | elem | | ssa.rb:26:3:28:5 | __synth__0__1 | ssa.rb:26:3:28:5 | __synth__0__1 | ssa.rb:26:3:28:5 | __synth__0__1 | +| ssa.rb:26:7:26:10 | elem | ssa.rb:26:7:26:10 | elem | ssa.rb:27:10:27:13 | elem | | ssa.rb:33:16:35:5 | <captured entry> self | ssa.rb:32:1:36:3 | self | ssa.rb:34:5:34:10 | self | | ssa.rb:33:20:33:20 | x | ssa.rb:33:20:33:20 | x | ssa.rb:34:10:34:10 | x | | ssa.rb:38:1:42:3 | self (m4) | ssa.rb:38:1:42:3 | self | ssa.rb:41:3:41:13 | self | -| ssa.rb:40:3:40:9 | ... = ... | ssa.rb:40:3:40:4 | m3 | ssa.rb:41:8:41:9 | m3 | +| ssa.rb:40:3:40:4 | m3 | ssa.rb:40:3:40:4 | m3 | ssa.rb:41:8:41:9 | m3 | | ssa.rb:44:1:47:3 | self (m5) | ssa.rb:44:1:47:3 | self | ssa.rb:46:3:46:8 | self | | ssa.rb:44:8:44:8 | b | ssa.rb:44:8:44:8 | b | ssa.rb:45:12:45:12 | b | | ssa.rb:45:3:45:12 | phi | ssa.rb:45:3:45:3 | x | ssa.rb:46:8:46:8 | x | @@ -638,10 +638,10 @@ lastRead | ssa.rb:50:3:50:8 | phi | ssa.rb:49:14:49:14 | y | ssa.rb:50:8:50:8 | y | | ssa.rb:53:1:56:3 | self (m7) | ssa.rb:53:1:56:3 | self | ssa.rb:55:3:55:8 | self | | ssa.rb:53:8:53:10 | foo | ssa.rb:53:8:53:10 | foo | ssa.rb:54:7:54:9 | foo | -| ssa.rb:54:3:54:11 | ... = ... | ssa.rb:54:3:54:3 | x | ssa.rb:55:8:55:8 | x | +| ssa.rb:54:3:54:3 | x | ssa.rb:54:3:54:3 | x | ssa.rb:55:8:55:8 | x | | ssa.rb:58:1:62:3 | self (m8) | ssa.rb:58:1:62:3 | self | ssa.rb:61:3:61:8 | self | -| ssa.rb:59:3:59:8 | ... = ... | ssa.rb:59:3:59:3 | x | ssa.rb:60:3:60:3 | x | -| ssa.rb:60:3:60:9 | ... = ... | ssa.rb:59:3:59:3 | x | ssa.rb:61:8:61:8 | x | +| ssa.rb:59:3:59:3 | x | ssa.rb:59:3:59:3 | x | ssa.rb:60:3:60:3 | x | +| ssa.rb:60:3:60:3 | x | ssa.rb:59:3:59:3 | x | ssa.rb:61:8:61:8 | x | | ssa.rb:64:1:72:3 | self (m9) | ssa.rb:64:1:72:3 | self | ssa.rb:71:3:71:15 | self | | ssa.rb:64:8:64:8 | a | ssa.rb:64:8:64:8 | a | ssa.rb:66:3:66:3 | a | | ssa.rb:66:3:70:5 | <captured exit> captured | ssa.rb:65:3:65:10 | captured | ssa.rb:71:8:71:15 | captured | @@ -663,10 +663,10 @@ lastRead | 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 | +| ssa.rb:91:3:91:3 | x | ssa.rb:91:3:91:3 | x | ssa.rb:93:10:93:10 | x | +| ssa.rb:91:3:91:3 | x | ssa.rb:91:3:91:3 | x | ssa.rb:95:10:95:10 | x | +| ssa.rb:91:3:91:3 | x | ssa.rb:91:3:91:3 | x | ssa.rb:99:10:99:10 | x | +| ssa.rb:91:3:91:3 | x | 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 | @@ -677,7 +677,7 @@ adjacentReads | instance_variables.rb:37:3:43:5 | self (x) | instance_variables.rb:37:3:43:5 | self | instance_variables.rb:42:4:42:7 | self | instance_variables.rb:42:6:42:7 | self | | nested_scopes.rb:8:5:35:7 | self (N) | nested_scopes.rb:8:5:35:7 | self | nested_scopes.rb:27:11:27:14 | self | nested_scopes.rb:30:16:30:19 | self | | nested_scopes.rb:8:5:35:7 | self (N) | nested_scopes.rb:8:5:35:7 | self | nested_scopes.rb:30:16:30:19 | self | nested_scopes.rb:34:7:34:12 | self | -| nested_scopes.rb:13:11:13:15 | ... = ... | nested_scopes.rb:13:11:13:11 | a | nested_scopes.rb:14:16:14:16 | a | nested_scopes.rb:15:11:15:11 | a | +| nested_scopes.rb:13:11:13:11 | a | nested_scopes.rb:13:11:13:11 | a | nested_scopes.rb:14:16:14:16 | a | nested_scopes.rb:15:11:15:11 | a | | nested_scopes.rb:27:7:29:9 | self (show) | nested_scopes.rb:27:7:29:9 | self | nested_scopes.rb:28:11:28:16 | self | nested_scopes.rb:28:16:28:16 | self | | nested_scopes.rb:30:16:30:19 | self (class << ...) | nested_scopes.rb:30:7:33:9 | self | nested_scopes.rb:30:16:30:19 | self | nested_scopes.rb:32:11:32:16 | self | | parameters.rb:1:9:5:3 | <captured entry> self | parameters.rb:1:1:62:1 | self | parameters.rb:3:4:3:9 | self | parameters.rb:4:4:4:9 | self | @@ -693,13 +693,13 @@ adjacentReads | scopes.rb:9:9:18:3 | <captured entry> self | scopes.rb:1:1:49:4 | self | scopes.rb:14:4:14:9 | self | scopes.rb:15:4:15:9 | self | | scopes.rb:9:9:18:3 | <captured entry> self | scopes.rb:1:1:49:4 | self | scopes.rb:15:4:15:9 | self | scopes.rb:16:4:16:9 | self | | scopes.rb:9:9:18:3 | <captured entry> self | scopes.rb:1:1:49:4 | self | scopes.rb:16:4:16:9 | self | scopes.rb:17:4:17:9 | self | -| scopes.rb:13:10:13:15 | ... = ... | scopes.rb:13:10:13:15 | __synth__0__1 | scopes.rb:13:11:13:11 | __synth__0__1 | scopes.rb:13:14:13:14 | __synth__0__1 | -| scopes.rb:13:19:13:32 | ... = ... | scopes.rb:13:4:13:32 | __synth__0 | scopes.rb:13:4:13:4 | __synth__0 | scopes.rb:13:7:13:7 | __synth__0 | -| scopes.rb:13:19:13:32 | ... = ... | scopes.rb:13:4:13:32 | __synth__0 | scopes.rb:13:7:13:7 | __synth__0 | scopes.rb:13:10:13:15 | __synth__0 | -| scopes.rb:27:1:27:5 | ... = ... | scopes.rb:27:1:27:1 | x | scopes.rb:28:8:28:8 | x | scopes.rb:31:10:31:10 | x | -| scopes.rb:27:1:27:5 | ... = ... | scopes.rb:27:1:27:1 | x | scopes.rb:31:10:31:10 | x | scopes.rb:34:7:34:7 | x | -| scopes.rb:27:1:27:5 | ... = ... | scopes.rb:27:1:27:1 | x | scopes.rb:34:7:34:7 | x | scopes.rb:34:14:34:14 | x | -| scopes.rb:27:1:27:5 | ... = ... | scopes.rb:27:1:27:1 | x | scopes.rb:34:14:34:14 | x | scopes.rb:37:5:37:5 | x | +| scopes.rb:13:10:13:15 | __synth__0__1 | scopes.rb:13:10:13:15 | __synth__0__1 | scopes.rb:13:11:13:11 | __synth__0__1 | scopes.rb:13:14:13:14 | __synth__0__1 | +| scopes.rb:13:19:13:32 | __synth__0 | scopes.rb:13:4:13:32 | __synth__0 | scopes.rb:13:4:13:4 | __synth__0 | scopes.rb:13:7:13:7 | __synth__0 | +| scopes.rb:13:19:13:32 | __synth__0 | scopes.rb:13:4:13:32 | __synth__0 | scopes.rb:13:7:13:7 | __synth__0 | scopes.rb:13:10:13:15 | __synth__0 | +| scopes.rb:27:1:27:1 | x | scopes.rb:27:1:27:1 | x | scopes.rb:28:8:28:8 | x | scopes.rb:31:10:31:10 | x | +| scopes.rb:27:1:27:1 | x | scopes.rb:27:1:27:1 | x | scopes.rb:31:10:31:10 | x | scopes.rb:34:7:34:7 | x | +| scopes.rb:27:1:27:1 | x | scopes.rb:27:1:27:1 | x | scopes.rb:34:7:34:7 | x | scopes.rb:34:14:34:14 | x | +| scopes.rb:27:1:27:1 | x | scopes.rb:27:1:27:1 | x | scopes.rb:34:14:34:14 | x | scopes.rb:37:5:37:5 | x | | ssa.rb:1:1:16:3 | self (m) | ssa.rb:1:1:16:3 | self | ssa.rb:3:3:3:8 | self | ssa.rb:4:3:4:12 | self | | ssa.rb:1:1:16:3 | self (m) | ssa.rb:1:1:16:3 | self | ssa.rb:4:3:4:12 | self | ssa.rb:7:5:7:10 | self | | ssa.rb:1:1:16:3 | self (m) | ssa.rb:1:1:16:3 | self | ssa.rb:4:3:4:12 | self | ssa.rb:11:5:11:10 | self | @@ -707,9 +707,9 @@ adjacentReads | ssa.rb:1:1:16:3 | self (m) | ssa.rb:1:1:16:3 | self | ssa.rb:8:5:8:14 | self | ssa.rb:15:3:15:8 | self | | ssa.rb:1:1:16:3 | self (m) | ssa.rb:1:1:16:3 | self | ssa.rb:11:5:11:10 | self | ssa.rb:12:5:12:14 | self | | ssa.rb:1:1:16:3 | self (m) | ssa.rb:1:1:16:3 | self | ssa.rb:12:5:12:14 | self | ssa.rb:15:3:15:8 | self | -| ssa.rb:2:3:2:7 | ... = ... | ssa.rb:2:3:2:3 | i | ssa.rb:3:8:3:8 | i | ssa.rb:4:8:4:8 | i | -| ssa.rb:6:5:6:9 | ... = ... | ssa.rb:2:3:2:3 | i | ssa.rb:7:10:7:10 | i | ssa.rb:8:10:8:10 | i | -| ssa.rb:10:5:10:9 | ... = ... | ssa.rb:2:3:2:3 | i | ssa.rb:11:10:11:10 | i | ssa.rb:12:10:12:10 | i | +| ssa.rb:2:3:2:3 | i | ssa.rb:2:3:2:3 | i | ssa.rb:3:8:3:8 | i | ssa.rb:4:8:4:8 | i | +| ssa.rb:6:5:6:5 | i | ssa.rb:2:3:2:3 | i | ssa.rb:7:10:7:10 | i | ssa.rb:8:10:8:10 | i | +| ssa.rb:10:5:10:5 | i | ssa.rb:2:3:2:3 | i | ssa.rb:11:10:11:10 | i | ssa.rb:12:10:12:10 | i | | ssa.rb:18:1:23:3 | self (m1) | ssa.rb:18:1:23:3 | self | ssa.rb:20:5:20:10 | self | ssa.rb:20:5:20:10 | self | | ssa.rb:19:9:19:9 | phi | ssa.rb:18:8:18:8 | x | ssa.rb:19:9:19:9 | x | ssa.rb:20:10:20:10 | x | | ssa.rb:19:9:19:9 | phi | ssa.rb:18:8:18:8 | x | ssa.rb:20:10:20:10 | x | ssa.rb:21:5:21:5 | x | @@ -721,25 +721,25 @@ adjacentReads | 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 | +| ssa.rb:91:3:91:3 | x | 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:3 | x | 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:3 | x | 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:3 | x | 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 | <uninitialized> | -| parameters.rb:37:3:37:18 | phi | parameters.rb:35:16:35:16 | b | parameters.rb:35:16:35:20 | ... = ... | +| parameters.rb:37:3:37:18 | phi | parameters.rb:35:16:35:16 | b | parameters.rb:35:16:35:16 | b | | parameters.rb:42:3:42:18 | phi | parameters.rb:40:15:40:15 | e | parameters.rb:40:1:43:3 | <uninitialized> | -| parameters.rb:42:3:42:18 | phi | parameters.rb:40:15:40:15 | e | parameters.rb:40:15:40:19 | ... = ... | +| parameters.rb:42:3:42:18 | phi | parameters.rb:40:15:40:15 | e | parameters.rb:40:15:40:15 | e | | parameters.rb:55:4:55:9 | phi | parameters.rb:53:1:53:1 | x | parameters.rb:54:9:57:3 | <captured entry> x | -| parameters.rb:55:4:55:9 | phi | parameters.rb:53:1:53:1 | x | parameters.rb:54:19:54:23 | ... = ... | -| ssa.rb:5:3:13:5 | phi | ssa.rb:2:3:2:3 | i | ssa.rb:6:5:6:9 | ... = ... | -| ssa.rb:5:3:13:5 | phi | ssa.rb:2:3:2:3 | i | ssa.rb:10:5:10:9 | ... = ... | +| parameters.rb:55:4:55:9 | phi | parameters.rb:53:1:53:1 | x | parameters.rb:54:19:54:19 | x | +| ssa.rb:5:3:13:5 | phi | ssa.rb:2:3:2:3 | i | ssa.rb:6:5:6:5 | i | +| ssa.rb:5:3:13:5 | phi | ssa.rb:2:3:2:3 | i | ssa.rb:10:5:10:5 | i | | ssa.rb:19:9:19:9 | phi | ssa.rb:18:8:18:8 | x | ssa.rb:18:8:18:8 | x | -| ssa.rb:19:9:19:9 | phi | ssa.rb:18:8:18:8 | x | ssa.rb:21:5:21:10 | ... = ... | +| ssa.rb:19:9:19:9 | phi | ssa.rb:18:8:18:8 | x | ssa.rb:21:5:21:5 | x | | ssa.rb:45:3:45:12 | phi | ssa.rb:45:3:45:3 | x | ssa.rb:44:1:47:3 | <uninitialized> | -| ssa.rb:45:3:45:12 | phi | ssa.rb:45:3:45:3 | x | ssa.rb:45:3:45:7 | ... = ... | +| ssa.rb:45:3:45:12 | phi | ssa.rb:45:3:45:3 | x | ssa.rb:45:3:45:3 | x | | ssa.rb:50:3:50:8 | phi | ssa.rb:49:14:49:14 | y | ssa.rb:49:1:51:3 | <uninitialized> | -| ssa.rb:50:3:50:8 | phi | ssa.rb:49:14:49:14 | y | ssa.rb:49:14:49:19 | ... = ... | +| ssa.rb:50:3:50:8 | phi | ssa.rb:49:14:49:14 | y | ssa.rb:49:14:49:14 | y | 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 | @@ -763,7 +763,7 @@ phiReadInput | 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:91:3:91:3 | x | | 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 | ... = ... | +| ssa.rb:94:3:95:10 | SSA phi read(x) | ssa.rb:91:3:91:3 | x | diff --git a/ruby/ql/test/query-tests/experimental/TemplateInjection/TemplateInjection.expected b/ruby/ql/test/query-tests/experimental/TemplateInjection/TemplateInjection.expected index 7f7e0a5bbe4..a3e20d71b20 100644 --- a/ruby/ql/test/query-tests/experimental/TemplateInjection/TemplateInjection.expected +++ b/ruby/ql/test/query-tests/experimental/TemplateInjection/TemplateInjection.expected @@ -1,30 +1,36 @@ edges +| ErbInjection.rb:5:5:5:8 | name : | ErbInjection.rb:8:5:8:12 | bad_text : | +| ErbInjection.rb:5:5:5:8 | name : | ErbInjection.rb:11:11:11:14 | name : | | ErbInjection.rb:5:12:5:17 | call to params : | ErbInjection.rb:5:12:5:24 | ...[...] : | -| ErbInjection.rb:5:12:5:24 | ...[...] : | ErbInjection.rb:11:11:11:14 | name : | -| ErbInjection.rb:5:12:5:24 | ...[...] : | ErbInjection.rb:15:24:15:31 | bad_text | -| ErbInjection.rb:8:16:11:14 | ... % ... : | ErbInjection.rb:15:24:15:31 | bad_text | +| ErbInjection.rb:5:12:5:24 | ...[...] : | ErbInjection.rb:5:5:5:8 | name : | +| ErbInjection.rb:8:5:8:12 | bad_text : | ErbInjection.rb:15:24:15:31 | bad_text | +| ErbInjection.rb:8:16:11:14 | ... % ... : | ErbInjection.rb:8:5:8:12 | bad_text : | | ErbInjection.rb:11:11:11:14 | name : | ErbInjection.rb:8:16:11:14 | ... % ... : | +| SlimInjection.rb:5:5:5:8 | name : | SlimInjection.rb:8:5:8:12 | bad_text : | +| SlimInjection.rb:5:5:5:8 | name : | SlimInjection.rb:11:11:11:14 | name : | +| SlimInjection.rb:5:5:5:8 | name : | SlimInjection.rb:17:5:17:13 | bad2_text : | | SlimInjection.rb:5:12:5:17 | call to params : | SlimInjection.rb:5:12:5:24 | ...[...] : | -| SlimInjection.rb:5:12:5:24 | ...[...] : | SlimInjection.rb:8:5:11:14 | ... = ... : | -| SlimInjection.rb:5:12:5:24 | ...[...] : | SlimInjection.rb:11:11:11:14 | name : | -| SlimInjection.rb:5:12:5:24 | ...[...] : | SlimInjection.rb:17:5:20:7 | ... = ... : | -| SlimInjection.rb:8:5:11:14 | ... = ... : | SlimInjection.rb:14:25:14:32 | bad_text | -| SlimInjection.rb:8:16:11:14 | ... % ... : | SlimInjection.rb:8:5:11:14 | ... = ... : | +| SlimInjection.rb:5:12:5:24 | ...[...] : | SlimInjection.rb:5:5:5:8 | name : | +| SlimInjection.rb:8:5:8:12 | bad_text : | SlimInjection.rb:14:25:14:32 | bad_text | +| SlimInjection.rb:8:16:11:14 | ... % ... : | SlimInjection.rb:8:5:8:12 | bad_text : | | SlimInjection.rb:11:11:11:14 | name : | SlimInjection.rb:8:16:11:14 | ... % ... : | -| SlimInjection.rb:17:5:20:7 | ... = ... : | SlimInjection.rb:23:25:23:33 | bad2_text | +| SlimInjection.rb:17:5:17:13 | bad2_text : | SlimInjection.rb:23:25:23:33 | bad2_text | nodes +| ErbInjection.rb:5:5:5:8 | name : | semmle.label | name : | | ErbInjection.rb:5:12:5:17 | call to params : | semmle.label | call to params : | | ErbInjection.rb:5:12:5:24 | ...[...] : | semmle.label | ...[...] : | +| ErbInjection.rb:8:5:8:12 | bad_text : | semmle.label | bad_text : | | ErbInjection.rb:8:16:11:14 | ... % ... : | semmle.label | ... % ... : | | ErbInjection.rb:11:11:11:14 | name : | semmle.label | name : | | ErbInjection.rb:15:24:15:31 | bad_text | semmle.label | bad_text | +| SlimInjection.rb:5:5:5:8 | name : | semmle.label | name : | | SlimInjection.rb:5:12:5:17 | call to params : | semmle.label | call to params : | | SlimInjection.rb:5:12:5:24 | ...[...] : | semmle.label | ...[...] : | -| SlimInjection.rb:8:5:11:14 | ... = ... : | semmle.label | ... = ... : | +| SlimInjection.rb:8:5:8:12 | bad_text : | semmle.label | bad_text : | | SlimInjection.rb:8:16:11:14 | ... % ... : | semmle.label | ... % ... : | | SlimInjection.rb:11:11:11:14 | name : | semmle.label | name : | | SlimInjection.rb:14:25:14:32 | bad_text | semmle.label | bad_text | -| SlimInjection.rb:17:5:20:7 | ... = ... : | semmle.label | ... = ... : | +| SlimInjection.rb:17:5:17:13 | bad2_text : | semmle.label | bad2_text : | | SlimInjection.rb:23:25:23:33 | bad2_text | semmle.label | bad2_text | subpaths #select diff --git a/ruby/ql/test/query-tests/experimental/cwe-022-ZipSlip/ZipSlip.expected b/ruby/ql/test/query-tests/experimental/cwe-022-ZipSlip/ZipSlip.expected index 4b7ace007ed..ca200083a96 100644 --- a/ruby/ql/test/query-tests/experimental/cwe-022-ZipSlip/ZipSlip.expected +++ b/ruby/ql/test/query-tests/experimental/cwe-022-ZipSlip/ZipSlip.expected @@ -1,5 +1,6 @@ edges -| zip_slip.rb:8:15:8:54 | call to new : | zip_slip.rb:9:5:9:11 | tarfile : | +| zip_slip.rb:8:5:8:11 | tarfile : | zip_slip.rb:9:5:9:11 | tarfile : | +| zip_slip.rb:8:15:8:54 | call to new : | zip_slip.rb:8:5:8:11 | tarfile : | | zip_slip.rb:9:5:9:11 | tarfile : | zip_slip.rb:9:22:9:26 | entry : | | zip_slip.rb:9:22:9:26 | entry : | zip_slip.rb:10:19:10:33 | call to full_name | | zip_slip.rb:20:50:20:56 | tarfile : | zip_slip.rb:21:7:21:13 | tarfile : | @@ -10,15 +11,20 @@ edges | zip_slip.rb:56:30:56:37 | zip_file : | zip_slip.rb:57:7:57:14 | zip_file : | | zip_slip.rb:57:7:57:14 | zip_file : | zip_slip.rb:57:25:57:29 | entry : | | zip_slip.rb:57:25:57:29 | entry : | zip_slip.rb:58:19:58:28 | call to name | -| zip_slip.rb:90:12:90:54 | call to open : | zip_slip.rb:91:11:91:14 | gzip : | +| zip_slip.rb:90:5:90:8 | gzip : | zip_slip.rb:91:11:91:14 | gzip : | +| zip_slip.rb:90:12:90:54 | call to open : | zip_slip.rb:90:5:90:8 | gzip : | | zip_slip.rb:91:11:91:14 | gzip : | zip_slip.rb:97:42:97:56 | compressed_file : | | zip_slip.rb:97:42:97:56 | compressed_file : | zip_slip.rb:98:7:98:21 | compressed_file : | | zip_slip.rb:98:7:98:21 | compressed_file : | zip_slip.rb:98:32:98:36 | entry : | -| zip_slip.rb:98:32:98:36 | entry : | zip_slip.rb:100:21:100:30 | entry_path | -| zip_slip.rb:123:12:123:34 | call to new : | zip_slip.rb:124:7:124:8 | gz : | +| zip_slip.rb:98:32:98:36 | entry : | zip_slip.rb:99:9:99:18 | entry_path : | +| zip_slip.rb:99:9:99:18 | entry_path : | zip_slip.rb:100:21:100:30 | entry_path | +| zip_slip.rb:123:7:123:8 | gz : | zip_slip.rb:124:7:124:8 | gz : | +| zip_slip.rb:123:12:123:34 | call to new : | zip_slip.rb:123:7:123:8 | gz : | | zip_slip.rb:124:7:124:8 | gz : | zip_slip.rb:124:19:124:23 | entry : | -| zip_slip.rb:124:19:124:23 | entry : | zip_slip.rb:126:21:126:30 | entry_path | +| zip_slip.rb:124:19:124:23 | entry : | zip_slip.rb:125:9:125:18 | entry_path : | +| zip_slip.rb:125:9:125:18 | entry_path : | zip_slip.rb:126:21:126:30 | entry_path | nodes +| zip_slip.rb:8:5:8:11 | tarfile : | semmle.label | tarfile : | | zip_slip.rb:8:15:8:54 | call to new : | semmle.label | call to new : | | zip_slip.rb:9:5:9:11 | tarfile : | semmle.label | tarfile : | | zip_slip.rb:9:22:9:26 | entry : | semmle.label | entry : | @@ -34,15 +40,19 @@ nodes | zip_slip.rb:57:7:57:14 | zip_file : | semmle.label | zip_file : | | zip_slip.rb:57:25:57:29 | entry : | semmle.label | entry : | | zip_slip.rb:58:19:58:28 | call to name | semmle.label | call to name | +| zip_slip.rb:90:5:90:8 | gzip : | semmle.label | gzip : | | zip_slip.rb:90:12:90:54 | call to open : | semmle.label | call to open : | | zip_slip.rb:91:11:91:14 | gzip : | semmle.label | gzip : | | zip_slip.rb:97:42:97:56 | compressed_file : | semmle.label | compressed_file : | | zip_slip.rb:98:7:98:21 | compressed_file : | semmle.label | compressed_file : | | zip_slip.rb:98:32:98:36 | entry : | semmle.label | entry : | +| zip_slip.rb:99:9:99:18 | entry_path : | semmle.label | entry_path : | | zip_slip.rb:100:21:100:30 | entry_path | semmle.label | entry_path | +| zip_slip.rb:123:7:123:8 | gz : | semmle.label | gz : | | zip_slip.rb:123:12:123:34 | call to new : | semmle.label | call to new : | | zip_slip.rb:124:7:124:8 | gz : | semmle.label | gz : | | zip_slip.rb:124:19:124:23 | entry : | semmle.label | entry : | +| zip_slip.rb:125:9:125:18 | entry_path : | semmle.label | entry_path : | | zip_slip.rb:126:21:126:30 | entry_path | semmle.label | entry_path | subpaths #select diff --git a/ruby/ql/test/query-tests/experimental/manually-check-http-verb/ManuallyCheckHttpVerb.expected b/ruby/ql/test/query-tests/experimental/manually-check-http-verb/ManuallyCheckHttpVerb.expected index b7dff706a1f..b43c529946f 100644 --- a/ruby/ql/test/query-tests/experimental/manually-check-http-verb/ManuallyCheckHttpVerb.expected +++ b/ruby/ql/test/query-tests/experimental/manually-check-http-verb/ManuallyCheckHttpVerb.expected @@ -1,22 +1,32 @@ edges +| ManuallyCheckHttpVerb.rb:11:5:11:10 | method : | ManuallyCheckHttpVerb.rb:12:8:12:22 | ... == ... | | ManuallyCheckHttpVerb.rb:11:14:11:24 | call to env : | ManuallyCheckHttpVerb.rb:11:14:11:42 | ...[...] : | -| ManuallyCheckHttpVerb.rb:11:14:11:42 | ...[...] : | ManuallyCheckHttpVerb.rb:12:8:12:22 | ... == ... | -| ManuallyCheckHttpVerb.rb:19:14:19:35 | call to request_method : | ManuallyCheckHttpVerb.rb:20:8:20:22 | ... == ... | -| ManuallyCheckHttpVerb.rb:27:14:27:27 | call to method : | ManuallyCheckHttpVerb.rb:28:8:28:22 | ... == ... | -| ManuallyCheckHttpVerb.rb:35:14:35:39 | call to raw_request_method : | ManuallyCheckHttpVerb.rb:36:8:36:22 | ... == ... | -| ManuallyCheckHttpVerb.rb:51:16:51:44 | call to request_method_symbol : | ManuallyCheckHttpVerb.rb:52:10:52:23 | ... == ... | +| ManuallyCheckHttpVerb.rb:11:14:11:42 | ...[...] : | ManuallyCheckHttpVerb.rb:11:5:11:10 | method : | +| ManuallyCheckHttpVerb.rb:19:5:19:10 | method : | ManuallyCheckHttpVerb.rb:20:8:20:22 | ... == ... | +| ManuallyCheckHttpVerb.rb:19:14:19:35 | call to request_method : | ManuallyCheckHttpVerb.rb:19:5:19:10 | method : | +| ManuallyCheckHttpVerb.rb:27:5:27:10 | method : | ManuallyCheckHttpVerb.rb:28:8:28:22 | ... == ... | +| ManuallyCheckHttpVerb.rb:27:14:27:27 | call to method : | ManuallyCheckHttpVerb.rb:27:5:27:10 | method : | +| ManuallyCheckHttpVerb.rb:35:5:35:10 | method : | ManuallyCheckHttpVerb.rb:36:8:36:22 | ... == ... | +| ManuallyCheckHttpVerb.rb:35:14:35:39 | call to raw_request_method : | ManuallyCheckHttpVerb.rb:35:5:35:10 | method : | +| ManuallyCheckHttpVerb.rb:51:7:51:12 | method : | ManuallyCheckHttpVerb.rb:52:10:52:23 | ... == ... | +| ManuallyCheckHttpVerb.rb:51:16:51:44 | call to request_method_symbol : | ManuallyCheckHttpVerb.rb:51:7:51:12 | method : | | ManuallyCheckHttpVerb.rb:59:10:59:20 | call to env : | ManuallyCheckHttpVerb.rb:59:10:59:38 | ...[...] | nodes | ManuallyCheckHttpVerb.rb:4:8:4:19 | call to get? | semmle.label | call to get? | +| ManuallyCheckHttpVerb.rb:11:5:11:10 | method : | semmle.label | method : | | ManuallyCheckHttpVerb.rb:11:14:11:24 | call to env : | semmle.label | call to env : | | ManuallyCheckHttpVerb.rb:11:14:11:42 | ...[...] : | semmle.label | ...[...] : | | ManuallyCheckHttpVerb.rb:12:8:12:22 | ... == ... | semmle.label | ... == ... | +| ManuallyCheckHttpVerb.rb:19:5:19:10 | method : | semmle.label | method : | | ManuallyCheckHttpVerb.rb:19:14:19:35 | call to request_method : | semmle.label | call to request_method : | | ManuallyCheckHttpVerb.rb:20:8:20:22 | ... == ... | semmle.label | ... == ... | +| ManuallyCheckHttpVerb.rb:27:5:27:10 | method : | semmle.label | method : | | ManuallyCheckHttpVerb.rb:27:14:27:27 | call to method : | semmle.label | call to method : | | ManuallyCheckHttpVerb.rb:28:8:28:22 | ... == ... | semmle.label | ... == ... | +| ManuallyCheckHttpVerb.rb:35:5:35:10 | method : | semmle.label | method : | | ManuallyCheckHttpVerb.rb:35:14:35:39 | call to raw_request_method : | semmle.label | call to raw_request_method : | | ManuallyCheckHttpVerb.rb:36:8:36:22 | ... == ... | semmle.label | ... == ... | +| ManuallyCheckHttpVerb.rb:51:7:51:12 | method : | semmle.label | method : | | ManuallyCheckHttpVerb.rb:51:16:51:44 | call to request_method_symbol : | semmle.label | call to request_method_symbol : | | ManuallyCheckHttpVerb.rb:52:10:52:23 | ... == ... | semmle.label | ... == ... | | ManuallyCheckHttpVerb.rb:59:10:59:20 | call to env : | semmle.label | call to env : | diff --git a/ruby/ql/test/query-tests/security/cwe-022/PathInjection.expected b/ruby/ql/test/query-tests/security/cwe-022/PathInjection.expected index 5e05271252e..7d5598d1d49 100644 --- a/ruby/ql/test/query-tests/security/cwe-022/PathInjection.expected +++ b/ruby/ql/test/query-tests/security/cwe-022/PathInjection.expected @@ -6,48 +6,62 @@ edges | ArchiveApiPathTraversal.rb:15:9:15:14 | call to params : | ArchiveApiPathTraversal.rb:15:9:15:25 | ...[...] : | | ArchiveApiPathTraversal.rb:15:9:15:25 | ...[...] : | ArchiveApiPathTraversal.rb:75:11:75:18 | filename : | | ArchiveApiPathTraversal.rb:49:17:49:27 | destination : | ArchiveApiPathTraversal.rb:52:38:52:48 | destination : | -| ArchiveApiPathTraversal.rb:52:28:52:67 | call to join : | ArchiveApiPathTraversal.rb:59:21:59:36 | destination_file | +| ArchiveApiPathTraversal.rb:52:9:52:24 | destination_file : | ArchiveApiPathTraversal.rb:59:21:59:36 | destination_file | +| ArchiveApiPathTraversal.rb:52:28:52:67 | call to join : | ArchiveApiPathTraversal.rb:52:9:52:24 | destination_file : | | ArchiveApiPathTraversal.rb:52:38:52:48 | destination : | ArchiveApiPathTraversal.rb:52:28:52:67 | call to join : | | ArchiveApiPathTraversal.rb:67:13:67:16 | file : | ArchiveApiPathTraversal.rb:68:20:68:23 | file | | ArchiveApiPathTraversal.rb:75:11:75:18 | filename : | ArchiveApiPathTraversal.rb:76:19:76:26 | filename | +| tainted_path.rb:4:5:4:8 | path : | tainted_path.rb:5:26:5:29 | path | | tainted_path.rb:4:12:4:17 | call to params : | tainted_path.rb:4:12:4:24 | ...[...] : | -| tainted_path.rb:4:12:4:24 | ...[...] : | tainted_path.rb:5:26:5:29 | path | -| tainted_path.rb:10:12:10:43 | call to absolute_path : | tainted_path.rb:11:26:11:29 | path | +| tainted_path.rb:4:12:4:24 | ...[...] : | tainted_path.rb:4:5:4:8 | path : | +| tainted_path.rb:10:5:10:8 | path : | tainted_path.rb:11:26:11:29 | path | +| tainted_path.rb:10:12:10:43 | call to absolute_path : | tainted_path.rb:10:5:10:8 | path : | | tainted_path.rb:10:31:10:36 | call to params : | tainted_path.rb:10:31:10:43 | ...[...] : | | tainted_path.rb:10:31:10:43 | ...[...] : | tainted_path.rb:10:12:10:43 | call to absolute_path : | -| tainted_path.rb:16:15:16:41 | call to dirname : | tainted_path.rb:17:26:17:29 | path | +| tainted_path.rb:16:5:16:8 | path : | tainted_path.rb:17:26:17:29 | path | +| tainted_path.rb:16:15:16:41 | call to dirname : | tainted_path.rb:16:5:16:8 | path : | | tainted_path.rb:16:28:16:33 | call to params : | tainted_path.rb:16:28:16:40 | ...[...] : | | tainted_path.rb:16:28:16:40 | ...[...] : | tainted_path.rb:16:15:16:41 | call to dirname : | -| tainted_path.rb:22:12:22:41 | call to expand_path : | tainted_path.rb:23:26:23:29 | path | +| tainted_path.rb:22:5:22:8 | path : | tainted_path.rb:23:26:23:29 | path | +| tainted_path.rb:22:12:22:41 | call to expand_path : | tainted_path.rb:22:5:22:8 | path : | | tainted_path.rb:22:29:22:34 | call to params : | tainted_path.rb:22:29:22:41 | ...[...] : | | tainted_path.rb:22:29:22:41 | ...[...] : | tainted_path.rb:22:12:22:41 | call to expand_path : | -| tainted_path.rb:28:12:28:34 | call to path : | tainted_path.rb:29:26:29:29 | path | +| tainted_path.rb:28:5:28:8 | path : | tainted_path.rb:29:26:29:29 | path | +| tainted_path.rb:28:12:28:34 | call to path : | tainted_path.rb:28:5:28:8 | path : | | tainted_path.rb:28:22:28:27 | call to params : | tainted_path.rb:28:22:28:34 | ...[...] : | | tainted_path.rb:28:22:28:34 | ...[...] : | tainted_path.rb:28:12:28:34 | call to path : | -| tainted_path.rb:34:12:34:41 | call to realdirpath : | tainted_path.rb:35:26:35:29 | path | +| tainted_path.rb:34:5:34:8 | path : | tainted_path.rb:35:26:35:29 | path | +| tainted_path.rb:34:12:34:41 | call to realdirpath : | tainted_path.rb:34:5:34:8 | path : | | tainted_path.rb:34:29:34:34 | call to params : | tainted_path.rb:34:29:34:41 | ...[...] : | | tainted_path.rb:34:29:34:41 | ...[...] : | tainted_path.rb:34:12:34:41 | call to realdirpath : | -| tainted_path.rb:40:12:40:38 | call to realpath : | tainted_path.rb:41:26:41:29 | path | +| tainted_path.rb:40:5:40:8 | path : | tainted_path.rb:41:26:41:29 | path | +| tainted_path.rb:40:12:40:38 | call to realpath : | tainted_path.rb:40:5:40:8 | path : | | tainted_path.rb:40:26:40:31 | call to params : | tainted_path.rb:40:26:40:38 | ...[...] : | | tainted_path.rb:40:26:40:38 | ...[...] : | tainted_path.rb:40:12:40:38 | call to realpath : | -| tainted_path.rb:47:12:47:63 | call to join : | tainted_path.rb:48:26:48:29 | path | +| tainted_path.rb:47:5:47:8 | path : | tainted_path.rb:48:26:48:29 | path | +| tainted_path.rb:47:12:47:63 | call to join : | tainted_path.rb:47:5:47:8 | path : | | tainted_path.rb:47:43:47:48 | call to params : | tainted_path.rb:47:43:47:55 | ...[...] : | | tainted_path.rb:47:43:47:55 | ...[...] : | tainted_path.rb:47:12:47:63 | call to join : | -| tainted_path.rb:59:12:59:53 | call to new : | tainted_path.rb:60:26:60:29 | path | +| tainted_path.rb:59:5:59:8 | path : | tainted_path.rb:60:26:60:29 | path | +| tainted_path.rb:59:12:59:53 | call to new : | tainted_path.rb:59:5:59:8 | path : | | tainted_path.rb:59:40:59:45 | call to params : | tainted_path.rb:59:40:59:52 | ...[...] : | | tainted_path.rb:59:40:59:52 | ...[...] : | tainted_path.rb:59:12:59:53 | call to new : | -| tainted_path.rb:71:12:71:53 | call to new : | tainted_path.rb:72:15:72:18 | path | +| tainted_path.rb:71:5:71:8 | path : | tainted_path.rb:72:15:72:18 | path | +| tainted_path.rb:71:12:71:53 | call to new : | tainted_path.rb:71:5:71:8 | path : | | tainted_path.rb:71:40:71:45 | call to params : | tainted_path.rb:71:40:71:52 | ...[...] : | | tainted_path.rb:71:40:71:52 | ...[...] : | tainted_path.rb:71:12:71:53 | call to new : | -| tainted_path.rb:77:12:77:53 | call to new : | tainted_path.rb:78:19:78:22 | path | -| tainted_path.rb:77:12:77:53 | call to new : | tainted_path.rb:79:14:79:17 | path | +| tainted_path.rb:77:5:77:8 | path : | tainted_path.rb:78:19:78:22 | path | +| tainted_path.rb:77:5:77:8 | path : | tainted_path.rb:79:14:79:17 | path | +| tainted_path.rb:77:12:77:53 | call to new : | tainted_path.rb:77:5:77:8 | path : | | tainted_path.rb:77:40:77:45 | call to params : | tainted_path.rb:77:40:77:52 | ...[...] : | | tainted_path.rb:77:40:77:52 | ...[...] : | tainted_path.rb:77:12:77:53 | call to new : | -| tainted_path.rb:84:12:84:53 | call to new : | tainted_path.rb:85:10:85:13 | path | -| tainted_path.rb:84:12:84:53 | call to new : | tainted_path.rb:86:25:86:28 | path | +| tainted_path.rb:84:5:84:8 | path : | tainted_path.rb:85:10:85:13 | path | +| tainted_path.rb:84:5:84:8 | path : | tainted_path.rb:86:25:86:28 | path | +| tainted_path.rb:84:12:84:53 | call to new : | tainted_path.rb:84:5:84:8 | path : | | tainted_path.rb:84:40:84:45 | call to params : | tainted_path.rb:84:40:84:52 | ...[...] : | | tainted_path.rb:84:40:84:52 | ...[...] : | tainted_path.rb:84:12:84:53 | call to new : | -| tainted_path.rb:90:12:90:53 | call to new : | tainted_path.rb:92:11:92:14 | path | +| tainted_path.rb:90:5:90:8 | path : | tainted_path.rb:92:11:92:14 | path | +| tainted_path.rb:90:12:90:53 | call to new : | tainted_path.rb:90:5:90:8 | path : | | tainted_path.rb:90:40:90:45 | call to params : | tainted_path.rb:90:40:90:52 | ...[...] : | | tainted_path.rb:90:40:90:52 | ...[...] : | tainted_path.rb:90:12:90:53 | call to new : | nodes @@ -58,6 +72,7 @@ nodes | ArchiveApiPathTraversal.rb:15:9:15:14 | call to params : | semmle.label | call to params : | | ArchiveApiPathTraversal.rb:15:9:15:25 | ...[...] : | semmle.label | ...[...] : | | ArchiveApiPathTraversal.rb:49:17:49:27 | destination : | semmle.label | destination : | +| ArchiveApiPathTraversal.rb:52:9:52:24 | destination_file : | semmle.label | destination_file : | | ArchiveApiPathTraversal.rb:52:28:52:67 | call to join : | semmle.label | call to join : | | ArchiveApiPathTraversal.rb:52:38:52:48 | destination : | semmle.label | destination : | | ArchiveApiPathTraversal.rb:59:21:59:36 | destination_file | semmle.label | destination_file | @@ -65,55 +80,68 @@ nodes | ArchiveApiPathTraversal.rb:68:20:68:23 | file | semmle.label | file | | ArchiveApiPathTraversal.rb:75:11:75:18 | filename : | semmle.label | filename : | | ArchiveApiPathTraversal.rb:76:19:76:26 | filename | semmle.label | filename | +| tainted_path.rb:4:5:4:8 | path : | semmle.label | path : | | tainted_path.rb:4:12:4:17 | call to params : | semmle.label | call to params : | | tainted_path.rb:4:12:4:24 | ...[...] : | semmle.label | ...[...] : | | tainted_path.rb:5:26:5:29 | path | semmle.label | path | +| tainted_path.rb:10:5:10:8 | path : | semmle.label | path : | | tainted_path.rb:10:12:10:43 | call to absolute_path : | semmle.label | call to absolute_path : | | tainted_path.rb:10:31:10:36 | call to params : | semmle.label | call to params : | | tainted_path.rb:10:31:10:43 | ...[...] : | semmle.label | ...[...] : | | tainted_path.rb:11:26:11:29 | path | semmle.label | path | +| tainted_path.rb:16:5:16:8 | path : | semmle.label | path : | | tainted_path.rb:16:15:16:41 | call to dirname : | semmle.label | call to dirname : | | tainted_path.rb:16:28:16:33 | call to params : | semmle.label | call to params : | | tainted_path.rb:16:28:16:40 | ...[...] : | semmle.label | ...[...] : | | tainted_path.rb:17:26:17:29 | path | semmle.label | path | +| tainted_path.rb:22:5:22:8 | path : | semmle.label | path : | | tainted_path.rb:22:12:22:41 | call to expand_path : | semmle.label | call to expand_path : | | tainted_path.rb:22:29:22:34 | call to params : | semmle.label | call to params : | | tainted_path.rb:22:29:22:41 | ...[...] : | semmle.label | ...[...] : | | tainted_path.rb:23:26:23:29 | path | semmle.label | path | +| tainted_path.rb:28:5:28:8 | path : | semmle.label | path : | | tainted_path.rb:28:12:28:34 | call to path : | semmle.label | call to path : | | tainted_path.rb:28:22:28:27 | call to params : | semmle.label | call to params : | | tainted_path.rb:28:22:28:34 | ...[...] : | semmle.label | ...[...] : | | tainted_path.rb:29:26:29:29 | path | semmle.label | path | +| tainted_path.rb:34:5:34:8 | path : | semmle.label | path : | | tainted_path.rb:34:12:34:41 | call to realdirpath : | semmle.label | call to realdirpath : | | tainted_path.rb:34:29:34:34 | call to params : | semmle.label | call to params : | | tainted_path.rb:34:29:34:41 | ...[...] : | semmle.label | ...[...] : | | tainted_path.rb:35:26:35:29 | path | semmle.label | path | +| tainted_path.rb:40:5:40:8 | path : | semmle.label | path : | | tainted_path.rb:40:12:40:38 | call to realpath : | semmle.label | call to realpath : | | tainted_path.rb:40:26:40:31 | call to params : | semmle.label | call to params : | | tainted_path.rb:40:26:40:38 | ...[...] : | semmle.label | ...[...] : | | tainted_path.rb:41:26:41:29 | path | semmle.label | path | +| tainted_path.rb:47:5:47:8 | path : | semmle.label | path : | | tainted_path.rb:47:12:47:63 | call to join : | semmle.label | call to join : | | tainted_path.rb:47:43:47:48 | call to params : | semmle.label | call to params : | | tainted_path.rb:47:43:47:55 | ...[...] : | semmle.label | ...[...] : | | tainted_path.rb:48:26:48:29 | path | semmle.label | path | +| tainted_path.rb:59:5:59:8 | path : | semmle.label | path : | | tainted_path.rb:59:12:59:53 | call to new : | semmle.label | call to new : | | tainted_path.rb:59:40:59:45 | call to params : | semmle.label | call to params : | | tainted_path.rb:59:40:59:52 | ...[...] : | semmle.label | ...[...] : | | tainted_path.rb:60:26:60:29 | path | semmle.label | path | +| tainted_path.rb:71:5:71:8 | path : | semmle.label | path : | | tainted_path.rb:71:12:71:53 | call to new : | semmle.label | call to new : | | tainted_path.rb:71:40:71:45 | call to params : | semmle.label | call to params : | | tainted_path.rb:71:40:71:52 | ...[...] : | semmle.label | ...[...] : | | tainted_path.rb:72:15:72:18 | path | semmle.label | path | +| tainted_path.rb:77:5:77:8 | path : | semmle.label | path : | | tainted_path.rb:77:12:77:53 | call to new : | semmle.label | call to new : | | tainted_path.rb:77:40:77:45 | call to params : | semmle.label | call to params : | | tainted_path.rb:77:40:77:52 | ...[...] : | semmle.label | ...[...] : | | tainted_path.rb:78:19:78:22 | path | semmle.label | path | | tainted_path.rb:79:14:79:17 | path | semmle.label | path | +| tainted_path.rb:84:5:84:8 | path : | semmle.label | path : | | tainted_path.rb:84:12:84:53 | call to new : | semmle.label | call to new : | | tainted_path.rb:84:40:84:45 | call to params : | semmle.label | call to params : | | tainted_path.rb:84:40:84:52 | ...[...] : | semmle.label | ...[...] : | | tainted_path.rb:85:10:85:13 | path | semmle.label | path | | tainted_path.rb:86:25:86:28 | path | semmle.label | path | +| tainted_path.rb:90:5:90:8 | path : | semmle.label | path : | | tainted_path.rb:90:12:90:53 | call to new : | semmle.label | call to new : | | tainted_path.rb:90:40:90:45 | call to params : | semmle.label | call to params : | | tainted_path.rb:90:40:90:52 | ...[...] : | semmle.label | ...[...] : | diff --git a/ruby/ql/test/query-tests/security/cwe-078/CommandInjection/CommandInjection.expected b/ruby/ql/test/query-tests/security/cwe-078/CommandInjection/CommandInjection.expected index dda603763e2..de8b527312e 100644 --- a/ruby/ql/test/query-tests/security/cwe-078/CommandInjection/CommandInjection.expected +++ b/ruby/ql/test/query-tests/security/cwe-078/CommandInjection/CommandInjection.expected @@ -1,25 +1,30 @@ edges +| CommandInjection.rb:6:9:6:11 | cmd : | CommandInjection.rb:7:10:7:15 | #{...} | +| CommandInjection.rb:6:9:6:11 | cmd : | CommandInjection.rb:8:16:8:18 | cmd | +| CommandInjection.rb:6:9:6:11 | cmd : | CommandInjection.rb:10:14:10:16 | cmd | +| CommandInjection.rb:6:9:6:11 | cmd : | CommandInjection.rb:11:17:11:22 | #{...} | +| CommandInjection.rb:6:9:6:11 | cmd : | CommandInjection.rb:13:9:13:14 | #{...} | +| CommandInjection.rb:6:9:6:11 | cmd : | CommandInjection.rb:29:19:29:24 | #{...} | +| CommandInjection.rb:6:9:6:11 | cmd : | CommandInjection.rb:33:24:33:36 | "echo #{...}" | +| CommandInjection.rb:6:9:6:11 | cmd : | CommandInjection.rb:34:39:34:51 | "grep #{...}" | | CommandInjection.rb:6:15:6:20 | call to params : | CommandInjection.rb:6:15:6:26 | ...[...] : | -| CommandInjection.rb:6:15:6:26 | ...[...] : | CommandInjection.rb:7:10:7:15 | #{...} | -| CommandInjection.rb:6:15:6:26 | ...[...] : | CommandInjection.rb:8:16:8:18 | cmd | -| CommandInjection.rb:6:15:6:26 | ...[...] : | CommandInjection.rb:10:14:10:16 | cmd | -| CommandInjection.rb:6:15:6:26 | ...[...] : | CommandInjection.rb:11:17:11:22 | #{...} | -| CommandInjection.rb:6:15:6:26 | ...[...] : | CommandInjection.rb:13:9:13:14 | #{...} | -| CommandInjection.rb:6:15:6:26 | ...[...] : | CommandInjection.rb:29:19:29:24 | #{...} | -| CommandInjection.rb:6:15:6:26 | ...[...] : | CommandInjection.rb:33:24:33:36 | "echo #{...}" | -| CommandInjection.rb:6:15:6:26 | ...[...] : | CommandInjection.rb:34:39:34:51 | "grep #{...}" | +| CommandInjection.rb:6:15:6:26 | ...[...] : | CommandInjection.rb:6:9:6:11 | cmd : | +| CommandInjection.rb:46:9:46:11 | cmd : | CommandInjection.rb:50:24:50:36 | "echo #{...}" | | CommandInjection.rb:46:15:46:20 | call to params : | CommandInjection.rb:46:15:46:26 | ...[...] : | -| CommandInjection.rb:46:15:46:26 | ...[...] : | CommandInjection.rb:50:24:50:36 | "echo #{...}" | +| CommandInjection.rb:46:15:46:26 | ...[...] : | CommandInjection.rb:46:9:46:11 | cmd : | +| CommandInjection.rb:54:7:54:9 | cmd : | CommandInjection.rb:59:14:59:16 | cmd | | CommandInjection.rb:54:13:54:18 | call to params : | CommandInjection.rb:54:13:54:24 | ...[...] : | -| CommandInjection.rb:54:13:54:24 | ...[...] : | CommandInjection.rb:59:14:59:16 | cmd | +| CommandInjection.rb:54:13:54:24 | ...[...] : | CommandInjection.rb:54:7:54:9 | cmd : | | CommandInjection.rb:73:18:73:23 | number : | CommandInjection.rb:74:14:74:29 | "echo #{...}" | | CommandInjection.rb:81:23:81:33 | blah_number : | CommandInjection.rb:82:14:82:34 | "echo #{...}" | | CommandInjection.rb:90:20:90:25 | **args : | CommandInjection.rb:91:22:91:25 | args : | | CommandInjection.rb:91:22:91:25 | args : | CommandInjection.rb:91:22:91:37 | ...[...] : | | CommandInjection.rb:91:22:91:37 | ...[...] : | CommandInjection.rb:91:14:91:39 | "echo #{...}" | +| CommandInjection.rb:103:9:103:12 | file : | CommandInjection.rb:104:16:104:28 | "cat #{...}" | | CommandInjection.rb:103:16:103:21 | call to params : | CommandInjection.rb:103:16:103:28 | ...[...] : | -| CommandInjection.rb:103:16:103:28 | ...[...] : | CommandInjection.rb:104:16:104:28 | "cat #{...}" | +| CommandInjection.rb:103:16:103:28 | ...[...] : | CommandInjection.rb:103:9:103:12 | file : | nodes +| CommandInjection.rb:6:9:6:11 | cmd : | semmle.label | cmd : | | CommandInjection.rb:6:15:6:20 | call to params : | semmle.label | call to params : | | CommandInjection.rb:6:15:6:26 | ...[...] : | semmle.label | ...[...] : | | CommandInjection.rb:7:10:7:15 | #{...} | semmle.label | #{...} | @@ -30,9 +35,11 @@ nodes | CommandInjection.rb:29:19:29:24 | #{...} | semmle.label | #{...} | | CommandInjection.rb:33:24:33:36 | "echo #{...}" | semmle.label | "echo #{...}" | | CommandInjection.rb:34:39:34:51 | "grep #{...}" | semmle.label | "grep #{...}" | +| CommandInjection.rb:46:9:46:11 | cmd : | semmle.label | cmd : | | CommandInjection.rb:46:15:46:20 | call to params : | semmle.label | call to params : | | CommandInjection.rb:46:15:46:26 | ...[...] : | semmle.label | ...[...] : | | CommandInjection.rb:50:24:50:36 | "echo #{...}" | semmle.label | "echo #{...}" | +| CommandInjection.rb:54:7:54:9 | cmd : | semmle.label | cmd : | | CommandInjection.rb:54:13:54:18 | call to params : | semmle.label | call to params : | | CommandInjection.rb:54:13:54:24 | ...[...] : | semmle.label | ...[...] : | | CommandInjection.rb:59:14:59:16 | cmd | semmle.label | cmd | @@ -44,6 +51,7 @@ nodes | CommandInjection.rb:91:14:91:39 | "echo #{...}" | semmle.label | "echo #{...}" | | CommandInjection.rb:91:22:91:25 | args : | semmle.label | args : | | CommandInjection.rb:91:22:91:37 | ...[...] : | semmle.label | ...[...] : | +| CommandInjection.rb:103:9:103:12 | file : | semmle.label | file : | | CommandInjection.rb:103:16:103:21 | call to params : | semmle.label | call to params : | | CommandInjection.rb:103:16:103:28 | ...[...] : | semmle.label | ...[...] : | | CommandInjection.rb:104:16:104:28 | "cat #{...}" | semmle.label | "cat #{...}" | diff --git a/ruby/ql/test/query-tests/security/cwe-078/KernelOpen/KernelOpen.expected b/ruby/ql/test/query-tests/security/cwe-078/KernelOpen/KernelOpen.expected index 1a7088fcbe8..b64fd8c416f 100644 --- a/ruby/ql/test/query-tests/security/cwe-078/KernelOpen/KernelOpen.expected +++ b/ruby/ql/test/query-tests/security/cwe-078/KernelOpen/KernelOpen.expected @@ -1,17 +1,19 @@ edges +| KernelOpen.rb:3:5:3:8 | file : | KernelOpen.rb:4:10:4:13 | file | +| KernelOpen.rb:3:5:3:8 | file : | KernelOpen.rb:5:13:5:16 | file | +| KernelOpen.rb:3:5:3:8 | file : | KernelOpen.rb:6:14:6:17 | file | +| KernelOpen.rb:3:5:3:8 | file : | KernelOpen.rb:7:16:7:19 | file | +| KernelOpen.rb:3:5:3:8 | file : | KernelOpen.rb:8:17:8:20 | file | +| KernelOpen.rb:3:5:3:8 | file : | KernelOpen.rb:9:16:9:19 | file | +| KernelOpen.rb:3:5:3:8 | file : | KernelOpen.rb:10:18:10:21 | file | +| KernelOpen.rb:3:5:3:8 | file : | KernelOpen.rb:11:14:11:17 | file | +| KernelOpen.rb:3:5:3:8 | file : | KernelOpen.rb:13:23:13:26 | file : | +| KernelOpen.rb:3:5:3:8 | file : | KernelOpen.rb:26:10:26:13 | file | | KernelOpen.rb:3:12:3:17 | call to params : | KernelOpen.rb:3:12:3:24 | ...[...] : | -| KernelOpen.rb:3:12:3:24 | ...[...] : | KernelOpen.rb:4:10:4:13 | file | -| KernelOpen.rb:3:12:3:24 | ...[...] : | KernelOpen.rb:5:13:5:16 | file | -| KernelOpen.rb:3:12:3:24 | ...[...] : | KernelOpen.rb:6:14:6:17 | file | -| KernelOpen.rb:3:12:3:24 | ...[...] : | KernelOpen.rb:7:16:7:19 | file | -| KernelOpen.rb:3:12:3:24 | ...[...] : | KernelOpen.rb:8:17:8:20 | file | -| KernelOpen.rb:3:12:3:24 | ...[...] : | KernelOpen.rb:9:16:9:19 | file | -| KernelOpen.rb:3:12:3:24 | ...[...] : | KernelOpen.rb:10:18:10:21 | file | -| KernelOpen.rb:3:12:3:24 | ...[...] : | KernelOpen.rb:11:14:11:17 | file | -| KernelOpen.rb:3:12:3:24 | ...[...] : | KernelOpen.rb:13:23:13:26 | file : | -| KernelOpen.rb:3:12:3:24 | ...[...] : | KernelOpen.rb:26:10:26:13 | file | +| KernelOpen.rb:3:12:3:24 | ...[...] : | KernelOpen.rb:3:5:3:8 | file : | | KernelOpen.rb:13:23:13:26 | file : | KernelOpen.rb:13:13:13:31 | call to join | nodes +| KernelOpen.rb:3:5:3:8 | file : | semmle.label | file : | | KernelOpen.rb:3:12:3:17 | call to params : | semmle.label | call to params : | | KernelOpen.rb:3:12:3:24 | ...[...] : | semmle.label | ...[...] : | | KernelOpen.rb:4:10:4:13 | file | semmle.label | file | diff --git a/ruby/ql/test/query-tests/security/cwe-079/ReflectedXSS.expected b/ruby/ql/test/query-tests/security/cwe-079/ReflectedXSS.expected index 55e0ea7f42b..40062a572a1 100644 --- a/ruby/ql/test/query-tests/security/cwe-079/ReflectedXSS.expected +++ b/ruby/ql/test/query-tests/security/cwe-079/ReflectedXSS.expected @@ -8,9 +8,10 @@ edges | app/controllers/foo/bars_controller.rb:13:20:13:37 | ...[...] : | app/views/foo/bars/show.html.erb:50:5:50:18 | call to user_name_memo | | app/controllers/foo/bars_controller.rb:17:21:17:26 | call to params : | app/controllers/foo/bars_controller.rb:17:21:17:36 | ...[...] : | | app/controllers/foo/bars_controller.rb:17:21:17:36 | ...[...] : | app/views/foo/bars/show.html.erb:2:18:2:30 | @user_website | +| app/controllers/foo/bars_controller.rb:18:5:18:6 | dt : | app/controllers/foo/bars_controller.rb:19:22:19:23 | dt : | +| app/controllers/foo/bars_controller.rb:18:5:18:6 | dt : | app/controllers/foo/bars_controller.rb:26:53:26:54 | dt : | | app/controllers/foo/bars_controller.rb:18:10:18:15 | call to params : | app/controllers/foo/bars_controller.rb:18:10:18:22 | ...[...] : | -| app/controllers/foo/bars_controller.rb:18:10:18:22 | ...[...] : | app/controllers/foo/bars_controller.rb:19:22:19:23 | dt : | -| app/controllers/foo/bars_controller.rb:18:10:18:22 | ...[...] : | app/controllers/foo/bars_controller.rb:26:53:26:54 | dt : | +| app/controllers/foo/bars_controller.rb:18:10:18:22 | ...[...] : | app/controllers/foo/bars_controller.rb:18:5:18:6 | dt : | | app/controllers/foo/bars_controller.rb:19:22:19:23 | dt : | app/views/foo/bars/show.html.erb:40:3:40:16 | @instance_text | | app/controllers/foo/bars_controller.rb:24:39:24:44 | call to params : | app/controllers/foo/bars_controller.rb:24:39:24:59 | ...[...] : | | app/controllers/foo/bars_controller.rb:24:39:24:59 | ...[...] : | app/controllers/foo/bars_controller.rb:24:39:24:59 | ... = ... | @@ -20,8 +21,9 @@ edges | app/controllers/foo/bars_controller.rb:26:53:26:54 | dt : | app/views/foo/bars/show.html.erb:17:15:17:27 | call to local_assigns [element :display_text] : | | app/controllers/foo/bars_controller.rb:26:53:26:54 | dt : | app/views/foo/bars/show.html.erb:35:3:35:14 | call to display_text | | app/controllers/foo/bars_controller.rb:26:53:26:54 | dt : | app/views/foo/bars/show.html.erb:43:76:43:87 | call to display_text : | +| app/controllers/foo/bars_controller.rb:30:5:30:7 | str : | app/controllers/foo/bars_controller.rb:31:5:31:7 | str | | app/controllers/foo/bars_controller.rb:30:11:30:16 | call to params : | app/controllers/foo/bars_controller.rb:30:11:30:28 | ...[...] : | -| app/controllers/foo/bars_controller.rb:30:11:30:28 | ...[...] : | app/controllers/foo/bars_controller.rb:31:5:31:7 | str | +| app/controllers/foo/bars_controller.rb:30:11:30:28 | ...[...] : | app/controllers/foo/bars_controller.rb:30:5:30:7 | str : | | app/views/foo/bars/_widget.html.erb:8:9:8:21 | call to local_assigns [element :display_text] : | app/views/foo/bars/_widget.html.erb:8:9:8:36 | ...[...] | | app/views/foo/bars/show.html.erb:8:9:8:21 | call to local_assigns [element :display_text] : | app/views/foo/bars/show.html.erb:8:9:8:36 | ...[...] | | app/views/foo/bars/show.html.erb:12:9:12:21 | call to local_assigns [element :display_text] : | app/views/foo/bars/show.html.erb:12:9:12:26 | ...[...] | @@ -41,6 +43,7 @@ nodes | app/controllers/foo/bars_controller.rb:13:20:13:37 | ...[...] : | semmle.label | ...[...] : | | app/controllers/foo/bars_controller.rb:17:21:17:26 | call to params : | semmle.label | call to params : | | app/controllers/foo/bars_controller.rb:17:21:17:36 | ...[...] : | semmle.label | ...[...] : | +| app/controllers/foo/bars_controller.rb:18:5:18:6 | dt : | semmle.label | dt : | | app/controllers/foo/bars_controller.rb:18:10:18:15 | call to params : | semmle.label | call to params : | | app/controllers/foo/bars_controller.rb:18:10:18:22 | ...[...] : | semmle.label | ...[...] : | | app/controllers/foo/bars_controller.rb:19:22:19:23 | dt : | semmle.label | dt : | @@ -48,6 +51,7 @@ nodes | app/controllers/foo/bars_controller.rb:24:39:24:59 | ... = ... | semmle.label | ... = ... | | app/controllers/foo/bars_controller.rb:24:39:24:59 | ...[...] : | semmle.label | ...[...] : | | app/controllers/foo/bars_controller.rb:26:53:26:54 | dt : | semmle.label | dt : | +| app/controllers/foo/bars_controller.rb:30:5:30:7 | str : | semmle.label | str : | | app/controllers/foo/bars_controller.rb:30:11:30:16 | call to params : | semmle.label | call to params : | | app/controllers/foo/bars_controller.rb:30:11:30:28 | ...[...] : | semmle.label | ...[...] : | | app/controllers/foo/bars_controller.rb:31:5:31:7 | str | semmle.label | str | 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 3edc843ea2f..01a48d43371 100644 --- a/ruby/ql/test/query-tests/security/cwe-079/StoredXSS.expected +++ b/ruby/ql/test/query-tests/security/cwe-079/StoredXSS.expected @@ -1,6 +1,7 @@ edges -| app/controllers/foo/stores_controller.rb:8:10:8:29 | call to read : | app/controllers/foo/stores_controller.rb:9:22:9:23 | dt : | -| app/controllers/foo/stores_controller.rb:8:10:8:29 | call to read : | app/controllers/foo/stores_controller.rb:13:55:13:56 | dt : | +| app/controllers/foo/stores_controller.rb:8:5:8:6 | dt : | app/controllers/foo/stores_controller.rb:9:22:9:23 | dt : | +| app/controllers/foo/stores_controller.rb:8:5:8:6 | dt : | app/controllers/foo/stores_controller.rb:13:55:13:56 | dt : | +| app/controllers/foo/stores_controller.rb:8:10:8:29 | call to read : | app/controllers/foo/stores_controller.rb:8:5:8:6 | dt : | | app/controllers/foo/stores_controller.rb:9:22:9:23 | dt : | app/views/foo/stores/show.html.erb:37:3:37:16 | @instance_text | | app/controllers/foo/stores_controller.rb:12:28:12:48 | call to raw_name : | app/views/foo/stores/show.html.erb:82:5:82:24 | @other_user_raw_name | | app/controllers/foo/stores_controller.rb:13:55:13:56 | dt : | app/views/foo/stores/show.html.erb:2:9:2:20 | call to display_text | @@ -18,6 +19,7 @@ edges | app/views/foo/stores/show.html.erb:40:76:40:87 | call to display_text : | app/views/foo/stores/show.html.erb:40:64:40:87 | ... + ... : | | app/views/foo/stores/show.html.erb:86:17:86:28 | call to handle : | app/views/foo/stores/show.html.erb:86:3:86:29 | call to sprintf | nodes +| app/controllers/foo/stores_controller.rb:8:5:8:6 | dt : | semmle.label | dt : | | 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 : | | app/controllers/foo/stores_controller.rb:12:28:12:48 | call to raw_name : | semmle.label | call to raw_name : | 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 cac3c53820c..a41722107d6 100644 --- a/ruby/ql/test/query-tests/security/cwe-089/SqlInjection.expected +++ b/ruby/ql/test/query-tests/security/cwe-089/SqlInjection.expected @@ -28,16 +28,21 @@ edges | ActiveRecordInjection.rb:92:21:92:26 | call to params : | ActiveRecordInjection.rb:92:21:92:35 | ...[...] | | ActiveRecordInjection.rb:94:18:94:23 | call to params : | ActiveRecordInjection.rb:94:18:94:35 | ...[...] | | ActiveRecordInjection.rb:96:23:96:28 | call to params : | ActiveRecordInjection.rb:96:23:96:47 | ...[...] | -| ActiveRecordInjection.rb:102:10:102:15 | call to params : | ActiveRecordInjection.rb:103:11:103:12 | ps : | +| ActiveRecordInjection.rb:102:5:102:6 | ps : | ActiveRecordInjection.rb:103:11:103:12 | ps : | +| ActiveRecordInjection.rb:102:10:102:15 | call to params : | ActiveRecordInjection.rb:102:5:102:6 | ps : | +| ActiveRecordInjection.rb:103:5:103:7 | uid : | ActiveRecordInjection.rb:104:5:104:9 | uidEq : | | ActiveRecordInjection.rb:103:11:103:12 | ps : | ActiveRecordInjection.rb:103:11:103:17 | ...[...] : | -| ActiveRecordInjection.rb:103:11:103:17 | ...[...] : | ActiveRecordInjection.rb:108:20:108:32 | ... + ... | +| ActiveRecordInjection.rb:103:11:103:17 | ...[...] : | ActiveRecordInjection.rb:103:5:103:7 | uid : | +| ActiveRecordInjection.rb:104:5:104:9 | uidEq : | ActiveRecordInjection.rb:108:20:108:32 | ... + ... | | ActiveRecordInjection.rb:141:21:141:26 | call to params : | ActiveRecordInjection.rb:141:21:141:44 | ...[...] : | | ActiveRecordInjection.rb:141:21:141:44 | ...[...] : | ActiveRecordInjection.rb:20:22:20:30 | condition : | | ActiveRecordInjection.rb:155:59:155:64 | call to params : | ActiveRecordInjection.rb:155:59:155:74 | ...[...] : | | ActiveRecordInjection.rb:155:59:155:74 | ...[...] : | ActiveRecordInjection.rb:155:27:155:76 | "this is an unsafe annotation:..." | -| ActiveRecordInjection.rb:166:17:166:32 | call to permitted_params : | ActiveRecordInjection.rb:167:47:167:55 | my_params : | +| ActiveRecordInjection.rb:166:5:166:13 | my_params : | ActiveRecordInjection.rb:167:47:167:55 | my_params : | +| ActiveRecordInjection.rb:166:17:166:32 | call to permitted_params : | ActiveRecordInjection.rb:166:5:166:13 | my_params : | +| ActiveRecordInjection.rb:167:5:167:9 | query : | ActiveRecordInjection.rb:168:37:168:41 | query | | ActiveRecordInjection.rb:167:47:167:55 | my_params : | ActiveRecordInjection.rb:167:47:167:65 | ...[...] : | -| ActiveRecordInjection.rb:167:47:167:65 | ...[...] : | ActiveRecordInjection.rb:168:37:168:41 | query | +| ActiveRecordInjection.rb:167:47:167:65 | ...[...] : | ActiveRecordInjection.rb:167:5:167:9 | query : | | ActiveRecordInjection.rb:173:5:173:10 | call to params : | ActiveRecordInjection.rb:173:5:173:27 | call to require : | | ActiveRecordInjection.rb:173:5:173:27 | call to require : | ActiveRecordInjection.rb:173:5:173:59 | call to permit : | | ActiveRecordInjection.rb:173:5:173:59 | call to permit : | ActiveRecordInjection.rb:166:17:166:32 | call to permitted_params : | @@ -47,8 +52,9 @@ edges | ActiveRecordInjection.rb:177:77:177:102 | ...[...] : | ActiveRecordInjection.rb:177:43:177:104 | "SELECT * FROM users WHERE id ..." | | ActiveRecordInjection.rb:178:69:178:84 | call to permitted_params : | ActiveRecordInjection.rb:178:69:178:94 | ...[...] : | | ActiveRecordInjection.rb:178:69:178:94 | ...[...] : | ActiveRecordInjection.rb:178:35:178:96 | "SELECT * FROM users WHERE id ..." | +| ArelInjection.rb:4:5:4:8 | name : | ArelInjection.rb:6:20:6:61 | "SELECT * FROM users WHERE nam..." | | 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..." | +| ArelInjection.rb:4:12:4:29 | ...[...] : | ArelInjection.rb:4:5:4:8 | name : | nodes | ActiveRecordInjection.rb:8:25:8:28 | name : | semmle.label | name : | | ActiveRecordInjection.rb:8:31:8:34 | pass : | semmle.label | pass : | @@ -96,16 +102,21 @@ nodes | ActiveRecordInjection.rb:94:18:94:35 | ...[...] | semmle.label | ...[...] | | ActiveRecordInjection.rb:96:23:96:28 | call to params : | semmle.label | call to params : | | ActiveRecordInjection.rb:96:23:96:47 | ...[...] | semmle.label | ...[...] | +| ActiveRecordInjection.rb:102:5:102:6 | ps : | semmle.label | ps : | | ActiveRecordInjection.rb:102:10:102:15 | call to params : | semmle.label | call to params : | +| ActiveRecordInjection.rb:103:5:103:7 | uid : | semmle.label | uid : | | ActiveRecordInjection.rb:103:11:103:12 | ps : | semmle.label | ps : | | ActiveRecordInjection.rb:103:11:103:17 | ...[...] : | semmle.label | ...[...] : | +| ActiveRecordInjection.rb:104:5:104:9 | uidEq : | semmle.label | uidEq : | | ActiveRecordInjection.rb:108:20:108:32 | ... + ... | semmle.label | ... + ... | | ActiveRecordInjection.rb:141:21:141:26 | call to params : | semmle.label | call to params : | | ActiveRecordInjection.rb:141:21:141:44 | ...[...] : | semmle.label | ...[...] : | | ActiveRecordInjection.rb:155:27:155:76 | "this is an unsafe annotation:..." | semmle.label | "this is an unsafe annotation:..." | | ActiveRecordInjection.rb:155:59:155:64 | call to params : | semmle.label | call to params : | | ActiveRecordInjection.rb:155:59:155:74 | ...[...] : | semmle.label | ...[...] : | +| ActiveRecordInjection.rb:166:5:166:13 | my_params : | semmle.label | my_params : | | ActiveRecordInjection.rb:166:17:166:32 | call to permitted_params : | semmle.label | call to permitted_params : | +| ActiveRecordInjection.rb:167:5:167:9 | query : | semmle.label | query : | | ActiveRecordInjection.rb:167:47:167:55 | my_params : | semmle.label | my_params : | | ActiveRecordInjection.rb:167:47:167:65 | ...[...] : | semmle.label | ...[...] : | | ActiveRecordInjection.rb:168:37:168:41 | query | semmle.label | query | @@ -118,6 +129,7 @@ nodes | ActiveRecordInjection.rb:178:35:178:96 | "SELECT * FROM users WHERE id ..." | semmle.label | "SELECT * FROM users WHERE id ..." | | ActiveRecordInjection.rb:178:69:178:84 | call to permitted_params : | semmle.label | call to permitted_params : | | ActiveRecordInjection.rb:178:69:178:94 | ...[...] : | semmle.label | ...[...] : | +| ArelInjection.rb:4:5:4:8 | name : | semmle.label | name : | | 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..." | diff --git a/ruby/ql/test/query-tests/security/cwe-094/CodeInjection/CodeInjection.expected b/ruby/ql/test/query-tests/security/cwe-094/CodeInjection/CodeInjection.expected index 53a181121c2..0c7a63915ed 100644 --- a/ruby/ql/test/query-tests/security/cwe-094/CodeInjection/CodeInjection.expected +++ b/ruby/ql/test/query-tests/security/cwe-094/CodeInjection/CodeInjection.expected @@ -1,26 +1,30 @@ edges +| CodeInjection.rb:5:5:5:8 | code : | CodeInjection.rb:8:10:8:13 | code | +| CodeInjection.rb:5:5:5:8 | code : | CodeInjection.rb:8:10:8:13 | code | +| CodeInjection.rb:5:5:5:8 | code : | CodeInjection.rb:20:20:20:23 | code | +| CodeInjection.rb:5:5:5:8 | code : | CodeInjection.rb:20:20:20:23 | code | +| CodeInjection.rb:5:5:5:8 | code : | CodeInjection.rb:23:21:23:24 | code | +| CodeInjection.rb:5:5:5:8 | code : | CodeInjection.rb:23:21:23:24 | code | +| CodeInjection.rb:5:5:5:8 | code : | CodeInjection.rb:29:15:29:18 | code | +| CodeInjection.rb:5:5:5:8 | code : | CodeInjection.rb:32:19:32:22 | code | +| CodeInjection.rb:5:5:5:8 | code : | CodeInjection.rb:38:24:38:27 | code : | +| CodeInjection.rb:5:5:5:8 | code : | CodeInjection.rb:38:24:38:27 | code : | +| CodeInjection.rb:5:5:5:8 | code : | CodeInjection.rb:41:40:41:43 | code | | CodeInjection.rb:5:12:5:17 | call to params : | CodeInjection.rb:5:12:5:24 | ...[...] : | | CodeInjection.rb:5:12:5:17 | call to params : | CodeInjection.rb:5:12:5:24 | ...[...] : | -| CodeInjection.rb:5:12:5:24 | ...[...] : | CodeInjection.rb:8:10:8:13 | code | -| CodeInjection.rb:5:12:5:24 | ...[...] : | CodeInjection.rb:8:10:8:13 | code | -| CodeInjection.rb:5:12:5:24 | ...[...] : | CodeInjection.rb:20:20:20:23 | code | -| CodeInjection.rb:5:12:5:24 | ...[...] : | CodeInjection.rb:20:20:20:23 | code | -| CodeInjection.rb:5:12:5:24 | ...[...] : | CodeInjection.rb:23:21:23:24 | code | -| CodeInjection.rb:5:12:5:24 | ...[...] : | CodeInjection.rb:23:21:23:24 | code | -| CodeInjection.rb:5:12:5:24 | ...[...] : | CodeInjection.rb:29:15:29:18 | code | -| CodeInjection.rb:5:12:5:24 | ...[...] : | CodeInjection.rb:32:19:32:22 | code | -| CodeInjection.rb:5:12:5:24 | ...[...] : | CodeInjection.rb:38:24:38:27 | code : | -| CodeInjection.rb:5:12:5:24 | ...[...] : | CodeInjection.rb:38:24:38:27 | code : | -| CodeInjection.rb:5:12:5:24 | ...[...] : | CodeInjection.rb:41:40:41:43 | code | +| CodeInjection.rb:5:12:5:24 | ...[...] : | CodeInjection.rb:5:5:5:8 | code : | +| CodeInjection.rb:5:12:5:24 | ...[...] : | CodeInjection.rb:5:5:5:8 | code : | | CodeInjection.rb:38:24:38:27 | code : | CodeInjection.rb:38:10:38:28 | call to escape | | CodeInjection.rb:38:24:38:27 | code : | CodeInjection.rb:38:10:38:28 | call to escape | +| CodeInjection.rb:78:5:78:8 | code : | CodeInjection.rb:80:16:80:19 | code | +| CodeInjection.rb:78:5:78:8 | code : | CodeInjection.rb:86:10:86:37 | ... + ... | +| CodeInjection.rb:78:5:78:8 | code : | CodeInjection.rb:88:10:88:32 | "prefix_#{...}_suffix" | +| CodeInjection.rb:78:5:78:8 | code : | CodeInjection.rb:90:10:90:13 | code | +| CodeInjection.rb:78:5:78:8 | code : | CodeInjection.rb:90:10:90:13 | code | | CodeInjection.rb:78:12:78:17 | call to params : | CodeInjection.rb:78:12:78:24 | ...[...] : | | CodeInjection.rb:78:12:78:17 | call to params : | CodeInjection.rb:78:12:78:24 | ...[...] : | -| CodeInjection.rb:78:12:78:24 | ...[...] : | CodeInjection.rb:80:16:80:19 | code | -| CodeInjection.rb:78:12:78:24 | ...[...] : | CodeInjection.rb:86:10:86:37 | ... + ... | -| CodeInjection.rb:78:12:78:24 | ...[...] : | CodeInjection.rb:88:10:88:32 | "prefix_#{...}_suffix" | -| CodeInjection.rb:78:12:78:24 | ...[...] : | CodeInjection.rb:90:10:90:13 | code | -| CodeInjection.rb:78:12:78:24 | ...[...] : | CodeInjection.rb:90:10:90:13 | code | +| CodeInjection.rb:78:12:78:24 | ...[...] : | CodeInjection.rb:78:5:78:8 | code : | +| CodeInjection.rb:78:12:78:24 | ...[...] : | CodeInjection.rb:78:5:78:8 | code : | | CodeInjection.rb:101:3:102:5 | self in index [@foo] : | CodeInjection.rb:111:3:113:5 | self in baz [@foo] : | | CodeInjection.rb:101:3:102:5 | self in index [@foo] : | CodeInjection.rb:111:3:113:5 | self in baz [@foo] : | | CodeInjection.rb:105:5:105:8 | [post] self [@foo] : | CodeInjection.rb:108:3:109:5 | self in bar [@foo] : | @@ -36,6 +40,8 @@ edges | CodeInjection.rb:112:10:112:13 | self [@foo] : | CodeInjection.rb:112:10:112:13 | @foo | | CodeInjection.rb:112:10:112:13 | self [@foo] : | CodeInjection.rb:112:10:112:13 | @foo | nodes +| CodeInjection.rb:5:5:5:8 | code : | semmle.label | code : | +| CodeInjection.rb:5:5:5:8 | code : | semmle.label | code : | | CodeInjection.rb:5:12:5:17 | call to params : | semmle.label | call to params : | | CodeInjection.rb:5:12:5:17 | call to params : | semmle.label | call to params : | | CodeInjection.rb:5:12:5:24 | ...[...] : | semmle.label | ...[...] : | @@ -55,6 +61,8 @@ nodes | CodeInjection.rb:38:24:38:27 | code : | semmle.label | code : | | CodeInjection.rb:38:24:38:27 | code : | semmle.label | code : | | CodeInjection.rb:41:40:41:43 | code | semmle.label | code | +| CodeInjection.rb:78:5:78:8 | code : | semmle.label | code : | +| CodeInjection.rb:78:5:78:8 | code : | semmle.label | code : | | CodeInjection.rb:78:12:78:17 | call to params : | semmle.label | call to params : | | CodeInjection.rb:78:12:78:17 | call to params : | semmle.label | call to params : | | CodeInjection.rb:78:12:78:24 | ...[...] : | semmle.label | ...[...] : | diff --git a/ruby/ql/test/query-tests/security/cwe-094/UnsafeCodeConstruction/UnsafeCodeConstruction.expected b/ruby/ql/test/query-tests/security/cwe-094/UnsafeCodeConstruction/UnsafeCodeConstruction.expected index 1b55dd3c999..f57dd6a3e88 100644 --- a/ruby/ql/test/query-tests/security/cwe-094/UnsafeCodeConstruction/UnsafeCodeConstruction.expected +++ b/ruby/ql/test/query-tests/security/cwe-094/UnsafeCodeConstruction/UnsafeCodeConstruction.expected @@ -4,7 +4,8 @@ edges | impl/unsafeCode.rb:12:12:12:12 | x : | impl/unsafeCode.rb:13:33:13:33 | x | | impl/unsafeCode.rb:28:17:28:22 | my_arr : | impl/unsafeCode.rb:29:10:29:15 | my_arr | | impl/unsafeCode.rb:32:21:32:21 | x : | impl/unsafeCode.rb:33:12:33:12 | x : | -| impl/unsafeCode.rb:33:12:33:12 | x : | impl/unsafeCode.rb:34:10:34:12 | arr | +| impl/unsafeCode.rb:33:5:33:7 | arr [element 0] : | impl/unsafeCode.rb:34:10:34:12 | arr | +| impl/unsafeCode.rb:33:12:33:12 | x : | impl/unsafeCode.rb:33:5:33:7 | arr [element 0] : | | impl/unsafeCode.rb:37:15:37:15 | x : | impl/unsafeCode.rb:39:14:39:14 | x : | | impl/unsafeCode.rb:39:5:39:7 | [post] arr [element] : | impl/unsafeCode.rb:40:10:40:12 | arr | | impl/unsafeCode.rb:39:5:39:7 | [post] arr [element] : | impl/unsafeCode.rb:44:10:44:12 | arr | @@ -13,10 +14,12 @@ edges | impl/unsafeCode.rb:54:21:54:21 | x : | impl/unsafeCode.rb:55:22:55:22 | x | | impl/unsafeCode.rb:59:21:59:21 | x : | impl/unsafeCode.rb:60:17:60:17 | x : | | impl/unsafeCode.rb:59:24:59:24 | y : | impl/unsafeCode.rb:63:30:63:30 | y : | -| impl/unsafeCode.rb:60:11:60:18 | call to Array [element 0] : | impl/unsafeCode.rb:61:10:61:12 | arr | +| impl/unsafeCode.rb:60:5:60:7 | arr [element 0] : | impl/unsafeCode.rb:61:10:61:12 | arr | +| impl/unsafeCode.rb:60:11:60:18 | call to Array [element 0] : | impl/unsafeCode.rb:60:5:60:7 | arr [element 0] : | | impl/unsafeCode.rb:60:17:60:17 | x : | impl/unsafeCode.rb:60:11:60:18 | call to Array [element 0] : | +| impl/unsafeCode.rb:63:5:63:8 | arr2 [element 0] : | impl/unsafeCode.rb:64:10:64:13 | arr2 | | impl/unsafeCode.rb:63:13:63:32 | call to Array [element 1] : | impl/unsafeCode.rb:63:13:63:42 | call to join : | -| impl/unsafeCode.rb:63:13:63:42 | call to join : | impl/unsafeCode.rb:64:10:64:13 | arr2 | +| impl/unsafeCode.rb:63:13:63:42 | call to join : | impl/unsafeCode.rb:63:5:63:8 | arr2 [element 0] : | | impl/unsafeCode.rb:63:30:63:30 | y : | impl/unsafeCode.rb:63:13:63:32 | call to Array [element 1] : | nodes | impl/unsafeCode.rb:2:12:2:17 | target : | semmle.label | target : | @@ -28,6 +31,7 @@ nodes | impl/unsafeCode.rb:28:17:28:22 | my_arr : | semmle.label | my_arr : | | impl/unsafeCode.rb:29:10:29:15 | my_arr | semmle.label | my_arr | | impl/unsafeCode.rb:32:21:32:21 | x : | semmle.label | x : | +| impl/unsafeCode.rb:33:5:33:7 | arr [element 0] : | semmle.label | arr [element 0] : | | impl/unsafeCode.rb:33:12:33:12 | x : | semmle.label | x : | | impl/unsafeCode.rb:34:10:34:12 | arr | semmle.label | arr | | impl/unsafeCode.rb:37:15:37:15 | x : | semmle.label | x : | @@ -41,9 +45,11 @@ nodes | impl/unsafeCode.rb:55:22:55:22 | x | semmle.label | x | | impl/unsafeCode.rb:59:21:59:21 | x : | semmle.label | x : | | impl/unsafeCode.rb:59:24:59:24 | y : | semmle.label | y : | +| impl/unsafeCode.rb:60:5:60:7 | arr [element 0] : | semmle.label | arr [element 0] : | | impl/unsafeCode.rb:60:11:60:18 | call to Array [element 0] : | semmle.label | call to Array [element 0] : | | impl/unsafeCode.rb:60:17:60:17 | x : | semmle.label | x : | | impl/unsafeCode.rb:61:10:61:12 | arr | semmle.label | arr | +| impl/unsafeCode.rb:63:5:63:8 | arr2 [element 0] : | semmle.label | arr2 [element 0] : | | impl/unsafeCode.rb:63:13:63:32 | call to Array [element 1] : | semmle.label | call to Array [element 1] : | | impl/unsafeCode.rb:63:13:63:42 | call to join : | semmle.label | call to join : | | impl/unsafeCode.rb:63:30:63:30 | y : | semmle.label | y : | diff --git a/ruby/ql/test/query-tests/security/cwe-117/LogInjection.expected b/ruby/ql/test/query-tests/security/cwe-117/LogInjection.expected index b0da6305e8a..7f461d5efe1 100644 --- a/ruby/ql/test/query-tests/security/cwe-117/LogInjection.expected +++ b/ruby/ql/test/query-tests/security/cwe-117/LogInjection.expected @@ -1,28 +1,30 @@ edges +| app/controllers/users_controller.rb:15:5:15:15 | unsanitized : | app/controllers/users_controller.rb:16:19:16:29 | unsanitized | +| app/controllers/users_controller.rb:15:5:15:15 | unsanitized : | app/controllers/users_controller.rb:17:19:17:41 | ... + ... | +| app/controllers/users_controller.rb:15:5:15:15 | unsanitized : | app/controllers/users_controller.rb:23:20:23:30 | unsanitized : | | app/controllers/users_controller.rb:15:19:15:24 | call to params : | app/controllers/users_controller.rb:15:19:15:30 | ...[...] : | -| app/controllers/users_controller.rb:15:19:15:30 | ...[...] : | app/controllers/users_controller.rb:16:19:16:29 | unsanitized | -| app/controllers/users_controller.rb:15:19:15:30 | ...[...] : | app/controllers/users_controller.rb:17:19:17:41 | ... + ... | -| app/controllers/users_controller.rb:15:19:15:30 | ...[...] : | app/controllers/users_controller.rb:23:20:23:30 | unsanitized : | -| app/controllers/users_controller.rb:23:5:23:44 | ... = ... : | app/controllers/users_controller.rb:25:7:25:18 | unsanitized2 | +| app/controllers/users_controller.rb:15:19:15:30 | ...[...] : | app/controllers/users_controller.rb:15:5:15:15 | unsanitized : | +| app/controllers/users_controller.rb:23:5:23:16 | unsanitized2 : | app/controllers/users_controller.rb:25:7:25:18 | unsanitized2 | +| app/controllers/users_controller.rb:23:5:23:16 | unsanitized2 : | app/controllers/users_controller.rb:27:16:27:39 | ... + ... | | app/controllers/users_controller.rb:23:20:23:30 | unsanitized : | app/controllers/users_controller.rb:23:20:23:44 | call to sub : | -| app/controllers/users_controller.rb:23:20:23:44 | call to sub : | app/controllers/users_controller.rb:23:5:23:44 | ... = ... : | -| app/controllers/users_controller.rb:23:20:23:44 | call to sub : | app/controllers/users_controller.rb:27:16:27:39 | ... + ... | -| app/controllers/users_controller.rb:33:5:33:31 | ... = ... : | app/controllers/users_controller.rb:34:33:34:43 | unsanitized | -| app/controllers/users_controller.rb:33:5:33:31 | ... = ... : | app/controllers/users_controller.rb:35:33:35:55 | ... + ... | +| app/controllers/users_controller.rb:23:20:23:44 | call to sub : | app/controllers/users_controller.rb:23:5:23:16 | unsanitized2 : | +| app/controllers/users_controller.rb:33:5:33:15 | unsanitized : | app/controllers/users_controller.rb:34:33:34:43 | unsanitized | +| app/controllers/users_controller.rb:33:5:33:15 | unsanitized : | app/controllers/users_controller.rb:35:33:35:55 | ... + ... | | app/controllers/users_controller.rb:33:19:33:25 | call to cookies : | app/controllers/users_controller.rb:33:19:33:31 | ...[...] : | -| app/controllers/users_controller.rb:33:19:33:31 | ...[...] : | app/controllers/users_controller.rb:33:5:33:31 | ... = ... : | +| app/controllers/users_controller.rb:33:19:33:31 | ...[...] : | app/controllers/users_controller.rb:33:5:33:15 | unsanitized : | | app/controllers/users_controller.rb:49:19:49:24 | call to params : | app/controllers/users_controller.rb:49:19:49:30 | ...[...] | nodes +| app/controllers/users_controller.rb:15:5:15:15 | unsanitized : | semmle.label | unsanitized : | | app/controllers/users_controller.rb:15:19:15:24 | call to params : | semmle.label | call to params : | | app/controllers/users_controller.rb:15:19:15:30 | ...[...] : | semmle.label | ...[...] : | | app/controllers/users_controller.rb:16:19:16:29 | unsanitized | semmle.label | unsanitized | | app/controllers/users_controller.rb:17:19:17:41 | ... + ... | semmle.label | ... + ... | -| app/controllers/users_controller.rb:23:5:23:44 | ... = ... : | semmle.label | ... = ... : | +| app/controllers/users_controller.rb:23:5:23:16 | unsanitized2 : | semmle.label | unsanitized2 : | | app/controllers/users_controller.rb:23:20:23:30 | unsanitized : | semmle.label | unsanitized : | | app/controllers/users_controller.rb:23:20:23:44 | call to sub : | semmle.label | call to sub : | | app/controllers/users_controller.rb:25:7:25:18 | unsanitized2 | semmle.label | unsanitized2 | | app/controllers/users_controller.rb:27:16:27:39 | ... + ... | semmle.label | ... + ... | -| app/controllers/users_controller.rb:33:5:33:31 | ... = ... : | semmle.label | ... = ... : | +| app/controllers/users_controller.rb:33:5:33:15 | unsanitized : | semmle.label | unsanitized : | | app/controllers/users_controller.rb:33:19:33:25 | call to cookies : | semmle.label | call to cookies : | | app/controllers/users_controller.rb:33:19:33:31 | ...[...] : | semmle.label | ...[...] : | | app/controllers/users_controller.rb:34:33:34:43 | unsanitized | semmle.label | unsanitized | diff --git a/ruby/ql/test/query-tests/security/cwe-1333-polynomial-redos/PolynomialReDoS.expected b/ruby/ql/test/query-tests/security/cwe-1333-polynomial-redos/PolynomialReDoS.expected index c428efe29cd..5341242ac8f 100644 --- a/ruby/ql/test/query-tests/security/cwe-1333-polynomial-redos/PolynomialReDoS.expected +++ b/ruby/ql/test/query-tests/security/cwe-1333-polynomial-redos/PolynomialReDoS.expected @@ -1,42 +1,49 @@ edges +| PolynomialReDoS.rb:4:5:4:8 | name : | PolynomialReDoS.rb:10:5:10:8 | name | +| PolynomialReDoS.rb:4:5:4:8 | name : | PolynomialReDoS.rb:11:5:11:8 | name | +| PolynomialReDoS.rb:4:5:4:8 | name : | PolynomialReDoS.rb:12:5:12:8 | name | +| PolynomialReDoS.rb:4:5:4:8 | name : | PolynomialReDoS.rb:13:5:13:8 | name | +| PolynomialReDoS.rb:4:5:4:8 | name : | PolynomialReDoS.rb:14:5:14:8 | name | +| PolynomialReDoS.rb:4:5:4:8 | name : | PolynomialReDoS.rb:15:5:15:8 | name | +| PolynomialReDoS.rb:4:5:4:8 | name : | PolynomialReDoS.rb:16:5:16:8 | name | +| PolynomialReDoS.rb:4:5:4:8 | name : | PolynomialReDoS.rb:17:5:17:8 | name | +| PolynomialReDoS.rb:4:5:4:8 | name : | PolynomialReDoS.rb:18:5:18:8 | name | +| PolynomialReDoS.rb:4:5:4:8 | name : | PolynomialReDoS.rb:19:5:19:8 | name | +| PolynomialReDoS.rb:4:5:4:8 | name : | PolynomialReDoS.rb:20:5:20:8 | name | +| PolynomialReDoS.rb:4:5:4:8 | name : | PolynomialReDoS.rb:21:5:21:8 | name | +| PolynomialReDoS.rb:4:5:4:8 | name : | PolynomialReDoS.rb:22:5:22:8 | name | +| PolynomialReDoS.rb:4:5:4:8 | name : | PolynomialReDoS.rb:23:17:23:20 | name | +| PolynomialReDoS.rb:4:5:4:8 | name : | PolynomialReDoS.rb:24:18:24:21 | name | +| PolynomialReDoS.rb:4:5:4:8 | name : | PolynomialReDoS.rb:42:10:42:13 | name | +| PolynomialReDoS.rb:4:5:4:8 | name : | PolynomialReDoS.rb:47:10:47:13 | name | | PolynomialReDoS.rb:4:12:4:17 | call to params : | PolynomialReDoS.rb:4:12:4:24 | ...[...] : | -| PolynomialReDoS.rb:4:12:4:24 | ...[...] : | PolynomialReDoS.rb:10:5:10:8 | name | -| PolynomialReDoS.rb:4:12:4:24 | ...[...] : | PolynomialReDoS.rb:11:5:11:8 | name | -| PolynomialReDoS.rb:4:12:4:24 | ...[...] : | PolynomialReDoS.rb:12:5:12:8 | name | -| PolynomialReDoS.rb:4:12:4:24 | ...[...] : | PolynomialReDoS.rb:13:5:13:8 | name | -| PolynomialReDoS.rb:4:12:4:24 | ...[...] : | PolynomialReDoS.rb:14:5:14:8 | name | -| PolynomialReDoS.rb:4:12:4:24 | ...[...] : | PolynomialReDoS.rb:15:5:15:8 | name | -| PolynomialReDoS.rb:4:12:4:24 | ...[...] : | PolynomialReDoS.rb:16:5:16:8 | name | -| PolynomialReDoS.rb:4:12:4:24 | ...[...] : | PolynomialReDoS.rb:17:5:17:8 | name | -| PolynomialReDoS.rb:4:12:4:24 | ...[...] : | PolynomialReDoS.rb:18:5:18:8 | name | -| PolynomialReDoS.rb:4:12:4:24 | ...[...] : | PolynomialReDoS.rb:19:5:19:8 | name | -| PolynomialReDoS.rb:4:12:4:24 | ...[...] : | PolynomialReDoS.rb:20:5:20:8 | name | -| PolynomialReDoS.rb:4:12:4:24 | ...[...] : | PolynomialReDoS.rb:21:5:21:8 | name | -| PolynomialReDoS.rb:4:12:4:24 | ...[...] : | PolynomialReDoS.rb:22:5:22:8 | name | -| PolynomialReDoS.rb:4:12:4:24 | ...[...] : | PolynomialReDoS.rb:23:17:23:20 | name | -| PolynomialReDoS.rb:4:12:4:24 | ...[...] : | PolynomialReDoS.rb:24:18:24:21 | name | -| PolynomialReDoS.rb:4:12:4:24 | ...[...] : | PolynomialReDoS.rb:42:10:42:13 | name | -| PolynomialReDoS.rb:4:12:4:24 | ...[...] : | PolynomialReDoS.rb:47:10:47:13 | name | +| PolynomialReDoS.rb:4:12:4:24 | ...[...] : | PolynomialReDoS.rb:4:5:4:8 | name : | +| PolynomialReDoS.rb:27:5:27:5 | a : | PolynomialReDoS.rb:28:5:28:5 | a | | PolynomialReDoS.rb:27:9:27:14 | call to params : | PolynomialReDoS.rb:27:9:27:18 | ...[...] : | -| PolynomialReDoS.rb:27:9:27:18 | ...[...] : | PolynomialReDoS.rb:28:5:28:5 | a | +| PolynomialReDoS.rb:27:9:27:18 | ...[...] : | PolynomialReDoS.rb:27:5:27:5 | a : | +| PolynomialReDoS.rb:29:5:29:5 | b : | PolynomialReDoS.rb:30:5:30:5 | b | | PolynomialReDoS.rb:29:9:29:14 | call to params : | PolynomialReDoS.rb:29:9:29:18 | ...[...] : | -| PolynomialReDoS.rb:29:9:29:18 | ...[...] : | PolynomialReDoS.rb:30:5:30:5 | b | +| PolynomialReDoS.rb:29:9:29:18 | ...[...] : | PolynomialReDoS.rb:29:5:29:5 | b : | +| PolynomialReDoS.rb:31:5:31:5 | c : | PolynomialReDoS.rb:32:5:32:5 | c | | PolynomialReDoS.rb:31:9:31:14 | call to params : | PolynomialReDoS.rb:31:9:31:18 | ...[...] : | -| PolynomialReDoS.rb:31:9:31:18 | ...[...] : | PolynomialReDoS.rb:32:5:32:5 | c | +| PolynomialReDoS.rb:31:9:31:18 | ...[...] : | PolynomialReDoS.rb:31:5:31:5 | c : | +| PolynomialReDoS.rb:54:5:54:8 | name : | PolynomialReDoS.rb:56:38:56:41 | name : | +| PolynomialReDoS.rb:54:5:54:8 | name : | PolynomialReDoS.rb:58:37:58:40 | name : | | PolynomialReDoS.rb:54:12:54:17 | call to params : | PolynomialReDoS.rb:54:12:54:24 | ...[...] : | -| PolynomialReDoS.rb:54:12:54:24 | ...[...] : | PolynomialReDoS.rb:56:38:56:41 | name : | -| PolynomialReDoS.rb:54:12:54:24 | ...[...] : | PolynomialReDoS.rb:58:37:58:40 | name : | +| PolynomialReDoS.rb:54:12:54:24 | ...[...] : | PolynomialReDoS.rb:54:5:54:8 | name : | | PolynomialReDoS.rb:56:38:56:41 | name : | PolynomialReDoS.rb:61:33:61:37 | input : | | PolynomialReDoS.rb:58:37:58:40 | name : | PolynomialReDoS.rb:65:42:65:46 | input : | | PolynomialReDoS.rb:61:33:61:37 | input : | PolynomialReDoS.rb:62:5:62:9 | input | | PolynomialReDoS.rb:65:42:65:46 | input : | PolynomialReDoS.rb:66:5:66:9 | input | +| PolynomialReDoS.rb:70:5:70:8 | name : | PolynomialReDoS.rb:73:32:73:35 | name : | | PolynomialReDoS.rb:70:12:70:17 | call to params : | PolynomialReDoS.rb:70:12:70:24 | ...[...] : | -| PolynomialReDoS.rb:70:12:70:24 | ...[...] : | PolynomialReDoS.rb:73:32:73:35 | name : | +| PolynomialReDoS.rb:70:12:70:24 | ...[...] : | PolynomialReDoS.rb:70:5:70:8 | name : | | PolynomialReDoS.rb:73:32:73:35 | name : | PolynomialReDoS.rb:76:35:76:39 | input : | | PolynomialReDoS.rb:76:35:76:39 | input : | PolynomialReDoS.rb:77:5:77:9 | input | | lib/index.rb:2:11:2:11 | x : | lib/index.rb:4:13:4:13 | x | | lib/index.rb:8:13:8:13 | x : | lib/index.rb:9:15:9:15 | x | nodes +| PolynomialReDoS.rb:4:5:4:8 | name : | semmle.label | name : | | PolynomialReDoS.rb:4:12:4:17 | call to params : | semmle.label | call to params : | | PolynomialReDoS.rb:4:12:4:24 | ...[...] : | semmle.label | ...[...] : | | PolynomialReDoS.rb:10:5:10:8 | name | semmle.label | name | @@ -54,17 +61,21 @@ nodes | PolynomialReDoS.rb:22:5:22:8 | name | semmle.label | name | | PolynomialReDoS.rb:23:17:23:20 | name | semmle.label | name | | PolynomialReDoS.rb:24:18:24:21 | name | semmle.label | name | +| PolynomialReDoS.rb:27:5:27:5 | a : | semmle.label | a : | | PolynomialReDoS.rb:27:9:27:14 | call to params : | semmle.label | call to params : | | PolynomialReDoS.rb:27:9:27:18 | ...[...] : | semmle.label | ...[...] : | | PolynomialReDoS.rb:28:5:28:5 | a | semmle.label | a | +| PolynomialReDoS.rb:29:5:29:5 | b : | semmle.label | b : | | PolynomialReDoS.rb:29:9:29:14 | call to params : | semmle.label | call to params : | | PolynomialReDoS.rb:29:9:29:18 | ...[...] : | semmle.label | ...[...] : | | PolynomialReDoS.rb:30:5:30:5 | b | semmle.label | b | +| PolynomialReDoS.rb:31:5:31:5 | c : | semmle.label | c : | | PolynomialReDoS.rb:31:9:31:14 | call to params : | semmle.label | call to params : | | PolynomialReDoS.rb:31:9:31:18 | ...[...] : | semmle.label | ...[...] : | | PolynomialReDoS.rb:32:5:32:5 | c | semmle.label | c | | PolynomialReDoS.rb:42:10:42:13 | name | semmle.label | name | | PolynomialReDoS.rb:47:10:47:13 | name | semmle.label | name | +| PolynomialReDoS.rb:54:5:54:8 | name : | semmle.label | name : | | PolynomialReDoS.rb:54:12:54:17 | call to params : | semmle.label | call to params : | | PolynomialReDoS.rb:54:12:54:24 | ...[...] : | semmle.label | ...[...] : | | PolynomialReDoS.rb:56:38:56:41 | name : | semmle.label | name : | @@ -73,6 +84,7 @@ nodes | PolynomialReDoS.rb:62:5:62:9 | input | semmle.label | input | | PolynomialReDoS.rb:65:42:65:46 | input : | semmle.label | input : | | PolynomialReDoS.rb:66:5:66:9 | input | semmle.label | input | +| PolynomialReDoS.rb:70:5:70:8 | name : | semmle.label | name : | | PolynomialReDoS.rb:70:12:70:17 | call to params : | semmle.label | call to params : | | PolynomialReDoS.rb:70:12:70:24 | ...[...] : | semmle.label | ...[...] : | | PolynomialReDoS.rb:73:32:73:35 | name : | semmle.label | name : | diff --git a/ruby/ql/test/query-tests/security/cwe-1333-regexp-injection/RegExpInjection.expected b/ruby/ql/test/query-tests/security/cwe-1333-regexp-injection/RegExpInjection.expected index 80c434f8002..8318c0a8ec8 100644 --- a/ruby/ql/test/query-tests/security/cwe-1333-regexp-injection/RegExpInjection.expected +++ b/ruby/ql/test/query-tests/security/cwe-1333-regexp-injection/RegExpInjection.expected @@ -1,27 +1,37 @@ edges +| RegExpInjection.rb:4:5:4:8 | name : | RegExpInjection.rb:5:13:5:21 | /#{...}/ | | RegExpInjection.rb:4:12:4:17 | call to params : | RegExpInjection.rb:4:12:4:24 | ...[...] : | -| RegExpInjection.rb:4:12:4:24 | ...[...] : | RegExpInjection.rb:5:13:5:21 | /#{...}/ | +| RegExpInjection.rb:4:12:4:24 | ...[...] : | RegExpInjection.rb:4:5:4:8 | name : | +| RegExpInjection.rb:10:5:10:8 | name : | RegExpInjection.rb:11:13:11:27 | /foo#{...}bar/ | | RegExpInjection.rb:10:12:10:17 | call to params : | RegExpInjection.rb:10:12:10:24 | ...[...] : | -| RegExpInjection.rb:10:12:10:24 | ...[...] : | RegExpInjection.rb:11:13:11:27 | /foo#{...}bar/ | +| RegExpInjection.rb:10:12:10:24 | ...[...] : | RegExpInjection.rb:10:5:10:8 | name : | +| RegExpInjection.rb:16:5:16:8 | name : | RegExpInjection.rb:17:24:17:27 | name | | RegExpInjection.rb:16:12:16:17 | call to params : | RegExpInjection.rb:16:12:16:24 | ...[...] : | -| RegExpInjection.rb:16:12:16:24 | ...[...] : | RegExpInjection.rb:17:24:17:27 | name | +| RegExpInjection.rb:16:12:16:24 | ...[...] : | RegExpInjection.rb:16:5:16:8 | name : | +| RegExpInjection.rb:22:5:22:8 | name : | RegExpInjection.rb:23:24:23:33 | ... + ... | | RegExpInjection.rb:22:12:22:17 | call to params : | RegExpInjection.rb:22:12:22:24 | ...[...] : | -| RegExpInjection.rb:22:12:22:24 | ...[...] : | RegExpInjection.rb:23:24:23:33 | ... + ... | +| RegExpInjection.rb:22:12:22:24 | ...[...] : | RegExpInjection.rb:22:5:22:8 | name : | +| RegExpInjection.rb:54:5:54:8 | name : | RegExpInjection.rb:55:28:55:37 | ... + ... | | RegExpInjection.rb:54:12:54:17 | call to params : | RegExpInjection.rb:54:12:54:24 | ...[...] : | -| RegExpInjection.rb:54:12:54:24 | ...[...] : | RegExpInjection.rb:55:28:55:37 | ... + ... | +| RegExpInjection.rb:54:12:54:24 | ...[...] : | RegExpInjection.rb:54:5:54:8 | name : | nodes +| RegExpInjection.rb:4:5:4:8 | name : | semmle.label | name : | | RegExpInjection.rb:4:12:4:17 | call to params : | semmle.label | call to params : | | RegExpInjection.rb:4:12:4:24 | ...[...] : | semmle.label | ...[...] : | | RegExpInjection.rb:5:13:5:21 | /#{...}/ | semmle.label | /#{...}/ | +| RegExpInjection.rb:10:5:10:8 | name : | semmle.label | name : | | RegExpInjection.rb:10:12:10:17 | call to params : | semmle.label | call to params : | | RegExpInjection.rb:10:12:10:24 | ...[...] : | semmle.label | ...[...] : | | RegExpInjection.rb:11:13:11:27 | /foo#{...}bar/ | semmle.label | /foo#{...}bar/ | +| RegExpInjection.rb:16:5:16:8 | name : | semmle.label | name : | | RegExpInjection.rb:16:12:16:17 | call to params : | semmle.label | call to params : | | RegExpInjection.rb:16:12:16:24 | ...[...] : | semmle.label | ...[...] : | | RegExpInjection.rb:17:24:17:27 | name | semmle.label | name | +| RegExpInjection.rb:22:5:22:8 | name : | semmle.label | name : | | RegExpInjection.rb:22:12:22:17 | call to params : | semmle.label | call to params : | | RegExpInjection.rb:22:12:22:24 | ...[...] : | semmle.label | ...[...] : | | RegExpInjection.rb:23:24:23:33 | ... + ... | semmle.label | ... + ... | +| RegExpInjection.rb:54:5:54:8 | name : | semmle.label | name : | | RegExpInjection.rb:54:12:54:17 | call to params : | semmle.label | call to params : | | RegExpInjection.rb:54:12:54:24 | ...[...] : | semmle.label | ...[...] : | | RegExpInjection.rb:55:28:55:37 | ... + ... | semmle.label | ... + ... | 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 0dba484c65a..532c7752905 100644 --- a/ruby/ql/test/query-tests/security/cwe-209/StackTraceExposure.expected +++ b/ruby/ql/test/query-tests/security/cwe-209/StackTraceExposure.expected @@ -1,7 +1,9 @@ edges -| StackTraceExposure.rb:11:10:11:17 | call to caller : | StackTraceExposure.rb:12:18:12:19 | bt | +| StackTraceExposure.rb:11:5:11:6 | bt : | StackTraceExposure.rb:12:18:12:19 | bt | +| StackTraceExposure.rb:11:10:11:17 | call to caller : | StackTraceExposure.rb:11:5:11:6 | bt : | nodes | StackTraceExposure.rb:6:18:6:28 | call to backtrace | semmle.label | call to backtrace | +| StackTraceExposure.rb:11:5:11:6 | bt : | semmle.label | bt : | | 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 | diff --git a/ruby/ql/test/query-tests/security/cwe-312/CleartextLogging.expected b/ruby/ql/test/query-tests/security/cwe-312/CleartextLogging.expected index 2931f4869c4..90968a06b2b 100644 --- a/ruby/ql/test/query-tests/security/cwe-312/CleartextLogging.expected +++ b/ruby/ql/test/query-tests/security/cwe-312/CleartextLogging.expected @@ -1,34 +1,45 @@ edges -| logging.rb:3:12:3:45 | "043697b96909e03ca907599d6420555f" : | logging.rb:6:20:6:27 | password | -| logging.rb:3:12:3:45 | "043697b96909e03ca907599d6420555f" : | logging.rb:8:21:8:28 | password | -| logging.rb:3:12:3:45 | "043697b96909e03ca907599d6420555f" : | logging.rb:10:21:10:28 | password | -| logging.rb:3:12:3:45 | "043697b96909e03ca907599d6420555f" : | logging.rb:12:21:12:28 | password | -| logging.rb:3:12:3:45 | "043697b96909e03ca907599d6420555f" : | logging.rb:14:23:14:30 | password | -| logging.rb:3:12:3:45 | "043697b96909e03ca907599d6420555f" : | logging.rb:16:20:16:27 | password | -| logging.rb:3:12:3:45 | "043697b96909e03ca907599d6420555f" : | logging.rb:19:33:19:40 | password | -| logging.rb:3:12:3:45 | "043697b96909e03ca907599d6420555f" : | logging.rb:21:44:21:51 | password | -| logging.rb:3:12:3:45 | "043697b96909e03ca907599d6420555f" : | logging.rb:23:33:23:40 | password | -| logging.rb:3:12:3:45 | "043697b96909e03ca907599d6420555f" : | logging.rb:26:18:26:34 | "pw: #{...}" | -| logging.rb:3:12:3:45 | "043697b96909e03ca907599d6420555f" : | logging.rb:28:26:28:33 | password | -| logging.rb:30:20:30:53 | "aec5058e61f7f122998b1a30ee2c66b6" : | logging.rb:38:20:38:23 | hsh1 [element :password] : | +| logging.rb:3:1:3:8 | password : | logging.rb:6:20:6:27 | password | +| logging.rb:3:1:3:8 | password : | logging.rb:8:21:8:28 | password | +| logging.rb:3:1:3:8 | password : | logging.rb:10:21:10:28 | password | +| logging.rb:3:1:3:8 | password : | logging.rb:12:21:12:28 | password | +| logging.rb:3:1:3:8 | password : | logging.rb:14:23:14:30 | password | +| logging.rb:3:1:3:8 | password : | logging.rb:16:20:16:27 | password | +| logging.rb:3:1:3:8 | password : | logging.rb:19:33:19:40 | password | +| logging.rb:3:1:3:8 | password : | logging.rb:21:44:21:51 | password | +| logging.rb:3:1:3:8 | password : | logging.rb:23:33:23:40 | password | +| logging.rb:3:1:3:8 | password : | logging.rb:26:18:26:34 | "pw: #{...}" | +| logging.rb:3:1:3:8 | password : | logging.rb:28:26:28:33 | password | +| logging.rb:3:12:3:45 | "043697b96909e03ca907599d6420555f" : | logging.rb:3:1:3:8 | password : | +| logging.rb:30:1:30:4 | hsh1 [element :password] : | logging.rb:38:20:38:23 | hsh1 [element :password] : | +| logging.rb:30:20:30:53 | "aec5058e61f7f122998b1a30ee2c66b6" : | logging.rb:30:1:30:4 | hsh1 [element :password] : | +| logging.rb:34:1:34:4 | [post] hsh2 [element :password] : | logging.rb:35:1:35:4 | hsh3 [element :password] : | | logging.rb:34:1:34:4 | [post] hsh2 [element :password] : | logging.rb:40:20:40:23 | hsh2 [element :password] : | -| logging.rb:34:1:34:4 | [post] hsh2 [element :password] : | logging.rb:42:20:42:23 | hsh3 [element :password] : | | logging.rb:34:19:34:52 | "beeda625d7306b45784d91ea0336e201" : | logging.rb:34:1:34:4 | [post] hsh2 [element :password] : | +| logging.rb:35:1:35:4 | hsh3 [element :password] : | logging.rb:42:20:42:23 | hsh3 [element :password] : | | logging.rb:38:20:38:23 | hsh1 [element :password] : | logging.rb:38:20:38:34 | ...[...] | | logging.rb:40:20:40:23 | hsh2 [element :password] : | logging.rb:40:20:40:34 | ...[...] | | logging.rb:42:20:42:23 | hsh3 [element :password] : | logging.rb:42:20:42:34 | ...[...] | -| logging.rb:64:35:64:68 | "ca497451f5e883662fb1a37bc9ec7838" : | logging.rb:68:35:68:65 | password_masked_ineffective_sub : | -| logging.rb:65:38:65:71 | "ca497451f5e883662fb1a37bc9ec7838" : | logging.rb:78:20:78:53 | password_masked_ineffective_sub_ex | -| logging.rb:66:36:66:69 | "a7e3747b19930d4f4b8181047194832f" : | logging.rb:70:36:70:67 | password_masked_ineffective_gsub : | -| logging.rb:67:39:67:72 | "a7e3747b19930d4f4b8181047194832f" : | logging.rb:80:20:80:54 | password_masked_ineffective_gsub_ex | +| logging.rb:64:1:64:31 | password_masked_ineffective_sub : | logging.rb:68:35:68:65 | password_masked_ineffective_sub : | +| logging.rb:64:35:64:68 | "ca497451f5e883662fb1a37bc9ec7838" : | logging.rb:64:1:64:31 | password_masked_ineffective_sub : | +| logging.rb:65:1:65:34 | password_masked_ineffective_sub_ex : | logging.rb:78:20:78:53 | password_masked_ineffective_sub_ex | +| logging.rb:65:38:65:71 | "ca497451f5e883662fb1a37bc9ec7838" : | logging.rb:65:1:65:34 | password_masked_ineffective_sub_ex : | +| logging.rb:66:1:66:32 | password_masked_ineffective_gsub : | logging.rb:70:36:70:67 | password_masked_ineffective_gsub : | +| logging.rb:66:36:66:69 | "a7e3747b19930d4f4b8181047194832f" : | logging.rb:66:1:66:32 | password_masked_ineffective_gsub : | +| logging.rb:67:1:67:35 | password_masked_ineffective_gsub_ex : | logging.rb:80:20:80:54 | password_masked_ineffective_gsub_ex | +| logging.rb:67:39:67:72 | "a7e3747b19930d4f4b8181047194832f" : | logging.rb:67:1:67:35 | password_masked_ineffective_gsub_ex : | +| logging.rb:68:1:68:31 | password_masked_ineffective_sub : | logging.rb:74:20:74:50 | password_masked_ineffective_sub | | logging.rb:68:35:68:65 | password_masked_ineffective_sub : | logging.rb:68:35:68:88 | call to sub : | -| logging.rb:68:35:68:88 | call to sub : | logging.rb:74:20:74:50 | password_masked_ineffective_sub | +| logging.rb:68:35:68:88 | call to sub : | logging.rb:68:1:68:31 | password_masked_ineffective_sub : | +| logging.rb:70:1:70:32 | password_masked_ineffective_gsub : | logging.rb:76:20:76:51 | password_masked_ineffective_gsub | | logging.rb:70:36:70:67 | password_masked_ineffective_gsub : | logging.rb:70:36:70:86 | call to gsub : | -| logging.rb:70:36:70:86 | call to gsub : | logging.rb:76:20:76:51 | password_masked_ineffective_gsub | +| logging.rb:70:36:70:86 | call to gsub : | logging.rb:70:1:70:32 | password_masked_ineffective_gsub : | | logging.rb:82:9:82:16 | password : | logging.rb:84:15:84:22 | password | -| logging.rb:87:16:87:49 | "65f2950df2f0e2c38d7ba2ccca767291" : | logging.rb:88:5:88:16 | password_arg : | +| logging.rb:87:1:87:12 | password_arg : | logging.rb:88:5:88:16 | password_arg : | +| logging.rb:87:16:87:49 | "65f2950df2f0e2c38d7ba2ccca767291" : | logging.rb:87:1:87:12 | password_arg : | | logging.rb:88:5:88:16 | password_arg : | logging.rb:82:9:82:16 | password : | nodes +| logging.rb:3:1:3:8 | password : | semmle.label | password : | | logging.rb:3:12:3:45 | "043697b96909e03ca907599d6420555f" : | semmle.label | "043697b96909e03ca907599d6420555f" : | | logging.rb:6:20:6:27 | password | semmle.label | password | | logging.rb:8:21:8:28 | password | semmle.label | password | @@ -41,21 +52,29 @@ nodes | logging.rb:23:33:23:40 | password | semmle.label | password | | logging.rb:26:18:26:34 | "pw: #{...}" | semmle.label | "pw: #{...}" | | logging.rb:28:26:28:33 | password | semmle.label | password | +| logging.rb:30:1:30:4 | hsh1 [element :password] : | semmle.label | hsh1 [element :password] : | | logging.rb:30:20:30:53 | "aec5058e61f7f122998b1a30ee2c66b6" : | semmle.label | "aec5058e61f7f122998b1a30ee2c66b6" : | | logging.rb:34:1:34:4 | [post] hsh2 [element :password] : | semmle.label | [post] hsh2 [element :password] : | | logging.rb:34:19:34:52 | "beeda625d7306b45784d91ea0336e201" : | semmle.label | "beeda625d7306b45784d91ea0336e201" : | +| logging.rb:35:1:35:4 | hsh3 [element :password] : | semmle.label | hsh3 [element :password] : | | logging.rb:38:20:38:23 | hsh1 [element :password] : | semmle.label | hsh1 [element :password] : | | logging.rb:38:20:38:34 | ...[...] | semmle.label | ...[...] | | logging.rb:40:20:40:23 | hsh2 [element :password] : | semmle.label | hsh2 [element :password] : | | logging.rb:40:20:40:34 | ...[...] | semmle.label | ...[...] | | logging.rb:42:20:42:23 | hsh3 [element :password] : | semmle.label | hsh3 [element :password] : | | logging.rb:42:20:42:34 | ...[...] | semmle.label | ...[...] | +| logging.rb:64:1:64:31 | password_masked_ineffective_sub : | semmle.label | password_masked_ineffective_sub : | | logging.rb:64:35:64:68 | "ca497451f5e883662fb1a37bc9ec7838" : | semmle.label | "ca497451f5e883662fb1a37bc9ec7838" : | +| logging.rb:65:1:65:34 | password_masked_ineffective_sub_ex : | semmle.label | password_masked_ineffective_sub_ex : | | logging.rb:65:38:65:71 | "ca497451f5e883662fb1a37bc9ec7838" : | semmle.label | "ca497451f5e883662fb1a37bc9ec7838" : | +| logging.rb:66:1:66:32 | password_masked_ineffective_gsub : | semmle.label | password_masked_ineffective_gsub : | | logging.rb:66:36:66:69 | "a7e3747b19930d4f4b8181047194832f" : | semmle.label | "a7e3747b19930d4f4b8181047194832f" : | +| logging.rb:67:1:67:35 | password_masked_ineffective_gsub_ex : | semmle.label | password_masked_ineffective_gsub_ex : | | logging.rb:67:39:67:72 | "a7e3747b19930d4f4b8181047194832f" : | semmle.label | "a7e3747b19930d4f4b8181047194832f" : | +| logging.rb:68:1:68:31 | password_masked_ineffective_sub : | semmle.label | password_masked_ineffective_sub : | | logging.rb:68:35:68:65 | password_masked_ineffective_sub : | semmle.label | password_masked_ineffective_sub : | | logging.rb:68:35:68:88 | call to sub : | semmle.label | call to sub : | +| logging.rb:70:1:70:32 | password_masked_ineffective_gsub : | semmle.label | password_masked_ineffective_gsub : | | logging.rb:70:36:70:67 | password_masked_ineffective_gsub : | semmle.label | password_masked_ineffective_gsub : | | logging.rb:70:36:70:86 | call to gsub : | semmle.label | call to gsub : | | logging.rb:74:20:74:50 | password_masked_ineffective_sub | semmle.label | password_masked_ineffective_sub | @@ -64,6 +83,7 @@ nodes | logging.rb:80:20:80:54 | password_masked_ineffective_gsub_ex | semmle.label | password_masked_ineffective_gsub_ex | | logging.rb:82:9:82:16 | password : | semmle.label | password : | | logging.rb:84:15:84:22 | password | semmle.label | password | +| logging.rb:87:1:87:12 | password_arg : | semmle.label | password_arg : | | logging.rb:87:16:87:49 | "65f2950df2f0e2c38d7ba2ccca767291" : | semmle.label | "65f2950df2f0e2c38d7ba2ccca767291" : | | logging.rb:88:5:88:16 | password_arg : | semmle.label | password_arg : | subpaths diff --git a/ruby/ql/test/query-tests/security/cwe-312/CleartextStorage.expected b/ruby/ql/test/query-tests/security/cwe-312/CleartextStorage.expected index 39f771ed08d..9f8f849b10a 100644 --- a/ruby/ql/test/query-tests/security/cwe-312/CleartextStorage.expected +++ b/ruby/ql/test/query-tests/security/cwe-312/CleartextStorage.expected @@ -1,51 +1,71 @@ edges -| app/controllers/users_controller.rb:3:20:3:53 | "043697b96909e03ca907599d6420555f" : | app/controllers/users_controller.rb:5:39:5:50 | new_password | -| app/controllers/users_controller.rb:3:20:3:53 | "043697b96909e03ca907599d6420555f" : | app/controllers/users_controller.rb:7:41:7:52 | new_password | -| app/controllers/users_controller.rb:11:20:11:53 | "083c9e1da4cc0c2f5480bb4dbe6ff141" : | app/controllers/users_controller.rb:13:42:13:53 | new_password | -| app/controllers/users_controller.rb:11:20:11:53 | "083c9e1da4cc0c2f5480bb4dbe6ff141" : | app/controllers/users_controller.rb:15:49:15:60 | new_password | -| app/controllers/users_controller.rb:11:20:11:53 | "083c9e1da4cc0c2f5480bb4dbe6ff141" : | app/controllers/users_controller.rb:15:49:15:60 | new_password : | -| app/controllers/users_controller.rb:11:20:11:53 | "083c9e1da4cc0c2f5480bb4dbe6ff141" : | app/controllers/users_controller.rb:15:87:15:98 | new_password | +| app/controllers/users_controller.rb:3:5:3:16 | new_password : | app/controllers/users_controller.rb:5:39:5:50 | new_password | +| app/controllers/users_controller.rb:3:5:3:16 | new_password : | app/controllers/users_controller.rb:7:41:7:52 | new_password | +| app/controllers/users_controller.rb:3:20:3:53 | "043697b96909e03ca907599d6420555f" : | app/controllers/users_controller.rb:3:5:3:16 | new_password : | +| app/controllers/users_controller.rb:11:5:11:16 | new_password : | app/controllers/users_controller.rb:13:42:13:53 | new_password | +| app/controllers/users_controller.rb:11:5:11:16 | new_password : | app/controllers/users_controller.rb:15:49:15:60 | new_password | +| app/controllers/users_controller.rb:11:5:11:16 | new_password : | app/controllers/users_controller.rb:15:49:15:60 | new_password : | +| app/controllers/users_controller.rb:11:5:11:16 | new_password : | app/controllers/users_controller.rb:15:87:15:98 | new_password | +| app/controllers/users_controller.rb:11:20:11:53 | "083c9e1da4cc0c2f5480bb4dbe6ff141" : | app/controllers/users_controller.rb:11:5:11:16 | new_password : | | app/controllers/users_controller.rb:15:49:15:60 | new_password : | app/controllers/users_controller.rb:15:87:15:98 | new_password | -| app/controllers/users_controller.rb:19:20:19:53 | "504d224a806cf8073cd14ef08242d422" : | app/controllers/users_controller.rb:21:45:21:56 | new_password | -| app/controllers/users_controller.rb:19:20:19:53 | "504d224a806cf8073cd14ef08242d422" : | app/controllers/users_controller.rb:21:45:21:56 | new_password : | -| app/controllers/users_controller.rb:19:20:19:53 | "504d224a806cf8073cd14ef08242d422" : | app/controllers/users_controller.rb:21:83:21:94 | new_password | +| app/controllers/users_controller.rb:19:5:19:16 | new_password : | app/controllers/users_controller.rb:21:45:21:56 | new_password | +| app/controllers/users_controller.rb:19:5:19:16 | new_password : | app/controllers/users_controller.rb:21:45:21:56 | new_password : | +| app/controllers/users_controller.rb:19:5:19:16 | new_password : | app/controllers/users_controller.rb:21:83:21:94 | new_password | +| app/controllers/users_controller.rb:19:20:19:53 | "504d224a806cf8073cd14ef08242d422" : | app/controllers/users_controller.rb:19:5:19:16 | new_password : | | app/controllers/users_controller.rb:21:45:21:56 | new_password : | app/controllers/users_controller.rb:21:83:21:94 | new_password | -| app/controllers/users_controller.rb:26:20:26:53 | "7d6ae08394c3f284506dca70f05995f6" : | app/controllers/users_controller.rb:28:27:28:38 | new_password | -| app/controllers/users_controller.rb:26:20:26:53 | "7d6ae08394c3f284506dca70f05995f6" : | app/controllers/users_controller.rb:30:28:30:39 | new_password | -| app/controllers/users_controller.rb:35:20:35:53 | "ff295f8648a406c37fbe378377320e4c" : | app/controllers/users_controller.rb:37:39:37:50 | new_password | -| app/controllers/users_controller.rb:42:20:42:53 | "78ffbec583b546bd073efd898f833184" : | app/controllers/users_controller.rb:44:21:44:32 | new_password | -| app/controllers/users_controller.rb:58:20:58:53 | "0157af7c38cbdd24f1616de4e5321861" : | app/controllers/users_controller.rb:61:25:61:53 | "password: #{...}\\n" | -| app/controllers/users_controller.rb:58:20:58:53 | "0157af7c38cbdd24f1616de4e5321861" : | app/controllers/users_controller.rb:64:35:64:61 | "password: #{...}" | -| app/models/user.rb:3:20:3:53 | "06c38c6a8a9c11a9d3b209a3193047b4" : | app/models/user.rb:5:27:5:38 | new_password | -| app/models/user.rb:9:20:9:53 | "52652fb5c709fb6b9b5a0194af7c6067" : | app/models/user.rb:11:22:11:33 | new_password | -| app/models/user.rb:15:20:15:53 | "f982bf2531c149a8a1444a951b12e830" : | app/models/user.rb:17:21:17:32 | new_password | +| app/controllers/users_controller.rb:26:5:26:16 | new_password : | app/controllers/users_controller.rb:28:27:28:38 | new_password | +| app/controllers/users_controller.rb:26:5:26:16 | new_password : | app/controllers/users_controller.rb:30:28:30:39 | new_password | +| app/controllers/users_controller.rb:26:20:26:53 | "7d6ae08394c3f284506dca70f05995f6" : | app/controllers/users_controller.rb:26:5:26:16 | new_password : | +| app/controllers/users_controller.rb:35:5:35:16 | new_password : | app/controllers/users_controller.rb:37:39:37:50 | new_password | +| app/controllers/users_controller.rb:35:20:35:53 | "ff295f8648a406c37fbe378377320e4c" : | app/controllers/users_controller.rb:35:5:35:16 | new_password : | +| app/controllers/users_controller.rb:42:5:42:16 | new_password : | app/controllers/users_controller.rb:44:21:44:32 | new_password | +| app/controllers/users_controller.rb:42:20:42:53 | "78ffbec583b546bd073efd898f833184" : | app/controllers/users_controller.rb:42:5:42:16 | new_password : | +| app/controllers/users_controller.rb:58:5:58:16 | new_password : | app/controllers/users_controller.rb:61:25:61:53 | "password: #{...}\\n" | +| app/controllers/users_controller.rb:58:5:58:16 | new_password : | app/controllers/users_controller.rb:64:35:64:61 | "password: #{...}" | +| app/controllers/users_controller.rb:58:20:58:53 | "0157af7c38cbdd24f1616de4e5321861" : | app/controllers/users_controller.rb:58:5:58:16 | new_password : | +| app/models/user.rb:3:5:3:16 | new_password : | app/models/user.rb:5:27:5:38 | new_password | +| app/models/user.rb:3:20:3:53 | "06c38c6a8a9c11a9d3b209a3193047b4" : | app/models/user.rb:3:5:3:16 | new_password : | +| app/models/user.rb:9:5:9:16 | new_password : | app/models/user.rb:11:22:11:33 | new_password | +| app/models/user.rb:9:20:9:53 | "52652fb5c709fb6b9b5a0194af7c6067" : | app/models/user.rb:9:5:9:16 | new_password : | +| app/models/user.rb:15:5:15:16 | new_password : | app/models/user.rb:17:21:17:32 | new_password | +| app/models/user.rb:15:20:15:53 | "f982bf2531c149a8a1444a951b12e830" : | app/models/user.rb:15:5:15:16 | new_password : | nodes +| app/controllers/users_controller.rb:3:5:3:16 | new_password : | semmle.label | new_password : | | app/controllers/users_controller.rb:3:20:3:53 | "043697b96909e03ca907599d6420555f" : | semmle.label | "043697b96909e03ca907599d6420555f" : | | app/controllers/users_controller.rb:5:39:5:50 | new_password | semmle.label | new_password | | app/controllers/users_controller.rb:7:41:7:52 | new_password | semmle.label | new_password | +| app/controllers/users_controller.rb:11:5:11:16 | new_password : | semmle.label | new_password : | | app/controllers/users_controller.rb:11:20:11:53 | "083c9e1da4cc0c2f5480bb4dbe6ff141" : | semmle.label | "083c9e1da4cc0c2f5480bb4dbe6ff141" : | | app/controllers/users_controller.rb:13:42:13:53 | new_password | semmle.label | new_password | | app/controllers/users_controller.rb:15:49:15:60 | new_password | semmle.label | new_password | | app/controllers/users_controller.rb:15:49:15:60 | new_password : | semmle.label | new_password : | | app/controllers/users_controller.rb:15:87:15:98 | new_password | semmle.label | new_password | +| app/controllers/users_controller.rb:19:5:19:16 | new_password : | semmle.label | new_password : | | app/controllers/users_controller.rb:19:20:19:53 | "504d224a806cf8073cd14ef08242d422" : | semmle.label | "504d224a806cf8073cd14ef08242d422" : | | app/controllers/users_controller.rb:21:45:21:56 | new_password | semmle.label | new_password | | app/controllers/users_controller.rb:21:45:21:56 | new_password : | semmle.label | new_password : | | app/controllers/users_controller.rb:21:83:21:94 | new_password | semmle.label | new_password | +| app/controllers/users_controller.rb:26:5:26:16 | new_password : | semmle.label | new_password : | | app/controllers/users_controller.rb:26:20:26:53 | "7d6ae08394c3f284506dca70f05995f6" : | semmle.label | "7d6ae08394c3f284506dca70f05995f6" : | | app/controllers/users_controller.rb:28:27:28:38 | new_password | semmle.label | new_password | | app/controllers/users_controller.rb:30:28:30:39 | new_password | semmle.label | new_password | +| app/controllers/users_controller.rb:35:5:35:16 | new_password : | semmle.label | new_password : | | app/controllers/users_controller.rb:35:20:35:53 | "ff295f8648a406c37fbe378377320e4c" : | semmle.label | "ff295f8648a406c37fbe378377320e4c" : | | app/controllers/users_controller.rb:37:39:37:50 | new_password | semmle.label | new_password | +| app/controllers/users_controller.rb:42:5:42:16 | new_password : | semmle.label | new_password : | | app/controllers/users_controller.rb:42:20:42:53 | "78ffbec583b546bd073efd898f833184" : | semmle.label | "78ffbec583b546bd073efd898f833184" : | | app/controllers/users_controller.rb:44:21:44:32 | new_password | semmle.label | new_password | +| app/controllers/users_controller.rb:58:5:58:16 | new_password : | semmle.label | new_password : | | app/controllers/users_controller.rb:58:20:58:53 | "0157af7c38cbdd24f1616de4e5321861" : | semmle.label | "0157af7c38cbdd24f1616de4e5321861" : | | app/controllers/users_controller.rb:61:25:61:53 | "password: #{...}\\n" | semmle.label | "password: #{...}\\n" | | app/controllers/users_controller.rb:64:35:64:61 | "password: #{...}" | semmle.label | "password: #{...}" | +| app/models/user.rb:3:5:3:16 | new_password : | semmle.label | new_password : | | app/models/user.rb:3:20:3:53 | "06c38c6a8a9c11a9d3b209a3193047b4" : | semmle.label | "06c38c6a8a9c11a9d3b209a3193047b4" : | | app/models/user.rb:5:27:5:38 | new_password | semmle.label | new_password | +| app/models/user.rb:9:5:9:16 | new_password : | semmle.label | new_password : | | app/models/user.rb:9:20:9:53 | "52652fb5c709fb6b9b5a0194af7c6067" : | semmle.label | "52652fb5c709fb6b9b5a0194af7c6067" : | | app/models/user.rb:11:22:11:33 | new_password | semmle.label | new_password | +| app/models/user.rb:15:5:15:16 | new_password : | semmle.label | new_password : | | app/models/user.rb:15:20:15:53 | "f982bf2531c149a8a1444a951b12e830" : | semmle.label | "f982bf2531c149a8a1444a951b12e830" : | | app/models/user.rb:17:21:17:32 | new_password | semmle.label | new_password | subpaths diff --git a/ruby/ql/test/query-tests/security/cwe-502/oj-global-options/UnsafeDeserialization.expected b/ruby/ql/test/query-tests/security/cwe-502/oj-global-options/UnsafeDeserialization.expected index 72c25575a21..38499665118 100644 --- a/ruby/ql/test/query-tests/security/cwe-502/oj-global-options/UnsafeDeserialization.expected +++ b/ruby/ql/test/query-tests/security/cwe-502/oj-global-options/UnsafeDeserialization.expected @@ -1,7 +1,9 @@ edges +| OjGlobalOptions.rb:13:5:13:13 | json_data : | OjGlobalOptions.rb:14:22:14:30 | json_data | | OjGlobalOptions.rb:13:17:13:22 | call to params : | OjGlobalOptions.rb:13:17:13:28 | ...[...] : | -| OjGlobalOptions.rb:13:17:13:28 | ...[...] : | OjGlobalOptions.rb:14:22:14:30 | json_data | +| OjGlobalOptions.rb:13:17:13:28 | ...[...] : | OjGlobalOptions.rb:13:5:13:13 | json_data : | nodes +| OjGlobalOptions.rb:13:5:13:13 | json_data : | semmle.label | json_data : | | OjGlobalOptions.rb:13:17:13:22 | call to params : | semmle.label | call to params : | | OjGlobalOptions.rb:13:17:13:28 | ...[...] : | semmle.label | ...[...] : | | OjGlobalOptions.rb:14:22:14:30 | json_data | semmle.label | json_data | diff --git a/ruby/ql/test/query-tests/security/cwe-502/unsafe-deserialization/UnsafeDeserialization.expected b/ruby/ql/test/query-tests/security/cwe-502/unsafe-deserialization/UnsafeDeserialization.expected index fe4addd5d4d..13fe16295d9 100644 --- a/ruby/ql/test/query-tests/security/cwe-502/unsafe-deserialization/UnsafeDeserialization.expected +++ b/ruby/ql/test/query-tests/security/cwe-502/unsafe-deserialization/UnsafeDeserialization.expected @@ -1,53 +1,71 @@ edges -| UnsafeDeserialization.rb:10:23:10:50 | call to decode64 : | UnsafeDeserialization.rb:11:27:11:41 | serialized_data | +| UnsafeDeserialization.rb:10:5:10:19 | serialized_data : | UnsafeDeserialization.rb:11:27:11:41 | serialized_data | +| UnsafeDeserialization.rb:10:23:10:50 | call to decode64 : | UnsafeDeserialization.rb:10:5:10:19 | serialized_data : | | UnsafeDeserialization.rb:10:39:10:44 | call to params : | UnsafeDeserialization.rb:10:39:10:50 | ...[...] : | | UnsafeDeserialization.rb:10:39:10:50 | ...[...] : | UnsafeDeserialization.rb:10:23:10:50 | call to decode64 : | -| UnsafeDeserialization.rb:16:23:16:50 | call to decode64 : | UnsafeDeserialization.rb:17:30:17:44 | serialized_data | +| UnsafeDeserialization.rb:16:5:16:19 | serialized_data : | UnsafeDeserialization.rb:17:30:17:44 | serialized_data | +| UnsafeDeserialization.rb:16:23:16:50 | call to decode64 : | UnsafeDeserialization.rb:16:5:16:19 | serialized_data : | | UnsafeDeserialization.rb:16:39:16:44 | call to params : | UnsafeDeserialization.rb:16:39:16:50 | ...[...] : | | UnsafeDeserialization.rb:16:39:16:50 | ...[...] : | UnsafeDeserialization.rb:16:23:16:50 | call to decode64 : | +| UnsafeDeserialization.rb:22:5:22:13 | json_data : | UnsafeDeserialization.rb:23:24:23:32 | json_data | | UnsafeDeserialization.rb:22:17:22:22 | call to params : | UnsafeDeserialization.rb:22:17:22:28 | ...[...] : | -| UnsafeDeserialization.rb:22:17:22:28 | ...[...] : | UnsafeDeserialization.rb:23:24:23:32 | json_data | +| UnsafeDeserialization.rb:22:17:22:28 | ...[...] : | UnsafeDeserialization.rb:22:5:22:13 | json_data : | +| UnsafeDeserialization.rb:28:5:28:13 | json_data : | UnsafeDeserialization.rb:29:27:29:35 | json_data | | UnsafeDeserialization.rb:28:17:28:22 | call to params : | UnsafeDeserialization.rb:28:17:28:28 | ...[...] : | -| UnsafeDeserialization.rb:28:17:28:28 | ...[...] : | UnsafeDeserialization.rb:29:27:29:35 | json_data | +| UnsafeDeserialization.rb:28:17:28:28 | ...[...] : | UnsafeDeserialization.rb:28:5:28:13 | json_data : | +| UnsafeDeserialization.rb:40:5:40:13 | yaml_data : | UnsafeDeserialization.rb:41:24:41:32 | yaml_data | | UnsafeDeserialization.rb:40:17:40:22 | call to params : | UnsafeDeserialization.rb:40:17:40:28 | ...[...] : | -| UnsafeDeserialization.rb:40:17:40:28 | ...[...] : | UnsafeDeserialization.rb:41:24:41:32 | yaml_data | +| UnsafeDeserialization.rb:40:17:40:28 | ...[...] : | UnsafeDeserialization.rb:40:5:40:13 | yaml_data : | +| UnsafeDeserialization.rb:52:5:52:13 | json_data : | UnsafeDeserialization.rb:53:22:53:30 | json_data | +| UnsafeDeserialization.rb:52:5:52:13 | json_data : | UnsafeDeserialization.rb:54:22:54:30 | json_data | | UnsafeDeserialization.rb:52:17:52:22 | call to params : | UnsafeDeserialization.rb:52:17:52:28 | ...[...] : | -| UnsafeDeserialization.rb:52:17:52:28 | ...[...] : | UnsafeDeserialization.rb:53:22:53:30 | json_data | -| UnsafeDeserialization.rb:52:17:52:28 | ...[...] : | UnsafeDeserialization.rb:54:22:54:30 | json_data | +| UnsafeDeserialization.rb:52:17:52:28 | ...[...] : | UnsafeDeserialization.rb:52:5:52:13 | json_data : | +| UnsafeDeserialization.rb:59:5:59:13 | json_data : | UnsafeDeserialization.rb:69:23:69:31 | json_data | | UnsafeDeserialization.rb:59:17:59:22 | call to params : | UnsafeDeserialization.rb:59:17:59:28 | ...[...] : | -| UnsafeDeserialization.rb:59:17:59:28 | ...[...] : | UnsafeDeserialization.rb:69:23:69:31 | json_data | +| UnsafeDeserialization.rb:59:17:59:28 | ...[...] : | UnsafeDeserialization.rb:59:5:59:13 | json_data : | +| UnsafeDeserialization.rb:81:5:81:7 | xml : | UnsafeDeserialization.rb:82:34:82:36 | xml | | UnsafeDeserialization.rb:81:11:81:16 | call to params : | UnsafeDeserialization.rb:81:11:81:22 | ...[...] : | -| UnsafeDeserialization.rb:81:11:81:22 | ...[...] : | UnsafeDeserialization.rb:82:34:82:36 | xml | +| UnsafeDeserialization.rb:81:11:81:22 | ...[...] : | UnsafeDeserialization.rb:81:5:81:7 | xml : | +| UnsafeDeserialization.rb:87:5:87:13 | yaml_data : | UnsafeDeserialization.rb:88:25:88:33 | yaml_data | | UnsafeDeserialization.rb:87:17:87:22 | call to params : | UnsafeDeserialization.rb:87:17:87:28 | ...[...] : | -| UnsafeDeserialization.rb:87:17:87:28 | ...[...] : | UnsafeDeserialization.rb:88:25:88:33 | yaml_data | +| UnsafeDeserialization.rb:87:17:87:28 | ...[...] : | UnsafeDeserialization.rb:87:5:87:13 | yaml_data : | nodes +| UnsafeDeserialization.rb:10:5:10:19 | serialized_data : | semmle.label | serialized_data : | | UnsafeDeserialization.rb:10:23:10:50 | call to decode64 : | semmle.label | call to decode64 : | | UnsafeDeserialization.rb:10:39:10:44 | call to params : | semmle.label | call to params : | | UnsafeDeserialization.rb:10:39:10:50 | ...[...] : | semmle.label | ...[...] : | | UnsafeDeserialization.rb:11:27:11:41 | serialized_data | semmle.label | serialized_data | +| UnsafeDeserialization.rb:16:5:16:19 | serialized_data : | semmle.label | serialized_data : | | UnsafeDeserialization.rb:16:23:16:50 | call to decode64 : | semmle.label | call to decode64 : | | UnsafeDeserialization.rb:16:39:16:44 | call to params : | semmle.label | call to params : | | UnsafeDeserialization.rb:16:39:16:50 | ...[...] : | semmle.label | ...[...] : | | UnsafeDeserialization.rb:17:30:17:44 | serialized_data | semmle.label | serialized_data | +| UnsafeDeserialization.rb:22:5:22:13 | json_data : | semmle.label | json_data : | | UnsafeDeserialization.rb:22:17:22:22 | call to params : | semmle.label | call to params : | | UnsafeDeserialization.rb:22:17:22:28 | ...[...] : | semmle.label | ...[...] : | | UnsafeDeserialization.rb:23:24:23:32 | json_data | semmle.label | json_data | +| UnsafeDeserialization.rb:28:5:28:13 | json_data : | semmle.label | json_data : | | UnsafeDeserialization.rb:28:17:28:22 | call to params : | semmle.label | call to params : | | UnsafeDeserialization.rb:28:17:28:28 | ...[...] : | semmle.label | ...[...] : | | UnsafeDeserialization.rb:29:27:29:35 | json_data | semmle.label | json_data | +| UnsafeDeserialization.rb:40:5:40:13 | yaml_data : | semmle.label | yaml_data : | | UnsafeDeserialization.rb:40:17:40:22 | call to params : | semmle.label | call to params : | | UnsafeDeserialization.rb:40:17:40:28 | ...[...] : | semmle.label | ...[...] : | | UnsafeDeserialization.rb:41:24:41:32 | yaml_data | semmle.label | yaml_data | +| UnsafeDeserialization.rb:52:5:52:13 | json_data : | semmle.label | json_data : | | UnsafeDeserialization.rb:52:17:52:22 | call to params : | semmle.label | call to params : | | UnsafeDeserialization.rb:52:17:52:28 | ...[...] : | semmle.label | ...[...] : | | UnsafeDeserialization.rb:53:22:53:30 | json_data | semmle.label | json_data | | UnsafeDeserialization.rb:54:22:54:30 | json_data | semmle.label | json_data | +| UnsafeDeserialization.rb:59:5:59:13 | json_data : | semmle.label | json_data : | | UnsafeDeserialization.rb:59:17:59:22 | call to params : | semmle.label | call to params : | | UnsafeDeserialization.rb:59:17:59:28 | ...[...] : | semmle.label | ...[...] : | | UnsafeDeserialization.rb:69:23:69:31 | json_data | semmle.label | json_data | +| UnsafeDeserialization.rb:81:5:81:7 | xml : | semmle.label | xml : | | UnsafeDeserialization.rb:81:11:81:16 | call to params : | semmle.label | call to params : | | UnsafeDeserialization.rb:81:11:81:22 | ...[...] : | semmle.label | ...[...] : | | UnsafeDeserialization.rb:82:34:82:36 | xml | semmle.label | xml | +| UnsafeDeserialization.rb:87:5:87:13 | yaml_data : | semmle.label | yaml_data : | | UnsafeDeserialization.rb:87:17:87:22 | call to params : | semmle.label | call to params : | | UnsafeDeserialization.rb:87:17:87:28 | ...[...] : | semmle.label | ...[...] : | | UnsafeDeserialization.rb:88:25:88:33 | yaml_data | semmle.label | yaml_data | diff --git a/ruby/ql/test/query-tests/security/cwe-506/HardcodedDataInterpretedAsCode.expected b/ruby/ql/test/query-tests/security/cwe-506/HardcodedDataInterpretedAsCode.expected index a52134aa7db..cf3cc204cbd 100644 --- a/ruby/ql/test/query-tests/security/cwe-506/HardcodedDataInterpretedAsCode.expected +++ b/ruby/ql/test/query-tests/security/cwe-506/HardcodedDataInterpretedAsCode.expected @@ -1,22 +1,26 @@ edges | tst.rb:1:7:1:7 | r : | tst.rb:2:4:2:4 | r : | | tst.rb:2:4:2:4 | r : | tst.rb:2:3:2:15 | call to pack : | -| tst.rb:5:27:5:72 | "707574732822636f646520696e6a6..." : | tst.rb:7:8:7:30 | totally_harmless_string : | +| tst.rb:5:1:5:23 | totally_harmless_string : | tst.rb:7:8:7:30 | totally_harmless_string : | +| tst.rb:5:27:5:72 | "707574732822636f646520696e6a6..." : | tst.rb:5:1:5:23 | totally_harmless_string : | | tst.rb:7:8:7:30 | totally_harmless_string : | tst.rb:1:7:1:7 | r : | | tst.rb:7:8:7:30 | totally_harmless_string : | tst.rb:7:6:7:31 | call to e | | tst.rb:10:11:10:24 | "666f6f626172" : | tst.rb:1:7:1:7 | r : | | tst.rb:10:11:10:24 | "666f6f626172" : | tst.rb:10:9:10:25 | call to e | -| tst.rb:16:31:16:84 | "\\x70\\x75\\x74\\x73\\x28\\x27\\x68\\..." : | tst.rb:17:6:17:32 | another_questionable_string : | +| tst.rb:16:1:16:27 | another_questionable_string : | tst.rb:17:6:17:32 | another_questionable_string : | +| tst.rb:16:31:16:84 | "\\x70\\x75\\x74\\x73\\x28\\x27\\x68\\..." : | tst.rb:16:1:16:27 | another_questionable_string : | | tst.rb:17:6:17:32 | another_questionable_string : | tst.rb:17:6:17:38 | call to strip | nodes | tst.rb:1:7:1:7 | r : | semmle.label | r : | | tst.rb:2:3:2:15 | call to pack : | semmle.label | call to pack : | | tst.rb:2:4:2:4 | r : | semmle.label | r : | +| tst.rb:5:1:5:23 | totally_harmless_string : | semmle.label | totally_harmless_string : | | tst.rb:5:27:5:72 | "707574732822636f646520696e6a6..." : | semmle.label | "707574732822636f646520696e6a6..." : | | tst.rb:7:6:7:31 | call to e | semmle.label | call to e | | tst.rb:7:8:7:30 | totally_harmless_string : | semmle.label | totally_harmless_string : | | tst.rb:10:9:10:25 | call to e | semmle.label | call to e | | tst.rb:10:11:10:24 | "666f6f626172" : | semmle.label | "666f6f626172" : | +| tst.rb:16:1:16:27 | another_questionable_string : | semmle.label | another_questionable_string : | | tst.rb:16:31:16:84 | "\\x70\\x75\\x74\\x73\\x28\\x27\\x68\\..." : | semmle.label | "\\x70\\x75\\x74\\x73\\x28\\x27\\x68\\..." : | | tst.rb:17:6:17:32 | another_questionable_string : | semmle.label | another_questionable_string : | | tst.rb:17:6:17:38 | call to strip | semmle.label | call to strip | diff --git a/ruby/ql/test/query-tests/security/cwe-598/SensitiveGetQuery.expected b/ruby/ql/test/query-tests/security/cwe-598/SensitiveGetQuery.expected index 005e2497be8..5fd00e43faf 100644 --- a/ruby/ql/test/query-tests/security/cwe-598/SensitiveGetQuery.expected +++ b/ruby/ql/test/query-tests/security/cwe-598/SensitiveGetQuery.expected @@ -1,7 +1,8 @@ edges | app/controllers/users_controller.rb:4:11:4:16 | call to params : | app/controllers/users_controller.rb:4:11:4:27 | ...[...] | +| app/controllers/users_controller.rb:9:5:9:12 | password : | app/controllers/users_controller.rb:10:42:10:49 | password | | app/controllers/users_controller.rb:9:16:9:21 | call to params : | app/controllers/users_controller.rb:9:16:9:27 | ...[...] : | -| app/controllers/users_controller.rb:9:16:9:27 | ...[...] : | app/controllers/users_controller.rb:10:42:10:49 | password | +| app/controllers/users_controller.rb:9:16:9:27 | ...[...] : | app/controllers/users_controller.rb:9:5:9:12 | password : | | app/controllers/users_controller.rb:14:5:14:13 | [post] self [@password] : | app/controllers/users_controller.rb:15:42:15:50 | self [@password] : | | app/controllers/users_controller.rb:14:17:14:22 | call to params : | app/controllers/users_controller.rb:14:17:14:28 | ...[...] : | | app/controllers/users_controller.rb:14:17:14:28 | ...[...] : | app/controllers/users_controller.rb:14:5:14:13 | [post] self [@password] : | @@ -9,6 +10,7 @@ edges nodes | app/controllers/users_controller.rb:4:11:4:16 | call to params : | semmle.label | call to params : | | app/controllers/users_controller.rb:4:11:4:27 | ...[...] | semmle.label | ...[...] | +| app/controllers/users_controller.rb:9:5:9:12 | password : | semmle.label | password : | | app/controllers/users_controller.rb:9:16:9:21 | call to params : | semmle.label | call to params : | | app/controllers/users_controller.rb:9:16:9:27 | ...[...] : | semmle.label | ...[...] : | | app/controllers/users_controller.rb:10:42:10:49 | password | semmle.label | password | diff --git a/ruby/ql/test/query-tests/security/cwe-611/libxml-backend/Xxe.expected b/ruby/ql/test/query-tests/security/cwe-611/libxml-backend/Xxe.expected index 30f57223c4b..6e0473c62c8 100644 --- a/ruby/ql/test/query-tests/security/cwe-611/libxml-backend/Xxe.expected +++ b/ruby/ql/test/query-tests/security/cwe-611/libxml-backend/Xxe.expected @@ -1,10 +1,12 @@ edges +| LibXmlBackend.rb:16:5:16:11 | content : | LibXmlBackend.rb:18:30:18:36 | content | +| LibXmlBackend.rb:16:5:16:11 | content : | LibXmlBackend.rb:19:19:19:25 | content | +| LibXmlBackend.rb:16:5:16:11 | content : | LibXmlBackend.rb:20:27:20:33 | content | +| LibXmlBackend.rb:16:5:16:11 | content : | LibXmlBackend.rb:21:34:21:40 | content | | LibXmlBackend.rb:16:15:16:20 | call to params : | LibXmlBackend.rb:16:15:16:26 | ...[...] : | -| LibXmlBackend.rb:16:15:16:26 | ...[...] : | LibXmlBackend.rb:18:30:18:36 | content | -| LibXmlBackend.rb:16:15:16:26 | ...[...] : | LibXmlBackend.rb:19:19:19:25 | content | -| LibXmlBackend.rb:16:15:16:26 | ...[...] : | LibXmlBackend.rb:20:27:20:33 | content | -| LibXmlBackend.rb:16:15:16:26 | ...[...] : | LibXmlBackend.rb:21:34:21:40 | content | +| LibXmlBackend.rb:16:15:16:26 | ...[...] : | LibXmlBackend.rb:16:5:16:11 | content : | nodes +| LibXmlBackend.rb:16:5:16:11 | content : | semmle.label | content : | | LibXmlBackend.rb:16:15:16:20 | call to params : | semmle.label | call to params : | | LibXmlBackend.rb:16:15:16:26 | ...[...] : | semmle.label | ...[...] : | | LibXmlBackend.rb:18:30:18:36 | content | semmle.label | content | diff --git a/ruby/ql/test/query-tests/security/cwe-611/xxe/Xxe.expected b/ruby/ql/test/query-tests/security/cwe-611/xxe/Xxe.expected index 442e5a9cfd4..638a3f3f805 100644 --- a/ruby/ql/test/query-tests/security/cwe-611/xxe/Xxe.expected +++ b/ruby/ql/test/query-tests/security/cwe-611/xxe/Xxe.expected @@ -1,30 +1,33 @@ edges +| LibXmlRuby.rb:3:5:3:11 | content : | LibXmlRuby.rb:4:34:4:40 | content | +| LibXmlRuby.rb:3:5:3:11 | content : | LibXmlRuby.rb:5:32:5:38 | content | +| LibXmlRuby.rb:3:5:3:11 | content : | LibXmlRuby.rb:6:30:6:36 | content | +| LibXmlRuby.rb:3:5:3:11 | content : | LibXmlRuby.rb:7:32:7:38 | content | +| LibXmlRuby.rb:3:5:3:11 | content : | LibXmlRuby.rb:8:30:8:36 | content | +| LibXmlRuby.rb:3:5:3:11 | content : | LibXmlRuby.rb:9:28:9:34 | content | +| LibXmlRuby.rb:3:5:3:11 | content : | LibXmlRuby.rb:11:26:11:32 | content | +| LibXmlRuby.rb:3:5:3:11 | content : | LibXmlRuby.rb:12:24:12:30 | content | | LibXmlRuby.rb:3:15:3:20 | call to params : | LibXmlRuby.rb:3:15:3:26 | ...[...] : | -| LibXmlRuby.rb:3:15:3:26 | ...[...] : | LibXmlRuby.rb:4:34:4:40 | content | -| LibXmlRuby.rb:3:15:3:26 | ...[...] : | LibXmlRuby.rb:5:32:5:38 | content | -| LibXmlRuby.rb:3:15:3:26 | ...[...] : | LibXmlRuby.rb:6:30:6:36 | content | -| LibXmlRuby.rb:3:15:3:26 | ...[...] : | LibXmlRuby.rb:7:32:7:38 | content | -| LibXmlRuby.rb:3:15:3:26 | ...[...] : | LibXmlRuby.rb:8:30:8:36 | content | -| LibXmlRuby.rb:3:15:3:26 | ...[...] : | LibXmlRuby.rb:9:28:9:34 | content | -| LibXmlRuby.rb:3:15:3:26 | ...[...] : | LibXmlRuby.rb:11:26:11:32 | content | -| LibXmlRuby.rb:3:15:3:26 | ...[...] : | LibXmlRuby.rb:12:24:12:30 | content | +| LibXmlRuby.rb:3:15:3:26 | ...[...] : | LibXmlRuby.rb:3:5:3:11 | content : | +| Nokogiri.rb:3:5:3:11 | content : | Nokogiri.rb:5:26:5:32 | content | +| Nokogiri.rb:3:5:3:11 | content : | Nokogiri.rb:6:26:6:32 | content | +| Nokogiri.rb:3:5:3:11 | content : | Nokogiri.rb:7:26:7:32 | content | +| Nokogiri.rb:3:5:3:11 | content : | Nokogiri.rb:8:26:8:32 | content | +| Nokogiri.rb:3:5:3:11 | content : | Nokogiri.rb:9:26:9:32 | content | +| Nokogiri.rb:3:5:3:11 | content : | Nokogiri.rb:11:26:11:32 | content | +| Nokogiri.rb:3:5:3:11 | content : | Nokogiri.rb:12:26:12:32 | content | +| Nokogiri.rb:3:5:3:11 | content : | Nokogiri.rb:15:26:15:32 | content | +| Nokogiri.rb:3:5:3:11 | content : | Nokogiri.rb:16:26:16:32 | content | +| Nokogiri.rb:3:5:3:11 | content : | Nokogiri.rb:18:26:18:32 | content | +| Nokogiri.rb:3:5:3:11 | content : | Nokogiri.rb:19:26:19:32 | content | +| Nokogiri.rb:3:5:3:11 | content : | Nokogiri.rb:22:26:22:32 | content | +| Nokogiri.rb:3:5:3:11 | content : | Nokogiri.rb:25:26:25:32 | content | +| Nokogiri.rb:3:5:3:11 | content : | Nokogiri.rb:27:26:27:32 | content | +| Nokogiri.rb:3:5:3:11 | content : | Nokogiri.rb:28:26:28:32 | content | | Nokogiri.rb:3:15:3:20 | call to params : | Nokogiri.rb:3:15:3:26 | ...[...] : | -| Nokogiri.rb:3:15:3:26 | ...[...] : | Nokogiri.rb:5:26:5:32 | content | -| Nokogiri.rb:3:15:3:26 | ...[...] : | Nokogiri.rb:6:26:6:32 | content | -| Nokogiri.rb:3:15:3:26 | ...[...] : | Nokogiri.rb:7:26:7:32 | content | -| Nokogiri.rb:3:15:3:26 | ...[...] : | Nokogiri.rb:8:26:8:32 | content | -| Nokogiri.rb:3:15:3:26 | ...[...] : | Nokogiri.rb:9:26:9:32 | content | -| Nokogiri.rb:3:15:3:26 | ...[...] : | Nokogiri.rb:11:26:11:32 | content | -| Nokogiri.rb:3:15:3:26 | ...[...] : | Nokogiri.rb:12:26:12:32 | content | -| Nokogiri.rb:3:15:3:26 | ...[...] : | Nokogiri.rb:15:26:15:32 | content | -| Nokogiri.rb:3:15:3:26 | ...[...] : | Nokogiri.rb:16:26:16:32 | content | -| Nokogiri.rb:3:15:3:26 | ...[...] : | Nokogiri.rb:18:26:18:32 | content | -| Nokogiri.rb:3:15:3:26 | ...[...] : | Nokogiri.rb:19:26:19:32 | content | -| Nokogiri.rb:3:15:3:26 | ...[...] : | Nokogiri.rb:22:26:22:32 | content | -| Nokogiri.rb:3:15:3:26 | ...[...] : | Nokogiri.rb:25:26:25:32 | content | -| Nokogiri.rb:3:15:3:26 | ...[...] : | Nokogiri.rb:27:26:27:32 | content | -| Nokogiri.rb:3:15:3:26 | ...[...] : | Nokogiri.rb:28:26:28:32 | content | +| Nokogiri.rb:3:15:3:26 | ...[...] : | Nokogiri.rb:3:5:3:11 | content : | nodes +| LibXmlRuby.rb:3:5:3:11 | content : | semmle.label | content : | | LibXmlRuby.rb:3:15:3:20 | call to params : | semmle.label | call to params : | | LibXmlRuby.rb:3:15:3:26 | ...[...] : | semmle.label | ...[...] : | | LibXmlRuby.rb:4:34:4:40 | content | semmle.label | content | @@ -35,6 +38,7 @@ nodes | LibXmlRuby.rb:9:28:9:34 | content | semmle.label | content | | LibXmlRuby.rb:11:26:11:32 | content | semmle.label | content | | LibXmlRuby.rb:12:24:12:30 | content | semmle.label | content | +| Nokogiri.rb:3:5:3:11 | content : | semmle.label | content : | | Nokogiri.rb:3:15:3:20 | call to params : | semmle.label | call to params : | | Nokogiri.rb:3:15:3:26 | ...[...] : | semmle.label | ...[...] : | | Nokogiri.rb:5:26:5:32 | content | semmle.label | content | diff --git a/ruby/ql/test/query-tests/security/cwe-732/WeakFilePermissions.expected b/ruby/ql/test/query-tests/security/cwe-732/WeakFilePermissions.expected index a7669549247..5df273f589f 100644 --- a/ruby/ql/test/query-tests/security/cwe-732/WeakFilePermissions.expected +++ b/ruby/ql/test/query-tests/security/cwe-732/WeakFilePermissions.expected @@ -1,17 +1,25 @@ edges -| FilePermissions.rb:51:10:51:13 | 0777 : | FilePermissions.rb:53:19:53:22 | perm | -| FilePermissions.rb:51:10:51:13 | 0777 : | FilePermissions.rb:56:19:56:23 | perm2 | -| FilePermissions.rb:58:10:58:26 | "u=wrx,g=rwx,o=x" : | FilePermissions.rb:61:19:61:23 | perm2 | +| FilePermissions.rb:51:3:51:6 | perm : | FilePermissions.rb:53:19:53:22 | perm | +| FilePermissions.rb:51:3:51:6 | perm : | FilePermissions.rb:54:3:54:7 | perm2 : | +| FilePermissions.rb:51:10:51:13 | 0777 : | FilePermissions.rb:51:3:51:6 | perm : | +| FilePermissions.rb:54:3:54:7 | perm2 : | FilePermissions.rb:56:19:56:23 | perm2 | +| FilePermissions.rb:58:3:58:6 | perm : | FilePermissions.rb:59:3:59:7 | perm2 : | +| FilePermissions.rb:58:10:58:26 | "u=wrx,g=rwx,o=x" : | FilePermissions.rb:58:3:58:6 | perm : | +| FilePermissions.rb:59:3:59:7 | perm2 : | FilePermissions.rb:61:19:61:23 | perm2 | nodes | FilePermissions.rb:5:19:5:22 | 0222 | semmle.label | 0222 | | FilePermissions.rb:7:19:7:22 | 0622 | semmle.label | 0622 | | FilePermissions.rb:9:19:9:22 | 0755 | semmle.label | 0755 | | FilePermissions.rb:11:19:11:22 | 0777 | semmle.label | 0777 | | FilePermissions.rb:28:13:28:16 | 0755 | semmle.label | 0755 | +| FilePermissions.rb:51:3:51:6 | perm : | semmle.label | perm : | | FilePermissions.rb:51:10:51:13 | 0777 : | semmle.label | 0777 : | | FilePermissions.rb:53:19:53:22 | perm | semmle.label | perm | +| FilePermissions.rb:54:3:54:7 | perm2 : | semmle.label | perm2 : | | FilePermissions.rb:56:19:56:23 | perm2 | semmle.label | perm2 | +| FilePermissions.rb:58:3:58:6 | perm : | semmle.label | perm : | | FilePermissions.rb:58:10:58:26 | "u=wrx,g=rwx,o=x" : | semmle.label | "u=wrx,g=rwx,o=x" : | +| FilePermissions.rb:59:3:59:7 | perm2 : | semmle.label | perm2 : | | FilePermissions.rb:61:19:61:23 | perm2 | semmle.label | perm2 | | FilePermissions.rb:63:19:63:29 | "u=rwx,o+r" | semmle.label | "u=rwx,o+r" | | FilePermissions.rb:67:19:67:24 | "a+rw" | semmle.label | "a+rw" | diff --git a/ruby/ql/test/query-tests/security/cwe-798/HardcodedCredentials.expected b/ruby/ql/test/query-tests/security/cwe-798/HardcodedCredentials.expected index 51e45945d0f..4d358671e34 100644 --- a/ruby/ql/test/query-tests/security/cwe-798/HardcodedCredentials.expected +++ b/ruby/ql/test/query-tests/security/cwe-798/HardcodedCredentials.expected @@ -3,8 +3,11 @@ edges | HardcodedCredentials.rb:15:30:15:75 | "WLC17dLQ9P8YlQvqm77qplOMm5pd1..." : | HardcodedCredentials.rb:1:33:1:36 | cert | | HardcodedCredentials.rb:18:19:18:72 | ... + ... : | HardcodedCredentials.rb:1:23:1:30 | password | | HardcodedCredentials.rb:18:27:18:72 | "ogH6qSYWGdbR/2WOGYa7eZ/tObL+G..." : | HardcodedCredentials.rb:18:19:18:72 | ... + ... : | -| HardcodedCredentials.rb:20:11:20:76 | "3jOe7sXKX6Tx52qHWUVqh2t9LNsE+..." : | HardcodedCredentials.rb:23:19:23:20 | pw : | -| HardcodedCredentials.rb:21:12:21:37 | "4fQuzXef4f2yow8KWvIJTA==" : | HardcodedCredentials.rb:23:19:23:20 | pw : | +| HardcodedCredentials.rb:20:1:20:7 | pw_left : | HardcodedCredentials.rb:22:1:22:2 | pw : | +| HardcodedCredentials.rb:20:11:20:76 | "3jOe7sXKX6Tx52qHWUVqh2t9LNsE+..." : | HardcodedCredentials.rb:20:1:20:7 | pw_left : | +| HardcodedCredentials.rb:21:1:21:8 | pw_right : | HardcodedCredentials.rb:22:1:22:2 | pw : | +| HardcodedCredentials.rb:21:12:21:37 | "4fQuzXef4f2yow8KWvIJTA==" : | HardcodedCredentials.rb:21:1:21:8 | pw_right : | +| HardcodedCredentials.rb:22:1:22:2 | pw : | HardcodedCredentials.rb:23:19:23:20 | pw : | | HardcodedCredentials.rb:23:19:23:20 | pw : | HardcodedCredentials.rb:1:23:1:30 | password | | HardcodedCredentials.rb:38:40:38:85 | "kdW/xVhiv6y1fQQNevDpUaq+2rfPK..." : | HardcodedCredentials.rb:31:18:31:23 | passwd | | HardcodedCredentials.rb:43:29:43:43 | "user@test.com" : | HardcodedCredentials.rb:43:18:43:25 | username | @@ -19,8 +22,11 @@ nodes | HardcodedCredentials.rb:15:30:15:75 | "WLC17dLQ9P8YlQvqm77qplOMm5pd1..." : | semmle.label | "WLC17dLQ9P8YlQvqm77qplOMm5pd1..." : | | HardcodedCredentials.rb:18:19:18:72 | ... + ... : | semmle.label | ... + ... : | | HardcodedCredentials.rb:18:27:18:72 | "ogH6qSYWGdbR/2WOGYa7eZ/tObL+G..." : | semmle.label | "ogH6qSYWGdbR/2WOGYa7eZ/tObL+G..." : | +| HardcodedCredentials.rb:20:1:20:7 | pw_left : | semmle.label | pw_left : | | HardcodedCredentials.rb:20:11:20:76 | "3jOe7sXKX6Tx52qHWUVqh2t9LNsE+..." : | semmle.label | "3jOe7sXKX6Tx52qHWUVqh2t9LNsE+..." : | +| HardcodedCredentials.rb:21:1:21:8 | pw_right : | semmle.label | pw_right : | | HardcodedCredentials.rb:21:12:21:37 | "4fQuzXef4f2yow8KWvIJTA==" : | semmle.label | "4fQuzXef4f2yow8KWvIJTA==" : | +| HardcodedCredentials.rb:22:1:22:2 | pw : | semmle.label | pw : | | HardcodedCredentials.rb:23:19:23:20 | pw : | semmle.label | pw : | | HardcodedCredentials.rb:31:18:31:23 | passwd | semmle.label | passwd | | HardcodedCredentials.rb:38:40:38:85 | "kdW/xVhiv6y1fQQNevDpUaq+2rfPK..." : | semmle.label | "kdW/xVhiv6y1fQQNevDpUaq+2rfPK..." : | diff --git a/ruby/ql/test/query-tests/security/cwe-807-user-controlled-bypass/ConditionalBypass.expected b/ruby/ql/test/query-tests/security/cwe-807-user-controlled-bypass/ConditionalBypass.expected index 912900936a1..32b778130ef 100644 --- a/ruby/ql/test/query-tests/security/cwe-807-user-controlled-bypass/ConditionalBypass.expected +++ b/ruby/ql/test/query-tests/security/cwe-807-user-controlled-bypass/ConditionalBypass.expected @@ -1,16 +1,20 @@ edges +| ConditionalBypass.rb:3:5:3:9 | check : | ConditionalBypass.rb:6:8:6:12 | check | | ConditionalBypass.rb:3:13:3:18 | call to params : | ConditionalBypass.rb:3:13:3:26 | ...[...] : | -| ConditionalBypass.rb:3:13:3:26 | ...[...] : | ConditionalBypass.rb:6:8:6:12 | check | +| ConditionalBypass.rb:3:13:3:26 | ...[...] : | ConditionalBypass.rb:3:5:3:9 | check : | | ConditionalBypass.rb:14:14:14:19 | call to params : | ConditionalBypass.rb:14:14:14:27 | ...[...] | +| ConditionalBypass.rb:25:5:25:5 | p : | ConditionalBypass.rb:27:8:27:8 | p | | ConditionalBypass.rb:25:10:25:15 | call to params : | ConditionalBypass.rb:25:10:25:22 | ...[...] | | ConditionalBypass.rb:25:10:25:15 | call to params : | ConditionalBypass.rb:25:10:25:22 | ...[...] : | -| ConditionalBypass.rb:25:10:25:22 | ...[...] : | ConditionalBypass.rb:27:8:27:8 | p | +| ConditionalBypass.rb:25:10:25:22 | ...[...] : | ConditionalBypass.rb:25:5:25:5 | p : | nodes +| ConditionalBypass.rb:3:5:3:9 | check : | semmle.label | check : | | ConditionalBypass.rb:3:13:3:18 | call to params : | semmle.label | call to params : | | ConditionalBypass.rb:3:13:3:26 | ...[...] : | semmle.label | ...[...] : | | ConditionalBypass.rb:6:8:6:12 | check | semmle.label | check | | ConditionalBypass.rb:14:14:14:19 | call to params : | semmle.label | call to params : | | ConditionalBypass.rb:14:14:14:27 | ...[...] | semmle.label | ...[...] | +| ConditionalBypass.rb:25:5:25:5 | p : | semmle.label | p : | | ConditionalBypass.rb:25:10:25:15 | call to params : | semmle.label | call to params : | | ConditionalBypass.rb:25:10:25:22 | ...[...] | semmle.label | ...[...] | | ConditionalBypass.rb:25:10:25:22 | ...[...] : | semmle.label | ...[...] : | diff --git a/ruby/ql/test/query-tests/security/cwe-829/InsecureDownload.expected b/ruby/ql/test/query-tests/security/cwe-829/InsecureDownload.expected index 77e26750686..3562b7a8c98 100644 --- a/ruby/ql/test/query-tests/security/cwe-829/InsecureDownload.expected +++ b/ruby/ql/test/query-tests/security/cwe-829/InsecureDownload.expected @@ -1,10 +1,14 @@ failures edges -| insecure_download.rb:31:11:31:41 | "http://example.org/unsafe.APK" : | insecure_download.rb:33:15:33:17 | url | -| insecure_download.rb:31:11:31:41 | "http://example.org/unsafe.APK" : | insecure_download.rb:33:15:33:17 | url | +| insecure_download.rb:31:5:31:7 | url : | insecure_download.rb:33:15:33:17 | url | +| insecure_download.rb:31:5:31:7 | url : | insecure_download.rb:33:15:33:17 | url | +| insecure_download.rb:31:11:31:41 | "http://example.org/unsafe.APK" : | insecure_download.rb:31:5:31:7 | url : | +| insecure_download.rb:31:11:31:41 | "http://example.org/unsafe.APK" : | insecure_download.rb:31:5:31:7 | url : | nodes | insecure_download.rb:27:15:27:45 | "http://example.org/unsafe.APK" | semmle.label | "http://example.org/unsafe.APK" | | insecure_download.rb:27:15:27:45 | "http://example.org/unsafe.APK" | semmle.label | "http://example.org/unsafe.APK" | +| insecure_download.rb:31:5:31:7 | url : | semmle.label | url : | +| insecure_download.rb:31:5:31:7 | url : | semmle.label | url : | | insecure_download.rb:31:11:31:41 | "http://example.org/unsafe.APK" : | semmle.label | "http://example.org/unsafe.APK" : | | insecure_download.rb:31:11:31:41 | "http://example.org/unsafe.APK" : | semmle.label | "http://example.org/unsafe.APK" : | | insecure_download.rb:33:15:33:17 | url | semmle.label | url | diff --git a/ruby/ql/test/query-tests/security/cwe-912/HttpToFileAccess.expected b/ruby/ql/test/query-tests/security/cwe-912/HttpToFileAccess.expected index ba8d776656b..1f26bdc2221 100644 --- a/ruby/ql/test/query-tests/security/cwe-912/HttpToFileAccess.expected +++ b/ruby/ql/test/query-tests/security/cwe-912/HttpToFileAccess.expected @@ -1,10 +1,14 @@ edges -| http_to_file_access.rb:3:8:3:52 | call to body : | http_to_file_access.rb:5:12:5:15 | resp | +| http_to_file_access.rb:3:1:3:4 | resp : | http_to_file_access.rb:5:12:5:15 | resp | +| http_to_file_access.rb:3:8:3:52 | call to body : | http_to_file_access.rb:3:1:3:4 | resp : | +| http_to_file_access.rb:9:7:9:12 | script : | http_to_file_access.rb:11:18:11:23 | script | | http_to_file_access.rb:9:16:9:21 | call to params : | http_to_file_access.rb:9:16:9:30 | ...[...] : | -| http_to_file_access.rb:9:16:9:30 | ...[...] : | http_to_file_access.rb:11:18:11:23 | script | +| http_to_file_access.rb:9:16:9:30 | ...[...] : | http_to_file_access.rb:9:7:9:12 | script : | nodes +| http_to_file_access.rb:3:1:3:4 | resp : | semmle.label | resp : | | http_to_file_access.rb:3:8:3:52 | call to body : | semmle.label | call to body : | | http_to_file_access.rb:5:12:5:15 | resp | semmle.label | resp | +| http_to_file_access.rb:9:7:9:12 | script : | semmle.label | script : | | http_to_file_access.rb:9:16:9:21 | call to params : | semmle.label | call to params : | | http_to_file_access.rb:9:16:9:30 | ...[...] : | semmle.label | ...[...] : | | http_to_file_access.rb:11:18:11:23 | script | semmle.label | script | diff --git a/ruby/ql/test/query-tests/security/cwe-918/ServerSideRequestForgery.expected b/ruby/ql/test/query-tests/security/cwe-918/ServerSideRequestForgery.expected index 1ac18b48554..906d4666020 100644 --- a/ruby/ql/test/query-tests/security/cwe-918/ServerSideRequestForgery.expected +++ b/ruby/ql/test/query-tests/security/cwe-918/ServerSideRequestForgery.expected @@ -1,9 +1,11 @@ edges +| ServerSideRequestForgery.rb:10:9:10:28 | users_service_domain : | ServerSideRequestForgery.rb:11:31:11:62 | "#{...}/logins" | | ServerSideRequestForgery.rb:10:32:10:37 | call to params : | ServerSideRequestForgery.rb:10:32:10:60 | ...[...] : | -| ServerSideRequestForgery.rb:10:32:10:60 | ...[...] : | ServerSideRequestForgery.rb:11:31:11:62 | "#{...}/logins" | +| ServerSideRequestForgery.rb:10:32:10:60 | ...[...] : | ServerSideRequestForgery.rb:10:9:10:28 | users_service_domain : | | ServerSideRequestForgery.rb:15:33:15:38 | call to params : | ServerSideRequestForgery.rb:15:33:15:44 | ...[...] | | ServerSideRequestForgery.rb:20:45:20:50 | call to params : | ServerSideRequestForgery.rb:20:45:20:56 | ...[...] | nodes +| ServerSideRequestForgery.rb:10:9:10:28 | users_service_domain : | semmle.label | users_service_domain : | | ServerSideRequestForgery.rb:10:32:10:37 | call to params : | semmle.label | call to params : | | ServerSideRequestForgery.rb:10:32:10:60 | ...[...] : | semmle.label | ...[...] : | | ServerSideRequestForgery.rb:11:31:11:62 | "#{...}/logins" | semmle.label | "#{...}/logins" | diff --git a/ruby/ql/test/query-tests/security/decompression-api/DecompressionApi.expected b/ruby/ql/test/query-tests/security/decompression-api/DecompressionApi.expected index 20ec5943541..265142d1ccd 100644 --- a/ruby/ql/test/query-tests/security/decompression-api/DecompressionApi.expected +++ b/ruby/ql/test/query-tests/security/decompression-api/DecompressionApi.expected @@ -1,8 +1,10 @@ edges +| decompression_api.rb:4:9:4:12 | path : | decompression_api.rb:5:31:5:34 | path | | decompression_api.rb:4:16:4:21 | call to params : | decompression_api.rb:4:16:4:28 | ...[...] : | -| decompression_api.rb:4:16:4:28 | ...[...] : | decompression_api.rb:5:31:5:34 | path | +| decompression_api.rb:4:16:4:28 | ...[...] : | decompression_api.rb:4:9:4:12 | path : | | decompression_api.rb:15:31:15:36 | call to params : | decompression_api.rb:15:31:15:43 | ...[...] | nodes +| decompression_api.rb:4:9:4:12 | path : | semmle.label | path : | | decompression_api.rb:4:16:4:21 | call to params : | semmle.label | call to params : | | decompression_api.rb:4:16:4:28 | ...[...] : | semmle.label | ...[...] : | | decompression_api.rb:5:31:5:34 | path | semmle.label | path | From 8b5393661b0cee13febbee060caf039e2003eafe Mon Sep 17 00:00:00 2001 From: Jeroen Ketema <jketema@github.com> Date: Fri, 24 Mar 2023 10:34:10 +0100 Subject: [PATCH 430/631] C++: Address review comments --- .../lib/semmle/code/cpp/security/boostorg/asio/protocols.qll | 5 ----- 1 file changed, 5 deletions(-) diff --git a/cpp/ql/lib/semmle/code/cpp/security/boostorg/asio/protocols.qll b/cpp/ql/lib/semmle/code/cpp/security/boostorg/asio/protocols.qll index 63b11597487..8668ecf078c 100644 --- a/cpp/ql/lib/semmle/code/cpp/security/boostorg/asio/protocols.qll +++ b/cpp/ql/lib/semmle/code/cpp/security/boostorg/asio/protocols.qll @@ -402,11 +402,6 @@ module BoostorgAsio { import DataFlow::Global<C> } - /** DEPRECATED: Use `SslContextCallGlobal` instead. */ - deprecated module SslContextCallMake<SslContextCallConfigSig Config> { - import SslContextCallGlobal<Config> - } - /** * Any protocol value that flows to the first argument of a context constructor. */ From a87a9438c76e955a64ac267eb6c231b6603e826c Mon Sep 17 00:00:00 2001 From: Jeroen Ketema <jketema@github.com> Date: Thu, 23 Mar 2023 21:13:52 +0100 Subject: [PATCH 431/631] Replace all definitions of `Unit` by `import codeql.util.Unit` --- cpp/ql/lib/qlpack.yml | 1 + .../code/cpp/dataflow/internal/DataFlowPrivate.qll | 10 +--------- .../cpp/ir/dataflow/internal/DataFlowPrivate.qll | 10 +--------- .../csharp/dataflow/internal/DataFlowPrivate.qll | 14 +++----------- go/ql/lib/qlpack.yml | 1 + .../go/dataflow/internal/DataFlowPrivate.qll | 10 +--------- .../go/dataflow/internal/TaintTrackingUtil.qll | 9 +-------- java/ql/lib/semmle/code/Unit.qll | 9 +-------- javascript/ql/lib/qlpack.yml | 1 + javascript/ql/lib/semmle/javascript/Unit.qll | 9 +-------- python/ql/lib/qlpack.yml | 2 +- python/ql/lib/semmle/python/Unit.qll | 9 +-------- .../ruby/dataflow/internal/DataFlowPrivate.qll | 10 +--------- swift/ql/lib/codeql/swift/Unit.qll | 9 +-------- swift/ql/lib/qlpack.yml | 1 + 15 files changed, 17 insertions(+), 88 deletions(-) diff --git a/cpp/ql/lib/qlpack.yml b/cpp/ql/lib/qlpack.yml index 12ad778c119..aa4f7c79fef 100644 --- a/cpp/ql/lib/qlpack.yml +++ b/cpp/ql/lib/qlpack.yml @@ -8,3 +8,4 @@ upgrades: upgrades dependencies: codeql/ssa: ${workspace} codeql/tutorial: ${workspace} + codeql/util: ${workspace} diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowPrivate.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowPrivate.qll index f54e3b9a9cb..c08e05b767d 100644 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowPrivate.qll +++ b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowPrivate.qll @@ -3,6 +3,7 @@ private import DataFlowUtil private import DataFlowDispatch private import FlowVar private import DataFlowImplConsistency +import codeql.util.Unit /** Gets the callable in which this node occurs. */ DataFlowCallable nodeGetEnclosingCallable(Node n) { result = n.getEnclosingCallable() } @@ -264,15 +265,6 @@ int accessPathLimit() { result = 5 } */ predicate forceHighPrecision(Content c) { none() } -/** 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" } -} - /** Holds if `n` should be hidden from path explanations. */ predicate nodeIsHidden(Node n) { none() } diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowPrivate.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowPrivate.qll index 9d69856e20b..331eb6241a5 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowPrivate.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowPrivate.qll @@ -6,6 +6,7 @@ private import DataFlowImplConsistency private import semmle.code.cpp.ir.internal.IRCppLanguage private import SsaInternals as Ssa private import DataFlowImplCommon as DataFlowImplCommon +import codeql.util.Unit cached private module Cached { @@ -799,15 +800,6 @@ int accessPathLimit() { result = 5 } */ predicate forceHighPrecision(Content c) { none() } -/** 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" } -} - /** Holds if `n` should be hidden from path explanations. */ predicate nodeIsHidden(Node n) { n instanceof OperandNode and 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 a7fc72d0c17..9bcddf7c6c2 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowPrivate.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowPrivate.qll @@ -19,6 +19,7 @@ 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 +import codeql.util.Unit /** Gets the callable in which this node occurs. */ DataFlowCallable nodeGetEnclosingCallable(NodeImpl n) { result = n.getEnclosingCallableImpl() } @@ -2163,15 +2164,6 @@ int accessPathLimit() { result = 5 } */ predicate forceHighPrecision(Content c) { c instanceof ElementContent } -/** 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" } -} - class LambdaCallKind = Unit; /** Holds if `creation` is an expression that creates a delegate for `c`. */ @@ -2183,7 +2175,7 @@ predicate lambdaCreation(ExprNode creation, LambdaCallKind kind, DataFlowCallabl e.(AddressOfExpr).getOperand().(CallableAccess).getTarget().getUnboundDeclaration() ] ) and - kind = TMkUnit() + exists(kind) } private class LambdaConfiguration extends ControlFlowReachabilityConfiguration { @@ -2214,7 +2206,7 @@ predicate lambdaCall(DataFlowCall call, LambdaCallKind kind, Node receiver) { or receiver = call.(SummaryCall).getReceiver() ) and - kind = TMkUnit() + exists(kind) } /** Extra data-flow steps needed for lambda flow analysis. */ diff --git a/go/ql/lib/qlpack.yml b/go/ql/lib/qlpack.yml index a8601ec94b7..db88dfdbcd7 100644 --- a/go/ql/lib/qlpack.yml +++ b/go/ql/lib/qlpack.yml @@ -7,5 +7,6 @@ library: true upgrades: upgrades dependencies: codeql/tutorial: ${workspace} + codeql/util: ${workspace} dataExtensions: - ext/*.model.yml diff --git a/go/ql/lib/semmle/go/dataflow/internal/DataFlowPrivate.qll b/go/ql/lib/semmle/go/dataflow/internal/DataFlowPrivate.qll index f6cb63c1c75..d57adbe5d69 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/DataFlowPrivate.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/DataFlowPrivate.qll @@ -3,6 +3,7 @@ private import DataFlowUtil private import DataFlowImplCommon private import ContainerFlow private import FlowSummaryImpl as FlowSummaryImpl +import codeql.util.Unit import DataFlowNodes::Private private newtype TReturnKind = @@ -339,15 +340,6 @@ predicate forceHighPrecision(Content c) { c instanceof ArrayContent or c instanceof CollectionContent } -/** 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" } -} - /** * Gets the `i`th argument of call `c`, where the receiver of a method call * counts as argument -1. diff --git a/go/ql/lib/semmle/go/dataflow/internal/TaintTrackingUtil.qll b/go/ql/lib/semmle/go/dataflow/internal/TaintTrackingUtil.qll index 6dfc0dbdcff..38e03f62b44 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/TaintTrackingUtil.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/TaintTrackingUtil.qll @@ -4,6 +4,7 @@ private import go private import FlowSummaryImpl as FlowSummaryImpl +private import codeql.util.Unit /** * Holds if taint can flow from `src` to `sink` in zero or more @@ -66,14 +67,6 @@ predicate defaultImplicitTaintRead(DataFlow::Node node, DataFlow::Content c) { ) } -private newtype TUnit = TMkUnit() - -/** A singleton class containing a single dummy "unit" value. */ -private class Unit extends TUnit { - /** Gets a textual representation of this element. */ - string toString() { result = "unit" } -} - /** * A unit class for adding additional taint steps. * diff --git a/java/ql/lib/semmle/code/Unit.qll b/java/ql/lib/semmle/code/Unit.qll index e9611ed3df4..83a4a03321d 100644 --- a/java/ql/lib/semmle/code/Unit.qll +++ b/java/ql/lib/semmle/code/Unit.qll @@ -1,10 +1,3 @@ /** 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" } -} +import codeql.util.Unit diff --git a/javascript/ql/lib/qlpack.yml b/javascript/ql/lib/qlpack.yml index 5c650164c39..99f044a6431 100644 --- a/javascript/ql/lib/qlpack.yml +++ b/javascript/ql/lib/qlpack.yml @@ -8,5 +8,6 @@ upgrades: upgrades dependencies: codeql/regex: ${workspace} codeql/tutorial: ${workspace} + codeql/util: ${workspace} dataExtensions: - semmle/javascript/frameworks/**/model.yml diff --git a/javascript/ql/lib/semmle/javascript/Unit.qll b/javascript/ql/lib/semmle/javascript/Unit.qll index dbc59f541e6..83a4a03321d 100644 --- a/javascript/ql/lib/semmle/javascript/Unit.qll +++ b/javascript/ql/lib/semmle/javascript/Unit.qll @@ -1,10 +1,3 @@ /** 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" } -} +import codeql.util.Unit diff --git a/python/ql/lib/qlpack.yml b/python/ql/lib/qlpack.yml index f40f7e10b4f..bc1863e7214 100644 --- a/python/ql/lib/qlpack.yml +++ b/python/ql/lib/qlpack.yml @@ -7,7 +7,7 @@ library: true upgrades: upgrades dependencies: codeql/regex: ${workspace} - codeql/util: ${workspace} codeql/tutorial: ${workspace} + codeql/util: ${workspace} dataExtensions: - semmle/python/frameworks/**/model.yml diff --git a/python/ql/lib/semmle/python/Unit.qll b/python/ql/lib/semmle/python/Unit.qll index e9611ed3df4..83a4a03321d 100644 --- a/python/ql/lib/semmle/python/Unit.qll +++ b/python/ql/lib/semmle/python/Unit.qll @@ -1,10 +1,3 @@ /** 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" } -} +import codeql.util.Unit diff --git a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowPrivate.qll b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowPrivate.qll index cfce508e706..4df29699da4 100644 --- a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowPrivate.qll +++ b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowPrivate.qll @@ -9,6 +9,7 @@ private import SsaImpl as SsaImpl private import FlowSummaryImpl as FlowSummaryImpl private import FlowSummaryImplSpecific as FlowSummaryImplSpecific private import codeql.ruby.frameworks.data.ModelsAsData +import codeql.util.Unit /** Gets the callable in which this node occurs. */ DataFlowCallable nodeGetEnclosingCallable(NodeImpl n) { result = n.getEnclosingCallable() } @@ -1345,15 +1346,6 @@ int accessPathLimit() { result = 5 } */ predicate forceHighPrecision(Content c) { c instanceof Content::ElementContent } -/** 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" } -} - /** * Holds if the node `n` is unreachable when the call context is `call`. */ diff --git a/swift/ql/lib/codeql/swift/Unit.qll b/swift/ql/lib/codeql/swift/Unit.qll index e9611ed3df4..83a4a03321d 100644 --- a/swift/ql/lib/codeql/swift/Unit.qll +++ b/swift/ql/lib/codeql/swift/Unit.qll @@ -1,10 +1,3 @@ /** 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" } -} +import codeql.util.Unit diff --git a/swift/ql/lib/qlpack.yml b/swift/ql/lib/qlpack.yml index 66c3bc0094d..3d3f00eb029 100644 --- a/swift/ql/lib/qlpack.yml +++ b/swift/ql/lib/qlpack.yml @@ -8,3 +8,4 @@ library: true dependencies: codeql/ssa: ${workspace} codeql/tutorial: ${workspace} + codeql/util: ${workspace} From e87747c52e260d3fe6d74f161eb0da0072ffb868 Mon Sep 17 00:00:00 2001 From: Michael Nebel <michaelnebel@github.com> Date: Fri, 24 Mar 2023 10:49:06 +0100 Subject: [PATCH 432/631] Document a few sink kinds. --- .../customizing-library-models-for-java.rst | 46 +++++++------------ 1 file changed, 16 insertions(+), 30 deletions(-) diff --git a/docs/codeql/codeql-language-guides/customizing-library-models-for-java.rst b/docs/codeql/codeql-language-guides/customizing-library-models-for-java.rst index 2fa9f9bb8f2..1e9af370051 100644 --- a/docs/codeql/codeql-language-guides/customizing-library-models-for-java.rst +++ b/docs/codeql/codeql-language-guides/customizing-library-models-for-java.rst @@ -311,9 +311,10 @@ As most sources are used by all taint tracking queries there are only a few diff The following source kinds are supported: - **remote**: A remote source of possibly tainted data. This is the most common kind for a source. Sources of this kind are used for almost all taint tracking queries. -- **contentprovider**: ? -- **android-widget**: ? -- **android-external-storage-dir**: ? + +Below is an enumeration of the remaining source kinds, but they are out of scope for this documentation: + +- **contentprovider**, **android-widget**, **android-external-storage-dir**. sinkModel(package, type, subtypes, name, signature, ext, input, kind, provenance) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -325,33 +326,18 @@ Taint sink. As opposed to source kinds, there are many different kinds of sinks The following sink kinds are supported: -- **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**: ? -- **read-file**: ? -- **write-file**: ? -- **set-hostname-verifier**: ? -- **header-splitting**: ? -- **information-leak**: ? -- **xslt**: ? -- **jexl**: ? -- **bean-validation**: ? -- **ssti**: ? -- **fragment-injection**: ? -- **regex-use[**\ `arg`\ **]**: ? +- **sql**: A SQL injection vulnerability sink. +- **xss**: A cross-site scripting vulnerability sink. +- **logging**: A log output sink. + +Below is an enumeration of the remaining sinks, but they are out of scope for this documentation: + +- **open-url**, **jndi-injection**, **ldap**, **jdbc-url** +- **mvel**, **xpath**, **groovy**, **ognl-injection** +- **intent-start**, **pending-intent-sent**, **url-open-stream**, **url-redirect** +- **create-file**, **read-file**, **write-file**, **set-hostname-verifier** +- **header-splitting**, **information-leak**, **xslt**, **jexl** +- **bean-validation**, **ssti**, **fragment-injection**, **regex-use[**\ `arg`\ **]** summaryModel(package, type, subtypes, name, signature, ext, input, output, kind, provenance) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ From b45c274f3316d67393522e36858f80324596b884 Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen <aschackmull@github.com> Date: Fri, 24 Mar 2023 12:41:53 +0100 Subject: [PATCH 433/631] Dataflow: Adjust qldoc --- java/ql/lib/semmle/code/java/dataflow/internal/DataFlow.qll | 4 ++-- .../java/dataflow/internal/tainttracking1/TaintTracking.qll | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlow.qll b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlow.qll index 137612c52af..865d7b4d6ce 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlow.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlow.qll @@ -222,7 +222,7 @@ signature module GlobalFlowSig { } /** - * Constructs a standard data flow computation. + * Constructs a global data flow computation. */ module Global<ConfigSig Config> implements GlobalFlowSig { private module C implements FullStateConfigSig { @@ -239,7 +239,7 @@ deprecated module Make<ConfigSig Config> implements GlobalFlowSig { } /** - * Constructs a data flow computation using flow state. + * Constructs a global data flow computation using flow state. */ module GlobalWithState<StateConfigSig Config> implements GlobalFlowSig { private module C implements FullStateConfigSig { diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/tainttracking1/TaintTracking.qll b/java/ql/lib/semmle/code/java/dataflow/internal/tainttracking1/TaintTracking.qll index 3f8cef3698a..872ac8d4cb8 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/tainttracking1/TaintTracking.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/tainttracking1/TaintTracking.qll @@ -33,7 +33,7 @@ private module AddTaintDefaults<DataFlowInternal::FullStateConfigSig Config> imp } /** - * Constructs a standard taint tracking computation. + * Constructs a global taint tracking computation. */ module Global<DataFlow::ConfigSig Config> implements DataFlow::GlobalFlowSig { private module Config0 implements DataFlowInternal::FullStateConfigSig { @@ -54,7 +54,7 @@ deprecated module Make<DataFlow::ConfigSig Config> implements DataFlow::GlobalFl } /** - * Constructs a taint tracking computation using flow state. + * Constructs a global taint tracking computation using flow state. */ module GlobalWithState<DataFlow::StateConfigSig Config> implements DataFlow::GlobalFlowSig { private module Config0 implements DataFlowInternal::FullStateConfigSig { From 85511ba19d4a5c7f64f259130b9b3e8cd484ff52 Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen <aschackmull@github.com> Date: Fri, 24 Mar 2023 12:42:06 +0100 Subject: [PATCH 434/631] Dataflow: Sync --- cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlow.qll | 4 ++-- .../cpp/dataflow/internal/tainttracking1/TaintTracking.qll | 4 ++-- cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlow.qll | 4 ++-- .../cpp/ir/dataflow/internal/tainttracking1/TaintTracking.qll | 4 ++-- .../ql/lib/semmle/code/csharp/dataflow/internal/DataFlow.qll | 4 ++-- .../csharp/dataflow/internal/tainttracking1/TaintTracking.qll | 4 ++-- go/ql/lib/semmle/go/dataflow/internal/DataFlow.qll | 4 ++-- .../go/dataflow/internal/tainttracking1/TaintTracking.qll | 4 ++-- .../ql/lib/semmle/python/dataflow/new/internal/DataFlow.qll | 4 ++-- .../dataflow/new/internal/tainttracking1/TaintTracking.qll | 4 ++-- ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlow.qll | 4 ++-- .../ruby/dataflow/internal/tainttracking1/TaintTracking.qll | 4 ++-- swift/ql/lib/codeql/swift/dataflow/internal/DataFlow.qll | 4 ++-- .../swift/dataflow/internal/tainttracking1/TaintTracking.qll | 4 ++-- 14 files changed, 28 insertions(+), 28 deletions(-) diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlow.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlow.qll index 137612c52af..865d7b4d6ce 100644 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlow.qll +++ b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlow.qll @@ -222,7 +222,7 @@ signature module GlobalFlowSig { } /** - * Constructs a standard data flow computation. + * Constructs a global data flow computation. */ module Global<ConfigSig Config> implements GlobalFlowSig { private module C implements FullStateConfigSig { @@ -239,7 +239,7 @@ deprecated module Make<ConfigSig Config> implements GlobalFlowSig { } /** - * Constructs a data flow computation using flow state. + * Constructs a global data flow computation using flow state. */ module GlobalWithState<StateConfigSig Config> implements GlobalFlowSig { private module C implements FullStateConfigSig { diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/tainttracking1/TaintTracking.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/tainttracking1/TaintTracking.qll index 3f8cef3698a..872ac8d4cb8 100644 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/tainttracking1/TaintTracking.qll +++ b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/tainttracking1/TaintTracking.qll @@ -33,7 +33,7 @@ private module AddTaintDefaults<DataFlowInternal::FullStateConfigSig Config> imp } /** - * Constructs a standard taint tracking computation. + * Constructs a global taint tracking computation. */ module Global<DataFlow::ConfigSig Config> implements DataFlow::GlobalFlowSig { private module Config0 implements DataFlowInternal::FullStateConfigSig { @@ -54,7 +54,7 @@ deprecated module Make<DataFlow::ConfigSig Config> implements DataFlow::GlobalFl } /** - * Constructs a taint tracking computation using flow state. + * Constructs a global taint tracking computation using flow state. */ module GlobalWithState<DataFlow::StateConfigSig Config> implements DataFlow::GlobalFlowSig { private module Config0 implements DataFlowInternal::FullStateConfigSig { diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlow.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlow.qll index 137612c52af..865d7b4d6ce 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlow.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlow.qll @@ -222,7 +222,7 @@ signature module GlobalFlowSig { } /** - * Constructs a standard data flow computation. + * Constructs a global data flow computation. */ module Global<ConfigSig Config> implements GlobalFlowSig { private module C implements FullStateConfigSig { @@ -239,7 +239,7 @@ deprecated module Make<ConfigSig Config> implements GlobalFlowSig { } /** - * Constructs a data flow computation using flow state. + * Constructs a global data flow computation using flow state. */ module GlobalWithState<StateConfigSig Config> implements GlobalFlowSig { private module C implements FullStateConfigSig { diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/tainttracking1/TaintTracking.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/tainttracking1/TaintTracking.qll index 3f8cef3698a..872ac8d4cb8 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/tainttracking1/TaintTracking.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/tainttracking1/TaintTracking.qll @@ -33,7 +33,7 @@ private module AddTaintDefaults<DataFlowInternal::FullStateConfigSig Config> imp } /** - * Constructs a standard taint tracking computation. + * Constructs a global taint tracking computation. */ module Global<DataFlow::ConfigSig Config> implements DataFlow::GlobalFlowSig { private module Config0 implements DataFlowInternal::FullStateConfigSig { @@ -54,7 +54,7 @@ deprecated module Make<DataFlow::ConfigSig Config> implements DataFlow::GlobalFl } /** - * Constructs a taint tracking computation using flow state. + * Constructs a global taint tracking computation using flow state. */ module GlobalWithState<DataFlow::StateConfigSig Config> implements DataFlow::GlobalFlowSig { private module Config0 implements DataFlowInternal::FullStateConfigSig { diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlow.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlow.qll index 137612c52af..865d7b4d6ce 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlow.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlow.qll @@ -222,7 +222,7 @@ signature module GlobalFlowSig { } /** - * Constructs a standard data flow computation. + * Constructs a global data flow computation. */ module Global<ConfigSig Config> implements GlobalFlowSig { private module C implements FullStateConfigSig { @@ -239,7 +239,7 @@ deprecated module Make<ConfigSig Config> implements GlobalFlowSig { } /** - * Constructs a data flow computation using flow state. + * Constructs a global data flow computation using flow state. */ module GlobalWithState<StateConfigSig Config> implements GlobalFlowSig { private module C implements FullStateConfigSig { diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/tainttracking1/TaintTracking.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/tainttracking1/TaintTracking.qll index 3f8cef3698a..872ac8d4cb8 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/tainttracking1/TaintTracking.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/tainttracking1/TaintTracking.qll @@ -33,7 +33,7 @@ private module AddTaintDefaults<DataFlowInternal::FullStateConfigSig Config> imp } /** - * Constructs a standard taint tracking computation. + * Constructs a global taint tracking computation. */ module Global<DataFlow::ConfigSig Config> implements DataFlow::GlobalFlowSig { private module Config0 implements DataFlowInternal::FullStateConfigSig { @@ -54,7 +54,7 @@ deprecated module Make<DataFlow::ConfigSig Config> implements DataFlow::GlobalFl } /** - * Constructs a taint tracking computation using flow state. + * Constructs a global taint tracking computation using flow state. */ module GlobalWithState<DataFlow::StateConfigSig Config> implements DataFlow::GlobalFlowSig { private module Config0 implements DataFlowInternal::FullStateConfigSig { diff --git a/go/ql/lib/semmle/go/dataflow/internal/DataFlow.qll b/go/ql/lib/semmle/go/dataflow/internal/DataFlow.qll index 137612c52af..865d7b4d6ce 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/DataFlow.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/DataFlow.qll @@ -222,7 +222,7 @@ signature module GlobalFlowSig { } /** - * Constructs a standard data flow computation. + * Constructs a global data flow computation. */ module Global<ConfigSig Config> implements GlobalFlowSig { private module C implements FullStateConfigSig { @@ -239,7 +239,7 @@ deprecated module Make<ConfigSig Config> implements GlobalFlowSig { } /** - * Constructs a data flow computation using flow state. + * Constructs a global data flow computation using flow state. */ module GlobalWithState<StateConfigSig Config> implements GlobalFlowSig { private module C implements FullStateConfigSig { diff --git a/go/ql/lib/semmle/go/dataflow/internal/tainttracking1/TaintTracking.qll b/go/ql/lib/semmle/go/dataflow/internal/tainttracking1/TaintTracking.qll index 3f8cef3698a..872ac8d4cb8 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/tainttracking1/TaintTracking.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/tainttracking1/TaintTracking.qll @@ -33,7 +33,7 @@ private module AddTaintDefaults<DataFlowInternal::FullStateConfigSig Config> imp } /** - * Constructs a standard taint tracking computation. + * Constructs a global taint tracking computation. */ module Global<DataFlow::ConfigSig Config> implements DataFlow::GlobalFlowSig { private module Config0 implements DataFlowInternal::FullStateConfigSig { @@ -54,7 +54,7 @@ deprecated module Make<DataFlow::ConfigSig Config> implements DataFlow::GlobalFl } /** - * Constructs a taint tracking computation using flow state. + * Constructs a global taint tracking computation using flow state. */ module GlobalWithState<DataFlow::StateConfigSig Config> implements DataFlow::GlobalFlowSig { private module Config0 implements DataFlowInternal::FullStateConfigSig { diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlow.qll b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlow.qll index 137612c52af..865d7b4d6ce 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlow.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlow.qll @@ -222,7 +222,7 @@ signature module GlobalFlowSig { } /** - * Constructs a standard data flow computation. + * Constructs a global data flow computation. */ module Global<ConfigSig Config> implements GlobalFlowSig { private module C implements FullStateConfigSig { @@ -239,7 +239,7 @@ deprecated module Make<ConfigSig Config> implements GlobalFlowSig { } /** - * Constructs a data flow computation using flow state. + * Constructs a global data flow computation using flow state. */ module GlobalWithState<StateConfigSig Config> implements GlobalFlowSig { private module C implements FullStateConfigSig { diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/tainttracking1/TaintTracking.qll b/python/ql/lib/semmle/python/dataflow/new/internal/tainttracking1/TaintTracking.qll index 3f8cef3698a..872ac8d4cb8 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/tainttracking1/TaintTracking.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/tainttracking1/TaintTracking.qll @@ -33,7 +33,7 @@ private module AddTaintDefaults<DataFlowInternal::FullStateConfigSig Config> imp } /** - * Constructs a standard taint tracking computation. + * Constructs a global taint tracking computation. */ module Global<DataFlow::ConfigSig Config> implements DataFlow::GlobalFlowSig { private module Config0 implements DataFlowInternal::FullStateConfigSig { @@ -54,7 +54,7 @@ deprecated module Make<DataFlow::ConfigSig Config> implements DataFlow::GlobalFl } /** - * Constructs a taint tracking computation using flow state. + * Constructs a global taint tracking computation using flow state. */ module GlobalWithState<DataFlow::StateConfigSig Config> implements DataFlow::GlobalFlowSig { private module Config0 implements DataFlowInternal::FullStateConfigSig { diff --git a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlow.qll b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlow.qll index 137612c52af..865d7b4d6ce 100644 --- a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlow.qll +++ b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlow.qll @@ -222,7 +222,7 @@ signature module GlobalFlowSig { } /** - * Constructs a standard data flow computation. + * Constructs a global data flow computation. */ module Global<ConfigSig Config> implements GlobalFlowSig { private module C implements FullStateConfigSig { @@ -239,7 +239,7 @@ deprecated module Make<ConfigSig Config> implements GlobalFlowSig { } /** - * Constructs a data flow computation using flow state. + * Constructs a global data flow computation using flow state. */ module GlobalWithState<StateConfigSig Config> implements GlobalFlowSig { private module C implements FullStateConfigSig { diff --git a/ruby/ql/lib/codeql/ruby/dataflow/internal/tainttracking1/TaintTracking.qll b/ruby/ql/lib/codeql/ruby/dataflow/internal/tainttracking1/TaintTracking.qll index 3f8cef3698a..872ac8d4cb8 100644 --- a/ruby/ql/lib/codeql/ruby/dataflow/internal/tainttracking1/TaintTracking.qll +++ b/ruby/ql/lib/codeql/ruby/dataflow/internal/tainttracking1/TaintTracking.qll @@ -33,7 +33,7 @@ private module AddTaintDefaults<DataFlowInternal::FullStateConfigSig Config> imp } /** - * Constructs a standard taint tracking computation. + * Constructs a global taint tracking computation. */ module Global<DataFlow::ConfigSig Config> implements DataFlow::GlobalFlowSig { private module Config0 implements DataFlowInternal::FullStateConfigSig { @@ -54,7 +54,7 @@ deprecated module Make<DataFlow::ConfigSig Config> implements DataFlow::GlobalFl } /** - * Constructs a taint tracking computation using flow state. + * Constructs a global taint tracking computation using flow state. */ module GlobalWithState<DataFlow::StateConfigSig Config> implements DataFlow::GlobalFlowSig { private module Config0 implements DataFlowInternal::FullStateConfigSig { diff --git a/swift/ql/lib/codeql/swift/dataflow/internal/DataFlow.qll b/swift/ql/lib/codeql/swift/dataflow/internal/DataFlow.qll index 137612c52af..865d7b4d6ce 100644 --- a/swift/ql/lib/codeql/swift/dataflow/internal/DataFlow.qll +++ b/swift/ql/lib/codeql/swift/dataflow/internal/DataFlow.qll @@ -222,7 +222,7 @@ signature module GlobalFlowSig { } /** - * Constructs a standard data flow computation. + * Constructs a global data flow computation. */ module Global<ConfigSig Config> implements GlobalFlowSig { private module C implements FullStateConfigSig { @@ -239,7 +239,7 @@ deprecated module Make<ConfigSig Config> implements GlobalFlowSig { } /** - * Constructs a data flow computation using flow state. + * Constructs a global data flow computation using flow state. */ module GlobalWithState<StateConfigSig Config> implements GlobalFlowSig { private module C implements FullStateConfigSig { diff --git a/swift/ql/lib/codeql/swift/dataflow/internal/tainttracking1/TaintTracking.qll b/swift/ql/lib/codeql/swift/dataflow/internal/tainttracking1/TaintTracking.qll index 3f8cef3698a..872ac8d4cb8 100644 --- a/swift/ql/lib/codeql/swift/dataflow/internal/tainttracking1/TaintTracking.qll +++ b/swift/ql/lib/codeql/swift/dataflow/internal/tainttracking1/TaintTracking.qll @@ -33,7 +33,7 @@ private module AddTaintDefaults<DataFlowInternal::FullStateConfigSig Config> imp } /** - * Constructs a standard taint tracking computation. + * Constructs a global taint tracking computation. */ module Global<DataFlow::ConfigSig Config> implements DataFlow::GlobalFlowSig { private module Config0 implements DataFlowInternal::FullStateConfigSig { @@ -54,7 +54,7 @@ deprecated module Make<DataFlow::ConfigSig Config> implements DataFlow::GlobalFl } /** - * Constructs a taint tracking computation using flow state. + * Constructs a global taint tracking computation using flow state. */ module GlobalWithState<DataFlow::StateConfigSig Config> implements DataFlow::GlobalFlowSig { private module Config0 implements DataFlowInternal::FullStateConfigSig { From ac4aa4f06cf82d2e6f846a28476cc2fcfb842a59 Mon Sep 17 00:00:00 2001 From: Michael Nebel <michaelnebel@github.com> Date: Fri, 24 Mar 2023 13:17:43 +0100 Subject: [PATCH 435/631] Apply suggestions from code review Co-authored-by: Ben Ahmady <32935794+subatoi@users.noreply.github.com> --- .../customizing-library-models-for-java.rst | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/codeql/codeql-language-guides/customizing-library-models-for-java.rst b/docs/codeql/codeql-language-guides/customizing-library-models-for-java.rst index 1e9af370051..40ddb14be4d 100644 --- a/docs/codeql/codeql-language-guides/customizing-library-models-for-java.rst +++ b/docs/codeql/codeql-language-guides/customizing-library-models-for-java.rst @@ -48,7 +48,7 @@ Example: Taint sink in the **java.sql** package In this example we will show how to model the argument of the **execute** method as a SQL injection sink. This is the **execute** method in the **Statement** class, which is located in the **java.sql** package. -Please note that this sink is already added to the CodeQL Java analysis. +Note that this sink is already added to the CodeQL Java analysis. .. code-block:: java @@ -89,7 +89,7 @@ Example: Taint source from the **java.net** package ---------------------------------------------------- In this example we show how to model the return value from the **getInputStream** method as a **remote** source. This is the **getInputStream** method in the **Socket** class, which is located in the **java.net** package. -Please note that this source is already added to the CodeQL Java analysis. +Note that this source is already added to the CodeQL Java analysis. .. code-block:: java @@ -130,7 +130,7 @@ Example: Add flow through the **concat** method ------------------------------------------------ In this example we show how to model flow through a method for a simple case. This pattern covers many of the cases where we need to define flow through a method. -Please note that the flow through the **concat** method is already added to the CodeQL Java analysis. +Note that the flow through the **concat** method is already added to the CodeQL Java analysis. .. code-block:: java @@ -178,7 +178,7 @@ Example: Add flow through the **map** method --------------------------------------------- In this example, we will see a more complex example of modeling flow through a method. This pattern shows how to model flow through higher order methods and collection types. -Please note that the flow through the **map** method is already added to the CodeQL Java analysis. +Note that the flow through the **map** method is already added to the CodeQL Java analysis. .. code-block:: java @@ -238,7 +238,7 @@ Example: Add a **neutral** method ---------------------------------- In this example we will show how to model the **now** method as being neutral. A neutral model is used to define that there is no flow through a method. -Please note that the neutral model for the **now** method is already added to the CodeQL Java analysis. +Note that the neutral model for the **now** method is already added to the CodeQL Java analysis. .. code-block:: java From cf4eac6fa1e3d4e89454426bc759a7a88b10c064 Mon Sep 17 00:00:00 2001 From: yoff <lerchedahl@gmail.com> Date: Fri, 24 Mar 2023 13:18:03 +0100 Subject: [PATCH 436/631] Update python/ql/src/Security/CWE-327/PyOpenSSL.qll Co-authored-by: Rasmus Wriedt Larsen <rasmuswriedtlarsen@gmail.com> --- python/ql/src/Security/CWE-327/PyOpenSSL.qll | 3 --- 1 file changed, 3 deletions(-) diff --git a/python/ql/src/Security/CWE-327/PyOpenSSL.qll b/python/ql/src/Security/CWE-327/PyOpenSSL.qll index 9b685ecfd1c..7e99ebe27d9 100644 --- a/python/ql/src/Security/CWE-327/PyOpenSSL.qll +++ b/python/ql/src/Security/CWE-327/PyOpenSSL.qll @@ -55,9 +55,6 @@ class SetOptionsCall extends ProtocolRestriction, DataFlow::CallCfgNode { } } -// class UnspecificPyOpenSslContextCreation extends PyOpenSslContextCreation, UnspecificContextCreation { -// override ProtocolVersion getProtocol() { result = PyOpenSslContextCreation.super.getProtocol() } -// } class PyOpenSsl extends TlsLibrary { PyOpenSsl() { this = "pyOpenSSL" } From 8ea4878f7a584440dd446c9e58ea025bc903da06 Mon Sep 17 00:00:00 2001 From: Rasmus Lerchedahl Petersen <yoff@github.com> Date: Fri, 24 Mar 2023 13:24:49 +0100 Subject: [PATCH 437/631] python: move comment --- python/ql/src/Security/CWE-327/PyOpenSSL.qll | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/python/ql/src/Security/CWE-327/PyOpenSSL.qll b/python/ql/src/Security/CWE-327/PyOpenSSL.qll index 7e99ebe27d9..e2571195bfa 100644 --- a/python/ql/src/Security/CWE-327/PyOpenSSL.qll +++ b/python/ql/src/Security/CWE-327/PyOpenSSL.qll @@ -19,10 +19,6 @@ class PyOpenSslContextCreation extends ContextCreation, DataFlow::CallCfgNode { protocolArg = pyo.specific_version(result).getAValueReachableFromSource() or protocolArg = pyo.unspecific_version().getAValueReachableFromSource() and - // PyOpenSSL also allows DTLS - // see https://www.pyopenssl.org/en/stable/api/ssl.html#OpenSSL.SSL.Context - // although they are not mentioned here: - // https://www.pyopenssl.org/en/stable/api/ssl.html#OpenSSL.SSL.TLS_METHOD result = any(ProtocolVersion pv) ) } @@ -64,6 +60,11 @@ class PyOpenSsl extends TlsLibrary { // See // - https://www.pyopenssl.org/en/23.0.0/api/ssl.html#module-OpenSSL.SSL // - https://www.openssl.org/docs/manmaster/man3/DTLS_server_method.html#NOTES + // + // PyOpenSSL also allows DTLS + // see https://www.pyopenssl.org/en/stable/api/ssl.html#OpenSSL.SSL.Context + // although they are not mentioned here: + // https://www.pyopenssl.org/en/stable/api/ssl.html#OpenSSL.SSL.TLS_METHOD result = ["TLS", "SSLv23"] + "_METHOD" or result = "TLS_" + ["CLIENT", "SERVER"] + "_METHOD" From 3c407eaa23c899c489025ac3f26444ff5d68bd5a Mon Sep 17 00:00:00 2001 From: Rasmus Lerchedahl Petersen <yoff@github.com> Date: Fri, 24 Mar 2023 13:32:25 +0100 Subject: [PATCH 438/631] python: rewrite comment --- .../ql/src/Security/CWE-327/FluentApiModel.qll | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/python/ql/src/Security/CWE-327/FluentApiModel.qll b/python/ql/src/Security/CWE-327/FluentApiModel.qll index 3d63cab940e..d036020a1ba 100644 --- a/python/ql/src/Security/CWE-327/FluentApiModel.qll +++ b/python/ql/src/Security/CWE-327/FluentApiModel.qll @@ -4,21 +4,16 @@ import TlsLibraryModel /** * Configuration to determine the state of a context being used to create - * a connection. There is one configuration for each pair of `TlsLibrary` and `ProtocolVersion`, - * such that a single configuration only tracks contexts where a specific `ProtocolVersion` is allowed. + * a connection. The configuration uses a flow state to track the `TlsLibrary` + * and the insecure `ProtocolVersion`s that are allowed. * * The state is in terms of whether a specific protocol is allowed. This is * either true or false when the context is created and can then be modified - * later by either restricting or unrestricting the protocol (see the predicates - * `isRestriction` and `isUnrestriction`). + * later by either restricting or unrestricting the protocol (see the predicate + * `isAdditionalFlowStep`). * - * Since we are interested in the final state, we want the flow to start from - * the last unrestriction, so we disallow flow into unrestrictions. We also - * model the creation as an unrestriction of everything it allows, to account - * for the common case where the creation plays the role of "last unrestriction". - * - * Since we really want "the last unrestriction, not nullified by a restriction", - * we also disallow flow into restrictions. + * The state is represented as a bit vector, where each bit corresponds to a + * protocol version. The bit is set if the protocol is allowed. */ module InsecureContextConfiguration implements DataFlow::StateConfigSig { private newtype TFlowState = From 179d0b36cf6630ef62ab303d0c44a0dd5f0b66e0 Mon Sep 17 00:00:00 2001 From: Asger F <asgerf@github.com> Date: Thu, 23 Mar 2023 15:19:21 +0100 Subject: [PATCH 439/631] Ruby: make up qnames for top-level namespaces --- .../lib/codeql/ruby/ast/internal/Module.qll | 34 ++++++++++++++++ .../library-tests/modules/ancestors.expected | 14 +++++-- .../library-tests/modules/methods.expected | 18 ++++----- .../library-tests/modules/modules.expected | 40 ++++++++++++++----- .../modules/superclasses.expected | 14 +++++-- 5 files changed, 94 insertions(+), 26 deletions(-) diff --git a/ruby/ql/lib/codeql/ruby/ast/internal/Module.qll b/ruby/ql/lib/codeql/ruby/ast/internal/Module.qll index b72d5ea2f9a..f6fa4ca1528 100644 --- a/ruby/ql/lib/codeql/ruby/ast/internal/Module.qll +++ b/ruby/ql/lib/codeql/ruby/ast/internal/Module.qll @@ -21,6 +21,8 @@ private module Cached { qName = getAnAssumedGlobalConst() or qName = namespaceDeclaration(_) + or + qName = getAnAssumedGlobalNamespacePrefix(_) } or TUnresolved(Namespace n) { not exists(namespaceDeclaration(n)) } @@ -36,6 +38,8 @@ private module Cached { TResolved(container) = resolveConstantReadAccess(n.getScopeExpr()) and result = scopeAppend(container, n.getName()) ) + or + result = getAnAssumedGlobalNamespacePrefix(n) } cached @@ -412,6 +416,30 @@ private module ResolveImpl { ) } + private ConstantAccess getANamespaceScopeInTopLevel() { + result.(Namespace).getEnclosingModule() instanceof Toplevel + or + result = getANamespaceScopeInTopLevel().getScopeExpr() + } + + /** + * Gets the syntactical qualified name of the given constant access, which must be a top-level + * namespace or scope prefix thereof. + * + * For example, for `module A::B::C` this gets `A`, `A::B`, and `A::B::C` for the two prefixes + * and the module itself, respectively. + */ + string getAnAssumedGlobalNamespacePrefix(ConstantAccess access) { + access = getANamespaceScopeInTopLevel() and + ( + not exists(access.getScopeExpr()) and + result = access.getName() + or + result = + scopeAppend(getAnAssumedGlobalNamespacePrefix(access.getScopeExpr()), access.getName()) + ) + } + pragma[nomagic] private string isDefinedConstantNonRec(string container, string name) { result = resolveConstantWriteAccessNonRec(_, container, name) @@ -419,6 +447,12 @@ private module ResolveImpl { result = [builtin(), getAnAssumedGlobalConst()] and name = result and container = "Object" + or + exists(ConstantAccess access | + container = getAnAssumedGlobalNamespacePrefix(access.getScopeExpr()) and + name = access.getName() and + result = getAnAssumedGlobalNamespacePrefix(access) + ) } pragma[nomagic] diff --git a/ruby/ql/test/library-tests/modules/ancestors.expected b/ruby/ql/test/library-tests/modules/ancestors.expected index 1a513f49e39..2ebc068459f 100644 --- a/ruby/ql/test/library-tests/modules/ancestors.expected +++ b/ruby/ql/test/library-tests/modules/ancestors.expected @@ -36,6 +36,12 @@ #-----| TrueClass #-----| super -> Object +#-----| UnresolvedNamespace::X1 + +#-----| UnresolvedNamespace::X1::X2 + +#-----| UnresolvedNamespace::X1::X2::X3 + calls.rb: # 21| M @@ -273,11 +279,11 @@ unresolved_subclass.rb: # 11| UnresolvedNamespace::A #-----| super -> Object -# 14| ...::Subclass1 +# 14| UnresolvedNamespace::X1::X2::X3::Subclass1 #-----| super -> ResolvableBaseClass -# 17| ...::Subclass2 -#-----| super -> Object +# 17| UnresolvedNamespace::X1::X2::X3::Subclass2 +#-----| super -> UnresolvedNamespace::X1::X2::X3::Subclass1 -# 21| ...::A +# 21| UnresolvedNamespace::X1::X2::X3::A #-----| super -> Object diff --git a/ruby/ql/test/library-tests/modules/methods.expected b/ruby/ql/test/library-tests/modules/methods.expected index 89c312aea44..cb936f30778 100644 --- a/ruby/ql/test/library-tests/modules/methods.expected +++ b/ruby/ql/test/library-tests/modules/methods.expected @@ -660,15 +660,15 @@ lookupMethod | unresolved_subclass.rb:11:1:12:3 | UnresolvedNamespace::A | new | calls.rb:117:5:117:16 | new | | unresolved_subclass.rb:11:1:12:3 | UnresolvedNamespace::A | puts | calls.rb:102:5:102:30 | puts | | unresolved_subclass.rb:11:1:12:3 | UnresolvedNamespace::A | to_s | calls.rb:172:5:173:7 | to_s | -| unresolved_subclass.rb:14:1:15:3 | ...::Subclass1 | new | calls.rb:117:5:117:16 | new | -| unresolved_subclass.rb:14:1:15:3 | ...::Subclass1 | puts | calls.rb:102:5:102:30 | puts | -| unresolved_subclass.rb:14:1:15:3 | ...::Subclass1 | to_s | calls.rb:172:5:173:7 | to_s | -| unresolved_subclass.rb:17:1:18:3 | ...::Subclass2 | new | calls.rb:117:5:117:16 | new | -| unresolved_subclass.rb:17:1:18:3 | ...::Subclass2 | puts | calls.rb:102:5:102:30 | puts | -| unresolved_subclass.rb:17:1:18:3 | ...::Subclass2 | to_s | calls.rb:172:5:173:7 | to_s | -| unresolved_subclass.rb:21:1:22:3 | ...::A | new | calls.rb:117:5:117:16 | new | -| unresolved_subclass.rb:21:1:22:3 | ...::A | puts | calls.rb:102:5:102:30 | puts | -| unresolved_subclass.rb:21:1:22:3 | ...::A | to_s | calls.rb:172:5:173:7 | to_s | +| unresolved_subclass.rb:14:1:15:3 | UnresolvedNamespace::X1::X2::X3::Subclass1 | new | calls.rb:117:5:117:16 | new | +| unresolved_subclass.rb:14:1:15:3 | UnresolvedNamespace::X1::X2::X3::Subclass1 | puts | calls.rb:102:5:102:30 | puts | +| unresolved_subclass.rb:14:1:15:3 | UnresolvedNamespace::X1::X2::X3::Subclass1 | to_s | calls.rb:172:5:173:7 | to_s | +| unresolved_subclass.rb:17:1:18:3 | UnresolvedNamespace::X1::X2::X3::Subclass2 | new | calls.rb:117:5:117:16 | new | +| unresolved_subclass.rb:17:1:18:3 | UnresolvedNamespace::X1::X2::X3::Subclass2 | puts | calls.rb:102:5:102:30 | puts | +| unresolved_subclass.rb:17:1:18:3 | UnresolvedNamespace::X1::X2::X3::Subclass2 | to_s | calls.rb:172:5:173:7 | to_s | +| unresolved_subclass.rb:21:1:22:3 | UnresolvedNamespace::X1::X2::X3::A | new | calls.rb:117:5:117:16 | new | +| unresolved_subclass.rb:21:1:22:3 | UnresolvedNamespace::X1::X2::X3::A | puts | calls.rb:102:5:102:30 | puts | +| unresolved_subclass.rb:21:1:22:3 | UnresolvedNamespace::X1::X2::X3::A | to_s | calls.rb:172:5:173:7 | to_s | enclosingMethod | calls.rb:2:5:2:14 | call to puts | calls.rb:1:1:3:3 | foo | | calls.rb:2:5:2:14 | self | calls.rb:1:1:3:3 | foo | diff --git a/ruby/ql/test/library-tests/modules/modules.expected b/ruby/ql/test/library-tests/modules/modules.expected index f4b14fe0004..e138f5ce4c3 100644 --- a/ruby/ql/test/library-tests/modules/modules.expected +++ b/ruby/ql/test/library-tests/modules/modules.expected @@ -51,6 +51,9 @@ getModule | file://:0:0:0:0 | Symbol | | file://:0:0:0:0 | TrueClass | | file://:0:0:0:0 | UnresolvedNamespace | +| file://:0:0:0:0 | UnresolvedNamespace::X1 | +| file://:0:0:0:0 | UnresolvedNamespace::X1::X2 | +| file://:0:0:0:0 | UnresolvedNamespace::X1::X2::X3 | | hello.rb:1:1:8:3 | EnglishWords | | hello.rb:11:1:16:3 | Greeting | | hello.rb:18:1:22:3 | HelloWorld | @@ -97,9 +100,9 @@ getModule | unresolved_subclass.rb:4:1:5:3 | UnresolvedNamespace::Subclass1 | | unresolved_subclass.rb:7:1:8:3 | UnresolvedNamespace::Subclass2 | | unresolved_subclass.rb:11:1:12:3 | UnresolvedNamespace::A | -| unresolved_subclass.rb:14:1:15:3 | ...::Subclass1 | -| unresolved_subclass.rb:17:1:18:3 | ...::Subclass2 | -| unresolved_subclass.rb:21:1:22:3 | ...::A | +| unresolved_subclass.rb:14:1:15:3 | UnresolvedNamespace::X1::X2::X3::Subclass1 | +| unresolved_subclass.rb:17:1:18:3 | UnresolvedNamespace::X1::X2::X3::Subclass2 | +| unresolved_subclass.rb:21:1:22:3 | UnresolvedNamespace::X1::X2::X3::A | getADeclaration | calls.rb:21:1:34:3 | M | calls.rb:21:1:34:3 | M | | calls.rb:43:1:58:3 | C | calls.rb:43:1:58:3 | C | @@ -200,9 +203,9 @@ getADeclaration | unresolved_subclass.rb:4:1:5:3 | UnresolvedNamespace::Subclass1 | unresolved_subclass.rb:4:1:5:3 | Subclass1 | | unresolved_subclass.rb:7:1:8:3 | UnresolvedNamespace::Subclass2 | unresolved_subclass.rb:7:1:8:3 | Subclass2 | | unresolved_subclass.rb:11:1:12:3 | UnresolvedNamespace::A | unresolved_subclass.rb:11:1:12:3 | A | -| unresolved_subclass.rb:14:1:15:3 | ...::Subclass1 | unresolved_subclass.rb:14:1:15:3 | Subclass1 | -| unresolved_subclass.rb:17:1:18:3 | ...::Subclass2 | unresolved_subclass.rb:17:1:18:3 | Subclass2 | -| unresolved_subclass.rb:21:1:22:3 | ...::A | unresolved_subclass.rb:21:1:22:3 | A | +| unresolved_subclass.rb:14:1:15:3 | UnresolvedNamespace::X1::X2::X3::Subclass1 | unresolved_subclass.rb:14:1:15:3 | Subclass1 | +| unresolved_subclass.rb:17:1:18:3 | UnresolvedNamespace::X1::X2::X3::Subclass2 | unresolved_subclass.rb:17:1:18:3 | Subclass2 | +| unresolved_subclass.rb:21:1:22:3 | UnresolvedNamespace::X1::X2::X3::A | unresolved_subclass.rb:21:1:22:3 | A | getSuperClass | calls.rb:43:1:58:3 | C | calls.rb:115:1:118:3 | Object | | calls.rb:65:1:69:3 | D | calls.rb:43:1:58:3 | C | @@ -265,9 +268,9 @@ getSuperClass | unresolved_subclass.rb:4:1:5:3 | UnresolvedNamespace::Subclass1 | unresolved_subclass.rb:1:1:2:3 | ResolvableBaseClass | | unresolved_subclass.rb:7:1:8:3 | UnresolvedNamespace::Subclass2 | unresolved_subclass.rb:4:1:5:3 | UnresolvedNamespace::Subclass1 | | unresolved_subclass.rb:11:1:12:3 | UnresolvedNamespace::A | calls.rb:115:1:118:3 | Object | -| unresolved_subclass.rb:14:1:15:3 | ...::Subclass1 | unresolved_subclass.rb:1:1:2:3 | ResolvableBaseClass | -| unresolved_subclass.rb:17:1:18:3 | ...::Subclass2 | calls.rb:115:1:118:3 | Object | -| unresolved_subclass.rb:21:1:22:3 | ...::A | calls.rb:115:1:118:3 | Object | +| unresolved_subclass.rb:14:1:15:3 | UnresolvedNamespace::X1::X2::X3::Subclass1 | unresolved_subclass.rb:1:1:2:3 | ResolvableBaseClass | +| unresolved_subclass.rb:17:1:18:3 | UnresolvedNamespace::X1::X2::X3::Subclass2 | unresolved_subclass.rb:14:1:15:3 | UnresolvedNamespace::X1::X2::X3::Subclass1 | +| unresolved_subclass.rb:21:1:22:3 | UnresolvedNamespace::X1::X2::X3::A | calls.rb:115:1:118:3 | Object | getAPrependedModule | calls.rb:115:1:118:3 | Object | calls.rb:171:1:174:3 | A | | calls.rb:171:1:174:3 | A | toplevel_self_singleton.rb:2:5:5:7 | A::B | @@ -429,11 +432,27 @@ resolveConstantReadAccess | unresolved_subclass.rb:11:7:11:25 | UnresolvedNamespace | UnresolvedNamespace | | unresolved_subclass.rb:11:32:11:50 | UnresolvedNamespace | UnresolvedNamespace | | unresolved_subclass.rb:14:7:14:25 | UnresolvedNamespace | UnresolvedNamespace | +| unresolved_subclass.rb:14:7:14:29 | X1 | UnresolvedNamespace::X1 | +| unresolved_subclass.rb:14:7:14:33 | X2 | UnresolvedNamespace::X1::X2 | +| unresolved_subclass.rb:14:7:14:37 | X3 | UnresolvedNamespace::X1::X2::X3 | | unresolved_subclass.rb:14:52:14:70 | ResolvableBaseClass | ResolvableBaseClass | | unresolved_subclass.rb:17:7:17:25 | UnresolvedNamespace | UnresolvedNamespace | +| unresolved_subclass.rb:17:7:17:29 | X1 | UnresolvedNamespace::X1 | +| unresolved_subclass.rb:17:7:17:33 | X2 | UnresolvedNamespace::X1::X2 | +| unresolved_subclass.rb:17:7:17:37 | X3 | UnresolvedNamespace::X1::X2::X3 | | unresolved_subclass.rb:17:52:17:70 | UnresolvedNamespace | UnresolvedNamespace | +| unresolved_subclass.rb:17:52:17:74 | X1 | UnresolvedNamespace::X1 | +| unresolved_subclass.rb:17:52:17:78 | X2 | UnresolvedNamespace::X1::X2 | +| unresolved_subclass.rb:17:52:17:82 | X3 | UnresolvedNamespace::X1::X2::X3 | +| unresolved_subclass.rb:17:52:17:93 | Subclass1 | UnresolvedNamespace::X1::X2::X3::Subclass1 | | unresolved_subclass.rb:21:7:21:25 | UnresolvedNamespace | UnresolvedNamespace | +| unresolved_subclass.rb:21:7:21:29 | X1 | UnresolvedNamespace::X1 | +| unresolved_subclass.rb:21:7:21:33 | X2 | UnresolvedNamespace::X1::X2 | +| unresolved_subclass.rb:21:7:21:37 | X3 | UnresolvedNamespace::X1::X2::X3 | | unresolved_subclass.rb:21:44:21:62 | UnresolvedNamespace | UnresolvedNamespace | +| unresolved_subclass.rb:21:44:21:66 | X1 | UnresolvedNamespace::X1 | +| unresolved_subclass.rb:21:44:21:70 | X2 | UnresolvedNamespace::X1::X2 | +| unresolved_subclass.rb:21:44:21:74 | X3 | UnresolvedNamespace::X1::X2::X3 | resolveConstantWriteAccess | calls.rb:21:1:34:3 | M | M | | calls.rb:43:1:58:3 | C | C | @@ -538,6 +557,9 @@ resolveConstantWriteAccess | unresolved_subclass.rb:4:1:5:3 | Subclass1 | UnresolvedNamespace::Subclass1 | | unresolved_subclass.rb:7:1:8:3 | Subclass2 | UnresolvedNamespace::Subclass2 | | unresolved_subclass.rb:11:1:12:3 | A | UnresolvedNamespace::A | +| unresolved_subclass.rb:14:1:15:3 | Subclass1 | UnresolvedNamespace::X1::X2::X3::Subclass1 | +| unresolved_subclass.rb:17:1:18:3 | Subclass2 | UnresolvedNamespace::X1::X2::X3::Subclass2 | +| unresolved_subclass.rb:21:1:22:3 | A | UnresolvedNamespace::X1::X2::X3::A | enclosingModule | calls.rb:1:1:3:3 | foo | calls.rb:1:1:651:24 | calls.rb | | calls.rb:2:5:2:14 | call to puts | calls.rb:1:1:651:24 | calls.rb | diff --git a/ruby/ql/test/library-tests/modules/superclasses.expected b/ruby/ql/test/library-tests/modules/superclasses.expected index 3c19d706484..a2c3473098b 100644 --- a/ruby/ql/test/library-tests/modules/superclasses.expected +++ b/ruby/ql/test/library-tests/modules/superclasses.expected @@ -36,6 +36,12 @@ #-----| TrueClass #-----| -> Object +#-----| UnresolvedNamespace::X1 + +#-----| UnresolvedNamespace::X1::X2 + +#-----| UnresolvedNamespace::X1::X2::X3 + calls.rb: # 21| M @@ -263,11 +269,11 @@ unresolved_subclass.rb: # 11| UnresolvedNamespace::A #-----| -> Object -# 14| ...::Subclass1 +# 14| UnresolvedNamespace::X1::X2::X3::Subclass1 #-----| -> ResolvableBaseClass -# 17| ...::Subclass2 -#-----| -> Object +# 17| UnresolvedNamespace::X1::X2::X3::Subclass2 +#-----| -> UnresolvedNamespace::X1::X2::X3::Subclass1 -# 21| ...::A +# 21| UnresolvedNamespace::X1::X2::X3::A #-----| -> Object From 395a9f0e8cc855069d0963e283f329a5fce13c95 Mon Sep 17 00:00:00 2001 From: Asger F <asgerf@github.com> Date: Fri, 24 Mar 2023 14:21:39 +0100 Subject: [PATCH 440/631] Apply suggestions from code review Co-authored-by: Ben Ahmady <32935794+subatoi@users.noreply.github.com> --- ...tomizing-library-models-for-javascript.rst | 30 ++++++++----------- 1 file changed, 12 insertions(+), 18 deletions(-) diff --git a/docs/codeql/codeql-language-guides/customizing-library-models-for-javascript.rst b/docs/codeql/codeql-language-guides/customizing-library-models-for-javascript.rst index 7242b3691a4..a1c41ab61e0 100644 --- a/docs/codeql/codeql-language-guides/customizing-library-models-for-javascript.rst +++ b/docs/codeql/codeql-language-guides/customizing-library-models-for-javascript.rst @@ -10,7 +10,7 @@ Customizing Library Models for JavaScript The JavaScript analysis can be customized by adding library models in data extension files. -A data extension for JavaScript is a YAML file of form: +A data extension for JavaScript is a YAML file of the form: .. code-block:: yaml @@ -23,7 +23,7 @@ A data extension for JavaScript is a YAML file of form: - <tuple2> - ... -The data extension can contribute to the following extension points: +The CodeQL library for JavaScript exposes the following extensible predicates: - **sourceModel**\(type, path, kind) - **sinkModel**\(type, path, kind) @@ -57,7 +57,6 @@ This can be achieved with the following data extension: data: - ["execa", "Member[shell].Argument[0]", "command-line-injection"] -To break this down: - Since we're adding a new sink, we add a tuple to the **sinkModel** extension point. - The first column, **"execa"**, identifies a set of values from which to begin the search for the sink. @@ -95,7 +94,6 @@ This source is already known by the CodeQL JS analysis, but we'll show how it co "remote", ] -To break this down: - Since we're adding a new taint source, we add a tuple to the **sourceModel** extension point. - The first column, **"global"**, begins the search at references to the global object (also known as **window** in browser contexts). This is a special JavaScript object that contains all global variables and methods. @@ -159,7 +157,6 @@ We can recognize this using the following extension: data: - ["mysql.Connection", "Member[query].Argument[0]", "sql-injection"] -To break this down: - The first column, **"mysql.Connection"**, begins the search at any expression whose value is known to be an instance of the **Connection** type from the **mysql** package. This will select the **connection** parameter above because of its type annotation. @@ -167,9 +164,9 @@ To break this down: - **Argument[0]** selects the first argument of a call to that member. - **sql-injection** indicates that this is considered a sink for the SQL injection query. -This works for the example above because the **connection** parameter has a type annotation that matches what the model is looking for. +This works in this example because the **connection** parameter has a type annotation that matches what the model is looking for. -In the next section, we'll show how to generalize the model to handle the absense of type annotations. +In the next section, we'll show how to generalize the model to handle the absence of type annotations. Continued example: Dealing with untyped code -------------------------------------------- @@ -194,7 +191,6 @@ Using a **typeModel** tuple we can tell our model that this function returns an data: - ["mysql.Connection", "@example/db", "Member[getConnection].ReturnValue"] -To break this down: - Since we're providing type information, we add a tuple to the **typeModel** extension point. - The first column, **"mysql.Connection"**, names the type that we're adding a new definition for. @@ -239,9 +235,8 @@ This flow is already recognized by the CodeQL JS analysis, but this is how it co "taint", ] -To break this down: -- Since we're adding flow *through* a function call, we add a tuple to the **summaryModel** extension point. +- Since we're adding flow through a function call, we add a tuple to the **summaryModel** extension point. - The first column, **"global"**, begins the search for relevant calls at references to the global object. In JavaScript, global variables are properties of the global object, so this lets us access global variables or functions. - The second column, **Member[decodeURIComponent]**, is a path leading to the function calls we wish to model. @@ -250,7 +245,7 @@ To break this down: - The third column, **Argument[0]**, indicates the input of the flow. In this case, the first argument to the function call. - The fourth column, **ReturnValue**, indicates the output of the flow. In this case, the return value of the function call. - The last column, **taint**, indicates the kind of flow to add. The value **taint** means the output is not necessarily equal - to the input, but was was derived from the input in a taint-preserving way. + to the input, but was derived from the input in a taint-preserving way. Example: Adding flow through 'underscore.forEach' ------------------------------------------------- @@ -278,9 +273,8 @@ This flow is already recognized by the CodeQL JS analysis, but we'll show how it "value", ] -To break this down: -- Since we're adding flow *through* a function call, we add a tuple to the **summaryModel** extension point. +- Since we're adding flow through a function call, we add a tuple to the **summaryModel** extension point. - The first column, **"underscore"**, begins the search for relevant calls at places where the **underscore** package is imported. - The second column, **Member[forEach]**, selects references to the **forEach** member from the **underscore** package. - The third column specifies the input of the flow: @@ -327,7 +321,7 @@ Example: sinkModel(type, path, kind) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Adds a new taint sink. Sinks are query-specific and will usually affect one or two queries. +Adds a new taint sink. Sinks are query-specific and will typically affect one or two queries. - **type**: Name of a type from which to evaluate **path**. - **path**: Access path leading to the sink. @@ -410,7 +404,7 @@ A type can be defined by adding **typeModel** tuples for that type. Additionally Access paths ------------ -The **path**, **input**, and **output** columns consist of a **.**-separated list of components, which is evaluted from left to right, with each step selecting a new set of values derived from the previous set of values. +The **path**, **input**, and **output** columns consist of a **.**-separated list of components, which is evaluated from left to right, with each step selecting a new set of values derived from the previous set of values. The following components are supported: @@ -438,7 +432,7 @@ Components related to decorators: - **DecoratedParameter** selects a parameter that is decorated by the current value. - **DecoratedMember** selects a method, field, or accessor that is decorated by the current value. -Some additional notes about the syntax of operands: +Additional notes about the syntax of operands: - Multiple operands may be given to a single component, as a shorthand for the union of the operands. For example, **Member[foo,bar]** matches the union of **Member[foo]** and **Member[bar]**. - Numeric operands to **Argument**, **Parameter**, and **WithArity** may be given as an interval. For example, **Argument[0..2]** matches argument 0, 1, or 2. @@ -455,11 +449,11 @@ Source kinds Sink kinds ~~~~~~~~~~ -Unlike sources, sinks tend to be highly query-specific, rarely affecting more than one or two queries. Not every query supports customizable sinks. If there is no suitable sink kind below, it is best to add a new query instead. +Unlike sources, sinks tend to be highly query-specific, rarely affecting more than one or two queries. Not every query supports customizable sinks. If the following sinks are not suitable for your use case, you should add a new query. - **code-injection**: A sink that can be used to inject code, such as in calls to **eval**. - **command-line-injection**: A sink that can be used to inject shell commands, such as in calls to **child_process.spawn**. -- **path-injection**: A sink that can be used for path injection in a file system access, such as in a calls to **fs.readFile**. +- **path-injection**: A sink that can be used for path injection in a file system access, such as in calls to **fs.readFile**. - **sql-injection**: A sink that can be used for SQL injection, such as in a MySQL **query** call. - **nosql-injection**: A sink that can be used for NoSQL injection, such as in a MongoDB **findOne** call. - **html-injection**: A sink that can be used for HTML injection, such as in a jQuery **$()** call. From c45c2ff842176b762227824a71d790586b19075e Mon Sep 17 00:00:00 2001 From: Michael Nebel <michaelnebel@github.com> Date: Fri, 24 Mar 2023 14:24:21 +0100 Subject: [PATCH 441/631] Add google doc link. --- docs/codeql/reusables/data-extensions.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/codeql/reusables/data-extensions.rst b/docs/codeql/reusables/data-extensions.rst index 5a1fa223347..5b79ba81265 100644 --- a/docs/codeql/reusables/data-extensions.rst +++ b/docs/codeql/reusables/data-extensions.rst @@ -7,4 +7,4 @@ Data Extensions Beta Notice - Internal documentation - Data extensions are documented internally in a Google doc. \ No newline at end of file + Data extensions are documented internally in a `Google doc <https://docs.google.com/document/d/14IYCHX8wWuU-HTvJ2gPSdXQKHKYbWCHQKOgn8oLaa80>`_. From 4a418b1f292184e512c613fb60e69df6a13165b0 Mon Sep 17 00:00:00 2001 From: Asger F <asgerf@github.com> Date: Fri, 24 Mar 2023 14:37:30 +0100 Subject: [PATCH 442/631] Apply suggestion from code review (execa) --- .../customizing-library-models-for-javascript.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/codeql/codeql-language-guides/customizing-library-models-for-javascript.rst b/docs/codeql/codeql-language-guides/customizing-library-models-for-javascript.rst index c5415c63ca4..f8e367f9cfc 100644 --- a/docs/codeql/codeql-language-guides/customizing-library-models-for-javascript.rst +++ b/docs/codeql/codeql-language-guides/customizing-library-models-for-javascript.rst @@ -37,7 +37,7 @@ We'll explain how to use these using a few examples, and provide some reference Example: Taint sink in the 'execa' package ------------------------------------------ -In this example, we'll show how to add the argument passed to **execa** below as a command-line injection sink: +In this example, we'll show how to add the following argument, passed to **execa**, as a command-line injection sink: .. code-block:: js From 8b7ab28f2553c34c841172e1725d3e422da0e85e Mon Sep 17 00:00:00 2001 From: Asger F <asgerf@github.com> Date: Fri, 24 Mar 2023 14:40:06 +0100 Subject: [PATCH 443/631] JS: Add "In the next section..." --- .../customizing-library-models-for-javascript.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/codeql/codeql-language-guides/customizing-library-models-for-javascript.rst b/docs/codeql/codeql-language-guides/customizing-library-models-for-javascript.rst index f8e367f9cfc..6861e748f4f 100644 --- a/docs/codeql/codeql-language-guides/customizing-library-models-for-javascript.rst +++ b/docs/codeql/codeql-language-guides/customizing-library-models-for-javascript.rst @@ -103,6 +103,8 @@ This source is already known by the CodeQL JS analysis, but we'll show how it co - **Member[data]** selects accesses to the **data** property of the event object. - Finally, the kind **remote** indicates that this is considered a source of remote flow. +In the next section, we'll show how to restrict the model to recognize events of a specific type. + Continued example: Restricting the event type --------------------------------------------- From 2a57b00a131e7bbe148e0f5e8d0dde9753a3e7cd Mon Sep 17 00:00:00 2001 From: Asger F <asgerf@github.com> Date: Fri, 24 Mar 2023 14:41:35 +0100 Subject: [PATCH 444/631] JS: Above -> previous section --- .../customizing-library-models-for-javascript.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/codeql/codeql-language-guides/customizing-library-models-for-javascript.rst b/docs/codeql/codeql-language-guides/customizing-library-models-for-javascript.rst index 6861e748f4f..c04f33b3c2b 100644 --- a/docs/codeql/codeql-language-guides/customizing-library-models-for-javascript.rst +++ b/docs/codeql/codeql-language-guides/customizing-library-models-for-javascript.rst @@ -396,7 +396,7 @@ Types ----- A type is a string that identifies a set of values. -In each of the extensible predicates mentioned above, the first column is always the name of a type. +In each of the extensible predicates mentioned in previous section, the first column is always the name of a type. A type can be defined by adding **typeModel** tuples for that type. Additionally, the following built-in types are available: - The name of an NPM package matches imports of that package. For example, the type **express** matches the expression **require("express")**. If the package name includes dots, it must be surrounded by single quotes, such as in **'lodash.escape'**. From 768102ee925be402d4dfcabeeaa8d69b54f4848e Mon Sep 17 00:00:00 2001 From: Ed Minnix <egregius313@github.com> Date: Thu, 16 Mar 2023 14:38:54 -0400 Subject: [PATCH 445/631] Refactor java/android/webview-debugging-enabled --- ...y.qll => WebviewDebuggingEnabledQuery.qll} | 30 +++++++++++++++++-- .../CWE/CWE-489/WebviewDebuggingEnabled.ql | 8 ++--- .../WebviewDebuggingEnabled.ql | 21 +++++++------ 3 files changed, 44 insertions(+), 15 deletions(-) rename java/ql/lib/semmle/code/java/security/{WebviewDubuggingEnabledQuery.qll => WebviewDebuggingEnabledQuery.qll} (59%) diff --git a/java/ql/lib/semmle/code/java/security/WebviewDubuggingEnabledQuery.qll b/java/ql/lib/semmle/code/java/security/WebviewDebuggingEnabledQuery.qll similarity index 59% rename from java/ql/lib/semmle/code/java/security/WebviewDubuggingEnabledQuery.qll rename to java/ql/lib/semmle/code/java/security/WebviewDebuggingEnabledQuery.qll index 92071c2af1a..858da08ea01 100644 --- a/java/ql/lib/semmle/code/java/security/WebviewDubuggingEnabledQuery.qll +++ b/java/ql/lib/semmle/code/java/security/WebviewDebuggingEnabledQuery.qll @@ -18,8 +18,12 @@ private predicate isDebugCheck(Expr ex) { ) } -/** A configuration to find instances of `setWebContentDebuggingEnabled` called with `true` values. */ -class WebviewDebugEnabledConfig extends DataFlow::Configuration { +/** + * DEPRECATED: Use `WebviewDebugEnabledFlow` instead. + * + * A configuration to find instances of `setWebContentDebuggingEnabled` called with `true` values. + */ +deprecated class WebviewDebugEnabledConfig extends DataFlow::Configuration { WebviewDebugEnabledConfig() { this = "WebviewDebugEnabledConfig" } override predicate isSource(DataFlow::Node node) { @@ -39,3 +43,25 @@ class WebviewDebugEnabledConfig extends DataFlow::Configuration { node.getEnclosingCallable().getDeclaringType() instanceof NonSecurityTestClass } } + +/** A configuration to find instances of `setWebContentDebuggingEnabled` called with `true` values. */ +private module WebviewDebugEnabledConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node node) { + node.asExpr().(BooleanLiteral).getBooleanValue() = true + } + + predicate isSink(DataFlow::Node node) { + exists(MethodAccess ma | + ma.getMethod().hasQualifiedName("android.webkit", "WebView", "setWebContentsDebuggingEnabled") and + node.asExpr() = ma.getArgument(0) + ) + } + + predicate isBarrier(DataFlow::Node node) { + exists(Guard debug | isDebugCheck(debug) and debug.controls(node.asExpr().getBasicBlock(), _)) + or + node.getEnclosingCallable().getDeclaringType() instanceof NonSecurityTestClass + } +} + +module WebviewDebugEnabledFlow = DataFlow::Make<WebviewDebugEnabledConfig>; diff --git a/java/ql/src/Security/CWE/CWE-489/WebviewDebuggingEnabled.ql b/java/ql/src/Security/CWE/CWE-489/WebviewDebuggingEnabled.ql index a8f7f81d832..cafa616e2d1 100644 --- a/java/ql/src/Security/CWE/CWE-489/WebviewDebuggingEnabled.ql +++ b/java/ql/src/Security/CWE/CWE-489/WebviewDebuggingEnabled.ql @@ -11,9 +11,9 @@ */ import java -import semmle.code.java.security.WebviewDubuggingEnabledQuery -import DataFlow::PathGraph +import semmle.code.java.security.WebviewDebuggingEnabledQuery +import WebviewDebugEnabledFlow::PathGraph -from WebviewDebugEnabledConfig conf, DataFlow::PathNode source, DataFlow::PathNode sink -where conf.hasFlowPath(source, sink) +from WebviewDebugEnabledFlow::PathNode source, WebviewDebugEnabledFlow::PathNode sink +where WebviewDebugEnabledFlow::hasFlowPath(source, sink) select sink, source, sink, "Webview debugging is enabled." diff --git a/java/ql/test/query-tests/security/CWE-489/webview-debugging/WebviewDebuggingEnabled.ql b/java/ql/test/query-tests/security/CWE-489/webview-debugging/WebviewDebuggingEnabled.ql index aeceb941e09..35d237bf134 100644 --- a/java/ql/test/query-tests/security/CWE-489/webview-debugging/WebviewDebuggingEnabled.ql +++ b/java/ql/test/query-tests/security/CWE-489/webview-debugging/WebviewDebuggingEnabled.ql @@ -1,15 +1,18 @@ import java -import TestUtilities.InlineFlowTest -import semmle.code.java.security.WebviewDubuggingEnabledQuery +import TestUtilities.InlineExpectationsTest +import semmle.code.java.security.WebviewDebuggingEnabledQuery -class EnableLegacy extends EnableLegacyConfiguration { - EnableLegacy() { exists(this) } -} +class HasFlowTest extends InlineExpectationsTest { + HasFlowTest() { this = "HasFlowTest" } -class HasFlowTest extends InlineFlowTest { - override DataFlow::Configuration getTaintFlowConfig() { none() } + override string getARelevantTag() { result = "hasValueFlow" } - override DataFlow::Configuration getValueFlowConfig() { - result = any(WebviewDebugEnabledConfig c) + override predicate hasActualResult(Location location, string element, string tag, string value) { + tag = "hasValueFlow" and + exists(DataFlow::Node sink | WebviewDebugEnabledFlow::hasFlowTo(sink) | + location = sink.getLocation() and + element = "sink" and + value = "" + ) } } From 807588a031ff065fbd0335666a7f4699ba4612f2 Mon Sep 17 00:00:00 2001 From: Ed Minnix <egregius313@github.com> Date: Thu, 16 Mar 2023 21:52:40 -0400 Subject: [PATCH 446/631] Refactor AndroidCertificatePinningQuery --- .../security/AndroidCertificatePinningQuery.qll | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/java/ql/lib/semmle/code/java/security/AndroidCertificatePinningQuery.qll b/java/ql/lib/semmle/code/java/security/AndroidCertificatePinningQuery.qll index 70dc1a7a328..cd8ccdf6758 100644 --- a/java/ql/lib/semmle/code/java/security/AndroidCertificatePinningQuery.qll +++ b/java/ql/lib/semmle/code/java/security/AndroidCertificatePinningQuery.qll @@ -106,10 +106,8 @@ private class MissingPinningSink extends DataFlow::Node { } /** Configuration for finding uses of non trusted URLs. */ -private class UntrustedUrlConfig extends TaintTracking::Configuration { - UntrustedUrlConfig() { this = "UntrustedUrlConfig" } - - override predicate isSource(DataFlow::Node node) { +private module UntrustedUrlConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node node) { trustedDomain(_) and exists(string lit | lit = node.asExpr().(CompileTimeConstantExpr).getStringValue() | lit.matches("%://%") and // it's a URL @@ -117,9 +115,11 @@ private class UntrustedUrlConfig extends TaintTracking::Configuration { ) } - override predicate isSink(DataFlow::Node node) { node instanceof MissingPinningSink } + predicate isSink(DataFlow::Node node) { node instanceof MissingPinningSink } } +private module UntrustedUrlFlow = TaintTracking::Make<UntrustedUrlConfig>; + /** Holds if `node` is a network communication call for which certificate pinning is not implemented. */ predicate missingPinning(DataFlow::Node node, string domain) { isAndroid() and @@ -127,8 +127,8 @@ predicate missingPinning(DataFlow::Node node, string domain) { ( not trustedDomain(_) and domain = "" or - exists(UntrustedUrlConfig conf, DataFlow::Node src | - conf.hasFlow(src, node) and + exists(DataFlow::Node src | + UntrustedUrlFlow::hasFlow(src, node) and domain = getDomain(src.asExpr()) ) ) From 1e0c6811a4f072242d1160d528b41b15403712f5 Mon Sep 17 00:00:00 2001 From: Ed Minnix <egregius313@github.com> Date: Tue, 21 Mar 2023 16:36:26 -0400 Subject: [PATCH 447/631] Refactor UnsafeAndroidAccess --- .../java/security/UnsafeAndroidAccessQuery.qll | 14 +++++++++++++- .../Security/CWE/CWE-749/UnsafeAndroidAccess.ql | 6 +++--- .../security/CWE-749/UnsafeAndroidAccessTest.ql | 2 +- 3 files changed, 17 insertions(+), 5 deletions(-) diff --git a/java/ql/lib/semmle/code/java/security/UnsafeAndroidAccessQuery.qll b/java/ql/lib/semmle/code/java/security/UnsafeAndroidAccessQuery.qll index 6bd9833047d..3d4a5bd8057 100644 --- a/java/ql/lib/semmle/code/java/security/UnsafeAndroidAccessQuery.qll +++ b/java/ql/lib/semmle/code/java/security/UnsafeAndroidAccessQuery.qll @@ -7,9 +7,11 @@ import semmle.code.java.security.RequestForgery import semmle.code.java.security.UnsafeAndroidAccess /** + * DEPRECATED: Use `FetchUntrustedResourceFlow` instead. + * * A taint configuration tracking flow from untrusted inputs to a resource fetching call. */ -class FetchUntrustedResourceConfiguration extends TaintTracking::Configuration { +deprecated class FetchUntrustedResourceConfiguration extends TaintTracking::Configuration { FetchUntrustedResourceConfiguration() { this = "FetchUntrustedResourceConfiguration" } override predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource } @@ -20,3 +22,13 @@ class FetchUntrustedResourceConfiguration extends TaintTracking::Configuration { sanitizer instanceof RequestForgerySanitizer } } + +private module FetchUntrustedResourceConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource } + + predicate isSink(DataFlow::Node sink) { sink instanceof UrlResourceSink } + + predicate isBarrier(DataFlow::Node sanitizer) { sanitizer instanceof RequestForgerySanitizer } +} + +module FetchUntrustedResourceFlow = TaintTracking::Make<FetchUntrustedResourceConfig>; diff --git a/java/ql/src/Security/CWE/CWE-749/UnsafeAndroidAccess.ql b/java/ql/src/Security/CWE/CWE-749/UnsafeAndroidAccess.ql index 277b1b5790e..c397bf74b93 100644 --- a/java/ql/src/Security/CWE/CWE-749/UnsafeAndroidAccess.ql +++ b/java/ql/src/Security/CWE/CWE-749/UnsafeAndroidAccess.ql @@ -14,9 +14,9 @@ import java import semmle.code.java.security.UnsafeAndroidAccessQuery -import DataFlow::PathGraph +import FetchUntrustedResourceFlow::PathGraph -from DataFlow::PathNode source, DataFlow::PathNode sink, FetchUntrustedResourceConfiguration conf -where conf.hasFlowPath(source, sink) +from FetchUntrustedResourceFlow::PathNode source, FetchUntrustedResourceFlow::PathNode sink +where FetchUntrustedResourceFlow::hasFlowPath(source, sink) select sink.getNode(), source, sink, "Unsafe resource fetching in Android WebView due to $@.", source.getNode(), sink.getNode().(UrlResourceSink).getSinkType() diff --git a/java/ql/test/query-tests/security/CWE-749/UnsafeAndroidAccessTest.ql b/java/ql/test/query-tests/security/CWE-749/UnsafeAndroidAccessTest.ql index 7305d6aeb6f..158c00e5566 100644 --- a/java/ql/test/query-tests/security/CWE-749/UnsafeAndroidAccessTest.ql +++ b/java/ql/test/query-tests/security/CWE-749/UnsafeAndroidAccessTest.ql @@ -9,7 +9,7 @@ class UnsafeAndroidAccessTest extends InlineExpectationsTest { override predicate hasActualResult(Location location, string element, string tag, string value) { tag = "hasUnsafeAndroidAccess" and - exists(DataFlow::Node sink, FetchUntrustedResourceConfiguration conf | conf.hasFlowTo(sink) | + exists(DataFlow::Node sink | FetchUntrustedResourceFlow::hasFlowTo(sink) | sink.getLocation() = location and element = sink.toString() and value = "" From d68bec98bcc952f4935cbbb81aacd84fe5645eb9 Mon Sep 17 00:00:00 2001 From: Ed Minnix <egregius313@github.com> Date: Thu, 16 Mar 2023 22:05:20 -0400 Subject: [PATCH 448/631] Refactor CWE-940/AndroidIntentRedirection --- .../AndroidIntentRedirectionQuery.qll | 49 +++++++++++++------ .../CWE/CWE-940/AndroidIntentRedirection.ql | 6 +-- .../CWE-940/AndroidIntentRedirectionTest.ql | 2 +- 3 files changed, 37 insertions(+), 20 deletions(-) diff --git a/java/ql/lib/semmle/code/java/security/AndroidIntentRedirectionQuery.qll b/java/ql/lib/semmle/code/java/security/AndroidIntentRedirectionQuery.qll index 9d5a2cb4cf2..5971ab597fa 100644 --- a/java/ql/lib/semmle/code/java/security/AndroidIntentRedirectionQuery.qll +++ b/java/ql/lib/semmle/code/java/security/AndroidIntentRedirectionQuery.qll @@ -8,9 +8,11 @@ import semmle.code.java.dataflow.TaintTracking3 import semmle.code.java.security.AndroidIntentRedirection /** + * DEPRECATED: Use `IntentRedirectionFlow` instead. + * * A taint tracking configuration for tainted Intents being used to start Android components. */ -class IntentRedirectionConfiguration extends TaintTracking::Configuration { +deprecated class IntentRedirectionConfiguration extends TaintTracking::Configuration { IntentRedirectionConfiguration() { this = "IntentRedirectionConfiguration" } override predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource } @@ -26,31 +28,44 @@ class IntentRedirectionConfiguration extends TaintTracking::Configuration { } } +private module IntentRedirectionConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource } + + predicate isSink(DataFlow::Node sink) { sink instanceof IntentRedirectionSink } + + predicate isBarrier(DataFlow::Node sanitizer) { sanitizer instanceof IntentRedirectionSanitizer } + + predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) { + any(IntentRedirectionAdditionalTaintStep c).step(node1, node2) + } +} + +/** A taint tracking configuration for tainted Intents being used to start Android components. */ +module IntentRedirectionFlow = TaintTracking::Make<IntentRedirectionConfig>; + /** * A sanitizer for sinks that receive the original incoming Intent, * since its component cannot be arbitrarily set. */ private class OriginalIntentSanitizer extends IntentRedirectionSanitizer { - OriginalIntentSanitizer() { any(SameIntentBeingRelaunchedConfiguration c).hasFlowTo(this) } + OriginalIntentSanitizer() { SameIntentBeingRelaunchedFlow::hasFlowTo(this) } } /** * Data flow configuration used to discard incoming Intents * flowing directly to sinks that start Android components. */ -private class SameIntentBeingRelaunchedConfiguration extends DataFlow2::Configuration { - SameIntentBeingRelaunchedConfiguration() { this = "SameIntentBeingRelaunchedConfiguration" } +private module SameIntentBeingRelaunchedConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource } - override predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource } + predicate isSink(DataFlow::Node sink) { sink instanceof IntentRedirectionSink } - override predicate isSink(DataFlow::Node sink) { sink instanceof IntentRedirectionSink } - - override predicate isBarrier(DataFlow::Node barrier) { + predicate isBarrier(DataFlow::Node barrier) { // Don't discard the Intent if its original component is tainted barrier instanceof IntentWithTaintedComponent } - override predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) { + predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) { // Intents being built with the copy constructor from the original Intent are discarded too exists(ClassInstanceExpr cie | cie.getConstructedType() instanceof TypeIntent and @@ -61,12 +76,14 @@ private class SameIntentBeingRelaunchedConfiguration extends DataFlow2::Configur } } +private module SameIntentBeingRelaunchedFlow = DataFlow::Make<SameIntentBeingRelaunchedConfig>; + /** An `Intent` with a tainted component. */ private class IntentWithTaintedComponent extends DataFlow::Node { IntentWithTaintedComponent() { - exists(IntentSetComponent setExpr, TaintedIntentComponentConf conf | + exists(IntentSetComponent setExpr | setExpr.getQualifier() = this.asExpr() and - conf.hasFlowTo(DataFlow::exprNode(setExpr.getSink())) + TaintedIntentComponentFlow::hasFlowTo(DataFlow::exprNode(setExpr.getSink())) ) } } @@ -74,16 +91,16 @@ private class IntentWithTaintedComponent extends DataFlow::Node { /** * A taint tracking configuration for tainted data flowing to an `Intent`'s component. */ -private class TaintedIntentComponentConf extends TaintTracking3::Configuration { - TaintedIntentComponentConf() { this = "TaintedIntentComponentConf" } +private module TaintedIntentComponentConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource } - override predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource } - - override predicate isSink(DataFlow::Node sink) { + predicate isSink(DataFlow::Node sink) { any(IntentSetComponent setComponent).getSink() = sink.asExpr() } } +private module TaintedIntentComponentFlow = TaintTracking::Make<TaintedIntentComponentConfig>; + /** A call to a method that changes the component of an `Intent`. */ private class IntentSetComponent extends MethodAccess { int sinkArg; diff --git a/java/ql/src/Security/CWE/CWE-940/AndroidIntentRedirection.ql b/java/ql/src/Security/CWE/CWE-940/AndroidIntentRedirection.ql index 1ace2fc4fcc..c00915f7172 100644 --- a/java/ql/src/Security/CWE/CWE-940/AndroidIntentRedirection.ql +++ b/java/ql/src/Security/CWE/CWE-940/AndroidIntentRedirection.ql @@ -15,10 +15,10 @@ import java import semmle.code.java.security.AndroidIntentRedirectionQuery -import DataFlow::PathGraph +import IntentRedirectionFlow::PathGraph -from DataFlow::PathNode source, DataFlow::PathNode sink, IntentRedirectionConfiguration conf -where conf.hasFlowPath(source, sink) +from IntentRedirectionFlow::PathNode source, IntentRedirectionFlow::PathNode sink +where IntentRedirectionFlow::hasFlowPath(source, sink) select sink.getNode(), source, sink, "Arbitrary Android activities or services can be started from a $@.", source.getNode(), "user-provided value" diff --git a/java/ql/test/query-tests/security/CWE-940/AndroidIntentRedirectionTest.ql b/java/ql/test/query-tests/security/CWE-940/AndroidIntentRedirectionTest.ql index 62605ed505d..02e69d025ff 100644 --- a/java/ql/test/query-tests/security/CWE-940/AndroidIntentRedirectionTest.ql +++ b/java/ql/test/query-tests/security/CWE-940/AndroidIntentRedirectionTest.ql @@ -9,7 +9,7 @@ class HasAndroidIntentRedirectionTest extends InlineExpectationsTest { override predicate hasActualResult(Location location, string element, string tag, string value) { tag = "hasAndroidIntentRedirection" and - exists(DataFlow::Node sink, IntentRedirectionConfiguration conf | conf.hasFlowTo(sink) | + exists(DataFlow::Node sink | IntentRedirectionFlow::hasFlowTo(sink) | sink.getLocation() = location and element = sink.toString() and value = "" From 413a6cbc4f476fc76719ca0977051c1c1dbfdfcd Mon Sep 17 00:00:00 2001 From: Ed Minnix <egregius313@github.com> Date: Tue, 21 Mar 2023 20:16:26 -0400 Subject: [PATCH 449/631] Refactor SensitiveKeyboardCacheQuery --- .../security/SensitiveKeyboardCacheQuery.qll | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/java/ql/lib/semmle/code/java/security/SensitiveKeyboardCacheQuery.qll b/java/ql/lib/semmle/code/java/security/SensitiveKeyboardCacheQuery.qll index 5a78932a7cd..ad4c480e7ad 100644 --- a/java/ql/lib/semmle/code/java/security/SensitiveKeyboardCacheQuery.qll +++ b/java/ql/lib/semmle/code/java/security/SensitiveKeyboardCacheQuery.qll @@ -91,16 +91,14 @@ private predicate inputTypeFieldNotCached(Field f) { } /** Configuration that finds uses of `setInputType` for non cached fields. */ -private class GoodInputTypeConf extends DataFlow::Configuration { - GoodInputTypeConf() { this = "GoodInputTypeConf" } - - override predicate isSource(DataFlow::Node node) { +private module GoodInputTypeConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node node) { inputTypeFieldNotCached(node.asExpr().(FieldAccess).getField()) } - override predicate isSink(DataFlow::Node node) { node.asExpr() = setInputTypeForId(_) } + predicate isSink(DataFlow::Node node) { node.asExpr() = setInputTypeForId(_) } - override predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) { + predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) { exists(OrBitwiseExpr bitOr | node1.asExpr() = bitOr.getAChildExpr() and node2.asExpr() = bitOr @@ -108,6 +106,8 @@ private class GoodInputTypeConf extends DataFlow::Configuration { } } +private module GoodInputTypeFlow = DataFlow::Make<GoodInputTypeConfig>; + /** Gets a regex indicating that an input field may contain sensitive data. */ private string getInputSensitiveInfoRegex() { result = @@ -130,8 +130,8 @@ AndroidEditableXmlElement getASensitiveCachedInput() { result.getId().regexpMatch(getInputSensitiveInfoRegex()) and ( not inputTypeNotCached(result.getInputType()) and - not exists(GoodInputTypeConf conf, DataFlow::Node sink | - conf.hasFlowTo(sink) and + not exists(DataFlow::Node sink | + GoodInputTypeFlow::hasFlowTo(sink) and sink.asExpr() = setInputTypeForId(result.getId()) ) ) From ef08a9134014cf1faac56a252838841ff7de0301 Mon Sep 17 00:00:00 2001 From: Ed Minnix <egregius313@github.com> Date: Tue, 21 Mar 2023 13:15:01 -0400 Subject: [PATCH 450/631] Refactor ImproperIntentVerificationQuery.qll --- .../security/ImproperIntentVerificationQuery.qll | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/java/ql/lib/semmle/code/java/security/ImproperIntentVerificationQuery.qll b/java/ql/lib/semmle/code/java/security/ImproperIntentVerificationQuery.qll index 00a6dae69e9..3f362c42bba 100644 --- a/java/ql/lib/semmle/code/java/security/ImproperIntentVerificationQuery.qll +++ b/java/ql/lib/semmle/code/java/security/ImproperIntentVerificationQuery.qll @@ -14,14 +14,12 @@ private class OnReceiveMethod extends Method { } /** A configuration to detect whether the `action` of an `Intent` is checked. */ -private class VerifiedIntentConfig extends DataFlow::Configuration { - VerifiedIntentConfig() { this = "VerifiedIntentConfig" } - - override predicate isSource(DataFlow::Node src) { +private module VerifiedIntentConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node src) { src.asParameter() = any(OnReceiveMethod orm).getIntentParameter() } - override predicate isSink(DataFlow::Node sink) { + predicate isSink(DataFlow::Node sink) { exists(MethodAccess ma | ma.getMethod().hasQualifiedName("android.content", "Intent", "getAction") and sink.asExpr() = ma.getQualifier() @@ -29,10 +27,12 @@ private class VerifiedIntentConfig extends DataFlow::Configuration { } } +private module VerifiedIntentFlow = DataFlow::Make<VerifiedIntentConfig>; + /** An `onReceive` method that doesn't verify the action of the intent it receives. */ private class UnverifiedOnReceiveMethod extends OnReceiveMethod { UnverifiedOnReceiveMethod() { - not any(VerifiedIntentConfig c).hasFlow(DataFlow::parameterNode(this.getIntentParameter()), _) + not VerifiedIntentFlow::hasFlow(DataFlow::parameterNode(this.getIntentParameter()), _) } } From e7f6d5390750894e59045b9e97ccd4377424c599 Mon Sep 17 00:00:00 2001 From: Ed Minnix <egregius313@github.com> Date: Wed, 22 Mar 2023 12:14:11 -0400 Subject: [PATCH 451/631] Deprecate `WebViewDubuggingQuery.qll` --- .../2023-03-22-deprecate-webviewdubuggingenabledquery.md | 4 ++++ .../code/java/security/WebviewDubuggingEnabledQuery.qll | 8 ++++++++ 2 files changed, 12 insertions(+) create mode 100644 java/ql/lib/change-notes/2023-03-22-deprecate-webviewdubuggingenabledquery.md create mode 100644 java/ql/lib/semmle/code/java/security/WebviewDubuggingEnabledQuery.qll diff --git a/java/ql/lib/change-notes/2023-03-22-deprecate-webviewdubuggingenabledquery.md b/java/ql/lib/change-notes/2023-03-22-deprecate-webviewdubuggingenabledquery.md new file mode 100644 index 00000000000..e4f2933c04a --- /dev/null +++ b/java/ql/lib/change-notes/2023-03-22-deprecate-webviewdubuggingenabledquery.md @@ -0,0 +1,4 @@ +--- +category: deprecated +--- +* The `WebViewDubuggingQuery` library has been renamed to `WebViewDebuggingQuery` to fix the typo in the file name. `WebViewDubuggingQuery` is now deprecated. diff --git a/java/ql/lib/semmle/code/java/security/WebviewDubuggingEnabledQuery.qll b/java/ql/lib/semmle/code/java/security/WebviewDubuggingEnabledQuery.qll new file mode 100644 index 00000000000..3c517ef719e --- /dev/null +++ b/java/ql/lib/semmle/code/java/security/WebviewDubuggingEnabledQuery.qll @@ -0,0 +1,8 @@ +/** + * DEPRECATED: Use `semmle.code.java.security.WebviewDebuggingEnabledQuery` instead. + * + * Definitions for the Android Webview Debugging Enabled query + */ + +import java +import semmle.code.java.security.WebviewDebuggingEnabledQuery From 58bd2f7fa2636b86267196c8ea01c67eac8566e3 Mon Sep 17 00:00:00 2001 From: Ed Minnix <egregius313@github.com> Date: Wed, 22 Mar 2023 12:17:49 -0400 Subject: [PATCH 452/631] Address code review comments --- .../code/java/security/AndroidIntentRedirectionQuery.qll | 5 +++-- .../code/java/security/UnsafeAndroidAccessQuery.qll | 8 +++++++- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/java/ql/lib/semmle/code/java/security/AndroidIntentRedirectionQuery.qll b/java/ql/lib/semmle/code/java/security/AndroidIntentRedirectionQuery.qll index 5971ab597fa..cc5d6a6004b 100644 --- a/java/ql/lib/semmle/code/java/security/AndroidIntentRedirectionQuery.qll +++ b/java/ql/lib/semmle/code/java/security/AndroidIntentRedirectionQuery.qll @@ -28,7 +28,8 @@ deprecated class IntentRedirectionConfiguration extends TaintTracking::Configura } } -private module IntentRedirectionConfig implements DataFlow::ConfigSig { +/** A taint tracking configuration for tainted Intents being used to start Android components. */ +module IntentRedirectionConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource } predicate isSink(DataFlow::Node sink) { sink instanceof IntentRedirectionSink } @@ -40,7 +41,7 @@ private module IntentRedirectionConfig implements DataFlow::ConfigSig { } } -/** A taint tracking configuration for tainted Intents being used to start Android components. */ +/** Tracks the flow of tainted Intents being used to start Android components. */ module IntentRedirectionFlow = TaintTracking::Make<IntentRedirectionConfig>; /** diff --git a/java/ql/lib/semmle/code/java/security/UnsafeAndroidAccessQuery.qll b/java/ql/lib/semmle/code/java/security/UnsafeAndroidAccessQuery.qll index 3d4a5bd8057..9a713ff7dfc 100644 --- a/java/ql/lib/semmle/code/java/security/UnsafeAndroidAccessQuery.qll +++ b/java/ql/lib/semmle/code/java/security/UnsafeAndroidAccessQuery.qll @@ -23,7 +23,10 @@ deprecated class FetchUntrustedResourceConfiguration extends TaintTracking::Conf } } -private module FetchUntrustedResourceConfig implements DataFlow::ConfigSig { +/** + * A taint configuration tracking flow from untrusted inputs to a resource fetching call. + */ +module FetchUntrustedResourceConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource } predicate isSink(DataFlow::Node sink) { sink instanceof UrlResourceSink } @@ -31,4 +34,7 @@ private module FetchUntrustedResourceConfig implements DataFlow::ConfigSig { predicate isBarrier(DataFlow::Node sanitizer) { sanitizer instanceof RequestForgerySanitizer } } +/** + * Detects taint flow from untrusted inputs to a resource fetching call. + */ module FetchUntrustedResourceFlow = TaintTracking::Make<FetchUntrustedResourceConfig>; From 8cc2a7329e49306385db1c687e35b6d25c6f32f0 Mon Sep 17 00:00:00 2001 From: Ed Minnix <egregius313@github.com> Date: Wed, 22 Mar 2023 22:55:55 -0400 Subject: [PATCH 453/631] Fix test to use new InlineFlowTest --- .../WebviewDebuggingEnabled.ql | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/java/ql/test/query-tests/security/CWE-489/webview-debugging/WebviewDebuggingEnabled.ql b/java/ql/test/query-tests/security/CWE-489/webview-debugging/WebviewDebuggingEnabled.ql index 35d237bf134..20c38ea52ee 100644 --- a/java/ql/test/query-tests/security/CWE-489/webview-debugging/WebviewDebuggingEnabled.ql +++ b/java/ql/test/query-tests/security/CWE-489/webview-debugging/WebviewDebuggingEnabled.ql @@ -1,18 +1,11 @@ import java -import TestUtilities.InlineExpectationsTest +import TestUtilities.InlineFlowTest import semmle.code.java.security.WebviewDebuggingEnabledQuery -class HasFlowTest extends InlineExpectationsTest { - HasFlowTest() { this = "HasFlowTest" } +class HasFlowTest extends InlineFlowTest { + override predicate hasTaintFlow(DataFlow::Node src, DataFlow::Node sink) { none() } - override string getARelevantTag() { result = "hasValueFlow" } - - override predicate hasActualResult(Location location, string element, string tag, string value) { - tag = "hasValueFlow" and - exists(DataFlow::Node sink | WebviewDebugEnabledFlow::hasFlowTo(sink) | - location = sink.getLocation() and - element = "sink" and - value = "" - ) + override predicate hasValueFlow(DataFlow::Node src, DataFlow::Node sink) { + WebviewDebugEnabledFlow::hasFlow(src, sink) } } From c62eaba60171053a234f02d322baf2c57bbd0d78 Mon Sep 17 00:00:00 2001 From: Edward Minnix III <egregius313@github.com> Date: Thu, 23 Mar 2023 10:04:24 -0400 Subject: [PATCH 454/631] Simulate deprecated import Co-authored-by: Anders Schack-Mulligen <aschackmull@users.noreply.github.com> --- .../code/java/security/WebviewDubuggingEnabledQuery.qll | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/java/ql/lib/semmle/code/java/security/WebviewDubuggingEnabledQuery.qll b/java/ql/lib/semmle/code/java/security/WebviewDubuggingEnabledQuery.qll index 3c517ef719e..70180d651bf 100644 --- a/java/ql/lib/semmle/code/java/security/WebviewDubuggingEnabledQuery.qll +++ b/java/ql/lib/semmle/code/java/security/WebviewDubuggingEnabledQuery.qll @@ -5,4 +5,6 @@ */ import java -import semmle.code.java.security.WebviewDebuggingEnabledQuery +private import semmle.code.java.security.WebviewDebuggingEnabledQuery as WebviewDebuggingEnabledQuery + +deprecated class WebviewDebugEnabledConfig = WebviewDebuggingEnabledQuery:: WebviewDebugEnabledConfig; From 2eea34dc4a884eff69c1040987a5c505a69cf229 Mon Sep 17 00:00:00 2001 From: Ed Minnix <egregius313@github.com> Date: Thu, 23 Mar 2023 10:08:22 -0400 Subject: [PATCH 455/631] Apply suggestions from code review --- .../code/java/security/WebviewDebuggingEnabledQuery.qll | 5 ++++- .../code/java/security/WebviewDubuggingEnabledQuery.qll | 3 ++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/java/ql/lib/semmle/code/java/security/WebviewDebuggingEnabledQuery.qll b/java/ql/lib/semmle/code/java/security/WebviewDebuggingEnabledQuery.qll index 858da08ea01..daeb0790121 100644 --- a/java/ql/lib/semmle/code/java/security/WebviewDebuggingEnabledQuery.qll +++ b/java/ql/lib/semmle/code/java/security/WebviewDebuggingEnabledQuery.qll @@ -45,7 +45,7 @@ deprecated class WebviewDebugEnabledConfig extends DataFlow::Configuration { } /** A configuration to find instances of `setWebContentDebuggingEnabled` called with `true` values. */ -private module WebviewDebugEnabledConfig implements DataFlow::ConfigSig { +module WebviewDebugEnabledConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node node) { node.asExpr().(BooleanLiteral).getBooleanValue() = true } @@ -64,4 +64,7 @@ private module WebviewDebugEnabledConfig implements DataFlow::ConfigSig { } } +/** + * Tracks instances of `setWebContentDebuggingEnabled` with `true` values. + */ module WebviewDebugEnabledFlow = DataFlow::Make<WebviewDebugEnabledConfig>; diff --git a/java/ql/lib/semmle/code/java/security/WebviewDubuggingEnabledQuery.qll b/java/ql/lib/semmle/code/java/security/WebviewDubuggingEnabledQuery.qll index 70180d651bf..f315c55291e 100644 --- a/java/ql/lib/semmle/code/java/security/WebviewDubuggingEnabledQuery.qll +++ b/java/ql/lib/semmle/code/java/security/WebviewDubuggingEnabledQuery.qll @@ -7,4 +7,5 @@ import java private import semmle.code.java.security.WebviewDebuggingEnabledQuery as WebviewDebuggingEnabledQuery -deprecated class WebviewDebugEnabledConfig = WebviewDebuggingEnabledQuery:: WebviewDebugEnabledConfig; +deprecated class WebviewDebugEnabledConfig = + WebviewDebuggingEnabledQuery::WebviewDebugEnabledConfig; From f6900bd8079b562e231d6d9d63d47f5d37af40b4 Mon Sep 17 00:00:00 2001 From: Asger F <asgerf@github.com> Date: Fri, 24 Mar 2023 14:54:13 +0100 Subject: [PATCH 456/631] JS: Rephrase a few sentences --- .../customizing-library-models-for-javascript.rst | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/docs/codeql/codeql-language-guides/customizing-library-models-for-javascript.rst b/docs/codeql/codeql-language-guides/customizing-library-models-for-javascript.rst index c04f33b3c2b..8ddf9ac8f70 100644 --- a/docs/codeql/codeql-language-guides/customizing-library-models-for-javascript.rst +++ b/docs/codeql/codeql-language-guides/customizing-library-models-for-javascript.rst @@ -44,9 +44,7 @@ In this example, we'll show how to add the following argument, passed to **execa import { shell } from "execa"; shell(cmd); // <-- add 'cmd' as a taint sink -This sink is already recognized by the CodeQL JS analysis, but for the sake of this example we'll show how it could be added as an extension. - -This can be achieved with the following data extension: +Note that this sink is already recognized by the CodeQL JS analysis, but for this example, you could use the following data extension: .. code-block:: yaml @@ -79,7 +77,7 @@ In this example, we'll show how the **event.data** expression below could be mar let data = event.data; // <-- add 'event.data' as a taint source }); -This source is already known by the CodeQL JS analysis, but we'll show how it could be added as an extension. This can be achieved with the following extension: +Note that this source is already known by the CodeQL JS analysis, but for this example, you could use the following data extension: .. code-block:: yaml @@ -220,7 +218,7 @@ In this example, we'll show how to add flow through calls to `decodeURIComponent let y = decodeURIComponent(x); // add taint flow from 'x' to 'y' -This flow is already recognized by the CodeQL JS analysis, but this is how it could be added with an extension: +Note that this flow is already recognized by the CodeQL JS analysis, but for this example, you could use the following data extension: .. code-block:: yaml @@ -258,7 +256,7 @@ In this example, we'll show how to add flow through calls to **forEach** from th require('underscore').forEach([x, y], (v) => { ... }); // add value flow from 'x' and 'y' to 'v' -This flow is already recognized by the CodeQL JS analysis, but we'll show how it could be added with an extension. +Note that this flow is already recognized by the CodeQL JS analysis, but for this example, you could use the following data extension: .. code-block:: yaml From 1bf4dd964995b9eae06cbe5e844bfa8cffd1be8e Mon Sep 17 00:00:00 2001 From: Ed Minnix <egregius313@github.com> Date: Fri, 24 Mar 2023 09:54:53 -0400 Subject: [PATCH 457/631] Update to DataFlow::Global --- .../java/security/AndroidCertificatePinningQuery.qll | 4 ++-- .../java/security/AndroidIntentRedirectionQuery.qll | 10 +++++----- .../java/security/ImproperIntentVerificationQuery.qll | 4 ++-- .../code/java/security/SensitiveKeyboardCacheQuery.qll | 4 ++-- .../code/java/security/UnsafeAndroidAccessQuery.qll | 2 +- .../java/security/WebviewDebuggingEnabledQuery.qll | 2 +- .../Security/CWE/CWE-489/WebviewDebuggingEnabled.ql | 2 +- .../ql/src/Security/CWE/CWE-749/UnsafeAndroidAccess.ql | 2 +- .../Security/CWE/CWE-940/AndroidIntentRedirection.ql | 2 +- .../webview-debugging/WebviewDebuggingEnabled.ql | 2 +- .../security/CWE-749/UnsafeAndroidAccessTest.ql | 2 +- .../security/CWE-940/AndroidIntentRedirectionTest.ql | 2 +- 12 files changed, 19 insertions(+), 19 deletions(-) diff --git a/java/ql/lib/semmle/code/java/security/AndroidCertificatePinningQuery.qll b/java/ql/lib/semmle/code/java/security/AndroidCertificatePinningQuery.qll index cd8ccdf6758..86779a4a911 100644 --- a/java/ql/lib/semmle/code/java/security/AndroidCertificatePinningQuery.qll +++ b/java/ql/lib/semmle/code/java/security/AndroidCertificatePinningQuery.qll @@ -118,7 +118,7 @@ private module UntrustedUrlConfig implements DataFlow::ConfigSig { predicate isSink(DataFlow::Node node) { node instanceof MissingPinningSink } } -private module UntrustedUrlFlow = TaintTracking::Make<UntrustedUrlConfig>; +private module UntrustedUrlFlow = TaintTracking::Global<UntrustedUrlConfig>; /** Holds if `node` is a network communication call for which certificate pinning is not implemented. */ predicate missingPinning(DataFlow::Node node, string domain) { @@ -128,7 +128,7 @@ predicate missingPinning(DataFlow::Node node, string domain) { not trustedDomain(_) and domain = "" or exists(DataFlow::Node src | - UntrustedUrlFlow::hasFlow(src, node) and + UntrustedUrlFlow::flow(src, node) and domain = getDomain(src.asExpr()) ) ) diff --git a/java/ql/lib/semmle/code/java/security/AndroidIntentRedirectionQuery.qll b/java/ql/lib/semmle/code/java/security/AndroidIntentRedirectionQuery.qll index cc5d6a6004b..87fd5003afb 100644 --- a/java/ql/lib/semmle/code/java/security/AndroidIntentRedirectionQuery.qll +++ b/java/ql/lib/semmle/code/java/security/AndroidIntentRedirectionQuery.qll @@ -42,14 +42,14 @@ module IntentRedirectionConfig implements DataFlow::ConfigSig { } /** Tracks the flow of tainted Intents being used to start Android components. */ -module IntentRedirectionFlow = TaintTracking::Make<IntentRedirectionConfig>; +module IntentRedirectionFlow = TaintTracking::Global<IntentRedirectionConfig>; /** * A sanitizer for sinks that receive the original incoming Intent, * since its component cannot be arbitrarily set. */ private class OriginalIntentSanitizer extends IntentRedirectionSanitizer { - OriginalIntentSanitizer() { SameIntentBeingRelaunchedFlow::hasFlowTo(this) } + OriginalIntentSanitizer() { SameIntentBeingRelaunchedFlow::flowTo(this) } } /** @@ -77,14 +77,14 @@ private module SameIntentBeingRelaunchedConfig implements DataFlow::ConfigSig { } } -private module SameIntentBeingRelaunchedFlow = DataFlow::Make<SameIntentBeingRelaunchedConfig>; +private module SameIntentBeingRelaunchedFlow = DataFlow::Global<SameIntentBeingRelaunchedConfig>; /** An `Intent` with a tainted component. */ private class IntentWithTaintedComponent extends DataFlow::Node { IntentWithTaintedComponent() { exists(IntentSetComponent setExpr | setExpr.getQualifier() = this.asExpr() and - TaintedIntentComponentFlow::hasFlowTo(DataFlow::exprNode(setExpr.getSink())) + TaintedIntentComponentFlow::flowTo(DataFlow::exprNode(setExpr.getSink())) ) } } @@ -100,7 +100,7 @@ private module TaintedIntentComponentConfig implements DataFlow::ConfigSig { } } -private module TaintedIntentComponentFlow = TaintTracking::Make<TaintedIntentComponentConfig>; +private module TaintedIntentComponentFlow = TaintTracking::Global<TaintedIntentComponentConfig>; /** A call to a method that changes the component of an `Intent`. */ private class IntentSetComponent extends MethodAccess { diff --git a/java/ql/lib/semmle/code/java/security/ImproperIntentVerificationQuery.qll b/java/ql/lib/semmle/code/java/security/ImproperIntentVerificationQuery.qll index 3f362c42bba..db59c5c5291 100644 --- a/java/ql/lib/semmle/code/java/security/ImproperIntentVerificationQuery.qll +++ b/java/ql/lib/semmle/code/java/security/ImproperIntentVerificationQuery.qll @@ -27,12 +27,12 @@ private module VerifiedIntentConfig implements DataFlow::ConfigSig { } } -private module VerifiedIntentFlow = DataFlow::Make<VerifiedIntentConfig>; +private module VerifiedIntentFlow = DataFlow::Global<VerifiedIntentConfig>; /** An `onReceive` method that doesn't verify the action of the intent it receives. */ private class UnverifiedOnReceiveMethod extends OnReceiveMethod { UnverifiedOnReceiveMethod() { - not VerifiedIntentFlow::hasFlow(DataFlow::parameterNode(this.getIntentParameter()), _) + not VerifiedIntentFlow::flow(DataFlow::parameterNode(this.getIntentParameter()), _) } } diff --git a/java/ql/lib/semmle/code/java/security/SensitiveKeyboardCacheQuery.qll b/java/ql/lib/semmle/code/java/security/SensitiveKeyboardCacheQuery.qll index ad4c480e7ad..2a41d2da08c 100644 --- a/java/ql/lib/semmle/code/java/security/SensitiveKeyboardCacheQuery.qll +++ b/java/ql/lib/semmle/code/java/security/SensitiveKeyboardCacheQuery.qll @@ -106,7 +106,7 @@ private module GoodInputTypeConfig implements DataFlow::ConfigSig { } } -private module GoodInputTypeFlow = DataFlow::Make<GoodInputTypeConfig>; +private module GoodInputTypeFlow = DataFlow::Global<GoodInputTypeConfig>; /** Gets a regex indicating that an input field may contain sensitive data. */ private string getInputSensitiveInfoRegex() { @@ -131,7 +131,7 @@ AndroidEditableXmlElement getASensitiveCachedInput() { ( not inputTypeNotCached(result.getInputType()) and not exists(DataFlow::Node sink | - GoodInputTypeFlow::hasFlowTo(sink) and + GoodInputTypeFlow::flowTo(sink) and sink.asExpr() = setInputTypeForId(result.getId()) ) ) diff --git a/java/ql/lib/semmle/code/java/security/UnsafeAndroidAccessQuery.qll b/java/ql/lib/semmle/code/java/security/UnsafeAndroidAccessQuery.qll index 9a713ff7dfc..267bfd6bf39 100644 --- a/java/ql/lib/semmle/code/java/security/UnsafeAndroidAccessQuery.qll +++ b/java/ql/lib/semmle/code/java/security/UnsafeAndroidAccessQuery.qll @@ -37,4 +37,4 @@ module FetchUntrustedResourceConfig implements DataFlow::ConfigSig { /** * Detects taint flow from untrusted inputs to a resource fetching call. */ -module FetchUntrustedResourceFlow = TaintTracking::Make<FetchUntrustedResourceConfig>; +module FetchUntrustedResourceFlow = TaintTracking::Global<FetchUntrustedResourceConfig>; diff --git a/java/ql/lib/semmle/code/java/security/WebviewDebuggingEnabledQuery.qll b/java/ql/lib/semmle/code/java/security/WebviewDebuggingEnabledQuery.qll index daeb0790121..d5aaf92f412 100644 --- a/java/ql/lib/semmle/code/java/security/WebviewDebuggingEnabledQuery.qll +++ b/java/ql/lib/semmle/code/java/security/WebviewDebuggingEnabledQuery.qll @@ -67,4 +67,4 @@ module WebviewDebugEnabledConfig implements DataFlow::ConfigSig { /** * Tracks instances of `setWebContentDebuggingEnabled` with `true` values. */ -module WebviewDebugEnabledFlow = DataFlow::Make<WebviewDebugEnabledConfig>; +module WebviewDebugEnabledFlow = DataFlow::Global<WebviewDebugEnabledConfig>; diff --git a/java/ql/src/Security/CWE/CWE-489/WebviewDebuggingEnabled.ql b/java/ql/src/Security/CWE/CWE-489/WebviewDebuggingEnabled.ql index cafa616e2d1..c34a40358d9 100644 --- a/java/ql/src/Security/CWE/CWE-489/WebviewDebuggingEnabled.ql +++ b/java/ql/src/Security/CWE/CWE-489/WebviewDebuggingEnabled.ql @@ -15,5 +15,5 @@ import semmle.code.java.security.WebviewDebuggingEnabledQuery import WebviewDebugEnabledFlow::PathGraph from WebviewDebugEnabledFlow::PathNode source, WebviewDebugEnabledFlow::PathNode sink -where WebviewDebugEnabledFlow::hasFlowPath(source, sink) +where WebviewDebugEnabledFlow::flowPath(source, sink) select sink, source, sink, "Webview debugging is enabled." diff --git a/java/ql/src/Security/CWE/CWE-749/UnsafeAndroidAccess.ql b/java/ql/src/Security/CWE/CWE-749/UnsafeAndroidAccess.ql index c397bf74b93..6cdcab9d4cc 100644 --- a/java/ql/src/Security/CWE/CWE-749/UnsafeAndroidAccess.ql +++ b/java/ql/src/Security/CWE/CWE-749/UnsafeAndroidAccess.ql @@ -17,6 +17,6 @@ import semmle.code.java.security.UnsafeAndroidAccessQuery import FetchUntrustedResourceFlow::PathGraph from FetchUntrustedResourceFlow::PathNode source, FetchUntrustedResourceFlow::PathNode sink -where FetchUntrustedResourceFlow::hasFlowPath(source, sink) +where FetchUntrustedResourceFlow::flowPath(source, sink) select sink.getNode(), source, sink, "Unsafe resource fetching in Android WebView due to $@.", source.getNode(), sink.getNode().(UrlResourceSink).getSinkType() diff --git a/java/ql/src/Security/CWE/CWE-940/AndroidIntentRedirection.ql b/java/ql/src/Security/CWE/CWE-940/AndroidIntentRedirection.ql index c00915f7172..5fac8c7ecc1 100644 --- a/java/ql/src/Security/CWE/CWE-940/AndroidIntentRedirection.ql +++ b/java/ql/src/Security/CWE/CWE-940/AndroidIntentRedirection.ql @@ -18,7 +18,7 @@ import semmle.code.java.security.AndroidIntentRedirectionQuery import IntentRedirectionFlow::PathGraph from IntentRedirectionFlow::PathNode source, IntentRedirectionFlow::PathNode sink -where IntentRedirectionFlow::hasFlowPath(source, sink) +where IntentRedirectionFlow::flowPath(source, sink) select sink.getNode(), source, sink, "Arbitrary Android activities or services can be started from a $@.", source.getNode(), "user-provided value" diff --git a/java/ql/test/query-tests/security/CWE-489/webview-debugging/WebviewDebuggingEnabled.ql b/java/ql/test/query-tests/security/CWE-489/webview-debugging/WebviewDebuggingEnabled.ql index 20c38ea52ee..5bd19fb5b9e 100644 --- a/java/ql/test/query-tests/security/CWE-489/webview-debugging/WebviewDebuggingEnabled.ql +++ b/java/ql/test/query-tests/security/CWE-489/webview-debugging/WebviewDebuggingEnabled.ql @@ -6,6 +6,6 @@ class HasFlowTest extends InlineFlowTest { override predicate hasTaintFlow(DataFlow::Node src, DataFlow::Node sink) { none() } override predicate hasValueFlow(DataFlow::Node src, DataFlow::Node sink) { - WebviewDebugEnabledFlow::hasFlow(src, sink) + WebviewDebugEnabledFlow::flow(src, sink) } } diff --git a/java/ql/test/query-tests/security/CWE-749/UnsafeAndroidAccessTest.ql b/java/ql/test/query-tests/security/CWE-749/UnsafeAndroidAccessTest.ql index 158c00e5566..4da1ca7fd5f 100644 --- a/java/ql/test/query-tests/security/CWE-749/UnsafeAndroidAccessTest.ql +++ b/java/ql/test/query-tests/security/CWE-749/UnsafeAndroidAccessTest.ql @@ -9,7 +9,7 @@ class UnsafeAndroidAccessTest extends InlineExpectationsTest { override predicate hasActualResult(Location location, string element, string tag, string value) { tag = "hasUnsafeAndroidAccess" and - exists(DataFlow::Node sink | FetchUntrustedResourceFlow::hasFlowTo(sink) | + exists(DataFlow::Node sink | FetchUntrustedResourceFlow::flowTo(sink) | sink.getLocation() = location and element = sink.toString() and value = "" diff --git a/java/ql/test/query-tests/security/CWE-940/AndroidIntentRedirectionTest.ql b/java/ql/test/query-tests/security/CWE-940/AndroidIntentRedirectionTest.ql index 02e69d025ff..7b74855caa5 100644 --- a/java/ql/test/query-tests/security/CWE-940/AndroidIntentRedirectionTest.ql +++ b/java/ql/test/query-tests/security/CWE-940/AndroidIntentRedirectionTest.ql @@ -9,7 +9,7 @@ class HasAndroidIntentRedirectionTest extends InlineExpectationsTest { override predicate hasActualResult(Location location, string element, string tag, string value) { tag = "hasAndroidIntentRedirection" and - exists(DataFlow::Node sink | IntentRedirectionFlow::hasFlowTo(sink) | + exists(DataFlow::Node sink | IntentRedirectionFlow::flowTo(sink) | sink.getLocation() = location and element = sink.toString() and value = "" From c44254e2e0ce5763c5b2c4ce8dd7b91272658819 Mon Sep 17 00:00:00 2001 From: Ed Minnix <egregius313@github.com> Date: Tue, 21 Mar 2023 15:50:10 -0400 Subject: [PATCH 458/631] Refactor XsltInjection --- .../code/java/security/XsltInjectionQuery.qll | 46 ++++++++++++++----- .../src/Security/CWE/CWE-074/XsltInjection.ql | 6 +-- .../security/CWE-074/XsltInjectionTest.ql | 2 +- 3 files changed, 38 insertions(+), 16 deletions(-) diff --git a/java/ql/lib/semmle/code/java/security/XsltInjectionQuery.qll b/java/ql/lib/semmle/code/java/security/XsltInjectionQuery.qll index 3cfe91f7408..8329fda0ca5 100644 --- a/java/ql/lib/semmle/code/java/security/XsltInjectionQuery.qll +++ b/java/ql/lib/semmle/code/java/security/XsltInjectionQuery.qll @@ -7,9 +7,11 @@ import semmle.code.java.security.XmlParsers import semmle.code.java.security.XsltInjection /** + * DEPRECATED: Use `XsltInjectionFlow` instead. + * * A taint-tracking configuration for unvalidated user input that is used in XSLT transformation. */ -class XsltInjectionFlowConfig extends TaintTracking::Configuration { +deprecated class XsltInjectionFlowConfig extends TaintTracking::Configuration { XsltInjectionFlowConfig() { this = "XsltInjectionFlowConfig" } override predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource } @@ -25,6 +27,28 @@ class XsltInjectionFlowConfig extends TaintTracking::Configuration { } } +/** + * A taint-tracking configuration for unvalidated user input that is used in XSLT transformation. + */ +private module XsltInjectionFlowConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource } + + predicate isSink(DataFlow::Node sink) { sink instanceof XsltInjectionSink } + + predicate isBarrier(DataFlow::Node node) { + node.getType() instanceof PrimitiveType or node.getType() instanceof BoxedType + } + + predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) { + any(XsltInjectionAdditionalTaintStep c).step(node1, node2) + } +} + +/** + * Tracks flow from unvalidated user input to XSLT transformation. + */ +module XsltInjectionFlow = TaintTracking::Make<XsltInjectionFlowConfig>; + /** * A set of additional taint steps to consider when taint tracking XSLT related data flows. * These steps use data flow logic themselves. @@ -46,22 +70,17 @@ private predicate newTransformerOrTemplatesStep(DataFlow::Node n1, DataFlow::Nod n2.asExpr() = ma and m.getDeclaringType() instanceof TransformerFactory and m.hasName(["newTransformer", "newTemplates"]) and - not exists(TransformerFactoryWithSecureProcessingFeatureFlowConfig conf | - conf.hasFlowToExpr(ma.getQualifier()) - ) + not TransformerFactoryWithSecureProcessingFeatureFlow::hasFlowToExpr(ma.getQualifier()) ) } /** * A data flow configuration for secure processing feature that is enabled on `TransformerFactory`. */ -private class TransformerFactoryWithSecureProcessingFeatureFlowConfig extends DataFlow2::Configuration +private module TransformerFactoryWithSecureProcessingFeatureFlowConfig implements + DataFlow::ConfigSig { - TransformerFactoryWithSecureProcessingFeatureFlowConfig() { - this = "TransformerFactoryWithSecureProcessingFeatureFlowConfig" - } - - override predicate isSource(DataFlow::Node src) { + predicate isSource(DataFlow::Node src) { exists(Variable v | v = src.asExpr().(VarAccess).getVariable() | exists(TransformerFactoryFeatureConfig config | config.getQualifier() = v.getAnAccess() | config.enables(configSecureProcessing()) @@ -69,16 +88,19 @@ private class TransformerFactoryWithSecureProcessingFeatureFlowConfig extends Da ) } - override predicate isSink(DataFlow::Node sink) { + predicate isSink(DataFlow::Node sink) { exists(MethodAccess ma | sink.asExpr() = ma.getQualifier() and ma.getMethod().getDeclaringType() instanceof TransformerFactory ) } - override int fieldFlowBranchLimit() { result = 0 } + int fieldFlowBranchLimit() { result = 0 } } +private module TransformerFactoryWithSecureProcessingFeatureFlow = + DataFlow::Make<TransformerFactoryWithSecureProcessingFeatureFlowConfig>; + /** A `ParserConfig` specific to `TransformerFactory`. */ private class TransformerFactoryFeatureConfig extends ParserConfig { TransformerFactoryFeatureConfig() { diff --git a/java/ql/src/Security/CWE/CWE-074/XsltInjection.ql b/java/ql/src/Security/CWE/CWE-074/XsltInjection.ql index 7c4a9b95c96..2888b91b3bf 100644 --- a/java/ql/src/Security/CWE/CWE-074/XsltInjection.ql +++ b/java/ql/src/Security/CWE/CWE-074/XsltInjection.ql @@ -13,9 +13,9 @@ import java import semmle.code.java.security.XsltInjectionQuery -import DataFlow::PathGraph +import XsltInjectionFlow::PathGraph -from DataFlow::PathNode source, DataFlow::PathNode sink, XsltInjectionFlowConfig conf -where conf.hasFlowPath(source, sink) +from XsltInjectionFlow::PathNode source, XsltInjectionFlow::PathNode sink +where XsltInjectionFlow::hasFlowPath(source, sink) select sink.getNode(), source, sink, "XSLT transformation might include stylesheet from $@.", source.getNode(), "this user input" diff --git a/java/ql/test/query-tests/security/CWE-074/XsltInjectionTest.ql b/java/ql/test/query-tests/security/CWE-074/XsltInjectionTest.ql index c914638a129..a8c79964742 100644 --- a/java/ql/test/query-tests/security/CWE-074/XsltInjectionTest.ql +++ b/java/ql/test/query-tests/security/CWE-074/XsltInjectionTest.ql @@ -11,7 +11,7 @@ class HasXsltInjectionTest extends InlineExpectationsTest { override predicate hasActualResult(Location location, string element, string tag, string value) { tag = "hasXsltInjection" and - exists(DataFlow::Node sink, XsltInjectionFlowConfig conf | conf.hasFlowTo(sink) | + exists(DataFlow::Node sink | XsltInjectionFlow::hasFlowTo(sink) | sink.getLocation() = location and element = sink.toString() and value = "" From 7ee6c06f7f518cdcc1620df98d89ec7c01d5e9bf Mon Sep 17 00:00:00 2001 From: Ed Minnix <egregius313@github.com> Date: Mon, 20 Mar 2023 17:21:38 -0400 Subject: [PATCH 459/631] Refactor RegexInjectionQuery --- .../security/regexp/RegexInjectionQuery.qll | 21 +++++++++++++++++-- .../Security/CWE/CWE-730/RegexInjection.ql | 6 +++--- .../security/CWE-730/RegexInjectionTest.ql | 2 +- 3 files changed, 23 insertions(+), 6 deletions(-) diff --git a/java/ql/lib/semmle/code/java/security/regexp/RegexInjectionQuery.qll b/java/ql/lib/semmle/code/java/security/regexp/RegexInjectionQuery.qll index e2453c08dca..88115465629 100644 --- a/java/ql/lib/semmle/code/java/security/regexp/RegexInjectionQuery.qll +++ b/java/ql/lib/semmle/code/java/security/regexp/RegexInjectionQuery.qll @@ -5,8 +5,12 @@ import semmle.code.java.dataflow.FlowSources import semmle.code.java.dataflow.TaintTracking import semmle.code.java.security.regexp.RegexInjection -/** A taint-tracking configuration for untrusted user input used to construct regular expressions. */ -class RegexInjectionConfiguration extends TaintTracking::Configuration { +/** + * DEPRECATED: Use `RegexInjectionFlow` instead. + * + * A taint-tracking configuration for untrusted user input used to construct regular expressions. + */ +deprecated class RegexInjectionConfiguration extends TaintTracking::Configuration { RegexInjectionConfiguration() { this = "RegexInjection" } override predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource } @@ -15,3 +19,16 @@ class RegexInjectionConfiguration extends TaintTracking::Configuration { override predicate isSanitizer(DataFlow::Node node) { node instanceof RegexInjectionSanitizer } } + +/** + * A taint-tracking configuration for untrusted user input used to construct regular expressions. + */ +private module RegexInjectionConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource } + + predicate isSink(DataFlow::Node sink) { sink instanceof RegexInjectionSink } + + predicate isBarrier(DataFlow::Node node) { node instanceof RegexInjectionSanitizer } +} + +module RegexInjectionFlow = TaintTracking::Make<RegexInjectionConfig>; diff --git a/java/ql/src/Security/CWE/CWE-730/RegexInjection.ql b/java/ql/src/Security/CWE/CWE-730/RegexInjection.ql index 820e0949d22..954bc8337fe 100644 --- a/java/ql/src/Security/CWE/CWE-730/RegexInjection.ql +++ b/java/ql/src/Security/CWE/CWE-730/RegexInjection.ql @@ -15,9 +15,9 @@ import java import semmle.code.java.security.regexp.RegexInjectionQuery -import DataFlow::PathGraph +import RegexInjectionFlow::PathGraph -from DataFlow::PathNode source, DataFlow::PathNode sink, RegexInjectionConfiguration c -where c.hasFlowPath(source, sink) +from RegexInjectionFlow::PathNode source, RegexInjectionFlow::PathNode sink +where RegexInjectionFlow::hasFlowPath(source, sink) select sink.getNode(), source, sink, "This regular expression is constructed from a $@.", source.getNode(), "user-provided value" diff --git a/java/ql/test/query-tests/security/CWE-730/RegexInjectionTest.ql b/java/ql/test/query-tests/security/CWE-730/RegexInjectionTest.ql index 63b4f19b3a1..2a9b34fc4cd 100644 --- a/java/ql/test/query-tests/security/CWE-730/RegexInjectionTest.ql +++ b/java/ql/test/query-tests/security/CWE-730/RegexInjectionTest.ql @@ -9,7 +9,7 @@ class RegexInjectionTest extends InlineExpectationsTest { override predicate hasActualResult(Location location, string element, string tag, string value) { tag = "hasRegexInjection" and - exists(DataFlow::PathNode sink, RegexInjectionConfiguration c | c.hasFlowPath(_, sink) | + exists(RegexInjectionFlow::PathNode sink | RegexInjectionFlow::hasFlowPath(_, sink) | location = sink.getNode().getLocation() and element = sink.getNode().toString() and value = "" From 8bf3315bb552732a8f87438d324309789b01e50e Mon Sep 17 00:00:00 2001 From: Ed Minnix <egregius313@github.com> Date: Tue, 21 Mar 2023 17:28:55 -0400 Subject: [PATCH 460/631] Refactor JexlInjection --- .../code/java/security/JexlInjectionQuery.qll | 41 ++++++++++++++----- .../src/Security/CWE/CWE-094/JexlInjection.ql | 6 +-- .../security/CWE-094/JexlInjectionTest.ql | 2 +- 3 files changed, 35 insertions(+), 14 deletions(-) diff --git a/java/ql/lib/semmle/code/java/security/JexlInjectionQuery.qll b/java/ql/lib/semmle/code/java/security/JexlInjectionQuery.qll index 655f78abcba..c2b2c799823 100644 --- a/java/ql/lib/semmle/code/java/security/JexlInjectionQuery.qll +++ b/java/ql/lib/semmle/code/java/security/JexlInjectionQuery.qll @@ -39,11 +39,13 @@ private class DefaultJexlInjectionAdditionalTaintStep extends JexlInjectionAddit } /** + * DEPRECATED: Use `JexlInjectionFlow` instead. + * * A taint-tracking configuration for unsafe user input * that is used to construct and evaluate a JEXL expression. * It supports both JEXL 2 and 3. */ -class JexlInjectionConfig extends TaintTracking::Configuration { +deprecated class JexlInjectionConfig extends TaintTracking::Configuration { JexlInjectionConfig() { this = "JexlInjectionConfig" } override predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource } @@ -55,6 +57,27 @@ class JexlInjectionConfig extends TaintTracking::Configuration { } } +/** + * A taint-tracking configuration for unsafe user input + * that is used to construct and evaluate a JEXL expression. + * It supports both JEXL 2 and 3. + */ +private module JexlInjectionConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource } + + predicate isSink(DataFlow::Node sink) { sink instanceof JexlEvaluationSink } + + predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) { + any(JexlInjectionAdditionalTaintStep c).step(node1, node2) + } +} + +/** + * Tracks unsafe user input that is used to construct and evaluate a JEXL expression. + * It supports both JEXL 2 and 3. + */ +module JexlInjectionFlow = TaintTracking::Make<JexlInjectionConfig>; + /** * Holds if `n1` to `n2` is a dataflow step that creates a JEXL script using an unsafe engine * by calling `tainted.createScript(jexlExpr)`. @@ -99,19 +122,15 @@ private predicate createJexlTemplateStep(DataFlow::Node n1, DataFlow::Node n2) { /** * Holds if `expr` is a JEXL engine that is configured with a sandbox. */ -private predicate isSafeEngine(Expr expr) { - exists(SandboxedJexlFlowConfig config | config.hasFlowTo(DataFlow::exprNode(expr))) -} +private predicate isSafeEngine(Expr expr) { SandboxedJexlFlow::hasFlowToExpr(expr) } /** * A configuration for tracking sandboxed JEXL engines. */ -private class SandboxedJexlFlowConfig extends DataFlow2::Configuration { - SandboxedJexlFlowConfig() { this = "JexlInjection::SandboxedJexlFlowConfig" } +private module SandboxedJexlFlowConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node node) { node instanceof SandboxedJexlSource } - override predicate isSource(DataFlow::Node node) { node instanceof SandboxedJexlSource } - - override predicate isSink(DataFlow::Node node) { + predicate isSink(DataFlow::Node node) { exists(MethodAccess ma, Method m | m instanceof CreateJexlScriptMethod or m instanceof CreateJexlExpressionMethod or @@ -121,11 +140,13 @@ private class SandboxedJexlFlowConfig extends DataFlow2::Configuration { ) } - override predicate isAdditionalFlowStep(DataFlow::Node fromNode, DataFlow::Node toNode) { + predicate isAdditionalFlowStep(DataFlow::Node fromNode, DataFlow::Node toNode) { createJexlEngineStep(fromNode, toNode) } } +private module SandboxedJexlFlow = DataFlow::Make<SandboxedJexlFlowConfig>; + /** * Defines a data flow source for JEXL engines configured with a sandbox. */ diff --git a/java/ql/src/Security/CWE/CWE-094/JexlInjection.ql b/java/ql/src/Security/CWE/CWE-094/JexlInjection.ql index 3e3cd793c05..d2ca8a2a8d9 100644 --- a/java/ql/src/Security/CWE/CWE-094/JexlInjection.ql +++ b/java/ql/src/Security/CWE/CWE-094/JexlInjection.ql @@ -13,9 +13,9 @@ import java import semmle.code.java.security.JexlInjectionQuery -import DataFlow::PathGraph +import JexlInjectionFlow::PathGraph -from DataFlow::PathNode source, DataFlow::PathNode sink, JexlInjectionConfig conf -where conf.hasFlowPath(source, sink) +from JexlInjectionFlow::PathNode source, JexlInjectionFlow::PathNode sink +where JexlInjectionFlow::hasFlowPath(source, sink) select sink.getNode(), source, sink, "JEXL expression depends on a $@.", source.getNode(), "user-provided value" diff --git a/java/ql/test/query-tests/security/CWE-094/JexlInjectionTest.ql b/java/ql/test/query-tests/security/CWE-094/JexlInjectionTest.ql index fa69c303211..729cc69cf7d 100644 --- a/java/ql/test/query-tests/security/CWE-094/JexlInjectionTest.ql +++ b/java/ql/test/query-tests/security/CWE-094/JexlInjectionTest.ql @@ -9,7 +9,7 @@ class JexlInjectionTest extends InlineExpectationsTest { override predicate hasActualResult(Location location, string element, string tag, string value) { tag = "hasJexlInjection" and - exists(DataFlow::Node sink, JexlInjectionConfig conf | conf.hasFlowTo(sink) | + exists(DataFlow::Node sink | JexlInjectionFlow::hasFlowTo(sink) | sink.getLocation() = location and element = sink.toString() and value = "" From 423ab1d9cf0368b290ad72bf788b9bcb899e2327 Mon Sep 17 00:00:00 2001 From: Ed Minnix <egregius313@github.com> Date: Tue, 21 Mar 2023 17:42:19 -0400 Subject: [PATCH 461/631] Refactor JndiInjection --- .../code/java/security/JndiInjectionQuery.qll | 38 ++++++++++++++----- .../src/Security/CWE/CWE-074/JndiInjection.ql | 6 +-- .../security/CWE-074/JndiInjectionTest.ql | 2 +- 3 files changed, 33 insertions(+), 13 deletions(-) diff --git a/java/ql/lib/semmle/code/java/security/JndiInjectionQuery.qll b/java/ql/lib/semmle/code/java/security/JndiInjectionQuery.qll index 970b8a65cef..c870ed4f470 100644 --- a/java/ql/lib/semmle/code/java/security/JndiInjectionQuery.qll +++ b/java/ql/lib/semmle/code/java/security/JndiInjectionQuery.qll @@ -7,9 +7,11 @@ import semmle.code.java.frameworks.SpringLdap import semmle.code.java.security.JndiInjection /** + * DEPRECATED: Use `JndiInjectionFlow` instead. + * * A taint-tracking configuration for unvalidated user input that is used in JNDI lookup. */ -class JndiInjectionFlowConfig extends TaintTracking::Configuration { +deprecated class JndiInjectionFlowConfig extends TaintTracking::Configuration { JndiInjectionFlowConfig() { this = "JndiInjectionFlowConfig" } override predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource } @@ -27,14 +29,32 @@ class JndiInjectionFlowConfig extends TaintTracking::Configuration { } } +/** + * A taint-tracking configuration for unvalidated user input that is used in JNDI lookup. + */ +private module JndiInjectionFlowConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource } + + predicate isSink(DataFlow::Node sink) { sink instanceof JndiInjectionSink } + + predicate isBarrier(DataFlow::Node node) { + node.getType() instanceof PrimitiveType or node.getType() instanceof BoxedType + } + + predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) { + any(JndiInjectionAdditionalTaintStep c).step(node1, node2) + } +} + +/** Tracks flow of unvalidated user input that is used in JNDI lookup */ +module JndiInjectionFlow = TaintTracking::Make<JndiInjectionFlowConfig>; + /** * A method that does a JNDI lookup when it receives a `SearchControls` argument with `setReturningObjFlag` = `true` */ private class UnsafeSearchControlsSink extends JndiInjectionSink { UnsafeSearchControlsSink() { - exists(UnsafeSearchControlsConf conf, MethodAccess ma | - conf.hasFlowTo(DataFlow::exprNode(ma.getAnArgument())) - | + exists(MethodAccess ma | UnsafeSearchControlsFlow::hasFlowToExpr(ma.getAnArgument()) | this.asExpr() = ma.getArgument(0) ) } @@ -44,14 +64,14 @@ private class UnsafeSearchControlsSink extends JndiInjectionSink { * Find flows between a `SearchControls` object with `setReturningObjFlag` = `true` * and an argument of an `LdapOperations.search` or `DirContext.search` call. */ -private class UnsafeSearchControlsConf extends DataFlow2::Configuration { - UnsafeSearchControlsConf() { this = "UnsafeSearchControlsConf" } +private module UnsafeSearchControlsConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node source) { source instanceof UnsafeSearchControls } - override predicate isSource(DataFlow::Node source) { source instanceof UnsafeSearchControls } - - override predicate isSink(DataFlow::Node sink) { sink instanceof UnsafeSearchControlsArgument } + predicate isSink(DataFlow::Node sink) { sink instanceof UnsafeSearchControlsArgument } } +private module UnsafeSearchControlsFlow = DataFlow::Make<UnsafeSearchControlsConfig>; + /** * An argument of type `SearchControls` of an `LdapOperations.search` or `DirContext.search` call. */ diff --git a/java/ql/src/Security/CWE/CWE-074/JndiInjection.ql b/java/ql/src/Security/CWE/CWE-074/JndiInjection.ql index 8a1438eccaf..7e22c4205d1 100644 --- a/java/ql/src/Security/CWE/CWE-074/JndiInjection.ql +++ b/java/ql/src/Security/CWE/CWE-074/JndiInjection.ql @@ -13,9 +13,9 @@ import java import semmle.code.java.security.JndiInjectionQuery -import DataFlow::PathGraph +import JndiInjectionFlow::PathGraph -from DataFlow::PathNode source, DataFlow::PathNode sink, JndiInjectionFlowConfig conf -where conf.hasFlowPath(source, sink) +from JndiInjectionFlow::PathNode source, JndiInjectionFlow::PathNode sink +where JndiInjectionFlow::hasFlowPath(source, sink) select sink.getNode(), source, sink, "JNDI lookup might include name from $@.", source.getNode(), "this user input" diff --git a/java/ql/test/query-tests/security/CWE-074/JndiInjectionTest.ql b/java/ql/test/query-tests/security/CWE-074/JndiInjectionTest.ql index fcad7bff3a4..e6824300b86 100644 --- a/java/ql/test/query-tests/security/CWE-074/JndiInjectionTest.ql +++ b/java/ql/test/query-tests/security/CWE-074/JndiInjectionTest.ql @@ -9,7 +9,7 @@ class HasJndiInjectionTest extends InlineExpectationsTest { override predicate hasActualResult(Location location, string element, string tag, string value) { tag = "hasJndiInjection" and - exists(DataFlow::Node sink, JndiInjectionFlowConfig conf | conf.hasFlowTo(sink) | + exists(DataFlow::Node sink | JndiInjectionFlow::hasFlowTo(sink) | sink.getLocation() = location and element = sink.toString() and value = "" From 3116e306b16ff5641f0804a0f315b236631b0c30 Mon Sep 17 00:00:00 2001 From: Ed Minnix <egregius313@github.com> Date: Tue, 21 Mar 2023 17:53:12 -0400 Subject: [PATCH 462/631] Refactor MvelInjection --- .../code/java/security/MvelInjectionQuery.qll | 23 ++++++++++++++++++- .../src/Security/CWE/CWE-094/MvelInjection.ql | 6 ++--- .../security/CWE-094/MvelInjectionTest.ql | 2 +- 3 files changed, 26 insertions(+), 5 deletions(-) diff --git a/java/ql/lib/semmle/code/java/security/MvelInjectionQuery.qll b/java/ql/lib/semmle/code/java/security/MvelInjectionQuery.qll index 332ea387e6b..5d3befbd81c 100644 --- a/java/ql/lib/semmle/code/java/security/MvelInjectionQuery.qll +++ b/java/ql/lib/semmle/code/java/security/MvelInjectionQuery.qll @@ -6,10 +6,12 @@ import semmle.code.java.dataflow.TaintTracking import semmle.code.java.security.MvelInjection /** + * DEPRECATED: Use `MvelInjectionFlow` instead. + * * A taint-tracking configuration for unsafe user input * that is used to construct and evaluate a MVEL expression. */ -class MvelInjectionFlowConfig extends TaintTracking::Configuration { +deprecated class MvelInjectionFlowConfig extends TaintTracking::Configuration { MvelInjectionFlowConfig() { this = "MvelInjectionFlowConfig" } override predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource } @@ -24,3 +26,22 @@ class MvelInjectionFlowConfig extends TaintTracking::Configuration { any(MvelInjectionAdditionalTaintStep c).step(node1, node2) } } + +/** + * A taint-tracking configuration for unsafe user input + * that is used to construct and evaluate a MVEL expression. + */ +private module MvelInjectionFlowConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource } + + predicate isSink(DataFlow::Node sink) { sink instanceof MvelEvaluationSink } + + predicate isBarrier(DataFlow::Node sanitizer) { sanitizer instanceof MvelInjectionSanitizer } + + predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) { + any(MvelInjectionAdditionalTaintStep c).step(node1, node2) + } +} + +/** Tracks flow of unsafe user input that is used to construct and evaluate a MVEL expression. */ +module MvelInjectionFlow = TaintTracking::Make<MvelInjectionFlowConfig>; diff --git a/java/ql/src/Security/CWE/CWE-094/MvelInjection.ql b/java/ql/src/Security/CWE/CWE-094/MvelInjection.ql index af623ac6ed9..e10ecf1bf21 100644 --- a/java/ql/src/Security/CWE/CWE-094/MvelInjection.ql +++ b/java/ql/src/Security/CWE/CWE-094/MvelInjection.ql @@ -13,9 +13,9 @@ import java import semmle.code.java.security.MvelInjectionQuery -import DataFlow::PathGraph +import MvelInjectionFlow::PathGraph -from DataFlow::PathNode source, DataFlow::PathNode sink, MvelInjectionFlowConfig conf -where conf.hasFlowPath(source, sink) +from MvelInjectionFlow::PathNode source, MvelInjectionFlow::PathNode sink +where MvelInjectionFlow::hasFlowPath(source, sink) select sink.getNode(), source, sink, "MVEL expression depends on a $@.", source.getNode(), "user-provided value" diff --git a/java/ql/test/query-tests/security/CWE-094/MvelInjectionTest.ql b/java/ql/test/query-tests/security/CWE-094/MvelInjectionTest.ql index 1a228f99e89..b3ffdc6d5ca 100644 --- a/java/ql/test/query-tests/security/CWE-094/MvelInjectionTest.ql +++ b/java/ql/test/query-tests/security/CWE-094/MvelInjectionTest.ql @@ -11,7 +11,7 @@ class HasMvelInjectionTest extends InlineExpectationsTest { override predicate hasActualResult(Location location, string element, string tag, string value) { tag = "hasMvelInjection" and - exists(DataFlow::Node sink, MvelInjectionFlowConfig conf | conf.hasFlowTo(sink) | + exists(DataFlow::Node sink | MvelInjectionFlow::hasFlowTo(sink) | sink.getLocation() = location and element = sink.toString() and value = "" From 7e1c42442a9143f2ee75bba44574045ad8b47512 Mon Sep 17 00:00:00 2001 From: Ed Minnix <egregius313@github.com> Date: Tue, 21 Mar 2023 18:02:19 -0400 Subject: [PATCH 463/631] Refactor OgnlInjection --- .../code/java/security/OgnlInjectionQuery.qll | 24 ++++++++++++++++++- .../src/Security/CWE/CWE-917/OgnlInjection.ql | 6 ++--- .../security/CWE-917/OgnlInjectionTest.ql | 2 +- 3 files changed, 27 insertions(+), 5 deletions(-) diff --git a/java/ql/lib/semmle/code/java/security/OgnlInjectionQuery.qll b/java/ql/lib/semmle/code/java/security/OgnlInjectionQuery.qll index 46a886ed65c..c0d14922119 100644 --- a/java/ql/lib/semmle/code/java/security/OgnlInjectionQuery.qll +++ b/java/ql/lib/semmle/code/java/security/OgnlInjectionQuery.qll @@ -5,9 +5,11 @@ import semmle.code.java.dataflow.FlowSources import semmle.code.java.security.OgnlInjection /** + * DEPRECATED: Use `OgnlInjectionFlow` instead. + * * A taint-tracking configuration for unvalidated user input that is used in OGNL EL evaluation. */ -class OgnlInjectionFlowConfig extends TaintTracking::Configuration { +deprecated class OgnlInjectionFlowConfig extends TaintTracking::Configuration { OgnlInjectionFlowConfig() { this = "OgnlInjectionFlowConfig" } override predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource } @@ -22,3 +24,23 @@ class OgnlInjectionFlowConfig extends TaintTracking::Configuration { any(OgnlInjectionAdditionalTaintStep c).step(node1, node2) } } + +/** + * A taint-tracking configuration for unvalidated user input that is used in OGNL EL evaluation. + */ +private module OgnlInjectionFlowConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource } + + predicate isSink(DataFlow::Node sink) { sink instanceof OgnlInjectionSink } + + predicate isBarrier(DataFlow::Node node) { + node.getType() instanceof PrimitiveType or node.getType() instanceof BoxedType + } + + predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) { + any(OgnlInjectionAdditionalTaintStep c).step(node1, node2) + } +} + +/** Tracks flow of unvalidated user input that is used in OGNL EL evaluation. */ +module OgnlInjectionFlow = TaintTracking::Make<OgnlInjectionFlowConfig>; diff --git a/java/ql/src/Security/CWE/CWE-917/OgnlInjection.ql b/java/ql/src/Security/CWE/CWE-917/OgnlInjection.ql index 06fc54ab22a..7a033b51ba2 100644 --- a/java/ql/src/Security/CWE/CWE-917/OgnlInjection.ql +++ b/java/ql/src/Security/CWE/CWE-917/OgnlInjection.ql @@ -13,9 +13,9 @@ import java import semmle.code.java.security.OgnlInjectionQuery -import DataFlow::PathGraph +import OgnlInjectionFlow::PathGraph -from DataFlow::PathNode source, DataFlow::PathNode sink, OgnlInjectionFlowConfig conf -where conf.hasFlowPath(source, sink) +from OgnlInjectionFlow::PathNode source, OgnlInjectionFlow::PathNode sink +where OgnlInjectionFlow::hasFlowPath(source, sink) select sink.getNode(), source, sink, "OGNL Expression Language statement depends on a $@.", source.getNode(), "user-provided value" diff --git a/java/ql/test/query-tests/security/CWE-917/OgnlInjectionTest.ql b/java/ql/test/query-tests/security/CWE-917/OgnlInjectionTest.ql index efbf1508fe4..cc3482dfe75 100644 --- a/java/ql/test/query-tests/security/CWE-917/OgnlInjectionTest.ql +++ b/java/ql/test/query-tests/security/CWE-917/OgnlInjectionTest.ql @@ -9,7 +9,7 @@ class OgnlInjectionTest extends InlineExpectationsTest { override predicate hasActualResult(Location location, string element, string tag, string value) { tag = "hasOgnlInjection" and - exists(DataFlow::Node sink, OgnlInjectionFlowConfig conf | conf.hasFlowTo(sink) | + exists(DataFlow::Node sink | OgnlInjectionFlow::hasFlowTo(sink) | sink.getLocation() = location and element = sink.toString() and value = "" From 787b73317dd268d176fe17b718406378d5e38ad4 Mon Sep 17 00:00:00 2001 From: Ed Minnix <egregius313@github.com> Date: Tue, 21 Mar 2023 18:09:12 -0400 Subject: [PATCH 464/631] Refactor TemplateInjection --- .../java/security/TemplateInjectionQuery.qll | 40 ++++++++++++++++++- .../Security/CWE/CWE-094/TemplateInjection.ql | 6 +-- .../security/CWE-094/TemplateInjectionTest.ql | 2 +- 3 files changed, 42 insertions(+), 6 deletions(-) diff --git a/java/ql/lib/semmle/code/java/security/TemplateInjectionQuery.qll b/java/ql/lib/semmle/code/java/security/TemplateInjectionQuery.qll index e8ed6f5aea9..e4a7a8250d7 100644 --- a/java/ql/lib/semmle/code/java/security/TemplateInjectionQuery.qll +++ b/java/ql/lib/semmle/code/java/security/TemplateInjectionQuery.qll @@ -5,8 +5,12 @@ import semmle.code.java.dataflow.TaintTracking import semmle.code.java.dataflow.FlowSources import semmle.code.java.security.TemplateInjection -/** A taint tracking configuration to reason about server-side template injection (SST) vulnerabilities */ -class TemplateInjectionFlowConfig extends TaintTracking::Configuration { +/** + * DEPRECATED: Use `TemplateInjectionFlow` instead. + * + * A taint tracking configuration to reason about server-side template injection (SST) vulnerabilities + */ +deprecated class TemplateInjectionFlowConfig extends TaintTracking::Configuration { TemplateInjectionFlowConfig() { this = "TemplateInjectionFlowConfig" } override predicate isSource(DataFlow::Node source, DataFlow::FlowState state) { @@ -36,3 +40,35 @@ class TemplateInjectionFlowConfig extends TaintTracking::Configuration { any(TemplateInjectionAdditionalTaintStep a).isAdditionalTaintStep(node1, state1, node2, state2) } } + +/** A taint tracking configuration to reason about server-side template injection (SST) vulnerabilities */ +private module TemplateInjectionFlowConfig implements DataFlow::StateConfigSig { + class FlowState = DataFlow::FlowState; + + predicate isSource(DataFlow::Node source, FlowState state) { + source.(TemplateInjectionSource).hasState(state) + } + + predicate isSink(DataFlow::Node sink, FlowState state) { + sink.(TemplateInjectionSink).hasState(state) + } + + predicate isBarrier(DataFlow::Node sanitizer) { sanitizer instanceof TemplateInjectionSanitizer } + + predicate isBarrier(DataFlow::Node sanitizer, FlowState state) { + sanitizer.(TemplateInjectionSanitizerWithState).hasState(state) + } + + predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) { + any(TemplateInjectionAdditionalTaintStep a).isAdditionalTaintStep(node1, node2) + } + + predicate isAdditionalFlowStep( + DataFlow::Node node1, FlowState state1, DataFlow::Node node2, FlowState state2 + ) { + any(TemplateInjectionAdditionalTaintStep a).isAdditionalTaintStep(node1, state1, node2, state2) + } +} + +/** Tracks server-side template injection (SST) vulnerabilities */ +module TemplateInjectionFlow = TaintTracking::MakeWithState<TemplateInjectionFlowConfig>; diff --git a/java/ql/src/Security/CWE/CWE-094/TemplateInjection.ql b/java/ql/src/Security/CWE/CWE-094/TemplateInjection.ql index 8085c3ec314..279881f95a0 100644 --- a/java/ql/src/Security/CWE/CWE-094/TemplateInjection.ql +++ b/java/ql/src/Security/CWE/CWE-094/TemplateInjection.ql @@ -13,9 +13,9 @@ import java import semmle.code.java.security.TemplateInjectionQuery -import DataFlow::PathGraph +import TemplateInjectionFlow::PathGraph -from TemplateInjectionFlowConfig config, DataFlow::PathNode source, DataFlow::PathNode sink -where config.hasFlowPath(source, sink) +from TemplateInjectionFlow::PathNode source, TemplateInjectionFlow::PathNode sink +where TemplateInjectionFlow::hasFlowPath(source, sink) select sink.getNode(), source, sink, "Template, which may contain code, depends on a $@.", source.getNode(), "user-provided value" diff --git a/java/ql/test/query-tests/security/CWE-094/TemplateInjectionTest.ql b/java/ql/test/query-tests/security/CWE-094/TemplateInjectionTest.ql index b509cb46b03..cc834b07a6b 100644 --- a/java/ql/test/query-tests/security/CWE-094/TemplateInjectionTest.ql +++ b/java/ql/test/query-tests/security/CWE-094/TemplateInjectionTest.ql @@ -9,7 +9,7 @@ class TemplateInjectionTest extends InlineExpectationsTest { override predicate hasActualResult(Location location, string element, string tag, string value) { tag = "hasTemplateInjection" and - exists(DataFlow::Node sink, TemplateInjectionFlowConfig conf | conf.hasFlowTo(sink) | + exists(DataFlow::Node sink | TemplateInjectionFlow::hasFlowTo(sink) | sink.getLocation() = location and element = sink.toString() and value = "" From fec80973a9425632b51a46617b74628677af0da2 Mon Sep 17 00:00:00 2001 From: Ed Minnix <egregius313@github.com> Date: Tue, 21 Mar 2023 20:44:47 -0400 Subject: [PATCH 465/631] Refactor SpelInjectionQuery --- .../code/java/security/SpelInjectionQuery.qll | 37 ++++++++++++++----- .../src/Security/CWE/CWE-094/SpelInjection.ql | 6 +-- .../security/CWE-094/SpelInjectionTest.ql | 2 +- 3 files changed, 31 insertions(+), 14 deletions(-) diff --git a/java/ql/lib/semmle/code/java/security/SpelInjectionQuery.qll b/java/ql/lib/semmle/code/java/security/SpelInjectionQuery.qll index 0d9cdc853bb..ed4fac7c06f 100644 --- a/java/ql/lib/semmle/code/java/security/SpelInjectionQuery.qll +++ b/java/ql/lib/semmle/code/java/security/SpelInjectionQuery.qll @@ -7,10 +7,12 @@ private import semmle.code.java.frameworks.spring.SpringExpression private import semmle.code.java.security.SpelInjection /** + * DEPRECATED: Use `SpelInjectionFlow` instead. + * * A taint-tracking configuration for unsafe user input * that is used to construct and evaluate a SpEL expression. */ -class SpelInjectionConfig extends TaintTracking::Configuration { +deprecated class SpelInjectionConfig extends TaintTracking::Configuration { SpelInjectionConfig() { this = "SpelInjectionConfig" } override predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource } @@ -22,15 +24,30 @@ class SpelInjectionConfig extends TaintTracking::Configuration { } } +/** + * A taint-tracking configuration for unsafe user input + * that is used to construct and evaluate a SpEL expression. + */ +private module SpelInjectionConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource } + + predicate isSink(DataFlow::Node sink) { sink instanceof SpelExpressionEvaluationSink } + + predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) { + any(SpelExpressionInjectionAdditionalTaintStep c).step(node1, node2) + } +} + +/** Tracks flow of unsafe user input that is used to construct and evaluate a SpEL expression. */ +module SpelInjectionFlow = TaintTracking::Make<SpelInjectionConfig>; + /** Default sink for SpEL injection vulnerabilities. */ private class DefaultSpelExpressionEvaluationSink extends SpelExpressionEvaluationSink { DefaultSpelExpressionEvaluationSink() { exists(MethodAccess ma | ma.getMethod() instanceof ExpressionEvaluationMethod and ma.getQualifier() = this.asExpr() and - not exists(SafeEvaluationContextFlowConfig config | - config.hasFlowTo(DataFlow::exprNode(ma.getArgument(0))) - ) + not SafeEvaluationContextFlow::hasFlowToExpr(ma.getArgument(0)) ) } } @@ -38,21 +55,21 @@ private class DefaultSpelExpressionEvaluationSink extends SpelExpressionEvaluati /** * A configuration for safe evaluation context that may be used in expression evaluation. */ -private class SafeEvaluationContextFlowConfig extends DataFlow2::Configuration { - SafeEvaluationContextFlowConfig() { this = "SpelInjection::SafeEvaluationContextFlowConfig" } +private module SafeEvaluationContextFlowConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node source) { source instanceof SafeContextSource } - override predicate isSource(DataFlow::Node source) { source instanceof SafeContextSource } - - override predicate isSink(DataFlow::Node sink) { + predicate isSink(DataFlow::Node sink) { exists(MethodAccess ma | ma.getMethod() instanceof ExpressionEvaluationMethod and ma.getArgument(0) = sink.asExpr() ) } - override int fieldFlowBranchLimit() { result = 0 } + int fieldFlowBranchLimit() { result = 0 } } +private module SafeEvaluationContextFlow = DataFlow::Make<SafeEvaluationContextFlowConfig>; + /** * A `ContextSource` that is safe from SpEL injection. */ diff --git a/java/ql/src/Security/CWE/CWE-094/SpelInjection.ql b/java/ql/src/Security/CWE/CWE-094/SpelInjection.ql index d6cc8f33c82..6963dfb22a6 100644 --- a/java/ql/src/Security/CWE/CWE-094/SpelInjection.ql +++ b/java/ql/src/Security/CWE/CWE-094/SpelInjection.ql @@ -14,9 +14,9 @@ import java import semmle.code.java.security.SpelInjectionQuery import semmle.code.java.dataflow.DataFlow -import DataFlow::PathGraph +import SpelInjectionFlow::PathGraph -from DataFlow::PathNode source, DataFlow::PathNode sink, SpelInjectionConfig conf -where conf.hasFlowPath(source, sink) +from SpelInjectionFlow::PathNode source, SpelInjectionFlow::PathNode sink +where SpelInjectionFlow::hasFlowPath(source, sink) select sink.getNode(), source, sink, "SpEL expression depends on a $@.", source.getNode(), "user-provided value" diff --git a/java/ql/test/query-tests/security/CWE-094/SpelInjectionTest.ql b/java/ql/test/query-tests/security/CWE-094/SpelInjectionTest.ql index cf89a1673ba..92bd3b2114e 100644 --- a/java/ql/test/query-tests/security/CWE-094/SpelInjectionTest.ql +++ b/java/ql/test/query-tests/security/CWE-094/SpelInjectionTest.ql @@ -11,7 +11,7 @@ class HasSpelInjectionTest extends InlineExpectationsTest { override predicate hasActualResult(Location location, string element, string tag, string value) { tag = "hasSpelInjection" and - exists(DataFlow::Node sink, SpelInjectionConfig conf | conf.hasFlowTo(sink) | + exists(DataFlow::Node sink | SpelInjectionFlow::hasFlowTo(sink) | sink.getLocation() = location and element = sink.toString() and value = "" From bf5f82bb785dcbcc3ca2e52fa6775a19a2e90c60 Mon Sep 17 00:00:00 2001 From: Ed Minnix <egregius313@github.com> Date: Tue, 21 Mar 2023 20:58:39 -0400 Subject: [PATCH 466/631] Refactor SqlInjectionQuery --- .../code/java/security/SqlInjectionQuery.qll | 30 +++++++++++++++++-- .../ql/src/Security/CWE/CWE-089/SqlTainted.ql | 5 ++-- 2 files changed, 30 insertions(+), 5 deletions(-) diff --git a/java/ql/lib/semmle/code/java/security/SqlInjectionQuery.qll b/java/ql/lib/semmle/code/java/security/SqlInjectionQuery.qll index 245c9146b2d..88e811f16be 100644 --- a/java/ql/lib/semmle/code/java/security/SqlInjectionQuery.qll +++ b/java/ql/lib/semmle/code/java/security/SqlInjectionQuery.qll @@ -11,9 +11,11 @@ import semmle.code.java.dataflow.FlowSources import semmle.code.java.security.QueryInjection /** + * DEPRECATED: Use `QueryInjectionFlow` instead. + * * A taint-tracking configuration for unvalidated user input that is used in SQL queries. */ -class QueryInjectionFlowConfig extends TaintTracking::Configuration { +deprecated class QueryInjectionFlowConfig extends TaintTracking::Configuration { QueryInjectionFlowConfig() { this = "SqlInjectionLib::QueryInjectionFlowConfig" } override predicate isSource(DataFlow::Node src) { src instanceof RemoteFlowSource } @@ -31,12 +33,34 @@ class QueryInjectionFlowConfig extends TaintTracking::Configuration { } } +/** + * A taint-tracking configuration for unvalidated user input that is used in SQL queries. + */ +private module QueryInjectionFlowConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node src) { src instanceof RemoteFlowSource } + + predicate isSink(DataFlow::Node sink) { sink instanceof QueryInjectionSink } + + predicate isBarrier(DataFlow::Node node) { + node.getType() instanceof PrimitiveType or + node.getType() instanceof BoxedType or + node.getType() instanceof NumberType + } + + predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) { + any(AdditionalQueryInjectionTaintStep s).step(node1, node2) + } +} + +/** Tracks flow of unvalidated user input that is used in SQL queries. */ +module QueryInjectionFlow = TaintTracking::Make<QueryInjectionFlowConfig>; + /** * Implementation of `SqlTainted.ql`. This is extracted to a QLL so that it * can be excluded from `SqlConcatenated.ql` to avoid overlapping results. */ predicate queryTaintedBy( - QueryInjectionSink query, DataFlow::PathNode source, DataFlow::PathNode sink + QueryInjectionSink query, QueryInjectionFlow::PathNode source, QueryInjectionFlow::PathNode sink ) { - exists(QueryInjectionFlowConfig conf | conf.hasFlowPath(source, sink) and sink.getNode() = query) + QueryInjectionFlow::hasFlowPath(source, sink) and sink.getNode() = query } diff --git a/java/ql/src/Security/CWE/CWE-089/SqlTainted.ql b/java/ql/src/Security/CWE/CWE-089/SqlTainted.ql index 963a927bf93..628d469bac7 100644 --- a/java/ql/src/Security/CWE/CWE-089/SqlTainted.ql +++ b/java/ql/src/Security/CWE/CWE-089/SqlTainted.ql @@ -15,8 +15,9 @@ import java import semmle.code.java.dataflow.FlowSources import semmle.code.java.security.SqlInjectionQuery -import DataFlow::PathGraph +import QueryInjectionFlow::PathGraph -from QueryInjectionSink query, DataFlow::PathNode source, DataFlow::PathNode sink +from + QueryInjectionSink query, QueryInjectionFlow::PathNode source, QueryInjectionFlow::PathNode sink where queryTaintedBy(query, source, sink) select query, source, sink, "This query depends on a $@.", source.getNode(), "user-provided value" From f6b8d897560d0e572e55586973aa1293c173bbc3 Mon Sep 17 00:00:00 2001 From: Ed Minnix <egregius313@github.com> Date: Mon, 20 Mar 2023 12:24:57 -0400 Subject: [PATCH 467/631] Refactor GroovyInjectionQuery --- .../java/security/GroovyInjectionQuery.qll | 24 ++++++++++++++++++- .../Security/CWE/CWE-094/GroovyInjection.ql | 6 ++--- .../security/CWE-094/GroovyInjectionTest.ql | 2 +- 3 files changed, 27 insertions(+), 5 deletions(-) diff --git a/java/ql/lib/semmle/code/java/security/GroovyInjectionQuery.qll b/java/ql/lib/semmle/code/java/security/GroovyInjectionQuery.qll index d364b8bd834..f5ecf50fa2f 100644 --- a/java/ql/lib/semmle/code/java/security/GroovyInjectionQuery.qll +++ b/java/ql/lib/semmle/code/java/security/GroovyInjectionQuery.qll @@ -6,10 +6,12 @@ import semmle.code.java.dataflow.TaintTracking import semmle.code.java.security.GroovyInjection /** + * DEPRECATED: Use `GroovyInjectionFlow` instead. + * * A taint-tracking configuration for unsafe user input * that is used to evaluate a Groovy expression. */ -class GroovyInjectionConfig extends TaintTracking::Configuration { +deprecated class GroovyInjectionConfig extends TaintTracking::Configuration { GroovyInjectionConfig() { this = "GroovyInjectionConfig" } override predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource } @@ -20,3 +22,23 @@ class GroovyInjectionConfig extends TaintTracking::Configuration { any(GroovyInjectionAdditionalTaintStep c).step(fromNode, toNode) } } + +/** + * A taint-tracking configuration for unsafe user input + * that is used to evaluate a Groovy expression. + */ +module GroovyInjectionConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource } + + predicate isSink(DataFlow::Node sink) { sink instanceof GroovyInjectionSink } + + predicate isAdditionalFlowStep(DataFlow::Node fromNode, DataFlow::Node toNode) { + any(GroovyInjectionAdditionalTaintStep c).step(fromNode, toNode) + } +} + +/** + * Detect taint flow of unsafe user input + * that is used to evaluate a Groovy expression. + */ +module GroovyInjectionFlow = TaintTracking::Make<GroovyInjectionConfig>; diff --git a/java/ql/src/Security/CWE/CWE-094/GroovyInjection.ql b/java/ql/src/Security/CWE/CWE-094/GroovyInjection.ql index f1febd7aa2c..1f077d36f3c 100644 --- a/java/ql/src/Security/CWE/CWE-094/GroovyInjection.ql +++ b/java/ql/src/Security/CWE/CWE-094/GroovyInjection.ql @@ -13,9 +13,9 @@ import java import semmle.code.java.security.GroovyInjectionQuery -import DataFlow::PathGraph +import GroovyInjectionFlow::PathGraph -from DataFlow::PathNode source, DataFlow::PathNode sink, GroovyInjectionConfig conf -where conf.hasFlowPath(source, sink) +from GroovyInjectionFlow::PathNode source, GroovyInjectionFlow::PathNode sink +where GroovyInjectionFlow::hasFlowPath(source, sink) select sink.getNode(), source, sink, "Groovy script depends on a $@.", source.getNode(), "user-provided value" diff --git a/java/ql/test/query-tests/security/CWE-094/GroovyInjectionTest.ql b/java/ql/test/query-tests/security/CWE-094/GroovyInjectionTest.ql index 4abcbf497a1..3eb01533bdd 100644 --- a/java/ql/test/query-tests/security/CWE-094/GroovyInjectionTest.ql +++ b/java/ql/test/query-tests/security/CWE-094/GroovyInjectionTest.ql @@ -11,7 +11,7 @@ class HasGroovyInjectionTest extends InlineExpectationsTest { override predicate hasActualResult(Location location, string element, string tag, string value) { tag = "hasGroovyInjection" and - exists(DataFlow::Node sink, GroovyInjectionConfig conf | conf.hasFlowTo(sink) | + exists(DataFlow::Node sink | GroovyInjectionFlow::hasFlowTo(sink) | sink.getLocation() = location and element = sink.toString() and value = "" From 899200a9c982317dfc6bf08ff3b81ac4155db93f Mon Sep 17 00:00:00 2001 From: Ed Minnix <egregius313@github.com> Date: Wed, 22 Mar 2023 22:40:58 -0400 Subject: [PATCH 468/631] Remove unnecessary private markers --- java/ql/lib/semmle/code/java/security/JexlInjectionQuery.qll | 2 +- java/ql/lib/semmle/code/java/security/JndiInjectionQuery.qll | 2 +- java/ql/lib/semmle/code/java/security/MvelInjectionQuery.qll | 2 +- java/ql/lib/semmle/code/java/security/OgnlInjectionQuery.qll | 2 +- java/ql/lib/semmle/code/java/security/SpelInjectionQuery.qll | 2 +- java/ql/lib/semmle/code/java/security/SqlInjectionQuery.qll | 2 +- .../ql/lib/semmle/code/java/security/TemplateInjectionQuery.qll | 2 +- java/ql/lib/semmle/code/java/security/XsltInjectionQuery.qll | 2 +- .../semmle/code/java/security/regexp/RegexInjectionQuery.qll | 2 +- 9 files changed, 9 insertions(+), 9 deletions(-) diff --git a/java/ql/lib/semmle/code/java/security/JexlInjectionQuery.qll b/java/ql/lib/semmle/code/java/security/JexlInjectionQuery.qll index c2b2c799823..e0ce78574bc 100644 --- a/java/ql/lib/semmle/code/java/security/JexlInjectionQuery.qll +++ b/java/ql/lib/semmle/code/java/security/JexlInjectionQuery.qll @@ -62,7 +62,7 @@ deprecated class JexlInjectionConfig extends TaintTracking::Configuration { * that is used to construct and evaluate a JEXL expression. * It supports both JEXL 2 and 3. */ -private module JexlInjectionConfig implements DataFlow::ConfigSig { +module JexlInjectionConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource } predicate isSink(DataFlow::Node sink) { sink instanceof JexlEvaluationSink } diff --git a/java/ql/lib/semmle/code/java/security/JndiInjectionQuery.qll b/java/ql/lib/semmle/code/java/security/JndiInjectionQuery.qll index c870ed4f470..81a52bdeaeb 100644 --- a/java/ql/lib/semmle/code/java/security/JndiInjectionQuery.qll +++ b/java/ql/lib/semmle/code/java/security/JndiInjectionQuery.qll @@ -32,7 +32,7 @@ deprecated class JndiInjectionFlowConfig extends TaintTracking::Configuration { /** * A taint-tracking configuration for unvalidated user input that is used in JNDI lookup. */ -private module JndiInjectionFlowConfig implements DataFlow::ConfigSig { +module JndiInjectionFlowConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource } predicate isSink(DataFlow::Node sink) { sink instanceof JndiInjectionSink } diff --git a/java/ql/lib/semmle/code/java/security/MvelInjectionQuery.qll b/java/ql/lib/semmle/code/java/security/MvelInjectionQuery.qll index 5d3befbd81c..393ccd0f4f8 100644 --- a/java/ql/lib/semmle/code/java/security/MvelInjectionQuery.qll +++ b/java/ql/lib/semmle/code/java/security/MvelInjectionQuery.qll @@ -31,7 +31,7 @@ deprecated class MvelInjectionFlowConfig extends TaintTracking::Configuration { * A taint-tracking configuration for unsafe user input * that is used to construct and evaluate a MVEL expression. */ -private module MvelInjectionFlowConfig implements DataFlow::ConfigSig { +module MvelInjectionFlowConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource } predicate isSink(DataFlow::Node sink) { sink instanceof MvelEvaluationSink } diff --git a/java/ql/lib/semmle/code/java/security/OgnlInjectionQuery.qll b/java/ql/lib/semmle/code/java/security/OgnlInjectionQuery.qll index c0d14922119..4501b4fe0c3 100644 --- a/java/ql/lib/semmle/code/java/security/OgnlInjectionQuery.qll +++ b/java/ql/lib/semmle/code/java/security/OgnlInjectionQuery.qll @@ -28,7 +28,7 @@ deprecated class OgnlInjectionFlowConfig extends TaintTracking::Configuration { /** * A taint-tracking configuration for unvalidated user input that is used in OGNL EL evaluation. */ -private module OgnlInjectionFlowConfig implements DataFlow::ConfigSig { +module OgnlInjectionFlowConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource } predicate isSink(DataFlow::Node sink) { sink instanceof OgnlInjectionSink } diff --git a/java/ql/lib/semmle/code/java/security/SpelInjectionQuery.qll b/java/ql/lib/semmle/code/java/security/SpelInjectionQuery.qll index ed4fac7c06f..67e5f053f2d 100644 --- a/java/ql/lib/semmle/code/java/security/SpelInjectionQuery.qll +++ b/java/ql/lib/semmle/code/java/security/SpelInjectionQuery.qll @@ -28,7 +28,7 @@ deprecated class SpelInjectionConfig extends TaintTracking::Configuration { * A taint-tracking configuration for unsafe user input * that is used to construct and evaluate a SpEL expression. */ -private module SpelInjectionConfig implements DataFlow::ConfigSig { +module SpelInjectionConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource } predicate isSink(DataFlow::Node sink) { sink instanceof SpelExpressionEvaluationSink } diff --git a/java/ql/lib/semmle/code/java/security/SqlInjectionQuery.qll b/java/ql/lib/semmle/code/java/security/SqlInjectionQuery.qll index 88e811f16be..71cb56d79c1 100644 --- a/java/ql/lib/semmle/code/java/security/SqlInjectionQuery.qll +++ b/java/ql/lib/semmle/code/java/security/SqlInjectionQuery.qll @@ -36,7 +36,7 @@ deprecated class QueryInjectionFlowConfig extends TaintTracking::Configuration { /** * A taint-tracking configuration for unvalidated user input that is used in SQL queries. */ -private module QueryInjectionFlowConfig implements DataFlow::ConfigSig { +module QueryInjectionFlowConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node src) { src instanceof RemoteFlowSource } predicate isSink(DataFlow::Node sink) { sink instanceof QueryInjectionSink } diff --git a/java/ql/lib/semmle/code/java/security/TemplateInjectionQuery.qll b/java/ql/lib/semmle/code/java/security/TemplateInjectionQuery.qll index e4a7a8250d7..aee797046f7 100644 --- a/java/ql/lib/semmle/code/java/security/TemplateInjectionQuery.qll +++ b/java/ql/lib/semmle/code/java/security/TemplateInjectionQuery.qll @@ -42,7 +42,7 @@ deprecated class TemplateInjectionFlowConfig extends TaintTracking::Configuratio } /** A taint tracking configuration to reason about server-side template injection (SST) vulnerabilities */ -private module TemplateInjectionFlowConfig implements DataFlow::StateConfigSig { +module TemplateInjectionFlowConfig implements DataFlow::StateConfigSig { class FlowState = DataFlow::FlowState; predicate isSource(DataFlow::Node source, FlowState state) { diff --git a/java/ql/lib/semmle/code/java/security/XsltInjectionQuery.qll b/java/ql/lib/semmle/code/java/security/XsltInjectionQuery.qll index 8329fda0ca5..9aa9ca71613 100644 --- a/java/ql/lib/semmle/code/java/security/XsltInjectionQuery.qll +++ b/java/ql/lib/semmle/code/java/security/XsltInjectionQuery.qll @@ -30,7 +30,7 @@ deprecated class XsltInjectionFlowConfig extends TaintTracking::Configuration { /** * A taint-tracking configuration for unvalidated user input that is used in XSLT transformation. */ -private module XsltInjectionFlowConfig implements DataFlow::ConfigSig { +module XsltInjectionFlowConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource } predicate isSink(DataFlow::Node sink) { sink instanceof XsltInjectionSink } diff --git a/java/ql/lib/semmle/code/java/security/regexp/RegexInjectionQuery.qll b/java/ql/lib/semmle/code/java/security/regexp/RegexInjectionQuery.qll index 88115465629..d0a7bd7d7f3 100644 --- a/java/ql/lib/semmle/code/java/security/regexp/RegexInjectionQuery.qll +++ b/java/ql/lib/semmle/code/java/security/regexp/RegexInjectionQuery.qll @@ -23,7 +23,7 @@ deprecated class RegexInjectionConfiguration extends TaintTracking::Configuratio /** * A taint-tracking configuration for untrusted user input used to construct regular expressions. */ -private module RegexInjectionConfig implements DataFlow::ConfigSig { +module RegexInjectionConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource } predicate isSink(DataFlow::Node sink) { sink instanceof RegexInjectionSink } From c158f8331a785e702b3d899348f14114734751c1 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Fri, 24 Mar 2023 14:03:30 +0000 Subject: [PATCH 469/631] Swift: Fix regression. --- .../StringLengthConflationExtensions.qll | 25 +++++++++++++------ 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/swift/ql/lib/codeql/swift/security/StringLengthConflationExtensions.qll b/swift/ql/lib/codeql/swift/security/StringLengthConflationExtensions.qll index 966734e5fcf..c4ecebf8d0d 100644 --- a/swift/ql/lib/codeql/swift/security/StringLengthConflationExtensions.qll +++ b/swift/ql/lib/codeql/swift/security/StringLengthConflationExtensions.qll @@ -113,9 +113,7 @@ private class StringLengthConflationSources extends SourceModelCsv { override predicate row(string row) { row = [ - ";String;true;count;;;;string-length", ";String.UTF8View;true;count;;;;string-utf8-length", - ";String.UTF16View;true;count;;;;string-utf16-length", - ";NSString;true;length;;;;nsstring-length", + ";String;true;count;;;;string-length", ";NSString;true;length;;;;nsstring-length", ";NSMutableString;true;length;;;;nsstring-length", ] } @@ -128,12 +126,23 @@ private class ExtraStringLengthConflationSource extends StringLengthConflationSo StringType stringType; ExtraStringLengthConflationSource() { - exists(MemberRefExpr memberRef | - // result of a call to `String.unicodeScalars.count` - memberRef.getBase().getType().(NominalType).getName() = "String.UnicodeScalarView" and + exists(MemberRefExpr memberRef, string typeName | + ( + // result of a call to `String.utf8.count` + typeName = "String.UTF8View" and + stringType = "String.utf8" + or + // result of a call to `String.utf16.count` + typeName = "String.UTF16View" and + stringType = "String.utf16" + or + // result of a call to `String.unicodeScalars.count` + typeName = "String.UnicodeScalarView" and + stringType = "String.unicodeScalars" + ) and + memberRef.getBase().getType().(NominalType).getName() = typeName and memberRef.getMember().(VarDecl).getName() = "count" and - this.asExpr() = memberRef and - stringType = "String.unicodeScalars" + this.asExpr() = memberRef ) } From e7bad4cd90ffd4fb9beaf8e5330e8d51341c6378 Mon Sep 17 00:00:00 2001 From: Ed Minnix <egregius313@github.com> Date: Fri, 24 Mar 2023 10:04:46 -0400 Subject: [PATCH 470/631] Refactor to DataFlow::Global --- .../lib/semmle/code/java/security/GroovyInjectionQuery.qll | 2 +- .../ql/lib/semmle/code/java/security/JexlInjectionQuery.qll | 6 +++--- .../ql/lib/semmle/code/java/security/JndiInjectionQuery.qll | 6 +++--- .../ql/lib/semmle/code/java/security/MvelInjectionQuery.qll | 2 +- .../ql/lib/semmle/code/java/security/OgnlInjectionQuery.qll | 2 +- .../ql/lib/semmle/code/java/security/SpelInjectionQuery.qll | 6 +++--- java/ql/lib/semmle/code/java/security/SqlInjectionQuery.qll | 4 ++-- .../semmle/code/java/security/TemplateInjectionQuery.qll | 2 +- .../ql/lib/semmle/code/java/security/XsltInjectionQuery.qll | 6 +++--- .../code/java/security/regexp/RegexInjectionQuery.qll | 2 +- java/ql/src/Security/CWE/CWE-074/JndiInjection.ql | 2 +- java/ql/src/Security/CWE/CWE-074/XsltInjection.ql | 2 +- java/ql/src/Security/CWE/CWE-094/GroovyInjection.ql | 2 +- java/ql/src/Security/CWE/CWE-094/JexlInjection.ql | 2 +- java/ql/src/Security/CWE/CWE-094/MvelInjection.ql | 2 +- java/ql/src/Security/CWE/CWE-094/SpelInjection.ql | 2 +- java/ql/src/Security/CWE/CWE-094/TemplateInjection.ql | 2 +- java/ql/src/Security/CWE/CWE-730/RegexInjection.ql | 2 +- java/ql/src/Security/CWE/CWE-917/OgnlInjection.ql | 2 +- .../test/query-tests/security/CWE-074/JndiInjectionTest.ql | 2 +- .../test/query-tests/security/CWE-074/XsltInjectionTest.ql | 2 +- .../query-tests/security/CWE-094/GroovyInjectionTest.ql | 2 +- .../test/query-tests/security/CWE-094/JexlInjectionTest.ql | 2 +- .../test/query-tests/security/CWE-094/MvelInjectionTest.ql | 2 +- .../test/query-tests/security/CWE-094/SpelInjectionTest.ql | 2 +- .../query-tests/security/CWE-094/TemplateInjectionTest.ql | 2 +- .../test/query-tests/security/CWE-730/RegexInjectionTest.ql | 2 +- .../test/query-tests/security/CWE-917/OgnlInjectionTest.ql | 2 +- 28 files changed, 37 insertions(+), 37 deletions(-) diff --git a/java/ql/lib/semmle/code/java/security/GroovyInjectionQuery.qll b/java/ql/lib/semmle/code/java/security/GroovyInjectionQuery.qll index f5ecf50fa2f..1d3c55398a5 100644 --- a/java/ql/lib/semmle/code/java/security/GroovyInjectionQuery.qll +++ b/java/ql/lib/semmle/code/java/security/GroovyInjectionQuery.qll @@ -41,4 +41,4 @@ module GroovyInjectionConfig implements DataFlow::ConfigSig { * Detect taint flow of unsafe user input * that is used to evaluate a Groovy expression. */ -module GroovyInjectionFlow = TaintTracking::Make<GroovyInjectionConfig>; +module GroovyInjectionFlow = TaintTracking::Global<GroovyInjectionConfig>; diff --git a/java/ql/lib/semmle/code/java/security/JexlInjectionQuery.qll b/java/ql/lib/semmle/code/java/security/JexlInjectionQuery.qll index e0ce78574bc..4138b851e85 100644 --- a/java/ql/lib/semmle/code/java/security/JexlInjectionQuery.qll +++ b/java/ql/lib/semmle/code/java/security/JexlInjectionQuery.qll @@ -76,7 +76,7 @@ module JexlInjectionConfig implements DataFlow::ConfigSig { * Tracks unsafe user input that is used to construct and evaluate a JEXL expression. * It supports both JEXL 2 and 3. */ -module JexlInjectionFlow = TaintTracking::Make<JexlInjectionConfig>; +module JexlInjectionFlow = TaintTracking::Global<JexlInjectionConfig>; /** * Holds if `n1` to `n2` is a dataflow step that creates a JEXL script using an unsafe engine @@ -122,7 +122,7 @@ private predicate createJexlTemplateStep(DataFlow::Node n1, DataFlow::Node n2) { /** * Holds if `expr` is a JEXL engine that is configured with a sandbox. */ -private predicate isSafeEngine(Expr expr) { SandboxedJexlFlow::hasFlowToExpr(expr) } +private predicate isSafeEngine(Expr expr) { SandboxedJexlFlow::flowToExpr(expr) } /** * A configuration for tracking sandboxed JEXL engines. @@ -145,7 +145,7 @@ private module SandboxedJexlFlowConfig implements DataFlow::ConfigSig { } } -private module SandboxedJexlFlow = DataFlow::Make<SandboxedJexlFlowConfig>; +private module SandboxedJexlFlow = DataFlow::Global<SandboxedJexlFlowConfig>; /** * Defines a data flow source for JEXL engines configured with a sandbox. diff --git a/java/ql/lib/semmle/code/java/security/JndiInjectionQuery.qll b/java/ql/lib/semmle/code/java/security/JndiInjectionQuery.qll index 81a52bdeaeb..225627fc5de 100644 --- a/java/ql/lib/semmle/code/java/security/JndiInjectionQuery.qll +++ b/java/ql/lib/semmle/code/java/security/JndiInjectionQuery.qll @@ -47,14 +47,14 @@ module JndiInjectionFlowConfig implements DataFlow::ConfigSig { } /** Tracks flow of unvalidated user input that is used in JNDI lookup */ -module JndiInjectionFlow = TaintTracking::Make<JndiInjectionFlowConfig>; +module JndiInjectionFlow = TaintTracking::Global<JndiInjectionFlowConfig>; /** * A method that does a JNDI lookup when it receives a `SearchControls` argument with `setReturningObjFlag` = `true` */ private class UnsafeSearchControlsSink extends JndiInjectionSink { UnsafeSearchControlsSink() { - exists(MethodAccess ma | UnsafeSearchControlsFlow::hasFlowToExpr(ma.getAnArgument()) | + exists(MethodAccess ma | UnsafeSearchControlsFlow::flowToExpr(ma.getAnArgument()) | this.asExpr() = ma.getArgument(0) ) } @@ -70,7 +70,7 @@ private module UnsafeSearchControlsConfig implements DataFlow::ConfigSig { predicate isSink(DataFlow::Node sink) { sink instanceof UnsafeSearchControlsArgument } } -private module UnsafeSearchControlsFlow = DataFlow::Make<UnsafeSearchControlsConfig>; +private module UnsafeSearchControlsFlow = DataFlow::Global<UnsafeSearchControlsConfig>; /** * An argument of type `SearchControls` of an `LdapOperations.search` or `DirContext.search` call. diff --git a/java/ql/lib/semmle/code/java/security/MvelInjectionQuery.qll b/java/ql/lib/semmle/code/java/security/MvelInjectionQuery.qll index 393ccd0f4f8..a87d7554dd7 100644 --- a/java/ql/lib/semmle/code/java/security/MvelInjectionQuery.qll +++ b/java/ql/lib/semmle/code/java/security/MvelInjectionQuery.qll @@ -44,4 +44,4 @@ module MvelInjectionFlowConfig implements DataFlow::ConfigSig { } /** Tracks flow of unsafe user input that is used to construct and evaluate a MVEL expression. */ -module MvelInjectionFlow = TaintTracking::Make<MvelInjectionFlowConfig>; +module MvelInjectionFlow = TaintTracking::Global<MvelInjectionFlowConfig>; diff --git a/java/ql/lib/semmle/code/java/security/OgnlInjectionQuery.qll b/java/ql/lib/semmle/code/java/security/OgnlInjectionQuery.qll index 4501b4fe0c3..d0dfdda94a4 100644 --- a/java/ql/lib/semmle/code/java/security/OgnlInjectionQuery.qll +++ b/java/ql/lib/semmle/code/java/security/OgnlInjectionQuery.qll @@ -43,4 +43,4 @@ module OgnlInjectionFlowConfig implements DataFlow::ConfigSig { } /** Tracks flow of unvalidated user input that is used in OGNL EL evaluation. */ -module OgnlInjectionFlow = TaintTracking::Make<OgnlInjectionFlowConfig>; +module OgnlInjectionFlow = TaintTracking::Global<OgnlInjectionFlowConfig>; diff --git a/java/ql/lib/semmle/code/java/security/SpelInjectionQuery.qll b/java/ql/lib/semmle/code/java/security/SpelInjectionQuery.qll index 67e5f053f2d..e54515f4827 100644 --- a/java/ql/lib/semmle/code/java/security/SpelInjectionQuery.qll +++ b/java/ql/lib/semmle/code/java/security/SpelInjectionQuery.qll @@ -39,7 +39,7 @@ module SpelInjectionConfig implements DataFlow::ConfigSig { } /** Tracks flow of unsafe user input that is used to construct and evaluate a SpEL expression. */ -module SpelInjectionFlow = TaintTracking::Make<SpelInjectionConfig>; +module SpelInjectionFlow = TaintTracking::Global<SpelInjectionConfig>; /** Default sink for SpEL injection vulnerabilities. */ private class DefaultSpelExpressionEvaluationSink extends SpelExpressionEvaluationSink { @@ -47,7 +47,7 @@ private class DefaultSpelExpressionEvaluationSink extends SpelExpressionEvaluati exists(MethodAccess ma | ma.getMethod() instanceof ExpressionEvaluationMethod and ma.getQualifier() = this.asExpr() and - not SafeEvaluationContextFlow::hasFlowToExpr(ma.getArgument(0)) + not SafeEvaluationContextFlow::flowToExpr(ma.getArgument(0)) ) } } @@ -68,7 +68,7 @@ private module SafeEvaluationContextFlowConfig implements DataFlow::ConfigSig { int fieldFlowBranchLimit() { result = 0 } } -private module SafeEvaluationContextFlow = DataFlow::Make<SafeEvaluationContextFlowConfig>; +private module SafeEvaluationContextFlow = DataFlow::Global<SafeEvaluationContextFlowConfig>; /** * A `ContextSource` that is safe from SpEL injection. diff --git a/java/ql/lib/semmle/code/java/security/SqlInjectionQuery.qll b/java/ql/lib/semmle/code/java/security/SqlInjectionQuery.qll index 71cb56d79c1..089ac1132ef 100644 --- a/java/ql/lib/semmle/code/java/security/SqlInjectionQuery.qll +++ b/java/ql/lib/semmle/code/java/security/SqlInjectionQuery.qll @@ -53,7 +53,7 @@ module QueryInjectionFlowConfig implements DataFlow::ConfigSig { } /** Tracks flow of unvalidated user input that is used in SQL queries. */ -module QueryInjectionFlow = TaintTracking::Make<QueryInjectionFlowConfig>; +module QueryInjectionFlow = TaintTracking::Global<QueryInjectionFlowConfig>; /** * Implementation of `SqlTainted.ql`. This is extracted to a QLL so that it @@ -62,5 +62,5 @@ module QueryInjectionFlow = TaintTracking::Make<QueryInjectionFlowConfig>; predicate queryTaintedBy( QueryInjectionSink query, QueryInjectionFlow::PathNode source, QueryInjectionFlow::PathNode sink ) { - QueryInjectionFlow::hasFlowPath(source, sink) and sink.getNode() = query + QueryInjectionFlow::flowPath(source, sink) and sink.getNode() = query } diff --git a/java/ql/lib/semmle/code/java/security/TemplateInjectionQuery.qll b/java/ql/lib/semmle/code/java/security/TemplateInjectionQuery.qll index aee797046f7..783c368482c 100644 --- a/java/ql/lib/semmle/code/java/security/TemplateInjectionQuery.qll +++ b/java/ql/lib/semmle/code/java/security/TemplateInjectionQuery.qll @@ -71,4 +71,4 @@ module TemplateInjectionFlowConfig implements DataFlow::StateConfigSig { } /** Tracks server-side template injection (SST) vulnerabilities */ -module TemplateInjectionFlow = TaintTracking::MakeWithState<TemplateInjectionFlowConfig>; +module TemplateInjectionFlow = TaintTracking::GlobalWithState<TemplateInjectionFlowConfig>; diff --git a/java/ql/lib/semmle/code/java/security/XsltInjectionQuery.qll b/java/ql/lib/semmle/code/java/security/XsltInjectionQuery.qll index 9aa9ca71613..5622ef60a84 100644 --- a/java/ql/lib/semmle/code/java/security/XsltInjectionQuery.qll +++ b/java/ql/lib/semmle/code/java/security/XsltInjectionQuery.qll @@ -47,7 +47,7 @@ module XsltInjectionFlowConfig implements DataFlow::ConfigSig { /** * Tracks flow from unvalidated user input to XSLT transformation. */ -module XsltInjectionFlow = TaintTracking::Make<XsltInjectionFlowConfig>; +module XsltInjectionFlow = TaintTracking::Global<XsltInjectionFlowConfig>; /** * A set of additional taint steps to consider when taint tracking XSLT related data flows. @@ -70,7 +70,7 @@ private predicate newTransformerOrTemplatesStep(DataFlow::Node n1, DataFlow::Nod n2.asExpr() = ma and m.getDeclaringType() instanceof TransformerFactory and m.hasName(["newTransformer", "newTemplates"]) and - not TransformerFactoryWithSecureProcessingFeatureFlow::hasFlowToExpr(ma.getQualifier()) + not TransformerFactoryWithSecureProcessingFeatureFlow::flowToExpr(ma.getQualifier()) ) } @@ -99,7 +99,7 @@ private module TransformerFactoryWithSecureProcessingFeatureFlowConfig implement } private module TransformerFactoryWithSecureProcessingFeatureFlow = - DataFlow::Make<TransformerFactoryWithSecureProcessingFeatureFlowConfig>; + DataFlow::Global<TransformerFactoryWithSecureProcessingFeatureFlowConfig>; /** A `ParserConfig` specific to `TransformerFactory`. */ private class TransformerFactoryFeatureConfig extends ParserConfig { diff --git a/java/ql/lib/semmle/code/java/security/regexp/RegexInjectionQuery.qll b/java/ql/lib/semmle/code/java/security/regexp/RegexInjectionQuery.qll index d0a7bd7d7f3..af8b4e204a1 100644 --- a/java/ql/lib/semmle/code/java/security/regexp/RegexInjectionQuery.qll +++ b/java/ql/lib/semmle/code/java/security/regexp/RegexInjectionQuery.qll @@ -31,4 +31,4 @@ module RegexInjectionConfig implements DataFlow::ConfigSig { predicate isBarrier(DataFlow::Node node) { node instanceof RegexInjectionSanitizer } } -module RegexInjectionFlow = TaintTracking::Make<RegexInjectionConfig>; +module RegexInjectionFlow = TaintTracking::Global<RegexInjectionConfig>; diff --git a/java/ql/src/Security/CWE/CWE-074/JndiInjection.ql b/java/ql/src/Security/CWE/CWE-074/JndiInjection.ql index 7e22c4205d1..900f3d923b3 100644 --- a/java/ql/src/Security/CWE/CWE-074/JndiInjection.ql +++ b/java/ql/src/Security/CWE/CWE-074/JndiInjection.ql @@ -16,6 +16,6 @@ import semmle.code.java.security.JndiInjectionQuery import JndiInjectionFlow::PathGraph from JndiInjectionFlow::PathNode source, JndiInjectionFlow::PathNode sink -where JndiInjectionFlow::hasFlowPath(source, sink) +where JndiInjectionFlow::flowPath(source, sink) select sink.getNode(), source, sink, "JNDI lookup might include name from $@.", source.getNode(), "this user input" diff --git a/java/ql/src/Security/CWE/CWE-074/XsltInjection.ql b/java/ql/src/Security/CWE/CWE-074/XsltInjection.ql index 2888b91b3bf..9cf98aea259 100644 --- a/java/ql/src/Security/CWE/CWE-074/XsltInjection.ql +++ b/java/ql/src/Security/CWE/CWE-074/XsltInjection.ql @@ -16,6 +16,6 @@ import semmle.code.java.security.XsltInjectionQuery import XsltInjectionFlow::PathGraph from XsltInjectionFlow::PathNode source, XsltInjectionFlow::PathNode sink -where XsltInjectionFlow::hasFlowPath(source, sink) +where XsltInjectionFlow::flowPath(source, sink) select sink.getNode(), source, sink, "XSLT transformation might include stylesheet from $@.", source.getNode(), "this user input" diff --git a/java/ql/src/Security/CWE/CWE-094/GroovyInjection.ql b/java/ql/src/Security/CWE/CWE-094/GroovyInjection.ql index 1f077d36f3c..98ae9f2fef3 100644 --- a/java/ql/src/Security/CWE/CWE-094/GroovyInjection.ql +++ b/java/ql/src/Security/CWE/CWE-094/GroovyInjection.ql @@ -16,6 +16,6 @@ import semmle.code.java.security.GroovyInjectionQuery import GroovyInjectionFlow::PathGraph from GroovyInjectionFlow::PathNode source, GroovyInjectionFlow::PathNode sink -where GroovyInjectionFlow::hasFlowPath(source, sink) +where GroovyInjectionFlow::flowPath(source, sink) select sink.getNode(), source, sink, "Groovy script depends on a $@.", source.getNode(), "user-provided value" diff --git a/java/ql/src/Security/CWE/CWE-094/JexlInjection.ql b/java/ql/src/Security/CWE/CWE-094/JexlInjection.ql index d2ca8a2a8d9..5335235d748 100644 --- a/java/ql/src/Security/CWE/CWE-094/JexlInjection.ql +++ b/java/ql/src/Security/CWE/CWE-094/JexlInjection.ql @@ -16,6 +16,6 @@ import semmle.code.java.security.JexlInjectionQuery import JexlInjectionFlow::PathGraph from JexlInjectionFlow::PathNode source, JexlInjectionFlow::PathNode sink -where JexlInjectionFlow::hasFlowPath(source, sink) +where JexlInjectionFlow::flowPath(source, sink) select sink.getNode(), source, sink, "JEXL expression depends on a $@.", source.getNode(), "user-provided value" diff --git a/java/ql/src/Security/CWE/CWE-094/MvelInjection.ql b/java/ql/src/Security/CWE/CWE-094/MvelInjection.ql index e10ecf1bf21..d7b033cabea 100644 --- a/java/ql/src/Security/CWE/CWE-094/MvelInjection.ql +++ b/java/ql/src/Security/CWE/CWE-094/MvelInjection.ql @@ -16,6 +16,6 @@ import semmle.code.java.security.MvelInjectionQuery import MvelInjectionFlow::PathGraph from MvelInjectionFlow::PathNode source, MvelInjectionFlow::PathNode sink -where MvelInjectionFlow::hasFlowPath(source, sink) +where MvelInjectionFlow::flowPath(source, sink) select sink.getNode(), source, sink, "MVEL expression depends on a $@.", source.getNode(), "user-provided value" diff --git a/java/ql/src/Security/CWE/CWE-094/SpelInjection.ql b/java/ql/src/Security/CWE/CWE-094/SpelInjection.ql index 6963dfb22a6..fe1a434cd71 100644 --- a/java/ql/src/Security/CWE/CWE-094/SpelInjection.ql +++ b/java/ql/src/Security/CWE/CWE-094/SpelInjection.ql @@ -17,6 +17,6 @@ import semmle.code.java.dataflow.DataFlow import SpelInjectionFlow::PathGraph from SpelInjectionFlow::PathNode source, SpelInjectionFlow::PathNode sink -where SpelInjectionFlow::hasFlowPath(source, sink) +where SpelInjectionFlow::flowPath(source, sink) select sink.getNode(), source, sink, "SpEL expression depends on a $@.", source.getNode(), "user-provided value" diff --git a/java/ql/src/Security/CWE/CWE-094/TemplateInjection.ql b/java/ql/src/Security/CWE/CWE-094/TemplateInjection.ql index 279881f95a0..6e405cf9b82 100644 --- a/java/ql/src/Security/CWE/CWE-094/TemplateInjection.ql +++ b/java/ql/src/Security/CWE/CWE-094/TemplateInjection.ql @@ -16,6 +16,6 @@ import semmle.code.java.security.TemplateInjectionQuery import TemplateInjectionFlow::PathGraph from TemplateInjectionFlow::PathNode source, TemplateInjectionFlow::PathNode sink -where TemplateInjectionFlow::hasFlowPath(source, sink) +where TemplateInjectionFlow::flowPath(source, sink) select sink.getNode(), source, sink, "Template, which may contain code, depends on a $@.", source.getNode(), "user-provided value" diff --git a/java/ql/src/Security/CWE/CWE-730/RegexInjection.ql b/java/ql/src/Security/CWE/CWE-730/RegexInjection.ql index 954bc8337fe..64fe906658b 100644 --- a/java/ql/src/Security/CWE/CWE-730/RegexInjection.ql +++ b/java/ql/src/Security/CWE/CWE-730/RegexInjection.ql @@ -18,6 +18,6 @@ import semmle.code.java.security.regexp.RegexInjectionQuery import RegexInjectionFlow::PathGraph from RegexInjectionFlow::PathNode source, RegexInjectionFlow::PathNode sink -where RegexInjectionFlow::hasFlowPath(source, sink) +where RegexInjectionFlow::flowPath(source, sink) select sink.getNode(), source, sink, "This regular expression is constructed from a $@.", source.getNode(), "user-provided value" diff --git a/java/ql/src/Security/CWE/CWE-917/OgnlInjection.ql b/java/ql/src/Security/CWE/CWE-917/OgnlInjection.ql index 7a033b51ba2..964360a96bf 100644 --- a/java/ql/src/Security/CWE/CWE-917/OgnlInjection.ql +++ b/java/ql/src/Security/CWE/CWE-917/OgnlInjection.ql @@ -16,6 +16,6 @@ import semmle.code.java.security.OgnlInjectionQuery import OgnlInjectionFlow::PathGraph from OgnlInjectionFlow::PathNode source, OgnlInjectionFlow::PathNode sink -where OgnlInjectionFlow::hasFlowPath(source, sink) +where OgnlInjectionFlow::flowPath(source, sink) select sink.getNode(), source, sink, "OGNL Expression Language statement depends on a $@.", source.getNode(), "user-provided value" diff --git a/java/ql/test/query-tests/security/CWE-074/JndiInjectionTest.ql b/java/ql/test/query-tests/security/CWE-074/JndiInjectionTest.ql index e6824300b86..7a6141b93ce 100644 --- a/java/ql/test/query-tests/security/CWE-074/JndiInjectionTest.ql +++ b/java/ql/test/query-tests/security/CWE-074/JndiInjectionTest.ql @@ -9,7 +9,7 @@ class HasJndiInjectionTest extends InlineExpectationsTest { override predicate hasActualResult(Location location, string element, string tag, string value) { tag = "hasJndiInjection" and - exists(DataFlow::Node sink | JndiInjectionFlow::hasFlowTo(sink) | + exists(DataFlow::Node sink | JndiInjectionFlow::flowTo(sink) | sink.getLocation() = location and element = sink.toString() and value = "" diff --git a/java/ql/test/query-tests/security/CWE-074/XsltInjectionTest.ql b/java/ql/test/query-tests/security/CWE-074/XsltInjectionTest.ql index a8c79964742..1f5a3030cdb 100644 --- a/java/ql/test/query-tests/security/CWE-074/XsltInjectionTest.ql +++ b/java/ql/test/query-tests/security/CWE-074/XsltInjectionTest.ql @@ -11,7 +11,7 @@ class HasXsltInjectionTest extends InlineExpectationsTest { override predicate hasActualResult(Location location, string element, string tag, string value) { tag = "hasXsltInjection" and - exists(DataFlow::Node sink | XsltInjectionFlow::hasFlowTo(sink) | + exists(DataFlow::Node sink | XsltInjectionFlow::flowTo(sink) | sink.getLocation() = location and element = sink.toString() and value = "" diff --git a/java/ql/test/query-tests/security/CWE-094/GroovyInjectionTest.ql b/java/ql/test/query-tests/security/CWE-094/GroovyInjectionTest.ql index 3eb01533bdd..9d979f125a8 100644 --- a/java/ql/test/query-tests/security/CWE-094/GroovyInjectionTest.ql +++ b/java/ql/test/query-tests/security/CWE-094/GroovyInjectionTest.ql @@ -11,7 +11,7 @@ class HasGroovyInjectionTest extends InlineExpectationsTest { override predicate hasActualResult(Location location, string element, string tag, string value) { tag = "hasGroovyInjection" and - exists(DataFlow::Node sink | GroovyInjectionFlow::hasFlowTo(sink) | + exists(DataFlow::Node sink | GroovyInjectionFlow::flowTo(sink) | sink.getLocation() = location and element = sink.toString() and value = "" diff --git a/java/ql/test/query-tests/security/CWE-094/JexlInjectionTest.ql b/java/ql/test/query-tests/security/CWE-094/JexlInjectionTest.ql index 729cc69cf7d..9593ae1a8ee 100644 --- a/java/ql/test/query-tests/security/CWE-094/JexlInjectionTest.ql +++ b/java/ql/test/query-tests/security/CWE-094/JexlInjectionTest.ql @@ -9,7 +9,7 @@ class JexlInjectionTest extends InlineExpectationsTest { override predicate hasActualResult(Location location, string element, string tag, string value) { tag = "hasJexlInjection" and - exists(DataFlow::Node sink | JexlInjectionFlow::hasFlowTo(sink) | + exists(DataFlow::Node sink | JexlInjectionFlow::flowTo(sink) | sink.getLocation() = location and element = sink.toString() and value = "" diff --git a/java/ql/test/query-tests/security/CWE-094/MvelInjectionTest.ql b/java/ql/test/query-tests/security/CWE-094/MvelInjectionTest.ql index b3ffdc6d5ca..8dc4127cbf1 100644 --- a/java/ql/test/query-tests/security/CWE-094/MvelInjectionTest.ql +++ b/java/ql/test/query-tests/security/CWE-094/MvelInjectionTest.ql @@ -11,7 +11,7 @@ class HasMvelInjectionTest extends InlineExpectationsTest { override predicate hasActualResult(Location location, string element, string tag, string value) { tag = "hasMvelInjection" and - exists(DataFlow::Node sink | MvelInjectionFlow::hasFlowTo(sink) | + exists(DataFlow::Node sink | MvelInjectionFlow::flowTo(sink) | sink.getLocation() = location and element = sink.toString() and value = "" diff --git a/java/ql/test/query-tests/security/CWE-094/SpelInjectionTest.ql b/java/ql/test/query-tests/security/CWE-094/SpelInjectionTest.ql index 92bd3b2114e..78e147849f1 100644 --- a/java/ql/test/query-tests/security/CWE-094/SpelInjectionTest.ql +++ b/java/ql/test/query-tests/security/CWE-094/SpelInjectionTest.ql @@ -11,7 +11,7 @@ class HasSpelInjectionTest extends InlineExpectationsTest { override predicate hasActualResult(Location location, string element, string tag, string value) { tag = "hasSpelInjection" and - exists(DataFlow::Node sink | SpelInjectionFlow::hasFlowTo(sink) | + exists(DataFlow::Node sink | SpelInjectionFlow::flowTo(sink) | sink.getLocation() = location and element = sink.toString() and value = "" diff --git a/java/ql/test/query-tests/security/CWE-094/TemplateInjectionTest.ql b/java/ql/test/query-tests/security/CWE-094/TemplateInjectionTest.ql index cc834b07a6b..7e0a7ae1ae2 100644 --- a/java/ql/test/query-tests/security/CWE-094/TemplateInjectionTest.ql +++ b/java/ql/test/query-tests/security/CWE-094/TemplateInjectionTest.ql @@ -9,7 +9,7 @@ class TemplateInjectionTest extends InlineExpectationsTest { override predicate hasActualResult(Location location, string element, string tag, string value) { tag = "hasTemplateInjection" and - exists(DataFlow::Node sink | TemplateInjectionFlow::hasFlowTo(sink) | + exists(DataFlow::Node sink | TemplateInjectionFlow::flowTo(sink) | sink.getLocation() = location and element = sink.toString() and value = "" diff --git a/java/ql/test/query-tests/security/CWE-730/RegexInjectionTest.ql b/java/ql/test/query-tests/security/CWE-730/RegexInjectionTest.ql index 2a9b34fc4cd..f42de310988 100644 --- a/java/ql/test/query-tests/security/CWE-730/RegexInjectionTest.ql +++ b/java/ql/test/query-tests/security/CWE-730/RegexInjectionTest.ql @@ -9,7 +9,7 @@ class RegexInjectionTest extends InlineExpectationsTest { override predicate hasActualResult(Location location, string element, string tag, string value) { tag = "hasRegexInjection" and - exists(RegexInjectionFlow::PathNode sink | RegexInjectionFlow::hasFlowPath(_, sink) | + exists(RegexInjectionFlow::PathNode sink | RegexInjectionFlow::flowPath(_, sink) | location = sink.getNode().getLocation() and element = sink.getNode().toString() and value = "" diff --git a/java/ql/test/query-tests/security/CWE-917/OgnlInjectionTest.ql b/java/ql/test/query-tests/security/CWE-917/OgnlInjectionTest.ql index cc3482dfe75..68db2593628 100644 --- a/java/ql/test/query-tests/security/CWE-917/OgnlInjectionTest.ql +++ b/java/ql/test/query-tests/security/CWE-917/OgnlInjectionTest.ql @@ -9,7 +9,7 @@ class OgnlInjectionTest extends InlineExpectationsTest { override predicate hasActualResult(Location location, string element, string tag, string value) { tag = "hasOgnlInjection" and - exists(DataFlow::Node sink | OgnlInjectionFlow::hasFlowTo(sink) | + exists(DataFlow::Node sink | OgnlInjectionFlow::flowTo(sink) | sink.getLocation() = location and element = sink.toString() and value = "" From fcd53a855584f973e7c5f43e631a8453e974d4ab Mon Sep 17 00:00:00 2001 From: Ed Minnix <egregius313@github.com> Date: Fri, 24 Mar 2023 10:07:40 -0400 Subject: [PATCH 471/631] Deprecate old predicate --- .../semmle/code/java/security/SqlInjectionQuery.qll | 12 +++++++++++- java/ql/src/Security/CWE/CWE-089/SqlTainted.ql | 2 +- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/java/ql/lib/semmle/code/java/security/SqlInjectionQuery.qll b/java/ql/lib/semmle/code/java/security/SqlInjectionQuery.qll index 089ac1132ef..18f3c01571e 100644 --- a/java/ql/lib/semmle/code/java/security/SqlInjectionQuery.qll +++ b/java/ql/lib/semmle/code/java/security/SqlInjectionQuery.qll @@ -59,7 +59,17 @@ module QueryInjectionFlow = TaintTracking::Global<QueryInjectionFlowConfig>; * Implementation of `SqlTainted.ql`. This is extracted to a QLL so that it * can be excluded from `SqlConcatenated.ql` to avoid overlapping results. */ -predicate queryTaintedBy( +deprecated predicate queryTaintedBy( + QueryInjectionSink query, DataFlow::PathNode source, DataFlow::PathNode sink +) { + any(QueryInjectionFlowConfig c).hasFlowPath(source, sink) and sink.getNode() = query +} + +/** + * Implementation of `SqlTainted.ql`. This is extracted to a QLL so that it + * can be excluded from `SqlConcatenated.ql` to avoid overlapping results. + */ +predicate queryIsTaintedBy( QueryInjectionSink query, QueryInjectionFlow::PathNode source, QueryInjectionFlow::PathNode sink ) { QueryInjectionFlow::flowPath(source, sink) and sink.getNode() = query diff --git a/java/ql/src/Security/CWE/CWE-089/SqlTainted.ql b/java/ql/src/Security/CWE/CWE-089/SqlTainted.ql index 628d469bac7..3549621c48d 100644 --- a/java/ql/src/Security/CWE/CWE-089/SqlTainted.ql +++ b/java/ql/src/Security/CWE/CWE-089/SqlTainted.ql @@ -19,5 +19,5 @@ import QueryInjectionFlow::PathGraph from QueryInjectionSink query, QueryInjectionFlow::PathNode source, QueryInjectionFlow::PathNode sink -where queryTaintedBy(query, source, sink) +where queryIsTaintedBy(query, source, sink) select query, source, sink, "This query depends on a $@.", source.getNode(), "user-provided value" From b87f12d5b2339bd70a50bd44cdfdb4336327e310 Mon Sep 17 00:00:00 2001 From: Gulshan Singh <gsgx@google.com> Date: Thu, 23 Mar 2023 16:52:31 -0700 Subject: [PATCH 472/631] C++: Add StrlenLiteralRangeExpr --- .../rangeanalysis/ExtendedRangeAnalysis.qll | 1 + .../extensions/StrlenLiteralRangeExpr.qll | 18 ++++++++++++++++++ .../strlenliteral/StrlenLiteralRange.expected | 2 ++ .../strlenliteral/StrlenLiteralRange.ql | 6 ++++++ .../rangeanalysis/strlenliteral/test.cpp | 6 ++++++ 5 files changed, 33 insertions(+) create mode 100644 cpp/ql/lib/experimental/semmle/code/cpp/rangeanalysis/extensions/StrlenLiteralRangeExpr.qll create mode 100644 cpp/ql/test/experimental/library-tests/rangeanalysis/strlenliteral/StrlenLiteralRange.expected create mode 100644 cpp/ql/test/experimental/library-tests/rangeanalysis/strlenliteral/StrlenLiteralRange.ql create mode 100644 cpp/ql/test/experimental/library-tests/rangeanalysis/strlenliteral/test.cpp diff --git a/cpp/ql/lib/experimental/semmle/code/cpp/rangeanalysis/ExtendedRangeAnalysis.qll b/cpp/ql/lib/experimental/semmle/code/cpp/rangeanalysis/ExtendedRangeAnalysis.qll index bc63d740c32..cba3a94c7af 100644 --- a/cpp/ql/lib/experimental/semmle/code/cpp/rangeanalysis/ExtendedRangeAnalysis.qll +++ b/cpp/ql/lib/experimental/semmle/code/cpp/rangeanalysis/ExtendedRangeAnalysis.qll @@ -3,3 +3,4 @@ import semmle.code.cpp.rangeanalysis.SimpleRangeAnalysis // Import each extension we want to enable import extensions.SubtractSelf import extensions.ConstantBitwiseAndExprRange +import extensions.StrlenLiteralRangeExpr diff --git a/cpp/ql/lib/experimental/semmle/code/cpp/rangeanalysis/extensions/StrlenLiteralRangeExpr.qll b/cpp/ql/lib/experimental/semmle/code/cpp/rangeanalysis/extensions/StrlenLiteralRangeExpr.qll new file mode 100644 index 00000000000..39326e89a51 --- /dev/null +++ b/cpp/ql/lib/experimental/semmle/code/cpp/rangeanalysis/extensions/StrlenLiteralRangeExpr.qll @@ -0,0 +1,18 @@ +private import cpp +private import experimental.semmle.code.cpp.models.interfaces.SimpleRangeAnalysisExpr + +/** + * Provides range analysis information for calls to `strlen` on literal strings. + * For example, the range of `strlen("literal")` will be 7. + */ +class StrlenLiteralRangeExpr extends SimpleRangeAnalysisExpr, FunctionCall { + StrlenLiteralRangeExpr() { + getTarget().hasGlobalOrStdName("strlen") and getArgument(0).isConstant() + } + + override int getLowerBounds() { result = getArgument(0).getValue().length() } + + override int getUpperBounds() { result = getArgument(0).getValue().length() } + + override predicate dependsOnChild(Expr e) { none() } +} diff --git a/cpp/ql/test/experimental/library-tests/rangeanalysis/strlenliteral/StrlenLiteralRange.expected b/cpp/ql/test/experimental/library-tests/rangeanalysis/strlenliteral/StrlenLiteralRange.expected new file mode 100644 index 00000000000..f714ac312ea --- /dev/null +++ b/cpp/ql/test/experimental/library-tests/rangeanalysis/strlenliteral/StrlenLiteralRange.expected @@ -0,0 +1,2 @@ +| test.cpp:4:3:4:8 | call to strlen | 7.0 | 7.0 | +| test.cpp:5:3:5:8 | call to strlen | 1.8446744073709552E19 | 0.0 | diff --git a/cpp/ql/test/experimental/library-tests/rangeanalysis/strlenliteral/StrlenLiteralRange.ql b/cpp/ql/test/experimental/library-tests/rangeanalysis/strlenliteral/StrlenLiteralRange.ql new file mode 100644 index 00000000000..c77b2078610 --- /dev/null +++ b/cpp/ql/test/experimental/library-tests/rangeanalysis/strlenliteral/StrlenLiteralRange.ql @@ -0,0 +1,6 @@ +import cpp +import semmle.code.cpp.rangeanalysis.SimpleRangeAnalysis +import experimental.semmle.code.cpp.rangeanalysis.extensions.StrlenLiteralRangeExpr + +from FunctionCall fc +select fc, upperBound(fc), lowerBound(fc) diff --git a/cpp/ql/test/experimental/library-tests/rangeanalysis/strlenliteral/test.cpp b/cpp/ql/test/experimental/library-tests/rangeanalysis/strlenliteral/test.cpp new file mode 100644 index 00000000000..02626c00f8f --- /dev/null +++ b/cpp/ql/test/experimental/library-tests/rangeanalysis/strlenliteral/test.cpp @@ -0,0 +1,6 @@ +unsigned long strlen(const char *); + +void func(const char *s) { + strlen("literal"); + strlen(s); +} From 8b90d021fae4563110725018b972f2031f33162e Mon Sep 17 00:00:00 2001 From: Arthur Baars <aibaars@github.com> Date: Fri, 3 Mar 2023 17:54:49 +0100 Subject: [PATCH 473/631] Ruby: change evaluation order of destructured assignments --- ruby/ql/lib/codeql/ruby/ast/internal/Expr.qll | 4 +- .../codeql/ruby/ast/internal/Synthesis.qll | 80 +++++++++++++--- .../library-tests/ast/AstDesugar.expected | 66 +++++++------ .../library-tests/ast/calls/calls.expected | 30 +++--- .../controlflow/graph/Cfg.expected | 93 ++++++++++--------- .../dataflow/array-flow/array-flow.expected | 12 +-- .../test/library-tests/variables/ssa.expected | 28 +++--- .../variables/varaccess.expected | 14 +-- .../library-tests/variables/variable.expected | 5 + 9 files changed, 212 insertions(+), 120 deletions(-) diff --git a/ruby/ql/lib/codeql/ruby/ast/internal/Expr.qll b/ruby/ql/lib/codeql/ruby/ast/internal/Expr.qll index 8160966ac1a..9e8ca5e8fba 100644 --- a/ruby/ql/lib/codeql/ruby/ast/internal/Expr.qll +++ b/ruby/ql/lib/codeql/ruby/ast/internal/Expr.qll @@ -4,7 +4,9 @@ private import AST private import TreeSitter class StmtSequenceSynth extends StmtSequence, TStmtSequenceSynth { - final override Stmt getStmt(int n) { synthChild(this, n, result) } + final override Stmt getStmt(int n) { + result = rank[n + 1](int i, Stmt s | synthChild(this, i, s) | s order by i) + } final override string toString() { result = "..." } } diff --git a/ruby/ql/lib/codeql/ruby/ast/internal/Synthesis.qll b/ruby/ql/lib/codeql/ruby/ast/internal/Synthesis.qll index 289f812931c..c36af496991 100644 --- a/ruby/ql/lib/codeql/ruby/ast/internal/Synthesis.qll +++ b/ruby/ql/lib/codeql/ruby/ast/internal/Synthesis.qll @@ -958,14 +958,32 @@ private module DestructuredAssignDesugar { child = SynthChild(StmtSequenceKind()) or exists(AstNode seq | seq = TStmtSequenceSynth(tae, -1) | + exists(MethodCall mc, int j | mc = tae.getElement(j) | + parent = seq and + i = j and + child = SynthChild(AssignExprKind()) + or + exists(AstNode assign | assign = TAssignExprSynth(seq, j) | + parent = assign and + i = 0 and + child = SynthChild(LocalVariableAccessSynthKind(TLocalVariableSynth(tae, j))) + or + parent = assign and + i = 1 and + child = childRef(mc.getReceiver()) + ) + ) + or parent = seq and - i = 0 and + i = tae.getNumberOfElements() and child = SynthChild(AssignExprKind()) or - exists(AstNode assign | assign = TAssignExprSynth(seq, 0) | + exists(AstNode assign | assign = TAssignExprSynth(seq, tae.getNumberOfElements()) | parent = assign and i = 0 and - child = SynthChild(LocalVariableAccessSynthKind(TLocalVariableSynth(tae, 0))) + child = + SynthChild(LocalVariableAccessSynthKind(TLocalVariableSynth(tae, + tae.getNumberOfElements()))) or parent = assign and i = 1 and @@ -981,10 +999,33 @@ private module DestructuredAssignDesugar { restIndex = tae.getRestIndexOrNumberOfElements() | parent = seq and - i = j + 1 and + i = j + 1 + tae.getNumberOfElements() and child = SynthChild(AssignExprKind()) or - exists(AstNode assign | assign = TAssignExprSynth(seq, j + 1) | + exists(AstNode assign | + assign = TAssignExprSynth(seq, j + 1 + tae.getNumberOfElements()) + | + exists(MethodCall mc | mc = elem | + parent = assign and + i = 0 and + child = + SynthChild(MethodCallKind(mc.getMethodName(), false, mc.getNumberOfArguments())) + or + exists(AstNode call | call = TMethodCallSynth(assign, 0, _, _, _) | + parent = call and + i = 0 and + child = SynthChild(LocalVariableAccessSynthKind(TLocalVariableSynth(tae, j))) + or + parent = call and + child = childRef(mc.getArgument(i - 1)) + ) + ) + or + ( + elem instanceof VariableAccess or + elem instanceof ConstantAccess or + elem instanceof DestructuredLhsExpr + ) and parent = assign and i = 0 and child = childRef(elem) @@ -995,7 +1036,9 @@ private module DestructuredAssignDesugar { or parent = TMethodCallSynth(assign, 1, _, _, _) and i = 0 and - child = SynthChild(LocalVariableAccessSynthKind(TLocalVariableSynth(tae, 0))) + child = + SynthChild(LocalVariableAccessSynthKind(TLocalVariableSynth(tae, + tae.getNumberOfElements()))) or j < restIndex and parent = TMethodCallSynth(assign, 1, _, _, _) and @@ -1050,26 +1093,41 @@ private module DestructuredAssignDesugar { final override predicate location(AstNode n, Location l) { exists(DestructuredAssignExpr tae, StmtSequence seq | seq = tae.getDesugared() | - n = seq.getStmt(0) and + synthChild(seq, tae.getNumberOfElements(), n) and hasLocation(tae.getRightOperand(), l) or - exists(AstNode elem, int j | + exists(MethodCall elem, int j | elem = tae.getElement(j) and - n = seq.getStmt(j + 1) and + synthChild(seq, j, n) and + hasLocation(elem.getReceiver(), l) + ) + or + exists(AstNode elem, int j | elem = tae.getElement(j) | + synthChild(seq, j + 1 + tae.getNumberOfElements(), n) and hasLocation(elem, l) ) ) } final override predicate localVariable(AstNode n, int i) { - n instanceof DestructuredAssignExpr and - i = 0 + i = [0 .. n.(DestructuredAssignExpr).getNumberOfElements()] } final override predicate methodCall(string name, boolean setter, int arity) { name = "[]" and setter = false and arity = 1 + or + exists(DestructuredAssignExpr tae, MethodCall mc | + mc = tae.getElement(_) and + name = mc.getMethodName() and + setter = false and + arity = mc.getNumberOfArguments() + ) + } + + final override predicate excludeFromControlFlowTree(AstNode n) { + n = any(DestructuredAssignExpr tae).getElement(_).(MethodCall) } } } diff --git a/ruby/ql/test/library-tests/ast/AstDesugar.expected b/ruby/ql/test/library-tests/ast/AstDesugar.expected index 8479718819c..f31e590b825 100644 --- a/ruby/ql/test/library-tests/ast/AstDesugar.expected +++ b/ruby/ql/test/library-tests/ast/AstDesugar.expected @@ -81,44 +81,53 @@ calls/calls.rb: # 318| [AssignExpr] ... = ... # 318| getDesugared: [StmtSequence] ... # 318| getStmt: [AssignExpr] ... = ... -# 318| getAnOperand/getLeftOperand: [MethodCall] call to foo +# 318| getAnOperand/getRightOperand: [SelfVariableAccess] self +# 318| getAnOperand/getLeftOperand: [LocalVariableAccess] __synth__0 +# 318| getStmt: [AssignExpr] ... = ... # 318| getDesugared: [StmtSequence] ... # 318| getStmt: [SetterMethodCall] call to foo= -# 318| getReceiver: [SelfVariableAccess] self +# 318| getReceiver: [LocalVariableAccess] __synth__0 # 318| getArgument: [AssignExpr] ... = ... # 318| getAnOperand/getLeftOperand: [LocalVariableAccess] __synth__0__1 # 318| getAnOperand/getRightOperand: [MethodCall] call to [] -# 318| getReceiver: [LocalVariableAccess] __synth__0 +# 318| getReceiver: [LocalVariableAccess] __synth__3 # 318| getArgument: [IntegerLiteral] 0 # 318| getStmt: [LocalVariableAccess] __synth__0__1 +# 318| getAnOperand/getLeftOperand: [MethodCall] call to foo +# 318| getStmt: [AssignExpr] ... = ... +# 318| getAnOperand/getRightOperand: [SelfVariableAccess] self +# 318| getAnOperand/getLeftOperand: [LocalVariableAccess] __synth__1 # 318| getStmt: [AssignExpr] ... = ... -# 318| getAnOperand/getLeftOperand: [MethodCall] call to bar # 318| getDesugared: [StmtSequence] ... # 318| getStmt: [SetterMethodCall] call to bar= -# 318| getReceiver: [SelfVariableAccess] self +# 318| getReceiver: [LocalVariableAccess] __synth__1 # 318| getArgument: [AssignExpr] ... = ... # 318| getAnOperand/getLeftOperand: [LocalVariableAccess] __synth__0__1 # 318| getAnOperand/getRightOperand: [MethodCall] call to [] -# 318| getReceiver: [LocalVariableAccess] __synth__0 +# 318| getReceiver: [LocalVariableAccess] __synth__3 # 318| getArgument: [RangeLiteral] _ .. _ # 318| getBegin: [IntegerLiteral] 1 # 318| getEnd: [IntegerLiteral] -2 # 318| getStmt: [LocalVariableAccess] __synth__0__1 +# 318| getAnOperand/getLeftOperand: [MethodCall] call to bar +# 318| getStmt: [AssignExpr] ... = ... +# 318| getAnOperand/getRightOperand: [MethodCall] call to foo +# 318| getReceiver: [SelfVariableAccess] self +# 318| getAnOperand/getLeftOperand: [LocalVariableAccess] __synth__2 # 318| getStmt: [AssignExpr] ... = ... -# 318| getAnOperand/getLeftOperand: [ElementReference] ...[...] # 318| getDesugared: [StmtSequence] ... # 318| getStmt: [SetterMethodCall] call to []= -# 318| getReceiver: [MethodCall] call to foo -# 318| getReceiver: [SelfVariableAccess] self +# 318| getReceiver: [LocalVariableAccess] __synth__2 # 318| getArgument: [AssignExpr] ... = ... # 318| getAnOperand/getLeftOperand: [LocalVariableAccess] __synth__0__1 # 318| getAnOperand/getRightOperand: [MethodCall] call to [] -# 318| getReceiver: [LocalVariableAccess] __synth__0 +# 318| getReceiver: [LocalVariableAccess] __synth__3 # 318| getArgument: [IntegerLiteral] -1 # 318| getArgument: [IntegerLiteral] 4 # 318| getStmt: [LocalVariableAccess] __synth__0__1 +# 318| getAnOperand/getLeftOperand: [MethodCall] call to [] # 318| getStmt: [AssignExpr] ... = ... -# 318| getAnOperand/getLeftOperand: [LocalVariableAccess] __synth__0 +# 318| getAnOperand/getLeftOperand: [LocalVariableAccess] __synth__3 # 318| getAnOperand/getRightOperand: [SplatExpr] * ... # 318| getAnOperand/getOperand/getReceiver: [ArrayLiteral] [...] # 318| getDesugared: [MethodCall] call to [] @@ -132,25 +141,28 @@ calls/calls.rb: # 319| getStmt: [AssignExpr] ... = ... # 319| getAnOperand/getLeftOperand: [LocalVariableAccess] a # 319| getAnOperand/getRightOperand: [MethodCall] call to [] -# 319| getReceiver: [LocalVariableAccess] __synth__0 +# 319| getReceiver: [LocalVariableAccess] __synth__2 # 319| getArgument: [IntegerLiteral] 0 # 319| getStmt: [AssignExpr] ... = ... -# 319| getAnOperand/getLeftOperand: [ElementReference] ...[...] +# 319| getAnOperand/getRightOperand: [MethodCall] call to foo +# 319| getReceiver: [SelfVariableAccess] self +# 319| getAnOperand/getLeftOperand: [LocalVariableAccess] __synth__1 +# 319| getStmt: [AssignExpr] ... = ... # 319| getDesugared: [StmtSequence] ... # 319| getStmt: [SetterMethodCall] call to []= -# 319| getReceiver: [MethodCall] call to foo -# 319| getReceiver: [SelfVariableAccess] self +# 319| getReceiver: [LocalVariableAccess] __synth__1 # 319| getArgument: [AssignExpr] ... = ... # 319| getAnOperand/getLeftOperand: [LocalVariableAccess] __synth__0__1 # 319| getAnOperand/getRightOperand: [MethodCall] call to [] -# 319| getReceiver: [LocalVariableAccess] __synth__0 +# 319| getReceiver: [LocalVariableAccess] __synth__2 # 319| getArgument: [RangeLiteral] _ .. _ # 319| getBegin: [IntegerLiteral] 1 # 319| getEnd: [IntegerLiteral] -1 # 319| getArgument: [IntegerLiteral] 5 # 319| getStmt: [LocalVariableAccess] __synth__0__1 +# 319| getAnOperand/getLeftOperand: [MethodCall] call to [] # 319| getStmt: [AssignExpr] ... = ... -# 319| getAnOperand/getLeftOperand: [LocalVariableAccess] __synth__0 +# 319| getAnOperand/getLeftOperand: [LocalVariableAccess] __synth__2 # 319| getAnOperand/getRightOperand: [SplatExpr] * ... # 319| getAnOperand/getOperand/getReceiver: [ArrayLiteral] [...] # 319| getDesugared: [MethodCall] call to [] @@ -240,23 +252,23 @@ calls/calls.rb: # 342| getStmt: [AssignExpr] ... = ... # 342| getDesugared: [StmtSequence] ... # 342| getStmt: [AssignExpr] ... = ... -# 342| getAnOperand/getLeftOperand: [LocalVariableAccess] __synth__0__1 +# 342| getAnOperand/getLeftOperand: [LocalVariableAccess] __synth__3__1 # 342| getAnOperand/getRightOperand: [SplatExpr] * ... # 342| getAnOperand/getOperand/getReceiver: [LocalVariableAccess] __synth__0__1 # 342| getStmt: [AssignExpr] ... = ... # 342| getAnOperand/getLeftOperand: [LocalVariableAccess] x # 342| getAnOperand/getRightOperand: [MethodCall] call to [] -# 342| getReceiver: [LocalVariableAccess] __synth__0__1 +# 342| getReceiver: [LocalVariableAccess] __synth__3__1 # 342| getArgument: [IntegerLiteral] 0 # 342| getStmt: [AssignExpr] ... = ... # 342| getAnOperand/getLeftOperand: [LocalVariableAccess] y # 342| getAnOperand/getRightOperand: [MethodCall] call to [] -# 342| getReceiver: [LocalVariableAccess] __synth__0__1 +# 342| getReceiver: [LocalVariableAccess] __synth__3__1 # 342| getArgument: [IntegerLiteral] 1 # 342| getStmt: [AssignExpr] ... = ... # 342| getAnOperand/getLeftOperand: [LocalVariableAccess] z # 342| getAnOperand/getRightOperand: [MethodCall] call to [] -# 342| getReceiver: [LocalVariableAccess] __synth__0__1 +# 342| getReceiver: [LocalVariableAccess] __synth__3__1 # 342| getArgument: [IntegerLiteral] 2 # 342| getAnOperand/getLeftOperand: [DestructuredLhsExpr] (..., ...) # 343| getStmt: [MethodCall] call to foo @@ -632,18 +644,18 @@ control/loops.rb: # 22| getStmt: [AssignExpr] ... = ... # 22| getDesugared: [StmtSequence] ... # 22| getStmt: [AssignExpr] ... = ... -# 22| getAnOperand/getLeftOperand: [LocalVariableAccess] __synth__0__1 +# 22| getAnOperand/getLeftOperand: [LocalVariableAccess] __synth__2__1 # 22| getAnOperand/getRightOperand: [SplatExpr] * ... # 22| getAnOperand/getOperand/getReceiver: [LocalVariableAccess] __synth__0__1 # 22| getStmt: [AssignExpr] ... = ... # 22| getAnOperand/getLeftOperand: [LocalVariableAccess] key # 22| getAnOperand/getRightOperand: [MethodCall] call to [] -# 22| getReceiver: [LocalVariableAccess] __synth__0__1 +# 22| getReceiver: [LocalVariableAccess] __synth__2__1 # 22| getArgument: [IntegerLiteral] 0 # 22| getStmt: [AssignExpr] ... = ... # 22| getAnOperand/getLeftOperand: [LocalVariableAccess] value # 22| getAnOperand/getRightOperand: [MethodCall] call to [] -# 22| getReceiver: [LocalVariableAccess] __synth__0__1 +# 22| getReceiver: [LocalVariableAccess] __synth__2__1 # 22| getArgument: [IntegerLiteral] 1 # 22| getAnOperand/getLeftOperand: [DestructuredLhsExpr] (..., ...) # 23| getStmt: [AssignAddExpr] ... += ... @@ -677,18 +689,18 @@ control/loops.rb: # 28| getStmt: [AssignExpr] ... = ... # 28| getDesugared: [StmtSequence] ... # 28| getStmt: [AssignExpr] ... = ... -# 28| getAnOperand/getLeftOperand: [LocalVariableAccess] __synth__0__1 +# 28| getAnOperand/getLeftOperand: [LocalVariableAccess] __synth__2__1 # 28| getAnOperand/getRightOperand: [SplatExpr] * ... # 28| getAnOperand/getOperand/getReceiver: [LocalVariableAccess] __synth__0__1 # 28| getStmt: [AssignExpr] ... = ... # 28| getAnOperand/getLeftOperand: [LocalVariableAccess] key # 28| getAnOperand/getRightOperand: [MethodCall] call to [] -# 28| getReceiver: [LocalVariableAccess] __synth__0__1 +# 28| getReceiver: [LocalVariableAccess] __synth__2__1 # 28| getArgument: [IntegerLiteral] 0 # 28| getStmt: [AssignExpr] ... = ... # 28| getAnOperand/getLeftOperand: [LocalVariableAccess] value # 28| getAnOperand/getRightOperand: [MethodCall] call to [] -# 28| getReceiver: [LocalVariableAccess] __synth__0__1 +# 28| getReceiver: [LocalVariableAccess] __synth__2__1 # 28| getArgument: [IntegerLiteral] 1 # 28| getAnOperand/getLeftOperand: [DestructuredLhsExpr] (..., ...) # 29| getStmt: [AssignAddExpr] ... += ... diff --git a/ruby/ql/test/library-tests/ast/calls/calls.expected b/ruby/ql/test/library-tests/ast/calls/calls.expected index a5d0fe1d272..956d3fa8a22 100644 --- a/ruby/ql/test/library-tests/ast/calls/calls.expected +++ b/ruby/ql/test/library-tests/ast/calls/calls.expected @@ -61,6 +61,7 @@ callsWithArguments | calls.rb:318:12:318:19 | call to bar= | bar= | 0 | calls.rb:318:12:318:19 | ... = ... | | calls.rb:318:22:318:27 | ...[...] | [] | 0 | calls.rb:318:26:318:26 | 4 | | calls.rb:318:22:318:27 | call to [] | [] | 0 | calls.rb:318:22:318:27 | -1 | +| calls.rb:318:22:318:27 | call to [] | [] | 0 | calls.rb:318:26:318:26 | 4 | | calls.rb:318:22:318:27 | call to []= | []= | 0 | calls.rb:318:26:318:26 | 4 | | calls.rb:318:22:318:27 | call to []= | []= | 1 | calls.rb:318:22:318:27 | ... = ... | | calls.rb:318:31:318:42 | call to [] | [] | 0 | calls.rb:318:32:318:32 | 1 | @@ -70,6 +71,7 @@ callsWithArguments | calls.rb:319:1:319:1 | call to [] | [] | 0 | calls.rb:319:1:319:1 | 0 | | calls.rb:319:5:319:10 | ...[...] | [] | 0 | calls.rb:319:9:319:9 | 5 | | calls.rb:319:5:319:10 | call to [] | [] | 0 | calls.rb:319:5:319:10 | _ .. _ | +| calls.rb:319:5:319:10 | call to [] | [] | 0 | calls.rb:319:9:319:9 | 5 | | calls.rb:319:5:319:10 | call to []= | []= | 0 | calls.rb:319:9:319:9 | 5 | | calls.rb:319:5:319:10 | call to []= | []= | 1 | calls.rb:319:5:319:10 | ... = ... | | calls.rb:319:14:319:22 | call to [] | [] | 0 | calls.rb:319:15:319:15 | 1 | @@ -321,23 +323,27 @@ callsWithReceiver | calls.rb:317:1:317:3 | call to foo | calls.rb:317:1:317:3 | self | | calls.rb:317:1:317:6 | ...[...] | calls.rb:317:1:317:3 | call to foo | | calls.rb:317:1:317:6 | call to []= | calls.rb:317:1:317:3 | call to foo | -| calls.rb:318:1:318:8 | call to [] | calls.rb:318:1:318:8 | __synth__0 | +| calls.rb:318:1:318:8 | call to [] | calls.rb:318:1:318:8 | __synth__3 | | calls.rb:318:1:318:8 | call to foo | calls.rb:318:1:318:4 | self | -| calls.rb:318:1:318:8 | call to foo= | calls.rb:318:1:318:4 | self | -| calls.rb:318:12:318:19 | call to [] | calls.rb:318:12:318:19 | __synth__0 | +| calls.rb:318:1:318:8 | call to foo | calls.rb:318:1:318:8 | __synth__0 | +| calls.rb:318:1:318:8 | call to foo= | calls.rb:318:1:318:8 | __synth__0 | +| calls.rb:318:12:318:19 | call to [] | calls.rb:318:12:318:19 | __synth__3 | | calls.rb:318:12:318:19 | call to bar | calls.rb:318:12:318:15 | self | -| calls.rb:318:12:318:19 | call to bar= | calls.rb:318:12:318:15 | self | +| calls.rb:318:12:318:19 | call to bar | calls.rb:318:12:318:19 | __synth__1 | +| calls.rb:318:12:318:19 | call to bar= | calls.rb:318:12:318:19 | __synth__1 | | calls.rb:318:22:318:24 | call to foo | calls.rb:318:22:318:24 | self | | calls.rb:318:22:318:27 | ...[...] | calls.rb:318:22:318:24 | call to foo | -| calls.rb:318:22:318:27 | call to [] | calls.rb:318:22:318:27 | __synth__0 | -| calls.rb:318:22:318:27 | call to []= | calls.rb:318:22:318:24 | call to foo | +| calls.rb:318:22:318:27 | call to [] | calls.rb:318:22:318:27 | __synth__2 | +| calls.rb:318:22:318:27 | call to [] | calls.rb:318:22:318:27 | __synth__3 | +| calls.rb:318:22:318:27 | call to []= | calls.rb:318:22:318:27 | __synth__2 | | calls.rb:318:31:318:42 | * ... | calls.rb:318:31:318:42 | [...] | | calls.rb:318:31:318:42 | call to [] | calls.rb:318:31:318:42 | Array | -| calls.rb:319:1:319:1 | call to [] | calls.rb:319:1:319:1 | __synth__0 | +| calls.rb:319:1:319:1 | call to [] | calls.rb:319:1:319:1 | __synth__2 | | calls.rb:319:5:319:7 | call to foo | calls.rb:319:5:319:7 | self | | calls.rb:319:5:319:10 | ...[...] | calls.rb:319:5:319:7 | call to foo | -| calls.rb:319:5:319:10 | call to [] | calls.rb:319:5:319:10 | __synth__0 | -| calls.rb:319:5:319:10 | call to []= | calls.rb:319:5:319:7 | call to foo | +| calls.rb:319:5:319:10 | call to [] | calls.rb:319:5:319:10 | __synth__1 | +| calls.rb:319:5:319:10 | call to [] | calls.rb:319:5:319:10 | __synth__2 | +| calls.rb:319:5:319:10 | call to []= | calls.rb:319:5:319:10 | __synth__1 | | calls.rb:319:14:319:22 | * ... | calls.rb:319:14:319:22 | [...] | | calls.rb:319:14:319:22 | call to [] | calls.rb:319:14:319:22 | Array | | calls.rb:320:1:320:10 | call to count | calls.rb:320:1:320:4 | __synth__0 | @@ -370,9 +376,9 @@ callsWithReceiver | calls.rb:338:3:338:13 | call to bar | calls.rb:338:3:338:13 | self | | calls.rb:342:1:344:3 | * ... | calls.rb:342:1:344:3 | __synth__0__1 | | calls.rb:342:1:344:3 | call to each | calls.rb:342:16:342:33 | [...] | -| calls.rb:342:5:342:5 | call to [] | calls.rb:342:5:342:5 | __synth__0__1 | -| calls.rb:342:8:342:8 | call to [] | calls.rb:342:8:342:8 | __synth__0__1 | -| calls.rb:342:11:342:11 | call to [] | calls.rb:342:11:342:11 | __synth__0__1 | +| calls.rb:342:5:342:5 | call to [] | calls.rb:342:5:342:5 | __synth__3__1 | +| calls.rb:342:8:342:8 | call to [] | calls.rb:342:8:342:8 | __synth__3__1 | +| calls.rb:342:11:342:11 | call to [] | calls.rb:342:11:342:11 | __synth__3__1 | | calls.rb:342:16:342:33 | call to [] | calls.rb:342:16:342:33 | Array | | calls.rb:342:17:342:23 | call to [] | calls.rb:342:17:342:23 | Array | | calls.rb:342:26:342:32 | call to [] | calls.rb:342:26:342:32 | Array | diff --git a/ruby/ql/test/library-tests/controlflow/graph/Cfg.expected b/ruby/ql/test/library-tests/controlflow/graph/Cfg.expected index bb43be4a082..8414c6df8c5 100644 --- a/ruby/ql/test/library-tests/controlflow/graph/Cfg.expected +++ b/ruby/ql/test/library-tests/controlflow/graph/Cfg.expected @@ -2083,7 +2083,7 @@ cfg.rb: #-----| -> constant # 61| ... = ... -#-----| -> __synth__0 +#-----| -> __synth__2 # 61| "constant" #-----| -> ... = ... @@ -2095,19 +2095,19 @@ cfg.rb: #-----| -> pattern # 62| ... = ... -#-----| -> __synth__0__1 +#-----| -> __synth__2__1 # 62| 0 #-----| -> call to [] -# 62| __synth__0 +# 62| __synth__2 #-----| -> 0 # 62| call to [] #-----| -> ... = ... # 62| x -#-----| -> __synth__0 +#-----| -> __synth__2 # 62| * ... #-----| -> ... = ... @@ -2121,11 +2121,11 @@ cfg.rb: # 62| 1 #-----| -> call to [] -# 62| __synth__0 +# 62| __synth__2 #-----| -> 1 -# 62| __synth__0__1 -#-----| -> __synth__0 +# 62| __synth__2__1 +#-----| -> __synth__2 # 62| call to [] #-----| -> * ... @@ -2136,14 +2136,14 @@ cfg.rb: # 62| 0 #-----| -> call to [] -# 62| __synth__0__1 +# 62| __synth__2__1 #-----| -> 0 # 62| call to [] #-----| -> ... = ... # 62| y -#-----| -> __synth__0__1 +#-----| -> __synth__2__1 # 62| ... = ... #-----| -> ... @@ -2151,14 +2151,14 @@ cfg.rb: # 62| 1 #-----| -> call to [] -# 62| __synth__0__1 +# 62| __synth__2__1 #-----| -> 1 # 62| call to [] #-----| -> ... = ... # 62| z -#-----| -> __synth__0__1 +#-----| -> __synth__2__1 # 62| * ... #-----| -> ... = ... @@ -2169,7 +2169,7 @@ cfg.rb: # 62| Array #-----| -> 1 -# 62| __synth__0 +# 62| __synth__2 #-----| -> Array # 62| call to [] @@ -2918,7 +2918,7 @@ cfg.rb: #-----| raise -> self # 136| ... rescue ... -#-----| -> __synth__0 +#-----| -> __synth__2 # 136| 0 #-----| -> ... / ... @@ -2950,14 +2950,14 @@ cfg.rb: # 138| _ .. _ #-----| -> call to [] -# 138| __synth__0 +# 138| __synth__2 #-----| -> 0 # 138| call to [] #-----| -> ... = ... # 138| init -#-----| -> __synth__0 +#-----| -> __synth__2 # 138| -1 #-----| -> call to [] @@ -2965,14 +2965,14 @@ cfg.rb: # 138| ... = ... #-----| -> ... -# 138| __synth__0 +# 138| __synth__2 #-----| -> -1 # 138| call to [] #-----| -> ... = ... # 138| last -#-----| -> __synth__0 +#-----| -> __synth__2 # 138| 1 #-----| -> 2 @@ -2986,7 +2986,7 @@ cfg.rb: # 138| ..., ... #-----| -> * ... -# 138| __synth__0 +# 138| __synth__2 #-----| -> 1 # 138| 2 @@ -4151,7 +4151,7 @@ desugar.rb: #-----| -> ... + ... # 21| enter m6 -#-----| -> __synth__0 +#-----| -> __synth__2 # 21| exit m6 @@ -4167,14 +4167,14 @@ desugar.rb: # 22| 0 #-----| -> call to [] -# 22| __synth__0 +# 22| __synth__3 #-----| -> 0 # 22| call to [] #-----| -> ... = ... # 22| x -#-----| -> __synth__0 +#-----| -> __synth__3 # 22| ... #-----| -> exit m6 (normal) @@ -4183,7 +4183,7 @@ desugar.rb: #-----| -> _ .. _ # 22| ... = ... -#-----| -> self +#-----| -> __synth__2 # 22| 1 #-----| -> -2 @@ -4191,17 +4191,23 @@ desugar.rb: # 22| _ .. _ #-----| -> call to [] -# 22| __synth__0 +# 22| __synth__3 #-----| -> 1 # 22| call to [] #-----| -> ... = ... # 22| y -#-----| -> __synth__0 +#-----| -> __synth__3 + +# 22| ... = ... +#-----| -> __synth__3 + +# 22| __synth__2 +#-----| -> self # 22| call to z -#-----| -> __synth__0__1 +#-----| -> ... = ... # 22| self #-----| -> call to z @@ -4215,14 +4221,17 @@ desugar.rb: # 22| ... = ... #-----| -> call to bar= -# 22| __synth__0 -#-----| -> -1 - # 22| __synth__0__1 #-----| -> ... # 22| __synth__0__1 -#-----| -> __synth__0 +#-----| -> __synth__3 + +# 22| __synth__2 +#-----| -> __synth__0__1 + +# 22| __synth__3 +#-----| -> -1 # 22| call to [] #-----| -> ... = ... @@ -4239,7 +4248,7 @@ desugar.rb: # 22| Array #-----| -> 1 -# 22| __synth__0 +# 22| __synth__3 #-----| -> Array # 22| call to [] @@ -4258,7 +4267,7 @@ desugar.rb: #-----| -> call to [] # 25| enter m7 -#-----| -> __synth__0 +#-----| -> __synth__2 # 25| exit m7 @@ -4269,19 +4278,19 @@ desugar.rb: #-----| -> X # 26| ... = ... -#-----| -> __synth__0__1 +#-----| -> __synth__2__1 # 26| 0 #-----| -> call to [] -# 26| __synth__0 +# 26| __synth__2 #-----| -> 0 # 26| call to [] #-----| -> ... = ... # 26| x -#-----| -> __synth__0 +#-----| -> __synth__2 # 26| ... #-----| -> exit m7 (normal) @@ -4298,11 +4307,11 @@ desugar.rb: # 26| 1 #-----| -> call to [] -# 26| __synth__0 +# 26| __synth__2 #-----| -> 1 -# 26| __synth__0__1 -#-----| -> __synth__0 +# 26| __synth__2__1 +#-----| -> __synth__2 # 26| call to [] #-----| -> * ... @@ -4313,14 +4322,14 @@ desugar.rb: # 26| 0 #-----| -> call to [] -# 26| __synth__0__1 +# 26| __synth__2__1 #-----| -> 0 # 26| call to [] #-----| -> ... = ... # 26| y -#-----| -> __synth__0__1 +#-----| -> __synth__2__1 # 26| ... = ... #-----| -> ... @@ -4328,14 +4337,14 @@ desugar.rb: # 26| 1 #-----| -> call to [] -# 26| __synth__0__1 +# 26| __synth__2__1 #-----| -> 1 # 26| call to [] #-----| -> ... = ... # 26| z -#-----| -> __synth__0__1 +#-----| -> __synth__2__1 # 26| * ... #-----| -> ... = ... @@ -4346,7 +4355,7 @@ desugar.rb: # 26| Array #-----| -> 1 -# 26| __synth__0 +# 26| __synth__2 #-----| -> Array # 26| call to [] diff --git a/ruby/ql/test/library-tests/dataflow/array-flow/array-flow.expected b/ruby/ql/test/library-tests/dataflow/array-flow/array-flow.expected index 2e813207b6a..35bbaabef87 100644 --- a/ruby/ql/test/library-tests/dataflow/array-flow/array-flow.expected +++ b/ruby/ql/test/library-tests/dataflow/array-flow/array-flow.expected @@ -203,10 +203,10 @@ edges | array_flow.rb:80:13:80:21 | call to source : | array_flow.rb:80:5:80:5 | a [element 1] : | | array_flow.rb:81:8:81:8 | c : | array_flow.rb:83:10:83:10 | c | | array_flow.rb:81:8:81:8 | c : | array_flow.rb:83:10:83:10 | c | -| array_flow.rb:81:15:81:15 | __synth__0 [element 1] : | array_flow.rb:81:8:81:8 | c : | -| array_flow.rb:81:15:81:15 | __synth__0 [element 1] : | array_flow.rb:81:8:81:8 | c : | -| array_flow.rb:81:15:81:15 | a [element 1] : | array_flow.rb:81:15:81:15 | __synth__0 [element 1] : | -| array_flow.rb:81:15:81:15 | a [element 1] : | array_flow.rb:81:15:81:15 | __synth__0 [element 1] : | +| array_flow.rb:81:15:81:15 | __synth__3 [element 1] : | array_flow.rb:81:8:81:8 | c : | +| array_flow.rb:81:15:81:15 | __synth__3 [element 1] : | array_flow.rb:81:8:81:8 | c : | +| array_flow.rb:81:15:81:15 | a [element 1] : | array_flow.rb:81:15:81:15 | __synth__3 [element 1] : | +| array_flow.rb:81:15:81:15 | a [element 1] : | array_flow.rb:81:15:81:15 | __synth__3 [element 1] : | | array_flow.rb:88:5:88:5 | a [element 1] : | array_flow.rb:89:9:89:9 | a [element 1] : | | array_flow.rb:88:5:88:5 | a [element 1] : | array_flow.rb:89:9:89:9 | a [element 1] : | | array_flow.rb:88:13:88:22 | call to source : | array_flow.rb:88:5:88:5 | a [element 1] : | @@ -4460,8 +4460,8 @@ nodes | array_flow.rb:80:13:80:21 | call to source : | semmle.label | call to source : | | array_flow.rb:81:8:81:8 | c : | semmle.label | c : | | array_flow.rb:81:8:81:8 | c : | semmle.label | c : | -| array_flow.rb:81:15:81:15 | __synth__0 [element 1] : | semmle.label | __synth__0 [element 1] : | -| array_flow.rb:81:15:81:15 | __synth__0 [element 1] : | semmle.label | __synth__0 [element 1] : | +| array_flow.rb:81:15:81:15 | __synth__3 [element 1] : | semmle.label | __synth__3 [element 1] : | +| array_flow.rb:81:15:81:15 | __synth__3 [element 1] : | semmle.label | __synth__3 [element 1] : | | array_flow.rb:81:15:81:15 | a [element 1] : | semmle.label | a [element 1] : | | array_flow.rb:81:15:81:15 | a [element 1] : | semmle.label | a [element 1] : | | array_flow.rb:83:10:83:10 | c | semmle.label | c | diff --git a/ruby/ql/test/library-tests/variables/ssa.expected b/ruby/ql/test/library-tests/variables/ssa.expected index a285f5f8cc4..962cd733a08 100644 --- a/ruby/ql/test/library-tests/variables/ssa.expected +++ b/ruby/ql/test/library-tests/variables/ssa.expected @@ -96,10 +96,10 @@ definition | scopes.rb:11:4:11:4 | a | scopes.rb:7:1:7:1 | a | | scopes.rb:13:4:13:4 | a | scopes.rb:7:1:7:1 | a | | scopes.rb:13:7:13:7 | b | scopes.rb:13:7:13:7 | b | -| scopes.rb:13:10:13:15 | __synth__0__1 | scopes.rb:13:10:13:15 | __synth__0__1 | +| scopes.rb:13:10:13:15 | __synth__2__1 | scopes.rb:13:10:13:15 | __synth__2__1 | | scopes.rb:13:11:13:11 | c | scopes.rb:13:11:13:11 | c | | scopes.rb:13:14:13:14 | d | scopes.rb:13:14:13:14 | d | -| scopes.rb:13:19:13:32 | __synth__0 | scopes.rb:13:4:13:32 | __synth__0 | +| scopes.rb:13:19:13:32 | __synth__3 | scopes.rb:13:4:13:32 | __synth__3 | | scopes.rb:26:1:26:12 | self (A) | scopes.rb:26:1:26:12 | self | | scopes.rb:27:1:27:1 | x | scopes.rb:27:1:27:1 | x | | scopes.rb:28:1:30:3 | self (B) | scopes.rb:28:1:30:3 | self | @@ -282,13 +282,13 @@ read | scopes.rb:11:4:11:4 | a | scopes.rb:7:1:7:1 | a | scopes.rb:12:9:12:9 | a | | scopes.rb:13:4:13:4 | a | scopes.rb:7:1:7:1 | a | scopes.rb:14:9:14:9 | a | | scopes.rb:13:7:13:7 | b | scopes.rb:13:7:13:7 | b | scopes.rb:15:9:15:9 | b | -| scopes.rb:13:10:13:15 | __synth__0__1 | scopes.rb:13:10:13:15 | __synth__0__1 | scopes.rb:13:11:13:11 | __synth__0__1 | -| scopes.rb:13:10:13:15 | __synth__0__1 | scopes.rb:13:10:13:15 | __synth__0__1 | scopes.rb:13:14:13:14 | __synth__0__1 | +| scopes.rb:13:10:13:15 | __synth__2__1 | scopes.rb:13:10:13:15 | __synth__2__1 | scopes.rb:13:11:13:11 | __synth__2__1 | +| scopes.rb:13:10:13:15 | __synth__2__1 | scopes.rb:13:10:13:15 | __synth__2__1 | scopes.rb:13:14:13:14 | __synth__2__1 | | scopes.rb:13:11:13:11 | c | scopes.rb:13:11:13:11 | c | scopes.rb:16:9:16:9 | c | | scopes.rb:13:14:13:14 | d | scopes.rb:13:14:13:14 | d | scopes.rb:17:9:17:9 | d | -| scopes.rb:13:19:13:32 | __synth__0 | scopes.rb:13:4:13:32 | __synth__0 | scopes.rb:13:4:13:4 | __synth__0 | -| scopes.rb:13:19:13:32 | __synth__0 | scopes.rb:13:4:13:32 | __synth__0 | scopes.rb:13:7:13:7 | __synth__0 | -| scopes.rb:13:19:13:32 | __synth__0 | scopes.rb:13:4:13:32 | __synth__0 | scopes.rb:13:10:13:15 | __synth__0 | +| scopes.rb:13:19:13:32 | __synth__3 | scopes.rb:13:4:13:32 | __synth__3 | scopes.rb:13:4:13:4 | __synth__3 | +| scopes.rb:13:19:13:32 | __synth__3 | scopes.rb:13:4:13:32 | __synth__3 | scopes.rb:13:7:13:7 | __synth__3 | +| scopes.rb:13:19:13:32 | __synth__3 | scopes.rb:13:4:13:32 | __synth__3 | scopes.rb:13:10:13:15 | __synth__3 | | scopes.rb:27:1:27:1 | x | scopes.rb:27:1:27:1 | x | scopes.rb:28:8:28:8 | x | | scopes.rb:27:1:27:1 | x | scopes.rb:27:1:27:1 | x | scopes.rb:31:10:31:10 | x | | scopes.rb:27:1:27:1 | x | scopes.rb:27:1:27:1 | x | scopes.rb:34:7:34:7 | x | @@ -454,10 +454,10 @@ firstRead | scopes.rb:11:4:11:4 | a | scopes.rb:7:1:7:1 | a | scopes.rb:12:9:12:9 | a | | scopes.rb:13:4:13:4 | a | scopes.rb:7:1:7:1 | a | scopes.rb:14:9:14:9 | a | | scopes.rb:13:7:13:7 | b | scopes.rb:13:7:13:7 | b | scopes.rb:15:9:15:9 | b | -| scopes.rb:13:10:13:15 | __synth__0__1 | scopes.rb:13:10:13:15 | __synth__0__1 | scopes.rb:13:11:13:11 | __synth__0__1 | +| scopes.rb:13:10:13:15 | __synth__2__1 | scopes.rb:13:10:13:15 | __synth__2__1 | scopes.rb:13:11:13:11 | __synth__2__1 | | scopes.rb:13:11:13:11 | c | scopes.rb:13:11:13:11 | c | scopes.rb:16:9:16:9 | c | | scopes.rb:13:14:13:14 | d | scopes.rb:13:14:13:14 | d | scopes.rb:17:9:17:9 | d | -| scopes.rb:13:19:13:32 | __synth__0 | scopes.rb:13:4:13:32 | __synth__0 | scopes.rb:13:4:13:4 | __synth__0 | +| scopes.rb:13:19:13:32 | __synth__3 | scopes.rb:13:4:13:32 | __synth__3 | scopes.rb:13:4:13:4 | __synth__3 | | scopes.rb:27:1:27:1 | x | scopes.rb:27:1:27:1 | x | scopes.rb:28:8:28:8 | x | | scopes.rb:41:1:49:3 | self (M) | scopes.rb:41:1:49:3 | self | scopes.rb:45:5:45:7 | self | | scopes.rb:42:2:42:4 | var | scopes.rb:42:2:42:4 | var | scopes.rb:44:5:44:7 | var | @@ -604,10 +604,10 @@ lastRead | scopes.rb:11:4:11:4 | a | scopes.rb:7:1:7:1 | a | scopes.rb:12:9:12:9 | a | | scopes.rb:13:4:13:4 | a | scopes.rb:7:1:7:1 | a | scopes.rb:14:9:14:9 | a | | scopes.rb:13:7:13:7 | b | scopes.rb:13:7:13:7 | b | scopes.rb:15:9:15:9 | b | -| scopes.rb:13:10:13:15 | __synth__0__1 | scopes.rb:13:10:13:15 | __synth__0__1 | scopes.rb:13:14:13:14 | __synth__0__1 | +| scopes.rb:13:10:13:15 | __synth__2__1 | scopes.rb:13:10:13:15 | __synth__2__1 | scopes.rb:13:14:13:14 | __synth__2__1 | | scopes.rb:13:11:13:11 | c | scopes.rb:13:11:13:11 | c | scopes.rb:16:9:16:9 | c | | scopes.rb:13:14:13:14 | d | scopes.rb:13:14:13:14 | d | scopes.rb:17:9:17:9 | d | -| scopes.rb:13:19:13:32 | __synth__0 | scopes.rb:13:4:13:32 | __synth__0 | scopes.rb:13:10:13:15 | __synth__0 | +| scopes.rb:13:19:13:32 | __synth__3 | scopes.rb:13:4:13:32 | __synth__3 | scopes.rb:13:10:13:15 | __synth__3 | | scopes.rb:27:1:27:1 | x | scopes.rb:27:1:27:1 | x | scopes.rb:37:5:37:5 | x | | scopes.rb:41:1:49:3 | self (M) | scopes.rb:41:1:49:3 | self | scopes.rb:45:5:45:7 | self | | scopes.rb:42:2:42:4 | var | scopes.rb:42:2:42:4 | var | scopes.rb:44:5:44:7 | var | @@ -693,9 +693,9 @@ adjacentReads | scopes.rb:9:9:18:3 | <captured entry> self | scopes.rb:1:1:49:4 | self | scopes.rb:14:4:14:9 | self | scopes.rb:15:4:15:9 | self | | scopes.rb:9:9:18:3 | <captured entry> self | scopes.rb:1:1:49:4 | self | scopes.rb:15:4:15:9 | self | scopes.rb:16:4:16:9 | self | | scopes.rb:9:9:18:3 | <captured entry> self | scopes.rb:1:1:49:4 | self | scopes.rb:16:4:16:9 | self | scopes.rb:17:4:17:9 | self | -| scopes.rb:13:10:13:15 | __synth__0__1 | scopes.rb:13:10:13:15 | __synth__0__1 | scopes.rb:13:11:13:11 | __synth__0__1 | scopes.rb:13:14:13:14 | __synth__0__1 | -| scopes.rb:13:19:13:32 | __synth__0 | scopes.rb:13:4:13:32 | __synth__0 | scopes.rb:13:4:13:4 | __synth__0 | scopes.rb:13:7:13:7 | __synth__0 | -| scopes.rb:13:19:13:32 | __synth__0 | scopes.rb:13:4:13:32 | __synth__0 | scopes.rb:13:7:13:7 | __synth__0 | scopes.rb:13:10:13:15 | __synth__0 | +| scopes.rb:13:10:13:15 | __synth__2__1 | scopes.rb:13:10:13:15 | __synth__2__1 | scopes.rb:13:11:13:11 | __synth__2__1 | scopes.rb:13:14:13:14 | __synth__2__1 | +| scopes.rb:13:19:13:32 | __synth__3 | scopes.rb:13:4:13:32 | __synth__3 | scopes.rb:13:4:13:4 | __synth__3 | scopes.rb:13:7:13:7 | __synth__3 | +| scopes.rb:13:19:13:32 | __synth__3 | scopes.rb:13:4:13:32 | __synth__3 | scopes.rb:13:7:13:7 | __synth__3 | scopes.rb:13:10:13:15 | __synth__3 | | scopes.rb:27:1:27:1 | x | scopes.rb:27:1:27:1 | x | scopes.rb:28:8:28:8 | x | scopes.rb:31:10:31:10 | x | | scopes.rb:27:1:27:1 | x | scopes.rb:27:1:27:1 | x | scopes.rb:31:10:31:10 | x | scopes.rb:34:7:34:7 | x | | scopes.rb:27:1:27:1 | x | scopes.rb:27:1:27:1 | x | scopes.rb:34:7:34:7 | x | scopes.rb:34:14:34:14 | x | diff --git a/ruby/ql/test/library-tests/variables/varaccess.expected b/ruby/ql/test/library-tests/variables/varaccess.expected index 4443373e8c2..82bc6c8cd58 100644 --- a/ruby/ql/test/library-tests/variables/varaccess.expected +++ b/ruby/ql/test/library-tests/variables/varaccess.expected @@ -332,12 +332,12 @@ explicitWrite | scopes.rb:13:4:13:4 | a | scopes.rb:13:4:13:32 | ... = ... | | scopes.rb:13:7:13:7 | b | scopes.rb:13:4:13:32 | ... = ... | | scopes.rb:13:7:13:7 | b | scopes.rb:13:7:13:7 | ... = ... | -| scopes.rb:13:10:13:15 | __synth__0__1 | scopes.rb:13:10:13:15 | ... = ... | +| scopes.rb:13:10:13:15 | __synth__2__1 | scopes.rb:13:10:13:15 | ... = ... | | scopes.rb:13:11:13:11 | c | scopes.rb:13:4:13:32 | ... = ... | | scopes.rb:13:11:13:11 | c | scopes.rb:13:11:13:11 | ... = ... | | scopes.rb:13:14:13:14 | d | scopes.rb:13:4:13:32 | ... = ... | | scopes.rb:13:14:13:14 | d | scopes.rb:13:14:13:14 | ... = ... | -| scopes.rb:13:19:13:32 | __synth__0 | scopes.rb:13:19:13:32 | ... = ... | +| scopes.rb:13:19:13:32 | __synth__3 | scopes.rb:13:19:13:32 | ... = ... | | scopes.rb:21:1:21:7 | $global | scopes.rb:21:1:21:12 | ... = ... | | scopes.rb:24:1:24:6 | script | scopes.rb:24:1:24:11 | ... = ... | | scopes.rb:27:1:27:1 | x | scopes.rb:27:1:27:5 | ... = ... | @@ -525,11 +525,11 @@ readAccess | scopes.rb:11:4:11:4 | a | | scopes.rb:12:4:12:9 | self | | scopes.rb:12:9:12:9 | a | -| scopes.rb:13:4:13:4 | __synth__0 | -| scopes.rb:13:7:13:7 | __synth__0 | -| scopes.rb:13:10:13:15 | __synth__0 | -| scopes.rb:13:11:13:11 | __synth__0__1 | -| scopes.rb:13:14:13:14 | __synth__0__1 | +| scopes.rb:13:4:13:4 | __synth__3 | +| scopes.rb:13:7:13:7 | __synth__3 | +| scopes.rb:13:10:13:15 | __synth__3 | +| scopes.rb:13:11:13:11 | __synth__2__1 | +| scopes.rb:13:14:13:14 | __synth__2__1 | | scopes.rb:14:4:14:9 | self | | scopes.rb:14:9:14:9 | a | | scopes.rb:15:4:15:9 | self | diff --git a/ruby/ql/test/library-tests/variables/variable.expected b/ruby/ql/test/library-tests/variables/variable.expected index ccab8a3cdf4..55288f74088 100644 --- a/ruby/ql/test/library-tests/variables/variable.expected +++ b/ruby/ql/test/library-tests/variables/variable.expected @@ -100,8 +100,13 @@ | scopes.rb:7:1:7:1 | a | | scopes.rb:9:14:9:14 | x | | scopes.rb:13:4:13:32 | __synth__0 | +| scopes.rb:13:4:13:32 | __synth__1 | +| scopes.rb:13:4:13:32 | __synth__2 | +| scopes.rb:13:4:13:32 | __synth__3 | | scopes.rb:13:7:13:7 | b | | scopes.rb:13:10:13:15 | __synth__0__1 | +| scopes.rb:13:10:13:15 | __synth__1__1 | +| scopes.rb:13:10:13:15 | __synth__2__1 | | scopes.rb:13:11:13:11 | c | | scopes.rb:13:14:13:14 | d | | scopes.rb:24:1:24:6 | script | From a819797508bb9532db88a4b03cab6f0f1360263a Mon Sep 17 00:00:00 2001 From: Arthur Baars <aibaars@github.com> Date: Tue, 21 Mar 2023 18:45:07 +0100 Subject: [PATCH 474/631] Ruby: add test case of destructured assignment with contants --- ruby/ql/test/library-tests/ast/Ast.expected | 10 +++++++ .../library-tests/ast/AstDesugar.expected | 27 +++++++++++++++++++ .../library-tests/ast/TreeSitter.expected | 21 +++++++++++++++ .../test/library-tests/ast/ValueText.expected | 12 +++++++++ .../ast/operations/assignment.expected | 5 ++++ .../ast/operations/operation.expected | 11 ++++++++ .../ast/operations/operations.rb | 1 + .../ast/operations/unary.expected | 1 + 8 files changed, 88 insertions(+) diff --git a/ruby/ql/test/library-tests/ast/Ast.expected b/ruby/ql/test/library-tests/ast/Ast.expected index 88129998d06..97d154c4175 100644 --- a/ruby/ql/test/library-tests/ast/Ast.expected +++ b/ruby/ql/test/library-tests/ast/Ast.expected @@ -2878,6 +2878,16 @@ operations/operations.rb: # 103| getStmt: [AssignLogicalOrExpr] ... ||= ... # 103| getAnOperand/getLeftOperand: [ConstantAssignment, ConstantReadAccess] CONSTANT4 # 103| getAnOperand/getRightOperand: [IntegerLiteral] 7 +# 104| getStmt: [AssignExpr] ... = ... +# 104| getAnOperand/getLeftOperand: [DestructuredLhsExpr] (..., ...) +# 104| getElement: [ConstantAssignment] FOO +# 104| getElement: [ConstantAssignment] BAR +# 104| getElement: [ConstantAssignment] FOO +# 104| getScopeExpr: [LocalVariableAccess] foo +# 104| getAnOperand/getRightOperand: [ArrayLiteral] [...] +# 104| getElement: [IntegerLiteral] 1 +# 104| getElement: [IntegerLiteral] 2 +# 104| getElement: [IntegerLiteral] 3 params/params.rb: # 1| [Toplevel] params.rb # 4| getStmt: [Method] identifier_method_params diff --git a/ruby/ql/test/library-tests/ast/AstDesugar.expected b/ruby/ql/test/library-tests/ast/AstDesugar.expected index f31e590b825..06b600c1fb6 100644 --- a/ruby/ql/test/library-tests/ast/AstDesugar.expected +++ b/ruby/ql/test/library-tests/ast/AstDesugar.expected @@ -946,6 +946,33 @@ operations/operations.rb: # 103| getAnOperand/getRightOperand: [LogicalOrExpr] ... || ... # 103| getAnOperand/getLeftOperand/getReceiver: [ConstantReadAccess] CONSTANT4 # 103| getAnOperand/getArgument/getRightOperand: [IntegerLiteral] 7 +# 104| [AssignExpr] ... = ... +# 104| getDesugared: [StmtSequence] ... +# 104| getStmt: [AssignExpr] ... = ... +# 104| getAnOperand/getLeftOperand: [ConstantAssignment] FOO +# 104| getAnOperand/getRightOperand: [MethodCall] call to [] +# 104| getReceiver: [LocalVariableAccess] __synth__3 +# 104| getArgument: [IntegerLiteral] 0 +# 104| getStmt: [AssignExpr] ... = ... +# 104| getAnOperand/getLeftOperand: [ConstantAssignment] BAR +# 104| getAnOperand/getRightOperand: [MethodCall] call to [] +# 104| getReceiver: [LocalVariableAccess] __synth__3 +# 104| getArgument: [IntegerLiteral] 1 +# 104| getStmt: [AssignExpr] ... = ... +# 104| getAnOperand/getLeftOperand: [ConstantAssignment] FOO +# 104| getScopeExpr: [LocalVariableAccess] foo +# 104| getAnOperand/getRightOperand: [MethodCall] call to [] +# 104| getReceiver: [LocalVariableAccess] __synth__3 +# 104| getArgument: [IntegerLiteral] 2 +# 104| getStmt: [AssignExpr] ... = ... +# 104| getAnOperand/getLeftOperand: [LocalVariableAccess] __synth__3 +# 104| getAnOperand/getRightOperand: [SplatExpr] * ... +# 104| getAnOperand/getOperand/getReceiver: [ArrayLiteral] [...] +# 104| getDesugared: [MethodCall] call to [] +# 104| getReceiver: [ConstantReadAccess] Array +# 104| getArgument: [IntegerLiteral] 1 +# 104| getArgument: [IntegerLiteral] 2 +# 104| getArgument: [IntegerLiteral] 3 params/params.rb: # 8| [HashLiteral] {...} # 8| getDesugared: [MethodCall] call to [] diff --git a/ruby/ql/test/library-tests/ast/TreeSitter.expected b/ruby/ql/test/library-tests/ast/TreeSitter.expected index e8cf91b46e3..d62d635b0b3 100644 --- a/ruby/ql/test/library-tests/ast/TreeSitter.expected +++ b/ruby/ql/test/library-tests/ast/TreeSitter.expected @@ -5615,6 +5615,27 @@ operations/operations.rb: # 103| 1: [Constant] CONSTANT4 # 103| 1: [ReservedWord] ||= # 103| 2: [Integer] 7 +# 104| 72: [Assignment] Assignment +# 104| 0: [LeftAssignmentList] LeftAssignmentList +# 104| 0: [Constant] FOO +# 104| 1: [ReservedWord] , +# 104| 2: [ScopeResolution] ScopeResolution +# 104| 0: [ReservedWord] :: +# 104| 1: [Constant] BAR +# 104| 3: [ReservedWord] , +# 104| 4: [ScopeResolution] ScopeResolution +# 104| 0: [Identifier] foo +# 104| 1: [ReservedWord] :: +# 104| 2: [Constant] FOO +# 104| 1: [ReservedWord] = +# 104| 2: [Array] Array +# 104| 0: [ReservedWord] [ +# 104| 1: [Integer] 1 +# 104| 2: [ReservedWord] , +# 104| 3: [Integer] 2 +# 104| 4: [ReservedWord] , +# 104| 5: [Integer] 3 +# 104| 6: [ReservedWord] ] # 1| [Comment] # Start with assignments to all the identifiers used below, so that they are # 2| [Comment] # interpreted as variables. # 22| [Comment] # Unary operations diff --git a/ruby/ql/test/library-tests/ast/ValueText.expected b/ruby/ql/test/library-tests/ast/ValueText.expected index 3c9254d284a..612b58e41e3 100644 --- a/ruby/ql/test/library-tests/ast/ValueText.expected +++ b/ruby/ql/test/library-tests/ast/ValueText.expected @@ -903,6 +903,12 @@ exprValue | operations/operations.rb:102:5:102:5 | 1 | 1 | int | | operations/operations.rb:102:31:102:31 | 7 | 7 | int | | operations/operations.rb:103:17:103:17 | 7 | 7 | int | +| operations/operations.rb:104:1:104:3 | 0 | 0 | int | +| operations/operations.rb:104:6:104:10 | 1 | 1 | int | +| operations/operations.rb:104:13:104:20 | 2 | 2 | int | +| operations/operations.rb:104:25:104:25 | 1 | 1 | int | +| operations/operations.rb:104:28:104:28 | 2 | 2 | int | +| operations/operations.rb:104:31:104:31 | 3 | 3 | int | | params/params.rb:41:46:41:46 | 7 | 7 | int | | params/params.rb:47:19:47:21 | :bar | :bar | symbol | | params/params.rb:47:24:47:24 | 2 | 2 | int | @@ -1792,6 +1798,12 @@ exprCfgNodeValue | operations/operations.rb:102:5:102:5 | 1 | 1 | int | | operations/operations.rb:102:31:102:31 | 7 | 7 | int | | operations/operations.rb:103:17:103:17 | 7 | 7 | int | +| operations/operations.rb:104:1:104:3 | 0 | 0 | int | +| operations/operations.rb:104:6:104:10 | 1 | 1 | int | +| operations/operations.rb:104:13:104:20 | 2 | 2 | int | +| operations/operations.rb:104:25:104:25 | 1 | 1 | int | +| operations/operations.rb:104:28:104:28 | 2 | 2 | int | +| operations/operations.rb:104:31:104:31 | 3 | 3 | int | | params/params.rb:41:46:41:46 | 7 | 7 | int | | params/params.rb:47:19:47:21 | :bar | :bar | symbol | | params/params.rb:47:24:47:24 | 2 | 2 | int | diff --git a/ruby/ql/test/library-tests/ast/operations/assignment.expected b/ruby/ql/test/library-tests/ast/operations/assignment.expected index ef88dc1751a..e22a0711065 100644 --- a/ruby/ql/test/library-tests/ast/operations/assignment.expected +++ b/ruby/ql/test/library-tests/ast/operations/assignment.expected @@ -65,6 +65,11 @@ assignments | operations.rb:102:1:102:31 | ... \|\|= ... | \|\|= | operations.rb:102:1:102:25 | OtherConstant | operations.rb:102:31:102:31 | 7 | AssignLogicalOrExpr | | operations.rb:103:1:103:17 | ... = ... | = | operations.rb:103:1:103:11 | CONSTANT4 | operations.rb:103:13:103:15 | ... \|\| ... | AssignExpr | | operations.rb:103:1:103:17 | ... \|\|= ... | \|\|= | operations.rb:103:1:103:11 | CONSTANT4 | operations.rb:103:17:103:17 | 7 | AssignLogicalOrExpr | +| operations.rb:104:1:104:3 | ... = ... | = | operations.rb:104:1:104:3 | FOO | operations.rb:104:1:104:3 | call to [] | AssignExpr | +| operations.rb:104:1:104:32 | ... = ... | = | operations.rb:104:1:104:20 | (..., ...) | operations.rb:104:24:104:32 | [...] | AssignExpr | +| operations.rb:104:6:104:10 | ... = ... | = | operations.rb:104:6:104:10 | BAR | operations.rb:104:6:104:10 | call to [] | AssignExpr | +| operations.rb:104:13:104:20 | ... = ... | = | operations.rb:104:13:104:20 | FOO | operations.rb:104:13:104:20 | call to [] | AssignExpr | +| operations.rb:104:24:104:32 | ... = ... | = | operations.rb:104:24:104:32 | __synth__3 | operations.rb:104:24:104:32 | * ... | AssignExpr | assignOperations | operations.rb:69:1:69:8 | ... += ... | += | operations.rb:69:1:69:1 | x | operations.rb:69:6:69:8 | 128 | AssignAddExpr | | operations.rb:70:1:70:7 | ... -= ... | -= | operations.rb:70:1:70:1 | y | operations.rb:70:6:70:7 | 32 | AssignSubExpr | diff --git a/ruby/ql/test/library-tests/ast/operations/operation.expected b/ruby/ql/test/library-tests/ast/operations/operation.expected index 0f74eb28fb3..71f65d65b74 100644 --- a/ruby/ql/test/library-tests/ast/operations/operation.expected +++ b/ruby/ql/test/library-tests/ast/operations/operation.expected @@ -230,3 +230,14 @@ | operations.rb:103:1:103:17 | ... \|\|= ... | \|\|= | operations.rb:103:17:103:17 | 7 | AssignLogicalOrExpr | | operations.rb:103:13:103:15 | ... \|\| ... | \|\| | operations.rb:103:1:103:11 | CONSTANT4 | LogicalOrExpr | | operations.rb:103:13:103:15 | ... \|\| ... | \|\| | operations.rb:103:17:103:17 | 7 | LogicalOrExpr | +| operations.rb:104:1:104:3 | ... = ... | = | operations.rb:104:1:104:3 | FOO | AssignExpr | +| operations.rb:104:1:104:3 | ... = ... | = | operations.rb:104:1:104:3 | call to [] | AssignExpr | +| operations.rb:104:1:104:32 | ... = ... | = | operations.rb:104:1:104:20 | (..., ...) | AssignExpr | +| operations.rb:104:1:104:32 | ... = ... | = | operations.rb:104:24:104:32 | [...] | AssignExpr | +| operations.rb:104:6:104:10 | ... = ... | = | operations.rb:104:6:104:10 | BAR | AssignExpr | +| operations.rb:104:6:104:10 | ... = ... | = | operations.rb:104:6:104:10 | call to [] | AssignExpr | +| operations.rb:104:13:104:20 | ... = ... | = | operations.rb:104:13:104:20 | FOO | AssignExpr | +| operations.rb:104:13:104:20 | ... = ... | = | operations.rb:104:13:104:20 | call to [] | AssignExpr | +| operations.rb:104:24:104:32 | * ... | * | operations.rb:104:24:104:32 | [...] | SplatExpr | +| operations.rb:104:24:104:32 | ... = ... | = | operations.rb:104:24:104:32 | * ... | AssignExpr | +| operations.rb:104:24:104:32 | ... = ... | = | operations.rb:104:24:104:32 | __synth__3 | AssignExpr | diff --git a/ruby/ql/test/library-tests/ast/operations/operations.rb b/ruby/ql/test/library-tests/ast/operations/operations.rb index 86fda3c7457..14fad78bbe3 100644 --- a/ruby/ql/test/library-tests/ast/operations/operations.rb +++ b/ruby/ql/test/library-tests/ast/operations/operations.rb @@ -101,3 +101,4 @@ CONSTANT3 ||= 7 Foo::MemberConstant ||= 8 foo(1).bar::OtherConstant ||= 7 ::CONSTANT4 ||= 7 +FOO, ::BAR, foo::FOO = [1, 2, 3] diff --git a/ruby/ql/test/library-tests/ast/operations/unary.expected b/ruby/ql/test/library-tests/ast/operations/unary.expected index 0190e9bcf56..43c23fff031 100644 --- a/ruby/ql/test/library-tests/ast/operations/unary.expected +++ b/ruby/ql/test/library-tests/ast/operations/unary.expected @@ -7,6 +7,7 @@ unaryOperations | operations.rb:28:1:28:12 | defined? ... | defined? | operations.rb:28:10:28:12 | foo | DefinedExpr | | operations.rb:29:20:29:23 | * ... | * | operations.rb:29:21:29:23 | [...] | SplatExpr | | operations.rb:29:31:29:42 | ** ... | ** | operations.rb:29:33:29:42 | {...} | HashSplatExpr | +| operations.rb:104:24:104:32 | * ... | * | operations.rb:104:24:104:32 | [...] | SplatExpr | unaryLogicalOperations | operations.rb:23:1:23:2 | ! ... | ! | operations.rb:23:2:23:2 | a | NotExpr | | operations.rb:24:1:24:5 | not ... | not | operations.rb:24:5:24:5 | b | NotExpr | From 9a8e138684911dfacbe3c5d60b03098c97aeee79 Mon Sep 17 00:00:00 2001 From: Arthur Baars <aibaars@github.com> Date: Tue, 21 Mar 2023 18:01:09 +0100 Subject: [PATCH 475/631] Ruby: also change evaluation order for scoped constants --- .../codeql/ruby/ast/internal/Synthesis.qll | 65 ++++++++++++++++--- .../library-tests/ast/AstDesugar.expected | 5 +- .../ast/operations/assignment.expected | 1 + .../ast/operations/operation.expected | 2 + 4 files changed, 62 insertions(+), 11 deletions(-) diff --git a/ruby/ql/lib/codeql/ruby/ast/internal/Synthesis.qll b/ruby/ql/lib/codeql/ruby/ast/internal/Synthesis.qll index c36af496991..e8f6d405ba3 100644 --- a/ruby/ql/lib/codeql/ruby/ast/internal/Synthesis.qll +++ b/ruby/ql/lib/codeql/ruby/ast/internal/Synthesis.qll @@ -950,6 +950,40 @@ private module DestructuredAssignDesugar { } } + abstract private class LhsWithReceiver extends Expr { + abstract Expr getReceiver(); + + abstract SynthKind getSynthKind(); + } + + private class LhsCall extends LhsWithReceiver instanceof MethodCall { + final override Expr getReceiver() { result = MethodCall.super.getReceiver() } + + final override SynthKind getSynthKind() { + result = MethodCallKind(super.getMethodName(), false, super.getNumberOfArguments()) + } + } + + private class LhsScopedConstant extends LhsWithReceiver, TScopeResolutionConstantAccess { + private Ruby::AstNode receiver; + private string name; + + LhsScopedConstant() { + exists(Ruby::ScopeResolution e, Ruby::Constant c | + this = TScopeResolutionConstantAccess(e, c) + | + receiver = e.getScope() and + name = c.getValue() + ) + } + + final string getName() { result = name } + + final override Expr getReceiver() { toGenerated(result) = receiver } + + final override SynthKind getSynthKind() { result = ConstantWriteAccessKind(name) } + } + pragma[nomagic] private predicate destructuredAssignSynthesis(AstNode parent, int i, Child child) { exists(DestructuredAssignExpr tae | @@ -958,7 +992,7 @@ private module DestructuredAssignDesugar { child = SynthChild(StmtSequenceKind()) or exists(AstNode seq | seq = TStmtSequenceSynth(tae, -1) | - exists(MethodCall mc, int j | mc = tae.getElement(j) | + exists(LhsWithReceiver mc, int j | mc = tae.getElement(j) | parent = seq and i = j and child = SynthChild(AssignExprKind()) @@ -1005,25 +1039,29 @@ private module DestructuredAssignDesugar { exists(AstNode assign | assign = TAssignExprSynth(seq, j + 1 + tae.getNumberOfElements()) | - exists(MethodCall mc | mc = elem | + exists(LhsWithReceiver mc | mc = elem | parent = assign and i = 0 and - child = - SynthChild(MethodCallKind(mc.getMethodName(), false, mc.getNumberOfArguments())) + child = SynthChild(mc.getSynthKind()) or - exists(AstNode call | call = TMethodCallSynth(assign, 0, _, _, _) | + exists(AstNode call | synthChild(assign, 0, call) | parent = call and i = 0 and child = SynthChild(LocalVariableAccessSynthKind(TLocalVariableSynth(tae, j))) or parent = call and - child = childRef(mc.getArgument(i - 1)) + child = childRef(mc.(MethodCall).getArgument(i - 1)) ) ) or ( - elem instanceof VariableAccess or - elem instanceof ConstantAccess or + elem instanceof VariableAccess + or + elem instanceof ConstantAccess and + not exists(Ruby::ScopeResolution g | + elem = TScopeResolutionConstantAccess(g, _) and exists(g.getScope()) + ) + or elem instanceof DestructuredLhsExpr ) and parent = assign and @@ -1096,7 +1134,7 @@ private module DestructuredAssignDesugar { synthChild(seq, tae.getNumberOfElements(), n) and hasLocation(tae.getRightOperand(), l) or - exists(MethodCall elem, int j | + exists(LhsWithReceiver elem, int j | elem = tae.getElement(j) and synthChild(seq, j, n) and hasLocation(elem.getReceiver(), l) @@ -1113,6 +1151,13 @@ private module DestructuredAssignDesugar { i = [0 .. n.(DestructuredAssignExpr).getNumberOfElements()] } + final override predicate constantWriteAccess(string name) { + exists(DestructuredAssignExpr tae, LhsScopedConstant ca | + ca = tae.getElement(_) and + name = ca.getName() + ) + } + final override predicate methodCall(string name, boolean setter, int arity) { name = "[]" and setter = false and @@ -1127,7 +1172,7 @@ private module DestructuredAssignDesugar { } final override predicate excludeFromControlFlowTree(AstNode n) { - n = any(DestructuredAssignExpr tae).getElement(_).(MethodCall) + n = any(DestructuredAssignExpr tae).getElement(_).(LhsWithReceiver) } } } diff --git a/ruby/ql/test/library-tests/ast/AstDesugar.expected b/ruby/ql/test/library-tests/ast/AstDesugar.expected index 06b600c1fb6..d8b49833332 100644 --- a/ruby/ql/test/library-tests/ast/AstDesugar.expected +++ b/ruby/ql/test/library-tests/ast/AstDesugar.expected @@ -959,8 +959,11 @@ operations/operations.rb: # 104| getReceiver: [LocalVariableAccess] __synth__3 # 104| getArgument: [IntegerLiteral] 1 # 104| getStmt: [AssignExpr] ... = ... +# 104| getAnOperand/getRightOperand: [LocalVariableAccess] foo +# 104| getAnOperand/getLeftOperand: [LocalVariableAccess] __synth__2 +# 104| getStmt: [AssignExpr] ... = ... # 104| getAnOperand/getLeftOperand: [ConstantAssignment] FOO -# 104| getScopeExpr: [LocalVariableAccess] foo +# 104| getScopeExpr: [LocalVariableAccess] __synth__2 # 104| getAnOperand/getRightOperand: [MethodCall] call to [] # 104| getReceiver: [LocalVariableAccess] __synth__3 # 104| getArgument: [IntegerLiteral] 2 diff --git a/ruby/ql/test/library-tests/ast/operations/assignment.expected b/ruby/ql/test/library-tests/ast/operations/assignment.expected index e22a0711065..5349ebf5cef 100644 --- a/ruby/ql/test/library-tests/ast/operations/assignment.expected +++ b/ruby/ql/test/library-tests/ast/operations/assignment.expected @@ -68,6 +68,7 @@ assignments | operations.rb:104:1:104:3 | ... = ... | = | operations.rb:104:1:104:3 | FOO | operations.rb:104:1:104:3 | call to [] | AssignExpr | | operations.rb:104:1:104:32 | ... = ... | = | operations.rb:104:1:104:20 | (..., ...) | operations.rb:104:24:104:32 | [...] | AssignExpr | | operations.rb:104:6:104:10 | ... = ... | = | operations.rb:104:6:104:10 | BAR | operations.rb:104:6:104:10 | call to [] | AssignExpr | +| operations.rb:104:13:104:15 | ... = ... | = | operations.rb:104:13:104:15 | __synth__2 | operations.rb:104:13:104:15 | foo | AssignExpr | | operations.rb:104:13:104:20 | ... = ... | = | operations.rb:104:13:104:20 | FOO | operations.rb:104:13:104:20 | call to [] | AssignExpr | | operations.rb:104:24:104:32 | ... = ... | = | operations.rb:104:24:104:32 | __synth__3 | operations.rb:104:24:104:32 | * ... | AssignExpr | assignOperations diff --git a/ruby/ql/test/library-tests/ast/operations/operation.expected b/ruby/ql/test/library-tests/ast/operations/operation.expected index 71f65d65b74..91e76d7c366 100644 --- a/ruby/ql/test/library-tests/ast/operations/operation.expected +++ b/ruby/ql/test/library-tests/ast/operations/operation.expected @@ -236,6 +236,8 @@ | operations.rb:104:1:104:32 | ... = ... | = | operations.rb:104:24:104:32 | [...] | AssignExpr | | operations.rb:104:6:104:10 | ... = ... | = | operations.rb:104:6:104:10 | BAR | AssignExpr | | operations.rb:104:6:104:10 | ... = ... | = | operations.rb:104:6:104:10 | call to [] | AssignExpr | +| operations.rb:104:13:104:15 | ... = ... | = | operations.rb:104:13:104:15 | __synth__2 | AssignExpr | +| operations.rb:104:13:104:15 | ... = ... | = | operations.rb:104:13:104:15 | foo | AssignExpr | | operations.rb:104:13:104:20 | ... = ... | = | operations.rb:104:13:104:20 | FOO | AssignExpr | | operations.rb:104:13:104:20 | ... = ... | = | operations.rb:104:13:104:20 | call to [] | AssignExpr | | operations.rb:104:24:104:32 | * ... | * | operations.rb:104:24:104:32 | [...] | SplatExpr | From 052bc9563920e68a82d14680aaddba10a76a9c7c Mon Sep 17 00:00:00 2001 From: Arthur Baars <aibaars@github.com> Date: Tue, 21 Mar 2023 19:03:49 +0100 Subject: [PATCH 476/631] Ruby: add change note --- ruby/ql/lib/change-notes/2023-03-21-evaluation-order.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 ruby/ql/lib/change-notes/2023-03-21-evaluation-order.md diff --git a/ruby/ql/lib/change-notes/2023-03-21-evaluation-order.md b/ruby/ql/lib/change-notes/2023-03-21-evaluation-order.md new file mode 100644 index 00000000000..0b943101e43 --- /dev/null +++ b/ruby/ql/lib/change-notes/2023-03-21-evaluation-order.md @@ -0,0 +1,5 @@ +--- + category: minorAnalysis +--- +* Control flow graph: the evaluation order of scope expressions and receivers in multiple assignments has been adjusted to match the changes made in Ruby +3.1 and 3.2. From 3b12ddfdc2d295393208e43d3982f17857512956 Mon Sep 17 00:00:00 2001 From: Arthur Baars <aibaars@github.com> Date: Thu, 23 Mar 2023 15:53:55 +0100 Subject: [PATCH 477/631] Address comments --- ruby/ql/lib/codeql/ruby/ast/Constant.qll | 49 --------------- .../lib/codeql/ruby/ast/internal/Constant.qll | 59 +++++++++++++++++++ .../codeql/ruby/ast/internal/Synthesis.qll | 21 ++----- 3 files changed, 64 insertions(+), 65 deletions(-) diff --git a/ruby/ql/lib/codeql/ruby/ast/Constant.qll b/ruby/ql/lib/codeql/ruby/ast/Constant.qll index b76fac8d47f..0a716ed8407 100644 --- a/ruby/ql/lib/codeql/ruby/ast/Constant.qll +++ b/ruby/ql/lib/codeql/ruby/ast/Constant.qll @@ -235,55 +235,6 @@ class ConstantAccess extends Expr, TConstantAccess { } } -private class TokenConstantAccess extends ConstantAccess, TTokenConstantAccess { - private Ruby::Constant g; - - TokenConstantAccess() { this = TTokenConstantAccess(g) } - - final override string getName() { result = g.getValue() } -} - -private class ScopeResolutionConstantAccess extends ConstantAccess, TScopeResolutionConstantAccess { - private Ruby::ScopeResolution g; - private Ruby::Constant constant; - - ScopeResolutionConstantAccess() { this = TScopeResolutionConstantAccess(g, constant) } - - final override string getName() { result = constant.getValue() } - - final override Expr getScopeExpr() { toGenerated(result) = g.getScope() } - - final override predicate hasGlobalScope() { not exists(g.getScope()) } -} - -private class ConstantReadAccessSynth extends ConstantAccess, TConstantReadAccessSynth { - private string value; - - ConstantReadAccessSynth() { this = TConstantReadAccessSynth(_, _, value) } - - final override string getName() { - if this.hasGlobalScope() then result = value.suffix(2) else result = value - } - - final override Expr getScopeExpr() { synthChild(this, 0, result) } - - final override predicate hasGlobalScope() { value.matches("::%") } -} - -private class ConstantWriteAccessSynth extends ConstantAccess, TConstantWriteAccessSynth { - private string value; - - ConstantWriteAccessSynth() { this = TConstantWriteAccessSynth(_, _, value) } - - final override string getName() { - if this.hasGlobalScope() then result = value.suffix(2) else result = value - } - - final override Expr getScopeExpr() { synthChild(this, 0, result) } - - final override predicate hasGlobalScope() { value.matches("::%") } -} - /** * A use (read) of a constant. * diff --git a/ruby/ql/lib/codeql/ruby/ast/internal/Constant.qll b/ruby/ql/lib/codeql/ruby/ast/internal/Constant.qll index 53355695e57..d68a5582e17 100644 --- a/ruby/ql/lib/codeql/ruby/ast/internal/Constant.qll +++ b/ruby/ql/lib/codeql/ruby/ast/internal/Constant.qll @@ -1,6 +1,8 @@ private import codeql.ruby.AST +private import codeql.ruby.ast.internal.AST private import codeql.ruby.ast.internal.Literal private import codeql.ruby.ast.internal.Module +private import codeql.ruby.ast.internal.TreeSitter private import codeql.ruby.controlflow.CfgNodes private import codeql.ruby.dataflow.SSA private import ExprNodes @@ -559,3 +561,60 @@ private predicate isArrayExpr(Expr e, ArrayLiteralCfgNode arr) { // results if the source is a phi node. forex(ExprCfgNode n | n = e.getAControlFlowNode() | isArrayConstant(n, arr)) } + +private class TokenConstantAccess extends ConstantAccess, TTokenConstantAccess { + private Ruby::Constant g; + + TokenConstantAccess() { this = TTokenConstantAccess(g) } + + final override string getName() { result = g.getValue() } +} + +/** + * A constant access that has a scope resolution qualifier. + */ +class ScopeResolutionConstantAccess extends ConstantAccess, TScopeResolutionConstantAccess { + private Ruby::ScopeResolution g; + private Ruby::Constant constant; + + ScopeResolutionConstantAccess() { this = TScopeResolutionConstantAccess(g, constant) } + + /** + * Gets the name of the constant. + */ + final override string getName() { result = constant.getValue() } + + /** Gets the scope resolution expression. */ + final override Expr getScopeExpr() { toGenerated(result) = g.getScope() } + + /** Holds if this constant access has a global scope. */ + final override predicate hasGlobalScope() { not exists(g.getScope()) } +} + +private class ConstantReadAccessSynth extends ConstantAccess, TConstantReadAccessSynth { + private string value; + + ConstantReadAccessSynth() { this = TConstantReadAccessSynth(_, _, value) } + + final override string getName() { + if this.hasGlobalScope() then result = value.suffix(2) else result = value + } + + final override Expr getScopeExpr() { synthChild(this, 0, result) } + + final override predicate hasGlobalScope() { value.matches("::%") } +} + +private class ConstantWriteAccessSynth extends ConstantAccess, TConstantWriteAccessSynth { + private string value; + + ConstantWriteAccessSynth() { this = TConstantWriteAccessSynth(_, _, value) } + + final override string getName() { + if this.hasGlobalScope() then result = value.suffix(2) else result = value + } + + final override Expr getScopeExpr() { synthChild(this, 0, result) } + + final override predicate hasGlobalScope() { value.matches("::%") } +} diff --git a/ruby/ql/lib/codeql/ruby/ast/internal/Synthesis.qll b/ruby/ql/lib/codeql/ruby/ast/internal/Synthesis.qll index e8f6d405ba3..d74b76a1998 100644 --- a/ruby/ql/lib/codeql/ruby/ast/internal/Synthesis.qll +++ b/ruby/ql/lib/codeql/ruby/ast/internal/Synthesis.qll @@ -3,6 +3,7 @@ private import AST private import TreeSitter private import codeql.ruby.ast.internal.Call +private import codeql.ruby.ast.internal.Constant private import codeql.ruby.ast.internal.Expr private import codeql.ruby.ast.internal.Variable private import codeql.ruby.ast.internal.Pattern @@ -964,24 +965,12 @@ private module DestructuredAssignDesugar { } } - private class LhsScopedConstant extends LhsWithReceiver, TScopeResolutionConstantAccess { - private Ruby::AstNode receiver; - private string name; + private class LhsScopedConstant extends LhsWithReceiver, ScopeResolutionConstantAccess { + LhsScopedConstant() { exists(this.getScopeExpr()) } - LhsScopedConstant() { - exists(Ruby::ScopeResolution e, Ruby::Constant c | - this = TScopeResolutionConstantAccess(e, c) - | - receiver = e.getScope() and - name = c.getValue() - ) - } + final override Expr getReceiver() { result = this.getScopeExpr() } - final string getName() { result = name } - - final override Expr getReceiver() { toGenerated(result) = receiver } - - final override SynthKind getSynthKind() { result = ConstantWriteAccessKind(name) } + final override SynthKind getSynthKind() { result = ConstantWriteAccessKind(this.getName()) } } pragma[nomagic] From 41a5dc8efe25d6c23bd1184467cf47c759350e09 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Fri, 24 Mar 2023 17:06:47 +0000 Subject: [PATCH 478/631] C++: Restrict tests that report all Elements to Elements in files. --- .../library-tests/CPP-205/elements.expected | 7 -- cpp/ql/test/library-tests/CPP-205/elements.ql | 2 +- .../lambdas/captures/elements.expected | 107 ------------------ .../lambdas/captures/elements.ql | 5 +- .../templates/extern/elements.expected | 1 - .../templates/extern/elements.ql | 5 +- 6 files changed, 5 insertions(+), 122 deletions(-) diff --git a/cpp/ql/test/library-tests/CPP-205/elements.expected b/cpp/ql/test/library-tests/CPP-205/elements.expected index f64b9d4e08b..6838bcd2fbf 100644 --- a/cpp/ql/test/library-tests/CPP-205/elements.expected +++ b/cpp/ql/test/library-tests/CPP-205/elements.expected @@ -26,10 +26,3 @@ | CPP-205.cpp:8:3:8:15 | return ... | | | CPP-205.cpp:8:10:8:11 | call to fn | | | CPP-205.cpp:8:13:8:13 | 0 | | -| file://:0:0:0:0 | (unnamed parameter 0) | parameter for __va_list_tag& __va_list_tag::operator=(__va_list_tag const&) | -| file://:0:0:0:0 | (unnamed parameter 0) | parameter for __va_list_tag& __va_list_tag::operator=(__va_list_tag&&) | -| file://:0:0:0:0 | __super | | -| file://:0:0:0:0 | __va_list_tag | | -| file://:0:0:0:0 | operator= | function __va_list_tag& __va_list_tag::operator=(__va_list_tag const&) | -| file://:0:0:0:0 | operator= | function __va_list_tag& __va_list_tag::operator=(__va_list_tag&&) | -| file://:0:0:0:0 | y | | diff --git a/cpp/ql/test/library-tests/CPP-205/elements.ql b/cpp/ql/test/library-tests/CPP-205/elements.ql index 9388a799dbc..78d74773ec4 100644 --- a/cpp/ql/test/library-tests/CPP-205/elements.ql +++ b/cpp/ql/test/library-tests/CPP-205/elements.ql @@ -18,6 +18,6 @@ string describe(Element e) { from Element e where - not e.getLocation() instanceof UnknownLocation and + e.getLocation().getFile().getBaseName() != "" and not e instanceof Folder select e, concat(describe(e), ", ") diff --git a/cpp/ql/test/library-tests/lambdas/captures/elements.expected b/cpp/ql/test/library-tests/lambdas/captures/elements.expected index 04b6192bdba..fbe1bcc0cfd 100644 --- a/cpp/ql/test/library-tests/lambdas/captures/elements.expected +++ b/cpp/ql/test/library-tests/lambdas/captures/elements.expected @@ -1,4 +1,3 @@ -| captures.cpp:0:0:0:0 | captures.cpp | | captures.cpp:1:8:1:8 | declaration of operator= | | captures.cpp:1:8:1:8 | declaration of operator= | | captures.cpp:1:8:1:8 | operator= | @@ -166,7 +165,6 @@ | captures.cpp:26:10:26:17 | myLambda | | captures.cpp:26:18:26:18 | call to operator() | | captures.cpp:26:19:26:22 | 1000 | -| end_pos.cpp:0:0:0:0 | end_pos.cpp | | end_pos.cpp:2:1:2:14 | #define OPEN { | | end_pos.cpp:3:6:3:10 | definition of igFun | | end_pos.cpp:3:6:3:10 | igFun | @@ -211,108 +209,3 @@ | end_pos.cpp:10:9:10:17 | return ... | | end_pos.cpp:10:16:10:16 | 1 | | end_pos.cpp:12:1:12:1 | return ... | -| file://:0:0:0:0 | | -| file://:0:0:0:0 | (global namespace) | -| file://:0:0:0:0 | (reference to) | -| file://:0:0:0:0 | (unnamed parameter 0) | -| file://:0:0:0:0 | (unnamed parameter 0) | -| file://:0:0:0:0 | (unnamed parameter 0) | -| file://:0:0:0:0 | (unnamed parameter 0) | -| file://:0:0:0:0 | (unnamed parameter 0) | -| file://:0:0:0:0 | (unnamed parameter 0) | -| file://:0:0:0:0 | (unnamed parameter 0) | -| file://:0:0:0:0 | (unnamed parameter 0) | -| file://:0:0:0:0 | (unnamed parameter 0) | -| file://:0:0:0:0 | (unnamed parameter 0) | -| file://:0:0:0:0 | (unnamed parameter 0) | -| file://:0:0:0:0 | (unnamed parameter 0) | -| file://:0:0:0:0 | (unnamed parameter 0) | -| file://:0:0:0:0 | (unnamed parameter 0) | -| file://:0:0:0:0 | (unnamed parameter 0) | -| file://:0:0:0:0 | (unnamed parameter 0) | -| file://:0:0:0:0 | (unnamed parameter 0) | -| file://:0:0:0:0 | (unnamed parameter 0) | -| file://:0:0:0:0 | (unnamed parameter 0) | -| file://:0:0:0:0 | ..()(..) | -| file://:0:0:0:0 | ..()(..) | -| file://:0:0:0:0 | ..(*)(..) | -| file://:0:0:0:0 | ..(*)(..) | -| file://:0:0:0:0 | ..(*)(..) | -| file://:0:0:0:0 | ..(..) | -| file://:0:0:0:0 | __super | -| file://:0:0:0:0 | __va_list_tag | -| file://:0:0:0:0 | __va_list_tag & | -| file://:0:0:0:0 | __va_list_tag && | -| file://:0:0:0:0 | auto | -| file://:0:0:0:0 | const __va_list_tag | -| file://:0:0:0:0 | const __va_list_tag & | -| file://:0:0:0:0 | const foo | -| file://:0:0:0:0 | const foo & | -| file://:0:0:0:0 | const lambda [] type at line 3, col. 5 | -| file://:0:0:0:0 | const lambda [] type at line 3, col. 5 & | -| file://:0:0:0:0 | const lambda [] type at line 3, col. 5 * | -| file://:0:0:0:0 | const lambda [] type at line 9, col. 5 | -| file://:0:0:0:0 | const lambda [] type at line 9, col. 5 & | -| file://:0:0:0:0 | const lambda [] type at line 9, col. 5 * | -| file://:0:0:0:0 | const lambda [] type at line 9, col. 15 | -| file://:0:0:0:0 | const lambda [] type at line 9, col. 15 & | -| file://:0:0:0:0 | const lambda [] type at line 9, col. 15 * | -| file://:0:0:0:0 | const lambda [] type at line 15, col. 5 | -| file://:0:0:0:0 | const lambda [] type at line 15, col. 5 & | -| file://:0:0:0:0 | const lambda [] type at line 15, col. 5 * | -| file://:0:0:0:0 | const lambda [] type at line 22, col. 19 | -| file://:0:0:0:0 | const lambda [] type at line 22, col. 19 & | -| file://:0:0:0:0 | const lambda [] type at line 22, col. 19 * | -| file://:0:0:0:0 | declaration of 1st parameter | -| file://:0:0:0:0 | declaration of 1st parameter | -| file://:0:0:0:0 | declaration of 1st parameter | -| file://:0:0:0:0 | declaration of 1st parameter | -| file://:0:0:0:0 | declaration of 1st parameter | -| file://:0:0:0:0 | declaration of 1st parameter | -| file://:0:0:0:0 | declaration of 1st parameter | -| file://:0:0:0:0 | declaration of 1st parameter | -| file://:0:0:0:0 | declaration of 1st parameter | -| file://:0:0:0:0 | declaration of 1st parameter | -| file://:0:0:0:0 | declaration of 1st parameter | -| file://:0:0:0:0 | declaration of 1st parameter | -| file://:0:0:0:0 | declaration of 1st parameter | -| file://:0:0:0:0 | declaration of 1st parameter | -| file://:0:0:0:0 | declaration of 1st parameter | -| file://:0:0:0:0 | declaration of 1st parameter | -| file://:0:0:0:0 | declaration of 1st parameter | -| file://:0:0:0:0 | decltype([...](...){...}) | -| file://:0:0:0:0 | decltype([...](...){...}) | -| file://:0:0:0:0 | decltype([...](...){...}) | -| file://:0:0:0:0 | decltype([...](...){...}) | -| file://:0:0:0:0 | decltype([...](...){...}) | -| file://:0:0:0:0 | definition of fp_offset | -| file://:0:0:0:0 | definition of gp_offset | -| file://:0:0:0:0 | definition of overflow_arg_area | -| file://:0:0:0:0 | definition of reg_save_area | -| file://:0:0:0:0 | foo & | -| file://:0:0:0:0 | foo && | -| file://:0:0:0:0 | foo * | -| file://:0:0:0:0 | foo *const | -| file://:0:0:0:0 | fp_offset | -| file://:0:0:0:0 | gp_offset | -| file://:0:0:0:0 | int & | -| file://:0:0:0:0 | lambda [] type at line 3, col. 5 & | -| file://:0:0:0:0 | lambda [] type at line 3, col. 5 && | -| file://:0:0:0:0 | lambda [] type at line 3, col. 5 * | -| file://:0:0:0:0 | lambda [] type at line 9, col. 5 & | -| file://:0:0:0:0 | lambda [] type at line 9, col. 5 && | -| file://:0:0:0:0 | lambda [] type at line 9, col. 5 * | -| file://:0:0:0:0 | lambda [] type at line 9, col. 15 & | -| file://:0:0:0:0 | lambda [] type at line 9, col. 15 && | -| file://:0:0:0:0 | lambda [] type at line 9, col. 15 * | -| file://:0:0:0:0 | lambda [] type at line 15, col. 5 & | -| file://:0:0:0:0 | lambda [] type at line 15, col. 5 && | -| file://:0:0:0:0 | lambda [] type at line 15, col. 5 * | -| file://:0:0:0:0 | lambda [] type at line 22, col. 19 & | -| file://:0:0:0:0 | lambda [] type at line 22, col. 19 && | -| file://:0:0:0:0 | lambda [] type at line 22, col. 19 * | -| file://:0:0:0:0 | operator= | -| file://:0:0:0:0 | operator= | -| file://:0:0:0:0 | overflow_arg_area | -| file://:0:0:0:0 | reg_save_area | -| file://:0:0:0:0 | void * | diff --git a/cpp/ql/test/library-tests/lambdas/captures/elements.ql b/cpp/ql/test/library-tests/lambdas/captures/elements.ql index b7a1275f388..7bc540f3b59 100644 --- a/cpp/ql/test/library-tests/lambdas/captures/elements.ql +++ b/cpp/ql/test/library-tests/lambdas/captures/elements.ql @@ -2,7 +2,6 @@ import cpp from Element e where - not e instanceof BuiltInType and - not e instanceof Specifier and - not e instanceof Folder + e.getLocation().getFile().getBaseName() != "" and + not e instanceof Container select e diff --git a/cpp/ql/test/library-tests/templates/extern/elements.expected b/cpp/ql/test/library-tests/templates/extern/elements.expected index 4006eb88484..2feaf133dca 100644 --- a/cpp/ql/test/library-tests/templates/extern/elements.expected +++ b/cpp/ql/test/library-tests/templates/extern/elements.expected @@ -1,4 +1,3 @@ -| extern.cpp:0:0:0:0 | extern.cpp | | extern.cpp:1:20:1:20 | T | | extern.cpp:1:20:1:20 | definition of T | | extern.cpp:2:5:2:5 | declaration of f | diff --git a/cpp/ql/test/library-tests/templates/extern/elements.ql b/cpp/ql/test/library-tests/templates/extern/elements.ql index be15ddcd4f4..7bc540f3b59 100644 --- a/cpp/ql/test/library-tests/templates/extern/elements.ql +++ b/cpp/ql/test/library-tests/templates/extern/elements.ql @@ -2,7 +2,6 @@ import cpp from Element e where - exists(e.getLocation()) and - not e.getLocation() instanceof UnknownLocation and - not e instanceof Folder + e.getLocation().getFile().getBaseName() != "" and + not e instanceof Container select e From d5b9cea4bc144e18e68ff139fa31bb5a47358b40 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Fri, 24 Mar 2023 17:43:33 +0000 Subject: [PATCH 479/631] C++: Focus the CPP-205 test on the templates. --- .../library-tests/CPP-205/elements.expected | 45 ++++++++----------- cpp/ql/test/library-tests/CPP-205/elements.ql | 12 ++++- 2 files changed, 30 insertions(+), 27 deletions(-) diff --git a/cpp/ql/test/library-tests/CPP-205/elements.expected b/cpp/ql/test/library-tests/CPP-205/elements.expected index 6838bcd2fbf..76104232401 100644 --- a/cpp/ql/test/library-tests/CPP-205/elements.expected +++ b/cpp/ql/test/library-tests/CPP-205/elements.expected @@ -1,28 +1,21 @@ -| CPP-205.cpp:0:0:0:0 | CPP-205.cpp | | -| CPP-205.cpp:1:20:1:20 | T | | -| CPP-205.cpp:1:20:1:20 | definition of T | | -| CPP-205.cpp:2:5:2:5 | definition of fn | function declaration entry for int fn<int>(int) | -| CPP-205.cpp:2:5:2:5 | fn | function int fn<int>(int) | -| CPP-205.cpp:2:5:2:6 | definition of fn | function declaration entry for int fn<T>(T) | -| CPP-205.cpp:2:5:2:6 | fn | function int fn<T>(T) | -| CPP-205.cpp:2:10:2:12 | definition of out | parameter declaration entry for int fn<T>(T) | -| CPP-205.cpp:2:10:2:12 | definition of out | parameter declaration entry for int fn<int>(int) | -| CPP-205.cpp:2:10:2:12 | out | parameter for int fn<T>(T) | -| CPP-205.cpp:2:10:2:12 | out | parameter for int fn<int>(int) | -| CPP-205.cpp:2:15:5:1 | { ... } | | -| CPP-205.cpp:2:15:5:1 | { ... } | | -| CPP-205.cpp:3:3:3:33 | declaration | | -| CPP-205.cpp:3:3:3:33 | declaration | | -| CPP-205.cpp:3:15:3:15 | declaration of y | | -| CPP-205.cpp:3:15:3:15 | y | | -| CPP-205.cpp:3:17:3:31 | 5 | | -| CPP-205.cpp:4:3:4:11 | return ... | | -| CPP-205.cpp:4:3:4:11 | return ... | | -| CPP-205.cpp:4:10:4:10 | 0 | | -| CPP-205.cpp:4:10:4:10 | 0 | | +| CPP-205.cpp:2:5:2:5 | definition of fn | function declaration entry for int fn<int>(int), isFromTemplateInstantiation(fn) | +| CPP-205.cpp:2:5:2:5 | fn | function int fn<int>(int), isFromTemplateInstantiation(fn) | +| CPP-205.cpp:2:5:2:6 | definition of fn | function declaration entry for int fn<T>(T), isFromUninstantiatedTemplate(fn) | +| CPP-205.cpp:2:5:2:6 | fn | function int fn<T>(T), isFromUninstantiatedTemplate(fn) | +| CPP-205.cpp:2:10:2:12 | definition of out | isFromTemplateInstantiation(fn), parameter declaration entry for int fn<int>(int) | +| CPP-205.cpp:2:10:2:12 | definition of out | isFromUninstantiatedTemplate(fn), parameter declaration entry for int fn<T>(T) | +| CPP-205.cpp:2:10:2:12 | out | isFromTemplateInstantiation(fn), parameter for int fn<int>(int) | +| CPP-205.cpp:2:10:2:12 | out | isFromUninstantiatedTemplate(fn), parameter for int fn<T>(T) | +| CPP-205.cpp:2:15:5:1 | { ... } | isFromTemplateInstantiation(fn) | +| CPP-205.cpp:2:15:5:1 | { ... } | isFromUninstantiatedTemplate(fn) | +| CPP-205.cpp:3:3:3:33 | declaration | isFromTemplateInstantiation(fn) | +| CPP-205.cpp:3:3:3:33 | declaration | isFromUninstantiatedTemplate(fn) | +| CPP-205.cpp:3:15:3:15 | declaration of y | isFromUninstantiatedTemplate(fn) | +| CPP-205.cpp:3:15:3:15 | y | isFromUninstantiatedTemplate(fn) | +| CPP-205.cpp:3:17:3:31 | 5 | isFromTemplateInstantiation(fn) | +| CPP-205.cpp:4:3:4:11 | return ... | isFromTemplateInstantiation(fn) | +| CPP-205.cpp:4:3:4:11 | return ... | isFromUninstantiatedTemplate(fn) | +| CPP-205.cpp:4:10:4:10 | 0 | isFromTemplateInstantiation(fn) | +| CPP-205.cpp:4:10:4:10 | 0 | isFromUninstantiatedTemplate(fn) | | CPP-205.cpp:7:5:7:8 | definition of main | function declaration entry for int main() | | CPP-205.cpp:7:5:7:8 | main | function int main() | -| CPP-205.cpp:7:12:9:1 | { ... } | | -| CPP-205.cpp:8:3:8:15 | return ... | | -| CPP-205.cpp:8:10:8:11 | call to fn | | -| CPP-205.cpp:8:13:8:13 | 0 | | diff --git a/cpp/ql/test/library-tests/CPP-205/elements.ql b/cpp/ql/test/library-tests/CPP-205/elements.ql index 78d74773ec4..b1ead8bb00e 100644 --- a/cpp/ql/test/library-tests/CPP-205/elements.ql +++ b/cpp/ql/test/library-tests/CPP-205/elements.ql @@ -14,10 +14,20 @@ string describe(Element e) { result = "parameter declaration entry for " + getIdentityString(e.(ParameterDeclarationEntry).getFunctionDeclarationEntry().getFunction()) + or + exists(Element template | + e.isFromTemplateInstantiation(template) and + result = "isFromTemplateInstantiation(" + template.toString() + ")" + ) + or + exists(Element template | + e.isFromUninstantiatedTemplate(template) and + result = "isFromUninstantiatedTemplate(" + template.toString() + ")" + ) } from Element e where e.getLocation().getFile().getBaseName() != "" and not e instanceof Folder -select e, concat(describe(e), ", ") +select e, strictconcat(describe(e), ", ") From b5de2a598517285232f0537dc7dc7f3e2de86aa0 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Fri, 24 Mar 2023 18:48:59 +0000 Subject: [PATCH 480/631] C++: Focus the lambda captures test on stuff inside the lambdas (including some that don't currently have locations). --- .../lambdas/captures/elements.expected | 109 ++++-------------- .../lambdas/captures/elements.ql | 11 +- 2 files changed, 30 insertions(+), 90 deletions(-) diff --git a/cpp/ql/test/library-tests/lambdas/captures/elements.expected b/cpp/ql/test/library-tests/lambdas/captures/elements.expected index fbe1bcc0cfd..83592696f8f 100644 --- a/cpp/ql/test/library-tests/lambdas/captures/elements.expected +++ b/cpp/ql/test/library-tests/lambdas/captures/elements.expected @@ -1,25 +1,9 @@ -| captures.cpp:1:8:1:8 | declaration of operator= | -| captures.cpp:1:8:1:8 | declaration of operator= | -| captures.cpp:1:8:1:8 | operator= | -| captures.cpp:1:8:1:8 | operator= | -| captures.cpp:1:8:1:10 | definition of foo | -| captures.cpp:1:8:1:10 | foo | -| captures.cpp:2:8:2:8 | a | -| captures.cpp:2:8:2:8 | definition of a | -| captures.cpp:2:14:2:14 | definition of x | -| captures.cpp:2:14:2:14 | x | -| captures.cpp:2:17:6:3 | { ... } | | captures.cpp:3:5:3:5 | (unnamed constructor) | | captures.cpp:3:5:3:5 | (unnamed constructor) | | captures.cpp:3:5:3:5 | (unnamed constructor) | -| captures.cpp:3:5:3:5 | declaration of (unnamed constructor) | -| captures.cpp:3:5:3:5 | declaration of (unnamed constructor) | -| captures.cpp:3:5:3:5 | definition of (unnamed constructor) | -| captures.cpp:3:5:3:5 | definition of operator= | | captures.cpp:3:5:3:5 | operator= | | captures.cpp:3:5:5:5 | [...](...){...} | | captures.cpp:3:5:5:5 | {...} | -| captures.cpp:3:5:5:6 | ExprStmt | | captures.cpp:3:6:3:6 | definition of x | | captures.cpp:3:6:3:6 | x | | captures.cpp:3:6:3:6 | x | @@ -28,7 +12,6 @@ | captures.cpp:3:9:3:9 | definition of (captured this) | | captures.cpp:3:9:3:12 | (captured this) | | captures.cpp:3:9:3:12 | this | -| captures.cpp:3:15:3:15 | definition of operator() | | captures.cpp:3:15:3:15 | operator() | | captures.cpp:3:15:5:5 | { ... } | | captures.cpp:4:7:4:7 | (captured this) | @@ -40,26 +23,14 @@ | captures.cpp:4:9:4:13 | x | | captures.cpp:4:13:4:13 | 1 | | captures.cpp:5:5:5:5 | return ... | -| captures.cpp:6:3:6:3 | return ... | -| captures.cpp:8:8:8:8 | b | -| captures.cpp:8:8:8:8 | definition of b | -| captures.cpp:8:14:8:14 | definition of x | -| captures.cpp:8:14:8:14 | x | -| captures.cpp:8:17:12:3 | { ... } | | captures.cpp:9:5:9:5 | (unnamed constructor) | | captures.cpp:9:5:9:5 | (unnamed constructor) | | captures.cpp:9:5:9:5 | (unnamed constructor) | -| captures.cpp:9:5:9:5 | declaration of (unnamed constructor) | -| captures.cpp:9:5:9:5 | declaration of (unnamed constructor) | -| captures.cpp:9:5:9:5 | definition of (unnamed constructor) | -| captures.cpp:9:5:9:5 | definition of operator= | | captures.cpp:9:5:9:5 | operator= | | captures.cpp:9:5:11:5 | [...](...){...} | | captures.cpp:9:5:11:5 | this | | captures.cpp:9:5:11:5 | x | | captures.cpp:9:5:11:5 | {...} | -| captures.cpp:9:5:11:6 | ExprStmt | -| captures.cpp:9:9:9:9 | definition of operator() | | captures.cpp:9:9:9:9 | operator() | | captures.cpp:9:9:11:5 | { ... } | | captures.cpp:10:7:10:7 | (captured this) | @@ -77,48 +48,23 @@ | captures.cpp:10:9:10:13 | x | | captures.cpp:10:13:10:13 | 1 | | captures.cpp:11:5:11:5 | return ... | -| captures.cpp:12:3:12:3 | return ... | -| captures.cpp:14:15:14:15 | c | -| captures.cpp:14:15:14:15 | definition of c | -| captures.cpp:14:21:14:21 | definition of x | -| captures.cpp:14:21:14:21 | x | -| captures.cpp:14:24:18:3 | { ... } | | captures.cpp:15:5:15:5 | (unnamed constructor) | | captures.cpp:15:5:15:5 | (unnamed constructor) | | captures.cpp:15:5:15:5 | (unnamed constructor) | -| captures.cpp:15:5:15:5 | declaration of (unnamed constructor) | -| captures.cpp:15:5:15:5 | declaration of (unnamed constructor) | -| captures.cpp:15:5:15:5 | definition of (unnamed constructor) | -| captures.cpp:15:5:15:5 | definition of operator= | | captures.cpp:15:5:15:5 | operator= | | captures.cpp:15:5:17:5 | [...](...){...} | | captures.cpp:15:5:17:5 | {...} | -| captures.cpp:15:5:17:6 | ExprStmt | | captures.cpp:15:6:15:6 | definition of x | | captures.cpp:15:6:15:6 | x | | captures.cpp:15:6:15:6 | x | | captures.cpp:15:6:15:6 | x | -| captures.cpp:15:9:15:9 | definition of operator() | | captures.cpp:15:9:15:9 | operator() | | captures.cpp:15:9:17:5 | { ... } | | captures.cpp:16:7:16:7 | call to c | | captures.cpp:16:7:16:11 | ExprStmt | | captures.cpp:16:9:16:9 | 0 | -| captures.cpp:16:13:16:49 | // `x` is unused, but still captured. | | captures.cpp:17:5:17:5 | return ... | -| captures.cpp:18:3:18:3 | return ... | -| captures.cpp:21:5:21:5 | d | -| captures.cpp:21:5:21:5 | definition of d | -| captures.cpp:21:11:21:11 | definition of x | -| captures.cpp:21:11:21:11 | x | -| captures.cpp:21:18:21:18 | definition of y | -| captures.cpp:21:18:21:18 | y | -| captures.cpp:21:21:27:1 | { ... } | -| captures.cpp:22:3:24:4 | declaration | -| captures.cpp:22:8:22:15 | definition of myLambda | -| captures.cpp:22:8:22:15 | myLambda | | captures.cpp:22:18:24:3 | [...](...){...} | -| captures.cpp:22:18:24:3 | initializer for myLambda | | captures.cpp:22:18:24:3 | y | | captures.cpp:22:18:24:3 | {...} | | captures.cpp:22:19:22:19 | (reference dereference) | @@ -130,10 +76,6 @@ | captures.cpp:22:19:22:19 | (unnamed parameter 0) | | captures.cpp:22:19:22:19 | constructor init of field x | | captures.cpp:22:19:22:19 | constructor init of field y | -| captures.cpp:22:19:22:19 | declaration of (unnamed constructor) | -| captures.cpp:22:19:22:19 | definition of (unnamed constructor) | -| captures.cpp:22:19:22:19 | definition of (unnamed constructor) | -| captures.cpp:22:19:22:19 | definition of operator= | | captures.cpp:22:19:22:19 | operator= | | captures.cpp:22:19:22:19 | return ... | | captures.cpp:22:19:22:19 | x | @@ -143,9 +85,7 @@ | captures.cpp:22:23:22:23 | x | | captures.cpp:22:23:22:23 | x | | captures.cpp:22:23:22:23 | x | -| captures.cpp:22:25:22:25 | definition of operator() | | captures.cpp:22:25:22:25 | operator() | -| captures.cpp:22:30:22:30 | definition of z | | captures.cpp:22:30:22:30 | z | | captures.cpp:22:40:24:3 | { ... } | | captures.cpp:23:5:23:21 | return ... | @@ -160,29 +100,7 @@ | captures.cpp:23:16:23:16 | y | | captures.cpp:23:16:23:16 | y | | captures.cpp:23:20:23:20 | z | -| captures.cpp:26:3:26:24 | return ... | -| captures.cpp:26:10:26:17 | (const lambda [] type at line 22, col. 19)... | -| captures.cpp:26:10:26:17 | myLambda | -| captures.cpp:26:18:26:18 | call to operator() | -| captures.cpp:26:19:26:22 | 1000 | -| end_pos.cpp:2:1:2:14 | #define OPEN { | -| end_pos.cpp:3:6:3:10 | definition of igFun | -| end_pos.cpp:3:6:3:10 | igFun | -| end_pos.cpp:3:14:12:1 | { ... } | -| end_pos.cpp:4:5:4:8 | OPEN | -| end_pos.cpp:4:5:5:5 | { ... } | -| end_pos.cpp:6:5:6:15 | declaration | -| end_pos.cpp:6:9:6:10 | definition of ii | -| end_pos.cpp:6:9:6:10 | ii | -| end_pos.cpp:6:13:6:14 | 0 | -| end_pos.cpp:6:13:6:14 | initializer for ii | -| end_pos.cpp:7:5:7:69 | // EDG used to not give the initialization for this ii capture an | -| end_pos.cpp:8:5:8:20 | // end location: | -| end_pos.cpp:9:5:11:6 | declaration | -| end_pos.cpp:9:10:9:11 | definition of fp | -| end_pos.cpp:9:10:9:11 | fp | | end_pos.cpp:9:14:11:5 | [...](...){...} | -| end_pos.cpp:9:14:11:5 | initializer for fp | | end_pos.cpp:9:14:11:5 | {...} | | end_pos.cpp:9:15:9:15 | (reference dereference) | | end_pos.cpp:9:15:9:15 | (unnamed constructor) | @@ -190,10 +108,6 @@ | end_pos.cpp:9:15:9:15 | (unnamed constructor) | | end_pos.cpp:9:15:9:15 | (unnamed parameter 0) | | end_pos.cpp:9:15:9:15 | constructor init of field ii | -| end_pos.cpp:9:15:9:15 | declaration of (unnamed constructor) | -| end_pos.cpp:9:15:9:15 | definition of (unnamed constructor) | -| end_pos.cpp:9:15:9:15 | definition of (unnamed constructor) | -| end_pos.cpp:9:15:9:15 | definition of operator= | | end_pos.cpp:9:15:9:15 | ii | | end_pos.cpp:9:15:9:15 | operator= | | end_pos.cpp:9:15:9:15 | return ... | @@ -203,9 +117,28 @@ | end_pos.cpp:9:17:9:18 | (reference to) | | end_pos.cpp:9:17:9:18 | ii | | end_pos.cpp:9:17:9:18 | ii | -| end_pos.cpp:9:20:9:20 | definition of operator() | | end_pos.cpp:9:20:9:20 | operator() | | end_pos.cpp:9:27:11:5 | { ... } | | end_pos.cpp:10:9:10:17 | return ... | | end_pos.cpp:10:16:10:16 | 1 | -| end_pos.cpp:12:1:12:1 | return ... | +| file://:0:0:0:0 | (reference to) | +| file://:0:0:0:0 | (unnamed parameter 0) | +| file://:0:0:0:0 | (unnamed parameter 0) | +| file://:0:0:0:0 | (unnamed parameter 0) | +| file://:0:0:0:0 | (unnamed parameter 0) | +| file://:0:0:0:0 | (unnamed parameter 0) | +| file://:0:0:0:0 | (unnamed parameter 0) | +| file://:0:0:0:0 | (unnamed parameter 0) | +| file://:0:0:0:0 | (unnamed parameter 0) | +| file://:0:0:0:0 | (unnamed parameter 0) | +| file://:0:0:0:0 | (unnamed parameter 0) | +| file://:0:0:0:0 | (unnamed parameter 0) | +| file://:0:0:0:0 | (unnamed parameter 0) | +| file://:0:0:0:0 | (unnamed parameter 0) | +| file://:0:0:0:0 | (unnamed parameter 0) | +| file://:0:0:0:0 | (unnamed parameter 0) | +| file://:0:0:0:0 | decltype([...](...){...}) | +| file://:0:0:0:0 | decltype([...](...){...}) | +| file://:0:0:0:0 | decltype([...](...){...}) | +| file://:0:0:0:0 | decltype([...](...){...}) | +| file://:0:0:0:0 | decltype([...](...){...}) | diff --git a/cpp/ql/test/library-tests/lambdas/captures/elements.ql b/cpp/ql/test/library-tests/lambdas/captures/elements.ql index 7bc540f3b59..904f4d43155 100644 --- a/cpp/ql/test/library-tests/lambdas/captures/elements.ql +++ b/cpp/ql/test/library-tests/lambdas/captures/elements.ql @@ -1,7 +1,14 @@ import cpp +predicate interesting(Element e) { + e instanceof LambdaCapture or + e instanceof LambdaExpression or + e = any(LambdaExpression le).getLambdaFunction() or + e = any(LambdaExpression le).getInitializer() or + e instanceof Closure +} + from Element e where - e.getLocation().getFile().getBaseName() != "" and - not e instanceof Container + interesting(e.getEnclosingElement*()) select e From 7096318884e4f5a9746c5e348aee20fde153eb60 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Fri, 24 Mar 2023 19:08:34 +0000 Subject: [PATCH 481/631] C++: Focus the templates extern test on Declarations. --- .../test/library-tests/templates/extern/elements.expected | 4 ---- cpp/ql/test/library-tests/templates/extern/elements.ql | 7 +++---- 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/cpp/ql/test/library-tests/templates/extern/elements.expected b/cpp/ql/test/library-tests/templates/extern/elements.expected index 2feaf133dca..5809f4c87a8 100644 --- a/cpp/ql/test/library-tests/templates/extern/elements.expected +++ b/cpp/ql/test/library-tests/templates/extern/elements.expected @@ -1,7 +1,3 @@ | extern.cpp:1:20:1:20 | T | -| extern.cpp:1:20:1:20 | definition of T | -| extern.cpp:2:5:2:5 | declaration of f | | extern.cpp:2:5:2:5 | f | | extern.cpp:2:7:2:7 | (unnamed parameter 0) | -| extern.cpp:2:7:2:7 | declaration of 1st parameter | -| extern.cpp:4:1:4:58 | // Currently we don't have an element for this declaration | diff --git a/cpp/ql/test/library-tests/templates/extern/elements.ql b/cpp/ql/test/library-tests/templates/extern/elements.ql index 7bc540f3b59..56dac14b946 100644 --- a/cpp/ql/test/library-tests/templates/extern/elements.ql +++ b/cpp/ql/test/library-tests/templates/extern/elements.ql @@ -1,7 +1,6 @@ import cpp -from Element e +from Declaration d where - e.getLocation().getFile().getBaseName() != "" and - not e instanceof Container -select e + d.getLocation().getFile().getBaseName() != "" +select d From 536c1939c046a142666849f46dc5d6113420408f Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Fri, 24 Mar 2023 19:22:18 +0000 Subject: [PATCH 482/631] C++: ... and rename the test to fit. --- .../templates/extern/{elements.expected => declarations.expected} | 0 .../templates/extern/{elements.ql => declarations.ql} | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename cpp/ql/test/library-tests/templates/extern/{elements.expected => declarations.expected} (100%) rename cpp/ql/test/library-tests/templates/extern/{elements.ql => declarations.ql} (100%) diff --git a/cpp/ql/test/library-tests/templates/extern/elements.expected b/cpp/ql/test/library-tests/templates/extern/declarations.expected similarity index 100% rename from cpp/ql/test/library-tests/templates/extern/elements.expected rename to cpp/ql/test/library-tests/templates/extern/declarations.expected diff --git a/cpp/ql/test/library-tests/templates/extern/elements.ql b/cpp/ql/test/library-tests/templates/extern/declarations.ql similarity index 100% rename from cpp/ql/test/library-tests/templates/extern/elements.ql rename to cpp/ql/test/library-tests/templates/extern/declarations.ql From 2b6cbc836dbc4cd516081fbae4a582dc19dca177 Mon Sep 17 00:00:00 2001 From: Harry Maclean <hmac@github.com> Date: Sat, 25 Mar 2023 10:39:41 +1300 Subject: [PATCH 483/631] Ruby: Remove outdated cache path --- .github/workflows/ruby-build.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/ruby-build.yml b/.github/workflows/ruby-build.yml index 7fc13d828af..8190d8c08fa 100644 --- a/.github/workflows/ruby-build.yml +++ b/.github/workflows/ruby-build.yml @@ -60,10 +60,8 @@ jobs: path: | ruby/extractor/target/release/autobuilder ruby/extractor/target/release/autobuilder.exe - ruby/extractor/target/x86_64-unknown-linux-gnu/release/autobuilder ruby/extractor/target/release/extractor ruby/extractor/target/release/extractor.exe - ruby/extractor/target/x86_64-unknown-linux-gnu/release/extractor ruby/extractor/ql/lib/codeql/ruby/ast/internal/TreeSitter.qll key: ${{ runner.os }}-${{ steps.os_version.outputs.version }}-ruby-extractor-${{ hashFiles('ruby/extractor/rust-toolchain.toml', 'ruby/extractor/Cargo.lock') }}--${{ hashFiles('ruby/extractor/**/*.rs') }} - uses: actions/cache@v3 From 6b2e8847f525ba1cb9dae2005c6c02e8d926b7db Mon Sep 17 00:00:00 2001 From: Harry Maclean <hmac@github.com> Date: Sat, 25 Mar 2023 10:43:07 +1300 Subject: [PATCH 484/631] Rename shared extractor It is now called `tree-sitter-extractor`, to make it clearer that it builds on tree-sitter grammars. --- ql/extractor/Cargo.toml | 2 +- ruby/extractor/Cargo.toml | 2 +- ruby/extractor/Cross.toml | 2 +- shared/{extractor => tree-sitter-extractor}/.gitignore | 0 shared/{extractor => tree-sitter-extractor}/Cargo.toml | 0 shared/{extractor => tree-sitter-extractor}/src/diagnostics.rs | 0 shared/{extractor => tree-sitter-extractor}/src/extractor.rs | 0 shared/{extractor => tree-sitter-extractor}/src/file_paths.rs | 0 .../src/generator/dbscheme.rs | 0 .../src/generator/language.rs | 0 .../{extractor => tree-sitter-extractor}/src/generator/mod.rs | 0 shared/{extractor => tree-sitter-extractor}/src/generator/ql.rs | 0 .../src/generator/ql_gen.rs | 0 shared/{extractor => tree-sitter-extractor}/src/lib.rs | 0 shared/{extractor => tree-sitter-extractor}/src/node_types.rs | 0 shared/{extractor => tree-sitter-extractor}/src/options.rs | 0 shared/{extractor => tree-sitter-extractor}/src/trap.rs | 0 17 files changed, 3 insertions(+), 3 deletions(-) rename shared/{extractor => tree-sitter-extractor}/.gitignore (100%) rename shared/{extractor => tree-sitter-extractor}/Cargo.toml (100%) rename shared/{extractor => tree-sitter-extractor}/src/diagnostics.rs (100%) rename shared/{extractor => tree-sitter-extractor}/src/extractor.rs (100%) rename shared/{extractor => tree-sitter-extractor}/src/file_paths.rs (100%) rename shared/{extractor => tree-sitter-extractor}/src/generator/dbscheme.rs (100%) rename shared/{extractor => tree-sitter-extractor}/src/generator/language.rs (100%) rename shared/{extractor => tree-sitter-extractor}/src/generator/mod.rs (100%) rename shared/{extractor => tree-sitter-extractor}/src/generator/ql.rs (100%) rename shared/{extractor => tree-sitter-extractor}/src/generator/ql_gen.rs (100%) rename shared/{extractor => tree-sitter-extractor}/src/lib.rs (100%) rename shared/{extractor => tree-sitter-extractor}/src/node_types.rs (100%) rename shared/{extractor => tree-sitter-extractor}/src/options.rs (100%) rename shared/{extractor => tree-sitter-extractor}/src/trap.rs (100%) diff --git a/ql/extractor/Cargo.toml b/ql/extractor/Cargo.toml index 4f9b4aebef0..57ffc5c5ad6 100644 --- a/ql/extractor/Cargo.toml +++ b/ql/extractor/Cargo.toml @@ -18,4 +18,4 @@ tracing = "0.1" tracing-subscriber = { version = "0.3.16", features = ["env-filter"] } rayon = "1.7.0" regex = "1.7.2" -codeql-extractor = { path = "../../shared/extractor" } +codeql-extractor = { path = "../../shared/tree-sitter-extractor" } diff --git a/ruby/extractor/Cargo.toml b/ruby/extractor/Cargo.toml index 439d86d4c41..ced118609fd 100644 --- a/ruby/extractor/Cargo.toml +++ b/ruby/extractor/Cargo.toml @@ -17,4 +17,4 @@ rayon = "1.5.0" regex = "1.7.1" encoding = "0.2" lazy_static = "1.4.0" -codeql-extractor = { path = "../../shared/extractor" } +codeql-extractor = { path = "../../shared/tree-sitter-extractor" } diff --git a/ruby/extractor/Cross.toml b/ruby/extractor/Cross.toml index 043f2826a7a..f3ed51aee59 100644 --- a/ruby/extractor/Cross.toml +++ b/ruby/extractor/Cross.toml @@ -5,4 +5,4 @@ image = "centos/devtoolset-7-toolchain-centos7" # Provide the path to the shared extractor # Cross mounts this directory as a volume, so builds inside the docker container # can see it. -volumes = ["__CODEQL-EXTRACTOR=../../shared/extractor"] +volumes = ["__CODEQL-EXTRACTOR=../../shared/tree-sitter-extractor"] diff --git a/shared/extractor/.gitignore b/shared/tree-sitter-extractor/.gitignore similarity index 100% rename from shared/extractor/.gitignore rename to shared/tree-sitter-extractor/.gitignore diff --git a/shared/extractor/Cargo.toml b/shared/tree-sitter-extractor/Cargo.toml similarity index 100% rename from shared/extractor/Cargo.toml rename to shared/tree-sitter-extractor/Cargo.toml diff --git a/shared/extractor/src/diagnostics.rs b/shared/tree-sitter-extractor/src/diagnostics.rs similarity index 100% rename from shared/extractor/src/diagnostics.rs rename to shared/tree-sitter-extractor/src/diagnostics.rs diff --git a/shared/extractor/src/extractor.rs b/shared/tree-sitter-extractor/src/extractor.rs similarity index 100% rename from shared/extractor/src/extractor.rs rename to shared/tree-sitter-extractor/src/extractor.rs diff --git a/shared/extractor/src/file_paths.rs b/shared/tree-sitter-extractor/src/file_paths.rs similarity index 100% rename from shared/extractor/src/file_paths.rs rename to shared/tree-sitter-extractor/src/file_paths.rs diff --git a/shared/extractor/src/generator/dbscheme.rs b/shared/tree-sitter-extractor/src/generator/dbscheme.rs similarity index 100% rename from shared/extractor/src/generator/dbscheme.rs rename to shared/tree-sitter-extractor/src/generator/dbscheme.rs diff --git a/shared/extractor/src/generator/language.rs b/shared/tree-sitter-extractor/src/generator/language.rs similarity index 100% rename from shared/extractor/src/generator/language.rs rename to shared/tree-sitter-extractor/src/generator/language.rs diff --git a/shared/extractor/src/generator/mod.rs b/shared/tree-sitter-extractor/src/generator/mod.rs similarity index 100% rename from shared/extractor/src/generator/mod.rs rename to shared/tree-sitter-extractor/src/generator/mod.rs diff --git a/shared/extractor/src/generator/ql.rs b/shared/tree-sitter-extractor/src/generator/ql.rs similarity index 100% rename from shared/extractor/src/generator/ql.rs rename to shared/tree-sitter-extractor/src/generator/ql.rs diff --git a/shared/extractor/src/generator/ql_gen.rs b/shared/tree-sitter-extractor/src/generator/ql_gen.rs similarity index 100% rename from shared/extractor/src/generator/ql_gen.rs rename to shared/tree-sitter-extractor/src/generator/ql_gen.rs diff --git a/shared/extractor/src/lib.rs b/shared/tree-sitter-extractor/src/lib.rs similarity index 100% rename from shared/extractor/src/lib.rs rename to shared/tree-sitter-extractor/src/lib.rs diff --git a/shared/extractor/src/node_types.rs b/shared/tree-sitter-extractor/src/node_types.rs similarity index 100% rename from shared/extractor/src/node_types.rs rename to shared/tree-sitter-extractor/src/node_types.rs diff --git a/shared/extractor/src/options.rs b/shared/tree-sitter-extractor/src/options.rs similarity index 100% rename from shared/extractor/src/options.rs rename to shared/tree-sitter-extractor/src/options.rs diff --git a/shared/extractor/src/trap.rs b/shared/tree-sitter-extractor/src/trap.rs similarity index 100% rename from shared/extractor/src/trap.rs rename to shared/tree-sitter-extractor/src/trap.rs From 202a717085eea8b4c908d26a37c7daabfc00c70e Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Fri, 24 Mar 2023 22:10:51 +0000 Subject: [PATCH 485/631] C++: Autoformat. --- cpp/ql/test/library-tests/lambdas/captures/elements.ql | 3 +-- cpp/ql/test/library-tests/templates/extern/declarations.ql | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/cpp/ql/test/library-tests/lambdas/captures/elements.ql b/cpp/ql/test/library-tests/lambdas/captures/elements.ql index 904f4d43155..ed93ddc6cbb 100644 --- a/cpp/ql/test/library-tests/lambdas/captures/elements.ql +++ b/cpp/ql/test/library-tests/lambdas/captures/elements.ql @@ -9,6 +9,5 @@ predicate interesting(Element e) { } from Element e -where - interesting(e.getEnclosingElement*()) +where interesting(e.getEnclosingElement*()) select e diff --git a/cpp/ql/test/library-tests/templates/extern/declarations.ql b/cpp/ql/test/library-tests/templates/extern/declarations.ql index 56dac14b946..82739e8cca2 100644 --- a/cpp/ql/test/library-tests/templates/extern/declarations.ql +++ b/cpp/ql/test/library-tests/templates/extern/declarations.ql @@ -1,6 +1,5 @@ import cpp from Declaration d -where - d.getLocation().getFile().getBaseName() != "" +where d.getLocation().getFile().getBaseName() != "" select d From 7aca5ee53476b14fc169fdf6d4497dbb06826ea4 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 27 Mar 2023 00:16:27 +0000 Subject: [PATCH 486/631] Add changed framework coverage reports --- java/documentation/library-coverage/coverage.csv | 9 +++++---- java/documentation/library-coverage/coverage.rst | 4 ++-- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/java/documentation/library-coverage/coverage.csv b/java/documentation/library-coverage/coverage.csv index 680b2440aab..16fbae8673a 100644 --- a/java/documentation/library-coverage/coverage.csv +++ b/java/documentation/library-coverage/coverage.csv @@ -49,13 +49,14 @@ 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.awt,,,3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,3 java.beans,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1, -java.io,42,,40,,17,,,,,,,,,,,,,,,3,,,,,,,,,,,,,22,,,,,,,,39,1 -java.lang,16,,76,,,,,,,,,,,,8,,,,,3,,4,,,1,,,,,,,,,,,,,,,,53,23 +java.io,42,,45,,17,,,,,,,,,,,,,,,3,,,,,,,,,,,,,22,,,,,,,,43,2 +java.lang,16,,90,,,,,,,,,,,,8,,,,,3,,4,,,1,,,,,,,,,,,,,,,,55,35 java.net,12,3,17,,,,,,,,,,,,,,,12,,,,,,,,,,,,,,,,,,,,,,3,17, -java.nio,25,,29,,19,,,,,,,,,,,,,,,4,,,,,,,,,,,,,2,,,,,,,,29, +java.nio,25,,30,,19,,,,,,,,,,,,,,,4,,,,,,,,,,,,,2,,,,,,,,30, java.sql,13,,3,,,,,,,,4,,,,,,,,,,,,,,,,,,9,,,,,,,,,,,,2,1 -java.util,44,,465,,,,,,,,,,,,34,,,,,,,,5,2,,1,2,,,,,,,,,,,,,,38,427 +java.util,44,,478,,,,,,,,,,,,34,,,,,,,,5,2,,1,2,,,,,,,,,,,,,,41,437 javafx.scene.web,1,,,,,,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,,,,, javax.faces.context,2,7,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,2,,,,7,, javax.imageio.stream,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1, diff --git a/java/documentation/library-coverage/coverage.rst b/java/documentation/library-coverage/coverage.rst index e2a186f1967..512c073d1fc 100644 --- a/java/documentation/library-coverage/coverage.rst +++ b/java/documentation/library-coverage/coverage.rst @@ -18,10 +18,10 @@ Java framework & library support `Google Guava <https://guava.dev/>`_,``com.google.common.*``,,730,39,,6,,,,, JBoss Logging,``org.jboss.logging``,,,324,,,,,,, `JSON-java <https://github.com/stleary/JSON-java>`_,``org.json``,,236,,,,,,,, - Java Standard Library,``java.*``,3,631,152,36,,,9,,,12 + Java Standard Library,``java.*``,3,667,152,36,,,9,,,12 Java extensions,"``javax.*``, ``jakarta.*``",63,611,34,1,,4,,1,1,2 Kotlin Standard Library,``kotlin*``,,1835,12,10,,,,,,2 `Spring <https://spring.io/>`_,``org.springframework.*``,29,480,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.thoughtworks.xstream``, ``com.unboundid.ldap.sdk``, ``com.zaxxer.hikari``, ``flexjson``, ``freemarker.cache``, ``freemarker.template``, ``groovy.lang``, ``groovy.util``, ``hudson.model``, ``hudson.os``, ``hudson.remoting``, ``hudson.util``, ``io.netty.bootstrap``, ``io.netty.channel``, ``io.netty.handler.codec.http``, ``io.netty.handler.ssl``, ``io.netty.handler.stream``, ``io.netty.resolver``, ``io.netty.util.internal``, ``javafx.scene.web``, ``jodd.json``, ``net.sf.saxon.s9api``, ``ognl``, ``okhttp3``, ``org.apache.commons.codec``, ``org.apache.commons.compress.archivers.tar``, ``org.apache.commons.jelly``, ``org.apache.commons.jexl2``, ``org.apache.commons.jexl3``, ``org.apache.commons.logging``, ``org.apache.commons.ognl``, ``org.apache.directory.ldap.client.api``, ``org.apache.hadoop.hive.metastore``, ``org.apache.hive.hcatalog.templeton``, ``org.apache.ibatis.jdbc``, ``org.apache.log4j``, ``org.apache.shiro.codec``, ``org.apache.shiro.jndi``, ``org.apache.tools.ant``, ``org.apache.tools.zip``, ``org.apache.velocity.app``, ``org.apache.velocity.runtime``, ``org.codehaus.cargo.container.installer``, ``org.codehaus.groovy.control``, ``org.dom4j``, ``org.geogebra.web.full.main``, ``org.hibernate``, ``org.jdbi.v3.core``, ``org.jooq``, ``org.kohsuke.stapler``, ``org.mvel2``, ``org.openjdk.jmh.runner.options``, ``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,314,328,12,,,18,18,,28 - Totals,,217,8508,1647,150,6,10,113,33,1,113 + Totals,,217,8544,1647,150,6,10,113,33,1,113 From 9a18043d9fc6dfce94df2db92a3d0789d1c4e88a Mon Sep 17 00:00:00 2001 From: Tony Torralba <atorralba@users.noreply.github.com> Date: Mon, 27 Mar 2023 10:28:13 +0200 Subject: [PATCH 487/631] Apply suggestions from code review --- java/ql/lib/ext/hudson.scm.model.yml | 6 +++--- java/ql/lib/ext/hudson.util.model.yml | 10 +++++++++- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/java/ql/lib/ext/hudson.scm.model.yml b/java/ql/lib/ext/hudson.scm.model.yml index 942fba356d1..477c31b6412 100644 --- a/java/ql/lib/ext/hudson.scm.model.yml +++ b/java/ql/lib/ext/hudson.scm.model.yml @@ -5,7 +5,7 @@ extensions: data: - ["hudson.scm", "ChangeLogParser", True, "parse", "(AbstractBuild,File)", "", "Argument[1]", "read-file", "ai-generated"] - ["hudson.scm", "ChangeLogParser", True, "parse", "(Run,RepositoryBrowser,File)", "", "Argument[2]", "read-file", "ai-generated"] - - ["hudson.scm", "SCM", True, "checkout", "(AbstractBuild,Launcher,FilePath,BuildListener,File)", "", "Argument[2]", "create-file", "ai-generated"] # A repo will be checked out into this location.. + - ["hudson.scm", "SCM", True, "checkout", "(AbstractBuild,Launcher,FilePath,BuildListener,File)", "", "Argument[2]", "create-file", "ai-generated"] - ["hudson.scm", "SCM", True, "checkout", "(Run,Launcher,FilePath,TaskListener,File,SCMRevisionState)", "", "Argument[2]", "create-file", "ai-generated"] - ["hudson.scm", "SCM", True, "compareRemoteRevisionWith", "(Job,Launcher,FilePath,TaskListener,SCMRevisionState)", "", "Argument[2]", "read-file", "ai-generated"] - addsTo: @@ -14,5 +14,5 @@ extensions: data: - ["hudson.scm", "SCM", True, "getModuleRoot", "(FilePath,AbstractBuild)", "", "Argument[0]", "ReturnValue", "taint", "ai-generated"] - ["hudson.scm", "SCM", True, "getModuleRoot", "(FilePath)", "", "Argument[0]", "ReturnValue", "taint", "ai-generated"] - - ["hudson.scm", "SCM", True, "getModuleRoots", "(FilePath,AbstractBuild)", "", "Argument[0]", "ReturnValue.ArrayElement", "taint", "ai-generated"] - - ["hudson.scm", "SCM", True, "getModuleRoots", "(FilePath)", "", "Argument[0]", "ReturnValue.ArrayElement", "taint", "ai-generated"] + - ["hudson.scm", "SCM", True, "getModuleRoots", "(FilePath,AbstractBuild)", "", "Argument[0]", "ReturnValue", "taint", "ai-generated"] + - ["hudson.scm", "SCM", True, "getModuleRoots", "(FilePath)", "", "Argument[0]", "ReturnValue", "taint", "ai-generated"] diff --git a/java/ql/lib/ext/hudson.util.model.yml b/java/ql/lib/ext/hudson.util.model.yml index cb32fd33bcf..969bd4a1e86 100644 --- a/java/ql/lib/ext/hudson.util.model.yml +++ b/java/ql/lib/ext/hudson.util.model.yml @@ -9,9 +9,17 @@ extensions: - ["hudson.util", "ClasspathBuilder", True, "add", "(FilePath)", "", "Argument[0]", "read-file", "ai-generated"] - ["hudson.util", "IOUtils", True, "mkdirs", "(File)", "", "Argument[0]", "create-file", "ai-generated"] - ["hudson.util", "StreamTaskListener", True, "StreamTaskListener", "(File,boolean,Charset)", "", "Argument[0]", "create-file", "ai-generated"] - - ["hudson.util", "TextFile", True, "TextFile", "(File)", "", "Argument[0]", "create-file", "ai-generated"] # @atorralba, PTAL - this class can be used to later write to/read from the file, but also only check existence. Could make ctor a step instead..? + - ["hudson.util", "TextFile", True, "delete", "()", "", "Argument[this]", "create-file", "manual"] + - ["hudson.util", "TextFile", True, "fastTail", "", "", "Argument[this]", "read-file", "manual"] + - ["hudson.util", "TextFile", True, "head", "", "", "Argument[this]", "read-file", "manual"] + - ["hudson.util", "TextFile", True, "lines", "()", "", "Argument[this]", "read-file", "manual"] + - ["hudson.util", "TextFile", True, "read", "()", "", "Argument[this]", "read-file", "manual"] + - ["hudson.util", "TextFile", True, "readTrim", "()", "", "Argument[this]", "read-file", "manual"] + - ["hudson.util", "TextFile", True, "write", "(String)", "", "Argument[0]", "write-file", "manual"] - addsTo: pack: codeql/java-all extensible: summaryModel data: - ["hudson.util", "QuotedStringTokenizer", True, "tokenize", "(String)", "", "Argument[0]", "ReturnValue", "taint", "ai-generated"] + - ["hudson.util", "TextFile", True, "TextFile", "(File)", "", "Argument[0]", "Argument[this]", "taint", "ai-generated"] + From ea1ca03bf1202556438ed954256050b2033cf936 Mon Sep 17 00:00:00 2001 From: Tony Torralba <atorralba@users.noreply.github.com> Date: Mon, 27 Mar 2023 10:30:47 +0200 Subject: [PATCH 488/631] Add change note --- java/ql/lib/change-notes/2023-03-27-hudson-models.md | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 java/ql/lib/change-notes/2023-03-27-hudson-models.md diff --git a/java/ql/lib/change-notes/2023-03-27-hudson-models.md b/java/ql/lib/change-notes/2023-03-27-hudson-models.md new file mode 100644 index 00000000000..27c0b73cbbb --- /dev/null +++ b/java/ql/lib/change-notes/2023-03-27-hudson-models.md @@ -0,0 +1,7 @@ +--- +category: minorAnalysis +--- +* Added more sink and summary dataflow models for the following packages: + * `hudson.model` + * `hudson.scm` + * `hudson.util` From 9f88a72d9f6aa67affe63b0b7a620b183fee49c7 Mon Sep 17 00:00:00 2001 From: Michael Nebel <michaelnebel@github.com> Date: Thu, 23 Mar 2023 18:57:46 +0100 Subject: [PATCH 489/631] C#: Make cs/web/debug-binary respect transformation file RemoveAttribute. --- csharp/ql/lib/semmle/code/asp/WebConfig.qll | 24 +++++++++++++++++++ .../Security Features/CWE-011/ASPNetDebug.ql | 15 ++++++++++-- 2 files changed, 37 insertions(+), 2 deletions(-) diff --git a/csharp/ql/lib/semmle/code/asp/WebConfig.qll b/csharp/ql/lib/semmle/code/asp/WebConfig.qll index 34fa9cf3972..49e42fce5c1 100644 --- a/csharp/ql/lib/semmle/code/asp/WebConfig.qll +++ b/csharp/ql/lib/semmle/code/asp/WebConfig.qll @@ -11,6 +11,13 @@ class WebConfigXml extends XmlFile { WebConfigXml() { this.getName().matches("%Web.config") } } +/** + * A `Web.config` transformation file. + */ +class WebConfigReleaseTransformXml extends XmlFile { + WebConfigReleaseTransformXml() { this.getName().matches("%Web.Release.config") } +} + /** DEPRECATED: Alias for WebConfigXml */ deprecated class WebConfigXML = WebConfigXml; @@ -19,6 +26,11 @@ class ConfigurationXmlElement extends XmlElement { ConfigurationXmlElement() { this.getName().toLowerCase() = "configuration" } } +/** A `<compilation>` tag in an ASP.NET configuration file. */ +class CompilationXmlElement extends XmlElement { + CompilationXmlElement() { this.getName().toLowerCase() = "compilation" } +} + /** DEPRECATED: Alias for ConfigurationXmlElement */ deprecated class ConfigurationXMLElement = ConfigurationXmlElement; @@ -149,3 +161,15 @@ class HttpCookiesElement extends XmlElement { /** DEPRECATED: Alias for isRequireSsl */ deprecated predicate isRequireSSL() { this.isRequireSsl() } } + +/** A `Transform` attribute in a Web.config transformation file. */ +class TransformXmlAttribute extends XmlAttribute { + TransformXmlAttribute() { this.getName().toLowerCase() = "transform" } + + /** + * Gets the list of attribute removals in `Transform=RemoveAttributes(list)`. + */ + string getRemoveAttributes() { + result = this.getValue().regexpCapture("RemoveAttributes\\((.*)\\)", 1).splitAt(",") + } +} diff --git a/csharp/ql/src/Security Features/CWE-011/ASPNetDebug.ql b/csharp/ql/src/Security Features/CWE-011/ASPNetDebug.ql index 1180d4990f8..308f3eeeac2 100644 --- a/csharp/ql/src/Security Features/CWE-011/ASPNetDebug.ql +++ b/csharp/ql/src/Security Features/CWE-011/ASPNetDebug.ql @@ -19,6 +19,17 @@ import semmle.code.asp.WebConfig from SystemWebXmlElement web, XmlAttribute debugAttribute where - debugAttribute = web.getAChild("compilation").getAttribute("debug") and - not debugAttribute.getValue().toLowerCase() = "false" + exists(CompilationXmlElement compilation | compilation.getParent() = web | + debugAttribute = compilation.getAttribute("debug") and + not debugAttribute.getValue().toLowerCase() = "false" + ) and + not exists( + TransformXmlAttribute attribute, CompilationXmlElement compilation, + WebConfigReleaseTransformXml file + | + compilation = attribute.getElement() and + file = compilation.getFile() and + attribute.getRemoveAttributes() = "debug" and + file.getParentContainer() = web.getFile().getParentContainer() + ) select debugAttribute, "The 'debug' flag is set for an ASP.NET configuration file." From 15c9e7666ae40b4d5256c9df24c2e53cad093fd9 Mon Sep 17 00:00:00 2001 From: Alex Ford <alexrford@github.com> Date: Fri, 24 Mar 2023 15:56:31 +0000 Subject: [PATCH 490/631] Ruby: convert rb/sensitive-get-query into a @kind problem --- .../queries/security/cwe-598/SensitiveGetQuery.ql | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/ruby/ql/src/queries/security/cwe-598/SensitiveGetQuery.ql b/ruby/ql/src/queries/security/cwe-598/SensitiveGetQuery.ql index ba3faf3fcae..46dbe7623e9 100644 --- a/ruby/ql/src/queries/security/cwe-598/SensitiveGetQuery.ql +++ b/ruby/ql/src/queries/security/cwe-598/SensitiveGetQuery.ql @@ -2,7 +2,7 @@ * @name Sensitive data read from GET request * @description Placing sensitive data in a GET request increases the risk of * the data being exposed to an attacker. - * @kind path-problem + * @kind problem * @problem.severity warning * @security-severity 6.5 * @precision high @@ -12,12 +12,10 @@ */ import ruby -import DataFlow::PathGraph import codeql.ruby.security.SensitiveGetQueryQuery import codeql.ruby.security.SensitiveActions -from DataFlow::PathNode source, DataFlow::PathNode sink, SensitiveGetQuery::Configuration config -where config.hasFlowPath(source, sink) -select source.getNode(), source, sink, - "$@ for GET requests uses query parameter as sensitive data.", - source.getNode().(SensitiveGetQuery::Source).getHandler(), "Route handler" +from DataFlow::Node source, DataFlow::Node sink, SensitiveGetQuery::Configuration config +where config.hasFlow(source, sink) +select source, "$@ for GET requests uses query parameter as sensitive data.", + source.(SensitiveGetQuery::Source).getHandler(), "Route handler" From 32ea8420a96610e12a57e84db34b1ae899333c68 Mon Sep 17 00:00:00 2001 From: Michael Nebel <michaelnebel@github.com> Date: Thu, 23 Mar 2023 19:00:19 +0100 Subject: [PATCH 491/631] C#: Move the existing tests into separate folders to emulate separate projects and add some more tests. --- .../Security Features/CWE-011/ASPNetDebug.expected | 3 ++- .../Security Features/CWE-011/{bad => bad1}/Web.config | 0 .../Security Features/CWE-011/bad2/Web.Debug.config | 6 ++++++ .../Security Features/CWE-011/bad2/Web.config | 9 +++++++++ .../Security Features/CWE-011/{ => good1}/Web.config | 0 .../Security Features/CWE-011/good2/Web.Release.config | 6 ++++++ .../Security Features/CWE-011/good2/Web.config | 9 +++++++++ 7 files changed, 32 insertions(+), 1 deletion(-) rename csharp/ql/test/query-tests/Security Features/CWE-011/{bad => bad1}/Web.config (100%) create mode 100644 csharp/ql/test/query-tests/Security Features/CWE-011/bad2/Web.Debug.config create mode 100644 csharp/ql/test/query-tests/Security Features/CWE-011/bad2/Web.config rename csharp/ql/test/query-tests/Security Features/CWE-011/{ => good1}/Web.config (100%) create mode 100644 csharp/ql/test/query-tests/Security Features/CWE-011/good2/Web.Release.config create mode 100644 csharp/ql/test/query-tests/Security Features/CWE-011/good2/Web.config diff --git a/csharp/ql/test/query-tests/Security Features/CWE-011/ASPNetDebug.expected b/csharp/ql/test/query-tests/Security Features/CWE-011/ASPNetDebug.expected index de43111afa6..8025e4990fd 100644 --- a/csharp/ql/test/query-tests/Security Features/CWE-011/ASPNetDebug.expected +++ b/csharp/ql/test/query-tests/Security Features/CWE-011/ASPNetDebug.expected @@ -1 +1,2 @@ -| bad/Web.config:4:5:7:7 | debug=true | The 'debug' flag is set for an ASP.NET configuration file. | +| bad1/Web.config:4:5:7:7 | debug=true | The 'debug' flag is set for an ASP.NET configuration file. | +| bad2/Web.config:4:5:7:7 | debug=true | The 'debug' flag is set for an ASP.NET configuration file. | diff --git a/csharp/ql/test/query-tests/Security Features/CWE-011/bad/Web.config b/csharp/ql/test/query-tests/Security Features/CWE-011/bad1/Web.config similarity index 100% rename from csharp/ql/test/query-tests/Security Features/CWE-011/bad/Web.config rename to csharp/ql/test/query-tests/Security Features/CWE-011/bad1/Web.config diff --git a/csharp/ql/test/query-tests/Security Features/CWE-011/bad2/Web.Debug.config b/csharp/ql/test/query-tests/Security Features/CWE-011/bad2/Web.Debug.config new file mode 100644 index 00000000000..d12250bc040 --- /dev/null +++ b/csharp/ql/test/query-tests/Security Features/CWE-011/bad2/Web.Debug.config @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="utf-8" ?> +<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform"> + <system.web> + <compilation xdt:Transform="RemoveAttributes(debug)" /> + </system.web> +</configuration> \ No newline at end of file diff --git a/csharp/ql/test/query-tests/Security Features/CWE-011/bad2/Web.config b/csharp/ql/test/query-tests/Security Features/CWE-011/bad2/Web.config new file mode 100644 index 00000000000..ffc04c240fa --- /dev/null +++ b/csharp/ql/test/query-tests/Security Features/CWE-011/bad2/Web.config @@ -0,0 +1,9 @@ +<?xml version="1.0" encoding="utf-8" ?> +<configuration> + <system.web> + <compilation + defaultLanguage="c#" + debug="true" + /> + </system.web> +</configuration> diff --git a/csharp/ql/test/query-tests/Security Features/CWE-011/Web.config b/csharp/ql/test/query-tests/Security Features/CWE-011/good1/Web.config similarity index 100% rename from csharp/ql/test/query-tests/Security Features/CWE-011/Web.config rename to csharp/ql/test/query-tests/Security Features/CWE-011/good1/Web.config diff --git a/csharp/ql/test/query-tests/Security Features/CWE-011/good2/Web.Release.config b/csharp/ql/test/query-tests/Security Features/CWE-011/good2/Web.Release.config new file mode 100644 index 00000000000..d12250bc040 --- /dev/null +++ b/csharp/ql/test/query-tests/Security Features/CWE-011/good2/Web.Release.config @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="utf-8" ?> +<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform"> + <system.web> + <compilation xdt:Transform="RemoveAttributes(debug)" /> + </system.web> +</configuration> \ No newline at end of file diff --git a/csharp/ql/test/query-tests/Security Features/CWE-011/good2/Web.config b/csharp/ql/test/query-tests/Security Features/CWE-011/good2/Web.config new file mode 100644 index 00000000000..ffc04c240fa --- /dev/null +++ b/csharp/ql/test/query-tests/Security Features/CWE-011/good2/Web.config @@ -0,0 +1,9 @@ +<?xml version="1.0" encoding="utf-8" ?> +<configuration> + <system.web> + <compilation + defaultLanguage="c#" + debug="true" + /> + </system.web> +</configuration> From 4a64479551c49d6bcacc374b3d56c35b77122b4c Mon Sep 17 00:00:00 2001 From: Michael Nebel <michaelnebel@github.com> Date: Thu, 23 Mar 2023 19:37:06 +0100 Subject: [PATCH 492/631] C#: Add change note. --- csharp/ql/src/change-notes/2023-03-23-cs-web-debug-binary.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 csharp/ql/src/change-notes/2023-03-23-cs-web-debug-binary.md diff --git a/csharp/ql/src/change-notes/2023-03-23-cs-web-debug-binary.md b/csharp/ql/src/change-notes/2023-03-23-cs-web-debug-binary.md new file mode 100644 index 00000000000..d87479c02ce --- /dev/null +++ b/csharp/ql/src/change-notes/2023-03-23-cs-web-debug-binary.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* The query `cs/web/debug-binary` now disregards the `debug` attribute in case there is a transformation that removes it. \ No newline at end of file From 24aa16c919ca152e247a62fc699f2ff2ccc8ce71 Mon Sep 17 00:00:00 2001 From: Alex Ford <alexrford@github.com> Date: Mon, 27 Mar 2023 09:44:55 +0100 Subject: [PATCH 493/631] Ruby: update rb/sensitive-get-query test output --- .../cwe-598/SensitiveGetQuery.expected | 27 +++---------------- 1 file changed, 3 insertions(+), 24 deletions(-) diff --git a/ruby/ql/test/query-tests/security/cwe-598/SensitiveGetQuery.expected b/ruby/ql/test/query-tests/security/cwe-598/SensitiveGetQuery.expected index 005e2497be8..455befe0480 100644 --- a/ruby/ql/test/query-tests/security/cwe-598/SensitiveGetQuery.expected +++ b/ruby/ql/test/query-tests/security/cwe-598/SensitiveGetQuery.expected @@ -1,24 +1,3 @@ -edges -| app/controllers/users_controller.rb:4:11:4:16 | call to params : | app/controllers/users_controller.rb:4:11:4:27 | ...[...] | -| app/controllers/users_controller.rb:9:16:9:21 | call to params : | app/controllers/users_controller.rb:9:16:9:27 | ...[...] : | -| app/controllers/users_controller.rb:9:16:9:27 | ...[...] : | app/controllers/users_controller.rb:10:42:10:49 | password | -| app/controllers/users_controller.rb:14:5:14:13 | [post] self [@password] : | app/controllers/users_controller.rb:15:42:15:50 | self [@password] : | -| app/controllers/users_controller.rb:14:17:14:22 | call to params : | app/controllers/users_controller.rb:14:17:14:28 | ...[...] : | -| app/controllers/users_controller.rb:14:17:14:28 | ...[...] : | app/controllers/users_controller.rb:14:5:14:13 | [post] self [@password] : | -| app/controllers/users_controller.rb:15:42:15:50 | self [@password] : | app/controllers/users_controller.rb:15:42:15:50 | @password | -nodes -| app/controllers/users_controller.rb:4:11:4:16 | call to params : | semmle.label | call to params : | -| app/controllers/users_controller.rb:4:11:4:27 | ...[...] | semmle.label | ...[...] | -| app/controllers/users_controller.rb:9:16:9:21 | call to params : | semmle.label | call to params : | -| app/controllers/users_controller.rb:9:16:9:27 | ...[...] : | semmle.label | ...[...] : | -| app/controllers/users_controller.rb:10:42:10:49 | password | semmle.label | password | -| app/controllers/users_controller.rb:14:5:14:13 | [post] self [@password] : | semmle.label | [post] self [@password] : | -| app/controllers/users_controller.rb:14:17:14:22 | call to params : | semmle.label | call to params : | -| app/controllers/users_controller.rb:14:17:14:28 | ...[...] : | semmle.label | ...[...] : | -| app/controllers/users_controller.rb:15:42:15:50 | @password | semmle.label | @password | -| app/controllers/users_controller.rb:15:42:15:50 | self [@password] : | semmle.label | self [@password] : | -subpaths -#select -| app/controllers/users_controller.rb:4:11:4:16 | call to params | app/controllers/users_controller.rb:4:11:4:16 | call to params : | app/controllers/users_controller.rb:4:11:4:27 | ...[...] | $@ for GET requests uses query parameter as sensitive data. | app/controllers/users_controller.rb:3:3:6:5 | login_get_1 | Route handler | -| app/controllers/users_controller.rb:9:16:9:21 | call to params | app/controllers/users_controller.rb:9:16:9:21 | call to params : | app/controllers/users_controller.rb:10:42:10:49 | password | $@ for GET requests uses query parameter as sensitive data. | app/controllers/users_controller.rb:8:3:11:5 | login_get_2 | Route handler | -| app/controllers/users_controller.rb:14:17:14:22 | call to params | app/controllers/users_controller.rb:14:17:14:22 | call to params : | app/controllers/users_controller.rb:15:42:15:50 | @password | $@ for GET requests uses query parameter as sensitive data. | app/controllers/users_controller.rb:13:3:16:5 | login_get_3 | Route handler | +| app/controllers/users_controller.rb:4:11:4:16 | call to params | $@ for GET requests uses query parameter as sensitive data. | app/controllers/users_controller.rb:3:3:6:5 | login_get_1 | Route handler | +| app/controllers/users_controller.rb:9:16:9:21 | call to params | $@ for GET requests uses query parameter as sensitive data. | app/controllers/users_controller.rb:8:3:11:5 | login_get_2 | Route handler | +| app/controllers/users_controller.rb:14:17:14:22 | call to params | $@ for GET requests uses query parameter as sensitive data. | app/controllers/users_controller.rb:13:3:16:5 | login_get_3 | Route handler | From 6f0844742783b1d27643106aa2ea2edd5ecc6530 Mon Sep 17 00:00:00 2001 From: Alex Ford <alexrford@github.com> Date: Fri, 24 Mar 2023 16:11:59 +0000 Subject: [PATCH 494/631] Ruby: add a change note for rb/sensitive-get-query flow path removal --- .../change-notes/2023-03-24-sensitive-get-query-problem.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 ruby/ql/src/change-notes/2023-03-24-sensitive-get-query-problem.md diff --git a/ruby/ql/src/change-notes/2023-03-24-sensitive-get-query-problem.md b/ruby/ql/src/change-notes/2023-03-24-sensitive-get-query-problem.md new file mode 100644 index 00000000000..b6a090ffec5 --- /dev/null +++ b/ruby/ql/src/change-notes/2023-03-24-sensitive-get-query-problem.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* `rb/sensitive-get-query` no longer reports flow paths from input parameters to sensitive use nodes. This avoids cases where many flow paths could be generated for a single parameter, which caused excessive paths to be generated. From bc2a772f3ba6c63e6ea06d6a5dc0c60681fbde99 Mon Sep 17 00:00:00 2001 From: Asger F <asgerf@github.com> Date: Mon, 27 Mar 2023 11:08:39 +0200 Subject: [PATCH 495/631] JS: Add test case showing false negative --- .../CWE-079/DomBasedXss/ConsistencyDomBasedXss.expected | 1 + .../query-tests/Security/CWE-079/DomBasedXss/Xss.expected | 5 +++++ .../CWE-079/DomBasedXss/XssWithAdditionalSources.expected | 4 ++++ .../test/query-tests/Security/CWE-079/DomBasedXss/jquery.js | 3 +++ 4 files changed, 13 insertions(+) diff --git a/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/ConsistencyDomBasedXss.expected b/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/ConsistencyDomBasedXss.expected index e69de29bb2d..e75e80036ab 100644 --- a/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/ConsistencyDomBasedXss.expected +++ b/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/ConsistencyDomBasedXss.expected @@ -0,0 +1 @@ +| query-tests/Security/CWE-079/DomBasedXss/jquery.js:37 | expected an alert, but found none | NOT OK | | diff --git a/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/Xss.expected b/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/Xss.expected index 95fbc8f15c3..5bdb9ed574b 100644 --- a/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/Xss.expected +++ b/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/Xss.expected @@ -431,6 +431,8 @@ nodes | jquery.js:34:5:34:25 | '<b>' + ... '</b>' | | jquery.js:34:5:34:25 | '<b>' + ... '</b>' | | jquery.js:34:13:34:16 | hash | +| jquery.js:36:25:36:31 | tainted | +| jquery.js:36:25:36:31 | tainted | | json-stringify.jsx:5:9:5:36 | locale | | json-stringify.jsx:5:9:5:36 | locale | | json-stringify.jsx:5:18:5:36 | req.param("locale") | @@ -1512,6 +1514,8 @@ edges | express.js:7:15:7:33 | req.param("wobble") | express.js:7:15:7:33 | req.param("wobble") | | jquery.js:2:7:2:40 | tainted | jquery.js:7:20:7:26 | tainted | | jquery.js:2:7:2:40 | tainted | jquery.js:8:28:8:34 | tainted | +| jquery.js:2:7:2:40 | tainted | jquery.js:36:25:36:31 | tainted | +| jquery.js:2:7:2:40 | tainted | jquery.js:36:25:36:31 | tainted | | jquery.js:2:17:2:40 | documen ... .search | jquery.js:2:7:2:40 | tainted | | jquery.js:2:17:2:40 | documen ... .search | jquery.js:2:7:2:40 | tainted | | jquery.js:7:20:7:26 | tainted | jquery.js:7:5:7:34 | "<div i ... + "\\">" | @@ -2355,6 +2359,7 @@ edges | jquery.js:27:5:27:25 | hash.re ... #', '') | jquery.js:18:14:18:33 | window.location.hash | jquery.js:27:5:27:25 | hash.re ... #', '') | Cross-site scripting vulnerability due to $@. | jquery.js:18:14:18:33 | window.location.hash | user-provided value | | jquery.js:28:5:28:43 | window. ... ?', '') | jquery.js:28:5:28:26 | window. ... .search | jquery.js:28:5:28:43 | window. ... ?', '') | Cross-site scripting vulnerability due to $@. | jquery.js:28:5:28:26 | window. ... .search | user-provided value | | jquery.js:34:5:34:25 | '<b>' + ... '</b>' | jquery.js:18:14:18:33 | window.location.hash | jquery.js:34:5:34:25 | '<b>' + ... '</b>' | Cross-site scripting vulnerability due to $@. | jquery.js:18:14:18:33 | window.location.hash | user-provided value | +| jquery.js:36:25:36:31 | tainted | jquery.js:2:17:2:40 | documen ... .search | jquery.js:36:25:36:31 | tainted | Cross-site scripting vulnerability due to $@. | jquery.js:2:17:2:40 | documen ... .search | user-provided value | | json-stringify.jsx:31:40:31:61 | JSON.st ... locale) | json-stringify.jsx:5:18:5:36 | req.param("locale") | json-stringify.jsx:31:40:31:61 | JSON.st ... locale) | Cross-site scripting vulnerability due to $@. | json-stringify.jsx:5:18:5:36 | req.param("locale") | user-provided value | | json-stringify.jsx:35:40:35:61 | JSON.st ... jsonLD) | json-stringify.jsx:5:18:5:36 | req.param("locale") | json-stringify.jsx:35:40:35:61 | JSON.st ... jsonLD) | Cross-site scripting vulnerability due to $@. | json-stringify.jsx:5:18:5:36 | req.param("locale") | user-provided value | | jwt-server.js:11:19:11:29 | decoded.foo | jwt-server.js:7:17:7:35 | req.param("wobble") | jwt-server.js:11:19:11:29 | decoded.foo | Cross-site scripting vulnerability due to $@. | jwt-server.js:7:17:7:35 | req.param("wobble") | user-provided value | diff --git a/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/XssWithAdditionalSources.expected b/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/XssWithAdditionalSources.expected index 03c3dd0d9ca..107f1ffee5e 100644 --- a/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/XssWithAdditionalSources.expected +++ b/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/XssWithAdditionalSources.expected @@ -431,6 +431,8 @@ nodes | jquery.js:34:5:34:25 | '<b>' + ... '</b>' | | jquery.js:34:5:34:25 | '<b>' + ... '</b>' | | jquery.js:34:13:34:16 | hash | +| jquery.js:36:25:36:31 | tainted | +| jquery.js:36:25:36:31 | tainted | | json-stringify.jsx:5:9:5:36 | locale | | json-stringify.jsx:5:9:5:36 | locale | | json-stringify.jsx:5:18:5:36 | req.param("locale") | @@ -1562,6 +1564,8 @@ edges | express.js:7:15:7:33 | req.param("wobble") | express.js:7:15:7:33 | req.param("wobble") | | jquery.js:2:7:2:40 | tainted | jquery.js:7:20:7:26 | tainted | | jquery.js:2:7:2:40 | tainted | jquery.js:8:28:8:34 | tainted | +| jquery.js:2:7:2:40 | tainted | jquery.js:36:25:36:31 | tainted | +| jquery.js:2:7:2:40 | tainted | jquery.js:36:25:36:31 | tainted | | jquery.js:2:17:2:40 | documen ... .search | jquery.js:2:7:2:40 | tainted | | jquery.js:2:17:2:40 | documen ... .search | jquery.js:2:7:2:40 | tainted | | jquery.js:7:20:7:26 | tainted | jquery.js:7:5:7:34 | "<div i ... + "\\">" | diff --git a/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/jquery.js b/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/jquery.js index 3bff577fbdf..3369df5dd87 100644 --- a/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/jquery.js +++ b/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/jquery.js @@ -32,4 +32,7 @@ function test() { $(hash + 'blah'); // OK $('blah' + hash); // OK - does not start with '<' $('<b>' + hash + '</b>'); // NOT OK + + $('#foo').replaceWith(tainted); // NOT OK + $('#foo').replaceWith(() => tainted); // NOT OK } From 92a681213de87fafbba14270afe5a1b0c8707019 Mon Sep 17 00:00:00 2001 From: Asger F <asgerf@github.com> Date: Mon, 27 Mar 2023 11:17:27 +0200 Subject: [PATCH 496/631] JS: Step through jQuery callback return values --- .../semmle/javascript/frameworks/jQuery.qll | 19 +++++++++++++++++++ .../security/dataflow/DomBasedXssQuery.qll | 7 +++++++ .../ConsistencyDomBasedXss.expected | 1 - .../Security/CWE-079/DomBasedXss/Xss.expected | 7 +++++++ .../XssWithAdditionalSources.expected | 6 ++++++ 5 files changed, 39 insertions(+), 1 deletion(-) diff --git a/javascript/ql/lib/semmle/javascript/frameworks/jQuery.qll b/javascript/ql/lib/semmle/javascript/frameworks/jQuery.qll index 4fad4ae1b05..2a0affedd7f 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/jQuery.qll +++ b/javascript/ql/lib/semmle/javascript/frameworks/jQuery.qll @@ -563,6 +563,25 @@ module JQuery { } } + /** Gets a data flow node that reaches a sink that is interpreted as HTML. */ + private DataFlow::SourceNode htmlCallback(DataFlow::TypeBackTracker t) { + t.start() and + any(JQuery::MethodCall c).interpretsArgumentAsHtml(result.getALocalUse()) + or + exists(DataFlow::TypeBackTracker t2 | result = htmlCallback(t2).backtrack(t2, t)) + } + + /** + * Gets a function that is passed as a callback to a jQuery function, which will interpret its return value as HTML. + * + * For example, this gets the function `f` below: + * ```js + * function f() { ... } + * $('#foo').replaceWith(f); + * ``` + */ + DataFlow::FunctionNode htmlCallback() { result = htmlCallback(DataFlow::TypeBackTracker::end()) } + /** * Holds for jQuery plugin definitions of the form `$.fn.<pluginName> = <plugin>` or `$.extend($.fn, {<pluginName>, <plugin>})`. */ diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/DomBasedXssQuery.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/DomBasedXssQuery.qll index 8eb9d6d6849..767789fa27f 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/DomBasedXssQuery.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/DomBasedXssQuery.qll @@ -122,6 +122,13 @@ class Configuration extends TaintTracking::Configuration { TaintedUrlSuffix::step(src, trg, TaintedUrlSuffix::label(), DataFlow::FlowLabel::taint()) and inlbl = TaintedUrlSuffix::label() and outlbl = prefixLabel() + or + exists(DataFlow::FunctionNode callback | + callback = JQuery::htmlCallback() and + src = callback.getReturnNode() and + trg = callback and + inlbl = outlbl + ) } } diff --git a/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/ConsistencyDomBasedXss.expected b/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/ConsistencyDomBasedXss.expected index e75e80036ab..e69de29bb2d 100644 --- a/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/ConsistencyDomBasedXss.expected +++ b/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/ConsistencyDomBasedXss.expected @@ -1 +0,0 @@ -| query-tests/Security/CWE-079/DomBasedXss/jquery.js:37 | expected an alert, but found none | NOT OK | | diff --git a/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/Xss.expected b/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/Xss.expected index 5bdb9ed574b..d40a652b962 100644 --- a/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/Xss.expected +++ b/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/Xss.expected @@ -433,6 +433,9 @@ nodes | jquery.js:34:13:34:16 | hash | | jquery.js:36:25:36:31 | tainted | | jquery.js:36:25:36:31 | tainted | +| jquery.js:37:25:37:37 | () => tainted | +| jquery.js:37:25:37:37 | () => tainted | +| jquery.js:37:31:37:37 | tainted | | json-stringify.jsx:5:9:5:36 | locale | | json-stringify.jsx:5:9:5:36 | locale | | json-stringify.jsx:5:18:5:36 | req.param("locale") | @@ -1516,6 +1519,7 @@ edges | jquery.js:2:7:2:40 | tainted | jquery.js:8:28:8:34 | tainted | | jquery.js:2:7:2:40 | tainted | jquery.js:36:25:36:31 | tainted | | jquery.js:2:7:2:40 | tainted | jquery.js:36:25:36:31 | tainted | +| jquery.js:2:7:2:40 | tainted | jquery.js:37:31:37:37 | tainted | | jquery.js:2:17:2:40 | documen ... .search | jquery.js:2:7:2:40 | tainted | | jquery.js:2:17:2:40 | documen ... .search | jquery.js:2:7:2:40 | tainted | | jquery.js:7:20:7:26 | tainted | jquery.js:7:5:7:34 | "<div i ... + "\\">" | @@ -1569,6 +1573,8 @@ edges | jquery.js:28:5:28:26 | window. ... .search | jquery.js:28:5:28:43 | window. ... ?', '') | | jquery.js:34:13:34:16 | hash | jquery.js:34:5:34:25 | '<b>' + ... '</b>' | | jquery.js:34:13:34:16 | hash | jquery.js:34:5:34:25 | '<b>' + ... '</b>' | +| jquery.js:37:31:37:37 | tainted | jquery.js:37:25:37:37 | () => tainted | +| jquery.js:37:31:37:37 | tainted | jquery.js:37:25:37:37 | () => tainted | | json-stringify.jsx:5:9:5:36 | locale | json-stringify.jsx:11:51:11:56 | locale | | json-stringify.jsx:5:9:5:36 | locale | json-stringify.jsx:19:56:19:61 | locale | | json-stringify.jsx:5:9:5:36 | locale | json-stringify.jsx:31:55:31:60 | locale | @@ -2360,6 +2366,7 @@ edges | jquery.js:28:5:28:43 | window. ... ?', '') | jquery.js:28:5:28:26 | window. ... .search | jquery.js:28:5:28:43 | window. ... ?', '') | Cross-site scripting vulnerability due to $@. | jquery.js:28:5:28:26 | window. ... .search | user-provided value | | jquery.js:34:5:34:25 | '<b>' + ... '</b>' | jquery.js:18:14:18:33 | window.location.hash | jquery.js:34:5:34:25 | '<b>' + ... '</b>' | Cross-site scripting vulnerability due to $@. | jquery.js:18:14:18:33 | window.location.hash | user-provided value | | jquery.js:36:25:36:31 | tainted | jquery.js:2:17:2:40 | documen ... .search | jquery.js:36:25:36:31 | tainted | Cross-site scripting vulnerability due to $@. | jquery.js:2:17:2:40 | documen ... .search | user-provided value | +| jquery.js:37:25:37:37 | () => tainted | jquery.js:2:17:2:40 | documen ... .search | jquery.js:37:25:37:37 | () => tainted | Cross-site scripting vulnerability due to $@. | jquery.js:2:17:2:40 | documen ... .search | user-provided value | | json-stringify.jsx:31:40:31:61 | JSON.st ... locale) | json-stringify.jsx:5:18:5:36 | req.param("locale") | json-stringify.jsx:31:40:31:61 | JSON.st ... locale) | Cross-site scripting vulnerability due to $@. | json-stringify.jsx:5:18:5:36 | req.param("locale") | user-provided value | | json-stringify.jsx:35:40:35:61 | JSON.st ... jsonLD) | json-stringify.jsx:5:18:5:36 | req.param("locale") | json-stringify.jsx:35:40:35:61 | JSON.st ... jsonLD) | Cross-site scripting vulnerability due to $@. | json-stringify.jsx:5:18:5:36 | req.param("locale") | user-provided value | | jwt-server.js:11:19:11:29 | decoded.foo | jwt-server.js:7:17:7:35 | req.param("wobble") | jwt-server.js:11:19:11:29 | decoded.foo | Cross-site scripting vulnerability due to $@. | jwt-server.js:7:17:7:35 | req.param("wobble") | user-provided value | diff --git a/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/XssWithAdditionalSources.expected b/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/XssWithAdditionalSources.expected index 107f1ffee5e..5e5010d126e 100644 --- a/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/XssWithAdditionalSources.expected +++ b/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/XssWithAdditionalSources.expected @@ -433,6 +433,9 @@ nodes | jquery.js:34:13:34:16 | hash | | jquery.js:36:25:36:31 | tainted | | jquery.js:36:25:36:31 | tainted | +| jquery.js:37:25:37:37 | () => tainted | +| jquery.js:37:25:37:37 | () => tainted | +| jquery.js:37:31:37:37 | tainted | | json-stringify.jsx:5:9:5:36 | locale | | json-stringify.jsx:5:9:5:36 | locale | | json-stringify.jsx:5:18:5:36 | req.param("locale") | @@ -1566,6 +1569,7 @@ edges | jquery.js:2:7:2:40 | tainted | jquery.js:8:28:8:34 | tainted | | jquery.js:2:7:2:40 | tainted | jquery.js:36:25:36:31 | tainted | | jquery.js:2:7:2:40 | tainted | jquery.js:36:25:36:31 | tainted | +| jquery.js:2:7:2:40 | tainted | jquery.js:37:31:37:37 | tainted | | jquery.js:2:17:2:40 | documen ... .search | jquery.js:2:7:2:40 | tainted | | jquery.js:2:17:2:40 | documen ... .search | jquery.js:2:7:2:40 | tainted | | jquery.js:7:20:7:26 | tainted | jquery.js:7:5:7:34 | "<div i ... + "\\">" | @@ -1619,6 +1623,8 @@ edges | jquery.js:28:5:28:26 | window. ... .search | jquery.js:28:5:28:43 | window. ... ?', '') | | jquery.js:34:13:34:16 | hash | jquery.js:34:5:34:25 | '<b>' + ... '</b>' | | jquery.js:34:13:34:16 | hash | jquery.js:34:5:34:25 | '<b>' + ... '</b>' | +| jquery.js:37:31:37:37 | tainted | jquery.js:37:25:37:37 | () => tainted | +| jquery.js:37:31:37:37 | tainted | jquery.js:37:25:37:37 | () => tainted | | json-stringify.jsx:5:9:5:36 | locale | json-stringify.jsx:11:51:11:56 | locale | | json-stringify.jsx:5:9:5:36 | locale | json-stringify.jsx:19:56:19:61 | locale | | json-stringify.jsx:5:9:5:36 | locale | json-stringify.jsx:31:55:31:60 | locale | From f92f390457d0a793918fe548e2d82b6dca1ca589 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 27 Mar 2023 09:34:18 +0000 Subject: [PATCH 497/631] Bump regex from 1.7.2 to 1.7.3 in /ql Bumps [regex](https://github.com/rust-lang/regex) from 1.7.2 to 1.7.3. - [Release notes](https://github.com/rust-lang/regex/releases) - [Changelog](https://github.com/rust-lang/regex/blob/master/CHANGELOG.md) - [Commits](https://github.com/rust-lang/regex/compare/1.7.2...1.7.3) --- updated-dependencies: - dependency-name: regex dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> --- ql/Cargo.lock | Bin 24184 -> 24184 bytes ql/buramu/Cargo.toml | 2 +- ql/extractor/Cargo.toml | 2 +- 3 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ql/Cargo.lock b/ql/Cargo.lock index ac27495128e0b35c5f94436e0b6c45df7aa31a04..41b76f14cfc6add81e8026cba5eec0068d7d33c0 100644 GIT binary patch delta 85 zcmWN_xeb6Y3;;l-We{pRF@8EWK#Y*j3sJBJ5^a`Y3re{1-Vxpru3bVp^0cj5(AiRn l<eaNvbW%&*K_gKUC=4v5(4u1|?zTWRHthde!*)M%&L4T`8JPe8 delta 82 zcmV~$u@QhE3;@7m8S4-dh@B(o2qb}hv~dmZY+1%FDE*%!%n_cWoY%gYwV0*1isGpO i_sF7NiA%N)CPdCatcGSOBlHTmVslnyiDd6r?&SxdC>r4a diff --git a/ql/buramu/Cargo.toml b/ql/buramu/Cargo.toml index b12e6d9a9c6..5b87a8a90be 100644 --- a/ql/buramu/Cargo.toml +++ b/ql/buramu/Cargo.toml @@ -9,4 +9,4 @@ edition = "2018" lazy_static = "1.4.0" chrono = "0.4.24" rayon = "1.7.0" -regex = "1.7.2" +regex = "1.7.3" diff --git a/ql/extractor/Cargo.toml b/ql/extractor/Cargo.toml index 57ffc5c5ad6..fe4712a03d5 100644 --- a/ql/extractor/Cargo.toml +++ b/ql/extractor/Cargo.toml @@ -17,5 +17,5 @@ clap = "2.33" tracing = "0.1" tracing-subscriber = { version = "0.3.16", features = ["env-filter"] } rayon = "1.7.0" -regex = "1.7.2" +regex = "1.7.3" codeql-extractor = { path = "../../shared/tree-sitter-extractor" } From f8c28bee6a2ce4bbcb8d4a38053cbd9ed73109aa Mon Sep 17 00:00:00 2001 From: Tom Hvitved <hvitved@github.com> Date: Tue, 21 Mar 2023 11:23:38 +0100 Subject: [PATCH 498/631] Ruby: Order synthetic children in PrintAST based on their index instead of location --- ruby/ql/lib/codeql/ruby/ast/internal/Call.qll | 9 +- .../codeql/ruby/ast/internal/Synthesis.qll | 35 +- ruby/ql/lib/codeql/ruby/printAst.qll | 23 +- .../library-tests/ast/AstDesugar.expected | 314 +++++++++--------- .../library-tests/ast/calls/calls.expected | 6 +- .../controlflow/graph/Cfg.expected | 12 +- .../controlflow/graph/Nodes.expected | 4 +- 7 files changed, 206 insertions(+), 197 deletions(-) diff --git a/ruby/ql/lib/codeql/ruby/ast/internal/Call.qll b/ruby/ql/lib/codeql/ruby/ast/internal/Call.qll index b6ac243e891..74acef8e860 100644 --- a/ruby/ql/lib/codeql/ruby/ast/internal/Call.qll +++ b/ruby/ql/lib/codeql/ruby/ast/internal/Call.qll @@ -43,11 +43,16 @@ class MethodCallSynth extends MethodCallImpl, TMethodCallSynth { final override AstNode getReceiverImpl() { synthChild(this, 0, result) } - final override AstNode getArgumentImpl(int n) { synthChild(this, n + 1, result) and n >= 0 } + final override AstNode getArgumentImpl(int n) { + synthChild(this, n + 1, result) and + n in [0 .. this.getNumberOfArgumentsImpl() - 1] + } final override int getNumberOfArgumentsImpl() { this = TMethodCallSynth(_, _, _, _, result) } - final override Block getBlockImpl() { synthChild(this, -2, result) } + final override Block getBlockImpl() { + synthChild(this, this.getNumberOfArgumentsImpl() + 1, result) + } } class IdentifierMethodCall extends MethodCallImpl, TIdentifierMethodCall { diff --git a/ruby/ql/lib/codeql/ruby/ast/internal/Synthesis.qll b/ruby/ql/lib/codeql/ruby/ast/internal/Synthesis.qll index d74b76a1998..6c92f401001 100644 --- a/ruby/ql/lib/codeql/ruby/ast/internal/Synthesis.qll +++ b/ruby/ql/lib/codeql/ruby/ast/internal/Synthesis.qll @@ -818,7 +818,7 @@ private module AssignOperationDesugar { i in [0 .. sao.getNumberOfArguments()] or parent = setter and - i = opAssignIndex + 1 and + i = opAssignIndex and child = SynthChild(LocalVariableAccessSynthKind(TLocalVariableSynth(sao, opAssignIndex))) ) @@ -975,7 +975,7 @@ private module DestructuredAssignDesugar { pragma[nomagic] private predicate destructuredAssignSynthesis(AstNode parent, int i, Child child) { - exists(DestructuredAssignExpr tae | + exists(DestructuredAssignExpr tae, int total | total = tae.getNumberOfElements() | parent = tae and i = -1 and child = SynthChild(StmtSequenceKind()) @@ -998,15 +998,13 @@ private module DestructuredAssignDesugar { ) or parent = seq and - i = tae.getNumberOfElements() and + i = total and child = SynthChild(AssignExprKind()) or - exists(AstNode assign | assign = TAssignExprSynth(seq, tae.getNumberOfElements()) | + exists(AstNode assign | assign = TAssignExprSynth(seq, total) | parent = assign and i = 0 and - child = - SynthChild(LocalVariableAccessSynthKind(TLocalVariableSynth(tae, - tae.getNumberOfElements()))) + child = SynthChild(LocalVariableAccessSynthKind(TLocalVariableSynth(tae, total))) or parent = assign and i = 1 and @@ -1022,12 +1020,10 @@ private module DestructuredAssignDesugar { restIndex = tae.getRestIndexOrNumberOfElements() | parent = seq and - i = j + 1 + tae.getNumberOfElements() and + i = j + 1 + total and child = SynthChild(AssignExprKind()) or - exists(AstNode assign | - assign = TAssignExprSynth(seq, j + 1 + tae.getNumberOfElements()) - | + exists(AstNode assign | assign = TAssignExprSynth(seq, j + 1 + total) | exists(LhsWithReceiver mc | mc = elem | parent = assign and i = 0 and @@ -1063,9 +1059,7 @@ private module DestructuredAssignDesugar { or parent = TMethodCallSynth(assign, 1, _, _, _) and i = 0 and - child = - SynthChild(LocalVariableAccessSynthKind(TLocalVariableSynth(tae, - tae.getNumberOfElements()))) + child = SynthChild(LocalVariableAccessSynthKind(TLocalVariableSynth(tae, total))) or j < restIndex and parent = TMethodCallSynth(assign, 1, _, _, _) and @@ -1086,14 +1080,14 @@ private module DestructuredAssignDesugar { child = SynthChild(IntegerLiteralKind(j)) or i = 1 and - child = SynthChild(IntegerLiteralKind(restIndex - tae.getNumberOfElements())) + child = SynthChild(IntegerLiteralKind(restIndex - total)) ) ) or j > restIndex and parent = TMethodCallSynth(assign, 1, _, _, _) and i = 1 and - child = SynthChild(IntegerLiteralKind(j - tae.getNumberOfElements())) + child = SynthChild(IntegerLiteralKind(j - total)) ) ) ) @@ -1284,10 +1278,10 @@ private module ForLoopDesugar { child = childRef(for.getValue()) // value is the Enumerable or parent = eachCall and - i = -2 and + i = 1 and child = SynthChild(BraceBlockKind()) or - exists(Block block | block = TBraceBlockSynth(eachCall, -2) | + exists(Block block | block = TBraceBlockSynth(eachCall, 1) | // block params parent = block and i = 0 and @@ -1534,14 +1528,13 @@ private module SafeNavigationCallDesugar { i = 1 ) or - parent = TMethodCallSynth(ifExpr, 2, _, _, _) and - ( + exists(int arity | parent = TMethodCallSynth(ifExpr, 2, _, _, arity) | i = 0 and child = SynthChild(local) or child = childRef(call.getArgumentImpl(i - 1)) or - child = childRef(call.getBlockImpl()) and i = -2 + child = childRef(call.getBlockImpl()) and i = arity + 1 ) ) ) diff --git a/ruby/ql/lib/codeql/ruby/printAst.qll b/ruby/ql/lib/codeql/ruby/printAst.qll index 25aa7908db3..c15b717610a 100644 --- a/ruby/ql/lib/codeql/ruby/printAst.qll +++ b/ruby/ql/lib/codeql/ruby/printAst.qll @@ -36,8 +36,6 @@ private predicate shouldPrintAstEdge(AstNode parent, string edgeName, AstNode ch any(PrintAstConfiguration config).shouldPrintAstEdge(parent, edgeName, child) } -private int nonSynthIndex() { result = min([-1, any(int i | exists(getSynthChild(_, i)))]) - 1 } - newtype TPrintNode = TPrintRegularAstNode(AstNode n) { shouldPrintNode(n) } or TPrintRegExpNode(RE::RegExpTerm term) { @@ -115,10 +113,23 @@ class PrintRegularAstNode extends PrintAstNode, TPrintRegularAstNode { ) } + private predicate parentIsSynthesized() { + exists(AstNode parent | + shouldPrintAstEdge(parent, _, astNode) and + parent.isSynthesized() + ) + } + private int getSynthAstNodeIndex() { - not astNode.isSynthesized() and result = nonSynthIndex() + this.parentIsSynthesized() and + exists(AstNode parent | + shouldPrintAstEdge(parent, _, astNode) and + parent.isSynthesized() and + synthChild(parent, result, astNode) + ) or - astNode = getSynthChild(astNode.getParent(), result) + not this.parentIsSynthesized() and + result = 0 } override int getOrder() { @@ -129,8 +140,8 @@ class PrintRegularAstNode extends PrintAstNode, TPrintRegularAstNode { | p order by - f.getBaseName(), f.getAbsolutePath(), l.getStartLine(), l.getStartColumn(), - l.getEndLine(), l.getEndColumn(), p.getSynthAstNodeIndex() + f.getBaseName(), f.getAbsolutePath(), l.getStartLine(), p.getSynthAstNodeIndex(), + l.getStartColumn(), l.getEndLine(), l.getEndColumn() ) } diff --git a/ruby/ql/test/library-tests/ast/AstDesugar.expected b/ruby/ql/test/library-tests/ast/AstDesugar.expected index d8b49833332..3625cb83574 100644 --- a/ruby/ql/test/library-tests/ast/AstDesugar.expected +++ b/ruby/ql/test/library-tests/ast/AstDesugar.expected @@ -25,28 +25,28 @@ calls/calls.rb: # 67| getReceiver: [ConstantReadAccess] X # 226| [ForExpr] for ... in ... # 226| getDesugared: [MethodCall] call to each +# 226| getReceiver: [MethodCall] call to bar +# 226| getReceiver: [SelfVariableAccess] self # 226| getBlock: [BraceBlock] { ... } # 226| getParameter: [SimpleParameter] __synth__0__1 # 226| getDefiningAccess: [LocalVariableAccess] __synth__0__1 # 226| getStmt: [AssignExpr] ... = ... -# 226| getAnOperand/getRightOperand: [LocalVariableAccess] __synth__0__1 # 226| getAnOperand/getLeftOperand: [LocalVariableAccess] x +# 226| getAnOperand/getRightOperand: [LocalVariableAccess] __synth__0__1 # 227| getStmt: [MethodCall] call to baz # 227| getReceiver: [SelfVariableAccess] self -# 226| getReceiver: [MethodCall] call to bar -# 226| getReceiver: [SelfVariableAccess] self # 229| [ForExpr] for ... in ... # 229| getDesugared: [MethodCall] call to each +# 229| getReceiver: [MethodCall] call to bar +# 229| getReceiver: [ConstantReadAccess] X # 229| getBlock: [BraceBlock] { ... } # 229| getParameter: [SimpleParameter] __synth__0__1 # 229| getDefiningAccess: [LocalVariableAccess] __synth__0__1 # 229| getStmt: [AssignExpr] ... = ... -# 229| getAnOperand/getRightOperand: [LocalVariableAccess] __synth__0__1 # 229| getAnOperand/getLeftOperand: [LocalVariableAccess] x +# 229| getAnOperand/getRightOperand: [LocalVariableAccess] __synth__0__1 # 230| getStmt: [MethodCall] call to baz # 230| getReceiver: [ConstantReadAccess] X -# 229| getReceiver: [MethodCall] call to bar -# 229| getReceiver: [ConstantReadAccess] X # 249| [HashLiteral] {...} # 249| getDesugared: [MethodCall] call to [] # 249| getReceiver: [ConstantReadAccess] Hash @@ -65,8 +65,8 @@ calls/calls.rb: # 316| getStmt: [SetterMethodCall] call to foo= # 316| getReceiver: [SelfVariableAccess] self # 316| getArgument: [AssignExpr] ... = ... -# 316| getAnOperand/getRightOperand: [IntegerLiteral] 10 # 316| getAnOperand/getLeftOperand: [LocalVariableAccess] __synth__0 +# 316| getAnOperand/getRightOperand: [IntegerLiteral] 10 # 316| getStmt: [LocalVariableAccess] __synth__0 # 317| [AssignExpr] ... = ... # 317| getDesugared: [StmtSequence] ... @@ -75,14 +75,31 @@ calls/calls.rb: # 317| getReceiver: [SelfVariableAccess] self # 317| getArgument: [IntegerLiteral] 0 # 317| getArgument: [AssignExpr] ... = ... -# 317| getAnOperand/getRightOperand: [IntegerLiteral] 10 # 317| getAnOperand/getLeftOperand: [LocalVariableAccess] __synth__0 +# 317| getAnOperand/getRightOperand: [IntegerLiteral] 10 # 317| getStmt: [LocalVariableAccess] __synth__0 # 318| [AssignExpr] ... = ... # 318| getDesugared: [StmtSequence] ... # 318| getStmt: [AssignExpr] ... = ... -# 318| getAnOperand/getRightOperand: [SelfVariableAccess] self # 318| getAnOperand/getLeftOperand: [LocalVariableAccess] __synth__0 +# 318| getAnOperand/getRightOperand: [SelfVariableAccess] self +# 318| getStmt: [AssignExpr] ... = ... +# 318| getAnOperand/getLeftOperand: [LocalVariableAccess] __synth__1 +# 318| getAnOperand/getRightOperand: [SelfVariableAccess] self +# 318| getStmt: [AssignExpr] ... = ... +# 318| getAnOperand/getLeftOperand: [LocalVariableAccess] __synth__2 +# 318| getAnOperand/getRightOperand: [MethodCall] call to foo +# 318| getReceiver: [SelfVariableAccess] self +# 318| getStmt: [AssignExpr] ... = ... +# 318| getAnOperand/getLeftOperand: [LocalVariableAccess] __synth__3 +# 318| getAnOperand/getRightOperand: [SplatExpr] * ... +# 318| getAnOperand/getOperand/getReceiver: [ArrayLiteral] [...] +# 318| getDesugared: [MethodCall] call to [] +# 318| getReceiver: [ConstantReadAccess] Array +# 318| getArgument: [IntegerLiteral] 1 +# 318| getArgument: [IntegerLiteral] 2 +# 318| getArgument: [IntegerLiteral] 3 +# 318| getArgument: [IntegerLiteral] 4 # 318| getStmt: [AssignExpr] ... = ... # 318| getDesugared: [StmtSequence] ... # 318| getStmt: [SetterMethodCall] call to foo= @@ -95,9 +112,6 @@ calls/calls.rb: # 318| getStmt: [LocalVariableAccess] __synth__0__1 # 318| getAnOperand/getLeftOperand: [MethodCall] call to foo # 318| getStmt: [AssignExpr] ... = ... -# 318| getAnOperand/getRightOperand: [SelfVariableAccess] self -# 318| getAnOperand/getLeftOperand: [LocalVariableAccess] __synth__1 -# 318| getStmt: [AssignExpr] ... = ... # 318| getDesugared: [StmtSequence] ... # 318| getStmt: [SetterMethodCall] call to bar= # 318| getReceiver: [LocalVariableAccess] __synth__1 @@ -111,56 +125,23 @@ calls/calls.rb: # 318| getStmt: [LocalVariableAccess] __synth__0__1 # 318| getAnOperand/getLeftOperand: [MethodCall] call to bar # 318| getStmt: [AssignExpr] ... = ... -# 318| getAnOperand/getRightOperand: [MethodCall] call to foo -# 318| getReceiver: [SelfVariableAccess] self -# 318| getAnOperand/getLeftOperand: [LocalVariableAccess] __synth__2 -# 318| getStmt: [AssignExpr] ... = ... # 318| getDesugared: [StmtSequence] ... # 318| getStmt: [SetterMethodCall] call to []= # 318| getReceiver: [LocalVariableAccess] __synth__2 +# 318| getArgument: [IntegerLiteral] 4 # 318| getArgument: [AssignExpr] ... = ... # 318| getAnOperand/getLeftOperand: [LocalVariableAccess] __synth__0__1 # 318| getAnOperand/getRightOperand: [MethodCall] call to [] # 318| getReceiver: [LocalVariableAccess] __synth__3 # 318| getArgument: [IntegerLiteral] -1 -# 318| getArgument: [IntegerLiteral] 4 # 318| getStmt: [LocalVariableAccess] __synth__0__1 # 318| getAnOperand/getLeftOperand: [MethodCall] call to [] -# 318| getStmt: [AssignExpr] ... = ... -# 318| getAnOperand/getLeftOperand: [LocalVariableAccess] __synth__3 -# 318| getAnOperand/getRightOperand: [SplatExpr] * ... -# 318| getAnOperand/getOperand/getReceiver: [ArrayLiteral] [...] -# 318| getDesugared: [MethodCall] call to [] -# 318| getReceiver: [ConstantReadAccess] Array -# 318| getArgument: [IntegerLiteral] 1 -# 318| getArgument: [IntegerLiteral] 2 -# 318| getArgument: [IntegerLiteral] 3 -# 318| getArgument: [IntegerLiteral] 4 # 319| [AssignExpr] ... = ... # 319| getDesugared: [StmtSequence] ... # 319| getStmt: [AssignExpr] ... = ... -# 319| getAnOperand/getLeftOperand: [LocalVariableAccess] a -# 319| getAnOperand/getRightOperand: [MethodCall] call to [] -# 319| getReceiver: [LocalVariableAccess] __synth__2 -# 319| getArgument: [IntegerLiteral] 0 -# 319| getStmt: [AssignExpr] ... = ... +# 319| getAnOperand/getLeftOperand: [LocalVariableAccess] __synth__1 # 319| getAnOperand/getRightOperand: [MethodCall] call to foo # 319| getReceiver: [SelfVariableAccess] self -# 319| getAnOperand/getLeftOperand: [LocalVariableAccess] __synth__1 -# 319| getStmt: [AssignExpr] ... = ... -# 319| getDesugared: [StmtSequence] ... -# 319| getStmt: [SetterMethodCall] call to []= -# 319| getReceiver: [LocalVariableAccess] __synth__1 -# 319| getArgument: [AssignExpr] ... = ... -# 319| getAnOperand/getLeftOperand: [LocalVariableAccess] __synth__0__1 -# 319| getAnOperand/getRightOperand: [MethodCall] call to [] -# 319| getReceiver: [LocalVariableAccess] __synth__2 -# 319| getArgument: [RangeLiteral] _ .. _ -# 319| getBegin: [IntegerLiteral] 1 -# 319| getEnd: [IntegerLiteral] -1 -# 319| getArgument: [IntegerLiteral] 5 -# 319| getStmt: [LocalVariableAccess] __synth__0__1 -# 319| getAnOperand/getLeftOperand: [MethodCall] call to [] # 319| getStmt: [AssignExpr] ... = ... # 319| getAnOperand/getLeftOperand: [LocalVariableAccess] __synth__2 # 319| getAnOperand/getRightOperand: [SplatExpr] * ... @@ -170,34 +151,49 @@ calls/calls.rb: # 319| getArgument: [IntegerLiteral] 1 # 319| getArgument: [IntegerLiteral] 2 # 319| getArgument: [IntegerLiteral] 3 +# 319| getStmt: [AssignExpr] ... = ... +# 319| getAnOperand/getLeftOperand: [LocalVariableAccess] a +# 319| getAnOperand/getRightOperand: [MethodCall] call to [] +# 319| getReceiver: [LocalVariableAccess] __synth__2 +# 319| getArgument: [IntegerLiteral] 0 +# 319| getStmt: [AssignExpr] ... = ... +# 319| getDesugared: [StmtSequence] ... +# 319| getStmt: [SetterMethodCall] call to []= +# 319| getReceiver: [LocalVariableAccess] __synth__1 +# 319| getArgument: [IntegerLiteral] 5 +# 319| getArgument: [AssignExpr] ... = ... +# 319| getAnOperand/getLeftOperand: [LocalVariableAccess] __synth__0__1 +# 319| getAnOperand/getRightOperand: [MethodCall] call to [] +# 319| getReceiver: [LocalVariableAccess] __synth__2 +# 319| getArgument: [RangeLiteral] _ .. _ +# 319| getBegin: [IntegerLiteral] 1 +# 319| getEnd: [IntegerLiteral] -1 +# 319| getStmt: [LocalVariableAccess] __synth__0__1 +# 319| getAnOperand/getLeftOperand: [MethodCall] call to [] # 320| [AssignAddExpr] ... += ... # 320| getDesugared: [StmtSequence] ... # 320| getStmt: [AssignExpr] ... = ... -# 320| getAnOperand/getRightOperand: [SelfVariableAccess] self # 320| getAnOperand/getLeftOperand: [LocalVariableAccess] __synth__0 -# 320| getStmt: [SetterMethodCall] call to count= -# 320| getReceiver: [LocalVariableAccess] __synth__0 -# 320| getArgument: [LocalVariableAccess] __synth__1 +# 320| getAnOperand/getRightOperand: [SelfVariableAccess] self # 320| getStmt: [AssignExpr] ... = ... # 320| getAnOperand/getLeftOperand: [LocalVariableAccess] __synth__1 # 320| getAnOperand/getRightOperand: [AddExpr] ... + ... # 320| getAnOperand/getLeftOperand/getReceiver: [MethodCall] call to count # 320| getReceiver: [LocalVariableAccess] __synth__0 # 320| getAnOperand/getArgument/getRightOperand: [IntegerLiteral] 1 +# 320| getStmt: [SetterMethodCall] call to count= +# 320| getReceiver: [LocalVariableAccess] __synth__0 +# 320| getArgument: [LocalVariableAccess] __synth__1 # 320| getStmt: [LocalVariableAccess] __synth__1 # 321| [AssignAddExpr] ... += ... # 321| getDesugared: [StmtSequence] ... # 321| getStmt: [AssignExpr] ... = ... +# 321| getAnOperand/getLeftOperand: [LocalVariableAccess] __synth__0 # 321| getAnOperand/getRightOperand: [MethodCall] call to foo # 321| getReceiver: [SelfVariableAccess] self -# 321| getAnOperand/getLeftOperand: [LocalVariableAccess] __synth__0 -# 321| getStmt: [SetterMethodCall] call to []= -# 321| getReceiver: [LocalVariableAccess] __synth__0 -# 321| getArgument: [LocalVariableAccess] __synth__1 -# 321| getArgument: [LocalVariableAccess] __synth__2 # 321| getStmt: [AssignExpr] ... = ... -# 321| getAnOperand/getRightOperand: [IntegerLiteral] 0 # 321| getAnOperand/getLeftOperand: [LocalVariableAccess] __synth__1 +# 321| getAnOperand/getRightOperand: [IntegerLiteral] 0 # 321| getStmt: [AssignExpr] ... = ... # 321| getAnOperand/getLeftOperand: [LocalVariableAccess] __synth__2 # 321| getAnOperand/getRightOperand: [AddExpr] ... + ... @@ -205,35 +201,33 @@ calls/calls.rb: # 321| getReceiver: [LocalVariableAccess] __synth__0 # 321| getArgument: [LocalVariableAccess] __synth__1 # 321| getAnOperand/getArgument/getRightOperand: [IntegerLiteral] 1 +# 321| getStmt: [SetterMethodCall] call to []= +# 321| getReceiver: [LocalVariableAccess] __synth__0 +# 321| getArgument: [LocalVariableAccess] __synth__1 +# 321| getArgument: [LocalVariableAccess] __synth__2 # 321| getStmt: [LocalVariableAccess] __synth__2 # 322| [AssignMulExpr] ... *= ... # 322| getDesugared: [StmtSequence] ... # 322| getStmt: [AssignExpr] ... = ... +# 322| getAnOperand/getLeftOperand: [LocalVariableAccess] __synth__0 # 322| getAnOperand/getRightOperand: [MethodCall] call to bar # 322| getReceiver: [MethodCall] call to foo # 322| getReceiver: [SelfVariableAccess] self -# 322| getAnOperand/getLeftOperand: [LocalVariableAccess] __synth__0 -# 322| getStmt: [SetterMethodCall] call to []= -# 322| getReceiver: [LocalVariableAccess] __synth__0 -# 322| getArgument: [LocalVariableAccess] __synth__1 -# 322| getArgument: [LocalVariableAccess] __synth__2 -# 322| getArgument: [LocalVariableAccess] __synth__3 -# 322| getArgument: [LocalVariableAccess] __synth__4 # 322| getStmt: [AssignExpr] ... = ... -# 322| getAnOperand/getRightOperand: [IntegerLiteral] 0 # 322| getAnOperand/getLeftOperand: [LocalVariableAccess] __synth__1 +# 322| getAnOperand/getRightOperand: [IntegerLiteral] 0 # 322| getStmt: [AssignExpr] ... = ... +# 322| getAnOperand/getLeftOperand: [LocalVariableAccess] __synth__2 # 322| getAnOperand/getRightOperand: [MethodCall] call to baz # 322| getReceiver: [MethodCall] call to foo # 322| getReceiver: [SelfVariableAccess] self -# 322| getAnOperand/getLeftOperand: [LocalVariableAccess] __synth__2 # 322| getStmt: [AssignExpr] ... = ... +# 322| getAnOperand/getLeftOperand: [LocalVariableAccess] __synth__3 # 322| getAnOperand/getRightOperand: [AddExpr] ... + ... # 322| getAnOperand/getLeftOperand/getReceiver: [MethodCall] call to boo # 322| getReceiver: [MethodCall] call to foo # 322| getReceiver: [SelfVariableAccess] self # 322| getAnOperand/getArgument/getRightOperand: [IntegerLiteral] 1 -# 322| getAnOperand/getLeftOperand: [LocalVariableAccess] __synth__3 # 322| getStmt: [AssignExpr] ... = ... # 322| getAnOperand/getLeftOperand: [LocalVariableAccess] __synth__4 # 322| getAnOperand/getRightOperand: [MulExpr] ... * ... @@ -243,9 +237,30 @@ calls/calls.rb: # 322| getArgument: [LocalVariableAccess] __synth__2 # 322| getArgument: [LocalVariableAccess] __synth__3 # 322| getAnOperand/getArgument/getRightOperand: [IntegerLiteral] 2 +# 322| getStmt: [SetterMethodCall] call to []= +# 322| getReceiver: [LocalVariableAccess] __synth__0 +# 322| getArgument: [LocalVariableAccess] __synth__1 +# 322| getArgument: [LocalVariableAccess] __synth__2 +# 322| getArgument: [LocalVariableAccess] __synth__3 +# 322| getArgument: [LocalVariableAccess] __synth__4 # 322| getStmt: [LocalVariableAccess] __synth__4 # 342| [ForExpr] for ... in ... # 342| getDesugared: [MethodCall] call to each +# 342| getReceiver: [ArrayLiteral] [...] +# 342| getDesugared: [MethodCall] call to [] +# 342| getReceiver: [ConstantReadAccess] Array +# 342| getArgument: [ArrayLiteral] [...] +# 342| getDesugared: [MethodCall] call to [] +# 342| getReceiver: [ConstantReadAccess] Array +# 342| getArgument: [IntegerLiteral] 1 +# 342| getArgument: [IntegerLiteral] 2 +# 342| getArgument: [IntegerLiteral] 3 +# 342| getArgument: [ArrayLiteral] [...] +# 342| getDesugared: [MethodCall] call to [] +# 342| getReceiver: [ConstantReadAccess] Array +# 342| getArgument: [IntegerLiteral] 4 +# 342| getArgument: [IntegerLiteral] 5 +# 342| getArgument: [IntegerLiteral] 6 # 342| getBlock: [BraceBlock] { ... } # 342| getParameter: [SimpleParameter] __synth__0__1 # 342| getDefiningAccess: [LocalVariableAccess] __synth__0__1 @@ -276,41 +291,29 @@ calls/calls.rb: # 343| getArgument: [LocalVariableAccess] x # 343| getArgument: [LocalVariableAccess] y # 343| getArgument: [LocalVariableAccess] z -# 342| getReceiver: [ArrayLiteral] [...] -# 342| getDesugared: [MethodCall] call to [] -# 342| getReceiver: [ConstantReadAccess] Array -# 342| getArgument: [ArrayLiteral] [...] -# 342| getDesugared: [MethodCall] call to [] -# 342| getReceiver: [ConstantReadAccess] Array -# 342| getArgument: [IntegerLiteral] 1 -# 342| getArgument: [IntegerLiteral] 2 -# 342| getArgument: [IntegerLiteral] 3 -# 342| getArgument: [ArrayLiteral] [...] -# 342| getDesugared: [MethodCall] call to [] -# 342| getReceiver: [ConstantReadAccess] Array -# 342| getArgument: [IntegerLiteral] 4 -# 342| getArgument: [IntegerLiteral] 5 -# 342| getArgument: [IntegerLiteral] 6 # 364| [MethodCall] call to empty? # 364| getDesugared: [StmtSequence] ... # 364| getStmt: [AssignExpr] ... = ... +# 364| getAnOperand/getLeftOperand: [LocalVariableAccess] __synth__0__1 # 364| getAnOperand/getRightOperand: [MethodCall] call to list # 364| getReceiver: [SelfVariableAccess] self -# 364| getAnOperand/getLeftOperand: [LocalVariableAccess] __synth__0__1 # 364| getStmt: [IfExpr] if ... +# 364| getCondition: [MethodCall] call to == +# 364| getReceiver: [NilLiteral] nil +# 364| getArgument: [LocalVariableAccess] __synth__0__1 # 364| getBranch/getThen: [NilLiteral] nil # 364| getBranch/getElse: [MethodCall] call to empty? # 364| getReceiver: [LocalVariableAccess] __synth__0__1 -# 364| getCondition: [MethodCall] call to == -# 364| getArgument: [LocalVariableAccess] __synth__0__1 -# 364| getReceiver: [NilLiteral] nil # 366| [MethodCall] call to bar # 366| getDesugared: [StmtSequence] ... # 366| getStmt: [AssignExpr] ... = ... +# 366| getAnOperand/getLeftOperand: [LocalVariableAccess] __synth__0__1 # 366| getAnOperand/getRightOperand: [MethodCall] call to foo # 366| getReceiver: [SelfVariableAccess] self -# 366| getAnOperand/getLeftOperand: [LocalVariableAccess] __synth__0__1 # 366| getStmt: [IfExpr] if ... +# 366| getCondition: [MethodCall] call to == +# 366| getReceiver: [NilLiteral] nil +# 366| getArgument: [LocalVariableAccess] __synth__0__1 # 366| getBranch/getThen: [NilLiteral] nil # 366| getBranch/getElse: [MethodCall] call to bar # 366| getReceiver: [LocalVariableAccess] __synth__0__1 @@ -320,9 +323,6 @@ calls/calls.rb: # 366| getParameter: [SimpleParameter] x # 366| getDefiningAccess: [LocalVariableAccess] x # 366| getStmt: [LocalVariableAccess] x -# 366| getCondition: [MethodCall] call to == -# 366| getArgument: [LocalVariableAccess] __synth__0__1 -# 366| getReceiver: [NilLiteral] nil control/cases.rb: # 90| [ArrayLiteral] %w(...) # 90| getDesugared: [MethodCall] call to [] @@ -343,10 +343,10 @@ control/cases.rb: # 160| getValue: [MethodCall] call to expr # 160| getReceiver: [SelfVariableAccess] self # 160| getBranch: [InClause] in ... then ... -# 160| getBody: [BooleanLiteral] true # 160| getPattern: [ArrayPattern] [ ..., * ] # 160| getPrefixElement: [IntegerLiteral] 1 # 160| getPrefixElement: [IntegerLiteral] 2 +# 160| getBody: [BooleanLiteral] true # 160| getBranch/getElseBranch: [StmtSequence] else ... # 160| getStmt: [BooleanLiteral] false # 162| [MatchPattern] ... => ... @@ -354,7 +354,6 @@ control/cases.rb: # 162| getValue: [MethodCall] call to expr # 162| getReceiver: [SelfVariableAccess] self # 162| getBranch: [InClause] in ... then ... -# 162| getBody: [NilLiteral] nil # 162| getPattern: [HashPattern] { ..., ** } # 162| getKey: [SymbolLiteral] :x # 162| getComponent: [StringTextComponent] x @@ -362,6 +361,7 @@ control/cases.rb: # 162| getKey: [SymbolLiteral] :y # 162| getComponent: [StringTextComponent] y # 162| getValue: [IntegerLiteral] 1 +# 162| getBody: [NilLiteral] nil constants/constants.rb: # 20| [ArrayLiteral] [...] # 20| getDesugared: [MethodCall] call to [] @@ -595,12 +595,15 @@ literals/literals.rb: control/loops.rb: # 9| [ForExpr] for ... in ... # 9| getDesugared: [MethodCall] call to each +# 9| getReceiver: [RangeLiteral] _ .. _ +# 9| getBegin: [IntegerLiteral] 1 +# 9| getEnd: [IntegerLiteral] 10 # 9| getBlock: [BraceBlock] { ... } # 9| getParameter: [SimpleParameter] __synth__0__1 # 9| getDefiningAccess: [LocalVariableAccess] __synth__0__1 # 9| getStmt: [AssignExpr] ... = ... -# 9| getAnOperand/getRightOperand: [LocalVariableAccess] __synth__0__1 # 9| getAnOperand/getLeftOperand: [LocalVariableAccess] n +# 9| getAnOperand/getRightOperand: [LocalVariableAccess] __synth__0__1 # 10| getStmt: [AssignAddExpr] ... += ... # 10| getDesugared: [AssignExpr] ... = ... # 10| getAnOperand/getLeftOperand: [LocalVariableAccess] sum @@ -610,17 +613,17 @@ control/loops.rb: # 11| getStmt: [AssignExpr] ... = ... # 11| getAnOperand/getLeftOperand: [LocalVariableAccess] foo # 11| getAnOperand/getRightOperand: [LocalVariableAccess] n -# 9| getReceiver: [RangeLiteral] _ .. _ -# 9| getBegin: [IntegerLiteral] 1 -# 9| getEnd: [IntegerLiteral] 10 # 16| [ForExpr] for ... in ... # 16| getDesugared: [MethodCall] call to each +# 16| getReceiver: [RangeLiteral] _ .. _ +# 16| getBegin: [IntegerLiteral] 1 +# 16| getEnd: [IntegerLiteral] 10 # 16| getBlock: [BraceBlock] { ... } # 16| getParameter: [SimpleParameter] __synth__0__1 # 16| getDefiningAccess: [LocalVariableAccess] __synth__0__1 # 16| getStmt: [AssignExpr] ... = ... -# 16| getAnOperand/getRightOperand: [LocalVariableAccess] __synth__0__1 # 16| getAnOperand/getLeftOperand: [LocalVariableAccess] n +# 16| getAnOperand/getRightOperand: [LocalVariableAccess] __synth__0__1 # 17| getStmt: [AssignAddExpr] ... += ... # 17| getDesugared: [AssignExpr] ... = ... # 17| getAnOperand/getLeftOperand: [LocalVariableAccess] sum @@ -633,11 +636,19 @@ control/loops.rb: # 18| getAnOperand/getRightOperand: [SubExpr] ... - ... # 18| getAnOperand/getLeftOperand/getReceiver: [LocalVariableAccess] foo # 18| getAnOperand/getArgument/getRightOperand: [LocalVariableAccess] n -# 16| getReceiver: [RangeLiteral] _ .. _ -# 16| getBegin: [IntegerLiteral] 1 -# 16| getEnd: [IntegerLiteral] 10 # 22| [ForExpr] for ... in ... # 22| getDesugared: [MethodCall] call to each +# 22| getReceiver: [HashLiteral] {...} +# 22| getDesugared: [MethodCall] call to [] +# 22| getReceiver: [ConstantReadAccess] Hash +# 22| getArgument: [Pair] Pair +# 22| getKey: [SymbolLiteral] :foo +# 22| getComponent: [StringTextComponent] foo +# 22| getValue: [IntegerLiteral] 0 +# 22| getArgument: [Pair] Pair +# 22| getKey: [SymbolLiteral] :bar +# 22| getComponent: [StringTextComponent] bar +# 22| getValue: [IntegerLiteral] 1 # 22| getBlock: [BraceBlock] { ... } # 22| getParameter: [SimpleParameter] __synth__0__1 # 22| getDefiningAccess: [LocalVariableAccess] __synth__0__1 @@ -670,19 +681,19 @@ control/loops.rb: # 24| getAnOperand/getRightOperand: [MulExpr] ... * ... # 24| getAnOperand/getLeftOperand/getReceiver: [LocalVariableAccess] foo # 24| getAnOperand/getArgument/getRightOperand: [LocalVariableAccess] value -# 22| getReceiver: [HashLiteral] {...} -# 22| getDesugared: [MethodCall] call to [] -# 22| getReceiver: [ConstantReadAccess] Hash -# 22| getArgument: [Pair] Pair -# 22| getKey: [SymbolLiteral] :foo -# 22| getComponent: [StringTextComponent] foo -# 22| getValue: [IntegerLiteral] 0 -# 22| getArgument: [Pair] Pair -# 22| getKey: [SymbolLiteral] :bar -# 22| getComponent: [StringTextComponent] bar -# 22| getValue: [IntegerLiteral] 1 # 28| [ForExpr] for ... in ... # 28| getDesugared: [MethodCall] call to each +# 28| getReceiver: [HashLiteral] {...} +# 28| getDesugared: [MethodCall] call to [] +# 28| getReceiver: [ConstantReadAccess] Hash +# 28| getArgument: [Pair] Pair +# 28| getKey: [SymbolLiteral] :foo +# 28| getComponent: [StringTextComponent] foo +# 28| getValue: [IntegerLiteral] 0 +# 28| getArgument: [Pair] Pair +# 28| getKey: [SymbolLiteral] :bar +# 28| getComponent: [StringTextComponent] bar +# 28| getValue: [IntegerLiteral] 1 # 28| getBlock: [BraceBlock] { ... } # 28| getParameter: [SimpleParameter] __synth__0__1 # 28| getDefiningAccess: [LocalVariableAccess] __synth__0__1 @@ -716,17 +727,6 @@ control/loops.rb: # 30| getAnOperand/getLeftOperand/getReceiver: [LocalVariableAccess] foo # 30| getAnOperand/getArgument/getRightOperand: [LocalVariableAccess] value # 31| getStmt: [BreakStmt] break -# 28| getReceiver: [HashLiteral] {...} -# 28| getDesugared: [MethodCall] call to [] -# 28| getReceiver: [ConstantReadAccess] Hash -# 28| getArgument: [Pair] Pair -# 28| getKey: [SymbolLiteral] :foo -# 28| getComponent: [StringTextComponent] foo -# 28| getValue: [IntegerLiteral] 0 -# 28| getArgument: [Pair] Pair -# 28| getKey: [SymbolLiteral] :bar -# 28| getComponent: [StringTextComponent] bar -# 28| getValue: [IntegerLiteral] 1 # 36| [AssignAddExpr] ... += ... # 36| getDesugared: [AssignExpr] ... = ... # 36| getAnOperand/getLeftOperand: [LocalVariableAccess] x @@ -916,8 +916,8 @@ operations/operations.rb: # 101| [AssignLogicalOrExpr] ... ||= ... # 101| getDesugared: [StmtSequence] ... # 101| getStmt: [AssignExpr] ... = ... -# 101| getAnOperand/getRightOperand: [ConstantReadAccess] Foo # 101| getAnOperand/getLeftOperand: [LocalVariableAccess] __synth__0 +# 101| getAnOperand/getRightOperand: [ConstantReadAccess] Foo # 101| getStmt: [AssignExpr] ... = ... # 101| getAnOperand/getLeftOperand: [ConstantAssignment] MemberConstant # 101| getScopeExpr: [LocalVariableAccess] __synth__0 @@ -928,11 +928,11 @@ operations/operations.rb: # 102| [AssignLogicalOrExpr] ... ||= ... # 102| getDesugared: [StmtSequence] ... # 102| getStmt: [AssignExpr] ... = ... +# 102| getAnOperand/getLeftOperand: [LocalVariableAccess] __synth__0 # 102| getAnOperand/getRightOperand: [MethodCall] call to bar # 102| getReceiver: [MethodCall] call to foo # 102| getReceiver: [SelfVariableAccess] self # 102| getArgument: [IntegerLiteral] 1 -# 102| getAnOperand/getLeftOperand: [LocalVariableAccess] __synth__0 # 102| getStmt: [AssignExpr] ... = ... # 102| getAnOperand/getLeftOperand: [ConstantAssignment] OtherConstant # 102| getScopeExpr: [LocalVariableAccess] __synth__0 @@ -949,6 +949,18 @@ operations/operations.rb: # 104| [AssignExpr] ... = ... # 104| getDesugared: [StmtSequence] ... # 104| getStmt: [AssignExpr] ... = ... +# 104| getAnOperand/getLeftOperand: [LocalVariableAccess] __synth__2 +# 104| getAnOperand/getRightOperand: [LocalVariableAccess] foo +# 104| getStmt: [AssignExpr] ... = ... +# 104| getAnOperand/getLeftOperand: [LocalVariableAccess] __synth__3 +# 104| getAnOperand/getRightOperand: [SplatExpr] * ... +# 104| getAnOperand/getOperand/getReceiver: [ArrayLiteral] [...] +# 104| getDesugared: [MethodCall] call to [] +# 104| getReceiver: [ConstantReadAccess] Array +# 104| getArgument: [IntegerLiteral] 1 +# 104| getArgument: [IntegerLiteral] 2 +# 104| getArgument: [IntegerLiteral] 3 +# 104| getStmt: [AssignExpr] ... = ... # 104| getAnOperand/getLeftOperand: [ConstantAssignment] FOO # 104| getAnOperand/getRightOperand: [MethodCall] call to [] # 104| getReceiver: [LocalVariableAccess] __synth__3 @@ -959,23 +971,11 @@ operations/operations.rb: # 104| getReceiver: [LocalVariableAccess] __synth__3 # 104| getArgument: [IntegerLiteral] 1 # 104| getStmt: [AssignExpr] ... = ... -# 104| getAnOperand/getRightOperand: [LocalVariableAccess] foo -# 104| getAnOperand/getLeftOperand: [LocalVariableAccess] __synth__2 -# 104| getStmt: [AssignExpr] ... = ... # 104| getAnOperand/getLeftOperand: [ConstantAssignment] FOO # 104| getScopeExpr: [LocalVariableAccess] __synth__2 # 104| getAnOperand/getRightOperand: [MethodCall] call to [] # 104| getReceiver: [LocalVariableAccess] __synth__3 # 104| getArgument: [IntegerLiteral] 2 -# 104| getStmt: [AssignExpr] ... = ... -# 104| getAnOperand/getLeftOperand: [LocalVariableAccess] __synth__3 -# 104| getAnOperand/getRightOperand: [SplatExpr] * ... -# 104| getAnOperand/getOperand/getReceiver: [ArrayLiteral] [...] -# 104| getDesugared: [MethodCall] call to [] -# 104| getReceiver: [ConstantReadAccess] Array -# 104| getArgument: [IntegerLiteral] 1 -# 104| getArgument: [IntegerLiteral] 2 -# 104| getArgument: [IntegerLiteral] 3 params/params.rb: # 8| [HashLiteral] {...} # 8| getDesugared: [MethodCall] call to [] @@ -986,19 +986,6 @@ params/params.rb: erb/template.html.erb: # 27| [ForExpr] for ... in ... # 27| getDesugared: [MethodCall] call to each -# 27| getBlock: [BraceBlock] { ... } -# 27| getParameter: [SimpleParameter] __synth__0__1 -# 27| getDefiningAccess: [LocalVariableAccess] __synth__0__1 -# 27| getStmt: [AssignExpr] ... = ... -# 27| getAnOperand/getRightOperand: [LocalVariableAccess] __synth__0__1 -# 27| getAnOperand/getLeftOperand: [LocalVariableAccess] x -# 28| getStmt: [AssignAddExpr] ... += ... -# 28| getDesugared: [AssignExpr] ... = ... -# 28| getAnOperand/getLeftOperand: [LocalVariableAccess] xs -# 28| getAnOperand/getRightOperand: [AddExpr] ... + ... -# 28| getAnOperand/getLeftOperand/getReceiver: [LocalVariableAccess] xs -# 28| getAnOperand/getArgument/getRightOperand: [LocalVariableAccess] x -# 29| getStmt: [LocalVariableAccess] xs # 27| getReceiver: [ArrayLiteral] [...] # 27| getDesugared: [MethodCall] call to [] # 27| getReceiver: [ConstantReadAccess] Array @@ -1008,82 +995,95 @@ erb/template.html.erb: # 27| getComponent: [StringTextComponent] bar # 27| getArgument: [StringLiteral] "baz" # 27| getComponent: [StringTextComponent] baz +# 27| getBlock: [BraceBlock] { ... } +# 27| getParameter: [SimpleParameter] __synth__0__1 +# 27| getDefiningAccess: [LocalVariableAccess] __synth__0__1 +# 27| getStmt: [AssignExpr] ... = ... +# 27| getAnOperand/getLeftOperand: [LocalVariableAccess] x +# 27| getAnOperand/getRightOperand: [LocalVariableAccess] __synth__0__1 +# 28| getStmt: [AssignAddExpr] ... += ... +# 28| getDesugared: [AssignExpr] ... = ... +# 28| getAnOperand/getLeftOperand: [LocalVariableAccess] xs +# 28| getAnOperand/getRightOperand: [AddExpr] ... + ... +# 28| getAnOperand/getLeftOperand/getReceiver: [LocalVariableAccess] xs +# 28| getAnOperand/getArgument/getRightOperand: [LocalVariableAccess] x +# 29| getStmt: [LocalVariableAccess] xs gems/test.gemspec: # 2| [AssignExpr] ... = ... # 2| getDesugared: [StmtSequence] ... # 2| getStmt: [SetterMethodCall] call to name= # 2| getReceiver: [LocalVariableAccess] s # 2| getArgument: [AssignExpr] ... = ... +# 2| getAnOperand/getLeftOperand: [LocalVariableAccess] __synth__0 # 2| getAnOperand/getRightOperand: [StringLiteral] "test" # 2| getComponent: [StringTextComponent] test -# 2| getAnOperand/getLeftOperand: [LocalVariableAccess] __synth__0 # 2| getStmt: [LocalVariableAccess] __synth__0 # 3| [AssignExpr] ... = ... # 3| getDesugared: [StmtSequence] ... # 3| getStmt: [SetterMethodCall] call to version= # 3| getReceiver: [LocalVariableAccess] s # 3| getArgument: [AssignExpr] ... = ... +# 3| getAnOperand/getLeftOperand: [LocalVariableAccess] __synth__0 # 3| getAnOperand/getRightOperand: [StringLiteral] "0.0.0" # 3| getComponent: [StringTextComponent] 0.0.0 -# 3| getAnOperand/getLeftOperand: [LocalVariableAccess] __synth__0 # 3| getStmt: [LocalVariableAccess] __synth__0 # 4| [AssignExpr] ... = ... # 4| getDesugared: [StmtSequence] ... # 4| getStmt: [SetterMethodCall] call to summary= # 4| getReceiver: [LocalVariableAccess] s # 4| getArgument: [AssignExpr] ... = ... +# 4| getAnOperand/getLeftOperand: [LocalVariableAccess] __synth__0 # 4| getAnOperand/getRightOperand: [StringLiteral] "foo!" # 4| getComponent: [StringTextComponent] foo! -# 4| getAnOperand/getLeftOperand: [LocalVariableAccess] __synth__0 # 4| getStmt: [LocalVariableAccess] __synth__0 # 5| [AssignExpr] ... = ... # 5| getDesugared: [StmtSequence] ... # 5| getStmt: [SetterMethodCall] call to description= # 5| getReceiver: [LocalVariableAccess] s # 5| getArgument: [AssignExpr] ... = ... +# 5| getAnOperand/getLeftOperand: [LocalVariableAccess] __synth__0 # 5| getAnOperand/getRightOperand: [StringLiteral] "A test" # 5| getComponent: [StringTextComponent] A test -# 5| getAnOperand/getLeftOperand: [LocalVariableAccess] __synth__0 # 5| getStmt: [LocalVariableAccess] __synth__0 # 6| [AssignExpr] ... = ... # 6| getDesugared: [StmtSequence] ... # 6| getStmt: [SetterMethodCall] call to authors= # 6| getReceiver: [LocalVariableAccess] s # 6| getArgument: [AssignExpr] ... = ... +# 6| getAnOperand/getLeftOperand: [LocalVariableAccess] __synth__0 # 6| getAnOperand/getRightOperand: [ArrayLiteral] [...] # 6| getDesugared: [MethodCall] call to [] # 6| getReceiver: [ConstantReadAccess] Array # 6| getArgument: [StringLiteral] "Mona Lisa" # 6| getComponent: [StringTextComponent] Mona Lisa -# 6| getAnOperand/getLeftOperand: [LocalVariableAccess] __synth__0 # 6| getStmt: [LocalVariableAccess] __synth__0 # 7| [AssignExpr] ... = ... # 7| getDesugared: [StmtSequence] ... # 7| getStmt: [SetterMethodCall] call to email= # 7| getReceiver: [LocalVariableAccess] s # 7| getArgument: [AssignExpr] ... = ... +# 7| getAnOperand/getLeftOperand: [LocalVariableAccess] __synth__0 # 7| getAnOperand/getRightOperand: [StringLiteral] "mona@example.com" # 7| getComponent: [StringTextComponent] mona@example.com -# 7| getAnOperand/getLeftOperand: [LocalVariableAccess] __synth__0 # 7| getStmt: [LocalVariableAccess] __synth__0 # 8| [AssignExpr] ... = ... # 8| getDesugared: [StmtSequence] ... # 8| getStmt: [SetterMethodCall] call to files= # 8| getReceiver: [LocalVariableAccess] s # 8| getArgument: [AssignExpr] ... = ... +# 8| getAnOperand/getLeftOperand: [LocalVariableAccess] __synth__0 # 8| getAnOperand/getRightOperand: [ArrayLiteral] [...] # 8| getDesugared: [MethodCall] call to [] # 8| getReceiver: [ConstantReadAccess] Array # 8| getArgument: [StringLiteral] "lib/test.rb" # 8| getComponent: [StringTextComponent] lib/test.rb -# 8| getAnOperand/getLeftOperand: [LocalVariableAccess] __synth__0 # 8| getStmt: [LocalVariableAccess] __synth__0 # 9| [AssignExpr] ... = ... # 9| getDesugared: [StmtSequence] ... # 9| getStmt: [SetterMethodCall] call to homepage= # 9| getReceiver: [LocalVariableAccess] s # 9| getArgument: [AssignExpr] ... = ... +# 9| getAnOperand/getLeftOperand: [LocalVariableAccess] __synth__0 # 9| getAnOperand/getRightOperand: [StringLiteral] "https://github.com/github/cod..." # 9| getComponent: [StringTextComponent] https://github.com/github/codeql-ruby -# 9| getAnOperand/getLeftOperand: [LocalVariableAccess] __synth__0 # 9| getStmt: [LocalVariableAccess] __synth__0 diff --git a/ruby/ql/test/library-tests/ast/calls/calls.expected b/ruby/ql/test/library-tests/ast/calls/calls.expected index 956d3fa8a22..628b3578994 100644 --- a/ruby/ql/test/library-tests/ast/calls/calls.expected +++ b/ruby/ql/test/library-tests/ast/calls/calls.expected @@ -77,12 +77,12 @@ callsWithArguments | calls.rb:319:14:319:22 | call to [] | [] | 0 | calls.rb:319:15:319:15 | 1 | | calls.rb:319:14:319:22 | call to [] | [] | 1 | calls.rb:319:18:319:18 | 2 | | calls.rb:319:14:319:22 | call to [] | [] | 2 | calls.rb:319:21:319:21 | 3 | -| calls.rb:320:1:320:10 | call to count= | count= | 1 | calls.rb:320:12:320:13 | __synth__1 | +| calls.rb:320:1:320:10 | call to count= | count= | 0 | calls.rb:320:1:320:10 | __synth__1 | | calls.rb:320:12:320:13 | ... + ... | + | 0 | calls.rb:320:15:320:15 | 1 | | calls.rb:321:1:321:6 | ...[...] | [] | 0 | calls.rb:321:5:321:5 | 0 | | calls.rb:321:1:321:6 | call to [] | [] | 0 | calls.rb:321:5:321:5 | __synth__1 | | calls.rb:321:1:321:6 | call to []= | []= | 0 | calls.rb:321:5:321:5 | __synth__1 | -| calls.rb:321:1:321:6 | call to []= | []= | 2 | calls.rb:321:8:321:9 | __synth__2 | +| calls.rb:321:1:321:6 | call to []= | []= | 1 | calls.rb:321:1:321:6 | __synth__2 | | calls.rb:321:8:321:9 | ... + ... | + | 0 | calls.rb:321:11:321:11 | 1 | | calls.rb:322:1:322:32 | ...[...] | [] | 0 | calls.rb:322:9:322:9 | 0 | | calls.rb:322:1:322:32 | ...[...] | [] | 1 | calls.rb:322:12:322:18 | call to baz | @@ -93,7 +93,7 @@ callsWithArguments | calls.rb:322:1:322:32 | call to []= | []= | 0 | calls.rb:322:9:322:9 | __synth__1 | | calls.rb:322:1:322:32 | call to []= | []= | 1 | calls.rb:322:12:322:18 | __synth__2 | | calls.rb:322:1:322:32 | call to []= | []= | 2 | calls.rb:322:21:322:31 | __synth__3 | -| calls.rb:322:1:322:32 | call to []= | []= | 4 | calls.rb:322:34:322:35 | __synth__4 | +| calls.rb:322:1:322:32 | call to []= | []= | 3 | calls.rb:322:1:322:32 | __synth__4 | | calls.rb:322:21:322:31 | ... + ... | + | 0 | calls.rb:322:31:322:31 | 1 | | calls.rb:322:34:322:35 | ... * ... | * | 0 | calls.rb:322:37:322:37 | 2 | | calls.rb:330:25:330:37 | call to print | print | 0 | calls.rb:330:31:330:37 | "error" | diff --git a/ruby/ql/test/library-tests/controlflow/graph/Cfg.expected b/ruby/ql/test/library-tests/controlflow/graph/Cfg.expected index 8414c6df8c5..071f118db84 100644 --- a/ruby/ql/test/library-tests/controlflow/graph/Cfg.expected +++ b/ruby/ql/test/library-tests/controlflow/graph/Cfg.expected @@ -4004,6 +4004,9 @@ desugar.rb: # 14| call to foo #-----| -> ... = ... +# 14| __synth__1 +#-----| -> call to count= + # 14| call to count #-----| -> 1 @@ -4025,9 +4028,6 @@ desugar.rb: # 14| __synth__1 #-----| -> __synth__0 -# 14| __synth__1 -#-----| -> call to count= - # 14| 1 #-----| -> ... + ... @@ -4066,6 +4066,9 @@ desugar.rb: # 18| call to foo #-----| -> ... = ... +# 18| __synth__4 +#-----| -> call to []= + # 18| call to [] #-----| -> 1 @@ -4144,9 +4147,6 @@ desugar.rb: # 18| __synth__4 #-----| -> __synth__0 -# 18| __synth__4 -#-----| -> call to []= - # 18| 1 #-----| -> ... + ... diff --git a/ruby/ql/test/library-tests/controlflow/graph/Nodes.expected b/ruby/ql/test/library-tests/controlflow/graph/Nodes.expected index f41b6e34a4d..0e39e2924bd 100644 --- a/ruby/ql/test/library-tests/controlflow/graph/Nodes.expected +++ b/ruby/ql/test/library-tests/controlflow/graph/Nodes.expected @@ -219,15 +219,15 @@ positionalArguments | desugar.rb:6:3:6:13 | call to count= | desugar.rb:6:17:6:17 | ... = ... | | desugar.rb:10:3:10:10 | call to []= | desugar.rb:10:9:10:9 | 0 | | desugar.rb:10:3:10:10 | call to []= | desugar.rb:10:14:10:14 | ... = ... | -| desugar.rb:14:3:14:13 | call to count= | desugar.rb:14:15:14:16 | __synth__1 | +| desugar.rb:14:3:14:13 | call to count= | desugar.rb:14:3:14:13 | __synth__1 | | desugar.rb:14:15:14:16 | ... + ... | desugar.rb:14:18:14:18 | 1 | | desugar.rb:18:3:18:28 | call to [] | desugar.rb:18:9:18:9 | __synth__1 | | desugar.rb:18:3:18:28 | call to [] | desugar.rb:18:12:18:16 | __synth__2 | | desugar.rb:18:3:18:28 | call to [] | desugar.rb:18:19:18:27 | __synth__3 | +| desugar.rb:18:3:18:28 | call to []= | desugar.rb:18:3:18:28 | __synth__4 | | desugar.rb:18:3:18:28 | call to []= | desugar.rb:18:9:18:9 | __synth__1 | | desugar.rb:18:3:18:28 | call to []= | desugar.rb:18:12:18:16 | __synth__2 | | desugar.rb:18:3:18:28 | call to []= | desugar.rb:18:19:18:27 | __synth__3 | -| desugar.rb:18:3:18:28 | call to []= | desugar.rb:18:30:18:31 | __synth__4 | | desugar.rb:18:19:18:27 | ... + ... | desugar.rb:18:27:18:27 | 3 | | desugar.rb:18:30:18:31 | ... + ... | desugar.rb:18:33:18:33 | 1 | | desugar.rb:22:3:22:3 | call to [] | desugar.rb:22:3:22:3 | 0 | From 95cc99c625c84d95220fab642a74e7331833f3e8 Mon Sep 17 00:00:00 2001 From: Tony Torralba <atorralba@users.noreply.github.com> Date: Mon, 27 Mar 2023 11:50:27 +0200 Subject: [PATCH 499/631] Apply suggestions from code review --- java/ql/lib/ext/hudson.cli.model.yml | 1 + java/ql/lib/ext/hudson.model.yml | 8 +++++--- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/java/ql/lib/ext/hudson.cli.model.yml b/java/ql/lib/ext/hudson.cli.model.yml index 5ac446f2b7c..138899d4bd3 100644 --- a/java/ql/lib/ext/hudson.cli.model.yml +++ b/java/ql/lib/ext/hudson.cli.model.yml @@ -4,3 +4,4 @@ extensions: extensible: sinkModel data: - ["hudson.cli", "FullDuplexHttpStream", True, "FullDuplexHttpStream", "(URL,String,String)", "", "Argument[0]", "open-url", "ai-generated"] + - ["hudson.cli", "FullDuplexHttpStream", True, "FullDuplexHttpStream", "(URL,String,String)", "", "Argument[1]", "open-url", "manual"] diff --git a/java/ql/lib/ext/hudson.model.yml b/java/ql/lib/ext/hudson.model.yml index cb640c09361..04984703274 100644 --- a/java/ql/lib/ext/hudson.model.yml +++ b/java/ql/lib/ext/hudson.model.yml @@ -3,6 +3,8 @@ extensions: pack: codeql/java-all extensible: sinkModel data: + - ["hudson", "FilePath", False, "copyFrom", "(FilePath)", "", "Argument[0]", "read-file", "manual"] + - ["hudson", "FilePath", False, "copyFrom", "(URL)", "", "Argument[0]", "read-file", "manual"] - ["hudson", "FilePath", False, "copyFrom", "(FileItem)", "", "Argument[0]", "read-file", "ai-generated"] - ["hudson", "FilePath", False, "copyRecursiveTo", "(DirScanner,FilePath,String,TarCompression)", "", "Argument[1]", "create-file", "ai-generated"] - ["hudson", "FilePath", False, "copyRecursiveTo", "(DirScanner,FilePath,String)", "", "Argument[1]", "write-file", "ai-generated"] @@ -17,8 +19,8 @@ extensions: extensible: summaryModel data: - ["hudson", "FilePath", False, "child", "(String)", "", "Argument[0]", "ReturnValue", "taint", "ai-generated"] - - ["hudson", "FilePath", False, "list", "(String,String,boolean)", "", "Argument[0]", "ReturnValue", "taint", "ai-generated"] - - ["hudson", "FilePath", False, "list", "(String,String,boolean)", "", "Argument[1]", "ReturnValue", "taint", "ai-generated"] - - ["hudson", "FilePath", False, "list", "(String)", "", "Argument[0]", "ReturnValue", "taint", "ai-generated"] + - ["hudson", "FilePath", False, "list", "(String,String,boolean)", "", "Argument[this]", "ReturnValue", "taint", "ai-generated"] + - ["hudson", "FilePath", False, "list", "(String,String)", "", "Argument[this]", "ReturnValue", "taint", "ai-generated"] + - ["hudson", "FilePath", False, "list", "(String)", "", "Argument[this]", "ReturnValue", "taint", "ai-generated"] - ["hudson", "FilePath", False, "normalize", "(String)", "", "Argument[0]", "ReturnValue", "taint", "ai-generated"] - ["hudson", "FilePath", False, "sibling", "(String)", "", "Argument[0]", "ReturnValue", "taint", "ai-generated"] From 7a9f1a570555647f5ba874e6e303be5d966e2dc7 Mon Sep 17 00:00:00 2001 From: Tony Torralba <atorralba@users.noreply.github.com> Date: Mon, 27 Mar 2023 11:51:59 +0200 Subject: [PATCH 500/631] Add change note --- java/ql/lib/change-notes/2023-03-27-more-hudson-models.md | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 java/ql/lib/change-notes/2023-03-27-more-hudson-models.md diff --git a/java/ql/lib/change-notes/2023-03-27-more-hudson-models.md b/java/ql/lib/change-notes/2023-03-27-more-hudson-models.md new file mode 100644 index 00000000000..2ddaec593fb --- /dev/null +++ b/java/ql/lib/change-notes/2023-03-27-more-hudson-models.md @@ -0,0 +1,8 @@ +--- +category: minorAnalysis +--- +* Added more sink and summary dataflow models for the following packages: + * `hudson.cli` + * `hudson.lifecycle` + * `hudson` + * `hudson.util.io` From 0b4c85f8d22b2cbb8c674e9dcfa9790537bb47af Mon Sep 17 00:00:00 2001 From: Taus <tausbn@github.com> Date: Mon, 27 Mar 2023 12:16:44 +0000 Subject: [PATCH 501/631] Python: Autoformat and fix broken module reference --- .../semmle/python/security/TimingAttack.qll | 31 +++++++++---------- 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/python/ql/src/experimental/semmle/python/security/TimingAttack.qll b/python/ql/src/experimental/semmle/python/security/TimingAttack.qll index 01613de2ed9..4df7752e64d 100644 --- a/python/ql/src/experimental/semmle/python/security/TimingAttack.qll +++ b/python/ql/src/experimental/semmle/python/security/TimingAttack.qll @@ -218,7 +218,7 @@ private class FlaskClientSuppliedSecret extends ClientSuppliedSecret { private class DjangoClientSuppliedSecret extends ClientSuppliedSecret { DjangoClientSuppliedSecret() { this = - PrivateDjango::DjangoImpl::Http::Request::HttpRequest::classRef() + PrivateDjango::DjangoImpl::DjangoHttp::Request::HttpRequest::classRef() .getMember(["headers", "META"]) .getMember("get") .getACall() and @@ -316,36 +316,35 @@ class CompareSink extends DataFlow::Node { exists(Compare compare | ( compare.getOp(0) instanceof Eq or - compare.getOp(0) instanceof NotEq + compare.getOp(0) instanceof NotEq ) and ( compare.getLeft() = this.asExpr() and - not compare.getComparator(0).(StrConst).getText() = "bearer" + not compare.getComparator(0).(StrConst).getText() = "bearer" or compare.getComparator(0) = this.asExpr() and - not compare.getLeft().(StrConst).getText() = "bearer" + not compare.getLeft().(StrConst).getText() = "bearer" ) - ) or - exists(Compare compare | - ( - compare.getOp(0) instanceof IsNot - ) and + ) + or + exists(Compare compare | + compare.getOp(0) instanceof IsNot and ( compare.getLeft() = this.asExpr() and not compare.getComparator(0) instanceof None or compare.getComparator(0) = this.asExpr() and not compare.getLeft() instanceof None - ) - ) + ) + ) } - -/** - * Holds if there is a flow to len(). - */ + + /** + * Holds if there is a flow to len(). + */ predicate flowtolen() { exists(ExcludeLenFunc config, DataFlow2::PathNode source, DataFlow2::PathNode sink | - config.hasFlowPath(source, sink) + config.hasFlowPath(source, sink) ) } } From eaf293020536b0d71d661fcd6a9098f0d06ccdb4 Mon Sep 17 00:00:00 2001 From: Taus <tausbn@github.com> Date: Mon, 27 Mar 2023 12:17:13 +0000 Subject: [PATCH 502/631] Python: Accept test changes (These look like they were the result of changes elsewhere in the analysis.) --- .../PossibleTimingAttackAgainstSensitiveInfo.expected | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstSensitiveInfo/PossibleTimingAttackAgainstSensitiveInfo.expected b/python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstSensitiveInfo/PossibleTimingAttackAgainstSensitiveInfo.expected index 4bde57c0b96..ec99cbceec9 100644 --- a/python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstSensitiveInfo/PossibleTimingAttackAgainstSensitiveInfo.expected +++ b/python/ql/test/experimental/query-tests/Security/CWE-208/TimingAttackAgainstSensitiveInfo/PossibleTimingAttackAgainstSensitiveInfo.expected @@ -1,4 +1,10 @@ edges +| TimingAttackAgainstSensitiveInfo.py:0:0:0:0 | ModuleVariableNode for TimingAttackAgainstSensitiveInfo.request | TimingAttackAgainstSensitiveInfo.py:14:8:14:14 | ControlFlowNode for request | +| TimingAttackAgainstSensitiveInfo.py:0:0:0:0 | ModuleVariableNode for TimingAttackAgainstSensitiveInfo.request | TimingAttackAgainstSensitiveInfo.py:15:20:15:26 | ControlFlowNode for request | +| TimingAttackAgainstSensitiveInfo.py:0:0:0:0 | ModuleVariableNode for TimingAttackAgainstSensitiveInfo.request | TimingAttackAgainstSensitiveInfo.py:20:8:20:14 | ControlFlowNode for request | +| TimingAttackAgainstSensitiveInfo.py:0:0:0:0 | ModuleVariableNode for TimingAttackAgainstSensitiveInfo.request | TimingAttackAgainstSensitiveInfo.py:21:20:21:26 | ControlFlowNode for request | +| TimingAttackAgainstSensitiveInfo.py:7:19:7:25 | ControlFlowNode for ImportMember | TimingAttackAgainstSensitiveInfo.py:7:19:7:25 | GSSA Variable request | +| TimingAttackAgainstSensitiveInfo.py:7:19:7:25 | GSSA Variable request | TimingAttackAgainstSensitiveInfo.py:0:0:0:0 | ModuleVariableNode for TimingAttackAgainstSensitiveInfo.request | | TimingAttackAgainstSensitiveInfo.py:14:8:14:14 | ControlFlowNode for request | TimingAttackAgainstSensitiveInfo.py:15:20:15:31 | ControlFlowNode for Attribute | | TimingAttackAgainstSensitiveInfo.py:15:20:15:26 | ControlFlowNode for request | TimingAttackAgainstSensitiveInfo.py:15:20:15:31 | ControlFlowNode for Attribute | | TimingAttackAgainstSensitiveInfo.py:15:20:15:31 | ControlFlowNode for Attribute | TimingAttackAgainstSensitiveInfo.py:15:20:15:38 | ControlFlowNode for Subscript | @@ -8,6 +14,9 @@ edges | TimingAttackAgainstSensitiveInfo.py:21:20:21:31 | ControlFlowNode for Attribute | TimingAttackAgainstSensitiveInfo.py:21:20:21:38 | ControlFlowNode for Subscript | | TimingAttackAgainstSensitiveInfo.py:21:20:21:38 | ControlFlowNode for Subscript | TimingAttackAgainstSensitiveInfo.py:22:38:22:45 | ControlFlowNode for password | nodes +| TimingAttackAgainstSensitiveInfo.py:0:0:0:0 | ModuleVariableNode for TimingAttackAgainstSensitiveInfo.request | semmle.label | ModuleVariableNode for TimingAttackAgainstSensitiveInfo.request | +| TimingAttackAgainstSensitiveInfo.py:7:19:7:25 | ControlFlowNode for ImportMember | semmle.label | ControlFlowNode for ImportMember | +| TimingAttackAgainstSensitiveInfo.py:7:19:7:25 | GSSA Variable request | semmle.label | GSSA Variable request | | TimingAttackAgainstSensitiveInfo.py:14:8:14:14 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | | TimingAttackAgainstSensitiveInfo.py:15:20:15:26 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | | TimingAttackAgainstSensitiveInfo.py:15:20:15:31 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | From 87c144d33bfe597f696db3e596e1eb1382d29528 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen <mathiasvp@github.com> Date: Mon, 27 Mar 2023 13:19:47 +0100 Subject: [PATCH 503/631] C++: Throw away the sign analysis when analyzing add expressions: instead, we now recursively analyze both operands. --- .../semantic/analysis/RangeAnalysisStage.qll | 49 ++++++++++++------- 1 file changed, 31 insertions(+), 18 deletions(-) diff --git a/cpp/ql/lib/experimental/semmle/code/cpp/semantic/analysis/RangeAnalysisStage.qll b/cpp/ql/lib/experimental/semmle/code/cpp/semantic/analysis/RangeAnalysisStage.qll index cdf0943eb65..2fb13cc8414 100644 --- a/cpp/ql/lib/experimental/semmle/code/cpp/semantic/analysis/RangeAnalysisStage.qll +++ b/cpp/ql/lib/experimental/semmle/code/cpp/semantic/analysis/RangeAnalysisStage.qll @@ -591,24 +591,6 @@ module RangeStage<DeltaSig D, BoundSig<D> Bounds, LangSig<D> LangParam, UtilSig< delta = D::fromInt(0) and (upper = true or upper = false) or - exists(SemExpr x | e2.(SemAddExpr).hasOperands(e1, x) | - // `x instanceof ConstantIntegerExpr` is covered by valueFlowStep - not x instanceof SemConstantIntegerExpr and - not e1 instanceof SemConstantIntegerExpr and - if strictlyPositiveIntegralExpr(x) - then upper = false and delta = D::fromInt(1) - else - if semPositive(x) - then upper = false and delta = D::fromInt(0) - else - if strictlyNegativeIntegralExpr(x) - then upper = true and delta = D::fromInt(-1) - else - if semNegative(x) - then upper = true and delta = D::fromInt(0) - else none() - ) - or exists(SemExpr x, SemSubExpr sub | e2 = sub and sub.getLeftOperand() = e1 and @@ -1043,13 +1025,44 @@ module RangeStage<DeltaSig D, BoundSig<D> Bounds, LangSig<D> LangParam, UtilSig< delta = D::fromFloat(f) and if semPositive(e) then f >= 0 else any() ) + or + exists( + SemBound bLeft, SemBound bRight, D::Delta dLeft, D::Delta dRight, boolean fbeLeft, + boolean fbeRight, D::Delta odLeft, D::Delta odRight, SemReason rLeft, SemReason rRight + | + boundedAddOperand(e, upper, bLeft, false, dLeft, fbeLeft, odLeft, rLeft) and + boundedAddOperand(e, upper, bRight, true, dRight, fbeRight, odRight, rRight) and + delta = D::fromFloat(D::toFloat(dLeft) + D::toFloat(dRight)) and + fromBackEdge = fbeLeft.booleanOr(fbeRight) + | + b = bLeft and origdelta = odLeft and reason = rLeft and bRight instanceof SemZeroBound + or + b = bRight and origdelta = odRight and reason = rRight and bLeft instanceof SemZeroBound + ) ) } + pragma[nomagic] private predicate boundedConditionalExpr( SemConditionalExpr cond, SemBound b, boolean upper, boolean branch, D::Delta delta, boolean fromBackEdge, D::Delta origdelta, SemReason reason ) { bounded(cond.getBranchExpr(branch), b, delta, upper, fromBackEdge, origdelta, reason) } + + pragma[nomagic] + private predicate boundedAddOperand( + SemAddExpr add, boolean upper, SemBound b, boolean isLeft, D::Delta delta, boolean fromBackEdge, + D::Delta origdelta, SemReason reason + ) { + // `semValueFlowStep` already handles the case where one of the operands is a constant. + not semValueFlowStep(add, _, _) and + ( + isLeft = true and + bounded(add.getLeftOperand(), b, delta, upper, fromBackEdge, origdelta, reason) + or + isLeft = false and + bounded(add.getRightOperand(), b, delta, upper, fromBackEdge, origdelta, reason) + ) + } } From 1a6186496f82558b121e991c5ded1fdf10ce76f7 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen <mathiasvp@github.com> Date: Mon, 27 Mar 2023 13:20:17 +0100 Subject: [PATCH 504/631] C++: Accept test changes. --- .../SimpleRangeAnalysis_tests.cpp | 122 +++++++++--------- .../library-tests/ir/range-analysis/test.cpp | 2 +- 2 files changed, 62 insertions(+), 62 deletions(-) diff --git a/cpp/ql/test/library-tests/ir/range-analysis/SimpleRangeAnalysis_tests.cpp b/cpp/ql/test/library-tests/ir/range-analysis/SimpleRangeAnalysis_tests.cpp index 58ed4fdf396..89b81e2829b 100644 --- a/cpp/ql/test/library-tests/ir/range-analysis/SimpleRangeAnalysis_tests.cpp +++ b/cpp/ql/test/library-tests/ir/range-analysis/SimpleRangeAnalysis_tests.cpp @@ -40,13 +40,13 @@ int test4() { int total = 0; for (i = 0; i < 2; i = i+1) { range(i); // $ range=<=1 range=>=0 - range(total); + range(total); // $ range=>=0 total += i; - range(total); + range(total); // $ range=<=i+1 range=<=i+1 range=>=0 range=>=i+0 } - range(total); + range(total); // $ range=>=0 range(i); // $ range===2 - range(total + i); // $ range=>=i+1 + range(total + i); // $ range===i+2 range=>=2 range=>=i+0 return total + i; } @@ -55,13 +55,13 @@ int test5() { int total = 0; for (i = 0; i < 2; i++) { range(i); // $ range=<=1 range=>=0 - range(total); + range(total); // $ range=>=0 total += i; - range(total); + range(total); // $ range=<=i+1 range=>=0 range=>=i+0 } - range(total); + range(total); // $ range=>=0 range(i); // $ range===2 - range(total + i); // $ range=>=i+1 + range(total + i); // $ range===i+2 range=>=2 range=>=i+0 return total + i; } @@ -70,9 +70,9 @@ int test6() { int total = 0; for (i = 0; i+2 < 4; i = i+1) { range(i); // $ range=<=1 range=>=0 - range(total); + range(total); // $ range=>=0 total += i; - range(total); + range(total); // $ range=<=i+1 range=>=0 range=>=i+0 } return total + i; } @@ -175,12 +175,12 @@ int test12() { size_type Start = 0; while (Start <= test12_helper()-1) { - range(Start); // $ range=>=0 + range(Start); const size_type Length = test12_helper(); Start += Length + 1; - range(Start); // $ range=>=1 range=>=Start+1 range=">=call to test12_helper+1" + range(Start); } - range(Start); // $ range=>=0 + range(Start); return 1; } @@ -194,8 +194,8 @@ int test13(char c, int i) { range(y); // $ range===-1 int z = i+1; range(z); // $ range===i+1 - range(c + i + uc + x + y + z); // $ range=>=1 range=">=... - ...+0" - range((double)(c + i + uc + x + y + z)); // $ range=>=1 range=">=... - ...+0" + range(c + i + uc + x + y + z); + range((double)(c + i + uc + x + y + z)); return (double)(c + i + uc + x + y + z); } @@ -233,9 +233,9 @@ int test_unary(int a) { range(b); // $ range=<=11 range=>=3 int c = -a; range(c); // $ range=<=-3 range=>=-11 - range(b+c); // $ range=<=10 range="<=+ ...:a-1" range=">=- ...+1" range=>=-10 + range(b+c); // $ range=<=8 range=>=-8 total += b+c; - range(total); + range(total); // $ range=<=8 range=>=-8 } if (0 <= a && a <= 11) { range(a); // $ range=<=11 range=>=0 @@ -243,9 +243,9 @@ int test_unary(int a) { range(b); // $ range=<=11 range=>=0 int c = -a; range(c); // $ range=<=0 range=>=-11 - range(b+c); // $ range=<=11 range="<=+ ...:a+0" range=">=- ...+0" range=>=-11 + range(b+c); // $ range=<=11 range=>=-11 total += b+c; - range(total); + range(total); // $ range=<=0+11 range=<=19 range=>=0-11 range=>=-19 } if (-7 <= a && a <= 11) { range(a); // $ range=<=11 range=>=-7 @@ -253,9 +253,9 @@ int test_unary(int a) { range(b); // $ range=<=11 range=>=-7 int c = -a; range(c); // $ range=<=7 range=>=-11 - range(b+c); + range(b+c); // $ range=<=18 range=>=-18 total += b+c; - range(total); + range(total); // $ range="<=- ...+18" range=">=- ...-18" range=<=0+29 range=<=37 range=>=0-29 range=>=-37 } if (-7 <= a && a <= 1) { range(a); // $ range=<=1 range=>=-7 @@ -263,9 +263,9 @@ int test_unary(int a) { range(b); // $ range=<=1 range=>=-7 int c = -a; range(c); // $ range=<=7 range=>=-1 - range(b+c); + range(b+c); // $ range=<=8 range=>=-8 total += b+c; - range(total); + range(total); // $ range="<=- ...+8" range="<=- ...+26" range=">=- ...-8" range=">=- ...-26" range=<=0+37 range=<=45 range=>=0-37 range=>=-45 } if (-7 <= a && a <= 0) { range(a); // $ range=<=0 range=>=-7 @@ -273,9 +273,9 @@ int test_unary(int a) { range(b); // $ range=<=0 range=>=-7 int c = -a; range(c); // $ range=<=7 range=>=0 - range(b+c); // $ range="<=- ...+0" range=">=+ ...:a+0" range=>=-7 range=<=7 + range(b+c); // $ range=>=-7 range=<=7 total += b+c; - range(total); + range(total); // $ range="<=- ...+7" range="<=- ...+15" range="<=- ...+33" range=">=- ...-7" range=">=- ...-15" range=">=- ...-33" range=<=0+44 range=<=52 range=>=0-44 range=>=-52 } if (-7 <= a && a <= -2) { range(a); // $ range=<=-2 range=>=-7 @@ -283,11 +283,11 @@ int test_unary(int a) { range(b); // $ range=<=-2 range=>=-7 int c = -a; range(c); // $ range=<=7 range=>=2 - range(b+c); // $ range="<=- ...-1" range=">=+ ...:a+1" range=>=-6 range=<=6 + range(b+c); // $ range=<=5 range=>=-5 total += b+c; - range(total); + range(total); // $ range="<=- ...+5" range="<=- ...+12" range="<=- ...+20" range="<=- ...+38" range=">=- ...-5" range=">=- ...-12" range=">=- ...-20" range=">=- ...-38" range=<=0+49 range=<=57 range=>=0-49 range=>=-57 } - range(total); + range(total); // $ range="<=- ...+5" range="<=- ...+12" range="<=- ...+20" range="<=- ...+38" range=">=- ...-5" range=">=- ...-12" range=">=- ...-20" range=">=- ...-38" range=<=0+49 range=<=57 range=>=0-49 range=>=-57 return total; } @@ -302,7 +302,7 @@ int test_mult01(int a, int b) { int r = a*b; // 15 .. 253 range(r); total += r; - range(total); // $ range=>=1 + range(total); // $ MISSING: range=>=1 } if (3 <= a && a <= 11 && 0 <= b && b <= 23) { range(a); // $ range=<=11 range=>=3 @@ -310,7 +310,7 @@ int test_mult01(int a, int b) { int r = a*b; // 0 .. 253 range(r); total += r; - range(total); // $ range=>=0 range=>=3+0 + range(total); // $ MISSING: range=>=0 range=>=3+0 } if (3 <= a && a <= 11 && -13 <= b && b <= 23) { range(a); // $ range=<=11 range=>=3 @@ -326,7 +326,7 @@ int test_mult01(int a, int b) { int r = a*b; // -143 .. 0 range(r); total += r; - range(total); // $ range=<=3+0 + range(total); // $ MISSING: range=<=3+0 } if (3 <= a && a <= 11 && -13 <= b && b <= -7) { range(a); // $ range=<=11 range=>=3 @@ -334,9 +334,9 @@ int test_mult01(int a, int b) { int r = a*b; // -143 .. -21 range(r); total += r; - range(total); // $ range=<=3-1 + range(total); // $ MISSING: range=<=3-1 } - range(total); // $ range=<=3+0 + range(total); // $ MISSING: range=<=3+0 return total; } @@ -350,7 +350,7 @@ int test_mult02(int a, int b) { int r = a*b; // 0 .. 253 range(r); total += r; - range(total); // $ range=>=0 + range(total); // $ MISSING: range=>=0 } if (0 <= a && a <= 11 && 0 <= b && b <= 23) { range(a); // $ range=<=11 range=>=0 @@ -358,7 +358,7 @@ int test_mult02(int a, int b) { int r = a*b; // 0 .. 253 range(r); total += r; - range(total); // $ range=>=0 range=>=0+0 + range(total); // $ MISSING: range=>=0 range=>=0+0 } if (0 <= a && a <= 11 && -13 <= b && b <= 23) { range(a); // $ range=<=11 range=>=0 @@ -374,7 +374,7 @@ int test_mult02(int a, int b) { int r = a*b; // -143 .. 0 range(r); total += r; - range(total); // $ range=<=0+0 + range(total); // $ MISSING: range=<=0+0 } if (0 <= a && a <= 11 && -13 <= b && b <= -7) { range(a); // $ range=<=11 range=>=0 @@ -382,9 +382,9 @@ int test_mult02(int a, int b) { int r = a*b; // -143 .. 0 range(r); total += r; - range(total); // $ range=<=0+0 + range(total); // $ MISSING: range=<=0+0 } - range(total); // $ range=<=0+0 + range(total); // $ MISSING: range=<=0+0 return total; } @@ -445,7 +445,7 @@ int test_mult04(int a, int b) { range(b); // $ range=<=23 range=>=5 int r = a*b; // -391 .. 0 total += r; - range(total); // $ range=<=0 + range(total); // $ MISSING: range=<=0 } if (-17 <= a && a <= 0 && 0 <= b && b <= 23) { range(a); // $ range=<=0 range=>=-17 @@ -453,7 +453,7 @@ int test_mult04(int a, int b) { int r = a*b; // -391 .. 0 range(r); total += r; - range(total); // $ range="<=- ...+0" range=<=0 + range(total); // $ MISSING: range="<=- ...+0" range=<=0 } if (-17 <= a && a <= 0 && -13 <= b && b <= 23) { range(a); // $ range=<=0 range=>=-17 @@ -469,7 +469,7 @@ int test_mult04(int a, int b) { int r = a*b; // 0 .. 221 range(r); total += r; - range(total); // $ range=">=- ...+0" + range(total); // $ MISSING: range=">=- ...+0" } if (-17 <= a && a <= 0 && -13 <= b && b <= -7) { range(a); // $ range=<=0 range=>=-17 @@ -477,9 +477,9 @@ int test_mult04(int a, int b) { int r = a*b; // 0 .. 221 range(r); total += r; - range(total); // $ range=">=- ...+0" + range(total); // $ MISSING: range=">=- ...+0" } - range(total); // $ range=">=- ...+0" + range(total); // $ MISSING: range=">=- ...+0" return total; } @@ -493,7 +493,7 @@ int test_mult05(int a, int b) { int r = a*b; // -391 .. -10 range(r); total += r; - range(total); // $ range=<=-1 + range(total); // $ MISSING: range=<=-1 } if (-17 <= a && a <= -2 && 0 <= b && b <= 23) { range(a); // $ range=<=-2 range=>=-17 @@ -501,7 +501,7 @@ int test_mult05(int a, int b) { int r = a*b; // -391 .. 0 range(r); total += r; - range(total); // $ range="<=- ...+0" range=<=0 + range(total); // $ MISSING: range="<=- ...+0" range=<=0 } if (-17 <= a && a <= -2 && -13 <= b && b <= 23) { range(a); // $ range=<=-2 range=>=-17 @@ -517,7 +517,7 @@ int test_mult05(int a, int b) { int r = a*b; // 0 .. 221 range(r); total += r; - range(total); // $ range=">=- ...+0" + range(total); // $ MISSING: range=">=- ...+0" } if (-17 <= a && a <= -2 && -13 <= b && b <= -7) { range(a); // $ range=<=-2 range=>=-17 @@ -525,9 +525,9 @@ int test_mult05(int a, int b) { int r = a*b; // 14 .. 221 range(r); total += r; - range(total); // $ range=">=- ...+1" + range(total); // $ MISSING: range=">=- ...+1" } - range(total); // $ range=">=- ...+0" + range(total); // $ MISSING: range=">=- ...+0" return total; } @@ -598,7 +598,7 @@ unsigned int test_ternary01(unsigned int x) { (range(x), 500); // $ range=<=299 range(y8); // y8 <= 300 } - range(y1 + y2 + y3 + y4 + y5 + y6 + y7 + y8); // $ range=">=... = ...:... ? ... : ...+0" range=">=call to range+0" + range(y1 + y2 + y3 + y4 + y5 + y6 + y7 + y8); // $ MISSING: range=">=... = ...:... ? ... : ...+0" range=">=call to range+0" return y1 + y2 + y3 + y4 + y5 + y6 + y7 + y8; } @@ -628,7 +628,7 @@ unsigned int test_ternary02(unsigned int x) { (range(x), 5); // $ range=>=300 range(y5); // y6 >= 0 } - range(y1 + y2 + y3 + y4 + y5); // $ range=">=... = ...:... ? ... : ...+0" range=">=call to range+0" + range(y1 + y2 + y3 + y4 + y5); // $ MISSING: range=">=... = ...:... ? ... : ...+0" range=">=call to range+0" return y1 + y2 + y3 + y4 + y5; } @@ -647,7 +647,7 @@ unsigned int test_comma01(unsigned int x) { range(y), // $ range="==++ ...:... = ...+4" range="==... +++3" range="==... ? ... : ...+5" y); range(y2); // $ range="==++ ...:... = ...+4" range="==... +++3" range="==... ? ... : ...+5" - range(y1 + y2); // $ range=">=++ ...:... = ...+5" range=">=... +++4" range=">=... += ...:... = ...+1" range=">=... ? ... : ...+6" + range(y1 + y2); // $ MISSING: range=">=++ ...:... = ...+5" range=">=... +++4" range=">=... += ...:... = ...+1" range=">=... ? ... : ...+6" return y1 + y2; } @@ -685,7 +685,7 @@ int test_unsigned_mult01(unsigned int a, unsigned b) { int r = a*b; // 15 .. 253 range(r); total += r; - range(total); // $ range=>=1 + range(total); // $ MISSING: range=>=1 } if (3 <= a && a <= 11 && 0 <= b && b <= 23) { range(a); // $ range=<=11 range=>=3 @@ -693,7 +693,7 @@ int test_unsigned_mult01(unsigned int a, unsigned b) { int r = a*b; // 0 .. 253 range(r); total += r; - range(total); // $ range=">=(unsigned int)...+0" range=>=0 + range(total); // $ MISSING: range=">=(unsigned int)...+0" range=>=0 } if (3 <= a && a <= 11 && 13 <= b && b <= 23) { range(a); // $ range=<=11 range=>=3 @@ -701,9 +701,9 @@ int test_unsigned_mult01(unsigned int a, unsigned b) { int r = a*b; // 39 .. 253 range(r); total += r; - range(total); // $ range=">=(unsigned int)...+1" range=>=1 + range(total); // $ MISSING: range=">=(unsigned int)...+1" range=>=1 } - range(total); // $ range=">=(unsigned int)...+0" range=>=0 + range(total); // $ MISSING: range=">=(unsigned int)...+0" range=>=0 return total; } @@ -715,23 +715,23 @@ int test_unsigned_mult02(unsigned b) { int r = 11*b; // 55 .. 253 range(r); total += r; - range(total); // $ range=>=1 + range(total); // $ MISSING: range=>=1 } if (0 <= b && b <= 23) { range(b); // $ range=<=23 range=>=0 int r = 11*b; // 0 .. 253 range(r); total += r; - range(total); // $ range=">=(unsigned int)...+0" range=>=0 + range(total); // $ MISSING: range=">=(unsigned int)...+0" range=>=0 } if (13 <= b && b <= 23) { range(b); // $ range=<=23 range=>=13 int r = 11*b; // 143 .. 253 range(r); total += r; - range(total); // $ range=">=(unsigned int)...+1" range=>=1 + range(total); // $ MISSING: range=">=(unsigned int)...+1" range=>=1 } - range(total); // $ range=">=(unsigned int)...+0" range=>=0 + range(total); // $ MISSING: range=">=(unsigned int)...+0" range=>=0 return total; } @@ -790,7 +790,7 @@ unsigned long mul_assign(unsigned int ui) { range(ulconst); // $ range===10 ulconst *= 4; range(ulconst); // $ range===40 - range(uiconst + ulconst); // $ range=">=... *= ...+1" range=>=41 + range(uiconst + ulconst); // $ range===80 return uiconst + ulconst; // 40 .. 40 for both } @@ -942,7 +942,7 @@ void widen_recursive_expr() { for (s = 0; s < 10; s++) { range(s); // $ range=<=9 range=>=0 int result = s + s; - range(result); // 0 .. 18 + range(result); // $ range=<=18 range=<=s+9 range=>=0 range=>=s+0 } } diff --git a/cpp/ql/test/library-tests/ir/range-analysis/test.cpp b/cpp/ql/test/library-tests/ir/range-analysis/test.cpp index 5290fffc8fd..f8587c42d67 100644 --- a/cpp/ql/test/library-tests/ir/range-analysis/test.cpp +++ b/cpp/ql/test/library-tests/ir/range-analysis/test.cpp @@ -7,7 +7,7 @@ } if (y - 2 == x && y > 300) { - range(x + y); // $ range=>=300 range=>=x+1 range=>=y-1 + range(x + y); // $ range=<=802 range=>=600 return x + y; } From 700eb04487eadae690cff60418b9d059b4386e2f Mon Sep 17 00:00:00 2001 From: Taus <tausbn@github.com> Date: Mon, 27 Mar 2023 12:22:17 +0000 Subject: [PATCH 505/631] Python: Lower precision of non-header queries cf. https://github.com/github/securitylab/issues/691#issuecomment-1387391014 --- .../TimingAttackAgainstHash/PossibleTimingAttackAgainstHash.ql | 2 +- .../CWE-208/TimingAttackAgainstHash/TimingAttackAgainstHash.ql | 2 +- .../PossibleTimingAttackAgainstSensitiveInfo.ql | 2 +- .../TimingAttackAgainstSensitiveInfo.ql | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHash/PossibleTimingAttackAgainstHash.ql b/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHash/PossibleTimingAttackAgainstHash.ql index 0d5809694b3..7fd75ecc5d9 100644 --- a/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHash/PossibleTimingAttackAgainstHash.ql +++ b/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHash/PossibleTimingAttackAgainstHash.ql @@ -6,7 +6,7 @@ * A successful attack can result in authentication bypass. * @kind path-problem * @problem.severity error - * @precision medium + * @precision low * @id py/possible-timing-attack-against-hash * @tags security * external/cwe/cwe-208 diff --git a/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHash/TimingAttackAgainstHash.ql b/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHash/TimingAttackAgainstHash.ql index f60e712cb4f..392356b7c42 100644 --- a/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHash/TimingAttackAgainstHash.ql +++ b/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHash/TimingAttackAgainstHash.ql @@ -6,7 +6,7 @@ * A successful attack can result in authentication bypass. * @kind path-problem * @problem.severity error - * @precision high + * @precision low * @id py/timing-attack-against-hash * @tags security * external/cwe/cwe-208 diff --git a/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstSensitiveInfo/PossibleTimingAttackAgainstSensitiveInfo.ql b/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstSensitiveInfo/PossibleTimingAttackAgainstSensitiveInfo.ql index 47173999a91..b2f0a637b53 100644 --- a/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstSensitiveInfo/PossibleTimingAttackAgainstSensitiveInfo.ql +++ b/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstSensitiveInfo/PossibleTimingAttackAgainstSensitiveInfo.ql @@ -4,7 +4,7 @@ * possibly allowing a timing attack to retrieve sensitive information. * @kind path-problem * @problem.severity error - * @precision medium + * @precision low * @id py/possible-timing-attack-sensitive-info * @tags security * external/cwe/cwe-208 diff --git a/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstSensitiveInfo/TimingAttackAgainstSensitiveInfo.ql b/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstSensitiveInfo/TimingAttackAgainstSensitiveInfo.ql index 2f6165753fc..b6227f647b7 100644 --- a/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstSensitiveInfo/TimingAttackAgainstSensitiveInfo.ql +++ b/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstSensitiveInfo/TimingAttackAgainstSensitiveInfo.ql @@ -4,7 +4,7 @@ * possibly allowing a timing attack to retrieve sensitive information. * @kind path-problem * @problem.severity error - * @precision high + * @precision low * @id py/timing-attack-sensitive-info * @tags security * external/cwe/cwe-208 From 213c4b081892c42f9f3528f0ac635ab0b4bc8318 Mon Sep 17 00:00:00 2001 From: Jeroen Ketema <jketema@github.com> Date: Mon, 27 Mar 2023 14:28:22 +0200 Subject: [PATCH 506/631] C++: Fix join-order problem in cpp/overrun-write Before on Wireshark: ``` [2023-03-27 12:59:25] Evaluated non-recursive predicate OverrunWriteProductFlow#fb5ce006::isSinkPairImpl#5#fffff@2ba90584 in 99742ms (size: 52640). Evaluated relational algebra for predicate OverrunWriteProductFlow#fb5ce006::isSinkPairImpl#5#fffff@2ba90584 with tuple counts: 1047588019 ~1% {3} r1 = JOIN DataFlowUtil#47741e1f::InstructionNode#fff_20#join_rhs WITH OverrunWriteProductFlow#fb5ce006::bounded#3#fff_102#join_rhs ON FIRST 1 OUTPUT Rhs.1, Lhs.1, Rhs.2 67558965 ~0% {4} r2 = JOIN r1 WITH Instruction#577b6a83::CallInstruction::getArgument#fbf_201#join_rhs ON FIRST 1 OUTPUT Rhs.2, Lhs.1, Lhs.2, Rhs.1 613572640 ~0% {5} r3 = JOIN r2 WITH ArrayFunction#ca0b6b68::ArrayFunction::hasArrayWithVariableSize#2#dispred#fff_201#join_rhs ON FIRST 1 OUTPUT Lhs.3, Rhs.1, Lhs.1, Lhs.2, Rhs.2 52640 ~0% {4} r4 = JOIN r3 WITH Instruction#577b6a83::CallInstruction::getStaticCallTarget#0#dispred#ff ON FIRST 2 OUTPUT Lhs.0, Lhs.4, Lhs.2, Lhs.3 52640 ~0% {4} r5 = JOIN r4 WITH Instruction#577b6a83::CallInstruction::getArgument#fbf ON FIRST 2 OUTPUT Rhs.2, Lhs.2, Lhs.3, Lhs.0 52640 ~0% {5} r6 = JOIN r5 WITH DataFlowUtil#47741e1f::InstructionNode#fff_20#join_rhs ON FIRST 1 OUTPUT Lhs.0, Lhs.1, Lhs.2, Lhs.3, Rhs.1 52640 ~0% {5} r7 = JOIN r6 WITH Instruction#577b6a83::Instruction::getUnconvertedResultExpression#0#dispred#ff ON FIRST 1 OUTPUT Lhs.3, Lhs.4, Lhs.1, Lhs.2, Rhs.1 return r7 ``` After: ``` [2023-03-27 13:56:36] Evaluated non-recursive predicate OverrunWriteProductFlow#fb5ce006::isSinkPairImpl#5#fffff@f936aapd in 777ms (size: 52640). Evaluated relational algebra for predicate OverrunWriteProductFlow#fb5ce006::isSinkPairImpl#5#fffff@f936aapd with tuple counts: 565480 ~5% {2} r1 = SCAN Instruction#577b6a83::CallInstruction::getStaticCallTarget#0#dispred#ff OUTPUT In.1, In.0 4420 ~1% {3} r2 = JOIN r1 WITH ArrayFunction#ca0b6b68::ArrayFunction::hasArrayWithVariableSize#2#dispred#fff ON FIRST 1 OUTPUT Lhs.1, Rhs.1, Rhs.2 4420 ~0% {3} r3 = JOIN r2 WITH Instruction#577b6a83::CallInstruction::getArgument#fff ON FIRST 2 OUTPUT Rhs.2, Lhs.2, Lhs.0 4420 ~0% {4} r4 = JOIN r3 WITH DataFlowUtil#47741e1f::InstructionNode#fff_20#join_rhs ON FIRST 1 OUTPUT Lhs.0, Lhs.1, Lhs.2, Rhs.1 4420 ~0% {4} r5 = JOIN r4 WITH Instruction#577b6a83::Instruction::getUnconvertedResultExpression#0#dispred#ff ON FIRST 1 OUTPUT Lhs.2, Lhs.1, Lhs.3, Rhs.1 4420 ~3% {4} r6 = JOIN r5 WITH Instruction#577b6a83::CallInstruction::getArgument#fff ON FIRST 2 OUTPUT Rhs.2, Lhs.0, Lhs.2, Lhs.3 52825 ~0% {5} r7 = JOIN r6 WITH OverrunWriteProductFlow#fb5ce006::bounded#3#fff ON FIRST 1 OUTPUT Rhs.1, Lhs.1, Lhs.2, Lhs.3, Rhs.2 52640 ~0% {5} r8 = JOIN r7 WITH DataFlowUtil#47741e1f::InstructionNode#fff_20#join_rhs ON FIRST 1 OUTPUT Lhs.1, Lhs.2, Rhs.1, Lhs.4, Lhs.3 return r8 ``` --- .../experimental/Likely Bugs/OverrunWriteProductFlow.ql | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/cpp/ql/src/experimental/Likely Bugs/OverrunWriteProductFlow.ql b/cpp/ql/src/experimental/Likely Bugs/OverrunWriteProductFlow.ql index 5e0d1d7b5bb..d4a4cb033b5 100644 --- a/cpp/ql/src/experimental/Likely Bugs/OverrunWriteProductFlow.ql +++ b/cpp/ql/src/experimental/Likely Bugs/OverrunWriteProductFlow.ql @@ -62,11 +62,16 @@ predicate hasSize(AllocationExpr alloc, DataFlow::Node n, string state) { predicate isSinkPairImpl( CallInstruction c, DataFlow::Node bufSink, DataFlow::Node sizeSink, int delta, Expr eBuf ) { - exists(int bufIndex, int sizeIndex, Instruction sizeInstr, Instruction bufInstr | + exists( + int bufIndex, int sizeIndex, Instruction sizeInstr, Instruction bufInstr, ArrayFunction func + | bufInstr = bufSink.asInstruction() and c.getArgument(bufIndex) = bufInstr and sizeInstr = sizeSink.asInstruction() and - c.getStaticCallTarget().(ArrayFunction).hasArrayWithVariableSize(bufIndex, sizeIndex) and + c.getStaticCallTarget() = func and + pragma[only_bind_into](func) + .hasArrayWithVariableSize(pragma[only_bind_into](bufIndex), + pragma[only_bind_into](sizeIndex)) and bounded(c.getArgument(sizeIndex), sizeInstr, delta) and eBuf = bufInstr.getUnconvertedResultExpression() ) From 32d7a802215a6497a10b7729d3f7df1356f57680 Mon Sep 17 00:00:00 2001 From: Asger F <asgerf@github.com> Date: Mon, 27 Mar 2023 14:46:08 +0200 Subject: [PATCH 507/631] JS: Change note --- .../ql/src/change-notes/2023-03-27-jquery-callback-sinks.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 javascript/ql/src/change-notes/2023-03-27-jquery-callback-sinks.md diff --git a/javascript/ql/src/change-notes/2023-03-27-jquery-callback-sinks.md b/javascript/ql/src/change-notes/2023-03-27-jquery-callback-sinks.md new file mode 100644 index 00000000000..166a5c139dc --- /dev/null +++ b/javascript/ql/src/change-notes/2023-03-27-jquery-callback-sinks.md @@ -0,0 +1,5 @@ +--- +category: minorAnalysis +--- +* Improved the model of jQuery to account for XSS sinks where the HTML string + is provided via a callback. This may lead to more results for the `js/xss` query. From a3c40a3ae49b4feab2949cb1311011555769d8e9 Mon Sep 17 00:00:00 2001 From: Taus <tausbn@github.com> Date: Mon, 27 Mar 2023 14:23:36 +0000 Subject: [PATCH 508/631] Python: Add `experimental` tags --- .../TimingAttackAgainstHash/PossibleTimingAttackAgainstHash.ql | 1 + .../TimingAttackAgainstHeaderValue.ql | 1 + .../PossibleTimingAttackAgainstSensitiveInfo.ql | 1 + .../TimingAttackAgainstSensitiveInfo.ql | 1 + 4 files changed, 4 insertions(+) diff --git a/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHash/PossibleTimingAttackAgainstHash.ql b/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHash/PossibleTimingAttackAgainstHash.ql index 7fd75ecc5d9..f46b93fb266 100644 --- a/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHash/PossibleTimingAttackAgainstHash.ql +++ b/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHash/PossibleTimingAttackAgainstHash.ql @@ -10,6 +10,7 @@ * @id py/possible-timing-attack-against-hash * @tags security * external/cwe/cwe-208 + * experimental */ import python diff --git a/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHeaderValue/TimingAttackAgainstHeaderValue.ql b/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHeaderValue/TimingAttackAgainstHeaderValue.ql index e88dbdcba36..1f2ff8f50fb 100644 --- a/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHeaderValue/TimingAttackAgainstHeaderValue.ql +++ b/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstHeaderValue/TimingAttackAgainstHeaderValue.ql @@ -8,6 +8,7 @@ * @id py/timing-attack-against-header-value * @tags security * external/cwe/cwe-208 + * experimental */ import python diff --git a/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstSensitiveInfo/PossibleTimingAttackAgainstSensitiveInfo.ql b/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstSensitiveInfo/PossibleTimingAttackAgainstSensitiveInfo.ql index b2f0a637b53..d43c3aa8995 100644 --- a/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstSensitiveInfo/PossibleTimingAttackAgainstSensitiveInfo.ql +++ b/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstSensitiveInfo/PossibleTimingAttackAgainstSensitiveInfo.ql @@ -8,6 +8,7 @@ * @id py/possible-timing-attack-sensitive-info * @tags security * external/cwe/cwe-208 + * experimental */ import python diff --git a/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstSensitiveInfo/TimingAttackAgainstSensitiveInfo.ql b/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstSensitiveInfo/TimingAttackAgainstSensitiveInfo.ql index b6227f647b7..63587d4afcc 100644 --- a/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstSensitiveInfo/TimingAttackAgainstSensitiveInfo.ql +++ b/python/ql/src/experimental/Security/CWE-208/TimingAttackAgainstSensitiveInfo/TimingAttackAgainstSensitiveInfo.ql @@ -8,6 +8,7 @@ * @id py/timing-attack-sensitive-info * @tags security * external/cwe/cwe-208 + * experimental */ import python From 57886e1713a4711854bc1fba11ccd91768729654 Mon Sep 17 00:00:00 2001 From: Ed Minnix <egregius313@github.com> Date: Thu, 2 Mar 2023 13:19:37 -0500 Subject: [PATCH 509/631] Moved files from experimental to src/ --- .../Security/CWE/CWE-522/InsecureLdapAuth.java | 0 .../Security/CWE/CWE-522/InsecureLdapAuth.qhelp | 0 .../{experimental => }/Security/CWE/CWE-522/InsecureLdapAuth.ql | 0 .../query-tests/security/CWE-522/InsecureLdapAuth.qlref | 1 - .../query-tests/security/CWE-522/InsecureLdapAuth.expected | 0 .../query-tests/security/CWE-522/InsecureLdapAuth.java | 0 java/ql/test/query-tests/security/CWE-522/InsecureLdapAuth.qlref | 1 + 7 files changed, 1 insertion(+), 1 deletion(-) rename java/ql/src/{experimental => }/Security/CWE/CWE-522/InsecureLdapAuth.java (100%) rename java/ql/src/{experimental => }/Security/CWE/CWE-522/InsecureLdapAuth.qhelp (100%) rename java/ql/src/{experimental => }/Security/CWE/CWE-522/InsecureLdapAuth.ql (100%) delete mode 100644 java/ql/test/experimental/query-tests/security/CWE-522/InsecureLdapAuth.qlref rename java/ql/test/{experimental => }/query-tests/security/CWE-522/InsecureLdapAuth.expected (100%) rename java/ql/test/{experimental => }/query-tests/security/CWE-522/InsecureLdapAuth.java (100%) create mode 100644 java/ql/test/query-tests/security/CWE-522/InsecureLdapAuth.qlref diff --git a/java/ql/src/experimental/Security/CWE/CWE-522/InsecureLdapAuth.java b/java/ql/src/Security/CWE/CWE-522/InsecureLdapAuth.java similarity index 100% rename from java/ql/src/experimental/Security/CWE/CWE-522/InsecureLdapAuth.java rename to java/ql/src/Security/CWE/CWE-522/InsecureLdapAuth.java diff --git a/java/ql/src/experimental/Security/CWE/CWE-522/InsecureLdapAuth.qhelp b/java/ql/src/Security/CWE/CWE-522/InsecureLdapAuth.qhelp similarity index 100% rename from java/ql/src/experimental/Security/CWE/CWE-522/InsecureLdapAuth.qhelp rename to java/ql/src/Security/CWE/CWE-522/InsecureLdapAuth.qhelp diff --git a/java/ql/src/experimental/Security/CWE/CWE-522/InsecureLdapAuth.ql b/java/ql/src/Security/CWE/CWE-522/InsecureLdapAuth.ql similarity index 100% rename from java/ql/src/experimental/Security/CWE/CWE-522/InsecureLdapAuth.ql rename to java/ql/src/Security/CWE/CWE-522/InsecureLdapAuth.ql diff --git a/java/ql/test/experimental/query-tests/security/CWE-522/InsecureLdapAuth.qlref b/java/ql/test/experimental/query-tests/security/CWE-522/InsecureLdapAuth.qlref deleted file mode 100644 index c2baa984177..00000000000 --- a/java/ql/test/experimental/query-tests/security/CWE-522/InsecureLdapAuth.qlref +++ /dev/null @@ -1 +0,0 @@ -experimental/Security/CWE/CWE-522/InsecureLdapAuth.ql diff --git a/java/ql/test/experimental/query-tests/security/CWE-522/InsecureLdapAuth.expected b/java/ql/test/query-tests/security/CWE-522/InsecureLdapAuth.expected similarity index 100% rename from java/ql/test/experimental/query-tests/security/CWE-522/InsecureLdapAuth.expected rename to java/ql/test/query-tests/security/CWE-522/InsecureLdapAuth.expected diff --git a/java/ql/test/experimental/query-tests/security/CWE-522/InsecureLdapAuth.java b/java/ql/test/query-tests/security/CWE-522/InsecureLdapAuth.java similarity index 100% rename from java/ql/test/experimental/query-tests/security/CWE-522/InsecureLdapAuth.java rename to java/ql/test/query-tests/security/CWE-522/InsecureLdapAuth.java diff --git a/java/ql/test/query-tests/security/CWE-522/InsecureLdapAuth.qlref b/java/ql/test/query-tests/security/CWE-522/InsecureLdapAuth.qlref new file mode 100644 index 00000000000..952f1d5663c --- /dev/null +++ b/java/ql/test/query-tests/security/CWE-522/InsecureLdapAuth.qlref @@ -0,0 +1 @@ +Security/CWE/CWE-522/InsecureLdapAuth.ql From 5ff4fcbc76caf25bb66275354408266661636a8e Mon Sep 17 00:00:00 2001 From: Ed Minnix <egregius313@github.com> Date: Thu, 2 Mar 2023 13:20:36 -0500 Subject: [PATCH 510/631] Replace `exists` with `any` --- java/ql/src/Security/CWE/CWE-522/InsecureLdapAuth.ql | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/java/ql/src/Security/CWE/CWE-522/InsecureLdapAuth.ql b/java/ql/src/Security/CWE/CWE-522/InsecureLdapAuth.ql index 5f2bda49f7c..d0da8198420 100644 --- a/java/ql/src/Security/CWE/CWE-522/InsecureLdapAuth.ql +++ b/java/ql/src/Security/CWE/CWE-522/InsecureLdapAuth.ql @@ -205,7 +205,7 @@ class SslFlowConfig extends DataFlow::Configuration { from DataFlow::PathNode source, DataFlow::PathNode sink, InsecureUrlFlowConfig config where config.hasFlowPath(source, sink) and - exists(BasicAuthFlowConfig bc | bc.hasFlowTo(sink.getNode())) and - not exists(SslFlowConfig sc | sc.hasFlowTo(sink.getNode())) + any(BasicAuthFlowConfig bc).hasFlowTo(sink.getNode()) and + not any(SslFlowConfig sc).hasFlowTo(sink.getNode()) select sink.getNode(), source, sink, "Insecure LDAP authentication from $@.", source.getNode(), "LDAP connection string" From 938d953789f99d8546781404dc7d2dd9296ce3e4 Mon Sep 17 00:00:00 2001 From: Ed Minnix <egregius313@github.com> Date: Fri, 3 Mar 2023 15:01:13 -0500 Subject: [PATCH 511/631] Refactor getLeftmostOperand method --- java/ql/src/Security/CWE/CWE-522/InsecureLdapAuth.ql | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/java/ql/src/Security/CWE/CWE-522/InsecureLdapAuth.ql b/java/ql/src/Security/CWE/CWE-522/InsecureLdapAuth.ql index d0da8198420..3f2ee65b0fa 100644 --- a/java/ql/src/Security/CWE/CWE-522/InsecureLdapAuth.ql +++ b/java/ql/src/Security/CWE/CWE-522/InsecureLdapAuth.ql @@ -53,8 +53,13 @@ predicate concatInsecureLdapString(Expr protocol, Expr host) { /** Gets the leftmost operand in a concatenated string */ Expr getLeftmostConcatOperand(Expr expr) { + // if expr instanceof AddExpr + // then result = getLeftmostConcatOperand(expr.(AddExpr).getLeftOperand()) + // else result = expr if expr instanceof AddExpr - then result = getLeftmostConcatOperand(expr.(AddExpr).getLeftOperand()) + then + result = expr.(AddExpr).getLeftOperand*() and + not result instanceof AddExpr else result = expr } From 9275b54e975a5aede33c00548c5717f200d13efe Mon Sep 17 00:00:00 2001 From: Ed Minnix <egregius313@github.com> Date: Tue, 7 Mar 2023 17:42:14 -0500 Subject: [PATCH 512/631] Refactoring the InsecureLdapUrl constructor --- .../Security/CWE/CWE-522/InsecureLdapAuth.ql | 47 ++++++++++--------- 1 file changed, 26 insertions(+), 21 deletions(-) diff --git a/java/ql/src/Security/CWE/CWE-522/InsecureLdapAuth.ql b/java/ql/src/Security/CWE/CWE-522/InsecureLdapAuth.ql index 3f2ee65b0fa..c235511fd44 100644 --- a/java/ql/src/Security/CWE/CWE-522/InsecureLdapAuth.ql +++ b/java/ql/src/Security/CWE/CWE-522/InsecureLdapAuth.ql @@ -36,33 +36,30 @@ class TypeHashtable extends Class { TypeHashtable() { this.getSourceDeclaration().hasQualifiedName("java.util", "Hashtable") } } +string getHostname(Expr expr) { + result = expr.(CompileTimeConstantExpr).getStringValue() or + result = + expr.(VarAccess).getVariable().getAnAssignedValue().(CompileTimeConstantExpr).getStringValue() +} + /** * Holds if a non-private LDAP string is concatenated from both protocol and host. */ -predicate concatInsecureLdapString(Expr protocol, Expr host) { - protocol.(CompileTimeConstantExpr).getStringValue() = "ldap://" and - not exists(string hostString | - hostString = host.(CompileTimeConstantExpr).getStringValue() or - hostString = - host.(VarAccess).getVariable().getAnAssignedValue().(CompileTimeConstantExpr).getStringValue() - | +predicate concatInsecureLdapString(CompileTimeConstantExpr protocol, Expr host) { + protocol.getStringValue() = "ldap://" and + not exists(string hostString | hostString = getHostname(host) | hostString.length() = 0 or // Empty host is loopback address hostString instanceof PrivateHostName ) } -/** Gets the leftmost operand in a concatenated string */ -Expr getLeftmostConcatOperand(Expr expr) { - // if expr instanceof AddExpr - // then result = getLeftmostConcatOperand(expr.(AddExpr).getLeftOperand()) - // else result = expr - if expr instanceof AddExpr - then - result = expr.(AddExpr).getLeftOperand*() and - not result instanceof AddExpr - else result = expr -} - +// Expr getLeftmostConcatOperand(Expr expr) { +// if expr instanceof AddExpr +// then +// result = expr.(AddExpr).getLeftOperand() and +// not result instanceof AddExpr +// else result = expr +// } /** * String concatenated with `InsecureLdapUrlLiteral`. */ @@ -70,8 +67,16 @@ class InsecureLdapUrl extends Expr { InsecureLdapUrl() { this instanceof InsecureLdapUrlLiteral or - concatInsecureLdapString(this.(AddExpr).getLeftOperand(), - getLeftmostConcatOperand(this.(AddExpr).getRightOperand())) + // protocol + host + ... + exists(AddExpr e, CompileTimeConstantExpr protocol, Expr rest, Expr host | + e = this and + protocol = e.getLeftOperand() and + rest = e.getRightOperand() and + if rest instanceof AddExpr then host = rest.(AddExpr).getLeftOperand() else host = rest + | + protocol.getStringValue() = "ldap://" and + concatInsecureLdapString(protocol, host) + ) } } From 3936aea69062beb53afc4a74d77d6b515ef4ad63 Mon Sep 17 00:00:00 2001 From: Ed Minnix <egregius313@github.com> Date: Wed, 8 Mar 2023 20:52:08 -0500 Subject: [PATCH 513/631] Split Ldap query file into libraries --- .../code/java/security/InsecureLdapAuth.qll | 128 +++++++++++ .../java/security/InsecureLdapAuthQuery.qll | 78 +++++++ .../Security/CWE/CWE-522/InsecureLdapAuth.ql | 199 +----------------- 3 files changed, 207 insertions(+), 198 deletions(-) create mode 100644 java/ql/lib/semmle/code/java/security/InsecureLdapAuth.qll create mode 100644 java/ql/lib/semmle/code/java/security/InsecureLdapAuthQuery.qll diff --git a/java/ql/lib/semmle/code/java/security/InsecureLdapAuth.qll b/java/ql/lib/semmle/code/java/security/InsecureLdapAuth.qll new file mode 100644 index 00000000000..d5948f2ff04 --- /dev/null +++ b/java/ql/lib/semmle/code/java/security/InsecureLdapAuth.qll @@ -0,0 +1,128 @@ +/** Provides classes to reason about insecure LDAP authentication. */ + +import java +import semmle.code.java.frameworks.Networking +import semmle.code.java.frameworks.Jndi + +/** + * Insecure (non-SSL, non-private) LDAP URL string literal. + */ +class InsecureLdapUrlLiteral extends StringLiteral { + InsecureLdapUrlLiteral() { + // Match connection strings with the LDAP protocol and without private IP addresses to reduce false positives. + exists(string s | this.getValue() = s | + s.regexpMatch("(?i)ldap://[\\[a-zA-Z0-9].*") and + not s.substring(7, s.length()) instanceof PrivateHostName + ) + } +} + +/** The class `java.util.Hashtable`. */ +class TypeHashtable extends Class { + TypeHashtable() { this.getSourceDeclaration().hasQualifiedName("java.util", "Hashtable") } +} + +string getHostname(Expr expr) { + result = expr.(CompileTimeConstantExpr).getStringValue() or + result = + expr.(VarAccess).getVariable().getAnAssignedValue().(CompileTimeConstantExpr).getStringValue() +} + +/** + * Holds if a non-private LDAP string is concatenated from both protocol and host. + */ +predicate concatInsecureLdapString(CompileTimeConstantExpr protocol, Expr host) { + protocol.getStringValue() = "ldap://" and + not exists(string hostString | hostString = getHostname(host) | + hostString.length() = 0 or // Empty host is loopback address + hostString instanceof PrivateHostName + ) +} + +// Expr getLeftmostConcatOperand(Expr expr) { +// if expr instanceof AddExpr +// then +// result = expr.(AddExpr).getLeftOperand() and +// not result instanceof AddExpr +// else result = expr +// } +/** + * String concatenated with `InsecureLdapUrlLiteral`. + */ +class InsecureLdapUrl extends Expr { + InsecureLdapUrl() { + this instanceof InsecureLdapUrlLiteral + or + // protocol + host + ... + exists(AddExpr e, CompileTimeConstantExpr protocol, Expr rest, Expr host | + e = this and + protocol = e.getLeftOperand() and + rest = e.getRightOperand() and + if rest instanceof AddExpr then host = rest.(AddExpr).getLeftOperand() else host = rest + | + protocol.getStringValue() = "ldap://" and + concatInsecureLdapString(protocol, host) + ) + } +} + +/** + * Holds if `ma` writes the `java.naming.provider.url` (also known as `Context.PROVIDER_URL`) key of a `Hashtable`. + */ +predicate isProviderUrlSetter(MethodAccess ma) { + ma.getMethod().getDeclaringType().getAnAncestor() instanceof TypeHashtable and + ma.getMethod().hasName(["put", "setProperty"]) and + ( + ma.getArgument(0).(CompileTimeConstantExpr).getStringValue() = "java.naming.provider.url" + or + exists(Field f | + ma.getArgument(0) = f.getAnAccess() and + f.hasName("PROVIDER_URL") and + f.getDeclaringType() instanceof TypeNamingContext + ) + ) +} + +/** + * Holds if `ma` sets `fieldValue` to `envValue` in some `Hashtable`. + */ +bindingset[fieldValue, envValue] +predicate hasFieldValueEnv(MethodAccess ma, string fieldValue, string envValue) { + // environment.put("java.naming.security.authentication", "simple") + ma.getMethod().getDeclaringType().getAnAncestor() instanceof TypeHashtable and + ma.getMethod().hasName(["put", "setProperty"]) and + ma.getArgument(0).(CompileTimeConstantExpr).getStringValue() = fieldValue and + ma.getArgument(1).(CompileTimeConstantExpr).getStringValue() = envValue +} + +/** + * Holds if `ma` sets attribute name `fieldName` to `envValue` in some `Hashtable`. + */ +bindingset[fieldName, envValue] +predicate hasFieldNameEnv(MethodAccess ma, string fieldName, string envValue) { + // environment.put(Context.SECURITY_AUTHENTICATION, "simple") + ma.getMethod().getDeclaringType().getAnAncestor() instanceof TypeHashtable and + ma.getMethod().hasName(["put", "setProperty"]) and + exists(Field f | + ma.getArgument(0) = f.getAnAccess() and + f.hasName(fieldName) and + f.getDeclaringType() instanceof TypeNamingContext + ) and + ma.getArgument(1).(CompileTimeConstantExpr).getStringValue() = envValue +} + +/** + * Holds if `ma` sets `java.naming.security.authentication` (also known as `Context.SECURITY_AUTHENTICATION`) to `simple` in some `Hashtable`. + */ +predicate isBasicAuthEnv(MethodAccess ma) { + hasFieldValueEnv(ma, "java.naming.security.authentication", "simple") or + hasFieldNameEnv(ma, "SECURITY_AUTHENTICATION", "simple") +} + +/** + * Holds if `ma` sets `java.naming.security.protocol` (also known as `Context.SECURITY_PROTOCOL`) to `ssl` in some `Hashtable`. + */ +predicate isSslEnv(MethodAccess ma) { + hasFieldValueEnv(ma, "java.naming.security.protocol", "ssl") or + hasFieldNameEnv(ma, "SECURITY_PROTOCOL", "ssl") +} diff --git a/java/ql/lib/semmle/code/java/security/InsecureLdapAuthQuery.qll b/java/ql/lib/semmle/code/java/security/InsecureLdapAuthQuery.qll new file mode 100644 index 00000000000..7d9b81dc3d3 --- /dev/null +++ b/java/ql/lib/semmle/code/java/security/InsecureLdapAuthQuery.qll @@ -0,0 +1,78 @@ +/** Provides dataflow configurations to reason about insecure LDAP authentication. */ + +import java +import DataFlow +import semmle.code.java.dataflow.DataFlow +import semmle.code.java.dataflow.TaintTracking +import semmle.code.java.security.InsecureLdapAuth + +/** + * A taint-tracking configuration for `ldap://` URL in LDAP authentication. + */ +class InsecureUrlFlowConfig extends TaintTracking::Configuration { + InsecureUrlFlowConfig() { this = "InsecureLdapAuth:InsecureUrlFlowConfig" } + + /** Source of `ldap://` connection string. */ + override predicate isSource(DataFlow::Node src) { src.asExpr() instanceof InsecureLdapUrl } + + /** Sink of directory context creation. */ + override predicate isSink(DataFlow::Node sink) { + exists(ConstructorCall cc | + cc.getConstructedType().getAnAncestor() instanceof TypeDirContext and + sink.asExpr() = cc.getArgument(0) + ) + } + + /** Method call of `env.put()`. */ + override predicate isAdditionalTaintStep(DataFlow::Node pred, DataFlow::Node succ) { + exists(MethodAccess ma | + pred.asExpr() = ma.getArgument(1) and + isProviderUrlSetter(ma) and + succ.asExpr() = ma.getQualifier() + ) + } +} + +/** + * A taint-tracking configuration for `simple` basic-authentication in LDAP configuration. + */ +class BasicAuthFlowConfig extends DataFlow::Configuration { + BasicAuthFlowConfig() { this = "InsecureLdapAuth:BasicAuthFlowConfig" } + + /** Source of `simple` configuration. */ + override predicate isSource(DataFlow::Node src) { + exists(MethodAccess ma | + isBasicAuthEnv(ma) and ma.getQualifier() = src.(PostUpdateNode).getPreUpdateNode().asExpr() + ) + } + + /** Sink of directory context creation. */ + override predicate isSink(DataFlow::Node sink) { + exists(ConstructorCall cc | + cc.getConstructedType().getAnAncestor() instanceof TypeDirContext and + sink.asExpr() = cc.getArgument(0) + ) + } +} + +/** + * A taint-tracking configuration for `ssl` configuration in LDAP authentication. + */ +class SslFlowConfig extends DataFlow::Configuration { + SslFlowConfig() { this = "InsecureLdapAuth:SSLFlowConfig" } + + /** Source of `ssl` configuration. */ + override predicate isSource(DataFlow::Node src) { + exists(MethodAccess ma | + isSslEnv(ma) and ma.getQualifier() = src.(PostUpdateNode).getPreUpdateNode().asExpr() + ) + } + + /** Sink of directory context creation. */ + override predicate isSink(DataFlow::Node sink) { + exists(ConstructorCall cc | + cc.getConstructedType().getAnAncestor() instanceof TypeDirContext and + sink.asExpr() = cc.getArgument(0) + ) + } +} diff --git a/java/ql/src/Security/CWE/CWE-522/InsecureLdapAuth.ql b/java/ql/src/Security/CWE/CWE-522/InsecureLdapAuth.ql index c235511fd44..be129f9521c 100644 --- a/java/ql/src/Security/CWE/CWE-522/InsecureLdapAuth.ql +++ b/java/ql/src/Security/CWE/CWE-522/InsecureLdapAuth.ql @@ -12,206 +12,9 @@ */ import java -import DataFlow -import semmle.code.java.frameworks.Jndi -import semmle.code.java.frameworks.Networking -import semmle.code.java.dataflow.TaintTracking +import semmle.code.java.security.InsecureLdapAuthQuery import DataFlow::PathGraph -/** - * Insecure (non-SSL, non-private) LDAP URL string literal. - */ -class InsecureLdapUrlLiteral extends StringLiteral { - InsecureLdapUrlLiteral() { - // Match connection strings with the LDAP protocol and without private IP addresses to reduce false positives. - exists(string s | this.getValue() = s | - s.regexpMatch("(?i)ldap://[\\[a-zA-Z0-9].*") and - not s.substring(7, s.length()) instanceof PrivateHostName - ) - } -} - -/** The class `java.util.Hashtable`. */ -class TypeHashtable extends Class { - TypeHashtable() { this.getSourceDeclaration().hasQualifiedName("java.util", "Hashtable") } -} - -string getHostname(Expr expr) { - result = expr.(CompileTimeConstantExpr).getStringValue() or - result = - expr.(VarAccess).getVariable().getAnAssignedValue().(CompileTimeConstantExpr).getStringValue() -} - -/** - * Holds if a non-private LDAP string is concatenated from both protocol and host. - */ -predicate concatInsecureLdapString(CompileTimeConstantExpr protocol, Expr host) { - protocol.getStringValue() = "ldap://" and - not exists(string hostString | hostString = getHostname(host) | - hostString.length() = 0 or // Empty host is loopback address - hostString instanceof PrivateHostName - ) -} - -// Expr getLeftmostConcatOperand(Expr expr) { -// if expr instanceof AddExpr -// then -// result = expr.(AddExpr).getLeftOperand() and -// not result instanceof AddExpr -// else result = expr -// } -/** - * String concatenated with `InsecureLdapUrlLiteral`. - */ -class InsecureLdapUrl extends Expr { - InsecureLdapUrl() { - this instanceof InsecureLdapUrlLiteral - or - // protocol + host + ... - exists(AddExpr e, CompileTimeConstantExpr protocol, Expr rest, Expr host | - e = this and - protocol = e.getLeftOperand() and - rest = e.getRightOperand() and - if rest instanceof AddExpr then host = rest.(AddExpr).getLeftOperand() else host = rest - | - protocol.getStringValue() = "ldap://" and - concatInsecureLdapString(protocol, host) - ) - } -} - -/** - * Holds if `ma` writes the `java.naming.provider.url` (also known as `Context.PROVIDER_URL`) key of a `Hashtable`. - */ -predicate isProviderUrlSetter(MethodAccess ma) { - ma.getMethod().getDeclaringType().getAnAncestor() instanceof TypeHashtable and - ma.getMethod().hasName(["put", "setProperty"]) and - ( - ma.getArgument(0).(CompileTimeConstantExpr).getStringValue() = "java.naming.provider.url" - or - exists(Field f | - ma.getArgument(0) = f.getAnAccess() and - f.hasName("PROVIDER_URL") and - f.getDeclaringType() instanceof TypeNamingContext - ) - ) -} - -/** - * Holds if `ma` sets `fieldValue` to `envValue` in some `Hashtable`. - */ -bindingset[fieldValue, envValue] -predicate hasFieldValueEnv(MethodAccess ma, string fieldValue, string envValue) { - // environment.put("java.naming.security.authentication", "simple") - ma.getMethod().getDeclaringType().getAnAncestor() instanceof TypeHashtable and - ma.getMethod().hasName(["put", "setProperty"]) and - ma.getArgument(0).(CompileTimeConstantExpr).getStringValue() = fieldValue and - ma.getArgument(1).(CompileTimeConstantExpr).getStringValue() = envValue -} - -/** - * Holds if `ma` sets attribute name `fieldName` to `envValue` in some `Hashtable`. - */ -bindingset[fieldName, envValue] -predicate hasFieldNameEnv(MethodAccess ma, string fieldName, string envValue) { - // environment.put(Context.SECURITY_AUTHENTICATION, "simple") - ma.getMethod().getDeclaringType().getAnAncestor() instanceof TypeHashtable and - ma.getMethod().hasName(["put", "setProperty"]) and - exists(Field f | - ma.getArgument(0) = f.getAnAccess() and - f.hasName(fieldName) and - f.getDeclaringType() instanceof TypeNamingContext - ) and - ma.getArgument(1).(CompileTimeConstantExpr).getStringValue() = envValue -} - -/** - * Holds if `ma` sets `java.naming.security.authentication` (also known as `Context.SECURITY_AUTHENTICATION`) to `simple` in some `Hashtable`. - */ -predicate isBasicAuthEnv(MethodAccess ma) { - hasFieldValueEnv(ma, "java.naming.security.authentication", "simple") or - hasFieldNameEnv(ma, "SECURITY_AUTHENTICATION", "simple") -} - -/** - * Holds if `ma` sets `java.naming.security.protocol` (also known as `Context.SECURITY_PROTOCOL`) to `ssl` in some `Hashtable`. - */ -predicate isSslEnv(MethodAccess ma) { - hasFieldValueEnv(ma, "java.naming.security.protocol", "ssl") or - hasFieldNameEnv(ma, "SECURITY_PROTOCOL", "ssl") -} - -/** - * A taint-tracking configuration for `ldap://` URL in LDAP authentication. - */ -class InsecureUrlFlowConfig extends TaintTracking::Configuration { - InsecureUrlFlowConfig() { this = "InsecureLdapAuth:InsecureUrlFlowConfig" } - - /** Source of `ldap://` connection string. */ - override predicate isSource(DataFlow::Node src) { src.asExpr() instanceof InsecureLdapUrl } - - /** Sink of directory context creation. */ - override predicate isSink(DataFlow::Node sink) { - exists(ConstructorCall cc | - cc.getConstructedType().getAnAncestor() instanceof TypeDirContext and - sink.asExpr() = cc.getArgument(0) - ) - } - - /** Method call of `env.put()`. */ - override predicate isAdditionalTaintStep(DataFlow::Node pred, DataFlow::Node succ) { - exists(MethodAccess ma | - pred.asExpr() = ma.getArgument(1) and - isProviderUrlSetter(ma) and - succ.asExpr() = ma.getQualifier() - ) - } -} - -/** - * A taint-tracking configuration for `simple` basic-authentication in LDAP configuration. - */ -class BasicAuthFlowConfig extends DataFlow::Configuration { - BasicAuthFlowConfig() { this = "InsecureLdapAuth:BasicAuthFlowConfig" } - - /** Source of `simple` configuration. */ - override predicate isSource(DataFlow::Node src) { - exists(MethodAccess ma | - isBasicAuthEnv(ma) and ma.getQualifier() = src.(PostUpdateNode).getPreUpdateNode().asExpr() - ) - } - - /** Sink of directory context creation. */ - override predicate isSink(DataFlow::Node sink) { - exists(ConstructorCall cc | - cc.getConstructedType().getAnAncestor() instanceof TypeDirContext and - sink.asExpr() = cc.getArgument(0) - ) - } -} - -/** - * A taint-tracking configuration for `ssl` configuration in LDAP authentication. - */ -class SslFlowConfig extends DataFlow::Configuration { - SslFlowConfig() { this = "InsecureLdapAuth:SSLFlowConfig" } - - /** Source of `ssl` configuration. */ - override predicate isSource(DataFlow::Node src) { - exists(MethodAccess ma | - isSslEnv(ma) and ma.getQualifier() = src.(PostUpdateNode).getPreUpdateNode().asExpr() - ) - } - - /** Sink of directory context creation. */ - override predicate isSink(DataFlow::Node sink) { - exists(ConstructorCall cc | - cc.getConstructedType().getAnAncestor() instanceof TypeDirContext and - sink.asExpr() = cc.getArgument(0) - ) - } -} - from DataFlow::PathNode source, DataFlow::PathNode sink, InsecureUrlFlowConfig config where config.hasFlowPath(source, sink) and From 98b445c6b756eda24f373ab08714ed47295c8a30 Mon Sep 17 00:00:00 2001 From: Ed Minnix <egregius313@github.com> Date: Wed, 8 Mar 2023 20:53:59 -0500 Subject: [PATCH 514/631] Convert test to InlineExpectationsTest --- .../CWE-522/InsecureLdapAuth.expected | 111 ------------------ .../security/CWE-522/InsecureLdapAuth.java | 32 ++--- .../security/CWE-522/InsecureLdapAuth.qlref | 1 - .../CWE-522/InsecureLdapAuthTest.expected | 0 .../security/CWE-522/InsecureLdapAuthTest.ql | 20 ++++ 5 files changed, 36 insertions(+), 128 deletions(-) delete mode 100644 java/ql/test/query-tests/security/CWE-522/InsecureLdapAuth.expected delete mode 100644 java/ql/test/query-tests/security/CWE-522/InsecureLdapAuth.qlref create mode 100644 java/ql/test/query-tests/security/CWE-522/InsecureLdapAuthTest.expected create mode 100644 java/ql/test/query-tests/security/CWE-522/InsecureLdapAuthTest.ql diff --git a/java/ql/test/query-tests/security/CWE-522/InsecureLdapAuth.expected b/java/ql/test/query-tests/security/CWE-522/InsecureLdapAuth.expected deleted file mode 100644 index 4ae27bd27af..00000000000 --- a/java/ql/test/query-tests/security/CWE-522/InsecureLdapAuth.expected +++ /dev/null @@ -1,111 +0,0 @@ -edges -| InsecureLdapAuth.java:11:20:11:50 | "ldap://ad.your-server.com:389" : String | InsecureLdapAuth.java:15:41:15:47 | ldapUrl : String | -| InsecureLdapAuth.java:11:20:11:50 | "ldap://ad.your-server.com:389" : String | InsecureLdapAuth.java:20:49:20:59 | environment | -| InsecureLdapAuth.java:15:3:15:13 | environment [post update] [<map.value>] : String | InsecureLdapAuth.java:20:49:20:59 | environment | -| InsecureLdapAuth.java:15:41:15:47 | ldapUrl : String | InsecureLdapAuth.java:15:3:15:13 | environment [post update] [<map.value>] : String | -| InsecureLdapAuth.java:17:3:17:13 | environment [post update] : Hashtable | InsecureLdapAuth.java:20:49:20:59 | environment | -| InsecureLdapAuth.java:25:20:25:39 | ... + ... : String | InsecureLdapAuth.java:29:41:29:47 | ldapUrl : String | -| InsecureLdapAuth.java:25:20:25:39 | ... + ... : String | InsecureLdapAuth.java:34:49:34:59 | environment | -| InsecureLdapAuth.java:29:3:29:13 | environment [post update] [<map.value>] : String | InsecureLdapAuth.java:34:49:34:59 | environment | -| InsecureLdapAuth.java:29:41:29:47 | ldapUrl : String | InsecureLdapAuth.java:29:3:29:13 | environment [post update] [<map.value>] : String | -| InsecureLdapAuth.java:31:3:31:13 | environment [post update] : Hashtable | InsecureLdapAuth.java:34:49:34:59 | environment | -| InsecureLdapAuth.java:45:3:45:13 | environment [post update] : Hashtable | InsecureLdapAuth.java:48:49:48:59 | environment | -| InsecureLdapAuth.java:53:20:53:50 | "ldap://ad.your-server.com:636" : String | InsecureLdapAuth.java:57:41:57:47 | ldapUrl : String | -| InsecureLdapAuth.java:53:20:53:50 | "ldap://ad.your-server.com:636" : String | InsecureLdapAuth.java:63:49:63:59 | environment | -| InsecureLdapAuth.java:57:3:57:13 | environment [post update] [<map.value>] : String | InsecureLdapAuth.java:63:49:63:59 | environment | -| InsecureLdapAuth.java:57:41:57:47 | ldapUrl : String | InsecureLdapAuth.java:57:3:57:13 | environment [post update] [<map.value>] : String | -| InsecureLdapAuth.java:59:3:59:13 | environment [post update] : Hashtable | InsecureLdapAuth.java:63:49:63:59 | environment | -| InsecureLdapAuth.java:62:3:62:13 | environment [post update] : Hashtable | InsecureLdapAuth.java:63:49:63:59 | environment | -| InsecureLdapAuth.java:68:20:68:50 | "ldap://ad.your-server.com:389" : String | InsecureLdapAuth.java:72:41:72:47 | ldapUrl : String | -| InsecureLdapAuth.java:68:20:68:50 | "ldap://ad.your-server.com:389" : String | InsecureLdapAuth.java:77:49:77:59 | environment | -| InsecureLdapAuth.java:72:3:72:13 | environment [post update] [<map.value>] : String | InsecureLdapAuth.java:77:49:77:59 | environment | -| InsecureLdapAuth.java:72:41:72:47 | ldapUrl : String | InsecureLdapAuth.java:72:3:72:13 | environment [post update] [<map.value>] : String | -| InsecureLdapAuth.java:88:3:88:13 | environment [post update] : Hashtable | InsecureLdapAuth.java:91:49:91:59 | environment | -| InsecureLdapAuth.java:96:20:96:50 | "ldap://ad.your-server.com:389" : String | InsecureLdapAuth.java:100:41:100:47 | ldapUrl : String | -| InsecureLdapAuth.java:96:20:96:50 | "ldap://ad.your-server.com:389" : String | InsecureLdapAuth.java:105:59:105:69 | environment | -| InsecureLdapAuth.java:100:3:100:13 | environment [post update] [<map.value>] : String | InsecureLdapAuth.java:105:59:105:69 | environment | -| InsecureLdapAuth.java:100:41:100:47 | ldapUrl : String | InsecureLdapAuth.java:100:3:100:13 | environment [post update] [<map.value>] : String | -| InsecureLdapAuth.java:102:3:102:13 | environment [post update] : Hashtable | InsecureLdapAuth.java:105:59:105:69 | environment | -| InsecureLdapAuth.java:111:20:111:50 | "ldap://ad.your-server.com:389" : String | InsecureLdapAuth.java:115:47:115:53 | ldapUrl : String | -| InsecureLdapAuth.java:111:20:111:50 | "ldap://ad.your-server.com:389" : String | InsecureLdapAuth.java:120:49:120:59 | environment | -| InsecureLdapAuth.java:115:3:115:13 | environment [post update] [<map.value>] : String | InsecureLdapAuth.java:120:49:120:59 | environment | -| InsecureLdapAuth.java:115:47:115:53 | ldapUrl : String | InsecureLdapAuth.java:115:3:115:13 | environment [post update] [<map.value>] : String | -| InsecureLdapAuth.java:117:3:117:13 | environment [post update] : Hashtable | InsecureLdapAuth.java:120:49:120:59 | environment | -| InsecureLdapAuth.java:124:3:124:5 | env [post update] : Hashtable | InsecureLdapAuth.java:137:10:137:20 | environment [post update] : Hashtable | -| InsecureLdapAuth.java:128:3:128:5 | env [post update] : Hashtable | InsecureLdapAuth.java:141:16:141:26 | environment [post update] : Hashtable | -| InsecureLdapAuth.java:128:3:128:5 | env [post update] : Hashtable | InsecureLdapAuth.java:152:16:152:26 | environment [post update] : Hashtable | -| InsecureLdapAuth.java:135:20:135:39 | ... + ... : String | InsecureLdapAuth.java:140:41:140:47 | ldapUrl : String | -| InsecureLdapAuth.java:135:20:135:39 | ... + ... : String | InsecureLdapAuth.java:142:50:142:60 | environment | -| InsecureLdapAuth.java:137:10:137:20 | environment [post update] : Hashtable | InsecureLdapAuth.java:142:50:142:60 | environment | -| InsecureLdapAuth.java:140:3:140:13 | environment [post update] [<map.value>] : String | InsecureLdapAuth.java:142:50:142:60 | environment | -| InsecureLdapAuth.java:140:41:140:47 | ldapUrl : String | InsecureLdapAuth.java:140:3:140:13 | environment [post update] [<map.value>] : String | -| InsecureLdapAuth.java:141:16:141:26 | environment [post update] : Hashtable | InsecureLdapAuth.java:142:50:142:60 | environment | -| InsecureLdapAuth.java:147:20:147:39 | ... + ... : String | InsecureLdapAuth.java:151:41:151:47 | ldapUrl : String | -| InsecureLdapAuth.java:147:20:147:39 | ... + ... : String | InsecureLdapAuth.java:153:50:153:60 | environment | -| InsecureLdapAuth.java:151:3:151:13 | environment [post update] [<map.value>] : String | InsecureLdapAuth.java:153:50:153:60 | environment | -| InsecureLdapAuth.java:151:41:151:47 | ldapUrl : String | InsecureLdapAuth.java:151:3:151:13 | environment [post update] [<map.value>] : String | -| InsecureLdapAuth.java:152:16:152:26 | environment [post update] : Hashtable | InsecureLdapAuth.java:153:50:153:60 | environment | -nodes -| InsecureLdapAuth.java:11:20:11:50 | "ldap://ad.your-server.com:389" : String | semmle.label | "ldap://ad.your-server.com:389" : String | -| InsecureLdapAuth.java:15:3:15:13 | environment [post update] [<map.value>] : String | semmle.label | environment [post update] [<map.value>] : String | -| InsecureLdapAuth.java:15:41:15:47 | ldapUrl : String | semmle.label | ldapUrl : String | -| InsecureLdapAuth.java:17:3:17:13 | environment [post update] : Hashtable | semmle.label | environment [post update] : Hashtable | -| InsecureLdapAuth.java:20:49:20:59 | environment | semmle.label | environment | -| InsecureLdapAuth.java:20:49:20:59 | environment | semmle.label | environment | -| InsecureLdapAuth.java:25:20:25:39 | ... + ... : String | semmle.label | ... + ... : String | -| InsecureLdapAuth.java:29:3:29:13 | environment [post update] [<map.value>] : String | semmle.label | environment [post update] [<map.value>] : String | -| InsecureLdapAuth.java:29:41:29:47 | ldapUrl : String | semmle.label | ldapUrl : String | -| InsecureLdapAuth.java:31:3:31:13 | environment [post update] : Hashtable | semmle.label | environment [post update] : Hashtable | -| InsecureLdapAuth.java:34:49:34:59 | environment | semmle.label | environment | -| InsecureLdapAuth.java:34:49:34:59 | environment | semmle.label | environment | -| InsecureLdapAuth.java:45:3:45:13 | environment [post update] : Hashtable | semmle.label | environment [post update] : Hashtable | -| InsecureLdapAuth.java:48:49:48:59 | environment | semmle.label | environment | -| InsecureLdapAuth.java:53:20:53:50 | "ldap://ad.your-server.com:636" : String | semmle.label | "ldap://ad.your-server.com:636" : String | -| InsecureLdapAuth.java:57:3:57:13 | environment [post update] [<map.value>] : String | semmle.label | environment [post update] [<map.value>] : String | -| InsecureLdapAuth.java:57:41:57:47 | ldapUrl : String | semmle.label | ldapUrl : String | -| InsecureLdapAuth.java:59:3:59:13 | environment [post update] : Hashtable | semmle.label | environment [post update] : Hashtable | -| InsecureLdapAuth.java:62:3:62:13 | environment [post update] : Hashtable | semmle.label | environment [post update] : Hashtable | -| InsecureLdapAuth.java:63:49:63:59 | environment | semmle.label | environment | -| InsecureLdapAuth.java:63:49:63:59 | environment | semmle.label | environment | -| InsecureLdapAuth.java:63:49:63:59 | environment | semmle.label | environment | -| InsecureLdapAuth.java:68:20:68:50 | "ldap://ad.your-server.com:389" : String | semmle.label | "ldap://ad.your-server.com:389" : String | -| InsecureLdapAuth.java:72:3:72:13 | environment [post update] [<map.value>] : String | semmle.label | environment [post update] [<map.value>] : String | -| InsecureLdapAuth.java:72:41:72:47 | ldapUrl : String | semmle.label | ldapUrl : String | -| InsecureLdapAuth.java:77:49:77:59 | environment | semmle.label | environment | -| InsecureLdapAuth.java:88:3:88:13 | environment [post update] : Hashtable | semmle.label | environment [post update] : Hashtable | -| InsecureLdapAuth.java:91:49:91:59 | environment | semmle.label | environment | -| InsecureLdapAuth.java:96:20:96:50 | "ldap://ad.your-server.com:389" : String | semmle.label | "ldap://ad.your-server.com:389" : String | -| InsecureLdapAuth.java:100:3:100:13 | environment [post update] [<map.value>] : String | semmle.label | environment [post update] [<map.value>] : String | -| InsecureLdapAuth.java:100:41:100:47 | ldapUrl : String | semmle.label | ldapUrl : String | -| InsecureLdapAuth.java:102:3:102:13 | environment [post update] : Hashtable | semmle.label | environment [post update] : Hashtable | -| InsecureLdapAuth.java:105:59:105:69 | environment | semmle.label | environment | -| InsecureLdapAuth.java:105:59:105:69 | environment | semmle.label | environment | -| InsecureLdapAuth.java:111:20:111:50 | "ldap://ad.your-server.com:389" : String | semmle.label | "ldap://ad.your-server.com:389" : String | -| InsecureLdapAuth.java:115:3:115:13 | environment [post update] [<map.value>] : String | semmle.label | environment [post update] [<map.value>] : String | -| InsecureLdapAuth.java:115:47:115:53 | ldapUrl : String | semmle.label | ldapUrl : String | -| InsecureLdapAuth.java:117:3:117:13 | environment [post update] : Hashtable | semmle.label | environment [post update] : Hashtable | -| InsecureLdapAuth.java:120:49:120:59 | environment | semmle.label | environment | -| InsecureLdapAuth.java:120:49:120:59 | environment | semmle.label | environment | -| InsecureLdapAuth.java:124:3:124:5 | env [post update] : Hashtable | semmle.label | env [post update] : Hashtable | -| InsecureLdapAuth.java:128:3:128:5 | env [post update] : Hashtable | semmle.label | env [post update] : Hashtable | -| InsecureLdapAuth.java:135:20:135:39 | ... + ... : String | semmle.label | ... + ... : String | -| InsecureLdapAuth.java:137:10:137:20 | environment [post update] : Hashtable | semmle.label | environment [post update] : Hashtable | -| InsecureLdapAuth.java:140:3:140:13 | environment [post update] [<map.value>] : String | semmle.label | environment [post update] [<map.value>] : String | -| InsecureLdapAuth.java:140:41:140:47 | ldapUrl : String | semmle.label | ldapUrl : String | -| InsecureLdapAuth.java:141:16:141:26 | environment [post update] : Hashtable | semmle.label | environment [post update] : Hashtable | -| InsecureLdapAuth.java:142:50:142:60 | environment | semmle.label | environment | -| InsecureLdapAuth.java:142:50:142:60 | environment | semmle.label | environment | -| InsecureLdapAuth.java:142:50:142:60 | environment | semmle.label | environment | -| InsecureLdapAuth.java:147:20:147:39 | ... + ... : String | semmle.label | ... + ... : String | -| InsecureLdapAuth.java:151:3:151:13 | environment [post update] [<map.value>] : String | semmle.label | environment [post update] [<map.value>] : String | -| InsecureLdapAuth.java:151:41:151:47 | ldapUrl : String | semmle.label | ldapUrl : String | -| InsecureLdapAuth.java:152:16:152:26 | environment [post update] : Hashtable | semmle.label | environment [post update] : Hashtable | -| InsecureLdapAuth.java:153:50:153:60 | environment | semmle.label | environment | -| InsecureLdapAuth.java:153:50:153:60 | environment | semmle.label | environment | -subpaths -#select -| InsecureLdapAuth.java:20:49:20:59 | environment | InsecureLdapAuth.java:11:20:11:50 | "ldap://ad.your-server.com:389" : String | InsecureLdapAuth.java:20:49:20:59 | environment | Insecure LDAP authentication from $@. | InsecureLdapAuth.java:11:20:11:50 | "ldap://ad.your-server.com:389" | LDAP connection string | -| InsecureLdapAuth.java:34:49:34:59 | environment | InsecureLdapAuth.java:25:20:25:39 | ... + ... : String | InsecureLdapAuth.java:34:49:34:59 | environment | Insecure LDAP authentication from $@. | InsecureLdapAuth.java:25:20:25:39 | ... + ... | LDAP connection string | -| InsecureLdapAuth.java:105:59:105:69 | environment | InsecureLdapAuth.java:96:20:96:50 | "ldap://ad.your-server.com:389" : String | InsecureLdapAuth.java:105:59:105:69 | environment | Insecure LDAP authentication from $@. | InsecureLdapAuth.java:96:20:96:50 | "ldap://ad.your-server.com:389" | LDAP connection string | -| InsecureLdapAuth.java:120:49:120:59 | environment | InsecureLdapAuth.java:111:20:111:50 | "ldap://ad.your-server.com:389" : String | InsecureLdapAuth.java:120:49:120:59 | environment | Insecure LDAP authentication from $@. | InsecureLdapAuth.java:111:20:111:50 | "ldap://ad.your-server.com:389" | LDAP connection string | -| InsecureLdapAuth.java:153:50:153:60 | environment | InsecureLdapAuth.java:147:20:147:39 | ... + ... : String | InsecureLdapAuth.java:153:50:153:60 | environment | Insecure LDAP authentication from $@. | InsecureLdapAuth.java:147:20:147:39 | ... + ... | LDAP connection string | diff --git a/java/ql/test/query-tests/security/CWE-522/InsecureLdapAuth.java b/java/ql/test/query-tests/security/CWE-522/InsecureLdapAuth.java index 978a4df671b..d769258a611 100644 --- a/java/ql/test/query-tests/security/CWE-522/InsecureLdapAuth.java +++ b/java/ql/test/query-tests/security/CWE-522/InsecureLdapAuth.java @@ -11,13 +11,13 @@ public class InsecureLdapAuth { String ldapUrl = "ldap://ad.your-server.com:389"; Hashtable<String, String> environment = new Hashtable<String, String>(); environment.put(Context.INITIAL_CONTEXT_FACTORY, - "com.sun.jndi.ldap.LdapCtxFactory"); + "com.sun.jndi.ldap.LdapCtxFactory"); environment.put(Context.PROVIDER_URL, ldapUrl); environment.put(Context.REFERRAL, "follow"); environment.put(Context.SECURITY_AUTHENTICATION, "simple"); environment.put(Context.SECURITY_PRINCIPAL, ldapUserName); environment.put(Context.SECURITY_CREDENTIALS, password); - DirContext dirContext = new InitialDirContext(environment); + DirContext dirContext = new InitialDirContext(environment); // $ hasInsecureLdapAuth } // BAD - Test LDAP authentication in cleartext using `DirContext`. @@ -25,13 +25,13 @@ public class InsecureLdapAuth { String ldapUrl = "ldap://"+serverName+":389"; Hashtable<String, String> environment = new Hashtable<String, String>(); environment.put(Context.INITIAL_CONTEXT_FACTORY, - "com.sun.jndi.ldap.LdapCtxFactory"); + "com.sun.jndi.ldap.LdapCtxFactory"); environment.put(Context.PROVIDER_URL, ldapUrl); environment.put(Context.REFERRAL, "follow"); environment.put(Context.SECURITY_AUTHENTICATION, "simple"); environment.put(Context.SECURITY_PRINCIPAL, ldapUserName); environment.put(Context.SECURITY_CREDENTIALS, password); - DirContext dirContext = new InitialDirContext(environment); + DirContext dirContext = new InitialDirContext(environment); // $ hasInsecureLdapAuth } // GOOD - Test LDAP authentication over SSL. @@ -39,7 +39,7 @@ public class InsecureLdapAuth { String ldapUrl = "ldaps://ad.your-server.com:636"; Hashtable<String, String> environment = new Hashtable<String, String>(); environment.put(Context.INITIAL_CONTEXT_FACTORY, - "com.sun.jndi.ldap.LdapCtxFactory"); + "com.sun.jndi.ldap.LdapCtxFactory"); environment.put(Context.PROVIDER_URL, ldapUrl); environment.put(Context.REFERRAL, "follow"); environment.put(Context.SECURITY_AUTHENTICATION, "simple"); @@ -53,7 +53,7 @@ public class InsecureLdapAuth { String ldapUrl = "ldap://ad.your-server.com:636"; Hashtable<String, String> environment = new Hashtable<String, String>(); environment.put(Context.INITIAL_CONTEXT_FACTORY, - "com.sun.jndi.ldap.LdapCtxFactory"); + "com.sun.jndi.ldap.LdapCtxFactory"); environment.put(Context.PROVIDER_URL, ldapUrl); environment.put(Context.REFERRAL, "follow"); environment.put(Context.SECURITY_AUTHENTICATION, "simple"); @@ -68,7 +68,7 @@ public class InsecureLdapAuth { String ldapUrl = "ldap://ad.your-server.com:389"; Hashtable<String, String> environment = new Hashtable<String, String>(); environment.put(Context.INITIAL_CONTEXT_FACTORY, - "com.sun.jndi.ldap.LdapCtxFactory"); + "com.sun.jndi.ldap.LdapCtxFactory"); environment.put(Context.PROVIDER_URL, ldapUrl); environment.put(Context.REFERRAL, "follow"); environment.put(Context.SECURITY_AUTHENTICATION, "DIGEST-MD5 GSSAPI"); @@ -82,7 +82,7 @@ public class InsecureLdapAuth { String ldapUrl = "ldap://localhost:389"; Hashtable<String, String> environment = new Hashtable<String, String>(); environment.put(Context.INITIAL_CONTEXT_FACTORY, - "com.sun.jndi.ldap.LdapCtxFactory"); + "com.sun.jndi.ldap.LdapCtxFactory"); environment.put(Context.PROVIDER_URL, ldapUrl); environment.put(Context.REFERRAL, "follow"); environment.put(Context.SECURITY_AUTHENTICATION, "simple"); @@ -96,14 +96,14 @@ public class InsecureLdapAuth { String ldapUrl = "ldap://ad.your-server.com:389"; Hashtable<String, String> environment = new Hashtable<String, String>(); environment.put(Context.INITIAL_CONTEXT_FACTORY, - "com.sun.jndi.ldap.LdapCtxFactory"); + "com.sun.jndi.ldap.LdapCtxFactory"); environment.put(Context.PROVIDER_URL, ldapUrl); environment.put(Context.REFERRAL, "follow"); environment.put(Context.SECURITY_AUTHENTICATION, "simple"); environment.put(Context.SECURITY_PRINCIPAL, ldapUserName); environment.put(Context.SECURITY_CREDENTIALS, password); - InitialLdapContext ldapContext = new InitialLdapContext(environment, null); - } + InitialLdapContext ldapContext = new InitialLdapContext(environment, null); // $ hasInsecureLdapAuth + } // BAD - Test LDAP authentication in cleartext using `DirContext` and string literals. @@ -111,13 +111,13 @@ public class InsecureLdapAuth { String ldapUrl = "ldap://ad.your-server.com:389"; Hashtable<String, String> environment = new Hashtable<String, String>(); environment.put("java.naming.factory.initial", - "com.sun.jndi.ldap.LdapCtxFactory"); + "com.sun.jndi.ldap.LdapCtxFactory"); environment.put("java.naming.provider.url", ldapUrl); environment.put("java.naming.referral", "follow"); environment.put("java.naming.security.authentication", "simple"); environment.put("java.naming.security.principal", ldapUserName); environment.put("java.naming.security.credentials", password); - DirContext dirContext = new InitialDirContext(environment); + DirContext dirContext = new InitialDirContext(environment); // $ hasInsecureLdapAuth } private void setSSL(Hashtable env) { @@ -136,7 +136,7 @@ public class InsecureLdapAuth { Hashtable<String, String> environment = new Hashtable<String, String>(); setSSL(environment); environment.put(Context.INITIAL_CONTEXT_FACTORY, - "com.sun.jndi.ldap.LdapCtxFactory"); + "com.sun.jndi.ldap.LdapCtxFactory"); environment.put(Context.PROVIDER_URL, ldapUrl); setBasicAuth(environment, ldapUserName, password); DirContext dirContext = new InitialLdapContext(environment, null); @@ -147,9 +147,9 @@ public class InsecureLdapAuth { String ldapUrl = "ldap://"+serverName+":389"; Hashtable<String, String> environment = new Hashtable<String, String>(); environment.put(Context.INITIAL_CONTEXT_FACTORY, - "com.sun.jndi.ldap.LdapCtxFactory"); + "com.sun.jndi.ldap.LdapCtxFactory"); environment.put(Context.PROVIDER_URL, ldapUrl); setBasicAuth(environment, ldapUserName, password); - DirContext dirContext = new InitialLdapContext(environment, null); + DirContext dirContext = new InitialLdapContext(environment, null); // $ hasInsecureLdapAuth } } diff --git a/java/ql/test/query-tests/security/CWE-522/InsecureLdapAuth.qlref b/java/ql/test/query-tests/security/CWE-522/InsecureLdapAuth.qlref deleted file mode 100644 index 952f1d5663c..00000000000 --- a/java/ql/test/query-tests/security/CWE-522/InsecureLdapAuth.qlref +++ /dev/null @@ -1 +0,0 @@ -Security/CWE/CWE-522/InsecureLdapAuth.ql diff --git a/java/ql/test/query-tests/security/CWE-522/InsecureLdapAuthTest.expected b/java/ql/test/query-tests/security/CWE-522/InsecureLdapAuthTest.expected new file mode 100644 index 00000000000..e69de29bb2d diff --git a/java/ql/test/query-tests/security/CWE-522/InsecureLdapAuthTest.ql b/java/ql/test/query-tests/security/CWE-522/InsecureLdapAuthTest.ql new file mode 100644 index 00000000000..c0779029591 --- /dev/null +++ b/java/ql/test/query-tests/security/CWE-522/InsecureLdapAuthTest.ql @@ -0,0 +1,20 @@ +import java +import semmle.code.java.security.InsecureLdapAuthQuery +import TestUtilities.InlineExpectationsTest + +class InsecureLdapAuthenticationTest extends InlineExpectationsTest { + InsecureLdapAuthenticationTest() { this = "InsecureLdapAuthentication" } + + override string getARelevantTag() { result = "hasInsecureLdapAuth" } + + override predicate hasActualResult(Location location, string element, string tag, string value) { + tag = "hasInsecureLdapAuth" and + exists(DataFlow::Node sink, InsecureUrlFlowConfig conf | conf.hasFlowTo(sink) | + any(BasicAuthFlowConfig bc).hasFlowTo(sink) and + not any(SslFlowConfig sc).hasFlowTo(sink) and + sink.getLocation() = location and + element = sink.toString() and + value = "" + ) + } +} From 05da1dc4a37ce91cc2df60d050cfe2c8a76889a1 Mon Sep 17 00:00:00 2001 From: Ed Minnix <egregius313@github.com> Date: Wed, 8 Mar 2023 21:08:02 -0500 Subject: [PATCH 515/631] Merge concatInsecureLdapString into InsecureLdapUrl constructor --- .../code/java/security/InsecureLdapAuth.qll | 27 +++++-------------- 1 file changed, 7 insertions(+), 20 deletions(-) diff --git a/java/ql/lib/semmle/code/java/security/InsecureLdapAuth.qll b/java/ql/lib/semmle/code/java/security/InsecureLdapAuth.qll index d5948f2ff04..68cafa845d2 100644 --- a/java/ql/lib/semmle/code/java/security/InsecureLdapAuth.qll +++ b/java/ql/lib/semmle/code/java/security/InsecureLdapAuth.qll @@ -22,30 +22,13 @@ class TypeHashtable extends Class { TypeHashtable() { this.getSourceDeclaration().hasQualifiedName("java.util", "Hashtable") } } -string getHostname(Expr expr) { +/** Get the string value of an expression representing a hostname. */ +private string getHostname(Expr expr) { result = expr.(CompileTimeConstantExpr).getStringValue() or result = expr.(VarAccess).getVariable().getAnAssignedValue().(CompileTimeConstantExpr).getStringValue() } -/** - * Holds if a non-private LDAP string is concatenated from both protocol and host. - */ -predicate concatInsecureLdapString(CompileTimeConstantExpr protocol, Expr host) { - protocol.getStringValue() = "ldap://" and - not exists(string hostString | hostString = getHostname(host) | - hostString.length() = 0 or // Empty host is loopback address - hostString instanceof PrivateHostName - ) -} - -// Expr getLeftmostConcatOperand(Expr expr) { -// if expr instanceof AddExpr -// then -// result = expr.(AddExpr).getLeftOperand() and -// not result instanceof AddExpr -// else result = expr -// } /** * String concatenated with `InsecureLdapUrlLiteral`. */ @@ -53,6 +36,7 @@ class InsecureLdapUrl extends Expr { InsecureLdapUrl() { this instanceof InsecureLdapUrlLiteral or + // Concatentation of insecure protcol and non-private host: // protocol + host + ... exists(AddExpr e, CompileTimeConstantExpr protocol, Expr rest, Expr host | e = this and @@ -61,7 +45,10 @@ class InsecureLdapUrl extends Expr { if rest instanceof AddExpr then host = rest.(AddExpr).getLeftOperand() else host = rest | protocol.getStringValue() = "ldap://" and - concatInsecureLdapString(protocol, host) + not exists(string hostString | hostString = getHostname(host) | + hostString.length() = 0 or // Empty host is loopback address + hostString instanceof PrivateHostName + ) ) } } From 6a0167fa7fadedfd6530d56ff908e6e187a47bc4 Mon Sep 17 00:00:00 2001 From: Ed Minnix <egregius313@github.com> Date: Wed, 8 Mar 2023 21:50:09 -0500 Subject: [PATCH 516/631] Convert to using the new DataFlow modules --- .../java/security/InsecureLdapAuthQuery.qll | 32 +++++++++---------- .../Security/CWE/CWE-522/InsecureLdapAuth.ql | 8 ++--- .../security/CWE-522/InsecureLdapAuthTest.ql | 6 ++-- 3 files changed, 23 insertions(+), 23 deletions(-) diff --git a/java/ql/lib/semmle/code/java/security/InsecureLdapAuthQuery.qll b/java/ql/lib/semmle/code/java/security/InsecureLdapAuthQuery.qll index 7d9b81dc3d3..caa451605ea 100644 --- a/java/ql/lib/semmle/code/java/security/InsecureLdapAuthQuery.qll +++ b/java/ql/lib/semmle/code/java/security/InsecureLdapAuthQuery.qll @@ -9,14 +9,12 @@ import semmle.code.java.security.InsecureLdapAuth /** * A taint-tracking configuration for `ldap://` URL in LDAP authentication. */ -class InsecureUrlFlowConfig extends TaintTracking::Configuration { - InsecureUrlFlowConfig() { this = "InsecureLdapAuth:InsecureUrlFlowConfig" } - +private module InsecureUrlFlowConfig implements DataFlow::ConfigSig { /** Source of `ldap://` connection string. */ - override predicate isSource(DataFlow::Node src) { src.asExpr() instanceof InsecureLdapUrl } + predicate isSource(DataFlow::Node src) { src.asExpr() instanceof InsecureLdapUrl } /** Sink of directory context creation. */ - override predicate isSink(DataFlow::Node sink) { + predicate isSink(DataFlow::Node sink) { exists(ConstructorCall cc | cc.getConstructedType().getAnAncestor() instanceof TypeDirContext and sink.asExpr() = cc.getArgument(0) @@ -24,7 +22,7 @@ class InsecureUrlFlowConfig extends TaintTracking::Configuration { } /** Method call of `env.put()`. */ - override predicate isAdditionalTaintStep(DataFlow::Node pred, DataFlow::Node succ) { + predicate isAdditionalFlowStep(DataFlow::Node pred, DataFlow::Node succ) { exists(MethodAccess ma | pred.asExpr() = ma.getArgument(1) and isProviderUrlSetter(ma) and @@ -33,21 +31,21 @@ class InsecureUrlFlowConfig extends TaintTracking::Configuration { } } +module InsecureUrlFlowConfiguration = TaintTracking::Make<InsecureUrlFlowConfig>; + /** * A taint-tracking configuration for `simple` basic-authentication in LDAP configuration. */ -class BasicAuthFlowConfig extends DataFlow::Configuration { - BasicAuthFlowConfig() { this = "InsecureLdapAuth:BasicAuthFlowConfig" } - +private module BasicAuthFlowConfig implements DataFlow::ConfigSig { /** Source of `simple` configuration. */ - override predicate isSource(DataFlow::Node src) { + predicate isSource(DataFlow::Node src) { exists(MethodAccess ma | isBasicAuthEnv(ma) and ma.getQualifier() = src.(PostUpdateNode).getPreUpdateNode().asExpr() ) } /** Sink of directory context creation. */ - override predicate isSink(DataFlow::Node sink) { + predicate isSink(DataFlow::Node sink) { exists(ConstructorCall cc | cc.getConstructedType().getAnAncestor() instanceof TypeDirContext and sink.asExpr() = cc.getArgument(0) @@ -55,24 +53,26 @@ class BasicAuthFlowConfig extends DataFlow::Configuration { } } +module BasicAuthFlowConfiguration = DataFlow::Make<BasicAuthFlowConfig>; + /** * A taint-tracking configuration for `ssl` configuration in LDAP authentication. */ -class SslFlowConfig extends DataFlow::Configuration { - SslFlowConfig() { this = "InsecureLdapAuth:SSLFlowConfig" } - +private module SslFlowConfig implements DataFlow::ConfigSig { /** Source of `ssl` configuration. */ - override predicate isSource(DataFlow::Node src) { + predicate isSource(DataFlow::Node src) { exists(MethodAccess ma | isSslEnv(ma) and ma.getQualifier() = src.(PostUpdateNode).getPreUpdateNode().asExpr() ) } /** Sink of directory context creation. */ - override predicate isSink(DataFlow::Node sink) { + predicate isSink(DataFlow::Node sink) { exists(ConstructorCall cc | cc.getConstructedType().getAnAncestor() instanceof TypeDirContext and sink.asExpr() = cc.getArgument(0) ) } } + +module SslFlowConfiguration = DataFlow::Make<SslFlowConfig>; diff --git a/java/ql/src/Security/CWE/CWE-522/InsecureLdapAuth.ql b/java/ql/src/Security/CWE/CWE-522/InsecureLdapAuth.ql index be129f9521c..12926256754 100644 --- a/java/ql/src/Security/CWE/CWE-522/InsecureLdapAuth.ql +++ b/java/ql/src/Security/CWE/CWE-522/InsecureLdapAuth.ql @@ -15,10 +15,10 @@ import java import semmle.code.java.security.InsecureLdapAuthQuery import DataFlow::PathGraph -from DataFlow::PathNode source, DataFlow::PathNode sink, InsecureUrlFlowConfig config +from InsecureUrlFlowConfiguration::PathNode source, InsecureUrlFlowConfiguration::PathNode sink where - config.hasFlowPath(source, sink) and - any(BasicAuthFlowConfig bc).hasFlowTo(sink.getNode()) and - not any(SslFlowConfig sc).hasFlowTo(sink.getNode()) + InsecureUrlFlowConfiguration::hasFlowPath(source, sink) and + BasicAuthFlowConfiguration::hasFlowTo(sink.getNode()) and + not SslFlowConfiguration::hasFlowTo(sink.getNode()) select sink.getNode(), source, sink, "Insecure LDAP authentication from $@.", source.getNode(), "LDAP connection string" diff --git a/java/ql/test/query-tests/security/CWE-522/InsecureLdapAuthTest.ql b/java/ql/test/query-tests/security/CWE-522/InsecureLdapAuthTest.ql index c0779029591..67660872c39 100644 --- a/java/ql/test/query-tests/security/CWE-522/InsecureLdapAuthTest.ql +++ b/java/ql/test/query-tests/security/CWE-522/InsecureLdapAuthTest.ql @@ -9,9 +9,9 @@ class InsecureLdapAuthenticationTest extends InlineExpectationsTest { override predicate hasActualResult(Location location, string element, string tag, string value) { tag = "hasInsecureLdapAuth" and - exists(DataFlow::Node sink, InsecureUrlFlowConfig conf | conf.hasFlowTo(sink) | - any(BasicAuthFlowConfig bc).hasFlowTo(sink) and - not any(SslFlowConfig sc).hasFlowTo(sink) and + exists(DataFlow::Node sink | InsecureUrlFlowConfiguration::hasFlowTo(sink) | + BasicAuthFlowConfiguration::hasFlowTo(sink) and + not SslFlowConfiguration::hasFlowTo(sink) and sink.getLocation() = location and element = sink.toString() and value = "" From db60c08de74ca0b0a3939248e5507dcd84fe7848 Mon Sep 17 00:00:00 2001 From: Ed Minnix <egregius313@github.com> Date: Wed, 8 Mar 2023 22:04:02 -0500 Subject: [PATCH 517/631] Add security severity --- java/ql/src/Security/CWE/CWE-522/InsecureLdapAuth.ql | 1 + 1 file changed, 1 insertion(+) diff --git a/java/ql/src/Security/CWE/CWE-522/InsecureLdapAuth.ql b/java/ql/src/Security/CWE/CWE-522/InsecureLdapAuth.ql index 12926256754..2bf227e0fea 100644 --- a/java/ql/src/Security/CWE/CWE-522/InsecureLdapAuth.ql +++ b/java/ql/src/Security/CWE/CWE-522/InsecureLdapAuth.ql @@ -3,6 +3,7 @@ * @description LDAP authentication with credentials sent in cleartext. * @kind path-problem * @problem.severity warning + * @security-severity 8.8 * @precision medium * @id java/insecure-ldap-auth * @tags security From 0f4709e76944e1557f70d924ac68346e95b1da7f Mon Sep 17 00:00:00 2001 From: Ed Minnix <egregius313@github.com> Date: Wed, 8 Mar 2023 22:03:34 -0500 Subject: [PATCH 518/631] Add change note --- .../change-notes/2023-03-08-insecure-ldap-authentication.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 java/ql/src/change-notes/2023-03-08-insecure-ldap-authentication.md diff --git a/java/ql/src/change-notes/2023-03-08-insecure-ldap-authentication.md b/java/ql/src/change-notes/2023-03-08-insecure-ldap-authentication.md new file mode 100644 index 00000000000..160d5639b22 --- /dev/null +++ b/java/ql/src/change-notes/2023-03-08-insecure-ldap-authentication.md @@ -0,0 +1,4 @@ +--- +category: newQuery +--- +* The query `java/insecure-ldap-auth` has been promoted from experimental to the main query pack. This query was originally [submitted as an experimental query by @luchua-bc](https://github.com/github/codeql/pull/4854) \ No newline at end of file From 59ce0d76821103f93cf8b87808f9e9fc9d9f013d Mon Sep 17 00:00:00 2001 From: Ed Minnix <egregius313@github.com> Date: Wed, 8 Mar 2023 22:16:44 -0500 Subject: [PATCH 519/631] Documentation changes --- java/ql/lib/semmle/code/java/security/InsecureLdapAuth.qll | 4 ++-- .../lib/semmle/code/java/security/InsecureLdapAuthQuery.qll | 6 ------ 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/java/ql/lib/semmle/code/java/security/InsecureLdapAuth.qll b/java/ql/lib/semmle/code/java/security/InsecureLdapAuth.qll index 68cafa845d2..1c9cab6f24d 100644 --- a/java/ql/lib/semmle/code/java/security/InsecureLdapAuth.qll +++ b/java/ql/lib/semmle/code/java/security/InsecureLdapAuth.qll @@ -5,7 +5,7 @@ import semmle.code.java.frameworks.Networking import semmle.code.java.frameworks.Jndi /** - * Insecure (non-SSL, non-private) LDAP URL string literal. + * An insecure (non-SSL, non-private) LDAP URL string literal. */ class InsecureLdapUrlLiteral extends StringLiteral { InsecureLdapUrlLiteral() { @@ -30,7 +30,7 @@ private string getHostname(Expr expr) { } /** - * String concatenated with `InsecureLdapUrlLiteral`. + * An expression that represents an insecure (non-SSL, non-private) LDAP URL. */ class InsecureLdapUrl extends Expr { InsecureLdapUrl() { diff --git a/java/ql/lib/semmle/code/java/security/InsecureLdapAuthQuery.qll b/java/ql/lib/semmle/code/java/security/InsecureLdapAuthQuery.qll index caa451605ea..04d452be423 100644 --- a/java/ql/lib/semmle/code/java/security/InsecureLdapAuthQuery.qll +++ b/java/ql/lib/semmle/code/java/security/InsecureLdapAuthQuery.qll @@ -10,10 +10,8 @@ import semmle.code.java.security.InsecureLdapAuth * A taint-tracking configuration for `ldap://` URL in LDAP authentication. */ private module InsecureUrlFlowConfig implements DataFlow::ConfigSig { - /** Source of `ldap://` connection string. */ predicate isSource(DataFlow::Node src) { src.asExpr() instanceof InsecureLdapUrl } - /** Sink of directory context creation. */ predicate isSink(DataFlow::Node sink) { exists(ConstructorCall cc | cc.getConstructedType().getAnAncestor() instanceof TypeDirContext and @@ -37,14 +35,12 @@ module InsecureUrlFlowConfiguration = TaintTracking::Make<InsecureUrlFlowConfig> * A taint-tracking configuration for `simple` basic-authentication in LDAP configuration. */ private module BasicAuthFlowConfig implements DataFlow::ConfigSig { - /** Source of `simple` configuration. */ predicate isSource(DataFlow::Node src) { exists(MethodAccess ma | isBasicAuthEnv(ma) and ma.getQualifier() = src.(PostUpdateNode).getPreUpdateNode().asExpr() ) } - /** Sink of directory context creation. */ predicate isSink(DataFlow::Node sink) { exists(ConstructorCall cc | cc.getConstructedType().getAnAncestor() instanceof TypeDirContext and @@ -59,14 +55,12 @@ module BasicAuthFlowConfiguration = DataFlow::Make<BasicAuthFlowConfig>; * A taint-tracking configuration for `ssl` configuration in LDAP authentication. */ private module SslFlowConfig implements DataFlow::ConfigSig { - /** Source of `ssl` configuration. */ predicate isSource(DataFlow::Node src) { exists(MethodAccess ma | isSslEnv(ma) and ma.getQualifier() = src.(PostUpdateNode).getPreUpdateNode().asExpr() ) } - /** Sink of directory context creation. */ predicate isSink(DataFlow::Node sink) { exists(ConstructorCall cc | cc.getConstructedType().getAnAncestor() instanceof TypeDirContext and From efdfc2d0c303edd1e2b350a2ec5ebb1d562e2c06 Mon Sep 17 00:00:00 2001 From: Ed Minnix <egregius313@github.com> Date: Thu, 9 Mar 2023 11:00:54 -0500 Subject: [PATCH 520/631] Change version of PathNode used to appropriate module --- java/ql/src/Security/CWE/CWE-522/InsecureLdapAuth.ql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/ql/src/Security/CWE/CWE-522/InsecureLdapAuth.ql b/java/ql/src/Security/CWE/CWE-522/InsecureLdapAuth.ql index 2bf227e0fea..98c4332bcfe 100644 --- a/java/ql/src/Security/CWE/CWE-522/InsecureLdapAuth.ql +++ b/java/ql/src/Security/CWE/CWE-522/InsecureLdapAuth.ql @@ -14,7 +14,7 @@ import java import semmle.code.java.security.InsecureLdapAuthQuery -import DataFlow::PathGraph +import InsecureLdapAuthQuery::PathGraph from InsecureUrlFlowConfiguration::PathNode source, InsecureUrlFlowConfiguration::PathNode sink where From 752620a34d1f3a2e7e889ba70158981e32f125fd Mon Sep 17 00:00:00 2001 From: Ed Minnix <egregius313@github.com> Date: Thu, 9 Mar 2023 17:15:21 -0500 Subject: [PATCH 521/631] Rename SSL configuration and fix PathGraph --- .../lib/semmle/code/java/security/InsecureLdapAuthQuery.qll | 4 ++-- java/ql/src/Security/CWE/CWE-522/InsecureLdapAuth.ql | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/java/ql/lib/semmle/code/java/security/InsecureLdapAuthQuery.qll b/java/ql/lib/semmle/code/java/security/InsecureLdapAuthQuery.qll index 04d452be423..b8acf539bed 100644 --- a/java/ql/lib/semmle/code/java/security/InsecureLdapAuthQuery.qll +++ b/java/ql/lib/semmle/code/java/security/InsecureLdapAuthQuery.qll @@ -54,7 +54,7 @@ module BasicAuthFlowConfiguration = DataFlow::Make<BasicAuthFlowConfig>; /** * A taint-tracking configuration for `ssl` configuration in LDAP authentication. */ -private module SslFlowConfig implements DataFlow::ConfigSig { +private module RequiresSslConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node src) { exists(MethodAccess ma | isSslEnv(ma) and ma.getQualifier() = src.(PostUpdateNode).getPreUpdateNode().asExpr() @@ -69,4 +69,4 @@ private module SslFlowConfig implements DataFlow::ConfigSig { } } -module SslFlowConfiguration = DataFlow::Make<SslFlowConfig>; +module RequiresSslConfiguration = DataFlow::Make<RequiresSslConfig>; diff --git a/java/ql/src/Security/CWE/CWE-522/InsecureLdapAuth.ql b/java/ql/src/Security/CWE/CWE-522/InsecureLdapAuth.ql index 98c4332bcfe..1abfdd69fec 100644 --- a/java/ql/src/Security/CWE/CWE-522/InsecureLdapAuth.ql +++ b/java/ql/src/Security/CWE/CWE-522/InsecureLdapAuth.ql @@ -14,12 +14,12 @@ import java import semmle.code.java.security.InsecureLdapAuthQuery -import InsecureLdapAuthQuery::PathGraph +import InsecureUrlFlowConfiguration::PathGraph from InsecureUrlFlowConfiguration::PathNode source, InsecureUrlFlowConfiguration::PathNode sink where InsecureUrlFlowConfiguration::hasFlowPath(source, sink) and BasicAuthFlowConfiguration::hasFlowTo(sink.getNode()) and - not SslFlowConfiguration::hasFlowTo(sink.getNode()) + not RequiresSslConfiguration::hasFlowTo(sink.getNode()) select sink.getNode(), source, sink, "Insecure LDAP authentication from $@.", source.getNode(), "LDAP connection string" From cb58936c083d1a5943fa2fd68fd3a1d8ef6c6b77 Mon Sep 17 00:00:00 2001 From: Ed Minnix <egregius313@github.com> Date: Fri, 10 Mar 2023 14:48:41 -0500 Subject: [PATCH 522/631] Documentation changes --- .../CWE/CWE-522/InsecureLdapAuth.java | 24 -------------- .../CWE/CWE-522/InsecureLdapAuth.qhelp | 32 ++++++++++++++++--- .../Security/CWE/CWE-522/LdapAuthUseLdap.java | 9 ++++++ .../CWE/CWE-522/LdapAuthUseLdaps.java | 9 ++++++ .../Security/CWE/CWE-522/LdapEnableSasl.java | 9 ++++++ 5 files changed, 55 insertions(+), 28 deletions(-) delete mode 100644 java/ql/src/Security/CWE/CWE-522/InsecureLdapAuth.java create mode 100644 java/ql/src/Security/CWE/CWE-522/LdapAuthUseLdap.java create mode 100644 java/ql/src/Security/CWE/CWE-522/LdapAuthUseLdaps.java create mode 100644 java/ql/src/Security/CWE/CWE-522/LdapEnableSasl.java diff --git a/java/ql/src/Security/CWE/CWE-522/InsecureLdapAuth.java b/java/ql/src/Security/CWE/CWE-522/InsecureLdapAuth.java deleted file mode 100644 index 3c5f6555100..00000000000 --- a/java/ql/src/Security/CWE/CWE-522/InsecureLdapAuth.java +++ /dev/null @@ -1,24 +0,0 @@ -public class InsecureLdapAuth { - /** LDAP authentication */ - public DirContext ldapAuth(String ldapUserName, String password) { - { - // BAD: LDAP authentication in cleartext - String ldapUrl = "ldap://ad.your-server.com:389"; - } - - { - // GOOD: LDAPS authentication over SSL - String ldapUrl = "ldaps://ad.your-server.com:636"; - } - - Hashtable<String, String> environment = new Hashtable<String, String>(); - environment.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory"); - environment.put(Context.PROVIDER_URL, ldapUrl); - environment.put(Context.REFERRAL, "follow"); - environment.put(Context.SECURITY_AUTHENTICATION, "simple"); - environment.put(Context.SECURITY_PRINCIPAL, ldapUserName); - environment.put(Context.SECURITY_CREDENTIALS, password); - DirContext dirContext = new InitialDirContext(environment); - return dirContext; - } -} diff --git a/java/ql/src/Security/CWE/CWE-522/InsecureLdapAuth.qhelp b/java/ql/src/Security/CWE/CWE-522/InsecureLdapAuth.qhelp index c729759a06e..9483e8d3705 100644 --- a/java/ql/src/Security/CWE/CWE-522/InsecureLdapAuth.qhelp +++ b/java/ql/src/Security/CWE/CWE-522/InsecureLdapAuth.qhelp @@ -2,16 +2,40 @@ <qhelp> <overview> - <p>When using the Java LDAP API to perform LDAPv3-style extended operations and controls, a context with connection properties including user credentials is started. Transmission of LDAP credentials in cleartext allows remote attackers to obtain sensitive information by sniffing the network.</p> + <p> + When using the Java LDAP API to perform LDAPv3-style extended operations + and controls, a context with connection properties including user + credentials is started. Transmission of LDAP credentials in cleartext + allows remote attackers to obtain sensitive information by sniffing the + network. + </p> </overview> <recommendation> - <p>Use LDAPS to send credentials through SSL or use SASL authentication.</p> + <p> + Use the <code>ldaps://</code> protocol to send credentials through SSL or + use SASL authentication. + </p> </recommendation> <example> - <p>The following example shows two ways of using LDAP authentication. In the 'BAD' case, the credentials are transmitted in cleartext. In the 'GOOD' case, the credentials are transmitted over SSL.</p> - <sample src="InsecureLdapAuth.java" /> + <p> + In the following (bad) example, a <code>ldap://</code> URL is used and + credentials will be sent in plaintext. + </p> + <sample src="LdapAuthUseLdap.java"/> + + <p> + In the following (good) example, a <code>ldaps://</code> URL is used so + credentials will be encrypted with SSL. + </p> + <sample src="LdapAuthUseLdaps.java"/> + + <p> + In the following (good) example, a <code>ldap://</code> URL is used, but + SASL authentication is enabled. + </p> + <sample src="LdapEnableSasl.java"/> </example> <references> diff --git a/java/ql/src/Security/CWE/CWE-522/LdapAuthUseLdap.java b/java/ql/src/Security/CWE/CWE-522/LdapAuthUseLdap.java new file mode 100644 index 00000000000..36826bf27b0 --- /dev/null +++ b/java/ql/src/Security/CWE/CWE-522/LdapAuthUseLdap.java @@ -0,0 +1,9 @@ +String ldapUrl = "ldap://ad.your-server.com:389"; +Hashtable<String, String> environment = new Hashtable<String, String>(); +environment.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory"); +environment.put(Context.PROVIDER_URL, ldapUrl); +environment.put(Context.REFERRAL, "follow"); +environment.put(Context.SECURITY_AUTHENTICATION, "simple"); +environment.put(Context.SECURITY_PRINCIPAL, ldapUserName); +environment.put(Context.SECURITY_CREDENTIALS, password); +DirContext dirContext = new InitialDirContext(environment); diff --git a/java/ql/src/Security/CWE/CWE-522/LdapAuthUseLdaps.java b/java/ql/src/Security/CWE/CWE-522/LdapAuthUseLdaps.java new file mode 100644 index 00000000000..e7d8bdefc60 --- /dev/null +++ b/java/ql/src/Security/CWE/CWE-522/LdapAuthUseLdaps.java @@ -0,0 +1,9 @@ +String ldapUrl = "ldaps://ad.your-server.com:636"; +Hashtable<String, String> environment = new Hashtable<String, String>(); +environment.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory"); +environment.put(Context.PROVIDER_URL, ldapUrl); +environment.put(Context.REFERRAL, "follow"); +environment.put(Context.SECURITY_AUTHENTICATION, "simple"); +environment.put(Context.SECURITY_PRINCIPAL, ldapUserName); +environment.put(Context.SECURITY_CREDENTIALS, password); +DirContext dirContext = new InitialDirContext(environment); diff --git a/java/ql/src/Security/CWE/CWE-522/LdapEnableSasl.java b/java/ql/src/Security/CWE/CWE-522/LdapEnableSasl.java new file mode 100644 index 00000000000..2e191c62918 --- /dev/null +++ b/java/ql/src/Security/CWE/CWE-522/LdapEnableSasl.java @@ -0,0 +1,9 @@ +String ldapUrl = "ldap://ad.your-server.com:389"; +Hashtable<String, String> environment = new Hashtable<String, String>(); +environment.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory"); +environment.put(Context.PROVIDER_URL, ldapUrl); +environment.put(Context.REFERRAL, "follow"); +environment.put(Context.SECURITY_AUTHENTICATION, "DIGEST-MD5 GSSAPI"); +environment.put(Context.SECURITY_PRINCIPAL, ldapUserName); +environment.put(Context.SECURITY_CREDENTIALS, password); +DirContext dirContext = new InitialDirContext(environment); From 658c54a18f2edf892b9fbcb549d9bdf517c9c4b8 Mon Sep 17 00:00:00 2001 From: Ed Minnix <egregius313@github.com> Date: Fri, 10 Mar 2023 15:05:07 -0500 Subject: [PATCH 523/631] Change names of configuration to fit new naming convention --- .../code/java/security/InsecureLdapAuthQuery.qll | 10 +++++----- java/ql/src/Security/CWE/CWE-522/InsecureLdapAuth.ql | 10 +++++----- .../security/CWE-522/InsecureLdapAuthTest.ql | 6 +++--- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/java/ql/lib/semmle/code/java/security/InsecureLdapAuthQuery.qll b/java/ql/lib/semmle/code/java/security/InsecureLdapAuthQuery.qll index b8acf539bed..548f3fafd0a 100644 --- a/java/ql/lib/semmle/code/java/security/InsecureLdapAuthQuery.qll +++ b/java/ql/lib/semmle/code/java/security/InsecureLdapAuthQuery.qll @@ -9,7 +9,7 @@ import semmle.code.java.security.InsecureLdapAuth /** * A taint-tracking configuration for `ldap://` URL in LDAP authentication. */ -private module InsecureUrlFlowConfig implements DataFlow::ConfigSig { +private module InsecureLdapUrlConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node src) { src.asExpr() instanceof InsecureLdapUrl } predicate isSink(DataFlow::Node sink) { @@ -29,12 +29,12 @@ private module InsecureUrlFlowConfig implements DataFlow::ConfigSig { } } -module InsecureUrlFlowConfiguration = TaintTracking::Make<InsecureUrlFlowConfig>; +module InsecureLdapUrlFlow = TaintTracking::Make<InsecureLdapUrlConfig>; /** * A taint-tracking configuration for `simple` basic-authentication in LDAP configuration. */ -private module BasicAuthFlowConfig implements DataFlow::ConfigSig { +private module BasicAuthConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node src) { exists(MethodAccess ma | isBasicAuthEnv(ma) and ma.getQualifier() = src.(PostUpdateNode).getPreUpdateNode().asExpr() @@ -49,7 +49,7 @@ private module BasicAuthFlowConfig implements DataFlow::ConfigSig { } } -module BasicAuthFlowConfiguration = DataFlow::Make<BasicAuthFlowConfig>; +module BasicAuthFlow = DataFlow::Make<BasicAuthConfig>; /** * A taint-tracking configuration for `ssl` configuration in LDAP authentication. @@ -69,4 +69,4 @@ private module RequiresSslConfig implements DataFlow::ConfigSig { } } -module RequiresSslConfiguration = DataFlow::Make<RequiresSslConfig>; +module RequiresSslFlow = DataFlow::Make<RequiresSslConfig>; diff --git a/java/ql/src/Security/CWE/CWE-522/InsecureLdapAuth.ql b/java/ql/src/Security/CWE/CWE-522/InsecureLdapAuth.ql index 1abfdd69fec..63502622284 100644 --- a/java/ql/src/Security/CWE/CWE-522/InsecureLdapAuth.ql +++ b/java/ql/src/Security/CWE/CWE-522/InsecureLdapAuth.ql @@ -14,12 +14,12 @@ import java import semmle.code.java.security.InsecureLdapAuthQuery -import InsecureUrlFlowConfiguration::PathGraph +import InsecureLdapUrlFlow::PathGraph -from InsecureUrlFlowConfiguration::PathNode source, InsecureUrlFlowConfiguration::PathNode sink +from InsecureLdapUrlFlow::PathNode source, InsecureLdapUrlFlow::PathNode sink where - InsecureUrlFlowConfiguration::hasFlowPath(source, sink) and - BasicAuthFlowConfiguration::hasFlowTo(sink.getNode()) and - not RequiresSslConfiguration::hasFlowTo(sink.getNode()) + InsecureLdapUrlFlow::hasFlowPath(source, sink) and + BasicAuthFlow::hasFlowTo(sink.getNode()) and + not RequiresSslFlow::hasFlowTo(sink.getNode()) select sink.getNode(), source, sink, "Insecure LDAP authentication from $@.", source.getNode(), "LDAP connection string" diff --git a/java/ql/test/query-tests/security/CWE-522/InsecureLdapAuthTest.ql b/java/ql/test/query-tests/security/CWE-522/InsecureLdapAuthTest.ql index 67660872c39..1d8bfbea58f 100644 --- a/java/ql/test/query-tests/security/CWE-522/InsecureLdapAuthTest.ql +++ b/java/ql/test/query-tests/security/CWE-522/InsecureLdapAuthTest.ql @@ -9,9 +9,9 @@ class InsecureLdapAuthenticationTest extends InlineExpectationsTest { override predicate hasActualResult(Location location, string element, string tag, string value) { tag = "hasInsecureLdapAuth" and - exists(DataFlow::Node sink | InsecureUrlFlowConfiguration::hasFlowTo(sink) | - BasicAuthFlowConfiguration::hasFlowTo(sink) and - not SslFlowConfiguration::hasFlowTo(sink) and + exists(DataFlow::Node sink | InsecureLdapUrlFlow::hasFlowTo(sink) | + BasicAuthFlow::hasFlowTo(sink) and + not RequiresSslFlow::hasFlowTo(sink) and sink.getLocation() = location and element = sink.toString() and value = "" From 151357d02d2d2451803ff41424907c03bf73b8f1 Mon Sep 17 00:00:00 2001 From: Edward Minnix III <egregius313@github.com> Date: Fri, 17 Mar 2023 10:25:46 -0400 Subject: [PATCH 524/631] Make classes/predicates not used outside of query private Co-authored-by: Tony Torralba <atorralba@users.noreply.github.com> --- .../lib/semmle/code/java/security/InsecureLdapAuth.qll | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/java/ql/lib/semmle/code/java/security/InsecureLdapAuth.qll b/java/ql/lib/semmle/code/java/security/InsecureLdapAuth.qll index 1c9cab6f24d..e90bfd4cf4f 100644 --- a/java/ql/lib/semmle/code/java/security/InsecureLdapAuth.qll +++ b/java/ql/lib/semmle/code/java/security/InsecureLdapAuth.qll @@ -1,13 +1,13 @@ /** Provides classes to reason about insecure LDAP authentication. */ import java -import semmle.code.java.frameworks.Networking -import semmle.code.java.frameworks.Jndi +private import semmle.code.java.frameworks.Networking +private import semmle.code.java.frameworks.Jndi /** * An insecure (non-SSL, non-private) LDAP URL string literal. */ -class InsecureLdapUrlLiteral extends StringLiteral { +private class InsecureLdapUrlLiteral extends StringLiteral { InsecureLdapUrlLiteral() { // Match connection strings with the LDAP protocol and without private IP addresses to reduce false positives. exists(string s | this.getValue() = s | @@ -18,7 +18,7 @@ class InsecureLdapUrlLiteral extends StringLiteral { } /** The class `java.util.Hashtable`. */ -class TypeHashtable extends Class { +private class TypeHashtable extends Class { TypeHashtable() { this.getSourceDeclaration().hasQualifiedName("java.util", "Hashtable") } } @@ -86,7 +86,7 @@ predicate hasFieldValueEnv(MethodAccess ma, string fieldValue, string envValue) * Holds if `ma` sets attribute name `fieldName` to `envValue` in some `Hashtable`. */ bindingset[fieldName, envValue] -predicate hasFieldNameEnv(MethodAccess ma, string fieldName, string envValue) { +private predicate hasFieldNameEnv(MethodAccess ma, string fieldName, string envValue) { // environment.put(Context.SECURITY_AUTHENTICATION, "simple") ma.getMethod().getDeclaringType().getAnAncestor() instanceof TypeHashtable and ma.getMethod().hasName(["put", "setProperty"]) and From 24d48591491ba845a6a3792c1392febd220a0b78 Mon Sep 17 00:00:00 2001 From: Edward Minnix III <egregius313@github.com> Date: Fri, 17 Mar 2023 10:26:32 -0400 Subject: [PATCH 525/631] Import changes Co-authored-by: Tony Torralba <atorralba@users.noreply.github.com> --- .../lib/semmle/code/java/security/InsecureLdapAuthQuery.qll | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/java/ql/lib/semmle/code/java/security/InsecureLdapAuthQuery.qll b/java/ql/lib/semmle/code/java/security/InsecureLdapAuthQuery.qll index 548f3fafd0a..dcc5529759d 100644 --- a/java/ql/lib/semmle/code/java/security/InsecureLdapAuthQuery.qll +++ b/java/ql/lib/semmle/code/java/security/InsecureLdapAuthQuery.qll @@ -1,9 +1,9 @@ /** Provides dataflow configurations to reason about insecure LDAP authentication. */ import java -import DataFlow import semmle.code.java.dataflow.DataFlow import semmle.code.java.dataflow.TaintTracking +import semmle.code.java.frameworks.Jndi import semmle.code.java.security.InsecureLdapAuth /** @@ -37,7 +37,7 @@ module InsecureLdapUrlFlow = TaintTracking::Make<InsecureLdapUrlConfig>; private module BasicAuthConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node src) { exists(MethodAccess ma | - isBasicAuthEnv(ma) and ma.getQualifier() = src.(PostUpdateNode).getPreUpdateNode().asExpr() + isBasicAuthEnv(ma) and ma.getQualifier() = src.(DataFlow::PostUpdateNode).getPreUpdateNode().asExpr() ) } @@ -57,7 +57,7 @@ module BasicAuthFlow = DataFlow::Make<BasicAuthConfig>; private module RequiresSslConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node src) { exists(MethodAccess ma | - isSslEnv(ma) and ma.getQualifier() = src.(PostUpdateNode).getPreUpdateNode().asExpr() + isSslEnv(ma) and ma.getQualifier() = src.(DataFlow::PostUpdateNode).getPreUpdateNode().asExpr() ) } From f28f1af5a4e0c856707220aa3d58a154cb322a74 Mon Sep 17 00:00:00 2001 From: Ed Minnix <egregius313@github.com> Date: Fri, 17 Mar 2023 11:36:12 -0400 Subject: [PATCH 526/631] Add `InsecureLdapUrlSink` --- .../code/java/security/InsecureLdapAuth.qll | 10 +++++++ .../java/security/InsecureLdapAuthQuery.qll | 27 +++++-------------- 2 files changed, 17 insertions(+), 20 deletions(-) diff --git a/java/ql/lib/semmle/code/java/security/InsecureLdapAuth.qll b/java/ql/lib/semmle/code/java/security/InsecureLdapAuth.qll index e90bfd4cf4f..42b56a11b67 100644 --- a/java/ql/lib/semmle/code/java/security/InsecureLdapAuth.qll +++ b/java/ql/lib/semmle/code/java/security/InsecureLdapAuth.qll @@ -1,6 +1,7 @@ /** Provides classes to reason about insecure LDAP authentication. */ import java +private import semmle.code.java.dataflow.DataFlow private import semmle.code.java.frameworks.Networking private import semmle.code.java.frameworks.Jndi @@ -113,3 +114,12 @@ predicate isSslEnv(MethodAccess ma) { hasFieldValueEnv(ma, "java.naming.security.protocol", "ssl") or hasFieldNameEnv(ma, "SECURITY_PROTOCOL", "ssl") } + +class InsecureLdapUrlSink extends DataFlow::Node { + InsecureLdapUrlSink() { + exists(ConstructorCall cc | + cc.getConstructedType().getAnAncestor() instanceof TypeDirContext and + this.asExpr() = cc.getArgument(0) + ) + } +} diff --git a/java/ql/lib/semmle/code/java/security/InsecureLdapAuthQuery.qll b/java/ql/lib/semmle/code/java/security/InsecureLdapAuthQuery.qll index dcc5529759d..150d9c72458 100644 --- a/java/ql/lib/semmle/code/java/security/InsecureLdapAuthQuery.qll +++ b/java/ql/lib/semmle/code/java/security/InsecureLdapAuthQuery.qll @@ -12,12 +12,7 @@ import semmle.code.java.security.InsecureLdapAuth private module InsecureLdapUrlConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node src) { src.asExpr() instanceof InsecureLdapUrl } - predicate isSink(DataFlow::Node sink) { - exists(ConstructorCall cc | - cc.getConstructedType().getAnAncestor() instanceof TypeDirContext and - sink.asExpr() = cc.getArgument(0) - ) - } + predicate isSink(DataFlow::Node sink) { sink instanceof InsecureLdapUrlSink } /** Method call of `env.put()`. */ predicate isAdditionalFlowStep(DataFlow::Node pred, DataFlow::Node succ) { @@ -37,16 +32,12 @@ module InsecureLdapUrlFlow = TaintTracking::Make<InsecureLdapUrlConfig>; private module BasicAuthConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node src) { exists(MethodAccess ma | - isBasicAuthEnv(ma) and ma.getQualifier() = src.(DataFlow::PostUpdateNode).getPreUpdateNode().asExpr() + isBasicAuthEnv(ma) and + ma.getQualifier() = src.(DataFlow::PostUpdateNode).getPreUpdateNode().asExpr() ) } - predicate isSink(DataFlow::Node sink) { - exists(ConstructorCall cc | - cc.getConstructedType().getAnAncestor() instanceof TypeDirContext and - sink.asExpr() = cc.getArgument(0) - ) - } + predicate isSink(DataFlow::Node sink) { sink instanceof InsecureLdapUrlSink } } module BasicAuthFlow = DataFlow::Make<BasicAuthConfig>; @@ -57,16 +48,12 @@ module BasicAuthFlow = DataFlow::Make<BasicAuthConfig>; private module RequiresSslConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node src) { exists(MethodAccess ma | - isSslEnv(ma) and ma.getQualifier() = src.(DataFlow::PostUpdateNode).getPreUpdateNode().asExpr() + isSslEnv(ma) and + ma.getQualifier() = src.(DataFlow::PostUpdateNode).getPreUpdateNode().asExpr() ) } - predicate isSink(DataFlow::Node sink) { - exists(ConstructorCall cc | - cc.getConstructedType().getAnAncestor() instanceof TypeDirContext and - sink.asExpr() = cc.getArgument(0) - ) - } + predicate isSink(DataFlow::Node sink) { sink instanceof InsecureLdapUrlSink } } module RequiresSslFlow = DataFlow::Make<RequiresSslConfig>; From 0eaf222b54dd3c184ad19207df52ac861578560d Mon Sep 17 00:00:00 2001 From: Ed Minnix <egregius313@github.com> Date: Fri, 17 Mar 2023 11:58:17 -0400 Subject: [PATCH 527/631] Move public classes/predicates to top of library file --- .../code/java/security/InsecureLdapAuth.qll | 137 +++++++++--------- 1 file changed, 70 insertions(+), 67 deletions(-) diff --git a/java/ql/lib/semmle/code/java/security/InsecureLdapAuth.qll b/java/ql/lib/semmle/code/java/security/InsecureLdapAuth.qll index 42b56a11b67..80007650c63 100644 --- a/java/ql/lib/semmle/code/java/security/InsecureLdapAuth.qll +++ b/java/ql/lib/semmle/code/java/security/InsecureLdapAuth.qll @@ -5,6 +5,75 @@ private import semmle.code.java.dataflow.DataFlow private import semmle.code.java.frameworks.Networking private import semmle.code.java.frameworks.Jndi +/** + * An expression that represents an insecure (non-SSL, non-private) LDAP URL. + */ +class InsecureLdapUrl extends Expr { + InsecureLdapUrl() { + this instanceof InsecureLdapUrlLiteral + or + // Concatentation of insecure protcol and non-private host: + // protocol + host + ... + exists(AddExpr e, CompileTimeConstantExpr protocol, Expr rest, Expr host | + e = this and + protocol = e.getLeftOperand() and + rest = e.getRightOperand() and + if rest instanceof AddExpr then host = rest.(AddExpr).getLeftOperand() else host = rest + | + protocol.getStringValue() = "ldap://" and + not exists(string hostString | hostString = getHostname(host) | + hostString.length() = 0 or // Empty host is loopback address + hostString instanceof PrivateHostName + ) + ) + } +} + +/** + * A sink representing the construction of a `DirContextEnvironment`. + */ +class InsecureLdapUrlSink extends DataFlow::Node { + InsecureLdapUrlSink() { + exists(ConstructorCall cc | + cc.getConstructedType().getAnAncestor() instanceof TypeDirContext and + this.asExpr() = cc.getArgument(0) + ) + } +} + +/** + * Holds if `ma` sets `java.naming.security.authentication` (also known as `Context.SECURITY_AUTHENTICATION`) to `simple` in some `Hashtable`. + */ +predicate isBasicAuthEnv(MethodAccess ma) { + hasFieldValueEnv(ma, "java.naming.security.authentication", "simple") or + hasFieldNameEnv(ma, "SECURITY_AUTHENTICATION", "simple") +} + +/** + * Holds if `ma` sets `java.naming.security.protocol` (also known as `Context.SECURITY_PROTOCOL`) to `ssl` in some `Hashtable`. + */ +predicate isSslEnv(MethodAccess ma) { + hasFieldValueEnv(ma, "java.naming.security.protocol", "ssl") or + hasFieldNameEnv(ma, "SECURITY_PROTOCOL", "ssl") +} + +/** + * Holds if `ma` writes the `java.naming.provider.url` (also known as `Context.PROVIDER_URL`) key of a `Hashtable`. + */ +predicate isProviderUrlSetter(MethodAccess ma) { + ma.getMethod().getDeclaringType().getAnAncestor() instanceof TypeHashtable and + ma.getMethod().hasName(["put", "setProperty"]) and + ( + ma.getArgument(0).(CompileTimeConstantExpr).getStringValue() = "java.naming.provider.url" + or + exists(Field f | + ma.getArgument(0) = f.getAnAccess() and + f.hasName("PROVIDER_URL") and + f.getDeclaringType() instanceof TypeNamingContext + ) + ) +} + /** * An insecure (non-SSL, non-private) LDAP URL string literal. */ @@ -30,52 +99,11 @@ private string getHostname(Expr expr) { expr.(VarAccess).getVariable().getAnAssignedValue().(CompileTimeConstantExpr).getStringValue() } -/** - * An expression that represents an insecure (non-SSL, non-private) LDAP URL. - */ -class InsecureLdapUrl extends Expr { - InsecureLdapUrl() { - this instanceof InsecureLdapUrlLiteral - or - // Concatentation of insecure protcol and non-private host: - // protocol + host + ... - exists(AddExpr e, CompileTimeConstantExpr protocol, Expr rest, Expr host | - e = this and - protocol = e.getLeftOperand() and - rest = e.getRightOperand() and - if rest instanceof AddExpr then host = rest.(AddExpr).getLeftOperand() else host = rest - | - protocol.getStringValue() = "ldap://" and - not exists(string hostString | hostString = getHostname(host) | - hostString.length() = 0 or // Empty host is loopback address - hostString instanceof PrivateHostName - ) - ) - } -} - -/** - * Holds if `ma` writes the `java.naming.provider.url` (also known as `Context.PROVIDER_URL`) key of a `Hashtable`. - */ -predicate isProviderUrlSetter(MethodAccess ma) { - ma.getMethod().getDeclaringType().getAnAncestor() instanceof TypeHashtable and - ma.getMethod().hasName(["put", "setProperty"]) and - ( - ma.getArgument(0).(CompileTimeConstantExpr).getStringValue() = "java.naming.provider.url" - or - exists(Field f | - ma.getArgument(0) = f.getAnAccess() and - f.hasName("PROVIDER_URL") and - f.getDeclaringType() instanceof TypeNamingContext - ) - ) -} - /** * Holds if `ma` sets `fieldValue` to `envValue` in some `Hashtable`. */ bindingset[fieldValue, envValue] -predicate hasFieldValueEnv(MethodAccess ma, string fieldValue, string envValue) { +private predicate hasFieldValueEnv(MethodAccess ma, string fieldValue, string envValue) { // environment.put("java.naming.security.authentication", "simple") ma.getMethod().getDeclaringType().getAnAncestor() instanceof TypeHashtable and ma.getMethod().hasName(["put", "setProperty"]) and @@ -98,28 +126,3 @@ private predicate hasFieldNameEnv(MethodAccess ma, string fieldName, string envV ) and ma.getArgument(1).(CompileTimeConstantExpr).getStringValue() = envValue } - -/** - * Holds if `ma` sets `java.naming.security.authentication` (also known as `Context.SECURITY_AUTHENTICATION`) to `simple` in some `Hashtable`. - */ -predicate isBasicAuthEnv(MethodAccess ma) { - hasFieldValueEnv(ma, "java.naming.security.authentication", "simple") or - hasFieldNameEnv(ma, "SECURITY_AUTHENTICATION", "simple") -} - -/** - * Holds if `ma` sets `java.naming.security.protocol` (also known as `Context.SECURITY_PROTOCOL`) to `ssl` in some `Hashtable`. - */ -predicate isSslEnv(MethodAccess ma) { - hasFieldValueEnv(ma, "java.naming.security.protocol", "ssl") or - hasFieldNameEnv(ma, "SECURITY_PROTOCOL", "ssl") -} - -class InsecureLdapUrlSink extends DataFlow::Node { - InsecureLdapUrlSink() { - exists(ConstructorCall cc | - cc.getConstructedType().getAnAncestor() instanceof TypeDirContext and - this.asExpr() = cc.getArgument(0) - ) - } -} From 43d79dc5b80b44d438a382b98bd1954d35a819ff Mon Sep 17 00:00:00 2001 From: Edward Minnix III <egregius313@github.com> Date: Fri, 24 Mar 2023 11:36:52 -0400 Subject: [PATCH 528/631] Apply docs review suggestions Co-authored-by: Sarita Iyer <66540150+saritai@users.noreply.github.com> --- java/ql/src/Security/CWE/CWE-522/InsecureLdapAuth.qhelp | 2 +- .../src/change-notes/2023-03-08-insecure-ldap-authentication.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/java/ql/src/Security/CWE/CWE-522/InsecureLdapAuth.qhelp b/java/ql/src/Security/CWE/CWE-522/InsecureLdapAuth.qhelp index 9483e8d3705..096fa99c809 100644 --- a/java/ql/src/Security/CWE/CWE-522/InsecureLdapAuth.qhelp +++ b/java/ql/src/Security/CWE/CWE-522/InsecureLdapAuth.qhelp @@ -33,7 +33,7 @@ <p> In the following (good) example, a <code>ldap://</code> URL is used, but - SASL authentication is enabled. + SASL authentication is enabled so that the credentials will be encrypted. </p> <sample src="LdapEnableSasl.java"/> </example> diff --git a/java/ql/src/change-notes/2023-03-08-insecure-ldap-authentication.md b/java/ql/src/change-notes/2023-03-08-insecure-ldap-authentication.md index 160d5639b22..8331274891c 100644 --- a/java/ql/src/change-notes/2023-03-08-insecure-ldap-authentication.md +++ b/java/ql/src/change-notes/2023-03-08-insecure-ldap-authentication.md @@ -1,4 +1,4 @@ --- category: newQuery --- -* The query `java/insecure-ldap-auth` has been promoted from experimental to the main query pack. This query was originally [submitted as an experimental query by @luchua-bc](https://github.com/github/codeql/pull/4854) \ No newline at end of file +* The query `java/insecure-ldap-auth` has been promoted from experimental to the main query pack. This query detects transmission of cleartext credentials in LDAP authentication. Insecure LDAP authentication causes sensitive information to be vulnerable to remote attackers. This query was originally [submitted as an experimental query by @luchua-bc](https://github.com/github/codeql/pull/4854) \ No newline at end of file From 106e5e714506be5d1c85c6272ac9bae542fb596d Mon Sep 17 00:00:00 2001 From: Edward Minnix III <egregius313@github.com> Date: Fri, 24 Mar 2023 12:40:10 -0400 Subject: [PATCH 529/631] Docs review suggestion Co-authored-by: Sarita Iyer <66540150+saritai@users.noreply.github.com> --- java/ql/src/Security/CWE/CWE-522/InsecureLdapAuth.ql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/ql/src/Security/CWE/CWE-522/InsecureLdapAuth.ql b/java/ql/src/Security/CWE/CWE-522/InsecureLdapAuth.ql index 63502622284..01c16ded3dd 100644 --- a/java/ql/src/Security/CWE/CWE-522/InsecureLdapAuth.ql +++ b/java/ql/src/Security/CWE/CWE-522/InsecureLdapAuth.ql @@ -1,6 +1,6 @@ /** * @name Insecure LDAP authentication - * @description LDAP authentication with credentials sent in cleartext. + * @description LDAP authentication with credentials sent in cleartext makes sensitive information vulnerable to remote attackers * @kind path-problem * @problem.severity warning * @security-severity 8.8 From 9bfb13b942a8d51b44b9df3a81219e7cb44e4f45 Mon Sep 17 00:00:00 2001 From: Ed Minnix <egregius313@github.com> Date: Mon, 27 Mar 2023 12:26:18 -0400 Subject: [PATCH 530/631] Update to the `Global`/`flow*` api --- .../lib/semmle/code/java/security/InsecureLdapAuthQuery.qll | 6 +++--- java/ql/src/Security/CWE/CWE-522/InsecureLdapAuth.ql | 6 +++--- .../query-tests/security/CWE-522/InsecureLdapAuthTest.ql | 6 +++--- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/java/ql/lib/semmle/code/java/security/InsecureLdapAuthQuery.qll b/java/ql/lib/semmle/code/java/security/InsecureLdapAuthQuery.qll index 150d9c72458..4d4546c7f8a 100644 --- a/java/ql/lib/semmle/code/java/security/InsecureLdapAuthQuery.qll +++ b/java/ql/lib/semmle/code/java/security/InsecureLdapAuthQuery.qll @@ -24,7 +24,7 @@ private module InsecureLdapUrlConfig implements DataFlow::ConfigSig { } } -module InsecureLdapUrlFlow = TaintTracking::Make<InsecureLdapUrlConfig>; +module InsecureLdapUrlFlow = TaintTracking::Global<InsecureLdapUrlConfig>; /** * A taint-tracking configuration for `simple` basic-authentication in LDAP configuration. @@ -40,7 +40,7 @@ private module BasicAuthConfig implements DataFlow::ConfigSig { predicate isSink(DataFlow::Node sink) { sink instanceof InsecureLdapUrlSink } } -module BasicAuthFlow = DataFlow::Make<BasicAuthConfig>; +module BasicAuthFlow = DataFlow::Global<BasicAuthConfig>; /** * A taint-tracking configuration for `ssl` configuration in LDAP authentication. @@ -56,4 +56,4 @@ private module RequiresSslConfig implements DataFlow::ConfigSig { predicate isSink(DataFlow::Node sink) { sink instanceof InsecureLdapUrlSink } } -module RequiresSslFlow = DataFlow::Make<RequiresSslConfig>; +module RequiresSslFlow = DataFlow::Global<RequiresSslConfig>; diff --git a/java/ql/src/Security/CWE/CWE-522/InsecureLdapAuth.ql b/java/ql/src/Security/CWE/CWE-522/InsecureLdapAuth.ql index 01c16ded3dd..dabd0d2c645 100644 --- a/java/ql/src/Security/CWE/CWE-522/InsecureLdapAuth.ql +++ b/java/ql/src/Security/CWE/CWE-522/InsecureLdapAuth.ql @@ -18,8 +18,8 @@ import InsecureLdapUrlFlow::PathGraph from InsecureLdapUrlFlow::PathNode source, InsecureLdapUrlFlow::PathNode sink where - InsecureLdapUrlFlow::hasFlowPath(source, sink) and - BasicAuthFlow::hasFlowTo(sink.getNode()) and - not RequiresSslFlow::hasFlowTo(sink.getNode()) + InsecureLdapUrlFlow::flowPath(source, sink) and + BasicAuthFlow::flowTo(sink.getNode()) and + not RequiresSslFlow::flowTo(sink.getNode()) select sink.getNode(), source, sink, "Insecure LDAP authentication from $@.", source.getNode(), "LDAP connection string" diff --git a/java/ql/test/query-tests/security/CWE-522/InsecureLdapAuthTest.ql b/java/ql/test/query-tests/security/CWE-522/InsecureLdapAuthTest.ql index 1d8bfbea58f..4ae89d21313 100644 --- a/java/ql/test/query-tests/security/CWE-522/InsecureLdapAuthTest.ql +++ b/java/ql/test/query-tests/security/CWE-522/InsecureLdapAuthTest.ql @@ -9,9 +9,9 @@ class InsecureLdapAuthenticationTest extends InlineExpectationsTest { override predicate hasActualResult(Location location, string element, string tag, string value) { tag = "hasInsecureLdapAuth" and - exists(DataFlow::Node sink | InsecureLdapUrlFlow::hasFlowTo(sink) | - BasicAuthFlow::hasFlowTo(sink) and - not RequiresSslFlow::hasFlowTo(sink) and + exists(DataFlow::Node sink | InsecureLdapUrlFlow::flowTo(sink) | + BasicAuthFlow::flowTo(sink) and + not RequiresSslFlow::flowTo(sink) and sink.getLocation() = location and element = sink.toString() and value = "" From 3d033fd72768b067dd56e8386806e0ff9372c593 Mon Sep 17 00:00:00 2001 From: Ed Minnix <egregius313@github.com> Date: Mon, 27 Mar 2023 13:06:31 -0400 Subject: [PATCH 531/631] Fix SqlConcatenated --- java/ql/src/Security/CWE/CWE-089/SqlConcatenated.ql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/ql/src/Security/CWE/CWE-089/SqlConcatenated.ql b/java/ql/src/Security/CWE/CWE-089/SqlConcatenated.ql index 87f478de979..db12b6e7fbb 100644 --- a/java/ql/src/Security/CWE/CWE-089/SqlConcatenated.ql +++ b/java/ql/src/Security/CWE/CWE-089/SqlConcatenated.ql @@ -48,6 +48,6 @@ where UncontrolledStringBuilderSourceFlow::flow(DataFlow::exprNode(sbv.getToStringCall()), query) ) ) and - not queryTaintedBy(query, _, _) + not queryIsTaintedBy(query, _, _) select query, "Query built by concatenation with $@, which may be untrusted.", uncontrolled, "this expression" From 9e8867aa9667902c537b50f016a1ef549950ef46 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nora=20Dimitrijevi=C4=87?= <d10c@users.noreply.github.com> Date: Wed, 8 Feb 2023 16:01:25 +0100 Subject: [PATCH 532/631] Swift: update enum dataflow test with more cases --- .../dataflow/dataflow/DataFlow.expected | 140 +++++------ .../dataflow/dataflow/LocalFlow.expected | 238 ++++++++++-------- .../dataflow/dataflow/test.swift | 109 +++++--- 3 files changed, 282 insertions(+), 205 deletions(-) diff --git a/swift/ql/test/library-tests/dataflow/dataflow/DataFlow.expected b/swift/ql/test/library-tests/dataflow/dataflow/DataFlow.expected index b7d32099952..321cd1f6c52 100644 --- a/swift/ql/test/library-tests/dataflow/dataflow/DataFlow.expected +++ b/swift/ql/test/library-tests/dataflow/dataflow/DataFlow.expected @@ -103,8 +103,8 @@ 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:259:12:259:19 | call to source() : | test.swift:439:13:439:28 | call to optionalSource() : | -| test.swift:259:12:259:19 | call to source() : | test.swift:466:13:466:28 | call to optionalSource() : | +| test.swift:259:12:259:19 | call to source() : | test.swift:486:13:486:28 | call to optionalSource() : | +| test.swift:259:12:259:19 | call to source() : | test.swift:513:13:513:28 | call to optionalSource() : | | 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 | ...? : | @@ -145,33 +145,33 @@ edges | test.swift:357:15:357:15 | t1 [Tuple element at index 1] : | test.swift:357:15:357:18 | .1 | | test.swift:360:15:360:15 | t2 [Tuple element at index 0] : | test.swift:360:15:360:18 | .0 | | test.swift:361:15:361:15 | t2 [Tuple element at index 1] : | test.swift:361:15:361:18 | .1 | -| test.swift:439:13:439:28 | call to optionalSource() : | test.swift:442:19:442:19 | a | -| test.swift:462:9:462:9 | self [x] : | file://:0:0:0:0 | self [x] : | -| test.swift:462:9:462:9 | value : | file://:0:0:0:0 | value : | -| test.swift:466:13:466:28 | call to optionalSource() : | test.swift:468:12:468:12 | x : | -| test.swift:468:5:468:5 | [post] cx [x] : | test.swift:472:20:472:20 | cx [x] : | -| test.swift:468:12:468:12 | x : | test.swift:462:9:462:9 | value : | -| test.swift:468:12:468:12 | x : | test.swift:468:5:468:5 | [post] cx [x] : | -| test.swift:472:20:472:20 | cx [x] : | test.swift:462:9:462:9 | self [x] : | -| test.swift:472:20:472:20 | cx [x] : | test.swift:472:20:472:23 | .x : | -| test.swift:472:20:472:23 | .x : | test.swift:473:15:473:15 | z1 | -| test.swift:479:14:479:21 | call to source() : | test.swift:479:13:479:21 | call to +(_:) | -| test.swift:488:9:488:9 | self [str] : | file://:0:0:0:0 | self [str] : | -| test.swift:489:10:489:13 | s : | test.swift:490:13:490:13 | s : | -| test.swift:490:7:490:7 | [post] self [str] : | test.swift:489:5:491:5 | self[return] [str] : | -| test.swift:490:13:490:13 | s : | test.swift:490:7:490:7 | [post] self [str] : | -| test.swift:495:17:498:5 | self[return] [str] : | test.swift:503:13:503:41 | call to Self.init(contentsOfFile:) [str] : | -| test.swift:496:7:496:7 | [post] self [str] : | test.swift:495:17:498:5 | self[return] [str] : | -| test.swift:496:7:496:7 | [post] self [str] : | test.swift:497:17:497:17 | self [str] : | -| test.swift:496:20:496:28 | call to source3() : | test.swift:489:10:489:13 | s : | -| test.swift:496:20:496:28 | call to source3() : | test.swift:496:7:496:7 | [post] self [str] : | -| test.swift:497:17:497:17 | self [str] : | test.swift:497:17:497:17 | .str | -| test.swift:502:13:502:33 | call to MyClass.init(s:) [str] : | test.swift:488:9:488:9 | self [str] : | -| test.swift:502:13:502:33 | call to MyClass.init(s:) [str] : | test.swift:502:13:502:35 | .str | -| test.swift:502:24:502:32 | call to source3() : | test.swift:489:10:489:13 | s : | -| test.swift:502:24:502:32 | call to source3() : | test.swift:502:13:502:33 | call to MyClass.init(s:) [str] : | -| test.swift:503:13:503:41 | call to Self.init(contentsOfFile:) [str] : | test.swift:488:9:488:9 | self [str] : | -| test.swift:503:13:503:41 | call to Self.init(contentsOfFile:) [str] : | test.swift:503:13:503:43 | .str | +| test.swift:486:13:486:28 | call to optionalSource() : | test.swift:489:19:489:19 | a | +| test.swift:509:9:509:9 | self [x] : | file://:0:0:0:0 | self [x] : | +| test.swift:509:9:509:9 | value : | file://:0:0:0:0 | value : | +| test.swift:513:13:513:28 | call to optionalSource() : | test.swift:515:12:515:12 | x : | +| test.swift:515:5:515:5 | [post] cx [x] : | test.swift:519:20:519:20 | cx [x] : | +| test.swift:515:12:515:12 | x : | test.swift:509:9:509:9 | value : | +| test.swift:515:12:515:12 | x : | test.swift:515:5:515:5 | [post] cx [x] : | +| test.swift:519:20:519:20 | cx [x] : | test.swift:509:9:509:9 | self [x] : | +| test.swift:519:20:519:20 | cx [x] : | test.swift:519:20:519:23 | .x : | +| test.swift:519:20:519:23 | .x : | test.swift:520:15:520:15 | z1 | +| test.swift:526:14:526:21 | call to source() : | test.swift:526:13:526:21 | call to +(_:) | +| test.swift:535:9:535:9 | self [str] : | file://:0:0:0:0 | self [str] : | +| test.swift:536:10:536:13 | s : | test.swift:537:13:537:13 | s : | +| test.swift:537:7:537:7 | [post] self [str] : | test.swift:536:5:538:5 | self[return] [str] : | +| test.swift:537:13:537:13 | s : | test.swift:537:7:537:7 | [post] self [str] : | +| test.swift:542:17:545:5 | self[return] [str] : | test.swift:550:13:550:41 | call to Self.init(contentsOfFile:) [str] : | +| test.swift:543:7:543:7 | [post] self [str] : | test.swift:542:17:545:5 | self[return] [str] : | +| test.swift:543:7:543:7 | [post] self [str] : | test.swift:544:17:544:17 | self [str] : | +| test.swift:543:20:543:28 | call to source3() : | test.swift:536:10:536:13 | s : | +| test.swift:543:20:543:28 | call to source3() : | test.swift:543:7:543:7 | [post] self [str] : | +| test.swift:544:17:544:17 | self [str] : | test.swift:544:17:544:17 | .str | +| test.swift:549:13:549:33 | call to MyClass.init(s:) [str] : | test.swift:535:9:535:9 | self [str] : | +| test.swift:549:13:549:33 | call to MyClass.init(s:) [str] : | test.swift:549:13:549:35 | .str | +| test.swift:549:24:549:32 | call to source3() : | test.swift:536:10:536:13 | s : | +| test.swift:549:24:549:32 | call to source3() : | test.swift:549:13:549:33 | call to MyClass.init(s:) [str] : | +| test.swift:550:13:550:41 | call to Self.init(contentsOfFile:) [str] : | test.swift:535:9:535:9 | self [str] : | +| test.swift:550:13:550:41 | call to Self.init(contentsOfFile:) [str] : | test.swift:550:13:550:43 | .str | nodes | file://:0:0:0:0 | .a [x] : | semmle.label | .a [x] : | | file://:0:0:0:0 | .str : | semmle.label | .str : | @@ -334,34 +334,34 @@ nodes | test.swift:360:15:360:18 | .0 | semmle.label | .0 | | test.swift:361:15:361:15 | t2 [Tuple element at index 1] : | semmle.label | t2 [Tuple element at index 1] : | | test.swift:361:15:361:18 | .1 | semmle.label | .1 | -| test.swift:439:13:439:28 | call to optionalSource() : | semmle.label | call to optionalSource() : | -| test.swift:442:19:442:19 | a | semmle.label | a | -| test.swift:462:9:462:9 | self [x] : | semmle.label | self [x] : | -| test.swift:462:9:462:9 | value : | semmle.label | value : | -| test.swift:466:13:466:28 | call to optionalSource() : | semmle.label | call to optionalSource() : | -| test.swift:468:5:468:5 | [post] cx [x] : | semmle.label | [post] cx [x] : | -| test.swift:468:12:468:12 | x : | semmle.label | x : | -| test.swift:472:20:472:20 | cx [x] : | semmle.label | cx [x] : | -| test.swift:472:20:472:23 | .x : | semmle.label | .x : | -| test.swift:473:15:473:15 | z1 | semmle.label | z1 | -| test.swift:479:13:479:21 | call to +(_:) | semmle.label | call to +(_:) | -| test.swift:479:14:479:21 | call to source() : | semmle.label | call to source() : | -| test.swift:480:14:480:21 | call to source() | semmle.label | call to source() | -| test.swift:488:9:488:9 | self [str] : | semmle.label | self [str] : | -| test.swift:489:5:491:5 | self[return] [str] : | semmle.label | self[return] [str] : | -| test.swift:489:10:489:13 | s : | semmle.label | s : | -| test.swift:490:7:490:7 | [post] self [str] : | semmle.label | [post] self [str] : | -| test.swift:490:13:490:13 | s : | semmle.label | s : | -| test.swift:495:17:498:5 | self[return] [str] : | semmle.label | self[return] [str] : | -| test.swift:496:7:496:7 | [post] self [str] : | semmle.label | [post] self [str] : | -| test.swift:496:20:496:28 | call to source3() : | semmle.label | call to source3() : | -| test.swift:497:17:497:17 | .str | semmle.label | .str | -| test.swift:497:17:497:17 | self [str] : | semmle.label | self [str] : | -| test.swift:502:13:502:33 | call to MyClass.init(s:) [str] : | semmle.label | call to MyClass.init(s:) [str] : | -| test.swift:502:13:502:35 | .str | semmle.label | .str | -| test.swift:502:24:502:32 | call to source3() : | semmle.label | call to source3() : | -| test.swift:503:13:503:41 | call to Self.init(contentsOfFile:) [str] : | semmle.label | call to Self.init(contentsOfFile:) [str] : | -| test.swift:503:13:503:43 | .str | semmle.label | .str | +| test.swift:486:13:486:28 | call to optionalSource() : | semmle.label | call to optionalSource() : | +| test.swift:489:19:489:19 | a | semmle.label | a | +| test.swift:509:9:509:9 | self [x] : | semmle.label | self [x] : | +| test.swift:509:9:509:9 | value : | semmle.label | value : | +| test.swift:513:13:513:28 | call to optionalSource() : | semmle.label | call to optionalSource() : | +| test.swift:515:5:515:5 | [post] cx [x] : | semmle.label | [post] cx [x] : | +| test.swift:515:12:515:12 | x : | semmle.label | x : | +| test.swift:519:20:519:20 | cx [x] : | semmle.label | cx [x] : | +| test.swift:519:20:519:23 | .x : | semmle.label | .x : | +| test.swift:520:15:520:15 | z1 | semmle.label | z1 | +| test.swift:526:13:526:21 | call to +(_:) | semmle.label | call to +(_:) | +| test.swift:526:14:526:21 | call to source() : | semmle.label | call to source() : | +| test.swift:527:14:527:21 | call to source() | semmle.label | call to source() | +| test.swift:535:9:535:9 | self [str] : | semmle.label | self [str] : | +| test.swift:536:5:538:5 | self[return] [str] : | semmle.label | self[return] [str] : | +| test.swift:536:10:536:13 | s : | semmle.label | s : | +| test.swift:537:7:537:7 | [post] self [str] : | semmle.label | [post] self [str] : | +| test.swift:537:13:537:13 | s : | semmle.label | s : | +| test.swift:542:17:545:5 | self[return] [str] : | semmle.label | self[return] [str] : | +| test.swift:543:7:543:7 | [post] self [str] : | semmle.label | [post] self [str] : | +| test.swift:543:20:543:28 | call to source3() : | semmle.label | call to source3() : | +| test.swift:544:17:544:17 | .str | semmle.label | .str | +| test.swift:544:17:544:17 | self [str] : | semmle.label | self [str] : | +| test.swift:549:13:549:33 | call to MyClass.init(s:) [str] : | semmle.label | call to MyClass.init(s:) [str] : | +| test.swift:549:13:549:35 | .str | semmle.label | .str | +| test.swift:549:24:549:32 | call to source3() : | semmle.label | call to source3() : | +| test.swift:550:13:550:41 | call to Self.init(contentsOfFile:) [str] : | semmle.label | call to Self.init(contentsOfFile:) [str] : | +| test.swift:550:13:550:43 | .str | semmle.label | .str | 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 ... : | @@ -392,12 +392,12 @@ subpaths | 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() : | | test.swift:291:16:291:17 | ...? : | file://:0:0:0:0 | [summary param] this in signum() : | file://:0:0:0:0 | [summary] to write: return (return) in signum() : | test.swift:291:16:291:26 | call to signum() : | | test.swift:303:15:303: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:303:15:303:25 | call to signum() | -| test.swift:468:12:468:12 | x : | test.swift:462:9:462:9 | value : | file://:0:0:0:0 | [post] self [x] : | test.swift:468:5:468:5 | [post] cx [x] : | -| test.swift:472:20:472:20 | cx [x] : | test.swift:462:9:462:9 | self [x] : | file://:0:0:0:0 | .x : | test.swift:472:20:472:23 | .x : | -| test.swift:496:20:496:28 | call to source3() : | test.swift:489:10:489:13 | s : | test.swift:490:7:490:7 | [post] self [str] : | test.swift:496:7:496:7 | [post] self [str] : | -| test.swift:502:13:502:33 | call to MyClass.init(s:) [str] : | test.swift:488:9:488:9 | self [str] : | file://:0:0:0:0 | .str : | test.swift:502:13:502:35 | .str | -| test.swift:502:24:502:32 | call to source3() : | test.swift:489:10:489:13 | s : | test.swift:489:5:491:5 | self[return] [str] : | test.swift:502:13:502:33 | call to MyClass.init(s:) [str] : | -| test.swift:503:13:503:41 | call to Self.init(contentsOfFile:) [str] : | test.swift:488:9:488:9 | self [str] : | file://:0:0:0:0 | .str : | test.swift:503:13:503:43 | .str | +| test.swift:515:12:515:12 | x : | test.swift:509:9:509:9 | value : | file://:0:0:0:0 | [post] self [x] : | test.swift:515:5:515:5 | [post] cx [x] : | +| test.swift:519:20:519:20 | cx [x] : | test.swift:509:9:509:9 | self [x] : | file://:0:0:0:0 | .x : | test.swift:519:20:519:23 | .x : | +| test.swift:543:20:543:28 | call to source3() : | test.swift:536:10:536:13 | s : | test.swift:537:7:537:7 | [post] self [str] : | test.swift:543:7:543:7 | [post] self [str] : | +| test.swift:549:13:549:33 | call to MyClass.init(s:) [str] : | test.swift:535:9:535:9 | self [str] : | file://:0:0:0:0 | .str : | test.swift:549:13:549:35 | .str | +| test.swift:549:24:549:32 | call to source3() : | test.swift:536:10:536:13 | s : | test.swift:536:5:538:5 | self[return] [str] : | test.swift:549:13:549:33 | call to MyClass.init(s:) [str] : | +| test.swift:550:13:550:41 | call to Self.init(contentsOfFile:) [str] : | test.swift:535:9:535:9 | self [str] : | file://:0:0:0:0 | .str : | test.swift:550:13:550:43 | .str | #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 | @@ -448,10 +448,10 @@ subpaths | test.swift:357:15:357:18 | .1 | test.swift:351:31:351:38 | call to source() : | test.swift:357:15:357:18 | .1 | result | | test.swift:360:15:360:18 | .0 | test.swift:351:18:351:25 | call to source() : | test.swift:360:15:360:18 | .0 | result | | test.swift:361:15:361:18 | .1 | test.swift:351:31:351:38 | call to source() : | test.swift:361:15:361:18 | .1 | result | -| test.swift:442:19:442:19 | a | test.swift:259:12:259:19 | call to source() : | test.swift:442:19:442:19 | a | result | -| test.swift:473:15:473:15 | z1 | test.swift:259:12:259:19 | call to source() : | test.swift:473:15:473:15 | z1 | result | -| test.swift:479:13:479:21 | call to +(_:) | test.swift:479:14:479:21 | call to source() : | test.swift:479:13:479:21 | call to +(_:) | result | -| test.swift:480:14:480:21 | call to source() | test.swift:480:14:480:21 | call to source() | test.swift:480:14:480:21 | call to source() | result | -| test.swift:497:17:497:17 | .str | test.swift:496:20:496:28 | call to source3() : | test.swift:497:17:497:17 | .str | result | -| test.swift:502:13:502:35 | .str | test.swift:502:24:502:32 | call to source3() : | test.swift:502:13:502:35 | .str | result | -| test.swift:503:13:503:43 | .str | test.swift:496:20:496:28 | call to source3() : | test.swift:503:13:503:43 | .str | result | +| test.swift:489:19:489:19 | a | test.swift:259:12:259:19 | call to source() : | test.swift:489:19:489:19 | a | result | +| test.swift:520:15:520:15 | z1 | test.swift:259:12:259:19 | call to source() : | test.swift:520:15:520:15 | z1 | result | +| test.swift:526:13:526:21 | call to +(_:) | test.swift:526:14:526:21 | call to source() : | test.swift:526:13:526:21 | call to +(_:) | result | +| test.swift:527:14:527:21 | call to source() | test.swift:527:14:527:21 | call to source() | test.swift:527:14:527:21 | call to source() | result | +| test.swift:544:17:544:17 | .str | test.swift:543:20:543:28 | call to source3() : | test.swift:544:17:544:17 | .str | result | +| test.swift:549:13:549:35 | .str | test.swift:549:24:549:32 | call to source3() : | test.swift:549:13:549:35 | .str | result | +| test.swift:550:13:550:43 | .str | test.swift:543:20:543:28 | call to source3() : | test.swift:550:13:550:43 | .str | result | diff --git a/swift/ql/test/library-tests/dataflow/dataflow/LocalFlow.expected b/swift/ql/test/library-tests/dataflow/dataflow/LocalFlow.expected index 647bb37f2e5..74b4164e4e7 100644 --- a/swift/ql/test/library-tests/dataflow/dataflow/LocalFlow.expected +++ b/swift/ql/test/library-tests/dataflow/dataflow/LocalFlow.expected @@ -316,107 +316,137 @@ | test.swift:360:15:360:15 | t2 | test.swift:361:15:361:15 | t2 | | test.swift:361:15:361:15 | [post] t2 | test.swift:362:15:362:15 | t2 | | test.swift:361:15:361:15 | t2 | test.swift:362:15:362:15 | t2 | -| test.swift:375:9:375:13 | SSA def(a) | test.swift:377:12:377:12 | a | -| test.swift:375:22:375:23 | .myNone | test.swift:375:9:375:13 | SSA def(a) | -| test.swift:377:12:377:12 | a | test.swift:387:32:387:32 | a | -| test.swift:380:10:380:25 | SSA def(a) | test.swift:381:19:381:19 | a | -| test.swift:382:10:382:30 | SSA def(a) | test.swift:383:19:383:19 | a | -| test.swift:382:10:382:30 | SSA def(b) | test.swift:384:19:384:19 | b | -| test.swift:387:13:387:28 | SSA def(x) | test.swift:388:19:388:19 | x | -| test.swift:387:32:387:32 | a | test.swift:387:13:387:28 | SSA def(x) | -| test.swift:387:32:387:32 | a | test.swift:390:37:390:37 | a | -| test.swift:390:13:390:33 | SSA def(x) | test.swift:391:19:391:19 | x | -| test.swift:390:13:390:33 | SSA def(y) | test.swift:392:19:392:19 | y | -| test.swift:390:37:390:37 | a | test.swift:407:32:407:32 | a | -| test.swift:395:9:395:13 | SSA def(b) | test.swift:397:12:397:12 | b | -| test.swift:395:22:395:40 | call to ... | test.swift:395:9:395:13 | SSA def(b) | -| test.swift:400:10:400:25 | SSA def(a) | test.swift:401:19:401:19 | a | -| test.swift:402:10:402:30 | SSA def(a) | test.swift:403:19:403:19 | a | -| test.swift:402:10:402:30 | SSA def(b) | test.swift:404:19:404:19 | b | -| test.swift:407:13:407:28 | SSA def(x) | test.swift:408:19:408:19 | x | -| test.swift:407:32:407:32 | a | test.swift:407:13:407:28 | SSA def(x) | -| test.swift:407:32:407:32 | a | test.swift:410:37:410:37 | a | -| test.swift:410:13:410:33 | SSA def(x) | test.swift:411:19:411:19 | x | -| test.swift:410:13:410:33 | SSA def(y) | test.swift:412:19:412:19 | y | -| test.swift:410:37:410:37 | a | test.swift:427:32:427:32 | a | -| test.swift:415:9:415:9 | SSA def(c) | test.swift:417:12:417:12 | c | -| test.swift:415:13:415:38 | call to ... | test.swift:415:9:415:9 | SSA def(c) | -| test.swift:420:10:420:25 | SSA def(a) | test.swift:421:19:421:19 | a | -| test.swift:422:10:422:30 | SSA def(a) | test.swift:423:19:423:19 | a | -| test.swift:422:10:422:30 | SSA def(b) | test.swift:424:19:424:19 | b | -| test.swift:427:13:427:28 | SSA def(x) | test.swift:428:19:428:19 | x | -| test.swift:427:32:427:32 | a | test.swift:427:13:427:28 | SSA def(x) | -| test.swift:427:32:427:32 | a | test.swift:430:37:430:37 | a | -| test.swift:430:13:430:33 | SSA def(x) | test.swift:431:19:431:19 | x | -| test.swift:430:13:430:33 | SSA def(y) | test.swift:432:19:432:19 | y | -| test.swift:438:21:438:27 | SSA def(y) | test.swift:441:27:441:27 | y | -| test.swift:438:21:438:27 | SSA def(y) | test.swift:446:22:446:22 | y | -| test.swift:438:21:438:27 | y | test.swift:438:21:438:27 | SSA def(y) | -| test.swift:439:9:439:9 | SSA def(x) | test.swift:441:16:441:16 | x | -| test.swift:439:13:439:28 | call to optionalSource() | test.swift:439:9:439:9 | SSA def(x) | -| test.swift:441:8:441:12 | SSA def(a) | test.swift:442:19:442:19 | a | -| test.swift:441:16:441:16 | x | test.swift:441:8:441:12 | SSA def(a) | -| test.swift:441:16:441:16 | x | test.swift:446:19:446:19 | x | -| test.swift:441:19:441:23 | SSA def(b) | test.swift:443:19:443:19 | b | -| test.swift:441:27:441:27 | y | test.swift:441:19:441:23 | SSA def(b) | -| test.swift:441:27:441:27 | y | test.swift:446:22:446:22 | y | -| test.swift:446:9:446:9 | SSA def(tuple1) | test.swift:447:12:447:12 | tuple1 | -| test.swift:446:18:446:23 | (...) | test.swift:446:9:446:9 | SSA def(tuple1) | -| test.swift:448:10:448:37 | SSA def(a) | test.swift:449:19:449:19 | a | -| test.swift:448:10:448:37 | SSA def(b) | test.swift:450:19:450:19 | b | -| test.swift:455:8:455:17 | SSA def(x) | test.swift:456:19:456:19 | x | -| test.swift:455:8:455:17 | SSA def(y) | test.swift:457:19:457:19 | y | -| test.swift:461:7:461:7 | SSA def(self) | test.swift:461:7:461:7 | self[return] | -| test.swift:461:7:461:7 | SSA def(self) | test.swift:461:7:461:7 | self[return] | -| test.swift:461:7:461:7 | self | test.swift:461:7:461:7 | SSA def(self) | -| test.swift:461:7:461:7 | self | test.swift:461:7:461:7 | SSA def(self) | -| test.swift:462:9:462:9 | self | test.swift:462:9:462:9 | SSA def(self) | -| test.swift:462:9:462:9 | self | test.swift:462:9:462:9 | SSA def(self) | -| test.swift:462:9:462:9 | self | test.swift:462:9:462:9 | SSA def(self) | -| test.swift:462:9:462:9 | value | test.swift:462:9:462:9 | SSA def(value) | -| test.swift:465:33:465:39 | SSA def(y) | test.swift:470:12:470:12 | y | -| test.swift:465:33:465:39 | y | test.swift:465:33:465:39 | SSA def(y) | -| test.swift:466:9:466:9 | SSA def(x) | test.swift:468:12:468:12 | x | -| test.swift:466:13:466:28 | call to optionalSource() | test.swift:466:9:466:9 | SSA def(x) | -| test.swift:467:9:467:9 | SSA def(cx) | test.swift:468:5:468:5 | cx | -| test.swift:467:14:467:16 | call to C.init() | test.swift:467:9:467:9 | SSA def(cx) | -| test.swift:468:5:468:5 | [post] cx | test.swift:472:20:472:20 | cx | -| test.swift:468:5:468:5 | cx | test.swift:472:20:472:20 | cx | -| test.swift:469:9:469:9 | SSA def(cy) | test.swift:470:5:470:5 | cy | -| test.swift:469:14:469:16 | call to C.init() | test.swift:469:9:469:9 | SSA def(cy) | -| test.swift:470:5:470:5 | [post] cy | test.swift:474:20:474:20 | cy | -| test.swift:470:5:470:5 | cy | test.swift:474:20:474:20 | cy | -| test.swift:472:11:472:15 | SSA def(z1) | test.swift:473:15:473:15 | z1 | -| test.swift:472:20:472:23 | .x | test.swift:472:11:472:15 | SSA def(z1) | -| test.swift:474:11:474:15 | SSA def(z2) | test.swift:475:15:475:15 | z2 | -| test.swift:474:20:474:23 | .x | test.swift:474:11:474:15 | SSA def(z2) | -| test.swift:479:14:479:21 | call to source() | test.swift:479:13:479:21 | call to +(_:) | -| test.swift:487:7:487:7 | SSA def(self) | test.swift:487:7:487:7 | self[return] | -| test.swift:487:7:487:7 | self | test.swift:487:7:487:7 | SSA def(self) | -| test.swift:488:9:488:9 | self | test.swift:488:9:488:9 | SSA def(self) | -| test.swift:488:9:488:9 | self | test.swift:488:9:488:9 | SSA def(self) | -| test.swift:488:9:488:9 | self | test.swift:488:9:488:9 | SSA def(self) | -| test.swift:488:9:488:9 | value | test.swift:488:9:488:9 | SSA def(value) | -| test.swift:489:5:489:5 | SSA def(self) | test.swift:490:7:490:7 | self | -| test.swift:489:5:489:5 | self | test.swift:489:5:489:5 | SSA def(self) | -| test.swift:489:10:489:13 | SSA def(s) | test.swift:490:13:490:13 | s | -| test.swift:489:10:489:13 | s | test.swift:489:10:489:13 | SSA def(s) | -| test.swift:490:7:490:7 | [post] self | test.swift:489:5:491:5 | self[return] | -| test.swift:490:7:490:7 | self | test.swift:489:5:491:5 | self[return] | -| test.swift:495:17:495:17 | SSA def(self) | test.swift:496:7:496:7 | self | -| test.swift:495:17:495:17 | self | test.swift:495:17:495:17 | SSA def(self) | -| test.swift:496:7:496:7 | [post] self | test.swift:497:17:497:17 | self | -| test.swift:496:7:496:7 | self | test.swift:497:17:497:17 | self | -| test.swift:497:17:497:17 | [post] self | test.swift:495:17:498:5 | self[return] | -| test.swift:497:17:497:17 | self | test.swift:495:17:498:5 | self[return] | -| test.swift:501:21:501:27 | SSA def(path) | test.swift:503:37:503:37 | path | -| test.swift:501:21:501:27 | path | test.swift:501:21:501:27 | SSA def(path) | -| test.swift:506:7:506:7 | SSA def(self) | test.swift:506:7:506:7 | self[return] | -| test.swift:506:7:506:7 | self | test.swift:506:7:506:7 | SSA def(self) | -| test.swift:507:3:507:3 | SSA def(self) | test.swift:507:3:507:40 | self[return] | -| test.swift:507:3:507:3 | self | test.swift:507:3:507:3 | SSA def(self) | -| test.swift:507:27:507:38 | SSA def(n) | test.swift:507:3:507:40 | n[return] | -| test.swift:507:31:507:38 | call to source() | test.swift:507:27:507:38 | SSA def(n) | -| test.swift:513:7:513:7 | SSA def(n) | test.swift:514:36:514:36 | n | -| test.swift:513:11:513:11 | 0 | test.swift:513:7:513:7 | SSA def(n) | -| test.swift:514:36:514:36 | n | test.swift:514:35:514:36 | &... | +| test.swift:376:9:376:13 | SSA def(a) | test.swift:378:12:378:12 | a | +| test.swift:376:22:376:23 | .myNone | test.swift:376:9:376:13 | SSA def(a) | +| test.swift:378:12:378:12 | a | test.swift:390:32:390:32 | a | +| test.swift:381:10:381:25 | SSA def(a) | test.swift:382:19:382:19 | a | +| test.swift:383:10:383:30 | SSA def(a) | test.swift:384:19:384:19 | a | +| test.swift:383:10:383:30 | SSA def(b) | test.swift:385:19:385:19 | b | +| test.swift:386:10:386:26 | SSA def(a) | test.swift:387:19:387:19 | a | +| test.swift:390:13:390:28 | SSA def(x) | test.swift:391:19:391:19 | x | +| test.swift:390:32:390:32 | a | test.swift:390:13:390:28 | SSA def(x) | +| test.swift:390:32:390:32 | a | test.swift:393:37:393:37 | a | +| test.swift:393:13:393:33 | SSA def(x) | test.swift:394:19:394:19 | x | +| test.swift:393:13:393:33 | SSA def(y) | test.swift:395:19:395:19 | y | +| test.swift:398:5:398:27 | SSA def(a) | test.swift:400:12:400:12 | a | +| test.swift:398:9:398:27 | call to ... | test.swift:398:5:398:27 | SSA def(a) | +| test.swift:400:12:400:12 | a | test.swift:412:32:412:32 | a | +| test.swift:403:10:403:25 | SSA def(a) | test.swift:404:19:404:19 | a | +| test.swift:405:10:405:30 | SSA def(a) | test.swift:406:19:406:19 | a | +| test.swift:405:10:405:30 | SSA def(b) | test.swift:407:19:407:19 | b | +| test.swift:408:10:408:26 | SSA def(a) | test.swift:409:19:409:19 | a | +| test.swift:412:13:412:28 | SSA def(x) | test.swift:413:19:413:19 | x | +| test.swift:412:32:412:32 | a | test.swift:412:13:412:28 | SSA def(x) | +| test.swift:412:32:412:32 | a | test.swift:415:37:415:37 | a | +| test.swift:415:13:415:33 | SSA def(x) | test.swift:416:19:416:19 | x | +| test.swift:415:13:415:33 | SSA def(y) | test.swift:417:19:417:19 | y | +| test.swift:420:5:420:34 | SSA def(a) | test.swift:422:12:422:12 | a | +| test.swift:420:9:420:34 | call to ... | test.swift:420:5:420:34 | SSA def(a) | +| test.swift:422:12:422:12 | a | test.swift:434:32:434:32 | a | +| test.swift:425:10:425:25 | SSA def(a) | test.swift:426:19:426:19 | a | +| test.swift:427:10:427:30 | SSA def(a) | test.swift:428:19:428:19 | a | +| test.swift:427:10:427:30 | SSA def(b) | test.swift:429:19:429:19 | b | +| test.swift:430:10:430:26 | SSA def(a) | test.swift:431:19:431:19 | a | +| test.swift:434:13:434:28 | SSA def(x) | test.swift:435:19:435:19 | x | +| test.swift:434:32:434:32 | a | test.swift:434:13:434:28 | SSA def(x) | +| test.swift:434:32:434:32 | a | test.swift:437:37:437:37 | a | +| test.swift:437:13:437:33 | SSA def(x) | test.swift:438:19:438:19 | x | +| test.swift:437:13:437:33 | SSA def(y) | test.swift:439:19:439:19 | y | +| test.swift:437:37:437:37 | a | test.swift:442:33:442:33 | a | +| test.swift:442:9:442:12 | SSA def(b) | test.swift:444:12:444:12 | b | +| test.swift:442:21:442:34 | call to ... | test.swift:442:9:442:12 | SSA def(b) | +| test.swift:442:33:442:33 | [post] a | test.swift:471:13:471:13 | a | +| test.swift:442:33:442:33 | a | test.swift:471:13:471:13 | a | +| test.swift:444:12:444:12 | b | test.swift:460:32:460:32 | b | +| test.swift:447:10:447:25 | SSA def(a) | test.swift:448:19:448:19 | a | +| test.swift:449:10:449:30 | SSA def(a) | test.swift:450:19:450:19 | a | +| test.swift:449:10:449:30 | SSA def(b) | test.swift:451:19:451:19 | b | +| test.swift:452:10:452:38 | SSA def(a) | test.swift:453:19:453:19 | a | +| test.swift:452:10:452:38 | SSA def(b) | test.swift:454:19:454:19 | b | +| test.swift:452:10:452:38 | SSA def(c) | test.swift:455:19:455:19 | c | +| test.swift:456:10:456:26 | SSA def(a) | test.swift:457:19:457:19 | a | +| test.swift:460:13:460:28 | SSA def(x) | test.swift:461:19:461:19 | x | +| test.swift:460:32:460:32 | b | test.swift:460:13:460:28 | SSA def(x) | +| test.swift:460:32:460:32 | b | test.swift:463:37:463:37 | b | +| test.swift:463:13:463:33 | SSA def(x) | test.swift:464:19:464:19 | x | +| test.swift:463:13:463:33 | SSA def(y) | test.swift:465:19:465:19 | y | +| test.swift:463:37:463:37 | b | test.swift:467:45:467:45 | b | +| test.swift:467:13:467:41 | SSA def(c) | test.swift:468:19:468:19 | c | +| test.swift:467:45:467:45 | b | test.swift:467:13:467:41 | SSA def(c) | +| test.swift:467:45:467:45 | b | test.swift:471:16:471:16 | b | +| test.swift:472:10:472:55 | SSA def(a) | test.swift:473:19:473:19 | a | +| test.swift:472:10:472:55 | SSA def(b) | test.swift:474:19:474:19 | b | +| test.swift:472:10:472:55 | SSA def(c) | test.swift:475:19:475:19 | c | +| test.swift:472:10:472:55 | SSA def(d) | test.swift:476:19:476:19 | d | +| test.swift:472:10:472:55 | SSA def(e) | test.swift:477:19:477:19 | e | +| test.swift:485:21:485:27 | SSA def(y) | test.swift:488:27:488:27 | y | +| test.swift:485:21:485:27 | SSA def(y) | test.swift:493:22:493:22 | y | +| test.swift:485:21:485:27 | y | test.swift:485:21:485:27 | SSA def(y) | +| test.swift:486:9:486:9 | SSA def(x) | test.swift:488:16:488:16 | x | +| test.swift:486:13:486:28 | call to optionalSource() | test.swift:486:9:486:9 | SSA def(x) | +| test.swift:488:8:488:12 | SSA def(a) | test.swift:489:19:489:19 | a | +| test.swift:488:16:488:16 | x | test.swift:488:8:488:12 | SSA def(a) | +| test.swift:488:16:488:16 | x | test.swift:493:19:493:19 | x | +| test.swift:488:19:488:23 | SSA def(b) | test.swift:490:19:490:19 | b | +| test.swift:488:27:488:27 | y | test.swift:488:19:488:23 | SSA def(b) | +| test.swift:488:27:488:27 | y | test.swift:493:22:493:22 | y | +| test.swift:493:9:493:9 | SSA def(tuple1) | test.swift:494:12:494:12 | tuple1 | +| test.swift:493:18:493:23 | (...) | test.swift:493:9:493:9 | SSA def(tuple1) | +| test.swift:495:10:495:37 | SSA def(a) | test.swift:496:19:496:19 | a | +| test.swift:495:10:495:37 | SSA def(b) | test.swift:497:19:497:19 | b | +| test.swift:502:8:502:17 | SSA def(x) | test.swift:503:19:503:19 | x | +| test.swift:502:8:502:17 | SSA def(y) | test.swift:504:19:504:19 | y | +| test.swift:508:7:508:7 | SSA def(self) | test.swift:508:7:508:7 | self[return] | +| test.swift:508:7:508:7 | SSA def(self) | test.swift:508:7:508:7 | self[return] | +| test.swift:508:7:508:7 | self | test.swift:508:7:508:7 | SSA def(self) | +| test.swift:508:7:508:7 | self | test.swift:508:7:508:7 | SSA def(self) | +| test.swift:509:9:509:9 | self | test.swift:509:9:509:9 | SSA def(self) | +| test.swift:509:9:509:9 | self | test.swift:509:9:509:9 | SSA def(self) | +| test.swift:509:9:509:9 | self | test.swift:509:9:509:9 | SSA def(self) | +| test.swift:509:9:509:9 | value | test.swift:509:9:509:9 | SSA def(value) | +| test.swift:512:33:512:39 | SSA def(y) | test.swift:517:12:517:12 | y | +| test.swift:512:33:512:39 | y | test.swift:512:33:512:39 | SSA def(y) | +| test.swift:513:9:513:9 | SSA def(x) | test.swift:515:12:515:12 | x | +| test.swift:513:13:513:28 | call to optionalSource() | test.swift:513:9:513:9 | SSA def(x) | +| test.swift:514:9:514:9 | SSA def(cx) | test.swift:515:5:515:5 | cx | +| test.swift:514:14:514:16 | call to C.init() | test.swift:514:9:514:9 | SSA def(cx) | +| test.swift:515:5:515:5 | [post] cx | test.swift:519:20:519:20 | cx | +| test.swift:515:5:515:5 | cx | test.swift:519:20:519:20 | cx | +| test.swift:516:9:516:9 | SSA def(cy) | test.swift:517:5:517:5 | cy | +| test.swift:516:14:516:16 | call to C.init() | test.swift:516:9:516:9 | SSA def(cy) | +| test.swift:517:5:517:5 | [post] cy | test.swift:521:20:521:20 | cy | +| test.swift:517:5:517:5 | cy | test.swift:521:20:521:20 | cy | +| test.swift:519:11:519:15 | SSA def(z1) | test.swift:520:15:520:15 | z1 | +| test.swift:519:20:519:23 | .x | test.swift:519:11:519:15 | SSA def(z1) | +| test.swift:521:11:521:15 | SSA def(z2) | test.swift:522:15:522:15 | z2 | +| test.swift:521:20:521:23 | .x | test.swift:521:11:521:15 | SSA def(z2) | +| test.swift:526:14:526:21 | call to source() | test.swift:526:13:526:21 | call to +(_:) | +| test.swift:534:7:534:7 | SSA def(self) | test.swift:534:7:534:7 | self[return] | +| test.swift:534:7:534:7 | self | test.swift:534:7:534:7 | SSA def(self) | +| test.swift:535:9:535:9 | self | test.swift:535:9:535:9 | SSA def(self) | +| test.swift:535:9:535:9 | self | test.swift:535:9:535:9 | SSA def(self) | +| test.swift:535:9:535:9 | self | test.swift:535:9:535:9 | SSA def(self) | +| test.swift:535:9:535:9 | value | test.swift:535:9:535:9 | SSA def(value) | +| test.swift:536:5:536:5 | SSA def(self) | test.swift:537:7:537:7 | self | +| test.swift:536:5:536:5 | self | test.swift:536:5:536:5 | SSA def(self) | +| test.swift:536:10:536:13 | SSA def(s) | test.swift:537:13:537:13 | s | +| test.swift:536:10:536:13 | s | test.swift:536:10:536:13 | SSA def(s) | +| test.swift:537:7:537:7 | [post] self | test.swift:536:5:538:5 | self[return] | +| test.swift:537:7:537:7 | self | test.swift:536:5:538:5 | self[return] | +| test.swift:542:17:542:17 | SSA def(self) | test.swift:543:7:543:7 | self | +| test.swift:542:17:542:17 | self | test.swift:542:17:542:17 | SSA def(self) | +| test.swift:543:7:543:7 | [post] self | test.swift:544:17:544:17 | self | +| test.swift:543:7:543:7 | self | test.swift:544:17:544:17 | self | +| test.swift:544:17:544:17 | [post] self | test.swift:542:17:545:5 | self[return] | +| test.swift:544:17:544:17 | self | test.swift:542:17:545:5 | self[return] | +| test.swift:548:21:548:27 | SSA def(path) | test.swift:550:37:550:37 | path | +| test.swift:548:21:548:27 | path | test.swift:548:21:548:27 | SSA def(path) | +| test.swift:553:7:553:7 | SSA def(self) | test.swift:553:7:553:7 | self[return] | +| test.swift:553:7:553:7 | self | test.swift:553:7:553:7 | SSA def(self) | +| test.swift:554:3:554:3 | SSA def(self) | test.swift:554:3:554:40 | self[return] | +| test.swift:554:3:554:3 | self | test.swift:554:3:554:3 | SSA def(self) | +| test.swift:554:27:554:38 | SSA def(n) | test.swift:554:3:554:40 | n[return] | +| test.swift:554:31:554:38 | call to source() | test.swift:554:27:554:38 | SSA def(n) | +| test.swift:560:7:560:7 | SSA def(n) | test.swift:561:36:561:36 | n | +| test.swift:560:11:560:11 | 0 | test.swift:560:7:560:7 | SSA def(n) | +| test.swift:561:36:561:36 | n | test.swift:561:35:561:36 | &... | diff --git a/swift/ql/test/library-tests/dataflow/dataflow/test.swift b/swift/ql/test/library-tests/dataflow/dataflow/test.swift index c64b29b8f2f..1d079e51333 100644 --- a/swift/ql/test/library-tests/dataflow/dataflow/test.swift +++ b/swift/ql/test/library-tests/dataflow/dataflow/test.swift @@ -365,14 +365,15 @@ func testTuples2() { sink(arg: c) } -enum MyEnum { +indirect enum MyEnum { case myNone case mySingle(Int) case myPair(Int, Int) + case myCons(Int, MyEnum) } func testEnums() { - let a : MyEnum = .myNone + var a : MyEnum = .myNone switch a { case .myNone: @@ -382,6 +383,8 @@ func testEnums() { case .myPair(let a, let b): sink(arg: a) sink(arg: b) + case let .myCons(a, _): + sink(arg: a) } if case .mySingle(let x) = a { @@ -392,44 +395,88 @@ func testEnums() { sink(arg: y) } - let b : MyEnum = .mySingle(source()) + a = .mySingle(source()) + + switch a { + case .myNone: + () + case .mySingle(let a): + sink(arg: a) // $ MISSING: flow=398 + case .myPair(let a, let b): + sink(arg: a) + sink(arg: b) + case let .myCons(a, _): + sink(arg: a) + } + + if case .mySingle(let x) = a { + sink(arg: x) // $ MISSING: flow=398 + } + if case .myPair(let x, let y) = a { + sink(arg: x) + sink(arg: y) + } + + a = MyEnum.myPair(0, source()) + + switch a { + case .myNone: + () + case .mySingle(let a): + sink(arg: a) + case .myPair(let a, let b): + sink(arg: a) + sink(arg: b) // $ MISSING: flow=420 + case let .myCons(a, _): + sink(arg: a) + } + + if case .mySingle(let x) = a { + sink(arg: x) + } + if case .myPair(let x, let y) = a { + sink(arg: x) + sink(arg: y) // $ MISSING: flow=420 + } + + let b: MyEnum = .myCons(42, a) switch b { case .myNone: () case .mySingle(let a): - sink(arg: a) // $ MISSING: flow=395 + sink(arg: a) case .myPair(let a, let b): sink(arg: a) sink(arg: b) + case let .myCons(a, .myPair(b, c)): + sink(arg: a) + sink(arg: b) + sink(arg: c) // $ MISSING: flow=420 + case let .myCons(a, _): + sink(arg: a) } - if case .mySingle(let x) = a { - sink(arg: x) // $ MISSING: flow=395 + if case .mySingle(let x) = b { + sink(arg: x) } - if case .myPair(let x, let y) = a { + if case .myPair(let x, let y) = b { sink(arg: x) sink(arg: y) } + if case let .myCons(_, .myPair(_, c)) = b { + sink(arg: c) // $ MISSING: flow=420 + } - let c = MyEnum.myPair(0, source()) - - switch c { - case .myNone: + switch (a, b) { + case let (.myPair(a, b), .myCons(c, .myPair(d, e))): + sink(arg: a) + sink(arg: b) // $ MISSING: flow=420 + sink(arg: c) + sink(arg: d) + sink(arg: e) // $ MISSING: flow=420 + default: () - case .mySingle(let a): - sink(arg: a) - case .myPair(let a, let b): - sink(arg: a) - sink(arg: b) // $ MISSING: flow=415 - } - - if case .mySingle(let x) = a { - sink(arg: x) - } - if case .myPair(let x, let y) = a { - sink(arg: x) - sink(arg: y) // $ MISSING: flow=415 } } @@ -476,8 +523,8 @@ func testOptionalPropertyAccess(y: Int?) { } func testIdentityArithmetic() { - sink(arg: +source()) // $ flow=479 - sink(arg: (source())) // $ flow=480 + sink(arg: +source()) // $ flow=526 + sink(arg: (source())) // $ flow=527 } func sink(str: String) {} @@ -493,14 +540,14 @@ class MyClass { extension MyClass { convenience init(contentsOfFile: String) { - self.init(s: source3()) - sink(str: str) // $ flow=496 + self.init(s: source3()) + sink(str: str) // $ flow=543 } } func extensionInits(path: String) { - sink(str: MyClass(s: source3()).str) // $ flow=502 - sink(str: MyClass(contentsOfFile: path).str) // $ flow=496 + sink(str: MyClass(s: source3()).str) // $ flow=549 + sink(str: MyClass(contentsOfFile: path).str) // $ flow=543 } class InoutConstructorClass { @@ -512,4 +559,4 @@ func sink(arg: InoutConstructorClass) {} func inoutConstructor() { var n = 0 sink(arg: InoutConstructorClass(&n)) -} \ No newline at end of file +} From feb8243d5f2c8f910eacf2dc5a3790590051017c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nora=20Dimitrijevi=C4=87?= <d10c@users.noreply.github.com> Date: Wed, 8 Feb 2023 19:00:47 +0100 Subject: [PATCH 533/631] Swift: move BindingPattern to the hidden AST --- .../swift/controlflow/internal/Completion.qll | 4 +- .../internal/ControlFlowGraphImpl.qll | 17 +---- .../swift/elements/pattern/BindingPattern.qll | 2 + .../statements/ConditionElements.expected | 4 +- .../test/library-tests/ast/PrintAst.expected | 74 +++++++++---------- .../controlflow/graph/Cfg.expected | 8 +- 6 files changed, 50 insertions(+), 59 deletions(-) diff --git a/swift/ql/lib/codeql/swift/controlflow/internal/Completion.qll b/swift/ql/lib/codeql/swift/controlflow/internal/Completion.qll index 4de54b4b0ec..3611bbda7c1 100644 --- a/swift/ql/lib/codeql/swift/controlflow/internal/Completion.qll +++ b/swift/ql/lib/codeql/swift/controlflow/internal/Completion.qll @@ -222,7 +222,7 @@ predicate catchMatchingPattern(DoCatchStmt s, CaseStmt c, Pattern pattern) { /** Holds if `sub` is a subpattern of `p`. */ private predicate isSubPattern(Pattern p, Pattern sub) { - sub = p.(BindingPattern).getSubPattern().getFullyUnresolved() + sub = p.(BindingPattern).getResolveStep() or sub = p.(EnumElementPattern).getSubPattern().getFullyUnresolved() or @@ -260,8 +260,6 @@ private string getPatternValue(Pattern p) { private predicate isIrrefutableMatch(Pattern p) { (p instanceof NamedPattern or p instanceof AnyPattern) or - isIrrefutableMatch(p.(BindingPattern).getSubPattern().getFullyUnresolved()) - or isIrrefutableMatch(p.(TypedPattern).getSubPattern().getFullyUnresolved()) or // A pattern hidden underneath a conversion is also an irrefutable pattern. diff --git a/swift/ql/lib/codeql/swift/controlflow/internal/ControlFlowGraphImpl.qll b/swift/ql/lib/codeql/swift/controlflow/internal/ControlFlowGraphImpl.qll index b93e972e6ff..80f07564747 100644 --- a/swift/ql/lib/codeql/swift/controlflow/internal/ControlFlowGraphImpl.qll +++ b/swift/ql/lib/codeql/swift/controlflow/internal/ControlFlowGraphImpl.qll @@ -897,21 +897,12 @@ module Patterns { } } - private class BindingTree extends AstPostOrderTree { + private class BindingTree extends AstStandardPostOrderTree { override BindingPattern ast; - final override predicate propagatesAbnormal(ControlFlowElement n) { - n.asAstNode() = ast.getSubPattern().getFullyUnresolved() - } - - final override predicate first(ControlFlowElement n) { - astFirst(ast.getSubPattern().getFullyUnresolved(), n) - } - - override predicate succ(ControlFlowElement pred, ControlFlowElement succ, Completion c) { - astLast(ast.getSubPattern().getFullyUnresolved(), pred, c) and - c.(MatchingCompletion).isMatch() and - succ.asAstNode() = ast + final override ControlFlowElement getChildElement(int i) { + i = 0 and + result.asAstNode() = ast.getResolveStep() } } diff --git a/swift/ql/lib/codeql/swift/elements/pattern/BindingPattern.qll b/swift/ql/lib/codeql/swift/elements/pattern/BindingPattern.qll index b8422f49dfb..e6c15b51cd8 100644 --- a/swift/ql/lib/codeql/swift/elements/pattern/BindingPattern.qll +++ b/swift/ql/lib/codeql/swift/elements/pattern/BindingPattern.qll @@ -1,5 +1,7 @@ private import codeql.swift.generated.pattern.BindingPattern class BindingPattern extends Generated::BindingPattern { + final override Pattern getResolveStep() { result = getImmediateSubPattern() } + override string toString() { result = "let ..." } } diff --git a/swift/ql/test/extractor-tests/statements/ConditionElements.expected b/swift/ql/test/extractor-tests/statements/ConditionElements.expected index e7f18b329d8..c8a1d23c5fe 100644 --- a/swift/ql/test/extractor-tests/statements/ConditionElements.expected +++ b/swift/ql/test/extractor-tests/statements/ConditionElements.expected @@ -1,7 +1,7 @@ | statements.swift:3:8:3:13 | ... .==(_:_:) ... | statements.swift:3:8:3:13 | ... .==(_:_:) ... | | statements.swift:10:17:10:24 | ... .<(_:_:) ... | statements.swift:10:18:10:22 | ... .<(_:_:) ... | | statements.swift:39:9:39:14 | ... .!=(_:_:) ... | statements.swift:39:9:39:14 | ... .!=(_:_:) ... | -| statements.swift:65:4:65:19 | let ... = ... | statements.swift:65:9:65:15 | let ... | -| statements.swift:65:4:65:19 | let ... = ... | statements.swift:65:19:65:19 | x | +| statements.swift:65:4:65:19 | let ...? = ... | statements.swift:65:13:65:15 | let ...? | +| statements.swift:65:4:65:19 | let ...? = ... | statements.swift:65:19:65:19 | x | | statements.swift:67:4:67:20 | .some(...) = ... | statements.swift:67:9:67:16 | .some(...) | | statements.swift:67:4:67:20 | .some(...) = ... | statements.swift:67:20:67:20 | x | diff --git a/swift/ql/test/library-tests/ast/PrintAst.expected b/swift/ql/test/library-tests/ast/PrintAst.expected index a09e72df54c..0d910ea4c05 100644 --- a/swift/ql/test/library-tests/ast/PrintAst.expected +++ b/swift/ql/test/library-tests/ast/PrintAst.expected @@ -180,8 +180,8 @@ cfg.swift: # 35| getPattern(): [IsPattern] ... is ... # 35| getSubPattern(): [EnumElementPattern] .error3(...) # 35| getSubPattern(): [TuplePattern] (...) -# 35| getElement(0): [BindingPattern] let ... -# 35| getSubPattern(): [NamedPattern] withParam +# 35| getElement(0): [NamedPattern] withParam +# 35| getElement(0).getFullyUnresolved(): [BindingPattern] let ... # 37| getCatch(2): [CaseStmt] case ... # 37| getBody(): [BraceStmt] { ... } # 38| getElement(0): [CallExpr] call to print(_:separator:terminator:) @@ -239,9 +239,9 @@ cfg.swift: # 40| getExpr(): [DefaultArgumentExpr] default separator # 40| getArgument(2): [Argument] terminator: default terminator # 40| getExpr(): [DefaultArgumentExpr] default terminator -# 39| getLabel(0): [CaseLabelItem] let ... -# 39| getPattern(): [BindingPattern] let ... -# 39| getSubPattern(): [NamedPattern] error +# 39| getLabel(0): [CaseLabelItem] error +# 39| getPattern(): [NamedPattern] error +# 39| getPattern().getFullyUnresolved(): [BindingPattern] let ... # 42| getElement(1): [ReturnStmt] return ... # 42| getResult(): [IntegerLiteralExpr] 0 # 35| [ConcreteVarDecl] withParam @@ -803,9 +803,9 @@ cfg.swift: # 156| getCondition(): [StmtCondition] StmtCondition # 156| getElement(0): [ConditionElement] .some(...) = ... # 156| getPattern(): [EnumElementPattern] .some(...) -# 156| getSubPattern(): [BindingPattern] let ... -# 156| getSubPattern(): [NamedPattern] x +# 156| getSubPattern(): [NamedPattern] x # 156| getSubPattern().getFullyUnresolved(): [ParenPattern] (...) +# 156| getImmediateSubPattern(): [BindingPattern] let ... # 156| getInitializer(): [DeclRefExpr] xOptional # 156| getThen(): [BraceStmt] { ... } # 157| getElement(0): [ReturnStmt] return ... @@ -5375,11 +5375,11 @@ patterns.swift: # 12| getCase(0): [CaseStmt] case ... # 12| getBody(): [BraceStmt] { ... } # 12| getElement(0): [StringLiteralExpr] binding -# 12| getLabel(0): [CaseLabelItem] let ... -# 12| getPattern(): [BindingPattern] let ... -# 12| getSubPattern(): [TuplePattern] (...) -# 12| getElement(0): [NamedPattern] xx -# 12| getElement(1): [NamedPattern] yy +# 12| getLabel(0): [CaseLabelItem] (...) +# 12| getPattern(): [TuplePattern] (...) +# 12| getElement(0): [NamedPattern] xx +# 12| getElement(1): [NamedPattern] yy +# 12| getPattern().getFullyUnresolved(): [BindingPattern] let ... # 15| getElement(3): [SwitchStmt] switch 3 { ... } # 15| getExpr(): [IntegerLiteralExpr] 3 # 16| getCase(0): [CaseStmt] case ... @@ -5424,12 +5424,12 @@ patterns.swift: # 28| getCase(1): [CaseStmt] case ... # 28| getBody(): [BraceStmt] { ... } # 28| getElement(0): [DeclRefExpr] i -# 28| getLabel(0): [CaseLabelItem] let ... -# 28| getPattern(): [BindingPattern] let ... -# 28| getSubPattern(): [EnumElementPattern] .baz(...) -# 28| getSubPattern(): [TuplePattern] (...) -# 28| getElement(0): [NamedPattern] i -# 28| getElement(1): [NamedPattern] s +# 28| getLabel(0): [CaseLabelItem] .baz(...) +# 28| getPattern(): [EnumElementPattern] .baz(...) +# 28| getSubPattern(): [TuplePattern] (...) +# 28| getElement(0): [NamedPattern] i +# 28| getElement(1): [NamedPattern] s +# 28| getPattern().getFullyUnresolved(): [BindingPattern] let ... # 31| getElement(8): [PatternBindingDecl] var ... = ... # 31| getInit(0): [NilLiteralExpr] nil # 31| getPattern(0): [TypedPattern] ... as ... @@ -5442,10 +5442,10 @@ patterns.swift: # 34| getCase(0): [CaseStmt] case ... # 34| getBody(): [BraceStmt] { ... } # 34| getElement(0): [DeclRefExpr] n -# 34| getLabel(0): [CaseLabelItem] let ... -# 34| getPattern(): [BindingPattern] let ... -# 34| getSubPattern(): [OptionalSomePattern] let ...? -# 34| getSubPattern(): [NamedPattern] n +# 34| getLabel(0): [CaseLabelItem] let ...? +# 34| getPattern(): [OptionalSomePattern] let ...? +# 34| getSubPattern(): [NamedPattern] n +# 34| getPattern().getFullyUnresolved(): [BindingPattern] let ... # 35| getCase(1): [CaseStmt] case ... # 35| getBody(): [BraceStmt] { ... } # 35| getElement(0): [StringLiteralExpr] none @@ -5470,11 +5470,11 @@ patterns.swift: # 42| getCase(1): [CaseStmt] case ... # 42| getBody(): [BraceStmt] { ... } # 42| getElement(0): [StringLiteralExpr] as pattern -# 42| getLabel(0): [CaseLabelItem] let ... -# 42| getPattern(): [BindingPattern] let ... -# 42| getSubPattern(): [IsPattern] ... is ... -# 42| getCastTypeRepr(): [TypeRepr] String -# 42| getSubPattern(): [NamedPattern] x +# 42| getLabel(0): [CaseLabelItem] ... is ... +# 42| getPattern(): [IsPattern] ... is ... +# 42| getCastTypeRepr(): [TypeRepr] String +# 42| getSubPattern(): [NamedPattern] x +# 42| getPattern().getFullyUnresolved(): [BindingPattern] let ... # 43| getCase(2): [CaseStmt] case ... # 43| getBody(): [BraceStmt] { ... } # 43| getElement(0): [StringLiteralExpr] other @@ -5621,9 +5621,9 @@ statements.swift: # 22| getExpr(): [DefaultArgumentExpr] default separator # 22| getArgument(2): [Argument] terminator: default terminator # 22| getExpr(): [DefaultArgumentExpr] default terminator -# 21| getLabel(0): [CaseLabelItem] let ... -# 21| getPattern(): [BindingPattern] let ... -# 21| getSubPattern(): [NamedPattern] error +# 21| getLabel(0): [CaseLabelItem] error +# 21| getPattern(): [NamedPattern] error +# 21| getPattern().getFullyUnresolved(): [BindingPattern] let ... # 25| getElement(7): [DoCatchStmt] do { ... } catch { ... } # 25| getBody(): [BraceStmt] { ... } # 26| getElement(0): [TryExpr] try ... @@ -5660,9 +5660,9 @@ statements.swift: # 30| getExpr(): [DefaultArgumentExpr] default separator # 30| getArgument(2): [Argument] terminator: default terminator # 30| getExpr(): [DefaultArgumentExpr] default terminator -# 29| getLabel(0): [CaseLabelItem] let ... -# 29| getPattern(): [BindingPattern] let ... -# 29| getSubPattern(): [NamedPattern] error +# 29| getLabel(0): [CaseLabelItem] error +# 29| getPattern(): [NamedPattern] error +# 29| getPattern().getFullyUnresolved(): [BindingPattern] let ... # 2| [ConcreteVarDecl] i # 2| Type = Int # 21| [ConcreteVarDecl] error @@ -5884,10 +5884,10 @@ statements.swift: # 65| getBody(): [BraceStmt] { ... } # 65| getElement(0): [IfStmt] if ... then { ... } # 65| getCondition(): [StmtCondition] StmtCondition -# 65| getElement(0): [ConditionElement] let ... = ... -# 65| getPattern(): [BindingPattern] let ... -# 65| getSubPattern(): [OptionalSomePattern] let ...? -# 65| getSubPattern(): [NamedPattern] xx +# 65| getElement(0): [ConditionElement] let ...? = ... +# 65| getPattern(): [OptionalSomePattern] let ...? +# 65| getSubPattern(): [NamedPattern] xx +# 65| getPattern().getFullyUnresolved(): [BindingPattern] let ... # 65| getInitializer(): [DeclRefExpr] x # 65| getThen(): [BraceStmt] { ... } # 67| [TopLevelCodeDecl] { ... } diff --git a/swift/ql/test/library-tests/controlflow/graph/Cfg.expected b/swift/ql/test/library-tests/controlflow/graph/Cfg.expected index f6a98546a9b..ae67debf690 100644 --- a/swift/ql/test/library-tests/controlflow/graph/Cfg.expected +++ b/swift/ql/test/library-tests/controlflow/graph/Cfg.expected @@ -334,7 +334,10 @@ cfg.swift: #-----| -> default separator # 39| case ... -#-----| -> let ... +#-----| -> error + +# 39| error +#-----| -> error # 39| error #-----| match -> let ... @@ -342,9 +345,6 @@ cfg.swift: # 39| let ... #-----| match -> print(_:separator:terminator:) -# 39| let ... -#-----| -> error - # 40| print(_:separator:terminator:) # 40| call to print(_:separator:terminator:) From 5419e65e019d76e910ffcb890d234d46b3516eff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nora=20Dimitrijevi=C4=87?= <d10c@users.noreply.github.com> Date: Thu, 9 Feb 2023 00:35:14 +0100 Subject: [PATCH 534/631] Swift: add NamedPattern.getVarDecl() --- .../swift/controlflow/internal/Completion.qll | 14 +-- .../swift/elements/pattern/NamedPattern.qll | 35 ++++++++ .../extractor-tests/patterns/all.expected | 20 +++++ .../patterns/bound_and_unbound.expected | 27 ++++++ .../patterns/bound_and_unbound.ql | 11 +++ .../extractor-tests/patterns/patterns.swift | 13 +++ .../test/library-tests/ast/PrintAst.expected | 89 +++++++++++++++++++ .../ql/test/library-tests/ast/patterns.swift | 13 +++ 8 files changed, 215 insertions(+), 7 deletions(-) create mode 100644 swift/ql/test/extractor-tests/patterns/bound_and_unbound.expected create mode 100644 swift/ql/test/extractor-tests/patterns/bound_and_unbound.ql diff --git a/swift/ql/lib/codeql/swift/controlflow/internal/Completion.qll b/swift/ql/lib/codeql/swift/controlflow/internal/Completion.qll index 3611bbda7c1..469194ad252 100644 --- a/swift/ql/lib/codeql/swift/controlflow/internal/Completion.qll +++ b/swift/ql/lib/codeql/swift/controlflow/internal/Completion.qll @@ -222,19 +222,19 @@ predicate catchMatchingPattern(DoCatchStmt s, CaseStmt c, Pattern pattern) { /** Holds if `sub` is a subpattern of `p`. */ private predicate isSubPattern(Pattern p, Pattern sub) { - sub = p.(BindingPattern).getResolveStep() + sub = p.(BindingPattern).getImmediateSubPattern() or - sub = p.(EnumElementPattern).getSubPattern().getFullyUnresolved() + sub = p.(EnumElementPattern).getImmediateSubPattern() or - sub = p.(IsPattern).getSubPattern().getFullyUnresolved() + sub = p.(IsPattern).getImmediateSubPattern() or - sub = p.(OptionalSomePattern).getFullyUnresolved() + sub = p.(OptionalSomePattern).getImmediateSubPattern() or - sub = p.(ParenPattern).getResolveStep() + sub = p.(ParenPattern).getImmediateSubPattern() or - sub = p.(TuplePattern).getAnElement().getFullyUnresolved() + sub = p.(TuplePattern).getImmediateElement(_) or - sub = p.(TypedPattern).getSubPattern().getFullyUnresolved() + sub = p.(TypedPattern).getImmediateSubPattern() } /** Gets the value of `e` if it is a constant value, disregarding conversions. */ diff --git a/swift/ql/lib/codeql/swift/elements/pattern/NamedPattern.qll b/swift/ql/lib/codeql/swift/elements/pattern/NamedPattern.qll index 29e77edc5b5..98fb96ab9cc 100644 --- a/swift/ql/lib/codeql/swift/elements/pattern/NamedPattern.qll +++ b/swift/ql/lib/codeql/swift/elements/pattern/NamedPattern.qll @@ -1,5 +1,40 @@ private import codeql.swift.generated.pattern.NamedPattern +private import codeql.swift.elements.pattern.BindingPattern +private import codeql.swift.elements.pattern.EnumElementPattern +private import codeql.swift.elements.pattern.IsPattern +private import codeql.swift.elements.pattern.OptionalSomePattern +private import codeql.swift.elements.pattern.ParenPattern +private import codeql.swift.elements.pattern.TuplePattern +private import codeql.swift.elements.pattern.TypedPattern +private import codeql.swift.elements.decl.VarDecl +private import codeql.swift.elements.stmt.LabeledConditionalStmt +private import codeql.swift.elements.stmt.ConditionElement class NamedPattern extends Generated::NamedPattern { + /** Holds if this named pattern has a corresponding `VarDecl` */ + predicate hasVarDecl() { exists(this.getVarDecl()) } + + /** Gets the `VarDecl` bound by this named pattern, if any. */ + VarDecl getVarDecl() { + isSubPattern*(result.getParentPattern().getFullyUnresolved(), this) and + result.getName() = this.getName() + } + override string toString() { result = this.getName() } } + +private predicate isSubPattern(Pattern p, Pattern sub) { + sub = p.(BindingPattern).getImmediateSubPattern() + or + sub = p.(EnumElementPattern).getImmediateSubPattern() + or + sub = p.(IsPattern).getImmediateSubPattern() + or + sub = p.(OptionalSomePattern).getImmediateSubPattern() + or + sub = p.(ParenPattern).getImmediateSubPattern() + or + sub = p.(TuplePattern).getImmediateElement(_) + or + sub = p.(TypedPattern).getImmediateSubPattern() +} diff --git a/swift/ql/test/extractor-tests/patterns/all.expected b/swift/ql/test/extractor-tests/patterns/all.expected index 0e63cbec501..4ebf0256203 100644 --- a/swift/ql/test/extractor-tests/patterns/all.expected +++ b/swift/ql/test/extractor-tests/patterns/all.expected @@ -39,3 +39,23 @@ | patterns.swift:46:9:46:9 | b | | patterns.swift:49:10:49:10 | true | | patterns.swift:50:10:50:10 | false | +| patterns.swift:55:9:55:9 | a | +| patterns.swift:55:16:55:16 | b | +| patterns.swift:55:23:55:23 | c | +| patterns.swift:55:23:55:26 | ... as ... | +| patterns.swift:57:8:57:20 | let ... | +| patterns.swift:57:8:57:20 | let ...? | +| patterns.swift:57:12:57:20 | (...) | +| patterns.swift:57:13:57:13 | a | +| patterns.swift:57:16:57:16 | b | +| patterns.swift:57:19:57:19 | c | +| patterns.swift:58:13:58:29 | (...) | +| patterns.swift:58:14:58:14 | =~ ... | +| patterns.swift:58:17:58:21 | let ... | +| patterns.swift:58:21:58:21 | b | +| patterns.swift:58:24:58:28 | let ... | +| patterns.swift:58:28:58:28 | c | +| patterns.swift:61:14:61:14 | =~ ... | +| patterns.swift:62:14:62:18 | let ... | +| patterns.swift:62:18:62:18 | c | +| patterns.swift:63:9:63:9 | _ | diff --git a/swift/ql/test/extractor-tests/patterns/bound_and_unbound.expected b/swift/ql/test/extractor-tests/patterns/bound_and_unbound.expected new file mode 100644 index 00000000000..0fa3b57a3b1 --- /dev/null +++ b/swift/ql/test/extractor-tests/patterns/bound_and_unbound.expected @@ -0,0 +1,27 @@ +bound +| patterns.swift:2:9:2:9 | an_int | +| patterns.swift:3:9:3:9 | a_string | +| patterns.swift:4:10:4:10 | x | +| patterns.swift:4:13:4:13 | y | +| patterns.swift:4:16:4:16 | z | +| patterns.swift:10:9:10:9 | point | +| patterns.swift:12:15:12:15 | xx | +| patterns.swift:12:19:12:19 | yy | +| patterns.swift:24:9:24:9 | v | +| patterns.swift:28:19:28:19 | i | +| patterns.swift:28:22:28:22 | s | +| patterns.swift:31:9:31:9 | w | +| patterns.swift:34:14:34:14 | n | +| patterns.swift:38:9:38:9 | a | +| patterns.swift:42:14:42:14 | x | +| patterns.swift:46:9:46:9 | b | +| patterns.swift:55:9:55:9 | a | +| patterns.swift:55:16:55:16 | b | +| patterns.swift:55:23:55:23 | c | +| patterns.swift:57:13:57:13 | a | +| patterns.swift:57:19:57:19 | c | +| patterns.swift:58:21:58:21 | b | +| patterns.swift:62:18:62:18 | c | +unbound +| patterns.swift:57:16:57:16 | b | +| patterns.swift:58:28:58:28 | c | diff --git a/swift/ql/test/extractor-tests/patterns/bound_and_unbound.ql b/swift/ql/test/extractor-tests/patterns/bound_and_unbound.ql new file mode 100644 index 00000000000..192938fea66 --- /dev/null +++ b/swift/ql/test/extractor-tests/patterns/bound_and_unbound.ql @@ -0,0 +1,11 @@ +import swift + +query predicate bound(NamedPattern p) { + p.getFile().getBaseName() = "patterns.swift" and + p.hasVarDecl() +} + +query predicate unbound(NamedPattern p) { + p.getFile().getBaseName() = "patterns.swift" and + not p.hasVarDecl() +} diff --git a/swift/ql/test/extractor-tests/patterns/patterns.swift b/swift/ql/test/extractor-tests/patterns/patterns.swift index ebc369310c9..9681695411e 100644 --- a/swift/ql/test/extractor-tests/patterns/patterns.swift +++ b/swift/ql/test/extractor-tests/patterns/patterns.swift @@ -50,3 +50,16 @@ func switch_patterns() { case false: "false" } } + +func bound_and_unbound() { + let a = 1, b = 2, c: Int = 3 + + if let (a, b, c) = Optional.some((a, b, c)) { _ = (a, c) } + if case (a, let b, let c) = (a, b, c) { _ = (b) } + + switch a { + case c: "equals c" + case let c: "binds c" + default: "default" + } +} diff --git a/swift/ql/test/library-tests/ast/PrintAst.expected b/swift/ql/test/library-tests/ast/PrintAst.expected index 0d910ea4c05..375dc9a596c 100644 --- a/swift/ql/test/library-tests/ast/PrintAst.expected +++ b/swift/ql/test/library-tests/ast/PrintAst.expected @@ -5509,6 +5509,95 @@ patterns.swift: # 34| Type = Int # 42| [ConcreteVarDecl] x # 42| Type = String +# 54| [ConcreteFuncDecl] bound_and_unbound() +# 54| InterfaceType = () -> () +# 54| getBody(): [BraceStmt] { ... } +# 55| getElement(0): [PatternBindingDecl] var ... = ... +# 55| getInit(0): [IntegerLiteralExpr] 1 +# 55| getInit(1): [IntegerLiteralExpr] 2 +# 55| getInit(2): [IntegerLiteralExpr] 3 +# 55| getPattern(0): [NamedPattern] a +# 55| getPattern(1): [NamedPattern] b +# 55| getPattern(2): [TypedPattern] ... as ... +# 55| getSubPattern(): [NamedPattern] c +# 55| getTypeRepr(): [TypeRepr] Int +# 55| getElement(1): [ConcreteVarDecl] a +# 55| Type = Int +# 55| getElement(2): [ConcreteVarDecl] b +# 55| Type = Int +# 55| getElement(3): [ConcreteVarDecl] c +# 55| Type = Int +# 57| getElement(4): [IfStmt] if ... then { ... } +# 57| getCondition(): [StmtCondition] StmtCondition +# 57| getElement(0): [ConditionElement] let ...? = ... +# 57| getPattern(): [OptionalSomePattern] let ...? +# 57| getSubPattern(): [TuplePattern] (...) +# 57| getElement(0): [NamedPattern] a +# 57| getElement(1): [NamedPattern] b +# 57| getElement(2): [NamedPattern] c +# 57| getSubPattern().getFullyUnresolved(): [BindingPattern] let ... +# 57| getInitializer(): [CallExpr] call to ... +# 57| getFunction(): [MethodLookupExpr] .some +# 57| getBase(): [TypeExpr] Optional<(Int, Int, Int)>.Type +# 57| getTypeRepr(): [TypeRepr] Optional<(Int, Int, Int)> +# 57| getMethodRef(): [DeclRefExpr] some +# 57| getArgument(0): [Argument] : (...) +# 57| getExpr(): [TupleExpr] (...) +# 57| getElement(0): [DeclRefExpr] a +# 57| getElement(1): [DeclRefExpr] b +# 57| getElement(2): [DeclRefExpr] c +# 57| getThen(): [BraceStmt] { ... } +# 57| getElement(0): [AssignExpr] ... = ... +# 57| getDest(): [DiscardAssignmentExpr] _ +# 57| getSource(): [TupleExpr] (...) +# 57| getElement(0): [DeclRefExpr] a +# 57| getElement(1): [DeclRefExpr] c +# 58| getElement(5): [IfStmt] if ... then { ... } +# 58| getCondition(): [StmtCondition] StmtCondition +# 58| getElement(0): [ConditionElement] (...) = ... +# 58| getPattern(): [TuplePattern] (...) +# 58| getElement(0): [ExprPattern] =~ ... +# 58| getSubExpr(): [DeclRefExpr] a +# 58| getElement(1): [NamedPattern] b +# 58| getElement(1).getFullyUnresolved(): [BindingPattern] let ... +# 58| getElement(2): [NamedPattern] c +# 58| getElement(2).getFullyUnresolved(): [BindingPattern] let ... +# 58| getInitializer(): [TupleExpr] (...) +# 58| getElement(0): [DeclRefExpr] a +# 58| getElement(1): [DeclRefExpr] b +# 58| getElement(2): [DeclRefExpr] c +# 58| getThen(): [BraceStmt] { ... } +# 58| getElement(0): [AssignExpr] ... = ... +# 58| getDest(): [DiscardAssignmentExpr] _ +# 58| getSource(): [DeclRefExpr] b +# 58| getSource().getFullyConverted(): [ParenExpr] (...) +# 60| getElement(6): [SwitchStmt] switch a { ... } +# 60| getExpr(): [DeclRefExpr] a +# 61| getCase(0): [CaseStmt] case ... +# 61| getBody(): [BraceStmt] { ... } +# 61| getElement(0): [StringLiteralExpr] equals c +# 61| getLabel(0): [CaseLabelItem] =~ ... +# 61| getPattern(): [ExprPattern] =~ ... +# 61| getSubExpr(): [DeclRefExpr] c +# 62| getCase(1): [CaseStmt] case ... +# 62| getBody(): [BraceStmt] { ... } +# 62| getElement(0): [StringLiteralExpr] binds c +# 62| getLabel(0): [CaseLabelItem] c +# 62| getPattern(): [NamedPattern] c +# 62| getPattern().getFullyUnresolved(): [BindingPattern] let ... +# 63| getCase(2): [CaseStmt] case ... +# 63| getBody(): [BraceStmt] { ... } +# 63| getElement(0): [StringLiteralExpr] default +# 63| getLabel(0): [CaseLabelItem] _ +# 63| getPattern(): [AnyPattern] _ +# 57| [ConcreteVarDecl] a +# 57| Type = Int +# 57| [ConcreteVarDecl] c +# 57| Type = Int +# 58| [ConcreteVarDecl] b +# 58| Type = Int +# 62| [ConcreteVarDecl] c +# 62| Type = Int statements.swift: # 1| [ConcreteFuncDecl] loop() # 1| InterfaceType = () -> () diff --git a/swift/ql/test/library-tests/ast/patterns.swift b/swift/ql/test/library-tests/ast/patterns.swift index ebc369310c9..9681695411e 100644 --- a/swift/ql/test/library-tests/ast/patterns.swift +++ b/swift/ql/test/library-tests/ast/patterns.swift @@ -50,3 +50,16 @@ func switch_patterns() { case false: "false" } } + +func bound_and_unbound() { + let a = 1, b = 2, c: Int = 3 + + if let (a, b, c) = Optional.some((a, b, c)) { _ = (a, c) } + if case (a, let b, let c) = (a, b, c) { _ = (b) } + + switch a { + case c: "equals c" + case let c: "binds c" + default: "default" + } +} From c2e9ffab63383da4aeefb5aafaebd8a1e563542d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nora=20Dimitrijevi=C4=87?= <d10c@users.noreply.github.com> Date: Thu, 9 Feb 2023 22:31:00 +0100 Subject: [PATCH 535/631] Swift: add EnumElementExpr + Pattern.getMatchingExpr() --- swift/ql/.generated.list | 1 - .../swift/elements/expr/EnumElementExpr.qll | 46 ++ .../elements/pattern/EnumElementPattern.qll | 13 + .../codeql/swift/elements/pattern/Pattern.qll | 68 +- swift/ql/lib/swift.qll | 1 + .../extractor-tests/patterns/all.expected | 138 +++++ .../patterns/bound_and_unbound.expected | 39 ++ .../patterns/matching_expr.expected | 80 +++ .../extractor-tests/patterns/matching_expr.ql | 5 + .../extractor-tests/patterns/patterns.swift | 118 ++++ .../test/library-tests/ast/PrintAst.expected | 583 ++++++++++++++++++ .../ql/test/library-tests/ast/patterns.swift | 118 ++++ .../dataflow/dataflow/LocalFlow.expected | 38 +- .../dataflow/dataflow/test.swift | 6 +- 14 files changed, 1228 insertions(+), 26 deletions(-) create mode 100644 swift/ql/lib/codeql/swift/elements/expr/EnumElementExpr.qll create mode 100644 swift/ql/test/extractor-tests/patterns/matching_expr.expected create mode 100644 swift/ql/test/extractor-tests/patterns/matching_expr.ql diff --git a/swift/ql/.generated.list b/swift/ql/.generated.list index 4c93ef9d164..5c6b0ce34c7 100644 --- a/swift/ql/.generated.list +++ b/swift/ql/.generated.list @@ -232,7 +232,6 @@ ql/lib/codeql/swift/elements/pattern/IsPatternConstructor.qll 209ad40227f49dfe1b 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 a5cee4c72446f884107acc248a10b098871dc027513452c569294aaeecbc5890 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 diff --git a/swift/ql/lib/codeql/swift/elements/expr/EnumElementExpr.qll b/swift/ql/lib/codeql/swift/elements/expr/EnumElementExpr.qll new file mode 100644 index 00000000000..da57b528056 --- /dev/null +++ b/swift/ql/lib/codeql/swift/elements/expr/EnumElementExpr.qll @@ -0,0 +1,46 @@ +private import codeql.swift.elements.expr.Expr +private import codeql.swift.elements.expr.Argument +private import codeql.swift.elements.expr.CallExpr +private import codeql.swift.elements.expr.DeclRefExpr +private import codeql.swift.elements.expr.MethodLookupExpr +private import codeql.swift.elements.decl.EnumElementDecl + +/** + * An expression that constructs a case of an enum. + */ +abstract class EnumElementExpr extends Expr { + EnumElementDecl decl; + + /** Gets the declaration of the enum element that this expression creates. */ + EnumElementDecl getElement() { result = decl } + + /** Gets the `i`th argument passed to this enum element expression (0-based). */ + Argument getArgument(int i) { none() } + + /** Gets an argument passed to this enum element expression, if any. */ + final Argument getAnArgument() { result = this.getArgument(_) } + + /** Gets the number of arguments passed to this enum element expression. */ + final int getNumberOfArguments() { result = count(this.getArgument(_)) } +} + +private class EnumElementLookupExpr extends MethodLookupExpr { + EnumElementLookupExpr() { this.getMember() instanceof EnumElementDecl } +} + +private class NullaryEnumElementExpr extends EnumElementExpr instanceof EnumElementLookupExpr { + NullaryEnumElementExpr() { + this.getMember() = decl and not exists(CallExpr ce | ce.getFunction() = this) + } +} + +private class NonNullaryEnumElementExpr extends EnumElementExpr instanceof CallExpr { + NonNullaryEnumElementExpr() { + exists(EnumElementLookupExpr eele | + this.getFunction() = eele and + eele.getMember() = decl + ) + } + + override Argument getArgument(int i) { result = CallExpr.super.getArgument(i) } +} diff --git a/swift/ql/lib/codeql/swift/elements/pattern/EnumElementPattern.qll b/swift/ql/lib/codeql/swift/elements/pattern/EnumElementPattern.qll index b7d97a03a53..7321341abf2 100644 --- a/swift/ql/lib/codeql/swift/elements/pattern/EnumElementPattern.qll +++ b/swift/ql/lib/codeql/swift/elements/pattern/EnumElementPattern.qll @@ -1,6 +1,19 @@ private import codeql.swift.generated.pattern.EnumElementPattern +private import codeql.swift.elements.pattern.TuplePattern class EnumElementPattern extends Generated::EnumElementPattern { + /** + * Gets the `i`th element (0-based) of this enum element's tuple + * sub-pattern, if any, or the sub-pattern itself if it is not a tuple pattern. + */ + Pattern getSubPattern(int i) { + result = this.getSubPattern().(TuplePattern).getElement(i) + or + not this.getSubPattern() instanceof TuplePattern and + result = this.getSubPattern() and + i = 0 + } + override string toString() { if this.hasSubPattern() then result = "." + this.getElement().toString() + "(...)" diff --git a/swift/ql/lib/codeql/swift/elements/pattern/Pattern.qll b/swift/ql/lib/codeql/swift/elements/pattern/Pattern.qll index 7388d7836e7..05eb1d5434e 100644 --- a/swift/ql/lib/codeql/swift/elements/pattern/Pattern.qll +++ b/swift/ql/lib/codeql/swift/elements/pattern/Pattern.qll @@ -1,4 +1,68 @@ -// generated by codegen/codegen.py, remove this comment if you wish to edit this file private import codeql.swift.generated.pattern.Pattern +private import codeql.swift.elements.pattern.EnumElementPattern +private import codeql.swift.elements.pattern.IsPattern +private import codeql.swift.elements.pattern.OptionalSomePattern +private import codeql.swift.elements.pattern.TypedPattern +private import codeql.swift.elements.pattern.TuplePattern +private import codeql.swift.elements.expr.Expr +private import codeql.swift.elements.expr.TupleExpr +private import codeql.swift.elements.expr.EnumElementExpr +private import codeql.swift.elements.expr.LookupExpr +private import codeql.swift.elements.expr.MethodLookupExpr +private import codeql.swift.elements.expr.DeclRefExpr +private import codeql.swift.elements.stmt.ConditionElement +private import codeql.swift.elements.stmt.SwitchStmt +private import codeql.swift.elements.stmt.CaseStmt +private import codeql.swift.elements.decl.VarDecl +private import codeql.swift.elements.decl.PatternBindingDecl +private import codeql.swift.elements.decl.EnumElementDecl +private import codeql.swift.generated.ParentChild -class Pattern extends Generated::Pattern { } +class Pattern extends Generated::Pattern { + /** + * Gets the expression that this pattern is matched against, if any. + * + * For example, in `switch e { case p: ... }`, the pattern `p` + * is matched against the expression `e`. + */ + Expr getMatchingExpr() { + exists(ConditionElement c | + c.getPattern() = this and + result = c.getInitializer() + ) + or + exists(SwitchStmt s | + s.getExpr() = result and + s.getACase().getALabel().getPattern() = this + ) + or + exists(PatternBindingDecl v, int i | + v.getPattern(i) = this and + result = v.getInit(i) + ) + or + exists(Pattern p | p.getMatchingExpr() = result | + this = p.(IsPattern).getSubPattern() + or + this = p.(OptionalSomePattern).getSubPattern() + or + this = p.(TypedPattern).getSubPattern() + ) + or + exists(TuplePattern p, TupleExpr e, int i | + p.getMatchingExpr() = e and + this = p.getElement(i) and + result = e.getElement(i) + ) + or + exists(EnumElementPattern p, EnumElementExpr e, int i | + p.getMatchingExpr() = e and + this = p.getSubPattern(i) and + result = e.getArgument(i).getExpr() and + p.getElement() = e.getElement() + ) + } + + /** Holds if this pattern is matched against an expression. */ + predicate hasMatchingExpr() { exists(this.getMatchingExpr()) } +} diff --git a/swift/ql/lib/swift.qll b/swift/ql/lib/swift.qll index 897bbf9b2f7..819f14e16eb 100644 --- a/swift/ql/lib/swift.qll +++ b/swift/ql/lib/swift.qll @@ -8,6 +8,7 @@ import codeql.swift.elements.expr.InitializerLookupExpr import codeql.swift.elements.expr.MethodCallExpr import codeql.swift.elements.expr.InitializerCallExpr import codeql.swift.elements.expr.SelfRefExpr +import codeql.swift.elements.expr.EnumElementExpr import codeql.swift.elements.decl.MethodDecl import codeql.swift.elements.decl.ClassOrStructDecl import codeql.swift.elements.type.NumericType diff --git a/swift/ql/test/extractor-tests/patterns/all.expected b/swift/ql/test/extractor-tests/patterns/all.expected index 4ebf0256203..bf339e77303 100644 --- a/swift/ql/test/extractor-tests/patterns/all.expected +++ b/swift/ql/test/extractor-tests/patterns/all.expected @@ -59,3 +59,141 @@ | patterns.swift:62:14:62:18 | let ... | | patterns.swift:62:18:62:18 | c | | patterns.swift:63:9:63:9 | _ | +| patterns.swift:78:9:78:9 | a | +| patterns.swift:78:9:78:13 | ... as ... | +| patterns.swift:81:10:81:11 | .myNone | +| patterns.swift:83:10:83:25 | .mySingle(...) | +| patterns.swift:83:19:83:25 | (...) | +| patterns.swift:83:20:83:24 | let ... | +| patterns.swift:83:24:83:24 | a | +| patterns.swift:85:10:85:30 | .myPair(...) | +| patterns.swift:85:17:85:30 | (...) | +| patterns.swift:85:18:85:22 | let ... | +| patterns.swift:85:22:85:22 | a | +| patterns.swift:85:25:85:29 | let ... | +| patterns.swift:85:29:85:29 | b | +| patterns.swift:88:10:88:26 | let ... | +| patterns.swift:88:14:88:26 | .myCons(...) | +| patterns.swift:88:21:88:26 | (...) | +| patterns.swift:88:22:88:22 | a | +| patterns.swift:88:25:88:25 | _ | +| patterns.swift:92:13:92:28 | .mySingle(...) | +| patterns.swift:92:22:92:28 | (...) | +| patterns.swift:92:23:92:27 | let ... | +| patterns.swift:92:27:92:27 | x | +| patterns.swift:95:13:95:33 | .myPair(...) | +| patterns.swift:95:20:95:33 | (...) | +| patterns.swift:95:21:95:25 | let ... | +| patterns.swift:95:25:95:25 | x | +| patterns.swift:95:28:95:32 | let ... | +| patterns.swift:95:32:95:32 | y | +| patterns.swift:103:10:103:11 | .myNone | +| patterns.swift:105:10:105:25 | .mySingle(...) | +| patterns.swift:105:19:105:25 | (...) | +| patterns.swift:105:20:105:24 | let ... | +| patterns.swift:105:24:105:24 | a | +| patterns.swift:107:10:107:30 | .myPair(...) | +| patterns.swift:107:17:107:30 | (...) | +| patterns.swift:107:18:107:22 | let ... | +| patterns.swift:107:22:107:22 | a | +| patterns.swift:107:25:107:29 | let ... | +| patterns.swift:107:29:107:29 | b | +| patterns.swift:110:10:110:26 | let ... | +| patterns.swift:110:14:110:26 | .myCons(...) | +| patterns.swift:110:21:110:26 | (...) | +| patterns.swift:110:22:110:22 | a | +| patterns.swift:110:25:110:25 | _ | +| patterns.swift:114:13:114:28 | .mySingle(...) | +| patterns.swift:114:22:114:28 | (...) | +| patterns.swift:114:23:114:27 | let ... | +| patterns.swift:114:27:114:27 | x | +| patterns.swift:117:13:117:33 | .myPair(...) | +| patterns.swift:117:20:117:33 | (...) | +| patterns.swift:117:21:117:25 | let ... | +| patterns.swift:117:25:117:25 | x | +| patterns.swift:117:28:117:32 | let ... | +| patterns.swift:117:32:117:32 | y | +| patterns.swift:125:10:125:11 | .myNone | +| patterns.swift:127:10:127:25 | .mySingle(...) | +| patterns.swift:127:19:127:25 | (...) | +| patterns.swift:127:20:127:24 | let ... | +| patterns.swift:127:24:127:24 | a | +| patterns.swift:129:10:129:30 | .myPair(...) | +| patterns.swift:129:17:129:30 | (...) | +| patterns.swift:129:18:129:22 | let ... | +| patterns.swift:129:22:129:22 | a | +| patterns.swift:129:25:129:29 | let ... | +| patterns.swift:129:29:129:29 | b | +| patterns.swift:132:10:132:26 | let ... | +| patterns.swift:132:14:132:26 | .myCons(...) | +| patterns.swift:132:21:132:26 | (...) | +| patterns.swift:132:22:132:22 | a | +| patterns.swift:132:25:132:25 | _ | +| patterns.swift:136:13:136:28 | .mySingle(...) | +| patterns.swift:136:22:136:28 | (...) | +| patterns.swift:136:23:136:27 | let ... | +| patterns.swift:136:27:136:27 | x | +| patterns.swift:139:13:139:33 | .myPair(...) | +| patterns.swift:139:20:139:33 | (...) | +| patterns.swift:139:21:139:25 | let ... | +| patterns.swift:139:25:139:25 | x | +| patterns.swift:139:28:139:32 | let ... | +| patterns.swift:139:32:139:32 | y | +| patterns.swift:144:9:144:9 | b | +| patterns.swift:144:9:144:12 | ... as ... | +| patterns.swift:147:10:147:11 | .myNone | +| patterns.swift:149:10:149:25 | .mySingle(...) | +| patterns.swift:149:19:149:25 | (...) | +| patterns.swift:149:20:149:24 | let ... | +| patterns.swift:149:24:149:24 | a | +| patterns.swift:151:10:151:30 | .myPair(...) | +| patterns.swift:151:17:151:30 | (...) | +| patterns.swift:151:18:151:22 | let ... | +| patterns.swift:151:22:151:22 | a | +| patterns.swift:151:25:151:29 | let ... | +| patterns.swift:151:29:151:29 | b | +| patterns.swift:154:10:154:38 | let ... | +| patterns.swift:154:14:154:38 | .myCons(...) | +| patterns.swift:154:21:154:38 | (...) | +| patterns.swift:154:22:154:22 | a | +| patterns.swift:154:25:154:37 | .myPair(...) | +| patterns.swift:154:32:154:37 | (...) | +| patterns.swift:154:33:154:33 | b | +| patterns.swift:154:36:154:36 | c | +| patterns.swift:158:10:158:26 | let ... | +| patterns.swift:158:14:158:26 | .myCons(...) | +| patterns.swift:158:21:158:26 | (...) | +| patterns.swift:158:22:158:22 | a | +| patterns.swift:158:25:158:25 | _ | +| patterns.swift:162:13:162:28 | .mySingle(...) | +| patterns.swift:162:22:162:28 | (...) | +| patterns.swift:162:23:162:27 | let ... | +| patterns.swift:162:27:162:27 | x | +| patterns.swift:165:13:165:39 | .myPair(...) | +| patterns.swift:165:26:165:39 | (...) | +| patterns.swift:165:27:165:31 | let ... | +| patterns.swift:165:31:165:31 | x | +| patterns.swift:165:34:165:38 | let ... | +| patterns.swift:165:38:165:38 | y | +| patterns.swift:169:13:169:41 | let ... | +| patterns.swift:169:17:169:41 | .myCons(...) | +| patterns.swift:169:24:169:41 | (...) | +| patterns.swift:169:25:169:25 | _ | +| patterns.swift:169:28:169:40 | .myPair(...) | +| patterns.swift:169:35:169:40 | (...) | +| patterns.swift:169:36:169:36 | _ | +| patterns.swift:169:39:169:39 | c | +| patterns.swift:174:10:174:55 | let ... | +| patterns.swift:174:14:174:55 | (...) | +| patterns.swift:174:15:174:27 | .myPair(...) | +| patterns.swift:174:22:174:27 | (...) | +| patterns.swift:174:23:174:23 | a | +| patterns.swift:174:26:174:26 | b | +| patterns.swift:174:30:174:54 | .myCons(...) | +| patterns.swift:174:37:174:54 | (...) | +| patterns.swift:174:38:174:38 | c | +| patterns.swift:174:41:174:53 | .myPair(...) | +| patterns.swift:174:48:174:53 | (...) | +| patterns.swift:174:49:174:49 | d | +| patterns.swift:174:52:174:52 | e | +| patterns.swift:180:5:180:5 | _ | diff --git a/swift/ql/test/extractor-tests/patterns/bound_and_unbound.expected b/swift/ql/test/extractor-tests/patterns/bound_and_unbound.expected index 0fa3b57a3b1..80ae00d4850 100644 --- a/swift/ql/test/extractor-tests/patterns/bound_and_unbound.expected +++ b/swift/ql/test/extractor-tests/patterns/bound_and_unbound.expected @@ -22,6 +22,45 @@ bound | patterns.swift:57:19:57:19 | c | | patterns.swift:58:21:58:21 | b | | patterns.swift:62:18:62:18 | c | +| patterns.swift:78:9:78:9 | a | +| patterns.swift:83:24:83:24 | a | +| patterns.swift:85:22:85:22 | a | +| patterns.swift:85:29:85:29 | b | +| patterns.swift:88:22:88:22 | a | +| patterns.swift:92:27:92:27 | x | +| patterns.swift:95:25:95:25 | x | +| patterns.swift:95:32:95:32 | y | +| patterns.swift:105:24:105:24 | a | +| patterns.swift:107:22:107:22 | a | +| patterns.swift:107:29:107:29 | b | +| patterns.swift:110:22:110:22 | a | +| patterns.swift:114:27:114:27 | x | +| patterns.swift:117:25:117:25 | x | +| patterns.swift:117:32:117:32 | y | +| patterns.swift:127:24:127:24 | a | +| patterns.swift:129:22:129:22 | a | +| patterns.swift:129:29:129:29 | b | +| patterns.swift:132:22:132:22 | a | +| patterns.swift:136:27:136:27 | x | +| patterns.swift:139:25:139:25 | x | +| patterns.swift:139:32:139:32 | y | +| patterns.swift:144:9:144:9 | b | +| patterns.swift:149:24:149:24 | a | +| patterns.swift:151:22:151:22 | a | +| patterns.swift:151:29:151:29 | b | +| patterns.swift:154:22:154:22 | a | +| patterns.swift:154:33:154:33 | b | +| patterns.swift:154:36:154:36 | c | +| patterns.swift:158:22:158:22 | a | +| patterns.swift:162:27:162:27 | x | +| patterns.swift:165:31:165:31 | x | +| patterns.swift:165:38:165:38 | y | +| patterns.swift:169:39:169:39 | c | +| patterns.swift:174:23:174:23 | a | +| patterns.swift:174:26:174:26 | b | +| patterns.swift:174:38:174:38 | c | +| patterns.swift:174:49:174:49 | d | +| patterns.swift:174:52:174:52 | e | unbound | patterns.swift:57:16:57:16 | b | | patterns.swift:58:28:58:28 | c | diff --git a/swift/ql/test/extractor-tests/patterns/matching_expr.expected b/swift/ql/test/extractor-tests/patterns/matching_expr.expected new file mode 100644 index 00000000000..46f5d675df9 --- /dev/null +++ b/swift/ql/test/extractor-tests/patterns/matching_expr.expected @@ -0,0 +1,80 @@ +| patterns.swift:2:9:2:9 | an_int | patterns.swift:2:18:2:18 | 42 | +| patterns.swift:3:9:3:9 | a_string | patterns.swift:3:28:3:28 | here | +| patterns.swift:3:9:3:19 | ... as ... | patterns.swift:3:28:3:28 | here | +| patterns.swift:4:9:4:17 | (...) | patterns.swift:4:21:4:29 | (...) | +| patterns.swift:4:10:4:10 | x | patterns.swift:4:22:4:22 | 1 | +| patterns.swift:4:13:4:13 | y | patterns.swift:4:25:4:25 | 2 | +| patterns.swift:4:16:4:16 | z | patterns.swift:4:28:4:28 | 3 | +| patterns.swift:5:9:5:9 | _ | patterns.swift:5:13:5:13 | any | +| patterns.swift:6:10:6:10 | _ | patterns.swift:6:15:6:15 | paren | +| patterns.swift:10:9:10:9 | point | patterns.swift:10:17:10:22 | (...) | +| patterns.swift:12:14:12:21 | (...) | patterns.swift:11:12:11:12 | point | +| patterns.swift:16:10:16:14 | =~ ... | patterns.swift:15:12:15:12 | 3 | +| patterns.swift:17:10:17:10 | _ | patterns.swift:15:12:15:12 | 3 | +| patterns.swift:24:9:24:9 | v | patterns.swift:24:18:24:19 | .bar | +| patterns.swift:24:9:24:12 | ... as ... | patterns.swift:24:18:24:19 | .bar | +| patterns.swift:27:10:27:11 | .bar | patterns.swift:26:12:26:12 | v | +| patterns.swift:28:14:28:23 | .baz(...) | patterns.swift:26:12:26:12 | v | +| patterns.swift:31:9:31:9 | w | patterns.swift:31:19:31:19 | nil | +| patterns.swift:31:9:31:15 | ... as ... | patterns.swift:31:19:31:19 | nil | +| patterns.swift:34:14:34:14 | n | patterns.swift:33:12:33:12 | w | +| patterns.swift:34:14:34:15 | let ...? | patterns.swift:33:12:33:12 | w | +| patterns.swift:35:10:35:10 | _ | patterns.swift:33:12:33:12 | w | +| patterns.swift:38:9:38:9 | a | patterns.swift:38:18:38:18 | any | +| patterns.swift:38:9:38:12 | ... as ... | patterns.swift:38:18:38:18 | any | +| patterns.swift:41:10:41:13 | ... is ... | patterns.swift:40:12:40:12 | a | +| patterns.swift:42:14:42:14 | x | patterns.swift:40:12:40:12 | a | +| patterns.swift:42:14:42:19 | ... is ... | patterns.swift:40:12:40:12 | a | +| patterns.swift:43:10:43:10 | _ | patterns.swift:40:12:40:12 | a | +| patterns.swift:46:9:46:9 | b | patterns.swift:46:13:46:13 | true | +| patterns.swift:49:10:49:10 | true | patterns.swift:48:12:48:12 | b | +| patterns.swift:50:10:50:10 | false | patterns.swift:48:12:48:12 | b | +| patterns.swift:55:9:55:9 | a | patterns.swift:55:13:55:13 | 1 | +| patterns.swift:55:16:55:16 | b | patterns.swift:55:20:55:20 | 2 | +| patterns.swift:55:23:55:23 | c | patterns.swift:55:32:55:32 | 3 | +| patterns.swift:55:23:55:26 | ... as ... | patterns.swift:55:32:55:32 | 3 | +| patterns.swift:57:8:57:20 | let ...? | patterns.swift:57:24:57:47 | call to ... | +| patterns.swift:57:12:57:20 | (...) | patterns.swift:57:24:57:47 | call to ... | +| patterns.swift:58:13:58:29 | (...) | patterns.swift:58:33:58:41 | (...) | +| patterns.swift:58:14:58:14 | =~ ... | patterns.swift:58:34:58:34 | a | +| patterns.swift:58:21:58:21 | b | patterns.swift:58:37:58:37 | b | +| patterns.swift:58:28:58:28 | c | patterns.swift:58:40:58:40 | c | +| patterns.swift:61:14:61:14 | =~ ... | patterns.swift:60:12:60:12 | a | +| patterns.swift:62:18:62:18 | c | patterns.swift:60:12:60:12 | a | +| patterns.swift:63:9:63:9 | _ | patterns.swift:60:12:60:12 | a | +| patterns.swift:78:9:78:9 | a | patterns.swift:78:22:78:23 | .myNone | +| patterns.swift:78:9:78:13 | ... as ... | patterns.swift:78:22:78:23 | .myNone | +| patterns.swift:81:10:81:11 | .myNone | patterns.swift:80:12:80:12 | a | +| patterns.swift:83:10:83:25 | .mySingle(...) | patterns.swift:80:12:80:12 | a | +| patterns.swift:85:10:85:30 | .myPair(...) | patterns.swift:80:12:80:12 | a | +| patterns.swift:88:14:88:26 | .myCons(...) | patterns.swift:80:12:80:12 | a | +| patterns.swift:92:13:92:28 | .mySingle(...) | patterns.swift:92:32:92:32 | a | +| patterns.swift:95:13:95:33 | .myPair(...) | patterns.swift:95:37:95:37 | a | +| patterns.swift:103:10:103:11 | .myNone | patterns.swift:102:12:102:12 | a | +| patterns.swift:105:10:105:25 | .mySingle(...) | patterns.swift:102:12:102:12 | a | +| patterns.swift:107:10:107:30 | .myPair(...) | patterns.swift:102:12:102:12 | a | +| patterns.swift:110:14:110:26 | .myCons(...) | patterns.swift:102:12:102:12 | a | +| patterns.swift:114:13:114:28 | .mySingle(...) | patterns.swift:114:32:114:32 | a | +| patterns.swift:117:13:117:33 | .myPair(...) | patterns.swift:117:37:117:37 | a | +| patterns.swift:125:10:125:11 | .myNone | patterns.swift:124:12:124:12 | a | +| patterns.swift:127:10:127:25 | .mySingle(...) | patterns.swift:124:12:124:12 | a | +| patterns.swift:129:10:129:30 | .myPair(...) | patterns.swift:124:12:124:12 | a | +| patterns.swift:132:14:132:26 | .myCons(...) | patterns.swift:124:12:124:12 | a | +| patterns.swift:136:13:136:28 | .mySingle(...) | patterns.swift:136:32:136:32 | a | +| patterns.swift:139:13:139:33 | .myPair(...) | patterns.swift:139:37:139:37 | a | +| patterns.swift:144:9:144:9 | b | patterns.swift:144:21:144:34 | call to ... | +| patterns.swift:144:9:144:12 | ... as ... | patterns.swift:144:21:144:34 | call to ... | +| patterns.swift:147:10:147:11 | .myNone | patterns.swift:146:12:146:12 | b | +| patterns.swift:149:10:149:25 | .mySingle(...) | patterns.swift:146:12:146:12 | b | +| patterns.swift:151:10:151:30 | .myPair(...) | patterns.swift:146:12:146:12 | b | +| patterns.swift:154:14:154:38 | .myCons(...) | patterns.swift:146:12:146:12 | b | +| patterns.swift:158:14:158:26 | .myCons(...) | patterns.swift:146:12:146:12 | b | +| patterns.swift:162:13:162:28 | .mySingle(...) | patterns.swift:162:32:162:57 | call to ... | +| patterns.swift:165:13:165:39 | .myPair(...) | patterns.swift:165:43:165:62 | call to ... | +| patterns.swift:165:31:165:31 | x | patterns.swift:165:51:165:58 | call to source() | +| patterns.swift:165:38:165:38 | y | patterns.swift:165:61:165:61 | 0 | +| patterns.swift:169:17:169:41 | .myCons(...) | patterns.swift:169:45:169:45 | b | +| patterns.swift:174:14:174:55 | (...) | patterns.swift:173:12:173:17 | (...) | +| patterns.swift:174:15:174:27 | .myPair(...) | patterns.swift:173:13:173:13 | a | +| patterns.swift:174:30:174:54 | .myCons(...) | patterns.swift:173:16:173:16 | b | +| patterns.swift:180:5:180:5 | _ | patterns.swift:173:12:173:17 | (...) | diff --git a/swift/ql/test/extractor-tests/patterns/matching_expr.ql b/swift/ql/test/extractor-tests/patterns/matching_expr.ql new file mode 100644 index 00000000000..ea01332aaeb --- /dev/null +++ b/swift/ql/test/extractor-tests/patterns/matching_expr.ql @@ -0,0 +1,5 @@ +import swift + +from Pattern p, Expr e +where p.getMatchingExpr() = e +select p, e diff --git a/swift/ql/test/extractor-tests/patterns/patterns.swift b/swift/ql/test/extractor-tests/patterns/patterns.swift index 9681695411e..95f3bfb17b6 100644 --- a/swift/ql/test/extractor-tests/patterns/patterns.swift +++ b/swift/ql/test/extractor-tests/patterns/patterns.swift @@ -63,3 +63,121 @@ func bound_and_unbound() { default: "default" } } + +func source() -> Int { 0 } +func sink(arg: Int) { } + +indirect enum MyEnum { + case myNone + case mySingle(Int) + case myPair(Int, Int) + case myCons(Int, MyEnum) +} + +func test_enums() { + var a : MyEnum = .myNone + + switch a { + case .myNone: + () + case .mySingle(let a): + sink(arg: a) + case .myPair(let a, let b): + sink(arg: a) + sink(arg: b) + case let .myCons(a, _): + sink(arg: a) + } + + if case .mySingle(let x) = a { + sink(arg: x) + } + if case .myPair(let x, let y) = a { + sink(arg: x) + sink(arg: y) + } + + a = .mySingle(source()) + + switch a { + case .myNone: + () + case .mySingle(let a): + sink(arg: a) + case .myPair(let a, let b): + sink(arg: a) + sink(arg: b) + case let .myCons(a, _): + sink(arg: a) + } + + if case .mySingle(let x) = a { + sink(arg: x) + } + if case .myPair(let x, let y) = a { + sink(arg: x) + sink(arg: y) + } + + a = MyEnum.myPair(0, source()) + + switch a { + case .myNone: + () + case .mySingle(let a): + sink(arg: a) + case .myPair(let a, let b): + sink(arg: a) + sink(arg: b) + case let .myCons(a, _): + sink(arg: a) + } + + if case .mySingle(let x) = a { + sink(arg: x) + } + if case .myPair(let x, let y) = a { + sink(arg: x) + sink(arg: y) + } + + let b: MyEnum = .myCons(42, a) + + switch b { + case .myNone: + () + case .mySingle(let a): + sink(arg: a) + case .myPair(let a, let b): + sink(arg: a) + sink(arg: b) + case let .myCons(a, .myPair(b, c)): + sink(arg: a) + sink(arg: b) + sink(arg: c) + case let .myCons(a, _): + sink(arg: a) + } + + if case .mySingle(let x) = MyEnum.myPair(source(), 0) { + sink(arg: x) + } + if case MyEnum.myPair(let x, let y) = .myPair(source(), 0) { + sink(arg: x) + sink(arg: y) + } + if case let .myCons(_, .myPair(_, c)) = b { + sink(arg: c) + } + + switch (a, b) { + case let (.myPair(a, b), .myCons(c, .myPair(d, e))): + sink(arg: a) + sink(arg: b) + sink(arg: c) + sink(arg: d) + sink(arg: e) + default: + () + } +} diff --git a/swift/ql/test/library-tests/ast/PrintAst.expected b/swift/ql/test/library-tests/ast/PrintAst.expected index 375dc9a596c..dc06c2810cd 100644 --- a/swift/ql/test/library-tests/ast/PrintAst.expected +++ b/swift/ql/test/library-tests/ast/PrintAst.expected @@ -5598,6 +5598,589 @@ patterns.swift: # 58| Type = Int # 62| [ConcreteVarDecl] c # 62| Type = Int +# 67| [ConcreteFuncDecl] source() +# 67| InterfaceType = () -> Int +# 67| getBody(): [BraceStmt] { ... } +# 67| getElement(0): [ReturnStmt] return ... +# 67| getResult(): [IntegerLiteralExpr] 0 +# 68| [ConcreteFuncDecl] sink(arg:) +# 68| InterfaceType = (Int) -> () +# 68| getParam(0): [ParamDecl] arg +# 68| Type = Int +# 68| getBody(): [BraceStmt] { ... } +# 70| [EnumDecl] MyEnum +# 71| getMember(0): [EnumCaseDecl] case ... +# 71| getMember(1): [EnumElementDecl] myNone +# 72| getMember(2): [EnumCaseDecl] case ... +# 72| getMember(3): [EnumElementDecl] mySingle +# 72| getParam(0): [ParamDecl] _ +# 72| Type = Int +# 73| getMember(4): [EnumCaseDecl] case ... +# 73| getMember(5): [EnumElementDecl] myPair +# 73| getParam(0): [ParamDecl] _ +# 73| Type = Int +# 73| getParam(1): [ParamDecl] _ +# 73| Type = Int +# 74| getMember(6): [EnumCaseDecl] case ... +# 74| getMember(7): [EnumElementDecl] myCons +# 74| getParam(0): [ParamDecl] _ +# 74| Type = Int +# 74| getParam(1): [ParamDecl] _ +# 74| Type = MyEnum +# 77| [ConcreteFuncDecl] test_enums() +# 77| InterfaceType = () -> () +# 77| getBody(): [BraceStmt] { ... } +# 78| getElement(0): [PatternBindingDecl] var ... = ... +# 78| getInit(0): [MethodLookupExpr] .myNone +# 78| getBase(): [TypeExpr] MyEnum.Type +# 78| getTypeRepr(): [TypeRepr] MyEnum +# 78| getMethodRef(): [DeclRefExpr] myNone +# 78| getPattern(0): [TypedPattern] ... as ... +# 78| getSubPattern(): [NamedPattern] a +# 78| getTypeRepr(): [TypeRepr] MyEnum +# 78| getElement(1): [ConcreteVarDecl] a +# 78| Type = MyEnum +# 80| getElement(2): [SwitchStmt] switch a { ... } +# 80| getExpr(): [DeclRefExpr] a +# 80| getExpr().getFullyConverted(): [LoadExpr] (MyEnum) ... +# 81| getCase(0): [CaseStmt] case ... +# 82| getBody(): [BraceStmt] { ... } +# 82| getElement(0): [TupleExpr] (...) +# 81| getLabel(0): [CaseLabelItem] .myNone +# 81| getPattern(): [EnumElementPattern] .myNone +# 83| getCase(1): [CaseStmt] case ... +# 84| getBody(): [BraceStmt] { ... } +# 84| getElement(0): [CallExpr] call to sink(arg:) +# 84| getFunction(): [DeclRefExpr] sink(arg:) +# 84| getArgument(0): [Argument] arg: a +# 84| getExpr(): [DeclRefExpr] a +# 83| getLabel(0): [CaseLabelItem] .mySingle(...) +# 83| getPattern(): [EnumElementPattern] .mySingle(...) +# 83| getSubPattern(): [NamedPattern] a +# 83| getSubPattern().getFullyUnresolved(): [ParenPattern] (...) +# 83| getImmediateSubPattern(): [BindingPattern] let ... +# 85| getCase(2): [CaseStmt] case ... +# 86| getBody(): [BraceStmt] { ... } +# 86| getElement(0): [CallExpr] call to sink(arg:) +# 86| getFunction(): [DeclRefExpr] sink(arg:) +# 86| getArgument(0): [Argument] arg: a +# 86| getExpr(): [DeclRefExpr] a +# 87| getElement(1): [CallExpr] call to sink(arg:) +# 87| getFunction(): [DeclRefExpr] sink(arg:) +# 87| getArgument(0): [Argument] arg: b +# 87| getExpr(): [DeclRefExpr] b +# 85| getLabel(0): [CaseLabelItem] .myPair(...) +# 85| getPattern(): [EnumElementPattern] .myPair(...) +# 85| getSubPattern(): [TuplePattern] (...) +# 85| getElement(0): [NamedPattern] a +# 85| getElement(0).getFullyUnresolved(): [BindingPattern] let ... +# 85| getElement(1): [NamedPattern] b +# 85| getElement(1).getFullyUnresolved(): [BindingPattern] let ... +# 88| getCase(3): [CaseStmt] case ... +# 89| getBody(): [BraceStmt] { ... } +# 89| getElement(0): [CallExpr] call to sink(arg:) +# 89| getFunction(): [DeclRefExpr] sink(arg:) +# 89| getArgument(0): [Argument] arg: a +# 89| getExpr(): [DeclRefExpr] a +# 88| getLabel(0): [CaseLabelItem] .myCons(...) +# 88| getPattern(): [EnumElementPattern] .myCons(...) +# 88| getSubPattern(): [TuplePattern] (...) +# 88| getElement(0): [NamedPattern] a +# 88| getElement(1): [AnyPattern] _ +# 88| getPattern().getFullyUnresolved(): [BindingPattern] let ... +# 92| getElement(3): [IfStmt] if ... then { ... } +# 92| getCondition(): [StmtCondition] StmtCondition +# 92| getElement(0): [ConditionElement] .mySingle(...) = ... +# 92| getPattern(): [EnumElementPattern] .mySingle(...) +# 92| getSubPattern(): [NamedPattern] x +# 92| getSubPattern().getFullyUnresolved(): [ParenPattern] (...) +# 92| getImmediateSubPattern(): [BindingPattern] let ... +# 92| getInitializer(): [DeclRefExpr] a +# 92| getInitializer().getFullyConverted(): [LoadExpr] (MyEnum) ... +# 92| getThen(): [BraceStmt] { ... } +# 93| getElement(0): [CallExpr] call to sink(arg:) +# 93| getFunction(): [DeclRefExpr] sink(arg:) +# 93| getArgument(0): [Argument] arg: x +# 93| getExpr(): [DeclRefExpr] x +# 95| getElement(4): [IfStmt] if ... then { ... } +# 95| getCondition(): [StmtCondition] StmtCondition +# 95| getElement(0): [ConditionElement] .myPair(...) = ... +# 95| getPattern(): [EnumElementPattern] .myPair(...) +# 95| getSubPattern(): [TuplePattern] (...) +# 95| getElement(0): [NamedPattern] x +# 95| getElement(0).getFullyUnresolved(): [BindingPattern] let ... +# 95| getElement(1): [NamedPattern] y +# 95| getElement(1).getFullyUnresolved(): [BindingPattern] let ... +# 95| getInitializer(): [DeclRefExpr] a +# 95| getInitializer().getFullyConverted(): [LoadExpr] (MyEnum) ... +# 95| getThen(): [BraceStmt] { ... } +# 96| getElement(0): [CallExpr] call to sink(arg:) +# 96| getFunction(): [DeclRefExpr] sink(arg:) +# 96| getArgument(0): [Argument] arg: x +# 96| getExpr(): [DeclRefExpr] x +# 97| getElement(1): [CallExpr] call to sink(arg:) +# 97| getFunction(): [DeclRefExpr] sink(arg:) +# 97| getArgument(0): [Argument] arg: y +# 97| getExpr(): [DeclRefExpr] y +# 100| getElement(5): [AssignExpr] ... = ... +# 100| getDest(): [DeclRefExpr] a +# 100| getSource(): [CallExpr] call to ... +# 100| getFunction(): [MethodLookupExpr] .mySingle +# 100| getBase(): [TypeExpr] MyEnum.Type +# 100| getTypeRepr(): [TypeRepr] MyEnum +# 100| getMethodRef(): [DeclRefExpr] mySingle +# 100| getArgument(0): [Argument] : call to source() +# 100| getExpr(): [CallExpr] call to source() +# 100| getFunction(): [DeclRefExpr] source() +# 102| getElement(6): [SwitchStmt] switch a { ... } +# 102| getExpr(): [DeclRefExpr] a +# 102| getExpr().getFullyConverted(): [LoadExpr] (MyEnum) ... +# 103| getCase(0): [CaseStmt] case ... +# 104| getBody(): [BraceStmt] { ... } +# 104| getElement(0): [TupleExpr] (...) +# 103| getLabel(0): [CaseLabelItem] .myNone +# 103| getPattern(): [EnumElementPattern] .myNone +# 105| getCase(1): [CaseStmt] case ... +# 106| getBody(): [BraceStmt] { ... } +# 106| getElement(0): [CallExpr] call to sink(arg:) +# 106| getFunction(): [DeclRefExpr] sink(arg:) +# 106| getArgument(0): [Argument] arg: a +# 106| getExpr(): [DeclRefExpr] a +# 105| getLabel(0): [CaseLabelItem] .mySingle(...) +# 105| getPattern(): [EnumElementPattern] .mySingle(...) +# 105| getSubPattern(): [NamedPattern] a +# 105| getSubPattern().getFullyUnresolved(): [ParenPattern] (...) +# 105| getImmediateSubPattern(): [BindingPattern] let ... +# 107| getCase(2): [CaseStmt] case ... +# 108| getBody(): [BraceStmt] { ... } +# 108| getElement(0): [CallExpr] call to sink(arg:) +# 108| getFunction(): [DeclRefExpr] sink(arg:) +# 108| getArgument(0): [Argument] arg: a +# 108| getExpr(): [DeclRefExpr] a +# 109| getElement(1): [CallExpr] call to sink(arg:) +# 109| getFunction(): [DeclRefExpr] sink(arg:) +# 109| getArgument(0): [Argument] arg: b +# 109| getExpr(): [DeclRefExpr] b +# 107| getLabel(0): [CaseLabelItem] .myPair(...) +# 107| getPattern(): [EnumElementPattern] .myPair(...) +# 107| getSubPattern(): [TuplePattern] (...) +# 107| getElement(0): [NamedPattern] a +# 107| getElement(0).getFullyUnresolved(): [BindingPattern] let ... +# 107| getElement(1): [NamedPattern] b +# 107| getElement(1).getFullyUnresolved(): [BindingPattern] let ... +# 110| getCase(3): [CaseStmt] case ... +# 111| getBody(): [BraceStmt] { ... } +# 111| getElement(0): [CallExpr] call to sink(arg:) +# 111| getFunction(): [DeclRefExpr] sink(arg:) +# 111| getArgument(0): [Argument] arg: a +# 111| getExpr(): [DeclRefExpr] a +# 110| getLabel(0): [CaseLabelItem] .myCons(...) +# 110| getPattern(): [EnumElementPattern] .myCons(...) +# 110| getSubPattern(): [TuplePattern] (...) +# 110| getElement(0): [NamedPattern] a +# 110| getElement(1): [AnyPattern] _ +# 110| getPattern().getFullyUnresolved(): [BindingPattern] let ... +# 114| getElement(7): [IfStmt] if ... then { ... } +# 114| getCondition(): [StmtCondition] StmtCondition +# 114| getElement(0): [ConditionElement] .mySingle(...) = ... +# 114| getPattern(): [EnumElementPattern] .mySingle(...) +# 114| getSubPattern(): [NamedPattern] x +# 114| getSubPattern().getFullyUnresolved(): [ParenPattern] (...) +# 114| getImmediateSubPattern(): [BindingPattern] let ... +# 114| getInitializer(): [DeclRefExpr] a +# 114| getInitializer().getFullyConverted(): [LoadExpr] (MyEnum) ... +# 114| getThen(): [BraceStmt] { ... } +# 115| getElement(0): [CallExpr] call to sink(arg:) +# 115| getFunction(): [DeclRefExpr] sink(arg:) +# 115| getArgument(0): [Argument] arg: x +# 115| getExpr(): [DeclRefExpr] x +# 117| getElement(8): [IfStmt] if ... then { ... } +# 117| getCondition(): [StmtCondition] StmtCondition +# 117| getElement(0): [ConditionElement] .myPair(...) = ... +# 117| getPattern(): [EnumElementPattern] .myPair(...) +# 117| getSubPattern(): [TuplePattern] (...) +# 117| getElement(0): [NamedPattern] x +# 117| getElement(0).getFullyUnresolved(): [BindingPattern] let ... +# 117| getElement(1): [NamedPattern] y +# 117| getElement(1).getFullyUnresolved(): [BindingPattern] let ... +# 117| getInitializer(): [DeclRefExpr] a +# 117| getInitializer().getFullyConverted(): [LoadExpr] (MyEnum) ... +# 117| getThen(): [BraceStmt] { ... } +# 118| getElement(0): [CallExpr] call to sink(arg:) +# 118| getFunction(): [DeclRefExpr] sink(arg:) +# 118| getArgument(0): [Argument] arg: x +# 118| getExpr(): [DeclRefExpr] x +# 119| getElement(1): [CallExpr] call to sink(arg:) +# 119| getFunction(): [DeclRefExpr] sink(arg:) +# 119| getArgument(0): [Argument] arg: y +# 119| getExpr(): [DeclRefExpr] y +# 122| getElement(9): [AssignExpr] ... = ... +# 122| getDest(): [DeclRefExpr] a +# 122| getSource(): [CallExpr] call to ... +# 122| getFunction(): [MethodLookupExpr] .myPair +# 122| getBase(): [TypeExpr] MyEnum.Type +# 122| getTypeRepr(): [TypeRepr] MyEnum +# 122| getMethodRef(): [DeclRefExpr] myPair +# 122| getArgument(0): [Argument] : 0 +# 122| getExpr(): [IntegerLiteralExpr] 0 +# 122| getArgument(1): [Argument] : call to source() +# 122| getExpr(): [CallExpr] call to source() +# 122| getFunction(): [DeclRefExpr] source() +# 124| getElement(10): [SwitchStmt] switch a { ... } +# 124| getExpr(): [DeclRefExpr] a +# 124| getExpr().getFullyConverted(): [LoadExpr] (MyEnum) ... +# 125| getCase(0): [CaseStmt] case ... +# 126| getBody(): [BraceStmt] { ... } +# 126| getElement(0): [TupleExpr] (...) +# 125| getLabel(0): [CaseLabelItem] .myNone +# 125| getPattern(): [EnumElementPattern] .myNone +# 127| getCase(1): [CaseStmt] case ... +# 128| getBody(): [BraceStmt] { ... } +# 128| getElement(0): [CallExpr] call to sink(arg:) +# 128| getFunction(): [DeclRefExpr] sink(arg:) +# 128| getArgument(0): [Argument] arg: a +# 128| getExpr(): [DeclRefExpr] a +# 127| getLabel(0): [CaseLabelItem] .mySingle(...) +# 127| getPattern(): [EnumElementPattern] .mySingle(...) +# 127| getSubPattern(): [NamedPattern] a +# 127| getSubPattern().getFullyUnresolved(): [ParenPattern] (...) +# 127| getImmediateSubPattern(): [BindingPattern] let ... +# 129| getCase(2): [CaseStmt] case ... +# 130| getBody(): [BraceStmt] { ... } +# 130| getElement(0): [CallExpr] call to sink(arg:) +# 130| getFunction(): [DeclRefExpr] sink(arg:) +# 130| getArgument(0): [Argument] arg: a +# 130| getExpr(): [DeclRefExpr] a +# 131| getElement(1): [CallExpr] call to sink(arg:) +# 131| getFunction(): [DeclRefExpr] sink(arg:) +# 131| getArgument(0): [Argument] arg: b +# 131| getExpr(): [DeclRefExpr] b +# 129| getLabel(0): [CaseLabelItem] .myPair(...) +# 129| getPattern(): [EnumElementPattern] .myPair(...) +# 129| getSubPattern(): [TuplePattern] (...) +# 129| getElement(0): [NamedPattern] a +# 129| getElement(0).getFullyUnresolved(): [BindingPattern] let ... +# 129| getElement(1): [NamedPattern] b +# 129| getElement(1).getFullyUnresolved(): [BindingPattern] let ... +# 132| getCase(3): [CaseStmt] case ... +# 133| getBody(): [BraceStmt] { ... } +# 133| getElement(0): [CallExpr] call to sink(arg:) +# 133| getFunction(): [DeclRefExpr] sink(arg:) +# 133| getArgument(0): [Argument] arg: a +# 133| getExpr(): [DeclRefExpr] a +# 132| getLabel(0): [CaseLabelItem] .myCons(...) +# 132| getPattern(): [EnumElementPattern] .myCons(...) +# 132| getSubPattern(): [TuplePattern] (...) +# 132| getElement(0): [NamedPattern] a +# 132| getElement(1): [AnyPattern] _ +# 132| getPattern().getFullyUnresolved(): [BindingPattern] let ... +# 136| getElement(11): [IfStmt] if ... then { ... } +# 136| getCondition(): [StmtCondition] StmtCondition +# 136| getElement(0): [ConditionElement] .mySingle(...) = ... +# 136| getPattern(): [EnumElementPattern] .mySingle(...) +# 136| getSubPattern(): [NamedPattern] x +# 136| getSubPattern().getFullyUnresolved(): [ParenPattern] (...) +# 136| getImmediateSubPattern(): [BindingPattern] let ... +# 136| getInitializer(): [DeclRefExpr] a +# 136| getInitializer().getFullyConverted(): [LoadExpr] (MyEnum) ... +# 136| getThen(): [BraceStmt] { ... } +# 137| getElement(0): [CallExpr] call to sink(arg:) +# 137| getFunction(): [DeclRefExpr] sink(arg:) +# 137| getArgument(0): [Argument] arg: x +# 137| getExpr(): [DeclRefExpr] x +# 139| getElement(12): [IfStmt] if ... then { ... } +# 139| getCondition(): [StmtCondition] StmtCondition +# 139| getElement(0): [ConditionElement] .myPair(...) = ... +# 139| getPattern(): [EnumElementPattern] .myPair(...) +# 139| getSubPattern(): [TuplePattern] (...) +# 139| getElement(0): [NamedPattern] x +# 139| getElement(0).getFullyUnresolved(): [BindingPattern] let ... +# 139| getElement(1): [NamedPattern] y +# 139| getElement(1).getFullyUnresolved(): [BindingPattern] let ... +# 139| getInitializer(): [DeclRefExpr] a +# 139| getInitializer().getFullyConverted(): [LoadExpr] (MyEnum) ... +# 139| getThen(): [BraceStmt] { ... } +# 140| getElement(0): [CallExpr] call to sink(arg:) +# 140| getFunction(): [DeclRefExpr] sink(arg:) +# 140| getArgument(0): [Argument] arg: x +# 140| getExpr(): [DeclRefExpr] x +# 141| getElement(1): [CallExpr] call to sink(arg:) +# 141| getFunction(): [DeclRefExpr] sink(arg:) +# 141| getArgument(0): [Argument] arg: y +# 141| getExpr(): [DeclRefExpr] y +# 144| getElement(13): [PatternBindingDecl] var ... = ... +# 144| getInit(0): [CallExpr] call to ... +# 144| getFunction(): [MethodLookupExpr] .myCons +# 144| getBase(): [TypeExpr] MyEnum.Type +# 144| getTypeRepr(): [TypeRepr] MyEnum +# 144| getMethodRef(): [DeclRefExpr] myCons +# 144| getArgument(0): [Argument] : 42 +# 144| getExpr(): [IntegerLiteralExpr] 42 +# 144| getArgument(1): [Argument] : a +# 144| getExpr(): [DeclRefExpr] a +# 144| getExpr().getFullyConverted(): [LoadExpr] (MyEnum) ... +# 144| getPattern(0): [TypedPattern] ... as ... +# 144| getSubPattern(): [NamedPattern] b +# 144| getTypeRepr(): [TypeRepr] MyEnum +# 144| getElement(14): [ConcreteVarDecl] b +# 144| Type = MyEnum +# 146| getElement(15): [SwitchStmt] switch b { ... } +# 146| getExpr(): [DeclRefExpr] b +# 147| getCase(0): [CaseStmt] case ... +# 148| getBody(): [BraceStmt] { ... } +# 148| getElement(0): [TupleExpr] (...) +# 147| getLabel(0): [CaseLabelItem] .myNone +# 147| getPattern(): [EnumElementPattern] .myNone +# 149| getCase(1): [CaseStmt] case ... +# 150| getBody(): [BraceStmt] { ... } +# 150| getElement(0): [CallExpr] call to sink(arg:) +# 150| getFunction(): [DeclRefExpr] sink(arg:) +# 150| getArgument(0): [Argument] arg: a +# 150| getExpr(): [DeclRefExpr] a +# 149| getLabel(0): [CaseLabelItem] .mySingle(...) +# 149| getPattern(): [EnumElementPattern] .mySingle(...) +# 149| getSubPattern(): [NamedPattern] a +# 149| getSubPattern().getFullyUnresolved(): [ParenPattern] (...) +# 149| getImmediateSubPattern(): [BindingPattern] let ... +# 151| getCase(2): [CaseStmt] case ... +# 152| getBody(): [BraceStmt] { ... } +# 152| getElement(0): [CallExpr] call to sink(arg:) +# 152| getFunction(): [DeclRefExpr] sink(arg:) +# 152| getArgument(0): [Argument] arg: a +# 152| getExpr(): [DeclRefExpr] a +# 153| getElement(1): [CallExpr] call to sink(arg:) +# 153| getFunction(): [DeclRefExpr] sink(arg:) +# 153| getArgument(0): [Argument] arg: b +# 153| getExpr(): [DeclRefExpr] b +# 151| getLabel(0): [CaseLabelItem] .myPair(...) +# 151| getPattern(): [EnumElementPattern] .myPair(...) +# 151| getSubPattern(): [TuplePattern] (...) +# 151| getElement(0): [NamedPattern] a +# 151| getElement(0).getFullyUnresolved(): [BindingPattern] let ... +# 151| getElement(1): [NamedPattern] b +# 151| getElement(1).getFullyUnresolved(): [BindingPattern] let ... +# 154| getCase(3): [CaseStmt] case ... +# 155| getBody(): [BraceStmt] { ... } +# 155| getElement(0): [CallExpr] call to sink(arg:) +# 155| getFunction(): [DeclRefExpr] sink(arg:) +# 155| getArgument(0): [Argument] arg: a +# 155| getExpr(): [DeclRefExpr] a +# 156| getElement(1): [CallExpr] call to sink(arg:) +# 156| getFunction(): [DeclRefExpr] sink(arg:) +# 156| getArgument(0): [Argument] arg: b +# 156| getExpr(): [DeclRefExpr] b +# 157| getElement(2): [CallExpr] call to sink(arg:) +# 157| getFunction(): [DeclRefExpr] sink(arg:) +# 157| getArgument(0): [Argument] arg: c +# 157| getExpr(): [DeclRefExpr] c +# 154| getLabel(0): [CaseLabelItem] .myCons(...) +# 154| getPattern(): [EnumElementPattern] .myCons(...) +# 154| getSubPattern(): [TuplePattern] (...) +# 154| getElement(0): [NamedPattern] a +# 154| getElement(1): [EnumElementPattern] .myPair(...) +# 154| getSubPattern(): [TuplePattern] (...) +# 154| getElement(0): [NamedPattern] b +# 154| getElement(1): [NamedPattern] c +# 154| getPattern().getFullyUnresolved(): [BindingPattern] let ... +# 158| getCase(4): [CaseStmt] case ... +# 159| getBody(): [BraceStmt] { ... } +# 159| getElement(0): [CallExpr] call to sink(arg:) +# 159| getFunction(): [DeclRefExpr] sink(arg:) +# 159| getArgument(0): [Argument] arg: a +# 159| getExpr(): [DeclRefExpr] a +# 158| getLabel(0): [CaseLabelItem] .myCons(...) +# 158| getPattern(): [EnumElementPattern] .myCons(...) +# 158| getSubPattern(): [TuplePattern] (...) +# 158| getElement(0): [NamedPattern] a +# 158| getElement(1): [AnyPattern] _ +# 158| getPattern().getFullyUnresolved(): [BindingPattern] let ... +# 162| getElement(16): [IfStmt] if ... then { ... } +# 162| getCondition(): [StmtCondition] StmtCondition +# 162| getElement(0): [ConditionElement] .mySingle(...) = ... +# 162| getPattern(): [EnumElementPattern] .mySingle(...) +# 162| getSubPattern(): [NamedPattern] x +# 162| getSubPattern().getFullyUnresolved(): [ParenPattern] (...) +# 162| getImmediateSubPattern(): [BindingPattern] let ... +# 162| getInitializer(): [CallExpr] call to ... +# 162| getFunction(): [MethodLookupExpr] .myPair +# 162| getBase(): [TypeExpr] MyEnum.Type +# 162| getTypeRepr(): [TypeRepr] MyEnum +# 162| getMethodRef(): [DeclRefExpr] myPair +# 162| getArgument(0): [Argument] : call to source() +# 162| getExpr(): [CallExpr] call to source() +# 162| getFunction(): [DeclRefExpr] source() +# 162| getArgument(1): [Argument] : 0 +# 162| getExpr(): [IntegerLiteralExpr] 0 +# 162| getThen(): [BraceStmt] { ... } +# 163| getElement(0): [CallExpr] call to sink(arg:) +# 163| getFunction(): [DeclRefExpr] sink(arg:) +# 163| getArgument(0): [Argument] arg: x +# 163| getExpr(): [DeclRefExpr] x +# 165| getElement(17): [IfStmt] if ... then { ... } +# 165| getCondition(): [StmtCondition] StmtCondition +# 165| getElement(0): [ConditionElement] .myPair(...) = ... +# 165| getPattern(): [EnumElementPattern] .myPair(...) +# 165| getSubPattern(): [TuplePattern] (...) +# 165| getElement(0): [NamedPattern] x +# 165| getElement(0).getFullyUnresolved(): [BindingPattern] let ... +# 165| getElement(1): [NamedPattern] y +# 165| getElement(1).getFullyUnresolved(): [BindingPattern] let ... +# 165| getInitializer(): [CallExpr] call to ... +# 165| getFunction(): [MethodLookupExpr] .myPair +# 165| getBase(): [TypeExpr] MyEnum.Type +# 165| getTypeRepr(): [TypeRepr] MyEnum +# 165| getMethodRef(): [DeclRefExpr] myPair +# 165| getArgument(0): [Argument] : call to source() +# 165| getExpr(): [CallExpr] call to source() +# 165| getFunction(): [DeclRefExpr] source() +# 165| getArgument(1): [Argument] : 0 +# 165| getExpr(): [IntegerLiteralExpr] 0 +# 165| getThen(): [BraceStmt] { ... } +# 166| getElement(0): [CallExpr] call to sink(arg:) +# 166| getFunction(): [DeclRefExpr] sink(arg:) +# 166| getArgument(0): [Argument] arg: x +# 166| getExpr(): [DeclRefExpr] x +# 167| getElement(1): [CallExpr] call to sink(arg:) +# 167| getFunction(): [DeclRefExpr] sink(arg:) +# 167| getArgument(0): [Argument] arg: y +# 167| getExpr(): [DeclRefExpr] y +# 169| getElement(18): [IfStmt] if ... then { ... } +# 169| getCondition(): [StmtCondition] StmtCondition +# 169| getElement(0): [ConditionElement] .myCons(...) = ... +# 169| getPattern(): [EnumElementPattern] .myCons(...) +# 169| getSubPattern(): [TuplePattern] (...) +# 169| getElement(0): [AnyPattern] _ +# 169| getElement(1): [EnumElementPattern] .myPair(...) +# 169| getSubPattern(): [TuplePattern] (...) +# 169| getElement(0): [AnyPattern] _ +# 169| getElement(1): [NamedPattern] c +# 169| getPattern().getFullyUnresolved(): [BindingPattern] let ... +# 169| getInitializer(): [DeclRefExpr] b +# 169| getThen(): [BraceStmt] { ... } +# 170| getElement(0): [CallExpr] call to sink(arg:) +# 170| getFunction(): [DeclRefExpr] sink(arg:) +# 170| getArgument(0): [Argument] arg: c +# 170| getExpr(): [DeclRefExpr] c +# 173| getElement(19): [SwitchStmt] switch (...) { ... } +# 173| getExpr(): [TupleExpr] (...) +# 173| getElement(0): [DeclRefExpr] a +# 173| getElement(0).getFullyConverted(): [LoadExpr] (MyEnum) ... +# 173| getElement(1): [DeclRefExpr] b +# 174| getCase(0): [CaseStmt] case ... +# 175| getBody(): [BraceStmt] { ... } +# 175| getElement(0): [CallExpr] call to sink(arg:) +# 175| getFunction(): [DeclRefExpr] sink(arg:) +# 175| getArgument(0): [Argument] arg: a +# 175| getExpr(): [DeclRefExpr] a +# 176| getElement(1): [CallExpr] call to sink(arg:) +# 176| getFunction(): [DeclRefExpr] sink(arg:) +# 176| getArgument(0): [Argument] arg: b +# 176| getExpr(): [DeclRefExpr] b +# 177| getElement(2): [CallExpr] call to sink(arg:) +# 177| getFunction(): [DeclRefExpr] sink(arg:) +# 177| getArgument(0): [Argument] arg: c +# 177| getExpr(): [DeclRefExpr] c +# 178| getElement(3): [CallExpr] call to sink(arg:) +# 178| getFunction(): [DeclRefExpr] sink(arg:) +# 178| getArgument(0): [Argument] arg: d +# 178| getExpr(): [DeclRefExpr] d +# 179| getElement(4): [CallExpr] call to sink(arg:) +# 179| getFunction(): [DeclRefExpr] sink(arg:) +# 179| getArgument(0): [Argument] arg: e +# 179| getExpr(): [DeclRefExpr] e +# 174| getLabel(0): [CaseLabelItem] (...) +# 174| getPattern(): [TuplePattern] (...) +# 174| getElement(0): [EnumElementPattern] .myPair(...) +# 174| getSubPattern(): [TuplePattern] (...) +# 174| getElement(0): [NamedPattern] a +# 174| getElement(1): [NamedPattern] b +# 174| getElement(1): [EnumElementPattern] .myCons(...) +# 174| getSubPattern(): [TuplePattern] (...) +# 174| getElement(0): [NamedPattern] c +# 174| getElement(1): [EnumElementPattern] .myPair(...) +# 174| getSubPattern(): [TuplePattern] (...) +# 174| getElement(0): [NamedPattern] d +# 174| getElement(1): [NamedPattern] e +# 174| getPattern().getFullyUnresolved(): [BindingPattern] let ... +# 180| getCase(1): [CaseStmt] case ... +# 181| getBody(): [BraceStmt] { ... } +# 181| getElement(0): [TupleExpr] (...) +# 180| getLabel(0): [CaseLabelItem] _ +# 180| getPattern(): [AnyPattern] _ +# 83| [ConcreteVarDecl] a +# 83| Type = (Int) +# 85| [ConcreteVarDecl] a +# 85| Type = Int +# 85| [ConcreteVarDecl] b +# 85| Type = Int +# 88| [ConcreteVarDecl] a +# 88| Type = Int +# 92| [ConcreteVarDecl] x +# 92| Type = (Int) +# 95| [ConcreteVarDecl] x +# 95| Type = Int +# 95| [ConcreteVarDecl] y +# 95| Type = Int +# 105| [ConcreteVarDecl] a +# 105| Type = (Int) +# 107| [ConcreteVarDecl] a +# 107| Type = Int +# 107| [ConcreteVarDecl] b +# 107| Type = Int +# 110| [ConcreteVarDecl] a +# 110| Type = Int +# 114| [ConcreteVarDecl] x +# 114| Type = (Int) +# 117| [ConcreteVarDecl] x +# 117| Type = Int +# 117| [ConcreteVarDecl] y +# 117| Type = Int +# 127| [ConcreteVarDecl] a +# 127| Type = (Int) +# 129| [ConcreteVarDecl] a +# 129| Type = Int +# 129| [ConcreteVarDecl] b +# 129| Type = Int +# 132| [ConcreteVarDecl] a +# 132| Type = Int +# 136| [ConcreteVarDecl] x +# 136| Type = (Int) +# 139| [ConcreteVarDecl] x +# 139| Type = Int +# 139| [ConcreteVarDecl] y +# 139| Type = Int +# 149| [ConcreteVarDecl] a +# 149| Type = (Int) +# 151| [ConcreteVarDecl] a +# 151| Type = Int +# 151| [ConcreteVarDecl] b +# 151| Type = Int +# 154| [ConcreteVarDecl] a +# 154| Type = Int +# 154| [ConcreteVarDecl] b +# 154| Type = Int +# 154| [ConcreteVarDecl] c +# 154| Type = Int +# 158| [ConcreteVarDecl] a +# 158| Type = Int +# 162| [ConcreteVarDecl] x +# 162| Type = (Int) +# 165| [ConcreteVarDecl] x +# 165| Type = Int +# 165| [ConcreteVarDecl] y +# 165| Type = Int +# 169| [ConcreteVarDecl] c +# 169| Type = Int +# 174| [ConcreteVarDecl] a +# 174| Type = Int +# 174| [ConcreteVarDecl] b +# 174| Type = Int +# 174| [ConcreteVarDecl] c +# 174| Type = Int +# 174| [ConcreteVarDecl] d +# 174| Type = Int +# 174| [ConcreteVarDecl] e +# 174| Type = Int statements.swift: # 1| [ConcreteFuncDecl] loop() # 1| InterfaceType = () -> () diff --git a/swift/ql/test/library-tests/ast/patterns.swift b/swift/ql/test/library-tests/ast/patterns.swift index 9681695411e..95f3bfb17b6 100644 --- a/swift/ql/test/library-tests/ast/patterns.swift +++ b/swift/ql/test/library-tests/ast/patterns.swift @@ -63,3 +63,121 @@ func bound_and_unbound() { default: "default" } } + +func source() -> Int { 0 } +func sink(arg: Int) { } + +indirect enum MyEnum { + case myNone + case mySingle(Int) + case myPair(Int, Int) + case myCons(Int, MyEnum) +} + +func test_enums() { + var a : MyEnum = .myNone + + switch a { + case .myNone: + () + case .mySingle(let a): + sink(arg: a) + case .myPair(let a, let b): + sink(arg: a) + sink(arg: b) + case let .myCons(a, _): + sink(arg: a) + } + + if case .mySingle(let x) = a { + sink(arg: x) + } + if case .myPair(let x, let y) = a { + sink(arg: x) + sink(arg: y) + } + + a = .mySingle(source()) + + switch a { + case .myNone: + () + case .mySingle(let a): + sink(arg: a) + case .myPair(let a, let b): + sink(arg: a) + sink(arg: b) + case let .myCons(a, _): + sink(arg: a) + } + + if case .mySingle(let x) = a { + sink(arg: x) + } + if case .myPair(let x, let y) = a { + sink(arg: x) + sink(arg: y) + } + + a = MyEnum.myPair(0, source()) + + switch a { + case .myNone: + () + case .mySingle(let a): + sink(arg: a) + case .myPair(let a, let b): + sink(arg: a) + sink(arg: b) + case let .myCons(a, _): + sink(arg: a) + } + + if case .mySingle(let x) = a { + sink(arg: x) + } + if case .myPair(let x, let y) = a { + sink(arg: x) + sink(arg: y) + } + + let b: MyEnum = .myCons(42, a) + + switch b { + case .myNone: + () + case .mySingle(let a): + sink(arg: a) + case .myPair(let a, let b): + sink(arg: a) + sink(arg: b) + case let .myCons(a, .myPair(b, c)): + sink(arg: a) + sink(arg: b) + sink(arg: c) + case let .myCons(a, _): + sink(arg: a) + } + + if case .mySingle(let x) = MyEnum.myPair(source(), 0) { + sink(arg: x) + } + if case MyEnum.myPair(let x, let y) = .myPair(source(), 0) { + sink(arg: x) + sink(arg: y) + } + if case let .myCons(_, .myPair(_, c)) = b { + sink(arg: c) + } + + switch (a, b) { + case let (.myPair(a, b), .myCons(c, .myPair(d, e))): + sink(arg: a) + sink(arg: b) + sink(arg: c) + sink(arg: d) + sink(arg: e) + default: + () + } +} diff --git a/swift/ql/test/library-tests/dataflow/dataflow/LocalFlow.expected b/swift/ql/test/library-tests/dataflow/dataflow/LocalFlow.expected index 74b4164e4e7..e01df699630 100644 --- a/swift/ql/test/library-tests/dataflow/dataflow/LocalFlow.expected +++ b/swift/ql/test/library-tests/dataflow/dataflow/LocalFlow.expected @@ -322,7 +322,7 @@ | test.swift:381:10:381:25 | SSA def(a) | test.swift:382:19:382:19 | a | | test.swift:383:10:383:30 | SSA def(a) | test.swift:384:19:384:19 | a | | test.swift:383:10:383:30 | SSA def(b) | test.swift:385:19:385:19 | b | -| test.swift:386:10:386:26 | SSA def(a) | test.swift:387:19:387:19 | a | +| test.swift:386:14:386:26 | SSA def(a) | test.swift:387:19:387:19 | a | | test.swift:390:13:390:28 | SSA def(x) | test.swift:391:19:391:19 | x | | test.swift:390:32:390:32 | a | test.swift:390:13:390:28 | SSA def(x) | | test.swift:390:32:390:32 | a | test.swift:393:37:393:37 | a | @@ -334,7 +334,7 @@ | test.swift:403:10:403:25 | SSA def(a) | test.swift:404:19:404:19 | a | | test.swift:405:10:405:30 | SSA def(a) | test.swift:406:19:406:19 | a | | test.swift:405:10:405:30 | SSA def(b) | test.swift:407:19:407:19 | b | -| test.swift:408:10:408:26 | SSA def(a) | test.swift:409:19:409:19 | a | +| test.swift:408:14:408:26 | SSA def(a) | test.swift:409:19:409:19 | a | | test.swift:412:13:412:28 | SSA def(x) | test.swift:413:19:413:19 | x | | test.swift:412:32:412:32 | a | test.swift:412:13:412:28 | SSA def(x) | | test.swift:412:32:412:32 | a | test.swift:415:37:415:37 | a | @@ -346,7 +346,7 @@ | test.swift:425:10:425:25 | SSA def(a) | test.swift:426:19:426:19 | a | | test.swift:427:10:427:30 | SSA def(a) | test.swift:428:19:428:19 | a | | test.swift:427:10:427:30 | SSA def(b) | test.swift:429:19:429:19 | b | -| test.swift:430:10:430:26 | SSA def(a) | test.swift:431:19:431:19 | a | +| test.swift:430:14:430:26 | SSA def(a) | test.swift:431:19:431:19 | a | | test.swift:434:13:434:28 | SSA def(x) | test.swift:435:19:435:19 | x | | test.swift:434:32:434:32 | a | test.swift:434:13:434:28 | SSA def(x) | | test.swift:434:32:434:32 | a | test.swift:437:37:437:37 | a | @@ -357,28 +357,26 @@ | test.swift:442:21:442:34 | call to ... | test.swift:442:9:442:12 | SSA def(b) | | test.swift:442:33:442:33 | [post] a | test.swift:471:13:471:13 | a | | test.swift:442:33:442:33 | a | test.swift:471:13:471:13 | a | -| test.swift:444:12:444:12 | b | test.swift:460:32:460:32 | b | +| test.swift:444:12:444:12 | b | test.swift:467:45:467:45 | b | | test.swift:447:10:447:25 | SSA def(a) | test.swift:448:19:448:19 | a | | test.swift:449:10:449:30 | SSA def(a) | test.swift:450:19:450:19 | a | | test.swift:449:10:449:30 | SSA def(b) | test.swift:451:19:451:19 | b | -| test.swift:452:10:452:38 | SSA def(a) | test.swift:453:19:453:19 | a | -| test.swift:452:10:452:38 | SSA def(b) | test.swift:454:19:454:19 | b | -| test.swift:452:10:452:38 | SSA def(c) | test.swift:455:19:455:19 | c | -| test.swift:456:10:456:26 | SSA def(a) | test.swift:457:19:457:19 | a | +| test.swift:452:14:452:38 | SSA def(a) | test.swift:453:19:453:19 | a | +| test.swift:452:14:452:38 | SSA def(b) | test.swift:454:19:454:19 | b | +| test.swift:452:14:452:38 | SSA def(c) | test.swift:455:19:455:19 | c | +| test.swift:456:14:456:26 | SSA def(a) | test.swift:457:19:457:19 | a | | test.swift:460:13:460:28 | SSA def(x) | test.swift:461:19:461:19 | x | -| test.swift:460:32:460:32 | b | test.swift:460:13:460:28 | SSA def(x) | -| test.swift:460:32:460:32 | b | test.swift:463:37:463:37 | b | -| test.swift:463:13:463:33 | SSA def(x) | test.swift:464:19:464:19 | x | -| test.swift:463:13:463:33 | SSA def(y) | test.swift:465:19:465:19 | y | -| test.swift:463:37:463:37 | b | test.swift:467:45:467:45 | b | -| test.swift:467:13:467:41 | SSA def(c) | test.swift:468:19:468:19 | c | -| test.swift:467:45:467:45 | b | test.swift:467:13:467:41 | SSA def(c) | +| test.swift:460:32:460:57 | call to ... | test.swift:460:13:460:28 | SSA def(x) | +| test.swift:463:13:463:39 | SSA def(x) | test.swift:464:19:464:19 | x | +| test.swift:463:13:463:39 | SSA def(y) | test.swift:465:19:465:19 | y | +| test.swift:467:17:467:41 | SSA def(c) | test.swift:468:19:468:19 | c | +| test.swift:467:45:467:45 | b | test.swift:467:17:467:41 | SSA def(c) | | test.swift:467:45:467:45 | b | test.swift:471:16:471:16 | b | -| test.swift:472:10:472:55 | SSA def(a) | test.swift:473:19:473:19 | a | -| test.swift:472:10:472:55 | SSA def(b) | test.swift:474:19:474:19 | b | -| test.swift:472:10:472:55 | SSA def(c) | test.swift:475:19:475:19 | c | -| test.swift:472:10:472:55 | SSA def(d) | test.swift:476:19:476:19 | d | -| test.swift:472:10:472:55 | SSA def(e) | test.swift:477:19:477:19 | e | +| test.swift:472:14:472:55 | SSA def(a) | test.swift:473:19:473:19 | a | +| test.swift:472:14:472:55 | SSA def(b) | test.swift:474:19:474:19 | b | +| test.swift:472:14:472:55 | SSA def(c) | test.swift:475:19:475:19 | c | +| test.swift:472:14:472:55 | SSA def(d) | test.swift:476:19:476:19 | d | +| test.swift:472:14:472:55 | SSA def(e) | test.swift:477:19:477:19 | e | | test.swift:485:21:485:27 | SSA def(y) | test.swift:488:27:488:27 | y | | test.swift:485:21:485:27 | SSA def(y) | test.swift:493:22:493:22 | y | | test.swift:485:21:485:27 | y | test.swift:485:21:485:27 | SSA def(y) | diff --git a/swift/ql/test/library-tests/dataflow/dataflow/test.swift b/swift/ql/test/library-tests/dataflow/dataflow/test.swift index 1d079e51333..81f830840d4 100644 --- a/swift/ql/test/library-tests/dataflow/dataflow/test.swift +++ b/swift/ql/test/library-tests/dataflow/dataflow/test.swift @@ -457,11 +457,11 @@ func testEnums() { sink(arg: a) } - if case .mySingle(let x) = b { + if case .mySingle(let x) = MyEnum.myPair(source(), 0) { sink(arg: x) } - if case .myPair(let x, let y) = b { - sink(arg: x) + if case MyEnum.myPair(let x, let y) = .myPair(source(), 0) { + sink(arg: x) // $ MISSING: flow=463 sink(arg: y) } if case let .myCons(_, .myPair(_, c)) = b { From 5c795632db1ba0fe04603f292b673e2a18178d22 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nora=20Dimitrijevi=C4=87?= <d10c@users.noreply.github.com> Date: Thu, 9 Feb 2023 23:49:56 +0100 Subject: [PATCH 536/631] Swift: add Pattern.getEnclosingPattern() --- .../swift/controlflow/internal/Completion.qll | 21 ++------------ .../swift/elements/pattern/NamedPattern.qll | 27 +----------------- .../codeql/swift/elements/pattern/Pattern.qll | 28 +++++++++++++++++++ 3 files changed, 31 insertions(+), 45 deletions(-) diff --git a/swift/ql/lib/codeql/swift/controlflow/internal/Completion.qll b/swift/ql/lib/codeql/swift/controlflow/internal/Completion.qll index 469194ad252..e3ba2775024 100644 --- a/swift/ql/lib/codeql/swift/controlflow/internal/Completion.qll +++ b/swift/ql/lib/codeql/swift/controlflow/internal/Completion.qll @@ -185,7 +185,7 @@ private predicate switchMatching(SwitchStmt switch, CaseStmt c, AstNode ast) { ( c.getALabel() = ast or - isSubPattern+(c.getALabel().getPattern(), ast) + ast.(Pattern).getEnclosingPattern+() = c.getALabel().getPattern() ) } @@ -216,27 +216,10 @@ predicate catchMatchingPattern(DoCatchStmt s, CaseStmt c, Pattern pattern) { exists(CaseLabelItem cli | catchMatching(s, c, cli) | cli.getPattern() = pattern or - isSubPattern+(cli.getPattern(), pattern) + pattern.getEnclosingPattern+() = cli.getPattern() ) } -/** Holds if `sub` is a subpattern of `p`. */ -private predicate isSubPattern(Pattern p, Pattern sub) { - sub = p.(BindingPattern).getImmediateSubPattern() - or - sub = p.(EnumElementPattern).getImmediateSubPattern() - or - sub = p.(IsPattern).getImmediateSubPattern() - or - sub = p.(OptionalSomePattern).getImmediateSubPattern() - or - sub = p.(ParenPattern).getImmediateSubPattern() - or - sub = p.(TuplePattern).getImmediateElement(_) - or - sub = p.(TypedPattern).getImmediateSubPattern() -} - /** Gets the value of `e` if it is a constant value, disregarding conversions. */ private string getExprValue(Expr e) { result = e.(IntegerLiteralExpr).getStringValue() diff --git a/swift/ql/lib/codeql/swift/elements/pattern/NamedPattern.qll b/swift/ql/lib/codeql/swift/elements/pattern/NamedPattern.qll index 98fb96ab9cc..fc8881f2dd4 100644 --- a/swift/ql/lib/codeql/swift/elements/pattern/NamedPattern.qll +++ b/swift/ql/lib/codeql/swift/elements/pattern/NamedPattern.qll @@ -1,14 +1,5 @@ private import codeql.swift.generated.pattern.NamedPattern -private import codeql.swift.elements.pattern.BindingPattern -private import codeql.swift.elements.pattern.EnumElementPattern -private import codeql.swift.elements.pattern.IsPattern -private import codeql.swift.elements.pattern.OptionalSomePattern -private import codeql.swift.elements.pattern.ParenPattern -private import codeql.swift.elements.pattern.TuplePattern -private import codeql.swift.elements.pattern.TypedPattern private import codeql.swift.elements.decl.VarDecl -private import codeql.swift.elements.stmt.LabeledConditionalStmt -private import codeql.swift.elements.stmt.ConditionElement class NamedPattern extends Generated::NamedPattern { /** Holds if this named pattern has a corresponding `VarDecl` */ @@ -16,25 +7,9 @@ class NamedPattern extends Generated::NamedPattern { /** Gets the `VarDecl` bound by this named pattern, if any. */ VarDecl getVarDecl() { - isSubPattern*(result.getParentPattern().getFullyUnresolved(), this) and + this.getEnclosingPattern*() = result.getParentPattern().getFullyUnresolved() and result.getName() = this.getName() } override string toString() { result = this.getName() } } - -private predicate isSubPattern(Pattern p, Pattern sub) { - sub = p.(BindingPattern).getImmediateSubPattern() - or - sub = p.(EnumElementPattern).getImmediateSubPattern() - or - sub = p.(IsPattern).getImmediateSubPattern() - or - sub = p.(OptionalSomePattern).getImmediateSubPattern() - or - sub = p.(ParenPattern).getImmediateSubPattern() - or - sub = p.(TuplePattern).getImmediateElement(_) - or - sub = p.(TypedPattern).getImmediateSubPattern() -} diff --git a/swift/ql/lib/codeql/swift/elements/pattern/Pattern.qll b/swift/ql/lib/codeql/swift/elements/pattern/Pattern.qll index 05eb1d5434e..63ea6adbc65 100644 --- a/swift/ql/lib/codeql/swift/elements/pattern/Pattern.qll +++ b/swift/ql/lib/codeql/swift/elements/pattern/Pattern.qll @@ -65,4 +65,32 @@ class Pattern extends Generated::Pattern { /** Holds if this pattern is matched against an expression. */ predicate hasMatchingExpr() { exists(this.getMatchingExpr()) } + + /** + * Holds if this occurs as a sub-pattern of the result. + */ + Pattern getEnclosingPattern() { + this = result.(EnumElementPattern).getImmediateSubPattern() + or + this = result.(OptionalSomePattern).getImmediateSubPattern() + or + this = result.(TuplePattern).getImmediateElement(_) + or + result = this.getIdentityPreservingEnclosingPattern() + } + + /** + * Holds if this occurs as a sub-pattern of the result + * without any intervening destructurings of + * complex data structures. + */ + Pattern getIdentityPreservingEnclosingPattern() { + this = result.(BindingPattern).getImmediateSubPattern() + or + this = result.(IsPattern).getImmediateSubPattern() + or + this = result.(ParenPattern).getImmediateSubPattern() + or + this = result.(TypedPattern).getImmediateSubPattern() + } } From 052a008926b2daed12a73749a0a4c8c03bbe53b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nora=20Dimitrijevi=C4=87?= <d10c@users.noreply.github.com> Date: Fri, 10 Feb 2023 13:27:03 +0100 Subject: [PATCH 537/631] Swift: Content-based dataflow through `case let` --- .../dataflow/internal/DataFlowPrivate.qll | 24 ++++++++- .../dataflow/internal/DataFlowPublic.qll | 14 ++++++ .../dataflow/dataflow/DataFlow.expected | 49 +++++++++++++++++++ .../dataflow/dataflow/test.swift | 12 ++--- 4 files changed, 92 insertions(+), 7 deletions(-) diff --git a/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowPrivate.qll b/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowPrivate.qll index 82d2e3a9e41..08c69cde705 100644 --- a/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowPrivate.qll +++ b/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowPrivate.qll @@ -201,7 +201,8 @@ private module Cached { cached newtype TContent = TFieldContent(FieldDecl f) or - TTupleContent(int index) { exists(any(TupleExpr te).getElement(index)) } + TTupleContent(int index) { exists(any(TupleExpr te).getElement(index)) } or + TEnumContent(ParamDecl f) { exists(EnumElementDecl d | d.getAParam() = f) } } /** @@ -558,6 +559,13 @@ predicate storeStep(Node node1, ContentSet c, Node node2) { c.isSingleton(any(Content::TupleContent tc | tc.getIndex() = tuple.getIndex())) ) or + // creation of an enum `.variant(v1, v2)` + exists(EnumElementExpr enum, int pos | + node1.asExpr() = enum.getArgument(pos).getExpr() and + node2.asExpr() = enum and + c.isSingleton(any(Content::EnumContent ec | ec.getField() = enum.getElement().getParam(pos))) + ) + or FlowSummaryImpl::Private::Steps::summaryStoreStep(node1, c, node2) } @@ -578,6 +586,20 @@ predicate readStep(Node node1, ContentSet c, Node node2) { node2.asExpr() = tuple and c.isSingleton(any(Content::TupleContent tc | tc.getIndex() = tuple.getIndex())) ) + or + // read of an enum member via `case let .variant(v1, v2)` pattern matching + exists(Expr enumExpr, ParamDecl enumField, VarDecl boundVar | + node1.asExpr() = enumExpr and + node2.asDefinition().getSourceVariable() = boundVar and + c.isSingleton(any(Content::EnumContent ec | ec.getField() = enumField)) + | + exists(EnumElementPattern enumPat, NamedPattern namePat, int idx | + enumPat.getMatchingExpr() = enumExpr and + enumPat.getElement().getParam(idx) = enumField and + namePat.getIdentityPreservingEnclosingPattern*() = enumPat.getSubPattern(idx) and + namePat.getVarDecl() = boundVar + ) + ) } /** diff --git a/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowPublic.qll b/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowPublic.qll index 9257c8ccb05..c468c146420 100644 --- a/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowPublic.qll +++ b/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowPublic.qll @@ -171,6 +171,20 @@ module Content { override string toString() { result = "Tuple element at index " + index.toString() } } + + /** A field of an enum element. */ + class EnumContent extends Content, TEnumContent { + private ParamDecl f; + + EnumContent() { this = TEnumContent(f) } + + /** Gets the declaration of the enum field. */ + ParamDecl getField() { result = f } + + override string toString() { + exists(EnumElementDecl d, int pos | d.getParam(pos) = f | result = d.toString() + ":" + pos) + } + } } /** diff --git a/swift/ql/test/library-tests/dataflow/dataflow/DataFlow.expected b/swift/ql/test/library-tests/dataflow/dataflow/DataFlow.expected index 321cd1f6c52..420f8ade411 100644 --- a/swift/ql/test/library-tests/dataflow/dataflow/DataFlow.expected +++ b/swift/ql/test/library-tests/dataflow/dataflow/DataFlow.expected @@ -145,6 +145,26 @@ edges | test.swift:357:15:357:15 | t1 [Tuple element at index 1] : | test.swift:357:15:357:18 | .1 | | test.swift:360:15:360:15 | t2 [Tuple element at index 0] : | test.swift:360:15:360:18 | .0 | | test.swift:361:15:361:15 | t2 [Tuple element at index 1] : | test.swift:361:15:361:18 | .1 | +| test.swift:398:9:398:27 | call to ... [mySingle:0] : | test.swift:400:12:400:12 | a [mySingle:0] : | +| test.swift:398:9:398:27 | call to ... [mySingle:0] : | test.swift:412:32:412:32 | a [mySingle:0] : | +| test.swift:398:19:398:26 | call to source() : | test.swift:398:9:398:27 | call to ... [mySingle:0] : | +| test.swift:400:12:400:12 | a [mySingle:0] : | test.swift:403:10:403:25 | SSA def(a) : | +| test.swift:403:10:403:25 | SSA def(a) : | test.swift:404:19:404:19 | a | +| test.swift:412:13:412:28 | SSA def(x) : | test.swift:413:19:413:19 | x | +| test.swift:412:32:412:32 | a [mySingle:0] : | test.swift:412:13:412:28 | SSA def(x) : | +| test.swift:420:9:420:34 | call to ... [myPair:1] : | test.swift:422:12:422:12 | a [myPair:1] : | +| test.swift:420:9:420:34 | call to ... [myPair:1] : | test.swift:437:37:437:37 | a [myPair:1] : | +| test.swift:420:9:420:34 | call to ... [myPair:1] : | test.swift:471:13:471:13 | a [myPair:1] : | +| test.swift:420:26:420:33 | call to source() : | test.swift:420:9:420:34 | call to ... [myPair:1] : | +| test.swift:422:12:422:12 | a [myPair:1] : | test.swift:427:10:427:30 | SSA def(b) : | +| test.swift:427:10:427:30 | SSA def(b) : | test.swift:429:19:429:19 | b | +| test.swift:437:13:437:33 | SSA def(y) : | test.swift:439:19:439:19 | y | +| test.swift:437:37:437:37 | a [myPair:1] : | test.swift:437:13:437:33 | SSA def(y) : | +| test.swift:463:13:463:39 | SSA def(x) : | test.swift:464:19:464:19 | x | +| test.swift:463:43:463:62 | call to ... [myPair:0] : | test.swift:463:13:463:39 | SSA def(x) : | +| test.swift:463:51:463:58 | call to source() : | test.swift:463:43:463:62 | call to ... [myPair:0] : | +| test.swift:471:13:471:13 | a [myPair:1] : | test.swift:472:14:472:55 | SSA def(b) : | +| test.swift:472:14:472:55 | SSA def(b) : | test.swift:474:19:474:19 | b | | test.swift:486:13:486:28 | call to optionalSource() : | test.swift:489:19:489:19 | a | | test.swift:509:9:509:9 | self [x] : | file://:0:0:0:0 | self [x] : | | test.swift:509:9:509:9 | value : | file://:0:0:0:0 | value : | @@ -334,6 +354,29 @@ nodes | test.swift:360:15:360:18 | .0 | semmle.label | .0 | | test.swift:361:15:361:15 | t2 [Tuple element at index 1] : | semmle.label | t2 [Tuple element at index 1] : | | test.swift:361:15:361:18 | .1 | semmle.label | .1 | +| test.swift:398:9:398:27 | call to ... [mySingle:0] : | semmle.label | call to ... [mySingle:0] : | +| test.swift:398:19:398:26 | call to source() : | semmle.label | call to source() : | +| test.swift:400:12:400:12 | a [mySingle:0] : | semmle.label | a [mySingle:0] : | +| test.swift:403:10:403:25 | SSA def(a) : | semmle.label | SSA def(a) : | +| test.swift:404:19:404:19 | a | semmle.label | a | +| test.swift:412:13:412:28 | SSA def(x) : | semmle.label | SSA def(x) : | +| test.swift:412:32:412:32 | a [mySingle:0] : | semmle.label | a [mySingle:0] : | +| test.swift:413:19:413:19 | x | semmle.label | x | +| test.swift:420:9:420:34 | call to ... [myPair:1] : | semmle.label | call to ... [myPair:1] : | +| test.swift:420:26:420:33 | call to source() : | semmle.label | call to source() : | +| test.swift:422:12:422:12 | a [myPair:1] : | semmle.label | a [myPair:1] : | +| test.swift:427:10:427:30 | SSA def(b) : | semmle.label | SSA def(b) : | +| test.swift:429:19:429:19 | b | semmle.label | b | +| test.swift:437:13:437:33 | SSA def(y) : | semmle.label | SSA def(y) : | +| test.swift:437:37:437:37 | a [myPair:1] : | semmle.label | a [myPair:1] : | +| test.swift:439:19:439:19 | y | semmle.label | y | +| test.swift:463:13:463:39 | SSA def(x) : | semmle.label | SSA def(x) : | +| test.swift:463:43:463:62 | call to ... [myPair:0] : | semmle.label | call to ... [myPair:0] : | +| test.swift:463:51:463:58 | call to source() : | semmle.label | call to source() : | +| test.swift:464:19:464:19 | x | semmle.label | x | +| test.swift:471:13:471:13 | a [myPair:1] : | semmle.label | a [myPair:1] : | +| test.swift:472:14:472:55 | SSA def(b) : | semmle.label | SSA def(b) : | +| test.swift:474:19:474:19 | b | semmle.label | b | | test.swift:486:13:486:28 | call to optionalSource() : | semmle.label | call to optionalSource() : | | test.swift:489:19:489:19 | a | semmle.label | a | | test.swift:509:9:509:9 | self [x] : | semmle.label | self [x] : | @@ -448,6 +491,12 @@ subpaths | test.swift:357:15:357:18 | .1 | test.swift:351:31:351:38 | call to source() : | test.swift:357:15:357:18 | .1 | result | | test.swift:360:15:360:18 | .0 | test.swift:351:18:351:25 | call to source() : | test.swift:360:15:360:18 | .0 | result | | test.swift:361:15:361:18 | .1 | test.swift:351:31:351:38 | call to source() : | test.swift:361:15:361:18 | .1 | result | +| test.swift:404:19:404:19 | a | test.swift:398:19:398:26 | call to source() : | test.swift:404:19:404:19 | a | result | +| test.swift:413:19:413:19 | x | test.swift:398:19:398:26 | call to source() : | test.swift:413:19:413:19 | x | result | +| test.swift:429:19:429:19 | b | test.swift:420:26:420:33 | call to source() : | test.swift:429:19:429:19 | b | result | +| test.swift:439:19:439:19 | y | test.swift:420:26:420:33 | call to source() : | test.swift:439:19:439:19 | y | result | +| test.swift:464:19:464:19 | x | test.swift:463:51:463:58 | call to source() : | test.swift:464:19:464:19 | x | result | +| test.swift:474:19:474:19 | b | test.swift:420:26:420:33 | call to source() : | test.swift:474:19:474:19 | b | result | | test.swift:489:19:489:19 | a | test.swift:259:12:259:19 | call to source() : | test.swift:489:19:489:19 | a | result | | test.swift:520:15:520:15 | z1 | test.swift:259:12:259:19 | call to source() : | test.swift:520:15:520:15 | z1 | result | | test.swift:526:13:526:21 | call to +(_:) | test.swift:526:14:526:21 | call to source() : | test.swift:526:13:526:21 | call to +(_:) | result | diff --git a/swift/ql/test/library-tests/dataflow/dataflow/test.swift b/swift/ql/test/library-tests/dataflow/dataflow/test.swift index 81f830840d4..3d8511fd7cb 100644 --- a/swift/ql/test/library-tests/dataflow/dataflow/test.swift +++ b/swift/ql/test/library-tests/dataflow/dataflow/test.swift @@ -401,7 +401,7 @@ func testEnums() { case .myNone: () case .mySingle(let a): - sink(arg: a) // $ MISSING: flow=398 + sink(arg: a) // $ flow=398 case .myPair(let a, let b): sink(arg: a) sink(arg: b) @@ -410,7 +410,7 @@ func testEnums() { } if case .mySingle(let x) = a { - sink(arg: x) // $ MISSING: flow=398 + sink(arg: x) // $ flow=398 } if case .myPair(let x, let y) = a { sink(arg: x) @@ -426,7 +426,7 @@ func testEnums() { sink(arg: a) case .myPair(let a, let b): sink(arg: a) - sink(arg: b) // $ MISSING: flow=420 + sink(arg: b) // $ flow=420 case let .myCons(a, _): sink(arg: a) } @@ -436,7 +436,7 @@ func testEnums() { } if case .myPair(let x, let y) = a { sink(arg: x) - sink(arg: y) // $ MISSING: flow=420 + sink(arg: y) // $ flow=420 } let b: MyEnum = .myCons(42, a) @@ -461,7 +461,7 @@ func testEnums() { sink(arg: x) } if case MyEnum.myPair(let x, let y) = .myPair(source(), 0) { - sink(arg: x) // $ MISSING: flow=463 + sink(arg: x) // $ flow=463 sink(arg: y) } if case let .myCons(_, .myPair(_, c)) = b { @@ -471,7 +471,7 @@ func testEnums() { switch (a, b) { case let (.myPair(a, b), .myCons(c, .myPair(d, e))): sink(arg: a) - sink(arg: b) // $ MISSING: flow=420 + sink(arg: b) // $ flow=420 sink(arg: c) sink(arg: d) sink(arg: e) // $ MISSING: flow=420 From 9353549629c255ab8a713398441e323ee38a631b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nora=20Dimitrijevi=C4=87?= <d10c@users.noreply.github.com> Date: Wed, 15 Feb 2023 15:57:02 +0100 Subject: [PATCH 538/631] Swift: fixes responding to comments --- .../dataflow/internal/DataFlowPrivate.qll | 8 ++-- .../dataflow/internal/DataFlowPublic.qll | 12 +++--- .../swift/elements/expr/EnumElementExpr.qll | 38 ++++++++++++------- .../swift/elements/pattern/NamedPattern.qll | 16 +++++++- 4 files changed, 48 insertions(+), 26 deletions(-) diff --git a/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowPrivate.qll b/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowPrivate.qll index 08c69cde705..03135803784 100644 --- a/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowPrivate.qll +++ b/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowPrivate.qll @@ -563,7 +563,7 @@ predicate storeStep(Node node1, ContentSet c, Node node2) { exists(EnumElementExpr enum, int pos | node1.asExpr() = enum.getArgument(pos).getExpr() and node2.asExpr() = enum and - c.isSingleton(any(Content::EnumContent ec | ec.getField() = enum.getElement().getParam(pos))) + c.isSingleton(any(Content::EnumContent ec | ec.getParam() = enum.getElement().getParam(pos))) ) or FlowSummaryImpl::Private::Steps::summaryStoreStep(node1, c, node2) @@ -588,14 +588,14 @@ predicate readStep(Node node1, ContentSet c, Node node2) { ) or // read of an enum member via `case let .variant(v1, v2)` pattern matching - exists(Expr enumExpr, ParamDecl enumField, VarDecl boundVar | + exists(Expr enumExpr, ParamDecl enumParam, VarDecl boundVar | node1.asExpr() = enumExpr and node2.asDefinition().getSourceVariable() = boundVar and - c.isSingleton(any(Content::EnumContent ec | ec.getField() = enumField)) + c.isSingleton(any(Content::EnumContent ec | ec.getParam() = enumParam)) | exists(EnumElementPattern enumPat, NamedPattern namePat, int idx | enumPat.getMatchingExpr() = enumExpr and - enumPat.getElement().getParam(idx) = enumField and + enumPat.getElement().getParam(idx) = enumParam and namePat.getIdentityPreservingEnclosingPattern*() = enumPat.getSubPattern(idx) and namePat.getVarDecl() = boundVar ) diff --git a/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowPublic.qll b/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowPublic.qll index c468c146420..3646a90cdf1 100644 --- a/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowPublic.qll +++ b/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowPublic.qll @@ -172,17 +172,17 @@ module Content { override string toString() { result = "Tuple element at index " + index.toString() } } - /** A field of an enum element. */ + /** A parameter of an enum element. */ class EnumContent extends Content, TEnumContent { - private ParamDecl f; + private ParamDecl p; - EnumContent() { this = TEnumContent(f) } + EnumContent() { this = TEnumContent(p) } - /** Gets the declaration of the enum field. */ - ParamDecl getField() { result = f } + /** Gets the declaration of the enum parameter. */ + ParamDecl getParam() { result = p } override string toString() { - exists(EnumElementDecl d, int pos | d.getParam(pos) = f | result = d.toString() + ":" + pos) + exists(EnumElementDecl d, int pos | d.getParam(pos) = p | result = d.toString() + ":" + pos) } } } diff --git a/swift/ql/lib/codeql/swift/elements/expr/EnumElementExpr.qll b/swift/ql/lib/codeql/swift/elements/expr/EnumElementExpr.qll index da57b528056..568248cf113 100644 --- a/swift/ql/lib/codeql/swift/elements/expr/EnumElementExpr.qll +++ b/swift/ql/lib/codeql/swift/elements/expr/EnumElementExpr.qll @@ -8,14 +8,19 @@ private import codeql.swift.elements.decl.EnumElementDecl /** * An expression that constructs a case of an enum. */ -abstract class EnumElementExpr extends Expr { +class EnumElementExpr extends Expr { EnumElementDecl decl; + EnumElementExpr() { + this.(NullaryEnumElementExpr).getElement() = decl or + this.(NonNullaryEnumElementExpr).getElement() = decl + } + /** Gets the declaration of the enum element that this expression creates. */ EnumElementDecl getElement() { result = decl } /** Gets the `i`th argument passed to this enum element expression (0-based). */ - Argument getArgument(int i) { none() } + Argument getArgument(int i) { result = this.(NonNullaryEnumElementExpr).getArgument(i) } /** Gets an argument passed to this enum element expression, if any. */ final Argument getAnArgument() { result = this.getArgument(_) } @@ -24,23 +29,28 @@ abstract class EnumElementExpr extends Expr { final int getNumberOfArguments() { result = count(this.getArgument(_)) } } +/** + * An expression that refers to an enum element, either directly in the case of a nullary enum element, + * or referring to the enum element constructor in the case of a non-nullary enum element. + */ private class EnumElementLookupExpr extends MethodLookupExpr { EnumElementLookupExpr() { this.getMember() instanceof EnumElementDecl } } -private class NullaryEnumElementExpr extends EnumElementExpr instanceof EnumElementLookupExpr { - NullaryEnumElementExpr() { - this.getMember() = decl and not exists(CallExpr ce | ce.getFunction() = this) - } +/** An expression creating an enum with no arguments */ +private class NullaryEnumElementExpr extends EnumElementLookupExpr { + /** Gets the declaration of the enum element that this expression creates. */ + EnumElementDecl getElement() { this.getMember() = result } + + NullaryEnumElementExpr() { not exists(CallExpr ce | ce.getFunction() = this) } } -private class NonNullaryEnumElementExpr extends EnumElementExpr instanceof CallExpr { - NonNullaryEnumElementExpr() { - exists(EnumElementLookupExpr eele | - this.getFunction() = eele and - eele.getMember() = decl - ) - } +/** An expression creating an enum with arguments */ +private class NonNullaryEnumElementExpr extends CallExpr { + EnumElementLookupExpr eele; - override Argument getArgument(int i) { result = CallExpr.super.getArgument(i) } + /** Gets the declaration of the enum element that this expression creates. */ + EnumElementDecl getElement() { eele.getMember() = result } + + NonNullaryEnumElementExpr() { this.getFunction() = eele } } diff --git a/swift/ql/lib/codeql/swift/elements/pattern/NamedPattern.qll b/swift/ql/lib/codeql/swift/elements/pattern/NamedPattern.qll index fc8881f2dd4..07f9bdefe6c 100644 --- a/swift/ql/lib/codeql/swift/elements/pattern/NamedPattern.qll +++ b/swift/ql/lib/codeql/swift/elements/pattern/NamedPattern.qll @@ -1,11 +1,23 @@ private import codeql.swift.generated.pattern.NamedPattern private import codeql.swift.elements.decl.VarDecl +/** + * A pattern that corresponds to a fresh variable binding. + * + * For example, `x` as in `if case let .some(x) = ...` is a `NamedPattern`, + * whereas `y` as in `if case .some(y) = ...` is instead an `ExprPattern`. + */ class NamedPattern extends Generated::NamedPattern { - /** Holds if this named pattern has a corresponding `VarDecl` */ + /** + * Holds if this named pattern has a corresponding `VarDecl`. + * This will be the case as long as the variable is subsequently used. + */ predicate hasVarDecl() { exists(this.getVarDecl()) } - /** Gets the `VarDecl` bound by this named pattern, if any. */ + /** + * Gets the `VarDecl` bound by this named pattern, if any. + * This will be the case as long as the variable is subsequently used. + */ VarDecl getVarDecl() { this.getEnclosingPattern*() = result.getParentPattern().getFullyUnresolved() and result.getName() = this.getName() From a715ebe82684f195c9f311ff7f406ae230118ce5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nora=20Dimitrijevi=C4=87?= <d10c@users.noreply.github.com> Date: Wed, 15 Feb 2023 18:59:17 +0100 Subject: [PATCH 539/631] Swift: distinguish Pattern.get(Immediate)EnclosingPattern --- .../swift/controlflow/internal/Completion.qll | 4 ++-- .../swift/dataflow/internal/DataFlowPrivate.qll | 2 +- .../codeql/swift/elements/pattern/NamedPattern.qll | 2 +- .../lib/codeql/swift/elements/pattern/Pattern.qll | 13 ++++++++++--- 4 files changed, 14 insertions(+), 7 deletions(-) diff --git a/swift/ql/lib/codeql/swift/controlflow/internal/Completion.qll b/swift/ql/lib/codeql/swift/controlflow/internal/Completion.qll index e3ba2775024..aa95602fd97 100644 --- a/swift/ql/lib/codeql/swift/controlflow/internal/Completion.qll +++ b/swift/ql/lib/codeql/swift/controlflow/internal/Completion.qll @@ -185,7 +185,7 @@ private predicate switchMatching(SwitchStmt switch, CaseStmt c, AstNode ast) { ( c.getALabel() = ast or - ast.(Pattern).getEnclosingPattern+() = c.getALabel().getPattern() + ast.(Pattern).getImmediateEnclosingPattern+() = c.getALabel().getPattern() ) } @@ -216,7 +216,7 @@ predicate catchMatchingPattern(DoCatchStmt s, CaseStmt c, Pattern pattern) { exists(CaseLabelItem cli | catchMatching(s, c, cli) | cli.getPattern() = pattern or - pattern.getEnclosingPattern+() = cli.getPattern() + pattern.getImmediateEnclosingPattern+() = cli.getPattern() ) } diff --git a/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowPrivate.qll b/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowPrivate.qll index 03135803784..2bb94a2062e 100644 --- a/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowPrivate.qll +++ b/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowPrivate.qll @@ -596,7 +596,7 @@ predicate readStep(Node node1, ContentSet c, Node node2) { exists(EnumElementPattern enumPat, NamedPattern namePat, int idx | enumPat.getMatchingExpr() = enumExpr and enumPat.getElement().getParam(idx) = enumParam and - namePat.getIdentityPreservingEnclosingPattern*() = enumPat.getSubPattern(idx) and + namePat.getImmediateIdentityPreservingEnclosingPattern*() = enumPat.getSubPattern(idx) and namePat.getVarDecl() = boundVar ) ) diff --git a/swift/ql/lib/codeql/swift/elements/pattern/NamedPattern.qll b/swift/ql/lib/codeql/swift/elements/pattern/NamedPattern.qll index 07f9bdefe6c..a9964f4370b 100644 --- a/swift/ql/lib/codeql/swift/elements/pattern/NamedPattern.qll +++ b/swift/ql/lib/codeql/swift/elements/pattern/NamedPattern.qll @@ -19,7 +19,7 @@ class NamedPattern extends Generated::NamedPattern { * This will be the case as long as the variable is subsequently used. */ VarDecl getVarDecl() { - this.getEnclosingPattern*() = result.getParentPattern().getFullyUnresolved() and + this.getImmediateEnclosingPattern*() = result.getParentPattern().getFullyUnresolved() and result.getName() = this.getName() } diff --git a/swift/ql/lib/codeql/swift/elements/pattern/Pattern.qll b/swift/ql/lib/codeql/swift/elements/pattern/Pattern.qll index 63ea6adbc65..8ea4a7281b6 100644 --- a/swift/ql/lib/codeql/swift/elements/pattern/Pattern.qll +++ b/swift/ql/lib/codeql/swift/elements/pattern/Pattern.qll @@ -70,21 +70,28 @@ class Pattern extends Generated::Pattern { * Holds if this occurs as a sub-pattern of the result. */ Pattern getEnclosingPattern() { + result = this.getFullyUnresolved().(Pattern).getImmediateEnclosingPattern() + } + + /** + * Holds if this occurs as an immediate sub-pattern of the result. + */ + Pattern getImmediateEnclosingPattern() { this = result.(EnumElementPattern).getImmediateSubPattern() or this = result.(OptionalSomePattern).getImmediateSubPattern() or this = result.(TuplePattern).getImmediateElement(_) or - result = this.getIdentityPreservingEnclosingPattern() + result = this.getImmediateIdentityPreservingEnclosingPattern() } /** - * Holds if this occurs as a sub-pattern of the result + * Holds if this occurs as an immediate sub-pattern of the result * without any intervening destructurings of * complex data structures. */ - Pattern getIdentityPreservingEnclosingPattern() { + Pattern getImmediateIdentityPreservingEnclosingPattern() { this = result.(BindingPattern).getImmediateSubPattern() or this = result.(IsPattern).getImmediateSubPattern() From 7dc793855bb62960854d6bf1bedd55a168b8511a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nora=20Dimitrijevi=C4=87?= <d10c@users.noreply.github.com> Date: Thu, 16 Feb 2023 17:22:17 +0100 Subject: [PATCH 540/631] Swift: introduce Node.asPattern() --- .../lib/codeql/swift/controlflow/CfgNodes.qll | 10 ++++++++++ .../dataflow/internal/DataFlowPrivate.qll | 14 ++++++++++++++ .../dataflow/internal/DataFlowPublic.qll | 19 +++++++++++++++++++ 3 files changed, 43 insertions(+) diff --git a/swift/ql/lib/codeql/swift/controlflow/CfgNodes.qll b/swift/ql/lib/codeql/swift/controlflow/CfgNodes.qll index 2754f705fa8..b1b93a17e4d 100644 --- a/swift/ql/lib/codeql/swift/controlflow/CfgNodes.qll +++ b/swift/ql/lib/codeql/swift/controlflow/CfgNodes.qll @@ -118,6 +118,16 @@ class ExprCfgNode extends CfgNode { Expr getExpr() { result = e } } +/** A control-flow node that wraps a pattern. */ +class PatternCfgNode extends CfgNode { + Pattern p; + + PatternCfgNode() { p = this.getNode().asAstNode() } + + /** Gets the underlying pattern. */ + Pattern getPattern() { result = p } +} + /** A control-flow node that wraps a property getter. */ class PropertyGetterCfgNode extends CfgNode { override PropertyGetterElement n; diff --git a/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowPrivate.qll b/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowPrivate.qll index 2bb94a2062e..5291e20c9cd 100644 --- a/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowPrivate.qll +++ b/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowPrivate.qll @@ -40,6 +40,14 @@ private class ExprNodeImpl extends ExprNode, NodeImpl { override DataFlowCallable getEnclosingCallable() { result = TDataFlowFunc(n.getScope()) } } +private class PatternNodeImpl extends PatternNode, NodeImpl { + override Location getLocationImpl() { result = pattern.getLocation() } + + override string toStringImpl() { result = pattern.toString() } + + override DataFlowCallable getEnclosingCallable() { result = TDataFlowFunc(n.getScope()) } +} + private class SsaDefinitionNodeImpl extends SsaDefinitionNode, NodeImpl { override Location getLocationImpl() { result = def.getLocation() } @@ -63,6 +71,7 @@ private module Cached { cached newtype TNode = TExprNode(CfgNode n, Expr e) { hasExprNode(n, e) } or + TPatternNode(CfgNode n, Pattern p) { hasPatternNode(n, p) } or TSsaDefinitionNode(Ssa::Definition def) or TInoutReturnNode(ParamDecl param) { modifiableParam(param) } or TSummaryNode(FlowSummary::SummarizedCallable c, FlowSummaryImpl::Private::SummaryNodeState state) { @@ -231,6 +240,11 @@ private predicate hasExprNode(CfgNode n, Expr e) { n.(PropertyObserverCfgNode).getAssignExpr() = e } +private predicate hasPatternNode(PatternCfgNode n, Pattern p) { + n.getPattern() = p and + p = p.resolve() // no need to turn hidden-AST patterns (`let`s, parens) into data flow nodes +} + import Cached /** Holds if `n` should be hidden from path explanations. */ diff --git a/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowPublic.qll b/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowPublic.qll index 3646a90cdf1..6d3db9c04fa 100644 --- a/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowPublic.qll +++ b/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowPublic.qll @@ -37,6 +37,11 @@ class Node extends TNode { */ Expr asExpr() { none() } + /** + * Gets this node's underlying pattern, if any. + */ + Pattern asPattern() { none() } + /** * Gets this data flow node's corresponding control flow node. */ @@ -66,6 +71,20 @@ class ExprNode extends Node, TExprNode { override ControlFlowNode getCfgNode() { result = n } } +/** + * A pattern, viewed as a node in a data flow graph. + */ +class PatternNode extends Node, TPatternNode { + CfgNode n; + Pattern pattern; + + PatternNode() { this = TPatternNode(n, pattern) } + + override Pattern asPattern() { result = pattern } + + override ControlFlowNode getCfgNode() { result = n } +} + /** * The value of a parameter at function entry, viewed as a node in a data * flow graph. From 6a127264af2fccab9687db3e58611493d98940dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nora=20Dimitrijevi=C4=87?= <d10c@users.noreply.github.com> Date: Fri, 17 Feb 2023 16:06:50 +0100 Subject: [PATCH 541/631] Swift: distinguish between Pattern.get(Immediate)IdentityPreservingEnclosingPattern --- .../codeql/swift/elements/pattern/Pattern.qll | 25 +++++++++++++------ 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/swift/ql/lib/codeql/swift/elements/pattern/Pattern.qll b/swift/ql/lib/codeql/swift/elements/pattern/Pattern.qll index 8ea4a7281b6..47d11ba3a70 100644 --- a/swift/ql/lib/codeql/swift/elements/pattern/Pattern.qll +++ b/swift/ql/lib/codeql/swift/elements/pattern/Pattern.qll @@ -64,17 +64,27 @@ class Pattern extends Generated::Pattern { } /** Holds if this pattern is matched against an expression. */ - predicate hasMatchingExpr() { exists(this.getMatchingExpr()) } + final predicate hasMatchingExpr() { exists(this.getMatchingExpr()) } /** - * Holds if this occurs as a sub-pattern of the result. + * Gets the parent pattern of this pattern, if any. */ - Pattern getEnclosingPattern() { + final Pattern getEnclosingPattern() { result = this.getFullyUnresolved().(Pattern).getImmediateEnclosingPattern() } /** - * Holds if this occurs as an immediate sub-pattern of the result. + * Gets the parent pattern of this pattern, but only if + * both patterns match against the same object, which is not + * the case when destructuring a complex data structure, + * like a tuple or enum. + */ + final Pattern getIdentityPreservingEnclosingPattern() { + result = this.getFullyUnresolved().(Pattern).getImmediateIdentityPreservingEnclosingPattern() + } + + /** + * Gets the parent pattern of this pattern, if any. */ Pattern getImmediateEnclosingPattern() { this = result.(EnumElementPattern).getImmediateSubPattern() @@ -87,9 +97,10 @@ class Pattern extends Generated::Pattern { } /** - * Holds if this occurs as an immediate sub-pattern of the result - * without any intervening destructurings of - * complex data structures. + * Gets the immediate parent pattern of this pattern, but only if + * both patterns match against the same object, which is not + * the case when destructuring a complex data structure, + * like a tuple or enum. */ Pattern getImmediateIdentityPreservingEnclosingPattern() { this = result.(BindingPattern).getImmediateSubPattern() From 03122d76cef0962542570db3aadbb99142cef8f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nora=20Dimitrijevi=C4=87?= <d10c@users.noreply.github.com> Date: Tue, 21 Mar 2023 18:12:08 +0100 Subject: [PATCH 542/631] Swift: fix a bunch of MISSING dataflow test cases Optional content flow through constructors remains. --- swift/ql/lib/codeql/swift/dataflow/Ssa.qll | 16 +- .../dataflow/internal/DataFlowPrivate.qll | 59 ++- .../codeql/swift/elements/pattern/Pattern.qll | 18 +- .../dataflow/dataflow/DataFlow.expected | 233 +++++++--- .../dataflow/dataflow/LocalFlow.expected | 405 ++++++++++++------ .../dataflow/dataflow/test.swift | 14 +- .../dataflow/taint/core/LocalTaint.expected | 21 +- 7 files changed, 548 insertions(+), 218 deletions(-) diff --git a/swift/ql/lib/codeql/swift/dataflow/Ssa.qll b/swift/ql/lib/codeql/swift/dataflow/Ssa.qll index ae4b4738a64..16ff1d27924 100644 --- a/swift/ql/lib/codeql/swift/dataflow/Ssa.qll +++ b/swift/ql/lib/codeql/swift/dataflow/Ssa.qll @@ -38,9 +38,9 @@ module Ssa { // if let x5 = optional { ... } // guard let x6 = optional else { ... } // ``` - exists(Pattern pattern | + exists(NamedPattern pattern | bb.getNode(i).getNode().asAstNode() = pattern and - v.getParentPattern() = pattern and + v = pattern.getVarDecl() and certain = true ) or @@ -153,14 +153,10 @@ module Ssa { value.getNode().asAstNode() = a.getSource() ) or - exists( - VarDecl var, SsaInput::BasicBlock bb, int blockIndex, PatternBindingDecl pbd, Expr init - | - this.definesAt(var, bb, blockIndex) and - pbd.getAPattern() = bb.getNode(blockIndex).getNode().asAstNode() and - init = var.getParentInitializer() - | - value.getAst() = init + exists(SsaInput::BasicBlock bb, int blockIndex, NamedPattern np | + this.definesAt(_, bb, blockIndex) and + np = bb.getNode(blockIndex).getNode().asAstNode() and + value.getNode().asAstNode() = np ) or exists(SsaInput::BasicBlock bb, int blockIndex, ConditionElement ce, Expr init | diff --git a/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowPrivate.qll b/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowPrivate.qll index 5291e20c9cd..7a84e5c3efd 100644 --- a/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowPrivate.qll +++ b/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowPrivate.qll @@ -184,6 +184,16 @@ private module Cached { nodeFrom.asExpr() = ie.getBranch(_) ) or + // flow from Expr to Pattern + exists(Expr e, Pattern p | + nodeFrom.asExpr() = e and + nodeTo.asPattern() = p and + p.getImmediateMatchingExpr() = e + ) + or + // flow from Pattern to an identity-preserving sub-Pattern: + nodeFrom.asPattern() = nodeTo.asPattern().getIdentityPreservingEnclosingPattern() + or // flow through a flow summary (extension of `SummaryModelCsv`) FlowSummaryImpl::Private::Steps::summaryLocalStep(nodeFrom, nodeTo, true) } @@ -580,6 +590,13 @@ predicate storeStep(Node node1, ContentSet c, Node node2) { c.isSingleton(any(Content::EnumContent ec | ec.getParam() = enum.getElement().getParam(pos))) ) or + // creation of an optional via implicit conversion + exists(InjectIntoOptionalExpr e, OptionalSomeDecl someDecl | + e.convertsFrom(node1.asExpr()) and + node2 = node1 and // HACK: we should ideally have a separate Node case for the (hidden) InjectIntoOptionalExpr + c.isSingleton(any(Content::EnumContent ec | ec.getParam() = someDecl.getParam(0))) + ) + or FlowSummaryImpl::Private::Steps::summaryStoreStep(node1, c, node2) } @@ -602,18 +619,32 @@ predicate readStep(Node node1, ContentSet c, Node node2) { ) or // read of an enum member via `case let .variant(v1, v2)` pattern matching - exists(Expr enumExpr, ParamDecl enumParam, VarDecl boundVar | - node1.asExpr() = enumExpr and - node2.asDefinition().getSourceVariable() = boundVar and + exists(EnumElementPattern enumPat, ParamDecl enumParam, Pattern subPat | + node1.asPattern() = enumPat and + node2.asPattern() = subPat and c.isSingleton(any(Content::EnumContent ec | ec.getParam() = enumParam)) | - exists(EnumElementPattern enumPat, NamedPattern namePat, int idx | - enumPat.getMatchingExpr() = enumExpr and + exists(int idx | enumPat.getElement().getParam(idx) = enumParam and - namePat.getImmediateIdentityPreservingEnclosingPattern*() = enumPat.getSubPattern(idx) and - namePat.getVarDecl() = boundVar + enumPat.getSubPattern(idx) = subPat ) ) + or + // read of a tuple member via `case let (v1, v2)` pattern matching + exists(TuplePattern tupPat, int idx, Pattern subPat | + node1.asPattern() = tupPat and + node2.asPattern() = subPat and + c.isSingleton(any(Content::TupleContent tc | tc.getIndex() = idx)) + | + tupPat.getElement(idx) = subPat + ) + or + // read of an optional .some member via `let x: T = y: T?` pattern matching + exists(OptionalSomePattern pat, OptionalSomeDecl someDecl | + node1.asPattern() = pat and + node2.asPattern() = pat.getSubPattern() and + c.isSingleton(any(Content::EnumContent ec | ec.getParam() = someDecl.getParam(0))) + ) } /** @@ -631,6 +662,20 @@ predicate clearsContent(Node n, ContentSet c) { */ predicate expectsContent(Node n, ContentSet c) { none() } +/** + * The global singleton `Optional.some` enum element. + */ +private class OptionalSomeDecl extends EnumElementDecl { + OptionalSomeDecl() { + exists(EnumDecl enum | + this.getName() = "some" and + this.getDeclaringDecl() = enum and + enum.getName() = "Optional" and + enum.getModule().getName() = "Swift" + ) + } +} + private newtype TDataFlowType = TODO_DataFlowType() class DataFlowType extends TDataFlowType { diff --git a/swift/ql/lib/codeql/swift/elements/pattern/Pattern.qll b/swift/ql/lib/codeql/swift/elements/pattern/Pattern.qll index 47d11ba3a70..e0c5c580e11 100644 --- a/swift/ql/lib/codeql/swift/elements/pattern/Pattern.qll +++ b/swift/ql/lib/codeql/swift/elements/pattern/Pattern.qll @@ -20,12 +20,12 @@ private import codeql.swift.generated.ParentChild class Pattern extends Generated::Pattern { /** - * Gets the expression that this pattern is matched against, if any. + * Gets the expression that this top-level pattern is matched against, if any. * * For example, in `switch e { case p: ... }`, the pattern `p` - * is matched against the expression `e`. + * is immediately matched against the expression `e`. */ - Expr getMatchingExpr() { + Expr getImmediateMatchingExpr() { exists(ConditionElement c | c.getPattern() = this and result = c.getInitializer() @@ -40,6 +40,18 @@ class Pattern extends Generated::Pattern { v.getPattern(i) = this and result = v.getInit(i) ) + } + + /** + * Gets the expression that this pattern is matched against, if any. + * The expression and the pattern need not be top-level children of + * a pattern-matching construct, but they must match each other syntactically. + * + * For example, in `switch .some(e) { case let .some(p): ... }`, the pattern `p` + * is matched against the expression `e`. + */ + Expr getMatchingExpr() { + result = this.getImmediateMatchingExpr() or exists(Pattern p | p.getMatchingExpr() = result | this = p.(IsPattern).getSubPattern() diff --git a/swift/ql/test/library-tests/dataflow/dataflow/DataFlow.expected b/swift/ql/test/library-tests/dataflow/dataflow/DataFlow.expected index 420f8ade411..0eea49ff838 100644 --- a/swift/ql/test/library-tests/dataflow/dataflow/DataFlow.expected +++ b/swift/ql/test/library-tests/dataflow/dataflow/DataFlow.expected @@ -1,11 +1,12 @@ edges | file://:0:0:0:0 | [summary param] this in signum() : | file://:0:0:0:0 | [summary] to write: return (return) in signum() : | +| file://:0:0:0:0 | [summary param] this in signum() [some:0] : | file://:0:0:0:0 | [summary] to write: return (return) in signum() [some:0] : | | file://:0:0:0:0 | self [a, x] : | file://:0:0:0:0 | .a [x] : | | file://:0:0:0:0 | self [str] : | file://:0:0:0:0 | .str : | -| file://:0:0:0:0 | self [x] : | file://:0:0:0:0 | .x : | +| file://:0:0:0:0 | self [x, some:0] : | file://:0:0:0:0 | .x [some:0] : | | file://:0:0:0:0 | self [x] : | file://:0:0:0:0 | .x : | | file://:0:0:0:0 | value : | file://:0:0:0:0 | [post] self [x] : | -| file://:0:0:0:0 | value : | file://:0:0:0:0 | [post] self [x] : | +| file://:0:0:0:0 | value [some:0] : | file://:0:0:0:0 | [post] self [x, some:0] : | | test.swift:6:19:6:26 | call to source() : | test.swift:7:15:7:15 | t1 | | test.swift:6:19:6:26 | call to source() : | test.swift:9:15:9:15 | t1 | | test.swift:6:19:6:26 | call to source() : | test.swift:10:15:10:15 | t2 | @@ -102,9 +103,11 @@ edges | test.swift:219:13:219:15 | .a [x] : | test.swift:219:13:219:17 | .x | | 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:259:12:259:19 | call to source() [some:0] : | | test.swift:259:12:259:19 | call to source() : | test.swift:263:13:263:28 | call to optionalSource() : | -| test.swift:259:12:259:19 | call to source() : | test.swift:486:13:486:28 | call to optionalSource() : | -| test.swift:259:12:259:19 | call to source() : | test.swift:513:13:513:28 | call to optionalSource() : | +| test.swift:259:12:259:19 | call to source() [some:0] : | test.swift:263:13:263:28 | call to optionalSource() [some:0] : | +| test.swift:259:12:259:19 | call to source() [some:0] : | test.swift:486:13:486:28 | call to optionalSource() [some:0] : | +| test.swift:259:12:259:19 | call to source() [some:0] : | test.swift:513:13:513:28 | call to optionalSource() [some:0] : | | 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 | ...? : | @@ -112,11 +115,13 @@ edges | 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:263:13:263:28 | call to optionalSource() : | test.swift:285:19:285:19 | z | | test.swift:263:13:263:28 | call to optionalSource() : | test.swift:291:16:291:17 | ...? : | -| test.swift:263:13:263:28 | call to optionalSource() : | test.swift:300:15:300:15 | z1 | | test.swift:263:13:263:28 | call to optionalSource() : | test.swift:303:15:303:16 | ...! : | -| test.swift:263:13:263:28 | call to optionalSource() : | test.swift:307:19:307:19 | z | +| test.swift:263:13:263:28 | call to optionalSource() [some:0] : | test.swift:284:8:284:12 | let ...? [some:0] : | +| test.swift:263:13:263:28 | call to optionalSource() [some:0] : | test.swift:291:16:291:17 | ...? [some:0] : | +| test.swift:263:13:263:28 | call to optionalSource() [some:0] : | test.swift:298:11:298:15 | let ...? [some:0] : | +| test.swift:263:13:263:28 | call to optionalSource() [some:0] : | test.swift:306:13:306:24 | .some(...) [some:0] : | +| test.swift:263:13:263:28 | call to optionalSource() [some:0] : | test.swift:314:10:314:21 | .some(...) [some:0] : | | 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() : | @@ -124,57 +129,107 @@ edges | 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:284:8:284:12 | let ...? [some:0] : | test.swift:284:12:284:12 | z : | +| test.swift:284:12:284:12 | z : | test.swift:285:19:285:19 | z | +| test.swift:291:8:291:12 | let ...? [some:0] : | test.swift:291:12:291:12 | z : | +| test.swift:291:12:291:12 | z : | test.swift:292:19:292:19 | z | | test.swift:291:16:291:17 | ...? : | file://:0:0:0:0 | [summary param] this in signum() : | | test.swift:291:16:291:17 | ...? : | test.swift:291:16:291:26 | call to signum() : | -| test.swift:291:16:291:26 | call to signum() : | test.swift:292:19:292:19 | z | +| test.swift:291:16:291:17 | ...? [some:0] : | file://:0:0:0:0 | [summary param] this in signum() [some:0] : | +| test.swift:291:16:291:17 | ...? [some:0] : | test.swift:291:16:291:26 | call to signum() [some:0] : | +| test.swift:291:16:291:26 | call to signum() : | test.swift:291:16:291:26 | call to signum() [some:0] : | +| test.swift:291:16:291:26 | call to signum() [some:0] : | test.swift:291:8:291:12 | let ...? [some:0] : | +| test.swift:298:11:298:15 | let ...? [some:0] : | test.swift:298:15:298:15 | z1 : | +| test.swift:298:15:298:15 | z1 : | test.swift:300:15:300:15 | z1 | | test.swift:303:15:303:16 | ...! : | file://:0:0:0:0 | [summary param] this in signum() : | | test.swift:303:15:303:16 | ...! : | test.swift:303:15:303:25 | call to signum() | +| test.swift:306:13:306:24 | .some(...) [some:0] : | test.swift:306:23:306:23 | z : | +| test.swift:306:23:306:23 | z : | test.swift:307:19:307:19 | z | +| test.swift:314:10:314:21 | .some(...) [some:0] : | test.swift:314:20:314:20 | z : | +| test.swift:314:20:314:20 | z : | test.swift:315:19:315:19 | z | | test.swift:331:14:331:26 | (...) [Tuple element at index 1] : | test.swift:335:15:335:15 | t1 [Tuple element at index 1] : | | test.swift:331:18:331:25 | call to source() : | test.swift:331:14:331:26 | (...) [Tuple element at index 1] : | | test.swift:335:15:335:15 | t1 [Tuple element at index 1] : | test.swift:335:15:335:18 | .1 | | test.swift:343:5:343:5 | [post] t1 [Tuple element at index 0] : | test.swift:346:15:346:15 | t1 [Tuple element at index 0] : | | test.swift:343:12:343:19 | call to source() : | test.swift:343:5:343:5 | [post] t1 [Tuple element at index 0] : | | test.swift:346:15:346:15 | t1 [Tuple element at index 0] : | test.swift:346:15:346:18 | .0 | +| test.swift:351:14:351:45 | (...) [Tuple element at index 0] : | test.swift:353:9:353:17 | (...) [Tuple element at index 0] : | | test.swift:351:14:351:45 | (...) [Tuple element at index 0] : | test.swift:356:15:356:15 | t1 [Tuple element at index 0] : | | test.swift:351:14:351:45 | (...) [Tuple element at index 0] : | test.swift:360:15:360:15 | t2 [Tuple element at index 0] : | +| test.swift:351:14:351:45 | (...) [Tuple element at index 1] : | test.swift:353:9:353:17 | (...) [Tuple element at index 1] : | | test.swift:351:14:351:45 | (...) [Tuple element at index 1] : | test.swift:357:15:357:15 | t1 [Tuple element at index 1] : | | test.swift:351:14:351:45 | (...) [Tuple element at index 1] : | test.swift:361:15:361:15 | t2 [Tuple element at index 1] : | | test.swift:351:18:351:25 | call to source() : | test.swift:351:14:351:45 | (...) [Tuple element at index 0] : | | test.swift:351:31:351:38 | call to source() : | test.swift:351:14:351:45 | (...) [Tuple element at index 1] : | +| test.swift:353:9:353:17 | (...) [Tuple element at index 0] : | test.swift:353:10:353:10 | a : | +| test.swift:353:9:353:17 | (...) [Tuple element at index 1] : | test.swift:353:13:353:13 | b : | +| test.swift:353:10:353:10 | a : | test.swift:363:15:363:15 | a | +| test.swift:353:13:353:13 | b : | test.swift:364:15:364:15 | b | | test.swift:356:15:356:15 | t1 [Tuple element at index 0] : | test.swift:356:15:356:18 | .0 | | test.swift:357:15:357:15 | t1 [Tuple element at index 1] : | test.swift:357:15:357:18 | .1 | | test.swift:360:15:360:15 | t2 [Tuple element at index 0] : | test.swift:360:15:360:18 | .0 | | test.swift:361:15:361:15 | t2 [Tuple element at index 1] : | test.swift:361:15:361:18 | .1 | -| test.swift:398:9:398:27 | call to ... [mySingle:0] : | test.swift:400:12:400:12 | a [mySingle:0] : | -| test.swift:398:9:398:27 | call to ... [mySingle:0] : | test.swift:412:32:412:32 | a [mySingle:0] : | +| test.swift:398:9:398:27 | call to ... [mySingle:0] : | test.swift:403:10:403:25 | .mySingle(...) [mySingle:0] : | +| test.swift:398:9:398:27 | call to ... [mySingle:0] : | test.swift:412:13:412:28 | .mySingle(...) [mySingle:0] : | | test.swift:398:19:398:26 | call to source() : | test.swift:398:9:398:27 | call to ... [mySingle:0] : | -| test.swift:400:12:400:12 | a [mySingle:0] : | test.swift:403:10:403:25 | SSA def(a) : | -| test.swift:403:10:403:25 | SSA def(a) : | test.swift:404:19:404:19 | a | -| test.swift:412:13:412:28 | SSA def(x) : | test.swift:413:19:413:19 | x | -| test.swift:412:32:412:32 | a [mySingle:0] : | test.swift:412:13:412:28 | SSA def(x) : | -| test.swift:420:9:420:34 | call to ... [myPair:1] : | test.swift:422:12:422:12 | a [myPair:1] : | -| test.swift:420:9:420:34 | call to ... [myPair:1] : | test.swift:437:37:437:37 | a [myPair:1] : | +| test.swift:403:10:403:25 | .mySingle(...) [mySingle:0] : | test.swift:403:24:403:24 | a : | +| test.swift:403:24:403:24 | a : | test.swift:404:19:404:19 | a | +| test.swift:412:13:412:28 | .mySingle(...) [mySingle:0] : | test.swift:412:27:412:27 | x : | +| test.swift:412:27:412:27 | x : | test.swift:413:19:413:19 | x | +| test.swift:420:9:420:34 | call to ... [myPair:1] : | test.swift:427:10:427:30 | .myPair(...) [myPair:1] : | +| test.swift:420:9:420:34 | call to ... [myPair:1] : | test.swift:437:13:437:33 | .myPair(...) [myPair:1] : | +| test.swift:420:9:420:34 | call to ... [myPair:1] : | test.swift:442:33:442:33 | a [myPair:1] : | | test.swift:420:9:420:34 | call to ... [myPair:1] : | test.swift:471:13:471:13 | a [myPair:1] : | | test.swift:420:26:420:33 | call to source() : | test.swift:420:9:420:34 | call to ... [myPair:1] : | -| test.swift:422:12:422:12 | a [myPair:1] : | test.swift:427:10:427:30 | SSA def(b) : | -| test.swift:427:10:427:30 | SSA def(b) : | test.swift:429:19:429:19 | b | -| test.swift:437:13:437:33 | SSA def(y) : | test.swift:439:19:439:19 | y | -| test.swift:437:37:437:37 | a [myPair:1] : | test.swift:437:13:437:33 | SSA def(y) : | -| test.swift:463:13:463:39 | SSA def(x) : | test.swift:464:19:464:19 | x | -| test.swift:463:43:463:62 | call to ... [myPair:0] : | test.swift:463:13:463:39 | SSA def(x) : | +| test.swift:427:10:427:30 | .myPair(...) [myPair:1] : | test.swift:427:29:427:29 | b : | +| test.swift:427:29:427:29 | b : | test.swift:429:19:429:19 | b | +| test.swift:437:13:437:33 | .myPair(...) [myPair:1] : | test.swift:437:32:437:32 | y : | +| test.swift:437:32:437:32 | y : | test.swift:439:19:439:19 | y | +| test.swift:442:21:442:34 | call to ... [myCons:1, myPair:1] : | test.swift:452:14:452:38 | .myCons(...) [myCons:1, myPair:1] : | +| test.swift:442:21:442:34 | call to ... [myCons:1, myPair:1] : | test.swift:467:17:467:41 | .myCons(...) [myCons:1, myPair:1] : | +| test.swift:442:21:442:34 | call to ... [myCons:1, myPair:1] : | test.swift:471:16:471:16 | b [myCons:1, myPair:1] : | +| test.swift:442:33:442:33 | a [myPair:1] : | test.swift:442:21:442:34 | call to ... [myCons:1, myPair:1] : | +| test.swift:452:14:452:38 | .myCons(...) [myCons:1, myPair:1] : | test.swift:452:25:452:37 | .myPair(...) [myPair:1] : | +| test.swift:452:25:452:37 | .myPair(...) [myPair:1] : | test.swift:452:36:452:36 | c : | +| test.swift:452:36:452:36 | c : | test.swift:455:19:455:19 | c | +| test.swift:463:13:463:39 | .myPair(...) [myPair:0] : | test.swift:463:31:463:31 | x : | +| test.swift:463:31:463:31 | x : | test.swift:464:19:464:19 | x | +| test.swift:463:43:463:62 | call to ... [myPair:0] : | test.swift:463:13:463:39 | .myPair(...) [myPair:0] : | | test.swift:463:51:463:58 | call to source() : | test.swift:463:43:463:62 | call to ... [myPair:0] : | -| test.swift:471:13:471:13 | a [myPair:1] : | test.swift:472:14:472:55 | SSA def(b) : | -| test.swift:472:14:472:55 | SSA def(b) : | test.swift:474:19:474:19 | b | -| test.swift:486:13:486:28 | call to optionalSource() : | test.swift:489:19:489:19 | a | -| test.swift:509:9:509:9 | self [x] : | file://:0:0:0:0 | self [x] : | -| test.swift:509:9:509:9 | value : | file://:0:0:0:0 | value : | -| test.swift:513:13:513:28 | call to optionalSource() : | test.swift:515:12:515:12 | x : | -| test.swift:515:5:515:5 | [post] cx [x] : | test.swift:519:20:519:20 | cx [x] : | -| test.swift:515:12:515:12 | x : | test.swift:509:9:509:9 | value : | -| test.swift:515:12:515:12 | x : | test.swift:515:5:515:5 | [post] cx [x] : | -| test.swift:519:20:519:20 | cx [x] : | test.swift:509:9:509:9 | self [x] : | -| test.swift:519:20:519:20 | cx [x] : | test.swift:519:20:519:23 | .x : | -| test.swift:519:20:519:23 | .x : | test.swift:520:15:520:15 | z1 | +| test.swift:467:17:467:41 | .myCons(...) [myCons:1, myPair:1] : | test.swift:467:28:467:40 | .myPair(...) [myPair:1] : | +| test.swift:467:28:467:40 | .myPair(...) [myPair:1] : | test.swift:467:39:467:39 | c : | +| test.swift:467:39:467:39 | c : | test.swift:468:19:468:19 | c | +| test.swift:471:12:471:17 | (...) [Tuple element at index 0, myPair:1] : | test.swift:472:14:472:55 | (...) [Tuple element at index 0, myPair:1] : | +| test.swift:471:12:471:17 | (...) [Tuple element at index 1, myCons:1, myPair:1] : | test.swift:472:14:472:55 | (...) [Tuple element at index 1, myCons:1, myPair:1] : | +| test.swift:471:13:471:13 | a [myPair:1] : | test.swift:471:12:471:17 | (...) [Tuple element at index 0, myPair:1] : | +| test.swift:471:16:471:16 | b [myCons:1, myPair:1] : | test.swift:471:12:471:17 | (...) [Tuple element at index 1, myCons:1, myPair:1] : | +| test.swift:472:14:472:55 | (...) [Tuple element at index 0, myPair:1] : | test.swift:472:15:472:27 | .myPair(...) [myPair:1] : | +| test.swift:472:14:472:55 | (...) [Tuple element at index 1, myCons:1, myPair:1] : | test.swift:472:30:472:54 | .myCons(...) [myCons:1, myPair:1] : | +| test.swift:472:15:472:27 | .myPair(...) [myPair:1] : | test.swift:472:26:472:26 | b : | +| test.swift:472:26:472:26 | b : | test.swift:474:19:474:19 | b | +| test.swift:472:30:472:54 | .myCons(...) [myCons:1, myPair:1] : | test.swift:472:41:472:53 | .myPair(...) [myPair:1] : | +| test.swift:472:41:472:53 | .myPair(...) [myPair:1] : | test.swift:472:52:472:52 | e : | +| test.swift:472:52:472:52 | e : | test.swift:477:19:477:19 | e | +| test.swift:486:13:486:28 | call to optionalSource() [some:0] : | test.swift:488:8:488:12 | let ...? [some:0] : | +| test.swift:486:13:486:28 | call to optionalSource() [some:0] : | test.swift:493:19:493:19 | x [some:0] : | +| test.swift:488:8:488:12 | let ...? [some:0] : | test.swift:488:12:488:12 | a : | +| test.swift:488:12:488:12 | a : | test.swift:489:19:489:19 | a | +| test.swift:493:18:493:23 | (...) [Tuple element at index 0, some:0] : | test.swift:495:10:495:37 | (...) [Tuple element at index 0, some:0] : | +| test.swift:493:19:493:19 | x [some:0] : | test.swift:493:18:493:23 | (...) [Tuple element at index 0, some:0] : | +| test.swift:495:10:495:37 | (...) [Tuple element at index 0, some:0] : | test.swift:495:11:495:22 | .some(...) [some:0] : | +| test.swift:495:11:495:22 | .some(...) [some:0] : | test.swift:495:21:495:21 | a : | +| test.swift:495:21:495:21 | a : | test.swift:496:19:496:19 | a | +| test.swift:509:9:509:9 | self [x, some:0] : | file://:0:0:0:0 | self [x, some:0] : | +| test.swift:509:9:509:9 | value [some:0] : | file://:0:0:0:0 | value [some:0] : | +| test.swift:513:13:513:28 | call to optionalSource() [some:0] : | test.swift:515:12:515:12 | x [some:0] : | +| test.swift:515:5:515:5 | [post] cx [x, some:0] : | test.swift:519:20:519:20 | cx [x, some:0] : | +| test.swift:515:12:515:12 | x [some:0] : | test.swift:509:9:509:9 | value [some:0] : | +| test.swift:515:12:515:12 | x [some:0] : | test.swift:515:5:515:5 | [post] cx [x, some:0] : | +| test.swift:519:11:519:15 | let ...? [some:0] : | test.swift:519:15:519:15 | z1 : | +| test.swift:519:15:519:15 | z1 : | test.swift:520:15:520:15 | z1 | +| test.swift:519:20:519:20 | cx [x, some:0] : | test.swift:509:9:509:9 | self [x, some:0] : | +| test.swift:519:20:519:20 | cx [x, some:0] : | test.swift:519:20:519:23 | .x [some:0] : | +| test.swift:519:20:519:23 | .x [some:0] : | test.swift:519:11:519:15 | let ...? [some:0] : | | test.swift:526:14:526:21 | call to source() : | test.swift:526:13:526:21 | call to +(_:) | | test.swift:535:9:535:9 | self [str] : | file://:0:0:0:0 | self [str] : | | test.swift:536:10:536:13 | s : | test.swift:537:13:537:13 | s : | @@ -196,17 +251,19 @@ nodes | file://:0:0:0:0 | .a [x] : | semmle.label | .a [x] : | | file://:0:0:0:0 | .str : | semmle.label | .str : | | file://:0:0:0:0 | .x : | semmle.label | .x : | -| file://:0:0:0:0 | .x : | semmle.label | .x : | -| file://:0:0:0:0 | [post] self [x] : | semmle.label | [post] self [x] : | +| file://:0:0:0:0 | .x [some:0] : | semmle.label | .x [some:0] : | +| file://:0:0:0:0 | [post] self [x, some:0] : | semmle.label | [post] self [x, some:0] : | | file://:0:0:0:0 | [post] self [x] : | semmle.label | [post] self [x] : | | file://:0:0:0:0 | [summary param] this in signum() : | semmle.label | [summary param] this in signum() : | +| file://:0:0:0:0 | [summary param] this in signum() [some:0] : | semmle.label | [summary param] this in signum() [some:0] : | | file://:0:0:0:0 | [summary] to write: return (return) in signum() : | semmle.label | [summary] to write: return (return) in signum() : | +| file://:0:0:0:0 | [summary] to write: return (return) in signum() [some:0] : | semmle.label | [summary] to write: return (return) in signum() [some:0] : | | file://:0:0:0:0 | self [a, x] : | semmle.label | self [a, x] : | | file://:0:0:0:0 | self [str] : | semmle.label | self [str] : | -| file://:0:0:0:0 | self [x] : | semmle.label | self [x] : | +| file://:0:0:0:0 | self [x, some:0] : | semmle.label | self [x, some:0] : | | file://:0:0:0:0 | self [x] : | semmle.label | self [x] : | | file://:0:0:0:0 | value : | semmle.label | value : | -| file://:0:0:0:0 | value : | semmle.label | value : | +| file://:0:0:0:0 | value [some:0] : | semmle.label | value [some:0] : | | test.swift:6:19:6:26 | call to source() : | semmle.label | call to source() : | | test.swift:7:15:7:15 | t1 | semmle.label | t1 | | test.swift:9:15:9:15 | t1 | semmle.label | t1 | @@ -311,7 +368,9 @@ nodes | test.swift:235:13:235:15 | .source_value | semmle.label | .source_value | | 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:259:12:259:19 | call to source() [some:0] : | semmle.label | call to source() [some:0] : | | test.swift:263:13:263:28 | call to optionalSource() : | semmle.label | call to optionalSource() : | +| test.swift:263:13:263:28 | call to optionalSource() [some:0] : | semmle.label | call to optionalSource() [some:0] : | | 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() : | @@ -326,14 +385,27 @@ nodes | 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:284:8:284:12 | let ...? [some:0] : | semmle.label | let ...? [some:0] : | +| test.swift:284:12:284:12 | z : | semmle.label | z : | | test.swift:285:19:285:19 | z | semmle.label | z | +| test.swift:291:8:291:12 | let ...? [some:0] : | semmle.label | let ...? [some:0] : | +| test.swift:291:12:291:12 | z : | semmle.label | z : | | test.swift:291:16:291:17 | ...? : | semmle.label | ...? : | +| test.swift:291:16:291:17 | ...? [some:0] : | semmle.label | ...? [some:0] : | | test.swift:291:16:291:26 | call to signum() : | semmle.label | call to signum() : | +| test.swift:291:16:291:26 | call to signum() [some:0] : | semmle.label | call to signum() [some:0] : | | test.swift:292:19:292:19 | z | semmle.label | z | +| test.swift:298:11:298:15 | let ...? [some:0] : | semmle.label | let ...? [some:0] : | +| test.swift:298:15:298:15 | z1 : | semmle.label | z1 : | | test.swift:300:15:300:15 | z1 | semmle.label | z1 | | test.swift:303:15:303:16 | ...! : | semmle.label | ...! : | | test.swift:303:15:303:25 | call to signum() | semmle.label | call to signum() | +| test.swift:306:13:306:24 | .some(...) [some:0] : | semmle.label | .some(...) [some:0] : | +| test.swift:306:23:306:23 | z : | semmle.label | z : | | test.swift:307:19:307:19 | z | semmle.label | z | +| test.swift:314:10:314:21 | .some(...) [some:0] : | semmle.label | .some(...) [some:0] : | +| test.swift:314:20:314:20 | z : | semmle.label | z : | +| test.swift:315:19:315:19 | z | semmle.label | z | | test.swift:331:14:331:26 | (...) [Tuple element at index 1] : | semmle.label | (...) [Tuple element at index 1] : | | test.swift:331:18:331:25 | call to source() : | semmle.label | call to source() : | | test.swift:335:15:335:15 | t1 [Tuple element at index 1] : | semmle.label | t1 [Tuple element at index 1] : | @@ -346,6 +418,10 @@ nodes | test.swift:351:14:351:45 | (...) [Tuple element at index 1] : | semmle.label | (...) [Tuple element at index 1] : | | test.swift:351:18:351:25 | call to source() : | semmle.label | call to source() : | | test.swift:351:31:351:38 | call to source() : | semmle.label | call to source() : | +| test.swift:353:9:353:17 | (...) [Tuple element at index 0] : | semmle.label | (...) [Tuple element at index 0] : | +| test.swift:353:9:353:17 | (...) [Tuple element at index 1] : | semmle.label | (...) [Tuple element at index 1] : | +| test.swift:353:10:353:10 | a : | semmle.label | a : | +| test.swift:353:13:353:13 | b : | semmle.label | b : | | test.swift:356:15:356:15 | t1 [Tuple element at index 0] : | semmle.label | t1 [Tuple element at index 0] : | | test.swift:356:15:356:18 | .0 | semmle.label | .0 | | test.swift:357:15:357:15 | t1 [Tuple element at index 1] : | semmle.label | t1 [Tuple element at index 1] : | @@ -354,38 +430,71 @@ nodes | test.swift:360:15:360:18 | .0 | semmle.label | .0 | | test.swift:361:15:361:15 | t2 [Tuple element at index 1] : | semmle.label | t2 [Tuple element at index 1] : | | test.swift:361:15:361:18 | .1 | semmle.label | .1 | +| test.swift:363:15:363:15 | a | semmle.label | a | +| test.swift:364:15:364:15 | b | semmle.label | b | | test.swift:398:9:398:27 | call to ... [mySingle:0] : | semmle.label | call to ... [mySingle:0] : | | test.swift:398:19:398:26 | call to source() : | semmle.label | call to source() : | -| test.swift:400:12:400:12 | a [mySingle:0] : | semmle.label | a [mySingle:0] : | -| test.swift:403:10:403:25 | SSA def(a) : | semmle.label | SSA def(a) : | +| test.swift:403:10:403:25 | .mySingle(...) [mySingle:0] : | semmle.label | .mySingle(...) [mySingle:0] : | +| test.swift:403:24:403:24 | a : | semmle.label | a : | | test.swift:404:19:404:19 | a | semmle.label | a | -| test.swift:412:13:412:28 | SSA def(x) : | semmle.label | SSA def(x) : | -| test.swift:412:32:412:32 | a [mySingle:0] : | semmle.label | a [mySingle:0] : | +| test.swift:412:13:412:28 | .mySingle(...) [mySingle:0] : | semmle.label | .mySingle(...) [mySingle:0] : | +| test.swift:412:27:412:27 | x : | semmle.label | x : | | test.swift:413:19:413:19 | x | semmle.label | x | | test.swift:420:9:420:34 | call to ... [myPair:1] : | semmle.label | call to ... [myPair:1] : | | test.swift:420:26:420:33 | call to source() : | semmle.label | call to source() : | -| test.swift:422:12:422:12 | a [myPair:1] : | semmle.label | a [myPair:1] : | -| test.swift:427:10:427:30 | SSA def(b) : | semmle.label | SSA def(b) : | +| test.swift:427:10:427:30 | .myPair(...) [myPair:1] : | semmle.label | .myPair(...) [myPair:1] : | +| test.swift:427:29:427:29 | b : | semmle.label | b : | | test.swift:429:19:429:19 | b | semmle.label | b | -| test.swift:437:13:437:33 | SSA def(y) : | semmle.label | SSA def(y) : | -| test.swift:437:37:437:37 | a [myPair:1] : | semmle.label | a [myPair:1] : | +| test.swift:437:13:437:33 | .myPair(...) [myPair:1] : | semmle.label | .myPair(...) [myPair:1] : | +| test.swift:437:32:437:32 | y : | semmle.label | y : | | test.swift:439:19:439:19 | y | semmle.label | y | -| test.swift:463:13:463:39 | SSA def(x) : | semmle.label | SSA def(x) : | +| test.swift:442:21:442:34 | call to ... [myCons:1, myPair:1] : | semmle.label | call to ... [myCons:1, myPair:1] : | +| test.swift:442:33:442:33 | a [myPair:1] : | semmle.label | a [myPair:1] : | +| test.swift:452:14:452:38 | .myCons(...) [myCons:1, myPair:1] : | semmle.label | .myCons(...) [myCons:1, myPair:1] : | +| test.swift:452:25:452:37 | .myPair(...) [myPair:1] : | semmle.label | .myPair(...) [myPair:1] : | +| test.swift:452:36:452:36 | c : | semmle.label | c : | +| test.swift:455:19:455:19 | c | semmle.label | c | +| test.swift:463:13:463:39 | .myPair(...) [myPair:0] : | semmle.label | .myPair(...) [myPair:0] : | +| test.swift:463:31:463:31 | x : | semmle.label | x : | | test.swift:463:43:463:62 | call to ... [myPair:0] : | semmle.label | call to ... [myPair:0] : | | test.swift:463:51:463:58 | call to source() : | semmle.label | call to source() : | | test.swift:464:19:464:19 | x | semmle.label | x | +| test.swift:467:17:467:41 | .myCons(...) [myCons:1, myPair:1] : | semmle.label | .myCons(...) [myCons:1, myPair:1] : | +| test.swift:467:28:467:40 | .myPair(...) [myPair:1] : | semmle.label | .myPair(...) [myPair:1] : | +| test.swift:467:39:467:39 | c : | semmle.label | c : | +| test.swift:468:19:468:19 | c | semmle.label | c | +| test.swift:471:12:471:17 | (...) [Tuple element at index 0, myPair:1] : | semmle.label | (...) [Tuple element at index 0, myPair:1] : | +| test.swift:471:12:471:17 | (...) [Tuple element at index 1, myCons:1, myPair:1] : | semmle.label | (...) [Tuple element at index 1, myCons:1, myPair:1] : | | test.swift:471:13:471:13 | a [myPair:1] : | semmle.label | a [myPair:1] : | -| test.swift:472:14:472:55 | SSA def(b) : | semmle.label | SSA def(b) : | +| test.swift:471:16:471:16 | b [myCons:1, myPair:1] : | semmle.label | b [myCons:1, myPair:1] : | +| test.swift:472:14:472:55 | (...) [Tuple element at index 0, myPair:1] : | semmle.label | (...) [Tuple element at index 0, myPair:1] : | +| test.swift:472:14:472:55 | (...) [Tuple element at index 1, myCons:1, myPair:1] : | semmle.label | (...) [Tuple element at index 1, myCons:1, myPair:1] : | +| test.swift:472:15:472:27 | .myPair(...) [myPair:1] : | semmle.label | .myPair(...) [myPair:1] : | +| test.swift:472:26:472:26 | b : | semmle.label | b : | +| test.swift:472:30:472:54 | .myCons(...) [myCons:1, myPair:1] : | semmle.label | .myCons(...) [myCons:1, myPair:1] : | +| test.swift:472:41:472:53 | .myPair(...) [myPair:1] : | semmle.label | .myPair(...) [myPair:1] : | +| test.swift:472:52:472:52 | e : | semmle.label | e : | | test.swift:474:19:474:19 | b | semmle.label | b | -| test.swift:486:13:486:28 | call to optionalSource() : | semmle.label | call to optionalSource() : | +| test.swift:477:19:477:19 | e | semmle.label | e | +| test.swift:486:13:486:28 | call to optionalSource() [some:0] : | semmle.label | call to optionalSource() [some:0] : | +| test.swift:488:8:488:12 | let ...? [some:0] : | semmle.label | let ...? [some:0] : | +| test.swift:488:12:488:12 | a : | semmle.label | a : | | test.swift:489:19:489:19 | a | semmle.label | a | -| test.swift:509:9:509:9 | self [x] : | semmle.label | self [x] : | -| test.swift:509:9:509:9 | value : | semmle.label | value : | -| test.swift:513:13:513:28 | call to optionalSource() : | semmle.label | call to optionalSource() : | -| test.swift:515:5:515:5 | [post] cx [x] : | semmle.label | [post] cx [x] : | -| test.swift:515:12:515:12 | x : | semmle.label | x : | -| test.swift:519:20:519:20 | cx [x] : | semmle.label | cx [x] : | -| test.swift:519:20:519:23 | .x : | semmle.label | .x : | +| test.swift:493:18:493:23 | (...) [Tuple element at index 0, some:0] : | semmle.label | (...) [Tuple element at index 0, some:0] : | +| test.swift:493:19:493:19 | x [some:0] : | semmle.label | x [some:0] : | +| test.swift:495:10:495:37 | (...) [Tuple element at index 0, some:0] : | semmle.label | (...) [Tuple element at index 0, some:0] : | +| test.swift:495:11:495:22 | .some(...) [some:0] : | semmle.label | .some(...) [some:0] : | +| test.swift:495:21:495:21 | a : | semmle.label | a : | +| test.swift:496:19:496:19 | a | semmle.label | a | +| test.swift:509:9:509:9 | self [x, some:0] : | semmle.label | self [x, some:0] : | +| test.swift:509:9:509:9 | value [some:0] : | semmle.label | value [some:0] : | +| test.swift:513:13:513:28 | call to optionalSource() [some:0] : | semmle.label | call to optionalSource() [some:0] : | +| test.swift:515:5:515:5 | [post] cx [x, some:0] : | semmle.label | [post] cx [x, some:0] : | +| test.swift:515:12:515:12 | x [some:0] : | semmle.label | x [some:0] : | +| test.swift:519:11:519:15 | let ...? [some:0] : | semmle.label | let ...? [some:0] : | +| test.swift:519:15:519:15 | z1 : | semmle.label | z1 : | +| test.swift:519:20:519:20 | cx [x, some:0] : | semmle.label | cx [x, some:0] : | +| test.swift:519:20:519:23 | .x [some:0] : | semmle.label | .x [some:0] : | | test.swift:520:15:520:15 | z1 | semmle.label | z1 | | test.swift:526:13:526:21 | call to +(_:) | semmle.label | call to +(_:) | | test.swift:526:14:526:21 | call to source() : | semmle.label | call to source() : | @@ -434,9 +543,10 @@ subpaths | 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() : | | test.swift:291:16:291:17 | ...? : | file://:0:0:0:0 | [summary param] this in signum() : | file://:0:0:0:0 | [summary] to write: return (return) in signum() : | test.swift:291:16:291:26 | call to signum() : | +| test.swift:291:16:291:17 | ...? [some:0] : | file://:0:0:0:0 | [summary param] this in signum() [some:0] : | file://:0:0:0:0 | [summary] to write: return (return) in signum() [some:0] : | test.swift:291:16:291:26 | call to signum() [some:0] : | | test.swift:303:15:303: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:303:15:303:25 | call to signum() | -| test.swift:515:12:515:12 | x : | test.swift:509:9:509:9 | value : | file://:0:0:0:0 | [post] self [x] : | test.swift:515:5:515:5 | [post] cx [x] : | -| test.swift:519:20:519:20 | cx [x] : | test.swift:509:9:509:9 | self [x] : | file://:0:0:0:0 | .x : | test.swift:519:20:519:23 | .x : | +| test.swift:515:12:515:12 | x [some:0] : | test.swift:509:9:509:9 | value [some:0] : | file://:0:0:0:0 | [post] self [x, some:0] : | test.swift:515:5:515:5 | [post] cx [x, some:0] : | +| test.swift:519:20:519:20 | cx [x, some:0] : | test.swift:509:9:509:9 | self [x, some:0] : | file://:0:0:0:0 | .x [some:0] : | test.swift:519:20:519:23 | .x [some:0] : | | test.swift:543:20:543:28 | call to source3() : | test.swift:536:10:536:13 | s : | test.swift:537:7:537:7 | [post] self [str] : | test.swift:543:7:543:7 | [post] self [str] : | | test.swift:549:13:549:33 | call to MyClass.init(s:) [str] : | test.swift:535:9:535:9 | self [str] : | file://:0:0:0:0 | .str : | test.swift:549:13:549:35 | .str | | test.swift:549:24:549:32 | call to source3() : | test.swift:536:10:536:13 | s : | test.swift:536:5:538:5 | self[return] [str] : | test.swift:549:13:549:33 | call to MyClass.init(s:) [str] : | @@ -485,19 +595,26 @@ subpaths | test.swift:300:15:300:15 | z1 | test.swift:259:12:259:19 | call to source() : | test.swift:300:15:300:15 | z1 | result | | test.swift:303:15:303:25 | call to signum() | test.swift:259:12:259:19 | call to source() : | test.swift:303:15:303:25 | call to signum() | result | | test.swift:307:19:307:19 | z | test.swift:259:12:259:19 | call to source() : | test.swift:307:19:307:19 | z | result | +| test.swift:315:19:315:19 | z | test.swift:259:12:259:19 | call to source() : | test.swift:315:19:315:19 | z | result | | test.swift:335:15:335:18 | .1 | test.swift:331:18:331:25 | call to source() : | test.swift:335:15:335:18 | .1 | result | | test.swift:346:15:346:18 | .0 | test.swift:343:12:343:19 | call to source() : | test.swift:346:15:346:18 | .0 | result | | test.swift:356:15:356:18 | .0 | test.swift:351:18:351:25 | call to source() : | test.swift:356:15:356:18 | .0 | result | | test.swift:357:15:357:18 | .1 | test.swift:351:31:351:38 | call to source() : | test.swift:357:15:357:18 | .1 | result | | test.swift:360:15:360:18 | .0 | test.swift:351:18:351:25 | call to source() : | test.swift:360:15:360:18 | .0 | result | | test.swift:361:15:361:18 | .1 | test.swift:351:31:351:38 | call to source() : | test.swift:361:15:361:18 | .1 | result | +| test.swift:363:15:363:15 | a | test.swift:351:18:351:25 | call to source() : | test.swift:363:15:363:15 | a | result | +| test.swift:364:15:364:15 | b | test.swift:351:31:351:38 | call to source() : | test.swift:364:15:364:15 | b | result | | test.swift:404:19:404:19 | a | test.swift:398:19:398:26 | call to source() : | test.swift:404:19:404:19 | a | result | | test.swift:413:19:413:19 | x | test.swift:398:19:398:26 | call to source() : | test.swift:413:19:413:19 | x | result | | test.swift:429:19:429:19 | b | test.swift:420:26:420:33 | call to source() : | test.swift:429:19:429:19 | b | result | | test.swift:439:19:439:19 | y | test.swift:420:26:420:33 | call to source() : | test.swift:439:19:439:19 | y | result | +| test.swift:455:19:455:19 | c | test.swift:420:26:420:33 | call to source() : | test.swift:455:19:455:19 | c | result | | test.swift:464:19:464:19 | x | test.swift:463:51:463:58 | call to source() : | test.swift:464:19:464:19 | x | result | +| test.swift:468:19:468:19 | c | test.swift:420:26:420:33 | call to source() : | test.swift:468:19:468:19 | c | result | | test.swift:474:19:474:19 | b | test.swift:420:26:420:33 | call to source() : | test.swift:474:19:474:19 | b | result | +| test.swift:477:19:477:19 | e | test.swift:420:26:420:33 | call to source() : | test.swift:477:19:477:19 | e | result | | test.swift:489:19:489:19 | a | test.swift:259:12:259:19 | call to source() : | test.swift:489:19:489:19 | a | result | +| test.swift:496:19:496:19 | a | test.swift:259:12:259:19 | call to source() : | test.swift:496:19:496:19 | a | result | | test.swift:520:15:520:15 | z1 | test.swift:259:12:259:19 | call to source() : | test.swift:520:15:520:15 | z1 | result | | test.swift:526:13:526:21 | call to +(_:) | test.swift:526:14:526:21 | call to source() : | test.swift:526:13:526:21 | call to +(_:) | result | | test.swift:527:14:527:21 | call to source() | test.swift:527:14:527:21 | call to source() | test.swift:527:14:527:21 | call to source() | result | diff --git a/swift/ql/test/library-tests/dataflow/dataflow/LocalFlow.expected b/swift/ql/test/library-tests/dataflow/dataflow/LocalFlow.expected index e01df699630..516612aa964 100644 --- a/swift/ql/test/library-tests/dataflow/dataflow/LocalFlow.expected +++ b/swift/ql/test/library-tests/dataflow/dataflow/LocalFlow.expected @@ -1,5 +1,8 @@ -| 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:5:9:5:13 | ... as ... | test.swift:5:9:5:9 | t2 | +| test.swift:6:9:6:9 | SSA def(t1) | test.swift:7:15:7:15 | t1 | +| test.swift:6:9:6:9 | t1 | test.swift:6:9:6:9 | SSA def(t1) | +| test.swift:6:9:6:13 | ... as ... | test.swift:6:9:6:9 | t1 | +| test.swift:6:19:6:26 | call to source() | test.swift:6:9:6:13 | ... as ... | | test.swift:7:15:7:15 | [post] t1 | test.swift:8:10:8:10 | t1 | | test.swift:7:15:7:15 | t1 | test.swift:8:10:8:10 | t1 | | test.swift:8:5:8:10 | SSA def(t2) | test.swift:10:15:10:15 | t2 | @@ -18,8 +21,12 @@ | 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:43:9:43:9 | SSA def(t1) | test.swift:46:13:46:13 | t1 | +| test.swift:43:9:43:9 | t1 | test.swift:43:9:43:9 | SSA def(t1) | +| test.swift:43:9:43:13 | ... as ... | test.swift:43:9:43:9 | t1 | +| test.swift:43:19:43:26 | call to source() | test.swift:43:9:43:13 | ... as ... | +| test.swift:44:9:44:12 | ... as ... | test.swift:44:9:44:9 | t | +| test.swift:44:18:44:18 | 0 | test.swift:44:9:44:12 | ... as ... | | 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) | @@ -27,8 +34,10 @@ | 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:59:9:59:9 | SSA def(x) | test.swift:60:15:60:15 | x | +| test.swift:59:9:59:9 | x | test.swift:59:9:59:9 | SSA def(x) | +| test.swift:59:9:59:12 | ... as ... | test.swift:59:9:59:9 | x | +| test.swift:59:18:59:18 | 0 | test.swift:59:9:59:12 | ... as ... | | test.swift:60:15:60:15 | [post] x | test.swift:61:23:61:23 | 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 | @@ -38,16 +47,22 @@ | 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:66:9:66:9 | SSA def(temp) | test.swift:68:12:68:12 | temp | +| test.swift:66:9:66:9 | temp | test.swift:66:9:66:9 | SSA def(temp) | +| test.swift:66:9:66:15 | ... as ... | test.swift:66:9:66:9 | temp | +| test.swift:66:21:66:21 | arg1 | test.swift:66:9:66:15 | ... as ... | | 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:73:9:73:9 | SSA def(x) | test.swift:75:22:75:22 | x | +| test.swift:73:9:73:9 | x | test.swift:73:9:73:9 | SSA def(x) | +| test.swift:73:9:73:12 | ... as ... | test.swift:73:9:73:9 | x | +| test.swift:73:18:73:25 | call to source() | test.swift:73:9:73:12 | ... as ... | +| test.swift:74:9:74:9 | SSA def(y) | test.swift:75:32:75:32 | y | +| test.swift:74:9:74:9 | y | test.swift:74:9:74:9 | SSA def(y) | +| test.swift:74:9:74:12 | ... as ... | test.swift:74:9:74:9 | y | +| test.swift:74:18:74:18 | 0 | test.swift:74:9:74:12 | ... as ... | | 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 | &... | @@ -65,15 +80,19 @@ | 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:95:13:95:13 | SSA def(x) | test.swift:96:19:96:19 | x | +| test.swift:95:13:95:13 | x | test.swift:95:13:95:13 | SSA def(x) | +| test.swift:95:13:95:16 | ... as ... | test.swift:95:13:95:13 | x | +| test.swift:95:22:95:22 | 0 | test.swift:95:13:95:16 | ... as ... | | test.swift:96:19:96:19 | [post] x | test.swift:97:40:97:40 | 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 | 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:102:13:102:13 | SSA def(x) | test.swift:103:19:103:19 | x | +| test.swift:102:13:102:13 | x | test.swift:102:13:102:13 | SSA def(x) | +| test.swift:102:13:102:16 | ... as ... | test.swift:102:13:102:13 | x | +| test.swift:102:22:102:22 | 0 | test.swift:102:13:102:16 | ... as ... | | test.swift:103:19:103:19 | [post] x | test.swift:104:41:104:41 | 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 | @@ -85,25 +104,37 @@ | 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:118:9:118:9 | SSA def(x) | test.swift:119:31:119:31 | x | +| test.swift:118:9:118:9 | x | test.swift:118:9:118:9 | SSA def(x) | +| test.swift:118:9:118:12 | ... as ... | test.swift:118:9:118:9 | x | +| test.swift:118:18:118:25 | call to source() | test.swift:118:9:118:12 | ... as ... | +| test.swift:119:9:119:9 | SSA def(y) | test.swift:120:15:120:15 | y | +| test.swift:119:9:119:9 | y | test.swift:119:9:119:9 | SSA def(y) | +| test.swift:119:9:119:12 | ... as ... | test.swift:119:9:119:9 | y | +| test.swift:119:18:119:44 | call to forward(arg:lambda:) | test.swift:119:9:119:12 | ... as ... | +| test.swift:122:9:122:9 | SSA def(z) | test.swift:126:15:126:15 | z | +| test.swift:122:9:122:9 | z | test.swift:122:9:122:9 | SSA def(z) | +| test.swift:122:9:122:12 | ... as ... | test.swift:122:9:122:9 | z | +| test.swift:122:18:125:6 | call to forward(arg:lambda:) | test.swift:122:9:122:12 | ... as ... | | 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:128:9:128:9 | SSA def(clean) | test.swift:132:15:132:15 | clean | +| test.swift:128:9:128:9 | clean | test.swift:128:9:128:9 | SSA def(clean) | +| test.swift:128:9:128:16 | ... as ... | test.swift:128:9:128:9 | clean | +| test.swift:128:22:131:6 | call to forward(arg:lambda:) | test.swift:128:9:128:16 | ... as ... | +| test.swift:136:19:139:5 | { ... } | test.swift:136:9:136:9 | lambda1 | | 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:141:9:141:9 | lambda2 | test.swift:141:9:141:9 | SSA def(lambda2) | +| test.swift:141:19:144:5 | { ... } | test.swift:141:9:141:9 | 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:147:9:147:9 | lambdaSource | test.swift:147:9:147:9 | SSA def(lambdaSource) | +| test.swift:147:24:150:5 | { ... } | test.swift:147:9:147:9 | lambdaSource | | test.swift:151:15:151:15 | lambdaSource | test.swift:159:16:159:16 | lambdaSource | | 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:153:9:153:9 | lambdaSink | test.swift:153:9:153:9 | SSA def(lambdaSink) | +| test.swift:153:22:156:5 | { ... } | test.swift:153:9:153:9 | 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 | @@ -128,7 +159,8 @@ | 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 | SSA def(a) | test.swift:180:3:180:3 | a | -| test.swift:179:11:179:13 | call to A.init() | test.swift:179:7:179:7 | SSA def(a) | +| test.swift:179:7:179:7 | a | test.swift:179:7:179:7 | SSA def(a) | +| test.swift:179:11:179:13 | call to A.init() | test.swift:179:7:179:7 | 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 | SSA def(self) | test.swift:184:7:184:7 | self[return] | @@ -142,23 +174,28 @@ | 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 | SSA def(b) | test.swift:194:3:194:3 | b | -| test.swift:193:11:193:13 | call to B.init() | test.swift:193:7:193:7 | SSA def(b) | +| test.swift:193:7:193:7 | b | test.swift:193:7:193:7 | SSA def(b) | +| test.swift:193:11:193:13 | call to B.init() | test.swift:193:7:193:7 | 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 | SSA def(a) | test.swift:200:3:200:3 | a | -| test.swift:199:11:199:13 | call to A.init() | test.swift:199:7:199:7 | SSA def(a) | +| test.swift:199:7:199:7 | a | test.swift:199:7:199:7 | SSA def(a) | +| test.swift:199:11:199:13 | call to A.init() | test.swift:199:7:199:7 | 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 | SSA def(a) | test.swift:206:3:206:3 | a | -| test.swift:205:11:205:13 | call to A.init() | test.swift:205:7:205:7 | SSA def(a) | +| test.swift:205:7:205:7 | a | test.swift:205:7:205:7 | SSA def(a) | +| test.swift:205:11:205:13 | call to A.init() | test.swift:205:7:205:7 | 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 | SSA def(a) | test.swift:212:3:212:3 | a | -| test.swift:211:11:211:13 | call to A.init() | test.swift:211:7:211:7 | SSA def(a) | +| test.swift:211:7:211:7 | a | test.swift:211:7:211:7 | SSA def(a) | +| test.swift:211:11:211:13 | call to A.init() | test.swift:211:7:211:7 | 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 | SSA def(b) | test.swift:218:3:218:3 | b | -| test.swift:217:11:217:13 | call to B.init() | test.swift:217:7:217:7 | SSA def(b) | +| test.swift:217:7:217:7 | b | test.swift:217:7:217:7 | SSA def(b) | +| test.swift:217:11:217:13 | call to B.init() | test.swift:217:7:217:7 | 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 | SSA def(self) | test.swift:222:7:222:7 | self[return] | @@ -171,7 +208,8 @@ | 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 HasComputedProperty.init() | test.swift:234:7:234:7 | SSA def(a) | +| test.swift:234:7:234:7 | a | test.swift:234:7:234:7 | SSA def(a) | +| test.swift:234:11:234:31 | call to HasComputedProperty.init() | test.swift:234:7:234:7 | 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 | @@ -188,11 +226,13 @@ | 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:6:252:27 | call to DidSetSource.init(wrappedValue:) | test.swift:252:23:252:23 | x | | test.swift:252:23:252:23 | value | test.swift:252:23:252:23 | SSA def(value) | | test.swift:262:21:262:27 | SSA def(y) | test.swift:266:15:266:15 | y | | test.swift:262:21:262:27 | y | test.swift:262:21:262:27 | SSA def(y) | | test.swift:263:9:263:9 | SSA def(x) | test.swift:265:15:265:15 | x | -| test.swift:263:13:263:28 | call to optionalSource() | test.swift:263:9:263:9 | SSA def(x) | +| test.swift:263:9:263:9 | x | test.swift:263:9:263:9 | SSA def(x) | +| test.swift:263:13:263:28 | call to optionalSource() | test.swift:263:9:263:9 | x | | 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 | ...! | @@ -241,42 +281,57 @@ | 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:8:284:12 | SSA def(z) | test.swift:285:19:285:19 | z | -| test.swift:284:16:284:16 | x | test.swift:284:8:284:12 | SSA def(z) | +| test.swift:284:12:284:12 | SSA def(z) | test.swift:285:19:285:19 | z | +| test.swift:284:12:284:12 | z | test.swift:284:12:284:12 | SSA def(z) | +| test.swift:284:16:284:16 | x | test.swift:284:8:284:12 | let ...? | | test.swift:284:16:284:16 | x | test.swift:291:16:291:16 | x | -| test.swift:287:8:287:12 | SSA def(z) | test.swift:288:19:288:19 | z | -| test.swift:287:16:287:16 | y | test.swift:287:8:287:12 | SSA def(z) | +| test.swift:287:12:287:12 | SSA def(z) | test.swift:288:19:288:19 | z | +| test.swift:287:12:287:12 | z | test.swift:287:12:287:12 | SSA def(z) | +| test.swift:287:16:287:16 | y | test.swift:287:8:287:12 | let ...? | | test.swift:287:16:287:16 | y | test.swift:294:16:294:16 | y | -| test.swift:291:8:291:12 | SSA def(z) | test.swift:292:19:292:19 | z | +| test.swift:291:12:291:12 | SSA def(z) | test.swift:292:19:292:19 | z | +| test.swift:291:12:291:12 | z | test.swift:291:12:291:12 | SSA def(z) | | test.swift:291:16:291:16 | x | test.swift:291:16:291:17 | ...? | | test.swift:291:16:291:16 | x | test.swift:298:20:298:20 | x | -| test.swift:291:16:291:26 | OptionalEvaluationExpr | test.swift:291:8:291:12 | SSA def(z) | +| test.swift:291:16:291:26 | OptionalEvaluationExpr | test.swift:291:8:291:12 | let ...? | | test.swift:291:16:291:26 | call to signum() | test.swift:291:16:291:26 | OptionalEvaluationExpr | -| test.swift:294:8:294:12 | SSA def(z) | test.swift:295:19:295:19 | z | +| test.swift:294:12:294:12 | SSA def(z) | test.swift:295:19:295:19 | z | +| test.swift:294:12:294:12 | z | test.swift:294:12:294:12 | SSA def(z) | | test.swift:294:16:294:16 | y | test.swift:294:16:294:17 | ...? | | test.swift:294:16:294:16 | y | test.swift:299:20:299:20 | y | -| test.swift:294:16:294:26 | OptionalEvaluationExpr | test.swift:294:8:294:12 | SSA def(z) | +| test.swift:294:16:294:26 | OptionalEvaluationExpr | test.swift:294:8:294:12 | let ...? | | test.swift:294:16:294:26 | call to signum() | test.swift:294:16:294:26 | OptionalEvaluationExpr | -| test.swift:298:11:298:15 | SSA def(z1) | test.swift:300:15:300:15 | z1 | -| test.swift:298:20:298:20 | x | test.swift:298:11:298:15 | SSA def(z1) | +| test.swift:298:15:298:15 | SSA def(z1) | test.swift:300:15:300:15 | z1 | +| test.swift:298:15:298:15 | z1 | test.swift:298:15:298:15 | SSA def(z1) | +| test.swift:298:20:298:20 | x | test.swift:298:11:298:15 | let ...? | | test.swift:298:20:298:20 | x | test.swift:303:15:303:15 | x | -| test.swift:299:11:299:15 | SSA def(z2) | test.swift:301:15:301:15 | z2 | -| test.swift:299:20:299:20 | y | test.swift:299:11:299:15 | SSA def(z2) | +| test.swift:299:15:299:15 | SSA def(z2) | test.swift:301:15:301:15 | z2 | +| test.swift:299:15:299:15 | z2 | test.swift:299:15:299:15 | SSA def(z2) | +| test.swift:299:20:299:20 | y | test.swift:299:11:299:15 | let ...? | | test.swift:299:20:299:20 | y | test.swift:304:15:304:15 | y | | test.swift:303:15:303:15 | x | test.swift:303:15:303:16 | ...! | | test.swift:303:15:303:15 | x | test.swift:306:28:306:28 | x | | test.swift:304:15:304:15 | y | test.swift:304:15:304:16 | ...! | | test.swift:304:15:304:15 | y | test.swift:309:28:309:28 | y | -| test.swift:306:13:306:24 | SSA def(z) | test.swift:307:19:307:19 | z | -| test.swift:306:28:306:28 | x | test.swift:306:13:306:24 | SSA def(z) | +| test.swift:306:23:306:23 | SSA def(z) | test.swift:307:19:307:19 | z | +| test.swift:306:23:306:23 | z | test.swift:306:23:306:23 | SSA def(z) | +| test.swift:306:28:306:28 | x | test.swift:306:13:306:24 | .some(...) | | test.swift:306:28:306:28 | x | test.swift:313:12:313:12 | x | -| test.swift:309:13:309:24 | SSA def(z) | test.swift:310:19:310:19 | z | -| test.swift:309:28:309:28 | y | test.swift:309:13:309:24 | SSA def(z) | +| test.swift:309:23:309:23 | SSA def(z) | test.swift:310:19:310:19 | z | +| test.swift:309:23:309:23 | z | test.swift:309:23:309:23 | SSA def(z) | +| test.swift:309:28:309:28 | y | test.swift:309:13:309:24 | .some(...) | | test.swift:309:28:309:28 | y | test.swift:319:12:319:12 | y | -| test.swift:314:10:314:21 | SSA def(z) | test.swift:315:19:315:19 | z | -| test.swift:320:10:320:21 | SSA def(z) | test.swift:321:19:321:19 | z | +| test.swift:313:12:313:12 | x | test.swift:314:10:314:21 | .some(...) | +| test.swift:313:12:313:12 | x | test.swift:316:10:316:11 | .none | +| test.swift:314:20:314:20 | SSA def(z) | test.swift:315:19:315:19 | z | +| test.swift:314:20:314:20 | z | test.swift:314:20:314:20 | SSA def(z) | +| test.swift:319:12:319:12 | y | test.swift:320:10:320:21 | .some(...) | +| test.swift:319:12:319:12 | y | test.swift:322:10:322:11 | .none | +| test.swift:320:20:320:20 | SSA def(z) | test.swift:321:19:321:19 | z | +| test.swift:320:20:320:20 | z | test.swift:320:20:320:20 | SSA def(z) | | test.swift:331:9:331:9 | SSA def(t1) | test.swift:333:15:333:15 | t1 | -| test.swift:331:14:331:26 | (...) | test.swift:331:9:331:9 | SSA def(t1) | +| test.swift:331:9:331:9 | t1 | test.swift:331:9:331:9 | SSA def(t1) | +| test.swift:331:14:331:26 | (...) | test.swift:331:9:331:9 | t1 | | test.swift:333:15:333:15 | t1 | test.swift:334:15:334:15 | t1 | | test.swift:334:15:334:15 | [post] t1 | test.swift:335:15:335:15 | t1 | | test.swift:334:15:334:15 | t1 | test.swift:335:15:335:15 | t1 | @@ -295,16 +350,19 @@ | test.swift:346:15:346:15 | [post] t1 | test.swift:347:15:347:15 | t1 | | test.swift:346:15:346:15 | t1 | test.swift:347:15:347:15 | t1 | | test.swift:351:9:351:9 | SSA def(t1) | test.swift:352:14:352:14 | t1 | -| test.swift:351:14:351:45 | (...) | test.swift:351:9:351:9 | SSA def(t1) | +| test.swift:351:9:351:9 | t1 | test.swift:351:9:351:9 | SSA def(t1) | +| test.swift:351:14:351:45 | (...) | test.swift:351:9:351:9 | t1 | | test.swift:352:9:352:9 | SSA def(t2) | test.swift:359:15:359:15 | t2 | -| test.swift:352:14:352:14 | t1 | test.swift:352:9:352:9 | SSA def(t2) | +| test.swift:352:9:352:9 | t2 | test.swift:352:9:352:9 | SSA def(t2) | +| test.swift:352:14:352:14 | t1 | test.swift:352:9:352:9 | t2 | | test.swift:352:14:352:14 | t1 | test.swift:353:21:353:21 | t1 | -| test.swift:353:9:353:17 | SSA def(a) | test.swift:363:15:363:15 | a | -| test.swift:353:9:353:17 | SSA def(b) | test.swift:364:15:364:15 | b | -| test.swift:353:9:353:17 | SSA def(c) | test.swift:365:15:365:15 | c | -| test.swift:353:21:353:21 | t1 | test.swift:353:9:353:17 | SSA def(a) | -| test.swift:353:21:353:21 | t1 | test.swift:353:9:353:17 | SSA def(b) | -| test.swift:353:21:353:21 | t1 | test.swift:353:9:353:17 | SSA def(c) | +| test.swift:353:10:353:10 | SSA def(a) | test.swift:363:15:363:15 | a | +| test.swift:353:10:353:10 | a | test.swift:353:10:353:10 | SSA def(a) | +| test.swift:353:13:353:13 | SSA def(b) | test.swift:364:15:364:15 | b | +| test.swift:353:13:353:13 | b | test.swift:353:13:353:13 | SSA def(b) | +| test.swift:353:16:353:16 | SSA def(c) | test.swift:365:15:365:15 | c | +| test.swift:353:16:353:16 | c | test.swift:353:16:353:16 | SSA def(c) | +| test.swift:353:21:353:21 | t1 | test.swift:353:9:353:17 | (...) | | test.swift:353:21:353:21 | t1 | test.swift:355:15:355:15 | t1 | | test.swift:355:15:355:15 | t1 | test.swift:356:15:356:15 | t1 | | test.swift:356:15:356:15 | [post] t1 | test.swift:357:15:357:15 | t1 | @@ -316,84 +374,173 @@ | test.swift:360:15:360:15 | t2 | test.swift:361:15:361:15 | t2 | | test.swift:361:15:361:15 | [post] t2 | test.swift:362:15:362:15 | t2 | | test.swift:361:15:361:15 | t2 | test.swift:362:15:362:15 | t2 | -| test.swift:376:9:376:13 | SSA def(a) | test.swift:378:12:378:12 | a | -| test.swift:376:22:376:23 | .myNone | test.swift:376:9:376:13 | SSA def(a) | +| test.swift:376:9:376:9 | SSA def(a) | test.swift:378:12:378:12 | a | +| test.swift:376:9:376:9 | a | test.swift:376:9:376:9 | SSA def(a) | +| test.swift:376:9:376:13 | ... as ... | test.swift:376:9:376:9 | a | +| test.swift:376:22:376:23 | .myNone | test.swift:376:9:376:13 | ... as ... | +| test.swift:378:12:378:12 | a | test.swift:379:10:379:11 | .myNone | +| test.swift:378:12:378:12 | a | test.swift:381:10:381:25 | .mySingle(...) | +| test.swift:378:12:378:12 | a | test.swift:383:10:383:30 | .myPair(...) | +| test.swift:378:12:378:12 | a | test.swift:386:14:386:26 | .myCons(...) | | test.swift:378:12:378:12 | a | test.swift:390:32:390:32 | a | -| test.swift:381:10:381:25 | SSA def(a) | test.swift:382:19:382:19 | a | -| test.swift:383:10:383:30 | SSA def(a) | test.swift:384:19:384:19 | a | -| test.swift:383:10:383:30 | SSA def(b) | test.swift:385:19:385:19 | b | -| test.swift:386:14:386:26 | SSA def(a) | test.swift:387:19:387:19 | a | -| test.swift:390:13:390:28 | SSA def(x) | test.swift:391:19:391:19 | x | -| test.swift:390:32:390:32 | a | test.swift:390:13:390:28 | SSA def(x) | +| test.swift:381:24:381:24 | SSA def(a) | test.swift:382:19:382:19 | a | +| test.swift:381:24:381:24 | a | test.swift:381:24:381:24 | SSA def(a) | +| test.swift:383:22:383:22 | SSA def(a) | test.swift:384:19:384:19 | a | +| test.swift:383:22:383:22 | a | test.swift:383:22:383:22 | SSA def(a) | +| test.swift:383:29:383:29 | SSA def(b) | test.swift:385:19:385:19 | b | +| test.swift:383:29:383:29 | b | test.swift:383:29:383:29 | SSA def(b) | +| test.swift:386:10:386:26 | SSA phi(a) | test.swift:387:19:387:19 | a | +| test.swift:386:22:386:22 | SSA def(a) | test.swift:386:10:386:26 | SSA phi(a) | +| test.swift:386:22:386:22 | a | test.swift:386:22:386:22 | SSA def(a) | +| test.swift:390:27:390:27 | SSA def(x) | test.swift:391:19:391:19 | x | +| test.swift:390:27:390:27 | x | test.swift:390:27:390:27 | SSA def(x) | +| test.swift:390:32:390:32 | a | test.swift:390:13:390:28 | .mySingle(...) | | test.swift:390:32:390:32 | a | test.swift:393:37:393:37 | a | -| test.swift:393:13:393:33 | SSA def(x) | test.swift:394:19:394:19 | x | -| test.swift:393:13:393:33 | SSA def(y) | test.swift:395:19:395:19 | y | +| test.swift:393:25:393:25 | SSA def(x) | test.swift:394:19:394:19 | x | +| test.swift:393:25:393:25 | x | test.swift:393:25:393:25 | SSA def(x) | +| test.swift:393:32:393:32 | SSA def(y) | test.swift:395:19:395:19 | y | +| test.swift:393:32:393:32 | y | test.swift:393:32:393:32 | SSA def(y) | +| test.swift:393:37:393:37 | a | test.swift:393:13:393:33 | .myPair(...) | | test.swift:398:5:398:27 | SSA def(a) | test.swift:400:12:400:12 | a | | test.swift:398:9:398:27 | call to ... | test.swift:398:5:398:27 | SSA def(a) | +| test.swift:400:12:400:12 | a | test.swift:401:10:401:11 | .myNone | +| test.swift:400:12:400:12 | a | test.swift:403:10:403:25 | .mySingle(...) | +| test.swift:400:12:400:12 | a | test.swift:405:10:405:30 | .myPair(...) | +| test.swift:400:12:400:12 | a | test.swift:408:14:408:26 | .myCons(...) | | test.swift:400:12:400:12 | a | test.swift:412:32:412:32 | a | -| test.swift:403:10:403:25 | SSA def(a) | test.swift:404:19:404:19 | a | -| test.swift:405:10:405:30 | SSA def(a) | test.swift:406:19:406:19 | a | -| test.swift:405:10:405:30 | SSA def(b) | test.swift:407:19:407:19 | b | -| test.swift:408:14:408:26 | SSA def(a) | test.swift:409:19:409:19 | a | -| test.swift:412:13:412:28 | SSA def(x) | test.swift:413:19:413:19 | x | -| test.swift:412:32:412:32 | a | test.swift:412:13:412:28 | SSA def(x) | +| test.swift:403:24:403:24 | SSA def(a) | test.swift:404:19:404:19 | a | +| test.swift:403:24:403:24 | a | test.swift:403:24:403:24 | SSA def(a) | +| test.swift:405:22:405:22 | SSA def(a) | test.swift:406:19:406:19 | a | +| test.swift:405:22:405:22 | a | test.swift:405:22:405:22 | SSA def(a) | +| test.swift:405:29:405:29 | SSA def(b) | test.swift:407:19:407:19 | b | +| test.swift:405:29:405:29 | b | test.swift:405:29:405:29 | SSA def(b) | +| test.swift:408:10:408:26 | SSA phi(a) | test.swift:409:19:409:19 | a | +| test.swift:408:22:408:22 | SSA def(a) | test.swift:408:10:408:26 | SSA phi(a) | +| test.swift:408:22:408:22 | a | test.swift:408:22:408:22 | SSA def(a) | +| test.swift:412:27:412:27 | SSA def(x) | test.swift:413:19:413:19 | x | +| test.swift:412:27:412:27 | x | test.swift:412:27:412:27 | SSA def(x) | +| test.swift:412:32:412:32 | a | test.swift:412:13:412:28 | .mySingle(...) | | test.swift:412:32:412:32 | a | test.swift:415:37:415:37 | a | -| test.swift:415:13:415:33 | SSA def(x) | test.swift:416:19:416:19 | x | -| test.swift:415:13:415:33 | SSA def(y) | test.swift:417:19:417:19 | y | +| test.swift:415:25:415:25 | SSA def(x) | test.swift:416:19:416:19 | x | +| test.swift:415:25:415:25 | x | test.swift:415:25:415:25 | SSA def(x) | +| test.swift:415:32:415:32 | SSA def(y) | test.swift:417:19:417:19 | y | +| test.swift:415:32:415:32 | y | test.swift:415:32:415:32 | SSA def(y) | +| test.swift:415:37:415:37 | a | test.swift:415:13:415:33 | .myPair(...) | | test.swift:420:5:420:34 | SSA def(a) | test.swift:422:12:422:12 | a | | test.swift:420:9:420:34 | call to ... | test.swift:420:5:420:34 | SSA def(a) | +| test.swift:422:12:422:12 | a | test.swift:423:10:423:11 | .myNone | +| test.swift:422:12:422:12 | a | test.swift:425:10:425:25 | .mySingle(...) | +| test.swift:422:12:422:12 | a | test.swift:427:10:427:30 | .myPair(...) | +| test.swift:422:12:422:12 | a | test.swift:430:14:430:26 | .myCons(...) | | test.swift:422:12:422:12 | a | test.swift:434:32:434:32 | a | -| test.swift:425:10:425:25 | SSA def(a) | test.swift:426:19:426:19 | a | -| test.swift:427:10:427:30 | SSA def(a) | test.swift:428:19:428:19 | a | -| test.swift:427:10:427:30 | SSA def(b) | test.swift:429:19:429:19 | b | -| test.swift:430:14:430:26 | SSA def(a) | test.swift:431:19:431:19 | a | -| test.swift:434:13:434:28 | SSA def(x) | test.swift:435:19:435:19 | x | -| test.swift:434:32:434:32 | a | test.swift:434:13:434:28 | SSA def(x) | +| test.swift:425:24:425:24 | SSA def(a) | test.swift:426:19:426:19 | a | +| test.swift:425:24:425:24 | a | test.swift:425:24:425:24 | SSA def(a) | +| test.swift:427:22:427:22 | SSA def(a) | test.swift:428:19:428:19 | a | +| test.swift:427:22:427:22 | a | test.swift:427:22:427:22 | SSA def(a) | +| test.swift:427:29:427:29 | SSA def(b) | test.swift:429:19:429:19 | b | +| test.swift:427:29:427:29 | b | test.swift:427:29:427:29 | SSA def(b) | +| test.swift:430:10:430:26 | SSA phi(a) | test.swift:431:19:431:19 | a | +| test.swift:430:22:430:22 | SSA def(a) | test.swift:430:10:430:26 | SSA phi(a) | +| test.swift:430:22:430:22 | a | test.swift:430:22:430:22 | SSA def(a) | +| test.swift:434:27:434:27 | SSA def(x) | test.swift:435:19:435:19 | x | +| test.swift:434:27:434:27 | x | test.swift:434:27:434:27 | SSA def(x) | +| test.swift:434:32:434:32 | a | test.swift:434:13:434:28 | .mySingle(...) | | test.swift:434:32:434:32 | a | test.swift:437:37:437:37 | a | -| test.swift:437:13:437:33 | SSA def(x) | test.swift:438:19:438:19 | x | -| test.swift:437:13:437:33 | SSA def(y) | test.swift:439:19:439:19 | y | +| test.swift:437:25:437:25 | SSA def(x) | test.swift:438:19:438:19 | x | +| test.swift:437:25:437:25 | x | test.swift:437:25:437:25 | SSA def(x) | +| test.swift:437:32:437:32 | SSA def(y) | test.swift:439:19:439:19 | y | +| test.swift:437:32:437:32 | y | test.swift:437:32:437:32 | SSA def(y) | +| test.swift:437:37:437:37 | a | test.swift:437:13:437:33 | .myPair(...) | | test.swift:437:37:437:37 | a | test.swift:442:33:442:33 | a | -| test.swift:442:9:442:12 | SSA def(b) | test.swift:444:12:444:12 | b | -| test.swift:442:21:442:34 | call to ... | test.swift:442:9:442:12 | SSA def(b) | +| test.swift:442:9:442:9 | SSA def(b) | test.swift:444:12:444:12 | b | +| test.swift:442:9:442:9 | b | test.swift:442:9:442:9 | SSA def(b) | +| test.swift:442:9:442:12 | ... as ... | test.swift:442:9:442:9 | b | +| test.swift:442:21:442:34 | call to ... | test.swift:442:9:442:12 | ... as ... | | test.swift:442:33:442:33 | [post] a | test.swift:471:13:471:13 | a | | test.swift:442:33:442:33 | a | test.swift:471:13:471:13 | a | +| test.swift:444:12:444:12 | b | test.swift:445:10:445:11 | .myNone | +| test.swift:444:12:444:12 | b | test.swift:447:10:447:25 | .mySingle(...) | +| test.swift:444:12:444:12 | b | test.swift:449:10:449:30 | .myPair(...) | +| test.swift:444:12:444:12 | b | test.swift:452:14:452:38 | .myCons(...) | +| test.swift:444:12:444:12 | b | test.swift:456:14:456:26 | .myCons(...) | | test.swift:444:12:444:12 | b | test.swift:467:45:467:45 | b | -| test.swift:447:10:447:25 | SSA def(a) | test.swift:448:19:448:19 | a | -| test.swift:449:10:449:30 | SSA def(a) | test.swift:450:19:450:19 | a | -| test.swift:449:10:449:30 | SSA def(b) | test.swift:451:19:451:19 | b | -| test.swift:452:14:452:38 | SSA def(a) | test.swift:453:19:453:19 | a | -| test.swift:452:14:452:38 | SSA def(b) | test.swift:454:19:454:19 | b | -| test.swift:452:14:452:38 | SSA def(c) | test.swift:455:19:455:19 | c | -| test.swift:456:14:456:26 | SSA def(a) | test.swift:457:19:457:19 | a | -| test.swift:460:13:460:28 | SSA def(x) | test.swift:461:19:461:19 | x | -| test.swift:460:32:460:57 | call to ... | test.swift:460:13:460:28 | SSA def(x) | -| test.swift:463:13:463:39 | SSA def(x) | test.swift:464:19:464:19 | x | -| test.swift:463:13:463:39 | SSA def(y) | test.swift:465:19:465:19 | y | -| test.swift:467:17:467:41 | SSA def(c) | test.swift:468:19:468:19 | c | -| test.swift:467:45:467:45 | b | test.swift:467:17:467:41 | SSA def(c) | +| test.swift:447:24:447:24 | SSA def(a) | test.swift:448:19:448:19 | a | +| test.swift:447:24:447:24 | a | test.swift:447:24:447:24 | SSA def(a) | +| test.swift:449:22:449:22 | SSA def(a) | test.swift:450:19:450:19 | a | +| test.swift:449:22:449:22 | a | test.swift:449:22:449:22 | SSA def(a) | +| test.swift:449:29:449:29 | SSA def(b) | test.swift:451:19:451:19 | b | +| test.swift:449:29:449:29 | b | test.swift:449:29:449:29 | SSA def(b) | +| test.swift:452:10:452:38 | SSA phi(a) | test.swift:453:19:453:19 | a | +| test.swift:452:10:452:38 | SSA phi(b) | test.swift:454:19:454:19 | b | +| test.swift:452:10:452:38 | SSA phi(c) | test.swift:455:19:455:19 | c | +| test.swift:452:22:452:22 | SSA def(a) | test.swift:452:10:452:38 | SSA phi(a) | +| test.swift:452:22:452:22 | a | test.swift:452:22:452:22 | SSA def(a) | +| test.swift:452:33:452:33 | SSA def(b) | test.swift:452:10:452:38 | SSA phi(b) | +| test.swift:452:33:452:33 | b | test.swift:452:33:452:33 | SSA def(b) | +| test.swift:452:36:452:36 | SSA def(c) | test.swift:452:10:452:38 | SSA phi(c) | +| test.swift:452:36:452:36 | c | test.swift:452:36:452:36 | SSA def(c) | +| test.swift:456:10:456:26 | SSA phi(a) | test.swift:457:19:457:19 | a | +| test.swift:456:22:456:22 | SSA def(a) | test.swift:456:10:456:26 | SSA phi(a) | +| test.swift:456:22:456:22 | a | test.swift:456:22:456:22 | SSA def(a) | +| test.swift:460:27:460:27 | SSA def(x) | test.swift:461:19:461:19 | x | +| test.swift:460:27:460:27 | x | test.swift:460:27:460:27 | SSA def(x) | +| test.swift:460:32:460:57 | call to ... | test.swift:460:13:460:28 | .mySingle(...) | +| test.swift:463:31:463:31 | SSA def(x) | test.swift:464:19:464:19 | x | +| test.swift:463:31:463:31 | x | test.swift:463:31:463:31 | SSA def(x) | +| test.swift:463:38:463:38 | SSA def(y) | test.swift:465:19:465:19 | y | +| test.swift:463:38:463:38 | y | test.swift:463:38:463:38 | SSA def(y) | +| test.swift:463:43:463:62 | call to ... | test.swift:463:13:463:39 | .myPair(...) | +| test.swift:467:13:467:41 | SSA phi(c) | test.swift:468:19:468:19 | c | +| test.swift:467:39:467:39 | SSA def(c) | test.swift:467:13:467:41 | SSA phi(c) | +| test.swift:467:39:467:39 | c | test.swift:467:39:467:39 | SSA def(c) | +| test.swift:467:45:467:45 | b | test.swift:467:17:467:41 | .myCons(...) | | test.swift:467:45:467:45 | b | test.swift:471:16:471:16 | b | -| test.swift:472:14:472:55 | SSA def(a) | test.swift:473:19:473:19 | a | -| test.swift:472:14:472:55 | SSA def(b) | test.swift:474:19:474:19 | b | -| test.swift:472:14:472:55 | SSA def(c) | test.swift:475:19:475:19 | c | -| test.swift:472:14:472:55 | SSA def(d) | test.swift:476:19:476:19 | d | -| test.swift:472:14:472:55 | SSA def(e) | test.swift:477:19:477:19 | e | +| test.swift:471:12:471:17 | (...) | test.swift:472:14:472:55 | (...) | +| test.swift:471:12:471:17 | (...) | test.swift:478:5:478:5 | _ | +| test.swift:472:10:472:55 | SSA phi(a) | test.swift:473:19:473:19 | a | +| test.swift:472:10:472:55 | SSA phi(b) | test.swift:474:19:474:19 | b | +| test.swift:472:10:472:55 | SSA phi(c) | test.swift:475:19:475:19 | c | +| test.swift:472:10:472:55 | SSA phi(d) | test.swift:476:19:476:19 | d | +| test.swift:472:10:472:55 | SSA phi(e) | test.swift:477:19:477:19 | e | +| test.swift:472:23:472:23 | SSA def(a) | test.swift:472:10:472:55 | SSA phi(a) | +| test.swift:472:23:472:23 | a | test.swift:472:23:472:23 | SSA def(a) | +| test.swift:472:26:472:26 | SSA def(b) | test.swift:472:10:472:55 | SSA phi(b) | +| test.swift:472:26:472:26 | b | test.swift:472:26:472:26 | SSA def(b) | +| test.swift:472:38:472:38 | SSA def(c) | test.swift:472:10:472:55 | SSA phi(c) | +| test.swift:472:38:472:38 | c | test.swift:472:38:472:38 | SSA def(c) | +| test.swift:472:49:472:49 | SSA def(d) | test.swift:472:10:472:55 | SSA phi(d) | +| test.swift:472:49:472:49 | d | test.swift:472:49:472:49 | SSA def(d) | +| test.swift:472:52:472:52 | SSA def(e) | test.swift:472:10:472:55 | SSA phi(e) | +| test.swift:472:52:472:52 | e | test.swift:472:52:472:52 | SSA def(e) | | test.swift:485:21:485:27 | SSA def(y) | test.swift:488:27:488:27 | y | | test.swift:485:21:485:27 | SSA def(y) | test.swift:493:22:493:22 | y | | test.swift:485:21:485:27 | y | test.swift:485:21:485:27 | SSA def(y) | | test.swift:486:9:486:9 | SSA def(x) | test.swift:488:16:488:16 | x | -| test.swift:486:13:486:28 | call to optionalSource() | test.swift:486:9:486:9 | SSA def(x) | -| test.swift:488:8:488:12 | SSA def(a) | test.swift:489:19:489:19 | a | -| test.swift:488:16:488:16 | x | test.swift:488:8:488:12 | SSA def(a) | +| test.swift:486:9:486:9 | x | test.swift:486:9:486:9 | SSA def(x) | +| test.swift:486:13:486:28 | call to optionalSource() | test.swift:486:9:486:9 | x | +| test.swift:488:12:488:12 | SSA def(a) | test.swift:488:27:488:27 | SSA phi(a) | +| test.swift:488:12:488:12 | a | test.swift:488:12:488:12 | SSA def(a) | +| test.swift:488:16:488:16 | x | test.swift:488:8:488:12 | let ...? | | test.swift:488:16:488:16 | x | test.swift:493:19:493:19 | x | -| test.swift:488:19:488:23 | SSA def(b) | test.swift:490:19:490:19 | b | -| test.swift:488:27:488:27 | y | test.swift:488:19:488:23 | SSA def(b) | +| test.swift:488:23:488:23 | SSA def(b) | test.swift:490:19:490:19 | b | +| test.swift:488:23:488:23 | b | test.swift:488:23:488:23 | SSA def(b) | +| test.swift:488:27:488:27 | SSA phi(a) | test.swift:489:19:489:19 | a | +| test.swift:488:27:488:27 | y | test.swift:488:19:488:23 | let ...? | | test.swift:488:27:488:27 | y | test.swift:493:22:493:22 | y | | test.swift:493:9:493:9 | SSA def(tuple1) | test.swift:494:12:494:12 | tuple1 | -| test.swift:493:18:493:23 | (...) | test.swift:493:9:493:9 | SSA def(tuple1) | -| test.swift:495:10:495:37 | SSA def(a) | test.swift:496:19:496:19 | a | -| test.swift:495:10:495:37 | SSA def(b) | test.swift:497:19:497:19 | b | -| test.swift:502:8:502:17 | SSA def(x) | test.swift:503:19:503:19 | x | -| test.swift:502:8:502:17 | SSA def(y) | test.swift:504:19:504:19 | y | +| test.swift:493:9:493:9 | tuple1 | test.swift:493:9:493:9 | SSA def(tuple1) | +| test.swift:493:18:493:23 | (...) | test.swift:493:9:493:9 | tuple1 | +| test.swift:494:12:494:12 | tuple1 | test.swift:495:10:495:37 | (...) | +| test.swift:494:12:494:12 | tuple1 | test.swift:498:5:498:5 | _ | +| test.swift:495:21:495:21 | SSA def(a) | test.swift:496:19:496:19 | a | +| test.swift:495:21:495:21 | a | test.swift:495:21:495:21 | SSA def(a) | +| test.swift:495:35:495:35 | SSA def(b) | test.swift:497:19:497:19 | b | +| test.swift:495:35:495:35 | b | test.swift:495:35:495:35 | SSA def(b) | +| test.swift:502:13:502:13 | SSA def(x) | test.swift:503:19:503:19 | x | +| test.swift:502:13:502:13 | x | test.swift:502:13:502:13 | SSA def(x) | +| test.swift:502:16:502:16 | SSA def(y) | test.swift:504:19:504:19 | y | +| test.swift:502:16:502:16 | y | test.swift:502:16:502:16 | SSA def(y) | +| test.swift:502:21:502:29 | call to source2() | test.swift:502:8:502:17 | let ...? | | test.swift:508:7:508:7 | SSA def(self) | test.swift:508:7:508:7 | self[return] | | test.swift:508:7:508:7 | SSA def(self) | test.swift:508:7:508:7 | self[return] | | test.swift:508:7:508:7 | self | test.swift:508:7:508:7 | SSA def(self) | @@ -405,19 +552,24 @@ | test.swift:512:33:512:39 | SSA def(y) | test.swift:517:12:517:12 | y | | test.swift:512:33:512:39 | y | test.swift:512:33:512:39 | SSA def(y) | | test.swift:513:9:513:9 | SSA def(x) | test.swift:515:12:515:12 | x | -| test.swift:513:13:513:28 | call to optionalSource() | test.swift:513:9:513:9 | SSA def(x) | +| test.swift:513:9:513:9 | x | test.swift:513:9:513:9 | SSA def(x) | +| test.swift:513:13:513:28 | call to optionalSource() | test.swift:513:9:513:9 | x | | test.swift:514:9:514:9 | SSA def(cx) | test.swift:515:5:515:5 | cx | -| test.swift:514:14:514:16 | call to C.init() | test.swift:514:9:514:9 | SSA def(cx) | +| test.swift:514:9:514:9 | cx | test.swift:514:9:514:9 | SSA def(cx) | +| test.swift:514:14:514:16 | call to C.init() | test.swift:514:9:514:9 | cx | | test.swift:515:5:515:5 | [post] cx | test.swift:519:20:519:20 | cx | | test.swift:515:5:515:5 | cx | test.swift:519:20:519:20 | cx | | test.swift:516:9:516:9 | SSA def(cy) | test.swift:517:5:517:5 | cy | -| test.swift:516:14:516:16 | call to C.init() | test.swift:516:9:516:9 | SSA def(cy) | +| test.swift:516:9:516:9 | cy | test.swift:516:9:516:9 | SSA def(cy) | +| test.swift:516:14:516:16 | call to C.init() | test.swift:516:9:516:9 | cy | | test.swift:517:5:517:5 | [post] cy | test.swift:521:20:521:20 | cy | | test.swift:517:5:517:5 | cy | test.swift:521:20:521:20 | cy | -| test.swift:519:11:519:15 | SSA def(z1) | test.swift:520:15:520:15 | z1 | -| test.swift:519:20:519:23 | .x | test.swift:519:11:519:15 | SSA def(z1) | -| test.swift:521:11:521:15 | SSA def(z2) | test.swift:522:15:522:15 | z2 | -| test.swift:521:20:521:23 | .x | test.swift:521:11:521:15 | SSA def(z2) | +| test.swift:519:15:519:15 | SSA def(z1) | test.swift:520:15:520:15 | z1 | +| test.swift:519:15:519:15 | z1 | test.swift:519:15:519:15 | SSA def(z1) | +| test.swift:519:20:519:23 | .x | test.swift:519:11:519:15 | let ...? | +| test.swift:521:15:521:15 | SSA def(z2) | test.swift:522:15:522:15 | z2 | +| test.swift:521:15:521:15 | z2 | test.swift:521:15:521:15 | SSA def(z2) | +| test.swift:521:20:521:23 | .x | test.swift:521:11:521:15 | let ...? | | test.swift:526:14:526:21 | call to source() | test.swift:526:13:526:21 | call to +(_:) | | test.swift:534:7:534:7 | SSA def(self) | test.swift:534:7:534:7 | self[return] | | test.swift:534:7:534:7 | self | test.swift:534:7:534:7 | SSA def(self) | @@ -446,5 +598,6 @@ | test.swift:554:27:554:38 | SSA def(n) | test.swift:554:3:554:40 | n[return] | | test.swift:554:31:554:38 | call to source() | test.swift:554:27:554:38 | SSA def(n) | | test.swift:560:7:560:7 | SSA def(n) | test.swift:561:36:561:36 | n | -| test.swift:560:11:560:11 | 0 | test.swift:560:7:560:7 | SSA def(n) | +| test.swift:560:7:560:7 | n | test.swift:560:7:560:7 | SSA def(n) | +| test.swift:560:11:560:11 | 0 | test.swift:560:7:560:7 | n | | test.swift:561:36:561:36 | n | test.swift:561:35:561:36 | &... | diff --git a/swift/ql/test/library-tests/dataflow/dataflow/test.swift b/swift/ql/test/library-tests/dataflow/dataflow/test.swift index 3d8511fd7cb..8fa01273d20 100644 --- a/swift/ql/test/library-tests/dataflow/dataflow/test.swift +++ b/swift/ql/test/library-tests/dataflow/dataflow/test.swift @@ -312,7 +312,7 @@ func test_optionals(y: Int?) { switch x { case .some(let z): - sink(arg: z) // $ MISSING: flow=259 + sink(arg: z) // $ flow=259 case .none: () } @@ -360,8 +360,8 @@ func testTuples2() { sink(arg: t2.x) // $ flow=351 sink(arg: t2.y) // $ flow=351 sink(arg: t2.z) - sink(arg: a) // $ MISSING: flow=351 - sink(arg: b) // $ MISSING: flow=351 + sink(arg: a) // $ flow=351 + sink(arg: b) // $ flow=351 sink(arg: c) } @@ -452,7 +452,7 @@ func testEnums() { case let .myCons(a, .myPair(b, c)): sink(arg: a) sink(arg: b) - sink(arg: c) // $ MISSING: flow=420 + sink(arg: c) // $ flow=420 case let .myCons(a, _): sink(arg: a) } @@ -465,7 +465,7 @@ func testEnums() { sink(arg: y) } if case let .myCons(_, .myPair(_, c)) = b { - sink(arg: c) // $ MISSING: flow=420 + sink(arg: c) // $ flow=420 } switch (a, b) { @@ -474,7 +474,7 @@ func testEnums() { sink(arg: b) // $ flow=420 sink(arg: c) sink(arg: d) - sink(arg: e) // $ MISSING: flow=420 + sink(arg: e) // $ flow=420 default: () } @@ -493,7 +493,7 @@ func testOptionals2(y: Int?) { let tuple1 = (x, y) switch tuple1 { case (.some(let a), .some(let b)): - sink(arg: a) // $ MISSING: flow=259 + sink(arg: a) // $ flow=259 sink(arg: b) default: () diff --git a/swift/ql/test/library-tests/dataflow/taint/core/LocalTaint.expected b/swift/ql/test/library-tests/dataflow/taint/core/LocalTaint.expected index 6f593ea2cb5..3d58e8a40ad 100644 --- a/swift/ql/test/library-tests/dataflow/taint/core/LocalTaint.expected +++ b/swift/ql/test/library-tests/dataflow/taint/core/LocalTaint.expected @@ -32,7 +32,8 @@ | simple.swift:32:13:32:20 | call to source() | simple.swift:32:13:32:25 | ... .&*(_:_:) ... | | simple.swift:32:25:32:25 | 2 | simple.swift:32:13:32:25 | ... .&*(_:_:) ... | | simple.swift:36:7:36:7 | SSA def(a) | simple.swift:37:13:37:13 | a | -| simple.swift:36:11:36:11 | 0 | simple.swift:36:7:36:7 | SSA def(a) | +| simple.swift:36:7:36:7 | a | simple.swift:36:7:36:7 | SSA def(a) | +| simple.swift:36:11:36:11 | 0 | simple.swift:36:7:36:7 | a | | simple.swift:37:13:37:13 | [post] a | simple.swift:38:3:38:3 | a | | simple.swift:37:13:37:13 | a | simple.swift:38:3:38:3 | a | | simple.swift:38:3:38:3 | &... | simple.swift:39:13:39:13 | a | @@ -54,7 +55,8 @@ | simple.swift:44:3:44:7 | SSA def(a) | simple.swift:45:13:45:13 | a | | simple.swift:44:7:44:7 | 0 | simple.swift:44:3:44:7 | SSA def(a) | | simple.swift:47:7:47:7 | SSA def(b) | simple.swift:48:3:48:3 | b | -| simple.swift:47:11:47:11 | 128 | simple.swift:47:7:47:7 | SSA def(b) | +| simple.swift:47:7:47:7 | b | simple.swift:47:7:47:7 | SSA def(b) | +| simple.swift:47:11:47:11 | 128 | simple.swift:47:7:47:7 | b | | simple.swift:48:3:48:3 | &... | simple.swift:49:13:49:13 | b | | simple.swift:48:3:48:3 | [post] &... | simple.swift:49:13:49:13 | b | | simple.swift:48:3:48:3 | b | simple.swift:48:3:48:3 | &... | @@ -66,7 +68,8 @@ | simple.swift:50:3:50:3 | b | simple.swift:50:3:50:3 | &... | | simple.swift:50:8:50:8 | 1 | simple.swift:50:3:50:3 | &... | | simple.swift:53:7:53:7 | SSA def(c) | simple.swift:54:3:54:3 | c | -| simple.swift:53:11:53:11 | 10 | simple.swift:53:7:53:7 | SSA def(c) | +| simple.swift:53:7:53:7 | c | simple.swift:53:7:53:7 | SSA def(c) | +| simple.swift:53:11:53:11 | 10 | simple.swift:53:7:53:7 | c | | simple.swift:54:3:54:3 | &... | simple.swift:55:13:55:13 | c | | simple.swift:54:3:54:3 | [post] &... | simple.swift:55:13:55:13 | c | | simple.swift:54:3:54:3 | c | simple.swift:54:3:54:3 | &... | @@ -78,7 +81,8 @@ | simple.swift:56:3:56:3 | c | simple.swift:56:3:56:3 | &... | | simple.swift:56:8:56:8 | 2 | simple.swift:56:3:56:3 | &... | | simple.swift:59:7:59:7 | SSA def(d) | simple.swift:60:3:60:3 | d | -| simple.swift:59:11:59:11 | 100 | simple.swift:59:7:59:7 | SSA def(d) | +| simple.swift:59:7:59:7 | d | simple.swift:59:7:59:7 | SSA def(d) | +| simple.swift:59:11:59:11 | 100 | simple.swift:59:7:59:7 | d | | simple.swift:60:3:60:3 | &... | simple.swift:61:13:61:13 | d | | simple.swift:60:3:60:3 | [post] &... | simple.swift:61:13:61:13 | d | | simple.swift:60:3:60:3 | d | simple.swift:60:3:60:3 | &... | @@ -90,7 +94,8 @@ | simple.swift:62:3:62:3 | d | simple.swift:62:3:62:3 | &... | | simple.swift:62:8:62:8 | 2 | simple.swift:62:3:62:3 | &... | | simple.swift:65:7:65:7 | SSA def(e) | simple.swift:66:3:66:3 | e | -| simple.swift:65:11:65:11 | 1000 | simple.swift:65:7:65:7 | SSA def(e) | +| simple.swift:65:7:65:7 | e | simple.swift:65:7:65:7 | SSA def(e) | +| simple.swift:65:11:65:11 | 1000 | simple.swift:65:7:65:7 | e | | simple.swift:66:3:66:3 | &... | simple.swift:67:13:67:13 | e | | simple.swift:66:3:66:3 | [post] &... | simple.swift:67:13:67:13 | e | | simple.swift:66:3:66:3 | e | simple.swift:66:3:66:3 | &... | @@ -168,7 +173,8 @@ | stringinterpolation.swift:13:47:13:47 | &... | stringinterpolation.swift:13:47:13:47 | [post] &... | | stringinterpolation.swift:13:47:13:47 | [post] &... | stringinterpolation.swift:13:23:13:23 | TapExpr | | stringinterpolation.swift:18:6:18:6 | SSA def(p1) | stringinterpolation.swift:19:2:19:2 | p1 | -| stringinterpolation.swift:18:11:18:24 | call to MyStringPair.init() | stringinterpolation.swift:18:6:18:6 | SSA def(p1) | +| stringinterpolation.swift:18:6:18:6 | p1 | stringinterpolation.swift:18:6:18:6 | SSA def(p1) | +| stringinterpolation.swift:18:11:18:24 | call to MyStringPair.init() | stringinterpolation.swift:18:6:18:6 | p1 | | stringinterpolation.swift:19:2:19:2 | [post] p1 | stringinterpolation.swift:20:2:20:2 | p1 | | stringinterpolation.swift:19:2:19:2 | p1 | stringinterpolation.swift:20:2:20:2 | p1 | | stringinterpolation.swift:20:2:20:2 | [post] p1 | stringinterpolation.swift:22:21:22:21 | p1 | @@ -246,7 +252,8 @@ | stringinterpolation.swift:24:24:24:24 | &... | stringinterpolation.swift:24:24:24:24 | [post] &... | | stringinterpolation.swift:24:24:24:24 | [post] &... | stringinterpolation.swift:24:12:24:12 | TapExpr | | stringinterpolation.swift:26:6:26:6 | SSA def(p2) | stringinterpolation.swift:27:2:27:2 | p2 | -| stringinterpolation.swift:26:11:26:24 | call to MyStringPair.init() | stringinterpolation.swift:26:6:26:6 | SSA def(p2) | +| stringinterpolation.swift:26:6:26:6 | p2 | stringinterpolation.swift:26:6:26:6 | SSA def(p2) | +| stringinterpolation.swift:26:11:26:24 | call to MyStringPair.init() | stringinterpolation.swift:26:6:26:6 | p2 | | stringinterpolation.swift:27:2:27:2 | [post] p2 | stringinterpolation.swift:28:2:28:2 | p2 | | stringinterpolation.swift:27:2:27:2 | p2 | stringinterpolation.swift:28:2:28:2 | p2 | | stringinterpolation.swift:28:2:28:2 | [post] p2 | stringinterpolation.swift:30:21:30:21 | p2 | From 41b283c07c9f37f89fcc5c63b1f7669225392c54 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nora=20Dimitrijevi=C4=87?= <d10c@users.noreply.github.com> Date: Mon, 27 Mar 2023 18:50:57 +0200 Subject: [PATCH 543/631] Swift: add `.some` enum content to `init?` calls Again, this is hacky; we don't distinguish rigorously between an optional value and its content (similar to how it was before enum content flow). --- .../swift/dataflow/internal/DataFlowPrivate.qll | 11 ++++++++++- 1 file changed, 10 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 7a84e5c3efd..2becda54662 100644 --- a/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowPrivate.qll +++ b/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowPrivate.qll @@ -590,13 +590,22 @@ predicate storeStep(Node node1, ContentSet c, Node node2) { c.isSingleton(any(Content::EnumContent ec | ec.getParam() = enum.getElement().getParam(pos))) ) or - // creation of an optional via implicit conversion + // creation of an optional via implicit conversion, + // i.e. from `f(x)` where `x: T` into `f(.some(x))` where the context `f` expects a `T?`. exists(InjectIntoOptionalExpr e, OptionalSomeDecl someDecl | e.convertsFrom(node1.asExpr()) and node2 = node1 and // HACK: we should ideally have a separate Node case for the (hidden) InjectIntoOptionalExpr c.isSingleton(any(Content::EnumContent ec | ec.getParam() = someDecl.getParam(0))) ) or + // creation of an optional by returning from an optional initializer (`init?`) + exists(ConstructorDecl init, OptionalType initRetType, OptionalSomeDecl someDecl | + node1.asExpr().(CallExpr).getStaticTarget() = init and + node2 = node1 and // HACK: again, we should ideally have a separate Node case here, and not reuse the CallExpr + c.isSingleton(any(Content::EnumContent ec | ec.getParam() = someDecl.getParam(0))) and + init.getInterfaceType().(FunctionType).getResult().(FunctionType).getResult() = initRetType + ) + or FlowSummaryImpl::Private::Steps::summaryStoreStep(node1, c, node2) } From 239e14b71a3eaa8c89aa4beec316b326b2987cfd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nora=20Dimitrijevi=C4=87?= <d10c@users.noreply.github.com> Date: Mon, 27 Mar 2023 23:48:37 +0200 Subject: [PATCH 544/631] Swift: fix QLdoc check for EnumElementExpr.qll --- swift/ql/lib/codeql/swift/elements/expr/EnumElementExpr.qll | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/swift/ql/lib/codeql/swift/elements/expr/EnumElementExpr.qll b/swift/ql/lib/codeql/swift/elements/expr/EnumElementExpr.qll index 568248cf113..4da1297820b 100644 --- a/swift/ql/lib/codeql/swift/elements/expr/EnumElementExpr.qll +++ b/swift/ql/lib/codeql/swift/elements/expr/EnumElementExpr.qll @@ -1,3 +1,7 @@ +/** + * `EnumElementExpr` is an expression that constructs a case of an enum. + */ + private import codeql.swift.elements.expr.Expr private import codeql.swift.elements.expr.Argument private import codeql.swift.elements.expr.CallExpr From 724d97eabb21bd4cf64b682917aef3ed64611d05 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen <mathiasvp@github.com> Date: Mon, 27 Mar 2023 21:23:55 +0100 Subject: [PATCH 545/631] C++: Make sign analysis aware of unsigned'ness and accept test changes. --- .../semmle/code/cpp/semantic/SemanticExprSpecific.qll | 4 +++- .../code/cpp/semantic/analysis/SignAnalysisCommon.qll | 10 ++++++++++ .../ir/range-analysis/SimpleRangeAnalysis_tests.cpp | 8 ++++---- 3 files changed, 17 insertions(+), 5 deletions(-) diff --git a/cpp/ql/lib/experimental/semmle/code/cpp/semantic/SemanticExprSpecific.qll b/cpp/ql/lib/experimental/semmle/code/cpp/semantic/SemanticExprSpecific.qll index 9d69154baa4..f12466b4785 100644 --- a/cpp/ql/lib/experimental/semmle/code/cpp/semantic/SemanticExprSpecific.qll +++ b/cpp/ql/lib/experimental/semmle/code/cpp/semantic/SemanticExprSpecific.qll @@ -216,7 +216,9 @@ module SemanticExprConfig { TSsaInstruction(IR::Instruction instr) { instr.hasMemoryResult() } or TSsaOperand(IR::Operand op) { op.isDefinitionInexact() } or TSsaPointerArithmeticGuard(ValueNumber instr) { - exists(Guard g, IR::Operand use | use = instr.getAUse() | + exists(Guard g, IR::Operand use | + use = instr.getAUse() and use.getIRType() instanceof IR::IRAddressType + | g.comparesLt(use, _, _, _, _) or g.comparesLt(_, use, _, _, _) or g.comparesEq(use, _, _, _, _) or diff --git a/cpp/ql/lib/experimental/semmle/code/cpp/semantic/analysis/SignAnalysisCommon.qll b/cpp/ql/lib/experimental/semmle/code/cpp/semantic/analysis/SignAnalysisCommon.qll index 4e2c0cb98c8..ec3427558d4 100644 --- a/cpp/ql/lib/experimental/semmle/code/cpp/semantic/analysis/SignAnalysisCommon.qll +++ b/cpp/ql/lib/experimental/semmle/code/cpp/semantic/analysis/SignAnalysisCommon.qll @@ -198,6 +198,16 @@ module SignAnalysis<DeltaSig D, UtilSig<D> Utils> { } } + /** An expression of an unsigned type. */ + private class UnsignedExpr extends FlowSignExpr { + UnsignedExpr() { Utils::getTrackedType(this) instanceof SemUnsignedIntegerType } + + override Sign getSignRestriction() { + result = TPos() or + result = TZero() + } + } + pragma[nomagic] private predicate binaryExprOperands(SemBinaryExpr binary, SemExpr left, SemExpr right) { binary.getLeftOperand() = left and binary.getRightOperand() = right diff --git a/cpp/ql/test/library-tests/ir/range-analysis/SimpleRangeAnalysis_tests.cpp b/cpp/ql/test/library-tests/ir/range-analysis/SimpleRangeAnalysis_tests.cpp index 520e656691a..f39d19f85b9 100644 --- a/cpp/ql/test/library-tests/ir/range-analysis/SimpleRangeAnalysis_tests.cpp +++ b/cpp/ql/test/library-tests/ir/range-analysis/SimpleRangeAnalysis_tests.cpp @@ -318,7 +318,7 @@ int test_mult01(int a, int b) { int r = a*b; // -143 .. 253 range(r); total += r; - range(total); // $ range=">=... * ...+0" + range(total); // $ MISSING: range=">=... * ...+0" } if (3 <= a && a <= 11 && -13 <= b && b <= 0) { range(a); // $ range=<=11 range=>=3 @@ -366,7 +366,7 @@ int test_mult02(int a, int b) { int r = a*b; // -143 .. 253 range(r); total += r; - range(total); // $ range=">=... * ...+0" + range(total); // $ MISSING: range=">=... * ...+0" } if (0 <= a && a <= 11 && -13 <= b && b <= 0) { range(a); // $ range=<=11 range=>=0 @@ -461,7 +461,7 @@ int test_mult04(int a, int b) { int r = a*b; // -391 .. 221 range(r); total += r; - range(total); // $ range="<=... * ...+0" + range(total); // $ MISSING: range="<=... * ...+0" } if (-17 <= a && a <= 0 && -13 <= b && b <= 0) { range(a); // $ range=<=0 range=>=-17 @@ -509,7 +509,7 @@ int test_mult05(int a, int b) { int r = a*b; // -391 .. 221 range(r); total += r; - range(total); // $ range="<=... * ...+0" + range(total); // $ MISSING: range="<=... * ...+0" } if (-17 <= a && a <= -2 && -13 <= b && b <= 0) { range(a); // $ range=<=-2 range=>=-17 From 99c6111b05a5343b9934785c6ccb080a354b3bf3 Mon Sep 17 00:00:00 2001 From: Jeroen Ketema <jketema@github.com> Date: Fri, 24 Mar 2023 11:51:38 +0100 Subject: [PATCH 546/631] C++: Add support for bounded modulus operations --- .../semantic/analysis/RangeAnalysisStage.qll | 29 +++++++++++++++++++ .../SimpleRangeAnalysis_tests.cpp | 27 +++++++++++++---- 2 files changed, 50 insertions(+), 6 deletions(-) diff --git a/cpp/ql/lib/experimental/semmle/code/cpp/semantic/analysis/RangeAnalysisStage.qll b/cpp/ql/lib/experimental/semmle/code/cpp/semantic/analysis/RangeAnalysisStage.qll index 2fb13cc8414..0364f42e544 100644 --- a/cpp/ql/lib/experimental/semmle/code/cpp/semantic/analysis/RangeAnalysisStage.qll +++ b/cpp/ql/lib/experimental/semmle/code/cpp/semantic/analysis/RangeAnalysisStage.qll @@ -1039,6 +1039,28 @@ module RangeStage<DeltaSig D, BoundSig<D> Bounds, LangSig<D> LangParam, UtilSig< or b = bRight and origdelta = odRight and reason = rRight and bLeft instanceof SemZeroBound ) + or + exists( + SemRemExpr rem, SemZeroBound b1, SemZeroBound b2, D::Delta d_max, D::Delta d1, D::Delta d2, + boolean fbe1, boolean fbe2, D::Delta od1, D::Delta od2, SemReason r1, SemReason r2 + | + rem = e and + boundedRemExpr(rem, b1, true, d1, fbe1, od1, r1) and + boundedRemExpr(rem, b2, false, d2, fbe2, od2, r2) and + ( + if D::toFloat(d1).abs() > D::toFloat(d2).abs() + then ( + b = b1 and d_max = d1 and fromBackEdge = fbe1 and origdelta = od1 and reason = r1 + ) else ( + b = b2 and d_max = d2 and fromBackEdge = fbe2 and origdelta = od2 and reason = r2 + ) + ) and + ( + upper = true and delta = D::fromFloat(D::toFloat(d_max).abs() - 1) + or + upper = false and delta = D::fromFloat(-D::toFloat(d_max).abs() + 1) + ) + ) ) } @@ -1065,4 +1087,11 @@ module RangeStage<DeltaSig D, BoundSig<D> Bounds, LangSig<D> LangParam, UtilSig< bounded(add.getRightOperand(), b, delta, upper, fromBackEdge, origdelta, reason) ) } + + private predicate boundedRemExpr( + SemRemExpr rem, SemZeroBound b, boolean upper, D::Delta delta, boolean fromBackEdge, + D::Delta origdelta, SemReason reason + ) { + bounded(rem.getRightOperand(), b, delta, upper, fromBackEdge, origdelta, reason) + } } diff --git a/cpp/ql/test/library-tests/ir/range-analysis/SimpleRangeAnalysis_tests.cpp b/cpp/ql/test/library-tests/ir/range-analysis/SimpleRangeAnalysis_tests.cpp index 89b81e2829b..f87b1fb103a 100644 --- a/cpp/ql/test/library-tests/ir/range-analysis/SimpleRangeAnalysis_tests.cpp +++ b/cpp/ql/test/library-tests/ir/range-analysis/SimpleRangeAnalysis_tests.cpp @@ -18,20 +18,20 @@ int test2(struct List* p) { int count = 0; for (; p; p = p->next) { count = (count+1) % 10; - range(count); // $ range=<=9 + range(count); // $ range=>=-9 range=<=9 } - range(count); // $ range=<=9 + range(count); // $ range=>=-9 range=<=9 return count; } int test3(struct List* p) { int count = 0; for (; p; p = p->next) { - range(count++); // $ range=<=9 + range(count++); // $ range=>=-9 range=<=9 count = count % 10; - range(count); // $ range=<=9 + range(count); // $ range=>=-9 range=<=9 } - range(count); // $ range=<=9 + range(count); // $ range=>=-9 range=<=9 return count; } @@ -960,7 +960,22 @@ void guard_bound_out_of_range(void) { void test_mod(int s) { int s2 = s % 5; - range(s2); // $ range=<=4 // -4 .. 4 + range(s2); // $ range=>=-4 range=<=4 +} + +void test_mod_neg(int s) { + int s2 = s % -5; + range(s2); // $ range=>=-4 range=<=4 +} + +void test_mod_ternary(int s, bool b) { + int s2 = s % (b ? 5 : 500); + range(s2); // $ range=>=-499 range=<=499 +} + +void test_mod_ternary2(int s, bool b1, bool b2) { + int s2 = s % (b1 ? (b2 ? 5 : -5000) : -500000); + range(s2); // $ range=>=-499999 range=<=499999 } void exit(int); From 930305501363d3623155596f2965433ad792139f Mon Sep 17 00:00:00 2001 From: Jeroen Ketema <jketema@github.com> Date: Fri, 24 Mar 2023 17:09:23 +0100 Subject: [PATCH 547/631] C++: Address review comment --- .../code/cpp/semantic/analysis/RangeAnalysisStage.qll | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/cpp/ql/lib/experimental/semmle/code/cpp/semantic/analysis/RangeAnalysisStage.qll b/cpp/ql/lib/experimental/semmle/code/cpp/semantic/analysis/RangeAnalysisStage.qll index 0364f42e544..d2c5c812c35 100644 --- a/cpp/ql/lib/experimental/semmle/code/cpp/semantic/analysis/RangeAnalysisStage.qll +++ b/cpp/ql/lib/experimental/semmle/code/cpp/semantic/analysis/RangeAnalysisStage.qll @@ -1054,12 +1054,11 @@ module RangeStage<DeltaSig D, BoundSig<D> Bounds, LangSig<D> LangParam, UtilSig< ) else ( b = b2 and d_max = d2 and fromBackEdge = fbe2 and origdelta = od2 and reason = r2 ) - ) and - ( - upper = true and delta = D::fromFloat(D::toFloat(d_max).abs() - 1) - or - upper = false and delta = D::fromFloat(-D::toFloat(d_max).abs() + 1) ) + | + upper = true and delta = D::fromFloat(D::toFloat(d_max).abs() - 1) + or + upper = false and delta = D::fromFloat(-D::toFloat(d_max).abs() + 1) ) ) } From 12da4f7814a1823d0278142c0cb367204dd9b853 Mon Sep 17 00:00:00 2001 From: Jeroen Ketema <jketema@github.com> Date: Tue, 28 Mar 2023 00:31:18 +0200 Subject: [PATCH 548/631] C++: Address review comment --- .../semmle/code/cpp/semantic/analysis/RangeAnalysisStage.qll | 2 ++ 1 file changed, 2 insertions(+) diff --git a/cpp/ql/lib/experimental/semmle/code/cpp/semantic/analysis/RangeAnalysisStage.qll b/cpp/ql/lib/experimental/semmle/code/cpp/semantic/analysis/RangeAnalysisStage.qll index d2c5c812c35..2cd13a63c4d 100644 --- a/cpp/ql/lib/experimental/semmle/code/cpp/semantic/analysis/RangeAnalysisStage.qll +++ b/cpp/ql/lib/experimental/semmle/code/cpp/semantic/analysis/RangeAnalysisStage.qll @@ -1045,6 +1045,8 @@ module RangeStage<DeltaSig D, BoundSig<D> Bounds, LangSig<D> LangParam, UtilSig< boolean fbe1, boolean fbe2, D::Delta od1, D::Delta od2, SemReason r1, SemReason r2 | rem = e and + not (upper = true and semPositive(rem.getRightOperand())) and + not (upper = true and semPositive(rem.getLeftOperand())) and boundedRemExpr(rem, b1, true, d1, fbe1, od1, r1) and boundedRemExpr(rem, b2, false, d2, fbe2, od2, r2) and ( From 2573efa358825ad75b86cdf4253907343ad325a7 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 28 Mar 2023 00:17:02 +0000 Subject: [PATCH 549/631] Add changed framework coverage reports --- java/documentation/library-coverage/coverage.csv | 12 +++++------- java/documentation/library-coverage/coverage.rst | 4 ++-- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/java/documentation/library-coverage/coverage.csv b/java/documentation/library-coverage/coverage.csv index 16fbae8673a..d5df48676e6 100644 --- a/java/documentation/library-coverage/coverage.csv +++ b/java/documentation/library-coverage/coverage.csv @@ -33,17 +33,15 @@ freemarker.cache,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,,,,,,,,, freemarker.template,7,,,,,,,,,,,,,,,,,,,,,,,,,,,,,7,,,,,,,,,,,, groovy.lang,26,,,,,,26,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, groovy.util,5,,,,,,5,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -hudson.model,4,,1,,2,,,,,,,,,,,,,1,,1,,,,,,,,,,,,,,,,,,,,,1, -hudson.os,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1, -hudson.remoting,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1, -hudson.util,4,,1,,3,,,,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,,1, +hudson,44,,16,,19,,,,,,,,,,,,,6,,17,,,,,,,,,,,,,2,,,,,,,,16, io.netty.bootstrap,3,,,,,,,,,,,,,,,,,3,,,,,,,,,,,,,,,,,,,,,,,, -io.netty.channel,9,,,,,,,,,,,,,,,,,9,,,,,,,,,,,,,,,,,,,,,,,, -io.netty.handler.codec.http,3,,1,,,,,,,,,,,,,,,2,,1,,,,,,,,,,,,,,,,,,,,,1, +io.netty.buffer,,,207,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,130,77 +io.netty.channel,9,2,,,,,,,,,,,,,,,,9,,,,,,,,,,,,,,,,,,,,,,2,, +io.netty.handler.codec,3,13,260,,,,,,,,,,,,,,,2,,1,,,,,,,,,,,,,,,,,,,,13,144,116 io.netty.handler.ssl,2,,,,,,,,,,,,,,,,,,,2,,,,,,,,,,,,,,,,,,,,,, io.netty.handler.stream,1,,,,,,,,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,,, io.netty.resolver,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1, -io.netty.util.internal,2,,2,,1,,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,,,,2, +io.netty.util,2,,23,,1,,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,,,,21,2 jakarta.faces.context,2,7,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,2,,,,7,, jakarta.json,,,123,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,100,23 jakarta.ws.rs.client,1,,,,,,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,,,,, diff --git a/java/documentation/library-coverage/coverage.rst b/java/documentation/library-coverage/coverage.rst index 512c073d1fc..973ffad9f13 100644 --- a/java/documentation/library-coverage/coverage.rst +++ b/java/documentation/library-coverage/coverage.rst @@ -22,6 +22,6 @@ Java framework & library support Java extensions,"``javax.*``, ``jakarta.*``",63,611,34,1,,4,,1,1,2 Kotlin Standard Library,``kotlin*``,,1835,12,10,,,,,,2 `Spring <https://spring.io/>`_,``org.springframework.*``,29,480,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.thoughtworks.xstream``, ``com.unboundid.ldap.sdk``, ``com.zaxxer.hikari``, ``flexjson``, ``freemarker.cache``, ``freemarker.template``, ``groovy.lang``, ``groovy.util``, ``hudson.model``, ``hudson.os``, ``hudson.remoting``, ``hudson.util``, ``io.netty.bootstrap``, ``io.netty.channel``, ``io.netty.handler.codec.http``, ``io.netty.handler.ssl``, ``io.netty.handler.stream``, ``io.netty.resolver``, ``io.netty.util.internal``, ``javafx.scene.web``, ``jodd.json``, ``net.sf.saxon.s9api``, ``ognl``, ``okhttp3``, ``org.apache.commons.codec``, ``org.apache.commons.compress.archivers.tar``, ``org.apache.commons.jelly``, ``org.apache.commons.jexl2``, ``org.apache.commons.jexl3``, ``org.apache.commons.logging``, ``org.apache.commons.ognl``, ``org.apache.directory.ldap.client.api``, ``org.apache.hadoop.hive.metastore``, ``org.apache.hive.hcatalog.templeton``, ``org.apache.ibatis.jdbc``, ``org.apache.log4j``, ``org.apache.shiro.codec``, ``org.apache.shiro.jndi``, ``org.apache.tools.ant``, ``org.apache.tools.zip``, ``org.apache.velocity.app``, ``org.apache.velocity.runtime``, ``org.codehaus.cargo.container.installer``, ``org.codehaus.groovy.control``, ``org.dom4j``, ``org.geogebra.web.full.main``, ``org.hibernate``, ``org.jdbi.v3.core``, ``org.jooq``, ``org.kohsuke.stapler``, ``org.mvel2``, ``org.openjdk.jmh.runner.options``, ``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,314,328,12,,,18,18,,28 - Totals,,217,8544,1647,150,6,10,113,33,1,113 + 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.thoughtworks.xstream``, ``com.unboundid.ldap.sdk``, ``com.zaxxer.hikari``, ``flexjson``, ``freemarker.cache``, ``freemarker.template``, ``groovy.lang``, ``groovy.util``, ``hudson``, ``io.netty.bootstrap``, ``io.netty.buffer``, ``io.netty.channel``, ``io.netty.handler.codec``, ``io.netty.handler.ssl``, ``io.netty.handler.stream``, ``io.netty.resolver``, ``io.netty.util``, ``javafx.scene.web``, ``jodd.json``, ``net.sf.saxon.s9api``, ``ognl``, ``okhttp3``, ``org.apache.commons.codec``, ``org.apache.commons.compress.archivers.tar``, ``org.apache.commons.jelly``, ``org.apache.commons.jexl2``, ``org.apache.commons.jexl3``, ``org.apache.commons.logging``, ``org.apache.commons.ognl``, ``org.apache.directory.ldap.client.api``, ``org.apache.hadoop.hive.metastore``, ``org.apache.hive.hcatalog.templeton``, ``org.apache.ibatis.jdbc``, ``org.apache.log4j``, ``org.apache.shiro.codec``, ``org.apache.shiro.jndi``, ``org.apache.tools.ant``, ``org.apache.tools.zip``, ``org.apache.velocity.app``, ``org.apache.velocity.runtime``, ``org.codehaus.cargo.container.installer``, ``org.codehaus.groovy.control``, ``org.dom4j``, ``org.geogebra.web.full.main``, ``org.hibernate``, ``org.jdbi.v3.core``, ``org.jooq``, ``org.kohsuke.stapler``, ``org.mvel2``, ``org.openjdk.jmh.runner.options``, ``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``",75,813,364,26,,,18,18,,33 + Totals,,232,9043,1683,164,6,10,113,33,1,118 From b5c66c514e7d693b741756ebd6d0fe67cf35e281 Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen <aschackmull@github.com> Date: Tue, 28 Mar 2023 09:52:05 +0200 Subject: [PATCH 550/631] Java: Support double-recursive range analysis bounds for addition. --- .../code/java/dataflow/RangeAnalysis.qll | 74 ++++++++++++------- 1 file changed, 48 insertions(+), 26 deletions(-) diff --git a/java/ql/lib/semmle/code/java/dataflow/RangeAnalysis.qll b/java/ql/lib/semmle/code/java/dataflow/RangeAnalysis.qll index aeb79ee99e1..95153b58043 100644 --- a/java/ql/lib/semmle/code/java/dataflow/RangeAnalysis.qll +++ b/java/ql/lib/semmle/code/java/dataflow/RangeAnalysis.qll @@ -421,32 +421,6 @@ private predicate boundFlowStep(Expr e2, Expr e1, int delta, boolean upper) { delta = 0 and (upper = true or upper = false) or - exists(Expr x | - e2.(AddExpr).hasOperands(e1, x) - or - exists(AssignAddExpr add | add = e2 | - add.getDest() = e1 and add.getRhs() = x - or - add.getDest() = x and add.getRhs() = e1 - ) - | - // `x instanceof ConstantIntegerExpr` is covered by valueFlowStep - not x instanceof ConstantIntegerExpr and - not e1 instanceof ConstantIntegerExpr and - if strictlyPositiveIntegralExpr(x) - then upper = false and delta = 1 - else - if positive(x) - then upper = false and delta = 0 - else - if strictlyNegativeIntegralExpr(x) - then upper = true and delta = -1 - else - if negative(x) - then upper = true and delta = 0 - else none() - ) - or exists(Expr x | exists(SubExpr sub | e2 = sub and @@ -896,6 +870,20 @@ private predicate bounded( or upper = false and delta = d1.minimum(d2) ) + or + exists( + Bound b1, Bound b2, int d1, int d2, boolean fbe1, boolean fbe2, int od1, int od2, Reason r1, + Reason r2 + | + boundedAddition(e, upper, b1, true, d1, fbe1, od1, r1) and + boundedAddition(e, upper, b2, false, d2, fbe2, od2, r2) and + delta = d1 + d2 and + fromBackEdge = fbe1.booleanOr(fbe2) + | + b = b1 and origdelta = od1 and reason = r1 and b2 instanceof ZeroBound + or + b = b2 and origdelta = od2 and reason = r2 and b1 instanceof ZeroBound + ) } private predicate boundedConditionalExpr( @@ -904,3 +892,37 @@ private predicate boundedConditionalExpr( ) { bounded(cond.getBranchExpr(branch), b, delta, upper, fromBackEdge, origdelta, reason) } + +private predicate nonConstAdd(Expr add, Expr operand, boolean isLeft) { + exists(Expr other | + add.(AddExpr).getLeftOperand() = operand and + add.(AddExpr).getRightOperand() = other and + isLeft = true + or + add.(AddExpr).getLeftOperand() = other and + add.(AddExpr).getRightOperand() = operand and + isLeft = false + or + add.(AssignAddExpr).getDest() = operand and + add.(AssignAddExpr).getRhs() = other and + isLeft = true + or + add.(AssignAddExpr).getDest() = other and + add.(AssignAddExpr).getRhs() = operand and + isLeft = false + | + // `ConstantIntegerExpr` is covered by valueFlowStep + not other instanceof ConstantIntegerExpr and + not operand instanceof ConstantIntegerExpr + ) +} + +private predicate boundedAddition( + Expr add, boolean upper, Bound b, boolean isLeft, int delta, boolean fromBackEdge, int origdelta, + Reason reason +) { + exists(Expr op | + nonConstAdd(add, op, isLeft) and + bounded(op, b, delta, upper, fromBackEdge, origdelta, reason) + ) +} From a5b1677cca29ed94cf84dd530ca4249114d3010f Mon Sep 17 00:00:00 2001 From: Asger F <asgerf@github.com> Date: Tue, 28 Mar 2023 10:03:07 +0200 Subject: [PATCH 551/631] Update docs/codeql/codeql-language-guides/customizing-library-models-for-javascript.rst Co-authored-by: Andrew Eisenberg <aeisenberg@github.com> --- .../customizing-library-models-for-javascript.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/codeql/codeql-language-guides/customizing-library-models-for-javascript.rst b/docs/codeql/codeql-language-guides/customizing-library-models-for-javascript.rst index 8ddf9ac8f70..3241a9a1420 100644 --- a/docs/codeql/codeql-language-guides/customizing-library-models-for-javascript.rst +++ b/docs/codeql/codeql-language-guides/customizing-library-models-for-javascript.rst @@ -30,7 +30,7 @@ The CodeQL library for JavaScript exposes the following extensible predicates: - **typeModel**\(type1, type2, path) - **summaryModel**\(type, path, input, output, kind) -TODO: mention how to actually load the data extension and/or link to page about data extensions. +See the [CLI documentation for how to load and use data extensions in a CodeQL evaluation run](https://docs.google.com/document/d/14IYCHX8wWuU-HTvJ2gPSdXQKHKYbWCHQKOgn8oLaa80/edit#heading=h.m0v53lpi6w2n) (internal access required). We'll explain how to use these using a few examples, and provide some reference material at the end of this article. From d406b051fc2c9df1b6a65a81a6396692e9776a87 Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen <aschackmull@github.com> Date: Tue, 28 Mar 2023 10:04:21 +0200 Subject: [PATCH 552/631] Dataflow: Remove accidentally exposed predicates. --- .../lib/semmle/code/cpp/dataflow/internal/DataFlowImpl1.qll | 5 +++-- .../lib/semmle/code/cpp/dataflow/internal/DataFlowImpl2.qll | 5 +++-- .../lib/semmle/code/cpp/dataflow/internal/DataFlowImpl3.qll | 5 +++-- .../lib/semmle/code/cpp/dataflow/internal/DataFlowImpl4.qll | 5 +++-- .../semmle/code/cpp/dataflow/internal/DataFlowImplLocal.qll | 5 +++-- .../semmle/code/cpp/ir/dataflow/internal/DataFlowImpl1.qll | 5 +++-- .../semmle/code/cpp/ir/dataflow/internal/DataFlowImpl2.qll | 5 +++-- .../semmle/code/cpp/ir/dataflow/internal/DataFlowImpl3.qll | 5 +++-- .../semmle/code/cpp/ir/dataflow/internal/DataFlowImpl4.qll | 5 +++-- .../semmle/code/csharp/dataflow/internal/DataFlowImpl1.qll | 5 +++-- .../semmle/code/csharp/dataflow/internal/DataFlowImpl2.qll | 5 +++-- .../semmle/code/csharp/dataflow/internal/DataFlowImpl3.qll | 5 +++-- .../semmle/code/csharp/dataflow/internal/DataFlowImpl4.qll | 5 +++-- .../semmle/code/csharp/dataflow/internal/DataFlowImpl5.qll | 5 +++-- .../dataflow/internal/DataFlowImplForContentDataFlow.qll | 5 +++-- go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl1.qll | 5 +++-- go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl2.qll | 5 +++-- .../dataflow/internal/DataFlowImplForStringsNewReplacer.qll | 5 +++-- .../lib/semmle/code/java/dataflow/internal/DataFlowImpl1.qll | 5 +++-- .../lib/semmle/code/java/dataflow/internal/DataFlowImpl2.qll | 5 +++-- .../lib/semmle/code/java/dataflow/internal/DataFlowImpl3.qll | 5 +++-- .../lib/semmle/code/java/dataflow/internal/DataFlowImpl4.qll | 5 +++-- .../lib/semmle/code/java/dataflow/internal/DataFlowImpl5.qll | 5 +++-- .../lib/semmle/code/java/dataflow/internal/DataFlowImpl6.qll | 5 +++-- .../semmle/python/dataflow/new/internal/DataFlowImpl1.qll | 5 +++-- .../semmle/python/dataflow/new/internal/DataFlowImpl2.qll | 5 +++-- .../semmle/python/dataflow/new/internal/DataFlowImpl3.qll | 5 +++-- .../semmle/python/dataflow/new/internal/DataFlowImpl4.qll | 5 +++-- .../python/dataflow/new/internal/DataFlowImplForRegExp.qll | 5 +++-- ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl1.qll | 5 +++-- ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl2.qll | 5 +++-- .../dataflow/internal/DataFlowImplForHttpClientLibraries.qll | 5 +++-- .../ruby/dataflow/internal/DataFlowImplForPathname.qll | 5 +++-- .../ql/lib/codeql/swift/dataflow/internal/DataFlowImpl1.qll | 5 +++-- 34 files changed, 102 insertions(+), 68 deletions(-) diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl1.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl1.qll index 8415c022111..e2d1fb15999 100644 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl1.qll +++ b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl1.qll @@ -328,7 +328,6 @@ private module Config implements FullStateConfigSig { } private import Impl<Config> as I -import I /** * A `Node` augmented with a call context (except for sinks), an access path, and a configuration. @@ -379,6 +378,8 @@ class PathNode instanceof I::PathNode { final predicate isSinkGroup(string group) { super.isSinkGroup(group) } } +module PathGraph = I::PathGraph; + private predicate hasFlow(Node source, Node sink, Configuration config) { exists(PathNode source0, PathNode sink0 | hasFlowPath(source0, sink0, config) and @@ -388,7 +389,7 @@ private predicate hasFlow(Node source, Node sink, Configuration config) { } private predicate hasFlowPath(PathNode source, PathNode sink, Configuration config) { - flowPath(source, sink) and source.getConfiguration() = config + I::flowPath(source, sink) and source.getConfiguration() = config } private predicate hasFlowTo(Node sink, Configuration config) { hasFlow(_, sink, config) } 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 8415c022111..e2d1fb15999 100644 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl2.qll +++ b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl2.qll @@ -328,7 +328,6 @@ private module Config implements FullStateConfigSig { } private import Impl<Config> as I -import I /** * A `Node` augmented with a call context (except for sinks), an access path, and a configuration. @@ -379,6 +378,8 @@ class PathNode instanceof I::PathNode { final predicate isSinkGroup(string group) { super.isSinkGroup(group) } } +module PathGraph = I::PathGraph; + private predicate hasFlow(Node source, Node sink, Configuration config) { exists(PathNode source0, PathNode sink0 | hasFlowPath(source0, sink0, config) and @@ -388,7 +389,7 @@ private predicate hasFlow(Node source, Node sink, Configuration config) { } private predicate hasFlowPath(PathNode source, PathNode sink, Configuration config) { - flowPath(source, sink) and source.getConfiguration() = config + I::flowPath(source, sink) and source.getConfiguration() = config } private predicate hasFlowTo(Node sink, Configuration config) { hasFlow(_, sink, config) } 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 8415c022111..e2d1fb15999 100644 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl3.qll +++ b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl3.qll @@ -328,7 +328,6 @@ private module Config implements FullStateConfigSig { } private import Impl<Config> as I -import I /** * A `Node` augmented with a call context (except for sinks), an access path, and a configuration. @@ -379,6 +378,8 @@ class PathNode instanceof I::PathNode { final predicate isSinkGroup(string group) { super.isSinkGroup(group) } } +module PathGraph = I::PathGraph; + private predicate hasFlow(Node source, Node sink, Configuration config) { exists(PathNode source0, PathNode sink0 | hasFlowPath(source0, sink0, config) and @@ -388,7 +389,7 @@ private predicate hasFlow(Node source, Node sink, Configuration config) { } private predicate hasFlowPath(PathNode source, PathNode sink, Configuration config) { - flowPath(source, sink) and source.getConfiguration() = config + I::flowPath(source, sink) and source.getConfiguration() = config } private predicate hasFlowTo(Node sink, Configuration config) { hasFlow(_, sink, config) } 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 8415c022111..e2d1fb15999 100644 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl4.qll +++ b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl4.qll @@ -328,7 +328,6 @@ private module Config implements FullStateConfigSig { } private import Impl<Config> as I -import I /** * A `Node` augmented with a call context (except for sinks), an access path, and a configuration. @@ -379,6 +378,8 @@ class PathNode instanceof I::PathNode { final predicate isSinkGroup(string group) { super.isSinkGroup(group) } } +module PathGraph = I::PathGraph; + private predicate hasFlow(Node source, Node sink, Configuration config) { exists(PathNode source0, PathNode sink0 | hasFlowPath(source0, sink0, config) and @@ -388,7 +389,7 @@ private predicate hasFlow(Node source, Node sink, Configuration config) { } private predicate hasFlowPath(PathNode source, PathNode sink, Configuration config) { - flowPath(source, sink) and source.getConfiguration() = config + I::flowPath(source, sink) and source.getConfiguration() = config } private predicate hasFlowTo(Node sink, Configuration config) { hasFlow(_, sink, config) } 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 8415c022111..e2d1fb15999 100644 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImplLocal.qll +++ b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImplLocal.qll @@ -328,7 +328,6 @@ private module Config implements FullStateConfigSig { } private import Impl<Config> as I -import I /** * A `Node` augmented with a call context (except for sinks), an access path, and a configuration. @@ -379,6 +378,8 @@ class PathNode instanceof I::PathNode { final predicate isSinkGroup(string group) { super.isSinkGroup(group) } } +module PathGraph = I::PathGraph; + private predicate hasFlow(Node source, Node sink, Configuration config) { exists(PathNode source0, PathNode sink0 | hasFlowPath(source0, sink0, config) and @@ -388,7 +389,7 @@ private predicate hasFlow(Node source, Node sink, Configuration config) { } private predicate hasFlowPath(PathNode source, PathNode sink, Configuration config) { - flowPath(source, sink) and source.getConfiguration() = config + I::flowPath(source, sink) and source.getConfiguration() = config } private predicate hasFlowTo(Node sink, Configuration config) { hasFlow(_, sink, config) } diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl1.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl1.qll index 8415c022111..e2d1fb15999 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl1.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl1.qll @@ -328,7 +328,6 @@ private module Config implements FullStateConfigSig { } private import Impl<Config> as I -import I /** * A `Node` augmented with a call context (except for sinks), an access path, and a configuration. @@ -379,6 +378,8 @@ class PathNode instanceof I::PathNode { final predicate isSinkGroup(string group) { super.isSinkGroup(group) } } +module PathGraph = I::PathGraph; + private predicate hasFlow(Node source, Node sink, Configuration config) { exists(PathNode source0, PathNode sink0 | hasFlowPath(source0, sink0, config) and @@ -388,7 +389,7 @@ private predicate hasFlow(Node source, Node sink, Configuration config) { } private predicate hasFlowPath(PathNode source, PathNode sink, Configuration config) { - flowPath(source, sink) and source.getConfiguration() = config + I::flowPath(source, sink) and source.getConfiguration() = config } private predicate hasFlowTo(Node sink, Configuration config) { hasFlow(_, sink, config) } 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 8415c022111..e2d1fb15999 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 @@ -328,7 +328,6 @@ private module Config implements FullStateConfigSig { } private import Impl<Config> as I -import I /** * A `Node` augmented with a call context (except for sinks), an access path, and a configuration. @@ -379,6 +378,8 @@ class PathNode instanceof I::PathNode { final predicate isSinkGroup(string group) { super.isSinkGroup(group) } } +module PathGraph = I::PathGraph; + private predicate hasFlow(Node source, Node sink, Configuration config) { exists(PathNode source0, PathNode sink0 | hasFlowPath(source0, sink0, config) and @@ -388,7 +389,7 @@ private predicate hasFlow(Node source, Node sink, Configuration config) { } private predicate hasFlowPath(PathNode source, PathNode sink, Configuration config) { - flowPath(source, sink) and source.getConfiguration() = config + I::flowPath(source, sink) and source.getConfiguration() = config } private predicate hasFlowTo(Node sink, Configuration config) { hasFlow(_, sink, config) } 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 8415c022111..e2d1fb15999 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 @@ -328,7 +328,6 @@ private module Config implements FullStateConfigSig { } private import Impl<Config> as I -import I /** * A `Node` augmented with a call context (except for sinks), an access path, and a configuration. @@ -379,6 +378,8 @@ class PathNode instanceof I::PathNode { final predicate isSinkGroup(string group) { super.isSinkGroup(group) } } +module PathGraph = I::PathGraph; + private predicate hasFlow(Node source, Node sink, Configuration config) { exists(PathNode source0, PathNode sink0 | hasFlowPath(source0, sink0, config) and @@ -388,7 +389,7 @@ private predicate hasFlow(Node source, Node sink, Configuration config) { } private predicate hasFlowPath(PathNode source, PathNode sink, Configuration config) { - flowPath(source, sink) and source.getConfiguration() = config + I::flowPath(source, sink) and source.getConfiguration() = config } private predicate hasFlowTo(Node sink, Configuration config) { hasFlow(_, sink, config) } 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 8415c022111..e2d1fb15999 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 @@ -328,7 +328,6 @@ private module Config implements FullStateConfigSig { } private import Impl<Config> as I -import I /** * A `Node` augmented with a call context (except for sinks), an access path, and a configuration. @@ -379,6 +378,8 @@ class PathNode instanceof I::PathNode { final predicate isSinkGroup(string group) { super.isSinkGroup(group) } } +module PathGraph = I::PathGraph; + private predicate hasFlow(Node source, Node sink, Configuration config) { exists(PathNode source0, PathNode sink0 | hasFlowPath(source0, sink0, config) and @@ -388,7 +389,7 @@ private predicate hasFlow(Node source, Node sink, Configuration config) { } private predicate hasFlowPath(PathNode source, PathNode sink, Configuration config) { - flowPath(source, sink) and source.getConfiguration() = config + I::flowPath(source, sink) and source.getConfiguration() = config } private predicate hasFlowTo(Node sink, Configuration config) { hasFlow(_, sink, config) } diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl1.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl1.qll index 8415c022111..e2d1fb15999 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl1.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl1.qll @@ -328,7 +328,6 @@ private module Config implements FullStateConfigSig { } private import Impl<Config> as I -import I /** * A `Node` augmented with a call context (except for sinks), an access path, and a configuration. @@ -379,6 +378,8 @@ class PathNode instanceof I::PathNode { final predicate isSinkGroup(string group) { super.isSinkGroup(group) } } +module PathGraph = I::PathGraph; + private predicate hasFlow(Node source, Node sink, Configuration config) { exists(PathNode source0, PathNode sink0 | hasFlowPath(source0, sink0, config) and @@ -388,7 +389,7 @@ private predicate hasFlow(Node source, Node sink, Configuration config) { } private predicate hasFlowPath(PathNode source, PathNode sink, Configuration config) { - flowPath(source, sink) and source.getConfiguration() = config + I::flowPath(source, sink) and source.getConfiguration() = config } private predicate hasFlowTo(Node sink, Configuration config) { hasFlow(_, sink, config) } 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 8415c022111..e2d1fb15999 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl2.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl2.qll @@ -328,7 +328,6 @@ private module Config implements FullStateConfigSig { } private import Impl<Config> as I -import I /** * A `Node` augmented with a call context (except for sinks), an access path, and a configuration. @@ -379,6 +378,8 @@ class PathNode instanceof I::PathNode { final predicate isSinkGroup(string group) { super.isSinkGroup(group) } } +module PathGraph = I::PathGraph; + private predicate hasFlow(Node source, Node sink, Configuration config) { exists(PathNode source0, PathNode sink0 | hasFlowPath(source0, sink0, config) and @@ -388,7 +389,7 @@ private predicate hasFlow(Node source, Node sink, Configuration config) { } private predicate hasFlowPath(PathNode source, PathNode sink, Configuration config) { - flowPath(source, sink) and source.getConfiguration() = config + I::flowPath(source, sink) and source.getConfiguration() = config } private predicate hasFlowTo(Node sink, Configuration config) { hasFlow(_, sink, config) } 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 8415c022111..e2d1fb15999 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl3.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl3.qll @@ -328,7 +328,6 @@ private module Config implements FullStateConfigSig { } private import Impl<Config> as I -import I /** * A `Node` augmented with a call context (except for sinks), an access path, and a configuration. @@ -379,6 +378,8 @@ class PathNode instanceof I::PathNode { final predicate isSinkGroup(string group) { super.isSinkGroup(group) } } +module PathGraph = I::PathGraph; + private predicate hasFlow(Node source, Node sink, Configuration config) { exists(PathNode source0, PathNode sink0 | hasFlowPath(source0, sink0, config) and @@ -388,7 +389,7 @@ private predicate hasFlow(Node source, Node sink, Configuration config) { } private predicate hasFlowPath(PathNode source, PathNode sink, Configuration config) { - flowPath(source, sink) and source.getConfiguration() = config + I::flowPath(source, sink) and source.getConfiguration() = config } private predicate hasFlowTo(Node sink, Configuration config) { hasFlow(_, sink, config) } 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 8415c022111..e2d1fb15999 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl4.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl4.qll @@ -328,7 +328,6 @@ private module Config implements FullStateConfigSig { } private import Impl<Config> as I -import I /** * A `Node` augmented with a call context (except for sinks), an access path, and a configuration. @@ -379,6 +378,8 @@ class PathNode instanceof I::PathNode { final predicate isSinkGroup(string group) { super.isSinkGroup(group) } } +module PathGraph = I::PathGraph; + private predicate hasFlow(Node source, Node sink, Configuration config) { exists(PathNode source0, PathNode sink0 | hasFlowPath(source0, sink0, config) and @@ -388,7 +389,7 @@ private predicate hasFlow(Node source, Node sink, Configuration config) { } private predicate hasFlowPath(PathNode source, PathNode sink, Configuration config) { - flowPath(source, sink) and source.getConfiguration() = config + I::flowPath(source, sink) and source.getConfiguration() = config } private predicate hasFlowTo(Node sink, Configuration config) { hasFlow(_, sink, config) } 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 8415c022111..e2d1fb15999 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl5.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl5.qll @@ -328,7 +328,6 @@ private module Config implements FullStateConfigSig { } private import Impl<Config> as I -import I /** * A `Node` augmented with a call context (except for sinks), an access path, and a configuration. @@ -379,6 +378,8 @@ class PathNode instanceof I::PathNode { final predicate isSinkGroup(string group) { super.isSinkGroup(group) } } +module PathGraph = I::PathGraph; + private predicate hasFlow(Node source, Node sink, Configuration config) { exists(PathNode source0, PathNode sink0 | hasFlowPath(source0, sink0, config) and @@ -388,7 +389,7 @@ private predicate hasFlow(Node source, Node sink, Configuration config) { } private predicate hasFlowPath(PathNode source, PathNode sink, Configuration config) { - flowPath(source, sink) and source.getConfiguration() = config + I::flowPath(source, sink) and source.getConfiguration() = config } private predicate hasFlowTo(Node sink, Configuration config) { hasFlow(_, sink, config) } 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 8415c022111..e2d1fb15999 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImplForContentDataFlow.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImplForContentDataFlow.qll @@ -328,7 +328,6 @@ private module Config implements FullStateConfigSig { } private import Impl<Config> as I -import I /** * A `Node` augmented with a call context (except for sinks), an access path, and a configuration. @@ -379,6 +378,8 @@ class PathNode instanceof I::PathNode { final predicate isSinkGroup(string group) { super.isSinkGroup(group) } } +module PathGraph = I::PathGraph; + private predicate hasFlow(Node source, Node sink, Configuration config) { exists(PathNode source0, PathNode sink0 | hasFlowPath(source0, sink0, config) and @@ -388,7 +389,7 @@ private predicate hasFlow(Node source, Node sink, Configuration config) { } private predicate hasFlowPath(PathNode source, PathNode sink, Configuration config) { - flowPath(source, sink) and source.getConfiguration() = config + I::flowPath(source, sink) and source.getConfiguration() = config } private predicate hasFlowTo(Node sink, Configuration config) { hasFlow(_, sink, config) } diff --git a/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl1.qll b/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl1.qll index 8415c022111..e2d1fb15999 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl1.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl1.qll @@ -328,7 +328,6 @@ private module Config implements FullStateConfigSig { } private import Impl<Config> as I -import I /** * A `Node` augmented with a call context (except for sinks), an access path, and a configuration. @@ -379,6 +378,8 @@ class PathNode instanceof I::PathNode { final predicate isSinkGroup(string group) { super.isSinkGroup(group) } } +module PathGraph = I::PathGraph; + private predicate hasFlow(Node source, Node sink, Configuration config) { exists(PathNode source0, PathNode sink0 | hasFlowPath(source0, sink0, config) and @@ -388,7 +389,7 @@ private predicate hasFlow(Node source, Node sink, Configuration config) { } private predicate hasFlowPath(PathNode source, PathNode sink, Configuration config) { - flowPath(source, sink) and source.getConfiguration() = config + I::flowPath(source, sink) and source.getConfiguration() = config } private predicate hasFlowTo(Node sink, Configuration config) { hasFlow(_, sink, config) } diff --git a/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl2.qll b/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl2.qll index 8415c022111..e2d1fb15999 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl2.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl2.qll @@ -328,7 +328,6 @@ private module Config implements FullStateConfigSig { } private import Impl<Config> as I -import I /** * A `Node` augmented with a call context (except for sinks), an access path, and a configuration. @@ -379,6 +378,8 @@ class PathNode instanceof I::PathNode { final predicate isSinkGroup(string group) { super.isSinkGroup(group) } } +module PathGraph = I::PathGraph; + private predicate hasFlow(Node source, Node sink, Configuration config) { exists(PathNode source0, PathNode sink0 | hasFlowPath(source0, sink0, config) and @@ -388,7 +389,7 @@ private predicate hasFlow(Node source, Node sink, Configuration config) { } private predicate hasFlowPath(PathNode source, PathNode sink, Configuration config) { - flowPath(source, sink) and source.getConfiguration() = config + I::flowPath(source, sink) and source.getConfiguration() = config } private predicate hasFlowTo(Node sink, Configuration config) { hasFlow(_, sink, config) } diff --git a/go/ql/lib/semmle/go/dataflow/internal/DataFlowImplForStringsNewReplacer.qll b/go/ql/lib/semmle/go/dataflow/internal/DataFlowImplForStringsNewReplacer.qll index 8415c022111..e2d1fb15999 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/DataFlowImplForStringsNewReplacer.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/DataFlowImplForStringsNewReplacer.qll @@ -328,7 +328,6 @@ private module Config implements FullStateConfigSig { } private import Impl<Config> as I -import I /** * A `Node` augmented with a call context (except for sinks), an access path, and a configuration. @@ -379,6 +378,8 @@ class PathNode instanceof I::PathNode { final predicate isSinkGroup(string group) { super.isSinkGroup(group) } } +module PathGraph = I::PathGraph; + private predicate hasFlow(Node source, Node sink, Configuration config) { exists(PathNode source0, PathNode sink0 | hasFlowPath(source0, sink0, config) and @@ -388,7 +389,7 @@ private predicate hasFlow(Node source, Node sink, Configuration config) { } private predicate hasFlowPath(PathNode source, PathNode sink, Configuration config) { - flowPath(source, sink) and source.getConfiguration() = config + I::flowPath(source, sink) and source.getConfiguration() = config } private predicate hasFlowTo(Node sink, Configuration config) { hasFlow(_, sink, config) } diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl1.qll b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl1.qll index 8415c022111..e2d1fb15999 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl1.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl1.qll @@ -328,7 +328,6 @@ private module Config implements FullStateConfigSig { } private import Impl<Config> as I -import I /** * A `Node` augmented with a call context (except for sinks), an access path, and a configuration. @@ -379,6 +378,8 @@ class PathNode instanceof I::PathNode { final predicate isSinkGroup(string group) { super.isSinkGroup(group) } } +module PathGraph = I::PathGraph; + private predicate hasFlow(Node source, Node sink, Configuration config) { exists(PathNode source0, PathNode sink0 | hasFlowPath(source0, sink0, config) and @@ -388,7 +389,7 @@ private predicate hasFlow(Node source, Node sink, Configuration config) { } private predicate hasFlowPath(PathNode source, PathNode sink, Configuration config) { - flowPath(source, sink) and source.getConfiguration() = config + I::flowPath(source, sink) and source.getConfiguration() = config } private predicate hasFlowTo(Node sink, Configuration config) { hasFlow(_, sink, config) } 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 8415c022111..e2d1fb15999 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl2.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl2.qll @@ -328,7 +328,6 @@ private module Config implements FullStateConfigSig { } private import Impl<Config> as I -import I /** * A `Node` augmented with a call context (except for sinks), an access path, and a configuration. @@ -379,6 +378,8 @@ class PathNode instanceof I::PathNode { final predicate isSinkGroup(string group) { super.isSinkGroup(group) } } +module PathGraph = I::PathGraph; + private predicate hasFlow(Node source, Node sink, Configuration config) { exists(PathNode source0, PathNode sink0 | hasFlowPath(source0, sink0, config) and @@ -388,7 +389,7 @@ private predicate hasFlow(Node source, Node sink, Configuration config) { } private predicate hasFlowPath(PathNode source, PathNode sink, Configuration config) { - flowPath(source, sink) and source.getConfiguration() = config + I::flowPath(source, sink) and source.getConfiguration() = config } private predicate hasFlowTo(Node sink, Configuration config) { hasFlow(_, sink, config) } 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 8415c022111..e2d1fb15999 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl3.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl3.qll @@ -328,7 +328,6 @@ private module Config implements FullStateConfigSig { } private import Impl<Config> as I -import I /** * A `Node` augmented with a call context (except for sinks), an access path, and a configuration. @@ -379,6 +378,8 @@ class PathNode instanceof I::PathNode { final predicate isSinkGroup(string group) { super.isSinkGroup(group) } } +module PathGraph = I::PathGraph; + private predicate hasFlow(Node source, Node sink, Configuration config) { exists(PathNode source0, PathNode sink0 | hasFlowPath(source0, sink0, config) and @@ -388,7 +389,7 @@ private predicate hasFlow(Node source, Node sink, Configuration config) { } private predicate hasFlowPath(PathNode source, PathNode sink, Configuration config) { - flowPath(source, sink) and source.getConfiguration() = config + I::flowPath(source, sink) and source.getConfiguration() = config } private predicate hasFlowTo(Node sink, Configuration config) { hasFlow(_, sink, config) } 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 8415c022111..e2d1fb15999 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl4.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl4.qll @@ -328,7 +328,6 @@ private module Config implements FullStateConfigSig { } private import Impl<Config> as I -import I /** * A `Node` augmented with a call context (except for sinks), an access path, and a configuration. @@ -379,6 +378,8 @@ class PathNode instanceof I::PathNode { final predicate isSinkGroup(string group) { super.isSinkGroup(group) } } +module PathGraph = I::PathGraph; + private predicate hasFlow(Node source, Node sink, Configuration config) { exists(PathNode source0, PathNode sink0 | hasFlowPath(source0, sink0, config) and @@ -388,7 +389,7 @@ private predicate hasFlow(Node source, Node sink, Configuration config) { } private predicate hasFlowPath(PathNode source, PathNode sink, Configuration config) { - flowPath(source, sink) and source.getConfiguration() = config + I::flowPath(source, sink) and source.getConfiguration() = config } private predicate hasFlowTo(Node sink, Configuration config) { hasFlow(_, sink, config) } 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 8415c022111..e2d1fb15999 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl5.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl5.qll @@ -328,7 +328,6 @@ private module Config implements FullStateConfigSig { } private import Impl<Config> as I -import I /** * A `Node` augmented with a call context (except for sinks), an access path, and a configuration. @@ -379,6 +378,8 @@ class PathNode instanceof I::PathNode { final predicate isSinkGroup(string group) { super.isSinkGroup(group) } } +module PathGraph = I::PathGraph; + private predicate hasFlow(Node source, Node sink, Configuration config) { exists(PathNode source0, PathNode sink0 | hasFlowPath(source0, sink0, config) and @@ -388,7 +389,7 @@ private predicate hasFlow(Node source, Node sink, Configuration config) { } private predicate hasFlowPath(PathNode source, PathNode sink, Configuration config) { - flowPath(source, sink) and source.getConfiguration() = config + I::flowPath(source, sink) and source.getConfiguration() = config } private predicate hasFlowTo(Node sink, Configuration config) { hasFlow(_, sink, config) } 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 8415c022111..e2d1fb15999 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl6.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl6.qll @@ -328,7 +328,6 @@ private module Config implements FullStateConfigSig { } private import Impl<Config> as I -import I /** * A `Node` augmented with a call context (except for sinks), an access path, and a configuration. @@ -379,6 +378,8 @@ class PathNode instanceof I::PathNode { final predicate isSinkGroup(string group) { super.isSinkGroup(group) } } +module PathGraph = I::PathGraph; + private predicate hasFlow(Node source, Node sink, Configuration config) { exists(PathNode source0, PathNode sink0 | hasFlowPath(source0, sink0, config) and @@ -388,7 +389,7 @@ private predicate hasFlow(Node source, Node sink, Configuration config) { } private predicate hasFlowPath(PathNode source, PathNode sink, Configuration config) { - flowPath(source, sink) and source.getConfiguration() = config + I::flowPath(source, sink) and source.getConfiguration() = config } private predicate hasFlowTo(Node sink, Configuration config) { hasFlow(_, sink, config) } diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl1.qll b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl1.qll index 8415c022111..e2d1fb15999 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl1.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl1.qll @@ -328,7 +328,6 @@ private module Config implements FullStateConfigSig { } private import Impl<Config> as I -import I /** * A `Node` augmented with a call context (except for sinks), an access path, and a configuration. @@ -379,6 +378,8 @@ class PathNode instanceof I::PathNode { final predicate isSinkGroup(string group) { super.isSinkGroup(group) } } +module PathGraph = I::PathGraph; + private predicate hasFlow(Node source, Node sink, Configuration config) { exists(PathNode source0, PathNode sink0 | hasFlowPath(source0, sink0, config) and @@ -388,7 +389,7 @@ private predicate hasFlow(Node source, Node sink, Configuration config) { } private predicate hasFlowPath(PathNode source, PathNode sink, Configuration config) { - flowPath(source, sink) and source.getConfiguration() = config + I::flowPath(source, sink) and source.getConfiguration() = config } private predicate hasFlowTo(Node sink, Configuration config) { hasFlow(_, sink, config) } 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 8415c022111..e2d1fb15999 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl2.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl2.qll @@ -328,7 +328,6 @@ private module Config implements FullStateConfigSig { } private import Impl<Config> as I -import I /** * A `Node` augmented with a call context (except for sinks), an access path, and a configuration. @@ -379,6 +378,8 @@ class PathNode instanceof I::PathNode { final predicate isSinkGroup(string group) { super.isSinkGroup(group) } } +module PathGraph = I::PathGraph; + private predicate hasFlow(Node source, Node sink, Configuration config) { exists(PathNode source0, PathNode sink0 | hasFlowPath(source0, sink0, config) and @@ -388,7 +389,7 @@ private predicate hasFlow(Node source, Node sink, Configuration config) { } private predicate hasFlowPath(PathNode source, PathNode sink, Configuration config) { - flowPath(source, sink) and source.getConfiguration() = config + I::flowPath(source, sink) and source.getConfiguration() = config } private predicate hasFlowTo(Node sink, Configuration config) { hasFlow(_, sink, config) } 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 8415c022111..e2d1fb15999 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl3.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl3.qll @@ -328,7 +328,6 @@ private module Config implements FullStateConfigSig { } private import Impl<Config> as I -import I /** * A `Node` augmented with a call context (except for sinks), an access path, and a configuration. @@ -379,6 +378,8 @@ class PathNode instanceof I::PathNode { final predicate isSinkGroup(string group) { super.isSinkGroup(group) } } +module PathGraph = I::PathGraph; + private predicate hasFlow(Node source, Node sink, Configuration config) { exists(PathNode source0, PathNode sink0 | hasFlowPath(source0, sink0, config) and @@ -388,7 +389,7 @@ private predicate hasFlow(Node source, Node sink, Configuration config) { } private predicate hasFlowPath(PathNode source, PathNode sink, Configuration config) { - flowPath(source, sink) and source.getConfiguration() = config + I::flowPath(source, sink) and source.getConfiguration() = config } private predicate hasFlowTo(Node sink, Configuration config) { hasFlow(_, sink, config) } 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 8415c022111..e2d1fb15999 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl4.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl4.qll @@ -328,7 +328,6 @@ private module Config implements FullStateConfigSig { } private import Impl<Config> as I -import I /** * A `Node` augmented with a call context (except for sinks), an access path, and a configuration. @@ -379,6 +378,8 @@ class PathNode instanceof I::PathNode { final predicate isSinkGroup(string group) { super.isSinkGroup(group) } } +module PathGraph = I::PathGraph; + private predicate hasFlow(Node source, Node sink, Configuration config) { exists(PathNode source0, PathNode sink0 | hasFlowPath(source0, sink0, config) and @@ -388,7 +389,7 @@ private predicate hasFlow(Node source, Node sink, Configuration config) { } private predicate hasFlowPath(PathNode source, PathNode sink, Configuration config) { - flowPath(source, sink) and source.getConfiguration() = config + I::flowPath(source, sink) and source.getConfiguration() = config } private predicate hasFlowTo(Node sink, Configuration config) { hasFlow(_, sink, config) } diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImplForRegExp.qll b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImplForRegExp.qll index 8415c022111..e2d1fb15999 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImplForRegExp.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImplForRegExp.qll @@ -328,7 +328,6 @@ private module Config implements FullStateConfigSig { } private import Impl<Config> as I -import I /** * A `Node` augmented with a call context (except for sinks), an access path, and a configuration. @@ -379,6 +378,8 @@ class PathNode instanceof I::PathNode { final predicate isSinkGroup(string group) { super.isSinkGroup(group) } } +module PathGraph = I::PathGraph; + private predicate hasFlow(Node source, Node sink, Configuration config) { exists(PathNode source0, PathNode sink0 | hasFlowPath(source0, sink0, config) and @@ -388,7 +389,7 @@ private predicate hasFlow(Node source, Node sink, Configuration config) { } private predicate hasFlowPath(PathNode source, PathNode sink, Configuration config) { - flowPath(source, sink) and source.getConfiguration() = config + I::flowPath(source, sink) and source.getConfiguration() = config } private predicate hasFlowTo(Node sink, Configuration config) { hasFlow(_, sink, config) } diff --git a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl1.qll b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl1.qll index 8415c022111..e2d1fb15999 100644 --- a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl1.qll +++ b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl1.qll @@ -328,7 +328,6 @@ private module Config implements FullStateConfigSig { } private import Impl<Config> as I -import I /** * A `Node` augmented with a call context (except for sinks), an access path, and a configuration. @@ -379,6 +378,8 @@ class PathNode instanceof I::PathNode { final predicate isSinkGroup(string group) { super.isSinkGroup(group) } } +module PathGraph = I::PathGraph; + private predicate hasFlow(Node source, Node sink, Configuration config) { exists(PathNode source0, PathNode sink0 | hasFlowPath(source0, sink0, config) and @@ -388,7 +389,7 @@ private predicate hasFlow(Node source, Node sink, Configuration config) { } private predicate hasFlowPath(PathNode source, PathNode sink, Configuration config) { - flowPath(source, sink) and source.getConfiguration() = config + I::flowPath(source, sink) and source.getConfiguration() = config } private predicate hasFlowTo(Node sink, Configuration config) { hasFlow(_, sink, config) } diff --git a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl2.qll b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl2.qll index 8415c022111..e2d1fb15999 100644 --- a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl2.qll +++ b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl2.qll @@ -328,7 +328,6 @@ private module Config implements FullStateConfigSig { } private import Impl<Config> as I -import I /** * A `Node` augmented with a call context (except for sinks), an access path, and a configuration. @@ -379,6 +378,8 @@ class PathNode instanceof I::PathNode { final predicate isSinkGroup(string group) { super.isSinkGroup(group) } } +module PathGraph = I::PathGraph; + private predicate hasFlow(Node source, Node sink, Configuration config) { exists(PathNode source0, PathNode sink0 | hasFlowPath(source0, sink0, config) and @@ -388,7 +389,7 @@ private predicate hasFlow(Node source, Node sink, Configuration config) { } private predicate hasFlowPath(PathNode source, PathNode sink, Configuration config) { - flowPath(source, sink) and source.getConfiguration() = config + I::flowPath(source, sink) and source.getConfiguration() = config } private predicate hasFlowTo(Node sink, Configuration config) { hasFlow(_, sink, config) } diff --git a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImplForHttpClientLibraries.qll b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImplForHttpClientLibraries.qll index 8415c022111..e2d1fb15999 100644 --- a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImplForHttpClientLibraries.qll +++ b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImplForHttpClientLibraries.qll @@ -328,7 +328,6 @@ private module Config implements FullStateConfigSig { } private import Impl<Config> as I -import I /** * A `Node` augmented with a call context (except for sinks), an access path, and a configuration. @@ -379,6 +378,8 @@ class PathNode instanceof I::PathNode { final predicate isSinkGroup(string group) { super.isSinkGroup(group) } } +module PathGraph = I::PathGraph; + private predicate hasFlow(Node source, Node sink, Configuration config) { exists(PathNode source0, PathNode sink0 | hasFlowPath(source0, sink0, config) and @@ -388,7 +389,7 @@ private predicate hasFlow(Node source, Node sink, Configuration config) { } private predicate hasFlowPath(PathNode source, PathNode sink, Configuration config) { - flowPath(source, sink) and source.getConfiguration() = config + I::flowPath(source, sink) and source.getConfiguration() = config } private predicate hasFlowTo(Node sink, Configuration config) { hasFlow(_, sink, config) } diff --git a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImplForPathname.qll b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImplForPathname.qll index 8415c022111..e2d1fb15999 100644 --- a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImplForPathname.qll +++ b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImplForPathname.qll @@ -328,7 +328,6 @@ private module Config implements FullStateConfigSig { } private import Impl<Config> as I -import I /** * A `Node` augmented with a call context (except for sinks), an access path, and a configuration. @@ -379,6 +378,8 @@ class PathNode instanceof I::PathNode { final predicate isSinkGroup(string group) { super.isSinkGroup(group) } } +module PathGraph = I::PathGraph; + private predicate hasFlow(Node source, Node sink, Configuration config) { exists(PathNode source0, PathNode sink0 | hasFlowPath(source0, sink0, config) and @@ -388,7 +389,7 @@ private predicate hasFlow(Node source, Node sink, Configuration config) { } private predicate hasFlowPath(PathNode source, PathNode sink, Configuration config) { - flowPath(source, sink) and source.getConfiguration() = config + I::flowPath(source, sink) and source.getConfiguration() = config } private predicate hasFlowTo(Node sink, Configuration config) { hasFlow(_, sink, config) } diff --git a/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowImpl1.qll b/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowImpl1.qll index 8415c022111..e2d1fb15999 100644 --- a/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowImpl1.qll +++ b/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowImpl1.qll @@ -328,7 +328,6 @@ private module Config implements FullStateConfigSig { } private import Impl<Config> as I -import I /** * A `Node` augmented with a call context (except for sinks), an access path, and a configuration. @@ -379,6 +378,8 @@ class PathNode instanceof I::PathNode { final predicate isSinkGroup(string group) { super.isSinkGroup(group) } } +module PathGraph = I::PathGraph; + private predicate hasFlow(Node source, Node sink, Configuration config) { exists(PathNode source0, PathNode sink0 | hasFlowPath(source0, sink0, config) and @@ -388,7 +389,7 @@ private predicate hasFlow(Node source, Node sink, Configuration config) { } private predicate hasFlowPath(PathNode source, PathNode sink, Configuration config) { - flowPath(source, sink) and source.getConfiguration() = config + I::flowPath(source, sink) and source.getConfiguration() = config } private predicate hasFlowTo(Node sink, Configuration config) { hasFlow(_, sink, config) } From 691ffcd3a4ee03058ddb440e61602eee0da691cd Mon Sep 17 00:00:00 2001 From: Rasmus Wriedt Larsen <rasmuswl@github.com> Date: Mon, 27 Mar 2023 14:58:29 +0200 Subject: [PATCH 553/631] Python: Add tests of `py/azure-storage/unsafe-client-side-encryption-in-use` Notice that it doesn't find the potentially unsafe version, or the vuln that spans calls. --- ...sageOfClientSideEncryptionVersion.expected | 1 + ...feUsageOfClientSideEncryptionVersion.qlref | 1 + .../test.py | 59 +++++++++++++++++++ 3 files changed, 61 insertions(+) create mode 100644 python/ql/test/experimental/query-tests/Security/CWE-327-UnsafeUsageOfClientSideEncryptionVersion/UnsafeUsageOfClientSideEncryptionVersion.expected create mode 100644 python/ql/test/experimental/query-tests/Security/CWE-327-UnsafeUsageOfClientSideEncryptionVersion/UnsafeUsageOfClientSideEncryptionVersion.qlref create mode 100644 python/ql/test/experimental/query-tests/Security/CWE-327-UnsafeUsageOfClientSideEncryptionVersion/test.py diff --git a/python/ql/test/experimental/query-tests/Security/CWE-327-UnsafeUsageOfClientSideEncryptionVersion/UnsafeUsageOfClientSideEncryptionVersion.expected b/python/ql/test/experimental/query-tests/Security/CWE-327-UnsafeUsageOfClientSideEncryptionVersion/UnsafeUsageOfClientSideEncryptionVersion.expected new file mode 100644 index 00000000000..5fdc975907a --- /dev/null +++ b/python/ql/test/experimental/query-tests/Security/CWE-327-UnsafeUsageOfClientSideEncryptionVersion/UnsafeUsageOfClientSideEncryptionVersion.expected @@ -0,0 +1 @@ +| test.py:8:5:8:34 | ControlFlowNode for Attribute | Unsafe usage of v1 version of Azure Storage client-side encryption. | diff --git a/python/ql/test/experimental/query-tests/Security/CWE-327-UnsafeUsageOfClientSideEncryptionVersion/UnsafeUsageOfClientSideEncryptionVersion.qlref b/python/ql/test/experimental/query-tests/Security/CWE-327-UnsafeUsageOfClientSideEncryptionVersion/UnsafeUsageOfClientSideEncryptionVersion.qlref new file mode 100644 index 00000000000..b737b32c815 --- /dev/null +++ b/python/ql/test/experimental/query-tests/Security/CWE-327-UnsafeUsageOfClientSideEncryptionVersion/UnsafeUsageOfClientSideEncryptionVersion.qlref @@ -0,0 +1 @@ +experimental/Security/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql diff --git a/python/ql/test/experimental/query-tests/Security/CWE-327-UnsafeUsageOfClientSideEncryptionVersion/test.py b/python/ql/test/experimental/query-tests/Security/CWE-327-UnsafeUsageOfClientSideEncryptionVersion/test.py new file mode 100644 index 00000000000..44d72f0bf1f --- /dev/null +++ b/python/ql/test/experimental/query-tests/Security/CWE-327-UnsafeUsageOfClientSideEncryptionVersion/test.py @@ -0,0 +1,59 @@ +from azure.storage.blob import BlobServiceClient + + +def unsafe(): + # does not set encryption_version to 2.0, default is unsafe + blob_client = BlobServiceClient.get_blob_client(...) + blob_client.require_encryption = True + blob_client.key_encryption_key = ... + with open("decryptedcontentfile.txt", "rb") as stream: + blob_client.upload_blob(stream) # BAD + + +def potentially_unsafe(use_new_version=False): + blob_client = BlobServiceClient.get_blob_client(...) + blob_client.require_encryption = True + blob_client.key_encryption_key = ... + + if use_new_version: + blob_client.encryption_version = '2.0' + + with open("decryptedcontentfile.txt", "rb") as stream: + blob_client.upload_blob(stream) # BAD + + +def safe(): + blob_client = BlobServiceClient.get_blob_client(...) + blob_client.require_encryption = True + blob_client.key_encryption_key = ... + # GOOD: Must use `encryption_version` set to `2.0` + blob_client.encryption_version = '2.0' + with open("decryptedcontentfile.txt", "rb") as stream: + blob_client.upload_blob(stream) # OK + + +def get_unsafe_blob_client(): + blob_client = BlobServiceClient.get_blob_client(...) + blob_client.require_encryption = True + blob_client.key_encryption_key = ... + return blob_client + + +def unsafe_with_calls(): + bc = get_unsafe_blob_client() + with open("decryptedcontentfile.txt", "rb") as stream: + bc.upload_blob(stream) # BAD + + +def get_safe_blob_client(): + blob_client = BlobServiceClient.get_blob_client(...) + blob_client.require_encryption = True + blob_client.key_encryption_key = ... + blob_client.encryption_version = '2.0' + return blob_client + + +def safe_with_calls(): + bc = get_safe_blob_client() + with open("decryptedcontentfile.txt", "rb") as stream: + bc.upload_blob(stream) # OK From 7a17cd2a9e46bbc77695f3761fa2c634883d8ac4 Mon Sep 17 00:00:00 2001 From: Rasmus Wriedt Larsen <rasmuswl@github.com> Date: Mon, 27 Mar 2023 17:37:09 +0200 Subject: [PATCH 554/631] Python: Rewrite azure query to more idiomatic ql --- ...nsafeUsageOfClientSideEncryptionVersion.ql | 46 ++++++++----------- 1 file changed, 20 insertions(+), 26 deletions(-) diff --git a/python/ql/src/experimental/Security/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql b/python/ql/src/experimental/Security/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql index 556132e5c64..af8dbb88cd3 100644 --- a/python/ql/src/experimental/Security/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql +++ b/python/ql/src/experimental/Security/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql @@ -12,38 +12,32 @@ */ import python +import semmle.python.dataflow.new.DataFlow import semmle.python.ApiGraphs predicate isUnsafeClientSideAzureStorageEncryptionViaAttributes(Call call, AttrNode node) { exists( - API::Node n, ControlFlowNode startingNode, Attribute attr, ControlFlowNode ctrlFlowNode, - Attribute attrUploadBlob, ControlFlowNode ctrlFlowNodeUploadBlob, string s1, string s2, - string s3 + API::Node client, DataFlow::AttrWrite keyAttrWrite, DataFlow::MethodCallNode uploadBlobCall | - call.getAChildNode() = attrUploadBlob and - node = ctrlFlowNode + call = uploadBlobCall.asExpr() and node = keyAttrWrite.asCfgNode() | - s1 in ["key_encryption_key", "key_resolver_function"] and - s2 in ["ContainerClient", "BlobClient", "BlobServiceClient"] and - s3 = "upload_blob" and - n = API::moduleImport("azure").getMember("storage").getMember("blob").getMember(s2).getAMember() and - startingNode = n.getACall().getReturn().getAValueReachableFromSource().asExpr().getAFlowNode() and - startingNode.strictlyReaches(ctrlFlowNode) and - attr.getAFlowNode() = ctrlFlowNode and - attr.getName() = s1 and - ctrlFlowNode.strictlyReaches(ctrlFlowNodeUploadBlob) and - attrUploadBlob.getAFlowNode() = ctrlFlowNodeUploadBlob and - attrUploadBlob.getName() = s3 and - not exists( - Attribute attrBarrier, ControlFlowNode ctrlFlowNodeBarrier, AssignStmt astmt2, StrConst uc - | - startingNode.strictlyReaches(ctrlFlowNodeBarrier) and - attrBarrier.getAFlowNode() = ctrlFlowNodeBarrier and - attrBarrier.getName() = "encryption_version" and - uc = astmt2.getValue() and - uc.getText() in ["'2.0'", "2.0"] and - astmt2.getATarget().getAChildNode*() = attrBarrier and - ctrlFlowNodeBarrier.strictlyReaches(ctrlFlowNodeUploadBlob) + client = + API::moduleImport("azure") + .getMember("storage") + .getMember("blob") + .getMember(["ContainerClient", "BlobClient", "BlobServiceClient"]) + .getAMember() + .getReturn() and + keyAttrWrite + .accesses(client.getAValueReachableFromSource(), + ["key_encryption_key", "key_resolver_function"]) and + uploadBlobCall.calls(client.getAValueReachableFromSource(), "upload_blob") and + DataFlow::localFlow(keyAttrWrite.getObject(), uploadBlobCall.getObject()) and + not exists(DataFlow::AttrWrite encryptionVersionWrite | + encryptionVersionWrite.accesses(client.getAValueReachableFromSource(), "encryption_version") and + encryptionVersionWrite.getValue().asExpr().(StrConst).getText() in ["'2.0'", "2.0"] and + DataFlow::localFlow(keyAttrWrite.getObject(), encryptionVersionWrite.getObject()) and + DataFlow::localFlow(encryptionVersionWrite.getObject(), uploadBlobCall.getObject()) ) ) } From 8ea6b6f256cd626c608dcd017ac34c3cc9786965 Mon Sep 17 00:00:00 2001 From: Rasmus Wriedt Larsen <rasmuswl@github.com> Date: Tue, 28 Mar 2023 10:09:22 +0200 Subject: [PATCH 555/631] Python: Update `py/azure-storage/unsafe-client-side-encryption-in-use` to use datafow --- ...nsafeUsageOfClientSideEncryptionVersion.ql | 69 +++++++++++-------- ...sageOfClientSideEncryptionVersion.expected | 21 +++++- 2 files changed, 60 insertions(+), 30 deletions(-) diff --git a/python/ql/src/experimental/Security/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql b/python/ql/src/experimental/Security/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql index af8dbb88cd3..293edddd9f0 100644 --- a/python/ql/src/experimental/Security/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql +++ b/python/ql/src/experimental/Security/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql @@ -1,7 +1,7 @@ /** * @name Unsafe usage of v1 version of Azure Storage client-side encryption. * @description Using version v1 of Azure Storage client-side encryption is insecure, and may enable an attacker to decrypt encrypted data - * @kind problem + * @kind path-problem * @tags security * experimental * cryptography @@ -15,33 +15,44 @@ import python import semmle.python.dataflow.new.DataFlow import semmle.python.ApiGraphs -predicate isUnsafeClientSideAzureStorageEncryptionViaAttributes(Call call, AttrNode node) { - exists( - API::Node client, DataFlow::AttrWrite keyAttrWrite, DataFlow::MethodCallNode uploadBlobCall - | - call = uploadBlobCall.asExpr() and node = keyAttrWrite.asCfgNode() - | - client = - API::moduleImport("azure") - .getMember("storage") - .getMember("blob") - .getMember(["ContainerClient", "BlobClient", "BlobServiceClient"]) - .getAMember() - .getReturn() and - keyAttrWrite - .accesses(client.getAValueReachableFromSource(), - ["key_encryption_key", "key_resolver_function"]) and - uploadBlobCall.calls(client.getAValueReachableFromSource(), "upload_blob") and - DataFlow::localFlow(keyAttrWrite.getObject(), uploadBlobCall.getObject()) and - not exists(DataFlow::AttrWrite encryptionVersionWrite | - encryptionVersionWrite.accesses(client.getAValueReachableFromSource(), "encryption_version") and - encryptionVersionWrite.getValue().asExpr().(StrConst).getText() in ["'2.0'", "2.0"] and - DataFlow::localFlow(keyAttrWrite.getObject(), encryptionVersionWrite.getObject()) and - DataFlow::localFlow(encryptionVersionWrite.getObject(), uploadBlobCall.getObject()) - ) - ) +API::Node getClient() { + result = + API::moduleImport("azure") + .getMember("storage") + .getMember("blob") + .getMember(["ContainerClient", "BlobClient", "BlobServiceClient"]) + .getAMember() + .getReturn() } -from Call call, ControlFlowNode node -where isUnsafeClientSideAzureStorageEncryptionViaAttributes(call, node) -select node, "Unsafe usage of v1 version of Azure Storage client-side encryption." +module AzureBlobClientConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node node) { + exists(DataFlow::AttrWrite attr | + node = getClient().getAValueReachableFromSource() and + attr.accesses(node, ["key_encryption_key", "key_resolver_function"]) + ) + } + + predicate isBarrier(DataFlow::Node node) { + exists(DataFlow::AttrWrite attr | + node = getClient().getAValueReachableFromSource() and + attr.accesses(node, "encryption_version") and + attr.getValue().asExpr().(StrConst).getText() in ["'2.0'", "2.0"] + ) + } + + predicate isSink(DataFlow::Node node) { + exists(DataFlow::MethodCallNode call | + call = getClient().getMember("upload_blob").getACall() and + node = call.getObject() + ) + } +} + +module AzureBlobClient = DataFlow::Global<AzureBlobClientConfig>; + +import AzureBlobClient::PathGraph + +from AzureBlobClient::PathNode source, AzureBlobClient::PathNode sink +where AzureBlobClient::flowPath(source, sink) +select sink, source, sink, "Unsafe usage of v1 version of Azure Storage client-side encryption" diff --git a/python/ql/test/experimental/query-tests/Security/CWE-327-UnsafeUsageOfClientSideEncryptionVersion/UnsafeUsageOfClientSideEncryptionVersion.expected b/python/ql/test/experimental/query-tests/Security/CWE-327-UnsafeUsageOfClientSideEncryptionVersion/UnsafeUsageOfClientSideEncryptionVersion.expected index 5fdc975907a..a1db6075756 100644 --- a/python/ql/test/experimental/query-tests/Security/CWE-327-UnsafeUsageOfClientSideEncryptionVersion/UnsafeUsageOfClientSideEncryptionVersion.expected +++ b/python/ql/test/experimental/query-tests/Security/CWE-327-UnsafeUsageOfClientSideEncryptionVersion/UnsafeUsageOfClientSideEncryptionVersion.expected @@ -1 +1,20 @@ -| test.py:8:5:8:34 | ControlFlowNode for Attribute | Unsafe usage of v1 version of Azure Storage client-side encryption. | +edges +| test.py:8:5:8:15 | ControlFlowNode for blob_client | test.py:10:9:10:19 | ControlFlowNode for blob_client | +| test.py:16:5:16:15 | ControlFlowNode for blob_client | test.py:22:9:22:19 | ControlFlowNode for blob_client | +| test.py:38:5:38:15 | ControlFlowNode for blob_client | test.py:39:12:39:22 | ControlFlowNode for blob_client | +| test.py:39:12:39:22 | ControlFlowNode for blob_client | test.py:43:10:43:33 | ControlFlowNode for get_unsafe_blob_client() | +| test.py:43:10:43:33 | ControlFlowNode for get_unsafe_blob_client() | test.py:45:9:45:10 | ControlFlowNode for bc | +nodes +| test.py:8:5:8:15 | ControlFlowNode for blob_client | semmle.label | ControlFlowNode for blob_client | +| test.py:10:9:10:19 | ControlFlowNode for blob_client | semmle.label | ControlFlowNode for blob_client | +| test.py:16:5:16:15 | ControlFlowNode for blob_client | semmle.label | ControlFlowNode for blob_client | +| test.py:22:9:22:19 | ControlFlowNode for blob_client | semmle.label | ControlFlowNode for blob_client | +| test.py:38:5:38:15 | ControlFlowNode for blob_client | semmle.label | ControlFlowNode for blob_client | +| test.py:39:12:39:22 | ControlFlowNode for blob_client | semmle.label | ControlFlowNode for blob_client | +| test.py:43:10:43:33 | ControlFlowNode for get_unsafe_blob_client() | semmle.label | ControlFlowNode for get_unsafe_blob_client() | +| test.py:45:9:45:10 | ControlFlowNode for bc | semmle.label | ControlFlowNode for bc | +subpaths +#select +| test.py:10:9:10:19 | ControlFlowNode for blob_client | test.py:8:5:8:15 | ControlFlowNode for blob_client | test.py:10:9:10:19 | ControlFlowNode for blob_client | Unsafe usage of v1 version of Azure Storage client-side encryption | +| test.py:22:9:22:19 | ControlFlowNode for blob_client | test.py:16:5:16:15 | ControlFlowNode for blob_client | test.py:22:9:22:19 | ControlFlowNode for blob_client | Unsafe usage of v1 version of Azure Storage client-side encryption | +| test.py:45:9:45:10 | ControlFlowNode for bc | test.py:38:5:38:15 | ControlFlowNode for blob_client | test.py:45:9:45:10 | ControlFlowNode for bc | Unsafe usage of v1 version of Azure Storage client-side encryption | From aec82f6ef881ac8c0fbe55fad1ac8ddb11add4c3 Mon Sep 17 00:00:00 2001 From: Asger F <asgerf@github.com> Date: Tue, 28 Mar 2023 10:12:38 +0200 Subject: [PATCH 556/631] Update docs/codeql/codeql-language-guides/customizing-library-models-for-javascript.rst Co-authored-by: Andrew Eisenberg <aeisenberg@github.com> --- .../customizing-library-models-for-javascript.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/codeql/codeql-language-guides/customizing-library-models-for-javascript.rst b/docs/codeql/codeql-language-guides/customizing-library-models-for-javascript.rst index 3241a9a1420..78de81b6fa0 100644 --- a/docs/codeql/codeql-language-guides/customizing-library-models-for-javascript.rst +++ b/docs/codeql/codeql-language-guides/customizing-library-models-for-javascript.rst @@ -8,7 +8,7 @@ Customizing Library Models for JavaScript .. include:: ../reusables/beta-note-customizing-library-models.rst -The JavaScript analysis can be customized by adding library models in data extension files. +JavaScript analysis can be customized by adding library models in data extension files. A data extension for JavaScript is a YAML file of the form: From d62b944b930b1f9eda97821d341ad2ce7add9103 Mon Sep 17 00:00:00 2001 From: Asger F <asgerf@github.com> Date: Tue, 28 Mar 2023 10:49:28 +0200 Subject: [PATCH 557/631] JS: Explain difference between type and member --- .../customizing-library-models-for-javascript.rst | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/docs/codeql/codeql-language-guides/customizing-library-models-for-javascript.rst b/docs/codeql/codeql-language-guides/customizing-library-models-for-javascript.rst index 78de81b6fa0..404bc0561a1 100644 --- a/docs/codeql/codeql-language-guides/customizing-library-models-for-javascript.rst +++ b/docs/codeql/codeql-language-guides/customizing-library-models-for-javascript.rst @@ -166,6 +166,17 @@ We can recognize this using the following extension: This works in this example because the **connection** parameter has a type annotation that matches what the model is looking for. +Note that there is a significant difference between the following two rows: + +.. code-block:: yaml + + data: + - ["mysql.Connection", "", ...] + - ["mysql", "Member[Connection]", ...] + +The first row matches instances of **mysql.Connection** which are objects that encapsulate a MySQL connection. +The second row would match something like **require('mysql').Connection**, which is not itself a connection object. + In the next section, we'll show how to generalize the model to handle the absence of type annotations. Continued example: Dealing with untyped code From 02da09c7d8834c7e14d56449403f03ad31829085 Mon Sep 17 00:00:00 2001 From: Asger F <asgerf@github.com> Date: Tue, 28 Mar 2023 11:36:24 +0200 Subject: [PATCH 558/631] Update docs/codeql/codeql-language-guides/customizing-library-models-for-javascript.rst Co-authored-by: Ben Ahmady <32935794+subatoi@users.noreply.github.com> --- .../customizing-library-models-for-javascript.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/codeql/codeql-language-guides/customizing-library-models-for-javascript.rst b/docs/codeql/codeql-language-guides/customizing-library-models-for-javascript.rst index 404bc0561a1..a50b6b11a85 100644 --- a/docs/codeql/codeql-language-guides/customizing-library-models-for-javascript.rst +++ b/docs/codeql/codeql-language-guides/customizing-library-models-for-javascript.rst @@ -174,7 +174,7 @@ Note that there is a significant difference between the following two rows: - ["mysql.Connection", "", ...] - ["mysql", "Member[Connection]", ...] -The first row matches instances of **mysql.Connection** which are objects that encapsulate a MySQL connection. +The first row matches instances of **mysql.Connection**, which are objects that encapsulate a MySQL connection. The second row would match something like **require('mysql').Connection**, which is not itself a connection object. In the next section, we'll show how to generalize the model to handle the absence of type annotations. From 61a7ee9387584fe1a51e37715884d9833fc80860 Mon Sep 17 00:00:00 2001 From: Asger F <asgerf@github.com> Date: Tue, 28 Mar 2023 12:56:03 +0200 Subject: [PATCH 559/631] JS: Use getABoundFunctionValue instead of type-tracking --- .../semmle/javascript/frameworks/jQuery.qll | 19 ------------------- .../security/dataflow/DomBasedXssQuery.qll | 5 +++-- 2 files changed, 3 insertions(+), 21 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/frameworks/jQuery.qll b/javascript/ql/lib/semmle/javascript/frameworks/jQuery.qll index 2a0affedd7f..4fad4ae1b05 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/jQuery.qll +++ b/javascript/ql/lib/semmle/javascript/frameworks/jQuery.qll @@ -563,25 +563,6 @@ module JQuery { } } - /** Gets a data flow node that reaches a sink that is interpreted as HTML. */ - private DataFlow::SourceNode htmlCallback(DataFlow::TypeBackTracker t) { - t.start() and - any(JQuery::MethodCall c).interpretsArgumentAsHtml(result.getALocalUse()) - or - exists(DataFlow::TypeBackTracker t2 | result = htmlCallback(t2).backtrack(t2, t)) - } - - /** - * Gets a function that is passed as a callback to a jQuery function, which will interpret its return value as HTML. - * - * For example, this gets the function `f` below: - * ```js - * function f() { ... } - * $('#foo').replaceWith(f); - * ``` - */ - DataFlow::FunctionNode htmlCallback() { result = htmlCallback(DataFlow::TypeBackTracker::end()) } - /** * Holds for jQuery plugin definitions of the form `$.fn.<pluginName> = <plugin>` or `$.extend($.fn, {<pluginName>, <plugin>})`. */ diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/DomBasedXssQuery.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/DomBasedXssQuery.qll index 767789fa27f..e26b4eea8c8 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/DomBasedXssQuery.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/DomBasedXssQuery.qll @@ -123,8 +123,9 @@ class Configuration extends TaintTracking::Configuration { inlbl = TaintedUrlSuffix::label() and outlbl = prefixLabel() or - exists(DataFlow::FunctionNode callback | - callback = JQuery::htmlCallback() and + exists(DataFlow::FunctionNode callback, DataFlow::Node arg | + any(JQuery::MethodCall c).interpretsArgumentAsHtml(arg) and + callback = arg.getABoundFunctionValue(_) and src = callback.getReturnNode() and trg = callback and inlbl = outlbl From e38196a3a8858cec89c335de064c5f1f84f69412 Mon Sep 17 00:00:00 2001 From: Michael Nebel <michaelnebel@github.com> Date: Tue, 28 Mar 2023 13:04:30 +0200 Subject: [PATCH 560/631] C#: Claim support for C# 11 / .NET 7 in external documentation. --- docs/codeql/reusables/supported-versions-compilers.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/codeql/reusables/supported-versions-compilers.rst b/docs/codeql/reusables/supported-versions-compilers.rst index 3ee4ab85ec2..3fe77ebb2ee 100644 --- a/docs/codeql/reusables/supported-versions-compilers.rst +++ b/docs/codeql/reusables/supported-versions-compilers.rst @@ -11,11 +11,11 @@ Microsoft extensions (up to VS 2019), Arm Compiler 5 [3]_","``.cpp``, ``.c++``, ``.cxx``, ``.hpp``, ``.hh``, ``.h++``, ``.hxx``, ``.c``, ``.cc``, ``.h``" - C#,C# up to 10.0,"Microsoft Visual Studio up to 2019 with .NET up to 4.8, + C#,C# up to 11,"Microsoft Visual Studio up to 2019 with .NET up to 4.8, .NET Core up to 3.1 - .NET 5, .NET 6","``.sln``, ``.csproj``, ``.cs``, ``.cshtml``, ``.xaml``" + .NET 5, .NET 6, .NET 7","``.sln``, ``.csproj``, ``.cs``, ``.cshtml``, ``.xaml``" Go (aka Golang), "Go up to 1.20", "Go 1.11 or more recent", ``.go`` Java,"Java 7 to 20 [4]_","javac (OpenJDK and Oracle JDK), From 47e7aa9566177a474e9e919989cb27020208da46 Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen <aschackmull@github.com> Date: Tue, 28 Mar 2023 13:17:48 +0200 Subject: [PATCH 561/631] Dataflow: Add change note. --- cpp/ql/lib/change-notes/2023-03-28-dataflow-rm-footgun.md | 4 ++++ csharp/ql/lib/change-notes/2023-03-28-dataflow-rm-footgun.md | 4 ++++ go/ql/lib/change-notes/2023-03-28-dataflow-rm-footgun.md | 4 ++++ java/ql/lib/change-notes/2023-03-28-dataflow-rm-footgun.md | 4 ++++ python/ql/lib/change-notes/2023-03-28-dataflow-rm-footgun.md | 4 ++++ ruby/ql/lib/change-notes/2023-03-28-dataflow-rm-footgun.md | 4 ++++ 6 files changed, 24 insertions(+) create mode 100644 cpp/ql/lib/change-notes/2023-03-28-dataflow-rm-footgun.md create mode 100644 csharp/ql/lib/change-notes/2023-03-28-dataflow-rm-footgun.md create mode 100644 go/ql/lib/change-notes/2023-03-28-dataflow-rm-footgun.md create mode 100644 java/ql/lib/change-notes/2023-03-28-dataflow-rm-footgun.md create mode 100644 python/ql/lib/change-notes/2023-03-28-dataflow-rm-footgun.md create mode 100644 ruby/ql/lib/change-notes/2023-03-28-dataflow-rm-footgun.md diff --git a/cpp/ql/lib/change-notes/2023-03-28-dataflow-rm-footgun.md b/cpp/ql/lib/change-notes/2023-03-28-dataflow-rm-footgun.md new file mode 100644 index 00000000000..82dc0a1d893 --- /dev/null +++ b/cpp/ql/lib/change-notes/2023-03-28-dataflow-rm-footgun.md @@ -0,0 +1,4 @@ +--- +category: fix +--- +* Fixed some accidental predicate visibility in the backwards-compatible wrapper for data flow configurations. In particular `DataFlow::hasFlowPath`, `DataFlow::hasFlow`, `DataFlow::hasFlowTo`, and `DataFlow::hasFlowToExpr` were accidentally exposed in a single version. diff --git a/csharp/ql/lib/change-notes/2023-03-28-dataflow-rm-footgun.md b/csharp/ql/lib/change-notes/2023-03-28-dataflow-rm-footgun.md new file mode 100644 index 00000000000..82dc0a1d893 --- /dev/null +++ b/csharp/ql/lib/change-notes/2023-03-28-dataflow-rm-footgun.md @@ -0,0 +1,4 @@ +--- +category: fix +--- +* Fixed some accidental predicate visibility in the backwards-compatible wrapper for data flow configurations. In particular `DataFlow::hasFlowPath`, `DataFlow::hasFlow`, `DataFlow::hasFlowTo`, and `DataFlow::hasFlowToExpr` were accidentally exposed in a single version. diff --git a/go/ql/lib/change-notes/2023-03-28-dataflow-rm-footgun.md b/go/ql/lib/change-notes/2023-03-28-dataflow-rm-footgun.md new file mode 100644 index 00000000000..82dc0a1d893 --- /dev/null +++ b/go/ql/lib/change-notes/2023-03-28-dataflow-rm-footgun.md @@ -0,0 +1,4 @@ +--- +category: fix +--- +* Fixed some accidental predicate visibility in the backwards-compatible wrapper for data flow configurations. In particular `DataFlow::hasFlowPath`, `DataFlow::hasFlow`, `DataFlow::hasFlowTo`, and `DataFlow::hasFlowToExpr` were accidentally exposed in a single version. diff --git a/java/ql/lib/change-notes/2023-03-28-dataflow-rm-footgun.md b/java/ql/lib/change-notes/2023-03-28-dataflow-rm-footgun.md new file mode 100644 index 00000000000..82dc0a1d893 --- /dev/null +++ b/java/ql/lib/change-notes/2023-03-28-dataflow-rm-footgun.md @@ -0,0 +1,4 @@ +--- +category: fix +--- +* Fixed some accidental predicate visibility in the backwards-compatible wrapper for data flow configurations. In particular `DataFlow::hasFlowPath`, `DataFlow::hasFlow`, `DataFlow::hasFlowTo`, and `DataFlow::hasFlowToExpr` were accidentally exposed in a single version. diff --git a/python/ql/lib/change-notes/2023-03-28-dataflow-rm-footgun.md b/python/ql/lib/change-notes/2023-03-28-dataflow-rm-footgun.md new file mode 100644 index 00000000000..82dc0a1d893 --- /dev/null +++ b/python/ql/lib/change-notes/2023-03-28-dataflow-rm-footgun.md @@ -0,0 +1,4 @@ +--- +category: fix +--- +* Fixed some accidental predicate visibility in the backwards-compatible wrapper for data flow configurations. In particular `DataFlow::hasFlowPath`, `DataFlow::hasFlow`, `DataFlow::hasFlowTo`, and `DataFlow::hasFlowToExpr` were accidentally exposed in a single version. diff --git a/ruby/ql/lib/change-notes/2023-03-28-dataflow-rm-footgun.md b/ruby/ql/lib/change-notes/2023-03-28-dataflow-rm-footgun.md new file mode 100644 index 00000000000..82dc0a1d893 --- /dev/null +++ b/ruby/ql/lib/change-notes/2023-03-28-dataflow-rm-footgun.md @@ -0,0 +1,4 @@ +--- +category: fix +--- +* Fixed some accidental predicate visibility in the backwards-compatible wrapper for data flow configurations. In particular `DataFlow::hasFlowPath`, `DataFlow::hasFlow`, `DataFlow::hasFlowTo`, and `DataFlow::hasFlowToExpr` were accidentally exposed in a single version. From 3b0095725c38560620f497caa69ef88bccd72638 Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen <aschackmull@github.com> Date: Tue, 28 Mar 2023 14:00:25 +0200 Subject: [PATCH 562/631] Java: Adjust test expectation. --- .../range-analysis/RangeAnalysis.expected | 67 +++++++++++++++---- 1 file changed, 53 insertions(+), 14 deletions(-) diff --git a/java/ql/test/library-tests/dataflow/range-analysis/RangeAnalysis.expected b/java/ql/test/library-tests/dataflow/range-analysis/RangeAnalysis.expected index d66a35bf397..9fbe076dfe9 100644 --- a/java/ql/test/library-tests/dataflow/range-analysis/RangeAnalysis.expected +++ b/java/ql/test/library-tests/dataflow/range-analysis/RangeAnalysis.expected @@ -33,9 +33,17 @@ | A.java:9:16:9:16 | x | SSA init(x) | 0 | upper | NoReason | | A.java:9:16:9:16 | x | SSA init(y) | -2 | lower | ... == ... | | A.java:9:16:9:16 | x | SSA init(y) | -2 | upper | ... == ... | -| A.java:9:16:9:20 | ... + ... | 0 | 300 | lower | ... > ... | -| A.java:9:16:9:20 | ... + ... | SSA init(x) | 1 | lower | NoReason | -| A.java:9:16:9:20 | ... + ... | SSA init(y) | -1 | lower | ... == ... | +| A.java:9:16:9:20 | ... + ... | 0 | 600 | lower | ... > ... | +| A.java:9:16:9:20 | ... + ... | 0 | 802 | upper | ... == ... | +| A.java:9:16:9:20 | ... + ... | 0 | 802 | upper | ... > ... | +| A.java:9:16:9:20 | ... + ... | SSA init(x) | 301 | lower | ... == ... | +| A.java:9:16:9:20 | ... + ... | SSA init(x) | 301 | lower | NoReason | +| A.java:9:16:9:20 | ... + ... | SSA init(x) | 402 | upper | ... == ... | +| A.java:9:16:9:20 | ... + ... | SSA init(x) | 402 | upper | NoReason | +| A.java:9:16:9:20 | ... + ... | SSA init(y) | 299 | lower | ... == ... | +| A.java:9:16:9:20 | ... + ... | SSA init(y) | 299 | lower | NoReason | +| A.java:9:16:9:20 | ... + ... | SSA init(y) | 400 | upper | ... == ... | +| A.java:9:16:9:20 | ... + ... | SSA init(y) | 400 | upper | NoReason | | A.java:9:20:9:20 | y | 0 | 301 | lower | ... > ... | | A.java:9:20:9:20 | y | 0 | 402 | upper | ... == ... | | A.java:9:20:9:20 | y | SSA init(x) | 2 | lower | ... == ... | @@ -54,6 +62,7 @@ | A.java:13:19:13:19 | x | 0 | 400 | upper | ... > ... | | A.java:13:19:13:19 | x | SSA init(x) | 0 | lower | NoReason | | A.java:13:19:13:19 | x | SSA init(x) | 0 | upper | NoReason | +| A.java:13:19:13:23 | ... + ... | SSA init(y) | 400 | upper | NoReason | | A.java:13:23:13:23 | y | SSA init(y) | 0 | lower | NoReason | | A.java:13:23:13:23 | y | SSA init(y) | 0 | upper | NoReason | | A.java:15:13:15:13 | y | 0 | 399 | upper | ... != ... | @@ -69,9 +78,17 @@ | A.java:16:21:16:21 | x | SSA init(x) | 0 | upper | NoReason | | A.java:16:21:16:21 | x | SSA init(y) | 1 | lower | ... != ... | | A.java:16:21:16:21 | x | SSA init(y) | 1 | upper | ... != ... | -| A.java:16:21:16:25 | ... + ... | 0 | 303 | lower | ... > ... | -| A.java:16:21:16:25 | ... + ... | SSA init(x) | 1 | lower | NoReason | -| A.java:16:21:16:25 | ... + ... | SSA init(y) | 2 | lower | ... != ... | +| A.java:16:21:16:25 | ... + ... | 0 | 603 | lower | ... > ... | +| A.java:16:21:16:25 | ... + ... | 0 | 799 | upper | ... != ... | +| A.java:16:21:16:25 | ... + ... | 0 | 799 | upper | ... > ... | +| A.java:16:21:16:25 | ... + ... | SSA init(x) | 301 | lower | ... != ... | +| A.java:16:21:16:25 | ... + ... | SSA init(x) | 301 | lower | NoReason | +| A.java:16:21:16:25 | ... + ... | SSA init(x) | 399 | upper | ... != ... | +| A.java:16:21:16:25 | ... + ... | SSA init(x) | 399 | upper | NoReason | +| A.java:16:21:16:25 | ... + ... | SSA init(y) | 302 | lower | ... != ... | +| A.java:16:21:16:25 | ... + ... | SSA init(y) | 302 | lower | NoReason | +| A.java:16:21:16:25 | ... + ... | SSA init(y) | 400 | upper | ... != ... | +| A.java:16:21:16:25 | ... + ... | SSA init(y) | 400 | upper | NoReason | | A.java:16:25:16:25 | y | 0 | 301 | lower | ... > ... | | A.java:16:25:16:25 | y | 0 | 399 | upper | ... != ... | | A.java:16:25:16:25 | y | SSA init(x) | -1 | lower | ... != ... | @@ -153,14 +170,36 @@ | A.java:35:16:35:16 | x | SSA init(y) | 1 | upper | ... == ... | | A.java:35:16:35:16 | x | SSA init(z) | -1 | lower | ... == ... | | A.java:35:16:35:16 | x | SSA init(z) | -1 | upper | ... == ... | -| A.java:35:16:35:20 | ... + ... | 0 | 350 | lower | ... == ... | -| A.java:35:16:35:20 | ... + ... | SSA init(x) | 1 | lower | NoReason | -| A.java:35:16:35:20 | ... + ... | SSA init(y) | 2 | lower | ... == ... | -| A.java:35:16:35:20 | ... + ... | SSA init(z) | 0 | lower | ... == ... | -| A.java:35:16:35:24 | ... + ... | 0 | 351 | lower | ... == ... | -| A.java:35:16:35:24 | ... + ... | SSA init(x) | 2 | lower | NoReason | -| A.java:35:16:35:24 | ... + ... | SSA init(y) | 3 | lower | ... == ... | -| A.java:35:16:35:24 | ... + ... | SSA init(z) | 1 | lower | ... == ... | +| A.java:35:16:35:20 | ... + ... | 0 | 697 | lower | ... == ... | +| A.java:35:16:35:20 | ... + ... | 0 | 697 | upper | ... == ... | +| A.java:35:16:35:20 | ... + ... | SSA init(x) | 348 | lower | ... == ... | +| A.java:35:16:35:20 | ... + ... | SSA init(x) | 348 | lower | NoReason | +| A.java:35:16:35:20 | ... + ... | SSA init(x) | 348 | upper | ... == ... | +| A.java:35:16:35:20 | ... + ... | SSA init(x) | 348 | upper | NoReason | +| A.java:35:16:35:20 | ... + ... | SSA init(y) | 349 | lower | ... == ... | +| A.java:35:16:35:20 | ... + ... | SSA init(y) | 349 | lower | NoReason | +| A.java:35:16:35:20 | ... + ... | SSA init(y) | 349 | upper | ... == ... | +| A.java:35:16:35:20 | ... + ... | SSA init(y) | 349 | upper | NoReason | +| A.java:35:16:35:20 | ... + ... | SSA init(z) | 347 | lower | ... == ... | +| A.java:35:16:35:20 | ... + ... | SSA init(z) | 347 | upper | ... == ... | +| A.java:35:16:35:24 | ... + ... | 0 | 1047 | lower | ... == ... | +| A.java:35:16:35:24 | ... + ... | 0 | 1047 | upper | ... == ... | +| A.java:35:16:35:24 | ... + ... | SSA init(x) | 698 | lower | ... == ... | +| A.java:35:16:35:24 | ... + ... | SSA init(x) | 698 | lower | ... == ... | +| A.java:35:16:35:24 | ... + ... | SSA init(x) | 698 | lower | NoReason | +| A.java:35:16:35:24 | ... + ... | SSA init(x) | 698 | upper | ... == ... | +| A.java:35:16:35:24 | ... + ... | SSA init(x) | 698 | upper | ... == ... | +| A.java:35:16:35:24 | ... + ... | SSA init(x) | 698 | upper | NoReason | +| A.java:35:16:35:24 | ... + ... | SSA init(y) | 699 | lower | ... == ... | +| A.java:35:16:35:24 | ... + ... | SSA init(y) | 699 | lower | ... == ... | +| A.java:35:16:35:24 | ... + ... | SSA init(y) | 699 | lower | NoReason | +| A.java:35:16:35:24 | ... + ... | SSA init(y) | 699 | upper | ... == ... | +| A.java:35:16:35:24 | ... + ... | SSA init(y) | 699 | upper | ... == ... | +| A.java:35:16:35:24 | ... + ... | SSA init(y) | 699 | upper | NoReason | +| A.java:35:16:35:24 | ... + ... | SSA init(z) | 697 | lower | ... == ... | +| A.java:35:16:35:24 | ... + ... | SSA init(z) | 697 | lower | NoReason | +| A.java:35:16:35:24 | ... + ... | SSA init(z) | 697 | upper | ... == ... | +| A.java:35:16:35:24 | ... + ... | SSA init(z) | 697 | upper | NoReason | | A.java:35:20:35:20 | y | 0 | 348 | lower | ... == ... | | A.java:35:20:35:20 | y | 0 | 348 | upper | ... == ... | | A.java:35:20:35:20 | y | SSA init(x) | -1 | lower | ... == ... | From 3b8ad087eb3304551de5d4c0602cded165703696 Mon Sep 17 00:00:00 2001 From: Jeroen Ketema <jketema@github.com> Date: Tue, 28 Mar 2023 12:37:33 +0200 Subject: [PATCH 563/631] Make imports of `codeql.util.Unit` private --- cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl.qll | 1 + .../lib/semmle/code/cpp/dataflow/internal/DataFlowImpl1.qll | 1 + .../lib/semmle/code/cpp/dataflow/internal/DataFlowImpl2.qll | 1 + .../lib/semmle/code/cpp/dataflow/internal/DataFlowImpl3.qll | 1 + .../lib/semmle/code/cpp/dataflow/internal/DataFlowImpl4.qll | 1 + .../semmle/code/cpp/dataflow/internal/DataFlowImplLocal.qll | 1 + .../lib/semmle/code/cpp/dataflow/internal/DataFlowPrivate.qll | 2 +- .../lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl.qll | 1 + .../semmle/code/cpp/ir/dataflow/internal/DataFlowImpl1.qll | 1 + .../semmle/code/cpp/ir/dataflow/internal/DataFlowImpl2.qll | 1 + .../semmle/code/cpp/ir/dataflow/internal/DataFlowImpl3.qll | 1 + .../semmle/code/cpp/ir/dataflow/internal/DataFlowImpl4.qll | 1 + .../semmle/code/cpp/ir/dataflow/internal/DataFlowPrivate.qll | 2 +- .../lib/semmle/code/csharp/dataflow/internal/DataFlowImpl.qll | 1 + .../semmle/code/csharp/dataflow/internal/DataFlowImpl1.qll | 1 + .../semmle/code/csharp/dataflow/internal/DataFlowImpl2.qll | 1 + .../semmle/code/csharp/dataflow/internal/DataFlowImpl3.qll | 1 + .../semmle/code/csharp/dataflow/internal/DataFlowImpl4.qll | 1 + .../semmle/code/csharp/dataflow/internal/DataFlowImpl5.qll | 1 + .../dataflow/internal/DataFlowImplForContentDataFlow.qll | 1 + .../semmle/code/csharp/dataflow/internal/DataFlowPrivate.qll | 2 +- .../semmle/code/csharp/dataflow/internal/FlowSummaryImpl.qll | 1 + .../utils/modelgenerator/internal/CaptureModelsSpecific.qll | 2 -- go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl.qll | 1 + go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl1.qll | 1 + go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl2.qll | 1 + .../dataflow/internal/DataFlowImplForStringsNewReplacer.qll | 1 + go/ql/lib/semmle/go/dataflow/internal/DataFlowPrivate.qll | 2 +- go/ql/lib/semmle/go/dataflow/internal/FlowSummaryImpl.qll | 1 + .../lib/semmle/code/java/dataflow/internal/DataFlowImpl.qll | 1 + .../lib/semmle/code/java/dataflow/internal/DataFlowImpl1.qll | 1 + .../lib/semmle/code/java/dataflow/internal/DataFlowImpl2.qll | 1 + .../lib/semmle/code/java/dataflow/internal/DataFlowImpl3.qll | 1 + .../lib/semmle/code/java/dataflow/internal/DataFlowImpl4.qll | 1 + .../lib/semmle/code/java/dataflow/internal/DataFlowImpl5.qll | 1 + .../lib/semmle/code/java/dataflow/internal/DataFlowImpl6.qll | 1 + .../lib/semmle/code/java/dataflow/internal/DataFlowUtil.qll | 1 - .../semmle/code/java/dataflow/internal/FlowSummaryImpl.qll | 1 + .../javascript/frameworks/data/internal/ApiGraphModels.qll | 3 +-- .../frameworks/data/internal/ApiGraphModelsSpecific.qll | 2 -- .../lib/semmle/python/dataflow/new/internal/DataFlowImpl.qll | 1 + .../lib/semmle/python/dataflow/new/internal/DataFlowImpl1.qll | 1 + .../lib/semmle/python/dataflow/new/internal/DataFlowImpl2.qll | 1 + .../lib/semmle/python/dataflow/new/internal/DataFlowImpl3.qll | 1 + .../lib/semmle/python/dataflow/new/internal/DataFlowImpl4.qll | 1 + .../python/dataflow/new/internal/DataFlowImplForRegExp.qll | 1 + .../python/dataflow/new/internal/DataFlowImplSpecific.qll | 3 --- .../semmle/python/dataflow/new/internal/FlowSummaryImpl.qll | 1 + .../semmle/python/frameworks/data/internal/ApiGraphModels.qll | 3 +-- .../frameworks/data/internal/ApiGraphModelsSpecific.qll | 3 --- ruby/ql/lib/codeql/ruby/dataflow/FlowSteps.qll | 4 +--- ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl.qll | 1 + ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl1.qll | 1 + ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl2.qll | 1 + .../dataflow/internal/DataFlowImplForHttpClientLibraries.qll | 1 + .../codeql/ruby/dataflow/internal/DataFlowImplForPathname.qll | 1 + ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowPrivate.qll | 2 +- ruby/ql/lib/codeql/ruby/dataflow/internal/FlowSummaryImpl.qll | 1 + .../codeql/ruby/frameworks/data/internal/ApiGraphModels.qll | 3 +-- .../ruby/frameworks/data/internal/ApiGraphModelsSpecific.qll | 4 ---- swift/ql/lib/codeql/swift/dataflow/internal/DataFlowImpl.qll | 1 + swift/ql/lib/codeql/swift/dataflow/internal/DataFlowImpl1.qll | 1 + .../codeql/swift/dataflow/internal/DataFlowImplSpecific.qll | 2 -- .../ql/lib/codeql/swift/dataflow/internal/FlowSummaryImpl.qll | 1 + 64 files changed, 57 insertions(+), 31 deletions(-) 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 39dbf8dc075..6ea97954bdf 100644 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl.qll +++ b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl.qll @@ -8,6 +8,7 @@ private import DataFlowImplCommon private import DataFlowImplSpecific::Private private import DataFlowImplSpecific::Public private import DataFlowImplCommonPublic +private import codeql.util.Unit import DataFlow /** diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl1.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl1.qll index 8415c022111..fcf01966abb 100644 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl1.qll +++ b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl1.qll @@ -11,6 +11,7 @@ import DataFlowImplSpecific::Public private import DataFlowImpl import DataFlowImplCommonPublic import FlowStateString +private import codeql.util.Unit /** * A configuration of interprocedural data flow analysis. This defines 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 8415c022111..fcf01966abb 100644 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl2.qll +++ b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl2.qll @@ -11,6 +11,7 @@ import DataFlowImplSpecific::Public private import DataFlowImpl import DataFlowImplCommonPublic import FlowStateString +private import codeql.util.Unit /** * A configuration of interprocedural data flow analysis. This defines 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 8415c022111..fcf01966abb 100644 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl3.qll +++ b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl3.qll @@ -11,6 +11,7 @@ import DataFlowImplSpecific::Public private import DataFlowImpl import DataFlowImplCommonPublic import FlowStateString +private import codeql.util.Unit /** * A configuration of interprocedural data flow analysis. This defines 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 8415c022111..fcf01966abb 100644 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl4.qll +++ b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl4.qll @@ -11,6 +11,7 @@ import DataFlowImplSpecific::Public private import DataFlowImpl import DataFlowImplCommonPublic import FlowStateString +private import codeql.util.Unit /** * A configuration of interprocedural data flow analysis. This defines 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 8415c022111..fcf01966abb 100644 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImplLocal.qll +++ b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImplLocal.qll @@ -11,6 +11,7 @@ import DataFlowImplSpecific::Public private import DataFlowImpl import DataFlowImplCommonPublic import FlowStateString +private import codeql.util.Unit /** * A configuration of interprocedural data flow analysis. This defines diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowPrivate.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowPrivate.qll index c08e05b767d..6f2da96f27f 100644 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowPrivate.qll +++ b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowPrivate.qll @@ -3,7 +3,7 @@ private import DataFlowUtil private import DataFlowDispatch private import FlowVar private import DataFlowImplConsistency -import codeql.util.Unit +private import codeql.util.Unit /** Gets the callable in which this node occurs. */ DataFlowCallable nodeGetEnclosingCallable(Node n) { result = n.getEnclosingCallable() } 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 39dbf8dc075..6ea97954bdf 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 @@ -8,6 +8,7 @@ private import DataFlowImplCommon private import DataFlowImplSpecific::Private private import DataFlowImplSpecific::Public private import DataFlowImplCommonPublic +private import codeql.util.Unit import DataFlow /** diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl1.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl1.qll index 8415c022111..fcf01966abb 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl1.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl1.qll @@ -11,6 +11,7 @@ import DataFlowImplSpecific::Public private import DataFlowImpl import DataFlowImplCommonPublic import FlowStateString +private import codeql.util.Unit /** * A configuration of interprocedural data flow analysis. This defines 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 8415c022111..fcf01966abb 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 @@ -11,6 +11,7 @@ import DataFlowImplSpecific::Public private import DataFlowImpl import DataFlowImplCommonPublic import FlowStateString +private import codeql.util.Unit /** * A configuration of interprocedural data flow analysis. This defines 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 8415c022111..fcf01966abb 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 @@ -11,6 +11,7 @@ import DataFlowImplSpecific::Public private import DataFlowImpl import DataFlowImplCommonPublic import FlowStateString +private import codeql.util.Unit /** * A configuration of interprocedural data flow analysis. This defines 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 8415c022111..fcf01966abb 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 @@ -11,6 +11,7 @@ import DataFlowImplSpecific::Public private import DataFlowImpl import DataFlowImplCommonPublic import FlowStateString +private import codeql.util.Unit /** * A configuration of interprocedural data flow analysis. This defines diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowPrivate.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowPrivate.qll index 331eb6241a5..30fdf102b6b 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowPrivate.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowPrivate.qll @@ -6,7 +6,7 @@ private import DataFlowImplConsistency private import semmle.code.cpp.ir.internal.IRCppLanguage private import SsaInternals as Ssa private import DataFlowImplCommon as DataFlowImplCommon -import codeql.util.Unit +private import codeql.util.Unit cached private module Cached { 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 39dbf8dc075..6ea97954bdf 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl.qll @@ -8,6 +8,7 @@ private import DataFlowImplCommon private import DataFlowImplSpecific::Private private import DataFlowImplSpecific::Public private import DataFlowImplCommonPublic +private import codeql.util.Unit import DataFlow /** diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl1.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl1.qll index 8415c022111..fcf01966abb 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl1.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl1.qll @@ -11,6 +11,7 @@ import DataFlowImplSpecific::Public private import DataFlowImpl import DataFlowImplCommonPublic import FlowStateString +private import codeql.util.Unit /** * A configuration of interprocedural data flow analysis. This defines 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 8415c022111..fcf01966abb 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl2.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl2.qll @@ -11,6 +11,7 @@ import DataFlowImplSpecific::Public private import DataFlowImpl import DataFlowImplCommonPublic import FlowStateString +private import codeql.util.Unit /** * A configuration of interprocedural data flow analysis. This defines 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 8415c022111..fcf01966abb 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl3.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl3.qll @@ -11,6 +11,7 @@ import DataFlowImplSpecific::Public private import DataFlowImpl import DataFlowImplCommonPublic import FlowStateString +private import codeql.util.Unit /** * A configuration of interprocedural data flow analysis. This defines 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 8415c022111..fcf01966abb 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl4.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl4.qll @@ -11,6 +11,7 @@ import DataFlowImplSpecific::Public private import DataFlowImpl import DataFlowImplCommonPublic import FlowStateString +private import codeql.util.Unit /** * A configuration of interprocedural data flow analysis. This defines 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 8415c022111..fcf01966abb 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl5.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl5.qll @@ -11,6 +11,7 @@ import DataFlowImplSpecific::Public private import DataFlowImpl import DataFlowImplCommonPublic import FlowStateString +private import codeql.util.Unit /** * A configuration of interprocedural data flow analysis. This defines 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 8415c022111..fcf01966abb 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImplForContentDataFlow.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImplForContentDataFlow.qll @@ -11,6 +11,7 @@ import DataFlowImplSpecific::Public private import DataFlowImpl import DataFlowImplCommonPublic import FlowStateString +private import codeql.util.Unit /** * A configuration of interprocedural data flow analysis. This defines 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 9bcddf7c6c2..2790ff1465e 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowPrivate.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowPrivate.qll @@ -19,7 +19,7 @@ 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 -import codeql.util.Unit +private import codeql.util.Unit /** Gets the callable in which this node occurs. */ DataFlowCallable nodeGetEnclosingCallable(NodeImpl n) { result = n.getEnclosingCallableImpl() } diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/FlowSummaryImpl.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/FlowSummaryImpl.qll index 6c718a66068..6665e0e7480 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/FlowSummaryImpl.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/FlowSummaryImpl.qll @@ -10,6 +10,7 @@ private import FlowSummaryImplSpecific private import DataFlowImplSpecific::Private private import DataFlowImplSpecific::Public private import DataFlowImplCommon +private import codeql.util.Unit /** Provides classes and predicates for defining flow summaries. */ module Public { diff --git a/csharp/ql/src/utils/modelgenerator/internal/CaptureModelsSpecific.qll b/csharp/ql/src/utils/modelgenerator/internal/CaptureModelsSpecific.qll index 0414de03016..ea45e8e049b 100644 --- a/csharp/ql/src/utils/modelgenerator/internal/CaptureModelsSpecific.qll +++ b/csharp/ql/src/utils/modelgenerator/internal/CaptureModelsSpecific.qll @@ -18,8 +18,6 @@ module TaintTracking = CS::TaintTracking; class Type = CS::Type; -class Unit = DataFlowPrivate::Unit; - /** * Holds if any of the parameters of `api` are `System.Func<>`. */ diff --git a/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl.qll b/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl.qll index 39dbf8dc075..6ea97954bdf 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl.qll @@ -8,6 +8,7 @@ private import DataFlowImplCommon private import DataFlowImplSpecific::Private private import DataFlowImplSpecific::Public private import DataFlowImplCommonPublic +private import codeql.util.Unit import DataFlow /** diff --git a/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl1.qll b/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl1.qll index 8415c022111..fcf01966abb 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl1.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl1.qll @@ -11,6 +11,7 @@ import DataFlowImplSpecific::Public private import DataFlowImpl import DataFlowImplCommonPublic import FlowStateString +private import codeql.util.Unit /** * A configuration of interprocedural data flow analysis. This defines diff --git a/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl2.qll b/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl2.qll index 8415c022111..fcf01966abb 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl2.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl2.qll @@ -11,6 +11,7 @@ import DataFlowImplSpecific::Public private import DataFlowImpl import DataFlowImplCommonPublic import FlowStateString +private import codeql.util.Unit /** * A configuration of interprocedural data flow analysis. This defines diff --git a/go/ql/lib/semmle/go/dataflow/internal/DataFlowImplForStringsNewReplacer.qll b/go/ql/lib/semmle/go/dataflow/internal/DataFlowImplForStringsNewReplacer.qll index 8415c022111..fcf01966abb 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/DataFlowImplForStringsNewReplacer.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/DataFlowImplForStringsNewReplacer.qll @@ -11,6 +11,7 @@ import DataFlowImplSpecific::Public private import DataFlowImpl import DataFlowImplCommonPublic import FlowStateString +private import codeql.util.Unit /** * A configuration of interprocedural data flow analysis. This defines diff --git a/go/ql/lib/semmle/go/dataflow/internal/DataFlowPrivate.qll b/go/ql/lib/semmle/go/dataflow/internal/DataFlowPrivate.qll index d57adbe5d69..6cddbd7b980 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/DataFlowPrivate.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/DataFlowPrivate.qll @@ -3,7 +3,7 @@ private import DataFlowUtil private import DataFlowImplCommon private import ContainerFlow private import FlowSummaryImpl as FlowSummaryImpl -import codeql.util.Unit +private import codeql.util.Unit import DataFlowNodes::Private private newtype TReturnKind = diff --git a/go/ql/lib/semmle/go/dataflow/internal/FlowSummaryImpl.qll b/go/ql/lib/semmle/go/dataflow/internal/FlowSummaryImpl.qll index 6c718a66068..6665e0e7480 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/FlowSummaryImpl.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/FlowSummaryImpl.qll @@ -10,6 +10,7 @@ private import FlowSummaryImplSpecific private import DataFlowImplSpecific::Private private import DataFlowImplSpecific::Public private import DataFlowImplCommon +private import codeql.util.Unit /** Provides classes and predicates for defining flow summaries. */ module Public { 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 39dbf8dc075..6ea97954bdf 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl.qll @@ -8,6 +8,7 @@ private import DataFlowImplCommon private import DataFlowImplSpecific::Private private import DataFlowImplSpecific::Public private import DataFlowImplCommonPublic +private import codeql.util.Unit import DataFlow /** diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl1.qll b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl1.qll index 8415c022111..fcf01966abb 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl1.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl1.qll @@ -11,6 +11,7 @@ import DataFlowImplSpecific::Public private import DataFlowImpl import DataFlowImplCommonPublic import FlowStateString +private import codeql.util.Unit /** * A configuration of interprocedural data flow analysis. This defines 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 8415c022111..fcf01966abb 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl2.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl2.qll @@ -11,6 +11,7 @@ import DataFlowImplSpecific::Public private import DataFlowImpl import DataFlowImplCommonPublic import FlowStateString +private import codeql.util.Unit /** * A configuration of interprocedural data flow analysis. This defines 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 8415c022111..fcf01966abb 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl3.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl3.qll @@ -11,6 +11,7 @@ import DataFlowImplSpecific::Public private import DataFlowImpl import DataFlowImplCommonPublic import FlowStateString +private import codeql.util.Unit /** * A configuration of interprocedural data flow analysis. This defines 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 8415c022111..fcf01966abb 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl4.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl4.qll @@ -11,6 +11,7 @@ import DataFlowImplSpecific::Public private import DataFlowImpl import DataFlowImplCommonPublic import FlowStateString +private import codeql.util.Unit /** * A configuration of interprocedural data flow analysis. This defines 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 8415c022111..fcf01966abb 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl5.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl5.qll @@ -11,6 +11,7 @@ import DataFlowImplSpecific::Public private import DataFlowImpl import DataFlowImplCommonPublic import FlowStateString +private import codeql.util.Unit /** * A configuration of interprocedural data flow analysis. This defines 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 8415c022111..fcf01966abb 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl6.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl6.qll @@ -11,6 +11,7 @@ import DataFlowImplSpecific::Public private import DataFlowImpl import DataFlowImplCommonPublic import FlowStateString +private import codeql.util.Unit /** * A configuration of interprocedural data flow analysis. This defines diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowUtil.qll b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowUtil.qll index ba5a1cfacc7..ff064cc8405 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowUtil.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowUtil.qll @@ -14,7 +14,6 @@ private import FlowSummaryImpl as FlowSummaryImpl private import TaintTrackingUtil as TaintTrackingUtil private import DataFlowNodes import DataFlowNodes::Public -import semmle.code.Unit /** Holds if `n` is an access to an unqualified `this` at `cfgnode`. */ private predicate thisAccess(Node n, ControlFlowNode cfgnode) { diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/FlowSummaryImpl.qll b/java/ql/lib/semmle/code/java/dataflow/internal/FlowSummaryImpl.qll index 6c718a66068..6665e0e7480 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/FlowSummaryImpl.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/FlowSummaryImpl.qll @@ -10,6 +10,7 @@ private import FlowSummaryImplSpecific private import DataFlowImplSpecific::Private private import DataFlowImplSpecific::Public private import DataFlowImplCommon +private import codeql.util.Unit /** Provides classes and predicates for defining flow summaries. */ module Public { 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 1b7e8cb326a..227f4ea22fb 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/data/internal/ApiGraphModels.qll +++ b/javascript/ql/lib/semmle/javascript/frameworks/data/internal/ApiGraphModels.qll @@ -63,10 +63,9 @@ * the type is not intended to match a static type. */ +private import codeql.util.Unit private import ApiGraphModelsSpecific as Specific -private class Unit = Specific::Unit; - private module API = Specific::API; private module DataFlow = Specific::DataFlow; 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 9ebbe4099db..ee2fd74b5de 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/data/internal/ApiGraphModelsSpecific.qll +++ b/javascript/ql/lib/semmle/javascript/frameworks/data/internal/ApiGraphModelsSpecific.qll @@ -22,8 +22,6 @@ private import javascript as JS private import ApiGraphModels -class Unit = JS::Unit; - // Re-export libraries needed by ApiGraphModels.qll module API = JS::API; 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 39dbf8dc075..6ea97954bdf 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl.qll @@ -8,6 +8,7 @@ private import DataFlowImplCommon private import DataFlowImplSpecific::Private private import DataFlowImplSpecific::Public private import DataFlowImplCommonPublic +private import codeql.util.Unit import DataFlow /** diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl1.qll b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl1.qll index 8415c022111..fcf01966abb 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl1.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl1.qll @@ -11,6 +11,7 @@ import DataFlowImplSpecific::Public private import DataFlowImpl import DataFlowImplCommonPublic import FlowStateString +private import codeql.util.Unit /** * A configuration of interprocedural data flow analysis. This defines 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 8415c022111..fcf01966abb 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl2.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl2.qll @@ -11,6 +11,7 @@ import DataFlowImplSpecific::Public private import DataFlowImpl import DataFlowImplCommonPublic import FlowStateString +private import codeql.util.Unit /** * A configuration of interprocedural data flow analysis. This defines 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 8415c022111..fcf01966abb 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl3.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl3.qll @@ -11,6 +11,7 @@ import DataFlowImplSpecific::Public private import DataFlowImpl import DataFlowImplCommonPublic import FlowStateString +private import codeql.util.Unit /** * A configuration of interprocedural data flow analysis. This defines 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 8415c022111..fcf01966abb 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl4.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl4.qll @@ -11,6 +11,7 @@ import DataFlowImplSpecific::Public private import DataFlowImpl import DataFlowImplCommonPublic import FlowStateString +private import codeql.util.Unit /** * A configuration of interprocedural data flow analysis. This defines diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImplForRegExp.qll b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImplForRegExp.qll index 8415c022111..fcf01966abb 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImplForRegExp.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImplForRegExp.qll @@ -11,6 +11,7 @@ import DataFlowImplSpecific::Public private import DataFlowImpl import DataFlowImplCommonPublic import FlowStateString +private import codeql.util.Unit /** * A configuration of interprocedural data flow analysis. This defines diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImplSpecific.qll b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImplSpecific.qll index cdbd1eecb2c..8a7ecbcb565 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImplSpecific.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImplSpecific.qll @@ -7,9 +7,6 @@ private import python as Python module Private { import DataFlowPrivate - - // import DataFlowDispatch - class Unit = Python::Unit; } module Public { diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/FlowSummaryImpl.qll b/python/ql/lib/semmle/python/dataflow/new/internal/FlowSummaryImpl.qll index 6c718a66068..6665e0e7480 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/FlowSummaryImpl.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/FlowSummaryImpl.qll @@ -10,6 +10,7 @@ private import FlowSummaryImplSpecific private import DataFlowImplSpecific::Private private import DataFlowImplSpecific::Public private import DataFlowImplCommon +private import codeql.util.Unit /** Provides classes and predicates for defining flow summaries. */ module Public { 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 1b7e8cb326a..227f4ea22fb 100644 --- a/python/ql/lib/semmle/python/frameworks/data/internal/ApiGraphModels.qll +++ b/python/ql/lib/semmle/python/frameworks/data/internal/ApiGraphModels.qll @@ -63,10 +63,9 @@ * the type is not intended to match a static type. */ +private import codeql.util.Unit private import ApiGraphModelsSpecific as Specific -private class Unit = Specific::Unit; - private module API = Specific::API; private module DataFlow = Specific::DataFlow; 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 eb23efe4aff..38a1198193e 100644 --- a/python/ql/lib/semmle/python/frameworks/data/internal/ApiGraphModelsSpecific.qll +++ b/python/ql/lib/semmle/python/frameworks/data/internal/ApiGraphModelsSpecific.qll @@ -22,9 +22,6 @@ private import python as PY private import ApiGraphModels import semmle.python.ApiGraphs::API as API - -class Unit = PY::Unit; - // Re-export libraries needed by ApiGraphModels.qll import semmle.python.dataflow.new.internal.AccessPathSyntax as AccessPathSyntax import semmle.python.dataflow.new.DataFlow::DataFlow as DataFlow diff --git a/ruby/ql/lib/codeql/ruby/dataflow/FlowSteps.qll b/ruby/ql/lib/codeql/ruby/dataflow/FlowSteps.qll index 881441fc765..f509208aab3 100644 --- a/ruby/ql/lib/codeql/ruby/dataflow/FlowSteps.qll +++ b/ruby/ql/lib/codeql/ruby/dataflow/FlowSteps.qll @@ -2,10 +2,8 @@ * Provides classes representing various flow steps for taint tracking. */ +private import codeql.util.Unit 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, diff --git a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl.qll b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl.qll index 39dbf8dc075..6ea97954bdf 100644 --- a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl.qll +++ b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl.qll @@ -8,6 +8,7 @@ private import DataFlowImplCommon private import DataFlowImplSpecific::Private private import DataFlowImplSpecific::Public private import DataFlowImplCommonPublic +private import codeql.util.Unit import DataFlow /** diff --git a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl1.qll b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl1.qll index 8415c022111..fcf01966abb 100644 --- a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl1.qll +++ b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl1.qll @@ -11,6 +11,7 @@ import DataFlowImplSpecific::Public private import DataFlowImpl import DataFlowImplCommonPublic import FlowStateString +private import codeql.util.Unit /** * A configuration of interprocedural data flow analysis. This defines diff --git a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl2.qll b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl2.qll index 8415c022111..fcf01966abb 100644 --- a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl2.qll +++ b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl2.qll @@ -11,6 +11,7 @@ import DataFlowImplSpecific::Public private import DataFlowImpl import DataFlowImplCommonPublic import FlowStateString +private import codeql.util.Unit /** * A configuration of interprocedural data flow analysis. This defines diff --git a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImplForHttpClientLibraries.qll b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImplForHttpClientLibraries.qll index 8415c022111..fcf01966abb 100644 --- a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImplForHttpClientLibraries.qll +++ b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImplForHttpClientLibraries.qll @@ -11,6 +11,7 @@ import DataFlowImplSpecific::Public private import DataFlowImpl import DataFlowImplCommonPublic import FlowStateString +private import codeql.util.Unit /** * A configuration of interprocedural data flow analysis. This defines diff --git a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImplForPathname.qll b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImplForPathname.qll index 8415c022111..fcf01966abb 100644 --- a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImplForPathname.qll +++ b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImplForPathname.qll @@ -11,6 +11,7 @@ import DataFlowImplSpecific::Public private import DataFlowImpl import DataFlowImplCommonPublic import FlowStateString +private import codeql.util.Unit /** * A configuration of interprocedural data flow analysis. This defines diff --git a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowPrivate.qll b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowPrivate.qll index bcff6df309a..86bc852200d 100644 --- a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowPrivate.qll +++ b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowPrivate.qll @@ -1,4 +1,5 @@ private import codeql.util.Boolean +private import codeql.util.Unit private import codeql.ruby.AST private import codeql.ruby.ast.internal.Synthesis private import codeql.ruby.CFG @@ -9,7 +10,6 @@ private import SsaImpl as SsaImpl private import FlowSummaryImpl as FlowSummaryImpl private import FlowSummaryImplSpecific as FlowSummaryImplSpecific private import codeql.ruby.frameworks.data.ModelsAsData -import codeql.util.Unit /** Gets the callable in which this node occurs. */ DataFlowCallable nodeGetEnclosingCallable(NodeImpl n) { result = n.getEnclosingCallable() } diff --git a/ruby/ql/lib/codeql/ruby/dataflow/internal/FlowSummaryImpl.qll b/ruby/ql/lib/codeql/ruby/dataflow/internal/FlowSummaryImpl.qll index 6c718a66068..6665e0e7480 100644 --- a/ruby/ql/lib/codeql/ruby/dataflow/internal/FlowSummaryImpl.qll +++ b/ruby/ql/lib/codeql/ruby/dataflow/internal/FlowSummaryImpl.qll @@ -10,6 +10,7 @@ private import FlowSummaryImplSpecific private import DataFlowImplSpecific::Private private import DataFlowImplSpecific::Public private import DataFlowImplCommon +private import codeql.util.Unit /** Provides classes and predicates for defining flow summaries. */ module Public { 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 1b7e8cb326a..227f4ea22fb 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/data/internal/ApiGraphModels.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/data/internal/ApiGraphModels.qll @@ -63,10 +63,9 @@ * the type is not intended to match a static type. */ +private import codeql.util.Unit private import ApiGraphModelsSpecific as Specific -private class Unit = Specific::Unit; - private module API = Specific::API; private module DataFlow = Specific::DataFlow; 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 500197f2f89..6627bd3faf1 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/data/internal/ApiGraphModelsSpecific.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/data/internal/ApiGraphModelsSpecific.qll @@ -20,11 +20,7 @@ */ private import codeql.ruby.AST -private import codeql.ruby.dataflow.internal.DataFlowPrivate as DataFlowPrivate private import ApiGraphModels - -class Unit = DataFlowPrivate::Unit; - // Re-export libraries needed by ApiGraphModels.qll import codeql.ruby.ApiGraphs import codeql.ruby.dataflow.internal.AccessPathSyntax as AccessPathSyntax diff --git a/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowImpl.qll b/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowImpl.qll index 39dbf8dc075..6ea97954bdf 100644 --- a/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowImpl.qll +++ b/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowImpl.qll @@ -8,6 +8,7 @@ private import DataFlowImplCommon private import DataFlowImplSpecific::Private private import DataFlowImplSpecific::Public private import DataFlowImplCommonPublic +private import codeql.util.Unit import DataFlow /** diff --git a/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowImpl1.qll b/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowImpl1.qll index 8415c022111..fcf01966abb 100644 --- a/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowImpl1.qll +++ b/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowImpl1.qll @@ -11,6 +11,7 @@ import DataFlowImplSpecific::Public private import DataFlowImpl import DataFlowImplCommonPublic import FlowStateString +private import codeql.util.Unit /** * A configuration of interprocedural data flow analysis. This defines diff --git a/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowImplSpecific.qll b/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowImplSpecific.qll index 5679ad2ae5d..9244a08582c 100644 --- a/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowImplSpecific.qll +++ b/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowImplSpecific.qll @@ -8,8 +8,6 @@ private import swift as Swift module Private { import DataFlowPrivate import DataFlowDispatch - - class Unit = Swift::Unit; } module Public { diff --git a/swift/ql/lib/codeql/swift/dataflow/internal/FlowSummaryImpl.qll b/swift/ql/lib/codeql/swift/dataflow/internal/FlowSummaryImpl.qll index 6c718a66068..6665e0e7480 100644 --- a/swift/ql/lib/codeql/swift/dataflow/internal/FlowSummaryImpl.qll +++ b/swift/ql/lib/codeql/swift/dataflow/internal/FlowSummaryImpl.qll @@ -10,6 +10,7 @@ private import FlowSummaryImplSpecific private import DataFlowImplSpecific::Private private import DataFlowImplSpecific::Public private import DataFlowImplCommon +private import codeql.util.Unit /** Provides classes and predicates for defining flow summaries. */ module Public { From ea9e8e7ddb6f63dab2f60eb36ad2d06419576ace Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nora=20Dimitrijevi=C4=87?= <d10c@users.noreply.github.com> Date: Tue, 28 Mar 2023 14:57:05 +0200 Subject: [PATCH 564/631] Swift: fix bad join order in Pattern.getImmediateMatchingExpr On Signal-iOS, this snippet: ```codeql class Pattern extends Generated::Pattern { ... Expr getImmediateMatchingExpr() { ... exists(PatternBindingDecl v, int i | v.getPattern(i) = this and result = v.getInit(i) ) ... } ... } ``` Had the following join order: ``` 33926 ~0% {3} r8 = SCAN PatternBindingDecl#ab5153b9::Generated::PatternBindingDecl::getImmediateInit#1#dispred#fff OUTPUT In.1, In.0, In.2 2565045964 ~0% {4} r9 = JOIN r8 WITH pattern_binding_decl_patterns_102#join_rhs ON FIRST 1 OUTPUT Lhs.1, Rhs.1, Lhs.2, Rhs.2 33926 ~0% {2} r10 = JOIN r9 WITH Synth#5f134a93::Synth::convertPatternBindingDeclToRaw#1#ff ON FIRST 2 OUTPUT Lhs.3, Lhs.2 33926 ~2% {2} r11 = JOIN r10 WITH Synth#5f134a93::Synth::convertPatternFromRaw#1#ff ON FIRST 1 OUTPUT Rhs.1, Lhs.1 33926 ~1% {2} r12 = JOIN r11 WITH Element#e67432df::Generated::Element::resolve#ff ON FIRST 1 OUTPUT Lhs.1, Rhs.1 33926 ~4% {2} r13 = JOIN r12 WITH Element#e67432df::Generated::Element::resolve#ff ON FIRST 1 OUTPUT Lhs.1, Rhs.1 ``` After applying `pragma[only_bind_out]` to `this`: ``` 198815 ~1% {2} r4 = SCAN Synth#5f134a93::Synth::TPattern#f OUTPUT In.0, In.0 198815 ~0% {2} r5 = JOIN r4 WITH Element#e67432df::Generated::Element::resolve#ff_10#join_rhs ON FIRST 1 OUTPUT Rhs.1, Lhs.1 75626 ~0% {3} r6 = JOIN r5 WITH PatternBindingDecl#ab5153b9::Generated::PatternBindingDecl::getImmediatePattern#1#dispred#fff_201#join_rhs ON FIRST 1 OUTPUT Rhs.1, Rhs.2, Lhs.1 33926 ~1% {2} r7 = JOIN r6 WITH PatternBindingDecl#ab5153b9::Generated::PatternBindingDecl::getImmediateInit#1#dispred#fff ON FIRST 2 OUTPUT Rhs.2, Lhs.2 33926 ~4% {2} r8 = JOIN r7 WITH Element#e67432df::Generated::Element::resolve#ff ON FIRST 1 OUTPUT Lhs.1, Rhs.1 ``` --- swift/ql/lib/codeql/swift/elements/pattern/Pattern.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/swift/ql/lib/codeql/swift/elements/pattern/Pattern.qll b/swift/ql/lib/codeql/swift/elements/pattern/Pattern.qll index e0c5c580e11..ee97c05c36d 100644 --- a/swift/ql/lib/codeql/swift/elements/pattern/Pattern.qll +++ b/swift/ql/lib/codeql/swift/elements/pattern/Pattern.qll @@ -37,7 +37,7 @@ class Pattern extends Generated::Pattern { ) or exists(PatternBindingDecl v, int i | - v.getPattern(i) = this and + v.getPattern(i) = pragma[only_bind_out](this) and result = v.getInit(i) ) } From 94614320b5639cc2ef5a46cbe8e9c9ac54238559 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nora=20Dimitrijevi=C4=87?= <d10c@users.noreply.github.com> Date: Tue, 28 Mar 2023 15:15:16 +0200 Subject: [PATCH 565/631] Swift: refactor OptionalSomeDecl -> OptionalSomeContentSet --- .../dataflow/internal/DataFlowPrivate.qll | 30 ++++++++++--------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowPrivate.qll b/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowPrivate.qll index 2becda54662..3a6877534d7 100644 --- a/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowPrivate.qll +++ b/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowPrivate.qll @@ -592,17 +592,17 @@ predicate storeStep(Node node1, ContentSet c, Node node2) { or // creation of an optional via implicit conversion, // i.e. from `f(x)` where `x: T` into `f(.some(x))` where the context `f` expects a `T?`. - exists(InjectIntoOptionalExpr e, OptionalSomeDecl someDecl | + exists(InjectIntoOptionalExpr e | e.convertsFrom(node1.asExpr()) and node2 = node1 and // HACK: we should ideally have a separate Node case for the (hidden) InjectIntoOptionalExpr - c.isSingleton(any(Content::EnumContent ec | ec.getParam() = someDecl.getParam(0))) + c instanceof OptionalSomeContentSet ) or // creation of an optional by returning from an optional initializer (`init?`) - exists(ConstructorDecl init, OptionalType initRetType, OptionalSomeDecl someDecl | + exists(ConstructorDecl init, OptionalType initRetType | node1.asExpr().(CallExpr).getStaticTarget() = init and node2 = node1 and // HACK: again, we should ideally have a separate Node case here, and not reuse the CallExpr - c.isSingleton(any(Content::EnumContent ec | ec.getParam() = someDecl.getParam(0))) and + c instanceof OptionalSomeContentSet and init.getInterfaceType().(FunctionType).getResult().(FunctionType).getResult() = initRetType ) or @@ -649,10 +649,10 @@ predicate readStep(Node node1, ContentSet c, Node node2) { ) or // read of an optional .some member via `let x: T = y: T?` pattern matching - exists(OptionalSomePattern pat, OptionalSomeDecl someDecl | + exists(OptionalSomePattern pat | node1.asPattern() = pat and node2.asPattern() = pat.getSubPattern() and - c.isSingleton(any(Content::EnumContent ec | ec.getParam() = someDecl.getParam(0))) + c instanceof OptionalSomeContentSet ) } @@ -672,15 +672,17 @@ predicate clearsContent(Node n, ContentSet c) { predicate expectsContent(Node n, ContentSet c) { none() } /** - * The global singleton `Optional.some` enum element. + * The global singleton `Optional.some` content set. */ -private class OptionalSomeDecl extends EnumElementDecl { - OptionalSomeDecl() { - exists(EnumDecl enum | - this.getName() = "some" and - this.getDeclaringDecl() = enum and - enum.getName() = "Optional" and - enum.getModule().getName() = "Swift" +private class OptionalSomeContentSet extends ContentSet { + OptionalSomeContentSet() { + exists(EnumDecl optional, EnumElementDecl some | + some.getDeclaringDecl() = optional and + some.getName() = "some" and + optional.getName() = "Optional" and + optional.getModule().getName() = "Swift" + | + this.isSingleton(any(Content::EnumContent ec | ec.getParam() = some.getParam(0))) ) } } From 97ec808a6f5dde9a662eff1dfdb918905807e82c Mon Sep 17 00:00:00 2001 From: Edward Minnix III <egregius313@github.com> Date: Tue, 28 Mar 2023 10:28:15 -0400 Subject: [PATCH 566/631] Make configuration public Co-authored-by: Tony Torralba <atorralba@users.noreply.github.com> --- java/ql/lib/semmle/code/java/security/InsecureLdapAuthQuery.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/ql/lib/semmle/code/java/security/InsecureLdapAuthQuery.qll b/java/ql/lib/semmle/code/java/security/InsecureLdapAuthQuery.qll index 4d4546c7f8a..6fb53b769e4 100644 --- a/java/ql/lib/semmle/code/java/security/InsecureLdapAuthQuery.qll +++ b/java/ql/lib/semmle/code/java/security/InsecureLdapAuthQuery.qll @@ -9,7 +9,7 @@ import semmle.code.java.security.InsecureLdapAuth /** * A taint-tracking configuration for `ldap://` URL in LDAP authentication. */ -private module InsecureLdapUrlConfig implements DataFlow::ConfigSig { +module InsecureLdapUrlConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node src) { src.asExpr() instanceof InsecureLdapUrl } predicate isSink(DataFlow::Node sink) { sink instanceof InsecureLdapUrlSink } From ce191e1f9f83cc31804ad58d52165583dd65a5ed Mon Sep 17 00:00:00 2001 From: Tony Torralba <atorralba@users.noreply.github.com> Date: Tue, 28 Mar 2023 16:47:01 +0200 Subject: [PATCH 567/631] Fix InsecureLdapAuth tags --- java/ql/src/Security/CWE/CWE-522/InsecureLdapAuth.ql | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/java/ql/src/Security/CWE/CWE-522/InsecureLdapAuth.ql b/java/ql/src/Security/CWE/CWE-522/InsecureLdapAuth.ql index dabd0d2c645..fb7848bb05e 100644 --- a/java/ql/src/Security/CWE/CWE-522/InsecureLdapAuth.ql +++ b/java/ql/src/Security/CWE/CWE-522/InsecureLdapAuth.ql @@ -2,12 +2,11 @@ * @name Insecure LDAP authentication * @description LDAP authentication with credentials sent in cleartext makes sensitive information vulnerable to remote attackers * @kind path-problem - * @problem.severity warning + * @problem.severity error * @security-severity 8.8 - * @precision medium + * @precision high * @id java/insecure-ldap-auth * @tags security - * experimental * external/cwe/cwe-522 * external/cwe/cwe-319 */ From 080acdbfffad03e50617046d15a859f6ade51da2 Mon Sep 17 00:00:00 2001 From: Asger F <asgerf@github.com> Date: Tue, 28 Mar 2023 17:29:26 +0200 Subject: [PATCH 568/631] JS: remove links to docs file... again --- docs/codeql/codeql-language-guides/codeql-for-javascript.rst | 2 -- ...specifying-additional-remote-flow-sources-for-javascript.rst | 2 -- 2 files changed, 4 deletions(-) diff --git a/docs/codeql/codeql-language-guides/codeql-for-javascript.rst b/docs/codeql/codeql-language-guides/codeql-for-javascript.rst index b94c5252107..be3950c53ec 100644 --- a/docs/codeql/codeql-language-guides/codeql-for-javascript.rst +++ b/docs/codeql/codeql-language-guides/codeql-for-javascript.rst @@ -28,8 +28,6 @@ Experiment and learn how to write effective and efficient queries for CodeQL dat - :doc:`Using flow labels for precise data flow analysis <using-flow-labels-for-precise-data-flow-analysis>`: You can associate flow labels with each value tracked by the flow analysis to determine whether the flow contains potential vulnerabilities. -- :doc:`Customizing library models for JavaScript <customizing-library-models-for-javascript>`: You can model the libraries used in your code without making changes to the CodeQL standard library by specifying source, sink, and flow summaries in a data extension file. - - :doc:`Using type tracking for API modeling <using-type-tracking-for-api-modeling>`: You can track data through an API by creating a model using the CodeQL type-tracking library for JavaScript. - :doc:`Abstract syntax tree classes for working with JavaScript and TypeScript programs <abstract-syntax-tree-classes-for-working-with-javascript-and-typescript-programs>`: CodeQL has a large selection of classes for representing the abstract syntax tree of JavaScript and TypeScript programs. diff --git a/docs/codeql/codeql-language-guides/specifying-additional-remote-flow-sources-for-javascript.rst b/docs/codeql/codeql-language-guides/specifying-additional-remote-flow-sources-for-javascript.rst index 81cc1ff854c..7ee1706db45 100644 --- a/docs/codeql/codeql-language-guides/specifying-additional-remote-flow-sources-for-javascript.rst +++ b/docs/codeql/codeql-language-guides/specifying-additional-remote-flow-sources-for-javascript.rst @@ -10,8 +10,6 @@ Specifying additional remote flow sources for JavaScript Specifying remote flow sources with the JSON format described here is soon to be deprecated and will be removed in the future. - See :ref:`Customizing Library Models for JavaScript <customizing-library-models-for-javascript>`. - You can model potential sources of untrusted user input in your code without making changes to the CodeQL standard library by specifying extra remote flow sources in an external file. As mentioned in the :ref:`Data flow cheat sheet for JavaScript <data-flow-cheat-sheet-for-javascript--untrusted-data>`, the CodeQL libraries for JavaScript From 31512b86270a9d72287bd875800bc90d23badd81 Mon Sep 17 00:00:00 2001 From: Jeroen Ketema <jketema@github.com> Date: Tue, 28 Mar 2023 17:36:00 +0200 Subject: [PATCH 569/631] Swift: Use `DataFlow::ConfigSig` in `StaticInitializationVector.ql` --- .../CWE-1204/StaticInitializationVector.ql | 20 +++++++++---------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/swift/ql/src/queries/Security/CWE-1204/StaticInitializationVector.ql b/swift/ql/src/queries/Security/CWE-1204/StaticInitializationVector.ql index 0324be01da9..e624c9efd2e 100644 --- a/swift/ql/src/queries/Security/CWE-1204/StaticInitializationVector.ql +++ b/swift/ql/src/queries/Security/CWE-1204/StaticInitializationVector.ql @@ -14,7 +14,7 @@ import swift import codeql.swift.dataflow.DataFlow import codeql.swift.dataflow.TaintTracking -import DataFlow::PathGraph +import StaticInitializationVectorFlow::PathGraph /** * A static IV is created through either a byte array or string literals. @@ -56,23 +56,21 @@ class EncryptionInitializationSink extends Expr { * A dataflow configuration from the source of a static IV to expressions that use * it to initialize a cipher. */ -class StaticInitializationVectorConfig extends TaintTracking::Configuration { - StaticInitializationVectorConfig() { this = "StaticInitializationVectorConfig" } - - override predicate isSource(DataFlow::Node node) { +module StaticInitializationVectorConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node node) { node.asExpr() instanceof StaticInitializationVectorSource } - override predicate isSink(DataFlow::Node node) { - node.asExpr() instanceof EncryptionInitializationSink - } + predicate isSink(DataFlow::Node node) { node.asExpr() instanceof EncryptionInitializationSink } } +module StaticInitializationVectorFlow = TaintTracking::Global<StaticInitializationVectorConfig>; + // The query itself from - StaticInitializationVectorConfig config, DataFlow::PathNode sourceNode, - DataFlow::PathNode sinkNode -where config.hasFlowPath(sourceNode, sinkNode) + StaticInitializationVectorFlow::PathNode sourceNode, + StaticInitializationVectorFlow::PathNode sinkNode +where StaticInitializationVectorFlow::flowPath(sourceNode, sinkNode) select sinkNode.getNode(), sourceNode, sinkNode, "The static value '" + sourceNode.getNode().toString() + "' is used as an initialization vector for encryption." From 1592b578d9e11cbea46a878e497dd04a9566115b Mon Sep 17 00:00:00 2001 From: Jeroen Ketema <jketema@github.com> Date: Tue, 28 Mar 2023 17:36:37 +0200 Subject: [PATCH 570/631] Swift: Use `DataFlow::ConfigSig` in `ConstantPassword.ql` --- .../Security/CWE-259/ConstantPassword.ql | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/swift/ql/src/queries/Security/CWE-259/ConstantPassword.ql b/swift/ql/src/queries/Security/CWE-259/ConstantPassword.ql index 48e53f50ab0..fa3500ccf9b 100644 --- a/swift/ql/src/queries/Security/CWE-259/ConstantPassword.ql +++ b/swift/ql/src/queries/Security/CWE-259/ConstantPassword.ql @@ -14,7 +14,7 @@ import swift import codeql.swift.dataflow.DataFlow import codeql.swift.dataflow.TaintTracking import codeql.swift.dataflow.FlowSteps -import DataFlow::PathGraph +import ConstantPasswordFlow::PathGraph /** * A constant password is created through either a byte array or string literals. @@ -60,18 +60,16 @@ class ConstantPasswordSink extends Expr { * A taint configuration from the source of constants passwords to expressions that use * them to initialize password-based encryption keys. */ -class ConstantPasswordConfig extends TaintTracking::Configuration { - ConstantPasswordConfig() { this = "ConstantPasswordConfig" } +module ConstantPasswordConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node node) { node.asExpr() instanceof ConstantPasswordSource } - override predicate isSource(DataFlow::Node node) { - node.asExpr() instanceof ConstantPasswordSource - } - - override predicate isSink(DataFlow::Node node) { node.asExpr() instanceof ConstantPasswordSink } + predicate isSink(DataFlow::Node node) { node.asExpr() instanceof ConstantPasswordSink } } +module ConstantPasswordFlow = TaintTracking::Global<ConstantPasswordConfig>; + // The query itself -from ConstantPasswordConfig config, DataFlow::PathNode sourceNode, DataFlow::PathNode sinkNode -where config.hasFlowPath(sourceNode, sinkNode) +from ConstantPasswordFlow::PathNode sourceNode, ConstantPasswordFlow::PathNode sinkNode +where ConstantPasswordFlow::flowPath(sourceNode, sinkNode) select sinkNode.getNode(), sourceNode, sinkNode, "The value '" + sourceNode.getNode().toString() + "' is used as a constant password." From cc23ba3698ce8640e7eaee2d32b05c3af603d71b Mon Sep 17 00:00:00 2001 From: Jeroen Ketema <jketema@github.com> Date: Tue, 28 Mar 2023 17:37:05 +0200 Subject: [PATCH 571/631] Swift: Use `DataFlow::ConfigSig` in `HardcodedEncryptionKey.ql` --- .../Security/CWE-321/HardcodedEncryptionKey.ql | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/swift/ql/src/queries/Security/CWE-321/HardcodedEncryptionKey.ql b/swift/ql/src/queries/Security/CWE-321/HardcodedEncryptionKey.ql index 4782d13dd14..d44e6a3187b 100644 --- a/swift/ql/src/queries/Security/CWE-321/HardcodedEncryptionKey.ql +++ b/swift/ql/src/queries/Security/CWE-321/HardcodedEncryptionKey.ql @@ -13,7 +13,7 @@ import swift import codeql.swift.dataflow.DataFlow import codeql.swift.dataflow.TaintTracking -import DataFlow::PathGraph +import HardcodedKeyFlow::PathGraph /** * An `Expr` that is used to initialize a key. @@ -62,17 +62,17 @@ class EncryptionKeySink extends Expr { * A taint configuration from the key source to expressions that use * it to initialize a cipher. */ -class HardcodedKeyConfig extends TaintTracking::Configuration { - HardcodedKeyConfig() { this = "HardcodedKeyConfig" } +module HardcodedKeyConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node node) { node.asExpr() instanceof KeySource } - override predicate isSource(DataFlow::Node node) { node.asExpr() instanceof KeySource } - - override predicate isSink(DataFlow::Node node) { node.asExpr() instanceof EncryptionKeySink } + predicate isSink(DataFlow::Node node) { node.asExpr() instanceof EncryptionKeySink } } +module HardcodedKeyFlow = TaintTracking::Global<HardcodedKeyConfig>; + // The query itself -from HardcodedKeyConfig config, DataFlow::PathNode sourceNode, DataFlow::PathNode sinkNode -where config.hasFlowPath(sourceNode, sinkNode) +from HardcodedKeyFlow::PathNode sourceNode, HardcodedKeyFlow::PathNode sinkNode +where HardcodedKeyFlow::flowPath(sourceNode, sinkNode) select sinkNode.getNode(), sourceNode, sinkNode, "The key '" + sinkNode.getNode().toString() + "' has been initialized with hard-coded values from $@.", sourceNode, From a8599eb6895e7edc04186a733e62c09195eb0f30 Mon Sep 17 00:00:00 2001 From: Jeroen Ketema <jketema@github.com> Date: Tue, 28 Mar 2023 17:37:37 +0200 Subject: [PATCH 572/631] Swift: Use `DataFlow::ConfigSig` in `ECBEncryption.ql` --- .../queries/Security/CWE-327/ECBEncryption.ql | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/swift/ql/src/queries/Security/CWE-327/ECBEncryption.ql b/swift/ql/src/queries/Security/CWE-327/ECBEncryption.ql index d9a47a139f8..f5c66684fea 100644 --- a/swift/ql/src/queries/Security/CWE-327/ECBEncryption.ql +++ b/swift/ql/src/queries/Security/CWE-327/ECBEncryption.ql @@ -13,7 +13,7 @@ import swift import codeql.swift.dataflow.DataFlow import codeql.swift.dataflow.TaintTracking -import DataFlow::PathGraph +import EcbEncryptionFlow::PathGraph /** * An `Expr` that is used to initialize the block mode of a cipher. @@ -54,22 +54,22 @@ class Blowfish extends BlockMode { * A taint configuration from the constructor of ECB mode to expressions that use * it to initialize a cipher. */ -class EcbEncryptionConfig extends DataFlow::Configuration { - EcbEncryptionConfig() { this = "EcbEncryptionConfig" } - - override predicate isSource(DataFlow::Node node) { +module EcbEncryptionConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node node) { exists(CallExpr call | call.getStaticTarget().(MethodDecl).hasQualifiedName("ECB", "init()") and node.asExpr() = call ) } - override predicate isSink(DataFlow::Node node) { node.asExpr() instanceof BlockMode } + predicate isSink(DataFlow::Node node) { node.asExpr() instanceof BlockMode } } +module EcbEncryptionFlow = DataFlow::Global<EcbEncryptionConfig>; + // The query itself -from EcbEncryptionConfig config, DataFlow::PathNode sourceNode, DataFlow::PathNode sinkNode -where config.hasFlowPath(sourceNode, sinkNode) +from EcbEncryptionFlow::PathNode sourceNode, EcbEncryptionFlow::PathNode sinkNode +where EcbEncryptionFlow::flowPath(sourceNode, sinkNode) select sinkNode.getNode(), sourceNode, sinkNode, "The initialization of the cipher '" + sinkNode.getNode().toString() + "' uses the insecure ECB block mode from $@.", sourceNode, sourceNode.getNode().toString() From 42248220b482029606f9fea657c59d65475f5792 Mon Sep 17 00:00:00 2001 From: Jeroen Ketema <jketema@github.com> Date: Tue, 28 Mar 2023 17:38:11 +0200 Subject: [PATCH 573/631] Swift: Use `DataFlow::ConfigSig` in `WeakSensitiveDataHashing.ql` --- .../CWE-328/WeakSensitiveDataHashing.ql | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/swift/ql/src/queries/Security/CWE-328/WeakSensitiveDataHashing.ql b/swift/ql/src/queries/Security/CWE-328/WeakSensitiveDataHashing.ql index 5a6fc396257..a5c884bd081 100755 --- a/swift/ql/src/queries/Security/CWE-328/WeakSensitiveDataHashing.ql +++ b/swift/ql/src/queries/Security/CWE-328/WeakSensitiveDataHashing.ql @@ -15,17 +15,17 @@ import swift import codeql.swift.security.SensitiveExprs import codeql.swift.dataflow.DataFlow import codeql.swift.dataflow.TaintTracking -import DataFlow::PathGraph +import WeakHashingFlow::PathGraph -class WeakHashingConfig extends TaintTracking::Configuration { - WeakHashingConfig() { this = "WeakHashingConfig" } +module WeakHashingConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node node) { node instanceof WeakHashingConfigImpl::Source } - override predicate isSource(DataFlow::Node node) { node instanceof WeakHashingConfig::Source } - - override predicate isSink(DataFlow::Node node) { node instanceof WeakHashingConfig::Sink } + predicate isSink(DataFlow::Node node) { node instanceof WeakHashingConfigImpl::Sink } } -module WeakHashingConfig { +module WeakHashingFlow = TaintTracking::Global<WeakHashingConfig>; + +module WeakHashingConfigImpl { class Source extends DataFlow::Node { Source() { this.asExpr() instanceof SensitiveExpr } } @@ -52,11 +52,11 @@ module WeakHashingConfig { } from - WeakHashingConfig config, DataFlow::PathNode source, DataFlow::PathNode sink, string algorithm, + WeakHashingFlow::PathNode source, WeakHashingFlow::PathNode sink, string algorithm, SensitiveExpr expr where - config.hasFlowPath(source, sink) and - algorithm = sink.getNode().(WeakHashingConfig::Sink).getAlgorithm() and + WeakHashingFlow::flowPath(source, sink) and + algorithm = sink.getNode().(WeakHashingConfigImpl::Sink).getAlgorithm() and expr = source.getNode().asExpr() select sink.getNode(), source, sink, "Insecure hashing algorithm (" + algorithm + ") depends on $@.", source.getNode(), From b97b3d9975c784636fae0a2329609d766d83f9a1 Mon Sep 17 00:00:00 2001 From: Jeroen Ketema <jketema@github.com> Date: Tue, 28 Mar 2023 17:38:46 +0200 Subject: [PATCH 574/631] Swift: Use `DtatFlow::ConfigSig` in `InsecureTLS.ql` --- .../src/queries/Security/CWE-757/InsecureTLS.ql | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/swift/ql/src/queries/Security/CWE-757/InsecureTLS.ql b/swift/ql/src/queries/Security/CWE-757/InsecureTLS.ql index 537b0844295..62cb0db697e 100644 --- a/swift/ql/src/queries/Security/CWE-757/InsecureTLS.ql +++ b/swift/ql/src/queries/Security/CWE-757/InsecureTLS.ql @@ -14,18 +14,16 @@ import swift import codeql.swift.dataflow.DataFlow import codeql.swift.dataflow.TaintTracking import codeql.swift.dataflow.FlowSources -import DataFlow::PathGraph +import InsecureTlsFlow::PathGraph /** * A taint config to detect insecure configuration of `NSURLSessionConfiguration` */ -class InsecureTlsConfig extends TaintTracking::Configuration { - InsecureTlsConfig() { this = "InsecureTLSConfig" } - +module InsecureTlsConfig implements DataFlow::ConfigSig { /** * Holds for enum values that represent an insecure version of TLS */ - override predicate isSource(DataFlow::Node node) { + predicate isSource(DataFlow::Node node) { node.asExpr().(MethodLookupExpr).getMember().(EnumElementDecl).getName() = ["TLSv10", "TLSv11", "tlsProtocol10", "tlsProtocol11"] } @@ -33,7 +31,7 @@ class InsecureTlsConfig extends TaintTracking::Configuration { /** * Holds for assignment of TLS-related properties of `NSURLSessionConfiguration` */ - override predicate isSink(DataFlow::Node node) { + predicate isSink(DataFlow::Node node) { exists(AssignExpr assign | assign.getSource() = node.asExpr() and assign.getDest().(MemberRefExpr).getMember().(ConcreteVarDecl).getName() = @@ -45,6 +43,8 @@ class InsecureTlsConfig extends TaintTracking::Configuration { } } -from InsecureTlsConfig config, DataFlow::PathNode sourceNode, DataFlow::PathNode sinkNode -where config.hasFlowPath(sourceNode, sinkNode) +module InsecureTlsFlow = TaintTracking::Global<InsecureTlsConfig>; + +from InsecureTlsFlow::PathNode sourceNode, InsecureTlsFlow::PathNode sinkNode +where InsecureTlsFlow::flowPath(sourceNode, sinkNode) select sinkNode.getNode(), sourceNode, sinkNode, "This TLS configuration is insecure." From 60f033f10cb9cbdd465b0e53367ca30baa9b7048 Mon Sep 17 00:00:00 2001 From: Jeroen Ketema <jketema@github.com> Date: Tue, 28 Mar 2023 17:39:18 +0200 Subject: [PATCH 575/631] Swift: Use `DataFlow::ConfigSig` in `ConstantSalt.ql` --- .../queries/Security/CWE-760/ConstantSalt.ql | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/swift/ql/src/queries/Security/CWE-760/ConstantSalt.ql b/swift/ql/src/queries/Security/CWE-760/ConstantSalt.ql index e510acffe3a..3b519527f41 100644 --- a/swift/ql/src/queries/Security/CWE-760/ConstantSalt.ql +++ b/swift/ql/src/queries/Security/CWE-760/ConstantSalt.ql @@ -14,7 +14,7 @@ import swift import codeql.swift.dataflow.DataFlow import codeql.swift.dataflow.TaintTracking import codeql.swift.dataflow.FlowSteps -import DataFlow::PathGraph +import ConstantSaltFlow::PathGraph /** * A constant salt is created through either a byte array or string literals. @@ -52,19 +52,19 @@ class ConstantSaltSink extends Expr { /** * A taint configuration from the source of constants salts to expressions that use - * them to initialize password-based enecryption keys. + * them to initialize password-based encryption keys. */ -class ConstantSaltConfig extends TaintTracking::Configuration { - ConstantSaltConfig() { this = "ConstantSaltConfig" } +module ConstantSaltConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node node) { node.asExpr() instanceof ConstantSaltSource } - override predicate isSource(DataFlow::Node node) { node.asExpr() instanceof ConstantSaltSource } - - override predicate isSink(DataFlow::Node node) { node.asExpr() instanceof ConstantSaltSink } + predicate isSink(DataFlow::Node node) { node.asExpr() instanceof ConstantSaltSink } } +module ConstantSaltFlow = TaintTracking::Global<ConstantSaltConfig>; + // The query itself -from ConstantSaltConfig config, DataFlow::PathNode sourceNode, DataFlow::PathNode sinkNode -where config.hasFlowPath(sourceNode, sinkNode) +from ConstantSaltFlow::PathNode sourceNode, ConstantSaltFlow::PathNode sinkNode +where ConstantSaltFlow::flowPath(sourceNode, sinkNode) select sinkNode.getNode(), sourceNode, sinkNode, "The value '" + sourceNode.getNode().toString() + "' is used as a constant salt, which is insecure for hashing passwords." From a381aa4d37c4c88a8bd43d4254bd0cdff0ced746 Mon Sep 17 00:00:00 2001 From: Jeroen Ketema <jketema@github.com> Date: Tue, 28 Mar 2023 17:39:58 +0200 Subject: [PATCH 576/631] Swift: Use `DataFlow::ConfigSig` in `InsufficientHashIterations.ql` --- .../CWE-916/InsufficientHashIterations.ql | 20 +++++++++---------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/swift/ql/src/queries/Security/CWE-916/InsufficientHashIterations.ql b/swift/ql/src/queries/Security/CWE-916/InsufficientHashIterations.ql index 310b038d3f3..7111ac61ed7 100644 --- a/swift/ql/src/queries/Security/CWE-916/InsufficientHashIterations.ql +++ b/swift/ql/src/queries/Security/CWE-916/InsufficientHashIterations.ql @@ -13,7 +13,7 @@ import swift import codeql.swift.dataflow.DataFlow import codeql.swift.dataflow.TaintTracking -import DataFlow::PathGraph +import InsufficientHashIterationsFlow::PathGraph /** * An `Expr` that is used to initialize a password-based encryption key. @@ -46,21 +46,19 @@ class InsufficientHashIterationsSink extends Expr { * A dataflow configuration from the hash iterations source to expressions that use * it to initialize hash functions. */ -class InsufficientHashIterationsConfig extends TaintTracking::Configuration { - InsufficientHashIterationsConfig() { this = "InsufficientHashIterationsConfig" } +module InsufficientHashIterationsConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node node) { node.asExpr() instanceof IterationsSource } - override predicate isSource(DataFlow::Node node) { node.asExpr() instanceof IterationsSource } - - override predicate isSink(DataFlow::Node node) { - node.asExpr() instanceof InsufficientHashIterationsSink - } + predicate isSink(DataFlow::Node node) { node.asExpr() instanceof InsufficientHashIterationsSink } } +module InsufficientHashIterationsFlow = TaintTracking::Global<InsufficientHashIterationsConfig>; + // The query itself from - InsufficientHashIterationsConfig config, DataFlow::PathNode sourceNode, - DataFlow::PathNode sinkNode -where config.hasFlowPath(sourceNode, sinkNode) + InsufficientHashIterationsFlow::PathNode sourceNode, + InsufficientHashIterationsFlow::PathNode sinkNode +where InsufficientHashIterationsFlow::flowPath(sourceNode, sinkNode) select sinkNode.getNode(), sourceNode, sinkNode, "The value '" + sourceNode.getNode().toString() + "' is an insufficient number of iterations for secure password hashing." From 6699a0cb1a6925abdc1dca15d0bfc89598031468 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen <mathiasvp@github.com> Date: Tue, 28 Mar 2023 16:39:24 +0100 Subject: [PATCH 577/631] C++: Add range analysis for binary multiplication. --- .../semantic/analysis/RangeAnalysisStage.qll | 110 ++++++++++++++++++ 1 file changed, 110 insertions(+) diff --git a/cpp/ql/lib/experimental/semmle/code/cpp/semantic/analysis/RangeAnalysisStage.qll b/cpp/ql/lib/experimental/semmle/code/cpp/semantic/analysis/RangeAnalysisStage.qll index 2cd13a63c4d..0c1dbd99cad 100644 --- a/cpp/ql/lib/experimental/semmle/code/cpp/semantic/analysis/RangeAnalysisStage.qll +++ b/cpp/ql/lib/experimental/semmle/code/cpp/semantic/analysis/RangeAnalysisStage.qll @@ -1062,6 +1062,20 @@ module RangeStage<DeltaSig D, BoundSig<D> Bounds, LangSig<D> LangParam, UtilSig< or upper = false and delta = D::fromFloat(-D::toFloat(d_max).abs() + 1) ) + or + exists( + SemZeroBound bLeft, SemZeroBound bRight, D::Delta dLeft, D::Delta dRight, boolean fbeLeft, + boolean fbeRight, D::Delta odLeft, D::Delta odRight, SemReason rLeft, SemReason rRight + | + boundedMulOperand(e, upper, bLeft, true, dLeft, fbeLeft, odLeft, rLeft) and + boundedMulOperand(e, upper, bRight, false, dRight, fbeRight, odRight, rRight) and + delta = D::fromFloat(D::toFloat(dLeft) * D::toFloat(dRight)) and + fromBackEdge = fbeLeft.booleanOr(fbeRight) + | + b = bLeft and origdelta = odLeft and reason = rLeft + or + b = bRight and origdelta = odRight and reason = rRight + ) ) } @@ -1095,4 +1109,100 @@ module RangeStage<DeltaSig D, BoundSig<D> Bounds, LangSig<D> LangParam, UtilSig< ) { bounded(rem.getRightOperand(), b, delta, upper, fromBackEdge, origdelta, reason) } + + /** + * Define `cmp(true) = <=` and `cmp(false) >=`. + * + * Holds if `mul = left * right`, and in order to know if `mul cmp(upper) B + k` (for + * some `B` and `k`) we need to know that `left cmp(upperLeft) B1 + k1` and + * `right cmp(upperRight) B2 + k2` (for some `B1`, `B2`, `k1`, and `k2`). + */ + pragma[nomagic] + private predicate boundedMulOperandCand( + SemMulExpr mul, SemExpr left, SemExpr right, boolean upper, boolean upperLeft, + boolean upperRight + ) { + not boundFlowStepMul(mul, _, _) and + mul.getLeftOperand() = left and + mul.getRightOperand() = right and + ( + semPositive(left) and + ( + // left, right >= 0 + semPositive(right) and + ( + // max(left * right) = max(left) * max(right) + upper = true and + upperLeft = true and + upperRight = true + or + // min(left * right) = min(left) * min(right) + upper = false and + upperLeft = false and + upperRight = false + ) + or + // left >= 0, right <= 0 + semNegative(right) and + ( + // max(left * right) = min(left) * max(right) + upper = true and + upperLeft = false and + upperRight = true + or + // min(left * right) = max(left) * min(right) + upper = false and + upperLeft = true and + upperRight = false + ) + ) + or + semNegative(left) and + ( + // left <= 0, right >= 0 + semPositive(right) and + ( + // max(left * right) = max(left) * min(right) + upper = true and + upperLeft = true and + upperRight = false + or + // min(left * right) = min(left) * max(right) + upper = false and + upperLeft = false and + upperRight = true + ) + or + // left, right <= 0 + semNegative(right) and + ( + // max(left * right) = min(left) * min(right) + upper = true and + upperLeft = false and + upperRight = false + or + // min(left * right) = max(left) * max(right) + upper = false and + upperLeft = true and + upperRight = true + ) + ) + ) + } + + pragma[nomagic] + private predicate boundedMulOperand( + SemMulExpr mul, boolean upper, SemZeroBound b, boolean isLeft, D::Delta delta, + boolean fromBackEdge, D::Delta origdelta, SemReason reason + ) { + exists(boolean upperLeft, boolean upperRight, SemExpr left, SemExpr right | + boundedMulOperandCand(mul, left, right, upper, upperLeft, upperRight) + | + isLeft = true and + bounded(left, b, delta, upperLeft, fromBackEdge, origdelta, reason) + or + isLeft = false and + bounded(right, b, delta, upperRight, fromBackEdge, origdelta, reason) + ) + } } From 8021958ac5383a5aed472d6167de34bd2e8863e8 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen <mathiasvp@github.com> Date: Tue, 28 Mar 2023 16:39:33 +0100 Subject: [PATCH 578/631] C++: Accept test changes. --- .../SimpleRangeAnalysis_tests.cpp | 80 +++++++++---------- 1 file changed, 40 insertions(+), 40 deletions(-) diff --git a/cpp/ql/test/library-tests/ir/range-analysis/SimpleRangeAnalysis_tests.cpp b/cpp/ql/test/library-tests/ir/range-analysis/SimpleRangeAnalysis_tests.cpp index f87b1fb103a..484c4954548 100644 --- a/cpp/ql/test/library-tests/ir/range-analysis/SimpleRangeAnalysis_tests.cpp +++ b/cpp/ql/test/library-tests/ir/range-analysis/SimpleRangeAnalysis_tests.cpp @@ -300,17 +300,17 @@ int test_mult01(int a, int b) { range(a); // $ range=<=11 range=>=3 range(b); // $ range=<=23 range=>=5 int r = a*b; // 15 .. 253 - range(r); + range(r); // $ range=<=253 range=>=15 total += r; - range(total); // $ MISSING: range=>=1 + range(total); // $ range=<=253 range=>=15 } if (3 <= a && a <= 11 && 0 <= b && b <= 23) { range(a); // $ range=<=11 range=>=3 range(b); // $ range=<=23 range=>=0 int r = a*b; // 0 .. 253 - range(r); + range(r); // $ range=<=253 range=>=0 total += r; - range(total); // $ MISSING: range=>=0 range=>=3+0 + range(total); // $ range=<=3+253 range=<=506 range=>=0 range=>=3+0 } if (3 <= a && a <= 11 && -13 <= b && b <= 23) { range(a); // $ range=<=11 range=>=3 @@ -324,19 +324,19 @@ int test_mult01(int a, int b) { range(a); // $ range=<=11 range=>=3 range(b); // $ range=<=0 range=>=-13 int r = a*b; // -143 .. 0 - range(r); + range(r); // $ range=<=0 range=>=-143 total += r; - range(total); // $ MISSING: range=<=3+0 + range(total); // $ range=<=3+0 range=>=3-143 } if (3 <= a && a <= 11 && -13 <= b && b <= -7) { range(a); // $ range=<=11 range=>=3 range(b); // $ range=<=-7 range=>=-13 int r = a*b; // -143 .. -21 - range(r); + range(r); // $ range=<=-21 range=>=-143 total += r; - range(total); // $ MISSING: range=<=3-1 + range(total); // $ range=<=3-21 range=>=3-143 range=>=3-286 } - range(total); // $ MISSING: range=<=3+0 + range(total); // $ range=<=3+0 range=>=3-143 range=>=3-286 return total; } @@ -348,17 +348,17 @@ int test_mult02(int a, int b) { range(a); // $ range=<=11 range=>=0 range(b); // $ range=<=23 range=>=5 int r = a*b; // 0 .. 253 - range(r); + range(r); // $ range=<=253 range=>=0 total += r; - range(total); // $ MISSING: range=>=0 + range(total); // $ range=>=0 range=<=253 } if (0 <= a && a <= 11 && 0 <= b && b <= 23) { range(a); // $ range=<=11 range=>=0 range(b); // $ range=<=23 range=>=0 int r = a*b; // 0 .. 253 - range(r); + range(r); // $ range=<=253 range=>=0 total += r; - range(total); // $ MISSING: range=>=0 range=>=0+0 + range(total); // $ range=>=0 range=>=0+0 range=<=0+253 range=<=506 } if (0 <= a && a <= 11 && -13 <= b && b <= 23) { range(a); // $ range=<=11 range=>=0 @@ -372,19 +372,19 @@ int test_mult02(int a, int b) { range(a); // $ range=<=11 range=>=0 range(b); // $ range=<=0 range=>=-13 int r = a*b; // -143 .. 0 - range(r); + range(r); // $ range=<=0 range=>=-143 total += r; - range(total); // $ MISSING: range=<=0+0 + range(total); // $ range=<=0+0 range=>=0-143 } if (0 <= a && a <= 11 && -13 <= b && b <= -7) { range(a); // $ range=<=11 range=>=0 range(b); // $ range=<=-7 range=>=-13 int r = a*b; // -143 .. 0 - range(r); + range(r); // $ range=<=0 range=>=-143 total += r; - range(total); // $ MISSING: range=<=0+0 + range(total); // $ range=<=0+0 range=>=0-143 range=>=0-286 } - range(total); // $ MISSING: range=<=0+0 + range(total); // $ range=<=0+0 range=>=0-143 range=>=0-286 return total; } @@ -445,15 +445,15 @@ int test_mult04(int a, int b) { range(b); // $ range=<=23 range=>=5 int r = a*b; // -391 .. 0 total += r; - range(total); // $ MISSING: range=<=0 + range(total); // $ range=<=0 range=>=-391 } if (-17 <= a && a <= 0 && 0 <= b && b <= 23) { range(a); // $ range=<=0 range=>=-17 range(b); // $ range=<=23 range=>=0 int r = a*b; // -391 .. 0 - range(r); + range(r); // $ range=<=0 range=>=-391 total += r; - range(total); // $ MISSING: range="<=- ...+0" range=<=0 + range(total); // $ range="<=- ...+0" range=<=0 range=">=- ...-391" range=>=-782 } if (-17 <= a && a <= 0 && -13 <= b && b <= 23) { range(a); // $ range=<=0 range=>=-17 @@ -467,19 +467,19 @@ int test_mult04(int a, int b) { range(a); // $ range=<=0 range=>=-17 range(b); // $ range=<=0 range=>=-13 int r = a*b; // 0 .. 221 - range(r); + range(r); // $ range=<=221 range=>=0 total += r; - range(total); // $ MISSING: range=">=- ...+0" + range(total); // $ range="<=- ...+221" range=">=- ...+0" } if (-17 <= a && a <= 0 && -13 <= b && b <= -7) { range(a); // $ range=<=0 range=>=-17 range(b); // $ range=<=-7 range=>=-13 int r = a*b; // 0 .. 221 - range(r); + range(r); // $ range=<=221 range=>=0 total += r; - range(total); // $ MISSING: range=">=- ...+0" + range(total); // $ range=">=- ...+0" range="<=- ...+221" range="<=- ...+442" } - range(total); // $ MISSING: range=">=- ...+0" + range(total); // $ range=">=- ...+0" range="<=- ...+221" range="<=- ...+442" return total; } @@ -491,17 +491,17 @@ int test_mult05(int a, int b) { range(a); // $ range=<=-2 range=>=-17 range(b); // $ range=<=23 range=>=5 int r = a*b; // -391 .. -10 - range(r); + range(r); // $ range=<=-10 range=>=-391 total += r; - range(total); // $ MISSING: range=<=-1 + range(total); // $ range=<=-10 range=>=-391 } if (-17 <= a && a <= -2 && 0 <= b && b <= 23) { range(a); // $ range=<=-2 range=>=-17 range(b); // $ range=<=23 range=>=0 int r = a*b; // -391 .. 0 - range(r); + range(r); // $ range=<=0 range=>=-391 total += r; - range(total); // $ MISSING: range="<=- ...+0" range=<=0 + range(total); // $ range="<=- ...+0" range=<=0 range=">=- ...-391" range=>=-782 } if (-17 <= a && a <= -2 && -13 <= b && b <= 23) { range(a); // $ range=<=-2 range=>=-17 @@ -515,19 +515,19 @@ int test_mult05(int a, int b) { range(a); // $ range=<=-2 range=>=-17 range(b); // $ range=<=0 range=>=-13 int r = a*b; // 0 .. 221 - range(r); + range(r); // $ range=<=221 range=>=0 total += r; - range(total); // $ MISSING: range=">=- ...+0" + range(total); // $ range="<=- ...+221" range=">=- ...+0" } if (-17 <= a && a <= -2 && -13 <= b && b <= -7) { range(a); // $ range=<=-2 range=>=-17 range(b); // $ range=<=-7 range=>=-13 int r = a*b; // 14 .. 221 - range(r); + range(r); // $ range=<=221 range=>=14 total += r; - range(total); // $ MISSING: range=">=- ...+1" + range(total); // $ range="<=- ...+221" range="<=- ...+442" range=">=- ...+14" } - range(total); // $ MISSING: range=">=- ...+0" + range(total); // $ range=">=- ...+0" range="<=- ...+221" range="<=- ...+442" return total; } @@ -741,7 +741,7 @@ unsigned long mult_rounding() { range(y); // $ range===1000000003 range(x); // $ range===1000000003 xy = x * y; - range(xy); + range(xy); // $ range===2147483647 return xy; // BUG: upper bound should be >= 1000000006000000009UL } @@ -761,13 +761,13 @@ unsigned long mult_lower_bound(unsigned int ui, unsigned long ul) { range(ui); // $ range=>=10 range((unsigned long)ui); // $ range=>=10 unsigned long result = (unsigned long)ui * ui; - range(result); + range(result); // $ range=>=100 range=>=100 return result; // BUG: upper bound should be >= 18446744065119617025 } if (ul >= 10) { range(ul); // $ range=>=10 unsigned long result = ul * ul; - range(result); + range(result); // $ range=>=100 return result; // BUG: lower bound should be 0 (overflow is possible) } return 0; @@ -777,7 +777,7 @@ unsigned long mul_assign(unsigned int ui) { if (ui <= 10 && ui >= 2) { range(ui); // $ range=<=10 range=>=2 ui *= ui + 0; - range(ui); + range(ui); // $ range=<=100 range=>=4 return ui; // 4 .. 100 } @@ -813,7 +813,7 @@ int mul_by_constant(int i, int j) { range(i); // $ range===-1 range((int)0xffFFffFF); // $ range===-1 i = i * (int)0xffFFffFF; // fully converted literal is -1 - range(i); // 1 .. 1 + range(i); // $ range===1 } i = i * -1; range( i); // -2^31 .. 2^31-1 From 2a5f29cd0f730c6d330fbc61de5336f84e6f42a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nora=20Dimitrijevi=C4=87?= <d10c@users.noreply.github.com> Date: Tue, 28 Mar 2023 18:18:32 +0200 Subject: [PATCH 579/631] Swift: remove getIdentityPreservingEnclosingPattern The Pattern public interface doesn't really need it. --- .../dataflow/internal/DataFlowPrivate.qll | 6 +++++- .../codeql/swift/elements/pattern/Pattern.qll | 20 ------------------- 2 files changed, 5 insertions(+), 21 deletions(-) diff --git a/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowPrivate.qll b/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowPrivate.qll index 3a6877534d7..3ddbde6718a 100644 --- a/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowPrivate.qll +++ b/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowPrivate.qll @@ -192,7 +192,11 @@ private module Cached { ) or // flow from Pattern to an identity-preserving sub-Pattern: - nodeFrom.asPattern() = nodeTo.asPattern().getIdentityPreservingEnclosingPattern() + nodeTo.asPattern() = + [ + nodeFrom.asPattern().(IsPattern).getSubPattern(), + nodeFrom.asPattern().(TypedPattern).getSubPattern() + ] or // flow through a flow summary (extension of `SummaryModelCsv`) FlowSummaryImpl::Private::Steps::summaryLocalStep(nodeFrom, nodeTo, true) diff --git a/swift/ql/lib/codeql/swift/elements/pattern/Pattern.qll b/swift/ql/lib/codeql/swift/elements/pattern/Pattern.qll index ee97c05c36d..617da58fdb1 100644 --- a/swift/ql/lib/codeql/swift/elements/pattern/Pattern.qll +++ b/swift/ql/lib/codeql/swift/elements/pattern/Pattern.qll @@ -85,16 +85,6 @@ class Pattern extends Generated::Pattern { result = this.getFullyUnresolved().(Pattern).getImmediateEnclosingPattern() } - /** - * Gets the parent pattern of this pattern, but only if - * both patterns match against the same object, which is not - * the case when destructuring a complex data structure, - * like a tuple or enum. - */ - final Pattern getIdentityPreservingEnclosingPattern() { - result = this.getFullyUnresolved().(Pattern).getImmediateIdentityPreservingEnclosingPattern() - } - /** * Gets the parent pattern of this pattern, if any. */ @@ -105,16 +95,6 @@ class Pattern extends Generated::Pattern { or this = result.(TuplePattern).getImmediateElement(_) or - result = this.getImmediateIdentityPreservingEnclosingPattern() - } - - /** - * Gets the immediate parent pattern of this pattern, but only if - * both patterns match against the same object, which is not - * the case when destructuring a complex data structure, - * like a tuple or enum. - */ - Pattern getImmediateIdentityPreservingEnclosingPattern() { this = result.(BindingPattern).getImmediateSubPattern() or this = result.(IsPattern).getImmediateSubPattern() From 85d824b96b8d557c1fb27c6b127fa3ceddc7c00d Mon Sep 17 00:00:00 2001 From: Tamas Vajk <tamasvajk@github.com> Date: Wed, 29 Mar 2023 10:11:30 +0200 Subject: [PATCH 580/631] Ruby: Adjust Makefile after shared library refactoring --- ruby/Makefile | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/ruby/Makefile b/ruby/Makefile index 09f4deb1e85..f106d42a3bf 100644 --- a/ruby/Makefile +++ b/ruby/Makefile @@ -38,14 +38,14 @@ tools: $(BIN_FILES) rm -rf tools/bin mkdir tools/bin cp -r target/release/ruby-autobuilder$(EXE) tools/bin/autobuilder$(EXE) - cp -r target/release/ruby-extractor$(EXE) tools/bin/extractor$(EXE) + cp -r target/release/ruby-extractor$(EXE) tools/bin/extractor$(EXE) target/release/%$(EXE): - cargo build --release --bin $(basename $(notdir $@)) + cd extractor && cargo build --release dbscheme: - cargo build --bin ruby-generator - cargo run -p ruby-generator -- --dbscheme ql/lib/ruby.dbscheme --library ql/lib/codeql/ruby/ast/internal/TreeSitter.qll + cd extractor && cargo build --release + extractor/target/release/generator --dbscheme ql/lib/ruby.dbscheme --library ql/lib/codeql/ruby/ast/internal/TreeSitter.qll codeql query format -i ql/lib/codeql/ruby/ast/internal/TreeSitter.qll .PHONY: extractor @@ -63,8 +63,8 @@ extractor: $(FILES) $(BIN_FILES) cp tools/autobuild.cmd extractor-pack/tools/autobuild.cmd cp ql/lib/ruby.dbscheme.stats extractor-pack/ruby.dbscheme.stats cp ql/lib/ruby.dbscheme extractor-pack/ruby.dbscheme - cp target/release/ruby-extractor$(EXE) extractor-pack/tools/$(CODEQL_PLATFORM)/extractor$(EXE) - cp target/release/ruby-autobuilder$(EXE) extractor-pack/tools/$(CODEQL_PLATFORM)/autobuilder$(EXE) + cp extractor/target/release/extractor$(EXE) extractor-pack/tools/$(CODEQL_PLATFORM)/extractor$(EXE) + cp extractor/target/release/autobuilder$(EXE) extractor-pack/tools/$(CODEQL_PLATFORM)/autobuilder$(EXE) test: extractor dbscheme codeql test run --check-databases --check-unused-labels --check-repeated-labels --check-redefined-labels --check-use-before-definition --search-path extractor-pack --consistency-queries ql/consistency-queries ql/test From 683985a00aa5a1e8d10f2f8b86c1efc0d5b8ad41 Mon Sep 17 00:00:00 2001 From: Rasmus Wriedt Larsen <rasmuswl@github.com> Date: Wed, 29 Mar 2023 11:24:36 +0200 Subject: [PATCH 581/631] Python: Expand azure blob modeling Now we can differentiate between the classes --- ...nsafeUsageOfClientSideEncryptionVersion.ql | 77 +++++++++++++++++-- ...sageOfClientSideEncryptionVersion.expected | 40 ++++++---- .../test.py | 33 ++++++-- 3 files changed, 122 insertions(+), 28 deletions(-) diff --git a/python/ql/src/experimental/Security/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql b/python/ql/src/experimental/Security/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql index 293edddd9f0..ab72f67f640 100644 --- a/python/ql/src/experimental/Security/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql +++ b/python/ql/src/experimental/Security/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql @@ -15,35 +15,100 @@ import python import semmle.python.dataflow.new.DataFlow import semmle.python.ApiGraphs -API::Node getClient() { +API::Node getBlobServiceClient() { result = API::moduleImport("azure") .getMember("storage") .getMember("blob") - .getMember(["ContainerClient", "BlobClient", "BlobServiceClient"]) - .getAMember() + .getMember("BlobServiceClient") + .getReturn() + or + result = + API::moduleImport("azure") + .getMember("storage") + .getMember("blob") + .getMember("BlobServiceClient") + .getMember("from_connection_string") .getReturn() } +API::CallNode getTransitionToContainerClient() { + result = getBlobServiceClient().getMember("get_container_client").getACall() + or + result = getBlobClient().getMember("_get_container_client").getACall() +} + +API::Node getContainerClient() { + result = getTransitionToContainerClient().getReturn() + or + result = + API::moduleImport("azure") + .getMember("storage") + .getMember("blob") + .getMember("ContainerClient") + .getReturn() + or + result = + API::moduleImport("azure") + .getMember("storage") + .getMember("blob") + .getMember("ContainerClient") + .getMember(["from_connection_string", "from_container_url"]) + .getReturn() +} + +API::CallNode getTransitionToBlobClient() { + result = [getBlobServiceClient(), getContainerClient()].getMember("get_blob_client").getACall() +} + +API::Node getBlobClient() { + result = getTransitionToBlobClient().getReturn() + or + result = + API::moduleImport("azure") + .getMember("storage") + .getMember("blob") + .getMember("BlobClient") + .getReturn() + or + result = + API::moduleImport("azure") + .getMember("storage") + .getMember("blob") + .getMember("BlobClient") + .getMember(["from_connection_string", "from_blob_url"]) + .getReturn() +} + +API::Node anyClient() { result in [getBlobServiceClient(), getContainerClient(), getBlobClient()] } + module AzureBlobClientConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node node) { exists(DataFlow::AttrWrite attr | - node = getClient().getAValueReachableFromSource() and + node = anyClient().getAValueReachableFromSource() and attr.accesses(node, ["key_encryption_key", "key_resolver_function"]) ) } predicate isBarrier(DataFlow::Node node) { exists(DataFlow::AttrWrite attr | - node = getClient().getAValueReachableFromSource() and + node = anyClient().getAValueReachableFromSource() and attr.accesses(node, "encryption_version") and attr.getValue().asExpr().(StrConst).getText() in ["'2.0'", "2.0"] ) } + predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) { + exists(DataFlow::MethodCallNode call | + call in [getTransitionToContainerClient(), getTransitionToBlobClient()] and + node1 = call.getObject() and + node2 = call + ) + } + predicate isSink(DataFlow::Node node) { exists(DataFlow::MethodCallNode call | - call = getClient().getMember("upload_blob").getACall() and + call = getBlobClient().getMember("upload_blob").getACall() and node = call.getObject() ) } diff --git a/python/ql/test/experimental/query-tests/Security/CWE-327-UnsafeUsageOfClientSideEncryptionVersion/UnsafeUsageOfClientSideEncryptionVersion.expected b/python/ql/test/experimental/query-tests/Security/CWE-327-UnsafeUsageOfClientSideEncryptionVersion/UnsafeUsageOfClientSideEncryptionVersion.expected index a1db6075756..cbd07c9fc78 100644 --- a/python/ql/test/experimental/query-tests/Security/CWE-327-UnsafeUsageOfClientSideEncryptionVersion/UnsafeUsageOfClientSideEncryptionVersion.expected +++ b/python/ql/test/experimental/query-tests/Security/CWE-327-UnsafeUsageOfClientSideEncryptionVersion/UnsafeUsageOfClientSideEncryptionVersion.expected @@ -1,20 +1,28 @@ edges -| test.py:8:5:8:15 | ControlFlowNode for blob_client | test.py:10:9:10:19 | ControlFlowNode for blob_client | -| test.py:16:5:16:15 | ControlFlowNode for blob_client | test.py:22:9:22:19 | ControlFlowNode for blob_client | -| test.py:38:5:38:15 | ControlFlowNode for blob_client | test.py:39:12:39:22 | ControlFlowNode for blob_client | -| test.py:39:12:39:22 | ControlFlowNode for blob_client | test.py:43:10:43:33 | ControlFlowNode for get_unsafe_blob_client() | -| test.py:43:10:43:33 | ControlFlowNode for get_unsafe_blob_client() | test.py:45:9:45:10 | ControlFlowNode for bc | +| test.py:9:5:9:15 | ControlFlowNode for blob_client | test.py:11:9:11:19 | ControlFlowNode for blob_client | +| test.py:17:5:17:23 | ControlFlowNode for blob_service_client | test.py:21:9:21:19 | ControlFlowNode for blob_client | +| test.py:27:5:27:20 | ControlFlowNode for container_client | test.py:31:9:31:19 | ControlFlowNode for blob_client | +| test.py:37:5:37:15 | ControlFlowNode for blob_client | test.py:43:9:43:19 | ControlFlowNode for blob_client | +| test.py:59:5:59:15 | ControlFlowNode for blob_client | test.py:60:12:60:22 | ControlFlowNode for blob_client | +| test.py:60:12:60:22 | ControlFlowNode for blob_client | test.py:64:10:64:33 | ControlFlowNode for get_unsafe_blob_client() | +| test.py:64:10:64:33 | ControlFlowNode for get_unsafe_blob_client() | test.py:66:9:66:10 | ControlFlowNode for bc | nodes -| test.py:8:5:8:15 | ControlFlowNode for blob_client | semmle.label | ControlFlowNode for blob_client | -| test.py:10:9:10:19 | ControlFlowNode for blob_client | semmle.label | ControlFlowNode for blob_client | -| test.py:16:5:16:15 | ControlFlowNode for blob_client | semmle.label | ControlFlowNode for blob_client | -| test.py:22:9:22:19 | ControlFlowNode for blob_client | semmle.label | ControlFlowNode for blob_client | -| test.py:38:5:38:15 | ControlFlowNode for blob_client | semmle.label | ControlFlowNode for blob_client | -| test.py:39:12:39:22 | ControlFlowNode for blob_client | semmle.label | ControlFlowNode for blob_client | -| test.py:43:10:43:33 | ControlFlowNode for get_unsafe_blob_client() | semmle.label | ControlFlowNode for get_unsafe_blob_client() | -| test.py:45:9:45:10 | ControlFlowNode for bc | semmle.label | ControlFlowNode for bc | +| test.py:9:5:9:15 | ControlFlowNode for blob_client | semmle.label | ControlFlowNode for blob_client | +| test.py:11:9:11:19 | ControlFlowNode for blob_client | semmle.label | ControlFlowNode for blob_client | +| test.py:17:5:17:23 | ControlFlowNode for blob_service_client | semmle.label | ControlFlowNode for blob_service_client | +| test.py:21:9:21:19 | ControlFlowNode for blob_client | semmle.label | ControlFlowNode for blob_client | +| test.py:27:5:27:20 | ControlFlowNode for container_client | semmle.label | ControlFlowNode for container_client | +| test.py:31:9:31:19 | ControlFlowNode for blob_client | semmle.label | ControlFlowNode for blob_client | +| test.py:37:5:37:15 | ControlFlowNode for blob_client | semmle.label | ControlFlowNode for blob_client | +| test.py:43:9:43:19 | ControlFlowNode for blob_client | semmle.label | ControlFlowNode for blob_client | +| test.py:59:5:59:15 | ControlFlowNode for blob_client | semmle.label | ControlFlowNode for blob_client | +| test.py:60:12:60:22 | ControlFlowNode for blob_client | semmle.label | ControlFlowNode for blob_client | +| test.py:64:10:64:33 | ControlFlowNode for get_unsafe_blob_client() | semmle.label | ControlFlowNode for get_unsafe_blob_client() | +| test.py:66:9:66:10 | ControlFlowNode for bc | semmle.label | ControlFlowNode for bc | subpaths #select -| test.py:10:9:10:19 | ControlFlowNode for blob_client | test.py:8:5:8:15 | ControlFlowNode for blob_client | test.py:10:9:10:19 | ControlFlowNode for blob_client | Unsafe usage of v1 version of Azure Storage client-side encryption | -| test.py:22:9:22:19 | ControlFlowNode for blob_client | test.py:16:5:16:15 | ControlFlowNode for blob_client | test.py:22:9:22:19 | ControlFlowNode for blob_client | Unsafe usage of v1 version of Azure Storage client-side encryption | -| test.py:45:9:45:10 | ControlFlowNode for bc | test.py:38:5:38:15 | ControlFlowNode for blob_client | test.py:45:9:45:10 | ControlFlowNode for bc | Unsafe usage of v1 version of Azure Storage client-side encryption | +| test.py:11:9:11:19 | ControlFlowNode for blob_client | test.py:9:5:9:15 | ControlFlowNode for blob_client | test.py:11:9:11:19 | ControlFlowNode for blob_client | Unsafe usage of v1 version of Azure Storage client-side encryption | +| test.py:21:9:21:19 | ControlFlowNode for blob_client | test.py:17:5:17:23 | ControlFlowNode for blob_service_client | test.py:21:9:21:19 | ControlFlowNode for blob_client | Unsafe usage of v1 version of Azure Storage client-side encryption | +| test.py:31:9:31:19 | ControlFlowNode for blob_client | test.py:27:5:27:20 | ControlFlowNode for container_client | test.py:31:9:31:19 | ControlFlowNode for blob_client | Unsafe usage of v1 version of Azure Storage client-side encryption | +| test.py:43:9:43:19 | ControlFlowNode for blob_client | test.py:37:5:37:15 | ControlFlowNode for blob_client | test.py:43:9:43:19 | ControlFlowNode for blob_client | Unsafe usage of v1 version of Azure Storage client-side encryption | +| test.py:66:9:66:10 | ControlFlowNode for bc | test.py:59:5:59:15 | ControlFlowNode for blob_client | test.py:66:9:66:10 | ControlFlowNode for bc | Unsafe usage of v1 version of Azure Storage client-side encryption | diff --git a/python/ql/test/experimental/query-tests/Security/CWE-327-UnsafeUsageOfClientSideEncryptionVersion/test.py b/python/ql/test/experimental/query-tests/Security/CWE-327-UnsafeUsageOfClientSideEncryptionVersion/test.py index 44d72f0bf1f..f17017a2bf6 100644 --- a/python/ql/test/experimental/query-tests/Security/CWE-327-UnsafeUsageOfClientSideEncryptionVersion/test.py +++ b/python/ql/test/experimental/query-tests/Security/CWE-327-UnsafeUsageOfClientSideEncryptionVersion/test.py @@ -1,17 +1,38 @@ -from azure.storage.blob import BlobServiceClient +from azure.storage.blob import BlobServiceClient, ContainerClient, BlobClient +BSC = BlobServiceClient.from_connection_string(...) def unsafe(): # does not set encryption_version to 2.0, default is unsafe - blob_client = BlobServiceClient.get_blob_client(...) + blob_client = BSC.get_blob_client(...) blob_client.require_encryption = True blob_client.key_encryption_key = ... with open("decryptedcontentfile.txt", "rb") as stream: blob_client.upload_blob(stream) # BAD +def unsafe_setting_on_blob_service_client(): + blob_service_client = BlobServiceClient.from_connection_string(...) + blob_service_client.require_encryption = True + blob_service_client.key_encryption_key = ... + + blob_client = blob_service_client.get_blob_client(...) + with open("decryptedcontentfile.txt", "rb") as stream: + blob_client.upload_blob(stream) + + +def unsafe_setting_on_container_client(): + container_client = ContainerClient.from_connection_string(...) + container_client.require_encryption = True + container_client.key_encryption_key = ... + + blob_client = container_client.get_blob_client(...) + with open("decryptedcontentfile.txt", "rb") as stream: + blob_client.upload_blob(stream) + + def potentially_unsafe(use_new_version=False): - blob_client = BlobServiceClient.get_blob_client(...) + blob_client = BSC.get_blob_client(...) blob_client.require_encryption = True blob_client.key_encryption_key = ... @@ -23,7 +44,7 @@ def potentially_unsafe(use_new_version=False): def safe(): - blob_client = BlobServiceClient.get_blob_client(...) + blob_client = BSC.get_blob_client(...) blob_client.require_encryption = True blob_client.key_encryption_key = ... # GOOD: Must use `encryption_version` set to `2.0` @@ -33,7 +54,7 @@ def safe(): def get_unsafe_blob_client(): - blob_client = BlobServiceClient.get_blob_client(...) + blob_client = BSC.get_blob_client(...) blob_client.require_encryption = True blob_client.key_encryption_key = ... return blob_client @@ -46,7 +67,7 @@ def unsafe_with_calls(): def get_safe_blob_client(): - blob_client = BlobServiceClient.get_blob_client(...) + blob_client = BSC.get_blob_client(...) blob_client.require_encryption = True blob_client.key_encryption_key = ... blob_client.encryption_version = '2.0' From 480f171d9bc34e5e52bd62a87d5c1994080fad3d Mon Sep 17 00:00:00 2001 From: Rasmus Wriedt Larsen <rasmuswl@github.com> Date: Wed, 29 Mar 2023 11:25:37 +0200 Subject: [PATCH 582/631] Python: Add azure blob tests with swapped order Just shows we need to use some state in the query to get the correct behavior. --- ...sageOfClientSideEncryptionVersion.expected | 20 +++++++++++-------- .../test.py | 9 +++++++++ 2 files changed, 21 insertions(+), 8 deletions(-) diff --git a/python/ql/test/experimental/query-tests/Security/CWE-327-UnsafeUsageOfClientSideEncryptionVersion/UnsafeUsageOfClientSideEncryptionVersion.expected b/python/ql/test/experimental/query-tests/Security/CWE-327-UnsafeUsageOfClientSideEncryptionVersion/UnsafeUsageOfClientSideEncryptionVersion.expected index cbd07c9fc78..d825dd3aadd 100644 --- a/python/ql/test/experimental/query-tests/Security/CWE-327-UnsafeUsageOfClientSideEncryptionVersion/UnsafeUsageOfClientSideEncryptionVersion.expected +++ b/python/ql/test/experimental/query-tests/Security/CWE-327-UnsafeUsageOfClientSideEncryptionVersion/UnsafeUsageOfClientSideEncryptionVersion.expected @@ -3,9 +3,10 @@ edges | test.py:17:5:17:23 | ControlFlowNode for blob_service_client | test.py:21:9:21:19 | ControlFlowNode for blob_client | | test.py:27:5:27:20 | ControlFlowNode for container_client | test.py:31:9:31:19 | ControlFlowNode for blob_client | | test.py:37:5:37:15 | ControlFlowNode for blob_client | test.py:43:9:43:19 | ControlFlowNode for blob_client | -| test.py:59:5:59:15 | ControlFlowNode for blob_client | test.py:60:12:60:22 | ControlFlowNode for blob_client | -| test.py:60:12:60:22 | ControlFlowNode for blob_client | test.py:64:10:64:33 | ControlFlowNode for get_unsafe_blob_client() | -| test.py:64:10:64:33 | ControlFlowNode for get_unsafe_blob_client() | test.py:66:9:66:10 | ControlFlowNode for bc | +| test.py:60:5:60:15 | ControlFlowNode for blob_client | test.py:62:9:62:19 | ControlFlowNode for blob_client | +| test.py:68:5:68:15 | ControlFlowNode for blob_client | test.py:69:12:69:22 | ControlFlowNode for blob_client | +| test.py:69:12:69:22 | ControlFlowNode for blob_client | test.py:73:10:73:33 | ControlFlowNode for get_unsafe_blob_client() | +| test.py:73:10:73:33 | ControlFlowNode for get_unsafe_blob_client() | test.py:75:9:75:10 | ControlFlowNode for bc | nodes | test.py:9:5:9:15 | ControlFlowNode for blob_client | semmle.label | ControlFlowNode for blob_client | | test.py:11:9:11:19 | ControlFlowNode for blob_client | semmle.label | ControlFlowNode for blob_client | @@ -15,14 +16,17 @@ nodes | test.py:31:9:31:19 | ControlFlowNode for blob_client | semmle.label | ControlFlowNode for blob_client | | test.py:37:5:37:15 | ControlFlowNode for blob_client | semmle.label | ControlFlowNode for blob_client | | test.py:43:9:43:19 | ControlFlowNode for blob_client | semmle.label | ControlFlowNode for blob_client | -| test.py:59:5:59:15 | ControlFlowNode for blob_client | semmle.label | ControlFlowNode for blob_client | -| test.py:60:12:60:22 | ControlFlowNode for blob_client | semmle.label | ControlFlowNode for blob_client | -| test.py:64:10:64:33 | ControlFlowNode for get_unsafe_blob_client() | semmle.label | ControlFlowNode for get_unsafe_blob_client() | -| test.py:66:9:66:10 | ControlFlowNode for bc | semmle.label | ControlFlowNode for bc | +| test.py:60:5:60:15 | ControlFlowNode for blob_client | semmle.label | ControlFlowNode for blob_client | +| test.py:62:9:62:19 | ControlFlowNode for blob_client | semmle.label | ControlFlowNode for blob_client | +| test.py:68:5:68:15 | ControlFlowNode for blob_client | semmle.label | ControlFlowNode for blob_client | +| test.py:69:12:69:22 | ControlFlowNode for blob_client | semmle.label | ControlFlowNode for blob_client | +| test.py:73:10:73:33 | ControlFlowNode for get_unsafe_blob_client() | semmle.label | ControlFlowNode for get_unsafe_blob_client() | +| test.py:75:9:75:10 | ControlFlowNode for bc | semmle.label | ControlFlowNode for bc | subpaths #select | test.py:11:9:11:19 | ControlFlowNode for blob_client | test.py:9:5:9:15 | ControlFlowNode for blob_client | test.py:11:9:11:19 | ControlFlowNode for blob_client | Unsafe usage of v1 version of Azure Storage client-side encryption | | test.py:21:9:21:19 | ControlFlowNode for blob_client | test.py:17:5:17:23 | ControlFlowNode for blob_service_client | test.py:21:9:21:19 | ControlFlowNode for blob_client | Unsafe usage of v1 version of Azure Storage client-side encryption | | test.py:31:9:31:19 | ControlFlowNode for blob_client | test.py:27:5:27:20 | ControlFlowNode for container_client | test.py:31:9:31:19 | ControlFlowNode for blob_client | Unsafe usage of v1 version of Azure Storage client-side encryption | | test.py:43:9:43:19 | ControlFlowNode for blob_client | test.py:37:5:37:15 | ControlFlowNode for blob_client | test.py:43:9:43:19 | ControlFlowNode for blob_client | Unsafe usage of v1 version of Azure Storage client-side encryption | -| test.py:66:9:66:10 | ControlFlowNode for bc | test.py:59:5:59:15 | ControlFlowNode for blob_client | test.py:66:9:66:10 | ControlFlowNode for bc | Unsafe usage of v1 version of Azure Storage client-side encryption | +| test.py:62:9:62:19 | ControlFlowNode for blob_client | test.py:60:5:60:15 | ControlFlowNode for blob_client | test.py:62:9:62:19 | ControlFlowNode for blob_client | Unsafe usage of v1 version of Azure Storage client-side encryption | +| test.py:75:9:75:10 | ControlFlowNode for bc | test.py:68:5:68:15 | ControlFlowNode for blob_client | test.py:75:9:75:10 | ControlFlowNode for bc | Unsafe usage of v1 version of Azure Storage client-side encryption | diff --git a/python/ql/test/experimental/query-tests/Security/CWE-327-UnsafeUsageOfClientSideEncryptionVersion/test.py b/python/ql/test/experimental/query-tests/Security/CWE-327-UnsafeUsageOfClientSideEncryptionVersion/test.py index f17017a2bf6..32fa60c6193 100644 --- a/python/ql/test/experimental/query-tests/Security/CWE-327-UnsafeUsageOfClientSideEncryptionVersion/test.py +++ b/python/ql/test/experimental/query-tests/Security/CWE-327-UnsafeUsageOfClientSideEncryptionVersion/test.py @@ -53,6 +53,15 @@ def safe(): blob_client.upload_blob(stream) # OK +def safe_different_order(): + blob_client: BlobClient = BSC.get_blob_client(...) + blob_client.encryption_version = '2.0' + blob_client.require_encryption = True + blob_client.key_encryption_key = ... + with open("decryptedcontentfile.txt", "rb") as stream: + blob_client.upload_blob(stream) # OK + + def get_unsafe_blob_client(): blob_client = BSC.get_blob_client(...) blob_client.require_encryption = True From 78443847687d4133ffe159ed4039ab63f2304968 Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen <aschackmull@github.com> Date: Wed, 29 Mar 2023 11:39:07 +0200 Subject: [PATCH 583/631] Java: Add change note. --- java/ql/lib/change-notes/2023-03-29-rangeanalysis-add.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 java/ql/lib/change-notes/2023-03-29-rangeanalysis-add.md diff --git a/java/ql/lib/change-notes/2023-03-29-rangeanalysis-add.md b/java/ql/lib/change-notes/2023-03-29-rangeanalysis-add.md new file mode 100644 index 00000000000..a097923ae46 --- /dev/null +++ b/java/ql/lib/change-notes/2023-03-29-rangeanalysis-add.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* Improved the handling of addition in the range analysis. This can cause in minor changes to the results produced by `java/index-out-of-bounds` and `java/constant-comparison`. From 32d52c023eab39902701dbeba7553115c170bf89 Mon Sep 17 00:00:00 2001 From: Rasmus Wriedt Larsen <rasmuswl@github.com> Date: Wed, 29 Mar 2023 11:42:01 +0200 Subject: [PATCH 584/631] Python: Allow any order for azure blob query By only allowing the sink in the state where encryption v1 is used, we can handle the new case where the order of attribute assignment is flipped. However, we get a few too many paths because we can have multiple sources reaching the same sink... let's fix in next commit. --- ...nsafeUsageOfClientSideEncryptionVersion.ql | 36 ++++++++--- ...sageOfClientSideEncryptionVersion.expected | 61 ++++++++++++++++--- 2 files changed, 79 insertions(+), 18 deletions(-) diff --git a/python/ql/src/experimental/Security/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql b/python/ql/src/experimental/Security/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql index ab72f67f640..5ea681cf5c7 100644 --- a/python/ql/src/experimental/Security/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql +++ b/python/ql/src/experimental/Security/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql @@ -82,15 +82,20 @@ API::Node getBlobClient() { API::Node anyClient() { result in [getBlobServiceClient(), getContainerClient(), getBlobClient()] } -module AzureBlobClientConfig implements DataFlow::ConfigSig { - predicate isSource(DataFlow::Node node) { - exists(DataFlow::AttrWrite attr | - node = anyClient().getAValueReachableFromSource() and - attr.accesses(node, ["key_encryption_key", "key_resolver_function"]) - ) +newtype TAzureFlowState = + MkUsesV1Encryption() or + MkUsesNoEncryption() + +module AzureBlobClientConfig implements DataFlow::StateConfigSig { + class FlowState = TAzureFlowState; + + predicate isSource(DataFlow::Node node, FlowState state) { + state = MkUsesNoEncryption() and + node = anyClient().asSource() } - predicate isBarrier(DataFlow::Node node) { + predicate isBarrier(DataFlow::Node node, FlowState state) { + exists(state) and exists(DataFlow::AttrWrite attr | node = anyClient().getAValueReachableFromSource() and attr.accesses(node, "encryption_version") and @@ -106,7 +111,20 @@ module AzureBlobClientConfig implements DataFlow::ConfigSig { ) } - predicate isSink(DataFlow::Node node) { + predicate isAdditionalFlowStep( + DataFlow::Node node1, FlowState state1, DataFlow::Node node2, FlowState state2 + ) { + node1 = node2 and + state1 = MkUsesNoEncryption() and + state2 = MkUsesV1Encryption() and + exists(DataFlow::AttrWrite attr | + node1 = anyClient().getAValueReachableFromSource() and + attr.accesses(node1, ["key_encryption_key", "key_resolver_function"]) + ) + } + + predicate isSink(DataFlow::Node node, FlowState state) { + state = MkUsesV1Encryption() and exists(DataFlow::MethodCallNode call | call = getBlobClient().getMember("upload_blob").getACall() and node = call.getObject() @@ -114,7 +132,7 @@ module AzureBlobClientConfig implements DataFlow::ConfigSig { } } -module AzureBlobClient = DataFlow::Global<AzureBlobClientConfig>; +module AzureBlobClient = DataFlow::GlobalWithState<AzureBlobClientConfig>; import AzureBlobClient::PathGraph diff --git a/python/ql/test/experimental/query-tests/Security/CWE-327-UnsafeUsageOfClientSideEncryptionVersion/UnsafeUsageOfClientSideEncryptionVersion.expected b/python/ql/test/experimental/query-tests/Security/CWE-327-UnsafeUsageOfClientSideEncryptionVersion/UnsafeUsageOfClientSideEncryptionVersion.expected index d825dd3aadd..078dea32c2e 100644 --- a/python/ql/test/experimental/query-tests/Security/CWE-327-UnsafeUsageOfClientSideEncryptionVersion/UnsafeUsageOfClientSideEncryptionVersion.expected +++ b/python/ql/test/experimental/query-tests/Security/CWE-327-UnsafeUsageOfClientSideEncryptionVersion/UnsafeUsageOfClientSideEncryptionVersion.expected @@ -1,32 +1,75 @@ edges +| test.py:0:0:0:0 | ModuleVariableNode for test.BSC | test.py:7:19:7:21 | ControlFlowNode for BSC | +| test.py:0:0:0:0 | ModuleVariableNode for test.BSC | test.py:35:19:35:21 | ControlFlowNode for BSC | +| test.py:0:0:0:0 | ModuleVariableNode for test.BSC | test.py:66:19:66:21 | ControlFlowNode for BSC | +| test.py:3:1:3:3 | GSSA Variable BSC | test.py:0:0:0:0 | ModuleVariableNode for test.BSC | +| test.py:3:7:3:51 | ControlFlowNode for Attribute() | test.py:3:1:3:3 | GSSA Variable BSC | +| test.py:7:19:7:21 | ControlFlowNode for BSC | test.py:8:5:8:15 | ControlFlowNode for blob_client | +| test.py:7:19:7:42 | ControlFlowNode for Attribute() | test.py:8:5:8:15 | ControlFlowNode for blob_client | +| test.py:8:5:8:15 | ControlFlowNode for blob_client | test.py:9:5:9:15 | ControlFlowNode for blob_client | +| test.py:9:5:9:15 | ControlFlowNode for blob_client | test.py:9:5:9:15 | ControlFlowNode for blob_client | | test.py:9:5:9:15 | ControlFlowNode for blob_client | test.py:11:9:11:19 | ControlFlowNode for blob_client | +| test.py:15:27:15:71 | ControlFlowNode for Attribute() | test.py:16:5:16:23 | ControlFlowNode for blob_service_client | +| test.py:16:5:16:23 | ControlFlowNode for blob_service_client | test.py:17:5:17:23 | ControlFlowNode for blob_service_client | +| test.py:17:5:17:23 | ControlFlowNode for blob_service_client | test.py:17:5:17:23 | ControlFlowNode for blob_service_client | | test.py:17:5:17:23 | ControlFlowNode for blob_service_client | test.py:21:9:21:19 | ControlFlowNode for blob_client | +| test.py:25:24:25:66 | ControlFlowNode for Attribute() | test.py:26:5:26:20 | ControlFlowNode for container_client | +| test.py:26:5:26:20 | ControlFlowNode for container_client | test.py:27:5:27:20 | ControlFlowNode for container_client | +| test.py:27:5:27:20 | ControlFlowNode for container_client | test.py:27:5:27:20 | ControlFlowNode for container_client | | test.py:27:5:27:20 | ControlFlowNode for container_client | test.py:31:9:31:19 | ControlFlowNode for blob_client | +| test.py:35:19:35:21 | ControlFlowNode for BSC | test.py:36:5:36:15 | ControlFlowNode for blob_client | +| test.py:35:19:35:42 | ControlFlowNode for Attribute() | test.py:36:5:36:15 | ControlFlowNode for blob_client | +| test.py:36:5:36:15 | ControlFlowNode for blob_client | test.py:37:5:37:15 | ControlFlowNode for blob_client | +| test.py:37:5:37:15 | ControlFlowNode for blob_client | test.py:37:5:37:15 | ControlFlowNode for blob_client | | test.py:37:5:37:15 | ControlFlowNode for blob_client | test.py:43:9:43:19 | ControlFlowNode for blob_client | -| test.py:60:5:60:15 | ControlFlowNode for blob_client | test.py:62:9:62:19 | ControlFlowNode for blob_client | +| test.py:66:19:66:21 | ControlFlowNode for BSC | test.py:67:5:67:15 | ControlFlowNode for blob_client | +| test.py:66:19:66:42 | ControlFlowNode for Attribute() | test.py:67:5:67:15 | ControlFlowNode for blob_client | +| test.py:67:5:67:15 | ControlFlowNode for blob_client | test.py:68:5:68:15 | ControlFlowNode for blob_client | +| test.py:68:5:68:15 | ControlFlowNode for blob_client | test.py:68:5:68:15 | ControlFlowNode for blob_client | | test.py:68:5:68:15 | ControlFlowNode for blob_client | test.py:69:12:69:22 | ControlFlowNode for blob_client | | test.py:69:12:69:22 | ControlFlowNode for blob_client | test.py:73:10:73:33 | ControlFlowNode for get_unsafe_blob_client() | | test.py:73:10:73:33 | ControlFlowNode for get_unsafe_blob_client() | test.py:75:9:75:10 | ControlFlowNode for bc | nodes +| test.py:0:0:0:0 | ModuleVariableNode for test.BSC | semmle.label | ModuleVariableNode for test.BSC | +| test.py:3:1:3:3 | GSSA Variable BSC | semmle.label | GSSA Variable BSC | +| test.py:3:7:3:51 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | +| test.py:7:19:7:21 | ControlFlowNode for BSC | semmle.label | ControlFlowNode for BSC | +| test.py:7:19:7:42 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | +| test.py:8:5:8:15 | ControlFlowNode for blob_client | semmle.label | ControlFlowNode for blob_client | +| test.py:9:5:9:15 | ControlFlowNode for blob_client | semmle.label | ControlFlowNode for blob_client | | test.py:9:5:9:15 | ControlFlowNode for blob_client | semmle.label | ControlFlowNode for blob_client | | test.py:11:9:11:19 | ControlFlowNode for blob_client | semmle.label | ControlFlowNode for blob_client | +| test.py:15:27:15:71 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | +| test.py:16:5:16:23 | ControlFlowNode for blob_service_client | semmle.label | ControlFlowNode for blob_service_client | +| test.py:17:5:17:23 | ControlFlowNode for blob_service_client | semmle.label | ControlFlowNode for blob_service_client | | test.py:17:5:17:23 | ControlFlowNode for blob_service_client | semmle.label | ControlFlowNode for blob_service_client | | test.py:21:9:21:19 | ControlFlowNode for blob_client | semmle.label | ControlFlowNode for blob_client | +| test.py:25:24:25:66 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | +| test.py:26:5:26:20 | ControlFlowNode for container_client | semmle.label | ControlFlowNode for container_client | +| test.py:27:5:27:20 | ControlFlowNode for container_client | semmle.label | ControlFlowNode for container_client | | test.py:27:5:27:20 | ControlFlowNode for container_client | semmle.label | ControlFlowNode for container_client | | test.py:31:9:31:19 | ControlFlowNode for blob_client | semmle.label | ControlFlowNode for blob_client | +| test.py:35:19:35:21 | ControlFlowNode for BSC | semmle.label | ControlFlowNode for BSC | +| test.py:35:19:35:42 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | +| test.py:36:5:36:15 | ControlFlowNode for blob_client | semmle.label | ControlFlowNode for blob_client | +| test.py:37:5:37:15 | ControlFlowNode for blob_client | semmle.label | ControlFlowNode for blob_client | | test.py:37:5:37:15 | ControlFlowNode for blob_client | semmle.label | ControlFlowNode for blob_client | | test.py:43:9:43:19 | ControlFlowNode for blob_client | semmle.label | ControlFlowNode for blob_client | -| test.py:60:5:60:15 | ControlFlowNode for blob_client | semmle.label | ControlFlowNode for blob_client | -| test.py:62:9:62:19 | ControlFlowNode for blob_client | semmle.label | ControlFlowNode for blob_client | +| test.py:66:19:66:21 | ControlFlowNode for BSC | semmle.label | ControlFlowNode for BSC | +| test.py:66:19:66:42 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | +| test.py:67:5:67:15 | ControlFlowNode for blob_client | semmle.label | ControlFlowNode for blob_client | +| test.py:68:5:68:15 | ControlFlowNode for blob_client | semmle.label | ControlFlowNode for blob_client | | test.py:68:5:68:15 | ControlFlowNode for blob_client | semmle.label | ControlFlowNode for blob_client | | test.py:69:12:69:22 | ControlFlowNode for blob_client | semmle.label | ControlFlowNode for blob_client | | test.py:73:10:73:33 | ControlFlowNode for get_unsafe_blob_client() | semmle.label | ControlFlowNode for get_unsafe_blob_client() | | test.py:75:9:75:10 | ControlFlowNode for bc | semmle.label | ControlFlowNode for bc | subpaths #select -| test.py:11:9:11:19 | ControlFlowNode for blob_client | test.py:9:5:9:15 | ControlFlowNode for blob_client | test.py:11:9:11:19 | ControlFlowNode for blob_client | Unsafe usage of v1 version of Azure Storage client-side encryption | -| test.py:21:9:21:19 | ControlFlowNode for blob_client | test.py:17:5:17:23 | ControlFlowNode for blob_service_client | test.py:21:9:21:19 | ControlFlowNode for blob_client | Unsafe usage of v1 version of Azure Storage client-side encryption | -| test.py:31:9:31:19 | ControlFlowNode for blob_client | test.py:27:5:27:20 | ControlFlowNode for container_client | test.py:31:9:31:19 | ControlFlowNode for blob_client | Unsafe usage of v1 version of Azure Storage client-side encryption | -| test.py:43:9:43:19 | ControlFlowNode for blob_client | test.py:37:5:37:15 | ControlFlowNode for blob_client | test.py:43:9:43:19 | ControlFlowNode for blob_client | Unsafe usage of v1 version of Azure Storage client-side encryption | -| test.py:62:9:62:19 | ControlFlowNode for blob_client | test.py:60:5:60:15 | ControlFlowNode for blob_client | test.py:62:9:62:19 | ControlFlowNode for blob_client | Unsafe usage of v1 version of Azure Storage client-side encryption | -| test.py:75:9:75:10 | ControlFlowNode for bc | test.py:68:5:68:15 | ControlFlowNode for blob_client | test.py:75:9:75:10 | ControlFlowNode for bc | Unsafe usage of v1 version of Azure Storage client-side encryption | +| test.py:11:9:11:19 | ControlFlowNode for blob_client | test.py:3:7:3:51 | ControlFlowNode for Attribute() | test.py:11:9:11:19 | ControlFlowNode for blob_client | Unsafe usage of v1 version of Azure Storage client-side encryption | +| test.py:11:9:11:19 | ControlFlowNode for blob_client | test.py:7:19:7:42 | ControlFlowNode for Attribute() | test.py:11:9:11:19 | ControlFlowNode for blob_client | Unsafe usage of v1 version of Azure Storage client-side encryption | +| test.py:21:9:21:19 | ControlFlowNode for blob_client | test.py:15:27:15:71 | ControlFlowNode for Attribute() | test.py:21:9:21:19 | ControlFlowNode for blob_client | Unsafe usage of v1 version of Azure Storage client-side encryption | +| test.py:31:9:31:19 | ControlFlowNode for blob_client | test.py:25:24:25:66 | ControlFlowNode for Attribute() | test.py:31:9:31:19 | ControlFlowNode for blob_client | Unsafe usage of v1 version of Azure Storage client-side encryption | +| test.py:43:9:43:19 | ControlFlowNode for blob_client | test.py:3:7:3:51 | ControlFlowNode for Attribute() | test.py:43:9:43:19 | ControlFlowNode for blob_client | Unsafe usage of v1 version of Azure Storage client-side encryption | +| test.py:43:9:43:19 | ControlFlowNode for blob_client | test.py:35:19:35:42 | ControlFlowNode for Attribute() | test.py:43:9:43:19 | ControlFlowNode for blob_client | Unsafe usage of v1 version of Azure Storage client-side encryption | +| test.py:75:9:75:10 | ControlFlowNode for bc | test.py:3:7:3:51 | ControlFlowNode for Attribute() | test.py:75:9:75:10 | ControlFlowNode for bc | Unsafe usage of v1 version of Azure Storage client-side encryption | +| test.py:75:9:75:10 | ControlFlowNode for bc | test.py:66:19:66:42 | ControlFlowNode for Attribute() | test.py:75:9:75:10 | ControlFlowNode for bc | Unsafe usage of v1 version of Azure Storage client-side encryption | From 86333e3ba5283ec01b1070dd64af4ce73dbf9a01 Mon Sep 17 00:00:00 2001 From: Rasmus Wriedt Larsen <rasmuswl@github.com> Date: Wed, 29 Mar 2023 11:46:59 +0200 Subject: [PATCH 585/631] Python: Remove duplicate results from azure blob query --- ...nsafeUsageOfClientSideEncryptionVersion.ql | 32 ++++++++++++------- ...sageOfClientSideEncryptionVersion.expected | 9 ------ 2 files changed, 21 insertions(+), 20 deletions(-) diff --git a/python/ql/src/experimental/Security/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql b/python/ql/src/experimental/Security/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql index 5ea681cf5c7..15892e00e5a 100644 --- a/python/ql/src/experimental/Security/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql +++ b/python/ql/src/experimental/Security/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql @@ -15,7 +15,8 @@ import python import semmle.python.dataflow.new.DataFlow import semmle.python.ApiGraphs -API::Node getBlobServiceClient() { +API::Node getBlobServiceClient(boolean isSource) { + isSource = true and result = API::moduleImport("azure") .getMember("storage") @@ -23,6 +24,7 @@ API::Node getBlobServiceClient() { .getMember("BlobServiceClient") .getReturn() or + isSource = true and result = API::moduleImport("azure") .getMember("storage") @@ -33,14 +35,16 @@ API::Node getBlobServiceClient() { } API::CallNode getTransitionToContainerClient() { - result = getBlobServiceClient().getMember("get_container_client").getACall() + result = getBlobServiceClient(_).getMember("get_container_client").getACall() or - result = getBlobClient().getMember("_get_container_client").getACall() + result = getBlobClient(_).getMember("_get_container_client").getACall() } -API::Node getContainerClient() { +API::Node getContainerClient(boolean isSource) { + isSource = false and result = getTransitionToContainerClient().getReturn() or + isSource = true and result = API::moduleImport("azure") .getMember("storage") @@ -48,6 +52,7 @@ API::Node getContainerClient() { .getMember("ContainerClient") .getReturn() or + isSource = true and result = API::moduleImport("azure") .getMember("storage") @@ -58,12 +63,14 @@ API::Node getContainerClient() { } API::CallNode getTransitionToBlobClient() { - result = [getBlobServiceClient(), getContainerClient()].getMember("get_blob_client").getACall() + result = [getBlobServiceClient(_), getContainerClient(_)].getMember("get_blob_client").getACall() } -API::Node getBlobClient() { +API::Node getBlobClient(boolean isSource) { + isSource = false and result = getTransitionToBlobClient().getReturn() or + isSource = true and result = API::moduleImport("azure") .getMember("storage") @@ -71,6 +78,7 @@ API::Node getBlobClient() { .getMember("BlobClient") .getReturn() or + isSource = true and result = API::moduleImport("azure") .getMember("storage") @@ -80,7 +88,9 @@ API::Node getBlobClient() { .getReturn() } -API::Node anyClient() { result in [getBlobServiceClient(), getContainerClient(), getBlobClient()] } +API::Node anyClient(boolean isSource) { + result in [getBlobServiceClient(isSource), getContainerClient(isSource), getBlobClient(isSource)] +} newtype TAzureFlowState = MkUsesV1Encryption() or @@ -91,13 +101,13 @@ module AzureBlobClientConfig implements DataFlow::StateConfigSig { predicate isSource(DataFlow::Node node, FlowState state) { state = MkUsesNoEncryption() and - node = anyClient().asSource() + node = anyClient(true).asSource() } predicate isBarrier(DataFlow::Node node, FlowState state) { exists(state) and exists(DataFlow::AttrWrite attr | - node = anyClient().getAValueReachableFromSource() and + node = anyClient(_).getAValueReachableFromSource() and attr.accesses(node, "encryption_version") and attr.getValue().asExpr().(StrConst).getText() in ["'2.0'", "2.0"] ) @@ -118,7 +128,7 @@ module AzureBlobClientConfig implements DataFlow::StateConfigSig { state1 = MkUsesNoEncryption() and state2 = MkUsesV1Encryption() and exists(DataFlow::AttrWrite attr | - node1 = anyClient().getAValueReachableFromSource() and + node1 = anyClient(_).getAValueReachableFromSource() and attr.accesses(node1, ["key_encryption_key", "key_resolver_function"]) ) } @@ -126,7 +136,7 @@ module AzureBlobClientConfig implements DataFlow::StateConfigSig { predicate isSink(DataFlow::Node node, FlowState state) { state = MkUsesV1Encryption() and exists(DataFlow::MethodCallNode call | - call = getBlobClient().getMember("upload_blob").getACall() and + call = getBlobClient(_).getMember("upload_blob").getACall() and node = call.getObject() ) } diff --git a/python/ql/test/experimental/query-tests/Security/CWE-327-UnsafeUsageOfClientSideEncryptionVersion/UnsafeUsageOfClientSideEncryptionVersion.expected b/python/ql/test/experimental/query-tests/Security/CWE-327-UnsafeUsageOfClientSideEncryptionVersion/UnsafeUsageOfClientSideEncryptionVersion.expected index 078dea32c2e..01a5f39bec5 100644 --- a/python/ql/test/experimental/query-tests/Security/CWE-327-UnsafeUsageOfClientSideEncryptionVersion/UnsafeUsageOfClientSideEncryptionVersion.expected +++ b/python/ql/test/experimental/query-tests/Security/CWE-327-UnsafeUsageOfClientSideEncryptionVersion/UnsafeUsageOfClientSideEncryptionVersion.expected @@ -5,7 +5,6 @@ edges | test.py:3:1:3:3 | GSSA Variable BSC | test.py:0:0:0:0 | ModuleVariableNode for test.BSC | | test.py:3:7:3:51 | ControlFlowNode for Attribute() | test.py:3:1:3:3 | GSSA Variable BSC | | test.py:7:19:7:21 | ControlFlowNode for BSC | test.py:8:5:8:15 | ControlFlowNode for blob_client | -| test.py:7:19:7:42 | ControlFlowNode for Attribute() | test.py:8:5:8:15 | ControlFlowNode for blob_client | | test.py:8:5:8:15 | ControlFlowNode for blob_client | test.py:9:5:9:15 | ControlFlowNode for blob_client | | test.py:9:5:9:15 | ControlFlowNode for blob_client | test.py:9:5:9:15 | ControlFlowNode for blob_client | | test.py:9:5:9:15 | ControlFlowNode for blob_client | test.py:11:9:11:19 | ControlFlowNode for blob_client | @@ -18,12 +17,10 @@ edges | test.py:27:5:27:20 | ControlFlowNode for container_client | test.py:27:5:27:20 | ControlFlowNode for container_client | | test.py:27:5:27:20 | ControlFlowNode for container_client | test.py:31:9:31:19 | ControlFlowNode for blob_client | | test.py:35:19:35:21 | ControlFlowNode for BSC | test.py:36:5:36:15 | ControlFlowNode for blob_client | -| test.py:35:19:35:42 | ControlFlowNode for Attribute() | test.py:36:5:36:15 | ControlFlowNode for blob_client | | test.py:36:5:36:15 | ControlFlowNode for blob_client | test.py:37:5:37:15 | ControlFlowNode for blob_client | | test.py:37:5:37:15 | ControlFlowNode for blob_client | test.py:37:5:37:15 | ControlFlowNode for blob_client | | test.py:37:5:37:15 | ControlFlowNode for blob_client | test.py:43:9:43:19 | ControlFlowNode for blob_client | | test.py:66:19:66:21 | ControlFlowNode for BSC | test.py:67:5:67:15 | ControlFlowNode for blob_client | -| test.py:66:19:66:42 | ControlFlowNode for Attribute() | test.py:67:5:67:15 | ControlFlowNode for blob_client | | test.py:67:5:67:15 | ControlFlowNode for blob_client | test.py:68:5:68:15 | ControlFlowNode for blob_client | | test.py:68:5:68:15 | ControlFlowNode for blob_client | test.py:68:5:68:15 | ControlFlowNode for blob_client | | test.py:68:5:68:15 | ControlFlowNode for blob_client | test.py:69:12:69:22 | ControlFlowNode for blob_client | @@ -34,7 +31,6 @@ nodes | test.py:3:1:3:3 | GSSA Variable BSC | semmle.label | GSSA Variable BSC | | test.py:3:7:3:51 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | | test.py:7:19:7:21 | ControlFlowNode for BSC | semmle.label | ControlFlowNode for BSC | -| test.py:7:19:7:42 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | | test.py:8:5:8:15 | ControlFlowNode for blob_client | semmle.label | ControlFlowNode for blob_client | | test.py:9:5:9:15 | ControlFlowNode for blob_client | semmle.label | ControlFlowNode for blob_client | | test.py:9:5:9:15 | ControlFlowNode for blob_client | semmle.label | ControlFlowNode for blob_client | @@ -50,13 +46,11 @@ nodes | test.py:27:5:27:20 | ControlFlowNode for container_client | semmle.label | ControlFlowNode for container_client | | test.py:31:9:31:19 | ControlFlowNode for blob_client | semmle.label | ControlFlowNode for blob_client | | test.py:35:19:35:21 | ControlFlowNode for BSC | semmle.label | ControlFlowNode for BSC | -| test.py:35:19:35:42 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | | test.py:36:5:36:15 | ControlFlowNode for blob_client | semmle.label | ControlFlowNode for blob_client | | test.py:37:5:37:15 | ControlFlowNode for blob_client | semmle.label | ControlFlowNode for blob_client | | test.py:37:5:37:15 | ControlFlowNode for blob_client | semmle.label | ControlFlowNode for blob_client | | test.py:43:9:43:19 | ControlFlowNode for blob_client | semmle.label | ControlFlowNode for blob_client | | test.py:66:19:66:21 | ControlFlowNode for BSC | semmle.label | ControlFlowNode for BSC | -| test.py:66:19:66:42 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | | test.py:67:5:67:15 | ControlFlowNode for blob_client | semmle.label | ControlFlowNode for blob_client | | test.py:68:5:68:15 | ControlFlowNode for blob_client | semmle.label | ControlFlowNode for blob_client | | test.py:68:5:68:15 | ControlFlowNode for blob_client | semmle.label | ControlFlowNode for blob_client | @@ -66,10 +60,7 @@ nodes subpaths #select | test.py:11:9:11:19 | ControlFlowNode for blob_client | test.py:3:7:3:51 | ControlFlowNode for Attribute() | test.py:11:9:11:19 | ControlFlowNode for blob_client | Unsafe usage of v1 version of Azure Storage client-side encryption | -| test.py:11:9:11:19 | ControlFlowNode for blob_client | test.py:7:19:7:42 | ControlFlowNode for Attribute() | test.py:11:9:11:19 | ControlFlowNode for blob_client | Unsafe usage of v1 version of Azure Storage client-side encryption | | test.py:21:9:21:19 | ControlFlowNode for blob_client | test.py:15:27:15:71 | ControlFlowNode for Attribute() | test.py:21:9:21:19 | ControlFlowNode for blob_client | Unsafe usage of v1 version of Azure Storage client-side encryption | | test.py:31:9:31:19 | ControlFlowNode for blob_client | test.py:25:24:25:66 | ControlFlowNode for Attribute() | test.py:31:9:31:19 | ControlFlowNode for blob_client | Unsafe usage of v1 version of Azure Storage client-side encryption | | test.py:43:9:43:19 | ControlFlowNode for blob_client | test.py:3:7:3:51 | ControlFlowNode for Attribute() | test.py:43:9:43:19 | ControlFlowNode for blob_client | Unsafe usage of v1 version of Azure Storage client-side encryption | -| test.py:43:9:43:19 | ControlFlowNode for blob_client | test.py:35:19:35:42 | ControlFlowNode for Attribute() | test.py:43:9:43:19 | ControlFlowNode for blob_client | Unsafe usage of v1 version of Azure Storage client-side encryption | | test.py:75:9:75:10 | ControlFlowNode for bc | test.py:3:7:3:51 | ControlFlowNode for Attribute() | test.py:75:9:75:10 | ControlFlowNode for bc | Unsafe usage of v1 version of Azure Storage client-side encryption | -| test.py:75:9:75:10 | ControlFlowNode for bc | test.py:66:19:66:42 | ControlFlowNode for Attribute() | test.py:75:9:75:10 | ControlFlowNode for bc | Unsafe usage of v1 version of Azure Storage client-side encryption | From 3fbf90cbd7dca404ac25eca52fd9edcabee37b45 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nora=20Dimitrijevi=C4=87?= <d10c@users.noreply.github.com> Date: Wed, 29 Mar 2023 11:35:22 +0200 Subject: [PATCH 586/631] Swift: add ConstructorDecl.isFailable/0 --- .../codeql/swift/dataflow/internal/DataFlowPrivate.qll | 6 +++--- .../ql/lib/codeql/swift/elements/decl/ConstructorDecl.qll | 8 ++++++++ 2 files changed, 11 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 3ddbde6718a..25bc8adfccc 100644 --- a/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowPrivate.qll +++ b/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowPrivate.qll @@ -602,12 +602,12 @@ predicate storeStep(Node node1, ContentSet c, Node node2) { c instanceof OptionalSomeContentSet ) or - // creation of an optional by returning from an optional initializer (`init?`) - exists(ConstructorDecl init, OptionalType initRetType | + // creation of an optional by returning from a failable initializer (`init?`) + exists(ConstructorDecl init | node1.asExpr().(CallExpr).getStaticTarget() = init and node2 = node1 and // HACK: again, we should ideally have a separate Node case here, and not reuse the CallExpr c instanceof OptionalSomeContentSet and - init.getInterfaceType().(FunctionType).getResult().(FunctionType).getResult() = initRetType + init.isFailable() ) or FlowSummaryImpl::Private::Steps::summaryStoreStep(node1, c, node2) diff --git a/swift/ql/lib/codeql/swift/elements/decl/ConstructorDecl.qll b/swift/ql/lib/codeql/swift/elements/decl/ConstructorDecl.qll index ea70657abb3..8cb6843744c 100644 --- a/swift/ql/lib/codeql/swift/elements/decl/ConstructorDecl.qll +++ b/swift/ql/lib/codeql/swift/elements/decl/ConstructorDecl.qll @@ -1,9 +1,17 @@ private import codeql.swift.generated.decl.ConstructorDecl private import codeql.swift.elements.decl.MethodDecl +private import codeql.swift.elements.type.FunctionType +private import codeql.swift.elements.type.OptionalType /** * An initializer of a class, struct, enum or protocol. */ class ConstructorDecl extends Generated::ConstructorDecl, MethodDecl { override string toString() { result = this.getSelfParam().getType() + "." + super.toString() } + + /** Holds if this initializer returns an optional type. Failable initializers are written as `init?`. */ + predicate isFailable() { + this.getInterfaceType().(FunctionType).getResult().(FunctionType).getResult() instanceof + OptionalType + } } From 70ed8c6e8fc5c3a948d2b59b72f5cc5014e000af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nora=20Dimitrijevi=C4=87?= <d10c@users.noreply.github.com> Date: Wed, 29 Mar 2023 11:52:36 +0200 Subject: [PATCH 587/631] Swift: add QLdoc to Pattern --- swift/ql/lib/codeql/swift/elements/pattern/Pattern.qll | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/swift/ql/lib/codeql/swift/elements/pattern/Pattern.qll b/swift/ql/lib/codeql/swift/elements/pattern/Pattern.qll index 617da58fdb1..74acce50ee9 100644 --- a/swift/ql/lib/codeql/swift/elements/pattern/Pattern.qll +++ b/swift/ql/lib/codeql/swift/elements/pattern/Pattern.qll @@ -18,6 +18,10 @@ private import codeql.swift.elements.decl.PatternBindingDecl private import codeql.swift.elements.decl.EnumElementDecl private import codeql.swift.generated.ParentChild +/** + * A syntactic construct that can be matched against an expression, + * occurring in switch cases, conditions, and variable bindings. + */ class Pattern extends Generated::Pattern { /** * Gets the expression that this top-level pattern is matched against, if any. From 5278bbcaaa50be652312311c307ef87cc4b8c869 Mon Sep 17 00:00:00 2001 From: Michael Nebel <michaelnebel@github.com> Date: Mon, 27 Mar 2023 11:45:55 +0200 Subject: [PATCH 588/631] C#: Re-factor SymmetricKeyTaintTrackingConfiguration to use the new API. --- .../EncryptionKeyDataFlowQuery.qll | 23 ++++++++++++++++++- .../CWE-321/HardcodedEncryptionKey.ql | 8 +++---- 2 files changed, 26 insertions(+), 5 deletions(-) diff --git a/csharp/ql/lib/semmle/code/csharp/security/cryptography/EncryptionKeyDataFlowQuery.qll b/csharp/ql/lib/semmle/code/csharp/security/cryptography/EncryptionKeyDataFlowQuery.qll index b1bd83d143c..0509066fbbc 100644 --- a/csharp/ql/lib/semmle/code/csharp/security/cryptography/EncryptionKeyDataFlowQuery.qll +++ b/csharp/ql/lib/semmle/code/csharp/security/cryptography/EncryptionKeyDataFlowQuery.qll @@ -64,9 +64,11 @@ class SymmetricEncryptionCreateDecryptorSink extends SymmetricEncryptionKeySink } /** + * DEPRECATED: Use `SymmetricKey` instead. + * * Symmetric Key Data Flow configuration. */ -class SymmetricKeyTaintTrackingConfiguration extends TaintTracking::Configuration { +deprecated class SymmetricKeyTaintTrackingConfiguration extends TaintTracking::Configuration { SymmetricKeyTaintTrackingConfiguration() { this = "SymmetricKeyTaintTracking" } /** Holds if the node is a key source. */ @@ -78,3 +80,22 @@ class SymmetricKeyTaintTrackingConfiguration extends TaintTracking::Configuratio /** Holds if the node is a key sanitizer. */ override predicate isSanitizer(DataFlow::Node sanitizer) { sanitizer instanceof KeySanitizer } } + +/** + * Symmetric Key Data Flow configuration. + */ +private module SymmetricKeyConfig implements DataFlow::ConfigSig { + /** Holds if the node is a key source. */ + predicate isSource(DataFlow::Node src) { src instanceof KeySource } + + /** Holds if the node is a symmetric encryption key sink. */ + predicate isSink(DataFlow::Node sink) { sink instanceof SymmetricEncryptionKeySink } + + /** Holds if the node is a key sanitizer. */ + predicate isBarrier(DataFlow::Node sanitizer) { sanitizer instanceof KeySanitizer } +} + +/** + * Symmetric Key Data Flow configuration. + */ +module SymmetricKey = TaintTracking::Global<SymmetricKeyConfig>; diff --git a/csharp/ql/src/Security Features/CWE-321/HardcodedEncryptionKey.ql b/csharp/ql/src/Security Features/CWE-321/HardcodedEncryptionKey.ql index 8e516f44d4a..c06768cb2bf 100644 --- a/csharp/ql/src/Security Features/CWE-321/HardcodedEncryptionKey.ql +++ b/csharp/ql/src/Security Features/CWE-321/HardcodedEncryptionKey.ql @@ -15,7 +15,7 @@ import csharp import semmle.code.csharp.security.cryptography.EncryptionKeyDataFlowQuery -import DataFlow::PathGraph +import SymmetricKey::PathGraph /** * The creation of a literal byte array. @@ -38,10 +38,10 @@ class StringLiteralSource extends KeySource { } from - SymmetricKeyTaintTrackingConfiguration keyFlow, DataFlow::PathNode source, - DataFlow::PathNode sink, KeySource srcNode, SymmetricEncryptionKeySink sinkNode + SymmetricKey::PathNode source, SymmetricKey::PathNode sink, KeySource srcNode, + SymmetricEncryptionKeySink sinkNode where - keyFlow.hasFlowPath(source, sink) and + SymmetricKey::flowPath(source, sink) and source.getNode() = srcNode and sink.getNode() = sinkNode select sink.getNode(), source, sink, From c03ce2f63b56bf2d665f9c823be89838b949910a Mon Sep 17 00:00:00 2001 From: Michael Nebel <michaelnebel@github.com> Date: Mon, 27 Mar 2023 11:57:37 +0200 Subject: [PATCH 589/631] C#: Re-factor HardCodedSymmetricEncryptionKey to use the new API. --- .../HardcodedSymmetricEncryptionKey.qll | 30 +++++++++++++++++++ .../HardcodedSymmetricEncryptionKey.ql | 6 ++-- 2 files changed, 33 insertions(+), 3 deletions(-) diff --git a/csharp/ql/lib/semmle/code/csharp/security/cryptography/HardcodedSymmetricEncryptionKey.qll b/csharp/ql/lib/semmle/code/csharp/security/cryptography/HardcodedSymmetricEncryptionKey.qll index e937e69919e..d00cef763df 100644 --- a/csharp/ql/lib/semmle/code/csharp/security/cryptography/HardcodedSymmetricEncryptionKey.qll +++ b/csharp/ql/lib/semmle/code/csharp/security/cryptography/HardcodedSymmetricEncryptionKey.qll @@ -62,6 +62,8 @@ module HardcodedSymmetricEncryptionKey { } /** + * DEPRECATED: Use `HardCodedSymmetricEncryption` instead. + * * A taint-tracking configuration for uncontrolled data in path expression vulnerabilities. */ class TaintTrackingConfiguration extends TaintTracking::Configuration { @@ -85,4 +87,32 @@ module HardcodedSymmetricEncryptionKey { ) } } + + /** + * A taint-tracking configuration for uncontrolled data in path expression vulnerabilities. + */ + private module HardCodedSymmetricEncryptionConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node source) { source instanceof Source } + + predicate isSink(DataFlow::Node sink) { sink instanceof Sink } + + predicate isBarrier(DataFlow::Node node) { node instanceof Sanitizer } + + /** + * Since `CryptographicBuffer` uses native code inside, taint tracking doesn't pass through it. + * Need to create an additional custom step. + */ + predicate isAdditionalFlowStep(DataFlow::Node pred, DataFlow::Node succ) { + exists(MethodCall mc, CryptographicBuffer c | + pred.asExpr() = mc.getAnArgument() and + mc.getTarget() = c.getAMethod() and + succ.asExpr() = mc + ) + } + } + + /** + * A taint-tracking module for uncontrolled data in path expression vulnerabilities. + */ + module HardCodedSymmetricEncryption = TaintTracking::Global<HardCodedSymmetricEncryptionConfig>; } diff --git a/csharp/ql/src/Security Features/CWE-321/HardcodedSymmetricEncryptionKey.ql b/csharp/ql/src/Security Features/CWE-321/HardcodedSymmetricEncryptionKey.ql index 4de91b9a214..099df293c23 100644 --- a/csharp/ql/src/Security Features/CWE-321/HardcodedSymmetricEncryptionKey.ql +++ b/csharp/ql/src/Security Features/CWE-321/HardcodedSymmetricEncryptionKey.ql @@ -15,10 +15,10 @@ import csharp import semmle.code.csharp.security.cryptography.HardcodedSymmetricEncryptionKey::HardcodedSymmetricEncryptionKey -import DataFlow::PathGraph +import HardCodedSymmetricEncryption::PathGraph -from TaintTrackingConfiguration c, DataFlow::PathNode source, DataFlow::PathNode sink -where c.hasFlowPath(source, sink) +from HardCodedSymmetricEncryption::PathNode source, HardCodedSymmetricEncryption::PathNode sink +where HardCodedSymmetricEncryption::flowPath(source, sink) select sink.getNode(), source, sink, "Hard-coded symmetric $@ is used in symmetric algorithm in " + sink.getNode().(Sink).getDescription() + ".", source.getNode(), "key" From cab976cf8f052919ffcfaf2fb5a3cf83d1901a55 Mon Sep 17 00:00:00 2001 From: Michael Nebel <michaelnebel@github.com> Date: Mon, 27 Mar 2023 13:45:10 +0200 Subject: [PATCH 590/631] C#: Re-factor CommandInjection to use the new API. --- .../dataflow/CommandInjectionQuery.qll | 28 +++++++++++++++++++ .../CWE-078/CommandInjection.ql | 6 ++-- .../CWE-078/StoredCommandInjection.ql | 16 +++++++---- 3 files changed, 42 insertions(+), 8 deletions(-) diff --git a/csharp/ql/lib/semmle/code/csharp/security/dataflow/CommandInjectionQuery.qll b/csharp/ql/lib/semmle/code/csharp/security/dataflow/CommandInjectionQuery.qll index 82798a34743..4eabf16e7a5 100644 --- a/csharp/ql/lib/semmle/code/csharp/security/dataflow/CommandInjectionQuery.qll +++ b/csharp/ql/lib/semmle/code/csharp/security/dataflow/CommandInjectionQuery.qll @@ -23,6 +23,8 @@ abstract class Sink extends DataFlow::ExprNode { } abstract class Sanitizer extends DataFlow::ExprNode { } /** + * DEPRECATED: Use `CommandInjection` instead. + * * A taint-tracking configuration for command injection vulnerabilities. */ class TaintTrackingConfiguration extends TaintTracking::Configuration { @@ -35,6 +37,32 @@ class TaintTrackingConfiguration extends TaintTracking::Configuration { override predicate isSanitizer(DataFlow::Node node) { node instanceof Sanitizer } } +/** + * A taint-tracking configuration for command injection vulnerabilities. + */ +module CommandInjectionConfig implements DataFlow::ConfigSig { + /** + * Holds if `source` is a relevant data flow source. + */ + predicate isSource(DataFlow::Node source) { source instanceof Source } + + /** + * Holds if `sink` is a relevant data flow sink. + */ + predicate isSink(DataFlow::Node sink) { sink instanceof Sink } + + /** + * Holds if data flow through `node` is prohibited. This completely removes + * `node` from the data flow graph. + */ + predicate isBarrier(DataFlow::Node node) { node instanceof Sanitizer } +} + +/** + * A taint-tracking module for command injection vulnerabilities. + */ +module CommandInjection = TaintTracking::Global<CommandInjectionConfig>; + /** A source of remote user input. */ class RemoteSource extends Source instanceof RemoteFlowSource { } diff --git a/csharp/ql/src/Security Features/CWE-078/CommandInjection.ql b/csharp/ql/src/Security Features/CWE-078/CommandInjection.ql index 20a7be1c5b0..41eea7f4238 100644 --- a/csharp/ql/src/Security Features/CWE-078/CommandInjection.ql +++ b/csharp/ql/src/Security Features/CWE-078/CommandInjection.ql @@ -15,9 +15,9 @@ import csharp import semmle.code.csharp.security.dataflow.CommandInjectionQuery -import semmle.code.csharp.dataflow.DataFlow::DataFlow::PathGraph +import CommandInjection::PathGraph -from TaintTrackingConfiguration c, DataFlow::PathNode source, DataFlow::PathNode sink -where c.hasFlowPath(source, sink) +from CommandInjection::PathNode source, CommandInjection::PathNode sink +where CommandInjection::flowPath(source, sink) select sink.getNode(), source, sink, "This command line depends on a $@.", source.getNode(), "user-provided value" diff --git a/csharp/ql/src/Security Features/CWE-078/StoredCommandInjection.ql b/csharp/ql/src/Security Features/CWE-078/StoredCommandInjection.ql index 8fa673f50f3..5f728db8473 100644 --- a/csharp/ql/src/Security Features/CWE-078/StoredCommandInjection.ql +++ b/csharp/ql/src/Security Features/CWE-078/StoredCommandInjection.ql @@ -16,13 +16,19 @@ import csharp import semmle.code.csharp.security.dataflow.flowsources.Stored import semmle.code.csharp.security.dataflow.CommandInjectionQuery -import semmle.code.csharp.dataflow.DataFlow::DataFlow::PathGraph +import StoredCommandInjection::PathGraph -class StoredTaintTrackingConfiguration extends TaintTrackingConfiguration { - override predicate isSource(DataFlow::Node source) { source instanceof StoredFlowSource } +module StoredCommandInjectionConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node source) { source instanceof StoredFlowSource } + + predicate isSink = CommandInjectionConfig::isSink/1; + + predicate isBarrier = CommandInjectionConfig::isBarrier/1; } -from StoredTaintTrackingConfiguration c, DataFlow::PathNode source, DataFlow::PathNode sink -where c.hasFlowPath(source, sink) +module StoredCommandInjection = TaintTracking::Global<StoredCommandInjectionConfig>; + +from StoredCommandInjection::PathNode source, StoredCommandInjection::PathNode sink +where StoredCommandInjection::flowPath(source, sink) select sink.getNode(), source, sink, "This command line depends on a $@.", source.getNode(), "stored (potentially user-provided) value" From 60c5bbde0fca43920ffef5993b7a2b2906df3004 Mon Sep 17 00:00:00 2001 From: Michael Nebel <michaelnebel@github.com> Date: Mon, 27 Mar 2023 14:09:59 +0200 Subject: [PATCH 591/631] C#: Re-factor ConditionalBypass to use the new API. --- .../dataflow/ConditionalBypassQuery.qll | 18 ++++++++++++++++++ .../CWE-807/ConditionalBypass.ql | 6 +++--- 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/csharp/ql/lib/semmle/code/csharp/security/dataflow/ConditionalBypassQuery.qll b/csharp/ql/lib/semmle/code/csharp/security/dataflow/ConditionalBypassQuery.qll index e41a868be48..9d52e623e66 100644 --- a/csharp/ql/lib/semmle/code/csharp/security/dataflow/ConditionalBypassQuery.qll +++ b/csharp/ql/lib/semmle/code/csharp/security/dataflow/ConditionalBypassQuery.qll @@ -30,6 +30,8 @@ abstract class Sink extends DataFlow::ExprNode { abstract class Sanitizer extends DataFlow::ExprNode { } /** + * DEPRECATED: Use `ConditionalBypass` instead. + * * A taint-tracking configuration for user-controlled bypass of sensitive method. */ class Configuration extends TaintTracking::Configuration { @@ -42,6 +44,22 @@ class Configuration extends TaintTracking::Configuration { override predicate isSanitizer(DataFlow::Node node) { node instanceof Sanitizer } } +/** + * A taint-tracking configuration for user-controlled bypass of sensitive method. + */ +private module ConditionalBypassConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node source) { source instanceof Source } + + predicate isSink(DataFlow::Node sink) { sink instanceof Sink } + + predicate isBarrier(DataFlow::Node node) { node instanceof Sanitizer } +} + +/** + * A taint-tracking module for user-controlled bypass of sensitive method. + */ +module ConditionalBypass = TaintTracking::Global<ConditionalBypassConfig>; + /** A source of remote user input. */ class RemoteSource extends Source instanceof RemoteFlowSource { } diff --git a/csharp/ql/src/Security Features/CWE-807/ConditionalBypass.ql b/csharp/ql/src/Security Features/CWE-807/ConditionalBypass.ql index 5fc59c13c57..cf55572e6c1 100644 --- a/csharp/ql/src/Security Features/CWE-807/ConditionalBypass.ql +++ b/csharp/ql/src/Security Features/CWE-807/ConditionalBypass.ql @@ -15,9 +15,9 @@ import csharp import semmle.code.csharp.security.dataflow.ConditionalBypassQuery -import semmle.code.csharp.dataflow.DataFlow::DataFlow::PathGraph +import ConditionalBypass::PathGraph -from Configuration config, DataFlow::PathNode source, DataFlow::PathNode sink -where config.hasFlowPath(source, sink) +from ConditionalBypass::PathNode source, ConditionalBypass::PathNode sink +where ConditionalBypass::flowPath(source, sink) select sink.getNode(), source, sink, "This condition guards a sensitive $@, but a $@ controls it.", sink.getNode().(Sink).getSensitiveMethodCall(), "action", source.getNode(), "user-provided value" From cc4f3f62340afc6eaa68c3840d2ecbbc11879cf0 Mon Sep 17 00:00:00 2001 From: Michael Nebel <michaelnebel@github.com> Date: Mon, 27 Mar 2023 14:24:01 +0200 Subject: [PATCH 592/631] C#: Re-factor CodeInjection to use the new API. --- .../security/dataflow/CodeInjectionQuery.qll | 18 ++++++++++++++++++ .../Security Features/CWE-094/CodeInjection.ql | 6 +++--- 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/csharp/ql/lib/semmle/code/csharp/security/dataflow/CodeInjectionQuery.qll b/csharp/ql/lib/semmle/code/csharp/security/dataflow/CodeInjectionQuery.qll index 4061ab8651c..0ae163c773e 100644 --- a/csharp/ql/lib/semmle/code/csharp/security/dataflow/CodeInjectionQuery.qll +++ b/csharp/ql/lib/semmle/code/csharp/security/dataflow/CodeInjectionQuery.qll @@ -25,6 +25,8 @@ abstract class Sink extends DataFlow::ExprNode { } abstract class Sanitizer extends DataFlow::ExprNode { } /** + * DEPRECATED: Use `CodeInjection` instead. + * * A taint-tracking configuration for user input treated as code vulnerabilities. */ class TaintTrackingConfiguration extends TaintTracking::Configuration { @@ -37,6 +39,22 @@ class TaintTrackingConfiguration extends TaintTracking::Configuration { override predicate isSanitizer(DataFlow::Node node) { node instanceof Sanitizer } } +/** + * A taint-tracking configuration for user input treated as code vulnerabilities. + */ +private module CodeInjectionConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node source) { source instanceof Source } + + predicate isSink(DataFlow::Node sink) { sink instanceof Sink } + + predicate isBarrier(DataFlow::Node node) { node instanceof Sanitizer } +} + +/** + * A taint-tracking module for user input treated as code vulnerabilities. + */ +module CodeInjection = TaintTracking::Global<CodeInjectionConfig>; + /** A source of remote user input. */ class RemoteSource extends Source instanceof RemoteFlowSource { } diff --git a/csharp/ql/src/Security Features/CWE-094/CodeInjection.ql b/csharp/ql/src/Security Features/CWE-094/CodeInjection.ql index 17e15fee924..060c6739d82 100644 --- a/csharp/ql/src/Security Features/CWE-094/CodeInjection.ql +++ b/csharp/ql/src/Security Features/CWE-094/CodeInjection.ql @@ -15,9 +15,9 @@ import csharp import semmle.code.csharp.security.dataflow.CodeInjectionQuery -import semmle.code.csharp.dataflow.DataFlow::DataFlow::PathGraph +import CodeInjection::PathGraph -from TaintTrackingConfiguration c, DataFlow::PathNode source, DataFlow::PathNode sink -where c.hasFlowPath(source, sink) +from CodeInjection::PathNode source, CodeInjection::PathNode sink +where CodeInjection::flowPath(source, sink) select sink.getNode(), source, sink, "This code compilation depends on a $@.", source.getNode(), "user-provided value" From 483e5c5264a4990ac705311fce72c99fa5116661 Mon Sep 17 00:00:00 2001 From: Michael Nebel <michaelnebel@github.com> Date: Mon, 27 Mar 2023 14:32:02 +0200 Subject: [PATCH 593/631] C#: Re-factor ExposureOfPrivateInformation to use the new API. --- .../ExposureOfPrivateInformationQuery.qll | 18 ++++++++++++++++++ .../CWE-359/ExposureOfPrivateInformation.ql | 6 +++--- 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/csharp/ql/lib/semmle/code/csharp/security/dataflow/ExposureOfPrivateInformationQuery.qll b/csharp/ql/lib/semmle/code/csharp/security/dataflow/ExposureOfPrivateInformationQuery.qll index 2bf409899ee..b1ea7c7b09c 100644 --- a/csharp/ql/lib/semmle/code/csharp/security/dataflow/ExposureOfPrivateInformationQuery.qll +++ b/csharp/ql/lib/semmle/code/csharp/security/dataflow/ExposureOfPrivateInformationQuery.qll @@ -23,6 +23,8 @@ abstract class Sink extends DataFlow::ExprNode { } abstract class Sanitizer extends DataFlow::ExprNode { } /** + * DEPRECATED: Use `ExposureOfPrivateInformation` instead. + * * A taint-tracking configuration for private information flowing unencrypted to an external location. */ class TaintTrackingConfiguration extends TaintTracking::Configuration { @@ -35,6 +37,22 @@ class TaintTrackingConfiguration extends TaintTracking::Configuration { override predicate isSanitizer(DataFlow::Node node) { node instanceof Sanitizer } } +/** + * A taint-tracking configuration for private information flowing unencrypted to an external location. + */ +private module ExposureOfPrivateInformationConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node source) { source instanceof Source } + + predicate isSink(DataFlow::Node sink) { sink instanceof Sink } + + predicate isBarrier(DataFlow::Node node) { node instanceof Sanitizer } +} + +/** + * A taint-tracking module for private information flowing unencrypted to an external location. + */ +module ExposureOfPrivateInformation = TaintTracking::Global<ExposureOfPrivateInformationConfig>; + private class PrivateDataSource extends Source { PrivateDataSource() { this.getExpr() instanceof PrivateDataExpr } } diff --git a/csharp/ql/src/Security Features/CWE-359/ExposureOfPrivateInformation.ql b/csharp/ql/src/Security Features/CWE-359/ExposureOfPrivateInformation.ql index ac2f945258e..3a8faf9e4c1 100644 --- a/csharp/ql/src/Security Features/CWE-359/ExposureOfPrivateInformation.ql +++ b/csharp/ql/src/Security Features/CWE-359/ExposureOfPrivateInformation.ql @@ -13,10 +13,10 @@ import csharp import semmle.code.csharp.security.dataflow.ExposureOfPrivateInformationQuery -import semmle.code.csharp.dataflow.DataFlow::DataFlow::PathGraph +import ExposureOfPrivateInformation::PathGraph -from TaintTrackingConfiguration c, DataFlow::PathNode source, DataFlow::PathNode sink -where c.hasFlowPath(source, sink) +from ExposureOfPrivateInformation::PathNode source, ExposureOfPrivateInformation::PathNode sink +where ExposureOfPrivateInformation::flowPath(source, sink) select sink.getNode(), source, sink, "Private data returned by $@ is written to an external location.", source.getNode(), source.getNode().toString() From 34cbaf10c23e1b31a412debc1ab83638c4a5685d Mon Sep 17 00:00:00 2001 From: Rasmus Wriedt Larsen <rasmuswl@github.com> Date: Wed, 29 Mar 2023 13:22:21 +0200 Subject: [PATCH 594/631] Python: Use PostUpdateNode in `py/azure-storage/unsafe-client-side-encryption-in-use` --- .../Azure/UnsafeUsageOfClientSideEncryptionVersion.ql | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/python/ql/src/experimental/Security/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql b/python/ql/src/experimental/Security/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql index 15892e00e5a..9b73cdcec87 100644 --- a/python/ql/src/experimental/Security/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql +++ b/python/ql/src/experimental/Security/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql @@ -111,6 +111,11 @@ module AzureBlobClientConfig implements DataFlow::StateConfigSig { attr.accesses(node, "encryption_version") and attr.getValue().asExpr().(StrConst).getText() in ["'2.0'", "2.0"] ) + or + // small optimization to block flow with no encryption out of the post-update node + // for the attribute assignment. + isAdditionalFlowStep(_, MkUsesNoEncryption(), node, MkUsesV1Encryption()) and + state = MkUsesNoEncryption() } predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) { @@ -124,7 +129,7 @@ module AzureBlobClientConfig implements DataFlow::StateConfigSig { predicate isAdditionalFlowStep( DataFlow::Node node1, FlowState state1, DataFlow::Node node2, FlowState state2 ) { - node1 = node2 and + node1 = node2.(DataFlow::PostUpdateNode).getPreUpdateNode() and state1 = MkUsesNoEncryption() and state2 = MkUsesV1Encryption() and exists(DataFlow::AttrWrite attr | From 17cdd16c19feb8a838606e03e1431e2f209c4fc7 Mon Sep 17 00:00:00 2001 From: Ed Minnix <egregius313@github.com> Date: Wed, 29 Mar 2023 07:23:13 -0400 Subject: [PATCH 595/631] Fix miscopied isBarrier in JndiInjectionQuery --- java/ql/lib/semmle/code/java/security/JndiInjectionQuery.qll | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/java/ql/lib/semmle/code/java/security/JndiInjectionQuery.qll b/java/ql/lib/semmle/code/java/security/JndiInjectionQuery.qll index 225627fc5de..d189c119080 100644 --- a/java/ql/lib/semmle/code/java/security/JndiInjectionQuery.qll +++ b/java/ql/lib/semmle/code/java/security/JndiInjectionQuery.qll @@ -38,7 +38,9 @@ module JndiInjectionFlowConfig implements DataFlow::ConfigSig { predicate isSink(DataFlow::Node sink) { sink instanceof JndiInjectionSink } predicate isBarrier(DataFlow::Node node) { - node.getType() instanceof PrimitiveType or node.getType() instanceof BoxedType + node.getType() instanceof PrimitiveType or + node.getType() instanceof BoxedType or + node instanceof JndiInjectionSanitizer } predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) { From c8579d8c26e61cf7e89c6d392e20abb7f8f23fcc Mon Sep 17 00:00:00 2001 From: Ed Minnix <egregius313@github.com> Date: Wed, 29 Mar 2023 07:24:32 -0400 Subject: [PATCH 596/631] RegexInjection docs --- .../semmle/code/java/security/regexp/RegexInjectionQuery.qll | 3 +++ 1 file changed, 3 insertions(+) diff --git a/java/ql/lib/semmle/code/java/security/regexp/RegexInjectionQuery.qll b/java/ql/lib/semmle/code/java/security/regexp/RegexInjectionQuery.qll index af8b4e204a1..409143c18f8 100644 --- a/java/ql/lib/semmle/code/java/security/regexp/RegexInjectionQuery.qll +++ b/java/ql/lib/semmle/code/java/security/regexp/RegexInjectionQuery.qll @@ -31,4 +31,7 @@ module RegexInjectionConfig implements DataFlow::ConfigSig { predicate isBarrier(DataFlow::Node node) { node instanceof RegexInjectionSanitizer } } +/** + * Taint-tracking flow for untrusted user input used to construct regular expressions. + */ module RegexInjectionFlow = TaintTracking::Global<RegexInjectionConfig>; From e91b5de875b03ed3b4a1d953fc40f2983c0886fa Mon Sep 17 00:00:00 2001 From: Tom Hvitved <hvitved@github.com> Date: Wed, 29 Mar 2023 13:27:06 +0200 Subject: [PATCH 597/631] Run Ruby QL tests on changes to `shared` --- .github/workflows/ruby-qltest.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/ruby-qltest.yml b/.github/workflows/ruby-qltest.yml index 370375cea93..765ed8ce8c7 100644 --- a/.github/workflows/ruby-qltest.yml +++ b/.github/workflows/ruby-qltest.yml @@ -4,6 +4,7 @@ on: push: paths: - "ruby/**" + - "shared/**" - .github/workflows/ruby-build.yml - .github/actions/fetch-codeql/action.yml - codeql-workspace.yml From fe487a1ae80746b4181fd1d40e7fdae46db4995d Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen <mathiasvp@github.com> Date: Wed, 29 Mar 2023 12:30:24 +0100 Subject: [PATCH 598/631] C++: Respond to PR reviews. --- .../semantic/analysis/RangeAnalysisStage.qll | 36 +++++++++++-------- 1 file changed, 22 insertions(+), 14 deletions(-) diff --git a/cpp/ql/lib/experimental/semmle/code/cpp/semantic/analysis/RangeAnalysisStage.qll b/cpp/ql/lib/experimental/semmle/code/cpp/semantic/analysis/RangeAnalysisStage.qll index 0c1dbd99cad..4331df00c17 100644 --- a/cpp/ql/lib/experimental/semmle/code/cpp/semantic/analysis/RangeAnalysisStage.qll +++ b/cpp/ql/lib/experimental/semmle/code/cpp/semantic/analysis/RangeAnalysisStage.qll @@ -1064,17 +1064,17 @@ module RangeStage<DeltaSig D, BoundSig<D> Bounds, LangSig<D> LangParam, UtilSig< ) or exists( - SemZeroBound bLeft, SemZeroBound bRight, D::Delta dLeft, D::Delta dRight, boolean fbeLeft, - boolean fbeRight, D::Delta odLeft, D::Delta odRight, SemReason rLeft, SemReason rRight + D::Delta dLeft, D::Delta dRight, boolean fbeLeft, boolean fbeRight, D::Delta odLeft, + D::Delta odRight, SemReason rLeft, SemReason rRight | - boundedMulOperand(e, upper, bLeft, true, dLeft, fbeLeft, odLeft, rLeft) and - boundedMulOperand(e, upper, bRight, false, dRight, fbeRight, odRight, rRight) and + boundedMulOperand(e, upper, true, dLeft, fbeLeft, odLeft, rLeft) and + boundedMulOperand(e, upper, false, dRight, fbeRight, odRight, rRight) and delta = D::fromFloat(D::toFloat(dLeft) * D::toFloat(dRight)) and fromBackEdge = fbeLeft.booleanOr(fbeRight) | - b = bLeft and origdelta = odLeft and reason = rLeft + b instanceof SemZeroBound and origdelta = odLeft and reason = rLeft or - b = bRight and origdelta = odRight and reason = rRight + b instanceof SemZeroBound and origdelta = odRight and reason = rRight ) ) } @@ -1111,11 +1111,11 @@ module RangeStage<DeltaSig D, BoundSig<D> Bounds, LangSig<D> LangParam, UtilSig< } /** - * Define `cmp(true) = <=` and `cmp(false) >=`. + * Define `cmp(true) = <=` and `cmp(false) = >=`. * - * Holds if `mul = left * right`, and in order to know if `mul cmp(upper) B + k` (for - * some `B` and `k`) we need to know that `left cmp(upperLeft) B1 + k1` and - * `right cmp(upperRight) B2 + k2` (for some `B1`, `B2`, `k1`, and `k2`). + * Holds if `mul = left * right`, and in order to know if `mul cmp(upper) Z + k` (for + * some `k`) we need to know that `left cmp(upperLeft) Z + k1` and + * `right cmp(upperRight) Z + k2` (for some `k1` and `k2`). */ pragma[nomagic] private predicate boundedMulOperandCand( @@ -1190,19 +1190,27 @@ module RangeStage<DeltaSig D, BoundSig<D> Bounds, LangSig<D> LangParam, UtilSig< ) } + /** + * Holds if `isLeft = true` and `mul`'s left operand is bounded by `delta`, + * or if `isLeft = false` and `mul`'s right operand is bounded by `delta`. + * + * If `upper = true` the computed bound is an upper boud, and if `upper = false` + * the computed bound is a lower bound. The `fromBackEdge`, `origdelta`, `reason` + * triple are defined by the recursive call to `bounded`. + */ pragma[nomagic] private predicate boundedMulOperand( - SemMulExpr mul, boolean upper, SemZeroBound b, boolean isLeft, D::Delta delta, - boolean fromBackEdge, D::Delta origdelta, SemReason reason + SemMulExpr mul, boolean upper, boolean isLeft, D::Delta delta, boolean fromBackEdge, + D::Delta origdelta, SemReason reason ) { exists(boolean upperLeft, boolean upperRight, SemExpr left, SemExpr right | boundedMulOperandCand(mul, left, right, upper, upperLeft, upperRight) | isLeft = true and - bounded(left, b, delta, upperLeft, fromBackEdge, origdelta, reason) + bounded(left, any(SemZeroBound zb), delta, upperLeft, fromBackEdge, origdelta, reason) or isLeft = false and - bounded(right, b, delta, upperRight, fromBackEdge, origdelta, reason) + bounded(right, any(SemZeroBound zb), delta, upperRight, fromBackEdge, origdelta, reason) ) } } From c14bccf7eb319beb636d2e0cf1d62d9b6fd51762 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen <mathiasvp@github.com> Date: Wed, 29 Mar 2023 12:41:04 +0100 Subject: [PATCH 599/631] C++: Fix QLDoc. --- .../code/cpp/semantic/analysis/RangeAnalysisStage.qll | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/cpp/ql/lib/experimental/semmle/code/cpp/semantic/analysis/RangeAnalysisStage.qll b/cpp/ql/lib/experimental/semmle/code/cpp/semantic/analysis/RangeAnalysisStage.qll index 4331df00c17..dc87c477dda 100644 --- a/cpp/ql/lib/experimental/semmle/code/cpp/semantic/analysis/RangeAnalysisStage.qll +++ b/cpp/ql/lib/experimental/semmle/code/cpp/semantic/analysis/RangeAnalysisStage.qll @@ -1194,9 +1194,10 @@ module RangeStage<DeltaSig D, BoundSig<D> Bounds, LangSig<D> LangParam, UtilSig< * Holds if `isLeft = true` and `mul`'s left operand is bounded by `delta`, * or if `isLeft = false` and `mul`'s right operand is bounded by `delta`. * - * If `upper = true` the computed bound is an upper boud, and if `upper = false` - * the computed bound is a lower bound. The `fromBackEdge`, `origdelta`, `reason` - * triple are defined by the recursive call to `bounded`. + * If `upper = true` the computed bound contributes to an upper bound of the + * operand, and if `upper = false` it contributes to a lower bound. + * The `fromBackEdge`, `origdelta`, `reason` triple are defined by the recursive + * call to `bounded`. */ pragma[nomagic] private predicate boundedMulOperand( From 09d0385f0f2f44cc97e119190d6a624678113410 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen <mathiasvp@github.com> Date: Wed, 29 Mar 2023 12:42:32 +0100 Subject: [PATCH 600/631] C++: Fix QLDoc. --- .../code/cpp/semantic/analysis/RangeAnalysisStage.qll | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cpp/ql/lib/experimental/semmle/code/cpp/semantic/analysis/RangeAnalysisStage.qll b/cpp/ql/lib/experimental/semmle/code/cpp/semantic/analysis/RangeAnalysisStage.qll index dc87c477dda..2d93cf9316f 100644 --- a/cpp/ql/lib/experimental/semmle/code/cpp/semantic/analysis/RangeAnalysisStage.qll +++ b/cpp/ql/lib/experimental/semmle/code/cpp/semantic/analysis/RangeAnalysisStage.qll @@ -1113,9 +1113,9 @@ module RangeStage<DeltaSig D, BoundSig<D> Bounds, LangSig<D> LangParam, UtilSig< /** * Define `cmp(true) = <=` and `cmp(false) = >=`. * - * Holds if `mul = left * right`, and in order to know if `mul cmp(upper) Z + k` (for - * some `k`) we need to know that `left cmp(upperLeft) Z + k1` and - * `right cmp(upperRight) Z + k2` (for some `k1` and `k2`). + * Holds if `mul = left * right`, and in order to know if `mul cmp(upper) 0 + k` (for + * some `k`) we need to know that `left cmp(upperLeft) 0 + k1` and + * `right cmp(upperRight) 0 + k2` (for some `k1` and `k2`). */ pragma[nomagic] private predicate boundedMulOperandCand( From 9d5c785d89d6bb694f239ae149ab5ebe18100a43 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen <mathiasvp@github.com> Date: Wed, 29 Mar 2023 12:45:27 +0100 Subject: [PATCH 601/631] C++: Even more fix'ing QLDoc. --- .../semmle/code/cpp/semantic/analysis/RangeAnalysisStage.qll | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cpp/ql/lib/experimental/semmle/code/cpp/semantic/analysis/RangeAnalysisStage.qll b/cpp/ql/lib/experimental/semmle/code/cpp/semantic/analysis/RangeAnalysisStage.qll index 2d93cf9316f..d70c59d168f 100644 --- a/cpp/ql/lib/experimental/semmle/code/cpp/semantic/analysis/RangeAnalysisStage.qll +++ b/cpp/ql/lib/experimental/semmle/code/cpp/semantic/analysis/RangeAnalysisStage.qll @@ -1194,8 +1194,8 @@ module RangeStage<DeltaSig D, BoundSig<D> Bounds, LangSig<D> LangParam, UtilSig< * Holds if `isLeft = true` and `mul`'s left operand is bounded by `delta`, * or if `isLeft = false` and `mul`'s right operand is bounded by `delta`. * - * If `upper = true` the computed bound contributes to an upper bound of the - * operand, and if `upper = false` it contributes to a lower bound. + * If `upper = true` the computed bound contributes to an upper bound of `mul`, + * and if `upper = false` it contributes to a lower bound. * The `fromBackEdge`, `origdelta`, `reason` triple are defined by the recursive * call to `bounded`. */ From 069598c9e14f5d0f0da6172a1061122934264714 Mon Sep 17 00:00:00 2001 From: Alex Denisov <alexdenisov@github.com> Date: Wed, 29 Mar 2023 14:02:49 +0200 Subject: [PATCH 602/631] Swift: consider declarations from non-swift modules as lazy This change fixes all of the VALUE_NOT_IN_TYPE errors I'm seeing with the integration tests on macOS. --- swift/extractor/infra/SwiftDispatcher.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/swift/extractor/infra/SwiftDispatcher.h b/swift/extractor/infra/SwiftDispatcher.h index b2c347e36e6..dcd903c242f 100644 --- a/swift/extractor/infra/SwiftDispatcher.h +++ b/swift/extractor/infra/SwiftDispatcher.h @@ -265,7 +265,8 @@ class SwiftDispatcher { private: bool isLazyDeclaration(const swift::Decl& decl) { swift::ModuleDecl* module = decl.getModuleContext(); - return module->isBuiltinModule() || module->getName().str() == "__ObjC"; + return module->isBuiltinModule() || module->getName().str() == "__ObjC" || + module->isNonSwiftModule(); } template <typename T, typename = void> From 4fa1bbf01882bb81885175359fdeb546b45194a6 Mon Sep 17 00:00:00 2001 From: Ian Lynagh <igfoo@github.com> Date: Tue, 28 Mar 2023 15:16:27 +0100 Subject: [PATCH 603/631] Java: Allow keys to be omitted from ExtractorInformation.ql This is useful in tests, as some keys contain unstable information. --- java/ql/src/Telemetry/ExtractorInformation.ql | 23 +++++++++++-------- .../ql/src/Telemetry/ExtractorInformation.yml | 5 ++++ java/ql/src/qlpack.yml | 2 ++ 3 files changed, 21 insertions(+), 9 deletions(-) create mode 100644 java/ql/src/Telemetry/ExtractorInformation.yml diff --git a/java/ql/src/Telemetry/ExtractorInformation.ql b/java/ql/src/Telemetry/ExtractorInformation.ql index 48eb49a1b07..51990878a34 100644 --- a/java/ql/src/Telemetry/ExtractorInformation.ql +++ b/java/ql/src/Telemetry/ExtractorInformation.ql @@ -9,6 +9,8 @@ import java import semmle.code.java.Diagnostics +extensible predicate extractorInformationSkipKey(string key); + predicate compilationInfo(string key, int value) { exists(Compilation c, string infoKey | key = infoKey + ": " + c.getInfo(infoKey) and @@ -85,13 +87,16 @@ predicate extractorTotalDiagnostics(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 - numberOfLinesOfCode(key, value) or - totalNumberOfLinesByExtension(key, value) or - numberOfLinesOfCodeByExtension(key, value) or - extractorDiagnostics(key, value) or - extractorTotalDiagnostics(key, value) + not extractorInformationSkipKey(key) and + ( + compilationInfo(key, value) or + fileCount(key, value) or + fileCountByExtension(key, value) or + totalNumberOfLines(key, value) or + numberOfLinesOfCode(key, value) or + totalNumberOfLinesByExtension(key, value) or + numberOfLinesOfCodeByExtension(key, value) or + extractorDiagnostics(key, value) or + extractorTotalDiagnostics(key, value) + ) select key, value diff --git a/java/ql/src/Telemetry/ExtractorInformation.yml b/java/ql/src/Telemetry/ExtractorInformation.yml new file mode 100644 index 00000000000..74a7f99520b --- /dev/null +++ b/java/ql/src/Telemetry/ExtractorInformation.yml @@ -0,0 +1,5 @@ +extensions: + - addsTo: + pack: codeql/java-queries + extensible: extractorInformationSkipKey + data: [] diff --git a/java/ql/src/qlpack.yml b/java/ql/src/qlpack.yml index 6295db39e31..52ed9a30a2d 100644 --- a/java/ql/src/qlpack.yml +++ b/java/ql/src/qlpack.yml @@ -10,3 +10,5 @@ dependencies: codeql/java-all: ${workspace} codeql/suite-helpers: ${workspace} codeql/util: ${workspace} +dataExtensions: + - Telemetry/ExtractorInformation.yml From d4746e05083bbb265e50b7430e7073cdfc2da839 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen <mathiasvp@github.com> Date: Wed, 29 Mar 2023 13:58:24 +0100 Subject: [PATCH 604/631] C++: Add test with VLA. --- .../ir/ssa/aliased_ssa_consistency.expected | 1 + .../aliased_ssa_consistency_unsound.expected | 1 + .../ir/ssa/aliased_ssa_ir.expected | 17 +++++++++++++++++ .../ir/ssa/aliased_ssa_ir_unsound.expected | 17 +++++++++++++++++ cpp/ql/test/library-tests/ir/ssa/ssa.cpp | 16 ++++++++++++++++ .../ir/ssa/unaliased_ssa_consistency.expected | 1 + .../unaliased_ssa_consistency_unsound.expected | 1 + .../ir/ssa/unaliased_ssa_ir.expected | 16 ++++++++++++++++ .../ir/ssa/unaliased_ssa_ir_unsound.expected | 16 ++++++++++++++++ 9 files changed, 86 insertions(+) diff --git a/cpp/ql/test/library-tests/ir/ssa/aliased_ssa_consistency.expected b/cpp/ql/test/library-tests/ir/ssa/aliased_ssa_consistency.expected index 79887fffc1f..ac95c9c3437 100644 --- a/cpp/ql/test/library-tests/ir/ssa/aliased_ssa_consistency.expected +++ b/cpp/ql/test/library-tests/ir/ssa/aliased_ssa_consistency.expected @@ -6,6 +6,7 @@ missingOperandType duplicateChiOperand sideEffectWithoutPrimary instructionWithoutSuccessor +| ssa.cpp:402:7:402:7 | Uninitialized: definition of b | Instruction 'Uninitialized: definition of b' has no successors in function '$@'. | ssa.cpp:401:6:401:8 | void vla(int, int, int, bool) | void vla(int, int, int, bool) | ambiguousSuccessors unexplainedLoop unnecessaryPhiInstruction diff --git a/cpp/ql/test/library-tests/ir/ssa/aliased_ssa_consistency_unsound.expected b/cpp/ql/test/library-tests/ir/ssa/aliased_ssa_consistency_unsound.expected index 79887fffc1f..ac95c9c3437 100644 --- a/cpp/ql/test/library-tests/ir/ssa/aliased_ssa_consistency_unsound.expected +++ b/cpp/ql/test/library-tests/ir/ssa/aliased_ssa_consistency_unsound.expected @@ -6,6 +6,7 @@ missingOperandType duplicateChiOperand sideEffectWithoutPrimary instructionWithoutSuccessor +| ssa.cpp:402:7:402:7 | Uninitialized: definition of b | Instruction 'Uninitialized: definition of b' has no successors in function '$@'. | ssa.cpp:401:6:401:8 | void vla(int, int, int, bool) | void vla(int, int, int, bool) | ambiguousSuccessors unexplainedLoop unnecessaryPhiInstruction diff --git a/cpp/ql/test/library-tests/ir/ssa/aliased_ssa_ir.expected b/cpp/ql/test/library-tests/ir/ssa/aliased_ssa_ir.expected index 147c10b7c7f..282143c6bf6 100644 --- a/cpp/ql/test/library-tests/ir/ssa/aliased_ssa_ir.expected +++ b/cpp/ql/test/library-tests/ir/ssa/aliased_ssa_ir.expected @@ -1814,3 +1814,20 @@ ssa.cpp: # 383| Block 5 # 383| v383_17(void) = Unreached : + +# 401| void vla(int, int, int, bool) +# 401| Block 0 +# 401| v401_1(void) = EnterFunction : +# 401| m401_2(unknown) = AliasedDefinition : +# 401| m401_3(unknown) = InitializeNonLocal : +# 401| m401_4(unknown) = Chi : total:m401_2, partial:m401_3 +# 401| r401_5(glval<int>) = VariableAddress[n1] : +# 401| m401_6(int) = InitializeParameter[n1] : &:r401_5 +# 401| r401_7(glval<int>) = VariableAddress[n2] : +# 401| m401_8(int) = InitializeParameter[n2] : &:r401_7 +# 401| r401_9(glval<int>) = VariableAddress[n3] : +# 401| m401_10(int) = InitializeParameter[n3] : &:r401_9 +# 401| r401_11(glval<bool>) = VariableAddress[b1] : +# 401| m401_12(bool) = InitializeParameter[b1] : &:r401_11 +# 402| r402_1(glval<int[]>) = VariableAddress[b] : +# 402| m402_2(int[]) = Uninitialized[b] : &:r402_1 diff --git a/cpp/ql/test/library-tests/ir/ssa/aliased_ssa_ir_unsound.expected b/cpp/ql/test/library-tests/ir/ssa/aliased_ssa_ir_unsound.expected index 396b7532d68..ac58290efe7 100644 --- a/cpp/ql/test/library-tests/ir/ssa/aliased_ssa_ir_unsound.expected +++ b/cpp/ql/test/library-tests/ir/ssa/aliased_ssa_ir_unsound.expected @@ -1804,3 +1804,20 @@ ssa.cpp: # 383| Block 5 # 383| v383_17(void) = Unreached : + +# 401| void vla(int, int, int, bool) +# 401| Block 0 +# 401| v401_1(void) = EnterFunction : +# 401| m401_2(unknown) = AliasedDefinition : +# 401| m401_3(unknown) = InitializeNonLocal : +# 401| m401_4(unknown) = Chi : total:m401_2, partial:m401_3 +# 401| r401_5(glval<int>) = VariableAddress[n1] : +# 401| m401_6(int) = InitializeParameter[n1] : &:r401_5 +# 401| r401_7(glval<int>) = VariableAddress[n2] : +# 401| m401_8(int) = InitializeParameter[n2] : &:r401_7 +# 401| r401_9(glval<int>) = VariableAddress[n3] : +# 401| m401_10(int) = InitializeParameter[n3] : &:r401_9 +# 401| r401_11(glval<bool>) = VariableAddress[b1] : +# 401| m401_12(bool) = InitializeParameter[b1] : &:r401_11 +# 402| r402_1(glval<int[]>) = VariableAddress[b] : +# 402| m402_2(int[]) = Uninitialized[b] : &:r402_1 diff --git a/cpp/ql/test/library-tests/ir/ssa/ssa.cpp b/cpp/ql/test/library-tests/ir/ssa/ssa.cpp index ec8ea81e9e4..98c33c3eddf 100644 --- a/cpp/ql/test/library-tests/ir/ssa/ssa.cpp +++ b/cpp/ql/test/library-tests/ir/ssa/ssa.cpp @@ -396,4 +396,20 @@ int FusedBlockPhiOperand(int x, int y, int z, bool b1) { } return ret; +} + +void vla(int n1, int n2, int n3, bool b1) { + int b[n1]; + int c[n1][n2]; + + *b = 0; + b[0] = 1; + + **(c + 1) = 0; + + if(b1) { + int b[n1]; + } else { + int b[n2]; + } } \ No newline at end of file diff --git a/cpp/ql/test/library-tests/ir/ssa/unaliased_ssa_consistency.expected b/cpp/ql/test/library-tests/ir/ssa/unaliased_ssa_consistency.expected index 79887fffc1f..ac95c9c3437 100644 --- a/cpp/ql/test/library-tests/ir/ssa/unaliased_ssa_consistency.expected +++ b/cpp/ql/test/library-tests/ir/ssa/unaliased_ssa_consistency.expected @@ -6,6 +6,7 @@ missingOperandType duplicateChiOperand sideEffectWithoutPrimary instructionWithoutSuccessor +| ssa.cpp:402:7:402:7 | Uninitialized: definition of b | Instruction 'Uninitialized: definition of b' has no successors in function '$@'. | ssa.cpp:401:6:401:8 | void vla(int, int, int, bool) | void vla(int, int, int, bool) | ambiguousSuccessors unexplainedLoop unnecessaryPhiInstruction diff --git a/cpp/ql/test/library-tests/ir/ssa/unaliased_ssa_consistency_unsound.expected b/cpp/ql/test/library-tests/ir/ssa/unaliased_ssa_consistency_unsound.expected index 79887fffc1f..ac95c9c3437 100644 --- a/cpp/ql/test/library-tests/ir/ssa/unaliased_ssa_consistency_unsound.expected +++ b/cpp/ql/test/library-tests/ir/ssa/unaliased_ssa_consistency_unsound.expected @@ -6,6 +6,7 @@ missingOperandType duplicateChiOperand sideEffectWithoutPrimary instructionWithoutSuccessor +| ssa.cpp:402:7:402:7 | Uninitialized: definition of b | Instruction 'Uninitialized: definition of b' has no successors in function '$@'. | ssa.cpp:401:6:401:8 | void vla(int, int, int, bool) | void vla(int, int, int, bool) | ambiguousSuccessors unexplainedLoop unnecessaryPhiInstruction diff --git a/cpp/ql/test/library-tests/ir/ssa/unaliased_ssa_ir.expected b/cpp/ql/test/library-tests/ir/ssa/unaliased_ssa_ir.expected index 3fc07bf6950..17bfcb76146 100644 --- a/cpp/ql/test/library-tests/ir/ssa/unaliased_ssa_ir.expected +++ b/cpp/ql/test/library-tests/ir/ssa/unaliased_ssa_ir.expected @@ -1695,3 +1695,19 @@ ssa.cpp: # 383| v383_13(void) = ReturnValue : &:r383_12, m398_5 # 383| v383_14(void) = AliasedUse : ~m? # 383| v383_15(void) = ExitFunction : + +# 401| void vla(int, int, int, bool) +# 401| Block 0 +# 401| v401_1(void) = EnterFunction : +# 401| mu401_2(unknown) = AliasedDefinition : +# 401| mu401_3(unknown) = InitializeNonLocal : +# 401| r401_4(glval<int>) = VariableAddress[n1] : +# 401| m401_5(int) = InitializeParameter[n1] : &:r401_4 +# 401| r401_6(glval<int>) = VariableAddress[n2] : +# 401| m401_7(int) = InitializeParameter[n2] : &:r401_6 +# 401| r401_8(glval<int>) = VariableAddress[n3] : +# 401| m401_9(int) = InitializeParameter[n3] : &:r401_8 +# 401| r401_10(glval<bool>) = VariableAddress[b1] : +# 401| m401_11(bool) = InitializeParameter[b1] : &:r401_10 +# 402| r402_1(glval<int[]>) = VariableAddress[b] : +# 402| mu402_2(int[]) = Uninitialized[b] : &:r402_1 diff --git a/cpp/ql/test/library-tests/ir/ssa/unaliased_ssa_ir_unsound.expected b/cpp/ql/test/library-tests/ir/ssa/unaliased_ssa_ir_unsound.expected index 3fc07bf6950..17bfcb76146 100644 --- a/cpp/ql/test/library-tests/ir/ssa/unaliased_ssa_ir_unsound.expected +++ b/cpp/ql/test/library-tests/ir/ssa/unaliased_ssa_ir_unsound.expected @@ -1695,3 +1695,19 @@ ssa.cpp: # 383| v383_13(void) = ReturnValue : &:r383_12, m398_5 # 383| v383_14(void) = AliasedUse : ~m? # 383| v383_15(void) = ExitFunction : + +# 401| void vla(int, int, int, bool) +# 401| Block 0 +# 401| v401_1(void) = EnterFunction : +# 401| mu401_2(unknown) = AliasedDefinition : +# 401| mu401_3(unknown) = InitializeNonLocal : +# 401| r401_4(glval<int>) = VariableAddress[n1] : +# 401| m401_5(int) = InitializeParameter[n1] : &:r401_4 +# 401| r401_6(glval<int>) = VariableAddress[n2] : +# 401| m401_7(int) = InitializeParameter[n2] : &:r401_6 +# 401| r401_8(glval<int>) = VariableAddress[n3] : +# 401| m401_9(int) = InitializeParameter[n3] : &:r401_8 +# 401| r401_10(glval<bool>) = VariableAddress[b1] : +# 401| m401_11(bool) = InitializeParameter[b1] : &:r401_10 +# 402| r402_1(glval<int[]>) = VariableAddress[b] : +# 402| mu402_2(int[]) = Uninitialized[b] : &:r402_1 From fb6e45b6f42bc5fe2b292209eb286df00d57efb0 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen <mathiasvp@github.com> Date: Wed, 29 Mar 2023 13:58:39 +0100 Subject: [PATCH 605/631] C++: Emit a NoOp during CFG construction for VLAs. --- .../raw/internal/TranslatedStmt.qll | 46 +++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedStmt.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedStmt.qll index da4183ca25c..064425476f7 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedStmt.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedStmt.qll @@ -1105,3 +1105,49 @@ class TranslatedAsmStmt extends TranslatedStmt { ) } } + +class TranslatedVlaDimensionStmt extends TranslatedStmt { + override VlaDimensionStmt stmt; + + override TranslatedExpr getChild(int id) { + id = 0 and + result = getTranslatedExpr(stmt.getDimensionExpr().getFullyConverted()) + } + + override Instruction getFirstInstruction() { result = getChild(0).getFirstInstruction() } + + override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) { + none() + } + + override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) { none() } + + override Instruction getChildSuccessor(TranslatedElement child) { + child = getChild(0) and + result = getParent().getChildSuccessor(this) + } +} + +class TranslatedVlaDeclarationStmt extends TranslatedStmt { + override VlaDeclStmt stmt; + + override TranslatedExpr getChild(int id) { none() } + + override Instruction getFirstInstruction() { result = getInstruction(OnlyInstructionTag()) } + + override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) { + // TODO: This needs a new kind of instruction that represents initialization of a VLA. + // For now we just emit a `NoOp` instruction so that the CFG isn't incomplete. + tag = OnlyInstructionTag() and + opcode instanceof Opcode::NoOp and + resultType = getVoidType() + } + + override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) { + tag = OnlyInstructionTag() and + result = getParent().getChildSuccessor(this) and + kind instanceof GotoEdge + } + + override Instruction getChildSuccessor(TranslatedElement child) { none() } +} From 0e9ed989e0ff57aea2d554e1c7fa8354d48ddc34 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen <mathiasvp@github.com> Date: Wed, 29 Mar 2023 14:01:01 +0100 Subject: [PATCH 606/631] C++: Accept test changes. --- .../ir/ssa/aliased_ssa_consistency.expected | 1 - .../aliased_ssa_consistency_unsound.expected | 1 - .../ir/ssa/aliased_ssa_ir.expected | 89 ++++++++++++++++--- .../ir/ssa/aliased_ssa_ir_unsound.expected | 88 +++++++++++++++--- .../ir/ssa/unaliased_ssa_consistency.expected | 1 - ...unaliased_ssa_consistency_unsound.expected | 1 - .../ir/ssa/unaliased_ssa_ir.expected | 83 ++++++++++++++--- .../ir/ssa/unaliased_ssa_ir_unsound.expected | 83 ++++++++++++++--- 8 files changed, 289 insertions(+), 58 deletions(-) diff --git a/cpp/ql/test/library-tests/ir/ssa/aliased_ssa_consistency.expected b/cpp/ql/test/library-tests/ir/ssa/aliased_ssa_consistency.expected index ac95c9c3437..79887fffc1f 100644 --- a/cpp/ql/test/library-tests/ir/ssa/aliased_ssa_consistency.expected +++ b/cpp/ql/test/library-tests/ir/ssa/aliased_ssa_consistency.expected @@ -6,7 +6,6 @@ missingOperandType duplicateChiOperand sideEffectWithoutPrimary instructionWithoutSuccessor -| ssa.cpp:402:7:402:7 | Uninitialized: definition of b | Instruction 'Uninitialized: definition of b' has no successors in function '$@'. | ssa.cpp:401:6:401:8 | void vla(int, int, int, bool) | void vla(int, int, int, bool) | ambiguousSuccessors unexplainedLoop unnecessaryPhiInstruction diff --git a/cpp/ql/test/library-tests/ir/ssa/aliased_ssa_consistency_unsound.expected b/cpp/ql/test/library-tests/ir/ssa/aliased_ssa_consistency_unsound.expected index ac95c9c3437..79887fffc1f 100644 --- a/cpp/ql/test/library-tests/ir/ssa/aliased_ssa_consistency_unsound.expected +++ b/cpp/ql/test/library-tests/ir/ssa/aliased_ssa_consistency_unsound.expected @@ -6,7 +6,6 @@ missingOperandType duplicateChiOperand sideEffectWithoutPrimary instructionWithoutSuccessor -| ssa.cpp:402:7:402:7 | Uninitialized: definition of b | Instruction 'Uninitialized: definition of b' has no successors in function '$@'. | ssa.cpp:401:6:401:8 | void vla(int, int, int, bool) | void vla(int, int, int, bool) | ambiguousSuccessors unexplainedLoop unnecessaryPhiInstruction diff --git a/cpp/ql/test/library-tests/ir/ssa/aliased_ssa_ir.expected b/cpp/ql/test/library-tests/ir/ssa/aliased_ssa_ir.expected index 282143c6bf6..7f76af075a7 100644 --- a/cpp/ql/test/library-tests/ir/ssa/aliased_ssa_ir.expected +++ b/cpp/ql/test/library-tests/ir/ssa/aliased_ssa_ir.expected @@ -1817,17 +1817,78 @@ ssa.cpp: # 401| void vla(int, int, int, bool) # 401| Block 0 -# 401| v401_1(void) = EnterFunction : -# 401| m401_2(unknown) = AliasedDefinition : -# 401| m401_3(unknown) = InitializeNonLocal : -# 401| m401_4(unknown) = Chi : total:m401_2, partial:m401_3 -# 401| r401_5(glval<int>) = VariableAddress[n1] : -# 401| m401_6(int) = InitializeParameter[n1] : &:r401_5 -# 401| r401_7(glval<int>) = VariableAddress[n2] : -# 401| m401_8(int) = InitializeParameter[n2] : &:r401_7 -# 401| r401_9(glval<int>) = VariableAddress[n3] : -# 401| m401_10(int) = InitializeParameter[n3] : &:r401_9 -# 401| r401_11(glval<bool>) = VariableAddress[b1] : -# 401| m401_12(bool) = InitializeParameter[b1] : &:r401_11 -# 402| r402_1(glval<int[]>) = VariableAddress[b] : -# 402| m402_2(int[]) = Uninitialized[b] : &:r402_1 +# 401| v401_1(void) = EnterFunction : +# 401| m401_2(unknown) = AliasedDefinition : +# 401| m401_3(unknown) = InitializeNonLocal : +# 401| m401_4(unknown) = Chi : total:m401_2, partial:m401_3 +# 401| r401_5(glval<int>) = VariableAddress[n1] : +# 401| m401_6(int) = InitializeParameter[n1] : &:r401_5 +# 401| r401_7(glval<int>) = VariableAddress[n2] : +# 401| m401_8(int) = InitializeParameter[n2] : &:r401_7 +# 401| r401_9(glval<int>) = VariableAddress[n3] : +# 401| m401_10(int) = InitializeParameter[n3] : &:r401_9 +# 401| r401_11(glval<bool>) = VariableAddress[b1] : +# 401| m401_12(bool) = InitializeParameter[b1] : &:r401_11 +# 402| r402_1(glval<int[]>) = VariableAddress[b] : +# 402| m402_2(int[]) = Uninitialized[b] : &:r402_1 +# 402| r402_3(glval<int>) = VariableAddress[n1] : +# 402| r402_4(int) = Load[n1] : &:r402_3, m401_6 +# 402| v402_5(void) = NoOp : +# 403| r403_1(glval<int[][]>) = VariableAddress[c] : +# 403| m403_2(int[][]) = Uninitialized[c] : &:r403_1 +# 403| m403_3(unknown) = Chi : total:m401_4, partial:m403_2 +# 403| r403_4(glval<int>) = VariableAddress[n1] : +# 403| r403_5(int) = Load[n1] : &:r403_4, m401_6 +# 403| r403_6(glval<int>) = VariableAddress[n2] : +# 403| r403_7(int) = Load[n2] : &:r403_6, m401_8 +# 403| v403_8(void) = NoOp : +# 405| r405_1(int) = Constant[0] : +# 405| r405_2(glval<int[]>) = VariableAddress[b] : +# 405| r405_3(int *) = Convert : r405_2 +# 405| r405_4(glval<int>) = CopyValue : r405_3 +# 405| m405_5(int) = Store[?] : &:r405_4, r405_1 +# 405| m405_6(int[]) = Chi : total:m402_2, partial:m405_5 +# 406| r406_1(int) = Constant[1] : +# 406| r406_2(glval<int[]>) = VariableAddress[b] : +# 406| r406_3(int *) = Convert : r406_2 +# 406| r406_4(int) = Constant[0] : +# 406| r406_5(glval<int>) = PointerAdd[4] : r406_3, r406_4 +# 406| m406_6(int) = Store[?] : &:r406_5, r406_1 +# 406| m406_7(int[]) = Chi : total:m405_6, partial:m406_6 +# 408| r408_1(int) = Constant[0] : +# 408| r408_2(glval<int[][]>) = VariableAddress[c] : +# 408| r408_3(int(*)[]) = Convert : r408_2 +# 408| r408_4(int) = Constant[1] : +# 408| r408_5(int(*)[]) = PointerAdd : r408_3, r408_4 +# 408| r408_6(glval<int[]>) = CopyValue : r408_5 +# 408| r408_7(int *) = Convert : r408_6 +# 408| r408_8(glval<int>) = CopyValue : r408_7 +# 408| m408_9(int) = Store[?] : &:r408_8, r408_1 +# 408| m408_10(unknown) = Chi : total:m403_3, partial:m408_9 +# 410| r410_1(glval<bool>) = VariableAddress[b1] : +# 410| r410_2(bool) = Load[b1] : &:r410_1, m401_12 +# 410| v410_3(void) = ConditionalBranch : r410_2 +#-----| False -> Block 2 +#-----| True -> Block 1 + +# 411| Block 1 +# 411| r411_1(glval<int[]>) = VariableAddress[b] : +# 411| m411_2(int[]) = Uninitialized[b] : &:r411_1 +# 411| r411_3(glval<int>) = VariableAddress[n1] : +# 411| r411_4(int) = Load[n1] : &:r411_3, m401_6 +# 411| v411_5(void) = NoOp : +#-----| Goto -> Block 3 + +# 413| Block 2 +# 413| r413_1(glval<int[]>) = VariableAddress[b] : +# 413| m413_2(int[]) = Uninitialized[b] : &:r413_1 +# 413| r413_3(glval<int>) = VariableAddress[n2] : +# 413| r413_4(int) = Load[n2] : &:r413_3, m401_8 +# 413| v413_5(void) = NoOp : +#-----| Goto -> Block 3 + +# 415| Block 3 +# 415| v415_1(void) = NoOp : +# 401| v401_13(void) = ReturnVoid : +# 401| v401_14(void) = AliasedUse : ~m408_10 +# 401| v401_15(void) = ExitFunction : diff --git a/cpp/ql/test/library-tests/ir/ssa/aliased_ssa_ir_unsound.expected b/cpp/ql/test/library-tests/ir/ssa/aliased_ssa_ir_unsound.expected index ac58290efe7..1ad86dc0da0 100644 --- a/cpp/ql/test/library-tests/ir/ssa/aliased_ssa_ir_unsound.expected +++ b/cpp/ql/test/library-tests/ir/ssa/aliased_ssa_ir_unsound.expected @@ -1807,17 +1807,77 @@ ssa.cpp: # 401| void vla(int, int, int, bool) # 401| Block 0 -# 401| v401_1(void) = EnterFunction : -# 401| m401_2(unknown) = AliasedDefinition : -# 401| m401_3(unknown) = InitializeNonLocal : -# 401| m401_4(unknown) = Chi : total:m401_2, partial:m401_3 -# 401| r401_5(glval<int>) = VariableAddress[n1] : -# 401| m401_6(int) = InitializeParameter[n1] : &:r401_5 -# 401| r401_7(glval<int>) = VariableAddress[n2] : -# 401| m401_8(int) = InitializeParameter[n2] : &:r401_7 -# 401| r401_9(glval<int>) = VariableAddress[n3] : -# 401| m401_10(int) = InitializeParameter[n3] : &:r401_9 -# 401| r401_11(glval<bool>) = VariableAddress[b1] : -# 401| m401_12(bool) = InitializeParameter[b1] : &:r401_11 -# 402| r402_1(glval<int[]>) = VariableAddress[b] : -# 402| m402_2(int[]) = Uninitialized[b] : &:r402_1 +# 401| v401_1(void) = EnterFunction : +# 401| m401_2(unknown) = AliasedDefinition : +# 401| m401_3(unknown) = InitializeNonLocal : +# 401| m401_4(unknown) = Chi : total:m401_2, partial:m401_3 +# 401| r401_5(glval<int>) = VariableAddress[n1] : +# 401| m401_6(int) = InitializeParameter[n1] : &:r401_5 +# 401| r401_7(glval<int>) = VariableAddress[n2] : +# 401| m401_8(int) = InitializeParameter[n2] : &:r401_7 +# 401| r401_9(glval<int>) = VariableAddress[n3] : +# 401| m401_10(int) = InitializeParameter[n3] : &:r401_9 +# 401| r401_11(glval<bool>) = VariableAddress[b1] : +# 401| m401_12(bool) = InitializeParameter[b1] : &:r401_11 +# 402| r402_1(glval<int[]>) = VariableAddress[b] : +# 402| m402_2(int[]) = Uninitialized[b] : &:r402_1 +# 402| r402_3(glval<int>) = VariableAddress[n1] : +# 402| r402_4(int) = Load[n1] : &:r402_3, m401_6 +# 402| v402_5(void) = NoOp : +# 403| r403_1(glval<int[][]>) = VariableAddress[c] : +# 403| m403_2(int[][]) = Uninitialized[c] : &:r403_1 +# 403| r403_3(glval<int>) = VariableAddress[n1] : +# 403| r403_4(int) = Load[n1] : &:r403_3, m401_6 +# 403| r403_5(glval<int>) = VariableAddress[n2] : +# 403| r403_6(int) = Load[n2] : &:r403_5, m401_8 +# 403| v403_7(void) = NoOp : +# 405| r405_1(int) = Constant[0] : +# 405| r405_2(glval<int[]>) = VariableAddress[b] : +# 405| r405_3(int *) = Convert : r405_2 +# 405| r405_4(glval<int>) = CopyValue : r405_3 +# 405| m405_5(int) = Store[?] : &:r405_4, r405_1 +# 405| m405_6(int[]) = Chi : total:m402_2, partial:m405_5 +# 406| r406_1(int) = Constant[1] : +# 406| r406_2(glval<int[]>) = VariableAddress[b] : +# 406| r406_3(int *) = Convert : r406_2 +# 406| r406_4(int) = Constant[0] : +# 406| r406_5(glval<int>) = PointerAdd[4] : r406_3, r406_4 +# 406| m406_6(int) = Store[?] : &:r406_5, r406_1 +# 406| m406_7(int[]) = Chi : total:m405_6, partial:m406_6 +# 408| r408_1(int) = Constant[0] : +# 408| r408_2(glval<int[][]>) = VariableAddress[c] : +# 408| r408_3(int(*)[]) = Convert : r408_2 +# 408| r408_4(int) = Constant[1] : +# 408| r408_5(int(*)[]) = PointerAdd : r408_3, r408_4 +# 408| r408_6(glval<int[]>) = CopyValue : r408_5 +# 408| r408_7(int *) = Convert : r408_6 +# 408| r408_8(glval<int>) = CopyValue : r408_7 +# 408| m408_9(int) = Store[?] : &:r408_8, r408_1 +# 408| m408_10(unknown) = Chi : total:m401_4, partial:m408_9 +# 410| r410_1(glval<bool>) = VariableAddress[b1] : +# 410| r410_2(bool) = Load[b1] : &:r410_1, m401_12 +# 410| v410_3(void) = ConditionalBranch : r410_2 +#-----| False -> Block 2 +#-----| True -> Block 1 + +# 411| Block 1 +# 411| r411_1(glval<int[]>) = VariableAddress[b] : +# 411| m411_2(int[]) = Uninitialized[b] : &:r411_1 +# 411| r411_3(glval<int>) = VariableAddress[n1] : +# 411| r411_4(int) = Load[n1] : &:r411_3, m401_6 +# 411| v411_5(void) = NoOp : +#-----| Goto -> Block 3 + +# 413| Block 2 +# 413| r413_1(glval<int[]>) = VariableAddress[b] : +# 413| m413_2(int[]) = Uninitialized[b] : &:r413_1 +# 413| r413_3(glval<int>) = VariableAddress[n2] : +# 413| r413_4(int) = Load[n2] : &:r413_3, m401_8 +# 413| v413_5(void) = NoOp : +#-----| Goto -> Block 3 + +# 415| Block 3 +# 415| v415_1(void) = NoOp : +# 401| v401_13(void) = ReturnVoid : +# 401| v401_14(void) = AliasedUse : ~m408_10 +# 401| v401_15(void) = ExitFunction : diff --git a/cpp/ql/test/library-tests/ir/ssa/unaliased_ssa_consistency.expected b/cpp/ql/test/library-tests/ir/ssa/unaliased_ssa_consistency.expected index ac95c9c3437..79887fffc1f 100644 --- a/cpp/ql/test/library-tests/ir/ssa/unaliased_ssa_consistency.expected +++ b/cpp/ql/test/library-tests/ir/ssa/unaliased_ssa_consistency.expected @@ -6,7 +6,6 @@ missingOperandType duplicateChiOperand sideEffectWithoutPrimary instructionWithoutSuccessor -| ssa.cpp:402:7:402:7 | Uninitialized: definition of b | Instruction 'Uninitialized: definition of b' has no successors in function '$@'. | ssa.cpp:401:6:401:8 | void vla(int, int, int, bool) | void vla(int, int, int, bool) | ambiguousSuccessors unexplainedLoop unnecessaryPhiInstruction diff --git a/cpp/ql/test/library-tests/ir/ssa/unaliased_ssa_consistency_unsound.expected b/cpp/ql/test/library-tests/ir/ssa/unaliased_ssa_consistency_unsound.expected index ac95c9c3437..79887fffc1f 100644 --- a/cpp/ql/test/library-tests/ir/ssa/unaliased_ssa_consistency_unsound.expected +++ b/cpp/ql/test/library-tests/ir/ssa/unaliased_ssa_consistency_unsound.expected @@ -6,7 +6,6 @@ missingOperandType duplicateChiOperand sideEffectWithoutPrimary instructionWithoutSuccessor -| ssa.cpp:402:7:402:7 | Uninitialized: definition of b | Instruction 'Uninitialized: definition of b' has no successors in function '$@'. | ssa.cpp:401:6:401:8 | void vla(int, int, int, bool) | void vla(int, int, int, bool) | ambiguousSuccessors unexplainedLoop unnecessaryPhiInstruction diff --git a/cpp/ql/test/library-tests/ir/ssa/unaliased_ssa_ir.expected b/cpp/ql/test/library-tests/ir/ssa/unaliased_ssa_ir.expected index 17bfcb76146..03de47a1ab0 100644 --- a/cpp/ql/test/library-tests/ir/ssa/unaliased_ssa_ir.expected +++ b/cpp/ql/test/library-tests/ir/ssa/unaliased_ssa_ir.expected @@ -1698,16 +1698,73 @@ ssa.cpp: # 401| void vla(int, int, int, bool) # 401| Block 0 -# 401| v401_1(void) = EnterFunction : -# 401| mu401_2(unknown) = AliasedDefinition : -# 401| mu401_3(unknown) = InitializeNonLocal : -# 401| r401_4(glval<int>) = VariableAddress[n1] : -# 401| m401_5(int) = InitializeParameter[n1] : &:r401_4 -# 401| r401_6(glval<int>) = VariableAddress[n2] : -# 401| m401_7(int) = InitializeParameter[n2] : &:r401_6 -# 401| r401_8(glval<int>) = VariableAddress[n3] : -# 401| m401_9(int) = InitializeParameter[n3] : &:r401_8 -# 401| r401_10(glval<bool>) = VariableAddress[b1] : -# 401| m401_11(bool) = InitializeParameter[b1] : &:r401_10 -# 402| r402_1(glval<int[]>) = VariableAddress[b] : -# 402| mu402_2(int[]) = Uninitialized[b] : &:r402_1 +# 401| v401_1(void) = EnterFunction : +# 401| mu401_2(unknown) = AliasedDefinition : +# 401| mu401_3(unknown) = InitializeNonLocal : +# 401| r401_4(glval<int>) = VariableAddress[n1] : +# 401| m401_5(int) = InitializeParameter[n1] : &:r401_4 +# 401| r401_6(glval<int>) = VariableAddress[n2] : +# 401| m401_7(int) = InitializeParameter[n2] : &:r401_6 +# 401| r401_8(glval<int>) = VariableAddress[n3] : +# 401| m401_9(int) = InitializeParameter[n3] : &:r401_8 +# 401| r401_10(glval<bool>) = VariableAddress[b1] : +# 401| m401_11(bool) = InitializeParameter[b1] : &:r401_10 +# 402| r402_1(glval<int[]>) = VariableAddress[b] : +# 402| mu402_2(int[]) = Uninitialized[b] : &:r402_1 +# 402| r402_3(glval<int>) = VariableAddress[n1] : +# 402| r402_4(int) = Load[n1] : &:r402_3, m401_5 +# 402| v402_5(void) = NoOp : +# 403| r403_1(glval<int[][]>) = VariableAddress[c] : +# 403| mu403_2(int[][]) = Uninitialized[c] : &:r403_1 +# 403| r403_3(glval<int>) = VariableAddress[n1] : +# 403| r403_4(int) = Load[n1] : &:r403_3, m401_5 +# 403| r403_5(glval<int>) = VariableAddress[n2] : +# 403| r403_6(int) = Load[n2] : &:r403_5, m401_7 +# 403| v403_7(void) = NoOp : +# 405| r405_1(int) = Constant[0] : +# 405| r405_2(glval<int[]>) = VariableAddress[b] : +# 405| r405_3(int *) = Convert : r405_2 +# 405| r405_4(glval<int>) = CopyValue : r405_3 +# 405| mu405_5(int) = Store[?] : &:r405_4, r405_1 +# 406| r406_1(int) = Constant[1] : +# 406| r406_2(glval<int[]>) = VariableAddress[b] : +# 406| r406_3(int *) = Convert : r406_2 +# 406| r406_4(int) = Constant[0] : +# 406| r406_5(glval<int>) = PointerAdd[4] : r406_3, r406_4 +# 406| mu406_6(int) = Store[?] : &:r406_5, r406_1 +# 408| r408_1(int) = Constant[0] : +# 408| r408_2(glval<int[][]>) = VariableAddress[c] : +# 408| r408_3(int(*)[]) = Convert : r408_2 +# 408| r408_4(int) = Constant[1] : +# 408| r408_5(int(*)[]) = PointerAdd : r408_3, r408_4 +# 408| r408_6(glval<int[]>) = CopyValue : r408_5 +# 408| r408_7(int *) = Convert : r408_6 +# 408| r408_8(glval<int>) = CopyValue : r408_7 +# 408| mu408_9(int) = Store[?] : &:r408_8, r408_1 +# 410| r410_1(glval<bool>) = VariableAddress[b1] : +# 410| r410_2(bool) = Load[b1] : &:r410_1, m401_11 +# 410| v410_3(void) = ConditionalBranch : r410_2 +#-----| False -> Block 2 +#-----| True -> Block 1 + +# 411| Block 1 +# 411| r411_1(glval<int[]>) = VariableAddress[b] : +# 411| m411_2(int[]) = Uninitialized[b] : &:r411_1 +# 411| r411_3(glval<int>) = VariableAddress[n1] : +# 411| r411_4(int) = Load[n1] : &:r411_3, m401_5 +# 411| v411_5(void) = NoOp : +#-----| Goto -> Block 3 + +# 413| Block 2 +# 413| r413_1(glval<int[]>) = VariableAddress[b] : +# 413| m413_2(int[]) = Uninitialized[b] : &:r413_1 +# 413| r413_3(glval<int>) = VariableAddress[n2] : +# 413| r413_4(int) = Load[n2] : &:r413_3, m401_7 +# 413| v413_5(void) = NoOp : +#-----| Goto -> Block 3 + +# 415| Block 3 +# 415| v415_1(void) = NoOp : +# 401| v401_12(void) = ReturnVoid : +# 401| v401_13(void) = AliasedUse : ~m? +# 401| v401_14(void) = ExitFunction : diff --git a/cpp/ql/test/library-tests/ir/ssa/unaliased_ssa_ir_unsound.expected b/cpp/ql/test/library-tests/ir/ssa/unaliased_ssa_ir_unsound.expected index 17bfcb76146..03de47a1ab0 100644 --- a/cpp/ql/test/library-tests/ir/ssa/unaliased_ssa_ir_unsound.expected +++ b/cpp/ql/test/library-tests/ir/ssa/unaliased_ssa_ir_unsound.expected @@ -1698,16 +1698,73 @@ ssa.cpp: # 401| void vla(int, int, int, bool) # 401| Block 0 -# 401| v401_1(void) = EnterFunction : -# 401| mu401_2(unknown) = AliasedDefinition : -# 401| mu401_3(unknown) = InitializeNonLocal : -# 401| r401_4(glval<int>) = VariableAddress[n1] : -# 401| m401_5(int) = InitializeParameter[n1] : &:r401_4 -# 401| r401_6(glval<int>) = VariableAddress[n2] : -# 401| m401_7(int) = InitializeParameter[n2] : &:r401_6 -# 401| r401_8(glval<int>) = VariableAddress[n3] : -# 401| m401_9(int) = InitializeParameter[n3] : &:r401_8 -# 401| r401_10(glval<bool>) = VariableAddress[b1] : -# 401| m401_11(bool) = InitializeParameter[b1] : &:r401_10 -# 402| r402_1(glval<int[]>) = VariableAddress[b] : -# 402| mu402_2(int[]) = Uninitialized[b] : &:r402_1 +# 401| v401_1(void) = EnterFunction : +# 401| mu401_2(unknown) = AliasedDefinition : +# 401| mu401_3(unknown) = InitializeNonLocal : +# 401| r401_4(glval<int>) = VariableAddress[n1] : +# 401| m401_5(int) = InitializeParameter[n1] : &:r401_4 +# 401| r401_6(glval<int>) = VariableAddress[n2] : +# 401| m401_7(int) = InitializeParameter[n2] : &:r401_6 +# 401| r401_8(glval<int>) = VariableAddress[n3] : +# 401| m401_9(int) = InitializeParameter[n3] : &:r401_8 +# 401| r401_10(glval<bool>) = VariableAddress[b1] : +# 401| m401_11(bool) = InitializeParameter[b1] : &:r401_10 +# 402| r402_1(glval<int[]>) = VariableAddress[b] : +# 402| mu402_2(int[]) = Uninitialized[b] : &:r402_1 +# 402| r402_3(glval<int>) = VariableAddress[n1] : +# 402| r402_4(int) = Load[n1] : &:r402_3, m401_5 +# 402| v402_5(void) = NoOp : +# 403| r403_1(glval<int[][]>) = VariableAddress[c] : +# 403| mu403_2(int[][]) = Uninitialized[c] : &:r403_1 +# 403| r403_3(glval<int>) = VariableAddress[n1] : +# 403| r403_4(int) = Load[n1] : &:r403_3, m401_5 +# 403| r403_5(glval<int>) = VariableAddress[n2] : +# 403| r403_6(int) = Load[n2] : &:r403_5, m401_7 +# 403| v403_7(void) = NoOp : +# 405| r405_1(int) = Constant[0] : +# 405| r405_2(glval<int[]>) = VariableAddress[b] : +# 405| r405_3(int *) = Convert : r405_2 +# 405| r405_4(glval<int>) = CopyValue : r405_3 +# 405| mu405_5(int) = Store[?] : &:r405_4, r405_1 +# 406| r406_1(int) = Constant[1] : +# 406| r406_2(glval<int[]>) = VariableAddress[b] : +# 406| r406_3(int *) = Convert : r406_2 +# 406| r406_4(int) = Constant[0] : +# 406| r406_5(glval<int>) = PointerAdd[4] : r406_3, r406_4 +# 406| mu406_6(int) = Store[?] : &:r406_5, r406_1 +# 408| r408_1(int) = Constant[0] : +# 408| r408_2(glval<int[][]>) = VariableAddress[c] : +# 408| r408_3(int(*)[]) = Convert : r408_2 +# 408| r408_4(int) = Constant[1] : +# 408| r408_5(int(*)[]) = PointerAdd : r408_3, r408_4 +# 408| r408_6(glval<int[]>) = CopyValue : r408_5 +# 408| r408_7(int *) = Convert : r408_6 +# 408| r408_8(glval<int>) = CopyValue : r408_7 +# 408| mu408_9(int) = Store[?] : &:r408_8, r408_1 +# 410| r410_1(glval<bool>) = VariableAddress[b1] : +# 410| r410_2(bool) = Load[b1] : &:r410_1, m401_11 +# 410| v410_3(void) = ConditionalBranch : r410_2 +#-----| False -> Block 2 +#-----| True -> Block 1 + +# 411| Block 1 +# 411| r411_1(glval<int[]>) = VariableAddress[b] : +# 411| m411_2(int[]) = Uninitialized[b] : &:r411_1 +# 411| r411_3(glval<int>) = VariableAddress[n1] : +# 411| r411_4(int) = Load[n1] : &:r411_3, m401_5 +# 411| v411_5(void) = NoOp : +#-----| Goto -> Block 3 + +# 413| Block 2 +# 413| r413_1(glval<int[]>) = VariableAddress[b] : +# 413| m413_2(int[]) = Uninitialized[b] : &:r413_1 +# 413| r413_3(glval<int>) = VariableAddress[n2] : +# 413| r413_4(int) = Load[n2] : &:r413_3, m401_7 +# 413| v413_5(void) = NoOp : +#-----| Goto -> Block 3 + +# 415| Block 3 +# 415| v415_1(void) = NoOp : +# 401| v401_12(void) = ReturnVoid : +# 401| v401_13(void) = AliasedUse : ~m? +# 401| v401_14(void) = ExitFunction : From 3bd193f721b07b2ddee5a4eb4b5ad57d937bab57 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen <mathiasvp@github.com> Date: Wed, 29 Mar 2023 14:02:34 +0100 Subject: [PATCH 607/631] C++: Fix Code Scanning errors. --- .../ir/implementation/raw/internal/TranslatedStmt.qll | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedStmt.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedStmt.qll index 064425476f7..f0d8e5d3d35 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedStmt.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedStmt.qll @@ -1114,7 +1114,7 @@ class TranslatedVlaDimensionStmt extends TranslatedStmt { result = getTranslatedExpr(stmt.getDimensionExpr().getFullyConverted()) } - override Instruction getFirstInstruction() { result = getChild(0).getFirstInstruction() } + override Instruction getFirstInstruction() { result = this.getChild(0).getFirstInstruction() } override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) { none() @@ -1123,8 +1123,8 @@ class TranslatedVlaDimensionStmt extends TranslatedStmt { override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) { none() } override Instruction getChildSuccessor(TranslatedElement child) { - child = getChild(0) and - result = getParent().getChildSuccessor(this) + child = this.getChild(0) and + result = this.getParent().getChildSuccessor(this) } } @@ -1133,7 +1133,7 @@ class TranslatedVlaDeclarationStmt extends TranslatedStmt { override TranslatedExpr getChild(int id) { none() } - override Instruction getFirstInstruction() { result = getInstruction(OnlyInstructionTag()) } + override Instruction getFirstInstruction() { result = this.getInstruction(OnlyInstructionTag()) } override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) { // TODO: This needs a new kind of instruction that represents initialization of a VLA. @@ -1145,7 +1145,7 @@ class TranslatedVlaDeclarationStmt extends TranslatedStmt { override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) { tag = OnlyInstructionTag() and - result = getParent().getChildSuccessor(this) and + result = this.getParent().getChildSuccessor(this) and kind instanceof GotoEdge } From 4d8159c581f85424f1ab07adebf51731e1d82a1a Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen <mathiasvp@github.com> Date: Tue, 28 Mar 2023 16:58:37 +0100 Subject: [PATCH 608/631] C++: Disable rounding. --- .../semmle/code/cpp/semantic/analysis/FloatDelta.qll | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/cpp/ql/lib/experimental/semmle/code/cpp/semantic/analysis/FloatDelta.qll b/cpp/ql/lib/experimental/semmle/code/cpp/semantic/analysis/FloatDelta.qll index b55eec5e5ad..1dfcc445208 100644 --- a/cpp/ql/lib/experimental/semmle/code/cpp/semantic/analysis/FloatDelta.qll +++ b/cpp/ql/lib/experimental/semmle/code/cpp/semantic/analysis/FloatDelta.qll @@ -16,14 +16,5 @@ module FloatDelta implements DeltaSig { Delta fromInt(int n) { result = n } bindingset[f] - Delta fromFloat(float f) { - result = - min(float diff, float res | - diff = (res - f) and res = f.ceil() - or - diff = (f - res) and res = f.floor() - | - res order by diff - ) - } + Delta fromFloat(float f) { result = f } } From a2c0e3606228876f87edab487422896d7daf2b91 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen <mathiasvp@github.com> Date: Wed, 29 Mar 2023 14:25:05 +0100 Subject: [PATCH 609/631] C++: Accept test changes. --- .../ir/range-analysis/SimpleRangeAnalysis_tests.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpp/ql/test/library-tests/ir/range-analysis/SimpleRangeAnalysis_tests.cpp b/cpp/ql/test/library-tests/ir/range-analysis/SimpleRangeAnalysis_tests.cpp index 484c4954548..f71b7c86e52 100644 --- a/cpp/ql/test/library-tests/ir/range-analysis/SimpleRangeAnalysis_tests.cpp +++ b/cpp/ql/test/library-tests/ir/range-analysis/SimpleRangeAnalysis_tests.cpp @@ -741,7 +741,7 @@ unsigned long mult_rounding() { range(y); // $ range===1000000003 range(x); // $ range===1000000003 xy = x * y; - range(xy); // $ range===2147483647 + range(xy); return xy; // BUG: upper bound should be >= 1000000006000000009UL } From 27d8f98418cc1e2565c72d30309756b44f7b085c Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen <mathiasvp@github.com> Date: Wed, 29 Mar 2023 14:27:37 +0100 Subject: [PATCH 610/631] C++: Replace 'int' with 'float' in tests and accept test changes. --- .../test/library-tests/ir/range-analysis/RangeAnalysis.ql | 6 +++--- .../ir/range-analysis/SimpleRangeAnalysis_tests.cpp | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/cpp/ql/test/library-tests/ir/range-analysis/RangeAnalysis.ql b/cpp/ql/test/library-tests/ir/range-analysis/RangeAnalysis.ql index d3e44c868cf..378ce56ed21 100644 --- a/cpp/ql/test/library-tests/ir/range-analysis/RangeAnalysis.ql +++ b/cpp/ql/test/library-tests/ir/range-analysis/RangeAnalysis.ql @@ -29,7 +29,7 @@ private string getDirectionString(boolean d) { } bindingset[value] -private string getOffsetString(int value) { +private string getOffsetString(float value) { if value >= 0 then result = "+" + value.toString() else result = value.toString() } @@ -37,7 +37,7 @@ bindingset[s] string quote(string s) { if s.matches("% %") then result = "\"" + s + "\"" else result = s } bindingset[delta] -private string getBoundString(SemBound b, int delta) { +private string getBoundString(SemBound b, float delta) { b instanceof SemZeroBound and result = delta.toString() or result = @@ -51,7 +51,7 @@ private string getBoundString(SemBound b, int delta) { } private string getARangeString(SemExpr e) { - exists(SemBound b, int delta, boolean upper | + exists(SemBound b, float delta, boolean upper | semBounded(e, b, delta, upper, _) and if semBounded(e, b, delta, upper.booleanNot(), _) then delta != 0 and result = "==" + getBoundString(b, delta) diff --git a/cpp/ql/test/library-tests/ir/range-analysis/SimpleRangeAnalysis_tests.cpp b/cpp/ql/test/library-tests/ir/range-analysis/SimpleRangeAnalysis_tests.cpp index f71b7c86e52..09c20b2a385 100644 --- a/cpp/ql/test/library-tests/ir/range-analysis/SimpleRangeAnalysis_tests.cpp +++ b/cpp/ql/test/library-tests/ir/range-analysis/SimpleRangeAnalysis_tests.cpp @@ -741,7 +741,7 @@ unsigned long mult_rounding() { range(y); // $ range===1000000003 range(x); // $ range===1000000003 xy = x * y; - range(xy); + range(xy); // $ range===1000000006000000000 return xy; // BUG: upper bound should be >= 1000000006000000009UL } From 65c7a504b224081a60cd2185e914790d8cce9874 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen <mathiasvp@github.com> Date: Wed, 29 Mar 2023 15:08:50 +0100 Subject: [PATCH 611/631] C++: Accept test changes. --- .../aliased_ssa_consistency.expected | 3 --- .../syntax-zoo/raw_consistency.expected | 19 ------------------- .../unaliased_ssa_consistency.expected | 3 --- 3 files changed, 25 deletions(-) diff --git a/cpp/ql/test/library-tests/syntax-zoo/aliased_ssa_consistency.expected b/cpp/ql/test/library-tests/syntax-zoo/aliased_ssa_consistency.expected index 63b6f72905b..d94b3df0bb3 100644 --- a/cpp/ql/test/library-tests/syntax-zoo/aliased_ssa_consistency.expected +++ b/cpp/ql/test/library-tests/syntax-zoo/aliased_ssa_consistency.expected @@ -12,12 +12,9 @@ instructionWithoutSuccessor | condition_decls.cpp:26:23:26:24 | Chi: call to BoxedInt | Instruction 'Chi: call to BoxedInt' has no successors in function '$@'. | condition_decls.cpp:25:6:25:21 | void switch_decl_bind(int) | void switch_decl_bind(int) | | condition_decls.cpp:41:22:41:23 | Chi: call to BoxedInt | Instruction 'Chi: call to BoxedInt' has no successors in function '$@'. | condition_decls.cpp:40:6:40:20 | void while_decl_bind(int) | void while_decl_bind(int) | | condition_decls.cpp:48:52:48:53 | Chi: call to BoxedInt | Instruction 'Chi: call to BoxedInt' has no successors in function '$@'. | condition_decls.cpp:47:6:47:18 | void for_decl_bind(int) | void for_decl_bind(int) | -| misc.c:171:10:171:13 | Uninitialized: definition of str2 | Instruction 'Uninitialized: definition of str2' has no successors in function '$@'. | misc.c:168:6:168:8 | void vla() | void vla() | | ms_try_mix.cpp:35:13:35:19 | ThrowValue: throw ... | Instruction 'ThrowValue: throw ...' has no successors in function '$@'. | ms_try_mix.cpp:29:6:29:19 | void ms_finally_mix(int) | void ms_finally_mix(int) | | ms_try_mix.cpp:53:5:53:11 | ThrowValue: throw ... | Instruction 'ThrowValue: throw ...' has no successors in function '$@'. | ms_try_mix.cpp:49:6:49:28 | void ms_empty_finally_at_end() | void ms_empty_finally_at_end() | | stmt_expr.cpp:27:5:27:15 | Store: ... = ... | Instruction 'Store: ... = ...' has no successors in function '$@'. | stmt_expr.cpp:21:13:21:13 | void stmtexpr::g(int) | void stmtexpr::g(int) | -| vla.c:5:9:5:14 | Uninitialized: definition of matrix | Instruction 'Uninitialized: definition of matrix' has no successors in function '$@'. | vla.c:3:12:3:12 | int f(int, char**) | int f(int, char**) | -| vla.c:11:6:11:16 | Chi: vla_typedef | Instruction 'Chi: vla_typedef' has no successors in function '$@'. | vla.c:11:6:11:16 | void vla_typedef() | void vla_typedef() | ambiguousSuccessors unexplainedLoop unnecessaryPhiInstruction diff --git a/cpp/ql/test/library-tests/syntax-zoo/raw_consistency.expected b/cpp/ql/test/library-tests/syntax-zoo/raw_consistency.expected index a498c7e4b23..6fa6c863aeb 100644 --- a/cpp/ql/test/library-tests/syntax-zoo/raw_consistency.expected +++ b/cpp/ql/test/library-tests/syntax-zoo/raw_consistency.expected @@ -23,29 +23,11 @@ instructionWithoutSuccessor | file://:0:0:0:0 | CompareNE: (bool)... | Instruction 'CompareNE: (bool)...' has no successors in function '$@'. | condition_decls.cpp:15:6:15:17 | void if_decl_bind(int) | void if_decl_bind(int) | | file://:0:0:0:0 | CompareNE: (bool)... | Instruction 'CompareNE: (bool)...' has no successors in function '$@'. | condition_decls.cpp:40:6:40:20 | void while_decl_bind(int) | void while_decl_bind(int) | | file://:0:0:0:0 | CompareNE: (bool)... | Instruction 'CompareNE: (bool)...' has no successors in function '$@'. | condition_decls.cpp:47:6:47:18 | void for_decl_bind(int) | void for_decl_bind(int) | -| misc.c:171:10:171:13 | Uninitialized: definition of str2 | Instruction 'Uninitialized: definition of str2' has no successors in function '$@'. | misc.c:168:6:168:8 | void vla() | void vla() | -| misc.c:171:15:171:31 | Add: ... + ... | Instruction 'Add: ... + ...' has no successors in function '$@'. | misc.c:168:6:168:8 | void vla() | void vla() | -| misc.c:173:14:173:26 | Mul: ... * ... | Instruction 'Mul: ... * ...' has no successors in function '$@'. | misc.c:168:6:168:8 | void vla() | void vla() | -| misc.c:173:37:173:39 | Store: array to pointer conversion | Instruction 'Store: array to pointer conversion' has no successors in function '$@'. | misc.c:168:6:168:8 | void vla() | void vla() | -| misc.c:174:17:174:22 | CallSideEffect: call to getInt | Instruction 'CallSideEffect: call to getInt' has no successors in function '$@'. | misc.c:168:6:168:8 | void vla() | void vla() | -| misc.c:174:30:174:35 | CallSideEffect: call to getInt | Instruction 'CallSideEffect: call to getInt' has no successors in function '$@'. | misc.c:168:6:168:8 | void vla() | void vla() | -| misc.c:174:55:174:60 | Store: (char ****)... | Instruction 'Store: (char ****)...' has no successors in function '$@'. | misc.c:168:6:168:8 | void vla() | void vla() | | ms_try_mix.cpp:35:13:35:19 | ThrowValue: throw ... | Instruction 'ThrowValue: throw ...' has no successors in function '$@'. | ms_try_mix.cpp:29:6:29:19 | void ms_finally_mix(int) | void ms_finally_mix(int) | | ms_try_mix.cpp:53:5:53:11 | ThrowValue: throw ... | Instruction 'ThrowValue: throw ...' has no successors in function '$@'. | ms_try_mix.cpp:49:6:49:28 | void ms_empty_finally_at_end() | void ms_empty_finally_at_end() | | stmt_expr.cpp:27:5:27:15 | Store: ... = ... | Instruction 'Store: ... = ...' has no successors in function '$@'. | stmt_expr.cpp:21:13:21:13 | void stmtexpr::g(int) | void stmtexpr::g(int) | | stmt_expr.cpp:29:11:32:11 | CopyValue: (statement expression) | Instruction 'CopyValue: (statement expression)' has no successors in function '$@'. | stmt_expr.cpp:21:13:21:13 | void stmtexpr::g(int) | void stmtexpr::g(int) | | stmt_in_type.cpp:5:53:5:53 | Constant: 1 | Instruction 'Constant: 1' has no successors in function '$@'. | stmt_in_type.cpp:2:6:2:12 | void cpp_fun() | void cpp_fun() | -| vla.c:5:9:5:14 | Uninitialized: definition of matrix | Instruction 'Uninitialized: definition of matrix' has no successors in function '$@'. | vla.c:3:12:3:12 | int f(int, char**) | int f(int, char**) | -| vla.c:5:16:5:19 | Load: argc | Instruction 'Load: argc' has no successors in function '$@'. | vla.c:3:12:3:12 | int f(int, char**) | int f(int, char**) | -| vla.c:5:27:5:33 | BufferReadSideEffect: (const char *)... | Instruction 'BufferReadSideEffect: (const char *)...' has no successors in function '$@'. | vla.c:3:12:3:12 | int f(int, char**) | int f(int, char**) | -| vla.c:11:6:11:16 | InitializeNonLocal: vla_typedef | Instruction 'InitializeNonLocal: vla_typedef' has no successors in function '$@'. | vla.c:11:6:11:16 | void vla_typedef() | void vla_typedef() | -| vla.c:12:33:12:44 | Add: ... + ... | Instruction 'Add: ... + ...' has no successors in function '$@'. | vla.c:11:6:11:16 | void vla_typedef() | void vla_typedef() | -| vla.c:12:50:12:62 | Mul: ... * ... | Instruction 'Mul: ... * ...' has no successors in function '$@'. | vla.c:11:6:11:16 | void vla_typedef() | void vla_typedef() | -| vla.c:13:12:13:14 | Uninitialized: definition of var | Instruction 'Uninitialized: definition of var' has no successors in function '$@'. | vla.c:11:6:11:16 | void vla_typedef() | void vla_typedef() | -| vla.c:14:36:14:47 | Add: ... + ... | Instruction 'Add: ... + ...' has no successors in function '$@'. | vla.c:11:6:11:16 | void vla_typedef() | void vla_typedef() | -| vla.c:14:53:14:65 | Mul: ... * ... | Instruction 'Mul: ... * ...' has no successors in function '$@'. | vla.c:11:6:11:16 | void vla_typedef() | void vla_typedef() | -| vla.c:14:74:14:79 | CallSideEffect: call to getInt | Instruction 'CallSideEffect: call to getInt' has no successors in function '$@'. | vla.c:11:6:11:16 | void vla_typedef() | void vla_typedef() | -| vla.c:14:92:14:94 | Store: (char *)... | Instruction 'Store: (char *)...' has no successors in function '$@'. | vla.c:11:6:11:16 | void vla_typedef() | void vla_typedef() | ambiguousSuccessors unexplainedLoop unnecessaryPhiInstruction @@ -65,7 +47,6 @@ useNotDominatedByDefinition | ms_try_except.cpp:19:17:19:21 | Left | Operand 'Left' is not dominated by its definition in function '$@'. | ms_try_except.cpp:2:6:2:18 | void ms_try_except(int) | void ms_try_except(int) | | static_init_templates.cpp:15:1:15:18 | Address | Operand 'Address' is not dominated by its definition in function '$@'. | static_init_templates.cpp:15:1:15:18 | void MyClass::MyClass() | void MyClass::MyClass() | | try_catch.cpp:21:9:21:9 | Address | Operand 'Address' is not dominated by its definition in function '$@'. | try_catch.cpp:19:6:19:23 | void throw_from_nonstmt(int) | void throw_from_nonstmt(int) | -| vla.c:3:31:3:34 | Address | Operand 'Address' is not dominated by its definition in function '$@'. | vla.c:3:12:3:12 | int f(int, char**) | int f(int, char**) | switchInstructionWithoutDefaultEdge notMarkedAsConflated wronglyMarkedAsConflated diff --git a/cpp/ql/test/library-tests/syntax-zoo/unaliased_ssa_consistency.expected b/cpp/ql/test/library-tests/syntax-zoo/unaliased_ssa_consistency.expected index 4e67089ba0a..6706c66c0a2 100644 --- a/cpp/ql/test/library-tests/syntax-zoo/unaliased_ssa_consistency.expected +++ b/cpp/ql/test/library-tests/syntax-zoo/unaliased_ssa_consistency.expected @@ -12,12 +12,9 @@ instructionWithoutSuccessor | condition_decls.cpp:26:23:26:24 | IndirectMayWriteSideEffect: call to BoxedInt | Instruction 'IndirectMayWriteSideEffect: call to BoxedInt' has no successors in function '$@'. | condition_decls.cpp:25:6:25:21 | void switch_decl_bind(int) | void switch_decl_bind(int) | | condition_decls.cpp:41:22:41:23 | IndirectMayWriteSideEffect: call to BoxedInt | Instruction 'IndirectMayWriteSideEffect: call to BoxedInt' has no successors in function '$@'. | condition_decls.cpp:40:6:40:20 | void while_decl_bind(int) | void while_decl_bind(int) | | condition_decls.cpp:48:52:48:53 | IndirectMayWriteSideEffect: call to BoxedInt | Instruction 'IndirectMayWriteSideEffect: call to BoxedInt' has no successors in function '$@'. | condition_decls.cpp:47:6:47:18 | void for_decl_bind(int) | void for_decl_bind(int) | -| misc.c:171:10:171:13 | Uninitialized: definition of str2 | Instruction 'Uninitialized: definition of str2' has no successors in function '$@'. | misc.c:168:6:168:8 | void vla() | void vla() | | ms_try_mix.cpp:35:13:35:19 | ThrowValue: throw ... | Instruction 'ThrowValue: throw ...' has no successors in function '$@'. | ms_try_mix.cpp:29:6:29:19 | void ms_finally_mix(int) | void ms_finally_mix(int) | | ms_try_mix.cpp:53:5:53:11 | ThrowValue: throw ... | Instruction 'ThrowValue: throw ...' has no successors in function '$@'. | ms_try_mix.cpp:49:6:49:28 | void ms_empty_finally_at_end() | void ms_empty_finally_at_end() | | stmt_expr.cpp:27:5:27:15 | Store: ... = ... | Instruction 'Store: ... = ...' has no successors in function '$@'. | stmt_expr.cpp:21:13:21:13 | void stmtexpr::g(int) | void stmtexpr::g(int) | -| vla.c:5:9:5:14 | Uninitialized: definition of matrix | Instruction 'Uninitialized: definition of matrix' has no successors in function '$@'. | vla.c:3:12:3:12 | int f(int, char**) | int f(int, char**) | -| vla.c:11:6:11:16 | InitializeNonLocal: vla_typedef | Instruction 'InitializeNonLocal: vla_typedef' has no successors in function '$@'. | vla.c:11:6:11:16 | void vla_typedef() | void vla_typedef() | ambiguousSuccessors unexplainedLoop unnecessaryPhiInstruction From d8703210dddd51b2a99e008010cf14c09387df00 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Fri, 10 Mar 2023 18:43:48 +0000 Subject: [PATCH 612/631] Swift: Extract type aliases. --- swift/extractor/translators/DeclTranslator.cpp | 1 + swift/ql/lib/swift.dbscheme | 3 ++- swift/schema.py | 13 ++++++++++++- 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/swift/extractor/translators/DeclTranslator.cpp b/swift/extractor/translators/DeclTranslator.cpp index 415f870df55..453379b2984 100644 --- a/swift/extractor/translators/DeclTranslator.cpp +++ b/swift/extractor/translators/DeclTranslator.cpp @@ -206,6 +206,7 @@ std::optional<codeql::AssociatedTypeDecl> DeclTranslator::translateAssociatedTyp std::optional<codeql::TypeAliasDecl> DeclTranslator::translateTypeAliasDecl( const swift::TypeAliasDecl& decl) { if (auto entry = createNamedEntry(decl)) { + entry->aliased_type = dispatcher.fetchLabel(decl.getUnderlyingType()); fillTypeDecl(decl, *entry); return entry; } diff --git a/swift/ql/lib/swift.dbscheme b/swift/ql/lib/swift.dbscheme index c2f01f2beb6..e646f9e0308 100644 --- a/swift/ql/lib/swift.dbscheme +++ b/swift/ql/lib/swift.dbscheme @@ -670,7 +670,8 @@ param_decl_property_wrapper_local_wrapped_vars( //dir=decl ); type_alias_decls( //dir=decl - unique int id: @type_alias_decl + unique int id: @type_alias_decl, + int aliased_type: @type_or_none ref ); class_decls( //dir=decl diff --git a/swift/schema.py b/swift/schema.py index a9b075cd933..2737ebf8ac4 100644 --- a/swift/schema.py +++ b/swift/schema.py @@ -324,7 +324,18 @@ class OpaqueTypeDecl(GenericTypeDecl): opaque_generic_params: list["GenericTypeParamType"] class TypeAliasDecl(GenericTypeDecl): - pass + """ + A declaration of a type alias to another type. For example: + ``` + typealias MyInt = Int + ``` + """ + aliased_type: Type | doc("aliased type on the right-hand side of this type alias declaration") | desc(""" + For example the aliased type of `MyInt` in the following code is `Int`: + ``` + typealias MyInt = Int + ``` + """) class ClassDecl(NominalTypeDecl): pass From f042195e5c6aca8daca680c757dded57efd6c54d Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Fri, 10 Mar 2023 18:45:54 +0000 Subject: [PATCH 613/631] Swift: Connect it up. --- swift/ql/lib/codeql/swift/elements/type/TypeAliasType.qll | 4 ++-- swift/ql/test/extractor-tests/declarations/all.ql | 3 +-- .../elements/type/nominaltype/nominaltypedecl.ql | 4 ++-- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/swift/ql/lib/codeql/swift/elements/type/TypeAliasType.qll b/swift/ql/lib/codeql/swift/elements/type/TypeAliasType.qll index e7763b45e70..b7b3045d9e0 100644 --- a/swift/ql/lib/codeql/swift/elements/type/TypeAliasType.qll +++ b/swift/ql/lib/codeql/swift/elements/type/TypeAliasType.qll @@ -10,7 +10,7 @@ class TypeAliasType extends Generated::TypeAliasType { * typealias MyInt = Int * ``` */ - Type getAliasedType() { none() } // TODO: not yet implemented. + Type getAliasedType() { result = this.getDecl().getAliasedType() } - override Type getUnderlyingType() { result = this } // TODO: not yet implemented. + override Type getUnderlyingType() { result = this.getAliasedType().getUnderlyingType() } } diff --git a/swift/ql/test/extractor-tests/declarations/all.ql b/swift/ql/test/extractor-tests/declarations/all.ql index bf36129f58a..1580a8e6002 100644 --- a/swift/ql/test/extractor-tests/declarations/all.ql +++ b/swift/ql/test/extractor-tests/declarations/all.ql @@ -1,8 +1,7 @@ import swift string describe(Decl decl) { - //result = "getAliasedType:" + decl.(TypeAliasDecl).getAliasedType().toString() TODO: not yet implemented - none() + result = "getAliasedType:" + decl.(TypeAliasDecl).getAliasedType().toString() } from Decl decl diff --git a/swift/ql/test/library-tests/elements/type/nominaltype/nominaltypedecl.ql b/swift/ql/test/library-tests/elements/type/nominaltype/nominaltypedecl.ql index 53afa43caf5..917b27d6826 100644 --- a/swift/ql/test/library-tests/elements/type/nominaltype/nominaltypedecl.ql +++ b/swift/ql/test/library-tests/elements/type/nominaltype/nominaltypedecl.ql @@ -1,8 +1,8 @@ import swift string describe(TypeDecl td) { - //result = "getAliasedType:" + td.(TypeAliasDecl).getAliasedType() TODO: not yet implemented. - //or + result = "getAliasedType:" + td.(TypeAliasDecl).getAliasedType() + or result = "getABaseType:" + td.(NominalTypeDecl).getABaseType() } From 4ba8de48029f1e24e846bdcb7de6fe19fd8f1ba5 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Wed, 29 Mar 2023 13:21:35 +0100 Subject: [PATCH 614/631] Swift: Update codegen. --- swift/ql/.generated.list | 6 ++-- swift/ql/lib/codeql/swift/generated/Raw.qll | 10 +++++++ .../swift/generated/decl/TypeAliasDecl.qll | 30 +++++++++++++++++++ 3 files changed, 43 insertions(+), 3 deletions(-) diff --git a/swift/ql/.generated.list b/swift/ql/.generated.list index 5c6b0ce34c7..2a0d663241d 100644 --- a/swift/ql/.generated.list +++ b/swift/ql/.generated.list @@ -381,10 +381,10 @@ ql/lib/codeql/swift/generated/File.qll f88c485883dd9b2b4a366080e098372912e03fb31 ql/lib/codeql/swift/generated/Locatable.qll bdc98b9fb7788f44a4bf7e487ee5bd329473409950a8e9f116d61995615ad849 0b36b4fe45e2aa195e4bb70c50ea95f32f141b8e01e5f23466c6427dd9ab88fb ql/lib/codeql/swift/generated/Location.qll 851766e474cdfdfa67da42e0031fc42dd60196ff5edd39d82f08d3e32deb84c1 b29b2c37672f5acff15f1d3c5727d902f193e51122327b31bd27ec5f877bca3b ql/lib/codeql/swift/generated/OtherAvailabilitySpec.qll 0e26a203b26ff0581b7396b0c6d1606feec5cc32477f676585cdec4911af91c5 0e26a203b26ff0581b7396b0c6d1606feec5cc32477f676585cdec4911af91c5 -ql/lib/codeql/swift/generated/ParentChild.qll 0ac2139b8b2e172858262d80950a0212b21fe46bf6af7259d9058fb7193f8242 6f7464ecd8ca04b6aa261139b36a162e5b0636237d514b8431ef4f97a1c603dc +ql/lib/codeql/swift/generated/ParentChild.qll 7d45d4e872e769f37a5b157ba422c48afe482552e44d94ff5f6a5a6449d672e7 6f7464ecd8ca04b6aa261139b36a162e5b0636237d514b8431ef4f97a1c603dc ql/lib/codeql/swift/generated/PlatformVersionAvailabilitySpec.qll f82d9ca416fe8bd59b5531b65b1c74c9f317b3297a6101544a11339a1cffce38 7f5c6d3309e66c134107afe55bae76dfc9a72cb7cdd6d4c3706b6b34cee09fa0 ql/lib/codeql/swift/generated/PureSynthConstructors.qll 173c0dd59396a1de26fe870e3bc2766c46de689da2a4d8807cb62023bbce1a98 173c0dd59396a1de26fe870e3bc2766c46de689da2a4d8807cb62023bbce1a98 -ql/lib/codeql/swift/generated/Raw.qll efe60f045f8a4aecedd7bfe8110c0c10539bcdcb9f17f342cf560c8d065e6aff 261825907250bb4ddeba8ccce0df29b45f13c6fb338eb41a06ea6b43e7aa9788 +ql/lib/codeql/swift/generated/Raw.qll b1ad09374cf2d5556e0a409a59eea723a7280882ae144f68fd2dae362cb147b7 587433583a7e93c9a8534cb59409fd802e4b6587faf1367df9447d06be191c73 ql/lib/codeql/swift/generated/Synth.qll af02e0b49fe7b488592687996cc74d9525d4e3fbc9d324820b310b356f4d2612 5c740a660721173e9e4e45eb701d373ca19ff14d61cdaea309b65871e0deea90 ql/lib/codeql/swift/generated/SynthConstructors.qll a1b3ca33017f82124286ccad317a05484fee144fb9c3cdd2e500ce38e5efcec4 a1b3ca33017f82124286ccad317a05484fee144fb9c3cdd2e500ce38e5efcec4 ql/lib/codeql/swift/generated/UnknownFile.qll 0fcf9beb8de79440bcdfff4bb6ab3dd139bd273e6c32754e05e6a632651e85f6 0fcf9beb8de79440bcdfff4bb6ab3dd139bd273e6c32754e05e6a632651e85f6 @@ -428,7 +428,7 @@ ql/lib/codeql/swift/generated/decl/ProtocolDecl.qll 4b03e3c2a7af66e66e8abc40bd2e ql/lib/codeql/swift/generated/decl/StructDecl.qll 9343b001dfeec83a6b41e88dc1ec75744d39c397e8e48441aa4d01493f10026a 9343b001dfeec83a6b41e88dc1ec75744d39c397e8e48441aa4d01493f10026a ql/lib/codeql/swift/generated/decl/SubscriptDecl.qll 31cb1f90d4c60060f64c432850821969953f1a46e36ce772456c67dfff375ff5 1d0098518c56aed96039b0b660b2cce5ea0db7ac4c9a550af07d758e282d4f61 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/TypeAliasDecl.qll 640912badc9d2278b6d14a746d85ed71b17c52cd1f2006aef46d5a4aeaa544f2 a6cbe000ea9d5d1ccd37eb50c23072e19ee0234d53dcb943fef20e3f553fcf4e ql/lib/codeql/swift/generated/decl/TypeDecl.qll 74bb5f0fe2648d95c84fdce804740f2bba5c7671e15cbea671d8509456bf5c2b 32bc7154c8585c25f27a3587bb4ba039c8d69f09d945725e45d730de44f7a5ae ql/lib/codeql/swift/generated/decl/ValueDecl.qll 7b4e4c9334be676f242857c77099306d8a0a4357b253f8bc68f71328cedf1f58 f18938c47f670f2e0c27ffd7e31e55f291f88fb50d8e576fcea116d5f9e5c66d ql/lib/codeql/swift/generated/decl/VarDecl.qll bdea76fe6c8f721bae52bbc26a2fc1cbd665a19a6920b36097822839158d9d3b 9c91d8159fd7a53cba479d8c8f31f49ad2b1e2617b8cd9e7d1a2cb4796dfa2da diff --git a/swift/ql/lib/codeql/swift/generated/Raw.qll b/swift/ql/lib/codeql/swift/generated/Raw.qll index 3dad5a302fc..beb035d81c5 100644 --- a/swift/ql/lib/codeql/swift/generated/Raw.qll +++ b/swift/ql/lib/codeql/swift/generated/Raw.qll @@ -660,6 +660,16 @@ module Raw { class TypeAliasDecl extends @type_alias_decl, GenericTypeDecl { override string toString() { result = "TypeAliasDecl" } + + /** + * Gets the aliased type on the right-hand side of this type alias declaration. + * + * For example the aliased type of `MyInt` in the following code is `Int`: + * ``` + * typealias MyInt = Int + * ``` + */ + Type getAliasedType() { type_alias_decls(this, result) } } class ClassDecl extends @class_decl, NominalTypeDecl { diff --git a/swift/ql/lib/codeql/swift/generated/decl/TypeAliasDecl.qll b/swift/ql/lib/codeql/swift/generated/decl/TypeAliasDecl.qll index 1e9dbd7bc46..d7bd1e8538d 100644 --- a/swift/ql/lib/codeql/swift/generated/decl/TypeAliasDecl.qll +++ b/swift/ql/lib/codeql/swift/generated/decl/TypeAliasDecl.qll @@ -2,9 +2,39 @@ private import codeql.swift.generated.Synth private import codeql.swift.generated.Raw import codeql.swift.elements.decl.GenericTypeDecl +import codeql.swift.elements.type.Type module Generated { + /** + * A declaration of a type alias to another type. For example: + * ``` + * typealias MyInt = Int + * ``` + */ class TypeAliasDecl extends Synth::TTypeAliasDecl, GenericTypeDecl { override string getAPrimaryQlClass() { result = "TypeAliasDecl" } + + /** + * Gets the aliased type on the right-hand side of this type alias declaration. + * + * This includes nodes from the "hidden" AST. It can be overridden in subclasses to change the + * behavior of both the `Immediate` and non-`Immediate` versions. + */ + Type getImmediateAliasedType() { + result = + Synth::convertTypeFromRaw(Synth::convertTypeAliasDeclToRaw(this) + .(Raw::TypeAliasDecl) + .getAliasedType()) + } + + /** + * Gets the aliased type on the right-hand side of this type alias declaration. + * + * For example the aliased type of `MyInt` in the following code is `Int`: + * ``` + * typealias MyInt = Int + * ``` + */ + final Type getAliasedType() { result = getImmediateAliasedType().resolve() } } } From 8e4c7a9d89f68d273332a5111758da2a30ecbb6d Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Wed, 29 Mar 2023 13:35:57 +0100 Subject: [PATCH 615/631] Swift: Test expectations. --- .../test/extractor-tests/declarations/all.expected | 4 ++-- .../elements/type/nominaltype/nominaltype.expected | 12 ++++++------ .../type/nominaltype/nominaltypedecl.expected | 12 ++++++------ 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/swift/ql/test/extractor-tests/declarations/all.expected b/swift/ql/test/extractor-tests/declarations/all.expected index 73027f2a857..f892820f41e 100644 --- a/swift/ql/test/extractor-tests/declarations/all.expected +++ b/swift/ql/test/extractor-tests/declarations/all.expected @@ -272,5 +272,5 @@ | declarations.swift:182:7:182:7 | B.init() | | | declarations.swift:182:7:182:7 | self | | | declarations.swift:182:7:182:7 | self | | -| declarations.swift:183:1:183:15 | A | | -| declarations.swift:184:1:184:18 | C | | +| declarations.swift:183:1:183:15 | A | getAliasedType:B | +| declarations.swift:184:1:184:18 | C | getAliasedType:Int? | diff --git a/swift/ql/test/library-tests/elements/type/nominaltype/nominaltype.expected b/swift/ql/test/library-tests/elements/type/nominaltype/nominaltype.expected index 3786b7c2620..0eb3c363ee8 100644 --- a/swift/ql/test/library-tests/elements/type/nominaltype/nominaltype.expected +++ b/swift/ql/test/library-tests/elements/type/nominaltype/nominaltype.expected @@ -1,13 +1,13 @@ | nominaltype.swift:35:6:35:6 | a | A | A | | -| nominaltype.swift:36:6:36:6 | a_alias | A_alias | A_alias | | -| nominaltype.swift:37:6:37:6 | a_optional_alias | A_optional_alias | A_optional_alias | | +| nominaltype.swift:36:6:36:6 | a_alias | A_alias | A | getAliasedType:A | +| nominaltype.swift:37:6:37:6 | a_optional_alias | A_optional_alias | A? | getAliasedType:A? | | nominaltype.swift:38:6:38:6 | b1 | B1 | B1 | getABaseType:A | | nominaltype.swift:39:6:39:6 | b2 | B2 | B2 | getABaseType:A_alias | -| nominaltype.swift:40:6:40:6 | b1_alias | B1_alias | B1_alias | | -| nominaltype.swift:41:6:41:6 | b2_alias | B2_alias | B2_alias | | +| nominaltype.swift:40:6:40:6 | b1_alias | B1_alias | B1 | getAliasedType:B1 | +| nominaltype.swift:41:6:41:6 | b2_alias | B2_alias | B2 | getAliasedType:B2 | | nominaltype.swift:42:6:42:6 | p | P | P | | | nominaltype.swift:43:6:43:6 | p_alias | P_alias | P_alias | | | nominaltype.swift:44:6:44:6 | c1 | C1 | C1 | getABaseType:P | | nominaltype.swift:45:6:45:6 | c2 | C2 | C2 | getABaseType:P_alias | -| nominaltype.swift:46:6:46:6 | c1_alias | C1_alias | C1_alias | | -| nominaltype.swift:47:6:47:6 | c2_alias | C2_alias | C2_alias | | +| nominaltype.swift:46:6:46:6 | c1_alias | C1_alias | C1 | getAliasedType:C1 | +| nominaltype.swift:47:6:47:6 | c2_alias | C2_alias | C2 | getAliasedType:C2 | diff --git a/swift/ql/test/library-tests/elements/type/nominaltype/nominaltypedecl.expected b/swift/ql/test/library-tests/elements/type/nominaltype/nominaltypedecl.expected index e5381fb2db4..612b031f54e 100644 --- a/swift/ql/test/library-tests/elements/type/nominaltype/nominaltypedecl.expected +++ b/swift/ql/test/library-tests/elements/type/nominaltype/nominaltypedecl.expected @@ -1,11 +1,11 @@ | nominaltype.swift:35:6:35:6 | a | A | | -| nominaltype.swift:36:6:36:6 | a_alias | A_alias | | -| nominaltype.swift:37:6:37:6 | a_optional_alias | A_optional_alias | | +| nominaltype.swift:36:6:36:6 | a_alias | A_alias | getAliasedType:A | +| nominaltype.swift:37:6:37:6 | a_optional_alias | A_optional_alias | getAliasedType:A? | | nominaltype.swift:38:6:38:6 | b1 | B1 | getABaseType:A | | nominaltype.swift:39:6:39:6 | b2 | B2 | getABaseType:A_alias | -| nominaltype.swift:40:6:40:6 | b1_alias | B1_alias | | -| nominaltype.swift:41:6:41:6 | b2_alias | B2_alias | | +| nominaltype.swift:40:6:40:6 | b1_alias | B1_alias | getAliasedType:B1 | +| nominaltype.swift:41:6:41:6 | b2_alias | B2_alias | getAliasedType:B2 | | nominaltype.swift:44:6:44:6 | c1 | C1 | getABaseType:P | | nominaltype.swift:45:6:45:6 | c2 | C2 | getABaseType:P_alias | -| nominaltype.swift:46:6:46:6 | c1_alias | C1_alias | | -| nominaltype.swift:47:6:47:6 | c2_alias | C2_alias | | +| nominaltype.swift:46:6:46:6 | c1_alias | C1_alias | getAliasedType:C1 | +| nominaltype.swift:47:6:47:6 | c2_alias | C2_alias | getAliasedType:C2 | From 704e42cf22dc74ef3758a7cefa92d40b15734564 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Wed, 29 Mar 2023 14:31:55 +0100 Subject: [PATCH 616/631] Swift: Accept integration test changes (not sure what caused this exactly but it looks OK to me). --- .../posix-only/deduplication/BuiltinTypes.expected | 1 + 1 file changed, 1 insertion(+) diff --git a/swift/integration-tests/posix-only/deduplication/BuiltinTypes.expected b/swift/integration-tests/posix-only/deduplication/BuiltinTypes.expected index 881be23da5e..53b3a353f64 100644 --- a/swift/integration-tests/posix-only/deduplication/BuiltinTypes.expected +++ b/swift/integration-tests/posix-only/deduplication/BuiltinTypes.expected @@ -13,6 +13,7 @@ | Builtin.NativeObject | BuiltinNativeObjectType | | Builtin.RawPointer | BuiltinRawPointerType | | Builtin.RawUnsafeContinuation | BuiltinRawUnsafeContinuationType | +| Builtin.UnsafeValueBuffer | BuiltinUnsafeValueBufferType | | Builtin.Vec2xFPIEEE32 | BuiltinVectorType | | Builtin.Vec2xFPIEEE64 | BuiltinVectorType | | Builtin.Vec2xInt8 | BuiltinVectorType | From d5928e150dd5c0a203bd50dcc411fea940fc9abb Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Wed, 29 Mar 2023 15:51:42 +0100 Subject: [PATCH 617/631] Swift: Prepare upgrade/downgrade scripts. --- .../old.dbscheme | 2602 +++++++++++++++++ .../swift.dbscheme | 2601 ++++++++++++++++ .../upgrade.properties | 2 + .../old.dbscheme | 2601 ++++++++++++++++ .../swift.dbscheme | 2602 +++++++++++++++++ .../upgrade.properties | 2 + 6 files changed, 10410 insertions(+) create mode 100644 swift/downgrades/e646f9e0308ec7135c83c0fdf96896d2737a8013/old.dbscheme create mode 100644 swift/downgrades/e646f9e0308ec7135c83c0fdf96896d2737a8013/swift.dbscheme create mode 100644 swift/downgrades/e646f9e0308ec7135c83c0fdf96896d2737a8013/upgrade.properties create mode 100644 swift/ql/lib/upgrades/c2f01f2beb67e5a57e9df9b6d1c51e35e8d5b0a2/old.dbscheme create mode 100644 swift/ql/lib/upgrades/c2f01f2beb67e5a57e9df9b6d1c51e35e8d5b0a2/swift.dbscheme create mode 100644 swift/ql/lib/upgrades/c2f01f2beb67e5a57e9df9b6d1c51e35e8d5b0a2/upgrade.properties diff --git a/swift/downgrades/e646f9e0308ec7135c83c0fdf96896d2737a8013/old.dbscheme b/swift/downgrades/e646f9e0308ec7135c83c0fdf96896d2737a8013/old.dbscheme new file mode 100644 index 00000000000..e646f9e0308 --- /dev/null +++ b/swift/downgrades/e646f9e0308ec7135c83c0fdf96896d2737a8013/old.dbscheme @@ -0,0 +1,2602 @@ +// 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 +| @locatable +| @location +| @type +; + +#keyset[id] +element_is_unknown( + int id: @element ref +); + +@callable = + @abstract_closure_expr +| @abstract_function_decl +; + +#keyset[id] +callable_names( + int id: @callable ref, + string name: string ref +); + +#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 +); + +#keyset[id, index] +callable_captures( + int id: @callable ref, + int index: int ref, + int capture: @captured_decl_or_none ref +); + +@file = + @db_file +; + +#keyset[id] +files( + int id: @file ref, + string name: string ref +); + +#keyset[id] +file_is_successfully_extracted( + int id: @file 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 = + @availability_info +| @availability_spec +| @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 +; + +availability_infos( + unique int id: @availability_info +); + +#keyset[id] +availability_info_is_unavailable( + int id: @availability_info ref +); + +#keyset[id, index] +availability_info_specs( + int id: @availability_info ref, + int index: int ref, + int spec: @availability_spec_or_none ref +); + +@availability_spec = + @other_availability_spec +| @platform_version_availability_spec +; + +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 +); + +other_availability_specs( + unique int id: @other_availability_spec +); + +platform_version_availability_specs( + unique int id: @platform_version_availability_spec, + string platform: string ref, + string version: string ref +); + +@decl = + @captured_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 +); + +#keyset[id, index] +decl_members( //dir=decl + int id: @decl ref, + int index: int ref, + int member: @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 +); + +captured_decls( //dir=decl + unique int id: @captured_decl, + int decl: @value_decl_or_none ref +); + +#keyset[id] +captured_decl_is_direct( //dir=decl + int id: @captured_decl ref +); + +#keyset[id] +captured_decl_is_escaping( //dir=decl + int id: @captured_decl 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 +); + +#keyset[id, index] +extension_decl_protocols( //dir=decl + int id: @extension_decl ref, + int index: int ref, + int protocol: @protocol_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 +; + +@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, + int aliased_type: @type_or_none ref +); + +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, + string pattern: string ref, + int version: int ref +); + +@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 +); + +#keyset[id] +condition_element_availabilities( //dir=stmt + int id: @condition_element ref, + int availability: @availability_info_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] +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: @generic_type_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 +; + +@availability_info_or_none = + @availability_info +| @unspecified_element +; + +@availability_spec_or_none = + @availability_spec +| @unspecified_element +; + +@brace_stmt_or_none = + @brace_stmt +| @unspecified_element +; + +@captured_decl_or_none = + @captured_decl +| @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_decl_or_none = + @generic_type_decl +| @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/e646f9e0308ec7135c83c0fdf96896d2737a8013/swift.dbscheme b/swift/downgrades/e646f9e0308ec7135c83c0fdf96896d2737a8013/swift.dbscheme new file mode 100644 index 00000000000..c2f01f2beb6 --- /dev/null +++ b/swift/downgrades/e646f9e0308ec7135c83c0fdf96896d2737a8013/swift.dbscheme @@ -0,0 +1,2601 @@ +// 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 +| @locatable +| @location +| @type +; + +#keyset[id] +element_is_unknown( + int id: @element ref +); + +@callable = + @abstract_closure_expr +| @abstract_function_decl +; + +#keyset[id] +callable_names( + int id: @callable ref, + string name: string ref +); + +#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 +); + +#keyset[id, index] +callable_captures( + int id: @callable ref, + int index: int ref, + int capture: @captured_decl_or_none ref +); + +@file = + @db_file +; + +#keyset[id] +files( + int id: @file ref, + string name: string ref +); + +#keyset[id] +file_is_successfully_extracted( + int id: @file 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 = + @availability_info +| @availability_spec +| @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 +; + +availability_infos( + unique int id: @availability_info +); + +#keyset[id] +availability_info_is_unavailable( + int id: @availability_info ref +); + +#keyset[id, index] +availability_info_specs( + int id: @availability_info ref, + int index: int ref, + int spec: @availability_spec_or_none ref +); + +@availability_spec = + @other_availability_spec +| @platform_version_availability_spec +; + +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 +); + +other_availability_specs( + unique int id: @other_availability_spec +); + +platform_version_availability_specs( + unique int id: @platform_version_availability_spec, + string platform: string ref, + string version: string ref +); + +@decl = + @captured_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 +); + +#keyset[id, index] +decl_members( //dir=decl + int id: @decl ref, + int index: int ref, + int member: @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 +); + +captured_decls( //dir=decl + unique int id: @captured_decl, + int decl: @value_decl_or_none ref +); + +#keyset[id] +captured_decl_is_direct( //dir=decl + int id: @captured_decl ref +); + +#keyset[id] +captured_decl_is_escaping( //dir=decl + int id: @captured_decl 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 +); + +#keyset[id, index] +extension_decl_protocols( //dir=decl + int id: @extension_decl ref, + int index: int ref, + int protocol: @protocol_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 +; + +@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, + string pattern: string ref, + int version: int ref +); + +@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 +); + +#keyset[id] +condition_element_availabilities( //dir=stmt + int id: @condition_element ref, + int availability: @availability_info_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] +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: @generic_type_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 +; + +@availability_info_or_none = + @availability_info +| @unspecified_element +; + +@availability_spec_or_none = + @availability_spec +| @unspecified_element +; + +@brace_stmt_or_none = + @brace_stmt +| @unspecified_element +; + +@captured_decl_or_none = + @captured_decl +| @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_decl_or_none = + @generic_type_decl +| @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/e646f9e0308ec7135c83c0fdf96896d2737a8013/upgrade.properties b/swift/downgrades/e646f9e0308ec7135c83c0fdf96896d2737a8013/upgrade.properties new file mode 100644 index 00000000000..64da53384a5 --- /dev/null +++ b/swift/downgrades/e646f9e0308ec7135c83c0fdf96896d2737a8013/upgrade.properties @@ -0,0 +1,2 @@ +description: <INSERT DESCRIPTION HERE> +compatibility: full|backwards|partial|breaking diff --git a/swift/ql/lib/upgrades/c2f01f2beb67e5a57e9df9b6d1c51e35e8d5b0a2/old.dbscheme b/swift/ql/lib/upgrades/c2f01f2beb67e5a57e9df9b6d1c51e35e8d5b0a2/old.dbscheme new file mode 100644 index 00000000000..c2f01f2beb6 --- /dev/null +++ b/swift/ql/lib/upgrades/c2f01f2beb67e5a57e9df9b6d1c51e35e8d5b0a2/old.dbscheme @@ -0,0 +1,2601 @@ +// 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 +| @locatable +| @location +| @type +; + +#keyset[id] +element_is_unknown( + int id: @element ref +); + +@callable = + @abstract_closure_expr +| @abstract_function_decl +; + +#keyset[id] +callable_names( + int id: @callable ref, + string name: string ref +); + +#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 +); + +#keyset[id, index] +callable_captures( + int id: @callable ref, + int index: int ref, + int capture: @captured_decl_or_none ref +); + +@file = + @db_file +; + +#keyset[id] +files( + int id: @file ref, + string name: string ref +); + +#keyset[id] +file_is_successfully_extracted( + int id: @file 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 = + @availability_info +| @availability_spec +| @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 +; + +availability_infos( + unique int id: @availability_info +); + +#keyset[id] +availability_info_is_unavailable( + int id: @availability_info ref +); + +#keyset[id, index] +availability_info_specs( + int id: @availability_info ref, + int index: int ref, + int spec: @availability_spec_or_none ref +); + +@availability_spec = + @other_availability_spec +| @platform_version_availability_spec +; + +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 +); + +other_availability_specs( + unique int id: @other_availability_spec +); + +platform_version_availability_specs( + unique int id: @platform_version_availability_spec, + string platform: string ref, + string version: string ref +); + +@decl = + @captured_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 +); + +#keyset[id, index] +decl_members( //dir=decl + int id: @decl ref, + int index: int ref, + int member: @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 +); + +captured_decls( //dir=decl + unique int id: @captured_decl, + int decl: @value_decl_or_none ref +); + +#keyset[id] +captured_decl_is_direct( //dir=decl + int id: @captured_decl ref +); + +#keyset[id] +captured_decl_is_escaping( //dir=decl + int id: @captured_decl 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 +); + +#keyset[id, index] +extension_decl_protocols( //dir=decl + int id: @extension_decl ref, + int index: int ref, + int protocol: @protocol_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 +; + +@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, + string pattern: string ref, + int version: int ref +); + +@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 +); + +#keyset[id] +condition_element_availabilities( //dir=stmt + int id: @condition_element ref, + int availability: @availability_info_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] +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: @generic_type_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 +; + +@availability_info_or_none = + @availability_info +| @unspecified_element +; + +@availability_spec_or_none = + @availability_spec +| @unspecified_element +; + +@brace_stmt_or_none = + @brace_stmt +| @unspecified_element +; + +@captured_decl_or_none = + @captured_decl +| @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_decl_or_none = + @generic_type_decl +| @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/c2f01f2beb67e5a57e9df9b6d1c51e35e8d5b0a2/swift.dbscheme b/swift/ql/lib/upgrades/c2f01f2beb67e5a57e9df9b6d1c51e35e8d5b0a2/swift.dbscheme new file mode 100644 index 00000000000..e646f9e0308 --- /dev/null +++ b/swift/ql/lib/upgrades/c2f01f2beb67e5a57e9df9b6d1c51e35e8d5b0a2/swift.dbscheme @@ -0,0 +1,2602 @@ +// 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 +| @locatable +| @location +| @type +; + +#keyset[id] +element_is_unknown( + int id: @element ref +); + +@callable = + @abstract_closure_expr +| @abstract_function_decl +; + +#keyset[id] +callable_names( + int id: @callable ref, + string name: string ref +); + +#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 +); + +#keyset[id, index] +callable_captures( + int id: @callable ref, + int index: int ref, + int capture: @captured_decl_or_none ref +); + +@file = + @db_file +; + +#keyset[id] +files( + int id: @file ref, + string name: string ref +); + +#keyset[id] +file_is_successfully_extracted( + int id: @file 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 = + @availability_info +| @availability_spec +| @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 +; + +availability_infos( + unique int id: @availability_info +); + +#keyset[id] +availability_info_is_unavailable( + int id: @availability_info ref +); + +#keyset[id, index] +availability_info_specs( + int id: @availability_info ref, + int index: int ref, + int spec: @availability_spec_or_none ref +); + +@availability_spec = + @other_availability_spec +| @platform_version_availability_spec +; + +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 +); + +other_availability_specs( + unique int id: @other_availability_spec +); + +platform_version_availability_specs( + unique int id: @platform_version_availability_spec, + string platform: string ref, + string version: string ref +); + +@decl = + @captured_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 +); + +#keyset[id, index] +decl_members( //dir=decl + int id: @decl ref, + int index: int ref, + int member: @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 +); + +captured_decls( //dir=decl + unique int id: @captured_decl, + int decl: @value_decl_or_none ref +); + +#keyset[id] +captured_decl_is_direct( //dir=decl + int id: @captured_decl ref +); + +#keyset[id] +captured_decl_is_escaping( //dir=decl + int id: @captured_decl 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 +); + +#keyset[id, index] +extension_decl_protocols( //dir=decl + int id: @extension_decl ref, + int index: int ref, + int protocol: @protocol_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 +; + +@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, + int aliased_type: @type_or_none ref +); + +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, + string pattern: string ref, + int version: int ref +); + +@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 +); + +#keyset[id] +condition_element_availabilities( //dir=stmt + int id: @condition_element ref, + int availability: @availability_info_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] +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: @generic_type_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 +; + +@availability_info_or_none = + @availability_info +| @unspecified_element +; + +@availability_spec_or_none = + @availability_spec +| @unspecified_element +; + +@brace_stmt_or_none = + @brace_stmt +| @unspecified_element +; + +@captured_decl_or_none = + @captured_decl +| @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_decl_or_none = + @generic_type_decl +| @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/c2f01f2beb67e5a57e9df9b6d1c51e35e8d5b0a2/upgrade.properties b/swift/ql/lib/upgrades/c2f01f2beb67e5a57e9df9b6d1c51e35e8d5b0a2/upgrade.properties new file mode 100644 index 00000000000..64da53384a5 --- /dev/null +++ b/swift/ql/lib/upgrades/c2f01f2beb67e5a57e9df9b6d1c51e35e8d5b0a2/upgrade.properties @@ -0,0 +1,2 @@ +description: <INSERT DESCRIPTION HERE> +compatibility: full|backwards|partial|breaking From fcefd03b14a543d02391863a4eb98087bb10f088 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Wed, 29 Mar 2023 13:48:31 +0100 Subject: [PATCH 618/631] Swift: Fill out the upgrade/downgrade scripts. --- .../type_alias_decls.ql | 6 ++++++ .../upgrade.properties | 5 +++-- .../type_alias_decls.ql | 14 ++++++++++++++ .../upgrade.properties | 5 +++-- 4 files changed, 26 insertions(+), 4 deletions(-) create mode 100644 swift/downgrades/e646f9e0308ec7135c83c0fdf96896d2737a8013/type_alias_decls.ql create mode 100644 swift/ql/lib/upgrades/c2f01f2beb67e5a57e9df9b6d1c51e35e8d5b0a2/type_alias_decls.ql diff --git a/swift/downgrades/e646f9e0308ec7135c83c0fdf96896d2737a8013/type_alias_decls.ql b/swift/downgrades/e646f9e0308ec7135c83c0fdf96896d2737a8013/type_alias_decls.ql new file mode 100644 index 00000000000..72f89e3946d --- /dev/null +++ b/swift/downgrades/e646f9e0308ec7135c83c0fdf96896d2737a8013/type_alias_decls.ql @@ -0,0 +1,6 @@ +class TypeAliasDecl extends @type_alias_decl { + string toString() { result = "TypeAliasDecl" } +} + +from TypeAliasDecl id +select id diff --git a/swift/downgrades/e646f9e0308ec7135c83c0fdf96896d2737a8013/upgrade.properties b/swift/downgrades/e646f9e0308ec7135c83c0fdf96896d2737a8013/upgrade.properties index 64da53384a5..31ffe35bf1c 100644 --- a/swift/downgrades/e646f9e0308ec7135c83c0fdf96896d2737a8013/upgrade.properties +++ b/swift/downgrades/e646f9e0308ec7135c83c0fdf96896d2737a8013/upgrade.properties @@ -1,2 +1,3 @@ -description: <INSERT DESCRIPTION HERE> -compatibility: full|backwards|partial|breaking +description: Revert adding TypeAliasDecl.getAliasedType() +compatibility: full +type_alias_decls.rel: run type_alias_decls.qlo diff --git a/swift/ql/lib/upgrades/c2f01f2beb67e5a57e9df9b6d1c51e35e8d5b0a2/type_alias_decls.ql b/swift/ql/lib/upgrades/c2f01f2beb67e5a57e9df9b6d1c51e35e8d5b0a2/type_alias_decls.ql new file mode 100644 index 00000000000..4b5ecd00925 --- /dev/null +++ b/swift/ql/lib/upgrades/c2f01f2beb67e5a57e9df9b6d1c51e35e8d5b0a2/type_alias_decls.ql @@ -0,0 +1,14 @@ +class TypeAliasDecl extends @type_alias_decl { + string toString() { result = "TypeAliasDecl" } +} + +class Type extends @type_or_none { + string toString() { result = "Type" } +} + +// use the canonical type as an approximation of the aliased type +from TypeAliasDecl td, Type t, Type canonical +where + type_alias_types(t, td) and // td is the declaration of t + types(t, _, canonical) // canonical is the canonical type of t +select td, canonical diff --git a/swift/ql/lib/upgrades/c2f01f2beb67e5a57e9df9b6d1c51e35e8d5b0a2/upgrade.properties b/swift/ql/lib/upgrades/c2f01f2beb67e5a57e9df9b6d1c51e35e8d5b0a2/upgrade.properties index 64da53384a5..301f7bb8899 100644 --- a/swift/ql/lib/upgrades/c2f01f2beb67e5a57e9df9b6d1c51e35e8d5b0a2/upgrade.properties +++ b/swift/ql/lib/upgrades/c2f01f2beb67e5a57e9df9b6d1c51e35e8d5b0a2/upgrade.properties @@ -1,2 +1,3 @@ -description: <INSERT DESCRIPTION HERE> -compatibility: full|backwards|partial|breaking +description: Add TypeAliasDecl.getAliasedType() +compatibility: backwards +type_alias_decls.rel: run type_alias_decls.qlo From abec99badbd50f8aa4654deae55f0339544fc93f Mon Sep 17 00:00:00 2001 From: Gulshan Singh <gsgx@google.com> Date: Tue, 21 Mar 2023 23:38:44 -0700 Subject: [PATCH 619/631] C++: Add getSizeExpr and getSizeMult predicates to BufferAccess --- .../semmle/code/cpp/security/BufferAccess.qll | 102 ++++++++++-------- 1 file changed, 60 insertions(+), 42 deletions(-) diff --git a/cpp/ql/lib/semmle/code/cpp/security/BufferAccess.qll b/cpp/ql/lib/semmle/code/cpp/security/BufferAccess.qll index e52babcfe2e..b8c5d67dc05 100644 --- a/cpp/ql/lib/semmle/code/cpp/security/BufferAccess.qll +++ b/cpp/ql/lib/semmle/code/cpp/security/BufferAccess.qll @@ -29,7 +29,23 @@ abstract class BufferAccess extends Expr { */ abstract Expr getBuffer(string bufferDesc, int accessType); - abstract int getSize(); + /** + * Gets the expression that represents the size of the buffer access. The + * actual size is typically the value of this expression multiplied by the + * result of `getSizeMult()`, in bytes. + */ + Expr getSizeExpr() { none() } + + /** + * Gets a constant multiplier for the buffer access size given by + * `getSizeExpr`, in bytes. + */ + int getSizeMult() { none() } + + /** + * Gets the buffer access size in bytes. + */ + int getSize() { result = this.getSizeExpr().getValue().toInt() * this.getSizeMult() } } /** @@ -63,10 +79,10 @@ class MemcpyBA extends BufferAccess { accessType = 1 } - override int getSize() { - result = - this.(FunctionCall).getArgument(2).getValue().toInt() * - getPointedSize(this.(FunctionCall).getTarget().getParameter(0).getType()) + override Expr getSizeExpr() { result = this.(FunctionCall).getArgument(2) } + + override int getSizeMult() { + result = getPointedSize(this.(FunctionCall).getTarget().getParameter(0).getType()) } } @@ -89,10 +105,10 @@ class BCopyBA extends BufferAccess { accessType = 1 } - override int getSize() { - result = - this.(FunctionCall).getArgument(2).getValue().toInt() * - getPointedSize(this.(FunctionCall).getTarget().getParameter(0).getType()) + override Expr getSizeExpr() { result = this.(FunctionCall).getArgument(2) } + + override int getSizeMult() { + result = getPointedSize(this.(FunctionCall).getTarget().getParameter(0).getType()) } } @@ -115,10 +131,10 @@ class StrncpyBA extends BufferAccess { accessType = 2 } - override int getSize() { - result = - this.(FunctionCall).getArgument(2).getValue().toInt() * - getPointedSize(this.(FunctionCall).getTarget().getParameter(0).getType()) + override Expr getSizeExpr() { result = this.(FunctionCall).getArgument(2) } + + override int getSizeMult() { + result = getPointedSize(this.(FunctionCall).getTarget().getParameter(0).getType()) } } @@ -141,10 +157,10 @@ class MemccpyBA extends BufferAccess { accessType = 2 } - override int getSize() { - result = - this.(FunctionCall).getArgument(3).getValue().toInt() * - getPointedSize(this.(FunctionCall).getTarget().getParameter(0).getType()) + override Expr getSizeExpr() { result = this.(FunctionCall).getArgument(3) } + + override int getSizeMult() { + result = getPointedSize(this.(FunctionCall).getTarget().getParameter(0).getType()) } } @@ -172,10 +188,10 @@ class MemcmpBA extends BufferAccess { accessType = 2 } - override int getSize() { - result = - this.(FunctionCall).getArgument(2).getValue().toInt() * - getPointedSize(this.(FunctionCall).getTarget().getParameter(0).getType()) + override Expr getSizeExpr() { result = this.(FunctionCall).getArgument(2) } + + override int getSizeMult() { + result = getPointedSize(this.(FunctionCall).getTarget().getParameter(0).getType()) } } @@ -199,10 +215,10 @@ class SwabBA extends BufferAccess { accessType = 1 } - override int getSize() { - result = - this.(FunctionCall).getArgument(2).getValue().toInt() * - getPointedSize(this.(FunctionCall).getTarget().getParameter(0).getType()) + override Expr getSizeExpr() { result = this.(FunctionCall).getArgument(2) } + + override int getSizeMult() { + result = getPointedSize(this.(FunctionCall).getTarget().getParameter(0).getType()) } } @@ -222,10 +238,10 @@ class MemsetBA extends BufferAccess { accessType = 1 } - override int getSize() { - result = - this.(FunctionCall).getArgument(2).getValue().toInt() * - getPointedSize(this.(FunctionCall).getTarget().getParameter(0).getType()) + override Expr getSizeExpr() { result = this.(FunctionCall).getArgument(2) } + + override int getSizeMult() { + result = getPointedSize(this.(FunctionCall).getTarget().getParameter(0).getType()) } } @@ -244,7 +260,9 @@ class ZeroMemoryBA extends BufferAccess { accessType = 1 } - override int getSize() { result = this.(FunctionCall).getArgument(1).getValue().toInt() } + override Expr getSizeExpr() { result = this.(FunctionCall).getArgument(1) } + + override int getSizeMult() { result = 1 } } /** @@ -263,10 +281,10 @@ class MemchrBA extends BufferAccess { accessType = 2 } - override int getSize() { - result = - this.(FunctionCall).getArgument(2).getValue().toInt() * - getPointedSize(this.(FunctionCall).getTarget().getParameter(0).getType()) + override Expr getSizeExpr() { result = this.(FunctionCall).getArgument(2) } + + override int getSizeMult() { + result = getPointedSize(this.(FunctionCall).getTarget().getParameter(0).getType()) } } @@ -285,11 +303,9 @@ class FreadBA extends BufferAccess { accessType = 2 } - override int getSize() { - result = - this.(FunctionCall).getArgument(1).getValue().toInt() * - this.(FunctionCall).getArgument(2).getValue().toInt() - } + override Expr getSizeExpr() { result = this.(FunctionCall).getArgument(1) } + + override int getSizeMult() { result = this.(FunctionCall).getArgument(2).getValue().toInt() } } /** @@ -318,11 +334,13 @@ class ArrayExprBA extends BufferAccess { accessType = 3 } + override Expr getSizeExpr() { result = this.(ArrayExpr).getArrayOffset() } + override int getSize() { // byte size of the buffer that would be required to support this // access - result = - (1 + this.(ArrayExpr).getArrayOffset().getValue().toInt()) * - this.(ArrayExpr).getType().getSize() + result = (1 + this.getSizeExpr().getValue().toInt()) * this.getSizeMult() } + + override int getSizeMult() { result = this.(ArrayExpr).getType().getSize() } } From 0249890747bae6bf0e74f587230df9af762a4687 Mon Sep 17 00:00:00 2001 From: Ed Minnix <egregius313@github.com> Date: Sun, 19 Mar 2023 23:33:02 -0400 Subject: [PATCH 620/631] Refactor CommandLineQuery.qll --- .../code/java/security/CommandLineQuery.qll | 34 ++++++++++++++++--- .../src/Security/CWE/CWE-078/ExecTainted.ql | 6 ++-- .../Security/CWE/CWE-078/ExecTainted.ql | 6 ++-- 3 files changed, 37 insertions(+), 9 deletions(-) diff --git a/java/ql/lib/semmle/code/java/security/CommandLineQuery.qll b/java/ql/lib/semmle/code/java/security/CommandLineQuery.qll index 42768d024e8..adc8148a8ff 100644 --- a/java/ql/lib/semmle/code/java/security/CommandLineQuery.qll +++ b/java/ql/lib/semmle/code/java/security/CommandLineQuery.qll @@ -12,9 +12,11 @@ import semmle.code.java.security.ExternalProcess import semmle.code.java.security.CommandArguments /** + * DEPRECATED: Use `RemoteUserInputToArgumentToExecFlow` instead. + * * A taint-tracking configuration for unvalidated user input that is used to run an external process. */ -class RemoteUserInputToArgumentToExecFlowConfig extends TaintTracking::Configuration { +deprecated class RemoteUserInputToArgumentToExecFlowConfig extends TaintTracking::Configuration { RemoteUserInputToArgumentToExecFlowConfig() { this = "ExecCommon::RemoteUserInputToArgumentToExecFlowConfig" } @@ -32,13 +34,35 @@ class RemoteUserInputToArgumentToExecFlowConfig extends TaintTracking::Configura } } +/** + * A taint-tracking configuration for unvalidated user input that is used to run an external process. + */ +private module RemoteUserInputToArgumentToExecFlowConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node src) { src instanceof RemoteFlowSource } + + predicate isSink(DataFlow::Node sink) { sink.asExpr() instanceof ArgumentToExec } + + predicate isBarrier(DataFlow::Node node) { + node.getType() instanceof PrimitiveType + or + node.getType() instanceof BoxedType + or + isSafeCommandArgument(node.asExpr()) + } +} + +module RemoteUserInputToArgumentToExecFlow = + TaintTracking::Make<RemoteUserInputToArgumentToExecFlowConfig>; + /** * Implementation of `ExecTainted.ql`. It is extracted to a QLL * so that it can be excluded from `ExecUnescaped.ql` to avoid * reporting overlapping results. */ -predicate execTainted(DataFlow::PathNode source, DataFlow::PathNode sink, ArgumentToExec execArg) { - exists(RemoteUserInputToArgumentToExecFlowConfig conf | - conf.hasFlowPath(source, sink) and sink.getNode() = DataFlow::exprNode(execArg) - ) +predicate execTainted( + RemoteUserInputToArgumentToExecFlow::PathNode source, + RemoteUserInputToArgumentToExecFlow::PathNode sink, ArgumentToExec execArg +) { + RemoteUserInputToArgumentToExecFlow::hasFlowPath(source, sink) and + sink.getNode() = DataFlow::exprNode(execArg) } diff --git a/java/ql/src/Security/CWE/CWE-078/ExecTainted.ql b/java/ql/src/Security/CWE/CWE-078/ExecTainted.ql index 4c275f1cacd..1bd9a6b51af 100644 --- a/java/ql/src/Security/CWE/CWE-078/ExecTainted.ql +++ b/java/ql/src/Security/CWE/CWE-078/ExecTainted.ql @@ -16,9 +16,11 @@ import java import semmle.code.java.dataflow.FlowSources import semmle.code.java.security.ExternalProcess import semmle.code.java.security.CommandLineQuery -import DataFlow::PathGraph +import RemoteUserInputToArgumentToExecFlow::PathGraph -from DataFlow::PathNode source, DataFlow::PathNode sink, ArgumentToExec execArg +from + RemoteUserInputToArgumentToExecFlow::PathNode source, + RemoteUserInputToArgumentToExecFlow::PathNode sink, ArgumentToExec execArg where execTainted(source, sink, execArg) select execArg, source, sink, "This command line depends on a $@.", source.getNode(), "user-provided value" diff --git a/java/ql/src/experimental/Security/CWE/CWE-078/ExecTainted.ql b/java/ql/src/experimental/Security/CWE/CWE-078/ExecTainted.ql index e672519d1c7..98241a527a1 100644 --- a/java/ql/src/experimental/Security/CWE/CWE-078/ExecTainted.ql +++ b/java/ql/src/experimental/Security/CWE/CWE-078/ExecTainted.ql @@ -17,10 +17,12 @@ import semmle.code.java.dataflow.FlowSources import semmle.code.java.security.ExternalProcess import semmle.code.java.security.CommandLineQuery import JSchOSInjection -import DataFlow::PathGraph +import RemoteUserInputToArgumentToExecFlow::PathGraph // This is a clone of query `java/command-line-injection` that also includes experimental sinks. -from DataFlow::PathNode source, DataFlow::PathNode sink, ArgumentToExec execArg +from + RemoteUserInputToArgumentToExecFlow::PathNode source, + RemoteUserInputToArgumentToExecFlow::PathNode sink, ArgumentToExec execArg where execTainted(source, sink, execArg) select execArg, source, sink, "This command line depends on a $@.", source.getNode(), "user-provided value" From bbf7c67f9b73b0053e25f541fa3474d408b6276d Mon Sep 17 00:00:00 2001 From: Ed Minnix <egregius313@github.com> Date: Tue, 28 Mar 2023 11:34:22 -0400 Subject: [PATCH 621/631] Remove unnecessary `private` markers (CommandLine and Request forgery) --- java/ql/lib/semmle/code/java/security/CommandLineQuery.qll | 2 +- java/ql/lib/semmle/code/java/security/RequestForgeryConfig.qll | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/java/ql/lib/semmle/code/java/security/CommandLineQuery.qll b/java/ql/lib/semmle/code/java/security/CommandLineQuery.qll index adc8148a8ff..0cf28810c2d 100644 --- a/java/ql/lib/semmle/code/java/security/CommandLineQuery.qll +++ b/java/ql/lib/semmle/code/java/security/CommandLineQuery.qll @@ -37,7 +37,7 @@ deprecated class RemoteUserInputToArgumentToExecFlowConfig extends TaintTracking /** * A taint-tracking configuration for unvalidated user input that is used to run an external process. */ -private module RemoteUserInputToArgumentToExecFlowConfig implements DataFlow::ConfigSig { +module RemoteUserInputToArgumentToExecFlowConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node src) { src instanceof RemoteFlowSource } predicate isSink(DataFlow::Node sink) { sink.asExpr() instanceof ArgumentToExec } diff --git a/java/ql/lib/semmle/code/java/security/RequestForgeryConfig.qll b/java/ql/lib/semmle/code/java/security/RequestForgeryConfig.qll index 9d1f9b5081e..0e3afacb83f 100644 --- a/java/ql/lib/semmle/code/java/security/RequestForgeryConfig.qll +++ b/java/ql/lib/semmle/code/java/security/RequestForgeryConfig.qll @@ -35,7 +35,7 @@ deprecated class RequestForgeryConfiguration extends TaintTracking::Configuratio /** * A taint-tracking configuration characterising request-forgery risks. */ -private module RequestForgeryConfig implements DataFlow::ConfigSig { +module RequestForgeryConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource and // Exclude results of remote HTTP requests: fetching something else based on that result From dcd703f1a93299ba51de51a259d744e5b6bd7ded Mon Sep 17 00:00:00 2001 From: Ed Minnix <egregius313@github.com> Date: Tue, 28 Mar 2023 13:04:39 -0400 Subject: [PATCH 622/631] Update to the `TaintTracking::Global` api --- java/ql/lib/semmle/code/java/security/CommandLineQuery.qll | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/java/ql/lib/semmle/code/java/security/CommandLineQuery.qll b/java/ql/lib/semmle/code/java/security/CommandLineQuery.qll index 0cf28810c2d..d496c2f9425 100644 --- a/java/ql/lib/semmle/code/java/security/CommandLineQuery.qll +++ b/java/ql/lib/semmle/code/java/security/CommandLineQuery.qll @@ -52,7 +52,7 @@ module RemoteUserInputToArgumentToExecFlowConfig implements DataFlow::ConfigSig } module RemoteUserInputToArgumentToExecFlow = - TaintTracking::Make<RemoteUserInputToArgumentToExecFlowConfig>; + TaintTracking::Global<RemoteUserInputToArgumentToExecFlowConfig>; /** * Implementation of `ExecTainted.ql`. It is extracted to a QLL @@ -63,6 +63,6 @@ predicate execTainted( RemoteUserInputToArgumentToExecFlow::PathNode source, RemoteUserInputToArgumentToExecFlow::PathNode sink, ArgumentToExec execArg ) { - RemoteUserInputToArgumentToExecFlow::hasFlowPath(source, sink) and + RemoteUserInputToArgumentToExecFlow::flowPath(source, sink) and sink.getNode() = DataFlow::exprNode(execArg) } From 25359d22183fa297634a713626241168ff9b5c4d Mon Sep 17 00:00:00 2001 From: Ed Minnix <egregius313@github.com> Date: Tue, 28 Mar 2023 13:18:48 -0400 Subject: [PATCH 623/631] Deprecate `execTainted` --- .../2023-03-28-deprecated-exectainted.md | 5 +++++ .../code/java/security/CommandLineQuery.qll | 17 ++++++++++++++++- java/ql/src/Security/CWE/CWE-078/ExecTainted.ql | 2 +- .../Security/CWE/CWE-078/ExecTainted.ql | 2 +- 4 files changed, 23 insertions(+), 3 deletions(-) create mode 100644 java/ql/lib/change-notes/2023-03-28-deprecated-exectainted.md diff --git a/java/ql/lib/change-notes/2023-03-28-deprecated-exectainted.md b/java/ql/lib/change-notes/2023-03-28-deprecated-exectainted.md new file mode 100644 index 00000000000..abe4eaf4bad --- /dev/null +++ b/java/ql/lib/change-notes/2023-03-28-deprecated-exectainted.md @@ -0,0 +1,5 @@ +--- +category: deprecated +--- +* The `execTainted` predicate in `CommandLineQuery.qll` has been deprecated and replaced with the predicate `execIsTainted`. + diff --git a/java/ql/lib/semmle/code/java/security/CommandLineQuery.qll b/java/ql/lib/semmle/code/java/security/CommandLineQuery.qll index d496c2f9425..7fa93e560ec 100644 --- a/java/ql/lib/semmle/code/java/security/CommandLineQuery.qll +++ b/java/ql/lib/semmle/code/java/security/CommandLineQuery.qll @@ -55,11 +55,26 @@ module RemoteUserInputToArgumentToExecFlow = TaintTracking::Global<RemoteUserInputToArgumentToExecFlowConfig>; /** + * DEPRECATED: Use `execIsTainted` instead. + * * Implementation of `ExecTainted.ql`. It is extracted to a QLL * so that it can be excluded from `ExecUnescaped.ql` to avoid * reporting overlapping results. */ -predicate execTainted( +deprecated predicate execTainted( + DataFlow::PathNode source, DataFlow::PathNode sink, ArgumentToExec execArg +) { + exists(RemoteUserInputToArgumentToExecFlowConfig conf | + conf.hasFlowPath(source, sink) and sink.getNode() = DataFlow::exprNode(execArg) + ) +} + +/** + * Implementation of `ExecTainted.ql`. It is extracted to a QLL + * so that it can be excluded from `ExecUnescaped.ql` to avoid + * reporting overlapping results. + */ +predicate execIsTainted( RemoteUserInputToArgumentToExecFlow::PathNode source, RemoteUserInputToArgumentToExecFlow::PathNode sink, ArgumentToExec execArg ) { diff --git a/java/ql/src/Security/CWE/CWE-078/ExecTainted.ql b/java/ql/src/Security/CWE/CWE-078/ExecTainted.ql index 1bd9a6b51af..d631c52201a 100644 --- a/java/ql/src/Security/CWE/CWE-078/ExecTainted.ql +++ b/java/ql/src/Security/CWE/CWE-078/ExecTainted.ql @@ -21,6 +21,6 @@ import RemoteUserInputToArgumentToExecFlow::PathGraph from RemoteUserInputToArgumentToExecFlow::PathNode source, RemoteUserInputToArgumentToExecFlow::PathNode sink, ArgumentToExec execArg -where execTainted(source, sink, execArg) +where execIsTainted(source, sink, execArg) select execArg, source, sink, "This command line depends on a $@.", source.getNode(), "user-provided value" diff --git a/java/ql/src/experimental/Security/CWE/CWE-078/ExecTainted.ql b/java/ql/src/experimental/Security/CWE/CWE-078/ExecTainted.ql index 98241a527a1..45fa0982b25 100644 --- a/java/ql/src/experimental/Security/CWE/CWE-078/ExecTainted.ql +++ b/java/ql/src/experimental/Security/CWE/CWE-078/ExecTainted.ql @@ -23,6 +23,6 @@ import RemoteUserInputToArgumentToExecFlow::PathGraph from RemoteUserInputToArgumentToExecFlow::PathNode source, RemoteUserInputToArgumentToExecFlow::PathNode sink, ArgumentToExec execArg -where execTainted(source, sink, execArg) +where execIsTainted(source, sink, execArg) select execArg, source, sink, "This command line depends on a $@.", source.getNode(), "user-provided value" From a3c1d08a59fdb42f62816a821f6815a503a1bcfa Mon Sep 17 00:00:00 2001 From: Ed Minnix <egregius313@github.com> Date: Tue, 28 Mar 2023 13:22:33 -0400 Subject: [PATCH 624/631] Fix ExecUnescaped --- java/ql/src/Security/CWE/CWE-078/ExecUnescaped.ql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/ql/src/Security/CWE/CWE-078/ExecUnescaped.ql b/java/ql/src/Security/CWE/CWE-078/ExecUnescaped.ql index 0890b3b6021..761b497ef77 100644 --- a/java/ql/src/Security/CWE/CWE-078/ExecUnescaped.ql +++ b/java/ql/src/Security/CWE/CWE-078/ExecUnescaped.ql @@ -48,5 +48,5 @@ predicate builtFromUncontrolledConcat(Expr expr) { from StringArgumentToExec argument where builtFromUncontrolledConcat(argument) and - not execTainted(_, _, argument) + not execIsTainted(_, _, argument) select argument, "Command line is built with string concatenation." From 744f2653f06169609349253a2416f54f0240a16a Mon Sep 17 00:00:00 2001 From: Ed Minnix <egregius313@github.com> Date: Wed, 29 Mar 2023 11:04:03 -0400 Subject: [PATCH 625/631] Add QLdoc for RemoteUserInputToArgumentToExecFlow --- java/ql/lib/semmle/code/java/security/CommandLineQuery.qll | 3 +++ 1 file changed, 3 insertions(+) diff --git a/java/ql/lib/semmle/code/java/security/CommandLineQuery.qll b/java/ql/lib/semmle/code/java/security/CommandLineQuery.qll index 7fa93e560ec..1f2d9c12b98 100644 --- a/java/ql/lib/semmle/code/java/security/CommandLineQuery.qll +++ b/java/ql/lib/semmle/code/java/security/CommandLineQuery.qll @@ -51,6 +51,9 @@ module RemoteUserInputToArgumentToExecFlowConfig implements DataFlow::ConfigSig } } +/** + * Taint-tracking flow for unvalidated user input that is used to run an external process. + */ module RemoteUserInputToArgumentToExecFlow = TaintTracking::Global<RemoteUserInputToArgumentToExecFlowConfig>; From ade02d80cf4964cd6ef0eee30ea3b1f613f990ce Mon Sep 17 00:00:00 2001 From: Jeroen Ketema <jketema@github.com> Date: Thu, 30 Mar 2023 09:00:44 +0200 Subject: [PATCH 626/631] C++: Match `SemZeroBound` handling of mul case in rem case --- .../semantic/analysis/RangeAnalysisStage.qll | 21 +++++++++++-------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/cpp/ql/lib/experimental/semmle/code/cpp/semantic/analysis/RangeAnalysisStage.qll b/cpp/ql/lib/experimental/semmle/code/cpp/semantic/analysis/RangeAnalysisStage.qll index d70c59d168f..cf5f1c5ee74 100644 --- a/cpp/ql/lib/experimental/semmle/code/cpp/semantic/analysis/RangeAnalysisStage.qll +++ b/cpp/ql/lib/experimental/semmle/code/cpp/semantic/analysis/RangeAnalysisStage.qll @@ -1041,20 +1041,21 @@ module RangeStage<DeltaSig D, BoundSig<D> Bounds, LangSig<D> LangParam, UtilSig< ) or exists( - SemRemExpr rem, SemZeroBound b1, SemZeroBound b2, D::Delta d_max, D::Delta d1, D::Delta d2, - boolean fbe1, boolean fbe2, D::Delta od1, D::Delta od2, SemReason r1, SemReason r2 + SemRemExpr rem, D::Delta d_max, D::Delta d1, D::Delta d2, boolean fbe1, boolean fbe2, + D::Delta od1, D::Delta od2, SemReason r1, SemReason r2 | rem = e and + b instanceof SemZeroBound and not (upper = true and semPositive(rem.getRightOperand())) and not (upper = true and semPositive(rem.getLeftOperand())) and - boundedRemExpr(rem, b1, true, d1, fbe1, od1, r1) and - boundedRemExpr(rem, b2, false, d2, fbe2, od2, r2) and + boundedRemExpr(rem, true, d1, fbe1, od1, r1) and + boundedRemExpr(rem, false, d2, fbe2, od2, r2) and ( if D::toFloat(d1).abs() > D::toFloat(d2).abs() then ( - b = b1 and d_max = d1 and fromBackEdge = fbe1 and origdelta = od1 and reason = r1 + d_max = d1 and fromBackEdge = fbe1 and origdelta = od1 and reason = r1 ) else ( - b = b2 and d_max = d2 and fromBackEdge = fbe2 and origdelta = od2 and reason = r2 + d_max = d2 and fromBackEdge = fbe2 and origdelta = od2 and reason = r2 ) ) | @@ -1103,11 +1104,13 @@ module RangeStage<DeltaSig D, BoundSig<D> Bounds, LangSig<D> LangParam, UtilSig< ) } + pragma[nomagic] private predicate boundedRemExpr( - SemRemExpr rem, SemZeroBound b, boolean upper, D::Delta delta, boolean fromBackEdge, - D::Delta origdelta, SemReason reason + SemRemExpr rem, boolean upper, D::Delta delta, boolean fromBackEdge, D::Delta origdelta, + SemReason reason ) { - bounded(rem.getRightOperand(), b, delta, upper, fromBackEdge, origdelta, reason) + bounded(rem.getRightOperand(), any(SemZeroBound zb), delta, upper, fromBackEdge, origdelta, + reason) } /** From 31e352afb03deccf0e8b502574a41bb6dca321e2 Mon Sep 17 00:00:00 2001 From: Michael Nebel <michaelnebel@github.com> Date: Thu, 30 Mar 2023 09:45:49 +0200 Subject: [PATCH 627/631] C#: Actually add the deprecated keyword to the deprecated classes. --- .../security/cryptography/HardcodedSymmetricEncryptionKey.qll | 2 +- .../semmle/code/csharp/security/dataflow/CodeInjectionQuery.qll | 2 +- .../code/csharp/security/dataflow/CommandInjectionQuery.qll | 2 +- .../code/csharp/security/dataflow/ConditionalBypassQuery.qll | 2 +- .../security/dataflow/ExposureOfPrivateInformationQuery.qll | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/csharp/ql/lib/semmle/code/csharp/security/cryptography/HardcodedSymmetricEncryptionKey.qll b/csharp/ql/lib/semmle/code/csharp/security/cryptography/HardcodedSymmetricEncryptionKey.qll index d00cef763df..9fdc6dc88be 100644 --- a/csharp/ql/lib/semmle/code/csharp/security/cryptography/HardcodedSymmetricEncryptionKey.qll +++ b/csharp/ql/lib/semmle/code/csharp/security/cryptography/HardcodedSymmetricEncryptionKey.qll @@ -66,7 +66,7 @@ module HardcodedSymmetricEncryptionKey { * * A taint-tracking configuration for uncontrolled data in path expression vulnerabilities. */ - class TaintTrackingConfiguration extends TaintTracking::Configuration { + deprecated class TaintTrackingConfiguration extends TaintTracking::Configuration { TaintTrackingConfiguration() { this = "HardcodedSymmetricEncryptionKey" } override predicate isSource(DataFlow::Node source) { source instanceof Source } diff --git a/csharp/ql/lib/semmle/code/csharp/security/dataflow/CodeInjectionQuery.qll b/csharp/ql/lib/semmle/code/csharp/security/dataflow/CodeInjectionQuery.qll index 0ae163c773e..76a9a495637 100644 --- a/csharp/ql/lib/semmle/code/csharp/security/dataflow/CodeInjectionQuery.qll +++ b/csharp/ql/lib/semmle/code/csharp/security/dataflow/CodeInjectionQuery.qll @@ -29,7 +29,7 @@ abstract class Sanitizer extends DataFlow::ExprNode { } * * A taint-tracking configuration for user input treated as code vulnerabilities. */ -class TaintTrackingConfiguration extends TaintTracking::Configuration { +deprecated class TaintTrackingConfiguration extends TaintTracking::Configuration { TaintTrackingConfiguration() { this = "CodeInjection" } override predicate isSource(DataFlow::Node source) { source instanceof Source } diff --git a/csharp/ql/lib/semmle/code/csharp/security/dataflow/CommandInjectionQuery.qll b/csharp/ql/lib/semmle/code/csharp/security/dataflow/CommandInjectionQuery.qll index 4eabf16e7a5..265cae5f08a 100644 --- a/csharp/ql/lib/semmle/code/csharp/security/dataflow/CommandInjectionQuery.qll +++ b/csharp/ql/lib/semmle/code/csharp/security/dataflow/CommandInjectionQuery.qll @@ -27,7 +27,7 @@ abstract class Sanitizer extends DataFlow::ExprNode { } * * A taint-tracking configuration for command injection vulnerabilities. */ -class TaintTrackingConfiguration extends TaintTracking::Configuration { +deprecated class TaintTrackingConfiguration extends TaintTracking::Configuration { TaintTrackingConfiguration() { this = "CommandInjection" } override predicate isSource(DataFlow::Node source) { source instanceof Source } diff --git a/csharp/ql/lib/semmle/code/csharp/security/dataflow/ConditionalBypassQuery.qll b/csharp/ql/lib/semmle/code/csharp/security/dataflow/ConditionalBypassQuery.qll index 9d52e623e66..e919684d751 100644 --- a/csharp/ql/lib/semmle/code/csharp/security/dataflow/ConditionalBypassQuery.qll +++ b/csharp/ql/lib/semmle/code/csharp/security/dataflow/ConditionalBypassQuery.qll @@ -34,7 +34,7 @@ abstract class Sanitizer extends DataFlow::ExprNode { } * * A taint-tracking configuration for user-controlled bypass of sensitive method. */ -class Configuration extends TaintTracking::Configuration { +deprecated class Configuration extends TaintTracking::Configuration { Configuration() { this = "UserControlledBypassOfSensitiveMethodConfiguration" } override predicate isSource(DataFlow::Node source) { source instanceof Source } diff --git a/csharp/ql/lib/semmle/code/csharp/security/dataflow/ExposureOfPrivateInformationQuery.qll b/csharp/ql/lib/semmle/code/csharp/security/dataflow/ExposureOfPrivateInformationQuery.qll index b1ea7c7b09c..0b53d9d1ca6 100644 --- a/csharp/ql/lib/semmle/code/csharp/security/dataflow/ExposureOfPrivateInformationQuery.qll +++ b/csharp/ql/lib/semmle/code/csharp/security/dataflow/ExposureOfPrivateInformationQuery.qll @@ -27,7 +27,7 @@ abstract class Sanitizer extends DataFlow::ExprNode { } * * A taint-tracking configuration for private information flowing unencrypted to an external location. */ -class TaintTrackingConfiguration extends TaintTracking::Configuration { +deprecated class TaintTrackingConfiguration extends TaintTracking::Configuration { TaintTrackingConfiguration() { this = "ExposureOfPrivateInformation" } override predicate isSource(DataFlow::Node source) { source instanceof Source } From f3937a4a12c81b8974a706c53c3715cdd56e0149 Mon Sep 17 00:00:00 2001 From: Rasmus Wriedt Larsen <rasmuswl@github.com> Date: Thu, 30 Mar 2023 10:17:33 +0200 Subject: [PATCH 628/631] Python: Update .expected from PostUpdateNode commit --- ...sageOfClientSideEncryptionVersion.expected | 30 +++++++++---------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/python/ql/test/experimental/query-tests/Security/CWE-327-UnsafeUsageOfClientSideEncryptionVersion/UnsafeUsageOfClientSideEncryptionVersion.expected b/python/ql/test/experimental/query-tests/Security/CWE-327-UnsafeUsageOfClientSideEncryptionVersion/UnsafeUsageOfClientSideEncryptionVersion.expected index 01a5f39bec5..12dfeafb931 100644 --- a/python/ql/test/experimental/query-tests/Security/CWE-327-UnsafeUsageOfClientSideEncryptionVersion/UnsafeUsageOfClientSideEncryptionVersion.expected +++ b/python/ql/test/experimental/query-tests/Security/CWE-327-UnsafeUsageOfClientSideEncryptionVersion/UnsafeUsageOfClientSideEncryptionVersion.expected @@ -6,24 +6,24 @@ edges | test.py:3:7:3:51 | ControlFlowNode for Attribute() | test.py:3:1:3:3 | GSSA Variable BSC | | test.py:7:19:7:21 | ControlFlowNode for BSC | test.py:8:5:8:15 | ControlFlowNode for blob_client | | test.py:8:5:8:15 | ControlFlowNode for blob_client | test.py:9:5:9:15 | ControlFlowNode for blob_client | -| test.py:9:5:9:15 | ControlFlowNode for blob_client | test.py:9:5:9:15 | ControlFlowNode for blob_client | -| test.py:9:5:9:15 | ControlFlowNode for blob_client | test.py:11:9:11:19 | ControlFlowNode for blob_client | +| test.py:9:5:9:15 | ControlFlowNode for blob_client | test.py:9:5:9:15 | [post] ControlFlowNode for blob_client | +| test.py:9:5:9:15 | [post] ControlFlowNode for blob_client | test.py:11:9:11:19 | ControlFlowNode for blob_client | | test.py:15:27:15:71 | ControlFlowNode for Attribute() | test.py:16:5:16:23 | ControlFlowNode for blob_service_client | | test.py:16:5:16:23 | ControlFlowNode for blob_service_client | test.py:17:5:17:23 | ControlFlowNode for blob_service_client | -| test.py:17:5:17:23 | ControlFlowNode for blob_service_client | test.py:17:5:17:23 | ControlFlowNode for blob_service_client | -| test.py:17:5:17:23 | ControlFlowNode for blob_service_client | test.py:21:9:21:19 | ControlFlowNode for blob_client | +| test.py:17:5:17:23 | ControlFlowNode for blob_service_client | test.py:17:5:17:23 | [post] ControlFlowNode for blob_service_client | +| test.py:17:5:17:23 | [post] ControlFlowNode for blob_service_client | test.py:21:9:21:19 | ControlFlowNode for blob_client | | test.py:25:24:25:66 | ControlFlowNode for Attribute() | test.py:26:5:26:20 | ControlFlowNode for container_client | | test.py:26:5:26:20 | ControlFlowNode for container_client | test.py:27:5:27:20 | ControlFlowNode for container_client | -| test.py:27:5:27:20 | ControlFlowNode for container_client | test.py:27:5:27:20 | ControlFlowNode for container_client | -| test.py:27:5:27:20 | ControlFlowNode for container_client | test.py:31:9:31:19 | ControlFlowNode for blob_client | +| test.py:27:5:27:20 | ControlFlowNode for container_client | test.py:27:5:27:20 | [post] ControlFlowNode for container_client | +| test.py:27:5:27:20 | [post] ControlFlowNode for container_client | test.py:31:9:31:19 | ControlFlowNode for blob_client | | test.py:35:19:35:21 | ControlFlowNode for BSC | test.py:36:5:36:15 | ControlFlowNode for blob_client | | test.py:36:5:36:15 | ControlFlowNode for blob_client | test.py:37:5:37:15 | ControlFlowNode for blob_client | -| test.py:37:5:37:15 | ControlFlowNode for blob_client | test.py:37:5:37:15 | ControlFlowNode for blob_client | -| test.py:37:5:37:15 | ControlFlowNode for blob_client | test.py:43:9:43:19 | ControlFlowNode for blob_client | +| test.py:37:5:37:15 | ControlFlowNode for blob_client | test.py:37:5:37:15 | [post] ControlFlowNode for blob_client | +| test.py:37:5:37:15 | [post] ControlFlowNode for blob_client | test.py:43:9:43:19 | ControlFlowNode for blob_client | | test.py:66:19:66:21 | ControlFlowNode for BSC | test.py:67:5:67:15 | ControlFlowNode for blob_client | | test.py:67:5:67:15 | ControlFlowNode for blob_client | test.py:68:5:68:15 | ControlFlowNode for blob_client | -| test.py:68:5:68:15 | ControlFlowNode for blob_client | test.py:68:5:68:15 | ControlFlowNode for blob_client | -| test.py:68:5:68:15 | ControlFlowNode for blob_client | test.py:69:12:69:22 | ControlFlowNode for blob_client | +| test.py:68:5:68:15 | ControlFlowNode for blob_client | test.py:68:5:68:15 | [post] ControlFlowNode for blob_client | +| test.py:68:5:68:15 | [post] ControlFlowNode for blob_client | test.py:69:12:69:22 | ControlFlowNode for blob_client | | test.py:69:12:69:22 | ControlFlowNode for blob_client | test.py:73:10:73:33 | ControlFlowNode for get_unsafe_blob_client() | | test.py:73:10:73:33 | ControlFlowNode for get_unsafe_blob_client() | test.py:75:9:75:10 | ControlFlowNode for bc | nodes @@ -33,27 +33,27 @@ nodes | test.py:7:19:7:21 | ControlFlowNode for BSC | semmle.label | ControlFlowNode for BSC | | test.py:8:5:8:15 | ControlFlowNode for blob_client | semmle.label | ControlFlowNode for blob_client | | test.py:9:5:9:15 | ControlFlowNode for blob_client | semmle.label | ControlFlowNode for blob_client | -| test.py:9:5:9:15 | ControlFlowNode for blob_client | semmle.label | ControlFlowNode for blob_client | +| test.py:9:5:9:15 | [post] ControlFlowNode for blob_client | semmle.label | [post] ControlFlowNode for blob_client | | test.py:11:9:11:19 | ControlFlowNode for blob_client | semmle.label | ControlFlowNode for blob_client | | test.py:15:27:15:71 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | | test.py:16:5:16:23 | ControlFlowNode for blob_service_client | semmle.label | ControlFlowNode for blob_service_client | | test.py:17:5:17:23 | ControlFlowNode for blob_service_client | semmle.label | ControlFlowNode for blob_service_client | -| test.py:17:5:17:23 | ControlFlowNode for blob_service_client | semmle.label | ControlFlowNode for blob_service_client | +| test.py:17:5:17:23 | [post] ControlFlowNode for blob_service_client | semmle.label | [post] ControlFlowNode for blob_service_client | | test.py:21:9:21:19 | ControlFlowNode for blob_client | semmle.label | ControlFlowNode for blob_client | | test.py:25:24:25:66 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | | test.py:26:5:26:20 | ControlFlowNode for container_client | semmle.label | ControlFlowNode for container_client | | test.py:27:5:27:20 | ControlFlowNode for container_client | semmle.label | ControlFlowNode for container_client | -| test.py:27:5:27:20 | ControlFlowNode for container_client | semmle.label | ControlFlowNode for container_client | +| test.py:27:5:27:20 | [post] ControlFlowNode for container_client | semmle.label | [post] ControlFlowNode for container_client | | test.py:31:9:31:19 | ControlFlowNode for blob_client | semmle.label | ControlFlowNode for blob_client | | test.py:35:19:35:21 | ControlFlowNode for BSC | semmle.label | ControlFlowNode for BSC | | test.py:36:5:36:15 | ControlFlowNode for blob_client | semmle.label | ControlFlowNode for blob_client | | test.py:37:5:37:15 | ControlFlowNode for blob_client | semmle.label | ControlFlowNode for blob_client | -| test.py:37:5:37:15 | ControlFlowNode for blob_client | semmle.label | ControlFlowNode for blob_client | +| test.py:37:5:37:15 | [post] ControlFlowNode for blob_client | semmle.label | [post] ControlFlowNode for blob_client | | test.py:43:9:43:19 | ControlFlowNode for blob_client | semmle.label | ControlFlowNode for blob_client | | test.py:66:19:66:21 | ControlFlowNode for BSC | semmle.label | ControlFlowNode for BSC | | test.py:67:5:67:15 | ControlFlowNode for blob_client | semmle.label | ControlFlowNode for blob_client | | test.py:68:5:68:15 | ControlFlowNode for blob_client | semmle.label | ControlFlowNode for blob_client | -| test.py:68:5:68:15 | ControlFlowNode for blob_client | semmle.label | ControlFlowNode for blob_client | +| test.py:68:5:68:15 | [post] ControlFlowNode for blob_client | semmle.label | [post] ControlFlowNode for blob_client | | test.py:69:12:69:22 | ControlFlowNode for blob_client | semmle.label | ControlFlowNode for blob_client | | test.py:73:10:73:33 | ControlFlowNode for get_unsafe_blob_client() | semmle.label | ControlFlowNode for get_unsafe_blob_client() | | test.py:75:9:75:10 | ControlFlowNode for bc | semmle.label | ControlFlowNode for bc | From 64a08cefd781d2bc5af7ae2fd8fde2f7085c3473 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen <mathiasvp@github.com> Date: Thu, 30 Mar 2023 09:37:27 +0100 Subject: [PATCH 629/631] C++: Add change note. --- cpp/ql/lib/change-notes/2023-03-30-bufferaccess.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 cpp/ql/lib/change-notes/2023-03-30-bufferaccess.md diff --git a/cpp/ql/lib/change-notes/2023-03-30-bufferaccess.md b/cpp/ql/lib/change-notes/2023-03-30-bufferaccess.md new file mode 100644 index 00000000000..1cd611501be --- /dev/null +++ b/cpp/ql/lib/change-notes/2023-03-30-bufferaccess.md @@ -0,0 +1,4 @@ +--- +category: feature +--- +* Added overridable predicates `getSizeExpr` and `getSizeMult` to the `BufferAccess` class (`semmle.code.cpp.security.BufferAccess.qll`). This makes it possible to model a larger class of buffer reads and writes using the library. \ No newline at end of file From 4602a8ae4af73414a8a2e67736bfe9e5e64ec81d Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen <mathiasvp@github.com> Date: Thu, 30 Mar 2023 11:16:54 +0100 Subject: [PATCH 630/631] C++: Simplify 'converts'. --- .../code/cpp/semantic/SemanticExprSpecific.qll | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/cpp/ql/lib/experimental/semmle/code/cpp/semantic/SemanticExprSpecific.qll b/cpp/ql/lib/experimental/semmle/code/cpp/semantic/SemanticExprSpecific.qll index f12466b4785..5e97a50a6af 100644 --- a/cpp/ql/lib/experimental/semmle/code/cpp/semantic/SemanticExprSpecific.qll +++ b/cpp/ql/lib/experimental/semmle/code/cpp/semantic/SemanticExprSpecific.qll @@ -22,17 +22,8 @@ module SemanticExprConfig { /** Holds if this instruction converts a value of type `tFrom` to a value of type `tTo`. */ predicate converts(SemType tFrom, SemType tTo) { - exists(IR::ConvertInstruction convert | - this = convert and - tFrom = getSemanticType(convert.getUnary().getResultIRType()) and - tTo = getSemanticType(convert.getResultIRType()) - ) - or - exists(IR::CopyValueInstruction copy | - this = copy and - tFrom = getSemanticType(copy.getUnary().getResultIRType()) and - tTo = getSemanticType(copy.getResultIRType()) - ) + tFrom = getSemanticType(this.getUnary().getResultIRType()) and + tTo = getSemanticType(this.getResultIRType()) } } From d9b2a722329e1b7f357f489901e970310803eef8 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen <mathiasvp@github.com> Date: Thu, 30 Mar 2023 11:22:24 +0100 Subject: [PATCH 631/631] C++: Ensure that equiv instructions are in the same block. --- .../semmle/code/cpp/semantic/SemanticExprSpecific.qll | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cpp/ql/lib/experimental/semmle/code/cpp/semantic/SemanticExprSpecific.qll b/cpp/ql/lib/experimental/semmle/code/cpp/semantic/SemanticExprSpecific.qll index 5e97a50a6af..0b3249a3013 100644 --- a/cpp/ql/lib/experimental/semmle/code/cpp/semantic/SemanticExprSpecific.qll +++ b/cpp/ql/lib/experimental/semmle/code/cpp/semantic/SemanticExprSpecific.qll @@ -46,7 +46,8 @@ module SemanticExprConfig { ( i1 = i2 or - i2 = safeConversion(i1.getAUse()) + i2 = safeConversion(i1.getAUse()) and + i1.getBlock() = i2.getBlock() ) }