Compare commits

..

75 Commits

Author SHA1 Message Date
Jeroen Ketema
f6b3d1eade Kotlin: Remove unneeded pytest imports 2026-06-24 23:34:39 +02:00
Jeroen Ketema
402c0f89bc Kotlin: Update tests to use new kotlin_2_3_20 fixture 2026-06-24 22:50:32 +02:00
Jeroen Ketema
cd23341dab Merge branch 'main' into andersfugmann/kotlin-2.4-v2 2026-06-23 11:45:17 +02:00
Idriss Riouak
ec91865a7f Merge pull request #22030 from github/idrissrio/cpp/update-stats-file
C/C++: Update stats file
2026-06-23 10:26:52 +02:00
Owen Mansel-Chan
f0576046b1 Merge pull request #22027 from owen-mc/go/improve-tests
Go: Improve two tests
2026-06-22 17:19:40 +01:00
yoff
32f7c541ae Merge pull request #21919 from github/yoff/python-remove-getAFlowNode
Python: deprecate AstNode.getAFlowNode() and rewrite callers
2026-06-22 15:35:52 +02:00
yoff
1a9bb2416a Python: deprecate Function.getAReturnValueFlowNode() and rewrite internal callers
Follow-up to the getAFlowNode deprecation in the same PR: same AST→legacy-CFG
bridge pattern. The 11 internal call sites (across objects/, types/,
frameworks/, and TypeTrackingImpl) are rewritten to bind a `Return ret`
explicitly, then constrain via `ret.getScope() = f and n.getNode() = ret.getValue()`.

The predicate itself is preserved with a deprecation note so external
users do not experience churn.

Semantic noop.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-06-22 14:55:19 +02:00
Copilot
717ff62d70 Python: deprecate AstNode.getAFlowNode() and rewrite internal callers
Preparatory refactor for the shared-CFG dataflow migration.

Deprecates the AstNode.getAFlowNode() cached predicate on the public
Python QL API and rewrites all ~140 internal callers across lib/, src/,
test/, and tools/ from `expr.getAFlowNode() = cfgNode` to
`cfgNode.getNode() = expr`, using ControlFlowNode.getNode() which
already exists in Flow.qll.

The predicate itself is preserved (with a deprecation note pointing at
the new pattern) so external users do not experience churn — they can
migrate at their own pace and the AST/CFG hierarchies still get the
intended untangling once the deprecation eventually elapses.

Semantic noop verified by:
- All 361 lib/ + src/ queries compile clean.
- All 122 ControlFlow + PointsTo library-tests pass.
- All 64 dataflow library-tests pass.
- All 113 Variables/Exceptions/Expressions/Statements/Functions/Imports/
  Security/CWE-798/ModificationOfParameterWithDefault query-tests pass.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-06-22 14:55:19 +02:00
yoff
8179bffe64 Merge pull request #21930 from github/yoff/python-dataflow-noop-simplifications
Python: inline init_module_submodule_defn into ImportResolution
2026-06-22 14:50:39 +02:00
Anders Schack-Mulligen
7197cc56dd Merge pull request #22014 from github/copilot/update-rescue-clause-exception-handling
Ruby AST: preserve ExceptionList node in RescueClause for 2+ exceptions
2026-06-22 13:28:29 +02:00
Anders Schack-Mulligen
48b0cbcf01 Merge pull request #22031 from github/copilot/tweak-csharp-extractor
Extract `TypeMention` for `catch (Exception)` clauses
2026-06-22 13:27:47 +02:00
Anders Schack-Mulligen
ac7ed0612d C#: Accept test change. 2026-06-22 13:00:55 +02:00
Jeroen Ketema
03187ae8be Merge pull request #22013 from jketema/swift/more-arguments
Swift: Strip out more unknown clang arguments
2026-06-22 12:35:36 +02:00
copilot-swe-agent[bot]
bd84fb31e1 Add regression for catch type mention extraction 2026-06-22 09:41:55 +00:00
copilot-swe-agent[bot]
4c9fa4dddc Emit catch type mentions without variables 2026-06-22 09:37:24 +00:00
Anders Schack-Mulligen
7d66ec0f39 Ruby: Clarify AST. 2026-06-22 11:14:53 +02:00
idrissrio
0a41157d77 C/C++: update stats file 2026-06-22 10:27:21 +02:00
Idriss Riouak
568a147f77 Merge pull request #22007 from github/java-update-ferstl-depgraph-cves
Java: update ferstl depgraph cves
2026-06-22 10:08:05 +02:00
Owen Mansel-Chan
07cf89568f Test CFG for function epilogue (read-result nodes and calls to defered functions) 2026-06-20 22:04:45 +01:00
Owen Mansel-Chan
42ebe56023 Make all lines in logging tests reachable 2026-06-20 22:04:43 +01:00
Sotiris Dragonas
d86ec1a4b4 Merge pull request #22012 from github/bazookamusic/js-prompt-injection-sinks
JS Prompt Injection - Add some more sinks and reclassify legacy API
2026-06-19 17:41:41 +03:00
Owen Mansel-Chan
b54d95d7c8 Merge pull request #21967 from github/copilot/conversion-of-codeql-queries
Convert selected Python qlref tests to inline expectations
2026-06-19 14:56:36 +01:00
Michael Nebel
a076ffcc9a Merge pull request #21996 from michaelnebel/csharp/fixpathcombineissues
C#: Fix the `cs/path-combine` code quality issues in the extractor.
2026-06-19 15:49:24 +02:00
Owen Mansel-Chan
f65d1e82cf Merge pull request #21554 from github/copilot/make-go-use-ssa-library
Go: use shared SSA library (codeql.ssa.Ssa)
2026-06-19 13:40:37 +01:00
Owen Mansel-Chan
27f6ffc00e Delete accidentally included text file 2026-06-19 13:24:06 +01:00
Owen Mansel-Chan
c9d45217d2 Fix order of comments in test 2026-06-19 13:23:52 +01:00
Jeroen Ketema
75328daf71 Swift: Match quotes 2026-06-19 13:55:19 +02:00
Anders Fugmann
0f83586757 Kotlin 2.4.0: Address peer review
* Update documentation to only claim support for 2.4.0x
* Python test code; remove newlines between imports.
* Sync comments between kotlin 1.8 and 1.9
* Update code comments to attach where actually relevant,
  and improve comments on IrMemberAccessExpression<*>.extensionReceiverParameterIndex()
2026-06-19 13:45:28 +02:00
Anders Schack-Mulligen
6fbb572950 Ruby: Get rid of the change note. 2026-06-19 13:27:34 +02:00
Anders Schack-Mulligen
132b476acd Ruby: autoformat 2026-06-19 13:26:10 +02:00
copilot-swe-agent[bot]
65b4a4346b Add ExceptionList AST node for rescue clauses with 2+ exceptions 2026-06-19 13:26:06 +02:00
Owen Mansel-Chan
451fc2e4e7 Undo conversion for queries that import LegacyPointsTo 2026-06-19 12:22:42 +01:00
Owen Mansel-Chan
5497f2c5fe Convert Python qlref tests to inline expectations 2026-06-19 12:22:40 +01:00
Anders Schack-Mulligen
0834e640bb Ruby: Prepare qltest change by line renumbering. 2026-06-19 13:15:18 +02:00
Owen Mansel-Chan
1496fb6b12 Shared: allow comment starting with # after inline expectation comment 2026-06-19 11:20:30 +01:00
Sotiris Dragonas
38435fc3f2 Merge branch 'main' into bazookamusic/js-prompt-injection-sinks 2026-06-19 12:19:50 +03:00
Jeroen Ketema
b743ad9a49 Swift: Strip out more unknown clang arguments 2026-06-19 11:08:55 +02:00
Michael Nebel
03b525b689 C#: Handle the places where we could risk that Path.Combine would have thrown away the first argument. 2026-06-19 10:22:52 +02:00
Michael Nebel
f7b3f851e8 C#: Rename PathCombine to PathJoin. 2026-06-19 10:22:49 +02:00
Michael Nebel
131d4a0d81 C#: Fix the cs/path-combine code quality issues in the extractor. 2026-06-19 10:22:40 +02:00
Michael Nebel
2686026608 Merge pull request #21993 from michaelnebel/csharp/dropmono
C#: Only use `nuget.exe` on Windows or machines with Mono.
2026-06-19 09:53:04 +02:00
idrissrio
ebb74a56f6 Java: accept new test results 2026-06-19 09:38:16 +02:00
Owen Mansel-Chan
1d69c30ec1 Merge pull request #22010 from github/workflow/coverage/update
Update CSV framework coverage reports
2026-06-19 03:26:14 +01:00
github-actions[bot]
65a3153066 Add changed framework coverage reports 2026-06-19 01:06:45 +00:00
Sotiris Dragonas
ea87f59480 JS: Add and reclassify prompt-injection sinks for AI SDKs
Add missing system/user prompt-injection sinks across the OpenAI,
Anthropic, and Google GenAI JavaScript models:

- OpenAI videos.create/edit/extend/remix prompts (user)
- OpenAI beta.realtime.sessions.create instructions (system)
- Anthropic legacy completions.create prompt (user)
- Google GenAI caches.create config.systemInstruction (system)
- Google GenAI caches.create config.contents (user)

Also reclassify the OpenAI legacy completions.create prompt from
system-prompt-injection to user-prompt-injection: the legacy
/v1/completions endpoint takes a single free-form prompt with no role
separation, so it is the text-in/text-out equivalent of a user message.

Note: videos.remix takes the prompt in Argument[1] (remix(videoID, body)),
and Google GenAI caches.create nests both contents and systemInstruction
under config, so the model entries differ slightly from a naive mapping.

Add corresponding test cases with inline annotations and regenerate the
.expected files.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-06-18 17:32:10 +03:00
Owen Mansel-Chan
db5fac17bf Add QLDoc to MakeSsa to silence CI 2026-06-18 14:54:21 +01:00
Owen Mansel-Chan
fc06aa1a32 Update expected data flow consistency results 2026-06-18 14:54:19 +01:00
idrissrio
99fb3879b2 Java: update ferstl script 2026-06-18 15:43:30 +02:00
Henry Mercer
4e7e363067 Merge branch 'main' into copilot/make-go-use-ssa-library 2026-06-18 14:31:47 +01:00
Anders Schack-Mulligen
779309edb1 Merge pull request #21999 from aschackmull/cfg/parameter-pattern
Cfg: Distinguish parameters from their patterns.
2026-06-18 15:18:22 +02:00
Owen Mansel-Chan
2d34b0be1b Merge branch 'main' into copilot/make-go-use-ssa-library 2026-06-18 14:09:20 +01:00
Owen Mansel-Chan
8c07e95f05 Rename mayCapture to mayUpdateCapturedVariable 2026-06-18 12:41:25 +01:00
Owen Mansel-Chan
f04c8ccbc7 Use module already provided by BasicBlocks lib 2026-06-18 12:37:27 +01:00
Owen Mansel-Chan
7222f1d3ad Remove change note 2026-06-18 12:34:20 +01:00
Jeroen Ketema
5016fcb396 Merge pull request #21995 from jketema/jketema/tele
Java: Update expected test results after extractor changes
2026-06-18 12:51:29 +02:00
Michael Nebel
142a72c77b C#: Address review comments. 2026-06-18 12:48:09 +02:00
Anders Schack-Mulligen
f844cd3754 Java/C#: Adapt to signature change. 2026-06-18 11:00:30 +02:00
Anders Schack-Mulligen
3a3ec1be90 Cfg: Distinguish parameters from their patterns. 2026-06-18 11:00:30 +02:00
Michael Nebel
c747352f41 C#: Fix some code quality issues by replacing Path.Combine with Path.Join. 2026-06-18 08:28:58 +02:00
Michael Nebel
dfdd12190e C#: Rename NugetExeWrapper to PackagesConfigRestorer. 2026-06-18 08:28:56 +02:00
Michael Nebel
63057db753 C#: Only download and use nuget.exe in case of windows or mono is installed. 2026-06-18 08:28:54 +02:00
Michael Nebel
21f8caf153 C#: Re-factor the NugetExeWrapper, introduce an interface and a factory method for constructing package config restorers. 2026-06-18 08:28:51 +02:00
Michael Nebel
9b34cfa362 C#: Invert logic in HasPackageSource. 2026-06-18 08:28:49 +02:00
Michael Nebel
944d76de44 C#: Use the build actions IsWindows in the NugetExeWrapper. 2026-06-18 08:28:47 +02:00
Jeroen Ketema
fefe01ecbf Java: Update expected test results after extractor changes 2026-06-17 17:40:23 +02:00
Anders Fugmann
1b785a8ff6 Kotlin: mark kotlin1 integration tests
Mark the integration tests that require a Kotlin 1.x language version
with @pytest.mark.kotlin1 so CI can run them on a pinned pre-2.4
compiler (Kotlin 2.4 no longer accepts -language-version 1.9).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-06-16 16:24:43 +02:00
Anders Fugmann
e10743bd08 Kotlin: add extractor support for 2.4.0
Add the Kotlin 2.4.0 compiler plugin variant (component registrar,
IR compatibility shims, and version-specific utilities), bundle the
2.4.0 compiler dependencies, and update the build wiring, supported
version metadata and the too-new diagnostic bound.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-06-16 16:24:42 +02:00
Owen Mansel-Chan
99538f0f07 Delete unused predicate (leftover from old implementation) 2026-06-12 22:21:07 +01:00
Owen Mansel-Chan
0dc95deca4 Test changes to investigate 2026-06-12 22:21:05 +01:00
Owen Mansel-Chan
0e902d0fe3 Fix captured variable liveness
- Extend synthetic uncertain reads to function exits of any function
  that writes a captured variable, not just the declaring function.
  This ensures writes to captured variables inside closures remain
  live (matching the old `v.isCaptured()` liveness shortcut).
- Uncomment toString overrides for SsaExplicitDefinition, SsaVariableCapture,
  SsaPhiNode, and SsaVariable to restore original output formats.
- Revert test expected files to pre-test-changes state matching the
  correct toString formats and capture variable results.

Agent-Logs-Url: https://github.com/github/codeql/sessions/6dbf9d42-b2e2-42a2-984b-8ea31df4e633

Co-authored-by: owen-mc <62447351+owen-mc@users.noreply.github.com>
2026-06-12 22:21:03 +01:00
copilot-swe-agent[bot]
6ccbf16f3c Make Go use the shared SSA library (codeql.ssa.Ssa)
Co-authored-by: owen-mc <62447351+owen-mc@users.noreply.github.com>
Agent-Logs-Url: https://github.com/github/codeql/sessions/b400ebd5-4095-401e-8811-fb550600b3c4
2026-06-12 22:21:02 +01:00
Owen Mansel-Chan
7a5219f06e Improve SSA tests for variables in closures 2026-06-12 22:21:00 +01:00
copilot-swe-agent[bot]
7a991e17b8 Initial plan 2026-06-12 22:20:58 +01:00
Owen Mansel-Chan
0b493c30cc Preemptively change toString() for SSA classes 2026-06-12 22:20:51 +01:00
yoff
ac5fa629ef Python: inline init_module_submodule_defn into ImportResolution
The new-dataflow ImportResolution module only used
semmle.python.essa.SsaDefinitions for the 5-line helper predicate
SsaSource::init_module_submodule_defn. Inline it locally and drop the
dependency on legacy SsaDefinitions. This is the only remaining direct
import of semmle.python.essa.* in the new dataflow stack, so dropping
it makes the layering cleaner.

Semantic noop on the current SSA: SsaSourceVariable.getName() and
GlobalVariable.getId() both project the same DB column
(variable(_,_,result)), and the old call's 'init.getEntryNode() = f'
join was just constraining init = package via Scope.getEntryNode()'s
functional uniqueness. RA dump of accesses.ql confirms only the
expected predicate-rename shuffle; all 70 dataflow + ApiGraphs library
tests pass.

This factors out commit 8cab5a20f2 from the larger shared-CFG
migration #21925.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-06-02 08:24:17 +00:00
641 changed files with 10558 additions and 10425 deletions

View File

@@ -248,6 +248,7 @@ use_repo(
"kotlin-compiler-2.2.20-Beta2",
"kotlin-compiler-2.3.0",
"kotlin-compiler-2.3.20",
"kotlin-compiler-2.4.0",
"kotlin-compiler-embeddable-1.8.0",
"kotlin-compiler-embeddable-1.9.0-Beta",
"kotlin-compiler-embeddable-1.9.20-Beta",
@@ -259,6 +260,7 @@ use_repo(
"kotlin-compiler-embeddable-2.2.20-Beta2",
"kotlin-compiler-embeddable-2.3.0",
"kotlin-compiler-embeddable-2.3.20",
"kotlin-compiler-embeddable-2.4.0",
"kotlin-stdlib-1.8.0",
"kotlin-stdlib-1.9.0-Beta",
"kotlin-stdlib-1.9.20-Beta",
@@ -270,6 +272,7 @@ use_repo(
"kotlin-stdlib-2.2.20-Beta2",
"kotlin-stdlib-2.3.0",
"kotlin-stdlib-2.3.20",
"kotlin-stdlib-2.4.0",
)
go_sdk = use_extension("@rules_go//go:extensions.bzl", "go_sdk")

File diff suppressed because it is too large Load Diff

View File

@@ -135,7 +135,7 @@ namespace Semmle.Autobuild.CSharp.Tests
if (!EnumerateFiles.TryGetValue(dir, out var str))
throw new ArgumentException("Missing EnumerateFiles " + dir);
return str.Split("\n").Select(p => PathCombine(dir, p));
return str.Split("\n").Select(p => PathJoin(dir, p));
}
public IDictionary<string, string> EnumerateDirectories { get; } = new Dictionary<string, string>();
@@ -147,7 +147,7 @@ namespace Semmle.Autobuild.CSharp.Tests
return string.IsNullOrEmpty(str)
? Enumerable.Empty<string>()
: str.Split("\n").Select(p => PathCombine(dir, p));
: str.Split("\n").Select(p => PathJoin(dir, p));
}
public bool IsWindows { get; set; }
@@ -170,7 +170,7 @@ namespace Semmle.Autobuild.CSharp.Tests
bool IBuildActions.IsMonoInstalled() => IsMonoInstalled;
public string PathCombine(params string[] parts)
public string PathJoin(params string[] parts)
{
return string.Join(IsWindows ? '\\' : '/', parts.Where(p => !string.IsNullOrWhiteSpace(p)));
}

View File

@@ -109,7 +109,7 @@ namespace Semmle.Autobuild.CSharp
=> WithDotNet(builder, ensureDotNetAvailable: false, (_, env) => f(env));
private static string DotNetCommand(IBuildActions actions, string? dotNetPath) =>
dotNetPath is not null ? actions.PathCombine(dotNetPath, "dotnet") : "dotnet";
dotNetPath is not null ? actions.PathJoin(dotNetPath, "dotnet") : "dotnet";
private static CommandBuilder GetCleanCommand(IBuildActions actions, string? dotNetPath, IDictionary<string, string>? environment)
{

View File

@@ -158,7 +158,7 @@ namespace Semmle.Autobuild.Cpp.Tests
bool IBuildActions.IsMonoInstalled() => IsMonoInstalled;
string IBuildActions.PathCombine(params string[] parts)
string IBuildActions.PathJoin(params string[] parts)
{
return string.Join(IsWindows ? '\\' : '/', parts.Where(p => !string.IsNullOrWhiteSpace(p)));
}

View File

@@ -108,7 +108,7 @@ namespace Semmle.Autobuild.Shared
/// </summary>
/// <param name="path">The relative path.</param>
/// <returns>True iff the path was found.</returns>
public bool HasRelativePath(string path) => HasPath(Actions.PathCombine(RootDirectory, path));
public bool HasRelativePath(string path) => HasPath(Actions.PathJoin(RootDirectory, path));
/// <summary>
/// List of project/solution files to build.

View File

@@ -32,7 +32,7 @@ namespace Semmle.Autobuild.Shared
yield break;
// Attempt to use vswhere to find installations of Visual Studio
var vswhere = actions.PathCombine(programFilesx86, "Microsoft Visual Studio", "Installer", "vswhere.exe");
var vswhere = actions.PathJoin(programFilesx86, "Microsoft Visual Studio", "Installer", "vswhere.exe");
if (actions.FileExists(vswhere))
{
@@ -51,14 +51,14 @@ namespace Semmle.Autobuild.Shared
if (majorVersion < 15)
{
// Visual Studio 2015 and below
yield return new VcVarsBatFile(actions.PathCombine(vsInstallation.InstallationPath, @"VC\vcvarsall.bat"), majorVersion);
yield return new VcVarsBatFile(actions.PathJoin(vsInstallation.InstallationPath, @"VC\vcvarsall.bat"), majorVersion);
}
else
{
// Visual Studio 2017 and above
yield return new VcVarsBatFile(actions.PathCombine(vsInstallation.InstallationPath, @"VC\Auxiliary\Build\vcvars32.bat"), majorVersion);
yield return new VcVarsBatFile(actions.PathCombine(vsInstallation.InstallationPath, @"VC\Auxiliary\Build\vcvars64.bat"), majorVersion);
yield return new VcVarsBatFile(actions.PathCombine(vsInstallation.InstallationPath, @"Common7\Tools\VsDevCmd.bat"), majorVersion);
yield return new VcVarsBatFile(actions.PathJoin(vsInstallation.InstallationPath, @"VC\Auxiliary\Build\vcvars32.bat"), majorVersion);
yield return new VcVarsBatFile(actions.PathJoin(vsInstallation.InstallationPath, @"VC\Auxiliary\Build\vcvars64.bat"), majorVersion);
yield return new VcVarsBatFile(actions.PathJoin(vsInstallation.InstallationPath, @"Common7\Tools\VsDevCmd.bat"), majorVersion);
}
}
// else: Skip installation without a version
@@ -68,10 +68,10 @@ namespace Semmle.Autobuild.Shared
}
// vswhere not installed or didn't run correctly - return legacy Visual Studio versions
yield return new VcVarsBatFile(actions.PathCombine(programFilesx86, @"Microsoft Visual Studio 14.0\VC\vcvarsall.bat"), 14);
yield return new VcVarsBatFile(actions.PathCombine(programFilesx86, @"Microsoft Visual Studio 12.0\VC\vcvarsall.bat"), 12);
yield return new VcVarsBatFile(actions.PathCombine(programFilesx86, @"Microsoft Visual Studio 11.0\VC\vcvarsall.bat"), 11);
yield return new VcVarsBatFile(actions.PathCombine(programFilesx86, @"Microsoft Visual Studio 10.0\VC\vcvarsall.bat"), 10);
yield return new VcVarsBatFile(actions.PathJoin(programFilesx86, @"Microsoft Visual Studio 14.0\VC\vcvarsall.bat"), 14);
yield return new VcVarsBatFile(actions.PathJoin(programFilesx86, @"Microsoft Visual Studio 12.0\VC\vcvarsall.bat"), 12);
yield return new VcVarsBatFile(actions.PathJoin(programFilesx86, @"Microsoft Visual Studio 11.0\VC\vcvarsall.bat"), 11);
yield return new VcVarsBatFile(actions.PathJoin(programFilesx86, @"Microsoft Visual Studio 10.0\VC\vcvarsall.bat"), 10);
}
/// <summary>

View File

@@ -60,7 +60,7 @@ namespace Semmle.Autobuild.Shared
// Use `nuget.exe` from source code repo, if present, otherwise first attempt with global
// `nuget` command, and if that fails, attempt to download `nuget.exe` from nuget.org
var nuget = builder.GetFilename("nuget.exe").Select(t => t.Item1).FirstOrDefault() ?? "nuget";
var nugetDownloadPath = builder.Actions.PathCombine(FileUtils.GetTemporaryWorkingDirectory(builder.Actions.GetEnvironmentVariable, builder.Options.Language.UpperCaseName, out _), ".nuget", "nuget.exe");
var nugetDownloadPath = builder.Actions.PathJoin(FileUtils.GetTemporaryWorkingDirectory(builder.Actions.GetEnvironmentVariable, builder.Options.Language.UpperCaseName, out _), ".nuget", "nuget.exe");
var nugetDownloaded = false;
var ret = BuildScript.Success;

View File

@@ -107,8 +107,9 @@ namespace Semmle.Autobuild.Shared
continue;
}
var includePath = builder.Actions.PathCombine(include.Value.Split('\\', StringSplitOptions.RemoveEmptyEntries));
ret.Add(new Project<TAutobuildOptions>(builder, builder.Actions.PathCombine(DirectoryName, includePath)));
var includePath = builder.Actions.PathJoin(include.Value.Split('\\', StringSplitOptions.RemoveEmptyEntries));
var path = Path.IsPathRooted(includePath) ? includePath : builder.Actions.PathJoin(DirectoryName, includePath);
ret.Add(new Project<TAutobuildOptions>(builder, path));
}
return ret;
});

View File

@@ -79,7 +79,7 @@ namespace Semmle.Autobuild.Shared
includedProjects = solution.ProjectsInOrder
.Where(p => p.ProjectType == SolutionProjectType.KnownToBeMSBuildFormat)
.Select(p => builder.Actions.PathCombine(DirectoryName, builder.Actions.PathCombine(p.RelativePath.Split('\\', StringSplitOptions.RemoveEmptyEntries))))
.Select(p => builder.Actions.PathJoin(DirectoryName, builder.Actions.PathJoin(p.RelativePath.Split('\\', StringSplitOptions.RemoveEmptyEntries))))
.Select(p => new Project<TAutobuildOptions>(builder, p))
.ToArray();
}

View File

@@ -50,7 +50,7 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
return;
}
var path = Path.Combine(p, ParseFilePath(d));
var path = Path.Join(p, ParseFilePath(d));
Paths.Add(path);
Packages.Add(GetPackageName(p));
}

View File

@@ -75,7 +75,7 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
}
}
this.diagnosticsWriter = new DiagnosticsStream(Path.Combine(
this.diagnosticsWriter = new DiagnosticsStream(Path.Join(
diagDirEnv ?? "",
$"dependency-manager-{DateTime.UtcNow:yyyyMMddHHmm}-{Environment.ProcessId}.jsonc"));
this.sourceDir = new DirectoryInfo(srcDir);
@@ -327,7 +327,7 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
private void RemoveNugetPackageReference(string packagePrefix, ISet<AssemblyLookupLocation> dllLocations)
{
var packageFolder = nugetPackageRestorer.PackageDirectory.DirInfo.FullName.ToLowerInvariant();
var packagePathPrefix = Path.Combine(packageFolder, packagePrefix.ToLowerInvariant());
var packagePathPrefix = Path.Join(packageFolder, packagePrefix.ToLowerInvariant());
var toRemove = dllLocations.Where(s => s.Path.StartsWith(packagePathPrefix, StringComparison.InvariantCultureIgnoreCase));
foreach (var path in toRemove)
{

View File

@@ -31,7 +31,7 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
}
}
private DotNet(ILogger logger, string? dotNetPath, TemporaryDirectory tempWorkingDirectory, DependabotProxy? dependabotProxy) : this(new DotNetCliInvoker(logger, Path.Combine(dotNetPath ?? string.Empty, "dotnet"), dependabotProxy), logger, dotNetPath is null, tempWorkingDirectory) { }
private DotNet(ILogger logger, string? dotNetPath, TemporaryDirectory tempWorkingDirectory, DependabotProxy? dependabotProxy) : this(new DotNetCliInvoker(logger, Path.Join(dotNetPath ?? string.Empty, "dotnet"), dependabotProxy), logger, dotNetPath is null, tempWorkingDirectory) { }
internal static IDotNet Make(IDotNetCliInvoker dotnetCliInvoker, ILogger logger, bool runDotnetInfo) => new DotNet(dotnetCliInvoker, logger, runDotnetInfo);
@@ -73,7 +73,7 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
var path = ".empty";
if (tempWorkingDirectory != null)
{
path = Path.Combine(tempWorkingDirectory.ToString(), "emptyFakeDotnetRoot");
path = Path.Join(tempWorkingDirectory.ToString(), "emptyFakeDotnetRoot");
Directory.CreateDirectory(path);
}
@@ -303,7 +303,7 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
}
else
{
var dotnetInstallPath = actions.PathCombine(tempWorkingDirectory, ".dotnet", "dotnet-install.sh");
var dotnetInstallPath = actions.PathJoin(tempWorkingDirectory, ".dotnet", "dotnet-install.sh");
var downloadDotNetInstallSh = BuildScript.DownloadFile(
"https://dot.net/v1/dotnet-install.sh",
dotnetInstallPath,
@@ -339,7 +339,7 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
};
}
var dotnetInfo = InfoScript(actions, actions.PathCombine(path, "dotnet"), MinimalEnvironment.ToDictionary(), logger);
var dotnetInfo = InfoScript(actions, actions.PathJoin(path, "dotnet"), MinimalEnvironment.ToDictionary(), logger);
Func<string, BuildScript> getInstallAndVerify = version =>
// run `dotnet --info` after install, to check that it executes successfully
@@ -384,7 +384,7 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
/// </summary>
public static BuildScript WithDotNet(IBuildActions actions, ILogger logger, IEnumerable<string> files, string tempWorkingDirectory, bool shouldCleanUp, bool ensureDotNetAvailable, string? version, Func<string?, BuildScript> f)
{
var installDir = actions.PathCombine(tempWorkingDirectory, ".dotnet");
var installDir = actions.PathJoin(tempWorkingDirectory, ".dotnet");
var installScript = DownloadDotNet(actions, logger, files, tempWorkingDirectory, shouldCleanUp, installDir, version, ensureDotNetAvailable);
return BuildScript.Bind(installScript, installed =>
{

View File

@@ -12,7 +12,7 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
private string FullVersion =>
version.ToString();
public string FullPath => Path.Combine(dir, FullVersion);
public string FullPath => Path.Join(dir, FullVersion);
/**
* The full path to the reference assemblies for this runtime.
@@ -33,7 +33,7 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
{
directories[^2] = "packs";
directories[^1] = $"{directories[^1]}.Ref";
return Path.Combine(string.Join(Path.DirectorySeparatorChar, directories), FullVersion, "ref");
return Path.Join(string.Join(Path.DirectorySeparatorChar, directories), FullVersion, "ref");
}
return null;
}

View File

@@ -1,304 +0,0 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using Semmle.Util;
namespace Semmle.Extraction.CSharp.DependencyFetching
{
/// <summary>
/// Manage the downloading of NuGet packages with nuget.exe.
/// Locates packages in a source tree and downloads all of the
/// referenced assemblies to a temp folder.
/// </summary>
internal class NugetExeWrapper : IDisposable
{
private readonly string? nugetExe;
private readonly Semmle.Util.Logging.ILogger logger;
public int PackageCount => fileProvider.PackagesConfigs.Count;
private readonly string? backupNugetConfig;
private readonly string? nugetConfigPath;
private readonly FileProvider fileProvider;
/// <summary>
/// The packages directory.
/// This will be in the user-specified or computed Temp location
/// so as to not trample the source tree.
/// </summary>
private readonly DependencyDirectory packageDirectory;
/// <summary>
/// Create the package manager for a specified source tree.
/// </summary>
public NugetExeWrapper(FileProvider fileProvider, DependencyDirectory packageDirectory, Semmle.Util.Logging.ILogger logger, Func<bool> useDefaultFeed)
{
this.fileProvider = fileProvider;
this.packageDirectory = packageDirectory;
this.logger = logger;
if (fileProvider.PackagesConfigs.Count > 0)
{
logger.LogInfo($"Found packages.config files, trying to use nuget.exe for package restore");
nugetExe = ResolveNugetExe();
if (HasNoPackageSource() && useDefaultFeed())
{
// We only modify or add a top level nuget.config file
nugetConfigPath = Path.Combine(fileProvider.SourceDir.FullName, "nuget.config");
try
{
if (File.Exists(nugetConfigPath))
{
var tempFolderPath = FileUtils.GetTemporaryWorkingDirectory(out _);
do
{
backupNugetConfig = Path.Combine(tempFolderPath, Path.GetRandomFileName());
}
while (File.Exists(backupNugetConfig));
File.Copy(nugetConfigPath, backupNugetConfig, true);
}
else
{
File.WriteAllText(nugetConfigPath,
"""
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<packageSources>
</packageSources>
</configuration>
""");
}
AddDefaultPackageSource(nugetConfigPath);
}
catch (Exception e)
{
logger.LogError($"Failed to add default package source to {nugetConfigPath}: {e}");
}
}
}
}
/// <summary>
/// Tries to find the location of `nuget.exe`. It looks for
/// - the environment variable specifying a location,
/// - files in the repository,
/// - tries to resolve nuget from the PATH, or
/// - downloads it if it is not found.
/// </summary>
private string ResolveNugetExe()
{
var envVarPath = Environment.GetEnvironmentVariable(EnvironmentVariableNames.NugetExePath);
if (!string.IsNullOrEmpty(envVarPath))
{
logger.LogInfo($"Using nuget.exe from environment variable: '{envVarPath}'");
return envVarPath;
}
try
{
return DownloadNugetExe(fileProvider.SourceDir.FullName);
}
catch (Exception exc)
{
logger.LogInfo($"Download of nuget.exe failed: {exc.Message}");
}
var nugetExesInRepo = fileProvider.NugetExes;
if (nugetExesInRepo.Count > 1)
{
logger.LogInfo($"Found multiple nuget.exe files in the repository: {string.Join(", ", nugetExesInRepo.OrderBy(s => s))}");
}
if (nugetExesInRepo.Count > 0)
{
var path = nugetExesInRepo.First();
logger.LogInfo($"Using nuget.exe from path '{path}'");
return path;
}
var executableName = Win32.IsWindows() ? "nuget.exe" : "nuget";
var nugetPath = FileUtils.FindProgramOnPath(executableName);
if (nugetPath is not null)
{
nugetPath = Path.Combine(nugetPath, executableName);
logger.LogInfo($"Using nuget.exe from PATH: {nugetPath}");
return nugetPath;
}
throw new Exception("Could not find or download nuget.exe.");
}
private string DownloadNugetExe(string sourceDir)
{
var directory = Path.Combine(sourceDir, ".nuget");
var nuget = Path.Combine(directory, "nuget.exe");
// Nuget.exe already exists in the .nuget directory.
if (File.Exists(nuget))
{
logger.LogInfo($"Found nuget.exe at {nuget}");
return nuget;
}
Directory.CreateDirectory(directory);
logger.LogInfo("Attempting to download nuget.exe");
FileUtils.DownloadFile(FileUtils.NugetExeUrl, nuget, logger);
logger.LogInfo($"Downloaded nuget.exe to {nuget}");
return nuget;
}
private bool RunWithMono => !Win32.IsWindows() && !string.IsNullOrEmpty(Path.GetExtension(nugetExe));
/// <summary>
/// Restore all packages in the specified packages.config file.
/// </summary>
/// <param name="packagesConfig">The packages.config file.</param>
private bool TryRestoreNugetPackage(string packagesConfig)
{
logger.LogInfo($"Restoring file \"{packagesConfig}\"...");
/* Use nuget.exe to install a package.
* Note that there is a clutch of NuGet assemblies which could be used to
* invoke this directly, which would arguably be nicer. However they are
* really unwieldy and this solution works for now.
*/
string exe, args;
if (RunWithMono)
{
exe = "mono";
args = $"\"{nugetExe}\" install -OutputDirectory \"{packageDirectory}\" \"{packagesConfig}\"";
}
else
{
exe = nugetExe!;
args = $"install -OutputDirectory \"{packageDirectory}\" \"{packagesConfig}\"";
}
var pi = new ProcessStartInfo(exe, args)
{
RedirectStandardOutput = true,
RedirectStandardError = true,
UseShellExecute = false
};
var threadId = Environment.CurrentManagedThreadId;
void onOut(string s) => logger.LogDebug(s, threadId);
void onError(string s) => logger.LogError(s, threadId);
var exitCode = pi.ReadOutput(out _, onOut, onError);
if (exitCode != 0)
{
logger.LogError($"Command {pi.FileName} {pi.Arguments} failed with exit code {exitCode}");
return false;
}
else
{
logger.LogInfo($"Restored file \"{packagesConfig}\"");
return true;
}
}
/// <summary>
/// Download the packages to the temp folder.
/// </summary>
public int InstallPackages()
{
return fileProvider.PackagesConfigs.Count(TryRestoreNugetPackage);
}
private bool HasNoPackageSource()
{
if (Win32.IsWindows())
{
return false;
}
try
{
logger.LogInfo("Checking if default package source is available...");
RunMonoNugetCommand("sources list -ForceEnglishOutput", out var stdout);
if (stdout.All(line => line != "No sources found."))
{
return false;
}
return true;
}
catch (Exception e)
{
logger.LogWarning($"Failed to check if default package source is added: {e}");
return false;
}
}
private void RunMonoNugetCommand(string command, out IList<string> stdout)
{
string exe, args;
if (RunWithMono)
{
exe = "mono";
args = $"\"{nugetExe}\" {command}";
}
else
{
exe = nugetExe!;
args = command;
}
var pi = new ProcessStartInfo(exe, args)
{
RedirectStandardOutput = true,
RedirectStandardError = true,
UseShellExecute = false
};
var threadId = Environment.CurrentManagedThreadId;
void onOut(string s) => logger.LogDebug(s, threadId);
void onError(string s) => logger.LogError(s, threadId);
pi.ReadOutput(out stdout, onOut, onError);
}
private void AddDefaultPackageSource(string nugetConfig)
{
logger.LogInfo("Adding default package source...");
RunMonoNugetCommand($"sources add -Name DefaultNugetOrg -Source {NugetPackageRestorer.PublicNugetOrgFeed} -ConfigFile \"{nugetConfig}\"", out _);
}
public void Dispose()
{
if (nugetConfigPath is null)
{
return;
}
try
{
if (backupNugetConfig is null)
{
logger.LogInfo("Removing nuget.config file");
File.Delete(nugetConfigPath);
return;
}
logger.LogInfo("Reverting nuget.config file content");
// The content of the original nuget.config file is reverted without changing the file's attributes or casing:
using (var backup = File.OpenRead(backupNugetConfig))
using (var current = File.OpenWrite(nugetConfigPath))
{
current.SetLength(0); // Truncate file
backup.CopyTo(current); // Restore original content
}
logger.LogInfo("Deleting backup nuget.config file");
File.Delete(backupNugetConfig);
}
catch (Exception exc)
{
logger.LogError($"Failed to restore original nuget.config file: {exc}");
}
}
}
}

View File

@@ -161,13 +161,13 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
reachableFeeds.UnionWith(reachableInheritedFeeds);
}
using (var nuget = new NugetExeWrapper(fileProvider, legacyPackageDirectory, logger, IsDefaultFeedReachable))
using (var packagesConfigRestore = PackagesConfigRestoreFactory.Create(fileProvider, legacyPackageDirectory, logger, IsDefaultFeedReachable))
{
var count = nuget.InstallPackages();
var count = packagesConfigRestore.InstallPackages();
if (nuget.PackageCount > 0)
if (packagesConfigRestore.PackageCount > 0)
{
compilationInfoContainer.CompilationInfos.Add(("packages.config files", nuget.PackageCount.ToString()));
compilationInfoContainer.CompilationInfos.Add(("packages.config files", packagesConfigRestore.PackageCount.ToString()));
compilationInfoContainer.CompilationInfos.Add(("Successfully restored packages.config files", count.ToString()));
}
}
@@ -209,7 +209,7 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
var paths = dependencies
.Paths
.Select(d => Path.Combine(PackageDirectory.DirInfo.FullName, d))
.Select(d => Path.Join(PackageDirectory.DirInfo.FullName, d))
.ToList();
assemblyLookupLocations.UnionWith(paths.Select(p => new AssemblyLookupLocation(p)));
@@ -527,7 +527,7 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
var sb = new StringBuilder();
fallbackNugetFeeds.ForEach((feed, index) => sb.AppendLine($"<add key=\"feed{index}\" value=\"{feed}\" />"));
var nugetConfigPath = Path.Combine(folderPath, "nuget.config");
var nugetConfigPath = Path.Join(folderPath, "nuget.config");
logger.LogInfo($"Creating fallback nuget.config file {nugetConfigPath}.");
File.WriteAllText(nugetConfigPath,
$"""
@@ -1052,7 +1052,7 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
/// </summary>
private static string ComputeTempDirectoryPath(string subfolderName)
{
return Path.Combine(FileUtils.GetTemporaryWorkingDirectory(out _), subfolderName);
return Path.Join(FileUtils.GetTemporaryWorkingDirectory(out _), subfolderName);
}
/// <summary>
@@ -1060,7 +1060,7 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
/// </summary>
private static string ComputeTempDirectoryPath(string srcDir, string subfolderName)
{
return Path.Combine(FileUtils.GetTemporaryWorkingDirectory(out _), FileUtils.ComputeHash(srcDir), subfolderName);
return Path.Join(FileUtils.GetTemporaryWorkingDirectory(out _), FileUtils.ComputeHash(srcDir), subfolderName);
}
}
}

View File

@@ -0,0 +1,368 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using Semmle.Util;
namespace Semmle.Extraction.CSharp.DependencyFetching
{
internal interface IPackagesConfigRestore : IDisposable
{
/// <summary>
/// The number of packages.config files found in the source tree.
/// </summary>
int PackageCount { get; }
/// <summary>
/// Download the packages to the temp folder.
/// </summary>
int InstallPackages();
}
/// <summary>
/// Factory for creating a package manager to restore NuGet packages referenced in packages.config files.
/// If the environment doesn't support using nuget.exe to restore packages from packages.config files, a no-op implementation is returned.
/// It is worth noting that for macOS and Linux, nuget.exe is used with mono. However, mono is being deprecated and the last GitHub images
/// to contain mono are:
/// - Ubuntu 22.04
/// - macOS 14
///
/// If the packages from the packages.config files are not restored with the packages.config restore functionality below, there is a subsequent
/// step that still may succeed in restoring the packages without the help of nuget.exe (by attempting to restore using dotnet).
/// </summary>
internal class PackagesConfigRestoreFactory
{
public static IPackagesConfigRestore Create(FileProvider fileProvider, DependencyDirectory packageDirectory, Semmle.Util.Logging.ILogger logger, Func<bool> useDefaultFeed)
{
if (SystemBuildActions.Instance.IsWindows() || SystemBuildActions.Instance.IsMonoInstalled())
{
return new NugetExeWrapper(fileProvider, packageDirectory, logger, useDefaultFeed);
}
return new NoOpPackagesConfig(fileProvider, logger);
}
/// <summary>
/// Manage the downloading of NuGet packages with nuget.exe.
/// Locates packages in a source tree and downloads all of the
/// referenced assemblies to a temp folder.
/// </summary>
private class NugetExeWrapper : IPackagesConfigRestore
{
private readonly string? nugetExe;
private readonly Semmle.Util.Logging.ILogger logger;
public int PackageCount => fileProvider.PackagesConfigs.Count;
private readonly string? backupNugetConfig;
private readonly string? nugetConfigPath;
private readonly FileProvider fileProvider;
/// <summary>
/// The packages directory.
/// This will be in the user-specified or computed Temp location
/// so as to not trample the source tree.
/// </summary>
private readonly DependencyDirectory packageDirectory;
private bool IsWindows => SystemBuildActions.Instance.IsWindows();
/// <summary>
/// Create the package manager for a specified source tree.
/// </summary>
public NugetExeWrapper(FileProvider fileProvider, DependencyDirectory packageDirectory, Semmle.Util.Logging.ILogger logger, Func<bool> useDefaultFeed)
{
this.fileProvider = fileProvider;
this.packageDirectory = packageDirectory;
this.logger = logger;
if (fileProvider.PackagesConfigs.Count > 0)
{
logger.LogInfo($"Found packages.config files, trying to use nuget.exe for package restore");
nugetExe = ResolveNugetExe();
if (!HasPackageSource() && useDefaultFeed())
{
// We only modify or add a top level nuget.config file
nugetConfigPath = Path.Join(fileProvider.SourceDir.FullName, "nuget.config");
try
{
if (File.Exists(nugetConfigPath))
{
var tempFolderPath = FileUtils.GetTemporaryWorkingDirectory(out _);
do
{
backupNugetConfig = Path.Join(tempFolderPath, Path.GetRandomFileName());
}
while (File.Exists(backupNugetConfig));
File.Copy(nugetConfigPath, backupNugetConfig, true);
}
else
{
File.WriteAllText(nugetConfigPath,
"""
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<packageSources>
</packageSources>
</configuration>
""");
}
AddDefaultPackageSource(nugetConfigPath);
}
catch (Exception e)
{
logger.LogError($"Failed to add default package source to {nugetConfigPath}: {e}");
}
}
}
}
/// <summary>
/// Tries to find the location of `nuget.exe`. It looks for
/// - the environment variable specifying a location,
/// - files in the repository,
/// - tries to resolve nuget from the PATH, or
/// - downloads it if it is not found.
/// </summary>
private string ResolveNugetExe()
{
var envVarPath = Environment.GetEnvironmentVariable(EnvironmentVariableNames.NugetExePath);
if (!string.IsNullOrEmpty(envVarPath))
{
logger.LogInfo($"Using nuget.exe from environment variable: '{envVarPath}'");
return envVarPath;
}
try
{
return DownloadNugetExe(fileProvider.SourceDir.FullName);
}
catch (Exception exc)
{
logger.LogInfo($"Download of nuget.exe failed: {exc.Message}");
}
var nugetExesInRepo = fileProvider.NugetExes;
if (nugetExesInRepo.Count > 1)
{
logger.LogInfo($"Found multiple nuget.exe files in the repository: {string.Join(", ", nugetExesInRepo.OrderBy(s => s))}");
}
if (nugetExesInRepo.Count > 0)
{
var path = nugetExesInRepo.First();
logger.LogInfo($"Using nuget.exe from path '{path}'");
return path;
}
var executableName = IsWindows ? "nuget.exe" : "nuget";
var nugetPath = FileUtils.FindProgramOnPath(executableName);
if (nugetPath is not null)
{
nugetPath = Path.Join(nugetPath, executableName);
logger.LogInfo($"Using nuget.exe from PATH: {nugetPath}");
return nugetPath;
}
throw new Exception("Could not find or download nuget.exe.");
}
private string DownloadNugetExe(string sourceDir)
{
var directory = Path.Join(sourceDir, ".nuget");
var nuget = Path.Join(directory, "nuget.exe");
// Nuget.exe already exists in the .nuget directory.
if (File.Exists(nuget))
{
logger.LogInfo($"Found nuget.exe at {nuget}");
return nuget;
}
Directory.CreateDirectory(directory);
logger.LogInfo("Attempting to download nuget.exe");
FileUtils.DownloadFile(FileUtils.NugetExeUrl, nuget, logger);
logger.LogInfo($"Downloaded nuget.exe to {nuget}");
return nuget;
}
private bool RunWithMono => !IsWindows && !string.IsNullOrEmpty(Path.GetExtension(nugetExe));
/// <summary>
/// Restore all packages in the specified packages.config file.
/// </summary>
/// <param name="packagesConfig">The packages.config file.</param>
private bool TryRestoreNugetPackage(string packagesConfig)
{
logger.LogInfo($"Restoring file \"{packagesConfig}\"...");
/* Use nuget.exe to install a package.
* Note that there is a clutch of NuGet assemblies which could be used to
* invoke this directly, which would arguably be nicer. However they are
* really unwieldy and this solution works for now.
*/
string exe, args;
if (RunWithMono)
{
exe = "mono";
args = $"\"{nugetExe}\" install -OutputDirectory \"{packageDirectory}\" \"{packagesConfig}\"";
}
else
{
exe = nugetExe!;
args = $"install -OutputDirectory \"{packageDirectory}\" \"{packagesConfig}\"";
}
var pi = new ProcessStartInfo(exe, args)
{
RedirectStandardOutput = true,
RedirectStandardError = true,
UseShellExecute = false
};
var threadId = Environment.CurrentManagedThreadId;
void onOut(string s) => logger.LogDebug(s, threadId);
void onError(string s) => logger.LogError(s, threadId);
var exitCode = pi.ReadOutput(out _, onOut, onError);
if (exitCode != 0)
{
logger.LogError($"Command {pi.FileName} {pi.Arguments} failed with exit code {exitCode}");
return false;
}
else
{
logger.LogInfo($"Restored file \"{packagesConfig}\"");
return true;
}
}
/// <summary>
/// Download the packages to the temp folder.
/// </summary>
public int InstallPackages()
{
return fileProvider.PackagesConfigs.Count(TryRestoreNugetPackage);
}
private bool HasPackageSource()
{
if (IsWindows)
{
return true;
}
try
{
logger.LogInfo("Checking if default package source is available...");
RunMonoNugetCommand("sources list -ForceEnglishOutput", out var stdout);
if (stdout.All(line => line != "No sources found."))
{
return true;
}
return false;
}
catch (Exception e)
{
logger.LogWarning($"Failed to check if default package source is added: {e}");
return true;
}
}
private void RunMonoNugetCommand(string command, out IList<string> stdout)
{
string exe, args;
if (RunWithMono)
{
exe = "mono";
args = $"\"{nugetExe}\" {command}";
}
else
{
exe = nugetExe!;
args = command;
}
var pi = new ProcessStartInfo(exe, args)
{
RedirectStandardOutput = true,
RedirectStandardError = true,
UseShellExecute = false
};
var threadId = Environment.CurrentManagedThreadId;
void onOut(string s) => logger.LogDebug(s, threadId);
void onError(string s) => logger.LogError(s, threadId);
pi.ReadOutput(out stdout, onOut, onError);
}
private void AddDefaultPackageSource(string nugetConfig)
{
logger.LogInfo("Adding default package source...");
RunMonoNugetCommand($"sources add -Name DefaultNugetOrg -Source {NugetPackageRestorer.PublicNugetOrgFeed} -ConfigFile \"{nugetConfig}\"", out _);
}
public void Dispose()
{
if (nugetConfigPath is null)
{
return;
}
try
{
if (backupNugetConfig is null)
{
logger.LogInfo("Removing nuget.config file");
File.Delete(nugetConfigPath);
return;
}
logger.LogInfo("Reverting nuget.config file content");
// The content of the original nuget.config file is reverted without changing the file's attributes or casing:
using (var backup = File.OpenRead(backupNugetConfig))
using (var current = File.OpenWrite(nugetConfigPath))
{
current.SetLength(0); // Truncate file
backup.CopyTo(current); // Restore original content
}
logger.LogInfo("Deleting backup nuget.config file");
File.Delete(backupNugetConfig);
}
catch (Exception exc)
{
logger.LogError($"Failed to restore original nuget.config file: {exc}");
}
}
}
private class NoOpPackagesConfig : IPackagesConfigRestore
{
private readonly Semmle.Util.Logging.ILogger logger;
private readonly FileProvider fileProvider;
public NoOpPackagesConfig(FileProvider fileProvider, Semmle.Util.Logging.ILogger logger)
{
this.fileProvider = fileProvider;
this.logger = logger;
}
public int PackageCount => fileProvider.PackagesConfigs.Count;
public int InstallPackages()
{
if (PackageCount > 0)
{
logger.LogInfo("Found packages.config files, but nuget.exe cannot be used to restore packages on this platform. Skipping restore of packages.config files.");
}
return 0;
}
public void Dispose() { }
}
}
}

View File

@@ -79,7 +79,7 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
var monoPath = FileUtils.FindProgramOnPath(Win32.IsWindows() ? "mono.exe" : "mono");
string[] monoDirs = monoPath is not null
? [Path.GetFullPath(Path.Combine(monoPath, "..", "lib", "mono")), monoPath]
? [Path.GetFullPath(Path.Join(monoPath, "..", "lib", "mono")), monoPath]
: ["/usr/lib/mono", "/usr/local/mono", "/usr/local/bin/mono", @"C:\Program Files\Mono\lib\mono"];
var monoDir = monoDirs.FirstOrDefault(Directory.Exists);

View File

@@ -63,7 +63,7 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
return null;
}
var path = Path.Combine(version.FullPath, "Roslyn", "bincore", "csc.dll");
var path = Path.Join(version.FullPath, "Roslyn", "bincore", "csc.dll");
logger.LogDebug($"Source generator CSC: '{path}'");
if (!File.Exists(path))
{

View File

@@ -41,10 +41,10 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
.Replace('\\', '/'); // Ensure we're generating the same hash regardless of the OS
var name = FileUtils.ComputeHash($"{relativePathToCsProj}\n{this.GetType().Name}");
using var tempDir = new TemporaryDirectory(Path.Join(FileUtils.GetTemporaryWorkingDirectory(out _), "source-generator"), "source generator temporary", logger);
var analyzerConfigPath = Path.Combine(tempDir.DirInfo.FullName, $"{name}.txt");
var dllPath = Path.Combine(tempDir.DirInfo.FullName, $"{name}.dll");
var cscArgsPath = Path.Combine(tempDir.DirInfo.FullName, $"{name}.rsp");
var outputFolder = Path.Combine(targetDir, name);
var analyzerConfigPath = Path.Join(tempDir.DirInfo.FullName, $"{name}.txt");
var dllPath = Path.Join(tempDir.DirInfo.FullName, $"{name}.dll");
var cscArgsPath = Path.Join(tempDir.DirInfo.FullName, $"{name}.rsp");
var outputFolder = Path.Join(targetDir, name);
Directory.CreateDirectory(outputFolder);
logger.LogInfo("Producing analyzer config content.");
GenerateAnalyzerConfig(additionalFiles, csprojFile, analyzerConfigPath);

View File

@@ -21,7 +21,7 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
throw new Exception("No SDK path available.");
}
SourceGeneratorFolder = Path.Combine(sdkPath, "Sdks", "Microsoft.NET.Sdk.Razor", "source-generators");
SourceGeneratorFolder = Path.Join(sdkPath, "Sdks", "Microsoft.NET.Sdk.Razor", "source-generators");
this.logger.LogInfo($"Razor source generator folder: {SourceGeneratorFolder}");
if (!Directory.Exists(SourceGeneratorFolder))
{

View File

@@ -50,7 +50,7 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
if (usings.Count > 0)
{
var tempDir = GetTemporaryWorkingDirectory("implicitUsings");
var path = Path.Combine(tempDir, "GlobalUsings.g.cs");
var path = Path.Join(tempDir, "GlobalUsings.g.cs");
using (var writer = new StreamWriter(path))
{
writer.WriteLine("// <auto-generated/>");

View File

@@ -32,7 +32,7 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
var nugetFolder = nugetPackageRestorer.TryRestore("Microsoft.CodeAnalysis.ResxSourceGenerator");
if (nugetFolder is not null)
{
sourceGeneratorFolder = System.IO.Path.Combine(nugetFolder, "analyzers", "dotnet", "cs");
sourceGeneratorFolder = System.IO.Path.Join(nugetFolder, "analyzers", "dotnet", "cs");
}
}
catch (Exception e)

View File

@@ -35,7 +35,7 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
/// </summary>
protected string GetTemporaryWorkingDirectory(string subfolder)
{
var temp = Path.Combine(tempWorkingDirectory.ToString(), subfolder);
var temp = Path.Join(tempWorkingDirectory.ToString(), subfolder);
Directory.CreateDirectory(temp);
return temp;

View File

@@ -23,7 +23,9 @@ namespace Semmle.Extraction.CSharp.Entities.Statements
}
else if (isSpecificCatchClause) // A catch clause of the form 'catch(Ex) { ... }'
{
trapFile.catch_type(this, Type.Create(Context, Context.GetType(Stmt.Declaration!.Type)).TypeRef, true);
var type = Type.Create(Context, Context.GetType(Stmt.Declaration!.Type));
trapFile.catch_type(this, type.TypeRef, true);
TypeMention.Create(Context, Stmt.Declaration!.Type, this, type);
}
else // A catch clause of the form 'catch { ... }'
{

View File

@@ -67,7 +67,7 @@ namespace Semmle.Extraction.CSharp
return;
}
var mscorlibExists = File.Exists(Path.Combine(compilerDir, "mscorlib.dll"));
var mscorlibExists = File.Exists(Path.Join(compilerDir, "mscorlib.dll"));
if (specifiedFramework is null && mscorlibExists)
{
@@ -107,7 +107,7 @@ namespace Semmle.Extraction.CSharp
/// <summary>
/// The file csc.rsp.
/// </summary>
private string CscRsp => Path.Combine(FrameworkPath, csc_rsp);
private string CscRsp => Path.Join(FrameworkPath, csc_rsp);
/// <summary>
/// Should we skip extraction?

View File

@@ -680,7 +680,7 @@ namespace Semmle.Extraction.CSharp
{
try
{
var fullPath = Path.GetFullPath(Path.Combine(Path.GetDirectoryName(mappedFromPath)!, mappedToPath));
var fullPath = Path.GetFullPath(Path.Join(Path.GetDirectoryName(mappedFromPath)!, mappedToPath));
ExtractionContext.Logger.LogDebug($"Found relative path in line mapping: '{mappedToPath}', interpreting it as '{fullPath}'");
mappedToPath = fullPath;

View File

@@ -159,7 +159,11 @@ namespace Semmle.Extraction.CSharp
return null;
}
return Path.GetFullPath(Path.Combine(projDir?.FullName ?? string.Empty, Path.DirectorySeparatorChar == '/' ? file.Replace("\\", "/") : file));
var normalized = Path.DirectorySeparatorChar == '/' ? file.Replace("\\", "/") : file;
var path = projDir is not null && !Path.IsPathRooted(normalized)
? Path.Join(projDir.FullName, normalized)
: normalized;
return Path.GetFullPath(path);
}
private readonly string[] references;

View File

@@ -210,7 +210,7 @@ namespace Semmle.Extraction.CSharp
TracingAnalyser.GetOutputName(compilation, args),
compilation,
generatedSyntaxTrees,
Path.Combine(compilationIdentifierPath, diagnosticName),
Path.Join(compilationIdentifierPath, diagnosticName),
options),
() => { });
@@ -377,7 +377,7 @@ namespace Semmle.Extraction.CSharp
else
{
var composed = referencePaths.Value
.Select(path => Path.Combine(path, clref.Reference))
.Select(path => Path.Join(path, clref.Reference))
.Where(path => File.Exists(path))
.Select(path => analyser.PathCache.GetCanonicalPath(path))
.FirstOrDefault();
@@ -559,13 +559,13 @@ namespace Semmle.Extraction.CSharp
/// Gets the path to the `csharp.log` file written to by the C# extractor.
/// </summary>
public static string GetCSharpLogPath() =>
Path.Combine(GetCSharpLogDirectory(), "csharp.log");
Path.Join(GetCSharpLogDirectory(), "csharp.log");
/// <summary>
/// Gets the path to a `csharp.{hash}.txt` file written to by the C# extractor.
/// </summary>
public static string GetCSharpArgsLogPath(string hash) =>
Path.Combine(GetCSharpLogDirectory(), $"csharp.{hash}.txt");
Path.Join(GetCSharpLogDirectory(), $"csharp.{hash}.txt");
/// <summary>
/// Gets a list of all `csharp.{hash}.txt` files currently written to the log directory.

View File

@@ -131,7 +131,7 @@ namespace Semmle.Extraction.CSharp
return Path.ChangeExtension(entryPointFilename, ".exe");
}
return Path.Combine(commandLineArguments.OutputDirectory, commandLineArguments.OutputFileName);
return Path.Join(commandLineArguments.OutputDirectory, commandLineArguments.OutputFileName);
}
private int LogDiagnostics()

View File

@@ -61,7 +61,7 @@ namespace Semmle.Extraction.CSharp
* Although GetRandomFileName() is cryptographically secure,
* there's a tiny chance the file could already exists.
*/
tmpFile = Path.Combine(tempPath, Path.GetRandomFileName());
tmpFile = Path.Join(tempPath, Path.GetRandomFileName());
}
while (File.Exists(tmpFile));

View File

@@ -82,13 +82,13 @@ namespace SemmleTests.Semmle.Util
[Fact]
public void CanonicalPathMissingFile()
{
Assert.Equal(Path.Combine(Directory.GetCurrentDirectory(), "NOSUCHFILE"), cache.GetCanonicalPath("NOSUCHFILE"));
Assert.Equal(Path.Join(Directory.GetCurrentDirectory(), "NOSUCHFILE"), cache.GetCanonicalPath("NOSUCHFILE"));
}
[Fact]
public void CanonicalPathMissingAbsolutePath()
{
Assert.Equal(Path.Combine(root, "no", "such", "file"), cache.GetCanonicalPath(Path.Combine(root, "no", "such", "file")));
Assert.Equal(Path.Join(root, "no", "such", "file"), cache.GetCanonicalPath(Path.Join(root, "no", "such", "file")));
if (Win32.IsWindows())
Assert.Equal(@"C:\Windows\no\such\file", cache.GetCanonicalPath(@"C:\windOws\no\such\file"));
@@ -97,7 +97,7 @@ namespace SemmleTests.Semmle.Util
[Fact]
public void CanonicalPathMissingRelativePath()
{
Assert.Equal(Path.Combine(Directory.GetCurrentDirectory(), "NO", "SUCH"), cache.GetCanonicalPath(Path.Combine("NO", "SUCH")));
Assert.Equal(Path.Join(Directory.GetCurrentDirectory(), "NO", "SUCH"), cache.GetCanonicalPath(Path.Join("NO", "SUCH")));
}
[Fact]
@@ -125,7 +125,7 @@ namespace SemmleTests.Semmle.Util
public void CanonicalPathDots()
{
var abcPath = Path.GetFullPath("abc");
Assert.Equal(abcPath, cache.GetCanonicalPath(Path.Combine("foo", ".", "..", "abc")));
Assert.Equal(abcPath, cache.GetCanonicalPath(Path.Join("foo", ".", "..", "abc")));
}
[Fact]

View File

@@ -14,20 +14,20 @@ namespace SemmleTests.Semmle.Util
public sealed class LongPaths
{
private static readonly string tmpDir = Environment.GetEnvironmentVariable("TEST_TMPDIR") ?? Path.GetTempPath();
private static readonly string longPathDir = Path.Combine(tmpDir, "aaaaaaaaaaaaaaaaaaaaaaaaaaaa", "bbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
private static readonly string longPathDir = Path.Join(tmpDir, "aaaaaaaaaaaaaaaaaaaaaaaaaaaa", "bbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
"ccccccccccccccccccccccccccccccc", "ddddddddddddddddddddddddddddddddddddd", "eeeeeeeeeeeeeeeeeeeeeeeeeeeeeee", "fffffffffffffffffffffffffffffffff",
"ggggggggggggggggggggggggggggggggggg", "hhhhhhhhhhhhhhhhhhhhhhhhhhhhhh");
private static string MakeLongPath()
{
var uniquePostfix = Guid.NewGuid().ToString("N");
return Path.Combine(longPathDir, $"iiiiiiiiiiiiiiii{uniquePostfix}.txt");
return Path.Join(longPathDir, $"iiiiiiiiiiiiiiii{uniquePostfix}.txt");
}
private static string MakeShortPath()
{
var uniquePostfix = Guid.NewGuid().ToString("N");
return Path.Combine(tmpDir, $"test{uniquePostfix}.txt");
return Path.Join(tmpDir, $"test{uniquePostfix}.txt");
}
public LongPaths()
@@ -62,7 +62,7 @@ namespace SemmleTests.Semmle.Util
[Fact]
public void ParentDirectory()
{
Assert.Equal("abc", Path.GetDirectoryName(Path.Combine("abc", "def")));
Assert.Equal("abc", Path.GetDirectoryName(Path.Join("abc", "def")));
Assert.Equal(Win32.IsWindows() ? "\\" : "/", Path.GetDirectoryName($@"{Path.DirectorySeparatorChar}def"));
Assert.Equal("", Path.GetDirectoryName(@"def"));

View File

@@ -137,11 +137,11 @@ namespace Semmle.Util
bool IsMonoInstalled();
/// <summary>
/// Combine path segments, Path.Combine().
/// Joins path segments, Path.Join().
/// </summary>
/// <param name="parts">The parts of the path.</param>
/// <returns>The combined path.</returns>
string PathCombine(params string[] parts);
string PathJoin(params string[] parts);
/// <summary>
/// Gets the full path for <paramref name="path"/>, Path.GetFullPath().
@@ -293,7 +293,7 @@ namespace Semmle.Util
}
}
string IBuildActions.PathCombine(params string[] parts) => Path.Combine(parts);
string IBuildActions.PathJoin(params string[] parts) => Path.Join(parts);
void IBuildActions.WriteAllText(string filename, string contents) => File.WriteAllText(filename, contents);

View File

@@ -43,7 +43,7 @@ namespace Semmle.Util
var parent = Directory.GetParent(path);
return parent is not null ?
Path.Combine(cache.GetCanonicalPath(parent.FullName), Path.GetFileName(path)) :
Path.Join(cache.GetCanonicalPath(parent.FullName), Path.GetFileName(path)) :
path.ToUpperInvariant();
}
}
@@ -138,12 +138,12 @@ namespace Semmle.Util
var entries = Directory.GetFileSystemEntries(parentPath, name);
return entries.Length == 1
? entries[0]
: Path.Combine(parentPath, name);
: Path.Join(parentPath, name);
}
catch // lgtm[cs/catch-of-all-exceptions]
{
// IO error or security error querying directory.
return Path.Combine(parentPath, name);
return Path.Join(parentPath, name);
}
}
}

View File

@@ -82,7 +82,7 @@ namespace Semmle.Util
{
exes = new[] { prog };
}
var candidates = paths?.Where(path => exes.Any(exe0 => File.Exists(Path.Combine(path, exe0))));
var candidates = paths?.Where(path => exes.Any(exe0 => File.Exists(Path.Join(path, exe0))));
return candidates?.FirstOrDefault();
}
@@ -179,7 +179,7 @@ namespace Semmle.Util
{
innerpath = ConvertPathToSafeRelativePath(innerpath);
nested = Path.Combine(outerpath, innerpath);
nested = Path.Join(outerpath, innerpath);
}
try
{
@@ -203,7 +203,7 @@ namespace Semmle.Util
{
var tempPath = Path.GetTempPath();
var name = Guid.NewGuid().ToString("N").ToUpper();
var tempFolder = Path.Combine(tempPath, "GitHub", name);
var tempFolder = Path.Join(tempPath, "GitHub", name);
Directory.CreateDirectory(tempFolder);
return tempFolder;
});
@@ -231,7 +231,7 @@ namespace Semmle.Util
string outputPath;
do
{
outputPath = Path.Combine(tempFolder, Path.GetRandomFileName() + extension);
outputPath = Path.Join(tempFolder, Path.GetRandomFileName() + extension);
}
while (File.Exists(outputPath));

View File

@@ -145,6 +145,8 @@ module Ast implements AstSig<Location> {
final private class ParameterFinal = CS::Parameter;
class Parameter extends ParameterFinal {
AstNode getPattern() { result = this }
Expr getDefaultValue() {
// Avoid combinatorial explosions for callables with multiple bodies
result = unique( | | super.getDefaultValue())

View File

@@ -101,6 +101,7 @@ csharp6.cs:
# 32| 0: [IntLiteral] 2
# 32| 0: [IntLiteral] 1
# 34| 1: [SpecificCatchClause] catch (...) {...}
# 34| 0: [TypeMention] IndexOutOfRangeException
# 35| 1: [BlockStmt] {...}
# 34| 2: [EQExpr] ... == ...
# 34| 0: [PropertyCall] access to property Value

View File

@@ -194,3 +194,16 @@ class C3<T> : C2<C4<T>> { }
class C4<T> : C2<C3<T>> { }
class C5 : C4<C5> { }
class CatchTypeMentions
{
void F()
{
try
{
}
catch (Exception)
{
}
}
}

View File

@@ -100,3 +100,5 @@
| Program.cs:194:21:194:21 | T |
| Program.cs:196:12:196:17 | C4<C5> |
| Program.cs:196:15:196:16 | C5 |
| Program.cs:200:5:200:8 | Void |
| Program.cs:205:16:205:24 | Exception |

View File

@@ -21,7 +21,7 @@
Java,"Java 7 to 26 [6]_","javac (OpenJDK and Oracle JDK),
Eclipse compiler for Java (ECJ) [7]_",``.java``
Kotlin,"Kotlin 1.8.0 to 2.3.2\ *x*","kotlinc",``.kt``
Kotlin,"Kotlin 1.8.0 to 2.4.0\ *x*","kotlinc",``.kt``
JavaScript,ECMAScript 2022 or lower,Not applicable,"``.js``, ``.jsx``, ``.mjs``, ``.es``, ``.es6``, ``.htm``, ``.html``, ``.xhtm``, ``.xhtml``, ``.vue``, ``.hbs``, ``.ejs``, ``.njk``, ``.json``, ``.yaml``, ``.yml``, ``.raml``, ``.xml`` [8]_"
Python [9]_,"2.7, 3.5, 3.6, 3.7, 3.8, 3.9, 3.10, 3.11, 3.12, 3.13",Not applicable,``.py``
Ruby [10]_,"up to 3.3",Not applicable,"``.rb``, ``.erb``, ``.gemspec``, ``Gemfile``"

View File

@@ -123,7 +123,7 @@ k8s.io/api/core,,,10,,,,,,,,,,,,,,,,,,,,,,,10,
k8s.io/apimachinery/pkg/runtime,,,47,,,,,,,,,,,,,,,,,,,,,,,47,
k8s.io/klog,90,,,,,,90,,,,,,,,,,,,,,,,,,,,
launchpad.net/xmlpath,2,,,,,,,,,,,,,,,,,,2,,,,,,,,
log,20,,3,,,,20,,,,,,,,,,,,,,,,,,,3,
log,40,,3,,,,40,,,,,,,,,,,,,,,,,,,3,
math/big,,,1,,,,,,,,,,,,,,,,,,,,,,,1,
mime,,,14,,,,,,,,,,,,,,,,,,,,,,,14,
net,2,16,100,,,,,,1,,,,,,,,1,,,,,,,16,,100,
1 package sink source summary sink:command-injection sink:credentials-key sink:jwt sink:log-injection sink:nosql-injection sink:path-injection sink:regex-use[0] sink:regex-use[1] sink:regex-use[c] sink:request-forgery sink:request-forgery[TCP Addr + Port] sink:sql-injection sink:url-redirection sink:url-redirection[0] sink:url-redirection[receiver] sink:xpath-injection source:commandargs source:database source:environment source:file source:remote source:stdin summary:taint summary:value
123 k8s.io/apimachinery/pkg/runtime 47 47
124 k8s.io/klog 90 90
125 launchpad.net/xmlpath 2 2
126 log 20 40 3 20 40 3
127 math/big 1 1
128 mime 14 14
129 net 2 16 100 1 1 16 100

View File

@@ -32,7 +32,7 @@ Go framework & library support
`Revel <http://revel.github.io/>`_,"``github.com/revel/revel*``, ``github.com/robfig/revel*``",46,20,4
`SendGrid <https://github.com/sendgrid/sendgrid-go>`_,``github.com/sendgrid/sendgrid-go*``,,1,
`Squirrel <https://github.com/Masterminds/squirrel>`_,"``github.com/Masterminds/squirrel*``, ``github.com/lann/squirrel*``, ``gopkg.in/Masterminds/squirrel``",81,,96
`Standard library <https://pkg.go.dev/std>`_,"````, ``archive/*``, ``bufio``, ``bytes``, ``cmp``, ``compress/*``, ``container/*``, ``context``, ``crypto``, ``crypto/*``, ``database/*``, ``debug/*``, ``embed``, ``encoding``, ``encoding/*``, ``errors``, ``expvar``, ``flag``, ``fmt``, ``go/*``, ``hash``, ``hash/*``, ``html``, ``html/*``, ``image``, ``image/*``, ``index/*``, ``io``, ``io/*``, ``log``, ``log/*``, ``maps``, ``math``, ``math/*``, ``mime``, ``mime/*``, ``net``, ``net/*``, ``os``, ``os/*``, ``path``, ``path/*``, ``plugin``, ``reflect``, ``reflect/*``, ``regexp``, ``regexp/*``, ``slices``, ``sort``, ``strconv``, ``strings``, ``sync``, ``sync/*``, ``syscall``, ``syscall/*``, ``testing``, ``testing/*``, ``text/*``, ``time``, ``time/*``, ``unicode``, ``unicode/*``, ``unsafe``, ``weak``",52,612,104
`Standard library <https://pkg.go.dev/std>`_,"````, ``archive/*``, ``bufio``, ``bytes``, ``cmp``, ``compress/*``, ``container/*``, ``context``, ``crypto``, ``crypto/*``, ``database/*``, ``debug/*``, ``embed``, ``encoding``, ``encoding/*``, ``errors``, ``expvar``, ``flag``, ``fmt``, ``go/*``, ``hash``, ``hash/*``, ``html``, ``html/*``, ``image``, ``image/*``, ``index/*``, ``io``, ``io/*``, ``log``, ``log/*``, ``maps``, ``math``, ``math/*``, ``mime``, ``mime/*``, ``net``, ``net/*``, ``os``, ``os/*``, ``path``, ``path/*``, ``plugin``, ``reflect``, ``reflect/*``, ``regexp``, ``regexp/*``, ``slices``, ``sort``, ``strconv``, ``strings``, ``sync``, ``sync/*``, ``syscall``, ``syscall/*``, ``testing``, ``testing/*``, ``text/*``, ``time``, ``time/*``, ``unicode``, ``unicode/*``, ``unsafe``, ``weak``",52,612,124
`XORM <https://xorm.io>`_,"``github.com/go-xorm/xorm*``, ``xorm.io/xorm*``",,,68
`XPath <https://github.com/antchfx/xpath>`_,``github.com/antchfx/xpath*``,,,4
`appleboy/gin-jwt <https://github.com/appleboy/gin-jwt>`_,``github.com/appleboy/gin-jwt*``,,,1
@@ -74,5 +74,5 @@ Go framework & library support
`xpathparser <https://github.com/santhosh-tekuri/xpathparser>`_,``github.com/santhosh-tekuri/xpathparser*``,,,2
`yaml <https://gopkg.in/yaml.v3>`_,``gopkg.in/yaml*``,,9,
`zap <https://go.uber.org/zap>`_,``go.uber.org/zap*``,,11,33
Totals,,688,1072,1557
Totals,,688,1072,1577

View File

@@ -10,6 +10,7 @@ dependencies:
codeql/controlflow: ${workspace}
codeql/dataflow: ${workspace}
codeql/mad: ${workspace}
codeql/ssa: ${workspace}
codeql/threat-models: ${workspace}
codeql/tutorial: ${workspace}
codeql/util: ${workspace}

View File

@@ -42,11 +42,11 @@ private module Input implements BB::InputSig<Location> {
predicate nodeIsPostDominanceExit(Node node) { node instanceof ExitNode }
}
private module BbImpl = BB::Make<Location, Input>;
module Cfg = BB::Make<Location, Input>;
class BasicBlock = BbImpl::BasicBlock;
class BasicBlock = Cfg::BasicBlock;
class EntryBasicBlock = BbImpl::EntryBasicBlock;
class EntryBasicBlock = Cfg::EntryBasicBlock;
cached
private predicate reachableBB(BasicBlock bb) {

View File

@@ -63,10 +63,7 @@ private predicate unresolvedIdentifier(Ident id, string name) {
/**
* An SSA variable.
*/
class SsaVariable extends TSsaDefinition {
/** Gets the source variable corresponding to this SSA variable. */
SsaSourceVariable getSourceVariable() { result = this.(SsaDefinition).getSourceVariable() }
class SsaVariable extends Definition {
/** Gets the (unique) definition of this SSA variable. */
SsaDefinition getDefinition() { result = this }
@@ -74,22 +71,17 @@ class SsaVariable extends TSsaDefinition {
Type getType() { result = this.getSourceVariable().getType() }
/** Gets a use in basic block `bb` that refers to this SSA variable. */
IR::Instruction getAUseIn(ReachableBasicBlock bb) {
IR::Instruction getAUseIn(BasicBlock bb) {
exists(int i, SsaSourceVariable v | v = this.getSourceVariable() |
result = bb.getNode(i) and
this = getDefinition(bb, i, v)
ssaDefReachesRead(v, this, bb, i) and
useAt(bb, i, v)
)
}
/** Gets a use that refers to this SSA variable. */
IR::Instruction getAUse() { result = this.getAUseIn(_) }
/** Gets a textual representation of this element. */
string toString() { result = this.getDefinition().prettyPrintRef() }
/** Gets the location of this SSA variable. */
Location getLocation() { result = this.getDefinition().getLocation() }
/**
* DEPRECATED: Use `getLocation()` instead.
*
@@ -109,50 +101,20 @@ class SsaVariable extends TSsaDefinition {
/**
* An SSA definition.
*/
class SsaDefinition extends TSsaDefinition {
class SsaDefinition extends Definition {
/** Gets the SSA variable defined by this definition. */
SsaVariable getVariable() { result = this }
/** Gets the source variable defined by this definition. */
abstract SsaSourceVariable getSourceVariable();
/**
* Gets the basic block to which this definition belongs.
*/
abstract ReachableBasicBlock getBasicBlock();
/**
* INTERNAL: Use `getBasicBlock()` and `getSourceVariable()` instead.
*
* Holds if this is a definition of source variable `v` at index `idx` in basic block `bb`.
*
* Phi nodes are considered to be at index `-1`, all other definitions at the index of
* the control flow node they correspond to.
*/
abstract predicate definesAt(ReachableBasicBlock bb, int idx, SsaSourceVariable v);
/**
* INTERNAL: Use `toString()` instead.
*
* Gets a pretty-printed representation of this SSA definition.
*/
abstract string prettyPrintDef();
/**
* INTERNAL: Do not use.
*
* Gets a pretty-printed representation of a reference to this SSA definition.
*/
abstract string prettyPrintRef();
/** Gets the innermost function or file to which this SSA definition belongs. */
ControlFlow::Root getRoot() { result = this.getBasicBlock().getScope() }
/** Gets a textual representation of this element. */
string toString() { result = this.prettyPrintDef() }
/** Gets the source location for this element. */
abstract Location getLocation();
/**
* INTERNAL: Do not use.
*
* Gets a short string identifying the kind of this SSA definition,
* used in reference formatting (e.g., `"def"`, `"capture"`, `"phi"`).
*/
string getKind() { none() }
/**
* DEPRECATED: Use `getLocation()` instead.
@@ -180,32 +142,23 @@ class SsaDefinition extends TSsaDefinition {
/**
* An SSA definition that corresponds to an explicit assignment or other variable definition.
*/
class SsaExplicitDefinition extends SsaDefinition, TExplicitDef {
class SsaExplicitDefinition extends SsaDefinition, WriteDefinition {
SsaExplicitDefinition() {
exists(BasicBlock bb, int i, SsaSourceVariable v |
this.definesAt(v, bb, i) and
defAt(bb, i, v)
)
}
/** Gets the instruction where the definition happens. */
IR::Instruction getInstruction() {
exists(BasicBlock bb, int i | this = TExplicitDef(bb, i, _) | result = bb.getNode(i))
exists(BasicBlock bb, int i | this.definesAt(_, bb, i) | result = bb.getNode(i))
}
/** Gets the right-hand side of the definition. */
IR::Instruction getRhs() { this.getInstruction().writes(_, result) }
override predicate definesAt(ReachableBasicBlock bb, int i, SsaSourceVariable v) {
this = TExplicitDef(bb, i, v)
}
override ReachableBasicBlock getBasicBlock() { this.definesAt(result, _, _) }
override SsaSourceVariable getSourceVariable() { this = TExplicitDef(_, _, result) }
override string prettyPrintRef() {
exists(Location loc | loc = this.getLocation() |
result = "def@" + loc.getStartLine() + ":" + loc.getStartColumn()
)
}
override string prettyPrintDef() { result = "definition of " + this.getSourceVariable() }
override Location getLocation() { result = this.getInstruction().getLocation() }
override string getKind() { result = "def" }
}
/** Provides a helper predicate for working with explicit SSA definitions. */
@@ -219,22 +172,7 @@ module SsaExplicitDefinition {
/**
* An SSA definition that does not correspond to an explicit variable definition.
*/
abstract class SsaImplicitDefinition extends SsaDefinition {
/**
* INTERNAL: Do not use.
*
* Gets the definition kind to include in `prettyPrintRef`.
*/
abstract string getKind();
override string prettyPrintRef() {
exists(Location loc | loc = this.getLocation() |
result = this.getKind() + "@" + loc.getStartLine() + ":" + loc.getStartColumn()
)
}
override Location getLocation() { result = this.getBasicBlock().getLocation() }
}
abstract class SsaImplicitDefinition extends SsaDefinition { }
/**
* An SSA definition representing the capturing of an SSA-convertible variable
@@ -243,24 +181,8 @@ abstract class SsaImplicitDefinition extends SsaDefinition {
* Capturing definitions appear at the beginning of such functions, as well as
* at any function call that may affect the value of the variable.
*/
class SsaVariableCapture extends SsaImplicitDefinition, TCapture {
override predicate definesAt(ReachableBasicBlock bb, int i, SsaSourceVariable v) {
this = TCapture(bb, i, v)
}
override ReachableBasicBlock getBasicBlock() { this.definesAt(result, _, _) }
override SsaSourceVariable getSourceVariable() { this.definesAt(_, _, result) }
class SsaVariableCapture extends SsaImplicitDefinition, UncertainWriteDefinition {
override string getKind() { result = "capture" }
override string prettyPrintDef() { result = "capture variable " + this.getSourceVariable() }
override Location getLocation() {
exists(ReachableBasicBlock bb, int i | this.definesAt(bb, i, _) |
result = bb.getNode(i).getLocation()
)
}
}
/**
@@ -272,12 +194,6 @@ abstract class SsaPseudoDefinition extends SsaImplicitDefinition {
* Gets an input of this pseudo-definition.
*/
abstract SsaVariable getAnInput();
/**
* Gets a textual representation of the inputs of this pseudo-definition
* in lexicographical order.
*/
string ppInputs() { result = concat(this.getAnInput().getDefinition().prettyPrintRef(), ", ") }
}
/**
@@ -285,26 +201,10 @@ abstract class SsaPseudoDefinition extends SsaImplicitDefinition {
* in the flow graph where otherwise two or more definitions for the variable
* would be visible.
*/
class SsaPhiNode extends SsaPseudoDefinition, TPhi {
override SsaVariable getAnInput() {
result = getDefReachingEndOf(this.getBasicBlock().getAPredecessor(_), this.getSourceVariable())
}
override predicate definesAt(ReachableBasicBlock bb, int i, SsaSourceVariable v) {
bb = this.getBasicBlock() and v = this.getSourceVariable() and i = -1
}
override ReachableBasicBlock getBasicBlock() { this = TPhi(result, _) }
override SsaSourceVariable getSourceVariable() { this = TPhi(_, result) }
class SsaPhiNode extends SsaPseudoDefinition, PhiNode {
override SsaVariable getAnInput() { phiHasInputFromBlock(this, result, _) }
override string getKind() { result = "phi" }
override string prettyPrintDef() {
result = this.getSourceVariable() + " = phi(" + this.ppInputs() + ")"
}
override Location getLocation() { result = this.getBasicBlock().getLocation() }
}
/**

View File

@@ -7,76 +7,25 @@ overlay[local]
module;
import go
private import codeql.ssa.Ssa as SsaImplCommon
private import semmle.go.controlflow.BasicBlocks as BasicBlocks
private class BasicBlock = BasicBlocks::BasicBlock;
cached
private module Internal {
/** Holds if the `i`th node of `bb` defines `v`. */
cached
predicate defAt(ReachableBasicBlock bb, int i, SsaSourceVariable v) {
predicate defAt(BasicBlock bb, int i, SsaSourceVariable v) {
bb.getNode(i).(IR::Instruction).writes(v, _)
}
/** Holds if the `i`th node of `bb` reads `v`. */
cached
predicate useAt(ReachableBasicBlock bb, int i, SsaSourceVariable v) {
predicate useAt(BasicBlock bb, int i, SsaSourceVariable v) {
bb.getNode(i).(IR::Instruction).reads(v)
}
/**
* A data type representing SSA definitions.
*
* We distinguish three kinds of SSA definitions:
*
* 1. Variable definitions, including declarations, assignments and increments/decrements.
* 2. Pseudo-definitions for captured variables at the beginning of the capturing function
* as well as after calls.
* 3. Phi nodes.
*
* SSA definitions are only introduced where necessary. In particular,
* unreachable code has no SSA definitions associated with it, and neither
* have dead assignments (that is, assignments whose value is never read).
*/
cached
newtype TSsaDefinition =
/**
* An SSA definition that corresponds to an explicit assignment or other variable definition.
*/
TExplicitDef(ReachableBasicBlock bb, int i, SsaSourceVariable v) {
defAt(bb, i, v) and
(liveAfterDef(bb, i, v) or v.isCaptured())
} or
/**
* An SSA definition representing the capturing of an SSA-convertible variable
* in the closure of a nested function.
*
* Capturing definitions appear at the beginning of such functions, as well as
* at any function call that may affect the value of the variable.
*/
TCapture(ReachableBasicBlock bb, int i, SsaSourceVariable v) {
mayCapture(bb, i, v) and
liveAfterDef(bb, i, v)
} or
/**
* An SSA phi node, that is, a pseudo-definition for a variable at a point
* in the flow graph where otherwise two or more definitions for the variable
* would be visible.
*/
TPhi(ReachableJoinBlock bb, SsaSourceVariable v) {
liveAtEntry(bb, v) and
inDefDominanceFrontier(bb, v)
}
/**
* Holds if `bb` is in the dominance frontier of a block containing a definition of `v`.
*/
pragma[noinline]
private predicate inDefDominanceFrontier(ReachableJoinBlock bb, SsaSourceVariable v) {
exists(ReachableBasicBlock defbb, SsaDefinition def |
def.definesAt(defbb, _, v) and
defbb.inDominanceFrontier(bb)
)
}
/**
* Holds if `v` is a captured variable which is declared in `declFun` and read in `useFun`.
*/
@@ -87,7 +36,7 @@ private module Internal {
}
/** Holds if the `i`th node of `bb` in function `f` is an entry node. */
private predicate entryNode(FuncDef f, ReachableBasicBlock bb, int i) {
private predicate entryNode(FuncDef f, BasicBlock bb, int i) {
f = bb.getScope() and
bb.getNode(i).isEntryNode()
}
@@ -95,17 +44,17 @@ private module Internal {
/**
* Holds if the `i`th node of `bb` in function `f` is a function call.
*/
private predicate callNode(FuncDef f, ReachableBasicBlock bb, int i) {
private predicate callNode(FuncDef f, BasicBlock bb, int i) {
f = bb.getScope() and
bb.getNode(i).(IR::EvalInstruction).getExpr() instanceof CallExpr
}
/**
* Holds if the `i`th node of basic block `bb` may induce a pseudo-definition for
* modeling updates to captured variable `v`. Whether the definition is actually
* introduced depends on whether `v` is live at this point in the program.
* modeling updates to captured variable `v`.
*/
private predicate mayCapture(ReachableBasicBlock bb, int i, SsaSourceVariable v) {
cached
predicate mayUpdateCapturedVariable(BasicBlock bb, int i, SsaSourceVariable v) {
exists(FuncDef capturingContainer, FuncDef declContainer |
// capture initial value of variable declared in enclosing scope
readsCapturedVar(capturingContainer, v, declContainer) and
@@ -119,347 +68,134 @@ private module Internal {
)
}
/** A classification of variable references into reads and writes. */
private newtype RefKind =
ReadRef() or
WriteRef()
/**
* Holds if the `i`th node of basic block `bb` is a reference to `v`, either a read
* (when `tp` is `ReadRef()`) or a direct or indirect write (when `tp` is `WriteRef()`).
*/
private predicate ref(ReachableBasicBlock bb, int i, SsaSourceVariable v, RefKind tp) {
useAt(bb, i, v) and tp = ReadRef()
or
(mayCapture(bb, i, v) or defAt(bb, i, v)) and
tp = WriteRef()
}
/**
* Gets the (1-based) rank of the reference to `v` at the `i`th node of basic block `bb`,
* which has the given reference kind `tp`.
*/
private int refRank(ReachableBasicBlock bb, int i, SsaSourceVariable v, RefKind tp) {
i = rank[result](int j | ref(bb, j, v, _)) and
ref(bb, i, v, tp)
}
/**
* Gets the maximum rank among all references to `v` in basic block `bb`.
*/
private int maxRefRank(ReachableBasicBlock bb, SsaSourceVariable v) {
result = max(refRank(bb, _, v, _))
}
/**
* Holds if variable `v` is live after the `i`th node of basic block `bb`, where
* `i` is the index of a node that may assign or capture `v`.
*
* For the purposes of this predicate, function calls are considered as writes of captured variables.
*/
private predicate liveAfterDef(ReachableBasicBlock bb, int i, SsaSourceVariable v) {
exists(int r | r = refRank(bb, i, v, WriteRef()) |
// the next reference to `v` inside `bb` is a read
r + 1 = refRank(bb, _, v, ReadRef())
or
// this is the last reference to `v` inside `bb`, but `v` is live at entry
// to a successor basic block of `bb`
r = maxRefRank(bb, v) and
liveAtSuccEntry(bb, v)
)
}
/**
* Holds if variable `v` is live at the beginning of basic block `bb`.
*
* For the purposes of this predicate, function calls are considered as writes of captured variables.
*/
private predicate liveAtEntry(ReachableBasicBlock bb, SsaSourceVariable v) {
// the first reference to `v` inside `bb` is a read
refRank(bb, _, v, ReadRef()) = 1
or
// there is no reference to `v` inside `bb`, but `v` is live at entry
// to a successor basic block of `bb`
not exists(refRank(bb, _, v, _)) and
liveAtSuccEntry(bb, v)
}
/**
* Holds if `v` is live at the beginning of any successor of basic block `bb`.
*/
private predicate liveAtSuccEntry(ReachableBasicBlock bb, SsaSourceVariable v) {
liveAtEntry(bb.getASuccessor(_), v)
}
/**
* Holds if `v` is assigned outside its declaring function.
*/
private predicate assignedThroughClosure(SsaSourceVariable v) {
cached
predicate assignedThroughClosure(SsaSourceVariable v) {
any(IR::Instruction def | def.writes(v, _)).getRoot() != v.getDeclaringFunction()
}
/**
* Holds if the `i`th node of `bb` is a use or an SSA definition of variable `v`, with
* `k` indicating whether it is the former or the latter.
*
* Note this includes phi nodes, whereas `ref` above only includes explicit writes and captures.
*/
private predicate ssaRef(ReachableBasicBlock bb, int i, SsaSourceVariable v, RefKind k) {
useAt(bb, i, v) and k = ReadRef()
or
any(SsaDefinition def).definesAt(bb, i, v) and k = WriteRef()
}
/** SSA input. */
cached
module SsaInput implements SsaImplCommon::InputSig<Location, BasicBlock> {
class SourceVariable = SsaSourceVariable;
/**
* Gets the (1-based) rank of the `i`th node of `bb` among all SSA definitions
* and uses of `v` in `bb`, with `k` indicating whether it is a definition or a use.
*
* For example, if `bb` is a basic block with a phi node for `v` (considered
* to be at index -1), uses `v` at node 2 and defines it at node 5, we have:
*
* ```
* ssaRefRank(bb, -1, v, WriteRef()) = 1 // phi node
* ssaRefRank(bb, 2, v, ReadRef()) = 2 // use at node 2
* ssaRefRank(bb, 5, v, WriteRef()) = 3 // definition at node 5
* ```
*/
private int ssaRefRank(ReachableBasicBlock bb, int i, SsaSourceVariable v, RefKind k) {
i = rank[result](int j | ssaRef(bb, j, v, _)) and
ssaRef(bb, i, v, k)
}
/**
* Holds if the `i`th node of basic block `bb` is a (potential) write to source
* variable `v`. The Boolean `certain` indicates whether the write is certain.
*
* Certain writes are explicit definitions; uncertain writes are captures.
*/
cached
predicate variableWrite(BasicBlock bb, int i, SourceVariable v, boolean certain) {
defAt(bb, i, v) and certain = true
or
mayUpdateCapturedVariable(bb, i, v) and certain = false
}
/**
* Gets the minimum rank of a read in `bb` such that all references to `v` between that
* read and the read at index `i` are reads (and not writes).
*/
private int rewindReads(ReachableBasicBlock bb, int i, SsaSourceVariable v) {
exists(int r | r = ssaRefRank(bb, i, v, ReadRef()) |
exists(int j, RefKind k | r - 1 = ssaRefRank(bb, j, v, k) |
k = ReadRef() and result = rewindReads(bb, j, v)
/**
* Holds if the `i`th node of basic block `bb` reads source variable `v`.
*
* We add a synthetic uncertain read at the exit node of every function
* that references a captured variable `v`. This ensures that definitions
* of captured variables are included in the SSA graph even when the
* variable is not locally read in that function scope (but may be read
* by another function sharing the same closure).
*/
cached
predicate variableRead(BasicBlock bb, int i, SourceVariable v, boolean certain) {
useAt(bb, i, v) and certain = true
or
v.isCaptured() and
exists(FuncDef f |
f = bb.getScope() and
bb.getLastNode().isExitNode() and
i = bb.length() - 1 and
certain = false
|
// The declaring function: captures may be read after calls to closures
f = v.getDeclaringFunction()
or
k = WriteRef() and result = r
)
or
r = 1 and result = r
)
}
/**
* Gets the SSA definition of `v` in `bb` that reaches the read of `v` at node `i`, if any.
*/
private SsaDefinition getLocalDefinition(ReachableBasicBlock bb, int i, SsaSourceVariable v) {
exists(int r | r = rewindReads(bb, i, v) |
exists(int j | result.definesAt(bb, j, v) and ssaRefRank(bb, j, v, _) = r - 1)
)
}
/**
* Gets an SSA definition of `v` that reaches the end of the immediate dominator of `bb`.
*/
pragma[noinline]
private SsaDefinition getDefReachingEndOfImmediateDominator(
ReachableBasicBlock bb, SsaSourceVariable v
) {
result = getDefReachingEndOf(bb.getImmediateDominator(), v)
}
/**
* Gets an SSA definition of `v` that reaches the end of basic block `bb`.
*/
cached
SsaDefinition getDefReachingEndOf(ReachableBasicBlock bb, SsaSourceVariable v) {
exists(int lastRef | lastRef = max(int i | ssaRef(bb, i, v, _)) |
result = getLocalDefinition(bb, lastRef, v)
or
result.definesAt(bb, lastRef, v) and
liveAtSuccEntry(bb, v)
)
or
// In SSA form, the (unique) reaching definition of a use is the closest
// definition that dominates the use. If two definitions dominate a node
// then one must dominate the other, so we can find the reaching definition
// by following the idominance relation backwards.
result = getDefReachingEndOfImmediateDominator(bb, v) and
not exists(SsaDefinition ssa | ssa.definesAt(bb, _, v)) and
liveAtSuccEntry(bb, v)
}
/**
* Gets the unique SSA definition of `v` whose value reaches the `i`th node of `bb`,
* which is a use of `v`.
*/
cached
SsaDefinition getDefinition(ReachableBasicBlock bb, int i, SsaSourceVariable v) {
result = getLocalDefinition(bb, i, v)
or
rewindReads(bb, i, v) = 1 and result = getDefReachingEndOf(bb.getImmediateDominator(), v)
}
private module AdjacentUsesImpl {
/** Holds if `v` is defined or used in `b`. */
private predicate varOccursInBlock(SsaSourceVariable v, ReachableBasicBlock b) {
ssaRef(b, _, v, _)
}
/** Holds if `v` occurs in `b` or one of `b`'s transitive successors. */
private predicate blockPrecedesVar(SsaSourceVariable v, ReachableBasicBlock b) {
varOccursInBlock(v, b)
or
exists(getDefReachingEndOf(b, v))
}
/**
* Holds if `v` occurs in `b1` and `b2` is one of `b1`'s successors.
*
* Factored out of `varBlockReaches` to force join order compared to the larger
* set `blockPrecedesVar(v, b2)`.
*/
pragma[noinline]
private predicate varBlockReachesBaseCand(
SsaSourceVariable v, ReachableBasicBlock b1, ReachableBasicBlock b2
) {
varOccursInBlock(v, b1) and
b2 = b1.getASuccessor(_)
}
/**
* Holds if `b2` is a transitive successor of `b1` and `v` occurs in `b1` and
* in `b2` or one of its transitive successors but not in any block on the path
* between `b1` and `b2`. Unlike `varBlockReaches` this may include blocks `b2`
* where `v` is dead.
*
* Factored out of `varBlockReaches` to force join order compared to the larger
* set `blockPrecedesVar(v, b2)`.
*/
pragma[noinline]
private predicate varBlockReachesRecCand(
SsaSourceVariable v, ReachableBasicBlock b1, ReachableBasicBlock mid, ReachableBasicBlock b2
) {
varBlockReaches(v, b1, mid) and
not varOccursInBlock(v, mid) and
b2 = mid.getASuccessor(_)
}
/**
* Holds if `b2` is a transitive successor of `b1` and `v` occurs in `b1` and
* in `b2` or one of its transitive successors but not in any block on the path
* between `b1` and `b2`.
*/
private predicate varBlockReaches(
SsaSourceVariable v, ReachableBasicBlock b1, ReachableBasicBlock b2
) {
varBlockReachesBaseCand(v, b1, b2) and
blockPrecedesVar(v, b2)
or
varBlockReachesRecCand(v, b1, _, b2) and
blockPrecedesVar(v, b2)
}
/**
* Holds if `b2` is a transitive successor of `b1` and `v` occurs in `b1` and
* `b2` but not in any block on the path between `b1` and `b2`.
*/
private predicate varBlockStep(
SsaSourceVariable v, ReachableBasicBlock b1, ReachableBasicBlock b2
) {
varBlockReaches(v, b1, b2) and
varOccursInBlock(v, b2)
}
/**
* Gets the maximum rank among all SSA references to `v` in basic block `bb`.
*/
private int maxSsaRefRank(ReachableBasicBlock bb, SsaSourceVariable v) {
result = max(ssaRefRank(bb, _, v, _))
}
/**
* Holds if `v` occurs at index `i1` in `b1` and at index `i2` in `b2` and
* there is a path between them without any occurrence of `v`.
*/
pragma[nomagic]
predicate adjacentVarRefs(
SsaSourceVariable v, ReachableBasicBlock b1, int i1, ReachableBasicBlock b2, int i2
) {
exists(int rankix |
b1 = b2 and
ssaRefRank(b1, i1, v, _) = rankix and
ssaRefRank(b2, i2, v, _) = rankix + 1
)
or
maxSsaRefRank(b1, v) = ssaRefRank(b1, i1, v, _) and
varBlockStep(v, b1, b2) and
ssaRefRank(b2, i2, v, _) = 1
}
predicate variableUse(SsaSourceVariable v, IR::Instruction use, ReachableBasicBlock bb, int i) {
bb.getNode(i) = use and
exists(SsaVariable sv |
sv.getSourceVariable() = v and
use = sv.getAUse()
// Any function that writes `v`: the write may be observed by the
// declaring function or another closure sharing the same variable
any(IR::Instruction def | def.writes(v, _)).getRoot() = f
)
}
}
private import AdjacentUsesImpl
/**
* Holds if the value defined at `def` can reach `use` without passing through
* any other uses, but possibly through phi nodes.
*/
cached
predicate firstUse(SsaDefinition def, IR::Instruction use) {
exists(SsaSourceVariable v, ReachableBasicBlock b1, int i1, ReachableBasicBlock b2, int i2 |
adjacentVarRefs(v, b1, i1, b2, i2) and
def.definesAt(b1, i1, v) and
variableUse(v, use, b2, i2)
)
or
exists(
SsaSourceVariable v, SsaPhiNode redef, ReachableBasicBlock b1, int i1, ReachableBasicBlock b2,
int i2
|
adjacentVarRefs(v, b1, i1, b2, i2) and
def.definesAt(b1, i1, v) and
redef.definesAt(b2, i2, v) and
firstUse(redef, use)
)
}
/**
* Holds if `use1` and `use2` form an adjacent use-use-pair of the same SSA
* variable, that is, the value read in `use1` can reach `use2` without passing
* through any other use or any SSA definition of the variable.
*/
cached
predicate adjacentUseUseSameVar(IR::Instruction use1, IR::Instruction use2) {
exists(SsaSourceVariable v, ReachableBasicBlock b1, int i1, ReachableBasicBlock b2, int i2 |
adjacentVarRefs(v, b1, i1, b2, i2) and
variableUse(v, use1, b1, i1) and
variableUse(v, use2, b2, i2)
)
}
/**
* Holds if `use1` and `use2` form an adjacent use-use-pair of the same
* `SsaSourceVariable`, that is, the value read in `use1` can reach `use2`
* without passing through any other use or any SSA definition of the variable
* except for phi nodes and uncertain implicit updates.
*/
cached
predicate adjacentUseUse(IR::Instruction use1, IR::Instruction use2) {
adjacentUseUseSameVar(use1, use2)
or
exists(
SsaSourceVariable v, SsaPhiNode def, ReachableBasicBlock b1, int i1, ReachableBasicBlock b2,
int i2
|
adjacentVarRefs(v, b1, i1, b2, i2) and
variableUse(v, use1, b1, i1) and
def.definesAt(b2, i2, v) and
firstUse(def, use2)
)
}
}
import Internal
import SsaImplCommon::Make<Location, BasicBlocks::Cfg, SsaInput> as Impl
final class Definition = Impl::Definition;
final class WriteDefinition = Impl::WriteDefinition;
final class UncertainWriteDefinition = Impl::UncertainWriteDefinition;
final class PhiNode = Impl::PhiNode;
module Consistency = Impl::Consistency;
/**
* NB: This predicate should be cached.
*
* Holds if the SSA definition of `v` at `def` reaches a read at index `i` in
* basic block `bb`.
*/
cached
predicate ssaDefReachesRead(SsaSourceVariable v, Definition def, BasicBlock bb, int i) {
Impl::ssaDefReachesRead(v, def, bb, i)
}
/**
* NB: This predicate should be cached.
*
* Holds if the SSA definition of `v` at `def` reaches the end of basic block `bb`.
*/
cached
predicate ssaDefReachesEndOfBlock(BasicBlock bb, Definition def, SsaSourceVariable v) {
Impl::ssaDefReachesEndOfBlock(bb, def, v)
}
/**
* NB: This predicate should be cached.
*
* Holds if `inp` is an input to the phi node `phi` along the edge originating in `bb`.
*/
cached
predicate phiHasInputFromBlock(PhiNode phi, Definition inp, BasicBlock bb) {
Impl::phiHasInputFromBlock(phi, inp, bb)
}
/**
* NB: This predicate should be cached.
*
* Holds if `def` reaches the first use `use` without going through any other use,
* but possibly through phi nodes.
*/
cached
predicate firstUse(Definition def, IR::Instruction use) {
exists(BasicBlock bb, int i |
Impl::firstUse(def, bb, i, _) and
use = bb.getNode(i)
)
}
/**
* NB: This predicate should be cached.
*
* Holds if `use1` and `use2` form an adjacent use-use-pair of the same SSA
* variable, that is, the value read in `use1` can reach `use2` without passing
* through any other use or any SSA definition of the variable except for phi nodes
* and uncertain implicit updates.
*/
cached
predicate adjacentUseUse(IR::Instruction use1, IR::Instruction use2) {
exists(BasicBlock bb1, int i1, BasicBlock bb2, int i2 |
Impl::adjacentUseUse(bb1, i1, bb2, i2, _, _) and
use1 = bb1.getNode(i1) and
use2 = bb2.getNode(i2)
)
}

View File

@@ -2,7 +2,7 @@
| file://:0:0:0:0 | [summary param] -1 in Clone |
| file://:0:0:0:0 | [summary param] -1 in Write |
| file://:0:0:0:0 | [summary param] -1 in WriteProxy |
| main.go:18:12:18:14 | SSA def(req) |
| main.go:18:12:18:14 | argument corresponding to req |
| main.go:18:12:18:14 | definition of req |
| main.go:20:5:20:7 | req |
| main.go:20:5:20:7 | req [postupdate] |

View File

@@ -47,27 +47,27 @@
| test.go:621:25:621:31 | tarRead | test.go:93:5:93:16 | selection of Body | test.go:621:25:621:31 | tarRead | This decompression is $@. | test.go:93:5:93:16 | selection of Body | decompressing compressed data without managing output size |
| test.go:629:2:629:8 | tarRead | test.go:93:5:93:16 | selection of Body | test.go:629:2:629:8 | tarRead | This decompression is $@. | test.go:93:5:93:16 | selection of Body | decompressing compressed data without managing output size |
edges
| test.go:59:16:59:44 | call to FormValue | test.go:128:20:128:27 | definition of filename | provenance | Src:MaD:2 |
| test.go:60:15:60:26 | selection of Body | test.go:158:19:158:22 | definition of file | provenance | Src:MaD:1 |
| test.go:61:24:61:35 | selection of Body | test.go:169:28:169:31 | definition of file | provenance | Src:MaD:1 |
| test.go:62:13:62:24 | selection of Body | test.go:181:17:181:20 | definition of file | provenance | Src:MaD:1 |
| test.go:64:8:64:19 | selection of Body | test.go:208:12:208:15 | definition of file | provenance | Src:MaD:1 |
| test.go:66:8:66:19 | selection of Body | test.go:233:12:233:15 | definition of file | provenance | Src:MaD:1 |
| test.go:68:17:68:28 | selection of Body | test.go:258:21:258:24 | definition of file | provenance | Src:MaD:1 |
| test.go:70:13:70:24 | selection of Body | test.go:283:17:283:20 | definition of file | provenance | Src:MaD:1 |
| test.go:72:16:72:27 | selection of Body | test.go:308:20:308:23 | definition of file | provenance | Src:MaD:1 |
| test.go:74:7:74:18 | selection of Body | test.go:333:11:333:14 | definition of file | provenance | Src:MaD:1 |
| test.go:76:9:76:20 | selection of Body | test.go:358:13:358:16 | definition of file | provenance | Src:MaD:1 |
| test.go:78:18:78:29 | selection of Body | test.go:384:22:384:25 | definition of file | provenance | Src:MaD:1 |
| test.go:80:5:80:16 | selection of Body | test.go:412:9:412:12 | definition of file | provenance | Src:MaD:1 |
| test.go:82:7:82:18 | selection of Body | test.go:447:11:447:14 | definition of file | provenance | Src:MaD:1 |
| test.go:84:15:84:26 | selection of Body | test.go:440:19:440:21 | definition of src | provenance | Src:MaD:1 |
| test.go:85:16:85:27 | selection of Body | test.go:472:20:472:23 | definition of file | provenance | Src:MaD:1 |
| test.go:87:16:87:27 | selection of Body | test.go:499:20:499:23 | definition of file | provenance | Src:MaD:1 |
| test.go:89:17:89:28 | selection of Body | test.go:526:21:526:24 | definition of file | provenance | Src:MaD:1 |
| test.go:91:15:91:26 | selection of Body | test.go:555:19:555:22 | definition of file | provenance | Src:MaD:1 |
| test.go:93:5:93:16 | selection of Body | test.go:580:9:580:12 | definition of file | provenance | Src:MaD:1 |
| test.go:128:20:128:27 | definition of filename | test.go:130:33:130:40 | filename | provenance | |
| test.go:59:16:59:44 | call to FormValue | test.go:128:20:128:27 | SSA def(filename) | provenance | Src:MaD:2 |
| test.go:60:15:60:26 | selection of Body | test.go:158:19:158:22 | SSA def(file) | provenance | Src:MaD:1 |
| test.go:61:24:61:35 | selection of Body | test.go:169:28:169:31 | SSA def(file) | provenance | Src:MaD:1 |
| test.go:62:13:62:24 | selection of Body | test.go:181:17:181:20 | SSA def(file) | provenance | Src:MaD:1 |
| test.go:64:8:64:19 | selection of Body | test.go:208:12:208:15 | SSA def(file) | provenance | Src:MaD:1 |
| test.go:66:8:66:19 | selection of Body | test.go:233:12:233:15 | SSA def(file) | provenance | Src:MaD:1 |
| test.go:68:17:68:28 | selection of Body | test.go:258:21:258:24 | SSA def(file) | provenance | Src:MaD:1 |
| test.go:70:13:70:24 | selection of Body | test.go:283:17:283:20 | SSA def(file) | provenance | Src:MaD:1 |
| test.go:72:16:72:27 | selection of Body | test.go:308:20:308:23 | SSA def(file) | provenance | Src:MaD:1 |
| test.go:74:7:74:18 | selection of Body | test.go:333:11:333:14 | SSA def(file) | provenance | Src:MaD:1 |
| test.go:76:9:76:20 | selection of Body | test.go:358:13:358:16 | SSA def(file) | provenance | Src:MaD:1 |
| test.go:78:18:78:29 | selection of Body | test.go:384:22:384:25 | SSA def(file) | provenance | Src:MaD:1 |
| test.go:80:5:80:16 | selection of Body | test.go:412:9:412:12 | SSA def(file) | provenance | Src:MaD:1 |
| test.go:82:7:82:18 | selection of Body | test.go:447:11:447:14 | SSA def(file) | provenance | Src:MaD:1 |
| test.go:84:15:84:26 | selection of Body | test.go:440:19:440:21 | SSA def(src) | provenance | Src:MaD:1 |
| test.go:85:16:85:27 | selection of Body | test.go:472:20:472:23 | SSA def(file) | provenance | Src:MaD:1 |
| test.go:87:16:87:27 | selection of Body | test.go:499:20:499:23 | SSA def(file) | provenance | Src:MaD:1 |
| test.go:89:17:89:28 | selection of Body | test.go:526:21:526:24 | SSA def(file) | provenance | Src:MaD:1 |
| test.go:91:15:91:26 | selection of Body | test.go:555:19:555:22 | SSA def(file) | provenance | Src:MaD:1 |
| test.go:93:5:93:16 | selection of Body | test.go:580:9:580:12 | SSA def(file) | provenance | Src:MaD:1 |
| test.go:128:20:128:27 | SSA def(filename) | test.go:130:33:130:40 | filename | provenance | |
| test.go:130:2:130:41 | ... := ...[0] | test.go:132:12:132:12 | f | provenance | |
| test.go:130:33:130:40 | filename | test.go:130:2:130:41 | ... := ...[0] | provenance | Config |
| test.go:130:33:130:40 | filename | test.go:143:51:143:58 | filename | provenance | |
@@ -77,7 +77,7 @@ edges
| test.go:143:51:143:58 | filename | test.go:143:2:143:59 | ... := ...[0] | provenance | Config |
| test.go:145:12:145:12 | f | test.go:145:12:145:19 | call to Open | provenance | Config |
| test.go:145:12:145:19 | call to Open | test.go:147:37:147:38 | rc | provenance | |
| test.go:158:19:158:22 | definition of file | test.go:159:25:159:28 | file | provenance | |
| test.go:158:19:158:22 | SSA def(file) | test.go:159:25:159:28 | file | provenance | |
| test.go:159:2:159:29 | ... := ...[0] | test.go:160:48:160:52 | file1 | provenance | |
| test.go:159:25:159:28 | file | test.go:159:2:159:29 | ... := ...[0] | provenance | MaD:6 |
| test.go:160:2:160:69 | ... := ...[0] | test.go:163:26:163:29 | file | provenance | |
@@ -85,7 +85,7 @@ edges
| test.go:160:48:160:52 | file1 | test.go:160:32:160:53 | call to NewReader | provenance | MaD:5 |
| test.go:163:3:163:36 | ... := ...[0] | test.go:164:36:164:51 | fileReaderCloser | provenance | |
| test.go:163:26:163:29 | file | test.go:163:3:163:36 | ... := ...[0] | provenance | MaD:4 |
| test.go:169:28:169:31 | definition of file | test.go:170:25:170:28 | file | provenance | |
| test.go:169:28:169:31 | SSA def(file) | test.go:170:25:170:28 | file | provenance | |
| test.go:170:2:170:29 | ... := ...[0] | test.go:171:57:171:61 | file2 | provenance | |
| test.go:170:25:170:28 | file | test.go:170:2:170:29 | ... := ...[0] | provenance | MaD:6 |
| test.go:171:2:171:78 | ... := ...[0] | test.go:175:26:175:29 | file | provenance | |
@@ -93,64 +93,64 @@ edges
| test.go:171:57:171:61 | file2 | test.go:171:41:171:62 | call to NewReader | provenance | MaD:5 |
| test.go:175:26:175:29 | file | test.go:175:26:175:36 | call to Open | provenance | Config |
| test.go:175:26:175:36 | call to Open | test.go:176:36:176:51 | fileReaderCloser | provenance | |
| test.go:181:17:181:20 | definition of file | test.go:184:41:184:44 | file | provenance | |
| test.go:181:17:181:20 | SSA def(file) | test.go:184:41:184:44 | file | provenance | |
| test.go:184:2:184:73 | ... := ...[0] | test.go:186:2:186:12 | bzip2Reader | provenance | |
| test.go:184:2:184:73 | ... := ...[0] | test.go:187:26:187:36 | bzip2Reader | provenance | |
| test.go:184:41:184:44 | file | test.go:184:2:184:73 | ... := ...[0] | provenance | Config |
| test.go:187:12:187:37 | call to NewReader | test.go:189:18:189:24 | tarRead | provenance | |
| test.go:187:26:187:36 | bzip2Reader | test.go:187:12:187:37 | call to NewReader | provenance | MaD:3 |
| test.go:189:18:189:24 | tarRead | test.go:611:22:611:28 | definition of tarRead | provenance | |
| test.go:208:12:208:15 | definition of file | test.go:211:33:211:36 | file | provenance | |
| test.go:189:18:189:24 | tarRead | test.go:611:22:611:28 | SSA def(tarRead) | provenance | |
| test.go:208:12:208:15 | SSA def(file) | test.go:211:33:211:36 | file | provenance | |
| test.go:211:17:211:37 | call to NewReader | test.go:213:2:213:12 | bzip2Reader | provenance | |
| test.go:211:17:211:37 | call to NewReader | test.go:214:26:214:36 | bzip2Reader | provenance | |
| test.go:211:33:211:36 | file | test.go:211:17:211:37 | call to NewReader | provenance | Config |
| test.go:214:12:214:37 | call to NewReader | test.go:216:18:216:24 | tarRead | provenance | |
| test.go:214:26:214:36 | bzip2Reader | test.go:214:12:214:37 | call to NewReader | provenance | MaD:3 |
| test.go:216:18:216:24 | tarRead | test.go:611:22:611:28 | definition of tarRead | provenance | |
| test.go:233:12:233:15 | definition of file | test.go:236:33:236:36 | file | provenance | |
| test.go:216:18:216:24 | tarRead | test.go:611:22:611:28 | SSA def(tarRead) | provenance | |
| test.go:233:12:233:15 | SSA def(file) | test.go:236:33:236:36 | file | provenance | |
| test.go:236:17:236:37 | call to NewReader | test.go:238:2:238:12 | flateReader | provenance | |
| test.go:236:17:236:37 | call to NewReader | test.go:239:26:239:36 | flateReader | provenance | |
| test.go:236:33:236:36 | file | test.go:236:17:236:37 | call to NewReader | provenance | Config |
| test.go:239:12:239:37 | call to NewReader | test.go:241:18:241:24 | tarRead | provenance | |
| test.go:239:26:239:36 | flateReader | test.go:239:12:239:37 | call to NewReader | provenance | MaD:3 |
| test.go:241:18:241:24 | tarRead | test.go:611:22:611:28 | definition of tarRead | provenance | |
| test.go:258:21:258:24 | definition of file | test.go:261:42:261:45 | file | provenance | |
| test.go:241:18:241:24 | tarRead | test.go:611:22:611:28 | SSA def(tarRead) | provenance | |
| test.go:258:21:258:24 | SSA def(file) | test.go:261:42:261:45 | file | provenance | |
| test.go:261:17:261:46 | call to NewReader | test.go:263:2:263:12 | flateReader | provenance | |
| test.go:261:17:261:46 | call to NewReader | test.go:264:26:264:36 | flateReader | provenance | |
| test.go:261:42:261:45 | file | test.go:261:17:261:46 | call to NewReader | provenance | Config |
| test.go:264:12:264:37 | call to NewReader | test.go:266:18:266:24 | tarRead | provenance | |
| test.go:264:26:264:36 | flateReader | test.go:264:12:264:37 | call to NewReader | provenance | MaD:3 |
| test.go:266:18:266:24 | tarRead | test.go:611:22:611:28 | definition of tarRead | provenance | |
| test.go:283:17:283:20 | definition of file | test.go:286:41:286:44 | file | provenance | |
| test.go:266:18:266:24 | tarRead | test.go:611:22:611:28 | SSA def(tarRead) | provenance | |
| test.go:283:17:283:20 | SSA def(file) | test.go:286:41:286:44 | file | provenance | |
| test.go:286:2:286:73 | ... := ...[0] | test.go:288:2:288:12 | flateReader | provenance | |
| test.go:286:2:286:73 | ... := ...[0] | test.go:289:26:289:36 | flateReader | provenance | |
| test.go:286:41:286:44 | file | test.go:286:2:286:73 | ... := ...[0] | provenance | Config |
| test.go:289:12:289:37 | call to NewReader | test.go:291:18:291:24 | tarRead | provenance | |
| test.go:289:26:289:36 | flateReader | test.go:289:12:289:37 | call to NewReader | provenance | MaD:3 |
| test.go:291:18:291:24 | tarRead | test.go:611:22:611:28 | definition of tarRead | provenance | |
| test.go:308:20:308:23 | definition of file | test.go:311:43:311:46 | file | provenance | |
| test.go:291:18:291:24 | tarRead | test.go:611:22:611:28 | SSA def(tarRead) | provenance | |
| test.go:308:20:308:23 | SSA def(file) | test.go:311:43:311:46 | file | provenance | |
| test.go:311:2:311:47 | ... := ...[0] | test.go:313:2:313:11 | zlibReader | provenance | |
| test.go:311:2:311:47 | ... := ...[0] | test.go:314:26:314:35 | zlibReader | provenance | |
| test.go:311:43:311:46 | file | test.go:311:2:311:47 | ... := ...[0] | provenance | Config |
| test.go:314:12:314:36 | call to NewReader | test.go:316:18:316:24 | tarRead | provenance | |
| test.go:314:26:314:35 | zlibReader | test.go:314:12:314:36 | call to NewReader | provenance | MaD:3 |
| test.go:316:18:316:24 | tarRead | test.go:611:22:611:28 | definition of tarRead | provenance | |
| test.go:333:11:333:14 | definition of file | test.go:336:34:336:37 | file | provenance | |
| test.go:316:18:316:24 | tarRead | test.go:611:22:611:28 | SSA def(tarRead) | provenance | |
| test.go:333:11:333:14 | SSA def(file) | test.go:336:34:336:37 | file | provenance | |
| test.go:336:2:336:38 | ... := ...[0] | test.go:338:2:338:11 | zlibReader | provenance | |
| test.go:336:2:336:38 | ... := ...[0] | test.go:339:26:339:35 | zlibReader | provenance | |
| test.go:336:34:336:37 | file | test.go:336:2:336:38 | ... := ...[0] | provenance | Config |
| test.go:339:12:339:36 | call to NewReader | test.go:341:18:341:24 | tarRead | provenance | |
| test.go:339:26:339:35 | zlibReader | test.go:339:12:339:36 | call to NewReader | provenance | MaD:3 |
| test.go:341:18:341:24 | tarRead | test.go:611:22:611:28 | definition of tarRead | provenance | |
| test.go:358:13:358:16 | definition of file | test.go:361:35:361:38 | file | provenance | |
| test.go:341:18:341:24 | tarRead | test.go:611:22:611:28 | SSA def(tarRead) | provenance | |
| test.go:358:13:358:16 | SSA def(file) | test.go:361:35:361:38 | file | provenance | |
| test.go:361:18:361:39 | call to NewReader | test.go:363:2:363:13 | snappyReader | provenance | |
| test.go:361:18:361:39 | call to NewReader | test.go:364:2:364:13 | snappyReader | provenance | |
| test.go:361:18:361:39 | call to NewReader | test.go:365:26:365:37 | snappyReader | provenance | |
| test.go:361:35:361:38 | file | test.go:361:18:361:39 | call to NewReader | provenance | Config |
| test.go:365:12:365:38 | call to NewReader | test.go:367:18:367:24 | tarRead | provenance | |
| test.go:365:26:365:37 | snappyReader | test.go:365:12:365:38 | call to NewReader | provenance | MaD:3 |
| test.go:367:18:367:24 | tarRead | test.go:611:22:611:28 | definition of tarRead | provenance | |
| test.go:384:22:384:25 | definition of file | test.go:387:44:387:47 | file | provenance | |
| test.go:367:18:367:24 | tarRead | test.go:611:22:611:28 | SSA def(tarRead) | provenance | |
| test.go:384:22:384:25 | SSA def(file) | test.go:387:44:387:47 | file | provenance | |
| test.go:387:18:387:48 | call to NewReader | test.go:389:2:389:13 | snappyReader | provenance | |
| test.go:387:18:387:48 | call to NewReader | test.go:391:2:391:13 | snappyReader | provenance | |
| test.go:387:18:387:48 | call to NewReader | test.go:392:2:392:13 | snappyReader | provenance | |
@@ -158,8 +158,8 @@ edges
| test.go:387:44:387:47 | file | test.go:387:18:387:48 | call to NewReader | provenance | Config |
| test.go:393:12:393:38 | call to NewReader | test.go:395:18:395:24 | tarRead | provenance | |
| test.go:393:26:393:37 | snappyReader | test.go:393:12:393:38 | call to NewReader | provenance | MaD:3 |
| test.go:395:18:395:24 | tarRead | test.go:611:22:611:28 | definition of tarRead | provenance | |
| test.go:412:9:412:12 | definition of file | test.go:415:27:415:30 | file | provenance | |
| test.go:395:18:395:24 | tarRead | test.go:611:22:611:28 | SSA def(tarRead) | provenance | |
| test.go:412:9:412:12 | SSA def(file) | test.go:415:27:415:30 | file | provenance | |
| test.go:415:14:415:31 | call to NewReader | test.go:417:2:417:9 | s2Reader | provenance | |
| test.go:415:14:415:31 | call to NewReader | test.go:418:2:418:9 | s2Reader | provenance | |
| test.go:415:14:415:31 | call to NewReader | test.go:420:2:420:9 | s2Reader | provenance | |
@@ -167,35 +167,35 @@ edges
| test.go:415:27:415:30 | file | test.go:415:14:415:31 | call to NewReader | provenance | Config |
| test.go:421:12:421:34 | call to NewReader | test.go:423:18:423:24 | tarRead | provenance | |
| test.go:421:26:421:33 | s2Reader | test.go:421:12:421:34 | call to NewReader | provenance | MaD:3 |
| test.go:423:18:423:24 | tarRead | test.go:611:22:611:28 | definition of tarRead | provenance | |
| test.go:440:19:440:21 | definition of src | test.go:441:34:441:36 | src | provenance | |
| test.go:423:18:423:24 | tarRead | test.go:611:22:611:28 | SSA def(tarRead) | provenance | |
| test.go:440:19:440:21 | SSA def(src) | test.go:441:34:441:36 | src | provenance | |
| test.go:441:2:441:37 | ... := ...[0] | test.go:444:12:444:32 | type conversion | provenance | |
| test.go:441:34:441:36 | src | test.go:441:2:441:37 | ... := ...[0] | provenance | Config |
| test.go:444:12:444:32 | type conversion | test.go:445:23:445:28 | newSrc | provenance | |
| test.go:447:11:447:14 | definition of file | test.go:450:34:450:37 | file | provenance | |
| test.go:447:11:447:14 | SSA def(file) | test.go:450:34:450:37 | file | provenance | |
| test.go:450:2:450:38 | ... := ...[0] | test.go:452:2:452:11 | gzipReader | provenance | |
| test.go:450:2:450:38 | ... := ...[0] | test.go:453:26:453:35 | gzipReader | provenance | |
| test.go:450:34:450:37 | file | test.go:450:2:450:38 | ... := ...[0] | provenance | Config |
| test.go:453:12:453:36 | call to NewReader | test.go:455:18:455:24 | tarRead | provenance | |
| test.go:453:26:453:35 | gzipReader | test.go:453:12:453:36 | call to NewReader | provenance | MaD:3 |
| test.go:455:18:455:24 | tarRead | test.go:611:22:611:28 | definition of tarRead | provenance | |
| test.go:472:20:472:23 | definition of file | test.go:475:43:475:46 | file | provenance | |
| test.go:455:18:455:24 | tarRead | test.go:611:22:611:28 | SSA def(tarRead) | provenance | |
| test.go:472:20:472:23 | SSA def(file) | test.go:475:43:475:46 | file | provenance | |
| test.go:475:2:475:47 | ... := ...[0] | test.go:477:2:477:11 | gzipReader | provenance | |
| test.go:475:2:475:47 | ... := ...[0] | test.go:479:2:479:11 | gzipReader | provenance | |
| test.go:475:2:475:47 | ... := ...[0] | test.go:480:26:480:35 | gzipReader | provenance | |
| test.go:475:43:475:46 | file | test.go:475:2:475:47 | ... := ...[0] | provenance | Config |
| test.go:480:12:480:36 | call to NewReader | test.go:482:18:482:24 | tarRead | provenance | |
| test.go:480:26:480:35 | gzipReader | test.go:480:12:480:36 | call to NewReader | provenance | MaD:3 |
| test.go:482:18:482:24 | tarRead | test.go:611:22:611:28 | definition of tarRead | provenance | |
| test.go:499:20:499:23 | definition of file | test.go:502:45:502:48 | file | provenance | |
| test.go:482:18:482:24 | tarRead | test.go:611:22:611:28 | SSA def(tarRead) | provenance | |
| test.go:499:20:499:23 | SSA def(file) | test.go:502:45:502:48 | file | provenance | |
| test.go:502:2:502:49 | ... := ...[0] | test.go:504:2:504:12 | pgzipReader | provenance | |
| test.go:502:2:502:49 | ... := ...[0] | test.go:506:2:506:12 | pgzipReader | provenance | |
| test.go:502:2:502:49 | ... := ...[0] | test.go:507:26:507:36 | pgzipReader | provenance | |
| test.go:502:45:502:48 | file | test.go:502:2:502:49 | ... := ...[0] | provenance | Config |
| test.go:507:12:507:37 | call to NewReader | test.go:509:18:509:24 | tarRead | provenance | |
| test.go:507:26:507:36 | pgzipReader | test.go:507:12:507:37 | call to NewReader | provenance | MaD:3 |
| test.go:509:18:509:24 | tarRead | test.go:611:22:611:28 | definition of tarRead | provenance | |
| test.go:526:21:526:24 | definition of file | test.go:529:43:529:46 | file | provenance | |
| test.go:509:18:509:24 | tarRead | test.go:611:22:611:28 | SSA def(tarRead) | provenance | |
| test.go:526:21:526:24 | SSA def(file) | test.go:529:43:529:46 | file | provenance | |
| test.go:529:2:529:47 | ... := ...[0] | test.go:531:2:531:11 | zstdReader | provenance | |
| test.go:529:2:529:47 | ... := ...[0] | test.go:533:2:533:11 | zstdReader | provenance | |
| test.go:529:2:529:47 | ... := ...[0] | test.go:535:2:535:11 | zstdReader | provenance | |
@@ -203,33 +203,33 @@ edges
| test.go:529:43:529:46 | file | test.go:529:2:529:47 | ... := ...[0] | provenance | Config |
| test.go:536:12:536:36 | call to NewReader | test.go:538:18:538:24 | tarRead | provenance | |
| test.go:536:26:536:35 | zstdReader | test.go:536:12:536:36 | call to NewReader | provenance | MaD:3 |
| test.go:538:18:538:24 | tarRead | test.go:611:22:611:28 | definition of tarRead | provenance | |
| test.go:555:19:555:22 | definition of file | test.go:558:38:558:41 | file | provenance | |
| test.go:538:18:538:24 | tarRead | test.go:611:22:611:28 | SSA def(tarRead) | provenance | |
| test.go:555:19:555:22 | SSA def(file) | test.go:558:38:558:41 | file | provenance | |
| test.go:558:16:558:42 | call to NewReader | test.go:560:2:560:11 | zstdReader | provenance | |
| test.go:558:16:558:42 | call to NewReader | test.go:561:26:561:35 | zstdReader | provenance | |
| test.go:558:38:558:41 | file | test.go:558:16:558:42 | call to NewReader | provenance | Config |
| test.go:561:12:561:36 | call to NewReader | test.go:563:18:563:24 | tarRead | provenance | |
| test.go:561:26:561:35 | zstdReader | test.go:561:12:561:36 | call to NewReader | provenance | MaD:3 |
| test.go:563:18:563:24 | tarRead | test.go:611:22:611:28 | definition of tarRead | provenance | |
| test.go:580:9:580:12 | definition of file | test.go:583:30:583:33 | file | provenance | |
| test.go:563:18:563:24 | tarRead | test.go:611:22:611:28 | SSA def(tarRead) | provenance | |
| test.go:580:9:580:12 | SSA def(file) | test.go:583:30:583:33 | file | provenance | |
| test.go:583:2:583:34 | ... := ...[0] | test.go:585:2:585:9 | xzReader | provenance | |
| test.go:583:2:583:34 | ... := ...[0] | test.go:586:26:586:33 | xzReader | provenance | |
| test.go:583:30:583:33 | file | test.go:583:2:583:34 | ... := ...[0] | provenance | Config |
| test.go:586:12:586:34 | call to NewReader | test.go:589:18:589:24 | tarRead | provenance | |
| test.go:586:12:586:34 | call to NewReader | test.go:590:19:590:25 | tarRead | provenance | |
| test.go:586:26:586:33 | xzReader | test.go:586:12:586:34 | call to NewReader | provenance | MaD:3 |
| test.go:589:18:589:24 | tarRead | test.go:611:22:611:28 | definition of tarRead | provenance | |
| test.go:590:19:590:25 | tarRead | test.go:627:23:627:29 | definition of tarRead | provenance | |
| test.go:611:22:611:28 | definition of tarRead | test.go:621:25:621:31 | tarRead | provenance | |
| test.go:611:22:611:28 | definition of tarRead | test.go:621:25:621:31 | tarRead | provenance | |
| test.go:611:22:611:28 | definition of tarRead | test.go:621:25:621:31 | tarRead | provenance | |
| test.go:611:22:611:28 | definition of tarRead | test.go:621:25:621:31 | tarRead | provenance | |
| test.go:611:22:611:28 | definition of tarRead | test.go:621:25:621:31 | tarRead | provenance | |
| test.go:611:22:611:28 | definition of tarRead | test.go:621:25:621:31 | tarRead | provenance | |
| test.go:611:22:611:28 | definition of tarRead | test.go:621:25:621:31 | tarRead | provenance | |
| test.go:611:22:611:28 | definition of tarRead | test.go:621:25:621:31 | tarRead | provenance | |
| test.go:611:22:611:28 | definition of tarRead | test.go:621:25:621:31 | tarRead | provenance | |
| test.go:627:23:627:29 | definition of tarRead | test.go:629:2:629:8 | tarRead | provenance | |
| test.go:589:18:589:24 | tarRead | test.go:611:22:611:28 | SSA def(tarRead) | provenance | |
| test.go:590:19:590:25 | tarRead | test.go:627:23:627:29 | SSA def(tarRead) | provenance | |
| test.go:611:22:611:28 | SSA def(tarRead) | test.go:621:25:621:31 | tarRead | provenance | |
| test.go:611:22:611:28 | SSA def(tarRead) | test.go:621:25:621:31 | tarRead | provenance | |
| test.go:611:22:611:28 | SSA def(tarRead) | test.go:621:25:621:31 | tarRead | provenance | |
| test.go:611:22:611:28 | SSA def(tarRead) | test.go:621:25:621:31 | tarRead | provenance | |
| test.go:611:22:611:28 | SSA def(tarRead) | test.go:621:25:621:31 | tarRead | provenance | |
| test.go:611:22:611:28 | SSA def(tarRead) | test.go:621:25:621:31 | tarRead | provenance | |
| test.go:611:22:611:28 | SSA def(tarRead) | test.go:621:25:621:31 | tarRead | provenance | |
| test.go:611:22:611:28 | SSA def(tarRead) | test.go:621:25:621:31 | tarRead | provenance | |
| test.go:611:22:611:28 | SSA def(tarRead) | test.go:621:25:621:31 | tarRead | provenance | |
| test.go:627:23:627:29 | SSA def(tarRead) | test.go:629:2:629:8 | tarRead | provenance | |
models
| 1 | Source: net/http; Request; true; Body; ; ; ; remote; manual |
| 2 | Source: net/http; Request; true; FormValue; ; ; ReturnValue; remote; manual |
@@ -258,7 +258,7 @@ nodes
| test.go:89:17:89:28 | selection of Body | semmle.label | selection of Body |
| test.go:91:15:91:26 | selection of Body | semmle.label | selection of Body |
| test.go:93:5:93:16 | selection of Body | semmle.label | selection of Body |
| test.go:128:20:128:27 | definition of filename | semmle.label | definition of filename |
| test.go:128:20:128:27 | SSA def(filename) | semmle.label | SSA def(filename) |
| test.go:130:2:130:41 | ... := ...[0] | semmle.label | ... := ...[0] |
| test.go:130:33:130:40 | filename | semmle.label | filename |
| test.go:132:3:132:19 | ... := ...[0] | semmle.label | ... := ...[0] |
@@ -269,7 +269,7 @@ nodes
| test.go:145:12:145:12 | f | semmle.label | f |
| test.go:145:12:145:19 | call to Open | semmle.label | call to Open |
| test.go:147:37:147:38 | rc | semmle.label | rc |
| test.go:158:19:158:22 | definition of file | semmle.label | definition of file |
| test.go:158:19:158:22 | SSA def(file) | semmle.label | SSA def(file) |
| test.go:159:2:159:29 | ... := ...[0] | semmle.label | ... := ...[0] |
| test.go:159:25:159:28 | file | semmle.label | file |
| test.go:160:2:160:69 | ... := ...[0] | semmle.label | ... := ...[0] |
@@ -278,7 +278,7 @@ nodes
| test.go:163:3:163:36 | ... := ...[0] | semmle.label | ... := ...[0] |
| test.go:163:26:163:29 | file | semmle.label | file |
| test.go:164:36:164:51 | fileReaderCloser | semmle.label | fileReaderCloser |
| test.go:169:28:169:31 | definition of file | semmle.label | definition of file |
| test.go:169:28:169:31 | SSA def(file) | semmle.label | SSA def(file) |
| test.go:170:2:170:29 | ... := ...[0] | semmle.label | ... := ...[0] |
| test.go:170:25:170:28 | file | semmle.label | file |
| test.go:171:2:171:78 | ... := ...[0] | semmle.label | ... := ...[0] |
@@ -287,56 +287,56 @@ nodes
| test.go:175:26:175:29 | file | semmle.label | file |
| test.go:175:26:175:36 | call to Open | semmle.label | call to Open |
| test.go:176:36:176:51 | fileReaderCloser | semmle.label | fileReaderCloser |
| test.go:181:17:181:20 | definition of file | semmle.label | definition of file |
| test.go:181:17:181:20 | SSA def(file) | semmle.label | SSA def(file) |
| test.go:184:2:184:73 | ... := ...[0] | semmle.label | ... := ...[0] |
| test.go:184:41:184:44 | file | semmle.label | file |
| test.go:186:2:186:12 | bzip2Reader | semmle.label | bzip2Reader |
| test.go:187:12:187:37 | call to NewReader | semmle.label | call to NewReader |
| test.go:187:26:187:36 | bzip2Reader | semmle.label | bzip2Reader |
| test.go:189:18:189:24 | tarRead | semmle.label | tarRead |
| test.go:208:12:208:15 | definition of file | semmle.label | definition of file |
| test.go:208:12:208:15 | SSA def(file) | semmle.label | SSA def(file) |
| test.go:211:17:211:37 | call to NewReader | semmle.label | call to NewReader |
| test.go:211:33:211:36 | file | semmle.label | file |
| test.go:213:2:213:12 | bzip2Reader | semmle.label | bzip2Reader |
| test.go:214:12:214:37 | call to NewReader | semmle.label | call to NewReader |
| test.go:214:26:214:36 | bzip2Reader | semmle.label | bzip2Reader |
| test.go:216:18:216:24 | tarRead | semmle.label | tarRead |
| test.go:233:12:233:15 | definition of file | semmle.label | definition of file |
| test.go:233:12:233:15 | SSA def(file) | semmle.label | SSA def(file) |
| test.go:236:17:236:37 | call to NewReader | semmle.label | call to NewReader |
| test.go:236:33:236:36 | file | semmle.label | file |
| test.go:238:2:238:12 | flateReader | semmle.label | flateReader |
| test.go:239:12:239:37 | call to NewReader | semmle.label | call to NewReader |
| test.go:239:26:239:36 | flateReader | semmle.label | flateReader |
| test.go:241:18:241:24 | tarRead | semmle.label | tarRead |
| test.go:258:21:258:24 | definition of file | semmle.label | definition of file |
| test.go:258:21:258:24 | SSA def(file) | semmle.label | SSA def(file) |
| test.go:261:17:261:46 | call to NewReader | semmle.label | call to NewReader |
| test.go:261:42:261:45 | file | semmle.label | file |
| test.go:263:2:263:12 | flateReader | semmle.label | flateReader |
| test.go:264:12:264:37 | call to NewReader | semmle.label | call to NewReader |
| test.go:264:26:264:36 | flateReader | semmle.label | flateReader |
| test.go:266:18:266:24 | tarRead | semmle.label | tarRead |
| test.go:283:17:283:20 | definition of file | semmle.label | definition of file |
| test.go:283:17:283:20 | SSA def(file) | semmle.label | SSA def(file) |
| test.go:286:2:286:73 | ... := ...[0] | semmle.label | ... := ...[0] |
| test.go:286:41:286:44 | file | semmle.label | file |
| test.go:288:2:288:12 | flateReader | semmle.label | flateReader |
| test.go:289:12:289:37 | call to NewReader | semmle.label | call to NewReader |
| test.go:289:26:289:36 | flateReader | semmle.label | flateReader |
| test.go:291:18:291:24 | tarRead | semmle.label | tarRead |
| test.go:308:20:308:23 | definition of file | semmle.label | definition of file |
| test.go:308:20:308:23 | SSA def(file) | semmle.label | SSA def(file) |
| test.go:311:2:311:47 | ... := ...[0] | semmle.label | ... := ...[0] |
| test.go:311:43:311:46 | file | semmle.label | file |
| test.go:313:2:313:11 | zlibReader | semmle.label | zlibReader |
| test.go:314:12:314:36 | call to NewReader | semmle.label | call to NewReader |
| test.go:314:26:314:35 | zlibReader | semmle.label | zlibReader |
| test.go:316:18:316:24 | tarRead | semmle.label | tarRead |
| test.go:333:11:333:14 | definition of file | semmle.label | definition of file |
| test.go:333:11:333:14 | SSA def(file) | semmle.label | SSA def(file) |
| test.go:336:2:336:38 | ... := ...[0] | semmle.label | ... := ...[0] |
| test.go:336:34:336:37 | file | semmle.label | file |
| test.go:338:2:338:11 | zlibReader | semmle.label | zlibReader |
| test.go:339:12:339:36 | call to NewReader | semmle.label | call to NewReader |
| test.go:339:26:339:35 | zlibReader | semmle.label | zlibReader |
| test.go:341:18:341:24 | tarRead | semmle.label | tarRead |
| test.go:358:13:358:16 | definition of file | semmle.label | definition of file |
| test.go:358:13:358:16 | SSA def(file) | semmle.label | SSA def(file) |
| test.go:361:18:361:39 | call to NewReader | semmle.label | call to NewReader |
| test.go:361:35:361:38 | file | semmle.label | file |
| test.go:363:2:363:13 | snappyReader | semmle.label | snappyReader |
@@ -344,7 +344,7 @@ nodes
| test.go:365:12:365:38 | call to NewReader | semmle.label | call to NewReader |
| test.go:365:26:365:37 | snappyReader | semmle.label | snappyReader |
| test.go:367:18:367:24 | tarRead | semmle.label | tarRead |
| test.go:384:22:384:25 | definition of file | semmle.label | definition of file |
| test.go:384:22:384:25 | SSA def(file) | semmle.label | SSA def(file) |
| test.go:387:18:387:48 | call to NewReader | semmle.label | call to NewReader |
| test.go:387:44:387:47 | file | semmle.label | file |
| test.go:389:2:389:13 | snappyReader | semmle.label | snappyReader |
@@ -353,7 +353,7 @@ nodes
| test.go:393:12:393:38 | call to NewReader | semmle.label | call to NewReader |
| test.go:393:26:393:37 | snappyReader | semmle.label | snappyReader |
| test.go:395:18:395:24 | tarRead | semmle.label | tarRead |
| test.go:412:9:412:12 | definition of file | semmle.label | definition of file |
| test.go:412:9:412:12 | SSA def(file) | semmle.label | SSA def(file) |
| test.go:415:14:415:31 | call to NewReader | semmle.label | call to NewReader |
| test.go:415:27:415:30 | file | semmle.label | file |
| test.go:417:2:417:9 | s2Reader | semmle.label | s2Reader |
@@ -362,19 +362,19 @@ nodes
| test.go:421:12:421:34 | call to NewReader | semmle.label | call to NewReader |
| test.go:421:26:421:33 | s2Reader | semmle.label | s2Reader |
| test.go:423:18:423:24 | tarRead | semmle.label | tarRead |
| test.go:440:19:440:21 | definition of src | semmle.label | definition of src |
| test.go:440:19:440:21 | SSA def(src) | semmle.label | SSA def(src) |
| test.go:441:2:441:37 | ... := ...[0] | semmle.label | ... := ...[0] |
| test.go:441:34:441:36 | src | semmle.label | src |
| test.go:444:12:444:32 | type conversion | semmle.label | type conversion |
| test.go:445:23:445:28 | newSrc | semmle.label | newSrc |
| test.go:447:11:447:14 | definition of file | semmle.label | definition of file |
| test.go:447:11:447:14 | SSA def(file) | semmle.label | SSA def(file) |
| test.go:450:2:450:38 | ... := ...[0] | semmle.label | ... := ...[0] |
| test.go:450:34:450:37 | file | semmle.label | file |
| test.go:452:2:452:11 | gzipReader | semmle.label | gzipReader |
| test.go:453:12:453:36 | call to NewReader | semmle.label | call to NewReader |
| test.go:453:26:453:35 | gzipReader | semmle.label | gzipReader |
| test.go:455:18:455:24 | tarRead | semmle.label | tarRead |
| test.go:472:20:472:23 | definition of file | semmle.label | definition of file |
| test.go:472:20:472:23 | SSA def(file) | semmle.label | SSA def(file) |
| test.go:475:2:475:47 | ... := ...[0] | semmle.label | ... := ...[0] |
| test.go:475:43:475:46 | file | semmle.label | file |
| test.go:477:2:477:11 | gzipReader | semmle.label | gzipReader |
@@ -382,7 +382,7 @@ nodes
| test.go:480:12:480:36 | call to NewReader | semmle.label | call to NewReader |
| test.go:480:26:480:35 | gzipReader | semmle.label | gzipReader |
| test.go:482:18:482:24 | tarRead | semmle.label | tarRead |
| test.go:499:20:499:23 | definition of file | semmle.label | definition of file |
| test.go:499:20:499:23 | SSA def(file) | semmle.label | SSA def(file) |
| test.go:502:2:502:49 | ... := ...[0] | semmle.label | ... := ...[0] |
| test.go:502:45:502:48 | file | semmle.label | file |
| test.go:504:2:504:12 | pgzipReader | semmle.label | pgzipReader |
@@ -390,7 +390,7 @@ nodes
| test.go:507:12:507:37 | call to NewReader | semmle.label | call to NewReader |
| test.go:507:26:507:36 | pgzipReader | semmle.label | pgzipReader |
| test.go:509:18:509:24 | tarRead | semmle.label | tarRead |
| test.go:526:21:526:24 | definition of file | semmle.label | definition of file |
| test.go:526:21:526:24 | SSA def(file) | semmle.label | SSA def(file) |
| test.go:529:2:529:47 | ... := ...[0] | semmle.label | ... := ...[0] |
| test.go:529:43:529:46 | file | semmle.label | file |
| test.go:531:2:531:11 | zstdReader | semmle.label | zstdReader |
@@ -399,14 +399,14 @@ nodes
| test.go:536:12:536:36 | call to NewReader | semmle.label | call to NewReader |
| test.go:536:26:536:35 | zstdReader | semmle.label | zstdReader |
| test.go:538:18:538:24 | tarRead | semmle.label | tarRead |
| test.go:555:19:555:22 | definition of file | semmle.label | definition of file |
| test.go:555:19:555:22 | SSA def(file) | semmle.label | SSA def(file) |
| test.go:558:16:558:42 | call to NewReader | semmle.label | call to NewReader |
| test.go:558:38:558:41 | file | semmle.label | file |
| test.go:560:2:560:11 | zstdReader | semmle.label | zstdReader |
| test.go:561:12:561:36 | call to NewReader | semmle.label | call to NewReader |
| test.go:561:26:561:35 | zstdReader | semmle.label | zstdReader |
| test.go:563:18:563:24 | tarRead | semmle.label | tarRead |
| test.go:580:9:580:12 | definition of file | semmle.label | definition of file |
| test.go:580:9:580:12 | SSA def(file) | semmle.label | SSA def(file) |
| test.go:583:2:583:34 | ... := ...[0] | semmle.label | ... := ...[0] |
| test.go:583:30:583:33 | file | semmle.label | file |
| test.go:585:2:585:9 | xzReader | semmle.label | xzReader |
@@ -414,15 +414,15 @@ nodes
| test.go:586:26:586:33 | xzReader | semmle.label | xzReader |
| test.go:589:18:589:24 | tarRead | semmle.label | tarRead |
| test.go:590:19:590:25 | tarRead | semmle.label | tarRead |
| test.go:611:22:611:28 | definition of tarRead | semmle.label | definition of tarRead |
| test.go:611:22:611:28 | definition of tarRead | semmle.label | definition of tarRead |
| test.go:611:22:611:28 | definition of tarRead | semmle.label | definition of tarRead |
| test.go:611:22:611:28 | definition of tarRead | semmle.label | definition of tarRead |
| test.go:611:22:611:28 | definition of tarRead | semmle.label | definition of tarRead |
| test.go:611:22:611:28 | definition of tarRead | semmle.label | definition of tarRead |
| test.go:611:22:611:28 | definition of tarRead | semmle.label | definition of tarRead |
| test.go:611:22:611:28 | definition of tarRead | semmle.label | definition of tarRead |
| test.go:611:22:611:28 | definition of tarRead | semmle.label | definition of tarRead |
| test.go:611:22:611:28 | SSA def(tarRead) | semmle.label | SSA def(tarRead) |
| test.go:611:22:611:28 | SSA def(tarRead) | semmle.label | SSA def(tarRead) |
| test.go:611:22:611:28 | SSA def(tarRead) | semmle.label | SSA def(tarRead) |
| test.go:611:22:611:28 | SSA def(tarRead) | semmle.label | SSA def(tarRead) |
| test.go:611:22:611:28 | SSA def(tarRead) | semmle.label | SSA def(tarRead) |
| test.go:611:22:611:28 | SSA def(tarRead) | semmle.label | SSA def(tarRead) |
| test.go:611:22:611:28 | SSA def(tarRead) | semmle.label | SSA def(tarRead) |
| test.go:611:22:611:28 | SSA def(tarRead) | semmle.label | SSA def(tarRead) |
| test.go:611:22:611:28 | SSA def(tarRead) | semmle.label | SSA def(tarRead) |
| test.go:621:25:621:31 | tarRead | semmle.label | tarRead |
| test.go:621:25:621:31 | tarRead | semmle.label | tarRead |
| test.go:621:25:621:31 | tarRead | semmle.label | tarRead |
@@ -432,6 +432,6 @@ nodes
| test.go:621:25:621:31 | tarRead | semmle.label | tarRead |
| test.go:621:25:621:31 | tarRead | semmle.label | tarRead |
| test.go:621:25:621:31 | tarRead | semmle.label | tarRead |
| test.go:627:23:627:29 | definition of tarRead | semmle.label | definition of tarRead |
| test.go:627:23:627:29 | SSA def(tarRead) | semmle.label | SSA def(tarRead) |
| test.go:629:2:629:8 | tarRead | semmle.label | tarRead |
subpaths

View File

@@ -22,8 +22,8 @@ edges
| WrongUsageOfUnsafe.go:166:33:166:57 | type conversion | WrongUsageOfUnsafe.go:166:16:166:58 | type conversion | provenance | |
| WrongUsageOfUnsafe.go:189:31:189:55 | type conversion | WrongUsageOfUnsafe.go:189:16:189:56 | type conversion | provenance | |
| WrongUsageOfUnsafe.go:211:31:211:60 | type conversion | WrongUsageOfUnsafe.go:211:16:211:61 | type conversion | provenance | |
| WrongUsageOfUnsafe.go:227:31:227:55 | type conversion | WrongUsageOfUnsafe.go:236:21:236:23 | definition of req | provenance | |
| WrongUsageOfUnsafe.go:236:21:236:23 | definition of req | WrongUsageOfUnsafe.go:243:9:243:27 | type conversion | provenance | |
| WrongUsageOfUnsafe.go:227:31:227:55 | type conversion | WrongUsageOfUnsafe.go:236:21:236:23 | SSA def(req) | provenance | |
| WrongUsageOfUnsafe.go:236:21:236:23 | SSA def(req) | WrongUsageOfUnsafe.go:243:9:243:27 | type conversion | provenance | |
| WrongUsageOfUnsafe.go:256:28:256:52 | type conversion | WrongUsageOfUnsafe.go:256:16:256:53 | type conversion | provenance | |
| WrongUsageOfUnsafe.go:274:25:274:49 | type conversion | WrongUsageOfUnsafe.go:274:16:274:50 | type conversion | provenance | |
| WrongUsageOfUnsafe.go:292:23:292:47 | type conversion | WrongUsageOfUnsafe.go:292:16:292:48 | type conversion | provenance | |
@@ -51,7 +51,7 @@ nodes
| WrongUsageOfUnsafe.go:211:16:211:61 | type conversion | semmle.label | type conversion |
| WrongUsageOfUnsafe.go:211:31:211:60 | type conversion | semmle.label | type conversion |
| WrongUsageOfUnsafe.go:227:31:227:55 | type conversion | semmle.label | type conversion |
| WrongUsageOfUnsafe.go:236:21:236:23 | definition of req | semmle.label | definition of req |
| WrongUsageOfUnsafe.go:236:21:236:23 | SSA def(req) | semmle.label | SSA def(req) |
| WrongUsageOfUnsafe.go:243:9:243:27 | type conversion | semmle.label | type conversion |
| WrongUsageOfUnsafe.go:256:16:256:53 | type conversion | semmle.label | type conversion |
| WrongUsageOfUnsafe.go:256:28:256:52 | type conversion | semmle.label | type conversion |

View File

@@ -13,7 +13,7 @@ func logSomething(entry *logrus.Entry) {
entry.Traceln(text) // $ logger=text
}
func logrusCalls() {
func logrusCalls(selector int) {
err := errors.New("Error")
var fields logrus.Fields = nil
var fn logrus.LogFunction = nil
@@ -27,11 +27,15 @@ func logrusCalls() {
tmp = logrus.WithFields(fields) // $ logger=fields
logSomething(tmp)
logrus.Error(text) // $ logger=text
logrus.Fatalf(fmt, text) // $ logger=fmt logger=text
logrus.Panicln(text) // $ logger=text
logrus.Infof(fmt, text) // $ logger=fmt logger=text
logrus.FatalFn(fn) // $ logger=fn
logrus.Error(text) // $ logger=text
logrus.Infof(fmt, text) // $ logger=fmt logger=text
if selector == 0 {
logrus.Fatalf(fmt, text) // $ logger=fmt logger=text
} else if selector == 1 {
logrus.Panicln(text) // $ logger=text
} else if selector == 2 {
logrus.FatalFn(fn) // $ logger=fn
}
// components corresponding to the format specifier "%T" are not considered vulnerable
logrus.Infof("%s: found type %T", text, v) // $ logger="%s: found type %T" logger=text type-logger=v

View File

@@ -8,6 +8,6 @@ var v []byte
func main() {
glogTest(len(v))
stdlib()
stdlib(len(v))
slogTest()
}

View File

@@ -4,37 +4,69 @@ import (
"log"
)
func stdlib() {
func stdlib(selector int) {
var logger log.Logger
logger.SetPrefix("prefix: ")
logger.Fatal(text) // $ logger=text
logger.Fatalf(fmt, text) // $ logger=fmt logger=text
logger.Fatalln(text) // $ logger=text
logger.Panic(text) // $ logger=text
logger.Panicf(fmt, text) // $ logger=fmt logger=text
logger.Panicln(text) // $ logger=text
logger.Print(text) // $ logger=text
logger.Printf(fmt, text) // $ logger=fmt logger=text
logger.Println(text) // $ logger=text
switch selector {
case 0:
logger.Fatal(text) // $ logger=text
case 1:
logger.Fatalf(fmt, text) // $ logger=fmt logger=text
case 2:
logger.Fatalln(text) // $ logger=text
case 3:
logger.Panic(text) // $ logger=text
case 4:
logger.Panicf(fmt, text) // $ logger=fmt logger=text
case 5:
logger.Panicln(text) // $ logger=text
case 6:
logger.Print(text) // $ logger=text
case 7:
logger.Printf(fmt, text) // $ logger=fmt logger=text
case 8:
logger.Println(text) // $ logger=text
}
// components corresponding to the format specifier "%T" are not considered vulnerable
logger.Fatalf("%s: found type %T", text, v) // $ logger="%s: found type %T" logger=text type-logger=v
logger.Panicf("%s: found type %T", text, v) // $ logger="%s: found type %T" logger=text type-logger=v
logger.Printf("%s: found type %T", text, v) // $ logger="%s: found type %T" logger=text type-logger=v
switch selector {
case 9:
logger.Fatalf("%s: found type %T", text, v) // $ logger="%s: found type %T" logger=text type-logger=v
case 10:
logger.Panicf("%s: found type %T", text, v) // $ logger="%s: found type %T" logger=text type-logger=v
case 11:
logger.Printf("%s: found type %T", text, v) // $ logger="%s: found type %T" logger=text type-logger=v
}
log.SetPrefix("prefix: ")
log.Fatal(text) // $ logger=text
log.Fatalf(fmt, text) // $ logger=fmt logger=text
log.Fatalln(text) // $ logger=text
log.Panic(text) // $ logger=text
log.Panicf(fmt, text) // $ logger=fmt logger=text
log.Panicln(text) // $ logger=text
log.Print(text) // $ logger=text
log.Printf(fmt, text) // $ logger=fmt logger=text
log.Println(text) // $ logger=text
switch selector {
case 12:
log.Fatal(text) // $ logger=text
case 13:
log.Fatalf(fmt, text) // $ logger=fmt logger=text
case 14:
log.Fatalln(text) // $ logger=text
case 15:
log.Panic(text) // $ logger=text
case 16:
log.Panicf(fmt, text) // $ logger=fmt logger=text
case 17:
log.Panicln(text) // $ logger=text
case 18:
log.Print(text) // $ logger=text
case 19:
log.Printf(fmt, text) // $ logger=fmt logger=text
case 20:
log.Println(text) // $ logger=text
}
// components corresponding to the format specifier "%T" are not considered vulnerable
log.Fatalf("%s: found type %T", text, v) // $ logger="%s: found type %T" logger=text type-logger=v
log.Panicf("%s: found type %T", text, v) // $ logger="%s: found type %T" logger=text type-logger=v
log.Printf("%s: found type %T", text, v) // $ logger="%s: found type %T" logger=text type-logger=v
switch selector {
case 21:
log.Fatalf("%s: found type %T", text, v) // $ logger="%s: found type %T" logger=text type-logger=v
case 22:
log.Panicf("%s: found type %T", text, v) // $ logger="%s: found type %T" logger=text type-logger=v
case 23:
log.Printf("%s: found type %T", text, v) // $ logger="%s: found type %T" logger=text type-logger=v
}
}

View File

@@ -3,7 +3,7 @@
| stdlib.go:13:21:13:24 | "ab" | ab | stdlib.go:13:21:13:24 | "ab" |
| stdlib.go:15:26:15:39 | "[so]me\|regex" | [so]me\|regex | stdlib.go:15:2:15:40 | ... := ...[0] |
| stdlib.go:15:26:15:39 | "[so]me\|regex" | [so]me\|regex | stdlib.go:15:26:15:39 | "[so]me\|regex" |
| stdlib.go:16:30:16:37 | "posix?" | posix? | stdlib.go:16:2:16:3 | definition of re |
| stdlib.go:16:30:16:37 | "posix?" | posix? | stdlib.go:16:2:16:3 | SSA def(re) |
| stdlib.go:16:30:16:37 | "posix?" | posix? | stdlib.go:16:2:16:38 | ... = ...[0] |
| stdlib.go:16:30:16:37 | "posix?" | posix? | stdlib.go:16:30:16:37 | "posix?" |
| stdlib.go:16:30:16:37 | "posix?" | posix? | stdlib.go:17:2:17:3 | re |

View File

@@ -34,6 +34,265 @@
| DuplicateSwitchCase.go:16:1:16:14 | function declaration | DuplicateSwitchCase.go:0:0:0:0 | exit |
| DuplicateSwitchCase.go:16:6:16:9 | skip | DuplicateSwitchCase.go:16:1:16:14 | function declaration |
| DuplicateSwitchCase.go:16:13:16:14 | skip | DuplicateSwitchCase.go:16:1:16:14 | exit |
| epilogues.go:0:0:0:0 | entry | epilogues.go:3:1:3:12 | skip |
| epilogues.go:3:1:3:12 | skip | epilogues.go:8:1:10:1 | skip |
| epilogues.go:8:1:10:1 | skip | epilogues.go:12:21:12:23 | skip |
| epilogues.go:12:1:14:1 | entry | epilogues.go:12:7:12:7 | argument corresponding to l |
| epilogues.go:12:1:14:1 | function declaration | epilogues.go:16:20:16:27 | skip |
| epilogues.go:12:7:12:7 | argument corresponding to l | epilogues.go:12:7:12:7 | initialization of l |
| epilogues.go:12:7:12:7 | initialization of l | epilogues.go:12:25:12:27 | argument corresponding to msg |
| epilogues.go:12:21:12:23 | skip | epilogues.go:12:1:14:1 | function declaration |
| epilogues.go:12:25:12:27 | argument corresponding to msg | epilogues.go:12:25:12:27 | initialization of msg |
| epilogues.go:12:25:12:27 | initialization of msg | epilogues.go:12:37:12:40 | argument corresponding to code |
| epilogues.go:12:37:12:40 | argument corresponding to code | epilogues.go:12:37:12:40 | initialization of code |
| epilogues.go:12:37:12:40 | initialization of code | epilogues.go:13:2:13:12 | selection of Println |
| epilogues.go:13:2:13:12 | selection of Println | epilogues.go:13:14:13:14 | l |
| epilogues.go:13:2:13:33 | call to Println | epilogues.go:12:1:14:1 | exit |
| epilogues.go:13:14:13:14 | implicit dereference | epilogues.go:12:1:14:1 | exit |
| epilogues.go:13:14:13:14 | implicit dereference | epilogues.go:13:14:13:21 | selection of prefix |
| epilogues.go:13:14:13:14 | l | epilogues.go:13:14:13:14 | implicit dereference |
| epilogues.go:13:14:13:21 | selection of prefix | epilogues.go:13:24:13:26 | msg |
| epilogues.go:13:24:13:26 | msg | epilogues.go:13:29:13:32 | code |
| epilogues.go:13:29:13:32 | code | epilogues.go:13:2:13:33 | call to Println |
| epilogues.go:16:1:18:1 | entry | epilogues.go:16:7:16:7 | argument corresponding to l |
| epilogues.go:16:1:18:1 | function declaration | epilogues.go:23:6:23:15 | skip |
| epilogues.go:16:7:16:7 | argument corresponding to l | epilogues.go:16:7:16:7 | initialization of l |
| epilogues.go:16:7:16:7 | initialization of l | epilogues.go:16:29:16:31 | argument corresponding to msg |
| epilogues.go:16:20:16:27 | skip | epilogues.go:16:1:18:1 | function declaration |
| epilogues.go:16:29:16:31 | argument corresponding to msg | epilogues.go:16:29:16:31 | initialization of msg |
| epilogues.go:16:29:16:31 | initialization of msg | epilogues.go:17:2:17:12 | selection of Println |
| epilogues.go:17:2:17:12 | selection of Println | epilogues.go:17:14:17:14 | l |
| epilogues.go:17:2:17:27 | call to Println | epilogues.go:16:1:18:1 | exit |
| epilogues.go:17:14:17:14 | l | epilogues.go:17:14:17:21 | selection of prefix |
| epilogues.go:17:14:17:21 | selection of prefix | epilogues.go:17:24:17:26 | msg |
| epilogues.go:17:24:17:26 | msg | epilogues.go:17:2:17:27 | call to Println |
| epilogues.go:23:1:27:1 | entry | epilogues.go:24:5:24:5 | skip |
| epilogues.go:23:1:27:1 | function declaration | epilogues.go:31:6:31:13 | skip |
| epilogues.go:23:6:23:15 | skip | epilogues.go:23:1:27:1 | function declaration |
| epilogues.go:24:5:24:5 | assignment to r | epilogues.go:24:21:24:21 | r |
| epilogues.go:24:5:24:5 | skip | epilogues.go:24:10:24:16 | recover |
| epilogues.go:24:10:24:16 | recover | epilogues.go:24:10:24:18 | call to recover |
| epilogues.go:24:10:24:18 | call to recover | epilogues.go:24:5:24:5 | assignment to r |
| epilogues.go:24:21:24:21 | r | epilogues.go:24:26:24:28 | nil |
| epilogues.go:24:21:24:28 | ...!=... | epilogues.go:23:1:27:1 | exit |
| epilogues.go:24:21:24:28 | ...!=... | epilogues.go:24:21:24:28 | ...!=... is false |
| epilogues.go:24:21:24:28 | ...!=... | epilogues.go:24:21:24:28 | ...!=... is true |
| epilogues.go:24:21:24:28 | ...!=... is false | epilogues.go:23:1:27:1 | exit |
| epilogues.go:24:21:24:28 | ...!=... is true | epilogues.go:25:3:25:13 | selection of Println |
| epilogues.go:24:26:24:28 | nil | epilogues.go:24:21:24:28 | ...!=... |
| epilogues.go:25:3:25:13 | selection of Println | epilogues.go:25:15:25:26 | "recovered:" |
| epilogues.go:25:3:25:30 | call to Println | epilogues.go:23:1:27:1 | exit |
| epilogues.go:25:15:25:26 | "recovered:" | epilogues.go:25:29:25:29 | r |
| epilogues.go:25:29:25:29 | r | epilogues.go:25:3:25:30 | call to Println |
| epilogues.go:31:1:33:1 | entry | epilogues.go:31:15:31:15 | argument corresponding to x |
| epilogues.go:31:1:33:1 | function declaration | epilogues.go:36:6:36:12 | skip |
| epilogues.go:31:6:31:13 | skip | epilogues.go:31:1:33:1 | function declaration |
| epilogues.go:31:15:31:15 | argument corresponding to x | epilogues.go:31:15:31:15 | initialization of x |
| epilogues.go:31:15:31:15 | initialization of x | epilogues.go:32:9:32:9 | x |
| epilogues.go:32:2:32:13 | return statement | epilogues.go:31:1:33:1 | exit |
| epilogues.go:32:9:32:9 | x | epilogues.go:32:13:32:13 | 2 |
| epilogues.go:32:9:32:13 | ...*... | epilogues.go:32:2:32:13 | return statement |
| epilogues.go:32:13:32:13 | 2 | epilogues.go:32:9:32:13 | ...*... |
| epilogues.go:36:1:38:1 | entry | epilogues.go:37:2:37:12 | selection of Println |
| epilogues.go:36:1:38:1 | function declaration | epilogues.go:42:6:42:18 | skip |
| epilogues.go:36:6:36:12 | skip | epilogues.go:36:1:38:1 | function declaration |
| epilogues.go:37:2:37:12 | selection of Println | epilogues.go:37:14:37:19 | "void" |
| epilogues.go:37:2:37:20 | call to Println | epilogues.go:36:1:38:1 | exit |
| epilogues.go:37:14:37:19 | "void" | epilogues.go:37:2:37:20 | call to Println |
| epilogues.go:42:1:48:1 | entry | epilogues.go:42:20:42:20 | argument corresponding to x |
| epilogues.go:42:1:48:1 | function declaration | epilogues.go:51:6:51:21 | skip |
| epilogues.go:42:6:42:18 | skip | epilogues.go:42:1:48:1 | function declaration |
| epilogues.go:42:20:42:20 | argument corresponding to x | epilogues.go:42:20:42:20 | initialization of x |
| epilogues.go:42:20:42:20 | initialization of x | epilogues.go:42:28:42:33 | zero value for result |
| epilogues.go:42:28:42:33 | implicit read of result | epilogues.go:42:40:42:42 | implicit read of err |
| epilogues.go:42:28:42:33 | initialization of result | epilogues.go:42:40:42:42 | zero value for err |
| epilogues.go:42:28:42:33 | zero value for result | epilogues.go:42:28:42:33 | initialization of result |
| epilogues.go:42:40:42:42 | implicit read of err | epilogues.go:42:1:48:1 | exit |
| epilogues.go:42:40:42:42 | initialization of err | epilogues.go:43:5:43:5 | x |
| epilogues.go:42:40:42:42 | zero value for err | epilogues.go:42:40:42:42 | initialization of err |
| epilogues.go:43:5:43:5 | x | epilogues.go:43:9:43:9 | 0 |
| epilogues.go:43:5:43:9 | ...<... | epilogues.go:43:5:43:9 | ...<... is false |
| epilogues.go:43:5:43:9 | ...<... | epilogues.go:43:5:43:9 | ...<... is true |
| epilogues.go:43:5:43:9 | ...<... is false | epilogues.go:47:9:47:9 | x |
| epilogues.go:43:5:43:9 | ...<... is true | epilogues.go:44:3:44:8 | skip |
| epilogues.go:43:9:43:9 | 0 | epilogues.go:43:5:43:9 | ...<... |
| epilogues.go:44:3:44:8 | assignment to result | epilogues.go:45:3:45:8 | return statement |
| epilogues.go:44:3:44:8 | skip | epilogues.go:44:13:44:13 | x |
| epilogues.go:44:12:44:13 | -... | epilogues.go:44:3:44:8 | assignment to result |
| epilogues.go:44:13:44:13 | x | epilogues.go:44:12:44:13 | -... |
| epilogues.go:45:3:45:8 | return statement | epilogues.go:42:28:42:33 | implicit read of result |
| epilogues.go:47:2:47:14 | return statement | epilogues.go:42:28:42:33 | implicit read of result |
| epilogues.go:47:9:47:9 | implicit write of result | epilogues.go:47:12:47:14 | nil |
| epilogues.go:47:9:47:9 | x | epilogues.go:47:9:47:9 | implicit write of result |
| epilogues.go:47:12:47:14 | implicit write of err | epilogues.go:47:2:47:14 | return statement |
| epilogues.go:47:12:47:14 | nil | epilogues.go:47:12:47:14 | implicit write of err |
| epilogues.go:51:1:54:1 | entry | epilogues.go:51:23:51:23 | argument corresponding to x |
| epilogues.go:51:1:54:1 | function declaration | epilogues.go:59:6:59:25 | skip |
| epilogues.go:51:6:51:21 | skip | epilogues.go:51:1:54:1 | function declaration |
| epilogues.go:51:23:51:23 | argument corresponding to x | epilogues.go:51:23:51:23 | initialization of x |
| epilogues.go:51:23:51:23 | initialization of x | epilogues.go:51:31:51:31 | zero value for n |
| epilogues.go:51:31:51:31 | implicit read of n | epilogues.go:51:1:54:1 | exit |
| epilogues.go:51:31:51:31 | initialization of n | epilogues.go:52:2:52:2 | skip |
| epilogues.go:51:31:51:31 | zero value for n | epilogues.go:51:31:51:31 | initialization of n |
| epilogues.go:52:2:52:2 | assignment to n | epilogues.go:53:2:53:7 | return statement |
| epilogues.go:52:2:52:2 | skip | epilogues.go:52:6:52:6 | x |
| epilogues.go:52:6:52:6 | x | epilogues.go:52:10:52:10 | 1 |
| epilogues.go:52:6:52:10 | ...+... | epilogues.go:52:2:52:2 | assignment to n |
| epilogues.go:52:10:52:10 | 1 | epilogues.go:52:6:52:10 | ...+... |
| epilogues.go:53:2:53:7 | return statement | epilogues.go:51:31:51:31 | implicit read of n |
| epilogues.go:59:1:62:1 | entry | epilogues.go:59:27:59:27 | argument corresponding to l |
| epilogues.go:59:1:62:1 | function declaration | epilogues.go:66:6:66:26 | skip |
| epilogues.go:59:6:59:25 | skip | epilogues.go:59:1:62:1 | function declaration |
| epilogues.go:59:27:59:27 | argument corresponding to l | epilogues.go:59:27:59:27 | initialization of l |
| epilogues.go:59:27:59:27 | initialization of l | epilogues.go:59:41:59:45 | argument corresponding to items |
| epilogues.go:59:41:59:45 | argument corresponding to items | epilogues.go:59:41:59:45 | initialization of items |
| epilogues.go:59:41:59:45 | initialization of items | epilogues.go:60:8:60:8 | l |
| epilogues.go:60:2:60:33 | defer statement | epilogues.go:61:2:61:12 | selection of Println |
| epilogues.go:60:8:60:8 | l | epilogues.go:60:8:60:12 | selection of log |
| epilogues.go:60:8:60:12 | selection of log | epilogues.go:60:14:60:20 | "count" |
| epilogues.go:60:8:60:33 | call to log | epilogues.go:59:1:62:1 | exit |
| epilogues.go:60:14:60:20 | "count" | epilogues.go:60:23:60:25 | len |
| epilogues.go:60:23:60:25 | len | epilogues.go:60:27:60:31 | items |
| epilogues.go:60:23:60:32 | call to len | epilogues.go:60:2:60:33 | defer statement |
| epilogues.go:60:27:60:31 | items | epilogues.go:60:23:60:32 | call to len |
| epilogues.go:61:2:61:12 | selection of Println | epilogues.go:61:14:61:25 | "processing" |
| epilogues.go:61:2:61:38 | call to Println | epilogues.go:60:8:60:33 | call to log |
| epilogues.go:61:14:61:25 | "processing" | epilogues.go:61:28:61:30 | len |
| epilogues.go:61:28:61:30 | len | epilogues.go:61:32:61:36 | items |
| epilogues.go:61:28:61:37 | call to len | epilogues.go:61:2:61:38 | call to Println |
| epilogues.go:61:32:61:36 | items | epilogues.go:61:28:61:37 | call to len |
| epilogues.go:66:1:71:1 | entry | epilogues.go:66:28:66:33 | argument corresponding to prefix |
| epilogues.go:66:1:71:1 | function declaration | epilogues.go:77:6:77:20 | skip |
| epilogues.go:66:6:66:26 | skip | epilogues.go:66:1:71:1 | function declaration |
| epilogues.go:66:28:66:33 | argument corresponding to prefix | epilogues.go:66:28:66:33 | initialization of prefix |
| epilogues.go:66:28:66:33 | initialization of prefix | epilogues.go:67:2:67:2 | skip |
| epilogues.go:67:2:67:2 | assignment to l | epilogues.go:68:8:68:8 | l |
| epilogues.go:67:2:67:2 | skip | epilogues.go:67:7:67:31 | struct literal |
| epilogues.go:67:7:67:31 | struct literal | epilogues.go:67:25:67:30 | prefix |
| epilogues.go:67:17:67:30 | init of key-value pair | epilogues.go:67:2:67:2 | assignment to l |
| epilogues.go:67:25:67:30 | prefix | epilogues.go:67:17:67:30 | init of key-value pair |
| epilogues.go:68:2:68:24 | defer statement | epilogues.go:69:10:69:10 | l |
| epilogues.go:68:8:68:8 | l | epilogues.go:68:8:68:17 | selection of logValue |
| epilogues.go:68:8:68:17 | selection of logValue | epilogues.go:68:19:68:23 | "bye" |
| epilogues.go:68:8:68:24 | call to logValue | epilogues.go:66:1:71:1 | exit |
| epilogues.go:68:19:68:23 | "bye" | epilogues.go:68:2:68:24 | defer statement |
| epilogues.go:69:2:69:25 | defer statement | epilogues.go:70:2:70:12 | selection of Println |
| epilogues.go:69:8:69:15 | selection of log | epilogues.go:69:17:69:21 | "ptr" |
| epilogues.go:69:8:69:25 | call to log | epilogues.go:68:8:68:24 | call to logValue |
| epilogues.go:69:9:69:10 | &... | epilogues.go:69:8:69:15 | selection of log |
| epilogues.go:69:10:69:10 | l | epilogues.go:69:9:69:10 | &... |
| epilogues.go:69:17:69:21 | "ptr" | epilogues.go:69:24:69:24 | 7 |
| epilogues.go:69:24:69:24 | 7 | epilogues.go:69:2:69:25 | defer statement |
| epilogues.go:70:2:70:12 | selection of Println | epilogues.go:70:14:70:19 | "body" |
| epilogues.go:70:2:70:20 | call to Println | epilogues.go:69:8:69:25 | call to log |
| epilogues.go:70:14:70:19 | "body" | epilogues.go:70:2:70:20 | call to Println |
| epilogues.go:77:1:82:1 | entry | epilogues.go:77:22:77:22 | argument corresponding to x |
| epilogues.go:77:1:82:1 | function declaration | epilogues.go:87:6:87:20 | skip |
| epilogues.go:77:6:77:20 | skip | epilogues.go:77:1:82:1 | function declaration |
| epilogues.go:77:22:77:22 | argument corresponding to x | epilogues.go:77:22:77:22 | initialization of x |
| epilogues.go:77:22:77:22 | initialization of x | epilogues.go:78:8:80:2 | function literal |
| epilogues.go:78:2:80:15 | defer statement | epilogues.go:81:2:81:12 | selection of Println |
| epilogues.go:78:8:80:2 | entry | epilogues.go:78:13:78:17 | argument corresponding to label |
| epilogues.go:78:8:80:2 | function literal | epilogues.go:80:4:80:9 | "done" |
| epilogues.go:78:8:80:15 | function call | epilogues.go:77:1:82:1 | exit |
| epilogues.go:78:13:78:17 | argument corresponding to label | epilogues.go:78:13:78:17 | initialization of label |
| epilogues.go:78:13:78:17 | initialization of label | epilogues.go:78:27:78:27 | argument corresponding to n |
| epilogues.go:78:27:78:27 | argument corresponding to n | epilogues.go:78:27:78:27 | initialization of n |
| epilogues.go:78:27:78:27 | initialization of n | epilogues.go:79:3:79:13 | selection of Println |
| epilogues.go:79:3:79:13 | selection of Println | epilogues.go:79:15:79:19 | label |
| epilogues.go:79:3:79:23 | call to Println | epilogues.go:78:8:80:2 | exit |
| epilogues.go:79:15:79:19 | label | epilogues.go:79:22:79:22 | n |
| epilogues.go:79:22:79:22 | n | epilogues.go:79:3:79:23 | call to Println |
| epilogues.go:80:4:80:9 | "done" | epilogues.go:80:12:80:12 | x |
| epilogues.go:80:12:80:12 | x | epilogues.go:80:14:80:14 | 1 |
| epilogues.go:80:12:80:14 | ...+... | epilogues.go:78:2:80:15 | defer statement |
| epilogues.go:80:14:80:14 | 1 | epilogues.go:80:12:80:14 | ...+... |
| epilogues.go:81:2:81:12 | selection of Println | epilogues.go:81:14:81:19 | "body" |
| epilogues.go:81:2:81:23 | call to Println | epilogues.go:78:8:80:15 | function call |
| epilogues.go:81:14:81:19 | "body" | epilogues.go:81:22:81:22 | x |
| epilogues.go:81:22:81:22 | x | epilogues.go:81:2:81:23 | call to Println |
| epilogues.go:87:1:98:1 | entry | epilogues.go:87:22:87:22 | argument corresponding to x |
| epilogues.go:87:1:98:1 | function declaration | epilogues.go:102:6:102:24 | skip |
| epilogues.go:87:6:87:20 | skip | epilogues.go:87:1:98:1 | function declaration |
| epilogues.go:87:22:87:22 | argument corresponding to x | epilogues.go:87:22:87:22 | initialization of x |
| epilogues.go:87:22:87:22 | initialization of x | epilogues.go:87:30:87:35 | zero value for result |
| epilogues.go:87:30:87:35 | implicit read of result | epilogues.go:87:1:98:1 | exit |
| epilogues.go:87:30:87:35 | initialization of result | epilogues.go:88:8:92:2 | function literal |
| epilogues.go:87:30:87:35 | zero value for result | epilogues.go:87:30:87:35 | initialization of result |
| epilogues.go:88:2:92:4 | defer statement | epilogues.go:93:5:93:5 | x |
| epilogues.go:88:8:92:2 | entry | epilogues.go:89:6:89:6 | skip |
| epilogues.go:88:8:92:2 | function literal | epilogues.go:88:2:92:4 | defer statement |
| epilogues.go:88:8:92:4 | function call | epilogues.go:87:1:98:1 | exit |
| epilogues.go:88:8:92:4 | function call | epilogues.go:87:30:87:35 | implicit read of result |
| epilogues.go:89:6:89:6 | assignment to r | epilogues.go:89:22:89:22 | r |
| epilogues.go:89:6:89:6 | skip | epilogues.go:89:11:89:17 | recover |
| epilogues.go:89:11:89:17 | recover | epilogues.go:89:11:89:19 | call to recover |
| epilogues.go:89:11:89:19 | call to recover | epilogues.go:89:6:89:6 | assignment to r |
| epilogues.go:89:22:89:22 | r | epilogues.go:89:27:89:29 | nil |
| epilogues.go:89:22:89:29 | ...!=... | epilogues.go:88:8:92:2 | exit |
| epilogues.go:89:22:89:29 | ...!=... | epilogues.go:89:22:89:29 | ...!=... is false |
| epilogues.go:89:22:89:29 | ...!=... | epilogues.go:89:22:89:29 | ...!=... is true |
| epilogues.go:89:22:89:29 | ...!=... is false | epilogues.go:88:8:92:2 | exit |
| epilogues.go:89:22:89:29 | ...!=... is true | epilogues.go:90:4:90:9 | skip |
| epilogues.go:89:27:89:29 | nil | epilogues.go:89:22:89:29 | ...!=... |
| epilogues.go:90:4:90:9 | assignment to result | epilogues.go:88:8:92:2 | exit |
| epilogues.go:90:4:90:9 | skip | epilogues.go:90:13:90:14 | -... |
| epilogues.go:90:13:90:14 | -... | epilogues.go:90:4:90:9 | assignment to result |
| epilogues.go:93:5:93:5 | x | epilogues.go:93:9:93:9 | 0 |
| epilogues.go:93:5:93:9 | ...<... | epilogues.go:93:5:93:9 | ...<... is false |
| epilogues.go:93:5:93:9 | ...<... | epilogues.go:93:5:93:9 | ...<... is true |
| epilogues.go:93:5:93:9 | ...<... is false | epilogues.go:96:2:96:7 | skip |
| epilogues.go:93:5:93:9 | ...<... is true | epilogues.go:94:3:94:7 | panic |
| epilogues.go:93:9:93:9 | 0 | epilogues.go:93:5:93:9 | ...<... |
| epilogues.go:94:3:94:7 | panic | epilogues.go:94:9:94:13 | "neg" |
| epilogues.go:94:3:94:14 | call to panic | epilogues.go:88:8:92:4 | function call |
| epilogues.go:94:9:94:13 | "neg" | epilogues.go:94:3:94:14 | call to panic |
| epilogues.go:96:2:96:7 | assignment to result | epilogues.go:97:9:97:14 | result |
| epilogues.go:96:2:96:7 | skip | epilogues.go:96:11:96:11 | x |
| epilogues.go:96:11:96:11 | x | epilogues.go:96:15:96:15 | x |
| epilogues.go:96:11:96:15 | ...*... | epilogues.go:96:2:96:7 | assignment to result |
| epilogues.go:96:15:96:15 | x | epilogues.go:96:11:96:15 | ...*... |
| epilogues.go:97:2:97:14 | return statement | epilogues.go:88:8:92:4 | function call |
| epilogues.go:97:9:97:14 | implicit write of result | epilogues.go:97:2:97:14 | return statement |
| epilogues.go:97:9:97:14 | result | epilogues.go:97:9:97:14 | implicit write of result |
| epilogues.go:102:1:110:1 | entry | epilogues.go:102:26:102:26 | argument corresponding to x |
| epilogues.go:102:1:110:1 | function declaration | epilogues.go:115:6:115:22 | skip |
| epilogues.go:102:6:102:24 | skip | epilogues.go:102:1:110:1 | function declaration |
| epilogues.go:102:26:102:26 | argument corresponding to x | epilogues.go:102:26:102:26 | initialization of x |
| epilogues.go:102:26:102:26 | initialization of x | epilogues.go:102:34:102:35 | zero value for ok |
| epilogues.go:102:34:102:35 | implicit read of ok | epilogues.go:102:43:102:43 | implicit read of n |
| epilogues.go:102:34:102:35 | initialization of ok | epilogues.go:102:43:102:43 | zero value for n |
| epilogues.go:102:34:102:35 | zero value for ok | epilogues.go:102:34:102:35 | initialization of ok |
| epilogues.go:102:43:102:43 | implicit read of n | epilogues.go:102:1:110:1 | exit |
| epilogues.go:102:43:102:43 | initialization of n | epilogues.go:103:8:103:17 | epiRecover |
| epilogues.go:102:43:102:43 | zero value for n | epilogues.go:102:43:102:43 | initialization of n |
| epilogues.go:103:2:103:19 | defer statement | epilogues.go:104:5:104:5 | x |
| epilogues.go:103:8:103:17 | epiRecover | epilogues.go:103:2:103:19 | defer statement |
| epilogues.go:103:8:103:19 | call to epiRecover | epilogues.go:102:1:110:1 | exit |
| epilogues.go:103:8:103:19 | call to epiRecover | epilogues.go:102:34:102:35 | implicit read of ok |
| epilogues.go:104:5:104:5 | x | epilogues.go:104:10:104:10 | 0 |
| epilogues.go:104:5:104:10 | ...==... | epilogues.go:104:5:104:10 | ...==... is false |
| epilogues.go:104:5:104:10 | ...==... | epilogues.go:104:5:104:10 | ...==... is true |
| epilogues.go:104:5:104:10 | ...==... is false | epilogues.go:107:2:107:2 | skip |
| epilogues.go:104:5:104:10 | ...==... is true | epilogues.go:105:3:105:8 | return statement |
| epilogues.go:104:10:104:10 | 0 | epilogues.go:104:5:104:10 | ...==... |
| epilogues.go:105:3:105:8 | return statement | epilogues.go:103:8:103:19 | call to epiRecover |
| epilogues.go:107:2:107:2 | assignment to n | epilogues.go:108:2:108:3 | skip |
| epilogues.go:107:2:107:2 | skip | epilogues.go:107:6:107:6 | x |
| epilogues.go:107:6:107:6 | x | epilogues.go:107:2:107:2 | assignment to n |
| epilogues.go:108:2:108:3 | assignment to ok | epilogues.go:109:2:109:7 | return statement |
| epilogues.go:108:2:108:3 | skip | epilogues.go:108:7:108:10 | true |
| epilogues.go:108:7:108:10 | true | epilogues.go:108:2:108:3 | assignment to ok |
| epilogues.go:109:2:109:7 | return statement | epilogues.go:103:8:103:19 | call to epiRecover |
| epilogues.go:115:1:118:1 | entry | epilogues.go:116:8:116:17 | epiRecover |
| epilogues.go:115:1:118:1 | function declaration | epilogues.go:0:0:0:0 | exit |
| epilogues.go:115:6:115:22 | skip | epilogues.go:115:1:118:1 | function declaration |
| epilogues.go:116:2:116:19 | defer statement | epilogues.go:117:2:117:6 | panic |
| epilogues.go:116:8:116:17 | epiRecover | epilogues.go:116:2:116:19 | defer statement |
| epilogues.go:116:8:116:19 | call to epiRecover | epilogues.go:115:1:118:1 | exit |
| epilogues.go:117:2:117:6 | panic | epilogues.go:117:8:117:13 | "boom" |
| epilogues.go:117:2:117:14 | call to panic | epilogues.go:116:8:116:19 | call to epiRecover |
| epilogues.go:117:8:117:13 | "boom" | epilogues.go:117:2:117:14 | call to panic |
| equalitytests.go:0:0:0:0 | entry | equalitytests.go:3:1:5:1 | skip |
| equalitytests.go:3:1:5:1 | skip | equalitytests.go:7:1:9:1 | skip |
| equalitytests.go:7:1:9:1 | skip | equalitytests.go:11:6:11:18 | skip |

View File

@@ -1,3 +1,4 @@
| epilogues.go:115:6:115:22 | epiRecoverUnnamed | github.com/github/codeql-go/ql/test/library-tests/semmle/go/controlflow/ControlFlowGraph.epiRecoverUnnamed |
| file://:0:0:0:0 | Exit | os.Exit |
| file://:0:0:0:0 | Fatal | log.Fatal |
| file://:0:0:0:0 | Fatal | log.Logger.Fatal |

View File

@@ -0,0 +1,118 @@
package main
import "fmt"
// epiLogger has methods with both pointer and value receivers, used to check
// that the receiver and arguments of a deferred call are evaluated at the
// `defer` statement rather than in the function epilogue.
type epiLogger struct {
prefix string
}
func (l *epiLogger) log(msg string, code int) {
fmt.Println(l.prefix, msg, code)
}
func (l epiLogger) logValue(msg string) {
fmt.Println(l.prefix, msg)
}
// epiRecover recovers from a panic. It is used as a deferred function so we can
// check that control flow returns to the result-read nodes and the normal exit
// node after recovering.
func epiRecover() {
if r := recover(); r != nil {
fmt.Println("recovered:", r)
}
}
// epiPlain has no named result variable and a single `return` with a child
// expression.
func epiPlain(x int) int {
return x * 2
}
// epiVoid has no named result variable and no `return` statement at all.
func epiVoid() {
fmt.Println("void")
}
// epiNamedMixed has named result variables and a mix of a bare `return` (no
// child expressions) and a `return` with child expressions.
func epiNamedMixed(x int) (result int, err error) {
if x < 0 {
result = -x
return
}
return x, nil
}
// epiNamedBareOnly has a named result variable and only a bare `return`.
func epiNamedBareOnly(x int) (n int) {
n = x + 1
return
}
// epiDeferReceiverArgs has a deferred call with a (pointer) receiver and
// arguments that are expressions, so we can check the receiver `l` and the
// arguments `"count"` and `len(items)` are evaluated at the `defer` statement.
func epiDeferReceiverArgs(l *epiLogger, items []int) {
defer l.log("count", len(items))
fmt.Println("processing", len(items))
}
// epiDeferValueReceiver has deferred calls with a value receiver and an
// address-of receiver, both with arguments evaluated at the `defer` statement.
func epiDeferValueReceiver(prefix string) {
l := epiLogger{prefix: prefix}
defer l.logValue("bye")
defer (&l).log("ptr", 7)
fmt.Println("body")
}
// epiDeferFuncLit has a deferred function literal with parameters, so we can
// check that the arguments `"done"` and `x+1` are evaluated at the `defer`
// statement and that control flow enters the function literal body when it is
// invoked at the function epilogue.
func epiDeferFuncLit(x int) {
defer func(label string, n int) {
fmt.Println(label, n)
}("done", x+1)
fmt.Println("body", x)
}
// epiRecoverNamed has a named result variable and a deferred closure containing
// `recover()`. After recovering on the panic path, control flow should return
// to the result-read nodes and the normal exit node.
func epiRecoverNamed(x int) (result int) {
defer func() {
if r := recover(); r != nil {
result = -1
}
}()
if x < 0 {
panic("neg")
}
result = x * x
return result
}
// epiRecoverNamedBare has named result variables, a deferred function
// containing `recover()`, and only bare `return` statements.
func epiRecoverNamedBare(x int) (ok bool, n int) {
defer epiRecover()
if x == 0 {
return
}
n = x
ok = true
return
}
// epiRecoverUnnamed has no named result variables and a deferred function
// containing `recover()`; after recovering, control flow should reach the
// normal exit node directly (there are no result-read nodes).
func epiRecoverUnnamed() {
defer epiRecover()
panic("boom")
}

View File

@@ -22,4 +22,4 @@ invalidModelRow
| test.go:187:24:187:31 | call to Src1 | qltest |
| test.go:191:24:191:31 | call to Src1 | qltest |
| test.go:201:10:201:28 | selection of SourceVariable | qltest |
| test.go:208:15:208:17 | definition of src | qltest |
| test.go:208:15:208:17 | SSA def(src) | qltest |

View File

@@ -22,4 +22,4 @@ invalidModelRow
| test.go:187:24:187:31 | call to Src1 | qltest |
| test.go:191:24:191:31 | call to Src1 | qltest |
| test.go:209:10:209:28 | selection of SourceVariable | qltest |
| test.go:216:15:216:17 | definition of src | qltest |
| test.go:216:15:216:17 | SSA def(src) | qltest |

View File

@@ -1,169 +1,169 @@
| main.go:3:12:3:12 | argument corresponding to x | main.go:3:12:3:12 | definition of x |
| main.go:3:12:3:12 | definition of x | main.go:5:5:5:5 | x |
| main.go:3:19:3:20 | argument corresponding to fn | main.go:3:19:3:20 | definition of fn |
| main.go:3:19:3:20 | definition of fn | main.go:10:24:10:25 | fn |
| main.go:3:12:3:12 | SSA def(x) | main.go:5:5:5:5 | x |
| main.go:3:12:3:12 | argument corresponding to x | main.go:3:12:3:12 | SSA def(x) |
| main.go:3:19:3:20 | SSA def(fn) | main.go:10:24:10:25 | fn |
| main.go:3:19:3:20 | argument corresponding to fn | main.go:3:19:3:20 | SSA def(fn) |
| main.go:5:5:5:5 | x | main.go:6:7:6:7 | x |
| main.go:5:5:5:5 | x | main.go:8:8:8:8 | x |
| main.go:6:3:6:3 | definition of y | main.go:10:12:10:12 | y |
| main.go:6:7:6:7 | x | main.go:6:3:6:3 | definition of y |
| main.go:6:3:6:3 | SSA def(y) | main.go:10:12:10:12 | y |
| main.go:6:7:6:7 | x | main.go:6:3:6:3 | SSA def(y) |
| main.go:6:7:6:7 | x | main.go:10:7:10:7 | x |
| main.go:8:3:8:3 | definition of y | main.go:10:12:10:12 | y |
| main.go:8:7:8:8 | -... | main.go:8:3:8:3 | definition of y |
| main.go:8:3:8:3 | SSA def(y) | main.go:10:12:10:12 | y |
| main.go:8:7:8:8 | -... | main.go:8:3:8:3 | SSA def(y) |
| main.go:8:8:8:8 | x | main.go:10:7:10:7 | x |
| main.go:10:2:10:2 | definition of z | main.go:11:14:11:14 | z |
| main.go:10:2:10:2 | SSA def(z) | main.go:11:14:11:14 | z |
| main.go:10:7:10:7 | x | main.go:10:22:10:22 | x |
| main.go:10:7:10:12 | ...<=... | main.go:10:7:10:27 | ...&&... |
| main.go:10:7:10:27 | ...&&... | main.go:10:2:10:2 | definition of z |
| main.go:10:7:10:27 | ...&&... | main.go:10:2:10:2 | SSA def(z) |
| main.go:10:12:10:12 | y | main.go:10:17:10:17 | y |
| main.go:10:17:10:27 | ...>=... | main.go:10:7:10:27 | ...&&... |
| main.go:11:14:11:14 | z | main.go:11:9:11:15 | type conversion |
| main.go:15:9:15:9 | 0 | main.go:15:2:15:4 | definition of acc |
| main.go:16:9:19:2 | capture variable acc | main.go:17:3:17:5 | acc |
| main.go:17:3:17:7 | definition of acc | main.go:18:10:18:12 | acc |
| main.go:17:3:17:7 | rhs of increment statement | main.go:17:3:17:7 | definition of acc |
| main.go:22:12:22:12 | argument corresponding to b | main.go:22:12:22:12 | definition of b |
| main.go:22:12:22:12 | definition of b | main.go:23:5:23:5 | b |
| main.go:22:20:22:20 | argument corresponding to x | main.go:22:20:22:20 | definition of x |
| main.go:22:20:22:20 | definition of x | main.go:24:10:24:10 | x |
| main.go:22:20:22:20 | definition of x | main.go:26:11:26:11 | x |
| main.go:15:9:15:9 | 0 | main.go:15:2:15:4 | SSA def(acc) |
| main.go:16:9:19:2 | SSA def(acc) | main.go:17:3:17:5 | acc |
| main.go:17:3:17:7 | SSA def(acc) | main.go:18:10:18:12 | acc |
| main.go:17:3:17:7 | rhs of increment statement | main.go:17:3:17:7 | SSA def(acc) |
| main.go:22:12:22:12 | SSA def(b) | main.go:23:5:23:5 | b |
| main.go:22:12:22:12 | argument corresponding to b | main.go:22:12:22:12 | SSA def(b) |
| main.go:22:20:22:20 | SSA def(x) | main.go:24:10:24:10 | x |
| main.go:22:20:22:20 | SSA def(x) | main.go:26:11:26:11 | x |
| main.go:22:20:22:20 | argument corresponding to x | main.go:22:20:22:20 | SSA def(x) |
| main.go:24:10:24:10 | x | main.go:24:10:24:19 | type assertion |
| main.go:26:2:26:2 | definition of n | main.go:27:11:27:11 | n |
| main.go:26:2:26:17 | ... := ...[0] | main.go:26:2:26:2 | definition of n |
| main.go:26:2:26:17 | ... := ...[1] | main.go:26:5:26:6 | definition of ok |
| main.go:26:5:26:6 | definition of ok | main.go:27:5:27:6 | ok |
| main.go:26:2:26:2 | SSA def(n) | main.go:27:11:27:11 | n |
| main.go:26:2:26:17 | ... := ...[0] | main.go:26:2:26:2 | SSA def(n) |
| main.go:26:2:26:17 | ... := ...[1] | main.go:26:5:26:6 | SSA def(ok) |
| main.go:26:5:26:6 | SSA def(ok) | main.go:27:5:27:6 | ok |
| main.go:26:11:26:11 | x | main.go:26:2:26:17 | ... := ...[0] |
| main.go:38:2:38:2 | definition of s | main.go:39:15:39:15 | s |
| main.go:38:7:38:20 | slice literal | main.go:38:2:38:2 | definition of s |
| main.go:38:7:38:20 | slice literal [postupdate] | main.go:38:2:38:2 | definition of s |
| main.go:39:2:39:3 | definition of s1 | main.go:40:18:40:19 | s1 |
| main.go:39:8:39:25 | call to append | main.go:39:2:39:3 | definition of s1 |
| main.go:38:2:38:2 | SSA def(s) | main.go:39:15:39:15 | s |
| main.go:38:7:38:20 | slice literal | main.go:38:2:38:2 | SSA def(s) |
| main.go:38:7:38:20 | slice literal [postupdate] | main.go:38:2:38:2 | SSA def(s) |
| main.go:39:2:39:3 | SSA def(s1) | main.go:40:18:40:19 | s1 |
| main.go:39:8:39:25 | call to append | main.go:39:2:39:3 | SSA def(s1) |
| main.go:39:15:39:15 | s | main.go:40:15:40:15 | s |
| main.go:39:15:39:15 | s [postupdate] | main.go:40:15:40:15 | s |
| main.go:40:2:40:3 | definition of s2 | main.go:43:9:43:10 | s2 |
| main.go:40:8:40:23 | call to append | main.go:40:2:40:3 | definition of s2 |
| main.go:40:2:40:3 | SSA def(s2) | main.go:43:9:43:10 | s2 |
| main.go:40:8:40:23 | call to append | main.go:40:2:40:3 | SSA def(s2) |
| main.go:40:15:40:15 | s | main.go:42:7:42:7 | s |
| main.go:40:15:40:15 | s [postupdate] | main.go:42:7:42:7 | s |
| main.go:41:2:41:3 | definition of s4 | main.go:42:10:42:11 | s4 |
| main.go:41:8:41:21 | call to make | main.go:41:2:41:3 | definition of s4 |
| main.go:46:13:46:14 | argument corresponding to xs | main.go:46:13:46:14 | definition of xs |
| main.go:46:13:46:14 | definition of xs | main.go:47:20:47:21 | xs |
| main.go:46:24:46:27 | definition of keys | main.go:46:24:46:27 | implicit read of keys |
| main.go:46:24:46:27 | definition of keys | main.go:49:3:49:6 | keys |
| main.go:46:24:46:27 | zero value for keys | main.go:46:24:46:27 | definition of keys |
| main.go:46:34:46:37 | definition of vals | main.go:46:34:46:37 | implicit read of vals |
| main.go:46:34:46:37 | definition of vals | main.go:48:3:48:6 | vals |
| main.go:46:34:46:37 | zero value for vals | main.go:46:34:46:37 | definition of vals |
| main.go:47:2:50:2 | range statement[0] | main.go:47:6:47:6 | definition of k |
| main.go:47:2:50:2 | range statement[1] | main.go:47:9:47:9 | definition of v |
| main.go:47:6:47:6 | definition of k | main.go:49:11:49:11 | k |
| main.go:47:9:47:9 | definition of v | main.go:48:11:48:11 | v |
| main.go:48:3:48:6 | definition of vals | main.go:46:34:46:37 | implicit read of vals |
| main.go:48:3:48:6 | definition of vals | main.go:48:3:48:6 | vals |
| main.go:48:3:48:11 | ... += ... | main.go:48:3:48:6 | definition of vals |
| main.go:49:3:49:6 | definition of keys | main.go:46:24:46:27 | implicit read of keys |
| main.go:49:3:49:6 | definition of keys | main.go:49:3:49:6 | keys |
| main.go:49:3:49:11 | ... += ... | main.go:49:3:49:6 | definition of keys |
| main.go:55:6:55:7 | definition of ch | main.go:56:2:56:3 | ch |
| main.go:55:6:55:7 | zero value for ch | main.go:55:6:55:7 | definition of ch |
| main.go:41:2:41:3 | SSA def(s4) | main.go:42:10:42:11 | s4 |
| main.go:41:8:41:21 | call to make | main.go:41:2:41:3 | SSA def(s4) |
| main.go:46:13:46:14 | SSA def(xs) | main.go:47:20:47:21 | xs |
| main.go:46:13:46:14 | argument corresponding to xs | main.go:46:13:46:14 | SSA def(xs) |
| main.go:46:24:46:27 | SSA def(keys) | main.go:46:24:46:27 | implicit read of keys |
| main.go:46:24:46:27 | SSA def(keys) | main.go:49:3:49:6 | keys |
| main.go:46:24:46:27 | zero value for keys | main.go:46:24:46:27 | SSA def(keys) |
| main.go:46:34:46:37 | SSA def(vals) | main.go:46:34:46:37 | implicit read of vals |
| main.go:46:34:46:37 | SSA def(vals) | main.go:48:3:48:6 | vals |
| main.go:46:34:46:37 | zero value for vals | main.go:46:34:46:37 | SSA def(vals) |
| main.go:47:2:50:2 | range statement[0] | main.go:47:6:47:6 | SSA def(k) |
| main.go:47:2:50:2 | range statement[1] | main.go:47:9:47:9 | SSA def(v) |
| main.go:47:6:47:6 | SSA def(k) | main.go:49:11:49:11 | k |
| main.go:47:9:47:9 | SSA def(v) | main.go:48:11:48:11 | v |
| main.go:48:3:48:6 | SSA def(vals) | main.go:46:34:46:37 | implicit read of vals |
| main.go:48:3:48:6 | SSA def(vals) | main.go:48:3:48:6 | vals |
| main.go:48:3:48:11 | ... += ... | main.go:48:3:48:6 | SSA def(vals) |
| main.go:49:3:49:6 | SSA def(keys) | main.go:46:24:46:27 | implicit read of keys |
| main.go:49:3:49:6 | SSA def(keys) | main.go:49:3:49:6 | keys |
| main.go:49:3:49:11 | ... += ... | main.go:49:3:49:6 | SSA def(keys) |
| main.go:55:6:55:7 | SSA def(ch) | main.go:56:2:56:3 | ch |
| main.go:55:6:55:7 | zero value for ch | main.go:55:6:55:7 | SSA def(ch) |
| main.go:56:2:56:3 | ch | main.go:57:4:57:5 | ch |
| main.go:56:2:56:3 | ch [postupdate] | main.go:57:4:57:5 | ch |
| main.go:61:2:61:2 | definition of x | main.go:64:11:64:11 | x |
| main.go:61:7:61:7 | 1 | main.go:61:2:61:2 | definition of x |
| main.go:62:2:62:2 | definition of y | main.go:64:14:64:14 | y |
| main.go:62:7:62:7 | 2 | main.go:62:2:62:2 | definition of y |
| main.go:63:2:63:2 | definition of z | main.go:64:17:64:17 | z |
| main.go:63:7:63:7 | 3 | main.go:63:2:63:2 | definition of z |
| main.go:64:2:64:2 | definition of a | main.go:66:9:66:9 | a |
| main.go:64:7:64:18 | call to min | main.go:64:2:64:2 | definition of a |
| main.go:61:2:61:2 | SSA def(x) | main.go:64:11:64:11 | x |
| main.go:61:7:61:7 | 1 | main.go:61:2:61:2 | SSA def(x) |
| main.go:62:2:62:2 | SSA def(y) | main.go:64:14:64:14 | y |
| main.go:62:7:62:7 | 2 | main.go:62:2:62:2 | SSA def(y) |
| main.go:63:2:63:2 | SSA def(z) | main.go:64:17:64:17 | z |
| main.go:63:7:63:7 | 3 | main.go:63:2:63:2 | SSA def(z) |
| main.go:64:2:64:2 | SSA def(a) | main.go:66:9:66:9 | a |
| main.go:64:7:64:18 | call to min | main.go:64:2:64:2 | SSA def(a) |
| main.go:64:11:64:11 | x | main.go:64:7:64:18 | call to min |
| main.go:64:11:64:11 | x | main.go:65:11:65:11 | x |
| main.go:64:14:64:14 | y | main.go:64:7:64:18 | call to min |
| main.go:64:14:64:14 | y | main.go:65:14:65:14 | y |
| main.go:64:17:64:17 | z | main.go:64:7:64:18 | call to min |
| main.go:64:17:64:17 | z | main.go:65:17:65:17 | z |
| main.go:65:2:65:2 | definition of b | main.go:66:12:66:12 | b |
| main.go:65:7:65:18 | call to max | main.go:65:2:65:2 | definition of b |
| main.go:65:2:65:2 | SSA def(b) | main.go:66:12:66:12 | b |
| main.go:65:7:65:18 | call to max | main.go:65:2:65:2 | SSA def(b) |
| main.go:65:11:65:11 | x | main.go:65:7:65:18 | call to max |
| main.go:65:14:65:14 | y | main.go:65:7:65:18 | call to max |
| main.go:65:17:65:17 | z | main.go:65:7:65:18 | call to max |
| strings.go:8:12:8:12 | argument corresponding to s | strings.go:8:12:8:12 | definition of s |
| strings.go:8:12:8:12 | definition of s | strings.go:9:24:9:24 | s |
| strings.go:9:2:9:3 | definition of s2 | strings.go:11:20:11:21 | s2 |
| strings.go:9:8:9:38 | call to Replace | strings.go:9:2:9:3 | definition of s2 |
| strings.go:8:12:8:12 | SSA def(s) | strings.go:9:24:9:24 | s |
| strings.go:8:12:8:12 | argument corresponding to s | strings.go:8:12:8:12 | SSA def(s) |
| strings.go:9:2:9:3 | SSA def(s2) | strings.go:11:20:11:21 | s2 |
| strings.go:9:8:9:38 | call to Replace | strings.go:9:2:9:3 | SSA def(s2) |
| strings.go:9:24:9:24 | s | strings.go:10:27:10:27 | s |
| strings.go:10:2:10:3 | definition of s3 | strings.go:11:24:11:25 | s3 |
| strings.go:10:8:10:42 | call to ReplaceAll | strings.go:10:2:10:3 | definition of s3 |
| strings.go:10:2:10:3 | SSA def(s3) | strings.go:11:24:11:25 | s3 |
| strings.go:10:8:10:42 | call to ReplaceAll | strings.go:10:2:10:3 | SSA def(s3) |
| strings.go:11:20:11:21 | s2 | strings.go:11:48:11:49 | s2 |
| strings.go:11:24:11:25 | s3 | strings.go:11:67:11:68 | s3 |
| url.go:8:12:8:12 | argument corresponding to b | url.go:8:12:8:12 | definition of b |
| url.go:8:12:8:12 | definition of b | url.go:11:5:11:5 | b |
| url.go:8:20:8:20 | argument corresponding to s | url.go:8:20:8:20 | definition of s |
| url.go:8:20:8:20 | definition of s | url.go:12:46:12:46 | s |
| url.go:8:20:8:20 | definition of s | url.go:14:48:14:48 | s |
| url.go:12:3:12:5 | definition of res | url.go:19:9:19:11 | res |
| url.go:12:3:12:48 | ... = ...[0] | url.go:12:3:12:5 | definition of res |
| url.go:12:3:12:48 | ... = ...[1] | url.go:12:8:12:10 | definition of err |
| url.go:12:8:12:10 | definition of err | url.go:16:5:16:7 | err |
| url.go:14:3:14:5 | definition of res | url.go:19:9:19:11 | res |
| url.go:14:3:14:50 | ... = ...[0] | url.go:14:3:14:5 | definition of res |
| url.go:14:3:14:50 | ... = ...[1] | url.go:14:8:14:10 | definition of err |
| url.go:14:8:14:10 | definition of err | url.go:16:5:16:7 | err |
| url.go:22:12:22:12 | argument corresponding to i | url.go:22:12:22:12 | definition of i |
| url.go:22:12:22:12 | definition of i | url.go:24:5:24:5 | i |
| url.go:22:19:22:19 | argument corresponding to s | url.go:22:19:22:19 | definition of s |
| url.go:22:19:22:19 | definition of s | url.go:23:20:23:20 | s |
| url.go:23:2:23:2 | definition of u | url.go:25:10:25:10 | u |
| url.go:23:2:23:21 | ... := ...[0] | url.go:23:2:23:2 | definition of u |
| url.go:8:12:8:12 | SSA def(b) | url.go:11:5:11:5 | b |
| url.go:8:12:8:12 | argument corresponding to b | url.go:8:12:8:12 | SSA def(b) |
| url.go:8:20:8:20 | SSA def(s) | url.go:12:46:12:46 | s |
| url.go:8:20:8:20 | SSA def(s) | url.go:14:48:14:48 | s |
| url.go:8:20:8:20 | argument corresponding to s | url.go:8:20:8:20 | SSA def(s) |
| url.go:12:3:12:5 | SSA def(res) | url.go:19:9:19:11 | res |
| url.go:12:3:12:48 | ... = ...[0] | url.go:12:3:12:5 | SSA def(res) |
| url.go:12:3:12:48 | ... = ...[1] | url.go:12:8:12:10 | SSA def(err) |
| url.go:12:8:12:10 | SSA def(err) | url.go:16:5:16:7 | err |
| url.go:14:3:14:5 | SSA def(res) | url.go:19:9:19:11 | res |
| url.go:14:3:14:50 | ... = ...[0] | url.go:14:3:14:5 | SSA def(res) |
| url.go:14:3:14:50 | ... = ...[1] | url.go:14:8:14:10 | SSA def(err) |
| url.go:14:8:14:10 | SSA def(err) | url.go:16:5:16:7 | err |
| url.go:22:12:22:12 | SSA def(i) | url.go:24:5:24:5 | i |
| url.go:22:12:22:12 | argument corresponding to i | url.go:22:12:22:12 | SSA def(i) |
| url.go:22:19:22:19 | SSA def(s) | url.go:23:20:23:20 | s |
| url.go:22:19:22:19 | argument corresponding to s | url.go:22:19:22:19 | SSA def(s) |
| url.go:23:2:23:2 | SSA def(u) | url.go:25:10:25:10 | u |
| url.go:23:2:23:21 | ... := ...[0] | url.go:23:2:23:2 | SSA def(u) |
| url.go:23:20:23:20 | s | url.go:27:29:27:29 | s |
| url.go:27:2:27:2 | definition of u | url.go:28:14:28:14 | u |
| url.go:27:2:27:30 | ... = ...[0] | url.go:27:2:27:2 | definition of u |
| url.go:27:2:27:2 | SSA def(u) | url.go:28:14:28:14 | u |
| url.go:27:2:27:30 | ... = ...[0] | url.go:27:2:27:2 | SSA def(u) |
| url.go:28:14:28:14 | u | url.go:29:14:29:14 | u |
| url.go:28:14:28:14 | u [postupdate] | url.go:29:14:29:14 | u |
| url.go:29:14:29:14 | u | url.go:30:11:30:11 | u |
| url.go:29:14:29:14 | u [postupdate] | url.go:30:11:30:11 | u |
| url.go:30:2:30:3 | definition of bs | url.go:31:14:31:15 | bs |
| url.go:30:2:30:27 | ... := ...[0] | url.go:30:2:30:3 | definition of bs |
| url.go:30:2:30:3 | SSA def(bs) | url.go:31:14:31:15 | bs |
| url.go:30:2:30:27 | ... := ...[0] | url.go:30:2:30:3 | SSA def(bs) |
| url.go:30:11:30:11 | u | url.go:32:9:32:9 | u |
| url.go:30:11:30:11 | u [postupdate] | url.go:32:9:32:9 | u |
| url.go:32:2:32:2 | definition of u | url.go:33:14:33:14 | u |
| url.go:32:2:32:23 | ... = ...[0] | url.go:32:2:32:2 | definition of u |
| url.go:32:2:32:2 | SSA def(u) | url.go:33:14:33:14 | u |
| url.go:32:2:32:23 | ... = ...[0] | url.go:32:2:32:2 | SSA def(u) |
| url.go:33:14:33:14 | u | url.go:34:14:34:14 | u |
| url.go:33:14:33:14 | u [postupdate] | url.go:34:14:34:14 | u |
| url.go:34:14:34:14 | u | url.go:35:14:35:14 | u |
| url.go:34:14:34:14 | u [postupdate] | url.go:35:14:35:14 | u |
| url.go:35:14:35:14 | u | url.go:36:6:36:6 | u |
| url.go:35:14:35:14 | u [postupdate] | url.go:36:6:36:6 | u |
| url.go:36:2:36:2 | definition of u | url.go:37:9:37:9 | u |
| url.go:36:2:36:2 | SSA def(u) | url.go:37:9:37:9 | u |
| url.go:36:6:36:6 | u | url.go:36:25:36:25 | u |
| url.go:36:6:36:6 | u [postupdate] | url.go:36:25:36:25 | u |
| url.go:36:6:36:26 | call to ResolveReference | url.go:36:2:36:2 | definition of u |
| url.go:42:2:42:3 | definition of ui | url.go:43:11:43:12 | ui |
| url.go:42:7:42:38 | call to UserPassword | url.go:42:2:42:3 | definition of ui |
| url.go:43:2:43:3 | definition of pw | url.go:44:14:44:15 | pw |
| url.go:43:2:43:23 | ... := ...[0] | url.go:43:2:43:3 | definition of pw |
| url.go:36:6:36:26 | call to ResolveReference | url.go:36:2:36:2 | SSA def(u) |
| url.go:42:2:42:3 | SSA def(ui) | url.go:43:11:43:12 | ui |
| url.go:42:7:42:38 | call to UserPassword | url.go:42:2:42:3 | SSA def(ui) |
| url.go:43:2:43:3 | SSA def(pw) | url.go:44:14:44:15 | pw |
| url.go:43:2:43:23 | ... := ...[0] | url.go:43:2:43:3 | SSA def(pw) |
| url.go:43:11:43:12 | ui | url.go:45:14:45:15 | ui |
| url.go:43:11:43:12 | ui [postupdate] | url.go:45:14:45:15 | ui |
| url.go:45:14:45:15 | ui | url.go:46:9:46:10 | ui |
| url.go:45:14:45:15 | ui [postupdate] | url.go:46:9:46:10 | ui |
| url.go:49:12:49:12 | argument corresponding to q | url.go:49:12:49:12 | definition of q |
| url.go:49:12:49:12 | definition of q | url.go:50:25:50:25 | q |
| url.go:50:2:50:2 | definition of v | url.go:51:14:51:14 | v |
| url.go:50:2:50:26 | ... := ...[0] | url.go:50:2:50:2 | definition of v |
| url.go:49:12:49:12 | SSA def(q) | url.go:50:25:50:25 | q |
| url.go:49:12:49:12 | argument corresponding to q | url.go:49:12:49:12 | SSA def(q) |
| url.go:50:2:50:2 | SSA def(v) | url.go:51:14:51:14 | v |
| url.go:50:2:50:26 | ... := ...[0] | url.go:50:2:50:2 | SSA def(v) |
| url.go:51:14:51:14 | v | url.go:52:14:52:14 | v |
| url.go:51:14:51:14 | v [postupdate] | url.go:52:14:52:14 | v |
| url.go:52:14:52:14 | v | url.go:53:9:53:9 | v |
| url.go:52:14:52:14 | v [postupdate] | url.go:53:9:53:9 | v |
| url.go:56:12:56:12 | argument corresponding to q | url.go:56:12:56:12 | definition of q |
| url.go:56:12:56:12 | definition of q | url.go:57:29:57:29 | q |
| url.go:57:2:57:8 | definition of joined1 | url.go:58:38:58:44 | joined1 |
| url.go:57:2:57:39 | ... := ...[0] | url.go:57:2:57:8 | definition of joined1 |
| url.go:58:2:58:8 | definition of joined2 | url.go:59:24:59:30 | joined2 |
| url.go:58:2:58:45 | ... := ...[0] | url.go:58:2:58:8 | definition of joined2 |
| url.go:59:2:59:6 | definition of asUrl | url.go:60:15:60:19 | asUrl |
| url.go:59:2:59:31 | ... := ...[0] | url.go:59:2:59:6 | definition of asUrl |
| url.go:60:2:60:10 | definition of joinedUrl | url.go:61:9:61:17 | joinedUrl |
| url.go:60:15:60:37 | call to JoinPath | url.go:60:2:60:10 | definition of joinedUrl |
| url.go:64:13:64:13 | argument corresponding to q | url.go:64:13:64:13 | definition of q |
| url.go:64:13:64:13 | definition of q | url.go:66:27:66:27 | q |
| url.go:65:2:65:9 | definition of cleanUrl | url.go:66:9:66:16 | cleanUrl |
| url.go:65:2:65:48 | ... := ...[0] | url.go:65:2:65:9 | definition of cleanUrl |
| url.go:56:12:56:12 | SSA def(q) | url.go:57:29:57:29 | q |
| url.go:56:12:56:12 | argument corresponding to q | url.go:56:12:56:12 | SSA def(q) |
| url.go:57:2:57:8 | SSA def(joined1) | url.go:58:38:58:44 | joined1 |
| url.go:57:2:57:39 | ... := ...[0] | url.go:57:2:57:8 | SSA def(joined1) |
| url.go:58:2:58:8 | SSA def(joined2) | url.go:59:24:59:30 | joined2 |
| url.go:58:2:58:45 | ... := ...[0] | url.go:58:2:58:8 | SSA def(joined2) |
| url.go:59:2:59:6 | SSA def(asUrl) | url.go:60:15:60:19 | asUrl |
| url.go:59:2:59:31 | ... := ...[0] | url.go:59:2:59:6 | SSA def(asUrl) |
| url.go:60:2:60:10 | SSA def(joinedUrl) | url.go:61:9:61:17 | joinedUrl |
| url.go:60:15:60:37 | call to JoinPath | url.go:60:2:60:10 | SSA def(joinedUrl) |
| url.go:64:13:64:13 | SSA def(q) | url.go:66:27:66:27 | q |
| url.go:64:13:64:13 | argument corresponding to q | url.go:64:13:64:13 | SSA def(q) |
| url.go:65:2:65:9 | SSA def(cleanUrl) | url.go:66:9:66:16 | cleanUrl |
| url.go:65:2:65:48 | ... := ...[0] | url.go:65:2:65:9 | SSA def(cleanUrl) |

View File

@@ -25,15 +25,15 @@
| result | main.go:53:2:53:22 | call to op2 | main.go:53:2:53:22 | call to op2 |
| result | main.go:53:14:53:21 | call to bump | main.go:53:14:53:21 | call to bump |
| result | tst2.go:10:9:10:26 | call to NewEncoder | tst2.go:10:9:10:26 | call to NewEncoder |
| result | tst2.go:10:9:10:39 | call to Encode | tst2.go:10:2:10:4 | definition of err |
| result | tst.go:9:17:9:33 | call to new | tst.go:9:2:9:12 | definition of bytesBuffer |
| result | tst2.go:10:9:10:39 | call to Encode | tst2.go:10:2:10:4 | SSA def(err) |
| result | tst.go:9:17:9:33 | call to new | tst.go:9:2:9:12 | SSA def(bytesBuffer) |
| result 0 | main.go:51:2:51:14 | call to op | main.go:51:2:51:14 | call to op |
| result 0 | main.go:53:2:53:22 | call to op2 | main.go:53:2:53:22 | call to op2 |
| result 0 | main.go:53:14:53:21 | call to bump | main.go:53:14:53:21 | call to bump |
| result 0 | main.go:54:10:54:15 | call to test | main.go:54:2:54:2 | definition of x |
| result 0 | main.go:56:9:56:15 | call to test2 | main.go:56:2:56:2 | definition of x |
| result 0 | main.go:54:10:54:15 | call to test | main.go:54:2:54:2 | SSA def(x) |
| result 0 | main.go:56:9:56:15 | call to test2 | main.go:56:2:56:2 | SSA def(x) |
| result 0 | tst2.go:10:9:10:26 | call to NewEncoder | tst2.go:10:9:10:26 | call to NewEncoder |
| result 0 | tst2.go:10:9:10:39 | call to Encode | tst2.go:10:2:10:4 | definition of err |
| result 0 | tst.go:9:17:9:33 | call to new | tst.go:9:2:9:12 | definition of bytesBuffer |
| result 1 | main.go:54:10:54:15 | call to test | main.go:54:5:54:5 | definition of y |
| result 1 | main.go:56:9:56:15 | call to test2 | main.go:56:5:56:5 | definition of y |
| result 0 | tst2.go:10:9:10:39 | call to Encode | tst2.go:10:2:10:4 | SSA def(err) |
| result 0 | tst.go:9:17:9:33 | call to new | tst.go:9:2:9:12 | SSA def(bytesBuffer) |
| result 1 | main.go:54:10:54:15 | call to test | main.go:54:5:54:5 | SSA def(y) |
| result 1 | main.go:56:9:56:15 | call to test2 | main.go:56:5:56:5 | SSA def(y) |

View File

@@ -1,14 +1,14 @@
| parameter 0 | main.go:5:1:11:1 | function declaration | main.go:5:9:5:10 | definition of op |
| parameter 0 | main.go:13:1:20:1 | function declaration | main.go:13:10:13:11 | definition of op |
| parameter 0 | main.go:40:1:48:1 | function declaration | main.go:40:12:40:12 | definition of b |
| parameter 0 | reset.go:8:1:16:1 | function declaration | reset.go:8:27:8:27 | definition of r |
| parameter 0 | tst2.go:8:1:12:1 | function declaration | tst2.go:8:12:8:15 | definition of data |
| parameter 0 | tst.go:8:1:11:1 | function declaration | tst.go:8:12:8:17 | definition of reader |
| parameter 0 | main.go:5:1:11:1 | function declaration | main.go:5:9:5:10 | SSA def(op) |
| parameter 0 | main.go:13:1:20:1 | function declaration | main.go:13:10:13:11 | SSA def(op) |
| parameter 0 | main.go:40:1:48:1 | function declaration | main.go:40:12:40:12 | SSA def(b) |
| parameter 0 | reset.go:8:1:16:1 | function declaration | reset.go:8:27:8:27 | SSA def(r) |
| parameter 0 | tst2.go:8:1:12:1 | function declaration | tst2.go:8:12:8:15 | SSA def(data) |
| parameter 0 | tst.go:8:1:11:1 | function declaration | tst.go:8:12:8:17 | SSA def(reader) |
| parameter 0 | tst.go:13:1:13:25 | function declaration | tst.go:13:12:13:13 | initialization of xs |
| parameter 0 | tst.go:15:1:19:1 | function declaration | tst.go:15:12:15:12 | definition of x |
| parameter 1 | main.go:5:1:11:1 | function declaration | main.go:5:20:5:20 | definition of x |
| parameter 1 | main.go:13:1:20:1 | function declaration | main.go:13:21:13:21 | definition of x |
| parameter 1 | tst.go:15:1:19:1 | function declaration | tst.go:15:15:15:15 | definition of y |
| parameter 2 | main.go:5:1:11:1 | function declaration | main.go:5:27:5:27 | definition of y |
| parameter 2 | main.go:13:1:20:1 | function declaration | main.go:13:28:13:28 | definition of y |
| receiver | main.go:26:1:29:1 | function declaration | main.go:26:7:26:7 | definition of c |
| parameter 0 | tst.go:15:1:19:1 | function declaration | tst.go:15:12:15:12 | SSA def(x) |
| parameter 1 | main.go:5:1:11:1 | function declaration | main.go:5:20:5:20 | SSA def(x) |
| parameter 1 | main.go:13:1:20:1 | function declaration | main.go:13:21:13:21 | SSA def(x) |
| parameter 1 | tst.go:15:1:19:1 | function declaration | tst.go:15:15:15:15 | SSA def(y) |
| parameter 2 | main.go:5:1:11:1 | function declaration | main.go:5:27:5:27 | SSA def(y) |
| parameter 2 | main.go:13:1:20:1 | function declaration | main.go:13:28:13:28 | SSA def(y) |
| receiver | main.go:26:1:29:1 | function declaration | main.go:26:7:26:7 | SSA def(c) |

View File

@@ -1,18 +1,18 @@
| main.go:6:2:6:5 | 1 | main.go:14:7:14:7 | 1 |
| main.go:10:2:10:2 | definition of x | main.go:10:7:10:7 | 0 |
| main.go:10:2:10:2 | SSA def(x) | main.go:10:7:10:7 | 0 |
| main.go:10:7:10:7 | 0 | main.go:10:7:10:7 | 0 |
| main.go:11:6:11:6 | definition of y | main.go:10:7:10:7 | 0 |
| main.go:11:6:11:6 | SSA def(y) | main.go:10:7:10:7 | 0 |
| main.go:11:6:11:6 | zero value for y | main.go:10:7:10:7 | 0 |
| main.go:12:2:12:18 | call to Println | main.go:12:2:12:18 | call to Println |
| main.go:12:14:12:14 | x | main.go:10:7:10:7 | 0 |
| main.go:12:17:12:17 | y | main.go:10:7:10:7 | 0 |
| main.go:14:2:14:2 | definition of z | main.go:14:7:14:7 | 1 |
| main.go:14:2:14:2 | SSA def(z) | main.go:14:7:14:7 | 1 |
| main.go:14:7:14:7 | 1 | main.go:14:7:14:7 | 1 |
| main.go:15:2:15:9 | call to bump | main.go:15:2:15:9 | call to bump |
| main.go:16:2:16:21 | call to Println | main.go:16:2:16:21 | call to Println |
| main.go:16:14:16:14 | x | main.go:10:7:10:7 | 0 |
| main.go:16:17:16:17 | y | main.go:10:7:10:7 | 0 |
| main.go:18:2:18:3 | definition of ss | main.go:18:8:18:24 | call to make |
| main.go:18:2:18:3 | SSA def(ss) | main.go:18:8:18:24 | call to make |
| main.go:18:8:18:24 | call to make | main.go:18:8:18:24 | call to make |
| main.go:18:23:18:23 | 3 | main.go:18:23:18:23 | 3 |
| main.go:19:5:19:5 | 2 | main.go:19:5:19:5 | 2 |
@@ -20,22 +20,20 @@
| main.go:20:2:20:16 | call to Println | main.go:20:2:20:16 | call to Println |
| main.go:23:14:23:16 | implicit read of res | main.go:24:8:24:8 | 4 |
| main.go:23:14:23:16 | zero value for res | main.go:10:7:10:7 | 0 |
| main.go:24:2:24:4 | definition of res | main.go:24:8:24:8 | 4 |
| main.go:24:2:24:4 | SSA def(res) | main.go:24:8:24:8 | 4 |
| main.go:24:8:24:8 | 4 | main.go:24:8:24:8 | 4 |
| main.go:28:15:28:17 | implicit read of res | main.go:30:9:30:9 | 6 |
| main.go:28:15:28:17 | zero value for res | main.go:10:7:10:7 | 0 |
| main.go:29:8:29:8 | 5 | main.go:29:8:29:8 | 5 |
| main.go:30:9:30:9 | 6 | main.go:30:9:30:9 | 6 |
| main.go:30:9:30:9 | definition of res | main.go:30:9:30:9 | 6 |
| main.go:33:15:33:17 | definition of res | main.go:10:7:10:7 | 0 |
| main.go:30:9:30:9 | SSA def(res) | main.go:30:9:30:9 | 6 |
| main.go:33:15:33:17 | zero value for res | main.go:10:7:10:7 | 0 |
| main.go:34:2:34:4 | definition of res | main.go:34:8:34:8 | 7 |
| main.go:34:8:34:8 | 7 | main.go:34:8:34:8 | 7 |
| main.go:35:8:37:4 | function call | main.go:35:8:37:4 | function call |
| main.go:36:3:36:5 | definition of res | main.go:36:9:36:9 | 8 |
| main.go:36:3:36:5 | SSA def(res) | main.go:36:9:36:9 | 8 |
| main.go:36:9:36:9 | 8 | main.go:36:9:36:9 | 8 |
| main.go:38:9:38:9 | 9 | main.go:38:9:38:9 | 9 |
| main.go:38:9:38:9 | definition of res | main.go:38:9:38:9 | 9 |
| main.go:38:9:38:9 | SSA def(res) | main.go:38:9:38:9 | 9 |
| regressions.go:5:11:5:31 | call to Sizeof | regressions.go:5:11:5:31 | call to Sizeof |
| regressions.go:7:11:7:15 | false | regressions.go:7:11:7:15 | false |
| regressions.go:9:11:9:12 | !... | regressions.go:11:11:11:14 | true |

View File

@@ -1,132 +1,132 @@
| main.go:22:2:22:6 | definition of outer | main.go:25:7:25:11 | outer |
| main.go:22:11:24:2 | struct literal | main.go:22:2:22:6 | definition of outer |
| main.go:22:11:24:2 | struct literal [postupdate] | main.go:22:2:22:6 | definition of outer |
| main.go:22:2:22:6 | SSA def(outer) | main.go:25:7:25:11 | outer |
| main.go:22:11:24:2 | struct literal | main.go:22:2:22:6 | SSA def(outer) |
| main.go:22:11:24:2 | struct literal [postupdate] | main.go:22:2:22:6 | SSA def(outer) |
| main.go:25:7:25:11 | outer | main.go:26:7:26:11 | outer |
| main.go:26:7:26:11 | outer | main.go:27:7:27:11 | outer |
| main.go:27:7:27:11 | outer | main.go:28:7:28:11 | outer |
| main.go:30:2:30:7 | definition of outerp | main.go:33:7:33:12 | outerp |
| main.go:30:12:32:2 | &... | main.go:30:2:30:7 | definition of outerp |
| main.go:30:12:32:2 | &... [postupdate] | main.go:30:2:30:7 | definition of outerp |
| main.go:30:2:30:7 | SSA def(outerp) | main.go:33:7:33:12 | outerp |
| main.go:30:12:32:2 | &... | main.go:30:2:30:7 | SSA def(outerp) |
| main.go:30:12:32:2 | &... [postupdate] | main.go:30:2:30:7 | SSA def(outerp) |
| main.go:33:7:33:12 | outerp | main.go:34:7:34:12 | outerp |
| main.go:33:7:33:12 | outerp [postupdate] | main.go:34:7:34:12 | outerp |
| main.go:34:7:34:12 | outerp | main.go:35:7:35:12 | outerp |
| main.go:34:7:34:12 | outerp [postupdate] | main.go:35:7:35:12 | outerp |
| main.go:35:7:35:12 | outerp | main.go:36:7:36:12 | outerp |
| main.go:35:7:35:12 | outerp [postupdate] | main.go:36:7:36:12 | outerp |
| main.go:40:2:40:6 | definition of outer | main.go:41:7:41:11 | outer |
| main.go:40:11:40:40 | struct literal | main.go:40:2:40:6 | definition of outer |
| main.go:40:11:40:40 | struct literal [postupdate] | main.go:40:2:40:6 | definition of outer |
| main.go:40:2:40:6 | SSA def(outer) | main.go:41:7:41:11 | outer |
| main.go:40:11:40:40 | struct literal | main.go:40:2:40:6 | SSA def(outer) |
| main.go:40:11:40:40 | struct literal [postupdate] | main.go:40:2:40:6 | SSA def(outer) |
| main.go:41:7:41:11 | outer | main.go:42:7:42:11 | outer |
| main.go:42:7:42:11 | outer | main.go:43:7:43:11 | outer |
| main.go:43:7:43:11 | outer | main.go:44:7:44:11 | outer |
| main.go:46:2:46:7 | definition of outerp | main.go:47:7:47:12 | outerp |
| main.go:46:12:46:42 | &... | main.go:46:2:46:7 | definition of outerp |
| main.go:46:12:46:42 | &... [postupdate] | main.go:46:2:46:7 | definition of outerp |
| main.go:46:2:46:7 | SSA def(outerp) | main.go:47:7:47:12 | outerp |
| main.go:46:12:46:42 | &... | main.go:46:2:46:7 | SSA def(outerp) |
| main.go:46:12:46:42 | &... [postupdate] | main.go:46:2:46:7 | SSA def(outerp) |
| main.go:47:7:47:12 | outerp | main.go:48:7:48:12 | outerp |
| main.go:47:7:47:12 | outerp [postupdate] | main.go:48:7:48:12 | outerp |
| main.go:48:7:48:12 | outerp | main.go:49:7:49:12 | outerp |
| main.go:48:7:48:12 | outerp [postupdate] | main.go:49:7:49:12 | outerp |
| main.go:49:7:49:12 | outerp | main.go:50:7:50:12 | outerp |
| main.go:49:7:49:12 | outerp [postupdate] | main.go:50:7:50:12 | outerp |
| main.go:54:2:54:6 | definition of inner | main.go:55:19:55:23 | inner |
| main.go:54:11:54:25 | struct literal | main.go:54:2:54:6 | definition of inner |
| main.go:54:11:54:25 | struct literal [postupdate] | main.go:54:2:54:6 | definition of inner |
| main.go:55:2:55:7 | definition of middle | main.go:56:17:56:22 | middle |
| main.go:55:12:55:24 | struct literal | main.go:55:2:55:7 | definition of middle |
| main.go:55:12:55:24 | struct literal [postupdate] | main.go:55:2:55:7 | definition of middle |
| main.go:56:2:56:6 | definition of outer | main.go:57:7:57:11 | outer |
| main.go:56:11:56:23 | struct literal | main.go:56:2:56:6 | definition of outer |
| main.go:56:11:56:23 | struct literal [postupdate] | main.go:56:2:56:6 | definition of outer |
| main.go:54:2:54:6 | SSA def(inner) | main.go:55:19:55:23 | inner |
| main.go:54:11:54:25 | struct literal | main.go:54:2:54:6 | SSA def(inner) |
| main.go:54:11:54:25 | struct literal [postupdate] | main.go:54:2:54:6 | SSA def(inner) |
| main.go:55:2:55:7 | SSA def(middle) | main.go:56:17:56:22 | middle |
| main.go:55:12:55:24 | struct literal | main.go:55:2:55:7 | SSA def(middle) |
| main.go:55:12:55:24 | struct literal [postupdate] | main.go:55:2:55:7 | SSA def(middle) |
| main.go:56:2:56:6 | SSA def(outer) | main.go:57:7:57:11 | outer |
| main.go:56:11:56:23 | struct literal | main.go:56:2:56:6 | SSA def(outer) |
| main.go:56:11:56:23 | struct literal [postupdate] | main.go:56:2:56:6 | SSA def(outer) |
| main.go:57:7:57:11 | outer | main.go:58:7:58:11 | outer |
| main.go:58:7:58:11 | outer | main.go:59:7:59:11 | outer |
| main.go:59:7:59:11 | outer | main.go:60:7:60:11 | outer |
| main.go:62:2:62:7 | definition of innerp | main.go:63:20:63:25 | innerp |
| main.go:62:12:62:26 | struct literal | main.go:62:2:62:7 | definition of innerp |
| main.go:62:12:62:26 | struct literal [postupdate] | main.go:62:2:62:7 | definition of innerp |
| main.go:63:2:63:8 | definition of middlep | main.go:64:18:64:24 | middlep |
| main.go:63:13:63:26 | struct literal | main.go:63:2:63:8 | definition of middlep |
| main.go:63:13:63:26 | struct literal [postupdate] | main.go:63:2:63:8 | definition of middlep |
| main.go:64:2:64:7 | definition of outerp | main.go:65:7:65:12 | outerp |
| main.go:64:12:64:25 | struct literal | main.go:64:2:64:7 | definition of outerp |
| main.go:64:12:64:25 | struct literal [postupdate] | main.go:64:2:64:7 | definition of outerp |
| main.go:62:2:62:7 | SSA def(innerp) | main.go:63:20:63:25 | innerp |
| main.go:62:12:62:26 | struct literal | main.go:62:2:62:7 | SSA def(innerp) |
| main.go:62:12:62:26 | struct literal [postupdate] | main.go:62:2:62:7 | SSA def(innerp) |
| main.go:63:2:63:8 | SSA def(middlep) | main.go:64:18:64:24 | middlep |
| main.go:63:13:63:26 | struct literal | main.go:63:2:63:8 | SSA def(middlep) |
| main.go:63:13:63:26 | struct literal [postupdate] | main.go:63:2:63:8 | SSA def(middlep) |
| main.go:64:2:64:7 | SSA def(outerp) | main.go:65:7:65:12 | outerp |
| main.go:64:12:64:25 | struct literal | main.go:64:2:64:7 | SSA def(outerp) |
| main.go:64:12:64:25 | struct literal [postupdate] | main.go:64:2:64:7 | SSA def(outerp) |
| main.go:65:7:65:12 | outerp | main.go:66:7:66:12 | outerp |
| main.go:66:7:66:12 | outerp | main.go:67:7:67:12 | outerp |
| main.go:67:7:67:12 | outerp | main.go:68:7:68:12 | outerp |
| main.go:72:2:72:6 | definition of inner | main.go:73:26:73:30 | inner |
| main.go:72:11:72:25 | struct literal | main.go:72:2:72:6 | definition of inner |
| main.go:72:11:72:25 | struct literal [postupdate] | main.go:72:2:72:6 | definition of inner |
| main.go:73:2:73:7 | definition of middle | main.go:74:25:74:30 | middle |
| main.go:73:12:73:31 | struct literal | main.go:73:2:73:7 | definition of middle |
| main.go:73:12:73:31 | struct literal [postupdate] | main.go:73:2:73:7 | definition of middle |
| main.go:74:2:74:6 | definition of outer | main.go:75:7:75:11 | outer |
| main.go:74:11:74:31 | struct literal | main.go:74:2:74:6 | definition of outer |
| main.go:74:11:74:31 | struct literal [postupdate] | main.go:74:2:74:6 | definition of outer |
| main.go:72:2:72:6 | SSA def(inner) | main.go:73:26:73:30 | inner |
| main.go:72:11:72:25 | struct literal | main.go:72:2:72:6 | SSA def(inner) |
| main.go:72:11:72:25 | struct literal [postupdate] | main.go:72:2:72:6 | SSA def(inner) |
| main.go:73:2:73:7 | SSA def(middle) | main.go:74:25:74:30 | middle |
| main.go:73:12:73:31 | struct literal | main.go:73:2:73:7 | SSA def(middle) |
| main.go:73:12:73:31 | struct literal [postupdate] | main.go:73:2:73:7 | SSA def(middle) |
| main.go:74:2:74:6 | SSA def(outer) | main.go:75:7:75:11 | outer |
| main.go:74:11:74:31 | struct literal | main.go:74:2:74:6 | SSA def(outer) |
| main.go:74:11:74:31 | struct literal [postupdate] | main.go:74:2:74:6 | SSA def(outer) |
| main.go:75:7:75:11 | outer | main.go:76:7:76:11 | outer |
| main.go:76:7:76:11 | outer | main.go:77:7:77:11 | outer |
| main.go:77:7:77:11 | outer | main.go:78:7:78:11 | outer |
| main.go:80:2:80:7 | definition of innerp | main.go:81:27:81:32 | innerp |
| main.go:80:12:80:26 | struct literal | main.go:80:2:80:7 | definition of innerp |
| main.go:80:12:80:26 | struct literal [postupdate] | main.go:80:2:80:7 | definition of innerp |
| main.go:81:2:81:8 | definition of middlep | main.go:82:26:82:32 | middlep |
| main.go:81:13:81:33 | struct literal | main.go:81:2:81:8 | definition of middlep |
| main.go:81:13:81:33 | struct literal [postupdate] | main.go:81:2:81:8 | definition of middlep |
| main.go:82:2:82:7 | definition of outerp | main.go:83:7:83:12 | outerp |
| main.go:82:12:82:33 | struct literal | main.go:82:2:82:7 | definition of outerp |
| main.go:82:12:82:33 | struct literal [postupdate] | main.go:82:2:82:7 | definition of outerp |
| main.go:80:2:80:7 | SSA def(innerp) | main.go:81:27:81:32 | innerp |
| main.go:80:12:80:26 | struct literal | main.go:80:2:80:7 | SSA def(innerp) |
| main.go:80:12:80:26 | struct literal [postupdate] | main.go:80:2:80:7 | SSA def(innerp) |
| main.go:81:2:81:8 | SSA def(middlep) | main.go:82:26:82:32 | middlep |
| main.go:81:13:81:33 | struct literal | main.go:81:2:81:8 | SSA def(middlep) |
| main.go:81:13:81:33 | struct literal [postupdate] | main.go:81:2:81:8 | SSA def(middlep) |
| main.go:82:2:82:7 | SSA def(outerp) | main.go:83:7:83:12 | outerp |
| main.go:82:12:82:33 | struct literal | main.go:82:2:82:7 | SSA def(outerp) |
| main.go:82:12:82:33 | struct literal [postupdate] | main.go:82:2:82:7 | SSA def(outerp) |
| main.go:83:7:83:12 | outerp | main.go:84:7:84:12 | outerp |
| main.go:84:7:84:12 | outerp | main.go:85:7:85:12 | outerp |
| main.go:85:7:85:12 | outerp | main.go:86:7:86:12 | outerp |
| main.go:90:6:90:10 | definition of outer | main.go:91:2:91:6 | outer |
| main.go:90:6:90:10 | zero value for outer | main.go:90:6:90:10 | definition of outer |
| main.go:90:6:90:10 | SSA def(outer) | main.go:91:2:91:6 | outer |
| main.go:90:6:90:10 | zero value for outer | main.go:90:6:90:10 | SSA def(outer) |
| main.go:91:2:91:6 | outer | main.go:92:7:92:11 | outer |
| main.go:91:2:91:6 | outer [postupdate] | main.go:92:7:92:11 | outer |
| main.go:92:7:92:11 | outer | main.go:93:7:93:11 | outer |
| main.go:93:7:93:11 | outer | main.go:94:7:94:11 | outer |
| main.go:94:7:94:11 | outer | main.go:95:7:95:11 | outer |
| main.go:97:6:97:11 | definition of outerp | main.go:98:2:98:7 | outerp |
| main.go:97:6:97:11 | zero value for outerp | main.go:97:6:97:11 | definition of outerp |
| main.go:97:6:97:11 | SSA def(outerp) | main.go:98:2:98:7 | outerp |
| main.go:97:6:97:11 | zero value for outerp | main.go:97:6:97:11 | SSA def(outerp) |
| main.go:98:2:98:7 | outerp | main.go:99:7:99:12 | outerp |
| main.go:98:2:98:7 | outerp [postupdate] | main.go:99:7:99:12 | outerp |
| main.go:99:7:99:12 | outerp | main.go:100:7:100:12 | outerp |
| main.go:100:7:100:12 | outerp | main.go:101:7:101:12 | outerp |
| main.go:101:7:101:12 | outerp | main.go:102:7:102:12 | outerp |
| main.go:106:6:106:10 | definition of outer | main.go:107:2:107:6 | outer |
| main.go:106:6:106:10 | zero value for outer | main.go:106:6:106:10 | definition of outer |
| main.go:106:6:106:10 | SSA def(outer) | main.go:107:2:107:6 | outer |
| main.go:106:6:106:10 | zero value for outer | main.go:106:6:106:10 | SSA def(outer) |
| main.go:107:2:107:6 | outer | main.go:108:7:108:11 | outer |
| main.go:107:2:107:6 | outer [postupdate] | main.go:108:7:108:11 | outer |
| main.go:108:7:108:11 | outer | main.go:109:7:109:11 | outer |
| main.go:109:7:109:11 | outer | main.go:110:7:110:11 | outer |
| main.go:110:7:110:11 | outer | main.go:111:7:111:11 | outer |
| main.go:113:6:113:11 | definition of outerp | main.go:114:2:114:7 | outerp |
| main.go:113:6:113:11 | zero value for outerp | main.go:113:6:113:11 | definition of outerp |
| main.go:113:6:113:11 | SSA def(outerp) | main.go:114:2:114:7 | outerp |
| main.go:113:6:113:11 | zero value for outerp | main.go:113:6:113:11 | SSA def(outerp) |
| main.go:114:2:114:7 | outerp | main.go:115:7:115:12 | outerp |
| main.go:114:2:114:7 | outerp [postupdate] | main.go:115:7:115:12 | outerp |
| main.go:115:7:115:12 | outerp | main.go:116:7:116:12 | outerp |
| main.go:116:7:116:12 | outerp | main.go:117:7:117:12 | outerp |
| main.go:117:7:117:12 | outerp | main.go:118:7:118:12 | outerp |
| main.go:122:6:122:10 | definition of outer | main.go:123:2:123:6 | outer |
| main.go:122:6:122:10 | zero value for outer | main.go:122:6:122:10 | definition of outer |
| main.go:122:6:122:10 | SSA def(outer) | main.go:123:2:123:6 | outer |
| main.go:122:6:122:10 | zero value for outer | main.go:122:6:122:10 | SSA def(outer) |
| main.go:123:2:123:6 | outer | main.go:124:7:124:11 | outer |
| main.go:123:2:123:6 | outer [postupdate] | main.go:124:7:124:11 | outer |
| main.go:124:7:124:11 | outer | main.go:125:7:125:11 | outer |
| main.go:125:7:125:11 | outer | main.go:126:7:126:11 | outer |
| main.go:126:7:126:11 | outer | main.go:127:7:127:11 | outer |
| main.go:129:6:129:11 | definition of outerp | main.go:130:2:130:7 | outerp |
| main.go:129:6:129:11 | zero value for outerp | main.go:129:6:129:11 | definition of outerp |
| main.go:129:6:129:11 | SSA def(outerp) | main.go:130:2:130:7 | outerp |
| main.go:129:6:129:11 | zero value for outerp | main.go:129:6:129:11 | SSA def(outerp) |
| main.go:130:2:130:7 | outerp | main.go:131:7:131:12 | outerp |
| main.go:130:2:130:7 | outerp [postupdate] | main.go:131:7:131:12 | outerp |
| main.go:131:7:131:12 | outerp | main.go:132:7:132:12 | outerp |
| main.go:132:7:132:12 | outerp | main.go:133:7:133:12 | outerp |
| main.go:133:7:133:12 | outerp | main.go:134:7:134:12 | outerp |
| main.go:138:6:138:10 | definition of outer | main.go:139:2:139:6 | outer |
| main.go:138:6:138:10 | zero value for outer | main.go:138:6:138:10 | definition of outer |
| main.go:138:6:138:10 | SSA def(outer) | main.go:139:2:139:6 | outer |
| main.go:138:6:138:10 | zero value for outer | main.go:138:6:138:10 | SSA def(outer) |
| main.go:139:2:139:6 | outer | main.go:140:7:140:11 | outer |
| main.go:139:2:139:6 | outer [postupdate] | main.go:140:7:140:11 | outer |
| main.go:140:7:140:11 | outer | main.go:141:7:141:11 | outer |
| main.go:141:7:141:11 | outer | main.go:142:7:142:11 | outer |
| main.go:142:7:142:11 | outer | main.go:143:7:143:11 | outer |
| main.go:145:6:145:11 | definition of outerp | main.go:146:2:146:7 | outerp |
| main.go:145:6:145:11 | zero value for outerp | main.go:145:6:145:11 | definition of outerp |
| main.go:145:6:145:11 | SSA def(outerp) | main.go:146:2:146:7 | outerp |
| main.go:145:6:145:11 | zero value for outerp | main.go:145:6:145:11 | SSA def(outerp) |
| main.go:146:2:146:7 | outerp | main.go:147:7:147:12 | outerp |
| main.go:146:2:146:7 | outerp [postupdate] | main.go:147:7:147:12 | outerp |
| main.go:147:7:147:12 | outerp | main.go:148:7:148:12 | outerp |

View File

@@ -1,3 +1,5 @@
reverseRead
| main.go:97:2:97:8 | wrapper | Origin of readStep is missing a PostUpdateNode. |
| main.go:117:2:117:2 | p | Origin of readStep is missing a PostUpdateNode. |
| main.go:105:2:105:8 | wrapper | Origin of readStep is missing a PostUpdateNode. |
| main.go:114:2:114:8 | wrapper | Origin of readStep is missing a PostUpdateNode. |
| main.go:135:2:135:2 | p | Origin of readStep is missing a PostUpdateNode. |

View File

@@ -1,34 +1,42 @@
| main.go:15:12:15:12 | x | main.go:13:6:13:6 | definition of x | main.go:13:6:13:6 | x |
| main.go:15:15:15:15 | y | main.go:14:2:14:2 | definition of y | main.go:14:2:14:2 | y |
| main.go:17:3:17:3 | y | main.go:14:2:14:2 | definition of y | main.go:14:2:14:2 | y |
| main.go:19:12:19:12 | x | main.go:13:6:13:6 | definition of x | main.go:13:6:13:6 | x |
| main.go:19:15:19:15 | y | main.go:19:2:19:10 | y = phi(def@14:2, def@17:3) | main.go:14:2:14:2 | y |
| main.go:21:7:21:7 | y | main.go:19:2:19:10 | y = phi(def@14:2, def@17:3) | main.go:14:2:14:2 | y |
| main.go:23:12:23:12 | x | main.go:23:2:23:10 | x = phi(def@13:6, def@21:3) | main.go:13:6:13:6 | x |
| main.go:23:15:23:15 | y | main.go:19:2:19:10 | y = phi(def@14:2, def@17:3) | main.go:14:2:14:2 | y |
| main.go:27:10:27:10 | x | main.go:26:10:26:10 | definition of x | main.go:26:10:26:10 | x |
| main.go:29:10:29:10 | b | main.go:27:5:27:5 | definition of b | main.go:27:5:27:5 | b |
| main.go:29:13:29:13 | a | main.go:27:2:27:2 | definition of a | main.go:27:2:27:2 | a |
| main.go:31:9:31:9 | a | main.go:31:9:31:9 | a = phi(def@27:2, def@29:3) | main.go:27:2:27:2 | a |
| main.go:31:12:31:12 | b | main.go:31:9:31:9 | b = phi(def@27:5, def@29:6) | main.go:27:5:27:5 | b |
| main.go:35:3:35:3 | x | main.go:34:11:34:11 | definition of x | main.go:34:11:34:11 | x |
| main.go:40:10:40:10 | x | main.go:39:2:39:2 | definition of x | main.go:39:2:39:2 | x |
| main.go:42:8:42:10 | ptr | main.go:40:2:40:4 | definition of ptr | main.go:40:2:40:4 | ptr |
| main.go:44:12:44:12 | x | main.go:39:2:39:2 | definition of x | main.go:39:2:39:2 | x |
| main.go:47:13:47:18 | implicit read of result | main.go:48:2:48:7 | definition of result | main.go:47:13:47:18 | result |
| main.go:52:14:52:19 | implicit read of result | main.go:52:14:52:19 | definition of result | main.go:52:14:52:19 | result |
| main.go:61:12:61:12 | x | main.go:58:6:58:9 | x = phi(def@57:6, def@59:3) | main.go:57:6:57:6 | x |
| main.go:64:16:64:16 | i | main.go:65:6:65:9 | i = phi(def@64:16, def@64:6) | main.go:64:6:64:6 | i |
| main.go:70:12:70:12 | y | main.go:65:6:65:9 | y = phi(def@63:2, def@68:3) | main.go:63:2:63:2 | y |
| main.go:73:16:73:16 | i | main.go:74:3:74:3 | i = phi(def@73:16, def@73:6) | main.go:73:6:73:6 | i |
| main.go:79:12:79:12 | z | main.go:74:3:74:3 | definition of z | main.go:72:2:72:2 | z |
| main.go:82:18:82:18 | implicit read of a | main.go:84:5:84:5 | definition of a | main.go:82:18:82:18 | a |
| main.go:82:25:82:25 | implicit read of b | main.go:82:25:82:25 | definition of b | main.go:82:25:82:25 | b |
| main.go:84:9:84:9 | x | main.go:83:2:83:2 | definition of x | main.go:83:2:83:2 | x |
| main.go:84:15:84:15 | x | main.go:83:2:83:2 | definition of x | main.go:83:2:83:2 | x |
| main.go:97:2:97:8 | wrapper | main.go:95:22:95:28 | definition of wrapper | main.go:95:22:95:28 | wrapper |
| main.go:100:9:100:9 | x | main.go:97:2:99:3 | capture variable x | main.go:96:2:96:2 | x |
| main.go:117:2:117:2 | p | main.go:117:2:117:2 | p = phi(def@112:3, def@114:3) | main.go:110:6:110:6 | p |
| main.go:119:12:119:12 | p | main.go:117:2:117:2 | p = phi(def@112:3, def@114:3) | main.go:110:6:110:6 | p |
| main.go:119:17:119:17 | p | main.go:117:2:117:2 | p = phi(def@112:3, def@114:3) | main.go:110:6:110:6 | p |
| main.go:119:24:119:24 | p | main.go:117:2:117:2 | p = phi(def@112:3, def@114:3) | main.go:110:6:110:6 | p |
| main.go:15:12:15:12 | x | main.go:13:6:13:6 | SSA def(x) | main.go:13:6:13:6 | x |
| main.go:15:15:15:15 | y | main.go:14:2:14:2 | SSA def(y) | main.go:14:2:14:2 | y |
| main.go:17:3:17:3 | y | main.go:14:2:14:2 | SSA def(y) | main.go:14:2:14:2 | y |
| main.go:19:12:19:12 | x | main.go:13:6:13:6 | SSA def(x) | main.go:13:6:13:6 | x |
| main.go:19:15:19:15 | y | main.go:19:2:19:10 | SSA phi(y) | main.go:14:2:14:2 | y |
| main.go:21:7:21:7 | y | main.go:19:2:19:10 | SSA phi(y) | main.go:14:2:14:2 | y |
| main.go:23:12:23:12 | x | main.go:23:2:23:10 | SSA phi(x) | main.go:13:6:13:6 | x |
| main.go:23:15:23:15 | y | main.go:19:2:19:10 | SSA phi(y) | main.go:14:2:14:2 | y |
| main.go:27:10:27:10 | x | main.go:26:10:26:10 | SSA def(x) | main.go:26:10:26:10 | x |
| main.go:29:10:29:10 | b | main.go:27:5:27:5 | SSA def(b) | main.go:27:5:27:5 | b |
| main.go:29:13:29:13 | a | main.go:27:2:27:2 | SSA def(a) | main.go:27:2:27:2 | a |
| main.go:31:9:31:9 | a | main.go:31:9:31:9 | SSA phi(a) | main.go:27:2:27:2 | a |
| main.go:31:12:31:12 | b | main.go:31:9:31:9 | SSA phi(b) | main.go:27:5:27:5 | b |
| main.go:35:3:35:3 | x | main.go:34:11:34:11 | SSA def(x) | main.go:34:11:34:11 | x |
| main.go:40:10:40:10 | x | main.go:39:2:39:2 | SSA def(x) | main.go:39:2:39:2 | x |
| main.go:42:8:42:10 | ptr | main.go:40:2:40:4 | SSA def(ptr) | main.go:40:2:40:4 | ptr |
| main.go:44:12:44:12 | x | main.go:39:2:39:2 | SSA def(x) | main.go:39:2:39:2 | x |
| main.go:47:13:47:18 | implicit read of result | main.go:48:2:48:7 | SSA def(result) | main.go:47:13:47:18 | result |
| main.go:52:14:52:19 | implicit read of result | main.go:52:14:52:19 | SSA def(result) | main.go:52:14:52:19 | result |
| main.go:61:12:61:12 | x | main.go:58:6:58:9 | SSA phi(x) | main.go:57:6:57:6 | x |
| main.go:64:16:64:16 | i | main.go:65:6:65:9 | SSA phi(i) | main.go:64:6:64:6 | i |
| main.go:70:12:70:12 | y | main.go:65:6:65:9 | SSA phi(y) | main.go:63:2:63:2 | y |
| main.go:73:16:73:16 | i | main.go:74:3:74:3 | SSA phi(i) | main.go:73:6:73:6 | i |
| main.go:79:12:79:12 | z | main.go:74:3:74:3 | SSA def(z) | main.go:72:2:72:2 | z |
| main.go:82:18:82:18 | implicit read of a | main.go:84:5:84:5 | SSA def(a) | main.go:82:18:82:18 | a |
| main.go:82:25:82:25 | implicit read of b | main.go:82:25:82:25 | SSA def(b) | main.go:82:25:82:25 | b |
| main.go:84:9:84:9 | x | main.go:83:2:83:2 | SSA def(x) | main.go:83:2:83:2 | x |
| main.go:84:15:84:15 | x | main.go:83:2:83:2 | SSA def(x) | main.go:83:2:83:2 | x |
| main.go:97:2:97:8 | wrapper | main.go:95:22:95:28 | SSA def(wrapper) | main.go:95:22:95:28 | wrapper |
| main.go:100:9:100:9 | x | main.go:97:2:99:3 | SSA def(x) | main.go:96:2:96:2 | x |
| main.go:105:2:105:8 | wrapper | main.go:103:20:103:26 | SSA def(wrapper) | main.go:103:20:103:26 | wrapper |
| main.go:106:8:106:8 | x | main.go:105:16:108:2 | SSA def(x) | main.go:104:2:104:2 | x |
| main.go:107:7:107:7 | y | main.go:106:3:106:3 | SSA def(y) | main.go:106:3:106:3 | y |
| main.go:109:9:109:9 | x | main.go:104:2:104:2 | SSA def(x) | main.go:104:2:104:2 | x |
| main.go:114:2:114:8 | wrapper | main.go:112:29:112:35 | SSA def(wrapper) | main.go:112:29:112:35 | wrapper |
| main.go:115:8:115:8 | x | main.go:114:16:117:2 | SSA def(x) | main.go:113:2:113:2 | x |
| main.go:116:7:116:7 | y | main.go:115:3:115:3 | SSA def(y) | main.go:115:3:115:3 | y |
| main.go:118:9:118:9 | x | main.go:114:2:117:3 | SSA def(x) | main.go:113:2:113:2 | x |
| main.go:135:2:135:2 | p | main.go:135:2:135:2 | SSA phi(p) | main.go:128:6:128:6 | p |
| main.go:137:12:137:12 | p | main.go:135:2:135:2 | SSA phi(p) | main.go:128:6:128:6 | p |
| main.go:137:17:137:17 | p | main.go:135:2:135:2 | SSA phi(p) | main.go:128:6:128:6 | p |
| main.go:137:24:137:24 | p | main.go:135:2:135:2 | SSA phi(p) | main.go:128:6:128:6 | p |

View File

@@ -1,41 +1,51 @@
| main.go:13:6:13:6 | definition of x |
| main.go:14:2:14:2 | definition of y |
| main.go:17:3:17:3 | definition of y |
| main.go:19:2:19:10 | y = phi(def@14:2, def@17:3) |
| main.go:21:3:21:3 | definition of x |
| main.go:23:2:23:10 | x = phi(def@13:6, def@21:3) |
| main.go:26:10:26:10 | definition of x |
| main.go:27:2:27:2 | definition of a |
| main.go:27:5:27:5 | definition of b |
| main.go:29:3:29:3 | definition of a |
| main.go:29:6:29:6 | definition of b |
| main.go:31:9:31:9 | a = phi(def@27:2, def@29:3) |
| main.go:31:9:31:9 | b = phi(def@27:5, def@29:6) |
| main.go:34:11:34:11 | definition of x |
| main.go:39:2:39:2 | definition of x |
| main.go:40:2:40:4 | definition of ptr |
| main.go:48:2:48:7 | definition of result |
| main.go:52:14:52:19 | definition of result |
| main.go:57:6:57:6 | definition of x |
| main.go:58:6:58:9 | x = phi(def@57:6, def@59:3) |
| main.go:59:3:59:3 | definition of x |
| main.go:63:2:63:2 | definition of y |
| main.go:64:6:64:6 | definition of i |
| main.go:64:16:64:18 | definition of i |
| main.go:65:6:65:9 | i = phi(def@64:16, def@64:6) |
| main.go:65:6:65:9 | y = phi(def@63:2, def@68:3) |
| main.go:68:3:68:3 | definition of y |
| main.go:73:6:73:6 | definition of i |
| main.go:73:16:73:18 | definition of i |
| main.go:74:3:74:3 | definition of z |
| main.go:74:3:74:3 | i = phi(def@73:16, def@73:6) |
| main.go:82:25:82:25 | definition of b |
| main.go:83:2:83:2 | definition of x |
| main.go:84:5:84:5 | definition of a |
| main.go:95:22:95:28 | definition of wrapper |
| main.go:96:2:96:2 | definition of x |
| main.go:97:2:99:3 | capture variable x |
| main.go:98:3:98:3 | definition of x |
| main.go:112:3:112:3 | definition of p |
| main.go:114:3:114:3 | definition of p |
| main.go:117:2:117:2 | p = phi(def@112:3, def@114:3) |
| main.go:13:6:13:6 | SSA def(x) |
| main.go:14:2:14:2 | SSA def(y) |
| main.go:17:3:17:3 | SSA def(y) |
| main.go:19:2:19:10 | SSA phi(y) |
| main.go:21:3:21:3 | SSA def(x) |
| main.go:23:2:23:10 | SSA phi(x) |
| main.go:26:10:26:10 | SSA def(x) |
| main.go:27:2:27:2 | SSA def(a) |
| main.go:27:5:27:5 | SSA def(b) |
| main.go:29:3:29:3 | SSA def(a) |
| main.go:29:6:29:6 | SSA def(b) |
| main.go:31:9:31:9 | SSA phi(a) |
| main.go:31:9:31:9 | SSA phi(b) |
| main.go:34:11:34:11 | SSA def(x) |
| main.go:39:2:39:2 | SSA def(x) |
| main.go:40:2:40:4 | SSA def(ptr) |
| main.go:48:2:48:7 | SSA def(result) |
| main.go:52:14:52:19 | SSA def(result) |
| main.go:57:6:57:6 | SSA def(x) |
| main.go:58:6:58:9 | SSA phi(x) |
| main.go:59:3:59:3 | SSA def(x) |
| main.go:63:2:63:2 | SSA def(y) |
| main.go:64:6:64:6 | SSA def(i) |
| main.go:64:16:64:18 | SSA def(i) |
| main.go:65:6:65:9 | SSA phi(i) |
| main.go:65:6:65:9 | SSA phi(y) |
| main.go:68:3:68:3 | SSA def(y) |
| main.go:73:6:73:6 | SSA def(i) |
| main.go:73:16:73:18 | SSA def(i) |
| main.go:74:3:74:3 | SSA def(z) |
| main.go:74:3:74:3 | SSA phi(i) |
| main.go:82:25:82:25 | SSA def(b) |
| main.go:83:2:83:2 | SSA def(x) |
| main.go:84:5:84:5 | SSA def(a) |
| main.go:95:22:95:28 | SSA def(wrapper) |
| main.go:96:2:96:2 | SSA def(x) |
| main.go:97:2:99:3 | SSA def(x) |
| main.go:98:3:98:3 | SSA def(x) |
| main.go:103:20:103:26 | SSA def(wrapper) |
| main.go:104:2:104:2 | SSA def(x) |
| main.go:105:16:108:2 | SSA def(x) |
| main.go:106:3:106:3 | SSA def(y) |
| main.go:112:29:112:35 | SSA def(wrapper) |
| main.go:113:2:113:2 | SSA def(x) |
| main.go:114:2:117:3 | SSA def(x) |
| main.go:114:16:117:2 | SSA def(x) |
| main.go:115:3:115:3 | SSA def(y) |
| main.go:116:3:116:3 | SSA def(x) |
| main.go:130:3:130:3 | SSA def(p) |
| main.go:132:3:132:3 | SSA def(p) |
| main.go:135:2:135:2 | SSA phi(p) |

View File

@@ -1,46 +1,58 @@
| main.go:13:6:13:6 | (def@13:6) | x |
| main.go:14:2:14:2 | (def@14:2) | y |
| main.go:17:3:17:3 | (def@17:3) | y |
| main.go:19:2:19:10 | (phi@19:2) | y |
| main.go:21:3:21:3 | (def@21:3) | x |
| main.go:23:2:23:10 | (phi@23:2) | x |
| main.go:26:10:26:10 | (def@26:10) | x |
| main.go:27:2:27:2 | (def@27:2) | a |
| main.go:27:5:27:5 | (def@27:5) | b |
| main.go:29:3:29:3 | (def@29:3) | a |
| main.go:29:6:29:6 | (def@29:6) | b |
| main.go:31:9:31:9 | (phi@31:9) | a |
| main.go:31:9:31:9 | (phi@31:9) | b |
| main.go:34:11:34:11 | (def@34:11) | x |
| main.go:39:2:39:2 | (def@39:2) | x |
| main.go:40:2:40:4 | (def@40:2) | ptr |
| main.go:48:2:48:7 | (def@48:2) | result |
| main.go:52:14:52:19 | (def@52:14) | result |
| main.go:57:6:57:6 | (def@57:6) | x |
| main.go:58:6:58:9 | (phi@58:6) | x |
| main.go:59:3:59:3 | (def@59:3) | x |
| main.go:63:2:63:2 | (def@63:2) | y |
| main.go:64:6:64:6 | (def@64:6) | i |
| main.go:64:16:64:18 | (def@64:16) | i |
| main.go:65:6:65:9 | (phi@65:6) | i |
| main.go:65:6:65:9 | (phi@65:6) | y |
| main.go:68:3:68:3 | (def@68:3) | y |
| main.go:73:6:73:6 | (def@73:6) | i |
| main.go:73:16:73:18 | (def@73:16) | i |
| main.go:74:3:74:3 | (def@74:3) | z |
| main.go:74:3:74:3 | (phi@74:3) | i |
| main.go:82:25:82:25 | (def@82:25) | b |
| main.go:83:2:83:2 | (def@83:2) | x |
| main.go:84:5:84:5 | (def@84:5) | a |
| main.go:95:22:95:28 | (def@95:22) | wrapper |
| main.go:95:22:95:28 | (def@95:22).s | wrapper.s |
| main.go:96:2:96:2 | (def@96:2) | x |
| main.go:97:2:99:3 | (capture@97:2) | x |
| main.go:98:3:98:3 | (def@98:3) | x |
| main.go:112:3:112:3 | (def@112:3) | p |
| main.go:114:3:114:3 | (def@114:3) | p |
| main.go:117:2:117:2 | (phi@117:2) | p |
| main.go:117:2:117:2 | (phi@117:2).a | p.a |
| main.go:117:2:117:2 | (phi@117:2).b | p.b |
| main.go:117:2:117:2 | (phi@117:2).b.a | p.b.a |
| main.go:117:2:117:2 | (phi@117:2).c | p.c |
| main.go:13:6:13:6 | (SSA def(x)) | x |
| main.go:14:2:14:2 | (SSA def(y)) | y |
| main.go:17:3:17:3 | (SSA def(y)) | y |
| main.go:19:2:19:10 | (SSA phi(y)) | y |
| main.go:21:3:21:3 | (SSA def(x)) | x |
| main.go:23:2:23:10 | (SSA phi(x)) | x |
| main.go:26:10:26:10 | (SSA def(x)) | x |
| main.go:27:2:27:2 | (SSA def(a)) | a |
| main.go:27:5:27:5 | (SSA def(b)) | b |
| main.go:29:3:29:3 | (SSA def(a)) | a |
| main.go:29:6:29:6 | (SSA def(b)) | b |
| main.go:31:9:31:9 | (SSA phi(a)) | a |
| main.go:31:9:31:9 | (SSA phi(b)) | b |
| main.go:34:11:34:11 | (SSA def(x)) | x |
| main.go:39:2:39:2 | (SSA def(x)) | x |
| main.go:40:2:40:4 | (SSA def(ptr)) | ptr |
| main.go:48:2:48:7 | (SSA def(result)) | result |
| main.go:52:14:52:19 | (SSA def(result)) | result |
| main.go:57:6:57:6 | (SSA def(x)) | x |
| main.go:58:6:58:9 | (SSA phi(x)) | x |
| main.go:59:3:59:3 | (SSA def(x)) | x |
| main.go:63:2:63:2 | (SSA def(y)) | y |
| main.go:64:6:64:6 | (SSA def(i)) | i |
| main.go:64:16:64:18 | (SSA def(i)) | i |
| main.go:65:6:65:9 | (SSA phi(i)) | i |
| main.go:65:6:65:9 | (SSA phi(y)) | y |
| main.go:68:3:68:3 | (SSA def(y)) | y |
| main.go:73:6:73:6 | (SSA def(i)) | i |
| main.go:73:16:73:18 | (SSA def(i)) | i |
| main.go:74:3:74:3 | (SSA def(z)) | z |
| main.go:74:3:74:3 | (SSA phi(i)) | i |
| main.go:82:25:82:25 | (SSA def(b)) | b |
| main.go:83:2:83:2 | (SSA def(x)) | x |
| main.go:84:5:84:5 | (SSA def(a)) | a |
| main.go:95:22:95:28 | (SSA def(wrapper)) | wrapper |
| main.go:95:22:95:28 | (SSA def(wrapper)).s | wrapper.s |
| main.go:96:2:96:2 | (SSA def(x)) | x |
| main.go:97:2:99:3 | (SSA def(x)) | x |
| main.go:98:3:98:3 | (SSA def(x)) | x |
| main.go:103:20:103:26 | (SSA def(wrapper)) | wrapper |
| main.go:103:20:103:26 | (SSA def(wrapper)).s | wrapper.s |
| main.go:104:2:104:2 | (SSA def(x)) | x |
| main.go:105:16:108:2 | (SSA def(x)) | x |
| main.go:106:3:106:3 | (SSA def(y)) | y |
| main.go:112:29:112:35 | (SSA def(wrapper)) | wrapper |
| main.go:112:29:112:35 | (SSA def(wrapper)).s | wrapper.s |
| main.go:113:2:113:2 | (SSA def(x)) | x |
| main.go:114:2:117:3 | (SSA def(x)) | x |
| main.go:114:16:117:2 | (SSA def(x)) | x |
| main.go:115:3:115:3 | (SSA def(y)) | y |
| main.go:116:3:116:3 | (SSA def(x)) | x |
| main.go:130:3:130:3 | (SSA def(p)) | p |
| main.go:132:3:132:3 | (SSA def(p)) | p |
| main.go:135:2:135:2 | (SSA phi(p)) | p |
| main.go:135:2:135:2 | (SSA phi(p)).a | p.a |
| main.go:135:2:135:2 | (SSA phi(p)).b | p.b |
| main.go:135:2:135:2 | (SSA phi(p)).b.a | p.b.a |
| main.go:135:2:135:2 | (SSA phi(p)).c | p.c |

View File

@@ -32,16 +32,23 @@
| main.go:95:22:95:28 | initialization of wrapper | main.go:95:22:95:28 | wrapper | main.go:95:22:95:28 | argument corresponding to wrapper |
| main.go:96:2:96:2 | assignment to x | main.go:96:2:96:2 | x | main.go:96:7:96:7 | 0 |
| main.go:98:3:98:3 | assignment to x | main.go:96:2:96:2 | x | main.go:98:7:98:7 | 1 |
| main.go:110:6:110:6 | assignment to p | main.go:110:6:110:6 | p | main.go:110:6:110:6 | zero value for p |
| main.go:112:3:112:3 | assignment to p | main.go:110:6:110:6 | p | main.go:112:7:112:24 | struct literal |
| main.go:112:9:112:9 | init of 2 | main.go:104:2:104:2 | a | main.go:112:9:112:9 | 2 |
| main.go:112:12:112:18 | init of struct literal | main.go:105:2:105:2 | b | main.go:112:12:112:18 | struct literal |
| main.go:112:14:112:14 | init of 1 | main.go:89:2:89:2 | a | main.go:112:14:112:14 | 1 |
| main.go:112:17:112:17 | init of 5 | main.go:90:2:90:2 | b | main.go:112:17:112:17 | 5 |
| main.go:112:21:112:23 | init of 'n' | main.go:106:2:106:2 | c | main.go:112:21:112:23 | 'n' |
| main.go:114:3:114:3 | assignment to p | main.go:110:6:110:6 | p | main.go:114:7:114:24 | struct literal |
| main.go:114:9:114:9 | init of 3 | main.go:104:2:104:2 | a | main.go:114:9:114:9 | 3 |
| main.go:114:12:114:18 | init of struct literal | main.go:105:2:105:2 | b | main.go:114:12:114:18 | struct literal |
| main.go:114:14:114:14 | init of 4 | main.go:89:2:89:2 | a | main.go:114:14:114:14 | 4 |
| main.go:114:17:114:17 | init of 5 | main.go:90:2:90:2 | b | main.go:114:17:114:17 | 5 |
| main.go:114:21:114:23 | init of '2' | main.go:106:2:106:2 | c | main.go:114:21:114:23 | '2' |
| main.go:103:20:103:26 | initialization of wrapper | main.go:103:20:103:26 | wrapper | main.go:103:20:103:26 | argument corresponding to wrapper |
| main.go:104:2:104:2 | assignment to x | main.go:104:2:104:2 | x | main.go:104:7:104:7 | 0 |
| main.go:106:3:106:3 | assignment to y | main.go:106:3:106:3 | y | main.go:106:8:106:8 | x |
| main.go:112:29:112:35 | initialization of wrapper | main.go:112:29:112:35 | wrapper | main.go:112:29:112:35 | argument corresponding to wrapper |
| main.go:113:2:113:2 | assignment to x | main.go:113:2:113:2 | x | main.go:113:7:113:7 | 0 |
| main.go:115:3:115:3 | assignment to y | main.go:115:3:115:3 | y | main.go:115:8:115:12 | ...+... |
| main.go:116:3:116:3 | assignment to x | main.go:113:2:113:2 | x | main.go:116:7:116:7 | y |
| main.go:128:6:128:6 | assignment to p | main.go:128:6:128:6 | p | main.go:128:6:128:6 | zero value for p |
| main.go:130:3:130:3 | assignment to p | main.go:128:6:128:6 | p | main.go:130:7:130:24 | struct literal |
| main.go:130:9:130:9 | init of 2 | main.go:122:2:122:2 | a | main.go:130:9:130:9 | 2 |
| main.go:130:12:130:18 | init of struct literal | main.go:123:2:123:2 | b | main.go:130:12:130:18 | struct literal |
| main.go:130:14:130:14 | init of 1 | main.go:89:2:89:2 | a | main.go:130:14:130:14 | 1 |
| main.go:130:17:130:17 | init of 5 | main.go:90:2:90:2 | b | main.go:130:17:130:17 | 5 |
| main.go:130:21:130:23 | init of 'n' | main.go:124:2:124:2 | c | main.go:130:21:130:23 | 'n' |
| main.go:132:3:132:3 | assignment to p | main.go:128:6:128:6 | p | main.go:132:7:132:24 | struct literal |
| main.go:132:9:132:9 | init of 3 | main.go:122:2:122:2 | a | main.go:132:9:132:9 | 3 |
| main.go:132:12:132:18 | init of struct literal | main.go:123:2:123:2 | b | main.go:132:12:132:18 | struct literal |
| main.go:132:14:132:14 | init of 4 | main.go:89:2:89:2 | a | main.go:132:14:132:14 | 4 |
| main.go:132:17:132:17 | init of 5 | main.go:90:2:90:2 | b | main.go:132:17:132:17 | 5 |
| main.go:132:21:132:23 | init of '2' | main.go:124:2:124:2 | c | main.go:132:21:132:23 | '2' |

View File

@@ -28,13 +28,29 @@
| main.go:84:15:84:15 | x | main.go:83:2:83:2 | x |
| main.go:97:2:97:8 | wrapper | main.go:95:22:95:28 | wrapper |
| main.go:97:2:97:10 | selection of s | main.go:95:38:95:38 | s |
| main.go:97:2:97:10 | selection of s | main.go:103:36:103:36 | s |
| main.go:97:2:97:10 | selection of s | main.go:112:45:112:45 | s |
| main.go:100:9:100:9 | x | main.go:96:2:96:2 | x |
| main.go:117:2:117:2 | p | main.go:110:6:110:6 | p |
| main.go:117:2:117:4 | selection of b | main.go:105:2:105:2 | b |
| main.go:119:12:119:12 | p | main.go:110:6:110:6 | p |
| main.go:119:12:119:14 | selection of a | main.go:104:2:104:2 | a |
| main.go:119:17:119:17 | p | main.go:110:6:110:6 | p |
| main.go:119:17:119:19 | selection of b | main.go:105:2:105:2 | b |
| main.go:119:17:119:21 | selection of a | main.go:89:2:89:2 | a |
| main.go:119:24:119:24 | p | main.go:110:6:110:6 | p |
| main.go:119:24:119:26 | selection of c | main.go:106:2:106:2 | c |
| main.go:105:2:105:8 | wrapper | main.go:103:20:103:26 | wrapper |
| main.go:105:2:105:10 | selection of s | main.go:95:38:95:38 | s |
| main.go:105:2:105:10 | selection of s | main.go:103:36:103:36 | s |
| main.go:105:2:105:10 | selection of s | main.go:112:45:112:45 | s |
| main.go:106:8:106:8 | x | main.go:104:2:104:2 | x |
| main.go:107:7:107:7 | y | main.go:106:3:106:3 | y |
| main.go:109:9:109:9 | x | main.go:104:2:104:2 | x |
| main.go:114:2:114:8 | wrapper | main.go:112:29:112:35 | wrapper |
| main.go:114:2:114:10 | selection of s | main.go:95:38:95:38 | s |
| main.go:114:2:114:10 | selection of s | main.go:103:36:103:36 | s |
| main.go:114:2:114:10 | selection of s | main.go:112:45:112:45 | s |
| main.go:115:8:115:8 | x | main.go:113:2:113:2 | x |
| main.go:116:7:116:7 | y | main.go:115:3:115:3 | y |
| main.go:118:9:118:9 | x | main.go:113:2:113:2 | x |
| main.go:135:2:135:2 | p | main.go:128:6:128:6 | p |
| main.go:135:2:135:4 | selection of b | main.go:123:2:123:2 | b |
| main.go:137:12:137:12 | p | main.go:128:6:128:6 | p |
| main.go:137:12:137:14 | selection of a | main.go:122:2:122:2 | a |
| main.go:137:17:137:17 | p | main.go:128:6:128:6 | p |
| main.go:137:17:137:19 | selection of b | main.go:123:2:123:2 | b |
| main.go:137:17:137:21 | selection of a | main.go:89:2:89:2 | a |
| main.go:137:24:137:24 | p | main.go:128:6:128:6 | p |
| main.go:137:24:137:26 | selection of c | main.go:124:2:124:2 | c |

View File

@@ -100,6 +100,24 @@ func updateInClosure(wrapper struct{ s }) int {
return x
}
func readInClosure(wrapper struct{ s }) int {
x := 0
wrapper.s.foo(func() {
y := x
_ = y
})
return x
}
func readAndUpdateInClosure(wrapper struct{ s }) int {
x := 0
wrapper.s.foo(func() {
y := x + 1
x = y
})
return x
}
type t struct {
a int
b s

View File

@@ -1,73 +1,73 @@
#select
| test.go:154:14:154:21 | password | test.go:153:17:153:24 | definition of password | test.go:154:14:154:21 | password | $@ flows to a logging call. | test.go:153:17:153:24 | definition of password | Sensitive data returned by an access to password |
| test.go:155:17:155:24 | password | test.go:153:17:153:24 | definition of password | test.go:155:17:155:24 | password | $@ flows to a logging call. | test.go:153:17:153:24 | definition of password | Sensitive data returned by an access to password |
| test.go:156:14:156:21 | password | test.go:153:17:153:24 | definition of password | test.go:156:14:156:21 | password | $@ flows to a logging call. | test.go:153:17:153:24 | definition of password | Sensitive data returned by an access to password |
| test.go:157:18:157:25 | password | test.go:153:17:153:24 | definition of password | test.go:157:18:157:25 | password | $@ flows to a logging call. | test.go:153:17:153:24 | definition of password | Sensitive data returned by an access to password |
| test.go:158:14:158:21 | password | test.go:153:17:153:24 | definition of password | test.go:158:14:158:21 | password | $@ flows to a logging call. | test.go:153:17:153:24 | definition of password | Sensitive data returned by an access to password |
| test.go:159:13:159:20 | password | test.go:153:17:153:24 | definition of password | test.go:159:13:159:20 | password | $@ flows to a logging call. | test.go:153:17:153:24 | definition of password | Sensitive data returned by an access to password |
| test.go:160:22:160:29 | password | test.go:153:17:153:24 | definition of password | test.go:160:22:160:29 | password | $@ flows to a logging call. | test.go:153:17:153:24 | definition of password | Sensitive data returned by an access to password |
| test.go:161:15:161:22 | password | test.go:153:17:153:24 | definition of password | test.go:161:15:161:22 | password | $@ flows to a logging call. | test.go:153:17:153:24 | definition of password | Sensitive data returned by an access to password |
| test.go:162:14:162:21 | password | test.go:153:17:153:24 | definition of password | test.go:162:14:162:21 | password | $@ flows to a logging call. | test.go:153:17:153:24 | definition of password | Sensitive data returned by an access to password |
| test.go:163:13:163:20 | password | test.go:153:17:153:24 | definition of password | test.go:163:13:163:20 | password | $@ flows to a logging call. | test.go:153:17:153:24 | definition of password | Sensitive data returned by an access to password |
| test.go:164:16:164:23 | password | test.go:153:17:153:24 | definition of password | test.go:164:16:164:23 | password | $@ flows to a logging call. | test.go:153:17:153:24 | definition of password | Sensitive data returned by an access to password |
| test.go:165:13:165:20 | password | test.go:153:17:153:24 | definition of password | test.go:165:13:165:20 | password | $@ flows to a logging call. | test.go:153:17:153:24 | definition of password | Sensitive data returned by an access to password |
| test.go:166:16:166:23 | password | test.go:153:17:153:24 | definition of password | test.go:166:16:166:23 | password | $@ flows to a logging call. | test.go:153:17:153:24 | definition of password | Sensitive data returned by an access to password |
| test.go:167:13:167:20 | password | test.go:153:17:153:24 | definition of password | test.go:167:13:167:20 | password | $@ flows to a logging call. | test.go:153:17:153:24 | definition of password | Sensitive data returned by an access to password |
| test.go:168:17:168:24 | password | test.go:153:17:153:24 | definition of password | test.go:168:17:168:24 | password | $@ flows to a logging call. | test.go:153:17:153:24 | definition of password | Sensitive data returned by an access to password |
| test.go:169:13:169:20 | password | test.go:153:17:153:24 | definition of password | test.go:169:13:169:20 | password | $@ flows to a logging call. | test.go:153:17:153:24 | definition of password | Sensitive data returned by an access to password |
| test.go:170:12:170:19 | password | test.go:153:17:153:24 | definition of password | test.go:170:12:170:19 | password | $@ flows to a logging call. | test.go:153:17:153:24 | definition of password | Sensitive data returned by an access to password |
| test.go:171:21:171:28 | password | test.go:153:17:153:24 | definition of password | test.go:171:21:171:28 | password | $@ flows to a logging call. | test.go:153:17:153:24 | definition of password | Sensitive data returned by an access to password |
| test.go:172:14:172:21 | password | test.go:153:17:153:24 | definition of password | test.go:172:14:172:21 | password | $@ flows to a logging call. | test.go:153:17:153:24 | definition of password | Sensitive data returned by an access to password |
| test.go:173:13:173:20 | password | test.go:153:17:153:24 | definition of password | test.go:173:13:173:20 | password | $@ flows to a logging call. | test.go:153:17:153:24 | definition of password | Sensitive data returned by an access to password |
| test.go:174:12:174:19 | password | test.go:153:17:153:24 | definition of password | test.go:174:12:174:19 | password | $@ flows to a logging call. | test.go:153:17:153:24 | definition of password | Sensitive data returned by an access to password |
| test.go:175:15:175:22 | password | test.go:153:17:153:24 | definition of password | test.go:175:15:175:22 | password | $@ flows to a logging call. | test.go:153:17:153:24 | definition of password | Sensitive data returned by an access to password |
| test.go:176:15:176:22 | password | test.go:153:17:153:24 | definition of password | test.go:176:15:176:22 | password | $@ flows to a logging call. | test.go:153:17:153:24 | definition of password | Sensitive data returned by an access to password |
| test.go:177:18:177:25 | password | test.go:153:17:153:24 | definition of password | test.go:177:18:177:25 | password | $@ flows to a logging call. | test.go:153:17:153:24 | definition of password | Sensitive data returned by an access to password |
| test.go:178:15:178:22 | password | test.go:153:17:153:24 | definition of password | test.go:178:15:178:22 | password | $@ flows to a logging call. | test.go:153:17:153:24 | definition of password | Sensitive data returned by an access to password |
| test.go:179:19:179:26 | password | test.go:153:17:153:24 | definition of password | test.go:179:19:179:26 | password | $@ flows to a logging call. | test.go:153:17:153:24 | definition of password | Sensitive data returned by an access to password |
| test.go:180:15:180:22 | password | test.go:153:17:153:24 | definition of password | test.go:180:15:180:22 | password | $@ flows to a logging call. | test.go:153:17:153:24 | definition of password | Sensitive data returned by an access to password |
| test.go:181:14:181:21 | password | test.go:153:17:153:24 | definition of password | test.go:181:14:181:21 | password | $@ flows to a logging call. | test.go:153:17:153:24 | definition of password | Sensitive data returned by an access to password |
| test.go:182:23:182:30 | password | test.go:153:17:153:24 | definition of password | test.go:182:23:182:30 | password | $@ flows to a logging call. | test.go:153:17:153:24 | definition of password | Sensitive data returned by an access to password |
| test.go:183:16:183:23 | password | test.go:153:17:153:24 | definition of password | test.go:183:16:183:23 | password | $@ flows to a logging call. | test.go:153:17:153:24 | definition of password | Sensitive data returned by an access to password |
| test.go:184:15:184:22 | password | test.go:153:17:153:24 | definition of password | test.go:184:15:184:22 | password | $@ flows to a logging call. | test.go:153:17:153:24 | definition of password | Sensitive data returned by an access to password |
| test.go:185:14:185:21 | password | test.go:153:17:153:24 | definition of password | test.go:185:14:185:21 | password | $@ flows to a logging call. | test.go:153:17:153:24 | definition of password | Sensitive data returned by an access to password |
| test.go:186:17:186:24 | password | test.go:153:17:153:24 | definition of password | test.go:186:17:186:24 | password | $@ flows to a logging call. | test.go:153:17:153:24 | definition of password | Sensitive data returned by an access to password |
| test.go:187:16:187:23 | password | test.go:153:17:153:24 | definition of password | test.go:187:16:187:23 | password | $@ flows to a logging call. | test.go:153:17:153:24 | definition of password | Sensitive data returned by an access to password |
| test.go:154:14:154:21 | password | test.go:153:17:153:24 | SSA def(password) | test.go:154:14:154:21 | password | $@ flows to a logging call. | test.go:153:17:153:24 | SSA def(password) | Sensitive data returned by an access to password |
| test.go:155:17:155:24 | password | test.go:153:17:153:24 | SSA def(password) | test.go:155:17:155:24 | password | $@ flows to a logging call. | test.go:153:17:153:24 | SSA def(password) | Sensitive data returned by an access to password |
| test.go:156:14:156:21 | password | test.go:153:17:153:24 | SSA def(password) | test.go:156:14:156:21 | password | $@ flows to a logging call. | test.go:153:17:153:24 | SSA def(password) | Sensitive data returned by an access to password |
| test.go:157:18:157:25 | password | test.go:153:17:153:24 | SSA def(password) | test.go:157:18:157:25 | password | $@ flows to a logging call. | test.go:153:17:153:24 | SSA def(password) | Sensitive data returned by an access to password |
| test.go:158:14:158:21 | password | test.go:153:17:153:24 | SSA def(password) | test.go:158:14:158:21 | password | $@ flows to a logging call. | test.go:153:17:153:24 | SSA def(password) | Sensitive data returned by an access to password |
| test.go:159:13:159:20 | password | test.go:153:17:153:24 | SSA def(password) | test.go:159:13:159:20 | password | $@ flows to a logging call. | test.go:153:17:153:24 | SSA def(password) | Sensitive data returned by an access to password |
| test.go:160:22:160:29 | password | test.go:153:17:153:24 | SSA def(password) | test.go:160:22:160:29 | password | $@ flows to a logging call. | test.go:153:17:153:24 | SSA def(password) | Sensitive data returned by an access to password |
| test.go:161:15:161:22 | password | test.go:153:17:153:24 | SSA def(password) | test.go:161:15:161:22 | password | $@ flows to a logging call. | test.go:153:17:153:24 | SSA def(password) | Sensitive data returned by an access to password |
| test.go:162:14:162:21 | password | test.go:153:17:153:24 | SSA def(password) | test.go:162:14:162:21 | password | $@ flows to a logging call. | test.go:153:17:153:24 | SSA def(password) | Sensitive data returned by an access to password |
| test.go:163:13:163:20 | password | test.go:153:17:153:24 | SSA def(password) | test.go:163:13:163:20 | password | $@ flows to a logging call. | test.go:153:17:153:24 | SSA def(password) | Sensitive data returned by an access to password |
| test.go:164:16:164:23 | password | test.go:153:17:153:24 | SSA def(password) | test.go:164:16:164:23 | password | $@ flows to a logging call. | test.go:153:17:153:24 | SSA def(password) | Sensitive data returned by an access to password |
| test.go:165:13:165:20 | password | test.go:153:17:153:24 | SSA def(password) | test.go:165:13:165:20 | password | $@ flows to a logging call. | test.go:153:17:153:24 | SSA def(password) | Sensitive data returned by an access to password |
| test.go:166:16:166:23 | password | test.go:153:17:153:24 | SSA def(password) | test.go:166:16:166:23 | password | $@ flows to a logging call. | test.go:153:17:153:24 | SSA def(password) | Sensitive data returned by an access to password |
| test.go:167:13:167:20 | password | test.go:153:17:153:24 | SSA def(password) | test.go:167:13:167:20 | password | $@ flows to a logging call. | test.go:153:17:153:24 | SSA def(password) | Sensitive data returned by an access to password |
| test.go:168:17:168:24 | password | test.go:153:17:153:24 | SSA def(password) | test.go:168:17:168:24 | password | $@ flows to a logging call. | test.go:153:17:153:24 | SSA def(password) | Sensitive data returned by an access to password |
| test.go:169:13:169:20 | password | test.go:153:17:153:24 | SSA def(password) | test.go:169:13:169:20 | password | $@ flows to a logging call. | test.go:153:17:153:24 | SSA def(password) | Sensitive data returned by an access to password |
| test.go:170:12:170:19 | password | test.go:153:17:153:24 | SSA def(password) | test.go:170:12:170:19 | password | $@ flows to a logging call. | test.go:153:17:153:24 | SSA def(password) | Sensitive data returned by an access to password |
| test.go:171:21:171:28 | password | test.go:153:17:153:24 | SSA def(password) | test.go:171:21:171:28 | password | $@ flows to a logging call. | test.go:153:17:153:24 | SSA def(password) | Sensitive data returned by an access to password |
| test.go:172:14:172:21 | password | test.go:153:17:153:24 | SSA def(password) | test.go:172:14:172:21 | password | $@ flows to a logging call. | test.go:153:17:153:24 | SSA def(password) | Sensitive data returned by an access to password |
| test.go:173:13:173:20 | password | test.go:153:17:153:24 | SSA def(password) | test.go:173:13:173:20 | password | $@ flows to a logging call. | test.go:153:17:153:24 | SSA def(password) | Sensitive data returned by an access to password |
| test.go:174:12:174:19 | password | test.go:153:17:153:24 | SSA def(password) | test.go:174:12:174:19 | password | $@ flows to a logging call. | test.go:153:17:153:24 | SSA def(password) | Sensitive data returned by an access to password |
| test.go:175:15:175:22 | password | test.go:153:17:153:24 | SSA def(password) | test.go:175:15:175:22 | password | $@ flows to a logging call. | test.go:153:17:153:24 | SSA def(password) | Sensitive data returned by an access to password |
| test.go:176:15:176:22 | password | test.go:153:17:153:24 | SSA def(password) | test.go:176:15:176:22 | password | $@ flows to a logging call. | test.go:153:17:153:24 | SSA def(password) | Sensitive data returned by an access to password |
| test.go:177:18:177:25 | password | test.go:153:17:153:24 | SSA def(password) | test.go:177:18:177:25 | password | $@ flows to a logging call. | test.go:153:17:153:24 | SSA def(password) | Sensitive data returned by an access to password |
| test.go:178:15:178:22 | password | test.go:153:17:153:24 | SSA def(password) | test.go:178:15:178:22 | password | $@ flows to a logging call. | test.go:153:17:153:24 | SSA def(password) | Sensitive data returned by an access to password |
| test.go:179:19:179:26 | password | test.go:153:17:153:24 | SSA def(password) | test.go:179:19:179:26 | password | $@ flows to a logging call. | test.go:153:17:153:24 | SSA def(password) | Sensitive data returned by an access to password |
| test.go:180:15:180:22 | password | test.go:153:17:153:24 | SSA def(password) | test.go:180:15:180:22 | password | $@ flows to a logging call. | test.go:153:17:153:24 | SSA def(password) | Sensitive data returned by an access to password |
| test.go:181:14:181:21 | password | test.go:153:17:153:24 | SSA def(password) | test.go:181:14:181:21 | password | $@ flows to a logging call. | test.go:153:17:153:24 | SSA def(password) | Sensitive data returned by an access to password |
| test.go:182:23:182:30 | password | test.go:153:17:153:24 | SSA def(password) | test.go:182:23:182:30 | password | $@ flows to a logging call. | test.go:153:17:153:24 | SSA def(password) | Sensitive data returned by an access to password |
| test.go:183:16:183:23 | password | test.go:153:17:153:24 | SSA def(password) | test.go:183:16:183:23 | password | $@ flows to a logging call. | test.go:153:17:153:24 | SSA def(password) | Sensitive data returned by an access to password |
| test.go:184:15:184:22 | password | test.go:153:17:153:24 | SSA def(password) | test.go:184:15:184:22 | password | $@ flows to a logging call. | test.go:153:17:153:24 | SSA def(password) | Sensitive data returned by an access to password |
| test.go:185:14:185:21 | password | test.go:153:17:153:24 | SSA def(password) | test.go:185:14:185:21 | password | $@ flows to a logging call. | test.go:153:17:153:24 | SSA def(password) | Sensitive data returned by an access to password |
| test.go:186:17:186:24 | password | test.go:153:17:153:24 | SSA def(password) | test.go:186:17:186:24 | password | $@ flows to a logging call. | test.go:153:17:153:24 | SSA def(password) | Sensitive data returned by an access to password |
| test.go:187:16:187:23 | password | test.go:153:17:153:24 | SSA def(password) | test.go:187:16:187:23 | password | $@ flows to a logging call. | test.go:153:17:153:24 | SSA def(password) | Sensitive data returned by an access to password |
edges
| test.go:153:17:153:24 | definition of password | test.go:154:14:154:21 | password | provenance | |
| test.go:153:17:153:24 | definition of password | test.go:155:17:155:24 | password | provenance | |
| test.go:153:17:153:24 | definition of password | test.go:156:14:156:21 | password | provenance | |
| test.go:153:17:153:24 | definition of password | test.go:157:18:157:25 | password | provenance | |
| test.go:153:17:153:24 | definition of password | test.go:158:14:158:21 | password | provenance | |
| test.go:153:17:153:24 | definition of password | test.go:159:13:159:20 | password | provenance | |
| test.go:153:17:153:24 | definition of password | test.go:160:22:160:29 | password | provenance | |
| test.go:153:17:153:24 | definition of password | test.go:161:15:161:22 | password | provenance | |
| test.go:153:17:153:24 | definition of password | test.go:162:14:162:21 | password | provenance | |
| test.go:153:17:153:24 | definition of password | test.go:163:13:163:20 | password | provenance | |
| test.go:153:17:153:24 | definition of password | test.go:164:16:164:23 | password | provenance | |
| test.go:153:17:153:24 | definition of password | test.go:165:13:165:20 | password | provenance | Sink:MaD:1 |
| test.go:153:17:153:24 | definition of password | test.go:166:16:166:23 | password | provenance | Sink:MaD:2 |
| test.go:153:17:153:24 | definition of password | test.go:167:13:167:20 | password | provenance | Sink:MaD:3 |
| test.go:153:17:153:24 | definition of password | test.go:168:17:168:24 | password | provenance | Sink:MaD:4 |
| test.go:153:17:153:24 | definition of password | test.go:169:13:169:20 | password | provenance | Sink:MaD:5 |
| test.go:153:17:153:24 | definition of password | test.go:170:12:170:19 | password | provenance | Sink:MaD:6 |
| test.go:153:17:153:24 | definition of password | test.go:171:21:171:28 | password | provenance | Sink:MaD:7 |
| test.go:153:17:153:24 | definition of password | test.go:172:14:172:21 | password | provenance | Sink:MaD:8 |
| test.go:153:17:153:24 | definition of password | test.go:173:13:173:20 | password | provenance | Sink:MaD:9 |
| test.go:153:17:153:24 | definition of password | test.go:174:12:174:19 | password | provenance | Sink:MaD:10 |
| test.go:153:17:153:24 | definition of password | test.go:175:15:175:22 | password | provenance | Sink:MaD:11 |
| test.go:153:17:153:24 | definition of password | test.go:176:15:176:22 | password | provenance | Sink:MaD:12 |
| test.go:153:17:153:24 | definition of password | test.go:177:18:177:25 | password | provenance | Sink:MaD:13 |
| test.go:153:17:153:24 | definition of password | test.go:178:15:178:22 | password | provenance | Sink:MaD:14 |
| test.go:153:17:153:24 | definition of password | test.go:179:19:179:26 | password | provenance | Sink:MaD:15 |
| test.go:153:17:153:24 | definition of password | test.go:180:15:180:22 | password | provenance | Sink:MaD:16 |
| test.go:153:17:153:24 | definition of password | test.go:181:14:181:21 | password | provenance | Sink:MaD:17 |
| test.go:153:17:153:24 | definition of password | test.go:182:23:182:30 | password | provenance | Sink:MaD:18 |
| test.go:153:17:153:24 | definition of password | test.go:183:16:183:23 | password | provenance | Sink:MaD:19 |
| test.go:153:17:153:24 | definition of password | test.go:184:15:184:22 | password | provenance | Sink:MaD:20 |
| test.go:153:17:153:24 | definition of password | test.go:185:14:185:21 | password | provenance | Sink:MaD:21 |
| test.go:153:17:153:24 | definition of password | test.go:186:17:186:24 | password | provenance | Sink:MaD:22 |
| test.go:153:17:153:24 | definition of password | test.go:187:16:187:23 | password | provenance | |
| test.go:153:17:153:24 | SSA def(password) | test.go:154:14:154:21 | password | provenance | |
| test.go:153:17:153:24 | SSA def(password) | test.go:155:17:155:24 | password | provenance | |
| test.go:153:17:153:24 | SSA def(password) | test.go:156:14:156:21 | password | provenance | |
| test.go:153:17:153:24 | SSA def(password) | test.go:157:18:157:25 | password | provenance | |
| test.go:153:17:153:24 | SSA def(password) | test.go:158:14:158:21 | password | provenance | |
| test.go:153:17:153:24 | SSA def(password) | test.go:159:13:159:20 | password | provenance | |
| test.go:153:17:153:24 | SSA def(password) | test.go:160:22:160:29 | password | provenance | |
| test.go:153:17:153:24 | SSA def(password) | test.go:161:15:161:22 | password | provenance | |
| test.go:153:17:153:24 | SSA def(password) | test.go:162:14:162:21 | password | provenance | |
| test.go:153:17:153:24 | SSA def(password) | test.go:163:13:163:20 | password | provenance | |
| test.go:153:17:153:24 | SSA def(password) | test.go:164:16:164:23 | password | provenance | |
| test.go:153:17:153:24 | SSA def(password) | test.go:165:13:165:20 | password | provenance | Sink:MaD:1 |
| test.go:153:17:153:24 | SSA def(password) | test.go:166:16:166:23 | password | provenance | Sink:MaD:2 |
| test.go:153:17:153:24 | SSA def(password) | test.go:167:13:167:20 | password | provenance | Sink:MaD:3 |
| test.go:153:17:153:24 | SSA def(password) | test.go:168:17:168:24 | password | provenance | Sink:MaD:4 |
| test.go:153:17:153:24 | SSA def(password) | test.go:169:13:169:20 | password | provenance | Sink:MaD:5 |
| test.go:153:17:153:24 | SSA def(password) | test.go:170:12:170:19 | password | provenance | Sink:MaD:6 |
| test.go:153:17:153:24 | SSA def(password) | test.go:171:21:171:28 | password | provenance | Sink:MaD:7 |
| test.go:153:17:153:24 | SSA def(password) | test.go:172:14:172:21 | password | provenance | Sink:MaD:8 |
| test.go:153:17:153:24 | SSA def(password) | test.go:173:13:173:20 | password | provenance | Sink:MaD:9 |
| test.go:153:17:153:24 | SSA def(password) | test.go:174:12:174:19 | password | provenance | Sink:MaD:10 |
| test.go:153:17:153:24 | SSA def(password) | test.go:175:15:175:22 | password | provenance | Sink:MaD:11 |
| test.go:153:17:153:24 | SSA def(password) | test.go:176:15:176:22 | password | provenance | Sink:MaD:12 |
| test.go:153:17:153:24 | SSA def(password) | test.go:177:18:177:25 | password | provenance | Sink:MaD:13 |
| test.go:153:17:153:24 | SSA def(password) | test.go:178:15:178:22 | password | provenance | Sink:MaD:14 |
| test.go:153:17:153:24 | SSA def(password) | test.go:179:19:179:26 | password | provenance | Sink:MaD:15 |
| test.go:153:17:153:24 | SSA def(password) | test.go:180:15:180:22 | password | provenance | Sink:MaD:16 |
| test.go:153:17:153:24 | SSA def(password) | test.go:181:14:181:21 | password | provenance | Sink:MaD:17 |
| test.go:153:17:153:24 | SSA def(password) | test.go:182:23:182:30 | password | provenance | Sink:MaD:18 |
| test.go:153:17:153:24 | SSA def(password) | test.go:183:16:183:23 | password | provenance | Sink:MaD:19 |
| test.go:153:17:153:24 | SSA def(password) | test.go:184:15:184:22 | password | provenance | Sink:MaD:20 |
| test.go:153:17:153:24 | SSA def(password) | test.go:185:14:185:21 | password | provenance | Sink:MaD:21 |
| test.go:153:17:153:24 | SSA def(password) | test.go:186:17:186:24 | password | provenance | Sink:MaD:22 |
| test.go:153:17:153:24 | SSA def(password) | test.go:187:16:187:23 | password | provenance | |
models
| 1 | Sink: group:beego-logs; ; false; Alert; ; ; Argument[0..1]; log-injection; manual |
| 2 | Sink: group:beego-logs; ; false; Critical; ; ; Argument[0..1]; log-injection; manual |
@@ -92,7 +92,7 @@ models
| 21 | Sink: group:beego-logs; BeeLogger; true; Warn; ; ; Argument[0..1]; log-injection; manual |
| 22 | Sink: group:beego-logs; BeeLogger; true; Warning; ; ; Argument[0..1]; log-injection; manual |
nodes
| test.go:153:17:153:24 | definition of password | semmle.label | definition of password |
| test.go:153:17:153:24 | SSA def(password) | semmle.label | SSA def(password) |
| test.go:154:14:154:21 | password | semmle.label | password |
| test.go:155:17:155:24 | password | semmle.label | password |
| test.go:156:14:156:21 | password | semmle.label | password |

View File

@@ -12,12 +12,12 @@ type MyService interface {
}
func makeEndpointLit(svc MyService) endpoint.Endpoint {
return func(_ context.Context, request interface{}) (interface{}, error) { // $ source="definition of request"
return func(_ context.Context, request interface{}) (interface{}, error) { // $ source="SSA def(request)"
return request, nil
}
}
func endpointfn(_ context.Context, request interface{}) (interface{}, error) { // $ source="definition of request"
func endpointfn(_ context.Context, request interface{}) (interface{}, error) { // $ source="SSA def(request)"
return request, nil
}

View File

@@ -1,8 +1,8 @@
#select
| main.go:21:28:21:31 | name | main.go:18:46:18:48 | definition of req | main.go:21:28:21:31 | name | This log entry depends on a $@. | main.go:18:46:18:48 | definition of req | user-provided value |
| main.go:21:28:21:31 | name | main.go:18:46:18:48 | SSA def(req) | main.go:21:28:21:31 | name | This log entry depends on a $@. | main.go:18:46:18:48 | SSA def(req) | user-provided value |
edges
| main.go:18:46:18:48 | definition of req | main.go:21:28:21:31 | name | provenance | |
| main.go:18:46:18:48 | SSA def(req) | main.go:21:28:21:31 | name | provenance | |
nodes
| main.go:18:46:18:48 | definition of req | semmle.label | definition of req |
| main.go:18:46:18:48 | SSA def(req) | semmle.label | SSA def(req) |
| main.go:21:28:21:31 | name | semmle.label | name |
subpaths

View File

@@ -15,7 +15,7 @@ import (
type Greeter struct{}
func (g *Greeter) Hello(ctx context.Context, req *pb.Request, rsp *pb.Response) error { // $ serverRequest="definition of req" Source
func (g *Greeter) Hello(ctx context.Context, req *pb.Request, rsp *pb.Response) error { // $ serverRequest="SSA def(req)" Source
// var access
name := req.Name
fmt.Println("Name :: %s", name) // $ Alert

View File

@@ -1,19 +1,19 @@
#select
| server/main.go:30:38:30:48 | selection of Text | rpc/notes/service.twirp.go:538:25:538:32 | selection of Body | server/main.go:30:38:30:48 | selection of Text | The $@ of this request depends on a $@. | server/main.go:30:38:30:48 | selection of Text | URL | rpc/notes/service.twirp.go:538:25:538:32 | selection of Body | user-provided value |
| server/main.go:30:38:30:48 | selection of Text | server/main.go:19:56:19:61 | definition of params | server/main.go:30:38:30:48 | selection of Text | The $@ of this request depends on a $@. | server/main.go:30:38:30:48 | selection of Text | URL | server/main.go:19:56:19:61 | definition of params | user-provided value |
| server/main.go:30:38:30:48 | selection of Text | server/main.go:19:56:19:61 | SSA def(params) | server/main.go:30:38:30:48 | selection of Text | The $@ of this request depends on a $@. | server/main.go:30:38:30:48 | selection of Text | URL | server/main.go:19:56:19:61 | SSA def(params) | user-provided value |
edges
| client/main.go:16:35:16:78 | &... | server/main.go:19:56:19:61 | definition of params | provenance | |
| client/main.go:16:35:16:78 | &... | server/main.go:19:56:19:61 | SSA def(params) | provenance | |
| client/main.go:16:35:16:78 | &... [postupdate] | client/main.go:16:35:16:78 | &... | provenance | |
| rpc/notes/service.twirp.go:538:2:538:33 | ... := ...[0] | rpc/notes/service.twirp.go:544:27:544:29 | buf | provenance | |
| rpc/notes/service.twirp.go:538:25:538:32 | selection of Body | rpc/notes/service.twirp.go:538:2:538:33 | ... := ...[0] | provenance | Src:MaD:1 MaD:3 |
| rpc/notes/service.twirp.go:544:27:544:29 | buf | rpc/notes/service.twirp.go:544:32:544:41 | reqContent [postupdate] | provenance | MaD:2 |
| rpc/notes/service.twirp.go:544:32:544:41 | reqContent [postupdate] | rpc/notes/service.twirp.go:574:2:577:2 | capture variable reqContent | provenance | |
| rpc/notes/service.twirp.go:574:2:577:2 | capture variable reqContent | rpc/notes/service.twirp.go:576:35:576:44 | reqContent | provenance | |
| rpc/notes/service.twirp.go:576:35:576:44 | reqContent | server/main.go:19:56:19:61 | definition of params | provenance | |
| server/main.go:19:56:19:61 | definition of params | server/main.go:19:56:19:61 | definition of params [Return] | provenance | |
| server/main.go:19:56:19:61 | definition of params | server/main.go:30:38:30:48 | selection of Text | provenance | |
| server/main.go:19:56:19:61 | definition of params | server/main.go:30:38:30:48 | selection of Text | provenance | |
| server/main.go:19:56:19:61 | definition of params [Return] | client/main.go:16:35:16:78 | &... [postupdate] | provenance | |
| rpc/notes/service.twirp.go:544:32:544:41 | reqContent [postupdate] | rpc/notes/service.twirp.go:574:2:577:2 | SSA def(reqContent) | provenance | |
| rpc/notes/service.twirp.go:574:2:577:2 | SSA def(reqContent) | rpc/notes/service.twirp.go:576:35:576:44 | reqContent | provenance | |
| rpc/notes/service.twirp.go:576:35:576:44 | reqContent | server/main.go:19:56:19:61 | SSA def(params) | provenance | |
| server/main.go:19:56:19:61 | SSA def(params) | server/main.go:19:56:19:61 | SSA def(params) [Return] | provenance | |
| server/main.go:19:56:19:61 | SSA def(params) | server/main.go:30:38:30:48 | selection of Text | provenance | |
| server/main.go:19:56:19:61 | SSA def(params) | server/main.go:30:38:30:48 | selection of Text | provenance | |
| server/main.go:19:56:19:61 | SSA def(params) [Return] | client/main.go:16:35:16:78 | &... [postupdate] | provenance | |
models
| 1 | Source: net/http; Request; true; Body; ; ; ; remote; manual |
| 2 | Summary: google.golang.org/protobuf/proto; ; false; Unmarshal; ; ; Argument[0]; Argument[1]; taint; manual |
@@ -25,10 +25,10 @@ nodes
| rpc/notes/service.twirp.go:538:25:538:32 | selection of Body | semmle.label | selection of Body |
| rpc/notes/service.twirp.go:544:27:544:29 | buf | semmle.label | buf |
| rpc/notes/service.twirp.go:544:32:544:41 | reqContent [postupdate] | semmle.label | reqContent [postupdate] |
| rpc/notes/service.twirp.go:574:2:577:2 | capture variable reqContent | semmle.label | capture variable reqContent |
| rpc/notes/service.twirp.go:574:2:577:2 | SSA def(reqContent) | semmle.label | SSA def(reqContent) |
| rpc/notes/service.twirp.go:576:35:576:44 | reqContent | semmle.label | reqContent |
| server/main.go:19:56:19:61 | definition of params | semmle.label | definition of params |
| server/main.go:19:56:19:61 | definition of params | semmle.label | definition of params |
| server/main.go:19:56:19:61 | definition of params [Return] | semmle.label | definition of params [Return] |
| server/main.go:19:56:19:61 | SSA def(params) | semmle.label | SSA def(params) |
| server/main.go:19:56:19:61 | SSA def(params) | semmle.label | SSA def(params) |
| server/main.go:19:56:19:61 | SSA def(params) [Return] | semmle.label | SSA def(params) [Return] |
| server/main.go:30:38:30:48 | selection of Text | semmle.label | selection of Text |
subpaths

View File

@@ -24,7 +24,7 @@ func main() {
d.Decode(out) // $ ttfnmodelstep="d -> out [postupdate]"
var w io.Writer
e := yaml2.NewEncoder(w) // $ ttfnmodelstep="definition of e -> w [postupdate]"
e := yaml2.NewEncoder(w) // $ ttfnmodelstep="SSA def(e) -> w [postupdate]"
e.Encode(in) // $ ttfnmodelstep="in -> e [postupdate]"
out, _ = yaml3.Marshal(in) // $ marshaler="yaml: in -> ... = ...[0]" ttfnmodelstep="in -> ... = ...[0]"
@@ -33,7 +33,7 @@ func main() {
d1 := yaml3.NewDecoder(r) // $ ttfnmodelstep="r -> call to NewDecoder"
d1.Decode(out) // $ ttfnmodelstep="d1 -> out [postupdate]"
e1 := yaml3.NewEncoder(w) // $ ttfnmodelstep="definition of e1 -> w [postupdate]"
e1 := yaml3.NewEncoder(w) // $ ttfnmodelstep="SSA def(e1) -> w [postupdate]"
e1.Encode(in) // $ ttfnmodelstep="in -> e1 [postupdate]"
var n1 yaml3.Node

View File

@@ -11,7 +11,7 @@ import (
)
// CreateTodo is the resolver for the createTodo field.
func (r *mutationResolver) CreateTodo(ctx context.Context, input model.NewTodo) (*model.Todo, error) { // $ resolverParameter="definition of input"
func (r *mutationResolver) CreateTodo(ctx context.Context, input model.NewTodo) (*model.Todo, error) { // $ resolverParameter="SSA def(input)"
panic(fmt.Errorf("not implemented: CreateTodo - createTodo %v", input))
}

View File

@@ -1,2 +1,2 @@
| tests.go:61:30:61:35 | result | $@ may be nil at this dereference because $@ may not have been checked. | tests.go:59:2:59:7 | definition of result | result | tests.go:59:10:59:12 | definition of err | err |
| tests.go:243:27:243:32 | result | $@ may be nil at this dereference because $@ may not have been checked. | tests.go:241:2:241:7 | definition of result | result | tests.go:241:10:241:12 | definition of err | err |
| tests.go:61:30:61:35 | result | $@ may be nil at this dereference because $@ may not have been checked. | tests.go:59:2:59:7 | SSA def(result) | result | tests.go:59:10:59:12 | SSA def(err) | err |
| tests.go:243:27:243:32 | result | $@ may be nil at this dereference because $@ may not have been checked. | tests.go:241:2:241:7 | SSA def(result) | result | tests.go:241:10:241:12 | SSA def(err) | err |

View File

@@ -9,17 +9,17 @@
| tests.go:145:3:145:3 | f | tests.go:141:5:141:78 | ... := ...[0] | tests.go:145:3:145:3 | f | File handle may be writable as a result of data flow from a $@ and closing it may result in data loss upon failure, which is not handled explicitly. | tests.go:141:15:141:78 | call to OpenFile | call to OpenFile |
| tests.go:166:8:166:8 | f | tests.go:162:2:162:74 | ... := ...[0] | tests.go:166:8:166:8 | f | File handle may be writable as a result of data flow from a $@ and closing it may result in data loss upon failure, which is not handled explicitly. | tests.go:162:12:162:74 | call to OpenFile | call to OpenFile |
edges
| tests.go:9:24:9:24 | definition of f | tests.go:10:8:10:8 | f | provenance | |
| tests.go:13:32:13:32 | definition of f | tests.go:14:13:16:2 | capture variable f | provenance | |
| tests.go:14:13:16:2 | capture variable f | tests.go:15:3:15:3 | f | provenance | |
| tests.go:9:24:9:24 | SSA def(f) | tests.go:10:8:10:8 | f | provenance | |
| tests.go:13:32:13:32 | SSA def(f) | tests.go:14:13:16:2 | SSA def(f) | provenance | |
| tests.go:14:13:16:2 | SSA def(f) | tests.go:15:3:15:3 | f | provenance | |
| tests.go:32:5:32:78 | ... := ...[0] | tests.go:33:21:33:21 | f | provenance | Src:MaD:1 |
| tests.go:32:5:32:78 | ... := ...[0] | tests.go:34:29:34:29 | f | provenance | Src:MaD:1 |
| tests.go:33:21:33:21 | f | tests.go:9:24:9:24 | definition of f | provenance | |
| tests.go:34:29:34:29 | f | tests.go:13:32:13:32 | definition of f | provenance | |
| tests.go:33:21:33:21 | f | tests.go:9:24:9:24 | SSA def(f) | provenance | |
| tests.go:34:29:34:29 | f | tests.go:13:32:13:32 | SSA def(f) | provenance | |
| tests.go:46:5:46:76 | ... := ...[0] | tests.go:47:21:47:21 | f | provenance | Src:MaD:1 |
| tests.go:46:5:46:76 | ... := ...[0] | tests.go:48:29:48:29 | f | provenance | Src:MaD:1 |
| tests.go:47:21:47:21 | f | tests.go:9:24:9:24 | definition of f | provenance | |
| tests.go:48:29:48:29 | f | tests.go:13:32:13:32 | definition of f | provenance | |
| tests.go:47:21:47:21 | f | tests.go:9:24:9:24 | SSA def(f) | provenance | |
| tests.go:48:29:48:29 | f | tests.go:13:32:13:32 | SSA def(f) | provenance | |
| tests.go:55:5:55:78 | ... := ...[0] | tests.go:57:3:57:3 | f | provenance | Src:MaD:1 |
| tests.go:67:5:67:76 | ... := ...[0] | tests.go:69:3:69:3 | f | provenance | Src:MaD:1 |
| tests.go:124:5:124:78 | ... := ...[0] | tests.go:126:9:126:9 | f | provenance | Src:MaD:1 |
@@ -28,10 +28,10 @@ edges
models
| 1 | Source: os; ; false; OpenFile; ; ; ReturnValue[0]; file; manual |
nodes
| tests.go:9:24:9:24 | definition of f | semmle.label | definition of f |
| tests.go:9:24:9:24 | SSA def(f) | semmle.label | SSA def(f) |
| tests.go:10:8:10:8 | f | semmle.label | f |
| tests.go:13:32:13:32 | definition of f | semmle.label | definition of f |
| tests.go:14:13:16:2 | capture variable f | semmle.label | capture variable f |
| tests.go:13:32:13:32 | SSA def(f) | semmle.label | SSA def(f) |
| tests.go:14:13:16:2 | SSA def(f) | semmle.label | SSA def(f) |
| tests.go:15:3:15:3 | f | semmle.label | f |
| tests.go:32:5:32:78 | ... := ...[0] | semmle.label | ... := ...[0] |
| tests.go:33:21:33:21 | f | semmle.label | f |

View File

@@ -5,18 +5,18 @@
| UnsafeUnzipSymlink.go:126:17:126:31 | selection of Linkname | UnsafeUnzipSymlink.go:126:17:126:31 | selection of Linkname | UnsafeUnzipSymlink.go:112:13:112:20 | linkName | Unresolved path from an archive header, which may point outside the archive root, is used in $@. | UnsafeUnzipSymlink.go:112:13:112:20 | linkName | symlink creation |
| UnsafeUnzipSymlink.go:126:34:126:44 | selection of Name | UnsafeUnzipSymlink.go:126:34:126:44 | selection of Name | UnsafeUnzipSymlink.go:112:23:112:30 | fileName | Unresolved path from an archive header, which may point outside the archive root, is used in $@. | UnsafeUnzipSymlink.go:112:23:112:30 | fileName | symlink creation |
edges
| UnsafeUnzipSymlink.go:111:19:111:26 | definition of linkName | UnsafeUnzipSymlink.go:112:13:112:20 | linkName | provenance | Sink:MaD:1 |
| UnsafeUnzipSymlink.go:111:29:111:36 | definition of fileName | UnsafeUnzipSymlink.go:112:23:112:30 | fileName | provenance | Sink:MaD:1 |
| UnsafeUnzipSymlink.go:126:17:126:31 | selection of Linkname | UnsafeUnzipSymlink.go:111:19:111:26 | definition of linkName | provenance | |
| UnsafeUnzipSymlink.go:126:34:126:44 | selection of Name | UnsafeUnzipSymlink.go:111:29:111:36 | definition of fileName | provenance | |
| UnsafeUnzipSymlink.go:111:19:111:26 | SSA def(linkName) | UnsafeUnzipSymlink.go:112:13:112:20 | linkName | provenance | Sink:MaD:1 |
| UnsafeUnzipSymlink.go:111:29:111:36 | SSA def(fileName) | UnsafeUnzipSymlink.go:112:23:112:30 | fileName | provenance | Sink:MaD:1 |
| UnsafeUnzipSymlink.go:126:17:126:31 | selection of Linkname | UnsafeUnzipSymlink.go:111:19:111:26 | SSA def(linkName) | provenance | |
| UnsafeUnzipSymlink.go:126:34:126:44 | selection of Name | UnsafeUnzipSymlink.go:111:29:111:36 | SSA def(fileName) | provenance | |
models
| 1 | Sink: os; ; false; Symlink; ; ; Argument[0..1]; path-injection; manual |
nodes
| UnsafeUnzipSymlink.go:31:15:31:29 | selection of Linkname | semmle.label | selection of Linkname |
| UnsafeUnzipSymlink.go:31:32:31:42 | selection of Name | semmle.label | selection of Name |
| UnsafeUnzipSymlink.go:43:25:43:35 | selection of Name | semmle.label | selection of Name |
| UnsafeUnzipSymlink.go:111:19:111:26 | definition of linkName | semmle.label | definition of linkName |
| UnsafeUnzipSymlink.go:111:29:111:36 | definition of fileName | semmle.label | definition of fileName |
| UnsafeUnzipSymlink.go:111:19:111:26 | SSA def(linkName) | semmle.label | SSA def(linkName) |
| UnsafeUnzipSymlink.go:111:29:111:36 | SSA def(fileName) | semmle.label | SSA def(fileName) |
| UnsafeUnzipSymlink.go:112:13:112:20 | linkName | semmle.label | linkName |
| UnsafeUnzipSymlink.go:112:23:112:30 | fileName | semmle.label | fileName |
| UnsafeUnzipSymlink.go:126:17:126:31 | selection of Linkname | semmle.label | selection of Linkname |

View File

@@ -4,12 +4,12 @@
| tarslip.go:15:2:15:30 | ... := ...[0] | tarslip.go:15:2:15:30 | ... := ...[0] | tarslip.go:16:14:16:34 | call to Dir | Unsanitized archive entry, which may contain '..', is used in a $@. | tarslip.go:16:14:16:34 | call to Dir | file system operation |
| tst.go:23:2:43:2 | range statement[1] | tst.go:23:2:43:2 | range statement[1] | tst.go:29:20:29:23 | path | Unsanitized archive entry, which may contain '..', is used in a $@. | tst.go:29:20:29:23 | path | file system operation |
edges
| UnsafeUnzipSymlinkGood.go:52:24:52:32 | definition of candidate | UnsafeUnzipSymlinkGood.go:61:53:61:61 | candidate | provenance | |
| UnsafeUnzipSymlinkGood.go:52:24:52:32 | SSA def(candidate) | UnsafeUnzipSymlinkGood.go:61:53:61:61 | candidate | provenance | |
| UnsafeUnzipSymlinkGood.go:61:53:61:61 | candidate | UnsafeUnzipSymlinkGood.go:61:31:61:62 | call to Join | provenance | FunctionModel Sink:MaD:3 |
| UnsafeUnzipSymlinkGood.go:72:3:72:25 | ... := ...[0] | UnsafeUnzipSymlinkGood.go:76:24:76:38 | selection of Linkname | provenance | |
| UnsafeUnzipSymlinkGood.go:72:3:72:25 | ... := ...[0] | UnsafeUnzipSymlinkGood.go:76:70:76:80 | selection of Name | provenance | |
| UnsafeUnzipSymlinkGood.go:76:24:76:38 | selection of Linkname | UnsafeUnzipSymlinkGood.go:52:24:52:32 | definition of candidate | provenance | |
| UnsafeUnzipSymlinkGood.go:76:70:76:80 | selection of Name | UnsafeUnzipSymlinkGood.go:52:24:52:32 | definition of candidate | provenance | |
| UnsafeUnzipSymlinkGood.go:76:24:76:38 | selection of Linkname | UnsafeUnzipSymlinkGood.go:52:24:52:32 | SSA def(candidate) | provenance | |
| UnsafeUnzipSymlinkGood.go:76:70:76:80 | selection of Name | UnsafeUnzipSymlinkGood.go:52:24:52:32 | SSA def(candidate) | provenance | |
| ZipSlip.go:11:2:15:2 | range statement[1] | ZipSlip.go:12:24:12:29 | selection of Name | provenance | |
| ZipSlip.go:12:3:12:30 | ... := ...[0] | ZipSlip.go:14:20:14:20 | p | provenance | Sink:MaD:1 |
| ZipSlip.go:12:24:12:29 | selection of Name | ZipSlip.go:12:3:12:30 | ... := ...[0] | provenance | MaD:4 |
@@ -23,7 +23,7 @@ models
| 4 | Summary: path/filepath; ; false; Abs; ; ; Argument[0]; ReturnValue[0]; taint; manual |
| 5 | Summary: path; ; false; Dir; ; ; Argument[0]; ReturnValue; taint; manual |
nodes
| UnsafeUnzipSymlinkGood.go:52:24:52:32 | definition of candidate | semmle.label | definition of candidate |
| UnsafeUnzipSymlinkGood.go:52:24:52:32 | SSA def(candidate) | semmle.label | SSA def(candidate) |
| UnsafeUnzipSymlinkGood.go:61:31:61:62 | call to Join | semmle.label | call to Join |
| UnsafeUnzipSymlinkGood.go:61:53:61:61 | candidate | semmle.label | candidate |
| UnsafeUnzipSymlinkGood.go:72:3:72:25 | ... := ...[0] | semmle.label | ... := ...[0] |

View File

@@ -48,14 +48,14 @@ edges
| GitSubcommands.go:11:13:11:27 | call to Query | GitSubcommands.go:17:36:17:42 | tainted | provenance | |
| GitSubcommands.go:33:13:33:19 | selection of URL | GitSubcommands.go:33:13:33:27 | call to Query | provenance | Src:MaD:2 MaD:7 |
| GitSubcommands.go:33:13:33:27 | call to Query | GitSubcommands.go:38:32:38:38 | tainted | provenance | |
| SanitizingDoubleDash.go:9:2:9:8 | definition of tainted | SanitizingDoubleDash.go:13:25:13:31 | tainted | provenance | |
| SanitizingDoubleDash.go:9:2:9:8 | definition of tainted | SanitizingDoubleDash.go:14:23:14:33 | slice expression | provenance | |
| SanitizingDoubleDash.go:9:2:9:8 | definition of tainted | SanitizingDoubleDash.go:39:31:39:37 | tainted | provenance | Config |
| SanitizingDoubleDash.go:9:2:9:8 | definition of tainted | SanitizingDoubleDash.go:52:24:52:30 | tainted | provenance | Config |
| SanitizingDoubleDash.go:9:2:9:8 | definition of tainted | SanitizingDoubleDash.go:68:31:68:37 | tainted | provenance | Config |
| SanitizingDoubleDash.go:9:2:9:8 | definition of tainted | SanitizingDoubleDash.go:80:23:80:29 | tainted | provenance | Config |
| SanitizingDoubleDash.go:9:2:9:8 | SSA def(tainted) | SanitizingDoubleDash.go:13:25:13:31 | tainted | provenance | |
| SanitizingDoubleDash.go:9:2:9:8 | SSA def(tainted) | SanitizingDoubleDash.go:14:23:14:33 | slice expression | provenance | |
| SanitizingDoubleDash.go:9:2:9:8 | SSA def(tainted) | SanitizingDoubleDash.go:39:31:39:37 | tainted | provenance | Config |
| SanitizingDoubleDash.go:9:2:9:8 | SSA def(tainted) | SanitizingDoubleDash.go:52:24:52:30 | tainted | provenance | Config |
| SanitizingDoubleDash.go:9:2:9:8 | SSA def(tainted) | SanitizingDoubleDash.go:68:31:68:37 | tainted | provenance | Config |
| SanitizingDoubleDash.go:9:2:9:8 | SSA def(tainted) | SanitizingDoubleDash.go:80:23:80:29 | tainted | provenance | Config |
| SanitizingDoubleDash.go:9:13:9:19 | selection of URL | SanitizingDoubleDash.go:9:13:9:27 | call to Query | provenance | Src:MaD:2 MaD:7 |
| SanitizingDoubleDash.go:9:13:9:27 | call to Query | SanitizingDoubleDash.go:9:2:9:8 | definition of tainted | provenance | |
| SanitizingDoubleDash.go:9:13:9:27 | call to Query | SanitizingDoubleDash.go:9:2:9:8 | SSA def(tainted) | provenance | |
| SanitizingDoubleDash.go:13:15:13:32 | array literal [array] | SanitizingDoubleDash.go:14:23:14:30 | arrayLit [array] | provenance | |
| SanitizingDoubleDash.go:13:25:13:31 | tainted | SanitizingDoubleDash.go:13:15:13:32 | array literal [array] | provenance | |
| SanitizingDoubleDash.go:14:23:14:30 | arrayLit [array] | SanitizingDoubleDash.go:14:23:14:33 | slice element node | provenance | |
@@ -181,7 +181,7 @@ nodes
| GitSubcommands.go:33:13:33:19 | selection of URL | semmle.label | selection of URL |
| GitSubcommands.go:33:13:33:27 | call to Query | semmle.label | call to Query |
| GitSubcommands.go:38:32:38:38 | tainted | semmle.label | tainted |
| SanitizingDoubleDash.go:9:2:9:8 | definition of tainted | semmle.label | definition of tainted |
| SanitizingDoubleDash.go:9:2:9:8 | SSA def(tainted) | semmle.label | SSA def(tainted) |
| SanitizingDoubleDash.go:9:13:9:19 | selection of URL | semmle.label | selection of URL |
| SanitizingDoubleDash.go:9:13:9:27 | call to Query | semmle.label | call to Query |
| SanitizingDoubleDash.go:13:15:13:32 | array literal [array] | semmle.label | array literal [array] |

View File

@@ -1,11 +1,11 @@
#select
| stored.go:30:22:30:25 | name | stored.go:18:3:18:28 | ... := ...[0] | stored.go:30:22:30:25 | name | Stored cross-site scripting vulnerability due to $@. | stored.go:18:3:18:28 | ... := ...[0] | stored value |
| stored.go:61:22:61:25 | path | stored.go:59:30:59:33 | definition of path | stored.go:61:22:61:25 | path | Stored cross-site scripting vulnerability due to $@. | stored.go:59:30:59:33 | definition of path | stored value |
| stored.go:61:22:61:25 | path | stored.go:59:30:59:33 | SSA def(path) | stored.go:61:22:61:25 | path | Stored cross-site scripting vulnerability due to $@. | stored.go:59:30:59:33 | SSA def(path) | stored value |
edges
| stored.go:18:3:18:28 | ... := ...[0] | stored.go:25:14:25:17 | rows | provenance | Src:MaD:1 |
| stored.go:25:14:25:17 | rows | stored.go:25:29:25:33 | &... [postupdate] | provenance | FunctionModel |
| stored.go:25:29:25:33 | &... [postupdate] | stored.go:30:22:30:25 | name | provenance | |
| stored.go:59:30:59:33 | definition of path | stored.go:61:22:61:25 | path | provenance | |
| stored.go:59:30:59:33 | SSA def(path) | stored.go:61:22:61:25 | path | provenance | |
models
| 1 | Source: database/sql; DB; true; Query; ; ; ReturnValue[0]; database; manual |
nodes
@@ -13,7 +13,7 @@ nodes
| stored.go:25:14:25:17 | rows | semmle.label | rows |
| stored.go:25:29:25:33 | &... [postupdate] | semmle.label | &... [postupdate] |
| stored.go:30:22:30:25 | name | semmle.label | name |
| stored.go:59:30:59:33 | definition of path | semmle.label | definition of path |
| stored.go:59:30:59:33 | SSA def(path) | semmle.label | SSA def(path) |
| stored.go:61:22:61:25 | path | semmle.label | path |
subpaths
testFailures

View File

@@ -1,80 +1,80 @@
#select
| klog.go:23:15:23:20 | header | klog.go:21:30:21:37 | selection of Header | klog.go:23:15:23:20 | header | $@ flows to a logging call. | klog.go:21:30:21:37 | selection of Header | Sensitive data returned by HTTP request headers |
| klog.go:29:13:29:41 | call to Get | klog.go:29:13:29:20 | selection of Header | klog.go:29:13:29:41 | call to Get | $@ flows to a logging call. | klog.go:29:13:29:20 | selection of Header | Sensitive data returned by HTTP request headers |
| main.go:19:12:19:19 | password | main.go:17:2:17:9 | definition of password | main.go:19:12:19:19 | password | $@ flows to a logging call. | main.go:17:2:17:9 | definition of password | Sensitive data returned by an access to password |
| main.go:20:19:20:26 | password | main.go:17:2:17:9 | definition of password | main.go:20:19:20:26 | password | $@ flows to a logging call. | main.go:17:2:17:9 | definition of password | Sensitive data returned by an access to password |
| main.go:21:13:21:20 | password | main.go:17:2:17:9 | definition of password | main.go:21:13:21:20 | password | $@ flows to a logging call. | main.go:17:2:17:9 | definition of password | Sensitive data returned by an access to password |
| main.go:22:14:22:21 | password | main.go:17:2:17:9 | definition of password | main.go:22:14:22:21 | password | $@ flows to a logging call. | main.go:17:2:17:9 | definition of password | Sensitive data returned by an access to password |
| main.go:24:13:24:20 | password | main.go:17:2:17:9 | definition of password | main.go:24:13:24:20 | password | $@ flows to a logging call. | main.go:17:2:17:9 | definition of password | Sensitive data returned by an access to password |
| main.go:27:20:27:27 | password | main.go:17:2:17:9 | definition of password | main.go:27:20:27:27 | password | $@ flows to a logging call. | main.go:17:2:17:9 | definition of password | Sensitive data returned by an access to password |
| main.go:30:14:30:21 | password | main.go:17:2:17:9 | definition of password | main.go:30:14:30:21 | password | $@ flows to a logging call. | main.go:17:2:17:9 | definition of password | Sensitive data returned by an access to password |
| main.go:33:15:33:22 | password | main.go:17:2:17:9 | definition of password | main.go:33:15:33:22 | password | $@ flows to a logging call. | main.go:17:2:17:9 | definition of password | Sensitive data returned by an access to password |
| main.go:36:13:36:20 | password | main.go:17:2:17:9 | definition of password | main.go:36:13:36:20 | password | $@ flows to a logging call. | main.go:17:2:17:9 | definition of password | Sensitive data returned by an access to password |
| main.go:39:20:39:27 | password | main.go:17:2:17:9 | definition of password | main.go:39:20:39:27 | password | $@ flows to a logging call. | main.go:17:2:17:9 | definition of password | Sensitive data returned by an access to password |
| main.go:42:14:42:21 | password | main.go:17:2:17:9 | definition of password | main.go:42:14:42:21 | password | $@ flows to a logging call. | main.go:17:2:17:9 | definition of password | Sensitive data returned by an access to password |
| main.go:45:15:45:22 | password | main.go:17:2:17:9 | definition of password | main.go:45:15:45:22 | password | $@ flows to a logging call. | main.go:17:2:17:9 | definition of password | Sensitive data returned by an access to password |
| main.go:47:16:47:23 | password | main.go:17:2:17:9 | definition of password | main.go:47:16:47:23 | password | $@ flows to a logging call. | main.go:17:2:17:9 | definition of password | Sensitive data returned by an access to password |
| main.go:51:10:51:17 | password | main.go:17:2:17:9 | definition of password | main.go:51:10:51:17 | password | $@ flows to a logging call. | main.go:17:2:17:9 | definition of password | Sensitive data returned by an access to password |
| main.go:52:17:52:24 | password | main.go:17:2:17:9 | definition of password | main.go:52:17:52:24 | password | $@ flows to a logging call. | main.go:17:2:17:9 | definition of password | Sensitive data returned by an access to password |
| main.go:53:11:53:18 | password | main.go:17:2:17:9 | definition of password | main.go:53:11:53:18 | password | $@ flows to a logging call. | main.go:17:2:17:9 | definition of password | Sensitive data returned by an access to password |
| main.go:54:12:54:19 | password | main.go:17:2:17:9 | definition of password | main.go:54:12:54:19 | password | $@ flows to a logging call. | main.go:17:2:17:9 | definition of password | Sensitive data returned by an access to password |
| main.go:56:11:56:18 | password | main.go:17:2:17:9 | definition of password | main.go:56:11:56:18 | password | $@ flows to a logging call. | main.go:17:2:17:9 | definition of password | Sensitive data returned by an access to password |
| main.go:59:18:59:25 | password | main.go:17:2:17:9 | definition of password | main.go:59:18:59:25 | password | $@ flows to a logging call. | main.go:17:2:17:9 | definition of password | Sensitive data returned by an access to password |
| main.go:62:12:62:19 | password | main.go:17:2:17:9 | definition of password | main.go:62:12:62:19 | password | $@ flows to a logging call. | main.go:17:2:17:9 | definition of password | Sensitive data returned by an access to password |
| main.go:65:13:65:20 | password | main.go:17:2:17:9 | definition of password | main.go:65:13:65:20 | password | $@ flows to a logging call. | main.go:17:2:17:9 | definition of password | Sensitive data returned by an access to password |
| main.go:68:11:68:18 | password | main.go:17:2:17:9 | definition of password | main.go:68:11:68:18 | password | $@ flows to a logging call. | main.go:17:2:17:9 | definition of password | Sensitive data returned by an access to password |
| main.go:71:18:71:25 | password | main.go:17:2:17:9 | definition of password | main.go:71:18:71:25 | password | $@ flows to a logging call. | main.go:17:2:17:9 | definition of password | Sensitive data returned by an access to password |
| main.go:74:12:74:19 | password | main.go:17:2:17:9 | definition of password | main.go:74:12:74:19 | password | $@ flows to a logging call. | main.go:17:2:17:9 | definition of password | Sensitive data returned by an access to password |
| main.go:77:13:77:20 | password | main.go:17:2:17:9 | definition of password | main.go:77:13:77:20 | password | $@ flows to a logging call. | main.go:17:2:17:9 | definition of password | Sensitive data returned by an access to password |
| main.go:79:14:79:21 | password | main.go:17:2:17:9 | definition of password | main.go:79:14:79:21 | password | $@ flows to a logging call. | main.go:17:2:17:9 | definition of password | Sensitive data returned by an access to password |
| main.go:82:12:82:19 | password | main.go:17:2:17:9 | definition of password | main.go:82:12:82:19 | password | $@ flows to a logging call. | main.go:17:2:17:9 | definition of password | Sensitive data returned by an access to password |
| main.go:83:17:83:24 | password | main.go:17:2:17:9 | definition of password | main.go:83:17:83:24 | password | $@ flows to a logging call. | main.go:17:2:17:9 | definition of password | Sensitive data returned by an access to password |
| main.go:87:29:87:34 | fields | main.go:17:2:17:9 | definition of password | main.go:87:29:87:34 | fields | $@ flows to a logging call. | main.go:17:2:17:9 | definition of password | Sensitive data returned by an access to password |
| main.go:90:35:90:42 | password | main.go:17:2:17:9 | definition of password | main.go:90:35:90:42 | password | $@ flows to a logging call. | main.go:17:2:17:9 | definition of password | Sensitive data returned by an access to password |
| overrides.go:13:14:13:23 | call to String | overrides.go:8:2:8:9 | definition of password | overrides.go:13:14:13:23 | call to String | $@ flows to a logging call. | overrides.go:8:2:8:9 | definition of password | Sensitive data returned by an access to password |
| passwords.go:9:14:9:14 | x | passwords.go:21:2:21:9 | definition of password | passwords.go:9:14:9:14 | x | $@ flows to a logging call. | passwords.go:21:2:21:9 | definition of password | Sensitive data returned by an access to password |
| passwords.go:25:14:25:21 | password | passwords.go:21:2:21:9 | definition of password | passwords.go:25:14:25:21 | password | $@ flows to a logging call. | passwords.go:21:2:21:9 | definition of password | Sensitive data returned by an access to password |
| main.go:19:12:19:19 | password | main.go:17:2:17:9 | SSA def(password) | main.go:19:12:19:19 | password | $@ flows to a logging call. | main.go:17:2:17:9 | SSA def(password) | Sensitive data returned by an access to password |
| main.go:20:19:20:26 | password | main.go:17:2:17:9 | SSA def(password) | main.go:20:19:20:26 | password | $@ flows to a logging call. | main.go:17:2:17:9 | SSA def(password) | Sensitive data returned by an access to password |
| main.go:21:13:21:20 | password | main.go:17:2:17:9 | SSA def(password) | main.go:21:13:21:20 | password | $@ flows to a logging call. | main.go:17:2:17:9 | SSA def(password) | Sensitive data returned by an access to password |
| main.go:22:14:22:21 | password | main.go:17:2:17:9 | SSA def(password) | main.go:22:14:22:21 | password | $@ flows to a logging call. | main.go:17:2:17:9 | SSA def(password) | Sensitive data returned by an access to password |
| main.go:24:13:24:20 | password | main.go:17:2:17:9 | SSA def(password) | main.go:24:13:24:20 | password | $@ flows to a logging call. | main.go:17:2:17:9 | SSA def(password) | Sensitive data returned by an access to password |
| main.go:27:20:27:27 | password | main.go:17:2:17:9 | SSA def(password) | main.go:27:20:27:27 | password | $@ flows to a logging call. | main.go:17:2:17:9 | SSA def(password) | Sensitive data returned by an access to password |
| main.go:30:14:30:21 | password | main.go:17:2:17:9 | SSA def(password) | main.go:30:14:30:21 | password | $@ flows to a logging call. | main.go:17:2:17:9 | SSA def(password) | Sensitive data returned by an access to password |
| main.go:33:15:33:22 | password | main.go:17:2:17:9 | SSA def(password) | main.go:33:15:33:22 | password | $@ flows to a logging call. | main.go:17:2:17:9 | SSA def(password) | Sensitive data returned by an access to password |
| main.go:36:13:36:20 | password | main.go:17:2:17:9 | SSA def(password) | main.go:36:13:36:20 | password | $@ flows to a logging call. | main.go:17:2:17:9 | SSA def(password) | Sensitive data returned by an access to password |
| main.go:39:20:39:27 | password | main.go:17:2:17:9 | SSA def(password) | main.go:39:20:39:27 | password | $@ flows to a logging call. | main.go:17:2:17:9 | SSA def(password) | Sensitive data returned by an access to password |
| main.go:42:14:42:21 | password | main.go:17:2:17:9 | SSA def(password) | main.go:42:14:42:21 | password | $@ flows to a logging call. | main.go:17:2:17:9 | SSA def(password) | Sensitive data returned by an access to password |
| main.go:45:15:45:22 | password | main.go:17:2:17:9 | SSA def(password) | main.go:45:15:45:22 | password | $@ flows to a logging call. | main.go:17:2:17:9 | SSA def(password) | Sensitive data returned by an access to password |
| main.go:47:16:47:23 | password | main.go:17:2:17:9 | SSA def(password) | main.go:47:16:47:23 | password | $@ flows to a logging call. | main.go:17:2:17:9 | SSA def(password) | Sensitive data returned by an access to password |
| main.go:51:10:51:17 | password | main.go:17:2:17:9 | SSA def(password) | main.go:51:10:51:17 | password | $@ flows to a logging call. | main.go:17:2:17:9 | SSA def(password) | Sensitive data returned by an access to password |
| main.go:52:17:52:24 | password | main.go:17:2:17:9 | SSA def(password) | main.go:52:17:52:24 | password | $@ flows to a logging call. | main.go:17:2:17:9 | SSA def(password) | Sensitive data returned by an access to password |
| main.go:53:11:53:18 | password | main.go:17:2:17:9 | SSA def(password) | main.go:53:11:53:18 | password | $@ flows to a logging call. | main.go:17:2:17:9 | SSA def(password) | Sensitive data returned by an access to password |
| main.go:54:12:54:19 | password | main.go:17:2:17:9 | SSA def(password) | main.go:54:12:54:19 | password | $@ flows to a logging call. | main.go:17:2:17:9 | SSA def(password) | Sensitive data returned by an access to password |
| main.go:56:11:56:18 | password | main.go:17:2:17:9 | SSA def(password) | main.go:56:11:56:18 | password | $@ flows to a logging call. | main.go:17:2:17:9 | SSA def(password) | Sensitive data returned by an access to password |
| main.go:59:18:59:25 | password | main.go:17:2:17:9 | SSA def(password) | main.go:59:18:59:25 | password | $@ flows to a logging call. | main.go:17:2:17:9 | SSA def(password) | Sensitive data returned by an access to password |
| main.go:62:12:62:19 | password | main.go:17:2:17:9 | SSA def(password) | main.go:62:12:62:19 | password | $@ flows to a logging call. | main.go:17:2:17:9 | SSA def(password) | Sensitive data returned by an access to password |
| main.go:65:13:65:20 | password | main.go:17:2:17:9 | SSA def(password) | main.go:65:13:65:20 | password | $@ flows to a logging call. | main.go:17:2:17:9 | SSA def(password) | Sensitive data returned by an access to password |
| main.go:68:11:68:18 | password | main.go:17:2:17:9 | SSA def(password) | main.go:68:11:68:18 | password | $@ flows to a logging call. | main.go:17:2:17:9 | SSA def(password) | Sensitive data returned by an access to password |
| main.go:71:18:71:25 | password | main.go:17:2:17:9 | SSA def(password) | main.go:71:18:71:25 | password | $@ flows to a logging call. | main.go:17:2:17:9 | SSA def(password) | Sensitive data returned by an access to password |
| main.go:74:12:74:19 | password | main.go:17:2:17:9 | SSA def(password) | main.go:74:12:74:19 | password | $@ flows to a logging call. | main.go:17:2:17:9 | SSA def(password) | Sensitive data returned by an access to password |
| main.go:77:13:77:20 | password | main.go:17:2:17:9 | SSA def(password) | main.go:77:13:77:20 | password | $@ flows to a logging call. | main.go:17:2:17:9 | SSA def(password) | Sensitive data returned by an access to password |
| main.go:79:14:79:21 | password | main.go:17:2:17:9 | SSA def(password) | main.go:79:14:79:21 | password | $@ flows to a logging call. | main.go:17:2:17:9 | SSA def(password) | Sensitive data returned by an access to password |
| main.go:82:12:82:19 | password | main.go:17:2:17:9 | SSA def(password) | main.go:82:12:82:19 | password | $@ flows to a logging call. | main.go:17:2:17:9 | SSA def(password) | Sensitive data returned by an access to password |
| main.go:83:17:83:24 | password | main.go:17:2:17:9 | SSA def(password) | main.go:83:17:83:24 | password | $@ flows to a logging call. | main.go:17:2:17:9 | SSA def(password) | Sensitive data returned by an access to password |
| main.go:87:29:87:34 | fields | main.go:17:2:17:9 | SSA def(password) | main.go:87:29:87:34 | fields | $@ flows to a logging call. | main.go:17:2:17:9 | SSA def(password) | Sensitive data returned by an access to password |
| main.go:90:35:90:42 | password | main.go:17:2:17:9 | SSA def(password) | main.go:90:35:90:42 | password | $@ flows to a logging call. | main.go:17:2:17:9 | SSA def(password) | Sensitive data returned by an access to password |
| overrides.go:13:14:13:23 | call to String | overrides.go:8:2:8:9 | SSA def(password) | overrides.go:13:14:13:23 | call to String | $@ flows to a logging call. | overrides.go:8:2:8:9 | SSA def(password) | Sensitive data returned by an access to password |
| passwords.go:9:14:9:14 | x | passwords.go:21:2:21:9 | SSA def(password) | passwords.go:9:14:9:14 | x | $@ flows to a logging call. | passwords.go:21:2:21:9 | SSA def(password) | Sensitive data returned by an access to password |
| passwords.go:25:14:25:21 | password | passwords.go:21:2:21:9 | SSA def(password) | passwords.go:25:14:25:21 | password | $@ flows to a logging call. | passwords.go:21:2:21:9 | SSA def(password) | Sensitive data returned by an access to password |
| passwords.go:26:14:26:23 | selection of password | passwords.go:26:14:26:23 | selection of password | passwords.go:26:14:26:23 | selection of password | $@ flows to a logging call. | passwords.go:26:14:26:23 | selection of password | Sensitive data returned by an access to password |
| passwords.go:27:14:27:26 | call to getPassword | passwords.go:27:14:27:26 | call to getPassword | passwords.go:27:14:27:26 | call to getPassword | $@ flows to a logging call. | passwords.go:27:14:27:26 | call to getPassword | Sensitive data returned by a call to getPassword |
| passwords.go:28:14:28:28 | call to getPassword | passwords.go:28:14:28:28 | call to getPassword | passwords.go:28:14:28:28 | call to getPassword | $@ flows to a logging call. | passwords.go:28:14:28:28 | call to getPassword | Sensitive data returned by a call to getPassword |
| passwords.go:33:13:33:20 | password | passwords.go:21:2:21:9 | definition of password | passwords.go:33:13:33:20 | password | $@ flows to a logging call. | passwords.go:21:2:21:9 | definition of password | Sensitive data returned by an access to password |
| passwords.go:36:14:36:35 | ...+... | passwords.go:21:2:21:9 | definition of password | passwords.go:36:14:36:35 | ...+... | $@ flows to a logging call. | passwords.go:21:2:21:9 | definition of password | Sensitive data returned by an access to password |
| passwords.go:33:13:33:20 | password | passwords.go:21:2:21:9 | SSA def(password) | passwords.go:33:13:33:20 | password | $@ flows to a logging call. | passwords.go:21:2:21:9 | SSA def(password) | Sensitive data returned by an access to password |
| passwords.go:36:14:36:35 | ...+... | passwords.go:21:2:21:9 | SSA def(password) | passwords.go:36:14:36:35 | ...+... | $@ flows to a logging call. | passwords.go:21:2:21:9 | SSA def(password) | Sensitive data returned by an access to password |
| passwords.go:41:14:41:17 | obj1 | passwords.go:39:13:39:13 | x | passwords.go:41:14:41:17 | obj1 | $@ flows to a logging call. | passwords.go:39:13:39:13 | x | Sensitive data returned by an access to password |
| passwords.go:46:14:46:17 | obj2 | passwords.go:21:2:21:9 | definition of password | passwords.go:46:14:46:17 | obj2 | $@ flows to a logging call. | passwords.go:21:2:21:9 | definition of password | Sensitive data returned by an access to password |
| passwords.go:53:14:53:27 | fixed_password | passwords.go:52:2:52:15 | definition of fixed_password | passwords.go:53:14:53:27 | fixed_password | $@ flows to a logging call. | passwords.go:52:2:52:15 | definition of fixed_password | Sensitive data returned by an access to fixed_password |
| passwords.go:46:14:46:17 | obj2 | passwords.go:21:2:21:9 | SSA def(password) | passwords.go:46:14:46:17 | obj2 | $@ flows to a logging call. | passwords.go:21:2:21:9 | SSA def(password) | Sensitive data returned by an access to password |
| passwords.go:53:14:53:27 | fixed_password | passwords.go:52:2:52:15 | SSA def(fixed_password) | passwords.go:53:14:53:27 | fixed_password | $@ flows to a logging call. | passwords.go:52:2:52:15 | SSA def(fixed_password) | Sensitive data returned by an access to fixed_password |
| passwords.go:91:14:91:26 | utilityObject | passwords.go:89:16:89:36 | call to make | passwords.go:91:14:91:26 | utilityObject | $@ flows to a logging call. | passwords.go:89:16:89:36 | call to make | Sensitive data returned by an access to passwordSet |
| passwords.go:94:23:94:28 | secret | passwords.go:21:2:21:9 | definition of password | passwords.go:94:23:94:28 | secret | $@ flows to a logging call. | passwords.go:21:2:21:9 | definition of password | Sensitive data returned by an access to password |
| passwords.go:104:15:104:40 | ...+... | passwords.go:21:2:21:9 | definition of password | passwords.go:104:15:104:40 | ...+... | $@ flows to a logging call. | passwords.go:21:2:21:9 | definition of password | Sensitive data returned by an access to password |
| passwords.go:110:16:110:41 | ...+... | passwords.go:21:2:21:9 | definition of password | passwords.go:110:16:110:41 | ...+... | $@ flows to a logging call. | passwords.go:21:2:21:9 | definition of password | Sensitive data returned by an access to password |
| passwords.go:115:15:115:40 | ...+... | passwords.go:21:2:21:9 | definition of password | passwords.go:115:15:115:40 | ...+... | $@ flows to a logging call. | passwords.go:21:2:21:9 | definition of password | Sensitive data returned by an access to password |
| passwords.go:119:14:119:45 | ...+... | passwords.go:118:6:118:14 | definition of password1 | passwords.go:119:14:119:45 | ...+... | $@ flows to a logging call. | passwords.go:118:6:118:14 | definition of password1 | Sensitive data returned by an access to password1 |
| passwords.go:129:14:129:19 | config | passwords.go:21:2:21:9 | definition of password | passwords.go:129:14:129:19 | config | $@ flows to a logging call. | passwords.go:21:2:21:9 | definition of password | Sensitive data returned by an access to password |
| passwords.go:94:23:94:28 | secret | passwords.go:21:2:21:9 | SSA def(password) | passwords.go:94:23:94:28 | secret | $@ flows to a logging call. | passwords.go:21:2:21:9 | SSA def(password) | Sensitive data returned by an access to password |
| passwords.go:104:15:104:40 | ...+... | passwords.go:21:2:21:9 | SSA def(password) | passwords.go:104:15:104:40 | ...+... | $@ flows to a logging call. | passwords.go:21:2:21:9 | SSA def(password) | Sensitive data returned by an access to password |
| passwords.go:110:16:110:41 | ...+... | passwords.go:21:2:21:9 | SSA def(password) | passwords.go:110:16:110:41 | ...+... | $@ flows to a logging call. | passwords.go:21:2:21:9 | SSA def(password) | Sensitive data returned by an access to password |
| passwords.go:115:15:115:40 | ...+... | passwords.go:21:2:21:9 | SSA def(password) | passwords.go:115:15:115:40 | ...+... | $@ flows to a logging call. | passwords.go:21:2:21:9 | SSA def(password) | Sensitive data returned by an access to password |
| passwords.go:119:14:119:45 | ...+... | passwords.go:118:6:118:14 | SSA def(password1) | passwords.go:119:14:119:45 | ...+... | $@ flows to a logging call. | passwords.go:118:6:118:14 | SSA def(password1) | Sensitive data returned by an access to password1 |
| passwords.go:129:14:129:19 | config | passwords.go:21:2:21:9 | SSA def(password) | passwords.go:129:14:129:19 | config | $@ flows to a logging call. | passwords.go:21:2:21:9 | SSA def(password) | Sensitive data returned by an access to password |
| passwords.go:129:14:129:19 | config | passwords.go:123:13:123:14 | x3 | passwords.go:129:14:129:19 | config | $@ flows to a logging call. | passwords.go:123:13:123:14 | x3 | Sensitive data returned by an access to password |
| passwords.go:129:14:129:19 | config | passwords.go:126:13:126:25 | call to getPassword | passwords.go:129:14:129:19 | config | $@ flows to a logging call. | passwords.go:126:13:126:25 | call to getPassword | Sensitive data returned by a call to getPassword |
| passwords.go:130:14:130:21 | selection of x | passwords.go:21:2:21:9 | definition of password | passwords.go:130:14:130:21 | selection of x | $@ flows to a logging call. | passwords.go:21:2:21:9 | definition of password | Sensitive data returned by an access to password |
| passwords.go:130:14:130:21 | selection of x | passwords.go:21:2:21:9 | SSA def(password) | passwords.go:130:14:130:21 | selection of x | $@ flows to a logging call. | passwords.go:21:2:21:9 | SSA def(password) | Sensitive data returned by an access to password |
| passwords.go:131:14:131:21 | selection of y | passwords.go:126:13:126:25 | call to getPassword | passwords.go:131:14:131:21 | selection of y | $@ flows to a logging call. | passwords.go:126:13:126:25 | call to getPassword | Sensitive data returned by a call to getPassword |
| protobuf.go:14:14:14:35 | call to GetDescription | protobuf.go:9:2:9:9 | definition of password | protobuf.go:14:14:14:35 | call to GetDescription | $@ flows to a logging call. | protobuf.go:9:2:9:9 | definition of password | Sensitive data returned by an access to password |
| protobuf.go:14:14:14:35 | call to GetDescription | protobuf.go:9:2:9:9 | SSA def(password) | protobuf.go:14:14:14:35 | call to GetDescription | $@ flows to a logging call. | protobuf.go:9:2:9:9 | SSA def(password) | Sensitive data returned by an access to password |
edges
| klog.go:21:3:26:3 | range statement[1] | klog.go:22:27:22:33 | headers | provenance | |
| klog.go:21:30:21:37 | selection of Header | klog.go:21:3:26:3 | range statement[1] | provenance | Src:MaD:11 Config |
| klog.go:22:4:25:4 | range statement[1] | klog.go:23:15:23:20 | header | provenance | |
| klog.go:22:27:22:33 | headers | klog.go:22:4:25:4 | range statement[1] | provenance | Config |
| klog.go:29:13:29:20 | selection of Header | klog.go:29:13:29:41 | call to Get | provenance | Src:MaD:11 Config |
| main.go:17:2:17:9 | definition of password | main.go:19:12:19:19 | password | provenance | |
| main.go:17:2:17:9 | definition of password | main.go:20:19:20:26 | password | provenance | |
| main.go:17:2:17:9 | definition of password | main.go:21:13:21:20 | password | provenance | Sink:MaD:6 |
| main.go:17:2:17:9 | definition of password | main.go:22:14:22:21 | password | provenance | |
| main.go:17:2:17:9 | definition of password | main.go:24:13:24:20 | password | provenance | |
| main.go:17:2:17:9 | definition of password | main.go:27:20:27:27 | password | provenance | |
| main.go:17:2:17:9 | definition of password | main.go:30:14:30:21 | password | provenance | Sink:MaD:3 |
| main.go:17:2:17:9 | definition of password | main.go:33:15:33:22 | password | provenance | |
| main.go:17:2:17:9 | definition of password | main.go:36:13:36:20 | password | provenance | |
| main.go:17:2:17:9 | definition of password | main.go:39:20:39:27 | password | provenance | |
| main.go:17:2:17:9 | definition of password | main.go:42:14:42:21 | password | provenance | Sink:MaD:5 |
| main.go:17:2:17:9 | definition of password | main.go:45:15:45:22 | password | provenance | |
| main.go:17:2:17:9 | definition of password | main.go:47:16:47:23 | password | provenance | Sink:MaD:4 |
| main.go:17:2:17:9 | definition of password | main.go:51:10:51:17 | password | provenance | |
| main.go:17:2:17:9 | definition of password | main.go:51:10:51:17 | password | provenance | |
| main.go:17:2:17:9 | SSA def(password) | main.go:19:12:19:19 | password | provenance | |
| main.go:17:2:17:9 | SSA def(password) | main.go:20:19:20:26 | password | provenance | |
| main.go:17:2:17:9 | SSA def(password) | main.go:21:13:21:20 | password | provenance | Sink:MaD:6 |
| main.go:17:2:17:9 | SSA def(password) | main.go:22:14:22:21 | password | provenance | |
| main.go:17:2:17:9 | SSA def(password) | main.go:24:13:24:20 | password | provenance | |
| main.go:17:2:17:9 | SSA def(password) | main.go:27:20:27:27 | password | provenance | |
| main.go:17:2:17:9 | SSA def(password) | main.go:30:14:30:21 | password | provenance | Sink:MaD:3 |
| main.go:17:2:17:9 | SSA def(password) | main.go:33:15:33:22 | password | provenance | |
| main.go:17:2:17:9 | SSA def(password) | main.go:36:13:36:20 | password | provenance | |
| main.go:17:2:17:9 | SSA def(password) | main.go:39:20:39:27 | password | provenance | |
| main.go:17:2:17:9 | SSA def(password) | main.go:42:14:42:21 | password | provenance | Sink:MaD:5 |
| main.go:17:2:17:9 | SSA def(password) | main.go:45:15:45:22 | password | provenance | |
| main.go:17:2:17:9 | SSA def(password) | main.go:47:16:47:23 | password | provenance | Sink:MaD:4 |
| main.go:17:2:17:9 | SSA def(password) | main.go:51:10:51:17 | password | provenance | |
| main.go:17:2:17:9 | SSA def(password) | main.go:51:10:51:17 | password | provenance | |
| main.go:51:10:51:17 | password | main.go:52:17:52:24 | password | provenance | |
| main.go:51:10:51:17 | password | main.go:52:17:52:24 | password | provenance | |
| main.go:52:17:52:24 | password | main.go:53:11:53:18 | password | provenance | |
@@ -97,14 +97,14 @@ edges
| main.go:86:2:86:7 | fields [postupdate] | main.go:87:29:87:34 | fields | provenance | Sink:MaD:2 |
| main.go:86:19:86:26 | password | main.go:86:2:86:7 | fields [postupdate] | provenance | Config |
| main.go:86:19:86:26 | password | main.go:90:35:90:42 | password | provenance | Sink:MaD:1 |
| overrides.go:8:2:8:9 | definition of password | overrides.go:9:9:9:16 | password | provenance | |
| overrides.go:8:2:8:9 | SSA def(password) | overrides.go:9:9:9:16 | password | provenance | |
| overrides.go:9:9:9:16 | password | overrides.go:13:14:13:23 | call to String | provenance | |
| passwords.go:8:12:8:12 | definition of x | passwords.go:9:14:9:14 | x | provenance | |
| passwords.go:21:2:21:9 | definition of password | passwords.go:25:14:25:21 | password | provenance | |
| passwords.go:21:2:21:9 | definition of password | passwords.go:30:8:30:15 | password | provenance | |
| passwords.go:21:2:21:9 | definition of password | passwords.go:33:13:33:20 | password | provenance | |
| passwords.go:21:2:21:9 | definition of password | passwords.go:36:28:36:35 | password | provenance | |
| passwords.go:30:8:30:15 | password | passwords.go:8:12:8:12 | definition of x | provenance | |
| passwords.go:8:12:8:12 | SSA def(x) | passwords.go:9:14:9:14 | x | provenance | |
| passwords.go:21:2:21:9 | SSA def(password) | passwords.go:25:14:25:21 | password | provenance | |
| passwords.go:21:2:21:9 | SSA def(password) | passwords.go:30:8:30:15 | password | provenance | |
| passwords.go:21:2:21:9 | SSA def(password) | passwords.go:33:13:33:20 | password | provenance | |
| passwords.go:21:2:21:9 | SSA def(password) | passwords.go:36:28:36:35 | password | provenance | |
| passwords.go:30:8:30:15 | password | passwords.go:8:12:8:12 | SSA def(x) | provenance | |
| passwords.go:36:28:36:35 | password | passwords.go:36:14:36:35 | ...+... | provenance | Config |
| passwords.go:36:28:36:35 | password | passwords.go:44:6:44:13 | password | provenance | |
| passwords.go:38:10:40:2 | struct literal | passwords.go:41:14:41:17 | obj1 | provenance | |
@@ -117,7 +117,7 @@ edges
| passwords.go:50:11:50:18 | password | passwords.go:110:34:110:41 | password | provenance | |
| passwords.go:50:11:50:18 | password | passwords.go:115:33:115:40 | password | provenance | |
| passwords.go:50:11:50:18 | password | passwords.go:125:13:125:20 | password | provenance | |
| passwords.go:52:2:52:15 | definition of fixed_password | passwords.go:53:14:53:27 | fixed_password | provenance | |
| passwords.go:52:2:52:15 | SSA def(fixed_password) | passwords.go:53:14:53:27 | fixed_password | provenance | |
| passwords.go:88:19:90:2 | struct literal | passwords.go:91:14:91:26 | utilityObject | provenance | |
| passwords.go:89:16:89:36 | call to make | passwords.go:88:19:90:2 | struct literal | provenance | Config |
| passwords.go:104:33:104:40 | password | passwords.go:104:15:104:40 | ...+... | provenance | Config |
@@ -129,7 +129,7 @@ edges
| passwords.go:110:34:110:41 | password | passwords.go:125:13:125:20 | password | provenance | |
| passwords.go:115:33:115:40 | password | passwords.go:115:15:115:40 | ...+... | provenance | Config |
| passwords.go:115:33:115:40 | password | passwords.go:125:13:125:20 | password | provenance | |
| passwords.go:118:6:118:14 | definition of password1 | passwords.go:119:28:119:36 | password1 | provenance | |
| passwords.go:118:6:118:14 | SSA def(password1) | passwords.go:119:28:119:36 | password1 | provenance | |
| passwords.go:119:28:119:36 | password1 | passwords.go:119:28:119:45 | call to String | provenance | Config |
| passwords.go:119:28:119:45 | call to String | passwords.go:119:14:119:45 | ...+... | provenance | Config |
| passwords.go:122:12:127:2 | struct literal | passwords.go:129:14:129:19 | config | provenance | |
@@ -142,13 +142,13 @@ edges
| passwords.go:126:13:126:25 | call to getPassword | passwords.go:122:12:127:2 | struct literal [y] | provenance | |
| passwords.go:130:14:130:19 | config [x] | passwords.go:130:14:130:21 | selection of x | provenance | |
| passwords.go:131:14:131:19 | config [y] | passwords.go:131:14:131:21 | selection of y | provenance | |
| protobuf.go:9:2:9:9 | definition of password | protobuf.go:12:22:12:29 | password | provenance | |
| protobuf.go:9:2:9:9 | SSA def(password) | protobuf.go:12:22:12:29 | password | provenance | |
| protobuf.go:12:2:12:6 | implicit dereference [postupdate] [Description] | protobuf.go:12:2:12:6 | query [postupdate] [pointer, Description] | provenance | |
| protobuf.go:12:2:12:6 | query [postupdate] [pointer, Description] | protobuf.go:14:14:14:18 | query [pointer, Description] | provenance | |
| protobuf.go:12:22:12:29 | password | protobuf.go:12:2:12:6 | implicit dereference [postupdate] [Description] | provenance | |
| protobuf.go:14:14:14:18 | query [pointer, Description] | protobuf.go:14:14:14:35 | call to GetDescription | provenance | |
| protobuf.go:14:14:14:18 | query [pointer, Description] | protos/query/query.pb.go:117:7:117:7 | definition of x [pointer, Description] | provenance | |
| protos/query/query.pb.go:117:7:117:7 | definition of x [pointer, Description] | protos/query/query.pb.go:119:10:119:10 | x [pointer, Description] | provenance | |
| protobuf.go:14:14:14:18 | query [pointer, Description] | protos/query/query.pb.go:117:7:117:7 | SSA def(x) [pointer, Description] | provenance | |
| protos/query/query.pb.go:117:7:117:7 | SSA def(x) [pointer, Description] | protos/query/query.pb.go:119:10:119:10 | x [pointer, Description] | provenance | |
| protos/query/query.pb.go:119:10:119:10 | implicit dereference [Description] | protos/query/query.pb.go:119:10:119:22 | selection of Description | provenance | |
| protos/query/query.pb.go:119:10:119:10 | x [pointer, Description] | protos/query/query.pb.go:119:10:119:10 | implicit dereference [Description] | provenance | |
models
@@ -171,7 +171,7 @@ nodes
| klog.go:23:15:23:20 | header | semmle.label | header |
| klog.go:29:13:29:20 | selection of Header | semmle.label | selection of Header |
| klog.go:29:13:29:41 | call to Get | semmle.label | call to Get |
| main.go:17:2:17:9 | definition of password | semmle.label | definition of password |
| main.go:17:2:17:9 | SSA def(password) | semmle.label | SSA def(password) |
| main.go:19:12:19:19 | password | semmle.label | password |
| main.go:20:19:20:26 | password | semmle.label | password |
| main.go:21:13:21:20 | password | semmle.label | password |
@@ -209,12 +209,12 @@ nodes
| main.go:86:19:86:26 | password | semmle.label | password |
| main.go:87:29:87:34 | fields | semmle.label | fields |
| main.go:90:35:90:42 | password | semmle.label | password |
| overrides.go:8:2:8:9 | definition of password | semmle.label | definition of password |
| overrides.go:8:2:8:9 | SSA def(password) | semmle.label | SSA def(password) |
| overrides.go:9:9:9:16 | password | semmle.label | password |
| overrides.go:13:14:13:23 | call to String | semmle.label | call to String |
| passwords.go:8:12:8:12 | definition of x | semmle.label | definition of x |
| passwords.go:8:12:8:12 | SSA def(x) | semmle.label | SSA def(x) |
| passwords.go:9:14:9:14 | x | semmle.label | x |
| passwords.go:21:2:21:9 | definition of password | semmle.label | definition of password |
| passwords.go:21:2:21:9 | SSA def(password) | semmle.label | SSA def(password) |
| passwords.go:25:14:25:21 | password | semmle.label | password |
| passwords.go:26:14:26:23 | selection of password | semmle.label | selection of password |
| passwords.go:27:14:27:26 | call to getPassword | semmle.label | call to getPassword |
@@ -230,7 +230,7 @@ nodes
| passwords.go:44:6:44:13 | password | semmle.label | password |
| passwords.go:46:14:46:17 | obj2 | semmle.label | obj2 |
| passwords.go:50:11:50:18 | password | semmle.label | password |
| passwords.go:52:2:52:15 | definition of fixed_password | semmle.label | definition of fixed_password |
| passwords.go:52:2:52:15 | SSA def(fixed_password) | semmle.label | SSA def(fixed_password) |
| passwords.go:53:14:53:27 | fixed_password | semmle.label | fixed_password |
| passwords.go:88:19:90:2 | struct literal | semmle.label | struct literal |
| passwords.go:89:16:89:36 | call to make | semmle.label | call to make |
@@ -242,7 +242,7 @@ nodes
| passwords.go:110:34:110:41 | password | semmle.label | password |
| passwords.go:115:15:115:40 | ...+... | semmle.label | ...+... |
| passwords.go:115:33:115:40 | password | semmle.label | password |
| passwords.go:118:6:118:14 | definition of password1 | semmle.label | definition of password1 |
| passwords.go:118:6:118:14 | SSA def(password1) | semmle.label | SSA def(password1) |
| passwords.go:119:14:119:45 | ...+... | semmle.label | ...+... |
| passwords.go:119:28:119:36 | password1 | semmle.label | password1 |
| passwords.go:119:28:119:45 | call to String | semmle.label | call to String |
@@ -257,15 +257,15 @@ nodes
| passwords.go:130:14:130:21 | selection of x | semmle.label | selection of x |
| passwords.go:131:14:131:19 | config [y] | semmle.label | config [y] |
| passwords.go:131:14:131:21 | selection of y | semmle.label | selection of y |
| protobuf.go:9:2:9:9 | definition of password | semmle.label | definition of password |
| protobuf.go:9:2:9:9 | SSA def(password) | semmle.label | SSA def(password) |
| protobuf.go:12:2:12:6 | implicit dereference [postupdate] [Description] | semmle.label | implicit dereference [postupdate] [Description] |
| protobuf.go:12:2:12:6 | query [postupdate] [pointer, Description] | semmle.label | query [postupdate] [pointer, Description] |
| protobuf.go:12:22:12:29 | password | semmle.label | password |
| protobuf.go:14:14:14:18 | query [pointer, Description] | semmle.label | query [pointer, Description] |
| protobuf.go:14:14:14:35 | call to GetDescription | semmle.label | call to GetDescription |
| protos/query/query.pb.go:117:7:117:7 | definition of x [pointer, Description] | semmle.label | definition of x [pointer, Description] |
| protos/query/query.pb.go:117:7:117:7 | SSA def(x) [pointer, Description] | semmle.label | SSA def(x) [pointer, Description] |
| protos/query/query.pb.go:119:10:119:10 | implicit dereference [Description] | semmle.label | implicit dereference [Description] |
| protos/query/query.pb.go:119:10:119:10 | x [pointer, Description] | semmle.label | x [pointer, Description] |
| protos/query/query.pb.go:119:10:119:22 | selection of Description | semmle.label | selection of Description |
subpaths
| protobuf.go:14:14:14:18 | query [pointer, Description] | protos/query/query.pb.go:117:7:117:7 | definition of x [pointer, Description] | protos/query/query.pb.go:119:10:119:22 | selection of Description | protobuf.go:14:14:14:35 | call to GetDescription |
| protobuf.go:14:14:14:18 | query [pointer, Description] | protos/query/query.pb.go:117:7:117:7 | SSA def(x) [pointer, Description] | protos/query/query.pb.go:119:10:119:22 | selection of Description | protobuf.go:14:14:14:35 | call to GetDescription |

View File

@@ -8,18 +8,18 @@ edges
| InsecureHostKeyCallbackExample.go:31:14:34:4 | type conversion | InsecureHostKeyCallbackExample.go:39:20:39:27 | callback | provenance | |
| InsecureHostKeyCallbackExample.go:32:3:34:3 | function literal | InsecureHostKeyCallbackExample.go:31:14:34:4 | type conversion | provenance | |
| InsecureHostKeyCallbackExample.go:45:3:47:3 | function literal | InsecureHostKeyCallbackExample.go:52:20:52:48 | type conversion | provenance | |
| InsecureHostKeyCallbackExample.go:58:39:58:46 | definition of callback | InsecureHostKeyCallbackExample.go:62:20:62:27 | callback | provenance | |
| InsecureHostKeyCallbackExample.go:68:48:68:55 | definition of callback | InsecureHostKeyCallbackExample.go:78:28:78:35 | callback | provenance | |
| InsecureHostKeyCallbackExample.go:58:39:58:46 | SSA def(callback) | InsecureHostKeyCallbackExample.go:62:20:62:27 | callback | provenance | |
| InsecureHostKeyCallbackExample.go:68:48:68:55 | SSA def(callback) | InsecureHostKeyCallbackExample.go:78:28:78:35 | callback | provenance | |
| InsecureHostKeyCallbackExample.go:94:3:94:43 | ... := ...[0] | InsecureHostKeyCallbackExample.go:95:28:95:35 | callback | provenance | |
| InsecureHostKeyCallbackExample.go:102:22:105:4 | type conversion | InsecureHostKeyCallbackExample.go:107:35:107:50 | insecureCallback | provenance | |
| InsecureHostKeyCallbackExample.go:103:3:105:3 | function literal | InsecureHostKeyCallbackExample.go:102:22:105:4 | type conversion | provenance | |
| InsecureHostKeyCallbackExample.go:107:35:107:50 | insecureCallback | InsecureHostKeyCallbackExample.go:58:39:58:46 | definition of callback | provenance | |
| InsecureHostKeyCallbackExample.go:107:35:107:50 | insecureCallback | InsecureHostKeyCallbackExample.go:58:39:58:46 | SSA def(callback) | provenance | |
| InsecureHostKeyCallbackExample.go:109:31:115:4 | type conversion | InsecureHostKeyCallbackExample.go:117:35:117:59 | potentiallySecureCallback | provenance | |
| InsecureHostKeyCallbackExample.go:109:31:115:4 | type conversion | InsecureHostKeyCallbackExample.go:120:44:120:68 | potentiallySecureCallback | provenance | |
| InsecureHostKeyCallbackExample.go:110:3:115:3 | function literal | InsecureHostKeyCallbackExample.go:109:31:115:4 | type conversion | provenance | |
| InsecureHostKeyCallbackExample.go:117:35:117:59 | potentiallySecureCallback | InsecureHostKeyCallbackExample.go:58:39:58:46 | definition of callback | provenance | |
| InsecureHostKeyCallbackExample.go:118:35:118:61 | call to InsecureIgnoreHostKey | InsecureHostKeyCallbackExample.go:58:39:58:46 | definition of callback | provenance | |
| InsecureHostKeyCallbackExample.go:120:44:120:68 | potentiallySecureCallback | InsecureHostKeyCallbackExample.go:68:48:68:55 | definition of callback | provenance | |
| InsecureHostKeyCallbackExample.go:117:35:117:59 | potentiallySecureCallback | InsecureHostKeyCallbackExample.go:58:39:58:46 | SSA def(callback) | provenance | |
| InsecureHostKeyCallbackExample.go:118:35:118:61 | call to InsecureIgnoreHostKey | InsecureHostKeyCallbackExample.go:58:39:58:46 | SSA def(callback) | provenance | |
| InsecureHostKeyCallbackExample.go:120:44:120:68 | potentiallySecureCallback | InsecureHostKeyCallbackExample.go:68:48:68:55 | SSA def(callback) | provenance | |
nodes
| InsecureHostKeyCallbackExample.go:15:20:18:5 | type conversion | semmle.label | type conversion |
| InsecureHostKeyCallbackExample.go:16:4:18:4 | function literal | semmle.label | function literal |
@@ -29,9 +29,9 @@ nodes
| InsecureHostKeyCallbackExample.go:39:20:39:27 | callback | semmle.label | callback |
| InsecureHostKeyCallbackExample.go:45:3:47:3 | function literal | semmle.label | function literal |
| InsecureHostKeyCallbackExample.go:52:20:52:48 | type conversion | semmle.label | type conversion |
| InsecureHostKeyCallbackExample.go:58:39:58:46 | definition of callback | semmle.label | definition of callback |
| InsecureHostKeyCallbackExample.go:58:39:58:46 | SSA def(callback) | semmle.label | SSA def(callback) |
| InsecureHostKeyCallbackExample.go:62:20:62:27 | callback | semmle.label | callback |
| InsecureHostKeyCallbackExample.go:68:48:68:55 | definition of callback | semmle.label | definition of callback |
| InsecureHostKeyCallbackExample.go:68:48:68:55 | SSA def(callback) | semmle.label | SSA def(callback) |
| InsecureHostKeyCallbackExample.go:76:28:76:54 | call to InsecureIgnoreHostKey | semmle.label | call to InsecureIgnoreHostKey |
| InsecureHostKeyCallbackExample.go:78:28:78:35 | callback | semmle.label | callback |
| InsecureHostKeyCallbackExample.go:92:28:92:54 | call to InsecureIgnoreHostKey | semmle.label | call to InsecureIgnoreHostKey |

View File

@@ -1,7 +1,7 @@
edges
| InsufficientKeySize.go:13:10:13:13 | 1024 | InsufficientKeySize.go:14:31:14:34 | size | provenance | |
| InsufficientKeySize.go:18:7:18:10 | 1024 | InsufficientKeySize.go:25:11:25:14 | definition of size | provenance | |
| InsufficientKeySize.go:25:11:25:14 | definition of size | InsufficientKeySize.go:26:31:26:34 | size | provenance | |
| InsufficientKeySize.go:18:7:18:10 | 1024 | InsufficientKeySize.go:25:11:25:14 | SSA def(size) | provenance | |
| InsufficientKeySize.go:25:11:25:14 | SSA def(size) | InsufficientKeySize.go:26:31:26:34 | size | provenance | |
| InsufficientKeySize.go:30:13:30:16 | 1024 | InsufficientKeySize.go:32:32:32:38 | keyBits | provenance | |
| InsufficientKeySize.go:44:13:44:16 | 1024 | InsufficientKeySize.go:47:32:47:38 | keyBits | provenance | |
| InsufficientKeySize.go:61:21:61:24 | 1024 | InsufficientKeySize.go:67:31:67:37 | keyBits | provenance | |
@@ -10,7 +10,7 @@ nodes
| InsufficientKeySize.go:13:10:13:13 | 1024 | semmle.label | 1024 |
| InsufficientKeySize.go:14:31:14:34 | size | semmle.label | size |
| InsufficientKeySize.go:18:7:18:10 | 1024 | semmle.label | 1024 |
| InsufficientKeySize.go:25:11:25:14 | definition of size | semmle.label | definition of size |
| InsufficientKeySize.go:25:11:25:14 | SSA def(size) | semmle.label | SSA def(size) |
| InsufficientKeySize.go:26:31:26:34 | size | semmle.label | size |
| InsufficientKeySize.go:30:13:30:16 | 1024 | semmle.label | 1024 |
| InsufficientKeySize.go:32:32:32:38 | keyBits | semmle.label | keyBits |

View File

@@ -5,15 +5,15 @@ edges
| go-jose.v3.go:25:16:25:20 | selection of URL | go-jose.v3.go:25:16:25:28 | call to Query | provenance | Src:MaD:3 MaD:5 |
| go-jose.v3.go:25:16:25:28 | call to Query | go-jose.v3.go:25:16:25:47 | call to Get | provenance | MaD:6 |
| go-jose.v3.go:25:16:25:47 | call to Get | go-jose.v3.go:26:15:26:25 | signedToken | provenance | |
| go-jose.v3.go:26:15:26:25 | signedToken | go-jose.v3.go:29:19:29:29 | definition of signedToken | provenance | |
| go-jose.v3.go:29:19:29:29 | definition of signedToken | go-jose.v3.go:31:37:31:47 | signedToken | provenance | |
| go-jose.v3.go:26:15:26:25 | signedToken | go-jose.v3.go:29:19:29:29 | SSA def(signedToken) | provenance | |
| go-jose.v3.go:29:19:29:29 | SSA def(signedToken) | go-jose.v3.go:31:37:31:47 | signedToken | provenance | |
| go-jose.v3.go:31:2:31:48 | ... := ...[0] | go-jose.v3.go:33:12:33:23 | DecodedToken | provenance | Sink:MaD:2 |
| go-jose.v3.go:31:37:31:47 | signedToken | go-jose.v3.go:31:2:31:48 | ... := ...[0] | provenance | MaD:4 |
| golang-jwt-v5.go:28:16:28:20 | selection of URL | golang-jwt-v5.go:28:16:28:28 | call to Query | provenance | Src:MaD:3 MaD:5 |
| golang-jwt-v5.go:28:16:28:28 | call to Query | golang-jwt-v5.go:28:16:28:47 | call to Get | provenance | MaD:6 |
| golang-jwt-v5.go:28:16:28:47 | call to Get | golang-jwt-v5.go:29:25:29:35 | signedToken | provenance | |
| golang-jwt-v5.go:29:25:29:35 | signedToken | golang-jwt-v5.go:32:29:32:39 | definition of signedToken | provenance | |
| golang-jwt-v5.go:32:29:32:39 | definition of signedToken | golang-jwt-v5.go:34:58:34:68 | signedToken | provenance | Sink:MaD:1 |
| golang-jwt-v5.go:29:25:29:35 | signedToken | golang-jwt-v5.go:32:29:32:39 | SSA def(signedToken) | provenance | |
| golang-jwt-v5.go:32:29:32:39 | SSA def(signedToken) | golang-jwt-v5.go:34:58:34:68 | signedToken | provenance | Sink:MaD:1 |
models
| 1 | Sink: github.com/golang-jwt/jwt; Parser; true; ParseUnverified; ; ; Argument[0]; jwt; manual |
| 2 | Sink: group:go-jose/jwt; JSONWebToken; true; UnsafeClaimsWithoutVerification; ; ; Argument[receiver]; jwt; manual |
@@ -26,7 +26,7 @@ nodes
| go-jose.v3.go:25:16:25:28 | call to Query | semmle.label | call to Query |
| go-jose.v3.go:25:16:25:47 | call to Get | semmle.label | call to Get |
| go-jose.v3.go:26:15:26:25 | signedToken | semmle.label | signedToken |
| go-jose.v3.go:29:19:29:29 | definition of signedToken | semmle.label | definition of signedToken |
| go-jose.v3.go:29:19:29:29 | SSA def(signedToken) | semmle.label | SSA def(signedToken) |
| go-jose.v3.go:31:2:31:48 | ... := ...[0] | semmle.label | ... := ...[0] |
| go-jose.v3.go:31:37:31:47 | signedToken | semmle.label | signedToken |
| go-jose.v3.go:33:12:33:23 | DecodedToken | semmle.label | DecodedToken |
@@ -34,6 +34,6 @@ nodes
| golang-jwt-v5.go:28:16:28:28 | call to Query | semmle.label | call to Query |
| golang-jwt-v5.go:28:16:28:47 | call to Get | semmle.label | call to Get |
| golang-jwt-v5.go:29:25:29:35 | signedToken | semmle.label | signedToken |
| golang-jwt-v5.go:32:29:32:39 | definition of signedToken | semmle.label | definition of signedToken |
| golang-jwt-v5.go:32:29:32:39 | SSA def(signedToken) | semmle.label | SSA def(signedToken) |
| golang-jwt-v5.go:34:58:34:68 | signedToken | semmle.label | signedToken |
subpaths

View File

@@ -9,31 +9,31 @@
| main.go:69:5:69:22 | ...!=... | main.go:76:19:76:21 | argument corresponding to url | main.go:77:25:77:39 | call to getTarget1 | This is a check that $@, which flows into a $@, has a leading slash, but not that it does not have '/' or '\\' in its second position. | main.go:76:19:76:21 | argument corresponding to url | this value | main.go:77:25:77:39 | call to getTarget1 | redirect |
| main.go:83:5:83:20 | ...!=... | main.go:87:9:87:14 | selection of Path | main.go:91:25:91:39 | call to getTarget2 | This is a check that $@, which flows into a $@, has a leading slash, but not that it does not have '/' or '\\' in its second position. | main.go:87:9:87:14 | selection of Path | this value | main.go:91:25:91:39 | call to getTarget2 | redirect |
edges
| BadRedirectCheck.go:3:18:3:22 | SSA def(redir) | BadRedirectCheck.go:5:10:5:14 | redir | provenance | |
| BadRedirectCheck.go:3:18:3:22 | argument corresponding to redir | BadRedirectCheck.go:5:10:5:14 | redir | provenance | |
| BadRedirectCheck.go:3:18:3:22 | definition of redir | BadRedirectCheck.go:5:10:5:14 | redir | provenance | |
| BadRedirectCheck.go:5:10:5:14 | redir | main.go:11:25:11:45 | call to sanitizeUrl | provenance | Sink:MaD:1 |
| cves.go:14:23:14:25 | argument corresponding to url | cves.go:16:26:16:28 | url | provenance | Sink:MaD:1 |
| cves.go:33:14:33:34 | call to Get | cves.go:37:25:37:32 | redirect | provenance | Sink:MaD:1 |
| cves.go:41:14:41:34 | call to Get | cves.go:45:25:45:32 | redirect | provenance | Sink:MaD:1 |
| main.go:10:18:10:25 | argument corresponding to redirect | main.go:11:37:11:44 | redirect | provenance | |
| main.go:11:37:11:44 | redirect | BadRedirectCheck.go:3:18:3:22 | definition of redir | provenance | |
| main.go:11:37:11:44 | redirect | BadRedirectCheck.go:3:18:3:22 | SSA def(redir) | provenance | |
| main.go:11:37:11:44 | redirect | main.go:11:25:11:45 | call to sanitizeUrl | provenance | Sink:MaD:1 |
| main.go:32:24:32:26 | argument corresponding to url | main.go:34:26:34:28 | url | provenance | Sink:MaD:1 |
| main.go:68:17:68:24 | SSA def(redirect) | main.go:73:20:73:27 | redirect | provenance | |
| main.go:68:17:68:24 | argument corresponding to redirect | main.go:73:20:73:27 | redirect | provenance | |
| main.go:68:17:68:24 | definition of redirect | main.go:73:20:73:27 | redirect | provenance | |
| main.go:73:9:73:28 | call to Clean | main.go:77:25:77:39 | call to getTarget1 | provenance | Sink:MaD:1 |
| main.go:73:20:73:27 | redirect | main.go:73:9:73:28 | call to Clean | provenance | MaD:2 |
| main.go:73:20:73:27 | redirect | main.go:73:9:73:28 | call to Clean | provenance | MaD:2 |
| main.go:76:19:76:21 | argument corresponding to url | main.go:77:36:77:38 | url | provenance | |
| main.go:77:36:77:38 | url | main.go:68:17:68:24 | definition of redirect | provenance | |
| main.go:77:36:77:38 | url | main.go:68:17:68:24 | SSA def(redirect) | provenance | |
| main.go:77:36:77:38 | url | main.go:77:25:77:39 | call to getTarget1 | provenance | MaD:2 Sink:MaD:1 |
| main.go:87:9:87:14 | selection of Path | main.go:91:25:91:39 | call to getTarget2 | provenance | Sink:MaD:1 |
models
| 1 | Sink: net/http; ; false; Redirect; ; ; Argument[2]; url-redirection[0]; manual |
| 2 | Summary: path; ; false; Clean; ; ; Argument[0]; ReturnValue; taint; manual |
nodes
| BadRedirectCheck.go:3:18:3:22 | SSA def(redir) | semmle.label | SSA def(redir) |
| BadRedirectCheck.go:3:18:3:22 | argument corresponding to redir | semmle.label | argument corresponding to redir |
| BadRedirectCheck.go:3:18:3:22 | definition of redir | semmle.label | definition of redir |
| BadRedirectCheck.go:5:10:5:14 | redir | semmle.label | redir |
| BadRedirectCheck.go:5:10:5:14 | redir | semmle.label | redir |
| cves.go:14:23:14:25 | argument corresponding to url | semmle.label | argument corresponding to url |
@@ -47,8 +47,8 @@ nodes
| main.go:11:37:11:44 | redirect | semmle.label | redirect |
| main.go:32:24:32:26 | argument corresponding to url | semmle.label | argument corresponding to url |
| main.go:34:26:34:28 | url | semmle.label | url |
| main.go:68:17:68:24 | SSA def(redirect) | semmle.label | SSA def(redirect) |
| main.go:68:17:68:24 | argument corresponding to redirect | semmle.label | argument corresponding to redirect |
| main.go:68:17:68:24 | definition of redirect | semmle.label | definition of redirect |
| main.go:73:9:73:28 | call to Clean | semmle.label | call to Clean |
| main.go:73:9:73:28 | call to Clean | semmle.label | call to Clean |
| main.go:73:20:73:27 | redirect | semmle.label | redirect |
@@ -59,5 +59,5 @@ nodes
| main.go:87:9:87:14 | selection of Path | semmle.label | selection of Path |
| main.go:91:25:91:39 | call to getTarget2 | semmle.label | call to getTarget2 |
subpaths
| main.go:11:37:11:44 | redirect | BadRedirectCheck.go:3:18:3:22 | definition of redir | BadRedirectCheck.go:5:10:5:14 | redir | main.go:11:25:11:45 | call to sanitizeUrl |
| main.go:77:36:77:38 | url | main.go:68:17:68:24 | definition of redirect | main.go:73:9:73:28 | call to Clean | main.go:77:25:77:39 | call to getTarget1 |
| main.go:11:37:11:44 | redirect | BadRedirectCheck.go:3:18:3:22 | SSA def(redir) | BadRedirectCheck.go:5:10:5:14 | redir | main.go:11:25:11:45 | call to sanitizeUrl |
| main.go:77:36:77:38 | url | main.go:68:17:68:24 | SSA def(redirect) | main.go:73:9:73:28 | call to Clean | main.go:77:25:77:39 | call to getTarget1 |

View File

@@ -53,6 +53,10 @@ _extractor_name_prefix = "%s-%s" % (
"embeddable" if _for_embeddable else "standalone",
)
_compiler_plugin_registrar_service_source = "src/main/resources/META-INF/services/org.jetbrains.kotlin.compiler.plugin.CompilerPluginRegistrar"
_compiler_plugin_registrar_service_target = "META-INF/services/org.jetbrains.kotlin.compiler.plugin.CompilerPluginRegistrar"
py_binary(
name = "generate_dbscheme",
srcs = ["generate_dbscheme.py"],
@@ -64,8 +68,14 @@ _resources = [
r[len("src/main/resources/"):],
)
for r in glob(["src/main/resources/**"])
if r != _compiler_plugin_registrar_service_source
]
_compiler_plugin_registrar_service = (
_compiler_plugin_registrar_service_source,
_compiler_plugin_registrar_service_target,
)
kt_javac_options(
name = "javac-options",
release = "8",
@@ -91,19 +101,32 @@ kt_javac_options(
# * `resource_strip_prefix` is unique per jar, so we must also put other resources under the same version prefix
genrule(
name = "resources-%s" % v,
srcs = [src for src, _ in _resources],
srcs = [src for src, _ in _resources] + (
[_compiler_plugin_registrar_service[0]] if not version_less(v, "2.4.0") else []
),
outs = [
"%s/com/github/codeql/extractor.name" % v,
] + [
"%s/%s" % (v, target)
for _, target in _resources
],
] + (
["%s/%s" % (
v,
_compiler_plugin_registrar_service[1],
)] if not version_less(v, "2.4.0") else []
),
cmd = "\n".join([
"echo %s-%s > $(RULEDIR)/%s/com/github/codeql/extractor.name" % (_extractor_name_prefix, v, v),
] + [
"cp $(execpath %s) $(RULEDIR)/%s/%s" % (source, v, target)
for source, target in _resources
]),
] + (
["cp $(execpath %s) $(RULEDIR)/%s/%s" % (
_compiler_plugin_registrar_service[0],
v,
_compiler_plugin_registrar_service[1],
)] if not version_less(v, "2.4.0") else []
)),
),
kt_jvm_library(
name = "%s-%s" % (_extractor_name_prefix, v),

BIN
java/kotlin-extractor/deps/kotlin-compiler-2.4.0.jar (Stored with Git LFS) Normal file

Binary file not shown.

Binary file not shown.

BIN
java/kotlin-extractor/deps/kotlin-stdlib-2.4.0.jar (Stored with Git LFS) Normal file

Binary file not shown.

View File

@@ -27,7 +27,7 @@ import shutil
import io
import os
DEFAULT_VERSION = "2.3.20"
DEFAULT_VERSION = "2.4.0"
def options():

View File

@@ -3,32 +3,21 @@
package com.github.codeql
import com.intellij.mock.MockProject
import com.intellij.openapi.extensions.LoadingOrder
import org.jetbrains.kotlin.backend.common.extensions.IrGenerationExtension
import org.jetbrains.kotlin.config.CompilerConfiguration
class KotlinExtractorComponentRegistrar : Kotlin2ComponentRegistrar() {
override fun registerProjectComponents(
project: MockProject,
configuration: CompilerConfiguration
) {
override fun doRegisterExtensions(configuration: CompilerConfiguration) {
val invocationTrapFile = configuration[KEY_INVOCATION_TRAP_FILE]
if (invocationTrapFile == null) {
throw Exception("Required argument for TRAP invocation file not given")
}
// Register with LoadingOrder.LAST to ensure the extractor runs after other
// IR generation plugins (like kotlinx.serialization) have generated their code.
val extensionPoint = project.extensionArea.getExtensionPoint(IrGenerationExtension.extensionPointName)
extensionPoint.registerExtension(
registerExtractorExtension(
KotlinExtractorExtension(
invocationTrapFile,
configuration[KEY_CHECK_TRAP_IDENTICAL] ?: false,
configuration[KEY_COMPILATION_STARTTIME],
configuration[KEY_EXIT_AFTER_EXTRACTION] ?: false
),
LoadingOrder.LAST,
project
)
)
}
}

View File

@@ -173,9 +173,9 @@ open class KotlinFileExtractor(
when (d) {
is IrFunction ->
when (d.name.asString()) {
"toString" -> d.valueParameters.isEmpty()
"hashCode" -> d.valueParameters.isEmpty()
"equals" -> d.valueParameters.singleOrNull()?.type?.isNullableAny() ?: false
"toString" -> d.codeQlValueParameters.isEmpty()
"hashCode" -> d.codeQlValueParameters.isEmpty()
"equals" -> d.codeQlValueParameters.singleOrNull()?.type?.isNullableAny() ?: false
else -> false
} && isJavaBinaryDeclaration(d)
else -> false
@@ -721,7 +721,7 @@ open class KotlinFileExtractor(
(it.type as? IrSimpleType)?.classFqName?.asString() != "kotlin.Deprecated"
} +
// Note we lose any arguments to @java.lang.Deprecated that were written in source.
IrConstructorCallImpl.fromSymbolOwner(
codeQlAnnotationFromSymbolOwner(
UNDEFINED_OFFSET,
UNDEFINED_OFFSET,
jldConstructor.returnType,
@@ -781,13 +781,13 @@ open class KotlinFileExtractor(
val locId = tw.getLocation(constructorCall)
tw.writeHasLocation(id, locId)
for (i in 0 until constructorCall.valueArgumentsCount) {
val param = constructorCall.symbol.owner.valueParameters[i]
for (i in 0 until constructorCall.codeQlValueArgumentsCount) {
val param = constructorCall.symbol.owner.codeQlValueParameters[i]
val prop =
constructorCall.symbol.owner.parentAsClass.declarations
.filterIsInstance<IrProperty>()
.first { it.name == param.name }
val v = constructorCall.getValueArgument(i) ?: param.defaultValue?.expression
val v = constructorCall.codeQlGetValueArgument(i) ?: param.defaultValue?.expression
val getter = prop.getter
if (getter == null) {
logger.warnElement("Expected annotation property to define a getter", prop)
@@ -1115,9 +1115,9 @@ open class KotlinFileExtractor(
returnId,
0,
returnId,
f.valueParameters.size,
f.codeQlValueParameters.size,
{ argParent, idxOffset ->
f.valueParameters.forEachIndexed { idx, param ->
f.codeQlValueParameters.forEachIndexed { idx, param ->
val syntheticParamId = useValueParameter(param, proxyFunctionId)
extractVariableAccess(
syntheticParamId,
@@ -1695,9 +1695,9 @@ open class KotlinFileExtractor(
returnId,
0,
returnId,
f.valueParameters.size,
f.codeQlValueParameters.size,
{ argParentId, idxOffset ->
f.valueParameters.mapIndexed { idx, param ->
f.codeQlValueParameters.mapIndexed { idx, param ->
val syntheticParamId = useValueParameter(param, functionId)
extractVariableAccess(
syntheticParamId,
@@ -1792,7 +1792,7 @@ open class KotlinFileExtractor(
extractBody: Boolean,
extractMethodAndParameterTypeAccesses: Boolean
) {
if (f.valueParameters.none { it.defaultValue != null }) return
if (f.codeQlValueParameters.none { it.defaultValue != null }) return
val id = getDefaultsMethodLabel(f)
if (id == null) {
@@ -1800,7 +1800,7 @@ open class KotlinFileExtractor(
return
}
val locId = getLocation(f, null)
val extReceiver = f.extensionReceiverParameter
val extReceiver = f.codeQlExtensionReceiverParameter
val dispatchReceiver = if (f.shouldExtractAsStatic) null else f.dispatchReceiverParameter
val parameterTypes = getDefaultsMethodArgTypes(f)
val allParamTypeResults =
@@ -1869,7 +1869,7 @@ open class KotlinFileExtractor(
tw.writeCompiler_generated(id, CompilerGeneratedKinds.DEFAULT_ARGUMENTS_METHOD.kind)
if (extractBody) {
val nonSyntheticParams = listOfNotNull(dispatchReceiver) + f.valueParameters
val nonSyntheticParams = listOfNotNull(dispatchReceiver) + f.codeQlValueParameters
// This stack entry represents as if we're extracting the 'real' function `f`, giving
// the indices of its non-synthetic parameters
// such that when we extract the default expressions below, any reference to f's nth
@@ -1895,12 +1895,12 @@ open class KotlinFileExtractor(
val realParamsVarId = getValueParameterLabel(id, parameterTypes.size - 2)
val intType = pluginContext.irBuiltIns.intType
val paramIdxOffset =
listOf(dispatchReceiver, f.extensionReceiverParameter).count { it != null }
listOf(dispatchReceiver, f.codeQlExtensionReceiverParameter).count { it != null }
extractBlockBody(id, locId).also { blockId ->
var nextStmt = 0
// For each parameter with a default, sub in the default value if the caller
// hasn't supplied a value:
f.valueParameters.forEachIndexed { paramIdx, param ->
f.codeQlValueParameters.forEachIndexed { paramIdx, param ->
val defaultVal = param.defaultValue
if (defaultVal != null) {
extractIfStmt(locId, blockId, nextStmt++, id).also { ifId ->
@@ -1975,7 +1975,7 @@ open class KotlinFileExtractor(
id
)
tw.writeHasLocation(thisCallId, locId)
f.valueParameters.forEachIndexed { idx, param ->
f.codeQlValueParameters.forEachIndexed { idx, param ->
extractVariableAccess(
tw.getLabelFor<DbParam>(getValueParameterLabel(id, idx)),
param.type,
@@ -2003,9 +2003,9 @@ open class KotlinFileExtractor(
)
.also { thisCallId ->
val realFnIdxOffset =
if (f.extensionReceiverParameter != null) 1 else 0
if (f.codeQlExtensionReceiverParameter != null) 1 else 0
val paramMappings =
f.valueParameters.mapIndexed { idx, param ->
f.codeQlValueParameters.mapIndexed { idx, param ->
Triple(
param.type,
idx + paramIdxOffset,
@@ -2156,7 +2156,7 @@ open class KotlinFileExtractor(
val dispatchReceiver =
f.dispatchReceiverParameter?.let { IrGetValueImpl(-1, -1, it.symbol) }
val extensionReceiver =
f.extensionReceiverParameter?.let { IrGetValueImpl(-1, -1, it.symbol) }
f.codeQlExtensionReceiverParameter?.let { IrGetValueImpl(-1, -1, it.symbol) }
extractExpressionBody(overloadId, realFunctionLocId).also { returnId ->
extractsDefaultsCall(
@@ -2180,28 +2180,28 @@ open class KotlinFileExtractor(
if (!f.hasAnnotation(jvmOverloadsFqName)) {
if (
f is IrConstructor &&
f.valueParameters.isNotEmpty() &&
f.valueParameters.all { it.defaultValue != null } &&
f.codeQlValueParameters.isNotEmpty() &&
f.codeQlValueParameters.all { it.defaultValue != null } &&
f.parentClassOrNull?.let {
// Don't create a default constructor for an annotation class, or a class
// that explicitly declares a no-arg constructor.
!it.isAnnotationClass &&
it.declarations.none { d ->
d is IrConstructor && d.valueParameters.isEmpty()
d is IrConstructor && d.codeQlValueParameters.isEmpty()
}
} == true
) {
// Per https://kotlinlang.org/docs/classes.html#creating-instances-of-classes, a
// single default overload gets created specifically
// when we have all default parameters, regardless of `@JvmOverloads`.
extractGeneratedOverload(f.valueParameters.map { _ -> null })
extractGeneratedOverload(f.codeQlValueParameters.map { _ -> null })
}
return
}
val paramList: MutableList<IrValueParameter?> = f.valueParameters.toMutableList()
for (n in (f.valueParameters.size - 1) downTo 0) {
if (f.valueParameters[n].defaultValue != null) {
val paramList: MutableList<IrValueParameter?> = f.codeQlValueParameters.toMutableList()
for (n in (f.codeQlValueParameters.size - 1) downTo 0) {
if (f.codeQlValueParameters[n].defaultValue != null) {
paramList[n] = null // Remove this parameter, to be replaced by a default value
extractGeneratedOverload(paramList)
}
@@ -2327,7 +2327,7 @@ open class KotlinFileExtractor(
getClassByFqName(pluginContext, it)?.let { annotationClass ->
annotationClass.owner.declarations.firstIsInstanceOrNull<IrConstructor>()?.let {
annotationConstructor ->
IrConstructorCallImpl.fromSymbolOwner(
codeQlAnnotationFromSymbolOwner(
UNDEFINED_OFFSET,
UNDEFINED_OFFSET,
annotationConstructor.returnType,
@@ -2388,13 +2388,13 @@ open class KotlinFileExtractor(
id
}
val extReceiver = f.extensionReceiverParameter
val extReceiver = f.codeQlExtensionReceiverParameter
// The following parameter order is correct, because member $default methods (where
// the order would be [dispatchParam], [extensionParam], normalParams) are not
// extracted here
val fParameters =
listOfNotNull(extReceiver) +
(overriddenAttributes?.valueParameters ?: f.valueParameters)
(overriddenAttributes?.valueParameters ?: f.codeQlValueParameters)
val paramTypes =
fParameters.mapIndexed { i, vp ->
extractValueParameter(
@@ -3069,14 +3069,14 @@ open class KotlinFileExtractor(
logger.errorElement("Unexpected dispatch receiver found", c)
}
if (c.valueArgumentsCount < 1) {
if (c.codeQlValueArgumentsCount < 1) {
logger.errorElement("No arguments found", c)
return
}
extractArgument(id, c, callable, enclosingStmt, 0, "Operand null")
if (c.valueArgumentsCount > 1) {
if (c.codeQlValueArgumentsCount > 1) {
logger.errorElement("Extra arguments found", c)
}
}
@@ -3095,21 +3095,21 @@ open class KotlinFileExtractor(
logger.errorElement("Unexpected dispatch receiver found", c)
}
if (c.valueArgumentsCount < 1) {
if (c.codeQlValueArgumentsCount < 1) {
logger.errorElement("No arguments found", c)
return
}
extractArgument(id, c, callable, enclosingStmt, 0, "LHS null")
if (c.valueArgumentsCount < 2) {
if (c.codeQlValueArgumentsCount < 2) {
logger.errorElement("No RHS found", c)
return
}
extractArgument(id, c, callable, enclosingStmt, 1, "RHS null")
if (c.valueArgumentsCount > 2) {
if (c.codeQlValueArgumentsCount > 2) {
logger.errorElement("Extra arguments found", c)
}
}
@@ -3122,7 +3122,7 @@ open class KotlinFileExtractor(
idx: Int,
msg: String
) {
val op = c.getValueArgument(idx)
val op = c.codeQlGetValueArgument(idx)
if (op == null) {
logger.errorElement(msg, c)
} else {
@@ -3267,8 +3267,8 @@ open class KotlinFileExtractor(
// and which should be replaced by defaults. The final Object parameter is apparently always
// null.
(listOfNotNull(if (f.shouldExtractAsStatic) null else f.dispatchReceiverParameter?.type) +
listOfNotNull(f.extensionReceiverParameter?.type) +
f.valueParameters.map { it.type } +
listOfNotNull(f.codeQlExtensionReceiverParameter?.type) +
f.codeQlValueParameters.map { it.type } +
listOf(pluginContext.irBuiltIns.intType, getDefaultsMethodLastArgType(f)))
.map { erase(it) }
@@ -3345,7 +3345,7 @@ open class KotlinFileExtractor(
val overriddenCallTarget =
(callTarget as? IrSimpleFunction)?.allOverridden(includeSelf = true)?.firstOrNull {
it.overriddenSymbols.isEmpty() &&
it.valueParameters.any { p -> p.defaultValue != null }
it.codeQlValueParameters.any { p -> p.defaultValue != null }
} ?: callTarget
if (isExternalDeclaration(overriddenCallTarget)) {
// Likewise, ensure the overridden target gets extracted.
@@ -3419,7 +3419,7 @@ open class KotlinFileExtractor(
}
val valueArgsWithDummies =
valueArguments.zip(callTarget.valueParameters).map { (expr, param) ->
valueArguments.zip(callTarget.codeQlValueParameters).map { (expr, param) ->
expr ?: IrConstImpl.defaultValueForType(0, 0, param.type)
}
@@ -3529,7 +3529,7 @@ open class KotlinFileExtractor(
callTarget: IrFunction,
valueArguments: List<IrExpression?>
): Boolean {
val varargParam = callTarget.valueParameters.withIndex().find { it.value.isVararg }
val varargParam = callTarget.codeQlValueParameters.withIndex().find { it.value.isVararg }
// If the vararg param is the only one not specified, and it has no default value, then we
// don't need to call a $default method,
// as omitting it already implies passing an empty vararg array.
@@ -3805,7 +3805,7 @@ open class KotlinFileExtractor(
) =
extractCallValueArguments(
callId,
(0 until call.valueArgumentsCount).map { call.getValueArgument(it) },
(0 until call.codeQlValueArgumentsCount).map { call.codeQlGetValueArgument(it) },
enclosingStmt,
enclosingCallable,
idxOffset
@@ -3874,7 +3874,7 @@ open class KotlinFileExtractor(
(owner.parentClassOrNull?.fqNameWhenAvailable?.asString() == type ||
(owner.parent is IrExternalPackageFragment &&
getFileClassFqName(owner)?.asString() == type)) &&
owner.valueParameters
owner.codeQlValueParameters
.map { it.type.classFqName?.asString() }
.toTypedArray() contentEquals parameterTypes
}
@@ -3926,8 +3926,8 @@ open class KotlinFileExtractor(
val result =
javaLangString?.declarations?.findSubType<IrFunction> {
it.name.asString() == "valueOf" &&
it.valueParameters.size == 1 &&
it.valueParameters[0].type == pluginContext.irBuiltIns.anyNType
it.codeQlValueParameters.size == 1 &&
it.codeQlValueParameters[0].type == pluginContext.irBuiltIns.anyNType
}
if (result == null) {
logger.error("Couldn't find declaration java.lang.String.valueOf(Object)")
@@ -3951,7 +3951,7 @@ open class KotlinFileExtractor(
val kotlinNoWhenBranchMatchedConstructor by lazy {
val result =
kotlinNoWhenBranchMatchedExn?.declarations?.findSubType<IrConstructor> {
it.valueParameters.isEmpty()
it.codeQlValueParameters.isEmpty()
}
if (result == null) {
logger.error("Couldn't find no-arg constructor for kotlin.NoWhenBranchMatchedException")
@@ -3990,7 +3990,7 @@ open class KotlinFileExtractor(
verboseln("No match as function name is ${target.name.asString()} not $fName")
return false
}
val extensionReceiverParameter = target.extensionReceiverParameter
val extensionReceiverParameter = target.codeQlExtensionReceiverParameter
val targetClass =
if (extensionReceiverParameter == null) {
if (isNullable == true) {
@@ -4098,8 +4098,8 @@ open class KotlinFileExtractor(
) {
val typeArgs =
if (extractMethodTypeArguments)
(0 until c.typeArgumentsCount)
.map { c.getTypeArgument(it) }
(0 until c.codeQlTypeArgumentsCount)
.map { c.codeQlGetTypeArgument(it) }
.requireNoNullsOrNull()
else listOf()
@@ -4116,9 +4116,9 @@ open class KotlinFileExtractor(
parent,
idx,
enclosingStmt,
(0 until c.valueArgumentsCount).map { c.getValueArgument(it) },
(0 until c.codeQlValueArgumentsCount).map { c.codeQlGetValueArgument(it) },
c.dispatchReceiver,
c.extensionReceiver,
c.codeQlExtensionReceiver,
typeArgs,
extractClassTypeArguments,
c.superQualifierSymbol
@@ -4126,12 +4126,12 @@ open class KotlinFileExtractor(
}
fun extractSpecialEnumFunction(fnName: String) {
if (c.typeArgumentsCount != 1) {
if (c.codeQlTypeArgumentsCount != 1) {
logger.errorElement("Expected to find exactly one type argument", c)
return
}
val enumType = (c.getTypeArgument(0) as? IrSimpleType)?.classifier?.owner
val enumType = (c.codeQlGetTypeArgument(0) as? IrSimpleType)?.classifier?.owner
if (enumType == null) {
logger.errorElement("Couldn't find type of enum type", c)
return
@@ -4178,13 +4178,13 @@ open class KotlinFileExtractor(
} else {
extractExpressionExpr(receiver, callable, id, 0, enclosingStmt)
}
if (c.valueArgumentsCount < 1) {
if (c.codeQlValueArgumentsCount < 1) {
logger.errorElement("No RHS found", c)
} else {
if (c.valueArgumentsCount > 1) {
if (c.codeQlValueArgumentsCount > 1) {
logger.errorElement("Extra arguments found", c)
}
val arg = c.getValueArgument(0)
val arg = c.codeQlGetValueArgument(0)
if (arg == null) {
logger.errorElement("RHS null", c)
} else {
@@ -4205,7 +4205,7 @@ open class KotlinFileExtractor(
} else {
extractExpressionExpr(receiver, callable, id, 0, enclosingStmt)
}
if (c.valueArgumentsCount > 0) {
if (c.codeQlValueArgumentsCount > 0) {
logger.errorElement("Extra arguments found", c)
}
}
@@ -4219,7 +4219,7 @@ open class KotlinFileExtractor(
}
fun binopExt(id: Label<out DbExpr>) {
binopReceiver(id, c.extensionReceiver, "Extension receiver")
binopReceiver(id, c.codeQlExtensionReceiver, "Extension receiver")
}
fun unaryopDisp(id: Label<out DbExpr>) {
@@ -4227,7 +4227,7 @@ open class KotlinFileExtractor(
}
fun unaryopExt(id: Label<out DbExpr>) {
unaryopReceiver(id, c.extensionReceiver, "Extension receiver")
unaryopReceiver(id, c.codeQlExtensionReceiver, "Extension receiver")
}
val dr = c.dispatchReceiver
@@ -4249,7 +4249,7 @@ open class KotlinFileExtractor(
parent,
idx,
enclosingStmt,
listOf(c.extensionReceiver, c.getValueArgument(0)),
listOf(c.codeQlExtensionReceiver, c.codeQlGetValueArgument(0)),
null,
null
)
@@ -4350,7 +4350,7 @@ open class KotlinFileExtractor(
// != gets desugared into not and ==. Here we resugar it.
c.origin == IrStatementOrigin.EXCLEQ &&
isFunction(target, "kotlin", "Boolean", "not") &&
c.valueArgumentsCount == 0 &&
c.codeQlValueArgumentsCount == 0 &&
dr != null &&
dr is IrCall &&
isBuiltinCallInternal(dr, "EQEQ") -> {
@@ -4362,7 +4362,7 @@ open class KotlinFileExtractor(
}
c.origin == IrStatementOrigin.EXCLEQEQ &&
isFunction(target, "kotlin", "Boolean", "not") &&
c.valueArgumentsCount == 0 &&
c.codeQlValueArgumentsCount == 0 &&
dr != null &&
dr is IrCall &&
isBuiltinCallInternal(dr, "EQEQEQ") -> {
@@ -4374,7 +4374,7 @@ open class KotlinFileExtractor(
}
c.origin == IrStatementOrigin.EXCLEQ &&
isFunction(target, "kotlin", "Boolean", "not") &&
c.valueArgumentsCount == 0 &&
c.codeQlValueArgumentsCount == 0 &&
dr != null &&
dr is IrCall &&
isBuiltinCallInternal(dr, "ieee754equals") -> {
@@ -4576,7 +4576,7 @@ open class KotlinFileExtractor(
parent,
idx,
enclosingStmt,
listOf(c.extensionReceiver),
listOf(c.codeQlExtensionReceiver),
null,
null
)
@@ -4596,8 +4596,8 @@ open class KotlinFileExtractor(
val locId = tw.getLocation(c)
extractExprContext(id, locId, callable, enclosingStmt)
if (c.typeArgumentsCount == 1) {
val typeArgument = c.getTypeArgument(0)
if (c.codeQlTypeArgumentsCount == 1) {
val typeArgument = c.codeQlGetTypeArgument(0)
if (typeArgument == null) {
logger.errorElement("Type argument missing in an arrayOfNulls call", c)
} else {
@@ -4618,8 +4618,8 @@ open class KotlinFileExtractor(
)
}
if (c.valueArgumentsCount == 1) {
val dim = c.getValueArgument(0)
if (c.codeQlValueArgumentsCount == 1) {
val dim = c.codeQlGetValueArgument(0)
if (dim != null) {
extractExpressionExpr(dim, callable, id, 0, enclosingStmt)
} else {
@@ -4651,8 +4651,8 @@ open class KotlinFileExtractor(
c.type.getArrayElementTypeCodeQL(pluginContext.irBuiltIns)
} else {
// TODO: is there any reason not to always use getArrayElementTypeCodeQL?
if (c.typeArgumentsCount == 1) {
c.getTypeArgument(0).also {
if (c.codeQlTypeArgumentsCount == 1) {
c.codeQlGetTypeArgument(0).also {
if (it == null) {
logger.errorElement(
"Type argument missing in an arrayOf call",
@@ -4670,7 +4670,7 @@ open class KotlinFileExtractor(
}
val arg =
if (c.valueArgumentsCount == 1) c.getValueArgument(0)
if (c.codeQlValueArgumentsCount == 1) c.codeQlGetValueArgument(0)
else {
logger.errorElement(
"Expected to find only one (vararg) argument in ${c.symbol.owner.name.asString()} call",
@@ -4719,7 +4719,7 @@ open class KotlinFileExtractor(
return
}
val ext = c.extensionReceiver
val ext = c.codeQlExtensionReceiver
if (ext == null) {
logger.errorElement(
"No extension receiver found for `KClass::java` call",
@@ -4826,8 +4826,8 @@ open class KotlinFileExtractor(
c.origin == IrStatementOrigin.EQ &&
c.dispatchReceiver != null -> {
val array = c.dispatchReceiver
val arrayIdx = c.getValueArgument(0)
val assignedValue = c.getValueArgument(1)
val arrayIdx = c.codeQlGetValueArgument(0)
val assignedValue = c.codeQlGetValueArgument(1)
if (array != null && arrayIdx != null && assignedValue != null) {
@@ -4882,22 +4882,22 @@ open class KotlinFileExtractor(
}
isBuiltinCall(c, "<unsafe-coerce>", "kotlin.jvm.internal") -> {
if (c.valueArgumentsCount != 1) {
if (c.codeQlValueArgumentsCount != 1) {
logger.errorElement(
"Expected to find one argument for a kotlin.jvm.internal.<unsafe-coerce>() call, but found ${c.valueArgumentsCount}",
"Expected to find one argument for a kotlin.jvm.internal.<unsafe-coerce>() call, but found ${c.codeQlValueArgumentsCount}",
c
)
return
}
if (c.typeArgumentsCount != 2) {
if (c.codeQlTypeArgumentsCount != 2) {
logger.errorElement(
"Expected to find two type arguments for a kotlin.jvm.internal.<unsafe-coerce>() call, but found ${c.typeArgumentsCount}",
"Expected to find two type arguments for a kotlin.jvm.internal.<unsafe-coerce>() call, but found ${c.codeQlTypeArgumentsCount}",
c
)
return
}
val valueArg = c.getValueArgument(0)
val valueArg = c.codeQlGetValueArgument(0)
if (valueArg == null) {
logger.errorElement(
"Cannot find value argument for a kotlin.jvm.internal.<unsafe-coerce>() call",
@@ -4905,7 +4905,7 @@ open class KotlinFileExtractor(
)
return
}
val typeArg = c.getTypeArgument(1)
val typeArg = c.codeQlGetTypeArgument(1)
if (typeArg == null) {
logger.errorElement(
"Cannot find type argument for a kotlin.jvm.internal.<unsafe-coerce>() call",
@@ -4924,7 +4924,7 @@ open class KotlinFileExtractor(
extractExpressionExpr(valueArg, callable, id, 1, enclosingStmt)
}
isBuiltinCallInternal(c, "dataClassArrayMemberToString") -> {
val arrayArg = c.getValueArgument(0)
val arrayArg = c.codeQlGetValueArgument(0)
val realArrayClass = arrayArg?.type?.classOrNull
if (realArrayClass == null) {
logger.errorElement(
@@ -4936,8 +4936,8 @@ open class KotlinFileExtractor(
val realCallee =
javaUtilArrays?.declarations?.findSubType<IrFunction> { decl ->
decl.name.asString() == "toString" &&
decl.valueParameters.size == 1 &&
decl.valueParameters[0].type.classOrNull?.let {
decl.codeQlValueParameters.size == 1 &&
decl.codeQlValueParameters[0].type.classOrNull?.let {
it == realArrayClass
} == true
}
@@ -4962,7 +4962,7 @@ open class KotlinFileExtractor(
}
}
isBuiltinCallInternal(c, "dataClassArrayMemberHashCode") -> {
val arrayArg = c.getValueArgument(0)
val arrayArg = c.codeQlGetValueArgument(0)
val realArrayClass = arrayArg?.type?.classOrNull
if (realArrayClass == null) {
logger.errorElement(
@@ -4974,8 +4974,8 @@ open class KotlinFileExtractor(
val realCallee =
javaUtilArrays?.declarations?.findSubType<IrFunction> { decl ->
decl.name.asString() == "hashCode" &&
decl.valueParameters.size == 1 &&
decl.valueParameters[0].type.classOrNull?.let {
decl.codeQlValueParameters.size == 1 &&
decl.codeQlValueParameters[0].type.classOrNull?.let {
it == realArrayClass
} == true
}
@@ -5155,7 +5155,7 @@ open class KotlinFileExtractor(
val type = useType(eType)
val isAnonymous = eType.isAnonymous
val locId = tw.getLocation(e)
val valueArgs = (0 until e.valueArgumentsCount).map { e.getValueArgument(it) }
val valueArgs = (0 until e.codeQlValueArgumentsCount).map { e.codeQlGetValueArgument(it) }
val id =
if (
@@ -5211,10 +5211,10 @@ open class KotlinFileExtractor(
realCallTarget is IrConstructor &&
realCallTarget.parentClassOrNull?.fqNameWhenAvailable?.asString() ==
"kotlin.Enum" &&
realCallTarget.valueParameters.size == 2 &&
realCallTarget.valueParameters[0].type ==
realCallTarget.codeQlValueParameters.size == 2 &&
realCallTarget.codeQlValueParameters[0].type ==
pluginContext.irBuiltIns.stringType &&
realCallTarget.valueParameters[1].type == pluginContext.irBuiltIns.intType
realCallTarget.codeQlValueParameters[1].type == pluginContext.irBuiltIns.intType
) {
val id0 =
@@ -5287,7 +5287,7 @@ open class KotlinFileExtractor(
}
val args =
(0 until e.typeArgumentsCount).map { e.getTypeArgument(it) }.requireNoNullsOrNull()
(0 until e.codeQlTypeArgumentsCount).map { e.codeQlGetTypeArgument(it) }.requireNoNullsOrNull()
if (args == null) {
logger.warnElement("Found null type argument in enum constructor call", e)
return
@@ -5365,7 +5365,7 @@ open class KotlinFileExtractor(
// Check for an expression like x = get(x).op(e):
val opReceiver = updateRhs.dispatchReceiver
if (isExpectedLhs(opReceiver)) {
updateRhs.getValueArgument(0)
updateRhs.codeQlGetValueArgument(0)
} else null
} else null
}
@@ -5560,7 +5560,7 @@ open class KotlinFileExtractor(
"set"
)
) {
val updateRhs0 = arraySetCall.getValueArgument(1)
val updateRhs0 = arraySetCall.codeQlGetValueArgument(1)
if (updateRhs0 == null) {
logger.errorElement("Update RHS not found", e)
return false
@@ -6403,12 +6403,12 @@ open class KotlinFileExtractor(
val ids = getLocallyVisibleFunctionLabels(e.function)
val locId = tw.getLocation(e)
val ext = e.function.extensionReceiverParameter
val ext = e.function.codeQlExtensionReceiverParameter
val parameters =
if (ext != null) {
listOf(ext) + e.function.valueParameters
listOf(ext) + e.function.codeQlValueParameters
} else {
e.function.valueParameters
e.function.codeQlValueParameters
}
var types = parameters.map { it.type }
@@ -6670,7 +6670,7 @@ open class KotlinFileExtractor(
is IrFunction -> {
if (
ownerParent.dispatchReceiverParameter == owner &&
ownerParent.extensionReceiverParameter != null
ownerParent.codeQlExtensionReceiverParameter != null
) {
val ownerParent2 = ownerParent.parent
@@ -7089,7 +7089,7 @@ open class KotlinFileExtractor(
makeReceiverInfo(callableReferenceExpr.dispatchReceiver, 0)
private val extensionReceiverInfo =
makeReceiverInfo(
callableReferenceExpr.extensionReceiver,
callableReferenceExpr.codeQlExtensionReceiver,
if (dispatchReceiverInfo == null) 0 else 1
)
@@ -7627,8 +7627,8 @@ open class KotlinFileExtractor(
}
val expressionTypeArguments =
(0 until propertyReferenceExpr.typeArgumentsCount).mapNotNull {
propertyReferenceExpr.getTypeArgument(it)
(0 until propertyReferenceExpr.codeQlTypeArgumentsCount).mapNotNull {
propertyReferenceExpr.codeQlGetTypeArgument(it)
}
val idPropertyRef = tw.getFreshIdLabel<DbPropertyref>()
@@ -7829,7 +7829,7 @@ open class KotlinFileExtractor(
if (
functionReferenceExpr.dispatchReceiver != null &&
functionReferenceExpr.extensionReceiver != null
functionReferenceExpr.codeQlExtensionReceiver != null
) {
logger.errorElement(
"Unexpected: dispatchReceiver and extensionReceiver are both non-null",
@@ -7840,7 +7840,7 @@ open class KotlinFileExtractor(
if (
target.owner.dispatchReceiverParameter != null &&
target.owner.extensionReceiverParameter != null
target.owner.codeQlExtensionReceiverParameter != null
) {
logger.errorElement(
"Unexpected: dispatch and extension parameters are both non-null",
@@ -7899,8 +7899,8 @@ open class KotlinFileExtractor(
null
}
expressionTypeArguments =
(0 until functionReferenceExpr.typeArgumentsCount).mapNotNull {
functionReferenceExpr.getTypeArgument(it)
(0 until functionReferenceExpr.codeQlTypeArgumentsCount).mapNotNull {
functionReferenceExpr.codeQlGetTypeArgument(it)
}
dispatchReceiverIdx = -1
}
@@ -7965,7 +7965,7 @@ open class KotlinFileExtractor(
functionReferenceExpr,
declarationParent,
null,
{ it.valueParameters.size == 1 }
{ it.codeQlValueParameters.size == 1 }
) {
// The argument to FunctionReference's constructor is the function arity.
extractConstantInteger(
@@ -8572,7 +8572,7 @@ open class KotlinFileExtractor(
reverse: Boolean = false
) {
val typeArguments =
(0 until c.typeArgumentsCount).map { c.getTypeArgument(it) }.requireNoNullsOrNull()
(0 until c.codeQlTypeArgumentsCount).map { c.codeQlGetTypeArgument(it) }.requireNoNullsOrNull()
if (typeArguments == null) {
logger.errorElement("Found a null type argument for a member access expression", c)
} else {
@@ -8923,11 +8923,11 @@ open class KotlinFileExtractor(
tw.writeVariableBinding(lhsId, fieldId)
val parameters = mutableListOf<IrValueParameter>()
val extParam = samMember.extensionReceiverParameter
val extParam = samMember.codeQlExtensionReceiverParameter
if (extParam != null) {
parameters.add(extParam)
}
parameters.addAll(samMember.valueParameters)
parameters.addAll(samMember.codeQlValueParameters)
fun extractArgument(
p: IrValueParameter,
@@ -9032,7 +9032,7 @@ open class KotlinFileExtractor(
elementToReportOn: IrElement,
declarationParent: IrDeclarationParent,
compilerGeneratedKindOverride: CompilerGeneratedKinds? = null,
superConstructorSelector: (IrFunction) -> Boolean = { it.valueParameters.isEmpty() },
superConstructorSelector: (IrFunction) -> Boolean = { it.codeQlValueParameters.isEmpty() },
extractSuperconstructorArgs: (Label<DbSuperconstructorinvocationstmt>) -> Unit = {},
): Label<out DbClassorinterface> {
// Write class

View File

@@ -12,7 +12,7 @@ import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.expressions.*
import org.jetbrains.kotlin.ir.symbols.*
import org.jetbrains.kotlin.ir.types.addAnnotations
import com.github.codeql.utils.versions.codeQlAddAnnotations
import org.jetbrains.kotlin.ir.types.classFqName
import org.jetbrains.kotlin.ir.types.classifierOrNull
import org.jetbrains.kotlin.ir.types.classOrNull
@@ -355,7 +355,7 @@ open class KotlinUsesExtractor(
}
private fun propertySignature(p: IrProperty) =
((p.getter ?: p.setter)?.extensionReceiverParameter?.let {
((p.getter ?: p.setter)?.codeQlExtensionReceiverParameter?.let {
useType(erase(it.type)).javaResult.signature
} ?: "")
@@ -368,7 +368,7 @@ open class KotlinUsesExtractor(
// useDeclarationParent -> useFunction
// -> extractFunctionLaterIfExternalFileMember, which would result for `fun <T> f(t:
// T) { ... }` for example.
(listOfNotNull(d.extensionReceiverParameter) + d.valueParameters)
(listOfNotNull(d.codeQlExtensionReceiverParameter) + d.codeQlValueParameters)
.map { useType(erase(it.type)).javaResult.signature }
.joinToString(separator = ",", prefix = "(", postfix = ")")
is IrProperty -> propertySignature(d) + externalClassExtractor.propertySignature
@@ -488,8 +488,8 @@ open class KotlinUsesExtractor(
val result =
replacementClass.declarations.findSubType<IrSimpleFunction> { replacementDecl ->
replacementDecl.name == f.name &&
replacementDecl.valueParameters.size == f.valueParameters.size &&
replacementDecl.valueParameters.zip(f.valueParameters).all {
replacementDecl.codeQlValueParameters.size == f.codeQlValueParameters.size &&
replacementDecl.codeQlValueParameters.zip(f.codeQlValueParameters).all {
erase(it.first.type) == erase(it.second.type)
}
}
@@ -1265,7 +1265,7 @@ open class KotlinUsesExtractor(
private fun getWildcardSuppressionDirective(t: IrAnnotationContainer): Boolean? =
t.getAnnotation(jvmWildcardSuppressionAnnotation)?.let {
@Suppress("USELESS_CAST") // `as? Boolean` is not needed for Kotlin < 2.1
(it.getValueArgument(0) as? CodeQLIrConst<Boolean>)?.value as? Boolean ?: true
(it.codeQlGetValueArgument(0) as? CodeQLIrConst<Boolean>)?.value as? Boolean ?: true
}
private fun addJavaLoweringArgumentWildcards(
@@ -1376,9 +1376,9 @@ open class KotlinUsesExtractor(
f.parent,
parentId,
getFunctionShortName(f).nameInDB,
(maybeParameterList ?: f.valueParameters).map { it.type },
(maybeParameterList ?: f.codeQlValueParameters).map { it.type },
getAdjustedReturnType(f),
f.extensionReceiverParameter?.type,
f.codeQlExtensionReceiverParameter?.type,
getFunctionTypeParameters(f),
classTypeArgsIncludingOuterClasses,
overridesCollectionsMethodWithAlteredParameterTypes(f),
@@ -1401,12 +1401,12 @@ open class KotlinUsesExtractor(
// The name of the function; normally f.name.asString().
name: String,
// The types of the value parameters that the functions takes; normally
// f.valueParameters.map { it.type }.
// f.codeQlValueParameters.map { it.type }.
parameterTypes: List<IrType>,
// The return type of the function; normally f.returnType.
returnType: IrType,
// The extension receiver of the function, if any; normally
// f.extensionReceiverParameter?.type.
// f.codeQlExtensionReceiverParameter?.type.
extensionParamType: IrType?,
// The type parameters of the function. This does not include type parameters of enclosing
// classes.
@@ -1579,7 +1579,7 @@ open class KotlinUsesExtractor(
parentClass.fqNameWhenAvailable?.asString() !=
"java.util.concurrent.ConcurrentHashMap" ||
getFunctionShortName(f).nameInDB != "keySet" ||
f.valueParameters.isNotEmpty() ||
f.codeQlValueParameters.isNotEmpty() ||
f.returnType.classFqName?.asString() != "kotlin.collections.MutableSet"
) {
return f.returnType
@@ -1587,7 +1587,7 @@ open class KotlinUsesExtractor(
val otherKeySet =
parentClass.declarations.findSubType<IrFunction> {
it.name.asString() == "keySet" && it.valueParameters.size == 1
it.name.asString() == "keySet" && it.codeQlValueParameters.size == 1
} ?: return f.returnType
return otherKeySet.returnType.codeQlWithHasQuestionMark(false)
@@ -1695,8 +1695,8 @@ open class KotlinUsesExtractor(
javaClass.declarations.findSubType<IrFunction> { decl ->
!decl.isFakeOverride &&
decl.name.asString() == jvmName &&
decl.valueParameters.size == f.valueParameters.size &&
decl.valueParameters.zip(f.valueParameters).all { p ->
decl.codeQlValueParameters.size == f.codeQlValueParameters.size &&
decl.codeQlValueParameters.zip(f.codeQlValueParameters).all { p ->
erase(p.first.type).classifierOrNull ==
erase(p.second.type).classifierOrNull
}
@@ -2125,7 +2125,7 @@ open class KotlinUsesExtractor(
}
return if (t.arguments.isNotEmpty())
t.addAnnotations(listOf(RawTypeAnnotation.annotationConstructor))
t.codeQlAddAnnotations(listOf(RawTypeAnnotation.annotationConstructor))
else t
}
}
@@ -2153,7 +2153,7 @@ open class KotlinUsesExtractor(
val idxOffset =
if (
declarationParent is IrFunction &&
declarationParent.extensionReceiverParameter != null
declarationParent.codeQlExtensionReceiverParameter != null
)
// For extension functions increase the index to match what the java extractor sees:
1
@@ -2187,7 +2187,7 @@ open class KotlinUsesExtractor(
// Gets a field's corresponding property's extension receiver type, if any
fun getExtensionReceiverType(f: IrField) =
f.correspondingPropertySymbol?.owner?.let {
(it.getter ?: it.setter)?.extensionReceiverParameter?.type
(it.getter ?: it.setter)?.codeQlExtensionReceiverParameter?.type
}
fun getFieldLabel(f: IrField): String {
@@ -2222,14 +2222,14 @@ open class KotlinUsesExtractor(
val setter = p.setter
val func = getter ?: setter
val ext = func?.extensionReceiverParameter
val ext = func?.codeQlExtensionReceiverParameter
return if (ext == null) {
"@\"property;{$parentId};${p.name.asString()}\""
} else {
val returnType =
getter?.returnType
?: setter?.valueParameters?.singleOrNull()?.type
?: setter?.codeQlValueParameters?.singleOrNull()?.type
?: pluginContext.irBuiltIns.unitType
val typeParams = getFunctionTypeParameters(func)

View File

@@ -1,5 +1,10 @@
package com.github.codeql
import com.github.codeql.utils.versions.codeQlAnnotationFromSymbolOwner
import com.github.codeql.utils.versions.codeQlGetValueArgument
import com.github.codeql.utils.versions.codeQlPutValueArgument
import com.github.codeql.utils.versions.codeQlSetAnnotations
import com.github.codeql.utils.versions.codeQlSetDispatchReceiverParameter
import com.github.codeql.utils.versions.createImplicitParameterDeclarationWithWrappedDescriptor
import java.lang.annotation.ElementType
import java.util.HashSet
@@ -95,7 +100,7 @@ class MetaAnnotationSupport(
JvmAnnotationNames.REPEATABLE_ANNOTATION
}
return if (jvmRepeatable != null) {
((jvmRepeatable.getValueArgument(0) as? IrClassReference)?.symbol as? IrClassSymbol)
((jvmRepeatable.codeQlGetValueArgument(0) as? IrClassReference)?.symbol as? IrClassSymbol)
?.owner
} else {
getOrCreateSyntheticRepeatableAnnotationContainer(annotationClass)
@@ -117,12 +122,12 @@ class MetaAnnotationSupport(
)
return null
} else {
return IrConstructorCallImpl.fromSymbolOwner(
return codeQlAnnotationFromSymbolOwner(
containerClass.defaultType,
containerConstructor.symbol
)
.apply {
putValueArgument(
codeQlPutValueArgument(
0,
IrVarargImpl(
UNDEFINED_OFFSET,
@@ -144,7 +149,7 @@ class MetaAnnotationSupport(
// Taken from AdditionalClassAnnotationLowering.kt
private fun loadAnnotationTargets(targetEntry: IrConstructorCall): Set<KotlinTarget>? {
val valueArgument = targetEntry.getValueArgument(0) as? IrVararg ?: return null
val valueArgument = targetEntry.codeQlGetValueArgument(0) as? IrVararg ?: return null
return valueArgument.elements
.filterIsInstance<IrGetEnumValue>()
.mapNotNull { KotlinTarget.valueOrNull(it.symbol.owner.name.asString()) }
@@ -230,14 +235,14 @@ class MetaAnnotationSupport(
)
}
return IrConstructorCallImpl.fromSymbolOwner(
return codeQlAnnotationFromSymbolOwner(
UNDEFINED_OFFSET,
UNDEFINED_OFFSET,
targetConstructor.returnType,
targetConstructor.symbol,
0
)
.apply { putValueArgument(0, vararg) }
.apply { codeQlPutValueArgument(0, vararg) }
}
private val javaAnnotationRetention by lazy {
@@ -263,7 +268,7 @@ class MetaAnnotationSupport(
// Taken from AnnotationCodegen.kt (not available in Kotlin < 1.6.20)
private fun IrClass.getAnnotationRetention(): KotlinRetention? {
val retentionArgument =
getAnnotation(StandardNames.FqNames.retention)?.getValueArgument(0) as? IrGetEnumValue
getAnnotation(StandardNames.FqNames.retention)?.codeQlGetValueArgument(0) as? IrGetEnumValue
?: return null
val retentionArgumentValue = retentionArgument.symbol.owner
return KotlinRetention.valueOf(retentionArgumentValue.name.asString())
@@ -283,7 +288,7 @@ class MetaAnnotationSupport(
val targetConstructor =
retentionType.declarations.firstIsInstanceOrNull<IrConstructor>() ?: return null
return IrConstructorCallImpl.fromSymbolOwner(
return codeQlAnnotationFromSymbolOwner(
UNDEFINED_OFFSET,
UNDEFINED_OFFSET,
targetConstructor.returnType,
@@ -291,7 +296,7 @@ class MetaAnnotationSupport(
0
)
.apply {
putValueArgument(
codeQlPutValueArgument(
0,
IrGetEnumValueImpl(
UNDEFINED_OFFSET,
@@ -333,7 +338,7 @@ class MetaAnnotationSupport(
return
}
val newParam = thisReceiever.copyTo(this)
dispatchReceiverParameter = newParam
codeQlSetDispatchReceiverParameter(newParam)
body =
factory
.createBlockBody(UNDEFINED_OFFSET, UNDEFINED_OFFSET)
@@ -406,7 +411,7 @@ class MetaAnnotationSupport(
val repeatableContainerAnnotation =
kotlinAnnotationRepeatableContainer?.constructors?.single()
containerClass.annotations =
codeQlSetAnnotations(containerClass,
annotationClass.annotations
.filter {
it.isAnnotationWithEqualFqName(StandardNames.FqNames.retention) ||
@@ -415,7 +420,7 @@ class MetaAnnotationSupport(
.map { it.deepCopyWithSymbols(containerClass) } +
listOfNotNull(
repeatableContainerAnnotation?.let {
IrConstructorCallImpl.fromSymbolOwner(
codeQlAnnotationFromSymbolOwner(
UNDEFINED_OFFSET,
UNDEFINED_OFFSET,
it.returnType,
@@ -424,6 +429,7 @@ class MetaAnnotationSupport(
)
}
)
)
containerClass
}
@@ -462,14 +468,14 @@ class MetaAnnotationSupport(
containerClass.symbol,
containerClass.defaultType
)
return IrConstructorCallImpl.fromSymbolOwner(
return codeQlAnnotationFromSymbolOwner(
UNDEFINED_OFFSET,
UNDEFINED_OFFSET,
repeatableConstructor.returnType,
repeatableConstructor.symbol,
0
)
.apply { putValueArgument(0, containerReference) }
.apply { codeQlPutValueArgument(0, containerReference) }
}
private val javaAnnotationDocumented by lazy {
@@ -488,7 +494,7 @@ class MetaAnnotationSupport(
javaAnnotationDocumented?.declarations?.firstIsInstanceOrNull<IrConstructor>()
?: return null
return IrConstructorCallImpl.fromSymbolOwner(
return codeQlAnnotationFromSymbolOwner(
UNDEFINED_OFFSET,
UNDEFINED_OFFSET,
documentedConstructor.returnType,

View File

@@ -1,6 +1,7 @@
package com.github.codeql
import com.github.codeql.KotlinUsesExtractor.LocallyVisibleFunctionLabels
import com.github.codeql.utils.versions.codeQlExtensionReceiver
import com.semmle.extractor.java.PopulateFile
import com.semmle.util.unicode.UTF8Util
import java.io.BufferedWriter
@@ -331,7 +332,7 @@ open class FileTrapWriter(
is IrCall -> {
// Calls have incorrect startOffset, so we adjust them:
val dr = e.dispatchReceiver?.let { getStartOffset(it) }
val er = e.extensionReceiver?.let { getStartOffset(it) }
val er = e.codeQlExtensionReceiver?.let { getStartOffset(it) }
offsetMinOf(e.startOffset, dr, er)
}
else -> e.startOffset

View File

@@ -2,6 +2,7 @@ package com.github.codeql.comments
import com.github.codeql.*
import com.github.codeql.utils.isLocalFunction
import com.github.codeql.utils.versions.codeQlExtensionReceiverParameter
import com.github.codeql.utils.versions.isDispatchReceiver
import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.declarations.*
@@ -11,7 +12,7 @@ import org.jetbrains.kotlin.ir.util.parentClassOrNull
private fun IrValueParameter.isExtensionReceiver(): Boolean {
val parentFun = parent as? IrFunction ?: return false
return parentFun.extensionReceiverParameter == this
return parentFun.codeQlExtensionReceiverParameter == this
}
open class CommentExtractor(

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