diff --git a/.bazelversion b/.bazelversion index 0e79152459e..e7fdef7e2e6 100644 --- a/.bazelversion +++ b/.bazelversion @@ -1 +1 @@ -8.1.1 +8.4.2 diff --git a/cpp/ql/src/Security/CWE/CWE-020/ExternalAPIs.qll b/cpp/ql/src/Security/CWE/CWE-020/ExternalAPIs.qll index 51dad0fc18c..74fe756093c 100644 --- a/cpp/ql/src/Security/CWE/CWE-020/ExternalAPIs.qll +++ b/cpp/ql/src/Security/CWE/CWE-020/ExternalAPIs.qll @@ -10,7 +10,7 @@ import ExternalAPIsSpecific /** A node representing untrusted data being passed to an external API. */ class UntrustedExternalApiDataNode extends ExternalApiDataNode { - UntrustedExternalApiDataNode() { UntrustedDataToExternalApiFlow::flow(_, this) } + UntrustedExternalApiDataNode() { UntrustedDataToExternalApiFlow::flowTo(this) } /** Gets a source of untrusted data which is passed to this external API data node. */ DataFlow::Node getAnUntrustedSource() { UntrustedDataToExternalApiFlow::flow(result, this) } 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 51dad0fc18c..74fe756093c 100644 --- a/cpp/ql/src/Security/CWE/CWE-020/ir/ExternalAPIs.qll +++ b/cpp/ql/src/Security/CWE/CWE-020/ir/ExternalAPIs.qll @@ -10,7 +10,7 @@ import ExternalAPIsSpecific /** A node representing untrusted data being passed to an external API. */ class UntrustedExternalApiDataNode extends ExternalApiDataNode { - UntrustedExternalApiDataNode() { UntrustedDataToExternalApiFlow::flow(_, this) } + UntrustedExternalApiDataNode() { UntrustedDataToExternalApiFlow::flowTo(this) } /** Gets a source of untrusted data which is passed to this external API data node. */ DataFlow::Node getAnUntrustedSource() { UntrustedDataToExternalApiFlow::flow(result, this) } diff --git a/cpp/ql/src/Security/CWE/CWE-311/CleartextTransmission.ql b/cpp/ql/src/Security/CWE/CWE-311/CleartextTransmission.ql index 01d078cf545..392650022e2 100644 --- a/cpp/ql/src/Security/CWE/CWE-311/CleartextTransmission.ql +++ b/cpp/ql/src/Security/CWE/CWE-311/CleartextTransmission.ql @@ -263,7 +263,7 @@ module FromSensitiveFlow = TaintTracking::Global; * 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::flow(source, _) } + predicate isSource(DataFlow::Node source) { FromSensitiveFlow::flowFrom(source) } predicate isSink(DataFlow::Node sink) { isSinkEncrypt(sink, _) } @@ -311,7 +311,7 @@ where FromSensitiveFlow::flowPath(source, sink) and isSinkSendRecv(sink.getNode(), networkSendRecv) and // no flow from sensitive -> evidence of encryption - not ToEncryptionFlow::flow(source.getNode(), _) and + not ToEncryptionFlow::flowFrom(source.getNode()) and not FromEncryptionFlow::flowTo(sink.getNode()) and // construct result if networkSendRecv instanceof NetworkSend 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 58f5dc2ade4..003c4f27f49 100644 --- a/cpp/ql/src/experimental/Security/CWE/CWE-193/ConstantSizeArrayOffByOne.ql +++ b/cpp/ql/src/experimental/Security/CWE/CWE-193/ConstantSizeArrayOffByOne.ql @@ -129,7 +129,7 @@ module PointerArithmeticToDerefFlow = DataFlow::Global dotNetPath is not null ? actions.PathCombine(dotNetPath, "dotnet") : "dotnet"; - private static BuildScript GetInfoCommand(IBuildActions actions, string? dotNetPath, IDictionary? environment) - { - var info = new CommandBuilder(actions, null, environment). - RunCommand(DotNetCommand(actions, dotNetPath)). - Argument("--info"); - return info.Script; - } - private static CommandBuilder GetCleanCommand(IBuildActions actions, string? dotNetPath, IDictionary? environment) { var clean = new CommandBuilder(actions, null, environment). diff --git a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DotNet.cs b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DotNet.cs index 7bc79238415..635b901397b 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DotNet.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DotNet.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Collections.ObjectModel; using System.IO; using System.Linq; +using System.Threading; using Newtonsoft.Json.Linq; using Semmle.Util; @@ -36,12 +37,29 @@ namespace Semmle.Extraction.CSharp.DependencyFetching public static IDotNet Make(ILogger logger, string? dotNetPath, TemporaryDirectory tempWorkingDirectory, DependabotProxy? dependabotProxy) => new DotNet(logger, dotNetPath, tempWorkingDirectory, dependabotProxy); + private static void HandleRetryExitCode143(string dotnet, int attempt, ILogger logger) + { + logger.LogWarning($"Running '{dotnet} --info' failed with exit code 143. Retrying..."); + var sleep = Math.Pow(2, attempt) * 1000; + Thread.Sleep((int)sleep); + } + private void Info() { - var res = dotnetCliInvoker.RunCommand("--info", silent: false); - if (!res) + // Allow up to four attempts (with up to three retries) to run `dotnet --info`, to mitigate transient issues + for (int attempt = 0; attempt < 4; attempt++) { - throw new Exception($"{dotnetCliInvoker.Exec} --info failed."); + var exitCode = dotnetCliInvoker.RunCommandExitCode("--info", silent: false); + switch (exitCode) + { + case 0: + return; + case 143 when attempt < 3: + HandleRetryExitCode143(dotnetCliInvoker.Exec, attempt, logger); + continue; + default: + throw new Exception($"{dotnetCliInvoker.Exec} --info failed with exit code {exitCode}."); + } } } @@ -193,6 +211,35 @@ namespace Semmle.Extraction.CSharp.DependencyFetching return BuildScript.Failure; } + /// + /// Returns a script for running `dotnet --info`, with retries on exit code 143. + /// + public static BuildScript InfoScript(IBuildActions actions, string dotnet, IDictionary? environment, ILogger logger) + { + var info = new CommandBuilder(actions, null, environment). + RunCommand(dotnet). + Argument("--info"); + var script = info.Script; + for (var attempt = 0; attempt < 4; attempt++) + { + var attemptCopy = attempt; // Capture in local variable + script = BuildScript.Bind(script, ret => + { + switch (ret) + { + case 0: + return BuildScript.Success; + case 143 when attemptCopy < 3: + HandleRetryExitCode143(dotnet, attemptCopy, logger); + return info.Script; + default: + return BuildScript.Failure; + } + }); + } + return script; + } + /// /// Returns a script for downloading specific .NET SDK versions, if the /// versions are not already installed. @@ -292,9 +339,7 @@ namespace Semmle.Extraction.CSharp.DependencyFetching }; } - var dotnetInfo = new CommandBuilder(actions, environment: MinimalEnvironment). - RunCommand(actions.PathCombine(path, "dotnet")). - Argument("--info").Script; + var dotnetInfo = InfoScript(actions, actions.PathCombine(path, "dotnet"), MinimalEnvironment.ToDictionary(), logger); Func getInstallAndVerify = version => // run `dotnet --info` after install, to check that it executes successfully diff --git a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DotNetCliInvoker.cs b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DotNetCliInvoker.cs index 45f69a1fdfc..4c4e789973c 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DotNetCliInvoker.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DotNetCliInvoker.cs @@ -57,15 +57,21 @@ namespace Semmle.Extraction.CSharp.DependencyFetching return startInfo; } - private bool RunCommandAux(string args, string? workingDirectory, out IList output, bool silent) + private int RunCommandExitCodeAux(string args, string? workingDirectory, out IList output, out string dirLog, bool silent) { - var dirLog = string.IsNullOrWhiteSpace(workingDirectory) ? "" : $" in {workingDirectory}"; + dirLog = string.IsNullOrWhiteSpace(workingDirectory) ? "" : $" in {workingDirectory}"; var pi = MakeDotnetStartInfo(args, workingDirectory); var threadId = Environment.CurrentManagedThreadId; void onOut(string s) => logger.Log(silent ? Severity.Debug : Severity.Info, s, threadId); void onError(string s) => logger.LogError(s, threadId); logger.LogInfo($"Running '{Exec} {args}'{dirLog}"); var exitCode = pi.ReadOutput(out output, onOut, onError); + return exitCode; + } + + private bool RunCommandAux(string args, string? workingDirectory, out IList output, bool silent) + { + var exitCode = RunCommandExitCodeAux(args, workingDirectory, out output, out var dirLog, silent); if (exitCode != 0) { logger.LogError($"Command '{Exec} {args}'{dirLog} failed with exit code {exitCode}"); @@ -77,6 +83,9 @@ namespace Semmle.Extraction.CSharp.DependencyFetching public bool RunCommand(string args, bool silent = true) => RunCommandAux(args, null, out _, silent); + public int RunCommandExitCode(string args, bool silent = true) => + RunCommandExitCodeAux(args, null, out _, out _, silent); + public bool RunCommand(string args, out IList output, bool silent = true) => RunCommandAux(args, null, out output, silent); diff --git a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/IDotNetCliInvoker.cs b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/IDotNetCliInvoker.cs index 3a599afe96d..61d0ea4260d 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/IDotNetCliInvoker.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/IDotNetCliInvoker.cs @@ -30,6 +30,12 @@ namespace Semmle.Extraction.CSharp.DependencyFetching /// bool RunCommand(string args, bool silent = true); + /// + /// Execute `dotnet ` and return the exit code. + /// If `silent` is true the output of the command is logged as `debug` otherwise as `info`. + /// + int RunCommandExitCode(string args, bool silent = true); + /// /// Execute `dotnet ` and return true if the command succeeded, otherwise false. /// The output of the command is returned in `output`. diff --git a/csharp/extractor/Semmle.Extraction.Tests/DotNet.cs b/csharp/extractor/Semmle.Extraction.Tests/DotNet.cs index 904ad04ce82..a2996497e00 100644 --- a/csharp/extractor/Semmle.Extraction.Tests/DotNet.cs +++ b/csharp/extractor/Semmle.Extraction.Tests/DotNet.cs @@ -12,6 +12,7 @@ namespace Semmle.Extraction.Tests private string lastArgs = ""; public string WorkingDirectory { get; private set; } = ""; public bool Success { get; set; } = true; + public int ExitCode { get; set; } = 0; public DotNetCliInvokerStub(IList output) { @@ -26,6 +27,12 @@ namespace Semmle.Extraction.Tests return Success; } + public int RunCommandExitCode(string args, bool silent) + { + lastArgs = args; + return ExitCode; + } + public bool RunCommand(string args, out IList output, bool silent) { lastArgs = args; @@ -83,7 +90,7 @@ namespace Semmle.Extraction.Tests public void TestDotnetInfoFailure() { // Setup - var dotnetCliInvoker = new DotNetCliInvokerStub(new List()) { Success = false }; + var dotnetCliInvoker = new DotNetCliInvokerStub(new List()) { ExitCode = 1 }; // Execute try @@ -94,7 +101,7 @@ namespace Semmle.Extraction.Tests // Verify catch (Exception e) { - Assert.Equal("dotnet --info failed.", e.Message); + Assert.Equal("dotnet --info failed with exit code 1.", e.Message); return; } Assert.Fail("Expected exception"); diff --git a/csharp/ql/integration-tests/all-platforms/dotnet_10/test.py b/csharp/ql/integration-tests/all-platforms/dotnet_10/test.py index d34be2b8b50..1f1fe52a4e5 100644 --- a/csharp/ql/integration-tests/all-platforms/dotnet_10/test.py +++ b/csharp/ql/integration-tests/all-platforms/dotnet_10/test.py @@ -1,9 +1,7 @@ import pytest -@pytest.mark.skip(reason=".NET 10 info command crashes") def test1(codeql, csharp): codeql.database.create() -@pytest.mark.skip(reason=".NET 10 info command crashes") def test2(codeql, csharp): codeql.database.create(build_mode="none") diff --git a/csharp/ql/lib/change-notes/2025-12-03-run-tracer-after-compilation.md b/csharp/ql/lib/change-notes/2025-12-03-run-tracer-after-compilation.md new file mode 100644 index 00000000000..d7dd475cb0b --- /dev/null +++ b/csharp/ql/lib/change-notes/2025-12-03-run-tracer-after-compilation.md @@ -0,0 +1,4 @@ +--- +category: fix +--- +* Fixed an issue where compiler-generated files were not being extracted. The extractor now runs after compilation completes to ensure all generated files are properly analyzed. diff --git a/csharp/ql/lib/semmle/code/csharp/frameworks/Sql.qll b/csharp/ql/lib/semmle/code/csharp/frameworks/Sql.qll index 77d749a0333..6b1eb7b67fb 100644 --- a/csharp/ql/lib/semmle/code/csharp/frameworks/Sql.qll +++ b/csharp/ql/lib/semmle/code/csharp/frameworks/Sql.qll @@ -52,7 +52,7 @@ class IDbCommandConstructionSqlExpr extends SqlExpr, ObjectCreation { class DapperCommandDefinitionMethodCallSqlExpr extends SqlExpr, ObjectCreation { DapperCommandDefinitionMethodCallSqlExpr() { this.getObjectType() instanceof Dapper::CommandDefinitionStruct and - DapperCommandDefinitionMethodCallSql::flow(DataFlow::exprNode(this), _) + DapperCommandDefinitionMethodCallSql::flowFromExpr(this) } override Expr getSql() { result = this.getArgumentForName("commandText") } diff --git a/csharp/ql/lib/semmle/code/csharp/security/dataflow/ExternalAPIsQuery.qll b/csharp/ql/lib/semmle/code/csharp/security/dataflow/ExternalAPIsQuery.qll index f1a64f6810b..e623628fea6 100644 --- a/csharp/ql/lib/semmle/code/csharp/security/dataflow/ExternalAPIsQuery.qll +++ b/csharp/ql/lib/semmle/code/csharp/security/dataflow/ExternalAPIsQuery.qll @@ -85,7 +85,7 @@ module RemoteSourceToExternalApi = TaintTracking::Global; private DataFlow::CallNode getALargeLenCall() { - exists(DataFlow::Node lenArg | FindLargeLensFlow::flow(_, lenArg) | + exists(DataFlow::Node lenArg | FindLargeLensFlow::flowTo(lenArg) | result.getArgument(0) = lenArg ) } diff --git a/go/ql/lib/semmle/go/security/ExternalAPIs.qll b/go/ql/lib/semmle/go/security/ExternalAPIs.qll index f85f939258f..0a9be6bcc70 100644 --- a/go/ql/lib/semmle/go/security/ExternalAPIs.qll +++ b/go/ql/lib/semmle/go/security/ExternalAPIs.qll @@ -211,7 +211,7 @@ module UntrustedDataToUnknownExternalApiFlow = /** A node representing untrusted data being passed to an external API. */ class UntrustedExternalApiDataNode extends ExternalApiDataNode { - UntrustedExternalApiDataNode() { UntrustedDataToExternalApiFlow::flow(_, this) } + UntrustedExternalApiDataNode() { UntrustedDataToExternalApiFlow::flowTo(this) } /** Gets a source of untrusted data which is passed to this external API data node. */ DataFlow::Node getAnUntrustedSource() { UntrustedDataToExternalApiFlow::flow(result, this) } diff --git a/go/ql/lib/semmle/go/security/MissingJwtSignatureCheck.qll b/go/ql/lib/semmle/go/security/MissingJwtSignatureCheck.qll index 15afe81944f..1f8185d4397 100644 --- a/go/ql/lib/semmle/go/security/MissingJwtSignatureCheck.qll +++ b/go/ql/lib/semmle/go/security/MissingJwtSignatureCheck.qll @@ -15,7 +15,7 @@ module MissingJwtSignatureCheck { module Config implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { source instanceof Source and - not SafeParse::flow(source, _) + not SafeParse::flowFrom(source) } predicate isSink(DataFlow::Node sink) { sink instanceof Sink } diff --git a/go/ql/lib/semmle/go/security/UnsafeUnzipSymlink.qll b/go/ql/lib/semmle/go/security/UnsafeUnzipSymlink.qll index 19047b12b78..0ced26c3eff 100644 --- a/go/ql/lib/semmle/go/security/UnsafeUnzipSymlink.qll +++ b/go/ql/lib/semmle/go/security/UnsafeUnzipSymlink.qll @@ -32,7 +32,7 @@ module UnsafeUnzipSymlink { * Holds if `node` is an archive header field read that flows to a `path/filepath.EvalSymlinks` call. */ private predicate symlinksEvald(DataFlow::Node node) { - EvalSymlinksFlow::flow(getASimilarReadNode(node), _) + EvalSymlinksFlow::flowFrom(getASimilarReadNode(node)) } private module Config implements DataFlow::ConfigSig { diff --git a/go/ql/src/Security/CWE-020/MissingRegexpAnchor.ql b/go/ql/src/Security/CWE-020/MissingRegexpAnchor.ql index 43a24b1aef3..a4b18bff8d3 100644 --- a/go/ql/src/Security/CWE-020/MissingRegexpAnchor.ql +++ b/go/ql/src/Security/CWE-020/MissingRegexpAnchor.ql @@ -81,5 +81,5 @@ module Config implements DataFlow::ConfigSig { module Flow = DataFlow::Global; from DataFlow::Node source, string msg -where Flow::flow(source, _) and Config::isSourceString(source, msg) +where Flow::flowFrom(source) and Config::isSourceString(source, msg) select source, msg diff --git a/go/ql/src/Security/CWE-352/ConstantOauth2State.ql b/go/ql/src/Security/CWE-352/ConstantOauth2State.ql index 501eb6109c7..edbb41782b8 100644 --- a/go/ql/src/Security/CWE-352/ConstantOauth2State.ql +++ b/go/ql/src/Security/CWE-352/ConstantOauth2State.ql @@ -154,7 +154,7 @@ module FlowToPrintFlow = DataFlow::Global; /** Holds if the provided `CallNode`'s result flows to an argument of a printer call. */ predicate resultFlowsToPrinter(DataFlow::CallNode authCodeUrlCall) { - FlowToPrintFlow::flow(authCodeUrlCall.getResult(), _) + FlowToPrintFlow::flowFrom(authCodeUrlCall.getResult()) } /** Get a data-flow node that reads the value of `os.Stdin`. */ diff --git a/go/ql/src/Security/CWE-601/OpenUrlRedirect.ql b/go/ql/src/Security/CWE-601/OpenUrlRedirect.ql index 17ec112955f..34023f6161e 100644 --- a/go/ql/src/Security/CWE-601/OpenUrlRedirect.ql +++ b/go/ql/src/Security/CWE-601/OpenUrlRedirect.ql @@ -21,6 +21,6 @@ where OpenUrlRedirect::Flow::flowPath(source, sink) and // this excludes flow from safe parts of request URLs, for example the full URL when the // doing a redirect from `http://` to `https://` - not SafeUrlFlow::Flow::flow(_, sink.getNode()) + not SafeUrlFlow::Flow::flowTo(sink.getNode()) select sink.getNode(), source, sink, "This path to an untrusted URL redirection depends on a $@.", source.getNode(), "user-provided value" diff --git a/go/ql/src/Security/CWE-918/RequestForgery.ql b/go/ql/src/Security/CWE-918/RequestForgery.ql index 5a5c3265483..a54f51db9ce 100644 --- a/go/ql/src/Security/CWE-918/RequestForgery.ql +++ b/go/ql/src/Security/CWE-918/RequestForgery.ql @@ -21,6 +21,6 @@ where RequestForgery::Flow::flowPath(source, sink) and request = sink.getNode().(RequestForgery::Sink).getARequest() and // this excludes flow from safe parts of request URLs, for example the full URL - not SafeUrlFlow::Flow::flow(_, sink.getNode()) + not SafeUrlFlow::Flow::flowTo(sink.getNode()) select request, source, sink, "The $@ of this request depends on a $@.", sink.getNode(), sink.getNode().(RequestForgery::Sink).getKind(), source, "user-provided value" diff --git a/go/ql/src/experimental/CWE-285/PamAuthBypass.ql b/go/ql/src/experimental/CWE-285/PamAuthBypass.ql index 755a023ef62..daba2f89544 100644 --- a/go/ql/src/experimental/CWE-285/PamAuthBypass.ql +++ b/go/ql/src/experimental/CWE-285/PamAuthBypass.ql @@ -70,5 +70,6 @@ module PamStartToAuthenticateFlow = TaintTracking::Global; -private TypeLiteral getSourceWithFlowToParseAs() { - TypeLiteralToParseAsFlow::flow(DataFlow::exprNode(result), _) -} +private TypeLiteral getSourceWithFlowToParseAs() { TypeLiteralToParseAsFlow::flowFromExpr(result) } /** A field that is deserialized by `HttpResponse.parseAs`. */ class HttpResponseParseAsDeserializableField extends DeserializableField { 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 aa7da753f43..b9fdbe58f77 100644 --- a/java/ql/lib/semmle/code/java/frameworks/jackson/JacksonSerializability.qll +++ b/java/ql/lib/semmle/code/java/frameworks/jackson/JacksonSerializability.qll @@ -110,7 +110,7 @@ private module TypeLiteralToJacksonDatabindFlow = DataFlow::Global; private TypeLiteral getSourceWithFlowToJacksonDatabind() { - TypeLiteralToJacksonDatabindFlow::flow(DataFlow::exprNode(result), _) + TypeLiteralToJacksonDatabindFlow::flowFromExpr(result) } /** A type whose values are explicitly deserialized in a call to a Jackson method. */ diff --git a/java/ql/lib/semmle/code/java/regex/RegexFlowConfigs.qll b/java/ql/lib/semmle/code/java/regex/RegexFlowConfigs.qll index 929fa2d6c91..4deb2bc812b 100644 --- a/java/ql/lib/semmle/code/java/regex/RegexFlowConfigs.qll +++ b/java/ql/lib/semmle/code/java/regex/RegexFlowConfigs.qll @@ -164,7 +164,7 @@ private module RegexFlowConfig implements DataFlow::ConfigSig { private module RegexFlow = DataFlow::Global; private predicate usedAsRegexImpl(StringLiteral regex, string mode, boolean match_full_string) { - RegexFlow::flow(DataFlow::exprNode(regex), _) and + RegexFlow::flowFromExpr(regex) and mode = "None" and // TODO: proper mode detection (if matchesFullString(regex) then match_full_string = true else match_full_string = false) } diff --git a/java/ql/lib/semmle/code/java/security/ImproperIntentVerificationQuery.qll b/java/ql/lib/semmle/code/java/security/ImproperIntentVerificationQuery.qll index ff5ebe86217..61f88f39578 100644 --- a/java/ql/lib/semmle/code/java/security/ImproperIntentVerificationQuery.qll +++ b/java/ql/lib/semmle/code/java/security/ImproperIntentVerificationQuery.qll @@ -51,7 +51,7 @@ private module VerifiedIntentFlow = DataFlow::Global; /** An `onReceive` method that doesn't verify the action of the intent it receives. */ private class UnverifiedOnReceiveMethod extends OnReceiveMethod { UnverifiedOnReceiveMethod() { - not VerifiedIntentFlow::flow(DataFlow::parameterNode(this.getIntentParameter()), _) and + not VerifiedIntentFlow::flowFrom(DataFlow::parameterNode(this.getIntentParameter())) and // Empty methods do not need to be verified since they do not perform any actions. this.getBody().getNumStmt() > 0 } diff --git a/java/ql/lib/semmle/code/java/security/RequestForgery.qll b/java/ql/lib/semmle/code/java/security/RequestForgery.qll index dc15ad943bc..9e3dec00357 100644 --- a/java/ql/lib/semmle/code/java/security/RequestForgery.qll +++ b/java/ql/lib/semmle/code/java/security/RequestForgery.qll @@ -166,22 +166,7 @@ private class HostComparisonSanitizer extends RequestForgerySanitizer { } /** - * A qualifier in a call to a `.matches()` method that is a sanitizer for URL redirects. - * - * Matches any method call where the method is named `matches`. + * A comparison with a regular expression that is a sanitizer for URL redirects. */ -private predicate isMatchesSanitizer(Guard guard, Expr e, boolean branch) { - guard = - any(MethodCall method | - method.getMethod().getName() = "matches" and - e = method.getQualifier() and - branch = true - ) -} - -/** - * A qualifier in a call to `.matches()` that is a sanitizer for URL redirects. - */ -private class MatchesSanitizer extends RequestForgerySanitizer { - MatchesSanitizer() { this = DataFlow::BarrierGuard::getABarrierNode() } -} +private class RegexpCheckRequestForgerySanitizer extends RequestForgerySanitizer instanceof RegexpCheckBarrier +{ } diff --git a/java/ql/lib/semmle/code/java/security/Sanitizers.qll b/java/ql/lib/semmle/code/java/security/Sanitizers.qll index 21e7ccf264f..3f909864d2c 100644 --- a/java/ql/lib/semmle/code/java/security/Sanitizers.qll +++ b/java/ql/lib/semmle/code/java/security/Sanitizers.qll @@ -3,7 +3,9 @@ overlay[local?] module; import java +private import semmle.code.java.controlflow.Guards private import semmle.code.java.dataflow.DataFlow +private import semmle.code.java.frameworks.Regex /** * A node whose type is a simple type unlikely to carry taint, such as primitives and their boxed counterparts, @@ -29,3 +31,44 @@ class SimpleTypeSanitizer extends DataFlow::Node { this.getType() instanceof EnumType } } + +/** + * Holds if `guard` holds with branch `branch` if `e` matches a regular expression. + * + * This is overapproximate: we do not attempt to reason about the correctness of the regexp. + * + * Use this if you want to define a derived `DataFlow::BarrierGuard` without + * make the type recursive. Otherwise use `RegexpCheckBarrier`. + */ +predicate regexpMatchGuardChecks(Guard guard, Expr e, boolean branch) { + exists(Method method, MethodCall mc | + method = mc.getMethod() and + guard = mc and + branch = true + | + // `String.matches` and other `matches` methods. + method.getName() = "matches" and + e = mc.getQualifier() + or + method instanceof PatternMatchesMethod and + e = mc.getArgument(1) + or + method instanceof MatcherMatchesMethod and + exists(MethodCall matcherCall | + matcherCall.getMethod() instanceof PatternMatcherMethod and + e = matcherCall.getArgument(0) and + DataFlow::localExprFlow(matcherCall, mc.getQualifier()) + ) + ) +} + +/** + * A check against a regular expression, considered as a barrier guard. + * + * This is overapproximate: we do not attempt to reason about the correctness of the regexp. + */ +class RegexpCheckBarrier extends DataFlow::Node { + RegexpCheckBarrier() { + this = DataFlow::BarrierGuard::getABarrierNode() + } +} diff --git a/java/ql/src/Security/CWE/CWE-200/AndroidWebViewSettingsAllowsContentAccess.ql b/java/ql/src/Security/CWE/CWE-200/AndroidWebViewSettingsAllowsContentAccess.ql index 45767185dfd..cc076039940 100644 --- a/java/ql/src/Security/CWE/CWE-200/AndroidWebViewSettingsAllowsContentAccess.ql +++ b/java/ql/src/Security/CWE/CWE-200/AndroidWebViewSettingsAllowsContentAccess.ql @@ -118,7 +118,7 @@ where // implicit: no setAllowContentAccess(false) exists(WebViewSource source | source.asExpr() = e and - not WebViewDisallowContentAccessFlow::flow(source, _) + not WebViewDisallowContentAccessFlow::flowFrom(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/experimental/Security/CWE/CWE-295/JxBrowserWithoutCertValidation.ql b/java/ql/src/experimental/Security/CWE/CWE-295/JxBrowserWithoutCertValidation.ql index 48c49d5c071..c53c2cacdae 100644 --- a/java/ql/src/experimental/Security/CWE/CWE-295/JxBrowserWithoutCertValidation.ql +++ b/java/ql/src/experimental/Security/CWE/CWE-295/JxBrowserWithoutCertValidation.ql @@ -85,7 +85,7 @@ private module JxBrowserFlow = DataFlow::Global; deprecated query predicate problems(DataFlow::Node src, string message) { JxBrowserFlowConfig::isSource(src) and - not JxBrowserFlow::flow(src, _) and + not JxBrowserFlow::flowFrom(src) and not isSafeJxBrowserVersion() and message = "This JxBrowser instance may not check HTTPS certificates." } diff --git a/java/ql/src/experimental/Security/CWE/CWE-346/UnvalidatedCors.ql b/java/ql/src/experimental/Security/CWE/CWE-346/UnvalidatedCors.ql index ef95db6f6c5..fc0cc59244c 100644 --- a/java/ql/src/experimental/Security/CWE/CWE-346/UnvalidatedCors.ql +++ b/java/ql/src/experimental/Security/CWE/CWE-346/UnvalidatedCors.ql @@ -50,7 +50,7 @@ private Expr getAccessControlAllowOriginHeaderName() { * A taint-tracking configuration for flow from a source node to CorsProbableCheckAccess methods. */ module CorsSourceReachesCheckConfig implements DataFlow::ConfigSig { - predicate isSource(DataFlow::Node source) { CorsOriginFlow::flow(source, _) } + predicate isSource(DataFlow::Node source) { CorsOriginFlow::flowFrom(source) } predicate isSink(DataFlow::Node sink) { sink.asExpr() = any(CorsProbableCheckAccess check).getAnArgument() @@ -86,7 +86,7 @@ deprecated query predicate problems( string message1, DataFlow::Node sourceNode, string message2 ) { CorsOriginFlow::flowPath(source, sink) and - not CorsSourceReachesCheckFlow::flow(sourceNode, _) and + not CorsSourceReachesCheckFlow::flowFrom(sourceNode) and sinkNode = sink.getNode() and message1 = "CORS header is being set using user controlled value $@." and sourceNode = source.getNode() and diff --git a/java/ql/src/experimental/Security/CWE/CWE-347/Auth0NoVerifier.ql b/java/ql/src/experimental/Security/CWE/CWE-347/Auth0NoVerifier.ql index 778939887f0..16b0f024329 100644 --- a/java/ql/src/experimental/Security/CWE/CWE-347/Auth0NoVerifier.ql +++ b/java/ql/src/experimental/Security/CWE/CWE-347/Auth0NoVerifier.ql @@ -17,7 +17,7 @@ deprecated import JwtAuth0 as JwtAuth0 deprecated module JwtDecodeConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource and - not FlowToJwtVerify::flow(source, _) + not FlowToJwtVerify::flowFrom(source) } predicate isSink(DataFlow::Node sink) { sink.asExpr() = any(JwtAuth0::GetPayload a) } diff --git a/java/ql/src/utils/modelgenerator/internal/CaptureModels.qll b/java/ql/src/utils/modelgenerator/internal/CaptureModels.qll index b86a4c54246..6978ca7e308 100644 --- a/java/ql/src/utils/modelgenerator/internal/CaptureModels.qll +++ b/java/ql/src/utils/modelgenerator/internal/CaptureModels.qll @@ -218,6 +218,8 @@ module SummaryModelGeneratorInput implements SummaryModelGeneratorInputSig { ) } + int contentAccessPathLimitInternal() { result = 2 } + predicate isField(DataFlow::ContentSet c) { c instanceof DataFlowUtil::FieldContent or c instanceof DataFlowUtil::SyntheticFieldContent diff --git a/java/ql/test-kotlin1/library-tests/parameter-defaults/flowTest.ql b/java/ql/test-kotlin1/library-tests/parameter-defaults/flowTest.ql index da0fc33464b..0bf36d842e1 100644 --- a/java/ql/test-kotlin1/library-tests/parameter-defaults/flowTest.ql +++ b/java/ql/test-kotlin1/library-tests/parameter-defaults/flowTest.ql @@ -25,9 +25,7 @@ module Config implements DataFlow::ConfigSig { module Flow = DataFlow::Global; -predicate isSunk(StringLiteral sl) { - exists(DataFlow::Node source | Flow::flow(source, _) and sl = source.asExpr()) -} +predicate isSunk(StringLiteral sl) { Flow::flowFromExpr(sl) } query predicate shouldBeSunkButIsnt(ShouldBeSunk src) { not isSunk(src) } diff --git a/java/ql/test-kotlin2/library-tests/parameter-defaults/flowTest.ql b/java/ql/test-kotlin2/library-tests/parameter-defaults/flowTest.ql index da0fc33464b..0bf36d842e1 100644 --- a/java/ql/test-kotlin2/library-tests/parameter-defaults/flowTest.ql +++ b/java/ql/test-kotlin2/library-tests/parameter-defaults/flowTest.ql @@ -25,9 +25,7 @@ module Config implements DataFlow::ConfigSig { module Flow = DataFlow::Global; -predicate isSunk(StringLiteral sl) { - exists(DataFlow::Node source | Flow::flow(source, _) and sl = source.asExpr()) -} +predicate isSunk(StringLiteral sl) { Flow::flowFromExpr(sl) } query predicate shouldBeSunkButIsnt(ShouldBeSunk src) { not isSunk(src) } diff --git a/java/ql/test/library-tests/frameworks/android/taint-database/flowSteps.ql b/java/ql/test/library-tests/frameworks/android/taint-database/flowSteps.ql index 5ca38c7e29b..ae4f8ca0da0 100644 --- a/java/ql/test/library-tests/frameworks/android/taint-database/flowSteps.ql +++ b/java/ql/test/library-tests/frameworks/android/taint-database/flowSteps.ql @@ -20,7 +20,7 @@ module FlowStepTest implements TestSig { predicate hasActualResult(Location l, string element, string tag, string value) { tag = "taintReachesReturn" and value = "" and - exists(DataFlow::Node source | Flow::flow(source, _) | + exists(DataFlow::Node source | Flow::flowFrom(source) | l = source.getLocation() and element = source.toString() ) diff --git a/java/ql/test/library-tests/frameworks/android/taint-database/sinks.ql b/java/ql/test/library-tests/frameworks/android/taint-database/sinks.ql index ccdb9698009..58b749364d2 100644 --- a/java/ql/test/library-tests/frameworks/android/taint-database/sinks.ql +++ b/java/ql/test/library-tests/frameworks/android/taint-database/sinks.ql @@ -20,7 +20,7 @@ module SinkTest implements TestSig { predicate hasActualResult(Location l, string element, string tag, string value) { tag = "taintReachesSink" and value = "" and - exists(DataFlow::Node source | Flow::flow(source, _) | + exists(DataFlow::Node source | Flow::flowFrom(source) | l = source.getLocation() and element = source.toString() ) diff --git a/java/ql/test/query-tests/security/CWE-918/RequestForgery.expected b/java/ql/test/query-tests/security/CWE-918/RequestForgery.expected index b08273da0ca..66dc968cb23 100644 --- a/java/ql/test/query-tests/security/CWE-918/RequestForgery.expected +++ b/java/ql/test/query-tests/security/CWE-918/RequestForgery.expected @@ -228,30 +228,30 @@ | JdbcUrlSSRF.java:88:19:88:25 | jdbcUrl | JdbcUrlSSRF.java:80:26:80:56 | getParameter(...) : String | JdbcUrlSSRF.java:88:19:88:25 | jdbcUrl | Potential server-side request forgery due to a $@. | JdbcUrlSSRF.java:80:26:80:56 | getParameter(...) | user-provided value | | ReactiveWebClientSSRF.java:16:52:16:54 | url | ReactiveWebClientSSRF.java:15:26:15:52 | getParameter(...) : String | ReactiveWebClientSSRF.java:16:52:16:54 | url | Potential server-side request forgery due to a $@. | ReactiveWebClientSSRF.java:15:26:15:52 | getParameter(...) | user-provided value | | ReactiveWebClientSSRF.java:35:30:35:32 | url | ReactiveWebClientSSRF.java:32:26:32:52 | getParameter(...) : String | ReactiveWebClientSSRF.java:35:30:35:32 | url | Potential server-side request forgery due to a $@. | ReactiveWebClientSSRF.java:32:26:32:52 | getParameter(...) | user-provided value | -| SanitizationTests.java:22:52:22:54 | uri | SanitizationTests.java:19:31:19:57 | getParameter(...) : String | SanitizationTests.java:22:52:22:54 | uri | Potential server-side request forgery due to a $@. | SanitizationTests.java:19:31:19:57 | getParameter(...) | user-provided value | -| SanitizationTests.java:23:25:23:25 | r | SanitizationTests.java:19:31:19:57 | getParameter(...) : String | SanitizationTests.java:23:25:23:25 | r | Potential server-side request forgery due to a $@. | SanitizationTests.java:19:31:19:57 | getParameter(...) | user-provided value | -| SanitizationTests.java:76:59:76:77 | new URI(...) | SanitizationTests.java:75:33:75:63 | getParameter(...) : String | SanitizationTests.java:76:59:76:77 | new URI(...) | Potential server-side request forgery due to a $@. | SanitizationTests.java:75:33:75:63 | getParameter(...) | user-provided value | -| SanitizationTests.java:77:25:77:32 | unsafer3 | SanitizationTests.java:75:33:75:63 | getParameter(...) : String | SanitizationTests.java:77:25:77:32 | unsafer3 | Potential server-side request forgery due to a $@. | SanitizationTests.java:75:33:75:63 | getParameter(...) | user-provided value | -| SanitizationTests.java:80:59:80:77 | new URI(...) | SanitizationTests.java:79:49:79:79 | getParameter(...) : String | SanitizationTests.java:80:59:80:77 | new URI(...) | Potential server-side request forgery due to a $@. | SanitizationTests.java:79:49:79:79 | getParameter(...) | user-provided value | -| SanitizationTests.java:81:25:81:32 | unsafer4 | SanitizationTests.java:79:49:79:79 | getParameter(...) : String | SanitizationTests.java:81:25:81:32 | unsafer4 | Potential server-side request forgery due to a $@. | SanitizationTests.java:79:49:79:79 | getParameter(...) | user-provided value | -| SanitizationTests.java:85:59:85:88 | new URI(...) | SanitizationTests.java:84:31:84:61 | getParameter(...) : String | SanitizationTests.java:85:59:85:88 | new URI(...) | Potential server-side request forgery due to a $@. | SanitizationTests.java:84:31:84:61 | getParameter(...) | user-provided value | -| SanitizationTests.java:86:25:86:32 | unsafer5 | SanitizationTests.java:84:31:84:61 | getParameter(...) : String | SanitizationTests.java:86:25:86:32 | unsafer5 | Potential server-side request forgery due to a $@. | SanitizationTests.java:84:31:84:61 | getParameter(...) | user-provided value | -| SanitizationTests.java:90:60:90:89 | new URI(...) | SanitizationTests.java:88:58:88:86 | getParameter(...) : String | SanitizationTests.java:90:60:90:89 | new URI(...) | Potential server-side request forgery due to a $@. | SanitizationTests.java:88:58:88:86 | getParameter(...) | user-provided value | -| SanitizationTests.java:91:25:91:33 | unsafer5a | SanitizationTests.java:88:58:88:86 | getParameter(...) : String | SanitizationTests.java:91:25:91:33 | unsafer5a | Potential server-side request forgery due to a $@. | SanitizationTests.java:88:58:88:86 | getParameter(...) | user-provided value | -| SanitizationTests.java:95:60:95:90 | new URI(...) | SanitizationTests.java:93:60:93:88 | getParameter(...) : String | SanitizationTests.java:95:60:95:90 | new URI(...) | Potential server-side request forgery due to a $@. | SanitizationTests.java:93:60:93:88 | getParameter(...) | user-provided value | -| SanitizationTests.java:96:25:96:33 | unsafer5b | SanitizationTests.java:93:60:93:88 | getParameter(...) : String | SanitizationTests.java:96:25:96:33 | unsafer5b | Potential server-side request forgery due to a $@. | SanitizationTests.java:93:60:93:88 | getParameter(...) | user-provided value | -| SanitizationTests.java:100:60:100:90 | new URI(...) | SanitizationTests.java:98:77:98:105 | getParameter(...) : String | SanitizationTests.java:100:60:100:90 | new URI(...) | Potential server-side request forgery due to a $@. | SanitizationTests.java:98:77:98:105 | getParameter(...) | user-provided value | -| SanitizationTests.java:101:25:101:33 | unsafer5c | SanitizationTests.java:98:77:98:105 | getParameter(...) : String | SanitizationTests.java:101:25:101:33 | unsafer5c | Potential server-side request forgery due to a $@. | SanitizationTests.java:98:77:98:105 | getParameter(...) | user-provided value | -| SanitizationTests.java:104:59:104:77 | new URI(...) | SanitizationTests.java:103:73:103:103 | getParameter(...) : String | SanitizationTests.java:104:59:104:77 | new URI(...) | Potential server-side request forgery due to a $@. | SanitizationTests.java:103:73:103:103 | getParameter(...) | user-provided value | -| SanitizationTests.java:105:25:105:32 | unsafer6 | SanitizationTests.java:103:73:103:103 | getParameter(...) : String | SanitizationTests.java:105:25:105:32 | unsafer6 | Potential server-side request forgery due to a $@. | SanitizationTests.java:103:73:103:103 | getParameter(...) | user-provided value | -| SanitizationTests.java:108:59:108:77 | new URI(...) | SanitizationTests.java:107:56:107:86 | getParameter(...) : String | SanitizationTests.java:108:59:108:77 | new URI(...) | Potential server-side request forgery due to a $@. | SanitizationTests.java:107:56:107:86 | getParameter(...) | user-provided value | -| SanitizationTests.java:109:25:109:32 | unsafer7 | SanitizationTests.java:107:56:107:86 | getParameter(...) : String | SanitizationTests.java:109:25:109:32 | unsafer7 | Potential server-side request forgery due to a $@. | SanitizationTests.java:107:56:107:86 | getParameter(...) | user-provided value | -| SanitizationTests.java:112:59:112:77 | new URI(...) | SanitizationTests.java:111:55:111:85 | getParameter(...) : String | SanitizationTests.java:112:59:112:77 | new URI(...) | Potential server-side request forgery due to a $@. | SanitizationTests.java:111:55:111:85 | getParameter(...) | user-provided value | -| SanitizationTests.java:113:25:113:32 | unsafer8 | SanitizationTests.java:111:55:111:85 | getParameter(...) : String | SanitizationTests.java:113:25:113:32 | unsafer8 | Potential server-side request forgery due to a $@. | SanitizationTests.java:111:55:111:85 | getParameter(...) | user-provided value | -| SanitizationTests.java:116:59:116:77 | new URI(...) | SanitizationTests.java:115:33:115:63 | getParameter(...) : String | SanitizationTests.java:116:59:116:77 | new URI(...) | Potential server-side request forgery due to a $@. | SanitizationTests.java:115:33:115:63 | getParameter(...) | user-provided value | -| SanitizationTests.java:117:25:117:32 | unsafer9 | SanitizationTests.java:115:33:115:63 | getParameter(...) : String | SanitizationTests.java:117:25:117:32 | unsafer9 | Potential server-side request forgery due to a $@. | SanitizationTests.java:115:33:115:63 | getParameter(...) | user-provided value | -| SanitizationTests.java:120:60:120:79 | new URI(...) | SanitizationTests.java:119:94:119:125 | getParameter(...) : String | SanitizationTests.java:120:60:120:79 | new URI(...) | Potential server-side request forgery due to a $@. | SanitizationTests.java:119:94:119:125 | getParameter(...) | user-provided value | -| SanitizationTests.java:121:25:121:33 | unsafer10 | SanitizationTests.java:119:94:119:125 | getParameter(...) : String | SanitizationTests.java:121:25:121:33 | unsafer10 | Potential server-side request forgery due to a $@. | SanitizationTests.java:119:94:119:125 | getParameter(...) | user-provided value | +| SanitizationTests.java:24:52:24:54 | uri | SanitizationTests.java:21:31:21:57 | getParameter(...) : String | SanitizationTests.java:24:52:24:54 | uri | Potential server-side request forgery due to a $@. | SanitizationTests.java:21:31:21:57 | getParameter(...) | user-provided value | +| SanitizationTests.java:25:25:25:25 | r | SanitizationTests.java:21:31:21:57 | getParameter(...) : String | SanitizationTests.java:25:25:25:25 | r | Potential server-side request forgery due to a $@. | SanitizationTests.java:21:31:21:57 | getParameter(...) | user-provided value | +| SanitizationTests.java:78:59:78:77 | new URI(...) | SanitizationTests.java:77:33:77:63 | getParameter(...) : String | SanitizationTests.java:78:59:78:77 | new URI(...) | Potential server-side request forgery due to a $@. | SanitizationTests.java:77:33:77:63 | getParameter(...) | user-provided value | +| SanitizationTests.java:79:25:79:32 | unsafer3 | SanitizationTests.java:77:33:77:63 | getParameter(...) : String | SanitizationTests.java:79:25:79:32 | unsafer3 | Potential server-side request forgery due to a $@. | SanitizationTests.java:77:33:77:63 | getParameter(...) | user-provided value | +| SanitizationTests.java:82:59:82:77 | new URI(...) | SanitizationTests.java:81:49:81:79 | getParameter(...) : String | SanitizationTests.java:82:59:82:77 | new URI(...) | Potential server-side request forgery due to a $@. | SanitizationTests.java:81:49:81:79 | getParameter(...) | user-provided value | +| SanitizationTests.java:83:25:83:32 | unsafer4 | SanitizationTests.java:81:49:81:79 | getParameter(...) : String | SanitizationTests.java:83:25:83:32 | unsafer4 | Potential server-side request forgery due to a $@. | SanitizationTests.java:81:49:81:79 | getParameter(...) | user-provided value | +| SanitizationTests.java:87:59:87:88 | new URI(...) | SanitizationTests.java:86:31:86:61 | getParameter(...) : String | SanitizationTests.java:87:59:87:88 | new URI(...) | Potential server-side request forgery due to a $@. | SanitizationTests.java:86:31:86:61 | getParameter(...) | user-provided value | +| SanitizationTests.java:88:25:88:32 | unsafer5 | SanitizationTests.java:86:31:86:61 | getParameter(...) : String | SanitizationTests.java:88:25:88:32 | unsafer5 | Potential server-side request forgery due to a $@. | SanitizationTests.java:86:31:86:61 | getParameter(...) | user-provided value | +| SanitizationTests.java:92:60:92:89 | new URI(...) | SanitizationTests.java:90:58:90:86 | getParameter(...) : String | SanitizationTests.java:92:60:92:89 | new URI(...) | Potential server-side request forgery due to a $@. | SanitizationTests.java:90:58:90:86 | getParameter(...) | user-provided value | +| SanitizationTests.java:93:25:93:33 | unsafer5a | SanitizationTests.java:90:58:90:86 | getParameter(...) : String | SanitizationTests.java:93:25:93:33 | unsafer5a | Potential server-side request forgery due to a $@. | SanitizationTests.java:90:58:90:86 | getParameter(...) | user-provided value | +| SanitizationTests.java:97:60:97:90 | new URI(...) | SanitizationTests.java:95:60:95:88 | getParameter(...) : String | SanitizationTests.java:97:60:97:90 | new URI(...) | Potential server-side request forgery due to a $@. | SanitizationTests.java:95:60:95:88 | getParameter(...) | user-provided value | +| SanitizationTests.java:98:25:98:33 | unsafer5b | SanitizationTests.java:95:60:95:88 | getParameter(...) : String | SanitizationTests.java:98:25:98:33 | unsafer5b | Potential server-side request forgery due to a $@. | SanitizationTests.java:95:60:95:88 | getParameter(...) | user-provided value | +| SanitizationTests.java:102:60:102:90 | new URI(...) | SanitizationTests.java:100:77:100:105 | getParameter(...) : String | SanitizationTests.java:102:60:102:90 | new URI(...) | Potential server-side request forgery due to a $@. | SanitizationTests.java:100:77:100:105 | getParameter(...) | user-provided value | +| SanitizationTests.java:103:25:103:33 | unsafer5c | SanitizationTests.java:100:77:100:105 | getParameter(...) : String | SanitizationTests.java:103:25:103:33 | unsafer5c | Potential server-side request forgery due to a $@. | SanitizationTests.java:100:77:100:105 | getParameter(...) | user-provided value | +| SanitizationTests.java:106:59:106:77 | new URI(...) | SanitizationTests.java:105:73:105:103 | getParameter(...) : String | SanitizationTests.java:106:59:106:77 | new URI(...) | Potential server-side request forgery due to a $@. | SanitizationTests.java:105:73:105:103 | getParameter(...) | user-provided value | +| SanitizationTests.java:107:25:107:32 | unsafer6 | SanitizationTests.java:105:73:105:103 | getParameter(...) : String | SanitizationTests.java:107:25:107:32 | unsafer6 | Potential server-side request forgery due to a $@. | SanitizationTests.java:105:73:105:103 | getParameter(...) | user-provided value | +| SanitizationTests.java:110:59:110:77 | new URI(...) | SanitizationTests.java:109:56:109:86 | getParameter(...) : String | SanitizationTests.java:110:59:110:77 | new URI(...) | Potential server-side request forgery due to a $@. | SanitizationTests.java:109:56:109:86 | getParameter(...) | user-provided value | +| SanitizationTests.java:111:25:111:32 | unsafer7 | SanitizationTests.java:109:56:109:86 | getParameter(...) : String | SanitizationTests.java:111:25:111:32 | unsafer7 | Potential server-side request forgery due to a $@. | SanitizationTests.java:109:56:109:86 | getParameter(...) | user-provided value | +| SanitizationTests.java:114:59:114:77 | new URI(...) | SanitizationTests.java:113:55:113:85 | getParameter(...) : String | SanitizationTests.java:114:59:114:77 | new URI(...) | Potential server-side request forgery due to a $@. | SanitizationTests.java:113:55:113:85 | getParameter(...) | user-provided value | +| SanitizationTests.java:115:25:115:32 | unsafer8 | SanitizationTests.java:113:55:113:85 | getParameter(...) : String | SanitizationTests.java:115:25:115:32 | unsafer8 | Potential server-side request forgery due to a $@. | SanitizationTests.java:113:55:113:85 | getParameter(...) | user-provided value | +| SanitizationTests.java:118:59:118:77 | new URI(...) | SanitizationTests.java:117:33:117:63 | getParameter(...) : String | SanitizationTests.java:118:59:118:77 | new URI(...) | Potential server-side request forgery due to a $@. | SanitizationTests.java:117:33:117:63 | getParameter(...) | user-provided value | +| SanitizationTests.java:119:25:119:32 | unsafer9 | SanitizationTests.java:117:33:117:63 | getParameter(...) : String | SanitizationTests.java:119:25:119:32 | unsafer9 | Potential server-side request forgery due to a $@. | SanitizationTests.java:117:33:117:63 | getParameter(...) | user-provided value | +| SanitizationTests.java:122:60:122:79 | new URI(...) | SanitizationTests.java:121:94:121:125 | getParameter(...) : String | SanitizationTests.java:122:60:122:79 | new URI(...) | Potential server-side request forgery due to a $@. | SanitizationTests.java:121:94:121:125 | getParameter(...) | user-provided value | +| SanitizationTests.java:123:25:123:33 | unsafer10 | SanitizationTests.java:121:94:121:125 | getParameter(...) : String | SanitizationTests.java:123:25:123:33 | unsafer10 | Potential server-side request forgery due to a $@. | SanitizationTests.java:121:94:121:125 | getParameter(...) | user-provided value | | SpringSSRF.java:32:39:32:59 | ... + ... | SpringSSRF.java:28:33:28:60 | getParameter(...) : String | SpringSSRF.java:32:39:32:59 | ... + ... | Potential server-side request forgery due to a $@. | SpringSSRF.java:28:33:28:60 | getParameter(...) | user-provided value | | SpringSSRF.java:33:35:33:48 | fooResourceUrl | SpringSSRF.java:28:33:28:60 | getParameter(...) : String | SpringSSRF.java:33:35:33:48 | fooResourceUrl | Potential server-side request forgery due to a $@. | SpringSSRF.java:28:33:28:60 | getParameter(...) | user-provided value | | SpringSSRF.java:34:34:34:47 | fooResourceUrl | SpringSSRF.java:28:33:28:60 | getParameter(...) : String | SpringSSRF.java:34:34:34:47 | fooResourceUrl | Potential server-side request forgery due to a $@. | SpringSSRF.java:28:33:28:60 | getParameter(...) | user-provided value | @@ -665,118 +665,118 @@ edges | JdbcUrlSSRF.java:80:26:80:56 | getParameter(...) : String | JdbcUrlSSRF.java:88:19:88:25 | jdbcUrl | provenance | Src:MaD:277 Sink:MaD:240 | | ReactiveWebClientSSRF.java:15:26:15:52 | getParameter(...) : String | ReactiveWebClientSSRF.java:16:52:16:54 | url | provenance | Src:MaD:277 Sink:MaD:274 | | ReactiveWebClientSSRF.java:32:26:32:52 | getParameter(...) : String | ReactiveWebClientSSRF.java:35:30:35:32 | url | provenance | Src:MaD:277 Sink:MaD:273 | -| SanitizationTests.java:19:23:19:58 | new URI(...) : URI | SanitizationTests.java:22:52:22:54 | uri | provenance | Sink:MaD:6 | -| SanitizationTests.java:19:23:19:58 | new URI(...) : URI | SanitizationTests.java:22:52:22:54 | uri : URI | provenance | | -| SanitizationTests.java:19:31:19:57 | getParameter(...) : String | SanitizationTests.java:19:23:19:58 | new URI(...) : URI | provenance | Src:MaD:277 Config | -| SanitizationTests.java:19:31:19:57 | getParameter(...) : String | SanitizationTests.java:19:23:19:58 | new URI(...) : URI | provenance | Src:MaD:277 MaD:285 | -| SanitizationTests.java:22:29:22:55 | newBuilder(...) : Builder | SanitizationTests.java:22:29:22:63 | build(...) : HttpRequest | provenance | MaD:283 | -| SanitizationTests.java:22:29:22:63 | build(...) : HttpRequest | SanitizationTests.java:23:25:23:25 | r | provenance | Sink:MaD:4 | -| SanitizationTests.java:22:52:22:54 | uri : URI | SanitizationTests.java:22:29:22:55 | newBuilder(...) : Builder | provenance | MaD:284 | -| SanitizationTests.java:75:33:75:63 | getParameter(...) : String | SanitizationTests.java:76:67:76:76 | unsafeUri3 : String | provenance | Src:MaD:277 | -| SanitizationTests.java:76:36:76:78 | newBuilder(...) : Builder | SanitizationTests.java:76:36:76:86 | build(...) : HttpRequest | provenance | MaD:283 | -| SanitizationTests.java:76:36:76:86 | build(...) : HttpRequest | SanitizationTests.java:77:25:77:32 | unsafer3 | provenance | Sink:MaD:4 | -| SanitizationTests.java:76:59:76:77 | new URI(...) : URI | SanitizationTests.java:76:36:76:78 | newBuilder(...) : Builder | provenance | MaD:284 | -| SanitizationTests.java:76:67:76:76 | unsafeUri3 : String | SanitizationTests.java:76:59:76:77 | new URI(...) | provenance | Config Sink:MaD:6 | -| SanitizationTests.java:76:67:76:76 | unsafeUri3 : String | SanitizationTests.java:76:59:76:77 | new URI(...) | provenance | MaD:285 Sink:MaD:6 | -| SanitizationTests.java:76:67:76:76 | unsafeUri3 : String | SanitizationTests.java:76:59:76:77 | new URI(...) : URI | provenance | Config | -| SanitizationTests.java:76:67:76:76 | unsafeUri3 : String | SanitizationTests.java:76:59:76:77 | new URI(...) : URI | provenance | MaD:285 | -| SanitizationTests.java:79:49:79:79 | getParameter(...) : String | SanitizationTests.java:80:67:80:76 | unsafeUri4 : String | provenance | Src:MaD:277 | -| SanitizationTests.java:80:36:80:78 | newBuilder(...) : Builder | SanitizationTests.java:80:36:80:86 | build(...) : HttpRequest | provenance | MaD:283 | -| SanitizationTests.java:80:36:80:86 | build(...) : HttpRequest | SanitizationTests.java:81:25:81:32 | unsafer4 | provenance | Sink:MaD:4 | -| SanitizationTests.java:80:59:80:77 | new URI(...) : URI | SanitizationTests.java:80:36:80:78 | newBuilder(...) : Builder | provenance | MaD:284 | -| SanitizationTests.java:80:67:80:76 | unsafeUri4 : String | SanitizationTests.java:80:59:80:77 | new URI(...) | provenance | Config Sink:MaD:6 | -| SanitizationTests.java:80:67:80:76 | unsafeUri4 : String | SanitizationTests.java:80:59:80:77 | new URI(...) | provenance | MaD:285 Sink:MaD:6 | -| SanitizationTests.java:80:67:80:76 | unsafeUri4 : String | SanitizationTests.java:80:59:80:77 | new URI(...) : URI | provenance | Config | -| SanitizationTests.java:80:67:80:76 | unsafeUri4 : String | SanitizationTests.java:80:59:80:77 | new URI(...) : URI | provenance | MaD:285 | -| SanitizationTests.java:84:13:84:22 | unsafeUri5 [post update] : StringBuilder | SanitizationTests.java:85:67:85:76 | unsafeUri5 : StringBuilder | provenance | | -| SanitizationTests.java:84:31:84:61 | getParameter(...) : String | SanitizationTests.java:84:13:84:22 | unsafeUri5 [post update] : StringBuilder | provenance | Src:MaD:277 MaD:278 | -| SanitizationTests.java:85:36:85:89 | newBuilder(...) : Builder | SanitizationTests.java:85:36:85:97 | build(...) : HttpRequest | provenance | MaD:283 | -| SanitizationTests.java:85:36:85:97 | build(...) : HttpRequest | SanitizationTests.java:86:25:86:32 | unsafer5 | provenance | Sink:MaD:4 | -| SanitizationTests.java:85:59:85:88 | new URI(...) : URI | SanitizationTests.java:85:36:85:89 | newBuilder(...) : Builder | provenance | MaD:284 | -| SanitizationTests.java:85:67:85:76 | unsafeUri5 : StringBuilder | SanitizationTests.java:85:67:85:87 | toString(...) : String | provenance | MaD:280 | -| SanitizationTests.java:85:67:85:87 | toString(...) : String | SanitizationTests.java:85:59:85:88 | new URI(...) | provenance | Config Sink:MaD:6 | -| SanitizationTests.java:85:67:85:87 | toString(...) : String | SanitizationTests.java:85:59:85:88 | new URI(...) | provenance | MaD:285 Sink:MaD:6 | -| SanitizationTests.java:85:67:85:87 | toString(...) : String | SanitizationTests.java:85:59:85:88 | new URI(...) : URI | provenance | Config | -| SanitizationTests.java:85:67:85:87 | toString(...) : String | SanitizationTests.java:85:59:85:88 | new URI(...) : URI | provenance | MaD:285 | -| SanitizationTests.java:88:40:88:87 | new StringBuilder(...) : StringBuilder | SanitizationTests.java:90:68:90:77 | unafeUri5a : StringBuilder | provenance | | -| SanitizationTests.java:88:58:88:86 | getParameter(...) : String | SanitizationTests.java:88:40:88:87 | new StringBuilder(...) : StringBuilder | provenance | Src:MaD:277 MaD:282 | -| SanitizationTests.java:90:37:90:90 | newBuilder(...) : Builder | SanitizationTests.java:90:37:90:98 | build(...) : HttpRequest | provenance | MaD:283 | -| SanitizationTests.java:90:37:90:98 | build(...) : HttpRequest | SanitizationTests.java:91:25:91:33 | unsafer5a | provenance | Sink:MaD:4 | -| SanitizationTests.java:90:60:90:89 | new URI(...) : URI | SanitizationTests.java:90:37:90:90 | newBuilder(...) : Builder | provenance | MaD:284 | -| SanitizationTests.java:90:68:90:77 | unafeUri5a : StringBuilder | SanitizationTests.java:90:68:90:88 | toString(...) : String | provenance | MaD:280 | -| SanitizationTests.java:90:68:90:88 | toString(...) : String | SanitizationTests.java:90:60:90:89 | new URI(...) | provenance | Config Sink:MaD:6 | -| SanitizationTests.java:90:68:90:88 | toString(...) : String | SanitizationTests.java:90:60:90:89 | new URI(...) | provenance | MaD:285 Sink:MaD:6 | -| SanitizationTests.java:90:68:90:88 | toString(...) : String | SanitizationTests.java:90:60:90:89 | new URI(...) : URI | provenance | Config | -| SanitizationTests.java:90:68:90:88 | toString(...) : String | SanitizationTests.java:90:60:90:89 | new URI(...) : URI | provenance | MaD:285 | -| SanitizationTests.java:93:41:93:105 | append(...) : StringBuilder | SanitizationTests.java:95:68:95:78 | unsafeUri5b : StringBuilder | provenance | | -| SanitizationTests.java:93:42:93:89 | new StringBuilder(...) : StringBuilder | SanitizationTests.java:93:41:93:105 | append(...) : StringBuilder | provenance | MaD:279 | -| SanitizationTests.java:93:60:93:88 | getParameter(...) : String | SanitizationTests.java:93:42:93:89 | new StringBuilder(...) : StringBuilder | provenance | Src:MaD:277 MaD:282 | -| SanitizationTests.java:95:37:95:91 | newBuilder(...) : Builder | SanitizationTests.java:95:37:95:99 | build(...) : HttpRequest | provenance | MaD:283 | -| SanitizationTests.java:95:37:95:99 | build(...) : HttpRequest | SanitizationTests.java:96:25:96:33 | unsafer5b | provenance | Sink:MaD:4 | -| SanitizationTests.java:95:60:95:90 | new URI(...) : URI | SanitizationTests.java:95:37:95:91 | newBuilder(...) : Builder | provenance | MaD:284 | -| SanitizationTests.java:95:68:95:78 | unsafeUri5b : StringBuilder | SanitizationTests.java:95:68:95:89 | toString(...) : String | provenance | MaD:280 | -| SanitizationTests.java:95:68:95:89 | toString(...) : String | SanitizationTests.java:95:60:95:90 | new URI(...) | provenance | Config Sink:MaD:6 | -| SanitizationTests.java:95:68:95:89 | toString(...) : String | SanitizationTests.java:95:60:95:90 | new URI(...) | provenance | MaD:285 Sink:MaD:6 | -| SanitizationTests.java:95:68:95:89 | toString(...) : String | SanitizationTests.java:95:60:95:90 | new URI(...) : URI | provenance | Config | -| SanitizationTests.java:95:68:95:89 | toString(...) : String | SanitizationTests.java:95:60:95:90 | new URI(...) : URI | provenance | MaD:285 | -| SanitizationTests.java:98:41:98:106 | append(...) : StringBuilder | SanitizationTests.java:100:68:100:78 | unsafeUri5c : StringBuilder | provenance | | -| SanitizationTests.java:98:77:98:105 | getParameter(...) : String | SanitizationTests.java:98:41:98:106 | append(...) : StringBuilder | provenance | Src:MaD:277 MaD:278+MaD:279 | -| SanitizationTests.java:100:37:100:91 | newBuilder(...) : Builder | SanitizationTests.java:100:37:100:99 | build(...) : HttpRequest | provenance | MaD:283 | -| SanitizationTests.java:100:37:100:99 | build(...) : HttpRequest | SanitizationTests.java:101:25:101:33 | unsafer5c | provenance | Sink:MaD:4 | -| SanitizationTests.java:100:60:100:90 | new URI(...) : URI | SanitizationTests.java:100:37:100:91 | newBuilder(...) : Builder | provenance | MaD:284 | -| SanitizationTests.java:100:68:100:78 | unsafeUri5c : StringBuilder | SanitizationTests.java:100:68:100:89 | toString(...) : String | provenance | MaD:280 | -| SanitizationTests.java:100:68:100:89 | toString(...) : String | SanitizationTests.java:100:60:100:90 | new URI(...) | provenance | Config Sink:MaD:6 | -| SanitizationTests.java:100:68:100:89 | toString(...) : String | SanitizationTests.java:100:60:100:90 | new URI(...) | provenance | MaD:285 Sink:MaD:6 | -| SanitizationTests.java:100:68:100:89 | toString(...) : String | SanitizationTests.java:100:60:100:90 | new URI(...) : URI | provenance | Config | -| SanitizationTests.java:100:68:100:89 | toString(...) : String | SanitizationTests.java:100:60:100:90 | new URI(...) : URI | provenance | MaD:285 | -| SanitizationTests.java:103:33:103:104 | format(...) : String | SanitizationTests.java:104:67:104:76 | unsafeUri6 : String | provenance | | -| SanitizationTests.java:103:33:103:104 | new ..[] { .. } : Object[] [[]] : String | SanitizationTests.java:103:33:103:104 | format(...) : String | provenance | MaD:281 | -| SanitizationTests.java:103:73:103:103 | getParameter(...) : String | SanitizationTests.java:103:33:103:104 | new ..[] { .. } : Object[] [[]] : String | provenance | Src:MaD:277 | -| SanitizationTests.java:104:36:104:78 | newBuilder(...) : Builder | SanitizationTests.java:104:36:104:86 | build(...) : HttpRequest | provenance | MaD:283 | -| SanitizationTests.java:104:36:104:86 | build(...) : HttpRequest | SanitizationTests.java:105:25:105:32 | unsafer6 | provenance | Sink:MaD:4 | -| SanitizationTests.java:104:59:104:77 | new URI(...) : URI | SanitizationTests.java:104:36:104:78 | newBuilder(...) : Builder | provenance | MaD:284 | -| SanitizationTests.java:104:67:104:76 | unsafeUri6 : String | SanitizationTests.java:104:59:104:77 | new URI(...) | provenance | Config Sink:MaD:6 | -| SanitizationTests.java:104:67:104:76 | unsafeUri6 : String | SanitizationTests.java:104:59:104:77 | new URI(...) | provenance | MaD:285 Sink:MaD:6 | -| SanitizationTests.java:104:67:104:76 | unsafeUri6 : String | SanitizationTests.java:104:59:104:77 | new URI(...) : URI | provenance | Config | -| SanitizationTests.java:104:67:104:76 | unsafeUri6 : String | SanitizationTests.java:104:59:104:77 | new URI(...) : URI | provenance | MaD:285 | -| SanitizationTests.java:107:33:107:110 | format(...) : String | SanitizationTests.java:108:67:108:76 | unsafeUri7 : String | provenance | | -| SanitizationTests.java:107:33:107:110 | new ..[] { .. } : Object[] [[]] : String | SanitizationTests.java:107:33:107:110 | format(...) : String | provenance | MaD:281 | -| SanitizationTests.java:107:56:107:86 | getParameter(...) : String | SanitizationTests.java:107:33:107:110 | new ..[] { .. } : Object[] [[]] : String | provenance | Src:MaD:277 | -| SanitizationTests.java:108:36:108:78 | newBuilder(...) : Builder | SanitizationTests.java:108:36:108:86 | build(...) : HttpRequest | provenance | MaD:283 | -| SanitizationTests.java:108:36:108:86 | build(...) : HttpRequest | SanitizationTests.java:109:25:109:32 | unsafer7 | provenance | Sink:MaD:4 | -| SanitizationTests.java:108:59:108:77 | new URI(...) : URI | SanitizationTests.java:108:36:108:78 | newBuilder(...) : Builder | provenance | MaD:284 | -| SanitizationTests.java:108:67:108:76 | unsafeUri7 : String | SanitizationTests.java:108:59:108:77 | new URI(...) | provenance | Config Sink:MaD:6 | -| SanitizationTests.java:108:67:108:76 | unsafeUri7 : String | SanitizationTests.java:108:59:108:77 | new URI(...) | provenance | MaD:285 Sink:MaD:6 | -| SanitizationTests.java:108:67:108:76 | unsafeUri7 : String | SanitizationTests.java:108:59:108:77 | new URI(...) : URI | provenance | Config | -| SanitizationTests.java:108:67:108:76 | unsafeUri7 : String | SanitizationTests.java:108:59:108:77 | new URI(...) : URI | provenance | MaD:285 | -| SanitizationTests.java:111:33:111:110 | format(...) : String | SanitizationTests.java:112:67:112:76 | unsafeUri8 : String | provenance | | -| SanitizationTests.java:111:33:111:110 | new ..[] { .. } : Object[] [[]] : String | SanitizationTests.java:111:33:111:110 | format(...) : String | provenance | MaD:281 | -| SanitizationTests.java:111:55:111:85 | getParameter(...) : String | SanitizationTests.java:111:33:111:110 | new ..[] { .. } : Object[] [[]] : String | provenance | Src:MaD:277 | -| SanitizationTests.java:112:36:112:78 | newBuilder(...) : Builder | SanitizationTests.java:112:36:112:86 | build(...) : HttpRequest | provenance | MaD:283 | -| SanitizationTests.java:112:36:112:86 | build(...) : HttpRequest | SanitizationTests.java:113:25:113:32 | unsafer8 | provenance | Sink:MaD:4 | -| SanitizationTests.java:112:59:112:77 | new URI(...) : URI | SanitizationTests.java:112:36:112:78 | newBuilder(...) : Builder | provenance | MaD:284 | -| SanitizationTests.java:112:67:112:76 | unsafeUri8 : String | SanitizationTests.java:112:59:112:77 | new URI(...) | provenance | Config Sink:MaD:6 | -| SanitizationTests.java:112:67:112:76 | unsafeUri8 : String | SanitizationTests.java:112:59:112:77 | new URI(...) | provenance | MaD:285 Sink:MaD:6 | -| SanitizationTests.java:112:67:112:76 | unsafeUri8 : String | SanitizationTests.java:112:59:112:77 | new URI(...) : URI | provenance | Config | -| SanitizationTests.java:112:67:112:76 | unsafeUri8 : String | SanitizationTests.java:112:59:112:77 | new URI(...) : URI | provenance | MaD:285 | -| SanitizationTests.java:115:33:115:63 | getParameter(...) : String | SanitizationTests.java:116:67:116:76 | unsafeUri9 : String | provenance | Src:MaD:277 | -| SanitizationTests.java:116:36:116:78 | newBuilder(...) : Builder | SanitizationTests.java:116:36:116:86 | build(...) : HttpRequest | provenance | MaD:283 | -| SanitizationTests.java:116:36:116:86 | build(...) : HttpRequest | SanitizationTests.java:117:25:117:32 | unsafer9 | provenance | Sink:MaD:4 | -| SanitizationTests.java:116:59:116:77 | new URI(...) : URI | SanitizationTests.java:116:36:116:78 | newBuilder(...) : Builder | provenance | MaD:284 | -| SanitizationTests.java:116:67:116:76 | unsafeUri9 : String | SanitizationTests.java:116:59:116:77 | new URI(...) | provenance | Config Sink:MaD:6 | -| SanitizationTests.java:116:67:116:76 | unsafeUri9 : String | SanitizationTests.java:116:59:116:77 | new URI(...) | provenance | MaD:285 Sink:MaD:6 | -| SanitizationTests.java:116:67:116:76 | unsafeUri9 : String | SanitizationTests.java:116:59:116:77 | new URI(...) : URI | provenance | Config | -| SanitizationTests.java:116:67:116:76 | unsafeUri9 : String | SanitizationTests.java:116:59:116:77 | new URI(...) : URI | provenance | MaD:285 | -| SanitizationTests.java:119:34:119:126 | format(...) : String | SanitizationTests.java:120:68:120:78 | unsafeUri10 : String | provenance | | -| SanitizationTests.java:119:34:119:126 | new ..[] { .. } : Object[] [[]] : String | SanitizationTests.java:119:34:119:126 | format(...) : String | provenance | MaD:281 | -| SanitizationTests.java:119:94:119:125 | getParameter(...) : String | SanitizationTests.java:119:34:119:126 | new ..[] { .. } : Object[] [[]] : String | provenance | Src:MaD:277 | -| SanitizationTests.java:120:37:120:80 | newBuilder(...) : Builder | SanitizationTests.java:120:37:120:88 | build(...) : HttpRequest | provenance | MaD:283 | -| SanitizationTests.java:120:37:120:88 | build(...) : HttpRequest | SanitizationTests.java:121:25:121:33 | unsafer10 | provenance | Sink:MaD:4 | -| SanitizationTests.java:120:60:120:79 | new URI(...) : URI | SanitizationTests.java:120:37:120:80 | newBuilder(...) : Builder | provenance | MaD:284 | -| SanitizationTests.java:120:68:120:78 | unsafeUri10 : String | SanitizationTests.java:120:60:120:79 | new URI(...) | provenance | Config Sink:MaD:6 | -| SanitizationTests.java:120:68:120:78 | unsafeUri10 : String | SanitizationTests.java:120:60:120:79 | new URI(...) | provenance | MaD:285 Sink:MaD:6 | -| SanitizationTests.java:120:68:120:78 | unsafeUri10 : String | SanitizationTests.java:120:60:120:79 | new URI(...) : URI | provenance | Config | -| SanitizationTests.java:120:68:120:78 | unsafeUri10 : String | SanitizationTests.java:120:60:120:79 | new URI(...) : URI | provenance | MaD:285 | +| SanitizationTests.java:21:23:21:58 | new URI(...) : URI | SanitizationTests.java:24:52:24:54 | uri | provenance | Sink:MaD:6 | +| SanitizationTests.java:21:23:21:58 | new URI(...) : URI | SanitizationTests.java:24:52:24:54 | uri : URI | provenance | | +| SanitizationTests.java:21:31:21:57 | getParameter(...) : String | SanitizationTests.java:21:23:21:58 | new URI(...) : URI | provenance | Src:MaD:277 Config | +| SanitizationTests.java:21:31:21:57 | getParameter(...) : String | SanitizationTests.java:21:23:21:58 | new URI(...) : URI | provenance | Src:MaD:277 MaD:285 | +| SanitizationTests.java:24:29:24:55 | newBuilder(...) : Builder | SanitizationTests.java:24:29:24:63 | build(...) : HttpRequest | provenance | MaD:283 | +| SanitizationTests.java:24:29:24:63 | build(...) : HttpRequest | SanitizationTests.java:25:25:25:25 | r | provenance | Sink:MaD:4 | +| SanitizationTests.java:24:52:24:54 | uri : URI | SanitizationTests.java:24:29:24:55 | newBuilder(...) : Builder | provenance | MaD:284 | +| SanitizationTests.java:77:33:77:63 | getParameter(...) : String | SanitizationTests.java:78:67:78:76 | unsafeUri3 : String | provenance | Src:MaD:277 | +| SanitizationTests.java:78:36:78:78 | newBuilder(...) : Builder | SanitizationTests.java:78:36:78:86 | build(...) : HttpRequest | provenance | MaD:283 | +| SanitizationTests.java:78:36:78:86 | build(...) : HttpRequest | SanitizationTests.java:79:25:79:32 | unsafer3 | provenance | Sink:MaD:4 | +| SanitizationTests.java:78:59:78:77 | new URI(...) : URI | SanitizationTests.java:78:36:78:78 | newBuilder(...) : Builder | provenance | MaD:284 | +| SanitizationTests.java:78:67:78:76 | unsafeUri3 : String | SanitizationTests.java:78:59:78:77 | new URI(...) | provenance | Config Sink:MaD:6 | +| SanitizationTests.java:78:67:78:76 | unsafeUri3 : String | SanitizationTests.java:78:59:78:77 | new URI(...) | provenance | MaD:285 Sink:MaD:6 | +| SanitizationTests.java:78:67:78:76 | unsafeUri3 : String | SanitizationTests.java:78:59:78:77 | new URI(...) : URI | provenance | Config | +| SanitizationTests.java:78:67:78:76 | unsafeUri3 : String | SanitizationTests.java:78:59:78:77 | new URI(...) : URI | provenance | MaD:285 | +| SanitizationTests.java:81:49:81:79 | getParameter(...) : String | SanitizationTests.java:82:67:82:76 | unsafeUri4 : String | provenance | Src:MaD:277 | +| SanitizationTests.java:82:36:82:78 | newBuilder(...) : Builder | SanitizationTests.java:82:36:82:86 | build(...) : HttpRequest | provenance | MaD:283 | +| SanitizationTests.java:82:36:82:86 | build(...) : HttpRequest | SanitizationTests.java:83:25:83:32 | unsafer4 | provenance | Sink:MaD:4 | +| SanitizationTests.java:82:59:82:77 | new URI(...) : URI | SanitizationTests.java:82:36:82:78 | newBuilder(...) : Builder | provenance | MaD:284 | +| SanitizationTests.java:82:67:82:76 | unsafeUri4 : String | SanitizationTests.java:82:59:82:77 | new URI(...) | provenance | Config Sink:MaD:6 | +| SanitizationTests.java:82:67:82:76 | unsafeUri4 : String | SanitizationTests.java:82:59:82:77 | new URI(...) | provenance | MaD:285 Sink:MaD:6 | +| SanitizationTests.java:82:67:82:76 | unsafeUri4 : String | SanitizationTests.java:82:59:82:77 | new URI(...) : URI | provenance | Config | +| SanitizationTests.java:82:67:82:76 | unsafeUri4 : String | SanitizationTests.java:82:59:82:77 | new URI(...) : URI | provenance | MaD:285 | +| SanitizationTests.java:86:13:86:22 | unsafeUri5 [post update] : StringBuilder | SanitizationTests.java:87:67:87:76 | unsafeUri5 : StringBuilder | provenance | | +| SanitizationTests.java:86:31:86:61 | getParameter(...) : String | SanitizationTests.java:86:13:86:22 | unsafeUri5 [post update] : StringBuilder | provenance | Src:MaD:277 MaD:278 | +| SanitizationTests.java:87:36:87:89 | newBuilder(...) : Builder | SanitizationTests.java:87:36:87:97 | build(...) : HttpRequest | provenance | MaD:283 | +| SanitizationTests.java:87:36:87:97 | build(...) : HttpRequest | SanitizationTests.java:88:25:88:32 | unsafer5 | provenance | Sink:MaD:4 | +| SanitizationTests.java:87:59:87:88 | new URI(...) : URI | SanitizationTests.java:87:36:87:89 | newBuilder(...) : Builder | provenance | MaD:284 | +| SanitizationTests.java:87:67:87:76 | unsafeUri5 : StringBuilder | SanitizationTests.java:87:67:87:87 | toString(...) : String | provenance | MaD:280 | +| SanitizationTests.java:87:67:87:87 | toString(...) : String | SanitizationTests.java:87:59:87:88 | new URI(...) | provenance | Config Sink:MaD:6 | +| SanitizationTests.java:87:67:87:87 | toString(...) : String | SanitizationTests.java:87:59:87:88 | new URI(...) | provenance | MaD:285 Sink:MaD:6 | +| SanitizationTests.java:87:67:87:87 | toString(...) : String | SanitizationTests.java:87:59:87:88 | new URI(...) : URI | provenance | Config | +| SanitizationTests.java:87:67:87:87 | toString(...) : String | SanitizationTests.java:87:59:87:88 | new URI(...) : URI | provenance | MaD:285 | +| SanitizationTests.java:90:40:90:87 | new StringBuilder(...) : StringBuilder | SanitizationTests.java:92:68:92:77 | unafeUri5a : StringBuilder | provenance | | +| SanitizationTests.java:90:58:90:86 | getParameter(...) : String | SanitizationTests.java:90:40:90:87 | new StringBuilder(...) : StringBuilder | provenance | Src:MaD:277 MaD:282 | +| SanitizationTests.java:92:37:92:90 | newBuilder(...) : Builder | SanitizationTests.java:92:37:92:98 | build(...) : HttpRequest | provenance | MaD:283 | +| SanitizationTests.java:92:37:92:98 | build(...) : HttpRequest | SanitizationTests.java:93:25:93:33 | unsafer5a | provenance | Sink:MaD:4 | +| SanitizationTests.java:92:60:92:89 | new URI(...) : URI | SanitizationTests.java:92:37:92:90 | newBuilder(...) : Builder | provenance | MaD:284 | +| SanitizationTests.java:92:68:92:77 | unafeUri5a : StringBuilder | SanitizationTests.java:92:68:92:88 | toString(...) : String | provenance | MaD:280 | +| SanitizationTests.java:92:68:92:88 | toString(...) : String | SanitizationTests.java:92:60:92:89 | new URI(...) | provenance | Config Sink:MaD:6 | +| SanitizationTests.java:92:68:92:88 | toString(...) : String | SanitizationTests.java:92:60:92:89 | new URI(...) | provenance | MaD:285 Sink:MaD:6 | +| SanitizationTests.java:92:68:92:88 | toString(...) : String | SanitizationTests.java:92:60:92:89 | new URI(...) : URI | provenance | Config | +| SanitizationTests.java:92:68:92:88 | toString(...) : String | SanitizationTests.java:92:60:92:89 | new URI(...) : URI | provenance | MaD:285 | +| SanitizationTests.java:95:41:95:105 | append(...) : StringBuilder | SanitizationTests.java:97:68:97:78 | unsafeUri5b : StringBuilder | provenance | | +| SanitizationTests.java:95:42:95:89 | new StringBuilder(...) : StringBuilder | SanitizationTests.java:95:41:95:105 | append(...) : StringBuilder | provenance | MaD:279 | +| SanitizationTests.java:95:60:95:88 | getParameter(...) : String | SanitizationTests.java:95:42:95:89 | new StringBuilder(...) : StringBuilder | provenance | Src:MaD:277 MaD:282 | +| SanitizationTests.java:97:37:97:91 | newBuilder(...) : Builder | SanitizationTests.java:97:37:97:99 | build(...) : HttpRequest | provenance | MaD:283 | +| SanitizationTests.java:97:37:97:99 | build(...) : HttpRequest | SanitizationTests.java:98:25:98:33 | unsafer5b | provenance | Sink:MaD:4 | +| SanitizationTests.java:97:60:97:90 | new URI(...) : URI | SanitizationTests.java:97:37:97:91 | newBuilder(...) : Builder | provenance | MaD:284 | +| SanitizationTests.java:97:68:97:78 | unsafeUri5b : StringBuilder | SanitizationTests.java:97:68:97:89 | toString(...) : String | provenance | MaD:280 | +| SanitizationTests.java:97:68:97:89 | toString(...) : String | SanitizationTests.java:97:60:97:90 | new URI(...) | provenance | Config Sink:MaD:6 | +| SanitizationTests.java:97:68:97:89 | toString(...) : String | SanitizationTests.java:97:60:97:90 | new URI(...) | provenance | MaD:285 Sink:MaD:6 | +| SanitizationTests.java:97:68:97:89 | toString(...) : String | SanitizationTests.java:97:60:97:90 | new URI(...) : URI | provenance | Config | +| SanitizationTests.java:97:68:97:89 | toString(...) : String | SanitizationTests.java:97:60:97:90 | new URI(...) : URI | provenance | MaD:285 | +| SanitizationTests.java:100:41:100:106 | append(...) : StringBuilder | SanitizationTests.java:102:68:102:78 | unsafeUri5c : StringBuilder | provenance | | +| SanitizationTests.java:100:77:100:105 | getParameter(...) : String | SanitizationTests.java:100:41:100:106 | append(...) : StringBuilder | provenance | Src:MaD:277 MaD:278+MaD:279 | +| SanitizationTests.java:102:37:102:91 | newBuilder(...) : Builder | SanitizationTests.java:102:37:102:99 | build(...) : HttpRequest | provenance | MaD:283 | +| SanitizationTests.java:102:37:102:99 | build(...) : HttpRequest | SanitizationTests.java:103:25:103:33 | unsafer5c | provenance | Sink:MaD:4 | +| SanitizationTests.java:102:60:102:90 | new URI(...) : URI | SanitizationTests.java:102:37:102:91 | newBuilder(...) : Builder | provenance | MaD:284 | +| SanitizationTests.java:102:68:102:78 | unsafeUri5c : StringBuilder | SanitizationTests.java:102:68:102:89 | toString(...) : String | provenance | MaD:280 | +| SanitizationTests.java:102:68:102:89 | toString(...) : String | SanitizationTests.java:102:60:102:90 | new URI(...) | provenance | Config Sink:MaD:6 | +| SanitizationTests.java:102:68:102:89 | toString(...) : String | SanitizationTests.java:102:60:102:90 | new URI(...) | provenance | MaD:285 Sink:MaD:6 | +| SanitizationTests.java:102:68:102:89 | toString(...) : String | SanitizationTests.java:102:60:102:90 | new URI(...) : URI | provenance | Config | +| SanitizationTests.java:102:68:102:89 | toString(...) : String | SanitizationTests.java:102:60:102:90 | new URI(...) : URI | provenance | MaD:285 | +| SanitizationTests.java:105:33:105:104 | format(...) : String | SanitizationTests.java:106:67:106:76 | unsafeUri6 : String | provenance | | +| SanitizationTests.java:105:33:105:104 | new ..[] { .. } : Object[] [[]] : String | SanitizationTests.java:105:33:105:104 | format(...) : String | provenance | MaD:281 | +| SanitizationTests.java:105:73:105:103 | getParameter(...) : String | SanitizationTests.java:105:33:105:104 | new ..[] { .. } : Object[] [[]] : String | provenance | Src:MaD:277 | +| SanitizationTests.java:106:36:106:78 | newBuilder(...) : Builder | SanitizationTests.java:106:36:106:86 | build(...) : HttpRequest | provenance | MaD:283 | +| SanitizationTests.java:106:36:106:86 | build(...) : HttpRequest | SanitizationTests.java:107:25:107:32 | unsafer6 | provenance | Sink:MaD:4 | +| SanitizationTests.java:106:59:106:77 | new URI(...) : URI | SanitizationTests.java:106:36:106:78 | newBuilder(...) : Builder | provenance | MaD:284 | +| SanitizationTests.java:106:67:106:76 | unsafeUri6 : String | SanitizationTests.java:106:59:106:77 | new URI(...) | provenance | Config Sink:MaD:6 | +| SanitizationTests.java:106:67:106:76 | unsafeUri6 : String | SanitizationTests.java:106:59:106:77 | new URI(...) | provenance | MaD:285 Sink:MaD:6 | +| SanitizationTests.java:106:67:106:76 | unsafeUri6 : String | SanitizationTests.java:106:59:106:77 | new URI(...) : URI | provenance | Config | +| SanitizationTests.java:106:67:106:76 | unsafeUri6 : String | SanitizationTests.java:106:59:106:77 | new URI(...) : URI | provenance | MaD:285 | +| SanitizationTests.java:109:33:109:110 | format(...) : String | SanitizationTests.java:110:67:110:76 | unsafeUri7 : String | provenance | | +| SanitizationTests.java:109:33:109:110 | new ..[] { .. } : Object[] [[]] : String | SanitizationTests.java:109:33:109:110 | format(...) : String | provenance | MaD:281 | +| SanitizationTests.java:109:56:109:86 | getParameter(...) : String | SanitizationTests.java:109:33:109:110 | new ..[] { .. } : Object[] [[]] : String | provenance | Src:MaD:277 | +| SanitizationTests.java:110:36:110:78 | newBuilder(...) : Builder | SanitizationTests.java:110:36:110:86 | build(...) : HttpRequest | provenance | MaD:283 | +| SanitizationTests.java:110:36:110:86 | build(...) : HttpRequest | SanitizationTests.java:111:25:111:32 | unsafer7 | provenance | Sink:MaD:4 | +| SanitizationTests.java:110:59:110:77 | new URI(...) : URI | SanitizationTests.java:110:36:110:78 | newBuilder(...) : Builder | provenance | MaD:284 | +| SanitizationTests.java:110:67:110:76 | unsafeUri7 : String | SanitizationTests.java:110:59:110:77 | new URI(...) | provenance | Config Sink:MaD:6 | +| SanitizationTests.java:110:67:110:76 | unsafeUri7 : String | SanitizationTests.java:110:59:110:77 | new URI(...) | provenance | MaD:285 Sink:MaD:6 | +| SanitizationTests.java:110:67:110:76 | unsafeUri7 : String | SanitizationTests.java:110:59:110:77 | new URI(...) : URI | provenance | Config | +| SanitizationTests.java:110:67:110:76 | unsafeUri7 : String | SanitizationTests.java:110:59:110:77 | new URI(...) : URI | provenance | MaD:285 | +| SanitizationTests.java:113:33:113:110 | format(...) : String | SanitizationTests.java:114:67:114:76 | unsafeUri8 : String | provenance | | +| SanitizationTests.java:113:33:113:110 | new ..[] { .. } : Object[] [[]] : String | SanitizationTests.java:113:33:113:110 | format(...) : String | provenance | MaD:281 | +| SanitizationTests.java:113:55:113:85 | getParameter(...) : String | SanitizationTests.java:113:33:113:110 | new ..[] { .. } : Object[] [[]] : String | provenance | Src:MaD:277 | +| SanitizationTests.java:114:36:114:78 | newBuilder(...) : Builder | SanitizationTests.java:114:36:114:86 | build(...) : HttpRequest | provenance | MaD:283 | +| SanitizationTests.java:114:36:114:86 | build(...) : HttpRequest | SanitizationTests.java:115:25:115:32 | unsafer8 | provenance | Sink:MaD:4 | +| SanitizationTests.java:114:59:114:77 | new URI(...) : URI | SanitizationTests.java:114:36:114:78 | newBuilder(...) : Builder | provenance | MaD:284 | +| SanitizationTests.java:114:67:114:76 | unsafeUri8 : String | SanitizationTests.java:114:59:114:77 | new URI(...) | provenance | Config Sink:MaD:6 | +| SanitizationTests.java:114:67:114:76 | unsafeUri8 : String | SanitizationTests.java:114:59:114:77 | new URI(...) | provenance | MaD:285 Sink:MaD:6 | +| SanitizationTests.java:114:67:114:76 | unsafeUri8 : String | SanitizationTests.java:114:59:114:77 | new URI(...) : URI | provenance | Config | +| SanitizationTests.java:114:67:114:76 | unsafeUri8 : String | SanitizationTests.java:114:59:114:77 | new URI(...) : URI | provenance | MaD:285 | +| SanitizationTests.java:117:33:117:63 | getParameter(...) : String | SanitizationTests.java:118:67:118:76 | unsafeUri9 : String | provenance | Src:MaD:277 | +| SanitizationTests.java:118:36:118:78 | newBuilder(...) : Builder | SanitizationTests.java:118:36:118:86 | build(...) : HttpRequest | provenance | MaD:283 | +| SanitizationTests.java:118:36:118:86 | build(...) : HttpRequest | SanitizationTests.java:119:25:119:32 | unsafer9 | provenance | Sink:MaD:4 | +| SanitizationTests.java:118:59:118:77 | new URI(...) : URI | SanitizationTests.java:118:36:118:78 | newBuilder(...) : Builder | provenance | MaD:284 | +| SanitizationTests.java:118:67:118:76 | unsafeUri9 : String | SanitizationTests.java:118:59:118:77 | new URI(...) | provenance | Config Sink:MaD:6 | +| SanitizationTests.java:118:67:118:76 | unsafeUri9 : String | SanitizationTests.java:118:59:118:77 | new URI(...) | provenance | MaD:285 Sink:MaD:6 | +| SanitizationTests.java:118:67:118:76 | unsafeUri9 : String | SanitizationTests.java:118:59:118:77 | new URI(...) : URI | provenance | Config | +| SanitizationTests.java:118:67:118:76 | unsafeUri9 : String | SanitizationTests.java:118:59:118:77 | new URI(...) : URI | provenance | MaD:285 | +| SanitizationTests.java:121:34:121:126 | format(...) : String | SanitizationTests.java:122:68:122:78 | unsafeUri10 : String | provenance | | +| SanitizationTests.java:121:34:121:126 | new ..[] { .. } : Object[] [[]] : String | SanitizationTests.java:121:34:121:126 | format(...) : String | provenance | MaD:281 | +| SanitizationTests.java:121:94:121:125 | getParameter(...) : String | SanitizationTests.java:121:34:121:126 | new ..[] { .. } : Object[] [[]] : String | provenance | Src:MaD:277 | +| SanitizationTests.java:122:37:122:80 | newBuilder(...) : Builder | SanitizationTests.java:122:37:122:88 | build(...) : HttpRequest | provenance | MaD:283 | +| SanitizationTests.java:122:37:122:88 | build(...) : HttpRequest | SanitizationTests.java:123:25:123:33 | unsafer10 | provenance | Sink:MaD:4 | +| SanitizationTests.java:122:60:122:79 | new URI(...) : URI | SanitizationTests.java:122:37:122:80 | newBuilder(...) : Builder | provenance | MaD:284 | +| SanitizationTests.java:122:68:122:78 | unsafeUri10 : String | SanitizationTests.java:122:60:122:79 | new URI(...) | provenance | Config Sink:MaD:6 | +| SanitizationTests.java:122:68:122:78 | unsafeUri10 : String | SanitizationTests.java:122:60:122:79 | new URI(...) | provenance | MaD:285 Sink:MaD:6 | +| SanitizationTests.java:122:68:122:78 | unsafeUri10 : String | SanitizationTests.java:122:60:122:79 | new URI(...) : URI | provenance | Config | +| SanitizationTests.java:122:68:122:78 | unsafeUri10 : String | SanitizationTests.java:122:60:122:79 | new URI(...) : URI | provenance | MaD:285 | | SpringSSRF.java:28:33:28:60 | getParameter(...) : String | SpringSSRF.java:32:39:32:59 | ... + ... | provenance | Src:MaD:277 Sink:MaD:264 | | SpringSSRF.java:28:33:28:60 | getParameter(...) : String | SpringSSRF.java:33:35:33:48 | fooResourceUrl | provenance | Src:MaD:277 Sink:MaD:262 | | SpringSSRF.java:28:33:28:60 | getParameter(...) : String | SpringSSRF.java:34:34:34:47 | fooResourceUrl | provenance | Src:MaD:277 Sink:MaD:263 | @@ -1580,107 +1580,107 @@ nodes | ReactiveWebClientSSRF.java:16:52:16:54 | url | semmle.label | url | | ReactiveWebClientSSRF.java:32:26:32:52 | getParameter(...) : String | semmle.label | getParameter(...) : String | | ReactiveWebClientSSRF.java:35:30:35:32 | url | semmle.label | url | -| SanitizationTests.java:19:23:19:58 | new URI(...) : URI | semmle.label | new URI(...) : URI | -| SanitizationTests.java:19:31:19:57 | getParameter(...) : String | semmle.label | getParameter(...) : String | -| SanitizationTests.java:22:29:22:55 | newBuilder(...) : Builder | semmle.label | newBuilder(...) : Builder | -| SanitizationTests.java:22:29:22:63 | build(...) : HttpRequest | semmle.label | build(...) : HttpRequest | -| SanitizationTests.java:22:52:22:54 | uri | semmle.label | uri | -| SanitizationTests.java:22:52:22:54 | uri : URI | semmle.label | uri : URI | -| SanitizationTests.java:23:25:23:25 | r | semmle.label | r | -| SanitizationTests.java:75:33:75:63 | getParameter(...) : String | semmle.label | getParameter(...) : String | -| SanitizationTests.java:76:36:76:78 | newBuilder(...) : Builder | semmle.label | newBuilder(...) : Builder | -| SanitizationTests.java:76:36:76:86 | build(...) : HttpRequest | semmle.label | build(...) : HttpRequest | -| SanitizationTests.java:76:59:76:77 | new URI(...) | semmle.label | new URI(...) | -| SanitizationTests.java:76:59:76:77 | new URI(...) : URI | semmle.label | new URI(...) : URI | -| SanitizationTests.java:76:67:76:76 | unsafeUri3 : String | semmle.label | unsafeUri3 : String | -| SanitizationTests.java:77:25:77:32 | unsafer3 | semmle.label | unsafer3 | -| SanitizationTests.java:79:49:79:79 | getParameter(...) : String | semmle.label | getParameter(...) : String | -| SanitizationTests.java:80:36:80:78 | newBuilder(...) : Builder | semmle.label | newBuilder(...) : Builder | -| SanitizationTests.java:80:36:80:86 | build(...) : HttpRequest | semmle.label | build(...) : HttpRequest | -| SanitizationTests.java:80:59:80:77 | new URI(...) | semmle.label | new URI(...) | -| SanitizationTests.java:80:59:80:77 | new URI(...) : URI | semmle.label | new URI(...) : URI | -| SanitizationTests.java:80:67:80:76 | unsafeUri4 : String | semmle.label | unsafeUri4 : String | -| SanitizationTests.java:81:25:81:32 | unsafer4 | semmle.label | unsafer4 | -| SanitizationTests.java:84:13:84:22 | unsafeUri5 [post update] : StringBuilder | semmle.label | unsafeUri5 [post update] : StringBuilder | -| SanitizationTests.java:84:31:84:61 | getParameter(...) : String | semmle.label | getParameter(...) : String | -| SanitizationTests.java:85:36:85:89 | newBuilder(...) : Builder | semmle.label | newBuilder(...) : Builder | -| SanitizationTests.java:85:36:85:97 | build(...) : HttpRequest | semmle.label | build(...) : HttpRequest | -| SanitizationTests.java:85:59:85:88 | new URI(...) | semmle.label | new URI(...) | -| SanitizationTests.java:85:59:85:88 | new URI(...) : URI | semmle.label | new URI(...) : URI | -| SanitizationTests.java:85:67:85:76 | unsafeUri5 : StringBuilder | semmle.label | unsafeUri5 : StringBuilder | -| SanitizationTests.java:85:67:85:87 | toString(...) : String | semmle.label | toString(...) : String | -| SanitizationTests.java:86:25:86:32 | unsafer5 | semmle.label | unsafer5 | -| SanitizationTests.java:88:40:88:87 | new StringBuilder(...) : StringBuilder | semmle.label | new StringBuilder(...) : StringBuilder | -| SanitizationTests.java:88:58:88:86 | getParameter(...) : String | semmle.label | getParameter(...) : String | -| SanitizationTests.java:90:37:90:90 | newBuilder(...) : Builder | semmle.label | newBuilder(...) : Builder | -| SanitizationTests.java:90:37:90:98 | build(...) : HttpRequest | semmle.label | build(...) : HttpRequest | -| SanitizationTests.java:90:60:90:89 | new URI(...) | semmle.label | new URI(...) | -| SanitizationTests.java:90:60:90:89 | new URI(...) : URI | semmle.label | new URI(...) : URI | -| SanitizationTests.java:90:68:90:77 | unafeUri5a : StringBuilder | semmle.label | unafeUri5a : StringBuilder | -| SanitizationTests.java:90:68:90:88 | toString(...) : String | semmle.label | toString(...) : String | -| SanitizationTests.java:91:25:91:33 | unsafer5a | semmle.label | unsafer5a | -| SanitizationTests.java:93:41:93:105 | append(...) : StringBuilder | semmle.label | append(...) : StringBuilder | -| SanitizationTests.java:93:42:93:89 | new StringBuilder(...) : StringBuilder | semmle.label | new StringBuilder(...) : StringBuilder | -| SanitizationTests.java:93:60:93:88 | getParameter(...) : String | semmle.label | getParameter(...) : String | -| SanitizationTests.java:95:37:95:91 | newBuilder(...) : Builder | semmle.label | newBuilder(...) : Builder | -| SanitizationTests.java:95:37:95:99 | build(...) : HttpRequest | semmle.label | build(...) : HttpRequest | -| SanitizationTests.java:95:60:95:90 | new URI(...) | semmle.label | new URI(...) | -| SanitizationTests.java:95:60:95:90 | new URI(...) : URI | semmle.label | new URI(...) : URI | -| SanitizationTests.java:95:68:95:78 | unsafeUri5b : StringBuilder | semmle.label | unsafeUri5b : StringBuilder | -| SanitizationTests.java:95:68:95:89 | toString(...) : String | semmle.label | toString(...) : String | -| SanitizationTests.java:96:25:96:33 | unsafer5b | semmle.label | unsafer5b | -| SanitizationTests.java:98:41:98:106 | append(...) : StringBuilder | semmle.label | append(...) : StringBuilder | -| SanitizationTests.java:98:77:98:105 | getParameter(...) : String | semmle.label | getParameter(...) : String | -| SanitizationTests.java:100:37:100:91 | newBuilder(...) : Builder | semmle.label | newBuilder(...) : Builder | -| SanitizationTests.java:100:37:100:99 | build(...) : HttpRequest | semmle.label | build(...) : HttpRequest | -| SanitizationTests.java:100:60:100:90 | new URI(...) | semmle.label | new URI(...) | -| SanitizationTests.java:100:60:100:90 | new URI(...) : URI | semmle.label | new URI(...) : URI | -| SanitizationTests.java:100:68:100:78 | unsafeUri5c : StringBuilder | semmle.label | unsafeUri5c : StringBuilder | -| SanitizationTests.java:100:68:100:89 | toString(...) : String | semmle.label | toString(...) : String | -| SanitizationTests.java:101:25:101:33 | unsafer5c | semmle.label | unsafer5c | -| SanitizationTests.java:103:33:103:104 | format(...) : String | semmle.label | format(...) : String | -| SanitizationTests.java:103:33:103:104 | new ..[] { .. } : Object[] [[]] : String | semmle.label | new ..[] { .. } : Object[] [[]] : String | -| SanitizationTests.java:103:73:103:103 | getParameter(...) : String | semmle.label | getParameter(...) : String | -| SanitizationTests.java:104:36:104:78 | newBuilder(...) : Builder | semmle.label | newBuilder(...) : Builder | -| SanitizationTests.java:104:36:104:86 | build(...) : HttpRequest | semmle.label | build(...) : HttpRequest | -| SanitizationTests.java:104:59:104:77 | new URI(...) | semmle.label | new URI(...) | -| SanitizationTests.java:104:59:104:77 | new URI(...) : URI | semmle.label | new URI(...) : URI | -| SanitizationTests.java:104:67:104:76 | unsafeUri6 : String | semmle.label | unsafeUri6 : String | -| SanitizationTests.java:105:25:105:32 | unsafer6 | semmle.label | unsafer6 | -| SanitizationTests.java:107:33:107:110 | format(...) : String | semmle.label | format(...) : String | -| SanitizationTests.java:107:33:107:110 | new ..[] { .. } : Object[] [[]] : String | semmle.label | new ..[] { .. } : Object[] [[]] : String | -| SanitizationTests.java:107:56:107:86 | getParameter(...) : String | semmle.label | getParameter(...) : String | -| SanitizationTests.java:108:36:108:78 | newBuilder(...) : Builder | semmle.label | newBuilder(...) : Builder | -| SanitizationTests.java:108:36:108:86 | build(...) : HttpRequest | semmle.label | build(...) : HttpRequest | -| SanitizationTests.java:108:59:108:77 | new URI(...) | semmle.label | new URI(...) | -| SanitizationTests.java:108:59:108:77 | new URI(...) : URI | semmle.label | new URI(...) : URI | -| SanitizationTests.java:108:67:108:76 | unsafeUri7 : String | semmle.label | unsafeUri7 : String | -| SanitizationTests.java:109:25:109:32 | unsafer7 | semmle.label | unsafer7 | -| SanitizationTests.java:111:33:111:110 | format(...) : String | semmle.label | format(...) : String | -| SanitizationTests.java:111:33:111:110 | new ..[] { .. } : Object[] [[]] : String | semmle.label | new ..[] { .. } : Object[] [[]] : String | -| SanitizationTests.java:111:55:111:85 | getParameter(...) : String | semmle.label | getParameter(...) : String | -| SanitizationTests.java:112:36:112:78 | newBuilder(...) : Builder | semmle.label | newBuilder(...) : Builder | -| SanitizationTests.java:112:36:112:86 | build(...) : HttpRequest | semmle.label | build(...) : HttpRequest | -| SanitizationTests.java:112:59:112:77 | new URI(...) | semmle.label | new URI(...) | -| SanitizationTests.java:112:59:112:77 | new URI(...) : URI | semmle.label | new URI(...) : URI | -| SanitizationTests.java:112:67:112:76 | unsafeUri8 : String | semmle.label | unsafeUri8 : String | -| SanitizationTests.java:113:25:113:32 | unsafer8 | semmle.label | unsafer8 | -| SanitizationTests.java:115:33:115:63 | getParameter(...) : String | semmle.label | getParameter(...) : String | -| SanitizationTests.java:116:36:116:78 | newBuilder(...) : Builder | semmle.label | newBuilder(...) : Builder | -| SanitizationTests.java:116:36:116:86 | build(...) : HttpRequest | semmle.label | build(...) : HttpRequest | -| SanitizationTests.java:116:59:116:77 | new URI(...) | semmle.label | new URI(...) | -| SanitizationTests.java:116:59:116:77 | new URI(...) : URI | semmle.label | new URI(...) : URI | -| SanitizationTests.java:116:67:116:76 | unsafeUri9 : String | semmle.label | unsafeUri9 : String | -| SanitizationTests.java:117:25:117:32 | unsafer9 | semmle.label | unsafer9 | -| SanitizationTests.java:119:34:119:126 | format(...) : String | semmle.label | format(...) : String | -| SanitizationTests.java:119:34:119:126 | new ..[] { .. } : Object[] [[]] : String | semmle.label | new ..[] { .. } : Object[] [[]] : String | -| SanitizationTests.java:119:94:119:125 | getParameter(...) : String | semmle.label | getParameter(...) : String | -| SanitizationTests.java:120:37:120:80 | newBuilder(...) : Builder | semmle.label | newBuilder(...) : Builder | -| SanitizationTests.java:120:37:120:88 | build(...) : HttpRequest | semmle.label | build(...) : HttpRequest | -| SanitizationTests.java:120:60:120:79 | new URI(...) | semmle.label | new URI(...) | -| SanitizationTests.java:120:60:120:79 | new URI(...) : URI | semmle.label | new URI(...) : URI | -| SanitizationTests.java:120:68:120:78 | unsafeUri10 : String | semmle.label | unsafeUri10 : String | -| SanitizationTests.java:121:25:121:33 | unsafer10 | semmle.label | unsafer10 | +| SanitizationTests.java:21:23:21:58 | new URI(...) : URI | semmle.label | new URI(...) : URI | +| SanitizationTests.java:21:31:21:57 | getParameter(...) : String | semmle.label | getParameter(...) : String | +| SanitizationTests.java:24:29:24:55 | newBuilder(...) : Builder | semmle.label | newBuilder(...) : Builder | +| SanitizationTests.java:24:29:24:63 | build(...) : HttpRequest | semmle.label | build(...) : HttpRequest | +| SanitizationTests.java:24:52:24:54 | uri | semmle.label | uri | +| SanitizationTests.java:24:52:24:54 | uri : URI | semmle.label | uri : URI | +| SanitizationTests.java:25:25:25:25 | r | semmle.label | r | +| SanitizationTests.java:77:33:77:63 | getParameter(...) : String | semmle.label | getParameter(...) : String | +| SanitizationTests.java:78:36:78:78 | newBuilder(...) : Builder | semmle.label | newBuilder(...) : Builder | +| SanitizationTests.java:78:36:78:86 | build(...) : HttpRequest | semmle.label | build(...) : HttpRequest | +| SanitizationTests.java:78:59:78:77 | new URI(...) | semmle.label | new URI(...) | +| SanitizationTests.java:78:59:78:77 | new URI(...) : URI | semmle.label | new URI(...) : URI | +| SanitizationTests.java:78:67:78:76 | unsafeUri3 : String | semmle.label | unsafeUri3 : String | +| SanitizationTests.java:79:25:79:32 | unsafer3 | semmle.label | unsafer3 | +| SanitizationTests.java:81:49:81:79 | getParameter(...) : String | semmle.label | getParameter(...) : String | +| SanitizationTests.java:82:36:82:78 | newBuilder(...) : Builder | semmle.label | newBuilder(...) : Builder | +| SanitizationTests.java:82:36:82:86 | build(...) : HttpRequest | semmle.label | build(...) : HttpRequest | +| SanitizationTests.java:82:59:82:77 | new URI(...) | semmle.label | new URI(...) | +| SanitizationTests.java:82:59:82:77 | new URI(...) : URI | semmle.label | new URI(...) : URI | +| SanitizationTests.java:82:67:82:76 | unsafeUri4 : String | semmle.label | unsafeUri4 : String | +| SanitizationTests.java:83:25:83:32 | unsafer4 | semmle.label | unsafer4 | +| SanitizationTests.java:86:13:86:22 | unsafeUri5 [post update] : StringBuilder | semmle.label | unsafeUri5 [post update] : StringBuilder | +| SanitizationTests.java:86:31:86:61 | getParameter(...) : String | semmle.label | getParameter(...) : String | +| SanitizationTests.java:87:36:87:89 | newBuilder(...) : Builder | semmle.label | newBuilder(...) : Builder | +| SanitizationTests.java:87:36:87:97 | build(...) : HttpRequest | semmle.label | build(...) : HttpRequest | +| SanitizationTests.java:87:59:87:88 | new URI(...) | semmle.label | new URI(...) | +| SanitizationTests.java:87:59:87:88 | new URI(...) : URI | semmle.label | new URI(...) : URI | +| SanitizationTests.java:87:67:87:76 | unsafeUri5 : StringBuilder | semmle.label | unsafeUri5 : StringBuilder | +| SanitizationTests.java:87:67:87:87 | toString(...) : String | semmle.label | toString(...) : String | +| SanitizationTests.java:88:25:88:32 | unsafer5 | semmle.label | unsafer5 | +| SanitizationTests.java:90:40:90:87 | new StringBuilder(...) : StringBuilder | semmle.label | new StringBuilder(...) : StringBuilder | +| SanitizationTests.java:90:58:90:86 | getParameter(...) : String | semmle.label | getParameter(...) : String | +| SanitizationTests.java:92:37:92:90 | newBuilder(...) : Builder | semmle.label | newBuilder(...) : Builder | +| SanitizationTests.java:92:37:92:98 | build(...) : HttpRequest | semmle.label | build(...) : HttpRequest | +| SanitizationTests.java:92:60:92:89 | new URI(...) | semmle.label | new URI(...) | +| SanitizationTests.java:92:60:92:89 | new URI(...) : URI | semmle.label | new URI(...) : URI | +| SanitizationTests.java:92:68:92:77 | unafeUri5a : StringBuilder | semmle.label | unafeUri5a : StringBuilder | +| SanitizationTests.java:92:68:92:88 | toString(...) : String | semmle.label | toString(...) : String | +| SanitizationTests.java:93:25:93:33 | unsafer5a | semmle.label | unsafer5a | +| SanitizationTests.java:95:41:95:105 | append(...) : StringBuilder | semmle.label | append(...) : StringBuilder | +| SanitizationTests.java:95:42:95:89 | new StringBuilder(...) : StringBuilder | semmle.label | new StringBuilder(...) : StringBuilder | +| SanitizationTests.java:95:60:95:88 | getParameter(...) : String | semmle.label | getParameter(...) : String | +| SanitizationTests.java:97:37:97:91 | newBuilder(...) : Builder | semmle.label | newBuilder(...) : Builder | +| SanitizationTests.java:97:37:97:99 | build(...) : HttpRequest | semmle.label | build(...) : HttpRequest | +| SanitizationTests.java:97:60:97:90 | new URI(...) | semmle.label | new URI(...) | +| SanitizationTests.java:97:60:97:90 | new URI(...) : URI | semmle.label | new URI(...) : URI | +| SanitizationTests.java:97:68:97:78 | unsafeUri5b : StringBuilder | semmle.label | unsafeUri5b : StringBuilder | +| SanitizationTests.java:97:68:97:89 | toString(...) : String | semmle.label | toString(...) : String | +| SanitizationTests.java:98:25:98:33 | unsafer5b | semmle.label | unsafer5b | +| SanitizationTests.java:100:41:100:106 | append(...) : StringBuilder | semmle.label | append(...) : StringBuilder | +| SanitizationTests.java:100:77:100:105 | getParameter(...) : String | semmle.label | getParameter(...) : String | +| SanitizationTests.java:102:37:102:91 | newBuilder(...) : Builder | semmle.label | newBuilder(...) : Builder | +| SanitizationTests.java:102:37:102:99 | build(...) : HttpRequest | semmle.label | build(...) : HttpRequest | +| SanitizationTests.java:102:60:102:90 | new URI(...) | semmle.label | new URI(...) | +| SanitizationTests.java:102:60:102:90 | new URI(...) : URI | semmle.label | new URI(...) : URI | +| SanitizationTests.java:102:68:102:78 | unsafeUri5c : StringBuilder | semmle.label | unsafeUri5c : StringBuilder | +| SanitizationTests.java:102:68:102:89 | toString(...) : String | semmle.label | toString(...) : String | +| SanitizationTests.java:103:25:103:33 | unsafer5c | semmle.label | unsafer5c | +| SanitizationTests.java:105:33:105:104 | format(...) : String | semmle.label | format(...) : String | +| SanitizationTests.java:105:33:105:104 | new ..[] { .. } : Object[] [[]] : String | semmle.label | new ..[] { .. } : Object[] [[]] : String | +| SanitizationTests.java:105:73:105:103 | getParameter(...) : String | semmle.label | getParameter(...) : String | +| SanitizationTests.java:106:36:106:78 | newBuilder(...) : Builder | semmle.label | newBuilder(...) : Builder | +| SanitizationTests.java:106:36:106:86 | build(...) : HttpRequest | semmle.label | build(...) : HttpRequest | +| SanitizationTests.java:106:59:106:77 | new URI(...) | semmle.label | new URI(...) | +| SanitizationTests.java:106:59:106:77 | new URI(...) : URI | semmle.label | new URI(...) : URI | +| SanitizationTests.java:106:67:106:76 | unsafeUri6 : String | semmle.label | unsafeUri6 : String | +| SanitizationTests.java:107:25:107:32 | unsafer6 | semmle.label | unsafer6 | +| SanitizationTests.java:109:33:109:110 | format(...) : String | semmle.label | format(...) : String | +| SanitizationTests.java:109:33:109:110 | new ..[] { .. } : Object[] [[]] : String | semmle.label | new ..[] { .. } : Object[] [[]] : String | +| SanitizationTests.java:109:56:109:86 | getParameter(...) : String | semmle.label | getParameter(...) : String | +| SanitizationTests.java:110:36:110:78 | newBuilder(...) : Builder | semmle.label | newBuilder(...) : Builder | +| SanitizationTests.java:110:36:110:86 | build(...) : HttpRequest | semmle.label | build(...) : HttpRequest | +| SanitizationTests.java:110:59:110:77 | new URI(...) | semmle.label | new URI(...) | +| SanitizationTests.java:110:59:110:77 | new URI(...) : URI | semmle.label | new URI(...) : URI | +| SanitizationTests.java:110:67:110:76 | unsafeUri7 : String | semmle.label | unsafeUri7 : String | +| SanitizationTests.java:111:25:111:32 | unsafer7 | semmle.label | unsafer7 | +| SanitizationTests.java:113:33:113:110 | format(...) : String | semmle.label | format(...) : String | +| SanitizationTests.java:113:33:113:110 | new ..[] { .. } : Object[] [[]] : String | semmle.label | new ..[] { .. } : Object[] [[]] : String | +| SanitizationTests.java:113:55:113:85 | getParameter(...) : String | semmle.label | getParameter(...) : String | +| SanitizationTests.java:114:36:114:78 | newBuilder(...) : Builder | semmle.label | newBuilder(...) : Builder | +| SanitizationTests.java:114:36:114:86 | build(...) : HttpRequest | semmle.label | build(...) : HttpRequest | +| SanitizationTests.java:114:59:114:77 | new URI(...) | semmle.label | new URI(...) | +| SanitizationTests.java:114:59:114:77 | new URI(...) : URI | semmle.label | new URI(...) : URI | +| SanitizationTests.java:114:67:114:76 | unsafeUri8 : String | semmle.label | unsafeUri8 : String | +| SanitizationTests.java:115:25:115:32 | unsafer8 | semmle.label | unsafer8 | +| SanitizationTests.java:117:33:117:63 | getParameter(...) : String | semmle.label | getParameter(...) : String | +| SanitizationTests.java:118:36:118:78 | newBuilder(...) : Builder | semmle.label | newBuilder(...) : Builder | +| SanitizationTests.java:118:36:118:86 | build(...) : HttpRequest | semmle.label | build(...) : HttpRequest | +| SanitizationTests.java:118:59:118:77 | new URI(...) | semmle.label | new URI(...) | +| SanitizationTests.java:118:59:118:77 | new URI(...) : URI | semmle.label | new URI(...) : URI | +| SanitizationTests.java:118:67:118:76 | unsafeUri9 : String | semmle.label | unsafeUri9 : String | +| SanitizationTests.java:119:25:119:32 | unsafer9 | semmle.label | unsafer9 | +| SanitizationTests.java:121:34:121:126 | format(...) : String | semmle.label | format(...) : String | +| SanitizationTests.java:121:34:121:126 | new ..[] { .. } : Object[] [[]] : String | semmle.label | new ..[] { .. } : Object[] [[]] : String | +| SanitizationTests.java:121:94:121:125 | getParameter(...) : String | semmle.label | getParameter(...) : String | +| SanitizationTests.java:122:37:122:80 | newBuilder(...) : Builder | semmle.label | newBuilder(...) : Builder | +| SanitizationTests.java:122:37:122:88 | build(...) : HttpRequest | semmle.label | build(...) : HttpRequest | +| SanitizationTests.java:122:60:122:79 | new URI(...) | semmle.label | new URI(...) | +| SanitizationTests.java:122:60:122:79 | new URI(...) : URI | semmle.label | new URI(...) : URI | +| SanitizationTests.java:122:68:122:78 | unsafeUri10 : String | semmle.label | unsafeUri10 : String | +| SanitizationTests.java:123:25:123:33 | unsafer10 | semmle.label | unsafer10 | | SpringSSRF.java:28:33:28:60 | getParameter(...) : String | semmle.label | getParameter(...) : String | | SpringSSRF.java:32:39:32:59 | ... + ... | semmle.label | ... + ... | | SpringSSRF.java:33:35:33:48 | fooResourceUrl | semmle.label | fooResourceUrl | diff --git a/java/ql/test/query-tests/security/CWE-918/SanitizationTests.java b/java/ql/test/query-tests/security/CWE-918/SanitizationTests.java index f32de324a1d..4da70e8dd75 100644 --- a/java/ql/test/query-tests/security/CWE-918/SanitizationTests.java +++ b/java/ql/test/query-tests/security/CWE-918/SanitizationTests.java @@ -2,6 +2,8 @@ import java.io.IOException; import java.net.URI; import java.net.http.HttpClient; import java.net.http.HttpRequest; +import java.util.regex.Pattern; +import java.util.regex.Matcher; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; @@ -126,11 +128,25 @@ public class SanitizationTests extends HttpServlet { HttpRequest r10 = HttpRequest.newBuilder(new URI(param10)).build(); client.send(r10, null); } - + String param11 = request.getParameter("uri11"); validate(param11); HttpRequest r11 = HttpRequest.newBuilder(new URI(param11)).build(); client.send(r11, null); + + String param12 = request.getParameter("uri12"); + if (Pattern.matches("[a-zA-Z0-9_-]+", param12)) { + HttpRequest r12 = HttpRequest.newBuilder(new URI(param12)).build(); + client.send(r12, null); + } + + Pattern pattern = Pattern.compile("[a-zA-Z0-9_-]+"); + String param13 = request.getParameter("uri13"); + Matcher matcher = pattern.matcher(param13); + if (matcher.matches()) { + HttpRequest r13 = HttpRequest.newBuilder(new URI(param13)).build(); + client.send(r13, null); + } } catch (Exception e) { // TODO: handle exception } diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/ExternalAPIUsedWithUntrustedDataQuery.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/ExternalAPIUsedWithUntrustedDataQuery.qll index 7972c379e87..7a936044756 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/ExternalAPIUsedWithUntrustedDataQuery.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/ExternalAPIUsedWithUntrustedDataQuery.qll @@ -97,7 +97,7 @@ class ExternalApiDataNode extends DataFlow::Node instanceof Sink { } /** A node representing untrusted data being passed to an external API. */ class UntrustedExternalApiDataNode extends ExternalApiDataNode { - UntrustedExternalApiDataNode() { ExternalAPIUsedWithUntrustedDataFlow::flow(_, this) } + UntrustedExternalApiDataNode() { ExternalAPIUsedWithUntrustedDataFlow::flowTo(this) } /** Gets a source of untrusted data which is passed to this external API data node. */ DataFlow::Node getAnUntrustedSource() { ExternalAPIUsedWithUntrustedDataFlow::flow(result, this) } @@ -110,7 +110,7 @@ private newtype TExternalApi = /** An external API sink with `name`. */ MkExternalApiNode(string name) { exists(Sink sink | - ExternalAPIUsedWithUntrustedDataFlow::flow(_, sink) and + ExternalAPIUsedWithUntrustedDataFlow::flowTo(sink) and name = sink.getApiName() ) } diff --git a/javascript/ql/src/experimental/Security/CWE-347/decodeJwtWithoutVerification.ql b/javascript/ql/src/experimental/Security/CWE-347/decodeJwtWithoutVerification.ql index 429744bbbd1..259d27227a3 100644 --- a/javascript/ql/src/experimental/Security/CWE-347/decodeJwtWithoutVerification.ql +++ b/javascript/ql/src/experimental/Security/CWE-347/decodeJwtWithoutVerification.ql @@ -36,6 +36,6 @@ import UnverifiedDecodeFlow::PathGraph from UnverifiedDecodeFlow::PathNode source, UnverifiedDecodeFlow::PathNode sink where UnverifiedDecodeFlow::flowPath(source, sink) and - not VerifiedDecodeFlow::flow(source.getNode(), _) + not VerifiedDecodeFlow::flowFrom(source.getNode()) select source.getNode(), source, sink, "Decoding JWT $@.", sink.getNode(), "without signature verification" diff --git a/javascript/ql/test/library-tests/FlowSummary/test.ql b/javascript/ql/test/library-tests/FlowSummary/test.ql index 0e40dcdadb0..147908706c8 100644 --- a/javascript/ql/test/library-tests/FlowSummary/test.ql +++ b/javascript/ql/test/library-tests/FlowSummary/test.ql @@ -32,5 +32,5 @@ class BasicBarrierGuard extends DataFlow::CallNode { deprecated class ConsistencyConfig extends ConsistencyConfiguration { ConsistencyConfig() { this = "ConsistencyConfig" } - override DataFlow::Node getAnAlert() { Flow::flow(_, result) } + override DataFlow::Node getAnAlert() { Flow::flowTo(result) } } diff --git a/javascript/ql/test/tutorials/Introducing the JavaScript libraries/query17.qll b/javascript/ql/test/tutorials/Introducing the JavaScript libraries/query17.qll index e6dff623e97..e0a5ac34a91 100644 --- a/javascript/ql/test/tutorials/Introducing the JavaScript libraries/query17.qll +++ b/javascript/ql/test/tutorials/Introducing the JavaScript libraries/query17.qll @@ -14,7 +14,7 @@ predicate passwordVarAssign(Variable v, DataFlow::Node nd) { module PasswordFlow = DataFlow::Global; query predicate test_query17(DataFlow::Node sink, string res) { - exists(Variable v | PasswordFlow::flow(_, sink) and passwordVarAssign(v, sink) | + exists(Variable v | PasswordFlow::flowTo(sink) and passwordVarAssign(v, sink) | res = "Password variable " + v.toString() + " is assigned a constant string." ) } diff --git a/python/ql/lib/change-notes/2025-11-26-model-ParseResult.md b/python/ql/lib/change-notes/2025-11-26-model-ParseResult.md new file mode 100644 index 00000000000..9d461643613 --- /dev/null +++ b/python/ql/lib/change-notes/2025-11-26-model-ParseResult.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* Added taint flow model and type model for `urllib.parseurl`. \ No newline at end of file diff --git a/python/ql/lib/semmle/python/frameworks/Stdlib.model.yml b/python/ql/lib/semmle/python/frameworks/Stdlib.model.yml index cdbb451b673..a01bf1b40ba 100644 --- a/python/ql/lib/semmle/python/frameworks/Stdlib.model.yml +++ b/python/ql/lib/semmle/python/frameworks/Stdlib.model.yml @@ -142,6 +142,8 @@ extensions: - ["typing", "Member[cast]", "Argument[1,val:]", "ReturnValue", "value"] # See https://docs.python.org/3/library/urllib.parse.html#urllib.parse.parse_qs - ["urllib", "Member[parse].Member[parse_qs]", "Argument[0,qs:]", "ReturnValue", "taint"] + # See https://docs.python.org/3/library/urllib.parse.html#urllib.parse.urlparse + - ["urllib", "Member[parse].Member[urlparse]", "Argument[0,urlstring:]", "ReturnValue", "taint"] # See https://docs.python.org/3/library/urllib.parse.html#urllib.parse.quote - ["urllib", "Member[parse].Member[quote]", "Argument[0,string:]", "ReturnValue", "taint"] # See https://docs.python.org/3/library/urllib.parse.html#urllib.parse.quote_plus @@ -181,7 +183,9 @@ extensions: - addsTo: pack: codeql/python-all extensible: typeModel - data: [] + data: + # See https://docs.python.org/3/library/urllib.parse.html#urllib.parse.urlparse + - ["urllib.parse.ParseResult~Subclass", 'urllib', 'Member[parse].Member[urlparse]'] - addsTo: pack: codeql/python-all diff --git a/python/ql/lib/semmle/python/frameworks/Stdlib.qll b/python/ql/lib/semmle/python/frameworks/Stdlib.qll index c6b671e8b78..143a575c6e9 100644 --- a/python/ql/lib/semmle/python/frameworks/Stdlib.qll +++ b/python/ql/lib/semmle/python/frameworks/Stdlib.qll @@ -245,6 +245,67 @@ module Stdlib { } } + /** + * Provides models for the `urllib.parse.ParseResult` class + * + * See https://docs.python.org/3.9/library/urllib.parse.html#urllib.parse.ParseResult. + */ + module ParseResult { + /** Gets a reference to the `urllib.parse.ParseResult` class. */ + API::Node classRef() { + result = API::moduleImport("urllib").getMember("parse").getMember("ParseResult") + or + result = ModelOutput::getATypeNode("urllib.parse.ParseResult~Subclass").getASubclass*() + } + + /** + * A source of instances of `urllib.parse.ParseResult`, extend this class to model new instances. + * + * This can include instantiations of the class, return values from function + * calls, or a special parameter that will be set when functions are called by an external + * library. + * + * Use the predicate `ParseResult::instance()` to get references to instances of `urllib.parse.ParseResult`. + */ + abstract class InstanceSource extends DataFlow::LocalSourceNode { } + + /** A direct instantiation of `urllib.parse.ParseResult`. */ + private class ClassInstantiation extends InstanceSource, DataFlow::CallCfgNode { + ClassInstantiation() { this = classRef().getACall() } + } + + /** Gets a reference to an instance of `urllib.parse.ParseResult`. */ + private DataFlow::TypeTrackingNode instance(DataFlow::TypeTracker t) { + t.start() and + result instanceof InstanceSource + or + exists(DataFlow::TypeTracker t2 | result = instance(t2).track(t2, t)) + } + + /** Gets a reference to an instance of `urllib.parse.ParseResult`. */ + DataFlow::Node instance() { instance(DataFlow::TypeTracker::end()).flowsTo(result) } + + /** + * Taint propagation for `urllib.parse.ParseResult`. + */ + private class InstanceTaintSteps extends InstanceTaintStepsHelper { + InstanceTaintSteps() { this = "urllib.parse.ParseResult" } + + override DataFlow::Node getInstance() { result = instance() } + + override string getAttributeName() { + result in [ + "netloc", "path", "params", "query", "fragment", "username", "password", "hostname", + "port" + ] + } + + override string getMethodName() { none() } + + override string getAsyncMethodName() { none() } + } + } + // --------------------------------------------------------------------------- // logging // --------------------------------------------------------------------------- diff --git a/python/ql/lib/semmle/python/security/dataflow/ServerSideRequestForgeryQuery.qll b/python/ql/lib/semmle/python/security/dataflow/ServerSideRequestForgeryQuery.qll index e60afa470ec..304e6376d2c 100644 --- a/python/ql/lib/semmle/python/security/dataflow/ServerSideRequestForgeryQuery.qll +++ b/python/ql/lib/semmle/python/security/dataflow/ServerSideRequestForgeryQuery.qll @@ -50,7 +50,7 @@ module FullServerSideRequestForgeryFlow = TaintTracking::Global; from DataFlow::Node reachable -where RemoteFlowSourceReachFlow::flow(_, reachable) +where RemoteFlowSourceReachFlow::flowTo(reachable) select reachable, prettyNode(reachable) diff --git a/python/ql/test/experimental/query-tests/Security/CWE-409/DecompressionBombs.expected b/python/ql/test/experimental/query-tests/Security/CWE-409/DecompressionBombs.expected index 12d1b8282c7..87b07df086f 100644 --- a/python/ql/test/experimental/query-tests/Security/CWE-409/DecompressionBombs.expected +++ b/python/ql/test/experimental/query-tests/Security/CWE-409/DecompressionBombs.expected @@ -1,23 +1,23 @@ edges | test.py:10:16:10:24 | ControlFlowNode for file_path | test.py:11:21:11:29 | ControlFlowNode for file_path | provenance | | | test.py:11:5:11:35 | ControlFlowNode for Attribute() | test.py:11:5:11:52 | ControlFlowNode for Attribute() | provenance | Config | -| test.py:11:21:11:29 | ControlFlowNode for file_path | test.py:11:5:11:35 | ControlFlowNode for Attribute() | provenance | MaD:85 | +| test.py:11:21:11:29 | ControlFlowNode for file_path | test.py:11:5:11:35 | ControlFlowNode for Attribute() | provenance | MaD:86 | | test.py:11:21:11:29 | ControlFlowNode for file_path | test.py:11:5:11:52 | ControlFlowNode for Attribute() | provenance | Config | | test.py:11:21:11:29 | ControlFlowNode for file_path | test.py:12:21:12:29 | ControlFlowNode for file_path | provenance | | | test.py:12:5:12:35 | ControlFlowNode for Attribute() | test.py:12:5:12:48 | ControlFlowNode for Attribute() | provenance | Config | -| test.py:12:21:12:29 | ControlFlowNode for file_path | test.py:12:5:12:35 | ControlFlowNode for Attribute() | provenance | MaD:85 | +| test.py:12:21:12:29 | ControlFlowNode for file_path | test.py:12:5:12:35 | ControlFlowNode for Attribute() | provenance | MaD:86 | | test.py:12:21:12:29 | ControlFlowNode for file_path | test.py:12:5:12:48 | ControlFlowNode for Attribute() | provenance | Config | | test.py:12:21:12:29 | ControlFlowNode for file_path | test.py:14:26:14:34 | ControlFlowNode for file_path | provenance | | | test.py:14:10:14:35 | ControlFlowNode for Attribute() | test.py:15:14:15:29 | ControlFlowNode for Attribute() | provenance | Config | -| test.py:14:26:14:34 | ControlFlowNode for file_path | test.py:14:10:14:35 | ControlFlowNode for Attribute() | provenance | MaD:85 | +| test.py:14:26:14:34 | ControlFlowNode for file_path | test.py:14:10:14:35 | ControlFlowNode for Attribute() | provenance | MaD:86 | | test.py:14:26:14:34 | ControlFlowNode for file_path | test.py:15:14:15:29 | ControlFlowNode for Attribute() | provenance | Config | | test.py:14:26:14:34 | ControlFlowNode for file_path | test.py:18:26:18:34 | ControlFlowNode for file_path | provenance | | | test.py:18:10:18:35 | ControlFlowNode for Attribute() | test.py:19:14:19:39 | ControlFlowNode for Attribute() | provenance | Config | -| test.py:18:26:18:34 | ControlFlowNode for file_path | test.py:18:10:18:35 | ControlFlowNode for Attribute() | provenance | MaD:85 | +| test.py:18:26:18:34 | ControlFlowNode for file_path | test.py:18:10:18:35 | ControlFlowNode for Attribute() | provenance | MaD:86 | | test.py:18:26:18:34 | ControlFlowNode for file_path | test.py:19:14:19:39 | ControlFlowNode for Attribute() | provenance | Config | | test.py:18:26:18:34 | ControlFlowNode for file_path | test.py:22:21:22:29 | ControlFlowNode for file_path | provenance | | | test.py:22:5:22:30 | ControlFlowNode for Attribute() | test.py:22:5:22:60 | ControlFlowNode for Attribute() | provenance | Config | -| test.py:22:21:22:29 | ControlFlowNode for file_path | test.py:22:5:22:30 | ControlFlowNode for Attribute() | provenance | MaD:85 | +| test.py:22:21:22:29 | ControlFlowNode for file_path | test.py:22:5:22:30 | ControlFlowNode for Attribute() | provenance | MaD:86 | | test.py:22:21:22:29 | ControlFlowNode for file_path | test.py:22:5:22:60 | ControlFlowNode for Attribute() | provenance | Config | | test.py:22:21:22:29 | ControlFlowNode for file_path | test.py:24:18:24:26 | ControlFlowNode for file_path | provenance | | | test.py:24:18:24:26 | ControlFlowNode for file_path | test.py:24:5:24:52 | ControlFlowNode for Attribute() | provenance | Config | diff --git a/python/ql/test/query-tests/Security/CWE-113-HeaderInjection/Tests1/HeaderInjection.expected b/python/ql/test/query-tests/Security/CWE-113-HeaderInjection/Tests1/HeaderInjection.expected index b5f4ff549c4..cea505fe39d 100644 --- a/python/ql/test/query-tests/Security/CWE-113-HeaderInjection/Tests1/HeaderInjection.expected +++ b/python/ql/test/query-tests/Security/CWE-113-HeaderInjection/Tests1/HeaderInjection.expected @@ -11,6 +11,16 @@ edges | flask_tests.py:31:5:31:14 | ControlFlowNode for rfs_header | flask_tests.py:33:11:33:20 | ControlFlowNode for rfs_header | provenance | | | flask_tests.py:31:5:31:14 | ControlFlowNode for rfs_header | flask_tests.py:35:12:35:21 | ControlFlowNode for rfs_header | provenance | | | flask_tests.py:31:18:31:24 | ControlFlowNode for request | flask_tests.py:31:5:31:14 | ControlFlowNode for rfs_header | provenance | AdditionalTaintStep | +| http_test.py:5:16:5:19 | ControlFlowNode for self | http_test.py:6:45:6:53 | ControlFlowNode for Attribute | provenance | AdditionalTaintStep | +| http_test.py:6:9:6:19 | ControlFlowNode for parsed_path | http_test.py:7:40:7:56 | ControlFlowNode for Attribute | provenance | AdditionalTaintStep | +| http_test.py:6:23:6:54 | ControlFlowNode for Attribute() | http_test.py:6:9:6:19 | ControlFlowNode for parsed_path | provenance | | +| http_test.py:6:45:6:53 | ControlFlowNode for Attribute | http_test.py:6:23:6:54 | ControlFlowNode for Attribute() | provenance | MaD:77 | +| http_test.py:7:9:7:14 | ControlFlowNode for params | http_test.py:8:23:8:28 | ControlFlowNode for params | provenance | | +| http_test.py:7:18:7:57 | ControlFlowNode for Attribute() | http_test.py:7:9:7:14 | ControlFlowNode for params | provenance | | +| http_test.py:7:40:7:56 | ControlFlowNode for Attribute | http_test.py:7:18:7:57 | ControlFlowNode for Attribute() | provenance | MaD:76 | +| http_test.py:8:9:8:19 | ControlFlowNode for input_value | http_test.py:12:40:12:50 | ControlFlowNode for input_value | provenance | | +| http_test.py:8:23:8:28 | ControlFlowNode for params | http_test.py:8:23:8:47 | ControlFlowNode for Attribute() | provenance | dict.get | +| http_test.py:8:23:8:47 | ControlFlowNode for Attribute() | http_test.py:8:9:8:19 | ControlFlowNode for input_value | provenance | | | wsgiref_tests.py:4:14:4:20 | ControlFlowNode for environ | wsgiref_tests.py:6:5:6:10 | ControlFlowNode for h_name | provenance | | | wsgiref_tests.py:4:14:4:20 | ControlFlowNode for environ | wsgiref_tests.py:7:5:7:9 | ControlFlowNode for h_val | provenance | | | wsgiref_tests.py:6:5:6:10 | ControlFlowNode for h_name | wsgiref_tests.py:8:17:8:22 | ControlFlowNode for h_name | provenance | | @@ -28,6 +38,17 @@ nodes | flask_tests.py:31:18:31:24 | ControlFlowNode for request | semmle.label | ControlFlowNode for request | | flask_tests.py:33:11:33:20 | ControlFlowNode for rfs_header | semmle.label | ControlFlowNode for rfs_header | | flask_tests.py:35:12:35:21 | ControlFlowNode for rfs_header | semmle.label | ControlFlowNode for rfs_header | +| http_test.py:5:16:5:19 | ControlFlowNode for self | semmle.label | ControlFlowNode for self | +| http_test.py:6:9:6:19 | ControlFlowNode for parsed_path | semmle.label | ControlFlowNode for parsed_path | +| http_test.py:6:23:6:54 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | +| http_test.py:6:45:6:53 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | +| http_test.py:7:9:7:14 | ControlFlowNode for params | semmle.label | ControlFlowNode for params | +| http_test.py:7:18:7:57 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | +| http_test.py:7:40:7:56 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute | +| http_test.py:8:9:8:19 | ControlFlowNode for input_value | semmle.label | ControlFlowNode for input_value | +| http_test.py:8:23:8:28 | ControlFlowNode for params | semmle.label | ControlFlowNode for params | +| http_test.py:8:23:8:47 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | +| http_test.py:12:40:12:50 | ControlFlowNode for input_value | semmle.label | ControlFlowNode for input_value | | wsgiref_tests.py:4:14:4:20 | ControlFlowNode for environ | semmle.label | ControlFlowNode for environ | | wsgiref_tests.py:6:5:6:10 | ControlFlowNode for h_name | semmle.label | ControlFlowNode for h_name | | wsgiref_tests.py:7:5:7:9 | ControlFlowNode for h_val | semmle.label | ControlFlowNode for h_val | @@ -39,5 +60,6 @@ subpaths | flask_tests.py:20:36:20:61 | ControlFlowNode for Subscript | flask_tests.py:1:29:1:35 | ControlFlowNode for ImportMember | flask_tests.py:20:36:20:61 | ControlFlowNode for Subscript | This HTTP header is constructed from a $@. | flask_tests.py:1:29:1:35 | ControlFlowNode for ImportMember | user-provided value | | flask_tests.py:33:11:33:20 | ControlFlowNode for rfs_header | flask_tests.py:1:29:1:35 | ControlFlowNode for ImportMember | flask_tests.py:33:11:33:20 | ControlFlowNode for rfs_header | This HTTP header is constructed from a $@. | flask_tests.py:1:29:1:35 | ControlFlowNode for ImportMember | user-provided value | | flask_tests.py:35:12:35:21 | ControlFlowNode for rfs_header | flask_tests.py:1:29:1:35 | ControlFlowNode for ImportMember | flask_tests.py:35:12:35:21 | ControlFlowNode for rfs_header | This HTTP header is constructed from a $@. | flask_tests.py:1:29:1:35 | ControlFlowNode for ImportMember | user-provided value | +| http_test.py:12:40:12:50 | ControlFlowNode for input_value | http_test.py:5:16:5:19 | ControlFlowNode for self | http_test.py:12:40:12:50 | ControlFlowNode for input_value | This HTTP header is constructed from a $@. | http_test.py:5:16:5:19 | ControlFlowNode for self | user-provided value | | wsgiref_tests.py:8:17:8:22 | ControlFlowNode for h_name | wsgiref_tests.py:4:14:4:20 | ControlFlowNode for environ | wsgiref_tests.py:8:17:8:22 | ControlFlowNode for h_name | This HTTP header is constructed from a $@. | wsgiref_tests.py:4:14:4:20 | ControlFlowNode for environ | user-provided value | | wsgiref_tests.py:8:42:8:46 | ControlFlowNode for h_val | wsgiref_tests.py:4:14:4:20 | ControlFlowNode for environ | wsgiref_tests.py:8:42:8:46 | ControlFlowNode for h_val | This HTTP header is constructed from a $@. | wsgiref_tests.py:4:14:4:20 | ControlFlowNode for environ | user-provided value | diff --git a/python/ql/test/query-tests/Security/CWE-113-HeaderInjection/Tests1/http_test.py b/python/ql/test/query-tests/Security/CWE-113-HeaderInjection/Tests1/http_test.py new file mode 100644 index 00000000000..cf46219fc59 --- /dev/null +++ b/python/ql/test/query-tests/Security/CWE-113-HeaderInjection/Tests1/http_test.py @@ -0,0 +1,22 @@ +from http.server import HTTPServer, BaseHTTPRequestHandler +import urllib.parse + +class VulnerableHandler(BaseHTTPRequestHandler): + def do_GET(self): + parsed_path = urllib.parse.urlparse(self.path) + params = urllib.parse.parse_qs(parsed_path.query) + input_value = params.get("input", [""])[0] + # Unsafe: Directly including user input in headers + self.send_response(200) + try: + self.send_header("X-Info", input_value) # BAD + except Exception as e: + print(f"[!] Header injection failed: {e}") + self.end_headers() + self.wfile.write(b"Hello world!") + + +# if __name__ == "__main__": +# print("Serving vulnerable app on http://127.0.0.1:8080") +# httpd = HTTPServer(("127.0.0.1", 8080), VulnerableHandler) +# httpd.serve_forever() diff --git a/ruby/ql/src/queries/meta/TaintedNodes.ql b/ruby/ql/src/queries/meta/TaintedNodes.ql index 2ee6e83e0de..1594c59d3b0 100644 --- a/ruby/ql/src/queries/meta/TaintedNodes.ql +++ b/ruby/ql/src/queries/meta/TaintedNodes.ql @@ -28,5 +28,5 @@ private module BasicTaintConfig implements DataFlow::ConfigSig { private module BasicTaintFlow = TaintTracking::Global; from DataFlow::Node node -where BasicTaintFlow::flow(_, node) +where BasicTaintFlow::flowTo(node) select node, "Tainted node" diff --git a/rust/downgrades/e54d01f67a416b3d6eb7b970f27295097f2cac7f/old.dbscheme b/rust/downgrades/e54d01f67a416b3d6eb7b970f27295097f2cac7f/old.dbscheme new file mode 100644 index 00000000000..e54d01f67a4 --- /dev/null +++ b/rust/downgrades/e54d01f67a416b3d6eb7b970f27295097f2cac7f/old.dbscheme @@ -0,0 +1,3624 @@ +// generated by codegen, do not edit + +// from ../shared/tree-sitter-extractor/src/generator/prefix.dbscheme +/*- Files and folders -*/ + +/** + * The location of an element. + * The location spans column `startcolumn` of line `startline` to + * column `endcolumn` of line `endline` in file `file`. + * For more information, see + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). + */ +locations_default( + unique int id: @location_default, + int file: @file ref, + int beginLine: int ref, + int beginColumn: int ref, + int endLine: int ref, + int endColumn: int ref +); + +files( + unique int id: @file, + string name: string ref +); + +folders( + unique int id: @folder, + string name: string ref +); + +@container = @file | @folder + +containerparent( + int parent: @container ref, + unique int child: @container ref +); + +/*- Empty location -*/ + +empty_location( + int location: @location_default ref +); + +/*- Source location prefix -*/ + +/** + * The source location of the snapshot. + */ +sourceLocationPrefix(string prefix : string ref); + +/*- Diagnostic messages -*/ + +diagnostics( + unique int id: @diagnostic, + int severity: int ref, + string error_tag: string ref, + string error_message: string ref, + string full_error_message: string ref, + int location: @location_default ref +); + +/*- Diagnostic messages: severity -*/ + +case @diagnostic.severity of + 10 = @diagnostic_debug +| 20 = @diagnostic_info +| 30 = @diagnostic_warning +| 40 = @diagnostic_error +; + +/*- YAML -*/ + +#keyset[parent, idx] +yaml (unique int id: @yaml_node, + int kind: int ref, + int parent: @yaml_node_parent ref, + int idx: int ref, + string tag: string ref, + string tostring: string ref); + +case @yaml_node.kind of + 0 = @yaml_scalar_node +| 1 = @yaml_mapping_node +| 2 = @yaml_sequence_node +| 3 = @yaml_alias_node +; + +@yaml_collection_node = @yaml_mapping_node | @yaml_sequence_node; + +@yaml_node_parent = @yaml_collection_node | @file; + +yaml_anchors (unique int node: @yaml_node ref, + string anchor: string ref); + +yaml_aliases (unique int alias: @yaml_alias_node ref, + string target: string ref); + +yaml_scalars (unique int scalar: @yaml_scalar_node ref, + int style: int ref, + string value: string ref); + +yaml_errors (unique int id: @yaml_error, + string message: string ref); + +yaml_locations(unique int locatable: @yaml_locatable ref, + int location: @location_default ref); + +@yaml_locatable = @yaml_node | @yaml_error; + +/*- Database metadata -*/ +databaseMetadata( + string metadataKey: string ref, + string value: string ref +); + +overlayChangedFiles( + string path: string ref +); + + +// from prefix.dbscheme +#keyset[id] +locatable_locations( + int id: @locatable ref, + int location: @location_default ref +); + + +// from schema + +@element = + @extractor_step +| @locatable +| @named_crate +| @unextracted +; + +extractor_steps( + unique int id: @extractor_step, + string action: string ref, + int duration_ms: int ref +); + +#keyset[id] +extractor_step_files( + int id: @extractor_step ref, + int file: @file ref +); + +@locatable = + @ast_node +| @crate +; + +named_crates( + unique int id: @named_crate, + string name: string ref, + int crate: @crate ref +); + +@unextracted = + @missing +| @unimplemented +; + +@ast_node = + @abi +| @addressable +| @arg_list +| @asm_dir_spec +| @asm_operand +| @asm_operand_expr +| @asm_option +| @asm_piece +| @asm_reg_spec +| @assoc_item_list +| @attr +| @callable +| @expr +| @extern_item_list +| @field_list +| @for_binder +| @format_args_arg +| @generic_arg +| @generic_arg_list +| @generic_param +| @generic_param_list +| @item_list +| @label +| @let_else +| @macro_items +| @match_arm +| @match_arm_list +| @match_guard +| @meta +| @name +| @param_base +| @param_list +| @parenthesized_arg_list +| @pat +| @path +| @path_ast_node +| @path_segment +| @rename +| @ret_type_repr +| @return_type_syntax +| @source_file +| @stmt +| @stmt_list +| @struct_expr_field +| @struct_expr_field_list +| @struct_field +| @struct_pat_field +| @struct_pat_field_list +| @token +| @token_tree +| @tuple_field +| @type_bound +| @type_bound_list +| @type_repr +| @use_bound_generic_arg +| @use_bound_generic_args +| @use_tree +| @use_tree_list +| @variant_list +| @visibility +| @where_clause +| @where_pred +; + +crates( + unique int id: @crate +); + +#keyset[id] +crate_names( + int id: @crate ref, + string name: string ref +); + +#keyset[id] +crate_versions( + int id: @crate ref, + string version: string ref +); + +#keyset[id, index] +crate_cfg_options( + int id: @crate ref, + int index: int ref, + string cfg_option: string ref +); + +#keyset[id, index] +crate_named_dependencies( + int id: @crate ref, + int index: int ref, + int named_dependency: @named_crate ref +); + +missings( + unique int id: @missing +); + +unimplementeds( + unique int id: @unimplemented +); + +abis( + unique int id: @abi +); + +#keyset[id] +abi_abi_strings( + int id: @abi ref, + string abi_string: string ref +); + +@addressable = + @item +| @variant +; + +arg_lists( + unique int id: @arg_list +); + +#keyset[id, index] +arg_list_args( + int id: @arg_list ref, + int index: int ref, + int arg: @expr ref +); + +asm_dir_specs( + unique int id: @asm_dir_spec +); + +@asm_operand = + @asm_const +| @asm_label +| @asm_reg_operand +| @asm_sym +; + +asm_operand_exprs( + unique int id: @asm_operand_expr +); + +#keyset[id] +asm_operand_expr_in_exprs( + int id: @asm_operand_expr ref, + int in_expr: @expr ref +); + +#keyset[id] +asm_operand_expr_out_exprs( + int id: @asm_operand_expr ref, + int out_expr: @expr ref +); + +asm_options( + unique int id: @asm_option +); + +#keyset[id] +asm_option_is_raw( + int id: @asm_option ref +); + +@asm_piece = + @asm_clobber_abi +| @asm_operand_named +| @asm_options_list +; + +asm_reg_specs( + unique int id: @asm_reg_spec +); + +#keyset[id] +asm_reg_spec_identifiers( + int id: @asm_reg_spec ref, + int identifier: @name_ref ref +); + +assoc_item_lists( + unique int id: @assoc_item_list +); + +#keyset[id, index] +assoc_item_list_assoc_items( + int id: @assoc_item_list ref, + int index: int ref, + int assoc_item: @assoc_item ref +); + +#keyset[id, index] +assoc_item_list_attrs( + int id: @assoc_item_list ref, + int index: int ref, + int attr: @attr ref +); + +attrs( + unique int id: @attr +); + +#keyset[id] +attr_meta( + int id: @attr ref, + int meta: @meta ref +); + +@callable = + @closure_expr +| @function +; + +#keyset[id] +callable_param_lists( + int id: @callable ref, + int param_list: @param_list ref +); + +#keyset[id, index] +callable_attrs( + int id: @callable ref, + int index: int ref, + int attr: @attr ref +); + +@expr = + @array_expr_internal +| @asm_expr +| @await_expr +| @become_expr +| @binary_expr +| @break_expr +| @call_expr +| @cast_expr +| @closure_expr +| @continue_expr +| @field_expr +| @format_args_expr +| @if_expr +| @index_expr +| @labelable_expr +| @let_expr +| @literal_expr +| @macro_block_expr +| @macro_expr +| @match_expr +| @method_call_expr +| @offset_of_expr +| @paren_expr +| @path_expr_base +| @prefix_expr +| @range_expr +| @ref_expr +| @return_expr +| @struct_expr +| @try_expr +| @tuple_expr +| @underscore_expr +| @yeet_expr +| @yield_expr +; + +extern_item_lists( + unique int id: @extern_item_list +); + +#keyset[id, index] +extern_item_list_attrs( + int id: @extern_item_list ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id, index] +extern_item_list_extern_items( + int id: @extern_item_list ref, + int index: int ref, + int extern_item: @extern_item ref +); + +@field_list = + @struct_field_list +| @tuple_field_list +; + +for_binders( + unique int id: @for_binder +); + +#keyset[id] +for_binder_generic_param_lists( + int id: @for_binder ref, + int generic_param_list: @generic_param_list ref +); + +format_args_args( + unique int id: @format_args_arg +); + +#keyset[id] +format_args_arg_exprs( + int id: @format_args_arg ref, + int expr: @expr ref +); + +#keyset[id] +format_args_arg_names( + int id: @format_args_arg ref, + int name: @name ref +); + +@generic_arg = + @assoc_type_arg +| @const_arg +| @lifetime_arg +| @type_arg +; + +generic_arg_lists( + unique int id: @generic_arg_list +); + +#keyset[id, index] +generic_arg_list_generic_args( + int id: @generic_arg_list ref, + int index: int ref, + int generic_arg: @generic_arg ref +); + +@generic_param = + @const_param +| @lifetime_param +| @type_param +; + +generic_param_lists( + unique int id: @generic_param_list +); + +#keyset[id, index] +generic_param_list_generic_params( + int id: @generic_param_list ref, + int index: int ref, + int generic_param: @generic_param ref +); + +item_lists( + unique int id: @item_list +); + +#keyset[id, index] +item_list_attrs( + int id: @item_list ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id, index] +item_list_items( + int id: @item_list ref, + int index: int ref, + int item: @item ref +); + +labels( + unique int id: @label +); + +#keyset[id] +label_lifetimes( + int id: @label ref, + int lifetime: @lifetime ref +); + +let_elses( + unique int id: @let_else +); + +#keyset[id] +let_else_block_exprs( + int id: @let_else ref, + int block_expr: @block_expr ref +); + +macro_items( + unique int id: @macro_items +); + +#keyset[id, index] +macro_items_items( + int id: @macro_items ref, + int index: int ref, + int item: @item ref +); + +match_arms( + unique int id: @match_arm +); + +#keyset[id, index] +match_arm_attrs( + int id: @match_arm ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +match_arm_exprs( + int id: @match_arm ref, + int expr: @expr ref +); + +#keyset[id] +match_arm_guards( + int id: @match_arm ref, + int guard: @match_guard ref +); + +#keyset[id] +match_arm_pats( + int id: @match_arm ref, + int pat: @pat ref +); + +match_arm_lists( + unique int id: @match_arm_list +); + +#keyset[id, index] +match_arm_list_arms( + int id: @match_arm_list ref, + int index: int ref, + int arm: @match_arm ref +); + +#keyset[id, index] +match_arm_list_attrs( + int id: @match_arm_list ref, + int index: int ref, + int attr: @attr ref +); + +match_guards( + unique int id: @match_guard +); + +#keyset[id] +match_guard_conditions( + int id: @match_guard ref, + int condition: @expr ref +); + +meta( + unique int id: @meta +); + +#keyset[id] +meta_exprs( + int id: @meta ref, + int expr: @expr ref +); + +#keyset[id] +meta_is_unsafe( + int id: @meta ref +); + +#keyset[id] +meta_paths( + int id: @meta ref, + int path: @path ref +); + +#keyset[id] +meta_token_trees( + int id: @meta ref, + int token_tree: @token_tree ref +); + +names( + unique int id: @name +); + +#keyset[id] +name_texts( + int id: @name ref, + string text: string ref +); + +@param_base = + @param +| @self_param +; + +#keyset[id, index] +param_base_attrs( + int id: @param_base ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +param_base_type_reprs( + int id: @param_base ref, + int type_repr: @type_repr ref +); + +param_lists( + unique int id: @param_list +); + +#keyset[id, index] +param_list_params( + int id: @param_list ref, + int index: int ref, + int param: @param ref +); + +#keyset[id] +param_list_self_params( + int id: @param_list ref, + int self_param: @self_param ref +); + +parenthesized_arg_lists( + unique int id: @parenthesized_arg_list +); + +#keyset[id, index] +parenthesized_arg_list_type_args( + int id: @parenthesized_arg_list ref, + int index: int ref, + int type_arg: @type_arg ref +); + +@pat = + @box_pat +| @const_block_pat +| @ident_pat +| @literal_pat +| @macro_pat +| @or_pat +| @paren_pat +| @path_pat +| @range_pat +| @ref_pat +| @rest_pat +| @slice_pat +| @struct_pat +| @tuple_pat +| @tuple_struct_pat +| @wildcard_pat +; + +paths( + unique int id: @path +); + +#keyset[id] +path_qualifiers( + int id: @path ref, + int qualifier: @path ref +); + +#keyset[id] +path_segments_( + int id: @path ref, + int segment: @path_segment ref +); + +@path_ast_node = + @path_expr +| @path_pat +| @struct_expr +| @struct_pat +| @tuple_struct_pat +; + +#keyset[id] +path_ast_node_paths( + int id: @path_ast_node ref, + int path: @path ref +); + +path_segments( + unique int id: @path_segment +); + +#keyset[id] +path_segment_generic_arg_lists( + int id: @path_segment ref, + int generic_arg_list: @generic_arg_list ref +); + +#keyset[id] +path_segment_identifiers( + int id: @path_segment ref, + int identifier: @name_ref ref +); + +#keyset[id] +path_segment_parenthesized_arg_lists( + int id: @path_segment ref, + int parenthesized_arg_list: @parenthesized_arg_list ref +); + +#keyset[id] +path_segment_ret_types( + int id: @path_segment ref, + int ret_type: @ret_type_repr ref +); + +#keyset[id] +path_segment_return_type_syntaxes( + int id: @path_segment ref, + int return_type_syntax: @return_type_syntax ref +); + +#keyset[id] +path_segment_type_reprs( + int id: @path_segment ref, + int type_repr: @type_repr ref +); + +#keyset[id] +path_segment_trait_type_reprs( + int id: @path_segment ref, + int trait_type_repr: @path_type_repr ref +); + +renames( + unique int id: @rename +); + +#keyset[id] +rename_names( + int id: @rename ref, + int name: @name ref +); + +ret_type_reprs( + unique int id: @ret_type_repr +); + +#keyset[id] +ret_type_repr_type_reprs( + int id: @ret_type_repr ref, + int type_repr: @type_repr ref +); + +return_type_syntaxes( + unique int id: @return_type_syntax +); + +source_files( + unique int id: @source_file +); + +#keyset[id, index] +source_file_attrs( + int id: @source_file ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id, index] +source_file_items( + int id: @source_file ref, + int index: int ref, + int item: @item ref +); + +@stmt = + @expr_stmt +| @item +| @let_stmt +; + +stmt_lists( + unique int id: @stmt_list +); + +#keyset[id, index] +stmt_list_attrs( + int id: @stmt_list ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id, index] +stmt_list_statements( + int id: @stmt_list ref, + int index: int ref, + int statement: @stmt ref +); + +#keyset[id] +stmt_list_tail_exprs( + int id: @stmt_list ref, + int tail_expr: @expr ref +); + +struct_expr_fields( + unique int id: @struct_expr_field +); + +#keyset[id, index] +struct_expr_field_attrs( + int id: @struct_expr_field ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +struct_expr_field_exprs( + int id: @struct_expr_field ref, + int expr: @expr ref +); + +#keyset[id] +struct_expr_field_identifiers( + int id: @struct_expr_field ref, + int identifier: @name_ref ref +); + +struct_expr_field_lists( + unique int id: @struct_expr_field_list +); + +#keyset[id, index] +struct_expr_field_list_attrs( + int id: @struct_expr_field_list ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id, index] +struct_expr_field_list_fields( + int id: @struct_expr_field_list ref, + int index: int ref, + int field: @struct_expr_field ref +); + +#keyset[id] +struct_expr_field_list_spreads( + int id: @struct_expr_field_list ref, + int spread: @expr ref +); + +struct_fields( + unique int id: @struct_field +); + +#keyset[id, index] +struct_field_attrs( + int id: @struct_field ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +struct_field_defaults( + int id: @struct_field ref, + int default: @expr ref +); + +#keyset[id] +struct_field_is_unsafe( + int id: @struct_field ref +); + +#keyset[id] +struct_field_names( + int id: @struct_field ref, + int name: @name ref +); + +#keyset[id] +struct_field_type_reprs( + int id: @struct_field ref, + int type_repr: @type_repr ref +); + +#keyset[id] +struct_field_visibilities( + int id: @struct_field ref, + int visibility: @visibility ref +); + +struct_pat_fields( + unique int id: @struct_pat_field +); + +#keyset[id, index] +struct_pat_field_attrs( + int id: @struct_pat_field ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +struct_pat_field_identifiers( + int id: @struct_pat_field ref, + int identifier: @name_ref ref +); + +#keyset[id] +struct_pat_field_pats( + int id: @struct_pat_field ref, + int pat: @pat ref +); + +struct_pat_field_lists( + unique int id: @struct_pat_field_list +); + +#keyset[id, index] +struct_pat_field_list_fields( + int id: @struct_pat_field_list ref, + int index: int ref, + int field: @struct_pat_field ref +); + +#keyset[id] +struct_pat_field_list_rest_pats( + int id: @struct_pat_field_list ref, + int rest_pat: @rest_pat ref +); + +@token = + @comment +; + +token_trees( + unique int id: @token_tree +); + +tuple_fields( + unique int id: @tuple_field +); + +#keyset[id, index] +tuple_field_attrs( + int id: @tuple_field ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +tuple_field_type_reprs( + int id: @tuple_field ref, + int type_repr: @type_repr ref +); + +#keyset[id] +tuple_field_visibilities( + int id: @tuple_field ref, + int visibility: @visibility ref +); + +type_bounds( + unique int id: @type_bound +); + +#keyset[id] +type_bound_for_binders( + int id: @type_bound ref, + int for_binder: @for_binder ref +); + +#keyset[id] +type_bound_is_async( + int id: @type_bound ref +); + +#keyset[id] +type_bound_is_const( + int id: @type_bound ref +); + +#keyset[id] +type_bound_lifetimes( + int id: @type_bound ref, + int lifetime: @lifetime ref +); + +#keyset[id] +type_bound_type_reprs( + int id: @type_bound ref, + int type_repr: @type_repr ref +); + +#keyset[id] +type_bound_use_bound_generic_args( + int id: @type_bound ref, + int use_bound_generic_args: @use_bound_generic_args ref +); + +type_bound_lists( + unique int id: @type_bound_list +); + +#keyset[id, index] +type_bound_list_bounds( + int id: @type_bound_list ref, + int index: int ref, + int bound: @type_bound ref +); + +@type_repr = + @array_type_repr +| @dyn_trait_type_repr +| @fn_ptr_type_repr +| @for_type_repr +| @impl_trait_type_repr +| @infer_type_repr +| @macro_type_repr +| @never_type_repr +| @paren_type_repr +| @path_type_repr +| @ptr_type_repr +| @ref_type_repr +| @slice_type_repr +| @tuple_type_repr +; + +@use_bound_generic_arg = + @lifetime +| @name_ref +; + +use_bound_generic_args( + unique int id: @use_bound_generic_args +); + +#keyset[id, index] +use_bound_generic_args_use_bound_generic_args( + int id: @use_bound_generic_args ref, + int index: int ref, + int use_bound_generic_arg: @use_bound_generic_arg ref +); + +use_trees( + unique int id: @use_tree +); + +#keyset[id] +use_tree_is_glob( + int id: @use_tree ref +); + +#keyset[id] +use_tree_paths( + int id: @use_tree ref, + int path: @path ref +); + +#keyset[id] +use_tree_renames( + int id: @use_tree ref, + int rename: @rename ref +); + +#keyset[id] +use_tree_use_tree_lists( + int id: @use_tree ref, + int use_tree_list: @use_tree_list ref +); + +use_tree_lists( + unique int id: @use_tree_list +); + +#keyset[id, index] +use_tree_list_use_trees( + int id: @use_tree_list ref, + int index: int ref, + int use_tree: @use_tree ref +); + +variant_lists( + unique int id: @variant_list +); + +#keyset[id, index] +variant_list_variants( + int id: @variant_list ref, + int index: int ref, + int variant: @variant ref +); + +visibilities( + unique int id: @visibility +); + +#keyset[id] +visibility_paths( + int id: @visibility ref, + int path: @path ref +); + +where_clauses( + unique int id: @where_clause +); + +#keyset[id, index] +where_clause_predicates( + int id: @where_clause ref, + int index: int ref, + int predicate: @where_pred ref +); + +where_preds( + unique int id: @where_pred +); + +#keyset[id] +where_pred_for_binders( + int id: @where_pred ref, + int for_binder: @for_binder ref +); + +#keyset[id] +where_pred_lifetimes( + int id: @where_pred ref, + int lifetime: @lifetime ref +); + +#keyset[id] +where_pred_type_reprs( + int id: @where_pred ref, + int type_repr: @type_repr ref +); + +#keyset[id] +where_pred_type_bound_lists( + int id: @where_pred ref, + int type_bound_list: @type_bound_list ref +); + +array_expr_internals( + unique int id: @array_expr_internal +); + +#keyset[id, index] +array_expr_internal_attrs( + int id: @array_expr_internal ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id, index] +array_expr_internal_exprs( + int id: @array_expr_internal ref, + int index: int ref, + int expr: @expr ref +); + +#keyset[id] +array_expr_internal_is_semicolon( + int id: @array_expr_internal ref +); + +array_type_reprs( + unique int id: @array_type_repr +); + +#keyset[id] +array_type_repr_const_args( + int id: @array_type_repr ref, + int const_arg: @const_arg ref +); + +#keyset[id] +array_type_repr_element_type_reprs( + int id: @array_type_repr ref, + int element_type_repr: @type_repr ref +); + +asm_clobber_abis( + unique int id: @asm_clobber_abi +); + +asm_consts( + unique int id: @asm_const +); + +#keyset[id] +asm_const_exprs( + int id: @asm_const ref, + int expr: @expr ref +); + +#keyset[id] +asm_const_is_const( + int id: @asm_const ref +); + +asm_labels( + unique int id: @asm_label +); + +#keyset[id] +asm_label_block_exprs( + int id: @asm_label ref, + int block_expr: @block_expr ref +); + +asm_operand_nameds( + unique int id: @asm_operand_named +); + +#keyset[id] +asm_operand_named_asm_operands( + int id: @asm_operand_named ref, + int asm_operand: @asm_operand ref +); + +#keyset[id] +asm_operand_named_names( + int id: @asm_operand_named ref, + int name: @name ref +); + +asm_options_lists( + unique int id: @asm_options_list +); + +#keyset[id, index] +asm_options_list_asm_options( + int id: @asm_options_list ref, + int index: int ref, + int asm_option: @asm_option ref +); + +asm_reg_operands( + unique int id: @asm_reg_operand +); + +#keyset[id] +asm_reg_operand_asm_dir_specs( + int id: @asm_reg_operand ref, + int asm_dir_spec: @asm_dir_spec ref +); + +#keyset[id] +asm_reg_operand_asm_operand_exprs( + int id: @asm_reg_operand ref, + int asm_operand_expr: @asm_operand_expr ref +); + +#keyset[id] +asm_reg_operand_asm_reg_specs( + int id: @asm_reg_operand ref, + int asm_reg_spec: @asm_reg_spec ref +); + +asm_syms( + unique int id: @asm_sym +); + +#keyset[id] +asm_sym_paths( + int id: @asm_sym ref, + int path: @path ref +); + +assoc_type_args( + unique int id: @assoc_type_arg +); + +#keyset[id] +assoc_type_arg_const_args( + int id: @assoc_type_arg ref, + int const_arg: @const_arg ref +); + +#keyset[id] +assoc_type_arg_generic_arg_lists( + int id: @assoc_type_arg ref, + int generic_arg_list: @generic_arg_list ref +); + +#keyset[id] +assoc_type_arg_identifiers( + int id: @assoc_type_arg ref, + int identifier: @name_ref ref +); + +#keyset[id] +assoc_type_arg_param_lists( + int id: @assoc_type_arg ref, + int param_list: @param_list ref +); + +#keyset[id] +assoc_type_arg_ret_types( + int id: @assoc_type_arg ref, + int ret_type: @ret_type_repr ref +); + +#keyset[id] +assoc_type_arg_return_type_syntaxes( + int id: @assoc_type_arg ref, + int return_type_syntax: @return_type_syntax ref +); + +#keyset[id] +assoc_type_arg_type_reprs( + int id: @assoc_type_arg ref, + int type_repr: @type_repr ref +); + +#keyset[id] +assoc_type_arg_type_bound_lists( + int id: @assoc_type_arg ref, + int type_bound_list: @type_bound_list ref +); + +await_exprs( + unique int id: @await_expr +); + +#keyset[id, index] +await_expr_attrs( + int id: @await_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +await_expr_exprs( + int id: @await_expr ref, + int expr: @expr ref +); + +become_exprs( + unique int id: @become_expr +); + +#keyset[id, index] +become_expr_attrs( + int id: @become_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +become_expr_exprs( + int id: @become_expr ref, + int expr: @expr ref +); + +binary_exprs( + unique int id: @binary_expr +); + +#keyset[id, index] +binary_expr_attrs( + int id: @binary_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +binary_expr_lhs( + int id: @binary_expr ref, + int lhs: @expr ref +); + +#keyset[id] +binary_expr_operator_names( + int id: @binary_expr ref, + string operator_name: string ref +); + +#keyset[id] +binary_expr_rhs( + int id: @binary_expr ref, + int rhs: @expr ref +); + +box_pats( + unique int id: @box_pat +); + +#keyset[id] +box_pat_pats( + int id: @box_pat ref, + int pat: @pat ref +); + +break_exprs( + unique int id: @break_expr +); + +#keyset[id, index] +break_expr_attrs( + int id: @break_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +break_expr_exprs( + int id: @break_expr ref, + int expr: @expr ref +); + +#keyset[id] +break_expr_lifetimes( + int id: @break_expr ref, + int lifetime: @lifetime ref +); + +call_exprs( + unique int id: @call_expr +); + +#keyset[id] +call_expr_arg_lists( + int id: @call_expr ref, + int arg_list: @arg_list ref +); + +#keyset[id, index] +call_expr_attrs( + int id: @call_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +call_expr_functions( + int id: @call_expr ref, + int function: @expr ref +); + +cast_exprs( + unique int id: @cast_expr +); + +#keyset[id, index] +cast_expr_attrs( + int id: @cast_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +cast_expr_exprs( + int id: @cast_expr ref, + int expr: @expr ref +); + +#keyset[id] +cast_expr_type_reprs( + int id: @cast_expr ref, + int type_repr: @type_repr ref +); + +closure_exprs( + unique int id: @closure_expr +); + +#keyset[id] +closure_expr_closure_bodies( + int id: @closure_expr ref, + int closure_body: @expr ref +); + +#keyset[id] +closure_expr_for_binders( + int id: @closure_expr ref, + int for_binder: @for_binder ref +); + +#keyset[id] +closure_expr_is_async( + int id: @closure_expr ref +); + +#keyset[id] +closure_expr_is_const( + int id: @closure_expr ref +); + +#keyset[id] +closure_expr_is_gen( + int id: @closure_expr ref +); + +#keyset[id] +closure_expr_is_move( + int id: @closure_expr ref +); + +#keyset[id] +closure_expr_is_static( + int id: @closure_expr ref +); + +#keyset[id] +closure_expr_ret_types( + int id: @closure_expr ref, + int ret_type: @ret_type_repr ref +); + +comments( + unique int id: @comment, + int parent: @ast_node ref, + string text: string ref +); + +const_args( + unique int id: @const_arg +); + +#keyset[id] +const_arg_exprs( + int id: @const_arg ref, + int expr: @expr ref +); + +const_block_pats( + unique int id: @const_block_pat +); + +#keyset[id] +const_block_pat_block_exprs( + int id: @const_block_pat ref, + int block_expr: @block_expr ref +); + +#keyset[id] +const_block_pat_is_const( + int id: @const_block_pat ref +); + +const_params( + unique int id: @const_param +); + +#keyset[id, index] +const_param_attrs( + int id: @const_param ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +const_param_default_vals( + int id: @const_param ref, + int default_val: @const_arg ref +); + +#keyset[id] +const_param_is_const( + int id: @const_param ref +); + +#keyset[id] +const_param_names( + int id: @const_param ref, + int name: @name ref +); + +#keyset[id] +const_param_type_reprs( + int id: @const_param ref, + int type_repr: @type_repr ref +); + +continue_exprs( + unique int id: @continue_expr +); + +#keyset[id, index] +continue_expr_attrs( + int id: @continue_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +continue_expr_lifetimes( + int id: @continue_expr ref, + int lifetime: @lifetime ref +); + +dyn_trait_type_reprs( + unique int id: @dyn_trait_type_repr +); + +#keyset[id] +dyn_trait_type_repr_type_bound_lists( + int id: @dyn_trait_type_repr ref, + int type_bound_list: @type_bound_list ref +); + +expr_stmts( + unique int id: @expr_stmt +); + +#keyset[id] +expr_stmt_exprs( + int id: @expr_stmt ref, + int expr: @expr ref +); + +field_exprs( + unique int id: @field_expr +); + +#keyset[id, index] +field_expr_attrs( + int id: @field_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +field_expr_containers( + int id: @field_expr ref, + int container: @expr ref +); + +#keyset[id] +field_expr_identifiers( + int id: @field_expr ref, + int identifier: @name_ref ref +); + +fn_ptr_type_reprs( + unique int id: @fn_ptr_type_repr +); + +#keyset[id] +fn_ptr_type_repr_abis( + int id: @fn_ptr_type_repr ref, + int abi: @abi ref +); + +#keyset[id] +fn_ptr_type_repr_is_async( + int id: @fn_ptr_type_repr ref +); + +#keyset[id] +fn_ptr_type_repr_is_const( + int id: @fn_ptr_type_repr ref +); + +#keyset[id] +fn_ptr_type_repr_is_unsafe( + int id: @fn_ptr_type_repr ref +); + +#keyset[id] +fn_ptr_type_repr_param_lists( + int id: @fn_ptr_type_repr ref, + int param_list: @param_list ref +); + +#keyset[id] +fn_ptr_type_repr_ret_types( + int id: @fn_ptr_type_repr ref, + int ret_type: @ret_type_repr ref +); + +for_type_reprs( + unique int id: @for_type_repr +); + +#keyset[id] +for_type_repr_for_binders( + int id: @for_type_repr ref, + int for_binder: @for_binder ref +); + +#keyset[id] +for_type_repr_type_reprs( + int id: @for_type_repr ref, + int type_repr: @type_repr ref +); + +format_args_exprs( + unique int id: @format_args_expr +); + +#keyset[id, index] +format_args_expr_args( + int id: @format_args_expr ref, + int index: int ref, + int arg: @format_args_arg ref +); + +#keyset[id, index] +format_args_expr_attrs( + int id: @format_args_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +format_args_expr_templates( + int id: @format_args_expr ref, + int template: @expr ref +); + +ident_pats( + unique int id: @ident_pat +); + +#keyset[id, index] +ident_pat_attrs( + int id: @ident_pat ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +ident_pat_is_mut( + int id: @ident_pat ref +); + +#keyset[id] +ident_pat_is_ref( + int id: @ident_pat ref +); + +#keyset[id] +ident_pat_names( + int id: @ident_pat ref, + int name: @name ref +); + +#keyset[id] +ident_pat_pats( + int id: @ident_pat ref, + int pat: @pat ref +); + +if_exprs( + unique int id: @if_expr +); + +#keyset[id, index] +if_expr_attrs( + int id: @if_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +if_expr_conditions( + int id: @if_expr ref, + int condition: @expr ref +); + +#keyset[id] +if_expr_elses( + int id: @if_expr ref, + int else: @expr ref +); + +#keyset[id] +if_expr_thens( + int id: @if_expr ref, + int then: @block_expr ref +); + +impl_trait_type_reprs( + unique int id: @impl_trait_type_repr +); + +#keyset[id] +impl_trait_type_repr_type_bound_lists( + int id: @impl_trait_type_repr ref, + int type_bound_list: @type_bound_list ref +); + +index_exprs( + unique int id: @index_expr +); + +#keyset[id, index] +index_expr_attrs( + int id: @index_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +index_expr_bases( + int id: @index_expr ref, + int base: @expr ref +); + +#keyset[id] +index_expr_indices( + int id: @index_expr ref, + int index: @expr ref +); + +infer_type_reprs( + unique int id: @infer_type_repr +); + +@item = + @adt +| @asm_expr +| @assoc_item +| @extern_block +| @extern_crate +| @extern_item +| @impl +| @macro_def +| @macro_rules +| @module +| @trait +| @trait_alias +| @use +; + +#keyset[id] +item_attribute_macro_expansions( + int id: @item ref, + int attribute_macro_expansion: @macro_items ref +); + +@labelable_expr = + @block_expr +| @looping_expr +; + +#keyset[id] +labelable_expr_labels( + int id: @labelable_expr ref, + int label: @label ref +); + +let_exprs( + unique int id: @let_expr +); + +#keyset[id, index] +let_expr_attrs( + int id: @let_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +let_expr_scrutinees( + int id: @let_expr ref, + int scrutinee: @expr ref +); + +#keyset[id] +let_expr_pats( + int id: @let_expr ref, + int pat: @pat ref +); + +let_stmts( + unique int id: @let_stmt +); + +#keyset[id, index] +let_stmt_attrs( + int id: @let_stmt ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +let_stmt_initializers( + int id: @let_stmt ref, + int initializer: @expr ref +); + +#keyset[id] +let_stmt_let_elses( + int id: @let_stmt ref, + int let_else: @let_else ref +); + +#keyset[id] +let_stmt_pats( + int id: @let_stmt ref, + int pat: @pat ref +); + +#keyset[id] +let_stmt_type_reprs( + int id: @let_stmt ref, + int type_repr: @type_repr ref +); + +lifetimes( + unique int id: @lifetime +); + +#keyset[id] +lifetime_texts( + int id: @lifetime ref, + string text: string ref +); + +lifetime_args( + unique int id: @lifetime_arg +); + +#keyset[id] +lifetime_arg_lifetimes( + int id: @lifetime_arg ref, + int lifetime: @lifetime ref +); + +lifetime_params( + unique int id: @lifetime_param +); + +#keyset[id, index] +lifetime_param_attrs( + int id: @lifetime_param ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +lifetime_param_lifetimes( + int id: @lifetime_param ref, + int lifetime: @lifetime ref +); + +#keyset[id] +lifetime_param_type_bound_lists( + int id: @lifetime_param ref, + int type_bound_list: @type_bound_list ref +); + +literal_exprs( + unique int id: @literal_expr +); + +#keyset[id, index] +literal_expr_attrs( + int id: @literal_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +literal_expr_text_values( + int id: @literal_expr ref, + string text_value: string ref +); + +literal_pats( + unique int id: @literal_pat +); + +#keyset[id] +literal_pat_literals( + int id: @literal_pat ref, + int literal: @literal_expr ref +); + +macro_block_exprs( + unique int id: @macro_block_expr +); + +#keyset[id, index] +macro_block_expr_statements( + int id: @macro_block_expr ref, + int index: int ref, + int statement: @stmt ref +); + +#keyset[id] +macro_block_expr_tail_exprs( + int id: @macro_block_expr ref, + int tail_expr: @expr ref +); + +macro_exprs( + unique int id: @macro_expr +); + +#keyset[id] +macro_expr_macro_calls( + int id: @macro_expr ref, + int macro_call: @macro_call ref +); + +macro_pats( + unique int id: @macro_pat +); + +#keyset[id] +macro_pat_macro_calls( + int id: @macro_pat ref, + int macro_call: @macro_call ref +); + +macro_type_reprs( + unique int id: @macro_type_repr +); + +#keyset[id] +macro_type_repr_macro_calls( + int id: @macro_type_repr ref, + int macro_call: @macro_call ref +); + +match_exprs( + unique int id: @match_expr +); + +#keyset[id, index] +match_expr_attrs( + int id: @match_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +match_expr_scrutinees( + int id: @match_expr ref, + int scrutinee: @expr ref +); + +#keyset[id] +match_expr_match_arm_lists( + int id: @match_expr ref, + int match_arm_list: @match_arm_list ref +); + +method_call_exprs( + unique int id: @method_call_expr +); + +#keyset[id] +method_call_expr_arg_lists( + int id: @method_call_expr ref, + int arg_list: @arg_list ref +); + +#keyset[id, index] +method_call_expr_attrs( + int id: @method_call_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +method_call_expr_generic_arg_lists( + int id: @method_call_expr ref, + int generic_arg_list: @generic_arg_list ref +); + +#keyset[id] +method_call_expr_identifiers( + int id: @method_call_expr ref, + int identifier: @name_ref ref +); + +#keyset[id] +method_call_expr_receivers( + int id: @method_call_expr ref, + int receiver: @expr ref +); + +name_refs( + unique int id: @name_ref +); + +#keyset[id] +name_ref_texts( + int id: @name_ref ref, + string text: string ref +); + +never_type_reprs( + unique int id: @never_type_repr +); + +offset_of_exprs( + unique int id: @offset_of_expr +); + +#keyset[id, index] +offset_of_expr_attrs( + int id: @offset_of_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id, index] +offset_of_expr_fields( + int id: @offset_of_expr ref, + int index: int ref, + int field: @name_ref ref +); + +#keyset[id] +offset_of_expr_type_reprs( + int id: @offset_of_expr ref, + int type_repr: @type_repr ref +); + +or_pats( + unique int id: @or_pat +); + +#keyset[id, index] +or_pat_pats( + int id: @or_pat ref, + int index: int ref, + int pat: @pat ref +); + +params( + unique int id: @param +); + +#keyset[id] +param_pats( + int id: @param ref, + int pat: @pat ref +); + +paren_exprs( + unique int id: @paren_expr +); + +#keyset[id, index] +paren_expr_attrs( + int id: @paren_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +paren_expr_exprs( + int id: @paren_expr ref, + int expr: @expr ref +); + +paren_pats( + unique int id: @paren_pat +); + +#keyset[id] +paren_pat_pats( + int id: @paren_pat ref, + int pat: @pat ref +); + +paren_type_reprs( + unique int id: @paren_type_repr +); + +#keyset[id] +paren_type_repr_type_reprs( + int id: @paren_type_repr ref, + int type_repr: @type_repr ref +); + +@path_expr_base = + @path_expr +; + +path_pats( + unique int id: @path_pat +); + +path_type_reprs( + unique int id: @path_type_repr +); + +#keyset[id] +path_type_repr_paths( + int id: @path_type_repr ref, + int path: @path ref +); + +prefix_exprs( + unique int id: @prefix_expr +); + +#keyset[id, index] +prefix_expr_attrs( + int id: @prefix_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +prefix_expr_exprs( + int id: @prefix_expr ref, + int expr: @expr ref +); + +#keyset[id] +prefix_expr_operator_names( + int id: @prefix_expr ref, + string operator_name: string ref +); + +ptr_type_reprs( + unique int id: @ptr_type_repr +); + +#keyset[id] +ptr_type_repr_is_const( + int id: @ptr_type_repr ref +); + +#keyset[id] +ptr_type_repr_is_mut( + int id: @ptr_type_repr ref +); + +#keyset[id] +ptr_type_repr_type_reprs( + int id: @ptr_type_repr ref, + int type_repr: @type_repr ref +); + +range_exprs( + unique int id: @range_expr +); + +#keyset[id, index] +range_expr_attrs( + int id: @range_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +range_expr_ends( + int id: @range_expr ref, + int end: @expr ref +); + +#keyset[id] +range_expr_operator_names( + int id: @range_expr ref, + string operator_name: string ref +); + +#keyset[id] +range_expr_starts( + int id: @range_expr ref, + int start: @expr ref +); + +range_pats( + unique int id: @range_pat +); + +#keyset[id] +range_pat_ends( + int id: @range_pat ref, + int end: @pat ref +); + +#keyset[id] +range_pat_operator_names( + int id: @range_pat ref, + string operator_name: string ref +); + +#keyset[id] +range_pat_starts( + int id: @range_pat ref, + int start: @pat ref +); + +ref_exprs( + unique int id: @ref_expr +); + +#keyset[id, index] +ref_expr_attrs( + int id: @ref_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +ref_expr_exprs( + int id: @ref_expr ref, + int expr: @expr ref +); + +#keyset[id] +ref_expr_is_const( + int id: @ref_expr ref +); + +#keyset[id] +ref_expr_is_mut( + int id: @ref_expr ref +); + +#keyset[id] +ref_expr_is_raw( + int id: @ref_expr ref +); + +ref_pats( + unique int id: @ref_pat +); + +#keyset[id] +ref_pat_is_mut( + int id: @ref_pat ref +); + +#keyset[id] +ref_pat_pats( + int id: @ref_pat ref, + int pat: @pat ref +); + +ref_type_reprs( + unique int id: @ref_type_repr +); + +#keyset[id] +ref_type_repr_is_mut( + int id: @ref_type_repr ref +); + +#keyset[id] +ref_type_repr_lifetimes( + int id: @ref_type_repr ref, + int lifetime: @lifetime ref +); + +#keyset[id] +ref_type_repr_type_reprs( + int id: @ref_type_repr ref, + int type_repr: @type_repr ref +); + +rest_pats( + unique int id: @rest_pat +); + +#keyset[id, index] +rest_pat_attrs( + int id: @rest_pat ref, + int index: int ref, + int attr: @attr ref +); + +return_exprs( + unique int id: @return_expr +); + +#keyset[id, index] +return_expr_attrs( + int id: @return_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +return_expr_exprs( + int id: @return_expr ref, + int expr: @expr ref +); + +self_params( + unique int id: @self_param +); + +#keyset[id] +self_param_is_ref( + int id: @self_param ref +); + +#keyset[id] +self_param_is_mut( + int id: @self_param ref +); + +#keyset[id] +self_param_lifetimes( + int id: @self_param ref, + int lifetime: @lifetime ref +); + +#keyset[id] +self_param_names( + int id: @self_param ref, + int name: @name ref +); + +slice_pats( + unique int id: @slice_pat +); + +#keyset[id, index] +slice_pat_pats( + int id: @slice_pat ref, + int index: int ref, + int pat: @pat ref +); + +slice_type_reprs( + unique int id: @slice_type_repr +); + +#keyset[id] +slice_type_repr_type_reprs( + int id: @slice_type_repr ref, + int type_repr: @type_repr ref +); + +struct_exprs( + unique int id: @struct_expr +); + +#keyset[id] +struct_expr_struct_expr_field_lists( + int id: @struct_expr ref, + int struct_expr_field_list: @struct_expr_field_list ref +); + +struct_field_lists( + unique int id: @struct_field_list +); + +#keyset[id, index] +struct_field_list_fields( + int id: @struct_field_list ref, + int index: int ref, + int field: @struct_field ref +); + +struct_pats( + unique int id: @struct_pat +); + +#keyset[id] +struct_pat_struct_pat_field_lists( + int id: @struct_pat ref, + int struct_pat_field_list: @struct_pat_field_list ref +); + +try_exprs( + unique int id: @try_expr +); + +#keyset[id, index] +try_expr_attrs( + int id: @try_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +try_expr_exprs( + int id: @try_expr ref, + int expr: @expr ref +); + +tuple_exprs( + unique int id: @tuple_expr +); + +#keyset[id, index] +tuple_expr_attrs( + int id: @tuple_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id, index] +tuple_expr_fields( + int id: @tuple_expr ref, + int index: int ref, + int field: @expr ref +); + +tuple_field_lists( + unique int id: @tuple_field_list +); + +#keyset[id, index] +tuple_field_list_fields( + int id: @tuple_field_list ref, + int index: int ref, + int field: @tuple_field ref +); + +tuple_pats( + unique int id: @tuple_pat +); + +#keyset[id, index] +tuple_pat_fields( + int id: @tuple_pat ref, + int index: int ref, + int field: @pat ref +); + +tuple_struct_pats( + unique int id: @tuple_struct_pat +); + +#keyset[id, index] +tuple_struct_pat_fields( + int id: @tuple_struct_pat ref, + int index: int ref, + int field: @pat ref +); + +tuple_type_reprs( + unique int id: @tuple_type_repr +); + +#keyset[id, index] +tuple_type_repr_fields( + int id: @tuple_type_repr ref, + int index: int ref, + int field: @type_repr ref +); + +type_args( + unique int id: @type_arg +); + +#keyset[id] +type_arg_type_reprs( + int id: @type_arg ref, + int type_repr: @type_repr ref +); + +type_params( + unique int id: @type_param +); + +#keyset[id, index] +type_param_attrs( + int id: @type_param ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +type_param_default_types( + int id: @type_param ref, + int default_type: @type_repr ref +); + +#keyset[id] +type_param_names( + int id: @type_param ref, + int name: @name ref +); + +#keyset[id] +type_param_type_bound_lists( + int id: @type_param ref, + int type_bound_list: @type_bound_list ref +); + +underscore_exprs( + unique int id: @underscore_expr +); + +#keyset[id, index] +underscore_expr_attrs( + int id: @underscore_expr ref, + int index: int ref, + int attr: @attr ref +); + +variants( + unique int id: @variant +); + +#keyset[id, index] +variant_attrs( + int id: @variant ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +variant_discriminants( + int id: @variant ref, + int discriminant: @expr ref +); + +#keyset[id] +variant_field_lists( + int id: @variant ref, + int field_list: @field_list ref +); + +#keyset[id] +variant_names( + int id: @variant ref, + int name: @name ref +); + +#keyset[id] +variant_visibilities( + int id: @variant ref, + int visibility: @visibility ref +); + +wildcard_pats( + unique int id: @wildcard_pat +); + +yeet_exprs( + unique int id: @yeet_expr +); + +#keyset[id, index] +yeet_expr_attrs( + int id: @yeet_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +yeet_expr_exprs( + int id: @yeet_expr ref, + int expr: @expr ref +); + +yield_exprs( + unique int id: @yield_expr +); + +#keyset[id, index] +yield_expr_attrs( + int id: @yield_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +yield_expr_exprs( + int id: @yield_expr ref, + int expr: @expr ref +); + +@adt = + @enum +| @struct +| @union +; + +#keyset[id, index] +adt_derive_macro_expansions( + int id: @adt ref, + int index: int ref, + int derive_macro_expansion: @macro_items ref +); + +asm_exprs( + unique int id: @asm_expr +); + +#keyset[id, index] +asm_expr_asm_pieces( + int id: @asm_expr ref, + int index: int ref, + int asm_piece: @asm_piece ref +); + +#keyset[id, index] +asm_expr_attrs( + int id: @asm_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id, index] +asm_expr_templates( + int id: @asm_expr ref, + int index: int ref, + int template: @expr ref +); + +@assoc_item = + @const +| @function +| @macro_call +| @type_alias +; + +block_exprs( + unique int id: @block_expr +); + +#keyset[id, index] +block_expr_attrs( + int id: @block_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +block_expr_is_async( + int id: @block_expr ref +); + +#keyset[id] +block_expr_is_const( + int id: @block_expr ref +); + +#keyset[id] +block_expr_is_gen( + int id: @block_expr ref +); + +#keyset[id] +block_expr_is_move( + int id: @block_expr ref +); + +#keyset[id] +block_expr_is_try( + int id: @block_expr ref +); + +#keyset[id] +block_expr_is_unsafe( + int id: @block_expr ref +); + +#keyset[id] +block_expr_stmt_lists( + int id: @block_expr ref, + int stmt_list: @stmt_list ref +); + +extern_blocks( + unique int id: @extern_block +); + +#keyset[id] +extern_block_abis( + int id: @extern_block ref, + int abi: @abi ref +); + +#keyset[id, index] +extern_block_attrs( + int id: @extern_block ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +extern_block_extern_item_lists( + int id: @extern_block ref, + int extern_item_list: @extern_item_list ref +); + +#keyset[id] +extern_block_is_unsafe( + int id: @extern_block ref +); + +extern_crates( + unique int id: @extern_crate +); + +#keyset[id, index] +extern_crate_attrs( + int id: @extern_crate ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +extern_crate_identifiers( + int id: @extern_crate ref, + int identifier: @name_ref ref +); + +#keyset[id] +extern_crate_renames( + int id: @extern_crate ref, + int rename: @rename ref +); + +#keyset[id] +extern_crate_visibilities( + int id: @extern_crate ref, + int visibility: @visibility ref +); + +@extern_item = + @function +| @macro_call +| @static +| @type_alias +; + +impls( + unique int id: @impl +); + +#keyset[id] +impl_assoc_item_lists( + int id: @impl ref, + int assoc_item_list: @assoc_item_list ref +); + +#keyset[id, index] +impl_attrs( + int id: @impl ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +impl_generic_param_lists( + int id: @impl ref, + int generic_param_list: @generic_param_list ref +); + +#keyset[id] +impl_is_const( + int id: @impl ref +); + +#keyset[id] +impl_is_default( + int id: @impl ref +); + +#keyset[id] +impl_is_unsafe( + int id: @impl ref +); + +#keyset[id] +impl_self_ties( + int id: @impl ref, + int self_ty: @type_repr ref +); + +#keyset[id] +impl_traits( + int id: @impl ref, + int trait: @type_repr ref +); + +#keyset[id] +impl_visibilities( + int id: @impl ref, + int visibility: @visibility ref +); + +#keyset[id] +impl_where_clauses( + int id: @impl ref, + int where_clause: @where_clause ref +); + +@looping_expr = + @for_expr +| @loop_expr +| @while_expr +; + +#keyset[id] +looping_expr_loop_bodies( + int id: @looping_expr ref, + int loop_body: @block_expr ref +); + +macro_defs( + unique int id: @macro_def +); + +#keyset[id] +macro_def_args( + int id: @macro_def ref, + int args: @token_tree ref +); + +#keyset[id, index] +macro_def_attrs( + int id: @macro_def ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +macro_def_bodies( + int id: @macro_def ref, + int body: @token_tree ref +); + +#keyset[id] +macro_def_names( + int id: @macro_def ref, + int name: @name ref +); + +#keyset[id] +macro_def_visibilities( + int id: @macro_def ref, + int visibility: @visibility ref +); + +macro_rules( + unique int id: @macro_rules +); + +#keyset[id, index] +macro_rules_attrs( + int id: @macro_rules ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +macro_rules_names( + int id: @macro_rules ref, + int name: @name ref +); + +#keyset[id] +macro_rules_token_trees( + int id: @macro_rules ref, + int token_tree: @token_tree ref +); + +#keyset[id] +macro_rules_visibilities( + int id: @macro_rules ref, + int visibility: @visibility ref +); + +modules( + unique int id: @module +); + +#keyset[id, index] +module_attrs( + int id: @module ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +module_item_lists( + int id: @module ref, + int item_list: @item_list ref +); + +#keyset[id] +module_names( + int id: @module ref, + int name: @name ref +); + +#keyset[id] +module_visibilities( + int id: @module ref, + int visibility: @visibility ref +); + +path_exprs( + unique int id: @path_expr +); + +#keyset[id, index] +path_expr_attrs( + int id: @path_expr ref, + int index: int ref, + int attr: @attr ref +); + +traits( + unique int id: @trait +); + +#keyset[id] +trait_assoc_item_lists( + int id: @trait ref, + int assoc_item_list: @assoc_item_list ref +); + +#keyset[id, index] +trait_attrs( + int id: @trait ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +trait_generic_param_lists( + int id: @trait ref, + int generic_param_list: @generic_param_list ref +); + +#keyset[id] +trait_is_auto( + int id: @trait ref +); + +#keyset[id] +trait_is_unsafe( + int id: @trait ref +); + +#keyset[id] +trait_names( + int id: @trait ref, + int name: @name ref +); + +#keyset[id] +trait_type_bound_lists( + int id: @trait ref, + int type_bound_list: @type_bound_list ref +); + +#keyset[id] +trait_visibilities( + int id: @trait ref, + int visibility: @visibility ref +); + +#keyset[id] +trait_where_clauses( + int id: @trait ref, + int where_clause: @where_clause ref +); + +trait_aliases( + unique int id: @trait_alias +); + +#keyset[id, index] +trait_alias_attrs( + int id: @trait_alias ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +trait_alias_generic_param_lists( + int id: @trait_alias ref, + int generic_param_list: @generic_param_list ref +); + +#keyset[id] +trait_alias_names( + int id: @trait_alias ref, + int name: @name ref +); + +#keyset[id] +trait_alias_type_bound_lists( + int id: @trait_alias ref, + int type_bound_list: @type_bound_list ref +); + +#keyset[id] +trait_alias_visibilities( + int id: @trait_alias ref, + int visibility: @visibility ref +); + +#keyset[id] +trait_alias_where_clauses( + int id: @trait_alias ref, + int where_clause: @where_clause ref +); + +uses( + unique int id: @use +); + +#keyset[id, index] +use_attrs( + int id: @use ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +use_use_trees( + int id: @use ref, + int use_tree: @use_tree ref +); + +#keyset[id] +use_visibilities( + int id: @use ref, + int visibility: @visibility ref +); + +consts( + unique int id: @const +); + +#keyset[id, index] +const_attrs( + int id: @const ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +const_bodies( + int id: @const ref, + int body: @expr ref +); + +#keyset[id] +const_generic_param_lists( + int id: @const ref, + int generic_param_list: @generic_param_list ref +); + +#keyset[id] +const_is_const( + int id: @const ref +); + +#keyset[id] +const_is_default( + int id: @const ref +); + +#keyset[id] +const_names( + int id: @const ref, + int name: @name ref +); + +#keyset[id] +const_type_reprs( + int id: @const ref, + int type_repr: @type_repr ref +); + +#keyset[id] +const_visibilities( + int id: @const ref, + int visibility: @visibility ref +); + +#keyset[id] +const_where_clauses( + int id: @const ref, + int where_clause: @where_clause ref +); + +#keyset[id] +const_has_implementation( + int id: @const ref +); + +enums( + unique int id: @enum +); + +#keyset[id, index] +enum_attrs( + int id: @enum ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +enum_generic_param_lists( + int id: @enum ref, + int generic_param_list: @generic_param_list ref +); + +#keyset[id] +enum_names( + int id: @enum ref, + int name: @name ref +); + +#keyset[id] +enum_variant_lists( + int id: @enum ref, + int variant_list: @variant_list ref +); + +#keyset[id] +enum_visibilities( + int id: @enum ref, + int visibility: @visibility ref +); + +#keyset[id] +enum_where_clauses( + int id: @enum ref, + int where_clause: @where_clause ref +); + +for_exprs( + unique int id: @for_expr +); + +#keyset[id, index] +for_expr_attrs( + int id: @for_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +for_expr_iterables( + int id: @for_expr ref, + int iterable: @expr ref +); + +#keyset[id] +for_expr_pats( + int id: @for_expr ref, + int pat: @pat ref +); + +functions( + unique int id: @function +); + +#keyset[id] +function_abis( + int id: @function ref, + int abi: @abi ref +); + +#keyset[id] +function_function_bodies( + int id: @function ref, + int function_body: @block_expr ref +); + +#keyset[id] +function_generic_param_lists( + int id: @function ref, + int generic_param_list: @generic_param_list ref +); + +#keyset[id] +function_is_async( + int id: @function ref +); + +#keyset[id] +function_is_const( + int id: @function ref +); + +#keyset[id] +function_is_default( + int id: @function ref +); + +#keyset[id] +function_is_gen( + int id: @function ref +); + +#keyset[id] +function_is_unsafe( + int id: @function ref +); + +#keyset[id] +function_names( + int id: @function ref, + int name: @name ref +); + +#keyset[id] +function_ret_types( + int id: @function ref, + int ret_type: @ret_type_repr ref +); + +#keyset[id] +function_visibilities( + int id: @function ref, + int visibility: @visibility ref +); + +#keyset[id] +function_where_clauses( + int id: @function ref, + int where_clause: @where_clause ref +); + +#keyset[id] +function_has_implementation( + int id: @function ref +); + +loop_exprs( + unique int id: @loop_expr +); + +#keyset[id, index] +loop_expr_attrs( + int id: @loop_expr ref, + int index: int ref, + int attr: @attr ref +); + +macro_calls( + unique int id: @macro_call +); + +#keyset[id, index] +macro_call_attrs( + int id: @macro_call ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +macro_call_paths( + int id: @macro_call ref, + int path: @path ref +); + +#keyset[id] +macro_call_token_trees( + int id: @macro_call ref, + int token_tree: @token_tree ref +); + +#keyset[id] +macro_call_macro_call_expansions( + int id: @macro_call ref, + int macro_call_expansion: @ast_node ref +); + +statics( + unique int id: @static +); + +#keyset[id, index] +static_attrs( + int id: @static ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +static_bodies( + int id: @static ref, + int body: @expr ref +); + +#keyset[id] +static_is_mut( + int id: @static ref +); + +#keyset[id] +static_is_static( + int id: @static ref +); + +#keyset[id] +static_is_unsafe( + int id: @static ref +); + +#keyset[id] +static_names( + int id: @static ref, + int name: @name ref +); + +#keyset[id] +static_type_reprs( + int id: @static ref, + int type_repr: @type_repr ref +); + +#keyset[id] +static_visibilities( + int id: @static ref, + int visibility: @visibility ref +); + +structs( + unique int id: @struct +); + +#keyset[id, index] +struct_attrs( + int id: @struct ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +struct_field_lists_( + int id: @struct ref, + int field_list: @field_list ref +); + +#keyset[id] +struct_generic_param_lists( + int id: @struct ref, + int generic_param_list: @generic_param_list ref +); + +#keyset[id] +struct_names( + int id: @struct ref, + int name: @name ref +); + +#keyset[id] +struct_visibilities( + int id: @struct ref, + int visibility: @visibility ref +); + +#keyset[id] +struct_where_clauses( + int id: @struct ref, + int where_clause: @where_clause ref +); + +type_aliases( + unique int id: @type_alias +); + +#keyset[id, index] +type_alias_attrs( + int id: @type_alias ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +type_alias_generic_param_lists( + int id: @type_alias ref, + int generic_param_list: @generic_param_list ref +); + +#keyset[id] +type_alias_is_default( + int id: @type_alias ref +); + +#keyset[id] +type_alias_names( + int id: @type_alias ref, + int name: @name ref +); + +#keyset[id] +type_alias_type_reprs( + int id: @type_alias ref, + int type_repr: @type_repr ref +); + +#keyset[id] +type_alias_type_bound_lists( + int id: @type_alias ref, + int type_bound_list: @type_bound_list ref +); + +#keyset[id] +type_alias_visibilities( + int id: @type_alias ref, + int visibility: @visibility ref +); + +#keyset[id] +type_alias_where_clauses( + int id: @type_alias ref, + int where_clause: @where_clause ref +); + +unions( + unique int id: @union +); + +#keyset[id, index] +union_attrs( + int id: @union ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +union_generic_param_lists( + int id: @union ref, + int generic_param_list: @generic_param_list ref +); + +#keyset[id] +union_names( + int id: @union ref, + int name: @name ref +); + +#keyset[id] +union_struct_field_lists( + int id: @union ref, + int struct_field_list: @struct_field_list ref +); + +#keyset[id] +union_visibilities( + int id: @union ref, + int visibility: @visibility ref +); + +#keyset[id] +union_where_clauses( + int id: @union ref, + int where_clause: @where_clause ref +); + +while_exprs( + unique int id: @while_expr +); + +#keyset[id, index] +while_expr_attrs( + int id: @while_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +while_expr_conditions( + int id: @while_expr ref, + int condition: @expr ref +); diff --git a/rust/downgrades/e54d01f67a416b3d6eb7b970f27295097f2cac7f/rust.dbscheme b/rust/downgrades/e54d01f67a416b3d6eb7b970f27295097f2cac7f/rust.dbscheme new file mode 100644 index 00000000000..30a0713e5bf --- /dev/null +++ b/rust/downgrades/e54d01f67a416b3d6eb7b970f27295097f2cac7f/rust.dbscheme @@ -0,0 +1,3615 @@ +// generated by codegen, do not edit + +// from ../shared/tree-sitter-extractor/src/generator/prefix.dbscheme +/*- Files and folders -*/ + +/** + * The location of an element. + * The location spans column `startcolumn` of line `startline` to + * column `endcolumn` of line `endline` in file `file`. + * For more information, see + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). + */ +locations_default( + unique int id: @location_default, + int file: @file ref, + int beginLine: int ref, + int beginColumn: int ref, + int endLine: int ref, + int endColumn: int ref +); + +files( + unique int id: @file, + string name: string ref +); + +folders( + unique int id: @folder, + string name: string ref +); + +@container = @file | @folder + +containerparent( + int parent: @container ref, + unique int child: @container ref +); + +/*- Empty location -*/ + +empty_location( + int location: @location_default ref +); + +/*- Source location prefix -*/ + +/** + * The source location of the snapshot. + */ +sourceLocationPrefix(string prefix : string ref); + +/*- Diagnostic messages -*/ + +diagnostics( + unique int id: @diagnostic, + int severity: int ref, + string error_tag: string ref, + string error_message: string ref, + string full_error_message: string ref, + int location: @location_default ref +); + +/*- Diagnostic messages: severity -*/ + +case @diagnostic.severity of + 10 = @diagnostic_debug +| 20 = @diagnostic_info +| 30 = @diagnostic_warning +| 40 = @diagnostic_error +; + +/*- YAML -*/ + +#keyset[parent, idx] +yaml (unique int id: @yaml_node, + int kind: int ref, + int parent: @yaml_node_parent ref, + int idx: int ref, + string tag: string ref, + string tostring: string ref); + +case @yaml_node.kind of + 0 = @yaml_scalar_node +| 1 = @yaml_mapping_node +| 2 = @yaml_sequence_node +| 3 = @yaml_alias_node +; + +@yaml_collection_node = @yaml_mapping_node | @yaml_sequence_node; + +@yaml_node_parent = @yaml_collection_node | @file; + +yaml_anchors (unique int node: @yaml_node ref, + string anchor: string ref); + +yaml_aliases (unique int alias: @yaml_alias_node ref, + string target: string ref); + +yaml_scalars (unique int scalar: @yaml_scalar_node ref, + int style: int ref, + string value: string ref); + +yaml_errors (unique int id: @yaml_error, + string message: string ref); + +yaml_locations(unique int locatable: @yaml_locatable ref, + int location: @location_default ref); + +@yaml_locatable = @yaml_node | @yaml_error; + +/*- Database metadata -*/ +databaseMetadata( + string metadataKey: string ref, + string value: string ref +); + +overlayChangedFiles( + string path: string ref +); + + +// from prefix.dbscheme +#keyset[id] +locatable_locations( + int id: @locatable ref, + int location: @location_default ref +); + + +// from schema + +@element = + @extractor_step +| @locatable +| @named_crate +| @unextracted +; + +extractor_steps( + unique int id: @extractor_step, + string action: string ref, + int duration_ms: int ref +); + +#keyset[id] +extractor_step_files( + int id: @extractor_step ref, + int file: @file ref +); + +@locatable = + @ast_node +| @crate +; + +named_crates( + unique int id: @named_crate, + string name: string ref, + int crate: @crate ref +); + +@unextracted = + @missing +| @unimplemented +; + +@ast_node = + @abi +| @addressable +| @arg_list +| @asm_dir_spec +| @asm_operand +| @asm_operand_expr +| @asm_option +| @asm_piece +| @asm_reg_spec +| @assoc_item_list +| @attr +| @callable +| @expr +| @extern_item_list +| @field_list +| @for_binder +| @format_args_arg +| @generic_arg +| @generic_arg_list +| @generic_param +| @generic_param_list +| @item_list +| @label +| @let_else +| @macro_items +| @match_arm +| @match_arm_list +| @match_guard +| @meta +| @name +| @param_base +| @param_list +| @parenthesized_arg_list +| @pat +| @path +| @path_ast_node +| @path_segment +| @rename +| @ret_type_repr +| @return_type_syntax +| @source_file +| @stmt +| @stmt_list +| @struct_expr_field +| @struct_expr_field_list +| @struct_field +| @struct_pat_field +| @struct_pat_field_list +| @token +| @token_tree +| @tuple_field +| @type_bound +| @type_bound_list +| @type_repr +| @use_bound_generic_arg +| @use_bound_generic_args +| @use_tree +| @use_tree_list +| @variant_list +| @visibility +| @where_clause +| @where_pred +; + +crates( + unique int id: @crate +); + +#keyset[id] +crate_names( + int id: @crate ref, + string name: string ref +); + +#keyset[id] +crate_versions( + int id: @crate ref, + string version: string ref +); + +#keyset[id, index] +crate_cfg_options( + int id: @crate ref, + int index: int ref, + string cfg_option: string ref +); + +#keyset[id, index] +crate_named_dependencies( + int id: @crate ref, + int index: int ref, + int named_dependency: @named_crate ref +); + +missings( + unique int id: @missing +); + +unimplementeds( + unique int id: @unimplemented +); + +abis( + unique int id: @abi +); + +#keyset[id] +abi_abi_strings( + int id: @abi ref, + string abi_string: string ref +); + +@addressable = + @item +| @variant +; + +arg_lists( + unique int id: @arg_list +); + +#keyset[id, index] +arg_list_args( + int id: @arg_list ref, + int index: int ref, + int arg: @expr ref +); + +asm_dir_specs( + unique int id: @asm_dir_spec +); + +@asm_operand = + @asm_const +| @asm_label +| @asm_reg_operand +| @asm_sym +; + +asm_operand_exprs( + unique int id: @asm_operand_expr +); + +#keyset[id] +asm_operand_expr_in_exprs( + int id: @asm_operand_expr ref, + int in_expr: @expr ref +); + +#keyset[id] +asm_operand_expr_out_exprs( + int id: @asm_operand_expr ref, + int out_expr: @expr ref +); + +asm_options( + unique int id: @asm_option +); + +#keyset[id] +asm_option_is_raw( + int id: @asm_option ref +); + +@asm_piece = + @asm_clobber_abi +| @asm_operand_named +| @asm_options_list +; + +asm_reg_specs( + unique int id: @asm_reg_spec +); + +#keyset[id] +asm_reg_spec_identifiers( + int id: @asm_reg_spec ref, + int identifier: @name_ref ref +); + +assoc_item_lists( + unique int id: @assoc_item_list +); + +#keyset[id, index] +assoc_item_list_assoc_items( + int id: @assoc_item_list ref, + int index: int ref, + int assoc_item: @assoc_item ref +); + +#keyset[id, index] +assoc_item_list_attrs( + int id: @assoc_item_list ref, + int index: int ref, + int attr: @attr ref +); + +attrs( + unique int id: @attr +); + +#keyset[id] +attr_meta( + int id: @attr ref, + int meta: @meta ref +); + +@callable = + @closure_expr +| @function +; + +#keyset[id] +callable_param_lists( + int id: @callable ref, + int param_list: @param_list ref +); + +#keyset[id, index] +callable_attrs( + int id: @callable ref, + int index: int ref, + int attr: @attr ref +); + +@expr = + @array_expr_internal +| @asm_expr +| @await_expr +| @become_expr +| @binary_expr +| @break_expr +| @call_expr_base +| @cast_expr +| @closure_expr +| @continue_expr +| @field_expr +| @format_args_expr +| @if_expr +| @index_expr +| @labelable_expr +| @let_expr +| @literal_expr +| @macro_block_expr +| @macro_expr +| @match_expr +| @offset_of_expr +| @paren_expr +| @path_expr_base +| @prefix_expr +| @range_expr +| @ref_expr +| @return_expr +| @struct_expr +| @try_expr +| @tuple_expr +| @underscore_expr +| @yeet_expr +| @yield_expr +; + +extern_item_lists( + unique int id: @extern_item_list +); + +#keyset[id, index] +extern_item_list_attrs( + int id: @extern_item_list ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id, index] +extern_item_list_extern_items( + int id: @extern_item_list ref, + int index: int ref, + int extern_item: @extern_item ref +); + +@field_list = + @struct_field_list +| @tuple_field_list +; + +for_binders( + unique int id: @for_binder +); + +#keyset[id] +for_binder_generic_param_lists( + int id: @for_binder ref, + int generic_param_list: @generic_param_list ref +); + +format_args_args( + unique int id: @format_args_arg +); + +#keyset[id] +format_args_arg_exprs( + int id: @format_args_arg ref, + int expr: @expr ref +); + +#keyset[id] +format_args_arg_names( + int id: @format_args_arg ref, + int name: @name ref +); + +@generic_arg = + @assoc_type_arg +| @const_arg +| @lifetime_arg +| @type_arg +; + +generic_arg_lists( + unique int id: @generic_arg_list +); + +#keyset[id, index] +generic_arg_list_generic_args( + int id: @generic_arg_list ref, + int index: int ref, + int generic_arg: @generic_arg ref +); + +@generic_param = + @const_param +| @lifetime_param +| @type_param +; + +generic_param_lists( + unique int id: @generic_param_list +); + +#keyset[id, index] +generic_param_list_generic_params( + int id: @generic_param_list ref, + int index: int ref, + int generic_param: @generic_param ref +); + +item_lists( + unique int id: @item_list +); + +#keyset[id, index] +item_list_attrs( + int id: @item_list ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id, index] +item_list_items( + int id: @item_list ref, + int index: int ref, + int item: @item ref +); + +labels( + unique int id: @label +); + +#keyset[id] +label_lifetimes( + int id: @label ref, + int lifetime: @lifetime ref +); + +let_elses( + unique int id: @let_else +); + +#keyset[id] +let_else_block_exprs( + int id: @let_else ref, + int block_expr: @block_expr ref +); + +macro_items( + unique int id: @macro_items +); + +#keyset[id, index] +macro_items_items( + int id: @macro_items ref, + int index: int ref, + int item: @item ref +); + +match_arms( + unique int id: @match_arm +); + +#keyset[id, index] +match_arm_attrs( + int id: @match_arm ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +match_arm_exprs( + int id: @match_arm ref, + int expr: @expr ref +); + +#keyset[id] +match_arm_guards( + int id: @match_arm ref, + int guard: @match_guard ref +); + +#keyset[id] +match_arm_pats( + int id: @match_arm ref, + int pat: @pat ref +); + +match_arm_lists( + unique int id: @match_arm_list +); + +#keyset[id, index] +match_arm_list_arms( + int id: @match_arm_list ref, + int index: int ref, + int arm: @match_arm ref +); + +#keyset[id, index] +match_arm_list_attrs( + int id: @match_arm_list ref, + int index: int ref, + int attr: @attr ref +); + +match_guards( + unique int id: @match_guard +); + +#keyset[id] +match_guard_conditions( + int id: @match_guard ref, + int condition: @expr ref +); + +meta( + unique int id: @meta +); + +#keyset[id] +meta_exprs( + int id: @meta ref, + int expr: @expr ref +); + +#keyset[id] +meta_is_unsafe( + int id: @meta ref +); + +#keyset[id] +meta_paths( + int id: @meta ref, + int path: @path ref +); + +#keyset[id] +meta_token_trees( + int id: @meta ref, + int token_tree: @token_tree ref +); + +names( + unique int id: @name +); + +#keyset[id] +name_texts( + int id: @name ref, + string text: string ref +); + +@param_base = + @param +| @self_param +; + +#keyset[id, index] +param_base_attrs( + int id: @param_base ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +param_base_type_reprs( + int id: @param_base ref, + int type_repr: @type_repr ref +); + +param_lists( + unique int id: @param_list +); + +#keyset[id, index] +param_list_params( + int id: @param_list ref, + int index: int ref, + int param: @param ref +); + +#keyset[id] +param_list_self_params( + int id: @param_list ref, + int self_param: @self_param ref +); + +parenthesized_arg_lists( + unique int id: @parenthesized_arg_list +); + +#keyset[id, index] +parenthesized_arg_list_type_args( + int id: @parenthesized_arg_list ref, + int index: int ref, + int type_arg: @type_arg ref +); + +@pat = + @box_pat +| @const_block_pat +| @ident_pat +| @literal_pat +| @macro_pat +| @or_pat +| @paren_pat +| @path_pat +| @range_pat +| @ref_pat +| @rest_pat +| @slice_pat +| @struct_pat +| @tuple_pat +| @tuple_struct_pat +| @wildcard_pat +; + +paths( + unique int id: @path +); + +#keyset[id] +path_qualifiers( + int id: @path ref, + int qualifier: @path ref +); + +#keyset[id] +path_segments_( + int id: @path ref, + int segment: @path_segment ref +); + +@path_ast_node = + @path_expr +| @path_pat +| @struct_expr +| @struct_pat +| @tuple_struct_pat +; + +#keyset[id] +path_ast_node_paths( + int id: @path_ast_node ref, + int path: @path ref +); + +path_segments( + unique int id: @path_segment +); + +#keyset[id] +path_segment_generic_arg_lists( + int id: @path_segment ref, + int generic_arg_list: @generic_arg_list ref +); + +#keyset[id] +path_segment_identifiers( + int id: @path_segment ref, + int identifier: @name_ref ref +); + +#keyset[id] +path_segment_parenthesized_arg_lists( + int id: @path_segment ref, + int parenthesized_arg_list: @parenthesized_arg_list ref +); + +#keyset[id] +path_segment_ret_types( + int id: @path_segment ref, + int ret_type: @ret_type_repr ref +); + +#keyset[id] +path_segment_return_type_syntaxes( + int id: @path_segment ref, + int return_type_syntax: @return_type_syntax ref +); + +#keyset[id] +path_segment_type_reprs( + int id: @path_segment ref, + int type_repr: @type_repr ref +); + +#keyset[id] +path_segment_trait_type_reprs( + int id: @path_segment ref, + int trait_type_repr: @path_type_repr ref +); + +renames( + unique int id: @rename +); + +#keyset[id] +rename_names( + int id: @rename ref, + int name: @name ref +); + +ret_type_reprs( + unique int id: @ret_type_repr +); + +#keyset[id] +ret_type_repr_type_reprs( + int id: @ret_type_repr ref, + int type_repr: @type_repr ref +); + +return_type_syntaxes( + unique int id: @return_type_syntax +); + +source_files( + unique int id: @source_file +); + +#keyset[id, index] +source_file_attrs( + int id: @source_file ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id, index] +source_file_items( + int id: @source_file ref, + int index: int ref, + int item: @item ref +); + +@stmt = + @expr_stmt +| @item +| @let_stmt +; + +stmt_lists( + unique int id: @stmt_list +); + +#keyset[id, index] +stmt_list_attrs( + int id: @stmt_list ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id, index] +stmt_list_statements( + int id: @stmt_list ref, + int index: int ref, + int statement: @stmt ref +); + +#keyset[id] +stmt_list_tail_exprs( + int id: @stmt_list ref, + int tail_expr: @expr ref +); + +struct_expr_fields( + unique int id: @struct_expr_field +); + +#keyset[id, index] +struct_expr_field_attrs( + int id: @struct_expr_field ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +struct_expr_field_exprs( + int id: @struct_expr_field ref, + int expr: @expr ref +); + +#keyset[id] +struct_expr_field_identifiers( + int id: @struct_expr_field ref, + int identifier: @name_ref ref +); + +struct_expr_field_lists( + unique int id: @struct_expr_field_list +); + +#keyset[id, index] +struct_expr_field_list_attrs( + int id: @struct_expr_field_list ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id, index] +struct_expr_field_list_fields( + int id: @struct_expr_field_list ref, + int index: int ref, + int field: @struct_expr_field ref +); + +#keyset[id] +struct_expr_field_list_spreads( + int id: @struct_expr_field_list ref, + int spread: @expr ref +); + +struct_fields( + unique int id: @struct_field +); + +#keyset[id, index] +struct_field_attrs( + int id: @struct_field ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +struct_field_defaults( + int id: @struct_field ref, + int default: @expr ref +); + +#keyset[id] +struct_field_is_unsafe( + int id: @struct_field ref +); + +#keyset[id] +struct_field_names( + int id: @struct_field ref, + int name: @name ref +); + +#keyset[id] +struct_field_type_reprs( + int id: @struct_field ref, + int type_repr: @type_repr ref +); + +#keyset[id] +struct_field_visibilities( + int id: @struct_field ref, + int visibility: @visibility ref +); + +struct_pat_fields( + unique int id: @struct_pat_field +); + +#keyset[id, index] +struct_pat_field_attrs( + int id: @struct_pat_field ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +struct_pat_field_identifiers( + int id: @struct_pat_field ref, + int identifier: @name_ref ref +); + +#keyset[id] +struct_pat_field_pats( + int id: @struct_pat_field ref, + int pat: @pat ref +); + +struct_pat_field_lists( + unique int id: @struct_pat_field_list +); + +#keyset[id, index] +struct_pat_field_list_fields( + int id: @struct_pat_field_list ref, + int index: int ref, + int field: @struct_pat_field ref +); + +#keyset[id] +struct_pat_field_list_rest_pats( + int id: @struct_pat_field_list ref, + int rest_pat: @rest_pat ref +); + +@token = + @comment +; + +token_trees( + unique int id: @token_tree +); + +tuple_fields( + unique int id: @tuple_field +); + +#keyset[id, index] +tuple_field_attrs( + int id: @tuple_field ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +tuple_field_type_reprs( + int id: @tuple_field ref, + int type_repr: @type_repr ref +); + +#keyset[id] +tuple_field_visibilities( + int id: @tuple_field ref, + int visibility: @visibility ref +); + +type_bounds( + unique int id: @type_bound +); + +#keyset[id] +type_bound_for_binders( + int id: @type_bound ref, + int for_binder: @for_binder ref +); + +#keyset[id] +type_bound_is_async( + int id: @type_bound ref +); + +#keyset[id] +type_bound_is_const( + int id: @type_bound ref +); + +#keyset[id] +type_bound_lifetimes( + int id: @type_bound ref, + int lifetime: @lifetime ref +); + +#keyset[id] +type_bound_type_reprs( + int id: @type_bound ref, + int type_repr: @type_repr ref +); + +#keyset[id] +type_bound_use_bound_generic_args( + int id: @type_bound ref, + int use_bound_generic_args: @use_bound_generic_args ref +); + +type_bound_lists( + unique int id: @type_bound_list +); + +#keyset[id, index] +type_bound_list_bounds( + int id: @type_bound_list ref, + int index: int ref, + int bound: @type_bound ref +); + +@type_repr = + @array_type_repr +| @dyn_trait_type_repr +| @fn_ptr_type_repr +| @for_type_repr +| @impl_trait_type_repr +| @infer_type_repr +| @macro_type_repr +| @never_type_repr +| @paren_type_repr +| @path_type_repr +| @ptr_type_repr +| @ref_type_repr +| @slice_type_repr +| @tuple_type_repr +; + +@use_bound_generic_arg = + @lifetime +| @name_ref +; + +use_bound_generic_args( + unique int id: @use_bound_generic_args +); + +#keyset[id, index] +use_bound_generic_args_use_bound_generic_args( + int id: @use_bound_generic_args ref, + int index: int ref, + int use_bound_generic_arg: @use_bound_generic_arg ref +); + +use_trees( + unique int id: @use_tree +); + +#keyset[id] +use_tree_is_glob( + int id: @use_tree ref +); + +#keyset[id] +use_tree_paths( + int id: @use_tree ref, + int path: @path ref +); + +#keyset[id] +use_tree_renames( + int id: @use_tree ref, + int rename: @rename ref +); + +#keyset[id] +use_tree_use_tree_lists( + int id: @use_tree ref, + int use_tree_list: @use_tree_list ref +); + +use_tree_lists( + unique int id: @use_tree_list +); + +#keyset[id, index] +use_tree_list_use_trees( + int id: @use_tree_list ref, + int index: int ref, + int use_tree: @use_tree ref +); + +variant_lists( + unique int id: @variant_list +); + +#keyset[id, index] +variant_list_variants( + int id: @variant_list ref, + int index: int ref, + int variant: @variant ref +); + +visibilities( + unique int id: @visibility +); + +#keyset[id] +visibility_paths( + int id: @visibility ref, + int path: @path ref +); + +where_clauses( + unique int id: @where_clause +); + +#keyset[id, index] +where_clause_predicates( + int id: @where_clause ref, + int index: int ref, + int predicate: @where_pred ref +); + +where_preds( + unique int id: @where_pred +); + +#keyset[id] +where_pred_for_binders( + int id: @where_pred ref, + int for_binder: @for_binder ref +); + +#keyset[id] +where_pred_lifetimes( + int id: @where_pred ref, + int lifetime: @lifetime ref +); + +#keyset[id] +where_pred_type_reprs( + int id: @where_pred ref, + int type_repr: @type_repr ref +); + +#keyset[id] +where_pred_type_bound_lists( + int id: @where_pred ref, + int type_bound_list: @type_bound_list ref +); + +array_expr_internals( + unique int id: @array_expr_internal +); + +#keyset[id, index] +array_expr_internal_attrs( + int id: @array_expr_internal ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id, index] +array_expr_internal_exprs( + int id: @array_expr_internal ref, + int index: int ref, + int expr: @expr ref +); + +#keyset[id] +array_expr_internal_is_semicolon( + int id: @array_expr_internal ref +); + +array_type_reprs( + unique int id: @array_type_repr +); + +#keyset[id] +array_type_repr_const_args( + int id: @array_type_repr ref, + int const_arg: @const_arg ref +); + +#keyset[id] +array_type_repr_element_type_reprs( + int id: @array_type_repr ref, + int element_type_repr: @type_repr ref +); + +asm_clobber_abis( + unique int id: @asm_clobber_abi +); + +asm_consts( + unique int id: @asm_const +); + +#keyset[id] +asm_const_exprs( + int id: @asm_const ref, + int expr: @expr ref +); + +#keyset[id] +asm_const_is_const( + int id: @asm_const ref +); + +asm_labels( + unique int id: @asm_label +); + +#keyset[id] +asm_label_block_exprs( + int id: @asm_label ref, + int block_expr: @block_expr ref +); + +asm_operand_nameds( + unique int id: @asm_operand_named +); + +#keyset[id] +asm_operand_named_asm_operands( + int id: @asm_operand_named ref, + int asm_operand: @asm_operand ref +); + +#keyset[id] +asm_operand_named_names( + int id: @asm_operand_named ref, + int name: @name ref +); + +asm_options_lists( + unique int id: @asm_options_list +); + +#keyset[id, index] +asm_options_list_asm_options( + int id: @asm_options_list ref, + int index: int ref, + int asm_option: @asm_option ref +); + +asm_reg_operands( + unique int id: @asm_reg_operand +); + +#keyset[id] +asm_reg_operand_asm_dir_specs( + int id: @asm_reg_operand ref, + int asm_dir_spec: @asm_dir_spec ref +); + +#keyset[id] +asm_reg_operand_asm_operand_exprs( + int id: @asm_reg_operand ref, + int asm_operand_expr: @asm_operand_expr ref +); + +#keyset[id] +asm_reg_operand_asm_reg_specs( + int id: @asm_reg_operand ref, + int asm_reg_spec: @asm_reg_spec ref +); + +asm_syms( + unique int id: @asm_sym +); + +#keyset[id] +asm_sym_paths( + int id: @asm_sym ref, + int path: @path ref +); + +assoc_type_args( + unique int id: @assoc_type_arg +); + +#keyset[id] +assoc_type_arg_const_args( + int id: @assoc_type_arg ref, + int const_arg: @const_arg ref +); + +#keyset[id] +assoc_type_arg_generic_arg_lists( + int id: @assoc_type_arg ref, + int generic_arg_list: @generic_arg_list ref +); + +#keyset[id] +assoc_type_arg_identifiers( + int id: @assoc_type_arg ref, + int identifier: @name_ref ref +); + +#keyset[id] +assoc_type_arg_param_lists( + int id: @assoc_type_arg ref, + int param_list: @param_list ref +); + +#keyset[id] +assoc_type_arg_ret_types( + int id: @assoc_type_arg ref, + int ret_type: @ret_type_repr ref +); + +#keyset[id] +assoc_type_arg_return_type_syntaxes( + int id: @assoc_type_arg ref, + int return_type_syntax: @return_type_syntax ref +); + +#keyset[id] +assoc_type_arg_type_reprs( + int id: @assoc_type_arg ref, + int type_repr: @type_repr ref +); + +#keyset[id] +assoc_type_arg_type_bound_lists( + int id: @assoc_type_arg ref, + int type_bound_list: @type_bound_list ref +); + +await_exprs( + unique int id: @await_expr +); + +#keyset[id, index] +await_expr_attrs( + int id: @await_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +await_expr_exprs( + int id: @await_expr ref, + int expr: @expr ref +); + +become_exprs( + unique int id: @become_expr +); + +#keyset[id, index] +become_expr_attrs( + int id: @become_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +become_expr_exprs( + int id: @become_expr ref, + int expr: @expr ref +); + +binary_exprs( + unique int id: @binary_expr +); + +#keyset[id, index] +binary_expr_attrs( + int id: @binary_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +binary_expr_lhs( + int id: @binary_expr ref, + int lhs: @expr ref +); + +#keyset[id] +binary_expr_operator_names( + int id: @binary_expr ref, + string operator_name: string ref +); + +#keyset[id] +binary_expr_rhs( + int id: @binary_expr ref, + int rhs: @expr ref +); + +box_pats( + unique int id: @box_pat +); + +#keyset[id] +box_pat_pats( + int id: @box_pat ref, + int pat: @pat ref +); + +break_exprs( + unique int id: @break_expr +); + +#keyset[id, index] +break_expr_attrs( + int id: @break_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +break_expr_exprs( + int id: @break_expr ref, + int expr: @expr ref +); + +#keyset[id] +break_expr_lifetimes( + int id: @break_expr ref, + int lifetime: @lifetime ref +); + +@call_expr_base = + @call_expr +| @method_call_expr +; + +#keyset[id] +call_expr_base_arg_lists( + int id: @call_expr_base ref, + int arg_list: @arg_list ref +); + +#keyset[id, index] +call_expr_base_attrs( + int id: @call_expr_base ref, + int index: int ref, + int attr: @attr ref +); + +cast_exprs( + unique int id: @cast_expr +); + +#keyset[id, index] +cast_expr_attrs( + int id: @cast_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +cast_expr_exprs( + int id: @cast_expr ref, + int expr: @expr ref +); + +#keyset[id] +cast_expr_type_reprs( + int id: @cast_expr ref, + int type_repr: @type_repr ref +); + +closure_exprs( + unique int id: @closure_expr +); + +#keyset[id] +closure_expr_closure_bodies( + int id: @closure_expr ref, + int closure_body: @expr ref +); + +#keyset[id] +closure_expr_for_binders( + int id: @closure_expr ref, + int for_binder: @for_binder ref +); + +#keyset[id] +closure_expr_is_async( + int id: @closure_expr ref +); + +#keyset[id] +closure_expr_is_const( + int id: @closure_expr ref +); + +#keyset[id] +closure_expr_is_gen( + int id: @closure_expr ref +); + +#keyset[id] +closure_expr_is_move( + int id: @closure_expr ref +); + +#keyset[id] +closure_expr_is_static( + int id: @closure_expr ref +); + +#keyset[id] +closure_expr_ret_types( + int id: @closure_expr ref, + int ret_type: @ret_type_repr ref +); + +comments( + unique int id: @comment, + int parent: @ast_node ref, + string text: string ref +); + +const_args( + unique int id: @const_arg +); + +#keyset[id] +const_arg_exprs( + int id: @const_arg ref, + int expr: @expr ref +); + +const_block_pats( + unique int id: @const_block_pat +); + +#keyset[id] +const_block_pat_block_exprs( + int id: @const_block_pat ref, + int block_expr: @block_expr ref +); + +#keyset[id] +const_block_pat_is_const( + int id: @const_block_pat ref +); + +const_params( + unique int id: @const_param +); + +#keyset[id, index] +const_param_attrs( + int id: @const_param ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +const_param_default_vals( + int id: @const_param ref, + int default_val: @const_arg ref +); + +#keyset[id] +const_param_is_const( + int id: @const_param ref +); + +#keyset[id] +const_param_names( + int id: @const_param ref, + int name: @name ref +); + +#keyset[id] +const_param_type_reprs( + int id: @const_param ref, + int type_repr: @type_repr ref +); + +continue_exprs( + unique int id: @continue_expr +); + +#keyset[id, index] +continue_expr_attrs( + int id: @continue_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +continue_expr_lifetimes( + int id: @continue_expr ref, + int lifetime: @lifetime ref +); + +dyn_trait_type_reprs( + unique int id: @dyn_trait_type_repr +); + +#keyset[id] +dyn_trait_type_repr_type_bound_lists( + int id: @dyn_trait_type_repr ref, + int type_bound_list: @type_bound_list ref +); + +expr_stmts( + unique int id: @expr_stmt +); + +#keyset[id] +expr_stmt_exprs( + int id: @expr_stmt ref, + int expr: @expr ref +); + +field_exprs( + unique int id: @field_expr +); + +#keyset[id, index] +field_expr_attrs( + int id: @field_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +field_expr_containers( + int id: @field_expr ref, + int container: @expr ref +); + +#keyset[id] +field_expr_identifiers( + int id: @field_expr ref, + int identifier: @name_ref ref +); + +fn_ptr_type_reprs( + unique int id: @fn_ptr_type_repr +); + +#keyset[id] +fn_ptr_type_repr_abis( + int id: @fn_ptr_type_repr ref, + int abi: @abi ref +); + +#keyset[id] +fn_ptr_type_repr_is_async( + int id: @fn_ptr_type_repr ref +); + +#keyset[id] +fn_ptr_type_repr_is_const( + int id: @fn_ptr_type_repr ref +); + +#keyset[id] +fn_ptr_type_repr_is_unsafe( + int id: @fn_ptr_type_repr ref +); + +#keyset[id] +fn_ptr_type_repr_param_lists( + int id: @fn_ptr_type_repr ref, + int param_list: @param_list ref +); + +#keyset[id] +fn_ptr_type_repr_ret_types( + int id: @fn_ptr_type_repr ref, + int ret_type: @ret_type_repr ref +); + +for_type_reprs( + unique int id: @for_type_repr +); + +#keyset[id] +for_type_repr_for_binders( + int id: @for_type_repr ref, + int for_binder: @for_binder ref +); + +#keyset[id] +for_type_repr_type_reprs( + int id: @for_type_repr ref, + int type_repr: @type_repr ref +); + +format_args_exprs( + unique int id: @format_args_expr +); + +#keyset[id, index] +format_args_expr_args( + int id: @format_args_expr ref, + int index: int ref, + int arg: @format_args_arg ref +); + +#keyset[id, index] +format_args_expr_attrs( + int id: @format_args_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +format_args_expr_templates( + int id: @format_args_expr ref, + int template: @expr ref +); + +ident_pats( + unique int id: @ident_pat +); + +#keyset[id, index] +ident_pat_attrs( + int id: @ident_pat ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +ident_pat_is_mut( + int id: @ident_pat ref +); + +#keyset[id] +ident_pat_is_ref( + int id: @ident_pat ref +); + +#keyset[id] +ident_pat_names( + int id: @ident_pat ref, + int name: @name ref +); + +#keyset[id] +ident_pat_pats( + int id: @ident_pat ref, + int pat: @pat ref +); + +if_exprs( + unique int id: @if_expr +); + +#keyset[id, index] +if_expr_attrs( + int id: @if_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +if_expr_conditions( + int id: @if_expr ref, + int condition: @expr ref +); + +#keyset[id] +if_expr_elses( + int id: @if_expr ref, + int else: @expr ref +); + +#keyset[id] +if_expr_thens( + int id: @if_expr ref, + int then: @block_expr ref +); + +impl_trait_type_reprs( + unique int id: @impl_trait_type_repr +); + +#keyset[id] +impl_trait_type_repr_type_bound_lists( + int id: @impl_trait_type_repr ref, + int type_bound_list: @type_bound_list ref +); + +index_exprs( + unique int id: @index_expr +); + +#keyset[id, index] +index_expr_attrs( + int id: @index_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +index_expr_bases( + int id: @index_expr ref, + int base: @expr ref +); + +#keyset[id] +index_expr_indices( + int id: @index_expr ref, + int index: @expr ref +); + +infer_type_reprs( + unique int id: @infer_type_repr +); + +@item = + @adt +| @asm_expr +| @assoc_item +| @extern_block +| @extern_crate +| @extern_item +| @impl +| @macro_def +| @macro_rules +| @module +| @trait +| @trait_alias +| @use +; + +#keyset[id] +item_attribute_macro_expansions( + int id: @item ref, + int attribute_macro_expansion: @macro_items ref +); + +@labelable_expr = + @block_expr +| @looping_expr +; + +#keyset[id] +labelable_expr_labels( + int id: @labelable_expr ref, + int label: @label ref +); + +let_exprs( + unique int id: @let_expr +); + +#keyset[id, index] +let_expr_attrs( + int id: @let_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +let_expr_scrutinees( + int id: @let_expr ref, + int scrutinee: @expr ref +); + +#keyset[id] +let_expr_pats( + int id: @let_expr ref, + int pat: @pat ref +); + +let_stmts( + unique int id: @let_stmt +); + +#keyset[id, index] +let_stmt_attrs( + int id: @let_stmt ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +let_stmt_initializers( + int id: @let_stmt ref, + int initializer: @expr ref +); + +#keyset[id] +let_stmt_let_elses( + int id: @let_stmt ref, + int let_else: @let_else ref +); + +#keyset[id] +let_stmt_pats( + int id: @let_stmt ref, + int pat: @pat ref +); + +#keyset[id] +let_stmt_type_reprs( + int id: @let_stmt ref, + int type_repr: @type_repr ref +); + +lifetimes( + unique int id: @lifetime +); + +#keyset[id] +lifetime_texts( + int id: @lifetime ref, + string text: string ref +); + +lifetime_args( + unique int id: @lifetime_arg +); + +#keyset[id] +lifetime_arg_lifetimes( + int id: @lifetime_arg ref, + int lifetime: @lifetime ref +); + +lifetime_params( + unique int id: @lifetime_param +); + +#keyset[id, index] +lifetime_param_attrs( + int id: @lifetime_param ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +lifetime_param_lifetimes( + int id: @lifetime_param ref, + int lifetime: @lifetime ref +); + +#keyset[id] +lifetime_param_type_bound_lists( + int id: @lifetime_param ref, + int type_bound_list: @type_bound_list ref +); + +literal_exprs( + unique int id: @literal_expr +); + +#keyset[id, index] +literal_expr_attrs( + int id: @literal_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +literal_expr_text_values( + int id: @literal_expr ref, + string text_value: string ref +); + +literal_pats( + unique int id: @literal_pat +); + +#keyset[id] +literal_pat_literals( + int id: @literal_pat ref, + int literal: @literal_expr ref +); + +macro_block_exprs( + unique int id: @macro_block_expr +); + +#keyset[id, index] +macro_block_expr_statements( + int id: @macro_block_expr ref, + int index: int ref, + int statement: @stmt ref +); + +#keyset[id] +macro_block_expr_tail_exprs( + int id: @macro_block_expr ref, + int tail_expr: @expr ref +); + +macro_exprs( + unique int id: @macro_expr +); + +#keyset[id] +macro_expr_macro_calls( + int id: @macro_expr ref, + int macro_call: @macro_call ref +); + +macro_pats( + unique int id: @macro_pat +); + +#keyset[id] +macro_pat_macro_calls( + int id: @macro_pat ref, + int macro_call: @macro_call ref +); + +macro_type_reprs( + unique int id: @macro_type_repr +); + +#keyset[id] +macro_type_repr_macro_calls( + int id: @macro_type_repr ref, + int macro_call: @macro_call ref +); + +match_exprs( + unique int id: @match_expr +); + +#keyset[id, index] +match_expr_attrs( + int id: @match_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +match_expr_scrutinees( + int id: @match_expr ref, + int scrutinee: @expr ref +); + +#keyset[id] +match_expr_match_arm_lists( + int id: @match_expr ref, + int match_arm_list: @match_arm_list ref +); + +name_refs( + unique int id: @name_ref +); + +#keyset[id] +name_ref_texts( + int id: @name_ref ref, + string text: string ref +); + +never_type_reprs( + unique int id: @never_type_repr +); + +offset_of_exprs( + unique int id: @offset_of_expr +); + +#keyset[id, index] +offset_of_expr_attrs( + int id: @offset_of_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id, index] +offset_of_expr_fields( + int id: @offset_of_expr ref, + int index: int ref, + int field: @name_ref ref +); + +#keyset[id] +offset_of_expr_type_reprs( + int id: @offset_of_expr ref, + int type_repr: @type_repr ref +); + +or_pats( + unique int id: @or_pat +); + +#keyset[id, index] +or_pat_pats( + int id: @or_pat ref, + int index: int ref, + int pat: @pat ref +); + +params( + unique int id: @param +); + +#keyset[id] +param_pats( + int id: @param ref, + int pat: @pat ref +); + +paren_exprs( + unique int id: @paren_expr +); + +#keyset[id, index] +paren_expr_attrs( + int id: @paren_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +paren_expr_exprs( + int id: @paren_expr ref, + int expr: @expr ref +); + +paren_pats( + unique int id: @paren_pat +); + +#keyset[id] +paren_pat_pats( + int id: @paren_pat ref, + int pat: @pat ref +); + +paren_type_reprs( + unique int id: @paren_type_repr +); + +#keyset[id] +paren_type_repr_type_reprs( + int id: @paren_type_repr ref, + int type_repr: @type_repr ref +); + +@path_expr_base = + @path_expr +; + +path_pats( + unique int id: @path_pat +); + +path_type_reprs( + unique int id: @path_type_repr +); + +#keyset[id] +path_type_repr_paths( + int id: @path_type_repr ref, + int path: @path ref +); + +prefix_exprs( + unique int id: @prefix_expr +); + +#keyset[id, index] +prefix_expr_attrs( + int id: @prefix_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +prefix_expr_exprs( + int id: @prefix_expr ref, + int expr: @expr ref +); + +#keyset[id] +prefix_expr_operator_names( + int id: @prefix_expr ref, + string operator_name: string ref +); + +ptr_type_reprs( + unique int id: @ptr_type_repr +); + +#keyset[id] +ptr_type_repr_is_const( + int id: @ptr_type_repr ref +); + +#keyset[id] +ptr_type_repr_is_mut( + int id: @ptr_type_repr ref +); + +#keyset[id] +ptr_type_repr_type_reprs( + int id: @ptr_type_repr ref, + int type_repr: @type_repr ref +); + +range_exprs( + unique int id: @range_expr +); + +#keyset[id, index] +range_expr_attrs( + int id: @range_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +range_expr_ends( + int id: @range_expr ref, + int end: @expr ref +); + +#keyset[id] +range_expr_operator_names( + int id: @range_expr ref, + string operator_name: string ref +); + +#keyset[id] +range_expr_starts( + int id: @range_expr ref, + int start: @expr ref +); + +range_pats( + unique int id: @range_pat +); + +#keyset[id] +range_pat_ends( + int id: @range_pat ref, + int end: @pat ref +); + +#keyset[id] +range_pat_operator_names( + int id: @range_pat ref, + string operator_name: string ref +); + +#keyset[id] +range_pat_starts( + int id: @range_pat ref, + int start: @pat ref +); + +ref_exprs( + unique int id: @ref_expr +); + +#keyset[id, index] +ref_expr_attrs( + int id: @ref_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +ref_expr_exprs( + int id: @ref_expr ref, + int expr: @expr ref +); + +#keyset[id] +ref_expr_is_const( + int id: @ref_expr ref +); + +#keyset[id] +ref_expr_is_mut( + int id: @ref_expr ref +); + +#keyset[id] +ref_expr_is_raw( + int id: @ref_expr ref +); + +ref_pats( + unique int id: @ref_pat +); + +#keyset[id] +ref_pat_is_mut( + int id: @ref_pat ref +); + +#keyset[id] +ref_pat_pats( + int id: @ref_pat ref, + int pat: @pat ref +); + +ref_type_reprs( + unique int id: @ref_type_repr +); + +#keyset[id] +ref_type_repr_is_mut( + int id: @ref_type_repr ref +); + +#keyset[id] +ref_type_repr_lifetimes( + int id: @ref_type_repr ref, + int lifetime: @lifetime ref +); + +#keyset[id] +ref_type_repr_type_reprs( + int id: @ref_type_repr ref, + int type_repr: @type_repr ref +); + +rest_pats( + unique int id: @rest_pat +); + +#keyset[id, index] +rest_pat_attrs( + int id: @rest_pat ref, + int index: int ref, + int attr: @attr ref +); + +return_exprs( + unique int id: @return_expr +); + +#keyset[id, index] +return_expr_attrs( + int id: @return_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +return_expr_exprs( + int id: @return_expr ref, + int expr: @expr ref +); + +self_params( + unique int id: @self_param +); + +#keyset[id] +self_param_is_ref( + int id: @self_param ref +); + +#keyset[id] +self_param_is_mut( + int id: @self_param ref +); + +#keyset[id] +self_param_lifetimes( + int id: @self_param ref, + int lifetime: @lifetime ref +); + +#keyset[id] +self_param_names( + int id: @self_param ref, + int name: @name ref +); + +slice_pats( + unique int id: @slice_pat +); + +#keyset[id, index] +slice_pat_pats( + int id: @slice_pat ref, + int index: int ref, + int pat: @pat ref +); + +slice_type_reprs( + unique int id: @slice_type_repr +); + +#keyset[id] +slice_type_repr_type_reprs( + int id: @slice_type_repr ref, + int type_repr: @type_repr ref +); + +struct_exprs( + unique int id: @struct_expr +); + +#keyset[id] +struct_expr_struct_expr_field_lists( + int id: @struct_expr ref, + int struct_expr_field_list: @struct_expr_field_list ref +); + +struct_field_lists( + unique int id: @struct_field_list +); + +#keyset[id, index] +struct_field_list_fields( + int id: @struct_field_list ref, + int index: int ref, + int field: @struct_field ref +); + +struct_pats( + unique int id: @struct_pat +); + +#keyset[id] +struct_pat_struct_pat_field_lists( + int id: @struct_pat ref, + int struct_pat_field_list: @struct_pat_field_list ref +); + +try_exprs( + unique int id: @try_expr +); + +#keyset[id, index] +try_expr_attrs( + int id: @try_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +try_expr_exprs( + int id: @try_expr ref, + int expr: @expr ref +); + +tuple_exprs( + unique int id: @tuple_expr +); + +#keyset[id, index] +tuple_expr_attrs( + int id: @tuple_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id, index] +tuple_expr_fields( + int id: @tuple_expr ref, + int index: int ref, + int field: @expr ref +); + +tuple_field_lists( + unique int id: @tuple_field_list +); + +#keyset[id, index] +tuple_field_list_fields( + int id: @tuple_field_list ref, + int index: int ref, + int field: @tuple_field ref +); + +tuple_pats( + unique int id: @tuple_pat +); + +#keyset[id, index] +tuple_pat_fields( + int id: @tuple_pat ref, + int index: int ref, + int field: @pat ref +); + +tuple_struct_pats( + unique int id: @tuple_struct_pat +); + +#keyset[id, index] +tuple_struct_pat_fields( + int id: @tuple_struct_pat ref, + int index: int ref, + int field: @pat ref +); + +tuple_type_reprs( + unique int id: @tuple_type_repr +); + +#keyset[id, index] +tuple_type_repr_fields( + int id: @tuple_type_repr ref, + int index: int ref, + int field: @type_repr ref +); + +type_args( + unique int id: @type_arg +); + +#keyset[id] +type_arg_type_reprs( + int id: @type_arg ref, + int type_repr: @type_repr ref +); + +type_params( + unique int id: @type_param +); + +#keyset[id, index] +type_param_attrs( + int id: @type_param ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +type_param_default_types( + int id: @type_param ref, + int default_type: @type_repr ref +); + +#keyset[id] +type_param_names( + int id: @type_param ref, + int name: @name ref +); + +#keyset[id] +type_param_type_bound_lists( + int id: @type_param ref, + int type_bound_list: @type_bound_list ref +); + +underscore_exprs( + unique int id: @underscore_expr +); + +#keyset[id, index] +underscore_expr_attrs( + int id: @underscore_expr ref, + int index: int ref, + int attr: @attr ref +); + +variants( + unique int id: @variant +); + +#keyset[id, index] +variant_attrs( + int id: @variant ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +variant_discriminants( + int id: @variant ref, + int discriminant: @expr ref +); + +#keyset[id] +variant_field_lists( + int id: @variant ref, + int field_list: @field_list ref +); + +#keyset[id] +variant_names( + int id: @variant ref, + int name: @name ref +); + +#keyset[id] +variant_visibilities( + int id: @variant ref, + int visibility: @visibility ref +); + +wildcard_pats( + unique int id: @wildcard_pat +); + +yeet_exprs( + unique int id: @yeet_expr +); + +#keyset[id, index] +yeet_expr_attrs( + int id: @yeet_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +yeet_expr_exprs( + int id: @yeet_expr ref, + int expr: @expr ref +); + +yield_exprs( + unique int id: @yield_expr +); + +#keyset[id, index] +yield_expr_attrs( + int id: @yield_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +yield_expr_exprs( + int id: @yield_expr ref, + int expr: @expr ref +); + +@adt = + @enum +| @struct +| @union +; + +#keyset[id, index] +adt_derive_macro_expansions( + int id: @adt ref, + int index: int ref, + int derive_macro_expansion: @macro_items ref +); + +asm_exprs( + unique int id: @asm_expr +); + +#keyset[id, index] +asm_expr_asm_pieces( + int id: @asm_expr ref, + int index: int ref, + int asm_piece: @asm_piece ref +); + +#keyset[id, index] +asm_expr_attrs( + int id: @asm_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id, index] +asm_expr_templates( + int id: @asm_expr ref, + int index: int ref, + int template: @expr ref +); + +@assoc_item = + @const +| @function +| @macro_call +| @type_alias +; + +block_exprs( + unique int id: @block_expr +); + +#keyset[id, index] +block_expr_attrs( + int id: @block_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +block_expr_is_async( + int id: @block_expr ref +); + +#keyset[id] +block_expr_is_const( + int id: @block_expr ref +); + +#keyset[id] +block_expr_is_gen( + int id: @block_expr ref +); + +#keyset[id] +block_expr_is_move( + int id: @block_expr ref +); + +#keyset[id] +block_expr_is_try( + int id: @block_expr ref +); + +#keyset[id] +block_expr_is_unsafe( + int id: @block_expr ref +); + +#keyset[id] +block_expr_stmt_lists( + int id: @block_expr ref, + int stmt_list: @stmt_list ref +); + +call_exprs( + unique int id: @call_expr +); + +#keyset[id] +call_expr_functions( + int id: @call_expr ref, + int function: @expr ref +); + +extern_blocks( + unique int id: @extern_block +); + +#keyset[id] +extern_block_abis( + int id: @extern_block ref, + int abi: @abi ref +); + +#keyset[id, index] +extern_block_attrs( + int id: @extern_block ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +extern_block_extern_item_lists( + int id: @extern_block ref, + int extern_item_list: @extern_item_list ref +); + +#keyset[id] +extern_block_is_unsafe( + int id: @extern_block ref +); + +extern_crates( + unique int id: @extern_crate +); + +#keyset[id, index] +extern_crate_attrs( + int id: @extern_crate ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +extern_crate_identifiers( + int id: @extern_crate ref, + int identifier: @name_ref ref +); + +#keyset[id] +extern_crate_renames( + int id: @extern_crate ref, + int rename: @rename ref +); + +#keyset[id] +extern_crate_visibilities( + int id: @extern_crate ref, + int visibility: @visibility ref +); + +@extern_item = + @function +| @macro_call +| @static +| @type_alias +; + +impls( + unique int id: @impl +); + +#keyset[id] +impl_assoc_item_lists( + int id: @impl ref, + int assoc_item_list: @assoc_item_list ref +); + +#keyset[id, index] +impl_attrs( + int id: @impl ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +impl_generic_param_lists( + int id: @impl ref, + int generic_param_list: @generic_param_list ref +); + +#keyset[id] +impl_is_const( + int id: @impl ref +); + +#keyset[id] +impl_is_default( + int id: @impl ref +); + +#keyset[id] +impl_is_unsafe( + int id: @impl ref +); + +#keyset[id] +impl_self_ties( + int id: @impl ref, + int self_ty: @type_repr ref +); + +#keyset[id] +impl_traits( + int id: @impl ref, + int trait: @type_repr ref +); + +#keyset[id] +impl_visibilities( + int id: @impl ref, + int visibility: @visibility ref +); + +#keyset[id] +impl_where_clauses( + int id: @impl ref, + int where_clause: @where_clause ref +); + +@looping_expr = + @for_expr +| @loop_expr +| @while_expr +; + +#keyset[id] +looping_expr_loop_bodies( + int id: @looping_expr ref, + int loop_body: @block_expr ref +); + +macro_defs( + unique int id: @macro_def +); + +#keyset[id] +macro_def_args( + int id: @macro_def ref, + int args: @token_tree ref +); + +#keyset[id, index] +macro_def_attrs( + int id: @macro_def ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +macro_def_bodies( + int id: @macro_def ref, + int body: @token_tree ref +); + +#keyset[id] +macro_def_names( + int id: @macro_def ref, + int name: @name ref +); + +#keyset[id] +macro_def_visibilities( + int id: @macro_def ref, + int visibility: @visibility ref +); + +macro_rules( + unique int id: @macro_rules +); + +#keyset[id, index] +macro_rules_attrs( + int id: @macro_rules ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +macro_rules_names( + int id: @macro_rules ref, + int name: @name ref +); + +#keyset[id] +macro_rules_token_trees( + int id: @macro_rules ref, + int token_tree: @token_tree ref +); + +#keyset[id] +macro_rules_visibilities( + int id: @macro_rules ref, + int visibility: @visibility ref +); + +method_call_exprs( + unique int id: @method_call_expr +); + +#keyset[id] +method_call_expr_generic_arg_lists( + int id: @method_call_expr ref, + int generic_arg_list: @generic_arg_list ref +); + +#keyset[id] +method_call_expr_identifiers( + int id: @method_call_expr ref, + int identifier: @name_ref ref +); + +#keyset[id] +method_call_expr_receivers( + int id: @method_call_expr ref, + int receiver: @expr ref +); + +modules( + unique int id: @module +); + +#keyset[id, index] +module_attrs( + int id: @module ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +module_item_lists( + int id: @module ref, + int item_list: @item_list ref +); + +#keyset[id] +module_names( + int id: @module ref, + int name: @name ref +); + +#keyset[id] +module_visibilities( + int id: @module ref, + int visibility: @visibility ref +); + +path_exprs( + unique int id: @path_expr +); + +#keyset[id, index] +path_expr_attrs( + int id: @path_expr ref, + int index: int ref, + int attr: @attr ref +); + +traits( + unique int id: @trait +); + +#keyset[id] +trait_assoc_item_lists( + int id: @trait ref, + int assoc_item_list: @assoc_item_list ref +); + +#keyset[id, index] +trait_attrs( + int id: @trait ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +trait_generic_param_lists( + int id: @trait ref, + int generic_param_list: @generic_param_list ref +); + +#keyset[id] +trait_is_auto( + int id: @trait ref +); + +#keyset[id] +trait_is_unsafe( + int id: @trait ref +); + +#keyset[id] +trait_names( + int id: @trait ref, + int name: @name ref +); + +#keyset[id] +trait_type_bound_lists( + int id: @trait ref, + int type_bound_list: @type_bound_list ref +); + +#keyset[id] +trait_visibilities( + int id: @trait ref, + int visibility: @visibility ref +); + +#keyset[id] +trait_where_clauses( + int id: @trait ref, + int where_clause: @where_clause ref +); + +trait_aliases( + unique int id: @trait_alias +); + +#keyset[id, index] +trait_alias_attrs( + int id: @trait_alias ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +trait_alias_generic_param_lists( + int id: @trait_alias ref, + int generic_param_list: @generic_param_list ref +); + +#keyset[id] +trait_alias_names( + int id: @trait_alias ref, + int name: @name ref +); + +#keyset[id] +trait_alias_type_bound_lists( + int id: @trait_alias ref, + int type_bound_list: @type_bound_list ref +); + +#keyset[id] +trait_alias_visibilities( + int id: @trait_alias ref, + int visibility: @visibility ref +); + +#keyset[id] +trait_alias_where_clauses( + int id: @trait_alias ref, + int where_clause: @where_clause ref +); + +uses( + unique int id: @use +); + +#keyset[id, index] +use_attrs( + int id: @use ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +use_use_trees( + int id: @use ref, + int use_tree: @use_tree ref +); + +#keyset[id] +use_visibilities( + int id: @use ref, + int visibility: @visibility ref +); + +consts( + unique int id: @const +); + +#keyset[id, index] +const_attrs( + int id: @const ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +const_bodies( + int id: @const ref, + int body: @expr ref +); + +#keyset[id] +const_generic_param_lists( + int id: @const ref, + int generic_param_list: @generic_param_list ref +); + +#keyset[id] +const_is_const( + int id: @const ref +); + +#keyset[id] +const_is_default( + int id: @const ref +); + +#keyset[id] +const_names( + int id: @const ref, + int name: @name ref +); + +#keyset[id] +const_type_reprs( + int id: @const ref, + int type_repr: @type_repr ref +); + +#keyset[id] +const_visibilities( + int id: @const ref, + int visibility: @visibility ref +); + +#keyset[id] +const_where_clauses( + int id: @const ref, + int where_clause: @where_clause ref +); + +#keyset[id] +const_has_implementation( + int id: @const ref +); + +enums( + unique int id: @enum +); + +#keyset[id, index] +enum_attrs( + int id: @enum ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +enum_generic_param_lists( + int id: @enum ref, + int generic_param_list: @generic_param_list ref +); + +#keyset[id] +enum_names( + int id: @enum ref, + int name: @name ref +); + +#keyset[id] +enum_variant_lists( + int id: @enum ref, + int variant_list: @variant_list ref +); + +#keyset[id] +enum_visibilities( + int id: @enum ref, + int visibility: @visibility ref +); + +#keyset[id] +enum_where_clauses( + int id: @enum ref, + int where_clause: @where_clause ref +); + +for_exprs( + unique int id: @for_expr +); + +#keyset[id, index] +for_expr_attrs( + int id: @for_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +for_expr_iterables( + int id: @for_expr ref, + int iterable: @expr ref +); + +#keyset[id] +for_expr_pats( + int id: @for_expr ref, + int pat: @pat ref +); + +functions( + unique int id: @function +); + +#keyset[id] +function_abis( + int id: @function ref, + int abi: @abi ref +); + +#keyset[id] +function_function_bodies( + int id: @function ref, + int function_body: @block_expr ref +); + +#keyset[id] +function_generic_param_lists( + int id: @function ref, + int generic_param_list: @generic_param_list ref +); + +#keyset[id] +function_is_async( + int id: @function ref +); + +#keyset[id] +function_is_const( + int id: @function ref +); + +#keyset[id] +function_is_default( + int id: @function ref +); + +#keyset[id] +function_is_gen( + int id: @function ref +); + +#keyset[id] +function_is_unsafe( + int id: @function ref +); + +#keyset[id] +function_names( + int id: @function ref, + int name: @name ref +); + +#keyset[id] +function_ret_types( + int id: @function ref, + int ret_type: @ret_type_repr ref +); + +#keyset[id] +function_visibilities( + int id: @function ref, + int visibility: @visibility ref +); + +#keyset[id] +function_where_clauses( + int id: @function ref, + int where_clause: @where_clause ref +); + +#keyset[id] +function_has_implementation( + int id: @function ref +); + +loop_exprs( + unique int id: @loop_expr +); + +#keyset[id, index] +loop_expr_attrs( + int id: @loop_expr ref, + int index: int ref, + int attr: @attr ref +); + +macro_calls( + unique int id: @macro_call +); + +#keyset[id, index] +macro_call_attrs( + int id: @macro_call ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +macro_call_paths( + int id: @macro_call ref, + int path: @path ref +); + +#keyset[id] +macro_call_token_trees( + int id: @macro_call ref, + int token_tree: @token_tree ref +); + +#keyset[id] +macro_call_macro_call_expansions( + int id: @macro_call ref, + int macro_call_expansion: @ast_node ref +); + +statics( + unique int id: @static +); + +#keyset[id, index] +static_attrs( + int id: @static ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +static_bodies( + int id: @static ref, + int body: @expr ref +); + +#keyset[id] +static_is_mut( + int id: @static ref +); + +#keyset[id] +static_is_static( + int id: @static ref +); + +#keyset[id] +static_is_unsafe( + int id: @static ref +); + +#keyset[id] +static_names( + int id: @static ref, + int name: @name ref +); + +#keyset[id] +static_type_reprs( + int id: @static ref, + int type_repr: @type_repr ref +); + +#keyset[id] +static_visibilities( + int id: @static ref, + int visibility: @visibility ref +); + +structs( + unique int id: @struct +); + +#keyset[id, index] +struct_attrs( + int id: @struct ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +struct_field_lists_( + int id: @struct ref, + int field_list: @field_list ref +); + +#keyset[id] +struct_generic_param_lists( + int id: @struct ref, + int generic_param_list: @generic_param_list ref +); + +#keyset[id] +struct_names( + int id: @struct ref, + int name: @name ref +); + +#keyset[id] +struct_visibilities( + int id: @struct ref, + int visibility: @visibility ref +); + +#keyset[id] +struct_where_clauses( + int id: @struct ref, + int where_clause: @where_clause ref +); + +type_aliases( + unique int id: @type_alias +); + +#keyset[id, index] +type_alias_attrs( + int id: @type_alias ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +type_alias_generic_param_lists( + int id: @type_alias ref, + int generic_param_list: @generic_param_list ref +); + +#keyset[id] +type_alias_is_default( + int id: @type_alias ref +); + +#keyset[id] +type_alias_names( + int id: @type_alias ref, + int name: @name ref +); + +#keyset[id] +type_alias_type_reprs( + int id: @type_alias ref, + int type_repr: @type_repr ref +); + +#keyset[id] +type_alias_type_bound_lists( + int id: @type_alias ref, + int type_bound_list: @type_bound_list ref +); + +#keyset[id] +type_alias_visibilities( + int id: @type_alias ref, + int visibility: @visibility ref +); + +#keyset[id] +type_alias_where_clauses( + int id: @type_alias ref, + int where_clause: @where_clause ref +); + +unions( + unique int id: @union +); + +#keyset[id, index] +union_attrs( + int id: @union ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +union_generic_param_lists( + int id: @union ref, + int generic_param_list: @generic_param_list ref +); + +#keyset[id] +union_names( + int id: @union ref, + int name: @name ref +); + +#keyset[id] +union_struct_field_lists( + int id: @union ref, + int struct_field_list: @struct_field_list ref +); + +#keyset[id] +union_visibilities( + int id: @union ref, + int visibility: @visibility ref +); + +#keyset[id] +union_where_clauses( + int id: @union ref, + int where_clause: @where_clause ref +); + +while_exprs( + unique int id: @while_expr +); + +#keyset[id, index] +while_expr_attrs( + int id: @while_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +while_expr_conditions( + int id: @while_expr ref, + int condition: @expr ref +); diff --git a/rust/downgrades/e54d01f67a416b3d6eb7b970f27295097f2cac7f/upgrade.properties b/rust/downgrades/e54d01f67a416b3d6eb7b970f27295097f2cac7f/upgrade.properties new file mode 100644 index 00000000000..d753a48ad74 --- /dev/null +++ b/rust/downgrades/e54d01f67a416b3d6eb7b970f27295097f2cac7f/upgrade.properties @@ -0,0 +1,10 @@ +description: Added the `@call_expr_base` union type +compatibility: backwards + +call_expr_arg_lists.rel: delete +call_expr_attrs.rel: delete +method_call_expr_arg_lists.rel: delete +method_call_expr_attrs.rel: delete + +call_expr_base_arg_lists.rel: run upgrade.ql call_expr_base_arg_lists +call_expr_base_attrs.rel: run upgrade.ql call_expr_base_attrs \ No newline at end of file diff --git a/rust/downgrades/e54d01f67a416b3d6eb7b970f27295097f2cac7f/upgrade.ql b/rust/downgrades/e54d01f67a416b3d6eb7b970f27295097f2cac7f/upgrade.ql new file mode 100644 index 00000000000..0ebeae26038 --- /dev/null +++ b/rust/downgrades/e54d01f67a416b3d6eb7b970f27295097f2cac7f/upgrade.ql @@ -0,0 +1,19 @@ +class Element extends @element { + string toString() { none() } +} + +class ArgList extends Element, @arg_list { } + +class Attr extends Element, @attr { } + +query predicate call_expr_base_arg_lists(Element c, ArgList l) { + call_expr_base_arg_lists(c, l) + or + method_call_expr_arg_lists(c, l) +} + +query predicate call_expr_base_attrs(Element c, int i, Attr a) { + call_expr_attrs(c, i, a) + or + method_call_expr_attrs(c, i, a) +} diff --git a/rust/extractor/src/generated/.generated.list b/rust/extractor/src/generated/.generated.list index fa35ec65d4c..578b21fc992 100644 --- a/rust/extractor/src/generated/.generated.list +++ b/rust/extractor/src/generated/.generated.list @@ -1,2 +1,2 @@ mod.rs 4bcb9def847469aae9d8649461546b7c21ec97cf6e63d3cf394e339915ce65d7 4bcb9def847469aae9d8649461546b7c21ec97cf6e63d3cf394e339915ce65d7 -top.rs 460e827738766301a137f1750be7cd3016e6b7e4e487c6c95972bd3e1d21b814 460e827738766301a137f1750be7cd3016e6b7e4e487c6c95972bd3e1d21b814 +top.rs b829c8ab9ec5ff07b997b9ee0b2c333d63e24eddcf7c5fc2b95a9a7f17a84a69 b829c8ab9ec5ff07b997b9ee0b2c333d63e24eddcf7c5fc2b95a9a7f17a84a69 diff --git a/rust/extractor/src/generated/top.rs b/rust/extractor/src/generated/top.rs index 3c4b51c78e6..510f6579d40 100644 --- a/rust/extractor/src/generated/top.rs +++ b/rust/extractor/src/generated/top.rs @@ -4315,44 +4315,66 @@ impl From> for trap::Label { } #[derive(Debug)] -pub struct CallExprBase { - _unused: () +pub struct CallExpr { + pub id: trap::TrapId, + pub arg_list: Option>, + pub attrs: Vec>, + pub function: Option>, } -impl trap::TrapClass for CallExprBase { - fn class_name() -> &'static str { "CallExprBase" } +impl trap::TrapEntry for CallExpr { + fn extract_id(&mut self) -> trap::TrapId { + std::mem::replace(&mut self.id, trap::TrapId::Star) + } + + fn emit(self, id: trap::Label, out: &mut trap::Writer) { + out.add_tuple("call_exprs", vec![id.into()]); + if let Some(v) = self.arg_list { + out.add_tuple("call_expr_arg_lists", vec![id.into(), v.into()]); + } + for (i, v) in self.attrs.into_iter().enumerate() { + out.add_tuple("call_expr_attrs", vec![id.into(), i.into(), v.into()]); + } + if let Some(v) = self.function { + out.add_tuple("call_expr_functions", vec![id.into(), v.into()]); + } + } } -impl From> for trap::Label { - fn from(value: trap::Label) -> Self { - // SAFETY: this is safe because in the dbscheme CallExprBase is a subclass of Expr +impl trap::TrapClass for CallExpr { + fn class_name() -> &'static str { "CallExpr" } +} + +impl From> for trap::Label { + fn from(value: trap::Label) -> Self { + // SAFETY: this is safe because in the dbscheme CallExpr is a subclass of Expr unsafe { Self::from_untyped(value.as_untyped()) } } } -impl From> for trap::Label { - fn from(value: trap::Label) -> Self { - // SAFETY: this is safe because in the dbscheme CallExprBase is a subclass of AstNode +impl From> for trap::Label { + fn from(value: trap::Label) -> Self { + // SAFETY: this is safe because in the dbscheme CallExpr is a subclass of AstNode unsafe { Self::from_untyped(value.as_untyped()) } } } -impl From> for trap::Label { - fn from(value: trap::Label) -> Self { - // SAFETY: this is safe because in the dbscheme CallExprBase is a subclass of Locatable +impl From> for trap::Label { + fn from(value: trap::Label) -> Self { + // SAFETY: this is safe because in the dbscheme CallExpr is a subclass of Locatable unsafe { Self::from_untyped(value.as_untyped()) } } } -impl From> for trap::Label { - fn from(value: trap::Label) -> Self { - // SAFETY: this is safe because in the dbscheme CallExprBase is a subclass of Element +impl From> for trap::Label { + fn from(value: trap::Label) -> Self { + // SAFETY: this is safe because in the dbscheme CallExpr is a subclass of Element unsafe { Self::from_untyped(value.as_untyped()) } @@ -6430,6 +6452,81 @@ impl From> for trap::Label { } } +#[derive(Debug)] +pub struct MethodCallExpr { + pub id: trap::TrapId, + pub arg_list: Option>, + pub attrs: Vec>, + pub generic_arg_list: Option>, + pub identifier: Option>, + pub receiver: Option>, +} + +impl trap::TrapEntry for MethodCallExpr { + fn extract_id(&mut self) -> trap::TrapId { + std::mem::replace(&mut self.id, trap::TrapId::Star) + } + + fn emit(self, id: trap::Label, out: &mut trap::Writer) { + out.add_tuple("method_call_exprs", vec![id.into()]); + if let Some(v) = self.arg_list { + out.add_tuple("method_call_expr_arg_lists", vec![id.into(), v.into()]); + } + for (i, v) in self.attrs.into_iter().enumerate() { + out.add_tuple("method_call_expr_attrs", vec![id.into(), i.into(), v.into()]); + } + if let Some(v) = self.generic_arg_list { + out.add_tuple("method_call_expr_generic_arg_lists", vec![id.into(), v.into()]); + } + if let Some(v) = self.identifier { + out.add_tuple("method_call_expr_identifiers", vec![id.into(), v.into()]); + } + if let Some(v) = self.receiver { + out.add_tuple("method_call_expr_receivers", vec![id.into(), v.into()]); + } + } +} + +impl trap::TrapClass for MethodCallExpr { + fn class_name() -> &'static str { "MethodCallExpr" } +} + +impl From> for trap::Label { + fn from(value: trap::Label) -> Self { + // SAFETY: this is safe because in the dbscheme MethodCallExpr is a subclass of Expr + unsafe { + Self::from_untyped(value.as_untyped()) + } + } +} + +impl From> for trap::Label { + fn from(value: trap::Label) -> Self { + // SAFETY: this is safe because in the dbscheme MethodCallExpr is a subclass of AstNode + unsafe { + Self::from_untyped(value.as_untyped()) + } + } +} + +impl From> for trap::Label { + fn from(value: trap::Label) -> Self { + // SAFETY: this is safe because in the dbscheme MethodCallExpr is a subclass of Locatable + unsafe { + Self::from_untyped(value.as_untyped()) + } + } +} + +impl From> for trap::Label { + fn from(value: trap::Label) -> Self { + // SAFETY: this is safe because in the dbscheme MethodCallExpr is a subclass of Element + unsafe { + Self::from_untyped(value.as_untyped()) + } + } +} + #[derive(Debug)] pub struct NameRef { pub id: trap::TrapId, @@ -9242,82 +9339,6 @@ impl From> for trap::Label { } } -#[derive(Debug)] -pub struct CallExpr { - pub id: trap::TrapId, - pub arg_list: Option>, - pub attrs: Vec>, - pub function: Option>, -} - -impl trap::TrapEntry for CallExpr { - fn extract_id(&mut self) -> trap::TrapId { - std::mem::replace(&mut self.id, trap::TrapId::Star) - } - - fn emit(self, id: trap::Label, out: &mut trap::Writer) { - out.add_tuple("call_exprs", vec![id.into()]); - if let Some(v) = self.arg_list { - out.add_tuple("call_expr_base_arg_lists", vec![id.into(), v.into()]); - } - for (i, v) in self.attrs.into_iter().enumerate() { - out.add_tuple("call_expr_base_attrs", vec![id.into(), i.into(), v.into()]); - } - if let Some(v) = self.function { - out.add_tuple("call_expr_functions", vec![id.into(), v.into()]); - } - } -} - -impl trap::TrapClass for CallExpr { - fn class_name() -> &'static str { "CallExpr" } -} - -impl From> for trap::Label { - fn from(value: trap::Label) -> Self { - // SAFETY: this is safe because in the dbscheme CallExpr is a subclass of CallExprBase - unsafe { - Self::from_untyped(value.as_untyped()) - } - } -} - -impl From> for trap::Label { - fn from(value: trap::Label) -> Self { - // SAFETY: this is safe because in the dbscheme CallExpr is a subclass of Expr - unsafe { - Self::from_untyped(value.as_untyped()) - } - } -} - -impl From> for trap::Label { - fn from(value: trap::Label) -> Self { - // SAFETY: this is safe because in the dbscheme CallExpr is a subclass of AstNode - unsafe { - Self::from_untyped(value.as_untyped()) - } - } -} - -impl From> for trap::Label { - fn from(value: trap::Label) -> Self { - // SAFETY: this is safe because in the dbscheme CallExpr is a subclass of Locatable - unsafe { - Self::from_untyped(value.as_untyped()) - } - } -} - -impl From> for trap::Label { - fn from(value: trap::Label) -> Self { - // SAFETY: this is safe because in the dbscheme CallExpr is a subclass of Element - unsafe { - Self::from_untyped(value.as_untyped()) - } - } -} - #[derive(Debug)] pub struct ExternBlock { pub id: trap::TrapId, @@ -9908,90 +9929,6 @@ impl From> for trap::Label { } } -#[derive(Debug)] -pub struct MethodCallExpr { - pub id: trap::TrapId, - pub arg_list: Option>, - pub attrs: Vec>, - pub generic_arg_list: Option>, - pub identifier: Option>, - pub receiver: Option>, -} - -impl trap::TrapEntry for MethodCallExpr { - fn extract_id(&mut self) -> trap::TrapId { - std::mem::replace(&mut self.id, trap::TrapId::Star) - } - - fn emit(self, id: trap::Label, out: &mut trap::Writer) { - out.add_tuple("method_call_exprs", vec![id.into()]); - if let Some(v) = self.arg_list { - out.add_tuple("call_expr_base_arg_lists", vec![id.into(), v.into()]); - } - for (i, v) in self.attrs.into_iter().enumerate() { - out.add_tuple("call_expr_base_attrs", vec![id.into(), i.into(), v.into()]); - } - if let Some(v) = self.generic_arg_list { - out.add_tuple("method_call_expr_generic_arg_lists", vec![id.into(), v.into()]); - } - if let Some(v) = self.identifier { - out.add_tuple("method_call_expr_identifiers", vec![id.into(), v.into()]); - } - if let Some(v) = self.receiver { - out.add_tuple("method_call_expr_receivers", vec![id.into(), v.into()]); - } - } -} - -impl trap::TrapClass for MethodCallExpr { - fn class_name() -> &'static str { "MethodCallExpr" } -} - -impl From> for trap::Label { - fn from(value: trap::Label) -> Self { - // SAFETY: this is safe because in the dbscheme MethodCallExpr is a subclass of CallExprBase - unsafe { - Self::from_untyped(value.as_untyped()) - } - } -} - -impl From> for trap::Label { - fn from(value: trap::Label) -> Self { - // SAFETY: this is safe because in the dbscheme MethodCallExpr is a subclass of Expr - unsafe { - Self::from_untyped(value.as_untyped()) - } - } -} - -impl From> for trap::Label { - fn from(value: trap::Label) -> Self { - // SAFETY: this is safe because in the dbscheme MethodCallExpr is a subclass of AstNode - unsafe { - Self::from_untyped(value.as_untyped()) - } - } -} - -impl From> for trap::Label { - fn from(value: trap::Label) -> Self { - // SAFETY: this is safe because in the dbscheme MethodCallExpr is a subclass of Locatable - unsafe { - Self::from_untyped(value.as_untyped()) - } - } -} - -impl From> for trap::Label { - fn from(value: trap::Label) -> Self { - // SAFETY: this is safe because in the dbscheme MethodCallExpr is a subclass of Element - unsafe { - Self::from_untyped(value.as_untyped()) - } - } -} - #[derive(Debug)] pub struct Module { pub id: trap::TrapId, diff --git a/rust/ql/.generated.list b/rust/ql/.generated.list index 98cd6b01af4..7def99275cf 100644 --- a/rust/ql/.generated.list +++ b/rust/ql/.generated.list @@ -1,4 +1,4 @@ -lib/codeql/rust/controlflow/internal/generated/CfgNodes.qll 11c7521ec2231a4d0447f30fc3d0bb14aebb659bd8cf75935af1050673a3b1d6 d0a77b572a032e43f1c47622315c0cdfe17e68c2b057534b9322fc528029fb40 +lib/codeql/rust/controlflow/internal/generated/CfgNodes.qll 1eac5a95247dec5cf51a453788b5bdebcf612590014b1e28f6b6f7e841c96a20 d4d8c9664ca406c3fd14d96a488eea97c42401e2791f41d7248ee5d3f299805c lib/codeql/rust/elements/Abi.qll 485a2e79f6f7bfd1c02a6e795a71e62dede3c3e150149d5f8f18b761253b7208 6159ba175e7ead0dd2e3f2788f49516c306ee11b1a443bd4bdc00b7017d559bd lib/codeql/rust/elements/Addressable.qll 13011bfd2e1556694c3d440cc34af8527da4df49ad92b62f2939d3699ff2cea5 ddb25935f7553a1a384b1abe2e4b4fa90ab50b952dadec32fd867afcb054f4be lib/codeql/rust/elements/Adt.qll c2afed4ac2e17039ccd98f74ea22111f4d765c4e232c50ccd3128da0d26da837 1380bde2eb667c6ec2ef5f8710aa24e926851c9e321ebc72ba514fa92c369dc3 @@ -32,8 +32,7 @@ lib/codeql/rust/elements/BinaryExpr.qll 394522da3bc3a716fc7bc40c3560143ca840f5d2 lib/codeql/rust/elements/BlockExpr.qll b5cf57119b15f27d0bc258dfa375b0ef2730c157870ff543f0dc7a8cfe514182 f6a01999606b010c81ef9c6ff1385e6640632b6f5ce067ffeb0ef0af0a0aeb92 lib/codeql/rust/elements/BoxPat.qll 1b2c3fff171aa6aa238c9460b122f26c79e04577cea67fa856de99842ba873d4 0caf8d23ed6e0997a6b8751def27641582151fba6e24fccf798712a4690b42f1 lib/codeql/rust/elements/BreakExpr.qll 7ca3807a20e9a9a988d1fd7abebf240325ed422fcb45c719ba46272f031f94db dffb7379d3f3ba220acfbd05eb7bb6cfd9cfda211e9c8b1f5240ca5fa61be3fc -lib/codeql/rust/elements/CallExpr.qll f336500ca7a611b164d48b90e80edb0c0d3816792b0ececce659ac1ff1ffeb3e f99a9c55466418ef53860c44d9f2d6161af4b492178ddd9e5870dff742b70ae5 -lib/codeql/rust/elements/CallExprBase.qll 2846202b5208b541977500286951d96487bf555838c6c16cdd006a71e383745a c789d412bf099c624329379e0c7d94fa0d23ae2edea7a25a2ea0f3c0042ccf62 +lib/codeql/rust/elements/CallExpr.qll ee3997f265dc1b6b2fc7134548dd88d509b6bcbc26cf65061a31980f9900ae26 7e86e0ab24ce78c3f592a5614eac083d00f331664f021a438f74e2e0785f4609 lib/codeql/rust/elements/Callable.qll 08a46e987b8fde29069795a536fcd1ad1a96f60341f72293e4d07e20334d554f cfc2be9287000718e5ff3c2a35bb45ffc93fd36d97f2e034888e9aa2ae9af555 lib/codeql/rust/elements/CastExpr.qll 2fe1f36ba31fa29de309baf0a665cfcae67b61c73345e8f9bbd41e8c235fec45 c5b4c1e9dc24eb2357799defcb2df25989075e3a80e8663b74204a1c1b70e29a lib/codeql/rust/elements/ClosureExpr.qll 69e0b7a7c7a4c348fcada5ad4da22dd2f51747109f856be239cede315a56d695 93400650282e2d4e682b826e9f5f844aa893dda126548e41ea1c703d2bf209ca @@ -103,7 +102,7 @@ lib/codeql/rust/elements/MatchArmList.qll f221c5e344814fa44db06ab897afdc249e8e88 lib/codeql/rust/elements/MatchExpr.qll e9ef1664f020823b6f4bb72d906a9dc0c1ee6432d4a9a13f7dbdbab2b2b1ee4d 38d71e5c487abcb5682293c573343be66e499a6e131bb630604c120d34b7777b lib/codeql/rust/elements/MatchGuard.qll 58256689a90f24b16401543452c2a32f00d619ddac6c0fe8b65a8cd3e46401bb 8efb2ac03c69a9db687e382331085d7a6cfbf8eca559174ba2727a9549ec7ddd lib/codeql/rust/elements/Meta.qll b17d7bf605bd0cf4f6d6c6cf4f39a16cfc431d256d45b93663a7569181d36168 815cdfef06231de4b4b1c85e321b8ccb3e22379e5a4e111df9cc9ca6be593841 -lib/codeql/rust/elements/MethodCallExpr.qll 91b411e0fb1a0547dcad8726db460dccc61bed972741598d5cb3740593fe75a7 538d23b6db115bb699389d29a1829bb0449c08424a1fff80377828eb7ceb2563 +lib/codeql/rust/elements/MethodCallExpr.qll 914633f304c587addced988a7f161a1a4b3297ce370f6a959b7a042b1c04dace 289a0854d6323df915ee5f268523ee597ba20a37c646bbb2a79c9ed1f7aa2260 lib/codeql/rust/elements/Missing.qll 70e6ac9790314752849c9888443c98223ccfc93a193998b7ce350b2c6ebe8ea4 e2f0623511acaa76b091f748d417714137a8b94f1f2bdbbd177f1c682c786dad lib/codeql/rust/elements/Module.qll 0bc85019177709256f8078d9de2a36f62f848d476225bff7bba1e35f249875c7 3fbb70e0c417a644dd0cada2c364c6e6876cfa16f37960e219c87e49c966c94e lib/codeql/rust/elements/Name.qll af41479d4260fe931d46154dda15484e4733c952b98f0e370106e6e9e8ce398b e188a0d0309dd1b684c0cb88df435b38e306eb94d6b66a2b748e75252f15e095 @@ -160,8 +159,8 @@ lib/codeql/rust/elements/Trait.qll f78a917c2f2e5a0dfcd7c36e95ad67b1fa218484ee509 lib/codeql/rust/elements/TraitAlias.qll 1d82d043f24dbac04baa7aa3882c6884b8ffbc5d9b97669ce8efb7e2c8d3d2c8 505ba5426e87b3c49721f440fbc9ad6b0e7d89d1b1a51ca3fa3a6cc2d36f8b82 lib/codeql/rust/elements/TryExpr.qll cb452f53292a1396139f64a35f05bb11501f6b363f8affc9f2d5f1945ad4a647 d60ad731bfe256d0f0b688bdc31708759a3d990c11dee4f1d85ccc0d9e07bec9 lib/codeql/rust/elements/TupleExpr.qll 1b1be270198f9d3db1c28c4caaa4a7fe9b5ae14651f1a10e2891a7d78d6ad18b 4f585aa684dfbff753e342903ddd60ee4d7c374b8bddeb645784d10903c90ae0 -lib/codeql/rust/elements/TupleField.qll e20a991f7f1322cc7c05b2a8946d5017edb119812efa3e44daa94a5dff2d0c7b 8c25c9577fef8b5b9a4b285ceb7cfffcd8d89448035b1967cd7fda1503adfe13 -lib/codeql/rust/elements/TupleFieldList.qll b67cd2dec918d09e582467e5db7a38c8fa18350af591b43a1b450cd2026dbb67 22fdd1e77c16e3be4627ee7a45985b94785492d36056eeeff2c94b43450b48c8 +lib/codeql/rust/elements/TupleField.qll 8d6288fd79959d5ef3732397c0a05a47fcb09091383058d1dba7268a950f8c32 1518cdd0fd9746d09fcdbecabc2a3ce6b36b6d983883850beed3f55c2bdf2c16 +lib/codeql/rust/elements/TupleFieldList.qll 2fa47599f78aa4639a40239cf49bc2f97d84118125b949c71fec4390589caaf0 3f71a86e38bdc6fe9f0c082a43d763c4f34b4bdab99c383cdc5d8b59e887cee0 lib/codeql/rust/elements/TuplePat.qll 028cdea43868b0fdd2fc4c31ff25b6bbb40813e8aaccf72186051a280db7632e 38c56187971671e6a9dd0c6ccccb2ee4470aa82852110c6b89884496eb4abc64 lib/codeql/rust/elements/TupleStructPat.qll da398a23eb616bf7dd586b2a87f4ab00f28623418f081cd7b1cc3de497ef1819 6573bf3f8501c30af3aeb23d96db9f5bea7ab73e2b7ef3473095c03e96c20a5c lib/codeql/rust/elements/TupleTypeRepr.qll 1ac5abf6281ea31680a4098407fbe55459d08f92a50dec20d1f8b93d498eee41 6d9625cce4e4abf6b6e6c22e47880fbd23740d07b621137bd7fa0a2ee13badd9 @@ -406,7 +405,7 @@ lib/codeql/rust/elements/internal/TupleExprConstructor.qll 71c38786723225d3d9039 lib/codeql/rust/elements/internal/TupleExprImpl.qll daabbc7dd36c615cdd8d3b59e06f4992a302b26554115711f733508836887abe 4c43a26e5f8b68d9d032bb5cd0af88cf9ac9b4b4e40af47dc85dd931ce9db6f8 lib/codeql/rust/elements/internal/TupleFieldConstructor.qll 89d3cf2540235044ed5a89706cfbdebc5cdf9180fd5b6d3376c79a1b2c0430c0 16861fe089aac8e42a5a90d81dd48d5015391d0a06c78ca02bd876d65378699f lib/codeql/rust/elements/internal/TupleFieldListConstructor.qll 4335ba2061b6e4968db9ec05c0b4d3e6a564db89a2df69e036f317672a7900b1 0b8dded875dbf696cf588e8c21acc27332a2ff66ced7bfabdfc1ad621991f888 -lib/codeql/rust/elements/internal/TupleFieldListImpl.qll 74869e92a3cbdd7895adaaa418d29d5e97387daf46c17315f219ad967af15d76 5815e4b37db958663df1f6fedc9667a11b261c9c2133e3f983a3aedc452c01fc +lib/codeql/rust/elements/internal/TupleFieldListImpl.qll 2e5141d5894d1cebadef9cd3afe7585779327c4e24390201e1ef05a29401caf8 bbfa1e0b513393012bf2ae43a3aa0e33fce6ea4d110d1be0f039562071f3c547 lib/codeql/rust/elements/internal/TuplePatConstructor.qll 2a5e83ad5b8713a732e610128aeddf14e9b344402d6cf30ff0b43aa39e838418 6d467f7141307523994f03ed7b8e8b1a5bcf860963c9934b90e54582ea38096a lib/codeql/rust/elements/internal/TupleStructPatConstructor.qll 9d68f67a17a5cec0e78907a53eccfa7696be5b0571da4b486c8184274e56344a 3ffa29f546cd6c644be4fecc7415477a3a4dc00d69b8764be9119abe4c6d8b9e lib/codeql/rust/elements/internal/TupleTypeReprConstructor.qll 80c31c25fd27e330690fb500d757a4bbd33f226186d88ea73bfe4cf29a7db508 d572a72fa361990a3d0a3f9b81d1e966e2ba1ac0a60314ec824c1b8b2814c857 @@ -478,8 +477,7 @@ lib/codeql/rust/elements/internal/generated/BinaryExpr.qll 64e9bd9c571edd6e5f3e7 lib/codeql/rust/elements/internal/generated/BlockExpr.qll 5a5ddbe34bc478a7bd9b0d07d3b6f017c2d1f20581d859251a963314e6514d1f 9804c30b8b279038b864c52557535f854bd012bacdfe8e5840f1f777c74e52df lib/codeql/rust/elements/internal/generated/BoxPat.qll 597bed52f7489e0addce3266f7bee5be7c53d2d1263eceec3a252d041ca0908f b8ccf363ca5f1a988547caf1fd266a55aec7cbf8623578deea99765d264b0151 lib/codeql/rust/elements/internal/generated/BreakExpr.qll 0f428a8b2f4209b134c2ffc3e1c93c30bc6b0e9c9172f140cefa88c1f77d8690 957b39f38ff6befe9061f55bc0b403c2f1c366dd0cf63b874bae6f8216576d76 -lib/codeql/rust/elements/internal/generated/CallExpr.qll f1b8dae487077cc9d1dccf8c3cd61fd17afe860585f17ce8b860be4859be7ca4 6034fc03778e38802cdf3a6e460364b74e92912622581b31e6179951022bbbd6 -lib/codeql/rust/elements/internal/generated/CallExprBase.qll 2268e01d65015014c05166161bb28e5a1e78164d525ca16fc1e3106866cf231d b2f9b912153ba4d3e3612df4f74ac0e83077c31d5b31383bd277974081417a56 +lib/codeql/rust/elements/internal/generated/CallExpr.qll 6096035ba2ef1ce3e6254d5b8497dcb6cd7570253423c778a9dd7e158f928644 e56caf9ba094ddfc4952ed5072c5f6f139db8029fa6bd6328d1a118e96a1d5fe lib/codeql/rust/elements/internal/generated/Callable.qll 12368b998c771c6b80f54123cea4d3600af7432ab34c9e571bc0bf3894ceb17e 273a9fd9cdae56cf2edbdc9c49b15da49cd5ad04be70acbbe2475c9c50200183 lib/codeql/rust/elements/internal/generated/CastExpr.qll ddc20054b0b339ad4d40298f3461490d25d00af87c876da5ffbc6a11c0832295 f4247307afcd74d80e926f29f8c57e78c50800984483e6b6003a44681e4a71f3 lib/codeql/rust/elements/internal/generated/ClosureExpr.qll 818aff75d86821c670d8ba0720c3270681b3e070140a9c41beab2a811b43eee6 9bf2d1d38f6c4a99d7c058f8ed096141f5ba6a75d2d26a464f0d65ed4e554222 @@ -550,7 +548,7 @@ lib/codeql/rust/elements/internal/generated/MatchArmList.qll 12d969ecb267a749918 lib/codeql/rust/elements/internal/generated/MatchExpr.qll b686842e7000fd61e3a0598bf245fb4e18167b99eca9162fdfdff0b0963def22 00f1743b1b0f1a92c5a687f5260fda02d80cc5871694cad0d5e7d94bac7fe977 lib/codeql/rust/elements/internal/generated/MatchGuard.qll 58fa1d6979ef22de2bd68574c7ffcf4a021d7543445f68834d879ff8cee3abcb 072f22a7929df3c0e764b2a770b4cdf03504b3053067d9b9008d6655fb5837e1 lib/codeql/rust/elements/internal/generated/Meta.qll 15e98e8d38f5618b7053057a629b135aae5e105fbf72731833a644fb695244c0 2977b6a0781c89383e87c595b14a39851f27b2508296f3e77466eea44c916188 -lib/codeql/rust/elements/internal/generated/MethodCallExpr.qll 0cd0f84147e5f3887d609cc58246eb493d3461aee00ff37e7d26282c835f73af 6f4c5dc1decbce54fc12300d34798b890a85129208b25565130205c9d8ee2e29 +lib/codeql/rust/elements/internal/generated/MethodCallExpr.qll ffce98a6a1921822b12ead721cff0878553eb3e049c5d2184a7abce32b6615b4 d1408a0f47ee5764fe7b484494daf6e1f99b1c6a505274c48545b3e650ef8baf lib/codeql/rust/elements/internal/generated/Missing.qll 16735d91df04a4e1ae52fae25db5f59a044e540755734bbab46b5fbb0fe6b0bd 28ca4e49fb7e6b4734be2f2f69e7c224c570344cc160ef80c5a5cd413e750dad lib/codeql/rust/elements/internal/generated/Module.qll ebae5d8963c9fd569c0fbad1d7770abd3fd2479437f236cbce0505ba9f9af52c fa3c382115fed18a26f1a755d8749a201b9489f82c09448a88fb8e9e1435fe5f lib/codeql/rust/elements/internal/generated/Name.qll e6bd6240a051383a52b21ab539bc204ce7bcd51a1a4379e497dff008d4eef5b4 578a3b45e70f519d57b3e3a3450f6272716c849940daee49889717c7aaa85fc9 @@ -565,7 +563,7 @@ lib/codeql/rust/elements/internal/generated/ParamList.qll eaa0cd4402d3665013d47e lib/codeql/rust/elements/internal/generated/ParenExpr.qll 812d2ff65079277f39f15c084657a955a960a7c1c0e96dd60472a58d56b945eb eb8c607f43e1fcbb41f37a10de203a1db806690e10ff4f04d48ed874189cb0eb lib/codeql/rust/elements/internal/generated/ParenPat.qll 24f9dc7fce75827d6fddb856cd48f80168143151b27295c0bab6db5a06567a09 ebadbc6f5498e9ed754b39893ce0763840409a0721036a25b56e1ead7dcc09aa lib/codeql/rust/elements/internal/generated/ParenTypeRepr.qll 03f5c5b96a37adeb845352d7fcea3e098da9050e534972d14ac0f70d60a2d776 ed3d6e5d02086523087adebce4e89e35461eb95f2a66d1d4100fe23fc691b126 -lib/codeql/rust/elements/internal/generated/ParentChild.qll f04ca3d02170f7e532a480cc81748cf04f1b022d5e0e32ffcdf0f15c8f1961aa 999104d69a5435c9cab594e04b82ed26ae38b1b1d2ac1dbbb315a433c586f941 +lib/codeql/rust/elements/internal/generated/ParentChild.qll 8a6e4335bcf6f7d72f5ed6ffba5448ae88b00323fe7dac6f406c8746c03ef2dc 867a0fb166b53d7a8218a02d671f117ba7ea4e67cb16abeea6e746dc5823b85e lib/codeql/rust/elements/internal/generated/ParenthesizedArgList.qll d901fdc8142a5b8847cc98fc2afcfd16428b8ace4fbffb457e761b5fd3901a77 5dbb0aea5a13f937da666ccb042494af8f11e776ade1459d16b70a4dd193f9fb lib/codeql/rust/elements/internal/generated/Pat.qll 3605ac062be2f294ee73336e9669027b8b655f4ad55660e1eab35266275154ee 7f9400db2884d336dd1d21df2a8093759c2a110be9bf6482ce8e80ae0fd74ed4 lib/codeql/rust/elements/internal/generated/Path.qll 9b12afb46fc5a9ad3a811b05472621bbecccb900c47504feb7f29d96b28421ca bcacbffc36fb3e0c9b26523b5963af0ffa9fd6b19f00a2a31bdb2316071546bd @@ -580,7 +578,7 @@ lib/codeql/rust/elements/internal/generated/PtrTypeRepr.qll 8d0ea4f6c7f8203340bf lib/codeql/rust/elements/internal/generated/PureSynthConstructors.qll e5b8e69519012bbaae29dcb82d53f7f7ecce368c0358ec27ef6180b228a0057f e5b8e69519012bbaae29dcb82d53f7f7ecce368c0358ec27ef6180b228a0057f lib/codeql/rust/elements/internal/generated/RangeExpr.qll 23cca03bf43535f33b22a38894f70d669787be4e4f5b8fe5c8f7b964d30e9027 18624cef6c6b679eeace2a98737e472432e0ead354cca02192b4d45330f047c9 lib/codeql/rust/elements/internal/generated/RangePat.qll 80826a6a6868a803aa2372e31c52a03e1811a3f1f2abdb469f91ca0bfdd9ecb6 34ee1e208c1690cba505dff2c588837c0cd91e185e2a87d1fe673191962276a9 -lib/codeql/rust/elements/internal/generated/Raw.qll 14758dc2e2a9af251f24e24516eab0fc95d334c1da06f418ea5da3c5521642c9 a8b6637f57293a85714cc8761f8fd1e23780d58f3873acaa3c77acd9cbfcf19f +lib/codeql/rust/elements/internal/generated/Raw.qll f207067167f8597ddf6de483372fc9e281d1661d3fc0a5da0d6d6bd7e32aa9c7 1c27c65c3ab4d07553bbd269c6737576feca3f5c29c8b02f81a0d65c209d4621 lib/codeql/rust/elements/internal/generated/RefExpr.qll 7d995884e3dc1c25fc719f5d7253179344d63650e217e9ff6530285fe7a57f64 f2c3c12551deea4964b66553fb9b6423ee16fec53bd63db4796191aa60dc6c66 lib/codeql/rust/elements/internal/generated/RefPat.qll 456ede39837463ee22a630ec7ab6c8630d3664a8ea206fcc6e4f199e92fa564c 5622062765f32930465ba6b170e986706f159f6070f48adee3c20e24e8df4e05 lib/codeql/rust/elements/internal/generated/RefTypeRepr.qll 5b0663a6d234572fb3e467e276d019415caa95ef006438cc59b7af4e1783161e 0e27c8a8f0e323c0e4d6db01fca821bf07c0864d293cdf96fa891b10820c1e4b @@ -605,7 +603,7 @@ lib/codeql/rust/elements/internal/generated/StructFieldList.qll 5da528a51a6a5db9 lib/codeql/rust/elements/internal/generated/StructPat.qll c76fa005c2fd0448a8803233e1e8818c4123301eb66ac5cf69d0b9eaafc61e98 6e0dffccdce24bca20e87d5ba0f0995c9a1ae8983283e71e7dbfcf6fffc67a58 lib/codeql/rust/elements/internal/generated/StructPatField.qll 5b5c7302dbc4a902ca8e69ff31875c867e295a16a626ba3cef29cd0aa248f179 4e192a0df79947f5cb0d47fdbbba7986137a6a40a1be92ae119873e2fad67edf lib/codeql/rust/elements/internal/generated/StructPatFieldList.qll 1a95a1bd9f64fb18e9571657cf2d02a8b13c747048a1f0f74baf31b91f0392ad fc274e414ff4ed54386046505920de92755ad0b4d39a7523cdffa4830bd53b37 -lib/codeql/rust/elements/internal/generated/Synth.qll a8ea364358a2bc3a9226d451c0867e89c29509a0f54dd88ed23c77045db2c85a a44de5e84a63cb5a1bfa66b0df33bf28c9f8b6628393d0f3b2f6215dabee47bd +lib/codeql/rust/elements/internal/generated/Synth.qll 61147c264e863dc5234b391ad2b7a01e0a2fe99e18ea237ba06e31340fd0a50a 6d33624a9b571d05aba1e9459a211f75b762e72fa716259abcd994f5098e15a6 lib/codeql/rust/elements/internal/generated/SynthConstructors.qll f41abfc73415b7accb38da7c107faebfe6843c270ad54e0e54a96e930dfe479a f41abfc73415b7accb38da7c107faebfe6843c270ad54e0e54a96e930dfe479a lib/codeql/rust/elements/internal/generated/Token.qll 77a91a25ca5669703cf3a4353b591cef4d72caa6b0b9db07bb9e005d69c848d1 2fdffc4882ed3a6ca9ac6d1fb5f1ac5a471ca703e2ffdc642885fa558d6e373b lib/codeql/rust/elements/internal/generated/TokenTree.qll 1a3c4f5f30659738641abdd28cb793dab3cfde484196b59656fc0a2767e53511 de2ebb210c7759ef7a6f7ee9f805e1cac879221287281775fc80ba34a5492edf @@ -613,8 +611,8 @@ lib/codeql/rust/elements/internal/generated/Trait.qll 8fa41b50fa0f68333534f2b66b lib/codeql/rust/elements/internal/generated/TraitAlias.qll 40a296cf89eceaf02a32db90acb42bdc90df10e717bae3ab95bc09d842360a5b af85cf1f8fa46a8b04b763cdcacc6643b83c074c58c1344e485157d2ceb26306 lib/codeql/rust/elements/internal/generated/TryExpr.qll 73052d7d309427a30019ad962ee332d22e7e48b9cc98ee60261ca2df2f433f93 d9dd70bf69eaa22475acd78bea504341e3574742a51ad9118566f39038a02d85 lib/codeql/rust/elements/internal/generated/TupleExpr.qll 98f10bc72d09f98e3be87f41b1a3cbf037f4a7e3d3560dfa6d5759905a8177a5 6a9eb5568c518876b2912371e2b7b774cf5245097c5a0206eda35b749995f00b -lib/codeql/rust/elements/internal/generated/TupleField.qll d546b4e0c1a0b243c2bf88b371377cf9a396ca497cd5e78915e0e552910b6093 c0a754d15e0de590ee15139d8d366e4d7e4d33882c943e6ea8fa5fa8dce790e3 -lib/codeql/rust/elements/internal/generated/TupleFieldList.qll fb76d1a395326361859177c05e90e5bbb22d37518758752e9d89906006fb683e f31508b120c36f569cc7dcae06c9e55cf875abfb2fbe54a64ec12d8b3d2db108 +lib/codeql/rust/elements/internal/generated/TupleField.qll 121f7b35e28b86592f83e00993f9041acbe7ab636db894d03055149c7f15fd32 b1ba9e1182307a44bb5afc11e92d62e7eb2c819ccdfb28ef54943b6fec676827 +lib/codeql/rust/elements/internal/generated/TupleFieldList.qll e7874518ce353f58312b02fb646f19eb109b3d868f8b550c84b7d6fc3a85fd5a f4bff793bbdbc252688296953116146f5c9a0894e14a7d3e4883a5ac211c122f lib/codeql/rust/elements/internal/generated/TuplePat.qll 4e13b509e1c9dd1581a9dc50d38e0a6e36abc1254ea9c732b5b3e6503335afeb 298028df9eb84e106e625ed09d6b20038ad47bfc2faf634a0ffea50b17b5805d lib/codeql/rust/elements/internal/generated/TupleStructPat.qll 6539d0edbdc16e7df849514d51980d4cd1a2c9cbb58ca9e5273851f96df4eb36 45a13bae5220d5737cbd04713a17af5b33d8bb4cfdf17ddd64b298ab0c1eea24 lib/codeql/rust/elements/internal/generated/TupleTypeRepr.qll 1756cdbad56d634bf4726bc39c768386754e62650492d7d6344012038236a05b 3ac0997a47f95f28cc70c782173ce345fcb5b073be10f3c0b414d1df8443e04c @@ -642,7 +640,7 @@ lib/codeql/rust/elements/internal/generated/WhileExpr.qll 0353aab87c49569e1fbf58 lib/codeql/rust/elements/internal/generated/WildcardPat.qll d74b70b57a0a66bfae017a329352a5b27a6b9e73dd5521d627f680e810c6c59e 4b913b548ba27ff3c82fcd32cf996ff329cb57d176d3bebd0fcef394486ea499 lib/codeql/rust/elements/internal/generated/YeetExpr.qll cac328200872a35337b4bcb15c851afb4743f82c080f9738d295571eb01d7392 94af734eea08129b587fed849b643e7572800e8330c0b57d727d41abda47930b lib/codeql/rust/elements/internal/generated/YieldExpr.qll 37e5f0c1e373a22bbc53d8b7f2c0e1f476e5be5080b8437c5e964f4e83fad79a 4a9a68643401637bf48e5c2b2f74a6bf0ddcb4ff76f6bffb61d436b685621e85 -lib/codeql/rust/elements.qll d3beb3a35f2b5ea47d60aeefd86fb0d6406dd0a1b7cd89aecbb2732b4e72da38 d3beb3a35f2b5ea47d60aeefd86fb0d6406dd0a1b7cd89aecbb2732b4e72da38 +lib/codeql/rust/elements.qll 5cc722db81259ee5d5b9cbed1a4d2795060ad996c80fd7121e7ce43dc392b62f 5cc722db81259ee5d5b9cbed1a4d2795060ad996c80fd7121e7ce43dc392b62f test/extractor-tests/generated/Abi/Abi.ql 086ed104ab1a7e7fe5c1ed29e03f1719a797c7096c738868bf6ebe872ab8fdaa fe23fe67ab0d9201e1177ea3f844b18ed428e13e3ce77381bf2b6910adfa3a0e test/extractor-tests/generated/ArgList/ArgList.ql da97b5b25418b2aa8cb8df793f48870c89fa00759cdade8ddba60d7f1f4bbc01 acfd5d2caf67282ad2d57b961068472100482d0f770a52a3c00214c647d18c75 test/extractor-tests/generated/ArrayListExpr/ArrayListExpr.ql 42b365276aa43e2cad588338463542d3ce1dd0db3a428621554584b07a1431d5 08a66a8b69af35ee3bc64c35c453a19a6c9881cc6cc7e65275d1fff056121270 @@ -668,7 +666,7 @@ test/extractor-tests/generated/BinaryExpr/BinaryExpr.ql 4e849e6eaae581f487aa74d0 test/extractor-tests/generated/BlockExpr/BlockExpr.ql cd6ef66de9e56ebb74964e59617d47999fb8c9081e885acece17a3b747a35ae1 6766844c1b87e518688565f2469575af5ca4e0ff4eb0c0b620df73a451d86a0b test/extractor-tests/generated/BoxPat/BoxPat.ql 854c9ba4e045dbe7ea1666866c1c443a92597df0ce02f4ca5993142925941c39 a22c17cce0bff7d1df51b817d2cb1a61045357f91be14465166971efa5f5daad test/extractor-tests/generated/BreakExpr/BreakExpr.ql c2181211da3dfe983cfca93ead32d5d211e91181899b9477152c58124eaa846d 57e57b926e14db2efb2e88e04699608b2ba9797ee4f6c4f710135b6858982256 -test/extractor-tests/generated/CallExpr/CallExpr.ql 2a1cd4485ccd8d4eb24a75889e832612adef9bb7feae414c90572796380bc6d7 95060b92aa04d7ad1fc6603c5ec14a275a5788ecb5a19932732e28105607a3b7 +test/extractor-tests/generated/CallExpr/CallExpr.ql 16d85d6e5cb68384d0b932fb4506c1855019b819f2c5faa39a4472f39427623a 14df8383948cedaff88f514f7239c1ec8c424720d24e3546cbcd0b689acecdb1 test/extractor-tests/generated/CastExpr/CastExpr.ql 3480ec51072399409b7553ab6139c832db6ed4ca991f3a7a2282a39afe07c6f2 614c8ea7a2fe30d57583dbf84ed7a12743c2aba49d8c6252d31af3ed10853a39 test/extractor-tests/generated/ClosureExpr/ClosureExpr.ql 675ae07193241fbd710ece4f74f86e9b00f47841299b1c5934f55dbf13a4b4af 21fb0664619c9c889e9491bfd651c2814dcf0f158dd6269937bd0acc18be6b0e test/extractor-tests/generated/Comment/Comment.ql 0e0454911d2cf2e7ef5c6d860b84c57b9d490090914ebcf4fa0e8a70f777f066 cbd1c195276ef163f8d3c122344738c884dc9fb70eb2f9b7067829d735d48c4c @@ -727,7 +725,7 @@ test/extractor-tests/generated/MatchArmList/MatchArmList.ql bbc679fe6d8dedf9131d test/extractor-tests/generated/MatchExpr/MatchExpr.ql b75a5936401bb5ca38686f1413f5c8267ad685722560a2e9041dacf2f8d54abc 7da57118fe5b1f7f5cbe8d6b5f3ae70816fd4837b1c2e6401b98175b36ca233f test/extractor-tests/generated/MatchGuard/MatchGuard.ql 91de18a0a18d120db568b2c329e5cb26f83e327cf22c5825c555ea17249d7d23 0bcdb25895362128517227c860b9dad76851215c2cdf9b2d0e5cc3534278f4ec test/extractor-tests/generated/Meta/Meta.ql 43dd1cd669099b38396b316616992af6d84b0c1cee953b19235a00ab3d3bb43c 80b1885809aa074357e21707d1f8c6dca19f0b968ccff43229bb0d5c6fffb2b2 -test/extractor-tests/generated/MethodCallExpr/MethodCallExpr.ql 05ca29fdab8ce600469728b964c369368e5097b2a5eb35b84a7630ef044ac6b6 aa45fdbb7fba8afee9f6cef10d337622429d3f0fb71f7fbf861afb4906bdef71 +test/extractor-tests/generated/MethodCallExpr/MethodCallExpr.ql 9d5af6b4771a8725fa5b56ccb3e2a33158b18c876546b88e6dc63da1f887910a 494c8c2fe5584aac45c828b38d8bb20c113927a1e909773d4a2dbd3965d26170 test/extractor-tests/generated/Module/Module.ql d7c442fd1b1f4f00da87e2228fc1aeeab0bb86648b2aa06a9dd6f40dbae1ee28 3229388727d14048e87238bcda5fde1bed503e5cac088922381e5833cfc32fa9 test/extractor-tests/generated/Name/Name.ql b2fe417f7c816f71d12622b4f84ece74eba3c128c806266a55b53f8120fa4fb3 8bc65bbf3f2909637485f5db7830d6fc110a94c9b12eefe12d7627f41eae2256 test/extractor-tests/generated/NameRef/NameRef.ql 210a70e0957f3444195eed3a3dfbb5806e349238c0b390dc00597e6b8b05fcec d74fbce3c71aa7b08ae4cb646ccb114335767cb4fe000322f9dd371c1bb3784f diff --git a/rust/ql/.gitattributes b/rust/ql/.gitattributes index 6afbf118f11..22c7d3a1549 100644 --- a/rust/ql/.gitattributes +++ b/rust/ql/.gitattributes @@ -35,7 +35,6 @@ /lib/codeql/rust/elements/BoxPat.qll linguist-generated /lib/codeql/rust/elements/BreakExpr.qll linguist-generated /lib/codeql/rust/elements/CallExpr.qll linguist-generated -/lib/codeql/rust/elements/CallExprBase.qll linguist-generated /lib/codeql/rust/elements/Callable.qll linguist-generated /lib/codeql/rust/elements/CastExpr.qll linguist-generated /lib/codeql/rust/elements/ClosureExpr.qll linguist-generated @@ -481,7 +480,6 @@ /lib/codeql/rust/elements/internal/generated/BoxPat.qll linguist-generated /lib/codeql/rust/elements/internal/generated/BreakExpr.qll linguist-generated /lib/codeql/rust/elements/internal/generated/CallExpr.qll linguist-generated -/lib/codeql/rust/elements/internal/generated/CallExprBase.qll linguist-generated /lib/codeql/rust/elements/internal/generated/Callable.qll linguist-generated /lib/codeql/rust/elements/internal/generated/CastExpr.qll linguist-generated /lib/codeql/rust/elements/internal/generated/ClosureExpr.qll linguist-generated diff --git a/rust/ql/examples/snippets/simple_constant_password.ql b/rust/ql/examples/snippets/simple_constant_password.ql index b0902235a96..e43238cedd4 100644 --- a/rust/ql/examples/snippets/simple_constant_password.ql +++ b/rust/ql/examples/snippets/simple_constant_password.ql @@ -30,11 +30,11 @@ module ConstantPasswordConfig implements DataFlow::ConfigSig { predicate isSink(DataFlow::Node node) { // `node` is an argument whose corresponding parameter name matches the pattern "pass%" - exists(CallExpr call, Function target, int argIndex, Variable v | + exists(Call call, Function target, int argIndex, Variable v | call.getStaticTarget() = target and v.getParameter() = target.getParam(argIndex) and v.getText().matches("pass%") and - call.getArg(argIndex) = node.asExpr() + call.getPositionalArgument(argIndex) = node.asExpr() ) } } diff --git a/rust/ql/examples/snippets/simple_sql_injection.ql b/rust/ql/examples/snippets/simple_sql_injection.ql index 653c761d7eb..251ab604402 100644 --- a/rust/ql/examples/snippets/simple_sql_injection.ql +++ b/rust/ql/examples/snippets/simple_sql_injection.ql @@ -23,9 +23,9 @@ module SqlInjectionConfig implements DataFlow::ConfigSig { predicate isSink(DataFlow::Node node) { // `node` is the first argument of a call to `sqlx_core::query::query` - exists(CallExpr call | + exists(Call call | call.getStaticTarget().getCanonicalPath() = "sqlx_core::query::query" and - call.getArg(0) = node.asExpr() + call.getPositionalArgument(0) = node.asExpr() ) } } diff --git a/rust/ql/lib/codeql/rust/controlflow/CfgNodes.qll b/rust/ql/lib/codeql/rust/controlflow/CfgNodes.qll index 96ae6f8fdbc..eeed7086546 100644 --- a/rust/ql/lib/codeql/rust/controlflow/CfgNodes.qll +++ b/rust/ql/lib/codeql/rust/controlflow/CfgNodes.qll @@ -4,7 +4,6 @@ */ private import rust -private import codeql.rust.elements.Call private import ControlFlowGraph private import internal.ControlFlowGraphImpl as CfgImpl private import internal.CfgNodes @@ -200,20 +199,6 @@ final class BreakExprCfgNode extends Nodes::BreakExprCfgNode { } } -/** - * A function or method call expression. See `CallExpr` and `MethodCallExpr` for further details. - */ -final class CallExprBaseCfgNode extends Nodes::CallExprBaseCfgNode { - private CallExprBaseChildMapping node; - - CallExprBaseCfgNode() { node = this.getAstNode() } - - /** Gets the `i`th argument of this call. */ - ExprCfgNode getArgument(int i) { - any(ChildMapping mapping).hasCfgChild(node, node.getArgList().getArg(i), this, result) - } -} - /** * A method call expression. For example: * ```rust @@ -221,7 +206,16 @@ final class CallExprBaseCfgNode extends Nodes::CallExprBaseCfgNode { * x.foo::(42); * ``` */ -final class MethodCallExprCfgNode extends CallExprBaseCfgNode, Nodes::MethodCallExprCfgNode { } +final class MethodCallExprCfgNode extends Nodes::MethodCallExprCfgNode { + private MethodCallExprChildMapping node; + + MethodCallExprCfgNode() { node = this.getAstNode() } + + /** Gets the `i`th argument of this call. */ + ExprCfgNode getPositionalArgument(int i) { + any(ChildMapping mapping).hasCfgChild(node, node.getPositionalArgument(i), this, result) + } +} /** * A CFG node that calls a function. @@ -238,7 +232,7 @@ final class CallCfgNode extends ExprCfgNode { /** Gets the receiver of this call if it is a method call. */ ExprCfgNode getReceiver() { - any(ChildMapping mapping).hasCfgChild(node, node.getReceiver(), this, result) + any(ChildMapping mapping).hasCfgChild(node, node.(MethodCall).getReceiver(), this, result) } /** Gets the `i`th argument of this call, if any. */ @@ -248,15 +242,26 @@ final class CallCfgNode extends ExprCfgNode { } /** - * A function call expression. For example: + * An expression with parenthesized arguments. For example: * ```rust * foo(42); * foo::(42); * foo[0](42); * foo(1) = 4; + * Option::Some(42); * ``` */ -final class CallExprCfgNode extends CallExprBaseCfgNode, Nodes::CallExprCfgNode { } +final class CallExprCfgNode extends Nodes::CallExprCfgNode { + private CallExprChildMapping node; + + CallExprCfgNode() { node = this.getAstNode() } + + /** Gets the `i`th argument of this call. */ + ExprCfgNode getSyntacticArgument(int i) { + any(ChildMapping mapping) + .hasCfgChild(node, node.getSyntacticPositionalArgument(i), this, result) + } +} /** * A FormatArgsExpr. For example: diff --git a/rust/ql/lib/codeql/rust/controlflow/internal/CfgNodes.qll b/rust/ql/lib/codeql/rust/controlflow/internal/CfgNodes.qll index eb4d665436e..ee1c0e6ab6b 100644 --- a/rust/ql/lib/codeql/rust/controlflow/internal/CfgNodes.qll +++ b/rust/ql/lib/codeql/rust/controlflow/internal/CfgNodes.qll @@ -57,8 +57,12 @@ class BreakExprTargetChildMapping extends ParentAstNode, Expr { override predicate relevantChild(AstNode child) { child.(BreakExpr).getTarget() = this } } -class CallExprBaseChildMapping extends ParentAstNode, CallExprBase { - override predicate relevantChild(AstNode child) { child = this.getAnArg() } +class CallExprChildMapping extends ParentAstNode, CallExpr { + override predicate relevantChild(AstNode child) { child = this.getArgList().getAnArg() } +} + +class MethodCallExprChildMapping extends ParentAstNode, MethodCallExpr { + override predicate relevantChild(AstNode child) { child = this.getArgList().getAnArg() } } class StructExprChildMapping extends ParentAstNode, StructExpr { diff --git a/rust/ql/lib/codeql/rust/controlflow/internal/ControlFlowGraphImpl.qll b/rust/ql/lib/codeql/rust/controlflow/internal/ControlFlowGraphImpl.qll index c3fb15ec0e7..522e5741795 100644 --- a/rust/ql/lib/codeql/rust/controlflow/internal/ControlFlowGraphImpl.qll +++ b/rust/ql/lib/codeql/rust/controlflow/internal/ControlFlowGraphImpl.qll @@ -210,13 +210,17 @@ module ExprTrees { override AstNode getChildNode(int i) { i = 0 and result = super.getExpr() } } - class BinaryOpExprTree extends StandardPostOrderTree instanceof BinaryExpr { - BinaryOpExprTree() { not this instanceof BinaryLogicalOperation } + class InvocationExprTree extends StandardPostOrderTree instanceof InvocationExpr { + InvocationExprTree() { + not this instanceof CallExpr and + not this instanceof BinaryLogicalOperation + } override AstNode getChildNode(int i) { - i = 0 and result = super.getLhs() + i = 0 and + result = super.getSyntacticReceiver() or - i = 1 and result = super.getRhs() + result = super.getSyntacticPositionalArgument(i - 1) } } @@ -296,7 +300,7 @@ module ExprTrees { override AstNode getChildNode(int i) { i = 0 and result = super.getFunction() or - result = super.getArgList().getArg(i - 1) + result = super.getSyntacticPositionalArgument(i - 1) } } @@ -371,14 +375,6 @@ module ExprTrees { } } - class IndexExprTree extends StandardPostOrderTree instanceof IndexExpr { - override AstNode getChildNode(int i) { - i = 0 and result = super.getBase() - or - i = 1 and result = super.getIndex() - } - } - class LetExprTree extends StandardPostOrderTree, LetExpr { override AstNode getChildNode(int i) { i = 0 and @@ -510,12 +506,6 @@ module ExprTrees { } } - class MethodCallExprTree extends StandardPostOrderTree, MethodCallExpr { - override AstNode getChildNode(int i) { - if i = 0 then result = this.getReceiver() else result = this.getArg(i - 1) - } - } - class OffsetOfExprTree extends LeafTree instanceof OffsetOfExpr { } class ParenExprTree extends ControlFlowTree, ParenExpr { @@ -534,10 +524,6 @@ module ExprTrees { class PathExprTree extends LeafTree instanceof PathExpr { } - class PrefixExprTree extends StandardPostOrderTree instanceof PrefixExpr { - override AstNode getChildNode(int i) { i = 0 and result = super.getExpr() } - } - class RangeExprTree extends StandardPostOrderTree instanceof RangeExpr { override AstNode getChildNode(int i) { i = 0 and result = super.getStart() @@ -552,10 +538,6 @@ module ExprTrees { } } - class RefExprTree extends StandardPostOrderTree instanceof RefExpr { - override AstNode getChildNode(int i) { i = 0 and result = super.getExpr() } - } - class ReturnExprTree extends StandardPostOrderTree instanceof ReturnExpr { override AstNode getChildNode(int i) { i = 0 and result = super.getExpr() } } diff --git a/rust/ql/lib/codeql/rust/controlflow/internal/generated/CfgNodes.qll b/rust/ql/lib/codeql/rust/controlflow/internal/generated/CfgNodes.qll index 9ce771983a3..016217e0a46 100644 --- a/rust/ql/lib/codeql/rust/controlflow/internal/generated/CfgNodes.qll +++ b/rust/ql/lib/codeql/rust/controlflow/internal/generated/CfgNodes.qll @@ -654,15 +654,18 @@ module MakeCfgNodes Input> { } /** - * A function call expression. For example: + * NOTE: Consider using `Call` instead, as that excludes call expressions that are + * instantiations of tuple structs and tuple variants. + * + * A call expression. For example: * ```rust * foo(42); * foo::(42); * foo[0](42); - * foo(1) = 4; + * Option::Some(42); // tuple variant instantiation * ``` */ - final class CallExprCfgNode extends CfgNodeFinal, CallExprBaseCfgNode { + final class CallExprCfgNode extends CfgNodeFinal, ExprCfgNode { private CallExpr node; CallExprCfgNode() { node = this.getAstNode() } @@ -670,6 +673,31 @@ module MakeCfgNodes Input> { /** Gets the underlying `CallExpr`. */ CallExpr getCallExpr() { result = node } + /** + * Gets the argument list of this call expression, if it exists. + */ + ArgList getArgList() { result = node.getArgList() } + + /** + * Holds if `getArgList()` exists. + */ + predicate hasArgList() { exists(this.getArgList()) } + + /** + * Gets the `index`th attr of this call expression (0-based). + */ + Attr getAttr(int index) { result = node.getAttr(index) } + + /** + * Gets any of the attrs of this call expression. + */ + Attr getAnAttr() { result = this.getAttr(_) } + + /** + * Gets the number of attrs of this call expression. + */ + int getNumberOfAttrs() { result = count(int i | exists(this.getAttr(i))) } + /** * Gets the function of this call expression, if it exists. */ @@ -683,62 +711,6 @@ module MakeCfgNodes Input> { predicate hasFunction() { exists(this.getFunction()) } } - final private class ParentCallExprBase extends ParentAstNode, CallExprBase { - override predicate relevantChild(AstNode child) { none() } - } - - /** - * A function or method call expression. See `CallExpr` and `MethodCallExpr` for further details. - */ - final class CallExprBaseCfgNode extends CfgNodeFinal, ExprCfgNode { - private CallExprBase node; - - CallExprBaseCfgNode() { node = this.getAstNode() } - - /** Gets the underlying `CallExprBase`. */ - CallExprBase getCallExprBase() { result = node } - - /** - * Gets the argument list of this call expression base, if it exists. - */ - ArgList getArgList() { result = node.getArgList() } - - /** - * Holds if `getArgList()` exists. - */ - predicate hasArgList() { exists(this.getArgList()) } - - /** - * Gets the `index`th attr of this call expression base (0-based). - */ - Attr getAttr(int index) { result = node.getAttr(index) } - - /** - * Gets any of the attrs of this call expression base. - */ - Attr getAnAttr() { result = this.getAttr(_) } - - /** - * Gets the number of attrs of this call expression base. - */ - int getNumberOfAttrs() { result = count(int i | exists(this.getAttr(i))) } - - /** - * Gets the `index`th argument of this call expression base (0-based). - */ - Expr getArg(int index) { result = node.getArg(index) } - - /** - * Gets any of the arguments of this call expression base. - */ - Expr getAnArg() { result = this.getArg(_) } - - /** - * Gets the number of arguments of this call expression base. - */ - int getNumberOfArgs() { result = count(int i | exists(this.getArg(i))) } - } - final private class ParentCastExpr extends ParentAstNode, CastExpr { override predicate relevantChild(AstNode child) { none() @@ -2071,13 +2043,17 @@ module MakeCfgNodes Input> { } /** + * NOTE: Consider using `MethodCall` instead, as that also includes calls to methods using + * call syntax (such as `Foo::method(x)`), operation syntax (such as `x + y`), and + * indexing syntax (such as `x[y]`). + * * A method call expression. For example: * ```rust * x.foo(42); * x.foo::(42); * ``` */ - final class MethodCallExprCfgNode extends CfgNodeFinal, CallExprBaseCfgNode { + final class MethodCallExprCfgNode extends CfgNodeFinal, ExprCfgNode { private MethodCallExpr node; MethodCallExprCfgNode() { node = this.getAstNode() } @@ -2085,6 +2061,31 @@ module MakeCfgNodes Input> { /** Gets the underlying `MethodCallExpr`. */ MethodCallExpr getMethodCallExpr() { result = node } + /** + * Gets the argument list of this method call expression, if it exists. + */ + ArgList getArgList() { result = node.getArgList() } + + /** + * Holds if `getArgList()` exists. + */ + predicate hasArgList() { exists(this.getArgList()) } + + /** + * Gets the `index`th attr of this method call expression (0-based). + */ + Attr getAttr(int index) { result = node.getAttr(index) } + + /** + * Gets any of the attrs of this method call expression. + */ + Attr getAnAttr() { result = this.getAttr(_) } + + /** + * Gets the number of attrs of this method call expression. + */ + int getNumberOfAttrs() { result = count(int i | exists(this.getAttr(i))) } + /** * Gets the generic argument list of this method call expression, if it exists. */ diff --git a/rust/ql/lib/codeql/rust/dataflow/internal/Content.qll b/rust/ql/lib/codeql/rust/dataflow/internal/Content.qll index 12e4b682091..a072edef612 100644 --- a/rust/ql/lib/codeql/rust/dataflow/internal/Content.qll +++ b/rust/ql/lib/codeql/rust/dataflow/internal/Content.qll @@ -5,6 +5,7 @@ private import rust private import codeql.rust.frameworks.stdlib.Builtins private import DataFlowImpl +private import codeql.rust.elements.internal.CallExprImpl::Impl as CallExprImpl /** * A path to a value contained in an object. For example a field name of a struct. @@ -163,7 +164,7 @@ final class TuplePositionContent extends FieldContent, TTuplePositionContent { } /** - * A content for the index of an argument to at function call. + * A content for the index of an argument to at closure call. * * Used by the model generator to create flow summaries for higher-order * functions. @@ -270,7 +271,7 @@ newtype TContent = } or TFunctionCallReturnContent() or TFunctionCallArgumentContent(int pos) { - pos in [0 .. any(CallExpr c).getArgList().getNumberOfArgs() - 1] + pos in [0 .. any(CallExprImpl::DynamicCallExpr c).getNumberOfPositionalArguments()] } or TCapturedVariableContent(VariableCapture::CapturedVariable v) or TReferenceContent() diff --git a/rust/ql/lib/codeql/rust/dataflow/internal/DataFlowImpl.qll b/rust/ql/lib/codeql/rust/dataflow/internal/DataFlowImpl.qll index ec50150390a..7a77b7de5b6 100644 --- a/rust/ql/lib/codeql/rust/dataflow/internal/DataFlowImpl.qll +++ b/rust/ql/lib/codeql/rust/dataflow/internal/DataFlowImpl.qll @@ -8,9 +8,9 @@ private import codeql.util.Boolean private import codeql.dataflow.DataFlow private import codeql.dataflow.internal.DataFlowImpl private import rust -private import codeql.rust.elements.Call private import SsaImpl as SsaImpl private import codeql.rust.controlflow.internal.Scope as Scope +private import codeql.rust.elements.internal.CallExprImpl::Impl as CallExprImpl private import codeql.rust.internal.PathResolution private import codeql.rust.controlflow.ControlFlowGraph private import codeql.rust.dataflow.Ssa @@ -57,7 +57,7 @@ final class DataFlowCallable extends TDataFlowCallable { } final class DataFlowCall extends TDataFlowCall { - /** Gets the underlying call in the CFG, if any. */ + /** Gets the underlying call, if any. */ Call asCall() { this = TCall(result) } predicate isSummaryCall( @@ -86,62 +86,10 @@ final class DataFlowCall extends TDataFlowCall { Location getLocation() { result = this.asCall().getLocation() } } -/** - * The position of a parameter in a function. - * - * In Rust there is a 1-to-1 correspondence between parameter positions and - * arguments positions, so we use the same underlying type for both. - */ -final class ParameterPosition extends TParameterPosition { - /** Gets the underlying integer position, if any. */ - int getPosition() { this = TPositionalParameterPosition(result) } - - predicate hasPosition() { exists(this.getPosition()) } - - /** Holds if this position represents the `self` position. */ - predicate isSelf() { this = TSelfParameterPosition() } - - /** - * Holds if this position represents a reference to a closure itself. Only - * used for tracking flow through captured variables. - */ - predicate isClosureSelf() { this = TClosureSelfParameterPosition() } - - /** Gets a textual representation of this position. */ - string toString() { - result = this.getPosition().toString() - or - result = "self" and this.isSelf() - or - result = "closure self" and this.isClosureSelf() - } - - ParamBase getParameterIn(ParamList ps) { - result = ps.getParam(this.getPosition()) - or - result = ps.getSelfParam() and this.isSelf() - } -} - -/** - * The position of an argument in a call. - * - * In Rust there is a 1-to-1 correspondence between parameter positions and - * arguments positions, so we use the same underlying type for both. - */ -final class ArgumentPosition extends ParameterPosition { - /** Gets the argument of `call` at this position, if any. */ - Expr getArgument(Call call) { - result = call.getPositionalArgument(this.getPosition()) - or - result = call.getReceiver() and this.isSelf() - } -} - /** * Holds if `arg` is an argument of `call` at the position `pos`. */ -predicate isArgumentForCall(Expr arg, Call call, ArgumentPosition pos) { +predicate isArgumentForCall(Expr arg, Call call, RustDataFlow::ArgumentPosition pos) { // TODO: Handle index expressions as calls in data flow. not call instanceof IndexExpr and arg = pos.getArgument(call) @@ -293,10 +241,8 @@ predicate lambdaCreationExpr(Expr creation) { * Holds if `call` is a lambda call of kind `kind` where `receiver` is the * invoked expression. */ -predicate lambdaCallExpr(CallExpr call, LambdaCallKind kind, Expr receiver) { +predicate lambdaCallExpr(CallExprImpl::DynamicCallExpr call, LambdaCallKind kind, Expr receiver) { receiver = call.getFunction() and - // All calls to complex expressions and local variable accesses are lambda call. - (receiver instanceof PathExpr implies receiver = any(Variable v).getAnAccess()) and exists(kind) } @@ -308,10 +254,6 @@ private module Aliases { class DataFlowCallAlias = DataFlowCall; - class ParameterPositionAlias = ParameterPosition; - - class ArgumentPositionAlias = ArgumentPosition; - class ContentAlias = Content; class ContentSetAlias = ContentSet; @@ -343,6 +285,58 @@ module RustDataFlow implements InputSig { final class CastNode = Node::CastNode; + /** + * The position of a parameter in a function. + * + * In Rust there is a 1-to-1 correspondence between parameter positions and + * arguments positions, so we use the same underlying type for both. + */ + final class ParameterPosition extends TParameterPosition { + /** Gets the underlying integer position, if any. */ + int getPosition() { this = TPositionalParameterPosition(result) } + + predicate hasPosition() { exists(this.getPosition()) } + + /** Holds if this position represents the `self` position. */ + predicate isSelf() { this = TSelfParameterPosition() } + + /** + * Holds if this position represents a reference to a closure itself. Only + * used for tracking flow through captured variables. + */ + predicate isClosureSelf() { this = TClosureSelfParameterPosition() } + + /** Gets a textual representation of this position. */ + string toString() { + result = this.getPosition().toString() + or + result = "self" and this.isSelf() + or + result = "closure self" and this.isClosureSelf() + } + + ParamBase getParameterIn(ParamList ps) { + result = ps.getParam(this.getPosition()) + or + result = ps.getSelfParam() and this.isSelf() + } + } + + /** + * The position of an argument in a call. + * + * In Rust there is a 1-to-1 correspondence between parameter positions and + * arguments positions, so we use the same underlying type for both. + */ + final class ArgumentPosition extends ParameterPosition { + /** Gets the argument of `call` at this position, if any. */ + Expr getArgument(Call call) { + result = call.getPositionalArgument(this.getPosition()) + or + result = call.(MethodCall).getReceiver() and this.isSelf() + } + } + /** Holds if `p` is a parameter of `c` at the position `pos`. */ predicate isParameterNode(ParameterNode p, DataFlowCallable c, ParameterPosition pos) { p.isParameterOf(c, pos) @@ -452,10 +446,6 @@ module RustDataFlow implements InputSig { ContentApprox getContentApprox(Content c) { result = c } - class ParameterPosition = ParameterPositionAlias; - - class ArgumentPosition = ArgumentPositionAlias; - /** * Holds if the parameter position `ppos` matches the argument position * `apos`. @@ -666,10 +656,14 @@ module RustDataFlow implements InputSig { pragma[nomagic] additional predicate storeContentStep(Node node1, Content c, Node node2) { - exists(CallExpr call, int pos | - node1.asExpr() = call.getArg(pragma[only_bind_into](pos)) and - node2.asExpr() = call and - c = TTupleFieldContent(call.getTupleField(pragma[only_bind_into](pos))) + exists(CallExpr ce, TupleField tf, int pos | + node1.asExpr() = ce.getSyntacticPositionalArgument(pos) and + node2.asExpr() = ce and + c = TTupleFieldContent(tf) + | + tf = ce.(TupleStructExpr).getTupleField(pos) + or + tf = ce.(TupleVariantExpr).getTupleField(pos) ) or exists(StructExpr re, string field | @@ -824,11 +818,7 @@ module RustDataFlow implements InputSig { */ predicate lambdaCall(DataFlowCall call, LambdaCallKind kind, Node receiver) { ( - receiver.asExpr() = call.asCall().(CallExpr).getFunction() and - // All calls to complex expressions and local variable accesses are lambda call. - exists(Expr f | f = receiver.asExpr() | - f instanceof PathExpr implies f = any(Variable v).getAnAccess() - ) + receiver.asExpr() = call.asCall().(CallExprImpl::DynamicCallExpr).getFunction() or call.isSummaryCall(_, receiver.(FlowSummaryNode).getSummaryNode()) ) and diff --git a/rust/ql/lib/codeql/rust/dataflow/internal/FlowSummaryImpl.qll b/rust/ql/lib/codeql/rust/dataflow/internal/FlowSummaryImpl.qll index d9457d79510..4aef065efdf 100644 --- a/rust/ql/lib/codeql/rust/dataflow/internal/FlowSummaryImpl.qll +++ b/rust/ql/lib/codeql/rust/dataflow/internal/FlowSummaryImpl.qll @@ -12,18 +12,17 @@ private import codeql.rust.dataflow.Ssa private import Content module Input implements InputSig { - private import codeql.rust.elements.internal.CallExprBaseImpl::Impl as CallExprBaseImpl private import codeql.rust.frameworks.stdlib.Stdlib class SummarizedCallableBase = Function; abstract private class SourceSinkBase extends AstNode { /** Gets the associated call. */ - abstract CallExprBase getCall(); + abstract Call getCall(); /** Holds if the associated call resolves to `path`. */ final predicate callResolvesTo(string path) { - path = this.getCall().getStaticTarget().(Addressable).getCanonicalPath() + path = this.getCall().getResolvedTarget().getCanonicalPath() } } @@ -36,7 +35,7 @@ module Input implements InputSig { CallExprFunction() { this = call.getFunction() } - override CallExpr getCall() { result = call } + override Call getCall() { result = call } } private class MethodCallExprNameRef extends SourceBase, SinkBase { @@ -51,11 +50,9 @@ module Input implements InputSig { ReturnKind getStandardReturnValueKind() { result = TNormalReturnKind() } - string encodeParameterPosition(ParameterPosition pos) { result = pos.toString() } + string encodeParameterPosition(RustDataFlow::ParameterPosition pos) { result = pos.toString() } - string encodeArgumentPosition(RustDataFlow::ArgumentPosition pos) { - result = encodeParameterPosition(pos) - } + string encodeArgumentPosition(RustDataFlow::ArgumentPosition pos) { result = pos.toString() } string encodeContent(ContentSet cs, string arg) { exists(Content c | cs = TSingletonContentSet(c) | @@ -108,7 +105,9 @@ module Input implements InputSig { string encodeWithContent(ContentSet c, string arg) { result = "With" + encodeContent(c, arg) } bindingset[token] - ParameterPosition decodeUnknownParameterPosition(AccessPath::AccessPathTokenBase token) { + RustDataFlow::ParameterPosition decodeUnknownParameterPosition( + AccessPath::AccessPathTokenBase token + ) { // needed to support `Argument[x..y]` ranges token.getName() = "Argument" and result.getPosition() = AccessPath::parseInt(token.getAnArgument()) @@ -135,7 +134,7 @@ private module StepsInput implements Impl::Private::StepsInputSig { /** Gets the argument of `source` described by `sc`, if any. */ private Expr getSourceNodeArgument(Input::SourceBase source, Impl::Private::SummaryComponent sc) { - exists(ArgumentPosition pos | + exists(RustDataFlow::ArgumentPosition pos | sc = Impl::Private::SummaryComponent::argument(pos) and result = pos.getArgument(source.getCall()) ) @@ -162,7 +161,7 @@ private module StepsInput implements Impl::Private::StepsInputSig { s.head() = Impl::Private::SummaryComponent::return(_) and result.asExpr() = source.getCall() or - exists(ArgumentPosition pos, Expr arg | + exists(RustDataFlow::ArgumentPosition pos, Expr arg | s.head() = Impl::Private::SummaryComponent::parameter(pos) and arg = getSourceNodeArgument(source, s.tail().headOfSingleton()) and result.asParameter() = getCallable(arg).getParam(pos.getPosition()) @@ -173,7 +172,7 @@ private module StepsInput implements Impl::Private::StepsInputSig { } RustDataFlow::Node getSinkNode(Input::SinkBase sink, Impl::Private::SummaryComponent sc) { - exists(CallExprBase call, Expr arg, ArgumentPosition pos | + exists(InvocationExpr call, Expr arg, RustDataFlow::ArgumentPosition pos | result.asExpr() = arg and sc = Impl::Private::SummaryComponent::argument(pos) and call = sink.getCall() and diff --git a/rust/ql/lib/codeql/rust/dataflow/internal/ModelsAsData.qll b/rust/ql/lib/codeql/rust/dataflow/internal/ModelsAsData.qll index 067ef98b2fc..a680f20d5f6 100644 --- a/rust/ql/lib/codeql/rust/dataflow/internal/ModelsAsData.qll +++ b/rust/ql/lib/codeql/rust/dataflow/internal/ModelsAsData.qll @@ -47,7 +47,6 @@ private import rust private import codeql.rust.dataflow.FlowSummary private import codeql.rust.dataflow.FlowSource private import codeql.rust.dataflow.FlowSink -private import codeql.rust.elements.internal.CallExprBaseImpl::Impl as CallExprBaseImpl /** * Holds if in a call to the function with canonical path `path`, the value referred diff --git a/rust/ql/lib/codeql/rust/dataflow/internal/Node.qll b/rust/ql/lib/codeql/rust/dataflow/internal/Node.qll index 0edc4c9e499..1e4289afa3f 100644 --- a/rust/ql/lib/codeql/rust/dataflow/internal/Node.qll +++ b/rust/ql/lib/codeql/rust/dataflow/internal/Node.qll @@ -167,7 +167,7 @@ final class NameNode extends AstNodeNode, TNameNode { */ abstract class ParameterNode extends Node { /** Holds if this node is a parameter of `c` at position `pos`. */ - abstract predicate isParameterOf(DataFlowCallable c, ParameterPosition pos); + abstract predicate isParameterOf(DataFlowCallable c, RustDataFlow::ParameterPosition pos); } final class SourceParameterNode extends AstNodeNode, ParameterNode, TSourceParameterNode { @@ -175,12 +175,12 @@ final class SourceParameterNode extends AstNodeNode, ParameterNode, TSourceParam SourceParameterNode() { this = TSourceParameterNode(n) } - override predicate isParameterOf(DataFlowCallable c, ParameterPosition pos) { + override predicate isParameterOf(DataFlowCallable c, RustDataFlow::ParameterPosition pos) { n = pos.getParameterIn(c.asCfgScope().(Callable).getParamList()) } /** Get the parameter position of this parameter. */ - ParameterPosition getPosition() { this.isParameterOf(_, result) } + RustDataFlow::ParameterPosition getPosition() { this.isParameterOf(_, result) } /** Gets the parameter in the CFG that this node corresponds to. */ ParamBase getParameter() { result = n } @@ -188,13 +188,13 @@ final class SourceParameterNode extends AstNodeNode, ParameterNode, TSourceParam /** A parameter for a library callable with a flow summary. */ final class SummaryParameterNode extends ParameterNode, FlowSummaryNode { - private ParameterPosition pos_; + private RustDataFlow::ParameterPosition pos_; SummaryParameterNode() { FlowSummaryImpl::Private::summaryParameterNode(this.getSummaryNode(), pos_) } - override predicate isParameterOf(DataFlowCallable c, ParameterPosition pos) { + override predicate isParameterOf(DataFlowCallable c, RustDataFlow::ParameterPosition pos) { this.getSummarizedCallable() = c.asSummarizedCallable() and pos = pos_ } } @@ -210,7 +210,7 @@ final class ClosureParameterNode extends ParameterNode, TClosureSelfReferenceNod final override CfgScope getCfgScope() { result = cfgScope } - override predicate isParameterOf(DataFlowCallable c, ParameterPosition pos) { + override predicate isParameterOf(DataFlowCallable c, RustDataFlow::ParameterPosition pos) { cfgScope = c.asCfgScope() and pos.isClosureSelf() } @@ -294,13 +294,12 @@ final class SummaryArgumentNode extends FlowSummaryNode, ArgumentNode { * passed into the closure body at an invocation. */ final class ClosureArgumentNode extends ArgumentNode, ExprNode { - private CallExpr call_; + private Call call_; ClosureArgumentNode() { lambdaCallExpr(call_, _, this.asExpr()) } override predicate isArgumentOf(DataFlowCall call, RustDataFlow::ArgumentPosition pos) { - call.asCall() = call_ and - pos.isClosureSelf() + call.asCall() = call_ and pos.isClosureSelf() } } diff --git a/rust/ql/lib/codeql/rust/dataflow/internal/SsaImpl.qll b/rust/ql/lib/codeql/rust/dataflow/internal/SsaImpl.qll index 29674cbd1df..03db7c35b4d 100644 --- a/rust/ql/lib/codeql/rust/dataflow/internal/SsaImpl.qll +++ b/rust/ql/lib/codeql/rust/dataflow/internal/SsaImpl.qll @@ -154,7 +154,7 @@ private predicate variableWriteInOuterScope(BasicBlock bb, int i, Variable v, Cf } /** Holds if evaluating `e` jumps to the evaluation of a different CFG scope. */ -private predicate isControlFlowJump(Expr e) { e instanceof CallExprBase or e instanceof AwaitExpr } +private predicate isControlFlowJump(Expr e) { e instanceof Call or e instanceof AwaitExpr } /** * Holds if the call `call` at index `i` in basic block `bb` may reach @@ -325,10 +325,8 @@ private module DataFlowIntegrationInput implements Impl::DataFlowIntegrationInpu predicate ssaDefHasSource(WriteDefinition def) { none() } // handled in `DataFlowImpl.qll` instead - private predicate isArg(CallExprBase call, Expr e) { - call.getAnArg() = e - or - call.(MethodCallExpr).getReceiver() = e + private predicate isArg(Call call, Expr e) { + call.getASyntacticArgument() = e or exists(Expr mid | isArg(call, mid) and diff --git a/rust/ql/lib/codeql/rust/elements.qll b/rust/ql/lib/codeql/rust/elements.qll index b42a93efc6c..9c7d0be306f 100644 --- a/rust/ql/lib/codeql/rust/elements.qll +++ b/rust/ql/lib/codeql/rust/elements.qll @@ -38,7 +38,6 @@ import codeql.rust.elements.BlockExpr import codeql.rust.elements.BoxPat import codeql.rust.elements.BreakExpr import codeql.rust.elements.CallExpr -import codeql.rust.elements.CallExprBase import codeql.rust.elements.Callable import codeql.rust.elements.CastExpr import codeql.rust.elements.ClosureExpr diff --git a/rust/ql/lib/codeql/rust/elements/Call.qll b/rust/ql/lib/codeql/rust/elements/Call.qll index 0fd7f1397e2..3a14425df1e 100644 --- a/rust/ql/lib/codeql/rust/elements/Call.qll +++ b/rust/ql/lib/codeql/rust/elements/Call.qll @@ -1,9 +1,11 @@ /** - * This module provides the public class `Call`. + * This module provides the public classes `Call` and `MethodCall`. */ +private import rust private import internal.CallImpl - -final class ArgumentPosition = Impl::ArgumentPosition; +private import internal.CallExprImpl::Impl as CallExprImpl final class Call = Impl::Call; + +final class MethodCall = Impl::MethodCall; diff --git a/rust/ql/lib/codeql/rust/elements/CallExpr.qll b/rust/ql/lib/codeql/rust/elements/CallExpr.qll index ab5631b07ca..1344af3a124 100644 --- a/rust/ql/lib/codeql/rust/elements/CallExpr.qll +++ b/rust/ql/lib/codeql/rust/elements/CallExpr.qll @@ -4,16 +4,20 @@ */ private import internal.CallExprImpl -import codeql.rust.elements.CallExprBase +import codeql.rust.elements.ArgList +import codeql.rust.elements.Attr import codeql.rust.elements.Expr /** - * A function call expression. For example: + * NOTE: Consider using `Call` instead, as that excludes call expressions that are + * instantiations of tuple structs and tuple variants. + * + * A call expression. For example: * ```rust * foo(42); * foo::(42); * foo[0](42); - * foo(1) = 4; + * Option::Some(42); // tuple variant instantiation * ``` */ final class CallExpr = Impl::CallExpr; diff --git a/rust/ql/lib/codeql/rust/elements/CallExprBase.qll b/rust/ql/lib/codeql/rust/elements/CallExprBase.qll deleted file mode 100644 index d59c4c705f7..00000000000 --- a/rust/ql/lib/codeql/rust/elements/CallExprBase.qll +++ /dev/null @@ -1,14 +0,0 @@ -// generated by codegen, do not edit -/** - * This module provides the public class `CallExprBase`. - */ - -private import internal.CallExprBaseImpl -import codeql.rust.elements.ArgList -import codeql.rust.elements.Attr -import codeql.rust.elements.Expr - -/** - * A function or method call expression. See `CallExpr` and `MethodCallExpr` for further details. - */ -final class CallExprBase = Impl::CallExprBase; diff --git a/rust/ql/lib/codeql/rust/elements/InvocationExpr.qll b/rust/ql/lib/codeql/rust/elements/InvocationExpr.qll new file mode 100644 index 00000000000..315c6bdef84 --- /dev/null +++ b/rust/ql/lib/codeql/rust/elements/InvocationExpr.qll @@ -0,0 +1,9 @@ +/** + * This module provides the public classes `InvocationExpr` and `ArgumentPosition`. + */ + +private import internal.InvocationExprImpl + +final class InvocationExpr = Impl::InvocationExpr; + +final class ArgumentPosition = Impl::ArgumentPosition; diff --git a/rust/ql/lib/codeql/rust/elements/Method.qll b/rust/ql/lib/codeql/rust/elements/Method.qll new file mode 100644 index 00000000000..e29b7acae9c --- /dev/null +++ b/rust/ql/lib/codeql/rust/elements/Method.qll @@ -0,0 +1,22 @@ +/** + * This module provides the public class `Method`. + */ + +private import rust + +/** + * A method declaration. For example + * ```rust + * fn foo(self, x: u32) -> u64 { (x + 1).into() } + * ``` + * + * A method declaration within a trait might not have a body: + * ```rust + * trait Trait { + * fn bar(self); + * } + * ``` + */ +final class Method extends Function { + Method() { this.hasSelfParam() } +} diff --git a/rust/ql/lib/codeql/rust/elements/MethodCallExpr.qll b/rust/ql/lib/codeql/rust/elements/MethodCallExpr.qll index fca8b086134..3ac0fccc42d 100644 --- a/rust/ql/lib/codeql/rust/elements/MethodCallExpr.qll +++ b/rust/ql/lib/codeql/rust/elements/MethodCallExpr.qll @@ -4,12 +4,17 @@ */ private import internal.MethodCallExprImpl -import codeql.rust.elements.CallExprBase +import codeql.rust.elements.ArgList +import codeql.rust.elements.Attr import codeql.rust.elements.Expr import codeql.rust.elements.GenericArgList import codeql.rust.elements.NameRef /** + * NOTE: Consider using `MethodCall` instead, as that also includes calls to methods using + * call syntax (such as `Foo::method(x)`), operation syntax (such as `x + y`), and + * indexing syntax (such as `x[y]`). + * * A method call expression. For example: * ```rust * x.foo(42); diff --git a/rust/ql/lib/codeql/rust/elements/TupleField.qll b/rust/ql/lib/codeql/rust/elements/TupleField.qll index 9dcfaa4fb33..3e63f377aeb 100644 --- a/rust/ql/lib/codeql/rust/elements/TupleField.qll +++ b/rust/ql/lib/codeql/rust/elements/TupleField.qll @@ -10,7 +10,7 @@ import codeql.rust.elements.TypeRepr import codeql.rust.elements.Visibility /** - * A field in a tuple struct or tuple enum variant. + * A field in a tuple struct or tuple variant. * * For example: * ```rust diff --git a/rust/ql/lib/codeql/rust/elements/TupleFieldList.qll b/rust/ql/lib/codeql/rust/elements/TupleFieldList.qll index 0c464944993..f2651228a78 100644 --- a/rust/ql/lib/codeql/rust/elements/TupleFieldList.qll +++ b/rust/ql/lib/codeql/rust/elements/TupleFieldList.qll @@ -8,7 +8,7 @@ import codeql.rust.elements.FieldList import codeql.rust.elements.TupleField /** - * A list of fields in a tuple struct or tuple enum variant. + * A list of fields in a tuple struct or tuple variant. * * For example: * ```rust diff --git a/rust/ql/lib/codeql/rust/elements/TupleStructExpr.qll b/rust/ql/lib/codeql/rust/elements/TupleStructExpr.qll new file mode 100644 index 00000000000..88da6aaa1cf --- /dev/null +++ b/rust/ql/lib/codeql/rust/elements/TupleStructExpr.qll @@ -0,0 +1,7 @@ +/** + * This module provides the public class `TupleStructExpr`. + */ + +private import internal.CallExprImpl + +final class TupleStructExpr = Impl::TupleStructExpr; diff --git a/rust/ql/lib/codeql/rust/elements/TupleVariantExpr.qll b/rust/ql/lib/codeql/rust/elements/TupleVariantExpr.qll new file mode 100644 index 00000000000..9afd18ea0d9 --- /dev/null +++ b/rust/ql/lib/codeql/rust/elements/TupleVariantExpr.qll @@ -0,0 +1,7 @@ +/** + * This module provides the public class `TupleVariantExpr`. + */ + +private import internal.CallExprImpl + +final class TupleVariantExpr = Impl::TupleVariantExpr; diff --git a/rust/ql/lib/codeql/rust/elements/internal/CallExprBaseImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/CallExprBaseImpl.qll deleted file mode 100644 index 05d5aee7a06..00000000000 --- a/rust/ql/lib/codeql/rust/elements/internal/CallExprBaseImpl.qll +++ /dev/null @@ -1,27 +0,0 @@ -/** - * This module provides a hand-modifiable wrapper around the generated class `CallExprBase`. - * - * INTERNAL: Do not use. - */ - -private import codeql.rust.elements.internal.generated.CallExprBase - -/** - * INTERNAL: This module contains the customizable definition of `CallExprBase` and should not - * be referenced directly. - */ -module Impl { - private import rust - private import codeql.rust.internal.TypeInference as TypeInference - - // the following QLdoc is generated: if you need to edit it, do it in the schema file - /** - * A function or method call expression. See `CallExpr` and `MethodCallExpr` for further details. - */ - class CallExprBase extends Generated::CallExprBase { - /** Gets the static target (function or tuple struct/variant) of this call, if any. */ - final Addressable getStaticTarget() { result = TypeInference::resolveCallTarget(this) } - - override Expr getArg(int index) { result = this.getArgList().getArg(index) } - } -} diff --git a/rust/ql/lib/codeql/rust/elements/internal/CallExprImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/CallExprImpl.qll index 5723e1fdbb5..3de75d6bdc2 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/CallExprImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/CallExprImpl.qll @@ -5,7 +5,6 @@ */ private import codeql.rust.elements.internal.generated.CallExpr -private import codeql.rust.elements.PathExpr /** * INTERNAL: This module contains the customizable definition of `CallExpr` and should not @@ -13,7 +12,10 @@ private import codeql.rust.elements.PathExpr */ module Impl { private import rust + private import codeql.rust.elements.internal.InvocationExprImpl::Impl as InvocationExprImpl + private import codeql.rust.elements.internal.CallImpl::Impl as CallImpl private import codeql.rust.internal.PathResolution as PathResolution + private import codeql.rust.internal.TypeInference as TypeInference pragma[nomagic] Path getFunctionPath(CallExpr ce) { result = ce.getFunction().(PathExpr).getPath() } @@ -23,9 +25,37 @@ module Impl { result = PathResolution::resolvePath(getFunctionPath(ce)) } + private Expr getSyntacticArg(CallExpr ce, int i) { result = ce.getArgList().getArg(i) } + // the following QLdoc is generated: if you need to edit it, do it in the schema file /** - * A function call expression. For example: + * NOTE: Consider using `Call` instead, as that excludes call expressions that are + * instantiations of tuple structs and tuple variants. + * + * A call expression. For example: + * ```rust + * foo(42); + * foo::(42); + * foo[0](42); + * Option::Some(42); // tuple variant instantiation + * ``` + */ + class CallExpr extends Generated::CallExpr, InvocationExprImpl::InvocationExpr { + override string toStringImpl() { result = this.getFunction().toAbbreviatedString() + "(...)" } + + override Expr getSyntacticPositionalArgument(int i) { result = getSyntacticArg(this, i) } + + // todo: remove once internal query has been updated + Expr getArg(int i) { result = getSyntacticArg(this, i) } + + // todo: remove once internal query has been updated + int getNumberOfArgs() { result = this.getNumberOfSyntacticArguments() } + } + + /** + * A call expression that is _not_ an instantiation of a tuple struct or a tuple variant. + * + * For example: * ```rust * foo(42); * foo::(42); @@ -33,33 +63,102 @@ module Impl { * foo(1) = 4; * ``` */ - class CallExpr extends Generated::CallExpr { - override string toStringImpl() { result = this.getFunction().toAbbreviatedString() + "(...)" } - - /** Gets the struct that this call resolves to, if any. */ - Struct getStruct() { result = getResolvedFunction(this) } - - /** Gets the variant that this call resolves to, if any. */ - Variant getVariant() { result = getResolvedFunction(this) } - - pragma[nomagic] - private PathResolution::ItemNode getResolvedFunctionAndPos(int pos) { - result = getResolvedFunction(this) and - exists(this.getArg(pos)) + class CallExprCall extends CallExpr, CallImpl::Call { + CallExprCall() { + not this instanceof TupleStructExpr and + not this instanceof TupleVariantExpr } - /** - * Gets the tuple field that matches the `pos`th argument of this call, if any. - * - * For example, if this call is `Option::Some(42)`, then the tuple field matching - * `42` is the first field of `Option::Some`. - */ - pragma[nomagic] - TupleField getTupleField(int pos) { - exists(PathResolution::ItemNode i | i = this.getResolvedFunctionAndPos(pos) | - result.isStructField(i, pos) or - result.isVariantField(i, pos) + override Expr getPositionalArgument(int i) { result = getSyntacticArg(this, i) } + } + + /** + * A call expression that targets a closure (or any value that implements + * `Fn`, `FnMut`, or `FnOnce`). + * + * Dynamic calls never have a static target, and the set of potential + * run-time targets is only available internally to the data flow library. + */ + class DynamicCallExpr extends CallExprCall { + DynamicCallExpr() { + exists(Expr f | f = this.getFunction() | + // All calls to complex expressions and local variable accesses are lambda calls + f instanceof PathExpr implies f = any(Variable v).getAnAccess() ) } } + + /** + * A call expression that is a _potential_ method call. + * + * Note: In order to prevent the AST layer from relying on the type inference + * layer, we do not check that the resolved target is a method in the charpred, + * instead we check this in `getPositionalArgument` and `getReceiver`. + */ + class CallExprMethodCall extends CallImpl::MethodCall instanceof CallExprCall { + CallExprMethodCall() { not this instanceof DynamicCallExpr } + + private predicate isInFactMethodCall() { this.getResolvedTarget() instanceof Method } + + override Expr getPositionalArgument(int i) { + if this.isInFactMethodCall() + then result = getSyntacticArg(this, i + 1) + else result = getSyntacticArg(this, i) + } + + override Expr getReceiver() { + this.isInFactMethodCall() and + result = getSyntacticArg(this, 0) + } + } + + /** + * A call expression that instantiates a tuple struct. + * + * For example: + * ```rust + * struct S(u32, u64); + * let s = S(42, 84); + * ``` + */ + class TupleStructExpr extends CallExpr { + private Struct struct; + + TupleStructExpr() { struct = getResolvedFunction(this) } + + /** Gets the struct that is instantiated. */ + Struct getStruct() { result = struct } + + /** Gets the `i`th tuple field of the instantiated struct. */ + pragma[nomagic] + TupleField getTupleField(int i) { result = this.getStruct().getTupleField(i) } + + override string getAPrimaryQlClass() { result = "TupleStructExpr" } + } + + /** + * A call expression that instantiates a tuple variant. + * + * For example: + * ```rust + * enum E { + * V(u32, u64), + * } + * let e = E::V(42, 84); + * ``` + */ + class TupleVariantExpr extends CallExpr { + private Variant variant; + + TupleVariantExpr() { variant = getResolvedFunction(this) } + + /** Gets the variant that is instantiated. */ + Variant getVariant() { result = variant } + + /** Gets the `i`th tuple field of the instantiated variant. */ + pragma[nomagic] + TupleField getTupleField(int i) { result = this.getVariant().getTupleField(i) } + + override string getAPrimaryQlClass() { result = "TupleVariantExpr" } + } } diff --git a/rust/ql/lib/codeql/rust/elements/internal/CallImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/CallImpl.qll index 71c6cfbffc0..ae01736f9fa 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/CallImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/CallImpl.qll @@ -1,69 +1,79 @@ private import rust -private import codeql.rust.internal.PathResolution -private import codeql.rust.internal.TypeInference as TypeInference -private import codeql.rust.elements.internal.ExprImpl::Impl as ExprImpl -private import codeql.rust.elements.Operation module Impl { - newtype TArgumentPosition = - TPositionalArgumentPosition(int i) { - i in [0 .. max([any(ParamList l).getNumberOfParams(), any(ArgList l).getNumberOfArgs()]) - 1] - } or - TSelfArgumentPosition() - - /** An argument position in a call. */ - class ArgumentPosition extends TArgumentPosition { - /** Gets the index of the argument in the call, if this is a positional argument. */ - int asPosition() { this = TPositionalArgumentPosition(result) } - - /** Holds if this call position is a self argument. */ - predicate isSelf() { this instanceof TSelfArgumentPosition } - - /** Gets a string representation of this argument position. */ - string toString() { - result = this.asPosition().toString() - or - this.isSelf() and result = "self" - } - } + private import codeql.rust.internal.TypeInference as TypeInference + private import codeql.rust.elements.internal.ExprImpl::Impl as ExprImpl + private import codeql.rust.elements.internal.InvocationExprImpl::Impl as InvocationExprImpl /** - * An expression that calls a function. + * A call. * - * This class abstracts over the different ways in which a function can be - * called in Rust. + * Either + * + * - a `CallExpr` that is _not_ an instantiation of a tuple struct or a tuple variant, + * - a `MethodCallExpr`, + * - an `Operation` that targets an overloadable operator, or + * - an `IndexExpr`. */ - abstract class Call extends ExprImpl::Expr { - /** Holds if the receiver of this call is implicitly borrowed. */ - predicate receiverImplicitlyBorrowed() { this.implicitBorrowAt(TSelfArgumentPosition(), _) } + abstract class Call extends InvocationExprImpl::InvocationExpr { + /** + * Gets the argument at position `pos` of this call. + * + * Examples: + * ```rust + * foo(42, "bar"); // `42` is argument 0 and `"bar"` is argument 1 + * foo.bar(42); // `foo` is receiver and `42` is argument 0 + * Foo::bar(foo, 42); // `foo` is receiver and `42` is argument 0 + * x + y; // `x` is receiver and `y` is argument 0 + * -x; // `x` is receiver + * x[y]; // `x` is receiver and `y` is argument 0 + * ``` + */ + final Expr getArgument(ArgumentPosition pos) { + result = this.getPositionalArgument(pos.asPosition()) + or + pos.isSelf() and + result = this.(MethodCall).getReceiver() + } - /** Gets the trait targeted by this call, if any. */ - abstract Trait getTrait(); + /** Gets an argument of this call. */ + Expr getAnArgument() { result = this.getArgument(_) } - /** Holds if this call targets a trait. */ - predicate hasTrait() { exists(this.getTrait()) } + // todo: remove once internal query has been updated + Expr getReceiver() { none() } - /** Gets the name of the method called if this call is a method call. */ - abstract string getMethodName(); + /** + * Gets the `i`th positional argument of this call. + * + * Examples: + * ```rust + * foo(42, "bar"); // `42` is argument 0 and `"bar"` is argument 1 + * foo.bar(42); // `42` is argument 0 + * Foo::bar(foo, 42); // `42` is argument 0 + * x + y; // `y` is argument 0 + * -x; // no positional arguments + * x[y]; // `y` is argument 0 + * ``` + */ + Expr getPositionalArgument(int i) { none() } - /** Gets the argument at the given position, if any. */ - abstract Expr getArgument(ArgumentPosition pos); + /** Gets a positional argument of this expression. */ + Expr getAPositionalArgument() { result = this.getPositionalArgument(_) } - /** Holds if the argument at `pos` might be implicitly borrowed. */ - abstract predicate implicitBorrowAt(ArgumentPosition pos, boolean certain); + /** Gets the number of positional arguments of this expression. */ + int getNumberOfPositionalArguments() { + result = count(Expr arg | arg = this.getPositionalArgument(_)) + } - /** Gets the number of arguments _excluding_ any `self` argument. */ - int getNumberOfArguments() { result = count(this.getArgument(TPositionalArgumentPosition(_))) } - - /** Gets the `i`th argument of this call, if any. */ - Expr getPositionalArgument(int i) { result = this.getArgument(TPositionalArgumentPosition(i)) } - - /** Gets the receiver of this call if it is a method call. */ - Expr getReceiver() { result = this.getArgument(TSelfArgumentPosition()) } - - /** Gets the static target of this call, if any. */ + /** Gets the resolved target of this call, if any. */ Function getStaticTarget() { result = TypeInference::resolveCallTarget(this) } + /** Gets the name of the function called, if any. */ + string getTargetName() { result = this.getStaticTarget().getName().getText() } + + // todo: remove once internal query has been updated + string getMethodName() { result = this.getTargetName() } + /** Gets a runtime target of this call, if any. */ pragma[nomagic] Function getARuntimeTarget() { @@ -76,134 +86,30 @@ module Impl { } } - private predicate callHasQualifier(CallExpr call, Path path, Path qualifier) { - path = call.getFunction().(PathExpr).getPath() and - qualifier = path.getQualifier() - } - - private predicate callHasTraitQualifier(CallExpr call, Trait qualifier) { - exists(PathExt qualifierPath | - callHasQualifier(call, _, qualifierPath) and - qualifier = resolvePath(qualifierPath) and - // When the qualifier is `Self` and resolves to a trait, it's inside a - // trait method's default implementation. This is not a dispatch whose - // target is inferred from the type of the receiver, but should always - // resolve to the function in the trait block as path resolution does. - not qualifierPath.isUnqualified("Self") - ) - } - - /** Holds if the call expression dispatches to a method. */ - private predicate callIsMethodCall( - CallExpr call, Path qualifier, string methodName, boolean selfIsRef - ) { - exists(Path path, Function f | - callHasQualifier(call, path, qualifier) and - f = resolvePath(path) and - path.getSegment().getIdentifier().getText() = methodName and - exists(SelfParam self | - self = f.getSelfParam() and - if self.isRef() then selfIsRef = true else selfIsRef = false - ) - ) - } - - class CallExprCall extends Call instanceof CallExpr { - CallExprCall() { not callIsMethodCall(this, _, _, _) } - - override string getMethodName() { none() } - - override Trait getTrait() { callHasTraitQualifier(this, result) } - - override predicate implicitBorrowAt(ArgumentPosition pos, boolean certain) { none() } - - override Expr getArgument(ArgumentPosition pos) { - result = super.getArgList().getArg(pos.asPosition()) - } - } - - class CallExprMethodCall extends Call instanceof CallExpr { - string methodName; - boolean selfIsRef; - - CallExprMethodCall() { callIsMethodCall(this, _, methodName, selfIsRef) } - + /** + * A method call. + * + * Either + * + * - a `CallExpr` where we can resolve the target as a method, + * - a `MethodCallExpr`, + * - an `Operation` that targets an overloadable operator, or + * - an `IndexExpr`. + */ + abstract class MethodCall extends Call { /** - * Holds if this call must have an explicit borrow for the `self` argument, - * because the corresponding parameter is `&self`. Explicit borrows are not - * needed when using method call syntax. + * Gets the receiver of this method call. + * + * Examples: + * ```rust + * foo(42, "bar"); // no receiver + * foo.bar(42); // `foo` is receiver + * Foo::bar(foo, 42); // `foo` is receiver + * x + y; // `x` is receiver + * -x; // `x` is receiver + * x[y]; // `x` is receiver + * ``` */ - predicate hasExplicitSelfBorrow() { selfIsRef = true } - - override string getMethodName() { result = methodName } - - override Trait getTrait() { callHasTraitQualifier(this, result) } - - override predicate implicitBorrowAt(ArgumentPosition pos, boolean certain) { none() } - - override Expr getArgument(ArgumentPosition pos) { - pos.isSelf() and result = super.getArgList().getArg(0) - or - result = super.getArgList().getArg(pos.asPosition() + 1) - } - } - - private class MethodCallExprCall extends Call instanceof MethodCallExpr { - override string getMethodName() { result = super.getIdentifier().getText() } - - override Trait getTrait() { none() } - - override predicate implicitBorrowAt(ArgumentPosition pos, boolean certain) { - pos.isSelf() and certain = false - } - - override Expr getArgument(ArgumentPosition pos) { - pos.isSelf() and result = this.(MethodCallExpr).getReceiver() - or - result = super.getArgList().getArg(pos.asPosition()) - } - } - - private class OperatorCall extends Call instanceof Operation { - Trait trait; - string methodName; - int borrows; - - OperatorCall() { super.isOverloaded(trait, methodName, borrows) } - - override string getMethodName() { result = methodName } - - override Trait getTrait() { result = trait } - - override predicate implicitBorrowAt(ArgumentPosition pos, boolean certain) { - ( - pos.isSelf() and borrows >= 1 - or - pos.asPosition() = 0 and borrows = 2 - ) and - certain = true - } - - override Expr getArgument(ArgumentPosition pos) { - pos.isSelf() and result = super.getOperand(0) - or - pos.asPosition() = 0 and result = super.getOperand(1) - } - } - - private class IndexCall extends Call instanceof IndexExpr { - override string getMethodName() { result = "index" } - - override Trait getTrait() { result.getCanonicalPath() = "core::ops::index::Index" } - - override predicate implicitBorrowAt(ArgumentPosition pos, boolean certain) { - pos.isSelf() and certain = true - } - - override Expr getArgument(ArgumentPosition pos) { - pos.isSelf() and result = super.getBase() - or - pos.asPosition() = 0 and result = super.getIndex() - } + override Expr getReceiver() { none() } } } diff --git a/rust/ql/lib/codeql/rust/elements/internal/IndexExprImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/IndexExprImpl.qll index 66c33b4a0b1..f5336497e28 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/IndexExprImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/IndexExprImpl.qll @@ -4,6 +4,7 @@ * INTERNAL: Do not use. */ +private import rust private import codeql.rust.elements.internal.generated.IndexExpr /** @@ -11,6 +12,8 @@ private import codeql.rust.elements.internal.generated.IndexExpr * be referenced directly. */ module Impl { + private import codeql.rust.elements.internal.CallImpl::Impl as CallImpl + // the following QLdoc is generated: if you need to edit it, do it in the schema file /** * An index expression. For example: @@ -19,10 +22,20 @@ module Impl { * list[42] = 1; * ``` */ - class IndexExpr extends Generated::IndexExpr { + class IndexExpr extends Generated::IndexExpr, CallImpl::MethodCall { override string toStringImpl() { result = this.getBase().toAbbreviatedString() + "[" + this.getIndex().toAbbreviatedString() + "]" } + + override Expr getSyntacticPositionalArgument(int i) { + i = 0 and result = this.getBase() + or + i = 1 and result = this.getIndex() + } + + override Expr getPositionalArgument(int i) { i = 0 and result = this.getIndex() } + + override Expr getReceiver() { result = this.getBase() } } } diff --git a/rust/ql/lib/codeql/rust/elements/internal/InvocationExprImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/InvocationExprImpl.qll new file mode 100644 index 00000000000..f3cf32248e1 --- /dev/null +++ b/rust/ql/lib/codeql/rust/elements/internal/InvocationExprImpl.qll @@ -0,0 +1,99 @@ +private import rust + +module Impl { + private import codeql.rust.internal.TypeInference as TypeInference + private import codeql.rust.elements.internal.ExprImpl::Impl as ExprImpl + + private newtype TArgumentPosition = + TPositionalArgumentPosition(int i) { + i in [0 .. max([any(ParamList l).getNumberOfParams(), any(ArgList l).getNumberOfArgs()]) - 1] + } or + TSelfArgumentPosition() + + /** An argument position in a call. */ + class ArgumentPosition extends TArgumentPosition { + /** Gets the index of the argument in the call, if this is a positional argument. */ + int asPosition() { this = TPositionalArgumentPosition(result) } + + /** Holds if this call position is a self argument. */ + predicate isSelf() { this instanceof TSelfArgumentPosition } + + /** Gets a string representation of this argument position. */ + string toString() { + result = this.asPosition().toString() + or + this.isSelf() and result = "self" + } + } + + /** + * An expression with arguments. + * + * Either a `CallExpr`, a `MethodCallExpr`, an `Operation`, or an `IndexExpr`. + */ + abstract class InvocationExpr extends ExprImpl::Expr { + /** + * Gets the `i`th syntactical argument of this expression. + * + * Examples: + * ```rust + * foo(42, "bar"); // `42` is syntactic argument 0 and `"bar"` is syntactic argument 1 + * foo.bar(42); // `42` is syntactic argument 0 + * Foo::bar(foo, 42); // `foo` is syntactic argument 0 and `42` is syntactic argument 1 + * Option::Some(x); // `x` is syntactic argument 0 + * x + y; // `x` is syntactic argument 0 and `y` is syntactic argument 1 + * -x; // `x` is syntactic argument 0 + * x[y]; // `x` is syntactic argument 0 and `y` is syntactic argument 1 + * ``` + */ + Expr getSyntacticPositionalArgument(int i) { none() } + + /** + * Gets the syntactic receiver of this expression, if any. + * + * Examples: + * ```rust + * foo(42, "bar"); // no syntactic receiver + * foo.bar(42); // `foo` is syntactic receiver + * Foo::bar(foo, 42); // no syntactic receiver + * Option::Some(x); // no syntactic receiver + * x + y; // no syntactic receiver + * -x; // no syntactic receiver + * x[y]; // no syntactic receiver + * ``` + */ + Expr getSyntacticReceiver() { none() } + + /** + * Gets the argument at syntactic position `pos` of this expression. + * + * Examples: + * ```rust + * foo(42, "bar"); // `42` is syntactic argument 0 and `"bar"` is syntactic argument 1 + * foo.bar(42); // `foo` is syntactic receiver and `42` is syntactic argument 0 + * Foo::bar(foo, 42); // `foo` is syntactic argument 0 and `42` is syntactic argument 1 + * Option::Some(x); // `x` is syntactic argument 0 + * x + y; // `x` is syntactic argument 0 and `y` is syntactic argument 1 + * -x; // `x` is syntactic argument 0 + * x[y]; // `x` is syntactic argument 0 and `y` is syntactic argument 1 + * ``` + */ + final Expr getSyntacticArgument(ArgumentPosition pos) { + result = this.getSyntacticPositionalArgument(pos.asPosition()) + or + pos.isSelf() and + result = this.getSyntacticReceiver() + } + + /** Gets a syntactic argument of this expression. */ + Expr getASyntacticArgument() { result = this.getSyntacticArgument(_) } + + /** Gets the number of syntactic arguments of this expression. */ + int getNumberOfSyntacticArguments() { + result = count(Expr arg | arg = this.getSyntacticArgument(_)) + } + + /** Gets the resolved target (function or tuple struct/variant), if any. */ + Addressable getResolvedTarget() { result = TypeInference::resolveCallTarget(this) } + } +} diff --git a/rust/ql/lib/codeql/rust/elements/internal/MethodCallExprImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/MethodCallExprImpl.qll index 7617ae456bb..d5fa29b26b2 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/MethodCallExprImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/MethodCallExprImpl.qll @@ -12,15 +12,22 @@ private import codeql.rust.elements.internal.generated.MethodCallExpr * be referenced directly. */ module Impl { + private import codeql.rust.elements.internal.CallImpl::Impl as CallImpl + private import codeql.rust.elements.internal.InvocationExprImpl::Impl as InvocationExprImpl + // the following QLdoc is generated: if you need to edit it, do it in the schema file /** + * NOTE: Consider using `MethodCall` instead, as that also includes calls to methods using + * call syntax (such as `Foo::method(x)`), operation syntax (such as `x + y`), and + * indexing syntax (such as `x[y]`). + * * A method call expression. For example: * ```rust * x.foo(42); * x.foo::(42); * ``` */ - class MethodCallExpr extends Generated::MethodCallExpr { + class MethodCallExpr extends Generated::MethodCallExpr, CallImpl::MethodCall { private string toStringPart(int index) { index = 0 and result = this.getReceiver().toAbbreviatedString() @@ -39,7 +46,12 @@ module Impl { result = strictconcat(int i | | this.toStringPart(i) order by i) } - /** Gets the static target of this method call, if any. */ - final Function getStaticTarget() { result = super.getStaticTarget() } + override Expr getSyntacticPositionalArgument(int i) { result = this.getArgList().getArg(i) } + + override Expr getSyntacticReceiver() { result = Generated::MethodCallExpr.super.getReceiver() } + + override Expr getPositionalArgument(int i) { result = this.getArgList().getArg(i) } + + override Expr getReceiver() { result = Generated::MethodCallExpr.super.getReceiver() } } } diff --git a/rust/ql/lib/codeql/rust/elements/internal/OperationImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/OperationImpl.qll index f22c95759d6..58dcdeb481f 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/OperationImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/OperationImpl.qll @@ -7,100 +7,116 @@ private import rust private import codeql.rust.elements.internal.ExprImpl::Impl as ExprImpl -/** - * Holds if the operator `op` with arity `arity` is overloaded to a trait with - * the canonical path `path` and the method name `method`, and if it borrows its - * first `borrows` arguments. - */ -predicate isOverloaded(string op, int arity, string path, string method, int borrows) { - arity = 1 and - ( - // Negation - op = "-" and path = "core::ops::arith::Neg" and method = "neg" and borrows = 0 - or - // Not - op = "!" and path = "core::ops::bit::Not" and method = "not" and borrows = 0 - or - // Dereference - op = "*" and path = "core::ops::deref::Deref" and method = "deref" and borrows = 1 - ) - or - arity = 2 and - ( - // Comparison operators - op = "==" and path = "core::cmp::PartialEq" and method = "eq" and borrows = 2 - or - op = "!=" and path = "core::cmp::PartialEq" and method = "ne" and borrows = 2 - or - op = "<" and path = "core::cmp::PartialOrd" and method = "lt" and borrows = 2 - or - op = "<=" and path = "core::cmp::PartialOrd" and method = "le" and borrows = 2 - or - op = ">" and path = "core::cmp::PartialOrd" and method = "gt" and borrows = 2 - or - op = ">=" and path = "core::cmp::PartialOrd" and method = "ge" and borrows = 2 - or - // Arithmetic operators - op = "+" and path = "core::ops::arith::Add" and method = "add" and borrows = 0 - or - op = "-" and path = "core::ops::arith::Sub" and method = "sub" and borrows = 0 - or - op = "*" and path = "core::ops::arith::Mul" and method = "mul" and borrows = 0 - or - op = "/" and path = "core::ops::arith::Div" and method = "div" and borrows = 0 - or - op = "%" and path = "core::ops::arith::Rem" and method = "rem" and borrows = 0 - or - // Arithmetic assignment expressions - op = "+=" and path = "core::ops::arith::AddAssign" and method = "add_assign" and borrows = 1 - or - op = "-=" and path = "core::ops::arith::SubAssign" and method = "sub_assign" and borrows = 1 - or - op = "*=" and path = "core::ops::arith::MulAssign" and method = "mul_assign" and borrows = 1 - or - op = "/=" and path = "core::ops::arith::DivAssign" and method = "div_assign" and borrows = 1 - or - op = "%=" and path = "core::ops::arith::RemAssign" and method = "rem_assign" and borrows = 1 - or - // Bitwise operators - op = "&" and path = "core::ops::bit::BitAnd" and method = "bitand" and borrows = 0 - or - op = "|" and path = "core::ops::bit::BitOr" and method = "bitor" and borrows = 0 - or - op = "^" and path = "core::ops::bit::BitXor" and method = "bitxor" and borrows = 0 - or - op = "<<" and path = "core::ops::bit::Shl" and method = "shl" and borrows = 0 - or - op = ">>" and path = "core::ops::bit::Shr" and method = "shr" and borrows = 0 - or - // Bitwise assignment operators - op = "&=" and path = "core::ops::bit::BitAndAssign" and method = "bitand_assign" and borrows = 1 - or - op = "|=" and path = "core::ops::bit::BitOrAssign" and method = "bitor_assign" and borrows = 1 - or - op = "^=" and path = "core::ops::bit::BitXorAssign" and method = "bitxor_assign" and borrows = 1 - or - op = "<<=" and path = "core::ops::bit::ShlAssign" and method = "shl_assign" and borrows = 1 - or - op = ">>=" and path = "core::ops::bit::ShrAssign" and method = "shr_assign" and borrows = 1 - ) -} - /** * INTERNAL: This module contains the customizable definition of `Operation` and should not * be referenced directly. */ module Impl { + private import codeql.rust.elements.internal.CallImpl::Impl as CallImpl + private import codeql.rust.elements.internal.InvocationExprImpl::Impl as InvocationExprImpl + + /** + * Holds if the operator `op` with arity `arity` is overloaded to a trait with + * the canonical path `path` and the method name `method`, and if it borrows its + * first `borrows` arguments. + */ + predicate isOverloaded(string op, int arity, string path, string method, int borrows) { + arity = 1 and + ( + // Negation + op = "-" and path = "core::ops::arith::Neg" and method = "neg" and borrows = 0 + or + // Not + op = "!" and path = "core::ops::bit::Not" and method = "not" and borrows = 0 + or + // Dereference + op = "*" and path = "core::ops::deref::Deref" and method = "deref" and borrows = 1 + ) + or + arity = 2 and + ( + // Comparison operators + op = "==" and path = "core::cmp::PartialEq" and method = "eq" and borrows = 2 + or + op = "!=" and path = "core::cmp::PartialEq" and method = "ne" and borrows = 2 + or + op = "<" and path = "core::cmp::PartialOrd" and method = "lt" and borrows = 2 + or + op = "<=" and path = "core::cmp::PartialOrd" and method = "le" and borrows = 2 + or + op = ">" and path = "core::cmp::PartialOrd" and method = "gt" and borrows = 2 + or + op = ">=" and path = "core::cmp::PartialOrd" and method = "ge" and borrows = 2 + or + // Arithmetic operators + op = "+" and path = "core::ops::arith::Add" and method = "add" and borrows = 0 + or + op = "-" and path = "core::ops::arith::Sub" and method = "sub" and borrows = 0 + or + op = "*" and path = "core::ops::arith::Mul" and method = "mul" and borrows = 0 + or + op = "/" and path = "core::ops::arith::Div" and method = "div" and borrows = 0 + or + op = "%" and path = "core::ops::arith::Rem" and method = "rem" and borrows = 0 + or + // Arithmetic assignment expressions + op = "+=" and path = "core::ops::arith::AddAssign" and method = "add_assign" and borrows = 1 + or + op = "-=" and path = "core::ops::arith::SubAssign" and method = "sub_assign" and borrows = 1 + or + op = "*=" and path = "core::ops::arith::MulAssign" and method = "mul_assign" and borrows = 1 + or + op = "/=" and path = "core::ops::arith::DivAssign" and method = "div_assign" and borrows = 1 + or + op = "%=" and path = "core::ops::arith::RemAssign" and method = "rem_assign" and borrows = 1 + or + // Bitwise operators + op = "&" and path = "core::ops::bit::BitAnd" and method = "bitand" and borrows = 0 + or + op = "|" and path = "core::ops::bit::BitOr" and method = "bitor" and borrows = 0 + or + op = "^" and path = "core::ops::bit::BitXor" and method = "bitxor" and borrows = 0 + or + op = "<<" and path = "core::ops::bit::Shl" and method = "shl" and borrows = 0 + or + op = ">>" and path = "core::ops::bit::Shr" and method = "shr" and borrows = 0 + or + // Bitwise assignment operators + op = "&=" and + path = "core::ops::bit::BitAndAssign" and + method = "bitand_assign" and + borrows = 1 + or + op = "|=" and path = "core::ops::bit::BitOrAssign" and method = "bitor_assign" and borrows = 1 + or + op = "^=" and + path = "core::ops::bit::BitXorAssign" and + method = "bitxor_assign" and + borrows = 1 + or + op = "<<=" and path = "core::ops::bit::ShlAssign" and method = "shl_assign" and borrows = 1 + or + op = ">>=" and path = "core::ops::bit::ShrAssign" and method = "shr_assign" and borrows = 1 + ) + } + /** * An operation, for example `&&`, `+=`, `!` or `*`. + * + * Overloadable operations are syntatic sugar for method calls, where the + * first operand is the receiver. For example, `x + y` is syntactic sugar + * for `Add::add(x, y)`, and `x += y` is syntactic sugar for + * `AddAssign::add_assign(&mut x, y)`. */ - abstract class Operation extends ExprImpl::Expr { + abstract class Operation extends InvocationExprImpl::InvocationExpr { /** Gets the operator name of this operation, if it exists. */ abstract string getOperatorName(); /** Gets the `n`th operand of this operation, if any. */ abstract Expr getOperand(int n); + override Expr getSyntacticPositionalArgument(int i) { result = this.getOperand(i) } + /** * Gets the number of operands of this operation. * @@ -120,4 +136,12 @@ module Impl { methodName, borrows) } } + + private class OperationMethodCall extends CallImpl::MethodCall instanceof Operation { + OperationMethodCall() { super.isOverloaded(_, _, _) } + + override Expr getPositionalArgument(int i) { result = super.getOperand(i + 1) } + + override Expr getReceiver() { result = super.getOperand(0) } + } } diff --git a/rust/ql/lib/codeql/rust/elements/internal/StructExprImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/StructExprImpl.qll index 5cbeb62c7a4..d7704894c49 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/StructExprImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/StructExprImpl.qll @@ -27,6 +27,16 @@ module Impl { class StructExpr extends Generated::StructExpr { override string toStringImpl() { result = this.getPath().toStringImpl() + " {...}" } + private PathResolution::ItemNode getResolvedPath() { + result = PathResolution::resolvePath(this.getPath()) + } + + /** Gets the struct that is instantiated, if any. */ + Struct getStruct() { result = this.getResolvedPath() } + + /** Gets the variant that is instantiated, if any. */ + Variant getVariant() { result = this.getResolvedPath() } + /** Gets the record expression for the field `name`. */ pragma[nomagic] StructExprField getFieldExpr(string name) { @@ -34,19 +44,11 @@ module Impl { name = result.getFieldName() } - pragma[nomagic] - private PathResolution::ItemNode getResolvedPath(string name) { - result = PathResolution::resolvePath(this.getPath()) and - exists(this.getFieldExpr(name)) - } - - /** Gets the record field that matches the `name` field of this record expression. */ - pragma[nomagic] + /** Gets the record field named `name` of the instantiated struct or variant. */ StructField getStructField(string name) { - exists(PathResolution::ItemNode i | i = this.getResolvedPath(name) | - result.isStructField(i, name) or - result.isVariantField(i, name) - ) + result = this.getStruct().getStructField(name) + or + result = this.getVariant().getStructField(name) } } } diff --git a/rust/ql/lib/codeql/rust/elements/internal/TupleFieldImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/TupleFieldImpl.qll index 05d799b6047..f26c855e3cb 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/TupleFieldImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/TupleFieldImpl.qll @@ -15,7 +15,7 @@ module Impl { // the following QLdoc is generated: if you need to edit it, do it in the schema file /** - * A field in a tuple struct or tuple enum variant. + * A field in a tuple struct or tuple variant. * * For example: * ```rust diff --git a/rust/ql/lib/codeql/rust/elements/internal/TupleFieldListImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/TupleFieldListImpl.qll index 3b5964693f3..b52f0477987 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/TupleFieldListImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/TupleFieldListImpl.qll @@ -13,7 +13,7 @@ private import codeql.rust.elements.internal.generated.TupleFieldList */ module Impl { /** - * A list of fields in a tuple struct or tuple enum variant. + * A list of fields in a tuple struct or tuple variant. * * For example: * ```rust diff --git a/rust/ql/lib/codeql/rust/elements/internal/generated/CallExpr.qll b/rust/ql/lib/codeql/rust/elements/internal/generated/CallExpr.qll index 829de70510b..196b78c1bde 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/generated/CallExpr.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/generated/CallExpr.qll @@ -6,8 +6,10 @@ private import codeql.rust.elements.internal.generated.Synth private import codeql.rust.elements.internal.generated.Raw -import codeql.rust.elements.internal.CallExprBaseImpl::Impl as CallExprBaseImpl +import codeql.rust.elements.ArgList +import codeql.rust.elements.Attr import codeql.rust.elements.Expr +import codeql.rust.elements.internal.ExprImpl::Impl as ExprImpl /** * INTERNAL: This module contains the fully generated definition of `CallExpr` and should not @@ -15,19 +17,53 @@ import codeql.rust.elements.Expr */ module Generated { /** - * A function call expression. For example: + * NOTE: Consider using `Call` instead, as that excludes call expressions that are + * instantiations of tuple structs and tuple variants. + * + * A call expression. For example: * ```rust * foo(42); * foo::(42); * foo[0](42); - * foo(1) = 4; + * Option::Some(42); // tuple variant instantiation * ``` * INTERNAL: Do not reference the `Generated::CallExpr` class directly. * Use the subclass `CallExpr`, where the following predicates are available. */ - class CallExpr extends Synth::TCallExpr, CallExprBaseImpl::CallExprBase { + class CallExpr extends Synth::TCallExpr, ExprImpl::Expr { override string getAPrimaryQlClass() { result = "CallExpr" } + /** + * Gets the argument list of this call expression, if it exists. + */ + ArgList getArgList() { + result = + Synth::convertArgListFromRaw(Synth::convertCallExprToRaw(this).(Raw::CallExpr).getArgList()) + } + + /** + * Holds if `getArgList()` exists. + */ + final predicate hasArgList() { exists(this.getArgList()) } + + /** + * Gets the `index`th attr of this call expression (0-based). + */ + Attr getAttr(int index) { + result = + Synth::convertAttrFromRaw(Synth::convertCallExprToRaw(this).(Raw::CallExpr).getAttr(index)) + } + + /** + * Gets any of the attrs of this call expression. + */ + final Attr getAnAttr() { result = this.getAttr(_) } + + /** + * Gets the number of attrs of this call expression. + */ + final int getNumberOfAttrs() { result = count(int i | exists(this.getAttr(i))) } + /** * Gets the function of this call expression, if it exists. */ diff --git a/rust/ql/lib/codeql/rust/elements/internal/generated/CallExprBase.qll b/rust/ql/lib/codeql/rust/elements/internal/generated/CallExprBase.qll deleted file mode 100644 index 1d6364fb94f..00000000000 --- a/rust/ql/lib/codeql/rust/elements/internal/generated/CallExprBase.qll +++ /dev/null @@ -1,75 +0,0 @@ -// generated by codegen, do not edit -/** - * This module provides the generated definition of `CallExprBase`. - * INTERNAL: Do not import directly. - */ - -private import codeql.rust.elements.internal.generated.Synth -private import codeql.rust.elements.internal.generated.Raw -import codeql.rust.elements.ArgList -import codeql.rust.elements.Attr -import codeql.rust.elements.Expr -import codeql.rust.elements.internal.ExprImpl::Impl as ExprImpl - -/** - * INTERNAL: This module contains the fully generated definition of `CallExprBase` and should not - * be referenced directly. - */ -module Generated { - /** - * A function or method call expression. See `CallExpr` and `MethodCallExpr` for further details. - * INTERNAL: Do not reference the `Generated::CallExprBase` class directly. - * Use the subclass `CallExprBase`, where the following predicates are available. - */ - class CallExprBase extends Synth::TCallExprBase, ExprImpl::Expr { - /** - * Gets the argument list of this call expression base, if it exists. - */ - ArgList getArgList() { - result = - Synth::convertArgListFromRaw(Synth::convertCallExprBaseToRaw(this) - .(Raw::CallExprBase) - .getArgList()) - } - - /** - * Holds if `getArgList()` exists. - */ - final predicate hasArgList() { exists(this.getArgList()) } - - /** - * Gets the `index`th attr of this call expression base (0-based). - */ - Attr getAttr(int index) { - result = - Synth::convertAttrFromRaw(Synth::convertCallExprBaseToRaw(this) - .(Raw::CallExprBase) - .getAttr(index)) - } - - /** - * Gets any of the attrs of this call expression base. - */ - final Attr getAnAttr() { result = this.getAttr(_) } - - /** - * Gets the number of attrs of this call expression base. - */ - final int getNumberOfAttrs() { result = count(int i | exists(this.getAttr(i))) } - - /** - * Gets the `index`th argument of this call expression base (0-based). - */ - Expr getArg(int index) { none() } - - /** - * Gets any of the arguments of this call expression base. - */ - final Expr getAnArg() { result = this.getArg(_) } - - /** - * Gets the number of arguments of this call expression base. - */ - final int getNumberOfArgs() { result = count(int i | exists(this.getArg(i))) } - } -} diff --git a/rust/ql/lib/codeql/rust/elements/internal/generated/MethodCallExpr.qll b/rust/ql/lib/codeql/rust/elements/internal/generated/MethodCallExpr.qll index 8908b71b7af..18d6803211b 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/generated/MethodCallExpr.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/generated/MethodCallExpr.qll @@ -6,8 +6,10 @@ private import codeql.rust.elements.internal.generated.Synth private import codeql.rust.elements.internal.generated.Raw -import codeql.rust.elements.internal.CallExprBaseImpl::Impl as CallExprBaseImpl +import codeql.rust.elements.ArgList +import codeql.rust.elements.Attr import codeql.rust.elements.Expr +import codeql.rust.elements.internal.ExprImpl::Impl as ExprImpl import codeql.rust.elements.GenericArgList import codeql.rust.elements.NameRef @@ -17,6 +19,10 @@ import codeql.rust.elements.NameRef */ module Generated { /** + * NOTE: Consider using `MethodCall` instead, as that also includes calls to methods using + * call syntax (such as `Foo::method(x)`), operation syntax (such as `x + y`), and + * indexing syntax (such as `x[y]`). + * * A method call expression. For example: * ```rust * x.foo(42); @@ -25,9 +31,44 @@ module Generated { * INTERNAL: Do not reference the `Generated::MethodCallExpr` class directly. * Use the subclass `MethodCallExpr`, where the following predicates are available. */ - class MethodCallExpr extends Synth::TMethodCallExpr, CallExprBaseImpl::CallExprBase { + class MethodCallExpr extends Synth::TMethodCallExpr, ExprImpl::Expr { override string getAPrimaryQlClass() { result = "MethodCallExpr" } + /** + * Gets the argument list of this method call expression, if it exists. + */ + ArgList getArgList() { + result = + Synth::convertArgListFromRaw(Synth::convertMethodCallExprToRaw(this) + .(Raw::MethodCallExpr) + .getArgList()) + } + + /** + * Holds if `getArgList()` exists. + */ + final predicate hasArgList() { exists(this.getArgList()) } + + /** + * Gets the `index`th attr of this method call expression (0-based). + */ + Attr getAttr(int index) { + result = + Synth::convertAttrFromRaw(Synth::convertMethodCallExprToRaw(this) + .(Raw::MethodCallExpr) + .getAttr(index)) + } + + /** + * Gets any of the attrs of this method call expression. + */ + final Attr getAnAttr() { result = this.getAttr(_) } + + /** + * Gets the number of attrs of this method call expression. + */ + final int getNumberOfAttrs() { result = count(int i | exists(this.getAttr(i))) } + /** * Gets the generic argument list of this method call expression, if it exists. */ diff --git a/rust/ql/lib/codeql/rust/elements/internal/generated/ParentChild.qll b/rust/ql/lib/codeql/rust/elements/internal/generated/ParentChild.qll index 233c29e0173..9d6ec74a53e 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/generated/ParentChild.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/generated/ParentChild.qll @@ -1070,6 +1070,25 @@ private module Impl { ) } + private Element getImmediateChildOfCallExpr(CallExpr e, int index, string partialPredicateCall) { + exists(int n, int nArgList, int nAttr, int nFunction | + n = 0 and + nArgList = n + 1 and + nAttr = nArgList + e.getNumberOfAttrs() and + nFunction = nAttr + 1 and + ( + none() + or + index = n and result = e.getArgList() and partialPredicateCall = "ArgList()" + or + result = e.getAttr(index - nArgList) and + partialPredicateCall = "Attr(" + (index - nArgList).toString() + ")" + or + index = nAttr and result = e.getFunction() and partialPredicateCall = "Function()" + ) + ) + } + private Element getImmediateChildOfCastExpr(CastExpr e, int index, string partialPredicateCall) { exists(int n, int nAttr, int nExpr, int nTypeRepr | n = 0 and @@ -1563,6 +1582,37 @@ private module Impl { ) } + private Element getImmediateChildOfMethodCallExpr( + MethodCallExpr e, int index, string partialPredicateCall + ) { + exists(int n, int nArgList, int nAttr, int nGenericArgList, int nIdentifier, int nReceiver | + n = 0 and + nArgList = n + 1 and + nAttr = nArgList + e.getNumberOfAttrs() and + nGenericArgList = nAttr + 1 and + nIdentifier = nGenericArgList + 1 and + nReceiver = nIdentifier + 1 and + ( + none() + or + index = n and result = e.getArgList() and partialPredicateCall = "ArgList()" + or + result = e.getAttr(index - nArgList) and + partialPredicateCall = "Attr(" + (index - nArgList).toString() + ")" + or + index = nAttr and + result = e.getGenericArgList() and + partialPredicateCall = "GenericArgList()" + or + index = nGenericArgList and + result = e.getIdentifier() and + partialPredicateCall = "Identifier()" + or + index = nIdentifier and result = e.getReceiver() and partialPredicateCall = "Receiver()" + ) + ) + } + private Element getImmediateChildOfNameRef(NameRef e, int index, string partialPredicateCall) { none() } @@ -2228,25 +2278,6 @@ private module Impl { ) } - private Element getImmediateChildOfCallExpr(CallExpr e, int index, string partialPredicateCall) { - exists(int n, int nArgList, int nAttr, int nFunction | - n = 0 and - nArgList = n + 1 and - nAttr = nArgList + e.getNumberOfAttrs() and - nFunction = nAttr + 1 and - ( - none() - or - index = n and result = e.getArgList() and partialPredicateCall = "ArgList()" - or - result = e.getAttr(index - nArgList) and - partialPredicateCall = "Attr(" + (index - nArgList).toString() + ")" - or - index = nAttr and result = e.getFunction() and partialPredicateCall = "Function()" - ) - ) - } - private Element getImmediateChildOfExternBlock( ExternBlock e, int index, string partialPredicateCall ) { @@ -2421,37 +2452,6 @@ private module Impl { ) } - private Element getImmediateChildOfMethodCallExpr( - MethodCallExpr e, int index, string partialPredicateCall - ) { - exists(int n, int nArgList, int nAttr, int nGenericArgList, int nIdentifier, int nReceiver | - n = 0 and - nArgList = n + 1 and - nAttr = nArgList + e.getNumberOfAttrs() and - nGenericArgList = nAttr + 1 and - nIdentifier = nGenericArgList + 1 and - nReceiver = nIdentifier + 1 and - ( - none() - or - index = n and result = e.getArgList() and partialPredicateCall = "ArgList()" - or - result = e.getAttr(index - nArgList) and - partialPredicateCall = "Attr(" + (index - nArgList).toString() + ")" - or - index = nAttr and - result = e.getGenericArgList() and - partialPredicateCall = "GenericArgList()" - or - index = nGenericArgList and - result = e.getIdentifier() and - partialPredicateCall = "Identifier()" - or - index = nIdentifier and result = e.getReceiver() and partialPredicateCall = "Receiver()" - ) - ) - } - private Element getImmediateChildOfModule(Module e, int index, string partialPredicateCall) { exists( int n, int nAttributeMacroExpansion, int nAttr, int nItemList, int nName, int nVisibility @@ -3167,6 +3167,8 @@ private module Impl { or result = getImmediateChildOfBreakExpr(e, index, partialAccessor) or + result = getImmediateChildOfCallExpr(e, index, partialAccessor) + or result = getImmediateChildOfCastExpr(e, index, partialAccessor) or result = getImmediateChildOfClosureExpr(e, index, partialAccessor) @@ -3227,6 +3229,8 @@ private module Impl { or result = getImmediateChildOfMatchExpr(e, index, partialAccessor) or + result = getImmediateChildOfMethodCallExpr(e, index, partialAccessor) + or result = getImmediateChildOfNameRef(e, index, partialAccessor) or result = getImmediateChildOfNeverTypeRepr(e, index, partialAccessor) @@ -3311,8 +3315,6 @@ private module Impl { or result = getImmediateChildOfBlockExpr(e, index, partialAccessor) or - result = getImmediateChildOfCallExpr(e, index, partialAccessor) - or result = getImmediateChildOfExternBlock(e, index, partialAccessor) or result = getImmediateChildOfExternCrate(e, index, partialAccessor) @@ -3325,8 +3327,6 @@ private module Impl { or result = getImmediateChildOfMacroRules(e, index, partialAccessor) or - result = getImmediateChildOfMethodCallExpr(e, index, partialAccessor) - or result = getImmediateChildOfModule(e, index, partialAccessor) or result = getImmediateChildOfPathExpr(e, index, partialAccessor) diff --git a/rust/ql/lib/codeql/rust/elements/internal/generated/Raw.qll b/rust/ql/lib/codeql/rust/elements/internal/generated/Raw.qll index aff81e9b9ab..7682b4b99f4 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/generated/Raw.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/generated/Raw.qll @@ -1808,7 +1808,7 @@ module Raw { /** * INTERNAL: Do not use. - * A field in a tuple struct or tuple enum variant. + * A field in a tuple struct or tuple variant. * * For example: * ```rust @@ -2942,23 +2942,57 @@ module Raw { /** * INTERNAL: Do not use. - * A function or method call expression. See `CallExpr` and `MethodCallExpr` for further details. + * NOTE: Consider using `Call` instead, as that excludes call expressions that are + * instantiations of tuple structs and tuple variants. + * + * A call expression. For example: + * ```rust + * foo(42); + * foo::(42); + * foo[0](42); + * Option::Some(42); // tuple variant instantiation + * ``` */ - class CallExprBase extends @call_expr_base, Expr { - /** - * Gets the argument list of this call expression base, if it exists. - */ - ArgList getArgList() { call_expr_base_arg_lists(this, result) } + class CallExpr extends @call_expr, Expr { + override string toString() { result = "CallExpr" } /** - * Gets the `index`th attr of this call expression base (0-based). + * Gets the argument list of this call expression, if it exists. */ - Attr getAttr(int index) { call_expr_base_attrs(this, index, result) } + ArgList getArgList() { call_expr_arg_lists(this, result) } /** - * Gets the number of attrs of this call expression base. + * Gets the `index`th attr of this call expression (0-based). */ - int getNumberOfAttrs() { result = count(int i | call_expr_base_attrs(this, i, _)) } + Attr getAttr(int index) { call_expr_attrs(this, index, result) } + + /** + * Gets the number of attrs of this call expression. + */ + int getNumberOfAttrs() { result = count(int i | call_expr_attrs(this, i, _)) } + + /** + * Gets the function of this call expression, if it exists. + */ + Expr getFunction() { call_expr_functions(this, result) } + } + + private Element getImmediateChildOfCallExpr(CallExpr e, int index) { + exists(int n, int nArgList, int nAttr, int nFunction | + n = 0 and + nArgList = n + 1 and + nAttr = nArgList + e.getNumberOfAttrs() and + nFunction = nAttr + 1 and + ( + none() + or + index = n and result = e.getArgList() + or + result = e.getAttr(index - nArgList) + or + index = nAttr and result = e.getFunction() + ) + ) } /** @@ -4345,6 +4379,76 @@ module Raw { ) } + /** + * INTERNAL: Do not use. + * NOTE: Consider using `MethodCall` instead, as that also includes calls to methods using + * call syntax (such as `Foo::method(x)`), operation syntax (such as `x + y`), and + * indexing syntax (such as `x[y]`). + * + * A method call expression. For example: + * ```rust + * x.foo(42); + * x.foo::(42); + * ``` + */ + class MethodCallExpr extends @method_call_expr, Expr { + override string toString() { result = "MethodCallExpr" } + + /** + * Gets the argument list of this method call expression, if it exists. + */ + ArgList getArgList() { method_call_expr_arg_lists(this, result) } + + /** + * Gets the `index`th attr of this method call expression (0-based). + */ + Attr getAttr(int index) { method_call_expr_attrs(this, index, result) } + + /** + * Gets the number of attrs of this method call expression. + */ + int getNumberOfAttrs() { result = count(int i | method_call_expr_attrs(this, i, _)) } + + /** + * Gets the generic argument list of this method call expression, if it exists. + */ + GenericArgList getGenericArgList() { method_call_expr_generic_arg_lists(this, result) } + + /** + * Gets the identifier of this method call expression, if it exists. + */ + NameRef getIdentifier() { method_call_expr_identifiers(this, result) } + + /** + * Gets the receiver of this method call expression, if it exists. + */ + Expr getReceiver() { method_call_expr_receivers(this, result) } + } + + private Element getImmediateChildOfMethodCallExpr(MethodCallExpr e, int index) { + exists(int n, int nArgList, int nAttr, int nGenericArgList, int nIdentifier, int nReceiver | + n = 0 and + nArgList = n + 1 and + nAttr = nArgList + e.getNumberOfAttrs() and + nGenericArgList = nAttr + 1 and + nIdentifier = nGenericArgList + 1 and + nReceiver = nIdentifier + 1 and + ( + none() + or + index = n and result = e.getArgList() + or + result = e.getAttr(index - nArgList) + or + index = nAttr and result = e.getGenericArgList() + or + index = nGenericArgList and result = e.getIdentifier() + or + index = nIdentifier and result = e.getReceiver() + ) + ) + } + /** * INTERNAL: Do not use. * A reference to a name. @@ -5418,7 +5522,7 @@ module Raw { /** * INTERNAL: Do not use. - * A list of fields in a tuple struct or tuple enum variant. + * A list of fields in a tuple struct or tuple variant. * * For example: * ```rust @@ -6033,43 +6137,6 @@ module Raw { ) } - /** - * INTERNAL: Do not use. - * A function call expression. For example: - * ```rust - * foo(42); - * foo::(42); - * foo[0](42); - * foo(1) = 4; - * ``` - */ - class CallExpr extends @call_expr, CallExprBase { - override string toString() { result = "CallExpr" } - - /** - * Gets the function of this call expression, if it exists. - */ - Expr getFunction() { call_expr_functions(this, result) } - } - - private Element getImmediateChildOfCallExpr(CallExpr e, int index) { - exists(int n, int nArgList, int nAttr, int nFunction | - n = 0 and - nArgList = n + 1 and - nAttr = nArgList + e.getNumberOfAttrs() and - nFunction = nAttr + 1 and - ( - none() - or - index = n and result = e.getArgList() - or - result = e.getAttr(index - nArgList) - or - index = nAttr and result = e.getFunction() - ) - ) - } - /** * INTERNAL: Do not use. * An extern block containing foreign function declarations. @@ -6467,57 +6534,6 @@ module Raw { ) } - /** - * INTERNAL: Do not use. - * A method call expression. For example: - * ```rust - * x.foo(42); - * x.foo::(42); - * ``` - */ - class MethodCallExpr extends @method_call_expr, CallExprBase { - override string toString() { result = "MethodCallExpr" } - - /** - * Gets the generic argument list of this method call expression, if it exists. - */ - GenericArgList getGenericArgList() { method_call_expr_generic_arg_lists(this, result) } - - /** - * Gets the identifier of this method call expression, if it exists. - */ - NameRef getIdentifier() { method_call_expr_identifiers(this, result) } - - /** - * Gets the receiver of this method call expression, if it exists. - */ - Expr getReceiver() { method_call_expr_receivers(this, result) } - } - - private Element getImmediateChildOfMethodCallExpr(MethodCallExpr e, int index) { - exists(int n, int nArgList, int nAttr, int nGenericArgList, int nIdentifier, int nReceiver | - n = 0 and - nArgList = n + 1 and - nAttr = nArgList + e.getNumberOfAttrs() and - nGenericArgList = nAttr + 1 and - nIdentifier = nGenericArgList + 1 and - nReceiver = nIdentifier + 1 and - ( - none() - or - index = n and result = e.getArgList() - or - result = e.getAttr(index - nArgList) - or - index = nAttr and result = e.getGenericArgList() - or - index = nGenericArgList and result = e.getIdentifier() - or - index = nIdentifier and result = e.getReceiver() - ) - ) - } - /** * INTERNAL: Do not use. * A module declaration. For example: @@ -7907,6 +7923,8 @@ module Raw { or result = getImmediateChildOfBreakExpr(e, index) or + result = getImmediateChildOfCallExpr(e, index) + or result = getImmediateChildOfCastExpr(e, index) or result = getImmediateChildOfClosureExpr(e, index) @@ -7967,6 +7985,8 @@ module Raw { or result = getImmediateChildOfMatchExpr(e, index) or + result = getImmediateChildOfMethodCallExpr(e, index) + or result = getImmediateChildOfNameRef(e, index) or result = getImmediateChildOfNeverTypeRepr(e, index) @@ -8047,8 +8067,6 @@ module Raw { or result = getImmediateChildOfBlockExpr(e, index) or - result = getImmediateChildOfCallExpr(e, index) - or result = getImmediateChildOfExternBlock(e, index) or result = getImmediateChildOfExternCrate(e, index) @@ -8059,8 +8077,6 @@ module Raw { or result = getImmediateChildOfMacroRules(e, index) or - result = getImmediateChildOfMethodCallExpr(e, index) - or result = getImmediateChildOfModule(e, index) or result = getImmediateChildOfPathExpr(e, index) diff --git a/rust/ql/lib/codeql/rust/elements/internal/generated/Synth.qll b/rust/ql/lib/codeql/rust/elements/internal/generated/Synth.qll index 74b4a14460a..b5fc41677b2 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/generated/Synth.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/generated/Synth.qll @@ -729,11 +729,6 @@ module Synth { TTypeBoundList or TTypeRepr or TUseBoundGenericArg or TUseBoundGenericArgs or TUseTree or TUseTreeList or TVariantList or TVisibility or TWhereClause or TWherePred; - /** - * INTERNAL: Do not use. - */ - class TCallExprBase = TCallExpr or TMethodCallExpr; - /** * INTERNAL: Do not use. */ @@ -744,11 +739,11 @@ module Synth { */ class TExpr = TArrayExpr or TArrayExprInternal or TAsmExpr or TAwaitExpr or TBecomeExpr or TBinaryExpr or - TBreakExpr or TCallExprBase or TCastExpr or TClosureExpr or TContinueExpr or TFieldExpr or + TBreakExpr or TCallExpr or TCastExpr or TClosureExpr or TContinueExpr or TFieldExpr or TFormatArgsExpr or TIfExpr or TIndexExpr or TLabelableExpr or TLetExpr or TLiteralExpr or - TMacroBlockExpr or TMacroExpr or TMatchExpr or TOffsetOfExpr or TParenExpr or - TPathExprBase or TPrefixExpr or TRangeExpr or TRefExpr or TReturnExpr or TStructExpr or - TTryExpr or TTupleExpr or TUnderscoreExpr or TYeetExpr or TYieldExpr; + TMacroBlockExpr or TMacroExpr or TMatchExpr or TMethodCallExpr or TOffsetOfExpr or + TParenExpr or TPathExprBase or TPrefixExpr or TRangeExpr or TRefExpr or TReturnExpr or + TStructExpr or TTryExpr or TTupleExpr or TUnderscoreExpr or TYeetExpr or TYieldExpr; /** * INTERNAL: Do not use. @@ -2229,16 +2224,6 @@ module Synth { result = convertWherePredFromRaw(e) } - /** - * INTERNAL: Do not use. - * Converts a raw DB element to a synthesized `TCallExprBase`, if possible. - */ - TCallExprBase convertCallExprBaseFromRaw(Raw::Element e) { - result = convertCallExprFromRaw(e) - or - result = convertMethodCallExprFromRaw(e) - } - /** * INTERNAL: Do not use. * Converts a raw DB element to a synthesized `TCallable`, if possible. @@ -2282,7 +2267,7 @@ module Synth { or result = convertBreakExprFromRaw(e) or - result = convertCallExprBaseFromRaw(e) + result = convertCallExprFromRaw(e) or result = convertCastExprFromRaw(e) or @@ -2310,6 +2295,8 @@ module Synth { or result = convertMatchExprFromRaw(e) or + result = convertMethodCallExprFromRaw(e) + or result = convertOffsetOfExprFromRaw(e) or result = convertParenExprFromRaw(e) @@ -3805,16 +3792,6 @@ module Synth { result = convertWherePredToRaw(e) } - /** - * INTERNAL: Do not use. - * Converts a synthesized `TCallExprBase` to a raw DB element, if possible. - */ - Raw::Element convertCallExprBaseToRaw(TCallExprBase e) { - result = convertCallExprToRaw(e) - or - result = convertMethodCallExprToRaw(e) - } - /** * INTERNAL: Do not use. * Converts a synthesized `TCallable` to a raw DB element, if possible. @@ -3858,7 +3835,7 @@ module Synth { or result = convertBreakExprToRaw(e) or - result = convertCallExprBaseToRaw(e) + result = convertCallExprToRaw(e) or result = convertCastExprToRaw(e) or @@ -3886,6 +3863,8 @@ module Synth { or result = convertMatchExprToRaw(e) or + result = convertMethodCallExprToRaw(e) + or result = convertOffsetOfExprToRaw(e) or result = convertParenExprToRaw(e) diff --git a/rust/ql/lib/codeql/rust/elements/internal/generated/TupleField.qll b/rust/ql/lib/codeql/rust/elements/internal/generated/TupleField.qll index 43696098386..8d39a116f5c 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/generated/TupleField.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/generated/TupleField.qll @@ -17,7 +17,7 @@ import codeql.rust.elements.Visibility */ module Generated { /** - * A field in a tuple struct or tuple enum variant. + * A field in a tuple struct or tuple variant. * * For example: * ```rust diff --git a/rust/ql/lib/codeql/rust/elements/internal/generated/TupleFieldList.qll b/rust/ql/lib/codeql/rust/elements/internal/generated/TupleFieldList.qll index 56b1d505c3a..6d68797e64b 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/generated/TupleFieldList.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/generated/TupleFieldList.qll @@ -15,7 +15,7 @@ import codeql.rust.elements.TupleField */ module Generated { /** - * A list of fields in a tuple struct or tuple enum variant. + * A list of fields in a tuple struct or tuple variant. * * For example: * ```rust diff --git a/rust/ql/lib/codeql/rust/frameworks/rustcrypto/RustCrypto.qll b/rust/ql/lib/codeql/rust/frameworks/rustcrypto/RustCrypto.qll index b6accba0734..6e50659103d 100644 --- a/rust/ql/lib/codeql/rust/frameworks/rustcrypto/RustCrypto.qll +++ b/rust/ql/lib/codeql/rust/frameworks/rustcrypto/RustCrypto.qll @@ -24,13 +24,12 @@ class StreamCipherInit extends Cryptography::CryptographicOperation::Range { StreamCipherInit() { // a call to `cipher::KeyInit::new`, `cipher::KeyInit::new_from_slice`, // `cipher::KeyIvInit::new`, `cipher::KeyIvInit::new_from_slices`, `rc2::Rc2::new_with_eff_key_len` or similar. - exists(CallExprBase ce, string rawAlgorithmName | - ce = this.asExpr() and - ce.getStaticTarget().(Function).getName().getText() = - ["new", "new_from_slice", "new_with_eff_key_len", "new_from_slices"] and + exists(Call call, string rawAlgorithmName | + call = this.asExpr() and + call.getTargetName() = ["new", "new_from_slice", "new_with_eff_key_len", "new_from_slices"] and // extract the algorithm name from the type of `ce` or its receiver. exists(Type t, TypePath tp | - t = inferType([ce, ce.(MethodCallExpr).getReceiver()], tp) and + t = inferType([call, call.(MethodCall).getReceiver()], tp) and rawAlgorithmName = t.(StructType).getStruct().(Addressable).getCanonicalPath().splitAt("::") ) and algorithmName = simplifyAlgorithmName(rawAlgorithmName) and diff --git a/rust/ql/lib/codeql/rust/frameworks/stdlib/Stdlib.qll b/rust/ql/lib/codeql/rust/frameworks/stdlib/Stdlib.qll index d078f08c168..00e03053654 100644 --- a/rust/ql/lib/codeql/rust/frameworks/stdlib/Stdlib.qll +++ b/rust/ql/lib/codeql/rust/frameworks/stdlib/Stdlib.qll @@ -10,7 +10,7 @@ private import codeql.rust.internal.PathResolution /** * A call to the `starts_with` method on a `Path`. */ -private class StartswithCall extends Path::SafeAccessCheck::Range, MethodCallExpr { +private class StartswithCall extends Path::SafeAccessCheck::Range, MethodCall { StartswithCall() { this.getStaticTarget().getCanonicalPath() = "::starts_with" } override predicate checks(Expr e, boolean branch) { diff --git a/rust/ql/lib/codeql/rust/internal/Definitions.qll b/rust/ql/lib/codeql/rust/internal/Definitions.qll index 60520a77cbf..aedcc3fc69c 100644 --- a/rust/ql/lib/codeql/rust/internal/Definitions.qll +++ b/rust/ql/lib/codeql/rust/internal/Definitions.qll @@ -147,7 +147,7 @@ private class PathUse extends Use instanceof NameRef { override Definition getDefinition() { // Our call resolution logic may disambiguate some calls, so only use those - result.asItemNode() = this.getCall().getStaticTarget() + result.asItemNode() = this.getCall().getResolvedTarget() or not exists(this.getCall()) and result.asItemNode() = resolvePath(path) diff --git a/rust/ql/lib/codeql/rust/internal/PathResolution.qll b/rust/ql/lib/codeql/rust/internal/PathResolution.qll index 13e1e0d381d..425e5a099dc 100644 --- a/rust/ql/lib/codeql/rust/internal/PathResolution.qll +++ b/rust/ql/lib/codeql/rust/internal/PathResolution.qll @@ -2046,7 +2046,7 @@ private ItemNode resolvePathCand(PathExt path) { or exists(CallExpr ce | path = CallExprImpl::getFunctionPath(ce) and - result.(ParameterizableItemNode).getArity() = ce.getNumberOfArgs() + result.(ParameterizableItemNode).getArity() = ce.getArgList().getNumberOfArgs() ) ) } diff --git a/rust/ql/lib/codeql/rust/internal/PathResolutionConsistency.qll b/rust/ql/lib/codeql/rust/internal/PathResolutionConsistency.qll index 1c8ac649df3..857afc1f552 100644 --- a/rust/ql/lib/codeql/rust/internal/PathResolutionConsistency.qll +++ b/rust/ql/lib/codeql/rust/internal/PathResolutionConsistency.qll @@ -24,10 +24,17 @@ query predicate multiplePathResolutions(Path p, ItemNode i) { strictcount(ItemNode i0 | i0 = resolvePath(p) and not i0 instanceof Crate) > 1 } +// TODO: Take other calls into account +abstract private class CallExprBase extends InvocationExpr { } + +private class CallExprCallExprBase extends CallExpr, CallExprBase { } + +private class MethodCallExprCallExprBase extends MethodCallExpr, CallExprBase { } + /** Holds if `call` has multiple static call targets including `target`. */ query predicate multipleCallTargets(CallExprBase call, Callable target) { - target = call.getStaticTarget() and - strictcount(call.getStaticTarget()) > 1 + target = call.getResolvedTarget() and + strictcount(call.getResolvedTarget()) > 1 } /** Holds if `fe` resolves to multiple record fields including `field`. */ diff --git a/rust/ql/lib/codeql/rust/internal/TypeInference.qll b/rust/ql/lib/codeql/rust/internal/TypeInference.qll index a21722d0e1f..05675a42088 100644 --- a/rust/ql/lib/codeql/rust/internal/TypeInference.qll +++ b/rust/ql/lib/codeql/rust/internal/TypeInference.qll @@ -13,8 +13,6 @@ private import codeql.rust.internal.CachedStages private import codeql.typeinference.internal.TypeInference private import codeql.rust.frameworks.stdlib.Stdlib private import codeql.rust.frameworks.stdlib.Builtins as Builtins -private import codeql.rust.elements.Call -private import codeql.rust.elements.internal.CallImpl::Impl as CallImpl private import codeql.rust.elements.internal.CallExprImpl::Impl as CallExprImpl class Type = T::Type; @@ -230,11 +228,6 @@ module Consistency { } } -/** A method, that is, a function with a `self` parameter. */ -private class Method extends Function { - Method() { this.hasSelfParam() } -} - /** A function without a `self` parameter. */ private class NonMethodFunction extends Function { NonMethodFunction() { not this.hasSelfParam() } @@ -961,6 +954,24 @@ private Type getCallExprTypeQualifier(CallExpr ce, TypePath path) { ) } +/** + * Gets the trait qualifier of function call `ce`, if any. + * + * For example, the trait qualifier of `Default::::default()` is `Default`. + */ +pragma[nomagic] +private Trait getCallExprTraitQualifier(CallExpr ce) { + exists(PathExt qualifierPath | + qualifierPath = getCallExprPathQualifier(ce) and + result = resolvePath(qualifierPath) and + // When the qualifier is `Self` and resolves to a trait, it's inside a + // trait method's default implementation. This is not a dispatch whose + // target is inferred from the type of the receiver, but should always + // resolve to the function in the trait block as path resolution does. + not qualifierPath.isUnqualified("Self") + ) +} + /** * Provides functionality related to context-based typing of calls. */ @@ -1244,14 +1255,17 @@ private module MethodResolution { pragma[nomagic] private predicate methodCallTraitCandidate(Element mc, Trait trait) { - exists(string name, int arity | - mc.(MethodCall).hasNameAndArity(name, arity) and - methodTraitInfo(name, arity, trait) - | - not mc.(Call).hasTrait() - or - trait = mc.(Call).getTrait() - ) + mc = + any(MethodCall mc0 | + exists(string name, int arity | + mc0.hasNameAndArity(name, arity) and + methodTraitInfo(name, arity, trait) + | + not mc0.hasTrait() + or + trait = mc0.getTrait() + ) + ) } private module MethodTraitIsVisible = TraitIsVisible; @@ -1296,7 +1310,7 @@ private module MethodResolution { or methodCallVisibleTraitCandidate(mc, i) or - i.(ImplItemNode).resolveTraitTy() = mc.(Call).getTrait() + i.(ImplItemNode).resolveTraitTy() = mc.getTrait() ) } @@ -1323,7 +1337,7 @@ private module MethodResolution { | methodCallVisibleImplTraitCandidate(mc, impl) or - impl.resolveTraitTy() = mc.(Call).getTrait() + impl.resolveTraitTy() = mc.getTrait() ) } @@ -1350,18 +1364,24 @@ private module MethodResolution { abstract class MethodCall extends Expr { abstract predicate hasNameAndArity(string name, int arity); - abstract Expr getArgument(ArgumentPosition pos); + abstract Expr getArg(ArgumentPosition pos); abstract predicate supportsAutoDerefAndBorrow(); + /** Gets the trait targeted by this call, if any. */ + abstract Trait getTrait(); + + /** Holds if this call targets a trait. */ + predicate hasTrait() { exists(this.getTrait()) } + AstNode getNodeAt(FunctionPosition apos) { - result = this.getArgument(apos.asArgumentPosition()) + result = this.getArg(apos.asArgumentPosition()) or result = this and apos.isReturn() } Type getArgumentTypeAt(ArgumentPosition pos, TypePath path) { - result = inferType(this.getArgument(pos), path) + result = inferType(this.getArg(pos), path) } private Type getReceiverTypeAt(TypePath path) { @@ -1587,12 +1607,12 @@ private module MethodResolution { predicate receiverHasImplicitDeref(AstNode receiver) { exists(this.resolveCallTarget(_, ".ref", false)) and - receiver = this.getArgument(CallImpl::TSelfArgumentPosition()) + receiver = this.getArg(any(ArgumentPosition pos | pos.isSelf())) } - predicate receiverHasImplicitBorrow(AstNode receiver) { + predicate argumentHasImplicitBorrow(AstNode arg) { exists(this.resolveCallTarget(_, "", true)) and - receiver = this.getArgument(CallImpl::TSelfArgumentPosition()) + arg = this.getArg(any(ArgumentPosition pos | pos.isSelf())) } } @@ -1603,35 +1623,36 @@ private module MethodResolution { arity = super.getArgList().getNumberOfArgs() } - override Expr getArgument(ArgumentPosition pos) { - pos.isSelf() and - result = MethodCallExpr.super.getReceiver() - or - result = super.getArgList().getArg(pos.asPosition()) + override Expr getArg(ArgumentPosition pos) { + result = MethodCallExpr.super.getSyntacticArgument(pos) } override predicate supportsAutoDerefAndBorrow() { any() } + + override Trait getTrait() { none() } } - private class MethodCallIndexExpr extends MethodCall, IndexExpr { + private class MethodCallIndexExpr extends MethodCall instanceof IndexExpr { pragma[nomagic] override predicate hasNameAndArity(string name, int arity) { name = "index" and arity = 1 } - override Expr getArgument(ArgumentPosition pos) { + override Expr getArg(ArgumentPosition pos) { pos.isSelf() and - result = this.getBase() + result = super.getBase() or pos.asPosition() = 0 and - result = this.getIndex() + result = super.getIndex() } override predicate supportsAutoDerefAndBorrow() { any() } + + override Trait getTrait() { result.getCanonicalPath() = "core::ops::index::Index" } } - private class MethodCallCallExpr extends MethodCall, CallExpr { + private class MethodCallCallExpr extends MethodCall instanceof CallExpr { MethodCallCallExpr() { exists(getCallExprPathQualifier(this)) and // even if a method cannot be resolved by path resolution, it may still @@ -1656,14 +1677,14 @@ private module MethodResolution { pragma[nomagic] override predicate hasNameAndArity(string name, int arity) { name = CallExprImpl::getFunctionPath(this).getText() and - arity = this.getArgList().getNumberOfArgs() - 1 + arity = super.getArgList().getNumberOfArgs() - 1 } - override Expr getArgument(ArgumentPosition pos) { + override Expr getArg(ArgumentPosition pos) { pos.isSelf() and - result = this.getArg(0) + result = super.getSyntacticPositionalArgument(0) or - result = this.getArgList().getArg(pos.asPosition() + 1) + result = super.getSyntacticPositionalArgument(pos.asPosition() + 1) } // needed for `TypeQualifierIsInstantiationOfImplSelfInput` @@ -1672,38 +1693,55 @@ private module MethodResolution { } override predicate supportsAutoDerefAndBorrow() { none() } + + override Trait getTrait() { result = getCallExprTraitQualifier(this) } } - final class MethodCallOperation extends MethodCall, Operation { + final class MethodCallOperation extends MethodCall instanceof Operation { pragma[nomagic] override predicate hasNameAndArity(string name, int arity) { - name = this.(Call).getMethodName() and - arity = this.getNumberOfOperands() - 1 + super.isOverloaded(_, name, _) and + arity = super.getNumberOfOperands() - 1 } - override Expr getArgument(ArgumentPosition pos) { result = this.(Call).getArgument(pos) } + override Expr getArg(ArgumentPosition pos) { + pos.isSelf() and + result = super.getOperand(0) + or + result = super.getOperand(pos.asPosition() + 1) + } + + private predicate implicitBorrowAt(ArgumentPosition pos) { + exists(int borrows | super.isOverloaded(_, _, borrows) | + pos.isSelf() and borrows >= 1 + or + pos.asPosition() = 0 and borrows = 2 + ) + } override Type getArgumentTypeAt(ArgumentPosition pos, TypePath path) { - if this.(Call).implicitBorrowAt(pos, true) + if this.implicitBorrowAt(pos) then result instanceof RefType and path.isEmpty() or exists(TypePath path0 | - result = inferType(this.getArgument(pos), path0) and + result = inferType(this.getArg(pos), path0) and path = TypePath::cons(getRefTypeParameter(), path0) ) - else result = inferType(this.getArgument(pos), path) + else result = inferType(this.getArg(pos), path) } - override predicate receiverHasImplicitBorrow(AstNode receiver) { + override predicate argumentHasImplicitBorrow(AstNode arg) { exists(ArgumentPosition pos | - this.(Call).implicitBorrowAt(pos, true) and - receiver = this.getArgument(pos) + this.implicitBorrowAt(pos) and + arg = this.getArg(pos) ) } override predicate supportsAutoDerefAndBorrow() { none() } + + override Trait getTrait() { super.isOverloaded(result, _, _) } } pragma[nomagic] @@ -2274,14 +2312,17 @@ private module NonMethodResolution { pragma[nomagic] private predicate blanketLikeCallTraitCandidate(Element fc, Trait trait) { - exists(string name, int arity | - fc.(NonMethodCall).hasNameAndArity(name, arity) and - functionInfoBlanketLikeRelevantPos(_, name, arity, _, trait, _, _, _, _) - | - not fc.(Call).hasTrait() - or - trait = fc.(Call).getTrait() - ) + fc = + any(NonMethodCall nmc | + exists(string name, int arity | + nmc.hasNameAndArity(name, arity) and + functionInfoBlanketLikeRelevantPos(_, name, arity, _, trait, _, _, _, _) + | + not nmc.hasTrait() + or + trait = nmc.getTrait() + ) + ) } private module BlanketTraitIsVisible = TraitIsVisible; @@ -2323,9 +2364,15 @@ private module NonMethodResolution { ) } + /** Gets the trait targeted by this call, if any. */ + Trait getTrait() { result = getCallExprTraitQualifier(this) } + + /** Holds if this call targets a trait. */ + predicate hasTrait() { exists(this.getTrait()) } + pragma[nomagic] NonMethodFunction resolveAssocCallTargetCand(ImplItemNode i) { - not this.(Call).hasTrait() and + not this.hasTrait() and result = this.getPathResolutionResolved() and result = i.getASuccessor(_) or @@ -2333,7 +2380,7 @@ private module NonMethodResolution { } AstNode getNodeAt(FunctionPosition pos) { - result = this.getArg(pos.asPosition()) + result = this.getSyntacticArgument(pos.asArgumentPosition()) or result = this and pos.isReturn() } @@ -2358,7 +2405,7 @@ private module NonMethodResolution { pragma[nomagic] predicate hasTraitResolved(TraitItemNode trait, NonMethodFunction resolved) { resolved = this.getPathResolutionResolved() and - trait = this.(Call).getTrait() + trait = this.getTrait() } /** @@ -2366,7 +2413,7 @@ private module NonMethodResolution { */ pragma[nomagic] ItemNode resolveCallTargetViaPathResolution() { - not this.(Call).hasTrait() and + not this.hasTrait() and result = this.getPathResolutionResolved() and not FunctionOverloading::functionResolutionDependsOnArgument(_, result, _, _, _) } @@ -2391,7 +2438,7 @@ private module NonMethodResolution { pragma[nomagic] NonMethodFunction resolveTraitFunctionViaPathResolution(TraitItemNode trait) { - this.(Call).hasTrait() and + this.hasTrait() and result = this.getPathResolutionResolved() and result = trait.getASuccessor(_) } @@ -2703,7 +2750,7 @@ private predicate inferNonMethodCallType = * A matching configuration for resolving types of operations like `a + b`. */ private module OperationMatchingInput implements MatchingInputSig { - private import codeql.rust.elements.internal.OperationImpl as OperationImpl + private import codeql.rust.elements.internal.OperationImpl::Impl as OperationImpl import FunctionPositionMatchingInput class Declaration extends MethodCallMatchingInput::Declaration { @@ -3365,8 +3412,9 @@ private Type inferDynamicCallExprType(Expr n, TypePath path) { or // Propagate the function's parameter type to the arguments exists(int index | - n = ce.getCall().getArgList().getArg(index) and - path = path0.stripPrefix(fnParameterPath(ce.getCall().getNumberOfArgs(), index)) + n = ce.getCall().getSyntacticPositionalArgument(index) and + path = + path0.stripPrefix(fnParameterPath(ce.getCall().getArgList().getNumberOfArgs(), index)) ) ) or @@ -3376,16 +3424,17 @@ private Type inferDynamicCallExprType(Expr n, TypePath path) { ce.getTypeAt(TypePath::nil()).(DynTraitType).getTrait() instanceof FnOnceTrait | // Propagate the type of arguments to the parameter types of closure - exists(int index | + exists(int index, ArgList args | n = ce and - arity = ce.getCall().getNumberOfArgs() and - result = inferType(ce.getCall().getArg(index), path0) and + args = ce.getCall().getArgList() and + arity = args.getNumberOfArgs() and + result = inferType(args.getArg(index), path0) and path = closureParameterPath(arity, index).append(path0) ) or // Propagate the type of the call expression to the return type of the closure n = ce and - arity = ce.getCall().getNumberOfArgs() and + arity = ce.getCall().getArgList().getNumberOfArgs() and result = inferType(ce.getCall(), path0) and path = closureReturnPath().append(path0) ) @@ -3432,12 +3481,12 @@ private module Cached { /** Holds if `n` is implicitly borrowed. */ cached predicate implicitBorrow(AstNode n) { - any(MethodResolution::MethodCall mc).receiverHasImplicitBorrow(n) + any(MethodResolution::MethodCall mc).argumentHasImplicitBorrow(n) } /** Gets an item (function or tuple struct/variant) that `call` resolves to, if any. */ cached - Addressable resolveCallTarget(Call call) { + Addressable resolveCallTarget(Expr call) { result = call.(MethodResolution::MethodCall).resolveCallTarget(_, _, _) or result = call.(NonMethodResolution::NonMethodCall).resolveCallTarget() @@ -3579,7 +3628,7 @@ private module Debug { result = inferType(n, path) } - Addressable debugResolveCallTarget(Call c) { + Addressable debugResolveCallTarget(InvocationExpr c) { c = getRelevantLocatable() and result = resolveCallTarget(c) } diff --git a/rust/ql/lib/codeql/rust/internal/typeinference/FunctionType.qll b/rust/ql/lib/codeql/rust/internal/typeinference/FunctionType.qll index 133393bf57a..c219ef0eacc 100644 --- a/rust/ql/lib/codeql/rust/internal/typeinference/FunctionType.qll +++ b/rust/ql/lib/codeql/rust/internal/typeinference/FunctionType.qll @@ -3,7 +3,6 @@ private import codeql.rust.internal.TypeInference private import codeql.rust.internal.PathResolution private import codeql.rust.internal.Type private import codeql.rust.internal.TypeMention -private import codeql.rust.elements.Call private newtype TFunctionPosition = TArgumentFunctionPosition(ArgumentPosition pos) or diff --git a/rust/ql/lib/codeql/rust/security/AccessAfterLifetimeExtensions.qll b/rust/ql/lib/codeql/rust/security/AccessAfterLifetimeExtensions.qll index e68fb2fb0fa..4b356aaa651 100644 --- a/rust/ql/lib/codeql/rust/security/AccessAfterLifetimeExtensions.qll +++ b/rust/ql/lib/codeql/rust/security/AccessAfterLifetimeExtensions.qll @@ -100,9 +100,9 @@ module AccessAfterLifetime { a = b.getEnclosingBlock*() or // propagate through function calls (static target) - exists(CallExprBase ce | - mayEncloseOnStack(a, ce.getEnclosingBlock()) and - ce.getStaticTarget() = b.getEnclosingCallable() + exists(Call call | + mayEncloseOnStack(a, call.getEnclosingBlock()) and + call.getStaticTarget() = b.getEnclosingCallable() ) or // propagate through function calls (runtime target) diff --git a/rust/ql/lib/codeql/rust/security/DisabledCertificateCheckExtensions.qll b/rust/ql/lib/codeql/rust/security/DisabledCertificateCheckExtensions.qll index 6a885828ee9..a86ee506dfa 100644 --- a/rust/ql/lib/codeql/rust/security/DisabledCertificateCheckExtensions.qll +++ b/rust/ql/lib/codeql/rust/security/DisabledCertificateCheckExtensions.qll @@ -33,12 +33,12 @@ module DisabledCertificateCheckExtensions { */ private class HeuristicSink extends Sink { HeuristicSink() { - exists(CallExprBase fc | - fc.getStaticTarget().(Function).getName().getText() = + exists(Call call | + call.getStaticTarget().getName().getText() = ["danger_accept_invalid_certs", "danger_accept_invalid_hostnames"] and - fc.getArg(0) = this.asExpr() and + call.getPositionalArgument(0) = this.asExpr() and // don't duplicate modeled sinks - not exists(ModelsAsDataSink s | s.(Node::FlowSummaryNode).getSinkElement().getCall() = fc) + not exists(ModelsAsDataSink s | s.(Node::FlowSummaryNode).getSinkElement().getCall() = call) ) } } diff --git a/rust/ql/lib/codeql/rust/security/HardcodedCryptographicValueExtensions.qll b/rust/ql/lib/codeql/rust/security/HardcodedCryptographicValueExtensions.qll index a7fb35d138b..9bdfc53971e 100644 --- a/rust/ql/lib/codeql/rust/security/HardcodedCryptographicValueExtensions.qll +++ b/rust/ql/lib/codeql/rust/security/HardcodedCryptographicValueExtensions.qll @@ -9,6 +9,7 @@ private import codeql.rust.dataflow.FlowSource private import codeql.rust.dataflow.FlowSink private import codeql.rust.Concepts private import codeql.rust.security.SensitiveData +private import codeql.rust.dataflow.internal.Node as Node /** * A kind of cryptographic value. @@ -98,15 +99,45 @@ module HardcodedCryptographicValue { override CryptographicValueKind getKind() { result = kind } } + /** + * A heuristic sink for hard-coded cryptographic value vulnerabilities. + */ + private class HeuristicSinks extends Sink { + CryptographicValueKind kind; + + HeuristicSinks() { + // any argument going to a parameter whose name matches a credential name + exists(Call c, Function f, int argIndex, string argName | + c.getPositionalArgument(argIndex) = this.asExpr() and + c.getStaticTarget() = f and + f.getParam(argIndex).getPat().(IdentPat).getName().getText() = argName and + ( + argName = "password" and kind = "password" + or + argName = "iv" and kind = "iv" + or + argName = "nonce" and kind = "nonce" + or + argName = "salt" and kind = "salt" + // + // note: matching "key" results in too many false positives + ) and + // don't duplicate modeled sinks + not exists(ModelsAsDataSinks s | s.(Node::FlowSummaryNode).getSinkElement().getCall() = c) + ) + } + + override CryptographicValueKind getKind() { result = kind } + } + /** * A call to `getrandom` that is a barrier. */ private class GetRandomBarrier extends Barrier { GetRandomBarrier() { - exists(CallExprBase ce | - ce.getStaticTarget().(Addressable).getCanonicalPath() = - ["getrandom::fill", "getrandom::getrandom"] and - this.asExpr().getParentNode*() = ce.getArgList().getArg(0) + exists(Call call | + call.getStaticTarget().getCanonicalPath() = ["getrandom::fill", "getrandom::getrandom"] and + this.asExpr().getParentNode*() = call.getPositionalArgument(0) ) } } diff --git a/rust/ql/lib/codeql/rust/security/InsecureCookieExtensions.qll b/rust/ql/lib/codeql/rust/security/InsecureCookieExtensions.qll index 8e9f855209e..87d37d6b85b 100644 --- a/rust/ql/lib/codeql/rust/security/InsecureCookieExtensions.qll +++ b/rust/ql/lib/codeql/rust/security/InsecureCookieExtensions.qll @@ -80,12 +80,12 @@ module InsecureCookie { * as `false`. */ predicate cookieSetNode(DataFlow::Node node, string attrib, boolean value) { - exists(FlowSummaryNode summaryNode, CallExprBase ce, int arg, DataFlow::Node argNode | + exists(FlowSummaryNode summaryNode, MethodCall call, int arg, DataFlow::Node argNode | // decode the models-as-data `OptionalBarrier` cookieOptionalBarrier(summaryNode, attrib, arg) and // find a call and arg referenced by this optional barrier - ce.getStaticTarget() = summaryNode.getSummarizedCallable() and - ce.getArg(arg) = argNode.asExpr() and + call.getStaticTarget() = summaryNode.getSummarizedCallable() and + call.getPositionalArgument(arg) = argNode.asExpr() and // check if the argument is always `true` ( if @@ -101,12 +101,12 @@ module InsecureCookie { // and find the node where this happens (we can't just use the flow summary node, since its // shared across all calls to the modeled function, we need a node specific to this call) ( - node.asExpr() = ce.(MethodCallExpr).getReceiver() // e.g. `a` in `a.set_secure(true)` + node.asExpr() = call.getReceiver() // e.g. `a` in `a.set_secure(true)` or exists(BasicBlock bb, int i | // associated SSA node node.(SsaNode).asDefinition().definesAt(_, bb, i) and - ce.(MethodCallExpr).getReceiver() = bb.getNode(i).getAstNode() + call.getReceiver() = bb.getNode(i).getAstNode() ) ) ) diff --git a/rust/ql/lib/codeql/rust/security/SensitiveData.qll b/rust/ql/lib/codeql/rust/security/SensitiveData.qll index 1b6abdd52fb..c4cd7c31366 100644 --- a/rust/ql/lib/codeql/rust/security/SensitiveData.qll +++ b/rust/ql/lib/codeql/rust/security/SensitiveData.qll @@ -28,12 +28,13 @@ private class SensitiveDataCall extends SensitiveData { SensitiveDataClassification classification; SensitiveDataCall() { - exists(CallExprBase call, string name | + exists(InvocationExpr call, Addressable target, string name | call = this.asExpr() and + target = call.getResolvedTarget() and name = [ - call.getStaticTarget().(Function).getName().getText(), - call.(CallExpr).getVariant().getName().getText(), + target.(Function).getName().getText(), + target.(Variant).getName().getText(), ] and HeuristicNames::nameIndicatesSensitiveData(name, classification) ) diff --git a/rust/ql/lib/codeql/rust/security/TaintedPathExtensions.qll b/rust/ql/lib/codeql/rust/security/TaintedPathExtensions.qll index 2d097c0aa4c..ccf3736ceb4 100644 --- a/rust/ql/lib/codeql/rust/security/TaintedPathExtensions.qll +++ b/rust/ql/lib/codeql/rust/security/TaintedPathExtensions.qll @@ -66,11 +66,11 @@ module SanitizerGuard { * A check of the form `!strings.Contains(nd, "..")`, considered as a sanitizer guard for * path traversal. */ -private class DotDotCheck extends SanitizerGuard::Range, MethodCallExpr { +private class DotDotCheck extends SanitizerGuard::Range, MethodCall { DotDotCheck() { - this.getStaticTarget().(Addressable).getCanonicalPath() = + this.getStaticTarget().getCanonicalPath() = ["::contains", "::contains"] and - this.getArg(0).(LiteralExpr).getTextValue() = ["\"..\"", "\"../\"", "\"..\\\""] + this.getPositionalArgument(0).(LiteralExpr).getTextValue() = ["\"..\"", "\"../\"", "\"..\\\""] } override predicate checks(Expr e, boolean branch) { diff --git a/rust/ql/lib/codeql/rust/security/XssExtensions.qll b/rust/ql/lib/codeql/rust/security/XssExtensions.qll index d1d043fafaf..cb0510cd704 100644 --- a/rust/ql/lib/codeql/rust/security/XssExtensions.qll +++ b/rust/ql/lib/codeql/rust/security/XssExtensions.qll @@ -53,9 +53,9 @@ module Xss { /** A call to a function with "escape" or "encode" in its name. */ private class HeuristicHtmlEncodingBarrier extends Barrier { HeuristicHtmlEncodingBarrier() { - exists(Call fc | - fc.getStaticTarget().getName().getText().regexpMatch(".*(escape|encode).*") and - fc.getArgument(_) = this.asExpr() + exists(Call c | + c.getStaticTarget().getName().getText().regexpMatch(".*(escape|encode).*") and + c.getAnArgument() = this.asExpr() ) } } diff --git a/rust/ql/lib/codeql/rust/security/regex/RegexInjectionExtensions.qll b/rust/ql/lib/codeql/rust/security/regex/RegexInjectionExtensions.qll index ae330ed1d0f..7cb0dc47c9f 100644 --- a/rust/ql/lib/codeql/rust/security/regex/RegexInjectionExtensions.qll +++ b/rust/ql/lib/codeql/rust/security/regex/RegexInjectionExtensions.qll @@ -53,10 +53,10 @@ module RegexInjection { */ private class NewSink extends Sink { NewSink() { - exists(CallExprBase call, Addressable a | - call.getStaticTarget() = a and - a.getCanonicalPath() = "::new" and - this.asExpr() = call.getArg(0) and + exists(Call call, Function f | + call.getStaticTarget() = f and + f.getCanonicalPath() = "::new" and + this.asExpr() = call.getPositionalArgument(0) and not this.asExpr() instanceof LiteralExpr ) } diff --git a/rust/ql/lib/rust.dbscheme b/rust/ql/lib/rust.dbscheme index 30a0713e5bf..e54d01f67a4 100644 --- a/rust/ql/lib/rust.dbscheme +++ b/rust/ql/lib/rust.dbscheme @@ -398,7 +398,7 @@ callable_attrs( | @become_expr | @binary_expr | @break_expr -| @call_expr_base +| @call_expr | @cast_expr | @closure_expr | @continue_expr @@ -412,6 +412,7 @@ callable_attrs( | @macro_block_expr | @macro_expr | @match_expr +| @method_call_expr | @offset_of_expr | @paren_expr | @path_expr_base @@ -1480,24 +1481,29 @@ break_expr_lifetimes( int lifetime: @lifetime ref ); -@call_expr_base = - @call_expr -| @method_call_expr -; +call_exprs( + unique int id: @call_expr +); #keyset[id] -call_expr_base_arg_lists( - int id: @call_expr_base ref, +call_expr_arg_lists( + int id: @call_expr ref, int arg_list: @arg_list ref ); #keyset[id, index] -call_expr_base_attrs( - int id: @call_expr_base ref, +call_expr_attrs( + int id: @call_expr ref, int index: int ref, int attr: @attr ref ); +#keyset[id] +call_expr_functions( + int id: @call_expr ref, + int function: @expr ref +); + cast_exprs( unique int id: @cast_expr ); @@ -2100,6 +2106,41 @@ match_expr_match_arm_lists( int match_arm_list: @match_arm_list ref ); +method_call_exprs( + unique int id: @method_call_expr +); + +#keyset[id] +method_call_expr_arg_lists( + int id: @method_call_expr ref, + int arg_list: @arg_list ref +); + +#keyset[id, index] +method_call_expr_attrs( + int id: @method_call_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +method_call_expr_generic_arg_lists( + int id: @method_call_expr ref, + int generic_arg_list: @generic_arg_list ref +); + +#keyset[id] +method_call_expr_identifiers( + int id: @method_call_expr ref, + int identifier: @name_ref ref +); + +#keyset[id] +method_call_expr_receivers( + int id: @method_call_expr ref, + int receiver: @expr ref +); + name_refs( unique int id: @name_ref ); @@ -2776,16 +2817,6 @@ block_expr_stmt_lists( int stmt_list: @stmt_list ref ); -call_exprs( - unique int id: @call_expr -); - -#keyset[id] -call_expr_functions( - int id: @call_expr ref, - int function: @expr ref -); - extern_blocks( unique int id: @extern_block ); @@ -2988,28 +3019,6 @@ macro_rules_visibilities( int visibility: @visibility ref ); -method_call_exprs( - unique int id: @method_call_expr -); - -#keyset[id] -method_call_expr_generic_arg_lists( - int id: @method_call_expr ref, - int generic_arg_list: @generic_arg_list ref -); - -#keyset[id] -method_call_expr_identifiers( - int id: @method_call_expr ref, - int identifier: @name_ref ref -); - -#keyset[id] -method_call_expr_receivers( - int id: @method_call_expr ref, - int receiver: @expr ref -); - modules( unique int id: @module ); diff --git a/rust/ql/lib/rust.qll b/rust/ql/lib/rust.qll index d209672028b..410f062d91e 100644 --- a/rust/ql/lib/rust.qll +++ b/rust/ql/lib/rust.qll @@ -6,6 +6,7 @@ import codeql.Locations import codeql.files.FileSystem import codeql.rust.elements.Operation import codeql.rust.elements.ArithmeticOperation +import codeql.rust.elements.InvocationExpr import codeql.rust.elements.AssignmentOperation import codeql.rust.elements.BitwiseOperation import codeql.rust.elements.ComparisonOperation @@ -18,6 +19,7 @@ import codeql.rust.elements.Variable import codeql.rust.elements.NamedFormatArgument import codeql.rust.elements.PositionalFormatArgument import codeql.rust.elements.RangeExprExt -private import codeql.rust.elements.Call as Call - -class Call = Call::Call; +import codeql.rust.elements.Call +import codeql.rust.elements.TupleStructExpr +import codeql.rust.elements.TupleVariantExpr +import codeql.rust.elements.Method diff --git a/rust/ql/lib/upgrades/30a0713e5bf69c60d003e4994e5abd1c78a36826/old.dbscheme b/rust/ql/lib/upgrades/30a0713e5bf69c60d003e4994e5abd1c78a36826/old.dbscheme new file mode 100644 index 00000000000..30a0713e5bf --- /dev/null +++ b/rust/ql/lib/upgrades/30a0713e5bf69c60d003e4994e5abd1c78a36826/old.dbscheme @@ -0,0 +1,3615 @@ +// generated by codegen, do not edit + +// from ../shared/tree-sitter-extractor/src/generator/prefix.dbscheme +/*- Files and folders -*/ + +/** + * The location of an element. + * The location spans column `startcolumn` of line `startline` to + * column `endcolumn` of line `endline` in file `file`. + * For more information, see + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). + */ +locations_default( + unique int id: @location_default, + int file: @file ref, + int beginLine: int ref, + int beginColumn: int ref, + int endLine: int ref, + int endColumn: int ref +); + +files( + unique int id: @file, + string name: string ref +); + +folders( + unique int id: @folder, + string name: string ref +); + +@container = @file | @folder + +containerparent( + int parent: @container ref, + unique int child: @container ref +); + +/*- Empty location -*/ + +empty_location( + int location: @location_default ref +); + +/*- Source location prefix -*/ + +/** + * The source location of the snapshot. + */ +sourceLocationPrefix(string prefix : string ref); + +/*- Diagnostic messages -*/ + +diagnostics( + unique int id: @diagnostic, + int severity: int ref, + string error_tag: string ref, + string error_message: string ref, + string full_error_message: string ref, + int location: @location_default ref +); + +/*- Diagnostic messages: severity -*/ + +case @diagnostic.severity of + 10 = @diagnostic_debug +| 20 = @diagnostic_info +| 30 = @diagnostic_warning +| 40 = @diagnostic_error +; + +/*- YAML -*/ + +#keyset[parent, idx] +yaml (unique int id: @yaml_node, + int kind: int ref, + int parent: @yaml_node_parent ref, + int idx: int ref, + string tag: string ref, + string tostring: string ref); + +case @yaml_node.kind of + 0 = @yaml_scalar_node +| 1 = @yaml_mapping_node +| 2 = @yaml_sequence_node +| 3 = @yaml_alias_node +; + +@yaml_collection_node = @yaml_mapping_node | @yaml_sequence_node; + +@yaml_node_parent = @yaml_collection_node | @file; + +yaml_anchors (unique int node: @yaml_node ref, + string anchor: string ref); + +yaml_aliases (unique int alias: @yaml_alias_node ref, + string target: string ref); + +yaml_scalars (unique int scalar: @yaml_scalar_node ref, + int style: int ref, + string value: string ref); + +yaml_errors (unique int id: @yaml_error, + string message: string ref); + +yaml_locations(unique int locatable: @yaml_locatable ref, + int location: @location_default ref); + +@yaml_locatable = @yaml_node | @yaml_error; + +/*- Database metadata -*/ +databaseMetadata( + string metadataKey: string ref, + string value: string ref +); + +overlayChangedFiles( + string path: string ref +); + + +// from prefix.dbscheme +#keyset[id] +locatable_locations( + int id: @locatable ref, + int location: @location_default ref +); + + +// from schema + +@element = + @extractor_step +| @locatable +| @named_crate +| @unextracted +; + +extractor_steps( + unique int id: @extractor_step, + string action: string ref, + int duration_ms: int ref +); + +#keyset[id] +extractor_step_files( + int id: @extractor_step ref, + int file: @file ref +); + +@locatable = + @ast_node +| @crate +; + +named_crates( + unique int id: @named_crate, + string name: string ref, + int crate: @crate ref +); + +@unextracted = + @missing +| @unimplemented +; + +@ast_node = + @abi +| @addressable +| @arg_list +| @asm_dir_spec +| @asm_operand +| @asm_operand_expr +| @asm_option +| @asm_piece +| @asm_reg_spec +| @assoc_item_list +| @attr +| @callable +| @expr +| @extern_item_list +| @field_list +| @for_binder +| @format_args_arg +| @generic_arg +| @generic_arg_list +| @generic_param +| @generic_param_list +| @item_list +| @label +| @let_else +| @macro_items +| @match_arm +| @match_arm_list +| @match_guard +| @meta +| @name +| @param_base +| @param_list +| @parenthesized_arg_list +| @pat +| @path +| @path_ast_node +| @path_segment +| @rename +| @ret_type_repr +| @return_type_syntax +| @source_file +| @stmt +| @stmt_list +| @struct_expr_field +| @struct_expr_field_list +| @struct_field +| @struct_pat_field +| @struct_pat_field_list +| @token +| @token_tree +| @tuple_field +| @type_bound +| @type_bound_list +| @type_repr +| @use_bound_generic_arg +| @use_bound_generic_args +| @use_tree +| @use_tree_list +| @variant_list +| @visibility +| @where_clause +| @where_pred +; + +crates( + unique int id: @crate +); + +#keyset[id] +crate_names( + int id: @crate ref, + string name: string ref +); + +#keyset[id] +crate_versions( + int id: @crate ref, + string version: string ref +); + +#keyset[id, index] +crate_cfg_options( + int id: @crate ref, + int index: int ref, + string cfg_option: string ref +); + +#keyset[id, index] +crate_named_dependencies( + int id: @crate ref, + int index: int ref, + int named_dependency: @named_crate ref +); + +missings( + unique int id: @missing +); + +unimplementeds( + unique int id: @unimplemented +); + +abis( + unique int id: @abi +); + +#keyset[id] +abi_abi_strings( + int id: @abi ref, + string abi_string: string ref +); + +@addressable = + @item +| @variant +; + +arg_lists( + unique int id: @arg_list +); + +#keyset[id, index] +arg_list_args( + int id: @arg_list ref, + int index: int ref, + int arg: @expr ref +); + +asm_dir_specs( + unique int id: @asm_dir_spec +); + +@asm_operand = + @asm_const +| @asm_label +| @asm_reg_operand +| @asm_sym +; + +asm_operand_exprs( + unique int id: @asm_operand_expr +); + +#keyset[id] +asm_operand_expr_in_exprs( + int id: @asm_operand_expr ref, + int in_expr: @expr ref +); + +#keyset[id] +asm_operand_expr_out_exprs( + int id: @asm_operand_expr ref, + int out_expr: @expr ref +); + +asm_options( + unique int id: @asm_option +); + +#keyset[id] +asm_option_is_raw( + int id: @asm_option ref +); + +@asm_piece = + @asm_clobber_abi +| @asm_operand_named +| @asm_options_list +; + +asm_reg_specs( + unique int id: @asm_reg_spec +); + +#keyset[id] +asm_reg_spec_identifiers( + int id: @asm_reg_spec ref, + int identifier: @name_ref ref +); + +assoc_item_lists( + unique int id: @assoc_item_list +); + +#keyset[id, index] +assoc_item_list_assoc_items( + int id: @assoc_item_list ref, + int index: int ref, + int assoc_item: @assoc_item ref +); + +#keyset[id, index] +assoc_item_list_attrs( + int id: @assoc_item_list ref, + int index: int ref, + int attr: @attr ref +); + +attrs( + unique int id: @attr +); + +#keyset[id] +attr_meta( + int id: @attr ref, + int meta: @meta ref +); + +@callable = + @closure_expr +| @function +; + +#keyset[id] +callable_param_lists( + int id: @callable ref, + int param_list: @param_list ref +); + +#keyset[id, index] +callable_attrs( + int id: @callable ref, + int index: int ref, + int attr: @attr ref +); + +@expr = + @array_expr_internal +| @asm_expr +| @await_expr +| @become_expr +| @binary_expr +| @break_expr +| @call_expr_base +| @cast_expr +| @closure_expr +| @continue_expr +| @field_expr +| @format_args_expr +| @if_expr +| @index_expr +| @labelable_expr +| @let_expr +| @literal_expr +| @macro_block_expr +| @macro_expr +| @match_expr +| @offset_of_expr +| @paren_expr +| @path_expr_base +| @prefix_expr +| @range_expr +| @ref_expr +| @return_expr +| @struct_expr +| @try_expr +| @tuple_expr +| @underscore_expr +| @yeet_expr +| @yield_expr +; + +extern_item_lists( + unique int id: @extern_item_list +); + +#keyset[id, index] +extern_item_list_attrs( + int id: @extern_item_list ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id, index] +extern_item_list_extern_items( + int id: @extern_item_list ref, + int index: int ref, + int extern_item: @extern_item ref +); + +@field_list = + @struct_field_list +| @tuple_field_list +; + +for_binders( + unique int id: @for_binder +); + +#keyset[id] +for_binder_generic_param_lists( + int id: @for_binder ref, + int generic_param_list: @generic_param_list ref +); + +format_args_args( + unique int id: @format_args_arg +); + +#keyset[id] +format_args_arg_exprs( + int id: @format_args_arg ref, + int expr: @expr ref +); + +#keyset[id] +format_args_arg_names( + int id: @format_args_arg ref, + int name: @name ref +); + +@generic_arg = + @assoc_type_arg +| @const_arg +| @lifetime_arg +| @type_arg +; + +generic_arg_lists( + unique int id: @generic_arg_list +); + +#keyset[id, index] +generic_arg_list_generic_args( + int id: @generic_arg_list ref, + int index: int ref, + int generic_arg: @generic_arg ref +); + +@generic_param = + @const_param +| @lifetime_param +| @type_param +; + +generic_param_lists( + unique int id: @generic_param_list +); + +#keyset[id, index] +generic_param_list_generic_params( + int id: @generic_param_list ref, + int index: int ref, + int generic_param: @generic_param ref +); + +item_lists( + unique int id: @item_list +); + +#keyset[id, index] +item_list_attrs( + int id: @item_list ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id, index] +item_list_items( + int id: @item_list ref, + int index: int ref, + int item: @item ref +); + +labels( + unique int id: @label +); + +#keyset[id] +label_lifetimes( + int id: @label ref, + int lifetime: @lifetime ref +); + +let_elses( + unique int id: @let_else +); + +#keyset[id] +let_else_block_exprs( + int id: @let_else ref, + int block_expr: @block_expr ref +); + +macro_items( + unique int id: @macro_items +); + +#keyset[id, index] +macro_items_items( + int id: @macro_items ref, + int index: int ref, + int item: @item ref +); + +match_arms( + unique int id: @match_arm +); + +#keyset[id, index] +match_arm_attrs( + int id: @match_arm ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +match_arm_exprs( + int id: @match_arm ref, + int expr: @expr ref +); + +#keyset[id] +match_arm_guards( + int id: @match_arm ref, + int guard: @match_guard ref +); + +#keyset[id] +match_arm_pats( + int id: @match_arm ref, + int pat: @pat ref +); + +match_arm_lists( + unique int id: @match_arm_list +); + +#keyset[id, index] +match_arm_list_arms( + int id: @match_arm_list ref, + int index: int ref, + int arm: @match_arm ref +); + +#keyset[id, index] +match_arm_list_attrs( + int id: @match_arm_list ref, + int index: int ref, + int attr: @attr ref +); + +match_guards( + unique int id: @match_guard +); + +#keyset[id] +match_guard_conditions( + int id: @match_guard ref, + int condition: @expr ref +); + +meta( + unique int id: @meta +); + +#keyset[id] +meta_exprs( + int id: @meta ref, + int expr: @expr ref +); + +#keyset[id] +meta_is_unsafe( + int id: @meta ref +); + +#keyset[id] +meta_paths( + int id: @meta ref, + int path: @path ref +); + +#keyset[id] +meta_token_trees( + int id: @meta ref, + int token_tree: @token_tree ref +); + +names( + unique int id: @name +); + +#keyset[id] +name_texts( + int id: @name ref, + string text: string ref +); + +@param_base = + @param +| @self_param +; + +#keyset[id, index] +param_base_attrs( + int id: @param_base ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +param_base_type_reprs( + int id: @param_base ref, + int type_repr: @type_repr ref +); + +param_lists( + unique int id: @param_list +); + +#keyset[id, index] +param_list_params( + int id: @param_list ref, + int index: int ref, + int param: @param ref +); + +#keyset[id] +param_list_self_params( + int id: @param_list ref, + int self_param: @self_param ref +); + +parenthesized_arg_lists( + unique int id: @parenthesized_arg_list +); + +#keyset[id, index] +parenthesized_arg_list_type_args( + int id: @parenthesized_arg_list ref, + int index: int ref, + int type_arg: @type_arg ref +); + +@pat = + @box_pat +| @const_block_pat +| @ident_pat +| @literal_pat +| @macro_pat +| @or_pat +| @paren_pat +| @path_pat +| @range_pat +| @ref_pat +| @rest_pat +| @slice_pat +| @struct_pat +| @tuple_pat +| @tuple_struct_pat +| @wildcard_pat +; + +paths( + unique int id: @path +); + +#keyset[id] +path_qualifiers( + int id: @path ref, + int qualifier: @path ref +); + +#keyset[id] +path_segments_( + int id: @path ref, + int segment: @path_segment ref +); + +@path_ast_node = + @path_expr +| @path_pat +| @struct_expr +| @struct_pat +| @tuple_struct_pat +; + +#keyset[id] +path_ast_node_paths( + int id: @path_ast_node ref, + int path: @path ref +); + +path_segments( + unique int id: @path_segment +); + +#keyset[id] +path_segment_generic_arg_lists( + int id: @path_segment ref, + int generic_arg_list: @generic_arg_list ref +); + +#keyset[id] +path_segment_identifiers( + int id: @path_segment ref, + int identifier: @name_ref ref +); + +#keyset[id] +path_segment_parenthesized_arg_lists( + int id: @path_segment ref, + int parenthesized_arg_list: @parenthesized_arg_list ref +); + +#keyset[id] +path_segment_ret_types( + int id: @path_segment ref, + int ret_type: @ret_type_repr ref +); + +#keyset[id] +path_segment_return_type_syntaxes( + int id: @path_segment ref, + int return_type_syntax: @return_type_syntax ref +); + +#keyset[id] +path_segment_type_reprs( + int id: @path_segment ref, + int type_repr: @type_repr ref +); + +#keyset[id] +path_segment_trait_type_reprs( + int id: @path_segment ref, + int trait_type_repr: @path_type_repr ref +); + +renames( + unique int id: @rename +); + +#keyset[id] +rename_names( + int id: @rename ref, + int name: @name ref +); + +ret_type_reprs( + unique int id: @ret_type_repr +); + +#keyset[id] +ret_type_repr_type_reprs( + int id: @ret_type_repr ref, + int type_repr: @type_repr ref +); + +return_type_syntaxes( + unique int id: @return_type_syntax +); + +source_files( + unique int id: @source_file +); + +#keyset[id, index] +source_file_attrs( + int id: @source_file ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id, index] +source_file_items( + int id: @source_file ref, + int index: int ref, + int item: @item ref +); + +@stmt = + @expr_stmt +| @item +| @let_stmt +; + +stmt_lists( + unique int id: @stmt_list +); + +#keyset[id, index] +stmt_list_attrs( + int id: @stmt_list ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id, index] +stmt_list_statements( + int id: @stmt_list ref, + int index: int ref, + int statement: @stmt ref +); + +#keyset[id] +stmt_list_tail_exprs( + int id: @stmt_list ref, + int tail_expr: @expr ref +); + +struct_expr_fields( + unique int id: @struct_expr_field +); + +#keyset[id, index] +struct_expr_field_attrs( + int id: @struct_expr_field ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +struct_expr_field_exprs( + int id: @struct_expr_field ref, + int expr: @expr ref +); + +#keyset[id] +struct_expr_field_identifiers( + int id: @struct_expr_field ref, + int identifier: @name_ref ref +); + +struct_expr_field_lists( + unique int id: @struct_expr_field_list +); + +#keyset[id, index] +struct_expr_field_list_attrs( + int id: @struct_expr_field_list ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id, index] +struct_expr_field_list_fields( + int id: @struct_expr_field_list ref, + int index: int ref, + int field: @struct_expr_field ref +); + +#keyset[id] +struct_expr_field_list_spreads( + int id: @struct_expr_field_list ref, + int spread: @expr ref +); + +struct_fields( + unique int id: @struct_field +); + +#keyset[id, index] +struct_field_attrs( + int id: @struct_field ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +struct_field_defaults( + int id: @struct_field ref, + int default: @expr ref +); + +#keyset[id] +struct_field_is_unsafe( + int id: @struct_field ref +); + +#keyset[id] +struct_field_names( + int id: @struct_field ref, + int name: @name ref +); + +#keyset[id] +struct_field_type_reprs( + int id: @struct_field ref, + int type_repr: @type_repr ref +); + +#keyset[id] +struct_field_visibilities( + int id: @struct_field ref, + int visibility: @visibility ref +); + +struct_pat_fields( + unique int id: @struct_pat_field +); + +#keyset[id, index] +struct_pat_field_attrs( + int id: @struct_pat_field ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +struct_pat_field_identifiers( + int id: @struct_pat_field ref, + int identifier: @name_ref ref +); + +#keyset[id] +struct_pat_field_pats( + int id: @struct_pat_field ref, + int pat: @pat ref +); + +struct_pat_field_lists( + unique int id: @struct_pat_field_list +); + +#keyset[id, index] +struct_pat_field_list_fields( + int id: @struct_pat_field_list ref, + int index: int ref, + int field: @struct_pat_field ref +); + +#keyset[id] +struct_pat_field_list_rest_pats( + int id: @struct_pat_field_list ref, + int rest_pat: @rest_pat ref +); + +@token = + @comment +; + +token_trees( + unique int id: @token_tree +); + +tuple_fields( + unique int id: @tuple_field +); + +#keyset[id, index] +tuple_field_attrs( + int id: @tuple_field ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +tuple_field_type_reprs( + int id: @tuple_field ref, + int type_repr: @type_repr ref +); + +#keyset[id] +tuple_field_visibilities( + int id: @tuple_field ref, + int visibility: @visibility ref +); + +type_bounds( + unique int id: @type_bound +); + +#keyset[id] +type_bound_for_binders( + int id: @type_bound ref, + int for_binder: @for_binder ref +); + +#keyset[id] +type_bound_is_async( + int id: @type_bound ref +); + +#keyset[id] +type_bound_is_const( + int id: @type_bound ref +); + +#keyset[id] +type_bound_lifetimes( + int id: @type_bound ref, + int lifetime: @lifetime ref +); + +#keyset[id] +type_bound_type_reprs( + int id: @type_bound ref, + int type_repr: @type_repr ref +); + +#keyset[id] +type_bound_use_bound_generic_args( + int id: @type_bound ref, + int use_bound_generic_args: @use_bound_generic_args ref +); + +type_bound_lists( + unique int id: @type_bound_list +); + +#keyset[id, index] +type_bound_list_bounds( + int id: @type_bound_list ref, + int index: int ref, + int bound: @type_bound ref +); + +@type_repr = + @array_type_repr +| @dyn_trait_type_repr +| @fn_ptr_type_repr +| @for_type_repr +| @impl_trait_type_repr +| @infer_type_repr +| @macro_type_repr +| @never_type_repr +| @paren_type_repr +| @path_type_repr +| @ptr_type_repr +| @ref_type_repr +| @slice_type_repr +| @tuple_type_repr +; + +@use_bound_generic_arg = + @lifetime +| @name_ref +; + +use_bound_generic_args( + unique int id: @use_bound_generic_args +); + +#keyset[id, index] +use_bound_generic_args_use_bound_generic_args( + int id: @use_bound_generic_args ref, + int index: int ref, + int use_bound_generic_arg: @use_bound_generic_arg ref +); + +use_trees( + unique int id: @use_tree +); + +#keyset[id] +use_tree_is_glob( + int id: @use_tree ref +); + +#keyset[id] +use_tree_paths( + int id: @use_tree ref, + int path: @path ref +); + +#keyset[id] +use_tree_renames( + int id: @use_tree ref, + int rename: @rename ref +); + +#keyset[id] +use_tree_use_tree_lists( + int id: @use_tree ref, + int use_tree_list: @use_tree_list ref +); + +use_tree_lists( + unique int id: @use_tree_list +); + +#keyset[id, index] +use_tree_list_use_trees( + int id: @use_tree_list ref, + int index: int ref, + int use_tree: @use_tree ref +); + +variant_lists( + unique int id: @variant_list +); + +#keyset[id, index] +variant_list_variants( + int id: @variant_list ref, + int index: int ref, + int variant: @variant ref +); + +visibilities( + unique int id: @visibility +); + +#keyset[id] +visibility_paths( + int id: @visibility ref, + int path: @path ref +); + +where_clauses( + unique int id: @where_clause +); + +#keyset[id, index] +where_clause_predicates( + int id: @where_clause ref, + int index: int ref, + int predicate: @where_pred ref +); + +where_preds( + unique int id: @where_pred +); + +#keyset[id] +where_pred_for_binders( + int id: @where_pred ref, + int for_binder: @for_binder ref +); + +#keyset[id] +where_pred_lifetimes( + int id: @where_pred ref, + int lifetime: @lifetime ref +); + +#keyset[id] +where_pred_type_reprs( + int id: @where_pred ref, + int type_repr: @type_repr ref +); + +#keyset[id] +where_pred_type_bound_lists( + int id: @where_pred ref, + int type_bound_list: @type_bound_list ref +); + +array_expr_internals( + unique int id: @array_expr_internal +); + +#keyset[id, index] +array_expr_internal_attrs( + int id: @array_expr_internal ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id, index] +array_expr_internal_exprs( + int id: @array_expr_internal ref, + int index: int ref, + int expr: @expr ref +); + +#keyset[id] +array_expr_internal_is_semicolon( + int id: @array_expr_internal ref +); + +array_type_reprs( + unique int id: @array_type_repr +); + +#keyset[id] +array_type_repr_const_args( + int id: @array_type_repr ref, + int const_arg: @const_arg ref +); + +#keyset[id] +array_type_repr_element_type_reprs( + int id: @array_type_repr ref, + int element_type_repr: @type_repr ref +); + +asm_clobber_abis( + unique int id: @asm_clobber_abi +); + +asm_consts( + unique int id: @asm_const +); + +#keyset[id] +asm_const_exprs( + int id: @asm_const ref, + int expr: @expr ref +); + +#keyset[id] +asm_const_is_const( + int id: @asm_const ref +); + +asm_labels( + unique int id: @asm_label +); + +#keyset[id] +asm_label_block_exprs( + int id: @asm_label ref, + int block_expr: @block_expr ref +); + +asm_operand_nameds( + unique int id: @asm_operand_named +); + +#keyset[id] +asm_operand_named_asm_operands( + int id: @asm_operand_named ref, + int asm_operand: @asm_operand ref +); + +#keyset[id] +asm_operand_named_names( + int id: @asm_operand_named ref, + int name: @name ref +); + +asm_options_lists( + unique int id: @asm_options_list +); + +#keyset[id, index] +asm_options_list_asm_options( + int id: @asm_options_list ref, + int index: int ref, + int asm_option: @asm_option ref +); + +asm_reg_operands( + unique int id: @asm_reg_operand +); + +#keyset[id] +asm_reg_operand_asm_dir_specs( + int id: @asm_reg_operand ref, + int asm_dir_spec: @asm_dir_spec ref +); + +#keyset[id] +asm_reg_operand_asm_operand_exprs( + int id: @asm_reg_operand ref, + int asm_operand_expr: @asm_operand_expr ref +); + +#keyset[id] +asm_reg_operand_asm_reg_specs( + int id: @asm_reg_operand ref, + int asm_reg_spec: @asm_reg_spec ref +); + +asm_syms( + unique int id: @asm_sym +); + +#keyset[id] +asm_sym_paths( + int id: @asm_sym ref, + int path: @path ref +); + +assoc_type_args( + unique int id: @assoc_type_arg +); + +#keyset[id] +assoc_type_arg_const_args( + int id: @assoc_type_arg ref, + int const_arg: @const_arg ref +); + +#keyset[id] +assoc_type_arg_generic_arg_lists( + int id: @assoc_type_arg ref, + int generic_arg_list: @generic_arg_list ref +); + +#keyset[id] +assoc_type_arg_identifiers( + int id: @assoc_type_arg ref, + int identifier: @name_ref ref +); + +#keyset[id] +assoc_type_arg_param_lists( + int id: @assoc_type_arg ref, + int param_list: @param_list ref +); + +#keyset[id] +assoc_type_arg_ret_types( + int id: @assoc_type_arg ref, + int ret_type: @ret_type_repr ref +); + +#keyset[id] +assoc_type_arg_return_type_syntaxes( + int id: @assoc_type_arg ref, + int return_type_syntax: @return_type_syntax ref +); + +#keyset[id] +assoc_type_arg_type_reprs( + int id: @assoc_type_arg ref, + int type_repr: @type_repr ref +); + +#keyset[id] +assoc_type_arg_type_bound_lists( + int id: @assoc_type_arg ref, + int type_bound_list: @type_bound_list ref +); + +await_exprs( + unique int id: @await_expr +); + +#keyset[id, index] +await_expr_attrs( + int id: @await_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +await_expr_exprs( + int id: @await_expr ref, + int expr: @expr ref +); + +become_exprs( + unique int id: @become_expr +); + +#keyset[id, index] +become_expr_attrs( + int id: @become_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +become_expr_exprs( + int id: @become_expr ref, + int expr: @expr ref +); + +binary_exprs( + unique int id: @binary_expr +); + +#keyset[id, index] +binary_expr_attrs( + int id: @binary_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +binary_expr_lhs( + int id: @binary_expr ref, + int lhs: @expr ref +); + +#keyset[id] +binary_expr_operator_names( + int id: @binary_expr ref, + string operator_name: string ref +); + +#keyset[id] +binary_expr_rhs( + int id: @binary_expr ref, + int rhs: @expr ref +); + +box_pats( + unique int id: @box_pat +); + +#keyset[id] +box_pat_pats( + int id: @box_pat ref, + int pat: @pat ref +); + +break_exprs( + unique int id: @break_expr +); + +#keyset[id, index] +break_expr_attrs( + int id: @break_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +break_expr_exprs( + int id: @break_expr ref, + int expr: @expr ref +); + +#keyset[id] +break_expr_lifetimes( + int id: @break_expr ref, + int lifetime: @lifetime ref +); + +@call_expr_base = + @call_expr +| @method_call_expr +; + +#keyset[id] +call_expr_base_arg_lists( + int id: @call_expr_base ref, + int arg_list: @arg_list ref +); + +#keyset[id, index] +call_expr_base_attrs( + int id: @call_expr_base ref, + int index: int ref, + int attr: @attr ref +); + +cast_exprs( + unique int id: @cast_expr +); + +#keyset[id, index] +cast_expr_attrs( + int id: @cast_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +cast_expr_exprs( + int id: @cast_expr ref, + int expr: @expr ref +); + +#keyset[id] +cast_expr_type_reprs( + int id: @cast_expr ref, + int type_repr: @type_repr ref +); + +closure_exprs( + unique int id: @closure_expr +); + +#keyset[id] +closure_expr_closure_bodies( + int id: @closure_expr ref, + int closure_body: @expr ref +); + +#keyset[id] +closure_expr_for_binders( + int id: @closure_expr ref, + int for_binder: @for_binder ref +); + +#keyset[id] +closure_expr_is_async( + int id: @closure_expr ref +); + +#keyset[id] +closure_expr_is_const( + int id: @closure_expr ref +); + +#keyset[id] +closure_expr_is_gen( + int id: @closure_expr ref +); + +#keyset[id] +closure_expr_is_move( + int id: @closure_expr ref +); + +#keyset[id] +closure_expr_is_static( + int id: @closure_expr ref +); + +#keyset[id] +closure_expr_ret_types( + int id: @closure_expr ref, + int ret_type: @ret_type_repr ref +); + +comments( + unique int id: @comment, + int parent: @ast_node ref, + string text: string ref +); + +const_args( + unique int id: @const_arg +); + +#keyset[id] +const_arg_exprs( + int id: @const_arg ref, + int expr: @expr ref +); + +const_block_pats( + unique int id: @const_block_pat +); + +#keyset[id] +const_block_pat_block_exprs( + int id: @const_block_pat ref, + int block_expr: @block_expr ref +); + +#keyset[id] +const_block_pat_is_const( + int id: @const_block_pat ref +); + +const_params( + unique int id: @const_param +); + +#keyset[id, index] +const_param_attrs( + int id: @const_param ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +const_param_default_vals( + int id: @const_param ref, + int default_val: @const_arg ref +); + +#keyset[id] +const_param_is_const( + int id: @const_param ref +); + +#keyset[id] +const_param_names( + int id: @const_param ref, + int name: @name ref +); + +#keyset[id] +const_param_type_reprs( + int id: @const_param ref, + int type_repr: @type_repr ref +); + +continue_exprs( + unique int id: @continue_expr +); + +#keyset[id, index] +continue_expr_attrs( + int id: @continue_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +continue_expr_lifetimes( + int id: @continue_expr ref, + int lifetime: @lifetime ref +); + +dyn_trait_type_reprs( + unique int id: @dyn_trait_type_repr +); + +#keyset[id] +dyn_trait_type_repr_type_bound_lists( + int id: @dyn_trait_type_repr ref, + int type_bound_list: @type_bound_list ref +); + +expr_stmts( + unique int id: @expr_stmt +); + +#keyset[id] +expr_stmt_exprs( + int id: @expr_stmt ref, + int expr: @expr ref +); + +field_exprs( + unique int id: @field_expr +); + +#keyset[id, index] +field_expr_attrs( + int id: @field_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +field_expr_containers( + int id: @field_expr ref, + int container: @expr ref +); + +#keyset[id] +field_expr_identifiers( + int id: @field_expr ref, + int identifier: @name_ref ref +); + +fn_ptr_type_reprs( + unique int id: @fn_ptr_type_repr +); + +#keyset[id] +fn_ptr_type_repr_abis( + int id: @fn_ptr_type_repr ref, + int abi: @abi ref +); + +#keyset[id] +fn_ptr_type_repr_is_async( + int id: @fn_ptr_type_repr ref +); + +#keyset[id] +fn_ptr_type_repr_is_const( + int id: @fn_ptr_type_repr ref +); + +#keyset[id] +fn_ptr_type_repr_is_unsafe( + int id: @fn_ptr_type_repr ref +); + +#keyset[id] +fn_ptr_type_repr_param_lists( + int id: @fn_ptr_type_repr ref, + int param_list: @param_list ref +); + +#keyset[id] +fn_ptr_type_repr_ret_types( + int id: @fn_ptr_type_repr ref, + int ret_type: @ret_type_repr ref +); + +for_type_reprs( + unique int id: @for_type_repr +); + +#keyset[id] +for_type_repr_for_binders( + int id: @for_type_repr ref, + int for_binder: @for_binder ref +); + +#keyset[id] +for_type_repr_type_reprs( + int id: @for_type_repr ref, + int type_repr: @type_repr ref +); + +format_args_exprs( + unique int id: @format_args_expr +); + +#keyset[id, index] +format_args_expr_args( + int id: @format_args_expr ref, + int index: int ref, + int arg: @format_args_arg ref +); + +#keyset[id, index] +format_args_expr_attrs( + int id: @format_args_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +format_args_expr_templates( + int id: @format_args_expr ref, + int template: @expr ref +); + +ident_pats( + unique int id: @ident_pat +); + +#keyset[id, index] +ident_pat_attrs( + int id: @ident_pat ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +ident_pat_is_mut( + int id: @ident_pat ref +); + +#keyset[id] +ident_pat_is_ref( + int id: @ident_pat ref +); + +#keyset[id] +ident_pat_names( + int id: @ident_pat ref, + int name: @name ref +); + +#keyset[id] +ident_pat_pats( + int id: @ident_pat ref, + int pat: @pat ref +); + +if_exprs( + unique int id: @if_expr +); + +#keyset[id, index] +if_expr_attrs( + int id: @if_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +if_expr_conditions( + int id: @if_expr ref, + int condition: @expr ref +); + +#keyset[id] +if_expr_elses( + int id: @if_expr ref, + int else: @expr ref +); + +#keyset[id] +if_expr_thens( + int id: @if_expr ref, + int then: @block_expr ref +); + +impl_trait_type_reprs( + unique int id: @impl_trait_type_repr +); + +#keyset[id] +impl_trait_type_repr_type_bound_lists( + int id: @impl_trait_type_repr ref, + int type_bound_list: @type_bound_list ref +); + +index_exprs( + unique int id: @index_expr +); + +#keyset[id, index] +index_expr_attrs( + int id: @index_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +index_expr_bases( + int id: @index_expr ref, + int base: @expr ref +); + +#keyset[id] +index_expr_indices( + int id: @index_expr ref, + int index: @expr ref +); + +infer_type_reprs( + unique int id: @infer_type_repr +); + +@item = + @adt +| @asm_expr +| @assoc_item +| @extern_block +| @extern_crate +| @extern_item +| @impl +| @macro_def +| @macro_rules +| @module +| @trait +| @trait_alias +| @use +; + +#keyset[id] +item_attribute_macro_expansions( + int id: @item ref, + int attribute_macro_expansion: @macro_items ref +); + +@labelable_expr = + @block_expr +| @looping_expr +; + +#keyset[id] +labelable_expr_labels( + int id: @labelable_expr ref, + int label: @label ref +); + +let_exprs( + unique int id: @let_expr +); + +#keyset[id, index] +let_expr_attrs( + int id: @let_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +let_expr_scrutinees( + int id: @let_expr ref, + int scrutinee: @expr ref +); + +#keyset[id] +let_expr_pats( + int id: @let_expr ref, + int pat: @pat ref +); + +let_stmts( + unique int id: @let_stmt +); + +#keyset[id, index] +let_stmt_attrs( + int id: @let_stmt ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +let_stmt_initializers( + int id: @let_stmt ref, + int initializer: @expr ref +); + +#keyset[id] +let_stmt_let_elses( + int id: @let_stmt ref, + int let_else: @let_else ref +); + +#keyset[id] +let_stmt_pats( + int id: @let_stmt ref, + int pat: @pat ref +); + +#keyset[id] +let_stmt_type_reprs( + int id: @let_stmt ref, + int type_repr: @type_repr ref +); + +lifetimes( + unique int id: @lifetime +); + +#keyset[id] +lifetime_texts( + int id: @lifetime ref, + string text: string ref +); + +lifetime_args( + unique int id: @lifetime_arg +); + +#keyset[id] +lifetime_arg_lifetimes( + int id: @lifetime_arg ref, + int lifetime: @lifetime ref +); + +lifetime_params( + unique int id: @lifetime_param +); + +#keyset[id, index] +lifetime_param_attrs( + int id: @lifetime_param ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +lifetime_param_lifetimes( + int id: @lifetime_param ref, + int lifetime: @lifetime ref +); + +#keyset[id] +lifetime_param_type_bound_lists( + int id: @lifetime_param ref, + int type_bound_list: @type_bound_list ref +); + +literal_exprs( + unique int id: @literal_expr +); + +#keyset[id, index] +literal_expr_attrs( + int id: @literal_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +literal_expr_text_values( + int id: @literal_expr ref, + string text_value: string ref +); + +literal_pats( + unique int id: @literal_pat +); + +#keyset[id] +literal_pat_literals( + int id: @literal_pat ref, + int literal: @literal_expr ref +); + +macro_block_exprs( + unique int id: @macro_block_expr +); + +#keyset[id, index] +macro_block_expr_statements( + int id: @macro_block_expr ref, + int index: int ref, + int statement: @stmt ref +); + +#keyset[id] +macro_block_expr_tail_exprs( + int id: @macro_block_expr ref, + int tail_expr: @expr ref +); + +macro_exprs( + unique int id: @macro_expr +); + +#keyset[id] +macro_expr_macro_calls( + int id: @macro_expr ref, + int macro_call: @macro_call ref +); + +macro_pats( + unique int id: @macro_pat +); + +#keyset[id] +macro_pat_macro_calls( + int id: @macro_pat ref, + int macro_call: @macro_call ref +); + +macro_type_reprs( + unique int id: @macro_type_repr +); + +#keyset[id] +macro_type_repr_macro_calls( + int id: @macro_type_repr ref, + int macro_call: @macro_call ref +); + +match_exprs( + unique int id: @match_expr +); + +#keyset[id, index] +match_expr_attrs( + int id: @match_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +match_expr_scrutinees( + int id: @match_expr ref, + int scrutinee: @expr ref +); + +#keyset[id] +match_expr_match_arm_lists( + int id: @match_expr ref, + int match_arm_list: @match_arm_list ref +); + +name_refs( + unique int id: @name_ref +); + +#keyset[id] +name_ref_texts( + int id: @name_ref ref, + string text: string ref +); + +never_type_reprs( + unique int id: @never_type_repr +); + +offset_of_exprs( + unique int id: @offset_of_expr +); + +#keyset[id, index] +offset_of_expr_attrs( + int id: @offset_of_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id, index] +offset_of_expr_fields( + int id: @offset_of_expr ref, + int index: int ref, + int field: @name_ref ref +); + +#keyset[id] +offset_of_expr_type_reprs( + int id: @offset_of_expr ref, + int type_repr: @type_repr ref +); + +or_pats( + unique int id: @or_pat +); + +#keyset[id, index] +or_pat_pats( + int id: @or_pat ref, + int index: int ref, + int pat: @pat ref +); + +params( + unique int id: @param +); + +#keyset[id] +param_pats( + int id: @param ref, + int pat: @pat ref +); + +paren_exprs( + unique int id: @paren_expr +); + +#keyset[id, index] +paren_expr_attrs( + int id: @paren_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +paren_expr_exprs( + int id: @paren_expr ref, + int expr: @expr ref +); + +paren_pats( + unique int id: @paren_pat +); + +#keyset[id] +paren_pat_pats( + int id: @paren_pat ref, + int pat: @pat ref +); + +paren_type_reprs( + unique int id: @paren_type_repr +); + +#keyset[id] +paren_type_repr_type_reprs( + int id: @paren_type_repr ref, + int type_repr: @type_repr ref +); + +@path_expr_base = + @path_expr +; + +path_pats( + unique int id: @path_pat +); + +path_type_reprs( + unique int id: @path_type_repr +); + +#keyset[id] +path_type_repr_paths( + int id: @path_type_repr ref, + int path: @path ref +); + +prefix_exprs( + unique int id: @prefix_expr +); + +#keyset[id, index] +prefix_expr_attrs( + int id: @prefix_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +prefix_expr_exprs( + int id: @prefix_expr ref, + int expr: @expr ref +); + +#keyset[id] +prefix_expr_operator_names( + int id: @prefix_expr ref, + string operator_name: string ref +); + +ptr_type_reprs( + unique int id: @ptr_type_repr +); + +#keyset[id] +ptr_type_repr_is_const( + int id: @ptr_type_repr ref +); + +#keyset[id] +ptr_type_repr_is_mut( + int id: @ptr_type_repr ref +); + +#keyset[id] +ptr_type_repr_type_reprs( + int id: @ptr_type_repr ref, + int type_repr: @type_repr ref +); + +range_exprs( + unique int id: @range_expr +); + +#keyset[id, index] +range_expr_attrs( + int id: @range_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +range_expr_ends( + int id: @range_expr ref, + int end: @expr ref +); + +#keyset[id] +range_expr_operator_names( + int id: @range_expr ref, + string operator_name: string ref +); + +#keyset[id] +range_expr_starts( + int id: @range_expr ref, + int start: @expr ref +); + +range_pats( + unique int id: @range_pat +); + +#keyset[id] +range_pat_ends( + int id: @range_pat ref, + int end: @pat ref +); + +#keyset[id] +range_pat_operator_names( + int id: @range_pat ref, + string operator_name: string ref +); + +#keyset[id] +range_pat_starts( + int id: @range_pat ref, + int start: @pat ref +); + +ref_exprs( + unique int id: @ref_expr +); + +#keyset[id, index] +ref_expr_attrs( + int id: @ref_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +ref_expr_exprs( + int id: @ref_expr ref, + int expr: @expr ref +); + +#keyset[id] +ref_expr_is_const( + int id: @ref_expr ref +); + +#keyset[id] +ref_expr_is_mut( + int id: @ref_expr ref +); + +#keyset[id] +ref_expr_is_raw( + int id: @ref_expr ref +); + +ref_pats( + unique int id: @ref_pat +); + +#keyset[id] +ref_pat_is_mut( + int id: @ref_pat ref +); + +#keyset[id] +ref_pat_pats( + int id: @ref_pat ref, + int pat: @pat ref +); + +ref_type_reprs( + unique int id: @ref_type_repr +); + +#keyset[id] +ref_type_repr_is_mut( + int id: @ref_type_repr ref +); + +#keyset[id] +ref_type_repr_lifetimes( + int id: @ref_type_repr ref, + int lifetime: @lifetime ref +); + +#keyset[id] +ref_type_repr_type_reprs( + int id: @ref_type_repr ref, + int type_repr: @type_repr ref +); + +rest_pats( + unique int id: @rest_pat +); + +#keyset[id, index] +rest_pat_attrs( + int id: @rest_pat ref, + int index: int ref, + int attr: @attr ref +); + +return_exprs( + unique int id: @return_expr +); + +#keyset[id, index] +return_expr_attrs( + int id: @return_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +return_expr_exprs( + int id: @return_expr ref, + int expr: @expr ref +); + +self_params( + unique int id: @self_param +); + +#keyset[id] +self_param_is_ref( + int id: @self_param ref +); + +#keyset[id] +self_param_is_mut( + int id: @self_param ref +); + +#keyset[id] +self_param_lifetimes( + int id: @self_param ref, + int lifetime: @lifetime ref +); + +#keyset[id] +self_param_names( + int id: @self_param ref, + int name: @name ref +); + +slice_pats( + unique int id: @slice_pat +); + +#keyset[id, index] +slice_pat_pats( + int id: @slice_pat ref, + int index: int ref, + int pat: @pat ref +); + +slice_type_reprs( + unique int id: @slice_type_repr +); + +#keyset[id] +slice_type_repr_type_reprs( + int id: @slice_type_repr ref, + int type_repr: @type_repr ref +); + +struct_exprs( + unique int id: @struct_expr +); + +#keyset[id] +struct_expr_struct_expr_field_lists( + int id: @struct_expr ref, + int struct_expr_field_list: @struct_expr_field_list ref +); + +struct_field_lists( + unique int id: @struct_field_list +); + +#keyset[id, index] +struct_field_list_fields( + int id: @struct_field_list ref, + int index: int ref, + int field: @struct_field ref +); + +struct_pats( + unique int id: @struct_pat +); + +#keyset[id] +struct_pat_struct_pat_field_lists( + int id: @struct_pat ref, + int struct_pat_field_list: @struct_pat_field_list ref +); + +try_exprs( + unique int id: @try_expr +); + +#keyset[id, index] +try_expr_attrs( + int id: @try_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +try_expr_exprs( + int id: @try_expr ref, + int expr: @expr ref +); + +tuple_exprs( + unique int id: @tuple_expr +); + +#keyset[id, index] +tuple_expr_attrs( + int id: @tuple_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id, index] +tuple_expr_fields( + int id: @tuple_expr ref, + int index: int ref, + int field: @expr ref +); + +tuple_field_lists( + unique int id: @tuple_field_list +); + +#keyset[id, index] +tuple_field_list_fields( + int id: @tuple_field_list ref, + int index: int ref, + int field: @tuple_field ref +); + +tuple_pats( + unique int id: @tuple_pat +); + +#keyset[id, index] +tuple_pat_fields( + int id: @tuple_pat ref, + int index: int ref, + int field: @pat ref +); + +tuple_struct_pats( + unique int id: @tuple_struct_pat +); + +#keyset[id, index] +tuple_struct_pat_fields( + int id: @tuple_struct_pat ref, + int index: int ref, + int field: @pat ref +); + +tuple_type_reprs( + unique int id: @tuple_type_repr +); + +#keyset[id, index] +tuple_type_repr_fields( + int id: @tuple_type_repr ref, + int index: int ref, + int field: @type_repr ref +); + +type_args( + unique int id: @type_arg +); + +#keyset[id] +type_arg_type_reprs( + int id: @type_arg ref, + int type_repr: @type_repr ref +); + +type_params( + unique int id: @type_param +); + +#keyset[id, index] +type_param_attrs( + int id: @type_param ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +type_param_default_types( + int id: @type_param ref, + int default_type: @type_repr ref +); + +#keyset[id] +type_param_names( + int id: @type_param ref, + int name: @name ref +); + +#keyset[id] +type_param_type_bound_lists( + int id: @type_param ref, + int type_bound_list: @type_bound_list ref +); + +underscore_exprs( + unique int id: @underscore_expr +); + +#keyset[id, index] +underscore_expr_attrs( + int id: @underscore_expr ref, + int index: int ref, + int attr: @attr ref +); + +variants( + unique int id: @variant +); + +#keyset[id, index] +variant_attrs( + int id: @variant ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +variant_discriminants( + int id: @variant ref, + int discriminant: @expr ref +); + +#keyset[id] +variant_field_lists( + int id: @variant ref, + int field_list: @field_list ref +); + +#keyset[id] +variant_names( + int id: @variant ref, + int name: @name ref +); + +#keyset[id] +variant_visibilities( + int id: @variant ref, + int visibility: @visibility ref +); + +wildcard_pats( + unique int id: @wildcard_pat +); + +yeet_exprs( + unique int id: @yeet_expr +); + +#keyset[id, index] +yeet_expr_attrs( + int id: @yeet_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +yeet_expr_exprs( + int id: @yeet_expr ref, + int expr: @expr ref +); + +yield_exprs( + unique int id: @yield_expr +); + +#keyset[id, index] +yield_expr_attrs( + int id: @yield_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +yield_expr_exprs( + int id: @yield_expr ref, + int expr: @expr ref +); + +@adt = + @enum +| @struct +| @union +; + +#keyset[id, index] +adt_derive_macro_expansions( + int id: @adt ref, + int index: int ref, + int derive_macro_expansion: @macro_items ref +); + +asm_exprs( + unique int id: @asm_expr +); + +#keyset[id, index] +asm_expr_asm_pieces( + int id: @asm_expr ref, + int index: int ref, + int asm_piece: @asm_piece ref +); + +#keyset[id, index] +asm_expr_attrs( + int id: @asm_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id, index] +asm_expr_templates( + int id: @asm_expr ref, + int index: int ref, + int template: @expr ref +); + +@assoc_item = + @const +| @function +| @macro_call +| @type_alias +; + +block_exprs( + unique int id: @block_expr +); + +#keyset[id, index] +block_expr_attrs( + int id: @block_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +block_expr_is_async( + int id: @block_expr ref +); + +#keyset[id] +block_expr_is_const( + int id: @block_expr ref +); + +#keyset[id] +block_expr_is_gen( + int id: @block_expr ref +); + +#keyset[id] +block_expr_is_move( + int id: @block_expr ref +); + +#keyset[id] +block_expr_is_try( + int id: @block_expr ref +); + +#keyset[id] +block_expr_is_unsafe( + int id: @block_expr ref +); + +#keyset[id] +block_expr_stmt_lists( + int id: @block_expr ref, + int stmt_list: @stmt_list ref +); + +call_exprs( + unique int id: @call_expr +); + +#keyset[id] +call_expr_functions( + int id: @call_expr ref, + int function: @expr ref +); + +extern_blocks( + unique int id: @extern_block +); + +#keyset[id] +extern_block_abis( + int id: @extern_block ref, + int abi: @abi ref +); + +#keyset[id, index] +extern_block_attrs( + int id: @extern_block ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +extern_block_extern_item_lists( + int id: @extern_block ref, + int extern_item_list: @extern_item_list ref +); + +#keyset[id] +extern_block_is_unsafe( + int id: @extern_block ref +); + +extern_crates( + unique int id: @extern_crate +); + +#keyset[id, index] +extern_crate_attrs( + int id: @extern_crate ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +extern_crate_identifiers( + int id: @extern_crate ref, + int identifier: @name_ref ref +); + +#keyset[id] +extern_crate_renames( + int id: @extern_crate ref, + int rename: @rename ref +); + +#keyset[id] +extern_crate_visibilities( + int id: @extern_crate ref, + int visibility: @visibility ref +); + +@extern_item = + @function +| @macro_call +| @static +| @type_alias +; + +impls( + unique int id: @impl +); + +#keyset[id] +impl_assoc_item_lists( + int id: @impl ref, + int assoc_item_list: @assoc_item_list ref +); + +#keyset[id, index] +impl_attrs( + int id: @impl ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +impl_generic_param_lists( + int id: @impl ref, + int generic_param_list: @generic_param_list ref +); + +#keyset[id] +impl_is_const( + int id: @impl ref +); + +#keyset[id] +impl_is_default( + int id: @impl ref +); + +#keyset[id] +impl_is_unsafe( + int id: @impl ref +); + +#keyset[id] +impl_self_ties( + int id: @impl ref, + int self_ty: @type_repr ref +); + +#keyset[id] +impl_traits( + int id: @impl ref, + int trait: @type_repr ref +); + +#keyset[id] +impl_visibilities( + int id: @impl ref, + int visibility: @visibility ref +); + +#keyset[id] +impl_where_clauses( + int id: @impl ref, + int where_clause: @where_clause ref +); + +@looping_expr = + @for_expr +| @loop_expr +| @while_expr +; + +#keyset[id] +looping_expr_loop_bodies( + int id: @looping_expr ref, + int loop_body: @block_expr ref +); + +macro_defs( + unique int id: @macro_def +); + +#keyset[id] +macro_def_args( + int id: @macro_def ref, + int args: @token_tree ref +); + +#keyset[id, index] +macro_def_attrs( + int id: @macro_def ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +macro_def_bodies( + int id: @macro_def ref, + int body: @token_tree ref +); + +#keyset[id] +macro_def_names( + int id: @macro_def ref, + int name: @name ref +); + +#keyset[id] +macro_def_visibilities( + int id: @macro_def ref, + int visibility: @visibility ref +); + +macro_rules( + unique int id: @macro_rules +); + +#keyset[id, index] +macro_rules_attrs( + int id: @macro_rules ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +macro_rules_names( + int id: @macro_rules ref, + int name: @name ref +); + +#keyset[id] +macro_rules_token_trees( + int id: @macro_rules ref, + int token_tree: @token_tree ref +); + +#keyset[id] +macro_rules_visibilities( + int id: @macro_rules ref, + int visibility: @visibility ref +); + +method_call_exprs( + unique int id: @method_call_expr +); + +#keyset[id] +method_call_expr_generic_arg_lists( + int id: @method_call_expr ref, + int generic_arg_list: @generic_arg_list ref +); + +#keyset[id] +method_call_expr_identifiers( + int id: @method_call_expr ref, + int identifier: @name_ref ref +); + +#keyset[id] +method_call_expr_receivers( + int id: @method_call_expr ref, + int receiver: @expr ref +); + +modules( + unique int id: @module +); + +#keyset[id, index] +module_attrs( + int id: @module ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +module_item_lists( + int id: @module ref, + int item_list: @item_list ref +); + +#keyset[id] +module_names( + int id: @module ref, + int name: @name ref +); + +#keyset[id] +module_visibilities( + int id: @module ref, + int visibility: @visibility ref +); + +path_exprs( + unique int id: @path_expr +); + +#keyset[id, index] +path_expr_attrs( + int id: @path_expr ref, + int index: int ref, + int attr: @attr ref +); + +traits( + unique int id: @trait +); + +#keyset[id] +trait_assoc_item_lists( + int id: @trait ref, + int assoc_item_list: @assoc_item_list ref +); + +#keyset[id, index] +trait_attrs( + int id: @trait ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +trait_generic_param_lists( + int id: @trait ref, + int generic_param_list: @generic_param_list ref +); + +#keyset[id] +trait_is_auto( + int id: @trait ref +); + +#keyset[id] +trait_is_unsafe( + int id: @trait ref +); + +#keyset[id] +trait_names( + int id: @trait ref, + int name: @name ref +); + +#keyset[id] +trait_type_bound_lists( + int id: @trait ref, + int type_bound_list: @type_bound_list ref +); + +#keyset[id] +trait_visibilities( + int id: @trait ref, + int visibility: @visibility ref +); + +#keyset[id] +trait_where_clauses( + int id: @trait ref, + int where_clause: @where_clause ref +); + +trait_aliases( + unique int id: @trait_alias +); + +#keyset[id, index] +trait_alias_attrs( + int id: @trait_alias ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +trait_alias_generic_param_lists( + int id: @trait_alias ref, + int generic_param_list: @generic_param_list ref +); + +#keyset[id] +trait_alias_names( + int id: @trait_alias ref, + int name: @name ref +); + +#keyset[id] +trait_alias_type_bound_lists( + int id: @trait_alias ref, + int type_bound_list: @type_bound_list ref +); + +#keyset[id] +trait_alias_visibilities( + int id: @trait_alias ref, + int visibility: @visibility ref +); + +#keyset[id] +trait_alias_where_clauses( + int id: @trait_alias ref, + int where_clause: @where_clause ref +); + +uses( + unique int id: @use +); + +#keyset[id, index] +use_attrs( + int id: @use ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +use_use_trees( + int id: @use ref, + int use_tree: @use_tree ref +); + +#keyset[id] +use_visibilities( + int id: @use ref, + int visibility: @visibility ref +); + +consts( + unique int id: @const +); + +#keyset[id, index] +const_attrs( + int id: @const ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +const_bodies( + int id: @const ref, + int body: @expr ref +); + +#keyset[id] +const_generic_param_lists( + int id: @const ref, + int generic_param_list: @generic_param_list ref +); + +#keyset[id] +const_is_const( + int id: @const ref +); + +#keyset[id] +const_is_default( + int id: @const ref +); + +#keyset[id] +const_names( + int id: @const ref, + int name: @name ref +); + +#keyset[id] +const_type_reprs( + int id: @const ref, + int type_repr: @type_repr ref +); + +#keyset[id] +const_visibilities( + int id: @const ref, + int visibility: @visibility ref +); + +#keyset[id] +const_where_clauses( + int id: @const ref, + int where_clause: @where_clause ref +); + +#keyset[id] +const_has_implementation( + int id: @const ref +); + +enums( + unique int id: @enum +); + +#keyset[id, index] +enum_attrs( + int id: @enum ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +enum_generic_param_lists( + int id: @enum ref, + int generic_param_list: @generic_param_list ref +); + +#keyset[id] +enum_names( + int id: @enum ref, + int name: @name ref +); + +#keyset[id] +enum_variant_lists( + int id: @enum ref, + int variant_list: @variant_list ref +); + +#keyset[id] +enum_visibilities( + int id: @enum ref, + int visibility: @visibility ref +); + +#keyset[id] +enum_where_clauses( + int id: @enum ref, + int where_clause: @where_clause ref +); + +for_exprs( + unique int id: @for_expr +); + +#keyset[id, index] +for_expr_attrs( + int id: @for_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +for_expr_iterables( + int id: @for_expr ref, + int iterable: @expr ref +); + +#keyset[id] +for_expr_pats( + int id: @for_expr ref, + int pat: @pat ref +); + +functions( + unique int id: @function +); + +#keyset[id] +function_abis( + int id: @function ref, + int abi: @abi ref +); + +#keyset[id] +function_function_bodies( + int id: @function ref, + int function_body: @block_expr ref +); + +#keyset[id] +function_generic_param_lists( + int id: @function ref, + int generic_param_list: @generic_param_list ref +); + +#keyset[id] +function_is_async( + int id: @function ref +); + +#keyset[id] +function_is_const( + int id: @function ref +); + +#keyset[id] +function_is_default( + int id: @function ref +); + +#keyset[id] +function_is_gen( + int id: @function ref +); + +#keyset[id] +function_is_unsafe( + int id: @function ref +); + +#keyset[id] +function_names( + int id: @function ref, + int name: @name ref +); + +#keyset[id] +function_ret_types( + int id: @function ref, + int ret_type: @ret_type_repr ref +); + +#keyset[id] +function_visibilities( + int id: @function ref, + int visibility: @visibility ref +); + +#keyset[id] +function_where_clauses( + int id: @function ref, + int where_clause: @where_clause ref +); + +#keyset[id] +function_has_implementation( + int id: @function ref +); + +loop_exprs( + unique int id: @loop_expr +); + +#keyset[id, index] +loop_expr_attrs( + int id: @loop_expr ref, + int index: int ref, + int attr: @attr ref +); + +macro_calls( + unique int id: @macro_call +); + +#keyset[id, index] +macro_call_attrs( + int id: @macro_call ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +macro_call_paths( + int id: @macro_call ref, + int path: @path ref +); + +#keyset[id] +macro_call_token_trees( + int id: @macro_call ref, + int token_tree: @token_tree ref +); + +#keyset[id] +macro_call_macro_call_expansions( + int id: @macro_call ref, + int macro_call_expansion: @ast_node ref +); + +statics( + unique int id: @static +); + +#keyset[id, index] +static_attrs( + int id: @static ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +static_bodies( + int id: @static ref, + int body: @expr ref +); + +#keyset[id] +static_is_mut( + int id: @static ref +); + +#keyset[id] +static_is_static( + int id: @static ref +); + +#keyset[id] +static_is_unsafe( + int id: @static ref +); + +#keyset[id] +static_names( + int id: @static ref, + int name: @name ref +); + +#keyset[id] +static_type_reprs( + int id: @static ref, + int type_repr: @type_repr ref +); + +#keyset[id] +static_visibilities( + int id: @static ref, + int visibility: @visibility ref +); + +structs( + unique int id: @struct +); + +#keyset[id, index] +struct_attrs( + int id: @struct ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +struct_field_lists_( + int id: @struct ref, + int field_list: @field_list ref +); + +#keyset[id] +struct_generic_param_lists( + int id: @struct ref, + int generic_param_list: @generic_param_list ref +); + +#keyset[id] +struct_names( + int id: @struct ref, + int name: @name ref +); + +#keyset[id] +struct_visibilities( + int id: @struct ref, + int visibility: @visibility ref +); + +#keyset[id] +struct_where_clauses( + int id: @struct ref, + int where_clause: @where_clause ref +); + +type_aliases( + unique int id: @type_alias +); + +#keyset[id, index] +type_alias_attrs( + int id: @type_alias ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +type_alias_generic_param_lists( + int id: @type_alias ref, + int generic_param_list: @generic_param_list ref +); + +#keyset[id] +type_alias_is_default( + int id: @type_alias ref +); + +#keyset[id] +type_alias_names( + int id: @type_alias ref, + int name: @name ref +); + +#keyset[id] +type_alias_type_reprs( + int id: @type_alias ref, + int type_repr: @type_repr ref +); + +#keyset[id] +type_alias_type_bound_lists( + int id: @type_alias ref, + int type_bound_list: @type_bound_list ref +); + +#keyset[id] +type_alias_visibilities( + int id: @type_alias ref, + int visibility: @visibility ref +); + +#keyset[id] +type_alias_where_clauses( + int id: @type_alias ref, + int where_clause: @where_clause ref +); + +unions( + unique int id: @union +); + +#keyset[id, index] +union_attrs( + int id: @union ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +union_generic_param_lists( + int id: @union ref, + int generic_param_list: @generic_param_list ref +); + +#keyset[id] +union_names( + int id: @union ref, + int name: @name ref +); + +#keyset[id] +union_struct_field_lists( + int id: @union ref, + int struct_field_list: @struct_field_list ref +); + +#keyset[id] +union_visibilities( + int id: @union ref, + int visibility: @visibility ref +); + +#keyset[id] +union_where_clauses( + int id: @union ref, + int where_clause: @where_clause ref +); + +while_exprs( + unique int id: @while_expr +); + +#keyset[id, index] +while_expr_attrs( + int id: @while_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +while_expr_conditions( + int id: @while_expr ref, + int condition: @expr ref +); diff --git a/rust/ql/lib/upgrades/30a0713e5bf69c60d003e4994e5abd1c78a36826/rust.dbscheme b/rust/ql/lib/upgrades/30a0713e5bf69c60d003e4994e5abd1c78a36826/rust.dbscheme new file mode 100644 index 00000000000..e54d01f67a4 --- /dev/null +++ b/rust/ql/lib/upgrades/30a0713e5bf69c60d003e4994e5abd1c78a36826/rust.dbscheme @@ -0,0 +1,3624 @@ +// generated by codegen, do not edit + +// from ../shared/tree-sitter-extractor/src/generator/prefix.dbscheme +/*- Files and folders -*/ + +/** + * The location of an element. + * The location spans column `startcolumn` of line `startline` to + * column `endcolumn` of line `endline` in file `file`. + * For more information, see + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). + */ +locations_default( + unique int id: @location_default, + int file: @file ref, + int beginLine: int ref, + int beginColumn: int ref, + int endLine: int ref, + int endColumn: int ref +); + +files( + unique int id: @file, + string name: string ref +); + +folders( + unique int id: @folder, + string name: string ref +); + +@container = @file | @folder + +containerparent( + int parent: @container ref, + unique int child: @container ref +); + +/*- Empty location -*/ + +empty_location( + int location: @location_default ref +); + +/*- Source location prefix -*/ + +/** + * The source location of the snapshot. + */ +sourceLocationPrefix(string prefix : string ref); + +/*- Diagnostic messages -*/ + +diagnostics( + unique int id: @diagnostic, + int severity: int ref, + string error_tag: string ref, + string error_message: string ref, + string full_error_message: string ref, + int location: @location_default ref +); + +/*- Diagnostic messages: severity -*/ + +case @diagnostic.severity of + 10 = @diagnostic_debug +| 20 = @diagnostic_info +| 30 = @diagnostic_warning +| 40 = @diagnostic_error +; + +/*- YAML -*/ + +#keyset[parent, idx] +yaml (unique int id: @yaml_node, + int kind: int ref, + int parent: @yaml_node_parent ref, + int idx: int ref, + string tag: string ref, + string tostring: string ref); + +case @yaml_node.kind of + 0 = @yaml_scalar_node +| 1 = @yaml_mapping_node +| 2 = @yaml_sequence_node +| 3 = @yaml_alias_node +; + +@yaml_collection_node = @yaml_mapping_node | @yaml_sequence_node; + +@yaml_node_parent = @yaml_collection_node | @file; + +yaml_anchors (unique int node: @yaml_node ref, + string anchor: string ref); + +yaml_aliases (unique int alias: @yaml_alias_node ref, + string target: string ref); + +yaml_scalars (unique int scalar: @yaml_scalar_node ref, + int style: int ref, + string value: string ref); + +yaml_errors (unique int id: @yaml_error, + string message: string ref); + +yaml_locations(unique int locatable: @yaml_locatable ref, + int location: @location_default ref); + +@yaml_locatable = @yaml_node | @yaml_error; + +/*- Database metadata -*/ +databaseMetadata( + string metadataKey: string ref, + string value: string ref +); + +overlayChangedFiles( + string path: string ref +); + + +// from prefix.dbscheme +#keyset[id] +locatable_locations( + int id: @locatable ref, + int location: @location_default ref +); + + +// from schema + +@element = + @extractor_step +| @locatable +| @named_crate +| @unextracted +; + +extractor_steps( + unique int id: @extractor_step, + string action: string ref, + int duration_ms: int ref +); + +#keyset[id] +extractor_step_files( + int id: @extractor_step ref, + int file: @file ref +); + +@locatable = + @ast_node +| @crate +; + +named_crates( + unique int id: @named_crate, + string name: string ref, + int crate: @crate ref +); + +@unextracted = + @missing +| @unimplemented +; + +@ast_node = + @abi +| @addressable +| @arg_list +| @asm_dir_spec +| @asm_operand +| @asm_operand_expr +| @asm_option +| @asm_piece +| @asm_reg_spec +| @assoc_item_list +| @attr +| @callable +| @expr +| @extern_item_list +| @field_list +| @for_binder +| @format_args_arg +| @generic_arg +| @generic_arg_list +| @generic_param +| @generic_param_list +| @item_list +| @label +| @let_else +| @macro_items +| @match_arm +| @match_arm_list +| @match_guard +| @meta +| @name +| @param_base +| @param_list +| @parenthesized_arg_list +| @pat +| @path +| @path_ast_node +| @path_segment +| @rename +| @ret_type_repr +| @return_type_syntax +| @source_file +| @stmt +| @stmt_list +| @struct_expr_field +| @struct_expr_field_list +| @struct_field +| @struct_pat_field +| @struct_pat_field_list +| @token +| @token_tree +| @tuple_field +| @type_bound +| @type_bound_list +| @type_repr +| @use_bound_generic_arg +| @use_bound_generic_args +| @use_tree +| @use_tree_list +| @variant_list +| @visibility +| @where_clause +| @where_pred +; + +crates( + unique int id: @crate +); + +#keyset[id] +crate_names( + int id: @crate ref, + string name: string ref +); + +#keyset[id] +crate_versions( + int id: @crate ref, + string version: string ref +); + +#keyset[id, index] +crate_cfg_options( + int id: @crate ref, + int index: int ref, + string cfg_option: string ref +); + +#keyset[id, index] +crate_named_dependencies( + int id: @crate ref, + int index: int ref, + int named_dependency: @named_crate ref +); + +missings( + unique int id: @missing +); + +unimplementeds( + unique int id: @unimplemented +); + +abis( + unique int id: @abi +); + +#keyset[id] +abi_abi_strings( + int id: @abi ref, + string abi_string: string ref +); + +@addressable = + @item +| @variant +; + +arg_lists( + unique int id: @arg_list +); + +#keyset[id, index] +arg_list_args( + int id: @arg_list ref, + int index: int ref, + int arg: @expr ref +); + +asm_dir_specs( + unique int id: @asm_dir_spec +); + +@asm_operand = + @asm_const +| @asm_label +| @asm_reg_operand +| @asm_sym +; + +asm_operand_exprs( + unique int id: @asm_operand_expr +); + +#keyset[id] +asm_operand_expr_in_exprs( + int id: @asm_operand_expr ref, + int in_expr: @expr ref +); + +#keyset[id] +asm_operand_expr_out_exprs( + int id: @asm_operand_expr ref, + int out_expr: @expr ref +); + +asm_options( + unique int id: @asm_option +); + +#keyset[id] +asm_option_is_raw( + int id: @asm_option ref +); + +@asm_piece = + @asm_clobber_abi +| @asm_operand_named +| @asm_options_list +; + +asm_reg_specs( + unique int id: @asm_reg_spec +); + +#keyset[id] +asm_reg_spec_identifiers( + int id: @asm_reg_spec ref, + int identifier: @name_ref ref +); + +assoc_item_lists( + unique int id: @assoc_item_list +); + +#keyset[id, index] +assoc_item_list_assoc_items( + int id: @assoc_item_list ref, + int index: int ref, + int assoc_item: @assoc_item ref +); + +#keyset[id, index] +assoc_item_list_attrs( + int id: @assoc_item_list ref, + int index: int ref, + int attr: @attr ref +); + +attrs( + unique int id: @attr +); + +#keyset[id] +attr_meta( + int id: @attr ref, + int meta: @meta ref +); + +@callable = + @closure_expr +| @function +; + +#keyset[id] +callable_param_lists( + int id: @callable ref, + int param_list: @param_list ref +); + +#keyset[id, index] +callable_attrs( + int id: @callable ref, + int index: int ref, + int attr: @attr ref +); + +@expr = + @array_expr_internal +| @asm_expr +| @await_expr +| @become_expr +| @binary_expr +| @break_expr +| @call_expr +| @cast_expr +| @closure_expr +| @continue_expr +| @field_expr +| @format_args_expr +| @if_expr +| @index_expr +| @labelable_expr +| @let_expr +| @literal_expr +| @macro_block_expr +| @macro_expr +| @match_expr +| @method_call_expr +| @offset_of_expr +| @paren_expr +| @path_expr_base +| @prefix_expr +| @range_expr +| @ref_expr +| @return_expr +| @struct_expr +| @try_expr +| @tuple_expr +| @underscore_expr +| @yeet_expr +| @yield_expr +; + +extern_item_lists( + unique int id: @extern_item_list +); + +#keyset[id, index] +extern_item_list_attrs( + int id: @extern_item_list ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id, index] +extern_item_list_extern_items( + int id: @extern_item_list ref, + int index: int ref, + int extern_item: @extern_item ref +); + +@field_list = + @struct_field_list +| @tuple_field_list +; + +for_binders( + unique int id: @for_binder +); + +#keyset[id] +for_binder_generic_param_lists( + int id: @for_binder ref, + int generic_param_list: @generic_param_list ref +); + +format_args_args( + unique int id: @format_args_arg +); + +#keyset[id] +format_args_arg_exprs( + int id: @format_args_arg ref, + int expr: @expr ref +); + +#keyset[id] +format_args_arg_names( + int id: @format_args_arg ref, + int name: @name ref +); + +@generic_arg = + @assoc_type_arg +| @const_arg +| @lifetime_arg +| @type_arg +; + +generic_arg_lists( + unique int id: @generic_arg_list +); + +#keyset[id, index] +generic_arg_list_generic_args( + int id: @generic_arg_list ref, + int index: int ref, + int generic_arg: @generic_arg ref +); + +@generic_param = + @const_param +| @lifetime_param +| @type_param +; + +generic_param_lists( + unique int id: @generic_param_list +); + +#keyset[id, index] +generic_param_list_generic_params( + int id: @generic_param_list ref, + int index: int ref, + int generic_param: @generic_param ref +); + +item_lists( + unique int id: @item_list +); + +#keyset[id, index] +item_list_attrs( + int id: @item_list ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id, index] +item_list_items( + int id: @item_list ref, + int index: int ref, + int item: @item ref +); + +labels( + unique int id: @label +); + +#keyset[id] +label_lifetimes( + int id: @label ref, + int lifetime: @lifetime ref +); + +let_elses( + unique int id: @let_else +); + +#keyset[id] +let_else_block_exprs( + int id: @let_else ref, + int block_expr: @block_expr ref +); + +macro_items( + unique int id: @macro_items +); + +#keyset[id, index] +macro_items_items( + int id: @macro_items ref, + int index: int ref, + int item: @item ref +); + +match_arms( + unique int id: @match_arm +); + +#keyset[id, index] +match_arm_attrs( + int id: @match_arm ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +match_arm_exprs( + int id: @match_arm ref, + int expr: @expr ref +); + +#keyset[id] +match_arm_guards( + int id: @match_arm ref, + int guard: @match_guard ref +); + +#keyset[id] +match_arm_pats( + int id: @match_arm ref, + int pat: @pat ref +); + +match_arm_lists( + unique int id: @match_arm_list +); + +#keyset[id, index] +match_arm_list_arms( + int id: @match_arm_list ref, + int index: int ref, + int arm: @match_arm ref +); + +#keyset[id, index] +match_arm_list_attrs( + int id: @match_arm_list ref, + int index: int ref, + int attr: @attr ref +); + +match_guards( + unique int id: @match_guard +); + +#keyset[id] +match_guard_conditions( + int id: @match_guard ref, + int condition: @expr ref +); + +meta( + unique int id: @meta +); + +#keyset[id] +meta_exprs( + int id: @meta ref, + int expr: @expr ref +); + +#keyset[id] +meta_is_unsafe( + int id: @meta ref +); + +#keyset[id] +meta_paths( + int id: @meta ref, + int path: @path ref +); + +#keyset[id] +meta_token_trees( + int id: @meta ref, + int token_tree: @token_tree ref +); + +names( + unique int id: @name +); + +#keyset[id] +name_texts( + int id: @name ref, + string text: string ref +); + +@param_base = + @param +| @self_param +; + +#keyset[id, index] +param_base_attrs( + int id: @param_base ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +param_base_type_reprs( + int id: @param_base ref, + int type_repr: @type_repr ref +); + +param_lists( + unique int id: @param_list +); + +#keyset[id, index] +param_list_params( + int id: @param_list ref, + int index: int ref, + int param: @param ref +); + +#keyset[id] +param_list_self_params( + int id: @param_list ref, + int self_param: @self_param ref +); + +parenthesized_arg_lists( + unique int id: @parenthesized_arg_list +); + +#keyset[id, index] +parenthesized_arg_list_type_args( + int id: @parenthesized_arg_list ref, + int index: int ref, + int type_arg: @type_arg ref +); + +@pat = + @box_pat +| @const_block_pat +| @ident_pat +| @literal_pat +| @macro_pat +| @or_pat +| @paren_pat +| @path_pat +| @range_pat +| @ref_pat +| @rest_pat +| @slice_pat +| @struct_pat +| @tuple_pat +| @tuple_struct_pat +| @wildcard_pat +; + +paths( + unique int id: @path +); + +#keyset[id] +path_qualifiers( + int id: @path ref, + int qualifier: @path ref +); + +#keyset[id] +path_segments_( + int id: @path ref, + int segment: @path_segment ref +); + +@path_ast_node = + @path_expr +| @path_pat +| @struct_expr +| @struct_pat +| @tuple_struct_pat +; + +#keyset[id] +path_ast_node_paths( + int id: @path_ast_node ref, + int path: @path ref +); + +path_segments( + unique int id: @path_segment +); + +#keyset[id] +path_segment_generic_arg_lists( + int id: @path_segment ref, + int generic_arg_list: @generic_arg_list ref +); + +#keyset[id] +path_segment_identifiers( + int id: @path_segment ref, + int identifier: @name_ref ref +); + +#keyset[id] +path_segment_parenthesized_arg_lists( + int id: @path_segment ref, + int parenthesized_arg_list: @parenthesized_arg_list ref +); + +#keyset[id] +path_segment_ret_types( + int id: @path_segment ref, + int ret_type: @ret_type_repr ref +); + +#keyset[id] +path_segment_return_type_syntaxes( + int id: @path_segment ref, + int return_type_syntax: @return_type_syntax ref +); + +#keyset[id] +path_segment_type_reprs( + int id: @path_segment ref, + int type_repr: @type_repr ref +); + +#keyset[id] +path_segment_trait_type_reprs( + int id: @path_segment ref, + int trait_type_repr: @path_type_repr ref +); + +renames( + unique int id: @rename +); + +#keyset[id] +rename_names( + int id: @rename ref, + int name: @name ref +); + +ret_type_reprs( + unique int id: @ret_type_repr +); + +#keyset[id] +ret_type_repr_type_reprs( + int id: @ret_type_repr ref, + int type_repr: @type_repr ref +); + +return_type_syntaxes( + unique int id: @return_type_syntax +); + +source_files( + unique int id: @source_file +); + +#keyset[id, index] +source_file_attrs( + int id: @source_file ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id, index] +source_file_items( + int id: @source_file ref, + int index: int ref, + int item: @item ref +); + +@stmt = + @expr_stmt +| @item +| @let_stmt +; + +stmt_lists( + unique int id: @stmt_list +); + +#keyset[id, index] +stmt_list_attrs( + int id: @stmt_list ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id, index] +stmt_list_statements( + int id: @stmt_list ref, + int index: int ref, + int statement: @stmt ref +); + +#keyset[id] +stmt_list_tail_exprs( + int id: @stmt_list ref, + int tail_expr: @expr ref +); + +struct_expr_fields( + unique int id: @struct_expr_field +); + +#keyset[id, index] +struct_expr_field_attrs( + int id: @struct_expr_field ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +struct_expr_field_exprs( + int id: @struct_expr_field ref, + int expr: @expr ref +); + +#keyset[id] +struct_expr_field_identifiers( + int id: @struct_expr_field ref, + int identifier: @name_ref ref +); + +struct_expr_field_lists( + unique int id: @struct_expr_field_list +); + +#keyset[id, index] +struct_expr_field_list_attrs( + int id: @struct_expr_field_list ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id, index] +struct_expr_field_list_fields( + int id: @struct_expr_field_list ref, + int index: int ref, + int field: @struct_expr_field ref +); + +#keyset[id] +struct_expr_field_list_spreads( + int id: @struct_expr_field_list ref, + int spread: @expr ref +); + +struct_fields( + unique int id: @struct_field +); + +#keyset[id, index] +struct_field_attrs( + int id: @struct_field ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +struct_field_defaults( + int id: @struct_field ref, + int default: @expr ref +); + +#keyset[id] +struct_field_is_unsafe( + int id: @struct_field ref +); + +#keyset[id] +struct_field_names( + int id: @struct_field ref, + int name: @name ref +); + +#keyset[id] +struct_field_type_reprs( + int id: @struct_field ref, + int type_repr: @type_repr ref +); + +#keyset[id] +struct_field_visibilities( + int id: @struct_field ref, + int visibility: @visibility ref +); + +struct_pat_fields( + unique int id: @struct_pat_field +); + +#keyset[id, index] +struct_pat_field_attrs( + int id: @struct_pat_field ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +struct_pat_field_identifiers( + int id: @struct_pat_field ref, + int identifier: @name_ref ref +); + +#keyset[id] +struct_pat_field_pats( + int id: @struct_pat_field ref, + int pat: @pat ref +); + +struct_pat_field_lists( + unique int id: @struct_pat_field_list +); + +#keyset[id, index] +struct_pat_field_list_fields( + int id: @struct_pat_field_list ref, + int index: int ref, + int field: @struct_pat_field ref +); + +#keyset[id] +struct_pat_field_list_rest_pats( + int id: @struct_pat_field_list ref, + int rest_pat: @rest_pat ref +); + +@token = + @comment +; + +token_trees( + unique int id: @token_tree +); + +tuple_fields( + unique int id: @tuple_field +); + +#keyset[id, index] +tuple_field_attrs( + int id: @tuple_field ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +tuple_field_type_reprs( + int id: @tuple_field ref, + int type_repr: @type_repr ref +); + +#keyset[id] +tuple_field_visibilities( + int id: @tuple_field ref, + int visibility: @visibility ref +); + +type_bounds( + unique int id: @type_bound +); + +#keyset[id] +type_bound_for_binders( + int id: @type_bound ref, + int for_binder: @for_binder ref +); + +#keyset[id] +type_bound_is_async( + int id: @type_bound ref +); + +#keyset[id] +type_bound_is_const( + int id: @type_bound ref +); + +#keyset[id] +type_bound_lifetimes( + int id: @type_bound ref, + int lifetime: @lifetime ref +); + +#keyset[id] +type_bound_type_reprs( + int id: @type_bound ref, + int type_repr: @type_repr ref +); + +#keyset[id] +type_bound_use_bound_generic_args( + int id: @type_bound ref, + int use_bound_generic_args: @use_bound_generic_args ref +); + +type_bound_lists( + unique int id: @type_bound_list +); + +#keyset[id, index] +type_bound_list_bounds( + int id: @type_bound_list ref, + int index: int ref, + int bound: @type_bound ref +); + +@type_repr = + @array_type_repr +| @dyn_trait_type_repr +| @fn_ptr_type_repr +| @for_type_repr +| @impl_trait_type_repr +| @infer_type_repr +| @macro_type_repr +| @never_type_repr +| @paren_type_repr +| @path_type_repr +| @ptr_type_repr +| @ref_type_repr +| @slice_type_repr +| @tuple_type_repr +; + +@use_bound_generic_arg = + @lifetime +| @name_ref +; + +use_bound_generic_args( + unique int id: @use_bound_generic_args +); + +#keyset[id, index] +use_bound_generic_args_use_bound_generic_args( + int id: @use_bound_generic_args ref, + int index: int ref, + int use_bound_generic_arg: @use_bound_generic_arg ref +); + +use_trees( + unique int id: @use_tree +); + +#keyset[id] +use_tree_is_glob( + int id: @use_tree ref +); + +#keyset[id] +use_tree_paths( + int id: @use_tree ref, + int path: @path ref +); + +#keyset[id] +use_tree_renames( + int id: @use_tree ref, + int rename: @rename ref +); + +#keyset[id] +use_tree_use_tree_lists( + int id: @use_tree ref, + int use_tree_list: @use_tree_list ref +); + +use_tree_lists( + unique int id: @use_tree_list +); + +#keyset[id, index] +use_tree_list_use_trees( + int id: @use_tree_list ref, + int index: int ref, + int use_tree: @use_tree ref +); + +variant_lists( + unique int id: @variant_list +); + +#keyset[id, index] +variant_list_variants( + int id: @variant_list ref, + int index: int ref, + int variant: @variant ref +); + +visibilities( + unique int id: @visibility +); + +#keyset[id] +visibility_paths( + int id: @visibility ref, + int path: @path ref +); + +where_clauses( + unique int id: @where_clause +); + +#keyset[id, index] +where_clause_predicates( + int id: @where_clause ref, + int index: int ref, + int predicate: @where_pred ref +); + +where_preds( + unique int id: @where_pred +); + +#keyset[id] +where_pred_for_binders( + int id: @where_pred ref, + int for_binder: @for_binder ref +); + +#keyset[id] +where_pred_lifetimes( + int id: @where_pred ref, + int lifetime: @lifetime ref +); + +#keyset[id] +where_pred_type_reprs( + int id: @where_pred ref, + int type_repr: @type_repr ref +); + +#keyset[id] +where_pred_type_bound_lists( + int id: @where_pred ref, + int type_bound_list: @type_bound_list ref +); + +array_expr_internals( + unique int id: @array_expr_internal +); + +#keyset[id, index] +array_expr_internal_attrs( + int id: @array_expr_internal ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id, index] +array_expr_internal_exprs( + int id: @array_expr_internal ref, + int index: int ref, + int expr: @expr ref +); + +#keyset[id] +array_expr_internal_is_semicolon( + int id: @array_expr_internal ref +); + +array_type_reprs( + unique int id: @array_type_repr +); + +#keyset[id] +array_type_repr_const_args( + int id: @array_type_repr ref, + int const_arg: @const_arg ref +); + +#keyset[id] +array_type_repr_element_type_reprs( + int id: @array_type_repr ref, + int element_type_repr: @type_repr ref +); + +asm_clobber_abis( + unique int id: @asm_clobber_abi +); + +asm_consts( + unique int id: @asm_const +); + +#keyset[id] +asm_const_exprs( + int id: @asm_const ref, + int expr: @expr ref +); + +#keyset[id] +asm_const_is_const( + int id: @asm_const ref +); + +asm_labels( + unique int id: @asm_label +); + +#keyset[id] +asm_label_block_exprs( + int id: @asm_label ref, + int block_expr: @block_expr ref +); + +asm_operand_nameds( + unique int id: @asm_operand_named +); + +#keyset[id] +asm_operand_named_asm_operands( + int id: @asm_operand_named ref, + int asm_operand: @asm_operand ref +); + +#keyset[id] +asm_operand_named_names( + int id: @asm_operand_named ref, + int name: @name ref +); + +asm_options_lists( + unique int id: @asm_options_list +); + +#keyset[id, index] +asm_options_list_asm_options( + int id: @asm_options_list ref, + int index: int ref, + int asm_option: @asm_option ref +); + +asm_reg_operands( + unique int id: @asm_reg_operand +); + +#keyset[id] +asm_reg_operand_asm_dir_specs( + int id: @asm_reg_operand ref, + int asm_dir_spec: @asm_dir_spec ref +); + +#keyset[id] +asm_reg_operand_asm_operand_exprs( + int id: @asm_reg_operand ref, + int asm_operand_expr: @asm_operand_expr ref +); + +#keyset[id] +asm_reg_operand_asm_reg_specs( + int id: @asm_reg_operand ref, + int asm_reg_spec: @asm_reg_spec ref +); + +asm_syms( + unique int id: @asm_sym +); + +#keyset[id] +asm_sym_paths( + int id: @asm_sym ref, + int path: @path ref +); + +assoc_type_args( + unique int id: @assoc_type_arg +); + +#keyset[id] +assoc_type_arg_const_args( + int id: @assoc_type_arg ref, + int const_arg: @const_arg ref +); + +#keyset[id] +assoc_type_arg_generic_arg_lists( + int id: @assoc_type_arg ref, + int generic_arg_list: @generic_arg_list ref +); + +#keyset[id] +assoc_type_arg_identifiers( + int id: @assoc_type_arg ref, + int identifier: @name_ref ref +); + +#keyset[id] +assoc_type_arg_param_lists( + int id: @assoc_type_arg ref, + int param_list: @param_list ref +); + +#keyset[id] +assoc_type_arg_ret_types( + int id: @assoc_type_arg ref, + int ret_type: @ret_type_repr ref +); + +#keyset[id] +assoc_type_arg_return_type_syntaxes( + int id: @assoc_type_arg ref, + int return_type_syntax: @return_type_syntax ref +); + +#keyset[id] +assoc_type_arg_type_reprs( + int id: @assoc_type_arg ref, + int type_repr: @type_repr ref +); + +#keyset[id] +assoc_type_arg_type_bound_lists( + int id: @assoc_type_arg ref, + int type_bound_list: @type_bound_list ref +); + +await_exprs( + unique int id: @await_expr +); + +#keyset[id, index] +await_expr_attrs( + int id: @await_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +await_expr_exprs( + int id: @await_expr ref, + int expr: @expr ref +); + +become_exprs( + unique int id: @become_expr +); + +#keyset[id, index] +become_expr_attrs( + int id: @become_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +become_expr_exprs( + int id: @become_expr ref, + int expr: @expr ref +); + +binary_exprs( + unique int id: @binary_expr +); + +#keyset[id, index] +binary_expr_attrs( + int id: @binary_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +binary_expr_lhs( + int id: @binary_expr ref, + int lhs: @expr ref +); + +#keyset[id] +binary_expr_operator_names( + int id: @binary_expr ref, + string operator_name: string ref +); + +#keyset[id] +binary_expr_rhs( + int id: @binary_expr ref, + int rhs: @expr ref +); + +box_pats( + unique int id: @box_pat +); + +#keyset[id] +box_pat_pats( + int id: @box_pat ref, + int pat: @pat ref +); + +break_exprs( + unique int id: @break_expr +); + +#keyset[id, index] +break_expr_attrs( + int id: @break_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +break_expr_exprs( + int id: @break_expr ref, + int expr: @expr ref +); + +#keyset[id] +break_expr_lifetimes( + int id: @break_expr ref, + int lifetime: @lifetime ref +); + +call_exprs( + unique int id: @call_expr +); + +#keyset[id] +call_expr_arg_lists( + int id: @call_expr ref, + int arg_list: @arg_list ref +); + +#keyset[id, index] +call_expr_attrs( + int id: @call_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +call_expr_functions( + int id: @call_expr ref, + int function: @expr ref +); + +cast_exprs( + unique int id: @cast_expr +); + +#keyset[id, index] +cast_expr_attrs( + int id: @cast_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +cast_expr_exprs( + int id: @cast_expr ref, + int expr: @expr ref +); + +#keyset[id] +cast_expr_type_reprs( + int id: @cast_expr ref, + int type_repr: @type_repr ref +); + +closure_exprs( + unique int id: @closure_expr +); + +#keyset[id] +closure_expr_closure_bodies( + int id: @closure_expr ref, + int closure_body: @expr ref +); + +#keyset[id] +closure_expr_for_binders( + int id: @closure_expr ref, + int for_binder: @for_binder ref +); + +#keyset[id] +closure_expr_is_async( + int id: @closure_expr ref +); + +#keyset[id] +closure_expr_is_const( + int id: @closure_expr ref +); + +#keyset[id] +closure_expr_is_gen( + int id: @closure_expr ref +); + +#keyset[id] +closure_expr_is_move( + int id: @closure_expr ref +); + +#keyset[id] +closure_expr_is_static( + int id: @closure_expr ref +); + +#keyset[id] +closure_expr_ret_types( + int id: @closure_expr ref, + int ret_type: @ret_type_repr ref +); + +comments( + unique int id: @comment, + int parent: @ast_node ref, + string text: string ref +); + +const_args( + unique int id: @const_arg +); + +#keyset[id] +const_arg_exprs( + int id: @const_arg ref, + int expr: @expr ref +); + +const_block_pats( + unique int id: @const_block_pat +); + +#keyset[id] +const_block_pat_block_exprs( + int id: @const_block_pat ref, + int block_expr: @block_expr ref +); + +#keyset[id] +const_block_pat_is_const( + int id: @const_block_pat ref +); + +const_params( + unique int id: @const_param +); + +#keyset[id, index] +const_param_attrs( + int id: @const_param ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +const_param_default_vals( + int id: @const_param ref, + int default_val: @const_arg ref +); + +#keyset[id] +const_param_is_const( + int id: @const_param ref +); + +#keyset[id] +const_param_names( + int id: @const_param ref, + int name: @name ref +); + +#keyset[id] +const_param_type_reprs( + int id: @const_param ref, + int type_repr: @type_repr ref +); + +continue_exprs( + unique int id: @continue_expr +); + +#keyset[id, index] +continue_expr_attrs( + int id: @continue_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +continue_expr_lifetimes( + int id: @continue_expr ref, + int lifetime: @lifetime ref +); + +dyn_trait_type_reprs( + unique int id: @dyn_trait_type_repr +); + +#keyset[id] +dyn_trait_type_repr_type_bound_lists( + int id: @dyn_trait_type_repr ref, + int type_bound_list: @type_bound_list ref +); + +expr_stmts( + unique int id: @expr_stmt +); + +#keyset[id] +expr_stmt_exprs( + int id: @expr_stmt ref, + int expr: @expr ref +); + +field_exprs( + unique int id: @field_expr +); + +#keyset[id, index] +field_expr_attrs( + int id: @field_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +field_expr_containers( + int id: @field_expr ref, + int container: @expr ref +); + +#keyset[id] +field_expr_identifiers( + int id: @field_expr ref, + int identifier: @name_ref ref +); + +fn_ptr_type_reprs( + unique int id: @fn_ptr_type_repr +); + +#keyset[id] +fn_ptr_type_repr_abis( + int id: @fn_ptr_type_repr ref, + int abi: @abi ref +); + +#keyset[id] +fn_ptr_type_repr_is_async( + int id: @fn_ptr_type_repr ref +); + +#keyset[id] +fn_ptr_type_repr_is_const( + int id: @fn_ptr_type_repr ref +); + +#keyset[id] +fn_ptr_type_repr_is_unsafe( + int id: @fn_ptr_type_repr ref +); + +#keyset[id] +fn_ptr_type_repr_param_lists( + int id: @fn_ptr_type_repr ref, + int param_list: @param_list ref +); + +#keyset[id] +fn_ptr_type_repr_ret_types( + int id: @fn_ptr_type_repr ref, + int ret_type: @ret_type_repr ref +); + +for_type_reprs( + unique int id: @for_type_repr +); + +#keyset[id] +for_type_repr_for_binders( + int id: @for_type_repr ref, + int for_binder: @for_binder ref +); + +#keyset[id] +for_type_repr_type_reprs( + int id: @for_type_repr ref, + int type_repr: @type_repr ref +); + +format_args_exprs( + unique int id: @format_args_expr +); + +#keyset[id, index] +format_args_expr_args( + int id: @format_args_expr ref, + int index: int ref, + int arg: @format_args_arg ref +); + +#keyset[id, index] +format_args_expr_attrs( + int id: @format_args_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +format_args_expr_templates( + int id: @format_args_expr ref, + int template: @expr ref +); + +ident_pats( + unique int id: @ident_pat +); + +#keyset[id, index] +ident_pat_attrs( + int id: @ident_pat ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +ident_pat_is_mut( + int id: @ident_pat ref +); + +#keyset[id] +ident_pat_is_ref( + int id: @ident_pat ref +); + +#keyset[id] +ident_pat_names( + int id: @ident_pat ref, + int name: @name ref +); + +#keyset[id] +ident_pat_pats( + int id: @ident_pat ref, + int pat: @pat ref +); + +if_exprs( + unique int id: @if_expr +); + +#keyset[id, index] +if_expr_attrs( + int id: @if_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +if_expr_conditions( + int id: @if_expr ref, + int condition: @expr ref +); + +#keyset[id] +if_expr_elses( + int id: @if_expr ref, + int else: @expr ref +); + +#keyset[id] +if_expr_thens( + int id: @if_expr ref, + int then: @block_expr ref +); + +impl_trait_type_reprs( + unique int id: @impl_trait_type_repr +); + +#keyset[id] +impl_trait_type_repr_type_bound_lists( + int id: @impl_trait_type_repr ref, + int type_bound_list: @type_bound_list ref +); + +index_exprs( + unique int id: @index_expr +); + +#keyset[id, index] +index_expr_attrs( + int id: @index_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +index_expr_bases( + int id: @index_expr ref, + int base: @expr ref +); + +#keyset[id] +index_expr_indices( + int id: @index_expr ref, + int index: @expr ref +); + +infer_type_reprs( + unique int id: @infer_type_repr +); + +@item = + @adt +| @asm_expr +| @assoc_item +| @extern_block +| @extern_crate +| @extern_item +| @impl +| @macro_def +| @macro_rules +| @module +| @trait +| @trait_alias +| @use +; + +#keyset[id] +item_attribute_macro_expansions( + int id: @item ref, + int attribute_macro_expansion: @macro_items ref +); + +@labelable_expr = + @block_expr +| @looping_expr +; + +#keyset[id] +labelable_expr_labels( + int id: @labelable_expr ref, + int label: @label ref +); + +let_exprs( + unique int id: @let_expr +); + +#keyset[id, index] +let_expr_attrs( + int id: @let_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +let_expr_scrutinees( + int id: @let_expr ref, + int scrutinee: @expr ref +); + +#keyset[id] +let_expr_pats( + int id: @let_expr ref, + int pat: @pat ref +); + +let_stmts( + unique int id: @let_stmt +); + +#keyset[id, index] +let_stmt_attrs( + int id: @let_stmt ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +let_stmt_initializers( + int id: @let_stmt ref, + int initializer: @expr ref +); + +#keyset[id] +let_stmt_let_elses( + int id: @let_stmt ref, + int let_else: @let_else ref +); + +#keyset[id] +let_stmt_pats( + int id: @let_stmt ref, + int pat: @pat ref +); + +#keyset[id] +let_stmt_type_reprs( + int id: @let_stmt ref, + int type_repr: @type_repr ref +); + +lifetimes( + unique int id: @lifetime +); + +#keyset[id] +lifetime_texts( + int id: @lifetime ref, + string text: string ref +); + +lifetime_args( + unique int id: @lifetime_arg +); + +#keyset[id] +lifetime_arg_lifetimes( + int id: @lifetime_arg ref, + int lifetime: @lifetime ref +); + +lifetime_params( + unique int id: @lifetime_param +); + +#keyset[id, index] +lifetime_param_attrs( + int id: @lifetime_param ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +lifetime_param_lifetimes( + int id: @lifetime_param ref, + int lifetime: @lifetime ref +); + +#keyset[id] +lifetime_param_type_bound_lists( + int id: @lifetime_param ref, + int type_bound_list: @type_bound_list ref +); + +literal_exprs( + unique int id: @literal_expr +); + +#keyset[id, index] +literal_expr_attrs( + int id: @literal_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +literal_expr_text_values( + int id: @literal_expr ref, + string text_value: string ref +); + +literal_pats( + unique int id: @literal_pat +); + +#keyset[id] +literal_pat_literals( + int id: @literal_pat ref, + int literal: @literal_expr ref +); + +macro_block_exprs( + unique int id: @macro_block_expr +); + +#keyset[id, index] +macro_block_expr_statements( + int id: @macro_block_expr ref, + int index: int ref, + int statement: @stmt ref +); + +#keyset[id] +macro_block_expr_tail_exprs( + int id: @macro_block_expr ref, + int tail_expr: @expr ref +); + +macro_exprs( + unique int id: @macro_expr +); + +#keyset[id] +macro_expr_macro_calls( + int id: @macro_expr ref, + int macro_call: @macro_call ref +); + +macro_pats( + unique int id: @macro_pat +); + +#keyset[id] +macro_pat_macro_calls( + int id: @macro_pat ref, + int macro_call: @macro_call ref +); + +macro_type_reprs( + unique int id: @macro_type_repr +); + +#keyset[id] +macro_type_repr_macro_calls( + int id: @macro_type_repr ref, + int macro_call: @macro_call ref +); + +match_exprs( + unique int id: @match_expr +); + +#keyset[id, index] +match_expr_attrs( + int id: @match_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +match_expr_scrutinees( + int id: @match_expr ref, + int scrutinee: @expr ref +); + +#keyset[id] +match_expr_match_arm_lists( + int id: @match_expr ref, + int match_arm_list: @match_arm_list ref +); + +method_call_exprs( + unique int id: @method_call_expr +); + +#keyset[id] +method_call_expr_arg_lists( + int id: @method_call_expr ref, + int arg_list: @arg_list ref +); + +#keyset[id, index] +method_call_expr_attrs( + int id: @method_call_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +method_call_expr_generic_arg_lists( + int id: @method_call_expr ref, + int generic_arg_list: @generic_arg_list ref +); + +#keyset[id] +method_call_expr_identifiers( + int id: @method_call_expr ref, + int identifier: @name_ref ref +); + +#keyset[id] +method_call_expr_receivers( + int id: @method_call_expr ref, + int receiver: @expr ref +); + +name_refs( + unique int id: @name_ref +); + +#keyset[id] +name_ref_texts( + int id: @name_ref ref, + string text: string ref +); + +never_type_reprs( + unique int id: @never_type_repr +); + +offset_of_exprs( + unique int id: @offset_of_expr +); + +#keyset[id, index] +offset_of_expr_attrs( + int id: @offset_of_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id, index] +offset_of_expr_fields( + int id: @offset_of_expr ref, + int index: int ref, + int field: @name_ref ref +); + +#keyset[id] +offset_of_expr_type_reprs( + int id: @offset_of_expr ref, + int type_repr: @type_repr ref +); + +or_pats( + unique int id: @or_pat +); + +#keyset[id, index] +or_pat_pats( + int id: @or_pat ref, + int index: int ref, + int pat: @pat ref +); + +params( + unique int id: @param +); + +#keyset[id] +param_pats( + int id: @param ref, + int pat: @pat ref +); + +paren_exprs( + unique int id: @paren_expr +); + +#keyset[id, index] +paren_expr_attrs( + int id: @paren_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +paren_expr_exprs( + int id: @paren_expr ref, + int expr: @expr ref +); + +paren_pats( + unique int id: @paren_pat +); + +#keyset[id] +paren_pat_pats( + int id: @paren_pat ref, + int pat: @pat ref +); + +paren_type_reprs( + unique int id: @paren_type_repr +); + +#keyset[id] +paren_type_repr_type_reprs( + int id: @paren_type_repr ref, + int type_repr: @type_repr ref +); + +@path_expr_base = + @path_expr +; + +path_pats( + unique int id: @path_pat +); + +path_type_reprs( + unique int id: @path_type_repr +); + +#keyset[id] +path_type_repr_paths( + int id: @path_type_repr ref, + int path: @path ref +); + +prefix_exprs( + unique int id: @prefix_expr +); + +#keyset[id, index] +prefix_expr_attrs( + int id: @prefix_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +prefix_expr_exprs( + int id: @prefix_expr ref, + int expr: @expr ref +); + +#keyset[id] +prefix_expr_operator_names( + int id: @prefix_expr ref, + string operator_name: string ref +); + +ptr_type_reprs( + unique int id: @ptr_type_repr +); + +#keyset[id] +ptr_type_repr_is_const( + int id: @ptr_type_repr ref +); + +#keyset[id] +ptr_type_repr_is_mut( + int id: @ptr_type_repr ref +); + +#keyset[id] +ptr_type_repr_type_reprs( + int id: @ptr_type_repr ref, + int type_repr: @type_repr ref +); + +range_exprs( + unique int id: @range_expr +); + +#keyset[id, index] +range_expr_attrs( + int id: @range_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +range_expr_ends( + int id: @range_expr ref, + int end: @expr ref +); + +#keyset[id] +range_expr_operator_names( + int id: @range_expr ref, + string operator_name: string ref +); + +#keyset[id] +range_expr_starts( + int id: @range_expr ref, + int start: @expr ref +); + +range_pats( + unique int id: @range_pat +); + +#keyset[id] +range_pat_ends( + int id: @range_pat ref, + int end: @pat ref +); + +#keyset[id] +range_pat_operator_names( + int id: @range_pat ref, + string operator_name: string ref +); + +#keyset[id] +range_pat_starts( + int id: @range_pat ref, + int start: @pat ref +); + +ref_exprs( + unique int id: @ref_expr +); + +#keyset[id, index] +ref_expr_attrs( + int id: @ref_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +ref_expr_exprs( + int id: @ref_expr ref, + int expr: @expr ref +); + +#keyset[id] +ref_expr_is_const( + int id: @ref_expr ref +); + +#keyset[id] +ref_expr_is_mut( + int id: @ref_expr ref +); + +#keyset[id] +ref_expr_is_raw( + int id: @ref_expr ref +); + +ref_pats( + unique int id: @ref_pat +); + +#keyset[id] +ref_pat_is_mut( + int id: @ref_pat ref +); + +#keyset[id] +ref_pat_pats( + int id: @ref_pat ref, + int pat: @pat ref +); + +ref_type_reprs( + unique int id: @ref_type_repr +); + +#keyset[id] +ref_type_repr_is_mut( + int id: @ref_type_repr ref +); + +#keyset[id] +ref_type_repr_lifetimes( + int id: @ref_type_repr ref, + int lifetime: @lifetime ref +); + +#keyset[id] +ref_type_repr_type_reprs( + int id: @ref_type_repr ref, + int type_repr: @type_repr ref +); + +rest_pats( + unique int id: @rest_pat +); + +#keyset[id, index] +rest_pat_attrs( + int id: @rest_pat ref, + int index: int ref, + int attr: @attr ref +); + +return_exprs( + unique int id: @return_expr +); + +#keyset[id, index] +return_expr_attrs( + int id: @return_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +return_expr_exprs( + int id: @return_expr ref, + int expr: @expr ref +); + +self_params( + unique int id: @self_param +); + +#keyset[id] +self_param_is_ref( + int id: @self_param ref +); + +#keyset[id] +self_param_is_mut( + int id: @self_param ref +); + +#keyset[id] +self_param_lifetimes( + int id: @self_param ref, + int lifetime: @lifetime ref +); + +#keyset[id] +self_param_names( + int id: @self_param ref, + int name: @name ref +); + +slice_pats( + unique int id: @slice_pat +); + +#keyset[id, index] +slice_pat_pats( + int id: @slice_pat ref, + int index: int ref, + int pat: @pat ref +); + +slice_type_reprs( + unique int id: @slice_type_repr +); + +#keyset[id] +slice_type_repr_type_reprs( + int id: @slice_type_repr ref, + int type_repr: @type_repr ref +); + +struct_exprs( + unique int id: @struct_expr +); + +#keyset[id] +struct_expr_struct_expr_field_lists( + int id: @struct_expr ref, + int struct_expr_field_list: @struct_expr_field_list ref +); + +struct_field_lists( + unique int id: @struct_field_list +); + +#keyset[id, index] +struct_field_list_fields( + int id: @struct_field_list ref, + int index: int ref, + int field: @struct_field ref +); + +struct_pats( + unique int id: @struct_pat +); + +#keyset[id] +struct_pat_struct_pat_field_lists( + int id: @struct_pat ref, + int struct_pat_field_list: @struct_pat_field_list ref +); + +try_exprs( + unique int id: @try_expr +); + +#keyset[id, index] +try_expr_attrs( + int id: @try_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +try_expr_exprs( + int id: @try_expr ref, + int expr: @expr ref +); + +tuple_exprs( + unique int id: @tuple_expr +); + +#keyset[id, index] +tuple_expr_attrs( + int id: @tuple_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id, index] +tuple_expr_fields( + int id: @tuple_expr ref, + int index: int ref, + int field: @expr ref +); + +tuple_field_lists( + unique int id: @tuple_field_list +); + +#keyset[id, index] +tuple_field_list_fields( + int id: @tuple_field_list ref, + int index: int ref, + int field: @tuple_field ref +); + +tuple_pats( + unique int id: @tuple_pat +); + +#keyset[id, index] +tuple_pat_fields( + int id: @tuple_pat ref, + int index: int ref, + int field: @pat ref +); + +tuple_struct_pats( + unique int id: @tuple_struct_pat +); + +#keyset[id, index] +tuple_struct_pat_fields( + int id: @tuple_struct_pat ref, + int index: int ref, + int field: @pat ref +); + +tuple_type_reprs( + unique int id: @tuple_type_repr +); + +#keyset[id, index] +tuple_type_repr_fields( + int id: @tuple_type_repr ref, + int index: int ref, + int field: @type_repr ref +); + +type_args( + unique int id: @type_arg +); + +#keyset[id] +type_arg_type_reprs( + int id: @type_arg ref, + int type_repr: @type_repr ref +); + +type_params( + unique int id: @type_param +); + +#keyset[id, index] +type_param_attrs( + int id: @type_param ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +type_param_default_types( + int id: @type_param ref, + int default_type: @type_repr ref +); + +#keyset[id] +type_param_names( + int id: @type_param ref, + int name: @name ref +); + +#keyset[id] +type_param_type_bound_lists( + int id: @type_param ref, + int type_bound_list: @type_bound_list ref +); + +underscore_exprs( + unique int id: @underscore_expr +); + +#keyset[id, index] +underscore_expr_attrs( + int id: @underscore_expr ref, + int index: int ref, + int attr: @attr ref +); + +variants( + unique int id: @variant +); + +#keyset[id, index] +variant_attrs( + int id: @variant ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +variant_discriminants( + int id: @variant ref, + int discriminant: @expr ref +); + +#keyset[id] +variant_field_lists( + int id: @variant ref, + int field_list: @field_list ref +); + +#keyset[id] +variant_names( + int id: @variant ref, + int name: @name ref +); + +#keyset[id] +variant_visibilities( + int id: @variant ref, + int visibility: @visibility ref +); + +wildcard_pats( + unique int id: @wildcard_pat +); + +yeet_exprs( + unique int id: @yeet_expr +); + +#keyset[id, index] +yeet_expr_attrs( + int id: @yeet_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +yeet_expr_exprs( + int id: @yeet_expr ref, + int expr: @expr ref +); + +yield_exprs( + unique int id: @yield_expr +); + +#keyset[id, index] +yield_expr_attrs( + int id: @yield_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +yield_expr_exprs( + int id: @yield_expr ref, + int expr: @expr ref +); + +@adt = + @enum +| @struct +| @union +; + +#keyset[id, index] +adt_derive_macro_expansions( + int id: @adt ref, + int index: int ref, + int derive_macro_expansion: @macro_items ref +); + +asm_exprs( + unique int id: @asm_expr +); + +#keyset[id, index] +asm_expr_asm_pieces( + int id: @asm_expr ref, + int index: int ref, + int asm_piece: @asm_piece ref +); + +#keyset[id, index] +asm_expr_attrs( + int id: @asm_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id, index] +asm_expr_templates( + int id: @asm_expr ref, + int index: int ref, + int template: @expr ref +); + +@assoc_item = + @const +| @function +| @macro_call +| @type_alias +; + +block_exprs( + unique int id: @block_expr +); + +#keyset[id, index] +block_expr_attrs( + int id: @block_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +block_expr_is_async( + int id: @block_expr ref +); + +#keyset[id] +block_expr_is_const( + int id: @block_expr ref +); + +#keyset[id] +block_expr_is_gen( + int id: @block_expr ref +); + +#keyset[id] +block_expr_is_move( + int id: @block_expr ref +); + +#keyset[id] +block_expr_is_try( + int id: @block_expr ref +); + +#keyset[id] +block_expr_is_unsafe( + int id: @block_expr ref +); + +#keyset[id] +block_expr_stmt_lists( + int id: @block_expr ref, + int stmt_list: @stmt_list ref +); + +extern_blocks( + unique int id: @extern_block +); + +#keyset[id] +extern_block_abis( + int id: @extern_block ref, + int abi: @abi ref +); + +#keyset[id, index] +extern_block_attrs( + int id: @extern_block ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +extern_block_extern_item_lists( + int id: @extern_block ref, + int extern_item_list: @extern_item_list ref +); + +#keyset[id] +extern_block_is_unsafe( + int id: @extern_block ref +); + +extern_crates( + unique int id: @extern_crate +); + +#keyset[id, index] +extern_crate_attrs( + int id: @extern_crate ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +extern_crate_identifiers( + int id: @extern_crate ref, + int identifier: @name_ref ref +); + +#keyset[id] +extern_crate_renames( + int id: @extern_crate ref, + int rename: @rename ref +); + +#keyset[id] +extern_crate_visibilities( + int id: @extern_crate ref, + int visibility: @visibility ref +); + +@extern_item = + @function +| @macro_call +| @static +| @type_alias +; + +impls( + unique int id: @impl +); + +#keyset[id] +impl_assoc_item_lists( + int id: @impl ref, + int assoc_item_list: @assoc_item_list ref +); + +#keyset[id, index] +impl_attrs( + int id: @impl ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +impl_generic_param_lists( + int id: @impl ref, + int generic_param_list: @generic_param_list ref +); + +#keyset[id] +impl_is_const( + int id: @impl ref +); + +#keyset[id] +impl_is_default( + int id: @impl ref +); + +#keyset[id] +impl_is_unsafe( + int id: @impl ref +); + +#keyset[id] +impl_self_ties( + int id: @impl ref, + int self_ty: @type_repr ref +); + +#keyset[id] +impl_traits( + int id: @impl ref, + int trait: @type_repr ref +); + +#keyset[id] +impl_visibilities( + int id: @impl ref, + int visibility: @visibility ref +); + +#keyset[id] +impl_where_clauses( + int id: @impl ref, + int where_clause: @where_clause ref +); + +@looping_expr = + @for_expr +| @loop_expr +| @while_expr +; + +#keyset[id] +looping_expr_loop_bodies( + int id: @looping_expr ref, + int loop_body: @block_expr ref +); + +macro_defs( + unique int id: @macro_def +); + +#keyset[id] +macro_def_args( + int id: @macro_def ref, + int args: @token_tree ref +); + +#keyset[id, index] +macro_def_attrs( + int id: @macro_def ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +macro_def_bodies( + int id: @macro_def ref, + int body: @token_tree ref +); + +#keyset[id] +macro_def_names( + int id: @macro_def ref, + int name: @name ref +); + +#keyset[id] +macro_def_visibilities( + int id: @macro_def ref, + int visibility: @visibility ref +); + +macro_rules( + unique int id: @macro_rules +); + +#keyset[id, index] +macro_rules_attrs( + int id: @macro_rules ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +macro_rules_names( + int id: @macro_rules ref, + int name: @name ref +); + +#keyset[id] +macro_rules_token_trees( + int id: @macro_rules ref, + int token_tree: @token_tree ref +); + +#keyset[id] +macro_rules_visibilities( + int id: @macro_rules ref, + int visibility: @visibility ref +); + +modules( + unique int id: @module +); + +#keyset[id, index] +module_attrs( + int id: @module ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +module_item_lists( + int id: @module ref, + int item_list: @item_list ref +); + +#keyset[id] +module_names( + int id: @module ref, + int name: @name ref +); + +#keyset[id] +module_visibilities( + int id: @module ref, + int visibility: @visibility ref +); + +path_exprs( + unique int id: @path_expr +); + +#keyset[id, index] +path_expr_attrs( + int id: @path_expr ref, + int index: int ref, + int attr: @attr ref +); + +traits( + unique int id: @trait +); + +#keyset[id] +trait_assoc_item_lists( + int id: @trait ref, + int assoc_item_list: @assoc_item_list ref +); + +#keyset[id, index] +trait_attrs( + int id: @trait ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +trait_generic_param_lists( + int id: @trait ref, + int generic_param_list: @generic_param_list ref +); + +#keyset[id] +trait_is_auto( + int id: @trait ref +); + +#keyset[id] +trait_is_unsafe( + int id: @trait ref +); + +#keyset[id] +trait_names( + int id: @trait ref, + int name: @name ref +); + +#keyset[id] +trait_type_bound_lists( + int id: @trait ref, + int type_bound_list: @type_bound_list ref +); + +#keyset[id] +trait_visibilities( + int id: @trait ref, + int visibility: @visibility ref +); + +#keyset[id] +trait_where_clauses( + int id: @trait ref, + int where_clause: @where_clause ref +); + +trait_aliases( + unique int id: @trait_alias +); + +#keyset[id, index] +trait_alias_attrs( + int id: @trait_alias ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +trait_alias_generic_param_lists( + int id: @trait_alias ref, + int generic_param_list: @generic_param_list ref +); + +#keyset[id] +trait_alias_names( + int id: @trait_alias ref, + int name: @name ref +); + +#keyset[id] +trait_alias_type_bound_lists( + int id: @trait_alias ref, + int type_bound_list: @type_bound_list ref +); + +#keyset[id] +trait_alias_visibilities( + int id: @trait_alias ref, + int visibility: @visibility ref +); + +#keyset[id] +trait_alias_where_clauses( + int id: @trait_alias ref, + int where_clause: @where_clause ref +); + +uses( + unique int id: @use +); + +#keyset[id, index] +use_attrs( + int id: @use ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +use_use_trees( + int id: @use ref, + int use_tree: @use_tree ref +); + +#keyset[id] +use_visibilities( + int id: @use ref, + int visibility: @visibility ref +); + +consts( + unique int id: @const +); + +#keyset[id, index] +const_attrs( + int id: @const ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +const_bodies( + int id: @const ref, + int body: @expr ref +); + +#keyset[id] +const_generic_param_lists( + int id: @const ref, + int generic_param_list: @generic_param_list ref +); + +#keyset[id] +const_is_const( + int id: @const ref +); + +#keyset[id] +const_is_default( + int id: @const ref +); + +#keyset[id] +const_names( + int id: @const ref, + int name: @name ref +); + +#keyset[id] +const_type_reprs( + int id: @const ref, + int type_repr: @type_repr ref +); + +#keyset[id] +const_visibilities( + int id: @const ref, + int visibility: @visibility ref +); + +#keyset[id] +const_where_clauses( + int id: @const ref, + int where_clause: @where_clause ref +); + +#keyset[id] +const_has_implementation( + int id: @const ref +); + +enums( + unique int id: @enum +); + +#keyset[id, index] +enum_attrs( + int id: @enum ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +enum_generic_param_lists( + int id: @enum ref, + int generic_param_list: @generic_param_list ref +); + +#keyset[id] +enum_names( + int id: @enum ref, + int name: @name ref +); + +#keyset[id] +enum_variant_lists( + int id: @enum ref, + int variant_list: @variant_list ref +); + +#keyset[id] +enum_visibilities( + int id: @enum ref, + int visibility: @visibility ref +); + +#keyset[id] +enum_where_clauses( + int id: @enum ref, + int where_clause: @where_clause ref +); + +for_exprs( + unique int id: @for_expr +); + +#keyset[id, index] +for_expr_attrs( + int id: @for_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +for_expr_iterables( + int id: @for_expr ref, + int iterable: @expr ref +); + +#keyset[id] +for_expr_pats( + int id: @for_expr ref, + int pat: @pat ref +); + +functions( + unique int id: @function +); + +#keyset[id] +function_abis( + int id: @function ref, + int abi: @abi ref +); + +#keyset[id] +function_function_bodies( + int id: @function ref, + int function_body: @block_expr ref +); + +#keyset[id] +function_generic_param_lists( + int id: @function ref, + int generic_param_list: @generic_param_list ref +); + +#keyset[id] +function_is_async( + int id: @function ref +); + +#keyset[id] +function_is_const( + int id: @function ref +); + +#keyset[id] +function_is_default( + int id: @function ref +); + +#keyset[id] +function_is_gen( + int id: @function ref +); + +#keyset[id] +function_is_unsafe( + int id: @function ref +); + +#keyset[id] +function_names( + int id: @function ref, + int name: @name ref +); + +#keyset[id] +function_ret_types( + int id: @function ref, + int ret_type: @ret_type_repr ref +); + +#keyset[id] +function_visibilities( + int id: @function ref, + int visibility: @visibility ref +); + +#keyset[id] +function_where_clauses( + int id: @function ref, + int where_clause: @where_clause ref +); + +#keyset[id] +function_has_implementation( + int id: @function ref +); + +loop_exprs( + unique int id: @loop_expr +); + +#keyset[id, index] +loop_expr_attrs( + int id: @loop_expr ref, + int index: int ref, + int attr: @attr ref +); + +macro_calls( + unique int id: @macro_call +); + +#keyset[id, index] +macro_call_attrs( + int id: @macro_call ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +macro_call_paths( + int id: @macro_call ref, + int path: @path ref +); + +#keyset[id] +macro_call_token_trees( + int id: @macro_call ref, + int token_tree: @token_tree ref +); + +#keyset[id] +macro_call_macro_call_expansions( + int id: @macro_call ref, + int macro_call_expansion: @ast_node ref +); + +statics( + unique int id: @static +); + +#keyset[id, index] +static_attrs( + int id: @static ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +static_bodies( + int id: @static ref, + int body: @expr ref +); + +#keyset[id] +static_is_mut( + int id: @static ref +); + +#keyset[id] +static_is_static( + int id: @static ref +); + +#keyset[id] +static_is_unsafe( + int id: @static ref +); + +#keyset[id] +static_names( + int id: @static ref, + int name: @name ref +); + +#keyset[id] +static_type_reprs( + int id: @static ref, + int type_repr: @type_repr ref +); + +#keyset[id] +static_visibilities( + int id: @static ref, + int visibility: @visibility ref +); + +structs( + unique int id: @struct +); + +#keyset[id, index] +struct_attrs( + int id: @struct ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +struct_field_lists_( + int id: @struct ref, + int field_list: @field_list ref +); + +#keyset[id] +struct_generic_param_lists( + int id: @struct ref, + int generic_param_list: @generic_param_list ref +); + +#keyset[id] +struct_names( + int id: @struct ref, + int name: @name ref +); + +#keyset[id] +struct_visibilities( + int id: @struct ref, + int visibility: @visibility ref +); + +#keyset[id] +struct_where_clauses( + int id: @struct ref, + int where_clause: @where_clause ref +); + +type_aliases( + unique int id: @type_alias +); + +#keyset[id, index] +type_alias_attrs( + int id: @type_alias ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +type_alias_generic_param_lists( + int id: @type_alias ref, + int generic_param_list: @generic_param_list ref +); + +#keyset[id] +type_alias_is_default( + int id: @type_alias ref +); + +#keyset[id] +type_alias_names( + int id: @type_alias ref, + int name: @name ref +); + +#keyset[id] +type_alias_type_reprs( + int id: @type_alias ref, + int type_repr: @type_repr ref +); + +#keyset[id] +type_alias_type_bound_lists( + int id: @type_alias ref, + int type_bound_list: @type_bound_list ref +); + +#keyset[id] +type_alias_visibilities( + int id: @type_alias ref, + int visibility: @visibility ref +); + +#keyset[id] +type_alias_where_clauses( + int id: @type_alias ref, + int where_clause: @where_clause ref +); + +unions( + unique int id: @union +); + +#keyset[id, index] +union_attrs( + int id: @union ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +union_generic_param_lists( + int id: @union ref, + int generic_param_list: @generic_param_list ref +); + +#keyset[id] +union_names( + int id: @union ref, + int name: @name ref +); + +#keyset[id] +union_struct_field_lists( + int id: @union ref, + int struct_field_list: @struct_field_list ref +); + +#keyset[id] +union_visibilities( + int id: @union ref, + int visibility: @visibility ref +); + +#keyset[id] +union_where_clauses( + int id: @union ref, + int where_clause: @where_clause ref +); + +while_exprs( + unique int id: @while_expr +); + +#keyset[id, index] +while_expr_attrs( + int id: @while_expr ref, + int index: int ref, + int attr: @attr ref +); + +#keyset[id] +while_expr_conditions( + int id: @while_expr ref, + int condition: @expr ref +); diff --git a/rust/ql/lib/upgrades/30a0713e5bf69c60d003e4994e5abd1c78a36826/upgrade.properties b/rust/ql/lib/upgrades/30a0713e5bf69c60d003e4994e5abd1c78a36826/upgrade.properties new file mode 100644 index 00000000000..d3abc91cc1b --- /dev/null +++ b/rust/ql/lib/upgrades/30a0713e5bf69c60d003e4994e5abd1c78a36826/upgrade.properties @@ -0,0 +1,10 @@ +description: Removed the `@call_expr_base` union type +compatibility: backwards + +call_expr_base_arg_lists.rel: delete +call_expr_base_attrs.rel: delete + +call_expr_arg_lists.rel: run upgrade.ql call_expr_arg_lists +call_expr_attrs.rel: run upgrade.ql call_expr_attrs +method_call_expr_arg_lists.rel: run upgrade.ql method_call_expr_arg_lists +method_call_expr_attrs.rel: run upgrade.ql method_call_expr_attrs diff --git a/rust/ql/lib/upgrades/30a0713e5bf69c60d003e4994e5abd1c78a36826/upgrade.ql b/rust/ql/lib/upgrades/30a0713e5bf69c60d003e4994e5abd1c78a36826/upgrade.ql new file mode 100644 index 00000000000..727b13634ef --- /dev/null +++ b/rust/ql/lib/upgrades/30a0713e5bf69c60d003e4994e5abd1c78a36826/upgrade.ql @@ -0,0 +1,23 @@ +class Element extends @element { + string toString() { none() } +} + +class CallExpr extends Element, @call_expr { } + +class ArgList extends Element, @arg_list { } + +class Attr extends Element, @attr { } + +class MethodCallExpr extends Element, @method_call_expr { } + +query predicate call_expr_arg_lists(CallExpr c, ArgList l) { call_expr_base_arg_lists(c, l) } + +query predicate call_expr_attrs(CallExpr c, int i, Attr a) { call_expr_base_attrs(c, i, a) } + +query predicate method_call_expr_arg_lists(MethodCallExpr c, ArgList l) { + call_expr_base_arg_lists(c, l) +} + +query predicate method_call_expr_attrs(MethodCallExpr c, int i, Attr a) { + call_expr_base_attrs(c, i, a) +} diff --git a/rust/ql/lib/utils/test/InlineFlowTest.qll b/rust/ql/lib/utils/test/InlineFlowTest.qll index 938559620fc..c1398df9e11 100644 --- a/rust/ql/lib/utils/test/InlineFlowTest.qll +++ b/rust/ql/lib/utils/test/InlineFlowTest.qll @@ -26,15 +26,16 @@ private module FlowTestImpl implements InputSig { predicate defaultSource(DataFlow::Node source) { callTargetName(source.asExpr(), "source") } predicate defaultSink(DataFlow::Node sink) { - any(CallExpr call | callTargetName(call, "sink")).getAnArg() = sink.asExpr() + any(CallExpr call | callTargetName(call, "sink")).getASyntacticArgument() = sink.asExpr() } private string getSourceArgString(DataFlow::Node src) { defaultSource(src) and - result = src.asExpr().(CallExpr).getArg(0).toString() + result = src.asExpr().(Call).getPositionalArgument(0).toString() or sourceNode(src, _) and - result = src.(Node::FlowSummaryNode).getSourceElement().getCall().getArg(0).toString() and + result = + src.(Node::FlowSummaryNode).getSourceElement().getCall().getPositionalArgument(0).toString() and // Don't use the result if it contains spaces not result.matches("% %") } diff --git a/rust/ql/src/change-notes/2025-12-01-hard-coded-cryptographic-value.md b/rust/ql/src/change-notes/2025-12-01-hard-coded-cryptographic-value.md new file mode 100644 index 00000000000..f211982df62 --- /dev/null +++ b/rust/ql/src/change-notes/2025-12-01-hard-coded-cryptographic-value.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* The `rust/hard-coded-cryptographic-value` query has been extended with new heuristic sinks identifying passwords, initialization vectors, nonces and salts. diff --git a/rust/ql/src/queries/security/CWE-614/InsecureCookie.ql b/rust/ql/src/queries/security/CWE-614/InsecureCookie.ql index 61996adaf05..4de9cc98948 100644 --- a/rust/ql/src/queries/security/CWE-614/InsecureCookie.ql +++ b/rust/ql/src/queries/security/CWE-614/InsecureCookie.ql @@ -88,5 +88,5 @@ import InsecureCookieFlow::PathGraph from InsecureCookieFlow::PathNode sourceNode, InsecureCookieFlow::PathNode sinkNode where InsecureCookieFlow::flowPath(sourceNode, sinkNode) and - not PartitionedCookieFlow::flow(_, sinkNode.getNode()) + not PartitionedCookieFlow::flowTo(sinkNode.getNode()) select sinkNode.getNode(), sourceNode, sinkNode, "Cookie attribute 'Secure' is not set to true." diff --git a/rust/ql/src/queries/security/CWE-696/BadCtorInitialization.ql b/rust/ql/src/queries/security/CWE-696/BadCtorInitialization.ql index f0f7cdf0d98..7a206856adf 100644 --- a/rust/ql/src/queries/security/CWE-696/BadCtorInitialization.ql +++ b/rust/ql/src/queries/security/CWE-696/BadCtorInitialization.ql @@ -30,10 +30,8 @@ class CtorAttr extends Attr { /** * A call into the Rust standard library, that is, a sink for this query. */ -class StdCall extends Expr { - StdCall() { - this.(CallExprBase).getStaticTarget().getCanonicalPath().matches(["std::%", " enclosed call edgesFwd(_, pred) and - pred = succ.(CallExprBase).getEnclosingCallable() + pred = succ.(Call).getEnclosingCallable() or // [forwards reachable] call -> target callable edgesFwd(_, pred) and - pred.(CallExprBase).getStaticTarget() = succ + pred.(Call).getStaticTarget() = succ } /** diff --git a/rust/ql/src/queries/security/CWE-798/HardcodedCryptographicValue.ql b/rust/ql/src/queries/security/CWE-798/HardcodedCryptographicValue.ql index f5a43c5419c..c8e6c9932cb 100644 --- a/rust/ql/src/queries/security/CWE-798/HardcodedCryptographicValue.ql +++ b/rust/ql/src/queries/security/CWE-798/HardcodedCryptographicValue.ql @@ -39,6 +39,11 @@ module HardcodedCryptographicValueConfig implements DataFlow::ConfigSig { // case like `[0, 0, 0, 0]`) isSource(node) } + + predicate isBarrierOut(DataFlow::Node node) { + // make sinks barriers so that we only report the closest instance + isSink(node) + } } module HardcodedCryptographicValueFlow = TaintTracking::Global; diff --git a/rust/ql/src/queries/telemetry/DatabaseQuality.qll b/rust/ql/src/queries/telemetry/DatabaseQuality.qll index 64adf9826dc..553783498ae 100644 --- a/rust/ql/src/queries/telemetry/DatabaseQuality.qll +++ b/rust/ql/src/queries/telemetry/DatabaseQuality.qll @@ -6,6 +6,7 @@ import rust import codeql.util.ReportStats +import codeql.rust.elements.internal.CallExprImpl::Impl as CallExprImpl import codeql.rust.internal.TypeInference as TypeInference /** @@ -19,22 +20,22 @@ private class RelevantFile extends File { } module CallTargetStats implements StatsSig { + // TODO: Take other calls into account + abstract private class CallExprBase extends InvocationExpr { } + + private class CallExprCallExprBase extends CallExpr, CallExprBase { } + + private class MethodCallExprCallExprBase extends MethodCallExpr, CallExprBase { } + int getNumberOfOk() { result = - count(CallExprBase c | c.getFile() instanceof RelevantFile and exists(c.getStaticTarget())) - } - - private predicate isLambdaCall(CallExpr call) { - exists(Expr receiver | receiver = call.getFunction() | - // All calls to complex expressions and local variable accesses are lambda calls - receiver instanceof PathExpr implies receiver = any(Variable v).getAnAccess() - ) + count(CallExprBase c | c.getFile() instanceof RelevantFile and exists(c.getResolvedTarget())) } additional predicate isNotOkCall(CallExprBase c) { c.getFile() instanceof RelevantFile and - not exists(c.getStaticTarget()) and - not isLambdaCall(c) + not exists(c.getResolvedTarget()) and + not c instanceof CallExprImpl::DynamicCallExpr } int getNumberOfNotOk() { result = count(CallExprBase c | isNotOkCall(c)) } diff --git a/rust/ql/src/utils/modelgenerator/internal/CaptureModels.qll b/rust/ql/src/utils/modelgenerator/internal/CaptureModels.qll index 420051f4ee1..9826f56795f 100644 --- a/rust/ql/src/utils/modelgenerator/internal/CaptureModels.qll +++ b/rust/ql/src/utils/modelgenerator/internal/CaptureModels.qll @@ -67,8 +67,9 @@ module ModelGeneratorCommonInput implements string parameterExactAccess(R::ParamBase p) { result = - "Argument[" + any(DataFlowImpl::ParameterPosition pos | p = pos.getParameterIn(_)).toString() + - "]" + "Argument[" + + any(DataFlowImpl::RustDataFlow::ParameterPosition pos | p = pos.getParameterIn(_)) + .toString() + "]" } string parameterApproximateAccess(R::ParamBase p) { result = parameterExactAccess(p) } @@ -78,12 +79,16 @@ module ModelGeneratorCommonInput implements } bindingset[c] - string paramReturnNodeAsApproximateOutput(QualifiedCallable c, DataFlowImpl::ParameterPosition pos) { + string paramReturnNodeAsApproximateOutput( + QualifiedCallable c, DataFlowImpl::RustDataFlow::ParameterPosition pos + ) { result = paramReturnNodeAsExactOutput(c, pos) } bindingset[c] - string paramReturnNodeAsExactOutput(QualifiedCallable c, DataFlowImpl::ParameterPosition pos) { + string paramReturnNodeAsExactOutput( + QualifiedCallable c, DataFlowImpl::RustDataFlow::ParameterPosition pos + ) { result = parameterExactAccess(c.getFunction().getParam(pos.getPosition())) or pos.isSelf() and result = qualifierString() diff --git a/rust/ql/test/extractor-tests/generated/.generated_tests.list b/rust/ql/test/extractor-tests/generated/.generated_tests.list index 879695fb758..a0f338af420 100644 --- a/rust/ql/test/extractor-tests/generated/.generated_tests.list +++ b/rust/ql/test/extractor-tests/generated/.generated_tests.list @@ -23,7 +23,7 @@ BinaryExpr/gen_binary_expr.rs 5ea68396dc2e3ff7fcaf5a5201636dd175dd45be36647b6ae0 BlockExpr/gen_block_expr.rs 17b06c726e304e0efcfde8e71afd9c657860312be554366894236125cb08719e 17b06c726e304e0efcfde8e71afd9c657860312be554366894236125cb08719e BoxPat/gen_box_pat.rs 1493e24b732370b577ade38c47db17fa157df19f5390606a67a6040e49b501c0 1493e24b732370b577ade38c47db17fa157df19f5390606a67a6040e49b501c0 BreakExpr/gen_break_expr.rs aacdf9df7fc51d19742b9e813835c0bd0913017e8d62765960e06b27d58b9031 aacdf9df7fc51d19742b9e813835c0bd0913017e8d62765960e06b27d58b9031 -CallExpr/gen_call_expr.rs 013a7c878996aefb25b94b68eebc4f0b1bb74ccd09e91c491980817a383e2401 013a7c878996aefb25b94b68eebc4f0b1bb74ccd09e91c491980817a383e2401 +CallExpr/gen_call_expr.rs 228705e9b0c46d34aa035da3c139a8c3e93fb144d3310592d5bad38ac97382c2 228705e9b0c46d34aa035da3c139a8c3e93fb144d3310592d5bad38ac97382c2 CastExpr/gen_cast_expr.rs c3892211fbae4fed7cb1f25ff1679fd79d2878bf0bf2bd4b7982af23d00129f5 c3892211fbae4fed7cb1f25ff1679fd79d2878bf0bf2bd4b7982af23d00129f5 ClosureExpr/gen_closure_expr.rs bd95408103b7f2084e526e6d35cf3319b2e9d7219aff4c80e4e6691180c549b4 bd95408103b7f2084e526e6d35cf3319b2e9d7219aff4c80e4e6691180c549b4 Comment/gen_comment.rs 1e1f9f43161a79c096c2056e8b7f5346385ab7addcdec68c2d53b383dd3debe6 1e1f9f43161a79c096c2056e8b7f5346385ab7addcdec68c2d53b383dd3debe6 @@ -80,7 +80,7 @@ MatchArmList/gen_match_arm_list.rs 6dcb92591c86771d2aeb762e4274d3e61a7d6c1a42da3 MatchExpr/gen_match_expr.rs 081c5d4c78cb71ccd13fb37a93d7f525267c51b179f44b5a22ca3297897002a0 081c5d4c78cb71ccd13fb37a93d7f525267c51b179f44b5a22ca3297897002a0 MatchGuard/gen_match_guard.rs f0e84a1f608c0361983c516a40216cea149620a36e0aed7ff39b0b7d77a9ab8a f0e84a1f608c0361983c516a40216cea149620a36e0aed7ff39b0b7d77a9ab8a Meta/gen_meta.rs 39172a1f7dd02fa3149e7a1fc1dc1f135aa87c84057ee721cd9b373517042b25 39172a1f7dd02fa3149e7a1fc1dc1f135aa87c84057ee721cd9b373517042b25 -MethodCallExpr/gen_method_call_expr.rs f2b4679eb1ec095981fe6bd656b632c22bf6bd0da133309da3f7ef5bd1ab4b5d f2b4679eb1ec095981fe6bd656b632c22bf6bd0da133309da3f7ef5bd1ab4b5d +MethodCallExpr/gen_method_call_expr.rs f696e63c5302f46dcac7bc2914fe899d029996d5064ffe8252cfa173a06f9dd3 f696e63c5302f46dcac7bc2914fe899d029996d5064ffe8252cfa173a06f9dd3 Module/gen_module.rs 815605a604fea1d9276684f8d6738a4e833eacad57ceeb27e2095fc450264fc1 815605a604fea1d9276684f8d6738a4e833eacad57ceeb27e2095fc450264fc1 Name/gen_name.rs 8a7fe65ee632a47d12eaa313e7248ac9210e5a381e9522499ca68f94c39e72c0 8a7fe65ee632a47d12eaa313e7248ac9210e5a381e9522499ca68f94c39e72c0 NameRef/gen_name_ref.rs c8c922e77a7d62b8272359ccdabbf7e15411f31ca85f15a3afdd94bec7ec64e7 c8c922e77a7d62b8272359ccdabbf7e15411f31ca85f15a3afdd94bec7ec64e7 @@ -129,8 +129,8 @@ Trait/gen_trait.rs bac694993e224f9c6dd86cfb28c54846ae1b3bae45a1e58d3149c88418448 TraitAlias/gen_trait_alias.rs 425d78a7cb87db7737ceaf713c9a62e0411537374d1bc58c5b1fb80cc25732c9 425d78a7cb87db7737ceaf713c9a62e0411537374d1bc58c5b1fb80cc25732c9 TryExpr/gen_try_expr.rs f60198181a423661f4ed1bf6f98d475f40ada190b7b5fc6af97aa5e45ca29a1e f60198181a423661f4ed1bf6f98d475f40ada190b7b5fc6af97aa5e45ca29a1e TupleExpr/gen_tuple_expr.rs 27e56846b3f08c37c8a345169c2a532b2023d231d46a5bdf586bbc6d8fb36a01 27e56846b3f08c37c8a345169c2a532b2023d231d46a5bdf586bbc6d8fb36a01 -TupleField/gen_tuple_field.rs 5d6b4f356af895541f975cc1fd90116fd047fe914c2049d47f61e4a43a8c2af4 5d6b4f356af895541f975cc1fd90116fd047fe914c2049d47f61e4a43a8c2af4 -TupleFieldList/gen_tuple_field_list.rs 42f0af8c391fb9e33fe09b791e0e719cadf5143b58764f8a5d38f8d9054daca7 42f0af8c391fb9e33fe09b791e0e719cadf5143b58764f8a5d38f8d9054daca7 +TupleField/gen_tuple_field.rs 20507753ddb979a33d0e568ae5ebe466f039e7ab7b8f2e6ce15b28b3e4450615 20507753ddb979a33d0e568ae5ebe466f039e7ab7b8f2e6ce15b28b3e4450615 +TupleFieldList/gen_tuple_field_list.rs 4702b92cfca9c4db9b84cb846c5d44569ad3f3e40cd07e9015d144152c684fd0 4702b92cfca9c4db9b84cb846c5d44569ad3f3e40cd07e9015d144152c684fd0 TuplePat/gen_tuple_pat.rs b1b0c9c5ff1b787f380644691c77807655a4f6441fc7431c90ecf78c54c26148 b1b0c9c5ff1b787f380644691c77807655a4f6441fc7431c90ecf78c54c26148 TupleStructPat/gen_tuple_struct_pat.rs 601ca8813272d15b4c8fd7402d0d28a42a62be82865eb5e86b985ad31464ca98 601ca8813272d15b4c8fd7402d0d28a42a62be82865eb5e86b985ad31464ca98 TupleTypeRepr/gen_tuple_type_repr.rs 64873a6a1cd5df6cd10165d7e9fa0399902b6bfbac086ef3a7ce83237b816879 64873a6a1cd5df6cd10165d7e9fa0399902b6bfbac086ef3a7ce83237b816879 diff --git a/rust/ql/test/extractor-tests/generated/CallExpr/CallExpr.expected b/rust/ql/test/extractor-tests/generated/CallExpr/CallExpr.expected index 3aaaed00da2..16e6f165028 100644 --- a/rust/ql/test/extractor-tests/generated/CallExpr/CallExpr.expected +++ b/rust/ql/test/extractor-tests/generated/CallExpr/CallExpr.expected @@ -1,21 +1,16 @@ instances -| gen_call_expr.rs:5:5:5:11 | foo(...) | -| gen_call_expr.rs:6:5:6:23 | foo::<...>(...) | -| gen_call_expr.rs:7:5:7:14 | ...(...) | -| gen_call_expr.rs:8:5:8:10 | foo(...) | +| gen_call_expr.rs:8:5:8:11 | foo(...) | +| gen_call_expr.rs:9:5:9:23 | foo::<...>(...) | +| gen_call_expr.rs:10:5:10:14 | ...(...) | +| gen_call_expr.rs:11:5:11:20 | ...::Some(...) | getArgList -| gen_call_expr.rs:5:5:5:11 | foo(...) | gen_call_expr.rs:5:8:5:11 | ArgList | -| gen_call_expr.rs:6:5:6:23 | foo::<...>(...) | gen_call_expr.rs:6:20:6:23 | ArgList | -| gen_call_expr.rs:7:5:7:14 | ...(...) | gen_call_expr.rs:7:11:7:14 | ArgList | -| gen_call_expr.rs:8:5:8:10 | foo(...) | gen_call_expr.rs:8:8:8:10 | ArgList | +| gen_call_expr.rs:8:5:8:11 | foo(...) | gen_call_expr.rs:8:8:8:11 | ArgList | +| gen_call_expr.rs:9:5:9:23 | foo::<...>(...) | gen_call_expr.rs:9:20:9:23 | ArgList | +| gen_call_expr.rs:10:5:10:14 | ...(...) | gen_call_expr.rs:10:11:10:14 | ArgList | +| gen_call_expr.rs:11:5:11:20 | ...::Some(...) | gen_call_expr.rs:11:17:11:20 | ArgList | getAttr -getArg -| gen_call_expr.rs:5:5:5:11 | foo(...) | 0 | gen_call_expr.rs:5:9:5:10 | 42 | -| gen_call_expr.rs:6:5:6:23 | foo::<...>(...) | 0 | gen_call_expr.rs:6:21:6:22 | 42 | -| gen_call_expr.rs:7:5:7:14 | ...(...) | 0 | gen_call_expr.rs:7:12:7:13 | 42 | -| gen_call_expr.rs:8:5:8:10 | foo(...) | 0 | gen_call_expr.rs:8:9:8:9 | 1 | getFunction -| gen_call_expr.rs:5:5:5:11 | foo(...) | gen_call_expr.rs:5:5:5:7 | foo | -| gen_call_expr.rs:6:5:6:23 | foo::<...>(...) | gen_call_expr.rs:6:5:6:19 | foo::<...> | -| gen_call_expr.rs:7:5:7:14 | ...(...) | gen_call_expr.rs:7:5:7:10 | foo[0] | -| gen_call_expr.rs:8:5:8:10 | foo(...) | gen_call_expr.rs:8:5:8:7 | foo | +| gen_call_expr.rs:8:5:8:11 | foo(...) | gen_call_expr.rs:8:5:8:7 | foo | +| gen_call_expr.rs:9:5:9:23 | foo::<...>(...) | gen_call_expr.rs:9:5:9:19 | foo::<...> | +| gen_call_expr.rs:10:5:10:14 | ...(...) | gen_call_expr.rs:10:5:10:10 | foo[0] | +| gen_call_expr.rs:11:5:11:20 | ...::Some(...) | gen_call_expr.rs:11:5:11:16 | ...::Some | diff --git a/rust/ql/test/extractor-tests/generated/CallExpr/CallExpr.ql b/rust/ql/test/extractor-tests/generated/CallExpr/CallExpr.ql index e16ab837325..4d3b26f2f78 100644 --- a/rust/ql/test/extractor-tests/generated/CallExpr/CallExpr.ql +++ b/rust/ql/test/extractor-tests/generated/CallExpr/CallExpr.ql @@ -12,10 +12,6 @@ query predicate getAttr(CallExpr x, int index, Attr getAttr) { toBeTested(x) and not x.isUnknown() and getAttr = x.getAttr(index) } -query predicate getArg(CallExpr x, int index, Expr getArg) { - toBeTested(x) and not x.isUnknown() and getArg = x.getArg(index) -} - query predicate getFunction(CallExpr x, Expr getFunction) { toBeTested(x) and not x.isUnknown() and getFunction = x.getFunction() } diff --git a/rust/ql/test/extractor-tests/generated/CallExpr/gen_call_expr.rs b/rust/ql/test/extractor-tests/generated/CallExpr/gen_call_expr.rs index b2436cc0042..3ab2646ae37 100644 --- a/rust/ql/test/extractor-tests/generated/CallExpr/gen_call_expr.rs +++ b/rust/ql/test/extractor-tests/generated/CallExpr/gen_call_expr.rs @@ -1,9 +1,12 @@ // generated by codegen, do not edit fn test_call_expr() -> () { - // A function call expression. For example: + // NOTE: Consider using `Call` instead, as that excludes call expressions that are + // instantiations of tuple structs and tuple variants. + // + // A call expression. For example: foo(42); foo::(42); foo[0](42); - foo(1) = 4; + Option::Some(42); // tuple variant instantiation } diff --git a/rust/ql/test/extractor-tests/generated/MethodCallExpr/MethodCallExpr.expected b/rust/ql/test/extractor-tests/generated/MethodCallExpr/MethodCallExpr.expected index 0eedcc70b5d..34d44431de2 100644 --- a/rust/ql/test/extractor-tests/generated/MethodCallExpr/MethodCallExpr.expected +++ b/rust/ql/test/extractor-tests/generated/MethodCallExpr/MethodCallExpr.expected @@ -1,18 +1,15 @@ instances -| gen_method_call_expr.rs:5:5:5:13 | x.foo(...) | -| gen_method_call_expr.rs:6:5:6:25 | x.foo(...) | +| gen_method_call_expr.rs:9:5:9:13 | x.foo(...) | +| gen_method_call_expr.rs:10:5:10:25 | x.foo(...) | getArgList -| gen_method_call_expr.rs:5:5:5:13 | x.foo(...) | gen_method_call_expr.rs:5:10:5:13 | ArgList | -| gen_method_call_expr.rs:6:5:6:25 | x.foo(...) | gen_method_call_expr.rs:6:22:6:25 | ArgList | +| gen_method_call_expr.rs:9:5:9:13 | x.foo(...) | gen_method_call_expr.rs:9:10:9:13 | ArgList | +| gen_method_call_expr.rs:10:5:10:25 | x.foo(...) | gen_method_call_expr.rs:10:22:10:25 | ArgList | getAttr -getArg -| gen_method_call_expr.rs:5:5:5:13 | x.foo(...) | 0 | gen_method_call_expr.rs:5:11:5:12 | 42 | -| gen_method_call_expr.rs:6:5:6:25 | x.foo(...) | 0 | gen_method_call_expr.rs:6:23:6:24 | 42 | getGenericArgList -| gen_method_call_expr.rs:6:5:6:25 | x.foo(...) | gen_method_call_expr.rs:6:10:6:21 | <...> | +| gen_method_call_expr.rs:10:5:10:25 | x.foo(...) | gen_method_call_expr.rs:10:10:10:21 | <...> | getIdentifier -| gen_method_call_expr.rs:5:5:5:13 | x.foo(...) | gen_method_call_expr.rs:5:7:5:9 | foo | -| gen_method_call_expr.rs:6:5:6:25 | x.foo(...) | gen_method_call_expr.rs:6:7:6:9 | foo | +| gen_method_call_expr.rs:9:5:9:13 | x.foo(...) | gen_method_call_expr.rs:9:7:9:9 | foo | +| gen_method_call_expr.rs:10:5:10:25 | x.foo(...) | gen_method_call_expr.rs:10:7:10:9 | foo | getReceiver -| gen_method_call_expr.rs:5:5:5:13 | x.foo(...) | gen_method_call_expr.rs:5:5:5:5 | x | -| gen_method_call_expr.rs:6:5:6:25 | x.foo(...) | gen_method_call_expr.rs:6:5:6:5 | x | +| gen_method_call_expr.rs:9:5:9:13 | x.foo(...) | gen_method_call_expr.rs:9:5:9:5 | x | +| gen_method_call_expr.rs:10:5:10:25 | x.foo(...) | gen_method_call_expr.rs:10:5:10:5 | x | diff --git a/rust/ql/test/extractor-tests/generated/MethodCallExpr/MethodCallExpr.ql b/rust/ql/test/extractor-tests/generated/MethodCallExpr/MethodCallExpr.ql index d1b6d5a1304..8ecc14ee820 100644 --- a/rust/ql/test/extractor-tests/generated/MethodCallExpr/MethodCallExpr.ql +++ b/rust/ql/test/extractor-tests/generated/MethodCallExpr/MethodCallExpr.ql @@ -12,10 +12,6 @@ query predicate getAttr(MethodCallExpr x, int index, Attr getAttr) { toBeTested(x) and not x.isUnknown() and getAttr = x.getAttr(index) } -query predicate getArg(MethodCallExpr x, int index, Expr getArg) { - toBeTested(x) and not x.isUnknown() and getArg = x.getArg(index) -} - query predicate getGenericArgList(MethodCallExpr x, GenericArgList getGenericArgList) { toBeTested(x) and not x.isUnknown() and getGenericArgList = x.getGenericArgList() } diff --git a/rust/ql/test/extractor-tests/generated/MethodCallExpr/gen_method_call_expr.rs b/rust/ql/test/extractor-tests/generated/MethodCallExpr/gen_method_call_expr.rs index f8bf728d257..5b4f22e8efc 100644 --- a/rust/ql/test/extractor-tests/generated/MethodCallExpr/gen_method_call_expr.rs +++ b/rust/ql/test/extractor-tests/generated/MethodCallExpr/gen_method_call_expr.rs @@ -1,6 +1,10 @@ // generated by codegen, do not edit fn test_method_call_expr() -> () { + // NOTE: Consider using `MethodCall` instead, as that also includes calls to methods using + // call syntax (such as `Foo::method(x)`), operation syntax (such as `x + y`), and + // indexing syntax (such as `x[y]`). + // // A method call expression. For example: x.foo(42); x.foo::(42); diff --git a/rust/ql/test/extractor-tests/generated/TupleField/gen_tuple_field.rs b/rust/ql/test/extractor-tests/generated/TupleField/gen_tuple_field.rs index 96fe3582e40..e7a28dd5939 100644 --- a/rust/ql/test/extractor-tests/generated/TupleField/gen_tuple_field.rs +++ b/rust/ql/test/extractor-tests/generated/TupleField/gen_tuple_field.rs @@ -1,7 +1,7 @@ // generated by codegen, do not edit fn test_tuple_field() -> () { - // A field in a tuple struct or tuple enum variant. + // A field in a tuple struct or tuple variant. // // For example: struct S(i32, String); diff --git a/rust/ql/test/extractor-tests/generated/TupleFieldList/gen_tuple_field_list.rs b/rust/ql/test/extractor-tests/generated/TupleFieldList/gen_tuple_field_list.rs index 26f955c4add..d010d73c207 100644 --- a/rust/ql/test/extractor-tests/generated/TupleFieldList/gen_tuple_field_list.rs +++ b/rust/ql/test/extractor-tests/generated/TupleFieldList/gen_tuple_field_list.rs @@ -1,7 +1,7 @@ // generated by codegen, do not edit fn test_tuple_field_list() -> () { - // A list of fields in a tuple struct or tuple enum variant. + // A list of fields in a tuple struct or tuple variant. // // For example: struct S(i32, String); diff --git a/rust/ql/test/extractor-tests/macro-expansion/PrintAst.expected b/rust/ql/test/extractor-tests/macro-expansion/PrintAst.expected index 158ee877d45..e50dc4d5274 100644 --- a/rust/ql/test/extractor-tests/macro-expansion/PrintAst.expected +++ b/rust/ql/test/extractor-tests/macro-expansion/PrintAst.expected @@ -1770,7 +1770,7 @@ proc_macro.rs: # 16| getIdentifier(): [NameRef] items # 15| getMatchArmList(): [MatchArmList] MatchArmList # 15| getArm(0): [MatchArm] ... => ... -# 15| getExpr(): [CallExpr] ...::RepInterp(...) +# 15| getExpr(): [TupleStructExpr] ...::RepInterp(...) # 15| getArgList(): [ArgList] ArgList # 15| getArg(0): [VariableAccess] _x # 15| getPath(): [Path] _x diff --git a/rust/ql/test/library-tests/dataflow/pointers/inline-flow.expected b/rust/ql/test/library-tests/dataflow/pointers/inline-flow.expected index 10325d5fe81..2c7fbc9381f 100644 --- a/rust/ql/test/library-tests/dataflow/pointers/inline-flow.expected +++ b/rust/ql/test/library-tests/dataflow/pointers/inline-flow.expected @@ -41,6 +41,9 @@ edges | main.rs:73:10:73:10 | [post] b [&ref] | main.rs:74:15:74:15 | b [&ref] | provenance | | | main.rs:73:14:73:23 | source(...) | main.rs:73:10:73:10 | [post] b [&ref] | provenance | | | main.rs:74:15:74:15 | b [&ref] | main.rs:74:14:74:15 | * ... | provenance | MaD:1 | +| main.rs:90:11:90:16 | [post] &mut a [&ref] | main.rs:90:16:90:16 | [post] a | provenance | | +| main.rs:90:16:90:16 | [post] a | main.rs:91:14:91:14 | a | provenance | | +| main.rs:90:21:90:30 | source(...) | main.rs:90:11:90:16 | [post] &mut a [&ref] | provenance | | | main.rs:105:10:105:10 | [post] c [&ref] | main.rs:106:15:106:15 | c [&ref] | provenance | | | main.rs:105:14:105:23 | source(...) | main.rs:105:10:105:10 | [post] c [&ref] | provenance | | | main.rs:106:15:106:15 | c [&ref] | main.rs:106:14:106:15 | * ... | provenance | MaD:1 | @@ -175,6 +178,10 @@ nodes | main.rs:73:14:73:23 | source(...) | semmle.label | source(...) | | main.rs:74:14:74:15 | * ... | semmle.label | * ... | | main.rs:74:15:74:15 | b [&ref] | semmle.label | b [&ref] | +| main.rs:90:11:90:16 | [post] &mut a [&ref] | semmle.label | [post] &mut a [&ref] | +| main.rs:90:16:90:16 | [post] a | semmle.label | [post] a | +| main.rs:90:21:90:30 | source(...) | semmle.label | source(...) | +| main.rs:91:14:91:14 | a | semmle.label | a | | main.rs:105:10:105:10 | [post] c [&ref] | semmle.label | [post] c [&ref] | | main.rs:105:14:105:23 | source(...) | semmle.label | source(...) | | main.rs:106:14:106:15 | * ... | semmle.label | * ... | @@ -288,6 +295,7 @@ testFailures | main.rs:53:14:53:15 | * ... | main.rs:51:17:51:26 | source(...) | main.rs:53:14:53:15 | * ... | $@ | main.rs:51:17:51:26 | source(...) | source(...) | | main.rs:59:33:59:34 | * ... | main.rs:57:22:57:31 | source(...) | main.rs:59:33:59:34 | * ... | $@ | main.rs:57:22:57:31 | source(...) | source(...) | | main.rs:74:14:74:15 | * ... | main.rs:73:14:73:23 | source(...) | main.rs:74:14:74:15 | * ... | $@ | main.rs:73:14:73:23 | source(...) | source(...) | +| main.rs:91:14:91:14 | a | main.rs:90:21:90:30 | source(...) | main.rs:91:14:91:14 | a | $@ | main.rs:90:21:90:30 | source(...) | source(...) | | main.rs:106:14:106:15 | * ... | main.rs:105:14:105:23 | source(...) | main.rs:106:14:106:15 | * ... | $@ | main.rs:105:14:105:23 | source(...) | source(...) | | main.rs:113:14:113:15 | * ... | main.rs:112:25:112:34 | source(...) | main.rs:113:14:113:15 | * ... | $@ | main.rs:112:25:112:34 | source(...) | source(...) | | main.rs:175:14:175:34 | my_number.to_number() | main.rs:174:44:174:53 | source(...) | main.rs:175:14:175:34 | my_number.to_number() | $@ | main.rs:174:44:174:53 | source(...) | source(...) | diff --git a/rust/ql/test/library-tests/dataflow/pointers/main.rs b/rust/ql/test/library-tests/dataflow/pointers/main.rs index d7e28c9368f..2ebd5ee28df 100644 --- a/rust/ql/test/library-tests/dataflow/pointers/main.rs +++ b/rust/ql/test/library-tests/dataflow/pointers/main.rs @@ -88,7 +88,7 @@ mod intraprocedural_mutable_borrows { let mut a = 1; sink(a); *(&mut a) = source(87); - sink(a); // $ MISSING: hasValueFlow=87 + sink(a); // $ hasValueFlow=87 } pub fn clear_through_borrow() { diff --git a/rust/ql/test/library-tests/dataflow/sources/net/InlineFlow.expected b/rust/ql/test/library-tests/dataflow/sources/net/InlineFlow.expected index 9682ff1a01d..c74ffd2989f 100644 --- a/rust/ql/test/library-tests/dataflow/sources/net/InlineFlow.expected +++ b/rust/ql/test/library-tests/dataflow/sources/net/InlineFlow.expected @@ -183,7 +183,11 @@ edges | test.rs:389:61:389:66 | [post] buffer | test.rs:392:23:392:33 | buffer[...] | provenance | | | test.rs:391:23:391:28 | buffer | test.rs:391:22:391:28 | &buffer | provenance | | | test.rs:392:23:392:33 | buffer[...] | test.rs:392:22:392:33 | &... | provenance | | +| test.rs:399:63:399:73 | &mut reader [&ref] | test.rs:399:63:399:73 | [post] &mut reader [&ref] | provenance | MaD:13 | | test.rs:399:63:399:73 | &mut reader [&ref] | test.rs:399:76:399:87 | [post] &mut buffer1 [&ref] | provenance | MaD:13 | +| test.rs:399:63:399:73 | [post] &mut reader [&ref] | test.rs:399:68:399:73 | [post] reader | provenance | | +| test.rs:399:68:399:73 | [post] reader | test.rs:403:31:403:36 | reader | provenance | | +| test.rs:399:68:399:73 | [post] reader | test.rs:408:55:408:60 | reader | provenance | | | test.rs:399:68:399:73 | reader | test.rs:399:63:399:73 | &mut reader [&ref] | provenance | | | test.rs:399:76:399:87 | [post] &mut buffer1 [&ref] | test.rs:399:81:399:87 | [post] buffer1 | provenance | | | test.rs:399:81:399:87 | [post] buffer1 | test.rs:400:19:400:40 | buffer1[...] | provenance | | @@ -257,7 +261,15 @@ edges | test.rs:447:61:447:66 | [post] buffer | test.rs:450:23:450:33 | buffer[...] | provenance | | | test.rs:448:19:448:24 | buffer | test.rs:448:18:448:24 | &buffer | provenance | | | test.rs:450:23:450:33 | buffer[...] | test.rs:450:22:450:33 | &... | provenance | | +| test.rs:457:63:457:74 | &mut reader2 [&ref] | test.rs:457:63:457:74 | [post] &mut reader2 [&ref] | provenance | MaD:13 | | test.rs:457:63:457:74 | &mut reader2 [&ref] | test.rs:457:77:457:88 | [post] &mut buffer1 [&ref] | provenance | MaD:13 | +| test.rs:457:63:457:74 | [post] &mut reader2 [&ref] | test.rs:457:68:457:74 | [post] reader2 | provenance | | +| test.rs:457:68:457:74 | [post] reader2 | test.rs:461:31:461:37 | reader2 | provenance | | +| test.rs:457:68:457:74 | [post] reader2 | test.rs:467:44:467:50 | reader2 | provenance | | +| test.rs:457:68:457:74 | [post] reader2 | test.rs:479:26:479:32 | reader2 | provenance | | +| test.rs:457:68:457:74 | [post] reader2 | test.rs:486:31:486:37 | reader2 | provenance | | +| test.rs:457:68:457:74 | [post] reader2 | test.rs:493:31:493:37 | reader2 | provenance | | +| test.rs:457:68:457:74 | [post] reader2 | test.rs:500:31:500:37 | reader2 | provenance | | | test.rs:457:68:457:74 | reader2 | test.rs:457:63:457:74 | &mut reader2 [&ref] | provenance | | | test.rs:457:77:457:88 | [post] &mut buffer1 [&ref] | test.rs:457:82:457:88 | [post] buffer1 | provenance | | | test.rs:457:82:457:88 | [post] buffer1 | test.rs:458:19:458:40 | buffer1[...] | provenance | | @@ -461,6 +473,8 @@ nodes | test.rs:392:22:392:33 | &... | semmle.label | &... | | test.rs:392:23:392:33 | buffer[...] | semmle.label | buffer[...] | | test.rs:399:63:399:73 | &mut reader [&ref] | semmle.label | &mut reader [&ref] | +| test.rs:399:63:399:73 | [post] &mut reader [&ref] | semmle.label | [post] &mut reader [&ref] | +| test.rs:399:68:399:73 | [post] reader | semmle.label | [post] reader | | test.rs:399:68:399:73 | reader | semmle.label | reader | | test.rs:399:76:399:87 | [post] &mut buffer1 [&ref] | semmle.label | [post] &mut buffer1 [&ref] | | test.rs:399:81:399:87 | [post] buffer1 | semmle.label | [post] buffer1 | @@ -529,6 +543,8 @@ nodes | test.rs:450:22:450:33 | &... | semmle.label | &... | | test.rs:450:23:450:33 | buffer[...] | semmle.label | buffer[...] | | test.rs:457:63:457:74 | &mut reader2 [&ref] | semmle.label | &mut reader2 [&ref] | +| test.rs:457:63:457:74 | [post] &mut reader2 [&ref] | semmle.label | [post] &mut reader2 [&ref] | +| test.rs:457:68:457:74 | [post] reader2 | semmle.label | [post] reader2 | | test.rs:457:68:457:74 | reader2 | semmle.label | reader2 | | test.rs:457:77:457:88 | [post] &mut buffer1 [&ref] | semmle.label | [post] &mut buffer1 [&ref] | | test.rs:457:82:457:88 | [post] buffer1 | semmle.label | [post] buffer1 | diff --git a/rust/ql/test/query-tests/security/CWE-798/HardcodedCryptographicValue.expected b/rust/ql/test/query-tests/security/CWE-798/HardcodedCryptographicValue.expected index e4657a426ea..f0e75e6a51a 100644 --- a/rust/ql/test/query-tests/security/CWE-798/HardcodedCryptographicValue.expected +++ b/rust/ql/test/query-tests/security/CWE-798/HardcodedCryptographicValue.expected @@ -10,37 +10,45 @@ | test_cookie.rs:21:28:21:34 | [0; 64] | test_cookie.rs:21:28:21:34 | [0; 64] | test_cookie.rs:22:16:22:24 | ...::from | This hard-coded value is used as $@. | test_cookie.rs:22:16:22:24 | ...::from | a key | | test_cookie.rs:38:28:38:36 | [0u8; 64] | test_cookie.rs:38:28:38:36 | [0u8; 64] | test_cookie.rs:42:14:42:32 | ...::from | This hard-coded value is used as $@. | test_cookie.rs:42:14:42:32 | ...::from | a key | | test_cookie.rs:49:23:49:25 | 0u8 | test_cookie.rs:49:23:49:25 | 0u8 | test_cookie.rs:53:14:53:32 | ...::from | This hard-coded value is used as $@. | test_cookie.rs:53:14:53:32 | ...::from | a key | +| test_heuristic.rs:44:31:44:38 | [0u8; 16] | test_heuristic.rs:44:31:44:38 | [0u8; 16] | test_heuristic.rs:45:41:45:48 | const_iv | This hard-coded value is used as $@. | test_heuristic.rs:45:41:45:48 | const_iv | an initialization vector | +| test_heuristic.rs:63:30:63:37 | "secret" | test_heuristic.rs:63:30:63:37 | "secret" | test_heuristic.rs:63:30:63:37 | "secret" | This hard-coded value is used as $@. | test_heuristic.rs:63:30:63:37 | "secret" | a password | +| test_heuristic.rs:64:20:64:27 | [0u8; 16] | test_heuristic.rs:64:20:64:27 | [0u8; 16] | test_heuristic.rs:64:19:64:27 | &... | This hard-coded value is used as $@. | test_heuristic.rs:64:19:64:27 | &... | a nonce | +| test_heuristic.rs:65:31:65:38 | [0u8; 16] | test_heuristic.rs:65:31:65:38 | [0u8; 16] | test_heuristic.rs:65:30:65:38 | &... | This hard-coded value is used as $@. | test_heuristic.rs:65:30:65:38 | &... | a salt | +| test_heuristic.rs:67:22:67:22 | 0 | test_heuristic.rs:67:22:67:22 | 0 | test_heuristic.rs:67:22:67:22 | 0 | This hard-coded value is used as $@. | test_heuristic.rs:67:22:67:22 | 0 | a salt | +| test_heuristic.rs:69:32:69:32 | 1 | test_heuristic.rs:69:32:69:32 | 1 | test_heuristic.rs:69:22:69:32 | ... + ... | This hard-coded value is used as $@. | test_heuristic.rs:69:22:69:32 | ... + ... | a salt | +| test_heuristic.rs:70:34:70:35 | 32 | test_heuristic.rs:70:34:70:35 | 32 | test_heuristic.rs:70:22:70:62 | ... ^ ... | This hard-coded value is used as $@. | test_heuristic.rs:70:22:70:62 | ... ^ ... | a salt | +| test_heuristic.rs:70:52:70:61 | 0xFFFFFFFF | test_heuristic.rs:70:52:70:61 | 0xFFFFFFFF | test_heuristic.rs:70:22:70:62 | ... ^ ... | This hard-coded value is used as $@. | test_heuristic.rs:70:22:70:62 | ... ^ ... | a salt | edges | test_cipher.rs:18:9:18:14 | const1 [&ref] | test_cipher.rs:19:73:19:78 | const1 [&ref] | provenance | | | test_cipher.rs:18:28:18:36 | &... [&ref] | test_cipher.rs:18:9:18:14 | const1 [&ref] | provenance | | | test_cipher.rs:18:29:18:36 | [0u8; 16] | test_cipher.rs:18:28:18:36 | &... [&ref] | provenance | | | test_cipher.rs:19:49:19:79 | ...::from_slice(...) [&ref] | test_cipher.rs:19:30:19:47 | ...::new | provenance | MaD:3 Sink:MaD:3 | -| test_cipher.rs:19:73:19:78 | const1 [&ref] | test_cipher.rs:19:49:19:79 | ...::from_slice(...) [&ref] | provenance | MaD:9 | +| test_cipher.rs:19:73:19:78 | const1 [&ref] | test_cipher.rs:19:49:19:79 | ...::from_slice(...) [&ref] | provenance | MaD:10 | | test_cipher.rs:25:9:25:14 | const4 [&ref] | test_cipher.rs:26:66:26:71 | const4 [&ref] | provenance | | | test_cipher.rs:25:28:25:36 | &... [&ref] | test_cipher.rs:25:9:25:14 | const4 [&ref] | provenance | | | test_cipher.rs:25:29:25:36 | [0u8; 16] | test_cipher.rs:25:28:25:36 | &... [&ref] | provenance | | | test_cipher.rs:26:42:26:72 | ...::from_slice(...) [&ref] | test_cipher.rs:26:30:26:40 | ...::new | provenance | MaD:4 Sink:MaD:4 | -| test_cipher.rs:26:66:26:71 | const4 [&ref] | test_cipher.rs:26:42:26:72 | ...::from_slice(...) [&ref] | provenance | MaD:9 | +| test_cipher.rs:26:66:26:71 | const4 [&ref] | test_cipher.rs:26:42:26:72 | ...::from_slice(...) [&ref] | provenance | MaD:10 | | test_cipher.rs:29:9:29:14 | const5 [&ref] | test_cipher.rs:30:95:30:100 | const5 [&ref] | provenance | | | test_cipher.rs:29:28:29:36 | &... [&ref] | test_cipher.rs:29:9:29:14 | const5 [&ref] | provenance | | | test_cipher.rs:29:29:29:36 | [0u8; 16] | test_cipher.rs:29:28:29:36 | &... [&ref] | provenance | | | test_cipher.rs:30:72:30:101 | ...::from_slice(...) [&ref] | test_cipher.rs:30:30:30:40 | ...::new | provenance | MaD:5 Sink:MaD:5 | -| test_cipher.rs:30:95:30:100 | const5 [&ref] | test_cipher.rs:30:72:30:101 | ...::from_slice(...) [&ref] | provenance | MaD:9 | +| test_cipher.rs:30:95:30:100 | const5 [&ref] | test_cipher.rs:30:72:30:101 | ...::from_slice(...) [&ref] | provenance | MaD:10 | | test_cipher.rs:37:9:37:14 | const7 | test_cipher.rs:38:74:38:79 | const7 | provenance | | | test_cipher.rs:37:27:37:74 | [...] | test_cipher.rs:37:9:37:14 | const7 | provenance | | | test_cipher.rs:38:49:38:80 | ...::from_slice(...) [&ref] | test_cipher.rs:38:30:38:47 | ...::new | provenance | MaD:3 Sink:MaD:3 | -| test_cipher.rs:38:73:38:79 | &const7 [&ref] | test_cipher.rs:38:49:38:80 | ...::from_slice(...) [&ref] | provenance | MaD:9 | +| test_cipher.rs:38:73:38:79 | &const7 [&ref] | test_cipher.rs:38:49:38:80 | ...::from_slice(...) [&ref] | provenance | MaD:10 | | test_cipher.rs:38:74:38:79 | const7 | test_cipher.rs:38:73:38:79 | &const7 [&ref] | provenance | | | test_cipher.rs:41:9:41:14 | const8 [&ref] | test_cipher.rs:42:73:42:78 | const8 [&ref] | provenance | | | test_cipher.rs:41:28:41:76 | &... [&ref] | test_cipher.rs:41:9:41:14 | const8 [&ref] | provenance | | | test_cipher.rs:41:29:41:76 | [...] | test_cipher.rs:41:28:41:76 | &... [&ref] | provenance | | | test_cipher.rs:42:49:42:79 | ...::from_slice(...) [&ref] | test_cipher.rs:42:30:42:47 | ...::new | provenance | MaD:3 Sink:MaD:3 | -| test_cipher.rs:42:73:42:78 | const8 [&ref] | test_cipher.rs:42:49:42:79 | ...::from_slice(...) [&ref] | provenance | MaD:9 | +| test_cipher.rs:42:73:42:78 | const8 [&ref] | test_cipher.rs:42:49:42:79 | ...::from_slice(...) [&ref] | provenance | MaD:10 | | test_cipher.rs:50:9:50:15 | const10 [element] | test_cipher.rs:51:75:51:81 | const10 [element] | provenance | | | test_cipher.rs:50:37:50:52 | ...::zeroed | test_cipher.rs:50:37:50:54 | ...::zeroed(...) [element] | provenance | Src:MaD:7 | | test_cipher.rs:50:37:50:54 | ...::zeroed(...) [element] | test_cipher.rs:50:9:50:15 | const10 [element] | provenance | | | test_cipher.rs:51:50:51:82 | ...::from_slice(...) [&ref, element] | test_cipher.rs:51:31:51:48 | ...::new | provenance | MaD:3 Sink:MaD:3 Sink:MaD:3 | -| test_cipher.rs:51:74:51:81 | &const10 [&ref, element] | test_cipher.rs:51:50:51:82 | ...::from_slice(...) [&ref, element] | provenance | MaD:9 | +| test_cipher.rs:51:74:51:81 | &const10 [&ref, element] | test_cipher.rs:51:50:51:82 | ...::from_slice(...) [&ref, element] | provenance | MaD:10 | | test_cipher.rs:51:75:51:81 | const10 [element] | test_cipher.rs:51:74:51:81 | &const10 [&ref, element] | provenance | | | test_cipher.rs:73:9:73:14 | const2 [&ref] | test_cipher.rs:74:46:74:51 | const2 [&ref] | provenance | | | test_cipher.rs:73:18:73:26 | &... [&ref] | test_cipher.rs:73:9:73:14 | const2 [&ref] | provenance | | @@ -59,9 +67,19 @@ edges | test_cookie.rs:38:28:38:36 | [0u8; 64] | test_cookie.rs:38:18:38:37 | ...::from(...) | provenance | MaD:8 | | test_cookie.rs:42:34:42:39 | array2 | test_cookie.rs:42:14:42:32 | ...::from | provenance | MaD:2 Sink:MaD:2 | | test_cookie.rs:49:9:49:14 | array3 [element] | test_cookie.rs:53:34:53:39 | array3 [element] | provenance | | -| test_cookie.rs:49:23:49:25 | 0u8 | test_cookie.rs:49:23:49:29 | ...::from_elem(...) [element] | provenance | MaD:10 | +| test_cookie.rs:49:23:49:25 | 0u8 | test_cookie.rs:49:23:49:29 | ...::from_elem(...) [element] | provenance | MaD:11 | | test_cookie.rs:49:23:49:29 | ...::from_elem(...) [element] | test_cookie.rs:49:9:49:14 | array3 [element] | provenance | | | test_cookie.rs:53:34:53:39 | array3 [element] | test_cookie.rs:53:14:53:32 | ...::from | provenance | MaD:2 Sink:MaD:2 | +| test_heuristic.rs:44:9:44:16 | const_iv [&ref] | test_heuristic.rs:45:41:45:48 | const_iv | provenance | | +| test_heuristic.rs:44:30:44:38 | &... [&ref] | test_heuristic.rs:44:9:44:16 | const_iv [&ref] | provenance | | +| test_heuristic.rs:44:31:44:38 | [0u8; 16] | test_heuristic.rs:44:30:44:38 | &... [&ref] | provenance | | +| test_heuristic.rs:64:20:64:27 | [0u8; 16] | test_heuristic.rs:64:19:64:27 | &... | provenance | | +| test_heuristic.rs:65:31:65:38 | [0u8; 16] | test_heuristic.rs:65:30:65:38 | &... | provenance | | +| test_heuristic.rs:69:32:69:32 | 1 | test_heuristic.rs:69:22:69:32 | ... + ... | provenance | | +| test_heuristic.rs:70:23:70:35 | ... << ... | test_heuristic.rs:70:22:70:62 | ... ^ ... | provenance | | +| test_heuristic.rs:70:34:70:35 | 32 | test_heuristic.rs:70:22:70:62 | ... ^ ... | provenance | | +| test_heuristic.rs:70:34:70:35 | 32 | test_heuristic.rs:70:23:70:35 | ... << ... | provenance | MaD:9 | +| test_heuristic.rs:70:52:70:61 | 0xFFFFFFFF | test_heuristic.rs:70:22:70:62 | ... ^ ... | provenance | | models | 1 | Sink: <_ as crypto_common::KeyInit>::new_from_slice; Argument[0]; credentials-key | | 2 | Sink: ::from; Argument[0]; credentials-key | @@ -71,8 +89,9 @@ models | 6 | Sink: ::from; Argument[0].Reference; credentials-key | | 7 | Source: core::mem::zeroed; ReturnValue.Element; constant-source | | 8 | Summary: <_ as core::convert::From>::from; Argument[0]; ReturnValue; taint | -| 9 | Summary: ::from_slice; Argument[0].Reference; ReturnValue.Reference; value | -| 10 | Summary: alloc::vec::from_elem; Argument[0]; ReturnValue.Element; value | +| 9 | Summary: ::shl; Argument[0]; ReturnValue; taint | +| 10 | Summary: ::from_slice; Argument[0].Reference; ReturnValue.Reference; value | +| 11 | Summary: alloc::vec::from_elem; Argument[0]; ReturnValue.Element; value | nodes | test_cipher.rs:18:9:18:14 | const1 [&ref] | semmle.label | const1 [&ref] | | test_cipher.rs:18:28:18:36 | &... [&ref] | semmle.label | &... [&ref] | @@ -136,4 +155,20 @@ nodes | test_cookie.rs:49:23:49:29 | ...::from_elem(...) [element] | semmle.label | ...::from_elem(...) [element] | | test_cookie.rs:53:14:53:32 | ...::from | semmle.label | ...::from | | test_cookie.rs:53:34:53:39 | array3 [element] | semmle.label | array3 [element] | +| test_heuristic.rs:44:9:44:16 | const_iv [&ref] | semmle.label | const_iv [&ref] | +| test_heuristic.rs:44:30:44:38 | &... [&ref] | semmle.label | &... [&ref] | +| test_heuristic.rs:44:31:44:38 | [0u8; 16] | semmle.label | [0u8; 16] | +| test_heuristic.rs:45:41:45:48 | const_iv | semmle.label | const_iv | +| test_heuristic.rs:63:30:63:37 | "secret" | semmle.label | "secret" | +| test_heuristic.rs:64:19:64:27 | &... | semmle.label | &... | +| test_heuristic.rs:64:20:64:27 | [0u8; 16] | semmle.label | [0u8; 16] | +| test_heuristic.rs:65:30:65:38 | &... | semmle.label | &... | +| test_heuristic.rs:65:31:65:38 | [0u8; 16] | semmle.label | [0u8; 16] | +| test_heuristic.rs:67:22:67:22 | 0 | semmle.label | 0 | +| test_heuristic.rs:69:22:69:32 | ... + ... | semmle.label | ... + ... | +| test_heuristic.rs:69:32:69:32 | 1 | semmle.label | 1 | +| test_heuristic.rs:70:22:70:62 | ... ^ ... | semmle.label | ... ^ ... | +| test_heuristic.rs:70:23:70:35 | ... << ... | semmle.label | ... << ... | +| test_heuristic.rs:70:34:70:35 | 32 | semmle.label | 32 | +| test_heuristic.rs:70:52:70:61 | 0xFFFFFFFF | semmle.label | 0xFFFFFFFF | subpaths diff --git a/rust/ql/test/query-tests/security/CWE-798/test_heuristic.rs b/rust/ql/test/query-tests/security/CWE-798/test_heuristic.rs new file mode 100644 index 00000000000..f8f16a16d12 --- /dev/null +++ b/rust/ql/test/query-tests/security/CWE-798/test_heuristic.rs @@ -0,0 +1,71 @@ + +// --- tests --- + +fn encrypt_with(plaintext: &str, key: &[u8;16], iv: &[u8;16]) { + // ... +} + +fn encrypt2(plaintext: &str, crypto_key: &[u8;16], iv_bytes: &[u8;16]) { + // ... +} + +fn database_op(text: &str, primary_key: &str, pivot: &str) { + // note: this one has nothing to do with encryption, but has + // `key` and `iv` contained within the parameter names. +} + +struct MyCryptor { +} + +impl MyCryptor { + fn new(password: &str) -> MyCryptor { + MyCryptor { } + } + + fn set_nonce(&self, nonce: &[u8;16]) { + // ... + } + + fn encrypt(&self, plaintext: &str, salt: &[u8;16]) { + // ... + } + + fn set_salt_u64(&self, salt: u64) { + // ... + } +} + +fn test(var_string: &str, var_data: &[u8;16], var_u64: u64) { + encrypt_with("plaintext", var_data, var_data); + + let const_key: &[u8;16] = &[0u8;16]; // $ MISSING: Alert[rust/hard-coded-cryptographic-value] + encrypt_with("plaintext", const_key, var_data); // $ MISSING: Sink + + let const_iv: &[u8;16] = &[0u8;16]; // $ Alert[rust/hard-coded-cryptographic-value] + encrypt_with("plaintext", var_data, const_iv); // $ Sink + + encrypt2("plaintext", var_data, var_data); + + let const_key2: &[u8;16] = &[1u8;16]; // $ MISSING: Alert[rust/hard-coded-cryptographic-value] + encrypt2("plaintext", const_key2, var_data); // $ MISSING: Sink + + let const_iv: &[u8;16] = &[1u8;16]; // $ MISSING: Alert[rust/hard-coded-cryptographic-value] + encrypt2("plaintext", var_data, const_iv); // $ MISSING: Sink + + let const_key_str = "primary_key"; + let const_pivot_str = "pivot"; + database_op("text", const_key_str, const_pivot_str); + + let mc1 = MyCryptor::new(var_string); + mc1.set_nonce(var_data); + mc1.encrypt("plaintext", var_data); + + let mc2 = MyCryptor::new("secret"); // $ Alert[rust/hard-coded-cryptographic-value] + mc2.set_nonce(&[0u8;16]); // $ Alert[rust/hard-coded-cryptographic-value] + mc2.encrypt("plaintext", &[0u8;16]); // $ Alert[rust/hard-coded-cryptographic-value] + + mc2.set_salt_u64(0); // $ Alert[rust/hard-coded-cryptographic-value] + mc2.set_salt_u64(var_u64); + mc2.set_salt_u64(var_u64 + 1); // $ SPURIOUS: Alert[rust/hard-coded-cryptographic-value] + mc2.set_salt_u64((var_u64 << 32) ^ (var_u64 & 0xFFFFFFFF)); // $ SPURIOUS: Alert[rust/hard-coded-cryptographic-value] +} diff --git a/rust/ql/test/utils-tests/modelgenerator/option.rs b/rust/ql/test/utils-tests/modelgenerator/option.rs index 145b6e34592..fd5cd649c2c 100644 --- a/rust/ql/test/utils-tests/modelgenerator/option.rs +++ b/rust/ql/test/utils-tests/modelgenerator/option.rs @@ -299,8 +299,7 @@ impl MyOption { } // summary=::insert;Argument[0];Argument[self].Reference.Field[test::option::MyOption::MySome(0)];value;dfc-generated - // This summary is currently missing because of access path limit - // summary-MISSING=::insert;Argument[0];ReturnValue.Reference;value;dfc-generated + // summary=::insert;Argument[0];ReturnValue.Reference;value;dfc-generated // The content of `self` is overwritten so it does not flow to the return value. // SPURIOUS-summary=::insert;Argument[self].Reference.Field[test::option::MyOption::MySome(0)];ReturnValue.Reference;value;dfc-generated pub fn insert(&mut self, value: T) -> &mut T { @@ -311,8 +310,7 @@ impl MyOption { } // summary=::get_or_insert;Argument[0];Argument[self].Reference.Field[test::option::MyOption::MySome(0)];value;dfc-generated - // This summary is currently missing because of access path limit - // summary-MISSING=::get_or_insert;Argument[0];ReturnValue.Reference;value;dfc-generated + // summary=::get_or_insert;Argument[0];ReturnValue.Reference;value;dfc-generated // summary=::get_or_insert;Argument[self].Reference.Field[test::option::MyOption::MySome(0)];ReturnValue.Reference;value;dfc-generated pub fn get_or_insert(&mut self, value: T) -> &mut T { self.get_or_insert_with(|| value) @@ -328,7 +326,7 @@ impl MyOption { // summary=::get_or_insert_with;Argument[self].Reference.Field[test::option::MyOption::MySome(0)];ReturnValue.Reference;value;dfc-generated // summary=::get_or_insert_with;Argument[0].ReturnValue;Argument[self].Reference.Field[test::option::MyOption::MySome(0)];value;dfc-generated - // SPURIOUS-summary=::get_or_insert_with;Argument[0];Argument[self].Reference.Field[test::option::MyOption::MySome(0)];value;dfc-generated + // summary=::get_or_insert_with;Argument[0].ReturnValue;ReturnValue.Reference;value;dfc-generated pub fn get_or_insert_with(&mut self, f: F) -> &mut T where F: FnOnce() -> T, diff --git a/rust/schema/annotations.py b/rust/schema/annotations.py index 5861ede759b..96173957278 100644 --- a/rust/schema/annotations.py +++ b/rust/schema/annotations.py @@ -228,41 +228,35 @@ class _: loop_body: drop -class CallExprBase(Expr): - """ - A function or method call expression. See `CallExpr` and `MethodCallExpr` for further details. - """ - arg_list: optional["ArgList"] | child - attrs: list["Attr"] | child - args: list["Expr"] | synth - - -@annotate(CallExpr, replace_bases={Expr: CallExprBase}, cfg=True) +@annotate(CallExpr, cfg=True) class _: """ - A function call expression. For example: + NOTE: Consider using `Call` instead, as that excludes call expressions that are + instantiations of tuple structs and tuple variants. + + A call expression. For example: ```rust foo(42); foo::(42); foo[0](42); - foo(1) = 4; + Option::Some(42); // tuple variant instantiation ``` """ - arg_list: drop - attrs: drop -@annotate(MethodCallExpr, replace_bases={Expr: CallExprBase}, cfg=True) +@annotate(MethodCallExpr, cfg=True) class _: """ + NOTE: Consider using `MethodCall` instead, as that also includes calls to methods using + call syntax (such as `Foo::method(x)`), operation syntax (such as `x + y`), and + indexing syntax (such as `x[y]`). + A method call expression. For example: ```rust x.foo(42); x.foo::(42); ``` """ - arg_list: drop - attrs: drop @annotate(MatchArm) @@ -1926,7 +1920,7 @@ class _: @annotate(TupleField) class _: """ - A field in a tuple struct or tuple enum variant. + A field in a tuple struct or tuple variant. For example: ```rust @@ -1939,7 +1933,7 @@ class _: @annotate(TupleFieldList) class _: """ - A list of fields in a tuple struct or tuple enum variant. + A list of fields in a tuple struct or tuple variant. For example: ```rust diff --git a/shared/dataflow/codeql/dataflow/internal/ContentDataFlowImpl.qll b/shared/dataflow/codeql/dataflow/internal/ContentDataFlowImpl.qll index baf473efff1..0c84d33244c 100644 --- a/shared/dataflow/codeql/dataflow/internal/ContentDataFlowImpl.qll +++ b/shared/dataflow/codeql/dataflow/internal/ContentDataFlowImpl.qll @@ -75,6 +75,9 @@ module MakeImplContentDataFlow Lang> { /** Gets a limit on the number of reads out of sources and number of stores into sinks. */ default int accessPathLimit() { result = Lang::accessPathLimit() } + /** Gets the access path limit used in the internal invocation of the standard data flow library. */ + default int accessPathLimitInternal() { result = Lang::accessPathLimit() } + /** Holds if `c` is relevant for reads out of sources or stores into sinks. */ default predicate isRelevantContent(ContentSet c) { any() } } @@ -110,7 +113,7 @@ module MakeImplContentDataFlow Lang> { FlowFeature getAFeature() { result = ContentConfig::getAFeature() } - predicate accessPathLimit = ContentConfig::accessPathLimit/0; + predicate accessPathLimit = ContentConfig::accessPathLimitInternal/0; // needed to record reads/stores inside summarized callables predicate includeHiddenNodes() { any() } @@ -274,6 +277,16 @@ module MakeImplContentDataFlow Lang> { ) } + /** + * Gets the length of this access path. + */ + int length() { + this = TAccessPathNil() and + result = 0 + or + result = this.getTail().length() + 1 + } + /** * Gets the content set at index `i` in this access path, if any. */ diff --git a/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll b/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll index ddcd052e8fd..aa74e44a8e8 100644 --- a/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll +++ b/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll @@ -207,6 +207,28 @@ module MakeImpl Lang> { flowLocal(source, sink) and Config::observeOverlayInformedIncrementalMode() } + /** + * Holds if data can flow from `source` to some sink. + * This is a local predicate that only has results local to the overlay/base database. + */ + predicate flowFromLocal(Node source) = forceLocal(Flow::flowFrom/1)(source) + + /** + * Holds if data can flow from `source` to some sink. + */ + predicate flowFrom(Node source) { + Flow::flowFrom(source) + or + // If we are overlay informed (i.e. we are not diff-informed), we + // merge in the local results which includes the base database results. + flowFromLocal(source) and Config::observeOverlayInformedIncrementalMode() + } + + /** + * Holds if data can flow from `source` to some sink. + */ + predicate flowFromExpr(Lang::DataFlowExpr source) { flowFrom(exprNode(source)) } + /** * Holds if data can flow from some source to `sink`. * This is a local predicate that only has results local to the overlay/base database. @@ -3501,6 +3523,16 @@ module MakeImpl Lang> { ) } + /** + * Holds if data can flow from `source` to some sink. + */ + predicate flowFrom(Node source) { exists(PathNode n | n.isSource() and n.getNode() = source) } + + /** + * Holds if data can flow from `source` to some sink. + */ + predicate flowFromExpr(Expr source) { flowFrom(exprNode(source)) } + /** * Holds if data can flow from some source to `sink`. */ diff --git a/shared/mad/codeql/mad/modelgenerator/internal/ModelGeneratorImpl.qll b/shared/mad/codeql/mad/modelgenerator/internal/ModelGeneratorImpl.qll index 51dafc2cc96..8abe4563580 100644 --- a/shared/mad/codeql/mad/modelgenerator/internal/ModelGeneratorImpl.qll +++ b/shared/mad/codeql/mad/modelgenerator/internal/ModelGeneratorImpl.qll @@ -277,6 +277,16 @@ module MakeModelGeneratorFactory< */ predicate isAdditionalContentFlowStep(Lang::Node nodeFrom, Lang::Node nodeTo); + /** + * Gets the access path limit for content flow analysis. + */ + default int contentAccessPathLimit() { result = 2 } + + /** + * Gets the internal access path limit for content flow analysis. + */ + default int contentAccessPathLimitInternal() { result = Lang::accessPathLimit() } + /** * Holds if the content set `c` is field like. */ @@ -650,7 +660,10 @@ module MakeModelGeneratorFactory< exists(Type t | t = n.(NodeExtended).getType() and not isRelevantType(t)) } - int accessPathLimit() { result = 2 } + predicate accessPathLimit = SummaryModelGeneratorInput::contentAccessPathLimit/0; + + predicate accessPathLimitInternal = + SummaryModelGeneratorInput::contentAccessPathLimitInternal/0; predicate isRelevantContent(DataFlow::ContentSet s) { isRelevantContent0(s) } @@ -703,14 +716,17 @@ module MakeModelGeneratorFactory< } /** - * Holds if the access path `ap` is not a parameter or returnvalue of a callback - * stored in a field. + * Holds if `ap` is valid for generating summary models. * - * That is, we currently don't include summaries that rely on parameters or return values - * of callbacks stored in fields. + * We currently don't include summaries that rely on parameters or return values + * of callbacks stored in fields, as those are not supported by the data flow + * library. + * + * We also exclude access paths with contents not supported by `printContent`. */ private predicate validateAccessPath(PropagateContentFlow::AccessPath ap) { - not (mentionsField(ap) and mentionsCallback(ap)) + not (mentionsField(ap) and mentionsCallback(ap)) and + forall(int i | i in [0 .. ap.length() - 1] | exists(getContent(ap, i))) } private predicate apiFlow( @@ -720,7 +736,9 @@ module MakeModelGeneratorFactory< ) { PropagateContentFlow::flow(p, reads, returnNodeExt, stores, preservesValue) and getEnclosingCallable(returnNodeExt) = api and - getEnclosingCallable(p) = api + getEnclosingCallable(p) = api and + validateAccessPath(reads) and + validateAccessPath(stores) } /** @@ -763,9 +781,7 @@ module MakeModelGeneratorFactory< PropagateContentFlow::AccessPath reads, ReturnNodeExt returnNodeExt, PropagateContentFlow::AccessPath stores, boolean preservesValue ) { - PropagateContentFlow::flow(p, reads, returnNodeExt, stores, preservesValue) and - getEnclosingCallable(returnNodeExt) = api and - getEnclosingCallable(p) = api and + apiFlow(api, p, reads, returnNodeExt, stores, preservesValue) and p = api.getARelevantParameterNode() } @@ -956,8 +972,6 @@ module MakeModelGeneratorFactory< input = parameterNodeAsExactInput(p) + printReadAccessPath(reads) and output = getExactOutput(returnNodeExt) + printStoreAccessPath(stores) and input != output and - validateAccessPath(reads) and - validateAccessPath(stores) and ( if mentionsField(reads) or mentionsField(stores) then lift = false and api.isRelevant() diff --git a/swift/ql/lib/codeql/swift/security/CleartextTransmissionExtensions.qll b/swift/ql/lib/codeql/swift/security/CleartextTransmissionExtensions.qll index 4b31a7ab23f..03d8dff3148 100644 --- a/swift/ql/lib/codeql/swift/security/CleartextTransmissionExtensions.qll +++ b/swift/ql/lib/codeql/swift/security/CleartextTransmissionExtensions.qll @@ -87,7 +87,7 @@ private class UrlTransmittedSink extends CleartextTransmissionSink { // exclude `tel:` and similar URLs. These URLs necessarily contain // sensitive data which you expect to transmit only by making the // phone call (or similar operation). - not ExcludeUrlFlow::flow(_, this) + not ExcludeUrlFlow::flowTo(this) } }