Merge remote-tracking branch 'upstream/main' into lifetimetest

This commit is contained in:
Geoffrey White
2025-12-04 17:33:39 +00:00
160 changed files with 16800 additions and 1647 deletions

View File

@@ -1 +1 @@
8.1.1
8.4.2

View File

@@ -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) }

View File

@@ -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) }

View File

@@ -263,7 +263,7 @@ module FromSensitiveFlow = TaintTracking::Global<FromSensitiveConfig>;
* A taint flow configuration for flow from a sensitive expression to an encryption operation.
*/
module ToEncryptionConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) { FromSensitiveFlow::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

View File

@@ -129,7 +129,7 @@ module PointerArithmeticToDerefFlow = DataFlow::Global<PointerArithmeticToDerefC
predicate pointerArithOverflow(PointerArithmeticInstruction pai, int delta) {
pointerArithOverflow0(pai, delta) and
PointerArithmeticToDerefFlow::flow(DataFlow::instructionNode(pai), _)
PointerArithmeticToDerefFlow::flowFrom(DataFlow::instructionNode(pai))
}
bindingset[v]

View File

@@ -48,7 +48,7 @@ namespace Semmle.Autobuild.CSharp
{
// When a custom .NET CLI has been installed, `dotnet --info` has already been executed
// to verify the installation.
var ret = dotNetPath is null ? GetInfoCommand(builder.Actions, dotNetPath, environment) : BuildScript.Success;
var ret = dotNetPath is null ? DotNet.InfoScript(builder.Actions, DotNetCommand(builder.Actions, dotNetPath), environment, builder.Logger) : BuildScript.Success;
foreach (var projectOrSolution in builder.ProjectsOrSolutionsToBuild)
{
var cleanCommand = GetCleanCommand(builder.Actions, dotNetPath, environment);
@@ -111,14 +111,6 @@ namespace Semmle.Autobuild.CSharp
private static string DotNetCommand(IBuildActions actions, string? dotNetPath) =>
dotNetPath is not null ? actions.PathCombine(dotNetPath, "dotnet") : "dotnet";
private static BuildScript GetInfoCommand(IBuildActions actions, string? dotNetPath, IDictionary<string, string>? 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<string, string>? environment)
{
var clean = new CommandBuilder(actions, null, environment).

View File

@@ -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;
}
/// <summary>
/// Returns a script for running `dotnet --info`, with retries on exit code 143.
/// </summary>
public static BuildScript InfoScript(IBuildActions actions, string dotnet, IDictionary<string, string>? 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;
}
/// <summary>
/// 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<string, BuildScript> getInstallAndVerify = version =>
// run `dotnet --info` after install, to check that it executes successfully

View File

@@ -57,15 +57,21 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
return startInfo;
}
private bool RunCommandAux(string args, string? workingDirectory, out IList<string> output, bool silent)
private int RunCommandExitCodeAux(string args, string? workingDirectory, out IList<string> 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<string> 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<string> output, bool silent = true) =>
RunCommandAux(args, null, out output, silent);

View File

@@ -30,6 +30,12 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
/// </summary>
bool RunCommand(string args, bool silent = true);
/// <summary>
/// Execute `dotnet <paramref name="args"/>` and return the exit code.
/// If `silent` is true the output of the command is logged as `debug` otherwise as `info`.
/// </summary>
int RunCommandExitCode(string args, bool silent = true);
/// <summary>
/// Execute `dotnet <paramref name="args"/>` and return true if the command succeeded, otherwise false.
/// The output of the command is returned in `output`.

View File

@@ -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<string> 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<string> output, bool silent)
{
lastArgs = args;
@@ -83,7 +90,7 @@ namespace Semmle.Extraction.Tests
public void TestDotnetInfoFailure()
{
// Setup
var dotnetCliInvoker = new DotNetCliInvokerStub(new List<string>()) { Success = false };
var dotnetCliInvoker = new DotNetCliInvokerStub(new List<string>()) { 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");

View File

@@ -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")

View File

@@ -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.

View File

@@ -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") }

View File

@@ -85,7 +85,7 @@ module RemoteSourceToExternalApi = TaintTracking::Global<RemoteSourceToExternalA
/** A node representing untrusted data being passed to an external API. */
class UntrustedExternalApiDataNode extends ExternalApiDataNode {
UntrustedExternalApiDataNode() { RemoteSourceToExternalApi::flow(_, this) }
UntrustedExternalApiDataNode() { RemoteSourceToExternalApi::flowTo(this) }
/** Gets a source of untrusted data which is passed to this external API data node. */
DataFlow::Node getAnUntrustedSource() { RemoteSourceToExternalApi::flow(result, this) }

View File

@@ -91,7 +91,7 @@ class ExponentialRegexSink extends DataFlow::ExprNode, Sink {
ExponentialRegexSink() {
exists(RegexOperation regexOperation |
// Exponential regex flows to the pattern argument
ExponentialRegexDataFlow::flow(_, DataFlow::exprNode(regexOperation.getPattern()))
ExponentialRegexDataFlow::flowToExpr(regexOperation.getPattern())
|
// This is used as an input for this pattern
this.getExpr() = regexOperation.getInput() and

View File

@@ -53,7 +53,7 @@ where
// JsonConvert static method call, but with additional unsafe typename tracking
exists(DataFlow::Node settingsCallArg |
JsonConvertTracking::flowPath(userInput.asPathNode3(), deserializeCallArg.asPathNode3()) and
TypeNameTracking::flow(_, settingsCallArg) and
TypeNameTracking::flowTo(settingsCallArg) and
sameParent(deserializeCallArg.getNode(), settingsCallArg)
)
select deserializeCallArg, userInput, deserializeCallArg, "$@ flows to unsafe deserializer.",

View File

@@ -46,10 +46,7 @@ predicate insecureCookieOptionsCreation(ObjectCreation oc) {
// `Secure` property in `CookieOptions` passed to IResponseCookies.Append(...) wasn't set
oc.getType() instanceof MicrosoftAspNetCoreHttpCookieOptions and
secureFalseOrNotSet(oc) and
exists(DataFlow::Node creation |
CookieOptionsTracking::flow(creation, _) and
creation.asExpr() = oc
)
CookieOptionsTracking::flowFromExpr(oc)
}
predicate insecureCookieAppend(Expr sink) {

View File

@@ -260,6 +260,8 @@ module SummaryModelGeneratorInput implements SummaryModelGeneratorInputSig {
)
}
int contentAccessPathLimitInternal() { result = 2 }
bindingset[d]
private string getFullyQualifiedName(Declaration d) {
exists(string qualifier, string name |

View File

@@ -183,7 +183,7 @@ function RegisterExtractorPack(id)
MsBuildMatcher,
CreatePatternMatcher({ '^csc.*%.exe$' }, MatchCompilerName, extractor, {
prepend = { '--compiler', '"${compiler}"' },
order = ORDER_BEFORE
order = ORDER_AFTER
}),
CreatePatternMatcher({ '^fakes.*%.exe$', 'moles.*%.exe' },
MatchCompilerName, nil, { trace = false }),
@@ -224,7 +224,7 @@ function RegisterExtractorPack(id)
CreatePatternMatcher({ '^mcs%.exe$', '^csc%.exe$', '^csc$' }, MatchCompilerName,
extractor, {
prepend = { '--compiler', '${compiler}' },
order = ORDER_BEFORE
order = ORDER_AFTER
}),
MsBuildMatcher,
function(compilerName, compilerPath, compilerArguments, _languageId)

View File

@@ -27,7 +27,7 @@ module AllocationSizeOverflow {
private module FindLargeLensFlow = TaintTracking::Global<FindLargeLensConfig>;
private DataFlow::CallNode getALargeLenCall() {
exists(DataFlow::Node lenArg | FindLargeLensFlow::flow(_, lenArg) |
exists(DataFlow::Node lenArg | FindLargeLensFlow::flowTo(lenArg) |
result.getArgument(0) = lenArg
)
}

View File

@@ -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) }

View File

@@ -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 }

View File

@@ -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 {

View File

@@ -81,5 +81,5 @@ module Config implements DataFlow::ConfigSig {
module Flow = DataFlow::Global<Config>;
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

View File

@@ -154,7 +154,7 @@ module FlowToPrintFlow = DataFlow::Global<FlowToPrintConfig>;
/** 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`. */

View File

@@ -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://<path>` to `https://<path>`
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"

View File

@@ -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"

View File

@@ -70,5 +70,6 @@ module PamStartToAuthenticateFlow = TaintTracking::Global<PamStartToAuthenticate
from DataFlow::Node source, DataFlow::Node sink
where
not isInTestFile(source.asExpr()) and
(PamStartToAuthenticateFlow::flow(source, sink) and not PamStartToAcctMgmtFlow::flow(source, _))
PamStartToAuthenticateFlow::flow(source, sink) and
not PamStartToAcctMgmtFlow::flowFrom(source)
select source, "This Pam transaction may not be secure."

View File

@@ -24,7 +24,7 @@ module JwtParseWithConstantKeyConfig implements DataFlow::ConfigSig {
or
n = fd.(FuncDecl).getFunction().getARead()
|
GolangJwtKeyFunc::flow(n, _) and
GolangJwtKeyFunc::flowFrom(n) and
sink = rn and
rn.getRoot() = fd and
rn.getIndex() = 0

View File

@@ -0,0 +1,4 @@
---
category: minorAnalysis
---
* A sanitizer has been added to `java/ssrf` to remove alerts when a regular expression check is used to verify that the value is safe.

View File

@@ -4,11 +4,46 @@ module;
import java
/** The class `java.util.regex.Matcher`. */
class TypeRegexMatcher extends Class {
TypeRegexMatcher() { this.hasQualifiedName("java.util.regex", "Matcher") }
}
/**
* The `matches` method of `java.util.regex.Matcher`.
*/
class MatcherMatchesMethod extends Method {
MatcherMatchesMethod() {
this.getDeclaringType() instanceof TypeRegexMatcher and
this.hasName("matches")
}
}
/** The class `java.util.regex.Pattern`. */
class TypeRegexPattern extends Class {
TypeRegexPattern() { this.hasQualifiedName("java.util.regex", "Pattern") }
}
/**
* The `matches` method of `java.util.regex.Pattern`.
*/
class PatternMatchesMethod extends Method {
PatternMatchesMethod() {
this.getDeclaringType() instanceof TypeRegexPattern and
this.hasName("matches")
}
}
/**
* The `matcher` method of `java.util.regex.Pattern`.
*/
class PatternMatcherMethod extends Method {
PatternMatcherMethod() {
this.getDeclaringType() instanceof TypeRegexPattern and
this.hasName("matcher")
}
}
/** The `quote` method of the `java.util.regex.Pattern` class. */
class PatternQuoteMethod extends Method {
PatternQuoteMethod() {

View File

@@ -26,9 +26,7 @@ private module TypeLiteralToParseAsFlowConfig implements DataFlow::ConfigSig {
private module TypeLiteralToParseAsFlow = DataFlow::Global<TypeLiteralToParseAsFlowConfig>;
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 {

View File

@@ -110,7 +110,7 @@ private module TypeLiteralToJacksonDatabindFlow =
DataFlow::Global<TypeLiteralToJacksonDatabindFlowConfig>;
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. */

View File

@@ -164,7 +164,7 @@ private module RegexFlowConfig implements DataFlow::ConfigSig {
private module RegexFlow = DataFlow::Global<RegexFlowConfig>;
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)
}

View File

@@ -51,7 +51,7 @@ private module VerifiedIntentFlow = DataFlow::Global<VerifiedIntentConfig>;
/** An `onReceive` method that doesn't verify the action of the intent it receives. */
private class UnverifiedOnReceiveMethod extends OnReceiveMethod {
UnverifiedOnReceiveMethod() {
not VerifiedIntentFlow::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
}

View File

@@ -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<isMatchesSanitizer/3>::getABarrierNode() }
}
private class RegexpCheckRequestForgerySanitizer extends RequestForgerySanitizer instanceof RegexpCheckBarrier
{ }

View File

@@ -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<regexpMatchGuardChecks/3>::getABarrierNode()
}
}

View File

@@ -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."

View File

@@ -85,7 +85,7 @@ private module JxBrowserFlow = DataFlow::Global<JxBrowserFlowConfig>;
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."
}

View File

@@ -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

View File

@@ -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) }

View File

@@ -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

View File

@@ -25,9 +25,7 @@ module Config implements DataFlow::ConfigSig {
module Flow = DataFlow::Global<Config>;
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) }

View File

@@ -25,9 +25,7 @@ module Config implements DataFlow::ConfigSig {
module Flow = DataFlow::Global<Config>;
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) }

View File

@@ -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()
)

View File

@@ -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()
)

View File

@@ -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 |

View File

@@ -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
}

View File

@@ -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()
)
}

View File

@@ -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"

View File

@@ -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) }
}

View File

@@ -14,7 +14,7 @@ predicate passwordVarAssign(Variable v, DataFlow::Node nd) {
module PasswordFlow = DataFlow::Global<PasswordConfig>;
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."
)
}

View File

@@ -0,0 +1,4 @@
---
category: minorAnalysis
---
* Added taint flow model and type model for `urllib.parseurl`.

View File

@@ -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

View File

@@ -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
// ---------------------------------------------------------------------------

View File

@@ -50,7 +50,7 @@ module FullServerSideRequestForgeryFlow = TaintTracking::Global<FullServerSideRe
*/
predicate fullyControlledRequest(Http::Client::Request request) {
forall(DataFlow::Node urlPart | urlPart = request.getAUrlPart() |
FullServerSideRequestForgeryFlow::flow(_, urlPart)
FullServerSideRequestForgeryFlow::flowTo(urlPart)
)
}

View File

@@ -182,7 +182,7 @@ module UntrustedDataToExternalApiFlow = TaintTracking::Global<UntrustedDataToExt
/** 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) }

View File

@@ -38,5 +38,5 @@ module RemoteFlowSourceReachConfig implements DataFlow::ConfigSig {
module RemoteFlowSourceReachFlow = TaintTracking::Global<RemoteFlowSourceReachConfig>;
from DataFlow::Node reachable
where RemoteFlowSourceReachFlow::flow(_, reachable)
where RemoteFlowSourceReachFlow::flowTo(reachable)
select reachable, prettyNode(reachable)

View File

@@ -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 |

View File

@@ -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 |

View File

@@ -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()

View File

@@ -28,5 +28,5 @@ private module BasicTaintConfig implements DataFlow::ConfigSig {
private module BasicTaintFlow = TaintTracking::Global<BasicTaintConfig>;
from DataFlow::Node node
where BasicTaintFlow::flow(_, node)
where BasicTaintFlow::flowTo(node)
select node, "Tainted node"

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -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

View File

@@ -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)
}

View File

@@ -1,2 +1,2 @@
mod.rs 4bcb9def847469aae9d8649461546b7c21ec97cf6e63d3cf394e339915ce65d7 4bcb9def847469aae9d8649461546b7c21ec97cf6e63d3cf394e339915ce65d7
top.rs 460e827738766301a137f1750be7cd3016e6b7e4e487c6c95972bd3e1d21b814 460e827738766301a137f1750be7cd3016e6b7e4e487c6c95972bd3e1d21b814
top.rs b829c8ab9ec5ff07b997b9ee0b2c333d63e24eddcf7c5fc2b95a9a7f17a84a69 b829c8ab9ec5ff07b997b9ee0b2c333d63e24eddcf7c5fc2b95a9a7f17a84a69

View File

@@ -4315,44 +4315,66 @@ impl From<trap::Label<BreakExpr>> for trap::Label<Element> {
}
#[derive(Debug)]
pub struct CallExprBase {
_unused: ()
pub struct CallExpr {
pub id: trap::TrapId<CallExpr>,
pub arg_list: Option<trap::Label<ArgList>>,
pub attrs: Vec<trap::Label<Attr>>,
pub function: Option<trap::Label<Expr>>,
}
impl trap::TrapClass for CallExprBase {
fn class_name() -> &'static str { "CallExprBase" }
impl trap::TrapEntry for CallExpr {
fn extract_id(&mut self) -> trap::TrapId<Self> {
std::mem::replace(&mut self.id, trap::TrapId::Star)
}
fn emit(self, id: trap::Label<Self>, 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<trap::Label<CallExprBase>> for trap::Label<Expr> {
fn from(value: trap::Label<CallExprBase>) -> 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<trap::Label<CallExpr>> for trap::Label<Expr> {
fn from(value: trap::Label<CallExpr>) -> Self {
// SAFETY: this is safe because in the dbscheme CallExpr is a subclass of Expr
unsafe {
Self::from_untyped(value.as_untyped())
}
}
}
impl From<trap::Label<CallExprBase>> for trap::Label<AstNode> {
fn from(value: trap::Label<CallExprBase>) -> Self {
// SAFETY: this is safe because in the dbscheme CallExprBase is a subclass of AstNode
impl From<trap::Label<CallExpr>> for trap::Label<AstNode> {
fn from(value: trap::Label<CallExpr>) -> Self {
// SAFETY: this is safe because in the dbscheme CallExpr is a subclass of AstNode
unsafe {
Self::from_untyped(value.as_untyped())
}
}
}
impl From<trap::Label<CallExprBase>> for trap::Label<Locatable> {
fn from(value: trap::Label<CallExprBase>) -> Self {
// SAFETY: this is safe because in the dbscheme CallExprBase is a subclass of Locatable
impl From<trap::Label<CallExpr>> for trap::Label<Locatable> {
fn from(value: trap::Label<CallExpr>) -> Self {
// SAFETY: this is safe because in the dbscheme CallExpr is a subclass of Locatable
unsafe {
Self::from_untyped(value.as_untyped())
}
}
}
impl From<trap::Label<CallExprBase>> for trap::Label<Element> {
fn from(value: trap::Label<CallExprBase>) -> Self {
// SAFETY: this is safe because in the dbscheme CallExprBase is a subclass of Element
impl From<trap::Label<CallExpr>> for trap::Label<Element> {
fn from(value: trap::Label<CallExpr>) -> 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<trap::Label<MatchExpr>> for trap::Label<Element> {
}
}
#[derive(Debug)]
pub struct MethodCallExpr {
pub id: trap::TrapId<MethodCallExpr>,
pub arg_list: Option<trap::Label<ArgList>>,
pub attrs: Vec<trap::Label<Attr>>,
pub generic_arg_list: Option<trap::Label<GenericArgList>>,
pub identifier: Option<trap::Label<NameRef>>,
pub receiver: Option<trap::Label<Expr>>,
}
impl trap::TrapEntry for MethodCallExpr {
fn extract_id(&mut self) -> trap::TrapId<Self> {
std::mem::replace(&mut self.id, trap::TrapId::Star)
}
fn emit(self, id: trap::Label<Self>, 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<trap::Label<MethodCallExpr>> for trap::Label<Expr> {
fn from(value: trap::Label<MethodCallExpr>) -> Self {
// SAFETY: this is safe because in the dbscheme MethodCallExpr is a subclass of Expr
unsafe {
Self::from_untyped(value.as_untyped())
}
}
}
impl From<trap::Label<MethodCallExpr>> for trap::Label<AstNode> {
fn from(value: trap::Label<MethodCallExpr>) -> Self {
// SAFETY: this is safe because in the dbscheme MethodCallExpr is a subclass of AstNode
unsafe {
Self::from_untyped(value.as_untyped())
}
}
}
impl From<trap::Label<MethodCallExpr>> for trap::Label<Locatable> {
fn from(value: trap::Label<MethodCallExpr>) -> Self {
// SAFETY: this is safe because in the dbscheme MethodCallExpr is a subclass of Locatable
unsafe {
Self::from_untyped(value.as_untyped())
}
}
}
impl From<trap::Label<MethodCallExpr>> for trap::Label<Element> {
fn from(value: trap::Label<MethodCallExpr>) -> 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<NameRef>,
@@ -9242,82 +9339,6 @@ impl From<trap::Label<BlockExpr>> for trap::Label<Element> {
}
}
#[derive(Debug)]
pub struct CallExpr {
pub id: trap::TrapId<CallExpr>,
pub arg_list: Option<trap::Label<ArgList>>,
pub attrs: Vec<trap::Label<Attr>>,
pub function: Option<trap::Label<Expr>>,
}
impl trap::TrapEntry for CallExpr {
fn extract_id(&mut self) -> trap::TrapId<Self> {
std::mem::replace(&mut self.id, trap::TrapId::Star)
}
fn emit(self, id: trap::Label<Self>, 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<trap::Label<CallExpr>> for trap::Label<CallExprBase> {
fn from(value: trap::Label<CallExpr>) -> Self {
// SAFETY: this is safe because in the dbscheme CallExpr is a subclass of CallExprBase
unsafe {
Self::from_untyped(value.as_untyped())
}
}
}
impl From<trap::Label<CallExpr>> for trap::Label<Expr> {
fn from(value: trap::Label<CallExpr>) -> Self {
// SAFETY: this is safe because in the dbscheme CallExpr is a subclass of Expr
unsafe {
Self::from_untyped(value.as_untyped())
}
}
}
impl From<trap::Label<CallExpr>> for trap::Label<AstNode> {
fn from(value: trap::Label<CallExpr>) -> Self {
// SAFETY: this is safe because in the dbscheme CallExpr is a subclass of AstNode
unsafe {
Self::from_untyped(value.as_untyped())
}
}
}
impl From<trap::Label<CallExpr>> for trap::Label<Locatable> {
fn from(value: trap::Label<CallExpr>) -> Self {
// SAFETY: this is safe because in the dbscheme CallExpr is a subclass of Locatable
unsafe {
Self::from_untyped(value.as_untyped())
}
}
}
impl From<trap::Label<CallExpr>> for trap::Label<Element> {
fn from(value: trap::Label<CallExpr>) -> 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<ExternBlock>,
@@ -9908,90 +9929,6 @@ impl From<trap::Label<MacroRules>> for trap::Label<Addressable> {
}
}
#[derive(Debug)]
pub struct MethodCallExpr {
pub id: trap::TrapId<MethodCallExpr>,
pub arg_list: Option<trap::Label<ArgList>>,
pub attrs: Vec<trap::Label<Attr>>,
pub generic_arg_list: Option<trap::Label<GenericArgList>>,
pub identifier: Option<trap::Label<NameRef>>,
pub receiver: Option<trap::Label<Expr>>,
}
impl trap::TrapEntry for MethodCallExpr {
fn extract_id(&mut self) -> trap::TrapId<Self> {
std::mem::replace(&mut self.id, trap::TrapId::Star)
}
fn emit(self, id: trap::Label<Self>, 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<trap::Label<MethodCallExpr>> for trap::Label<CallExprBase> {
fn from(value: trap::Label<MethodCallExpr>) -> Self {
// SAFETY: this is safe because in the dbscheme MethodCallExpr is a subclass of CallExprBase
unsafe {
Self::from_untyped(value.as_untyped())
}
}
}
impl From<trap::Label<MethodCallExpr>> for trap::Label<Expr> {
fn from(value: trap::Label<MethodCallExpr>) -> Self {
// SAFETY: this is safe because in the dbscheme MethodCallExpr is a subclass of Expr
unsafe {
Self::from_untyped(value.as_untyped())
}
}
}
impl From<trap::Label<MethodCallExpr>> for trap::Label<AstNode> {
fn from(value: trap::Label<MethodCallExpr>) -> Self {
// SAFETY: this is safe because in the dbscheme MethodCallExpr is a subclass of AstNode
unsafe {
Self::from_untyped(value.as_untyped())
}
}
}
impl From<trap::Label<MethodCallExpr>> for trap::Label<Locatable> {
fn from(value: trap::Label<MethodCallExpr>) -> Self {
// SAFETY: this is safe because in the dbscheme MethodCallExpr is a subclass of Locatable
unsafe {
Self::from_untyped(value.as_untyped())
}
}
}
impl From<trap::Label<MethodCallExpr>> for trap::Label<Element> {
fn from(value: trap::Label<MethodCallExpr>) -> 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<Module>,

View File

@@ -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

2
rust/ql/.gitattributes generated vendored
View File

@@ -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

View File

@@ -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()
)
}
}

View File

@@ -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()
)
}
}

View File

@@ -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::<u32, u64>(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::<u32, u64>(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:

View File

@@ -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 {

View File

@@ -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() }
}

View File

@@ -654,15 +654,18 @@ module MakeCfgNodes<LocationSig Loc, InputSig<Loc> 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::<u32, u64>(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<LocationSig Loc, InputSig<Loc> 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<LocationSig Loc, InputSig<Loc> 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<LocationSig Loc, InputSig<Loc> 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::<u32, u64>(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<LocationSig Loc, InputSig<Loc> 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.
*/

View File

@@ -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()

View File

@@ -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<Location> {
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<Location> {
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<Location> {
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<Location> {
*/
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

View File

@@ -12,18 +12,17 @@ private import codeql.rust.dataflow.Ssa
private import Content
module Input implements InputSig<Location, RustDataFlow> {
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<Location, RustDataFlow> {
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<Location, RustDataFlow> {
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<Location, RustDataFlow> {
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

View File

@@ -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

View File

@@ -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()
}
}

View File

@@ -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

View File

@@ -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

View File

@@ -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;

View File

@@ -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::<u32, u64>(42);
* foo[0](42);
* foo(1) = 4;
* Option::Some(42); // tuple variant instantiation
* ```
*/
final class CallExpr = Impl::CallExpr;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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() }
}

View File

@@ -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);

View File

@@ -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

View File

@@ -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

View File

@@ -0,0 +1,7 @@
/**
* This module provides the public class `TupleStructExpr`.
*/
private import internal.CallExprImpl
final class TupleStructExpr = Impl::TupleStructExpr;

View File

@@ -0,0 +1,7 @@
/**
* This module provides the public class `TupleVariantExpr`.
*/
private import internal.CallExprImpl
final class TupleVariantExpr = Impl::TupleVariantExpr;

View File

@@ -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) }
}
}

View File

@@ -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::<u32, u64>(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::<u32, u64>(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" }
}
}

View File

@@ -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() }
}
}

View File

@@ -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() }
}
}

View File

@@ -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) }
}
}

View File

@@ -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::<u32, u64>(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() }
}
}

View File

@@ -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) }
}
}

Some files were not shown because too many files have changed in this diff Show More