diff --git a/.github/workflows/close-stale.yml b/.github/workflows/close-stale.yml new file mode 100644 index 00000000000..c63a6be690c --- /dev/null +++ b/.github/workflows/close-stale.yml @@ -0,0 +1,30 @@ +name: Mark stale issues + +on: + workflow_dispatch: + schedule: + - cron: "30 1 * * *" + +jobs: + stale: + if: github.repository == 'github/codeql' + + runs-on: ubuntu-latest + + steps: + - uses: actions/stale@v3 + with: + repo-token: ${{ secrets.GITHUB_TOKEN }} + stale-issue-message: 'This issue is stale because it has been open 14 days with no activity. Comment or remove the `Stale` label in order to avoid having this issue closed in 7 days.' + close-issue-message: 'This issue was closed because it has been inactive for 7 days.' + days-before-stale: 14 + days-before-close: 7 + only-labels: awaiting-response + + # do not mark PRs as stale + days-before-pr-stale: -1 + days-before-pr-close: -1 + + # Uncomment for dry-run + # debug-only: true + # operations-per-run: 1000 diff --git a/.github/workflows/docs-review.yml b/.github/workflows/docs-review.yml deleted file mode 100644 index bf813f46ead..00000000000 --- a/.github/workflows/docs-review.yml +++ /dev/null @@ -1,29 +0,0 @@ -# When a PR is labelled with 'ready-for-docs-review', -# this workflow comments on the PR to notify the GitHub CodeQL docs team. -name: Request docs review -on: - # Runs in the context of the base repo. - # This gives the workflow write access to comment on PRs. - # The workflow should not check out or build the given ref, - # or use untrusted data from the event payload in a command line. - pull_request_target: - types: [labeled] - -jobs: - request-docs-review: - name: Request docs review - # Run only on labelled PRs to the main repository. - # Do not run on PRs to forks. - if: - github.event.label.name == 'ready-for-docs-review' - && github.event.pull_request.draft == false - && github.event.pull_request.base.repo.full_name == 'github/codeql' - runs-on: ubuntu-latest - steps: - - name: Comment to request docs review - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - PR_NUMBER: ${{ github.event.pull_request.number }} - run: | - gh pr comment "$PR_NUMBER" --repo "github/codeql" \ - --body "Hello @github/docs-content-codeql - this PR is ready for docs review." diff --git a/config/identical-files.json b/config/identical-files.json index b63690c5f1e..3916e95a0cf 100644 --- a/config/identical-files.json +++ b/config/identical-files.json @@ -36,6 +36,7 @@ "cpp/ql/src/semmle/code/cpp/dataflow/internal/tainttracking2/TaintTrackingImpl.qll", "cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/tainttracking1/TaintTrackingImpl.qll", "cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/tainttracking2/TaintTrackingImpl.qll", + "cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/tainttracking3/TaintTrackingImpl.qll", "csharp/ql/src/semmle/code/csharp/dataflow/internal/tainttracking1/TaintTrackingImpl.qll", "csharp/ql/src/semmle/code/csharp/dataflow/internal/tainttracking2/TaintTrackingImpl.qll", "csharp/ql/src/semmle/code/csharp/dataflow/internal/tainttracking3/TaintTrackingImpl.qll", @@ -55,6 +56,10 @@ "csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImplConsistency.qll", "python/ql/src/semmle/python/dataflow/new/internal/DataFlowImplConsistency.qll" ], + "DataFlow Java/C# Flow Summaries": [ + "java/ql/src/semmle/code/java/dataflow/internal/FlowSummaryImpl.qll", + "csharp/ql/src/semmle/code/csharp/dataflow/internal/FlowSummaryImpl.qll" + ], "SsaReadPosition Java/C#": [ "java/ql/src/semmle/code/java/dataflow/internal/rangeanalysis/SsaReadPositionCommon.qll", "csharp/ql/src/semmle/code/csharp/dataflow/internal/rangeanalysis/SsaReadPositionCommon.qll" @@ -376,7 +381,6 @@ ], "DuplicationProblems.inc.qhelp": [ "cpp/ql/src/Metrics/Files/DuplicationProblems.inc.qhelp", - "csharp/ql/src/Metrics/Files/DuplicationProblems.inc.qhelp", "javascript/ql/src/Metrics/DuplicationProblems.inc.qhelp", "python/ql/src/Metrics/DuplicationProblems.inc.qhelp" ], @@ -429,10 +433,11 @@ "SSA C#": [ "csharp/ql/src/semmle/code/csharp/dataflow/internal/SsaImplCommon.qll", "csharp/ql/src/semmle/code/csharp/controlflow/internal/pressa/SsaImplCommon.qll", - "csharp/ql/src/semmle/code/csharp/dataflow/internal/basessa/SsaImplCommon.qll" + "csharp/ql/src/semmle/code/csharp/dataflow/internal/basessa/SsaImplCommon.qll", + "csharp/ql/src/semmle/code/cil/internal/SsaImplCommon.qll" ], "CryptoAlgorithms Python/JS": [ "javascript/ql/src/semmle/javascript/security/CryptoAlgorithms.qll", "python/ql/src/semmle/crypto/Crypto.qll" ] -} +} \ No newline at end of file diff --git a/cpp/autobuilder/Semmle.Autobuild.Cpp.Tests/BuildScripts.cs b/cpp/autobuilder/Semmle.Autobuild.Cpp.Tests/BuildScripts.cs index 87390b7bf8f..d37f3e30e66 100644 --- a/cpp/autobuilder/Semmle.Autobuild.Cpp.Tests/BuildScripts.cs +++ b/cpp/autobuilder/Semmle.Autobuild.Cpp.Tests/BuildScripts.cs @@ -5,6 +5,7 @@ using System; using System.Linq; using Microsoft.Build.Construction; using System.Xml; +using System.IO; namespace Semmle.Autobuild.Cpp.Tests { @@ -43,6 +44,8 @@ namespace Semmle.Autobuild.Cpp.Tests public IDictionary RunProcess = new Dictionary(); public IDictionary RunProcessOut = new Dictionary(); public IDictionary RunProcessWorkingDirectory = new Dictionary(); + public HashSet CreateDirectories { get; } = new HashSet(); + public HashSet<(string, string)> DownloadFiles { get; } = new HashSet<(string, string)>(); int IBuildActions.RunProcess(string cmd, string args, string? workingDirectory, IDictionary? env, out IList stdOut) { @@ -135,6 +138,14 @@ namespace Semmle.Autobuild.Cpp.Tests string IBuildActions.GetFullPath(string path) => path; + string? IBuildActions.GetFileName(string? path) => Path.GetFileName(path?.Replace('\\', '/')); + + public string? GetDirectoryName(string? path) + { + var dir = Path.GetDirectoryName(path?.Replace('\\', '/')); + return dir is null ? path : path?.Substring(0, dir.Length); + } + void IBuildActions.WriteAllText(string filename, string contents) { } @@ -153,6 +164,18 @@ namespace Semmle.Autobuild.Cpp.Tests s = s.Replace($"%{kvp.Key}%", kvp.Value); return s; } + + public void CreateDirectory(string path) + { + if (!CreateDirectories.Contains(path)) + throw new ArgumentException($"Missing CreateDirectory, {path}"); + } + + public void DownloadFile(string address, string fileName) + { + if (!DownloadFiles.Contains((address, fileName))) + throw new ArgumentException($"Missing DownloadFile, {address}, {fileName}"); + } } /// @@ -213,6 +236,7 @@ namespace Semmle.Autobuild.Cpp.Tests Actions.GetEnvironmentVariable[$"CODEQL_EXTRACTOR_{codeqlUpperLanguage}_SOURCE_ARCHIVE_DIR"] = ""; Actions.GetEnvironmentVariable[$"CODEQL_EXTRACTOR_{codeqlUpperLanguage}_ROOT"] = $@"C:\codeql\{codeqlUpperLanguage.ToLowerInvariant()}"; Actions.GetEnvironmentVariable["CODEQL_JAVA_HOME"] = @"C:\codeql\tools\java"; + Actions.GetEnvironmentVariable["CODEQL_PLATFORM"] = "win64"; Actions.GetEnvironmentVariable["SEMMLE_DIST"] = @"C:\odasa"; Actions.GetEnvironmentVariable["SEMMLE_JAVA_HOME"] = @"C:\odasa\tools\java"; Actions.GetEnvironmentVariable["SEMMLE_PLATFORM_TOOLS"] = @"C:\odasa\tools"; @@ -273,7 +297,8 @@ namespace Semmle.Autobuild.Cpp.Tests [Fact] public void TestCppAutobuilderSuccess() { - Actions.RunProcess[@"cmd.exe /C C:\odasa\tools\csharp\nuget\nuget.exe restore C:\Project\test.sln"] = 1; + Actions.RunProcess[@"cmd.exe /C nuget restore C:\Project\test.sln -DisableParallelProcessing"] = 1; + Actions.RunProcess[@"cmd.exe /C C:\Project\.nuget\nuget.exe restore C:\Project\test.sln -DisableParallelProcessing"] = 0; Actions.RunProcess[@"cmd.exe /C CALL ^""C:\Program Files ^(x86^)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat^"" && set Platform=&& type NUL && C:\odasa\tools\odasa index --auto msbuild C:\Project\test.sln /p:UseSharedCompilation=false /t:rebuild /p:Platform=""x86"" /p:Configuration=""Release"" /p:MvcBuildViews=true"] = 0; Actions.RunProcessOut[@"C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe -prerelease -legacy -property installationPath"] = ""; Actions.RunProcess[@"C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe -prerelease -legacy -property installationPath"] = 1; @@ -286,11 +311,13 @@ namespace Semmle.Autobuild.Cpp.Tests Actions.FileExists[@"C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe"] = true; Actions.EnumerateFiles[@"C:\Project"] = "foo.cs\ntest.slx"; Actions.EnumerateDirectories[@"C:\Project"] = ""; + Actions.CreateDirectories.Add(@"C:\Project\.nuget"); + Actions.DownloadFiles.Add(("https://dist.nuget.org/win-x86-commandline/latest/nuget.exe", @"C:\Project\.nuget\nuget.exe")); var autobuilder = CreateAutoBuilder(true); var solution = new TestSolution(@"C:\Project\test.sln"); autobuilder.ProjectsOrSolutionsToBuild.Add(solution); - TestAutobuilderScript(autobuilder, 0, 2); + TestAutobuilderScript(autobuilder, 0, 3); } } } diff --git a/cpp/autobuilder/Semmle.Autobuild.Cpp/Semmle.Autobuild.Cpp.csproj b/cpp/autobuilder/Semmle.Autobuild.Cpp/Semmle.Autobuild.Cpp.csproj index 68cfef57b3d..1d6459d77e3 100644 --- a/cpp/autobuilder/Semmle.Autobuild.Cpp/Semmle.Autobuild.Cpp.csproj +++ b/cpp/autobuilder/Semmle.Autobuild.Cpp/Semmle.Autobuild.Cpp.csproj @@ -17,7 +17,7 @@ - + diff --git a/cpp/change-notes/2021-04-06-assign-where-compare-meant.md b/cpp/change-notes/2021-04-06-assign-where-compare-meant.md new file mode 100644 index 00000000000..e540593b15a --- /dev/null +++ b/cpp/change-notes/2021-04-06-assign-where-compare-meant.md @@ -0,0 +1,2 @@ +lgtm,codescanning +* The 'Assignment where comparison was intended' (cpp/assign-where-compare-meant) query has been improved to flag fewer benign assignments in conditionals. diff --git a/cpp/change-notes/2021-04-13-arithmetic-queries.md b/cpp/change-notes/2021-04-13-arithmetic-queries.md new file mode 100644 index 00000000000..4d0f8833adc --- /dev/null +++ b/cpp/change-notes/2021-04-13-arithmetic-queries.md @@ -0,0 +1,2 @@ +lgtm +* The queries cpp/tainted-arithmetic, cpp/uncontrolled-arithmetic, and cpp/arithmetic-with-extreme-values have been improved to produce fewer false positives. diff --git a/cpp/ql/src/Diagnostics/ExtractionErrors.ql b/cpp/ql/src/Diagnostics/ExtractionErrors.ql new file mode 100644 index 00000000000..a445c3bc0c4 --- /dev/null +++ b/cpp/ql/src/Diagnostics/ExtractionErrors.ql @@ -0,0 +1,16 @@ +/** + * @name Extraction errors + * @description List all extraction errors for files in the source code directory. + * @kind diagnostic + * @id cpp/diagnostics/extraction-errors + */ + +import cpp +import ExtractionErrors + +from ExtractionError error +where + error instanceof ExtractionUnknownError or + exists(error.getFile().getRelativePath()) +select error, "Extraction failed in " + error.getFile() + " with error " + error.getErrorMessage(), + error.getSeverity() diff --git a/cpp/ql/src/Diagnostics/ExtractionErrors.qll b/cpp/ql/src/Diagnostics/ExtractionErrors.qll new file mode 100644 index 00000000000..4cf6f8145f8 --- /dev/null +++ b/cpp/ql/src/Diagnostics/ExtractionErrors.qll @@ -0,0 +1,137 @@ +/** + * Provides a common hierarchy of all types of errors that can occur during extraction. + */ + +import cpp + +/* + * A note about how the C/C++ extractor emits diagnostics: + * When the extractor frontend encounters an error, it emits a diagnostic message, + * that includes a message, location and severity. + * However, that process is best-effort and may fail (e.g. due to lack of memory). + * Thus, if the extractor emitted at least one diagnostic of severity discretionary + * error (or higher), it *also* emits a simple "There was an error during this compilation" + * error diagnostic, without location information. + * In the common case, this means that a compilation during which one or more errors happened also gets + * the catch-all diagnostic. + * This diagnostic has the empty string as file path. + * We filter out these useless diagnostics if there is at least one error-level diagnostic + * for the affected compilation in the database. + * Otherwise, we show it to indicate that something went wrong and that we + * don't know what exactly happened. + */ + +/** + * An error that, if present, leads to a file being marked as non-successfully extracted. + */ +class ReportableError extends Diagnostic { + ReportableError() { + ( + this instanceof CompilerDiscretionaryError or + this instanceof CompilerError or + this instanceof CompilerCatastrophe + ) and + // Filter for the catch-all diagnostic, see note above. + not this.getFile().getAbsolutePath() = "" + } +} + +private newtype TExtractionError = + TReportableError(ReportableError err) or + TCompilationFailed(Compilation c, File f) { + f = c.getAFileCompiled() and not c.normalTermination() + } or + // Show the catch-all diagnostic (see note above) only if we haven't seen any other error-level diagnostic + // for that compilation + TUnknownError(CompilerError err) { + not exists(ReportableError e | e.getCompilation() = err.getCompilation()) + } + +/** + * Superclass for the extraction error hierarchy. + */ +class ExtractionError extends TExtractionError { + /** Gets the string representation of the error. */ + string toString() { none() } + + /** Gets the error message for this error. */ + string getErrorMessage() { none() } + + /** Gets the file this error occured in. */ + File getFile() { none() } + + /** Gets the location this error occured in. */ + Location getLocation() { none() } + + /** Gets the SARIF severity of this error. */ + int getSeverity() { + // Unfortunately, we can't distinguish between errors and fatal errors in SARIF, + // so all errors have severity 2. + result = 2 + } +} + +/** + * An unrecoverable extraction error, where extraction was unable to finish. + * This can be caused by a multitude of reasons, for example: + * - hitting a frontend assertion + * - crashing due to dereferencing an invalid pointer + * - stack overflow + * - out of memory + */ +class ExtractionUnrecoverableError extends ExtractionError, TCompilationFailed { + Compilation c; + File f; + + ExtractionUnrecoverableError() { this = TCompilationFailed(c, f) } + + override string toString() { + result = "Unrecoverable extraction error while compiling " + f.toString() + } + + override string getErrorMessage() { result = "unrecoverable compilation failure." } + + override File getFile() { result = f } + + override Location getLocation() { result = f.getLocation() } +} + +/** + * A recoverable extraction error. + * These are compiler errors from the frontend. + * Upon encountering one of these, we still continue extraction, but the + * database will be incomplete for that file. + */ +class ExtractionRecoverableError extends ExtractionError, TReportableError { + ReportableError err; + + ExtractionRecoverableError() { this = TReportableError(err) } + + override string toString() { result = "Recoverable extraction error: " + err } + + override string getErrorMessage() { result = err.getFullMessage() } + + override File getFile() { result = err.getFile() } + + override Location getLocation() { result = err.getLocation() } +} + +/** + * An unknown error happened during extraction. + * These are only displayed if we know that we encountered an error during extraction, + * but, for some reason, failed to emit a proper diagnostic with location information + * and error message. + */ +class ExtractionUnknownError extends ExtractionError, TUnknownError { + CompilerError err; + + ExtractionUnknownError() { this = TUnknownError(err) } + + override string toString() { result = "Unknown extraction error: " + err } + + override string getErrorMessage() { result = err.getFullMessage() } + + override File getFile() { result = err.getFile() } + + override Location getLocation() { result = err.getLocation() } +} diff --git a/cpp/ql/src/Diagnostics/FailedExtractions.ql b/cpp/ql/src/Diagnostics/FailedExtractorInvocations.ql similarity index 70% rename from cpp/ql/src/Diagnostics/FailedExtractions.ql rename to cpp/ql/src/Diagnostics/FailedExtractorInvocations.ql index 513c833f14f..ec1a243f245 100644 --- a/cpp/ql/src/Diagnostics/FailedExtractions.ql +++ b/cpp/ql/src/Diagnostics/FailedExtractorInvocations.ql @@ -1,8 +1,8 @@ /** - * @name Failed extractions - * @description Gives the command-line of compilations for which extraction did not run to completion. + * @name Failed extractor invocations + * @description Gives the command line of compilations for which extraction did not run to completion. * @kind diagnostic - * @id cpp/diagnostics/failed-extractions + * @id cpp/diagnostics/failed-extractor-invocations */ import cpp @@ -19,4 +19,4 @@ string describe(Compilation c) { from Compilation c where not c.normalTermination() -select c, "Extraction failed for " + describe(c), 2 +select c, "Extraction aborted for " + describe(c), 2 diff --git a/cpp/ql/src/Diagnostics/SuccessfullyExtractedFiles.ql b/cpp/ql/src/Diagnostics/SuccessfullyExtractedFiles.ql new file mode 100644 index 00000000000..a920af8e767 --- /dev/null +++ b/cpp/ql/src/Diagnostics/SuccessfullyExtractedFiles.ql @@ -0,0 +1,15 @@ +/** + * @name Successfully extracted files + * @description Lists all files in the source code directory that were extracted without encountering an error in the file. + * @kind diagnostic + * @id cpp/diagnostics/successfully-extracted-files + */ + +import cpp +import ExtractionErrors + +from File f +where + not exists(ExtractionError e | e.getFile() = f) and + exists(f.getRelativePath()) +select f, "" diff --git a/cpp/ql/src/Likely Bugs/Likely Typos/AssignWhereCompareMeant.ql b/cpp/ql/src/Likely Bugs/Likely Typos/AssignWhereCompareMeant.ql index ca116a8609c..e60b763bc53 100644 --- a/cpp/ql/src/Likely Bugs/Likely Typos/AssignWhereCompareMeant.ql +++ b/cpp/ql/src/Likely Bugs/Likely Typos/AssignWhereCompareMeant.ql @@ -54,7 +54,7 @@ class BooleanControllingAssignmentInExpr extends BooleanControllingAssignment { override predicate isWhitelisted() { this.getConversion().(ParenthesisExpr).isParenthesised() or - // whitelist this assignment if all comparison operations in the expression that this + // Allow this assignment if all comparison operations in the expression that this // assignment is part of, are not parenthesized. In that case it seems like programmer // is fine with unparenthesized comparison operands to binary logical operators, and // the parenthesis around this assignment was used to call it out as an assignment. @@ -62,6 +62,21 @@ class BooleanControllingAssignmentInExpr extends BooleanControllingAssignment { forex(ComparisonOperation op | op = getComparisonOperand*(this.getParent+()) | not op.isParenthesised() ) + or + // Match a pattern like: + // ``` + // if((a = b) && use_value(a)) { ... } + // ``` + // where the assignment is meant to update the value of `a` before it's used in some other boolean + // subexpression that is guarenteed to be evaluate _after_ the assignment. + this.isParenthesised() and + exists(LogicalAndExpr parent, Variable var, VariableAccess access | + var = this.getLValue().(VariableAccess).getTarget() and + access = var.getAnAccess() and + not access.isUsedAsLValue() and + parent.getRightOperand() = access.getParent*() and + parent.getLeftOperand() = this.getParent*() + ) } } diff --git a/cpp/ql/src/Likely Bugs/Memory Management/ReturnStackAllocatedMemory.ql b/cpp/ql/src/Likely Bugs/Memory Management/ReturnStackAllocatedMemory.ql index fc06ed0a500..f5dda53d484 100644 --- a/cpp/ql/src/Likely Bugs/Memory Management/ReturnStackAllocatedMemory.ql +++ b/cpp/ql/src/Likely Bugs/Memory Management/ReturnStackAllocatedMemory.ql @@ -13,6 +13,7 @@ import cpp import semmle.code.cpp.dataflow.EscapesTree +import semmle.code.cpp.models.interfaces.PointerWrapper import semmle.code.cpp.dataflow.DataFlow /** @@ -39,6 +40,10 @@ predicate hasNontrivialConversion(Expr e) { e instanceof ParenthesisExpr ) or + // A smart pointer can be stack-allocated while the data it points to is heap-allocated. + // So we exclude such "conversions" from this predicate. + e = any(PointerWrapper wrapper).getAnUnwrapperFunction().getACallToThisFunction() + or hasNontrivialConversion(e.getConversion()) } diff --git a/cpp/ql/src/Metrics/Dependencies/ExternalDependencies.ql b/cpp/ql/src/Metrics/Dependencies/ExternalDependencies.ql index 47ddb9d1f1e..a4e9c925119 100644 --- a/cpp/ql/src/Metrics/Dependencies/ExternalDependencies.ql +++ b/cpp/ql/src/Metrics/Dependencies/ExternalDependencies.ql @@ -5,7 +5,6 @@ * @kind treemap * @treemap.warnOn highValues * @metricType externalDependency - * @precision medium * @id cpp/external-dependencies * @tags modularity */ diff --git a/cpp/ql/src/Metrics/Files/FLinesOfCode.ql b/cpp/ql/src/Metrics/Files/FLinesOfCode.ql index 07c8934115c..11b3eac2977 100644 --- a/cpp/ql/src/Metrics/Files/FLinesOfCode.ql +++ b/cpp/ql/src/Metrics/Files/FLinesOfCode.ql @@ -7,7 +7,6 @@ * @treemap.warnOn highValues * @metricType file * @metricAggregate avg sum max - * @precision very-high * @id cpp/lines-of-code-in-files * @tags maintainability * complexity diff --git a/cpp/ql/src/Metrics/Files/FLinesOfCommentedOutCode.ql b/cpp/ql/src/Metrics/Files/FLinesOfCommentedOutCode.ql index 495464d633b..13ff54e5525 100644 --- a/cpp/ql/src/Metrics/Files/FLinesOfCommentedOutCode.ql +++ b/cpp/ql/src/Metrics/Files/FLinesOfCommentedOutCode.ql @@ -5,7 +5,6 @@ * @treemap.warnOn highValues * @metricType file * @metricAggregate avg sum max - * @precision high * @id cpp/lines-of-commented-out-code-in-files * @tags documentation */ diff --git a/cpp/ql/src/Metrics/Files/FLinesOfComments.ql b/cpp/ql/src/Metrics/Files/FLinesOfComments.ql index 4787587474e..2372f5cc375 100644 --- a/cpp/ql/src/Metrics/Files/FLinesOfComments.ql +++ b/cpp/ql/src/Metrics/Files/FLinesOfComments.ql @@ -7,7 +7,6 @@ * @treemap.warnOn lowValues * @metricType file * @metricAggregate avg sum max - * @precision very-high * @id cpp/lines-of-comments-in-files * @tags maintainability * documentation diff --git a/cpp/ql/src/Metrics/Files/FLinesOfDuplicatedCode.ql b/cpp/ql/src/Metrics/Files/FLinesOfDuplicatedCode.ql index ab9317ea316..8b46df05adc 100644 --- a/cpp/ql/src/Metrics/Files/FLinesOfDuplicatedCode.ql +++ b/cpp/ql/src/Metrics/Files/FLinesOfDuplicatedCode.ql @@ -8,7 +8,6 @@ * @treemap.warnOn highValues * @metricType file * @metricAggregate avg sum max - * @precision high * @id cpp/duplicated-lines-in-files * @tags testability * modularity diff --git a/cpp/ql/src/Metrics/Files/FNumberOfTests.ql b/cpp/ql/src/Metrics/Files/FNumberOfTests.ql index 421fc2baba1..c7ec5983253 100644 --- a/cpp/ql/src/Metrics/Files/FNumberOfTests.ql +++ b/cpp/ql/src/Metrics/Files/FNumberOfTests.ql @@ -5,7 +5,6 @@ * @treemap.warnOn lowValues * @metricType file * @metricAggregate avg sum max - * @precision medium * @id cpp/tests-in-files * @tags maintainability */ diff --git a/cpp/ql/src/Security/CWE/CWE-428/UnsafeCreateProcessCall.ql b/cpp/ql/src/Security/CWE/CWE-428/UnsafeCreateProcessCall.ql index 81e50446d9d..c0f44a0c3d6 100644 --- a/cpp/ql/src/Security/CWE/CWE-428/UnsafeCreateProcessCall.ql +++ b/cpp/ql/src/Security/CWE/CWE-428/UnsafeCreateProcessCall.ql @@ -93,7 +93,7 @@ class QuotedCommandInCreateProcessFunctionConfiguration extends DataFlow2::Confi bindingset[s] predicate isQuotedOrNoSpaceApplicationNameOnCmd(string s) { - s.regexpMatch("\"([^\"])*\"(\\s|.)*") // The first element (path) is quoted + s.regexpMatch("\"([^\"])*\"[\\s\\S]*") // The first element (path) is quoted or s.regexpMatch("[^\\s]+") // There are no spaces in the string } diff --git a/cpp/ql/src/Summary/LinesOfCode.ql b/cpp/ql/src/Summary/LinesOfCode.ql new file mode 100644 index 00000000000..3b2aa2ac4c9 --- /dev/null +++ b/cpp/ql/src/Summary/LinesOfCode.ql @@ -0,0 +1,11 @@ +/** + * @id cpp/summary/lines-of-code + * @name Total lines of C/C++ code in the database + * @description The total number of lines of C/C++ code across all files, including system headers, libraries, and auto-generated files. This is a useful metric of the size of a database. For all files that were seen during the build, this query counts the lines of code, excluding whitespace or comments. + * @kind metric + * @tags summary + */ + +import cpp + +select sum(File f | f.fromSource() | f.getMetrics().getNumberOfLinesOfCode()) diff --git a/cpp/ql/src/experimental/Security/CWE/CWE-570/WrongInDetectingAndHandlingMemoryAllocationErrors.ql b/cpp/ql/src/experimental/Security/CWE/CWE-570/WrongInDetectingAndHandlingMemoryAllocationErrors.ql index dd9c16fac11..4869da7e6f3 100644 --- a/cpp/ql/src/experimental/Security/CWE/CWE-570/WrongInDetectingAndHandlingMemoryAllocationErrors.ql +++ b/cpp/ql/src/experimental/Security/CWE/CWE-570/WrongInDetectingAndHandlingMemoryAllocationErrors.ql @@ -72,9 +72,9 @@ class WrongCheckErrorOperatorNew extends FunctionCall { } /** - * Holds if `(std::nothrow)` exists in call `operator new`. + * Holds if `(std::nothrow)` or `(std::noexcept)` exists in call `operator new`. */ - predicate isExistsNothrow() { this.getAChild().toString() = "nothrow" } + predicate isExistsNothrow() { getTarget().isNoExcept() or getTarget().isNoThrow() } } from WrongCheckErrorOperatorNew op diff --git a/cpp/ql/src/experimental/Security/CWE/CWE-691/InsufficientControlFlowManagementWhenUsingBitOperations.c b/cpp/ql/src/experimental/Security/CWE/CWE-691/InsufficientControlFlowManagementWhenUsingBitOperations.c new file mode 100644 index 00000000000..27631843118 --- /dev/null +++ b/cpp/ql/src/experimental/Security/CWE/CWE-691/InsufficientControlFlowManagementWhenUsingBitOperations.c @@ -0,0 +1,4 @@ +if(len>0 & memset(buf,0,len)) return 1; // BAD: `memset` will be called regardless of the value of the `len` variable. moreover, one cannot be sure that it will happen after verification +... +if(len>0 && memset(buf,0,len)) return 1; // GOOD: `memset` will be called after the `len` variable has been checked. +... diff --git a/cpp/ql/src/experimental/Security/CWE/CWE-691/InsufficientControlFlowManagementWhenUsingBitOperations.qhelp b/cpp/ql/src/experimental/Security/CWE/CWE-691/InsufficientControlFlowManagementWhenUsingBitOperations.qhelp new file mode 100644 index 00000000000..f49d5a4fe78 --- /dev/null +++ b/cpp/ql/src/experimental/Security/CWE/CWE-691/InsufficientControlFlowManagementWhenUsingBitOperations.qhelp @@ -0,0 +1,28 @@ + + + +

Using bitwise operations can be a mistake in some situations. For example, if parameters are evaluated in an expression and the function should be called only upon certain test results. These bitwise operations look suspicious and require developer attention.

+ + +
+ + +

We recommend that you evaluate the correctness of using the specified bit operations.

+ +
+ +

The following example demonstrates the erroneous and fixed use of bit and logical operations.

+ + +
+ + +
  • + CWE Common Weakness Enumeration: + CWE-691: Insufficient Control Flow Management. +
  • + +
    +
    diff --git a/cpp/ql/src/experimental/Security/CWE/CWE-691/InsufficientControlFlowManagementWhenUsingBitOperations.ql b/cpp/ql/src/experimental/Security/CWE/CWE-691/InsufficientControlFlowManagementWhenUsingBitOperations.ql new file mode 100644 index 00000000000..72d7625b517 --- /dev/null +++ b/cpp/ql/src/experimental/Security/CWE/CWE-691/InsufficientControlFlowManagementWhenUsingBitOperations.ql @@ -0,0 +1,78 @@ +/** + * @name Errors When Using Bit Operations + * @description Unlike the binary operations `||` and `&&`, there is no sequence point after evaluating an + * operand of a bitwise operation like `|` or `&`. If left-to-right evaluation is expected this may be confusing. + * @kind problem + * @id cpp/errors-when-using-bit-operations + * @problem.severity warning + * @precision medium + * @tags correctness + * security + * external/cwe/cwe-691 + */ + +import cpp +import semmle.code.cpp.valuenumbering.GlobalValueNumbering + +/** + * Dangerous uses of bit operations. + * For example: `if(intA>0 & intA<10 & charBuf&myFunc(charBuf[intA]))`. + * In this case, the function will be called in any case, and even the sequence of the call is not guaranteed. + */ +class DangerousBitOperations extends BinaryBitwiseOperation { + FunctionCall bfc; + + /** + * The assignment indicates the conscious use of the bit operator. + * Use in comparison, conversion, or return value indicates conscious use of the bit operator. + * The use of shifts and bitwise operations on any element of an expression indicates a conscious use of the bitwise operator. + */ + DangerousBitOperations() { + bfc = this.getRightOperand() and + not this.getParent*() instanceof Assignment and + not this.getParent*() instanceof Initializer and + not this.getParent*() instanceof ReturnStmt and + not this.getParent*() instanceof EqualityOperation and + not this.getParent*() instanceof UnaryLogicalOperation and + not this.getParent*() instanceof BinaryLogicalOperation and + not this.getAChild*() instanceof BitwiseXorExpr and + not this.getAChild*() instanceof LShiftExpr and + not this.getAChild*() instanceof RShiftExpr + } + + /** Holds when part of a bit expression is used in a logical operation. */ + predicate useInLogicalOperations() { + exists(BinaryLogicalOperation blop, Expr exp | + blop.getAChild*() = exp and + exp.(FunctionCall).getTarget() = bfc.getTarget() and + not exp.getParent() instanceof ComparisonOperation and + not exp.getParent() instanceof BinaryBitwiseOperation + ) + } + + /** Holds when part of a bit expression is used as part of another supply. For example, as an argument to another function. */ + predicate useInOtherCalls() { + bfc.hasQualifier() or + bfc.getTarget() instanceof Operator or + exists(FunctionCall fc | fc.getAnArgument().getAChild*() = this) or + bfc.getTarget() instanceof BuiltInFunction + } + + /** Holds when the bit expression contains both arguments and a function call. */ + predicate dangerousArgumentChecking() { + not this.getLeftOperand() instanceof Call and + globalValueNumber(this.getLeftOperand().getAChild*()) = globalValueNumber(bfc.getAnArgument()) + } + + /** Holds when function calls are present in the bit expression. */ + predicate functionCallsInBitsExpression() { + this.getLeftOperand().getAChild*() instanceof FunctionCall + } +} + +from DangerousBitOperations dbo +where + not dbo.useInOtherCalls() and + dbo.useInLogicalOperations() and + (not dbo.functionCallsInBitsExpression() or dbo.dangerousArgumentChecking()) +select dbo, "This bitwise operation appears in a context where a Boolean operation is expected." diff --git a/cpp/ql/src/experimental/Security/CWE/CWE-783/OperatorPrecedenceLogicErrorWhenUseBoolType.c b/cpp/ql/src/experimental/Security/CWE/CWE-783/OperatorPrecedenceLogicErrorWhenUseBoolType.c new file mode 100644 index 00000000000..8458d82f7ad --- /dev/null +++ b/cpp/ql/src/experimental/Security/CWE/CWE-783/OperatorPrecedenceLogicErrorWhenUseBoolType.c @@ -0,0 +1,11 @@ +if(len=funcReadData()==0) return 1; // BAD: variable `len` will not equal the value returned by function `funcReadData()` +... +if((len=funcReadData())==0) return 1; // GOOD: variable `len` equal the value returned by function `funcReadData()` +... +bool a=true; +a++;// BAD: variable `a` does not change its meaning +bool b; +b=-a;// BAD: variable `b` equal `true` +... +a=false;// GOOD: variable `a` equal `false` +b=!a;// GOOD: variable `b` equal `false` diff --git a/cpp/ql/src/experimental/Security/CWE/CWE-783/OperatorPrecedenceLogicErrorWhenUseBoolType.qhelp b/cpp/ql/src/experimental/Security/CWE/CWE-783/OperatorPrecedenceLogicErrorWhenUseBoolType.qhelp new file mode 100644 index 00000000000..8114da831fe --- /dev/null +++ b/cpp/ql/src/experimental/Security/CWE/CWE-783/OperatorPrecedenceLogicErrorWhenUseBoolType.qhelp @@ -0,0 +1,28 @@ + + + +

    Finding places of confusing use of boolean type. For example, a unary minus does not work before a boolean type and an increment always gives true.

    + + +
    + + +

    we recommend making the code simpler.

    + +
    + +

    The following example demonstrates erroneous and fixed methods for using a boolean data type.

    + + +
    + + +
  • + CERT C Coding Standard: + EXP00-C. Use parentheses for precedence of operation. +
  • + +
    +
    diff --git a/cpp/ql/src/experimental/Security/CWE/CWE-783/OperatorPrecedenceLogicErrorWhenUseBoolType.ql b/cpp/ql/src/experimental/Security/CWE/CWE-783/OperatorPrecedenceLogicErrorWhenUseBoolType.ql new file mode 100644 index 00000000000..4f30f112eb0 --- /dev/null +++ b/cpp/ql/src/experimental/Security/CWE/CWE-783/OperatorPrecedenceLogicErrorWhenUseBoolType.ql @@ -0,0 +1,54 @@ +/** + * @name Operator Precedence Logic Error When Use Bool Type + * @description --Finding places of confusing use of boolean type. + * --For example, a unary minus does not work before a boolean type and an increment always gives true. + * @kind problem + * @id cpp/operator-precedence-logic-error-when-use-bool-type + * @problem.severity warning + * @precision medium + * @tags correctness + * security + * external/cwe/cwe-783 + * external/cwe/cwe-480 + */ + +import cpp +import semmle.code.cpp.valuenumbering.HashCons + +/** Holds if `exp` increments a boolean value. */ +predicate incrementBoolType(IncrementOperation exp) { + exp.getOperand().getType() instanceof BoolType +} + +/** Holds if `exp` applies the unary minus operator to a boolean type. */ +predicate revertSignBoolType(UnaryMinusExpr exp) { + exp.getAnOperand().getType() instanceof BoolType and + exp.getFullyConverted().getType() instanceof BoolType +} + +/** Holds, if this is an expression, uses comparison and assignment outside of execution precedence. */ +predicate assignBoolType(Expr exp) { + exists(ComparisonOperation co | + exp.(AssignExpr).getRValue() = co and + exp.isCondition() and + not co.isParenthesised() and + not exp.(AssignExpr).getLValue().getType() instanceof BoolType and + not exists(Expr exbl | + hashCons(exbl.(AssignExpr).getLValue()) = hashCons(exp.(AssignExpr).getLValue()) and + not exbl.isCondition() and + exbl.(AssignExpr).getRValue().getType() instanceof BoolType and + exbl.(AssignExpr).getLValue().getType() = exp.(AssignExpr).getLValue().getType() + ) and + co.getLeftOperand() instanceof FunctionCall and + not co.getRightOperand().getType() instanceof BoolType and + not co.getRightOperand().getValue() = "0" and + not co.getRightOperand().getValue() = "1" + ) +} + +from Expr exp +where + incrementBoolType(exp) or + revertSignBoolType(exp) or + assignBoolType(exp) +select exp, "this expression needs attention" diff --git a/cpp/ql/src/experimental/Security/CWE/CWE-788/AccessOfMemoryLocationAfterEndOfBufferUsingStrlen.ql b/cpp/ql/src/experimental/Security/CWE/CWE-788/AccessOfMemoryLocationAfterEndOfBufferUsingStrlen.ql index 012109074e9..e4577968730 100644 --- a/cpp/ql/src/experimental/Security/CWE/CWE-788/AccessOfMemoryLocationAfterEndOfBufferUsingStrlen.ql +++ b/cpp/ql/src/experimental/Security/CWE/CWE-788/AccessOfMemoryLocationAfterEndOfBufferUsingStrlen.ql @@ -3,7 +3,7 @@ * @description The expression `buffer [strlen (buffer)] = 0` is potentially dangerous, if the variable `buffer` does not have a terminal zero, then access beyond the bounds of the allocated memory is possible, which will lead to undefined behavior. * If terminal zero is present, then the specified expression is meaningless. * @kind problem - * @id cpp/access-memory-location-after-end-buffer + * @id cpp/access-memory-location-after-end-buffer-strlen * @problem.severity warning * @precision medium * @tags correctness diff --git a/cpp/ql/src/experimental/Security/CWE/CWE-788/AccessOfMemoryLocationAfterEndOfBufferUsingStrncat.ql b/cpp/ql/src/experimental/Security/CWE/CWE-788/AccessOfMemoryLocationAfterEndOfBufferUsingStrncat.ql index 5311ffe2708..f68395f29bf 100644 --- a/cpp/ql/src/experimental/Security/CWE/CWE-788/AccessOfMemoryLocationAfterEndOfBufferUsingStrncat.ql +++ b/cpp/ql/src/experimental/Security/CWE/CWE-788/AccessOfMemoryLocationAfterEndOfBufferUsingStrncat.ql @@ -2,7 +2,7 @@ * @name Access Of Memory Location After The End Of A Buffer Using Strncat * @description Calls of the form `strncat(dest, source, sizeof (dest) - strlen (dest))` set the third argument to one more than possible. So when `dest` is full, the expression `sizeof(dest) - strlen (dest)` will be equal to one, and not zero as the programmer might think. Making a call of this type may result in a zero byte being written just outside the `dest` buffer. * @kind problem - * @id cpp/access-memory-location-after-end-buffer + * @id cpp/access-memory-location-after-end-buffer-strncat * @problem.severity warning * @precision medium * @tags correctness @@ -11,54 +11,32 @@ */ import cpp +import semmle.code.cpp.models.implementations.Strcat import semmle.code.cpp.valuenumbering.GlobalValueNumbering /** - * A call to `strncat` of the form `strncat(buff, str, someExpr - strlen(buf))`, for some expression `someExpr` equal to `sizeof(buff)`. + * Holds if `call` is a call to `strncat` such that `sizeArg` and `destArg` are the size and + * destination arguments, respectively. */ -class WrongCallStrncat extends FunctionCall { - Expr leftsomeExpr; - - WrongCallStrncat() { - this.getTarget().hasGlobalOrStdName("strncat") and - // the expression of the first argument in `strncat` and `strnlen` is identical - globalValueNumber(this.getArgument(0)) = - globalValueNumber(this.getArgument(2).(SubExpr).getRightOperand().(StrlenCall).getStringExpr()) and - // using a string constant often speaks of manually calculating the length of the required buffer. - ( - not this.getArgument(1) instanceof StringLiteral and - not this.getArgument(1) instanceof CharLiteral - ) and - // for use in predicates - leftsomeExpr = this.getArgument(2).(SubExpr).getLeftOperand() - } - - /** - * Holds if the left side of the expression `someExpr` equal to `sizeof(buf)`. - */ - predicate isExpressionEqualSizeof() { - // the left side of the expression `someExpr` is `sizeof(buf)`. - globalValueNumber(this.getArgument(0)) = - globalValueNumber(leftsomeExpr.(SizeofExprOperator).getExprOperand()) - or - // value of the left side of the expression `someExpr` equal `sizeof(buf)` value, and `buf` is array. - leftsomeExpr.getValue().toInt() = this.getArgument(0).getType().getSize() - } - - /** - * Holds if the left side of the expression `someExpr` equal to variable containing the length of the memory allocated for the buffer. - */ - predicate isVariableEqualValueSizegBuffer() { - // the left side of expression `someExpr` is the variable that was used in the function of allocating memory for the buffer`. - exists(AllocationExpr alc | - leftsomeExpr.(VariableAccess).getTarget() = - alc.(FunctionCall).getArgument(0).(VariableAccess).getTarget() - ) - } +predicate interestringCallWithArgs(Call call, Expr sizeArg, Expr destArg) { + exists(StrcatFunction strcat | + strcat = call.getTarget() and + sizeArg = call.getArgument(strcat.getParamSize()) and + destArg = call.getArgument(strcat.getParamDest()) + ) } -from WrongCallStrncat sc +from FunctionCall call, Expr sizeArg, Expr destArg, SubExpr sub, int n where - sc.isExpressionEqualSizeof() or - sc.isVariableEqualValueSizegBuffer() -select sc, "if the used buffer is full, writing out of the buffer is possible" + interestringCallWithArgs(call, sizeArg, destArg) and + // The destination buffer is an array of size n + destArg.getUnspecifiedType().(ArrayType).getSize() = n and + // The size argument is equivalent to a subtraction + globalValueNumber(sizeArg).getAnExpr() = sub and + // ... where the left side of the subtraction is the constant n + globalValueNumber(sub.getLeftOperand()).getAnExpr().getValue().toInt() = n and + // ... and the right side of the subtraction is a call to `strlen` where the argument is the + // destination buffer. + globalValueNumber(sub.getRightOperand()).getAnExpr().(StrlenCall).getStringExpr() = + globalValueNumber(destArg).getAnExpr() +select call, "Possible out-of-bounds write due to incorrect size argument." diff --git a/cpp/ql/src/external/tests/DefectFilter.ql b/cpp/ql/src/external/tests/DefectFilter.ql deleted file mode 100644 index 88da84e1a52..00000000000 --- a/cpp/ql/src/external/tests/DefectFilter.ql +++ /dev/null @@ -1,12 +0,0 @@ -/** - * @name Defect filter - * @description Only include results in large files (200) lines of code, and change the message. - * @tags filter - */ - -import cpp -import external.DefectFilter - -from DefectResult res -where res.getFile().getMetrics().getNumberOfLinesOfCode() > 200 -select res, "Large files: " + res.getMessage() diff --git a/cpp/ql/src/external/tests/DefectFromExternalData.ql b/cpp/ql/src/external/tests/DefectFromExternalData.ql deleted file mode 100644 index 276977e35b5..00000000000 --- a/cpp/ql/src/external/tests/DefectFromExternalData.ql +++ /dev/null @@ -1,18 +0,0 @@ -/** - * @name Defect from external data - * @description Insert description here... - * @kind problem - * @problem.severity warning - * @tags external-data - */ - -import cpp -import external.ExternalArtifact - -from ExternalData d, File u -where - d.getQueryPath() = "external-data.ql" and - u.getShortName() = d.getField(0) -select u, - d.getField(5) + ", " + d.getFieldAsDate(1) + ", " + d.getField(2) + ", " + d.getFieldAsFloat(3) + - ", " + d.getFieldAsInt(4) + ": " + d.getNumFields() diff --git a/cpp/ql/src/external/tests/MetricFilter.ql b/cpp/ql/src/external/tests/MetricFilter.ql deleted file mode 100644 index ba2868254ef..00000000000 --- a/cpp/ql/src/external/tests/MetricFilter.ql +++ /dev/null @@ -1,12 +0,0 @@ -/** - * @name Metric filter - * @description Only include results in large files (200) lines of code. - * @tags filter - */ - -import cpp -import external.MetricFilter - -from MetricResult res -where res.getFile().getMetrics().getNumberOfLinesOfCode() > 200 -select res, res.getValue() diff --git a/cpp/ql/src/filters/FilterAutogenerated.ql b/cpp/ql/src/filters/FilterAutogenerated.ql deleted file mode 100644 index 43956b48d05..00000000000 --- a/cpp/ql/src/filters/FilterAutogenerated.ql +++ /dev/null @@ -1,16 +0,0 @@ -/** - * @name Filter: exclude results from files that are autogenerated - * @description Use this filter to return results only if they are - * located in files that are maintained manually. - * @kind problem - * @id cpp/autogenerated-filter - * @tags filter - */ - -import cpp -import semmle.code.cpp.AutogeneratedFile -import external.DefectFilter - -from DefectResult res -where not res.getFile() instanceof AutogeneratedFile -select res, res.getMessage() diff --git a/cpp/ql/src/filters/FilterAutogeneratedForMetric.ql b/cpp/ql/src/filters/FilterAutogeneratedForMetric.ql deleted file mode 100644 index 6cc6833f7f8..00000000000 --- a/cpp/ql/src/filters/FilterAutogeneratedForMetric.ql +++ /dev/null @@ -1,16 +0,0 @@ -/** - * @name Metric filter: exclude results from files that are autogenerated - * @description Use this filter to return results only if they are - * located in files that are maintained manually. - * @kind treemap - * @id cpp/autogenerated-for-metric-filter - * @tags filter - */ - -import cpp -import semmle.code.cpp.AutogeneratedFile -import external.MetricFilter - -from MetricResult res -where not res.getFile() instanceof AutogeneratedFile -select res, res.getValue() diff --git a/cpp/ql/src/filters/FromSource.ql b/cpp/ql/src/filters/FromSource.ql deleted file mode 100644 index 459ca94d3c6..00000000000 --- a/cpp/ql/src/filters/FromSource.ql +++ /dev/null @@ -1,16 +0,0 @@ -/** - * @name Filter: exclude results from files for which we do not have - * source code - * @description Use this filter to return results only if they are - * located in files for which we have source code. - * @kind problem - * @id cpp/from-source-filter - * @tags filter - */ - -import cpp -import external.DefectFilter - -from DefectResult res -where res.getFile().fromSource() -select res, res.getMessage() diff --git a/cpp/ql/src/filters/Macros.ql b/cpp/ql/src/filters/Macros.ql deleted file mode 100644 index b5e9e7ca5bf..00000000000 --- a/cpp/ql/src/filters/Macros.ql +++ /dev/null @@ -1,36 +0,0 @@ -/** - * @name Filter: exclude results on lines covered by a macro expansion - * @description Use this filter to return results only when there is no - * macro expansion whose location spans all the lines of - * the result's location. - * @kind problem - * @id cpp/macros-filter - * @tags filter - */ - -import cpp -import external.DefectFilter - -predicate macroLocation(File f, int startLine, int endLine) { - exists(MacroInvocation mi, Location l | - l = mi.getLocation() and - l.getFile() = f and - l.getStartLine() = startLine and - l.getEndLine() = endLine - ) -} - -predicate macroCovering(DefectResult r) { - exists(File f, int macroStart, int macroEnd, int defectStart, int defectEnd | - f = r.getFile() and - defectStart = r.getStartLine() and - defectEnd = r.getEndLine() and - macroLocation(f, macroStart, macroEnd) and - macroStart <= defectStart and - macroEnd >= defectEnd - ) -} - -from DefectResult res -where not macroCovering(res) -select res, res.getMessage() diff --git a/cpp/ql/src/jsf/4.10 Classes/AV Rule 79.ql b/cpp/ql/src/jsf/4.10 Classes/AV Rule 79.ql index d582cfa4224..3ae7bc65b45 100644 --- a/cpp/ql/src/jsf/4.10 Classes/AV Rule 79.ql +++ b/cpp/ql/src/jsf/4.10 Classes/AV Rule 79.ql @@ -91,16 +91,17 @@ private predicate exprReleases(Expr e, Expr released, string kind) { // `e` is a call to a release function and `released` is the released argument releaseExpr(e, released, kind) or - exists(Function f, int arg | + exists(int arg, VariableAccess access, Function f | // `e` is a call to a function that releases one of it's parameters, // and `released` is the corresponding argument ( e.(FunctionCall).getTarget() = f or e.(FunctionCall).getTarget().(MemberFunction).getAnOverridingFunction+() = f ) and + access = f.getParameter(arg).getAnAccess() and e.(FunctionCall).getArgument(arg) = released and exprReleases(_, - exprOrDereference(globalValueNumber(f.getParameter(arg).getAnAccess()).getAnExpr()), kind) + pragma[only_bind_into](exprOrDereference(globalValueNumber(access).getAnExpr())), kind) ) or exists(Function f, ThisExpr innerThis | @@ -112,7 +113,7 @@ private predicate exprReleases(Expr e, Expr released, string kind) { ) and e.(FunctionCall).getQualifier() = exprOrDereference(released) and innerThis.getEnclosingFunction() = f and - exprReleases(_, globalValueNumber(innerThis).getAnExpr(), kind) + exprReleases(_, pragma[only_bind_into](globalValueNumber(innerThis).getAnExpr()), kind) ) } diff --git a/cpp/ql/src/semmle/code/cpp/Diagnostics.qll b/cpp/ql/src/semmle/code/cpp/Diagnostics.qll index 79074fa8657..9ad38d4e4be 100644 --- a/cpp/ql/src/semmle/code/cpp/Diagnostics.qll +++ b/cpp/ql/src/semmle/code/cpp/Diagnostics.qll @@ -6,6 +6,9 @@ import semmle.code.cpp.Location /** A compiler-generated error, warning or remark. */ class Diagnostic extends Locatable, @diagnostic { + /** Gets the compilation that generated this diagnostic. */ + Compilation getCompilation() { diagnostic_for(underlyingElement(this), result, _, _) } + /** * Gets the severity of the message, on a range from 1 to 5: 1=remark, * 2=warning, 3=discretionary error, 4=error, 5=catastrophic error. diff --git a/cpp/ql/src/semmle/code/cpp/Location.qll b/cpp/ql/src/semmle/code/cpp/Location.qll index dc37d4009c0..8d3653ea1c0 100644 --- a/cpp/ql/src/semmle/code/cpp/Location.qll +++ b/cpp/ql/src/semmle/code/cpp/Location.qll @@ -72,6 +72,7 @@ class Location extends @location { } /** Holds if `this` comes on a line strictly before `l`. */ + pragma[inline] predicate isBefore(Location l) { this.getFile() = l.getFile() and this.getEndLine() < l.getStartLine() } diff --git a/cpp/ql/src/semmle/code/cpp/dataflow/internal/AddressFlow.qll b/cpp/ql/src/semmle/code/cpp/dataflow/internal/AddressFlow.qll index 7024f9d8598..f6072763e1a 100644 --- a/cpp/ql/src/semmle/code/cpp/dataflow/internal/AddressFlow.qll +++ b/cpp/ql/src/semmle/code/cpp/dataflow/internal/AddressFlow.qll @@ -15,6 +15,7 @@ */ private import cpp +private import semmle.code.cpp.models.interfaces.PointerWrapper /** * Holds if `f` is an instantiation of the `std::move` or `std::forward` @@ -94,6 +95,12 @@ private predicate pointerToPointerStep(Expr pointerIn, Expr pointerOut) { private predicate lvalueToReferenceStep(Expr lvalueIn, Expr referenceOut) { lvalueIn.getConversion() = referenceOut.(ReferenceToExpr) + or + exists(PointerWrapper wrapper, Call call | call = referenceOut | + referenceOut.getUnspecifiedType() instanceof ReferenceType and + call = wrapper.getAnUnwrapperFunction().getACallToThisFunction() and + lvalueIn = call.getQualifier().getFullyConverted() + ) } private predicate referenceToLvalueStep(Expr referenceIn, Expr lvalueOut) { @@ -106,6 +113,13 @@ private predicate referenceToPointerStep(Expr referenceIn, Expr pointerOut) { stdAddressOf(call.getTarget()) and referenceIn = call.getArgument(0).getFullyConverted() ) + or + exists(CopyConstructor copy, Call call | call = pointerOut | + copy.getDeclaringType() instanceof PointerWrapper and + call.getTarget() = copy and + // The 0'th argument is the value being copied. + referenceIn = call.getArgument(0).getFullyConverted() + ) } private predicate referenceToReferenceStep(Expr referenceIn, Expr referenceOut) { @@ -190,6 +204,19 @@ private predicate pointerToUpdate(Expr pointer, Expr outer, ControlFlowNode node // See the `lvalueToUpdate` case for an explanation of this conjunct. call.getType().isDeeplyConstBelow() ) + or + // Pointer wrappers behave as raw pointers for dataflow purposes. + outer = call.getAnArgument().getFullyConverted() and + exists(PointerWrapper wrapper | wrapper = outer.getType().stripTopLevelSpecifiers() | + not wrapper.pointsToConst() + ) + or + outer = call.getQualifier().getFullyConverted() and + outer.getUnspecifiedType() instanceof PointerWrapper and + not ( + call.getTarget().hasSpecifier("const") and + call.getType().isDeeplyConstBelow() + ) ) or exists(PointerFieldAccess fa | @@ -218,7 +245,9 @@ private predicate referenceToUpdate(Expr reference, Expr outer, ControlFlowNode not stdIdentityFunction(call.getTarget()) and not stdAddressOf(call.getTarget()) and exists(ReferenceType rt | rt = outer.getType().stripTopLevelSpecifiers() | - not rt.getBaseType().isConst() + not rt.getBaseType().isConst() or + rt.getBaseType().getUnspecifiedType() = + any(PointerWrapper wrapper | not wrapper.pointsToConst()) ) ) and reference = outer diff --git a/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl.qll b/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl.qll index 8b446d28b86..9498e51e7e6 100644 --- a/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl.qll +++ b/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl.qll @@ -2133,11 +2133,8 @@ private module Stage4 { bindingset[node, cc, config] private LocalCc getLocalCc(Node node, Cc cc, Configuration config) { - exists(Cc cc0 | - cc = pragma[only_bind_into](cc0) and - localFlowEntry(node, config) and - result = getLocalCallContext(cc0, getNodeEnclosingCallable(node)) - ) + localFlowEntry(node, config) and + result = getLocalCallContext(pragma[only_bind_out](cc), getNodeEnclosingCallable(node)) } private predicate localStep( @@ -3132,7 +3129,7 @@ private predicate pathStep(PathNodeMid mid, Node node, CallContext cc, SummaryCt conf = mid.getConfiguration() and cc = mid.getCallContext() and sc = mid.getSummaryCtx() and - localCC = getLocalCallContext(cc, getNodeEnclosingCallable(midnode)) and + localCC = getLocalCallContext(pragma[only_bind_out](cc), getNodeEnclosingCallable(midnode)) and ap0 = mid.getAp() | localFlowBigStep(midnode, node, true, _, conf, localCC) and diff --git a/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl2.qll b/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl2.qll index 8b446d28b86..9498e51e7e6 100644 --- a/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl2.qll +++ b/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl2.qll @@ -2133,11 +2133,8 @@ private module Stage4 { bindingset[node, cc, config] private LocalCc getLocalCc(Node node, Cc cc, Configuration config) { - exists(Cc cc0 | - cc = pragma[only_bind_into](cc0) and - localFlowEntry(node, config) and - result = getLocalCallContext(cc0, getNodeEnclosingCallable(node)) - ) + localFlowEntry(node, config) and + result = getLocalCallContext(pragma[only_bind_out](cc), getNodeEnclosingCallable(node)) } private predicate localStep( @@ -3132,7 +3129,7 @@ private predicate pathStep(PathNodeMid mid, Node node, CallContext cc, SummaryCt conf = mid.getConfiguration() and cc = mid.getCallContext() and sc = mid.getSummaryCtx() and - localCC = getLocalCallContext(cc, getNodeEnclosingCallable(midnode)) and + localCC = getLocalCallContext(pragma[only_bind_out](cc), getNodeEnclosingCallable(midnode)) and ap0 = mid.getAp() | localFlowBigStep(midnode, node, true, _, conf, localCC) and diff --git a/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl3.qll b/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl3.qll index 8b446d28b86..9498e51e7e6 100644 --- a/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl3.qll +++ b/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl3.qll @@ -2133,11 +2133,8 @@ private module Stage4 { bindingset[node, cc, config] private LocalCc getLocalCc(Node node, Cc cc, Configuration config) { - exists(Cc cc0 | - cc = pragma[only_bind_into](cc0) and - localFlowEntry(node, config) and - result = getLocalCallContext(cc0, getNodeEnclosingCallable(node)) - ) + localFlowEntry(node, config) and + result = getLocalCallContext(pragma[only_bind_out](cc), getNodeEnclosingCallable(node)) } private predicate localStep( @@ -3132,7 +3129,7 @@ private predicate pathStep(PathNodeMid mid, Node node, CallContext cc, SummaryCt conf = mid.getConfiguration() and cc = mid.getCallContext() and sc = mid.getSummaryCtx() and - localCC = getLocalCallContext(cc, getNodeEnclosingCallable(midnode)) and + localCC = getLocalCallContext(pragma[only_bind_out](cc), getNodeEnclosingCallable(midnode)) and ap0 = mid.getAp() | localFlowBigStep(midnode, node, true, _, conf, localCC) and diff --git a/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl4.qll b/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl4.qll index 8b446d28b86..9498e51e7e6 100644 --- a/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl4.qll +++ b/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl4.qll @@ -2133,11 +2133,8 @@ private module Stage4 { bindingset[node, cc, config] private LocalCc getLocalCc(Node node, Cc cc, Configuration config) { - exists(Cc cc0 | - cc = pragma[only_bind_into](cc0) and - localFlowEntry(node, config) and - result = getLocalCallContext(cc0, getNodeEnclosingCallable(node)) - ) + localFlowEntry(node, config) and + result = getLocalCallContext(pragma[only_bind_out](cc), getNodeEnclosingCallable(node)) } private predicate localStep( @@ -3132,7 +3129,7 @@ private predicate pathStep(PathNodeMid mid, Node node, CallContext cc, SummaryCt conf = mid.getConfiguration() and cc = mid.getCallContext() and sc = mid.getSummaryCtx() and - localCC = getLocalCallContext(cc, getNodeEnclosingCallable(midnode)) and + localCC = getLocalCallContext(pragma[only_bind_out](cc), getNodeEnclosingCallable(midnode)) and ap0 = mid.getAp() | localFlowBigStep(midnode, node, true, _, conf, localCC) and diff --git a/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImplCommon.qll b/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImplCommon.qll index 1319f972037..a51c20c2288 100644 --- a/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImplCommon.qll +++ b/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImplCommon.qll @@ -26,15 +26,243 @@ predicate accessPathCostLimits(int apLimit, int tupleLimit) { tupleLimit = 1000 } +/** + * Provides a simple data-flow analysis for resolving lambda calls. The analysis + * currently excludes read-steps, store-steps, and flow-through. + * + * The analysis uses non-linear recursion: When computing a flow path in or out + * of a call, we use the results of the analysis recursively to resolve lamba + * calls. For this reason, we cannot reuse the code from `DataFlowImpl.qll` directly. + */ +private module LambdaFlow { + private predicate viableParamNonLambda(DataFlowCall call, int i, ParameterNode p) { + p.isParameterOf(viableCallable(call), i) + } + + private predicate viableParamLambda(DataFlowCall call, int i, ParameterNode p) { + p.isParameterOf(viableCallableLambda(call, _), i) + } + + private predicate viableParamArgNonLambda(DataFlowCall call, ParameterNode p, ArgumentNode arg) { + exists(int i | + viableParamNonLambda(call, i, p) and + arg.argumentOf(call, i) + ) + } + + private predicate viableParamArgLambda(DataFlowCall call, ParameterNode p, ArgumentNode arg) { + exists(int i | + viableParamLambda(call, i, p) and + arg.argumentOf(call, i) + ) + } + + private newtype TReturnPositionSimple = + TReturnPositionSimple0(DataFlowCallable c, ReturnKind kind) { + exists(ReturnNode ret | + c = getNodeEnclosingCallable(ret) and + kind = ret.getKind() + ) + } + + pragma[noinline] + private TReturnPositionSimple getReturnPositionSimple(ReturnNode ret, ReturnKind kind) { + result = TReturnPositionSimple0(getNodeEnclosingCallable(ret), kind) + } + + pragma[nomagic] + private TReturnPositionSimple viableReturnPosNonLambda(DataFlowCall call, ReturnKind kind) { + result = TReturnPositionSimple0(viableCallable(call), kind) + } + + pragma[nomagic] + private TReturnPositionSimple viableReturnPosLambda( + DataFlowCall call, DataFlowCallOption lastCall, ReturnKind kind + ) { + result = TReturnPositionSimple0(viableCallableLambda(call, lastCall), kind) + } + + private predicate viableReturnPosOutNonLambda( + DataFlowCall call, TReturnPositionSimple pos, OutNode out + ) { + exists(ReturnKind kind | + pos = viableReturnPosNonLambda(call, kind) and + out = getAnOutNode(call, kind) + ) + } + + private predicate viableReturnPosOutLambda( + DataFlowCall call, DataFlowCallOption lastCall, TReturnPositionSimple pos, OutNode out + ) { + exists(ReturnKind kind | + pos = viableReturnPosLambda(call, lastCall, kind) and + out = getAnOutNode(call, kind) + ) + } + + /** + * Holds if data can flow (inter-procedurally) from `node` (of type `t`) to + * the lambda call `lambdaCall`. + * + * The parameter `toReturn` indicates whether the path from `node` to + * `lambdaCall` goes through a return, and `toJump` whether the path goes + * through a jump step. + * + * The call context `lastCall` records the last call on the path from `node` + * to `lambdaCall`, if any. That is, `lastCall` is able to target the enclosing + * callable of `lambdaCall`. + */ + pragma[nomagic] + predicate revLambdaFlow( + DataFlowCall lambdaCall, LambdaCallKind kind, Node node, DataFlowType t, boolean toReturn, + boolean toJump, DataFlowCallOption lastCall + ) { + revLambdaFlow0(lambdaCall, kind, node, t, toReturn, toJump, lastCall) and + if node instanceof CastNode or node instanceof ArgumentNode or node instanceof ReturnNode + then compatibleTypes(t, getNodeType(node)) + else any() + } + + pragma[nomagic] + predicate revLambdaFlow0( + DataFlowCall lambdaCall, LambdaCallKind kind, Node node, DataFlowType t, boolean toReturn, + boolean toJump, DataFlowCallOption lastCall + ) { + lambdaCall(lambdaCall, kind, node) and + t = getNodeType(node) and + toReturn = false and + toJump = false and + lastCall = TDataFlowCallNone() + or + // local flow + exists(Node mid, DataFlowType t0 | + revLambdaFlow(lambdaCall, kind, mid, t0, toReturn, toJump, lastCall) + | + simpleLocalFlowStep(node, mid) and + t = t0 + or + exists(boolean preservesValue | + additionalLambdaFlowStep(node, mid, preservesValue) and + getNodeEnclosingCallable(node) = getNodeEnclosingCallable(mid) + | + preservesValue = false and + t = getNodeType(node) + or + preservesValue = true and + t = t0 + ) + ) + or + // jump step + exists(Node mid, DataFlowType t0 | + revLambdaFlow(lambdaCall, kind, mid, t0, _, _, _) and + toReturn = false and + toJump = true and + lastCall = TDataFlowCallNone() + | + jumpStep(node, mid) and + t = t0 + or + exists(boolean preservesValue | + additionalLambdaFlowStep(node, mid, preservesValue) and + getNodeEnclosingCallable(node) != getNodeEnclosingCallable(mid) + | + preservesValue = false and + t = getNodeType(node) + or + preservesValue = true and + t = t0 + ) + ) + or + // flow into a callable + exists(ParameterNode p, DataFlowCallOption lastCall0, DataFlowCall call | + revLambdaFlowIn(lambdaCall, kind, p, t, toJump, lastCall0) and + ( + if lastCall0 = TDataFlowCallNone() and toJump = false + then lastCall = TDataFlowCallSome(call) + else lastCall = lastCall0 + ) and + toReturn = false + | + viableParamArgNonLambda(call, p, node) + or + viableParamArgLambda(call, p, node) // non-linear recursion + ) + or + // flow out of a callable + exists(TReturnPositionSimple pos | + revLambdaFlowOut(lambdaCall, kind, pos, t, toJump, lastCall) and + getReturnPositionSimple(node, node.(ReturnNode).getKind()) = pos and + toReturn = true + ) + } + + pragma[nomagic] + predicate revLambdaFlowOutLambdaCall( + DataFlowCall lambdaCall, LambdaCallKind kind, OutNode out, DataFlowType t, boolean toJump, + DataFlowCall call, DataFlowCallOption lastCall + ) { + revLambdaFlow(lambdaCall, kind, out, t, _, toJump, lastCall) and + exists(ReturnKindExt rk | + out = rk.getAnOutNode(call) and + lambdaCall(call, _, _) + ) + } + + pragma[nomagic] + predicate revLambdaFlowOut( + DataFlowCall lambdaCall, LambdaCallKind kind, TReturnPositionSimple pos, DataFlowType t, + boolean toJump, DataFlowCallOption lastCall + ) { + exists(DataFlowCall call, OutNode out | + revLambdaFlow(lambdaCall, kind, out, t, _, toJump, lastCall) and + viableReturnPosOutNonLambda(call, pos, out) + or + // non-linear recursion + revLambdaFlowOutLambdaCall(lambdaCall, kind, out, t, toJump, call, lastCall) and + viableReturnPosOutLambda(call, _, pos, out) + ) + } + + pragma[nomagic] + predicate revLambdaFlowIn( + DataFlowCall lambdaCall, LambdaCallKind kind, ParameterNode p, DataFlowType t, boolean toJump, + DataFlowCallOption lastCall + ) { + revLambdaFlow(lambdaCall, kind, p, t, false, toJump, lastCall) + } +} + +private DataFlowCallable viableCallableExt(DataFlowCall call) { + result = viableCallable(call) + or + result = viableCallableLambda(call, _) +} + cached private module Cached { + /** + * Gets a viable target for the lambda call `call`. + * + * `lastCall` records the call required to reach `call` in order for the result + * to be a viable target, if any. + */ + cached + DataFlowCallable viableCallableLambda(DataFlowCall call, DataFlowCallOption lastCall) { + exists(Node creation, LambdaCallKind kind | + LambdaFlow::revLambdaFlow(call, kind, creation, _, _, _, lastCall) and + lambdaCreation(creation, kind, result) + ) + } + /** * Holds if `p` is the `i`th parameter of a viable dispatch target of `call`. * The instance parameter is considered to have index `-1`. */ pragma[nomagic] private predicate viableParam(DataFlowCall call, int i, ParameterNode p) { - p.isParameterOf(viableCallable(call), i) + p.isParameterOf(viableCallableExt(call), i) } /** @@ -52,7 +280,7 @@ private module Cached { pragma[nomagic] private ReturnPosition viableReturnPos(DataFlowCall call, ReturnKindExt kind) { - viableCallable(call) = result.getCallable() and + viableCallableExt(call) = result.getCallable() and kind = result.getKind() } @@ -317,6 +545,35 @@ private module Cached { cached private module DispatchWithCallContext { + /** + * Holds if the set of viable implementations that can be called by `call` + * might be improved by knowing the call context. + */ + pragma[nomagic] + private predicate mayBenefitFromCallContextExt(DataFlowCall call, DataFlowCallable callable) { + mayBenefitFromCallContext(call, callable) + or + callable = call.getEnclosingCallable() and + exists(viableCallableLambda(call, TDataFlowCallSome(_))) + } + + /** + * Gets a viable dispatch target of `call` in the context `ctx`. This is + * restricted to those `call`s for which a context might make a difference. + */ + pragma[nomagic] + private DataFlowCallable viableImplInCallContextExt(DataFlowCall call, DataFlowCall ctx) { + result = viableImplInCallContext(call, ctx) + or + result = viableCallableLambda(call, TDataFlowCallSome(ctx)) + or + exists(DataFlowCallable enclosing | + mayBenefitFromCallContextExt(call, enclosing) and + enclosing = viableCallableExt(ctx) and + result = viableCallableLambda(call, TDataFlowCallNone()) + ) + } + /** * Holds if the call context `ctx` reduces the set of viable run-time * dispatch targets of call `call` in `c`. @@ -324,10 +581,10 @@ private module Cached { cached predicate reducedViableImplInCallContext(DataFlowCall call, DataFlowCallable c, DataFlowCall ctx) { exists(int tgts, int ctxtgts | - mayBenefitFromCallContext(call, c) and - c = viableCallable(ctx) and - ctxtgts = count(viableImplInCallContext(call, ctx)) and - tgts = strictcount(viableCallable(call)) and + mayBenefitFromCallContextExt(call, c) and + c = viableCallableExt(ctx) and + ctxtgts = count(viableImplInCallContextExt(call, ctx)) and + tgts = strictcount(viableCallableExt(call)) and ctxtgts < tgts ) } @@ -339,7 +596,7 @@ private module Cached { */ cached DataFlowCallable prunedViableImplInCallContext(DataFlowCall call, DataFlowCall ctx) { - result = viableImplInCallContext(call, ctx) and + result = viableImplInCallContextExt(call, ctx) and reducedViableImplInCallContext(call, _, ctx) } @@ -351,10 +608,10 @@ private module Cached { cached predicate reducedViableImplInReturn(DataFlowCallable c, DataFlowCall call) { exists(int tgts, int ctxtgts | - mayBenefitFromCallContext(call, _) and - c = viableCallable(call) and - ctxtgts = count(DataFlowCall ctx | c = viableImplInCallContext(call, ctx)) and - tgts = strictcount(DataFlowCall ctx | viableCallable(ctx) = call.getEnclosingCallable()) and + mayBenefitFromCallContextExt(call, _) and + c = viableCallableExt(call) and + ctxtgts = count(DataFlowCall ctx | c = viableImplInCallContextExt(call, ctx)) and + tgts = strictcount(DataFlowCall ctx | viableCallableExt(ctx) = call.getEnclosingCallable()) and ctxtgts < tgts ) } @@ -367,7 +624,7 @@ private module Cached { */ cached DataFlowCallable prunedViableImplInCallContextReverse(DataFlowCall call, DataFlowCall ctx) { - result = viableImplInCallContext(call, ctx) and + result = viableImplInCallContextExt(call, ctx) and reducedViableImplInReturn(result, call) } } @@ -481,6 +738,11 @@ private module Cached { TBooleanNone() or TBooleanSome(boolean b) { b = true or b = false } + cached + newtype TDataFlowCallOption = + TDataFlowCallNone() or + TDataFlowCallSome(DataFlowCall call) + cached newtype TTypedContent = MkTypedContent(Content c, DataFlowType t) { store(_, c, _, _, t) } @@ -777,7 +1039,7 @@ ReturnPosition getReturnPosition(ReturnNodeExt ret) { bindingset[cc, callable] predicate resolveReturn(CallContext cc, DataFlowCallable callable, DataFlowCall call) { - cc instanceof CallContextAny and callable = viableCallable(call) + cc instanceof CallContextAny and callable = viableCallableExt(call) or exists(DataFlowCallable c0, DataFlowCall call0 | call0.getEnclosingCallable() = callable and @@ -791,14 +1053,14 @@ DataFlowCallable resolveCall(DataFlowCall call, CallContext cc) { exists(DataFlowCall ctx | cc = TSpecificCall(ctx) | if reducedViableImplInCallContext(call, _, ctx) then result = prunedViableImplInCallContext(call, ctx) - else result = viableCallable(call) + else result = viableCallableExt(call) ) or - result = viableCallable(call) and cc instanceof CallContextSomeCall + result = viableCallableExt(call) and cc instanceof CallContextSomeCall or - result = viableCallable(call) and cc instanceof CallContextAny + result = viableCallableExt(call) and cc instanceof CallContextAny or - result = viableCallable(call) and cc instanceof CallContextReturn + result = viableCallableExt(call) and cc instanceof CallContextReturn } predicate read = readStep/3; @@ -812,6 +1074,19 @@ class BooleanOption extends TBooleanOption { } } +/** An optional `DataFlowCall`. */ +class DataFlowCallOption extends TDataFlowCallOption { + string toString() { + this = TDataFlowCallNone() and + result = "(none)" + or + exists(DataFlowCall call | + this = TDataFlowCallSome(call) and + result = call.toString() + ) + } +} + /** Content tagged with the type of a containing object. */ class TypedContent extends MkTypedContent { private Content c; diff --git a/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImplLocal.qll b/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImplLocal.qll index 8b446d28b86..9498e51e7e6 100644 --- a/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImplLocal.qll +++ b/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImplLocal.qll @@ -2133,11 +2133,8 @@ private module Stage4 { bindingset[node, cc, config] private LocalCc getLocalCc(Node node, Cc cc, Configuration config) { - exists(Cc cc0 | - cc = pragma[only_bind_into](cc0) and - localFlowEntry(node, config) and - result = getLocalCallContext(cc0, getNodeEnclosingCallable(node)) - ) + localFlowEntry(node, config) and + result = getLocalCallContext(pragma[only_bind_out](cc), getNodeEnclosingCallable(node)) } private predicate localStep( @@ -3132,7 +3129,7 @@ private predicate pathStep(PathNodeMid mid, Node node, CallContext cc, SummaryCt conf = mid.getConfiguration() and cc = mid.getCallContext() and sc = mid.getSummaryCtx() and - localCC = getLocalCallContext(cc, getNodeEnclosingCallable(midnode)) and + localCC = getLocalCallContext(pragma[only_bind_out](cc), getNodeEnclosingCallable(midnode)) and ap0 = mid.getAp() | localFlowBigStep(midnode, node, true, _, conf, localCC) and diff --git a/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowPrivate.qll b/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowPrivate.qll index da20528760f..835e6c46451 100644 --- a/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowPrivate.qll +++ b/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowPrivate.qll @@ -312,3 +312,14 @@ predicate isImmutableOrUnobservable(Node n) { /** Holds if `n` should be hidden from path explanations. */ predicate nodeIsHidden(Node n) { none() } + +class LambdaCallKind = Unit; + +/** Holds if `creation` is an expression that creates a lambda of kind `kind` for `c`. */ +predicate lambdaCreation(Node creation, LambdaCallKind kind, DataFlowCallable c) { none() } + +/** Holds if `call` is a lambda call of kind `kind` where `receiver` is the lambda expression. */ +predicate lambdaCall(DataFlowCall call, LambdaCallKind kind, Node receiver) { none() } + +/** Extra data-flow steps needed for lamba flow analysis. */ +predicate additionalLambdaFlowStep(Node nodeFrom, Node nodeTo, boolean preservesValue) { none() } diff --git a/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowUtil.qll b/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowUtil.qll index 0a6d459ec79..690f24fc59a 100644 --- a/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowUtil.qll +++ b/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowUtil.qll @@ -46,7 +46,7 @@ class Node extends TNode { /** * INTERNAL: Do not use. Alternative name for `getFunction`. */ - final Function getEnclosingCallable() { result = unique(Function f | f = this.getFunction() | f) } + final Function getEnclosingCallable() { result = this.getFunction() } /** Gets the type of this node. */ Type getType() { none() } // overridden in subclasses @@ -324,7 +324,7 @@ private class VariablePartialDefinitionNode extends PartialDefinitionNode { * A synthetic data flow node used for flow into a collection when an iterator * write occurs in a callee. */ -class IteratorPartialDefinitionNode extends PartialDefinitionNode { +private class IteratorPartialDefinitionNode extends PartialDefinitionNode { override IteratorPartialDefinition pd; override Node getPreUpdateNode() { pd.definesExpressions(_, result.asExpr()) } @@ -715,6 +715,7 @@ private predicate exprToDefinitionByReferenceStep(Expr exprIn, Expr argOut) { } private module FieldFlow { + private import DataFlowImplCommon private import DataFlowImplLocal private import DataFlowPrivate @@ -747,7 +748,7 @@ private module FieldFlow { exists(FieldConfiguration cfg | cfg.hasFlow(node1, node2)) and // This configuration should not be able to cross function boundaries, but // we double-check here just to be sure. - node1.getEnclosingCallable() = node2.getEnclosingCallable() + getNodeEnclosingCallable(node1) = getNodeEnclosingCallable(node2) } } diff --git a/cpp/ql/src/semmle/code/cpp/dataflow/internal/FlowVar.qll b/cpp/ql/src/semmle/code/cpp/dataflow/internal/FlowVar.qll index f3aa94a7992..e3f8b6f68fb 100644 --- a/cpp/ql/src/semmle/code/cpp/dataflow/internal/FlowVar.qll +++ b/cpp/ql/src/semmle/code/cpp/dataflow/internal/FlowVar.qll @@ -7,6 +7,7 @@ private import semmle.code.cpp.controlflow.SSA private import semmle.code.cpp.dataflow.internal.SubBasicBlocks private import semmle.code.cpp.dataflow.internal.AddressFlow private import semmle.code.cpp.models.implementations.Iterator +private import semmle.code.cpp.models.interfaces.PointerWrapper /** * A conceptual variable that is assigned only once, like an SSA variable. This @@ -158,18 +159,14 @@ private module PartialDefinitions { Expr innerDefinedExpr; IteratorPartialDefinition() { - exists(Expr convertedInner | - not this instanceof Conversion and - valueToUpdate(convertedInner, this.getFullyConverted(), node) and - innerDefinedExpr = convertedInner.getUnconverted() and - ( - innerDefinedExpr.(Call).getQualifier() = getAnIteratorAccess(collection) - or - innerDefinedExpr.(Call).getQualifier() = collection.getAnAccess() and - collection instanceof IteratorParameter - ) and - innerDefinedExpr.(Call).getTarget() instanceof IteratorPointerDereferenceMemberOperator - ) + innerDefinedExpr = getInnerDefinedExpr(this, node) and + ( + innerDefinedExpr.(Call).getQualifier() = getAnIteratorAccess(collection) + or + innerDefinedExpr.(Call).getQualifier() = collection.getAnAccess() and + collection instanceof IteratorParameter + ) and + innerDefinedExpr.(Call).getTarget() instanceof IteratorPointerDereferenceMemberOperator or // iterators passed by value without a copy constructor exists(Call call | @@ -207,16 +204,18 @@ private module PartialDefinitions { } } + private Expr getInnerDefinedExpr(Expr e, ControlFlowNode node) { + not e instanceof Conversion and + exists(Expr convertedInner | + valueToUpdate(convertedInner, e.getFullyConverted(), node) and + result = convertedInner.getUnconverted() + ) + } + class VariablePartialDefinition extends PartialDefinition { Expr innerDefinedExpr; - VariablePartialDefinition() { - not this instanceof Conversion and - exists(Expr convertedInner | - valueToUpdate(convertedInner, this.getFullyConverted(), node) and - innerDefinedExpr = convertedInner.getUnconverted() - ) - } + VariablePartialDefinition() { innerDefinedExpr = getInnerDefinedExpr(this, node) } deprecated override predicate partiallyDefines(Variable v) { innerDefinedExpr = v.getAnAccess() @@ -296,7 +295,8 @@ module FlowVar_internal { // treating them as immutable, but for data flow it gives better results in // practice to make the variable synonymous with its contents. not v.getUnspecifiedType() instanceof ReferenceType and - not v instanceof IteratorParameter + not v instanceof IteratorParameter and + not v instanceof PointerWrapperParameter } /** @@ -644,10 +644,19 @@ module FlowVar_internal { predicate parameterIsNonConstReference(Parameter p) { exists(ReferenceType refType | refType = p.getUnderlyingType() and - not refType.getBaseType().isConst() + ( + not refType.getBaseType().isConst() + or + // A field of a parameter of type `const std::shared_ptr& p` can still be changed even though + // the base type of the reference is `const`. + refType.getBaseType().getUnspecifiedType() = + any(PointerWrapper wrapper | not wrapper.pointsToConst()) + ) ) or p instanceof IteratorParameter + or + p instanceof PointerWrapperParameter } /** @@ -836,6 +845,10 @@ module FlowVar_internal { IteratorParameter() { this.getUnspecifiedType() instanceof Iterator } } + class PointerWrapperParameter extends Parameter { + PointerWrapperParameter() { this.getUnspecifiedType() instanceof PointerWrapper } + } + /** * Holds if `v` is initialized to have value `assignedExpr`. */ diff --git a/cpp/ql/src/semmle/code/cpp/dataflow/internal/TaintTrackingUtil.qll b/cpp/ql/src/semmle/code/cpp/dataflow/internal/TaintTrackingUtil.qll index 1ef340c4f21..591f461c8eb 100644 --- a/cpp/ql/src/semmle/code/cpp/dataflow/internal/TaintTrackingUtil.qll +++ b/cpp/ql/src/semmle/code/cpp/dataflow/internal/TaintTrackingUtil.qll @@ -11,6 +11,7 @@ private import semmle.code.cpp.models.interfaces.DataFlow private import semmle.code.cpp.models.interfaces.Taint private import semmle.code.cpp.models.interfaces.Iterator +private import semmle.code.cpp.models.interfaces.PointerWrapper private module DataFlow { import semmle.code.cpp.dataflow.internal.DataFlowUtil @@ -141,7 +142,10 @@ private predicate noFlowFromChildExpr(Expr e) { or e instanceof LogicalOrExpr or - e instanceof Call + // Allow taint from `operator*` on smart pointers. + exists(Call call | e = call | + not call.getTarget() = any(PointerWrapper wrapper).getAnUnwrapperFunction() + ) or e instanceof SizeofOperator or diff --git a/cpp/ql/src/semmle/code/cpp/exprs/Call.qll b/cpp/ql/src/semmle/code/cpp/exprs/Call.qll index c57c608b69b..6f6f710ac4b 100644 --- a/cpp/ql/src/semmle/code/cpp/exprs/Call.qll +++ b/cpp/ql/src/semmle/code/cpp/exprs/Call.qll @@ -300,17 +300,25 @@ class FunctionCall extends Call, @funbindexpr { } } +/** A _user-defined_ unary `operator*` function. */ +class OverloadedPointerDereferenceFunction extends Function { + OverloadedPointerDereferenceFunction() { + this.hasName("operator*") and + this.getEffectiveNumberOfParameters() = 1 + } +} + /** * An instance of a _user-defined_ unary `operator*` applied to its argument. * ``` * T1 operator*(const T2 &); * T1 a; T2 b; * a = *b; + * ``` */ class OverloadedPointerDereferenceExpr extends FunctionCall { OverloadedPointerDereferenceExpr() { - getTarget().hasName("operator*") and - getTarget().getEffectiveNumberOfParameters() = 1 + this.getTarget() instanceof OverloadedPointerDereferenceFunction } override string getAPrimaryQlClass() { result = "OverloadedPointerDereferenceExpr" } diff --git a/cpp/ql/src/semmle/code/cpp/ir/dataflow/DefaultTaintTracking.qll b/cpp/ql/src/semmle/code/cpp/ir/dataflow/DefaultTaintTracking.qll index 7ca03067d0a..3092031cbc7 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/dataflow/DefaultTaintTracking.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/dataflow/DefaultTaintTracking.qll @@ -2,13 +2,16 @@ import cpp import semmle.code.cpp.security.Security private import semmle.code.cpp.ir.dataflow.DataFlow private import semmle.code.cpp.ir.dataflow.internal.DataFlowUtil -private import semmle.code.cpp.ir.dataflow.DataFlow2 private import semmle.code.cpp.ir.dataflow.DataFlow3 private import semmle.code.cpp.ir.IR private import semmle.code.cpp.ir.dataflow.internal.DataFlowDispatch as Dispatch private import semmle.code.cpp.controlflow.IRGuards private import semmle.code.cpp.models.interfaces.Taint private import semmle.code.cpp.models.interfaces.DataFlow +private import semmle.code.cpp.ir.dataflow.TaintTracking +private import semmle.code.cpp.ir.dataflow.TaintTracking2 +private import semmle.code.cpp.ir.dataflow.TaintTracking3 +private import semmle.code.cpp.ir.dataflow.internal.ModelUtil /** * A predictable instruction is one where an external user can predict @@ -65,23 +68,19 @@ private DataFlow::Node getNodeForExpr(Expr node) { not argv(node.(VariableAccess).getTarget()) } -private class DefaultTaintTrackingCfg extends DataFlow::Configuration { +private class DefaultTaintTrackingCfg extends TaintTracking::Configuration { DefaultTaintTrackingCfg() { this = "DefaultTaintTrackingCfg" } override predicate isSource(DataFlow::Node source) { source = getNodeForSource(_) } override predicate isSink(DataFlow::Node sink) { exists(adjustedSink(sink)) } - override predicate isAdditionalFlowStep(DataFlow::Node n1, DataFlow::Node n2) { - commonTaintStep(n1, n2) - } + override predicate isSanitizer(DataFlow::Node node) { nodeIsBarrier(node) } - override predicate isBarrier(DataFlow::Node node) { nodeIsBarrier(node) } - - override predicate isBarrierIn(DataFlow::Node node) { nodeIsBarrierIn(node) } + override predicate isSanitizerIn(DataFlow::Node node) { nodeIsBarrierIn(node) } } -private class ToGlobalVarTaintTrackingCfg extends DataFlow::Configuration { +private class ToGlobalVarTaintTrackingCfg extends TaintTracking::Configuration { ToGlobalVarTaintTrackingCfg() { this = "GlobalVarTaintTrackingCfg" } override predicate isSource(DataFlow::Node source) { source = getNodeForSource(_) } @@ -90,20 +89,18 @@ private class ToGlobalVarTaintTrackingCfg extends DataFlow::Configuration { sink.asVariable() instanceof GlobalOrNamespaceVariable } - override predicate isAdditionalFlowStep(DataFlow::Node n1, DataFlow::Node n2) { - commonTaintStep(n1, n2) - or + override predicate isAdditionalTaintStep(DataFlow::Node n1, DataFlow::Node n2) { writesVariable(n1.asInstruction(), n2.asVariable().(GlobalOrNamespaceVariable)) or readsVariable(n2.asInstruction(), n1.asVariable().(GlobalOrNamespaceVariable)) } - override predicate isBarrier(DataFlow::Node node) { nodeIsBarrier(node) } + override predicate isSanitizer(DataFlow::Node node) { nodeIsBarrier(node) } - override predicate isBarrierIn(DataFlow::Node node) { nodeIsBarrierIn(node) } + override predicate isSanitizerIn(DataFlow::Node node) { nodeIsBarrierIn(node) } } -private class FromGlobalVarTaintTrackingCfg extends DataFlow2::Configuration { +private class FromGlobalVarTaintTrackingCfg extends TaintTracking2::Configuration { FromGlobalVarTaintTrackingCfg() { this = "FromGlobalVarTaintTrackingCfg" } override predicate isSource(DataFlow::Node source) { @@ -114,18 +111,16 @@ private class FromGlobalVarTaintTrackingCfg extends DataFlow2::Configuration { override predicate isSink(DataFlow::Node sink) { exists(adjustedSink(sink)) } - override predicate isAdditionalFlowStep(DataFlow::Node n1, DataFlow::Node n2) { - commonTaintStep(n1, n2) - or + override predicate isAdditionalTaintStep(DataFlow::Node n1, DataFlow::Node n2) { // Additional step for flow out of variables. There is no flow _into_ // variables in this configuration, so this step only serves to take flow // out of a variable that's a source. readsVariable(n2.asInstruction(), n1.asVariable()) } - override predicate isBarrier(DataFlow::Node node) { nodeIsBarrier(node) } + override predicate isSanitizer(DataFlow::Node node) { nodeIsBarrier(node) } - override predicate isBarrierIn(DataFlow::Node node) { nodeIsBarrierIn(node) } + override predicate isSanitizerIn(DataFlow::Node node) { nodeIsBarrierIn(node) } } private predicate readsVariable(LoadInstruction load, Variable var) { @@ -202,206 +197,26 @@ private predicate nodeIsBarrierIn(DataFlow::Node node) { // `getNodeForSource`. node = DataFlow::definitionByReferenceNodeFromArgument(source) ) -} - -cached -private predicate commonTaintStep(DataFlow::Node fromNode, DataFlow::Node toNode) { - operandToInstructionTaintStep(fromNode.asOperand(), toNode.asInstruction()) or - instructionToOperandTaintStep(fromNode.asInstruction(), toNode.asOperand()) -} - -private predicate instructionToOperandTaintStep(Instruction fromInstr, Operand toOperand) { - // Propagate flow from the definition of an operand to the operand, even when the overlap is inexact. - // We only do this in certain cases: - // 1. The instruction's result must not be conflated, and - // 2. The instruction's result type is one the types where we expect element-to-object flow. Currently - // this is array types and union types. This matches the other two cases of element-to-object flow in - // `DefaultTaintTracking`. - toOperand.getAnyDef() = fromInstr and - not fromInstr.isResultConflated() and - ( - fromInstr.getResultType() instanceof ArrayType or - fromInstr.getResultType() instanceof Union + // don't use dataflow into binary instructions if both operands are unpredictable + exists(BinaryInstruction iTo | + iTo = node.asInstruction() and + not predictableInstruction(iTo.getLeft()) and + not predictableInstruction(iTo.getRight()) and + // propagate taint from either the pointer or the offset, regardless of predictability + not iTo instanceof PointerArithmeticInstruction ) or - exists(ReadSideEffectInstruction readInstr | - fromInstr = readInstr.getArgumentDef() and - toOperand = readInstr.getSideEffectOperand() - ) -} - -private predicate operandToInstructionTaintStep(Operand fromOperand, Instruction toInstr) { - // Expressions computed from tainted data are also tainted - exists(CallInstruction call, int argIndex | call = toInstr | - isPureFunction(call.getStaticCallTarget().getName()) and - fromOperand = getACallArgumentOrIndirection(call, argIndex) and - forall(Operand argOperand | argOperand = call.getAnArgumentOperand() | - argOperand = getACallArgumentOrIndirection(call, argIndex) or - predictableInstruction(argOperand.getAnyDef()) - ) and - // flow through `strlen` tends to cause dubious results, if the length is - // bounded. - not call.getStaticCallTarget().getName() = "strlen" - ) - or - // Flow from argument to return value - toInstr = - any(CallInstruction call | - exists(int indexIn | - modelTaintToReturnValue(call.getStaticCallTarget(), indexIn) and - fromOperand = getACallArgumentOrIndirection(call, indexIn) and - not predictableOnlyFlow(call.getStaticCallTarget().getName()) - ) - ) - or - // Flow from input argument to output argument - // TODO: This won't work in practice as long as all aliased memory is tracked - // together in a single virtual variable. - // TODO: Will this work on the test for `TaintedPath.ql`, where the output arg - // is a pointer addition expression? - toInstr = - any(WriteSideEffectInstruction outInstr | - exists(CallInstruction call, int indexIn, int indexOut | - modelTaintToParameter(call.getStaticCallTarget(), indexIn, indexOut) and - fromOperand = getACallArgumentOrIndirection(call, indexIn) and - outInstr.getIndex() = indexOut and - outInstr.getPrimaryInstruction() = call - ) - ) - or - // Flow through pointer dereference - toInstr.(LoadInstruction).getSourceAddressOperand() = fromOperand - or - // Flow through partial reads of arrays and unions - toInstr.(LoadInstruction).getSourceValueOperand() = fromOperand and - exists(Instruction fromInstr | fromInstr = fromOperand.getAnyDef() | - not fromInstr.isResultConflated() and - ( - fromInstr.getResultType() instanceof ArrayType or - fromInstr.getResultType() instanceof Union - ) - ) - or - // Unary instructions tend to preserve enough information in practice that we - // want taint to flow through. - // The exception is `FieldAddressInstruction`. Together with the rule for - // `LoadInstruction` above and for `ChiInstruction` below, flow through - // `FieldAddressInstruction` could cause flow into one field to come out an - // unrelated field. This would happen across function boundaries, where the IR - // would not be able to match loads to stores. - toInstr.(UnaryInstruction).getUnaryOperand() = fromOperand and - ( - not toInstr instanceof FieldAddressInstruction - or - toInstr.(FieldAddressInstruction).getField().getDeclaringType() instanceof Union - ) - or - // Flow from an element to an array or union that contains it. - toInstr.(ChiInstruction).getPartialOperand() = fromOperand and - not toInstr.isResultConflated() and - exists(Type t | toInstr.getResultLanguageType().hasType(t, false) | - t instanceof Union - or - t instanceof ArrayType - ) - or - exists(BinaryInstruction bin | - bin = toInstr and - predictableInstruction(toInstr.getAnOperand().getDef()) and - fromOperand = toInstr.getAnOperand() - ) - or - // This is part of the translation of `a[i]`, where we want taint to flow - // from `a`. - toInstr.(PointerAddInstruction).getLeftOperand() = fromOperand - or - // Until we have flow through indirections across calls, we'll take flow out - // of the indirection and into the argument. - // When we get proper flow through indirections across calls, this code can be - // moved to `adjusedSink` or possibly into the `DataFlow::ExprNode` class. - exists(ReadSideEffectInstruction read | - read.getSideEffectOperand() = fromOperand and - read.getArgumentDef() = toInstr - ) - or - // Until we have from through indirections across calls, we'll take flow out - // of the parameter and into its indirection. - // `InitializeIndirectionInstruction` only has a single operand: the address of the - // value whose indirection we are initializing. When initializing an indirection of a parameter `p`, - // the IR looks like this: - // ``` - // m1 = InitializeParameter[p] : &r1 - // r2 = Load[p] : r2, m1 - // m3 = InitializeIndirection[p] : &r2 - // ``` - // So by having flow from `r2` to `m3` we're enabling flow from `m1` to `m3`. This relies on the - // `LoadOperand`'s overlap being exact. - toInstr.(InitializeIndirectionInstruction).getAnOperand() = fromOperand -} - -/** - * Returns the index of the side effect instruction corresponding to the specified function output, - * if one exists. - */ -private int getWriteSideEffectIndex(FunctionOutput output) { - output.isParameterDeref(result) - or - output.isQualifierObject() and result = -1 -} - -/** - * Get an operand that goes into argument `argumentIndex` of `call`. This - * can be either directly or through one pointer indirection. - */ -private Operand getACallArgumentOrIndirection(CallInstruction call, int argumentIndex) { - result = call.getPositionalArgumentOperand(argumentIndex) - or - exists(ReadSideEffectInstruction readSE | - // TODO: why are read side effect operands imprecise? - result = readSE.getSideEffectOperand() and - readSE.getPrimaryInstruction() = call and - readSE.getIndex() = argumentIndex - ) -} - -private predicate modelTaintToParameter(Function f, int parameterIn, int parameterOut) { - exists(FunctionInput modelIn, FunctionOutput modelOut | - ( - f.(DataFlowFunction).hasDataFlow(modelIn, modelOut) - or - f.(TaintFunction).hasTaintFlow(modelIn, modelOut) - ) and - (modelIn.isParameter(parameterIn) or modelIn.isParameterDeref(parameterIn)) and - parameterOut = getWriteSideEffectIndex(modelOut) - ) -} - -private predicate modelTaintToReturnValue(Function f, int parameterIn) { - // Taint flow from parameter to return value - exists(FunctionInput modelIn, FunctionOutput modelOut | - f.(TaintFunction).hasTaintFlow(modelIn, modelOut) and - (modelIn.isParameter(parameterIn) or modelIn.isParameterDeref(parameterIn)) and - (modelOut.isReturnValue() or modelOut.isReturnValueDeref()) - ) - or - // Data flow (not taint flow) to where the return value points. For the time - // being we will conflate pointers and objects in taint tracking. - exists(FunctionInput modelIn, FunctionOutput modelOut | - f.(DataFlowFunction).hasDataFlow(modelIn, modelOut) and - (modelIn.isParameter(parameterIn) or modelIn.isParameterDeref(parameterIn)) and - modelOut.isReturnValueDeref() - ) - or - // Taint flow from one argument to another and data flow from an argument to a - // return value. This happens in functions like `strcat` and `memcpy`. We - // could model this flow in two separate steps, but that would add reverse - // flow from the write side-effect to the call instruction, which may not be - // desirable. - exists(int parameterMid, InParameter modelMid, OutReturnValue returnOut | - modelTaintToParameter(f, parameterIn, parameterMid) and - modelMid.isParameter(parameterMid) and - f.(DataFlowFunction).hasDataFlow(modelMid, returnOut) + // don't use dataflow through calls to pure functions if two or more operands + // are unpredictable + exists(Instruction iFrom1, Instruction iFrom2, CallInstruction iTo | + iTo = node.asInstruction() and + isPureFunction(iTo.getStaticCallTarget().getName()) and + iFrom1 = iTo.getAnArgument() and + iFrom2 = iTo.getAnArgument() and + not predictableInstruction(iFrom1) and + not predictableInstruction(iFrom2) and + iFrom1 != iFrom2 ) } @@ -440,6 +255,14 @@ private Element adjustedSink(DataFlow::Node sink) { or // Taint `e1 += e2`, `e &= e2` and friends when `e1` or `e2` is tainted. result.(AssignOperation).getAnOperand() = sink.asExpr() + or + result = + sink.asOperand() + .(SideEffectOperand) + .getUse() + .(ReadSideEffectInstruction) + .getArgumentDef() + .getUnconvertedResultExpression() } /** @@ -558,7 +381,7 @@ module TaintedWithPath { string toString() { result = "TaintTrackingConfiguration" } } - private class AdjustedConfiguration extends DataFlow3::Configuration { + private class AdjustedConfiguration extends TaintTracking3::Configuration { AdjustedConfiguration() { this = "AdjustedConfiguration" } override predicate isSource(DataFlow::Node source) { @@ -571,21 +394,34 @@ module TaintedWithPath { exists(TaintTrackingConfiguration cfg | cfg.isSink(adjustedSink(sink))) } - override predicate isAdditionalFlowStep(DataFlow::Node n1, DataFlow::Node n2) { - commonTaintStep(n1, n2) - or + override predicate isAdditionalTaintStep(DataFlow::Node n1, DataFlow::Node n2) { + // Steps into and out of global variables exists(TaintTrackingConfiguration cfg | cfg.taintThroughGlobals() | writesVariable(n1.asInstruction(), n2.asVariable().(GlobalOrNamespaceVariable)) or readsVariable(n2.asInstruction(), n1.asVariable().(GlobalOrNamespaceVariable)) ) + or + // Step to return value of a modeled function when an input taints the + // dereference of the return value + exists(CallInstruction call, Function func, FunctionInput modelIn, FunctionOutput modelOut | + n1.asOperand() = callInput(call, modelIn) and + ( + func.(TaintFunction).hasTaintFlow(modelIn, modelOut) + or + func.(DataFlowFunction).hasDataFlow(modelIn, modelOut) + ) and + call.getStaticCallTarget() = func and + modelOut.isReturnValueDeref() and + call = n2.asInstruction() + ) } - override predicate isBarrier(DataFlow::Node node) { + override predicate isSanitizer(DataFlow::Node node) { exists(TaintTrackingConfiguration cfg, Expr e | cfg.isBarrier(e) and node = getNodeForExpr(e)) } - override predicate isBarrierIn(DataFlow::Node node) { nodeIsBarrierIn(node) } + override predicate isSanitizerIn(DataFlow::Node node) { nodeIsBarrierIn(node) } } /* diff --git a/cpp/ql/src/semmle/code/cpp/ir/dataflow/TaintTracking3.qll b/cpp/ql/src/semmle/code/cpp/ir/dataflow/TaintTracking3.qll new file mode 100644 index 00000000000..98e1caebf38 --- /dev/null +++ b/cpp/ql/src/semmle/code/cpp/ir/dataflow/TaintTracking3.qll @@ -0,0 +1,15 @@ +/** + * Provides a `TaintTracking3` module, which is a copy of the `TaintTracking` + * module. Use this class when data-flow configurations or taint-tracking + * configurations must depend on each other. Two classes extending + * `DataFlow::Configuration` should never depend on each other, but one of them + * should instead depend on a `DataFlow2::Configuration`, a + * `DataFlow3::Configuration`, or a `DataFlow4::Configuration`. The + * `TaintTracking::Configuration` class extends `DataFlow::Configuration`, and + * `TaintTracking2::Configuration` extends `DataFlow2::Configuration`. + * + * See `semmle.code.cpp.ir.dataflow.TaintTracking` for the full documentation. + */ +module TaintTracking3 { + import semmle.code.cpp.ir.dataflow.internal.tainttracking3.TaintTrackingImpl +} diff --git a/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl.qll b/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl.qll index 8b446d28b86..9498e51e7e6 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl.qll @@ -2133,11 +2133,8 @@ private module Stage4 { bindingset[node, cc, config] private LocalCc getLocalCc(Node node, Cc cc, Configuration config) { - exists(Cc cc0 | - cc = pragma[only_bind_into](cc0) and - localFlowEntry(node, config) and - result = getLocalCallContext(cc0, getNodeEnclosingCallable(node)) - ) + localFlowEntry(node, config) and + result = getLocalCallContext(pragma[only_bind_out](cc), getNodeEnclosingCallable(node)) } private predicate localStep( @@ -3132,7 +3129,7 @@ private predicate pathStep(PathNodeMid mid, Node node, CallContext cc, SummaryCt conf = mid.getConfiguration() and cc = mid.getCallContext() and sc = mid.getSummaryCtx() and - localCC = getLocalCallContext(cc, getNodeEnclosingCallable(midnode)) and + localCC = getLocalCallContext(pragma[only_bind_out](cc), getNodeEnclosingCallable(midnode)) and ap0 = mid.getAp() | localFlowBigStep(midnode, node, true, _, conf, localCC) and diff --git a/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl2.qll b/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl2.qll index 8b446d28b86..9498e51e7e6 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl2.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl2.qll @@ -2133,11 +2133,8 @@ private module Stage4 { bindingset[node, cc, config] private LocalCc getLocalCc(Node node, Cc cc, Configuration config) { - exists(Cc cc0 | - cc = pragma[only_bind_into](cc0) and - localFlowEntry(node, config) and - result = getLocalCallContext(cc0, getNodeEnclosingCallable(node)) - ) + localFlowEntry(node, config) and + result = getLocalCallContext(pragma[only_bind_out](cc), getNodeEnclosingCallable(node)) } private predicate localStep( @@ -3132,7 +3129,7 @@ private predicate pathStep(PathNodeMid mid, Node node, CallContext cc, SummaryCt conf = mid.getConfiguration() and cc = mid.getCallContext() and sc = mid.getSummaryCtx() and - localCC = getLocalCallContext(cc, getNodeEnclosingCallable(midnode)) and + localCC = getLocalCallContext(pragma[only_bind_out](cc), getNodeEnclosingCallable(midnode)) and ap0 = mid.getAp() | localFlowBigStep(midnode, node, true, _, conf, localCC) and diff --git a/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl3.qll b/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl3.qll index 8b446d28b86..9498e51e7e6 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl3.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl3.qll @@ -2133,11 +2133,8 @@ private module Stage4 { bindingset[node, cc, config] private LocalCc getLocalCc(Node node, Cc cc, Configuration config) { - exists(Cc cc0 | - cc = pragma[only_bind_into](cc0) and - localFlowEntry(node, config) and - result = getLocalCallContext(cc0, getNodeEnclosingCallable(node)) - ) + localFlowEntry(node, config) and + result = getLocalCallContext(pragma[only_bind_out](cc), getNodeEnclosingCallable(node)) } private predicate localStep( @@ -3132,7 +3129,7 @@ private predicate pathStep(PathNodeMid mid, Node node, CallContext cc, SummaryCt conf = mid.getConfiguration() and cc = mid.getCallContext() and sc = mid.getSummaryCtx() and - localCC = getLocalCallContext(cc, getNodeEnclosingCallable(midnode)) and + localCC = getLocalCallContext(pragma[only_bind_out](cc), getNodeEnclosingCallable(midnode)) and ap0 = mid.getAp() | localFlowBigStep(midnode, node, true, _, conf, localCC) and diff --git a/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl4.qll b/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl4.qll index 8b446d28b86..9498e51e7e6 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl4.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl4.qll @@ -2133,11 +2133,8 @@ private module Stage4 { bindingset[node, cc, config] private LocalCc getLocalCc(Node node, Cc cc, Configuration config) { - exists(Cc cc0 | - cc = pragma[only_bind_into](cc0) and - localFlowEntry(node, config) and - result = getLocalCallContext(cc0, getNodeEnclosingCallable(node)) - ) + localFlowEntry(node, config) and + result = getLocalCallContext(pragma[only_bind_out](cc), getNodeEnclosingCallable(node)) } private predicate localStep( @@ -3132,7 +3129,7 @@ private predicate pathStep(PathNodeMid mid, Node node, CallContext cc, SummaryCt conf = mid.getConfiguration() and cc = mid.getCallContext() and sc = mid.getSummaryCtx() and - localCC = getLocalCallContext(cc, getNodeEnclosingCallable(midnode)) and + localCC = getLocalCallContext(pragma[only_bind_out](cc), getNodeEnclosingCallable(midnode)) and ap0 = mid.getAp() | localFlowBigStep(midnode, node, true, _, conf, localCC) and diff --git a/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImplCommon.qll b/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImplCommon.qll index 1319f972037..a51c20c2288 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImplCommon.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImplCommon.qll @@ -26,15 +26,243 @@ predicate accessPathCostLimits(int apLimit, int tupleLimit) { tupleLimit = 1000 } +/** + * Provides a simple data-flow analysis for resolving lambda calls. The analysis + * currently excludes read-steps, store-steps, and flow-through. + * + * The analysis uses non-linear recursion: When computing a flow path in or out + * of a call, we use the results of the analysis recursively to resolve lamba + * calls. For this reason, we cannot reuse the code from `DataFlowImpl.qll` directly. + */ +private module LambdaFlow { + private predicate viableParamNonLambda(DataFlowCall call, int i, ParameterNode p) { + p.isParameterOf(viableCallable(call), i) + } + + private predicate viableParamLambda(DataFlowCall call, int i, ParameterNode p) { + p.isParameterOf(viableCallableLambda(call, _), i) + } + + private predicate viableParamArgNonLambda(DataFlowCall call, ParameterNode p, ArgumentNode arg) { + exists(int i | + viableParamNonLambda(call, i, p) and + arg.argumentOf(call, i) + ) + } + + private predicate viableParamArgLambda(DataFlowCall call, ParameterNode p, ArgumentNode arg) { + exists(int i | + viableParamLambda(call, i, p) and + arg.argumentOf(call, i) + ) + } + + private newtype TReturnPositionSimple = + TReturnPositionSimple0(DataFlowCallable c, ReturnKind kind) { + exists(ReturnNode ret | + c = getNodeEnclosingCallable(ret) and + kind = ret.getKind() + ) + } + + pragma[noinline] + private TReturnPositionSimple getReturnPositionSimple(ReturnNode ret, ReturnKind kind) { + result = TReturnPositionSimple0(getNodeEnclosingCallable(ret), kind) + } + + pragma[nomagic] + private TReturnPositionSimple viableReturnPosNonLambda(DataFlowCall call, ReturnKind kind) { + result = TReturnPositionSimple0(viableCallable(call), kind) + } + + pragma[nomagic] + private TReturnPositionSimple viableReturnPosLambda( + DataFlowCall call, DataFlowCallOption lastCall, ReturnKind kind + ) { + result = TReturnPositionSimple0(viableCallableLambda(call, lastCall), kind) + } + + private predicate viableReturnPosOutNonLambda( + DataFlowCall call, TReturnPositionSimple pos, OutNode out + ) { + exists(ReturnKind kind | + pos = viableReturnPosNonLambda(call, kind) and + out = getAnOutNode(call, kind) + ) + } + + private predicate viableReturnPosOutLambda( + DataFlowCall call, DataFlowCallOption lastCall, TReturnPositionSimple pos, OutNode out + ) { + exists(ReturnKind kind | + pos = viableReturnPosLambda(call, lastCall, kind) and + out = getAnOutNode(call, kind) + ) + } + + /** + * Holds if data can flow (inter-procedurally) from `node` (of type `t`) to + * the lambda call `lambdaCall`. + * + * The parameter `toReturn` indicates whether the path from `node` to + * `lambdaCall` goes through a return, and `toJump` whether the path goes + * through a jump step. + * + * The call context `lastCall` records the last call on the path from `node` + * to `lambdaCall`, if any. That is, `lastCall` is able to target the enclosing + * callable of `lambdaCall`. + */ + pragma[nomagic] + predicate revLambdaFlow( + DataFlowCall lambdaCall, LambdaCallKind kind, Node node, DataFlowType t, boolean toReturn, + boolean toJump, DataFlowCallOption lastCall + ) { + revLambdaFlow0(lambdaCall, kind, node, t, toReturn, toJump, lastCall) and + if node instanceof CastNode or node instanceof ArgumentNode or node instanceof ReturnNode + then compatibleTypes(t, getNodeType(node)) + else any() + } + + pragma[nomagic] + predicate revLambdaFlow0( + DataFlowCall lambdaCall, LambdaCallKind kind, Node node, DataFlowType t, boolean toReturn, + boolean toJump, DataFlowCallOption lastCall + ) { + lambdaCall(lambdaCall, kind, node) and + t = getNodeType(node) and + toReturn = false and + toJump = false and + lastCall = TDataFlowCallNone() + or + // local flow + exists(Node mid, DataFlowType t0 | + revLambdaFlow(lambdaCall, kind, mid, t0, toReturn, toJump, lastCall) + | + simpleLocalFlowStep(node, mid) and + t = t0 + or + exists(boolean preservesValue | + additionalLambdaFlowStep(node, mid, preservesValue) and + getNodeEnclosingCallable(node) = getNodeEnclosingCallable(mid) + | + preservesValue = false and + t = getNodeType(node) + or + preservesValue = true and + t = t0 + ) + ) + or + // jump step + exists(Node mid, DataFlowType t0 | + revLambdaFlow(lambdaCall, kind, mid, t0, _, _, _) and + toReturn = false and + toJump = true and + lastCall = TDataFlowCallNone() + | + jumpStep(node, mid) and + t = t0 + or + exists(boolean preservesValue | + additionalLambdaFlowStep(node, mid, preservesValue) and + getNodeEnclosingCallable(node) != getNodeEnclosingCallable(mid) + | + preservesValue = false and + t = getNodeType(node) + or + preservesValue = true and + t = t0 + ) + ) + or + // flow into a callable + exists(ParameterNode p, DataFlowCallOption lastCall0, DataFlowCall call | + revLambdaFlowIn(lambdaCall, kind, p, t, toJump, lastCall0) and + ( + if lastCall0 = TDataFlowCallNone() and toJump = false + then lastCall = TDataFlowCallSome(call) + else lastCall = lastCall0 + ) and + toReturn = false + | + viableParamArgNonLambda(call, p, node) + or + viableParamArgLambda(call, p, node) // non-linear recursion + ) + or + // flow out of a callable + exists(TReturnPositionSimple pos | + revLambdaFlowOut(lambdaCall, kind, pos, t, toJump, lastCall) and + getReturnPositionSimple(node, node.(ReturnNode).getKind()) = pos and + toReturn = true + ) + } + + pragma[nomagic] + predicate revLambdaFlowOutLambdaCall( + DataFlowCall lambdaCall, LambdaCallKind kind, OutNode out, DataFlowType t, boolean toJump, + DataFlowCall call, DataFlowCallOption lastCall + ) { + revLambdaFlow(lambdaCall, kind, out, t, _, toJump, lastCall) and + exists(ReturnKindExt rk | + out = rk.getAnOutNode(call) and + lambdaCall(call, _, _) + ) + } + + pragma[nomagic] + predicate revLambdaFlowOut( + DataFlowCall lambdaCall, LambdaCallKind kind, TReturnPositionSimple pos, DataFlowType t, + boolean toJump, DataFlowCallOption lastCall + ) { + exists(DataFlowCall call, OutNode out | + revLambdaFlow(lambdaCall, kind, out, t, _, toJump, lastCall) and + viableReturnPosOutNonLambda(call, pos, out) + or + // non-linear recursion + revLambdaFlowOutLambdaCall(lambdaCall, kind, out, t, toJump, call, lastCall) and + viableReturnPosOutLambda(call, _, pos, out) + ) + } + + pragma[nomagic] + predicate revLambdaFlowIn( + DataFlowCall lambdaCall, LambdaCallKind kind, ParameterNode p, DataFlowType t, boolean toJump, + DataFlowCallOption lastCall + ) { + revLambdaFlow(lambdaCall, kind, p, t, false, toJump, lastCall) + } +} + +private DataFlowCallable viableCallableExt(DataFlowCall call) { + result = viableCallable(call) + or + result = viableCallableLambda(call, _) +} + cached private module Cached { + /** + * Gets a viable target for the lambda call `call`. + * + * `lastCall` records the call required to reach `call` in order for the result + * to be a viable target, if any. + */ + cached + DataFlowCallable viableCallableLambda(DataFlowCall call, DataFlowCallOption lastCall) { + exists(Node creation, LambdaCallKind kind | + LambdaFlow::revLambdaFlow(call, kind, creation, _, _, _, lastCall) and + lambdaCreation(creation, kind, result) + ) + } + /** * Holds if `p` is the `i`th parameter of a viable dispatch target of `call`. * The instance parameter is considered to have index `-1`. */ pragma[nomagic] private predicate viableParam(DataFlowCall call, int i, ParameterNode p) { - p.isParameterOf(viableCallable(call), i) + p.isParameterOf(viableCallableExt(call), i) } /** @@ -52,7 +280,7 @@ private module Cached { pragma[nomagic] private ReturnPosition viableReturnPos(DataFlowCall call, ReturnKindExt kind) { - viableCallable(call) = result.getCallable() and + viableCallableExt(call) = result.getCallable() and kind = result.getKind() } @@ -317,6 +545,35 @@ private module Cached { cached private module DispatchWithCallContext { + /** + * Holds if the set of viable implementations that can be called by `call` + * might be improved by knowing the call context. + */ + pragma[nomagic] + private predicate mayBenefitFromCallContextExt(DataFlowCall call, DataFlowCallable callable) { + mayBenefitFromCallContext(call, callable) + or + callable = call.getEnclosingCallable() and + exists(viableCallableLambda(call, TDataFlowCallSome(_))) + } + + /** + * Gets a viable dispatch target of `call` in the context `ctx`. This is + * restricted to those `call`s for which a context might make a difference. + */ + pragma[nomagic] + private DataFlowCallable viableImplInCallContextExt(DataFlowCall call, DataFlowCall ctx) { + result = viableImplInCallContext(call, ctx) + or + result = viableCallableLambda(call, TDataFlowCallSome(ctx)) + or + exists(DataFlowCallable enclosing | + mayBenefitFromCallContextExt(call, enclosing) and + enclosing = viableCallableExt(ctx) and + result = viableCallableLambda(call, TDataFlowCallNone()) + ) + } + /** * Holds if the call context `ctx` reduces the set of viable run-time * dispatch targets of call `call` in `c`. @@ -324,10 +581,10 @@ private module Cached { cached predicate reducedViableImplInCallContext(DataFlowCall call, DataFlowCallable c, DataFlowCall ctx) { exists(int tgts, int ctxtgts | - mayBenefitFromCallContext(call, c) and - c = viableCallable(ctx) and - ctxtgts = count(viableImplInCallContext(call, ctx)) and - tgts = strictcount(viableCallable(call)) and + mayBenefitFromCallContextExt(call, c) and + c = viableCallableExt(ctx) and + ctxtgts = count(viableImplInCallContextExt(call, ctx)) and + tgts = strictcount(viableCallableExt(call)) and ctxtgts < tgts ) } @@ -339,7 +596,7 @@ private module Cached { */ cached DataFlowCallable prunedViableImplInCallContext(DataFlowCall call, DataFlowCall ctx) { - result = viableImplInCallContext(call, ctx) and + result = viableImplInCallContextExt(call, ctx) and reducedViableImplInCallContext(call, _, ctx) } @@ -351,10 +608,10 @@ private module Cached { cached predicate reducedViableImplInReturn(DataFlowCallable c, DataFlowCall call) { exists(int tgts, int ctxtgts | - mayBenefitFromCallContext(call, _) and - c = viableCallable(call) and - ctxtgts = count(DataFlowCall ctx | c = viableImplInCallContext(call, ctx)) and - tgts = strictcount(DataFlowCall ctx | viableCallable(ctx) = call.getEnclosingCallable()) and + mayBenefitFromCallContextExt(call, _) and + c = viableCallableExt(call) and + ctxtgts = count(DataFlowCall ctx | c = viableImplInCallContextExt(call, ctx)) and + tgts = strictcount(DataFlowCall ctx | viableCallableExt(ctx) = call.getEnclosingCallable()) and ctxtgts < tgts ) } @@ -367,7 +624,7 @@ private module Cached { */ cached DataFlowCallable prunedViableImplInCallContextReverse(DataFlowCall call, DataFlowCall ctx) { - result = viableImplInCallContext(call, ctx) and + result = viableImplInCallContextExt(call, ctx) and reducedViableImplInReturn(result, call) } } @@ -481,6 +738,11 @@ private module Cached { TBooleanNone() or TBooleanSome(boolean b) { b = true or b = false } + cached + newtype TDataFlowCallOption = + TDataFlowCallNone() or + TDataFlowCallSome(DataFlowCall call) + cached newtype TTypedContent = MkTypedContent(Content c, DataFlowType t) { store(_, c, _, _, t) } @@ -777,7 +1039,7 @@ ReturnPosition getReturnPosition(ReturnNodeExt ret) { bindingset[cc, callable] predicate resolveReturn(CallContext cc, DataFlowCallable callable, DataFlowCall call) { - cc instanceof CallContextAny and callable = viableCallable(call) + cc instanceof CallContextAny and callable = viableCallableExt(call) or exists(DataFlowCallable c0, DataFlowCall call0 | call0.getEnclosingCallable() = callable and @@ -791,14 +1053,14 @@ DataFlowCallable resolveCall(DataFlowCall call, CallContext cc) { exists(DataFlowCall ctx | cc = TSpecificCall(ctx) | if reducedViableImplInCallContext(call, _, ctx) then result = prunedViableImplInCallContext(call, ctx) - else result = viableCallable(call) + else result = viableCallableExt(call) ) or - result = viableCallable(call) and cc instanceof CallContextSomeCall + result = viableCallableExt(call) and cc instanceof CallContextSomeCall or - result = viableCallable(call) and cc instanceof CallContextAny + result = viableCallableExt(call) and cc instanceof CallContextAny or - result = viableCallable(call) and cc instanceof CallContextReturn + result = viableCallableExt(call) and cc instanceof CallContextReturn } predicate read = readStep/3; @@ -812,6 +1074,19 @@ class BooleanOption extends TBooleanOption { } } +/** An optional `DataFlowCall`. */ +class DataFlowCallOption extends TDataFlowCallOption { + string toString() { + this = TDataFlowCallNone() and + result = "(none)" + or + exists(DataFlowCall call | + this = TDataFlowCallSome(call) and + result = call.toString() + ) + } +} + /** Content tagged with the type of a containing object. */ class TypedContent extends MkTypedContent { private Content c; diff --git a/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowPrivate.qll b/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowPrivate.qll index a2b1cae14d6..3b94e574de0 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowPrivate.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowPrivate.qll @@ -548,3 +548,14 @@ predicate isImmutableOrUnobservable(Node n) { /** Holds if `n` should be hidden from path explanations. */ predicate nodeIsHidden(Node n) { n instanceof OperandNode and not n instanceof ArgumentNode } + +class LambdaCallKind = Unit; + +/** Holds if `creation` is an expression that creates a lambda of kind `kind` for `c`. */ +predicate lambdaCreation(Node creation, LambdaCallKind kind, DataFlowCallable c) { none() } + +/** Holds if `call` is a lambda call of kind `kind` where `receiver` is the lambda expression. */ +predicate lambdaCall(DataFlowCall call, LambdaCallKind kind, Node receiver) { none() } + +/** Extra data-flow steps needed for lamba flow analysis. */ +predicate additionalLambdaFlowStep(Node nodeFrom, Node nodeTo, boolean preservesValue) { none() } diff --git a/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowUtil.qll b/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowUtil.qll index 76ca7b215dc..f5fb7309cff 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowUtil.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowUtil.qll @@ -362,15 +362,22 @@ private class ExplicitFieldStoreQualifierNode extends PartialDefinitionNode { /** * Not every store instruction generates a chi instruction that we can attach a PostUpdateNode to. - * For instance, an update to a field of a struct containing only one field. For these cases we - * attach the PostUpdateNode to the store instruction. There's no obvious pre update node for this case - * (as the entire memory is updated), so `getPreUpdateNode` is implemented as `none()`. + * For instance, an update to a field of a struct containing only one field. Even if the store does + * have a chi instruction, a subsequent use of the result of the store may be linked directly to the + * result of the store as an inexact definition if the store totally overlaps the use. For these + * cases we attach the PostUpdateNode to the store instruction. There's no obvious pre update node + * for this case (as the entire memory is updated), so `getPreUpdateNode` is implemented as + * `none()`. */ private class ExplicitSingleFieldStoreQualifierNode extends PartialDefinitionNode { override StoreInstruction instr; ExplicitSingleFieldStoreQualifierNode() { - not exists(ChiInstruction chi | chi.getPartial() = instr) and + ( + instr.getAUse().isDefinitionInexact() + or + not exists(ChiInstruction chi | chi.getPartial() = instr) + ) and // Without this condition any store would create a `PostUpdateNode`. instr.getDestinationAddress() instanceof FieldAddressInstruction } diff --git a/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/ModelUtil.qll b/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/ModelUtil.qll index 93d74519ca5..2f4037d4ec8 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/ModelUtil.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/ModelUtil.qll @@ -9,30 +9,18 @@ private import semmle.code.cpp.ir.dataflow.DataFlow /** * Gets the instruction that goes into `input` for `call`. */ -DataFlow::Node callInput(CallInstruction call, FunctionInput input) { - // A positional argument +Operand callInput(CallInstruction call, FunctionInput input) { + // An argument or qualifier exists(int index | - result.asInstruction() = call.getPositionalArgument(index) and - input.isParameter(index) + result = call.getArgumentOperand(index) and + input.isParameterOrQualifierAddress(index) ) or - // A value pointed to by a positional argument + // A value pointed to by an argument or qualifier exists(ReadSideEffectInstruction read | - result.asOperand() = read.getSideEffectOperand() and + result = read.getSideEffectOperand() and read.getPrimaryInstruction() = call and - input.isParameterDeref(read.getIndex()) - ) - or - // The qualifier pointer - result.asInstruction() = call.getThisArgument() and - input.isQualifierAddress() - or - // The qualifier object - exists(ReadSideEffectInstruction read | - result.asOperand() = read.getSideEffectOperand() and - read.getPrimaryInstruction() = call and - read.getIndex() = -1 and - input.isQualifierObject() + input.isParameterDerefOrQualifierObject(read.getIndex()) ) } @@ -44,19 +32,11 @@ Instruction callOutput(CallInstruction call, FunctionOutput output) { result = call and output.isReturnValue() or - // The side effect of a call on the value pointed to by a positional argument + // The side effect of a call on the value pointed to by an argument or qualifier exists(WriteSideEffectInstruction effect | result = effect and effect.getPrimaryInstruction() = call and - output.isParameterDeref(effect.getIndex()) - ) - or - // The side effect of a call on the qualifier object - exists(WriteSideEffectInstruction effect | - result = effect and - effect.getPrimaryInstruction() = call and - effect.getIndex() = -1 and - output.isQualifierObject() + output.isParameterDerefOrQualifierObject(effect.getIndex()) ) // TODO: return value dereference } diff --git a/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/PrintIRLocalFlow.qll b/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/PrintIRLocalFlow.qll index 337dc71a3ca..16182296e40 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/PrintIRLocalFlow.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/PrintIRLocalFlow.qll @@ -6,34 +6,7 @@ private import semmle.code.cpp.ir.ValueNumbering private import semmle.code.cpp.ir.IR private import semmle.code.cpp.ir.dataflow.DataFlow private import semmle.code.cpp.ir.dataflow.internal.DataFlowUtil - -/** - * Gets a short ID for an IR dataflow node. - * - For `Instruction`s, this is just the result ID of the instruction (e.g. `m128`). - * - For `Operand`s, this is the label of the operand, prefixed with the result ID of the - * instruction and a dot (e.g. `m128.left`). - * - For `Variable`s, this is the qualified name of the variable. - */ -private string nodeId(DataFlow::Node node, int order1, int order2) { - exists(Instruction instruction | instruction = node.asInstruction() | - result = instruction.getResultId() and - order1 = instruction.getBlock().getDisplayIndex() and - order2 = instruction.getDisplayIndexInBlock() - ) - or - exists(Operand operand, Instruction instruction | - operand = node.asOperand() and - instruction = operand.getUse() - | - result = instruction.getResultId() + "." + operand.getDumpId() and - order1 = instruction.getBlock().getDisplayIndex() and - order2 = instruction.getDisplayIndexInBlock() - ) - or - result = "var(" + node.asVariable().getQualifiedName() + ")" and - order1 = 1000000 and - order2 = 0 -} +private import PrintIRUtilities /** * Gets the local dataflow from other nodes in the same function to this node. diff --git a/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/PrintIRStoreSteps.qll b/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/PrintIRStoreSteps.qll new file mode 100644 index 00000000000..8c318216217 --- /dev/null +++ b/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/PrintIRStoreSteps.qll @@ -0,0 +1,33 @@ +/** + * Print the dataflow local store steps in IR dumps. + */ + +private import cpp +// The `ValueNumbering` library has to be imported right after `cpp` to ensure +// that the cached IR gets the same checksum here as it does in queries that use +// `ValueNumbering` without `DataFlow`. +private import semmle.code.cpp.ir.ValueNumbering +private import semmle.code.cpp.ir.IR +private import semmle.code.cpp.ir.dataflow.DataFlow +private import semmle.code.cpp.ir.dataflow.internal.DataFlowUtil +private import semmle.code.cpp.ir.dataflow.internal.DataFlowPrivate +private import PrintIRUtilities + +/** + * Property provider for local IR dataflow store steps. + */ +class LocalFlowPropertyProvider extends IRPropertyProvider { + override string getInstructionProperty(Instruction instruction, string key) { + exists(DataFlow::Node objectNode, Content content | + key = "content[" + content.toString() + "]" and + instruction = objectNode.asInstruction() and + result = + strictconcat(string element, DataFlow::Node fieldNode | + storeStep(fieldNode, content, objectNode) and + element = nodeId(fieldNode, _, _) + | + element, ", " + ) + ) + } +} diff --git a/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/PrintIRUtilities.qll b/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/PrintIRUtilities.qll new file mode 100644 index 00000000000..5fc15cf986c --- /dev/null +++ b/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/PrintIRUtilities.qll @@ -0,0 +1,39 @@ +/** + * Shared utilities used when printing dataflow annotations in IR dumps. + */ + +private import cpp +// The `ValueNumbering` library has to be imported right after `cpp` to ensure +// that the cached IR gets the same checksum here as it does in queries that use +// `ValueNumbering` without `DataFlow`. +private import semmle.code.cpp.ir.ValueNumbering +private import semmle.code.cpp.ir.IR +private import semmle.code.cpp.ir.dataflow.DataFlow + +/** + * Gets a short ID for an IR dataflow node. + * - For `Instruction`s, this is just the result ID of the instruction (e.g. `m128`). + * - For `Operand`s, this is the label of the operand, prefixed with the result ID of the + * instruction and a dot (e.g. `m128.left`). + * - For `Variable`s, this is the qualified name of the variable. + */ +string nodeId(DataFlow::Node node, int order1, int order2) { + exists(Instruction instruction | instruction = node.asInstruction() | + result = instruction.getResultId() and + order1 = instruction.getBlock().getDisplayIndex() and + order2 = instruction.getDisplayIndexInBlock() + ) + or + exists(Operand operand, Instruction instruction | + operand = node.asOperand() and + instruction = operand.getUse() + | + result = instruction.getResultId() + "." + operand.getDumpId() and + order1 = instruction.getBlock().getDisplayIndex() and + order2 = instruction.getDisplayIndexInBlock() + ) + or + result = "var(" + node.asVariable().getQualifiedName() + ")" and + order1 = 1000000 and + order2 = 0 +} diff --git a/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/TaintTrackingUtil.qll b/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/TaintTrackingUtil.qll index 202d3f1c14e..ab1177daea9 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/TaintTrackingUtil.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/TaintTrackingUtil.qll @@ -21,53 +21,104 @@ predicate localTaintStep(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) { */ cached predicate localAdditionalTaintStep(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) { - localInstructionTaintStep(nodeFrom.asInstruction(), nodeTo.asInstruction()) + operandToInstructionTaintStep(nodeFrom.asOperand(), nodeTo.asInstruction()) or - modeledTaintStep(nodeFrom, nodeTo) + instructionToOperandTaintStep(nodeFrom.asInstruction(), nodeTo.asOperand()) +} + +private predicate instructionToOperandTaintStep(Instruction fromInstr, Operand toOperand) { + // Propagate flow from the definition of an operand to the operand, even when the overlap is inexact. + // We only do this in certain cases: + // 1. The instruction's result must not be conflated, and + // 2. The instruction's result type is one the types where we expect element-to-object flow. Currently + // this is array types and union types. This matches the other two cases of element-to-object flow in + // `DefaultTaintTracking`. + toOperand.getAnyDef() = fromInstr and + not fromInstr.isResultConflated() and + ( + fromInstr.getResultType() instanceof ArrayType or + fromInstr.getResultType() instanceof Union + ) + or + exists(ReadSideEffectInstruction readInstr | + fromInstr = readInstr.getArgumentDef() and + toOperand = readInstr.getSideEffectOperand() + ) + or + toOperand.(LoadOperand).getAnyDef() = fromInstr } /** * Holds if taint propagates from `nodeFrom` to `nodeTo` in exactly one local * (intra-procedural) step. */ -private predicate localInstructionTaintStep(Instruction nodeFrom, Instruction nodeTo) { +private predicate operandToInstructionTaintStep(Operand opFrom, Instruction instrTo) { // Taint can flow through expressions that alter the value but preserve // more than one bit of it _or_ expressions that follow data through // pointer indirections. - nodeTo.getAnOperand().getAnyDef() = nodeFrom and + instrTo.getAnOperand() = opFrom and ( - nodeTo instanceof ArithmeticInstruction + instrTo instanceof ArithmeticInstruction or - nodeTo instanceof BitwiseInstruction + instrTo instanceof BitwiseInstruction or - nodeTo instanceof PointerArithmeticInstruction - or - nodeTo instanceof FieldAddressInstruction + instrTo instanceof PointerArithmeticInstruction or // The `CopyInstruction` case is also present in non-taint data flow, but // that uses `getDef` rather than `getAnyDef`. For taint, we want flow // from a definition of `myStruct` to a `myStruct.myField` expression. - nodeTo instanceof CopyInstruction + instrTo instanceof CopyInstruction ) or - nodeTo.(LoadInstruction).getSourceAddress() = nodeFrom - or - // Flow through partial reads of arrays and unions - nodeTo.(LoadInstruction).getSourceValueOperand().getAnyDef() = nodeFrom and - not nodeFrom.isResultConflated() and + // Unary instructions tend to preserve enough information in practice that we + // want taint to flow through. + // The exception is `FieldAddressInstruction`. Together with the rules below for + // `LoadInstruction`s and `ChiInstruction`s, flow through `FieldAddressInstruction` + // could cause flow into one field to come out an unrelated field. + // This would happen across function boundaries, where the IR would not be able to + // match loads to stores. + instrTo.(UnaryInstruction).getUnaryOperand() = opFrom and ( - nodeFrom.getResultType() instanceof ArrayType or - nodeFrom.getResultType() instanceof Union + not instrTo instanceof FieldAddressInstruction + or + instrTo.(FieldAddressInstruction).getField().getDeclaringType() instanceof Union ) or + instrTo.(LoadInstruction).getSourceAddressOperand() = opFrom + or // Flow from an element to an array or union that contains it. - nodeTo.(ChiInstruction).getPartial() = nodeFrom and - not nodeTo.isResultConflated() and - exists(Type t | nodeTo.getResultLanguageType().hasType(t, false) | + instrTo.(ChiInstruction).getPartialOperand() = opFrom and + not instrTo.isResultConflated() and + exists(Type t | instrTo.getResultLanguageType().hasType(t, false) | t instanceof Union or t instanceof ArrayType ) + or + // Until we have flow through indirections across calls, we'll take flow out + // of the indirection and into the argument. + // When we get proper flow through indirections across calls, this code can be + // moved to `adjusedSink` or possibly into the `DataFlow::ExprNode` class. + exists(ReadSideEffectInstruction read | + read.getSideEffectOperand() = opFrom and + read.getArgumentDef() = instrTo + ) + or + // Until we have from through indirections across calls, we'll take flow out + // of the parameter and into its indirection. + // `InitializeIndirectionInstruction` only has a single operand: the address of the + // value whose indirection we are initializing. When initializing an indirection of a parameter `p`, + // the IR looks like this: + // ``` + // m1 = InitializeParameter[p] : &r1 + // r2 = Load[p] : r2, m1 + // m3 = InitializeIndirection[p] : &r2 + // ``` + // So by having flow from `r2` to `m3` we're enabling flow from `m1` to `m3`. This relies on the + // `LoadOperand`'s overlap being exact. + instrTo.(InitializeIndirectionInstruction).getAnOperand() = opFrom + or + modeledTaintStep(opFrom, instrTo) } /** @@ -110,17 +161,19 @@ predicate defaultTaintSanitizer(DataFlow::Node node) { none() } * Holds if taint can flow from `instrIn` to `instrOut` through a call to a * modeled function. */ -predicate modeledTaintStep(DataFlow::Node nodeIn, DataFlow::Node nodeOut) { +predicate modeledTaintStep(Operand nodeIn, Instruction nodeOut) { exists(CallInstruction call, TaintFunction func, FunctionInput modelIn, FunctionOutput modelOut | ( nodeIn = callInput(call, modelIn) or exists(int n | - modelIn.isParameterDeref(n) and - nodeIn = callInput(call, any(InParameter inParam | inParam.getIndex() = n)) + modelIn.isParameterDerefOrQualifierObject(n) and + if n = -1 + then nodeIn = callInput(call, any(InQualifierObject inQualifier)) + else nodeIn = callInput(call, any(InParameter inParam | inParam.getIndex() = n)) ) ) and - nodeOut.asInstruction() = callOutput(call, modelOut) and + nodeOut = callOutput(call, modelOut) and call.getStaticCallTarget() = func and func.hasTaintFlow(modelIn, modelOut) ) @@ -135,11 +188,29 @@ predicate modeledTaintStep(DataFlow::Node nodeIn, DataFlow::Node nodeOut) { int indexMid, InParameter modelMidIn, OutReturnValue modelOut | nodeIn = callInput(call, modelIn) and - nodeOut.asInstruction() = callOutput(call, modelOut) and + nodeOut = callOutput(call, modelOut) and call.getStaticCallTarget() = func and func.(TaintFunction).hasTaintFlow(modelIn, modelMidOut) and func.(DataFlowFunction).hasDataFlow(modelMidIn, modelOut) and modelMidOut.isParameterDeref(indexMid) and modelMidIn.isParameter(indexMid) ) + or + // Taint flow from a pointer argument to an output, when the model specifies flow from the deref + // to that output, but the deref is not modeled in the IR for the caller. + exists( + CallInstruction call, ReadSideEffectInstruction read, Function func, FunctionInput modelIn, + FunctionOutput modelOut + | + read.getSideEffectOperand() = callInput(call, modelIn) and + read.getArgumentDef() = nodeIn.getDef() and + not read.getSideEffect().isResultModeled() and + call.getStaticCallTarget() = func and + ( + func.(DataFlowFunction).hasDataFlow(modelIn, modelOut) + or + func.(TaintFunction).hasTaintFlow(modelIn, modelOut) + ) and + nodeOut = callOutput(call, modelOut) + ) } diff --git a/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/tainttracking3/TaintTrackingImpl.qll b/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/tainttracking3/TaintTrackingImpl.qll new file mode 100644 index 00000000000..b509fad9cd2 --- /dev/null +++ b/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/tainttracking3/TaintTrackingImpl.qll @@ -0,0 +1,115 @@ +/** + * Provides an implementation of global (interprocedural) taint tracking. + * This file re-exports the local (intraprocedural) taint-tracking analysis + * from `TaintTrackingParameter::Public` and adds a global analysis, mainly + * exposed through the `Configuration` class. For some languages, this file + * exists in several identical copies, allowing queries to use multiple + * `Configuration` classes that depend on each other without introducing + * mutual recursion among those configurations. + */ + +import TaintTrackingParameter::Public +private import TaintTrackingParameter::Private + +/** + * A configuration of interprocedural taint tracking analysis. This defines + * sources, sinks, and any other configurable aspect of the analysis. Each + * use of the taint tracking library must define its own unique extension of + * this abstract class. + * + * A taint-tracking configuration is a special data flow configuration + * (`DataFlow::Configuration`) that allows for flow through nodes that do not + * necessarily preserve values but are still relevant from a taint tracking + * perspective. (For example, string concatenation, where one of the operands + * is tainted.) + * + * To create a configuration, extend this class with a subclass whose + * characteristic predicate is a unique singleton string. For example, write + * + * ```ql + * class MyAnalysisConfiguration extends TaintTracking::Configuration { + * MyAnalysisConfiguration() { this = "MyAnalysisConfiguration" } + * // Override `isSource` and `isSink`. + * // Optionally override `isSanitizer`. + * // Optionally override `isSanitizerIn`. + * // Optionally override `isSanitizerOut`. + * // Optionally override `isSanitizerGuard`. + * // Optionally override `isAdditionalTaintStep`. + * } + * ``` + * + * Then, to query whether there is flow between some `source` and `sink`, + * write + * + * ```ql + * exists(MyAnalysisConfiguration cfg | cfg.hasFlow(source, sink)) + * ``` + * + * Multiple configurations can coexist, but it is unsupported to depend on + * another `TaintTracking::Configuration` or a `DataFlow::Configuration` in the + * overridden predicates that define sources, sinks, or additional steps. + * Instead, the dependency should go to a `TaintTracking2::Configuration` or a + * `DataFlow2::Configuration`, `DataFlow3::Configuration`, etc. + */ +abstract class Configuration extends DataFlow::Configuration { + bindingset[this] + Configuration() { any() } + + /** + * Holds if `source` is a relevant taint source. + * + * The smaller this predicate is, the faster `hasFlow()` will converge. + */ + // overridden to provide taint-tracking specific qldoc + abstract override predicate isSource(DataFlow::Node source); + + /** + * Holds if `sink` is a relevant taint sink. + * + * The smaller this predicate is, the faster `hasFlow()` will converge. + */ + // overridden to provide taint-tracking specific qldoc + abstract override predicate isSink(DataFlow::Node sink); + + /** Holds if the node `node` is a taint sanitizer. */ + predicate isSanitizer(DataFlow::Node node) { none() } + + final override predicate isBarrier(DataFlow::Node node) { + isSanitizer(node) or + defaultTaintSanitizer(node) + } + + /** Holds if taint propagation into `node` is prohibited. */ + predicate isSanitizerIn(DataFlow::Node node) { none() } + + final override predicate isBarrierIn(DataFlow::Node node) { isSanitizerIn(node) } + + /** Holds if taint propagation out of `node` is prohibited. */ + predicate isSanitizerOut(DataFlow::Node node) { none() } + + final override predicate isBarrierOut(DataFlow::Node node) { isSanitizerOut(node) } + + /** Holds if taint propagation through nodes guarded by `guard` is prohibited. */ + predicate isSanitizerGuard(DataFlow::BarrierGuard guard) { none() } + + final override predicate isBarrierGuard(DataFlow::BarrierGuard guard) { isSanitizerGuard(guard) } + + /** + * Holds if the additional taint propagation step from `node1` to `node2` + * must be taken into account in the analysis. + */ + predicate isAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) { none() } + + final override predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) { + isAdditionalTaintStep(node1, node2) or + defaultAdditionalTaintStep(node1, node2) + } + + /** + * Holds if taint may flow from `source` to `sink` for this configuration. + */ + // overridden to provide taint-tracking specific qldoc + override predicate hasFlow(DataFlow::Node source, DataFlow::Node sink) { + super.hasFlow(source, sink) + } +} diff --git a/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/tainttracking3/TaintTrackingParameter.qll b/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/tainttracking3/TaintTrackingParameter.qll new file mode 100644 index 00000000000..2a3b69f55cd --- /dev/null +++ b/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/tainttracking3/TaintTrackingParameter.qll @@ -0,0 +1,5 @@ +import semmle.code.cpp.ir.dataflow.internal.TaintTrackingUtil as Public + +module Private { + import semmle.code.cpp.ir.dataflow.DataFlow3::DataFlow3 as DataFlow +} diff --git a/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/SideEffects.qll b/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/SideEffects.qll new file mode 100644 index 00000000000..350127a58d1 --- /dev/null +++ b/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/SideEffects.qll @@ -0,0 +1,109 @@ +/** + * Predicates to compute the modeled side effects of calls during IR construction. + * + * These are used in `TranslatedElement.qll` to generate the `TTranslatedSideEffect` instances, and + * also in `TranslatedCall.qll` to inject the actual side effect instructions. + */ + +private import cpp +private import semmle.code.cpp.ir.implementation.Opcode +private import semmle.code.cpp.models.interfaces.SideEffect + +/** + * Holds if the specified call has a side effect that does not come from a `SideEffectFunction` + * model. + */ +private predicate hasDefaultSideEffect(Call call, ParameterIndex i, boolean buffer, boolean isWrite) { + not call.getTarget() instanceof SideEffectFunction and + ( + exists(MemberFunction mfunc | + // A non-static member function, including a constructor or destructor, may write to `*this`, + // and may also read from `*this` if it is not a constructor. + i = -1 and + mfunc = call.getTarget() and + not mfunc.isStatic() and + buffer = false and + ( + isWrite = false and not mfunc instanceof Constructor + or + isWrite = true and not mfunc instanceof ConstMemberFunction + ) + ) + or + exists(Expr expr | + // A pointer-like argument is assumed to read from the pointed-to buffer, and may write to the + // buffer as well unless the pointer points to a `const` value. + i >= 0 and + buffer = true and + expr = call.getArgument(i).getFullyConverted() and + exists(Type t | t = expr.getUnspecifiedType() | + t instanceof ArrayType or + t instanceof PointerType or + t instanceof ReferenceType + ) and + ( + isWrite = true and + not call.getTarget().getParameter(i).getType().isDeeplyConstBelow() + or + isWrite = false + ) + ) + ) +} + +/** + * Returns a side effect opcode for parameter index `i` of the specified call. + * + * This predicate will return at most two results: one read side effect, and one write side effect. + */ +Opcode getASideEffectOpcode(Call call, ParameterIndex i) { + exists(boolean buffer | + ( + call.getTarget().(SideEffectFunction).hasSpecificReadSideEffect(i, buffer) + or + not call.getTarget() instanceof SideEffectFunction and + hasDefaultSideEffect(call, i, buffer, false) + ) and + if exists(call.getTarget().(SideEffectFunction).getParameterSizeIndex(i)) + then ( + buffer = true and + result instanceof Opcode::SizedBufferReadSideEffect + ) else ( + buffer = false and result instanceof Opcode::IndirectReadSideEffect + or + buffer = true and result instanceof Opcode::BufferReadSideEffect + ) + ) + or + exists(boolean buffer, boolean mustWrite | + ( + call.getTarget().(SideEffectFunction).hasSpecificWriteSideEffect(i, buffer, mustWrite) + or + not call.getTarget() instanceof SideEffectFunction and + hasDefaultSideEffect(call, i, buffer, true) and + mustWrite = false + ) and + if exists(call.getTarget().(SideEffectFunction).getParameterSizeIndex(i)) + then ( + buffer = true and + mustWrite = false and + result instanceof Opcode::SizedBufferMayWriteSideEffect + or + buffer = true and + mustWrite = true and + result instanceof Opcode::SizedBufferMustWriteSideEffect + ) else ( + buffer = false and + mustWrite = false and + result instanceof Opcode::IndirectMayWriteSideEffect + or + buffer = false and + mustWrite = true and + result instanceof Opcode::IndirectMustWriteSideEffect + or + buffer = true and mustWrite = false and result instanceof Opcode::BufferMayWriteSideEffect + or + buffer = true and mustWrite = true and result instanceof Opcode::BufferMustWriteSideEffect + ) + ) +} diff --git a/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/TranslatedCall.qll b/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/TranslatedCall.qll index 7ad1dd2c01e..56d4c807ac8 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/TranslatedCall.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/TranslatedCall.qll @@ -4,6 +4,7 @@ private import semmle.code.cpp.ir.implementation.internal.OperandTag private import semmle.code.cpp.ir.internal.CppType private import semmle.code.cpp.models.interfaces.SideEffect private import InstructionTag +private import SideEffects private import TranslatedElement private import TranslatedExpr private import TranslatedFunction @@ -424,12 +425,15 @@ class TranslatedCallSideEffects extends TranslatedSideEffects, TTranslatedCallSi } class TranslatedStructorCallSideEffects extends TranslatedCallSideEffects { - TranslatedStructorCallSideEffects() { getParent().(TranslatedStructorCall).hasQualifier() } + TranslatedStructorCallSideEffects() { + getParent().(TranslatedStructorCall).hasQualifier() and + getASideEffectOpcode(expr, -1) instanceof WriteSideEffectOpcode + } override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType t) { - opcode instanceof Opcode::IndirectMayWriteSideEffect and tag instanceof OnlyInstructionTag and - t = getTypeForPRValue(expr.getTarget().getDeclaringType()) + t = getTypeForPRValue(expr.getTarget().getDeclaringType()) and + opcode = getASideEffectOpcode(expr, -1).(WriteSideEffectOpcode) } override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) { @@ -460,9 +464,11 @@ class TranslatedSideEffect extends TranslatedElement, TTranslatedArgumentSideEff Call call; Expr arg; int index; - boolean write; + SideEffectOpcode sideEffectOpcode; - TranslatedSideEffect() { this = TTranslatedArgumentSideEffect(call, arg, index, write) } + TranslatedSideEffect() { + this = TTranslatedArgumentSideEffect(call, arg, index, sideEffectOpcode) + } override Locatable getAST() { result = arg } @@ -472,13 +478,13 @@ class TranslatedSideEffect extends TranslatedElement, TTranslatedArgumentSideEff int getArgumentIndex() { result = index } - predicate isWrite() { write = true } + predicate isWrite() { sideEffectOpcode instanceof WriteSideEffectOpcode } override string toString() { - write = true and + isWrite() and result = "(write side effect for " + arg.toString() + ")" or - write = false and + not isWrite() and result = "(read side effect for " + arg.toString() + ")" } @@ -489,29 +495,29 @@ class TranslatedSideEffect extends TranslatedElement, TTranslatedArgumentSideEff override Instruction getFirstInstruction() { result = getInstruction(OnlyInstructionTag()) } override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType type) { - isWrite() and - hasSpecificWriteSideEffect(opcode) and tag = OnlyInstructionTag() and + opcode = sideEffectOpcode and ( - opcode instanceof BufferAccessOpcode and - type = getUnknownType() - or - not opcode instanceof BufferAccessOpcode and - exists(Type baseType | baseType = arg.getUnspecifiedType().(DerivedType).getBaseType() | - if baseType instanceof VoidType - then type = getUnknownType() - else type = getTypeForPRValueOrUnknown(baseType) + isWrite() and + ( + opcode instanceof BufferAccessOpcode and + type = getUnknownType() + or + not opcode instanceof BufferAccessOpcode and + exists(Type baseType | baseType = arg.getUnspecifiedType().(DerivedType).getBaseType() | + if baseType instanceof VoidType + then type = getUnknownType() + else type = getTypeForPRValueOrUnknown(baseType) + ) + or + index = -1 and + not arg.getUnspecifiedType() instanceof DerivedType and + type = getTypeForPRValueOrUnknown(arg.getUnspecifiedType()) ) or - index = -1 and - not arg.getUnspecifiedType() instanceof DerivedType and - type = getTypeForPRValueOrUnknown(arg.getUnspecifiedType()) + not isWrite() and + type = getVoidType() ) - or - not isWrite() and - hasSpecificReadSideEffect(opcode) and - tag = OnlyInstructionTag() and - type = getVoidType() } override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) { @@ -535,7 +541,7 @@ class TranslatedSideEffect extends TranslatedElement, TTranslatedArgumentSideEff override CppType getInstructionMemoryOperandType(InstructionTag tag, TypedOperandTag operandTag) { not isWrite() and - if hasSpecificReadSideEffect(any(BufferAccessOpcode op)) + if sideEffectOpcode instanceof BufferAccessOpcode then result = getUnknownType() and tag instanceof OnlyInstructionTag and @@ -557,56 +563,6 @@ class TranslatedSideEffect extends TranslatedElement, TTranslatedArgumentSideEff ) } - predicate hasSpecificWriteSideEffect(Opcode op) { - exists(boolean buffer, boolean mustWrite | - if exists(call.getTarget().(SideEffectFunction).getParameterSizeIndex(index)) - then - call.getTarget().(SideEffectFunction).hasSpecificWriteSideEffect(index, true, mustWrite) and - buffer = true and - ( - mustWrite = false and op instanceof Opcode::SizedBufferMayWriteSideEffect - or - mustWrite = true and op instanceof Opcode::SizedBufferMustWriteSideEffect - ) - else ( - call.getTarget().(SideEffectFunction).hasSpecificWriteSideEffect(index, buffer, mustWrite) and - ( - buffer = true and mustWrite = false and op instanceof Opcode::BufferMayWriteSideEffect - or - buffer = false and mustWrite = false and op instanceof Opcode::IndirectMayWriteSideEffect - or - buffer = true and mustWrite = true and op instanceof Opcode::BufferMustWriteSideEffect - or - buffer = false and mustWrite = true and op instanceof Opcode::IndirectMustWriteSideEffect - ) - ) - ) - or - not call.getTarget() instanceof SideEffectFunction and - getArgumentIndex() != -1 and - op instanceof Opcode::BufferMayWriteSideEffect - or - not call.getTarget() instanceof SideEffectFunction and - getArgumentIndex() = -1 and - op instanceof Opcode::IndirectMayWriteSideEffect - } - - predicate hasSpecificReadSideEffect(Opcode op) { - exists(boolean buffer | - call.getTarget().(SideEffectFunction).hasSpecificReadSideEffect(index, buffer) and - if exists(call.getTarget().(SideEffectFunction).getParameterSizeIndex(index)) - then buffer = true and op instanceof Opcode::SizedBufferReadSideEffect - else ( - buffer = true and op instanceof Opcode::BufferReadSideEffect - or - buffer = false and op instanceof Opcode::IndirectReadSideEffect - ) - ) - or - not call.getTarget() instanceof SideEffectFunction and - op instanceof Opcode::BufferReadSideEffect - } - override Instruction getPrimaryInstructionForSideEffect(InstructionTag tag) { tag = OnlyInstructionTag() and result = getTranslatedCallInstruction(call) diff --git a/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/TranslatedElement.qll b/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/TranslatedElement.qll index 1de9936ae1f..eca659914b0 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/TranslatedElement.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/TranslatedElement.qll @@ -12,6 +12,7 @@ private import TranslatedStmt private import TranslatedExpr private import IRConstruction private import semmle.code.cpp.models.interfaces.SideEffect +private import SideEffects /** * Gets the "real" parent of `expr`. This predicate treats conversions as if @@ -635,46 +636,15 @@ newtype TTranslatedElement = // The side effects of an allocation, i.e. `new`, `new[]` or `malloc` TTranslatedAllocationSideEffects(AllocationExpr expr) { not ignoreExpr(expr) } or // A precise side effect of an argument to a `Call` - TTranslatedArgumentSideEffect(Call call, Expr expr, int n, boolean isWrite) { - ( - expr = call.getArgument(n).getFullyConverted() - or - expr = call.getQualifier().getFullyConverted() and - n = -1 and - // Exclude calls to static member functions. They don't modify the qualifier - not exists(MemberFunction func | func = call.getTarget() and func.isStatic()) - ) and - ( - call.getTarget().(SideEffectFunction).hasSpecificReadSideEffect(n, _) and - isWrite = false - or - call.getTarget().(SideEffectFunction).hasSpecificWriteSideEffect(n, _, _) and - isWrite = true - or - not call.getTarget() instanceof SideEffectFunction and - exists(Type t | t = expr.getUnspecifiedType() | - t instanceof ArrayType or - t instanceof PointerType or - t instanceof ReferenceType - ) and - ( - isWrite = true and - not call.getTarget().getParameter(n).getType().isDeeplyConstBelow() - or - isWrite = false - ) - or - not call.getTarget() instanceof SideEffectFunction and - n = -1 and - ( - isWrite = true and - not call.getTarget() instanceof ConstMemberFunction - or - isWrite = false - ) - ) and + TTranslatedArgumentSideEffect(Call call, Expr expr, int n, SideEffectOpcode opcode) { not ignoreExpr(expr) and - not ignoreExpr(call) + not ignoreExpr(call) and + ( + n >= 0 and expr = call.getArgument(n).getFullyConverted() + or + n = -1 and expr = call.getQualifier().getFullyConverted() + ) and + opcode = getASideEffectOpcode(call, n) } /** diff --git a/cpp/ql/src/semmle/code/cpp/models/implementations/Accept.qll b/cpp/ql/src/semmle/code/cpp/models/implementations/Accept.qll index 150f481de28..cea4598acf3 100644 --- a/cpp/ql/src/semmle/code/cpp/models/implementations/Accept.qll +++ b/cpp/ql/src/semmle/code/cpp/models/implementations/Accept.qll @@ -15,9 +15,7 @@ import semmle.code.cpp.models.interfaces.SideEffect private class Accept extends ArrayFunction, AliasFunction, TaintFunction, SideEffectFunction { Accept() { this.hasGlobalName(["accept", "accept4", "WSAAccept"]) } - override predicate hasArrayWithVariableSize(int bufParam, int countParam) { - bufParam = 1 and countParam = 2 - } + override predicate hasArrayWithUnknownSize(int bufParam) { bufParam = 1 } override predicate hasArrayInput(int bufParam) { bufParam = 1 } @@ -46,8 +44,8 @@ private class Accept extends ArrayFunction, AliasFunction, TaintFunction, SideEf i = 1 and buffer = false } - override ParameterIndex getParameterSizeIndex(ParameterIndex i) { i = 1 and result = 2 } - + // NOTE: The size parameter is a pointer to the size. So we can't implement `getParameterSizeIndex` for + // this model. // NOTE: We implement thse two predicates as none because we can't model the low-level changes made to // the structure pointed to by the file-descriptor argument. override predicate hasOnlySpecificReadSideEffects() { none() } diff --git a/cpp/ql/src/semmle/code/cpp/models/implementations/SmartPointer.qll b/cpp/ql/src/semmle/code/cpp/models/implementations/SmartPointer.qll index c6152624792..adef44a1125 100644 --- a/cpp/ql/src/semmle/code/cpp/models/implementations/SmartPointer.qll +++ b/cpp/ql/src/semmle/code/cpp/models/implementations/SmartPointer.qll @@ -1,10 +1,37 @@ import semmle.code.cpp.models.interfaces.Taint +import semmle.code.cpp.models.interfaces.DataFlow +import semmle.code.cpp.models.interfaces.PointerWrapper /** * The `std::shared_ptr` and `std::unique_ptr` template classes. */ -private class UniqueOrSharedPtr extends Class { +private class UniqueOrSharedPtr extends Class, PointerWrapper { UniqueOrSharedPtr() { this.hasQualifiedName(["std", "bsl"], ["shared_ptr", "unique_ptr"]) } + + override MemberFunction getAnUnwrapperFunction() { + result.(OverloadedPointerDereferenceFunction).getDeclaringType() = this + or + result.getClassAndName(["operator->", "get"]) = this + } + + override predicate pointsToConst() { this.getTemplateArgument(0).(Type).isConst() } +} + +/** Any function that unwraps a pointer wrapper class to reveal the underlying pointer. */ +private class PointerWrapperFlow extends TaintFunction, DataFlowFunction { + PointerWrapperFlow() { + this = any(PointerWrapper wrapper).getAnUnwrapperFunction() and + not this.getUnspecifiedType() instanceof ReferenceType + } + + override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { + input.isReturnValueDeref() and + output.isQualifierObject() + } + + override predicate hasDataFlow(FunctionInput input, FunctionOutput output) { + input.isQualifierObject() and output.isReturnValue() + } } /** diff --git a/cpp/ql/src/semmle/code/cpp/models/interfaces/PointerWrapper.qll b/cpp/ql/src/semmle/code/cpp/models/interfaces/PointerWrapper.qll new file mode 100644 index 00000000000..8948aee424b --- /dev/null +++ b/cpp/ql/src/semmle/code/cpp/models/interfaces/PointerWrapper.qll @@ -0,0 +1,17 @@ +/** Provides classes for modeling pointer wrapper types and expressions. */ + +private import cpp + +/** A class that wraps a pointer type. For example, `std::unique_ptr` and `std::shared_ptr`. */ +abstract class PointerWrapper extends Class { + /** + * Gets a member function of this class that returns the wrapped pointer, if any. + * + * This includes both functions that return the wrapped pointer by value, and functions + * that return a reference to the pointed-to object. + */ + abstract MemberFunction getAnUnwrapperFunction(); + + /** Holds if the type of the data that is pointed to by this pointer wrapper is `const`. */ + abstract predicate pointsToConst(); +} diff --git a/cpp/ql/src/semmle/code/cpp/security/Overflow.qll b/cpp/ql/src/semmle/code/cpp/security/Overflow.qll index e7ad1c559e6..465e64b9b6c 100644 --- a/cpp/ql/src/semmle/code/cpp/security/Overflow.qll +++ b/cpp/ql/src/semmle/code/cpp/security/Overflow.qll @@ -5,6 +5,8 @@ import cpp import semmle.code.cpp.controlflow.Dominance +import semmle.code.cpp.rangeanalysis.SimpleRangeAnalysis +import semmle.code.cpp.rangeanalysis.RangeAnalysisUtils /** * Holds if the value of `use` is guarded using `abs`. @@ -94,9 +96,15 @@ predicate guardedGreater(Operation e, Expr use) { VariableAccess varUse(LocalScopeVariable v) { result = v.getAnAccess() } /** - * Holds if `e` is not guarded against overflow by `use`. + * Holds if `e` potentially overflows and `use` is an operand of `e` that is not guarded. */ predicate missingGuardAgainstOverflow(Operation e, VariableAccess use) { + ( + convertedExprMightOverflowPositively(e) + or + // Ensure that the predicate holds when range analysis cannot determine an upper bound + upperBound(e.getFullyConverted()) = exprMaxVal(e.getFullyConverted()) + ) and use = e.getAnOperand() and exists(LocalScopeVariable v | use.getTarget() = v | // overflow possible if large @@ -115,9 +123,15 @@ predicate missingGuardAgainstOverflow(Operation e, VariableAccess use) { } /** - * Holds if `e` is not guarded against underflow by `use`. + * Holds if `e` potentially underflows and `use` is an operand of `e` that is not guarded. */ predicate missingGuardAgainstUnderflow(Operation e, VariableAccess use) { + ( + convertedExprMightOverflowNegatively(e) + or + // Ensure that the predicate holds when range analysis cannot determine a lower bound + lowerBound(e.getFullyConverted()) = exprMinVal(e.getFullyConverted()) + ) and use = e.getAnOperand() and exists(LocalScopeVariable v | use.getTarget() = v | // underflow possible if use is left operand and small diff --git a/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-570/semmle/tests/test.cpp b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-570/semmle/tests/test.cpp index e4aa8cf2976..4fc12d9ccbf 100644 --- a/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-570/semmle/tests/test.cpp +++ b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-570/semmle/tests/test.cpp @@ -14,8 +14,8 @@ using namespace std; void* operator new(std::size_t _Size); void* operator new[](std::size_t _Size); -void* operator new( std::size_t count, const std::nothrow_t& tag ); -void* operator new[]( std::size_t count, const std::nothrow_t& tag ); +void* operator new( std::size_t count, const std::nothrow_t& tag ) noexcept; +void* operator new[]( std::size_t count, const std::nothrow_t& tag ) noexcept; void badNew_0_0() { diff --git a/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-691/semmle/tests/InsufficientControlFlowManagementWhenUsingBitOperations.expected b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-691/semmle/tests/InsufficientControlFlowManagementWhenUsingBitOperations.expected new file mode 100644 index 00000000000..d11bbd446a6 --- /dev/null +++ b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-691/semmle/tests/InsufficientControlFlowManagementWhenUsingBitOperations.expected @@ -0,0 +1,2 @@ +| test.c:8:6:8:51 | ... & ... | This bitwise operation appears in a context where a Boolean operation is expected. | +| test.c:10:6:10:30 | ... & ... | This bitwise operation appears in a context where a Boolean operation is expected. | diff --git a/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-691/semmle/tests/InsufficientControlFlowManagementWhenUsingBitOperations.qlref b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-691/semmle/tests/InsufficientControlFlowManagementWhenUsingBitOperations.qlref new file mode 100644 index 00000000000..9bf28db3c8a --- /dev/null +++ b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-691/semmle/tests/InsufficientControlFlowManagementWhenUsingBitOperations.qlref @@ -0,0 +1 @@ +experimental/Security/CWE/CWE-691/InsufficientControlFlowManagementWhenUsingBitOperations.ql diff --git a/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-691/semmle/tests/test.c b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-691/semmle/tests/test.c new file mode 100644 index 00000000000..1db60826b60 --- /dev/null +++ b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-691/semmle/tests/test.c @@ -0,0 +1,28 @@ +int tmpFunction(){ + return 5; +} +void workFunction_0(char *s) { + int intSize; + char buf[80]; + if(intSize>0 && intSize<80 && memset(buf,0,intSize)) return; // GOOD + if(intSize>0 & intSize<80 & memset(buf,0,intSize)) return; // BAD + if(intSize>0 && tmpFunction()) return; + if(intSize<0 & tmpFunction()) return; // BAD +} +void workFunction_1(char *s) { + int intA,intB; + + if(intA + intB) return; // BAD [NOT DETECTED] + if(intA + intB>4) return; // GOOD + if(intA>0 && (intA + intB)) return; // BAD [NOT DETECTED] + while(intA>0) + { + if(intB - intA<10) break; + intA--; + }while(intA>0); // BAD [NOT DETECTED] + while(intA>0) + { + if(intB - intA<10) break; + intA--; + } // GOOD +} diff --git a/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-788/semmle/tests/AccessOfMemoryLocationAfterEndOfBufferUsingStrlen.expected b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-788/semmle/tests/AccessOfMemoryLocationAfterEndOfBufferUsingStrlen.expected index 103afd8ffd9..cd160a70638 100644 --- a/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-788/semmle/tests/AccessOfMemoryLocationAfterEndOfBufferUsingStrlen.expected +++ b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-788/semmle/tests/AccessOfMemoryLocationAfterEndOfBufferUsingStrlen.expected @@ -1,9 +1,9 @@ -| test.c:42:3:42:24 | ... = ... | potential unsafe or redundant assignment. | -| test.c:43:3:43:40 | ... = ... | potential unsafe or redundant assignment. | -| test.c:44:3:44:40 | ... = ... | potential unsafe or redundant assignment. | -| test.c:45:3:45:44 | ... = ... | potential unsafe or redundant assignment. | -| test.c:46:3:46:44 | ... = ... | potential unsafe or redundant assignment. | -| test.c:47:3:47:48 | ... = ... | potential unsafe or redundant assignment. | -| test.c:48:3:48:48 | ... = ... | potential unsafe or redundant assignment. | -| test.c:49:3:49:50 | ... = ... | potential unsafe or redundant assignment. | -| test.c:50:3:50:50 | ... = ... | potential unsafe or redundant assignment. | +| test.c:54:3:54:24 | ... = ... | potential unsafe or redundant assignment. | +| test.c:55:3:55:40 | ... = ... | potential unsafe or redundant assignment. | +| test.c:56:3:56:44 | ... = ... | potential unsafe or redundant assignment. | +| test.c:57:3:57:44 | ... = ... | potential unsafe or redundant assignment. | +| test.c:58:3:58:48 | ... = ... | potential unsafe or redundant assignment. | +| test.c:59:3:59:48 | ... = ... | potential unsafe or redundant assignment. | +| test.c:60:3:60:52 | ... = ... | potential unsafe or redundant assignment. | +| test.c:61:3:61:50 | ... = ... | potential unsafe or redundant assignment. | +| test.c:62:3:62:54 | ... = ... | potential unsafe or redundant assignment. | diff --git a/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-788/semmle/tests/AccessOfMemoryLocationAfterEndOfBufferUsingStrncat.expected b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-788/semmle/tests/AccessOfMemoryLocationAfterEndOfBufferUsingStrncat.expected index af52dac0144..3e9791e1024 100644 --- a/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-788/semmle/tests/AccessOfMemoryLocationAfterEndOfBufferUsingStrncat.expected +++ b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-788/semmle/tests/AccessOfMemoryLocationAfterEndOfBufferUsingStrncat.expected @@ -1,3 +1,5 @@ -| test.c:4:3:4:9 | call to strncat | if the used buffer is full, writing out of the buffer is possible | -| test.c:11:3:11:9 | call to strncat | if the used buffer is full, writing out of the buffer is possible | -| test.c:19:3:19:9 | call to strncat | if the used buffer is full, writing out of the buffer is possible | +| test.c:8:3:8:9 | call to strncat | Possible out-of-bounds write due to incorrect size argument. | +| test.c:9:3:9:9 | call to strncat | Possible out-of-bounds write due to incorrect size argument. | +| test.c:17:3:17:9 | call to strncat | Possible out-of-bounds write due to incorrect size argument. | +| test.c:18:3:18:9 | call to strncat | Possible out-of-bounds write due to incorrect size argument. | +| test.c:46:3:46:9 | call to strncat | Possible out-of-bounds write due to incorrect size argument. | diff --git a/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-788/semmle/tests/OperatorPrecedenceLogicErrorWhenUseBoolType.expected b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-788/semmle/tests/OperatorPrecedenceLogicErrorWhenUseBoolType.expected new file mode 100644 index 00000000000..1209c7e7830 --- /dev/null +++ b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-788/semmle/tests/OperatorPrecedenceLogicErrorWhenUseBoolType.expected @@ -0,0 +1,5 @@ +| test.cpp:10:8:10:10 | - ... | this expression needs attention | +| test.cpp:12:3:12:6 | ... ++ | this expression needs attention | +| test.cpp:13:3:13:6 | ++ ... | this expression needs attention | +| test.cpp:14:6:14:21 | ... = ... | this expression needs attention | +| test.cpp:16:6:16:21 | ... = ... | this expression needs attention | diff --git a/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-788/semmle/tests/OperatorPrecedenceLogicErrorWhenUseBoolType.qlref b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-788/semmle/tests/OperatorPrecedenceLogicErrorWhenUseBoolType.qlref new file mode 100644 index 00000000000..5189abcce5d --- /dev/null +++ b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-788/semmle/tests/OperatorPrecedenceLogicErrorWhenUseBoolType.qlref @@ -0,0 +1 @@ +experimental/Security/CWE/CWE-783/OperatorPrecedenceLogicErrorWhenUseBoolType.ql diff --git a/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-788/semmle/tests/test.c b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-788/semmle/tests/test.c index d986bb3b13c..6d310875630 100644 --- a/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-788/semmle/tests/test.c +++ b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-788/semmle/tests/test.c @@ -1,70 +1,84 @@ -void workFunction_0(char *s) { +char * strncat(char*, const char*, unsigned); +unsigned strlen(const char*); +void* malloc(unsigned); + +void strncat_test1(char *s) { char buf[80]; - strncat(buf, s, sizeof(buf)-strlen(buf)-1); // GOOD - strncat(buf, s, sizeof(buf)-strlen(buf)); // BAD - strncat(buf, "fix", sizeof(buf)-strlen(buf)); // BAD [NOT DETECTED] + strncat(buf, s, sizeof(buf) - strlen(buf) - 1); // GOOD + strncat(buf, s, sizeof(buf) - strlen(buf)); // BAD + strncat(buf, "fix", sizeof(buf)-strlen(buf)); // BAD } -void workFunction_1(char *s) { + #define MAX_SIZE 80 + +void strncat_test2(char *s) { char buf[MAX_SIZE]; - strncat(buf, s, MAX_SIZE-strlen(buf)-1); // GOOD - strncat(buf, s, MAX_SIZE-strlen(buf)); // BAD - strncat(buf, "fix", MAX_SIZE-strlen(buf)); // BAD [NOT DETECTED] + strncat(buf, s, MAX_SIZE - strlen(buf) - 1); // GOOD + strncat(buf, s, MAX_SIZE - strlen(buf)); // BAD + strncat(buf, "fix", MAX_SIZE - strlen(buf)); // BAD } -void workFunction_2_0(char *s) { - char * buf; - int len=80; - buf = (char *) malloc(len); - strncat(buf, s, len-strlen(buf)-1); // GOOD - strncat(buf, s, len-strlen(buf)); // BAD - strncat(buf, "fix", len-strlen(buf)); // BAD [NOT DETECTED] + +void strncat_test3(char *s) { + int len = 80; + char* buf = (char *) malloc(len); + strncat(buf, s, len - strlen(buf) - 1); // GOOD + strncat(buf, s, len - strlen(buf)); // BAD [NOT DETECTED] + strncat(buf, "fix", len - strlen(buf)); // BAD [NOT DETECTED] } -void workFunction_2_1(char *s) { - char * buf; - int len=80; - buf = (char *) malloc(len+1); - strncat(buf, s, len-strlen(buf)-1); // GOOD - strncat(buf, s, len-strlen(buf)); // GOOD + +void strncat_test4(char *s) { + int len = 80; + char* buf = (char *) malloc(len + 1); + strncat(buf, s, len - strlen(buf) - 1); // GOOD + strncat(buf, s, len - strlen(buf)); // GOOD } struct buffers { - unsigned char buff1[50]; - unsigned char *buff2; + unsigned char array[50]; + unsigned char *pointer; } globalBuff1,*globalBuff2,globalBuff1_c,*globalBuff2_c; +void strncat_test5(char* s, struct buffers* buffers) { + unsigned len_array = strlen(buffers->array); + unsigned max_size = sizeof(buffers->array); + unsigned free_size = max_size - len_array; + strncat(buffers->array, s, free_size); // BAD +} -void badFunc0(){ +void strlen_test1(){ unsigned char buff1[12]; struct buffers buffAll; struct buffers * buffAll1; buff1[strlen(buff1)]=0; // BAD - buffAll.buff1[strlen(buffAll.buff1)]=0; // BAD - buffAll.buff2[strlen(buffAll.buff2)]=0; // BAD - buffAll1->buff1[strlen(buffAll1->buff1)]=0; // BAD - buffAll1->buff2[strlen(buffAll1->buff2)]=0; // BAD - globalBuff1.buff1[strlen(globalBuff1.buff1)]=0; // BAD - globalBuff1.buff2[strlen(globalBuff1.buff2)]=0; // BAD - globalBuff2->buff1[strlen(globalBuff2->buff1)]=0; // BAD - globalBuff2->buff2[strlen(globalBuff2->buff2)]=0; // BAD + buffAll.array[strlen(buffAll.array)]=0; // BAD + buffAll.pointer[strlen(buffAll.pointer)]=0; // BAD + buffAll1->array[strlen(buffAll1->array)]=0; // BAD + buffAll1->pointer[strlen(buffAll1->pointer)]=0; // BAD + globalBuff1.array[strlen(globalBuff1.array)]=0; // BAD + globalBuff1.pointer[strlen(globalBuff1.pointer)]=0; // BAD + globalBuff2->array[strlen(globalBuff2->array)]=0; // BAD + globalBuff2->pointer[strlen(globalBuff2->pointer)]=0; // BAD } -void noBadFunc0(){ + +void strlen_test2(){ unsigned char buff1[12],buff1_c[12]; struct buffers buffAll,buffAll_c; struct buffers * buffAll1,*buffAll1_c; buff1[strlen(buff1_c)]=0; // GOOD - buffAll.buff1[strlen(buffAll_c.buff1)]=0; // GOOD - buffAll.buff2[strlen(buffAll.buff1)]=0; // GOOD - buffAll1->buff1[strlen(buffAll1_c->buff1)]=0; // GOOD - buffAll1->buff2[strlen(buffAll1->buff1)]=0; // GOOD - globalBuff1.buff1[strlen(globalBuff1_c.buff1)]=0; // GOOD - globalBuff1.buff2[strlen(globalBuff1.buff1)]=0; // GOOD - globalBuff2->buff1[strlen(globalBuff2_c->buff1)]=0; // GOOD - globalBuff2->buff2[strlen(globalBuff2->buff1)]=0; // GOOD + buffAll.array[strlen(buffAll_c.array)]=0; // GOOD + buffAll.pointer[strlen(buffAll.array)]=0; // GOOD + buffAll1->array[strlen(buffAll1_c->array)]=0; // GOOD + buffAll1->pointer[strlen(buffAll1->array)]=0; // GOOD + globalBuff1.array[strlen(globalBuff1_c.array)]=0; // GOOD + globalBuff1.pointer[strlen(globalBuff1.array)]=0; // GOOD + globalBuff2->array[strlen(globalBuff2_c->array)]=0; // GOOD + globalBuff2->pointer[strlen(globalBuff2->array)]=0; // GOOD } -void goodFunc0(){ + +void strlen_test3(){ unsigned char buffer[12]; int i; for(i = 0; i < 6; i++) diff --git a/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-788/semmle/tests/test.cpp b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-788/semmle/tests/test.cpp new file mode 100644 index 00000000000..f08d2a45757 --- /dev/null +++ b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-788/semmle/tests/test.cpp @@ -0,0 +1,26 @@ +int tmpFunc() +{ + return 12; +} +void testFunction() +{ + int i1,i2,i3; + bool b1,b2,b3; + char c1,c2,c3; + b1 = -b2; //BAD + b1 = !b2; //GOOD + b1++; //BAD + ++b1; //BAD + if(i1=tmpFunc()!=i2) //BAD + return; + if(i1=tmpFunc()!=11) //BAD + return; + if((i1=tmpFunc())!=i2) //GOOD + return; + if((i1=tmpFunc())!=11) //GOOD + return; + if(i1=tmpFunc()!=1) //GOOD + return; + if(i1=tmpFunc()==b1) //GOOD + return; +} diff --git a/cpp/ql/test/library-tests/dataflow/DefaultTaintTracking/annotate_path_to_sink/tainted.ql b/cpp/ql/test/library-tests/dataflow/DefaultTaintTracking/annotate_path_to_sink/tainted.ql index 89a7622c49a..27f45cf64ef 100644 --- a/cpp/ql/test/library-tests/dataflow/DefaultTaintTracking/annotate_path_to_sink/tainted.ql +++ b/cpp/ql/test/library-tests/dataflow/DefaultTaintTracking/annotate_path_to_sink/tainted.ql @@ -6,6 +6,7 @@ import cpp import semmle.code.cpp.security.TaintTrackingImpl as ASTTaintTracking import semmle.code.cpp.ir.dataflow.DefaultTaintTracking as IRDefaultTaintTracking +import IRDefaultTaintTracking::TaintedWithPath as TaintedWithPath import TestUtilities.InlineExpectationsTest predicate isSink(Element sink) { @@ -17,7 +18,13 @@ predicate isSink(Element sink) { predicate astTaint(Expr source, Element sink) { ASTTaintTracking::tainted(source, sink) } -predicate irTaint(Expr source, Element sink) { IRDefaultTaintTracking::tainted(source, sink) } +class SourceConfiguration extends TaintedWithPath::TaintTrackingConfiguration { + override predicate isSink(Element e) { any() } +} + +predicate irTaint(Expr source, Element sink) { + TaintedWithPath::taintedWithPath(source, sink, _, _) +} class IRDefaultTaintTrackingTest extends InlineExpectationsTest { IRDefaultTaintTrackingTest() { this = "IRDefaultTaintTrackingTest" } diff --git a/cpp/ql/test/library-tests/dataflow/DefaultTaintTracking/annotate_sinks_only/defaulttainttracking.cpp b/cpp/ql/test/library-tests/dataflow/DefaultTaintTracking/annotate_sinks_only/defaulttainttracking.cpp index 020a2f90b9e..d64f1966b49 100644 --- a/cpp/ql/test/library-tests/dataflow/DefaultTaintTracking/annotate_sinks_only/defaulttainttracking.cpp +++ b/cpp/ql/test/library-tests/dataflow/DefaultTaintTracking/annotate_sinks_only/defaulttainttracking.cpp @@ -19,7 +19,7 @@ int main() { char untainted_buf[100] = ""; char buf[100] = "VAR = "; - sink(strcat(buf, getenv("VAR"))); // $ ast,ir + sink(strcat(buf, getenv("VAR"))); // $ ast MISSING: ir sink(buf); // $ ast,ir sink(untainted_buf); // the two buffers would be conflated if we added flow through all partial chi inputs @@ -250,12 +250,12 @@ void sink(iovec); int test_readv_and_writev(iovec* iovs) { readv(0, iovs, 16); sink(iovs); // $ast,ir - sink(iovs[0]); // $ast MISSING: ir - sink(*iovs); // $ast MISSING: ir + sink(iovs[0]); // $ast,ir + sink(*iovs); // $ast,ir char* p = (char*)iovs[1].iov_base; - sink(p); // $ MISSING: ast,ir - sink(*p); // $ MISSING: ast,ir + sink(p); // $ ir MISSING: ast + sink(*p); // $ ir MISSING: ast writev(0, iovs, 16); // $ remote } diff --git a/cpp/ql/test/library-tests/dataflow/DefaultTaintTracking/annotate_sinks_only/stl.cpp b/cpp/ql/test/library-tests/dataflow/DefaultTaintTracking/annotate_sinks_only/stl.cpp index e2f5d3b16bd..8a15071ef3c 100644 --- a/cpp/ql/test/library-tests/dataflow/DefaultTaintTracking/annotate_sinks_only/stl.cpp +++ b/cpp/ql/test/library-tests/dataflow/DefaultTaintTracking/annotate_sinks_only/stl.cpp @@ -73,7 +73,7 @@ void test_string() sink(b); // clean sink(c); // $ ir MISSING: ast sink(b.c_str()); // clean - sink(c.c_str()); // $ MISSING: ast,ir + sink(c.c_str()); // $ ir MISSING: ast } void test_stringstream() @@ -93,10 +93,10 @@ void test_stringstream() sink(ss4); // $ ir MISSING: ast sink(ss5); // $ ir MISSING: ast sink(ss1.str()); - sink(ss2.str()); // $ MISSING: ast,ir + sink(ss2.str()); // $ ir MISSING: ast sink(ss3.str()); // $ MISSING: ast,ir - sink(ss4.str()); // $ MISSING: ast,ir - sink(ss5.str()); // $ MISSING: ast,ir + sink(ss4.str()); // $ ir MISSING: ast + sink(ss5.str()); // $ ir MISSING: ast } void test_stringstream_int(int source) @@ -123,14 +123,14 @@ void sink(const char *filename, const char *mode); void test_strings2() { string path1 = user_input(); - sink(path1.c_str(), "r"); // $ MISSING: ast,ir + sink(path1.c_str(), "r"); // $ ir MISSING: ast string path2; path2 = user_input(); - sink(path2.c_str(), "r"); // $ MISSING: ast,ir + sink(path2.c_str(), "r"); // $ ir MISSING: ast string path3(user_input()); - sink(path3.c_str(), "r"); // $ MISSING: ast,ir + sink(path3.c_str(), "r"); // $ ir MISSING: ast } void test_string3() @@ -154,6 +154,6 @@ void test_string4() // convert back std::string -> char * cs = ss.c_str(); - sink(cs); // $ ast MISSING: ir + sink(cs); // $ ast,ir sink(ss); // $ ir MISSING: ast } diff --git a/cpp/ql/test/library-tests/dataflow/DefaultTaintTracking/annotate_sinks_only/tainted.ql b/cpp/ql/test/library-tests/dataflow/DefaultTaintTracking/annotate_sinks_only/tainted.ql index d6ddf93bf49..5784906862b 100644 --- a/cpp/ql/test/library-tests/dataflow/DefaultTaintTracking/annotate_sinks_only/tainted.ql +++ b/cpp/ql/test/library-tests/dataflow/DefaultTaintTracking/annotate_sinks_only/tainted.ql @@ -7,9 +7,10 @@ import cpp import semmle.code.cpp.security.TaintTrackingImpl as ASTTaintTracking import semmle.code.cpp.ir.dataflow.DefaultTaintTracking as IRDefaultTaintTracking +import IRDefaultTaintTracking::TaintedWithPath as TaintedWithPath import TestUtilities.InlineExpectationsTest -predicate isSink(Element sink) { +predicate argToSinkCall(Element sink) { exists(FunctionCall call | call.getTarget().getName() = "sink" and sink = call.getAnArgument() @@ -17,11 +18,15 @@ predicate isSink(Element sink) { } predicate astTaint(Expr source, Element sink) { - ASTTaintTracking::tainted(source, sink) and isSink(sink) + ASTTaintTracking::tainted(source, sink) and argToSinkCall(sink) +} + +class SourceConfiguration extends TaintedWithPath::TaintTrackingConfiguration { + override predicate isSink(Element e) { argToSinkCall(e) } } predicate irTaint(Expr source, Element sink) { - IRDefaultTaintTracking::tainted(source, sink) and isSink(sink) + TaintedWithPath::taintedWithPath(source, sink, _, _) } class IRDefaultTaintTrackingTest extends InlineExpectationsTest { diff --git a/cpp/ql/test/library-tests/dataflow/dataflow-tests/dataflow-ir-consistency.expected b/cpp/ql/test/library-tests/dataflow/dataflow-tests/dataflow-ir-consistency.expected index fc6c97aa2a6..db9a86fbb57 100644 --- a/cpp/ql/test/library-tests/dataflow/dataflow-tests/dataflow-ir-consistency.expected +++ b/cpp/ql/test/library-tests/dataflow/dataflow-tests/dataflow-ir-consistency.expected @@ -26,6 +26,7 @@ unreachableNodeCCtx localCallNodes postIsNotPre postHasUniquePre +| test.cpp:373:5:373:20 | Store | PostUpdateNode should have one pre-update node but has 0. | uniquePostUpdate postIsInSameCallable reverseRead @@ -82,4 +83,5 @@ postWithInFlow | test.cpp:125:3:125:11 | Chi | PostUpdateNode should not be the target of local flow. | | test.cpp:359:5:359:20 | Chi | PostUpdateNode should not be the target of local flow. | | test.cpp:373:5:373:20 | Chi | PostUpdateNode should not be the target of local flow. | +| test.cpp:373:5:373:20 | Store | PostUpdateNode should not be the target of local flow. | | test.cpp:465:3:465:15 | Chi | PostUpdateNode should not be the target of local flow. | diff --git a/cpp/ql/test/library-tests/dataflow/fields/dataflow-ir-consistency.expected b/cpp/ql/test/library-tests/dataflow/fields/dataflow-ir-consistency.expected index 63d3b2c0f48..fe7d8360403 100644 --- a/cpp/ql/test/library-tests/dataflow/fields/dataflow-ir-consistency.expected +++ b/cpp/ql/test/library-tests/dataflow/fields/dataflow-ir-consistency.expected @@ -20,7 +20,9 @@ unreachableNodeCCtx localCallNodes postIsNotPre postHasUniquePre +| D.cpp:57:5:57:42 | Store | PostUpdateNode should have one pre-update node but has 0. | | simple.cpp:65:5:65:22 | Store | PostUpdateNode should have one pre-update node but has 0. | +| simple.cpp:83:9:83:28 | Store | PostUpdateNode should have one pre-update node but has 0. | | simple.cpp:92:5:92:22 | Store | PostUpdateNode should have one pre-update node but has 0. | uniquePostUpdate postIsInSameCallable @@ -54,6 +56,7 @@ postWithInFlow | D.cpp:49:15:49:24 | Chi | PostUpdateNode should not be the target of local flow. | | D.cpp:56:15:56:24 | Chi | PostUpdateNode should not be the target of local flow. | | D.cpp:57:5:57:42 | Chi | PostUpdateNode should not be the target of local flow. | +| D.cpp:57:5:57:42 | Store | PostUpdateNode should not be the target of local flow. | | aliasing.cpp:9:3:9:22 | Chi | PostUpdateNode should not be the target of local flow. | | aliasing.cpp:13:3:13:21 | Chi | PostUpdateNode should not be the target of local flow. | | aliasing.cpp:17:3:17:21 | Chi | PostUpdateNode should not be the target of local flow. | @@ -150,6 +153,7 @@ postWithInFlow | simple.cpp:23:35:23:35 | Chi | PostUpdateNode should not be the target of local flow. | | simple.cpp:65:5:65:22 | Store | PostUpdateNode should not be the target of local flow. | | simple.cpp:83:9:83:28 | Chi | PostUpdateNode should not be the target of local flow. | +| simple.cpp:83:9:83:28 | Store | PostUpdateNode should not be the target of local flow. | | simple.cpp:92:5:92:22 | Store | PostUpdateNode should not be the target of local flow. | | struct_init.c:20:20:20:29 | Chi | PostUpdateNode should not be the target of local flow. | | struct_init.c:20:34:20:34 | Chi | PostUpdateNode should not be the target of local flow. | diff --git a/cpp/ql/test/library-tests/dataflow/fields/ir-path-flow.expected b/cpp/ql/test/library-tests/dataflow/fields/ir-path-flow.expected index 37a0dc3832a..e6234ca17f7 100644 --- a/cpp/ql/test/library-tests/dataflow/fields/ir-path-flow.expected +++ b/cpp/ql/test/library-tests/dataflow/fields/ir-path-flow.expected @@ -228,8 +228,8 @@ edges | simple.cpp:65:5:65:22 | Store [i] | simple.cpp:66:12:66:12 | Store [i] | | simple.cpp:65:11:65:20 | call to user_input | simple.cpp:65:5:65:22 | Store [i] | | simple.cpp:66:12:66:12 | Store [i] | simple.cpp:67:13:67:13 | i | -| simple.cpp:83:9:83:28 | Chi [f1] | simple.cpp:84:14:84:20 | this indirection [f1] | -| simple.cpp:83:17:83:26 | call to user_input | simple.cpp:83:9:83:28 | Chi [f1] | +| simple.cpp:83:9:83:28 | Store [f1] | simple.cpp:84:14:84:20 | this indirection [f1] | +| simple.cpp:83:17:83:26 | call to user_input | simple.cpp:83:9:83:28 | Store [f1] | | simple.cpp:84:14:84:20 | this indirection [f1] | simple.cpp:84:14:84:20 | call to getf2f1 | | simple.cpp:92:5:92:22 | Store [i] | simple.cpp:93:20:93:20 | Store [i] | | simple.cpp:92:11:92:20 | call to user_input | simple.cpp:92:5:92:22 | Store [i] | @@ -494,7 +494,7 @@ nodes | simple.cpp:65:11:65:20 | call to user_input | semmle.label | call to user_input | | simple.cpp:66:12:66:12 | Store [i] | semmle.label | Store [i] | | simple.cpp:67:13:67:13 | i | semmle.label | i | -| simple.cpp:83:9:83:28 | Chi [f1] | semmle.label | Chi [f1] | +| simple.cpp:83:9:83:28 | Store [f1] | semmle.label | Store [f1] | | simple.cpp:83:17:83:26 | call to user_input | semmle.label | call to user_input | | simple.cpp:84:14:84:20 | call to getf2f1 | semmle.label | call to getf2f1 | | simple.cpp:84:14:84:20 | this indirection [f1] | semmle.label | this indirection [f1] | diff --git a/cpp/ql/test/library-tests/dataflow/fields/partial-definition-diff.ql b/cpp/ql/test/library-tests/dataflow/fields/partial-definition-diff.ql index d8b6b4e0e69..fae4b06da5a 100644 --- a/cpp/ql/test/library-tests/dataflow/fields/partial-definition-diff.ql +++ b/cpp/ql/test/library-tests/dataflow/fields/partial-definition-diff.ql @@ -19,15 +19,19 @@ class IRPartialDefNode extends IRNode { override string toString() { result = n.asPartialDefinition().toString() } } -from Node node, AST::Node astNode, IR::Node irNode, string msg +from Node node, string msg where - node.asIR() = irNode and - exists(irNode.asPartialDefinition()) and - not exists(AST::Node otherNode | otherNode.asPartialDefinition() = irNode.asPartialDefinition()) and + exists(IR::Node irNode, Expr partial | + node.asIR() = irNode and + partial = irNode.asPartialDefinition() and + not exists(AST::Node otherNode | otherNode.asPartialDefinition() = partial) + ) and msg = "IR only" or - node.asAST() = astNode and - exists(astNode.asPartialDefinition()) and - not exists(IR::Node otherNode | otherNode.asPartialDefinition() = astNode.asPartialDefinition()) and + exists(AST::Node astNode, Expr partial | + node.asAST() = astNode and + partial = astNode.asPartialDefinition() and + not exists(IR::Node otherNode | otherNode.asPartialDefinition() = partial) + ) and msg = "AST only" select node, msg diff --git a/cpp/ql/test/library-tests/dataflow/security-taint/tainted_diff.expected b/cpp/ql/test/library-tests/dataflow/security-taint/tainted_diff.expected index 26441b08ba4..2b1b021716b 100644 --- a/cpp/ql/test/library-tests/dataflow/security-taint/tainted_diff.expected +++ b/cpp/ql/test/library-tests/dataflow/security-taint/tainted_diff.expected @@ -1,19 +1,42 @@ +| test.cpp:23:23:23:28 | call to getenv | test.cpp:8:24:8:25 | s1 | AST only | +| test.cpp:23:23:23:28 | call to getenv | test.cpp:23:14:23:19 | envStr | AST only | +| test.cpp:38:23:38:28 | call to getenv | test.cpp:8:24:8:25 | s1 | AST only | +| test.cpp:38:23:38:28 | call to getenv | test.cpp:38:14:38:19 | envStr | AST only | +| test.cpp:49:23:49:28 | call to getenv | test.cpp:8:24:8:25 | s1 | AST only | +| test.cpp:49:23:49:28 | call to getenv | test.cpp:45:13:45:24 | envStrGlobal | AST only | +| test.cpp:49:23:49:28 | call to getenv | test.cpp:49:14:49:19 | envStr | AST only | | test.cpp:49:23:49:28 | call to getenv | test.cpp:50:15:50:24 | envStr_ptr | AST only | | test.cpp:49:23:49:28 | call to getenv | test.cpp:50:28:50:40 | & ... | AST only | | test.cpp:49:23:49:28 | call to getenv | test.cpp:50:29:50:40 | envStrGlobal | AST only | | test.cpp:49:23:49:28 | call to getenv | test.cpp:52:2:52:12 | * ... | AST only | | test.cpp:49:23:49:28 | call to getenv | test.cpp:52:3:52:12 | envStr_ptr | AST only | +| test.cpp:60:29:60:34 | call to getenv | test.cpp:10:27:10:27 | s | AST only | +| test.cpp:60:29:60:34 | call to getenv | test.cpp:60:18:60:25 | userName | AST only | | test.cpp:68:28:68:33 | call to getenv | test.cpp:11:20:11:21 | s1 | AST only | +| test.cpp:68:28:68:33 | call to getenv | test.cpp:11:36:11:37 | s2 | AST only | | test.cpp:68:28:68:33 | call to getenv | test.cpp:67:7:67:13 | copying | AST only | +| test.cpp:68:28:68:33 | call to getenv | test.cpp:68:17:68:24 | userName | AST only | | test.cpp:68:28:68:33 | call to getenv | test.cpp:69:10:69:13 | copy | AST only | +| test.cpp:68:28:68:33 | call to getenv | test.cpp:70:5:70:10 | call to strcpy | AST only | | test.cpp:68:28:68:33 | call to getenv | test.cpp:70:12:70:15 | copy | AST only | | test.cpp:68:28:68:33 | call to getenv | test.cpp:71:12:71:15 | copy | AST only | +| test.cpp:75:20:75:25 | call to getenv | test.cpp:15:22:15:25 | nptr | AST only | +| test.cpp:83:28:83:33 | call to getenv | test.cpp:8:24:8:25 | s1 | AST only | | test.cpp:83:28:83:33 | call to getenv | test.cpp:11:20:11:21 | s1 | AST only | +| test.cpp:83:28:83:33 | call to getenv | test.cpp:11:36:11:37 | s2 | AST only | +| test.cpp:83:28:83:33 | call to getenv | test.cpp:83:17:83:24 | userName | AST only | | test.cpp:83:28:83:33 | call to getenv | test.cpp:85:8:85:11 | copy | AST only | +| test.cpp:83:28:83:33 | call to getenv | test.cpp:86:2:86:7 | call to strcpy | AST only | | test.cpp:83:28:83:33 | call to getenv | test.cpp:86:9:86:12 | copy | AST only | +| test.cpp:100:12:100:15 | call to gets | test.cpp:98:8:98:14 | pointer | AST only | | test.cpp:100:12:100:15 | call to gets | test.cpp:100:2:100:8 | pointer | AST only | +| test.cpp:100:17:100:22 | buffer | test.cpp:93:18:93:18 | s | AST only | | test.cpp:100:17:100:22 | buffer | test.cpp:97:7:97:12 | buffer | AST only | | test.cpp:100:17:100:22 | buffer | test.cpp:100:17:100:22 | array to pointer conversion | IR only | +| test.cpp:106:28:106:33 | call to getenv | test.cpp:8:24:8:25 | s1 | AST only | | test.cpp:106:28:106:33 | call to getenv | test.cpp:11:20:11:21 | s1 | AST only | +| test.cpp:106:28:106:33 | call to getenv | test.cpp:11:36:11:37 | s2 | AST only | +| test.cpp:106:28:106:33 | call to getenv | test.cpp:106:17:106:24 | userName | AST only | | test.cpp:106:28:106:33 | call to getenv | test.cpp:108:8:108:11 | copy | AST only | +| test.cpp:106:28:106:33 | call to getenv | test.cpp:109:2:109:7 | call to strcpy | AST only | | test.cpp:106:28:106:33 | call to getenv | test.cpp:109:9:109:12 | copy | AST only | diff --git a/cpp/ql/test/library-tests/dataflow/security-taint/tainted_diff.ql b/cpp/ql/test/library-tests/dataflow/security-taint/tainted_diff.ql index 13a1b7b6f3f..37bd9f5437d 100644 --- a/cpp/ql/test/library-tests/dataflow/security-taint/tainted_diff.ql +++ b/cpp/ql/test/library-tests/dataflow/security-taint/tainted_diff.ql @@ -2,14 +2,18 @@ import semmle.code.cpp.security.TaintTrackingImpl as AST import semmle.code.cpp.ir.dataflow.DefaultTaintTracking as IR import cpp +class SourceConfiguration extends IR::TaintedWithPath::TaintTrackingConfiguration { + override predicate isSink(Element e) { any() } +} + from Expr source, Element tainted, string side where AST::taintedIncludingGlobalVars(source, tainted, _) and - not IR::taintedIncludingGlobalVars(source, tainted, _) and + not IR::TaintedWithPath::taintedWithPath(source, tainted, _, _) and not tainted.getLocation().getFile().getExtension() = "h" and side = "AST only" or - IR::taintedIncludingGlobalVars(source, tainted, _) and + IR::TaintedWithPath::taintedWithPath(source, tainted, _, _) and not AST::taintedIncludingGlobalVars(source, tainted, _) and not tainted.getLocation().getFile().getExtension() = "h" and side = "IR only" diff --git a/cpp/ql/test/library-tests/dataflow/security-taint/tainted_ir.expected b/cpp/ql/test/library-tests/dataflow/security-taint/tainted_ir.expected index 50c90bccb2b..fb19ea7fc9f 100644 --- a/cpp/ql/test/library-tests/dataflow/security-taint/tainted_ir.expected +++ b/cpp/ql/test/library-tests/dataflow/security-taint/tainted_ir.expected @@ -1,71 +1,48 @@ -| test.cpp:23:23:23:28 | call to getenv | test.cpp:8:24:8:25 | s1 | | -| test.cpp:23:23:23:28 | call to getenv | test.cpp:23:14:23:19 | envStr | | -| test.cpp:23:23:23:28 | call to getenv | test.cpp:23:23:23:28 | call to getenv | | -| test.cpp:23:23:23:28 | call to getenv | test.cpp:23:23:23:40 | (const char *)... | | -| test.cpp:23:23:23:28 | call to getenv | test.cpp:25:6:25:29 | ! ... | | -| test.cpp:23:23:23:28 | call to getenv | test.cpp:25:7:25:12 | call to strcmp | | -| test.cpp:23:23:23:28 | call to getenv | test.cpp:25:7:25:29 | (bool)... | | -| test.cpp:23:23:23:28 | call to getenv | test.cpp:25:14:25:19 | envStr | | -| test.cpp:23:23:23:28 | call to getenv | test.cpp:29:6:29:28 | ! ... | | -| test.cpp:23:23:23:28 | call to getenv | test.cpp:29:7:29:12 | call to strcmp | | -| test.cpp:23:23:23:28 | call to getenv | test.cpp:29:7:29:28 | (bool)... | | -| test.cpp:23:23:23:28 | call to getenv | test.cpp:29:14:29:19 | envStr | | -| test.cpp:38:23:38:28 | call to getenv | test.cpp:8:24:8:25 | s1 | | -| test.cpp:38:23:38:28 | call to getenv | test.cpp:38:14:38:19 | envStr | | -| test.cpp:38:23:38:28 | call to getenv | test.cpp:38:23:38:28 | call to getenv | | -| test.cpp:38:23:38:28 | call to getenv | test.cpp:38:23:38:40 | (const char *)... | | -| test.cpp:38:23:38:28 | call to getenv | test.cpp:40:14:40:19 | envStr | | -| test.cpp:49:23:49:28 | call to getenv | test.cpp:8:24:8:25 | s1 | | -| test.cpp:49:23:49:28 | call to getenv | test.cpp:45:13:45:24 | envStrGlobal | | -| test.cpp:49:23:49:28 | call to getenv | test.cpp:49:14:49:19 | envStr | | -| test.cpp:49:23:49:28 | call to getenv | test.cpp:49:23:49:28 | call to getenv | | -| test.cpp:49:23:49:28 | call to getenv | test.cpp:49:23:49:40 | (const char *)... | | -| test.cpp:49:23:49:28 | call to getenv | test.cpp:52:16:52:21 | envStr | | -| test.cpp:49:23:49:28 | call to getenv | test.cpp:54:6:54:35 | ! ... | | -| test.cpp:49:23:49:28 | call to getenv | test.cpp:54:7:54:12 | call to strcmp | | -| test.cpp:49:23:49:28 | call to getenv | test.cpp:54:7:54:35 | (bool)... | | -| test.cpp:49:23:49:28 | call to getenv | test.cpp:54:14:54:25 | envStrGlobal | | -| test.cpp:60:29:60:34 | call to getenv | test.cpp:10:27:10:27 | s | | -| test.cpp:60:29:60:34 | call to getenv | test.cpp:60:18:60:25 | userName | | -| test.cpp:60:29:60:34 | call to getenv | test.cpp:60:29:60:34 | call to getenv | | -| test.cpp:60:29:60:34 | call to getenv | test.cpp:60:29:60:47 | (const char *)... | | -| test.cpp:60:29:60:34 | call to getenv | test.cpp:64:25:64:32 | userName | | -| test.cpp:68:28:68:33 | call to getenv | test.cpp:11:36:11:37 | s2 | | -| test.cpp:68:28:68:33 | call to getenv | test.cpp:68:17:68:24 | userName | | -| test.cpp:68:28:68:33 | call to getenv | test.cpp:68:28:68:33 | call to getenv | | -| test.cpp:68:28:68:33 | call to getenv | test.cpp:68:28:68:46 | (const char *)... | | -| test.cpp:68:28:68:33 | call to getenv | test.cpp:70:5:70:10 | call to strcpy | | -| test.cpp:68:28:68:33 | call to getenv | test.cpp:70:18:70:25 | userName | | -| test.cpp:75:20:75:25 | call to getenv | test.cpp:15:22:15:25 | nptr | | -| test.cpp:75:20:75:25 | call to getenv | test.cpp:75:15:75:18 | call to atoi | | -| test.cpp:75:20:75:25 | call to getenv | test.cpp:75:20:75:25 | call to getenv | | -| test.cpp:75:20:75:25 | call to getenv | test.cpp:75:20:75:45 | (const char *)... | | -| test.cpp:83:28:83:33 | call to getenv | test.cpp:8:24:8:25 | s1 | | -| test.cpp:83:28:83:33 | call to getenv | test.cpp:11:36:11:37 | s2 | | -| test.cpp:83:28:83:33 | call to getenv | test.cpp:83:17:83:24 | userName | | -| test.cpp:83:28:83:33 | call to getenv | test.cpp:83:28:83:33 | call to getenv | | -| test.cpp:83:28:83:33 | call to getenv | test.cpp:83:28:83:46 | (const char *)... | | -| test.cpp:83:28:83:33 | call to getenv | test.cpp:86:2:86:7 | call to strcpy | | -| test.cpp:83:28:83:33 | call to getenv | test.cpp:86:15:86:22 | userName | | -| test.cpp:83:28:83:33 | call to getenv | test.cpp:88:6:88:27 | ! ... | | -| test.cpp:83:28:83:33 | call to getenv | test.cpp:88:7:88:12 | call to strcmp | | -| test.cpp:83:28:83:33 | call to getenv | test.cpp:88:7:88:27 | (bool)... | | -| test.cpp:83:28:83:33 | call to getenv | test.cpp:88:14:88:17 | (const char *)... | | -| test.cpp:83:28:83:33 | call to getenv | test.cpp:88:14:88:17 | copy | | -| test.cpp:100:12:100:15 | call to gets | test.cpp:98:8:98:14 | pointer | | -| test.cpp:100:12:100:15 | call to gets | test.cpp:100:12:100:15 | call to gets | | -| test.cpp:100:17:100:22 | buffer | test.cpp:93:18:93:18 | s | | -| test.cpp:100:17:100:22 | buffer | test.cpp:100:17:100:22 | array to pointer conversion | | -| test.cpp:100:17:100:22 | buffer | test.cpp:100:17:100:22 | buffer | | -| test.cpp:106:28:106:33 | call to getenv | test.cpp:8:24:8:25 | s1 | | -| test.cpp:106:28:106:33 | call to getenv | test.cpp:11:36:11:37 | s2 | | -| test.cpp:106:28:106:33 | call to getenv | test.cpp:106:17:106:24 | userName | | -| test.cpp:106:28:106:33 | call to getenv | test.cpp:106:28:106:33 | call to getenv | | -| test.cpp:106:28:106:33 | call to getenv | test.cpp:106:28:106:46 | (const char *)... | | -| test.cpp:106:28:106:33 | call to getenv | test.cpp:109:2:109:7 | call to strcpy | | -| test.cpp:106:28:106:33 | call to getenv | test.cpp:109:15:109:22 | userName | | -| test.cpp:106:28:106:33 | call to getenv | test.cpp:111:6:111:27 | ! ... | | -| test.cpp:106:28:106:33 | call to getenv | test.cpp:111:7:111:12 | call to strcmp | | -| test.cpp:106:28:106:33 | call to getenv | test.cpp:111:7:111:27 | (bool)... | | -| test.cpp:106:28:106:33 | call to getenv | test.cpp:111:14:111:17 | (const char *)... | | -| test.cpp:106:28:106:33 | call to getenv | test.cpp:111:14:111:17 | copy | | +| test.cpp:23:23:23:28 | call to getenv | test.cpp:23:23:23:28 | call to getenv | +| test.cpp:23:23:23:28 | call to getenv | test.cpp:23:23:23:40 | (const char *)... | +| test.cpp:23:23:23:28 | call to getenv | test.cpp:25:6:25:29 | ! ... | +| test.cpp:23:23:23:28 | call to getenv | test.cpp:25:7:25:12 | call to strcmp | +| test.cpp:23:23:23:28 | call to getenv | test.cpp:25:7:25:29 | (bool)... | +| test.cpp:23:23:23:28 | call to getenv | test.cpp:25:14:25:19 | envStr | +| test.cpp:23:23:23:28 | call to getenv | test.cpp:29:6:29:28 | ! ... | +| test.cpp:23:23:23:28 | call to getenv | test.cpp:29:7:29:12 | call to strcmp | +| test.cpp:23:23:23:28 | call to getenv | test.cpp:29:7:29:28 | (bool)... | +| test.cpp:23:23:23:28 | call to getenv | test.cpp:29:14:29:19 | envStr | +| test.cpp:38:23:38:28 | call to getenv | test.cpp:38:23:38:28 | call to getenv | +| test.cpp:38:23:38:28 | call to getenv | test.cpp:38:23:38:40 | (const char *)... | +| test.cpp:38:23:38:28 | call to getenv | test.cpp:40:14:40:19 | envStr | +| test.cpp:49:23:49:28 | call to getenv | test.cpp:49:23:49:28 | call to getenv | +| test.cpp:49:23:49:28 | call to getenv | test.cpp:49:23:49:40 | (const char *)... | +| test.cpp:49:23:49:28 | call to getenv | test.cpp:52:16:52:21 | envStr | +| test.cpp:49:23:49:28 | call to getenv | test.cpp:54:6:54:35 | ! ... | +| test.cpp:49:23:49:28 | call to getenv | test.cpp:54:7:54:12 | call to strcmp | +| test.cpp:49:23:49:28 | call to getenv | test.cpp:54:7:54:35 | (bool)... | +| test.cpp:49:23:49:28 | call to getenv | test.cpp:54:14:54:25 | envStrGlobal | +| test.cpp:60:29:60:34 | call to getenv | test.cpp:60:29:60:34 | call to getenv | +| test.cpp:60:29:60:34 | call to getenv | test.cpp:60:29:60:47 | (const char *)... | +| test.cpp:60:29:60:34 | call to getenv | test.cpp:64:25:64:32 | userName | +| test.cpp:68:28:68:33 | call to getenv | test.cpp:68:28:68:33 | call to getenv | +| test.cpp:68:28:68:33 | call to getenv | test.cpp:68:28:68:46 | (const char *)... | +| test.cpp:68:28:68:33 | call to getenv | test.cpp:70:18:70:25 | userName | +| test.cpp:75:20:75:25 | call to getenv | test.cpp:75:15:75:18 | call to atoi | +| test.cpp:75:20:75:25 | call to getenv | test.cpp:75:20:75:25 | call to getenv | +| test.cpp:75:20:75:25 | call to getenv | test.cpp:75:20:75:45 | (const char *)... | +| test.cpp:83:28:83:33 | call to getenv | test.cpp:83:28:83:33 | call to getenv | +| test.cpp:83:28:83:33 | call to getenv | test.cpp:83:28:83:46 | (const char *)... | +| test.cpp:83:28:83:33 | call to getenv | test.cpp:86:15:86:22 | userName | +| test.cpp:83:28:83:33 | call to getenv | test.cpp:88:6:88:27 | ! ... | +| test.cpp:83:28:83:33 | call to getenv | test.cpp:88:7:88:12 | call to strcmp | +| test.cpp:83:28:83:33 | call to getenv | test.cpp:88:7:88:27 | (bool)... | +| test.cpp:83:28:83:33 | call to getenv | test.cpp:88:14:88:17 | (const char *)... | +| test.cpp:83:28:83:33 | call to getenv | test.cpp:88:14:88:17 | copy | +| test.cpp:100:12:100:15 | call to gets | test.cpp:100:12:100:15 | call to gets | +| test.cpp:100:17:100:22 | buffer | test.cpp:100:17:100:22 | array to pointer conversion | +| test.cpp:100:17:100:22 | buffer | test.cpp:100:17:100:22 | buffer | +| test.cpp:106:28:106:33 | call to getenv | test.cpp:106:28:106:33 | call to getenv | +| test.cpp:106:28:106:33 | call to getenv | test.cpp:106:28:106:46 | (const char *)... | +| test.cpp:106:28:106:33 | call to getenv | test.cpp:109:15:109:22 | userName | +| test.cpp:106:28:106:33 | call to getenv | test.cpp:111:6:111:27 | ! ... | +| test.cpp:106:28:106:33 | call to getenv | test.cpp:111:7:111:12 | call to strcmp | +| test.cpp:106:28:106:33 | call to getenv | test.cpp:111:7:111:27 | (bool)... | +| test.cpp:106:28:106:33 | call to getenv | test.cpp:111:14:111:17 | (const char *)... | +| test.cpp:106:28:106:33 | call to getenv | test.cpp:111:14:111:17 | copy | diff --git a/cpp/ql/test/library-tests/dataflow/security-taint/tainted_ir.ql b/cpp/ql/test/library-tests/dataflow/security-taint/tainted_ir.ql index 6d8effe7ffe..2a07e444cf9 100644 --- a/cpp/ql/test/library-tests/dataflow/security-taint/tainted_ir.ql +++ b/cpp/ql/test/library-tests/dataflow/security-taint/tainted_ir.ql @@ -1,7 +1,11 @@ import semmle.code.cpp.ir.dataflow.DefaultTaintTracking -from Expr source, Element tainted, string globalVar +class SourceConfiguration extends TaintedWithPath::TaintTrackingConfiguration { + override predicate isSink(Element e) { any() } +} + +from Expr source, Element tainted where - taintedIncludingGlobalVars(source, tainted, globalVar) and + TaintedWithPath::taintedWithPath(source, tainted, _, _) and not tainted.getLocation().getFile().getExtension() = "h" -select source, tainted, globalVar +select source, tainted diff --git a/cpp/ql/test/library-tests/dataflow/smart-pointers-taint/memory.h b/cpp/ql/test/library-tests/dataflow/smart-pointers-taint/memory.h new file mode 100644 index 00000000000..79f39b831c6 --- /dev/null +++ b/cpp/ql/test/library-tests/dataflow/smart-pointers-taint/memory.h @@ -0,0 +1,127 @@ + +namespace std { + namespace detail { + template + class compressed_pair_element { + T element; + + public: + compressed_pair_element() = default; + compressed_pair_element(const T& t) : element(t) {} + + T& get() { return element; } + + const T& get() const { return element; } + }; + + template + struct compressed_pair : private compressed_pair_element, private compressed_pair_element { + compressed_pair() = default; + compressed_pair(T& t) : compressed_pair_element(t), compressed_pair_element() {} + compressed_pair(const compressed_pair&) = delete; + compressed_pair(compressed_pair&&) noexcept = default; + + T& first() { return static_cast&>(*this).get(); } + U& second() { return static_cast&>(*this).get(); } + + const T& first() const { return static_cast&>(*this).get(); } + const U& second() const { return static_cast&>(*this).get(); } + }; + } + + template + struct default_delete { + void operator()(T* ptr) const { delete ptr; } + }; + + template + struct default_delete { + template + void operator()(U* ptr) const { delete[] ptr; } + }; + + template > + class unique_ptr { + private: + detail::compressed_pair data; + public: + constexpr unique_ptr() noexcept {} + explicit unique_ptr(T* ptr) noexcept : data(ptr) {} + unique_ptr(const unique_ptr& ptr) = delete; + unique_ptr(unique_ptr&& ptr) noexcept = default; + + unique_ptr& operator=(unique_ptr&& ptr) noexcept = default; + + T& operator*() const { return *get(); } + T* operator->() const noexcept { return get(); } + + T* get() const noexcept { return data.first(); } + + ~unique_ptr() { + Deleter& d = data.second(); + d(data.first()); + } + }; + + template unique_ptr make_unique(Args&&... args) { + return unique_ptr(new T(args...)); // std::forward calls elided for simplicity. + } + + class ctrl_block { + unsigned uses; + + public: + ctrl_block() : uses(1) {} + + void inc() { ++uses; } + bool dec() { return --uses == 0; } + + virtual void destroy() = 0; + virtual ~ctrl_block() {} + }; + + template > + struct ctrl_block_impl: public ctrl_block { + T* ptr; + Deleter d; + + ctrl_block_impl(T* ptr, Deleter d) : ptr(ptr), d(d) {} + virtual void destroy() override { d(ptr); } + }; + + template + class shared_ptr { + private: + ctrl_block* ctrl; + T* ptr; + + void dec() { + if(ctrl->dec()) { + ctrl->destroy(); + delete ctrl; + } + } + + void inc() { + ctrl->inc(); + } + + public: + constexpr shared_ptr() noexcept = default; + shared_ptr(T* ptr) : ctrl(new ctrl_block_impl(ptr, default_delete())) {} + shared_ptr(const shared_ptr& s) noexcept : ptr(s.ptr), ctrl(s.ctrl) { + inc(); + } + shared_ptr(shared_ptr&& s) noexcept = default; + + T* operator->() const { return ptr; } + + T& operator*() const { return *ptr; } + + ~shared_ptr() { dec(); } + }; + + template shared_ptr make_shared(Args&&... args) { + return shared_ptr(new T(args...)); // std::forward calls elided for simplicity. + } +} \ No newline at end of file diff --git a/csharp/ql/test/query-tests/Security Features/CWE-937/Program.cs b/cpp/ql/test/library-tests/dataflow/smart-pointers-taint/taint.expected similarity index 100% rename from csharp/ql/test/query-tests/Security Features/CWE-937/Program.cs rename to cpp/ql/test/library-tests/dataflow/smart-pointers-taint/taint.expected diff --git a/cpp/ql/test/library-tests/dataflow/smart-pointers-taint/taint.ql b/cpp/ql/test/library-tests/dataflow/smart-pointers-taint/taint.ql new file mode 100644 index 00000000000..4f18139b2af --- /dev/null +++ b/cpp/ql/test/library-tests/dataflow/smart-pointers-taint/taint.ql @@ -0,0 +1,39 @@ +import TestUtilities.dataflow.FlowTestCommon + +module ASTTest { + private import semmle.code.cpp.dataflow.TaintTracking + + class ASTSmartPointerTaintConfig extends TaintTracking::Configuration { + ASTSmartPointerTaintConfig() { this = "ASTSmartPointerTaintConfig" } + + override predicate isSource(DataFlow::Node source) { + source.asExpr().(FunctionCall).getTarget().getName() = "source" + } + + override predicate isSink(DataFlow::Node sink) { + exists(FunctionCall call | + call.getTarget().getName() = "sink" and + sink.asExpr() = call.getAnArgument() + ) + } + } +} + +module IRTest { + private import semmle.code.cpp.ir.dataflow.TaintTracking + + class IRSmartPointerTaintConfig extends TaintTracking::Configuration { + IRSmartPointerTaintConfig() { this = "IRSmartPointerTaintConfig" } + + override predicate isSource(DataFlow::Node source) { + source.asExpr().(FunctionCall).getTarget().getName() = "source" + } + + override predicate isSink(DataFlow::Node sink) { + exists(FunctionCall call | + call.getTarget().getName() = "sink" and + sink.asExpr() = call.getAnArgument() + ) + } + } +} diff --git a/cpp/ql/test/library-tests/dataflow/smart-pointers-taint/test.cpp b/cpp/ql/test/library-tests/dataflow/smart-pointers-taint/test.cpp new file mode 100644 index 00000000000..0dbbd7a2384 --- /dev/null +++ b/cpp/ql/test/library-tests/dataflow/smart-pointers-taint/test.cpp @@ -0,0 +1,46 @@ +#include "memory.h" + +int source(); +void sink(int); + +void test_unique_ptr_int() { + std::unique_ptr p1(new int(source())); + std::unique_ptr p2 = std::make_unique(source()); + + sink(*p1); // $ MISSING: ast,ir + sink(*p2); // $ ast ir=8:50 +} + +struct A { + int x, y; + + A(int x, int y) : x(x), y(y) {} +}; + +void test_unique_ptr_struct() { + std::unique_ptr p1(new A{source(), 0}); + std::unique_ptr p2 = std::make_unique(source(), 0); + + sink(p1->x); // $ MISSING: ast,ir + sink(p1->y); + sink(p2->x); // $ MISSING: ast,ir + sink(p2->y); +} + +void test_shared_ptr_int() { + std::shared_ptr p1(new int(source())); + std::shared_ptr p2 = std::make_shared(source()); + + sink(*p1); // $ ast + sink(*p2); // $ ast ir=32:50 +} + +void test_shared_ptr_struct() { + std::shared_ptr p1(new A{source(), 0}); + std::shared_ptr p2 = std::make_shared(source(), 0); + + sink(p1->x); // $ MISSING: ast,ir + sink(p1->y); + sink(p2->x); // $ MISSING: ast,ir + sink(p2->y); +} \ No newline at end of file diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/bsd.cpp b/cpp/ql/test/library-tests/dataflow/taint-tests/bsd.cpp index 4846420a5a5..fe138a8d8fc 100644 --- a/cpp/ql/test/library-tests/dataflow/taint-tests/bsd.cpp +++ b/cpp/ql/test/library-tests/dataflow/taint-tests/bsd.cpp @@ -19,6 +19,6 @@ void test_accept() { int size = sizeof(sockaddr); int a = accept(s, &addr, &size); - sink(a); // $ ast=17:11 SPURIOUS: ast=18:12 MISSING: ir - sink(addr); // $ ast MISSING: ir + sink(a); // $ ast=17:11 ir SPURIOUS: ast=18:12 + sink(addr); // $ ast,ir } diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/localTaint.expected b/cpp/ql/test/library-tests/dataflow/taint-tests/localTaint.expected index 4444ea13267..b003dc5a12b 100644 --- a/cpp/ql/test/library-tests/dataflow/taint-tests/localTaint.expected +++ b/cpp/ql/test/library-tests/dataflow/taint-tests/localTaint.expected @@ -3223,52 +3223,224 @@ | smart_pointer.cpp:11:30:11:50 | call to make_shared | smart_pointer.cpp:12:11:12:11 | p | | | smart_pointer.cpp:11:30:11:50 | call to make_shared | smart_pointer.cpp:13:10:13:10 | p | | | smart_pointer.cpp:11:52:11:57 | call to source | smart_pointer.cpp:11:30:11:50 | call to make_shared | TAINT | -| smart_pointer.cpp:12:11:12:11 | p | smart_pointer.cpp:12:10:12:10 | call to operator* | TAINT | +| smart_pointer.cpp:12:11:12:11 | p | smart_pointer.cpp:12:10:12:10 | call to operator* | | | smart_pointer.cpp:12:11:12:11 | ref arg p | smart_pointer.cpp:13:10:13:10 | p | | | smart_pointer.cpp:17:32:17:54 | call to make_shared | smart_pointer.cpp:18:11:18:11 | p | | | smart_pointer.cpp:17:32:17:54 | call to make_shared | smart_pointer.cpp:19:10:19:10 | p | | +| smart_pointer.cpp:18:10:18:10 | ref arg call to operator* | smart_pointer.cpp:18:11:18:11 | p [inner post update] | | +| smart_pointer.cpp:18:10:18:10 | ref arg call to operator* | smart_pointer.cpp:19:10:19:10 | p | | | smart_pointer.cpp:18:11:18:11 | p | smart_pointer.cpp:18:10:18:10 | call to operator* | TAINT | +| smart_pointer.cpp:18:11:18:11 | ref arg p | smart_pointer.cpp:18:11:18:11 | p [inner post update] | | | smart_pointer.cpp:18:11:18:11 | ref arg p | smart_pointer.cpp:19:10:19:10 | p | | | smart_pointer.cpp:23:30:23:50 | call to make_unique | smart_pointer.cpp:24:11:24:11 | p | | | smart_pointer.cpp:23:30:23:50 | call to make_unique | smart_pointer.cpp:25:10:25:10 | p | | | smart_pointer.cpp:23:52:23:57 | call to source | smart_pointer.cpp:23:30:23:50 | call to make_unique | TAINT | -| smart_pointer.cpp:24:11:24:11 | p | smart_pointer.cpp:24:10:24:10 | call to operator* | TAINT | +| smart_pointer.cpp:24:11:24:11 | p | smart_pointer.cpp:24:10:24:10 | call to operator* | | | smart_pointer.cpp:24:11:24:11 | ref arg p | smart_pointer.cpp:25:10:25:10 | p | | | smart_pointer.cpp:29:32:29:54 | call to make_unique | smart_pointer.cpp:30:11:30:11 | p | | | smart_pointer.cpp:29:32:29:54 | call to make_unique | smart_pointer.cpp:31:10:31:10 | p | | +| smart_pointer.cpp:30:10:30:10 | ref arg call to operator* | smart_pointer.cpp:30:11:30:11 | p [inner post update] | | +| smart_pointer.cpp:30:10:30:10 | ref arg call to operator* | smart_pointer.cpp:31:10:31:10 | p | | | smart_pointer.cpp:30:11:30:11 | p | smart_pointer.cpp:30:10:30:10 | call to operator* | TAINT | +| smart_pointer.cpp:30:11:30:11 | ref arg p | smart_pointer.cpp:30:11:30:11 | p [inner post update] | | | smart_pointer.cpp:30:11:30:11 | ref arg p | smart_pointer.cpp:31:10:31:10 | p | | | smart_pointer.cpp:35:30:35:50 | call to make_shared | smart_pointer.cpp:37:6:37:6 | p | | | smart_pointer.cpp:35:30:35:50 | call to make_shared | smart_pointer.cpp:38:10:38:10 | p | | | smart_pointer.cpp:35:30:35:50 | call to make_shared | smart_pointer.cpp:39:11:39:11 | p | | +| smart_pointer.cpp:37:5:37:5 | call to operator* [post update] | smart_pointer.cpp:37:6:37:6 | p [inner post update] | | +| smart_pointer.cpp:37:5:37:5 | call to operator* [post update] | smart_pointer.cpp:38:10:38:10 | p | | +| smart_pointer.cpp:37:5:37:5 | call to operator* [post update] | smart_pointer.cpp:39:11:39:11 | p | | | smart_pointer.cpp:37:5:37:17 | ... = ... | smart_pointer.cpp:37:5:37:5 | call to operator* [post update] | | -| smart_pointer.cpp:37:6:37:6 | p | smart_pointer.cpp:37:5:37:5 | call to operator* | TAINT | +| smart_pointer.cpp:37:6:37:6 | p | smart_pointer.cpp:37:5:37:5 | call to operator* | | +| smart_pointer.cpp:37:6:37:6 | ref arg p | smart_pointer.cpp:37:6:37:6 | p [inner post update] | | | smart_pointer.cpp:37:6:37:6 | ref arg p | smart_pointer.cpp:38:10:38:10 | p | | | smart_pointer.cpp:37:6:37:6 | ref arg p | smart_pointer.cpp:39:11:39:11 | p | | | smart_pointer.cpp:37:10:37:15 | call to source | smart_pointer.cpp:37:5:37:17 | ... = ... | | | smart_pointer.cpp:38:10:38:10 | ref arg p | smart_pointer.cpp:39:11:39:11 | p | | -| smart_pointer.cpp:39:11:39:11 | p | smart_pointer.cpp:39:10:39:10 | call to operator* | TAINT | +| smart_pointer.cpp:39:11:39:11 | p | smart_pointer.cpp:39:10:39:10 | call to operator* | | | smart_pointer.cpp:43:29:43:51 | call to unique_ptr | smart_pointer.cpp:45:6:45:6 | p | | | smart_pointer.cpp:43:29:43:51 | call to unique_ptr | smart_pointer.cpp:46:10:46:10 | p | | | smart_pointer.cpp:43:29:43:51 | call to unique_ptr | smart_pointer.cpp:47:11:47:11 | p | | +| smart_pointer.cpp:45:5:45:5 | call to operator* [post update] | smart_pointer.cpp:45:6:45:6 | p [inner post update] | | +| smart_pointer.cpp:45:5:45:5 | call to operator* [post update] | smart_pointer.cpp:46:10:46:10 | p | | +| smart_pointer.cpp:45:5:45:5 | call to operator* [post update] | smart_pointer.cpp:47:11:47:11 | p | | | smart_pointer.cpp:45:5:45:17 | ... = ... | smart_pointer.cpp:45:5:45:5 | call to operator* [post update] | | -| smart_pointer.cpp:45:6:45:6 | p | smart_pointer.cpp:45:5:45:5 | call to operator* | TAINT | +| smart_pointer.cpp:45:6:45:6 | p | smart_pointer.cpp:45:5:45:5 | call to operator* | | +| smart_pointer.cpp:45:6:45:6 | ref arg p | smart_pointer.cpp:45:6:45:6 | p [inner post update] | | | smart_pointer.cpp:45:6:45:6 | ref arg p | smart_pointer.cpp:46:10:46:10 | p | | | smart_pointer.cpp:45:6:45:6 | ref arg p | smart_pointer.cpp:47:11:47:11 | p | | | smart_pointer.cpp:45:10:45:15 | call to source | smart_pointer.cpp:45:5:45:17 | ... = ... | | | smart_pointer.cpp:46:10:46:10 | ref arg p | smart_pointer.cpp:47:11:47:11 | p | | -| smart_pointer.cpp:47:11:47:11 | p | smart_pointer.cpp:47:10:47:10 | call to operator* | TAINT | +| smart_pointer.cpp:47:11:47:11 | p | smart_pointer.cpp:47:10:47:10 | call to operator* | | | smart_pointer.cpp:51:30:51:50 | call to make_shared | smart_pointer.cpp:52:10:52:10 | p | | | smart_pointer.cpp:51:52:51:57 | call to source | smart_pointer.cpp:51:30:51:50 | call to make_shared | TAINT | -| smart_pointer.cpp:52:10:52:10 | p | smart_pointer.cpp:52:12:52:14 | call to get | TAINT | +| smart_pointer.cpp:52:10:52:10 | p | smart_pointer.cpp:52:12:52:14 | call to get | | +| smart_pointer.cpp:52:12:52:14 | ref arg call to get | smart_pointer.cpp:52:10:52:10 | ref arg p | TAINT | | smart_pointer.cpp:56:30:56:50 | call to make_unique | smart_pointer.cpp:57:10:57:10 | p | | | smart_pointer.cpp:56:52:56:57 | call to source | smart_pointer.cpp:56:30:56:50 | call to make_unique | TAINT | -| smart_pointer.cpp:57:10:57:10 | p | smart_pointer.cpp:57:12:57:14 | call to get | TAINT | +| smart_pointer.cpp:57:10:57:10 | p | smart_pointer.cpp:57:12:57:14 | call to get | | +| smart_pointer.cpp:57:12:57:14 | ref arg call to get | smart_pointer.cpp:57:10:57:10 | ref arg p | TAINT | | smart_pointer.cpp:65:28:65:46 | call to make_unique | smart_pointer.cpp:66:10:66:10 | p | | | smart_pointer.cpp:65:28:65:46 | call to make_unique | smart_pointer.cpp:67:10:67:10 | p | | | smart_pointer.cpp:65:48:65:53 | call to source | smart_pointer.cpp:65:28:65:46 | call to make_unique | TAINT | | smart_pointer.cpp:65:58:65:58 | 0 | smart_pointer.cpp:65:28:65:46 | call to make_unique | TAINT | +| smart_pointer.cpp:66:10:66:10 | p | smart_pointer.cpp:66:11:66:11 | call to operator-> | | | smart_pointer.cpp:66:10:66:10 | ref arg p | smart_pointer.cpp:67:10:67:10 | p | | +| smart_pointer.cpp:67:10:67:10 | p | smart_pointer.cpp:67:11:67:11 | call to operator-> | | +| smart_pointer.cpp:70:37:70:39 | ptr | smart_pointer.cpp:70:37:70:39 | ptr | | +| smart_pointer.cpp:70:37:70:39 | ptr | smart_pointer.cpp:71:4:71:6 | ptr | | +| smart_pointer.cpp:71:3:71:3 | call to operator* [post update] | smart_pointer.cpp:70:37:70:39 | ptr | | +| smart_pointer.cpp:71:3:71:3 | call to operator* [post update] | smart_pointer.cpp:71:4:71:6 | ptr [inner post update] | | +| smart_pointer.cpp:71:3:71:17 | ... = ... | smart_pointer.cpp:71:3:71:3 | call to operator* [post update] | | +| smart_pointer.cpp:71:4:71:6 | ptr | smart_pointer.cpp:71:3:71:3 | call to operator* | | +| smart_pointer.cpp:71:4:71:6 | ref arg ptr | smart_pointer.cpp:70:37:70:39 | ptr | | +| smart_pointer.cpp:71:4:71:6 | ref arg ptr | smart_pointer.cpp:71:4:71:6 | ptr [inner post update] | | +| smart_pointer.cpp:71:10:71:15 | call to source | smart_pointer.cpp:71:3:71:17 | ... = ... | | +| smart_pointer.cpp:75:26:75:33 | call to shared_ptr | smart_pointer.cpp:76:13:76:13 | p | | +| smart_pointer.cpp:75:26:75:33 | call to shared_ptr | smart_pointer.cpp:77:9:77:9 | p | | +| smart_pointer.cpp:76:13:76:13 | p | smart_pointer.cpp:76:13:76:13 | call to shared_ptr | | +| smart_pointer.cpp:76:13:76:13 | ref arg call to shared_ptr | smart_pointer.cpp:76:13:76:13 | p [inner post update] | | +| smart_pointer.cpp:76:13:76:13 | ref arg call to shared_ptr | smart_pointer.cpp:77:9:77:9 | p | | +| smart_pointer.cpp:76:13:76:13 | ref arg p | smart_pointer.cpp:76:13:76:13 | p [inner post update] | | +| smart_pointer.cpp:76:13:76:13 | ref arg p | smart_pointer.cpp:77:9:77:9 | p | | +| smart_pointer.cpp:77:9:77:9 | p | smart_pointer.cpp:77:8:77:8 | call to operator* | | +| smart_pointer.cpp:86:45:86:45 | p | smart_pointer.cpp:86:45:86:45 | p | | +| smart_pointer.cpp:86:45:86:45 | p | smart_pointer.cpp:87:3:87:3 | p | | +| smart_pointer.cpp:86:45:86:45 | p | smart_pointer.cpp:88:8:88:8 | p | | +| smart_pointer.cpp:86:45:86:45 | p | smart_pointer.cpp:89:8:89:8 | p | | +| smart_pointer.cpp:86:67:86:67 | q | smart_pointer.cpp:86:67:86:67 | q | | +| smart_pointer.cpp:86:67:86:67 | q | smart_pointer.cpp:91:3:91:3 | q | | +| smart_pointer.cpp:86:67:86:67 | q | smart_pointer.cpp:92:8:92:8 | q | | +| smart_pointer.cpp:86:67:86:67 | q | smart_pointer.cpp:93:8:93:8 | q | | +| smart_pointer.cpp:86:67:86:67 | q | smart_pointer.cpp:94:8:94:8 | q | | +| smart_pointer.cpp:87:3:87:3 | p | smart_pointer.cpp:87:4:87:4 | call to operator-> | | +| smart_pointer.cpp:87:3:87:3 | ref arg p | smart_pointer.cpp:86:45:86:45 | p | | +| smart_pointer.cpp:87:3:87:3 | ref arg p | smart_pointer.cpp:88:8:88:8 | p | | +| smart_pointer.cpp:87:3:87:3 | ref arg p | smart_pointer.cpp:89:8:89:8 | p | | +| smart_pointer.cpp:87:3:87:17 | ... = ... | smart_pointer.cpp:87:6:87:6 | x [post update] | | +| smart_pointer.cpp:87:3:87:17 | ... = ... | smart_pointer.cpp:88:11:88:11 | x | | +| smart_pointer.cpp:87:4:87:4 | call to operator-> [post update] | smart_pointer.cpp:87:3:87:3 | ref arg p | TAINT | +| smart_pointer.cpp:87:10:87:15 | call to source | smart_pointer.cpp:87:3:87:17 | ... = ... | | +| smart_pointer.cpp:88:8:88:8 | p | smart_pointer.cpp:88:9:88:9 | call to operator-> | | +| smart_pointer.cpp:88:8:88:8 | ref arg p | smart_pointer.cpp:86:45:86:45 | p | | +| smart_pointer.cpp:88:8:88:8 | ref arg p | smart_pointer.cpp:89:8:89:8 | p | | +| smart_pointer.cpp:89:8:89:8 | p | smart_pointer.cpp:89:9:89:9 | call to operator-> | | +| smart_pointer.cpp:89:8:89:8 | ref arg p | smart_pointer.cpp:86:45:86:45 | p | | +| smart_pointer.cpp:91:3:91:3 | q | smart_pointer.cpp:91:4:91:4 | call to operator-> | | +| smart_pointer.cpp:91:3:91:3 | ref arg q | smart_pointer.cpp:86:67:86:67 | q | | +| smart_pointer.cpp:91:3:91:3 | ref arg q | smart_pointer.cpp:92:8:92:8 | q | | +| smart_pointer.cpp:91:3:91:3 | ref arg q | smart_pointer.cpp:93:8:93:8 | q | | +| smart_pointer.cpp:91:3:91:3 | ref arg q | smart_pointer.cpp:94:8:94:8 | q | | +| smart_pointer.cpp:91:3:91:20 | ... = ... | smart_pointer.cpp:91:9:91:9 | x [post update] | | +| smart_pointer.cpp:91:3:91:20 | ... = ... | smart_pointer.cpp:92:14:92:14 | x | | +| smart_pointer.cpp:91:4:91:4 | call to operator-> [post update] | smart_pointer.cpp:91:3:91:3 | ref arg q | TAINT | +| smart_pointer.cpp:91:13:91:18 | call to source | smart_pointer.cpp:91:3:91:20 | ... = ... | | +| smart_pointer.cpp:92:8:92:8 | q | smart_pointer.cpp:92:9:92:9 | call to operator-> | | +| smart_pointer.cpp:92:8:92:8 | ref arg q | smart_pointer.cpp:86:67:86:67 | q | | +| smart_pointer.cpp:92:8:92:8 | ref arg q | smart_pointer.cpp:93:8:93:8 | q | | +| smart_pointer.cpp:92:8:92:8 | ref arg q | smart_pointer.cpp:94:8:94:8 | q | | +| smart_pointer.cpp:93:8:93:8 | q | smart_pointer.cpp:93:9:93:9 | call to operator-> | | +| smart_pointer.cpp:93:8:93:8 | ref arg q | smart_pointer.cpp:86:67:86:67 | q | | +| smart_pointer.cpp:93:8:93:8 | ref arg q | smart_pointer.cpp:94:8:94:8 | q | | +| smart_pointer.cpp:94:8:94:8 | q | smart_pointer.cpp:94:9:94:9 | call to operator-> | | +| smart_pointer.cpp:94:8:94:8 | ref arg q | smart_pointer.cpp:86:67:86:67 | q | | +| smart_pointer.cpp:97:17:97:18 | pa | smart_pointer.cpp:98:5:98:6 | pa | | +| smart_pointer.cpp:98:5:98:20 | ... = ... | smart_pointer.cpp:98:9:98:9 | x [post update] | | +| smart_pointer.cpp:98:13:98:18 | call to source | smart_pointer.cpp:98:5:98:20 | ... = ... | | +| smart_pointer.cpp:102:25:102:50 | call to unique_ptr | smart_pointer.cpp:103:11:103:11 | p | | +| smart_pointer.cpp:102:25:102:50 | call to unique_ptr | smart_pointer.cpp:104:8:104:8 | p | | +| smart_pointer.cpp:103:11:103:11 | p | smart_pointer.cpp:103:13:103:15 | call to get | | +| smart_pointer.cpp:103:11:103:11 | ref arg p | smart_pointer.cpp:104:8:104:8 | p | | +| smart_pointer.cpp:103:13:103:15 | ref arg call to get | smart_pointer.cpp:103:11:103:11 | ref arg p | TAINT | +| smart_pointer.cpp:104:8:104:8 | p | smart_pointer.cpp:104:9:104:9 | call to operator-> | | +| smart_pointer.cpp:112:40:112:42 | ptr | smart_pointer.cpp:112:40:112:42 | ptr | | +| smart_pointer.cpp:112:40:112:42 | ptr | smart_pointer.cpp:113:2:113:4 | ptr | | +| smart_pointer.cpp:113:2:113:4 | ptr | smart_pointer.cpp:113:5:113:5 | call to operator-> | | +| smart_pointer.cpp:113:2:113:4 | ref arg ptr | smart_pointer.cpp:112:40:112:42 | ptr | | +| smart_pointer.cpp:113:2:113:18 | ... = ... | smart_pointer.cpp:113:7:113:7 | x [post update] | | +| smart_pointer.cpp:113:5:113:5 | call to operator-> [post update] | smart_pointer.cpp:113:2:113:4 | ref arg ptr | TAINT | +| smart_pointer.cpp:113:11:113:16 | call to source | smart_pointer.cpp:113:2:113:18 | ... = ... | | +| smart_pointer.cpp:116:52:116:54 | ptr | smart_pointer.cpp:116:52:116:54 | ptr | | +| smart_pointer.cpp:116:52:116:54 | ptr | smart_pointer.cpp:117:2:117:4 | ptr | | +| smart_pointer.cpp:117:2:117:4 | ptr | smart_pointer.cpp:117:5:117:5 | call to operator-> | | +| smart_pointer.cpp:117:2:117:4 | ref arg ptr | smart_pointer.cpp:116:52:116:54 | ptr | | +| smart_pointer.cpp:117:2:117:18 | ... = ... | smart_pointer.cpp:117:7:117:7 | x [post update] | | +| smart_pointer.cpp:117:5:117:5 | call to operator-> [post update] | smart_pointer.cpp:117:2:117:4 | ref arg ptr | TAINT | +| smart_pointer.cpp:117:11:117:16 | call to source | smart_pointer.cpp:117:2:117:18 | ... = ... | | +| smart_pointer.cpp:120:48:120:50 | ptr | smart_pointer.cpp:120:48:120:50 | ptr | | +| smart_pointer.cpp:120:48:120:50 | ptr | smart_pointer.cpp:121:4:121:6 | ptr | | +| smart_pointer.cpp:121:3:121:3 | call to operator* [post update] | smart_pointer.cpp:120:48:120:50 | ptr | | +| smart_pointer.cpp:121:3:121:3 | call to operator* [post update] | smart_pointer.cpp:121:4:121:6 | ptr [inner post update] | | +| smart_pointer.cpp:121:3:121:17 | ... = ... | smart_pointer.cpp:121:3:121:3 | call to operator* [post update] | | +| smart_pointer.cpp:121:4:121:6 | ptr | smart_pointer.cpp:121:3:121:3 | call to operator* | | +| smart_pointer.cpp:121:4:121:6 | ref arg ptr | smart_pointer.cpp:120:48:120:50 | ptr | | +| smart_pointer.cpp:121:4:121:6 | ref arg ptr | smart_pointer.cpp:121:4:121:6 | ptr [inner post update] | | +| smart_pointer.cpp:121:10:121:15 | call to source | smart_pointer.cpp:121:3:121:17 | ... = ... | | +| smart_pointer.cpp:124:48:124:49 | p1 | smart_pointer.cpp:124:48:124:49 | p1 | | +| smart_pointer.cpp:124:48:124:49 | p1 | smart_pointer.cpp:125:18:125:19 | p1 | | +| smart_pointer.cpp:124:48:124:49 | p1 | smart_pointer.cpp:126:8:126:9 | p1 | | +| smart_pointer.cpp:124:90:124:91 | p2 | smart_pointer.cpp:124:90:124:91 | p2 | | +| smart_pointer.cpp:124:90:124:91 | p2 | smart_pointer.cpp:128:14:128:15 | p2 | | +| smart_pointer.cpp:124:90:124:91 | p2 | smart_pointer.cpp:129:10:129:11 | p2 | | +| smart_pointer.cpp:125:18:125:19 | p1 | smart_pointer.cpp:125:20:125:20 | call to operator-> | | +| smart_pointer.cpp:125:18:125:19 | ref arg p1 | smart_pointer.cpp:124:48:124:49 | p1 | | +| smart_pointer.cpp:125:18:125:19 | ref arg p1 | smart_pointer.cpp:126:8:126:9 | p1 | | +| smart_pointer.cpp:125:18:125:22 | ref arg call to shared_ptr | smart_pointer.cpp:125:22:125:22 | q [inner post update] | | +| smart_pointer.cpp:125:20:125:20 | call to operator-> [post update] | smart_pointer.cpp:125:18:125:19 | ref arg p1 | TAINT | +| smart_pointer.cpp:125:22:125:22 | q | smart_pointer.cpp:125:18:125:22 | call to shared_ptr | | +| smart_pointer.cpp:125:22:125:22 | ref arg q | smart_pointer.cpp:125:22:125:22 | q [inner post update] | | +| smart_pointer.cpp:126:8:126:9 | p1 | smart_pointer.cpp:126:10:126:10 | call to operator-> | | +| smart_pointer.cpp:126:8:126:9 | ref arg p1 | smart_pointer.cpp:124:48:124:49 | p1 | | +| smart_pointer.cpp:126:10:126:10 | call to operator-> [post update] | smart_pointer.cpp:126:8:126:9 | ref arg p1 | TAINT | +| smart_pointer.cpp:126:12:126:12 | q | smart_pointer.cpp:126:13:126:13 | call to operator-> | | +| smart_pointer.cpp:128:13:128:13 | call to operator* | smart_pointer.cpp:128:13:128:15 | call to shared_ptr | TAINT | +| smart_pointer.cpp:128:13:128:13 | ref arg call to operator* | smart_pointer.cpp:124:90:124:91 | p2 | | +| smart_pointer.cpp:128:13:128:13 | ref arg call to operator* | smart_pointer.cpp:128:13:128:13 | call to operator* [inner post update] | | +| smart_pointer.cpp:128:13:128:13 | ref arg call to operator* | smart_pointer.cpp:128:14:128:15 | p2 [inner post update] | | +| smart_pointer.cpp:128:13:128:13 | ref arg call to operator* | smart_pointer.cpp:129:10:129:11 | p2 | | +| smart_pointer.cpp:128:13:128:15 | ref arg call to shared_ptr | smart_pointer.cpp:124:90:124:91 | p2 | | +| smart_pointer.cpp:128:13:128:15 | ref arg call to shared_ptr | smart_pointer.cpp:128:13:128:13 | call to operator* [inner post update] | | +| smart_pointer.cpp:128:13:128:15 | ref arg call to shared_ptr | smart_pointer.cpp:128:14:128:15 | p2 [inner post update] | | +| smart_pointer.cpp:128:13:128:15 | ref arg call to shared_ptr | smart_pointer.cpp:129:10:129:11 | p2 | | +| smart_pointer.cpp:128:14:128:15 | p2 | smart_pointer.cpp:128:13:128:13 | call to operator* | TAINT | +| smart_pointer.cpp:128:14:128:15 | ref arg p2 | smart_pointer.cpp:124:90:124:91 | p2 | | +| smart_pointer.cpp:128:14:128:15 | ref arg p2 | smart_pointer.cpp:128:14:128:15 | p2 [inner post update] | | +| smart_pointer.cpp:128:14:128:15 | ref arg p2 | smart_pointer.cpp:129:10:129:11 | p2 | | +| smart_pointer.cpp:129:9:129:9 | call to operator* | smart_pointer.cpp:129:8:129:8 | call to operator* | TAINT | +| smart_pointer.cpp:129:9:129:9 | ref arg call to operator* | smart_pointer.cpp:124:90:124:91 | p2 | | +| smart_pointer.cpp:129:9:129:9 | ref arg call to operator* | smart_pointer.cpp:129:10:129:11 | p2 [inner post update] | | +| smart_pointer.cpp:129:10:129:11 | p2 | smart_pointer.cpp:129:8:129:8 | call to operator* | | +| smart_pointer.cpp:129:10:129:11 | p2 | smart_pointer.cpp:129:9:129:9 | call to operator* | TAINT | +| smart_pointer.cpp:129:10:129:11 | ref arg p2 | smart_pointer.cpp:124:90:124:91 | p2 | | +| smart_pointer.cpp:129:10:129:11 | ref arg p2 | smart_pointer.cpp:129:10:129:11 | p2 [inner post update] | | +| smart_pointer.cpp:132:53:132:54 | p1 | smart_pointer.cpp:132:53:132:54 | p1 | | +| smart_pointer.cpp:132:53:132:54 | p1 | smart_pointer.cpp:133:23:133:24 | p1 | | +| smart_pointer.cpp:132:53:132:54 | p1 | smart_pointer.cpp:134:8:134:9 | p1 | | +| smart_pointer.cpp:132:95:132:96 | p2 | smart_pointer.cpp:132:95:132:96 | p2 | | +| smart_pointer.cpp:132:95:132:96 | p2 | smart_pointer.cpp:136:18:136:19 | p2 | | +| smart_pointer.cpp:132:95:132:96 | p2 | smart_pointer.cpp:137:10:137:11 | p2 | | +| smart_pointer.cpp:133:23:133:24 | p1 | smart_pointer.cpp:133:25:133:25 | call to operator-> | | +| smart_pointer.cpp:133:23:133:24 | ref arg p1 | smart_pointer.cpp:132:53:132:54 | p1 | | +| smart_pointer.cpp:133:23:133:24 | ref arg p1 | smart_pointer.cpp:134:8:134:9 | p1 | | +| smart_pointer.cpp:133:25:133:25 | call to operator-> [post update] | smart_pointer.cpp:133:23:133:24 | ref arg p1 | TAINT | +| smart_pointer.cpp:134:8:134:9 | p1 | smart_pointer.cpp:134:10:134:10 | call to operator-> | | +| smart_pointer.cpp:134:8:134:9 | ref arg p1 | smart_pointer.cpp:132:53:132:54 | p1 | | +| smart_pointer.cpp:134:10:134:10 | call to operator-> [post update] | smart_pointer.cpp:134:8:134:9 | ref arg p1 | TAINT | +| smart_pointer.cpp:134:12:134:12 | q | smart_pointer.cpp:134:13:134:13 | call to operator-> | | +| smart_pointer.cpp:136:17:136:17 | ref arg call to operator* | smart_pointer.cpp:132:95:132:96 | p2 | | +| smart_pointer.cpp:136:17:136:17 | ref arg call to operator* | smart_pointer.cpp:136:18:136:19 | p2 [inner post update] | | +| smart_pointer.cpp:136:17:136:17 | ref arg call to operator* | smart_pointer.cpp:137:10:137:11 | p2 | | +| smart_pointer.cpp:136:18:136:19 | p2 | smart_pointer.cpp:136:17:136:17 | call to operator* | TAINT | +| smart_pointer.cpp:136:18:136:19 | ref arg p2 | smart_pointer.cpp:132:95:132:96 | p2 | | +| smart_pointer.cpp:136:18:136:19 | ref arg p2 | smart_pointer.cpp:136:18:136:19 | p2 [inner post update] | | +| smart_pointer.cpp:136:18:136:19 | ref arg p2 | smart_pointer.cpp:137:10:137:11 | p2 | | +| smart_pointer.cpp:137:9:137:9 | call to operator* | smart_pointer.cpp:137:8:137:8 | call to operator* | TAINT | +| smart_pointer.cpp:137:9:137:9 | ref arg call to operator* | smart_pointer.cpp:132:95:132:96 | p2 | | +| smart_pointer.cpp:137:9:137:9 | ref arg call to operator* | smart_pointer.cpp:137:10:137:11 | p2 [inner post update] | | +| smart_pointer.cpp:137:10:137:11 | p2 | smart_pointer.cpp:137:8:137:8 | call to operator* | | +| smart_pointer.cpp:137:10:137:11 | p2 | smart_pointer.cpp:137:9:137:9 | call to operator* | TAINT | +| smart_pointer.cpp:137:10:137:11 | ref arg p2 | smart_pointer.cpp:132:95:132:96 | p2 | | +| smart_pointer.cpp:137:10:137:11 | ref arg p2 | smart_pointer.cpp:137:10:137:11 | p2 [inner post update] | | | standalone_iterators.cpp:39:45:39:51 | source1 | standalone_iterators.cpp:39:45:39:51 | source1 | | | standalone_iterators.cpp:39:45:39:51 | source1 | standalone_iterators.cpp:40:11:40:17 | source1 | | | standalone_iterators.cpp:39:45:39:51 | source1 | standalone_iterators.cpp:41:12:41:18 | source1 | | @@ -3388,125 +3560,125 @@ | stl.h:292:30:292:40 | call to allocator | stl.h:292:21:292:41 | noexcept(...) | TAINT | | stl.h:292:30:292:40 | call to allocator | stl.h:292:21:292:41 | noexcept(...) | TAINT | | stl.h:292:53:292:63 | 0 | stl.h:292:46:292:64 | (no string representation) | TAINT | -| stl.h:388:9:388:9 | Unknown literal | stl.h:388:9:388:9 | constructor init of field first | TAINT | -| stl.h:388:9:388:9 | Unknown literal | stl.h:388:9:388:9 | constructor init of field first | TAINT | -| stl.h:388:9:388:9 | Unknown literal | stl.h:388:9:388:9 | constructor init of field first | TAINT | -| stl.h:388:9:388:9 | Unknown literal | stl.h:388:9:388:9 | constructor init of field first | TAINT | -| stl.h:388:9:388:9 | Unknown literal | stl.h:388:9:388:9 | constructor init of field first | TAINT | -| stl.h:388:9:388:9 | Unknown literal | stl.h:388:9:388:9 | constructor init of field second | TAINT | -| stl.h:388:9:388:9 | Unknown literal | stl.h:388:9:388:9 | constructor init of field second | TAINT | -| stl.h:388:9:388:9 | Unknown literal | stl.h:388:9:388:9 | constructor init of field second | TAINT | -| stl.h:388:9:388:9 | Unknown literal | stl.h:388:9:388:9 | constructor init of field second | TAINT | -| stl.h:388:9:388:9 | Unknown literal | stl.h:388:9:388:9 | constructor init of field second | TAINT | -| stl.h:388:9:388:9 | constructor init of field first [post-this] | stl.h:388:9:388:9 | constructor init of field second [pre-this] | | -| stl.h:388:9:388:9 | constructor init of field first [post-this] | stl.h:388:9:388:9 | constructor init of field second [pre-this] | | -| stl.h:388:9:388:9 | constructor init of field first [post-this] | stl.h:388:9:388:9 | constructor init of field second [pre-this] | | -| stl.h:388:9:388:9 | constructor init of field first [post-this] | stl.h:388:9:388:9 | constructor init of field second [pre-this] | | -| stl.h:388:9:388:9 | constructor init of field first [post-this] | stl.h:388:9:388:9 | constructor init of field second [pre-this] | | -| stl.h:388:9:388:9 | constructor init of field first [pre-this] | stl.h:388:9:388:9 | constructor init of field second [pre-this] | | -| stl.h:388:9:388:9 | constructor init of field first [pre-this] | stl.h:388:9:388:9 | constructor init of field second [pre-this] | | -| stl.h:388:9:388:9 | constructor init of field first [pre-this] | stl.h:388:9:388:9 | constructor init of field second [pre-this] | | -| stl.h:388:9:388:9 | constructor init of field first [pre-this] | stl.h:388:9:388:9 | constructor init of field second [pre-this] | | -| stl.h:388:9:388:9 | constructor init of field first [pre-this] | stl.h:388:9:388:9 | constructor init of field second [pre-this] | | -| stl.h:388:9:388:9 | this | stl.h:388:9:388:9 | constructor init of field first [pre-this] | | -| stl.h:388:9:388:9 | this | stl.h:388:9:388:9 | constructor init of field first [pre-this] | | -| stl.h:388:9:388:9 | this | stl.h:388:9:388:9 | constructor init of field first [pre-this] | | -| stl.h:388:9:388:9 | this | stl.h:388:9:388:9 | constructor init of field first [pre-this] | | -| stl.h:388:9:388:9 | this | stl.h:388:9:388:9 | constructor init of field first [pre-this] | | -| stl.h:395:3:395:3 | this | stl.h:395:36:395:43 | constructor init of field first [pre-this] | | -| stl.h:395:3:395:3 | this | stl.h:395:36:395:43 | constructor init of field first [pre-this] | | -| stl.h:395:3:395:3 | this | stl.h:395:36:395:43 | constructor init of field first [pre-this] | | -| stl.h:395:3:395:3 | this | stl.h:395:36:395:43 | constructor init of field first [pre-this] | | -| stl.h:395:3:395:3 | this | stl.h:395:36:395:43 | constructor init of field first [pre-this] | | -| stl.h:395:3:395:6 | this | stl.h:395:36:395:43 | constructor init of field first [pre-this] | | -| stl.h:395:18:395:18 | x | stl.h:395:42:395:42 | x | | -| stl.h:395:18:395:18 | x | stl.h:395:42:395:42 | x | | -| stl.h:395:18:395:18 | x | stl.h:395:42:395:42 | x | | -| stl.h:395:18:395:18 | x | stl.h:395:42:395:42 | x | | -| stl.h:395:18:395:18 | x | stl.h:395:42:395:42 | x | | -| stl.h:395:18:395:18 | x | stl.h:395:42:395:42 | x | | -| stl.h:395:31:395:31 | y | stl.h:395:53:395:53 | y | | -| stl.h:395:31:395:31 | y | stl.h:395:53:395:53 | y | | -| stl.h:395:31:395:31 | y | stl.h:395:53:395:53 | y | | -| stl.h:395:31:395:31 | y | stl.h:395:53:395:53 | y | | -| stl.h:395:31:395:31 | y | stl.h:395:53:395:53 | y | | -| stl.h:395:31:395:31 | y | stl.h:395:53:395:53 | y | | -| stl.h:395:36:395:43 | call to unknown function | stl.h:395:36:395:43 | constructor init of field first | TAINT | -| stl.h:395:36:395:43 | constructor init of field first [post-this] | stl.h:395:46:395:54 | constructor init of field second [pre-this] | | -| stl.h:395:36:395:43 | constructor init of field first [post-this] | stl.h:395:46:395:54 | constructor init of field second [pre-this] | | -| stl.h:395:36:395:43 | constructor init of field first [post-this] | stl.h:395:46:395:54 | constructor init of field second [pre-this] | | -| stl.h:395:36:395:43 | constructor init of field first [post-this] | stl.h:395:46:395:54 | constructor init of field second [pre-this] | | -| stl.h:395:36:395:43 | constructor init of field first [post-this] | stl.h:395:46:395:54 | constructor init of field second [pre-this] | | -| stl.h:395:36:395:43 | constructor init of field first [post-this] | stl.h:395:46:395:54 | constructor init of field second [pre-this] | | -| stl.h:395:36:395:43 | constructor init of field first [pre-this] | stl.h:395:46:395:54 | constructor init of field second [pre-this] | | -| stl.h:395:36:395:43 | constructor init of field first [pre-this] | stl.h:395:46:395:54 | constructor init of field second [pre-this] | | -| stl.h:395:36:395:43 | constructor init of field first [pre-this] | stl.h:395:46:395:54 | constructor init of field second [pre-this] | | -| stl.h:395:36:395:43 | constructor init of field first [pre-this] | stl.h:395:46:395:54 | constructor init of field second [pre-this] | | -| stl.h:395:36:395:43 | constructor init of field first [pre-this] | stl.h:395:46:395:54 | constructor init of field second [pre-this] | | -| stl.h:395:36:395:43 | constructor init of field first [pre-this] | stl.h:395:46:395:54 | constructor init of field second [pre-this] | | -| stl.h:395:42:395:42 | x | stl.h:395:36:395:43 | constructor init of field first | TAINT | -| stl.h:395:42:395:42 | x | stl.h:395:36:395:43 | constructor init of field first | TAINT | -| stl.h:395:42:395:42 | x | stl.h:395:36:395:43 | constructor init of field first | TAINT | -| stl.h:395:42:395:42 | x | stl.h:395:36:395:43 | constructor init of field first | TAINT | -| stl.h:395:42:395:42 | x | stl.h:395:36:395:43 | constructor init of field first | TAINT | -| stl.h:395:46:395:54 | call to unknown function | stl.h:395:46:395:54 | constructor init of field second | TAINT | -| stl.h:395:53:395:53 | y | stl.h:395:46:395:54 | constructor init of field second | TAINT | -| stl.h:395:53:395:53 | y | stl.h:395:46:395:54 | constructor init of field second | TAINT | -| stl.h:395:53:395:53 | y | stl.h:395:46:395:54 | constructor init of field second | TAINT | -| stl.h:395:53:395:53 | y | stl.h:395:46:395:54 | constructor init of field second | TAINT | -| stl.h:395:53:395:53 | y | stl.h:395:46:395:54 | constructor init of field second | TAINT | -| stl.h:401:87:401:87 | x | stl.h:401:87:401:87 | x | | -| stl.h:401:87:401:87 | x | stl.h:401:87:401:87 | x | | -| stl.h:401:87:401:87 | x | stl.h:401:87:401:87 | x | | -| stl.h:401:87:401:87 | x | stl.h:401:87:401:87 | x | | -| stl.h:401:87:401:87 | x | stl.h:401:87:401:87 | x | | -| stl.h:401:87:401:87 | x | stl.h:401:87:401:87 | x | | -| stl.h:401:87:401:87 | x | stl.h:401:87:401:87 | x | | -| stl.h:401:87:401:87 | x | stl.h:402:58:402:58 | x | | -| stl.h:401:87:401:87 | x | stl.h:402:58:402:58 | x | | -| stl.h:401:87:401:87 | x | stl.h:402:58:402:58 | x | | -| stl.h:401:87:401:87 | x | stl.h:402:58:402:58 | x | | -| stl.h:401:87:401:87 | x | stl.h:402:58:402:58 | x | | -| stl.h:401:87:401:87 | x | stl.h:402:58:402:58 | x | | -| stl.h:401:87:401:87 | x | stl.h:402:58:402:58 | x | | -| stl.h:401:95:401:95 | y | stl.h:401:95:401:95 | y | | -| stl.h:401:95:401:95 | y | stl.h:401:95:401:95 | y | | -| stl.h:401:95:401:95 | y | stl.h:401:95:401:95 | y | | -| stl.h:401:95:401:95 | y | stl.h:401:95:401:95 | y | | -| stl.h:401:95:401:95 | y | stl.h:401:95:401:95 | y | | -| stl.h:401:95:401:95 | y | stl.h:401:95:401:95 | y | | -| stl.h:401:95:401:95 | y | stl.h:401:95:401:95 | y | | -| stl.h:401:95:401:95 | y | stl.h:402:79:402:79 | y | | -| stl.h:401:95:401:95 | y | stl.h:402:79:402:79 | y | | -| stl.h:401:95:401:95 | y | stl.h:402:79:402:79 | y | | -| stl.h:401:95:401:95 | y | stl.h:402:79:402:79 | y | | -| stl.h:401:95:401:95 | y | stl.h:402:79:402:79 | y | | -| stl.h:401:95:401:95 | y | stl.h:402:79:402:79 | y | | -| stl.h:401:95:401:95 | y | stl.h:402:79:402:79 | y | | -| stl.h:402:58:402:58 | x | stl.h:402:41:402:56 | call to forward | | -| stl.h:402:58:402:58 | x | stl.h:402:41:402:56 | call to forward | | -| stl.h:402:58:402:58 | x | stl.h:402:41:402:56 | call to forward | | -| stl.h:402:58:402:58 | x | stl.h:402:41:402:56 | call to forward | | -| stl.h:402:58:402:58 | x | stl.h:402:41:402:56 | call to forward | | -| stl.h:402:58:402:58 | x | stl.h:402:41:402:56 | call to forward | | -| stl.h:402:62:402:77 | call to forward | stl.h:402:3:402:82 | call to pair | TAINT | -| stl.h:402:62:402:77 | call to forward | stl.h:402:3:402:82 | call to pair | TAINT | -| stl.h:402:62:402:77 | call to forward | stl.h:402:3:402:82 | call to pair | TAINT | -| stl.h:402:62:402:77 | call to forward | stl.h:402:3:402:82 | call to pair | TAINT | -| stl.h:402:62:402:77 | call to forward | stl.h:402:3:402:82 | call to pair | TAINT | -| stl.h:402:62:402:77 | call to forward | stl.h:402:3:402:82 | call to pair | TAINT | -| stl.h:402:79:402:79 | y | stl.h:402:3:402:82 | call to pair | TAINT | -| stl.h:402:79:402:79 | y | stl.h:402:3:402:82 | call to pair | TAINT | -| stl.h:402:79:402:79 | y | stl.h:402:3:402:82 | call to pair | TAINT | -| stl.h:402:79:402:79 | y | stl.h:402:3:402:82 | call to pair | TAINT | -| stl.h:402:79:402:79 | y | stl.h:402:3:402:82 | call to pair | TAINT | -| stl.h:402:79:402:79 | y | stl.h:402:3:402:82 | call to pair | TAINT | -| stl.h:402:79:402:79 | y | stl.h:402:62:402:77 | call to forward | | -| stl.h:402:79:402:79 | y | stl.h:402:62:402:77 | call to forward | | -| stl.h:402:79:402:79 | y | stl.h:402:62:402:77 | call to forward | | -| stl.h:402:79:402:79 | y | stl.h:402:62:402:77 | call to forward | | -| stl.h:402:79:402:79 | y | stl.h:402:62:402:77 | call to forward | | -| stl.h:402:79:402:79 | y | stl.h:402:62:402:77 | call to forward | | +| stl.h:389:9:389:9 | Unknown literal | stl.h:389:9:389:9 | constructor init of field first | TAINT | +| stl.h:389:9:389:9 | Unknown literal | stl.h:389:9:389:9 | constructor init of field first | TAINT | +| stl.h:389:9:389:9 | Unknown literal | stl.h:389:9:389:9 | constructor init of field first | TAINT | +| stl.h:389:9:389:9 | Unknown literal | stl.h:389:9:389:9 | constructor init of field first | TAINT | +| stl.h:389:9:389:9 | Unknown literal | stl.h:389:9:389:9 | constructor init of field first | TAINT | +| stl.h:389:9:389:9 | Unknown literal | stl.h:389:9:389:9 | constructor init of field second | TAINT | +| stl.h:389:9:389:9 | Unknown literal | stl.h:389:9:389:9 | constructor init of field second | TAINT | +| stl.h:389:9:389:9 | Unknown literal | stl.h:389:9:389:9 | constructor init of field second | TAINT | +| stl.h:389:9:389:9 | Unknown literal | stl.h:389:9:389:9 | constructor init of field second | TAINT | +| stl.h:389:9:389:9 | Unknown literal | stl.h:389:9:389:9 | constructor init of field second | TAINT | +| stl.h:389:9:389:9 | constructor init of field first [post-this] | stl.h:389:9:389:9 | constructor init of field second [pre-this] | | +| stl.h:389:9:389:9 | constructor init of field first [post-this] | stl.h:389:9:389:9 | constructor init of field second [pre-this] | | +| stl.h:389:9:389:9 | constructor init of field first [post-this] | stl.h:389:9:389:9 | constructor init of field second [pre-this] | | +| stl.h:389:9:389:9 | constructor init of field first [post-this] | stl.h:389:9:389:9 | constructor init of field second [pre-this] | | +| stl.h:389:9:389:9 | constructor init of field first [post-this] | stl.h:389:9:389:9 | constructor init of field second [pre-this] | | +| stl.h:389:9:389:9 | constructor init of field first [pre-this] | stl.h:389:9:389:9 | constructor init of field second [pre-this] | | +| stl.h:389:9:389:9 | constructor init of field first [pre-this] | stl.h:389:9:389:9 | constructor init of field second [pre-this] | | +| stl.h:389:9:389:9 | constructor init of field first [pre-this] | stl.h:389:9:389:9 | constructor init of field second [pre-this] | | +| stl.h:389:9:389:9 | constructor init of field first [pre-this] | stl.h:389:9:389:9 | constructor init of field second [pre-this] | | +| stl.h:389:9:389:9 | constructor init of field first [pre-this] | stl.h:389:9:389:9 | constructor init of field second [pre-this] | | +| stl.h:389:9:389:9 | this | stl.h:389:9:389:9 | constructor init of field first [pre-this] | | +| stl.h:389:9:389:9 | this | stl.h:389:9:389:9 | constructor init of field first [pre-this] | | +| stl.h:389:9:389:9 | this | stl.h:389:9:389:9 | constructor init of field first [pre-this] | | +| stl.h:389:9:389:9 | this | stl.h:389:9:389:9 | constructor init of field first [pre-this] | | +| stl.h:389:9:389:9 | this | stl.h:389:9:389:9 | constructor init of field first [pre-this] | | +| stl.h:396:3:396:3 | this | stl.h:396:36:396:43 | constructor init of field first [pre-this] | | +| stl.h:396:3:396:3 | this | stl.h:396:36:396:43 | constructor init of field first [pre-this] | | +| stl.h:396:3:396:3 | this | stl.h:396:36:396:43 | constructor init of field first [pre-this] | | +| stl.h:396:3:396:3 | this | stl.h:396:36:396:43 | constructor init of field first [pre-this] | | +| stl.h:396:3:396:3 | this | stl.h:396:36:396:43 | constructor init of field first [pre-this] | | +| stl.h:396:3:396:6 | this | stl.h:396:36:396:43 | constructor init of field first [pre-this] | | +| stl.h:396:18:396:18 | x | stl.h:396:42:396:42 | x | | +| stl.h:396:18:396:18 | x | stl.h:396:42:396:42 | x | | +| stl.h:396:18:396:18 | x | stl.h:396:42:396:42 | x | | +| stl.h:396:18:396:18 | x | stl.h:396:42:396:42 | x | | +| stl.h:396:18:396:18 | x | stl.h:396:42:396:42 | x | | +| stl.h:396:18:396:18 | x | stl.h:396:42:396:42 | x | | +| stl.h:396:31:396:31 | y | stl.h:396:53:396:53 | y | | +| stl.h:396:31:396:31 | y | stl.h:396:53:396:53 | y | | +| stl.h:396:31:396:31 | y | stl.h:396:53:396:53 | y | | +| stl.h:396:31:396:31 | y | stl.h:396:53:396:53 | y | | +| stl.h:396:31:396:31 | y | stl.h:396:53:396:53 | y | | +| stl.h:396:31:396:31 | y | stl.h:396:53:396:53 | y | | +| stl.h:396:36:396:43 | call to unknown function | stl.h:396:36:396:43 | constructor init of field first | TAINT | +| stl.h:396:36:396:43 | constructor init of field first [post-this] | stl.h:396:46:396:54 | constructor init of field second [pre-this] | | +| stl.h:396:36:396:43 | constructor init of field first [post-this] | stl.h:396:46:396:54 | constructor init of field second [pre-this] | | +| stl.h:396:36:396:43 | constructor init of field first [post-this] | stl.h:396:46:396:54 | constructor init of field second [pre-this] | | +| stl.h:396:36:396:43 | constructor init of field first [post-this] | stl.h:396:46:396:54 | constructor init of field second [pre-this] | | +| stl.h:396:36:396:43 | constructor init of field first [post-this] | stl.h:396:46:396:54 | constructor init of field second [pre-this] | | +| stl.h:396:36:396:43 | constructor init of field first [post-this] | stl.h:396:46:396:54 | constructor init of field second [pre-this] | | +| stl.h:396:36:396:43 | constructor init of field first [pre-this] | stl.h:396:46:396:54 | constructor init of field second [pre-this] | | +| stl.h:396:36:396:43 | constructor init of field first [pre-this] | stl.h:396:46:396:54 | constructor init of field second [pre-this] | | +| stl.h:396:36:396:43 | constructor init of field first [pre-this] | stl.h:396:46:396:54 | constructor init of field second [pre-this] | | +| stl.h:396:36:396:43 | constructor init of field first [pre-this] | stl.h:396:46:396:54 | constructor init of field second [pre-this] | | +| stl.h:396:36:396:43 | constructor init of field first [pre-this] | stl.h:396:46:396:54 | constructor init of field second [pre-this] | | +| stl.h:396:36:396:43 | constructor init of field first [pre-this] | stl.h:396:46:396:54 | constructor init of field second [pre-this] | | +| stl.h:396:42:396:42 | x | stl.h:396:36:396:43 | constructor init of field first | TAINT | +| stl.h:396:42:396:42 | x | stl.h:396:36:396:43 | constructor init of field first | TAINT | +| stl.h:396:42:396:42 | x | stl.h:396:36:396:43 | constructor init of field first | TAINT | +| stl.h:396:42:396:42 | x | stl.h:396:36:396:43 | constructor init of field first | TAINT | +| stl.h:396:42:396:42 | x | stl.h:396:36:396:43 | constructor init of field first | TAINT | +| stl.h:396:46:396:54 | call to unknown function | stl.h:396:46:396:54 | constructor init of field second | TAINT | +| stl.h:396:53:396:53 | y | stl.h:396:46:396:54 | constructor init of field second | TAINT | +| stl.h:396:53:396:53 | y | stl.h:396:46:396:54 | constructor init of field second | TAINT | +| stl.h:396:53:396:53 | y | stl.h:396:46:396:54 | constructor init of field second | TAINT | +| stl.h:396:53:396:53 | y | stl.h:396:46:396:54 | constructor init of field second | TAINT | +| stl.h:396:53:396:53 | y | stl.h:396:46:396:54 | constructor init of field second | TAINT | +| stl.h:402:87:402:87 | x | stl.h:402:87:402:87 | x | | +| stl.h:402:87:402:87 | x | stl.h:402:87:402:87 | x | | +| stl.h:402:87:402:87 | x | stl.h:402:87:402:87 | x | | +| stl.h:402:87:402:87 | x | stl.h:402:87:402:87 | x | | +| stl.h:402:87:402:87 | x | stl.h:402:87:402:87 | x | | +| stl.h:402:87:402:87 | x | stl.h:402:87:402:87 | x | | +| stl.h:402:87:402:87 | x | stl.h:402:87:402:87 | x | | +| stl.h:402:87:402:87 | x | stl.h:403:58:403:58 | x | | +| stl.h:402:87:402:87 | x | stl.h:403:58:403:58 | x | | +| stl.h:402:87:402:87 | x | stl.h:403:58:403:58 | x | | +| stl.h:402:87:402:87 | x | stl.h:403:58:403:58 | x | | +| stl.h:402:87:402:87 | x | stl.h:403:58:403:58 | x | | +| stl.h:402:87:402:87 | x | stl.h:403:58:403:58 | x | | +| stl.h:402:87:402:87 | x | stl.h:403:58:403:58 | x | | +| stl.h:402:95:402:95 | y | stl.h:402:95:402:95 | y | | +| stl.h:402:95:402:95 | y | stl.h:402:95:402:95 | y | | +| stl.h:402:95:402:95 | y | stl.h:402:95:402:95 | y | | +| stl.h:402:95:402:95 | y | stl.h:402:95:402:95 | y | | +| stl.h:402:95:402:95 | y | stl.h:402:95:402:95 | y | | +| stl.h:402:95:402:95 | y | stl.h:402:95:402:95 | y | | +| stl.h:402:95:402:95 | y | stl.h:402:95:402:95 | y | | +| stl.h:402:95:402:95 | y | stl.h:403:79:403:79 | y | | +| stl.h:402:95:402:95 | y | stl.h:403:79:403:79 | y | | +| stl.h:402:95:402:95 | y | stl.h:403:79:403:79 | y | | +| stl.h:402:95:402:95 | y | stl.h:403:79:403:79 | y | | +| stl.h:402:95:402:95 | y | stl.h:403:79:403:79 | y | | +| stl.h:402:95:402:95 | y | stl.h:403:79:403:79 | y | | +| stl.h:402:95:402:95 | y | stl.h:403:79:403:79 | y | | +| stl.h:403:58:403:58 | x | stl.h:403:41:403:56 | call to forward | | +| stl.h:403:58:403:58 | x | stl.h:403:41:403:56 | call to forward | | +| stl.h:403:58:403:58 | x | stl.h:403:41:403:56 | call to forward | | +| stl.h:403:58:403:58 | x | stl.h:403:41:403:56 | call to forward | | +| stl.h:403:58:403:58 | x | stl.h:403:41:403:56 | call to forward | | +| stl.h:403:58:403:58 | x | stl.h:403:41:403:56 | call to forward | | +| stl.h:403:62:403:77 | call to forward | stl.h:403:3:403:82 | call to pair | TAINT | +| stl.h:403:62:403:77 | call to forward | stl.h:403:3:403:82 | call to pair | TAINT | +| stl.h:403:62:403:77 | call to forward | stl.h:403:3:403:82 | call to pair | TAINT | +| stl.h:403:62:403:77 | call to forward | stl.h:403:3:403:82 | call to pair | TAINT | +| stl.h:403:62:403:77 | call to forward | stl.h:403:3:403:82 | call to pair | TAINT | +| stl.h:403:62:403:77 | call to forward | stl.h:403:3:403:82 | call to pair | TAINT | +| stl.h:403:79:403:79 | y | stl.h:403:3:403:82 | call to pair | TAINT | +| stl.h:403:79:403:79 | y | stl.h:403:3:403:82 | call to pair | TAINT | +| stl.h:403:79:403:79 | y | stl.h:403:3:403:82 | call to pair | TAINT | +| stl.h:403:79:403:79 | y | stl.h:403:3:403:82 | call to pair | TAINT | +| stl.h:403:79:403:79 | y | stl.h:403:3:403:82 | call to pair | TAINT | +| stl.h:403:79:403:79 | y | stl.h:403:3:403:82 | call to pair | TAINT | +| stl.h:403:79:403:79 | y | stl.h:403:62:403:77 | call to forward | | +| stl.h:403:79:403:79 | y | stl.h:403:62:403:77 | call to forward | | +| stl.h:403:79:403:79 | y | stl.h:403:62:403:77 | call to forward | | +| stl.h:403:79:403:79 | y | stl.h:403:62:403:77 | call to forward | | +| stl.h:403:79:403:79 | y | stl.h:403:62:403:77 | call to forward | | +| stl.h:403:79:403:79 | y | stl.h:403:62:403:77 | call to forward | | | string.cpp:25:12:25:17 | call to source | string.cpp:29:7:29:7 | a | | | string.cpp:26:16:26:20 | 123 | string.cpp:26:16:26:21 | call to basic_string | TAINT | | string.cpp:26:16:26:21 | call to basic_string | string.cpp:30:7:30:7 | b | | diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/map.cpp b/cpp/ql/test/library-tests/dataflow/taint-tests/map.cpp index 0154ef2c7bb..aabd898830e 100644 --- a/cpp/ql/test/library-tests/dataflow/taint-tests/map.cpp +++ b/cpp/ql/test/library-tests/dataflow/taint-tests/map.cpp @@ -152,8 +152,8 @@ void test_map() for (i2 = m2.begin(); i2 != m2.end(); i2++) { sink(*i2); // $ ast,ir - sink(i2->first); // $ SPURIOUS: ir - sink(i2->second); // $ ir MISSING: ast + sink(i2->first); // clean + sink(i2->second); // $ MISSING: ast,ir } for (i3 = m3.begin(); i3 != m3.end(); i3++) { @@ -304,8 +304,8 @@ void test_unordered_map() for (i2 = m2.begin(); i2 != m2.end(); i2++) { sink(*i2); // $ ast,ir - sink(i2->first); // $ SPURIOUS: ir - sink(i2->second); // $ ir MISSING: ast + sink(i2->first); // clean + sink(i2->second); // $ MISSING: ast,ir } for (i3 = m3.begin(); i3 != m3.end(); i3++) { diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/smart_pointer.cpp b/cpp/ql/test/library-tests/dataflow/taint-tests/smart_pointer.cpp index f45260228e8..39cff39e3ed 100644 --- a/cpp/ql/test/library-tests/dataflow/taint-tests/smart_pointer.cpp +++ b/cpp/ql/test/library-tests/dataflow/taint-tests/smart_pointer.cpp @@ -35,16 +35,16 @@ void test_reverse_taint_shared() { std::shared_ptr p = std::make_shared(); *p = source(); - sink(p); // $ MISSING: ast,ir - sink(*p); // $ MISSING: ast,ir + sink(p); // $ ast MISSING: ir + sink(*p); // $ ast MISSING: ir } void test_reverse_taint_unique() { std::unique_ptr p = std::unique_ptr(); *p = source(); - sink(p); // $ MISSING: ast,ir - sink(*p); // $ MISSING: ast,ir + sink(p); // $ ast MISSING: ir + sink(*p); // $ ast MISSING: ir } void test_shared_get() { @@ -65,4 +65,74 @@ void test_shared_field_member() { std::unique_ptr p = std::make_unique(source(), 0); sink(p->x); // $ MISSING: ast,ir sink(p->y); // not tainted +} + +void getNumber(std::shared_ptr ptr) { + *ptr = source(); +} + +int test_from_issue_5190() { + std::shared_ptr p(new int); + getNumber(p); + sink(*p); // $ ast MISSING: ir +} + +struct B { + A a1; + A a2; + int z; +}; + +void test_operator_arrow(std::unique_ptr p, std::unique_ptr q) { + p->x = source(); + sink(p->x); // $ ast MISSING: ir + sink(p->y); + + q->a1.x = source(); + sink(q->a1.x); // $ ast MISSING: ir + sink(q->a1.y); + sink(q->a2.x); +} + +void taint_x(A* pa) { + pa->x = source(); +} + +void reverse_taint_smart_pointer() { + std::unique_ptr p = std::unique_ptr(new A); + taint_x(p.get()); + sink(p->x); // $ ast MISSING: ir +} + +struct C { + int z; + std::shared_ptr q; +}; + +void taint_x_shared(std::shared_ptr ptr) { + ptr->x = source(); +} + +void taint_x_shared_cref(const std::shared_ptr& ptr) { + ptr->x = source(); +} + +void getNumberCRef(const std::shared_ptr& ptr) { + *ptr = source(); +} + +int nested_shared_ptr_taint(std::shared_ptr p1, std::unique_ptr> p2) { + taint_x_shared(p1->q); + sink(p1->q->x); // $ ast MISSING: ir + + getNumber(*p2); + sink(**p2); // $ ast MISSING: ir +} + +int nested_shared_ptr_taint_cref(std::shared_ptr p1, std::unique_ptr> p2) { + taint_x_shared_cref(p1->q); + sink(p1->q->x); // $ ast MISSING: ir + + getNumberCRef(*p2); + sink(**p2); // $ ast MISSING: ir } \ No newline at end of file diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/standalone_iterators.cpp b/cpp/ql/test/library-tests/dataflow/taint-tests/standalone_iterators.cpp index 362784eeb1a..376582381ac 100644 --- a/cpp/ql/test/library-tests/dataflow/taint-tests/standalone_iterators.cpp +++ b/cpp/ql/test/library-tests/dataflow/taint-tests/standalone_iterators.cpp @@ -39,13 +39,13 @@ public: void test_typedefs(int_iterator_by_typedefs source1) { sink(*source1); // $ ast,ir sink(*(source1++)); // $ ast,ir - sink(*(++source1)); // $ ast MISSING: ir + sink(*(++source1)); // $ ast,ir } void test_trait(int_iterator_by_trait source1) { sink(*source1); // $ ast,ir sink(*(source1++)); // $ ast,ir - sink(*(++source1)); // $ ast MISSING: ir + sink(*(++source1)); // $ ast,ir } void test_non_iterator(non_iterator source1) { diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/stl.h b/cpp/ql/test/library-tests/dataflow/taint-tests/stl.h index 09e77c5a3b6..44550c3df76 100644 --- a/cpp/ql/test/library-tests/dataflow/taint-tests/stl.h +++ b/cpp/ql/test/library-tests/dataflow/taint-tests/stl.h @@ -349,6 +349,7 @@ namespace std { public: shared_ptr() noexcept; explicit shared_ptr(T*); + shared_ptr(const shared_ptr&) noexcept; template shared_ptr(const shared_ptr&) noexcept; template shared_ptr(shared_ptr&&) noexcept; diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/string.cpp b/cpp/ql/test/library-tests/dataflow/taint-tests/string.cpp index 9169113c1d9..0e29d314887 100644 --- a/cpp/ql/test/library-tests/dataflow/taint-tests/string.cpp +++ b/cpp/ql/test/library-tests/dataflow/taint-tests/string.cpp @@ -396,9 +396,9 @@ void test_string_iterators() { sink(*(i2+1)); // $ ast,ir sink(*(i2-1)); // $ ast,ir i3 = i2; - sink(*(++i3)); // $ ast MISSING: ir + sink(*(++i3)); // $ ast,ir i4 = i2; - sink(*(--i4)); // $ ast MISSING: ir + sink(*(--i4)); // $ ast,ir i5 = i2; i5++; sink(*i5); // $ ast,ir @@ -406,9 +406,9 @@ void test_string_iterators() { i6--; sink(*i6); // $ ast,ir i7 = i2; - sink(*(i7+=1)); // $ ast MISSING: ir + sink(*(i7+=1)); // $ ast,ir i8 = i2; - sink(*(i8-=1)); // $ ast MISSING: ir + sink(*(i8-=1)); // $ ast,ir i9 = s2.end(); --i9; diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/stringstream.cpp b/cpp/ql/test/library-tests/dataflow/taint-tests/stringstream.cpp index 7b7712f0c01..fab96fc878d 100644 --- a/cpp/ql/test/library-tests/dataflow/taint-tests/stringstream.cpp +++ b/cpp/ql/test/library-tests/dataflow/taint-tests/stringstream.cpp @@ -32,18 +32,18 @@ void test_stringstream_string(int amount) sink(ss2 << source()); // $ ast,ir sink(ss3 << "123" << source()); // $ ast,ir sink(ss4 << source() << "456"); // $ ast,ir - sink(ss5 << t); // $ ast MISSING: ir + sink(ss5 << t); // $ ast,ir sink(ss1); sink(ss2); // $ ast,ir sink(ss3); // $ ast MISSING: ir sink(ss4); // $ ast,ir - sink(ss5); // $ ast MISSING: ir + sink(ss5); // $ ast,ir sink(ss1.str()); sink(ss2.str()); // $ ast,ir sink(ss3.str()); // $ ast MISSING: ir sink(ss4.str()); // $ ast,ir - sink(ss5.str()); // $ ast MISSING: ir + sink(ss5.str()); // $ ast,ir ss6.str("abc"); ss6.str(source()); // (overwrites) @@ -229,7 +229,7 @@ void test_getline() sink(ss2.getline(b7, 1000).getline(b8, 1000)); // $ ast,ir sink(b7); // $ ast,ir - sink(b8); // $ ast MISSING: ir + sink(b8); // $ ast,ir sink(getline(ss1, s1)); sink(getline(ss2, s2)); // $ ast,ir @@ -261,7 +261,7 @@ void test_chaining() sink(ss1.get(b1, 100).unget().get(b2, 100)); // $ ast,ir sink(b1); // $ ast,ir - sink(b2); // $ ast MISSING: ir + sink(b2); // $ ast,ir sink(ss2.write("abc", 3).flush().write(source(), 3).flush().write("xyz", 3)); // $ ast MISSING: ir sink(ss2); // $ ast MISSING: ir diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/taint.cpp b/cpp/ql/test/library-tests/dataflow/taint-tests/taint.cpp index 5ba2425300f..0365d8c2c77 100644 --- a/cpp/ql/test/library-tests/dataflow/taint-tests/taint.cpp +++ b/cpp/ql/test/library-tests/dataflow/taint-tests/taint.cpp @@ -192,7 +192,7 @@ void *memcpy(void *dest, void *src, int len); void test_memcpy(int *source) { int x; memcpy(&x, source, sizeof(int)); - sink(x); // $ ast=192:23 MISSING: ir SPURIOUS: ast=193:6 + sink(x); // $ ast=192:23 ir SPURIOUS: ast=193:6 } // --- std::swap --- @@ -369,9 +369,9 @@ void test_strdup(char *source) a = strdup(source); b = strdup("hello, world"); c = strndup(source, 100); - sink(a); // $ ast MISSING: ir + sink(a); // $ ast,ir sink(b); - sink(c); // $ ast MISSING: ir + sink(c); // $ ast,ir } void test_strndup(int source) @@ -388,7 +388,7 @@ void test_wcsdup(wchar_t *source) a = wcsdup(source); b = wcsdup(L"hello, world"); - sink(a); // $ ast MISSING: ir + sink(a); // $ ast,ir sink(b); } @@ -518,7 +518,7 @@ void *mempcpy(void *dest, const void *src, size_t n); void test_mempcpy(int *source) { int x; mempcpy(&x, source, sizeof(int)); - sink(x); // $ ast=518:24 MISSING: ir SPURIOUS: ast=519:6 + sink(x); // $ ast=518:24 ir SPURIOUS: ast=519:6 } // --- memccpy --- @@ -528,7 +528,7 @@ void *memccpy(void *dest, const void *src, int c, size_t n); void test_memccpy(int *source) { int dest[16]; memccpy(dest, source, 42, sizeof(dest)); - sink(dest); // $ ast=528:24 MISSING: ir SPURIOUS: ast=529:6 + sink(dest); // $ ast=528:24 ir SPURIOUS: ast=529:6 } // --- strcat and related functions --- diff --git a/cpp/ql/test/library-tests/ir/ir/raw_ir.expected b/cpp/ql/test/library-tests/ir/ir/raw_ir.expected index a7dac56cc96..e008e2de659 100644 --- a/cpp/ql/test/library-tests/ir/ir/raw_ir.expected +++ b/cpp/ql/test/library-tests/ir/ir/raw_ir.expected @@ -42,7 +42,7 @@ bad_asts.cpp: # 16| r16_3(int) = Constant[1] : # 16| r16_4(int) = Call[MemberFunction] : func:r16_2, this:r16_1, 0:r16_3 # 16| mu16_5(unknown) = ^CallSideEffect : ~m? -# 16| v16_6(void) = ^BufferReadSideEffect[-1] : &:r16_1, ~m? +# 16| v16_6(void) = ^IndirectReadSideEffect[-1] : &:r16_1, ~m? # 16| mu16_7(S) = ^IndirectMayWriteSideEffect[-1] : &:r16_1 # 17| v17_1(void) = NoOp : # 14| v14_4(void) = ReturnVoid : @@ -3385,47 +3385,46 @@ ir.cpp: # 622| void CallMethods(String&, String*, String) # 622| Block 0 -# 622| v622_1(void) = EnterFunction : -# 622| mu622_2(unknown) = AliasedDefinition : -# 622| mu622_3(unknown) = InitializeNonLocal : -# 622| r622_4(glval) = VariableAddress[r] : -# 622| mu622_5(String &) = InitializeParameter[r] : &:r622_4 -# 622| r622_6(String &) = Load[r] : &:r622_4, ~m? -# 622| mu622_7(unknown) = InitializeIndirection[r] : &:r622_6 -# 622| r622_8(glval) = VariableAddress[p] : -# 622| mu622_9(String *) = InitializeParameter[p] : &:r622_8 -# 622| r622_10(String *) = Load[p] : &:r622_8, ~m? -# 622| mu622_11(unknown) = InitializeIndirection[p] : &:r622_10 -# 622| r622_12(glval) = VariableAddress[s] : -# 622| mu622_13(String) = InitializeParameter[s] : &:r622_12 -# 623| r623_1(glval) = VariableAddress[r] : -# 623| r623_2(String &) = Load[r] : &:r623_1, ~m? -# 623| r623_3(glval) = CopyValue : r623_2 -# 623| r623_4(glval) = Convert : r623_3 -# 623| r623_5(glval) = FunctionAddress[c_str] : -# 623| r623_6(char *) = Call[c_str] : func:r623_5, this:r623_4 -# 623| mu623_7(unknown) = ^CallSideEffect : ~m? -# 623| v623_8(void) = ^BufferReadSideEffect[-1] : &:r623_4, ~m? -# 624| r624_1(glval) = VariableAddress[p] : -# 624| r624_2(String *) = Load[p] : &:r624_1, ~m? -# 624| r624_3(String *) = Convert : r624_2 -# 624| r624_4(glval) = FunctionAddress[c_str] : -# 624| r624_5(char *) = Call[c_str] : func:r624_4, this:r624_3 -# 624| mu624_6(unknown) = ^CallSideEffect : ~m? -# 624| v624_7(void) = ^BufferReadSideEffect[-1] : &:r624_3, ~m? -# 624| mu624_8(String) = ^IndirectMayWriteSideEffect[-1] : &:r624_3 -# 625| r625_1(glval) = VariableAddress[s] : -# 625| r625_2(glval) = Convert : r625_1 -# 625| r625_3(glval) = FunctionAddress[c_str] : -# 625| r625_4(char *) = Call[c_str] : func:r625_3, this:r625_2 -# 625| mu625_5(unknown) = ^CallSideEffect : ~m? -# 625| v625_6(void) = ^BufferReadSideEffect[-1] : &:r625_2, ~m? -# 626| v626_1(void) = NoOp : -# 622| v622_14(void) = ReturnIndirection[r] : &:r622_6, ~m? -# 622| v622_15(void) = ReturnIndirection[p] : &:r622_10, ~m? -# 622| v622_16(void) = ReturnVoid : -# 622| v622_17(void) = AliasedUse : ~m? -# 622| v622_18(void) = ExitFunction : +# 622| v622_1(void) = EnterFunction : +# 622| mu622_2(unknown) = AliasedDefinition : +# 622| mu622_3(unknown) = InitializeNonLocal : +# 622| r622_4(glval) = VariableAddress[r] : +# 622| mu622_5(String &) = InitializeParameter[r] : &:r622_4 +# 622| r622_6(String &) = Load[r] : &:r622_4, ~m? +# 622| mu622_7(unknown) = InitializeIndirection[r] : &:r622_6 +# 622| r622_8(glval) = VariableAddress[p] : +# 622| mu622_9(String *) = InitializeParameter[p] : &:r622_8 +# 622| r622_10(String *) = Load[p] : &:r622_8, ~m? +# 622| mu622_11(unknown) = InitializeIndirection[p] : &:r622_10 +# 622| r622_12(glval) = VariableAddress[s] : +# 622| mu622_13(String) = InitializeParameter[s] : &:r622_12 +# 623| r623_1(glval) = VariableAddress[r] : +# 623| r623_2(String &) = Load[r] : &:r623_1, ~m? +# 623| r623_3(glval) = CopyValue : r623_2 +# 623| r623_4(glval) = Convert : r623_3 +# 623| r623_5(glval) = FunctionAddress[c_str] : +# 623| r623_6(char *) = Call[c_str] : func:r623_5, this:r623_4 +# 623| mu623_7(unknown) = ^CallSideEffect : ~m? +# 623| v623_8(void) = ^IndirectReadSideEffect[-1] : &:r623_4, ~m? +# 624| r624_1(glval) = VariableAddress[p] : +# 624| r624_2(String *) = Load[p] : &:r624_1, ~m? +# 624| r624_3(String *) = Convert : r624_2 +# 624| r624_4(glval) = FunctionAddress[c_str] : +# 624| r624_5(char *) = Call[c_str] : func:r624_4, this:r624_3 +# 624| mu624_6(unknown) = ^CallSideEffect : ~m? +# 624| v624_7(void) = ^IndirectReadSideEffect[-1] : &:r624_3, ~m? +# 625| r625_1(glval) = VariableAddress[s] : +# 625| r625_2(glval) = Convert : r625_1 +# 625| r625_3(glval) = FunctionAddress[c_str] : +# 625| r625_4(char *) = Call[c_str] : func:r625_3, this:r625_2 +# 625| mu625_5(unknown) = ^CallSideEffect : ~m? +# 625| v625_6(void) = ^IndirectReadSideEffect[-1] : &:r625_2, ~m? +# 626| v626_1(void) = NoOp : +# 622| v622_14(void) = ReturnIndirection[r] : &:r622_6, ~m? +# 622| v622_15(void) = ReturnIndirection[p] : &:r622_10, ~m? +# 622| v622_16(void) = ReturnVoid : +# 622| v622_17(void) = AliasedUse : ~m? +# 622| v622_18(void) = ExitFunction : # 628| void C::~C() # 628| Block 0 @@ -3575,7 +3574,7 @@ ir.cpp: # 653| r653_4(int) = Constant[0] : # 653| r653_5(int) = Call[InstanceMemberFunction] : func:r653_3, this:r653_2, 0:r653_4 # 653| mu653_6(unknown) = ^CallSideEffect : ~m? -# 653| v653_7(void) = ^BufferReadSideEffect[-1] : &:r653_2, ~m? +# 653| v653_7(void) = ^IndirectReadSideEffect[-1] : &:r653_2, ~m? # 653| mu653_8(C) = ^IndirectMayWriteSideEffect[-1] : &:r653_2 # 654| r654_1(glval) = VariableAddress[#this] : # 654| r654_2(C *) = Load[#this] : &:r654_1, ~m? @@ -3584,7 +3583,7 @@ ir.cpp: # 654| r654_5(int) = Constant[1] : # 654| r654_6(int) = Call[InstanceMemberFunction] : func:r654_4, this:r654_3, 0:r654_5 # 654| mu654_7(unknown) = ^CallSideEffect : ~m? -# 654| v654_8(void) = ^BufferReadSideEffect[-1] : &:r654_3, ~m? +# 654| v654_8(void) = ^IndirectReadSideEffect[-1] : &:r654_3, ~m? # 654| mu654_9(C) = ^IndirectMayWriteSideEffect[-1] : &:r654_3 # 655| r655_1(glval) = VariableAddress[#this] : # 655| r655_2(C *) = Load[#this] : &:r655_1, ~m? @@ -3592,7 +3591,7 @@ ir.cpp: # 655| r655_4(int) = Constant[2] : # 655| r655_5(int) = Call[InstanceMemberFunction] : func:r655_3, this:r655_2, 0:r655_4 # 655| mu655_6(unknown) = ^CallSideEffect : ~m? -# 655| v655_7(void) = ^BufferReadSideEffect[-1] : &:r655_2, ~m? +# 655| v655_7(void) = ^IndirectReadSideEffect[-1] : &:r655_2, ~m? # 655| mu655_8(C) = ^IndirectMayWriteSideEffect[-1] : &:r655_2 # 656| v656_1(void) = NoOp : # 652| v652_8(void) = ReturnIndirection[#this] : &:r652_6, ~m? @@ -4006,7 +4005,7 @@ ir.cpp: #-----| r0_6(String &) = CopyValue : r745_15 # 745| r745_16(String &) = Call[operator=] : func:r745_12, this:r745_11, 0:r0_6 # 745| mu745_17(unknown) = ^CallSideEffect : ~m? -# 745| v745_18(void) = ^BufferReadSideEffect[-1] : &:r745_11, ~m? +# 745| v745_18(void) = ^IndirectReadSideEffect[-1] : &:r745_11, ~m? #-----| v0_7(void) = ^BufferReadSideEffect[0] : &:r0_6, ~m? # 745| mu745_19(String) = ^IndirectMayWriteSideEffect[-1] : &:r745_11 #-----| r0_8(glval) = CopyValue : r745_16 @@ -4113,7 +4112,7 @@ ir.cpp: #-----| r0_8(Base &) = CopyValue : r754_14 # 754| r754_15(Base &) = Call[operator=] : func:r754_10, this:r0_5, 0:r0_8 # 754| mu754_16(unknown) = ^CallSideEffect : ~m? -#-----| v0_9(void) = ^BufferReadSideEffect[-1] : &:r0_5, ~m? +#-----| v0_9(void) = ^IndirectReadSideEffect[-1] : &:r0_5, ~m? #-----| v0_10(void) = ^BufferReadSideEffect[0] : &:r0_8, ~m? #-----| mu0_11(Base) = ^IndirectMayWriteSideEffect[-1] : &:r0_5 #-----| r0_12(glval) = CopyValue : r754_15 @@ -4129,7 +4128,7 @@ ir.cpp: #-----| r0_14(String &) = CopyValue : r754_24 # 754| r754_25(String &) = Call[operator=] : func:r754_21, this:r754_20, 0:r0_14 # 754| mu754_26(unknown) = ^CallSideEffect : ~m? -# 754| v754_27(void) = ^BufferReadSideEffect[-1] : &:r754_20, ~m? +# 754| v754_27(void) = ^IndirectReadSideEffect[-1] : &:r754_20, ~m? #-----| v0_15(void) = ^BufferReadSideEffect[0] : &:r0_14, ~m? # 754| mu754_28(String) = ^IndirectMayWriteSideEffect[-1] : &:r754_20 #-----| r0_16(glval) = CopyValue : r754_25 @@ -4220,7 +4219,7 @@ ir.cpp: #-----| r0_8(Middle &) = CopyValue : r763_14 # 763| r763_15(Middle &) = Call[operator=] : func:r763_10, this:r0_5, 0:r0_8 # 763| mu763_16(unknown) = ^CallSideEffect : ~m? -#-----| v0_9(void) = ^BufferReadSideEffect[-1] : &:r0_5, ~m? +#-----| v0_9(void) = ^IndirectReadSideEffect[-1] : &:r0_5, ~m? #-----| v0_10(void) = ^BufferReadSideEffect[0] : &:r0_8, ~m? #-----| mu0_11(Middle) = ^IndirectMayWriteSideEffect[-1] : &:r0_5 #-----| r0_12(glval) = CopyValue : r763_15 @@ -4236,7 +4235,7 @@ ir.cpp: #-----| r0_14(String &) = CopyValue : r763_24 # 763| r763_25(String &) = Call[operator=] : func:r763_21, this:r763_20, 0:r0_14 # 763| mu763_26(unknown) = ^CallSideEffect : ~m? -# 763| v763_27(void) = ^BufferReadSideEffect[-1] : &:r763_20, ~m? +# 763| v763_27(void) = ^IndirectReadSideEffect[-1] : &:r763_20, ~m? #-----| v0_15(void) = ^BufferReadSideEffect[0] : &:r0_14, ~m? # 763| mu763_28(String) = ^IndirectMayWriteSideEffect[-1] : &:r763_20 #-----| r0_16(glval) = CopyValue : r763_25 @@ -4505,7 +4504,7 @@ ir.cpp: # 808| r808_5(Base &) = CopyValue : r808_4 # 808| r808_6(Base &) = Call[operator=] : func:r808_2, this:r808_1, 0:r808_5 # 808| mu808_7(unknown) = ^CallSideEffect : ~m? -# 808| v808_8(void) = ^BufferReadSideEffect[-1] : &:r808_1, ~m? +# 808| v808_8(void) = ^IndirectReadSideEffect[-1] : &:r808_1, ~m? # 808| v808_9(void) = ^BufferReadSideEffect[0] : &:r808_5, ~m? # 808| mu808_10(Base) = ^IndirectMayWriteSideEffect[-1] : &:r808_1 # 808| r808_11(glval) = CopyValue : r808_6 @@ -4525,7 +4524,7 @@ ir.cpp: # 809| r809_14(Base &) = CopyValue : r809_13 # 809| r809_15(Base &) = Call[operator=] : func:r809_2, this:r809_1, 0:r809_14 # 809| mu809_16(unknown) = ^CallSideEffect : ~m? -# 809| v809_17(void) = ^BufferReadSideEffect[-1] : &:r809_1, ~m? +# 809| v809_17(void) = ^IndirectReadSideEffect[-1] : &:r809_1, ~m? # 809| v809_18(void) = ^BufferReadSideEffect[0] : &:r809_14, ~m? # 809| mu809_19(Base) = ^IndirectMayWriteSideEffect[-1] : &:r809_1 # 809| r809_20(glval) = CopyValue : r809_15 @@ -4545,7 +4544,7 @@ ir.cpp: # 810| r810_14(Base &) = CopyValue : r810_13 # 810| r810_15(Base &) = Call[operator=] : func:r810_2, this:r810_1, 0:r810_14 # 810| mu810_16(unknown) = ^CallSideEffect : ~m? -# 810| v810_17(void) = ^BufferReadSideEffect[-1] : &:r810_1, ~m? +# 810| v810_17(void) = ^IndirectReadSideEffect[-1] : &:r810_1, ~m? # 810| v810_18(void) = ^BufferReadSideEffect[0] : &:r810_14, ~m? # 810| mu810_19(Base) = ^IndirectMayWriteSideEffect[-1] : &:r810_1 # 810| r810_20(glval) = CopyValue : r810_15 @@ -4577,7 +4576,7 @@ ir.cpp: # 816| r816_6(Middle &) = CopyValue : r816_5 # 816| r816_7(Middle &) = Call[operator=] : func:r816_2, this:r816_1, 0:r816_6 # 816| mu816_8(unknown) = ^CallSideEffect : ~m? -# 816| v816_9(void) = ^BufferReadSideEffect[-1] : &:r816_1, ~m? +# 816| v816_9(void) = ^IndirectReadSideEffect[-1] : &:r816_1, ~m? # 816| v816_10(void) = ^BufferReadSideEffect[0] : &:r816_6, ~m? # 816| mu816_11(Middle) = ^IndirectMayWriteSideEffect[-1] : &:r816_1 # 816| r816_12(glval) = CopyValue : r816_7 @@ -4589,7 +4588,7 @@ ir.cpp: # 817| r817_6(Middle &) = CopyValue : r817_5 # 817| r817_7(Middle &) = Call[operator=] : func:r817_2, this:r817_1, 0:r817_6 # 817| mu817_8(unknown) = ^CallSideEffect : ~m? -# 817| v817_9(void) = ^BufferReadSideEffect[-1] : &:r817_1, ~m? +# 817| v817_9(void) = ^IndirectReadSideEffect[-1] : &:r817_1, ~m? # 817| v817_10(void) = ^BufferReadSideEffect[0] : &:r817_6, ~m? # 817| mu817_11(Middle) = ^IndirectMayWriteSideEffect[-1] : &:r817_1 # 817| r817_12(glval) = CopyValue : r817_7 @@ -4616,7 +4615,7 @@ ir.cpp: # 822| r822_6(Base &) = CopyValue : r822_5 # 822| r822_7(Base &) = Call[operator=] : func:r822_2, this:r822_1, 0:r822_6 # 822| mu822_8(unknown) = ^CallSideEffect : ~m? -# 822| v822_9(void) = ^BufferReadSideEffect[-1] : &:r822_1, ~m? +# 822| v822_9(void) = ^IndirectReadSideEffect[-1] : &:r822_1, ~m? # 822| v822_10(void) = ^BufferReadSideEffect[0] : &:r822_6, ~m? # 822| mu822_11(Base) = ^IndirectMayWriteSideEffect[-1] : &:r822_1 # 822| r822_12(glval) = CopyValue : r822_7 @@ -4637,7 +4636,7 @@ ir.cpp: # 823| r823_15(Base &) = CopyValue : r823_14 # 823| r823_16(Base &) = Call[operator=] : func:r823_2, this:r823_1, 0:r823_15 # 823| mu823_17(unknown) = ^CallSideEffect : ~m? -# 823| v823_18(void) = ^BufferReadSideEffect[-1] : &:r823_1, ~m? +# 823| v823_18(void) = ^IndirectReadSideEffect[-1] : &:r823_1, ~m? # 823| v823_19(void) = ^BufferReadSideEffect[0] : &:r823_15, ~m? # 823| mu823_20(Base) = ^IndirectMayWriteSideEffect[-1] : &:r823_1 # 823| r823_21(glval) = CopyValue : r823_16 @@ -4658,7 +4657,7 @@ ir.cpp: # 824| r824_15(Base &) = CopyValue : r824_14 # 824| r824_16(Base &) = Call[operator=] : func:r824_2, this:r824_1, 0:r824_15 # 824| mu824_17(unknown) = ^CallSideEffect : ~m? -# 824| v824_18(void) = ^BufferReadSideEffect[-1] : &:r824_1, ~m? +# 824| v824_18(void) = ^IndirectReadSideEffect[-1] : &:r824_1, ~m? # 824| v824_19(void) = ^BufferReadSideEffect[0] : &:r824_15, ~m? # 824| mu824_20(Base) = ^IndirectMayWriteSideEffect[-1] : &:r824_1 # 824| r824_21(glval) = CopyValue : r824_16 @@ -4694,7 +4693,7 @@ ir.cpp: # 830| r830_7(Derived &) = CopyValue : r830_6 # 830| r830_8(Derived &) = Call[operator=] : func:r830_2, this:r830_1, 0:r830_7 # 830| mu830_9(unknown) = ^CallSideEffect : ~m? -# 830| v830_10(void) = ^BufferReadSideEffect[-1] : &:r830_1, ~m? +# 830| v830_10(void) = ^IndirectReadSideEffect[-1] : &:r830_1, ~m? # 830| v830_11(void) = ^BufferReadSideEffect[0] : &:r830_7, ~m? # 830| mu830_12(Derived) = ^IndirectMayWriteSideEffect[-1] : &:r830_1 # 830| r830_13(glval) = CopyValue : r830_8 @@ -4707,7 +4706,7 @@ ir.cpp: # 831| r831_7(Derived &) = CopyValue : r831_6 # 831| r831_8(Derived &) = Call[operator=] : func:r831_2, this:r831_1, 0:r831_7 # 831| mu831_9(unknown) = ^CallSideEffect : ~m? -# 831| v831_10(void) = ^BufferReadSideEffect[-1] : &:r831_1, ~m? +# 831| v831_10(void) = ^IndirectReadSideEffect[-1] : &:r831_1, ~m? # 831| v831_11(void) = ^BufferReadSideEffect[0] : &:r831_7, ~m? # 831| mu831_12(Derived) = ^IndirectMayWriteSideEffect[-1] : &:r831_1 # 831| r831_13(glval) = CopyValue : r831_8 @@ -5688,7 +5687,7 @@ ir.cpp: # 1044| r1044_4(float) = Constant[1.0] : # 1044| r1044_5(char) = Call[operator()] : func:r1044_3, this:r1044_2, 0:r1044_4 # 1044| mu1044_6(unknown) = ^CallSideEffect : ~m? -# 1044| v1044_7(void) = ^BufferReadSideEffect[-1] : &:r1044_2, ~m? +# 1044| v1044_7(void) = ^IndirectReadSideEffect[-1] : &:r1044_2, ~m? # 1045| r1045_1(glval) = VariableAddress[lambda_val] : # 1045| r1045_2(glval) = VariableAddress[#temp1045:20] : # 1045| mu1045_3(decltype([...](...){...})) = Uninitialized[#temp1045:20] : &:r1045_2 @@ -5709,7 +5708,7 @@ ir.cpp: # 1046| r1046_4(float) = Constant[2.0] : # 1046| r1046_5(char) = Call[operator()] : func:r1046_3, this:r1046_2, 0:r1046_4 # 1046| mu1046_6(unknown) = ^CallSideEffect : ~m? -# 1046| v1046_7(void) = ^BufferReadSideEffect[-1] : &:r1046_2, ~m? +# 1046| v1046_7(void) = ^IndirectReadSideEffect[-1] : &:r1046_2, ~m? # 1047| r1047_1(glval) = VariableAddress[lambda_ref_explicit] : # 1047| r1047_2(glval) = VariableAddress[#temp1047:29] : # 1047| mu1047_3(decltype([...](...){...})) = Uninitialized[#temp1047:29] : &:r1047_2 @@ -5727,7 +5726,7 @@ ir.cpp: # 1048| r1048_4(float) = Constant[3.0] : # 1048| r1048_5(char) = Call[operator()] : func:r1048_3, this:r1048_2, 0:r1048_4 # 1048| mu1048_6(unknown) = ^CallSideEffect : ~m? -# 1048| v1048_7(void) = ^BufferReadSideEffect[-1] : &:r1048_2, ~m? +# 1048| v1048_7(void) = ^IndirectReadSideEffect[-1] : &:r1048_2, ~m? # 1049| r1049_1(glval) = VariableAddress[lambda_val_explicit] : # 1049| r1049_2(glval) = VariableAddress[#temp1049:29] : # 1049| mu1049_3(decltype([...](...){...})) = Uninitialized[#temp1049:29] : &:r1049_2 @@ -5744,7 +5743,7 @@ ir.cpp: # 1050| r1050_4(float) = Constant[4.0] : # 1050| r1050_5(char) = Call[operator()] : func:r1050_3, this:r1050_2, 0:r1050_4 # 1050| mu1050_6(unknown) = ^CallSideEffect : ~m? -# 1050| v1050_7(void) = ^BufferReadSideEffect[-1] : &:r1050_2, ~m? +# 1050| v1050_7(void) = ^IndirectReadSideEffect[-1] : &:r1050_2, ~m? # 1051| r1051_1(glval) = VariableAddress[lambda_mixed_explicit] : # 1051| r1051_2(glval) = VariableAddress[#temp1051:31] : # 1051| mu1051_3(decltype([...](...){...})) = Uninitialized[#temp1051:31] : &:r1051_2 @@ -5766,7 +5765,7 @@ ir.cpp: # 1052| r1052_4(float) = Constant[5.0] : # 1052| r1052_5(char) = Call[operator()] : func:r1052_3, this:r1052_2, 0:r1052_4 # 1052| mu1052_6(unknown) = ^CallSideEffect : ~m? -# 1052| v1052_7(void) = ^BufferReadSideEffect[-1] : &:r1052_2, ~m? +# 1052| v1052_7(void) = ^IndirectReadSideEffect[-1] : &:r1052_2, ~m? # 1053| r1053_1(glval) = VariableAddress[r] : # 1053| r1053_2(glval) = VariableAddress[x] : # 1053| r1053_3(int) = Load[x] : &:r1053_2, ~m? @@ -5804,7 +5803,7 @@ ir.cpp: # 1055| r1055_4(float) = Constant[6.0] : # 1055| r1055_5(char) = Call[operator()] : func:r1055_3, this:r1055_2, 0:r1055_4 # 1055| mu1055_6(unknown) = ^CallSideEffect : ~m? -# 1055| v1055_7(void) = ^BufferReadSideEffect[-1] : &:r1055_2, ~m? +# 1055| v1055_7(void) = ^IndirectReadSideEffect[-1] : &:r1055_2, ~m? # 1056| v1056_1(void) = NoOp : # 1040| v1040_10(void) = ReturnIndirection[s] : &:r1040_8, ~m? # 1040| v1040_11(void) = ReturnVoid : @@ -5869,7 +5868,7 @@ ir.cpp: # 1043| r1043_16(glval) = FunctionAddress[c_str] : # 1043| r1043_17(char *) = Call[c_str] : func:r1043_16, this:r1043_15 # 1043| mu1043_18(unknown) = ^CallSideEffect : ~m? -# 1043| v1043_19(void) = ^BufferReadSideEffect[-1] : &:r1043_15, ~m? +# 1043| v1043_19(void) = ^IndirectReadSideEffect[-1] : &:r1043_15, ~m? # 1043| r1043_20(glval) = VariableAddress[#this] : # 1043| r1043_21(lambda [] type at line 1043, col. 21 *) = Load[#this] : &:r1043_20, ~m? # 1043| r1043_22(glval) = FieldAddress[x] : r1043_21 @@ -5921,7 +5920,7 @@ ir.cpp: # 1045| r1045_14(glval) = FunctionAddress[c_str] : # 1045| r1045_15(char *) = Call[c_str] : func:r1045_14, this:r1045_13 # 1045| mu1045_16(unknown) = ^CallSideEffect : ~m? -# 1045| v1045_17(void) = ^BufferReadSideEffect[-1] : &:r1045_13, ~m? +# 1045| v1045_17(void) = ^IndirectReadSideEffect[-1] : &:r1045_13, ~m? # 1045| r1045_18(glval) = VariableAddress[#this] : # 1045| r1045_19(lambda [] type at line 1045, col. 21 *) = Load[#this] : &:r1045_18, ~m? # 1045| r1045_20(glval) = FieldAddress[x] : r1045_19 @@ -5955,7 +5954,7 @@ ir.cpp: # 1047| r1047_16(glval) = FunctionAddress[c_str] : # 1047| r1047_17(char *) = Call[c_str] : func:r1047_16, this:r1047_15 # 1047| mu1047_18(unknown) = ^CallSideEffect : ~m? -# 1047| v1047_19(void) = ^BufferReadSideEffect[-1] : &:r1047_15, ~m? +# 1047| v1047_19(void) = ^IndirectReadSideEffect[-1] : &:r1047_15, ~m? # 1047| r1047_20(int) = Constant[0] : # 1047| r1047_21(glval) = PointerAdd[1] : r1047_17, r1047_20 # 1047| r1047_22(char) = Load[?] : &:r1047_21, ~m? @@ -6003,7 +6002,7 @@ ir.cpp: # 1049| r1049_14(glval) = FunctionAddress[c_str] : # 1049| r1049_15(char *) = Call[c_str] : func:r1049_14, this:r1049_13 # 1049| mu1049_16(unknown) = ^CallSideEffect : ~m? -# 1049| v1049_17(void) = ^BufferReadSideEffect[-1] : &:r1049_13, ~m? +# 1049| v1049_17(void) = ^IndirectReadSideEffect[-1] : &:r1049_13, ~m? # 1049| r1049_18(int) = Constant[0] : # 1049| r1049_19(glval) = PointerAdd[1] : r1049_15, r1049_18 # 1049| r1049_20(char) = Load[?] : &:r1049_19, ~m? @@ -6034,7 +6033,7 @@ ir.cpp: # 1051| r1051_16(glval) = FunctionAddress[c_str] : # 1051| r1051_17(char *) = Call[c_str] : func:r1051_16, this:r1051_15 # 1051| mu1051_18(unknown) = ^CallSideEffect : ~m? -# 1051| v1051_19(void) = ^BufferReadSideEffect[-1] : &:r1051_15, ~m? +# 1051| v1051_19(void) = ^IndirectReadSideEffect[-1] : &:r1051_15, ~m? # 1051| r1051_20(glval) = VariableAddress[#this] : # 1051| r1051_21(lambda [] type at line 1051, col. 32 *) = Load[#this] : &:r1051_20, ~m? # 1051| r1051_22(glval) = FieldAddress[x] : r1051_21 @@ -6068,7 +6067,7 @@ ir.cpp: # 1054| r1054_16(glval) = FunctionAddress[c_str] : # 1054| r1054_17(char *) = Call[c_str] : func:r1054_16, this:r1054_15 # 1054| mu1054_18(unknown) = ^CallSideEffect : ~m? -# 1054| v1054_19(void) = ^BufferReadSideEffect[-1] : &:r1054_15, ~m? +# 1054| v1054_19(void) = ^IndirectReadSideEffect[-1] : &:r1054_15, ~m? # 1054| r1054_20(glval) = VariableAddress[#this] : # 1054| r1054_21(lambda [] type at line 1054, col. 23 *) = Load[#this] : &:r1054_20, ~m? # 1054| r1054_22(glval) = FieldAddress[x] : r1054_21 @@ -6095,37 +6094,37 @@ ir.cpp: # 1077| void RangeBasedFor(vector const&) # 1077| Block 0 -# 1077| v1077_1(void) = EnterFunction : -# 1077| mu1077_2(unknown) = AliasedDefinition : -# 1077| mu1077_3(unknown) = InitializeNonLocal : -# 1077| r1077_4(glval &>) = VariableAddress[v] : -# 1077| mu1077_5(vector &) = InitializeParameter[v] : &:r1077_4 -# 1077| r1077_6(vector &) = Load[v] : &:r1077_4, ~m? -# 1077| mu1077_7(unknown) = InitializeIndirection[v] : &:r1077_6 -# 1078| r1078_1(glval &>) = VariableAddress[(__range)] : -# 1078| r1078_2(glval &>) = VariableAddress[v] : -# 1078| r1078_3(vector &) = Load[v] : &:r1078_2, ~m? -# 1078| r1078_4(glval>) = CopyValue : r1078_3 -# 1078| r1078_5(vector &) = CopyValue : r1078_4 -# 1078| mu1078_6(vector &) = Store[(__range)] : &:r1078_1, r1078_5 -# 1078| r1078_7(glval) = VariableAddress[(__begin)] : -# 1078| r1078_8(glval &>) = VariableAddress[(__range)] : -# 1078| r1078_9(vector &) = Load[(__range)] : &:r1078_8, ~m? -#-----| r0_1(glval>) = CopyValue : r1078_9 -# 1078| r1078_10(glval) = FunctionAddress[begin] : -# 1078| r1078_11(iterator) = Call[begin] : func:r1078_10, this:r0_1 -# 1078| mu1078_12(unknown) = ^CallSideEffect : ~m? -#-----| v0_2(void) = ^BufferReadSideEffect[-1] : &:r0_1, ~m? -# 1078| mu1078_13(iterator) = Store[(__begin)] : &:r1078_7, r1078_11 -# 1078| r1078_14(glval) = VariableAddress[(__end)] : -# 1078| r1078_15(glval &>) = VariableAddress[(__range)] : -# 1078| r1078_16(vector &) = Load[(__range)] : &:r1078_15, ~m? -#-----| r0_3(glval>) = CopyValue : r1078_16 -# 1078| r1078_17(glval) = FunctionAddress[end] : -# 1078| r1078_18(iterator) = Call[end] : func:r1078_17, this:r0_3 -# 1078| mu1078_19(unknown) = ^CallSideEffect : ~m? -#-----| v0_4(void) = ^BufferReadSideEffect[-1] : &:r0_3, ~m? -# 1078| mu1078_20(iterator) = Store[(__end)] : &:r1078_14, r1078_18 +# 1077| v1077_1(void) = EnterFunction : +# 1077| mu1077_2(unknown) = AliasedDefinition : +# 1077| mu1077_3(unknown) = InitializeNonLocal : +# 1077| r1077_4(glval &>) = VariableAddress[v] : +# 1077| mu1077_5(vector &) = InitializeParameter[v] : &:r1077_4 +# 1077| r1077_6(vector &) = Load[v] : &:r1077_4, ~m? +# 1077| mu1077_7(unknown) = InitializeIndirection[v] : &:r1077_6 +# 1078| r1078_1(glval &>) = VariableAddress[(__range)] : +# 1078| r1078_2(glval &>) = VariableAddress[v] : +# 1078| r1078_3(vector &) = Load[v] : &:r1078_2, ~m? +# 1078| r1078_4(glval>) = CopyValue : r1078_3 +# 1078| r1078_5(vector &) = CopyValue : r1078_4 +# 1078| mu1078_6(vector &) = Store[(__range)] : &:r1078_1, r1078_5 +# 1078| r1078_7(glval) = VariableAddress[(__begin)] : +# 1078| r1078_8(glval &>) = VariableAddress[(__range)] : +# 1078| r1078_9(vector &) = Load[(__range)] : &:r1078_8, ~m? +#-----| r0_1(glval>) = CopyValue : r1078_9 +# 1078| r1078_10(glval) = FunctionAddress[begin] : +# 1078| r1078_11(iterator) = Call[begin] : func:r1078_10, this:r0_1 +# 1078| mu1078_12(unknown) = ^CallSideEffect : ~m? +#-----| v0_2(void) = ^IndirectReadSideEffect[-1] : &:r0_1, ~m? +# 1078| mu1078_13(iterator) = Store[(__begin)] : &:r1078_7, r1078_11 +# 1078| r1078_14(glval) = VariableAddress[(__end)] : +# 1078| r1078_15(glval &>) = VariableAddress[(__range)] : +# 1078| r1078_16(vector &) = Load[(__range)] : &:r1078_15, ~m? +#-----| r0_3(glval>) = CopyValue : r1078_16 +# 1078| r1078_17(glval) = FunctionAddress[end] : +# 1078| r1078_18(iterator) = Call[end] : func:r1078_17, this:r0_3 +# 1078| mu1078_19(unknown) = ^CallSideEffect : ~m? +#-----| v0_4(void) = ^IndirectReadSideEffect[-1] : &:r0_3, ~m? +# 1078| mu1078_20(iterator) = Store[(__end)] : &:r1078_14, r1078_18 #-----| Goto -> Block 1 # 1078| Block 1 @@ -6136,26 +6135,26 @@ ir.cpp: # 1078| r1078_24(iterator) = Load[(__end)] : &:r1078_23, ~m? # 1078| r1078_25(bool) = Call[operator!=] : func:r1078_22, this:r0_5, 0:r1078_24 # 1078| mu1078_26(unknown) = ^CallSideEffect : ~m? -#-----| v0_6(void) = ^BufferReadSideEffect[-1] : &:r0_5, ~m? +#-----| v0_6(void) = ^IndirectReadSideEffect[-1] : &:r0_5, ~m? # 1078| v1078_27(void) = ConditionalBranch : r1078_25 #-----| False -> Block 5 #-----| True -> Block 2 # 1078| Block 2 -# 1078| r1078_28(glval) = VariableAddress[e] : -# 1078| r1078_29(glval) = VariableAddress[(__begin)] : -#-----| r0_7(glval) = Convert : r1078_29 -# 1078| r1078_30(glval) = FunctionAddress[operator*] : -# 1078| r1078_31(int &) = Call[operator*] : func:r1078_30, this:r0_7 -# 1078| mu1078_32(unknown) = ^CallSideEffect : ~m? -#-----| v0_8(void) = ^BufferReadSideEffect[-1] : &:r0_7, ~m? -# 1078| r1078_33(int) = Load[?] : &:r1078_31, ~m? -# 1078| mu1078_34(int) = Store[e] : &:r1078_28, r1078_33 -# 1079| r1079_1(glval) = VariableAddress[e] : -# 1079| r1079_2(int) = Load[e] : &:r1079_1, ~m? -# 1079| r1079_3(int) = Constant[0] : -# 1079| r1079_4(bool) = CompareGT : r1079_2, r1079_3 -# 1079| v1079_5(void) = ConditionalBranch : r1079_4 +# 1078| r1078_28(glval) = VariableAddress[e] : +# 1078| r1078_29(glval) = VariableAddress[(__begin)] : +#-----| r0_7(glval) = Convert : r1078_29 +# 1078| r1078_30(glval) = FunctionAddress[operator*] : +# 1078| r1078_31(int &) = Call[operator*] : func:r1078_30, this:r0_7 +# 1078| mu1078_32(unknown) = ^CallSideEffect : ~m? +#-----| v0_8(void) = ^IndirectReadSideEffect[-1] : &:r0_7, ~m? +# 1078| r1078_33(int) = Load[?] : &:r1078_31, ~m? +# 1078| mu1078_34(int) = Store[e] : &:r1078_28, r1078_33 +# 1079| r1079_1(glval) = VariableAddress[e] : +# 1079| r1079_2(int) = Load[e] : &:r1079_1, ~m? +# 1079| r1079_3(int) = Constant[0] : +# 1079| r1079_4(bool) = CompareGT : r1079_2, r1079_3 +# 1079| v1079_5(void) = ConditionalBranch : r1079_4 #-----| False -> Block 4 #-----| True -> Block 3 @@ -6169,36 +6168,36 @@ ir.cpp: # 1078| r1078_37(glval) = FunctionAddress[operator++] : # 1078| r1078_38(iterator &) = Call[operator++] : func:r1078_37, this:r1078_36 # 1078| mu1078_39(unknown) = ^CallSideEffect : ~m? -# 1078| v1078_40(void) = ^BufferReadSideEffect[-1] : &:r1078_36, ~m? +# 1078| v1078_40(void) = ^IndirectReadSideEffect[-1] : &:r1078_36, ~m? # 1078| mu1078_41(iterator) = ^IndirectMayWriteSideEffect[-1] : &:r1078_36 # 1078| r1078_42(glval) = CopyValue : r1078_38 #-----| Goto (back edge) -> Block 1 # 1084| Block 5 -# 1084| r1084_1(glval &>) = VariableAddress[(__range)] : -# 1084| r1084_2(glval &>) = VariableAddress[v] : -# 1084| r1084_3(vector &) = Load[v] : &:r1084_2, ~m? -# 1084| r1084_4(glval>) = CopyValue : r1084_3 -# 1084| r1084_5(vector &) = CopyValue : r1084_4 -# 1084| mu1084_6(vector &) = Store[(__range)] : &:r1084_1, r1084_5 -# 1084| r1084_7(glval) = VariableAddress[(__begin)] : -# 1084| r1084_8(glval &>) = VariableAddress[(__range)] : -# 1084| r1084_9(vector &) = Load[(__range)] : &:r1084_8, ~m? -#-----| r0_9(glval>) = CopyValue : r1084_9 -# 1084| r1084_10(glval) = FunctionAddress[begin] : -# 1084| r1084_11(iterator) = Call[begin] : func:r1084_10, this:r0_9 -# 1084| mu1084_12(unknown) = ^CallSideEffect : ~m? -#-----| v0_10(void) = ^BufferReadSideEffect[-1] : &:r0_9, ~m? -# 1084| mu1084_13(iterator) = Store[(__begin)] : &:r1084_7, r1084_11 -# 1084| r1084_14(glval) = VariableAddress[(__end)] : -# 1084| r1084_15(glval &>) = VariableAddress[(__range)] : -# 1084| r1084_16(vector &) = Load[(__range)] : &:r1084_15, ~m? -#-----| r0_11(glval>) = CopyValue : r1084_16 -# 1084| r1084_17(glval) = FunctionAddress[end] : -# 1084| r1084_18(iterator) = Call[end] : func:r1084_17, this:r0_11 -# 1084| mu1084_19(unknown) = ^CallSideEffect : ~m? -#-----| v0_12(void) = ^BufferReadSideEffect[-1] : &:r0_11, ~m? -# 1084| mu1084_20(iterator) = Store[(__end)] : &:r1084_14, r1084_18 +# 1084| r1084_1(glval &>) = VariableAddress[(__range)] : +# 1084| r1084_2(glval &>) = VariableAddress[v] : +# 1084| r1084_3(vector &) = Load[v] : &:r1084_2, ~m? +# 1084| r1084_4(glval>) = CopyValue : r1084_3 +# 1084| r1084_5(vector &) = CopyValue : r1084_4 +# 1084| mu1084_6(vector &) = Store[(__range)] : &:r1084_1, r1084_5 +# 1084| r1084_7(glval) = VariableAddress[(__begin)] : +# 1084| r1084_8(glval &>) = VariableAddress[(__range)] : +# 1084| r1084_9(vector &) = Load[(__range)] : &:r1084_8, ~m? +#-----| r0_9(glval>) = CopyValue : r1084_9 +# 1084| r1084_10(glval) = FunctionAddress[begin] : +# 1084| r1084_11(iterator) = Call[begin] : func:r1084_10, this:r0_9 +# 1084| mu1084_12(unknown) = ^CallSideEffect : ~m? +#-----| v0_10(void) = ^IndirectReadSideEffect[-1] : &:r0_9, ~m? +# 1084| mu1084_13(iterator) = Store[(__begin)] : &:r1084_7, r1084_11 +# 1084| r1084_14(glval) = VariableAddress[(__end)] : +# 1084| r1084_15(glval &>) = VariableAddress[(__range)] : +# 1084| r1084_16(vector &) = Load[(__range)] : &:r1084_15, ~m? +#-----| r0_11(glval>) = CopyValue : r1084_16 +# 1084| r1084_17(glval) = FunctionAddress[end] : +# 1084| r1084_18(iterator) = Call[end] : func:r1084_17, this:r0_11 +# 1084| mu1084_19(unknown) = ^CallSideEffect : ~m? +#-----| v0_12(void) = ^IndirectReadSideEffect[-1] : &:r0_11, ~m? +# 1084| mu1084_20(iterator) = Store[(__end)] : &:r1084_14, r1084_18 #-----| Goto -> Block 6 # 1084| Block 6 @@ -6209,7 +6208,7 @@ ir.cpp: # 1084| r1084_24(iterator) = Load[(__end)] : &:r1084_23, ~m? # 1084| r1084_25(bool) = Call[operator!=] : func:r1084_22, this:r0_13, 0:r1084_24 # 1084| mu1084_26(unknown) = ^CallSideEffect : ~m? -#-----| v0_14(void) = ^BufferReadSideEffect[-1] : &:r0_13, ~m? +#-----| v0_14(void) = ^IndirectReadSideEffect[-1] : &:r0_13, ~m? # 1084| v1084_27(void) = ConditionalBranch : r1084_25 #-----| False -> Block 10 #-----| True -> Block 8 @@ -6219,29 +6218,29 @@ ir.cpp: # 1084| r1084_29(glval) = FunctionAddress[operator++] : # 1084| r1084_30(iterator &) = Call[operator++] : func:r1084_29, this:r1084_28 # 1084| mu1084_31(unknown) = ^CallSideEffect : ~m? -# 1084| v1084_32(void) = ^BufferReadSideEffect[-1] : &:r1084_28, ~m? +# 1084| v1084_32(void) = ^IndirectReadSideEffect[-1] : &:r1084_28, ~m? # 1084| mu1084_33(iterator) = ^IndirectMayWriteSideEffect[-1] : &:r1084_28 # 1084| r1084_34(glval) = CopyValue : r1084_30 #-----| Goto (back edge) -> Block 6 # 1084| Block 8 -# 1084| r1084_35(glval) = VariableAddress[e] : -# 1084| r1084_36(glval) = VariableAddress[(__begin)] : -#-----| r0_15(glval) = Convert : r1084_36 -# 1084| r1084_37(glval) = FunctionAddress[operator*] : -# 1084| r1084_38(int &) = Call[operator*] : func:r1084_37, this:r0_15 -# 1084| mu1084_39(unknown) = ^CallSideEffect : ~m? -#-----| v0_16(void) = ^BufferReadSideEffect[-1] : &:r0_15, ~m? -# 1084| r1084_40(glval) = CopyValue : r1084_38 -# 1084| r1084_41(glval) = Convert : r1084_40 -# 1084| r1084_42(int &) = CopyValue : r1084_41 -# 1084| mu1084_43(int &) = Store[e] : &:r1084_35, r1084_42 -# 1085| r1085_1(glval) = VariableAddress[e] : -# 1085| r1085_2(int &) = Load[e] : &:r1085_1, ~m? -# 1085| r1085_3(int) = Load[?] : &:r1085_2, ~m? -# 1085| r1085_4(int) = Constant[5] : -# 1085| r1085_5(bool) = CompareLT : r1085_3, r1085_4 -# 1085| v1085_6(void) = ConditionalBranch : r1085_5 +# 1084| r1084_35(glval) = VariableAddress[e] : +# 1084| r1084_36(glval) = VariableAddress[(__begin)] : +#-----| r0_15(glval) = Convert : r1084_36 +# 1084| r1084_37(glval) = FunctionAddress[operator*] : +# 1084| r1084_38(int &) = Call[operator*] : func:r1084_37, this:r0_15 +# 1084| mu1084_39(unknown) = ^CallSideEffect : ~m? +#-----| v0_16(void) = ^IndirectReadSideEffect[-1] : &:r0_15, ~m? +# 1084| r1084_40(glval) = CopyValue : r1084_38 +# 1084| r1084_41(glval) = Convert : r1084_40 +# 1084| r1084_42(int &) = CopyValue : r1084_41 +# 1084| mu1084_43(int &) = Store[e] : &:r1084_35, r1084_42 +# 1085| r1085_1(glval) = VariableAddress[e] : +# 1085| r1085_2(int &) = Load[e] : &:r1085_1, ~m? +# 1085| r1085_3(int) = Load[?] : &:r1085_2, ~m? +# 1085| r1085_4(int) = Constant[5] : +# 1085| r1085_5(bool) = CompareLT : r1085_3, r1085_4 +# 1085| v1085_6(void) = ConditionalBranch : r1085_5 #-----| False -> Block 7 #-----| True -> Block 9 @@ -7525,7 +7524,7 @@ ir.cpp: # 1373| r1373_8(glval) = FunctionAddress[c_str] : # 1373| r1373_9(char *) = Call[c_str] : func:r1373_8, this:r1373_7 # 1373| mu1373_10(unknown) = ^CallSideEffect : ~m? -# 1373| v1373_11(void) = ^BufferReadSideEffect[-1] : &:r1373_7, ~m? +# 1373| v1373_11(void) = ^IndirectReadSideEffect[-1] : &:r1373_7, ~m? # 1374| r1374_1(glval) = VariableAddress[#temp1374:5] : # 1374| r1374_2(glval) = FunctionAddress[returnValue] : # 1374| r1374_3(String) = Call[returnValue] : func:r1374_2 @@ -7535,7 +7534,7 @@ ir.cpp: # 1374| r1374_7(glval) = FunctionAddress[c_str] : # 1374| r1374_8(char *) = Call[c_str] : func:r1374_7, this:r1374_6 # 1374| mu1374_9(unknown) = ^CallSideEffect : ~m? -# 1374| v1374_10(void) = ^BufferReadSideEffect[-1] : &:r1374_6, ~m? +# 1374| v1374_10(void) = ^IndirectReadSideEffect[-1] : &:r1374_6, ~m? # 1376| r1376_1(glval) = VariableAddress[#temp1376:5] : # 1376| r1376_2(glval) = FunctionAddress[defaultConstruct] : # 1376| r1376_3(String) = Call[defaultConstruct] : func:r1376_2 @@ -7589,7 +7588,7 @@ ir.cpp: # 1385| r1385_4(glval) = FunctionAddress[method] : # 1385| v1385_5(void) = Call[method] : func:r1385_4, this:r1385_1 # 1385| mu1385_6(unknown) = ^CallSideEffect : ~m? -# 1385| v1385_7(void) = ^BufferReadSideEffect[-1] : &:r1385_1, ~m? +# 1385| v1385_7(void) = ^IndirectReadSideEffect[-1] : &:r1385_1, ~m? # 1385| mu1385_8(destructor_only) = ^IndirectMayWriteSideEffect[-1] : &:r1385_1 # 1386| r1386_1(glval) = VariableAddress[#temp1386:5] : # 1386| r1386_2(glval) = FunctionAddress[returnValue] : @@ -7599,7 +7598,7 @@ ir.cpp: # 1386| r1386_6(glval) = FunctionAddress[method] : # 1386| v1386_7(void) = Call[method] : func:r1386_6, this:r1386_1 # 1386| mu1386_8(unknown) = ^CallSideEffect : ~m? -# 1386| v1386_9(void) = ^BufferReadSideEffect[-1] : &:r1386_1, ~m? +# 1386| v1386_9(void) = ^IndirectReadSideEffect[-1] : &:r1386_1, ~m? # 1386| mu1386_10(destructor_only) = ^IndirectMayWriteSideEffect[-1] : &:r1386_1 # 1388| r1388_1(glval) = VariableAddress[#temp1388:5] : # 1388| r1388_2(glval) = FunctionAddress[defaultConstruct] : @@ -7667,7 +7666,7 @@ ir.cpp: # 1397| r1397_7(glval) = FunctionAddress[method] : # 1397| v1397_8(void) = Call[method] : func:r1397_7, this:r1397_1 # 1397| mu1397_9(unknown) = ^CallSideEffect : ~m? -# 1397| v1397_10(void) = ^BufferReadSideEffect[-1] : &:r1397_1, ~m? +# 1397| v1397_10(void) = ^IndirectReadSideEffect[-1] : &:r1397_1, ~m? # 1397| mu1397_11(copy_constructor) = ^IndirectMayWriteSideEffect[-1] : &:r1397_1 # 1398| r1398_1(glval) = VariableAddress[#temp1398:5] : # 1398| r1398_2(glval) = FunctionAddress[returnValue] : @@ -7677,7 +7676,7 @@ ir.cpp: # 1398| r1398_6(glval) = FunctionAddress[method] : # 1398| v1398_7(void) = Call[method] : func:r1398_6, this:r1398_1 # 1398| mu1398_8(unknown) = ^CallSideEffect : ~m? -# 1398| v1398_9(void) = ^BufferReadSideEffect[-1] : &:r1398_1, ~m? +# 1398| v1398_9(void) = ^IndirectReadSideEffect[-1] : &:r1398_1, ~m? # 1398| mu1398_10(copy_constructor) = ^IndirectMayWriteSideEffect[-1] : &:r1398_1 # 1399| r1399_1(glval) = VariableAddress[#temp1399:5] : # 1399| r1399_2(glval) = FunctionAddress[defaultConstruct] : @@ -7851,7 +7850,7 @@ ir.cpp: # 1447| r1447_9(glval) = FunctionAddress[f] : # 1447| r1447_10(float) = Call[f] : func:r1447_9, this:r1447_8 # 1447| mu1447_11(unknown) = ^CallSideEffect : ~m? -# 1447| v1447_12(void) = ^BufferReadSideEffect[-1] : &:r1447_8, ~m? +# 1447| v1447_12(void) = ^IndirectReadSideEffect[-1] : &:r1447_8, ~m? # 1447| mu1447_13(float) = Store[f] : &:r1447_1, r1447_10 # 1448| v1448_1(void) = NoOp : # 1443| v1443_4(void) = ReturnVoid : diff --git a/cpp/ql/test/library-tests/ir/ssa/aliased_ssa_ir.expected b/cpp/ql/test/library-tests/ir/ssa/aliased_ssa_ir.expected index c4019a38251..76de50dd792 100644 --- a/cpp/ql/test/library-tests/ir/ssa/aliased_ssa_ir.expected +++ b/cpp/ql/test/library-tests/ir/ssa/aliased_ssa_ir.expected @@ -1059,7 +1059,7 @@ ssa.cpp: # 241| v241_3(void) = Call[g] : func:r241_2, this:r241_1 # 241| m241_4(unknown) = ^CallSideEffect : ~m240_7 # 241| m241_5(unknown) = Chi : total:m240_7, partial:m241_4 -# 241| v241_6(void) = ^BufferReadSideEffect[-1] : &:r241_1, ~m240_9 +# 241| v241_6(void) = ^IndirectReadSideEffect[-1] : &:r241_1, m240_9 # 241| m241_7(Constructible) = ^IndirectMayWriteSideEffect[-1] : &:r241_1 # 241| m241_8(Constructible) = Chi : total:m240_9, partial:m241_7 # 242| r242_1(glval) = VariableAddress[c] : @@ -1067,7 +1067,7 @@ ssa.cpp: # 242| v242_3(void) = Call[g] : func:r242_2, this:r242_1 # 242| m242_4(unknown) = ^CallSideEffect : ~m241_5 # 242| m242_5(unknown) = Chi : total:m241_5, partial:m242_4 -# 242| v242_6(void) = ^BufferReadSideEffect[-1] : &:r242_1, ~m241_8 +# 242| v242_6(void) = ^IndirectReadSideEffect[-1] : &:r242_1, m241_8 # 242| m242_7(Constructible) = ^IndirectMayWriteSideEffect[-1] : &:r242_1 # 242| m242_8(Constructible) = Chi : total:m241_8, partial:m242_7 # 243| r243_1(glval) = VariableAddress[c2] : @@ -1084,7 +1084,7 @@ ssa.cpp: # 244| v244_3(void) = Call[g] : func:r244_2, this:r244_1 # 244| m244_4(unknown) = ^CallSideEffect : ~m243_7 # 244| m244_5(unknown) = Chi : total:m243_7, partial:m244_4 -# 244| v244_6(void) = ^BufferReadSideEffect[-1] : &:r244_1, ~m243_9 +# 244| v244_6(void) = ^IndirectReadSideEffect[-1] : &:r244_1, m243_9 # 244| m244_7(Constructible) = ^IndirectMayWriteSideEffect[-1] : &:r244_1 # 244| m244_8(Constructible) = Chi : total:m243_9, partial:m244_7 # 245| v245_1(void) = NoOp : diff --git a/cpp/ql/test/library-tests/ir/ssa/aliased_ssa_ir_unsound.expected b/cpp/ql/test/library-tests/ir/ssa/aliased_ssa_ir_unsound.expected index a101e638cd0..ab79d20214a 100644 --- a/cpp/ql/test/library-tests/ir/ssa/aliased_ssa_ir_unsound.expected +++ b/cpp/ql/test/library-tests/ir/ssa/aliased_ssa_ir_unsound.expected @@ -1054,7 +1054,7 @@ ssa.cpp: # 241| v241_3(void) = Call[g] : func:r241_2, this:r241_1 # 241| m241_4(unknown) = ^CallSideEffect : ~m240_7 # 241| m241_5(unknown) = Chi : total:m240_7, partial:m241_4 -# 241| v241_6(void) = ^BufferReadSideEffect[-1] : &:r241_1, ~m240_9 +# 241| v241_6(void) = ^IndirectReadSideEffect[-1] : &:r241_1, m240_9 # 241| m241_7(Constructible) = ^IndirectMayWriteSideEffect[-1] : &:r241_1 # 241| m241_8(Constructible) = Chi : total:m240_9, partial:m241_7 # 242| r242_1(glval) = VariableAddress[c] : @@ -1062,7 +1062,7 @@ ssa.cpp: # 242| v242_3(void) = Call[g] : func:r242_2, this:r242_1 # 242| m242_4(unknown) = ^CallSideEffect : ~m241_5 # 242| m242_5(unknown) = Chi : total:m241_5, partial:m242_4 -# 242| v242_6(void) = ^BufferReadSideEffect[-1] : &:r242_1, ~m241_8 +# 242| v242_6(void) = ^IndirectReadSideEffect[-1] : &:r242_1, m241_8 # 242| m242_7(Constructible) = ^IndirectMayWriteSideEffect[-1] : &:r242_1 # 242| m242_8(Constructible) = Chi : total:m241_8, partial:m242_7 # 243| r243_1(glval) = VariableAddress[c2] : @@ -1079,7 +1079,7 @@ ssa.cpp: # 244| v244_3(void) = Call[g] : func:r244_2, this:r244_1 # 244| m244_4(unknown) = ^CallSideEffect : ~m243_7 # 244| m244_5(unknown) = Chi : total:m243_7, partial:m244_4 -# 244| v244_6(void) = ^BufferReadSideEffect[-1] : &:r244_1, ~m243_9 +# 244| v244_6(void) = ^IndirectReadSideEffect[-1] : &:r244_1, m243_9 # 244| m244_7(Constructible) = ^IndirectMayWriteSideEffect[-1] : &:r244_1 # 244| m244_8(Constructible) = Chi : total:m243_9, partial:m244_7 # 245| v245_1(void) = NoOp : diff --git a/cpp/ql/test/library-tests/ir/ssa/unaliased_ssa_ir.expected b/cpp/ql/test/library-tests/ir/ssa/unaliased_ssa_ir.expected index 8b6cf17dbbb..0b257db98a4 100644 --- a/cpp/ql/test/library-tests/ir/ssa/unaliased_ssa_ir.expected +++ b/cpp/ql/test/library-tests/ir/ssa/unaliased_ssa_ir.expected @@ -983,13 +983,13 @@ ssa.cpp: # 241| r241_2(glval) = FunctionAddress[g] : # 241| v241_3(void) = Call[g] : func:r241_2, this:r241_1 # 241| mu241_4(unknown) = ^CallSideEffect : ~m? -# 241| v241_5(void) = ^BufferReadSideEffect[-1] : &:r241_1, ~m? +# 241| v241_5(void) = ^IndirectReadSideEffect[-1] : &:r241_1, ~m? # 241| mu241_6(Constructible) = ^IndirectMayWriteSideEffect[-1] : &:r241_1 # 242| r242_1(glval) = VariableAddress[c] : # 242| r242_2(glval) = FunctionAddress[g] : # 242| v242_3(void) = Call[g] : func:r242_2, this:r242_1 # 242| mu242_4(unknown) = ^CallSideEffect : ~m? -# 242| v242_5(void) = ^BufferReadSideEffect[-1] : &:r242_1, ~m? +# 242| v242_5(void) = ^IndirectReadSideEffect[-1] : &:r242_1, ~m? # 242| mu242_6(Constructible) = ^IndirectMayWriteSideEffect[-1] : &:r242_1 # 243| r243_1(glval) = VariableAddress[c2] : # 243| mu243_2(Constructible) = Uninitialized[c2] : &:r243_1 @@ -1002,7 +1002,7 @@ ssa.cpp: # 244| r244_2(glval) = FunctionAddress[g] : # 244| v244_3(void) = Call[g] : func:r244_2, this:r244_1 # 244| mu244_4(unknown) = ^CallSideEffect : ~m? -# 244| v244_5(void) = ^BufferReadSideEffect[-1] : &:r244_1, ~m? +# 244| v244_5(void) = ^IndirectReadSideEffect[-1] : &:r244_1, ~m? # 244| mu244_6(Constructible) = ^IndirectMayWriteSideEffect[-1] : &:r244_1 # 245| v245_1(void) = NoOp : # 239| v239_4(void) = ReturnVoid : diff --git a/cpp/ql/test/library-tests/ir/ssa/unaliased_ssa_ir_unsound.expected b/cpp/ql/test/library-tests/ir/ssa/unaliased_ssa_ir_unsound.expected index 8b6cf17dbbb..0b257db98a4 100644 --- a/cpp/ql/test/library-tests/ir/ssa/unaliased_ssa_ir_unsound.expected +++ b/cpp/ql/test/library-tests/ir/ssa/unaliased_ssa_ir_unsound.expected @@ -983,13 +983,13 @@ ssa.cpp: # 241| r241_2(glval) = FunctionAddress[g] : # 241| v241_3(void) = Call[g] : func:r241_2, this:r241_1 # 241| mu241_4(unknown) = ^CallSideEffect : ~m? -# 241| v241_5(void) = ^BufferReadSideEffect[-1] : &:r241_1, ~m? +# 241| v241_5(void) = ^IndirectReadSideEffect[-1] : &:r241_1, ~m? # 241| mu241_6(Constructible) = ^IndirectMayWriteSideEffect[-1] : &:r241_1 # 242| r242_1(glval) = VariableAddress[c] : # 242| r242_2(glval) = FunctionAddress[g] : # 242| v242_3(void) = Call[g] : func:r242_2, this:r242_1 # 242| mu242_4(unknown) = ^CallSideEffect : ~m? -# 242| v242_5(void) = ^BufferReadSideEffect[-1] : &:r242_1, ~m? +# 242| v242_5(void) = ^IndirectReadSideEffect[-1] : &:r242_1, ~m? # 242| mu242_6(Constructible) = ^IndirectMayWriteSideEffect[-1] : &:r242_1 # 243| r243_1(glval) = VariableAddress[c2] : # 243| mu243_2(Constructible) = Uninitialized[c2] : &:r243_1 @@ -1002,7 +1002,7 @@ ssa.cpp: # 244| r244_2(glval) = FunctionAddress[g] : # 244| v244_3(void) = Call[g] : func:r244_2, this:r244_1 # 244| mu244_4(unknown) = ^CallSideEffect : ~m? -# 244| v244_5(void) = ^BufferReadSideEffect[-1] : &:r244_1, ~m? +# 244| v244_5(void) = ^IndirectReadSideEffect[-1] : &:r244_1, ~m? # 244| mu244_6(Constructible) = ^IndirectMayWriteSideEffect[-1] : &:r244_1 # 245| v245_1(void) = NoOp : # 239| v239_4(void) = ReturnVoid : diff --git a/cpp/ql/test/library-tests/syntax-zoo/modeled-functions.cpp b/cpp/ql/test/library-tests/syntax-zoo/modeled-functions.cpp new file mode 100644 index 00000000000..c6867a9abe3 --- /dev/null +++ b/cpp/ql/test/library-tests/syntax-zoo/modeled-functions.cpp @@ -0,0 +1,7 @@ +void accept(int arg, char *buf, unsigned long* bufSize); + +void testAccept(int socket1, int socket2) +{ + char buffer[1024]; + accept(socket2, 0, 0); +} diff --git a/cpp/ql/test/query-tests/Critical/MemoryFreed/MemoryNeverFreed.expected b/cpp/ql/test/query-tests/Critical/MemoryFreed/MemoryNeverFreed.expected index 900925d8927..d44735d4bee 100644 --- a/cpp/ql/test/query-tests/Critical/MemoryFreed/MemoryNeverFreed.expected +++ b/cpp/ql/test/query-tests/Critical/MemoryFreed/MemoryNeverFreed.expected @@ -10,3 +10,4 @@ | test.cpp:89:18:89:23 | call to malloc | This memory is never freed | | test.cpp:156:3:156:26 | new | This memory is never freed | | test.cpp:157:3:157:26 | new[] | This memory is never freed | +| test.cpp:167:14:167:19 | call to strdup | This memory is never freed | diff --git a/cpp/ql/test/query-tests/Critical/MemoryFreed/test.cpp b/cpp/ql/test/query-tests/Critical/MemoryFreed/test.cpp index 63636166fc8..651afe85006 100644 --- a/cpp/ql/test/query-tests/Critical/MemoryFreed/test.cpp +++ b/cpp/ql/test/query-tests/Critical/MemoryFreed/test.cpp @@ -156,3 +156,15 @@ int overloadedNew() { new(std::nothrow) int(3); // BAD new(std::nothrow) int[2]; // BAD } + +// --- strdup --- + +char *strdup(const char *s1); +void output_msg(const char *msg); + +void test_strdup() { + char msg[] = "OctoCat"; + char *cpy = strdup(msg); // BAD + + output_msg(cpy); +} diff --git a/cpp/ql/test/query-tests/Likely Bugs/Likely Typos/AssignWhereCompareMeant/AssignWhereCompareMeant.expected b/cpp/ql/test/query-tests/Likely Bugs/Likely Typos/AssignWhereCompareMeant/AssignWhereCompareMeant.expected index 6c4dfaea0a7..a5a1a6ca0bd 100644 --- a/cpp/ql/test/query-tests/Likely Bugs/Likely Typos/AssignWhereCompareMeant/AssignWhereCompareMeant.expected +++ b/cpp/ql/test/query-tests/Likely Bugs/Likely Typos/AssignWhereCompareMeant/AssignWhereCompareMeant.expected @@ -19,3 +19,7 @@ | test.cpp:144:32:144:36 | ... = ... | Use of '=' where '==' may have been intended. | | test.cpp:150:32:150:36 | ... = ... | Use of '=' where '==' may have been intended. | | test.cpp:153:46:153:50 | ... = ... | Use of '=' where '==' may have been intended. | +| test.cpp:166:22:166:27 | ... = ... | Use of '=' where '==' may have been intended. | +| test.cpp:168:24:168:29 | ... = ... | Use of '=' where '==' may have been intended. | +| test.cpp:169:23:169:28 | ... = ... | Use of '=' where '==' may have been intended. | +| test.cpp:171:7:171:12 | ... = ... | Use of '=' where '==' may have been intended. | diff --git a/cpp/ql/test/query-tests/Likely Bugs/Likely Typos/AssignWhereCompareMeant/test.cpp b/cpp/ql/test/query-tests/Likely Bugs/Likely Typos/AssignWhereCompareMeant/test.cpp index 63cac141cc6..3cd18125467 100644 --- a/cpp/ql/test/query-tests/Likely Bugs/Likely Typos/AssignWhereCompareMeant/test.cpp +++ b/cpp/ql/test/query-tests/Likely Bugs/Likely Typos/AssignWhereCompareMeant/test.cpp @@ -153,3 +153,21 @@ void f3(int x, int y) { if((x == 10) || ((z == z) && (x == 1)) && (y = 2)) { // BAD } } + +bool use(int); + +void f4(int x, bool b) { + if((x = 10) && use(x)) {} // GOOD: This is likely just a short-hand way of writing an assignment + // followed by a boolean check. + if((x = 10) && b && use(x)) {} // GOOD: Same reason as above + if((x = 10) && use(x) && b) {} // GOOD: Same reason as above + if((x = 10) && (use(x) && b)) {} // GOOD: Same reason as above + + if(use(x) && b && (x = 10)) {} // BAD: The assignment is the last thing that happens in the comparison. + // This doesn't match the usual pattern. + if((use(x) && b) && (x = 10)) {} // BAD: Same reason as above + if(use(x) && (b && (x = 10))) {} // BAD: Same reason as above + + if((x = 10) || use(x)) {} // BAD: This doesn't follow the usual style of writing an assignment in + // a boolean check. +} diff --git a/cpp/ql/test/query-tests/Likely Bugs/Memory Management/ReturnStackAllocatedMemory/test.cpp b/cpp/ql/test/query-tests/Likely Bugs/Memory Management/ReturnStackAllocatedMemory/test.cpp index 03b202817ca..1ce2558a34f 100644 --- a/cpp/ql/test/query-tests/Likely Bugs/Memory Management/ReturnStackAllocatedMemory/test.cpp +++ b/cpp/ql/test/query-tests/Likely Bugs/Memory Management/ReturnStackAllocatedMemory/test.cpp @@ -189,3 +189,30 @@ int *&conversionInFlow() { int *&pRef = p; // has conversion in the middle of data flow return pRef; // BAD [NOT DETECTED] } + +namespace std { + template + class shared_ptr { + public: + shared_ptr() noexcept; + explicit shared_ptr(T*); + shared_ptr(const shared_ptr&) noexcept; + template shared_ptr(const shared_ptr&) noexcept; + template shared_ptr(shared_ptr&&) noexcept; + + shared_ptr& operator=(const shared_ptr&) noexcept; + shared_ptr& operator=(shared_ptr&&) noexcept; + + T& operator*() const noexcept; + T* operator->() const noexcept; + + T* get() const noexcept; + }; +} + +auto make_read_port() +{ + auto port = std::shared_ptr(new int); + auto ptr = port.get(); + return ptr; // GOOD +} \ No newline at end of file diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-022/semmle/tests/TaintedPath.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-022/semmle/tests/TaintedPath.expected index d7db531fbde..7b513c574ad 100644 --- a/cpp/ql/test/query-tests/Security/CWE/CWE-022/semmle/tests/TaintedPath.expected +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-022/semmle/tests/TaintedPath.expected @@ -3,11 +3,15 @@ edges | test.c:9:23:9:26 | argv | test.c:17:11:17:18 | (const char *)... | | test.c:9:23:9:26 | argv | test.c:17:11:17:18 | fileName | | test.c:9:23:9:26 | argv | test.c:17:11:17:18 | fileName | +| test.c:9:23:9:26 | argv | test.c:17:11:17:18 | fileName indirection | +| test.c:9:23:9:26 | argv | test.c:17:11:17:18 | fileName indirection | nodes | test.c:9:23:9:26 | argv | semmle.label | argv | | test.c:9:23:9:26 | argv | semmle.label | argv | | test.c:17:11:17:18 | (const char *)... | semmle.label | (const char *)... | | test.c:17:11:17:18 | (const char *)... | semmle.label | (const char *)... | | test.c:17:11:17:18 | fileName | semmle.label | fileName | +| test.c:17:11:17:18 | fileName indirection | semmle.label | fileName indirection | +| test.c:17:11:17:18 | fileName indirection | semmle.label | fileName indirection | #select | test.c:17:11:17:18 | fileName | test.c:9:23:9:26 | argv | test.c:17:11:17:18 | fileName | This argument to a file access function is derived from $@ and then passed to fopen(filename) | test.c:9:23:9:26 | argv | user input (argv) | diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-079/semmle/CgiXss/CgiXss.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-079/semmle/CgiXss/CgiXss.expected index 6fc3eab83e9..d9fa0d7029f 100644 --- a/cpp/ql/test/query-tests/Security/CWE/CWE-079/semmle/CgiXss/CgiXss.expected +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-079/semmle/CgiXss/CgiXss.expected @@ -1,13 +1,17 @@ edges | search.c:14:24:14:28 | *query | search.c:17:8:17:12 | (const char *)... | | search.c:14:24:14:28 | *query | search.c:17:8:17:12 | query | +| search.c:14:24:14:28 | *query | search.c:17:8:17:12 | query indirection | | search.c:14:24:14:28 | query | search.c:17:8:17:12 | (const char *)... | | search.c:14:24:14:28 | query | search.c:17:8:17:12 | query | | search.c:14:24:14:28 | query | search.c:17:8:17:12 | query | +| search.c:14:24:14:28 | query | search.c:17:8:17:12 | query indirection | | search.c:22:24:22:28 | *query | search.c:23:39:23:43 | query | | search.c:22:24:22:28 | *query | search.c:23:39:23:43 | query | +| search.c:22:24:22:28 | *query | search.c:23:39:23:43 | query indirection | | search.c:22:24:22:28 | query | search.c:23:39:23:43 | query | | search.c:22:24:22:28 | query | search.c:23:39:23:43 | query | +| search.c:22:24:22:28 | query | search.c:23:39:23:43 | query indirection | | search.c:51:21:51:26 | call to getenv | search.c:55:5:55:15 | raw_query | | search.c:51:21:51:26 | call to getenv | search.c:55:5:55:15 | raw_query | | search.c:51:21:51:26 | call to getenv | search.c:55:17:55:25 | raw_query indirection | @@ -28,11 +32,15 @@ nodes | search.c:17:8:17:12 | query | semmle.label | query | | search.c:17:8:17:12 | query | semmle.label | query | | search.c:17:8:17:12 | query | semmle.label | query | +| search.c:17:8:17:12 | query indirection | semmle.label | query indirection | +| search.c:17:8:17:12 | query indirection | semmle.label | query indirection | | search.c:22:24:22:28 | *query | semmle.label | *query | | search.c:22:24:22:28 | query | semmle.label | query | | search.c:23:39:23:43 | query | semmle.label | query | | search.c:23:39:23:43 | query | semmle.label | query | | search.c:23:39:23:43 | query | semmle.label | query | +| search.c:23:39:23:43 | query indirection | semmle.label | query indirection | +| search.c:23:39:23:43 | query indirection | semmle.label | query indirection | | search.c:51:21:51:26 | call to getenv | semmle.label | call to getenv | | search.c:51:21:51:26 | call to getenv | semmle.label | call to getenv | | search.c:55:5:55:15 | raw_query | semmle.label | raw_query | diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-089/SqlTainted/SqlTainted.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-089/SqlTainted/SqlTainted.expected index af50f184740..e267dd48bba 100644 --- a/cpp/ql/test/query-tests/Security/CWE/CWE-089/SqlTainted/SqlTainted.expected +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-089/SqlTainted/SqlTainted.expected @@ -3,11 +3,15 @@ edges | test.c:15:20:15:23 | argv | test.c:21:18:21:23 | (const char *)... | | test.c:15:20:15:23 | argv | test.c:21:18:21:23 | query1 | | test.c:15:20:15:23 | argv | test.c:21:18:21:23 | query1 | +| test.c:15:20:15:23 | argv | test.c:21:18:21:23 | query1 indirection | +| test.c:15:20:15:23 | argv | test.c:21:18:21:23 | query1 indirection | nodes | test.c:15:20:15:23 | argv | semmle.label | argv | | test.c:15:20:15:23 | argv | semmle.label | argv | | test.c:21:18:21:23 | (const char *)... | semmle.label | (const char *)... | | test.c:21:18:21:23 | (const char *)... | semmle.label | (const char *)... | | test.c:21:18:21:23 | query1 | semmle.label | query1 | +| test.c:21:18:21:23 | query1 indirection | semmle.label | query1 indirection | +| test.c:21:18:21:23 | query1 indirection | semmle.label | query1 indirection | #select | test.c:21:18:21:23 | query1 | test.c:15:20:15:23 | argv | test.c:21:18:21:23 | query1 | This argument to a SQL query function is derived from $@ and then passed to mysql_query(sqlArg) | test.c:15:20:15:23 | argv | user input (argv) | diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-114/semmle/UncontrolledProcessOperation/UncontrolledProcessOperation.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-114/semmle/UncontrolledProcessOperation/UncontrolledProcessOperation.expected index e67d10272aa..5b45af80d5b 100644 --- a/cpp/ql/test/query-tests/Security/CWE/CWE-114/semmle/UncontrolledProcessOperation/UncontrolledProcessOperation.expected +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-114/semmle/UncontrolledProcessOperation/UncontrolledProcessOperation.expected @@ -1,12 +1,16 @@ edges | test.cpp:24:30:24:36 | *command | test.cpp:26:10:26:16 | command | | test.cpp:24:30:24:36 | *command | test.cpp:26:10:26:16 | command | +| test.cpp:24:30:24:36 | *command | test.cpp:26:10:26:16 | command indirection | | test.cpp:24:30:24:36 | command | test.cpp:26:10:26:16 | command | | test.cpp:24:30:24:36 | command | test.cpp:26:10:26:16 | command | +| test.cpp:24:30:24:36 | command | test.cpp:26:10:26:16 | command indirection | | test.cpp:29:30:29:36 | *command | test.cpp:31:10:31:16 | command | | test.cpp:29:30:29:36 | *command | test.cpp:31:10:31:16 | command | +| test.cpp:29:30:29:36 | *command | test.cpp:31:10:31:16 | command indirection | | test.cpp:29:30:29:36 | command | test.cpp:31:10:31:16 | command | | test.cpp:29:30:29:36 | command | test.cpp:31:10:31:16 | command | +| test.cpp:29:30:29:36 | command | test.cpp:31:10:31:16 | command indirection | | test.cpp:42:7:42:16 | call to getenv | test.cpp:24:30:24:36 | command | | test.cpp:42:18:42:23 | call to getenv | test.cpp:42:7:42:16 | call to getenv | | test.cpp:42:18:42:23 | call to getenv | test.cpp:42:18:42:34 | call to getenv indirection | @@ -21,31 +25,55 @@ edges | test.cpp:43:18:43:34 | call to getenv indirection | test.cpp:29:30:29:36 | *command | | test.cpp:56:12:56:17 | buffer | test.cpp:62:10:62:15 | (const char *)... | | test.cpp:56:12:56:17 | buffer | test.cpp:62:10:62:15 | buffer | +| test.cpp:56:12:56:17 | buffer | test.cpp:62:10:62:15 | buffer indirection | | test.cpp:56:12:56:17 | buffer | test.cpp:63:10:63:13 | (const char *)... | | test.cpp:56:12:56:17 | buffer | test.cpp:63:10:63:13 | data | +| test.cpp:56:12:56:17 | buffer | test.cpp:63:10:63:13 | data indirection | | test.cpp:56:12:56:17 | fgets output argument | test.cpp:62:10:62:15 | (const char *)... | | test.cpp:56:12:56:17 | fgets output argument | test.cpp:62:10:62:15 | buffer | +| test.cpp:56:12:56:17 | fgets output argument | test.cpp:62:10:62:15 | buffer indirection | | test.cpp:56:12:56:17 | fgets output argument | test.cpp:63:10:63:13 | (const char *)... | | test.cpp:56:12:56:17 | fgets output argument | test.cpp:63:10:63:13 | data | +| test.cpp:56:12:56:17 | fgets output argument | test.cpp:63:10:63:13 | data indirection | | test.cpp:76:12:76:17 | buffer | test.cpp:78:10:78:15 | (const char *)... | | test.cpp:76:12:76:17 | buffer | test.cpp:78:10:78:15 | buffer | +| test.cpp:76:12:76:17 | buffer | test.cpp:78:10:78:15 | buffer indirection | | test.cpp:76:12:76:17 | buffer | test.cpp:79:10:79:13 | (const char *)... | | test.cpp:76:12:76:17 | buffer | test.cpp:79:10:79:13 | data | +| test.cpp:76:12:76:17 | buffer | test.cpp:79:10:79:13 | data indirection | | test.cpp:76:12:76:17 | fgets output argument | test.cpp:78:10:78:15 | (const char *)... | | test.cpp:76:12:76:17 | fgets output argument | test.cpp:78:10:78:15 | buffer | +| test.cpp:76:12:76:17 | fgets output argument | test.cpp:78:10:78:15 | buffer indirection | | test.cpp:76:12:76:17 | fgets output argument | test.cpp:79:10:79:13 | (const char *)... | | test.cpp:76:12:76:17 | fgets output argument | test.cpp:79:10:79:13 | data | +| test.cpp:76:12:76:17 | fgets output argument | test.cpp:79:10:79:13 | data indirection | +| test.cpp:98:17:98:22 | buffer | test.cpp:99:15:99:20 | (const char *)... | +| test.cpp:98:17:98:22 | buffer | test.cpp:99:15:99:20 | buffer | +| test.cpp:98:17:98:22 | buffer | test.cpp:99:15:99:20 | buffer indirection | +| test.cpp:98:17:98:22 | recv output argument | test.cpp:99:15:99:20 | (const char *)... | +| test.cpp:98:17:98:22 | recv output argument | test.cpp:99:15:99:20 | buffer | +| test.cpp:98:17:98:22 | recv output argument | test.cpp:99:15:99:20 | buffer indirection | +| test.cpp:106:17:106:22 | buffer | test.cpp:107:15:107:20 | (const char *)... | +| test.cpp:106:17:106:22 | buffer | test.cpp:107:15:107:20 | buffer | +| test.cpp:106:17:106:22 | buffer | test.cpp:107:15:107:20 | buffer indirection | +| test.cpp:106:17:106:22 | recv output argument | test.cpp:107:15:107:20 | (const char *)... | +| test.cpp:106:17:106:22 | recv output argument | test.cpp:107:15:107:20 | buffer | +| test.cpp:106:17:106:22 | recv output argument | test.cpp:107:15:107:20 | buffer indirection | nodes | test.cpp:24:30:24:36 | *command | semmle.label | *command | | test.cpp:24:30:24:36 | command | semmle.label | command | | test.cpp:26:10:26:16 | command | semmle.label | command | | test.cpp:26:10:26:16 | command | semmle.label | command | | test.cpp:26:10:26:16 | command | semmle.label | command | +| test.cpp:26:10:26:16 | command indirection | semmle.label | command indirection | +| test.cpp:26:10:26:16 | command indirection | semmle.label | command indirection | | test.cpp:29:30:29:36 | *command | semmle.label | *command | | test.cpp:29:30:29:36 | command | semmle.label | command | | test.cpp:31:10:31:16 | command | semmle.label | command | | test.cpp:31:10:31:16 | command | semmle.label | command | | test.cpp:31:10:31:16 | command | semmle.label | command | +| test.cpp:31:10:31:16 | command indirection | semmle.label | command indirection | +| test.cpp:31:10:31:16 | command indirection | semmle.label | command indirection | | test.cpp:42:7:42:16 | call to getenv | semmle.label | call to getenv | | test.cpp:42:18:42:23 | call to getenv | semmle.label | call to getenv | | test.cpp:42:18:42:34 | (const char *)... | semmle.label | (const char *)... | @@ -59,17 +87,39 @@ nodes | test.cpp:62:10:62:15 | (const char *)... | semmle.label | (const char *)... | | test.cpp:62:10:62:15 | (const char *)... | semmle.label | (const char *)... | | test.cpp:62:10:62:15 | buffer | semmle.label | buffer | +| test.cpp:62:10:62:15 | buffer indirection | semmle.label | buffer indirection | +| test.cpp:62:10:62:15 | buffer indirection | semmle.label | buffer indirection | | test.cpp:63:10:63:13 | (const char *)... | semmle.label | (const char *)... | | test.cpp:63:10:63:13 | (const char *)... | semmle.label | (const char *)... | | test.cpp:63:10:63:13 | data | semmle.label | data | +| test.cpp:63:10:63:13 | data indirection | semmle.label | data indirection | +| test.cpp:63:10:63:13 | data indirection | semmle.label | data indirection | | test.cpp:76:12:76:17 | buffer | semmle.label | buffer | | test.cpp:76:12:76:17 | fgets output argument | semmle.label | fgets output argument | | test.cpp:78:10:78:15 | (const char *)... | semmle.label | (const char *)... | | test.cpp:78:10:78:15 | (const char *)... | semmle.label | (const char *)... | | test.cpp:78:10:78:15 | buffer | semmle.label | buffer | +| test.cpp:78:10:78:15 | buffer indirection | semmle.label | buffer indirection | +| test.cpp:78:10:78:15 | buffer indirection | semmle.label | buffer indirection | | test.cpp:79:10:79:13 | (const char *)... | semmle.label | (const char *)... | | test.cpp:79:10:79:13 | (const char *)... | semmle.label | (const char *)... | | test.cpp:79:10:79:13 | data | semmle.label | data | +| test.cpp:79:10:79:13 | data indirection | semmle.label | data indirection | +| test.cpp:79:10:79:13 | data indirection | semmle.label | data indirection | +| test.cpp:98:17:98:22 | buffer | semmle.label | buffer | +| test.cpp:98:17:98:22 | recv output argument | semmle.label | recv output argument | +| test.cpp:99:15:99:20 | (const char *)... | semmle.label | (const char *)... | +| test.cpp:99:15:99:20 | (const char *)... | semmle.label | (const char *)... | +| test.cpp:99:15:99:20 | buffer | semmle.label | buffer | +| test.cpp:99:15:99:20 | buffer indirection | semmle.label | buffer indirection | +| test.cpp:99:15:99:20 | buffer indirection | semmle.label | buffer indirection | +| test.cpp:106:17:106:22 | buffer | semmle.label | buffer | +| test.cpp:106:17:106:22 | recv output argument | semmle.label | recv output argument | +| test.cpp:107:15:107:20 | (const char *)... | semmle.label | (const char *)... | +| test.cpp:107:15:107:20 | (const char *)... | semmle.label | (const char *)... | +| test.cpp:107:15:107:20 | buffer | semmle.label | buffer | +| test.cpp:107:15:107:20 | buffer indirection | semmle.label | buffer indirection | +| test.cpp:107:15:107:20 | buffer indirection | semmle.label | buffer indirection | #select | test.cpp:26:10:26:16 | command | test.cpp:42:18:42:23 | call to getenv | test.cpp:26:10:26:16 | command | The value of this argument may come from $@ and is being passed to system | test.cpp:42:18:42:23 | call to getenv | call to getenv | | test.cpp:31:10:31:16 | command | test.cpp:43:18:43:23 | call to getenv | test.cpp:31:10:31:16 | command | The value of this argument may come from $@ and is being passed to system | test.cpp:43:18:43:23 | call to getenv | call to getenv | @@ -77,3 +127,5 @@ nodes | test.cpp:63:10:63:13 | data | test.cpp:56:12:56:17 | buffer | test.cpp:63:10:63:13 | data | The value of this argument may come from $@ and is being passed to system | test.cpp:56:12:56:17 | buffer | buffer | | test.cpp:78:10:78:15 | buffer | test.cpp:76:12:76:17 | buffer | test.cpp:78:10:78:15 | buffer | The value of this argument may come from $@ and is being passed to system | test.cpp:76:12:76:17 | buffer | buffer | | test.cpp:79:10:79:13 | data | test.cpp:76:12:76:17 | buffer | test.cpp:79:10:79:13 | data | The value of this argument may come from $@ and is being passed to system | test.cpp:76:12:76:17 | buffer | buffer | +| test.cpp:99:15:99:20 | buffer | test.cpp:98:17:98:22 | buffer | test.cpp:99:15:99:20 | buffer | The value of this argument may come from $@ and is being passed to LoadLibrary | test.cpp:98:17:98:22 | buffer | buffer | +| test.cpp:107:15:107:20 | buffer | test.cpp:106:17:106:22 | buffer | test.cpp:107:15:107:20 | buffer | The value of this argument may come from $@ and is being passed to LoadLibrary | test.cpp:106:17:106:22 | buffer | buffer | diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-114/semmle/UncontrolledProcessOperation/test.cpp b/cpp/ql/test/query-tests/Security/CWE/CWE-114/semmle/UncontrolledProcessOperation/test.cpp index eb9436bcadb..26aff44f3d8 100644 --- a/cpp/ql/test/query-tests/Security/CWE/CWE-114/semmle/UncontrolledProcessOperation/test.cpp +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-114/semmle/UncontrolledProcessOperation/test.cpp @@ -81,3 +81,29 @@ void testReferencePointer2() system(data2); // BAD [NOT DETECTED] } } + +// --- + +typedef unsigned long size_t; + +void accept(int arg, char *buf, size_t *bufSize); +void recv(int arg, char *buf, size_t bufSize); +void LoadLibrary(const char *arg); + +void testAcceptRecv(int socket1, int socket2) +{ + { + char buffer[1024]; + + recv(socket1, buffer, 1024); + LoadLibrary(buffer); // BAD: using data from recv + } + + { + char buffer[1024]; + + accept(socket2, 0, 0); + recv(socket2, buffer, 1024); + LoadLibrary(buffer); // BAD: using data from recv + } +} diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-120/semmle/tests/UnboundedWrite.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-120/semmle/tests/UnboundedWrite.expected index 291c1cb3a71..5255753b235 100644 --- a/cpp/ql/test/query-tests/Security/CWE/CWE-120/semmle/tests/UnboundedWrite.expected +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-120/semmle/tests/UnboundedWrite.expected @@ -5,16 +5,50 @@ edges | tests.c:28:22:28:25 | argv | tests.c:28:22:28:28 | access to array | | tests.c:28:22:28:25 | argv | tests.c:28:22:28:28 | access to array | | tests.c:28:22:28:25 | argv | tests.c:28:22:28:28 | access to array | +| tests.c:28:22:28:25 | argv | tests.c:28:22:28:28 | access to array indirection | +| tests.c:28:22:28:25 | argv | tests.c:28:22:28:28 | access to array indirection | +| tests.c:28:22:28:25 | argv | tests.c:31:15:31:23 | buffer100 | +| tests.c:28:22:28:25 | argv | tests.c:31:15:31:23 | buffer100 | +| tests.c:28:22:28:25 | argv | tests.c:31:15:31:23 | buffer100 indirection | +| tests.c:28:22:28:25 | argv | tests.c:31:15:31:23 | buffer100 indirection | +| tests.c:28:22:28:25 | argv | tests.c:33:21:33:29 | buffer100 | +| tests.c:28:22:28:25 | argv | tests.c:33:21:33:29 | buffer100 | +| tests.c:28:22:28:25 | argv | tests.c:33:21:33:29 | buffer100 indirection | +| tests.c:28:22:28:25 | argv | tests.c:33:21:33:29 | buffer100 indirection | | tests.c:29:28:29:31 | argv | tests.c:29:28:29:34 | access to array | | tests.c:29:28:29:31 | argv | tests.c:29:28:29:34 | access to array | | tests.c:29:28:29:31 | argv | tests.c:29:28:29:34 | access to array | | tests.c:29:28:29:31 | argv | tests.c:29:28:29:34 | access to array | +| tests.c:29:28:29:31 | argv | tests.c:29:28:29:34 | access to array indirection | +| tests.c:29:28:29:31 | argv | tests.c:29:28:29:34 | access to array indirection | +| tests.c:29:28:29:31 | argv | tests.c:31:15:31:23 | buffer100 | +| tests.c:29:28:29:31 | argv | tests.c:31:15:31:23 | buffer100 | +| tests.c:29:28:29:31 | argv | tests.c:31:15:31:23 | buffer100 indirection | +| tests.c:29:28:29:31 | argv | tests.c:31:15:31:23 | buffer100 indirection | +| tests.c:29:28:29:31 | argv | tests.c:33:21:33:29 | buffer100 | +| tests.c:29:28:29:31 | argv | tests.c:33:21:33:29 | buffer100 | +| tests.c:29:28:29:31 | argv | tests.c:33:21:33:29 | buffer100 indirection | +| tests.c:29:28:29:31 | argv | tests.c:33:21:33:29 | buffer100 indirection | +| tests.c:31:15:31:23 | array to pointer conversion | tests.c:31:15:31:23 | buffer100 | +| tests.c:31:15:31:23 | array to pointer conversion | tests.c:31:15:31:23 | buffer100 indirection | +| tests.c:31:15:31:23 | buffer100 | tests.c:31:15:31:23 | buffer100 | +| tests.c:31:15:31:23 | buffer100 | tests.c:31:15:31:23 | buffer100 indirection | +| tests.c:31:15:31:23 | buffer100 | tests.c:33:21:33:29 | buffer100 | +| tests.c:31:15:31:23 | buffer100 | tests.c:33:21:33:29 | buffer100 indirection | +| tests.c:31:15:31:23 | scanf output argument | tests.c:33:21:33:29 | buffer100 | +| tests.c:31:15:31:23 | scanf output argument | tests.c:33:21:33:29 | buffer100 indirection | +| tests.c:33:21:33:29 | array to pointer conversion | tests.c:33:21:33:29 | buffer100 | +| tests.c:33:21:33:29 | array to pointer conversion | tests.c:33:21:33:29 | buffer100 indirection | +| tests.c:33:21:33:29 | buffer100 | tests.c:33:21:33:29 | buffer100 | +| tests.c:33:21:33:29 | buffer100 | tests.c:33:21:33:29 | buffer100 indirection | | tests.c:34:10:34:13 | argv | tests.c:34:10:34:16 | (const char *)... | | tests.c:34:10:34:13 | argv | tests.c:34:10:34:16 | (const char *)... | | tests.c:34:10:34:13 | argv | tests.c:34:10:34:16 | access to array | | tests.c:34:10:34:13 | argv | tests.c:34:10:34:16 | access to array | | tests.c:34:10:34:13 | argv | tests.c:34:10:34:16 | access to array | | tests.c:34:10:34:13 | argv | tests.c:34:10:34:16 | access to array | +| tests.c:34:10:34:13 | argv | tests.c:34:10:34:16 | access to array indirection | +| tests.c:34:10:34:13 | argv | tests.c:34:10:34:16 | access to array indirection | nodes | tests.c:28:22:28:25 | argv | semmle.label | argv | | tests.c:28:22:28:25 | argv | semmle.label | argv | @@ -23,21 +57,30 @@ nodes | tests.c:28:22:28:28 | access to array | semmle.label | access to array | | tests.c:28:22:28:28 | access to array | semmle.label | access to array | | tests.c:28:22:28:28 | access to array | semmle.label | access to array | +| tests.c:28:22:28:28 | access to array indirection | semmle.label | access to array indirection | +| tests.c:28:22:28:28 | access to array indirection | semmle.label | access to array indirection | | tests.c:29:28:29:31 | argv | semmle.label | argv | | tests.c:29:28:29:31 | argv | semmle.label | argv | | tests.c:29:28:29:34 | access to array | semmle.label | access to array | | tests.c:29:28:29:34 | access to array | semmle.label | access to array | | tests.c:29:28:29:34 | access to array | semmle.label | access to array | +| tests.c:29:28:29:34 | access to array indirection | semmle.label | access to array indirection | +| tests.c:29:28:29:34 | access to array indirection | semmle.label | access to array indirection | | tests.c:31:15:31:23 | array to pointer conversion | semmle.label | array to pointer conversion | | tests.c:31:15:31:23 | array to pointer conversion | semmle.label | array to pointer conversion | | tests.c:31:15:31:23 | buffer100 | semmle.label | buffer100 | | tests.c:31:15:31:23 | buffer100 | semmle.label | buffer100 | | tests.c:31:15:31:23 | buffer100 | semmle.label | buffer100 | +| tests.c:31:15:31:23 | buffer100 indirection | semmle.label | buffer100 indirection | +| tests.c:31:15:31:23 | buffer100 indirection | semmle.label | buffer100 indirection | +| tests.c:31:15:31:23 | scanf output argument | semmle.label | scanf output argument | | tests.c:33:21:33:29 | array to pointer conversion | semmle.label | array to pointer conversion | | tests.c:33:21:33:29 | array to pointer conversion | semmle.label | array to pointer conversion | | tests.c:33:21:33:29 | buffer100 | semmle.label | buffer100 | | tests.c:33:21:33:29 | buffer100 | semmle.label | buffer100 | | tests.c:33:21:33:29 | buffer100 | semmle.label | buffer100 | +| tests.c:33:21:33:29 | buffer100 indirection | semmle.label | buffer100 indirection | +| tests.c:33:21:33:29 | buffer100 indirection | semmle.label | buffer100 indirection | | tests.c:34:10:34:13 | argv | semmle.label | argv | | tests.c:34:10:34:13 | argv | semmle.label | argv | | tests.c:34:10:34:16 | (const char *)... | semmle.label | (const char *)... | @@ -45,9 +88,16 @@ nodes | tests.c:34:10:34:16 | access to array | semmle.label | access to array | | tests.c:34:10:34:16 | access to array | semmle.label | access to array | | tests.c:34:10:34:16 | access to array | semmle.label | access to array | +| tests.c:34:10:34:16 | access to array indirection | semmle.label | access to array indirection | +| tests.c:34:10:34:16 | access to array indirection | semmle.label | access to array indirection | #select | tests.c:28:3:28:9 | call to sprintf | tests.c:28:22:28:25 | argv | tests.c:28:22:28:28 | access to array | This 'call to sprintf' with input from $@ may overflow the destination. | tests.c:28:22:28:25 | argv | argv | | tests.c:29:3:29:9 | call to sprintf | tests.c:29:28:29:31 | argv | tests.c:29:28:29:34 | access to array | This 'call to sprintf' with input from $@ may overflow the destination. | tests.c:29:28:29:31 | argv | argv | +| tests.c:31:15:31:23 | buffer100 | tests.c:28:22:28:25 | argv | tests.c:31:15:31:23 | buffer100 | This 'scanf string argument' with input from $@ may overflow the destination. | tests.c:28:22:28:25 | argv | argv | +| tests.c:31:15:31:23 | buffer100 | tests.c:29:28:29:31 | argv | tests.c:31:15:31:23 | buffer100 | This 'scanf string argument' with input from $@ may overflow the destination. | tests.c:29:28:29:31 | argv | argv | | tests.c:31:15:31:23 | buffer100 | tests.c:31:15:31:23 | buffer100 | tests.c:31:15:31:23 | buffer100 | This 'scanf string argument' with input from $@ may overflow the destination. | tests.c:31:15:31:23 | buffer100 | buffer100 | +| tests.c:33:21:33:29 | buffer100 | tests.c:28:22:28:25 | argv | tests.c:33:21:33:29 | buffer100 | This 'scanf string argument' with input from $@ may overflow the destination. | tests.c:28:22:28:25 | argv | argv | +| tests.c:33:21:33:29 | buffer100 | tests.c:29:28:29:31 | argv | tests.c:33:21:33:29 | buffer100 | This 'scanf string argument' with input from $@ may overflow the destination. | tests.c:29:28:29:31 | argv | argv | +| tests.c:33:21:33:29 | buffer100 | tests.c:31:15:31:23 | buffer100 | tests.c:33:21:33:29 | buffer100 | This 'scanf string argument' with input from $@ may overflow the destination. | tests.c:31:15:31:23 | buffer100 | buffer100 | | tests.c:33:21:33:29 | buffer100 | tests.c:33:21:33:29 | buffer100 | tests.c:33:21:33:29 | buffer100 | This 'scanf string argument' with input from $@ may overflow the destination. | tests.c:33:21:33:29 | buffer100 | buffer100 | | tests.c:34:25:34:33 | buffer100 | tests.c:34:10:34:13 | argv | tests.c:34:10:34:16 | access to array | This 'sscanf string argument' with input from $@ may overflow the destination. | tests.c:34:10:34:13 | argv | argv | diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-134/semmle/argv/argvLocal.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-134/semmle/argv/argvLocal.expected index 4c02b16cfe7..b1cf6fbaf8d 100644 --- a/cpp/ql/test/query-tests/Security/CWE/CWE-134/semmle/argv/argvLocal.expected +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-134/semmle/argv/argvLocal.expected @@ -5,54 +5,76 @@ edges | argvLocal.c:95:9:95:12 | argv | argvLocal.c:95:9:95:15 | access to array | | argvLocal.c:95:9:95:12 | argv | argvLocal.c:95:9:95:15 | access to array | | argvLocal.c:95:9:95:12 | argv | argvLocal.c:95:9:95:15 | access to array | +| argvLocal.c:95:9:95:12 | argv | argvLocal.c:95:9:95:15 | access to array indirection | +| argvLocal.c:95:9:95:12 | argv | argvLocal.c:95:9:95:15 | access to array indirection | | argvLocal.c:96:15:96:18 | argv | argvLocal.c:96:15:96:21 | access to array | | argvLocal.c:96:15:96:18 | argv | argvLocal.c:96:15:96:21 | access to array | | argvLocal.c:96:15:96:18 | argv | argvLocal.c:96:15:96:21 | access to array | | argvLocal.c:96:15:96:18 | argv | argvLocal.c:96:15:96:21 | access to array | +| argvLocal.c:96:15:96:18 | argv | argvLocal.c:96:15:96:21 | access to array indirection | +| argvLocal.c:96:15:96:18 | argv | argvLocal.c:96:15:96:21 | access to array indirection | | argvLocal.c:100:7:100:10 | argv | argvLocal.c:101:9:101:10 | (const char *)... | | argvLocal.c:100:7:100:10 | argv | argvLocal.c:101:9:101:10 | (const char *)... | | argvLocal.c:100:7:100:10 | argv | argvLocal.c:101:9:101:10 | i1 | | argvLocal.c:100:7:100:10 | argv | argvLocal.c:101:9:101:10 | i1 | | argvLocal.c:100:7:100:10 | argv | argvLocal.c:101:9:101:10 | i1 | | argvLocal.c:100:7:100:10 | argv | argvLocal.c:101:9:101:10 | i1 | +| argvLocal.c:100:7:100:10 | argv | argvLocal.c:101:9:101:10 | i1 indirection | +| argvLocal.c:100:7:100:10 | argv | argvLocal.c:101:9:101:10 | i1 indirection | | argvLocal.c:100:7:100:10 | argv | argvLocal.c:102:15:102:16 | i1 | | argvLocal.c:100:7:100:10 | argv | argvLocal.c:102:15:102:16 | i1 | | argvLocal.c:100:7:100:10 | argv | argvLocal.c:102:15:102:16 | i1 | | argvLocal.c:100:7:100:10 | argv | argvLocal.c:102:15:102:16 | i1 | +| argvLocal.c:100:7:100:10 | argv | argvLocal.c:102:15:102:16 | i1 indirection | +| argvLocal.c:100:7:100:10 | argv | argvLocal.c:102:15:102:16 | i1 indirection | | argvLocal.c:100:7:100:10 | argv | argvLocal.c:144:9:144:10 | (const char *)... | | argvLocal.c:100:7:100:10 | argv | argvLocal.c:144:9:144:10 | (const char *)... | | argvLocal.c:100:7:100:10 | argv | argvLocal.c:144:9:144:10 | i7 | | argvLocal.c:100:7:100:10 | argv | argvLocal.c:144:9:144:10 | i7 | | argvLocal.c:100:7:100:10 | argv | argvLocal.c:144:9:144:10 | i7 | | argvLocal.c:100:7:100:10 | argv | argvLocal.c:144:9:144:10 | i7 | +| argvLocal.c:100:7:100:10 | argv | argvLocal.c:144:9:144:10 | i7 indirection | +| argvLocal.c:100:7:100:10 | argv | argvLocal.c:144:9:144:10 | i7 indirection | | argvLocal.c:100:7:100:10 | argv | argvLocal.c:145:15:145:16 | i7 | | argvLocal.c:100:7:100:10 | argv | argvLocal.c:145:15:145:16 | i7 | | argvLocal.c:100:7:100:10 | argv | argvLocal.c:145:15:145:16 | i7 | | argvLocal.c:100:7:100:10 | argv | argvLocal.c:145:15:145:16 | i7 | +| argvLocal.c:100:7:100:10 | argv | argvLocal.c:145:15:145:16 | i7 indirection | +| argvLocal.c:100:7:100:10 | argv | argvLocal.c:145:15:145:16 | i7 indirection | | argvLocal.c:105:14:105:17 | argv | argvLocal.c:106:9:106:13 | (const char *)... | | argvLocal.c:105:14:105:17 | argv | argvLocal.c:106:9:106:13 | (const char *)... | | argvLocal.c:105:14:105:17 | argv | argvLocal.c:106:9:106:13 | access to array | | argvLocal.c:105:14:105:17 | argv | argvLocal.c:106:9:106:13 | access to array | | argvLocal.c:105:14:105:17 | argv | argvLocal.c:106:9:106:13 | access to array | | argvLocal.c:105:14:105:17 | argv | argvLocal.c:106:9:106:13 | access to array | +| argvLocal.c:105:14:105:17 | argv | argvLocal.c:106:9:106:13 | access to array indirection | +| argvLocal.c:105:14:105:17 | argv | argvLocal.c:106:9:106:13 | access to array indirection | | argvLocal.c:105:14:105:17 | argv | argvLocal.c:107:15:107:19 | access to array | | argvLocal.c:105:14:105:17 | argv | argvLocal.c:107:15:107:19 | access to array | | argvLocal.c:105:14:105:17 | argv | argvLocal.c:107:15:107:19 | access to array | | argvLocal.c:105:14:105:17 | argv | argvLocal.c:107:15:107:19 | access to array | +| argvLocal.c:105:14:105:17 | argv | argvLocal.c:107:15:107:19 | access to array indirection | +| argvLocal.c:105:14:105:17 | argv | argvLocal.c:107:15:107:19 | access to array indirection | | argvLocal.c:105:14:105:17 | argv | argvLocal.c:110:9:110:11 | (const char *)... | | argvLocal.c:105:14:105:17 | argv | argvLocal.c:110:9:110:11 | (const char *)... | | argvLocal.c:105:14:105:17 | argv | argvLocal.c:110:9:110:11 | * ... | | argvLocal.c:105:14:105:17 | argv | argvLocal.c:110:9:110:11 | * ... | | argvLocal.c:105:14:105:17 | argv | argvLocal.c:110:9:110:11 | * ... | | argvLocal.c:105:14:105:17 | argv | argvLocal.c:110:9:110:11 | * ... | +| argvLocal.c:105:14:105:17 | argv | argvLocal.c:110:9:110:11 | * ... indirection | +| argvLocal.c:105:14:105:17 | argv | argvLocal.c:110:9:110:11 | * ... indirection | | argvLocal.c:105:14:105:17 | argv | argvLocal.c:111:15:111:17 | * ... | | argvLocal.c:105:14:105:17 | argv | argvLocal.c:111:15:111:17 | * ... | | argvLocal.c:105:14:105:17 | argv | argvLocal.c:111:15:111:17 | * ... | | argvLocal.c:105:14:105:17 | argv | argvLocal.c:111:15:111:17 | * ... | +| argvLocal.c:105:14:105:17 | argv | argvLocal.c:111:15:111:17 | * ... indirection | +| argvLocal.c:105:14:105:17 | argv | argvLocal.c:111:15:111:17 | * ... indirection | | argvLocal.c:115:13:115:16 | argv | argvLocal.c:116:9:116:10 | (const char *)... | | argvLocal.c:115:13:115:16 | argv | argvLocal.c:116:9:116:10 | (const char *)... | | argvLocal.c:115:13:115:16 | argv | argvLocal.c:116:9:116:10 | i3 | | argvLocal.c:115:13:115:16 | argv | argvLocal.c:116:9:116:10 | i3 | +| argvLocal.c:115:13:115:16 | argv | argvLocal.c:116:9:116:10 | i3 indirection | +| argvLocal.c:115:13:115:16 | argv | argvLocal.c:116:9:116:10 | i3 indirection | | argvLocal.c:115:13:115:16 | argv | argvLocal.c:117:2:117:13 | i3 | | argvLocal.c:115:13:115:16 | argv | argvLocal.c:117:2:117:13 | i3 | | argvLocal.c:115:13:115:16 | argv | argvLocal.c:117:15:117:16 | array to pointer conversion | @@ -61,10 +83,14 @@ edges | argvLocal.c:115:13:115:16 | argv | argvLocal.c:117:15:117:16 | i3 | | argvLocal.c:115:13:115:16 | argv | argvLocal.c:117:15:117:16 | i3 indirection | | argvLocal.c:115:13:115:16 | argv | argvLocal.c:117:15:117:16 | i3 indirection | +| argvLocal.c:115:13:115:16 | argv | argvLocal.c:117:15:117:16 | i3 indirection | +| argvLocal.c:115:13:115:16 | argv | argvLocal.c:117:15:117:16 | i3 indirection | | argvLocal.c:115:13:115:16 | argv | argvLocal.c:121:9:121:10 | (const char *)... | | argvLocal.c:115:13:115:16 | argv | argvLocal.c:121:9:121:10 | (const char *)... | | argvLocal.c:115:13:115:16 | argv | argvLocal.c:121:9:121:10 | i4 | | argvLocal.c:115:13:115:16 | argv | argvLocal.c:121:9:121:10 | i4 | +| argvLocal.c:115:13:115:16 | argv | argvLocal.c:121:9:121:10 | i4 indirection | +| argvLocal.c:115:13:115:16 | argv | argvLocal.c:121:9:121:10 | i4 indirection | | argvLocal.c:115:13:115:16 | argv | argvLocal.c:122:2:122:13 | i4 | | argvLocal.c:115:13:115:16 | argv | argvLocal.c:122:2:122:13 | i4 | | argvLocal.c:115:13:115:16 | argv | argvLocal.c:122:15:122:16 | i4 | @@ -73,36 +99,50 @@ edges | argvLocal.c:115:13:115:16 | argv | argvLocal.c:122:15:122:16 | i4 | | argvLocal.c:115:13:115:16 | argv | argvLocal.c:122:15:122:16 | i4 indirection | | argvLocal.c:115:13:115:16 | argv | argvLocal.c:122:15:122:16 | i4 indirection | +| argvLocal.c:115:13:115:16 | argv | argvLocal.c:122:15:122:16 | i4 indirection | +| argvLocal.c:115:13:115:16 | argv | argvLocal.c:122:15:122:16 | i4 indirection | | argvLocal.c:115:13:115:16 | argv | argvLocal.c:135:9:135:12 | (const char *)... | | argvLocal.c:115:13:115:16 | argv | argvLocal.c:135:9:135:12 | (const char *)... | | argvLocal.c:115:13:115:16 | argv | argvLocal.c:135:9:135:12 | ... ++ | | argvLocal.c:115:13:115:16 | argv | argvLocal.c:135:9:135:12 | ... ++ | +| argvLocal.c:115:13:115:16 | argv | argvLocal.c:135:9:135:12 | ... ++ indirection | +| argvLocal.c:115:13:115:16 | argv | argvLocal.c:135:9:135:12 | ... ++ indirection | | argvLocal.c:115:13:115:16 | argv | argvLocal.c:136:15:136:18 | -- ... | | argvLocal.c:115:13:115:16 | argv | argvLocal.c:136:15:136:18 | -- ... | | argvLocal.c:115:13:115:16 | argv | argvLocal.c:136:15:136:18 | -- ... | | argvLocal.c:115:13:115:16 | argv | argvLocal.c:136:15:136:18 | -- ... | +| argvLocal.c:115:13:115:16 | argv | argvLocal.c:136:15:136:18 | -- ... indirection | +| argvLocal.c:115:13:115:16 | argv | argvLocal.c:136:15:136:18 | -- ... indirection | | argvLocal.c:117:2:117:13 | i3 | argvLocal.c:117:15:117:16 | printWrapper output argument | | argvLocal.c:117:15:117:16 | i3 indirection | argvLocal.c:117:15:117:16 | printWrapper output argument | | argvLocal.c:117:15:117:16 | printWrapper output argument | argvLocal.c:121:9:121:10 | (const char *)... | | argvLocal.c:117:15:117:16 | printWrapper output argument | argvLocal.c:121:9:121:10 | i4 | +| argvLocal.c:117:15:117:16 | printWrapper output argument | argvLocal.c:121:9:121:10 | i4 indirection | | argvLocal.c:117:15:117:16 | printWrapper output argument | argvLocal.c:122:2:122:13 | i4 | | argvLocal.c:117:15:117:16 | printWrapper output argument | argvLocal.c:122:15:122:16 | i4 | | argvLocal.c:117:15:117:16 | printWrapper output argument | argvLocal.c:122:15:122:16 | i4 | | argvLocal.c:117:15:117:16 | printWrapper output argument | argvLocal.c:122:15:122:16 | i4 indirection | +| argvLocal.c:117:15:117:16 | printWrapper output argument | argvLocal.c:122:15:122:16 | i4 indirection | | argvLocal.c:117:15:117:16 | printWrapper output argument | argvLocal.c:135:9:135:12 | (const char *)... | | argvLocal.c:117:15:117:16 | printWrapper output argument | argvLocal.c:135:9:135:12 | ... ++ | +| argvLocal.c:117:15:117:16 | printWrapper output argument | argvLocal.c:135:9:135:12 | ... ++ indirection | | argvLocal.c:117:15:117:16 | printWrapper output argument | argvLocal.c:136:15:136:18 | -- ... | | argvLocal.c:117:15:117:16 | printWrapper output argument | argvLocal.c:136:15:136:18 | -- ... | +| argvLocal.c:117:15:117:16 | printWrapper output argument | argvLocal.c:136:15:136:18 | -- ... indirection | | argvLocal.c:122:2:122:13 | i4 | argvLocal.c:122:15:122:16 | printWrapper output argument | | argvLocal.c:122:15:122:16 | i4 indirection | argvLocal.c:122:15:122:16 | printWrapper output argument | | argvLocal.c:122:15:122:16 | printWrapper output argument | argvLocal.c:135:9:135:12 | (const char *)... | | argvLocal.c:122:15:122:16 | printWrapper output argument | argvLocal.c:135:9:135:12 | ... ++ | +| argvLocal.c:122:15:122:16 | printWrapper output argument | argvLocal.c:135:9:135:12 | ... ++ indirection | | argvLocal.c:122:15:122:16 | printWrapper output argument | argvLocal.c:136:15:136:18 | -- ... | | argvLocal.c:122:15:122:16 | printWrapper output argument | argvLocal.c:136:15:136:18 | -- ... | +| argvLocal.c:122:15:122:16 | printWrapper output argument | argvLocal.c:136:15:136:18 | -- ... indirection | | argvLocal.c:126:10:126:13 | argv | argvLocal.c:127:9:127:10 | (const char *)... | | argvLocal.c:126:10:126:13 | argv | argvLocal.c:127:9:127:10 | (const char *)... | | argvLocal.c:126:10:126:13 | argv | argvLocal.c:127:9:127:10 | i5 | | argvLocal.c:126:10:126:13 | argv | argvLocal.c:127:9:127:10 | i5 | +| argvLocal.c:126:10:126:13 | argv | argvLocal.c:127:9:127:10 | i5 indirection | +| argvLocal.c:126:10:126:13 | argv | argvLocal.c:127:9:127:10 | i5 indirection | | argvLocal.c:126:10:126:13 | argv | argvLocal.c:128:2:128:13 | i5 | | argvLocal.c:126:10:126:13 | argv | argvLocal.c:128:2:128:13 | i5 | | argvLocal.c:126:10:126:13 | argv | argvLocal.c:128:15:128:16 | array to pointer conversion | @@ -111,56 +151,80 @@ edges | argvLocal.c:126:10:126:13 | argv | argvLocal.c:128:15:128:16 | i5 | | argvLocal.c:126:10:126:13 | argv | argvLocal.c:128:15:128:16 | i5 indirection | | argvLocal.c:126:10:126:13 | argv | argvLocal.c:128:15:128:16 | i5 indirection | +| argvLocal.c:126:10:126:13 | argv | argvLocal.c:128:15:128:16 | i5 indirection | +| argvLocal.c:126:10:126:13 | argv | argvLocal.c:128:15:128:16 | i5 indirection | | argvLocal.c:126:10:126:13 | argv | argvLocal.c:131:9:131:14 | (const char *)... | | argvLocal.c:126:10:126:13 | argv | argvLocal.c:131:9:131:14 | (const char *)... | | argvLocal.c:126:10:126:13 | argv | argvLocal.c:131:9:131:14 | ... + ... | | argvLocal.c:126:10:126:13 | argv | argvLocal.c:131:9:131:14 | ... + ... | +| argvLocal.c:126:10:126:13 | argv | argvLocal.c:131:9:131:14 | ... + ... indirection | +| argvLocal.c:126:10:126:13 | argv | argvLocal.c:131:9:131:14 | ... + ... indirection | | argvLocal.c:126:10:126:13 | argv | argvLocal.c:132:15:132:20 | ... + ... | | argvLocal.c:126:10:126:13 | argv | argvLocal.c:132:15:132:20 | ... + ... | | argvLocal.c:126:10:126:13 | argv | argvLocal.c:132:15:132:20 | ... + ... | | argvLocal.c:126:10:126:13 | argv | argvLocal.c:132:15:132:20 | ... + ... | +| argvLocal.c:126:10:126:13 | argv | argvLocal.c:132:15:132:20 | ... + ... indirection | +| argvLocal.c:126:10:126:13 | argv | argvLocal.c:132:15:132:20 | ... + ... indirection | | argvLocal.c:128:2:128:13 | i5 | argvLocal.c:128:15:128:16 | printWrapper output argument | | argvLocal.c:128:15:128:16 | i5 indirection | argvLocal.c:128:15:128:16 | printWrapper output argument | | argvLocal.c:128:15:128:16 | printWrapper output argument | argvLocal.c:131:9:131:14 | (const char *)... | | argvLocal.c:128:15:128:16 | printWrapper output argument | argvLocal.c:131:9:131:14 | ... + ... | +| argvLocal.c:128:15:128:16 | printWrapper output argument | argvLocal.c:131:9:131:14 | ... + ... indirection | | argvLocal.c:128:15:128:16 | printWrapper output argument | argvLocal.c:132:15:132:20 | ... + ... | | argvLocal.c:128:15:128:16 | printWrapper output argument | argvLocal.c:132:15:132:20 | ... + ... | +| argvLocal.c:128:15:128:16 | printWrapper output argument | argvLocal.c:132:15:132:20 | ... + ... indirection | | argvLocal.c:149:11:149:14 | argv | argvLocal.c:150:9:150:10 | (const char *)... | | argvLocal.c:149:11:149:14 | argv | argvLocal.c:150:9:150:10 | (const char *)... | | argvLocal.c:149:11:149:14 | argv | argvLocal.c:150:9:150:10 | i8 | | argvLocal.c:149:11:149:14 | argv | argvLocal.c:150:9:150:10 | i8 | | argvLocal.c:149:11:149:14 | argv | argvLocal.c:150:9:150:10 | i8 | | argvLocal.c:149:11:149:14 | argv | argvLocal.c:150:9:150:10 | i8 | +| argvLocal.c:149:11:149:14 | argv | argvLocal.c:150:9:150:10 | i8 indirection | +| argvLocal.c:149:11:149:14 | argv | argvLocal.c:150:9:150:10 | i8 indirection | | argvLocal.c:149:11:149:14 | argv | argvLocal.c:151:15:151:16 | i8 | | argvLocal.c:149:11:149:14 | argv | argvLocal.c:151:15:151:16 | i8 | | argvLocal.c:149:11:149:14 | argv | argvLocal.c:151:15:151:16 | i8 | | argvLocal.c:149:11:149:14 | argv | argvLocal.c:151:15:151:16 | i8 | +| argvLocal.c:149:11:149:14 | argv | argvLocal.c:151:15:151:16 | i8 indirection | +| argvLocal.c:149:11:149:14 | argv | argvLocal.c:151:15:151:16 | i8 indirection | | argvLocal.c:156:23:156:26 | argv | argvLocal.c:157:9:157:10 | (const char *)... | | argvLocal.c:156:23:156:26 | argv | argvLocal.c:157:9:157:10 | (const char *)... | | argvLocal.c:156:23:156:26 | argv | argvLocal.c:157:9:157:10 | i9 | | argvLocal.c:156:23:156:26 | argv | argvLocal.c:157:9:157:10 | i9 | +| argvLocal.c:156:23:156:26 | argv | argvLocal.c:157:9:157:10 | i9 indirection | +| argvLocal.c:156:23:156:26 | argv | argvLocal.c:157:9:157:10 | i9 indirection | | argvLocal.c:156:23:156:26 | argv | argvLocal.c:158:15:158:16 | i9 | | argvLocal.c:156:23:156:26 | argv | argvLocal.c:158:15:158:16 | i9 | | argvLocal.c:156:23:156:26 | argv | argvLocal.c:158:15:158:16 | i9 | | argvLocal.c:156:23:156:26 | argv | argvLocal.c:158:15:158:16 | i9 | +| argvLocal.c:156:23:156:26 | argv | argvLocal.c:158:15:158:16 | i9 indirection | +| argvLocal.c:156:23:156:26 | argv | argvLocal.c:158:15:158:16 | i9 indirection | | argvLocal.c:163:22:163:25 | argv | argvLocal.c:164:9:164:11 | (const char *)... | | argvLocal.c:163:22:163:25 | argv | argvLocal.c:164:9:164:11 | (const char *)... | | argvLocal.c:163:22:163:25 | argv | argvLocal.c:164:9:164:11 | i91 | | argvLocal.c:163:22:163:25 | argv | argvLocal.c:164:9:164:11 | i91 | +| argvLocal.c:163:22:163:25 | argv | argvLocal.c:164:9:164:11 | i91 indirection | +| argvLocal.c:163:22:163:25 | argv | argvLocal.c:164:9:164:11 | i91 indirection | | argvLocal.c:163:22:163:25 | argv | argvLocal.c:165:15:165:17 | i91 | | argvLocal.c:163:22:163:25 | argv | argvLocal.c:165:15:165:17 | i91 | | argvLocal.c:163:22:163:25 | argv | argvLocal.c:165:15:165:17 | i91 | | argvLocal.c:163:22:163:25 | argv | argvLocal.c:165:15:165:17 | i91 | +| argvLocal.c:163:22:163:25 | argv | argvLocal.c:165:15:165:17 | i91 indirection | +| argvLocal.c:163:22:163:25 | argv | argvLocal.c:165:15:165:17 | i91 indirection | | argvLocal.c:168:18:168:21 | argv | argvLocal.c:169:9:169:20 | (char *)... | | argvLocal.c:168:18:168:21 | argv | argvLocal.c:169:9:169:20 | (char *)... | | argvLocal.c:168:18:168:21 | argv | argvLocal.c:169:9:169:20 | (const char *)... | | argvLocal.c:168:18:168:21 | argv | argvLocal.c:169:9:169:20 | (const char *)... | +| argvLocal.c:168:18:168:21 | argv | argvLocal.c:169:9:169:20 | i10 indirection | +| argvLocal.c:168:18:168:21 | argv | argvLocal.c:169:9:169:20 | i10 indirection | | argvLocal.c:168:18:168:21 | argv | argvLocal.c:169:18:169:20 | i10 | | argvLocal.c:168:18:168:21 | argv | argvLocal.c:169:18:169:20 | i10 | | argvLocal.c:168:18:168:21 | argv | argvLocal.c:169:18:169:20 | i10 | | argvLocal.c:168:18:168:21 | argv | argvLocal.c:169:18:169:20 | i10 | | argvLocal.c:168:18:168:21 | argv | argvLocal.c:170:15:170:26 | (char *)... | | argvLocal.c:168:18:168:21 | argv | argvLocal.c:170:15:170:26 | (char *)... | +| argvLocal.c:168:18:168:21 | argv | argvLocal.c:170:15:170:26 | i10 indirection | +| argvLocal.c:168:18:168:21 | argv | argvLocal.c:170:15:170:26 | i10 indirection | | argvLocal.c:168:18:168:21 | argv | argvLocal.c:170:24:170:26 | i10 | | argvLocal.c:168:18:168:21 | argv | argvLocal.c:170:24:170:26 | i10 | | argvLocal.c:168:18:168:21 | argv | argvLocal.c:170:24:170:26 | i10 | @@ -176,11 +240,15 @@ nodes | argvLocal.c:95:9:95:15 | access to array | semmle.label | access to array | | argvLocal.c:95:9:95:15 | access to array | semmle.label | access to array | | argvLocal.c:95:9:95:15 | access to array | semmle.label | access to array | +| argvLocal.c:95:9:95:15 | access to array indirection | semmle.label | access to array indirection | +| argvLocal.c:95:9:95:15 | access to array indirection | semmle.label | access to array indirection | | argvLocal.c:96:15:96:18 | argv | semmle.label | argv | | argvLocal.c:96:15:96:18 | argv | semmle.label | argv | | argvLocal.c:96:15:96:21 | access to array | semmle.label | access to array | | argvLocal.c:96:15:96:21 | access to array | semmle.label | access to array | | argvLocal.c:96:15:96:21 | access to array | semmle.label | access to array | +| argvLocal.c:96:15:96:21 | access to array indirection | semmle.label | access to array indirection | +| argvLocal.c:96:15:96:21 | access to array indirection | semmle.label | access to array indirection | | argvLocal.c:100:7:100:10 | argv | semmle.label | argv | | argvLocal.c:100:7:100:10 | argv | semmle.label | argv | | argvLocal.c:101:9:101:10 | (const char *)... | semmle.label | (const char *)... | @@ -188,9 +256,13 @@ nodes | argvLocal.c:101:9:101:10 | i1 | semmle.label | i1 | | argvLocal.c:101:9:101:10 | i1 | semmle.label | i1 | | argvLocal.c:101:9:101:10 | i1 | semmle.label | i1 | +| argvLocal.c:101:9:101:10 | i1 indirection | semmle.label | i1 indirection | +| argvLocal.c:101:9:101:10 | i1 indirection | semmle.label | i1 indirection | | argvLocal.c:102:15:102:16 | i1 | semmle.label | i1 | | argvLocal.c:102:15:102:16 | i1 | semmle.label | i1 | | argvLocal.c:102:15:102:16 | i1 | semmle.label | i1 | +| argvLocal.c:102:15:102:16 | i1 indirection | semmle.label | i1 indirection | +| argvLocal.c:102:15:102:16 | i1 indirection | semmle.label | i1 indirection | | argvLocal.c:105:14:105:17 | argv | semmle.label | argv | | argvLocal.c:105:14:105:17 | argv | semmle.label | argv | | argvLocal.c:106:9:106:13 | (const char *)... | semmle.label | (const char *)... | @@ -198,68 +270,97 @@ nodes | argvLocal.c:106:9:106:13 | access to array | semmle.label | access to array | | argvLocal.c:106:9:106:13 | access to array | semmle.label | access to array | | argvLocal.c:106:9:106:13 | access to array | semmle.label | access to array | +| argvLocal.c:106:9:106:13 | access to array indirection | semmle.label | access to array indirection | +| argvLocal.c:106:9:106:13 | access to array indirection | semmle.label | access to array indirection | | argvLocal.c:107:15:107:19 | access to array | semmle.label | access to array | | argvLocal.c:107:15:107:19 | access to array | semmle.label | access to array | | argvLocal.c:107:15:107:19 | access to array | semmle.label | access to array | +| argvLocal.c:107:15:107:19 | access to array indirection | semmle.label | access to array indirection | +| argvLocal.c:107:15:107:19 | access to array indirection | semmle.label | access to array indirection | | argvLocal.c:110:9:110:11 | (const char *)... | semmle.label | (const char *)... | | argvLocal.c:110:9:110:11 | (const char *)... | semmle.label | (const char *)... | | argvLocal.c:110:9:110:11 | * ... | semmle.label | * ... | | argvLocal.c:110:9:110:11 | * ... | semmle.label | * ... | | argvLocal.c:110:9:110:11 | * ... | semmle.label | * ... | +| argvLocal.c:110:9:110:11 | * ... indirection | semmle.label | * ... indirection | +| argvLocal.c:110:9:110:11 | * ... indirection | semmle.label | * ... indirection | | argvLocal.c:111:15:111:17 | * ... | semmle.label | * ... | | argvLocal.c:111:15:111:17 | * ... | semmle.label | * ... | | argvLocal.c:111:15:111:17 | * ... | semmle.label | * ... | +| argvLocal.c:111:15:111:17 | * ... indirection | semmle.label | * ... indirection | +| argvLocal.c:111:15:111:17 | * ... indirection | semmle.label | * ... indirection | | argvLocal.c:115:13:115:16 | argv | semmle.label | argv | | argvLocal.c:115:13:115:16 | argv | semmle.label | argv | | argvLocal.c:116:9:116:10 | (const char *)... | semmle.label | (const char *)... | | argvLocal.c:116:9:116:10 | (const char *)... | semmle.label | (const char *)... | | argvLocal.c:116:9:116:10 | i3 | semmle.label | i3 | +| argvLocal.c:116:9:116:10 | i3 indirection | semmle.label | i3 indirection | +| argvLocal.c:116:9:116:10 | i3 indirection | semmle.label | i3 indirection | | argvLocal.c:117:2:117:13 | i3 | semmle.label | i3 | | argvLocal.c:117:15:117:16 | array to pointer conversion | semmle.label | array to pointer conversion | | argvLocal.c:117:15:117:16 | array to pointer conversion | semmle.label | array to pointer conversion | | argvLocal.c:117:15:117:16 | i3 | semmle.label | i3 | | argvLocal.c:117:15:117:16 | i3 indirection | semmle.label | i3 indirection | +| argvLocal.c:117:15:117:16 | i3 indirection | semmle.label | i3 indirection | | argvLocal.c:117:15:117:16 | printWrapper output argument | semmle.label | printWrapper output argument | | argvLocal.c:121:9:121:10 | (const char *)... | semmle.label | (const char *)... | | argvLocal.c:121:9:121:10 | (const char *)... | semmle.label | (const char *)... | | argvLocal.c:121:9:121:10 | i4 | semmle.label | i4 | +| argvLocal.c:121:9:121:10 | i4 indirection | semmle.label | i4 indirection | +| argvLocal.c:121:9:121:10 | i4 indirection | semmle.label | i4 indirection | | argvLocal.c:122:2:122:13 | i4 | semmle.label | i4 | | argvLocal.c:122:15:122:16 | i4 | semmle.label | i4 | | argvLocal.c:122:15:122:16 | i4 | semmle.label | i4 | | argvLocal.c:122:15:122:16 | i4 | semmle.label | i4 | | argvLocal.c:122:15:122:16 | i4 indirection | semmle.label | i4 indirection | +| argvLocal.c:122:15:122:16 | i4 indirection | semmle.label | i4 indirection | | argvLocal.c:122:15:122:16 | printWrapper output argument | semmle.label | printWrapper output argument | | argvLocal.c:126:10:126:13 | argv | semmle.label | argv | | argvLocal.c:126:10:126:13 | argv | semmle.label | argv | | argvLocal.c:127:9:127:10 | (const char *)... | semmle.label | (const char *)... | | argvLocal.c:127:9:127:10 | (const char *)... | semmle.label | (const char *)... | | argvLocal.c:127:9:127:10 | i5 | semmle.label | i5 | +| argvLocal.c:127:9:127:10 | i5 indirection | semmle.label | i5 indirection | +| argvLocal.c:127:9:127:10 | i5 indirection | semmle.label | i5 indirection | | argvLocal.c:128:2:128:13 | i5 | semmle.label | i5 | | argvLocal.c:128:15:128:16 | array to pointer conversion | semmle.label | array to pointer conversion | | argvLocal.c:128:15:128:16 | array to pointer conversion | semmle.label | array to pointer conversion | | argvLocal.c:128:15:128:16 | i5 | semmle.label | i5 | | argvLocal.c:128:15:128:16 | i5 indirection | semmle.label | i5 indirection | +| argvLocal.c:128:15:128:16 | i5 indirection | semmle.label | i5 indirection | | argvLocal.c:128:15:128:16 | printWrapper output argument | semmle.label | printWrapper output argument | | argvLocal.c:131:9:131:14 | (const char *)... | semmle.label | (const char *)... | | argvLocal.c:131:9:131:14 | (const char *)... | semmle.label | (const char *)... | | argvLocal.c:131:9:131:14 | ... + ... | semmle.label | ... + ... | +| argvLocal.c:131:9:131:14 | ... + ... indirection | semmle.label | ... + ... indirection | +| argvLocal.c:131:9:131:14 | ... + ... indirection | semmle.label | ... + ... indirection | | argvLocal.c:132:15:132:20 | ... + ... | semmle.label | ... + ... | | argvLocal.c:132:15:132:20 | ... + ... | semmle.label | ... + ... | | argvLocal.c:132:15:132:20 | ... + ... | semmle.label | ... + ... | +| argvLocal.c:132:15:132:20 | ... + ... indirection | semmle.label | ... + ... indirection | +| argvLocal.c:132:15:132:20 | ... + ... indirection | semmle.label | ... + ... indirection | | argvLocal.c:135:9:135:12 | (const char *)... | semmle.label | (const char *)... | | argvLocal.c:135:9:135:12 | (const char *)... | semmle.label | (const char *)... | | argvLocal.c:135:9:135:12 | ... ++ | semmle.label | ... ++ | +| argvLocal.c:135:9:135:12 | ... ++ indirection | semmle.label | ... ++ indirection | +| argvLocal.c:135:9:135:12 | ... ++ indirection | semmle.label | ... ++ indirection | | argvLocal.c:136:15:136:18 | -- ... | semmle.label | -- ... | | argvLocal.c:136:15:136:18 | -- ... | semmle.label | -- ... | | argvLocal.c:136:15:136:18 | -- ... | semmle.label | -- ... | +| argvLocal.c:136:15:136:18 | -- ... indirection | semmle.label | -- ... indirection | +| argvLocal.c:136:15:136:18 | -- ... indirection | semmle.label | -- ... indirection | | argvLocal.c:144:9:144:10 | (const char *)... | semmle.label | (const char *)... | | argvLocal.c:144:9:144:10 | (const char *)... | semmle.label | (const char *)... | | argvLocal.c:144:9:144:10 | i7 | semmle.label | i7 | | argvLocal.c:144:9:144:10 | i7 | semmle.label | i7 | | argvLocal.c:144:9:144:10 | i7 | semmle.label | i7 | +| argvLocal.c:144:9:144:10 | i7 indirection | semmle.label | i7 indirection | +| argvLocal.c:144:9:144:10 | i7 indirection | semmle.label | i7 indirection | | argvLocal.c:145:15:145:16 | i7 | semmle.label | i7 | | argvLocal.c:145:15:145:16 | i7 | semmle.label | i7 | | argvLocal.c:145:15:145:16 | i7 | semmle.label | i7 | +| argvLocal.c:145:15:145:16 | i7 indirection | semmle.label | i7 indirection | +| argvLocal.c:145:15:145:16 | i7 indirection | semmle.label | i7 indirection | | argvLocal.c:149:11:149:14 | argv | semmle.label | argv | | argvLocal.c:149:11:149:14 | argv | semmle.label | argv | | argvLocal.c:150:9:150:10 | (const char *)... | semmle.label | (const char *)... | @@ -267,36 +368,52 @@ nodes | argvLocal.c:150:9:150:10 | i8 | semmle.label | i8 | | argvLocal.c:150:9:150:10 | i8 | semmle.label | i8 | | argvLocal.c:150:9:150:10 | i8 | semmle.label | i8 | +| argvLocal.c:150:9:150:10 | i8 indirection | semmle.label | i8 indirection | +| argvLocal.c:150:9:150:10 | i8 indirection | semmle.label | i8 indirection | | argvLocal.c:151:15:151:16 | i8 | semmle.label | i8 | | argvLocal.c:151:15:151:16 | i8 | semmle.label | i8 | | argvLocal.c:151:15:151:16 | i8 | semmle.label | i8 | +| argvLocal.c:151:15:151:16 | i8 indirection | semmle.label | i8 indirection | +| argvLocal.c:151:15:151:16 | i8 indirection | semmle.label | i8 indirection | | argvLocal.c:156:23:156:26 | argv | semmle.label | argv | | argvLocal.c:156:23:156:26 | argv | semmle.label | argv | | argvLocal.c:157:9:157:10 | (const char *)... | semmle.label | (const char *)... | | argvLocal.c:157:9:157:10 | (const char *)... | semmle.label | (const char *)... | | argvLocal.c:157:9:157:10 | i9 | semmle.label | i9 | +| argvLocal.c:157:9:157:10 | i9 indirection | semmle.label | i9 indirection | +| argvLocal.c:157:9:157:10 | i9 indirection | semmle.label | i9 indirection | | argvLocal.c:158:15:158:16 | i9 | semmle.label | i9 | | argvLocal.c:158:15:158:16 | i9 | semmle.label | i9 | | argvLocal.c:158:15:158:16 | i9 | semmle.label | i9 | +| argvLocal.c:158:15:158:16 | i9 indirection | semmle.label | i9 indirection | +| argvLocal.c:158:15:158:16 | i9 indirection | semmle.label | i9 indirection | | argvLocal.c:163:22:163:25 | argv | semmle.label | argv | | argvLocal.c:163:22:163:25 | argv | semmle.label | argv | | argvLocal.c:164:9:164:11 | (const char *)... | semmle.label | (const char *)... | | argvLocal.c:164:9:164:11 | (const char *)... | semmle.label | (const char *)... | | argvLocal.c:164:9:164:11 | i91 | semmle.label | i91 | +| argvLocal.c:164:9:164:11 | i91 indirection | semmle.label | i91 indirection | +| argvLocal.c:164:9:164:11 | i91 indirection | semmle.label | i91 indirection | | argvLocal.c:165:15:165:17 | i91 | semmle.label | i91 | | argvLocal.c:165:15:165:17 | i91 | semmle.label | i91 | | argvLocal.c:165:15:165:17 | i91 | semmle.label | i91 | +| argvLocal.c:165:15:165:17 | i91 indirection | semmle.label | i91 indirection | +| argvLocal.c:165:15:165:17 | i91 indirection | semmle.label | i91 indirection | | argvLocal.c:168:18:168:21 | argv | semmle.label | argv | | argvLocal.c:168:18:168:21 | argv | semmle.label | argv | | argvLocal.c:169:9:169:20 | (char *)... | semmle.label | (char *)... | | argvLocal.c:169:9:169:20 | (char *)... | semmle.label | (char *)... | | argvLocal.c:169:9:169:20 | (const char *)... | semmle.label | (const char *)... | | argvLocal.c:169:9:169:20 | (const char *)... | semmle.label | (const char *)... | +| argvLocal.c:169:9:169:20 | i10 indirection | semmle.label | i10 indirection | +| argvLocal.c:169:9:169:20 | i10 indirection | semmle.label | i10 indirection | | argvLocal.c:169:18:169:20 | i10 | semmle.label | i10 | | argvLocal.c:169:18:169:20 | i10 | semmle.label | i10 | | argvLocal.c:169:18:169:20 | i10 | semmle.label | i10 | | argvLocal.c:170:15:170:26 | (char *)... | semmle.label | (char *)... | | argvLocal.c:170:15:170:26 | (char *)... | semmle.label | (char *)... | +| argvLocal.c:170:15:170:26 | i10 indirection | semmle.label | i10 indirection | +| argvLocal.c:170:15:170:26 | i10 indirection | semmle.label | i10 indirection | | argvLocal.c:170:24:170:26 | i10 | semmle.label | i10 | | argvLocal.c:170:24:170:26 | i10 | semmle.label | i10 | | argvLocal.c:170:24:170:26 | i10 | semmle.label | i10 | diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-134/semmle/funcs/funcsLocal.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-134/semmle/funcs/funcsLocal.expected index a05e392ecf2..ceaf0489ec6 100644 --- a/cpp/ql/test/query-tests/Security/CWE/CWE-134/semmle/funcs/funcsLocal.expected +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-134/semmle/funcs/funcsLocal.expected @@ -1,51 +1,71 @@ edges | funcsLocal.c:16:8:16:9 | fread output argument | funcsLocal.c:17:9:17:10 | (const char *)... | | funcsLocal.c:16:8:16:9 | fread output argument | funcsLocal.c:17:9:17:10 | i1 | +| funcsLocal.c:16:8:16:9 | fread output argument | funcsLocal.c:17:9:17:10 | i1 indirection | | funcsLocal.c:16:8:16:9 | fread output argument | funcsLocal.c:58:9:58:10 | (const char *)... | | funcsLocal.c:16:8:16:9 | fread output argument | funcsLocal.c:58:9:58:10 | e1 | +| funcsLocal.c:16:8:16:9 | fread output argument | funcsLocal.c:58:9:58:10 | e1 indirection | | funcsLocal.c:16:8:16:9 | i1 | funcsLocal.c:17:9:17:10 | (const char *)... | | funcsLocal.c:16:8:16:9 | i1 | funcsLocal.c:17:9:17:10 | i1 | +| funcsLocal.c:16:8:16:9 | i1 | funcsLocal.c:17:9:17:10 | i1 indirection | | funcsLocal.c:16:8:16:9 | i1 | funcsLocal.c:58:9:58:10 | (const char *)... | | funcsLocal.c:16:8:16:9 | i1 | funcsLocal.c:58:9:58:10 | e1 | +| funcsLocal.c:16:8:16:9 | i1 | funcsLocal.c:58:9:58:10 | e1 indirection | | funcsLocal.c:26:8:26:9 | fgets output argument | funcsLocal.c:27:9:27:10 | (const char *)... | | funcsLocal.c:26:8:26:9 | fgets output argument | funcsLocal.c:27:9:27:10 | i3 | +| funcsLocal.c:26:8:26:9 | fgets output argument | funcsLocal.c:27:9:27:10 | i3 indirection | | funcsLocal.c:26:8:26:9 | i3 | funcsLocal.c:27:9:27:10 | (const char *)... | | funcsLocal.c:26:8:26:9 | i3 | funcsLocal.c:27:9:27:10 | i3 | +| funcsLocal.c:26:8:26:9 | i3 | funcsLocal.c:27:9:27:10 | i3 indirection | | funcsLocal.c:31:13:31:17 | call to fgets | funcsLocal.c:32:9:32:10 | (const char *)... | | funcsLocal.c:31:13:31:17 | call to fgets | funcsLocal.c:32:9:32:10 | (const char *)... | | funcsLocal.c:31:13:31:17 | call to fgets | funcsLocal.c:32:9:32:10 | i4 | | funcsLocal.c:31:13:31:17 | call to fgets | funcsLocal.c:32:9:32:10 | i4 | | funcsLocal.c:31:13:31:17 | call to fgets | funcsLocal.c:32:9:32:10 | i4 | | funcsLocal.c:31:13:31:17 | call to fgets | funcsLocal.c:32:9:32:10 | i4 | +| funcsLocal.c:31:13:31:17 | call to fgets | funcsLocal.c:32:9:32:10 | i4 indirection | +| funcsLocal.c:31:13:31:17 | call to fgets | funcsLocal.c:32:9:32:10 | i4 indirection | | funcsLocal.c:31:19:31:21 | fgets output argument | funcsLocal.c:32:9:32:10 | (const char *)... | | funcsLocal.c:31:19:31:21 | fgets output argument | funcsLocal.c:32:9:32:10 | i4 | +| funcsLocal.c:31:19:31:21 | fgets output argument | funcsLocal.c:32:9:32:10 | i4 indirection | | funcsLocal.c:31:19:31:21 | i41 | funcsLocal.c:32:9:32:10 | (const char *)... | | funcsLocal.c:31:19:31:21 | i41 | funcsLocal.c:32:9:32:10 | i4 | +| funcsLocal.c:31:19:31:21 | i41 | funcsLocal.c:32:9:32:10 | i4 indirection | | funcsLocal.c:36:7:36:8 | gets output argument | funcsLocal.c:37:9:37:10 | (const char *)... | | funcsLocal.c:36:7:36:8 | gets output argument | funcsLocal.c:37:9:37:10 | i5 | +| funcsLocal.c:36:7:36:8 | gets output argument | funcsLocal.c:37:9:37:10 | i5 indirection | | funcsLocal.c:36:7:36:8 | i5 | funcsLocal.c:37:9:37:10 | (const char *)... | | funcsLocal.c:36:7:36:8 | i5 | funcsLocal.c:37:9:37:10 | i5 | +| funcsLocal.c:36:7:36:8 | i5 | funcsLocal.c:37:9:37:10 | i5 indirection | | funcsLocal.c:41:13:41:16 | call to gets | funcsLocal.c:42:9:42:10 | (const char *)... | | funcsLocal.c:41:13:41:16 | call to gets | funcsLocal.c:42:9:42:10 | (const char *)... | | funcsLocal.c:41:13:41:16 | call to gets | funcsLocal.c:42:9:42:10 | i6 | | funcsLocal.c:41:13:41:16 | call to gets | funcsLocal.c:42:9:42:10 | i6 | | funcsLocal.c:41:13:41:16 | call to gets | funcsLocal.c:42:9:42:10 | i6 | | funcsLocal.c:41:13:41:16 | call to gets | funcsLocal.c:42:9:42:10 | i6 | +| funcsLocal.c:41:13:41:16 | call to gets | funcsLocal.c:42:9:42:10 | i6 indirection | +| funcsLocal.c:41:13:41:16 | call to gets | funcsLocal.c:42:9:42:10 | i6 indirection | | funcsLocal.c:41:18:41:20 | gets output argument | funcsLocal.c:42:9:42:10 | (const char *)... | | funcsLocal.c:41:18:41:20 | gets output argument | funcsLocal.c:42:9:42:10 | i6 | +| funcsLocal.c:41:18:41:20 | gets output argument | funcsLocal.c:42:9:42:10 | i6 indirection | | funcsLocal.c:41:18:41:20 | i61 | funcsLocal.c:42:9:42:10 | (const char *)... | | funcsLocal.c:41:18:41:20 | i61 | funcsLocal.c:42:9:42:10 | i6 | +| funcsLocal.c:41:18:41:20 | i61 | funcsLocal.c:42:9:42:10 | i6 indirection | nodes | funcsLocal.c:16:8:16:9 | fread output argument | semmle.label | fread output argument | | funcsLocal.c:16:8:16:9 | i1 | semmle.label | i1 | | funcsLocal.c:17:9:17:10 | (const char *)... | semmle.label | (const char *)... | | funcsLocal.c:17:9:17:10 | (const char *)... | semmle.label | (const char *)... | | funcsLocal.c:17:9:17:10 | i1 | semmle.label | i1 | +| funcsLocal.c:17:9:17:10 | i1 indirection | semmle.label | i1 indirection | +| funcsLocal.c:17:9:17:10 | i1 indirection | semmle.label | i1 indirection | | funcsLocal.c:26:8:26:9 | fgets output argument | semmle.label | fgets output argument | | funcsLocal.c:26:8:26:9 | i3 | semmle.label | i3 | | funcsLocal.c:27:9:27:10 | (const char *)... | semmle.label | (const char *)... | | funcsLocal.c:27:9:27:10 | (const char *)... | semmle.label | (const char *)... | | funcsLocal.c:27:9:27:10 | i3 | semmle.label | i3 | +| funcsLocal.c:27:9:27:10 | i3 indirection | semmle.label | i3 indirection | +| funcsLocal.c:27:9:27:10 | i3 indirection | semmle.label | i3 indirection | | funcsLocal.c:31:13:31:17 | call to fgets | semmle.label | call to fgets | | funcsLocal.c:31:13:31:17 | call to fgets | semmle.label | call to fgets | | funcsLocal.c:31:19:31:21 | fgets output argument | semmle.label | fgets output argument | @@ -55,11 +75,15 @@ nodes | funcsLocal.c:32:9:32:10 | i4 | semmle.label | i4 | | funcsLocal.c:32:9:32:10 | i4 | semmle.label | i4 | | funcsLocal.c:32:9:32:10 | i4 | semmle.label | i4 | +| funcsLocal.c:32:9:32:10 | i4 indirection | semmle.label | i4 indirection | +| funcsLocal.c:32:9:32:10 | i4 indirection | semmle.label | i4 indirection | | funcsLocal.c:36:7:36:8 | gets output argument | semmle.label | gets output argument | | funcsLocal.c:36:7:36:8 | i5 | semmle.label | i5 | | funcsLocal.c:37:9:37:10 | (const char *)... | semmle.label | (const char *)... | | funcsLocal.c:37:9:37:10 | (const char *)... | semmle.label | (const char *)... | | funcsLocal.c:37:9:37:10 | i5 | semmle.label | i5 | +| funcsLocal.c:37:9:37:10 | i5 indirection | semmle.label | i5 indirection | +| funcsLocal.c:37:9:37:10 | i5 indirection | semmle.label | i5 indirection | | funcsLocal.c:41:13:41:16 | call to gets | semmle.label | call to gets | | funcsLocal.c:41:13:41:16 | call to gets | semmle.label | call to gets | | funcsLocal.c:41:18:41:20 | gets output argument | semmle.label | gets output argument | @@ -69,9 +93,13 @@ nodes | funcsLocal.c:42:9:42:10 | i6 | semmle.label | i6 | | funcsLocal.c:42:9:42:10 | i6 | semmle.label | i6 | | funcsLocal.c:42:9:42:10 | i6 | semmle.label | i6 | +| funcsLocal.c:42:9:42:10 | i6 indirection | semmle.label | i6 indirection | +| funcsLocal.c:42:9:42:10 | i6 indirection | semmle.label | i6 indirection | | funcsLocal.c:58:9:58:10 | (const char *)... | semmle.label | (const char *)... | | funcsLocal.c:58:9:58:10 | (const char *)... | semmle.label | (const char *)... | | funcsLocal.c:58:9:58:10 | e1 | semmle.label | e1 | +| funcsLocal.c:58:9:58:10 | e1 indirection | semmle.label | e1 indirection | +| funcsLocal.c:58:9:58:10 | e1 indirection | semmle.label | e1 indirection | #select | funcsLocal.c:17:9:17:10 | i1 | funcsLocal.c:16:8:16:9 | i1 | funcsLocal.c:17:9:17:10 | i1 | The value of this argument may come from $@ and is being used as a formatting argument to printf(format) | funcsLocal.c:16:8:16:9 | i1 | fread | | funcsLocal.c:27:9:27:10 | i3 | funcsLocal.c:26:8:26:9 | i3 | funcsLocal.c:27:9:27:10 | i3 | The value of this argument may come from $@ and is being used as a formatting argument to printf(format) | funcsLocal.c:26:8:26:9 | i3 | fgets | diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-134/semmle/globalVars/UncontrolledFormatStringThroughGlobalVar.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-134/semmle/globalVars/UncontrolledFormatStringThroughGlobalVar.expected index 1e66a438a5a..f095153f39c 100644 --- a/cpp/ql/test/query-tests/Security/CWE/CWE-134/semmle/globalVars/UncontrolledFormatStringThroughGlobalVar.expected +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-134/semmle/globalVars/UncontrolledFormatStringThroughGlobalVar.expected @@ -29,18 +29,23 @@ edges | globalVars.c:24:11:24:14 | argv indirection | globalVars.c:11:22:11:25 | *argv | | globalVars.c:27:9:27:12 | copy | globalVars.c:27:9:27:12 | (const char *)... | | globalVars.c:27:9:27:12 | copy | globalVars.c:27:9:27:12 | copy | +| globalVars.c:27:9:27:12 | copy | globalVars.c:27:9:27:12 | copy indirection | | globalVars.c:30:15:30:18 | copy | globalVars.c:30:15:30:18 | copy | | globalVars.c:30:15:30:18 | copy | globalVars.c:30:15:30:18 | copy | | globalVars.c:30:15:30:18 | copy | globalVars.c:30:15:30:18 | copy | +| globalVars.c:30:15:30:18 | copy | globalVars.c:30:15:30:18 | copy indirection | | globalVars.c:35:2:35:9 | copy | globalVars.c:15:21:15:23 | val | | globalVars.c:35:11:35:14 | copy | globalVars.c:35:2:35:9 | copy | | globalVars.c:38:9:38:13 | copy2 | globalVars.c:38:9:38:13 | (const char *)... | | globalVars.c:38:9:38:13 | copy2 | globalVars.c:38:9:38:13 | copy2 | +| globalVars.c:38:9:38:13 | copy2 | globalVars.c:38:9:38:13 | copy2 indirection | | globalVars.c:41:15:41:19 | copy2 | globalVars.c:41:15:41:19 | copy2 | | globalVars.c:41:15:41:19 | copy2 | globalVars.c:41:15:41:19 | copy2 | | globalVars.c:41:15:41:19 | copy2 | globalVars.c:41:15:41:19 | copy2 | +| globalVars.c:41:15:41:19 | copy2 | globalVars.c:41:15:41:19 | copy2 indirection | | globalVars.c:50:9:50:13 | copy2 | globalVars.c:50:9:50:13 | (const char *)... | | globalVars.c:50:9:50:13 | copy2 | globalVars.c:50:9:50:13 | copy2 | +| globalVars.c:50:9:50:13 | copy2 | globalVars.c:50:9:50:13 | copy2 indirection | nodes | globalVars.c:8:7:8:10 | copy | semmle.label | copy | | globalVars.c:9:7:9:11 | copy2 | semmle.label | copy2 | @@ -58,9 +63,13 @@ nodes | globalVars.c:27:9:27:12 | copy | semmle.label | copy | | globalVars.c:27:9:27:12 | copy | semmle.label | copy | | globalVars.c:27:9:27:12 | copy | semmle.label | copy | +| globalVars.c:27:9:27:12 | copy indirection | semmle.label | copy indirection | +| globalVars.c:27:9:27:12 | copy indirection | semmle.label | copy indirection | | globalVars.c:30:15:30:18 | copy | semmle.label | copy | | globalVars.c:30:15:30:18 | copy | semmle.label | copy | | globalVars.c:30:15:30:18 | copy | semmle.label | copy | +| globalVars.c:30:15:30:18 | copy indirection | semmle.label | copy indirection | +| globalVars.c:30:15:30:18 | copy indirection | semmle.label | copy indirection | | globalVars.c:35:2:35:9 | copy | semmle.label | copy | | globalVars.c:35:11:35:14 | copy | semmle.label | copy | | globalVars.c:38:9:38:13 | (const char *)... | semmle.label | (const char *)... | @@ -68,14 +77,20 @@ nodes | globalVars.c:38:9:38:13 | copy2 | semmle.label | copy2 | | globalVars.c:38:9:38:13 | copy2 | semmle.label | copy2 | | globalVars.c:38:9:38:13 | copy2 | semmle.label | copy2 | +| globalVars.c:38:9:38:13 | copy2 indirection | semmle.label | copy2 indirection | +| globalVars.c:38:9:38:13 | copy2 indirection | semmle.label | copy2 indirection | | globalVars.c:41:15:41:19 | copy2 | semmle.label | copy2 | | globalVars.c:41:15:41:19 | copy2 | semmle.label | copy2 | | globalVars.c:41:15:41:19 | copy2 | semmle.label | copy2 | +| globalVars.c:41:15:41:19 | copy2 indirection | semmle.label | copy2 indirection | +| globalVars.c:41:15:41:19 | copy2 indirection | semmle.label | copy2 indirection | | globalVars.c:50:9:50:13 | (const char *)... | semmle.label | (const char *)... | | globalVars.c:50:9:50:13 | (const char *)... | semmle.label | (const char *)... | | globalVars.c:50:9:50:13 | copy2 | semmle.label | copy2 | | globalVars.c:50:9:50:13 | copy2 | semmle.label | copy2 | | globalVars.c:50:9:50:13 | copy2 | semmle.label | copy2 | +| globalVars.c:50:9:50:13 | copy2 indirection | semmle.label | copy2 indirection | +| globalVars.c:50:9:50:13 | copy2 indirection | semmle.label | copy2 indirection | #select | globalVars.c:27:9:27:12 | copy | globalVars.c:24:11:24:14 | argv | globalVars.c:27:9:27:12 | copy | The value of this argument may come from $@ and is being used as a formatting argument to printf(format) | globalVars.c:24:11:24:14 | argv | argv | | globalVars.c:30:15:30:18 | copy | globalVars.c:24:11:24:14 | argv | globalVars.c:30:15:30:18 | copy | The value of this argument may come from $@ and is being used as a formatting argument to printWrapper(str), which calls printf(format) | globalVars.c:24:11:24:14 | argv | argv | diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-134/semmle/ifs/ifs.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-134/semmle/ifs/ifs.expected index 62c36d0192d..50ae940400a 100644 --- a/cpp/ql/test/query-tests/Security/CWE/CWE-134/semmle/ifs/ifs.expected +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-134/semmle/ifs/ifs.expected @@ -5,66 +5,88 @@ edges | ifs.c:61:8:61:11 | argv | ifs.c:62:9:62:10 | c7 | | ifs.c:61:8:61:11 | argv | ifs.c:62:9:62:10 | c7 | | ifs.c:61:8:61:11 | argv | ifs.c:62:9:62:10 | c7 | +| ifs.c:61:8:61:11 | argv | ifs.c:62:9:62:10 | c7 indirection | +| ifs.c:61:8:61:11 | argv | ifs.c:62:9:62:10 | c7 indirection | | ifs.c:68:8:68:11 | argv | ifs.c:69:9:69:10 | (const char *)... | | ifs.c:68:8:68:11 | argv | ifs.c:69:9:69:10 | (const char *)... | | ifs.c:68:8:68:11 | argv | ifs.c:69:9:69:10 | c8 | | ifs.c:68:8:68:11 | argv | ifs.c:69:9:69:10 | c8 | | ifs.c:68:8:68:11 | argv | ifs.c:69:9:69:10 | c8 | | ifs.c:68:8:68:11 | argv | ifs.c:69:9:69:10 | c8 | +| ifs.c:68:8:68:11 | argv | ifs.c:69:9:69:10 | c8 indirection | +| ifs.c:68:8:68:11 | argv | ifs.c:69:9:69:10 | c8 indirection | | ifs.c:74:8:74:11 | argv | ifs.c:75:9:75:10 | (const char *)... | | ifs.c:74:8:74:11 | argv | ifs.c:75:9:75:10 | (const char *)... | | ifs.c:74:8:74:11 | argv | ifs.c:75:9:75:10 | i1 | | ifs.c:74:8:74:11 | argv | ifs.c:75:9:75:10 | i1 | | ifs.c:74:8:74:11 | argv | ifs.c:75:9:75:10 | i1 | | ifs.c:74:8:74:11 | argv | ifs.c:75:9:75:10 | i1 | +| ifs.c:74:8:74:11 | argv | ifs.c:75:9:75:10 | i1 indirection | +| ifs.c:74:8:74:11 | argv | ifs.c:75:9:75:10 | i1 indirection | | ifs.c:80:8:80:11 | argv | ifs.c:81:9:81:10 | (const char *)... | | ifs.c:80:8:80:11 | argv | ifs.c:81:9:81:10 | (const char *)... | | ifs.c:80:8:80:11 | argv | ifs.c:81:9:81:10 | i2 | | ifs.c:80:8:80:11 | argv | ifs.c:81:9:81:10 | i2 | | ifs.c:80:8:80:11 | argv | ifs.c:81:9:81:10 | i2 | | ifs.c:80:8:80:11 | argv | ifs.c:81:9:81:10 | i2 | +| ifs.c:80:8:80:11 | argv | ifs.c:81:9:81:10 | i2 indirection | +| ifs.c:80:8:80:11 | argv | ifs.c:81:9:81:10 | i2 indirection | | ifs.c:86:8:86:11 | argv | ifs.c:87:9:87:10 | (const char *)... | | ifs.c:86:8:86:11 | argv | ifs.c:87:9:87:10 | (const char *)... | | ifs.c:86:8:86:11 | argv | ifs.c:87:9:87:10 | i3 | | ifs.c:86:8:86:11 | argv | ifs.c:87:9:87:10 | i3 | | ifs.c:86:8:86:11 | argv | ifs.c:87:9:87:10 | i3 | | ifs.c:86:8:86:11 | argv | ifs.c:87:9:87:10 | i3 | +| ifs.c:86:8:86:11 | argv | ifs.c:87:9:87:10 | i3 indirection | +| ifs.c:86:8:86:11 | argv | ifs.c:87:9:87:10 | i3 indirection | | ifs.c:92:8:92:11 | argv | ifs.c:93:9:93:10 | (const char *)... | | ifs.c:92:8:92:11 | argv | ifs.c:93:9:93:10 | (const char *)... | | ifs.c:92:8:92:11 | argv | ifs.c:93:9:93:10 | i4 | | ifs.c:92:8:92:11 | argv | ifs.c:93:9:93:10 | i4 | | ifs.c:92:8:92:11 | argv | ifs.c:93:9:93:10 | i4 | | ifs.c:92:8:92:11 | argv | ifs.c:93:9:93:10 | i4 | +| ifs.c:92:8:92:11 | argv | ifs.c:93:9:93:10 | i4 indirection | +| ifs.c:92:8:92:11 | argv | ifs.c:93:9:93:10 | i4 indirection | | ifs.c:98:8:98:11 | argv | ifs.c:99:9:99:10 | (const char *)... | | ifs.c:98:8:98:11 | argv | ifs.c:99:9:99:10 | (const char *)... | | ifs.c:98:8:98:11 | argv | ifs.c:99:9:99:10 | i5 | | ifs.c:98:8:98:11 | argv | ifs.c:99:9:99:10 | i5 | | ifs.c:98:8:98:11 | argv | ifs.c:99:9:99:10 | i5 | | ifs.c:98:8:98:11 | argv | ifs.c:99:9:99:10 | i5 | +| ifs.c:98:8:98:11 | argv | ifs.c:99:9:99:10 | i5 indirection | +| ifs.c:98:8:98:11 | argv | ifs.c:99:9:99:10 | i5 indirection | | ifs.c:105:8:105:11 | argv | ifs.c:106:9:106:10 | (const char *)... | | ifs.c:105:8:105:11 | argv | ifs.c:106:9:106:10 | (const char *)... | | ifs.c:105:8:105:11 | argv | ifs.c:106:9:106:10 | i6 | | ifs.c:105:8:105:11 | argv | ifs.c:106:9:106:10 | i6 | | ifs.c:105:8:105:11 | argv | ifs.c:106:9:106:10 | i6 | | ifs.c:105:8:105:11 | argv | ifs.c:106:9:106:10 | i6 | +| ifs.c:105:8:105:11 | argv | ifs.c:106:9:106:10 | i6 indirection | +| ifs.c:105:8:105:11 | argv | ifs.c:106:9:106:10 | i6 indirection | | ifs.c:111:8:111:11 | argv | ifs.c:112:9:112:10 | (const char *)... | | ifs.c:111:8:111:11 | argv | ifs.c:112:9:112:10 | (const char *)... | | ifs.c:111:8:111:11 | argv | ifs.c:112:9:112:10 | i7 | | ifs.c:111:8:111:11 | argv | ifs.c:112:9:112:10 | i7 | | ifs.c:111:8:111:11 | argv | ifs.c:112:9:112:10 | i7 | | ifs.c:111:8:111:11 | argv | ifs.c:112:9:112:10 | i7 | +| ifs.c:111:8:111:11 | argv | ifs.c:112:9:112:10 | i7 indirection | +| ifs.c:111:8:111:11 | argv | ifs.c:112:9:112:10 | i7 indirection | | ifs.c:117:8:117:11 | argv | ifs.c:118:9:118:10 | (const char *)... | | ifs.c:117:8:117:11 | argv | ifs.c:118:9:118:10 | (const char *)... | | ifs.c:117:8:117:11 | argv | ifs.c:118:9:118:10 | i8 | | ifs.c:117:8:117:11 | argv | ifs.c:118:9:118:10 | i8 | | ifs.c:117:8:117:11 | argv | ifs.c:118:9:118:10 | i8 | | ifs.c:117:8:117:11 | argv | ifs.c:118:9:118:10 | i8 | +| ifs.c:117:8:117:11 | argv | ifs.c:118:9:118:10 | i8 indirection | +| ifs.c:117:8:117:11 | argv | ifs.c:118:9:118:10 | i8 indirection | | ifs.c:123:8:123:11 | argv | ifs.c:124:9:124:10 | (const char *)... | | ifs.c:123:8:123:11 | argv | ifs.c:124:9:124:10 | (const char *)... | | ifs.c:123:8:123:11 | argv | ifs.c:124:9:124:10 | i9 | | ifs.c:123:8:123:11 | argv | ifs.c:124:9:124:10 | i9 | | ifs.c:123:8:123:11 | argv | ifs.c:124:9:124:10 | i9 | | ifs.c:123:8:123:11 | argv | ifs.c:124:9:124:10 | i9 | +| ifs.c:123:8:123:11 | argv | ifs.c:124:9:124:10 | i9 indirection | +| ifs.c:123:8:123:11 | argv | ifs.c:124:9:124:10 | i9 indirection | nodes | ifs.c:61:8:61:11 | argv | semmle.label | argv | | ifs.c:61:8:61:11 | argv | semmle.label | argv | @@ -73,6 +95,8 @@ nodes | ifs.c:62:9:62:10 | c7 | semmle.label | c7 | | ifs.c:62:9:62:10 | c7 | semmle.label | c7 | | ifs.c:62:9:62:10 | c7 | semmle.label | c7 | +| ifs.c:62:9:62:10 | c7 indirection | semmle.label | c7 indirection | +| ifs.c:62:9:62:10 | c7 indirection | semmle.label | c7 indirection | | ifs.c:68:8:68:11 | argv | semmle.label | argv | | ifs.c:68:8:68:11 | argv | semmle.label | argv | | ifs.c:69:9:69:10 | (const char *)... | semmle.label | (const char *)... | @@ -80,6 +104,8 @@ nodes | ifs.c:69:9:69:10 | c8 | semmle.label | c8 | | ifs.c:69:9:69:10 | c8 | semmle.label | c8 | | ifs.c:69:9:69:10 | c8 | semmle.label | c8 | +| ifs.c:69:9:69:10 | c8 indirection | semmle.label | c8 indirection | +| ifs.c:69:9:69:10 | c8 indirection | semmle.label | c8 indirection | | ifs.c:74:8:74:11 | argv | semmle.label | argv | | ifs.c:74:8:74:11 | argv | semmle.label | argv | | ifs.c:75:9:75:10 | (const char *)... | semmle.label | (const char *)... | @@ -87,6 +113,8 @@ nodes | ifs.c:75:9:75:10 | i1 | semmle.label | i1 | | ifs.c:75:9:75:10 | i1 | semmle.label | i1 | | ifs.c:75:9:75:10 | i1 | semmle.label | i1 | +| ifs.c:75:9:75:10 | i1 indirection | semmle.label | i1 indirection | +| ifs.c:75:9:75:10 | i1 indirection | semmle.label | i1 indirection | | ifs.c:80:8:80:11 | argv | semmle.label | argv | | ifs.c:80:8:80:11 | argv | semmle.label | argv | | ifs.c:81:9:81:10 | (const char *)... | semmle.label | (const char *)... | @@ -94,6 +122,8 @@ nodes | ifs.c:81:9:81:10 | i2 | semmle.label | i2 | | ifs.c:81:9:81:10 | i2 | semmle.label | i2 | | ifs.c:81:9:81:10 | i2 | semmle.label | i2 | +| ifs.c:81:9:81:10 | i2 indirection | semmle.label | i2 indirection | +| ifs.c:81:9:81:10 | i2 indirection | semmle.label | i2 indirection | | ifs.c:86:8:86:11 | argv | semmle.label | argv | | ifs.c:86:8:86:11 | argv | semmle.label | argv | | ifs.c:87:9:87:10 | (const char *)... | semmle.label | (const char *)... | @@ -101,6 +131,8 @@ nodes | ifs.c:87:9:87:10 | i3 | semmle.label | i3 | | ifs.c:87:9:87:10 | i3 | semmle.label | i3 | | ifs.c:87:9:87:10 | i3 | semmle.label | i3 | +| ifs.c:87:9:87:10 | i3 indirection | semmle.label | i3 indirection | +| ifs.c:87:9:87:10 | i3 indirection | semmle.label | i3 indirection | | ifs.c:92:8:92:11 | argv | semmle.label | argv | | ifs.c:92:8:92:11 | argv | semmle.label | argv | | ifs.c:93:9:93:10 | (const char *)... | semmle.label | (const char *)... | @@ -108,6 +140,8 @@ nodes | ifs.c:93:9:93:10 | i4 | semmle.label | i4 | | ifs.c:93:9:93:10 | i4 | semmle.label | i4 | | ifs.c:93:9:93:10 | i4 | semmle.label | i4 | +| ifs.c:93:9:93:10 | i4 indirection | semmle.label | i4 indirection | +| ifs.c:93:9:93:10 | i4 indirection | semmle.label | i4 indirection | | ifs.c:98:8:98:11 | argv | semmle.label | argv | | ifs.c:98:8:98:11 | argv | semmle.label | argv | | ifs.c:99:9:99:10 | (const char *)... | semmle.label | (const char *)... | @@ -115,6 +149,8 @@ nodes | ifs.c:99:9:99:10 | i5 | semmle.label | i5 | | ifs.c:99:9:99:10 | i5 | semmle.label | i5 | | ifs.c:99:9:99:10 | i5 | semmle.label | i5 | +| ifs.c:99:9:99:10 | i5 indirection | semmle.label | i5 indirection | +| ifs.c:99:9:99:10 | i5 indirection | semmle.label | i5 indirection | | ifs.c:105:8:105:11 | argv | semmle.label | argv | | ifs.c:105:8:105:11 | argv | semmle.label | argv | | ifs.c:106:9:106:10 | (const char *)... | semmle.label | (const char *)... | @@ -122,6 +158,8 @@ nodes | ifs.c:106:9:106:10 | i6 | semmle.label | i6 | | ifs.c:106:9:106:10 | i6 | semmle.label | i6 | | ifs.c:106:9:106:10 | i6 | semmle.label | i6 | +| ifs.c:106:9:106:10 | i6 indirection | semmle.label | i6 indirection | +| ifs.c:106:9:106:10 | i6 indirection | semmle.label | i6 indirection | | ifs.c:111:8:111:11 | argv | semmle.label | argv | | ifs.c:111:8:111:11 | argv | semmle.label | argv | | ifs.c:112:9:112:10 | (const char *)... | semmle.label | (const char *)... | @@ -129,6 +167,8 @@ nodes | ifs.c:112:9:112:10 | i7 | semmle.label | i7 | | ifs.c:112:9:112:10 | i7 | semmle.label | i7 | | ifs.c:112:9:112:10 | i7 | semmle.label | i7 | +| ifs.c:112:9:112:10 | i7 indirection | semmle.label | i7 indirection | +| ifs.c:112:9:112:10 | i7 indirection | semmle.label | i7 indirection | | ifs.c:117:8:117:11 | argv | semmle.label | argv | | ifs.c:117:8:117:11 | argv | semmle.label | argv | | ifs.c:118:9:118:10 | (const char *)... | semmle.label | (const char *)... | @@ -136,6 +176,8 @@ nodes | ifs.c:118:9:118:10 | i8 | semmle.label | i8 | | ifs.c:118:9:118:10 | i8 | semmle.label | i8 | | ifs.c:118:9:118:10 | i8 | semmle.label | i8 | +| ifs.c:118:9:118:10 | i8 indirection | semmle.label | i8 indirection | +| ifs.c:118:9:118:10 | i8 indirection | semmle.label | i8 indirection | | ifs.c:123:8:123:11 | argv | semmle.label | argv | | ifs.c:123:8:123:11 | argv | semmle.label | argv | | ifs.c:124:9:124:10 | (const char *)... | semmle.label | (const char *)... | @@ -143,6 +185,8 @@ nodes | ifs.c:124:9:124:10 | i9 | semmle.label | i9 | | ifs.c:124:9:124:10 | i9 | semmle.label | i9 | | ifs.c:124:9:124:10 | i9 | semmle.label | i9 | +| ifs.c:124:9:124:10 | i9 indirection | semmle.label | i9 indirection | +| ifs.c:124:9:124:10 | i9 indirection | semmle.label | i9 indirection | #select | ifs.c:62:9:62:10 | c7 | ifs.c:61:8:61:11 | argv | ifs.c:62:9:62:10 | c7 | The value of this argument may come from $@ and is being used as a formatting argument to printf(format) | ifs.c:61:8:61:11 | argv | argv | | ifs.c:69:9:69:10 | c8 | ifs.c:68:8:68:11 | argv | ifs.c:69:9:69:10 | c8 | The value of this argument may come from $@ and is being used as a formatting argument to printf(format) | ifs.c:68:8:68:11 | argv | argv | diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-190/semmle/TaintedAllocationSize/TaintedAllocationSize.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-190/semmle/TaintedAllocationSize/TaintedAllocationSize.expected index 8b5e24af336..25ff3162973 100644 --- a/cpp/ql/test/query-tests/Security/CWE/CWE-190/semmle/TaintedAllocationSize/TaintedAllocationSize.expected +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-190/semmle/TaintedAllocationSize/TaintedAllocationSize.expected @@ -27,6 +27,24 @@ edges | test.cpp:39:21:39:24 | argv | test.cpp:52:35:52:60 | ... * ... | | test.cpp:39:21:39:24 | argv | test.cpp:52:35:52:60 | ... * ... | | test.cpp:39:21:39:24 | argv | test.cpp:52:35:52:60 | ... * ... | +| test.cpp:75:25:75:29 | start | test.cpp:79:18:79:28 | ... - ... | +| test.cpp:75:25:75:29 | start | test.cpp:79:18:79:28 | ... - ... | +| test.cpp:75:38:75:40 | end | test.cpp:79:18:79:28 | ... - ... | +| test.cpp:75:38:75:40 | end | test.cpp:79:18:79:28 | ... - ... | +| test.cpp:97:18:97:23 | buffer | test.cpp:100:4:100:15 | buffer | +| test.cpp:97:18:97:23 | buffer | test.cpp:100:17:100:22 | buffer indirection | +| test.cpp:97:18:97:23 | buffer | test.cpp:101:4:101:15 | ... + ... | +| test.cpp:97:18:97:23 | buffer | test.cpp:101:4:101:15 | buffer | +| test.cpp:97:18:97:23 | fread output argument | test.cpp:100:4:100:15 | buffer | +| test.cpp:97:18:97:23 | fread output argument | test.cpp:100:17:100:22 | buffer indirection | +| test.cpp:97:18:97:23 | fread output argument | test.cpp:101:4:101:15 | ... + ... | +| test.cpp:97:18:97:23 | fread output argument | test.cpp:101:4:101:15 | buffer | +| test.cpp:100:4:100:15 | buffer | test.cpp:100:17:100:22 | processData1 output argument | +| test.cpp:100:17:100:22 | buffer indirection | test.cpp:100:17:100:22 | processData1 output argument | +| test.cpp:100:17:100:22 | processData1 output argument | test.cpp:101:4:101:15 | ... + ... | +| test.cpp:100:17:100:22 | processData1 output argument | test.cpp:101:4:101:15 | buffer | +| test.cpp:101:4:101:15 | ... + ... | test.cpp:75:38:75:40 | end | +| test.cpp:101:4:101:15 | buffer | test.cpp:75:25:75:29 | start | | test.cpp:123:18:123:23 | call to getenv | test.cpp:127:24:127:41 | ... * ... | | test.cpp:123:18:123:23 | call to getenv | test.cpp:127:24:127:41 | ... * ... | | test.cpp:123:18:123:31 | (const char *)... | test.cpp:127:24:127:41 | ... * ... | @@ -106,6 +124,21 @@ nodes | test.cpp:52:35:52:60 | ... * ... | semmle.label | ... * ... | | test.cpp:52:35:52:60 | ... * ... | semmle.label | ... * ... | | test.cpp:52:35:52:60 | ... * ... | semmle.label | ... * ... | +| test.cpp:64:25:64:30 | *buffer | semmle.label | *buffer | +| test.cpp:64:25:64:30 | *buffer | semmle.label | *buffer | +| test.cpp:64:25:64:30 | buffer | semmle.label | buffer | +| test.cpp:75:25:75:29 | start | semmle.label | start | +| test.cpp:75:38:75:40 | end | semmle.label | end | +| test.cpp:79:18:79:28 | ... - ... | semmle.label | ... - ... | +| test.cpp:79:18:79:28 | ... - ... | semmle.label | ... - ... | +| test.cpp:79:18:79:28 | ... - ... | semmle.label | ... - ... | +| test.cpp:97:18:97:23 | buffer | semmle.label | buffer | +| test.cpp:97:18:97:23 | fread output argument | semmle.label | fread output argument | +| test.cpp:100:4:100:15 | buffer | semmle.label | buffer | +| test.cpp:100:17:100:22 | buffer indirection | semmle.label | buffer indirection | +| test.cpp:100:17:100:22 | processData1 output argument | semmle.label | processData1 output argument | +| test.cpp:101:4:101:15 | ... + ... | semmle.label | ... + ... | +| test.cpp:101:4:101:15 | buffer | semmle.label | buffer | | test.cpp:123:18:123:23 | call to getenv | semmle.label | call to getenv | | test.cpp:123:18:123:31 | (const char *)... | semmle.label | (const char *)... | | test.cpp:127:24:127:41 | ... * ... | semmle.label | ... * ... | @@ -180,6 +213,7 @@ nodes | test.cpp:48:25:48:30 | call to malloc | test.cpp:39:21:39:24 | argv | test.cpp:48:32:48:35 | size | This allocation size is derived from $@ and might overflow | test.cpp:39:21:39:24 | argv | user input (argv) | | test.cpp:49:17:49:30 | new[] | test.cpp:39:21:39:24 | argv | test.cpp:49:26:49:29 | size | This allocation size is derived from $@ and might overflow | test.cpp:39:21:39:24 | argv | user input (argv) | | test.cpp:52:21:52:27 | call to realloc | test.cpp:39:21:39:24 | argv | test.cpp:52:35:52:60 | ... * ... | This allocation size is derived from $@ and might overflow | test.cpp:39:21:39:24 | argv | user input (argv) | +| test.cpp:79:9:79:29 | new[] | test.cpp:97:18:97:23 | buffer | test.cpp:79:18:79:28 | ... - ... | This allocation size is derived from $@ and might overflow | test.cpp:97:18:97:23 | buffer | user input (fread) | | test.cpp:127:17:127:22 | call to malloc | test.cpp:123:18:123:23 | call to getenv | test.cpp:127:24:127:41 | ... * ... | This allocation size is derived from $@ and might overflow | test.cpp:123:18:123:23 | call to getenv | user input (getenv) | | test.cpp:134:3:134:8 | call to malloc | test.cpp:132:19:132:24 | call to getenv | test.cpp:134:10:134:27 | ... * ... | This allocation size is derived from $@ and might overflow | test.cpp:132:19:132:24 | call to getenv | user input (getenv) | | test.cpp:142:4:142:9 | call to malloc | test.cpp:138:19:138:24 | call to getenv | test.cpp:142:11:142:28 | ... * ... | This allocation size is derived from $@ and might overflow | test.cpp:138:19:138:24 | call to getenv | user input (getenv) | diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-190/semmle/TaintedAllocationSize/test.cpp b/cpp/ql/test/query-tests/Security/CWE/CWE-190/semmle/TaintedAllocationSize/test.cpp index 0683f7211e3..943bc3b1214 100644 --- a/cpp/ql/test/query-tests/Security/CWE/CWE-190/semmle/TaintedAllocationSize/test.cpp +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-190/semmle/TaintedAllocationSize/test.cpp @@ -76,7 +76,7 @@ void processData2(char *start, char *end) { char *copy; - copy = new char[end - start]; // GOOD + copy = new char[end - start]; // GOOD [FALSE POSITIVE] // ... diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-190/semmle/extreme/ArithmeticWithExtremeValues.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-190/semmle/extreme/ArithmeticWithExtremeValues.expected index a46371f36b6..77b08e62d83 100644 --- a/cpp/ql/test/query-tests/Security/CWE/CWE-190/semmle/extreme/ArithmeticWithExtremeValues.expected +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-190/semmle/extreme/ArithmeticWithExtremeValues.expected @@ -4,5 +4,4 @@ | test.c:59:3:59:5 | sc6 | $@ flows to here and is used in arithmetic, potentially causing an overflow. | test.c:58:9:58:16 | 127 | Extreme value | | test.c:63:3:63:5 | sc8 | $@ flows to here and is used in arithmetic, potentially causing an underflow. | test.c:62:9:62:16 | - ... | Extreme value | | test.c:75:3:75:5 | sc1 | $@ flows to here and is used in arithmetic, potentially causing an overflow. | test.c:74:9:74:16 | 127 | Extreme value | -| test.c:76:3:76:5 | sc1 | $@ flows to here and is used in arithmetic, potentially causing an overflow. | test.c:74:9:74:16 | 127 | Extreme value | | test.c:124:9:124:9 | x | $@ flows to here and is used in arithmetic, potentially causing an overflow. | test.c:118:17:118:23 | 2147483647 | Extreme value | diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-190/semmle/extreme/test.c b/cpp/ql/test/query-tests/Security/CWE/CWE-190/semmle/extreme/test.c index 8c40d984ee0..ee2e041db3c 100644 --- a/cpp/ql/test/query-tests/Security/CWE/CWE-190/semmle/extreme/test.c +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-190/semmle/extreme/test.c @@ -73,7 +73,7 @@ void test_negatives() { sc1 = CHAR_MAX; sc1 += 0; // GOOD [FALSE POSITIVE] - sc1 += -1; // GOOD [FALSE POSITIVE] + sc1 += -1; // GOOD sc2 = CHAR_MIN; sc2 += -1; // BAD [NOT DETECTED] sc3 = CHAR_MIN; diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-190/semmle/tainted/ArithmeticTainted.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-190/semmle/tainted/ArithmeticTainted.expected index 8bb25025b86..bdf00e0a5df 100644 --- a/cpp/ql/test/query-tests/Security/CWE/CWE-190/semmle/tainted/ArithmeticTainted.expected +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-190/semmle/tainted/ArithmeticTainted.expected @@ -1,8 +1,5 @@ | test2.cpp:14:11:14:11 | v | $@ flows to here and is used in arithmetic, potentially causing an overflow. | test2.cpp:25:22:25:23 | & ... | User-provided value | | test2.cpp:14:11:14:11 | v | $@ flows to here and is used in arithmetic, potentially causing an underflow. | test2.cpp:25:22:25:23 | & ... | User-provided value | -| test3.c:15:10:15:10 | x | $@ flows to here and is used in arithmetic, potentially causing an overflow. | test3.c:11:15:11:18 | argv | User-provided value | -| test3.c:15:14:15:14 | y | $@ flows to here and is used in arithmetic, potentially causing an overflow. | test3.c:11:15:11:18 | argv | User-provided value | -| test3.c:15:18:15:18 | z | $@ flows to here and is used in arithmetic, potentially causing an overflow. | test3.c:11:15:11:18 | argv | User-provided value | | test5.cpp:17:6:17:18 | call to getTaintedInt | $@ flows to here and is used in arithmetic, potentially causing an overflow. | test5.cpp:9:7:9:9 | buf | User-provided value | | test5.cpp:19:6:19:6 | y | $@ flows to here and is used in arithmetic, potentially causing an overflow. | test5.cpp:9:7:9:9 | buf | User-provided value | | test5.cpp:19:6:19:6 | y | $@ flows to here and is used in arithmetic, potentially causing an underflow. | test5.cpp:9:7:9:9 | buf | User-provided value | diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-190/semmle/uncontrolled/test.cpp b/cpp/ql/test/query-tests/Security/CWE/CWE-190/semmle/uncontrolled/test.cpp index 5d4d7e8c5c3..d3dc3352a29 100644 --- a/cpp/ql/test/query-tests/Security/CWE/CWE-190/semmle/uncontrolled/test.cpp +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-190/semmle/uncontrolled/test.cpp @@ -28,7 +28,7 @@ void randomTester2() { int r; get_rand2(&r); - r = r + 100; // BAD [NOT DETECTED] + r = r + 100; // BAD } { diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-290/semmle/AuthenticationBypass/AuthenticationBypass.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-290/semmle/AuthenticationBypass/AuthenticationBypass.expected index e2671c07952..1ad31c3f9f7 100644 --- a/cpp/ql/test/query-tests/Security/CWE/CWE-290/semmle/AuthenticationBypass/AuthenticationBypass.expected +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-290/semmle/AuthenticationBypass/AuthenticationBypass.expected @@ -1,32 +1,44 @@ edges | test.cpp:16:25:16:30 | call to getenv | test.cpp:20:14:20:20 | address | | test.cpp:16:25:16:30 | call to getenv | test.cpp:20:14:20:20 | address | +| test.cpp:16:25:16:30 | call to getenv | test.cpp:20:14:20:20 | address indirection | | test.cpp:16:25:16:42 | (const char *)... | test.cpp:20:14:20:20 | address | | test.cpp:16:25:16:42 | (const char *)... | test.cpp:20:14:20:20 | address | +| test.cpp:16:25:16:42 | (const char *)... | test.cpp:20:14:20:20 | address indirection | | test.cpp:27:25:27:30 | call to getenv | test.cpp:31:14:31:20 | address | | test.cpp:27:25:27:30 | call to getenv | test.cpp:31:14:31:20 | address | +| test.cpp:27:25:27:30 | call to getenv | test.cpp:31:14:31:20 | address indirection | | test.cpp:27:25:27:42 | (const char *)... | test.cpp:31:14:31:20 | address | | test.cpp:27:25:27:42 | (const char *)... | test.cpp:31:14:31:20 | address | +| test.cpp:27:25:27:42 | (const char *)... | test.cpp:31:14:31:20 | address indirection | | test.cpp:38:25:38:30 | call to getenv | test.cpp:42:14:42:20 | address | | test.cpp:38:25:38:30 | call to getenv | test.cpp:42:14:42:20 | address | +| test.cpp:38:25:38:30 | call to getenv | test.cpp:42:14:42:20 | address indirection | | test.cpp:38:25:38:42 | (const char *)... | test.cpp:42:14:42:20 | address | | test.cpp:38:25:38:42 | (const char *)... | test.cpp:42:14:42:20 | address | +| test.cpp:38:25:38:42 | (const char *)... | test.cpp:42:14:42:20 | address indirection | nodes | test.cpp:16:25:16:30 | call to getenv | semmle.label | call to getenv | | test.cpp:16:25:16:42 | (const char *)... | semmle.label | (const char *)... | | test.cpp:20:14:20:20 | address | semmle.label | address | | test.cpp:20:14:20:20 | address | semmle.label | address | | test.cpp:20:14:20:20 | address | semmle.label | address | +| test.cpp:20:14:20:20 | address indirection | semmle.label | address indirection | +| test.cpp:20:14:20:20 | address indirection | semmle.label | address indirection | | test.cpp:27:25:27:30 | call to getenv | semmle.label | call to getenv | | test.cpp:27:25:27:42 | (const char *)... | semmle.label | (const char *)... | | test.cpp:31:14:31:20 | address | semmle.label | address | | test.cpp:31:14:31:20 | address | semmle.label | address | | test.cpp:31:14:31:20 | address | semmle.label | address | +| test.cpp:31:14:31:20 | address indirection | semmle.label | address indirection | +| test.cpp:31:14:31:20 | address indirection | semmle.label | address indirection | | test.cpp:38:25:38:30 | call to getenv | semmle.label | call to getenv | | test.cpp:38:25:38:42 | (const char *)... | semmle.label | (const char *)... | | test.cpp:42:14:42:20 | address | semmle.label | address | | test.cpp:42:14:42:20 | address | semmle.label | address | | test.cpp:42:14:42:20 | address | semmle.label | address | +| test.cpp:42:14:42:20 | address indirection | semmle.label | address indirection | +| test.cpp:42:14:42:20 | address indirection | semmle.label | address indirection | #select | test.cpp:20:7:20:12 | call to strcmp | test.cpp:16:25:16:30 | call to getenv | test.cpp:20:14:20:20 | address | Untrusted input $@ might be vulnerable to a spoofing attack. | test.cpp:16:25:16:30 | call to getenv | call to getenv | | test.cpp:31:7:31:12 | call to strcmp | test.cpp:27:25:27:30 | call to getenv | test.cpp:31:14:31:20 | address | Untrusted input $@ might be vulnerable to a spoofing attack. | test.cpp:27:25:27:30 | call to getenv | call to getenv | diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-311/semmle/tests/CleartextBufferWrite.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-311/semmle/tests/CleartextBufferWrite.expected index f78d75eeed1..e4f9bc918a4 100644 --- a/cpp/ql/test/query-tests/Security/CWE/CWE-311/semmle/tests/CleartextBufferWrite.expected +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-311/semmle/tests/CleartextBufferWrite.expected @@ -3,11 +3,15 @@ edges | test.cpp:54:17:54:20 | argv | test.cpp:58:25:58:29 | input | | test.cpp:54:17:54:20 | argv | test.cpp:58:25:58:29 | input | | test.cpp:54:17:54:20 | argv | test.cpp:58:25:58:29 | input | +| test.cpp:54:17:54:20 | argv | test.cpp:58:25:58:29 | input indirection | +| test.cpp:54:17:54:20 | argv | test.cpp:58:25:58:29 | input indirection | nodes | test.cpp:54:17:54:20 | argv | semmle.label | argv | | test.cpp:54:17:54:20 | argv | semmle.label | argv | | test.cpp:58:25:58:29 | input | semmle.label | input | | test.cpp:58:25:58:29 | input | semmle.label | input | | test.cpp:58:25:58:29 | input | semmle.label | input | +| test.cpp:58:25:58:29 | input indirection | semmle.label | input indirection | +| test.cpp:58:25:58:29 | input indirection | semmle.label | input indirection | #select | test.cpp:58:3:58:9 | call to sprintf | test.cpp:54:17:54:20 | argv | test.cpp:58:25:58:29 | input | This write into buffer 'passwd' may contain unencrypted data from $@ | test.cpp:54:17:54:20 | argv | user input (argv) | diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-764/semmle/tests/UnreleasedLock.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-764/semmle/tests/UnreleasedLock.expected index 0d06ce59719..de14b91f8eb 100644 --- a/cpp/ql/test/query-tests/Security/CWE/CWE-764/semmle/tests/UnreleasedLock.expected +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-764/semmle/tests/UnreleasedLock.expected @@ -7,3 +7,4 @@ | test.cpp:303:11:303:18 | call to try_lock | This lock might not be unlocked or might be locked more times than it is unlocked. | | test.cpp:313:11:313:18 | call to try_lock | This lock might not be unlocked or might be locked more times than it is unlocked. | | test.cpp:442:8:442:17 | call to mutex_lock | This lock might not be unlocked or might be locked more times than it is unlocked. | +| test.cpp:482:2:482:19 | call to pthread_mutex_lock | This lock might not be unlocked or might be locked more times than it is unlocked. | diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-764/semmle/tests/test.cpp b/cpp/ql/test/query-tests/Security/CWE/CWE-764/semmle/tests/test.cpp index c08ac2f63c3..9114e545fd5 100644 --- a/cpp/ql/test/query-tests/Security/CWE/CWE-764/semmle/tests/test.cpp +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-764/semmle/tests/test.cpp @@ -445,3 +445,46 @@ bool test_mutex(data_t *data) return true; } + +// --- + +struct pthread_mutex +{ + // ... +}; + +void pthread_mutex_lock(pthread_mutex *m); +void pthread_mutex_unlock(pthread_mutex *m); + +class MyClass +{ +public: + pthread_mutex lock; +}; + +bool maybe(); + +int test_MyClass_good(MyClass *obj) +{ + pthread_mutex_lock(&obj->lock); + + if (maybe()) { + pthread_mutex_unlock(&obj->lock); + return -1; // GOOD + } + + pthread_mutex_unlock(&obj->lock); // GOOD + return 0; +} + +int test_MyClass_bad(MyClass *obj) +{ + pthread_mutex_lock(&obj->lock); + + if (maybe()) { + return -1; // BAD + } + + pthread_mutex_unlock(&obj->lock); // GOOD + return 0; +} diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-807/semmle/TaintedCondition/TaintedCondition.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-807/semmle/TaintedCondition/TaintedCondition.expected index cc5004047cf..e04a20830d0 100644 --- a/cpp/ql/test/query-tests/Security/CWE/CWE-807/semmle/TaintedCondition/TaintedCondition.expected +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-807/semmle/TaintedCondition/TaintedCondition.expected @@ -1,37 +1,21 @@ edges | test.cpp:20:29:20:34 | call to getenv | test.cpp:24:10:24:35 | ! ... | | test.cpp:20:29:20:34 | call to getenv | test.cpp:24:11:24:16 | call to strcmp | -| test.cpp:20:29:20:34 | call to getenv | test.cpp:24:11:24:16 | call to strcmp | -| test.cpp:20:29:20:34 | call to getenv | test.cpp:24:11:24:35 | (bool)... | | test.cpp:20:29:20:34 | call to getenv | test.cpp:41:10:41:38 | ! ... | | test.cpp:20:29:20:34 | call to getenv | test.cpp:41:11:41:16 | call to strcmp | -| test.cpp:20:29:20:34 | call to getenv | test.cpp:41:11:41:16 | call to strcmp | -| test.cpp:20:29:20:34 | call to getenv | test.cpp:41:11:41:38 | (bool)... | | test.cpp:20:29:20:47 | (const char *)... | test.cpp:24:10:24:35 | ! ... | | test.cpp:20:29:20:47 | (const char *)... | test.cpp:24:11:24:16 | call to strcmp | -| test.cpp:20:29:20:47 | (const char *)... | test.cpp:24:11:24:16 | call to strcmp | -| test.cpp:20:29:20:47 | (const char *)... | test.cpp:24:11:24:35 | (bool)... | | test.cpp:20:29:20:47 | (const char *)... | test.cpp:41:10:41:38 | ! ... | | test.cpp:20:29:20:47 | (const char *)... | test.cpp:41:11:41:16 | call to strcmp | -| test.cpp:20:29:20:47 | (const char *)... | test.cpp:41:11:41:16 | call to strcmp | -| test.cpp:20:29:20:47 | (const char *)... | test.cpp:41:11:41:38 | (bool)... | -| test.cpp:24:11:24:16 | call to strcmp | test.cpp:24:10:24:35 | ! ... | -| test.cpp:24:11:24:16 | call to strcmp | test.cpp:24:11:24:35 | (bool)... | -| test.cpp:41:11:41:16 | call to strcmp | test.cpp:41:10:41:38 | ! ... | -| test.cpp:41:11:41:16 | call to strcmp | test.cpp:41:11:41:38 | (bool)... | nodes | test.cpp:20:29:20:34 | call to getenv | semmle.label | call to getenv | | test.cpp:20:29:20:47 | (const char *)... | semmle.label | (const char *)... | | test.cpp:24:10:24:35 | ! ... | semmle.label | ! ... | | test.cpp:24:11:24:16 | call to strcmp | semmle.label | call to strcmp | | test.cpp:24:11:24:16 | call to strcmp | semmle.label | call to strcmp | -| test.cpp:24:11:24:35 | (bool)... | semmle.label | (bool)... | -| test.cpp:24:11:24:35 | (bool)... | semmle.label | (bool)... | | test.cpp:41:10:41:38 | ! ... | semmle.label | ! ... | | test.cpp:41:11:41:16 | call to strcmp | semmle.label | call to strcmp | | test.cpp:41:11:41:16 | call to strcmp | semmle.label | call to strcmp | -| test.cpp:41:11:41:38 | (bool)... | semmle.label | (bool)... | -| test.cpp:41:11:41:38 | (bool)... | semmle.label | (bool)... | #select | test.cpp:24:10:24:35 | ! ... | test.cpp:20:29:20:34 | call to getenv | test.cpp:24:10:24:35 | ! ... | Reliance on untrusted input $@ to raise privilege at $@ | test.cpp:20:29:20:34 | call to getenv | call to getenv | test.cpp:25:9:25:27 | ... = ... | ... = ... | | test.cpp:41:10:41:38 | ! ... | test.cpp:20:29:20:34 | call to getenv | test.cpp:41:10:41:38 | ! ... | Reliance on untrusted input $@ to raise privilege at $@ | test.cpp:20:29:20:34 | call to getenv | call to getenv | test.cpp:42:8:42:26 | ... = ... | ... = ... | diff --git a/cpp/ql/test/query-tests/Summary/LinesOfCode.expected b/cpp/ql/test/query-tests/Summary/LinesOfCode.expected new file mode 100644 index 00000000000..a75c288c151 --- /dev/null +++ b/cpp/ql/test/query-tests/Summary/LinesOfCode.expected @@ -0,0 +1 @@ +| 93 | diff --git a/cpp/ql/test/query-tests/Summary/LinesOfCode.qlref b/cpp/ql/test/query-tests/Summary/LinesOfCode.qlref new file mode 100644 index 00000000000..b60eb791722 --- /dev/null +++ b/cpp/ql/test/query-tests/Summary/LinesOfCode.qlref @@ -0,0 +1 @@ +Summary/LinesOfCode.ql diff --git a/cpp/ql/test/query-tests/Summary/empty-file.cpp b/cpp/ql/test/query-tests/Summary/empty-file.cpp new file mode 100644 index 00000000000..8b137891791 --- /dev/null +++ b/cpp/ql/test/query-tests/Summary/empty-file.cpp @@ -0,0 +1 @@ + diff --git a/cpp/ql/test/query-tests/Summary/large-file.cpp b/cpp/ql/test/query-tests/Summary/large-file.cpp new file mode 100644 index 00000000000..b4af2da0cde --- /dev/null +++ b/cpp/ql/test/query-tests/Summary/large-file.cpp @@ -0,0 +1,123 @@ +int a00(float x) { + return (int)x; +} + +int a01(float x) { + return (int)x; +} + +int a02(float x) { + return (int)x; +} + +int a03(float x) { + return (int)x; +} + +int a04(float x) { + return (int)x; +} + +int a05(float x) { + return (int)x; +} + +int a06(float x) { + return (int)x; +} + +/** + * This is a multi-line comment + */ +int a07(float x) { + return (int)x; +} + +// this is a single-line comment +int a08(float x) { + return (int)x; +} + +int a09(float x) { + return (int)x; +} + +int a10(float x) { + return (int)x; +} + +int a11(float x) { + return (int)x; +} + +int a12(float x) { + return (int)x; +} + +int a13(float x) { + return (int)x; +} + +int a14(float x) { + return (int)x; +} + +int a15(float x) { + return (int)x; +} + +int a16(float x) { + return (int)x; +} + +int a17(float x) { + return (int)x; +} + +int a18(float x) { + return (int)x; +} + +int a19(float x) { + return (int)x; +} + +int a20(float x) { + return (int)x; +} + +int a21(float x) { + return (int)x; +} + +int a22(float x) { + return (int)x; +} + +int a23(float x) { + return (int)x; +} + +int a24(float x) { + return (int)x; +} + +int a25(float x) { + return (int)x; +} + +int a26(float x) { + return (int)x; +} + +int a27(float x) { + return (int)x; +} + +int a28(float x) { + return (int)x; +} + +int a29(float x) { + return (int)x; +} diff --git a/cpp/ql/test/query-tests/Summary/short-file.cpp b/cpp/ql/test/query-tests/Summary/short-file.cpp new file mode 100644 index 00000000000..e4055360d37 --- /dev/null +++ b/cpp/ql/test/query-tests/Summary/short-file.cpp @@ -0,0 +1,3 @@ +int g(float x) { + return (int)x; +} diff --git a/cpp/ql/test/query-tests/jsf/4.10 Classes/AV Rule 79/AV Rule 79.expected b/cpp/ql/test/query-tests/jsf/4.10 Classes/AV Rule 79/AV Rule 79.expected index 1d0ef245f3b..70ee3fb4704 100644 --- a/cpp/ql/test/query-tests/jsf/4.10 Classes/AV Rule 79/AV Rule 79.expected +++ b/cpp/ql/test/query-tests/jsf/4.10 Classes/AV Rule 79/AV Rule 79.expected @@ -18,9 +18,10 @@ | NoDestructor.cpp:23:3:23:20 | ... = ... | Resource n is acquired by class MyClass5 but not released anywhere in this class. | | PlacementNew.cpp:36:3:36:36 | ... = ... | Resource p1 is acquired by class MyTestForPlacementNew but not released anywhere in this class. | | SelfRegistering.cpp:25:3:25:24 | ... = ... | Resource side is acquired by class MyOwner but not released anywhere in this class. | -| Variants.cpp:25:3:25:13 | ... = ... | Resource f is acquired by class MyClass4 but not released anywhere in this class. | -| Variants.cpp:65:3:65:17 | ... = ... | Resource a is acquired by class MyClass6 but not released anywhere in this class. | -| Variants.cpp:66:3:66:36 | ... = ... | Resource b is acquired by class MyClass6 but not released anywhere in this class. | -| Variants.cpp:67:3:67:41 | ... = ... | Resource c is acquired by class MyClass6 but not released anywhere in this class. | +| Variants.cpp:26:3:26:13 | ... = ... | Resource f is acquired by class MyClass4 but not released anywhere in this class. | +| Variants.cpp:69:3:69:17 | ... = ... | Resource a is acquired by class MyClass6 but not released anywhere in this class. | +| Variants.cpp:70:3:70:36 | ... = ... | Resource b is acquired by class MyClass6 but not released anywhere in this class. | +| Variants.cpp:71:3:71:41 | ... = ... | Resource c is acquired by class MyClass6 but not released anywhere in this class. | +| Variants.cpp:72:3:72:22 | ... = ... | Resource d is acquired by class MyClass6 but not released anywhere in this class. | | Wrapped.cpp:46:3:46:22 | ... = ... | Resource ptr2 is acquired by class Wrapped2 but not released anywhere in this class. | | Wrapped.cpp:59:3:59:22 | ... = ... | Resource ptr4 is acquired by class Wrapped2 but not released anywhere in this class. | diff --git a/cpp/ql/test/query-tests/jsf/4.10 Classes/AV Rule 79/Variants.cpp b/cpp/ql/test/query-tests/jsf/4.10 Classes/AV Rule 79/Variants.cpp index e96a5cd4f0d..7727a038248 100644 --- a/cpp/ql/test/query-tests/jsf/4.10 Classes/AV Rule 79/Variants.cpp +++ b/cpp/ql/test/query-tests/jsf/4.10 Classes/AV Rule 79/Variants.cpp @@ -5,6 +5,7 @@ void *malloc(size_t size); void *calloc(size_t nmemb, size_t size); void *realloc(void *ptr, size_t size); void free(void* ptr); +char *strdup(const char *s1); int *ID(int *x) { @@ -45,6 +46,7 @@ public: a = new int[10]; // GOOD b = (int *)calloc(10, sizeof(int)); // GOOD c = (int *)realloc(0, 10 * sizeof(int)); // GOOD + d = strdup("string"); } ~MyClass5() @@ -52,9 +54,11 @@ public: delete [] a; free(b); free(c); + free(d); } int *a, *b, *c; + char *d; }; class MyClass6 @@ -65,6 +69,7 @@ public: a = new int[10]; // BAD b = (int *)calloc(10, sizeof(int)); // BAD c = (int *)realloc(0, 10 * sizeof(int)); // BAD + d = strdup("string"); // BAD } ~MyClass6() @@ -72,6 +77,7 @@ public: } int *a, *b, *c; + char *d; }; class MyClass7 diff --git a/csharp/autobuilder/Semmle.Autobuild.CSharp.Tests/BuildScripts.cs b/csharp/autobuilder/Semmle.Autobuild.CSharp.Tests/BuildScripts.cs index 7b9f2e78881..99ad4c8f963 100644 --- a/csharp/autobuilder/Semmle.Autobuild.CSharp.Tests/BuildScripts.cs +++ b/csharp/autobuilder/Semmle.Autobuild.CSharp.Tests/BuildScripts.cs @@ -976,13 +976,11 @@ Microsoft.NETCore.App 2.1.4 [/usr/local/share/dotnet/shared/Microsoft.NETCore.Ap TestAutobuilderScript(autobuilder, 0, 9); } - [Fact] - public void TestDotnetVersionWindows() + private void TestDotnetVersionWindows(Action action, int commandsRun) { actions.RunProcess["cmd.exe /C dotnet --list-sdks"] = 0; actions.RunProcessOut["cmd.exe /C dotnet --list-sdks"] = "2.1.3 [C:\\Program Files\\dotnet\\sdks]\n2.1.4 [C:\\Program Files\\dotnet\\sdks]"; - actions.RunProcess[@"cmd.exe /C powershell -NoProfile -ExecutionPolicy unrestricted -file C:\Project\install-dotnet.ps1 -Version 2.1.3 -InstallDir C:\Project\.dotnet"] = 0; - actions.RunProcess[@"cmd.exe /C del C:\Project\install-dotnet.ps1"] = 0; + action(); actions.RunProcess[@"cmd.exe /C C:\Project\.dotnet\dotnet --info"] = 0; actions.RunProcess[@"cmd.exe /C C:\Project\.dotnet\dotnet clean C:\Project\test.csproj"] = 0; actions.RunProcess[@"cmd.exe /C C:\Project\.dotnet\dotnet restore C:\Project\test.csproj"] = 0; @@ -1005,7 +1003,28 @@ Microsoft.NETCore.App 2.1.4 [/usr/local/share/dotnet/shared/Microsoft.NETCore.Ap actions.LoadXml[@"C:\Project\test.csproj"] = xml; var autobuilder = CreateAutoBuilder(true, dotnetVersion: "2.1.3"); - TestAutobuilderScript(autobuilder, 0, 7); + TestAutobuilderScript(autobuilder, 0, commandsRun); + } + + [Fact] + public void TestDotnetVersionWindowsWithPwsh() + { + TestDotnetVersionWindows(() => + { + actions.RunProcess[@"cmd.exe /C pwsh -NoProfile -ExecutionPolicy unrestricted -Command ""[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; &([scriptblock]::Create((Invoke-WebRequest -UseBasicParsing 'https://dot.net/v1/dotnet-install.ps1'))) -Version 2.1.3 -InstallDir C:\Project\.dotnet"""] = 0; + }, + 6); + } + + [Fact] + public void TestDotnetVersionWindowsWithoutPwsh() + { + TestDotnetVersionWindows(() => + { + actions.RunProcess[@"cmd.exe /C pwsh -NoProfile -ExecutionPolicy unrestricted -Command ""[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; &([scriptblock]::Create((Invoke-WebRequest -UseBasicParsing 'https://dot.net/v1/dotnet-install.ps1'))) -Version 2.1.3 -InstallDir C:\Project\.dotnet"""] = 1; + actions.RunProcess[@"cmd.exe /C powershell -NoProfile -ExecutionPolicy unrestricted -Command ""[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; &([scriptblock]::Create((Invoke-WebRequest -UseBasicParsing 'https://dot.net/v1/dotnet-install.ps1'))) -Version 2.1.3 -InstallDir C:\Project\.dotnet"""] = 0; + }, + 7); } [Fact] diff --git a/csharp/autobuilder/Semmle.Autobuild.CSharp.Tests/Semmle.Autobuild.CSharp.Tests.csproj b/csharp/autobuilder/Semmle.Autobuild.CSharp.Tests/Semmle.Autobuild.CSharp.Tests.csproj index 64e25a8eb64..cc79699848a 100644 --- a/csharp/autobuilder/Semmle.Autobuild.CSharp.Tests/Semmle.Autobuild.CSharp.Tests.csproj +++ b/csharp/autobuilder/Semmle.Autobuild.CSharp.Tests/Semmle.Autobuild.CSharp.Tests.csproj @@ -1,7 +1,6 @@ - Exe net5.0 false win-x64;linux-x64;osx-x64 @@ -12,10 +11,11 @@ - + all runtime; build; native; contentfiles; analyzers +
    diff --git a/csharp/autobuilder/Semmle.Autobuild.CSharp/DotNetRule.cs b/csharp/autobuilder/Semmle.Autobuild.CSharp/DotNetRule.cs index 93f0a630d1e..a456c9407db 100644 --- a/csharp/autobuilder/Semmle.Autobuild.CSharp/DotNetRule.cs +++ b/csharp/autobuilder/Semmle.Autobuild.CSharp/DotNetRule.cs @@ -145,7 +145,7 @@ namespace Semmle.Autobuild.CSharp try { var o = JObject.Parse(File.ReadAllText(path)); - version = (string)o["sdk"]["version"]; + version = (string)(o?["sdk"]?["version"]!); } catch // lgtm[cs/catch-of-all-exceptions] { @@ -179,53 +179,20 @@ namespace Semmle.Autobuild.CSharp if (builder.Actions.IsWindows()) { - var psScript = @"param([string]$Version, [string]$InstallDir) -add-type @"" -using System.Net; -using System.Security.Cryptography.X509Certificates; -public class TrustAllCertsPolicy : ICertificatePolicy -{ - public bool CheckValidationResult(ServicePoint srvPoint, X509Certificate certificate, WebRequest request, int certificateProblem) - { - return true; - } -} -""@ -$AllProtocols = [System.Net.SecurityProtocolType]'Ssl3,Tls,Tls11,Tls12' -[System.Net.ServicePointManager]::SecurityProtocol = $AllProtocols -[System.Net.ServicePointManager]::CertificatePolicy = New-Object TrustAllCertsPolicy -$Script = Invoke-WebRequest -useb 'https://dot.net/v1/dotnet-install.ps1' + var psCommand = $"[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; &([scriptblock]::Create((Invoke-WebRequest -UseBasicParsing 'https://dot.net/v1/dotnet-install.ps1'))) -Version {version} -InstallDir {path}"; -$arguments = @{ - Channel = 'release' - Version = $Version - InstallDir = $InstallDir -} - -$ScriptBlock = [scriptblock]::create("".{$($Script)} $(&{$args} @arguments)"") - -Invoke-Command -ScriptBlock $ScriptBlock"; - var psScriptFile = builder.Actions.PathCombine(builder.Options.RootDirectory, "install-dotnet.ps1"); - builder.Actions.WriteAllText(psScriptFile, psScript); - - var install = new CommandBuilder(builder.Actions). - RunCommand("powershell"). + BuildScript GetInstall(string pwsh) => + new CommandBuilder(builder.Actions). + RunCommand(pwsh). Argument("-NoProfile"). Argument("-ExecutionPolicy"). Argument("unrestricted"). - Argument("-file"). - Argument(psScriptFile). - Argument("-Version"). - Argument(version). - Argument("-InstallDir"). - Argument(path); + Argument("-Command"). + Argument("\"" + psCommand + "\""). + Script; - var removeScript = new CommandBuilder(builder.Actions). - RunCommand("del"). - Argument(psScriptFile); - - return install.Script & BuildScript.Try(removeScript.Script); + return GetInstall("pwsh") | GetInstall("powershell"); } else { diff --git a/csharp/autobuilder/Semmle.Autobuild.CSharp/Semmle.Autobuild.CSharp.csproj b/csharp/autobuilder/Semmle.Autobuild.CSharp/Semmle.Autobuild.CSharp.csproj index b02b1a3fef1..b24f243de01 100644 --- a/csharp/autobuilder/Semmle.Autobuild.CSharp/Semmle.Autobuild.CSharp.csproj +++ b/csharp/autobuilder/Semmle.Autobuild.CSharp/Semmle.Autobuild.CSharp.csproj @@ -17,8 +17,8 @@ - - + + diff --git a/csharp/autobuilder/Semmle.Autobuild.Shared/Semmle.Autobuild.Shared.csproj b/csharp/autobuilder/Semmle.Autobuild.Shared/Semmle.Autobuild.Shared.csproj index 5f59b205527..ae1c61bc992 100644 --- a/csharp/autobuilder/Semmle.Autobuild.Shared/Semmle.Autobuild.Shared.csproj +++ b/csharp/autobuilder/Semmle.Autobuild.Shared/Semmle.Autobuild.Shared.csproj @@ -14,7 +14,7 @@ - + diff --git a/csharp/change-notes/2021-03-24-cil-ssa.md b/csharp/change-notes/2021-03-24-cil-ssa.md new file mode 100644 index 00000000000..2c971fe39f5 --- /dev/null +++ b/csharp/change-notes/2021-03-24-cil-ssa.md @@ -0,0 +1,2 @@ +lgtm,codescanning +* A static single assignment (SSA) library has been added to the CIL analysis library. The SSA library replaces the existing `DefUse` module, which has been deprecated. diff --git a/csharp/change-notes/2021-03-24-remove-legacy-queries.md b/csharp/change-notes/2021-03-24-remove-legacy-queries.md new file mode 100644 index 00000000000..1cbcbb6a1a0 --- /dev/null +++ b/csharp/change-notes/2021-03-24-remove-legacy-queries.md @@ -0,0 +1,2 @@ +lgtm,codescanning +* Legacy queries in the folders `external` and `filters` have all been removed. \ No newline at end of file diff --git a/csharp/change-notes/2021-03-24-remove-vuln-package-query.md b/csharp/change-notes/2021-03-24-remove-vuln-package-query.md new file mode 100644 index 00000000000..2a211823b39 --- /dev/null +++ b/csharp/change-notes/2021-03-24-remove-vuln-package-query.md @@ -0,0 +1,2 @@ +lgtm,codescanning +* The query `VulnerablePackage.ql` has been removed. \ No newline at end of file diff --git a/csharp/change-notes/2021-04-09-dapper-support.md b/csharp/change-notes/2021-04-09-dapper-support.md new file mode 100644 index 00000000000..a7db9d045d2 --- /dev/null +++ b/csharp/change-notes/2021-04-09-dapper-support.md @@ -0,0 +1,2 @@ +lgtm,codescanning +* Support for the Dapper ORM library has been added to the SQL injection checks. \ No newline at end of file diff --git a/csharp/change-notes/2021-04-09-default-argument-values.md b/csharp/change-notes/2021-04-09-default-argument-values.md new file mode 100644 index 00000000000..ef34dca4f6a --- /dev/null +++ b/csharp/change-notes/2021-04-09-default-argument-values.md @@ -0,0 +1,2 @@ +lgtm,codescanning +* The extractor has been improved to store default argument values for parameters that are extracted from referenced assemblies. \ No newline at end of file diff --git a/csharp/change-notes/2021-04-14-customizations.md b/csharp/change-notes/2021-04-14-customizations.md new file mode 100644 index 00000000000..a2f957ca923 --- /dev/null +++ b/csharp/change-notes/2021-04-14-customizations.md @@ -0,0 +1,2 @@ +lgtm,codescanning +* A new library, `Customizations.qll`, has been added, which allows for global customizations that affect all queries. \ No newline at end of file diff --git a/csharp/config/suites/lgtm/csharp-metrics-lgtm b/csharp/config/suites/lgtm/csharp-metrics-lgtm index 00c35820362..7a9cd6efb31 100644 --- a/csharp/config/suites/lgtm/csharp-metrics-lgtm +++ b/csharp/config/suites/lgtm/csharp-metrics-lgtm @@ -4,8 +4,6 @@ @_namespace com.lgtm/csharp-queries + odasa-csharp-metrics/Files/FLinesOfCommentedCode.ql: /Metrics/Documentation @_namespace com.lgtm/csharp-queries -+ odasa-csharp-metrics/Files/FLinesOfDuplicatedCode.ql: /Metrics/Coupling - @_namespace com.lgtm/csharp-queries + odasa-csharp-metrics/Files/FNumberOfTests.ql: /Metrics/Size @_namespace com.lgtm/csharp-queries diff --git a/csharp/extractor/Semmle.Extraction.CSharp.Standalone/Semmle.Extraction.CSharp.Standalone.csproj b/csharp/extractor/Semmle.Extraction.CSharp.Standalone/Semmle.Extraction.CSharp.Standalone.csproj index adf51941ad7..aed85473e7c 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp.Standalone/Semmle.Extraction.CSharp.Standalone.csproj +++ b/csharp/extractor/Semmle.Extraction.CSharp.Standalone/Semmle.Extraction.CSharp.Standalone.csproj @@ -23,7 +23,7 @@ - + diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/CachedSymbol.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/CachedSymbol.cs index f7f18ff4c25..d6fb0d65e5d 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/Entities/CachedSymbol.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/CachedSymbol.cs @@ -151,13 +151,10 @@ namespace Semmle.Extraction.CSharp.Entities if (handleProp is null) { var underlyingSymbolProp = GetPropertyInfo(Symbol, "UnderlyingSymbol"); - if (underlyingSymbolProp is not null) + if (underlyingSymbolProp?.GetValue(Symbol) is object underlying) { - if (underlyingSymbolProp.GetValue(Symbol) is object underlying) - { - handleProp = GetPropertyInfo(underlying, "Handle"); - handleObj = underlying; - } + handleProp = GetPropertyInfo(underlying, "Handle"); + handleObj = underlying; } } diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expression.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expression.cs index cdf17311440..6d36dded801 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expression.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expression.cs @@ -164,6 +164,39 @@ namespace Semmle.Extraction.CSharp.Entities } } + /// + /// Creates a generated expression for a default argument value. + /// + public static Expression? CreateGenerated(Context cx, IParameterSymbol parameter, IExpressionParentEntity parent, + int childIndex, Extraction.Entities.Location location) + { + if (!parameter.HasExplicitDefaultValue) + { + return null; + } + + var defaultValue = parameter.ExplicitDefaultValue; + + if (parameter.Type is INamedTypeSymbol nt && nt.EnumUnderlyingType is not null) + { + // = (MyEnum)1, = MyEnum.Value1, = default(MyEnum), = new MyEnum() + // we're generating a (MyEnum)value cast expression: + defaultValue ??= 0; + Action createChild = (parent, index) => Literal.CreateGenerated(cx, parent, index, nt.EnumUnderlyingType, defaultValue, location); + return Cast.CreateGenerated(cx, parent, childIndex, parameter.Type, defaultValue, createChild, location); + } + + if (defaultValue is null) + { + // = null, = default, = default(T), = new MyStruct() + // we're generating a default expression: + return Default.CreateGenerated(cx, parent, childIndex, location, parameter.Type.IsReferenceType ? ValueAsString(null) : null); + } + + // const literal: + return Literal.CreateGenerated(cx, parent, childIndex, parameter.Type, defaultValue, location); + } + /// /// Adapt the operator kind depending on whether it's a dynamic call or a user-operator call. /// diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/Default.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/Default.cs index 9e1b42834b1..9fdfd18d3bd 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/Default.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/Default.cs @@ -14,5 +14,20 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions { TypeAccess.Create(Context, Syntax.Type, this, 0); } + + public static Expression CreateGenerated(Context cx, IExpressionParentEntity parent, int childIndex, Extraction.Entities.Location location, string? value) + { + var info = new ExpressionInfo( + cx, + null, + location, + ExprKind.DEFAULT, + parent, + childIndex, + true, + value); + + return new Expression(info); + } } } diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/ImplicitCast.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/ImplicitCast.cs index a6995adc30f..2d617cdb1b9 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/ImplicitCast.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/ImplicitCast.cs @@ -3,7 +3,7 @@ using Semmle.Extraction.Kinds; namespace Semmle.Extraction.CSharp.Entities.Expressions { - internal class ImplicitCast : Expression + internal sealed class ImplicitCast : Expression { public Expression Expr { diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/MemberAccess.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/MemberAccess.cs index 0de154509c8..426145e2d27 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/MemberAccess.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/MemberAccess.cs @@ -4,7 +4,7 @@ using Semmle.Extraction.Kinds; namespace Semmle.Extraction.CSharp.Entities.Expressions { - internal class MemberAccess : Expression + internal sealed class MemberAccess : Expression { private MemberAccess(ExpressionNodeInfo info, ExpressionSyntax qualifier, ISymbol? target) : base(info) { diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Parameter.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Parameter.cs index 3bbf38a71eb..462c8bbb297 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Parameter.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Parameter.cs @@ -4,6 +4,7 @@ using System.Linq; using Microsoft.CodeAnalysis.CSharp.Syntax; using Semmle.Extraction.Entities; using System.IO; +using System; namespace Semmle.Extraction.CSharp.Entities { @@ -124,6 +125,17 @@ namespace Semmle.Extraction.CSharp.Entities trapFile.param_location(this, Context.CreateLocation()); } + if (Symbol.HasExplicitDefaultValue && Context.Defines(Symbol)) + { + var defaultValueSyntax = GetDefaultValueFromSyntax(Symbol); + + Action defaultValueExpressionCreation = defaultValueSyntax is not null + ? () => Expression.Create(Context, defaultValueSyntax.Value, this, 0) + : () => Expression.CreateGenerated(Context, Symbol, this, 0, Location); + + Context.PopulateLater(defaultValueExpressionCreation); + } + if (!IsSourceDeclaration || !Symbol.FromSource()) return; @@ -139,36 +151,28 @@ namespace Semmle.Extraction.CSharp.Entities TypeMention.Create(Context, syntax.Type!, this, type); } } + } - if (Symbol.HasExplicitDefaultValue && Context.Defines(Symbol)) + private static EqualsValueClauseSyntax? GetDefaultValueFromSyntax(IParameterSymbol symbol) + { + // This is a slight bug in the dbscheme + // We should really define param_default(param, string) + // And use parameter child #0 to encode the default expression. + var defaultValue = GetParameterDefaultValue(symbol); + if (defaultValue is null) { - // This is a slight bug in the dbscheme - // We should really define param_default(param, string) - // And use parameter child #0 to encode the default expression. - var defaultValue = GetParameterDefaultValue(Symbol); - if (defaultValue is null) + // In case this parameter belongs to an accessor of an indexer, we need + // to get the default value from the corresponding parameter belonging + // to the indexer itself + if (symbol.ContainingSymbol is IMethodSymbol method) { - // In case this parameter belongs to an accessor of an indexer, we need - // to get the default value from the corresponding parameter belonging - // to the indexer itself - var method = (IMethodSymbol)Symbol.ContainingSymbol; - if (method is not null) - { - var i = method.Parameters.IndexOf(Symbol); - var indexer = (IPropertySymbol?)method.AssociatedSymbol; - if (indexer is not null) - defaultValue = GetParameterDefaultValue(indexer.Parameters[i]); - } - } - - if (defaultValue is not null) - { - Context.PopulateLater(() => - { - Expression.Create(Context, defaultValue.Value, this, 0); - }); + var i = method.Parameters.IndexOf(symbol); + if (method.AssociatedSymbol is IPropertySymbol indexer) + defaultValue = GetParameterDefaultValue(indexer.Parameters[i]); } } + + return defaultValue; } public override bool IsSourceDeclaration => Symbol.IsSourceDeclaration(); diff --git a/csharp/extractor/Semmle.Extraction.Tests/Semmle.Extraction.Tests.csproj b/csharp/extractor/Semmle.Extraction.Tests/Semmle.Extraction.Tests.csproj index 5b242d984ee..4a3e079e754 100644 --- a/csharp/extractor/Semmle.Extraction.Tests/Semmle.Extraction.Tests.csproj +++ b/csharp/extractor/Semmle.Extraction.Tests/Semmle.Extraction.Tests.csproj @@ -1,7 +1,6 @@ - Exe net5.0 false win-x64;linux-x64;osx-x64 @@ -12,10 +11,11 @@ - + all runtime; build; native; contentfiles; analyzers + diff --git a/csharp/extractor/Semmle.Extraction/Semmle.Extraction.csproj b/csharp/extractor/Semmle.Extraction/Semmle.Extraction.csproj index 87259c99668..03189150a47 100644 --- a/csharp/extractor/Semmle.Extraction/Semmle.Extraction.csproj +++ b/csharp/extractor/Semmle.Extraction/Semmle.Extraction.csproj @@ -16,7 +16,7 @@ - + runtime; build; native; contentfiles; analyzers; buildtransitive all diff --git a/csharp/extractor/Semmle.Util.Tests/Semmle.Util.Tests.csproj b/csharp/extractor/Semmle.Util.Tests/Semmle.Util.Tests.csproj index ca9599cf770..e5c2019bb42 100644 --- a/csharp/extractor/Semmle.Util.Tests/Semmle.Util.Tests.csproj +++ b/csharp/extractor/Semmle.Util.Tests/Semmle.Util.Tests.csproj @@ -1,7 +1,6 @@ - Exe net5.0 false win-x64;linux-x64;osx-x64 @@ -10,10 +9,11 @@ - + all runtime; build; native; contentfiles; analyzers + diff --git a/csharp/ql/src/API Abuse/DisposeNotCalledOnException.ql b/csharp/ql/src/API Abuse/DisposeNotCalledOnException.ql index 7469cbc59e7..abb962449b9 100644 --- a/csharp/ql/src/API Abuse/DisposeNotCalledOnException.ql +++ b/csharp/ql/src/API Abuse/DisposeNotCalledOnException.ql @@ -18,36 +18,6 @@ import csharp import Dispose import semmle.code.csharp.frameworks.System -/** - * Gets an exception type that may be thrown during the execution of method `m`. - * Assumes any exception may be thrown by library types. - */ -Class getAThrownException(Method m) { - m.fromLibrary() and - result = any(SystemExceptionClass sc) - or - exists(ControlFlowElement cfe | - cfe = any(ThrowElement te | result = te.getExpr().getType()) or - cfe = any(MethodCall mc | result = getAThrownException(mc.getARuntimeTarget())) - | - cfe.getEnclosingCallable() = m and - not isTriedAgainstException(cfe, result) - ) -} - -/** - * Holds if control flow element is tried against throwing an exception of type - * `ec`. - */ -pragma[noinline] -predicate isTriedAgainstException(ControlFlowElement cfe, ExceptionClass ec) { - (cfe instanceof ThrowElement or cfe instanceof MethodCall) and - exists(TryStmt ts | - ts.getATriedElement() = cfe and - exists(ts.getAnExceptionHandler(ec)) - ) -} - private class DisposeCall extends MethodCall { DisposeCall() { this.getTarget() instanceof DisposeMethod } } @@ -78,8 +48,17 @@ predicate disposeReachableFromDisposableCreation(DisposeCall disposeCall, Expr d reachesDisposeCall(disposeCall, DataFlow::exprNode(disposableCreation)) } -class MethodCallThatMayThrow extends MethodCall { - MethodCallThatMayThrow() { exists(getAThrownException(this.getARuntimeTarget())) } +/** + * Holds if control flow element is tried against throwing an exception of type + * `ec`. + */ +pragma[noinline] +predicate isTriedAgainstException(ControlFlowElement cfe, ExceptionClass ec) { + (cfe instanceof ThrowElement or cfe instanceof MethodCall) and + exists(TryStmt ts | + ts.getATriedElement() = cfe and + exists(ts.getAnExceptionHandler(ec)) + ) } ControlFlowElement getACatchOrFinallyClauseChild() { @@ -88,15 +67,71 @@ ControlFlowElement getACatchOrFinallyClauseChild() { result = getACatchOrFinallyClauseChild().getAChild() } -from DisposeCall disposeCall, Expr disposableCreation, MethodCallThatMayThrow callThatThrows -where +private predicate candidate(DisposeCall disposeCall, Call call, Expr disposableCreation) { disposeReachableFromDisposableCreation(disposeCall, disposableCreation) and // The dispose call is not, itself, within a dispose method. not disposeCall.getEnclosingCallable() instanceof DisposeMethod and // Dispose call not within a finally or catch block not getACatchOrFinallyClauseChild() = disposeCall and // At least one method call exists between the allocation and disposal that could throw - disposableCreation.getAReachableElement() = callThatThrows and - callThatThrows.getAReachableElement() = disposeCall + disposableCreation.getAReachableElement() = call and + call.getAReachableElement() = disposeCall +} + +private class RelevantMethod extends Method { + RelevantMethod() { + exists(Call call | + candidate(_, call, _) and + this = call.getARuntimeTarget() + ) + or + exists(RelevantMethod other | other.calls(this)) + } + + pragma[noinline] + private RelevantMethod callsNoTry() { + exists(MethodCall mc | + result = mc.getARuntimeTarget() and + not isTriedAgainstException(mc, _) and + mc.getEnclosingCallable() = this + ) + } + + pragma[noinline] + private RelevantMethod callsInTry(MethodCall mc) { + result = mc.getARuntimeTarget() and + isTriedAgainstException(mc, _) and + mc.getEnclosingCallable() = this + } + + /** + * Gets an exception type that may be thrown during the execution of this method. + * Assumes any exception may be thrown by library types. + */ + Class getAThrownException() { + this.fromLibrary() and + result instanceof SystemExceptionClass + or + exists(ControlFlowElement cfe | + result = cfe.(ThrowElement).getExpr().getType() and + cfe.getEnclosingCallable() = this + or + result = this.callsInTry(cfe).getAThrownException() + | + not isTriedAgainstException(cfe, result) + ) + or + result = this.callsNoTry().getAThrownException() + } +} + +class MethodCallThatMayThrow extends MethodCall { + MethodCallThatMayThrow() { + exists(this.getARuntimeTarget().(RelevantMethod).getAThrownException()) + } +} + +from DisposeCall disposeCall, Expr disposableCreation, MethodCallThatMayThrow callThatThrows +where candidate(disposeCall, callThatThrows, disposableCreation) select disposeCall, "Dispose missed if exception is thrown by $@.", callThatThrows, callThatThrows.toString() diff --git a/csharp/ql/src/Customizations.qll b/csharp/ql/src/Customizations.qll new file mode 100644 index 00000000000..d5378a44f0d --- /dev/null +++ b/csharp/ql/src/Customizations.qll @@ -0,0 +1,12 @@ +/** + * Contains customizations to the standard library. + * + * This module is imported by `csharp.qll`, so any customizations defined here automatically + * apply to all queries. + * + * Typical examples of customizations include adding new subclasses of abstract classes such as + * the `RemoteFlowSource` and `SummarizedCallable` classes associated with the security queries + * to model frameworks that are not covered by the standard library. + */ + +import csharp diff --git a/csharp/ql/src/Metrics/Dependencies/ExternalDependencies.ql b/csharp/ql/src/Metrics/Dependencies/ExternalDependencies.ql index 6139262afd3..87e7d3a5cf6 100644 --- a/csharp/ql/src/Metrics/Dependencies/ExternalDependencies.ql +++ b/csharp/ql/src/Metrics/Dependencies/ExternalDependencies.ql @@ -5,7 +5,6 @@ * @kind treemap * @treemap.warnOn highValues * @metricType externalDependency - * @precision medium * @id cs/external-dependencies */ diff --git a/csharp/ql/src/Metrics/Files/DuplicationProblems.inc.qhelp b/csharp/ql/src/Metrics/Files/DuplicationProblems.inc.qhelp deleted file mode 100644 index 54397da6c99..00000000000 --- a/csharp/ql/src/Metrics/Files/DuplicationProblems.inc.qhelp +++ /dev/null @@ -1,16 +0,0 @@ - - - -

    -Duplicated code increases overall code size, making the code base -harder to maintain and harder to understand. It also becomes harder to fix bugs, -since a programmer applying a fix to one copy has to always remember to update -other copies accordingly. Finally, code duplication is generally an indication of -a poorly designed or hastily written code base, which typically suffers from other -problems as well. -

    - -
    -
    diff --git a/csharp/ql/src/Metrics/Files/FLinesOfCode.ql b/csharp/ql/src/Metrics/Files/FLinesOfCode.ql index 7aa709b2579..93f426d6329 100644 --- a/csharp/ql/src/Metrics/Files/FLinesOfCode.ql +++ b/csharp/ql/src/Metrics/Files/FLinesOfCode.ql @@ -5,7 +5,6 @@ * @treemap.warnOn highValues * @metricType file * @metricAggregate avg sum max - * @precision very-high * @id cs/lines-of-code-in-files * @tags maintainability * complexity diff --git a/csharp/ql/src/Metrics/Files/FLinesOfComment.ql b/csharp/ql/src/Metrics/Files/FLinesOfComment.ql index 2071b86ad7a..0686268169f 100644 --- a/csharp/ql/src/Metrics/Files/FLinesOfComment.ql +++ b/csharp/ql/src/Metrics/Files/FLinesOfComment.ql @@ -5,7 +5,6 @@ * @treemap.warnOn lowValues * @metricType file * @metricAggregate avg sum max - * @precision very-high * @id cs/lines-of-comments-in-files * @tags maintainability * documentation diff --git a/csharp/ql/src/Metrics/Files/FLinesOfCommentedCode.ql b/csharp/ql/src/Metrics/Files/FLinesOfCommentedCode.ql index 7e88ef5e91b..e84100b8928 100644 --- a/csharp/ql/src/Metrics/Files/FLinesOfCommentedCode.ql +++ b/csharp/ql/src/Metrics/Files/FLinesOfCommentedCode.ql @@ -5,7 +5,6 @@ * @treemap.warnOn highValues * @metricType file * @metricAggregate avg sum max - * @precision high * @id cs/lines-of-commented-out-code-in-files * @tags maintainability * documentation diff --git a/csharp/ql/src/Metrics/Files/FLinesOfDuplicatedCode.qhelp b/csharp/ql/src/Metrics/Files/FLinesOfDuplicatedCode.qhelp deleted file mode 100644 index 3f7b574a4dc..00000000000 --- a/csharp/ql/src/Metrics/Files/FLinesOfDuplicatedCode.qhelp +++ /dev/null @@ -1,30 +0,0 @@ - - - -

    -A file that contains many lines that are duplicated within the code base is problematic -for a number of reasons. -

    - -
    - - - - -

    -Refactor files with lots of duplicated code to extract the common code into -shared classes and assemblies. -

    - -
    - - - -
    -
  • M. Fowler, Refactoring. Addison-Wesley, 1999.
  • - - - - diff --git a/csharp/ql/src/Metrics/Files/FLinesOfDuplicatedCode.ql b/csharp/ql/src/Metrics/Files/FLinesOfDuplicatedCode.ql deleted file mode 100644 index bf3da5e1f80..00000000000 --- a/csharp/ql/src/Metrics/Files/FLinesOfDuplicatedCode.ql +++ /dev/null @@ -1,27 +0,0 @@ -/** - * @deprecated - * @name Duplicated lines in files - * @description The number of lines in a file, including code, comment and whitespace lines, - * which are duplicated in at least one other place. - * @kind treemap - * @treemap.warnOn highValues - * @metricType file - * @metricAggregate avg sum max - * @precision high - * @id cs/duplicated-lines-in-files - * @tags testability - * modularity - */ - -import external.CodeDuplication - -from SourceFile f, int n -where - n = - count(int line | - exists(DuplicateBlock d | d.sourceFile() = f | - line in [d.sourceStartLine() .. d.sourceEndLine()] and - not whitelistedLineForDuplication(f, line) - ) - ) -select f, n order by n desc diff --git a/csharp/ql/src/Metrics/Files/FNumberOfTests.ql b/csharp/ql/src/Metrics/Files/FNumberOfTests.ql index 613c76c68af..f7abfc24a91 100644 --- a/csharp/ql/src/Metrics/Files/FNumberOfTests.ql +++ b/csharp/ql/src/Metrics/Files/FNumberOfTests.ql @@ -5,7 +5,6 @@ * @treemap.warnOn highValues * @metricType file * @metricAggregate avg sum max - * @precision medium * @id cs/tests-in-files * @tags maintainability */ diff --git a/csharp/ql/src/Security Features/CWE-937/Vulnerabilities.qll b/csharp/ql/src/Security Features/CWE-937/Vulnerabilities.qll deleted file mode 100644 index 86f32443cdb..00000000000 --- a/csharp/ql/src/Security Features/CWE-937/Vulnerabilities.qll +++ /dev/null @@ -1,335 +0,0 @@ -/** - * Provides a list of NuGet packages with known vulnerabilities. - * - * To add a new vulnerability follow the existing pattern. - * Create a new class that extends the abstract class `Vulnerability`, - * supplying the name and the URL, and override one (or both) of - * `matchesRange` and `matchesVersion`. - */ - -import csharp -import Vulnerability - -class MicrosoftAdvisory4021279 extends Vulnerability { - MicrosoftAdvisory4021279() { this = "Microsoft Security Advisory 4021279" } - - override string getUrl() { result = "https://github.com/dotnet/corefx/issues/19535" } - - override predicate matchesRange(string name, Version affected, Version fixed) { - name = "System.Text.Encodings.Web" and - ( - affected = "4.0.0" and fixed = "4.0.1" - or - affected = "4.3.0" and fixed = "4.3.1" - ) - or - name = "System.Net.Http" and - ( - affected = "4.1.1" and fixed = "4.1.2" - or - affected = "4.3.1" and fixed = "4.3.2" - ) - or - name = "System.Net.Http.WinHttpHandler" and - ( - affected = "4.0.1" and fixed = "4.0.2" - or - affected = "4.3.0" and fixed = "4.3.1" - ) - or - name = "System.Net.Security" and - ( - affected = "4.0.0" and fixed = "4.0.1" - or - affected = "4.3.0" and fixed = "4.3.1" - ) - or - ( - name = "Microsoft.AspNetCore.Mvc" - or - name = "Microsoft.AspNetCore.Mvc.Core" - or - name = "Microsoft.AspNetCore.Mvc.Abstractions" - or - name = "Microsoft.AspNetCore.Mvc.ApiExplorer" - or - name = "Microsoft.AspNetCore.Mvc.Cors" - or - name = "Microsoft.AspNetCore.Mvc.DataAnnotations" - or - name = "Microsoft.AspNetCore.Mvc.Formatters.Json" - or - name = "Microsoft.AspNetCore.Mvc.Formatters.Xml" - or - name = "Microsoft.AspNetCore.Mvc.Localization" - or - name = "Microsoft.AspNetCore.Mvc.Razor.Host" - or - name = "Microsoft.AspNetCore.Mvc.Razor" - or - name = "Microsoft.AspNetCore.Mvc.TagHelpers" - or - name = "Microsoft.AspNetCore.Mvc.ViewFeatures" - or - name = "Microsoft.AspNetCore.Mvc.WebApiCompatShim" - ) and - ( - affected = "1.0.0" and fixed = "1.0.4" - or - affected = "1.1.0" and fixed = "1.1.3" - ) - } -} - -class CVE_2017_8700 extends Vulnerability { - CVE_2017_8700() { this = "CVE-2017-8700" } - - override string getUrl() { result = "https://github.com/aspnet/Announcements/issues/279" } - - override predicate matchesRange(string name, Version affected, Version fixed) { - ( - name = "Microsoft.AspNetCore.Mvc.Core" - or - name = "Microsoft.AspNetCore.Mvc.Cors" - ) and - ( - affected = "1.0.0" and fixed = "1.0.6" - or - affected = "1.1.0" and fixed = "1.1.6" - ) - } -} - -class CVE_2018_0765 extends Vulnerability { - CVE_2018_0765() { this = "CVE-2018-0765" } - - override string getUrl() { result = "https://github.com/dotnet/announcements/issues/67" } - - override predicate matchesRange(string name, Version affected, Version fixed) { - name = "System.Security.Cryptography.Xml" and - affected = "0.0.0" and - fixed = "4.4.2" - } -} - -class AspNetCore_Mar18 extends Vulnerability { - AspNetCore_Mar18() { this = "ASPNETCore-Mar18" } - - override string getUrl() { result = "https://github.com/aspnet/Announcements/issues/300" } - - override predicate matchesRange(string name, Version affected, Version fixed) { - ( - name = "Microsoft.AspNetCore.Server.Kestrel.Core" - or - name = "Microsoft.AspNetCore.Server.Kestrel.Transport.Abstractions" - or - name = "Microsoft.AspNetCore.Server.Kestrel.Transport.Libuv" - ) and - affected = "2.0.0" and - fixed = "2.0.3" - or - name = "Microsoft.AspNetCore.All" and - affected = "2.0.0" and - fixed = "2.0.8" - } -} - -class CVE_2018_8409 extends Vulnerability { - CVE_2018_8409() { this = "CVE-2018-8409" } - - override string getUrl() { result = "https://github.com/aspnet/Announcements/issues/316" } - - override predicate matchesRange(string name, Version affected, Version fixed) { - name = "System.IO.Pipelines" and affected = "4.5.0" and fixed = "4.5.1" - or - (name = "Microsoft.AspNetCore.All" or name = "Microsoft.AspNetCore.App") and - affected = "2.1.0" and - fixed = "2.1.4" - } -} - -class CVE_2018_8171 extends Vulnerability { - CVE_2018_8171() { this = "CVE-2018-8171" } - - override string getUrl() { result = "https://github.com/aspnet/Announcements/issues/310" } - - override predicate matchesRange(string name, Version affected, Version fixed) { - name = "Microsoft.AspNetCore.Identity" and - ( - affected = "1.0.0" and fixed = "1.0.6" - or - affected = "1.1.0" and fixed = "1.1.6" - or - affected = "2.0.0" and fixed = "2.0.4" - or - affected = "2.1.0" and fixed = "2.1.2" - ) - } -} - -class CVE_2018_8356 extends Vulnerability { - CVE_2018_8356() { this = "CVE-2018-8356" } - - override string getUrl() { result = "https://github.com/dotnet/announcements/issues/73" } - - override predicate matchesRange(string name, Version affected, Version fixed) { - ( - name = "System.Private.ServiceModel" - or - name = "System.ServiceModel.Http" - or - name = "System.ServiceModel.NetTcp" - ) and - ( - affected = "4.0.0" and fixed = "4.1.3" - or - affected = "4.3.0" and fixed = "4.3.3" - or - affected = "4.4.0" and fixed = "4.4.4" - or - affected = "4.5.0" and fixed = "4.5.3" - ) - or - ( - name = "System.ServiceModel.Duplex" - or - name = "System.ServiceModel.Security" - ) and - ( - affected = "4.0.0" and fixed = "4.0.4" - or - affected = "4.3.0" and fixed = "4.3.3" - or - affected = "4.4.0" and fixed = "4.4.4" - or - affected = "4.5.0" and fixed = "4.5.3" - ) - or - name = "System.ServiceModel.NetTcp" and - ( - affected = "4.0.0" and fixed = "4.1.3" - or - affected = "4.3.0" and fixed = "4.3.3" - or - affected = "4.4.0" and fixed = "4.4.4" - or - affected = "4.5.0" and fixed = "4.5.1" - ) - } -} - -class ASPNETCore_Jul18 extends Vulnerability { - ASPNETCore_Jul18() { this = "ASPNETCore-July18" } - - override string getUrl() { result = "https://github.com/aspnet/Announcements/issues/311" } - - override predicate matchesRange(string name, Version affected, Version fixed) { - name = "Microsoft.AspNetCore.Server.Kestrel.Core" and - ( - affected = "2.0.0" and fixed = "2.0.4" - or - affected = "2.1.0" and fixed = "2.1.2" - ) - or - name = "Microsoft.AspNetCore.All" and - ( - affected = "2.0.0" and fixed = "2.0.9" - or - affected = "2.1.0" and fixed = "2.1.2" - ) - or - name = "Microsoft.AspNetCore.App" and - affected = "2.1.0" and - fixed = "2.1.2" - } -} - -class CVE_2018_8292 extends Vulnerability { - CVE_2018_8292() { this = "CVE-2018-8292" } - - override string getUrl() { result = "https://github.com/dotnet/announcements/issues/88" } - - override predicate matchesVersion(string name, Version affected, Version fixed) { - name = "System.Net.Http" and - ( - affected = "2.0" or - affected = "4.0.0" or - affected = "4.1.0" or - affected = "1.1.1" or - affected = "4.1.2" or - affected = "4.3.0" or - affected = "4.3.1" or - affected = "4.3.2" or - affected = "4.3.3" - ) and - fixed = "4.3.4" - } -} - -class CVE_2018_0786 extends Vulnerability { - CVE_2018_0786() { this = "CVE-2018-0786" } - - override string getUrl() { result = "https://github.com/dotnet/announcements/issues/51" } - - override predicate matchesRange(string name, Version affected, Version fixed) { - ( - name = "System.ServiceModel.Primitives" - or - name = "System.ServiceModel.Http" - or - name = "System.ServiceModel.NetTcp" - or - name = "System.ServiceModel.Duplex" - or - name = "System.ServiceModel.Security" - or - name = "System.Private.ServiceModel" - ) and - ( - affected = "4.4.0" and fixed = "4.4.1" - or - affected = "4.3.0" and fixed = "4.3.1" - ) - or - ( - name = "System.ServiceModel.Primitives" - or - name = "System.ServiceModel.Http" - or - name = "System.ServiceModel.NetTcp" - or - name = "System.Private.ServiceModel" - ) and - affected = "4.1.0" and - fixed = "4.1.1" - or - ( - name = "System.ServiceModel.Duplex" - or - name = "System.ServiceModel.Security" - ) and - affected = "4.0.1" and - fixed = "4.0.2" - } -} - -class CVE_2019_0657 extends Vulnerability { - CVE_2019_0657() { this = "CVE-2019-0657" } - - override predicate matchesRange(string name, Version affected, Version fixed) { - name = "Microsoft.NETCore.App" and - ( - affected = "2.1.0" and fixed = "2.1.8" - or - affected = "2.2.0" and fixed = "2.2.2" - ) - } - - override predicate matchesVersion(string name, Version affected, Version fixed) { - name = "System.Private.Uri" and - affected = "4.3.0" and - fixed = "4.3.1" - } - - override string getUrl() { result = "https://github.com/dotnet/announcements/issues/97" } -} diff --git a/csharp/ql/src/Security Features/CWE-937/Vulnerability.qll b/csharp/ql/src/Security Features/CWE-937/Vulnerability.qll deleted file mode 100644 index a2c6d482c1c..00000000000 --- a/csharp/ql/src/Security Features/CWE-937/Vulnerability.qll +++ /dev/null @@ -1,93 +0,0 @@ -import csharp - -/** - * A package reference in an XML file, for example in a - * `.csproj` file, a `.props` file, or a `packages.config` file. - */ -class Package extends XMLElement { - string name; - Version version; - - Package() { - (this.getName() = "PackageManagement" or this.getName() = "PackageReference") and - name = this.getAttributeValue("Include") and - version = this.getAttributeValue("Version") - or - this.getName() = "package" and - name = this.getAttributeValue("id") and - version = this.getAttributeValue("version") - } - - /** Gets the name of the package, for example `System.IO.Pipelines`. */ - string getPackageName() { result = name } - - /** Gets the version of the package, for example `4.5.1`. */ - Version getVersion() { result = version } - - override string toString() { result = name + " " + version } -} - -/** - * A vulnerability, where the name of the vulnerability is this string. - * One of `matchesRange` or `matchesVersion` must be overridden in order to - * specify which packages are vulnerable. - */ -abstract class Vulnerability extends string { - bindingset[this] - Vulnerability() { any() } - - /** - * Holds if a package with name `name` is vulnerable from version `affected` - * until version `fixed`. - */ - predicate matchesRange(string name, Version affected, Version fixed) { none() } - - /** - * Holds if a package with name `name` is vulnerable in version `affected`, and - * is fixed by version `fixed`. - */ - predicate matchesVersion(string name, Version affected, Version fixed) { none() } - - /** Gets the URL describing the vulnerability. */ - abstract string getUrl(); - - /** - * Holds if a package with name `name` and version `version` - * has this vulnerability. The fixed version is given by `fixed`. - */ - bindingset[name, version] - predicate isVulnerable(string name, Version version, Version fixed) { - exists(Version affected, string n | name.toLowerCase() = n.toLowerCase() | - matchesRange(n, affected, fixed) and - version.compareTo(fixed) < 0 and - version.compareTo(affected) >= 0 - or - matchesVersion(n, affected, fixed) and - version.compareTo(affected) = 0 - ) - } -} - -bindingset[name, version] -private Version getUltimateFix(string name, Version version) { - result = max(Version fix | any(Vulnerability v).isVulnerable(name, version, fix)) -} - -/** - * A package with a vulnerability. - */ -class VulnerablePackage extends Package { - Vulnerability vuln; - - VulnerablePackage() { vuln.isVulnerable(this.getPackageName(), this.getVersion(), _) } - - /** Gets the vulnerability of this package. */ - Vulnerability getVulnerability() { result = vuln } - - /** Gets the version of this package where the vulnerability is fixed. */ - Version getFixedVersion() { - // This is needed because sometimes the "fixed" version of some - // vulnerabilities are themselves vulnerable to other vulnerabilities. - result = getUltimateFix(this.getPackageName(), this.getVersion()) - } -} diff --git a/csharp/ql/src/Security Features/CWE-937/VulnerablePackage.qhelp b/csharp/ql/src/Security Features/CWE-937/VulnerablePackage.qhelp deleted file mode 100644 index 112642c7958..00000000000 --- a/csharp/ql/src/Security Features/CWE-937/VulnerablePackage.qhelp +++ /dev/null @@ -1,43 +0,0 @@ - - - - -

    -Using a package with a known vulnerability is a security risk that could leave the -software vulnerable to attack. -

    -

    -This query reads the packages imported by the project build files and -.config files, and checks them against a list of packages with known -vulnerabilities. -

    -
    - - -

    -Upgrade the package to the recommended version using, for example, the NuGet package manager, -or by editing the project files directly. -

    -
    - - -

    -The following example shows a C# project file referencing package System.Net.Http -version 4.3.1, which is vulnerable to CVE-2018-8292. -

    - -

    -The project file can be fixed by changing the version of the package to 4.3.4. -

    - -
    - - -
  • -OWASP: A9-Using Components with Known Vulnerabilities. -
  • -
    - -
    diff --git a/csharp/ql/src/Security Features/CWE-937/VulnerablePackage.ql b/csharp/ql/src/Security Features/CWE-937/VulnerablePackage.ql deleted file mode 100644 index 4be7c76dd7b..00000000000 --- a/csharp/ql/src/Security Features/CWE-937/VulnerablePackage.ql +++ /dev/null @@ -1,20 +0,0 @@ -/** - * @name Using a package with a known vulnerability - * @description Using a package with a known vulnerability is a security risk. - * Upgrade the package to a version that does not contain the vulnerability. - * @kind problem - * @problem.severity error - * @precision high - * @id cs/use-of-vulnerable-package - * @tags security - * external/cwe/cwe-937 - */ - -import csharp -import Vulnerabilities - -from Vulnerability vuln, VulnerablePackage package -where vuln = package.getVulnerability() -select package, - "Package '" + package + "' has vulnerability $@, and should be upgraded to version " + - package.getFixedVersion() + ".", vuln.getUrl(), vuln.toString() diff --git a/csharp/ql/src/Security Features/CWE-937/VulnerablePackageBAD.csproj b/csharp/ql/src/Security Features/CWE-937/VulnerablePackageBAD.csproj deleted file mode 100644 index b13494984ec..00000000000 --- a/csharp/ql/src/Security Features/CWE-937/VulnerablePackageBAD.csproj +++ /dev/null @@ -1,15 +0,0 @@ - - - - netcoreapp2.0 - Semmle.Autobuild - Semmle.Autobuild - Exe - - - - - - - - diff --git a/csharp/ql/src/Security Features/CWE-937/VulnerablePackageGOOD.csproj b/csharp/ql/src/Security Features/CWE-937/VulnerablePackageGOOD.csproj deleted file mode 100644 index 98275b86a6f..00000000000 --- a/csharp/ql/src/Security Features/CWE-937/VulnerablePackageGOOD.csproj +++ /dev/null @@ -1,15 +0,0 @@ - - - - netcoreapp2.0 - Semmle.Autobuild - Semmle.Autobuild - Exe - - - - - - - - diff --git a/csharp/ql/src/Stubs/make_stubs.py b/csharp/ql/src/Stubs/make_stubs.py index e94cf0c7261..7d2ce9f7ed7 100644 --- a/csharp/ql/src/Stubs/make_stubs.py +++ b/csharp/ql/src/Stubs/make_stubs.py @@ -43,12 +43,6 @@ if not foundCS: print("Test directory does not contain .cs files. Please specify a working qltest directory.") exit(1) -cmd = ['odasa', 'selfTest'] -print('Running ' + ' '.join(cmd)) -if subprocess.check_call(cmd): - print("odasa selfTest failed. Ensure odasa is on your current path.") - exit(1) - csharpQueries = os.path.abspath(os.path.dirname(sys.argv[0])) outputFile = os.path.join(testDir, 'stubs.cs') @@ -58,56 +52,75 @@ if os.path.isfile(outputFile): os.remove(outputFile) # It would interfere with the test. print("Removed previous", outputFile) -cmd = ['odasa', 'qltest', '--optimize', '--leave-temp-files', testDir] +cmd = ['codeql', 'test', 'run', '--keep-databases', testDir] print('Running ' + ' '.join(cmd)) if subprocess.check_call(cmd): - print("qltest failed. Please fix up the test before proceeding.") + print("codeql test failed. Please fix up the test before proceeding.") exit(1) -dbDir = os.path.join(testDir, os.path.basename(testDir) + ".testproj", "db-csharp") +dbDir = os.path.join(testDir, os.path.basename(testDir) + ".testproj") if not os.path.isdir(dbDir): - print("Expected database directory " + dbDir + " not found. Please contact Semmle.") + print("Expected database directory " + dbDir + " not found.") exit(1) -cmd = ['odasa', 'runQuery', '--query', os.path.join(csharpQueries, 'MinimalStubsFromSource.ql'), '--db', dbDir, '--output-file', outputFile] +cmd = ['codeql', 'query', 'run', os.path.join( + csharpQueries, 'MinimalStubsFromSource.ql'), '--database', dbDir, '--output', outputFile] print('Running ' + ' '.join(cmd)) if subprocess.check_call(cmd): - print('Failed to run the query to generate output file. Please contact Semmle.') + print('Failed to run the query to generate output file.') exit(1) -# Remove the leading " and trailing " bytes from the file -len = os.stat(outputFile).st_size -f = open(outputFile, "rb") -try: - quote = f.read(1) - if quote != b'"': - print("Unexpected character in file. Please contact Semmle.") - contents = f.read(len-3) - quote = f.read(1) - if quote != b'"': - print("Unexpected end character. Please contact Semmle.", quote) -finally: - f.close() +# Remove the leading and trailing bytes from the file +length = os.stat(outputFile).st_size +if length < 20: + contents = b'' +else: + f = open(outputFile, "rb") + try: + countTillSlash = 0 + foundSlash = False + slash = f.read(1) + while slash != b'': + if slash == b'/': + foundSlash = True + break + countTillSlash += 1 + slash = f.read(1) + + if not foundSlash: + countTillSlash = 0 + + f.seek(0) + quote = f.read(countTillSlash) + print("Start characters in file skipped.", quote) + post = b'\x0e\x01\x08#select\x01\x01\x00s\x00' + contents = f.read(length - len(post) - countTillSlash) + quote = f.read(len(post)) + if quote != post: + print("Unexpected end character in file.", quote) + finally: + f.close() f = open(outputFile, "wb") f.write(contents) f.close() -cmd = ['odasa', 'qltest', '--optimize', testDir] +cmd = ['codeql', 'test', 'run', testDir] print('Running ' + ' '.join(cmd)) if subprocess.check_call(cmd): - print('\nTest failed. You may need to fix up', outputFile) - print('It may help to view', outputFile, ' in Visual Studio') - print("Next steps:") - print('1. Look at the compilation errors, and fix up', outputFile, 'so that the test compiles') - print('2. Re-run odasa qltest --optimize "' + testDir + '"') - print('3. git add "' + outputFile + '"') - exit(1) + print('\nTest failed. You may need to fix up', outputFile) + print('It may help to view', outputFile, ' in Visual Studio') + print("Next steps:") + print('1. Look at the compilation errors, and fix up', + outputFile, 'so that the test compiles') + print('2. Re-run codeql test run "' + testDir + '"') + print('3. git add "' + outputFile + '"') + exit(1) print("\nStub generation successful! Next steps:") print('1. Edit "semmle-extractor-options" in the .cs files to remove unused references') -print('2. Re-run odasa qltest --optimize "' + testDir + '"') +print('2. Re-run codeql test run "' + testDir + '"') print('3. git add "' + outputFile + '"') print('4. Commit your changes.') diff --git a/csharp/ql/src/codeql-suites/csharp-code-scanning.qls b/csharp/ql/src/codeql-suites/csharp-code-scanning.qls index 44fe11937e4..3646204da7d 100644 --- a/csharp/ql/src/codeql-suites/csharp-code-scanning.qls +++ b/csharp/ql/src/codeql-suites/csharp-code-scanning.qls @@ -2,5 +2,3 @@ - qlpack: codeql-csharp - apply: code-scanning-selectors.yml from: codeql-suite-helpers -- apply: codeql-suites/exclude-dependency-queries.yml - from: codeql-csharp diff --git a/csharp/ql/src/codeql-suites/csharp-security-and-quality.qls b/csharp/ql/src/codeql-suites/csharp-security-and-quality.qls index f5df6527965..20ead656db0 100644 --- a/csharp/ql/src/codeql-suites/csharp-security-and-quality.qls +++ b/csharp/ql/src/codeql-suites/csharp-security-and-quality.qls @@ -2,5 +2,3 @@ - qlpack: codeql-csharp - apply: security-and-quality-selectors.yml from: codeql-suite-helpers -- apply: codeql-suites/exclude-dependency-queries.yml - from: codeql-csharp diff --git a/csharp/ql/src/codeql-suites/csharp-security-extended.qls b/csharp/ql/src/codeql-suites/csharp-security-extended.qls index f4efe70892c..b74ffa9c2e0 100644 --- a/csharp/ql/src/codeql-suites/csharp-security-extended.qls +++ b/csharp/ql/src/codeql-suites/csharp-security-extended.qls @@ -2,5 +2,3 @@ - qlpack: codeql-csharp - apply: security-extended-selectors.yml from: codeql-suite-helpers -- apply: codeql-suites/exclude-dependency-queries.yml - from: codeql-csharp diff --git a/csharp/ql/src/codeql-suites/exclude-dependency-queries.yml b/csharp/ql/src/codeql-suites/exclude-dependency-queries.yml deleted file mode 100644 index 53ad48be212..00000000000 --- a/csharp/ql/src/codeql-suites/exclude-dependency-queries.yml +++ /dev/null @@ -1,4 +0,0 @@ -- description: C# queries which overlap with dependency analysis -- exclude: - query path: - - Security Features/CWE-937/VulnerablePackage.ql diff --git a/csharp/ql/src/csharp.qll b/csharp/ql/src/csharp.qll index 3c821c9a443..dc187fc8d92 100644 --- a/csharp/ql/src/csharp.qll +++ b/csharp/ql/src/csharp.qll @@ -2,6 +2,7 @@ * The default C# QL library. */ +import Customizations import semmle.code.csharp.Attribute import semmle.code.csharp.Callable import semmle.code.csharp.Comments diff --git a/csharp/ql/src/definitions.qll b/csharp/ql/src/definitions.qll index 2004ad0d218..c1b456f4dbf 100644 --- a/csharp/ql/src/definitions.qll +++ b/csharp/ql/src/definitions.qll @@ -187,5 +187,11 @@ cached Declaration definitionOf(Use use, string kind) { result = use.getDefinition() and result.fromSource() and - kind = use.getUseType() + kind = use.getUseType() and + // Some entities have many locations. This can arise for files that + // are duplicated multiple times in the database at different + // locations. Rather than letting the result set explode, we just + // exclude results that are "too ambiguous" -- we could also arbitrarily + // pick one location later on. + strictcount(result.getLocation()) < 10 } diff --git a/csharp/ql/src/external/CodeDuplication.qll b/csharp/ql/src/external/CodeDuplication.qll deleted file mode 100644 index f4165e599e8..00000000000 --- a/csharp/ql/src/external/CodeDuplication.qll +++ /dev/null @@ -1,305 +0,0 @@ -import csharp - -private string relativePath(File file) { result = file.getRelativePath().replaceAll("\\", "/") } - -/** - * Holds if the `index`-th token of block `copy` is in file `file`, spanning - * column `sc` of line `sl` to column `ec` of line `el`. - * - * For more information, see [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html). - */ -pragma[nomagic] -predicate tokenLocation(File file, int sl, int sc, int ec, int el, Copy copy, int index) { - file = copy.sourceFile() and - tokens(copy, index, sl, sc, ec, el) -} - -class Copy extends @duplication_or_similarity { - private int lastToken() { result = max(int i | tokens(this, i, _, _, _, _) | i) } - - int tokenStartingAt(Location loc) { - tokenLocation(loc.getFile(), loc.getStartLine(), loc.getStartColumn(), _, _, this, result) - } - - int tokenEndingAt(Location loc) { - tokenLocation(loc.getFile(), _, _, loc.getEndLine(), loc.getEndColumn(), this, result) - } - - int sourceStartLine() { tokens(this, 0, result, _, _, _) } - - int sourceStartColumn() { tokens(this, 0, _, result, _, _) } - - int sourceEndLine() { tokens(this, lastToken(), _, _, result, _) } - - int sourceEndColumn() { tokens(this, lastToken(), _, _, _, result) } - - int sourceLines() { result = this.sourceEndLine() + 1 - this.sourceStartLine() } - - int getEquivalenceClass() { duplicateCode(this, _, result) or similarCode(this, _, result) } - - File sourceFile() { - exists(string name | duplicateCode(this, name, _) or similarCode(this, name, _) | - name.replaceAll("\\", "/") = relativePath(result) - ) - } - - predicate hasLocationInfo( - string filepath, int startline, int startcolumn, int endline, int endcolumn - ) { - sourceFile().getAbsolutePath() = filepath and - startline = sourceStartLine() and - startcolumn = sourceStartColumn() and - endline = sourceEndLine() and - endcolumn = sourceEndColumn() - } - - string toString() { none() } -} - -class DuplicateBlock extends Copy, @duplication { - override string toString() { result = "Duplicate code: " + sourceLines() + " duplicated lines." } -} - -class SimilarBlock extends Copy, @similarity { - override string toString() { - result = "Similar code: " + sourceLines() + " almost duplicated lines." - } -} - -private Method sourceMethod() { method_location(result, _) and numlines(result, _, _, _) } - -private int numberOfSourceMethods(Class c) { - result = count(Method m | m = sourceMethod() and m.getDeclaringType() = c) -} - -private predicate blockCoversStatement(int equivClass, int first, int last, Stmt stmt) { - exists(DuplicateBlock b, Location loc | - stmt.getLocation() = loc and - first = b.tokenStartingAt(loc) and - last = b.tokenEndingAt(loc) and - b.getEquivalenceClass() = equivClass - ) -} - -private Stmt statementInMethod(Method m) { - result.getEnclosingCallable() = m and - not result instanceof BlockStmt -} - -private predicate duplicateStatement(Method m1, Method m2, Stmt s1, Stmt s2) { - exists(int equivClass, int first, int last | - s1 = statementInMethod(m1) and - s2 = statementInMethod(m2) and - blockCoversStatement(equivClass, first, last, s1) and - blockCoversStatement(equivClass, first, last, s2) and - s1 != s2 and - m1 != m2 - ) -} - -/** Holds if `duplicate` number of statements are duplicated in the methods. */ -predicate duplicateStatements(Method m1, Method m2, int duplicate, int total) { - duplicate = strictcount(Stmt s | duplicateStatement(m1, m2, s, _)) and - total = strictcount(statementInMethod(m1)) -} - -/** - * Find pairs of methods are identical - */ -predicate duplicateMethod(Method m, Method other) { - exists(int total | duplicateStatements(m, other, total, total)) -} - -private predicate similarLines(File f, int line) { - exists(SimilarBlock b | b.sourceFile() = f and line in [b.sourceStartLine() .. b.sourceEndLine()]) -} - -private predicate similarLinesPerEquivalenceClass(int equivClass, int lines, File f) { - lines = - strictsum(SimilarBlock b, int toSum | - (b.sourceFile() = f and b.getEquivalenceClass() = equivClass) and - toSum = b.sourceLines() - | - toSum - ) -} - -pragma[noopt] -private predicate similarLinesCovered(File f, int coveredLines, File otherFile) { - exists(int numLines | numLines = f.getNumberOfLines() | - exists(int coveredApprox | - coveredApprox = - strictsum(int num | - exists(int equivClass | - similarLinesPerEquivalenceClass(equivClass, num, f) and - similarLinesPerEquivalenceClass(equivClass, num, otherFile) and - f != otherFile - ) - ) and - exists(int n, int product | product = coveredApprox * 100 and n = product / numLines | n > 75) - ) and - exists(int notCovered | - notCovered = - count(int j | - j in [1 .. numLines] and - not similarLines(f, j) - ) and - coveredLines = numLines - notCovered - ) - ) -} - -private predicate duplicateLines(File f, int line) { - exists(DuplicateBlock b | - b.sourceFile() = f and line in [b.sourceStartLine() .. b.sourceEndLine()] - ) -} - -private predicate duplicateLinesPerEquivalenceClass(int equivClass, int lines, File f) { - lines = - strictsum(DuplicateBlock b, int toSum | - (b.sourceFile() = f and b.getEquivalenceClass() = equivClass) and - toSum = b.sourceLines() - | - toSum - ) -} - -pragma[noopt] -private predicate duplicateLinesCovered(File f, int coveredLines, File otherFile) { - exists(int numLines | numLines = f.getNumberOfLines() | - exists(int coveredApprox | - coveredApprox = - strictsum(int num | - exists(int equivClass | - duplicateLinesPerEquivalenceClass(equivClass, num, f) and - duplicateLinesPerEquivalenceClass(equivClass, num, otherFile) and - f != otherFile - ) - ) and - exists(int n, int product | product = coveredApprox * 100 and n = product / numLines | n > 75) - ) and - exists(int notCovered | - notCovered = - count(int j | - j in [1 .. numLines] and - not duplicateLines(f, j) - ) and - coveredLines = numLines - notCovered - ) - ) -} - -/** Holds if the two files are not duplicated but have more than 80% similar lines. */ -predicate similarFiles(File f, File other, int percent) { - exists(int covered, int total | - similarLinesCovered(f, covered, other) and - total = f.getNumberOfLines() and - covered * 100 / total = percent and - percent > 80 - ) and - not duplicateFiles(f, other, _) -} - -/** Holds if the two files have more than 70% duplicated lines. */ -predicate duplicateFiles(File f, File other, int percent) { - exists(int covered, int total | - duplicateLinesCovered(f, covered, other) and - total = f.getNumberOfLines() and - covered * 100 / total = percent and - percent > 70 - ) -} - -pragma[noopt] -private predicate duplicateAnonymousClass(AnonymousClass c, AnonymousClass other) { - exists(int numDup | - numDup = - strictcount(Method m1 | - exists(Method m2 | - duplicateMethod(m1, m2) and - m1 = sourceMethod() and - m1.getDeclaringType() = c and - c instanceof AnonymousClass and - m2.getDeclaringType() = other and - other instanceof AnonymousClass and - c != other - ) - ) and - numDup = numberOfSourceMethods(c) and - numDup = numberOfSourceMethods(other) and - forall(Type t | c.getABaseType() = t | t = other.getABaseType()) - ) -} - -pragma[noopt] -private predicate mostlyDuplicateClassBase(Class c, Class other, int numDup, int total) { - numDup = - strictcount(Method m1 | - exists(Method m2 | - duplicateMethod(m1, m2) and - m1 = sourceMethod() and - m1.getDeclaringType() = c and - m2.getDeclaringType() = other and - other instanceof Class and - c != other - ) - ) and - total = numberOfSourceMethods(c) and - exists(int n, int product | product = 100 * numDup and n = product / total | n > 80) and - not c instanceof AnonymousClass and - not other instanceof AnonymousClass -} - -/** Holds if the methods in the two classes are more than 80% duplicated. */ -predicate mostlyDuplicateClass(Class c, Class other, string message) { - exists(int numDup, int total | - mostlyDuplicateClassBase(c, other, numDup, total) and - ( - total != numDup and - exists(string s1, string s2, string s3, string name | - s1 = " out of " and - s2 = " methods in " and - s3 = " are duplicated in $@." and - name = c.getName() - | - message = numDup + s1 + total + s2 + name + s3 - ) - or - total = numDup and - exists(string s1, string s2, string name | - s1 = "All methods in " and s2 = " are identical in $@." and name = c.getName() - | - message = s1 + name + s2 - ) - ) - ) -} - -/** Holds if the two files are similar or duplicated. */ -predicate fileLevelDuplication(File f, File other) { - similarFiles(f, other, _) or duplicateFiles(f, other, _) -} - -/** - * Holds if the two classes are duplicated anonymous classes or more than 80% of - * their methods are duplicated. - */ -predicate classLevelDuplication(Class c, Class other) { - duplicateAnonymousClass(c, other) or mostlyDuplicateClass(c, other, _) -} - -private Element whitelistedDuplicateElement() { - result instanceof UsingNamespaceDirective or - result instanceof UsingStaticDirective -} - -/** - * Holds if the `line` in the `file` contains an element, such as a `using` - * directive, that is not considered for code duplication. - */ -predicate whitelistedLineForDuplication(File file, int line) { - exists(Location loc | loc = whitelistedDuplicateElement().getLocation() | - line = loc.getStartLine() and file = loc.getFile() - ) -} diff --git a/csharp/ql/src/external/DefectFilter.qll b/csharp/ql/src/external/DefectFilter.qll deleted file mode 100644 index 4f4f60b66c1..00000000000 --- a/csharp/ql/src/external/DefectFilter.qll +++ /dev/null @@ -1,34 +0,0 @@ -import csharp - -external predicate defectResults( - int id, string queryPath, string file, int startline, int startcol, int endline, int endcol, - string message -); - -class DefectResult extends int { - DefectResult() { defectResults(this, _, _, _, _, _, _, _) } - - string getQueryPath() { defectResults(this, result, _, _, _, _, _, _) } - - File getFile() { - exists(string path | - defectResults(this, _, path, _, _, _, _, _) and result.getAbsolutePath() = path - ) - } - - int getStartLine() { defectResults(this, _, _, result, _, _, _, _) } - - int getStartColumn() { defectResults(this, _, _, _, result, _, _, _) } - - int getEndLine() { defectResults(this, _, _, _, _, result, _, _) } - - int getEndColumn() { defectResults(this, _, _, _, _, _, result, _) } - - string getMessage() { defectResults(this, _, _, _, _, _, _, result) } - - string getURL() { - result = - "file://" + getFile().getAbsolutePath() + ":" + getStartLine() + ":" + getStartColumn() + ":" + - getEndLine() + ":" + getEndColumn() - } -} diff --git a/csharp/ql/src/external/DuplicateMethod.cs b/csharp/ql/src/external/DuplicateMethod.cs deleted file mode 100644 index 8a963528267..00000000000 --- a/csharp/ql/src/external/DuplicateMethod.cs +++ /dev/null @@ -1,22 +0,0 @@ -class Toolbox -{ - private int x; - private int y; - public void move(int x, int y) - { - this.x = x; - this.y = y; - } - // ... -} -class Window -{ - private int x; - private int y; - public void move(int x, int y) - { - this.x = x; - this.y = y; - } - // ... -} diff --git a/csharp/ql/src/external/DuplicateMethod.qhelp b/csharp/ql/src/external/DuplicateMethod.qhelp deleted file mode 100644 index d42ffb73c64..00000000000 --- a/csharp/ql/src/external/DuplicateMethod.qhelp +++ /dev/null @@ -1,35 +0,0 @@ - - - -

    Methods should not be duplicated at more than one place in the program. Duplicating code makes it harder to update -should a change need to be made. It also makes the code harder to read.

    - -
    - -

    Determining how to address this issue requires some consideration. If the duplicate methods are in the same class -then it is normally possible to just remove one and replace all references to that method by references to the other -method. If the methods are in different classes then there might be a need to create a superclass that -contains the method, which both classes inherit. If it is not logical to create a superclass the method -could be moved into a separate utility class.

    - -
    - -

    In this example the Toolbox and the Window class both have the same move method. In this case it would be logical to -put this method as well as the x and y properties into a new superclass that Toolbox and Window extend.

    - - -
    -
    -

    The example could be easily fixed by moving the x and y properties as well as the move method to a parent class. Note -that the x and y properties have to be changed to protected if they are accessed from the Toolbox and Window classes.

    - - -
    - - -
  • Elmar Juergens, Florian Deissenboeck, Benjamin Hummel and Stefan Wagner. Do Code Clones Matter?. 2009.
  • - -
    -
    diff --git a/csharp/ql/src/external/DuplicateMethod.ql b/csharp/ql/src/external/DuplicateMethod.ql deleted file mode 100644 index 371315cd4e6..00000000000 --- a/csharp/ql/src/external/DuplicateMethod.ql +++ /dev/null @@ -1,41 +0,0 @@ -/** - * @deprecated - * @name Duplicate method - * @description There is another identical implementation of this method. Extract the code to a common superclass or delegate to improve sharing. - * @kind problem - * @problem.severity recommendation - * @precision high - * @id cs/duplicate-method - * @tags testability - * maintainability - * useless-code - * duplicate-code - * statistical - * non-attributable - */ - -import csharp -import CodeDuplication - -predicate relevant(Method m) { - m.getNumberOfLinesOfCode() > 5 and not m.getName().matches("get%") - or - m.getNumberOfLinesOfCode() > 10 -} - -pragma[noopt] -predicate query(Method m, Method other) { - duplicateMethod(m, other) and - relevant(m) and - not exists(File f1, File f2 | - m.getFile() = f1 and fileLevelDuplication(f1, f2) and other.getFile() = f2 - ) and - not exists(Type t1, Type t2 | - m.getDeclaringType() = t1 and classLevelDuplication(t1, t2) and other.getDeclaringType() = t2 - ) -} - -from Method m, Method other -where query(m, other) -select m, "Method " + m.getName() + " is duplicated in $@.", other, - other.getDeclaringType().getName() + "." + other.getName() diff --git a/csharp/ql/src/external/DuplicateMethodFix.cs b/csharp/ql/src/external/DuplicateMethodFix.cs deleted file mode 100644 index 5fb9864de99..00000000000 --- a/csharp/ql/src/external/DuplicateMethodFix.cs +++ /dev/null @@ -1,18 +0,0 @@ -class Container -{ - protected int x; - protected int y; - public void move(int x, int y) - { - this.x = x; - this.y = y; - } -} -class Toolbox : Container -{ - // ... -} -class Window : Container -{ - // ... -} diff --git a/csharp/ql/src/external/ExternalArtifact.qll b/csharp/ql/src/external/ExternalArtifact.qll deleted file mode 100644 index 15be44b15bd..00000000000 --- a/csharp/ql/src/external/ExternalArtifact.qll +++ /dev/null @@ -1,79 +0,0 @@ -import csharp - -class ExternalElement extends @external_element { - /** Gets a textual representation of this element. */ - string toString() { none() } - - /** Gets the location of this element. */ - Location getLocation() { none() } - - /** Gets the file containing this element. */ - File getFile() { result = getLocation().getFile() } -} - -class ExternalDefect extends ExternalElement, @externalDefect { - string getQueryPath() { - exists(string path | - externalDefects(this, path, _, _, _) and - result = path.replaceAll("\\", "/") - ) - } - - string getMessage() { externalDefects(this, _, _, result, _) } - - float getSeverity() { externalDefects(this, _, _, _, result) } - - override Location getLocation() { externalDefects(this, _, result, _, _) } - - override string toString() { - result = getQueryPath() + ": " + getLocation() + " - " + getMessage() - } -} - -class ExternalMetric extends ExternalElement, @externalMetric { - string getQueryPath() { externalMetrics(this, result, _, _) } - - float getValue() { externalMetrics(this, _, _, result) } - - override Location getLocation() { externalMetrics(this, _, result, _) } - - override string toString() { result = getQueryPath() + ": " + getLocation() + " - " + getValue() } -} - -class ExternalData extends ExternalElement, @externalDataElement { - string getDataPath() { externalData(this, result, _, _) } - - string getQueryPath() { result = getDataPath().regexpReplaceAll("\\.[^.]*$", ".ql") } - - int getNumFields() { result = 1 + max(int i | externalData(this, _, i, _) | i) } - - string getField(int index) { externalData(this, _, index, result) } - - int getFieldAsInt(int index) { result = getField(index).toInt() } - - float getFieldAsFloat(int index) { result = getField(index).toFloat() } - - date getFieldAsDate(int index) { result = getField(index).toDate() } - - override string toString() { result = getQueryPath() + ": " + buildTupleString(0) } - - private string buildTupleString(int start) { - start = getNumFields() - 1 and result = getField(start) - or - start < getNumFields() - 1 and result = getField(start) + "," + buildTupleString(start + 1) - } -} - -/** - * External data with a location, and a message, as produced by tools that used to produce QLDs. - */ -class DefectExternalData extends ExternalData { - DefectExternalData() { - this.getField(0).regexpMatch("\\w+://.*:[0-9]+:[0-9]+:[0-9]+:[0-9]+$") and - this.getNumFields() = 2 - } - - string getURL() { result = getField(0) } - - string getMessage() { result = getField(1) } -} diff --git a/csharp/ql/src/external/MetricFilter.qll b/csharp/ql/src/external/MetricFilter.qll deleted file mode 100644 index 6d7197662c0..00000000000 --- a/csharp/ql/src/external/MetricFilter.qll +++ /dev/null @@ -1,44 +0,0 @@ -import csharp - -external predicate metricResults( - int id, string queryPath, string file, int startline, int startcol, int endline, int endcol, - float value -); - -class MetricResult extends int { - MetricResult() { metricResults(this, _, _, _, _, _, _, _) } - - string getQueryPath() { metricResults(this, result, _, _, _, _, _, _) } - - File getFile() { - exists(string path | - metricResults(this, _, path, _, _, _, _, _) and result.getAbsolutePath() = path - ) - } - - int getStartLine() { metricResults(this, _, _, result, _, _, _, _) } - - int getStartColumn() { metricResults(this, _, _, _, result, _, _, _) } - - int getEndLine() { metricResults(this, _, _, _, _, result, _, _) } - - int getEndColumn() { metricResults(this, _, _, _, _, _, result, _) } - - predicate hasMatchingLocation() { exists(this.getMatchingLocation()) } - - Location getMatchingLocation() { - result.getFile() = this.getFile() and - result.getStartLine() = this.getStartLine() and - result.getEndLine() = this.getEndLine() and - result.getStartColumn() = this.getStartColumn() and - result.getEndColumn() = this.getEndColumn() - } - - float getValue() { metricResults(this, _, _, _, _, _, _, result) } - - string getURL() { - result = - "file://" + getFile().getAbsolutePath() + ":" + getStartLine() + ":" + getStartColumn() + ":" + - getEndLine() + ":" + getEndColumn() - } -} diff --git a/csharp/ql/src/external/MostlyDuplicateClass.qhelp b/csharp/ql/src/external/MostlyDuplicateClass.qhelp deleted file mode 100644 index 2e053657d0a..00000000000 --- a/csharp/ql/src/external/MostlyDuplicateClass.qhelp +++ /dev/null @@ -1,20 +0,0 @@ - - - -

    If two classes share a lot of each other's methods then there is a lot of unnecessary code duplication. -This makes it difficult to make changes in future and makes the code harder to read.

    - -
    - -

    If a duplicate class has been included by mistake then remove it. Otherwise consider making a common -superclass for both classes or even making one of the classes a superclass of the other.

    - -
    - - -
  • Elmar Juergens, Florian Deissenboeck, Benjamin Hummel and Stefan Wagner. Do Code Clones Matter?. 2009.
  • - -
    -
    diff --git a/csharp/ql/src/external/MostlyDuplicateClass.ql b/csharp/ql/src/external/MostlyDuplicateClass.ql deleted file mode 100644 index 7b7d5ef3eff..00000000000 --- a/csharp/ql/src/external/MostlyDuplicateClass.ql +++ /dev/null @@ -1,24 +0,0 @@ -/** - * @deprecated - * @name Duplicate class - * @description More than 80% of the methods in this class are duplicated in another class. Create a common supertype to improve code sharing. - * @kind problem - * @problem.severity recommendation - * @precision high - * @id cs/duplicate-class - * @tags testability - * maintainability - * useless-code - * duplicate-code - * statistical - * non-attributable - */ - -import csharp -import CodeDuplication - -from Class c, string message, Class link -where - mostlyDuplicateClass(c, link, message) and - not fileLevelDuplication(c.getFile(), _) -select c, message, link, link.getName() diff --git a/csharp/ql/src/external/MostlyDuplicateFile.qhelp b/csharp/ql/src/external/MostlyDuplicateFile.qhelp deleted file mode 100644 index 9cfe21f43cf..00000000000 --- a/csharp/ql/src/external/MostlyDuplicateFile.qhelp +++ /dev/null @@ -1,31 +0,0 @@ - - - -

    If two files share a lot of each other's code then there is a lot of unnecessary code duplication. -This makes it difficult to make changes in future and makes the code harder to read.

    - -
    - -

    While completely duplicated files are rare, they are usually a sign of a simple oversight. -Usually the required action is to remove all but one of them. A common exception to this rule may arise -from generated code that simply occurs in several places in the source tree; the check can be -adapted to exclude such results.

    - -

    It is far more common to see duplication of many lines between two files, leaving just a few that -are actually different. Consider such situations carefully. Are the differences deliberate or -a result of an inconsistent update to one of the clones? If the latter, then treating the files as -completely duplicate and eliminating one (while preserving any corrections or new features that -may have been introduced) is the best course. If two files serve genuinely different purposes but almost -all of their lines are the same, that can be a sign that there is a missing level of abstraction. Look -for ways to share the functionality, either by creating a utility class for the common parts or by -encapsulating the common parts into a new super class of any classes involved.

    - -
    - - -
  • Elmar Juergens, Florian Deissenboeck, Benjamin Hummel and Stefan Wagner. Do Code Clones Matter?. 2009.
  • - -
    -
    diff --git a/csharp/ql/src/external/MostlyDuplicateFile.ql b/csharp/ql/src/external/MostlyDuplicateFile.ql deleted file mode 100644 index 2dbc2e17ffb..00000000000 --- a/csharp/ql/src/external/MostlyDuplicateFile.ql +++ /dev/null @@ -1,23 +0,0 @@ -/** - * @deprecated - * @name Mostly duplicate file - * @description There is another file that shares a lot of the code with this file. Merge the two files to improve maintainability. - * @kind problem - * @problem.severity recommendation - * @precision high - * @id cs/duplicate-file - * @tags testability - * maintainability - * useless-code - * duplicate-code - * statistical - * non-attributable - */ - -import csharp -import CodeDuplication - -from File f, File other, int percent -where duplicateFiles(f, other, percent) -select f, percent + "% of the lines in " + f.getBaseName() + " are copies of lines in $@.", other, - other.getBaseName() diff --git a/csharp/ql/src/external/MostlyDuplicateMethod.qhelp b/csharp/ql/src/external/MostlyDuplicateMethod.qhelp deleted file mode 100644 index 8388520189d..00000000000 --- a/csharp/ql/src/external/MostlyDuplicateMethod.qhelp +++ /dev/null @@ -1,48 +0,0 @@ - - - - -

    When most of the lines in one method are duplicated in one or more other -methods, the methods themselves are regarded as mostly duplicate or similar.

    - -

    Code duplication in general is highly undesirable for a range of reasons. The artificially -inflated amount of code is more difficult to understand, and sequences of similar but subtly different lines -can mask the real purpose or intention behind them. Also, there is always a risk that only one -of several copies of the code is updated to address a defect or add a feature.

    - -
    - -

    Although completely duplicated methods are rare, they are usually a sign of a simple -oversight (or deliberate copy/paste) by a developer. Usually the required solution -is to remove all but one of them.

    - -

    It is more common to see duplication of many lines between two methods, leaving just -a few that are actually different. Decide whether the differences are -intended or the result of an inconsistent update to one of the copies.

    -
      -
    • If the two methods serve different purposes but many of their lines are duplicated, this indicates -that there is a missing level of abstraction. Look for ways of encapsulating the commonality and sharing it while -retaining the differences in functionality. Perhaps the method can be moved to a single place -and given an additional parameter, allowing it to cover all use cases. Alternatively, there -may be a common pre-processing or post-processing step that can be extracted to its own (shared) -method, leaving only the specific parts in the existing methods. Modern IDEs may provide -refactoring support for this sort of issue, usually with the names "Extract method", "Change method signature", -"Pull up" or "Extract supertype".
    • -
    • If the two methods serve the same purpose and are different only as a result of inconsistent updates -then treat the methods as completely duplicate. Determine -the most up-to-date and correct version of the code and eliminate all near duplicates. Callers of the -removed methods should be updated to call the remaining method instead.
    - -
    - - -
  • E. Juergens, F. Deissenboeck, B. Hummel, S. Wagner. -Do code clones matter? Proceedings of the 31st International Conference on -Software Engineering, -485-495, 2009.
  • - - -
    -
    diff --git a/csharp/ql/src/external/MostlyDuplicateMethod.ql b/csharp/ql/src/external/MostlyDuplicateMethod.ql deleted file mode 100644 index aa0003c113b..00000000000 --- a/csharp/ql/src/external/MostlyDuplicateMethod.ql +++ /dev/null @@ -1,30 +0,0 @@ -/** - * @deprecated - * @name Mostly duplicate method - * @description There is another method that shares a lot of the code with this method. Extract the code to a common superclass or delegate to improve sharing. - * @kind problem - * @problem.severity recommendation - * @precision high - * @id cs/similar-method - * @tags testability - * maintainability - * useless-code - * statistical - * non-attributable - */ - -import csharp -import CodeDuplication - -from Method m, int covered, int total, Method other, int percent -where - duplicateStatements(m, other, covered, total) and - covered != total and - m.getNumberOfLinesOfCode() > 5 and - covered * 100 / total = percent and - percent > 80 and - not duplicateMethod(m, other) and - not classLevelDuplication(m.getDeclaringType(), other.getDeclaringType()) and - not fileLevelDuplication(m.getFile(), other.getFile()) -select m, percent + "% of the statements in " + m.getName() + " are duplicated in $@.", other, - other.getDeclaringType().getName() + "." + other.getName() diff --git a/csharp/ql/src/external/MostlySimilarFile.qhelp b/csharp/ql/src/external/MostlySimilarFile.qhelp deleted file mode 100644 index f0fd64c99ad..00000000000 --- a/csharp/ql/src/external/MostlySimilarFile.qhelp +++ /dev/null @@ -1,24 +0,0 @@ - - - -

    This rule identifies two files that have a lot of the same lines but with different variable and method -names. This makes it difficult to make changes in future and makes the code harder to read.

    - -
    - -

    It is important to determine why there are small differences in the files. Sometimes the files might have -been duplicates but an update was only applied to one copy. If this is the case it should be simple to merge -the files, preserving any changes.

    - -

    If the files are intentionally different then it could be a good idea to consider extracting some of the -shared code into a superclass or a separate utility class.

    - -
    - - -
  • Elmar Juergens, Florian Deissenboeck, Benjamin Hummel and Stefan Wagner. Do Code Clones Matter?. 2009.
  • - -
    -
    diff --git a/csharp/ql/src/external/MostlySimilarFile.ql b/csharp/ql/src/external/MostlySimilarFile.ql deleted file mode 100644 index a66df834aca..00000000000 --- a/csharp/ql/src/external/MostlySimilarFile.ql +++ /dev/null @@ -1,31 +0,0 @@ -/** - * @deprecated - * @name Mostly similar file - * @description There is another file that shares a lot of the code with this file. Notice that names of variables and types may have been changed. Merge the two files to improve maintainability. - * @kind problem - * @problem.severity recommendation - * @precision high - * @id cs/similar-file - * @tags testability - * maintainability - * useless-code - * duplicate-code - * statistical - * non-attributable - */ - -import csharp -import CodeDuplication - -predicate irrelevant(File f) { - f.getStem() = "AssemblyInfo" or - f.getStem().matches("%.Designer") -} - -from File f, File other, int percent -where - similarFiles(f, other, percent) and - not irrelevant(f) and - not irrelevant(other) -select f, percent + "% of the lines in " + f.getBaseName() + " are similar to lines in $@.", other, - other.getBaseName() diff --git a/csharp/ql/src/filters/ChangedLines.ql b/csharp/ql/src/filters/ChangedLines.ql deleted file mode 100644 index f97e60d4faf..00000000000 --- a/csharp/ql/src/filters/ChangedLines.ql +++ /dev/null @@ -1,20 +0,0 @@ -/** - * @name Filter: only keep results from source that have been changed since the base line - * @description Exclude results that have not changed since the base line. - * @id cs/changed-lines-filter - * @kind problem - */ - -import csharp -import external.ExternalArtifact -import external.DefectFilter -import ChangedLines - -from DefectResult res -where - changedLine(res.getFile(), res.getStartLine()) - or - changedLine(res.getFile(), res.getEndLine()) - or - res.getStartLine() = 0 and changedLine(res.getFile(), _) -select res, res.getMessage() diff --git a/csharp/ql/src/filters/ChangedLines.qll b/csharp/ql/src/filters/ChangedLines.qll deleted file mode 100644 index 75628dab020..00000000000 --- a/csharp/ql/src/filters/ChangedLines.qll +++ /dev/null @@ -1,12 +0,0 @@ -import csharp -import external.ExternalArtifact - -pragma[noopt] -predicate changedLine(File f, int line) { - exists(ExternalMetric metric, Location l | - exists(string s | s = "changedLines.ql" and metric.getQueryPath() = s) and - l = metric.getLocation() and - f = l.getFile() and - line = l.getStartLine() - ) -} diff --git a/csharp/ql/src/filters/ChangedLinesForMetric.ql b/csharp/ql/src/filters/ChangedLinesForMetric.ql deleted file mode 100644 index d04cc681a37..00000000000 --- a/csharp/ql/src/filters/ChangedLinesForMetric.ql +++ /dev/null @@ -1,15 +0,0 @@ -/** - * @name Filter: only keep results from source that have been changed since the base line - * @description Exclude results that have not changed since the base line. - * @id cs/changed-lines-metric-filter - * @kind treemap - */ - -import csharp -import external.ExternalArtifact -import external.MetricFilter -import ChangedLines - -from MetricResult res -where changedLine(res.getFile(), _) -select res, res.getValue() diff --git a/csharp/ql/src/filters/ClassifyFiles.ql b/csharp/ql/src/filters/ClassifyFiles.ql index 4277e321a1c..23b0994dcfa 100644 --- a/csharp/ql/src/filters/ClassifyFiles.ql +++ b/csharp/ql/src/filters/ClassifyFiles.ql @@ -2,6 +2,8 @@ * @name Classify files * @description This query produces a list of all files in a snapshot * that are classified as generated code or test code. + * + * Used by LGTM. * @kind file-classifier * @id cs/file-classifier */ diff --git a/csharp/ql/src/filters/FromSource.ql b/csharp/ql/src/filters/FromSource.ql deleted file mode 100644 index e19785afad9..00000000000 --- a/csharp/ql/src/filters/FromSource.ql +++ /dev/null @@ -1,13 +0,0 @@ -/** - * @name Filter: only keep results from source - * @description Exclude results that do not come from source code files. - * @kind problem - * @id cs/source-filter - */ - -import csharp -import external.DefectFilter - -from DefectResult res -where res.getFile().fromSource() -select res, res.getMessage() diff --git a/csharp/ql/src/filters/FromSourceForMetric.ql b/csharp/ql/src/filters/FromSourceForMetric.ql deleted file mode 100644 index 49e1d4a2f3c..00000000000 --- a/csharp/ql/src/filters/FromSourceForMetric.ql +++ /dev/null @@ -1,13 +0,0 @@ -/** - * @name Filter: only keep metric results from source - * @description Exclude results that do not come from source code files. - * @kind treemap - * @id cs/source-metric-filter - */ - -import csharp -import external.MetricFilter - -from MetricResult res -where res.getFile().fromSource() -select res, res.getValue() diff --git a/csharp/ql/src/filters/NotGenerated.ql b/csharp/ql/src/filters/NotGenerated.ql deleted file mode 100644 index 5e80ffe8e2e..00000000000 --- a/csharp/ql/src/filters/NotGenerated.ql +++ /dev/null @@ -1,13 +0,0 @@ -/** - * @name Filter: only keep results in non-generated files - * @description Exclude results that come from generated code. - * @kind problem - * @id cs/not-generated-file-filter - */ - -import semmle.code.csharp.commons.GeneratedCode -import external.DefectFilter - -from DefectResult res -where not isGeneratedCode(res.getFile()) -select res, res.getMessage() diff --git a/csharp/ql/src/filters/NotGeneratedForMetric.ql b/csharp/ql/src/filters/NotGeneratedForMetric.ql deleted file mode 100644 index ca6e7f8080f..00000000000 --- a/csharp/ql/src/filters/NotGeneratedForMetric.ql +++ /dev/null @@ -1,13 +0,0 @@ -/** - * @name Filter: only keep metric results in non-generated files - * @description Exclude results that come from generated code. - * @kind treemap - * @id cs/not-generated-file-metric-filter - */ - -import semmle.code.csharp.commons.GeneratedCode -import external.MetricFilter - -from MetricResult res -where not isGeneratedCode(res.getFile()) -select res, res.getValue() diff --git a/csharp/ql/src/filters/NotInTestFile.ql b/csharp/ql/src/filters/NotInTestFile.ql deleted file mode 100644 index 041163ef946..00000000000 --- a/csharp/ql/src/filters/NotInTestFile.ql +++ /dev/null @@ -1,14 +0,0 @@ -/** - * @name Filter: only keep results that are outside of test files - * @description Exclude results in test files. - * @kind problem - * @id cs/test-file-filter - */ - -import csharp -import semmle.code.csharp.frameworks.Test -import external.DefectFilter - -from DefectResult res -where not res.getFile() instanceof TestFile -select res, res.getMessage() diff --git a/csharp/ql/src/filters/NotInTestFileForMetric.ql b/csharp/ql/src/filters/NotInTestFileForMetric.ql deleted file mode 100644 index 47b8e71253f..00000000000 --- a/csharp/ql/src/filters/NotInTestFileForMetric.ql +++ /dev/null @@ -1,14 +0,0 @@ -/** - * @name Filter: only keep results that are outside of test files - * @description Exclude results in test files. - * @kind treemap - * @id cs/test-file-metric-filter - */ - -import csharp -import semmle.code.csharp.frameworks.Test -import external.MetricFilter - -from MetricResult res -where not res.getFile() instanceof TestFile -select res, res.getValue() diff --git a/csharp/ql/src/filters/NotInTestMethod.ql b/csharp/ql/src/filters/NotInTestMethod.ql deleted file mode 100644 index 2981b891380..00000000000 --- a/csharp/ql/src/filters/NotInTestMethod.ql +++ /dev/null @@ -1,17 +0,0 @@ -/** - * @name Filter: only keep results that are outside of test methods - * @description Exclude results in test methods. - * @kind problem - * @id cs/test-method-filter - */ - -import csharp -import semmle.code.csharp.frameworks.Test -import external.DefectFilter - -from DefectResult res -where - not res.getFile() instanceof TestFile - or - not res.getStartLine() = res.getFile().(TestFile).lineInTestMethod() -select res, res.getMessage() diff --git a/csharp/ql/src/filters/NotInTestMethodExpectingException.ql b/csharp/ql/src/filters/NotInTestMethodExpectingException.ql deleted file mode 100644 index f4879211484..00000000000 --- a/csharp/ql/src/filters/NotInTestMethodExpectingException.ql +++ /dev/null @@ -1,24 +0,0 @@ -/** - * @name Filter: only keep results that are outside of a test method expecting an exception - * @description Exclude results in test methods expecting exceptions. - * @kind problem - * @id cs/test-method-exception-filter - */ - -import csharp -import semmle.code.csharp.frameworks.Test -import external.DefectFilter - -predicate ignoredLine(File f, int line) { - exists(TestMethod m | m.expectsException() | - f = m.getFile() and - line in [m.getLocation().getStartLine() .. m.getBody().getLocation().getEndLine()] - ) -} - -from DefectResult res -where - not res.getFile() instanceof TestFile - or - not ignoredLine(res.getFile(), res.getStartLine()) -select res, res.getMessage() diff --git a/csharp/ql/src/filters/UnchangedLines.ql b/csharp/ql/src/filters/UnchangedLines.ql deleted file mode 100644 index 89d43ac2561..00000000000 --- a/csharp/ql/src/filters/UnchangedLines.ql +++ /dev/null @@ -1,22 +0,0 @@ -/** - * @name Filter: only keep results from source that have not changed since the base line - * @description Complement of ChangedLines.ql. - * @kind problem - * @id cs/unchanged-lines-filter - */ - -import csharp -import external.ExternalArtifact -import external.DefectFilter -import ChangedLines - -from DefectResult res -where - not ( - changedLine(res.getFile(), res.getStartLine()) - or - changedLine(res.getFile(), res.getEndLine()) - or - res.getStartLine() = 0 and changedLine(res.getFile(), _) - ) -select res, res.getMessage() diff --git a/csharp/ql/src/filters/UnchangedLinesForMetric.ql b/csharp/ql/src/filters/UnchangedLinesForMetric.ql deleted file mode 100644 index b31b4cb5d56..00000000000 --- a/csharp/ql/src/filters/UnchangedLinesForMetric.ql +++ /dev/null @@ -1,15 +0,0 @@ -/** - * @name Filter: only keep results from source that have not changed since the base line - * @description Complement of ChangedLinesForMetric.ql. - * @kind treemap - * @id cs/unchanged-lines-metric-filter - */ - -import csharp -import external.ExternalArtifact -import external.MetricFilter -import ChangedLines - -from MetricResult res -where not changedLine(res.getFile(), _) -select res, res.getValue() diff --git a/csharp/ql/src/semmle/code/cil/BasicBlock.qll b/csharp/ql/src/semmle/code/cil/BasicBlock.qll index 459bb667e6f..0c9c0b8ad07 100644 --- a/csharp/ql/src/semmle/code/cil/BasicBlock.qll +++ b/csharp/ql/src/semmle/code/cil/BasicBlock.qll @@ -240,6 +240,9 @@ class BasicBlock extends Cached::TBasicBlockStart { /** Gets a textual representation of this basic block. */ string toString() { result = getFirstNode().toString() } + + /** Gets the location of this basic block. */ + Location getLocation() { result = this.getFirstNode().getLocation() } } /** @@ -305,7 +308,7 @@ class EntryBasicBlock extends BasicBlock { } /** Holds if `bb` is an entry basic block. */ -private predicate entryBB(BasicBlock bb) { bb.getFirstNode() instanceof EntryPoint } +private predicate entryBB(BasicBlock bb) { bb.getFirstNode() instanceof MethodImplementation } /** * An exit basic block, that is, a basic block whose last node is diff --git a/csharp/ql/src/semmle/code/cil/CIL.qll b/csharp/ql/src/semmle/code/cil/CIL.qll index 1e77d98fd29..db0018d8216 100644 --- a/csharp/ql/src/semmle/code/cil/CIL.qll +++ b/csharp/ql/src/semmle/code/cil/CIL.qll @@ -20,3 +20,4 @@ import Attribute import Stubs import CustomModifierReceiver import Parameterizable +import semmle.code.cil.Ssa diff --git a/csharp/ql/src/semmle/code/cil/CallableReturns.qll b/csharp/ql/src/semmle/code/cil/CallableReturns.qll index ee60713b801..8b029d87dd4 100644 --- a/csharp/ql/src/semmle/code/cil/CallableReturns.qll +++ b/csharp/ql/src/semmle/code/cil/CallableReturns.qll @@ -42,7 +42,11 @@ private predicate alwaysNullExpr(Expr expr) { or alwaysNullMethod(expr.(StaticCall).getTarget()) or - forex(VariableUpdate vu | DefUse::variableUpdateUse(_, vu, expr) | alwaysNullVariableUpdate(vu)) + forex(Ssa::Definition def | + expr = any(Ssa::Definition def0 | def = def0.getAnUltimateDefinition()).getARead() + | + alwaysNullVariableUpdate(def.getVariableUpdate()) + ) } pragma[noinline] @@ -58,7 +62,9 @@ private predicate alwaysNotNullExpr(Expr expr) { or alwaysNotNullMethod(expr.(StaticCall).getTarget()) or - forex(VariableUpdate vu | DefUse::variableUpdateUse(_, vu, expr) | - alwaysNotNullVariableUpdate(vu) + forex(Ssa::Definition def | + expr = any(Ssa::Definition def0 | def = def0.getAnUltimateDefinition()).getARead() + | + alwaysNotNullVariableUpdate(def.getVariableUpdate()) ) } diff --git a/csharp/ql/src/semmle/code/cil/ControlFlow.qll b/csharp/ql/src/semmle/code/cil/ControlFlow.qll index 176df2a20dc..52a2ddc3376 100644 --- a/csharp/ql/src/semmle/code/cil/ControlFlow.qll +++ b/csharp/ql/src/semmle/code/cil/ControlFlow.qll @@ -9,6 +9,9 @@ class ControlFlowNode extends @cil_controlflow_node { /** Gets a textual representation of this control flow node. */ string toString() { none() } + /** Gets the location of this control flow node. */ + Location getLocation() { none() } + /** * Gets the number of items this node pushes onto the stack. * This value is either 0 or 1, except for the instruction `dup` diff --git a/csharp/ql/src/semmle/code/cil/DataFlow.qll b/csharp/ql/src/semmle/code/cil/DataFlow.qll index 6991658ea3a..d62ee739369 100644 --- a/csharp/ql/src/semmle/code/cil/DataFlow.qll +++ b/csharp/ql/src/semmle/code/cil/DataFlow.qll @@ -57,12 +57,40 @@ class Untainted extends TaintType, TExactValue { } /** A taint type where the data is tainted. */ class Tainted extends TaintType, TTaintedValue { } +private predicate localFlowPhiInput(DataFlowNode input, Ssa::PhiNode phi) { + exists(Ssa::Definition def, BasicBlock bb, int i | phi.hasLastInputRef(def, bb, i) | + def.definesAt(_, bb, i) and + input = def.getVariableUpdate().getSource() + or + input = + any(ReadAccess ra | + bb.getNode(i) = ra and + ra.getTarget() = def.getSourceVariable() + ) + ) + or + exists(Ssa::PhiNode mid, BasicBlock bb, int i | + localFlowPhiInput(input, mid) and + phi.hasLastInputRef(mid, bb, i) and + mid.definesAt(_, bb, i) + ) +} + private predicate localExactStep(DataFlowNode src, DataFlowNode sink) { src = sink.(Opcodes::Dup).getAnOperand() or - defUse(_, src, sink) + exists(Ssa::Definition def, VariableUpdate vu | + vu = def.getVariableUpdate() and + src = vu.getSource() and + sink = def.getAFirstRead() + ) or - src = sink.(ParameterReadAccess).getTarget() + any(Ssa::Definition def).hasAdjacentReads(src, sink) + or + exists(Ssa::PhiNode phi | + localFlowPhiInput(src, phi) and + sink = phi.getAFirstRead() + ) or src = sink.(Conversion).getExpr() or @@ -73,12 +101,6 @@ private predicate localExactStep(DataFlowNode src, DataFlowNode sink) { src = sink.(Return).getExpr() or src = sink.(ConditionalBranch).getAnOperand() - or - src = sink.(MethodParameter).getAWrite() - or - exists(VariableUpdate update | - update.getVariable().(Parameter) = sink and src = update.getSource() - ) } private predicate localTaintStep(DataFlowNode src, DataFlowNode sink) { @@ -87,8 +109,7 @@ private predicate localTaintStep(DataFlowNode src, DataFlowNode sink) { src = sink.(UnaryBitwiseOperation).getOperand() } -cached -module DefUse { +deprecated module DefUse { /** * A classification of variable references into reads and writes. */ @@ -189,7 +210,7 @@ module DefUse { /** Holds if the variable update `vu` can be used at the read `use`. */ cached - predicate variableUpdateUse(StackVariable target, VariableUpdate vu, ReadAccess use) { + deprecated predicate variableUpdateUse(StackVariable target, VariableUpdate vu, ReadAccess use) { defReachesReadWithinBlock(target, vu, use) or exists(BasicBlock bb, int i | @@ -202,23 +223,40 @@ module DefUse { /** Holds if the update `def` can be used at the read `use`. */ cached - predicate defUse(StackVariable target, Expr def, ReadAccess use) { + deprecated predicate defUse(StackVariable target, Expr def, ReadAccess use) { exists(VariableUpdate vu | def = vu.getSource() | variableUpdateUse(target, vu, use)) } } -private import DefUse - -abstract library class VariableUpdate extends Instruction { - abstract Expr getSource(); +/** A node that updates a variable. */ +abstract class VariableUpdate extends DataFlowNode { + /** Gets the value assigned, if any. */ + abstract DataFlowNode getSource(); + /** Gets the variable that is updated. */ abstract Variable getVariable(); + + /** Holds if this variable update happens at index `i` in basic block `bb`. */ + abstract predicate updatesAt(BasicBlock bb, int i); +} + +private class MethodParameterDef extends VariableUpdate, MethodParameter { + override MethodParameter getSource() { result = this } + + override MethodParameter getVariable() { result = this } + + override predicate updatesAt(BasicBlock bb, int i) { + bb.(EntryBasicBlock).getANode().getImplementation().getMethod() = this.getMethod() and + i = -1 + } } private class VariableWrite extends VariableUpdate, WriteAccess { - override Expr getSource() { result = getExpr() } + override Expr getSource() { result = this.getExpr() } - override Variable getVariable() { result = getTarget() } + override Variable getVariable() { result = this.getTarget() } + + override predicate updatesAt(BasicBlock bb, int i) { this = bb.getNode(i) } } private class MethodOutOrRefTarget extends VariableUpdate, Call { @@ -230,5 +268,7 @@ private class MethodOutOrRefTarget extends VariableUpdate, Call { result = this.getRawArgument(parameterIndex).(ReadAccess).getTarget() } - override Expr getSource() { result = this } + override Expr getSource() { none() } + + override predicate updatesAt(BasicBlock bb, int i) { this = bb.getNode(i) } } diff --git a/csharp/ql/src/semmle/code/cil/Method.qll b/csharp/ql/src/semmle/code/cil/Method.qll index 5ef282e582a..8da707cb423 100644 --- a/csharp/ql/src/semmle/code/cil/Method.qll +++ b/csharp/ql/src/semmle/code/cil/Method.qll @@ -19,7 +19,7 @@ class MethodImplementation extends EntryPoint, @cil_method_implementation { override MethodImplementation getImplementation() { result = this } /** Gets the location of this implementation. */ - Assembly getLocation() { cil_method_implementation(this, _, result) } + override Assembly getLocation() { cil_method_implementation(this, _, result) } /** Gets the instruction at index `index`. */ Instruction getInstruction(int index) { cil_instruction(result, _, index, this) } diff --git a/csharp/ql/src/semmle/code/cil/Ssa.qll b/csharp/ql/src/semmle/code/cil/Ssa.qll new file mode 100644 index 00000000000..229925f6d08 --- /dev/null +++ b/csharp/ql/src/semmle/code/cil/Ssa.qll @@ -0,0 +1,66 @@ +/** + * Provides the module `Ssa` for working with static single assignment (SSA) form. + */ + +private import CIL + +/** + * Provides classes for working with static single assignment (SSA) form. + */ +module Ssa { + private import internal.SsaImplCommon as SsaImpl + private import internal.SsaImpl + + /** An SSA definition. */ + class Definition extends SsaImpl::Definition { + /** Gets a read of this SSA definition. */ + final ReadAccess getARead() { result = getARead(this) } + + /** Gets the underlying variable update, if any. */ + final VariableUpdate getVariableUpdate() { + exists(BasicBlock bb, int i | + result.updatesAt(bb, i) and + this.definesAt(result.getVariable(), bb, i) + ) + } + + /** Gets a first read of this SSA definition. */ + final ReadAccess getAFirstRead() { result = getAFirstRead(this) } + + /** Holds if `first` and `second` are adjacent reads of this SSA definition. */ + final predicate hasAdjacentReads(ReadAccess first, ReadAccess second) { + hasAdjacentReads(this, first, second) + } + + private Definition getAPhiInput() { result = this.(PhiNode).getAnInput() } + + /** + * Gets a definition that ultimately defines this SSA definition and is + * not itself a phi node. + */ + final Definition getAnUltimateDefinition() { + result = this.getAPhiInput*() and + not result instanceof PhiNode + } + + /** Gets the location of this SSA definition. */ + Location getLocation() { result = this.getVariableUpdate().getLocation() } + } + + /** A phi node. */ + class PhiNode extends SsaImpl::PhiNode, Definition { + final override Location getLocation() { result = this.getBasicBlock().getLocation() } + + /** Gets an input to this phi node. */ + final Definition getAnInput() { result = getAPhiInput(this) } + + /** + * Holds if if `def` is an input to this phi node, and a reference to `def` at + * index `i` in basic block `bb` can reach this phi node without going through + * other references. + */ + final predicate hasLastInputRef(Definition def, BasicBlock bb, int i) { + hasLastInputRef(this, def, bb, i) + } + } +} diff --git a/csharp/ql/src/semmle/code/cil/internal/SsaImpl.qll b/csharp/ql/src/semmle/code/cil/internal/SsaImpl.qll new file mode 100644 index 00000000000..593c877b9af --- /dev/null +++ b/csharp/ql/src/semmle/code/cil/internal/SsaImpl.qll @@ -0,0 +1,45 @@ +private import semmle.code.cil.CIL +private import SsaImplCommon + +cached +private module Cached { + cached + predicate forceCachingInSameStage() { any() } + + cached + ReadAccess getARead(Definition def) { + exists(BasicBlock bb, int i | + ssaDefReachesRead(_, def, bb, i) and + result = bb.getNode(i) + ) + } + + cached + ReadAccess getAFirstRead(Definition def) { + exists(BasicBlock bb1, int i1, BasicBlock bb2, int i2 | + def.definesAt(_, bb1, i1) and + adjacentDefRead(def, bb1, i1, bb2, i2) and + result = bb2.getNode(i2) + ) + } + + cached + predicate hasAdjacentReads(Definition def, ReadAccess first, ReadAccess second) { + exists(BasicBlock bb1, int i1, BasicBlock bb2, int i2 | + first = bb1.getNode(i1) and + adjacentDefRead(def, bb1, i1, bb2, i2) and + second = bb2.getNode(i2) + ) + } + + cached + Definition getAPhiInput(PhiNode phi) { phiHasInputFromBlock(phi, result, _) } + + cached + predicate hasLastInputRef(Definition phi, Definition def, BasicBlock bb, int i) { + lastRefRedef(def, bb, i, phi) and + def = getAPhiInput(phi) + } +} + +import Cached diff --git a/csharp/ql/src/semmle/code/cil/internal/SsaImplCommon.qll b/csharp/ql/src/semmle/code/cil/internal/SsaImplCommon.qll new file mode 100644 index 00000000000..f828419a440 --- /dev/null +++ b/csharp/ql/src/semmle/code/cil/internal/SsaImplCommon.qll @@ -0,0 +1,620 @@ +/** + * Provides a language-independent implementation of static single assignment + * (SSA) form. + */ + +private import SsaImplSpecific + +private BasicBlock getABasicBlockPredecessor(BasicBlock bb) { getABasicBlockSuccessor(result) = bb } + +/** + * Liveness analysis (based on source variables) to restrict the size of the + * SSA representation. + */ +private module Liveness { + /** + * A classification of variable references into reads (of a given kind) and + * (certain or uncertain) writes. + */ + private newtype TRefKind = + Read(boolean certain) { certain in [false, true] } or + Write(boolean certain) { certain in [false, true] } + + private class RefKind extends TRefKind { + string toString() { + exists(boolean certain | this = Read(certain) and result = "read (" + certain + ")") + or + exists(boolean certain | this = Write(certain) and result = "write (" + certain + ")") + } + + int getOrder() { + this = Read(_) and + result = 0 + or + this = Write(_) and + result = 1 + } + } + + /** + * Holds if the `i`th node of basic block `bb` is a reference to `v` of kind `k`. + */ + private predicate ref(BasicBlock bb, int i, SourceVariable v, RefKind k) { + exists(boolean certain | variableRead(bb, i, v, certain) | k = Read(certain)) + or + exists(boolean certain | variableWrite(bb, i, v, certain) | k = Write(certain)) + } + + private newtype OrderedRefIndex = + MkOrderedRefIndex(int i, int tag) { + exists(RefKind rk | ref(_, i, _, rk) | tag = rk.getOrder()) + } + + private OrderedRefIndex refOrd(BasicBlock bb, int i, SourceVariable v, RefKind k, int ord) { + ref(bb, i, v, k) and + result = MkOrderedRefIndex(i, ord) and + ord = k.getOrder() + } + + /** + * 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 `k`. + * + * Reads are considered before writes when they happen at the same index. + */ + private int refRank(BasicBlock bb, int i, SourceVariable v, RefKind k) { + refOrd(bb, i, v, k, _) = + rank[result](int j, int ord, OrderedRefIndex res | + res = refOrd(bb, j, v, _, ord) + | + res order by j, ord + ) + } + + private int maxRefRank(BasicBlock bb, SourceVariable v) { + result = refRank(bb, _, v, _) and + not result + 1 = refRank(bb, _, v, _) + } + + /** + * Gets the (1-based) rank of the first reference to `v` inside basic block `bb` + * that is either a read or a certain write. + */ + private int firstReadOrCertainWrite(BasicBlock bb, SourceVariable v) { + result = + min(int r, RefKind k | + r = refRank(bb, _, v, k) and + k != Write(false) + | + r + ) + } + + /** + * Holds if source variable `v` is live at the beginning of basic block `bb`. + */ + predicate liveAtEntry(BasicBlock bb, SourceVariable v) { + // The first read or certain write to `v` inside `bb` is a read + refRank(bb, _, v, Read(_)) = firstReadOrCertainWrite(bb, v) + or + // There is no certain write to `v` inside `bb`, but `v` is live at entry + // to a successor basic block of `bb` + not exists(firstReadOrCertainWrite(bb, v)) and + liveAtExit(bb, v) + } + + /** + * Holds if source variable `v` is live at the end of basic block `bb`. + */ + predicate liveAtExit(BasicBlock bb, SourceVariable v) { + liveAtEntry(getABasicBlockSuccessor(bb), v) + } + + /** + * Holds if variable `v` is live in basic block `bb` at index `i`. + * The rank of `i` is `rnk` as defined by `refRank()`. + */ + private predicate liveAtRank(BasicBlock bb, int i, SourceVariable v, int rnk) { + exists(RefKind kind | rnk = refRank(bb, i, v, kind) | + rnk = maxRefRank(bb, v) and + liveAtExit(bb, v) + or + ref(bb, i, v, kind) and + kind = Read(_) + or + exists(RefKind nextKind | + liveAtRank(bb, _, v, rnk + 1) and + rnk + 1 = refRank(bb, _, v, nextKind) and + nextKind != Write(true) + ) + ) + } + + /** + * Holds if variable `v` is live after the (certain or uncertain) write at + * index `i` inside basic block `bb`. + */ + predicate liveAfterWrite(BasicBlock bb, int i, SourceVariable v) { + exists(int rnk | rnk = refRank(bb, i, v, Write(_)) | liveAtRank(bb, i, v, rnk)) + } +} + +private import Liveness + +/** Holds if `bb1` strictly dominates `bb2`. */ +private predicate strictlyDominates(BasicBlock bb1, BasicBlock bb2) { + bb1 = getImmediateBasicBlockDominator+(bb2) +} + +/** Holds if `bb1` dominates a predecessor of `bb2`. */ +private predicate dominatesPredecessor(BasicBlock bb1, BasicBlock bb2) { + exists(BasicBlock pred | pred = getABasicBlockPredecessor(bb2) | + bb1 = pred + or + strictlyDominates(bb1, pred) + ) +} + +/** Holds if `df` is in the dominance frontier of `bb`. */ +private predicate inDominanceFrontier(BasicBlock bb, BasicBlock df) { + dominatesPredecessor(bb, df) and + not strictlyDominates(bb, df) +} + +/** + * Holds if `bb` is in the dominance frontier of a block containing a + * definition of `v`. + */ +pragma[noinline] +private predicate inDefDominanceFrontier(BasicBlock bb, SourceVariable v) { + exists(BasicBlock defbb, Definition def | + def.definesAt(v, defbb, _) and + inDominanceFrontier(defbb, bb) + ) +} + +cached +newtype TDefinition = + TWriteDef(SourceVariable v, BasicBlock bb, int i) { + variableWrite(bb, i, v, _) and + liveAfterWrite(bb, i, v) + } or + TPhiNode(SourceVariable v, BasicBlock bb) { + inDefDominanceFrontier(bb, v) and + liveAtEntry(bb, v) + } + +private module SsaDefReaches { + newtype TSsaRefKind = + SsaRead() or + SsaDef() + + /** + * A classification of SSA variable references into reads and definitions. + */ + class SsaRefKind extends TSsaRefKind { + string toString() { + this = SsaRead() and + result = "SsaRead" + or + this = SsaDef() and + result = "SsaDef" + } + + int getOrder() { + this = SsaRead() and + result = 0 + or + this = SsaDef() and + result = 1 + } + } + + /** + * Holds if the `i`th node of basic block `bb` is a reference to `v`, + * either a read (when `k` is `SsaRead()`) or an SSA definition (when `k` + * is `SsaDef()`). + * + * Unlike `Liveness::ref`, this includes `phi` nodes. + */ + predicate ssaRef(BasicBlock bb, int i, SourceVariable v, SsaRefKind k) { + variableRead(bb, i, v, _) and + k = SsaRead() + or + exists(Definition def | def.definesAt(v, bb, i)) and + k = SsaDef() + } + + private newtype OrderedSsaRefIndex = + MkOrderedSsaRefIndex(int i, SsaRefKind k) { ssaRef(_, i, _, k) } + + private OrderedSsaRefIndex ssaRefOrd(BasicBlock bb, int i, SourceVariable v, SsaRefKind k, int ord) { + ssaRef(bb, i, v, k) and + result = MkOrderedSsaRefIndex(i, k) and + ord = k.getOrder() + } + + /** + * 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 `k`. + * + * For example, if `bb` is a basic block with a phi node for `v` (considered + * to be at index -1), reads `v` at node 2, and defines it at node 5, we have: + * + * ```ql + * ssaRefRank(bb, -1, v, SsaDef()) = 1 // phi node + * ssaRefRank(bb, 2, v, Read()) = 2 // read at node 2 + * ssaRefRank(bb, 5, v, SsaDef()) = 3 // definition at node 5 + * ``` + * + * Reads are considered before writes when they happen at the same index. + */ + int ssaRefRank(BasicBlock bb, int i, SourceVariable v, SsaRefKind k) { + ssaRefOrd(bb, i, v, k, _) = + rank[result](int j, int ord, OrderedSsaRefIndex res | + res = ssaRefOrd(bb, j, v, _, ord) + | + res order by j, ord + ) + } + + int maxSsaRefRank(BasicBlock bb, SourceVariable v) { + result = ssaRefRank(bb, _, v, _) and + not result + 1 = ssaRefRank(bb, _, v, _) + } + + /** + * Holds if the SSA definition `def` reaches rank index `rnk` in its own + * basic block `bb`. + */ + predicate ssaDefReachesRank(BasicBlock bb, Definition def, int rnk, SourceVariable v) { + exists(int i | + rnk = ssaRefRank(bb, i, v, SsaDef()) and + def.definesAt(v, bb, i) + ) + or + ssaDefReachesRank(bb, def, rnk - 1, v) and + rnk = ssaRefRank(bb, _, v, SsaRead()) + } + + /** + * Holds if the SSA definition of `v` at `def` reaches index `i` in the same + * basic block `bb`, without crossing another SSA definition of `v`. + */ + predicate ssaDefReachesReadWithinBlock(SourceVariable v, Definition def, BasicBlock bb, int i) { + exists(int rnk | + ssaDefReachesRank(bb, def, rnk, v) and + rnk = ssaRefRank(bb, i, v, SsaRead()) and + variableRead(bb, i, v, _) + ) + } + + /** + * Holds if the SSA definition of `v` at `def` reaches uncertain SSA definition + * `redef` in the same basic block, without crossing another SSA definition of `v`. + */ + predicate ssaDefReachesUncertainDefWithinBlock( + SourceVariable v, Definition def, UncertainWriteDefinition redef + ) { + exists(BasicBlock bb, int rnk, int i | + ssaDefReachesRank(bb, def, rnk, v) and + rnk = ssaRefRank(bb, i, v, SsaDef()) - 1 and + redef.definesAt(v, bb, i) + ) + } + + /** + * Same as `ssaRefRank()`, but restricted to a particular SSA definition `def`. + */ + int ssaDefRank(Definition def, SourceVariable v, BasicBlock bb, int i, SsaRefKind k) { + v = def.getSourceVariable() and + result = ssaRefRank(bb, i, v, k) and + ( + ssaDefReachesRead(_, def, bb, i) + or + def.definesAt(_, bb, i) + ) + } + + predicate defOccursInBlock(Definition def, BasicBlock bb, SourceVariable v) { + exists(ssaDefRank(def, v, bb, _, _)) + } + + pragma[noinline] + private predicate ssaDefReachesThroughBlock(Definition def, BasicBlock bb) { + ssaDefReachesEndOfBlock(bb, def, _) and + not defOccursInBlock(_, bb, def.getSourceVariable()) + } + + /** + * Holds if `def` is accessed in basic block `bb1` (either a read or a write), + * `bb2` is a transitive successor of `bb1`, `def` is live at the end of `bb1`, + * and the underlying variable for `def` is neither read nor written in any block + * on the path between `bb1` and `bb2`. + */ + predicate varBlockReaches(Definition def, BasicBlock bb1, BasicBlock bb2) { + defOccursInBlock(def, bb1, _) and + bb2 = getABasicBlockSuccessor(bb1) + or + exists(BasicBlock mid | + varBlockReaches(def, bb1, mid) and + ssaDefReachesThroughBlock(def, mid) and + bb2 = getABasicBlockSuccessor(mid) + ) + } + + /** + * Holds if `def` is accessed in basic block `bb1` (either a read or a write), + * `def` is read at index `i2` in basic block `bb2`, `bb2` is in a transitive + * successor block of `bb1`, and `def` is neither read nor written in any block + * on a path between `bb1` and `bb2`. + */ + predicate defAdjacentRead(Definition def, BasicBlock bb1, BasicBlock bb2, int i2) { + varBlockReaches(def, bb1, bb2) and + ssaRefRank(bb2, i2, def.getSourceVariable(), SsaRead()) = 1 and + variableRead(bb2, i2, _, _) + } +} + +private import SsaDefReaches + +pragma[nomagic] +predicate liveThrough(BasicBlock bb, SourceVariable v) { + liveAtExit(bb, v) and + not ssaRef(bb, _, v, SsaDef()) +} + +/** + * NB: If this predicate is exposed, it should be cached. + * + * Holds if the SSA definition of `v` at `def` reaches the end of basic + * block `bb`, at which point it is still live, without crossing another + * SSA definition of `v`. + */ +pragma[nomagic] +predicate ssaDefReachesEndOfBlock(BasicBlock bb, Definition def, SourceVariable v) { + exists(int last | last = maxSsaRefRank(bb, v) | + ssaDefReachesRank(bb, def, last, v) and + liveAtExit(bb, v) + ) + or + // The construction of SSA form ensures that each read of a variable is + // dominated by its definition. An SSA definition therefore reaches a + // control flow node if it is the _closest_ SSA definition that dominates + // the node. If two definitions dominate a node then one must dominate the + // other, so therefore the definition of _closest_ is given by the dominator + // tree. Thus, reaching definitions can be calculated in terms of dominance. + ssaDefReachesEndOfBlock(getImmediateBasicBlockDominator(bb), def, pragma[only_bind_into](v)) and + liveThrough(bb, pragma[only_bind_into](v)) +} + +/** + * NB: If this predicate is exposed, it should be cached. + * + * Holds if `inp` is an input to the phi node `phi` along the edge originating in `bb`. + */ +pragma[nomagic] +predicate phiHasInputFromBlock(PhiNode phi, Definition inp, BasicBlock bb) { + exists(SourceVariable v, BasicBlock bbDef | + phi.definesAt(v, bbDef, _) and + getABasicBlockPredecessor(bbDef) = bb and + ssaDefReachesEndOfBlock(bb, inp, v) + ) +} + +/** + * NB: If this predicate is exposed, it should be cached. + * + * Holds if the SSA definition of `v` at `def` reaches a read at index `i` in + * basic block `bb`, without crossing another SSA definition of `v`. The read + * is of kind `rk`. + */ +pragma[nomagic] +predicate ssaDefReachesRead(SourceVariable v, Definition def, BasicBlock bb, int i) { + ssaDefReachesReadWithinBlock(v, def, bb, i) + or + variableRead(bb, i, v, _) and + ssaDefReachesEndOfBlock(getABasicBlockPredecessor(bb), def, v) and + not ssaDefReachesReadWithinBlock(v, _, bb, i) +} + +/** + * NB: If this predicate is exposed, it should be cached. + * + * Holds if `def` is accessed at index `i1` in basic block `bb1` (either a read + * or a write), `def` is read at index `i2` in basic block `bb2`, and there is a + * path between them without any read of `def`. + */ +pragma[nomagic] +predicate adjacentDefRead(Definition def, BasicBlock bb1, int i1, BasicBlock bb2, int i2) { + exists(int rnk | + rnk = ssaDefRank(def, _, bb1, i1, _) and + rnk + 1 = ssaDefRank(def, _, bb1, i2, SsaRead()) and + variableRead(bb1, i2, _, _) and + bb2 = bb1 + ) + or + exists(SourceVariable v | ssaDefRank(def, v, bb1, i1, _) = maxSsaRefRank(bb1, v)) and + defAdjacentRead(def, bb1, bb2, i2) +} + +private predicate adjacentDefReachesRead( + Definition def, BasicBlock bb1, int i1, BasicBlock bb2, int i2 +) { + adjacentDefRead(def, bb1, i1, bb2, i2) and + exists(SourceVariable v | v = def.getSourceVariable() | + ssaRef(bb1, i1, v, SsaDef()) + or + variableRead(bb1, i1, v, true) + ) + or + exists(BasicBlock bb3, int i3 | + adjacentDefReachesRead(def, bb1, i1, bb3, i3) and + variableRead(bb3, i3, _, false) and + adjacentDefRead(def, bb3, i3, bb2, i2) + ) +} + +/** + * NB: If this predicate is exposed, it should be cached. + * + * Same as `adjacentDefRead`, but ignores uncertain reads. + */ +pragma[nomagic] +predicate adjacentDefNoUncertainReads(Definition def, BasicBlock bb1, int i1, BasicBlock bb2, int i2) { + adjacentDefReachesRead(def, bb1, i1, bb2, i2) and + variableRead(bb2, i2, _, true) +} + +/** + * NB: If this predicate is exposed, it should be cached. + * + * Holds if the node at index `i` in `bb` is a last reference to SSA definition + * `def`. The reference is last because it can reach another write `next`, + * without passing through another read or write. + */ +pragma[nomagic] +predicate lastRefRedef(Definition def, BasicBlock bb, int i, Definition next) { + exists(int rnk, SourceVariable v, int j | rnk = ssaDefRank(def, v, bb, i, _) | + // Next reference to `v` inside `bb` is a write + next.definesAt(v, bb, j) and + rnk + 1 = ssaRefRank(bb, j, v, SsaDef()) + or + // Can reach a write using one or more steps + rnk = maxSsaRefRank(bb, v) and + exists(BasicBlock bb2 | + varBlockReaches(def, bb, bb2) and + next.definesAt(v, bb2, j) and + 1 = ssaRefRank(bb2, j, v, SsaDef()) + ) + ) +} + +/** + * NB: If this predicate is exposed, it should be cached. + * + * Holds if `inp` is an immediately preceding definition of uncertain definition + * `def`. Since `def` is uncertain, the value from the preceding definition might + * still be valid. + */ +pragma[nomagic] +predicate uncertainWriteDefinitionInput(UncertainWriteDefinition def, Definition inp) { + lastRefRedef(inp, _, _, def) +} + +private predicate adjacentDefReachesUncertainRead( + Definition def, BasicBlock bb1, int i1, BasicBlock bb2, int i2 +) { + adjacentDefReachesRead(def, bb1, i1, bb2, i2) and + variableRead(bb2, i2, _, false) +} + +/** + * NB: If this predicate is exposed, it should be cached. + * + * Same as `lastRefRedef`, but ignores uncertain reads. + */ +pragma[nomagic] +predicate lastRefRedefNoUncertainReads(Definition def, BasicBlock bb, int i, Definition next) { + lastRefRedef(def, bb, i, next) and + not variableRead(bb, i, def.getSourceVariable(), false) + or + exists(BasicBlock bb0, int i0 | + lastRefRedef(def, bb0, i0, next) and + adjacentDefReachesUncertainRead(def, bb, i, bb0, i0) + ) +} + +/** + * NB: If this predicate is exposed, it should be cached. + * + * Holds if the node at index `i` in `bb` is a last reference to SSA + * definition `def`. + * + * That is, the node can reach the end of the enclosing callable, or another + * SSA definition for the underlying source variable, without passing through + * another read. + */ +pragma[nomagic] +predicate lastRef(Definition def, BasicBlock bb, int i) { + lastRefRedef(def, bb, i, _) + or + exists(SourceVariable v | ssaDefRank(def, v, bb, i, _) = maxSsaRefRank(bb, v) | + // Can reach exit directly + bb instanceof ExitBasicBlock + or + // Can reach a block using one or more steps, where `def` is no longer live + exists(BasicBlock bb2 | varBlockReaches(def, bb, bb2) | + not defOccursInBlock(def, bb2, _) and + not ssaDefReachesEndOfBlock(bb2, def, _) + ) + ) +} + +/** + * NB: If this predicate is exposed, it should be cached. + * + * Same as `lastRefRedef`, but ignores uncertain reads. + */ +pragma[nomagic] +predicate lastRefNoUncertainReads(Definition def, BasicBlock bb, int i) { + lastRef(def, bb, i) and + not variableRead(bb, i, def.getSourceVariable(), false) + or + exists(BasicBlock bb0, int i0 | + lastRef(def, bb0, i0) and + adjacentDefReachesUncertainRead(def, bb, i, bb0, i0) + ) +} + +/** A static single assignment (SSA) definition. */ +class Definition extends TDefinition { + /** Gets the source variable underlying this SSA definition. */ + SourceVariable getSourceVariable() { this.definesAt(result, _, _) } + + /** + * Holds if this SSA definition defines `v` at index `i` in basic block `bb`. + * Phi nodes are considered to be at index `-1`, while normal variable writes + * are at the index of the control flow node they wrap. + */ + final predicate definesAt(SourceVariable v, BasicBlock bb, int i) { + this = TWriteDef(v, bb, i) + or + this = TPhiNode(v, bb) and i = -1 + } + + /** Gets the basic block to which this SSA definition belongs. */ + final BasicBlock getBasicBlock() { this.definesAt(_, result, _) } + + /** Gets a textual representation of this SSA definition. */ + string toString() { none() } +} + +/** An SSA definition that corresponds to a write. */ +class WriteDefinition extends Definition, TWriteDef { + private SourceVariable v; + private BasicBlock bb; + private int i; + + WriteDefinition() { this = TWriteDef(v, bb, i) } + + override string toString() { result = "WriteDef" } +} + +/** A phi node. */ +class PhiNode extends Definition, TPhiNode { + override string toString() { result = "Phi" } +} + +/** + * An SSA definition that represents an uncertain update of the underlying + * source variable. + */ +class UncertainWriteDefinition extends WriteDefinition { + UncertainWriteDefinition() { + exists(SourceVariable v, BasicBlock bb, int i | + this.definesAt(v, bb, i) and + variableWrite(bb, i, v, false) + ) + } +} diff --git a/csharp/ql/src/semmle/code/cil/internal/SsaImplSpecific.qll b/csharp/ql/src/semmle/code/cil/internal/SsaImplSpecific.qll new file mode 100644 index 00000000000..94b4812d996 --- /dev/null +++ b/csharp/ql/src/semmle/code/cil/internal/SsaImplSpecific.qll @@ -0,0 +1,30 @@ +/** Provides the CIL specific parameters for `SsaImplCommon.qll`. */ + +private import cil +private import SsaImpl + +class BasicBlock = CIL::BasicBlock; + +BasicBlock getImmediateBasicBlockDominator(BasicBlock bb) { result = bb.getImmediateDominator() } + +BasicBlock getABasicBlockSuccessor(BasicBlock bb) { result = bb.getASuccessor() } + +class ExitBasicBlock = CIL::ExitBasicBlock; + +class SourceVariable = CIL::StackVariable; + +predicate variableWrite(BasicBlock bb, int i, SourceVariable v, boolean certain) { + forceCachingInSameStage() and + exists(CIL::VariableUpdate vu | + vu.updatesAt(bb, i) and + v = vu.getVariable() and + certain = true + ) +} + +predicate variableRead(BasicBlock bb, int i, SourceVariable v, boolean certain) { + exists(CIL::ReadAccess ra | bb.getNode(i) = ra | + ra.getTarget() = v and + certain = true + ) +} diff --git a/csharp/ql/src/semmle/code/csharp/Callable.qll b/csharp/ql/src/semmle/code/csharp/Callable.qll index 6dc7cfced9b..111702bac48 100644 --- a/csharp/ql/src/semmle/code/csharp/Callable.qll +++ b/csharp/ql/src/semmle/code/csharp/Callable.qll @@ -206,7 +206,11 @@ class Callable extends DotNet::Callable, Parameterizable, ExprOrStmtParent, @cal exists(ReturnStmt ret | ret.getEnclosingCallable() = this | e = ret.getExpr()) or e = this.getExpressionBody() and - not this.getReturnType() instanceof VoidType + not this.getReturnType() instanceof VoidType and + ( + not this.(Modifiable).isAsync() or + this.getReturnType() instanceof Generic + ) } /** Holds if this callable can yield return the expression `e`. */ diff --git a/csharp/ql/src/semmle/code/csharp/Element.qll b/csharp/ql/src/semmle/code/csharp/Element.qll index 521138db1b5..fbd96f6086d 100644 --- a/csharp/ql/src/semmle/code/csharp/Element.qll +++ b/csharp/ql/src/semmle/code/csharp/Element.qll @@ -27,9 +27,6 @@ class Element extends DotNet::Element, @element { /** Gets a location of this element, including sources and assemblies. */ override Location getALocation() { none() } - /** Holds if this element is from an assembly. */ - predicate fromLibrary() { this.getFile().fromLibrary() } - /** Gets the parent of this element, if any. */ Element getParent() { result.getAChild() = this } diff --git a/csharp/ql/src/semmle/code/csharp/Enclosing.qll b/csharp/ql/src/semmle/code/csharp/Enclosing.qll deleted file mode 100644 index ab106421196..00000000000 --- a/csharp/ql/src/semmle/code/csharp/Enclosing.qll +++ /dev/null @@ -1,83 +0,0 @@ -/** - * INTERNAL: Do not use. - * - * Provides efficient cached predicates for finding enclosing statements and callables. - * - * There are a number of difficulties. There can be expressions without - * enclosing statements (for example initialisers for fields and constructors) - * or enclosing callables (even if we consider constructor initialisers - * to be enclosed by constructors, field initialisers don't have callables). - * - * The only cases where a `Stmt` has an `Expr` parent are delegate and lambda - * expressions, which are both callable. - */ - -import Stmt -private import semmle.code.csharp.ExprOrStmtParent - -/** - * INTERNAL: Do not use. - */ -cached -module Internal { - /** - * INTERNAL: Do not use. - * - * Holds if `c` is the enclosing callable of statement `s`. - */ - cached - predicate enclosingCallable(Stmt s, Callable c) { - // Compute the enclosing callable for a statement. This walks up through - // enclosing statements until it hits a callable. It's unambiguous, since - // if a statement has no parent statement, it's either the method body - // or the body of an anonymous function declaration, in each of which cases the - // non-statement parent is in fact the enclosing callable. - c.getAChildStmt+() = s - } - - private Expr getAChildExpr(ExprOrStmtParent p) { - result = p.getAChildExpr() or - result = p.(AssignOperation).getExpandedAssignment() - } - - /** - * INTERNAL: Do not use. - * - * Holds if `s` is the enclosing statement of expression `e`. - */ - cached - predicate enclosingStmt(Expr e, Stmt s) { - // Compute the enclosing statement for an expression. Note that this need - // not exist, since expressions can occur in contexts where they have no - // enclosing statement (examples include field initialisers, both inline - // and explicit on constructor definitions, and annotation arguments). - getAChildExpr+(s) = e - } - - private predicate childExprOfCallable(Callable parent, Expr child) { - child = getAChildExpr(parent) - or - exists(Expr mid | childExprOfCallable(parent, mid) | - not mid instanceof Callable and - child = getAChildExpr(mid) - ) - } - - /** - * INTERNAL: Do not use. - * - * Holds if `c` is the enclosing callable of expression `e`. - */ - cached - predicate exprEnclosingCallable(Expr e, Callable c) { - // Compute the enclosing callable of an expression. Note that expressions in - // lambda functions should have the lambdas as enclosing callables, and their - // enclosing statement may be the same as the enclosing statement of the - // lambda; thus, it is *not* safe to go up to the enclosing statement and - // take its own enclosing callable. - childExprOfCallable(c, e) - or - not childExprOfCallable(_, e) and - exists(Stmt s | enclosingStmt(e, s) | enclosingCallable(s, c)) - } -} diff --git a/csharp/ql/src/semmle/code/csharp/ExprOrStmtParent.qll b/csharp/ql/src/semmle/code/csharp/ExprOrStmtParent.qll index c7c7bfe00e8..b6501477117 100644 --- a/csharp/ql/src/semmle/code/csharp/ExprOrStmtParent.qll +++ b/csharp/ql/src/semmle/code/csharp/ExprOrStmtParent.qll @@ -138,6 +138,54 @@ private module Cached { ) else expr_parent(child, i, parent) } + + private Expr getAChildExpr(ExprOrStmtParent parent) { + result = parent.getAChildExpr() or + result = parent.(AssignOperation).getExpandedAssignment() + } + + private ControlFlowElement getAChild(ExprOrStmtParent parent) { + result = getAChildExpr(parent) + or + result = parent.getAChildStmt() + } + + pragma[inline] + private ControlFlowElement enclosingStart(ControlFlowElement cfe) { + result = cfe + or + getAChild(result).(AnonymousFunctionExpr) = cfe + } + + private predicate parent(ControlFlowElement child, ExprOrStmtParent parent) { + child = getAChild(parent) and + not child instanceof Callable + } + + /** Holds if the enclosing body of `cfe` is `body`. */ + cached + predicate enclosingBody(ControlFlowElement cfe, ControlFlowElement body) { + body = any(Callable c).getBody() and + parent*(enclosingStart(cfe), body) + } + + /** Holds if the enclosing callable of `cfe` is `c`. */ + cached + predicate enclosingCallable(ControlFlowElement cfe, Callable c) { + enclosingBody(cfe, c.getBody()) + or + parent*(enclosingStart(cfe), c.(Constructor).getInitializer()) + } + + /** Holds if the enclosing statement of expression `e` is `s`. */ + cached + predicate enclosingStmt(Expr e, Stmt s) { + // Compute the enclosing statement for an expression. Note that this need + // not exist, since expressions can occur in contexts where they have no + // enclosing statement (examples include field initialisers, both inline + // and explicit on constructor definitions, and annotation arguments). + getAChildExpr+(s) = e + } } import Cached diff --git a/csharp/ql/src/semmle/code/csharp/Stmt.qll b/csharp/ql/src/semmle/code/csharp/Stmt.qll index 375e698d1cb..2ccd57078db 100644 --- a/csharp/ql/src/semmle/code/csharp/Stmt.qll +++ b/csharp/ql/src/semmle/code/csharp/Stmt.qll @@ -8,7 +8,7 @@ import Element import Location import Member import exprs.Expr -private import semmle.code.csharp.Enclosing::Internal +private import semmle.code.csharp.ExprOrStmtParent private import semmle.code.csharp.frameworks.System private import TypeRef diff --git a/csharp/ql/src/semmle/code/csharp/commons/Disposal.qll b/csharp/ql/src/semmle/code/csharp/commons/Disposal.qll index 28c79d749ff..090599a60a7 100644 --- a/csharp/ql/src/semmle/code/csharp/commons/Disposal.qll +++ b/csharp/ql/src/semmle/code/csharp/commons/Disposal.qll @@ -11,14 +11,22 @@ private predicate isDisposeMethod(DotNet::Callable method) { method.getNumberOfParameters() = 0 } +private predicate cilVariableReadFlowsTo(CIL::Variable variable, CIL::DataFlowNode n) { + n = variable.getARead() + or + exists(CIL::DataFlowNode mid | + cilVariableReadFlowsTo(variable, mid) and + mid.getALocalFlowSucc(n, any(CIL::Untainted u)) + ) +} + private predicate disposedCilVariable(CIL::Variable variable) { // `variable` is the `this` parameter on a dispose method. isDisposeMethod(variable.(CIL::ThisParameter).getMethod()) or // `variable` is passed to a method that disposes it. - exists(CIL::Call call, CIL::Parameter param, CIL::ReadAccess read | - read.getTarget() = variable and - read.flowsTo(call.getArgumentForParameter(param)) and + exists(CIL::Call call, CIL::Parameter param | + cilVariableReadFlowsTo(variable, call.getArgumentForParameter(param)) and disposedCilVariable(param) ) or @@ -27,9 +35,8 @@ private predicate disposedCilVariable(CIL::Variable variable) { or // A variable is disposed if it's assigned to another variable // that may be disposed. - exists(CIL::ReadAccess read, CIL::WriteAccess write | - read.flowsTo(write.getExpr()) and - read.getTarget() = variable and + exists(CIL::WriteAccess write | + cilVariableReadFlowsTo(variable, write.getExpr()) and disposedCilVariable(write.getTarget()) ) } diff --git a/csharp/ql/src/semmle/code/csharp/controlflow/internal/pressa/SsaImplCommon.qll b/csharp/ql/src/semmle/code/csharp/controlflow/internal/pressa/SsaImplCommon.qll index be01c05b8fa..f828419a440 100644 --- a/csharp/ql/src/semmle/code/csharp/controlflow/internal/pressa/SsaImplCommon.qll +++ b/csharp/ql/src/semmle/code/csharp/controlflow/internal/pressa/SsaImplCommon.qll @@ -1,5 +1,5 @@ /** - * Provides a language-independant implementation of static single assignment + * Provides a language-independent implementation of static single assignment * (SSA) form. */ @@ -321,10 +321,9 @@ private module SsaDefReaches { } pragma[noinline] - private BasicBlock getAMaybeLiveSuccessor(Definition def, BasicBlock bb) { - result = getABasicBlockSuccessor(bb) and - not defOccursInBlock(_, bb, def.getSourceVariable()) and - ssaDefReachesEndOfBlock(bb, def, _) + private predicate ssaDefReachesThroughBlock(Definition def, BasicBlock bb) { + ssaDefReachesEndOfBlock(bb, def, _) and + not defOccursInBlock(_, bb, def.getSourceVariable()) } /** @@ -337,7 +336,11 @@ private module SsaDefReaches { defOccursInBlock(def, bb1, _) and bb2 = getABasicBlockSuccessor(bb1) or - exists(BasicBlock mid | varBlockReaches(def, bb1, mid) | bb2 = getAMaybeLiveSuccessor(def, mid)) + exists(BasicBlock mid | + varBlockReaches(def, bb1, mid) and + ssaDefReachesThroughBlock(def, mid) and + bb2 = getABasicBlockSuccessor(mid) + ) } /** @@ -355,17 +358,10 @@ private module SsaDefReaches { private import SsaDefReaches -pragma[noinline] -private predicate ssaDefReachesEndOfBlockRec(BasicBlock bb, Definition def, SourceVariable v) { - exists(BasicBlock idom | ssaDefReachesEndOfBlock(idom, def, v) | - // The construction of SSA form ensures that each read of a variable is - // dominated by its definition. An SSA definition therefore reaches a - // control flow node if it is the _closest_ SSA definition that dominates - // the node. If two definitions dominate a node then one must dominate the - // other, so therefore the definition of _closest_ is given by the dominator - // tree. Thus, reaching definitions can be calculated in terms of dominance. - idom = getImmediateBasicBlockDominator(bb) - ) +pragma[nomagic] +predicate liveThrough(BasicBlock bb, SourceVariable v) { + liveAtExit(bb, v) and + not ssaRef(bb, _, v, SsaDef()) } /** @@ -382,9 +378,14 @@ predicate ssaDefReachesEndOfBlock(BasicBlock bb, Definition def, SourceVariable liveAtExit(bb, v) ) or - ssaDefReachesEndOfBlockRec(bb, def, v) and - liveAtExit(bb, v) and - not ssaRef(bb, _, v, SsaDef()) + // The construction of SSA form ensures that each read of a variable is + // dominated by its definition. An SSA definition therefore reaches a + // control flow node if it is the _closest_ SSA definition that dominates + // the node. If two definitions dominate a node then one must dominate the + // other, so therefore the definition of _closest_ is given by the dominator + // tree. Thus, reaching definitions can be calculated in terms of dominance. + ssaDefReachesEndOfBlock(getImmediateBasicBlockDominator(bb), def, pragma[only_bind_into](v)) and + liveThrough(bb, pragma[only_bind_into](v)) } /** diff --git a/csharp/ql/src/semmle/code/csharp/dataflow/CallContext.qll b/csharp/ql/src/semmle/code/csharp/dataflow/CallContext.qll index 8be2fc0939f..47ff7f96111 100755 --- a/csharp/ql/src/semmle/code/csharp/dataflow/CallContext.qll +++ b/csharp/ql/src/semmle/code/csharp/dataflow/CallContext.qll @@ -1,4 +1,6 @@ /** + * DEPRECATED. + * * Provides classes for data flow call contexts. */ @@ -15,11 +17,13 @@ private newtype TCallContext = TArgFunctionPointerCallContext(FunctionPointerCall fptrc, int i) { exists(fptrc.getArgument(i)) } /** + * DEPRECATED. + * * A call context. * * A call context records the origin of data flow into callables. */ -class CallContext extends TCallContext { +deprecated class CallContext extends TCallContext { /** Gets a textual representation of this call context. */ string toString() { none() } @@ -27,18 +31,20 @@ class CallContext extends TCallContext { Location getLocation() { none() } } -/** An empty call context. */ -class EmptyCallContext extends CallContext, TEmptyCallContext { +/** DEPRECATED. An empty call context. */ +deprecated class EmptyCallContext extends CallContext, TEmptyCallContext { override string toString() { result = "" } override EmptyLocation getLocation() { any() } } /** + * DEPRECATED. + * * An argument call context, that is a call argument through which data flows * into a callable. */ -abstract class ArgumentCallContext extends CallContext { +abstract deprecated class ArgumentCallContext extends CallContext { /** * Holds if this call context represents the argument at position `i` of the * call expression `call`. @@ -46,8 +52,9 @@ abstract class ArgumentCallContext extends CallContext { abstract predicate isArgument(Expr call, int i); } -/** An argument of a non-delegate call. */ -class NonDelegateCallArgumentCallContext extends ArgumentCallContext, TArgNonDelegateCallContext { +/** DEPRECATED. An argument of a non-delegate call. */ +deprecated class NonDelegateCallArgumentCallContext extends ArgumentCallContext, + TArgNonDelegateCallContext { Expr arg; NonDelegateCallArgumentCallContext() { this = TArgNonDelegateCallContext(arg) } @@ -61,8 +68,8 @@ class NonDelegateCallArgumentCallContext extends ArgumentCallContext, TArgNonDel override Location getLocation() { result = arg.getLocation() } } -/** An argument of a delegate or function pointer call. */ -class DelegateLikeCallArgumentCallContext extends ArgumentCallContext { +/** DEPRECATED. An argument of a delegate or function pointer call. */ +deprecated class DelegateLikeCallArgumentCallContext extends ArgumentCallContext { DelegateLikeCall dc; int arg; @@ -80,10 +87,10 @@ class DelegateLikeCallArgumentCallContext extends ArgumentCallContext { override Location getLocation() { result = dc.getArgument(arg).getLocation() } } -/** An argument of a delegate call. */ -class DelegateCallArgumentCallContext extends DelegateLikeCallArgumentCallContext, +/** DEPRECATED. An argument of a delegate call. */ +deprecated class DelegateCallArgumentCallContext extends DelegateLikeCallArgumentCallContext, TArgDelegateCallContext { } -/** An argument of a function pointer call. */ -class FunctionPointerCallArgumentCallContext extends DelegateLikeCallArgumentCallContext, +/** DEPRECATED. An argument of a function pointer call. */ +deprecated class FunctionPointerCallArgumentCallContext extends DelegateLikeCallArgumentCallContext, TArgFunctionPointerCallContext { } diff --git a/csharp/ql/src/semmle/code/csharp/dataflow/FlowSummary.qll b/csharp/ql/src/semmle/code/csharp/dataflow/FlowSummary.qll index 587a6dc0cd0..374c42ed7e9 100644 --- a/csharp/ql/src/semmle/code/csharp/dataflow/FlowSummary.qll +++ b/csharp/ql/src/semmle/code/csharp/dataflow/FlowSummary.qll @@ -1,181 +1,109 @@ -/** - * Provides classes and predicates for definining flow summaries. - */ +/** Provides classes and predicates for defining flow summaries. */ import csharp private import internal.FlowSummaryImpl as Impl -private import internal.FlowSummarySpecific::Private -private import internal.DataFlowPublic as DataFlowPublic +private import internal.DataFlowDispatch + // import all instances below -private import semmle.code.csharp.dataflow.LibraryTypeDataFlow -private import semmle.code.csharp.frameworks.EntityFramework +private module Summaries { + private import semmle.code.csharp.dataflow.LibraryTypeDataFlow + private import semmle.code.csharp.frameworks.EntityFramework +} -class SummarizableCallable = Impl::Public::SummarizableCallable; +class SummaryComponent = Impl::Public::SummaryComponent; -/** An unbound method. */ -class SummarizableMethod extends SummarizableCallable, Method { } +/** Provides predicates for constructing summary components. */ +module SummaryComponent { + import Impl::Public::SummaryComponent -class ContentList = Impl::Public::ContentList; + /** Gets a summary component that represents a qualifier. */ + SummaryComponent qualifier() { result = argument(-1) } -/** Provides predicates for constructing content lists. */ -module ContentList { - import Impl::Public::ContentList + /** Gets a summary component that represents an element in a collection. */ + SummaryComponent element() { result = content(any(DataFlow::ElementContent c)) } - /** Gets the singleton "element content" content list. */ - ContentList element() { result = singleton(any(DataFlowPublic::ElementContent c)) } - - /** Gets a singleton property content list. */ - ContentList property(Property p) { - result = - singleton(any(DataFlowPublic::PropertyContent c | c.getProperty() = p.getUnboundDeclaration())) + /** Gets a summary component for property `p`. */ + SummaryComponent property(Property p) { + result = content(any(DataFlow::PropertyContent c | c.getProperty() = p.getUnboundDeclaration())) } - /** Gets a singleton field content list. */ - ContentList field(Field f) { + /** Gets a summary component for field `f`. */ + SummaryComponent field(Field f) { + result = content(any(DataFlow::FieldContent c | c.getField() = f.getUnboundDeclaration())) + } + + /** Gets a summary component that represents the return value of a call. */ + SummaryComponent return() { result = return(any(NormalReturnKind rk)) } + + /** + * Gets a summary component that represents the return value through the `i`th + * `out` argument of a call. + */ + SummaryComponent outArgument(int i) { + result = return(any(OutReturnKind rk | rk.getPosition() = i)) + } + + /** + * Gets a summary component that represents the return value through the `i`th + * `ref` argument of a call. + */ + SummaryComponent refArgument(int i) { + result = return(any(RefReturnKind rk | rk.getPosition() = i)) + } + + /** Gets a summary component that represents a jump to `c`. */ + SummaryComponent jump(Callable c) { result = - singleton(any(DataFlowPublic::FieldContent c | c.getField() = f.getUnboundDeclaration())) + return(any(JumpReturnKind jrk | + jrk.getTarget() = c.getUnboundDeclaration() and + jrk.getTargetReturnKind() instanceof NormalReturnKind + )) } } -class SummaryInput = Impl::Public::SummaryInput; +class SummaryComponentStack = Impl::Public::SummaryComponentStack; -/** Provides predicates for constructing flow-summary input specifications */ -module SummaryInput { - private import semmle.code.csharp.frameworks.system.Collections +/** Provides predicates for constructing stacks of summary components. */ +module SummaryComponentStack { + import Impl::Public::SummaryComponentStack - /** - * Gets an input specification that specifies the `i`th parameter as - * the input. - */ - SummaryInput parameter(int i) { result = TParameterSummaryInput(i) } + /** Gets a singleton stack representing a qualifier. */ + SummaryComponentStack qualifier() { result = singleton(SummaryComponent::qualifier()) } - private predicate isCollectionType(ValueOrRefType t) { - t.getABaseType*() instanceof SystemCollectionsIEnumerableInterface and - not t instanceof StringType + /** Gets a stack representing an element of `container`. */ + SummaryComponentStack elementOf(SummaryComponentStack container) { + result = push(SummaryComponent::element(), container) } - /** - * Gets an input specification that specifies the `i`th parameter as - * the input. - * - * `inputContents` is either empty or a singleton element content list, - * depending on whether the type of the `i`th parameter of `c` is a - * collection type. - */ - SummaryInput parameter(SummarizableCallable c, int i, ContentList inputContents) { - result = parameter(i) and - exists(Parameter p | - p = c.getParameter(i) and - if isCollectionType(p.getType()) - then inputContents = ContentList::element() - else inputContents = ContentList::empty() - ) + /** Gets a stack representing a propery `p` of `object`. */ + SummaryComponentStack propertyOf(Property p, SummaryComponentStack object) { + result = push(SummaryComponent::property(p), object) } - /** - * Gets an input specification that specifies the implicit `this` parameter - * as the input. - */ - SummaryInput thisParameter() { result = TParameterSummaryInput(-1) } - - /** - * Gets an input specification that specifies output from the delegate at - * parameter `i` as the input. - */ - SummaryInput delegate(int i) { result = TDelegateSummaryInput(i) } - - /** - * Gets an input specification that specifies output from the delegate at - * parameter `i` as the input. - * - * `c` must be a compatible callable, that is, a callable where the `i`th - * parameter is a delegate. - */ - SummaryInput delegate(SummarizableCallable c, int i) { - result = delegate(i) and - hasDelegateArgumentPosition(c, i) - } -} - -class SummaryOutput = Impl::Public::SummaryOutput; - -/** Provides predicates for constructing flow-summary output specifications. */ -module SummaryOutput { - /** - * Gets an output specification that specifies the return value from a call as - * the output. - */ - SummaryOutput return() { result = TReturnSummaryOutput() } - - /** - * Gets an output specification that specifies the `i`th parameter as the - * output. - */ - SummaryOutput parameter(int i) { result = TParameterSummaryOutput(i) } - - /** - * Gets an output specification that specifies the implicit `this` parameter - * as the output. - */ - SummaryOutput thisParameter() { result = TParameterSummaryOutput(-1) } - - /** - * Gets an output specification that specifies parameter `j` of the delegate at - * parameter `i` as the output. - */ - SummaryOutput delegate(int i, int j) { result = TDelegateSummaryOutput(i, j) } - - /** - * Gets an output specification that specifies parameter `j` of the delegate at - * parameter `i` as the output. - * - * `c` must be a compatible callable, that is, a callable where the `i`th - * parameter is a delegate with a parameter at position `j`. - */ - SummaryOutput delegate(SummarizableCallable c, int i, int j) { - result = TDelegateSummaryOutput(i, j) and - hasDelegateArgumentPosition2(c, i, j) + /** Gets a stack representing a field `f` of `object`. */ + SummaryComponentStack fieldOf(Field f, SummaryComponentStack object) { + result = push(SummaryComponent::field(f), object) } + /** Gets a singleton stack representing the return value of a call. */ + SummaryComponentStack return() { result = singleton(SummaryComponent::return()) } + /** - * Gets an output specification that specifies the `output` of `target` as the - * output. That is, data will flow into one callable and out of another callable - * (`target`). - * - * `output` is limited to (this) parameters and ordinary returns. + * Gets a singleton stack representing the return value through the `i`th + * `out` argument of a call. */ - SummaryOutput jump(SummarizableCallable target, SummaryOutput output) { - result = TJumpSummaryOutput(target, toReturnKind(output)) - } + SummaryComponentStack outArgument(int i) { result = singleton(SummaryComponent::outArgument(i)) } + + /** + * Gets a singleton stack representing the return value through the `i`th + * `ref` argument of a call. + */ + SummaryComponentStack refArgument(int i) { result = singleton(SummaryComponent::refArgument(i)) } + + /** Gets a singleton stack representing a jump to `c`. */ + SummaryComponentStack jump(Callable c) { result = singleton(SummaryComponent::jump(c)) } } class SummarizedCallable = Impl::Public::SummarizedCallable; -/** Provides a query predicate for outputting a set of relevant flow summaries. */ -module TestOutput { - /** A flow summary to include in the `summary/3` query predicate. */ - abstract class RelevantSummarizedCallable extends SummarizedCallable { } - - /** A query predicate for outputting flow summaries in QL tests. */ - query predicate summary(string callable, string flow, boolean preservesValue) { - exists( - RelevantSummarizedCallable c, SummaryInput input, ContentList inputContents, - string inputContentsString, SummaryOutput output, ContentList outputContents, - string outputContentsString - | - callable = c.getQualifiedNameWithTypes() and - Impl::Private::summary(c, input, inputContents, output, outputContents, preservesValue) and - ( - if inputContents.length() = 0 - then inputContentsString = "" - else inputContentsString = " [" + inputContents + "]" - ) and - ( - if outputContents.length() = 0 - then outputContentsString = "" - else outputContentsString = " [" + outputContents + "]" - ) and - flow = input + inputContentsString + " -> " + output + outputContentsString - ) - } -} +class RequiredSummaryComponentStack = Impl::Public::RequiredSummaryComponentStack; diff --git a/csharp/ql/src/semmle/code/csharp/dataflow/LibraryTypeDataFlow.qll b/csharp/ql/src/semmle/code/csharp/dataflow/LibraryTypeDataFlow.qll index 547d269a24c..5798080a98a 100644 --- a/csharp/ql/src/semmle/code/csharp/dataflow/LibraryTypeDataFlow.qll +++ b/csharp/ql/src/semmle/code/csharp/dataflow/LibraryTypeDataFlow.qll @@ -354,86 +354,148 @@ abstract class LibraryTypeDataFlow extends Type { } } -private CallableFlowSource toCallableFlowSource(SummaryInput input) { - result = TCallableFlowSourceQualifier() and - input = SummaryInput::parameter(-1) - or - exists(int i | - result = TCallableFlowSourceArg(i) and - input = SummaryInput::parameter(i) - ) - or - exists(int i | - result = TCallableFlowSourceDelegateArg(i) and - input = SummaryInput::delegate(i) - ) -} - -private CallableFlowSink toCallableFlowSink(SummaryOutput output) { - result = TCallableFlowSinkQualifier() and - output = SummaryOutput::parameter(-1) - or - result = TCallableFlowSinkReturn() and - output = SummaryOutput::return() - or - exists(int i | - result = TCallableFlowSinkArg(i) and - output = SummaryOutput::parameter(i) - ) - or - exists(int i, int j | - result = TCallableFlowSinkDelegateArg(i, j) and - output = SummaryOutput::delegate(i, j) - ) -} - -private AccessPath toAccessPath(ContentList cl) { - cl = ContentList::empty() and - result = TNilAccessPath() - or - exists(Content head, ContentList tail | - cl = ContentList::cons(head, tail) and - result = TConsAccessPath(head, toAccessPath(tail)) - ) -} - -private class FrameworkDataFlowAdaptor extends SummarizedCallable { - private LibraryTypeDataFlow ltdf; - - FrameworkDataFlowAdaptor() { - ltdf.callableFlow(_, _, this, _) or - ltdf.callableFlow(_, _, _, _, this, _) or - ltdf.clearsContent(_, _, this) - } - - override predicate propagatesFlow(SummaryInput input, SummaryOutput output, boolean preservesValue) { - ltdf.callableFlow(toCallableFlowSource(input), toCallableFlowSink(output), this, preservesValue) - } - - override predicate propagatesFlow( - SummaryInput input, ContentList inputContents, SummaryOutput output, ContentList outputContents, - boolean preservesValue - ) { - ltdf.callableFlow(toCallableFlowSource(input), toAccessPath(inputContents), - toCallableFlowSink(output), toAccessPath(outputContents), this, preservesValue) - } - - private AccessPath getAnAccessPath() { - ltdf.callableFlow(_, result, _, _, this, _) +/** + * An internal module for translating old `LibraryTypeDataFlow`-style + * flow summaries into the new style. + */ +private module FrameworkDataFlowAdaptor { + private CallableFlowSource toCallableFlowSource(SummaryComponentStack input) { + result = TCallableFlowSourceQualifier() and + input = SummaryComponentStack::qualifier() or - ltdf.callableFlow(_, _, _, result, _, _) - } - - override predicate requiresContentList(Content head, ContentList tail) { - exists(AccessPath ap | - ap = this.getAnAccessPath().drop(_) and - head = ap.getHead() and - toAccessPath(tail) = ap.getTail() + exists(int i | + result = TCallableFlowSourceArg(i) and + input = SummaryComponentStack::argument(i) + ) + or + exists(int i | result = TCallableFlowSourceDelegateArg(i) | + input = + SummaryComponentStack::push(SummaryComponent::return(), SummaryComponentStack::argument(i)) ) } - override predicate clearsContent(SummaryInput input, Content content) { - ltdf.clearsContent(toCallableFlowSource(input), content, this) + private CallableFlowSink toCallableFlowSink(SummaryComponentStack output) { + result = TCallableFlowSinkQualifier() and + output = SummaryComponentStack::qualifier() + or + result = TCallableFlowSinkReturn() and + output = SummaryComponentStack::return() + or + exists(int i | + result = TCallableFlowSinkArg(i) and + output = SummaryComponentStack::outArgument(i) + ) + or + exists(int i, int j | result = TCallableFlowSinkDelegateArg(i, j) | + output = + SummaryComponentStack::push(SummaryComponent::parameter(j), + SummaryComponentStack::argument(i)) + ) + } + + private class FrameworkDataFlowAdaptor extends SummarizedCallable { + private LibraryTypeDataFlow ltdf; + + FrameworkDataFlowAdaptor() { + ltdf.callableFlow(_, _, this, _) or + ltdf.callableFlow(_, _, _, _, this, _) or + ltdf.clearsContent(_, _, this) + } + + predicate input( + CallableFlowSource source, AccessPath sourceAp, SummaryComponent head, + SummaryComponentStack tail, int i + ) { + ltdf.callableFlow(source, sourceAp, _, _, this, _) and + source = toCallableFlowSource(tail) and + head = SummaryComponent::content(sourceAp.getHead()) and + i = 0 + or + exists(SummaryComponent tailHead, SummaryComponentStack tailTail | + this.input(source, sourceAp, tailHead, tailTail, i - 1) and + head = SummaryComponent::content(sourceAp.drop(i).getHead()) and + tail = SummaryComponentStack::push(tailHead, tailTail) + ) + } + + predicate output( + CallableFlowSink sink, AccessPath sinkAp, SummaryComponent head, SummaryComponentStack tail, + int i + ) { + ltdf.callableFlow(_, _, sink, sinkAp, this, _) and + sink = toCallableFlowSink(tail) and + head = SummaryComponent::content(sinkAp.getHead()) and + i = 0 + or + exists(SummaryComponent tailHead, SummaryComponentStack tailTail | + this.output(sink, sinkAp, tailHead, tailTail, i - 1) and + head = SummaryComponent::content(sinkAp.drop(i).getHead()) and + tail = SummaryComponentStack::push(tailHead, tailTail) + ) + } + + override predicate propagatesFlow( + SummaryComponentStack input, SummaryComponentStack output, boolean preservesValue + ) { + ltdf.callableFlow(toCallableFlowSource(input), toCallableFlowSink(output), this, + preservesValue) + or + exists( + CallableFlowSource source, AccessPath sourceAp, CallableFlowSink sink, AccessPath sinkAp + | + ltdf.callableFlow(source, sourceAp, sink, sinkAp, this, preservesValue) and + ( + exists(SummaryComponent head, SummaryComponentStack tail | + this.input(source, sourceAp, head, tail, sourceAp.length() - 1) and + input = SummaryComponentStack::push(head, tail) + ) + or + sourceAp.length() = 0 and + source = toCallableFlowSource(input) + ) and + ( + exists(SummaryComponent head, SummaryComponentStack tail | + this.output(sink, sinkAp, head, tail, sinkAp.length() - 1) and + output = SummaryComponentStack::push(head, tail) + ) + or + sinkAp.length() = 0 and + sink = toCallableFlowSink(output) + ) + ) + } + + override predicate clearsContent(int i, Content content) { + exists(SummaryComponentStack input | + ltdf.clearsContent(toCallableFlowSource(input), content, this) and + input = SummaryComponentStack::singleton(SummaryComponent::argument(i)) + ) + } + } + + private class AdaptorRequiredSummaryComponentStack extends RequiredSummaryComponentStack { + private SummaryComponent head; + + AdaptorRequiredSummaryComponentStack() { + exists(int i | + exists(TCallableFlowSourceDelegateArg(i)) and + head = SummaryComponent::return() and + this = SummaryComponentStack::singleton(SummaryComponent::argument(i)) + ) + or + exists(int i, int j | exists(TCallableFlowSinkDelegateArg(i, j)) | + head = SummaryComponent::parameter(j) and + this = SummaryComponentStack::singleton(SummaryComponent::argument(i)) + ) + or + exists(FrameworkDataFlowAdaptor adaptor | + adaptor.input(_, _, head, this, _) + or + adaptor.output(_, _, head, this, _) + ) + } + + override predicate required(SummaryComponent c) { c = head } } } @@ -2417,20 +2479,38 @@ class StringValuesFlow extends LibraryTypeDataFlow, Struct { } } +private predicate recordConstructorFlow(Constructor c, int i, Property p) { + c = any(Record r).getAMember() and + exists(string name | + c.getParameter(i).getName() = name and + c.getDeclaringType().getAMember(name) = p + ) +} + +private class RecordConstructorFlowRequiredSummaryComponentStack extends RequiredSummaryComponentStack { + private SummaryComponent head; + + RecordConstructorFlowRequiredSummaryComponentStack() { + exists(Property p | + recordConstructorFlow(_, _, p) and + head = SummaryComponent::property(p) and + this = SummaryComponentStack::singleton(SummaryComponent::return()) + ) + } + + override predicate required(SummaryComponent c) { c = head } +} + private class RecordConstructorFlow extends SummarizedCallable { - RecordConstructorFlow() { this = any(Record r).getAMember().(Constructor) } + RecordConstructorFlow() { recordConstructorFlow(this, _, _) } override predicate propagatesFlow( - SummaryInput input, ContentList inputContents, SummaryOutput output, ContentList outputContents, - boolean preservesValue + SummaryComponentStack input, SummaryComponentStack output, boolean preservesValue ) { - exists(int i, Property p, string name | - this.getParameter(i).getName() = name and - this.getDeclaringType().getAMember(name) = p and - input = SummaryInput::parameter(i) and - inputContents = ContentList::empty() and - output = SummaryOutput::return() and - outputContents = ContentList::property(p) and + exists(int i, Property p | + recordConstructorFlow(this, i, p) and + input = SummaryComponentStack::argument(i) and + output = SummaryComponentStack::propertyOf(p, SummaryComponentStack::return()) and preservesValue = true ) } diff --git a/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowDispatch.qll b/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowDispatch.qll index c68ba38e0b5..4eac274b04f 100644 --- a/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowDispatch.qll +++ b/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowDispatch.qll @@ -1,14 +1,20 @@ private import csharp private import cil private import dotnet +private import DataFlowPublic private import DataFlowPrivate -private import DelegateDataFlow private import FlowSummaryImpl as FlowSummaryImpl private import semmle.code.csharp.dataflow.FlowSummary private import semmle.code.csharp.dispatch.Dispatch private import semmle.code.csharp.frameworks.system.Collections private import semmle.code.csharp.frameworks.system.collections.Generic +private predicate summarizedCallable(DataFlowCallable c) { + c instanceof SummarizedCallable + or + FlowSummaryImpl::Private::summaryReturnNode(_, TJumpReturnKind(c, _)) +} + /** * Gets a source declaration of callable `c` that has a body or has * a flow summary. @@ -18,11 +24,8 @@ private import semmle.code.csharp.frameworks.system.collections.Generic */ DotNet::Callable getCallableForDataFlow(DotNet::Callable c) { exists(DotNet::Callable unboundDecl | unboundDecl = c.getUnboundDeclaration() | - result = unboundDecl and - result instanceof SummarizedCallable - or - result = unboundDecl and - FlowSummaryImpl::Private::summary(_, _, _, SummaryOutput::jump(result, _), _, _) + summarizedCallable(unboundDecl) and + result = unboundDecl or result.hasBody() and if unboundDecl.getFile().fromSource() @@ -44,17 +47,6 @@ DotNet::Callable getCallableForDataFlow(DotNet::Callable c) { ) } -/** - * Holds if callable `c` can return `e` as an `out`/`ref` value for parameter `p`. - */ -private predicate callableReturnsOutOrRef(Callable c, Parameter p, Expr e) { - exists(Ssa::ExplicitDefinition def | - def.getADefinition().getSource() = e and - def.isLiveOutRefParameterDefinition(p) and - p = c.getAParameter() - ) -} - /** * Holds if `cfn` corresponds to a call that can reach callable `c` using * additional calls, and `c` is a callable that either reads or writes to @@ -82,19 +74,22 @@ private module Cached { cached newtype TReturnKind = TNormalReturnKind() { Stages::DataFlowStage::forceCachingInSameStage() } or - TYieldReturnKind() or - TOutReturnKind(int i) { - exists(Parameter p | callableReturnsOutOrRef(_, p, _) and p.isOut() | i = p.getPosition()) - } or - TRefReturnKind(int i) { - exists(Parameter p | callableReturnsOutOrRef(_, p, _) and p.isRef() | i = p.getPosition()) - } or + TOutReturnKind(int i) { i = any(Parameter p | p.isOut()).getPosition() } or + TRefReturnKind(int i) { i = any(Parameter p | p.isRef()).getPosition() } or TImplicitCapturedReturnKind(LocalScopeVariable v) { exists(Ssa::ExplicitDefinition def | def.isCapturedVariableDefinitionFlowOut(_, _) | v = def.getSourceVariable().getAssignable() ) } or - TQualifierReturnKind() + TJumpReturnKind(DataFlowCallable target, ReturnKind rk) { + rk instanceof NormalReturnKind and + ( + target instanceof Constructor or + not target.getReturnType() instanceof VoidType + ) + or + exists(target.getParameter(rk.(OutRefReturnKind).getPosition())) + } cached newtype TDataFlowCall = @@ -111,16 +106,8 @@ private module Cached { // No need to include calls that are compiled from source not call.getImplementation().getMethod().compiledFromSource() } or - TSummaryDelegateCall(SummarizedCallable c, int pos) { - exists(SummaryInput input | - FlowSummaryImpl::Private::summary(c, input, _, _, _, _) and - input = SummaryInput::delegate(pos) - ) - or - exists(SummaryOutput output | - FlowSummaryImpl::Private::summary(c, _, _, output, _, _) and - output = SummaryOutput::delegate(pos, _) - ) + TSummaryCall(SummarizedCallable c, Node receiver) { + FlowSummaryImpl::Private::summaryCallbackRange(c, receiver) } /** Gets a viable run-time target for the call `call`. */ @@ -131,45 +118,24 @@ private module Cached { import Cached private module DispatchImpl { - private import CallContext - - /** - * Gets a viable run-time target for the delegate call `call`, requiring - * call context `cc`. - */ - private DataFlowCallable viableDelegateCallable(DataFlowCall call, CallContext cc) { - result = call.(DelegateDataFlowCall).getARuntimeTarget(cc) - } - /** * Holds if the set of viable implementations that can be called by `call` * might be improved by knowing the call context. This is the case if the * call is a delegate call, or if the qualifier accesses a parameter of * the enclosing callable `c` (including the implicit `this` parameter). */ - predicate mayBenefitFromCallContext(DataFlowCall call, Callable c) { + predicate mayBenefitFromCallContext(NonDelegateDataFlowCall call, Callable c) { c = call.getEnclosingCallable() and - ( - exists(CallContext cc | exists(viableDelegateCallable(call, cc)) | - not cc instanceof EmptyCallContext - ) - or - call.(NonDelegateDataFlowCall).getDispatchCall().mayBenefitFromCallContext() - ) + call.getDispatchCall().mayBenefitFromCallContext() } /** * Gets a viable dispatch target of `call` in the context `ctx`. This is * restricted to those `call`s for which a context might make a difference. */ - DataFlowCallable viableImplInCallContext(DataFlowCall call, DataFlowCall ctx) { - exists(ArgumentCallContext cc | result = viableDelegateCallable(call, cc) | - cc.isArgument(ctx.getExpr(), _) - ) - or + DataFlowCallable viableImplInCallContext(NonDelegateDataFlowCall call, DataFlowCall ctx) { result = - call.(NonDelegateDataFlowCall) - .getDispatchCall() + call.getDispatchCall() .getADynamicTargetInCallContext(ctx.(NonDelegateDataFlowCall).getDispatchCall()) .getUnboundDeclaration() } @@ -197,12 +163,7 @@ abstract class ReturnKind extends TReturnKind { * body, that is, a "normal" return. */ class NormalReturnKind extends ReturnKind, TNormalReturnKind { - override string toString() { result = "return" } -} - -/** A value returned from a callable using a `yield return` statement. */ -class YieldReturnKind extends ReturnKind, TYieldReturnKind { - override string toString() { result = "yield return" } + override string toString() { result = "normal" } } /** A value returned from a callable using an `out` or a `ref` parameter. */ @@ -213,16 +174,24 @@ abstract class OutRefReturnKind extends ReturnKind { /** A value returned from a callable using an `out` parameter. */ class OutReturnKind extends OutRefReturnKind, TOutReturnKind { - override int getPosition() { this = TOutReturnKind(result) } + private int pos; - override string toString() { result = "out" } + OutReturnKind() { this = TOutReturnKind(pos) } + + override int getPosition() { result = pos } + + override string toString() { result = "out parameter " + pos } } /** A value returned from a callable using a `ref` parameter. */ class RefReturnKind extends OutRefReturnKind, TRefReturnKind { - override int getPosition() { this = TRefReturnKind(result) } + private int pos; - override string toString() { result = "ref" } + RefReturnKind() { this = TRefReturnKind(pos) } + + override int getPosition() { result = pos } + + override string toString() { result = "ref parameter " + pos } } /** A value implicitly returned from a callable using a captured variable. */ @@ -237,12 +206,30 @@ class ImplicitCapturedReturnKind extends ReturnKind, TImplicitCapturedReturnKind override string toString() { result = "captured " + v } } -/** A value returned through the qualifier of a call. */ -class QualifierReturnKind extends ReturnKind, TQualifierReturnKind { - override string toString() { result = "qualifier" } +/** + * A value returned through the output of another callable. + * + * This is currently only used to model flow summaries where data may flow into + * one API entry point and out of another. + */ +class JumpReturnKind extends ReturnKind, TJumpReturnKind { + private DataFlowCallable target; + private ReturnKind rk; + + JumpReturnKind() { this = TJumpReturnKind(target, rk) } + + /** Gets the target of the jump. */ + DataFlowCallable getTarget() { result = target } + + /** Gets the return kind of the target. */ + ReturnKind getTargetReturnKind() { result = rk } + + override string toString() { result = "jump to " + target } } -class DataFlowCallable = DotNet::Callable; +class DataFlowCallable extends DotNet::Callable { + DataFlowCallable() { this.isUnboundDeclaration() } +} /** A call relevant for data flow. */ abstract class DataFlowCall extends TDataFlowCall { @@ -293,7 +280,7 @@ class NonDelegateDataFlowCall extends DataFlowCall, TNonDelegateCall { override DataFlow::ExprNode getNode() { result.getControlFlowNode() = cfn } - override Callable getEnclosingCallable() { result = cfn.getEnclosingCallable() } + override DataFlowCallable getEnclosingCallable() { result = cfn.getEnclosingCallable() } override string toString() { result = cfn.toString() } @@ -301,12 +288,7 @@ class NonDelegateDataFlowCall extends DataFlowCall, TNonDelegateCall { } /** A delegate call relevant for data flow. */ -abstract class DelegateDataFlowCall extends DataFlowCall { - /** Gets a viable run-time target of this call requiring call context `cc`. */ - abstract DataFlowCallable getARuntimeTarget(CallContext::CallContext cc); - - override DataFlowCallable getARuntimeTarget() { result = this.getARuntimeTarget(_) } -} +abstract class DelegateDataFlowCall extends DataFlowCall { } /** An explicit delegate or function pointer call relevant for data flow. */ class ExplicitDelegateLikeDataFlowCall extends DelegateDataFlowCall, TExplicitDelegateLikeCall { @@ -315,15 +297,18 @@ class ExplicitDelegateLikeDataFlowCall extends DelegateDataFlowCall, TExplicitDe ExplicitDelegateLikeDataFlowCall() { this = TExplicitDelegateLikeCall(cfn, dc) } - override DataFlowCallable getARuntimeTarget(CallContext::CallContext cc) { - result = getCallableForDataFlow(dc.getARuntimeTarget(cc)) + /** Gets the underlying call. */ + DelegateLikeCall getCall() { result = dc } + + override DataFlowCallable getARuntimeTarget() { + none() // handled by the shared library } override ControlFlow::Nodes::ElementNode getControlFlowNode() { result = cfn } override DataFlow::ExprNode getNode() { result.getControlFlowNode() = cfn } - override Callable getEnclosingCallable() { result = cfn.getEnclosingCallable() } + override DataFlowCallable getEnclosingCallable() { result = cfn.getEnclosingCallable() } override string toString() { result = cfn.toString() } @@ -341,13 +326,13 @@ class TransitiveCapturedDataFlowCall extends DataFlowCall, TTransitiveCapturedCa TransitiveCapturedDataFlowCall() { this = TTransitiveCapturedCall(cfn, target) } - override Callable getARuntimeTarget() { result = target } + override DataFlowCallable getARuntimeTarget() { result = target } override ControlFlow::Nodes::ElementNode getControlFlowNode() { result = cfn } override DataFlow::ExprNode getNode() { none() } - override Callable getEnclosingCallable() { result = cfn.getEnclosingCallable() } + override DataFlowCallable getEnclosingCallable() { result = cfn.getEnclosingCallable() } override string toString() { result = "[transitive] " + cfn.toString() } @@ -369,7 +354,7 @@ class CilDataFlowCall extends DataFlowCall, TCilCall { override DataFlow::ExprNode getNode() { result.getExpr() = call } - override CIL::Callable getEnclosingCallable() { result = call.getEnclosingCallable() } + override DataFlowCallable getEnclosingCallable() { result = call.getEnclosingCallable() } override string toString() { result = call.toString() } @@ -377,32 +362,32 @@ class CilDataFlowCall extends DataFlowCall, TCilCall { } /** - * A delegate call inside a callable with a flow summary. + * A synthesized call inside a callable with a flow summary. * * For example, in `ints.Select(i => i + 1)` there is a call to the delegate at * parameter position `1` (counting the qualifier as the `0`th argument) inside * the method `Select`. */ -class SummaryDelegateCall extends DelegateDataFlowCall, TSummaryDelegateCall { +class SummaryCall extends DelegateDataFlowCall, TSummaryCall { private SummarizedCallable c; - private int pos; + private Node receiver; - SummaryDelegateCall() { this = TSummaryDelegateCall(c, pos) } + SummaryCall() { this = TSummaryCall(c, receiver) } - override DataFlowCallable getARuntimeTarget(CallContext::CallContext cc) { - exists(SummaryDelegateParameterSink p | - p.isParameterOf(c, pos) and - result = p.getARuntimeTarget(cc) - ) + /** Gets the data flow node that this call targets. */ + Node getReceiver() { result = receiver } + + override DataFlowCallable getARuntimeTarget() { + none() // handled by the shared library } override ControlFlow::Nodes::ElementNode getControlFlowNode() { none() } override DataFlow::Node getNode() { none() } - override Callable getEnclosingCallable() { result = c } + override DataFlowCallable getEnclosingCallable() { result = c } - override string toString() { result = "[summary] delegate call, parameter " + pos + " of " + c } + override string toString() { result = "[summary] call to " + receiver + " in " + c } override Location getLocation() { result = c.getLocation() } } diff --git a/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl.qll b/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl.qll index 8b446d28b86..9498e51e7e6 100644 --- a/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl.qll +++ b/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl.qll @@ -2133,11 +2133,8 @@ private module Stage4 { bindingset[node, cc, config] private LocalCc getLocalCc(Node node, Cc cc, Configuration config) { - exists(Cc cc0 | - cc = pragma[only_bind_into](cc0) and - localFlowEntry(node, config) and - result = getLocalCallContext(cc0, getNodeEnclosingCallable(node)) - ) + localFlowEntry(node, config) and + result = getLocalCallContext(pragma[only_bind_out](cc), getNodeEnclosingCallable(node)) } private predicate localStep( @@ -3132,7 +3129,7 @@ private predicate pathStep(PathNodeMid mid, Node node, CallContext cc, SummaryCt conf = mid.getConfiguration() and cc = mid.getCallContext() and sc = mid.getSummaryCtx() and - localCC = getLocalCallContext(cc, getNodeEnclosingCallable(midnode)) and + localCC = getLocalCallContext(pragma[only_bind_out](cc), getNodeEnclosingCallable(midnode)) and ap0 = mid.getAp() | localFlowBigStep(midnode, node, true, _, conf, localCC) and diff --git a/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl2.qll b/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl2.qll index 8b446d28b86..9498e51e7e6 100644 --- a/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl2.qll +++ b/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl2.qll @@ -2133,11 +2133,8 @@ private module Stage4 { bindingset[node, cc, config] private LocalCc getLocalCc(Node node, Cc cc, Configuration config) { - exists(Cc cc0 | - cc = pragma[only_bind_into](cc0) and - localFlowEntry(node, config) and - result = getLocalCallContext(cc0, getNodeEnclosingCallable(node)) - ) + localFlowEntry(node, config) and + result = getLocalCallContext(pragma[only_bind_out](cc), getNodeEnclosingCallable(node)) } private predicate localStep( @@ -3132,7 +3129,7 @@ private predicate pathStep(PathNodeMid mid, Node node, CallContext cc, SummaryCt conf = mid.getConfiguration() and cc = mid.getCallContext() and sc = mid.getSummaryCtx() and - localCC = getLocalCallContext(cc, getNodeEnclosingCallable(midnode)) and + localCC = getLocalCallContext(pragma[only_bind_out](cc), getNodeEnclosingCallable(midnode)) and ap0 = mid.getAp() | localFlowBigStep(midnode, node, true, _, conf, localCC) and diff --git a/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl3.qll b/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl3.qll index 8b446d28b86..9498e51e7e6 100644 --- a/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl3.qll +++ b/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl3.qll @@ -2133,11 +2133,8 @@ private module Stage4 { bindingset[node, cc, config] private LocalCc getLocalCc(Node node, Cc cc, Configuration config) { - exists(Cc cc0 | - cc = pragma[only_bind_into](cc0) and - localFlowEntry(node, config) and - result = getLocalCallContext(cc0, getNodeEnclosingCallable(node)) - ) + localFlowEntry(node, config) and + result = getLocalCallContext(pragma[only_bind_out](cc), getNodeEnclosingCallable(node)) } private predicate localStep( @@ -3132,7 +3129,7 @@ private predicate pathStep(PathNodeMid mid, Node node, CallContext cc, SummaryCt conf = mid.getConfiguration() and cc = mid.getCallContext() and sc = mid.getSummaryCtx() and - localCC = getLocalCallContext(cc, getNodeEnclosingCallable(midnode)) and + localCC = getLocalCallContext(pragma[only_bind_out](cc), getNodeEnclosingCallable(midnode)) and ap0 = mid.getAp() | localFlowBigStep(midnode, node, true, _, conf, localCC) and diff --git a/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl4.qll b/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl4.qll index 8b446d28b86..9498e51e7e6 100644 --- a/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl4.qll +++ b/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl4.qll @@ -2133,11 +2133,8 @@ private module Stage4 { bindingset[node, cc, config] private LocalCc getLocalCc(Node node, Cc cc, Configuration config) { - exists(Cc cc0 | - cc = pragma[only_bind_into](cc0) and - localFlowEntry(node, config) and - result = getLocalCallContext(cc0, getNodeEnclosingCallable(node)) - ) + localFlowEntry(node, config) and + result = getLocalCallContext(pragma[only_bind_out](cc), getNodeEnclosingCallable(node)) } private predicate localStep( @@ -3132,7 +3129,7 @@ private predicate pathStep(PathNodeMid mid, Node node, CallContext cc, SummaryCt conf = mid.getConfiguration() and cc = mid.getCallContext() and sc = mid.getSummaryCtx() and - localCC = getLocalCallContext(cc, getNodeEnclosingCallable(midnode)) and + localCC = getLocalCallContext(pragma[only_bind_out](cc), getNodeEnclosingCallable(midnode)) and ap0 = mid.getAp() | localFlowBigStep(midnode, node, true, _, conf, localCC) and diff --git a/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl5.qll b/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl5.qll index 8b446d28b86..9498e51e7e6 100644 --- a/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl5.qll +++ b/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl5.qll @@ -2133,11 +2133,8 @@ private module Stage4 { bindingset[node, cc, config] private LocalCc getLocalCc(Node node, Cc cc, Configuration config) { - exists(Cc cc0 | - cc = pragma[only_bind_into](cc0) and - localFlowEntry(node, config) and - result = getLocalCallContext(cc0, getNodeEnclosingCallable(node)) - ) + localFlowEntry(node, config) and + result = getLocalCallContext(pragma[only_bind_out](cc), getNodeEnclosingCallable(node)) } private predicate localStep( @@ -3132,7 +3129,7 @@ private predicate pathStep(PathNodeMid mid, Node node, CallContext cc, SummaryCt conf = mid.getConfiguration() and cc = mid.getCallContext() and sc = mid.getSummaryCtx() and - localCC = getLocalCallContext(cc, getNodeEnclosingCallable(midnode)) and + localCC = getLocalCallContext(pragma[only_bind_out](cc), getNodeEnclosingCallable(midnode)) and ap0 = mid.getAp() | localFlowBigStep(midnode, node, true, _, conf, localCC) and diff --git a/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImplCommon.qll b/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImplCommon.qll index 1319f972037..a51c20c2288 100644 --- a/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImplCommon.qll +++ b/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImplCommon.qll @@ -26,15 +26,243 @@ predicate accessPathCostLimits(int apLimit, int tupleLimit) { tupleLimit = 1000 } +/** + * Provides a simple data-flow analysis for resolving lambda calls. The analysis + * currently excludes read-steps, store-steps, and flow-through. + * + * The analysis uses non-linear recursion: When computing a flow path in or out + * of a call, we use the results of the analysis recursively to resolve lamba + * calls. For this reason, we cannot reuse the code from `DataFlowImpl.qll` directly. + */ +private module LambdaFlow { + private predicate viableParamNonLambda(DataFlowCall call, int i, ParameterNode p) { + p.isParameterOf(viableCallable(call), i) + } + + private predicate viableParamLambda(DataFlowCall call, int i, ParameterNode p) { + p.isParameterOf(viableCallableLambda(call, _), i) + } + + private predicate viableParamArgNonLambda(DataFlowCall call, ParameterNode p, ArgumentNode arg) { + exists(int i | + viableParamNonLambda(call, i, p) and + arg.argumentOf(call, i) + ) + } + + private predicate viableParamArgLambda(DataFlowCall call, ParameterNode p, ArgumentNode arg) { + exists(int i | + viableParamLambda(call, i, p) and + arg.argumentOf(call, i) + ) + } + + private newtype TReturnPositionSimple = + TReturnPositionSimple0(DataFlowCallable c, ReturnKind kind) { + exists(ReturnNode ret | + c = getNodeEnclosingCallable(ret) and + kind = ret.getKind() + ) + } + + pragma[noinline] + private TReturnPositionSimple getReturnPositionSimple(ReturnNode ret, ReturnKind kind) { + result = TReturnPositionSimple0(getNodeEnclosingCallable(ret), kind) + } + + pragma[nomagic] + private TReturnPositionSimple viableReturnPosNonLambda(DataFlowCall call, ReturnKind kind) { + result = TReturnPositionSimple0(viableCallable(call), kind) + } + + pragma[nomagic] + private TReturnPositionSimple viableReturnPosLambda( + DataFlowCall call, DataFlowCallOption lastCall, ReturnKind kind + ) { + result = TReturnPositionSimple0(viableCallableLambda(call, lastCall), kind) + } + + private predicate viableReturnPosOutNonLambda( + DataFlowCall call, TReturnPositionSimple pos, OutNode out + ) { + exists(ReturnKind kind | + pos = viableReturnPosNonLambda(call, kind) and + out = getAnOutNode(call, kind) + ) + } + + private predicate viableReturnPosOutLambda( + DataFlowCall call, DataFlowCallOption lastCall, TReturnPositionSimple pos, OutNode out + ) { + exists(ReturnKind kind | + pos = viableReturnPosLambda(call, lastCall, kind) and + out = getAnOutNode(call, kind) + ) + } + + /** + * Holds if data can flow (inter-procedurally) from `node` (of type `t`) to + * the lambda call `lambdaCall`. + * + * The parameter `toReturn` indicates whether the path from `node` to + * `lambdaCall` goes through a return, and `toJump` whether the path goes + * through a jump step. + * + * The call context `lastCall` records the last call on the path from `node` + * to `lambdaCall`, if any. That is, `lastCall` is able to target the enclosing + * callable of `lambdaCall`. + */ + pragma[nomagic] + predicate revLambdaFlow( + DataFlowCall lambdaCall, LambdaCallKind kind, Node node, DataFlowType t, boolean toReturn, + boolean toJump, DataFlowCallOption lastCall + ) { + revLambdaFlow0(lambdaCall, kind, node, t, toReturn, toJump, lastCall) and + if node instanceof CastNode or node instanceof ArgumentNode or node instanceof ReturnNode + then compatibleTypes(t, getNodeType(node)) + else any() + } + + pragma[nomagic] + predicate revLambdaFlow0( + DataFlowCall lambdaCall, LambdaCallKind kind, Node node, DataFlowType t, boolean toReturn, + boolean toJump, DataFlowCallOption lastCall + ) { + lambdaCall(lambdaCall, kind, node) and + t = getNodeType(node) and + toReturn = false and + toJump = false and + lastCall = TDataFlowCallNone() + or + // local flow + exists(Node mid, DataFlowType t0 | + revLambdaFlow(lambdaCall, kind, mid, t0, toReturn, toJump, lastCall) + | + simpleLocalFlowStep(node, mid) and + t = t0 + or + exists(boolean preservesValue | + additionalLambdaFlowStep(node, mid, preservesValue) and + getNodeEnclosingCallable(node) = getNodeEnclosingCallable(mid) + | + preservesValue = false and + t = getNodeType(node) + or + preservesValue = true and + t = t0 + ) + ) + or + // jump step + exists(Node mid, DataFlowType t0 | + revLambdaFlow(lambdaCall, kind, mid, t0, _, _, _) and + toReturn = false and + toJump = true and + lastCall = TDataFlowCallNone() + | + jumpStep(node, mid) and + t = t0 + or + exists(boolean preservesValue | + additionalLambdaFlowStep(node, mid, preservesValue) and + getNodeEnclosingCallable(node) != getNodeEnclosingCallable(mid) + | + preservesValue = false and + t = getNodeType(node) + or + preservesValue = true and + t = t0 + ) + ) + or + // flow into a callable + exists(ParameterNode p, DataFlowCallOption lastCall0, DataFlowCall call | + revLambdaFlowIn(lambdaCall, kind, p, t, toJump, lastCall0) and + ( + if lastCall0 = TDataFlowCallNone() and toJump = false + then lastCall = TDataFlowCallSome(call) + else lastCall = lastCall0 + ) and + toReturn = false + | + viableParamArgNonLambda(call, p, node) + or + viableParamArgLambda(call, p, node) // non-linear recursion + ) + or + // flow out of a callable + exists(TReturnPositionSimple pos | + revLambdaFlowOut(lambdaCall, kind, pos, t, toJump, lastCall) and + getReturnPositionSimple(node, node.(ReturnNode).getKind()) = pos and + toReturn = true + ) + } + + pragma[nomagic] + predicate revLambdaFlowOutLambdaCall( + DataFlowCall lambdaCall, LambdaCallKind kind, OutNode out, DataFlowType t, boolean toJump, + DataFlowCall call, DataFlowCallOption lastCall + ) { + revLambdaFlow(lambdaCall, kind, out, t, _, toJump, lastCall) and + exists(ReturnKindExt rk | + out = rk.getAnOutNode(call) and + lambdaCall(call, _, _) + ) + } + + pragma[nomagic] + predicate revLambdaFlowOut( + DataFlowCall lambdaCall, LambdaCallKind kind, TReturnPositionSimple pos, DataFlowType t, + boolean toJump, DataFlowCallOption lastCall + ) { + exists(DataFlowCall call, OutNode out | + revLambdaFlow(lambdaCall, kind, out, t, _, toJump, lastCall) and + viableReturnPosOutNonLambda(call, pos, out) + or + // non-linear recursion + revLambdaFlowOutLambdaCall(lambdaCall, kind, out, t, toJump, call, lastCall) and + viableReturnPosOutLambda(call, _, pos, out) + ) + } + + pragma[nomagic] + predicate revLambdaFlowIn( + DataFlowCall lambdaCall, LambdaCallKind kind, ParameterNode p, DataFlowType t, boolean toJump, + DataFlowCallOption lastCall + ) { + revLambdaFlow(lambdaCall, kind, p, t, false, toJump, lastCall) + } +} + +private DataFlowCallable viableCallableExt(DataFlowCall call) { + result = viableCallable(call) + or + result = viableCallableLambda(call, _) +} + cached private module Cached { + /** + * Gets a viable target for the lambda call `call`. + * + * `lastCall` records the call required to reach `call` in order for the result + * to be a viable target, if any. + */ + cached + DataFlowCallable viableCallableLambda(DataFlowCall call, DataFlowCallOption lastCall) { + exists(Node creation, LambdaCallKind kind | + LambdaFlow::revLambdaFlow(call, kind, creation, _, _, _, lastCall) and + lambdaCreation(creation, kind, result) + ) + } + /** * Holds if `p` is the `i`th parameter of a viable dispatch target of `call`. * The instance parameter is considered to have index `-1`. */ pragma[nomagic] private predicate viableParam(DataFlowCall call, int i, ParameterNode p) { - p.isParameterOf(viableCallable(call), i) + p.isParameterOf(viableCallableExt(call), i) } /** @@ -52,7 +280,7 @@ private module Cached { pragma[nomagic] private ReturnPosition viableReturnPos(DataFlowCall call, ReturnKindExt kind) { - viableCallable(call) = result.getCallable() and + viableCallableExt(call) = result.getCallable() and kind = result.getKind() } @@ -317,6 +545,35 @@ private module Cached { cached private module DispatchWithCallContext { + /** + * Holds if the set of viable implementations that can be called by `call` + * might be improved by knowing the call context. + */ + pragma[nomagic] + private predicate mayBenefitFromCallContextExt(DataFlowCall call, DataFlowCallable callable) { + mayBenefitFromCallContext(call, callable) + or + callable = call.getEnclosingCallable() and + exists(viableCallableLambda(call, TDataFlowCallSome(_))) + } + + /** + * Gets a viable dispatch target of `call` in the context `ctx`. This is + * restricted to those `call`s for which a context might make a difference. + */ + pragma[nomagic] + private DataFlowCallable viableImplInCallContextExt(DataFlowCall call, DataFlowCall ctx) { + result = viableImplInCallContext(call, ctx) + or + result = viableCallableLambda(call, TDataFlowCallSome(ctx)) + or + exists(DataFlowCallable enclosing | + mayBenefitFromCallContextExt(call, enclosing) and + enclosing = viableCallableExt(ctx) and + result = viableCallableLambda(call, TDataFlowCallNone()) + ) + } + /** * Holds if the call context `ctx` reduces the set of viable run-time * dispatch targets of call `call` in `c`. @@ -324,10 +581,10 @@ private module Cached { cached predicate reducedViableImplInCallContext(DataFlowCall call, DataFlowCallable c, DataFlowCall ctx) { exists(int tgts, int ctxtgts | - mayBenefitFromCallContext(call, c) and - c = viableCallable(ctx) and - ctxtgts = count(viableImplInCallContext(call, ctx)) and - tgts = strictcount(viableCallable(call)) and + mayBenefitFromCallContextExt(call, c) and + c = viableCallableExt(ctx) and + ctxtgts = count(viableImplInCallContextExt(call, ctx)) and + tgts = strictcount(viableCallableExt(call)) and ctxtgts < tgts ) } @@ -339,7 +596,7 @@ private module Cached { */ cached DataFlowCallable prunedViableImplInCallContext(DataFlowCall call, DataFlowCall ctx) { - result = viableImplInCallContext(call, ctx) and + result = viableImplInCallContextExt(call, ctx) and reducedViableImplInCallContext(call, _, ctx) } @@ -351,10 +608,10 @@ private module Cached { cached predicate reducedViableImplInReturn(DataFlowCallable c, DataFlowCall call) { exists(int tgts, int ctxtgts | - mayBenefitFromCallContext(call, _) and - c = viableCallable(call) and - ctxtgts = count(DataFlowCall ctx | c = viableImplInCallContext(call, ctx)) and - tgts = strictcount(DataFlowCall ctx | viableCallable(ctx) = call.getEnclosingCallable()) and + mayBenefitFromCallContextExt(call, _) and + c = viableCallableExt(call) and + ctxtgts = count(DataFlowCall ctx | c = viableImplInCallContextExt(call, ctx)) and + tgts = strictcount(DataFlowCall ctx | viableCallableExt(ctx) = call.getEnclosingCallable()) and ctxtgts < tgts ) } @@ -367,7 +624,7 @@ private module Cached { */ cached DataFlowCallable prunedViableImplInCallContextReverse(DataFlowCall call, DataFlowCall ctx) { - result = viableImplInCallContext(call, ctx) and + result = viableImplInCallContextExt(call, ctx) and reducedViableImplInReturn(result, call) } } @@ -481,6 +738,11 @@ private module Cached { TBooleanNone() or TBooleanSome(boolean b) { b = true or b = false } + cached + newtype TDataFlowCallOption = + TDataFlowCallNone() or + TDataFlowCallSome(DataFlowCall call) + cached newtype TTypedContent = MkTypedContent(Content c, DataFlowType t) { store(_, c, _, _, t) } @@ -777,7 +1039,7 @@ ReturnPosition getReturnPosition(ReturnNodeExt ret) { bindingset[cc, callable] predicate resolveReturn(CallContext cc, DataFlowCallable callable, DataFlowCall call) { - cc instanceof CallContextAny and callable = viableCallable(call) + cc instanceof CallContextAny and callable = viableCallableExt(call) or exists(DataFlowCallable c0, DataFlowCall call0 | call0.getEnclosingCallable() = callable and @@ -791,14 +1053,14 @@ DataFlowCallable resolveCall(DataFlowCall call, CallContext cc) { exists(DataFlowCall ctx | cc = TSpecificCall(ctx) | if reducedViableImplInCallContext(call, _, ctx) then result = prunedViableImplInCallContext(call, ctx) - else result = viableCallable(call) + else result = viableCallableExt(call) ) or - result = viableCallable(call) and cc instanceof CallContextSomeCall + result = viableCallableExt(call) and cc instanceof CallContextSomeCall or - result = viableCallable(call) and cc instanceof CallContextAny + result = viableCallableExt(call) and cc instanceof CallContextAny or - result = viableCallable(call) and cc instanceof CallContextReturn + result = viableCallableExt(call) and cc instanceof CallContextReturn } predicate read = readStep/3; @@ -812,6 +1074,19 @@ class BooleanOption extends TBooleanOption { } } +/** An optional `DataFlowCall`. */ +class DataFlowCallOption extends TDataFlowCallOption { + string toString() { + this = TDataFlowCallNone() and + result = "(none)" + or + exists(DataFlowCall call | + this = TDataFlowCallSome(call) and + result = call.toString() + ) + } +} + /** Content tagged with the type of a containing object. */ class TypedContent extends MkTypedContent { private Content c; diff --git a/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowPrivate.qll b/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowPrivate.qll index 5e3ac64f7c2..3b646973e28 100644 --- a/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowPrivate.qll +++ b/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowPrivate.qll @@ -5,7 +5,6 @@ private import DataFlowPublic private import DataFlowDispatch private import DataFlowImplCommon private import ControlFlowReachability -private import DelegateDataFlow private import FlowSummaryImpl as FlowSummaryImpl private import semmle.code.csharp.dataflow.FlowSummary private import semmle.code.csharp.Caching @@ -19,7 +18,6 @@ private import semmle.code.csharp.frameworks.EntityFramework private import semmle.code.csharp.frameworks.NHibernate private import semmle.code.csharp.frameworks.system.Collections private import semmle.code.csharp.frameworks.system.threading.Tasks -private import semmle.code.csharp.frameworks.system.linq.Expressions abstract class NodeImpl extends Node { /** Do not call: use `getEnclosingCallable()` instead. */ @@ -71,9 +69,6 @@ private class ExprNodeImpl extends ExprNode, NodeImpl { } } -/** A data-flow node used to interpret a flow summary. */ -abstract private class SummaryNodeImpl extends NodeImpl { } - /** Calculation of the relative order in which `this` references are read. */ private module ThisFlow { private class BasicBlock = ControlFlow::BasicBlock; @@ -292,8 +287,8 @@ module LocalFlow { */ private predicate localFlowSsaInput(Node nodeFrom, Ssa::Definition def, Ssa::Definition next) { exists(ControlFlow::BasicBlock bb, int i | SsaImpl::lastRefBeforeRedef(def, bb, i, next) | - def = nodeFrom.(SsaDefinitionNode).getDefinition() and - def.definesAt(_, bb, i) + def.definesAt(_, bb, i) and + def = getSsaDefinition(nodeFrom) or nodeFrom.asExprAtNode(bb.getNode(i)) instanceof AssignableRead ) @@ -380,7 +375,7 @@ module LocalFlow { * inter-procedurality or field-sensitivity. */ predicate excludeFromExposedRelations(Node n) { - n instanceof SummaryNodeImpl or + n instanceof SummaryNode or n instanceof ImplicitCapturedArgumentNode } } @@ -433,7 +428,7 @@ private class Argument extends Expr { this = dc.getQualifier() and arg = -1 and not dc.getAStaticTarget().(Modifiable).isStatic() ).getCall() or - this = call.(DelegateCall).getArgument(arg) + this = call.(DelegateLikeCall).getArgument(arg) } /** @@ -456,9 +451,9 @@ private predicate fieldOrPropertyStore(Expr e, Content c, Expr src, Expr q, bool f.isFieldLike() and f instanceof InstanceFieldOrProperty or - exists(ContentList cl | - FlowSummaryImpl::Private::summary(_, _, cl, _, _, _) and - cl.contains(f.getContent()) + exists(SummarizedCallable callable, FlowSummaryImpl::Public::SummaryComponentStack input | + callable.propagatesFlow(input, _, _) and + input.contains(SummaryComponent::content(f.getContent())) ) ) | @@ -612,8 +607,6 @@ private Gvn::GvnType getANonTypeParameterSubTypeRestricted(DataFlowType t) { /** A collection of cached types and predicates to be evaluated in the same stage. */ cached private module Cached { - private import FlowSummarySpecific as FlowSummarySpecific - cached newtype TNode = TExprNode(ControlFlow::Nodes::ElementNode cfn) { @@ -632,6 +625,9 @@ private module Cached { TYieldReturnNode(ControlFlow::Nodes::ElementNode cfn) { any(Callable c).canYieldReturn(cfn.getElement()) } or + TAsyncReturnNode(ControlFlow::Nodes::ElementNode cfn) { + any(Callable c | c.(Modifiable).isAsync()).canReturn(cfn.getElement()) + } or TImplicitCapturedArgumentNode(ControlFlow::Nodes::ElementNode cfn, LocalScopeVariable v) { exists(Ssa::ExplicitDefinition def | def.isCapturedVariableDefinitionFlowIn(_, cfn, _) | v = def.getSourceVariable().getAssignable() @@ -662,32 +658,8 @@ private module Cached { cfn.getElement() = fla.getQualifier() ) } or - TSummaryInternalNode( - SummarizedCallable c, FlowSummaryImpl::Private::SummaryInternalNodeState state - ) { - FlowSummaryImpl::Private::internalNodeRange(c, state) - } or - TSummaryReturnNode(SummarizedCallable c, ReturnKind rk) { - exists(SummaryOutput output | - FlowSummaryImpl::Private::summary(c, _, _, output, _, _) and - rk = FlowSummarySpecific::Private::toReturnKind(output) - ) - } or - TSummaryDelegateOutNode(SummarizedCallable c, int pos) { - exists(SummaryInput input | - FlowSummaryImpl::Private::summary(c, input, _, _, _, _) and - input = SummaryInput::delegate(pos) - ) - } or - TSummaryDelegateArgumentNode(SummarizedCallable c, int delegateIndex, int parameterIndex) { - exists(SummaryOutput output | - FlowSummaryImpl::Private::summary(c, _, _, output, _, _) and - output = SummaryOutput::delegate(delegateIndex, parameterIndex) - ) - } or - TSummaryJumpNode(SummarizedCallable c, SummarizableCallable target, ReturnKind rk) { - FlowSummaryImpl::Private::summary(c, _, _, - FlowSummarySpecific::Private::TJumpSummaryOutput(target, rk), _, _) + TSummaryNode(SummarizedCallable c, FlowSummaryImpl::Private::SummaryNodeState state) { + FlowSummaryImpl::Private::summaryNodeRange(c, state) } or TParamsArgumentNode(ControlFlow::Node callCfn) { callCfn = any(Call c | isParamsArg(c, _, _)).getAControlFlowNode() @@ -705,7 +677,7 @@ private module Cached { or LocalFlow::localFlowCapturedVarStep(nodeFrom, nodeTo) or - FlowSummaryImpl::Private::localStep(nodeFrom, nodeTo, true) + FlowSummaryImpl::Private::Steps::summaryLocalStep(nodeFrom, nodeTo, true) or nodeTo.(ObjectCreationNode).getPreUpdateNode() = nodeFrom.(ObjectInitializerNode) } @@ -725,7 +697,7 @@ private module Cached { or // Simple flow through library code is included in the exposed local // step relation, even though flow is technically inter-procedural - FlowSummaryImpl::Private::throughStep(nodeFrom, nodeTo, true) + FlowSummaryImpl::Private::Steps::summaryThroughStep(nodeFrom, nodeTo, true) } /** @@ -746,7 +718,11 @@ private module Cached { flr.hasNonlocalValue() ) or - succ = pred.(SummaryJumpNode).getAJumpTarget() + exists(JumpReturnKind jrk, DataFlowCall call | + FlowSummaryImpl::Private::summaryReturnNode(pred, jrk) and + viableCallable(call) = jrk.getTarget() and + succ = getAnOutNode(call, jrk.getTargetReturnKind()) + ) } cached @@ -783,7 +759,13 @@ private module Cached { c instanceof ElementContent ) or - FlowSummaryImpl::Private::storeStep(node1, c, node2) + exists(Expr e | + e = node1.asExpr() and + node2.(AsyncReturnNode).getExpr() = e and + c = getResultContent() + ) + or + FlowSummaryImpl::Private::Steps::summaryStoreStep(node1, c, node2) } pragma[nomagic] @@ -847,7 +829,7 @@ private module Cached { ) ) or - FlowSummaryImpl::Private::readStep(node1, c, node2) + FlowSummaryImpl::Private::Steps::summaryReadStep(node1, c, node2) } /** @@ -861,14 +843,10 @@ private module Cached { or fieldOrPropertyStore(_, c, _, n.(ObjectInitializerNode).getInitializer(), false) or - FlowSummaryImpl::Private::storeStep(n, c, _) and + FlowSummaryImpl::Private::Steps::summaryStoresIntoArg(c, n) and not c instanceof ElementContent or - exists(SummaryInput input, DataFlowCall call, int i | - FlowSummaryImpl::Private::clearsContent(input, call, c) and - input = SummaryInput::parameter(i) and - n.(ArgumentNode).argumentOf(call, i) - ) + FlowSummaryImpl::Private::Steps::summaryClearsContent(n, c) or exists(WithExpr we, ObjectInitializer oi, FieldOrProperty f | oi = we.getInitializer() and @@ -930,11 +908,24 @@ private module Cached { } cached - predicate qualifierOutNode(DataFlowCall call, Node n) { - n.(ExprPostUpdateNode).getPreUpdateNode().(ExplicitArgumentNode).argumentOf(call, -1) - or - any(ObjectOrCollectionInitializerConfiguration x) - .hasExprPath(_, n.(ExprNode).getControlFlowNode(), _, call.getControlFlowNode()) + predicate summaryOutNodeCached(DataFlowCall c, Node out, ReturnKind rk) { + FlowSummaryImpl::Private::summaryOutNode(c, out, rk) + } + + cached + predicate summaryArgumentNodeCached(DataFlowCall c, Node arg, int i) { + FlowSummaryImpl::Private::summaryArgumentNode(c, arg, i) + } + + cached + predicate summaryPostUpdateNodeCached(Node post, ParameterNode pre) { + FlowSummaryImpl::Private::summaryPostUpdateNode(post, pre) + } + + cached + predicate summaryReturnNodeCached(Node ret, ReturnKind rk) { + FlowSummaryImpl::Private::summaryReturnNode(ret, rk) and + not rk instanceof JumpReturnKind } cached @@ -960,13 +951,17 @@ private module Cached { not p.fromSource() ) or + n = TInstanceParameterNode(any(Callable c | not c.fromSource())) + or n instanceof YieldReturnNode or + n instanceof AsyncReturnNode + or n instanceof ImplicitCapturedArgumentNode or n instanceof MallocNode or - n instanceof SummaryNodeImpl + n instanceof SummaryNode or n instanceof ParamsArgumentNode or @@ -985,7 +980,7 @@ class SsaDefinitionNode extends NodeImpl, TSsaDefinitionNode { /** Gets the underlying SSA definition. */ Ssa::Definition getDefinition() { result = def } - override Callable getEnclosingCallableImpl() { result = def.getEnclosingCallable() } + override DataFlowCallable getEnclosingCallableImpl() { result = def.getEnclosingCallable() } override Type getTypeImpl() { result = def.getSourceVariable().getType() } @@ -996,9 +991,13 @@ class SsaDefinitionNode extends NodeImpl, TSsaDefinitionNode { override string toStringImpl() { result = def.toString() } } -private module ParameterNodes { - abstract private class ParameterNodeImpl extends ParameterNode, NodeImpl { } +abstract class ParameterNodeImpl extends NodeImpl { + abstract DotNet::Parameter getParameter(); + abstract predicate isParameterOf(DataFlowCallable c, int i); +} + +private module ParameterNodes { /** * The value of an explicit parameter at function entry, viewed as a node in a data * flow graph. @@ -1038,9 +1037,11 @@ private module ParameterNodes { /** Gets the callable containing this implicit instance parameter. */ Callable getCallable() { result = callable } + override DotNet::Parameter getParameter() { none() } + override predicate isParameterOf(DataFlowCallable c, int pos) { callable = c and pos = -1 } - override Callable getEnclosingCallableImpl() { result = callable } + override DataFlowCallable getEnclosingCallableImpl() { result = callable } override Type getTypeImpl() { result = callable.getDeclaringType() } @@ -1104,7 +1105,7 @@ private module ParameterNodes { * } } * ``` */ - class ImplicitCapturedParameterNode extends ParameterNode, SsaDefinitionNode { + class ImplicitCapturedParameterNode extends ParameterNodeImpl, SsaDefinitionNode { override SsaCapturedEntryDefinition def; ImplicitCapturedParameterNode() { def = this.getDefinition() } @@ -1112,6 +1113,8 @@ private module ParameterNodes { /** Gets the captured variable that this implicit parameter models. */ LocalScopeVariable getVariable() { result = def.getVariable() } + override DotNet::Parameter getParameter() { none() } + override predicate isParameterOf(DataFlowCallable c, int i) { i = getParameterPosition(def) and c = this.getEnclosingCallable() @@ -1213,7 +1216,7 @@ private module ArgumentNodes { ) } - override Callable getEnclosingCallableImpl() { result = cfn.getEnclosingCallable() } + override DataFlowCallable getEnclosingCallableImpl() { result = cfn.getEnclosingCallable() } override Type getTypeImpl() { result = v.getType() } @@ -1240,7 +1243,7 @@ private module ArgumentNodes { override ControlFlow::Node getControlFlowNodeImpl() { result = cfn } - override Callable getEnclosingCallableImpl() { result = cfn.getEnclosingCallable() } + override DataFlowCallable getEnclosingCallableImpl() { result = cfn.getEnclosingCallable() } override Type getTypeImpl() { result = cfn.getElement().(Expr).getType() } @@ -1277,7 +1280,7 @@ private module ArgumentNodes { pos = this.getParameter().getPosition() } - override Callable getEnclosingCallableImpl() { result = callCfn.getEnclosingCallable() } + override DataFlowCallable getEnclosingCallableImpl() { result = callCfn.getEnclosingCallable() } override Type getTypeImpl() { result = this.getParameter().getType() } @@ -1288,46 +1291,15 @@ private module ArgumentNodes { override string toStringImpl() { result = "[implicit array creation] " + callCfn } } - /** - * An argument node inside a callable with a flow summary, where the argument is - * passed to a supplied delegate. For example, in `ints.Select(Foo)` there is a - * node that represents the argument of the call to `Foo` inside `Select`. - */ - class SummaryDelegateArgumentNode extends ArgumentNode, SummaryNodeImpl, - TSummaryDelegateArgumentNode { - private SummarizedCallable c; - private int delegateIndex; - private int parameterIndex; + private class SummaryArgumentNode extends SummaryNode, ArgumentNode { + private DataFlowCall c; + private int i; - SummaryDelegateArgumentNode() { - this = TSummaryDelegateArgumentNode(c, delegateIndex, parameterIndex) - } - - override DataFlowCallable getEnclosingCallableImpl() { result = c } - - override DotNet::Type getTypeImpl() { - result = - c.getParameter(delegateIndex) - .getType() - .(SystemLinqExpressions::DelegateExtType) - .getDelegateType() - .getParameter(parameterIndex) - .getType() - } - - override ControlFlow::Node getControlFlowNodeImpl() { none() } - - override Location getLocationImpl() { result = c.getLocation() } - - override string toStringImpl() { - result = - "[summary] argument " + parameterIndex + " of delegate call, parameter " + parameterIndex + - " of " + c - } + SummaryArgumentNode() { summaryArgumentNodeCached(c, this, i) } override predicate argumentOf(DataFlowCall call, int pos) { - call = TSummaryDelegateCall(c, delegateIndex) and - pos = parameterIndex + call = c and + i = pos } } } @@ -1343,19 +1315,18 @@ abstract class ReturnNode extends Node { private module ReturnNodes { /** * A data-flow node that represents an expression returned by a callable, - * either using a (`yield`) `return` statement or an expression body (`=>`). + * either using a `return` statement or an expression body (`=>`). */ class ExprReturnNode extends ReturnNode, ExprNode { ExprReturnNode() { exists(DotNet::Callable c, DotNet::Expr e | e = this.getExpr() | - c.canReturn(e) - or - c.(Callable).canYieldReturn(e) + c.canReturn(e) and not c.(Modifiable).isAsync() ) } - override ReturnKind getKind() { - any(DotNet::Callable c).canReturn(this.getExpr()) and result instanceof NormalReturnKind + override NormalReturnKind getKind() { + any(DotNet::Callable c).canReturn(this.getExpr()) and + exists(result) } } @@ -1384,9 +1355,9 @@ private module ReturnNodes { YieldReturnStmt getYieldReturnStmt() { result = yrs } - override YieldReturnKind getKind() { any() } + override NormalReturnKind getKind() { any() } - override Callable getEnclosingCallableImpl() { result = yrs.getEnclosingCallable() } + override DataFlowCallable getEnclosingCallableImpl() { result = yrs.getEnclosingCallable() } override Type getTypeImpl() { result = yrs.getEnclosingCallable().getReturnType() } @@ -1397,6 +1368,30 @@ private module ReturnNodes { override string toStringImpl() { result = yrs.toString() } } + /** + * A synthesized `return` node for returned expressions inside `async` methods. + */ + class AsyncReturnNode extends ReturnNode, NodeImpl, TAsyncReturnNode { + private ControlFlow::Nodes::ElementNode cfn; + private Expr expr; + + AsyncReturnNode() { this = TAsyncReturnNode(cfn) and expr = cfn.getElement() } + + Expr getExpr() { result = expr } + + override NormalReturnKind getKind() { any() } + + override DataFlowCallable getEnclosingCallableImpl() { result = expr.getEnclosingCallable() } + + override Type getTypeImpl() { result = expr.getEnclosingCallable().getReturnType() } + + override ControlFlow::Node getControlFlowNodeImpl() { result = cfn } + + override Location getLocationImpl() { result = expr.getLocation() } + + override string toStringImpl() { result = expr.toString() } + } + /** * The value of a captured variable as an implicit return from a call, viewed * as a node in a data flow graph. @@ -1436,30 +1431,10 @@ private module ReturnNodes { } } - /** A return node for a callable with a flow summary. */ - class SummaryReturnNode extends ReturnNode, SummaryNodeImpl, TSummaryReturnNode { - private SummarizedCallable sc; + private class SummaryReturnNode extends SummaryNode, ReturnNode { private ReturnKind rk; - SummaryReturnNode() { this = TSummaryReturnNode(sc, rk) } - - override Callable getEnclosingCallableImpl() { result = sc } - - override DotNet::Type getTypeImpl() { - rk instanceof NormalReturnKind and - result in [sc.getReturnType(), sc.(Constructor).getDeclaringType()] - or - rk instanceof QualifierReturnKind and - result = sc.getDeclaringType() - or - result = sc.getParameter(rk.(OutRefReturnKind).getPosition()).getType() - } - - override ControlFlow::Node getControlFlowNodeImpl() { none() } - - override Location getLocationImpl() { result = sc.getLocation() } - - override string toStringImpl() { result = "[summary] return of kind " + rk + " inside " + sc } + SummaryReturnNode() { summaryReturnNodeCached(this, rk) } override ReturnKind getKind() { result = rk } } @@ -1483,21 +1458,6 @@ private module OutNodes { result = TExplicitDelegateLikeCall(cfn, e) } - /** A valid return type for a method that uses `yield return`. */ - private class YieldReturnType extends Type { - YieldReturnType() { - exists(Type t | t = this.getUnboundDeclaration() | - t instanceof SystemCollectionsIEnumerableInterface - or - t instanceof SystemCollectionsIEnumeratorInterface - or - t instanceof SystemCollectionsGenericIEnumerableTInterface - or - t instanceof SystemCollectionsGenericIEnumeratorInterface - ) - } - } - /** * A data-flow node that reads a value returned directly by a callable, * either via a C# call or a CIL call. @@ -1518,9 +1478,6 @@ private module OutNodes { ( kind instanceof NormalReturnKind and not call.getExpr().getType() instanceof VoidType - or - kind instanceof YieldReturnKind and - call.getExpr().getType() instanceof YieldReturnType ) } } @@ -1535,32 +1492,17 @@ private module OutNodes { ) { exactScope = false and scope = e1 and - isSuccessor = false and - ( + isSuccessor = true and + exists(ObjectOrCollectionInitializer init | init = e1.(ObjectCreation).getInitializer() | // E.g. `new Dictionary{ {0, "a"}, {1, "b"} }` - e1.(CollectionInitializer).getAnElementInitializer() = e2 + e2 = init.(CollectionInitializer).getAnElementInitializer() or // E.g. `new Dictionary() { [0] = "a", [1] = "b" }` - e1.(ObjectInitializer).getAMemberInitializer().getLValue() = e2 + e2 = init.(ObjectInitializer).getAMemberInitializer().getLValue() ) } } - /** - * A data-flow node that contains a value returned by a callable, by writing - * to the qualifier of the call. - */ - private class QualifierOutNode extends OutNode, Node { - private DataFlowCall call; - - QualifierOutNode() { qualifierOutNode(call, this) } - - override DataFlowCall getCall(ReturnKind kind) { - result = call and - kind instanceof QualifierReturnKind - } - } - /** * A data-flow node that reads a value returned implicitly by a callable * using a captured variable. @@ -1606,39 +1548,15 @@ private module OutNodes { } } - /** - * An output node inside a callable with a flow summary, where the output is the - * result of calling a supplied delegate. For example, in `ints.Select(Foo)` there - * is a node that represents the output of calling `Foo` inside `Select`. - */ - private class SummaryDelegateOutNode extends OutNode, SummaryNodeImpl, TSummaryDelegateOutNode { - private SummarizedCallable c; - private int pos; + private class SummaryOutNode extends SummaryNode, OutNode { + private DataFlowCall c; + private ReturnKind rk; - SummaryDelegateOutNode() { this = TSummaryDelegateOutNode(c, pos) } + SummaryOutNode() { summaryOutNodeCached(c, this, rk) } - override Callable getEnclosingCallableImpl() { result = c } - - override DotNet::Type getTypeImpl() { - result = - c.getParameter(pos) - .getType() - .(SystemLinqExpressions::DelegateExtType) - .getDelegateType() - .getReturnType() - } - - override ControlFlow::Node getControlFlowNodeImpl() { none() } - - override Location getLocationImpl() { result = c.getLocation() } - - override string toStringImpl() { - result = "[summary] output from delegate call, parameter " + pos + " of " + c + "]" - } - - override SummaryDelegateCall getCall(ReturnKind kind) { - result = TSummaryDelegateCall(c, pos) and - kind instanceof NormalReturnKind + override DataFlowCall getCall(ReturnKind kind) { + result = c and + kind = rk } } } @@ -1646,15 +1564,17 @@ private module OutNodes { import OutNodes /** A data-flow node used to model flow summaries. */ -private class SummaryInternalNode extends SummaryNodeImpl, TSummaryInternalNode { +private class SummaryNode extends NodeImpl, TSummaryNode { private SummarizedCallable c; - private FlowSummaryImpl::Private::SummaryInternalNodeState state; + private FlowSummaryImpl::Private::SummaryNodeState state; - SummaryInternalNode() { this = TSummaryInternalNode(c, state) } + SummaryNode() { this = TSummaryNode(c, state) } override DataFlowCallable getEnclosingCallableImpl() { result = c } - override DataFlowType getDataFlowType() { result = state.getType() } + override DataFlowType getDataFlowType() { + result = FlowSummaryImpl::Private::summaryNodeType(this) + } override DotNet::Type getTypeImpl() { none() } @@ -1665,28 +1585,6 @@ private class SummaryInternalNode extends SummaryNodeImpl, TSummaryInternalNode override string toStringImpl() { result = "[summary] " + state + " in " + c } } -/** A data-flow node used to model flow summaries with jumps. */ -private class SummaryJumpNode extends SummaryNodeImpl, TSummaryJumpNode { - private SummarizedCallable c; - private SummarizableCallable target; - private ReturnKind rk; - - SummaryJumpNode() { this = TSummaryJumpNode(c, target, rk) } - - /** Gets a jump target of this node. */ - OutNode getAJumpTarget() { target = viableCallable(result.getCall(rk)) } - - override Callable getEnclosingCallableImpl() { result = c } - - override DotNet::Type getTypeImpl() { result = target.getReturnType() } - - override ControlFlow::Node getControlFlowNodeImpl() { none() } - - override Location getLocationImpl() { result = c.getLocation() } - - override string toStringImpl() { result = "[summary] jump to " + target } -} - /** A field or a property. */ class FieldOrProperty extends Assignable, Modifiable { FieldOrProperty() { @@ -1921,7 +1819,7 @@ private module PostUpdateNodes { * Such a node acts as both a post-update node for the `MallocNode`, as well as * a pre-update node for the `ObjectCreationNode`. */ - class ObjectInitializerNode extends PostUpdateNode, NodeImpl, TObjectInitializerNode { + class ObjectInitializerNode extends PostUpdateNode, NodeImpl, ArgumentNode, TObjectInitializerNode { private ObjectCreation oc; private ControlFlow::Nodes::ElementNode cfn; @@ -1935,7 +1833,13 @@ private module PostUpdateNodes { override MallocNode getPreUpdateNode() { result.getControlFlowNode() = cfn } - override Callable getEnclosingCallableImpl() { result = cfn.getEnclosingCallable() } + override predicate argumentOf(DataFlowCall call, int pos) { + pos = -1 and + any(ObjectOrCollectionInitializerConfiguration x) + .hasExprPath(_, cfn, _, call.getControlFlowNode()) + } + + override DataFlowCallable getEnclosingCallableImpl() { result = cfn.getEnclosingCallable() } override DotNet::Type getTypeImpl() { result = oc.getType() } @@ -1953,7 +1857,7 @@ private module PostUpdateNodes { override ExprNode getPreUpdateNode() { cfn = result.getControlFlowNode() } - override Callable getEnclosingCallableImpl() { result = cfn.getEnclosingCallable() } + override DataFlowCallable getEnclosingCallableImpl() { result = cfn.getEnclosingCallable() } override Type getTypeImpl() { result = cfn.getElement().(Expr).getType() } @@ -1963,6 +1867,14 @@ private module PostUpdateNodes { override string toStringImpl() { result = "[post] " + cfn.toString() } } + + private class SummaryPostUpdateNode extends SummaryNode, PostUpdateNode { + private Node pre; + + SummaryPostUpdateNode() { summaryPostUpdateNodeCached(this, pre) } + + override Node getPreUpdateNode() { result = pre } + } } private import PostUpdateNodes @@ -2022,3 +1934,69 @@ class Unit extends TUnit { * This predicate is only used for consistency checks. */ predicate isImmutableOrUnobservable(Node n) { none() } + +class LambdaCallKind = Unit; + +/** Holds if `creation` is an expression that creates a delegate for `c`. */ +predicate lambdaCreation(ExprNode creation, LambdaCallKind kind, DataFlowCallable c) { + exists(Expr e | e = creation.getExpr() | + c = e.(AnonymousFunctionExpr) + or + c = e.(CallableAccess).getTarget().getUnboundDeclaration() + or + c = e.(AddressOfExpr).getOperand().(CallableAccess).getTarget().getUnboundDeclaration() + ) and + kind = TMkUnit() +} + +private class LambdaConfiguration extends ControlFlowReachabilityConfiguration { + LambdaConfiguration() { this = "LambdaConfiguration" } + + override predicate candidate( + Expr e1, Expr e2, ControlFlowElement scope, boolean exactScope, boolean isSuccessor + ) { + e1 = e2.(DelegateLikeCall).getExpr() and + exactScope = false and + scope = e2 and + isSuccessor = true + or + e1 = e2.(DelegateCreation).getArgument() and + exactScope = false and + scope = e2 and + isSuccessor = true + } +} + +/** Holds if `call` is a lambda call where `receiver` is the lambda expression. */ +predicate lambdaCall(DataFlowCall call, LambdaCallKind kind, Node receiver) { + ( + exists(LambdaConfiguration x, DelegateLikeCall dc | + x.hasExprPath(dc.getExpr(), receiver.(ExprNode).getControlFlowNode(), dc, + call.getControlFlowNode()) + ) + or + receiver = call.(SummaryCall).getReceiver() + ) and + kind = TMkUnit() +} + +/** Extra data-flow steps needed for lamba flow analysis. */ +predicate additionalLambdaFlowStep(Node nodeFrom, Node nodeTo, boolean preservesValue) { + exists(Ssa::Definition def | + LocalFlow::localSsaFlowStep(def, nodeFrom, nodeTo) and + LocalFlow::usesInstanceField(def) and + preservesValue = true + ) + or + exists(LambdaConfiguration x, DelegateCreation dc | + x.hasExprPath(dc.getArgument(), nodeFrom.(ExprNode).getControlFlowNode(), dc, + nodeTo.(ExprNode).getControlFlowNode()) and + preservesValue = false + ) + or + exists(AddEventExpr aee | + nodeFrom.asExpr() = aee.getRValue() and + nodeTo.asExpr().(EventRead).getTarget() = aee.getTarget() and + preservesValue = false + ) +} diff --git a/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowPublic.qll b/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowPublic.qll index 13ca7658240..dd6e72d54f6 100644 --- a/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowPublic.qll +++ b/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowPublic.qll @@ -47,14 +47,14 @@ class Node extends TNode { cached final DataFlowCallable getEnclosingCallable() { Stages::DataFlowStage::forceCachingInSameStage() and - result = unique(DataFlowCallable c | c = this.(NodeImpl).getEnclosingCallableImpl() | c) + result = this.(NodeImpl).getEnclosingCallableImpl() } /** Gets the control flow node corresponding to this node, if any. */ cached final ControlFlow::Node getControlFlowNode() { Stages::DataFlowStage::forceCachingInSameStage() and - result = unique(ControlFlow::Node n | n = this.(NodeImpl).getControlFlowNodeImpl() | n) + result = this.(NodeImpl).getControlFlowNodeImpl() } /** Gets a textual representation of this node. */ @@ -117,22 +117,18 @@ class ExprNode extends Node { * flow graph. */ class ParameterNode extends Node { - ParameterNode() { - // charpred needed to avoid making `ParameterNode` abstract - this = TExplicitParameterNode(_) or - this.(SsaDefinitionNode).getDefinition() instanceof - ImplicitCapturedParameterNodeImpl::SsaCapturedEntryDefinition or - this = TInstanceParameterNode(_) - } + private ParameterNodeImpl p; + + ParameterNode() { this = p } /** Gets the parameter corresponding to this node, if any. */ - DotNet::Parameter getParameter() { none() } + DotNet::Parameter getParameter() { result = p.getParameter() } /** * Holds if this node is the parameter of callable `c` at the specified * (zero-based) position. */ - predicate isParameterOf(DataFlowCallable c, int i) { none() } + predicate isParameterOf(DataFlowCallable c, int i) { p.isParameterOf(c, i) } } /** A definition, viewed as a node in a data flow graph. */ @@ -236,7 +232,7 @@ class FieldContent extends Content, TFieldContent { /** Gets the field that is referenced. */ Field getField() { result = f } - override string toString() { result = f.toString() } + override string toString() { result = "field " + f.getName() } override Location getLocation() { result = f.getLocation() } @@ -256,7 +252,7 @@ class PropertyContent extends Content, TPropertyContent { /** Gets the property that is referenced. */ Property getProperty() { result = p } - override string toString() { result = p.toString() } + override string toString() { result = "property " + p.getName() } override Location getLocation() { result = p.getLocation() } @@ -269,7 +265,7 @@ class PropertyContent extends Content, TPropertyContent { /** A reference to an element in a collection. */ class ElementContent extends Content, TElementContent { - override string toString() { result = "[]" } + override string toString() { result = "element" } override Location getLocation() { result instanceof EmptyLocation } } diff --git a/csharp/ql/src/semmle/code/csharp/dataflow/internal/DelegateDataFlow.qll b/csharp/ql/src/semmle/code/csharp/dataflow/internal/DelegateDataFlow.qll index e6b15b95d7f..df6f62a3975 100755 --- a/csharp/ql/src/semmle/code/csharp/dataflow/internal/DelegateDataFlow.qll +++ b/csharp/ql/src/semmle/code/csharp/dataflow/internal/DelegateDataFlow.qll @@ -1,4 +1,6 @@ /** + * DEPRECATED. + * * INTERNAL: Do not use. * * Provides classes for resolving delegate calls. @@ -108,7 +110,7 @@ abstract private class DelegateLikeFlowSink extends DataFlow::Node { * possible delegates resolved on line 6. */ cached - Callable getARuntimeTarget(CallContext context) { + deprecated Callable getARuntimeTarget(CallContext context) { exists(DelegateLikeFlowSource dfs | flowsFrom(this, dfs, _, context) and result = dfs.getCallable() @@ -117,7 +119,7 @@ abstract private class DelegateLikeFlowSink extends DataFlow::Node { } /** A delegate or function pointer call expression. */ -class DelegateLikeCallExpr extends DelegateLikeFlowSink, DataFlow::ExprNode { +deprecated class DelegateLikeCallExpr extends DelegateLikeFlowSink, DataFlow::ExprNode { DelegateLikeCall dc; DelegateLikeCallExpr() { this.getExpr() = dc.getExpr() } @@ -126,16 +128,8 @@ class DelegateLikeCallExpr extends DelegateLikeFlowSink, DataFlow::ExprNode { DelegateLikeCall getCall() { result = dc } } -/** A parameter of delegate type belonging to a callable with a flow summary. */ -class SummaryDelegateParameterSink extends DelegateLikeFlowSink, ParameterNode { - SummaryDelegateParameterSink() { - this.getType() instanceof SystemLinqExpressions::DelegateExtType and - this.isParameterOf(any(SummarizedCallable c), _) - } -} - /** A delegate expression that is added to an event. */ -class AddEventSource extends DelegateLikeFlowSink, DataFlow::ExprNode { +deprecated class AddEventSource extends DelegateLikeFlowSink, DataFlow::ExprNode { AddEventExpr ae; AddEventSource() { this.getExpr() = ae.getRValue() } @@ -173,7 +167,7 @@ private class NormalReturnNode extends Node { * `node` goes through a returned expression. The call context `lastCall` * records the last call on the path from `node` to `sink`, if any. */ -private predicate flowsFrom( +deprecated private predicate flowsFrom( DelegateLikeFlowSink sink, DataFlow::Node node, boolean isReturned, CallContext lastCall ) { // Base case @@ -244,7 +238,7 @@ private predicate flowsFrom( * previous call if it exists, otherwise `call` is the last call. */ bindingset[call, i] -private CallContext getLastCall(CallContext prevLastCall, Expr call, int i) { +deprecated private CallContext getLastCall(CallContext prevLastCall, Expr call, int i) { prevLastCall instanceof EmptyCallContext and result.(ArgumentCallContext).isArgument(call, i) or @@ -263,7 +257,7 @@ private predicate flowIntoNonDelegateCall(NonDelegateCall call, Expr arg, DotNet } pragma[noinline] -private predicate flowIntoDelegateCall(DelegateLikeCall call, Callable c, Expr arg, int i) { +deprecated private predicate flowIntoDelegateCall(DelegateLikeCall call, Callable c, Expr arg, int i) { exists(DelegateLikeFlowSource dfs, DelegateLikeCallExpr dce | // the call context is irrelevant because the delegate call // itself will be the context @@ -280,7 +274,7 @@ private predicate flowOutOfNonDelegateCall(NonDelegateCall call, NormalReturnNod } pragma[noinline] -private predicate flowOutOfDelegateCall( +deprecated private predicate flowOutOfDelegateCall( DelegateLikeCall dc, NormalReturnNode ret, CallContext lastCall ) { exists(DelegateLikeFlowSource dfs, DelegateLikeCallExpr dce, Callable c | diff --git a/csharp/ql/src/semmle/code/csharp/dataflow/internal/FlowSummaryImpl.qll b/csharp/ql/src/semmle/code/csharp/dataflow/internal/FlowSummaryImpl.qll index 2a258d04f2e..3c8c94c913c 100644 --- a/csharp/ql/src/semmle/code/csharp/dataflow/internal/FlowSummaryImpl.qll +++ b/csharp/ql/src/semmle/code/csharp/dataflow/internal/FlowSummaryImpl.qll @@ -1,127 +1,174 @@ /** - * Provides classes and predicates for definining flow summaries. + * Provides classes and predicates for defining flow summaries. * - * The definitions in this file are language-independant, and language-specific - * definitions are passed in via the `FlowSummarySpecific` module. + * The definitions in this file are language-independent, and language-specific + * definitions are passed in via the `DataFlowImplSpecific` and + * `FlowSummaryImplSpecific` modules. */ -private import FlowSummarySpecific::Private +private import FlowSummaryImplSpecific +private import DataFlowImplSpecific::Private +private import DataFlowImplSpecific::Public -/** - * Provides classes and predicates for definining flow summaries. - */ +/** Provides classes and predicates for defining flow summaries. */ module Public { - import FlowSummarySpecific::Public + private import Private - private newtype TContentList = - TNilContentList() or - TConsContentList(Content head, ContentList tail) { - tail = TNilContentList() + /** + * A component used in a flow summary. + * + * Either a parameter or an argument at a given position, a specific + * content type, or a return kind. + */ + class SummaryComponent extends TSummaryComponent { + /** Gets a textual representation of this summary component. */ + string toString() { + exists(Content c | this = TContentSummaryComponent(c) and result = c.toString()) or - any(SummarizedCallable c).requiresContentList(head, tail) and - tail.length() < accessPathLimit() + exists(int i | this = TParameterSummaryComponent(i) and result = "parameter " + i) + or + exists(int i | this = TArgumentSummaryComponent(i) and result = "argument " + i) + or + exists(ReturnKind rk | this = TReturnSummaryComponent(rk) and result = "return (" + rk + ")") + } + } + + /** Provides predicates for constructing summary components. */ + module SummaryComponent { + /** Gets a summary component for content `c`. */ + SummaryComponent content(Content c) { result = TContentSummaryComponent(c) } + + /** Gets a summary component for parameter `i`. */ + SummaryComponent parameter(int i) { result = TParameterSummaryComponent(i) } + + /** Gets a summary component for argument `i`. */ + SummaryComponent argument(int i) { result = TArgumentSummaryComponent(i) } + + /** Gets a summary component for a return of kind `rk`. */ + SummaryComponent return(ReturnKind rk) { result = TReturnSummaryComponent(rk) } + } + + /** + * A (non-empty) stack of summary components. + * + * A stack is used to represent where data is read from (input) or where it + * is written to (output). For example, an input stack `[Field f, Argument 0]` + * means that data is read from field `f` from the `0`th argument, while an + * output stack `[Field g, Return]` means that data is written to the field + * `g` of the returned object. + */ + class SummaryComponentStack extends TSummaryComponentStack { + /** Gets the head of this stack. */ + SummaryComponent head() { + this = TSingletonSummaryComponentStack(result) or + this = TConsSummaryComponentStack(result, _) } - /** A content list. */ - class ContentList extends TContentList { - /** Gets the head of this content list, if any. */ - Content head() { this = TConsContentList(result, _) } + /** Gets the tail of this stack, if any. */ + SummaryComponentStack tail() { this = TConsSummaryComponentStack(_, result) } - /** Gets the tail of this content list, if any. */ - ContentList tail() { this = TConsContentList(_, result) } - - /** Gets the length of this content list. */ + /** Gets the length of this stack. */ int length() { - this = TNilContentList() and result = 0 + this = TSingletonSummaryComponentStack(_) and result = 1 or result = 1 + this.tail().length() } - /** Gets the content list obtained by dropping the first `i` elements, if any. */ - ContentList drop(int i) { + /** Gets the stack obtained by dropping the first `i` elements, if any. */ + SummaryComponentStack drop(int i) { i = 0 and result = this or result = this.tail().drop(i - 1) } - /** Holds if this content list contains content `c`. */ - predicate contains(Content c) { c = this.drop(_).head() } + /** Holds if this stack contains summary component `c`. */ + predicate contains(SummaryComponent c) { c = this.drop(_).head() } - /** Gets a textual representation of this content list. */ + /** Gets a textual representation of this stack. */ string toString() { - exists(Content head, ContentList tail | + exists(SummaryComponent head, SummaryComponentStack tail | head = this.head() and tail = this.tail() and - if tail.length() = 0 then result = head.toString() else result = head + ", " + tail + result = head + " of " + tail ) or - this = TNilContentList() and - result = "" + exists(SummaryComponent c | + this = TSingletonSummaryComponentStack(c) and + result = c.toString() + ) } } - /** Provides predicates for constructing content lists. */ - module ContentList { - /** Gets the empty content list. */ - ContentList empty() { result = TNilContentList() } + /** Provides predicates for constructing stacks of summary components. */ + module SummaryComponentStack { + /** Gets a singleton stack containing `c`. */ + SummaryComponentStack singleton(SummaryComponent c) { + result = TSingletonSummaryComponentStack(c) + } - /** Gets a singleton content list containing `c`. */ - ContentList singleton(Content c) { result = TConsContentList(c, TNilContentList()) } - - /** Gets the content list obtained by consing `head` onto `tail`. */ - ContentList cons(Content head, ContentList tail) { result = TConsContentList(head, tail) } - } - - /** A callable with flow summaries. */ - abstract class SummarizedCallable extends SummarizableCallable { /** - * Holds if data may flow from `input` to `output` through this callable. + * Gets the stack obtained by pushing `head` onto `tail`. * - * `preservesValue` indicates whether this is a value-preserving step - * or a taint-step. + * Make sure to override `RequiredSummaryComponentStack::required()` in order + * to ensure that the constructed stack exists. */ - pragma[nomagic] - predicate propagatesFlow(SummaryInput input, SummaryOutput output, boolean preservesValue) { - none() + SummaryComponentStack push(SummaryComponent head, SummaryComponentStack tail) { + result = TConsSummaryComponentStack(head, tail) } + /** Gets a singleton stack for argument `i`. */ + SummaryComponentStack argument(int i) { result = singleton(SummaryComponent::argument(i)) } + + /** Gets a singleton stack representing a return of kind `rk`. */ + SummaryComponentStack return(ReturnKind rk) { result = singleton(SummaryComponent::return(rk)) } + } + + /** + * A class that exists for QL technical reasons only (the IPA type used + * to represent component stacks needs to be bounded). + */ + abstract class RequiredSummaryComponentStack extends SummaryComponentStack { + /** + * Holds if the stack obtained by pushing `head` onto `tail` is required. + */ + abstract predicate required(SummaryComponent c); + } + + /** A callable with a flow summary. */ + abstract class SummarizedCallable extends DataFlowCallable { /** * Holds if data may flow from `input` to `output` through this callable. * - * `inputContents` describes the contents that is popped from the access - * path from the input and `outputContents` describes the contents that - * is pushed onto the resulting access path. - * * `preservesValue` indicates whether this is a value-preserving step * or a taint-step. + * + * Input specifications are restricted to stacks that end with + * `SummaryComponent::argument(_)`, preceded by zero or more + * `SummaryComponent::return(_)` or `SummaryComponent::content(_)` components. + * + * Output specifications are restricted to stacks that end with + * `SummaryComponent::return(_)` or `SummaryComponent::argument(_)`. + * + * Output stacks ending with `SummaryComponent::return(_)` can be preceded by zero + * or more `SummaryComponent::content(_)` components. + * + * Output stacks ending with `SummaryComponent::argument(_)` can be preceded by an + * optional `SummaryComponent::parameter(_)` component, which in turn can be preceded + * by zero or more `SummaryComponent::content(_)` components. */ pragma[nomagic] predicate propagatesFlow( - SummaryInput input, ContentList inputContents, SummaryOutput output, - ContentList outputContents, boolean preservesValue + SummaryComponentStack input, SummaryComponentStack output, boolean preservesValue ) { none() } - /** - * Holds if the content list obtained by consing `head` onto `tail` is needed - * for a summary specified by `propagatesFlow()`. - * - * This predicate is needed for QL technical reasons only (the IPA type used - * to represent content lists needs to be bounded). - * - * Only summaries using content lists of length >= 2 need to override this - * predicate. - */ - pragma[nomagic] - predicate requiresContentList(Content head, ContentList tail) { none() } - /** * Holds if values stored inside `content` are cleared on objects passed as - * arguments of type `input` to this callable. + * the `i`th argument to this callable. */ pragma[nomagic] - predicate clearsContent(SummaryInput input, Content content) { none() } + predicate clearsContent(int i, Content content) { none() } } } @@ -131,340 +178,497 @@ module Public { */ module Private { private import Public - private import DataFlowDispatch - private import FlowSummarySpecific::Public + private import DataFlowImplCommon as DataFlowImplCommon + + newtype TSummaryComponent = + TContentSummaryComponent(Content c) or + TParameterSummaryComponent(int i) { parameterPosition(i) } or + TArgumentSummaryComponent(int i) { parameterPosition(i) } or + TReturnSummaryComponent(ReturnKind rk) + + newtype TSummaryComponentStack = + TSingletonSummaryComponentStack(SummaryComponent c) or + TConsSummaryComponentStack(SummaryComponent head, SummaryComponentStack tail) { + tail.(RequiredSummaryComponentStack).required(head) + } - /** - * Holds if data may flow from `input` to `output` when calling `c`. - * - * `inputContents` describes the contents that is popped from the access - * path from the input and `outputContents` describes the contents that - * is pushed onto the resulting access path. - * - * `preservesValue` indicates whether this is a value-preserving step - * or a taint-step. - */ pragma[nomagic] - predicate summary( - SummarizedCallable c, SummaryInput input, ContentList inputContents, SummaryOutput output, - ContentList outputContents, boolean preservesValue + private predicate summary( + SummarizedCallable c, SummaryComponentStack input, SummaryComponentStack output, + boolean preservesValue ) { - c.propagatesFlow(input, output, preservesValue) and - inputContents = ContentList::empty() and - outputContents = ContentList::empty() - or - c.propagatesFlow(input, inputContents, output, outputContents, preservesValue) + c.propagatesFlow(input, output, preservesValue) } - /** Gets the `i`th element in `l`. */ - pragma[noinline] - private Content getContent(ContentList l, int i) { result = l.drop(i).head() } - - private newtype TContentListRev = - TConsNilContentListRev(Content c) or - TConsContentListRev(Content head, ContentListRev tail) { - exists(ContentList l, int i | - tail = reverse(l, i) and - head = getContent(l, i) - ) - } - - /** - * Gets the reversed content list that contains the `i` first elements of `l` - * in reverse order. - */ - private ContentListRev reverse(ContentList l, int i) { - exists(Content head | - result = TConsNilContentListRev(head) and - head = l.head() and - i = 1 - or - exists(ContentListRev tail | - result = TConsContentListRev(head, tail) and - tail = reverse(l, i - 1) and - head = getContent(l, i - 1) - ) - ) - } - - /** A reversed, non-empty content list. */ - private class ContentListRev extends TContentListRev { - /** Gets the head of this reversed content list. */ - Content head() { - this = TConsNilContentListRev(result) or this = TConsContentListRev(result, _) - } - - /** Gets the tail of this reversed content list, if any. */ - ContentListRev tail() { this = TConsContentListRev(_, result) } - - /** Gets the length of this reversed content list. */ - int length() { - this = TConsNilContentListRev(_) and result = 1 - or - result = 1 + this.tail().length() - } - - /** Gets a textual representation of this reversed content list. */ - string toString() { - exists(Content head | - this = TConsNilContentListRev(head) and - result = head.toString() - or - exists(ContentListRev tail | - head = this.head() and - tail = this.tail() and - result = head + ", " + tail - ) - ) - } - } - - private newtype TSummaryInternalNodeState = - TSummaryInternalNodeReadState(SummaryInput input, ContentListRev l) { - exists(ContentList inputContents | - summary(_, input, inputContents, _, _, _) and - l = reverse(inputContents, _) + private newtype TSummaryNodeState = + TSummaryNodeInputState(SummaryComponentStack s) { + exists(SummaryComponentStack input | + summary(_, input, _, _) and + s = input.drop(_) ) } or - TSummaryInternalNodeStoreState(SummaryOutput output, ContentListRev l) { - exists(ContentList outputContents | - summary(_, _, _, output, outputContents, _) and - l = reverse(outputContents, _) + TSummaryNodeOutputState(SummaryComponentStack s) { + exists(SummaryComponentStack output | + summary(_, _, output, _) and + s = output.drop(_) ) } /** * A state used to break up (complex) flow summaries into atomic flow steps. - * For a flow summary with input `input`, input contents `inputContents`, output - * `output`, and output contents `outputContents`, the following states are used: + * For a flow summary * - * - `TSummaryInternalNodeReadState(SummaryInput input, ContentListRev l)`: - * this state represents that the contents in `l` has been read from `input`, - * where `l` is a reversed, non-empty suffix of `inputContents`. - * - `TSummaryInternalNodeStoreState(SummaryOutput output, ContentListRev l)`: - * this state represents that the contents of `l` remains to be stored into - * `output`, where `l` is a reversed, non-empty suffix of `outputContents`. + * ```ql + * propagatesFlow( + * SummaryComponentStack input, SummaryComponentStack output, boolean preservesValue + * ) + * ``` + * + * the following states are used: + * + * - `TSummaryNodeInputState(SummaryComponentStack s)`: + * this state represents that the components in `s` _have been read_ from the + * input. + * - `TSummaryNodeOutputState(SummaryComponentStack s)`: + * this state represents that the components in `s` _remain to be written_ to + * the output. */ - class SummaryInternalNodeState extends TSummaryInternalNodeState { - /** - * Holds if this state represents that the `i` first elements of `inputContents` - * have been read from `input` in `c`. - */ + class SummaryNodeState extends TSummaryNodeState { + /** Holds if this state is a valid input state for `c`. */ pragma[nomagic] - predicate isReadState(SummarizedCallable c, SummaryInput input, ContentList inputContents, int i) { - this = TSummaryInternalNodeReadState(input, reverse(inputContents, i)) and - summary(c, input, inputContents, _, _, _) + predicate isInputState(SummarizedCallable c, SummaryComponentStack s) { + this = TSummaryNodeInputState(s) and + exists(SummaryComponentStack input | + summary(c, input, _, _) and + s = input.drop(_) + ) } - /** - * Holds if this state represents that the `i` first elements of `outputContents` - * remain to be stored into `output` in `c`. - */ + /** Holds if this state is a valid output state for `c`. */ pragma[nomagic] - predicate isStoreState( - SummarizedCallable c, SummaryOutput output, ContentList outputContents, int i - ) { - this = TSummaryInternalNodeStoreState(output, reverse(outputContents, i)) and - summary(c, _, _, output, outputContents, _) - } - - /** Gets the type of a node in this state. */ - DataFlowType getType() { - exists(ContentListRev l | result = getContentType(l.head()) | - this = TSummaryInternalNodeReadState(_, l) - or - this = TSummaryInternalNodeStoreState(_, l) + predicate isOutputState(SummarizedCallable c, SummaryComponentStack s) { + this = TSummaryNodeOutputState(s) and + exists(SummaryComponentStack output | + summary(c, _, output, _) and + s = output.drop(_) ) } /** Gets a textual representation of this state. */ string toString() { - exists(SummaryInput input, ContentListRev l | - this = TSummaryInternalNodeReadState(input, l) and - result = "input: " + input + ", read: " + l + exists(SummaryComponentStack s | + this = TSummaryNodeInputState(s) and + result = "read: " + s ) or - exists(SummaryOutput output, ContentListRev l | - this = TSummaryInternalNodeStoreState(output, l) and - result = "output: " + output + ", to store: " + l + exists(SummaryComponentStack s | + this = TSummaryNodeOutputState(s) and + result = "to write: " + s ) } } /** - * Holds if an internal summary node is needed for the state `state` in summarized + * Holds if `state` represents having read the `i`th argument for `c`. In this case + * we are not synthesizing a data-flow node, but instead assume that a relevant + * parameter node already exists. + */ + private predicate parameterReadState(SummarizedCallable c, SummaryNodeState state, int i) { + state.isInputState(c, SummaryComponentStack::argument(i)) + } + + /** + * Holds if a synthesized summary node is needed for the state `state` in summarized * callable `c`. */ - predicate internalNodeRange(SummarizedCallable c, SummaryInternalNodeState state) { - state.isReadState(c, _, _, _) + predicate summaryNodeRange(SummarizedCallable c, SummaryNodeState state) { + state.isInputState(c, _) and + not parameterReadState(c, state, _) or - state.isStoreState(c, _, _, _) + state.isOutputState(c, _) } pragma[noinline] - private Node internalNodeLastReadState( - SummarizedCallable c, SummaryInput input, ContentList inputContents - ) { - exists(SummaryInternalNodeState state | - state.isReadState(c, input, inputContents, inputContents.length()) and - result = internalNode(c, state) + private Node summaryNodeInputState(SummarizedCallable c, SummaryComponentStack s) { + exists(SummaryNodeState state | state.isInputState(c, s) | + result = summaryNode(c, state) + or + exists(int i | + parameterReadState(c, state, i) and + result.(ParameterNode).isParameterOf(c, i) + ) ) } pragma[noinline] - private Node internalNodeFirstStoreState( - SummarizedCallable c, SummaryOutput output, ContentList outputContents + private Node summaryNodeOutputState(SummarizedCallable c, SummaryComponentStack s) { + exists(SummaryNodeState state | + state.isOutputState(c, s) and + result = summaryNode(c, state) + ) + } + + /** + * Holds if a write targets `post`, which is a post-update node for the `i`th + * parameter of `c`. + */ + private predicate isParameterPostUpdate(Node post, SummarizedCallable c, int i) { + post = summaryNodeOutputState(c, SummaryComponentStack::argument(i)) + } + + /** Holds if a parameter node is required for the `i`th parameter of `c`. */ + predicate summaryParameterNodeRange(SummarizedCallable c, int i) { + parameterReadState(c, _, i) + or + isParameterPostUpdate(_, c, i) + } + + private predicate callbackOutput( + SummarizedCallable c, SummaryComponentStack s, Node receiver, ReturnKind rk ) { - exists(SummaryInternalNodeState state | - state.isStoreState(c, output, outputContents, outputContents.length()) and - result = internalNode(c, state) - ) + any(SummaryNodeState state).isInputState(c, s) and + s.head() = TReturnSummaryComponent(rk) and + receiver = summaryNodeInputState(c, s.drop(1)) + } + + private Node pre(Node post) { + summaryPostUpdateNode(post, result) + or + not summaryPostUpdateNode(post, _) and + result = post + } + + private predicate callbackInput( + SummarizedCallable c, SummaryComponentStack s, Node receiver, int i + ) { + any(SummaryNodeState state).isOutputState(c, s) and + s.head() = TParameterSummaryComponent(i) and + receiver = pre(summaryNodeOutputState(c, s.drop(1))) + } + + /** Holds if a call targeting `receiver` should be synthesized inside `c`. */ + predicate summaryCallbackRange(SummarizedCallable c, Node receiver) { + callbackOutput(c, _, receiver, _) + or + callbackInput(c, _, receiver, _) } /** - * Holds if there is a local step from `pred` to `succ`, which is synthesized - * from a flow summary. + * Gets the type of synthesized summary node `n`. + * + * The type is computed based on the language-specific predicates + * `getContentType()`, `getReturnType()`, `getCallbackParameterType()`, and + * `getCallbackReturnType()`. */ - predicate localStep(Node pred, Node succ, boolean preservesValue) { - exists( - SummarizedCallable c, SummaryInput input, ContentList inputContents, SummaryOutput output, - ContentList outputContents - | - summary(c, input, inputContents, output, outputContents, preservesValue) - | - pred = inputNode(c, input) and + DataFlowType summaryNodeType(Node n) { + exists(Node pre | + summaryPostUpdateNode(n, pre) and + result = getNodeType(pre) + ) + or + exists(SummarizedCallable c, SummaryComponentStack s, SummaryComponent head | head = s.head() | + n = summaryNodeInputState(c, s) and ( - // Simple flow summary without reads or stores - inputContents = ContentList::empty() and - outputContents = ContentList::empty() and - succ = outputNode(c, output) + exists(Content cont | + head = TContentSummaryComponent(cont) and result = getContentType(cont) + ) or - // Flow summary with stores but no reads - inputContents = ContentList::empty() and - succ = internalNodeFirstStoreState(c, output, outputContents) + exists(ReturnKind rk | + head = TReturnSummaryComponent(rk) and + result = getCallbackReturnType(getNodeType(summaryNodeInputState(c, s.drop(1))), rk) + ) ) or - pred = internalNodeLastReadState(c, input, inputContents) and + n = summaryNodeOutputState(c, s) and ( - // Exit step after last read (no stores) - outputContents = ContentList::empty() and - succ = outputNode(c, output) + exists(Content cont | + head = TContentSummaryComponent(cont) and result = getContentType(cont) + ) or - // Internal step for complex flow summaries with both reads and writes - succ = internalNodeFirstStoreState(c, output, outputContents) + s.length() = 1 and + exists(ReturnKind rk | + head = TReturnSummaryComponent(rk) and + result = getReturnType(c, rk) + ) + or + exists(int i | head = TParameterSummaryComponent(i) | + result = getCallbackParameterType(getNodeType(summaryNodeOutputState(c, s.drop(1))), i) + ) ) ) } - /** - * Holds if there is a read step from `pred` to `succ`, which is synthesized - * from a flow summary. - */ - predicate readStep(Node pred, Content c, Node succ) { - exists( - SummarizedCallable sc, SummaryInput input, ContentList inputContents, - SummaryInternalNodeState succState, int i - | - succState.isReadState(sc, input, inputContents, i) and - succ = internalNode(sc, succState) and - c = getContent(inputContents, i - 1) - | - // First read - i = 1 and - pred = inputNode(sc, input) - or - // Subsequent reads - exists(SummaryInternalNodeState predState | - predState.isReadState(sc, input, inputContents, i - 1) and - pred = internalNode(sc, predState) + /** Holds if summary node `out` contains output of kind `rk` from call `c`. */ + predicate summaryOutNode(DataFlowCall c, Node out, ReturnKind rk) { + exists(SummarizedCallable callable, SummaryComponentStack s, Node receiver | + callbackOutput(callable, s, receiver, rk) and + out = summaryNodeInputState(callable, s) and + c = summaryDataFlowCall(receiver) + ) + } + + /** Holds if summary node `arg` is the `i`th argument of call `c`. */ + predicate summaryArgumentNode(DataFlowCall c, Node arg, int i) { + exists(SummarizedCallable callable, SummaryComponentStack s, Node receiver | + callbackInput(callable, s, receiver, i) and + arg = summaryNodeOutputState(callable, s) and + c = summaryDataFlowCall(receiver) + ) + } + + /** Holds if summary node `post` is a post-update node with pre-update node `pre`. */ + predicate summaryPostUpdateNode(Node post, ParameterNode pre) { + exists(SummarizedCallable c, int i | + isParameterPostUpdate(post, c, i) and + pre.isParameterOf(c, i) + ) + } + + /** Holds if summary node `ret` is a return node of kind `rk`. */ + predicate summaryReturnNode(Node ret, ReturnKind rk) { + exists(SummarizedCallable callable, SummaryComponentStack s | + ret = summaryNodeOutputState(callable, s) and + s = TSingletonSummaryComponentStack(TReturnSummaryComponent(rk)) + ) + } + + /** Provides a compilation of flow summaries to atomic data-flow steps. */ + module Steps { + /** + * Holds if there is a local step from `pred` to `succ`, which is synthesized + * from a flow summary. + */ + predicate summaryLocalStep(Node pred, Node succ, boolean preservesValue) { + exists( + SummarizedCallable c, SummaryComponentStack inputContents, + SummaryComponentStack outputContents + | + summary(c, inputContents, outputContents, preservesValue) and + pred = summaryNodeInputState(c, inputContents) and + succ = summaryNodeOutputState(c, outputContents) ) - ) - } + } - /** - * Holds if there is a store step from `pred` to `succ`, which is synthesized - * from a flow summary. - */ - predicate storeStep(Node pred, Content c, Node succ) { - exists( - SummarizedCallable sc, SummaryOutput output, ContentList outputContents, - SummaryInternalNodeState predState, int i - | - predState.isStoreState(sc, output, outputContents, i) and - pred = internalNode(sc, predState) and - c = getContent(outputContents, i - 1) - | - // More stores needed - exists(SummaryInternalNodeState succState | - succState.isStoreState(sc, output, outputContents, i - 1) and - succ = internalNode(sc, succState) + /** + * Holds if there is a read step of content `c` from `pred` to `succ`, which + * is synthesized from a flow summary. + */ + predicate summaryReadStep(Node pred, Content c, Node succ) { + exists(SummarizedCallable sc, SummaryComponentStack s | + pred = summaryNodeInputState(sc, s.drop(1)) and + succ = summaryNodeInputState(sc, s) and + SummaryComponent::content(c) = s.head() ) - or - // Last store - i = 1 and - succ = outputNode(sc, output) - ) - } + } - pragma[nomagic] - private ParameterNode summaryArgParam(ArgumentNode arg, ReturnKind rk, OutNode out) { - exists(DataFlowCall call, int pos, SummarizedCallable callable | - arg.argumentOf(call, pos) and - viableCallable(call) = callable and - result.isParameterOf(callable, pos) and - call = out.getCall(rk) - ) + /** + * Holds if there is a store step of content `c` from `pred` to `succ`, which + * is synthesized from a flow summary. + */ + predicate summaryStoreStep(Node pred, Content c, Node succ) { + exists(SummarizedCallable sc, SummaryComponentStack s | + pred = summaryNodeOutputState(sc, s) and + succ = summaryNodeOutputState(sc, s.drop(1)) and + SummaryComponent::content(c) = s.head() + ) + } + + /** + * Holds if values stored inside content `c` are cleared when passed as + * input of type `input` in `call`. + */ + predicate summaryClearsContent(ArgumentNode arg, Content c) { + exists(DataFlowCall call, int i | + viableCallable(call).(SummarizedCallable).clearsContent(i, c) and + arg.argumentOf(call, i) + ) + } + + pragma[nomagic] + private ParameterNode summaryArgParam( + ArgumentNode arg, DataFlowImplCommon::ReturnKindExt rk, DataFlowImplCommon::OutNodeExt out + ) { + exists(DataFlowCall call, int pos, SummarizedCallable callable | + arg.argumentOf(call, pos) and + viableCallable(call) = callable and + result.isParameterOf(callable, pos) and + out = rk.getAnOutNode(call) + ) + } + + /** + * Holds if `arg` flows to `out` using a simple flow summary, that is, a flow + * summary without reads and stores. + * + * NOTE: This step should not be used in global data-flow/taint-tracking, but may + * be useful to include in the exposed local data-flow/taint-tracking relations. + */ + predicate summaryThroughStep(ArgumentNode arg, Node out, boolean preservesValue) { + exists(DataFlowImplCommon::ReturnKindExt rk, DataFlowImplCommon::ReturnNodeExt ret | + summaryLocalStep(summaryArgParam(arg, rk, out), ret, preservesValue) and + ret.getKind() = rk + ) + } + + /** + * Holds if there is a read(+taint) of `c` from `arg` to `out` using a + * flow summary. + * + * NOTE: This step should not be used in global data-flow/taint-tracking, but may + * be useful to include in the exposed local data-flow/taint-tracking relations. + */ + predicate summaryGetterStep(ArgumentNode arg, Content c, Node out) { + exists(DataFlowImplCommon::ReturnKindExt rk, Node mid, DataFlowImplCommon::ReturnNodeExt ret | + summaryReadStep(summaryArgParam(arg, rk, out), c, mid) and + summaryLocalStep(mid, ret, _) and + ret.getKind() = rk + ) + } + + /** + * Holds if there is a (taint+)store of `arg` into content `c` of `out` using a + * flow summary. + * + * NOTE: This step should not be used in global data-flow/taint-tracking, but may + * be useful to include in the exposed local data-flow/taint-tracking relations. + */ + predicate summarySetterStep(ArgumentNode arg, Content c, Node out) { + exists(DataFlowImplCommon::ReturnKindExt rk, Node mid, DataFlowImplCommon::ReturnNodeExt ret | + summaryLocalStep(summaryArgParam(arg, rk, out), mid, _) and + summaryStoreStep(mid, c, ret) and + ret.getKind() = rk + ) + } + + /** + * Holds if data is written into content `c` of argument `arg` using a flow summary. + * + * Depending on the type of `c`, this predicate may be relevant to include in the + * definition of `clearsContent()`. + */ + predicate summaryStoresIntoArg(Content c, Node arg) { + exists( + DataFlowImplCommon::ParamUpdateReturnKind rk, DataFlowImplCommon::ReturnNodeExt ret, + PostUpdateNode out + | + exists(DataFlowCall call, SummarizedCallable callable | + DataFlowImplCommon::getNodeEnclosingCallable(ret) = callable and + viableCallable(call) = callable and + summaryStoreStep(_, c, ret) and + ret.getKind() = pragma[only_bind_into](rk) and + out = rk.getAnOutNode(call) and + arg = out.getPreUpdateNode() + ) + ) + } } /** - * Holds if `arg` flows to `out` using a simple flow summary, that is, a flow - * summary without reads and stores. - * - * NOTE: This step should not be used in global data-flow/taint-tracking, but may - * be useful to include in the exposed local data-flow/taint-tracking relations. + * Provides a means of translating externally (e.g., CSV) defined flow + * summaries into a `SummarizedCallable`s. */ - predicate throughStep(ArgumentNode arg, OutNode out, boolean preservesValue) { - exists(ReturnKind rk, ReturnNode ret | - localStep(summaryArgParam(arg, rk, out), ret, preservesValue) and - ret.getKind() = rk - ) + module External { + /** + * Provides a means of translating an externally (e.g., CSV) defined flow + * summary into a `SummarizedCallable`. + */ + abstract class ExternalSummaryCompilation extends string { + bindingset[this] + ExternalSummaryCompilation() { any() } + + /** Holds if this flow summary is for callable `c`. */ + abstract predicate callable(DataFlowCallable c, boolean preservesValue); + + /** Holds if the `i`th input component is `c`. */ + abstract predicate input(int i, SummaryComponent c); + + /** Holds if the `i`th output component is `c`. */ + abstract predicate output(int i, SummaryComponent c); + + /** + * Holds if the input components starting from index `i` translate into `suffix`. + */ + final predicate translateInput(int i, SummaryComponentStack suffix) { + exists(SummaryComponent comp | this.input(i, comp) | + i = max(int j | this.input(j, _)) and + suffix = TSingletonSummaryComponentStack(comp) + or + exists(TSummaryComponent head, SummaryComponentStack tail | + this.translateInputCons(i, head, tail) and + suffix = TConsSummaryComponentStack(head, tail) + ) + ) + } + + final predicate translateInputCons(int i, SummaryComponent head, SummaryComponentStack tail) { + this.input(i, head) and + this.translateInput(i + 1, tail) + } + + /** + * Holds if the output components starting from index `i` translate into `suffix`. + */ + predicate translateOutput(int i, SummaryComponentStack suffix) { + exists(SummaryComponent comp | this.output(i, comp) | + i = max(int j | this.output(j, _)) and + suffix = TSingletonSummaryComponentStack(comp) + or + exists(TSummaryComponent head, SummaryComponentStack tail | + this.translateOutputCons(i, head, tail) and + suffix = TConsSummaryComponentStack(head, tail) + ) + ) + } + + predicate translateOutputCons(int i, SummaryComponent head, SummaryComponentStack tail) { + this.output(i, head) and + this.translateOutput(i + 1, tail) + } + } + + private class ExternalRequiredSummaryComponentStack extends RequiredSummaryComponentStack { + private SummaryComponent head; + + ExternalRequiredSummaryComponentStack() { + any(ExternalSummaryCompilation s).translateInputCons(_, head, this) or + any(ExternalSummaryCompilation s).translateOutputCons(_, head, this) + } + + override predicate required(SummaryComponent c) { c = head } + } + + class ExternalSummarizedCallableAdaptor extends SummarizedCallable { + ExternalSummarizedCallableAdaptor() { any(ExternalSummaryCompilation s).callable(this, _) } + + override predicate propagatesFlow( + SummaryComponentStack input, SummaryComponentStack output, boolean preservesValue + ) { + exists(ExternalSummaryCompilation s | + s.callable(this, preservesValue) and + s.translateInput(0, input) and + s.translateOutput(0, output) + ) + } + } } - /** - * Holds if there is a read(+taint) of `c` from `arg` to `out` using a - * flow summary. - * - * NOTE: This step should not be used in global data-flow/taint-tracking, but may - * be useful to include in the exposed local data-flow/taint-tracking relations. - */ - predicate getterStep(ArgumentNode arg, Content c, OutNode out) { - exists(ReturnKind rk, Node mid, ReturnNode ret | - readStep(summaryArgParam(arg, rk, out), c, mid) and - localStep(mid, ret, _) and - ret.getKind() = rk - ) - } + /** Provides a query predicate for outputting a set of relevant flow summaries. */ + module TestOutput { + /** A flow summary to include in the `summary/3` query predicate. */ + abstract class RelevantSummarizedCallable extends SummarizedCallable { + /** Gets the string representation of this callable used by `summary/3`. */ + string getFullString() { result = this.toString() } + } - /** - * Holds if there is a (taint+)store of `arg` into content `c` of `out` using a - * flow summary. - * - * NOTE: This step should not be used in global data-flow/taint-tracking, but may - * be useful to include in the exposed local data-flow/taint-tracking relations. - */ - predicate setterStep(ArgumentNode arg, Content c, OutNode out) { - exists(ReturnKind rk, Node mid, ReturnNode ret | - localStep(summaryArgParam(arg, rk, out), mid, _) and - storeStep(mid, c, ret) and - ret.getKind() = rk - ) - } - - /** - * Holds if values stored inside content `c` are cleared when passed as - * input of type `input` in `call`. - */ - predicate clearsContent(SummaryInput input, DataFlowCall call, Content c) { - viableCallable(call).(SummarizedCallable).clearsContent(input, c) + /** A query predicate for outputting flow summaries in QL tests. */ + query predicate summary(string callable, string flow, boolean preservesValue) { + exists( + RelevantSummarizedCallable c, SummaryComponentStack input, SummaryComponentStack output + | + callable = c.getFullString() and + c.propagatesFlow(input, output, preservesValue) and + flow = input + " -> " + output + ) + } } } diff --git a/csharp/ql/src/semmle/code/csharp/dataflow/internal/FlowSummaryImplSpecific.qll b/csharp/ql/src/semmle/code/csharp/dataflow/internal/FlowSummaryImplSpecific.qll new file mode 100644 index 00000000000..01e3a2e1633 --- /dev/null +++ b/csharp/ql/src/semmle/code/csharp/dataflow/internal/FlowSummaryImplSpecific.qll @@ -0,0 +1,79 @@ +/** + * Provides C# specific classes and predicates for defining flow summaries. + */ + +private import csharp +private import semmle.code.csharp.frameworks.system.linq.Expressions +private import DataFlowDispatch +private import DataFlowPrivate +private import DataFlowPublic +private import FlowSummaryImpl::Private +private import FlowSummaryImpl::Public +private import semmle.code.csharp.Unification + +/** Holds is `i` is a valid parameter position. */ +predicate parameterPosition(int i) { i in [-1 .. any(Parameter p).getPosition()] } + +/** Gets the synthesized summary data-flow node for the given values. */ +Node summaryNode(SummarizedCallable c, SummaryNodeState state) { result = TSummaryNode(c, state) } + +/** Gets the synthesized data-flow call for `receiver`. */ +SummaryCall summaryDataFlowCall(Node receiver) { receiver = result.getReceiver() } + +/** Gets the type of content `c`. */ +DataFlowType getContentType(Content c) { + exists(Type t | result = Gvn::getGlobalValueNumber(t) | + t = c.(FieldContent).getField().getType() + or + t = c.(PropertyContent).getProperty().getType() + or + c instanceof ElementContent and + t instanceof ObjectType // we don't know what the actual element type is + ) +} + +private DataFlowType getReturnTypeBase(DataFlowCallable c, ReturnKind rk) { + exists(Type t | result = Gvn::getGlobalValueNumber(t) | + rk instanceof NormalReturnKind and + ( + t = c.(Constructor).getDeclaringType() + or + not c instanceof Constructor and + t = c.getReturnType() + ) + or + t = c.getParameter(rk.(OutRefReturnKind).getPosition()).getType() + ) +} + +/** Gets the return type of kind `rk` for callable `c`. */ +bindingset[c] +DataFlowType getReturnType(SummarizedCallable c, ReturnKind rk) { + result = getReturnTypeBase(c, rk) + or + rk = + any(JumpReturnKind jrk | result = getReturnTypeBase(jrk.getTarget(), jrk.getTargetReturnKind())) +} + +/** + * Gets the type of the `i`th parameter in a synthesized call that targets a + * callback of type `t`. + */ +DataFlowType getCallbackParameterType(DataFlowType t, int i) { + exists(SystemLinqExpressions::DelegateExtType dt | + t = Gvn::getGlobalValueNumber(dt) and + result = Gvn::getGlobalValueNumber(dt.getDelegateType().getParameter(i).getType()) + ) +} + +/** + * Gets the return type of kind `rk` in a synthesized call that targets a + * callback of type `t`. + */ +DataFlowType getCallbackReturnType(DataFlowType t, ReturnKind rk) { + rk instanceof NormalReturnKind and + exists(SystemLinqExpressions::DelegateExtType dt | + t = Gvn::getGlobalValueNumber(dt) and + result = Gvn::getGlobalValueNumber(dt.getDelegateType().getReturnType()) + ) +} diff --git a/csharp/ql/src/semmle/code/csharp/dataflow/internal/FlowSummarySpecific.qll b/csharp/ql/src/semmle/code/csharp/dataflow/internal/FlowSummarySpecific.qll deleted file mode 100644 index 2edca6111ed..00000000000 --- a/csharp/ql/src/semmle/code/csharp/dataflow/internal/FlowSummarySpecific.qll +++ /dev/null @@ -1,178 +0,0 @@ -/** - * Provides C# specific classes and predicates for definining flow summaries. - */ - -private import csharp -private import semmle.code.csharp.frameworks.system.linq.Expressions -private import DataFlowDispatch - -module Private { - private import Public - private import DataFlowPrivate as DataFlowPrivate - private import DataFlowPublic as DataFlowPublic - private import FlowSummaryImpl as Impl - private import semmle.code.csharp.Unification - - class Content = DataFlowPublic::Content; - - class DataFlowType = DataFlowPrivate::DataFlowType; - - class Node = DataFlowPublic::Node; - - class ParameterNode = DataFlowPublic::ParameterNode; - - class ArgumentNode = DataFlowPrivate::ArgumentNode; - - class ReturnNode = DataFlowPrivate::ReturnNode; - - class OutNode = DataFlowPrivate::OutNode; - - private class NodeImpl = DataFlowPrivate::NodeImpl; - - predicate accessPathLimit = DataFlowPrivate::accessPathLimit/0; - - predicate hasDelegateArgumentPosition(SummarizableCallable c, int i) { - exists(DelegateType dt | - dt = c.getParameter(i).getType().(SystemLinqExpressions::DelegateExtType).getDelegateType() - | - not dt.getReturnType() instanceof VoidType - ) - } - - predicate hasDelegateArgumentPosition2(SummarizableCallable c, int i, int j) { - exists(DelegateType dt | - dt = c.getParameter(i).getType().(SystemLinqExpressions::DelegateExtType).getDelegateType() - | - exists(dt.getParameter(j)) - ) - } - - newtype TSummaryInput = - TParameterSummaryInput(int i) { i in [-1, any(Parameter p).getPosition()] } or - TDelegateSummaryInput(int i) { hasDelegateArgumentPosition(_, i) } - - newtype TSummaryOutput = - TReturnSummaryOutput() or - TParameterSummaryOutput(int i) { - i in [-1, any(SummarizableCallable c).getAParameter().getPosition()] - } or - TDelegateSummaryOutput(int i, int j) { hasDelegateArgumentPosition2(_, i, j) } or - TJumpSummaryOutput(SummarizableCallable target, ReturnKind rk) { - rk instanceof NormalReturnKind and - ( - target instanceof Constructor or - not target.getReturnType() instanceof VoidType - ) - or - rk instanceof QualifierReturnKind and - not target.(Modifiable).isStatic() - or - exists(target.getParameter(rk.(OutRefReturnKind).getPosition())) - } - - /** Gets the return kind that matches `sink`, if any. */ - ReturnKind toReturnKind(SummaryOutput output) { - output = TReturnSummaryOutput() and - result instanceof NormalReturnKind - or - exists(int i | output = TParameterSummaryOutput(i) | - i = -1 and - result instanceof QualifierReturnKind - or - i = result.(OutRefReturnKind).getPosition() - ) - } - - /** Gets the input node for `c` of type `input`. */ - NodeImpl inputNode(SummarizableCallable c, SummaryInput input) { - exists(int i | - input = TParameterSummaryInput(i) and - result.(ParameterNode).isParameterOf(c, i) - ) - or - exists(int i | - input = TDelegateSummaryInput(i) and - result = DataFlowPrivate::TSummaryDelegateOutNode(c, i) - ) - } - - /** Gets the output node for `c` of type `output`. */ - NodeImpl outputNode(SummarizableCallable c, SummaryOutput output) { - result = DataFlowPrivate::TSummaryReturnNode(c, toReturnKind(output)) - or - exists(int i, int j | - output = TDelegateSummaryOutput(i, j) and - result = DataFlowPrivate::TSummaryDelegateArgumentNode(c, i, j) - ) - or - exists(SummarizableCallable target, ReturnKind rk | - output = TJumpSummaryOutput(target, rk) and - result = DataFlowPrivate::TSummaryJumpNode(c, target, rk) - ) - } - - /** Gets the internal summary node for the given values. */ - Node internalNode(SummarizableCallable c, Impl::Private::SummaryInternalNodeState state) { - result = DataFlowPrivate::TSummaryInternalNode(c, state) - } - - /** Gets the type of content `c`. */ - pragma[noinline] - DataFlowType getContentType(Content c) { - exists(Type t | result = Gvn::getGlobalValueNumber(t) | - t = c.(DataFlowPublic::FieldContent).getField().getType() - or - t = c.(DataFlowPublic::PropertyContent).getProperty().getType() - or - c instanceof DataFlowPublic::ElementContent and - t instanceof ObjectType // we don't know what the actual element type is - ) - } -} - -module Public { - private import Private - - /** An unbound callable. */ - class SummarizableCallable extends Callable { - SummarizableCallable() { this.isUnboundDeclaration() } - } - - /** A flow-summary input specification. */ - class SummaryInput extends TSummaryInput { - /** Gets a textual representation of this input specification. */ - final string toString() { - exists(int i | - this = TParameterSummaryInput(i) and - if i = -1 then result = "this parameter" else result = "parameter " + i - or - this = TDelegateSummaryInput(i) and - result = "deleget output from parameter " + i - ) - } - } - - /** A flow-summary output specification. */ - class SummaryOutput extends TSummaryOutput { - /** Gets a textual representation of this flow sink specification. */ - final string toString() { - this = TReturnSummaryOutput() and - result = "return" - or - exists(int i | - this = TParameterSummaryOutput(i) and - if i = -1 then result = "this parameter" else result = "parameter " + i - ) - or - exists(int delegateIndex, int parameterIndex | - this = TDelegateSummaryOutput(delegateIndex, parameterIndex) and - result = "parameter " + parameterIndex + " of delegate parameter " + delegateIndex - ) - or - exists(SummarizableCallable target, ReturnKind rk | - this = TJumpSummaryOutput(target, rk) and - result = "jump to " + target + " (" + rk + ")" - ) - } - } -} diff --git a/csharp/ql/src/semmle/code/csharp/dataflow/internal/SsaImpl.qll b/csharp/ql/src/semmle/code/csharp/dataflow/internal/SsaImpl.qll index 7f54d3287d1..63d6c902fed 100644 --- a/csharp/ql/src/semmle/code/csharp/dataflow/internal/SsaImpl.qll +++ b/csharp/ql/src/semmle/code/csharp/dataflow/internal/SsaImpl.qll @@ -235,7 +235,6 @@ private module CallGraph { } private module SimpleDelegateAnalysis { - private import semmle.code.csharp.dataflow.internal.DelegateDataFlow private import semmle.code.csharp.dataflow.internal.Steps private import semmle.code.csharp.frameworks.system.linq.Expressions @@ -269,56 +268,146 @@ private module CallGraph { ) } + /** + * A simple flow step that does not take flow through fields or flow out + * of callables into account. + */ + pragma[nomagic] private predicate delegateFlowStep(Expr pred, Expr succ) { Steps::stepClosed(pred, succ) or - exists(Call call, Callable callable | - callable.getUnboundDeclaration().canReturn(pred) and - call = succ - | - callable = call.getTarget() or - callable = call.getTarget().(Method).getAnOverrider+() or - callable = call.getTarget().(Method).getAnUltimateImplementor() or - callable = getARuntimeDelegateTarget(call, false) - ) - or pred = succ.(DelegateCreation).getArgument() or - exists(AssignableDefinition def, Assignable a | - a instanceof Field or - a instanceof Property - | - a = def.getTarget() and - succ.(AssignableRead) = a.getAnAccess() and - pred = def.getSource() - ) - or exists(AddEventExpr ae | succ.(EventAccess).getTarget() = ae.getTarget() | pred = ae.getRValue() ) } - private predicate reachesDelegateCall(Expr e) { - delegateCall(_, e, _) + private predicate delegateCreationReaches(Callable c, Expr e) { + delegateCreation(e, c, _) or - exists(Expr mid | reachesDelegateCall(mid) | delegateFlowStep(e, mid)) + exists(Expr mid | + delegateCreationReaches(c, mid) and + delegateFlowStep(mid, e) + ) } - pragma[nomagic] - private predicate delegateFlowStepReaches(Expr pred, Expr succ) { - delegateFlowStep(pred, succ) and - reachesDelegateCall(succ) + private predicate reachesDelegateCall(Expr e, Call c, boolean libraryDelegateCall) { + delegateCall(c, e, libraryDelegateCall) + or + exists(Expr mid | + reachesDelegateCall(mid, c, libraryDelegateCall) and + delegateFlowStep(e, mid) + ) } - private Expr delegateCallSource(Callable c) { - delegateCreation(result, c, _) - or - delegateFlowStepReaches(delegateCallSource(c), result) + /** + * A "busy" flow element, that is, a node in the data-flow graph that typically + * has a large fan-in or a large fan-out (or both). + * + * For such busy elements, we do not track flow directly from all delegate + * creations, but instead we first perform a flow analysis between busy elements, + * and then only in the end join up with delegate creations and delegate calls. + */ + abstract private class BusyFlowElement extends Element { + pragma[nomagic] + abstract Expr getAnInput(); + + pragma[nomagic] + abstract Expr getAnOutput(); + + /** Holds if this element can be reached from expression `e`. */ + pragma[nomagic] + private predicate exprReaches(Expr e) { + this.reachesCall(_) and + e = this.getAnInput() + or + exists(Expr mid | + this.exprReaches(mid) and + delegateFlowStep(e, mid) + ) + } + + /** + * Holds if this element can reach a delegate call `c` directly without + * passing through another busy element. + */ + pragma[nomagic] + predicate delegateCall(Call c, boolean libraryDelegateCall) { + reachesDelegateCall(this.getAnOutput(), c, libraryDelegateCall) + } + + pragma[nomagic] + private BusyFlowElement getASuccessor() { result.exprReaches(this.getAnOutput()) } + + /** + * Holds if this element reaches another busy element `other`, + * which can reach a delegate call directly without passing + * through another busy element. + */ + pragma[nomagic] + private predicate reachesCall(BusyFlowElement other) { + this = other and + other.delegateCall(_, _) + or + this.getASuccessor().reachesCall(other) + } + + /** Holds if this element is reached by a delegate creation for `c`. */ + pragma[nomagic] + predicate isReachedBy(Callable c) { + exists(BusyFlowElement pred | + pred.reachesCall(this) and + delegateCreationReaches(c, pred.getAnInput()) + ) + } + } + + private class TFieldOrProperty = @field or @property; + + private class FieldOrPropertyFlow extends BusyFlowElement, Assignable, TFieldOrProperty { + final override Expr getAnInput() { + exists(Assignable target | + target = this.getUnboundDeclaration() and + result = target.getAnAssignedValue() + ) + } + + final override AssignableRead getAnOutput() { + exists(Assignable target | + target = this.getUnboundDeclaration() and + result = target.getAnAccess() + ) + } + } + + private class CallOutputFlow extends BusyFlowElement, Callable { + final override Expr getAnInput() { this.canReturn(result) } + + final override Call getAnOutput() { + exists(Callable target | this = target.getUnboundDeclaration() | + target = result.getTarget() or + target = result.getTarget().(Method).getAnOverrider+() or + target = result.getTarget().(Method).getAnUltimateImplementor() or + target = getARuntimeDelegateTarget(result, false) + ) + } } /** Gets a run-time target for the delegate call `c`. */ + pragma[nomagic] Callable getARuntimeDelegateTarget(Call c, boolean libraryDelegateCall) { - delegateCall(c, delegateCallSource(result), libraryDelegateCall) + // directly resolvable without going through a "busy" element + exists(Expr e | + delegateCreationReaches(result, e) and + delegateCall(c, e, libraryDelegateCall) + ) + or + // resolvable by going through one or more "busy" elements + exists(BusyFlowElement busy | + busy.isReachedBy(result) and + busy.delegateCall(c, libraryDelegateCall) + ) } } diff --git a/csharp/ql/src/semmle/code/csharp/dataflow/internal/SsaImplCommon.qll b/csharp/ql/src/semmle/code/csharp/dataflow/internal/SsaImplCommon.qll index be01c05b8fa..f828419a440 100644 --- a/csharp/ql/src/semmle/code/csharp/dataflow/internal/SsaImplCommon.qll +++ b/csharp/ql/src/semmle/code/csharp/dataflow/internal/SsaImplCommon.qll @@ -1,5 +1,5 @@ /** - * Provides a language-independant implementation of static single assignment + * Provides a language-independent implementation of static single assignment * (SSA) form. */ @@ -321,10 +321,9 @@ private module SsaDefReaches { } pragma[noinline] - private BasicBlock getAMaybeLiveSuccessor(Definition def, BasicBlock bb) { - result = getABasicBlockSuccessor(bb) and - not defOccursInBlock(_, bb, def.getSourceVariable()) and - ssaDefReachesEndOfBlock(bb, def, _) + private predicate ssaDefReachesThroughBlock(Definition def, BasicBlock bb) { + ssaDefReachesEndOfBlock(bb, def, _) and + not defOccursInBlock(_, bb, def.getSourceVariable()) } /** @@ -337,7 +336,11 @@ private module SsaDefReaches { defOccursInBlock(def, bb1, _) and bb2 = getABasicBlockSuccessor(bb1) or - exists(BasicBlock mid | varBlockReaches(def, bb1, mid) | bb2 = getAMaybeLiveSuccessor(def, mid)) + exists(BasicBlock mid | + varBlockReaches(def, bb1, mid) and + ssaDefReachesThroughBlock(def, mid) and + bb2 = getABasicBlockSuccessor(mid) + ) } /** @@ -355,17 +358,10 @@ private module SsaDefReaches { private import SsaDefReaches -pragma[noinline] -private predicate ssaDefReachesEndOfBlockRec(BasicBlock bb, Definition def, SourceVariable v) { - exists(BasicBlock idom | ssaDefReachesEndOfBlock(idom, def, v) | - // The construction of SSA form ensures that each read of a variable is - // dominated by its definition. An SSA definition therefore reaches a - // control flow node if it is the _closest_ SSA definition that dominates - // the node. If two definitions dominate a node then one must dominate the - // other, so therefore the definition of _closest_ is given by the dominator - // tree. Thus, reaching definitions can be calculated in terms of dominance. - idom = getImmediateBasicBlockDominator(bb) - ) +pragma[nomagic] +predicate liveThrough(BasicBlock bb, SourceVariable v) { + liveAtExit(bb, v) and + not ssaRef(bb, _, v, SsaDef()) } /** @@ -382,9 +378,14 @@ predicate ssaDefReachesEndOfBlock(BasicBlock bb, Definition def, SourceVariable liveAtExit(bb, v) ) or - ssaDefReachesEndOfBlockRec(bb, def, v) and - liveAtExit(bb, v) and - not ssaRef(bb, _, v, SsaDef()) + // The construction of SSA form ensures that each read of a variable is + // dominated by its definition. An SSA definition therefore reaches a + // control flow node if it is the _closest_ SSA definition that dominates + // the node. If two definitions dominate a node then one must dominate the + // other, so therefore the definition of _closest_ is given by the dominator + // tree. Thus, reaching definitions can be calculated in terms of dominance. + ssaDefReachesEndOfBlock(getImmediateBasicBlockDominator(bb), def, pragma[only_bind_into](v)) and + liveThrough(bb, pragma[only_bind_into](v)) } /** diff --git a/csharp/ql/src/semmle/code/csharp/dataflow/internal/TaintTrackingPrivate.qll b/csharp/ql/src/semmle/code/csharp/dataflow/internal/TaintTrackingPrivate.qll index e8922edbf9f..72525d3234a 100755 --- a/csharp/ql/src/semmle/code/csharp/dataflow/internal/TaintTrackingPrivate.qll +++ b/csharp/ql/src/semmle/code/csharp/dataflow/internal/TaintTrackingPrivate.qll @@ -103,19 +103,19 @@ private module Cached { ( // Simple flow through library code is included in the exposed local // step relation, even though flow is technically inter-procedural - FlowSummaryImpl::Private::throughStep(nodeFrom, nodeTo, false) + FlowSummaryImpl::Private::Steps::summaryThroughStep(nodeFrom, nodeTo, false) or // Taint collection by adding a tainted element exists(DataFlow::ElementContent c | storeStep(nodeFrom, c, nodeTo) or - FlowSummaryImpl::Private::setterStep(nodeFrom, c, nodeTo) + FlowSummaryImpl::Private::Steps::summarySetterStep(nodeFrom, c, nodeTo) ) or exists(DataFlow::Content c | readStep(nodeFrom, c, nodeTo) or - FlowSummaryImpl::Private::getterStep(nodeFrom, c, nodeTo) + FlowSummaryImpl::Private::Steps::summaryGetterStep(nodeFrom, c, nodeTo) | // Taint members c = any(TaintedMember m).(FieldOrProperty).getContent() @@ -142,7 +142,7 @@ private module Cached { // tracking configurations where the source is a collection readStep(nodeFrom, TElementContent(), nodeTo) or - FlowSummaryImpl::Private::localStep(nodeFrom, nodeTo, false) + FlowSummaryImpl::Private::Steps::summaryLocalStep(nodeFrom, nodeTo, false) or nodeTo = nodeFrom.(DataFlow::NonLocalJumpNode).getAJumpSuccessor(false) } diff --git a/csharp/ql/src/semmle/code/csharp/dataflow/internal/basessa/SsaImplCommon.qll b/csharp/ql/src/semmle/code/csharp/dataflow/internal/basessa/SsaImplCommon.qll index be01c05b8fa..f828419a440 100644 --- a/csharp/ql/src/semmle/code/csharp/dataflow/internal/basessa/SsaImplCommon.qll +++ b/csharp/ql/src/semmle/code/csharp/dataflow/internal/basessa/SsaImplCommon.qll @@ -1,5 +1,5 @@ /** - * Provides a language-independant implementation of static single assignment + * Provides a language-independent implementation of static single assignment * (SSA) form. */ @@ -321,10 +321,9 @@ private module SsaDefReaches { } pragma[noinline] - private BasicBlock getAMaybeLiveSuccessor(Definition def, BasicBlock bb) { - result = getABasicBlockSuccessor(bb) and - not defOccursInBlock(_, bb, def.getSourceVariable()) and - ssaDefReachesEndOfBlock(bb, def, _) + private predicate ssaDefReachesThroughBlock(Definition def, BasicBlock bb) { + ssaDefReachesEndOfBlock(bb, def, _) and + not defOccursInBlock(_, bb, def.getSourceVariable()) } /** @@ -337,7 +336,11 @@ private module SsaDefReaches { defOccursInBlock(def, bb1, _) and bb2 = getABasicBlockSuccessor(bb1) or - exists(BasicBlock mid | varBlockReaches(def, bb1, mid) | bb2 = getAMaybeLiveSuccessor(def, mid)) + exists(BasicBlock mid | + varBlockReaches(def, bb1, mid) and + ssaDefReachesThroughBlock(def, mid) and + bb2 = getABasicBlockSuccessor(mid) + ) } /** @@ -355,17 +358,10 @@ private module SsaDefReaches { private import SsaDefReaches -pragma[noinline] -private predicate ssaDefReachesEndOfBlockRec(BasicBlock bb, Definition def, SourceVariable v) { - exists(BasicBlock idom | ssaDefReachesEndOfBlock(idom, def, v) | - // The construction of SSA form ensures that each read of a variable is - // dominated by its definition. An SSA definition therefore reaches a - // control flow node if it is the _closest_ SSA definition that dominates - // the node. If two definitions dominate a node then one must dominate the - // other, so therefore the definition of _closest_ is given by the dominator - // tree. Thus, reaching definitions can be calculated in terms of dominance. - idom = getImmediateBasicBlockDominator(bb) - ) +pragma[nomagic] +predicate liveThrough(BasicBlock bb, SourceVariable v) { + liveAtExit(bb, v) and + not ssaRef(bb, _, v, SsaDef()) } /** @@ -382,9 +378,14 @@ predicate ssaDefReachesEndOfBlock(BasicBlock bb, Definition def, SourceVariable liveAtExit(bb, v) ) or - ssaDefReachesEndOfBlockRec(bb, def, v) and - liveAtExit(bb, v) and - not ssaRef(bb, _, v, SsaDef()) + // The construction of SSA form ensures that each read of a variable is + // dominated by its definition. An SSA definition therefore reaches a + // control flow node if it is the _closest_ SSA definition that dominates + // the node. If two definitions dominate a node then one must dominate the + // other, so therefore the definition of _closest_ is given by the dominator + // tree. Thus, reaching definitions can be calculated in terms of dominance. + ssaDefReachesEndOfBlock(getImmediateBasicBlockDominator(bb), def, pragma[only_bind_into](v)) and + liveThrough(bb, pragma[only_bind_into](v)) } /** diff --git a/csharp/ql/src/semmle/code/csharp/dispatch/Dispatch.qll b/csharp/ql/src/semmle/code/csharp/dispatch/Dispatch.qll index 1e0eaaf8017..e436fb2b99a 100644 --- a/csharp/ql/src/semmle/code/csharp/dispatch/Dispatch.qll +++ b/csharp/ql/src/semmle/code/csharp/dispatch/Dispatch.qll @@ -636,31 +636,41 @@ private module Internal { ) } - private predicate stepExpr0(Expr succ, Expr pred) { - Steps::stepOpen(pred, succ) - or - exists(Assignable a | - a instanceof Field or - a instanceof Property - | - succ.(AssignableRead) = a.getAnAccess() and - pred = a.getAnAssignedValue() and - a = any(Modifiable m | not m.isEffectivelyPublic()) - ) - } - - private predicate stepExpr(Expr succ, Expr pred) { - stepExpr0(succ, pred) and + private predicate stepExpr(Expr pred, Expr succ) { + Steps::stepOpen(pred, succ) and // Do not step through down casts not downCast(succ) and // Only step when we may learn more about the actual type typeMayBeImprecise(succ.getType()) } - private predicate stepTC(Expr succ, Expr pred) = fastTC(stepExpr/2)(succ, pred) + private class AnalyzableFieldOrProperty extends Assignable, Modifiable { + AnalyzableFieldOrProperty() { + ( + this instanceof Field or + this instanceof Property + ) and + not this.isEffectivelyPublic() and + exists(this.getAnAssignedValue()) + } + + AssignableRead getARead() { result = this.getAnAccess() } + } private class Source extends Expr { - Source() { not stepExpr(this, _) } + Source() { + not stepExpr(_, this) and + not this = any(AnalyzableFieldOrProperty a).getARead() + } + + Type getType(boolean isExact) { + result = this.getType() and + if + this instanceof ObjectCreation or + this instanceof BaseAccess + then isExact = true + else isExact = false + } } private class Sink extends Expr { @@ -680,24 +690,38 @@ private module Internal { this = any(DispatchCallImpl c).getArgument(_) } - Source getASource() { stepTC(this, result) } + pragma[nomagic] + Expr getAPred() { stepExpr*(result, this) } + + pragma[nomagic] + AnalyzableFieldOrProperty getAPredRead() { this.getAPred() = result.getARead() } } - /** Holds if the expression `e` has an exact type. */ - private predicate hasExactType(Expr e) { - e instanceof ObjectCreation or - e instanceof BaseAccess + /** Gets a source type for sink expression `e`, using simple data flow. */ + Type getASourceType(Sink sink, boolean isExact) { + result = sink.getAPred().(Source).getType(isExact) + or + result = sink.getAPredRead().(RelevantFieldOrProperty).getASourceType(isExact) } - /** Gets a source type for expression `e`, using simple data flow. */ - Type getASourceType(Sink e, boolean isExact) { - exists(Source s | - s = e.getASource() or - s = e - | - result = s.getType() and - if hasExactType(s) then isExact = true else isExact = false - ) + private class RelevantFieldOrProperty extends AnalyzableFieldOrProperty { + RelevantFieldOrProperty() { + this = any(Sink s).getAPredRead() + or + this = any(RelevantFieldOrProperty a).getAPredRead() + } + + pragma[nomagic] + Expr getAPred() { stepExpr*(result, this.getAnAssignedValue()) } + + pragma[nomagic] + AnalyzableFieldOrProperty getAPredRead() { this.getAPred() = result.getARead() } + + Type getASourceType(boolean isExact) { + result = this.getAPred().(Source).getType(isExact) + or + result = this.getAPredRead().(RelevantFieldOrProperty).getASourceType(isExact) + } } } diff --git a/csharp/ql/src/semmle/code/csharp/exprs/Call.qll b/csharp/ql/src/semmle/code/csharp/exprs/Call.qll index 078ecd1a52a..6dc88e941ef 100644 --- a/csharp/ql/src/semmle/code/csharp/exprs/Call.qll +++ b/csharp/ql/src/semmle/code/csharp/exprs/Call.qll @@ -8,6 +8,8 @@ import Expr import semmle.code.csharp.Callable import semmle.code.csharp.dataflow.CallContext as CallContext private import semmle.code.csharp.dataflow.internal.DelegateDataFlow +private import semmle.code.csharp.dataflow.internal.DataFlowDispatch +private import semmle.code.csharp.dataflow.internal.DataFlowImplCommon private import semmle.code.csharp.dispatch.Dispatch private import dotnet @@ -536,10 +538,12 @@ class DelegateLikeCall extends Call, DelegateLikeCall_ { override Callable getTarget() { none() } /** + * DEPRECATED: Use `getARuntimeTarget/0` instead. + * * Gets a potential run-time target of this delegate or function pointer call in the given * call context `cc`. */ - Callable getARuntimeTarget(CallContext::CallContext cc) { + deprecated Callable getARuntimeTarget(CallContext::CallContext cc) { exists(DelegateLikeCallExpr call | this = call.getCall() and result = call.getARuntimeTarget(cc) @@ -562,7 +566,12 @@ class DelegateLikeCall extends Call, DelegateLikeCall_ { */ Expr getExpr() { result = this.getChild(-1) } - override Callable getARuntimeTarget() { result = getARuntimeTarget(_) } + final override Callable getARuntimeTarget() { + exists(ExplicitDelegateLikeDataFlowCall call | + this = call.getCall() and + result = viableCallableLambda(call, _) + ) + } override Expr getRuntimeArgument(int i) { result = getArgument(i) } } @@ -582,10 +591,12 @@ class DelegateLikeCall extends Call, DelegateLikeCall_ { */ class DelegateCall extends DelegateLikeCall, @delegate_invocation_expr { /** + * DEPRECATED: Use `getARuntimeTarget/0` instead. + * * Gets a potential run-time target of this delegate call in the given * call context `cc`. */ - override Callable getARuntimeTarget(CallContext::CallContext cc) { + deprecated override Callable getARuntimeTarget(CallContext::CallContext cc) { result = DelegateLikeCall.super.getARuntimeTarget(cc) or exists(AddEventSource aes, CallContext::CallContext cc2 | @@ -601,16 +612,16 @@ class DelegateCall extends DelegateLikeCall, @delegate_invocation_expr { ) } - private AddEventSource getAnAddEventSource(Callable enclosingCallable) { + deprecated private AddEventSource getAnAddEventSource(Callable enclosingCallable) { this.getExpr().(EventAccess).getTarget() = result.getEvent() and enclosingCallable = result.getExpr().getEnclosingCallable() } - private AddEventSource getAnAddEventSourceSameEnclosingCallable() { + deprecated private AddEventSource getAnAddEventSourceSameEnclosingCallable() { result = getAnAddEventSource(this.getEnclosingCallable()) } - private AddEventSource getAnAddEventSourceDifferentEnclosingCallable() { + deprecated private AddEventSource getAnAddEventSourceDifferentEnclosingCallable() { exists(Callable c | result = getAnAddEventSource(c) | c != this.getEnclosingCallable()) } diff --git a/csharp/ql/src/semmle/code/csharp/exprs/Expr.qll b/csharp/ql/src/semmle/code/csharp/exprs/Expr.qll index 6006e165470..0988bb84340 100644 --- a/csharp/ql/src/semmle/code/csharp/exprs/Expr.qll +++ b/csharp/ql/src/semmle/code/csharp/exprs/Expr.qll @@ -20,7 +20,7 @@ import semmle.code.csharp.Location import semmle.code.csharp.Stmt import semmle.code.csharp.Type private import dotnet -private import semmle.code.csharp.Enclosing::Internal +private import semmle.code.csharp.ExprOrStmtParent private import semmle.code.csharp.frameworks.System private import semmle.code.csharp.TypeRef @@ -55,7 +55,7 @@ class Expr extends DotNet::Expr, ControlFlowElement, @expr { final Stmt getEnclosingStmt() { enclosingStmt(this, result) } /** Gets the enclosing callable of this expression, if any. */ - override Callable getEnclosingCallable() { exprEnclosingCallable(this, result) } + override Callable getEnclosingCallable() { enclosingCallable(this, result) } /** * Holds if this expression is generated by the compiler and does not appear diff --git a/csharp/ql/src/semmle/code/csharp/frameworks/Dapper.qll b/csharp/ql/src/semmle/code/csharp/frameworks/Dapper.qll new file mode 100644 index 00000000000..3d25f4389fd --- /dev/null +++ b/csharp/ql/src/semmle/code/csharp/frameworks/Dapper.qll @@ -0,0 +1,42 @@ +/** + * Classes for modeling Dapper. + */ + +import csharp +private import semmle.code.csharp.frameworks.system.Data + +/** Definitions relating to the `Dapper` package. */ +module Dapper { + /** The namespace `Dapper`. */ + class DapperNamespace extends Namespace { + DapperNamespace() { this.hasQualifiedName("Dapper") } + } + + /** A class in `Dapper`. */ + class DapperClass extends Class { + DapperClass() { this.getParent() instanceof DapperNamespace } + } + + /** A struct in `Dapper`. */ + class DapperStruct extends Struct { + DapperStruct() { this.getParent() instanceof DapperNamespace } + } + + /** The `Dapper.SqlMapper` class. */ + class SqlMapperClass extends DapperClass { + SqlMapperClass() { this.hasName("SqlMapper") } + + /** Gets a DB query method. */ + ExtensionMethod getAQueryMethod() { + result = this.getAMethod() and + result.getName().regexpMatch("Query.*|Execute.*") and + result.getExtendedType() instanceof SystemDataIDbConnectionInterface and + result.isPublic() + } + } + + /** The `Dapper.CommandDefinition` struct. */ + class CommandDefinitionStruct extends DapperStruct { + CommandDefinitionStruct() { this.hasName("CommandDefinition") } + } +} diff --git a/csharp/ql/src/semmle/code/csharp/frameworks/EntityFramework.qll b/csharp/ql/src/semmle/code/csharp/frameworks/EntityFramework.qll index 19f598d0ad1..29939efccdb 100644 --- a/csharp/ql/src/semmle/code/csharp/frameworks/EntityFramework.qll +++ b/csharp/ql/src/semmle/code/csharp/frameworks/EntityFramework.qll @@ -9,6 +9,7 @@ private import semmle.code.csharp.frameworks.system.data.Entity private import semmle.code.csharp.frameworks.system.collections.Generic private import semmle.code.csharp.frameworks.Sql private import semmle.code.csharp.dataflow.FlowSummary +private import semmle.code.csharp.dataflow.internal.DataFlowPrivate as DataFlowPrivate /** * Definitions relating to the `System.ComponentModel.DataAnnotations` @@ -74,7 +75,7 @@ module EntityFramework { DbSet() { this.getName() = "DbSet<>" } /** Gets a method that adds or updates entities in a DB set. */ - SummarizableMethod getAnAddOrUpdateMethod(boolean range) { + Method getAnAddOrUpdateMethod(boolean range) { exists(string name | result = this.getAMethod(name) | name in ["Add", "AddAsync", "Attach", "Update"] and range = false @@ -88,23 +89,31 @@ module EntityFramework { /** A flow summary for EntityFramework. */ abstract class EFSummarizedCallable extends SummarizedCallable { } + private class DbSetAddOrUpdateRequiredSummaryComponentStack extends RequiredSummaryComponentStack { + private SummaryComponent head; + + DbSetAddOrUpdateRequiredSummaryComponentStack() { + this = SummaryComponentStack::argument([-1, 0]) and + head = SummaryComponent::element() + } + + override predicate required(SummaryComponent c) { c = head } + } + private class DbSetAddOrUpdate extends EFSummarizedCallable { private boolean range; DbSetAddOrUpdate() { this = any(DbSet c).getAnAddOrUpdateMethod(range) } override predicate propagatesFlow( - SummaryInput input, ContentList inputContents, SummaryOutput output, - ContentList outputContents, boolean preservesValue + SummaryComponentStack input, SummaryComponentStack output, boolean preservesValue ) { - input = SummaryInput::parameter(0) and ( if range = true - then inputContents = ContentList::element() - else inputContents = ContentList::empty() + then input = SummaryComponentStack::elementOf(SummaryComponentStack::argument(0)) + else input = SummaryComponentStack::argument(0) ) and - output = SummaryOutput::thisParameter() and - outputContents = ContentList::element() and + output = SummaryComponentStack::elementOf(SummaryComponentStack::argument(-1)) and preservesValue = true } } @@ -165,27 +174,27 @@ module EntityFramework { } private class RawSqlStringSummarizedCallable extends EFSummarizedCallable { - private SummaryInput input_; - private SummaryOutput output_; + private SummaryComponentStack input_; + private SummaryComponentStack output_; private boolean preservesValue_; RawSqlStringSummarizedCallable() { exists(RawSqlStringStruct s | this = s.getAConstructor() and - input_ = SummaryInput::parameter(0) and + input_ = SummaryComponentStack::argument(0) and this.getNumberOfParameters() > 0 and - output_ = SummaryOutput::return() and + output_ = SummaryComponentStack::return() and preservesValue_ = false or this = s.getAConversionTo() and - input_ = SummaryInput::parameter(0) and - output_ = SummaryOutput::return() and + input_ = SummaryComponentStack::argument(0) and + output_ = SummaryComponentStack::return() and preservesValue_ = false ) } override predicate propagatesFlow( - SummaryInput input, SummaryOutput output, boolean preservesValue + SummaryComponentStack input, SummaryComponentStack output, boolean preservesValue ) { input = input_ and output = output_ and @@ -295,15 +304,17 @@ module EntityFramework { * If `t2` is a column type, `c2` will be included in the model (see * https://docs.microsoft.com/en-us/ef/core/modeling/entity-types?tabs=data-annotations). */ - private predicate step(Content c1, Type t1, Content c2, Type t2) { + private predicate step(Content c1, Type t1, Content c2, Type t2, int dist) { exists(Property p1 | p1 = this.getADbSetProperty(t2) and c1.(PropertyContent).getProperty() = p1 and t1 = p1.getType() and - c2 instanceof ElementContent + c2 instanceof ElementContent and + dist = 0 ) or - step(_, _, c1, t1) and + step(_, _, c1, t1, dist - 1) and + dist < DataFlowPrivate::accessPathLimit() - 1 and not isNotMapped(t2) and ( // Navigation property (https://docs.microsoft.com/en-us/ef/ef6/fundamentals/relationships) @@ -350,52 +361,61 @@ module EntityFramework { * } * ``` */ - private Property getAColumnProperty() { + Property getAColumnProperty(int dist) { exists(PropertyContent c, Type t | - this.step(_, _, c, t) and + this.step(_, _, c, t, dist) and c.getProperty() = result and isColumnType(t) ) } + private predicate stepRev(Content c1, Type t1, Content c2, Type t2, int dist) { + step(c1, t1, c2, t2, dist) and + c2.(PropertyContent).getProperty() = getAColumnProperty(dist) + or + stepRev(c2, t2, _, _, dist + 1) and + step(c1, t1, c2, t2, dist) + } + /** Gets a `SaveChanges[Async]` method. */ pragma[nomagic] - SummarizableMethod getASaveChanges() { + Method getASaveChanges() { this.hasMethod(result) and result.getName().matches("SaveChanges%") } - /** Holds if content list `head :: tail` is required. */ - predicate requiresContentList( - Content head, Type headType, ContentList tail, Type tailType, Property last + /** Holds if component stack `head :: tail` is required for the input specification. */ + predicate requiresComponentStackIn( + Content head, Type headType, SummaryComponentStack tail, int dist ) { - exists(PropertyContent p | - last = this.getAColumnProperty() and - p.getProperty() = last and - tail = ContentList::singleton(p) and - this.step(head, headType, p, tailType) - ) + tail = SummaryComponentStack::qualifier() and + this.stepRev(head, headType, _, _, 0) and + dist = -1 or - exists(Content tailHead, ContentList tailTail | - this.requiresContentList(tailHead, tailType, tailTail, _, last) and - tail = ContentList::cons(tailHead, tailTail) and - this.step(head, headType, tailHead, tailType) + exists(Content tailHead, Type tailType, SummaryComponentStack tailTail | + this.requiresComponentStackIn(tailHead, tailType, tailTail, dist - 1) and + tail = SummaryComponentStack::push(SummaryComponent::content(tailHead), tailTail) and + this.stepRev(tailHead, tailType, head, headType, dist) ) } - /** - * Holds if the access path obtained by concatenating `head` onto `tail` - * is a path from `dbSet` (which is a `DbSet` property belonging to - * this DB context) to `last`, which is a property that is mapped directly - * to a column in the underlying DB. - */ - pragma[noinline] - predicate pathFromDbSetToDbProperty( - Property dbSet, PropertyContent head, ContentList tail, Property last + /** Holds if component stack `head :: tail` is required for the output specification. */ + predicate requiresComponentStackOut( + Content head, Type headType, SummaryComponentStack tail, int dist ) { - this.requiresContentList(head, _, tail, _, last) and - head.getProperty() = dbSet and - dbSet = this.getADbSetProperty(_) + exists(Property dbSetProp, PropertyContent c1 | + dbSetProp = this.getADbSetProperty(headType) and + this.stepRev(c1, _, head, headType, 0) and + c1.getProperty() = dbSetProp and + tail = SummaryComponentStack::jump(dbSetProp.getGetter()) and + dist = 0 + ) + or + exists(Content tailHead, SummaryComponentStack tailTail, Type tailType | + this.requiresComponentStackOut(tailHead, tailType, tailTail, dist - 1) and + tail = SummaryComponentStack::push(SummaryComponent::content(tailHead), tailTail) and + this.stepRev(tailHead, tailType, head, headType, dist) + ) } } @@ -404,26 +424,46 @@ module EntityFramework { DbContextSaveChanges() { this = c.getASaveChanges() } - override predicate requiresContentList(Content head, ContentList tail) { - c.requiresContentList(head, _, tail, _, _) + pragma[noinline] + private predicate input(SummaryComponentStack input, Property mapped) { + exists(PropertyContent head, SummaryComponentStack tail | + c.requiresComponentStackIn(head, _, tail, _) and + head.getProperty() = mapped and + mapped = c.getAColumnProperty(_) and + input = SummaryComponentStack::push(SummaryComponent::content(head), tail) + ) + } + + pragma[noinline] + private predicate output(SummaryComponentStack output, Property mapped) { + exists(PropertyContent head, SummaryComponentStack tail | + c.requiresComponentStackOut(head, _, tail, _) and + head.getProperty() = mapped and + mapped = c.getAColumnProperty(_) and + output = SummaryComponentStack::push(SummaryComponent::content(head), tail) + ) } override predicate propagatesFlow( - SummaryInput input, ContentList inputContents, SummaryOutput output, - ContentList outputContents, boolean preservesValue + SummaryComponentStack input, SummaryComponentStack output, boolean preservesValue ) { exists(Property mapped | preservesValue = true and - exists(PropertyContent sourceHead, ContentList sourceTail | - input = SummaryInput::thisParameter() and - c.pathFromDbSetToDbProperty(_, sourceHead, sourceTail, mapped) and - inputContents = ContentList::cons(sourceHead, sourceTail) - ) and - exists(Property dbSetProp | - output = SummaryOutput::jump(dbSetProp.getGetter(), SummaryOutput::return()) and - c.pathFromDbSetToDbProperty(dbSetProp, _, outputContents, mapped) - ) + input(input, mapped) and + output(output, mapped) ) } } + + private class DbContextSaveChangesRequiredSummaryComponentStack extends RequiredSummaryComponentStack { + private Content head; + + DbContextSaveChangesRequiredSummaryComponentStack() { + any(DbContextClass c).requiresComponentStackIn(head, _, this, _) + or + any(DbContextClass c).requiresComponentStackOut(head, _, this, _) + } + + override predicate required(SummaryComponent c) { c = SummaryComponent::content(head) } + } } diff --git a/csharp/ql/src/semmle/code/csharp/frameworks/Sql.qll b/csharp/ql/src/semmle/code/csharp/frameworks/Sql.qll index 5774b22a631..1a727030bea 100644 --- a/csharp/ql/src/semmle/code/csharp/frameworks/Sql.qll +++ b/csharp/ql/src/semmle/code/csharp/frameworks/Sql.qll @@ -5,6 +5,8 @@ private import semmle.code.csharp.frameworks.system.Data private import semmle.code.csharp.frameworks.system.data.SqlClient private import semmle.code.csharp.frameworks.EntityFramework private import semmle.code.csharp.frameworks.NHibernate +private import semmle.code.csharp.frameworks.Dapper +private import semmle.code.csharp.dataflow.DataFlow4 /** An expression containing a SQL command. */ abstract class SqlExpr extends Expr { @@ -83,3 +85,37 @@ class MicrosoftSqlHelperMethodCallSqlExpr extends SqlExpr, MethodCall { ) } } + +/** A `Dapper.SqlMapper` method that is taking a SQL string argument. */ +class DapperSqlMethodCallSqlExpr extends SqlExpr, MethodCall { + DapperSqlMethodCallSqlExpr() { + this.getTarget() = any(Dapper::SqlMapperClass c).getAQueryMethod() + } + + override Expr getSql() { result = this.getArgumentForName("sql") } +} + +/** A `Dapper.CommandDefinition` creation that is taking a SQL string argument and is passed to a `Dapper.SqlMapper` method. */ +class DapperCommandDefinitionMethodCallSqlExpr extends SqlExpr, ObjectCreation { + DapperCommandDefinitionMethodCallSqlExpr() { + this.getObjectType() instanceof Dapper::CommandDefinitionStruct and + exists(Conf c | c.hasFlow(DataFlow::exprNode(this), _)) + } + + override Expr getSql() { result = this.getArgumentForName("commandText") } +} + +private class Conf extends DataFlow4::Configuration { + Conf() { this = "DapperCommandDefinitionFlowConfig" } + + override predicate isSource(DataFlow::Node node) { + node.asExpr().(ObjectCreation).getObjectType() instanceof Dapper::CommandDefinitionStruct + } + + override predicate isSink(DataFlow::Node node) { + exists(MethodCall mc | + mc.getTarget() = any(Dapper::SqlMapperClass c).getAQueryMethod() and + node.asExpr() = mc.getArgumentForName("command") + ) + } +} diff --git a/csharp/ql/src/semmle/code/dotnet/Element.qll b/csharp/ql/src/semmle/code/dotnet/Element.qll index 956a5f2c052..c38b09ce270 100644 --- a/csharp/ql/src/semmle/code/dotnet/Element.qll +++ b/csharp/ql/src/semmle/code/dotnet/Element.qll @@ -28,6 +28,9 @@ class Element extends @dotnet_element { /** Holds if this element is from source code. */ predicate fromSource() { this.getFile().fromSource() } + /** Holds if this element is from an assembly. */ + predicate fromLibrary() { this.getFile().fromLibrary() } + /** * Gets the "language" of this program element, as defined by the extension of the filename. * For example, C# has language "cs", and Visual Basic has language "vb". diff --git a/csharp/ql/test/library-tests/controlflow/graph/Common.qll b/csharp/ql/test/library-tests/controlflow/graph/Common.qll index 5945d2003b2..f6f9b26f1cd 100644 --- a/csharp/ql/test/library-tests/controlflow/graph/Common.qll +++ b/csharp/ql/test/library-tests/controlflow/graph/Common.qll @@ -11,9 +11,15 @@ class SourceControlFlowElement extends ControlFlowElement { } class SourceControlFlowNode extends ControlFlow::Node { - SourceControlFlowNode() { not this.getLocation().getFile() instanceof StubFile } + SourceControlFlowNode() { + not this.getLocation().getFile() instanceof StubFile and + not this.getLocation().getFile().fromLibrary() + } } class SourceBasicBlock extends ControlFlow::BasicBlock { - SourceBasicBlock() { not this.getLocation().getFile() instanceof StubFile } + SourceBasicBlock() { + not this.getLocation().getFile() instanceof StubFile and + not this.getLocation().getFile().fromLibrary() + } } diff --git a/csharp/ql/test/library-tests/controlflow/splits/SplittingStressTest.ql b/csharp/ql/test/library-tests/controlflow/splits/SplittingStressTest.ql index 4a07618c373..2c637ff0db1 100644 --- a/csharp/ql/test/library-tests/controlflow/splits/SplittingStressTest.ql +++ b/csharp/ql/test/library-tests/controlflow/splits/SplittingStressTest.ql @@ -1,6 +1,7 @@ import csharp query predicate countSplits(ControlFlowElement cfe, int i) { + not cfe.fromLibrary() and i = strictcount(ControlFlow::Nodes::ElementNode n | n.getElement() = cfe) } diff --git a/csharp/ql/test/library-tests/csharp7.1/DefaultLiterals.ql b/csharp/ql/test/library-tests/csharp7.1/DefaultLiterals.ql index 63e5a69b6e5..578b7e7fef4 100644 --- a/csharp/ql/test/library-tests/csharp7.1/DefaultLiterals.ql +++ b/csharp/ql/test/library-tests/csharp7.1/DefaultLiterals.ql @@ -1,4 +1,5 @@ import csharp from DefaultValueExpr l +where l.fromSource() select l, l.getValue() diff --git a/csharp/ql/test/library-tests/csharp7/GlobalFlow.expected b/csharp/ql/test/library-tests/csharp7/GlobalFlow.expected index 9e928eddbf9..1c058bc57f8 100644 --- a/csharp/ql/test/library-tests/csharp7/GlobalFlow.expected +++ b/csharp/ql/test/library-tests/csharp7/GlobalFlow.expected @@ -4,9 +4,9 @@ edges | CSharp7.cs:51:22:51:23 | SSA def(t1) : String | CSharp7.cs:53:18:53:19 | access to local variable t1 | | CSharp7.cs:57:11:57:19 | "tainted" : String | CSharp7.cs:57:30:57:31 | SSA def(t4) : String | | CSharp7.cs:57:30:57:31 | SSA def(t4) : String | CSharp7.cs:58:18:58:19 | access to local variable t4 | -| CSharp7.cs:89:18:89:34 | (..., ...) [Item1] : String | CSharp7.cs:92:20:92:21 | access to local variable t1 [Item1] : String | -| CSharp7.cs:89:19:89:27 | "tainted" : String | CSharp7.cs:89:18:89:34 | (..., ...) [Item1] : String | -| CSharp7.cs:92:20:92:21 | access to local variable t1 [Item1] : String | CSharp7.cs:92:20:92:27 | access to field Item1 : String | +| CSharp7.cs:89:18:89:34 | (..., ...) [field Item1] : String | CSharp7.cs:92:20:92:21 | access to local variable t1 [field Item1] : String | +| CSharp7.cs:89:19:89:27 | "tainted" : String | CSharp7.cs:89:18:89:34 | (..., ...) [field Item1] : String | +| CSharp7.cs:92:20:92:21 | access to local variable t1 [field Item1] : String | CSharp7.cs:92:20:92:27 | access to field Item1 : String | | CSharp7.cs:92:20:92:27 | access to field Item1 : String | CSharp7.cs:92:18:92:28 | call to method I | | CSharp7.cs:177:22:177:30 | "tainted" : String | CSharp7.cs:183:23:183:25 | access to local variable src : String | | CSharp7.cs:177:22:177:30 | "tainted" : String | CSharp7.cs:184:23:184:25 | access to local variable src : String | @@ -20,10 +20,10 @@ nodes | CSharp7.cs:57:11:57:19 | "tainted" : String | semmle.label | "tainted" : String | | CSharp7.cs:57:30:57:31 | SSA def(t4) : String | semmle.label | SSA def(t4) : String | | CSharp7.cs:58:18:58:19 | access to local variable t4 | semmle.label | access to local variable t4 | -| CSharp7.cs:89:18:89:34 | (..., ...) [Item1] : String | semmle.label | (..., ...) [Item1] : String | +| CSharp7.cs:89:18:89:34 | (..., ...) [field Item1] : String | semmle.label | (..., ...) [field Item1] : String | | CSharp7.cs:89:19:89:27 | "tainted" : String | semmle.label | "tainted" : String | | CSharp7.cs:92:18:92:28 | call to method I | semmle.label | call to method I | -| CSharp7.cs:92:20:92:21 | access to local variable t1 [Item1] : String | semmle.label | access to local variable t1 [Item1] : String | +| CSharp7.cs:92:20:92:21 | access to local variable t1 [field Item1] : String | semmle.label | access to local variable t1 [field Item1] : String | | CSharp7.cs:92:20:92:27 | access to field Item1 : String | semmle.label | access to field Item1 : String | | CSharp7.cs:177:22:177:30 | "tainted" | semmle.label | "tainted" | | CSharp7.cs:177:22:177:30 | "tainted" : String | semmle.label | "tainted" : String | diff --git a/csharp/ql/test/library-tests/csharp7/GlobalTaintTracking.expected b/csharp/ql/test/library-tests/csharp7/GlobalTaintTracking.expected index 5a04e010d6b..905162f0bbb 100644 --- a/csharp/ql/test/library-tests/csharp7/GlobalTaintTracking.expected +++ b/csharp/ql/test/library-tests/csharp7/GlobalTaintTracking.expected @@ -4,9 +4,9 @@ edges | CSharp7.cs:51:22:51:23 | SSA def(t1) : String | CSharp7.cs:53:18:53:19 | access to local variable t1 | | CSharp7.cs:57:11:57:19 | "tainted" : String | CSharp7.cs:57:30:57:31 | SSA def(t4) : String | | CSharp7.cs:57:30:57:31 | SSA def(t4) : String | CSharp7.cs:58:18:58:19 | access to local variable t4 | -| CSharp7.cs:89:18:89:34 | (..., ...) [Item1] : String | CSharp7.cs:92:20:92:21 | access to local variable t1 [Item1] : String | -| CSharp7.cs:89:19:89:27 | "tainted" : String | CSharp7.cs:89:18:89:34 | (..., ...) [Item1] : String | -| CSharp7.cs:92:20:92:21 | access to local variable t1 [Item1] : String | CSharp7.cs:92:20:92:27 | access to field Item1 : String | +| CSharp7.cs:89:18:89:34 | (..., ...) [field Item1] : String | CSharp7.cs:92:20:92:21 | access to local variable t1 [field Item1] : String | +| CSharp7.cs:89:19:89:27 | "tainted" : String | CSharp7.cs:89:18:89:34 | (..., ...) [field Item1] : String | +| CSharp7.cs:92:20:92:21 | access to local variable t1 [field Item1] : String | CSharp7.cs:92:20:92:27 | access to field Item1 : String | | CSharp7.cs:92:20:92:27 | access to field Item1 : String | CSharp7.cs:92:18:92:28 | call to method I | | CSharp7.cs:177:22:177:30 | "tainted" : String | CSharp7.cs:182:23:182:25 | access to local variable src : String | | CSharp7.cs:177:22:177:30 | "tainted" : String | CSharp7.cs:183:23:183:25 | access to local variable src : String | @@ -22,10 +22,10 @@ nodes | CSharp7.cs:57:11:57:19 | "tainted" : String | semmle.label | "tainted" : String | | CSharp7.cs:57:30:57:31 | SSA def(t4) : String | semmle.label | SSA def(t4) : String | | CSharp7.cs:58:18:58:19 | access to local variable t4 | semmle.label | access to local variable t4 | -| CSharp7.cs:89:18:89:34 | (..., ...) [Item1] : String | semmle.label | (..., ...) [Item1] : String | +| CSharp7.cs:89:18:89:34 | (..., ...) [field Item1] : String | semmle.label | (..., ...) [field Item1] : String | | CSharp7.cs:89:19:89:27 | "tainted" : String | semmle.label | "tainted" : String | | CSharp7.cs:92:18:92:28 | call to method I | semmle.label | call to method I | -| CSharp7.cs:92:20:92:21 | access to local variable t1 [Item1] : String | semmle.label | access to local variable t1 [Item1] : String | +| CSharp7.cs:92:20:92:21 | access to local variable t1 [field Item1] : String | semmle.label | access to local variable t1 [field Item1] : String | | CSharp7.cs:92:20:92:27 | access to field Item1 : String | semmle.label | access to field Item1 : String | | CSharp7.cs:177:22:177:30 | "tainted" | semmle.label | "tainted" | | CSharp7.cs:177:22:177:30 | "tainted" : String | semmle.label | "tainted" : String | diff --git a/csharp/ql/test/library-tests/csharp7/LocalTaintFlow.ql b/csharp/ql/test/library-tests/csharp7/LocalTaintFlow.ql index 22f61aacdd8..ed293efc2ba 100644 --- a/csharp/ql/test/library-tests/csharp7/LocalTaintFlow.ql +++ b/csharp/ql/test/library-tests/csharp7/LocalTaintFlow.ql @@ -2,5 +2,7 @@ import csharp import semmle.code.csharp.dataflow.TaintTracking from DataFlow::Node pred, DataFlow::Node succ -where TaintTracking::localTaintStep(pred, succ) +where + TaintTracking::localTaintStep(pred, succ) and + not pred.asExpr().fromLibrary() select pred, succ diff --git a/csharp/ql/test/library-tests/dataflow/async/Async.cs b/csharp/ql/test/library-tests/dataflow/async/Async.cs new file mode 100644 index 00000000000..feb30fbbc49 --- /dev/null +++ b/csharp/ql/test/library-tests/dataflow/async/Async.cs @@ -0,0 +1,52 @@ +using System.Threading.Tasks; + +class Test +{ + private void Sink(string s) + { + } + + public void TestNonAwait(string input) + { + Sink(Return(input)); + } + + private string Return(string x) + { + return x; + } + + public async Task TestAwait1(string input) + { + Sink(await ReturnAwait(input)); + } + + public async Task TestAwait2(string input) + { + var x = await ReturnAwait(input); + Sink(x); + } + + public void TestAwait3(string input) + { + Sink(ReturnAwait2(input).Result); + } + + private async Task ReturnAwait(string x) + { + await Task.Delay(1); + return x; + } + + public void TestTask(string input) + { + Sink(ReturnTask(input).Result); + } + + private Task ReturnTask(string x) + { + return Task.FromResult(x); + } + + private async Task ReturnAwait2(string x) => x; +} \ No newline at end of file diff --git a/csharp/ql/test/library-tests/dataflow/async/Async.expected b/csharp/ql/test/library-tests/dataflow/async/Async.expected new file mode 100644 index 00000000000..6e1434dcf68 --- /dev/null +++ b/csharp/ql/test/library-tests/dataflow/async/Async.expected @@ -0,0 +1,67 @@ +edges +| Async.cs:9:37:9:41 | input : String | Async.cs:11:21:11:25 | access to parameter input : String | +| Async.cs:11:21:11:25 | access to parameter input : String | Async.cs:11:14:11:26 | call to method Return | +| Async.cs:14:34:14:34 | x : String | Async.cs:16:16:16:16 | access to parameter x : String | +| Async.cs:16:16:16:16 | access to parameter x : String | Async.cs:11:14:11:26 | call to method Return | +| Async.cs:19:41:19:45 | input : String | Async.cs:21:32:21:36 | access to parameter input : String | +| Async.cs:21:20:21:37 | call to method ReturnAwait [property Result] : String | Async.cs:21:14:21:37 | await ... | +| Async.cs:21:32:21:36 | access to parameter input : String | Async.cs:21:20:21:37 | call to method ReturnAwait [property Result] : String | +| Async.cs:24:41:24:45 | input : String | Async.cs:26:35:26:39 | access to parameter input : String | +| Async.cs:26:17:26:40 | await ... : String | Async.cs:27:14:27:14 | access to local variable x | +| Async.cs:26:23:26:40 | call to method ReturnAwait [property Result] : String | Async.cs:26:17:26:40 | await ... : String | +| Async.cs:26:35:26:39 | access to parameter input : String | Async.cs:26:23:26:40 | call to method ReturnAwait [property Result] : String | +| Async.cs:30:35:30:39 | input : String | Async.cs:32:27:32:31 | access to parameter input : String | +| Async.cs:32:14:32:32 | call to method ReturnAwait2 [property Result] : String | Async.cs:32:14:32:39 | access to property Result | +| Async.cs:32:27:32:31 | access to parameter input : String | Async.cs:32:14:32:32 | call to method ReturnAwait2 [property Result] : String | +| Async.cs:35:51:35:51 | x : String | Async.cs:38:16:38:16 | access to parameter x : String | +| Async.cs:38:16:38:16 | access to parameter x : String | Async.cs:21:20:21:37 | call to method ReturnAwait [property Result] : String | +| Async.cs:38:16:38:16 | access to parameter x : String | Async.cs:26:23:26:40 | call to method ReturnAwait [property Result] : String | +| Async.cs:41:33:41:37 | input : String | Async.cs:43:25:43:29 | access to parameter input : String | +| Async.cs:43:14:43:30 | call to method ReturnTask [property Result] : String | Async.cs:43:14:43:37 | access to property Result | +| Async.cs:43:25:43:29 | access to parameter input : String | Async.cs:43:14:43:30 | call to method ReturnTask [property Result] : String | +| Async.cs:46:44:46:44 | x : String | Async.cs:48:32:48:32 | access to parameter x : String | +| Async.cs:48:16:48:33 | call to method FromResult [property Result] : String | Async.cs:43:14:43:30 | call to method ReturnTask [property Result] : String | +| Async.cs:48:32:48:32 | access to parameter x : String | Async.cs:48:16:48:33 | call to method FromResult [property Result] : String | +| Async.cs:51:52:51:52 | x : String | Async.cs:51:58:51:58 | access to parameter x : String | +| Async.cs:51:58:51:58 | access to parameter x : String | Async.cs:32:14:32:32 | call to method ReturnAwait2 [property Result] : String | +nodes +| Async.cs:9:37:9:41 | input : String | semmle.label | input : String | +| Async.cs:11:14:11:26 | call to method Return | semmle.label | call to method Return | +| Async.cs:11:21:11:25 | access to parameter input : String | semmle.label | access to parameter input : String | +| Async.cs:14:34:14:34 | x : String | semmle.label | x : String | +| Async.cs:16:16:16:16 | access to parameter x : String | semmle.label | access to parameter x : String | +| Async.cs:19:41:19:45 | input : String | semmle.label | input : String | +| Async.cs:21:14:21:37 | await ... | semmle.label | await ... | +| Async.cs:21:20:21:37 | call to method ReturnAwait [property Result] : String | semmle.label | call to method ReturnAwait [property Result] : String | +| Async.cs:21:32:21:36 | access to parameter input : String | semmle.label | access to parameter input : String | +| Async.cs:24:41:24:45 | input : String | semmle.label | input : String | +| Async.cs:26:17:26:40 | await ... : String | semmle.label | await ... : String | +| Async.cs:26:23:26:40 | call to method ReturnAwait [property Result] : String | semmle.label | call to method ReturnAwait [property Result] : String | +| Async.cs:26:35:26:39 | access to parameter input : String | semmle.label | access to parameter input : String | +| Async.cs:27:14:27:14 | access to local variable x | semmle.label | access to local variable x | +| Async.cs:30:35:30:39 | input : String | semmle.label | input : String | +| Async.cs:32:14:32:32 | call to method ReturnAwait2 [property Result] : String | semmle.label | call to method ReturnAwait2 [property Result] : String | +| Async.cs:32:14:32:39 | access to property Result | semmle.label | access to property Result | +| Async.cs:32:27:32:31 | access to parameter input : String | semmle.label | access to parameter input : String | +| Async.cs:35:51:35:51 | x : String | semmle.label | x : String | +| Async.cs:38:16:38:16 | access to parameter x : String | semmle.label | access to parameter x : String | +| Async.cs:41:33:41:37 | input : String | semmle.label | input : String | +| Async.cs:43:14:43:30 | call to method ReturnTask [property Result] : String | semmle.label | call to method ReturnTask [property Result] : String | +| Async.cs:43:14:43:37 | access to property Result | semmle.label | access to property Result | +| Async.cs:43:25:43:29 | access to parameter input : String | semmle.label | access to parameter input : String | +| Async.cs:46:44:46:44 | x : String | semmle.label | x : String | +| Async.cs:48:16:48:33 | call to method FromResult [property Result] : String | semmle.label | call to method FromResult [property Result] : String | +| Async.cs:48:32:48:32 | access to parameter x : String | semmle.label | access to parameter x : String | +| Async.cs:51:52:51:52 | x : String | semmle.label | x : String | +| Async.cs:51:58:51:58 | access to parameter x : String | semmle.label | access to parameter x : String | +#select +| Async.cs:11:14:11:26 | call to method Return | Async.cs:9:37:9:41 | input : String | Async.cs:11:14:11:26 | call to method Return | $@ flows to here and is used. | Async.cs:9:37:9:41 | input | User-provided value | +| Async.cs:11:14:11:26 | call to method Return | Async.cs:14:34:14:34 | x : String | Async.cs:11:14:11:26 | call to method Return | $@ flows to here and is used. | Async.cs:14:34:14:34 | x | User-provided value | +| Async.cs:21:14:21:37 | await ... | Async.cs:19:41:19:45 | input : String | Async.cs:21:14:21:37 | await ... | $@ flows to here and is used. | Async.cs:19:41:19:45 | input | User-provided value | +| Async.cs:21:14:21:37 | await ... | Async.cs:35:51:35:51 | x : String | Async.cs:21:14:21:37 | await ... | $@ flows to here and is used. | Async.cs:35:51:35:51 | x | User-provided value | +| Async.cs:27:14:27:14 | access to local variable x | Async.cs:24:41:24:45 | input : String | Async.cs:27:14:27:14 | access to local variable x | $@ flows to here and is used. | Async.cs:24:41:24:45 | input | User-provided value | +| Async.cs:27:14:27:14 | access to local variable x | Async.cs:35:51:35:51 | x : String | Async.cs:27:14:27:14 | access to local variable x | $@ flows to here and is used. | Async.cs:35:51:35:51 | x | User-provided value | +| Async.cs:32:14:32:39 | access to property Result | Async.cs:30:35:30:39 | input : String | Async.cs:32:14:32:39 | access to property Result | $@ flows to here and is used. | Async.cs:30:35:30:39 | input | User-provided value | +| Async.cs:32:14:32:39 | access to property Result | Async.cs:51:52:51:52 | x : String | Async.cs:32:14:32:39 | access to property Result | $@ flows to here and is used. | Async.cs:51:52:51:52 | x | User-provided value | +| Async.cs:43:14:43:37 | access to property Result | Async.cs:41:33:41:37 | input : String | Async.cs:43:14:43:37 | access to property Result | $@ flows to here and is used. | Async.cs:41:33:41:37 | input | User-provided value | +| Async.cs:43:14:43:37 | access to property Result | Async.cs:46:44:46:44 | x : String | Async.cs:43:14:43:37 | access to property Result | $@ flows to here and is used. | Async.cs:46:44:46:44 | x | User-provided value | diff --git a/csharp/ql/test/library-tests/dataflow/async/Async.ql b/csharp/ql/test/library-tests/dataflow/async/Async.ql new file mode 100644 index 00000000000..71799e22f8a --- /dev/null +++ b/csharp/ql/test/library-tests/dataflow/async/Async.ql @@ -0,0 +1,33 @@ +import csharp +import semmle.code.csharp.dataflow.DataFlow::DataFlow::PathGraph + +class MySink extends DataFlow::ExprNode { + MySink() { + exists(Method m, MethodCall mc | + mc.getTarget() = m and + m.getName() = "Sink" and + this.getExpr() = mc.getArgumentForName("s") + ) + } +} + +class MySource extends DataFlow::ParameterNode { + MySource() { + exists(Parameter p | p = this.getParameter() | + p = any(Class c | c.hasQualifiedName("Test")).getAMethod().getAParameter() + ) + } +} + +class MyConfig extends TaintTracking::Configuration { + MyConfig() { this = "MyConfig" } + + override predicate isSource(DataFlow::Node source) { source instanceof MySource } + + override predicate isSink(DataFlow::Node sink) { sink instanceof MySink } +} + +from MyConfig c, DataFlow::PathNode source, DataFlow::PathNode sink +where c.hasFlowPath(source, sink) +select sink.getNode(), source, sink, "$@ flows to here and is used.", source.getNode(), + "User-provided value" diff --git a/csharp/ql/test/library-tests/dataflow/collections/CollectionFlow.expected b/csharp/ql/test/library-tests/dataflow/collections/CollectionFlow.expected index 3c27e96311b..3295c03ac94 100644 --- a/csharp/ql/test/library-tests/dataflow/collections/CollectionFlow.expected +++ b/csharp/ql/test/library-tests/dataflow/collections/CollectionFlow.expected @@ -1,367 +1,367 @@ edges | CollectionFlow.cs:14:17:14:23 | object creation of type A : A | CollectionFlow.cs:15:27:15:27 | access to local variable a : A | -| CollectionFlow.cs:15:25:15:29 | { ..., ... } [[]] : A | CollectionFlow.cs:16:14:16:16 | access to local variable as [[]] : A | -| CollectionFlow.cs:15:25:15:29 | { ..., ... } [[]] : A | CollectionFlow.cs:17:18:17:20 | access to local variable as [[]] : A | -| CollectionFlow.cs:15:25:15:29 | { ..., ... } [[]] : A | CollectionFlow.cs:18:20:18:22 | access to local variable as [[]] : A | -| CollectionFlow.cs:15:27:15:27 | access to local variable a : A | CollectionFlow.cs:15:25:15:29 | { ..., ... } [[]] : A | -| CollectionFlow.cs:16:14:16:16 | access to local variable as [[]] : A | CollectionFlow.cs:16:14:16:19 | access to array element | -| CollectionFlow.cs:17:18:17:20 | access to local variable as [[]] : A | CollectionFlow.cs:374:40:374:41 | ts [[]] : A | -| CollectionFlow.cs:18:20:18:22 | access to local variable as [[]] : A | CollectionFlow.cs:18:14:18:23 | call to method First | +| CollectionFlow.cs:15:25:15:29 | { ..., ... } [element] : A | CollectionFlow.cs:16:14:16:16 | access to local variable as [element] : A | +| CollectionFlow.cs:15:25:15:29 | { ..., ... } [element] : A | CollectionFlow.cs:17:18:17:20 | access to local variable as [element] : A | +| CollectionFlow.cs:15:25:15:29 | { ..., ... } [element] : A | CollectionFlow.cs:18:20:18:22 | access to local variable as [element] : A | +| CollectionFlow.cs:15:27:15:27 | access to local variable a : A | CollectionFlow.cs:15:25:15:29 | { ..., ... } [element] : A | +| CollectionFlow.cs:16:14:16:16 | access to local variable as [element] : A | CollectionFlow.cs:16:14:16:19 | access to array element | +| CollectionFlow.cs:17:18:17:20 | access to local variable as [element] : A | CollectionFlow.cs:374:40:374:41 | ts [element] : A | +| CollectionFlow.cs:18:20:18:22 | access to local variable as [element] : A | CollectionFlow.cs:18:14:18:23 | call to method First | | CollectionFlow.cs:32:17:32:23 | object creation of type A : A | CollectionFlow.cs:33:53:33:53 | access to local variable a : A | -| CollectionFlow.cs:33:38:33:57 | { ..., ... } [As, []] : A | CollectionFlow.cs:34:14:34:14 | access to local variable c [As, []] : A | -| CollectionFlow.cs:33:38:33:57 | { ..., ... } [As, []] : A | CollectionFlow.cs:35:18:35:18 | access to local variable c [As, []] : A | -| CollectionFlow.cs:33:38:33:57 | { ..., ... } [As, []] : A | CollectionFlow.cs:36:20:36:20 | access to local variable c [As, []] : A | -| CollectionFlow.cs:33:45:33:55 | { ..., ... } [[]] : A | CollectionFlow.cs:33:38:33:57 | { ..., ... } [As, []] : A | -| CollectionFlow.cs:33:53:33:53 | access to local variable a : A | CollectionFlow.cs:33:45:33:55 | { ..., ... } [[]] : A | -| CollectionFlow.cs:34:14:34:14 | access to local variable c [As, []] : A | CollectionFlow.cs:34:14:34:17 | access to field As [[]] : A | -| CollectionFlow.cs:34:14:34:17 | access to field As [[]] : A | CollectionFlow.cs:34:14:34:20 | access to array element | -| CollectionFlow.cs:35:18:35:18 | access to local variable c [As, []] : A | CollectionFlow.cs:35:18:35:21 | access to field As [[]] : A | -| CollectionFlow.cs:35:18:35:21 | access to field As [[]] : A | CollectionFlow.cs:374:40:374:41 | ts [[]] : A | -| CollectionFlow.cs:36:20:36:20 | access to local variable c [As, []] : A | CollectionFlow.cs:36:20:36:23 | access to field As [[]] : A | -| CollectionFlow.cs:36:20:36:23 | access to field As [[]] : A | CollectionFlow.cs:36:14:36:24 | call to method First | +| CollectionFlow.cs:33:38:33:57 | { ..., ... } [field As, element] : A | CollectionFlow.cs:34:14:34:14 | access to local variable c [field As, element] : A | +| CollectionFlow.cs:33:38:33:57 | { ..., ... } [field As, element] : A | CollectionFlow.cs:35:18:35:18 | access to local variable c [field As, element] : A | +| CollectionFlow.cs:33:38:33:57 | { ..., ... } [field As, element] : A | CollectionFlow.cs:36:20:36:20 | access to local variable c [field As, element] : A | +| CollectionFlow.cs:33:45:33:55 | { ..., ... } [element] : A | CollectionFlow.cs:33:38:33:57 | { ..., ... } [field As, element] : A | +| CollectionFlow.cs:33:53:33:53 | access to local variable a : A | CollectionFlow.cs:33:45:33:55 | { ..., ... } [element] : A | +| CollectionFlow.cs:34:14:34:14 | access to local variable c [field As, element] : A | CollectionFlow.cs:34:14:34:17 | access to field As [element] : A | +| CollectionFlow.cs:34:14:34:17 | access to field As [element] : A | CollectionFlow.cs:34:14:34:20 | access to array element | +| CollectionFlow.cs:35:18:35:18 | access to local variable c [field As, element] : A | CollectionFlow.cs:35:18:35:21 | access to field As [element] : A | +| CollectionFlow.cs:35:18:35:21 | access to field As [element] : A | CollectionFlow.cs:374:40:374:41 | ts [element] : A | +| CollectionFlow.cs:36:20:36:20 | access to local variable c [field As, element] : A | CollectionFlow.cs:36:20:36:23 | access to field As [element] : A | +| CollectionFlow.cs:36:20:36:23 | access to field As [element] : A | CollectionFlow.cs:36:14:36:24 | call to method First | | CollectionFlow.cs:50:17:50:23 | object creation of type A : A | CollectionFlow.cs:52:18:52:18 | access to local variable a : A | -| CollectionFlow.cs:52:9:52:11 | [post] access to local variable as [[]] : A | CollectionFlow.cs:53:14:53:16 | access to local variable as [[]] : A | -| CollectionFlow.cs:52:9:52:11 | [post] access to local variable as [[]] : A | CollectionFlow.cs:54:18:54:20 | access to local variable as [[]] : A | -| CollectionFlow.cs:52:9:52:11 | [post] access to local variable as [[]] : A | CollectionFlow.cs:55:20:55:22 | access to local variable as [[]] : A | -| CollectionFlow.cs:52:18:52:18 | access to local variable a : A | CollectionFlow.cs:52:9:52:11 | [post] access to local variable as [[]] : A | -| CollectionFlow.cs:53:14:53:16 | access to local variable as [[]] : A | CollectionFlow.cs:53:14:53:19 | access to array element | -| CollectionFlow.cs:54:18:54:20 | access to local variable as [[]] : A | CollectionFlow.cs:374:40:374:41 | ts [[]] : A | -| CollectionFlow.cs:55:20:55:22 | access to local variable as [[]] : A | CollectionFlow.cs:55:14:55:23 | call to method First | +| CollectionFlow.cs:52:9:52:11 | [post] access to local variable as [element] : A | CollectionFlow.cs:53:14:53:16 | access to local variable as [element] : A | +| CollectionFlow.cs:52:9:52:11 | [post] access to local variable as [element] : A | CollectionFlow.cs:54:18:54:20 | access to local variable as [element] : A | +| CollectionFlow.cs:52:9:52:11 | [post] access to local variable as [element] : A | CollectionFlow.cs:55:20:55:22 | access to local variable as [element] : A | +| CollectionFlow.cs:52:18:52:18 | access to local variable a : A | CollectionFlow.cs:52:9:52:11 | [post] access to local variable as [element] : A | +| CollectionFlow.cs:53:14:53:16 | access to local variable as [element] : A | CollectionFlow.cs:53:14:53:19 | access to array element | +| CollectionFlow.cs:54:18:54:20 | access to local variable as [element] : A | CollectionFlow.cs:374:40:374:41 | ts [element] : A | +| CollectionFlow.cs:55:20:55:22 | access to local variable as [element] : A | CollectionFlow.cs:55:14:55:23 | call to method First | | CollectionFlow.cs:70:17:70:23 | object creation of type A : A | CollectionFlow.cs:72:19:72:19 | access to local variable a : A | -| CollectionFlow.cs:72:9:72:12 | [post] access to local variable list [[]] : A | CollectionFlow.cs:73:14:73:17 | access to local variable list [[]] : A | -| CollectionFlow.cs:72:9:72:12 | [post] access to local variable list [[]] : A | CollectionFlow.cs:74:22:74:25 | access to local variable list [[]] : A | -| CollectionFlow.cs:72:9:72:12 | [post] access to local variable list [[]] : A | CollectionFlow.cs:75:24:75:27 | access to local variable list [[]] : A | -| CollectionFlow.cs:72:19:72:19 | access to local variable a : A | CollectionFlow.cs:72:9:72:12 | [post] access to local variable list [[]] : A | -| CollectionFlow.cs:73:14:73:17 | access to local variable list [[]] : A | CollectionFlow.cs:73:14:73:20 | access to indexer | -| CollectionFlow.cs:74:22:74:25 | access to local variable list [[]] : A | CollectionFlow.cs:376:49:376:52 | list [[]] : A | -| CollectionFlow.cs:75:24:75:27 | access to local variable list [[]] : A | CollectionFlow.cs:75:14:75:28 | call to method ListFirst | +| CollectionFlow.cs:72:9:72:12 | [post] access to local variable list [element] : A | CollectionFlow.cs:73:14:73:17 | access to local variable list [element] : A | +| CollectionFlow.cs:72:9:72:12 | [post] access to local variable list [element] : A | CollectionFlow.cs:74:22:74:25 | access to local variable list [element] : A | +| CollectionFlow.cs:72:9:72:12 | [post] access to local variable list [element] : A | CollectionFlow.cs:75:24:75:27 | access to local variable list [element] : A | +| CollectionFlow.cs:72:19:72:19 | access to local variable a : A | CollectionFlow.cs:72:9:72:12 | [post] access to local variable list [element] : A | +| CollectionFlow.cs:73:14:73:17 | access to local variable list [element] : A | CollectionFlow.cs:73:14:73:20 | access to indexer | +| CollectionFlow.cs:74:22:74:25 | access to local variable list [element] : A | CollectionFlow.cs:376:49:376:52 | list [element] : A | +| CollectionFlow.cs:75:24:75:27 | access to local variable list [element] : A | CollectionFlow.cs:75:14:75:28 | call to method ListFirst | | CollectionFlow.cs:89:17:89:23 | object creation of type A : A | CollectionFlow.cs:90:36:90:36 | access to local variable a : A | -| CollectionFlow.cs:90:34:90:38 | { ..., ... } [[]] : A | CollectionFlow.cs:91:14:91:17 | access to local variable list [[]] : A | -| CollectionFlow.cs:90:34:90:38 | { ..., ... } [[]] : A | CollectionFlow.cs:92:22:92:25 | access to local variable list [[]] : A | -| CollectionFlow.cs:90:34:90:38 | { ..., ... } [[]] : A | CollectionFlow.cs:93:24:93:27 | access to local variable list [[]] : A | -| CollectionFlow.cs:90:36:90:36 | access to local variable a : A | CollectionFlow.cs:90:34:90:38 | { ..., ... } [[]] : A | -| CollectionFlow.cs:91:14:91:17 | access to local variable list [[]] : A | CollectionFlow.cs:91:14:91:20 | access to indexer | -| CollectionFlow.cs:92:22:92:25 | access to local variable list [[]] : A | CollectionFlow.cs:376:49:376:52 | list [[]] : A | -| CollectionFlow.cs:93:24:93:27 | access to local variable list [[]] : A | CollectionFlow.cs:93:14:93:28 | call to method ListFirst | +| CollectionFlow.cs:90:20:90:38 | object creation of type List [element] : A | CollectionFlow.cs:91:14:91:17 | access to local variable list [element] : A | +| CollectionFlow.cs:90:20:90:38 | object creation of type List [element] : A | CollectionFlow.cs:92:22:92:25 | access to local variable list [element] : A | +| CollectionFlow.cs:90:20:90:38 | object creation of type List [element] : A | CollectionFlow.cs:93:24:93:27 | access to local variable list [element] : A | +| CollectionFlow.cs:90:36:90:36 | access to local variable a : A | CollectionFlow.cs:90:20:90:38 | object creation of type List [element] : A | +| CollectionFlow.cs:91:14:91:17 | access to local variable list [element] : A | CollectionFlow.cs:91:14:91:20 | access to indexer | +| CollectionFlow.cs:92:22:92:25 | access to local variable list [element] : A | CollectionFlow.cs:376:49:376:52 | list [element] : A | +| CollectionFlow.cs:93:24:93:27 | access to local variable list [element] : A | CollectionFlow.cs:93:14:93:28 | call to method ListFirst | | CollectionFlow.cs:106:17:106:23 | object creation of type A : A | CollectionFlow.cs:108:18:108:18 | access to local variable a : A | -| CollectionFlow.cs:108:9:108:12 | [post] access to local variable list [[]] : A | CollectionFlow.cs:109:14:109:17 | access to local variable list [[]] : A | -| CollectionFlow.cs:108:9:108:12 | [post] access to local variable list [[]] : A | CollectionFlow.cs:110:22:110:25 | access to local variable list [[]] : A | -| CollectionFlow.cs:108:9:108:12 | [post] access to local variable list [[]] : A | CollectionFlow.cs:111:24:111:27 | access to local variable list [[]] : A | -| CollectionFlow.cs:108:18:108:18 | access to local variable a : A | CollectionFlow.cs:108:9:108:12 | [post] access to local variable list [[]] : A | -| CollectionFlow.cs:109:14:109:17 | access to local variable list [[]] : A | CollectionFlow.cs:109:14:109:20 | access to indexer | -| CollectionFlow.cs:110:22:110:25 | access to local variable list [[]] : A | CollectionFlow.cs:376:49:376:52 | list [[]] : A | -| CollectionFlow.cs:111:24:111:27 | access to local variable list [[]] : A | CollectionFlow.cs:111:14:111:28 | call to method ListFirst | +| CollectionFlow.cs:108:9:108:12 | [post] access to local variable list [element] : A | CollectionFlow.cs:109:14:109:17 | access to local variable list [element] : A | +| CollectionFlow.cs:108:9:108:12 | [post] access to local variable list [element] : A | CollectionFlow.cs:110:22:110:25 | access to local variable list [element] : A | +| CollectionFlow.cs:108:9:108:12 | [post] access to local variable list [element] : A | CollectionFlow.cs:111:24:111:27 | access to local variable list [element] : A | +| CollectionFlow.cs:108:18:108:18 | access to local variable a : A | CollectionFlow.cs:108:9:108:12 | [post] access to local variable list [element] : A | +| CollectionFlow.cs:109:14:109:17 | access to local variable list [element] : A | CollectionFlow.cs:109:14:109:20 | access to indexer | +| CollectionFlow.cs:110:22:110:25 | access to local variable list [element] : A | CollectionFlow.cs:376:49:376:52 | list [element] : A | +| CollectionFlow.cs:111:24:111:27 | access to local variable list [element] : A | CollectionFlow.cs:111:14:111:28 | call to method ListFirst | | CollectionFlow.cs:125:17:125:23 | object creation of type A : A | CollectionFlow.cs:127:19:127:19 | access to local variable a : A | -| CollectionFlow.cs:127:9:127:12 | [post] access to local variable dict [[], Value] : A | CollectionFlow.cs:128:14:128:17 | access to local variable dict [[], Value] : A | -| CollectionFlow.cs:127:9:127:12 | [post] access to local variable dict [[], Value] : A | CollectionFlow.cs:129:23:129:26 | access to local variable dict [[], Value] : A | -| CollectionFlow.cs:127:9:127:12 | [post] access to local variable dict [[], Value] : A | CollectionFlow.cs:130:28:130:31 | access to local variable dict [[], Value] : A | -| CollectionFlow.cs:127:9:127:12 | [post] access to local variable dict [[], Value] : A | CollectionFlow.cs:131:29:131:32 | access to local variable dict [[], Value] : A | -| CollectionFlow.cs:127:9:127:12 | [post] access to local variable dict [[], Value] : A | CollectionFlow.cs:132:30:132:33 | access to local variable dict [[], Value] : A | -| CollectionFlow.cs:127:19:127:19 | access to local variable a : A | CollectionFlow.cs:127:9:127:12 | [post] access to local variable dict [[], Value] : A | -| CollectionFlow.cs:128:14:128:17 | access to local variable dict [[], Value] : A | CollectionFlow.cs:128:14:128:20 | access to indexer | -| CollectionFlow.cs:129:23:129:26 | access to local variable dict [[], Value] : A | CollectionFlow.cs:378:61:378:64 | dict [[], Value] : A | -| CollectionFlow.cs:130:28:130:31 | access to local variable dict [[], Value] : A | CollectionFlow.cs:130:14:130:32 | call to method DictIndexZero | -| CollectionFlow.cs:131:29:131:32 | access to local variable dict [[], Value] : A | CollectionFlow.cs:131:14:131:33 | call to method DictFirstValue | -| CollectionFlow.cs:132:30:132:33 | access to local variable dict [[], Value] : A | CollectionFlow.cs:132:14:132:34 | call to method DictValuesFirst | +| CollectionFlow.cs:127:9:127:12 | [post] access to local variable dict [element, property Value] : A | CollectionFlow.cs:128:14:128:17 | access to local variable dict [element, property Value] : A | +| CollectionFlow.cs:127:9:127:12 | [post] access to local variable dict [element, property Value] : A | CollectionFlow.cs:129:23:129:26 | access to local variable dict [element, property Value] : A | +| CollectionFlow.cs:127:9:127:12 | [post] access to local variable dict [element, property Value] : A | CollectionFlow.cs:130:28:130:31 | access to local variable dict [element, property Value] : A | +| CollectionFlow.cs:127:9:127:12 | [post] access to local variable dict [element, property Value] : A | CollectionFlow.cs:131:29:131:32 | access to local variable dict [element, property Value] : A | +| CollectionFlow.cs:127:9:127:12 | [post] access to local variable dict [element, property Value] : A | CollectionFlow.cs:132:30:132:33 | access to local variable dict [element, property Value] : A | +| CollectionFlow.cs:127:19:127:19 | access to local variable a : A | CollectionFlow.cs:127:9:127:12 | [post] access to local variable dict [element, property Value] : A | +| CollectionFlow.cs:128:14:128:17 | access to local variable dict [element, property Value] : A | CollectionFlow.cs:128:14:128:20 | access to indexer | +| CollectionFlow.cs:129:23:129:26 | access to local variable dict [element, property Value] : A | CollectionFlow.cs:378:61:378:64 | dict [element, property Value] : A | +| CollectionFlow.cs:130:28:130:31 | access to local variable dict [element, property Value] : A | CollectionFlow.cs:130:14:130:32 | call to method DictIndexZero | +| CollectionFlow.cs:131:29:131:32 | access to local variable dict [element, property Value] : A | CollectionFlow.cs:131:14:131:33 | call to method DictFirstValue | +| CollectionFlow.cs:132:30:132:33 | access to local variable dict [element, property Value] : A | CollectionFlow.cs:132:14:132:34 | call to method DictValuesFirst | | CollectionFlow.cs:148:17:148:23 | object creation of type A : A | CollectionFlow.cs:149:52:149:52 | access to local variable a : A | -| CollectionFlow.cs:149:45:149:56 | { ..., ... } [[], Value] : A | CollectionFlow.cs:150:14:150:17 | access to local variable dict [[], Value] : A | -| CollectionFlow.cs:149:45:149:56 | { ..., ... } [[], Value] : A | CollectionFlow.cs:151:23:151:26 | access to local variable dict [[], Value] : A | -| CollectionFlow.cs:149:45:149:56 | { ..., ... } [[], Value] : A | CollectionFlow.cs:152:28:152:31 | access to local variable dict [[], Value] : A | -| CollectionFlow.cs:149:45:149:56 | { ..., ... } [[], Value] : A | CollectionFlow.cs:153:29:153:32 | access to local variable dict [[], Value] : A | -| CollectionFlow.cs:149:45:149:56 | { ..., ... } [[], Value] : A | CollectionFlow.cs:154:30:154:33 | access to local variable dict [[], Value] : A | -| CollectionFlow.cs:149:52:149:52 | access to local variable a : A | CollectionFlow.cs:149:45:149:56 | { ..., ... } [[], Value] : A | -| CollectionFlow.cs:150:14:150:17 | access to local variable dict [[], Value] : A | CollectionFlow.cs:150:14:150:20 | access to indexer | -| CollectionFlow.cs:151:23:151:26 | access to local variable dict [[], Value] : A | CollectionFlow.cs:378:61:378:64 | dict [[], Value] : A | -| CollectionFlow.cs:152:28:152:31 | access to local variable dict [[], Value] : A | CollectionFlow.cs:152:14:152:32 | call to method DictIndexZero | -| CollectionFlow.cs:153:29:153:32 | access to local variable dict [[], Value] : A | CollectionFlow.cs:153:14:153:33 | call to method DictFirstValue | -| CollectionFlow.cs:154:30:154:33 | access to local variable dict [[], Value] : A | CollectionFlow.cs:154:14:154:34 | call to method DictValuesFirst | +| CollectionFlow.cs:149:20:149:56 | object creation of type Dictionary [element, property Value] : A | CollectionFlow.cs:150:14:150:17 | access to local variable dict [element, property Value] : A | +| CollectionFlow.cs:149:20:149:56 | object creation of type Dictionary [element, property Value] : A | CollectionFlow.cs:151:23:151:26 | access to local variable dict [element, property Value] : A | +| CollectionFlow.cs:149:20:149:56 | object creation of type Dictionary [element, property Value] : A | CollectionFlow.cs:152:28:152:31 | access to local variable dict [element, property Value] : A | +| CollectionFlow.cs:149:20:149:56 | object creation of type Dictionary [element, property Value] : A | CollectionFlow.cs:153:29:153:32 | access to local variable dict [element, property Value] : A | +| CollectionFlow.cs:149:20:149:56 | object creation of type Dictionary [element, property Value] : A | CollectionFlow.cs:154:30:154:33 | access to local variable dict [element, property Value] : A | +| CollectionFlow.cs:149:52:149:52 | access to local variable a : A | CollectionFlow.cs:149:20:149:56 | object creation of type Dictionary [element, property Value] : A | +| CollectionFlow.cs:150:14:150:17 | access to local variable dict [element, property Value] : A | CollectionFlow.cs:150:14:150:20 | access to indexer | +| CollectionFlow.cs:151:23:151:26 | access to local variable dict [element, property Value] : A | CollectionFlow.cs:378:61:378:64 | dict [element, property Value] : A | +| CollectionFlow.cs:152:28:152:31 | access to local variable dict [element, property Value] : A | CollectionFlow.cs:152:14:152:32 | call to method DictIndexZero | +| CollectionFlow.cs:153:29:153:32 | access to local variable dict [element, property Value] : A | CollectionFlow.cs:153:14:153:33 | call to method DictFirstValue | +| CollectionFlow.cs:154:30:154:33 | access to local variable dict [element, property Value] : A | CollectionFlow.cs:154:14:154:34 | call to method DictValuesFirst | | CollectionFlow.cs:169:17:169:23 | object creation of type A : A | CollectionFlow.cs:170:53:170:53 | access to local variable a : A | -| CollectionFlow.cs:170:45:170:55 | { ..., ... } [[], Value] : A | CollectionFlow.cs:171:14:171:17 | access to local variable dict [[], Value] : A | -| CollectionFlow.cs:170:45:170:55 | { ..., ... } [[], Value] : A | CollectionFlow.cs:172:23:172:26 | access to local variable dict [[], Value] : A | -| CollectionFlow.cs:170:45:170:55 | { ..., ... } [[], Value] : A | CollectionFlow.cs:173:28:173:31 | access to local variable dict [[], Value] : A | -| CollectionFlow.cs:170:45:170:55 | { ..., ... } [[], Value] : A | CollectionFlow.cs:174:29:174:32 | access to local variable dict [[], Value] : A | -| CollectionFlow.cs:170:45:170:55 | { ..., ... } [[], Value] : A | CollectionFlow.cs:175:30:175:33 | access to local variable dict [[], Value] : A | -| CollectionFlow.cs:170:53:170:53 | access to local variable a : A | CollectionFlow.cs:170:45:170:55 | { ..., ... } [[], Value] : A | -| CollectionFlow.cs:171:14:171:17 | access to local variable dict [[], Value] : A | CollectionFlow.cs:171:14:171:20 | access to indexer | -| CollectionFlow.cs:172:23:172:26 | access to local variable dict [[], Value] : A | CollectionFlow.cs:378:61:378:64 | dict [[], Value] : A | -| CollectionFlow.cs:173:28:173:31 | access to local variable dict [[], Value] : A | CollectionFlow.cs:173:14:173:32 | call to method DictIndexZero | -| CollectionFlow.cs:174:29:174:32 | access to local variable dict [[], Value] : A | CollectionFlow.cs:174:14:174:33 | call to method DictFirstValue | -| CollectionFlow.cs:175:30:175:33 | access to local variable dict [[], Value] : A | CollectionFlow.cs:175:14:175:34 | call to method DictValuesFirst | +| CollectionFlow.cs:170:20:170:55 | object creation of type Dictionary [element, property Value] : A | CollectionFlow.cs:171:14:171:17 | access to local variable dict [element, property Value] : A | +| CollectionFlow.cs:170:20:170:55 | object creation of type Dictionary [element, property Value] : A | CollectionFlow.cs:172:23:172:26 | access to local variable dict [element, property Value] : A | +| CollectionFlow.cs:170:20:170:55 | object creation of type Dictionary [element, property Value] : A | CollectionFlow.cs:173:28:173:31 | access to local variable dict [element, property Value] : A | +| CollectionFlow.cs:170:20:170:55 | object creation of type Dictionary [element, property Value] : A | CollectionFlow.cs:174:29:174:32 | access to local variable dict [element, property Value] : A | +| CollectionFlow.cs:170:20:170:55 | object creation of type Dictionary [element, property Value] : A | CollectionFlow.cs:175:30:175:33 | access to local variable dict [element, property Value] : A | +| CollectionFlow.cs:170:53:170:53 | access to local variable a : A | CollectionFlow.cs:170:20:170:55 | object creation of type Dictionary [element, property Value] : A | +| CollectionFlow.cs:171:14:171:17 | access to local variable dict [element, property Value] : A | CollectionFlow.cs:171:14:171:20 | access to indexer | +| CollectionFlow.cs:172:23:172:26 | access to local variable dict [element, property Value] : A | CollectionFlow.cs:378:61:378:64 | dict [element, property Value] : A | +| CollectionFlow.cs:173:28:173:31 | access to local variable dict [element, property Value] : A | CollectionFlow.cs:173:14:173:32 | call to method DictIndexZero | +| CollectionFlow.cs:174:29:174:32 | access to local variable dict [element, property Value] : A | CollectionFlow.cs:174:14:174:33 | call to method DictFirstValue | +| CollectionFlow.cs:175:30:175:33 | access to local variable dict [element, property Value] : A | CollectionFlow.cs:175:14:175:34 | call to method DictValuesFirst | | CollectionFlow.cs:191:17:191:23 | object creation of type A : A | CollectionFlow.cs:192:49:192:49 | access to local variable a : A | -| CollectionFlow.cs:192:45:192:56 | { ..., ... } [[], Key] : A | CollectionFlow.cs:193:14:193:17 | access to local variable dict [[], Key] : A | -| CollectionFlow.cs:192:45:192:56 | { ..., ... } [[], Key] : A | CollectionFlow.cs:194:21:194:24 | access to local variable dict [[], Key] : A | -| CollectionFlow.cs:192:45:192:56 | { ..., ... } [[], Key] : A | CollectionFlow.cs:195:28:195:31 | access to local variable dict [[], Key] : A | -| CollectionFlow.cs:192:45:192:56 | { ..., ... } [[], Key] : A | CollectionFlow.cs:196:27:196:30 | access to local variable dict [[], Key] : A | -| CollectionFlow.cs:192:49:192:49 | access to local variable a : A | CollectionFlow.cs:192:45:192:56 | { ..., ... } [[], Key] : A | -| CollectionFlow.cs:193:14:193:17 | access to local variable dict [[], Key] : A | CollectionFlow.cs:193:14:193:22 | access to property Keys [[]] : A | -| CollectionFlow.cs:193:14:193:22 | access to property Keys [[]] : A | CollectionFlow.cs:193:14:193:30 | call to method First | -| CollectionFlow.cs:194:21:194:24 | access to local variable dict [[], Key] : A | CollectionFlow.cs:380:59:380:62 | dict [[], Key] : A | -| CollectionFlow.cs:195:28:195:31 | access to local variable dict [[], Key] : A | CollectionFlow.cs:195:14:195:32 | call to method DictKeysFirst | -| CollectionFlow.cs:196:27:196:30 | access to local variable dict [[], Key] : A | CollectionFlow.cs:196:14:196:31 | call to method DictFirstKey | +| CollectionFlow.cs:192:20:192:56 | object creation of type Dictionary [element, property Key] : A | CollectionFlow.cs:193:14:193:17 | access to local variable dict [element, property Key] : A | +| CollectionFlow.cs:192:20:192:56 | object creation of type Dictionary [element, property Key] : A | CollectionFlow.cs:194:21:194:24 | access to local variable dict [element, property Key] : A | +| CollectionFlow.cs:192:20:192:56 | object creation of type Dictionary [element, property Key] : A | CollectionFlow.cs:195:28:195:31 | access to local variable dict [element, property Key] : A | +| CollectionFlow.cs:192:20:192:56 | object creation of type Dictionary [element, property Key] : A | CollectionFlow.cs:196:27:196:30 | access to local variable dict [element, property Key] : A | +| CollectionFlow.cs:192:49:192:49 | access to local variable a : A | CollectionFlow.cs:192:20:192:56 | object creation of type Dictionary [element, property Key] : A | +| CollectionFlow.cs:193:14:193:17 | access to local variable dict [element, property Key] : A | CollectionFlow.cs:193:14:193:22 | access to property Keys [element] : A | +| CollectionFlow.cs:193:14:193:22 | access to property Keys [element] : A | CollectionFlow.cs:193:14:193:30 | call to method First | +| CollectionFlow.cs:194:21:194:24 | access to local variable dict [element, property Key] : A | CollectionFlow.cs:380:59:380:62 | dict [element, property Key] : A | +| CollectionFlow.cs:195:28:195:31 | access to local variable dict [element, property Key] : A | CollectionFlow.cs:195:14:195:32 | call to method DictKeysFirst | +| CollectionFlow.cs:196:27:196:30 | access to local variable dict [element, property Key] : A | CollectionFlow.cs:196:14:196:31 | call to method DictFirstKey | | CollectionFlow.cs:210:17:210:23 | object creation of type A : A | CollectionFlow.cs:211:48:211:48 | access to local variable a : A | -| CollectionFlow.cs:211:45:211:55 | { ..., ... } [[], Key] : A | CollectionFlow.cs:212:14:212:17 | access to local variable dict [[], Key] : A | -| CollectionFlow.cs:211:45:211:55 | { ..., ... } [[], Key] : A | CollectionFlow.cs:213:21:213:24 | access to local variable dict [[], Key] : A | -| CollectionFlow.cs:211:45:211:55 | { ..., ... } [[], Key] : A | CollectionFlow.cs:214:28:214:31 | access to local variable dict [[], Key] : A | -| CollectionFlow.cs:211:45:211:55 | { ..., ... } [[], Key] : A | CollectionFlow.cs:215:27:215:30 | access to local variable dict [[], Key] : A | -| CollectionFlow.cs:211:48:211:48 | access to local variable a : A | CollectionFlow.cs:211:45:211:55 | { ..., ... } [[], Key] : A | -| CollectionFlow.cs:212:14:212:17 | access to local variable dict [[], Key] : A | CollectionFlow.cs:212:14:212:22 | access to property Keys [[]] : A | -| CollectionFlow.cs:212:14:212:22 | access to property Keys [[]] : A | CollectionFlow.cs:212:14:212:30 | call to method First | -| CollectionFlow.cs:213:21:213:24 | access to local variable dict [[], Key] : A | CollectionFlow.cs:380:59:380:62 | dict [[], Key] : A | -| CollectionFlow.cs:214:28:214:31 | access to local variable dict [[], Key] : A | CollectionFlow.cs:214:14:214:32 | call to method DictKeysFirst | -| CollectionFlow.cs:215:27:215:30 | access to local variable dict [[], Key] : A | CollectionFlow.cs:215:14:215:31 | call to method DictFirstKey | +| CollectionFlow.cs:211:20:211:55 | object creation of type Dictionary [element, property Key] : A | CollectionFlow.cs:212:14:212:17 | access to local variable dict [element, property Key] : A | +| CollectionFlow.cs:211:20:211:55 | object creation of type Dictionary [element, property Key] : A | CollectionFlow.cs:213:21:213:24 | access to local variable dict [element, property Key] : A | +| CollectionFlow.cs:211:20:211:55 | object creation of type Dictionary [element, property Key] : A | CollectionFlow.cs:214:28:214:31 | access to local variable dict [element, property Key] : A | +| CollectionFlow.cs:211:20:211:55 | object creation of type Dictionary [element, property Key] : A | CollectionFlow.cs:215:27:215:30 | access to local variable dict [element, property Key] : A | +| CollectionFlow.cs:211:48:211:48 | access to local variable a : A | CollectionFlow.cs:211:20:211:55 | object creation of type Dictionary [element, property Key] : A | +| CollectionFlow.cs:212:14:212:17 | access to local variable dict [element, property Key] : A | CollectionFlow.cs:212:14:212:22 | access to property Keys [element] : A | +| CollectionFlow.cs:212:14:212:22 | access to property Keys [element] : A | CollectionFlow.cs:212:14:212:30 | call to method First | +| CollectionFlow.cs:213:21:213:24 | access to local variable dict [element, property Key] : A | CollectionFlow.cs:380:59:380:62 | dict [element, property Key] : A | +| CollectionFlow.cs:214:28:214:31 | access to local variable dict [element, property Key] : A | CollectionFlow.cs:214:14:214:32 | call to method DictKeysFirst | +| CollectionFlow.cs:215:27:215:30 | access to local variable dict [element, property Key] : A | CollectionFlow.cs:215:14:215:31 | call to method DictFirstKey | | CollectionFlow.cs:229:17:229:23 | object creation of type A : A | CollectionFlow.cs:230:27:230:27 | access to local variable a : A | -| CollectionFlow.cs:230:25:230:29 | { ..., ... } [[]] : A | CollectionFlow.cs:231:27:231:29 | access to local variable as [[]] : A | -| CollectionFlow.cs:230:27:230:27 | access to local variable a : A | CollectionFlow.cs:230:25:230:29 | { ..., ... } [[]] : A | +| CollectionFlow.cs:230:25:230:29 | { ..., ... } [element] : A | CollectionFlow.cs:231:27:231:29 | access to local variable as [element] : A | +| CollectionFlow.cs:230:27:230:27 | access to local variable a : A | CollectionFlow.cs:230:25:230:29 | { ..., ... } [element] : A | | CollectionFlow.cs:231:22:231:22 | SSA def(x) : A | CollectionFlow.cs:232:18:232:18 | access to local variable x | -| CollectionFlow.cs:231:27:231:29 | access to local variable as [[]] : A | CollectionFlow.cs:231:22:231:22 | SSA def(x) : A | +| CollectionFlow.cs:231:27:231:29 | access to local variable as [element] : A | CollectionFlow.cs:231:22:231:22 | SSA def(x) : A | | CollectionFlow.cs:244:17:244:23 | object creation of type A : A | CollectionFlow.cs:245:27:245:27 | access to local variable a : A | -| CollectionFlow.cs:245:25:245:29 | { ..., ... } [[]] : A | CollectionFlow.cs:246:26:246:28 | access to local variable as [[]] : A | -| CollectionFlow.cs:245:27:245:27 | access to local variable a : A | CollectionFlow.cs:245:25:245:29 | { ..., ... } [[]] : A | -| CollectionFlow.cs:246:26:246:28 | access to local variable as [[]] : A | CollectionFlow.cs:246:26:246:44 | call to method GetEnumerator [Current] : A | -| CollectionFlow.cs:246:26:246:44 | call to method GetEnumerator [Current] : A | CollectionFlow.cs:248:18:248:27 | access to local variable enumerator [Current] : A | -| CollectionFlow.cs:248:18:248:27 | access to local variable enumerator [Current] : A | CollectionFlow.cs:248:18:248:35 | access to property Current | +| CollectionFlow.cs:245:25:245:29 | { ..., ... } [element] : A | CollectionFlow.cs:246:26:246:28 | access to local variable as [element] : A | +| CollectionFlow.cs:245:27:245:27 | access to local variable a : A | CollectionFlow.cs:245:25:245:29 | { ..., ... } [element] : A | +| CollectionFlow.cs:246:26:246:28 | access to local variable as [element] : A | CollectionFlow.cs:246:26:246:44 | call to method GetEnumerator [property Current] : A | +| CollectionFlow.cs:246:26:246:44 | call to method GetEnumerator [property Current] : A | CollectionFlow.cs:248:18:248:27 | access to local variable enumerator [property Current] : A | +| CollectionFlow.cs:248:18:248:27 | access to local variable enumerator [property Current] : A | CollectionFlow.cs:248:18:248:35 | access to property Current | | CollectionFlow.cs:261:17:261:23 | object creation of type A : A | CollectionFlow.cs:263:18:263:18 | access to local variable a : A | -| CollectionFlow.cs:263:9:263:12 | [post] access to local variable list [[]] : A | CollectionFlow.cs:264:26:264:29 | access to local variable list [[]] : A | -| CollectionFlow.cs:263:18:263:18 | access to local variable a : A | CollectionFlow.cs:263:9:263:12 | [post] access to local variable list [[]] : A | -| CollectionFlow.cs:264:26:264:29 | access to local variable list [[]] : A | CollectionFlow.cs:264:26:264:45 | call to method GetEnumerator [Current] : A | -| CollectionFlow.cs:264:26:264:45 | call to method GetEnumerator [Current] : A | CollectionFlow.cs:266:18:266:27 | access to local variable enumerator [Current] : A | -| CollectionFlow.cs:266:18:266:27 | access to local variable enumerator [Current] : A | CollectionFlow.cs:266:18:266:35 | access to property Current | +| CollectionFlow.cs:263:9:263:12 | [post] access to local variable list [element] : A | CollectionFlow.cs:264:26:264:29 | access to local variable list [element] : A | +| CollectionFlow.cs:263:18:263:18 | access to local variable a : A | CollectionFlow.cs:263:9:263:12 | [post] access to local variable list [element] : A | +| CollectionFlow.cs:264:26:264:29 | access to local variable list [element] : A | CollectionFlow.cs:264:26:264:45 | call to method GetEnumerator [property Current] : A | +| CollectionFlow.cs:264:26:264:45 | call to method GetEnumerator [property Current] : A | CollectionFlow.cs:266:18:266:27 | access to local variable enumerator [property Current] : A | +| CollectionFlow.cs:266:18:266:27 | access to local variable enumerator [property Current] : A | CollectionFlow.cs:266:18:266:35 | access to property Current | | CollectionFlow.cs:280:17:280:23 | object creation of type A : A | CollectionFlow.cs:282:43:282:43 | access to local variable a : A | -| CollectionFlow.cs:282:9:282:12 | [post] access to local variable list [[], Key] : A | CollectionFlow.cs:283:9:283:12 | access to local variable list [[], Key] : A | -| CollectionFlow.cs:282:18:282:47 | object creation of type KeyValuePair [Key] : A | CollectionFlow.cs:282:9:282:12 | [post] access to local variable list [[], Key] : A | -| CollectionFlow.cs:282:43:282:43 | access to local variable a : A | CollectionFlow.cs:282:18:282:47 | object creation of type KeyValuePair [Key] : A | -| CollectionFlow.cs:283:9:283:12 | access to local variable list [[], Key] : A | CollectionFlow.cs:283:21:283:23 | kvp [Key] : A | -| CollectionFlow.cs:283:21:283:23 | kvp [Key] : A | CollectionFlow.cs:285:18:285:20 | access to parameter kvp [Key] : A | -| CollectionFlow.cs:285:18:285:20 | access to parameter kvp [Key] : A | CollectionFlow.cs:285:18:285:24 | access to property Key | +| CollectionFlow.cs:282:9:282:12 | [post] access to local variable list [element, property Key] : A | CollectionFlow.cs:283:9:283:12 | access to local variable list [element, property Key] : A | +| CollectionFlow.cs:282:18:282:47 | object creation of type KeyValuePair [property Key] : A | CollectionFlow.cs:282:9:282:12 | [post] access to local variable list [element, property Key] : A | +| CollectionFlow.cs:282:43:282:43 | access to local variable a : A | CollectionFlow.cs:282:18:282:47 | object creation of type KeyValuePair [property Key] : A | +| CollectionFlow.cs:283:9:283:12 | access to local variable list [element, property Key] : A | CollectionFlow.cs:283:21:283:23 | kvp [property Key] : A | +| CollectionFlow.cs:283:21:283:23 | kvp [property Key] : A | CollectionFlow.cs:285:18:285:20 | access to parameter kvp [property Key] : A | +| CollectionFlow.cs:285:18:285:20 | access to parameter kvp [property Key] : A | CollectionFlow.cs:285:18:285:24 | access to property Key | | CollectionFlow.cs:306:17:306:23 | object creation of type A : A | CollectionFlow.cs:308:23:308:23 | access to local variable a : A | -| CollectionFlow.cs:308:18:308:20 | [post] access to local variable as [[]] : A | CollectionFlow.cs:309:14:309:16 | access to local variable as [[]] : A | -| CollectionFlow.cs:308:18:308:20 | [post] access to local variable as [[]] : A | CollectionFlow.cs:310:18:310:20 | access to local variable as [[]] : A | -| CollectionFlow.cs:308:18:308:20 | [post] access to local variable as [[]] : A | CollectionFlow.cs:311:20:311:22 | access to local variable as [[]] : A | -| CollectionFlow.cs:308:23:308:23 | access to local variable a : A | CollectionFlow.cs:308:18:308:20 | [post] access to local variable as [[]] : A | -| CollectionFlow.cs:309:14:309:16 | access to local variable as [[]] : A | CollectionFlow.cs:309:14:309:19 | access to array element | -| CollectionFlow.cs:310:18:310:20 | access to local variable as [[]] : A | CollectionFlow.cs:374:40:374:41 | ts [[]] : A | -| CollectionFlow.cs:311:20:311:22 | access to local variable as [[]] : A | CollectionFlow.cs:311:14:311:23 | call to method First | +| CollectionFlow.cs:308:18:308:20 | [post] access to local variable as [element] : A | CollectionFlow.cs:309:14:309:16 | access to local variable as [element] : A | +| CollectionFlow.cs:308:18:308:20 | [post] access to local variable as [element] : A | CollectionFlow.cs:310:18:310:20 | access to local variable as [element] : A | +| CollectionFlow.cs:308:18:308:20 | [post] access to local variable as [element] : A | CollectionFlow.cs:311:20:311:22 | access to local variable as [element] : A | +| CollectionFlow.cs:308:23:308:23 | access to local variable a : A | CollectionFlow.cs:308:18:308:20 | [post] access to local variable as [element] : A | +| CollectionFlow.cs:309:14:309:16 | access to local variable as [element] : A | CollectionFlow.cs:309:14:309:19 | access to array element | +| CollectionFlow.cs:310:18:310:20 | access to local variable as [element] : A | CollectionFlow.cs:374:40:374:41 | ts [element] : A | +| CollectionFlow.cs:311:20:311:22 | access to local variable as [element] : A | CollectionFlow.cs:311:14:311:23 | call to method First | | CollectionFlow.cs:328:17:328:23 | object creation of type A : A | CollectionFlow.cs:330:23:330:23 | access to local variable a : A | -| CollectionFlow.cs:330:17:330:20 | [post] access to local variable list [[]] : A | CollectionFlow.cs:331:14:331:17 | access to local variable list [[]] : A | -| CollectionFlow.cs:330:17:330:20 | [post] access to local variable list [[]] : A | CollectionFlow.cs:332:22:332:25 | access to local variable list [[]] : A | -| CollectionFlow.cs:330:17:330:20 | [post] access to local variable list [[]] : A | CollectionFlow.cs:333:24:333:27 | access to local variable list [[]] : A | -| CollectionFlow.cs:330:23:330:23 | access to local variable a : A | CollectionFlow.cs:330:17:330:20 | [post] access to local variable list [[]] : A | -| CollectionFlow.cs:331:14:331:17 | access to local variable list [[]] : A | CollectionFlow.cs:331:14:331:20 | access to indexer | -| CollectionFlow.cs:332:22:332:25 | access to local variable list [[]] : A | CollectionFlow.cs:376:49:376:52 | list [[]] : A | -| CollectionFlow.cs:333:24:333:27 | access to local variable list [[]] : A | CollectionFlow.cs:333:14:333:28 | call to method ListFirst | -| CollectionFlow.cs:347:20:347:26 | object creation of type A : A | CollectionFlow.cs:396:49:396:52 | args [[]] : A | -| CollectionFlow.cs:348:26:348:32 | object creation of type A : A | CollectionFlow.cs:396:49:396:52 | args [[]] : A | -| CollectionFlow.cs:349:26:349:32 | object creation of type A : A | CollectionFlow.cs:396:49:396:52 | args [[]] : A | -| CollectionFlow.cs:350:20:350:38 | array creation of type A[] [[]] : A | CollectionFlow.cs:396:49:396:52 | args [[]] : A | -| CollectionFlow.cs:350:28:350:38 | { ..., ... } [[]] : A | CollectionFlow.cs:350:20:350:38 | array creation of type A[] [[]] : A | -| CollectionFlow.cs:350:30:350:36 | object creation of type A : A | CollectionFlow.cs:350:28:350:38 | { ..., ... } [[]] : A | -| CollectionFlow.cs:374:40:374:41 | ts [[]] : A | CollectionFlow.cs:374:52:374:53 | access to parameter ts [[]] : A | -| CollectionFlow.cs:374:40:374:41 | ts [[]] : A | CollectionFlow.cs:374:52:374:53 | access to parameter ts [[]] : A | -| CollectionFlow.cs:374:52:374:53 | access to parameter ts [[]] : A | CollectionFlow.cs:374:52:374:56 | access to array element | -| CollectionFlow.cs:374:52:374:53 | access to parameter ts [[]] : A | CollectionFlow.cs:374:52:374:56 | access to array element | -| CollectionFlow.cs:376:49:376:52 | list [[]] : A | CollectionFlow.cs:376:63:376:66 | access to parameter list [[]] : A | -| CollectionFlow.cs:376:49:376:52 | list [[]] : A | CollectionFlow.cs:376:63:376:66 | access to parameter list [[]] : A | -| CollectionFlow.cs:376:49:376:52 | list [[]] : A | CollectionFlow.cs:376:63:376:66 | access to parameter list [[]] : A | -| CollectionFlow.cs:376:49:376:52 | list [[]] : A | CollectionFlow.cs:376:63:376:66 | access to parameter list [[]] : A | -| CollectionFlow.cs:376:63:376:66 | access to parameter list [[]] : A | CollectionFlow.cs:376:63:376:69 | access to indexer | -| CollectionFlow.cs:376:63:376:66 | access to parameter list [[]] : A | CollectionFlow.cs:376:63:376:69 | access to indexer | -| CollectionFlow.cs:376:63:376:66 | access to parameter list [[]] : A | CollectionFlow.cs:376:63:376:69 | access to indexer | -| CollectionFlow.cs:376:63:376:66 | access to parameter list [[]] : A | CollectionFlow.cs:376:63:376:69 | access to indexer | -| CollectionFlow.cs:378:61:378:64 | dict [[], Value] : A | CollectionFlow.cs:378:75:378:78 | access to parameter dict [[], Value] : A | -| CollectionFlow.cs:378:75:378:78 | access to parameter dict [[], Value] : A | CollectionFlow.cs:378:75:378:81 | access to indexer | -| CollectionFlow.cs:380:59:380:62 | dict [[], Key] : A | CollectionFlow.cs:380:73:380:76 | access to parameter dict [[], Key] : A | -| CollectionFlow.cs:380:73:380:76 | access to parameter dict [[], Key] : A | CollectionFlow.cs:380:73:380:81 | access to property Keys [[]] : A | -| CollectionFlow.cs:380:73:380:81 | access to property Keys [[]] : A | CollectionFlow.cs:380:73:380:89 | call to method First | -| CollectionFlow.cs:396:49:396:52 | args [[]] : A | CollectionFlow.cs:396:63:396:66 | access to parameter args [[]] : A | -| CollectionFlow.cs:396:49:396:52 | args [[]] : A | CollectionFlow.cs:396:63:396:66 | access to parameter args [[]] : A | -| CollectionFlow.cs:396:63:396:66 | access to parameter args [[]] : A | CollectionFlow.cs:396:63:396:69 | access to array element | -| CollectionFlow.cs:396:63:396:66 | access to parameter args [[]] : A | CollectionFlow.cs:396:63:396:69 | access to array element | +| CollectionFlow.cs:330:17:330:20 | [post] access to local variable list [element] : A | CollectionFlow.cs:331:14:331:17 | access to local variable list [element] : A | +| CollectionFlow.cs:330:17:330:20 | [post] access to local variable list [element] : A | CollectionFlow.cs:332:22:332:25 | access to local variable list [element] : A | +| CollectionFlow.cs:330:17:330:20 | [post] access to local variable list [element] : A | CollectionFlow.cs:333:24:333:27 | access to local variable list [element] : A | +| CollectionFlow.cs:330:23:330:23 | access to local variable a : A | CollectionFlow.cs:330:17:330:20 | [post] access to local variable list [element] : A | +| CollectionFlow.cs:331:14:331:17 | access to local variable list [element] : A | CollectionFlow.cs:331:14:331:20 | access to indexer | +| CollectionFlow.cs:332:22:332:25 | access to local variable list [element] : A | CollectionFlow.cs:376:49:376:52 | list [element] : A | +| CollectionFlow.cs:333:24:333:27 | access to local variable list [element] : A | CollectionFlow.cs:333:14:333:28 | call to method ListFirst | +| CollectionFlow.cs:347:20:347:26 | object creation of type A : A | CollectionFlow.cs:396:49:396:52 | args [element] : A | +| CollectionFlow.cs:348:26:348:32 | object creation of type A : A | CollectionFlow.cs:396:49:396:52 | args [element] : A | +| CollectionFlow.cs:349:26:349:32 | object creation of type A : A | CollectionFlow.cs:396:49:396:52 | args [element] : A | +| CollectionFlow.cs:350:20:350:38 | array creation of type A[] [element] : A | CollectionFlow.cs:396:49:396:52 | args [element] : A | +| CollectionFlow.cs:350:28:350:38 | { ..., ... } [element] : A | CollectionFlow.cs:350:20:350:38 | array creation of type A[] [element] : A | +| CollectionFlow.cs:350:30:350:36 | object creation of type A : A | CollectionFlow.cs:350:28:350:38 | { ..., ... } [element] : A | +| CollectionFlow.cs:374:40:374:41 | ts [element] : A | CollectionFlow.cs:374:52:374:53 | access to parameter ts [element] : A | +| CollectionFlow.cs:374:40:374:41 | ts [element] : A | CollectionFlow.cs:374:52:374:53 | access to parameter ts [element] : A | +| CollectionFlow.cs:374:52:374:53 | access to parameter ts [element] : A | CollectionFlow.cs:374:52:374:56 | access to array element | +| CollectionFlow.cs:374:52:374:53 | access to parameter ts [element] : A | CollectionFlow.cs:374:52:374:56 | access to array element | +| CollectionFlow.cs:376:49:376:52 | list [element] : A | CollectionFlow.cs:376:63:376:66 | access to parameter list [element] : A | +| CollectionFlow.cs:376:49:376:52 | list [element] : A | CollectionFlow.cs:376:63:376:66 | access to parameter list [element] : A | +| CollectionFlow.cs:376:49:376:52 | list [element] : A | CollectionFlow.cs:376:63:376:66 | access to parameter list [element] : A | +| CollectionFlow.cs:376:49:376:52 | list [element] : A | CollectionFlow.cs:376:63:376:66 | access to parameter list [element] : A | +| CollectionFlow.cs:376:63:376:66 | access to parameter list [element] : A | CollectionFlow.cs:376:63:376:69 | access to indexer | +| CollectionFlow.cs:376:63:376:66 | access to parameter list [element] : A | CollectionFlow.cs:376:63:376:69 | access to indexer | +| CollectionFlow.cs:376:63:376:66 | access to parameter list [element] : A | CollectionFlow.cs:376:63:376:69 | access to indexer | +| CollectionFlow.cs:376:63:376:66 | access to parameter list [element] : A | CollectionFlow.cs:376:63:376:69 | access to indexer | +| CollectionFlow.cs:378:61:378:64 | dict [element, property Value] : A | CollectionFlow.cs:378:75:378:78 | access to parameter dict [element, property Value] : A | +| CollectionFlow.cs:378:75:378:78 | access to parameter dict [element, property Value] : A | CollectionFlow.cs:378:75:378:81 | access to indexer | +| CollectionFlow.cs:380:59:380:62 | dict [element, property Key] : A | CollectionFlow.cs:380:73:380:76 | access to parameter dict [element, property Key] : A | +| CollectionFlow.cs:380:73:380:76 | access to parameter dict [element, property Key] : A | CollectionFlow.cs:380:73:380:81 | access to property Keys [element] : A | +| CollectionFlow.cs:380:73:380:81 | access to property Keys [element] : A | CollectionFlow.cs:380:73:380:89 | call to method First | +| CollectionFlow.cs:396:49:396:52 | args [element] : A | CollectionFlow.cs:396:63:396:66 | access to parameter args [element] : A | +| CollectionFlow.cs:396:49:396:52 | args [element] : A | CollectionFlow.cs:396:63:396:66 | access to parameter args [element] : A | +| CollectionFlow.cs:396:63:396:66 | access to parameter args [element] : A | CollectionFlow.cs:396:63:396:69 | access to array element | +| CollectionFlow.cs:396:63:396:66 | access to parameter args [element] : A | CollectionFlow.cs:396:63:396:69 | access to array element | nodes | CollectionFlow.cs:14:17:14:23 | object creation of type A : A | semmle.label | object creation of type A : A | -| CollectionFlow.cs:15:25:15:29 | { ..., ... } [[]] : A | semmle.label | { ..., ... } [[]] : A | +| CollectionFlow.cs:15:25:15:29 | { ..., ... } [element] : A | semmle.label | { ..., ... } [element] : A | | CollectionFlow.cs:15:27:15:27 | access to local variable a : A | semmle.label | access to local variable a : A | -| CollectionFlow.cs:16:14:16:16 | access to local variable as [[]] : A | semmle.label | access to local variable as [[]] : A | +| CollectionFlow.cs:16:14:16:16 | access to local variable as [element] : A | semmle.label | access to local variable as [element] : A | | CollectionFlow.cs:16:14:16:19 | access to array element | semmle.label | access to array element | -| CollectionFlow.cs:17:18:17:20 | access to local variable as [[]] : A | semmle.label | access to local variable as [[]] : A | +| CollectionFlow.cs:17:18:17:20 | access to local variable as [element] : A | semmle.label | access to local variable as [element] : A | | CollectionFlow.cs:18:14:18:23 | call to method First | semmle.label | call to method First | -| CollectionFlow.cs:18:20:18:22 | access to local variable as [[]] : A | semmle.label | access to local variable as [[]] : A | +| CollectionFlow.cs:18:20:18:22 | access to local variable as [element] : A | semmle.label | access to local variable as [element] : A | | CollectionFlow.cs:32:17:32:23 | object creation of type A : A | semmle.label | object creation of type A : A | -| CollectionFlow.cs:33:38:33:57 | { ..., ... } [As, []] : A | semmle.label | { ..., ... } [As, []] : A | -| CollectionFlow.cs:33:45:33:55 | { ..., ... } [[]] : A | semmle.label | { ..., ... } [[]] : A | +| CollectionFlow.cs:33:38:33:57 | { ..., ... } [field As, element] : A | semmle.label | { ..., ... } [field As, element] : A | +| CollectionFlow.cs:33:45:33:55 | { ..., ... } [element] : A | semmle.label | { ..., ... } [element] : A | | CollectionFlow.cs:33:53:33:53 | access to local variable a : A | semmle.label | access to local variable a : A | -| CollectionFlow.cs:34:14:34:14 | access to local variable c [As, []] : A | semmle.label | access to local variable c [As, []] : A | -| CollectionFlow.cs:34:14:34:17 | access to field As [[]] : A | semmle.label | access to field As [[]] : A | +| CollectionFlow.cs:34:14:34:14 | access to local variable c [field As, element] : A | semmle.label | access to local variable c [field As, element] : A | +| CollectionFlow.cs:34:14:34:17 | access to field As [element] : A | semmle.label | access to field As [element] : A | | CollectionFlow.cs:34:14:34:20 | access to array element | semmle.label | access to array element | -| CollectionFlow.cs:35:18:35:18 | access to local variable c [As, []] : A | semmle.label | access to local variable c [As, []] : A | -| CollectionFlow.cs:35:18:35:21 | access to field As [[]] : A | semmle.label | access to field As [[]] : A | +| CollectionFlow.cs:35:18:35:18 | access to local variable c [field As, element] : A | semmle.label | access to local variable c [field As, element] : A | +| CollectionFlow.cs:35:18:35:21 | access to field As [element] : A | semmle.label | access to field As [element] : A | | CollectionFlow.cs:36:14:36:24 | call to method First | semmle.label | call to method First | -| CollectionFlow.cs:36:20:36:20 | access to local variable c [As, []] : A | semmle.label | access to local variable c [As, []] : A | -| CollectionFlow.cs:36:20:36:23 | access to field As [[]] : A | semmle.label | access to field As [[]] : A | +| CollectionFlow.cs:36:20:36:20 | access to local variable c [field As, element] : A | semmle.label | access to local variable c [field As, element] : A | +| CollectionFlow.cs:36:20:36:23 | access to field As [element] : A | semmle.label | access to field As [element] : A | | CollectionFlow.cs:50:17:50:23 | object creation of type A : A | semmle.label | object creation of type A : A | -| CollectionFlow.cs:52:9:52:11 | [post] access to local variable as [[]] : A | semmle.label | [post] access to local variable as [[]] : A | +| CollectionFlow.cs:52:9:52:11 | [post] access to local variable as [element] : A | semmle.label | [post] access to local variable as [element] : A | | CollectionFlow.cs:52:18:52:18 | access to local variable a : A | semmle.label | access to local variable a : A | -| CollectionFlow.cs:53:14:53:16 | access to local variable as [[]] : A | semmle.label | access to local variable as [[]] : A | +| CollectionFlow.cs:53:14:53:16 | access to local variable as [element] : A | semmle.label | access to local variable as [element] : A | | CollectionFlow.cs:53:14:53:19 | access to array element | semmle.label | access to array element | -| CollectionFlow.cs:54:18:54:20 | access to local variable as [[]] : A | semmle.label | access to local variable as [[]] : A | +| CollectionFlow.cs:54:18:54:20 | access to local variable as [element] : A | semmle.label | access to local variable as [element] : A | | CollectionFlow.cs:55:14:55:23 | call to method First | semmle.label | call to method First | -| CollectionFlow.cs:55:20:55:22 | access to local variable as [[]] : A | semmle.label | access to local variable as [[]] : A | +| CollectionFlow.cs:55:20:55:22 | access to local variable as [element] : A | semmle.label | access to local variable as [element] : A | | CollectionFlow.cs:70:17:70:23 | object creation of type A : A | semmle.label | object creation of type A : A | -| CollectionFlow.cs:72:9:72:12 | [post] access to local variable list [[]] : A | semmle.label | [post] access to local variable list [[]] : A | +| CollectionFlow.cs:72:9:72:12 | [post] access to local variable list [element] : A | semmle.label | [post] access to local variable list [element] : A | | CollectionFlow.cs:72:19:72:19 | access to local variable a : A | semmle.label | access to local variable a : A | -| CollectionFlow.cs:73:14:73:17 | access to local variable list [[]] : A | semmle.label | access to local variable list [[]] : A | +| CollectionFlow.cs:73:14:73:17 | access to local variable list [element] : A | semmle.label | access to local variable list [element] : A | | CollectionFlow.cs:73:14:73:20 | access to indexer | semmle.label | access to indexer | -| CollectionFlow.cs:74:22:74:25 | access to local variable list [[]] : A | semmle.label | access to local variable list [[]] : A | +| CollectionFlow.cs:74:22:74:25 | access to local variable list [element] : A | semmle.label | access to local variable list [element] : A | | CollectionFlow.cs:75:14:75:28 | call to method ListFirst | semmle.label | call to method ListFirst | -| CollectionFlow.cs:75:24:75:27 | access to local variable list [[]] : A | semmle.label | access to local variable list [[]] : A | +| CollectionFlow.cs:75:24:75:27 | access to local variable list [element] : A | semmle.label | access to local variable list [element] : A | | CollectionFlow.cs:89:17:89:23 | object creation of type A : A | semmle.label | object creation of type A : A | -| CollectionFlow.cs:90:34:90:38 | { ..., ... } [[]] : A | semmle.label | { ..., ... } [[]] : A | +| CollectionFlow.cs:90:20:90:38 | object creation of type List [element] : A | semmle.label | object creation of type List [element] : A | | CollectionFlow.cs:90:36:90:36 | access to local variable a : A | semmle.label | access to local variable a : A | -| CollectionFlow.cs:91:14:91:17 | access to local variable list [[]] : A | semmle.label | access to local variable list [[]] : A | +| CollectionFlow.cs:91:14:91:17 | access to local variable list [element] : A | semmle.label | access to local variable list [element] : A | | CollectionFlow.cs:91:14:91:20 | access to indexer | semmle.label | access to indexer | -| CollectionFlow.cs:92:22:92:25 | access to local variable list [[]] : A | semmle.label | access to local variable list [[]] : A | +| CollectionFlow.cs:92:22:92:25 | access to local variable list [element] : A | semmle.label | access to local variable list [element] : A | | CollectionFlow.cs:93:14:93:28 | call to method ListFirst | semmle.label | call to method ListFirst | -| CollectionFlow.cs:93:24:93:27 | access to local variable list [[]] : A | semmle.label | access to local variable list [[]] : A | +| CollectionFlow.cs:93:24:93:27 | access to local variable list [element] : A | semmle.label | access to local variable list [element] : A | | CollectionFlow.cs:106:17:106:23 | object creation of type A : A | semmle.label | object creation of type A : A | -| CollectionFlow.cs:108:9:108:12 | [post] access to local variable list [[]] : A | semmle.label | [post] access to local variable list [[]] : A | +| CollectionFlow.cs:108:9:108:12 | [post] access to local variable list [element] : A | semmle.label | [post] access to local variable list [element] : A | | CollectionFlow.cs:108:18:108:18 | access to local variable a : A | semmle.label | access to local variable a : A | -| CollectionFlow.cs:109:14:109:17 | access to local variable list [[]] : A | semmle.label | access to local variable list [[]] : A | +| CollectionFlow.cs:109:14:109:17 | access to local variable list [element] : A | semmle.label | access to local variable list [element] : A | | CollectionFlow.cs:109:14:109:20 | access to indexer | semmle.label | access to indexer | -| CollectionFlow.cs:110:22:110:25 | access to local variable list [[]] : A | semmle.label | access to local variable list [[]] : A | +| CollectionFlow.cs:110:22:110:25 | access to local variable list [element] : A | semmle.label | access to local variable list [element] : A | | CollectionFlow.cs:111:14:111:28 | call to method ListFirst | semmle.label | call to method ListFirst | -| CollectionFlow.cs:111:24:111:27 | access to local variable list [[]] : A | semmle.label | access to local variable list [[]] : A | +| CollectionFlow.cs:111:24:111:27 | access to local variable list [element] : A | semmle.label | access to local variable list [element] : A | | CollectionFlow.cs:125:17:125:23 | object creation of type A : A | semmle.label | object creation of type A : A | -| CollectionFlow.cs:127:9:127:12 | [post] access to local variable dict [[], Value] : A | semmle.label | [post] access to local variable dict [[], Value] : A | +| CollectionFlow.cs:127:9:127:12 | [post] access to local variable dict [element, property Value] : A | semmle.label | [post] access to local variable dict [element, property Value] : A | | CollectionFlow.cs:127:19:127:19 | access to local variable a : A | semmle.label | access to local variable a : A | -| CollectionFlow.cs:128:14:128:17 | access to local variable dict [[], Value] : A | semmle.label | access to local variable dict [[], Value] : A | +| CollectionFlow.cs:128:14:128:17 | access to local variable dict [element, property Value] : A | semmle.label | access to local variable dict [element, property Value] : A | | CollectionFlow.cs:128:14:128:20 | access to indexer | semmle.label | access to indexer | -| CollectionFlow.cs:129:23:129:26 | access to local variable dict [[], Value] : A | semmle.label | access to local variable dict [[], Value] : A | +| CollectionFlow.cs:129:23:129:26 | access to local variable dict [element, property Value] : A | semmle.label | access to local variable dict [element, property Value] : A | | CollectionFlow.cs:130:14:130:32 | call to method DictIndexZero | semmle.label | call to method DictIndexZero | -| CollectionFlow.cs:130:28:130:31 | access to local variable dict [[], Value] : A | semmle.label | access to local variable dict [[], Value] : A | +| CollectionFlow.cs:130:28:130:31 | access to local variable dict [element, property Value] : A | semmle.label | access to local variable dict [element, property Value] : A | | CollectionFlow.cs:131:14:131:33 | call to method DictFirstValue | semmle.label | call to method DictFirstValue | -| CollectionFlow.cs:131:29:131:32 | access to local variable dict [[], Value] : A | semmle.label | access to local variable dict [[], Value] : A | +| CollectionFlow.cs:131:29:131:32 | access to local variable dict [element, property Value] : A | semmle.label | access to local variable dict [element, property Value] : A | | CollectionFlow.cs:132:14:132:34 | call to method DictValuesFirst | semmle.label | call to method DictValuesFirst | -| CollectionFlow.cs:132:30:132:33 | access to local variable dict [[], Value] : A | semmle.label | access to local variable dict [[], Value] : A | +| CollectionFlow.cs:132:30:132:33 | access to local variable dict [element, property Value] : A | semmle.label | access to local variable dict [element, property Value] : A | | CollectionFlow.cs:148:17:148:23 | object creation of type A : A | semmle.label | object creation of type A : A | -| CollectionFlow.cs:149:45:149:56 | { ..., ... } [[], Value] : A | semmle.label | { ..., ... } [[], Value] : A | +| CollectionFlow.cs:149:20:149:56 | object creation of type Dictionary [element, property Value] : A | semmle.label | object creation of type Dictionary [element, property Value] : A | | CollectionFlow.cs:149:52:149:52 | access to local variable a : A | semmle.label | access to local variable a : A | -| CollectionFlow.cs:150:14:150:17 | access to local variable dict [[], Value] : A | semmle.label | access to local variable dict [[], Value] : A | +| CollectionFlow.cs:150:14:150:17 | access to local variable dict [element, property Value] : A | semmle.label | access to local variable dict [element, property Value] : A | | CollectionFlow.cs:150:14:150:20 | access to indexer | semmle.label | access to indexer | -| CollectionFlow.cs:151:23:151:26 | access to local variable dict [[], Value] : A | semmle.label | access to local variable dict [[], Value] : A | +| CollectionFlow.cs:151:23:151:26 | access to local variable dict [element, property Value] : A | semmle.label | access to local variable dict [element, property Value] : A | | CollectionFlow.cs:152:14:152:32 | call to method DictIndexZero | semmle.label | call to method DictIndexZero | -| CollectionFlow.cs:152:28:152:31 | access to local variable dict [[], Value] : A | semmle.label | access to local variable dict [[], Value] : A | +| CollectionFlow.cs:152:28:152:31 | access to local variable dict [element, property Value] : A | semmle.label | access to local variable dict [element, property Value] : A | | CollectionFlow.cs:153:14:153:33 | call to method DictFirstValue | semmle.label | call to method DictFirstValue | -| CollectionFlow.cs:153:29:153:32 | access to local variable dict [[], Value] : A | semmle.label | access to local variable dict [[], Value] : A | +| CollectionFlow.cs:153:29:153:32 | access to local variable dict [element, property Value] : A | semmle.label | access to local variable dict [element, property Value] : A | | CollectionFlow.cs:154:14:154:34 | call to method DictValuesFirst | semmle.label | call to method DictValuesFirst | -| CollectionFlow.cs:154:30:154:33 | access to local variable dict [[], Value] : A | semmle.label | access to local variable dict [[], Value] : A | +| CollectionFlow.cs:154:30:154:33 | access to local variable dict [element, property Value] : A | semmle.label | access to local variable dict [element, property Value] : A | | CollectionFlow.cs:169:17:169:23 | object creation of type A : A | semmle.label | object creation of type A : A | -| CollectionFlow.cs:170:45:170:55 | { ..., ... } [[], Value] : A | semmle.label | { ..., ... } [[], Value] : A | +| CollectionFlow.cs:170:20:170:55 | object creation of type Dictionary [element, property Value] : A | semmle.label | object creation of type Dictionary [element, property Value] : A | | CollectionFlow.cs:170:53:170:53 | access to local variable a : A | semmle.label | access to local variable a : A | -| CollectionFlow.cs:171:14:171:17 | access to local variable dict [[], Value] : A | semmle.label | access to local variable dict [[], Value] : A | +| CollectionFlow.cs:171:14:171:17 | access to local variable dict [element, property Value] : A | semmle.label | access to local variable dict [element, property Value] : A | | CollectionFlow.cs:171:14:171:20 | access to indexer | semmle.label | access to indexer | -| CollectionFlow.cs:172:23:172:26 | access to local variable dict [[], Value] : A | semmle.label | access to local variable dict [[], Value] : A | +| CollectionFlow.cs:172:23:172:26 | access to local variable dict [element, property Value] : A | semmle.label | access to local variable dict [element, property Value] : A | | CollectionFlow.cs:173:14:173:32 | call to method DictIndexZero | semmle.label | call to method DictIndexZero | -| CollectionFlow.cs:173:28:173:31 | access to local variable dict [[], Value] : A | semmle.label | access to local variable dict [[], Value] : A | +| CollectionFlow.cs:173:28:173:31 | access to local variable dict [element, property Value] : A | semmle.label | access to local variable dict [element, property Value] : A | | CollectionFlow.cs:174:14:174:33 | call to method DictFirstValue | semmle.label | call to method DictFirstValue | -| CollectionFlow.cs:174:29:174:32 | access to local variable dict [[], Value] : A | semmle.label | access to local variable dict [[], Value] : A | +| CollectionFlow.cs:174:29:174:32 | access to local variable dict [element, property Value] : A | semmle.label | access to local variable dict [element, property Value] : A | | CollectionFlow.cs:175:14:175:34 | call to method DictValuesFirst | semmle.label | call to method DictValuesFirst | -| CollectionFlow.cs:175:30:175:33 | access to local variable dict [[], Value] : A | semmle.label | access to local variable dict [[], Value] : A | +| CollectionFlow.cs:175:30:175:33 | access to local variable dict [element, property Value] : A | semmle.label | access to local variable dict [element, property Value] : A | | CollectionFlow.cs:191:17:191:23 | object creation of type A : A | semmle.label | object creation of type A : A | -| CollectionFlow.cs:192:45:192:56 | { ..., ... } [[], Key] : A | semmle.label | { ..., ... } [[], Key] : A | +| CollectionFlow.cs:192:20:192:56 | object creation of type Dictionary [element, property Key] : A | semmle.label | object creation of type Dictionary [element, property Key] : A | | CollectionFlow.cs:192:49:192:49 | access to local variable a : A | semmle.label | access to local variable a : A | -| CollectionFlow.cs:193:14:193:17 | access to local variable dict [[], Key] : A | semmle.label | access to local variable dict [[], Key] : A | -| CollectionFlow.cs:193:14:193:22 | access to property Keys [[]] : A | semmle.label | access to property Keys [[]] : A | +| CollectionFlow.cs:193:14:193:17 | access to local variable dict [element, property Key] : A | semmle.label | access to local variable dict [element, property Key] : A | +| CollectionFlow.cs:193:14:193:22 | access to property Keys [element] : A | semmle.label | access to property Keys [element] : A | | CollectionFlow.cs:193:14:193:30 | call to method First | semmle.label | call to method First | -| CollectionFlow.cs:194:21:194:24 | access to local variable dict [[], Key] : A | semmle.label | access to local variable dict [[], Key] : A | +| CollectionFlow.cs:194:21:194:24 | access to local variable dict [element, property Key] : A | semmle.label | access to local variable dict [element, property Key] : A | | CollectionFlow.cs:195:14:195:32 | call to method DictKeysFirst | semmle.label | call to method DictKeysFirst | -| CollectionFlow.cs:195:28:195:31 | access to local variable dict [[], Key] : A | semmle.label | access to local variable dict [[], Key] : A | +| CollectionFlow.cs:195:28:195:31 | access to local variable dict [element, property Key] : A | semmle.label | access to local variable dict [element, property Key] : A | | CollectionFlow.cs:196:14:196:31 | call to method DictFirstKey | semmle.label | call to method DictFirstKey | -| CollectionFlow.cs:196:27:196:30 | access to local variable dict [[], Key] : A | semmle.label | access to local variable dict [[], Key] : A | +| CollectionFlow.cs:196:27:196:30 | access to local variable dict [element, property Key] : A | semmle.label | access to local variable dict [element, property Key] : A | | CollectionFlow.cs:210:17:210:23 | object creation of type A : A | semmle.label | object creation of type A : A | -| CollectionFlow.cs:211:45:211:55 | { ..., ... } [[], Key] : A | semmle.label | { ..., ... } [[], Key] : A | +| CollectionFlow.cs:211:20:211:55 | object creation of type Dictionary [element, property Key] : A | semmle.label | object creation of type Dictionary [element, property Key] : A | | CollectionFlow.cs:211:48:211:48 | access to local variable a : A | semmle.label | access to local variable a : A | -| CollectionFlow.cs:212:14:212:17 | access to local variable dict [[], Key] : A | semmle.label | access to local variable dict [[], Key] : A | -| CollectionFlow.cs:212:14:212:22 | access to property Keys [[]] : A | semmle.label | access to property Keys [[]] : A | +| CollectionFlow.cs:212:14:212:17 | access to local variable dict [element, property Key] : A | semmle.label | access to local variable dict [element, property Key] : A | +| CollectionFlow.cs:212:14:212:22 | access to property Keys [element] : A | semmle.label | access to property Keys [element] : A | | CollectionFlow.cs:212:14:212:30 | call to method First | semmle.label | call to method First | -| CollectionFlow.cs:213:21:213:24 | access to local variable dict [[], Key] : A | semmle.label | access to local variable dict [[], Key] : A | +| CollectionFlow.cs:213:21:213:24 | access to local variable dict [element, property Key] : A | semmle.label | access to local variable dict [element, property Key] : A | | CollectionFlow.cs:214:14:214:32 | call to method DictKeysFirst | semmle.label | call to method DictKeysFirst | -| CollectionFlow.cs:214:28:214:31 | access to local variable dict [[], Key] : A | semmle.label | access to local variable dict [[], Key] : A | +| CollectionFlow.cs:214:28:214:31 | access to local variable dict [element, property Key] : A | semmle.label | access to local variable dict [element, property Key] : A | | CollectionFlow.cs:215:14:215:31 | call to method DictFirstKey | semmle.label | call to method DictFirstKey | -| CollectionFlow.cs:215:27:215:30 | access to local variable dict [[], Key] : A | semmle.label | access to local variable dict [[], Key] : A | +| CollectionFlow.cs:215:27:215:30 | access to local variable dict [element, property Key] : A | semmle.label | access to local variable dict [element, property Key] : A | | CollectionFlow.cs:229:17:229:23 | object creation of type A : A | semmle.label | object creation of type A : A | -| CollectionFlow.cs:230:25:230:29 | { ..., ... } [[]] : A | semmle.label | { ..., ... } [[]] : A | +| CollectionFlow.cs:230:25:230:29 | { ..., ... } [element] : A | semmle.label | { ..., ... } [element] : A | | CollectionFlow.cs:230:27:230:27 | access to local variable a : A | semmle.label | access to local variable a : A | | CollectionFlow.cs:231:22:231:22 | SSA def(x) : A | semmle.label | SSA def(x) : A | -| CollectionFlow.cs:231:27:231:29 | access to local variable as [[]] : A | semmle.label | access to local variable as [[]] : A | +| CollectionFlow.cs:231:27:231:29 | access to local variable as [element] : A | semmle.label | access to local variable as [element] : A | | CollectionFlow.cs:232:18:232:18 | access to local variable x | semmle.label | access to local variable x | | CollectionFlow.cs:244:17:244:23 | object creation of type A : A | semmle.label | object creation of type A : A | -| CollectionFlow.cs:245:25:245:29 | { ..., ... } [[]] : A | semmle.label | { ..., ... } [[]] : A | +| CollectionFlow.cs:245:25:245:29 | { ..., ... } [element] : A | semmle.label | { ..., ... } [element] : A | | CollectionFlow.cs:245:27:245:27 | access to local variable a : A | semmle.label | access to local variable a : A | -| CollectionFlow.cs:246:26:246:28 | access to local variable as [[]] : A | semmle.label | access to local variable as [[]] : A | -| CollectionFlow.cs:246:26:246:44 | call to method GetEnumerator [Current] : A | semmle.label | call to method GetEnumerator [Current] : A | -| CollectionFlow.cs:248:18:248:27 | access to local variable enumerator [Current] : A | semmle.label | access to local variable enumerator [Current] : A | +| CollectionFlow.cs:246:26:246:28 | access to local variable as [element] : A | semmle.label | access to local variable as [element] : A | +| CollectionFlow.cs:246:26:246:44 | call to method GetEnumerator [property Current] : A | semmle.label | call to method GetEnumerator [property Current] : A | +| CollectionFlow.cs:248:18:248:27 | access to local variable enumerator [property Current] : A | semmle.label | access to local variable enumerator [property Current] : A | | CollectionFlow.cs:248:18:248:35 | access to property Current | semmle.label | access to property Current | | CollectionFlow.cs:261:17:261:23 | object creation of type A : A | semmle.label | object creation of type A : A | -| CollectionFlow.cs:263:9:263:12 | [post] access to local variable list [[]] : A | semmle.label | [post] access to local variable list [[]] : A | +| CollectionFlow.cs:263:9:263:12 | [post] access to local variable list [element] : A | semmle.label | [post] access to local variable list [element] : A | | CollectionFlow.cs:263:18:263:18 | access to local variable a : A | semmle.label | access to local variable a : A | -| CollectionFlow.cs:264:26:264:29 | access to local variable list [[]] : A | semmle.label | access to local variable list [[]] : A | -| CollectionFlow.cs:264:26:264:45 | call to method GetEnumerator [Current] : A | semmle.label | call to method GetEnumerator [Current] : A | -| CollectionFlow.cs:266:18:266:27 | access to local variable enumerator [Current] : A | semmle.label | access to local variable enumerator [Current] : A | +| CollectionFlow.cs:264:26:264:29 | access to local variable list [element] : A | semmle.label | access to local variable list [element] : A | +| CollectionFlow.cs:264:26:264:45 | call to method GetEnumerator [property Current] : A | semmle.label | call to method GetEnumerator [property Current] : A | +| CollectionFlow.cs:266:18:266:27 | access to local variable enumerator [property Current] : A | semmle.label | access to local variable enumerator [property Current] : A | | CollectionFlow.cs:266:18:266:35 | access to property Current | semmle.label | access to property Current | | CollectionFlow.cs:280:17:280:23 | object creation of type A : A | semmle.label | object creation of type A : A | -| CollectionFlow.cs:282:9:282:12 | [post] access to local variable list [[], Key] : A | semmle.label | [post] access to local variable list [[], Key] : A | -| CollectionFlow.cs:282:18:282:47 | object creation of type KeyValuePair [Key] : A | semmle.label | object creation of type KeyValuePair [Key] : A | +| CollectionFlow.cs:282:9:282:12 | [post] access to local variable list [element, property Key] : A | semmle.label | [post] access to local variable list [element, property Key] : A | +| CollectionFlow.cs:282:18:282:47 | object creation of type KeyValuePair [property Key] : A | semmle.label | object creation of type KeyValuePair [property Key] : A | | CollectionFlow.cs:282:43:282:43 | access to local variable a : A | semmle.label | access to local variable a : A | -| CollectionFlow.cs:283:9:283:12 | access to local variable list [[], Key] : A | semmle.label | access to local variable list [[], Key] : A | -| CollectionFlow.cs:283:21:283:23 | kvp [Key] : A | semmle.label | kvp [Key] : A | -| CollectionFlow.cs:285:18:285:20 | access to parameter kvp [Key] : A | semmle.label | access to parameter kvp [Key] : A | +| CollectionFlow.cs:283:9:283:12 | access to local variable list [element, property Key] : A | semmle.label | access to local variable list [element, property Key] : A | +| CollectionFlow.cs:283:21:283:23 | kvp [property Key] : A | semmle.label | kvp [property Key] : A | +| CollectionFlow.cs:285:18:285:20 | access to parameter kvp [property Key] : A | semmle.label | access to parameter kvp [property Key] : A | | CollectionFlow.cs:285:18:285:24 | access to property Key | semmle.label | access to property Key | | CollectionFlow.cs:306:17:306:23 | object creation of type A : A | semmle.label | object creation of type A : A | -| CollectionFlow.cs:308:18:308:20 | [post] access to local variable as [[]] : A | semmle.label | [post] access to local variable as [[]] : A | +| CollectionFlow.cs:308:18:308:20 | [post] access to local variable as [element] : A | semmle.label | [post] access to local variable as [element] : A | | CollectionFlow.cs:308:23:308:23 | access to local variable a : A | semmle.label | access to local variable a : A | -| CollectionFlow.cs:309:14:309:16 | access to local variable as [[]] : A | semmle.label | access to local variable as [[]] : A | +| CollectionFlow.cs:309:14:309:16 | access to local variable as [element] : A | semmle.label | access to local variable as [element] : A | | CollectionFlow.cs:309:14:309:19 | access to array element | semmle.label | access to array element | -| CollectionFlow.cs:310:18:310:20 | access to local variable as [[]] : A | semmle.label | access to local variable as [[]] : A | +| CollectionFlow.cs:310:18:310:20 | access to local variable as [element] : A | semmle.label | access to local variable as [element] : A | | CollectionFlow.cs:311:14:311:23 | call to method First | semmle.label | call to method First | -| CollectionFlow.cs:311:20:311:22 | access to local variable as [[]] : A | semmle.label | access to local variable as [[]] : A | +| CollectionFlow.cs:311:20:311:22 | access to local variable as [element] : A | semmle.label | access to local variable as [element] : A | | CollectionFlow.cs:328:17:328:23 | object creation of type A : A | semmle.label | object creation of type A : A | -| CollectionFlow.cs:330:17:330:20 | [post] access to local variable list [[]] : A | semmle.label | [post] access to local variable list [[]] : A | +| CollectionFlow.cs:330:17:330:20 | [post] access to local variable list [element] : A | semmle.label | [post] access to local variable list [element] : A | | CollectionFlow.cs:330:23:330:23 | access to local variable a : A | semmle.label | access to local variable a : A | -| CollectionFlow.cs:331:14:331:17 | access to local variable list [[]] : A | semmle.label | access to local variable list [[]] : A | +| CollectionFlow.cs:331:14:331:17 | access to local variable list [element] : A | semmle.label | access to local variable list [element] : A | | CollectionFlow.cs:331:14:331:20 | access to indexer | semmle.label | access to indexer | -| CollectionFlow.cs:332:22:332:25 | access to local variable list [[]] : A | semmle.label | access to local variable list [[]] : A | +| CollectionFlow.cs:332:22:332:25 | access to local variable list [element] : A | semmle.label | access to local variable list [element] : A | | CollectionFlow.cs:333:14:333:28 | call to method ListFirst | semmle.label | call to method ListFirst | -| CollectionFlow.cs:333:24:333:27 | access to local variable list [[]] : A | semmle.label | access to local variable list [[]] : A | +| CollectionFlow.cs:333:24:333:27 | access to local variable list [element] : A | semmle.label | access to local variable list [element] : A | | CollectionFlow.cs:347:20:347:26 | object creation of type A : A | semmle.label | object creation of type A : A | | CollectionFlow.cs:348:26:348:32 | object creation of type A : A | semmle.label | object creation of type A : A | | CollectionFlow.cs:349:26:349:32 | object creation of type A : A | semmle.label | object creation of type A : A | -| CollectionFlow.cs:350:20:350:38 | array creation of type A[] [[]] : A | semmle.label | array creation of type A[] [[]] : A | -| CollectionFlow.cs:350:28:350:38 | { ..., ... } [[]] : A | semmle.label | { ..., ... } [[]] : A | +| CollectionFlow.cs:350:20:350:38 | array creation of type A[] [element] : A | semmle.label | array creation of type A[] [element] : A | +| CollectionFlow.cs:350:28:350:38 | { ..., ... } [element] : A | semmle.label | { ..., ... } [element] : A | | CollectionFlow.cs:350:30:350:36 | object creation of type A : A | semmle.label | object creation of type A : A | -| CollectionFlow.cs:374:40:374:41 | ts [[]] : A | semmle.label | ts [[]] : A | -| CollectionFlow.cs:374:40:374:41 | ts [[]] : A | semmle.label | ts [[]] : A | -| CollectionFlow.cs:374:52:374:53 | access to parameter ts [[]] : A | semmle.label | access to parameter ts [[]] : A | -| CollectionFlow.cs:374:52:374:53 | access to parameter ts [[]] : A | semmle.label | access to parameter ts [[]] : A | +| CollectionFlow.cs:374:40:374:41 | ts [element] : A | semmle.label | ts [element] : A | +| CollectionFlow.cs:374:40:374:41 | ts [element] : A | semmle.label | ts [element] : A | +| CollectionFlow.cs:374:52:374:53 | access to parameter ts [element] : A | semmle.label | access to parameter ts [element] : A | +| CollectionFlow.cs:374:52:374:53 | access to parameter ts [element] : A | semmle.label | access to parameter ts [element] : A | | CollectionFlow.cs:374:52:374:56 | access to array element | semmle.label | access to array element | -| CollectionFlow.cs:376:49:376:52 | list [[]] : A | semmle.label | list [[]] : A | -| CollectionFlow.cs:376:49:376:52 | list [[]] : A | semmle.label | list [[]] : A | -| CollectionFlow.cs:376:49:376:52 | list [[]] : A | semmle.label | list [[]] : A | -| CollectionFlow.cs:376:49:376:52 | list [[]] : A | semmle.label | list [[]] : A | -| CollectionFlow.cs:376:63:376:66 | access to parameter list [[]] : A | semmle.label | access to parameter list [[]] : A | -| CollectionFlow.cs:376:63:376:66 | access to parameter list [[]] : A | semmle.label | access to parameter list [[]] : A | -| CollectionFlow.cs:376:63:376:66 | access to parameter list [[]] : A | semmle.label | access to parameter list [[]] : A | -| CollectionFlow.cs:376:63:376:66 | access to parameter list [[]] : A | semmle.label | access to parameter list [[]] : A | +| CollectionFlow.cs:376:49:376:52 | list [element] : A | semmle.label | list [element] : A | +| CollectionFlow.cs:376:49:376:52 | list [element] : A | semmle.label | list [element] : A | +| CollectionFlow.cs:376:49:376:52 | list [element] : A | semmle.label | list [element] : A | +| CollectionFlow.cs:376:49:376:52 | list [element] : A | semmle.label | list [element] : A | +| CollectionFlow.cs:376:63:376:66 | access to parameter list [element] : A | semmle.label | access to parameter list [element] : A | +| CollectionFlow.cs:376:63:376:66 | access to parameter list [element] : A | semmle.label | access to parameter list [element] : A | +| CollectionFlow.cs:376:63:376:66 | access to parameter list [element] : A | semmle.label | access to parameter list [element] : A | +| CollectionFlow.cs:376:63:376:66 | access to parameter list [element] : A | semmle.label | access to parameter list [element] : A | | CollectionFlow.cs:376:63:376:69 | access to indexer | semmle.label | access to indexer | -| CollectionFlow.cs:378:61:378:64 | dict [[], Value] : A | semmle.label | dict [[], Value] : A | -| CollectionFlow.cs:378:75:378:78 | access to parameter dict [[], Value] : A | semmle.label | access to parameter dict [[], Value] : A | +| CollectionFlow.cs:378:61:378:64 | dict [element, property Value] : A | semmle.label | dict [element, property Value] : A | +| CollectionFlow.cs:378:75:378:78 | access to parameter dict [element, property Value] : A | semmle.label | access to parameter dict [element, property Value] : A | | CollectionFlow.cs:378:75:378:81 | access to indexer | semmle.label | access to indexer | -| CollectionFlow.cs:380:59:380:62 | dict [[], Key] : A | semmle.label | dict [[], Key] : A | -| CollectionFlow.cs:380:73:380:76 | access to parameter dict [[], Key] : A | semmle.label | access to parameter dict [[], Key] : A | -| CollectionFlow.cs:380:73:380:81 | access to property Keys [[]] : A | semmle.label | access to property Keys [[]] : A | +| CollectionFlow.cs:380:59:380:62 | dict [element, property Key] : A | semmle.label | dict [element, property Key] : A | +| CollectionFlow.cs:380:73:380:76 | access to parameter dict [element, property Key] : A | semmle.label | access to parameter dict [element, property Key] : A | +| CollectionFlow.cs:380:73:380:81 | access to property Keys [element] : A | semmle.label | access to property Keys [element] : A | | CollectionFlow.cs:380:73:380:89 | call to method First | semmle.label | call to method First | -| CollectionFlow.cs:396:49:396:52 | args [[]] : A | semmle.label | args [[]] : A | -| CollectionFlow.cs:396:49:396:52 | args [[]] : A | semmle.label | args [[]] : A | -| CollectionFlow.cs:396:63:396:66 | access to parameter args [[]] : A | semmle.label | access to parameter args [[]] : A | -| CollectionFlow.cs:396:63:396:66 | access to parameter args [[]] : A | semmle.label | access to parameter args [[]] : A | +| CollectionFlow.cs:396:49:396:52 | args [element] : A | semmle.label | args [element] : A | +| CollectionFlow.cs:396:49:396:52 | args [element] : A | semmle.label | args [element] : A | +| CollectionFlow.cs:396:63:396:66 | access to parameter args [element] : A | semmle.label | access to parameter args [element] : A | +| CollectionFlow.cs:396:63:396:66 | access to parameter args [element] : A | semmle.label | access to parameter args [element] : A | | CollectionFlow.cs:396:63:396:69 | access to array element | semmle.label | access to array element | #select | CollectionFlow.cs:14:17:14:23 | object creation of type A : A | CollectionFlow.cs:14:17:14:23 | object creation of type A : A | CollectionFlow.cs:16:14:16:19 | access to array element | $@ | CollectionFlow.cs:16:14:16:19 | access to array element | access to array element | diff --git a/csharp/ql/test/library-tests/dataflow/delegates/DelegateFlow.cs b/csharp/ql/test/library-tests/dataflow/delegates/DelegateFlow.cs index 59c1c924a80..15d628aea9a 100644 --- a/csharp/ql/test/library-tests/dataflow/delegates/DelegateFlow.cs +++ b/csharp/ql/test/library-tests/dataflow/delegates/DelegateFlow.cs @@ -124,4 +124,13 @@ class DelegateFlow delegate*, void> fnptr = &M2; fnptr((i) => { }); } + + void M19(Action a, bool b) + { + if (b) + a = () => {}; + a(); + } + + void M20(bool b) => M19(() => {}, b); } diff --git a/csharp/ql/test/library-tests/dataflow/delegates/DelegateFlow.expected b/csharp/ql/test/library-tests/dataflow/delegates/DelegateFlow.expected index 80ae0d0fe89..f9fbbbab6be 100644 --- a/csharp/ql/test/library-tests/dataflow/delegates/DelegateFlow.expected +++ b/csharp/ql/test/library-tests/dataflow/delegates/DelegateFlow.expected @@ -1,26 +1,55 @@ -summaryDelegateCall -| file://:0:0:0:0 | valueFactory | DelegateFlow.cs:104:23:104:30 | (...) => ... | DelegateFlow.cs:105:23:105:23 | access to local variable f | -| file://:0:0:0:0 | valueFactory | DelegateFlow.cs:106:13:106:20 | (...) => ... | DelegateFlow.cs:107:23:107:23 | access to local variable f | delegateCall -| DelegateFlow.cs:9:9:9:12 | delegate call | DelegateFlow.cs:5:10:5:11 | M1 | DelegateFlow.cs:17:12:17:13 | delegate creation of type Action | -| DelegateFlow.cs:9:9:9:12 | delegate call | DelegateFlow.cs:5:10:5:11 | M1 | DelegateFlow.cs:22:12:22:12 | access to parameter a | -| DelegateFlow.cs:9:9:9:12 | delegate call | DelegateFlow.cs:16:12:16:19 | (...) => ... | DelegateFlow.cs:16:12:16:19 | (...) => ... | -| DelegateFlow.cs:9:9:9:12 | delegate call | DelegateFlow.cs:27:12:27:19 | (...) => ... | DelegateFlow.cs:22:12:22:12 | access to parameter a | -| DelegateFlow.cs:9:9:9:12 | delegate call | DelegateFlow.cs:98:9:98:37 | LocalFunction | DelegateFlow.cs:99:12:99:24 | delegate creation of type Action | -| DelegateFlow.cs:9:9:9:12 | delegate call | DelegateFlow.cs:119:18:119:27 | (...) => ... | DelegateFlow.cs:114:15:114:15 | access to parameter a | -| DelegateFlow.cs:9:9:9:12 | delegate call | DelegateFlow.cs:125:15:125:24 | (...) => ... | DelegateFlow.cs:125:15:125:24 | (...) => ... | -| DelegateFlow.cs:11:9:11:12 | delegate call | DelegateFlow.cs:10:13:10:20 | (...) => ... | file://:0:0:0:0 | | -| DelegateFlow.cs:33:9:33:13 | delegate call | DelegateFlow.cs:38:12:38:25 | (...) => ... | DelegateFlow.cs:38:12:38:25 | (...) => ... | -| DelegateFlow.cs:38:19:38:22 | delegate call | DelegateFlow.cs:5:10:5:11 | M1 | DelegateFlow.cs:33:12:33:12 | access to parameter a | -| DelegateFlow.cs:44:15:44:22 | delegate call | DelegateFlow.cs:43:22:43:29 | (...) => ... | DelegateFlow.cs:50:18:50:23 | dynamic access to member Prop | -| DelegateFlow.cs:57:9:57:11 | delegate call | DelegateFlow.cs:53:34:53:47 | (...) => ... | file://:0:0:0:0 | | -| DelegateFlow.cs:57:9:57:14 | delegate call | DelegateFlow.cs:53:40:53:47 | (...) => ... | file://:0:0:0:0 | | -| DelegateFlow.cs:67:9:67:16 | delegate call | DelegateFlow.cs:62:16:62:23 | (...) => ... | file://:0:0:0:0 | | -| DelegateFlow.cs:77:9:77:15 | delegate call | DelegateFlow.cs:55:10:55:11 | M9 | file://:0:0:0:0 | | -| DelegateFlow.cs:77:9:77:15 | delegate call | DelegateFlow.cs:65:10:65:12 | M11 | file://:0:0:0:0 | | -| DelegateFlow.cs:84:9:84:15 | delegate call | DelegateFlow.cs:55:10:55:11 | M9 | DelegateFlow.cs:78:13:78:14 | delegate creation of type EventHandler | -| DelegateFlow.cs:84:9:84:15 | delegate call | DelegateFlow.cs:65:10:65:12 | M11 | file://:0:0:0:0 | | -| DelegateFlow.cs:89:35:89:37 | delegate call | DelegateFlow.cs:55:10:55:11 | M9 | DelegateFlow.cs:90:13:90:30 | delegate creation of type MyDelegate | -| DelegateFlow.cs:89:35:89:37 | delegate call | DelegateFlow.cs:65:10:65:12 | M11 | DelegateFlow.cs:91:13:91:47 | delegate creation of type MyDelegate | -| DelegateFlow.cs:89:35:89:37 | delegate call | DelegateFlow.cs:74:17:74:19 | M12 | DelegateFlow.cs:92:13:92:15 | delegate creation of type MyDelegate | -| DelegateFlow.cs:89:35:89:37 | delegate call | DelegateFlow.cs:93:13:93:21 | (...) => ... | DelegateFlow.cs:93:13:93:21 | (...) => ... | +| DelegateFlow.cs:9:9:9:12 | delegate call | DelegateFlow.cs:5:10:5:11 | M1 | +| DelegateFlow.cs:9:9:9:12 | delegate call | DelegateFlow.cs:16:12:16:19 | (...) => ... | +| DelegateFlow.cs:9:9:9:12 | delegate call | DelegateFlow.cs:27:12:27:19 | (...) => ... | +| DelegateFlow.cs:9:9:9:12 | delegate call | DelegateFlow.cs:98:9:98:37 | LocalFunction | +| DelegateFlow.cs:9:9:9:12 | delegate call | DelegateFlow.cs:119:18:119:27 | (...) => ... | +| DelegateFlow.cs:9:9:9:12 | delegate call | DelegateFlow.cs:125:15:125:24 | (...) => ... | +| DelegateFlow.cs:11:9:11:12 | delegate call | DelegateFlow.cs:10:13:10:20 | (...) => ... | +| DelegateFlow.cs:33:9:33:13 | delegate call | DelegateFlow.cs:38:12:38:25 | (...) => ... | +| DelegateFlow.cs:38:19:38:22 | delegate call | DelegateFlow.cs:5:10:5:11 | M1 | +| DelegateFlow.cs:44:15:44:22 | delegate call | DelegateFlow.cs:43:22:43:29 | (...) => ... | +| DelegateFlow.cs:57:9:57:11 | delegate call | DelegateFlow.cs:53:34:53:47 | (...) => ... | +| DelegateFlow.cs:57:9:57:14 | delegate call | DelegateFlow.cs:53:40:53:47 | (...) => ... | +| DelegateFlow.cs:67:9:67:16 | delegate call | DelegateFlow.cs:62:16:62:23 | (...) => ... | +| DelegateFlow.cs:77:9:77:15 | delegate call | DelegateFlow.cs:55:10:55:11 | M9 | +| DelegateFlow.cs:77:9:77:15 | delegate call | DelegateFlow.cs:65:10:65:12 | M11 | +| DelegateFlow.cs:84:9:84:15 | delegate call | DelegateFlow.cs:55:10:55:11 | M9 | +| DelegateFlow.cs:84:9:84:15 | delegate call | DelegateFlow.cs:65:10:65:12 | M11 | +| DelegateFlow.cs:89:35:89:37 | delegate call | DelegateFlow.cs:55:10:55:11 | M9 | +| DelegateFlow.cs:89:35:89:37 | delegate call | DelegateFlow.cs:65:10:65:12 | M11 | +| DelegateFlow.cs:89:35:89:37 | delegate call | DelegateFlow.cs:74:17:74:19 | M12 | +| DelegateFlow.cs:89:35:89:37 | delegate call | DelegateFlow.cs:93:13:93:21 | (...) => ... | +| DelegateFlow.cs:114:9:114:16 | function pointer call | DelegateFlow.cs:7:17:7:18 | M2 | +| DelegateFlow.cs:125:9:125:25 | function pointer call | DelegateFlow.cs:7:17:7:18 | M2 | +| DelegateFlow.cs:132:9:132:11 | delegate call | DelegateFlow.cs:131:17:131:24 | (...) => ... | +| DelegateFlow.cs:132:9:132:11 | delegate call | DelegateFlow.cs:135:29:135:36 | (...) => ... | +viableLambda +| DelegateFlow.cs:9:9:9:12 | delegate call | DelegateFlow.cs:16:9:16:20 | call to method M2 | DelegateFlow.cs:16:12:16:19 | (...) => ... | +| DelegateFlow.cs:9:9:9:12 | delegate call | DelegateFlow.cs:17:9:17:14 | call to method M2 | DelegateFlow.cs:5:10:5:11 | M1 | +| DelegateFlow.cs:9:9:9:12 | delegate call | DelegateFlow.cs:22:9:22:13 | call to method M2 | DelegateFlow.cs:5:10:5:11 | M1 | +| DelegateFlow.cs:9:9:9:12 | delegate call | DelegateFlow.cs:22:9:22:13 | call to method M2 | DelegateFlow.cs:27:12:27:19 | (...) => ... | +| DelegateFlow.cs:9:9:9:12 | delegate call | DelegateFlow.cs:99:9:99:25 | call to method M2 | DelegateFlow.cs:98:9:98:37 | LocalFunction | +| DelegateFlow.cs:9:9:9:12 | delegate call | DelegateFlow.cs:114:9:114:16 | function pointer call | DelegateFlow.cs:119:18:119:27 | (...) => ... | +| DelegateFlow.cs:9:9:9:12 | delegate call | DelegateFlow.cs:125:9:125:25 | function pointer call | DelegateFlow.cs:125:15:125:24 | (...) => ... | +| DelegateFlow.cs:11:9:11:12 | delegate call | file://:0:0:0:0 | (none) | DelegateFlow.cs:10:13:10:20 | (...) => ... | +| DelegateFlow.cs:33:9:33:13 | delegate call | DelegateFlow.cs:38:9:38:30 | call to method M6 | DelegateFlow.cs:38:12:38:25 | (...) => ... | +| DelegateFlow.cs:38:19:38:22 | delegate call | DelegateFlow.cs:33:9:33:13 | delegate call | DelegateFlow.cs:5:10:5:11 | M1 | +| DelegateFlow.cs:44:15:44:22 | delegate call | DelegateFlow.cs:50:9:50:14 | dynamic access to member Prop | DelegateFlow.cs:43:22:43:29 | (...) => ... | +| DelegateFlow.cs:57:9:57:11 | delegate call | file://:0:0:0:0 | (none) | DelegateFlow.cs:53:34:53:47 | (...) => ... | +| DelegateFlow.cs:57:9:57:14 | delegate call | file://:0:0:0:0 | (none) | DelegateFlow.cs:53:40:53:47 | (...) => ... | +| DelegateFlow.cs:67:9:67:16 | delegate call | file://:0:0:0:0 | (none) | DelegateFlow.cs:62:16:62:23 | (...) => ... | +| DelegateFlow.cs:77:9:77:15 | delegate call | file://:0:0:0:0 | (none) | DelegateFlow.cs:55:10:55:11 | M9 | +| DelegateFlow.cs:77:9:77:15 | delegate call | file://:0:0:0:0 | (none) | DelegateFlow.cs:65:10:65:12 | M11 | +| DelegateFlow.cs:84:9:84:15 | delegate call | DelegateFlow.cs:78:9:78:15 | call to method M13 | DelegateFlow.cs:55:10:55:11 | M9 | +| DelegateFlow.cs:84:9:84:15 | delegate call | file://:0:0:0:0 | (none) | DelegateFlow.cs:65:10:65:12 | M11 | +| DelegateFlow.cs:89:35:89:37 | delegate call | DelegateFlow.cs:90:9:90:31 | call to local function M14 | DelegateFlow.cs:55:10:55:11 | M9 | +| DelegateFlow.cs:89:35:89:37 | delegate call | DelegateFlow.cs:91:9:91:48 | call to local function M14 | DelegateFlow.cs:65:10:65:12 | M11 | +| DelegateFlow.cs:89:35:89:37 | delegate call | DelegateFlow.cs:92:9:92:16 | call to local function M14 | DelegateFlow.cs:74:17:74:19 | M12 | +| DelegateFlow.cs:89:35:89:37 | delegate call | DelegateFlow.cs:93:9:93:22 | call to local function M14 | DelegateFlow.cs:93:13:93:21 | (...) => ... | +| DelegateFlow.cs:114:9:114:16 | function pointer call | DelegateFlow.cs:119:9:119:28 | call to method M16 | DelegateFlow.cs:7:17:7:18 | M2 | +| DelegateFlow.cs:125:9:125:25 | function pointer call | file://:0:0:0:0 | (none) | DelegateFlow.cs:7:17:7:18 | M2 | +| DelegateFlow.cs:132:9:132:11 | delegate call | DelegateFlow.cs:135:25:135:40 | call to method M19 | DelegateFlow.cs:135:29:135:36 | (...) => ... | +| DelegateFlow.cs:132:9:132:11 | delegate call | file://:0:0:0:0 | (none) | DelegateFlow.cs:131:17:131:24 | (...) => ... | +| file://:0:0:0:0 | [summary] call to valueFactory in Lazy | DelegateFlow.cs:105:9:105:24 | object creation of type Lazy | DelegateFlow.cs:104:23:104:30 | (...) => ... | +| file://:0:0:0:0 | [summary] call to valueFactory in Lazy | DelegateFlow.cs:107:9:107:24 | object creation of type Lazy | DelegateFlow.cs:106:13:106:20 | (...) => ... | diff --git a/csharp/ql/test/library-tests/dataflow/delegates/DelegateFlow.ql b/csharp/ql/test/library-tests/dataflow/delegates/DelegateFlow.ql index c01feabc2f9..6ec7637bf6c 100644 --- a/csharp/ql/test/library-tests/dataflow/delegates/DelegateFlow.ql +++ b/csharp/ql/test/library-tests/dataflow/delegates/DelegateFlow.ql @@ -1,22 +1,34 @@ import csharp -import semmle.code.csharp.dataflow.internal.DataFlowPrivate -import semmle.code.csharp.dataflow.internal.DelegateDataFlow +import semmle.code.csharp.dataflow.internal.DataFlowImplCommon +import semmle.code.csharp.dataflow.internal.DataFlowDispatch -private class NodeAdjusted extends TNode { - string toString() { result = this.(DataFlow::Node).toString() } +query predicate delegateCall(DelegateLikeCall dc, Callable c) { c = dc.getARuntimeTarget() } + +private class LocatableDataFlowCallOption extends DataFlowCallOption { + Location getLocation() { + this = TDataFlowCallNone() and + result instanceof EmptyLocation + or + exists(DataFlowCall call | + this = TDataFlowCallSome(call) and + result = call.getLocation() + ) + } +} + +private class LocatableDataFlowCall extends TDataFlowCall { + string toString() { result = this.(DataFlowCall).toString() } Location getLocation() { exists(Location l | - l = this.(DataFlow::Node).getLocation() and + l = this.(DataFlowCall).getLocation() and if l instanceof SourceLocation then result = l else result instanceof EmptyLocation ) } } -query predicate summaryDelegateCall(NodeAdjusted sink, Callable c, CallContext::CallContext cc) { - c = sink.(SummaryDelegateParameterSink).getARuntimeTarget(cc) -} - -query predicate delegateCall(DelegateCall dc, Callable c, CallContext::CallContext cc) { - c = dc.getARuntimeTarget(cc) +query predicate viableLambda( + LocatableDataFlowCall call, LocatableDataFlowCallOption lastCall, DataFlowCallable target +) { + target = viableCallableLambda(call, lastCall) } diff --git a/csharp/ql/test/library-tests/dataflow/fields/FieldFlow.expected b/csharp/ql/test/library-tests/dataflow/fields/FieldFlow.expected index e776b086467..46dfd50b07a 100644 --- a/csharp/ql/test/library-tests/dataflow/fields/FieldFlow.expected +++ b/csharp/ql/test/library-tests/dataflow/fields/FieldFlow.expected @@ -1,542 +1,542 @@ edges | A.cs:5:17:5:23 | object creation of type C : C | A.cs:6:24:6:24 | access to local variable c : C | -| A.cs:6:17:6:25 | call to method Make [c] : C | A.cs:7:14:7:14 | access to local variable b [c] : C | -| A.cs:6:24:6:24 | access to local variable c : C | A.cs:6:17:6:25 | call to method Make [c] : C | -| A.cs:7:14:7:14 | access to local variable b [c] : C | A.cs:7:14:7:16 | access to field c | -| A.cs:13:9:13:9 | [post] access to local variable b [c] : C1 | A.cs:14:14:14:14 | access to local variable b [c] : C1 | -| A.cs:13:15:13:22 | object creation of type C1 : C1 | A.cs:13:9:13:9 | [post] access to local variable b [c] : C1 | -| A.cs:14:14:14:14 | access to local variable b [c] : C1 | A.cs:14:14:14:20 | call to method Get | -| A.cs:15:15:15:28 | object creation of type B [c] : C | A.cs:15:14:15:35 | call to method Get | -| A.cs:15:21:15:27 | object creation of type C : C | A.cs:15:15:15:28 | object creation of type B [c] : C | -| A.cs:22:14:22:33 | call to method SetOnB [c] : C2 | A.cs:24:14:24:15 | access to local variable b2 [c] : C2 | -| A.cs:22:25:22:32 | object creation of type C2 : C2 | A.cs:22:14:22:33 | call to method SetOnB [c] : C2 | -| A.cs:24:14:24:15 | access to local variable b2 [c] : C2 | A.cs:24:14:24:17 | access to field c | -| A.cs:31:14:31:37 | call to method SetOnBWrap [c] : C2 | A.cs:33:14:33:15 | access to local variable b2 [c] : C2 | -| A.cs:31:29:31:36 | object creation of type C2 : C2 | A.cs:31:14:31:37 | call to method SetOnBWrap [c] : C2 | -| A.cs:33:14:33:15 | access to local variable b2 [c] : C2 | A.cs:33:14:33:17 | access to field c | +| A.cs:6:17:6:25 | call to method Make [field c] : C | A.cs:7:14:7:14 | access to local variable b [field c] : C | +| A.cs:6:24:6:24 | access to local variable c : C | A.cs:6:17:6:25 | call to method Make [field c] : C | +| A.cs:7:14:7:14 | access to local variable b [field c] : C | A.cs:7:14:7:16 | access to field c | +| A.cs:13:9:13:9 | [post] access to local variable b [field c] : C1 | A.cs:14:14:14:14 | access to local variable b [field c] : C1 | +| A.cs:13:15:13:22 | object creation of type C1 : C1 | A.cs:13:9:13:9 | [post] access to local variable b [field c] : C1 | +| A.cs:14:14:14:14 | access to local variable b [field c] : C1 | A.cs:14:14:14:20 | call to method Get | +| A.cs:15:15:15:28 | object creation of type B [field c] : C | A.cs:15:14:15:35 | call to method Get | +| A.cs:15:21:15:27 | object creation of type C : C | A.cs:15:15:15:28 | object creation of type B [field c] : C | +| A.cs:22:14:22:33 | call to method SetOnB [field c] : C2 | A.cs:24:14:24:15 | access to local variable b2 [field c] : C2 | +| A.cs:22:25:22:32 | object creation of type C2 : C2 | A.cs:22:14:22:33 | call to method SetOnB [field c] : C2 | +| A.cs:24:14:24:15 | access to local variable b2 [field c] : C2 | A.cs:24:14:24:17 | access to field c | +| A.cs:31:14:31:37 | call to method SetOnBWrap [field c] : C2 | A.cs:33:14:33:15 | access to local variable b2 [field c] : C2 | +| A.cs:31:29:31:36 | object creation of type C2 : C2 | A.cs:31:14:31:37 | call to method SetOnBWrap [field c] : C2 | +| A.cs:33:14:33:15 | access to local variable b2 [field c] : C2 | A.cs:33:14:33:17 | access to field c | | A.cs:55:17:55:23 | object creation of type A : A | A.cs:57:16:57:16 | access to local variable a : A | -| A.cs:57:9:57:10 | [post] access to local variable c1 [a] : A | A.cs:58:12:58:13 | access to local variable c1 [a] : A | -| A.cs:57:16:57:16 | access to local variable a : A | A.cs:57:9:57:10 | [post] access to local variable c1 [a] : A | -| A.cs:58:12:58:13 | access to local variable c1 [a] : A | A.cs:60:22:60:22 | c [a] : A | -| A.cs:60:22:60:22 | c [a] : A | A.cs:64:19:64:23 | (...) ... [a] : A | -| A.cs:64:19:64:23 | (...) ... [a] : A | A.cs:64:18:64:26 | access to field a | -| A.cs:83:9:83:9 | [post] access to parameter b [c] : C | A.cs:88:12:88:12 | [post] access to local variable b [c] : C | -| A.cs:83:15:83:21 | object creation of type C : C | A.cs:83:9:83:9 | [post] access to parameter b [c] : C | -| A.cs:88:12:88:12 | [post] access to local variable b [c] : C | A.cs:89:14:89:14 | access to local variable b [c] : C | -| A.cs:89:14:89:14 | access to local variable b [c] : C | A.cs:89:14:89:16 | access to field c | -| A.cs:97:13:97:13 | [post] access to parameter b [c] : C | A.cs:98:22:98:36 | ... ? ... : ... [c] : C | -| A.cs:97:13:97:13 | [post] access to parameter b [c] : C | A.cs:105:23:105:23 | [post] access to local variable b [c] : C | -| A.cs:97:19:97:25 | object creation of type C : C | A.cs:97:13:97:13 | [post] access to parameter b [c] : C | -| A.cs:98:13:98:16 | [post] this access [b, c] : C | A.cs:105:17:105:29 | object creation of type D [b, c] : C | -| A.cs:98:13:98:16 | [post] this access [b] : B | A.cs:105:17:105:29 | object creation of type D [b] : B | -| A.cs:98:22:98:36 | ... ? ... : ... : B | A.cs:98:13:98:16 | [post] this access [b] : B | -| A.cs:98:22:98:36 | ... ? ... : ... [c] : C | A.cs:98:13:98:16 | [post] this access [b, c] : C | +| A.cs:57:9:57:10 | [post] access to local variable c1 [field a] : A | A.cs:58:12:58:13 | access to local variable c1 [field a] : A | +| A.cs:57:16:57:16 | access to local variable a : A | A.cs:57:9:57:10 | [post] access to local variable c1 [field a] : A | +| A.cs:58:12:58:13 | access to local variable c1 [field a] : A | A.cs:60:22:60:22 | c [field a] : A | +| A.cs:60:22:60:22 | c [field a] : A | A.cs:64:19:64:23 | (...) ... [field a] : A | +| A.cs:64:19:64:23 | (...) ... [field a] : A | A.cs:64:18:64:26 | access to field a | +| A.cs:83:9:83:9 | [post] access to parameter b [field c] : C | A.cs:88:12:88:12 | [post] access to local variable b [field c] : C | +| A.cs:83:15:83:21 | object creation of type C : C | A.cs:83:9:83:9 | [post] access to parameter b [field c] : C | +| A.cs:88:12:88:12 | [post] access to local variable b [field c] : C | A.cs:89:14:89:14 | access to local variable b [field c] : C | +| A.cs:89:14:89:14 | access to local variable b [field c] : C | A.cs:89:14:89:16 | access to field c | +| A.cs:97:13:97:13 | [post] access to parameter b [field c] : C | A.cs:98:22:98:36 | ... ? ... : ... [field c] : C | +| A.cs:97:13:97:13 | [post] access to parameter b [field c] : C | A.cs:105:23:105:23 | [post] access to local variable b [field c] : C | +| A.cs:97:19:97:25 | object creation of type C : C | A.cs:97:13:97:13 | [post] access to parameter b [field c] : C | +| A.cs:98:13:98:16 | [post] this access [field b, field c] : C | A.cs:105:17:105:29 | object creation of type D [field b, field c] : C | +| A.cs:98:13:98:16 | [post] this access [field b] : B | A.cs:105:17:105:29 | object creation of type D [field b] : B | +| A.cs:98:22:98:36 | ... ? ... : ... : B | A.cs:98:13:98:16 | [post] this access [field b] : B | +| A.cs:98:22:98:36 | ... ? ... : ... [field c] : C | A.cs:98:13:98:16 | [post] this access [field b, field c] : C | | A.cs:98:30:98:36 | object creation of type B : B | A.cs:98:22:98:36 | ... ? ... : ... : B | | A.cs:104:17:104:23 | object creation of type B : B | A.cs:105:23:105:23 | access to local variable b : B | -| A.cs:105:17:105:29 | object creation of type D [b, c] : C | A.cs:107:14:107:14 | access to local variable d [b, c] : C | -| A.cs:105:17:105:29 | object creation of type D [b] : B | A.cs:106:14:106:14 | access to local variable d [b] : B | -| A.cs:105:23:105:23 | [post] access to local variable b [c] : C | A.cs:108:14:108:14 | access to local variable b [c] : C | -| A.cs:105:23:105:23 | access to local variable b : B | A.cs:105:17:105:29 | object creation of type D [b] : B | -| A.cs:106:14:106:14 | access to local variable d [b] : B | A.cs:106:14:106:16 | access to field b | -| A.cs:107:14:107:14 | access to local variable d [b, c] : C | A.cs:107:14:107:16 | access to field b [c] : C | -| A.cs:107:14:107:16 | access to field b [c] : C | A.cs:107:14:107:18 | access to field c | -| A.cs:108:14:108:14 | access to local variable b [c] : C | A.cs:108:14:108:16 | access to field c | +| A.cs:105:17:105:29 | object creation of type D [field b, field c] : C | A.cs:107:14:107:14 | access to local variable d [field b, field c] : C | +| A.cs:105:17:105:29 | object creation of type D [field b] : B | A.cs:106:14:106:14 | access to local variable d [field b] : B | +| A.cs:105:23:105:23 | [post] access to local variable b [field c] : C | A.cs:108:14:108:14 | access to local variable b [field c] : C | +| A.cs:105:23:105:23 | access to local variable b : B | A.cs:105:17:105:29 | object creation of type D [field b] : B | +| A.cs:106:14:106:14 | access to local variable d [field b] : B | A.cs:106:14:106:16 | access to field b | +| A.cs:107:14:107:14 | access to local variable d [field b, field c] : C | A.cs:107:14:107:16 | access to field b [field c] : C | +| A.cs:107:14:107:16 | access to field b [field c] : C | A.cs:107:14:107:18 | access to field c | +| A.cs:108:14:108:14 | access to local variable b [field c] : C | A.cs:108:14:108:16 | access to field c | | A.cs:113:17:113:23 | object creation of type B : B | A.cs:114:29:114:29 | access to local variable b : B | -| A.cs:114:18:114:54 | object creation of type MyList [head] : B | A.cs:115:35:115:36 | access to local variable l1 [head] : B | -| A.cs:114:29:114:29 | access to local variable b : B | A.cs:114:18:114:54 | object creation of type MyList [head] : B | -| A.cs:115:18:115:37 | object creation of type MyList [next, head] : B | A.cs:116:35:116:36 | access to local variable l2 [next, head] : B | -| A.cs:115:35:115:36 | access to local variable l1 [head] : B | A.cs:115:18:115:37 | object creation of type MyList [next, head] : B | -| A.cs:116:18:116:37 | object creation of type MyList [next, next, head] : B | A.cs:119:14:119:15 | access to local variable l3 [next, next, head] : B | -| A.cs:116:18:116:37 | object creation of type MyList [next, next, head] : B | A.cs:121:41:121:41 | access to local variable l [next, next, head] : B | -| A.cs:116:35:116:36 | access to local variable l2 [next, head] : B | A.cs:116:18:116:37 | object creation of type MyList [next, next, head] : B | -| A.cs:119:14:119:15 | access to local variable l3 [next, next, head] : B | A.cs:119:14:119:20 | access to field next [next, head] : B | -| A.cs:119:14:119:20 | access to field next [next, head] : B | A.cs:119:14:119:25 | access to field next [head] : B | -| A.cs:119:14:119:25 | access to field next [head] : B | A.cs:119:14:119:30 | access to field head | -| A.cs:121:41:121:41 | access to local variable l [next, head] : B | A.cs:121:41:121:46 | access to field next [head] : B | -| A.cs:121:41:121:41 | access to local variable l [next, next, head] : B | A.cs:121:41:121:46 | access to field next [next, head] : B | -| A.cs:121:41:121:46 | access to field next [head] : B | A.cs:123:18:123:18 | access to local variable l [head] : B | -| A.cs:121:41:121:46 | access to field next [next, head] : B | A.cs:121:41:121:41 | access to local variable l [next, head] : B | -| A.cs:123:18:123:18 | access to local variable l [head] : B | A.cs:123:18:123:23 | access to field head | +| A.cs:114:18:114:54 | object creation of type MyList [field head] : B | A.cs:115:35:115:36 | access to local variable l1 [field head] : B | +| A.cs:114:29:114:29 | access to local variable b : B | A.cs:114:18:114:54 | object creation of type MyList [field head] : B | +| A.cs:115:18:115:37 | object creation of type MyList [field next, field head] : B | A.cs:116:35:116:36 | access to local variable l2 [field next, field head] : B | +| A.cs:115:35:115:36 | access to local variable l1 [field head] : B | A.cs:115:18:115:37 | object creation of type MyList [field next, field head] : B | +| A.cs:116:18:116:37 | object creation of type MyList [field next, field next, field head] : B | A.cs:119:14:119:15 | access to local variable l3 [field next, field next, field head] : B | +| A.cs:116:18:116:37 | object creation of type MyList [field next, field next, field head] : B | A.cs:121:41:121:41 | access to local variable l [field next, field next, field head] : B | +| A.cs:116:35:116:36 | access to local variable l2 [field next, field head] : B | A.cs:116:18:116:37 | object creation of type MyList [field next, field next, field head] : B | +| A.cs:119:14:119:15 | access to local variable l3 [field next, field next, field head] : B | A.cs:119:14:119:20 | access to field next [field next, field head] : B | +| A.cs:119:14:119:20 | access to field next [field next, field head] : B | A.cs:119:14:119:25 | access to field next [field head] : B | +| A.cs:119:14:119:25 | access to field next [field head] : B | A.cs:119:14:119:30 | access to field head | +| A.cs:121:41:121:41 | access to local variable l [field next, field head] : B | A.cs:121:41:121:46 | access to field next [field head] : B | +| A.cs:121:41:121:41 | access to local variable l [field next, field next, field head] : B | A.cs:121:41:121:46 | access to field next [field next, field head] : B | +| A.cs:121:41:121:46 | access to field next [field head] : B | A.cs:123:18:123:18 | access to local variable l [field head] : B | +| A.cs:121:41:121:46 | access to field next [field next, field head] : B | A.cs:121:41:121:41 | access to local variable l [field next, field head] : B | +| A.cs:123:18:123:18 | access to local variable l [field head] : B | A.cs:123:18:123:23 | access to field head | | B.cs:5:17:5:26 | object creation of type Elem : Elem | B.cs:6:27:6:27 | access to local variable e : Elem | -| B.cs:6:18:6:34 | object creation of type Box1 [elem1] : Elem | B.cs:7:27:7:28 | access to local variable b1 [elem1] : Elem | -| B.cs:6:27:6:27 | access to local variable e : Elem | B.cs:6:18:6:34 | object creation of type Box1 [elem1] : Elem | -| B.cs:7:18:7:29 | object creation of type Box2 [box1, elem1] : Elem | B.cs:8:14:8:15 | access to local variable b2 [box1, elem1] : Elem | -| B.cs:7:27:7:28 | access to local variable b1 [elem1] : Elem | B.cs:7:18:7:29 | object creation of type Box2 [box1, elem1] : Elem | -| B.cs:8:14:8:15 | access to local variable b2 [box1, elem1] : Elem | B.cs:8:14:8:20 | access to field box1 [elem1] : Elem | -| B.cs:8:14:8:20 | access to field box1 [elem1] : Elem | B.cs:8:14:8:26 | access to field elem1 | +| B.cs:6:18:6:34 | object creation of type Box1 [field elem1] : Elem | B.cs:7:27:7:28 | access to local variable b1 [field elem1] : Elem | +| B.cs:6:27:6:27 | access to local variable e : Elem | B.cs:6:18:6:34 | object creation of type Box1 [field elem1] : Elem | +| B.cs:7:18:7:29 | object creation of type Box2 [field box1, field elem1] : Elem | B.cs:8:14:8:15 | access to local variable b2 [field box1, field elem1] : Elem | +| B.cs:7:27:7:28 | access to local variable b1 [field elem1] : Elem | B.cs:7:18:7:29 | object creation of type Box2 [field box1, field elem1] : Elem | +| B.cs:8:14:8:15 | access to local variable b2 [field box1, field elem1] : Elem | B.cs:8:14:8:20 | access to field box1 [field elem1] : Elem | +| B.cs:8:14:8:20 | access to field box1 [field elem1] : Elem | B.cs:8:14:8:26 | access to field elem1 | | B.cs:14:17:14:26 | object creation of type Elem : Elem | B.cs:15:33:15:33 | access to local variable e : Elem | -| B.cs:15:18:15:34 | object creation of type Box1 [elem2] : Elem | B.cs:16:27:16:28 | access to local variable b1 [elem2] : Elem | -| B.cs:15:33:15:33 | access to local variable e : Elem | B.cs:15:18:15:34 | object creation of type Box1 [elem2] : Elem | -| B.cs:16:18:16:29 | object creation of type Box2 [box1, elem2] : Elem | B.cs:18:14:18:15 | access to local variable b2 [box1, elem2] : Elem | -| B.cs:16:27:16:28 | access to local variable b1 [elem2] : Elem | B.cs:16:18:16:29 | object creation of type Box2 [box1, elem2] : Elem | -| B.cs:18:14:18:15 | access to local variable b2 [box1, elem2] : Elem | B.cs:18:14:18:20 | access to field box1 [elem2] : Elem | -| B.cs:18:14:18:20 | access to field box1 [elem2] : Elem | B.cs:18:14:18:26 | access to field elem2 | -| C.cs:3:18:3:19 | [post] this access [s1] : Elem | C.cs:12:15:12:21 | object creation of type C [s1] : Elem | -| C.cs:3:23:3:32 | object creation of type Elem : Elem | C.cs:3:18:3:19 | [post] this access [s1] : Elem | -| C.cs:4:27:4:28 | [post] this access [s2] : Elem | C.cs:12:15:12:21 | object creation of type C [s2] : Elem | -| C.cs:4:32:4:41 | object creation of type Elem : Elem | C.cs:4:27:4:28 | [post] this access [s2] : Elem | +| B.cs:15:18:15:34 | object creation of type Box1 [field elem2] : Elem | B.cs:16:27:16:28 | access to local variable b1 [field elem2] : Elem | +| B.cs:15:33:15:33 | access to local variable e : Elem | B.cs:15:18:15:34 | object creation of type Box1 [field elem2] : Elem | +| B.cs:16:18:16:29 | object creation of type Box2 [field box1, field elem2] : Elem | B.cs:18:14:18:15 | access to local variable b2 [field box1, field elem2] : Elem | +| B.cs:16:27:16:28 | access to local variable b1 [field elem2] : Elem | B.cs:16:18:16:29 | object creation of type Box2 [field box1, field elem2] : Elem | +| B.cs:18:14:18:15 | access to local variable b2 [field box1, field elem2] : Elem | B.cs:18:14:18:20 | access to field box1 [field elem2] : Elem | +| B.cs:18:14:18:20 | access to field box1 [field elem2] : Elem | B.cs:18:14:18:26 | access to field elem2 | +| C.cs:3:18:3:19 | [post] this access [field s1] : Elem | C.cs:12:15:12:21 | object creation of type C [field s1] : Elem | +| C.cs:3:23:3:32 | object creation of type Elem : Elem | C.cs:3:18:3:19 | [post] this access [field s1] : Elem | +| C.cs:4:27:4:28 | [post] this access [field s2] : Elem | C.cs:12:15:12:21 | object creation of type C [field s2] : Elem | +| C.cs:4:32:4:41 | object creation of type Elem : Elem | C.cs:4:27:4:28 | [post] this access [field s2] : Elem | | C.cs:6:30:6:39 | object creation of type Elem : Elem | C.cs:26:14:26:15 | access to field s4 | -| C.cs:7:18:7:19 | [post] this access [s5] : Elem | C.cs:12:15:12:21 | object creation of type C [s5] : Elem | -| C.cs:7:37:7:46 | object creation of type Elem : Elem | C.cs:7:18:7:19 | [post] this access [s5] : Elem | +| C.cs:7:18:7:19 | [post] this access [property s5] : Elem | C.cs:12:15:12:21 | object creation of type C [property s5] : Elem | +| C.cs:7:37:7:46 | object creation of type Elem : Elem | C.cs:7:18:7:19 | [post] this access [property s5] : Elem | | C.cs:8:30:8:39 | object creation of type Elem : Elem | C.cs:28:14:28:15 | access to property s6 | -| C.cs:12:15:12:21 | object creation of type C [s1] : Elem | C.cs:13:9:13:9 | access to local variable c [s1] : Elem | -| C.cs:12:15:12:21 | object creation of type C [s2] : Elem | C.cs:13:9:13:9 | access to local variable c [s2] : Elem | -| C.cs:12:15:12:21 | object creation of type C [s3] : Elem | C.cs:13:9:13:9 | access to local variable c [s3] : Elem | -| C.cs:12:15:12:21 | object creation of type C [s5] : Elem | C.cs:13:9:13:9 | access to local variable c [s5] : Elem | -| C.cs:13:9:13:9 | access to local variable c [s1] : Elem | C.cs:21:17:21:18 | this [s1] : Elem | -| C.cs:13:9:13:9 | access to local variable c [s2] : Elem | C.cs:21:17:21:18 | this [s2] : Elem | -| C.cs:13:9:13:9 | access to local variable c [s3] : Elem | C.cs:21:17:21:18 | this [s3] : Elem | -| C.cs:13:9:13:9 | access to local variable c [s5] : Elem | C.cs:21:17:21:18 | this [s5] : Elem | -| C.cs:18:9:18:12 | [post] this access [s3] : Elem | C.cs:12:15:12:21 | object creation of type C [s3] : Elem | -| C.cs:18:19:18:28 | object creation of type Elem : Elem | C.cs:18:9:18:12 | [post] this access [s3] : Elem | -| C.cs:21:17:21:18 | this [s1] : Elem | C.cs:23:14:23:15 | this access [s1] : Elem | -| C.cs:21:17:21:18 | this [s2] : Elem | C.cs:24:14:24:15 | this access [s2] : Elem | -| C.cs:21:17:21:18 | this [s3] : Elem | C.cs:25:14:25:15 | this access [s3] : Elem | -| C.cs:21:17:21:18 | this [s5] : Elem | C.cs:27:14:27:15 | this access [s5] : Elem | -| C.cs:23:14:23:15 | this access [s1] : Elem | C.cs:23:14:23:15 | access to field s1 | -| C.cs:24:14:24:15 | this access [s2] : Elem | C.cs:24:14:24:15 | access to field s2 | -| C.cs:25:14:25:15 | this access [s3] : Elem | C.cs:25:14:25:15 | access to field s3 | -| C.cs:27:14:27:15 | this access [s5] : Elem | C.cs:27:14:27:15 | access to property s5 | +| C.cs:12:15:12:21 | object creation of type C [field s1] : Elem | C.cs:13:9:13:9 | access to local variable c [field s1] : Elem | +| C.cs:12:15:12:21 | object creation of type C [field s2] : Elem | C.cs:13:9:13:9 | access to local variable c [field s2] : Elem | +| C.cs:12:15:12:21 | object creation of type C [field s3] : Elem | C.cs:13:9:13:9 | access to local variable c [field s3] : Elem | +| C.cs:12:15:12:21 | object creation of type C [property s5] : Elem | C.cs:13:9:13:9 | access to local variable c [property s5] : Elem | +| C.cs:13:9:13:9 | access to local variable c [field s1] : Elem | C.cs:21:17:21:18 | this [field s1] : Elem | +| C.cs:13:9:13:9 | access to local variable c [field s2] : Elem | C.cs:21:17:21:18 | this [field s2] : Elem | +| C.cs:13:9:13:9 | access to local variable c [field s3] : Elem | C.cs:21:17:21:18 | this [field s3] : Elem | +| C.cs:13:9:13:9 | access to local variable c [property s5] : Elem | C.cs:21:17:21:18 | this [property s5] : Elem | +| C.cs:18:9:18:12 | [post] this access [field s3] : Elem | C.cs:12:15:12:21 | object creation of type C [field s3] : Elem | +| C.cs:18:19:18:28 | object creation of type Elem : Elem | C.cs:18:9:18:12 | [post] this access [field s3] : Elem | +| C.cs:21:17:21:18 | this [field s1] : Elem | C.cs:23:14:23:15 | this access [field s1] : Elem | +| C.cs:21:17:21:18 | this [field s2] : Elem | C.cs:24:14:24:15 | this access [field s2] : Elem | +| C.cs:21:17:21:18 | this [field s3] : Elem | C.cs:25:14:25:15 | this access [field s3] : Elem | +| C.cs:21:17:21:18 | this [property s5] : Elem | C.cs:27:14:27:15 | this access [property s5] : Elem | +| C.cs:23:14:23:15 | this access [field s1] : Elem | C.cs:23:14:23:15 | access to field s1 | +| C.cs:24:14:24:15 | this access [field s2] : Elem | C.cs:24:14:24:15 | access to field s2 | +| C.cs:25:14:25:15 | this access [field s3] : Elem | C.cs:25:14:25:15 | access to field s3 | +| C.cs:27:14:27:15 | this access [property s5] : Elem | C.cs:27:14:27:15 | access to property s5 | | D.cs:29:17:29:28 | object creation of type Object : Object | D.cs:31:24:31:24 | access to local variable o : Object | | D.cs:29:17:29:28 | object creation of type Object : Object | D.cs:37:26:37:26 | access to local variable o : Object | | D.cs:29:17:29:28 | object creation of type Object : Object | D.cs:43:32:43:32 | access to local variable o : Object | -| D.cs:31:17:31:37 | call to method Create [AutoProp] : Object | D.cs:32:14:32:14 | access to local variable d [AutoProp] : Object | -| D.cs:31:24:31:24 | access to local variable o : Object | D.cs:31:17:31:37 | call to method Create [AutoProp] : Object | -| D.cs:32:14:32:14 | access to local variable d [AutoProp] : Object | D.cs:32:14:32:23 | access to property AutoProp | -| D.cs:37:13:37:33 | call to method Create [trivialPropField] : Object | D.cs:39:14:39:14 | access to local variable d [trivialPropField] : Object | -| D.cs:37:13:37:33 | call to method Create [trivialPropField] : Object | D.cs:40:14:40:14 | access to local variable d [trivialPropField] : Object | -| D.cs:37:13:37:33 | call to method Create [trivialPropField] : Object | D.cs:41:14:41:14 | access to local variable d [trivialPropField] : Object | -| D.cs:37:26:37:26 | access to local variable o : Object | D.cs:37:13:37:33 | call to method Create [trivialPropField] : Object | -| D.cs:39:14:39:14 | access to local variable d [trivialPropField] : Object | D.cs:39:14:39:26 | access to property TrivialProp | -| D.cs:40:14:40:14 | access to local variable d [trivialPropField] : Object | D.cs:40:14:40:31 | access to field trivialPropField | -| D.cs:41:14:41:14 | access to local variable d [trivialPropField] : Object | D.cs:41:14:41:26 | access to property ComplexProp | -| D.cs:43:13:43:33 | call to method Create [trivialPropField] : Object | D.cs:45:14:45:14 | access to local variable d [trivialPropField] : Object | -| D.cs:43:13:43:33 | call to method Create [trivialPropField] : Object | D.cs:46:14:46:14 | access to local variable d [trivialPropField] : Object | -| D.cs:43:13:43:33 | call to method Create [trivialPropField] : Object | D.cs:47:14:47:14 | access to local variable d [trivialPropField] : Object | -| D.cs:43:32:43:32 | access to local variable o : Object | D.cs:43:13:43:33 | call to method Create [trivialPropField] : Object | -| D.cs:45:14:45:14 | access to local variable d [trivialPropField] : Object | D.cs:45:14:45:26 | access to property TrivialProp | -| D.cs:46:14:46:14 | access to local variable d [trivialPropField] : Object | D.cs:46:14:46:31 | access to field trivialPropField | -| D.cs:47:14:47:14 | access to local variable d [trivialPropField] : Object | D.cs:47:14:47:26 | access to property ComplexProp | +| D.cs:31:17:31:37 | call to method Create [property AutoProp] : Object | D.cs:32:14:32:14 | access to local variable d [property AutoProp] : Object | +| D.cs:31:24:31:24 | access to local variable o : Object | D.cs:31:17:31:37 | call to method Create [property AutoProp] : Object | +| D.cs:32:14:32:14 | access to local variable d [property AutoProp] : Object | D.cs:32:14:32:23 | access to property AutoProp | +| D.cs:37:13:37:33 | call to method Create [field trivialPropField] : Object | D.cs:39:14:39:14 | access to local variable d [field trivialPropField] : Object | +| D.cs:37:13:37:33 | call to method Create [field trivialPropField] : Object | D.cs:40:14:40:14 | access to local variable d [field trivialPropField] : Object | +| D.cs:37:13:37:33 | call to method Create [field trivialPropField] : Object | D.cs:41:14:41:14 | access to local variable d [field trivialPropField] : Object | +| D.cs:37:26:37:26 | access to local variable o : Object | D.cs:37:13:37:33 | call to method Create [field trivialPropField] : Object | +| D.cs:39:14:39:14 | access to local variable d [field trivialPropField] : Object | D.cs:39:14:39:26 | access to property TrivialProp | +| D.cs:40:14:40:14 | access to local variable d [field trivialPropField] : Object | D.cs:40:14:40:31 | access to field trivialPropField | +| D.cs:41:14:41:14 | access to local variable d [field trivialPropField] : Object | D.cs:41:14:41:26 | access to property ComplexProp | +| D.cs:43:13:43:33 | call to method Create [field trivialPropField] : Object | D.cs:45:14:45:14 | access to local variable d [field trivialPropField] : Object | +| D.cs:43:13:43:33 | call to method Create [field trivialPropField] : Object | D.cs:46:14:46:14 | access to local variable d [field trivialPropField] : Object | +| D.cs:43:13:43:33 | call to method Create [field trivialPropField] : Object | D.cs:47:14:47:14 | access to local variable d [field trivialPropField] : Object | +| D.cs:43:32:43:32 | access to local variable o : Object | D.cs:43:13:43:33 | call to method Create [field trivialPropField] : Object | +| D.cs:45:14:45:14 | access to local variable d [field trivialPropField] : Object | D.cs:45:14:45:26 | access to property TrivialProp | +| D.cs:46:14:46:14 | access to local variable d [field trivialPropField] : Object | D.cs:46:14:46:31 | access to field trivialPropField | +| D.cs:47:14:47:14 | access to local variable d [field trivialPropField] : Object | D.cs:47:14:47:26 | access to property ComplexProp | | E.cs:22:17:22:28 | object creation of type Object : Object | E.cs:23:25:23:25 | access to local variable o : Object | -| E.cs:23:17:23:26 | call to method CreateS [Field] : Object | E.cs:24:14:24:14 | access to local variable s [Field] : Object | -| E.cs:23:25:23:25 | access to local variable o : Object | E.cs:23:17:23:26 | call to method CreateS [Field] : Object | -| E.cs:24:14:24:14 | access to local variable s [Field] : Object | E.cs:24:14:24:20 | access to field Field | +| E.cs:23:17:23:26 | call to method CreateS [field Field] : Object | E.cs:24:14:24:14 | access to local variable s [field Field] : Object | +| E.cs:23:25:23:25 | access to local variable o : Object | E.cs:23:17:23:26 | call to method CreateS [field Field] : Object | +| E.cs:24:14:24:14 | access to local variable s [field Field] : Object | E.cs:24:14:24:20 | access to field Field | | F.cs:10:17:10:28 | object creation of type Object : Object | F.cs:11:24:11:24 | access to local variable o : Object | | F.cs:10:17:10:28 | object creation of type Object : Object | F.cs:15:26:15:26 | access to local variable o : Object | | F.cs:10:17:10:28 | object creation of type Object : Object | F.cs:19:32:19:32 | access to local variable o : Object | | F.cs:10:17:10:28 | object creation of type Object : Object | F.cs:23:32:23:32 | access to local variable o : Object | -| F.cs:11:17:11:31 | call to method Create [Field1] : Object | F.cs:12:14:12:14 | access to local variable f [Field1] : Object | -| F.cs:11:24:11:24 | access to local variable o : Object | F.cs:11:17:11:31 | call to method Create [Field1] : Object | -| F.cs:12:14:12:14 | access to local variable f [Field1] : Object | F.cs:12:14:12:21 | access to field Field1 | -| F.cs:15:13:15:27 | call to method Create [Field2] : Object | F.cs:17:14:17:14 | access to local variable f [Field2] : Object | -| F.cs:15:26:15:26 | access to local variable o : Object | F.cs:15:13:15:27 | call to method Create [Field2] : Object | -| F.cs:17:14:17:14 | access to local variable f [Field2] : Object | F.cs:17:14:17:21 | access to field Field2 | -| F.cs:19:21:19:34 | { ..., ... } [Field1] : Object | F.cs:20:14:20:14 | access to local variable f [Field1] : Object | -| F.cs:19:32:19:32 | access to local variable o : Object | F.cs:19:21:19:34 | { ..., ... } [Field1] : Object | -| F.cs:20:14:20:14 | access to local variable f [Field1] : Object | F.cs:20:14:20:21 | access to field Field1 | -| F.cs:23:21:23:34 | { ..., ... } [Field2] : Object | F.cs:25:14:25:14 | access to local variable f [Field2] : Object | -| F.cs:23:32:23:32 | access to local variable o : Object | F.cs:23:21:23:34 | { ..., ... } [Field2] : Object | -| F.cs:25:14:25:14 | access to local variable f [Field2] : Object | F.cs:25:14:25:21 | access to field Field2 | +| F.cs:11:17:11:31 | call to method Create [field Field1] : Object | F.cs:12:14:12:14 | access to local variable f [field Field1] : Object | +| F.cs:11:24:11:24 | access to local variable o : Object | F.cs:11:17:11:31 | call to method Create [field Field1] : Object | +| F.cs:12:14:12:14 | access to local variable f [field Field1] : Object | F.cs:12:14:12:21 | access to field Field1 | +| F.cs:15:13:15:27 | call to method Create [field Field2] : Object | F.cs:17:14:17:14 | access to local variable f [field Field2] : Object | +| F.cs:15:26:15:26 | access to local variable o : Object | F.cs:15:13:15:27 | call to method Create [field Field2] : Object | +| F.cs:17:14:17:14 | access to local variable f [field Field2] : Object | F.cs:17:14:17:21 | access to field Field2 | +| F.cs:19:21:19:34 | { ..., ... } [field Field1] : Object | F.cs:20:14:20:14 | access to local variable f [field Field1] : Object | +| F.cs:19:32:19:32 | access to local variable o : Object | F.cs:19:21:19:34 | { ..., ... } [field Field1] : Object | +| F.cs:20:14:20:14 | access to local variable f [field Field1] : Object | F.cs:20:14:20:21 | access to field Field1 | +| F.cs:23:21:23:34 | { ..., ... } [field Field2] : Object | F.cs:25:14:25:14 | access to local variable f [field Field2] : Object | +| F.cs:23:32:23:32 | access to local variable o : Object | F.cs:23:21:23:34 | { ..., ... } [field Field2] : Object | +| F.cs:25:14:25:14 | access to local variable f [field Field2] : Object | F.cs:25:14:25:21 | access to field Field2 | | G.cs:7:18:7:27 | object creation of type Elem : Elem | G.cs:9:23:9:23 | access to local variable e : Elem | -| G.cs:9:9:9:9 | [post] access to local variable b [Box1, Elem] : Elem | G.cs:10:18:10:18 | access to local variable b [Box1, Elem] : Elem | -| G.cs:9:9:9:14 | [post] access to field Box1 [Elem] : Elem | G.cs:9:9:9:9 | [post] access to local variable b [Box1, Elem] : Elem | -| G.cs:9:23:9:23 | access to local variable e : Elem | G.cs:9:9:9:14 | [post] access to field Box1 [Elem] : Elem | -| G.cs:10:18:10:18 | access to local variable b [Box1, Elem] : Elem | G.cs:37:38:37:39 | b2 [Box1, Elem] : Elem | +| G.cs:9:9:9:9 | [post] access to local variable b [field Box1, field Elem] : Elem | G.cs:10:18:10:18 | access to local variable b [field Box1, field Elem] : Elem | +| G.cs:9:9:9:14 | [post] access to field Box1 [field Elem] : Elem | G.cs:9:9:9:9 | [post] access to local variable b [field Box1, field Elem] : Elem | +| G.cs:9:23:9:23 | access to local variable e : Elem | G.cs:9:9:9:14 | [post] access to field Box1 [field Elem] : Elem | +| G.cs:10:18:10:18 | access to local variable b [field Box1, field Elem] : Elem | G.cs:37:38:37:39 | b2 [field Box1, field Elem] : Elem | | G.cs:15:18:15:27 | object creation of type Elem : Elem | G.cs:17:24:17:24 | access to local variable e : Elem | -| G.cs:17:9:17:9 | [post] access to local variable b [Box1, Elem] : Elem | G.cs:18:18:18:18 | access to local variable b [Box1, Elem] : Elem | -| G.cs:17:9:17:14 | [post] access to field Box1 [Elem] : Elem | G.cs:17:9:17:9 | [post] access to local variable b [Box1, Elem] : Elem | -| G.cs:17:24:17:24 | access to local variable e : Elem | G.cs:17:9:17:14 | [post] access to field Box1 [Elem] : Elem | -| G.cs:18:18:18:18 | access to local variable b [Box1, Elem] : Elem | G.cs:37:38:37:39 | b2 [Box1, Elem] : Elem | +| G.cs:17:9:17:9 | [post] access to local variable b [field Box1, field Elem] : Elem | G.cs:18:18:18:18 | access to local variable b [field Box1, field Elem] : Elem | +| G.cs:17:9:17:14 | [post] access to field Box1 [field Elem] : Elem | G.cs:17:9:17:9 | [post] access to local variable b [field Box1, field Elem] : Elem | +| G.cs:17:24:17:24 | access to local variable e : Elem | G.cs:17:9:17:14 | [post] access to field Box1 [field Elem] : Elem | +| G.cs:18:18:18:18 | access to local variable b [field Box1, field Elem] : Elem | G.cs:37:38:37:39 | b2 [field Box1, field Elem] : Elem | | G.cs:23:18:23:27 | object creation of type Elem : Elem | G.cs:25:28:25:28 | access to local variable e : Elem | -| G.cs:25:9:25:9 | [post] access to local variable b [Box1, Elem] : Elem | G.cs:26:18:26:18 | access to local variable b [Box1, Elem] : Elem | -| G.cs:25:9:25:19 | [post] call to method GetBox1 [Elem] : Elem | G.cs:25:9:25:9 | [post] access to local variable b [Box1, Elem] : Elem | -| G.cs:25:28:25:28 | access to local variable e : Elem | G.cs:25:9:25:19 | [post] call to method GetBox1 [Elem] : Elem | -| G.cs:26:18:26:18 | access to local variable b [Box1, Elem] : Elem | G.cs:37:38:37:39 | b2 [Box1, Elem] : Elem | +| G.cs:25:9:25:9 | [post] access to local variable b [field Box1, field Elem] : Elem | G.cs:26:18:26:18 | access to local variable b [field Box1, field Elem] : Elem | +| G.cs:25:9:25:19 | [post] call to method GetBox1 [field Elem] : Elem | G.cs:25:9:25:9 | [post] access to local variable b [field Box1, field Elem] : Elem | +| G.cs:25:28:25:28 | access to local variable e : Elem | G.cs:25:9:25:19 | [post] call to method GetBox1 [field Elem] : Elem | +| G.cs:26:18:26:18 | access to local variable b [field Box1, field Elem] : Elem | G.cs:37:38:37:39 | b2 [field Box1, field Elem] : Elem | | G.cs:31:18:31:27 | object creation of type Elem : Elem | G.cs:33:29:33:29 | access to local variable e : Elem | -| G.cs:33:9:33:9 | [post] access to local variable b [Box1, Elem] : Elem | G.cs:34:18:34:18 | access to local variable b [Box1, Elem] : Elem | -| G.cs:33:9:33:19 | [post] call to method GetBox1 [Elem] : Elem | G.cs:33:9:33:9 | [post] access to local variable b [Box1, Elem] : Elem | -| G.cs:33:29:33:29 | access to local variable e : Elem | G.cs:33:9:33:19 | [post] call to method GetBox1 [Elem] : Elem | -| G.cs:34:18:34:18 | access to local variable b [Box1, Elem] : Elem | G.cs:37:38:37:39 | b2 [Box1, Elem] : Elem | -| G.cs:37:38:37:39 | b2 [Box1, Elem] : Elem | G.cs:39:14:39:15 | access to parameter b2 [Box1, Elem] : Elem | -| G.cs:39:14:39:15 | access to parameter b2 [Box1, Elem] : Elem | G.cs:39:14:39:25 | call to method GetBox1 [Elem] : Elem | -| G.cs:39:14:39:25 | call to method GetBox1 [Elem] : Elem | G.cs:39:14:39:35 | call to method GetElem | +| G.cs:33:9:33:9 | [post] access to local variable b [field Box1, field Elem] : Elem | G.cs:34:18:34:18 | access to local variable b [field Box1, field Elem] : Elem | +| G.cs:33:9:33:19 | [post] call to method GetBox1 [field Elem] : Elem | G.cs:33:9:33:9 | [post] access to local variable b [field Box1, field Elem] : Elem | +| G.cs:33:29:33:29 | access to local variable e : Elem | G.cs:33:9:33:19 | [post] call to method GetBox1 [field Elem] : Elem | +| G.cs:34:18:34:18 | access to local variable b [field Box1, field Elem] : Elem | G.cs:37:38:37:39 | b2 [field Box1, field Elem] : Elem | +| G.cs:37:38:37:39 | b2 [field Box1, field Elem] : Elem | G.cs:39:14:39:15 | access to parameter b2 [field Box1, field Elem] : Elem | +| G.cs:39:14:39:15 | access to parameter b2 [field Box1, field Elem] : Elem | G.cs:39:14:39:25 | call to method GetBox1 [field Elem] : Elem | +| G.cs:39:14:39:25 | call to method GetBox1 [field Elem] : Elem | G.cs:39:14:39:35 | call to method GetElem | | G.cs:44:18:44:27 | object creation of type Elem : Elem | G.cs:46:30:46:30 | access to local variable e : Elem | -| G.cs:46:9:46:16 | [post] access to field boxfield [Box1, Elem] : Elem | G.cs:46:9:46:16 | [post] this access [boxfield, Box1, Elem] : Elem | -| G.cs:46:9:46:16 | [post] this access [boxfield, Box1, Elem] : Elem | G.cs:47:9:47:13 | this access [boxfield, Box1, Elem] : Elem | -| G.cs:46:9:46:21 | [post] access to field Box1 [Elem] : Elem | G.cs:46:9:46:16 | [post] access to field boxfield [Box1, Elem] : Elem | -| G.cs:46:30:46:30 | access to local variable e : Elem | G.cs:46:9:46:21 | [post] access to field Box1 [Elem] : Elem | -| G.cs:47:9:47:13 | this access [boxfield, Box1, Elem] : Elem | G.cs:50:18:50:20 | this [boxfield, Box1, Elem] : Elem | -| G.cs:50:18:50:20 | this [boxfield, Box1, Elem] : Elem | G.cs:52:14:52:21 | this access [boxfield, Box1, Elem] : Elem | -| G.cs:52:14:52:21 | access to field boxfield [Box1, Elem] : Elem | G.cs:52:14:52:26 | access to field Box1 [Elem] : Elem | -| G.cs:52:14:52:21 | this access [boxfield, Box1, Elem] : Elem | G.cs:52:14:52:21 | access to field boxfield [Box1, Elem] : Elem | -| G.cs:52:14:52:26 | access to field Box1 [Elem] : Elem | G.cs:52:14:52:31 | access to field Elem | -| H.cs:23:9:23:9 | [post] access to local variable a [FieldA] : Object | H.cs:24:27:24:27 | access to local variable a [FieldA] : Object | -| H.cs:23:20:23:31 | object creation of type Object : Object | H.cs:23:9:23:9 | [post] access to local variable a [FieldA] : Object | -| H.cs:24:21:24:28 | call to method Clone [FieldA] : Object | H.cs:25:14:25:18 | access to local variable clone [FieldA] : Object | -| H.cs:24:27:24:27 | access to local variable a [FieldA] : Object | H.cs:24:21:24:28 | call to method Clone [FieldA] : Object | -| H.cs:25:14:25:18 | access to local variable clone [FieldA] : Object | H.cs:25:14:25:25 | access to field FieldA | -| H.cs:43:9:43:9 | [post] access to local variable a [FieldA] : Object | H.cs:44:27:44:27 | access to local variable a [FieldA] : Object | -| H.cs:43:20:43:31 | object creation of type Object : Object | H.cs:43:9:43:9 | [post] access to local variable a [FieldA] : Object | -| H.cs:44:17:44:28 | call to method Transform [FieldB] : Object | H.cs:45:14:45:14 | access to local variable b [FieldB] : Object | -| H.cs:44:27:44:27 | access to local variable a [FieldA] : Object | H.cs:44:17:44:28 | call to method Transform [FieldB] : Object | -| H.cs:45:14:45:14 | access to local variable b [FieldB] : Object | H.cs:45:14:45:21 | access to field FieldB | -| H.cs:63:9:63:9 | [post] access to local variable a [FieldA] : Object | H.cs:64:22:64:22 | access to local variable a [FieldA] : Object | -| H.cs:63:20:63:31 | object creation of type Object : Object | H.cs:63:9:63:9 | [post] access to local variable a [FieldA] : Object | -| H.cs:64:22:64:22 | access to local variable a [FieldA] : Object | H.cs:64:25:64:26 | [post] access to local variable b1 [FieldB] : Object | -| H.cs:64:25:64:26 | [post] access to local variable b1 [FieldB] : Object | H.cs:65:14:65:15 | access to local variable b1 [FieldB] : Object | -| H.cs:65:14:65:15 | access to local variable b1 [FieldB] : Object | H.cs:65:14:65:22 | access to field FieldB | -| H.cs:88:17:88:17 | [post] access to local variable a [FieldA] : Object | H.cs:89:14:89:14 | access to local variable a [FieldA] : Object | -| H.cs:88:20:88:31 | object creation of type Object : Object | H.cs:88:17:88:17 | [post] access to local variable a [FieldA] : Object | -| H.cs:88:20:88:31 | object creation of type Object : Object | H.cs:88:34:88:35 | [post] access to local variable b1 [FieldB] : Object | -| H.cs:88:34:88:35 | [post] access to local variable b1 [FieldB] : Object | H.cs:90:14:90:15 | access to local variable b1 [FieldB] : Object | -| H.cs:89:14:89:14 | access to local variable a [FieldA] : Object | H.cs:89:14:89:21 | access to field FieldA | -| H.cs:90:14:90:15 | access to local variable b1 [FieldB] : Object | H.cs:90:14:90:22 | access to field FieldB | -| H.cs:112:9:112:9 | [post] access to local variable a [FieldA] : Object | H.cs:113:31:113:31 | access to local variable a [FieldA] : Object | -| H.cs:112:20:112:31 | object creation of type Object : Object | H.cs:112:9:112:9 | [post] access to local variable a [FieldA] : Object | -| H.cs:113:17:113:32 | call to method TransformWrap [FieldB] : Object | H.cs:114:14:114:14 | access to local variable b [FieldB] : Object | -| H.cs:113:31:113:31 | access to local variable a [FieldA] : Object | H.cs:113:17:113:32 | call to method TransformWrap [FieldB] : Object | -| H.cs:114:14:114:14 | access to local variable b [FieldB] : Object | H.cs:114:14:114:21 | access to field FieldB | -| H.cs:130:9:130:9 | [post] access to local variable a [FieldA] : Object | H.cs:131:18:131:18 | access to local variable a [FieldA] : Object | -| H.cs:130:20:130:31 | object creation of type Object : Object | H.cs:130:9:130:9 | [post] access to local variable a [FieldA] : Object | -| H.cs:131:18:131:18 | access to local variable a [FieldA] : Object | H.cs:131:14:131:19 | call to method Get | +| G.cs:46:9:46:16 | [post] access to field boxfield [field Box1, field Elem] : Elem | G.cs:46:9:46:16 | [post] this access [field boxfield, field Box1, field Elem] : Elem | +| G.cs:46:9:46:16 | [post] this access [field boxfield, field Box1, field Elem] : Elem | G.cs:47:9:47:13 | this access [field boxfield, field Box1, field Elem] : Elem | +| G.cs:46:9:46:21 | [post] access to field Box1 [field Elem] : Elem | G.cs:46:9:46:16 | [post] access to field boxfield [field Box1, field Elem] : Elem | +| G.cs:46:30:46:30 | access to local variable e : Elem | G.cs:46:9:46:21 | [post] access to field Box1 [field Elem] : Elem | +| G.cs:47:9:47:13 | this access [field boxfield, field Box1, field Elem] : Elem | G.cs:50:18:50:20 | this [field boxfield, field Box1, field Elem] : Elem | +| G.cs:50:18:50:20 | this [field boxfield, field Box1, field Elem] : Elem | G.cs:52:14:52:21 | this access [field boxfield, field Box1, field Elem] : Elem | +| G.cs:52:14:52:21 | access to field boxfield [field Box1, field Elem] : Elem | G.cs:52:14:52:26 | access to field Box1 [field Elem] : Elem | +| G.cs:52:14:52:21 | this access [field boxfield, field Box1, field Elem] : Elem | G.cs:52:14:52:21 | access to field boxfield [field Box1, field Elem] : Elem | +| G.cs:52:14:52:26 | access to field Box1 [field Elem] : Elem | G.cs:52:14:52:31 | access to field Elem | +| H.cs:23:9:23:9 | [post] access to local variable a [field FieldA] : Object | H.cs:24:27:24:27 | access to local variable a [field FieldA] : Object | +| H.cs:23:20:23:31 | object creation of type Object : Object | H.cs:23:9:23:9 | [post] access to local variable a [field FieldA] : Object | +| H.cs:24:21:24:28 | call to method Clone [field FieldA] : Object | H.cs:25:14:25:18 | access to local variable clone [field FieldA] : Object | +| H.cs:24:27:24:27 | access to local variable a [field FieldA] : Object | H.cs:24:21:24:28 | call to method Clone [field FieldA] : Object | +| H.cs:25:14:25:18 | access to local variable clone [field FieldA] : Object | H.cs:25:14:25:25 | access to field FieldA | +| H.cs:43:9:43:9 | [post] access to local variable a [field FieldA] : Object | H.cs:44:27:44:27 | access to local variable a [field FieldA] : Object | +| H.cs:43:20:43:31 | object creation of type Object : Object | H.cs:43:9:43:9 | [post] access to local variable a [field FieldA] : Object | +| H.cs:44:17:44:28 | call to method Transform [field FieldB] : Object | H.cs:45:14:45:14 | access to local variable b [field FieldB] : Object | +| H.cs:44:27:44:27 | access to local variable a [field FieldA] : Object | H.cs:44:17:44:28 | call to method Transform [field FieldB] : Object | +| H.cs:45:14:45:14 | access to local variable b [field FieldB] : Object | H.cs:45:14:45:21 | access to field FieldB | +| H.cs:63:9:63:9 | [post] access to local variable a [field FieldA] : Object | H.cs:64:22:64:22 | access to local variable a [field FieldA] : Object | +| H.cs:63:20:63:31 | object creation of type Object : Object | H.cs:63:9:63:9 | [post] access to local variable a [field FieldA] : Object | +| H.cs:64:22:64:22 | access to local variable a [field FieldA] : Object | H.cs:64:25:64:26 | [post] access to local variable b1 [field FieldB] : Object | +| H.cs:64:25:64:26 | [post] access to local variable b1 [field FieldB] : Object | H.cs:65:14:65:15 | access to local variable b1 [field FieldB] : Object | +| H.cs:65:14:65:15 | access to local variable b1 [field FieldB] : Object | H.cs:65:14:65:22 | access to field FieldB | +| H.cs:88:17:88:17 | [post] access to local variable a [field FieldA] : Object | H.cs:89:14:89:14 | access to local variable a [field FieldA] : Object | +| H.cs:88:20:88:31 | object creation of type Object : Object | H.cs:88:17:88:17 | [post] access to local variable a [field FieldA] : Object | +| H.cs:88:20:88:31 | object creation of type Object : Object | H.cs:88:34:88:35 | [post] access to local variable b1 [field FieldB] : Object | +| H.cs:88:34:88:35 | [post] access to local variable b1 [field FieldB] : Object | H.cs:90:14:90:15 | access to local variable b1 [field FieldB] : Object | +| H.cs:89:14:89:14 | access to local variable a [field FieldA] : Object | H.cs:89:14:89:21 | access to field FieldA | +| H.cs:90:14:90:15 | access to local variable b1 [field FieldB] : Object | H.cs:90:14:90:22 | access to field FieldB | +| H.cs:112:9:112:9 | [post] access to local variable a [field FieldA] : Object | H.cs:113:31:113:31 | access to local variable a [field FieldA] : Object | +| H.cs:112:20:112:31 | object creation of type Object : Object | H.cs:112:9:112:9 | [post] access to local variable a [field FieldA] : Object | +| H.cs:113:17:113:32 | call to method TransformWrap [field FieldB] : Object | H.cs:114:14:114:14 | access to local variable b [field FieldB] : Object | +| H.cs:113:31:113:31 | access to local variable a [field FieldA] : Object | H.cs:113:17:113:32 | call to method TransformWrap [field FieldB] : Object | +| H.cs:114:14:114:14 | access to local variable b [field FieldB] : Object | H.cs:114:14:114:21 | access to field FieldB | +| H.cs:130:9:130:9 | [post] access to local variable a [field FieldA] : Object | H.cs:131:18:131:18 | access to local variable a [field FieldA] : Object | +| H.cs:130:20:130:31 | object creation of type Object : Object | H.cs:130:9:130:9 | [post] access to local variable a [field FieldA] : Object | +| H.cs:131:18:131:18 | access to local variable a [field FieldA] : Object | H.cs:131:14:131:19 | call to method Get | | H.cs:147:17:147:32 | call to method Through : A | H.cs:148:14:148:14 | access to local variable a | | H.cs:147:25:147:31 | object creation of type A : A | H.cs:147:17:147:32 | call to method Through : A | | H.cs:155:17:155:23 | object creation of type B : B | H.cs:156:9:156:9 | access to local variable b : B | | H.cs:156:9:156:9 | access to local variable b : B | H.cs:157:20:157:20 | access to local variable b : B | -| H.cs:157:9:157:9 | [post] access to parameter a [FieldA] : B | H.cs:164:19:164:19 | [post] access to local variable a [FieldA] : B | -| H.cs:157:20:157:20 | access to local variable b : B | H.cs:157:9:157:9 | [post] access to parameter a [FieldA] : B | +| H.cs:157:9:157:9 | [post] access to parameter a [field FieldA] : B | H.cs:164:19:164:19 | [post] access to local variable a [field FieldA] : B | +| H.cs:157:20:157:20 | access to local variable b : B | H.cs:157:9:157:9 | [post] access to parameter a [field FieldA] : B | | H.cs:163:17:163:28 | object creation of type Object : Object | H.cs:164:22:164:22 | access to local variable o : Object | -| H.cs:164:19:164:19 | [post] access to local variable a [FieldA, FieldB] : Object | H.cs:165:21:165:21 | access to local variable a [FieldA, FieldB] : Object | -| H.cs:164:19:164:19 | [post] access to local variable a [FieldA] : B | H.cs:165:21:165:21 | access to local variable a [FieldA] : B | -| H.cs:164:22:164:22 | access to local variable o : Object | H.cs:164:19:164:19 | [post] access to local variable a [FieldA, FieldB] : Object | +| H.cs:164:19:164:19 | [post] access to local variable a [field FieldA, field FieldB] : Object | H.cs:165:21:165:21 | access to local variable a [field FieldA, field FieldB] : Object | +| H.cs:164:19:164:19 | [post] access to local variable a [field FieldA] : B | H.cs:165:21:165:21 | access to local variable a [field FieldA] : B | +| H.cs:164:22:164:22 | access to local variable o : Object | H.cs:164:19:164:19 | [post] access to local variable a [field FieldA, field FieldB] : Object | | H.cs:165:17:165:28 | (...) ... : B | H.cs:166:14:166:14 | access to local variable b | -| H.cs:165:17:165:28 | (...) ... [FieldB] : Object | H.cs:167:14:167:14 | access to local variable b [FieldB] : Object | -| H.cs:165:21:165:21 | access to local variable a [FieldA, FieldB] : Object | H.cs:165:21:165:28 | access to field FieldA [FieldB] : Object | -| H.cs:165:21:165:21 | access to local variable a [FieldA] : B | H.cs:165:21:165:28 | access to field FieldA : B | +| H.cs:165:17:165:28 | (...) ... [field FieldB] : Object | H.cs:167:14:167:14 | access to local variable b [field FieldB] : Object | +| H.cs:165:21:165:21 | access to local variable a [field FieldA, field FieldB] : Object | H.cs:165:21:165:28 | access to field FieldA [field FieldB] : Object | +| H.cs:165:21:165:21 | access to local variable a [field FieldA] : B | H.cs:165:21:165:28 | access to field FieldA : B | | H.cs:165:21:165:28 | access to field FieldA : B | H.cs:165:17:165:28 | (...) ... : B | -| H.cs:165:21:165:28 | access to field FieldA [FieldB] : Object | H.cs:165:17:165:28 | (...) ... [FieldB] : Object | -| H.cs:167:14:167:14 | access to local variable b [FieldB] : Object | H.cs:167:14:167:21 | access to field FieldB | -| I.cs:7:9:7:14 | [post] this access [Field1] : Object | I.cs:21:13:21:19 | object creation of type I [Field1] : Object | -| I.cs:7:9:7:14 | [post] this access [Field1] : Object | I.cs:26:13:26:37 | [pre-initializer] object creation of type I [Field1] : Object | -| I.cs:7:18:7:29 | object creation of type Object : Object | I.cs:7:9:7:14 | [post] this access [Field1] : Object | +| H.cs:165:21:165:28 | access to field FieldA [field FieldB] : Object | H.cs:165:17:165:28 | (...) ... [field FieldB] : Object | +| H.cs:167:14:167:14 | access to local variable b [field FieldB] : Object | H.cs:167:14:167:21 | access to field FieldB | +| I.cs:7:9:7:14 | [post] this access [field Field1] : Object | I.cs:21:13:21:19 | object creation of type I [field Field1] : Object | +| I.cs:7:9:7:14 | [post] this access [field Field1] : Object | I.cs:26:13:26:37 | [pre-initializer] object creation of type I [field Field1] : Object | +| I.cs:7:18:7:29 | object creation of type Object : Object | I.cs:7:9:7:14 | [post] this access [field Field1] : Object | | I.cs:13:17:13:28 | object creation of type Object : Object | I.cs:15:20:15:20 | access to local variable o : Object | -| I.cs:15:9:15:9 | [post] access to local variable i [Field1] : Object | I.cs:16:9:16:9 | access to local variable i [Field1] : Object | -| I.cs:15:20:15:20 | access to local variable o : Object | I.cs:15:9:15:9 | [post] access to local variable i [Field1] : Object | -| I.cs:16:9:16:9 | access to local variable i [Field1] : Object | I.cs:17:9:17:9 | access to local variable i [Field1] : Object | -| I.cs:17:9:17:9 | access to local variable i [Field1] : Object | I.cs:18:14:18:14 | access to local variable i [Field1] : Object | -| I.cs:18:14:18:14 | access to local variable i [Field1] : Object | I.cs:18:14:18:21 | access to field Field1 | -| I.cs:21:13:21:19 | object creation of type I [Field1] : Object | I.cs:22:9:22:9 | access to local variable i [Field1] : Object | -| I.cs:22:9:22:9 | access to local variable i [Field1] : Object | I.cs:23:14:23:14 | access to local variable i [Field1] : Object | -| I.cs:23:14:23:14 | access to local variable i [Field1] : Object | I.cs:23:14:23:21 | access to field Field1 | -| I.cs:26:13:26:37 | [pre-initializer] object creation of type I [Field1] : Object | I.cs:27:14:27:14 | access to local variable i [Field1] : Object | -| I.cs:27:14:27:14 | access to local variable i [Field1] : Object | I.cs:27:14:27:21 | access to field Field1 | +| I.cs:15:9:15:9 | [post] access to local variable i [field Field1] : Object | I.cs:16:9:16:9 | access to local variable i [field Field1] : Object | +| I.cs:15:20:15:20 | access to local variable o : Object | I.cs:15:9:15:9 | [post] access to local variable i [field Field1] : Object | +| I.cs:16:9:16:9 | access to local variable i [field Field1] : Object | I.cs:17:9:17:9 | access to local variable i [field Field1] : Object | +| I.cs:17:9:17:9 | access to local variable i [field Field1] : Object | I.cs:18:14:18:14 | access to local variable i [field Field1] : Object | +| I.cs:18:14:18:14 | access to local variable i [field Field1] : Object | I.cs:18:14:18:21 | access to field Field1 | +| I.cs:21:13:21:19 | object creation of type I [field Field1] : Object | I.cs:22:9:22:9 | access to local variable i [field Field1] : Object | +| I.cs:22:9:22:9 | access to local variable i [field Field1] : Object | I.cs:23:14:23:14 | access to local variable i [field Field1] : Object | +| I.cs:23:14:23:14 | access to local variable i [field Field1] : Object | I.cs:23:14:23:21 | access to field Field1 | +| I.cs:26:13:26:37 | [pre-initializer] object creation of type I [field Field1] : Object | I.cs:27:14:27:14 | access to local variable i [field Field1] : Object | +| I.cs:27:14:27:14 | access to local variable i [field Field1] : Object | I.cs:27:14:27:21 | access to field Field1 | | I.cs:31:13:31:24 | object creation of type Object : Object | I.cs:32:20:32:20 | access to local variable o : Object | -| I.cs:32:9:32:9 | [post] access to local variable i [Field1] : Object | I.cs:33:9:33:9 | access to local variable i [Field1] : Object | -| I.cs:32:20:32:20 | access to local variable o : Object | I.cs:32:9:32:9 | [post] access to local variable i [Field1] : Object | -| I.cs:33:9:33:9 | access to local variable i [Field1] : Object | I.cs:34:12:34:12 | access to local variable i [Field1] : Object | -| I.cs:34:12:34:12 | access to local variable i [Field1] : Object | I.cs:37:23:37:23 | i [Field1] : Object | -| I.cs:37:23:37:23 | i [Field1] : Object | I.cs:39:9:39:9 | access to parameter i [Field1] : Object | -| I.cs:39:9:39:9 | access to parameter i [Field1] : Object | I.cs:40:14:40:14 | access to parameter i [Field1] : Object | -| I.cs:40:14:40:14 | access to parameter i [Field1] : Object | I.cs:40:14:40:21 | access to field Field1 | +| I.cs:32:9:32:9 | [post] access to local variable i [field Field1] : Object | I.cs:33:9:33:9 | access to local variable i [field Field1] : Object | +| I.cs:32:20:32:20 | access to local variable o : Object | I.cs:32:9:32:9 | [post] access to local variable i [field Field1] : Object | +| I.cs:33:9:33:9 | access to local variable i [field Field1] : Object | I.cs:34:12:34:12 | access to local variable i [field Field1] : Object | +| I.cs:34:12:34:12 | access to local variable i [field Field1] : Object | I.cs:37:23:37:23 | i [field Field1] : Object | +| I.cs:37:23:37:23 | i [field Field1] : Object | I.cs:39:9:39:9 | access to parameter i [field Field1] : Object | +| I.cs:39:9:39:9 | access to parameter i [field Field1] : Object | I.cs:40:14:40:14 | access to parameter i [field Field1] : Object | +| I.cs:40:14:40:14 | access to parameter i [field Field1] : Object | I.cs:40:14:40:21 | access to field Field1 | | J.cs:12:17:12:28 | object creation of type Object : Object | J.cs:13:29:13:29 | access to local variable o : Object | | J.cs:12:17:12:28 | object creation of type Object : Object | J.cs:21:36:21:36 | access to local variable o : Object | -| J.cs:13:18:13:36 | object creation of type Record [Prop1] : Object | J.cs:14:14:14:15 | access to local variable r1 [Prop1] : Object | -| J.cs:13:18:13:36 | object creation of type Record [Prop1] : Object | J.cs:18:14:18:15 | access to local variable r2 [Prop1] : Object | -| J.cs:13:18:13:36 | object creation of type Record [Prop1] : Object | J.cs:22:14:22:15 | access to local variable r3 [Prop1] : Object | -| J.cs:13:29:13:29 | access to local variable o : Object | J.cs:13:18:13:36 | object creation of type Record [Prop1] : Object | -| J.cs:14:14:14:15 | access to local variable r1 [Prop1] : Object | J.cs:14:14:14:21 | access to property Prop1 | -| J.cs:18:14:18:15 | access to local variable r2 [Prop1] : Object | J.cs:18:14:18:21 | access to property Prop1 | -| J.cs:21:18:21:38 | ... with { ... } [Prop2] : Object | J.cs:23:14:23:15 | access to local variable r3 [Prop2] : Object | -| J.cs:21:36:21:36 | access to local variable o : Object | J.cs:21:18:21:38 | ... with { ... } [Prop2] : Object | -| J.cs:22:14:22:15 | access to local variable r3 [Prop1] : Object | J.cs:22:14:22:21 | access to property Prop1 | -| J.cs:23:14:23:15 | access to local variable r3 [Prop2] : Object | J.cs:23:14:23:21 | access to property Prop2 | +| J.cs:13:18:13:36 | object creation of type Record [property Prop1] : Object | J.cs:14:14:14:15 | access to local variable r1 [property Prop1] : Object | +| J.cs:13:18:13:36 | object creation of type Record [property Prop1] : Object | J.cs:18:14:18:15 | access to local variable r2 [property Prop1] : Object | +| J.cs:13:18:13:36 | object creation of type Record [property Prop1] : Object | J.cs:22:14:22:15 | access to local variable r3 [property Prop1] : Object | +| J.cs:13:29:13:29 | access to local variable o : Object | J.cs:13:18:13:36 | object creation of type Record [property Prop1] : Object | +| J.cs:14:14:14:15 | access to local variable r1 [property Prop1] : Object | J.cs:14:14:14:21 | access to property Prop1 | +| J.cs:18:14:18:15 | access to local variable r2 [property Prop1] : Object | J.cs:18:14:18:21 | access to property Prop1 | +| J.cs:21:18:21:38 | ... with { ... } [property Prop2] : Object | J.cs:23:14:23:15 | access to local variable r3 [property Prop2] : Object | +| J.cs:21:36:21:36 | access to local variable o : Object | J.cs:21:18:21:38 | ... with { ... } [property Prop2] : Object | +| J.cs:22:14:22:15 | access to local variable r3 [property Prop1] : Object | J.cs:22:14:22:21 | access to property Prop1 | +| J.cs:23:14:23:15 | access to local variable r3 [property Prop2] : Object | J.cs:23:14:23:21 | access to property Prop2 | nodes | A.cs:5:17:5:23 | object creation of type C : C | semmle.label | object creation of type C : C | -| A.cs:6:17:6:25 | call to method Make [c] : C | semmle.label | call to method Make [c] : C | +| A.cs:6:17:6:25 | call to method Make [field c] : C | semmle.label | call to method Make [field c] : C | | A.cs:6:24:6:24 | access to local variable c : C | semmle.label | access to local variable c : C | -| A.cs:7:14:7:14 | access to local variable b [c] : C | semmle.label | access to local variable b [c] : C | +| A.cs:7:14:7:14 | access to local variable b [field c] : C | semmle.label | access to local variable b [field c] : C | | A.cs:7:14:7:16 | access to field c | semmle.label | access to field c | -| A.cs:13:9:13:9 | [post] access to local variable b [c] : C1 | semmle.label | [post] access to local variable b [c] : C1 | +| A.cs:13:9:13:9 | [post] access to local variable b [field c] : C1 | semmle.label | [post] access to local variable b [field c] : C1 | | A.cs:13:15:13:22 | object creation of type C1 : C1 | semmle.label | object creation of type C1 : C1 | -| A.cs:14:14:14:14 | access to local variable b [c] : C1 | semmle.label | access to local variable b [c] : C1 | +| A.cs:14:14:14:14 | access to local variable b [field c] : C1 | semmle.label | access to local variable b [field c] : C1 | | A.cs:14:14:14:20 | call to method Get | semmle.label | call to method Get | | A.cs:15:14:15:35 | call to method Get | semmle.label | call to method Get | -| A.cs:15:15:15:28 | object creation of type B [c] : C | semmle.label | object creation of type B [c] : C | +| A.cs:15:15:15:28 | object creation of type B [field c] : C | semmle.label | object creation of type B [field c] : C | | A.cs:15:21:15:27 | object creation of type C : C | semmle.label | object creation of type C : C | -| A.cs:22:14:22:33 | call to method SetOnB [c] : C2 | semmle.label | call to method SetOnB [c] : C2 | +| A.cs:22:14:22:33 | call to method SetOnB [field c] : C2 | semmle.label | call to method SetOnB [field c] : C2 | | A.cs:22:25:22:32 | object creation of type C2 : C2 | semmle.label | object creation of type C2 : C2 | -| A.cs:24:14:24:15 | access to local variable b2 [c] : C2 | semmle.label | access to local variable b2 [c] : C2 | +| A.cs:24:14:24:15 | access to local variable b2 [field c] : C2 | semmle.label | access to local variable b2 [field c] : C2 | | A.cs:24:14:24:17 | access to field c | semmle.label | access to field c | -| A.cs:31:14:31:37 | call to method SetOnBWrap [c] : C2 | semmle.label | call to method SetOnBWrap [c] : C2 | +| A.cs:31:14:31:37 | call to method SetOnBWrap [field c] : C2 | semmle.label | call to method SetOnBWrap [field c] : C2 | | A.cs:31:29:31:36 | object creation of type C2 : C2 | semmle.label | object creation of type C2 : C2 | -| A.cs:33:14:33:15 | access to local variable b2 [c] : C2 | semmle.label | access to local variable b2 [c] : C2 | +| A.cs:33:14:33:15 | access to local variable b2 [field c] : C2 | semmle.label | access to local variable b2 [field c] : C2 | | A.cs:33:14:33:17 | access to field c | semmle.label | access to field c | | A.cs:55:17:55:23 | object creation of type A : A | semmle.label | object creation of type A : A | -| A.cs:57:9:57:10 | [post] access to local variable c1 [a] : A | semmle.label | [post] access to local variable c1 [a] : A | +| A.cs:57:9:57:10 | [post] access to local variable c1 [field a] : A | semmle.label | [post] access to local variable c1 [field a] : A | | A.cs:57:16:57:16 | access to local variable a : A | semmle.label | access to local variable a : A | -| A.cs:58:12:58:13 | access to local variable c1 [a] : A | semmle.label | access to local variable c1 [a] : A | -| A.cs:60:22:60:22 | c [a] : A | semmle.label | c [a] : A | +| A.cs:58:12:58:13 | access to local variable c1 [field a] : A | semmle.label | access to local variable c1 [field a] : A | +| A.cs:60:22:60:22 | c [field a] : A | semmle.label | c [field a] : A | | A.cs:64:18:64:26 | access to field a | semmle.label | access to field a | -| A.cs:64:19:64:23 | (...) ... [a] : A | semmle.label | (...) ... [a] : A | -| A.cs:83:9:83:9 | [post] access to parameter b [c] : C | semmle.label | [post] access to parameter b [c] : C | +| A.cs:64:19:64:23 | (...) ... [field a] : A | semmle.label | (...) ... [field a] : A | +| A.cs:83:9:83:9 | [post] access to parameter b [field c] : C | semmle.label | [post] access to parameter b [field c] : C | | A.cs:83:15:83:21 | object creation of type C : C | semmle.label | object creation of type C : C | -| A.cs:88:12:88:12 | [post] access to local variable b [c] : C | semmle.label | [post] access to local variable b [c] : C | -| A.cs:89:14:89:14 | access to local variable b [c] : C | semmle.label | access to local variable b [c] : C | +| A.cs:88:12:88:12 | [post] access to local variable b [field c] : C | semmle.label | [post] access to local variable b [field c] : C | +| A.cs:89:14:89:14 | access to local variable b [field c] : C | semmle.label | access to local variable b [field c] : C | | A.cs:89:14:89:16 | access to field c | semmle.label | access to field c | -| A.cs:97:13:97:13 | [post] access to parameter b [c] : C | semmle.label | [post] access to parameter b [c] : C | +| A.cs:97:13:97:13 | [post] access to parameter b [field c] : C | semmle.label | [post] access to parameter b [field c] : C | | A.cs:97:19:97:25 | object creation of type C : C | semmle.label | object creation of type C : C | -| A.cs:98:13:98:16 | [post] this access [b, c] : C | semmle.label | [post] this access [b, c] : C | -| A.cs:98:13:98:16 | [post] this access [b] : B | semmle.label | [post] this access [b] : B | +| A.cs:98:13:98:16 | [post] this access [field b, field c] : C | semmle.label | [post] this access [field b, field c] : C | +| A.cs:98:13:98:16 | [post] this access [field b] : B | semmle.label | [post] this access [field b] : B | | A.cs:98:22:98:36 | ... ? ... : ... : B | semmle.label | ... ? ... : ... : B | -| A.cs:98:22:98:36 | ... ? ... : ... [c] : C | semmle.label | ... ? ... : ... [c] : C | +| A.cs:98:22:98:36 | ... ? ... : ... [field c] : C | semmle.label | ... ? ... : ... [field c] : C | | A.cs:98:30:98:36 | object creation of type B : B | semmle.label | object creation of type B : B | | A.cs:104:17:104:23 | object creation of type B : B | semmle.label | object creation of type B : B | -| A.cs:105:17:105:29 | object creation of type D [b, c] : C | semmle.label | object creation of type D [b, c] : C | -| A.cs:105:17:105:29 | object creation of type D [b] : B | semmle.label | object creation of type D [b] : B | -| A.cs:105:23:105:23 | [post] access to local variable b [c] : C | semmle.label | [post] access to local variable b [c] : C | +| A.cs:105:17:105:29 | object creation of type D [field b, field c] : C | semmle.label | object creation of type D [field b, field c] : C | +| A.cs:105:17:105:29 | object creation of type D [field b] : B | semmle.label | object creation of type D [field b] : B | +| A.cs:105:23:105:23 | [post] access to local variable b [field c] : C | semmle.label | [post] access to local variable b [field c] : C | | A.cs:105:23:105:23 | access to local variable b : B | semmle.label | access to local variable b : B | -| A.cs:106:14:106:14 | access to local variable d [b] : B | semmle.label | access to local variable d [b] : B | +| A.cs:106:14:106:14 | access to local variable d [field b] : B | semmle.label | access to local variable d [field b] : B | | A.cs:106:14:106:16 | access to field b | semmle.label | access to field b | -| A.cs:107:14:107:14 | access to local variable d [b, c] : C | semmle.label | access to local variable d [b, c] : C | -| A.cs:107:14:107:16 | access to field b [c] : C | semmle.label | access to field b [c] : C | +| A.cs:107:14:107:14 | access to local variable d [field b, field c] : C | semmle.label | access to local variable d [field b, field c] : C | +| A.cs:107:14:107:16 | access to field b [field c] : C | semmle.label | access to field b [field c] : C | | A.cs:107:14:107:18 | access to field c | semmle.label | access to field c | -| A.cs:108:14:108:14 | access to local variable b [c] : C | semmle.label | access to local variable b [c] : C | +| A.cs:108:14:108:14 | access to local variable b [field c] : C | semmle.label | access to local variable b [field c] : C | | A.cs:108:14:108:16 | access to field c | semmle.label | access to field c | | A.cs:113:17:113:23 | object creation of type B : B | semmle.label | object creation of type B : B | -| A.cs:114:18:114:54 | object creation of type MyList [head] : B | semmle.label | object creation of type MyList [head] : B | +| A.cs:114:18:114:54 | object creation of type MyList [field head] : B | semmle.label | object creation of type MyList [field head] : B | | A.cs:114:29:114:29 | access to local variable b : B | semmle.label | access to local variable b : B | -| A.cs:115:18:115:37 | object creation of type MyList [next, head] : B | semmle.label | object creation of type MyList [next, head] : B | -| A.cs:115:35:115:36 | access to local variable l1 [head] : B | semmle.label | access to local variable l1 [head] : B | -| A.cs:116:18:116:37 | object creation of type MyList [next, next, head] : B | semmle.label | object creation of type MyList [next, next, head] : B | -| A.cs:116:35:116:36 | access to local variable l2 [next, head] : B | semmle.label | access to local variable l2 [next, head] : B | -| A.cs:119:14:119:15 | access to local variable l3 [next, next, head] : B | semmle.label | access to local variable l3 [next, next, head] : B | -| A.cs:119:14:119:20 | access to field next [next, head] : B | semmle.label | access to field next [next, head] : B | -| A.cs:119:14:119:25 | access to field next [head] : B | semmle.label | access to field next [head] : B | +| A.cs:115:18:115:37 | object creation of type MyList [field next, field head] : B | semmle.label | object creation of type MyList [field next, field head] : B | +| A.cs:115:35:115:36 | access to local variable l1 [field head] : B | semmle.label | access to local variable l1 [field head] : B | +| A.cs:116:18:116:37 | object creation of type MyList [field next, field next, field head] : B | semmle.label | object creation of type MyList [field next, field next, field head] : B | +| A.cs:116:35:116:36 | access to local variable l2 [field next, field head] : B | semmle.label | access to local variable l2 [field next, field head] : B | +| A.cs:119:14:119:15 | access to local variable l3 [field next, field next, field head] : B | semmle.label | access to local variable l3 [field next, field next, field head] : B | +| A.cs:119:14:119:20 | access to field next [field next, field head] : B | semmle.label | access to field next [field next, field head] : B | +| A.cs:119:14:119:25 | access to field next [field head] : B | semmle.label | access to field next [field head] : B | | A.cs:119:14:119:30 | access to field head | semmle.label | access to field head | -| A.cs:121:41:121:41 | access to local variable l [next, head] : B | semmle.label | access to local variable l [next, head] : B | -| A.cs:121:41:121:41 | access to local variable l [next, next, head] : B | semmle.label | access to local variable l [next, next, head] : B | -| A.cs:121:41:121:46 | access to field next [head] : B | semmle.label | access to field next [head] : B | -| A.cs:121:41:121:46 | access to field next [next, head] : B | semmle.label | access to field next [next, head] : B | -| A.cs:123:18:123:18 | access to local variable l [head] : B | semmle.label | access to local variable l [head] : B | +| A.cs:121:41:121:41 | access to local variable l [field next, field head] : B | semmle.label | access to local variable l [field next, field head] : B | +| A.cs:121:41:121:41 | access to local variable l [field next, field next, field head] : B | semmle.label | access to local variable l [field next, field next, field head] : B | +| A.cs:121:41:121:46 | access to field next [field head] : B | semmle.label | access to field next [field head] : B | +| A.cs:121:41:121:46 | access to field next [field next, field head] : B | semmle.label | access to field next [field next, field head] : B | +| A.cs:123:18:123:18 | access to local variable l [field head] : B | semmle.label | access to local variable l [field head] : B | | A.cs:123:18:123:23 | access to field head | semmle.label | access to field head | | B.cs:5:17:5:26 | object creation of type Elem : Elem | semmle.label | object creation of type Elem : Elem | -| B.cs:6:18:6:34 | object creation of type Box1 [elem1] : Elem | semmle.label | object creation of type Box1 [elem1] : Elem | +| B.cs:6:18:6:34 | object creation of type Box1 [field elem1] : Elem | semmle.label | object creation of type Box1 [field elem1] : Elem | | B.cs:6:27:6:27 | access to local variable e : Elem | semmle.label | access to local variable e : Elem | -| B.cs:7:18:7:29 | object creation of type Box2 [box1, elem1] : Elem | semmle.label | object creation of type Box2 [box1, elem1] : Elem | -| B.cs:7:27:7:28 | access to local variable b1 [elem1] : Elem | semmle.label | access to local variable b1 [elem1] : Elem | -| B.cs:8:14:8:15 | access to local variable b2 [box1, elem1] : Elem | semmle.label | access to local variable b2 [box1, elem1] : Elem | -| B.cs:8:14:8:20 | access to field box1 [elem1] : Elem | semmle.label | access to field box1 [elem1] : Elem | +| B.cs:7:18:7:29 | object creation of type Box2 [field box1, field elem1] : Elem | semmle.label | object creation of type Box2 [field box1, field elem1] : Elem | +| B.cs:7:27:7:28 | access to local variable b1 [field elem1] : Elem | semmle.label | access to local variable b1 [field elem1] : Elem | +| B.cs:8:14:8:15 | access to local variable b2 [field box1, field elem1] : Elem | semmle.label | access to local variable b2 [field box1, field elem1] : Elem | +| B.cs:8:14:8:20 | access to field box1 [field elem1] : Elem | semmle.label | access to field box1 [field elem1] : Elem | | B.cs:8:14:8:26 | access to field elem1 | semmle.label | access to field elem1 | | B.cs:14:17:14:26 | object creation of type Elem : Elem | semmle.label | object creation of type Elem : Elem | -| B.cs:15:18:15:34 | object creation of type Box1 [elem2] : Elem | semmle.label | object creation of type Box1 [elem2] : Elem | +| B.cs:15:18:15:34 | object creation of type Box1 [field elem2] : Elem | semmle.label | object creation of type Box1 [field elem2] : Elem | | B.cs:15:33:15:33 | access to local variable e : Elem | semmle.label | access to local variable e : Elem | -| B.cs:16:18:16:29 | object creation of type Box2 [box1, elem2] : Elem | semmle.label | object creation of type Box2 [box1, elem2] : Elem | -| B.cs:16:27:16:28 | access to local variable b1 [elem2] : Elem | semmle.label | access to local variable b1 [elem2] : Elem | -| B.cs:18:14:18:15 | access to local variable b2 [box1, elem2] : Elem | semmle.label | access to local variable b2 [box1, elem2] : Elem | -| B.cs:18:14:18:20 | access to field box1 [elem2] : Elem | semmle.label | access to field box1 [elem2] : Elem | +| B.cs:16:18:16:29 | object creation of type Box2 [field box1, field elem2] : Elem | semmle.label | object creation of type Box2 [field box1, field elem2] : Elem | +| B.cs:16:27:16:28 | access to local variable b1 [field elem2] : Elem | semmle.label | access to local variable b1 [field elem2] : Elem | +| B.cs:18:14:18:15 | access to local variable b2 [field box1, field elem2] : Elem | semmle.label | access to local variable b2 [field box1, field elem2] : Elem | +| B.cs:18:14:18:20 | access to field box1 [field elem2] : Elem | semmle.label | access to field box1 [field elem2] : Elem | | B.cs:18:14:18:26 | access to field elem2 | semmle.label | access to field elem2 | -| C.cs:3:18:3:19 | [post] this access [s1] : Elem | semmle.label | [post] this access [s1] : Elem | +| C.cs:3:18:3:19 | [post] this access [field s1] : Elem | semmle.label | [post] this access [field s1] : Elem | | C.cs:3:23:3:32 | object creation of type Elem : Elem | semmle.label | object creation of type Elem : Elem | -| C.cs:4:27:4:28 | [post] this access [s2] : Elem | semmle.label | [post] this access [s2] : Elem | +| C.cs:4:27:4:28 | [post] this access [field s2] : Elem | semmle.label | [post] this access [field s2] : Elem | | C.cs:4:32:4:41 | object creation of type Elem : Elem | semmle.label | object creation of type Elem : Elem | | C.cs:6:30:6:39 | object creation of type Elem : Elem | semmle.label | object creation of type Elem : Elem | -| C.cs:7:18:7:19 | [post] this access [s5] : Elem | semmle.label | [post] this access [s5] : Elem | +| C.cs:7:18:7:19 | [post] this access [property s5] : Elem | semmle.label | [post] this access [property s5] : Elem | | C.cs:7:37:7:46 | object creation of type Elem : Elem | semmle.label | object creation of type Elem : Elem | | C.cs:8:30:8:39 | object creation of type Elem : Elem | semmle.label | object creation of type Elem : Elem | -| C.cs:12:15:12:21 | object creation of type C [s1] : Elem | semmle.label | object creation of type C [s1] : Elem | -| C.cs:12:15:12:21 | object creation of type C [s2] : Elem | semmle.label | object creation of type C [s2] : Elem | -| C.cs:12:15:12:21 | object creation of type C [s3] : Elem | semmle.label | object creation of type C [s3] : Elem | -| C.cs:12:15:12:21 | object creation of type C [s5] : Elem | semmle.label | object creation of type C [s5] : Elem | -| C.cs:13:9:13:9 | access to local variable c [s1] : Elem | semmle.label | access to local variable c [s1] : Elem | -| C.cs:13:9:13:9 | access to local variable c [s2] : Elem | semmle.label | access to local variable c [s2] : Elem | -| C.cs:13:9:13:9 | access to local variable c [s3] : Elem | semmle.label | access to local variable c [s3] : Elem | -| C.cs:13:9:13:9 | access to local variable c [s5] : Elem | semmle.label | access to local variable c [s5] : Elem | -| C.cs:18:9:18:12 | [post] this access [s3] : Elem | semmle.label | [post] this access [s3] : Elem | +| C.cs:12:15:12:21 | object creation of type C [field s1] : Elem | semmle.label | object creation of type C [field s1] : Elem | +| C.cs:12:15:12:21 | object creation of type C [field s2] : Elem | semmle.label | object creation of type C [field s2] : Elem | +| C.cs:12:15:12:21 | object creation of type C [field s3] : Elem | semmle.label | object creation of type C [field s3] : Elem | +| C.cs:12:15:12:21 | object creation of type C [property s5] : Elem | semmle.label | object creation of type C [property s5] : Elem | +| C.cs:13:9:13:9 | access to local variable c [field s1] : Elem | semmle.label | access to local variable c [field s1] : Elem | +| C.cs:13:9:13:9 | access to local variable c [field s2] : Elem | semmle.label | access to local variable c [field s2] : Elem | +| C.cs:13:9:13:9 | access to local variable c [field s3] : Elem | semmle.label | access to local variable c [field s3] : Elem | +| C.cs:13:9:13:9 | access to local variable c [property s5] : Elem | semmle.label | access to local variable c [property s5] : Elem | +| C.cs:18:9:18:12 | [post] this access [field s3] : Elem | semmle.label | [post] this access [field s3] : Elem | | C.cs:18:19:18:28 | object creation of type Elem : Elem | semmle.label | object creation of type Elem : Elem | -| C.cs:21:17:21:18 | this [s1] : Elem | semmle.label | this [s1] : Elem | -| C.cs:21:17:21:18 | this [s2] : Elem | semmle.label | this [s2] : Elem | -| C.cs:21:17:21:18 | this [s3] : Elem | semmle.label | this [s3] : Elem | -| C.cs:21:17:21:18 | this [s5] : Elem | semmle.label | this [s5] : Elem | +| C.cs:21:17:21:18 | this [field s1] : Elem | semmle.label | this [field s1] : Elem | +| C.cs:21:17:21:18 | this [field s2] : Elem | semmle.label | this [field s2] : Elem | +| C.cs:21:17:21:18 | this [field s3] : Elem | semmle.label | this [field s3] : Elem | +| C.cs:21:17:21:18 | this [property s5] : Elem | semmle.label | this [property s5] : Elem | | C.cs:23:14:23:15 | access to field s1 | semmle.label | access to field s1 | -| C.cs:23:14:23:15 | this access [s1] : Elem | semmle.label | this access [s1] : Elem | +| C.cs:23:14:23:15 | this access [field s1] : Elem | semmle.label | this access [field s1] : Elem | | C.cs:24:14:24:15 | access to field s2 | semmle.label | access to field s2 | -| C.cs:24:14:24:15 | this access [s2] : Elem | semmle.label | this access [s2] : Elem | +| C.cs:24:14:24:15 | this access [field s2] : Elem | semmle.label | this access [field s2] : Elem | | C.cs:25:14:25:15 | access to field s3 | semmle.label | access to field s3 | -| C.cs:25:14:25:15 | this access [s3] : Elem | semmle.label | this access [s3] : Elem | +| C.cs:25:14:25:15 | this access [field s3] : Elem | semmle.label | this access [field s3] : Elem | | C.cs:26:14:26:15 | access to field s4 | semmle.label | access to field s4 | | C.cs:27:14:27:15 | access to property s5 | semmle.label | access to property s5 | -| C.cs:27:14:27:15 | this access [s5] : Elem | semmle.label | this access [s5] : Elem | +| C.cs:27:14:27:15 | this access [property s5] : Elem | semmle.label | this access [property s5] : Elem | | C.cs:28:14:28:15 | access to property s6 | semmle.label | access to property s6 | | D.cs:29:17:29:28 | object creation of type Object : Object | semmle.label | object creation of type Object : Object | -| D.cs:31:17:31:37 | call to method Create [AutoProp] : Object | semmle.label | call to method Create [AutoProp] : Object | +| D.cs:31:17:31:37 | call to method Create [property AutoProp] : Object | semmle.label | call to method Create [property AutoProp] : Object | | D.cs:31:24:31:24 | access to local variable o : Object | semmle.label | access to local variable o : Object | -| D.cs:32:14:32:14 | access to local variable d [AutoProp] : Object | semmle.label | access to local variable d [AutoProp] : Object | +| D.cs:32:14:32:14 | access to local variable d [property AutoProp] : Object | semmle.label | access to local variable d [property AutoProp] : Object | | D.cs:32:14:32:23 | access to property AutoProp | semmle.label | access to property AutoProp | -| D.cs:37:13:37:33 | call to method Create [trivialPropField] : Object | semmle.label | call to method Create [trivialPropField] : Object | +| D.cs:37:13:37:33 | call to method Create [field trivialPropField] : Object | semmle.label | call to method Create [field trivialPropField] : Object | | D.cs:37:26:37:26 | access to local variable o : Object | semmle.label | access to local variable o : Object | -| D.cs:39:14:39:14 | access to local variable d [trivialPropField] : Object | semmle.label | access to local variable d [trivialPropField] : Object | +| D.cs:39:14:39:14 | access to local variable d [field trivialPropField] : Object | semmle.label | access to local variable d [field trivialPropField] : Object | | D.cs:39:14:39:26 | access to property TrivialProp | semmle.label | access to property TrivialProp | -| D.cs:40:14:40:14 | access to local variable d [trivialPropField] : Object | semmle.label | access to local variable d [trivialPropField] : Object | +| D.cs:40:14:40:14 | access to local variable d [field trivialPropField] : Object | semmle.label | access to local variable d [field trivialPropField] : Object | | D.cs:40:14:40:31 | access to field trivialPropField | semmle.label | access to field trivialPropField | -| D.cs:41:14:41:14 | access to local variable d [trivialPropField] : Object | semmle.label | access to local variable d [trivialPropField] : Object | +| D.cs:41:14:41:14 | access to local variable d [field trivialPropField] : Object | semmle.label | access to local variable d [field trivialPropField] : Object | | D.cs:41:14:41:26 | access to property ComplexProp | semmle.label | access to property ComplexProp | -| D.cs:43:13:43:33 | call to method Create [trivialPropField] : Object | semmle.label | call to method Create [trivialPropField] : Object | +| D.cs:43:13:43:33 | call to method Create [field trivialPropField] : Object | semmle.label | call to method Create [field trivialPropField] : Object | | D.cs:43:32:43:32 | access to local variable o : Object | semmle.label | access to local variable o : Object | -| D.cs:45:14:45:14 | access to local variable d [trivialPropField] : Object | semmle.label | access to local variable d [trivialPropField] : Object | +| D.cs:45:14:45:14 | access to local variable d [field trivialPropField] : Object | semmle.label | access to local variable d [field trivialPropField] : Object | | D.cs:45:14:45:26 | access to property TrivialProp | semmle.label | access to property TrivialProp | -| D.cs:46:14:46:14 | access to local variable d [trivialPropField] : Object | semmle.label | access to local variable d [trivialPropField] : Object | +| D.cs:46:14:46:14 | access to local variable d [field trivialPropField] : Object | semmle.label | access to local variable d [field trivialPropField] : Object | | D.cs:46:14:46:31 | access to field trivialPropField | semmle.label | access to field trivialPropField | -| D.cs:47:14:47:14 | access to local variable d [trivialPropField] : Object | semmle.label | access to local variable d [trivialPropField] : Object | +| D.cs:47:14:47:14 | access to local variable d [field trivialPropField] : Object | semmle.label | access to local variable d [field trivialPropField] : Object | | D.cs:47:14:47:26 | access to property ComplexProp | semmle.label | access to property ComplexProp | | E.cs:22:17:22:28 | object creation of type Object : Object | semmle.label | object creation of type Object : Object | -| E.cs:23:17:23:26 | call to method CreateS [Field] : Object | semmle.label | call to method CreateS [Field] : Object | +| E.cs:23:17:23:26 | call to method CreateS [field Field] : Object | semmle.label | call to method CreateS [field Field] : Object | | E.cs:23:25:23:25 | access to local variable o : Object | semmle.label | access to local variable o : Object | -| E.cs:24:14:24:14 | access to local variable s [Field] : Object | semmle.label | access to local variable s [Field] : Object | +| E.cs:24:14:24:14 | access to local variable s [field Field] : Object | semmle.label | access to local variable s [field Field] : Object | | E.cs:24:14:24:20 | access to field Field | semmle.label | access to field Field | | F.cs:10:17:10:28 | object creation of type Object : Object | semmle.label | object creation of type Object : Object | -| F.cs:11:17:11:31 | call to method Create [Field1] : Object | semmle.label | call to method Create [Field1] : Object | +| F.cs:11:17:11:31 | call to method Create [field Field1] : Object | semmle.label | call to method Create [field Field1] : Object | | F.cs:11:24:11:24 | access to local variable o : Object | semmle.label | access to local variable o : Object | -| F.cs:12:14:12:14 | access to local variable f [Field1] : Object | semmle.label | access to local variable f [Field1] : Object | +| F.cs:12:14:12:14 | access to local variable f [field Field1] : Object | semmle.label | access to local variable f [field Field1] : Object | | F.cs:12:14:12:21 | access to field Field1 | semmle.label | access to field Field1 | -| F.cs:15:13:15:27 | call to method Create [Field2] : Object | semmle.label | call to method Create [Field2] : Object | +| F.cs:15:13:15:27 | call to method Create [field Field2] : Object | semmle.label | call to method Create [field Field2] : Object | | F.cs:15:26:15:26 | access to local variable o : Object | semmle.label | access to local variable o : Object | -| F.cs:17:14:17:14 | access to local variable f [Field2] : Object | semmle.label | access to local variable f [Field2] : Object | +| F.cs:17:14:17:14 | access to local variable f [field Field2] : Object | semmle.label | access to local variable f [field Field2] : Object | | F.cs:17:14:17:21 | access to field Field2 | semmle.label | access to field Field2 | -| F.cs:19:21:19:34 | { ..., ... } [Field1] : Object | semmle.label | { ..., ... } [Field1] : Object | +| F.cs:19:21:19:34 | { ..., ... } [field Field1] : Object | semmle.label | { ..., ... } [field Field1] : Object | | F.cs:19:32:19:32 | access to local variable o : Object | semmle.label | access to local variable o : Object | -| F.cs:20:14:20:14 | access to local variable f [Field1] : Object | semmle.label | access to local variable f [Field1] : Object | +| F.cs:20:14:20:14 | access to local variable f [field Field1] : Object | semmle.label | access to local variable f [field Field1] : Object | | F.cs:20:14:20:21 | access to field Field1 | semmle.label | access to field Field1 | -| F.cs:23:21:23:34 | { ..., ... } [Field2] : Object | semmle.label | { ..., ... } [Field2] : Object | +| F.cs:23:21:23:34 | { ..., ... } [field Field2] : Object | semmle.label | { ..., ... } [field Field2] : Object | | F.cs:23:32:23:32 | access to local variable o : Object | semmle.label | access to local variable o : Object | -| F.cs:25:14:25:14 | access to local variable f [Field2] : Object | semmle.label | access to local variable f [Field2] : Object | +| F.cs:25:14:25:14 | access to local variable f [field Field2] : Object | semmle.label | access to local variable f [field Field2] : Object | | F.cs:25:14:25:21 | access to field Field2 | semmle.label | access to field Field2 | | G.cs:7:18:7:27 | object creation of type Elem : Elem | semmle.label | object creation of type Elem : Elem | -| G.cs:9:9:9:9 | [post] access to local variable b [Box1, Elem] : Elem | semmle.label | [post] access to local variable b [Box1, Elem] : Elem | -| G.cs:9:9:9:14 | [post] access to field Box1 [Elem] : Elem | semmle.label | [post] access to field Box1 [Elem] : Elem | +| G.cs:9:9:9:9 | [post] access to local variable b [field Box1, field Elem] : Elem | semmle.label | [post] access to local variable b [field Box1, field Elem] : Elem | +| G.cs:9:9:9:14 | [post] access to field Box1 [field Elem] : Elem | semmle.label | [post] access to field Box1 [field Elem] : Elem | | G.cs:9:23:9:23 | access to local variable e : Elem | semmle.label | access to local variable e : Elem | -| G.cs:10:18:10:18 | access to local variable b [Box1, Elem] : Elem | semmle.label | access to local variable b [Box1, Elem] : Elem | +| G.cs:10:18:10:18 | access to local variable b [field Box1, field Elem] : Elem | semmle.label | access to local variable b [field Box1, field Elem] : Elem | | G.cs:15:18:15:27 | object creation of type Elem : Elem | semmle.label | object creation of type Elem : Elem | -| G.cs:17:9:17:9 | [post] access to local variable b [Box1, Elem] : Elem | semmle.label | [post] access to local variable b [Box1, Elem] : Elem | -| G.cs:17:9:17:14 | [post] access to field Box1 [Elem] : Elem | semmle.label | [post] access to field Box1 [Elem] : Elem | +| G.cs:17:9:17:9 | [post] access to local variable b [field Box1, field Elem] : Elem | semmle.label | [post] access to local variable b [field Box1, field Elem] : Elem | +| G.cs:17:9:17:14 | [post] access to field Box1 [field Elem] : Elem | semmle.label | [post] access to field Box1 [field Elem] : Elem | | G.cs:17:24:17:24 | access to local variable e : Elem | semmle.label | access to local variable e : Elem | -| G.cs:18:18:18:18 | access to local variable b [Box1, Elem] : Elem | semmle.label | access to local variable b [Box1, Elem] : Elem | +| G.cs:18:18:18:18 | access to local variable b [field Box1, field Elem] : Elem | semmle.label | access to local variable b [field Box1, field Elem] : Elem | | G.cs:23:18:23:27 | object creation of type Elem : Elem | semmle.label | object creation of type Elem : Elem | -| G.cs:25:9:25:9 | [post] access to local variable b [Box1, Elem] : Elem | semmle.label | [post] access to local variable b [Box1, Elem] : Elem | -| G.cs:25:9:25:19 | [post] call to method GetBox1 [Elem] : Elem | semmle.label | [post] call to method GetBox1 [Elem] : Elem | +| G.cs:25:9:25:9 | [post] access to local variable b [field Box1, field Elem] : Elem | semmle.label | [post] access to local variable b [field Box1, field Elem] : Elem | +| G.cs:25:9:25:19 | [post] call to method GetBox1 [field Elem] : Elem | semmle.label | [post] call to method GetBox1 [field Elem] : Elem | | G.cs:25:28:25:28 | access to local variable e : Elem | semmle.label | access to local variable e : Elem | -| G.cs:26:18:26:18 | access to local variable b [Box1, Elem] : Elem | semmle.label | access to local variable b [Box1, Elem] : Elem | +| G.cs:26:18:26:18 | access to local variable b [field Box1, field Elem] : Elem | semmle.label | access to local variable b [field Box1, field Elem] : Elem | | G.cs:31:18:31:27 | object creation of type Elem : Elem | semmle.label | object creation of type Elem : Elem | -| G.cs:33:9:33:9 | [post] access to local variable b [Box1, Elem] : Elem | semmle.label | [post] access to local variable b [Box1, Elem] : Elem | -| G.cs:33:9:33:19 | [post] call to method GetBox1 [Elem] : Elem | semmle.label | [post] call to method GetBox1 [Elem] : Elem | +| G.cs:33:9:33:9 | [post] access to local variable b [field Box1, field Elem] : Elem | semmle.label | [post] access to local variable b [field Box1, field Elem] : Elem | +| G.cs:33:9:33:19 | [post] call to method GetBox1 [field Elem] : Elem | semmle.label | [post] call to method GetBox1 [field Elem] : Elem | | G.cs:33:29:33:29 | access to local variable e : Elem | semmle.label | access to local variable e : Elem | -| G.cs:34:18:34:18 | access to local variable b [Box1, Elem] : Elem | semmle.label | access to local variable b [Box1, Elem] : Elem | -| G.cs:37:38:37:39 | b2 [Box1, Elem] : Elem | semmle.label | b2 [Box1, Elem] : Elem | -| G.cs:39:14:39:15 | access to parameter b2 [Box1, Elem] : Elem | semmle.label | access to parameter b2 [Box1, Elem] : Elem | -| G.cs:39:14:39:25 | call to method GetBox1 [Elem] : Elem | semmle.label | call to method GetBox1 [Elem] : Elem | +| G.cs:34:18:34:18 | access to local variable b [field Box1, field Elem] : Elem | semmle.label | access to local variable b [field Box1, field Elem] : Elem | +| G.cs:37:38:37:39 | b2 [field Box1, field Elem] : Elem | semmle.label | b2 [field Box1, field Elem] : Elem | +| G.cs:39:14:39:15 | access to parameter b2 [field Box1, field Elem] : Elem | semmle.label | access to parameter b2 [field Box1, field Elem] : Elem | +| G.cs:39:14:39:25 | call to method GetBox1 [field Elem] : Elem | semmle.label | call to method GetBox1 [field Elem] : Elem | | G.cs:39:14:39:35 | call to method GetElem | semmle.label | call to method GetElem | | G.cs:44:18:44:27 | object creation of type Elem : Elem | semmle.label | object creation of type Elem : Elem | -| G.cs:46:9:46:16 | [post] access to field boxfield [Box1, Elem] : Elem | semmle.label | [post] access to field boxfield [Box1, Elem] : Elem | -| G.cs:46:9:46:16 | [post] this access [boxfield, Box1, Elem] : Elem | semmle.label | [post] this access [boxfield, Box1, Elem] : Elem | -| G.cs:46:9:46:21 | [post] access to field Box1 [Elem] : Elem | semmle.label | [post] access to field Box1 [Elem] : Elem | +| G.cs:46:9:46:16 | [post] access to field boxfield [field Box1, field Elem] : Elem | semmle.label | [post] access to field boxfield [field Box1, field Elem] : Elem | +| G.cs:46:9:46:16 | [post] this access [field boxfield, field Box1, field Elem] : Elem | semmle.label | [post] this access [field boxfield, field Box1, field Elem] : Elem | +| G.cs:46:9:46:21 | [post] access to field Box1 [field Elem] : Elem | semmle.label | [post] access to field Box1 [field Elem] : Elem | | G.cs:46:30:46:30 | access to local variable e : Elem | semmle.label | access to local variable e : Elem | -| G.cs:47:9:47:13 | this access [boxfield, Box1, Elem] : Elem | semmle.label | this access [boxfield, Box1, Elem] : Elem | -| G.cs:50:18:50:20 | this [boxfield, Box1, Elem] : Elem | semmle.label | this [boxfield, Box1, Elem] : Elem | -| G.cs:52:14:52:21 | access to field boxfield [Box1, Elem] : Elem | semmle.label | access to field boxfield [Box1, Elem] : Elem | -| G.cs:52:14:52:21 | this access [boxfield, Box1, Elem] : Elem | semmle.label | this access [boxfield, Box1, Elem] : Elem | -| G.cs:52:14:52:26 | access to field Box1 [Elem] : Elem | semmle.label | access to field Box1 [Elem] : Elem | +| G.cs:47:9:47:13 | this access [field boxfield, field Box1, field Elem] : Elem | semmle.label | this access [field boxfield, field Box1, field Elem] : Elem | +| G.cs:50:18:50:20 | this [field boxfield, field Box1, field Elem] : Elem | semmle.label | this [field boxfield, field Box1, field Elem] : Elem | +| G.cs:52:14:52:21 | access to field boxfield [field Box1, field Elem] : Elem | semmle.label | access to field boxfield [field Box1, field Elem] : Elem | +| G.cs:52:14:52:21 | this access [field boxfield, field Box1, field Elem] : Elem | semmle.label | this access [field boxfield, field Box1, field Elem] : Elem | +| G.cs:52:14:52:26 | access to field Box1 [field Elem] : Elem | semmle.label | access to field Box1 [field Elem] : Elem | | G.cs:52:14:52:31 | access to field Elem | semmle.label | access to field Elem | -| H.cs:23:9:23:9 | [post] access to local variable a [FieldA] : Object | semmle.label | [post] access to local variable a [FieldA] : Object | +| H.cs:23:9:23:9 | [post] access to local variable a [field FieldA] : Object | semmle.label | [post] access to local variable a [field FieldA] : Object | | H.cs:23:20:23:31 | object creation of type Object : Object | semmle.label | object creation of type Object : Object | -| H.cs:24:21:24:28 | call to method Clone [FieldA] : Object | semmle.label | call to method Clone [FieldA] : Object | -| H.cs:24:27:24:27 | access to local variable a [FieldA] : Object | semmle.label | access to local variable a [FieldA] : Object | -| H.cs:25:14:25:18 | access to local variable clone [FieldA] : Object | semmle.label | access to local variable clone [FieldA] : Object | +| H.cs:24:21:24:28 | call to method Clone [field FieldA] : Object | semmle.label | call to method Clone [field FieldA] : Object | +| H.cs:24:27:24:27 | access to local variable a [field FieldA] : Object | semmle.label | access to local variable a [field FieldA] : Object | +| H.cs:25:14:25:18 | access to local variable clone [field FieldA] : Object | semmle.label | access to local variable clone [field FieldA] : Object | | H.cs:25:14:25:25 | access to field FieldA | semmle.label | access to field FieldA | -| H.cs:43:9:43:9 | [post] access to local variable a [FieldA] : Object | semmle.label | [post] access to local variable a [FieldA] : Object | +| H.cs:43:9:43:9 | [post] access to local variable a [field FieldA] : Object | semmle.label | [post] access to local variable a [field FieldA] : Object | | H.cs:43:20:43:31 | object creation of type Object : Object | semmle.label | object creation of type Object : Object | -| H.cs:44:17:44:28 | call to method Transform [FieldB] : Object | semmle.label | call to method Transform [FieldB] : Object | -| H.cs:44:27:44:27 | access to local variable a [FieldA] : Object | semmle.label | access to local variable a [FieldA] : Object | -| H.cs:45:14:45:14 | access to local variable b [FieldB] : Object | semmle.label | access to local variable b [FieldB] : Object | +| H.cs:44:17:44:28 | call to method Transform [field FieldB] : Object | semmle.label | call to method Transform [field FieldB] : Object | +| H.cs:44:27:44:27 | access to local variable a [field FieldA] : Object | semmle.label | access to local variable a [field FieldA] : Object | +| H.cs:45:14:45:14 | access to local variable b [field FieldB] : Object | semmle.label | access to local variable b [field FieldB] : Object | | H.cs:45:14:45:21 | access to field FieldB | semmle.label | access to field FieldB | -| H.cs:63:9:63:9 | [post] access to local variable a [FieldA] : Object | semmle.label | [post] access to local variable a [FieldA] : Object | +| H.cs:63:9:63:9 | [post] access to local variable a [field FieldA] : Object | semmle.label | [post] access to local variable a [field FieldA] : Object | | H.cs:63:20:63:31 | object creation of type Object : Object | semmle.label | object creation of type Object : Object | -| H.cs:64:22:64:22 | access to local variable a [FieldA] : Object | semmle.label | access to local variable a [FieldA] : Object | -| H.cs:64:25:64:26 | [post] access to local variable b1 [FieldB] : Object | semmle.label | [post] access to local variable b1 [FieldB] : Object | -| H.cs:65:14:65:15 | access to local variable b1 [FieldB] : Object | semmle.label | access to local variable b1 [FieldB] : Object | +| H.cs:64:22:64:22 | access to local variable a [field FieldA] : Object | semmle.label | access to local variable a [field FieldA] : Object | +| H.cs:64:25:64:26 | [post] access to local variable b1 [field FieldB] : Object | semmle.label | [post] access to local variable b1 [field FieldB] : Object | +| H.cs:65:14:65:15 | access to local variable b1 [field FieldB] : Object | semmle.label | access to local variable b1 [field FieldB] : Object | | H.cs:65:14:65:22 | access to field FieldB | semmle.label | access to field FieldB | -| H.cs:88:17:88:17 | [post] access to local variable a [FieldA] : Object | semmle.label | [post] access to local variable a [FieldA] : Object | +| H.cs:88:17:88:17 | [post] access to local variable a [field FieldA] : Object | semmle.label | [post] access to local variable a [field FieldA] : Object | | H.cs:88:20:88:31 | object creation of type Object : Object | semmle.label | object creation of type Object : Object | -| H.cs:88:34:88:35 | [post] access to local variable b1 [FieldB] : Object | semmle.label | [post] access to local variable b1 [FieldB] : Object | -| H.cs:89:14:89:14 | access to local variable a [FieldA] : Object | semmle.label | access to local variable a [FieldA] : Object | +| H.cs:88:34:88:35 | [post] access to local variable b1 [field FieldB] : Object | semmle.label | [post] access to local variable b1 [field FieldB] : Object | +| H.cs:89:14:89:14 | access to local variable a [field FieldA] : Object | semmle.label | access to local variable a [field FieldA] : Object | | H.cs:89:14:89:21 | access to field FieldA | semmle.label | access to field FieldA | -| H.cs:90:14:90:15 | access to local variable b1 [FieldB] : Object | semmle.label | access to local variable b1 [FieldB] : Object | +| H.cs:90:14:90:15 | access to local variable b1 [field FieldB] : Object | semmle.label | access to local variable b1 [field FieldB] : Object | | H.cs:90:14:90:22 | access to field FieldB | semmle.label | access to field FieldB | -| H.cs:112:9:112:9 | [post] access to local variable a [FieldA] : Object | semmle.label | [post] access to local variable a [FieldA] : Object | +| H.cs:112:9:112:9 | [post] access to local variable a [field FieldA] : Object | semmle.label | [post] access to local variable a [field FieldA] : Object | | H.cs:112:20:112:31 | object creation of type Object : Object | semmle.label | object creation of type Object : Object | -| H.cs:113:17:113:32 | call to method TransformWrap [FieldB] : Object | semmle.label | call to method TransformWrap [FieldB] : Object | -| H.cs:113:31:113:31 | access to local variable a [FieldA] : Object | semmle.label | access to local variable a [FieldA] : Object | -| H.cs:114:14:114:14 | access to local variable b [FieldB] : Object | semmle.label | access to local variable b [FieldB] : Object | +| H.cs:113:17:113:32 | call to method TransformWrap [field FieldB] : Object | semmle.label | call to method TransformWrap [field FieldB] : Object | +| H.cs:113:31:113:31 | access to local variable a [field FieldA] : Object | semmle.label | access to local variable a [field FieldA] : Object | +| H.cs:114:14:114:14 | access to local variable b [field FieldB] : Object | semmle.label | access to local variable b [field FieldB] : Object | | H.cs:114:14:114:21 | access to field FieldB | semmle.label | access to field FieldB | -| H.cs:130:9:130:9 | [post] access to local variable a [FieldA] : Object | semmle.label | [post] access to local variable a [FieldA] : Object | +| H.cs:130:9:130:9 | [post] access to local variable a [field FieldA] : Object | semmle.label | [post] access to local variable a [field FieldA] : Object | | H.cs:130:20:130:31 | object creation of type Object : Object | semmle.label | object creation of type Object : Object | | H.cs:131:14:131:19 | call to method Get | semmle.label | call to method Get | -| H.cs:131:18:131:18 | access to local variable a [FieldA] : Object | semmle.label | access to local variable a [FieldA] : Object | +| H.cs:131:18:131:18 | access to local variable a [field FieldA] : Object | semmle.label | access to local variable a [field FieldA] : Object | | H.cs:147:17:147:32 | call to method Through : A | semmle.label | call to method Through : A | | H.cs:147:25:147:31 | object creation of type A : A | semmle.label | object creation of type A : A | | H.cs:148:14:148:14 | access to local variable a | semmle.label | access to local variable a | | H.cs:155:17:155:23 | object creation of type B : B | semmle.label | object creation of type B : B | | H.cs:156:9:156:9 | access to local variable b : B | semmle.label | access to local variable b : B | -| H.cs:157:9:157:9 | [post] access to parameter a [FieldA] : B | semmle.label | [post] access to parameter a [FieldA] : B | +| H.cs:157:9:157:9 | [post] access to parameter a [field FieldA] : B | semmle.label | [post] access to parameter a [field FieldA] : B | | H.cs:157:20:157:20 | access to local variable b : B | semmle.label | access to local variable b : B | | H.cs:163:17:163:28 | object creation of type Object : Object | semmle.label | object creation of type Object : Object | -| H.cs:164:19:164:19 | [post] access to local variable a [FieldA, FieldB] : Object | semmle.label | [post] access to local variable a [FieldA, FieldB] : Object | -| H.cs:164:19:164:19 | [post] access to local variable a [FieldA] : B | semmle.label | [post] access to local variable a [FieldA] : B | +| H.cs:164:19:164:19 | [post] access to local variable a [field FieldA, field FieldB] : Object | semmle.label | [post] access to local variable a [field FieldA, field FieldB] : Object | +| H.cs:164:19:164:19 | [post] access to local variable a [field FieldA] : B | semmle.label | [post] access to local variable a [field FieldA] : B | | H.cs:164:22:164:22 | access to local variable o : Object | semmle.label | access to local variable o : Object | | H.cs:165:17:165:28 | (...) ... : B | semmle.label | (...) ... : B | -| H.cs:165:17:165:28 | (...) ... [FieldB] : Object | semmle.label | (...) ... [FieldB] : Object | -| H.cs:165:21:165:21 | access to local variable a [FieldA, FieldB] : Object | semmle.label | access to local variable a [FieldA, FieldB] : Object | -| H.cs:165:21:165:21 | access to local variable a [FieldA] : B | semmle.label | access to local variable a [FieldA] : B | +| H.cs:165:17:165:28 | (...) ... [field FieldB] : Object | semmle.label | (...) ... [field FieldB] : Object | +| H.cs:165:21:165:21 | access to local variable a [field FieldA, field FieldB] : Object | semmle.label | access to local variable a [field FieldA, field FieldB] : Object | +| H.cs:165:21:165:21 | access to local variable a [field FieldA] : B | semmle.label | access to local variable a [field FieldA] : B | | H.cs:165:21:165:28 | access to field FieldA : B | semmle.label | access to field FieldA : B | -| H.cs:165:21:165:28 | access to field FieldA [FieldB] : Object | semmle.label | access to field FieldA [FieldB] : Object | +| H.cs:165:21:165:28 | access to field FieldA [field FieldB] : Object | semmle.label | access to field FieldA [field FieldB] : Object | | H.cs:166:14:166:14 | access to local variable b | semmle.label | access to local variable b | -| H.cs:167:14:167:14 | access to local variable b [FieldB] : Object | semmle.label | access to local variable b [FieldB] : Object | +| H.cs:167:14:167:14 | access to local variable b [field FieldB] : Object | semmle.label | access to local variable b [field FieldB] : Object | | H.cs:167:14:167:21 | access to field FieldB | semmle.label | access to field FieldB | -| I.cs:7:9:7:14 | [post] this access [Field1] : Object | semmle.label | [post] this access [Field1] : Object | +| I.cs:7:9:7:14 | [post] this access [field Field1] : Object | semmle.label | [post] this access [field Field1] : Object | | I.cs:7:18:7:29 | object creation of type Object : Object | semmle.label | object creation of type Object : Object | | I.cs:13:17:13:28 | object creation of type Object : Object | semmle.label | object creation of type Object : Object | -| I.cs:15:9:15:9 | [post] access to local variable i [Field1] : Object | semmle.label | [post] access to local variable i [Field1] : Object | +| I.cs:15:9:15:9 | [post] access to local variable i [field Field1] : Object | semmle.label | [post] access to local variable i [field Field1] : Object | | I.cs:15:20:15:20 | access to local variable o : Object | semmle.label | access to local variable o : Object | -| I.cs:16:9:16:9 | access to local variable i [Field1] : Object | semmle.label | access to local variable i [Field1] : Object | -| I.cs:17:9:17:9 | access to local variable i [Field1] : Object | semmle.label | access to local variable i [Field1] : Object | -| I.cs:18:14:18:14 | access to local variable i [Field1] : Object | semmle.label | access to local variable i [Field1] : Object | +| I.cs:16:9:16:9 | access to local variable i [field Field1] : Object | semmle.label | access to local variable i [field Field1] : Object | +| I.cs:17:9:17:9 | access to local variable i [field Field1] : Object | semmle.label | access to local variable i [field Field1] : Object | +| I.cs:18:14:18:14 | access to local variable i [field Field1] : Object | semmle.label | access to local variable i [field Field1] : Object | | I.cs:18:14:18:21 | access to field Field1 | semmle.label | access to field Field1 | -| I.cs:21:13:21:19 | object creation of type I [Field1] : Object | semmle.label | object creation of type I [Field1] : Object | -| I.cs:22:9:22:9 | access to local variable i [Field1] : Object | semmle.label | access to local variable i [Field1] : Object | -| I.cs:23:14:23:14 | access to local variable i [Field1] : Object | semmle.label | access to local variable i [Field1] : Object | +| I.cs:21:13:21:19 | object creation of type I [field Field1] : Object | semmle.label | object creation of type I [field Field1] : Object | +| I.cs:22:9:22:9 | access to local variable i [field Field1] : Object | semmle.label | access to local variable i [field Field1] : Object | +| I.cs:23:14:23:14 | access to local variable i [field Field1] : Object | semmle.label | access to local variable i [field Field1] : Object | | I.cs:23:14:23:21 | access to field Field1 | semmle.label | access to field Field1 | -| I.cs:26:13:26:37 | [pre-initializer] object creation of type I [Field1] : Object | semmle.label | [pre-initializer] object creation of type I [Field1] : Object | -| I.cs:27:14:27:14 | access to local variable i [Field1] : Object | semmle.label | access to local variable i [Field1] : Object | +| I.cs:26:13:26:37 | [pre-initializer] object creation of type I [field Field1] : Object | semmle.label | [pre-initializer] object creation of type I [field Field1] : Object | +| I.cs:27:14:27:14 | access to local variable i [field Field1] : Object | semmle.label | access to local variable i [field Field1] : Object | | I.cs:27:14:27:21 | access to field Field1 | semmle.label | access to field Field1 | | I.cs:31:13:31:24 | object creation of type Object : Object | semmle.label | object creation of type Object : Object | -| I.cs:32:9:32:9 | [post] access to local variable i [Field1] : Object | semmle.label | [post] access to local variable i [Field1] : Object | +| I.cs:32:9:32:9 | [post] access to local variable i [field Field1] : Object | semmle.label | [post] access to local variable i [field Field1] : Object | | I.cs:32:20:32:20 | access to local variable o : Object | semmle.label | access to local variable o : Object | -| I.cs:33:9:33:9 | access to local variable i [Field1] : Object | semmle.label | access to local variable i [Field1] : Object | -| I.cs:34:12:34:12 | access to local variable i [Field1] : Object | semmle.label | access to local variable i [Field1] : Object | -| I.cs:37:23:37:23 | i [Field1] : Object | semmle.label | i [Field1] : Object | -| I.cs:39:9:39:9 | access to parameter i [Field1] : Object | semmle.label | access to parameter i [Field1] : Object | -| I.cs:40:14:40:14 | access to parameter i [Field1] : Object | semmle.label | access to parameter i [Field1] : Object | +| I.cs:33:9:33:9 | access to local variable i [field Field1] : Object | semmle.label | access to local variable i [field Field1] : Object | +| I.cs:34:12:34:12 | access to local variable i [field Field1] : Object | semmle.label | access to local variable i [field Field1] : Object | +| I.cs:37:23:37:23 | i [field Field1] : Object | semmle.label | i [field Field1] : Object | +| I.cs:39:9:39:9 | access to parameter i [field Field1] : Object | semmle.label | access to parameter i [field Field1] : Object | +| I.cs:40:14:40:14 | access to parameter i [field Field1] : Object | semmle.label | access to parameter i [field Field1] : Object | | I.cs:40:14:40:21 | access to field Field1 | semmle.label | access to field Field1 | | J.cs:12:17:12:28 | object creation of type Object : Object | semmle.label | object creation of type Object : Object | -| J.cs:13:18:13:36 | object creation of type Record [Prop1] : Object | semmle.label | object creation of type Record [Prop1] : Object | +| J.cs:13:18:13:36 | object creation of type Record [property Prop1] : Object | semmle.label | object creation of type Record [property Prop1] : Object | | J.cs:13:29:13:29 | access to local variable o : Object | semmle.label | access to local variable o : Object | -| J.cs:14:14:14:15 | access to local variable r1 [Prop1] : Object | semmle.label | access to local variable r1 [Prop1] : Object | +| J.cs:14:14:14:15 | access to local variable r1 [property Prop1] : Object | semmle.label | access to local variable r1 [property Prop1] : Object | | J.cs:14:14:14:21 | access to property Prop1 | semmle.label | access to property Prop1 | -| J.cs:18:14:18:15 | access to local variable r2 [Prop1] : Object | semmle.label | access to local variable r2 [Prop1] : Object | +| J.cs:18:14:18:15 | access to local variable r2 [property Prop1] : Object | semmle.label | access to local variable r2 [property Prop1] : Object | | J.cs:18:14:18:21 | access to property Prop1 | semmle.label | access to property Prop1 | -| J.cs:21:18:21:38 | ... with { ... } [Prop2] : Object | semmle.label | ... with { ... } [Prop2] : Object | +| J.cs:21:18:21:38 | ... with { ... } [property Prop2] : Object | semmle.label | ... with { ... } [property Prop2] : Object | | J.cs:21:36:21:36 | access to local variable o : Object | semmle.label | access to local variable o : Object | -| J.cs:22:14:22:15 | access to local variable r3 [Prop1] : Object | semmle.label | access to local variable r3 [Prop1] : Object | +| J.cs:22:14:22:15 | access to local variable r3 [property Prop1] : Object | semmle.label | access to local variable r3 [property Prop1] : Object | | J.cs:22:14:22:21 | access to property Prop1 | semmle.label | access to property Prop1 | -| J.cs:23:14:23:15 | access to local variable r3 [Prop2] : Object | semmle.label | access to local variable r3 [Prop2] : Object | +| J.cs:23:14:23:15 | access to local variable r3 [property Prop2] : Object | semmle.label | access to local variable r3 [property Prop2] : Object | | J.cs:23:14:23:21 | access to property Prop2 | semmle.label | access to property Prop2 | #select | A.cs:7:14:7:16 | access to field c | A.cs:5:17:5:23 | object creation of type C : C | A.cs:7:14:7:16 | access to field c | $@ | A.cs:5:17:5:23 | object creation of type C : C | object creation of type C : C | diff --git a/csharp/ql/test/library-tests/dataflow/functionpointers/FunctionPointerFlow.expected b/csharp/ql/test/library-tests/dataflow/functionpointers/FunctionPointerFlow.expected index ad2bfb887c0..a25f9c14539 100644 --- a/csharp/ql/test/library-tests/dataflow/functionpointers/FunctionPointerFlow.expected +++ b/csharp/ql/test/library-tests/dataflow/functionpointers/FunctionPointerFlow.expected @@ -1,9 +1,20 @@ -| FunctionPointerFlow.cs:14:9:14:12 | function pointer call | FunctionPointerFlow.cs:5:24:5:27 | Log1 | FunctionPointerFlow.cs:21:12:21:16 | &... | -| FunctionPointerFlow.cs:14:9:14:12 | function pointer call | FunctionPointerFlow.cs:6:24:6:27 | Log2 | FunctionPointerFlow.cs:26:12:26:12 | access to parameter a | -| FunctionPointerFlow.cs:14:9:14:12 | function pointer call | FunctionPointerFlow.cs:10:24:10:27 | Log6 | FunctionPointerFlow.cs:26:12:26:12 | access to parameter a | -| FunctionPointerFlow.cs:14:9:14:12 | function pointer call | FunctionPointerFlow.cs:46:9:46:44 | LocalFunction | FunctionPointerFlow.cs:47:12:47:25 | &... | -| FunctionPointerFlow.cs:16:9:16:12 | function pointer call | FunctionPointerFlow.cs:7:24:7:27 | Log3 | file://:0:0:0:0 | | -| FunctionPointerFlow.cs:41:9:41:15 | function pointer call | FunctionPointerFlow.cs:8:24:8:27 | Log4 | file://:0:0:0:0 | | -| FunctionPointerFlow.cs:54:9:54:16 | function pointer call | FunctionPointerFlow.cs:9:24:9:27 | Log5 | file://:0:0:0:0 | | -| FunctionPointerFlow.cs:59:9:59:13 | function pointer call | FunctionPointerFlow.cs:24:24:24:25 | M4 | FunctionPointerFlow.cs:64:13:64:15 | &... | -| FunctionPointerFlow.cs:69:9:69:13 | function pointer call | FunctionPointerFlow.cs:72:24:72:26 | M17 | FunctionPointerFlow.cs:81:13:81:16 | &... | +fptrCall +| FunctionPointerFlow.cs:14:9:14:12 | function pointer call | FunctionPointerFlow.cs:5:24:5:27 | Log1 | +| FunctionPointerFlow.cs:14:9:14:12 | function pointer call | FunctionPointerFlow.cs:6:24:6:27 | Log2 | +| FunctionPointerFlow.cs:14:9:14:12 | function pointer call | FunctionPointerFlow.cs:10:24:10:27 | Log6 | +| FunctionPointerFlow.cs:14:9:14:12 | function pointer call | FunctionPointerFlow.cs:46:9:46:44 | LocalFunction | +| FunctionPointerFlow.cs:16:9:16:12 | function pointer call | FunctionPointerFlow.cs:7:24:7:27 | Log3 | +| FunctionPointerFlow.cs:41:9:41:15 | function pointer call | FunctionPointerFlow.cs:8:24:8:27 | Log4 | +| FunctionPointerFlow.cs:54:9:54:16 | function pointer call | FunctionPointerFlow.cs:9:24:9:27 | Log5 | +| FunctionPointerFlow.cs:59:9:59:13 | function pointer call | FunctionPointerFlow.cs:24:24:24:25 | M4 | +| FunctionPointerFlow.cs:69:9:69:13 | function pointer call | FunctionPointerFlow.cs:72:24:72:26 | M17 | +fptrCallContext +| FunctionPointerFlow.cs:14:9:14:12 | function pointer call | FunctionPointerFlow.cs:21:9:21:17 | call to method M2 | FunctionPointerFlow.cs:5:24:5:27 | Log1 | +| FunctionPointerFlow.cs:14:9:14:12 | function pointer call | FunctionPointerFlow.cs:26:9:26:13 | call to method M2 | FunctionPointerFlow.cs:6:24:6:27 | Log2 | +| FunctionPointerFlow.cs:14:9:14:12 | function pointer call | FunctionPointerFlow.cs:26:9:26:13 | call to method M2 | FunctionPointerFlow.cs:10:24:10:27 | Log6 | +| FunctionPointerFlow.cs:14:9:14:12 | function pointer call | FunctionPointerFlow.cs:47:9:47:26 | call to method M2 | FunctionPointerFlow.cs:46:9:46:44 | LocalFunction | +| FunctionPointerFlow.cs:16:9:16:12 | function pointer call | file://:0:0:0:0 | (none) | FunctionPointerFlow.cs:7:24:7:27 | Log3 | +| FunctionPointerFlow.cs:41:9:41:15 | function pointer call | file://:0:0:0:0 | (none) | FunctionPointerFlow.cs:8:24:8:27 | Log4 | +| FunctionPointerFlow.cs:54:9:54:16 | function pointer call | file://:0:0:0:0 | (none) | FunctionPointerFlow.cs:9:24:9:27 | Log5 | +| FunctionPointerFlow.cs:59:9:59:13 | function pointer call | FunctionPointerFlow.cs:64:9:64:23 | call to method M10 | FunctionPointerFlow.cs:24:24:24:25 | M4 | +| FunctionPointerFlow.cs:69:9:69:13 | function pointer call | FunctionPointerFlow.cs:81:9:81:29 | call to method M16 | FunctionPointerFlow.cs:72:24:72:26 | M17 | diff --git a/csharp/ql/test/library-tests/dataflow/functionpointers/FunctionPointerFlow.ql b/csharp/ql/test/library-tests/dataflow/functionpointers/FunctionPointerFlow.ql index 3434d068329..fced49bc9c6 100644 --- a/csharp/ql/test/library-tests/dataflow/functionpointers/FunctionPointerFlow.ql +++ b/csharp/ql/test/library-tests/dataflow/functionpointers/FunctionPointerFlow.ql @@ -1,5 +1,38 @@ import csharp +import semmle.code.csharp.dataflow.internal.DataFlowImplCommon +import semmle.code.csharp.dataflow.internal.DataFlowDispatch -query predicate fptrCall(FunctionPointerCall fptrc, Callable c, CallContext::CallContext cc) { - c = fptrc.getARuntimeTarget(cc) +query predicate fptrCall(FunctionPointerCall dc, Callable c) { c = dc.getARuntimeTarget() } + +private class LocatableDataFlowCallOption extends DataFlowCallOption { + Location getLocation() { + this = TDataFlowCallNone() and + result instanceof EmptyLocation + or + exists(DataFlowCall call | + this = TDataFlowCallSome(call) and + result = call.getLocation() + ) + } +} + +private class LocatableDataFlowCall extends TDataFlowCall { + LocatableDataFlowCall() { + this.(ExplicitDelegateLikeDataFlowCall).getCall() instanceof FunctionPointerCall + } + + string toString() { result = this.(DataFlowCall).toString() } + + Location getLocation() { + exists(Location l | + l = this.(DataFlowCall).getLocation() and + if l instanceof SourceLocation then result = l else result instanceof EmptyLocation + ) + } +} + +query predicate fptrCallContext( + LocatableDataFlowCall call, LocatableDataFlowCallOption lastCall, DataFlowCallable target +) { + target = viableCallableLambda(call, lastCall) } diff --git a/csharp/ql/test/library-tests/dataflow/global/DataFlow.expected b/csharp/ql/test/library-tests/dataflow/global/DataFlow.expected index 9c382aaee62..b0506ab3e4e 100644 --- a/csharp/ql/test/library-tests/dataflow/global/DataFlow.expected +++ b/csharp/ql/test/library-tests/dataflow/global/DataFlow.expected @@ -52,6 +52,7 @@ | GlobalDataFlow.cs:401:15:401:20 | access to local variable sink11 | | GlobalDataFlow.cs:424:41:424:46 | access to local variable sink20 | | GlobalDataFlow.cs:475:15:475:20 | access to local variable sink45 | +| GlobalDataFlow.cs:483:32:483:32 | access to parameter s | | Splitting.cs:9:15:9:15 | [b (line 3): false] access to local variable x | | Splitting.cs:9:15:9:15 | [b (line 3): true] access to local variable x | | Splitting.cs:11:19:11:19 | access to local variable x | diff --git a/csharp/ql/test/library-tests/dataflow/global/DataFlowPath.expected b/csharp/ql/test/library-tests/dataflow/global/DataFlowPath.expected index a806a9a6256..41258053f33 100644 --- a/csharp/ql/test/library-tests/dataflow/global/DataFlowPath.expected +++ b/csharp/ql/test/library-tests/dataflow/global/DataFlowPath.expected @@ -119,30 +119,30 @@ edges | GlobalDataFlow.cs:79:30:79:34 | SSA def(sink3) : String | GlobalDataFlow.cs:80:15:80:19 | access to local variable sink3 | | GlobalDataFlow.cs:79:30:79:34 | SSA def(sink3) : String | GlobalDataFlow.cs:81:59:81:63 | access to local variable sink3 : String | | GlobalDataFlow.cs:79:30:79:34 | SSA def(sink3) : String | GlobalDataFlow.cs:136:29:136:33 | access to local variable sink3 : String | -| GlobalDataFlow.cs:81:22:81:85 | call to method SelectEven [[]] : String | GlobalDataFlow.cs:81:22:81:93 | call to method First : String | +| GlobalDataFlow.cs:81:22:81:85 | call to method SelectEven [element] : String | GlobalDataFlow.cs:81:22:81:93 | call to method First : String | | GlobalDataFlow.cs:81:22:81:93 | call to method First : String | GlobalDataFlow.cs:82:15:82:20 | access to local variable sink13 | | GlobalDataFlow.cs:81:22:81:93 | call to method First : String | GlobalDataFlow.cs:83:59:83:64 | access to local variable sink13 : String | -| GlobalDataFlow.cs:81:23:81:65 | (...) ... [[]] : String | GlobalDataFlow.cs:81:22:81:85 | call to method SelectEven [[]] : String | -| GlobalDataFlow.cs:81:57:81:65 | { ..., ... } [[]] : String | GlobalDataFlow.cs:81:23:81:65 | (...) ... [[]] : String | -| GlobalDataFlow.cs:81:59:81:63 | access to local variable sink3 : String | GlobalDataFlow.cs:81:57:81:65 | { ..., ... } [[]] : String | -| GlobalDataFlow.cs:83:22:83:87 | call to method Select [[]] : String | GlobalDataFlow.cs:83:22:83:95 | call to method First : String | +| GlobalDataFlow.cs:81:23:81:65 | (...) ... [element] : String | GlobalDataFlow.cs:81:22:81:85 | call to method SelectEven [element] : String | +| GlobalDataFlow.cs:81:57:81:65 | { ..., ... } [element] : String | GlobalDataFlow.cs:81:23:81:65 | (...) ... [element] : String | +| GlobalDataFlow.cs:81:59:81:63 | access to local variable sink3 : String | GlobalDataFlow.cs:81:57:81:65 | { ..., ... } [element] : String | +| GlobalDataFlow.cs:83:22:83:87 | call to method Select [element] : String | GlobalDataFlow.cs:83:22:83:95 | call to method First : String | | GlobalDataFlow.cs:83:22:83:95 | call to method First : String | GlobalDataFlow.cs:84:15:84:20 | access to local variable sink14 | | GlobalDataFlow.cs:83:22:83:95 | call to method First : String | GlobalDataFlow.cs:85:59:85:64 | access to local variable sink14 : String | -| GlobalDataFlow.cs:83:23:83:66 | (...) ... [[]] : String | GlobalDataFlow.cs:83:22:83:87 | call to method Select [[]] : String | -| GlobalDataFlow.cs:83:23:83:66 | (...) ... [[]] : String | GlobalDataFlow.cs:312:31:312:40 | sinkParam8 : String | -| GlobalDataFlow.cs:83:57:83:66 | { ..., ... } [[]] : String | GlobalDataFlow.cs:83:23:83:66 | (...) ... [[]] : String | -| GlobalDataFlow.cs:83:59:83:64 | access to local variable sink13 : String | GlobalDataFlow.cs:83:57:83:66 | { ..., ... } [[]] : String | -| GlobalDataFlow.cs:85:22:85:128 | call to method Zip [[]] : String | GlobalDataFlow.cs:85:22:85:136 | call to method First : String | +| GlobalDataFlow.cs:83:23:83:66 | (...) ... [element] : String | GlobalDataFlow.cs:83:22:83:87 | call to method Select [element] : String | +| GlobalDataFlow.cs:83:23:83:66 | (...) ... [element] : String | GlobalDataFlow.cs:312:31:312:40 | sinkParam8 : String | +| GlobalDataFlow.cs:83:57:83:66 | { ..., ... } [element] : String | GlobalDataFlow.cs:83:23:83:66 | (...) ... [element] : String | +| GlobalDataFlow.cs:83:59:83:64 | access to local variable sink13 : String | GlobalDataFlow.cs:83:57:83:66 | { ..., ... } [element] : String | +| GlobalDataFlow.cs:85:22:85:128 | call to method Zip [element] : String | GlobalDataFlow.cs:85:22:85:136 | call to method First : String | | GlobalDataFlow.cs:85:22:85:136 | call to method First : String | GlobalDataFlow.cs:86:15:86:20 | access to local variable sink15 | | GlobalDataFlow.cs:85:22:85:136 | call to method First : String | GlobalDataFlow.cs:87:106:87:111 | access to local variable sink15 : String | -| GlobalDataFlow.cs:85:23:85:66 | (...) ... [[]] : String | GlobalDataFlow.cs:85:22:85:128 | call to method Zip [[]] : String | -| GlobalDataFlow.cs:85:57:85:66 | { ..., ... } [[]] : String | GlobalDataFlow.cs:85:23:85:66 | (...) ... [[]] : String | -| GlobalDataFlow.cs:85:59:85:64 | access to local variable sink14 : String | GlobalDataFlow.cs:85:57:85:66 | { ..., ... } [[]] : String | -| GlobalDataFlow.cs:87:22:87:128 | call to method Zip [[]] : String | GlobalDataFlow.cs:87:22:87:136 | call to method First : String | +| GlobalDataFlow.cs:85:23:85:66 | (...) ... [element] : String | GlobalDataFlow.cs:85:22:85:128 | call to method Zip [element] : String | +| GlobalDataFlow.cs:85:57:85:66 | { ..., ... } [element] : String | GlobalDataFlow.cs:85:23:85:66 | (...) ... [element] : String | +| GlobalDataFlow.cs:85:59:85:64 | access to local variable sink14 : String | GlobalDataFlow.cs:85:57:85:66 | { ..., ... } [element] : String | +| GlobalDataFlow.cs:87:22:87:128 | call to method Zip [element] : String | GlobalDataFlow.cs:87:22:87:136 | call to method First : String | | GlobalDataFlow.cs:87:22:87:136 | call to method First : String | GlobalDataFlow.cs:88:15:88:20 | access to local variable sink16 | -| GlobalDataFlow.cs:87:70:87:113 | (...) ... [[]] : String | GlobalDataFlow.cs:87:22:87:128 | call to method Zip [[]] : String | -| GlobalDataFlow.cs:87:104:87:113 | { ..., ... } [[]] : String | GlobalDataFlow.cs:87:70:87:113 | (...) ... [[]] : String | -| GlobalDataFlow.cs:87:106:87:111 | access to local variable sink15 : String | GlobalDataFlow.cs:87:104:87:113 | { ..., ... } [[]] : String | +| GlobalDataFlow.cs:87:70:87:113 | (...) ... [element] : String | GlobalDataFlow.cs:87:22:87:128 | call to method Zip [element] : String | +| GlobalDataFlow.cs:87:104:87:113 | { ..., ... } [element] : String | GlobalDataFlow.cs:87:70:87:113 | (...) ... [element] : String | +| GlobalDataFlow.cs:87:106:87:111 | access to local variable sink15 : String | GlobalDataFlow.cs:87:104:87:113 | { ..., ... } [element] : String | | GlobalDataFlow.cs:136:21:136:34 | delegate call : String | GlobalDataFlow.cs:137:15:137:19 | access to local variable sink4 | | GlobalDataFlow.cs:136:21:136:34 | delegate call : String | GlobalDataFlow.cs:144:39:144:43 | access to local variable sink4 : String | | GlobalDataFlow.cs:136:29:136:33 | access to local variable sink3 : String | GlobalDataFlow.cs:136:21:136:34 | delegate call : String | @@ -151,42 +151,42 @@ edges | GlobalDataFlow.cs:154:21:154:25 | call to method Out : String | GlobalDataFlow.cs:155:15:155:19 | access to local variable sink6 | | GlobalDataFlow.cs:157:20:157:24 | SSA def(sink7) : String | GlobalDataFlow.cs:158:15:158:19 | access to local variable sink7 | | GlobalDataFlow.cs:160:20:160:24 | SSA def(sink8) : String | GlobalDataFlow.cs:161:15:161:19 | access to local variable sink8 | -| GlobalDataFlow.cs:162:22:162:31 | call to method OutYield [[]] : String | GlobalDataFlow.cs:162:22:162:39 | call to method First : String | +| GlobalDataFlow.cs:162:22:162:31 | call to method OutYield [element] : String | GlobalDataFlow.cs:162:22:162:39 | call to method First : String | | GlobalDataFlow.cs:162:22:162:39 | call to method First : String | GlobalDataFlow.cs:163:15:163:20 | access to local variable sink12 | | GlobalDataFlow.cs:164:22:164:43 | call to method TaintedParam : String | GlobalDataFlow.cs:165:15:165:20 | access to local variable sink23 | | GlobalDataFlow.cs:180:35:180:48 | "taint source" : String | GlobalDataFlow.cs:181:21:181:26 | delegate call : String | | GlobalDataFlow.cs:181:21:181:26 | delegate call : String | GlobalDataFlow.cs:182:15:182:19 | access to local variable sink9 | -| GlobalDataFlow.cs:190:22:190:42 | object creation of type Lazy [Value] : String | GlobalDataFlow.cs:190:22:190:48 | access to property Value : String | +| GlobalDataFlow.cs:190:22:190:42 | object creation of type Lazy [property Value] : String | GlobalDataFlow.cs:190:22:190:48 | access to property Value : String | | GlobalDataFlow.cs:190:22:190:48 | access to property Value : String | GlobalDataFlow.cs:191:15:191:20 | access to local variable sink10 | | GlobalDataFlow.cs:198:22:198:32 | access to property OutProperty : String | GlobalDataFlow.cs:199:15:199:20 | access to local variable sink19 | -| GlobalDataFlow.cs:208:38:208:61 | array creation of type String[] [[]] : String | GlobalDataFlow.cs:208:38:208:75 | call to method AsQueryable [[]] : String | -| GlobalDataFlow.cs:208:38:208:75 | call to method AsQueryable [[]] : String | GlobalDataFlow.cs:213:22:213:28 | access to local variable tainted [[]] : String | -| GlobalDataFlow.cs:208:38:208:75 | call to method AsQueryable [[]] : String | GlobalDataFlow.cs:215:22:215:28 | access to local variable tainted [[]] : String | -| GlobalDataFlow.cs:208:38:208:75 | call to method AsQueryable [[]] : String | GlobalDataFlow.cs:217:22:217:28 | access to local variable tainted [[]] : String | -| GlobalDataFlow.cs:208:44:208:61 | { ..., ... } [[]] : String | GlobalDataFlow.cs:208:38:208:61 | array creation of type String[] [[]] : String | -| GlobalDataFlow.cs:208:46:208:59 | "taint source" : String | GlobalDataFlow.cs:208:44:208:61 | { ..., ... } [[]] : String | +| GlobalDataFlow.cs:208:38:208:61 | array creation of type String[] [element] : String | GlobalDataFlow.cs:208:38:208:75 | call to method AsQueryable [element] : String | +| GlobalDataFlow.cs:208:38:208:75 | call to method AsQueryable [element] : String | GlobalDataFlow.cs:213:22:213:28 | access to local variable tainted [element] : String | +| GlobalDataFlow.cs:208:38:208:75 | call to method AsQueryable [element] : String | GlobalDataFlow.cs:215:22:215:28 | access to local variable tainted [element] : String | +| GlobalDataFlow.cs:208:38:208:75 | call to method AsQueryable [element] : String | GlobalDataFlow.cs:217:22:217:28 | access to local variable tainted [element] : String | +| GlobalDataFlow.cs:208:44:208:61 | { ..., ... } [element] : String | GlobalDataFlow.cs:208:38:208:61 | array creation of type String[] [element] : String | +| GlobalDataFlow.cs:208:46:208:59 | "taint source" : String | GlobalDataFlow.cs:208:44:208:61 | { ..., ... } [element] : String | | GlobalDataFlow.cs:211:35:211:45 | sinkParam10 : String | GlobalDataFlow.cs:211:58:211:68 | access to parameter sinkParam10 | | GlobalDataFlow.cs:212:71:212:71 | x : String | GlobalDataFlow.cs:212:89:212:89 | access to parameter x : String | | GlobalDataFlow.cs:212:89:212:89 | access to parameter x : String | GlobalDataFlow.cs:318:32:318:41 | sinkParam9 : String | -| GlobalDataFlow.cs:213:22:213:28 | access to local variable tainted [[]] : String | GlobalDataFlow.cs:211:35:211:45 | sinkParam10 : String | -| GlobalDataFlow.cs:213:22:213:28 | access to local variable tainted [[]] : String | GlobalDataFlow.cs:213:22:213:39 | call to method Select [[]] : String | -| GlobalDataFlow.cs:213:22:213:39 | call to method Select [[]] : String | GlobalDataFlow.cs:213:22:213:47 | call to method First : String | +| GlobalDataFlow.cs:213:22:213:28 | access to local variable tainted [element] : String | GlobalDataFlow.cs:211:35:211:45 | sinkParam10 : String | +| GlobalDataFlow.cs:213:22:213:28 | access to local variable tainted [element] : String | GlobalDataFlow.cs:213:22:213:39 | call to method Select [element] : String | +| GlobalDataFlow.cs:213:22:213:39 | call to method Select [element] : String | GlobalDataFlow.cs:213:22:213:47 | call to method First : String | | GlobalDataFlow.cs:213:22:213:47 | call to method First : String | GlobalDataFlow.cs:214:15:214:20 | access to local variable sink24 | -| GlobalDataFlow.cs:215:22:215:28 | access to local variable tainted [[]] : String | GlobalDataFlow.cs:212:71:212:71 | x : String | -| GlobalDataFlow.cs:215:22:215:28 | access to local variable tainted [[]] : String | GlobalDataFlow.cs:215:22:215:39 | call to method Select [[]] : String | -| GlobalDataFlow.cs:215:22:215:39 | call to method Select [[]] : String | GlobalDataFlow.cs:215:22:215:47 | call to method First : String | +| GlobalDataFlow.cs:215:22:215:28 | access to local variable tainted [element] : String | GlobalDataFlow.cs:212:71:212:71 | x : String | +| GlobalDataFlow.cs:215:22:215:28 | access to local variable tainted [element] : String | GlobalDataFlow.cs:215:22:215:39 | call to method Select [element] : String | +| GlobalDataFlow.cs:215:22:215:39 | call to method Select [element] : String | GlobalDataFlow.cs:215:22:215:47 | call to method First : String | | GlobalDataFlow.cs:215:22:215:47 | call to method First : String | GlobalDataFlow.cs:216:15:216:20 | access to local variable sink25 | -| GlobalDataFlow.cs:217:22:217:28 | access to local variable tainted [[]] : String | GlobalDataFlow.cs:217:22:217:49 | call to method Select [[]] : String | -| GlobalDataFlow.cs:217:22:217:28 | access to local variable tainted [[]] : String | GlobalDataFlow.cs:324:32:324:42 | sinkParam11 : String | -| GlobalDataFlow.cs:217:22:217:49 | call to method Select [[]] : String | GlobalDataFlow.cs:217:22:217:57 | call to method First : String | +| GlobalDataFlow.cs:217:22:217:28 | access to local variable tainted [element] : String | GlobalDataFlow.cs:217:22:217:49 | call to method Select [element] : String | +| GlobalDataFlow.cs:217:22:217:28 | access to local variable tainted [element] : String | GlobalDataFlow.cs:324:32:324:42 | sinkParam11 : String | +| GlobalDataFlow.cs:217:22:217:49 | call to method Select [element] : String | GlobalDataFlow.cs:217:22:217:57 | call to method First : String | | GlobalDataFlow.cs:217:22:217:57 | call to method First : String | GlobalDataFlow.cs:218:15:218:20 | access to local variable sink26 | -| GlobalDataFlow.cs:238:20:238:49 | call to method Run [Result] : String | GlobalDataFlow.cs:239:22:239:25 | access to local variable task [Result] : String | -| GlobalDataFlow.cs:238:20:238:49 | call to method Run [Result] : String | GlobalDataFlow.cs:241:28:241:31 | access to local variable task [Result] : String | -| GlobalDataFlow.cs:238:35:238:48 | "taint source" : String | GlobalDataFlow.cs:238:20:238:49 | call to method Run [Result] : String | -| GlobalDataFlow.cs:239:22:239:25 | access to local variable task [Result] : String | GlobalDataFlow.cs:239:22:239:32 | access to property Result : String | +| GlobalDataFlow.cs:238:20:238:49 | call to method Run [property Result] : String | GlobalDataFlow.cs:239:22:239:25 | access to local variable task [property Result] : String | +| GlobalDataFlow.cs:238:20:238:49 | call to method Run [property Result] : String | GlobalDataFlow.cs:241:28:241:31 | access to local variable task [property Result] : String | +| GlobalDataFlow.cs:238:35:238:48 | "taint source" : String | GlobalDataFlow.cs:238:20:238:49 | call to method Run [property Result] : String | +| GlobalDataFlow.cs:239:22:239:25 | access to local variable task [property Result] : String | GlobalDataFlow.cs:239:22:239:32 | access to property Result : String | | GlobalDataFlow.cs:239:22:239:32 | access to property Result : String | GlobalDataFlow.cs:240:15:240:20 | access to local variable sink41 | | GlobalDataFlow.cs:241:22:241:31 | await ... : String | GlobalDataFlow.cs:242:15:242:20 | access to local variable sink42 | -| GlobalDataFlow.cs:241:28:241:31 | access to local variable task [Result] : String | GlobalDataFlow.cs:241:22:241:31 | await ... : String | +| GlobalDataFlow.cs:241:28:241:31 | access to local variable task [property Result] : String | GlobalDataFlow.cs:241:22:241:31 | await ... : String | | GlobalDataFlow.cs:254:26:254:35 | sinkParam0 : String | GlobalDataFlow.cs:256:16:256:25 | access to parameter sinkParam0 : String | | GlobalDataFlow.cs:254:26:254:35 | sinkParam0 : String | GlobalDataFlow.cs:257:15:257:24 | access to parameter sinkParam0 | | GlobalDataFlow.cs:256:16:256:25 | access to parameter sinkParam0 : String | GlobalDataFlow.cs:254:26:254:35 | sinkParam0 : String | @@ -200,12 +200,12 @@ edges | GlobalDataFlow.cs:318:32:318:41 | sinkParam9 : String | GlobalDataFlow.cs:320:15:320:24 | access to parameter sinkParam9 | | GlobalDataFlow.cs:324:32:324:42 | sinkParam11 : String | GlobalDataFlow.cs:326:15:326:25 | access to parameter sinkParam11 | | GlobalDataFlow.cs:338:16:338:29 | "taint source" : String | GlobalDataFlow.cs:154:21:154:25 | call to method Out : String | -| GlobalDataFlow.cs:338:16:338:29 | "taint source" : String | GlobalDataFlow.cs:190:22:190:42 | object creation of type Lazy [Value] : String | +| GlobalDataFlow.cs:338:16:338:29 | "taint source" : String | GlobalDataFlow.cs:190:22:190:42 | object creation of type Lazy [property Value] : String | | GlobalDataFlow.cs:343:9:343:26 | SSA def(x) : String | GlobalDataFlow.cs:157:20:157:24 | SSA def(sink7) : String | | GlobalDataFlow.cs:343:13:343:26 | "taint source" : String | GlobalDataFlow.cs:343:9:343:26 | SSA def(x) : String | | GlobalDataFlow.cs:348:9:348:26 | SSA def(x) : String | GlobalDataFlow.cs:160:20:160:24 | SSA def(sink8) : String | | GlobalDataFlow.cs:348:13:348:26 | "taint source" : String | GlobalDataFlow.cs:348:9:348:26 | SSA def(x) : String | -| GlobalDataFlow.cs:354:22:354:35 | "taint source" : String | GlobalDataFlow.cs:162:22:162:31 | call to method OutYield [[]] : String | +| GlobalDataFlow.cs:354:22:354:35 | "taint source" : String | GlobalDataFlow.cs:162:22:162:31 | call to method OutYield [element] : String | | GlobalDataFlow.cs:379:41:379:41 | x : String | GlobalDataFlow.cs:381:11:381:11 | access to parameter x : String | | GlobalDataFlow.cs:379:41:379:41 | x : String | GlobalDataFlow.cs:381:11:381:11 | access to parameter x : String | | GlobalDataFlow.cs:381:11:381:11 | access to parameter x : String | GlobalDataFlow.cs:54:15:54:15 | x : String | @@ -221,14 +221,18 @@ edges | GlobalDataFlow.cs:402:16:402:21 | access to local variable sink11 : String | GlobalDataFlow.cs:164:22:164:43 | call to method TaintedParam : String | | GlobalDataFlow.cs:424:9:424:11 | value : String | GlobalDataFlow.cs:424:41:424:46 | access to local variable sink20 | | GlobalDataFlow.cs:435:22:435:35 | "taint source" : String | GlobalDataFlow.cs:198:22:198:32 | access to property OutProperty : String | -| GlobalDataFlow.cs:471:20:471:49 | call to method Run [Result] : String | GlobalDataFlow.cs:472:25:472:28 | access to local variable task [Result] : String | -| GlobalDataFlow.cs:471:35:471:48 | "taint source" : String | GlobalDataFlow.cs:471:20:471:49 | call to method Run [Result] : String | -| GlobalDataFlow.cs:472:25:472:28 | access to local variable task [Result] : String | GlobalDataFlow.cs:472:25:472:50 | call to method ConfigureAwait [m_configuredTaskAwaiter, m_task, Result] : String | -| GlobalDataFlow.cs:472:25:472:50 | call to method ConfigureAwait [m_configuredTaskAwaiter, m_task, Result] : String | GlobalDataFlow.cs:473:23:473:31 | access to local variable awaitable [m_configuredTaskAwaiter, m_task, Result] : String | -| GlobalDataFlow.cs:473:23:473:31 | access to local variable awaitable [m_configuredTaskAwaiter, m_task, Result] : String | GlobalDataFlow.cs:473:23:473:44 | call to method GetAwaiter [m_task, Result] : String | -| GlobalDataFlow.cs:473:23:473:44 | call to method GetAwaiter [m_task, Result] : String | GlobalDataFlow.cs:474:22:474:28 | access to local variable awaiter [m_task, Result] : String | -| GlobalDataFlow.cs:474:22:474:28 | access to local variable awaiter [m_task, Result] : String | GlobalDataFlow.cs:474:22:474:40 | call to method GetResult : String | +| GlobalDataFlow.cs:471:20:471:49 | call to method Run [property Result] : String | GlobalDataFlow.cs:472:25:472:28 | access to local variable task [property Result] : String | +| GlobalDataFlow.cs:471:35:471:48 | "taint source" : String | GlobalDataFlow.cs:471:20:471:49 | call to method Run [property Result] : String | +| GlobalDataFlow.cs:472:25:472:28 | access to local variable task [property Result] : String | GlobalDataFlow.cs:472:25:472:50 | call to method ConfigureAwait [field m_configuredTaskAwaiter, field m_task, property Result] : String | +| GlobalDataFlow.cs:472:25:472:50 | call to method ConfigureAwait [field m_configuredTaskAwaiter, field m_task, property Result] : String | GlobalDataFlow.cs:473:23:473:31 | access to local variable awaitable [field m_configuredTaskAwaiter, field m_task, property Result] : String | +| GlobalDataFlow.cs:473:23:473:31 | access to local variable awaitable [field m_configuredTaskAwaiter, field m_task, property Result] : String | GlobalDataFlow.cs:473:23:473:44 | call to method GetAwaiter [field m_task, property Result] : String | +| GlobalDataFlow.cs:473:23:473:44 | call to method GetAwaiter [field m_task, property Result] : String | GlobalDataFlow.cs:474:22:474:28 | access to local variable awaiter [field m_task, property Result] : String | +| GlobalDataFlow.cs:474:22:474:28 | access to local variable awaiter [field m_task, property Result] : String | GlobalDataFlow.cs:474:22:474:40 | call to method GetResult : String | | GlobalDataFlow.cs:474:22:474:40 | call to method GetResult : String | GlobalDataFlow.cs:475:15:475:20 | access to local variable sink45 | +| GlobalDataFlow.cs:480:53:480:55 | arg : String | GlobalDataFlow.cs:484:15:484:17 | access to parameter arg : String | +| GlobalDataFlow.cs:483:21:483:21 | s : String | GlobalDataFlow.cs:483:32:483:32 | access to parameter s | +| GlobalDataFlow.cs:484:15:484:17 | access to parameter arg : String | GlobalDataFlow.cs:483:21:483:21 | s : String | +| GlobalDataFlow.cs:487:27:487:40 | "taint source" : String | GlobalDataFlow.cs:480:53:480:55 | arg : String | | Splitting.cs:3:28:3:34 | tainted : String | Splitting.cs:8:24:8:30 | [b (line 3): false] access to parameter tainted : String | | Splitting.cs:3:28:3:34 | tainted : String | Splitting.cs:8:24:8:30 | [b (line 3): true] access to parameter tainted : String | | Splitting.cs:8:17:8:31 | [b (line 3): false] call to method Return : String | Splitting.cs:9:15:9:15 | [b (line 3): false] access to local variable x | @@ -315,28 +319,28 @@ nodes | GlobalDataFlow.cs:79:19:79:23 | access to local variable sink2 : String | semmle.label | access to local variable sink2 : String | | GlobalDataFlow.cs:79:30:79:34 | SSA def(sink3) : String | semmle.label | SSA def(sink3) : String | | GlobalDataFlow.cs:80:15:80:19 | access to local variable sink3 | semmle.label | access to local variable sink3 | -| GlobalDataFlow.cs:81:22:81:85 | call to method SelectEven [[]] : String | semmle.label | call to method SelectEven [[]] : String | +| GlobalDataFlow.cs:81:22:81:85 | call to method SelectEven [element] : String | semmle.label | call to method SelectEven [element] : String | | GlobalDataFlow.cs:81:22:81:93 | call to method First : String | semmle.label | call to method First : String | -| GlobalDataFlow.cs:81:23:81:65 | (...) ... [[]] : String | semmle.label | (...) ... [[]] : String | -| GlobalDataFlow.cs:81:57:81:65 | { ..., ... } [[]] : String | semmle.label | { ..., ... } [[]] : String | +| GlobalDataFlow.cs:81:23:81:65 | (...) ... [element] : String | semmle.label | (...) ... [element] : String | +| GlobalDataFlow.cs:81:57:81:65 | { ..., ... } [element] : String | semmle.label | { ..., ... } [element] : String | | GlobalDataFlow.cs:81:59:81:63 | access to local variable sink3 : String | semmle.label | access to local variable sink3 : String | | GlobalDataFlow.cs:82:15:82:20 | access to local variable sink13 | semmle.label | access to local variable sink13 | -| GlobalDataFlow.cs:83:22:83:87 | call to method Select [[]] : String | semmle.label | call to method Select [[]] : String | +| GlobalDataFlow.cs:83:22:83:87 | call to method Select [element] : String | semmle.label | call to method Select [element] : String | | GlobalDataFlow.cs:83:22:83:95 | call to method First : String | semmle.label | call to method First : String | -| GlobalDataFlow.cs:83:23:83:66 | (...) ... [[]] : String | semmle.label | (...) ... [[]] : String | -| GlobalDataFlow.cs:83:57:83:66 | { ..., ... } [[]] : String | semmle.label | { ..., ... } [[]] : String | +| GlobalDataFlow.cs:83:23:83:66 | (...) ... [element] : String | semmle.label | (...) ... [element] : String | +| GlobalDataFlow.cs:83:57:83:66 | { ..., ... } [element] : String | semmle.label | { ..., ... } [element] : String | | GlobalDataFlow.cs:83:59:83:64 | access to local variable sink13 : String | semmle.label | access to local variable sink13 : String | | GlobalDataFlow.cs:84:15:84:20 | access to local variable sink14 | semmle.label | access to local variable sink14 | -| GlobalDataFlow.cs:85:22:85:128 | call to method Zip [[]] : String | semmle.label | call to method Zip [[]] : String | +| GlobalDataFlow.cs:85:22:85:128 | call to method Zip [element] : String | semmle.label | call to method Zip [element] : String | | GlobalDataFlow.cs:85:22:85:136 | call to method First : String | semmle.label | call to method First : String | -| GlobalDataFlow.cs:85:23:85:66 | (...) ... [[]] : String | semmle.label | (...) ... [[]] : String | -| GlobalDataFlow.cs:85:57:85:66 | { ..., ... } [[]] : String | semmle.label | { ..., ... } [[]] : String | +| GlobalDataFlow.cs:85:23:85:66 | (...) ... [element] : String | semmle.label | (...) ... [element] : String | +| GlobalDataFlow.cs:85:57:85:66 | { ..., ... } [element] : String | semmle.label | { ..., ... } [element] : String | | GlobalDataFlow.cs:85:59:85:64 | access to local variable sink14 : String | semmle.label | access to local variable sink14 : String | | GlobalDataFlow.cs:86:15:86:20 | access to local variable sink15 | semmle.label | access to local variable sink15 | -| GlobalDataFlow.cs:87:22:87:128 | call to method Zip [[]] : String | semmle.label | call to method Zip [[]] : String | +| GlobalDataFlow.cs:87:22:87:128 | call to method Zip [element] : String | semmle.label | call to method Zip [element] : String | | GlobalDataFlow.cs:87:22:87:136 | call to method First : String | semmle.label | call to method First : String | -| GlobalDataFlow.cs:87:70:87:113 | (...) ... [[]] : String | semmle.label | (...) ... [[]] : String | -| GlobalDataFlow.cs:87:104:87:113 | { ..., ... } [[]] : String | semmle.label | { ..., ... } [[]] : String | +| GlobalDataFlow.cs:87:70:87:113 | (...) ... [element] : String | semmle.label | (...) ... [element] : String | +| GlobalDataFlow.cs:87:104:87:113 | { ..., ... } [element] : String | semmle.label | { ..., ... } [element] : String | | GlobalDataFlow.cs:87:106:87:111 | access to local variable sink15 : String | semmle.label | access to local variable sink15 : String | | GlobalDataFlow.cs:88:15:88:20 | access to local variable sink16 | semmle.label | access to local variable sink16 | | GlobalDataFlow.cs:136:21:136:34 | delegate call : String | semmle.label | delegate call : String | @@ -351,7 +355,7 @@ nodes | GlobalDataFlow.cs:158:15:158:19 | access to local variable sink7 | semmle.label | access to local variable sink7 | | GlobalDataFlow.cs:160:20:160:24 | SSA def(sink8) : String | semmle.label | SSA def(sink8) : String | | GlobalDataFlow.cs:161:15:161:19 | access to local variable sink8 | semmle.label | access to local variable sink8 | -| GlobalDataFlow.cs:162:22:162:31 | call to method OutYield [[]] : String | semmle.label | call to method OutYield [[]] : String | +| GlobalDataFlow.cs:162:22:162:31 | call to method OutYield [element] : String | semmle.label | call to method OutYield [element] : String | | GlobalDataFlow.cs:162:22:162:39 | call to method First : String | semmle.label | call to method First : String | | GlobalDataFlow.cs:163:15:163:20 | access to local variable sink12 | semmle.label | access to local variable sink12 | | GlobalDataFlow.cs:164:22:164:43 | call to method TaintedParam : String | semmle.label | call to method TaintedParam : String | @@ -359,38 +363,38 @@ nodes | GlobalDataFlow.cs:180:35:180:48 | "taint source" : String | semmle.label | "taint source" : String | | GlobalDataFlow.cs:181:21:181:26 | delegate call : String | semmle.label | delegate call : String | | GlobalDataFlow.cs:182:15:182:19 | access to local variable sink9 | semmle.label | access to local variable sink9 | -| GlobalDataFlow.cs:190:22:190:42 | object creation of type Lazy [Value] : String | semmle.label | object creation of type Lazy [Value] : String | +| GlobalDataFlow.cs:190:22:190:42 | object creation of type Lazy [property Value] : String | semmle.label | object creation of type Lazy [property Value] : String | | GlobalDataFlow.cs:190:22:190:48 | access to property Value : String | semmle.label | access to property Value : String | | GlobalDataFlow.cs:191:15:191:20 | access to local variable sink10 | semmle.label | access to local variable sink10 | | GlobalDataFlow.cs:198:22:198:32 | access to property OutProperty : String | semmle.label | access to property OutProperty : String | | GlobalDataFlow.cs:199:15:199:20 | access to local variable sink19 | semmle.label | access to local variable sink19 | -| GlobalDataFlow.cs:208:38:208:61 | array creation of type String[] [[]] : String | semmle.label | array creation of type String[] [[]] : String | -| GlobalDataFlow.cs:208:38:208:75 | call to method AsQueryable [[]] : String | semmle.label | call to method AsQueryable [[]] : String | -| GlobalDataFlow.cs:208:44:208:61 | { ..., ... } [[]] : String | semmle.label | { ..., ... } [[]] : String | +| GlobalDataFlow.cs:208:38:208:61 | array creation of type String[] [element] : String | semmle.label | array creation of type String[] [element] : String | +| GlobalDataFlow.cs:208:38:208:75 | call to method AsQueryable [element] : String | semmle.label | call to method AsQueryable [element] : String | +| GlobalDataFlow.cs:208:44:208:61 | { ..., ... } [element] : String | semmle.label | { ..., ... } [element] : String | | GlobalDataFlow.cs:208:46:208:59 | "taint source" : String | semmle.label | "taint source" : String | | GlobalDataFlow.cs:211:35:211:45 | sinkParam10 : String | semmle.label | sinkParam10 : String | | GlobalDataFlow.cs:211:58:211:68 | access to parameter sinkParam10 | semmle.label | access to parameter sinkParam10 | | GlobalDataFlow.cs:212:71:212:71 | x : String | semmle.label | x : String | | GlobalDataFlow.cs:212:89:212:89 | access to parameter x : String | semmle.label | access to parameter x : String | -| GlobalDataFlow.cs:213:22:213:28 | access to local variable tainted [[]] : String | semmle.label | access to local variable tainted [[]] : String | -| GlobalDataFlow.cs:213:22:213:39 | call to method Select [[]] : String | semmle.label | call to method Select [[]] : String | +| GlobalDataFlow.cs:213:22:213:28 | access to local variable tainted [element] : String | semmle.label | access to local variable tainted [element] : String | +| GlobalDataFlow.cs:213:22:213:39 | call to method Select [element] : String | semmle.label | call to method Select [element] : String | | GlobalDataFlow.cs:213:22:213:47 | call to method First : String | semmle.label | call to method First : String | | GlobalDataFlow.cs:214:15:214:20 | access to local variable sink24 | semmle.label | access to local variable sink24 | -| GlobalDataFlow.cs:215:22:215:28 | access to local variable tainted [[]] : String | semmle.label | access to local variable tainted [[]] : String | -| GlobalDataFlow.cs:215:22:215:39 | call to method Select [[]] : String | semmle.label | call to method Select [[]] : String | +| GlobalDataFlow.cs:215:22:215:28 | access to local variable tainted [element] : String | semmle.label | access to local variable tainted [element] : String | +| GlobalDataFlow.cs:215:22:215:39 | call to method Select [element] : String | semmle.label | call to method Select [element] : String | | GlobalDataFlow.cs:215:22:215:47 | call to method First : String | semmle.label | call to method First : String | | GlobalDataFlow.cs:216:15:216:20 | access to local variable sink25 | semmle.label | access to local variable sink25 | -| GlobalDataFlow.cs:217:22:217:28 | access to local variable tainted [[]] : String | semmle.label | access to local variable tainted [[]] : String | -| GlobalDataFlow.cs:217:22:217:49 | call to method Select [[]] : String | semmle.label | call to method Select [[]] : String | +| GlobalDataFlow.cs:217:22:217:28 | access to local variable tainted [element] : String | semmle.label | access to local variable tainted [element] : String | +| GlobalDataFlow.cs:217:22:217:49 | call to method Select [element] : String | semmle.label | call to method Select [element] : String | | GlobalDataFlow.cs:217:22:217:57 | call to method First : String | semmle.label | call to method First : String | | GlobalDataFlow.cs:218:15:218:20 | access to local variable sink26 | semmle.label | access to local variable sink26 | -| GlobalDataFlow.cs:238:20:238:49 | call to method Run [Result] : String | semmle.label | call to method Run [Result] : String | +| GlobalDataFlow.cs:238:20:238:49 | call to method Run [property Result] : String | semmle.label | call to method Run [property Result] : String | | GlobalDataFlow.cs:238:35:238:48 | "taint source" : String | semmle.label | "taint source" : String | -| GlobalDataFlow.cs:239:22:239:25 | access to local variable task [Result] : String | semmle.label | access to local variable task [Result] : String | +| GlobalDataFlow.cs:239:22:239:25 | access to local variable task [property Result] : String | semmle.label | access to local variable task [property Result] : String | | GlobalDataFlow.cs:239:22:239:32 | access to property Result : String | semmle.label | access to property Result : String | | GlobalDataFlow.cs:240:15:240:20 | access to local variable sink41 | semmle.label | access to local variable sink41 | | GlobalDataFlow.cs:241:22:241:31 | await ... : String | semmle.label | await ... : String | -| GlobalDataFlow.cs:241:28:241:31 | access to local variable task [Result] : String | semmle.label | access to local variable task [Result] : String | +| GlobalDataFlow.cs:241:28:241:31 | access to local variable task [property Result] : String | semmle.label | access to local variable task [property Result] : String | | GlobalDataFlow.cs:242:15:242:20 | access to local variable sink42 | semmle.label | access to local variable sink42 | | GlobalDataFlow.cs:254:26:254:35 | sinkParam0 : String | semmle.label | sinkParam0 : String | | GlobalDataFlow.cs:256:16:256:25 | access to parameter sinkParam0 : String | semmle.label | access to parameter sinkParam0 : String | @@ -435,15 +439,20 @@ nodes | GlobalDataFlow.cs:424:9:424:11 | value : String | semmle.label | value : String | | GlobalDataFlow.cs:424:41:424:46 | access to local variable sink20 | semmle.label | access to local variable sink20 | | GlobalDataFlow.cs:435:22:435:35 | "taint source" : String | semmle.label | "taint source" : String | -| GlobalDataFlow.cs:471:20:471:49 | call to method Run [Result] : String | semmle.label | call to method Run [Result] : String | +| GlobalDataFlow.cs:471:20:471:49 | call to method Run [property Result] : String | semmle.label | call to method Run [property Result] : String | | GlobalDataFlow.cs:471:35:471:48 | "taint source" : String | semmle.label | "taint source" : String | -| GlobalDataFlow.cs:472:25:472:28 | access to local variable task [Result] : String | semmle.label | access to local variable task [Result] : String | -| GlobalDataFlow.cs:472:25:472:50 | call to method ConfigureAwait [m_configuredTaskAwaiter, m_task, Result] : String | semmle.label | call to method ConfigureAwait [m_configuredTaskAwaiter, m_task, Result] : String | -| GlobalDataFlow.cs:473:23:473:31 | access to local variable awaitable [m_configuredTaskAwaiter, m_task, Result] : String | semmle.label | access to local variable awaitable [m_configuredTaskAwaiter, m_task, Result] : String | -| GlobalDataFlow.cs:473:23:473:44 | call to method GetAwaiter [m_task, Result] : String | semmle.label | call to method GetAwaiter [m_task, Result] : String | -| GlobalDataFlow.cs:474:22:474:28 | access to local variable awaiter [m_task, Result] : String | semmle.label | access to local variable awaiter [m_task, Result] : String | +| GlobalDataFlow.cs:472:25:472:28 | access to local variable task [property Result] : String | semmle.label | access to local variable task [property Result] : String | +| GlobalDataFlow.cs:472:25:472:50 | call to method ConfigureAwait [field m_configuredTaskAwaiter, field m_task, property Result] : String | semmle.label | call to method ConfigureAwait [field m_configuredTaskAwaiter, field m_task, property Result] : String | +| GlobalDataFlow.cs:473:23:473:31 | access to local variable awaitable [field m_configuredTaskAwaiter, field m_task, property Result] : String | semmle.label | access to local variable awaitable [field m_configuredTaskAwaiter, field m_task, property Result] : String | +| GlobalDataFlow.cs:473:23:473:44 | call to method GetAwaiter [field m_task, property Result] : String | semmle.label | call to method GetAwaiter [field m_task, property Result] : String | +| GlobalDataFlow.cs:474:22:474:28 | access to local variable awaiter [field m_task, property Result] : String | semmle.label | access to local variable awaiter [field m_task, property Result] : String | | GlobalDataFlow.cs:474:22:474:40 | call to method GetResult : String | semmle.label | call to method GetResult : String | | GlobalDataFlow.cs:475:15:475:20 | access to local variable sink45 | semmle.label | access to local variable sink45 | +| GlobalDataFlow.cs:480:53:480:55 | arg : String | semmle.label | arg : String | +| GlobalDataFlow.cs:483:21:483:21 | s : String | semmle.label | s : String | +| GlobalDataFlow.cs:483:32:483:32 | access to parameter s | semmle.label | access to parameter s | +| GlobalDataFlow.cs:484:15:484:17 | access to parameter arg : String | semmle.label | access to parameter arg : String | +| GlobalDataFlow.cs:487:27:487:40 | "taint source" : String | semmle.label | "taint source" : String | | Splitting.cs:3:28:3:34 | tainted : String | semmle.label | tainted : String | | Splitting.cs:8:17:8:31 | [b (line 3): false] call to method Return : String | semmle.label | [b (line 3): false] call to method Return : String | | Splitting.cs:8:17:8:31 | [b (line 3): true] call to method Return : String | semmle.label | [b (line 3): true] call to method Return : String | @@ -520,6 +529,7 @@ nodes | GlobalDataFlow.cs:182:15:182:19 | access to local variable sink9 | GlobalDataFlow.cs:180:35:180:48 | "taint source" : String | GlobalDataFlow.cs:182:15:182:19 | access to local variable sink9 | access to local variable sink9 | | Splitting.cs:11:19:11:19 | access to local variable x | Splitting.cs:3:28:3:34 | tainted : String | Splitting.cs:11:19:11:19 | access to local variable x | access to local variable x | | Splitting.cs:34:19:34:19 | access to local variable x | Splitting.cs:24:28:24:34 | tainted : String | Splitting.cs:34:19:34:19 | access to local variable x | access to local variable x | +| GlobalDataFlow.cs:483:32:483:32 | access to parameter s | GlobalDataFlow.cs:487:27:487:40 | "taint source" : String | GlobalDataFlow.cs:483:32:483:32 | access to parameter s | access to parameter s | | Capture.cs:57:27:57:32 | access to parameter sink39 | Capture.cs:7:20:7:26 | tainted : String | Capture.cs:57:27:57:32 | access to parameter sink39 | access to parameter sink39 | | GlobalDataFlow.cs:257:15:257:24 | access to parameter sinkParam0 | GlobalDataFlow.cs:18:27:18:40 | "taint source" : String | GlobalDataFlow.cs:257:15:257:24 | access to parameter sinkParam0 | access to parameter sinkParam0 | | GlobalDataFlow.cs:262:15:262:24 | access to parameter sinkParam1 | GlobalDataFlow.cs:18:27:18:40 | "taint source" : String | GlobalDataFlow.cs:262:15:262:24 | access to parameter sinkParam1 | access to parameter sinkParam1 | diff --git a/csharp/ql/test/library-tests/dataflow/global/GetAnOutNode.expected b/csharp/ql/test/library-tests/dataflow/global/GetAnOutNode.expected index 5b4957a19e9..ce0ed3c75af 100644 --- a/csharp/ql/test/library-tests/dataflow/global/GetAnOutNode.expected +++ b/csharp/ql/test/library-tests/dataflow/global/GetAnOutNode.expected @@ -1,364 +1,313 @@ -| Capture.cs:33:9:33:40 | call to method Select | return | Capture.cs:33:9:33:40 | call to method Select | -| Capture.cs:33:9:33:40 | call to method Select | yield return | Capture.cs:33:9:33:40 | call to method Select | -| Capture.cs:33:9:33:50 | call to method ToArray | return | Capture.cs:33:9:33:50 | call to method ToArray | +| Capture.cs:33:9:33:40 | call to method Select | normal | Capture.cs:33:9:33:40 | call to method Select | +| Capture.cs:33:9:33:50 | call to method ToArray | normal | Capture.cs:33:9:33:50 | call to method ToArray | | Capture.cs:71:9:71:21 | call to local function CaptureOut1 | captured sink30 | Capture.cs:71:9:71:21 | SSA call def(sink30) | | Capture.cs:83:9:83:21 | [transitive] call to local function CaptureOut2 | captured sink31 | Capture.cs:83:9:83:21 | SSA call def(sink31) | | Capture.cs:92:9:92:41 | [transitive] call to method Select | captured sink32 | Capture.cs:92:9:92:41 | SSA call def(sink32) | -| Capture.cs:92:9:92:41 | call to method Select | return | Capture.cs:92:9:92:41 | call to method Select | -| Capture.cs:92:9:92:41 | call to method Select | yield return | Capture.cs:92:9:92:41 | call to method Select | -| Capture.cs:92:9:92:51 | call to method ToArray | return | Capture.cs:92:9:92:51 | call to method ToArray | +| Capture.cs:92:9:92:41 | call to method Select | normal | Capture.cs:92:9:92:41 | call to method Select | +| Capture.cs:92:9:92:51 | call to method ToArray | normal | Capture.cs:92:9:92:51 | call to method ToArray | | Capture.cs:121:9:121:35 | [transitive] call to local function CaptureOutMultipleLambdas | captured nonSink0 | Capture.cs:121:9:121:35 | SSA call def(nonSink0) | | Capture.cs:121:9:121:35 | [transitive] call to local function CaptureOutMultipleLambdas | captured sink40 | Capture.cs:121:9:121:35 | SSA call def(sink40) | | Capture.cs:132:9:132:25 | call to local function CaptureThrough1 | captured sink33 | Capture.cs:132:9:132:25 | SSA call def(sink33) | | Capture.cs:144:9:144:25 | [transitive] call to local function CaptureThrough2 | captured sink34 | Capture.cs:144:9:144:25 | SSA call def(sink34) | | Capture.cs:153:9:153:45 | [transitive] call to method Select | captured sink35 | Capture.cs:153:9:153:45 | SSA call def(sink35) | -| Capture.cs:153:9:153:45 | call to method Select | return | Capture.cs:153:9:153:45 | call to method Select | -| Capture.cs:153:9:153:45 | call to method Select | yield return | Capture.cs:153:9:153:45 | call to method Select | -| Capture.cs:153:9:153:55 | call to method ToArray | return | Capture.cs:153:9:153:55 | call to method ToArray | -| Capture.cs:160:22:160:38 | call to local function CaptureThrough4 | return | Capture.cs:160:22:160:38 | call to local function CaptureThrough4 | +| Capture.cs:153:9:153:45 | call to method Select | normal | Capture.cs:153:9:153:45 | call to method Select | +| Capture.cs:153:9:153:55 | call to method ToArray | normal | Capture.cs:153:9:153:55 | call to method ToArray | +| Capture.cs:160:22:160:38 | call to local function CaptureThrough4 | normal | Capture.cs:160:22:160:38 | call to local function CaptureThrough4 | | Capture.cs:168:9:168:32 | call to local function CaptureThrough5 | captured sink37 | Capture.cs:168:9:168:32 | SSA call def(sink37) | -| Capture.cs:191:20:191:22 | call to local function M | return | Capture.cs:191:20:191:22 | call to local function M | -| Capture.cs:194:22:194:32 | call to local function Id | return | Capture.cs:194:22:194:32 | call to local function Id | -| Capture.cs:196:20:196:25 | call to local function Id | return | Capture.cs:196:20:196:25 | call to local function Id | -| GlobalDataFlow.cs:26:9:26:26 | access to property SinkProperty0 | return | GlobalDataFlow.cs:26:9:26:26 | access to property SinkProperty0 | -| GlobalDataFlow.cs:27:15:27:32 | access to property SinkProperty0 | return | GlobalDataFlow.cs:27:15:27:32 | access to property SinkProperty0 | -| GlobalDataFlow.cs:30:9:30:29 | access to property NonSinkProperty0 | return | GlobalDataFlow.cs:30:9:30:29 | access to property NonSinkProperty0 | -| GlobalDataFlow.cs:31:15:31:35 | access to property NonSinkProperty0 | return | GlobalDataFlow.cs:31:15:31:35 | access to property NonSinkProperty0 | -| GlobalDataFlow.cs:32:9:32:29 | access to property NonSinkProperty1 | return | GlobalDataFlow.cs:32:9:32:29 | access to property NonSinkProperty1 | -| GlobalDataFlow.cs:33:15:33:35 | access to property NonSinkProperty1 | return | GlobalDataFlow.cs:33:15:33:35 | access to property NonSinkProperty1 | -| GlobalDataFlow.cs:36:13:36:30 | access to property SinkProperty0 | return | GlobalDataFlow.cs:36:13:36:30 | access to property SinkProperty0 | -| GlobalDataFlow.cs:37:26:37:58 | call to method GetMethod | qualifier | GlobalDataFlow.cs:37:26:37:41 | [post] typeof(...) | -| GlobalDataFlow.cs:37:26:37:58 | call to method GetMethod | return | GlobalDataFlow.cs:37:26:37:58 | call to method GetMethod | -| GlobalDataFlow.cs:38:35:38:52 | access to property SinkProperty0 | return | GlobalDataFlow.cs:38:35:38:52 | access to property SinkProperty0 | -| GlobalDataFlow.cs:39:9:39:37 | call to method Invoke | return | GlobalDataFlow.cs:39:9:39:37 | call to method Invoke | -| GlobalDataFlow.cs:46:13:46:30 | access to property SinkProperty0 | return | GlobalDataFlow.cs:46:13:46:30 | access to property SinkProperty0 | -| GlobalDataFlow.cs:53:20:53:37 | access to property SinkProperty0 | return | GlobalDataFlow.cs:53:20:53:37 | access to property SinkProperty0 | -| GlobalDataFlow.cs:54:28:54:45 | access to property SinkProperty0 | return | GlobalDataFlow.cs:54:28:54:45 | access to property SinkProperty0 | -| GlobalDataFlow.cs:55:44:55:61 | access to property SinkProperty0 | return | GlobalDataFlow.cs:55:44:55:61 | access to property SinkProperty0 | -| GlobalDataFlow.cs:56:28:56:45 | access to property SinkProperty0 | return | GlobalDataFlow.cs:56:28:56:45 | access to property SinkProperty0 | -| GlobalDataFlow.cs:58:35:58:52 | access to property SinkProperty0 | return | GlobalDataFlow.cs:58:35:58:52 | access to property SinkProperty0 | -| GlobalDataFlow.cs:65:9:65:18 | access to property InProperty | qualifier | GlobalDataFlow.cs:65:9:65:18 | [post] this access | -| GlobalDataFlow.cs:65:9:65:18 | access to property InProperty | return | GlobalDataFlow.cs:65:9:65:18 | access to property InProperty | -| GlobalDataFlow.cs:65:22:65:39 | access to property SinkProperty0 | return | GlobalDataFlow.cs:65:22:65:39 | access to property SinkProperty0 | -| GlobalDataFlow.cs:68:9:68:21 | access to property NonInProperty | qualifier | GlobalDataFlow.cs:68:9:68:21 | [post] this access | -| GlobalDataFlow.cs:68:9:68:21 | access to property NonInProperty | return | GlobalDataFlow.cs:68:9:68:21 | access to property NonInProperty | -| GlobalDataFlow.cs:71:21:71:46 | call to method Return | return | GlobalDataFlow.cs:71:21:71:46 | call to method Return | -| GlobalDataFlow.cs:71:28:71:45 | access to property SinkProperty0 | return | GlobalDataFlow.cs:71:28:71:45 | access to property SinkProperty0 | -| GlobalDataFlow.cs:73:29:73:64 | call to method GetMethod | qualifier | GlobalDataFlow.cs:73:29:73:44 | [post] typeof(...) | -| GlobalDataFlow.cs:73:29:73:64 | call to method GetMethod | return | GlobalDataFlow.cs:73:29:73:64 | call to method GetMethod | -| GlobalDataFlow.cs:73:29:73:101 | call to method Invoke | return | GlobalDataFlow.cs:73:29:73:101 | call to method Invoke | -| GlobalDataFlow.cs:76:9:76:46 | call to method ReturnOut | out | GlobalDataFlow.cs:76:30:76:34 | SSA def(sink2) | -| GlobalDataFlow.cs:76:9:76:46 | call to method ReturnOut | ref | GlobalDataFlow.cs:76:30:76:34 | SSA def(sink2) | -| GlobalDataFlow.cs:79:9:79:46 | call to method ReturnRef | out | GlobalDataFlow.cs:79:30:79:34 | SSA def(sink3) | -| GlobalDataFlow.cs:79:9:79:46 | call to method ReturnRef | ref | GlobalDataFlow.cs:79:30:79:34 | SSA def(sink3) | -| GlobalDataFlow.cs:81:22:81:85 | call to method SelectEven | return | GlobalDataFlow.cs:81:22:81:85 | call to method SelectEven | -| GlobalDataFlow.cs:81:22:81:85 | call to method SelectEven | yield return | GlobalDataFlow.cs:81:22:81:85 | call to method SelectEven | -| GlobalDataFlow.cs:81:22:81:93 | call to method First | return | GlobalDataFlow.cs:81:22:81:93 | call to method First | -| GlobalDataFlow.cs:83:22:83:87 | call to method Select | return | GlobalDataFlow.cs:83:22:83:87 | call to method Select | -| GlobalDataFlow.cs:83:22:83:87 | call to method Select | yield return | GlobalDataFlow.cs:83:22:83:87 | call to method Select | -| GlobalDataFlow.cs:83:22:83:95 | call to method First | return | GlobalDataFlow.cs:83:22:83:95 | call to method First | -| GlobalDataFlow.cs:85:22:85:128 | call to method Zip | return | GlobalDataFlow.cs:85:22:85:128 | call to method Zip | -| GlobalDataFlow.cs:85:22:85:128 | call to method Zip | yield return | GlobalDataFlow.cs:85:22:85:128 | call to method Zip | -| GlobalDataFlow.cs:85:22:85:136 | call to method First | return | GlobalDataFlow.cs:85:22:85:136 | call to method First | -| GlobalDataFlow.cs:87:22:87:128 | call to method Zip | return | GlobalDataFlow.cs:87:22:87:128 | call to method Zip | -| GlobalDataFlow.cs:87:22:87:128 | call to method Zip | yield return | GlobalDataFlow.cs:87:22:87:128 | call to method Zip | -| GlobalDataFlow.cs:87:22:87:136 | call to method First | return | GlobalDataFlow.cs:87:22:87:136 | call to method First | -| GlobalDataFlow.cs:89:22:89:110 | call to method Aggregate | return | GlobalDataFlow.cs:89:22:89:110 | call to method Aggregate | -| GlobalDataFlow.cs:91:22:91:110 | call to method Aggregate | return | GlobalDataFlow.cs:91:22:91:110 | call to method Aggregate | -| GlobalDataFlow.cs:94:9:94:42 | call to method TryParse | out | GlobalDataFlow.cs:94:36:94:41 | SSA def(sink21) | -| GlobalDataFlow.cs:94:9:94:42 | call to method TryParse | ref | GlobalDataFlow.cs:94:36:94:41 | SSA def(sink21) | -| GlobalDataFlow.cs:94:9:94:42 | call to method TryParse | return | GlobalDataFlow.cs:94:9:94:42 | call to method TryParse | -| GlobalDataFlow.cs:97:9:97:41 | call to method TryParse | out | GlobalDataFlow.cs:97:35:97:40 | SSA def(sink22) | -| GlobalDataFlow.cs:97:9:97:41 | call to method TryParse | ref | GlobalDataFlow.cs:97:35:97:40 | SSA def(sink22) | -| GlobalDataFlow.cs:97:9:97:41 | call to method TryParse | return | GlobalDataFlow.cs:97:9:97:41 | call to method TryParse | -| GlobalDataFlow.cs:101:24:101:33 | call to method Return | return | GlobalDataFlow.cs:101:24:101:33 | call to method Return | -| GlobalDataFlow.cs:103:28:103:63 | call to method GetMethod | qualifier | GlobalDataFlow.cs:103:28:103:43 | [post] typeof(...) | -| GlobalDataFlow.cs:103:28:103:63 | call to method GetMethod | return | GlobalDataFlow.cs:103:28:103:63 | call to method GetMethod | -| GlobalDataFlow.cs:103:28:103:103 | call to method Invoke | return | GlobalDataFlow.cs:103:28:103:103 | call to method Invoke | -| GlobalDataFlow.cs:105:9:105:49 | call to method ReturnOut | out | GlobalDataFlow.cs:105:27:105:34 | SSA def(nonSink0) | -| GlobalDataFlow.cs:105:9:105:49 | call to method ReturnOut | ref | GlobalDataFlow.cs:105:27:105:34 | SSA def(nonSink0) | -| GlobalDataFlow.cs:107:9:107:49 | call to method ReturnOut | out | GlobalDataFlow.cs:107:41:107:48 | SSA def(nonSink0) | -| GlobalDataFlow.cs:109:9:109:49 | call to method ReturnRef | out | GlobalDataFlow.cs:109:27:109:34 | SSA def(nonSink0) | -| GlobalDataFlow.cs:109:9:109:49 | call to method ReturnRef | ref | GlobalDataFlow.cs:109:27:109:34 | SSA def(nonSink0) | -| GlobalDataFlow.cs:111:9:111:49 | call to method ReturnRef | out | GlobalDataFlow.cs:111:30:111:34 | SSA def(sink1) | -| GlobalDataFlow.cs:111:9:111:49 | call to method ReturnRef | ref | GlobalDataFlow.cs:111:30:111:34 | SSA def(sink1) | -| GlobalDataFlow.cs:113:20:113:86 | call to method SelectEven | return | GlobalDataFlow.cs:113:20:113:86 | call to method SelectEven | -| GlobalDataFlow.cs:113:20:113:86 | call to method SelectEven | yield return | GlobalDataFlow.cs:113:20:113:86 | call to method SelectEven | -| GlobalDataFlow.cs:113:20:113:94 | call to method First | return | GlobalDataFlow.cs:113:20:113:94 | call to method First | -| GlobalDataFlow.cs:115:20:115:82 | call to method Select | return | GlobalDataFlow.cs:115:20:115:82 | call to method Select | -| GlobalDataFlow.cs:115:20:115:82 | call to method Select | yield return | GlobalDataFlow.cs:115:20:115:82 | call to method Select | -| GlobalDataFlow.cs:115:20:115:90 | call to method First | return | GlobalDataFlow.cs:115:20:115:90 | call to method First | -| GlobalDataFlow.cs:117:20:117:126 | call to method Zip | return | GlobalDataFlow.cs:117:20:117:126 | call to method Zip | -| GlobalDataFlow.cs:117:20:117:126 | call to method Zip | yield return | GlobalDataFlow.cs:117:20:117:126 | call to method Zip | -| GlobalDataFlow.cs:117:20:117:134 | call to method First | return | GlobalDataFlow.cs:117:20:117:134 | call to method First | -| GlobalDataFlow.cs:119:20:119:126 | call to method Zip | return | GlobalDataFlow.cs:119:20:119:126 | call to method Zip | -| GlobalDataFlow.cs:119:20:119:126 | call to method Zip | yield return | GlobalDataFlow.cs:119:20:119:126 | call to method Zip | -| GlobalDataFlow.cs:119:20:119:134 | call to method First | return | GlobalDataFlow.cs:119:20:119:134 | call to method First | -| GlobalDataFlow.cs:121:20:121:104 | call to method Aggregate | return | GlobalDataFlow.cs:121:20:121:104 | call to method Aggregate | -| GlobalDataFlow.cs:123:20:123:109 | call to method Aggregate | return | GlobalDataFlow.cs:123:20:123:109 | call to method Aggregate | -| GlobalDataFlow.cs:125:20:125:107 | call to method Aggregate | return | GlobalDataFlow.cs:125:20:125:107 | call to method Aggregate | -| GlobalDataFlow.cs:128:9:128:46 | call to method TryParse | out | GlobalDataFlow.cs:128:38:128:45 | SSA def(nonSink2) | -| GlobalDataFlow.cs:128:9:128:46 | call to method TryParse | ref | GlobalDataFlow.cs:128:38:128:45 | SSA def(nonSink2) | -| GlobalDataFlow.cs:128:9:128:46 | call to method TryParse | return | GlobalDataFlow.cs:128:9:128:46 | call to method TryParse | -| GlobalDataFlow.cs:131:9:131:45 | call to method TryParse | out | GlobalDataFlow.cs:131:37:131:44 | SSA def(nonSink3) | -| GlobalDataFlow.cs:131:9:131:45 | call to method TryParse | ref | GlobalDataFlow.cs:131:37:131:44 | SSA def(nonSink3) | -| GlobalDataFlow.cs:131:9:131:45 | call to method TryParse | return | GlobalDataFlow.cs:131:9:131:45 | call to method TryParse | -| GlobalDataFlow.cs:135:45:135:64 | call to method ApplyFunc | return | GlobalDataFlow.cs:135:45:135:64 | call to method ApplyFunc | -| GlobalDataFlow.cs:136:21:136:34 | delegate call | return | GlobalDataFlow.cs:136:21:136:34 | delegate call | -| GlobalDataFlow.cs:140:20:140:36 | delegate call | return | GlobalDataFlow.cs:140:20:140:36 | delegate call | -| GlobalDataFlow.cs:144:21:144:44 | call to method ApplyFunc | return | GlobalDataFlow.cs:144:21:144:44 | call to method ApplyFunc | -| GlobalDataFlow.cs:148:20:148:40 | call to method ApplyFunc | return | GlobalDataFlow.cs:148:20:148:40 | call to method ApplyFunc | -| GlobalDataFlow.cs:150:20:150:44 | call to method ApplyFunc | return | GlobalDataFlow.cs:150:20:150:44 | call to method ApplyFunc | -| GlobalDataFlow.cs:154:21:154:25 | call to method Out | qualifier | GlobalDataFlow.cs:154:21:154:25 | [post] this access | -| GlobalDataFlow.cs:154:21:154:25 | call to method Out | return | GlobalDataFlow.cs:154:21:154:25 | call to method Out | -| GlobalDataFlow.cs:157:9:157:25 | call to method OutOut | out | GlobalDataFlow.cs:157:20:157:24 | SSA def(sink7) | -| GlobalDataFlow.cs:157:9:157:25 | call to method OutOut | qualifier | GlobalDataFlow.cs:157:9:157:25 | [post] this access | -| GlobalDataFlow.cs:157:9:157:25 | call to method OutOut | ref | GlobalDataFlow.cs:157:20:157:24 | SSA def(sink7) | -| GlobalDataFlow.cs:160:9:160:25 | call to method OutRef | out | GlobalDataFlow.cs:160:20:160:24 | SSA def(sink8) | -| GlobalDataFlow.cs:160:9:160:25 | call to method OutRef | qualifier | GlobalDataFlow.cs:160:9:160:25 | [post] this access | -| GlobalDataFlow.cs:160:9:160:25 | call to method OutRef | ref | GlobalDataFlow.cs:160:20:160:24 | SSA def(sink8) | -| GlobalDataFlow.cs:162:22:162:31 | call to method OutYield | qualifier | GlobalDataFlow.cs:162:22:162:31 | [post] this access | -| GlobalDataFlow.cs:162:22:162:31 | call to method OutYield | return | GlobalDataFlow.cs:162:22:162:31 | call to method OutYield | -| GlobalDataFlow.cs:162:22:162:31 | call to method OutYield | yield return | GlobalDataFlow.cs:162:22:162:31 | call to method OutYield | -| GlobalDataFlow.cs:162:22:162:39 | call to method First | return | GlobalDataFlow.cs:162:22:162:39 | call to method First | -| GlobalDataFlow.cs:164:22:164:43 | call to method TaintedParam | return | GlobalDataFlow.cs:164:22:164:43 | call to method TaintedParam | -| GlobalDataFlow.cs:168:20:168:27 | call to method NonOut | qualifier | GlobalDataFlow.cs:168:20:168:27 | [post] this access | -| GlobalDataFlow.cs:168:20:168:27 | call to method NonOut | return | GlobalDataFlow.cs:168:20:168:27 | call to method NonOut | -| GlobalDataFlow.cs:170:9:170:31 | call to method NonOutOut | out | GlobalDataFlow.cs:170:23:170:30 | SSA def(nonSink0) | -| GlobalDataFlow.cs:170:9:170:31 | call to method NonOutOut | qualifier | GlobalDataFlow.cs:170:9:170:31 | [post] this access | -| GlobalDataFlow.cs:170:9:170:31 | call to method NonOutOut | ref | GlobalDataFlow.cs:170:23:170:30 | SSA def(nonSink0) | -| GlobalDataFlow.cs:172:9:172:31 | call to method NonOutRef | out | GlobalDataFlow.cs:172:23:172:30 | SSA def(nonSink0) | -| GlobalDataFlow.cs:172:9:172:31 | call to method NonOutRef | qualifier | GlobalDataFlow.cs:172:9:172:31 | [post] this access | -| GlobalDataFlow.cs:172:9:172:31 | call to method NonOutRef | ref | GlobalDataFlow.cs:172:23:172:30 | SSA def(nonSink0) | -| GlobalDataFlow.cs:174:20:174:32 | call to method NonOutYield | qualifier | GlobalDataFlow.cs:174:20:174:32 | [post] this access | -| GlobalDataFlow.cs:174:20:174:32 | call to method NonOutYield | return | GlobalDataFlow.cs:174:20:174:32 | call to method NonOutYield | -| GlobalDataFlow.cs:174:20:174:32 | call to method NonOutYield | yield return | GlobalDataFlow.cs:174:20:174:32 | call to method NonOutYield | -| GlobalDataFlow.cs:174:20:174:40 | call to method First | return | GlobalDataFlow.cs:174:20:174:40 | call to method First | -| GlobalDataFlow.cs:176:20:176:44 | call to method NonTaintedParam | return | GlobalDataFlow.cs:176:20:176:44 | call to method NonTaintedParam | -| GlobalDataFlow.cs:181:21:181:26 | delegate call | return | GlobalDataFlow.cs:181:21:181:26 | delegate call | -| GlobalDataFlow.cs:186:20:186:27 | delegate call | return | GlobalDataFlow.cs:186:20:186:27 | delegate call | -| GlobalDataFlow.cs:190:22:190:42 | object creation of type Lazy | return | GlobalDataFlow.cs:190:22:190:42 | object creation of type Lazy | -| GlobalDataFlow.cs:190:22:190:48 | access to property Value | qualifier | GlobalDataFlow.cs:190:22:190:42 | [post] object creation of type Lazy | -| GlobalDataFlow.cs:190:22:190:48 | access to property Value | return | GlobalDataFlow.cs:190:22:190:48 | access to property Value | -| GlobalDataFlow.cs:194:20:194:43 | object creation of type Lazy | return | GlobalDataFlow.cs:194:20:194:43 | object creation of type Lazy | -| GlobalDataFlow.cs:194:20:194:49 | access to property Value | qualifier | GlobalDataFlow.cs:194:20:194:43 | [post] object creation of type Lazy | -| GlobalDataFlow.cs:194:20:194:49 | access to property Value | return | GlobalDataFlow.cs:194:20:194:49 | access to property Value | -| GlobalDataFlow.cs:198:22:198:32 | access to property OutProperty | qualifier | GlobalDataFlow.cs:198:22:198:32 | [post] this access | -| GlobalDataFlow.cs:198:22:198:32 | access to property OutProperty | return | GlobalDataFlow.cs:198:22:198:32 | access to property OutProperty | -| GlobalDataFlow.cs:202:20:202:33 | access to property NonOutProperty | qualifier | GlobalDataFlow.cs:202:20:202:33 | [post] this access | -| GlobalDataFlow.cs:202:20:202:33 | access to property NonOutProperty | return | GlobalDataFlow.cs:202:20:202:33 | access to property NonOutProperty | -| GlobalDataFlow.cs:208:38:208:75 | call to method AsQueryable | return | GlobalDataFlow.cs:208:38:208:75 | call to method AsQueryable | -| GlobalDataFlow.cs:209:41:209:77 | call to method AsQueryable | return | GlobalDataFlow.cs:209:41:209:77 | call to method AsQueryable | -| GlobalDataFlow.cs:212:76:212:90 | call to method ReturnCheck2 | return | GlobalDataFlow.cs:212:76:212:90 | call to method ReturnCheck2 | -| GlobalDataFlow.cs:213:22:213:39 | call to method Select | return | GlobalDataFlow.cs:213:22:213:39 | call to method Select | -| GlobalDataFlow.cs:213:22:213:39 | call to method Select | yield return | GlobalDataFlow.cs:213:22:213:39 | call to method Select | -| GlobalDataFlow.cs:213:22:213:47 | call to method First | return | GlobalDataFlow.cs:213:22:213:47 | call to method First | -| GlobalDataFlow.cs:215:22:215:39 | call to method Select | return | GlobalDataFlow.cs:215:22:215:39 | call to method Select | -| GlobalDataFlow.cs:215:22:215:47 | call to method First | return | GlobalDataFlow.cs:215:22:215:47 | call to method First | -| GlobalDataFlow.cs:217:22:217:49 | call to method Select | return | GlobalDataFlow.cs:217:22:217:49 | call to method Select | -| GlobalDataFlow.cs:217:22:217:49 | call to method Select | yield return | GlobalDataFlow.cs:217:22:217:49 | call to method Select | -| GlobalDataFlow.cs:217:22:217:57 | call to method First | return | GlobalDataFlow.cs:217:22:217:57 | call to method First | -| GlobalDataFlow.cs:222:76:222:92 | call to method NonReturnCheck | return | GlobalDataFlow.cs:222:76:222:92 | call to method NonReturnCheck | -| GlobalDataFlow.cs:223:23:223:43 | call to method Select | return | GlobalDataFlow.cs:223:23:223:43 | call to method Select | -| GlobalDataFlow.cs:223:23:223:43 | call to method Select | yield return | GlobalDataFlow.cs:223:23:223:43 | call to method Select | -| GlobalDataFlow.cs:223:23:223:51 | call to method First | return | GlobalDataFlow.cs:223:23:223:51 | call to method First | -| GlobalDataFlow.cs:225:19:225:39 | call to method Select | return | GlobalDataFlow.cs:225:19:225:39 | call to method Select | -| GlobalDataFlow.cs:225:19:225:47 | call to method First | return | GlobalDataFlow.cs:225:19:225:47 | call to method First | -| GlobalDataFlow.cs:227:19:227:39 | call to method Select | return | GlobalDataFlow.cs:227:19:227:39 | call to method Select | -| GlobalDataFlow.cs:227:19:227:39 | call to method Select | yield return | GlobalDataFlow.cs:227:19:227:39 | call to method Select | -| GlobalDataFlow.cs:227:19:227:47 | call to method First | return | GlobalDataFlow.cs:227:19:227:47 | call to method First | -| GlobalDataFlow.cs:229:19:229:39 | call to method Select | return | GlobalDataFlow.cs:229:19:229:39 | call to method Select | -| GlobalDataFlow.cs:229:19:229:47 | call to method First | return | GlobalDataFlow.cs:229:19:229:47 | call to method First | -| GlobalDataFlow.cs:231:19:231:49 | call to method Select | return | GlobalDataFlow.cs:231:19:231:49 | call to method Select | -| GlobalDataFlow.cs:231:19:231:49 | call to method Select | yield return | GlobalDataFlow.cs:231:19:231:49 | call to method Select | -| GlobalDataFlow.cs:231:19:231:57 | call to method First | return | GlobalDataFlow.cs:231:19:231:57 | call to method First | -| GlobalDataFlow.cs:238:20:238:49 | call to method Run | return | GlobalDataFlow.cs:238:20:238:49 | call to method Run | -| GlobalDataFlow.cs:239:22:239:32 | access to property Result | qualifier | GlobalDataFlow.cs:239:22:239:25 | [post] access to local variable task | -| GlobalDataFlow.cs:239:22:239:32 | access to property Result | return | GlobalDataFlow.cs:239:22:239:32 | access to property Result | -| GlobalDataFlow.cs:245:16:245:33 | call to method Run | return | GlobalDataFlow.cs:245:16:245:33 | call to method Run | -| GlobalDataFlow.cs:246:24:246:34 | access to property Result | qualifier | GlobalDataFlow.cs:246:24:246:27 | [post] access to local variable task | -| GlobalDataFlow.cs:246:24:246:34 | access to property Result | return | GlobalDataFlow.cs:246:24:246:34 | access to property Result | -| GlobalDataFlow.cs:297:17:297:38 | call to method ApplyFunc | return | GlobalDataFlow.cs:297:17:297:38 | call to method ApplyFunc | -| GlobalDataFlow.cs:386:16:386:19 | delegate call | return | GlobalDataFlow.cs:386:16:386:19 | delegate call | -| GlobalDataFlow.cs:445:9:445:20 | call to method Append | qualifier | GlobalDataFlow.cs:445:9:445:10 | [post] access to parameter sb | -| GlobalDataFlow.cs:445:9:445:20 | call to method Append | return | GlobalDataFlow.cs:445:9:445:20 | call to method Append | -| GlobalDataFlow.cs:450:18:450:36 | object creation of type StringBuilder | return | GlobalDataFlow.cs:450:18:450:36 | object creation of type StringBuilder | -| GlobalDataFlow.cs:452:22:452:34 | call to method ToString | qualifier | GlobalDataFlow.cs:452:22:452:23 | [post] access to local variable sb | -| GlobalDataFlow.cs:452:22:452:34 | call to method ToString | return | GlobalDataFlow.cs:452:22:452:34 | call to method ToString | -| GlobalDataFlow.cs:455:9:455:18 | call to method Clear | qualifier | GlobalDataFlow.cs:455:9:455:10 | [post] access to local variable sb | -| GlobalDataFlow.cs:455:9:455:18 | call to method Clear | return | GlobalDataFlow.cs:455:9:455:18 | call to method Clear | -| GlobalDataFlow.cs:456:23:456:35 | call to method ToString | qualifier | GlobalDataFlow.cs:456:23:456:24 | [post] access to local variable sb | -| GlobalDataFlow.cs:456:23:456:35 | call to method ToString | return | GlobalDataFlow.cs:456:23:456:35 | call to method ToString | -| GlobalDataFlow.cs:462:22:462:65 | call to method Join | return | GlobalDataFlow.cs:462:22:462:65 | call to method Join | -| GlobalDataFlow.cs:465:23:465:65 | call to method Join | return | GlobalDataFlow.cs:465:23:465:65 | call to method Join | -| GlobalDataFlow.cs:471:20:471:49 | call to method Run | return | GlobalDataFlow.cs:471:20:471:49 | call to method Run | -| GlobalDataFlow.cs:472:25:472:50 | call to method ConfigureAwait | qualifier | GlobalDataFlow.cs:472:25:472:28 | [post] access to local variable task | -| GlobalDataFlow.cs:472:25:472:50 | call to method ConfigureAwait | return | GlobalDataFlow.cs:472:25:472:50 | call to method ConfigureAwait | -| GlobalDataFlow.cs:473:23:473:44 | call to method GetAwaiter | return | GlobalDataFlow.cs:473:23:473:44 | call to method GetAwaiter | -| GlobalDataFlow.cs:474:22:474:40 | call to method GetResult | return | GlobalDataFlow.cs:474:22:474:40 | call to method GetResult | -| GlobalDataFlow.cs:486:44:486:47 | delegate call | return | GlobalDataFlow.cs:486:44:486:47 | delegate call | -| Splitting.cs:8:17:8:31 | [b (line 3): false] call to method Return | return | Splitting.cs:8:17:8:31 | [b (line 3): false] call to method Return | -| Splitting.cs:8:17:8:31 | [b (line 3): true] call to method Return | return | Splitting.cs:8:17:8:31 | [b (line 3): true] call to method Return | -| Splitting.cs:20:22:20:30 | call to method Return | return | Splitting.cs:20:22:20:30 | call to method Return | -| Splitting.cs:21:21:21:33 | call to method Return | return | Splitting.cs:21:21:21:33 | call to method Return | -| Splitting.cs:30:9:30:13 | [b (line 24): false] dynamic access to element | qualifier | Splitting.cs:30:9:30:9 | [post] [b (line 24): false] access to local variable d | -| Splitting.cs:30:9:30:13 | [b (line 24): false] dynamic access to element | return | Splitting.cs:30:9:30:13 | [b (line 24): false] dynamic access to element | -| Splitting.cs:30:9:30:13 | [b (line 24): true] dynamic access to element | qualifier | Splitting.cs:30:9:30:9 | [post] [b (line 24): true] access to local variable d | -| Splitting.cs:30:9:30:13 | [b (line 24): true] dynamic access to element | return | Splitting.cs:30:9:30:13 | [b (line 24): true] dynamic access to element | -| Splitting.cs:31:17:31:26 | [b (line 24): false] dynamic access to element | qualifier | Splitting.cs:31:17:31:17 | [post] [b (line 24): false] access to local variable d | -| Splitting.cs:31:17:31:26 | [b (line 24): false] dynamic access to element | return | Splitting.cs:31:17:31:26 | [b (line 24): false] dynamic access to element | -| Splitting.cs:31:17:31:26 | [b (line 24): true] dynamic access to element | qualifier | Splitting.cs:31:17:31:17 | [post] [b (line 24): true] access to local variable d | -| Splitting.cs:31:17:31:26 | [b (line 24): true] dynamic access to element | return | Splitting.cs:31:17:31:26 | [b (line 24): true] dynamic access to element | -| Splitting.cs:32:9:32:16 | [b (line 24): false] dynamic call to method Check | return | Splitting.cs:32:9:32:16 | [b (line 24): false] dynamic call to method Check | -| Splitting.cs:32:9:32:16 | [b (line 24): true] dynamic call to method Check | return | Splitting.cs:32:9:32:16 | [b (line 24): true] dynamic call to method Check | -| Splitting.cs:34:13:34:20 | dynamic call to method Check | return | Splitting.cs:34:13:34:20 | dynamic call to method Check | -| This.cs:12:9:12:20 | call to method M | qualifier | This.cs:12:9:12:12 | [post] this access | -| This.cs:13:9:13:15 | call to method M | qualifier | This.cs:13:9:13:15 | [post] this access | -| This.cs:15:9:15:21 | call to method M | qualifier | This.cs:15:9:15:12 | [post] this access | -| This.cs:16:9:16:16 | call to method M | qualifier | This.cs:16:9:16:16 | [post] this access | -| This.cs:17:9:17:18 | object creation of type This | return | This.cs:17:9:17:18 | object creation of type This | -| This.cs:26:13:26:24 | call to method M | qualifier | This.cs:26:13:26:16 | [post] this access | -| This.cs:27:13:27:24 | call to method M | qualifier | This.cs:27:13:27:16 | [post] base access | -| This.cs:28:13:28:21 | object creation of type Sub | return | This.cs:28:13:28:21 | object creation of type Sub | -| file://:0:0:0:0 | [summary] delegate call, parameter 0 of ContinueWith | return | file://:0:0:0:0 | [summary] output from delegate call, parameter 0 of ContinueWith] | -| file://:0:0:0:0 | [summary] delegate call, parameter 0 of ContinueWith | return | file://:0:0:0:0 | [summary] output from delegate call, parameter 0 of ContinueWith] | -| file://:0:0:0:0 | [summary] delegate call, parameter 0 of ContinueWith | return | file://:0:0:0:0 | [summary] output from delegate call, parameter 0 of ContinueWith] | -| file://:0:0:0:0 | [summary] delegate call, parameter 0 of ContinueWith | return | file://:0:0:0:0 | [summary] output from delegate call, parameter 0 of ContinueWith] | -| file://:0:0:0:0 | [summary] delegate call, parameter 0 of ContinueWith | return | file://:0:0:0:0 | [summary] output from delegate call, parameter 0 of ContinueWith] | -| file://:0:0:0:0 | [summary] delegate call, parameter 0 of ContinueWith | return | file://:0:0:0:0 | [summary] output from delegate call, parameter 0 of ContinueWith] | -| file://:0:0:0:0 | [summary] delegate call, parameter 0 of ContinueWith | return | file://:0:0:0:0 | [summary] output from delegate call, parameter 0 of ContinueWith] | -| file://:0:0:0:0 | [summary] delegate call, parameter 0 of ContinueWith | return | file://:0:0:0:0 | [summary] output from delegate call, parameter 0 of ContinueWith] | -| file://:0:0:0:0 | [summary] delegate call, parameter 0 of ContinueWith | return | file://:0:0:0:0 | [summary] output from delegate call, parameter 0 of ContinueWith] | -| file://:0:0:0:0 | [summary] delegate call, parameter 0 of ContinueWith | return | file://:0:0:0:0 | [summary] output from delegate call, parameter 0 of ContinueWith] | -| file://:0:0:0:0 | [summary] delegate call, parameter 0 of ContinueWith | return | file://:0:0:0:0 | [summary] output from delegate call, parameter 0 of ContinueWith] | -| file://:0:0:0:0 | [summary] delegate call, parameter 0 of ContinueWith | return | file://:0:0:0:0 | [summary] output from delegate call, parameter 0 of ContinueWith] | -| file://:0:0:0:0 | [summary] delegate call, parameter 0 of ContinueWith | return | file://:0:0:0:0 | [summary] output from delegate call, parameter 0 of ContinueWith] | -| file://:0:0:0:0 | [summary] delegate call, parameter 0 of ContinueWith | return | file://:0:0:0:0 | [summary] output from delegate call, parameter 0 of ContinueWith] | -| file://:0:0:0:0 | [summary] delegate call, parameter 0 of ContinueWith | return | file://:0:0:0:0 | [summary] output from delegate call, parameter 0 of ContinueWith] | -| file://:0:0:0:0 | [summary] delegate call, parameter 0 of ContinueWith | return | file://:0:0:0:0 | [summary] output from delegate call, parameter 0 of ContinueWith] | -| file://:0:0:0:0 | [summary] delegate call, parameter 0 of ContinueWith | return | file://:0:0:0:0 | [summary] output from delegate call, parameter 0 of ContinueWith] | -| file://:0:0:0:0 | [summary] delegate call, parameter 0 of ContinueWith | return | file://:0:0:0:0 | [summary] output from delegate call, parameter 0 of ContinueWith] | -| file://:0:0:0:0 | [summary] delegate call, parameter 0 of ContinueWith | return | file://:0:0:0:0 | [summary] output from delegate call, parameter 0 of ContinueWith] | -| file://:0:0:0:0 | [summary] delegate call, parameter 0 of ContinueWith | return | file://:0:0:0:0 | [summary] output from delegate call, parameter 0 of ContinueWith] | -| file://:0:0:0:0 | [summary] delegate call, parameter 0 of Lazy | return | file://:0:0:0:0 | [summary] output from delegate call, parameter 0 of Lazy] | -| file://:0:0:0:0 | [summary] delegate call, parameter 0 of Lazy | return | file://:0:0:0:0 | [summary] output from delegate call, parameter 0 of Lazy] | -| file://:0:0:0:0 | [summary] delegate call, parameter 0 of Lazy | return | file://:0:0:0:0 | [summary] output from delegate call, parameter 0 of Lazy] | -| file://:0:0:0:0 | [summary] delegate call, parameter 0 of Run | return | file://:0:0:0:0 | [summary] output from delegate call, parameter 0 of Run] | -| file://:0:0:0:0 | [summary] delegate call, parameter 0 of Run | return | file://:0:0:0:0 | [summary] output from delegate call, parameter 0 of Run] | -| file://:0:0:0:0 | [summary] delegate call, parameter 0 of Run | return | file://:0:0:0:0 | [summary] output from delegate call, parameter 0 of Run] | -| file://:0:0:0:0 | [summary] delegate call, parameter 0 of Run | return | file://:0:0:0:0 | [summary] output from delegate call, parameter 0 of Run] | -| file://:0:0:0:0 | [summary] delegate call, parameter 0 of StartNew | return | file://:0:0:0:0 | [summary] output from delegate call, parameter 0 of StartNew] | -| file://:0:0:0:0 | [summary] delegate call, parameter 0 of StartNew | return | file://:0:0:0:0 | [summary] output from delegate call, parameter 0 of StartNew] | -| file://:0:0:0:0 | [summary] delegate call, parameter 0 of StartNew | return | file://:0:0:0:0 | [summary] output from delegate call, parameter 0 of StartNew] | -| file://:0:0:0:0 | [summary] delegate call, parameter 0 of StartNew | return | file://:0:0:0:0 | [summary] output from delegate call, parameter 0 of StartNew] | -| file://:0:0:0:0 | [summary] delegate call, parameter 0 of StartNew | return | file://:0:0:0:0 | [summary] output from delegate call, parameter 0 of StartNew] | -| file://:0:0:0:0 | [summary] delegate call, parameter 0 of StartNew | return | file://:0:0:0:0 | [summary] output from delegate call, parameter 0 of StartNew] | -| file://:0:0:0:0 | [summary] delegate call, parameter 0 of StartNew | return | file://:0:0:0:0 | [summary] output from delegate call, parameter 0 of StartNew] | -| file://:0:0:0:0 | [summary] delegate call, parameter 0 of StartNew | return | file://:0:0:0:0 | [summary] output from delegate call, parameter 0 of StartNew] | -| file://:0:0:0:0 | [summary] delegate call, parameter 0 of StartNew | return | file://:0:0:0:0 | [summary] output from delegate call, parameter 0 of StartNew] | -| file://:0:0:0:0 | [summary] delegate call, parameter 0 of StartNew | return | file://:0:0:0:0 | [summary] output from delegate call, parameter 0 of StartNew] | -| file://:0:0:0:0 | [summary] delegate call, parameter 0 of StartNew | return | file://:0:0:0:0 | [summary] output from delegate call, parameter 0 of StartNew] | -| file://:0:0:0:0 | [summary] delegate call, parameter 0 of StartNew | return | file://:0:0:0:0 | [summary] output from delegate call, parameter 0 of StartNew] | -| file://:0:0:0:0 | [summary] delegate call, parameter 0 of StartNew | return | file://:0:0:0:0 | [summary] output from delegate call, parameter 0 of StartNew] | -| file://:0:0:0:0 | [summary] delegate call, parameter 0 of StartNew | return | file://:0:0:0:0 | [summary] output from delegate call, parameter 0 of StartNew] | -| file://:0:0:0:0 | [summary] delegate call, parameter 0 of StartNew | return | file://:0:0:0:0 | [summary] output from delegate call, parameter 0 of StartNew] | -| file://:0:0:0:0 | [summary] delegate call, parameter 0 of StartNew | return | file://:0:0:0:0 | [summary] output from delegate call, parameter 0 of StartNew] | -| file://:0:0:0:0 | [summary] delegate call, parameter 0 of Task | return | file://:0:0:0:0 | [summary] output from delegate call, parameter 0 of Task] | -| file://:0:0:0:0 | [summary] delegate call, parameter 0 of Task | return | file://:0:0:0:0 | [summary] output from delegate call, parameter 0 of Task] | -| file://:0:0:0:0 | [summary] delegate call, parameter 0 of Task | return | file://:0:0:0:0 | [summary] output from delegate call, parameter 0 of Task] | -| file://:0:0:0:0 | [summary] delegate call, parameter 0 of Task | return | file://:0:0:0:0 | [summary] output from delegate call, parameter 0 of Task] | -| file://:0:0:0:0 | [summary] delegate call, parameter 0 of Task | return | file://:0:0:0:0 | [summary] output from delegate call, parameter 0 of Task] | -| file://:0:0:0:0 | [summary] delegate call, parameter 0 of Task | return | file://:0:0:0:0 | [summary] output from delegate call, parameter 0 of Task] | -| file://:0:0:0:0 | [summary] delegate call, parameter 0 of Task | return | file://:0:0:0:0 | [summary] output from delegate call, parameter 0 of Task] | -| file://:0:0:0:0 | [summary] delegate call, parameter 0 of Task | return | file://:0:0:0:0 | [summary] output from delegate call, parameter 0 of Task] | -| file://:0:0:0:0 | [summary] delegate call, parameter 1 of Aggregate | return | file://:0:0:0:0 | [summary] output from delegate call, parameter 1 of Aggregate] | -| file://:0:0:0:0 | [summary] delegate call, parameter 1 of Aggregate | return | file://:0:0:0:0 | [summary] output from delegate call, parameter 1 of Aggregate] | -| file://:0:0:0:0 | [summary] delegate call, parameter 1 of ContinueWhenAll | return | file://:0:0:0:0 | [summary] output from delegate call, parameter 1 of ContinueWhenAll] | -| file://:0:0:0:0 | [summary] delegate call, parameter 1 of ContinueWhenAll | return | file://:0:0:0:0 | [summary] output from delegate call, parameter 1 of ContinueWhenAll] | -| file://:0:0:0:0 | [summary] delegate call, parameter 1 of ContinueWhenAll | return | file://:0:0:0:0 | [summary] output from delegate call, parameter 1 of ContinueWhenAll] | -| file://:0:0:0:0 | [summary] delegate call, parameter 1 of ContinueWhenAll | return | file://:0:0:0:0 | [summary] output from delegate call, parameter 1 of ContinueWhenAll] | -| file://:0:0:0:0 | [summary] delegate call, parameter 1 of ContinueWhenAll | return | file://:0:0:0:0 | [summary] output from delegate call, parameter 1 of ContinueWhenAll] | -| file://:0:0:0:0 | [summary] delegate call, parameter 1 of ContinueWhenAll | return | file://:0:0:0:0 | [summary] output from delegate call, parameter 1 of ContinueWhenAll] | -| file://:0:0:0:0 | [summary] delegate call, parameter 1 of ContinueWhenAll | return | file://:0:0:0:0 | [summary] output from delegate call, parameter 1 of ContinueWhenAll] | -| file://:0:0:0:0 | [summary] delegate call, parameter 1 of ContinueWhenAll | return | file://:0:0:0:0 | [summary] output from delegate call, parameter 1 of ContinueWhenAll] | -| file://:0:0:0:0 | [summary] delegate call, parameter 1 of ContinueWhenAll | return | file://:0:0:0:0 | [summary] output from delegate call, parameter 1 of ContinueWhenAll] | -| file://:0:0:0:0 | [summary] delegate call, parameter 1 of ContinueWhenAll | return | file://:0:0:0:0 | [summary] output from delegate call, parameter 1 of ContinueWhenAll] | -| file://:0:0:0:0 | [summary] delegate call, parameter 1 of ContinueWhenAll | return | file://:0:0:0:0 | [summary] output from delegate call, parameter 1 of ContinueWhenAll] | -| file://:0:0:0:0 | [summary] delegate call, parameter 1 of ContinueWhenAll | return | file://:0:0:0:0 | [summary] output from delegate call, parameter 1 of ContinueWhenAll] | -| file://:0:0:0:0 | [summary] delegate call, parameter 1 of ContinueWhenAll | return | file://:0:0:0:0 | [summary] output from delegate call, parameter 1 of ContinueWhenAll] | -| file://:0:0:0:0 | [summary] delegate call, parameter 1 of ContinueWhenAll | return | file://:0:0:0:0 | [summary] output from delegate call, parameter 1 of ContinueWhenAll] | -| file://:0:0:0:0 | [summary] delegate call, parameter 1 of ContinueWhenAll | return | file://:0:0:0:0 | [summary] output from delegate call, parameter 1 of ContinueWhenAll] | -| file://:0:0:0:0 | [summary] delegate call, parameter 1 of ContinueWhenAll | return | file://:0:0:0:0 | [summary] output from delegate call, parameter 1 of ContinueWhenAll] | -| file://:0:0:0:0 | [summary] delegate call, parameter 1 of ContinueWhenAny | return | file://:0:0:0:0 | [summary] output from delegate call, parameter 1 of ContinueWhenAny] | -| file://:0:0:0:0 | [summary] delegate call, parameter 1 of ContinueWhenAny | return | file://:0:0:0:0 | [summary] output from delegate call, parameter 1 of ContinueWhenAny] | -| file://:0:0:0:0 | [summary] delegate call, parameter 1 of ContinueWhenAny | return | file://:0:0:0:0 | [summary] output from delegate call, parameter 1 of ContinueWhenAny] | -| file://:0:0:0:0 | [summary] delegate call, parameter 1 of ContinueWhenAny | return | file://:0:0:0:0 | [summary] output from delegate call, parameter 1 of ContinueWhenAny] | -| file://:0:0:0:0 | [summary] delegate call, parameter 1 of ContinueWhenAny | return | file://:0:0:0:0 | [summary] output from delegate call, parameter 1 of ContinueWhenAny] | -| file://:0:0:0:0 | [summary] delegate call, parameter 1 of ContinueWhenAny | return | file://:0:0:0:0 | [summary] output from delegate call, parameter 1 of ContinueWhenAny] | -| file://:0:0:0:0 | [summary] delegate call, parameter 1 of ContinueWhenAny | return | file://:0:0:0:0 | [summary] output from delegate call, parameter 1 of ContinueWhenAny] | -| file://:0:0:0:0 | [summary] delegate call, parameter 1 of ContinueWhenAny | return | file://:0:0:0:0 | [summary] output from delegate call, parameter 1 of ContinueWhenAny] | -| file://:0:0:0:0 | [summary] delegate call, parameter 1 of ContinueWhenAny | return | file://:0:0:0:0 | [summary] output from delegate call, parameter 1 of ContinueWhenAny] | -| file://:0:0:0:0 | [summary] delegate call, parameter 1 of ContinueWhenAny | return | file://:0:0:0:0 | [summary] output from delegate call, parameter 1 of ContinueWhenAny] | -| file://:0:0:0:0 | [summary] delegate call, parameter 1 of ContinueWhenAny | return | file://:0:0:0:0 | [summary] output from delegate call, parameter 1 of ContinueWhenAny] | -| file://:0:0:0:0 | [summary] delegate call, parameter 1 of ContinueWhenAny | return | file://:0:0:0:0 | [summary] output from delegate call, parameter 1 of ContinueWhenAny] | -| file://:0:0:0:0 | [summary] delegate call, parameter 1 of ContinueWhenAny | return | file://:0:0:0:0 | [summary] output from delegate call, parameter 1 of ContinueWhenAny] | -| file://:0:0:0:0 | [summary] delegate call, parameter 1 of ContinueWhenAny | return | file://:0:0:0:0 | [summary] output from delegate call, parameter 1 of ContinueWhenAny] | -| file://:0:0:0:0 | [summary] delegate call, parameter 1 of ContinueWhenAny | return | file://:0:0:0:0 | [summary] output from delegate call, parameter 1 of ContinueWhenAny] | -| file://:0:0:0:0 | [summary] delegate call, parameter 1 of ContinueWhenAny | return | file://:0:0:0:0 | [summary] output from delegate call, parameter 1 of ContinueWhenAny] | -| file://:0:0:0:0 | [summary] delegate call, parameter 1 of GroupBy | return | file://:0:0:0:0 | [summary] output from delegate call, parameter 1 of GroupBy] | -| file://:0:0:0:0 | [summary] delegate call, parameter 1 of GroupBy | return | file://:0:0:0:0 | [summary] output from delegate call, parameter 1 of GroupBy] | -| file://:0:0:0:0 | [summary] delegate call, parameter 1 of GroupBy | return | file://:0:0:0:0 | [summary] output from delegate call, parameter 1 of GroupBy] | -| file://:0:0:0:0 | [summary] delegate call, parameter 1 of GroupBy | return | file://:0:0:0:0 | [summary] output from delegate call, parameter 1 of GroupBy] | -| file://:0:0:0:0 | [summary] delegate call, parameter 1 of GroupBy | return | file://:0:0:0:0 | [summary] output from delegate call, parameter 1 of GroupBy] | -| file://:0:0:0:0 | [summary] delegate call, parameter 1 of GroupBy | return | file://:0:0:0:0 | [summary] output from delegate call, parameter 1 of GroupBy] | -| file://:0:0:0:0 | [summary] delegate call, parameter 1 of GroupBy | return | file://:0:0:0:0 | [summary] output from delegate call, parameter 1 of GroupBy] | -| file://:0:0:0:0 | [summary] delegate call, parameter 1 of GroupBy | return | file://:0:0:0:0 | [summary] output from delegate call, parameter 1 of GroupBy] | -| file://:0:0:0:0 | [summary] delegate call, parameter 1 of GroupBy | return | file://:0:0:0:0 | [summary] output from delegate call, parameter 1 of GroupBy] | -| file://:0:0:0:0 | [summary] delegate call, parameter 1 of Select | return | file://:0:0:0:0 | [summary] output from delegate call, parameter 1 of Select] | -| file://:0:0:0:0 | [summary] delegate call, parameter 1 of Select | return | file://:0:0:0:0 | [summary] output from delegate call, parameter 1 of Select] | -| file://:0:0:0:0 | [summary] delegate call, parameter 1 of Select | return | file://:0:0:0:0 | [summary] output from delegate call, parameter 1 of Select] | -| file://:0:0:0:0 | [summary] delegate call, parameter 1 of Select | return | file://:0:0:0:0 | [summary] output from delegate call, parameter 1 of Select] | -| file://:0:0:0:0 | [summary] delegate call, parameter 1 of SelectMany | return | file://:0:0:0:0 | [summary] output from delegate call, parameter 1 of SelectMany] | -| file://:0:0:0:0 | [summary] delegate call, parameter 1 of SelectMany | return | file://:0:0:0:0 | [summary] output from delegate call, parameter 1 of SelectMany] | -| file://:0:0:0:0 | [summary] delegate call, parameter 1 of SelectMany | return | file://:0:0:0:0 | [summary] output from delegate call, parameter 1 of SelectMany] | -| file://:0:0:0:0 | [summary] delegate call, parameter 1 of SelectMany | return | file://:0:0:0:0 | [summary] output from delegate call, parameter 1 of SelectMany] | -| file://:0:0:0:0 | [summary] delegate call, parameter 1 of SelectMany | return | file://:0:0:0:0 | [summary] output from delegate call, parameter 1 of SelectMany] | -| file://:0:0:0:0 | [summary] delegate call, parameter 1 of SelectMany | return | file://:0:0:0:0 | [summary] output from delegate call, parameter 1 of SelectMany] | -| file://:0:0:0:0 | [summary] delegate call, parameter 1 of SelectMany | return | file://:0:0:0:0 | [summary] output from delegate call, parameter 1 of SelectMany] | -| file://:0:0:0:0 | [summary] delegate call, parameter 1 of SelectMany | return | file://:0:0:0:0 | [summary] output from delegate call, parameter 1 of SelectMany] | -| file://:0:0:0:0 | [summary] delegate call, parameter 2 of Aggregate | return | file://:0:0:0:0 | [summary] output from delegate call, parameter 2 of Aggregate] | -| file://:0:0:0:0 | [summary] delegate call, parameter 2 of Aggregate | return | file://:0:0:0:0 | [summary] output from delegate call, parameter 2 of Aggregate] | -| file://:0:0:0:0 | [summary] delegate call, parameter 2 of Aggregate | return | file://:0:0:0:0 | [summary] output from delegate call, parameter 2 of Aggregate] | -| file://:0:0:0:0 | [summary] delegate call, parameter 2 of Aggregate | return | file://:0:0:0:0 | [summary] output from delegate call, parameter 2 of Aggregate] | -| file://:0:0:0:0 | [summary] delegate call, parameter 2 of GroupBy | return | file://:0:0:0:0 | [summary] output from delegate call, parameter 2 of GroupBy] | -| file://:0:0:0:0 | [summary] delegate call, parameter 2 of GroupBy | return | file://:0:0:0:0 | [summary] output from delegate call, parameter 2 of GroupBy] | -| file://:0:0:0:0 | [summary] delegate call, parameter 2 of GroupBy | return | file://:0:0:0:0 | [summary] output from delegate call, parameter 2 of GroupBy] | -| file://:0:0:0:0 | [summary] delegate call, parameter 2 of GroupBy | return | file://:0:0:0:0 | [summary] output from delegate call, parameter 2 of GroupBy] | -| file://:0:0:0:0 | [summary] delegate call, parameter 2 of GroupBy | return | file://:0:0:0:0 | [summary] output from delegate call, parameter 2 of GroupBy] | -| file://:0:0:0:0 | [summary] delegate call, parameter 2 of GroupBy | return | file://:0:0:0:0 | [summary] output from delegate call, parameter 2 of GroupBy] | -| file://:0:0:0:0 | [summary] delegate call, parameter 2 of GroupBy | return | file://:0:0:0:0 | [summary] output from delegate call, parameter 2 of GroupBy] | -| file://:0:0:0:0 | [summary] delegate call, parameter 2 of GroupBy | return | file://:0:0:0:0 | [summary] output from delegate call, parameter 2 of GroupBy] | -| file://:0:0:0:0 | [summary] delegate call, parameter 2 of SelectMany | return | file://:0:0:0:0 | [summary] output from delegate call, parameter 2 of SelectMany] | -| file://:0:0:0:0 | [summary] delegate call, parameter 2 of SelectMany | return | file://:0:0:0:0 | [summary] output from delegate call, parameter 2 of SelectMany] | -| file://:0:0:0:0 | [summary] delegate call, parameter 2 of SelectMany | return | file://:0:0:0:0 | [summary] output from delegate call, parameter 2 of SelectMany] | -| file://:0:0:0:0 | [summary] delegate call, parameter 2 of SelectMany | return | file://:0:0:0:0 | [summary] output from delegate call, parameter 2 of SelectMany] | -| file://:0:0:0:0 | [summary] delegate call, parameter 2 of ToDictionary | return | file://:0:0:0:0 | [summary] output from delegate call, parameter 2 of ToDictionary] | -| file://:0:0:0:0 | [summary] delegate call, parameter 2 of ToDictionary | return | file://:0:0:0:0 | [summary] output from delegate call, parameter 2 of ToDictionary] | -| file://:0:0:0:0 | [summary] delegate call, parameter 2 of ToLookup | return | file://:0:0:0:0 | [summary] output from delegate call, parameter 2 of ToLookup] | -| file://:0:0:0:0 | [summary] delegate call, parameter 2 of ToLookup | return | file://:0:0:0:0 | [summary] output from delegate call, parameter 2 of ToLookup] | -| file://:0:0:0:0 | [summary] delegate call, parameter 2 of Zip | return | file://:0:0:0:0 | [summary] output from delegate call, parameter 2 of Zip] | -| file://:0:0:0:0 | [summary] delegate call, parameter 2 of Zip | return | file://:0:0:0:0 | [summary] output from delegate call, parameter 2 of Zip] | -| file://:0:0:0:0 | [summary] delegate call, parameter 3 of Aggregate | return | file://:0:0:0:0 | [summary] output from delegate call, parameter 3 of Aggregate] | -| file://:0:0:0:0 | [summary] delegate call, parameter 3 of Aggregate | return | file://:0:0:0:0 | [summary] output from delegate call, parameter 3 of Aggregate] | -| file://:0:0:0:0 | [summary] delegate call, parameter 3 of GroupBy | return | file://:0:0:0:0 | [summary] output from delegate call, parameter 3 of GroupBy] | -| file://:0:0:0:0 | [summary] delegate call, parameter 3 of GroupBy | return | file://:0:0:0:0 | [summary] output from delegate call, parameter 3 of GroupBy] | -| file://:0:0:0:0 | [summary] delegate call, parameter 3 of GroupBy | return | file://:0:0:0:0 | [summary] output from delegate call, parameter 3 of GroupBy] | -| file://:0:0:0:0 | [summary] delegate call, parameter 3 of GroupBy | return | file://:0:0:0:0 | [summary] output from delegate call, parameter 3 of GroupBy] | -| file://:0:0:0:0 | [summary] delegate call, parameter 4 of GroupJoin | return | file://:0:0:0:0 | [summary] output from delegate call, parameter 4 of GroupJoin] | -| file://:0:0:0:0 | [summary] delegate call, parameter 4 of GroupJoin | return | file://:0:0:0:0 | [summary] output from delegate call, parameter 4 of GroupJoin] | -| file://:0:0:0:0 | [summary] delegate call, parameter 4 of GroupJoin | return | file://:0:0:0:0 | [summary] output from delegate call, parameter 4 of GroupJoin] | -| file://:0:0:0:0 | [summary] delegate call, parameter 4 of GroupJoin | return | file://:0:0:0:0 | [summary] output from delegate call, parameter 4 of GroupJoin] | -| file://:0:0:0:0 | [summary] delegate call, parameter 4 of Join | return | file://:0:0:0:0 | [summary] output from delegate call, parameter 4 of Join] | -| file://:0:0:0:0 | [summary] delegate call, parameter 4 of Join | return | file://:0:0:0:0 | [summary] output from delegate call, parameter 4 of Join] | -| file://:0:0:0:0 | [summary] delegate call, parameter 4 of Join | return | file://:0:0:0:0 | [summary] output from delegate call, parameter 4 of Join] | -| file://:0:0:0:0 | [summary] delegate call, parameter 4 of Join | return | file://:0:0:0:0 | [summary] output from delegate call, parameter 4 of Join] | +| Capture.cs:191:20:191:22 | call to local function M | normal | Capture.cs:191:20:191:22 | call to local function M | +| Capture.cs:194:22:194:32 | call to local function Id | normal | Capture.cs:194:22:194:32 | call to local function Id | +| Capture.cs:196:20:196:25 | call to local function Id | normal | Capture.cs:196:20:196:25 | call to local function Id | +| GlobalDataFlow.cs:26:9:26:26 | access to property SinkProperty0 | normal | GlobalDataFlow.cs:26:9:26:26 | access to property SinkProperty0 | +| GlobalDataFlow.cs:27:15:27:32 | access to property SinkProperty0 | normal | GlobalDataFlow.cs:27:15:27:32 | access to property SinkProperty0 | +| GlobalDataFlow.cs:30:9:30:29 | access to property NonSinkProperty0 | normal | GlobalDataFlow.cs:30:9:30:29 | access to property NonSinkProperty0 | +| GlobalDataFlow.cs:31:15:31:35 | access to property NonSinkProperty0 | normal | GlobalDataFlow.cs:31:15:31:35 | access to property NonSinkProperty0 | +| GlobalDataFlow.cs:32:9:32:29 | access to property NonSinkProperty1 | normal | GlobalDataFlow.cs:32:9:32:29 | access to property NonSinkProperty1 | +| GlobalDataFlow.cs:33:15:33:35 | access to property NonSinkProperty1 | normal | GlobalDataFlow.cs:33:15:33:35 | access to property NonSinkProperty1 | +| GlobalDataFlow.cs:36:13:36:30 | access to property SinkProperty0 | normal | GlobalDataFlow.cs:36:13:36:30 | access to property SinkProperty0 | +| GlobalDataFlow.cs:37:26:37:58 | call to method GetMethod | normal | GlobalDataFlow.cs:37:26:37:58 | call to method GetMethod | +| GlobalDataFlow.cs:38:35:38:52 | access to property SinkProperty0 | normal | GlobalDataFlow.cs:38:35:38:52 | access to property SinkProperty0 | +| GlobalDataFlow.cs:39:9:39:37 | call to method Invoke | normal | GlobalDataFlow.cs:39:9:39:37 | call to method Invoke | +| GlobalDataFlow.cs:46:13:46:30 | access to property SinkProperty0 | normal | GlobalDataFlow.cs:46:13:46:30 | access to property SinkProperty0 | +| GlobalDataFlow.cs:53:20:53:37 | access to property SinkProperty0 | normal | GlobalDataFlow.cs:53:20:53:37 | access to property SinkProperty0 | +| GlobalDataFlow.cs:54:28:54:45 | access to property SinkProperty0 | normal | GlobalDataFlow.cs:54:28:54:45 | access to property SinkProperty0 | +| GlobalDataFlow.cs:55:44:55:61 | access to property SinkProperty0 | normal | GlobalDataFlow.cs:55:44:55:61 | access to property SinkProperty0 | +| GlobalDataFlow.cs:56:28:56:45 | access to property SinkProperty0 | normal | GlobalDataFlow.cs:56:28:56:45 | access to property SinkProperty0 | +| GlobalDataFlow.cs:58:35:58:52 | access to property SinkProperty0 | normal | GlobalDataFlow.cs:58:35:58:52 | access to property SinkProperty0 | +| GlobalDataFlow.cs:65:9:65:18 | access to property InProperty | normal | GlobalDataFlow.cs:65:9:65:18 | access to property InProperty | +| GlobalDataFlow.cs:65:22:65:39 | access to property SinkProperty0 | normal | GlobalDataFlow.cs:65:22:65:39 | access to property SinkProperty0 | +| GlobalDataFlow.cs:68:9:68:21 | access to property NonInProperty | normal | GlobalDataFlow.cs:68:9:68:21 | access to property NonInProperty | +| GlobalDataFlow.cs:71:21:71:46 | call to method Return | normal | GlobalDataFlow.cs:71:21:71:46 | call to method Return | +| GlobalDataFlow.cs:71:28:71:45 | access to property SinkProperty0 | normal | GlobalDataFlow.cs:71:28:71:45 | access to property SinkProperty0 | +| GlobalDataFlow.cs:73:29:73:64 | call to method GetMethod | normal | GlobalDataFlow.cs:73:29:73:64 | call to method GetMethod | +| GlobalDataFlow.cs:73:29:73:101 | call to method Invoke | normal | GlobalDataFlow.cs:73:29:73:101 | call to method Invoke | +| GlobalDataFlow.cs:76:9:76:46 | call to method ReturnOut | out parameter 1 | GlobalDataFlow.cs:76:30:76:34 | SSA def(sink2) | +| GlobalDataFlow.cs:76:9:76:46 | call to method ReturnOut | ref parameter 1 | GlobalDataFlow.cs:76:30:76:34 | SSA def(sink2) | +| GlobalDataFlow.cs:79:9:79:46 | call to method ReturnRef | out parameter 1 | GlobalDataFlow.cs:79:30:79:34 | SSA def(sink3) | +| GlobalDataFlow.cs:79:9:79:46 | call to method ReturnRef | ref parameter 1 | GlobalDataFlow.cs:79:30:79:34 | SSA def(sink3) | +| GlobalDataFlow.cs:81:22:81:85 | call to method SelectEven | normal | GlobalDataFlow.cs:81:22:81:85 | call to method SelectEven | +| GlobalDataFlow.cs:81:22:81:93 | call to method First | normal | GlobalDataFlow.cs:81:22:81:93 | call to method First | +| GlobalDataFlow.cs:83:22:83:87 | call to method Select | normal | GlobalDataFlow.cs:83:22:83:87 | call to method Select | +| GlobalDataFlow.cs:83:22:83:95 | call to method First | normal | GlobalDataFlow.cs:83:22:83:95 | call to method First | +| GlobalDataFlow.cs:85:22:85:128 | call to method Zip | normal | GlobalDataFlow.cs:85:22:85:128 | call to method Zip | +| GlobalDataFlow.cs:85:22:85:136 | call to method First | normal | GlobalDataFlow.cs:85:22:85:136 | call to method First | +| GlobalDataFlow.cs:87:22:87:128 | call to method Zip | normal | GlobalDataFlow.cs:87:22:87:128 | call to method Zip | +| GlobalDataFlow.cs:87:22:87:136 | call to method First | normal | GlobalDataFlow.cs:87:22:87:136 | call to method First | +| GlobalDataFlow.cs:89:22:89:110 | call to method Aggregate | normal | GlobalDataFlow.cs:89:22:89:110 | call to method Aggregate | +| GlobalDataFlow.cs:91:22:91:110 | call to method Aggregate | normal | GlobalDataFlow.cs:91:22:91:110 | call to method Aggregate | +| GlobalDataFlow.cs:94:9:94:42 | call to method TryParse | normal | GlobalDataFlow.cs:94:9:94:42 | call to method TryParse | +| GlobalDataFlow.cs:94:9:94:42 | call to method TryParse | out parameter 1 | GlobalDataFlow.cs:94:36:94:41 | SSA def(sink21) | +| GlobalDataFlow.cs:94:9:94:42 | call to method TryParse | ref parameter 1 | GlobalDataFlow.cs:94:36:94:41 | SSA def(sink21) | +| GlobalDataFlow.cs:97:9:97:41 | call to method TryParse | normal | GlobalDataFlow.cs:97:9:97:41 | call to method TryParse | +| GlobalDataFlow.cs:97:9:97:41 | call to method TryParse | out parameter 1 | GlobalDataFlow.cs:97:35:97:40 | SSA def(sink22) | +| GlobalDataFlow.cs:97:9:97:41 | call to method TryParse | ref parameter 1 | GlobalDataFlow.cs:97:35:97:40 | SSA def(sink22) | +| GlobalDataFlow.cs:101:24:101:33 | call to method Return | normal | GlobalDataFlow.cs:101:24:101:33 | call to method Return | +| GlobalDataFlow.cs:103:28:103:63 | call to method GetMethod | normal | GlobalDataFlow.cs:103:28:103:63 | call to method GetMethod | +| GlobalDataFlow.cs:103:28:103:103 | call to method Invoke | normal | GlobalDataFlow.cs:103:28:103:103 | call to method Invoke | +| GlobalDataFlow.cs:105:9:105:49 | call to method ReturnOut | out parameter 1 | GlobalDataFlow.cs:105:27:105:34 | SSA def(nonSink0) | +| GlobalDataFlow.cs:105:9:105:49 | call to method ReturnOut | ref parameter 1 | GlobalDataFlow.cs:105:27:105:34 | SSA def(nonSink0) | +| GlobalDataFlow.cs:107:9:107:49 | call to method ReturnOut | out parameter 2 | GlobalDataFlow.cs:107:41:107:48 | SSA def(nonSink0) | +| GlobalDataFlow.cs:107:9:107:49 | call to method ReturnOut | ref parameter 2 | GlobalDataFlow.cs:107:41:107:48 | SSA def(nonSink0) | +| GlobalDataFlow.cs:109:9:109:49 | call to method ReturnRef | out parameter 1 | GlobalDataFlow.cs:109:27:109:34 | SSA def(nonSink0) | +| GlobalDataFlow.cs:109:9:109:49 | call to method ReturnRef | ref parameter 1 | GlobalDataFlow.cs:109:27:109:34 | SSA def(nonSink0) | +| GlobalDataFlow.cs:111:9:111:49 | call to method ReturnRef | out parameter 1 | GlobalDataFlow.cs:111:30:111:34 | SSA def(sink1) | +| GlobalDataFlow.cs:111:9:111:49 | call to method ReturnRef | ref parameter 1 | GlobalDataFlow.cs:111:30:111:34 | SSA def(sink1) | +| GlobalDataFlow.cs:113:20:113:86 | call to method SelectEven | normal | GlobalDataFlow.cs:113:20:113:86 | call to method SelectEven | +| GlobalDataFlow.cs:113:20:113:94 | call to method First | normal | GlobalDataFlow.cs:113:20:113:94 | call to method First | +| GlobalDataFlow.cs:115:20:115:82 | call to method Select | normal | GlobalDataFlow.cs:115:20:115:82 | call to method Select | +| GlobalDataFlow.cs:115:20:115:90 | call to method First | normal | GlobalDataFlow.cs:115:20:115:90 | call to method First | +| GlobalDataFlow.cs:117:20:117:126 | call to method Zip | normal | GlobalDataFlow.cs:117:20:117:126 | call to method Zip | +| GlobalDataFlow.cs:117:20:117:134 | call to method First | normal | GlobalDataFlow.cs:117:20:117:134 | call to method First | +| GlobalDataFlow.cs:119:20:119:126 | call to method Zip | normal | GlobalDataFlow.cs:119:20:119:126 | call to method Zip | +| GlobalDataFlow.cs:119:20:119:134 | call to method First | normal | GlobalDataFlow.cs:119:20:119:134 | call to method First | +| GlobalDataFlow.cs:121:20:121:104 | call to method Aggregate | normal | GlobalDataFlow.cs:121:20:121:104 | call to method Aggregate | +| GlobalDataFlow.cs:123:20:123:109 | call to method Aggregate | normal | GlobalDataFlow.cs:123:20:123:109 | call to method Aggregate | +| GlobalDataFlow.cs:125:20:125:107 | call to method Aggregate | normal | GlobalDataFlow.cs:125:20:125:107 | call to method Aggregate | +| GlobalDataFlow.cs:128:9:128:46 | call to method TryParse | normal | GlobalDataFlow.cs:128:9:128:46 | call to method TryParse | +| GlobalDataFlow.cs:128:9:128:46 | call to method TryParse | out parameter 1 | GlobalDataFlow.cs:128:38:128:45 | SSA def(nonSink2) | +| GlobalDataFlow.cs:128:9:128:46 | call to method TryParse | ref parameter 1 | GlobalDataFlow.cs:128:38:128:45 | SSA def(nonSink2) | +| GlobalDataFlow.cs:131:9:131:45 | call to method TryParse | normal | GlobalDataFlow.cs:131:9:131:45 | call to method TryParse | +| GlobalDataFlow.cs:131:9:131:45 | call to method TryParse | out parameter 1 | GlobalDataFlow.cs:131:37:131:44 | SSA def(nonSink3) | +| GlobalDataFlow.cs:131:9:131:45 | call to method TryParse | ref parameter 1 | GlobalDataFlow.cs:131:37:131:44 | SSA def(nonSink3) | +| GlobalDataFlow.cs:135:45:135:64 | call to method ApplyFunc | normal | GlobalDataFlow.cs:135:45:135:64 | call to method ApplyFunc | +| GlobalDataFlow.cs:136:21:136:34 | delegate call | normal | GlobalDataFlow.cs:136:21:136:34 | delegate call | +| GlobalDataFlow.cs:140:20:140:36 | delegate call | normal | GlobalDataFlow.cs:140:20:140:36 | delegate call | +| GlobalDataFlow.cs:144:21:144:44 | call to method ApplyFunc | normal | GlobalDataFlow.cs:144:21:144:44 | call to method ApplyFunc | +| GlobalDataFlow.cs:148:20:148:40 | call to method ApplyFunc | normal | GlobalDataFlow.cs:148:20:148:40 | call to method ApplyFunc | +| GlobalDataFlow.cs:150:20:150:44 | call to method ApplyFunc | normal | GlobalDataFlow.cs:150:20:150:44 | call to method ApplyFunc | +| GlobalDataFlow.cs:154:21:154:25 | call to method Out | normal | GlobalDataFlow.cs:154:21:154:25 | call to method Out | +| GlobalDataFlow.cs:157:9:157:25 | call to method OutOut | out parameter 0 | GlobalDataFlow.cs:157:20:157:24 | SSA def(sink7) | +| GlobalDataFlow.cs:157:9:157:25 | call to method OutOut | ref parameter 0 | GlobalDataFlow.cs:157:20:157:24 | SSA def(sink7) | +| GlobalDataFlow.cs:160:9:160:25 | call to method OutRef | out parameter 0 | GlobalDataFlow.cs:160:20:160:24 | SSA def(sink8) | +| GlobalDataFlow.cs:160:9:160:25 | call to method OutRef | ref parameter 0 | GlobalDataFlow.cs:160:20:160:24 | SSA def(sink8) | +| GlobalDataFlow.cs:162:22:162:31 | call to method OutYield | normal | GlobalDataFlow.cs:162:22:162:31 | call to method OutYield | +| GlobalDataFlow.cs:162:22:162:39 | call to method First | normal | GlobalDataFlow.cs:162:22:162:39 | call to method First | +| GlobalDataFlow.cs:164:22:164:43 | call to method TaintedParam | normal | GlobalDataFlow.cs:164:22:164:43 | call to method TaintedParam | +| GlobalDataFlow.cs:168:20:168:27 | call to method NonOut | normal | GlobalDataFlow.cs:168:20:168:27 | call to method NonOut | +| GlobalDataFlow.cs:170:9:170:31 | call to method NonOutOut | out parameter 0 | GlobalDataFlow.cs:170:23:170:30 | SSA def(nonSink0) | +| GlobalDataFlow.cs:170:9:170:31 | call to method NonOutOut | ref parameter 0 | GlobalDataFlow.cs:170:23:170:30 | SSA def(nonSink0) | +| GlobalDataFlow.cs:172:9:172:31 | call to method NonOutRef | out parameter 0 | GlobalDataFlow.cs:172:23:172:30 | SSA def(nonSink0) | +| GlobalDataFlow.cs:172:9:172:31 | call to method NonOutRef | ref parameter 0 | GlobalDataFlow.cs:172:23:172:30 | SSA def(nonSink0) | +| GlobalDataFlow.cs:174:20:174:32 | call to method NonOutYield | normal | GlobalDataFlow.cs:174:20:174:32 | call to method NonOutYield | +| GlobalDataFlow.cs:174:20:174:40 | call to method First | normal | GlobalDataFlow.cs:174:20:174:40 | call to method First | +| GlobalDataFlow.cs:176:20:176:44 | call to method NonTaintedParam | normal | GlobalDataFlow.cs:176:20:176:44 | call to method NonTaintedParam | +| GlobalDataFlow.cs:181:21:181:26 | delegate call | normal | GlobalDataFlow.cs:181:21:181:26 | delegate call | +| GlobalDataFlow.cs:186:20:186:27 | delegate call | normal | GlobalDataFlow.cs:186:20:186:27 | delegate call | +| GlobalDataFlow.cs:190:22:190:42 | object creation of type Lazy | normal | GlobalDataFlow.cs:190:22:190:42 | object creation of type Lazy | +| GlobalDataFlow.cs:190:22:190:48 | access to property Value | normal | GlobalDataFlow.cs:190:22:190:48 | access to property Value | +| GlobalDataFlow.cs:194:20:194:43 | object creation of type Lazy | normal | GlobalDataFlow.cs:194:20:194:43 | object creation of type Lazy | +| GlobalDataFlow.cs:194:20:194:49 | access to property Value | normal | GlobalDataFlow.cs:194:20:194:49 | access to property Value | +| GlobalDataFlow.cs:198:22:198:32 | access to property OutProperty | normal | GlobalDataFlow.cs:198:22:198:32 | access to property OutProperty | +| GlobalDataFlow.cs:202:20:202:33 | access to property NonOutProperty | normal | GlobalDataFlow.cs:202:20:202:33 | access to property NonOutProperty | +| GlobalDataFlow.cs:208:38:208:75 | call to method AsQueryable | normal | GlobalDataFlow.cs:208:38:208:75 | call to method AsQueryable | +| GlobalDataFlow.cs:209:41:209:77 | call to method AsQueryable | normal | GlobalDataFlow.cs:209:41:209:77 | call to method AsQueryable | +| GlobalDataFlow.cs:212:76:212:90 | call to method ReturnCheck2 | normal | GlobalDataFlow.cs:212:76:212:90 | call to method ReturnCheck2 | +| GlobalDataFlow.cs:213:22:213:39 | call to method Select | normal | GlobalDataFlow.cs:213:22:213:39 | call to method Select | +| GlobalDataFlow.cs:213:22:213:47 | call to method First | normal | GlobalDataFlow.cs:213:22:213:47 | call to method First | +| GlobalDataFlow.cs:215:22:215:39 | call to method Select | normal | GlobalDataFlow.cs:215:22:215:39 | call to method Select | +| GlobalDataFlow.cs:215:22:215:47 | call to method First | normal | GlobalDataFlow.cs:215:22:215:47 | call to method First | +| GlobalDataFlow.cs:217:22:217:49 | call to method Select | normal | GlobalDataFlow.cs:217:22:217:49 | call to method Select | +| GlobalDataFlow.cs:217:22:217:57 | call to method First | normal | GlobalDataFlow.cs:217:22:217:57 | call to method First | +| GlobalDataFlow.cs:222:76:222:92 | call to method NonReturnCheck | normal | GlobalDataFlow.cs:222:76:222:92 | call to method NonReturnCheck | +| GlobalDataFlow.cs:223:23:223:43 | call to method Select | normal | GlobalDataFlow.cs:223:23:223:43 | call to method Select | +| GlobalDataFlow.cs:223:23:223:51 | call to method First | normal | GlobalDataFlow.cs:223:23:223:51 | call to method First | +| GlobalDataFlow.cs:225:19:225:39 | call to method Select | normal | GlobalDataFlow.cs:225:19:225:39 | call to method Select | +| GlobalDataFlow.cs:225:19:225:47 | call to method First | normal | GlobalDataFlow.cs:225:19:225:47 | call to method First | +| GlobalDataFlow.cs:227:19:227:39 | call to method Select | normal | GlobalDataFlow.cs:227:19:227:39 | call to method Select | +| GlobalDataFlow.cs:227:19:227:47 | call to method First | normal | GlobalDataFlow.cs:227:19:227:47 | call to method First | +| GlobalDataFlow.cs:229:19:229:39 | call to method Select | normal | GlobalDataFlow.cs:229:19:229:39 | call to method Select | +| GlobalDataFlow.cs:229:19:229:47 | call to method First | normal | GlobalDataFlow.cs:229:19:229:47 | call to method First | +| GlobalDataFlow.cs:231:19:231:49 | call to method Select | normal | GlobalDataFlow.cs:231:19:231:49 | call to method Select | +| GlobalDataFlow.cs:231:19:231:57 | call to method First | normal | GlobalDataFlow.cs:231:19:231:57 | call to method First | +| GlobalDataFlow.cs:238:20:238:49 | call to method Run | normal | GlobalDataFlow.cs:238:20:238:49 | call to method Run | +| GlobalDataFlow.cs:239:22:239:32 | access to property Result | normal | GlobalDataFlow.cs:239:22:239:32 | access to property Result | +| GlobalDataFlow.cs:245:16:245:33 | call to method Run | normal | GlobalDataFlow.cs:245:16:245:33 | call to method Run | +| GlobalDataFlow.cs:246:24:246:34 | access to property Result | normal | GlobalDataFlow.cs:246:24:246:34 | access to property Result | +| GlobalDataFlow.cs:297:17:297:38 | call to method ApplyFunc | normal | GlobalDataFlow.cs:297:17:297:38 | call to method ApplyFunc | +| GlobalDataFlow.cs:386:16:386:19 | delegate call | normal | GlobalDataFlow.cs:386:16:386:19 | delegate call | +| GlobalDataFlow.cs:445:9:445:20 | call to method Append | normal | GlobalDataFlow.cs:445:9:445:20 | call to method Append | +| GlobalDataFlow.cs:450:18:450:36 | object creation of type StringBuilder | normal | GlobalDataFlow.cs:450:18:450:36 | object creation of type StringBuilder | +| GlobalDataFlow.cs:452:22:452:34 | call to method ToString | normal | GlobalDataFlow.cs:452:22:452:34 | call to method ToString | +| GlobalDataFlow.cs:455:9:455:18 | call to method Clear | normal | GlobalDataFlow.cs:455:9:455:18 | call to method Clear | +| GlobalDataFlow.cs:456:23:456:35 | call to method ToString | normal | GlobalDataFlow.cs:456:23:456:35 | call to method ToString | +| GlobalDataFlow.cs:462:22:462:65 | call to method Join | normal | GlobalDataFlow.cs:462:22:462:65 | call to method Join | +| GlobalDataFlow.cs:465:23:465:65 | call to method Join | normal | GlobalDataFlow.cs:465:23:465:65 | call to method Join | +| GlobalDataFlow.cs:471:20:471:49 | call to method Run | normal | GlobalDataFlow.cs:471:20:471:49 | call to method Run | +| GlobalDataFlow.cs:472:25:472:50 | call to method ConfigureAwait | normal | GlobalDataFlow.cs:472:25:472:50 | call to method ConfigureAwait | +| GlobalDataFlow.cs:473:23:473:44 | call to method GetAwaiter | normal | GlobalDataFlow.cs:473:23:473:44 | call to method GetAwaiter | +| GlobalDataFlow.cs:474:22:474:40 | call to method GetResult | normal | GlobalDataFlow.cs:474:22:474:40 | call to method GetResult | +| GlobalDataFlow.cs:498:44:498:47 | delegate call | normal | GlobalDataFlow.cs:498:44:498:47 | delegate call | +| Splitting.cs:8:17:8:31 | [b (line 3): false] call to method Return | normal | Splitting.cs:8:17:8:31 | [b (line 3): false] call to method Return | +| Splitting.cs:8:17:8:31 | [b (line 3): true] call to method Return | normal | Splitting.cs:8:17:8:31 | [b (line 3): true] call to method Return | +| Splitting.cs:20:22:20:30 | call to method Return | normal | Splitting.cs:20:22:20:30 | call to method Return | +| Splitting.cs:21:21:21:33 | call to method Return | normal | Splitting.cs:21:21:21:33 | call to method Return | +| Splitting.cs:30:9:30:13 | [b (line 24): false] dynamic access to element | normal | Splitting.cs:30:9:30:13 | [b (line 24): false] dynamic access to element | +| Splitting.cs:30:9:30:13 | [b (line 24): true] dynamic access to element | normal | Splitting.cs:30:9:30:13 | [b (line 24): true] dynamic access to element | +| Splitting.cs:31:17:31:26 | [b (line 24): false] dynamic access to element | normal | Splitting.cs:31:17:31:26 | [b (line 24): false] dynamic access to element | +| Splitting.cs:31:17:31:26 | [b (line 24): true] dynamic access to element | normal | Splitting.cs:31:17:31:26 | [b (line 24): true] dynamic access to element | +| Splitting.cs:32:9:32:16 | [b (line 24): false] dynamic call to method Check | normal | Splitting.cs:32:9:32:16 | [b (line 24): false] dynamic call to method Check | +| Splitting.cs:32:9:32:16 | [b (line 24): true] dynamic call to method Check | normal | Splitting.cs:32:9:32:16 | [b (line 24): true] dynamic call to method Check | +| Splitting.cs:34:13:34:20 | dynamic call to method Check | normal | Splitting.cs:34:13:34:20 | dynamic call to method Check | +| This.cs:17:9:17:18 | object creation of type This | normal | This.cs:17:9:17:18 | object creation of type This | +| This.cs:28:13:28:21 | object creation of type Sub | normal | This.cs:28:13:28:21 | object creation of type Sub | +| file://:0:0:0:0 | [summary] call to collectionSelector in SelectMany | normal | file://:0:0:0:0 | [summary] read: return (normal) of argument 1 in SelectMany | +| file://:0:0:0:0 | [summary] call to collectionSelector in SelectMany | normal | file://:0:0:0:0 | [summary] read: return (normal) of argument 1 in SelectMany | +| file://:0:0:0:0 | [summary] call to collectionSelector in SelectMany | normal | file://:0:0:0:0 | [summary] read: return (normal) of argument 1 in SelectMany | +| file://:0:0:0:0 | [summary] call to collectionSelector in SelectMany | normal | file://:0:0:0:0 | [summary] read: return (normal) of argument 1 in SelectMany | +| file://:0:0:0:0 | [summary] call to continuationFunction in ContinueWhenAll | normal | file://:0:0:0:0 | [summary] read: return (normal) of argument 1 in ContinueWhenAll | +| file://:0:0:0:0 | [summary] call to continuationFunction in ContinueWhenAll | normal | file://:0:0:0:0 | [summary] read: return (normal) of argument 1 in ContinueWhenAll | +| file://:0:0:0:0 | [summary] call to continuationFunction in ContinueWhenAll | normal | file://:0:0:0:0 | [summary] read: return (normal) of argument 1 in ContinueWhenAll | +| file://:0:0:0:0 | [summary] call to continuationFunction in ContinueWhenAll | normal | file://:0:0:0:0 | [summary] read: return (normal) of argument 1 in ContinueWhenAll | +| file://:0:0:0:0 | [summary] call to continuationFunction in ContinueWhenAll | normal | file://:0:0:0:0 | [summary] read: return (normal) of argument 1 in ContinueWhenAll | +| file://:0:0:0:0 | [summary] call to continuationFunction in ContinueWhenAll | normal | file://:0:0:0:0 | [summary] read: return (normal) of argument 1 in ContinueWhenAll | +| file://:0:0:0:0 | [summary] call to continuationFunction in ContinueWhenAll | normal | file://:0:0:0:0 | [summary] read: return (normal) of argument 1 in ContinueWhenAll | +| file://:0:0:0:0 | [summary] call to continuationFunction in ContinueWhenAll | normal | file://:0:0:0:0 | [summary] read: return (normal) of argument 1 in ContinueWhenAll | +| file://:0:0:0:0 | [summary] call to continuationFunction in ContinueWhenAll | normal | file://:0:0:0:0 | [summary] read: return (normal) of argument 1 in ContinueWhenAll | +| file://:0:0:0:0 | [summary] call to continuationFunction in ContinueWhenAll | normal | file://:0:0:0:0 | [summary] read: return (normal) of argument 1 in ContinueWhenAll | +| file://:0:0:0:0 | [summary] call to continuationFunction in ContinueWhenAll | normal | file://:0:0:0:0 | [summary] read: return (normal) of argument 1 in ContinueWhenAll | +| file://:0:0:0:0 | [summary] call to continuationFunction in ContinueWhenAll | normal | file://:0:0:0:0 | [summary] read: return (normal) of argument 1 in ContinueWhenAll | +| file://:0:0:0:0 | [summary] call to continuationFunction in ContinueWhenAll | normal | file://:0:0:0:0 | [summary] read: return (normal) of argument 1 in ContinueWhenAll | +| file://:0:0:0:0 | [summary] call to continuationFunction in ContinueWhenAll | normal | file://:0:0:0:0 | [summary] read: return (normal) of argument 1 in ContinueWhenAll | +| file://:0:0:0:0 | [summary] call to continuationFunction in ContinueWhenAll | normal | file://:0:0:0:0 | [summary] read: return (normal) of argument 1 in ContinueWhenAll | +| file://:0:0:0:0 | [summary] call to continuationFunction in ContinueWhenAll | normal | file://:0:0:0:0 | [summary] read: return (normal) of argument 1 in ContinueWhenAll | +| file://:0:0:0:0 | [summary] call to continuationFunction in ContinueWhenAny | normal | file://:0:0:0:0 | [summary] read: return (normal) of argument 1 in ContinueWhenAny | +| file://:0:0:0:0 | [summary] call to continuationFunction in ContinueWhenAny | normal | file://:0:0:0:0 | [summary] read: return (normal) of argument 1 in ContinueWhenAny | +| file://:0:0:0:0 | [summary] call to continuationFunction in ContinueWhenAny | normal | file://:0:0:0:0 | [summary] read: return (normal) of argument 1 in ContinueWhenAny | +| file://:0:0:0:0 | [summary] call to continuationFunction in ContinueWhenAny | normal | file://:0:0:0:0 | [summary] read: return (normal) of argument 1 in ContinueWhenAny | +| file://:0:0:0:0 | [summary] call to continuationFunction in ContinueWhenAny | normal | file://:0:0:0:0 | [summary] read: return (normal) of argument 1 in ContinueWhenAny | +| file://:0:0:0:0 | [summary] call to continuationFunction in ContinueWhenAny | normal | file://:0:0:0:0 | [summary] read: return (normal) of argument 1 in ContinueWhenAny | +| file://:0:0:0:0 | [summary] call to continuationFunction in ContinueWhenAny | normal | file://:0:0:0:0 | [summary] read: return (normal) of argument 1 in ContinueWhenAny | +| file://:0:0:0:0 | [summary] call to continuationFunction in ContinueWhenAny | normal | file://:0:0:0:0 | [summary] read: return (normal) of argument 1 in ContinueWhenAny | +| file://:0:0:0:0 | [summary] call to continuationFunction in ContinueWhenAny | normal | file://:0:0:0:0 | [summary] read: return (normal) of argument 1 in ContinueWhenAny | +| file://:0:0:0:0 | [summary] call to continuationFunction in ContinueWhenAny | normal | file://:0:0:0:0 | [summary] read: return (normal) of argument 1 in ContinueWhenAny | +| file://:0:0:0:0 | [summary] call to continuationFunction in ContinueWhenAny | normal | file://:0:0:0:0 | [summary] read: return (normal) of argument 1 in ContinueWhenAny | +| file://:0:0:0:0 | [summary] call to continuationFunction in ContinueWhenAny | normal | file://:0:0:0:0 | [summary] read: return (normal) of argument 1 in ContinueWhenAny | +| file://:0:0:0:0 | [summary] call to continuationFunction in ContinueWhenAny | normal | file://:0:0:0:0 | [summary] read: return (normal) of argument 1 in ContinueWhenAny | +| file://:0:0:0:0 | [summary] call to continuationFunction in ContinueWhenAny | normal | file://:0:0:0:0 | [summary] read: return (normal) of argument 1 in ContinueWhenAny | +| file://:0:0:0:0 | [summary] call to continuationFunction in ContinueWhenAny | normal | file://:0:0:0:0 | [summary] read: return (normal) of argument 1 in ContinueWhenAny | +| file://:0:0:0:0 | [summary] call to continuationFunction in ContinueWhenAny | normal | file://:0:0:0:0 | [summary] read: return (normal) of argument 1 in ContinueWhenAny | +| file://:0:0:0:0 | [summary] call to continuationFunction in ContinueWith | normal | file://:0:0:0:0 | [summary] read: return (normal) of argument 0 in ContinueWith | +| file://:0:0:0:0 | [summary] call to continuationFunction in ContinueWith | normal | file://:0:0:0:0 | [summary] read: return (normal) of argument 0 in ContinueWith | +| file://:0:0:0:0 | [summary] call to continuationFunction in ContinueWith | normal | file://:0:0:0:0 | [summary] read: return (normal) of argument 0 in ContinueWith | +| file://:0:0:0:0 | [summary] call to continuationFunction in ContinueWith | normal | file://:0:0:0:0 | [summary] read: return (normal) of argument 0 in ContinueWith | +| file://:0:0:0:0 | [summary] call to continuationFunction in ContinueWith | normal | file://:0:0:0:0 | [summary] read: return (normal) of argument 0 in ContinueWith | +| file://:0:0:0:0 | [summary] call to continuationFunction in ContinueWith | normal | file://:0:0:0:0 | [summary] read: return (normal) of argument 0 in ContinueWith | +| file://:0:0:0:0 | [summary] call to continuationFunction in ContinueWith | normal | file://:0:0:0:0 | [summary] read: return (normal) of argument 0 in ContinueWith | +| file://:0:0:0:0 | [summary] call to continuationFunction in ContinueWith | normal | file://:0:0:0:0 | [summary] read: return (normal) of argument 0 in ContinueWith | +| file://:0:0:0:0 | [summary] call to continuationFunction in ContinueWith | normal | file://:0:0:0:0 | [summary] read: return (normal) of argument 0 in ContinueWith | +| file://:0:0:0:0 | [summary] call to continuationFunction in ContinueWith | normal | file://:0:0:0:0 | [summary] read: return (normal) of argument 0 in ContinueWith | +| file://:0:0:0:0 | [summary] call to continuationFunction in ContinueWith | normal | file://:0:0:0:0 | [summary] read: return (normal) of argument 0 in ContinueWith | +| file://:0:0:0:0 | [summary] call to continuationFunction in ContinueWith | normal | file://:0:0:0:0 | [summary] read: return (normal) of argument 0 in ContinueWith | +| file://:0:0:0:0 | [summary] call to continuationFunction in ContinueWith | normal | file://:0:0:0:0 | [summary] read: return (normal) of argument 0 in ContinueWith | +| file://:0:0:0:0 | [summary] call to continuationFunction in ContinueWith | normal | file://:0:0:0:0 | [summary] read: return (normal) of argument 0 in ContinueWith | +| file://:0:0:0:0 | [summary] call to continuationFunction in ContinueWith | normal | file://:0:0:0:0 | [summary] read: return (normal) of argument 0 in ContinueWith | +| file://:0:0:0:0 | [summary] call to continuationFunction in ContinueWith | normal | file://:0:0:0:0 | [summary] read: return (normal) of argument 0 in ContinueWith | +| file://:0:0:0:0 | [summary] call to continuationFunction in ContinueWith | normal | file://:0:0:0:0 | [summary] read: return (normal) of argument 0 in ContinueWith | +| file://:0:0:0:0 | [summary] call to continuationFunction in ContinueWith | normal | file://:0:0:0:0 | [summary] read: return (normal) of argument 0 in ContinueWith | +| file://:0:0:0:0 | [summary] call to continuationFunction in ContinueWith | normal | file://:0:0:0:0 | [summary] read: return (normal) of argument 0 in ContinueWith | +| file://:0:0:0:0 | [summary] call to continuationFunction in ContinueWith | normal | file://:0:0:0:0 | [summary] read: return (normal) of argument 0 in ContinueWith | +| file://:0:0:0:0 | [summary] call to elementSelector in GroupBy | normal | file://:0:0:0:0 | [summary] read: return (normal) of argument 2 in GroupBy | +| file://:0:0:0:0 | [summary] call to elementSelector in GroupBy | normal | file://:0:0:0:0 | [summary] read: return (normal) of argument 2 in GroupBy | +| file://:0:0:0:0 | [summary] call to elementSelector in GroupBy | normal | file://:0:0:0:0 | [summary] read: return (normal) of argument 2 in GroupBy | +| file://:0:0:0:0 | [summary] call to elementSelector in GroupBy | normal | file://:0:0:0:0 | [summary] read: return (normal) of argument 2 in GroupBy | +| file://:0:0:0:0 | [summary] call to elementSelector in GroupBy | normal | file://:0:0:0:0 | [summary] read: return (normal) of argument 2 in GroupBy | +| file://:0:0:0:0 | [summary] call to elementSelector in GroupBy | normal | file://:0:0:0:0 | [summary] read: return (normal) of argument 2 in GroupBy | +| file://:0:0:0:0 | [summary] call to elementSelector in ToDictionary | normal | file://:0:0:0:0 | [summary] read: return (normal) of argument 2 in ToDictionary | +| file://:0:0:0:0 | [summary] call to elementSelector in ToDictionary | normal | file://:0:0:0:0 | [summary] read: return (normal) of argument 2 in ToDictionary | +| file://:0:0:0:0 | [summary] call to elementSelector in ToLookup | normal | file://:0:0:0:0 | [summary] read: return (normal) of argument 2 in ToLookup | +| file://:0:0:0:0 | [summary] call to elementSelector in ToLookup | normal | file://:0:0:0:0 | [summary] read: return (normal) of argument 2 in ToLookup | +| file://:0:0:0:0 | [summary] call to func in Aggregate | normal | file://:0:0:0:0 | [summary] read: return (normal) of argument 1 in Aggregate | +| file://:0:0:0:0 | [summary] call to func in Aggregate | normal | file://:0:0:0:0 | [summary] read: return (normal) of argument 1 in Aggregate | +| file://:0:0:0:0 | [summary] call to func in Aggregate | normal | file://:0:0:0:0 | [summary] read: return (normal) of argument 2 in Aggregate | +| file://:0:0:0:0 | [summary] call to func in Aggregate | normal | file://:0:0:0:0 | [summary] read: return (normal) of argument 2 in Aggregate | +| file://:0:0:0:0 | [summary] call to func in Aggregate | normal | file://:0:0:0:0 | [summary] read: return (normal) of argument 2 in Aggregate | +| file://:0:0:0:0 | [summary] call to func in Aggregate | normal | file://:0:0:0:0 | [summary] read: return (normal) of argument 2 in Aggregate | +| file://:0:0:0:0 | [summary] call to function in Run | normal | file://:0:0:0:0 | [summary] read: return (normal) of argument 0 in Run | +| file://:0:0:0:0 | [summary] call to function in Run | normal | file://:0:0:0:0 | [summary] read: return (normal) of argument 0 in Run | +| file://:0:0:0:0 | [summary] call to function in Run | normal | file://:0:0:0:0 | [summary] read: return (normal) of argument 0 in Run | +| file://:0:0:0:0 | [summary] call to function in Run | normal | file://:0:0:0:0 | [summary] read: return (normal) of argument 0 in Run | +| file://:0:0:0:0 | [summary] call to function in StartNew | normal | file://:0:0:0:0 | [summary] read: return (normal) of argument 0 in StartNew | +| file://:0:0:0:0 | [summary] call to function in StartNew | normal | file://:0:0:0:0 | [summary] read: return (normal) of argument 0 in StartNew | +| file://:0:0:0:0 | [summary] call to function in StartNew | normal | file://:0:0:0:0 | [summary] read: return (normal) of argument 0 in StartNew | +| file://:0:0:0:0 | [summary] call to function in StartNew | normal | file://:0:0:0:0 | [summary] read: return (normal) of argument 0 in StartNew | +| file://:0:0:0:0 | [summary] call to function in StartNew | normal | file://:0:0:0:0 | [summary] read: return (normal) of argument 0 in StartNew | +| file://:0:0:0:0 | [summary] call to function in StartNew | normal | file://:0:0:0:0 | [summary] read: return (normal) of argument 0 in StartNew | +| file://:0:0:0:0 | [summary] call to function in StartNew | normal | file://:0:0:0:0 | [summary] read: return (normal) of argument 0 in StartNew | +| file://:0:0:0:0 | [summary] call to function in StartNew | normal | file://:0:0:0:0 | [summary] read: return (normal) of argument 0 in StartNew | +| file://:0:0:0:0 | [summary] call to function in StartNew | normal | file://:0:0:0:0 | [summary] read: return (normal) of argument 0 in StartNew | +| file://:0:0:0:0 | [summary] call to function in StartNew | normal | file://:0:0:0:0 | [summary] read: return (normal) of argument 0 in StartNew | +| file://:0:0:0:0 | [summary] call to function in StartNew | normal | file://:0:0:0:0 | [summary] read: return (normal) of argument 0 in StartNew | +| file://:0:0:0:0 | [summary] call to function in StartNew | normal | file://:0:0:0:0 | [summary] read: return (normal) of argument 0 in StartNew | +| file://:0:0:0:0 | [summary] call to function in StartNew | normal | file://:0:0:0:0 | [summary] read: return (normal) of argument 0 in StartNew | +| file://:0:0:0:0 | [summary] call to function in StartNew | normal | file://:0:0:0:0 | [summary] read: return (normal) of argument 0 in StartNew | +| file://:0:0:0:0 | [summary] call to function in StartNew | normal | file://:0:0:0:0 | [summary] read: return (normal) of argument 0 in StartNew | +| file://:0:0:0:0 | [summary] call to function in StartNew | normal | file://:0:0:0:0 | [summary] read: return (normal) of argument 0 in StartNew | +| file://:0:0:0:0 | [summary] call to function in Task | normal | file://:0:0:0:0 | [summary] read: return (normal) of argument 0 in Task | +| file://:0:0:0:0 | [summary] call to function in Task | normal | file://:0:0:0:0 | [summary] read: return (normal) of argument 0 in Task | +| file://:0:0:0:0 | [summary] call to function in Task | normal | file://:0:0:0:0 | [summary] read: return (normal) of argument 0 in Task | +| file://:0:0:0:0 | [summary] call to function in Task | normal | file://:0:0:0:0 | [summary] read: return (normal) of argument 0 in Task | +| file://:0:0:0:0 | [summary] call to function in Task | normal | file://:0:0:0:0 | [summary] read: return (normal) of argument 0 in Task | +| file://:0:0:0:0 | [summary] call to function in Task | normal | file://:0:0:0:0 | [summary] read: return (normal) of argument 0 in Task | +| file://:0:0:0:0 | [summary] call to function in Task | normal | file://:0:0:0:0 | [summary] read: return (normal) of argument 0 in Task | +| file://:0:0:0:0 | [summary] call to function in Task | normal | file://:0:0:0:0 | [summary] read: return (normal) of argument 0 in Task | +| file://:0:0:0:0 | [summary] call to keySelector in GroupBy | normal | file://:0:0:0:0 | [summary] read: return (normal) of argument 1 in GroupBy | +| file://:0:0:0:0 | [summary] call to keySelector in GroupBy | normal | file://:0:0:0:0 | [summary] read: return (normal) of argument 1 in GroupBy | +| file://:0:0:0:0 | [summary] call to keySelector in GroupBy | normal | file://:0:0:0:0 | [summary] read: return (normal) of argument 1 in GroupBy | +| file://:0:0:0:0 | [summary] call to keySelector in GroupBy | normal | file://:0:0:0:0 | [summary] read: return (normal) of argument 1 in GroupBy | +| file://:0:0:0:0 | [summary] call to keySelector in GroupBy | normal | file://:0:0:0:0 | [summary] read: return (normal) of argument 1 in GroupBy | +| file://:0:0:0:0 | [summary] call to keySelector in GroupBy | normal | file://:0:0:0:0 | [summary] read: return (normal) of argument 1 in GroupBy | +| file://:0:0:0:0 | [summary] call to keySelector in GroupBy | normal | file://:0:0:0:0 | [summary] read: return (normal) of argument 1 in GroupBy | +| file://:0:0:0:0 | [summary] call to keySelector in GroupBy | normal | file://:0:0:0:0 | [summary] read: return (normal) of argument 1 in GroupBy | +| file://:0:0:0:0 | [summary] call to keySelector in GroupBy | normal | file://:0:0:0:0 | [summary] read: return (normal) of argument 1 in GroupBy | +| file://:0:0:0:0 | [summary] call to resultSelector in Aggregate | normal | file://:0:0:0:0 | [summary] read: return (normal) of argument 3 in Aggregate | +| file://:0:0:0:0 | [summary] call to resultSelector in GroupBy | normal | file://:0:0:0:0 | [summary] read: return (normal) of argument 2 in GroupBy | +| file://:0:0:0:0 | [summary] call to resultSelector in GroupBy | normal | file://:0:0:0:0 | [summary] read: return (normal) of argument 2 in GroupBy | +| file://:0:0:0:0 | [summary] call to resultSelector in GroupBy | normal | file://:0:0:0:0 | [summary] read: return (normal) of argument 3 in GroupBy | +| file://:0:0:0:0 | [summary] call to resultSelector in GroupBy | normal | file://:0:0:0:0 | [summary] read: return (normal) of argument 3 in GroupBy | +| file://:0:0:0:0 | [summary] call to resultSelector in GroupBy | normal | file://:0:0:0:0 | [summary] read: return (normal) of argument 3 in GroupBy | +| file://:0:0:0:0 | [summary] call to resultSelector in GroupBy | normal | file://:0:0:0:0 | [summary] read: return (normal) of argument 3 in GroupBy | +| file://:0:0:0:0 | [summary] call to resultSelector in GroupJoin | normal | file://:0:0:0:0 | [summary] read: return (normal) of argument 4 in GroupJoin | +| file://:0:0:0:0 | [summary] call to resultSelector in GroupJoin | normal | file://:0:0:0:0 | [summary] read: return (normal) of argument 4 in GroupJoin | +| file://:0:0:0:0 | [summary] call to resultSelector in GroupJoin | normal | file://:0:0:0:0 | [summary] read: return (normal) of argument 4 in GroupJoin | +| file://:0:0:0:0 | [summary] call to resultSelector in GroupJoin | normal | file://:0:0:0:0 | [summary] read: return (normal) of argument 4 in GroupJoin | +| file://:0:0:0:0 | [summary] call to resultSelector in Join | normal | file://:0:0:0:0 | [summary] read: return (normal) of argument 4 in Join | +| file://:0:0:0:0 | [summary] call to resultSelector in Join | normal | file://:0:0:0:0 | [summary] read: return (normal) of argument 4 in Join | +| file://:0:0:0:0 | [summary] call to resultSelector in Join | normal | file://:0:0:0:0 | [summary] read: return (normal) of argument 4 in Join | +| file://:0:0:0:0 | [summary] call to resultSelector in Join | normal | file://:0:0:0:0 | [summary] read: return (normal) of argument 4 in Join | +| file://:0:0:0:0 | [summary] call to resultSelector in SelectMany | normal | file://:0:0:0:0 | [summary] read: return (normal) of argument 2 in SelectMany | +| file://:0:0:0:0 | [summary] call to resultSelector in SelectMany | normal | file://:0:0:0:0 | [summary] read: return (normal) of argument 2 in SelectMany | +| file://:0:0:0:0 | [summary] call to resultSelector in SelectMany | normal | file://:0:0:0:0 | [summary] read: return (normal) of argument 2 in SelectMany | +| file://:0:0:0:0 | [summary] call to resultSelector in SelectMany | normal | file://:0:0:0:0 | [summary] read: return (normal) of argument 2 in SelectMany | +| file://:0:0:0:0 | [summary] call to resultSelector in Zip | normal | file://:0:0:0:0 | [summary] read: return (normal) of argument 2 in Zip | +| file://:0:0:0:0 | [summary] call to resultSelector in Zip | normal | file://:0:0:0:0 | [summary] read: return (normal) of argument 2 in Zip | +| file://:0:0:0:0 | [summary] call to selector in Aggregate | normal | file://:0:0:0:0 | [summary] read: return (normal) of argument 3 in Aggregate | +| file://:0:0:0:0 | [summary] call to selector in Select | normal | file://:0:0:0:0 | [summary] read: return (normal) of argument 1 in Select | +| file://:0:0:0:0 | [summary] call to selector in Select | normal | file://:0:0:0:0 | [summary] read: return (normal) of argument 1 in Select | +| file://:0:0:0:0 | [summary] call to selector in Select | normal | file://:0:0:0:0 | [summary] read: return (normal) of argument 1 in Select | +| file://:0:0:0:0 | [summary] call to selector in Select | normal | file://:0:0:0:0 | [summary] read: return (normal) of argument 1 in Select | +| file://:0:0:0:0 | [summary] call to selector in SelectMany | normal | file://:0:0:0:0 | [summary] read: return (normal) of argument 1 in SelectMany | +| file://:0:0:0:0 | [summary] call to selector in SelectMany | normal | file://:0:0:0:0 | [summary] read: return (normal) of argument 1 in SelectMany | +| file://:0:0:0:0 | [summary] call to selector in SelectMany | normal | file://:0:0:0:0 | [summary] read: return (normal) of argument 1 in SelectMany | +| file://:0:0:0:0 | [summary] call to selector in SelectMany | normal | file://:0:0:0:0 | [summary] read: return (normal) of argument 1 in SelectMany | +| file://:0:0:0:0 | [summary] call to valueFactory in Lazy | normal | file://:0:0:0:0 | [summary] read: return (normal) of argument 0 in Lazy | +| file://:0:0:0:0 | [summary] call to valueFactory in Lazy | normal | file://:0:0:0:0 | [summary] read: return (normal) of argument 0 in Lazy | +| file://:0:0:0:0 | [summary] call to valueFactory in Lazy | normal | file://:0:0:0:0 | [summary] read: return (normal) of argument 0 in Lazy | diff --git a/csharp/ql/test/library-tests/dataflow/global/GlobalDataFlow.cs b/csharp/ql/test/library-tests/dataflow/global/GlobalDataFlow.cs index 4d072ca4d1c..5405acd5a6c 100644 --- a/csharp/ql/test/library-tests/dataflow/global/GlobalDataFlow.cs +++ b/csharp/ql/test/library-tests/dataflow/global/GlobalDataFlow.cs @@ -474,6 +474,18 @@ public class DataFlow var sink45 = awaiter.GetResult(); Check(sink45); } + + void M5(bool b) + { + void Inner(Action a, bool b, string arg) + { + if (b) + a = s => Check(s); + a(arg); + } + + Inner(_ => {}, b, "taint source"); + } } static class IEnumerableExtensions diff --git a/csharp/ql/test/library-tests/dataflow/global/TaintTracking.expected b/csharp/ql/test/library-tests/dataflow/global/TaintTracking.expected index fd800913202..43e5ee21e42 100644 --- a/csharp/ql/test/library-tests/dataflow/global/TaintTracking.expected +++ b/csharp/ql/test/library-tests/dataflow/global/TaintTracking.expected @@ -58,6 +58,7 @@ | GlobalDataFlow.cs:453:15:453:20 | access to local variable sink43 | | GlobalDataFlow.cs:463:15:463:20 | access to local variable sink44 | | GlobalDataFlow.cs:475:15:475:20 | access to local variable sink45 | +| GlobalDataFlow.cs:483:32:483:32 | access to parameter s | | Splitting.cs:9:15:9:15 | [b (line 3): false] access to local variable x | | Splitting.cs:9:15:9:15 | [b (line 3): true] access to local variable x | | Splitting.cs:11:19:11:19 | access to local variable x | diff --git a/csharp/ql/test/library-tests/dataflow/global/TaintTrackingPath.expected b/csharp/ql/test/library-tests/dataflow/global/TaintTrackingPath.expected index 7297686b5e3..2bd27156b17 100644 --- a/csharp/ql/test/library-tests/dataflow/global/TaintTrackingPath.expected +++ b/csharp/ql/test/library-tests/dataflow/global/TaintTrackingPath.expected @@ -119,36 +119,36 @@ edges | GlobalDataFlow.cs:79:30:79:34 | SSA def(sink3) : String | GlobalDataFlow.cs:80:15:80:19 | access to local variable sink3 | | GlobalDataFlow.cs:79:30:79:34 | SSA def(sink3) : String | GlobalDataFlow.cs:81:59:81:63 | access to local variable sink3 : String | | GlobalDataFlow.cs:79:30:79:34 | SSA def(sink3) : String | GlobalDataFlow.cs:136:29:136:33 | access to local variable sink3 : String | -| GlobalDataFlow.cs:81:22:81:85 | call to method SelectEven [[]] : String | GlobalDataFlow.cs:81:22:81:93 | call to method First : String | +| GlobalDataFlow.cs:81:22:81:85 | call to method SelectEven [element] : String | GlobalDataFlow.cs:81:22:81:93 | call to method First : String | | GlobalDataFlow.cs:81:22:81:93 | call to method First : String | GlobalDataFlow.cs:82:15:82:20 | access to local variable sink13 | | GlobalDataFlow.cs:81:22:81:93 | call to method First : String | GlobalDataFlow.cs:83:59:83:64 | access to local variable sink13 : String | -| GlobalDataFlow.cs:81:23:81:65 | (...) ... [[]] : String | GlobalDataFlow.cs:81:22:81:85 | call to method SelectEven [[]] : String | -| GlobalDataFlow.cs:81:57:81:65 | { ..., ... } [[]] : String | GlobalDataFlow.cs:81:23:81:65 | (...) ... [[]] : String | -| GlobalDataFlow.cs:81:59:81:63 | access to local variable sink3 : String | GlobalDataFlow.cs:81:57:81:65 | { ..., ... } [[]] : String | -| GlobalDataFlow.cs:83:22:83:87 | call to method Select [[]] : String | GlobalDataFlow.cs:83:22:83:95 | call to method First : String | +| GlobalDataFlow.cs:81:23:81:65 | (...) ... [element] : String | GlobalDataFlow.cs:81:22:81:85 | call to method SelectEven [element] : String | +| GlobalDataFlow.cs:81:57:81:65 | { ..., ... } [element] : String | GlobalDataFlow.cs:81:23:81:65 | (...) ... [element] : String | +| GlobalDataFlow.cs:81:59:81:63 | access to local variable sink3 : String | GlobalDataFlow.cs:81:57:81:65 | { ..., ... } [element] : String | +| GlobalDataFlow.cs:83:22:83:87 | call to method Select [element] : String | GlobalDataFlow.cs:83:22:83:95 | call to method First : String | | GlobalDataFlow.cs:83:22:83:95 | call to method First : String | GlobalDataFlow.cs:84:15:84:20 | access to local variable sink14 | | GlobalDataFlow.cs:83:22:83:95 | call to method First : String | GlobalDataFlow.cs:85:59:85:64 | access to local variable sink14 : String | | GlobalDataFlow.cs:83:22:83:95 | call to method First : String | GlobalDataFlow.cs:89:59:89:64 | access to local variable sink14 : String | | GlobalDataFlow.cs:83:22:83:95 | call to method First : String | GlobalDataFlow.cs:91:75:91:80 | access to local variable sink14 : String | -| GlobalDataFlow.cs:83:23:83:66 | (...) ... [[]] : String | GlobalDataFlow.cs:83:22:83:87 | call to method Select [[]] : String | -| GlobalDataFlow.cs:83:23:83:66 | (...) ... [[]] : String | GlobalDataFlow.cs:312:31:312:40 | sinkParam8 : String | -| GlobalDataFlow.cs:83:57:83:66 | { ..., ... } [[]] : String | GlobalDataFlow.cs:83:23:83:66 | (...) ... [[]] : String | -| GlobalDataFlow.cs:83:59:83:64 | access to local variable sink13 : String | GlobalDataFlow.cs:83:57:83:66 | { ..., ... } [[]] : String | -| GlobalDataFlow.cs:85:22:85:128 | call to method Zip [[]] : String | GlobalDataFlow.cs:85:22:85:136 | call to method First : String | +| GlobalDataFlow.cs:83:23:83:66 | (...) ... [element] : String | GlobalDataFlow.cs:83:22:83:87 | call to method Select [element] : String | +| GlobalDataFlow.cs:83:23:83:66 | (...) ... [element] : String | GlobalDataFlow.cs:312:31:312:40 | sinkParam8 : String | +| GlobalDataFlow.cs:83:57:83:66 | { ..., ... } [element] : String | GlobalDataFlow.cs:83:23:83:66 | (...) ... [element] : String | +| GlobalDataFlow.cs:83:59:83:64 | access to local variable sink13 : String | GlobalDataFlow.cs:83:57:83:66 | { ..., ... } [element] : String | +| GlobalDataFlow.cs:85:22:85:128 | call to method Zip [element] : String | GlobalDataFlow.cs:85:22:85:136 | call to method First : String | | GlobalDataFlow.cs:85:22:85:136 | call to method First : String | GlobalDataFlow.cs:86:15:86:20 | access to local variable sink15 | | GlobalDataFlow.cs:85:22:85:136 | call to method First : String | GlobalDataFlow.cs:87:106:87:111 | access to local variable sink15 : String | -| GlobalDataFlow.cs:85:23:85:66 | (...) ... [[]] : String | GlobalDataFlow.cs:85:22:85:128 | call to method Zip [[]] : String | -| GlobalDataFlow.cs:85:57:85:66 | { ..., ... } [[]] : String | GlobalDataFlow.cs:85:23:85:66 | (...) ... [[]] : String | -| GlobalDataFlow.cs:85:59:85:64 | access to local variable sink14 : String | GlobalDataFlow.cs:85:57:85:66 | { ..., ... } [[]] : String | -| GlobalDataFlow.cs:87:22:87:128 | call to method Zip [[]] : String | GlobalDataFlow.cs:87:22:87:136 | call to method First : String | +| GlobalDataFlow.cs:85:23:85:66 | (...) ... [element] : String | GlobalDataFlow.cs:85:22:85:128 | call to method Zip [element] : String | +| GlobalDataFlow.cs:85:57:85:66 | { ..., ... } [element] : String | GlobalDataFlow.cs:85:23:85:66 | (...) ... [element] : String | +| GlobalDataFlow.cs:85:59:85:64 | access to local variable sink14 : String | GlobalDataFlow.cs:85:57:85:66 | { ..., ... } [element] : String | +| GlobalDataFlow.cs:87:22:87:128 | call to method Zip [element] : String | GlobalDataFlow.cs:87:22:87:136 | call to method First : String | | GlobalDataFlow.cs:87:22:87:136 | call to method First : String | GlobalDataFlow.cs:88:15:88:20 | access to local variable sink16 | -| GlobalDataFlow.cs:87:70:87:113 | (...) ... [[]] : String | GlobalDataFlow.cs:87:22:87:128 | call to method Zip [[]] : String | -| GlobalDataFlow.cs:87:104:87:113 | { ..., ... } [[]] : String | GlobalDataFlow.cs:87:70:87:113 | (...) ... [[]] : String | -| GlobalDataFlow.cs:87:106:87:111 | access to local variable sink15 : String | GlobalDataFlow.cs:87:104:87:113 | { ..., ... } [[]] : String | +| GlobalDataFlow.cs:87:70:87:113 | (...) ... [element] : String | GlobalDataFlow.cs:87:22:87:128 | call to method Zip [element] : String | +| GlobalDataFlow.cs:87:104:87:113 | { ..., ... } [element] : String | GlobalDataFlow.cs:87:70:87:113 | (...) ... [element] : String | +| GlobalDataFlow.cs:87:106:87:111 | access to local variable sink15 : String | GlobalDataFlow.cs:87:104:87:113 | { ..., ... } [element] : String | | GlobalDataFlow.cs:89:22:89:110 | call to method Aggregate : String | GlobalDataFlow.cs:90:15:90:20 | access to local variable sink17 | -| GlobalDataFlow.cs:89:23:89:66 | (...) ... [[]] : String | GlobalDataFlow.cs:89:22:89:110 | call to method Aggregate : String | -| GlobalDataFlow.cs:89:57:89:66 | { ..., ... } [[]] : String | GlobalDataFlow.cs:89:23:89:66 | (...) ... [[]] : String | -| GlobalDataFlow.cs:89:59:89:64 | access to local variable sink14 : String | GlobalDataFlow.cs:89:57:89:66 | { ..., ... } [[]] : String | +| GlobalDataFlow.cs:89:23:89:66 | (...) ... [element] : String | GlobalDataFlow.cs:89:22:89:110 | call to method Aggregate : String | +| GlobalDataFlow.cs:89:57:89:66 | { ..., ... } [element] : String | GlobalDataFlow.cs:89:23:89:66 | (...) ... [element] : String | +| GlobalDataFlow.cs:89:59:89:64 | access to local variable sink14 : String | GlobalDataFlow.cs:89:57:89:66 | { ..., ... } [element] : String | | GlobalDataFlow.cs:91:22:91:110 | call to method Aggregate : String | GlobalDataFlow.cs:92:15:92:20 | access to local variable sink18 | | GlobalDataFlow.cs:91:22:91:110 | call to method Aggregate : String | GlobalDataFlow.cs:94:24:94:29 | access to local variable sink18 : String | | GlobalDataFlow.cs:91:22:91:110 | call to method Aggregate : String | GlobalDataFlow.cs:97:23:97:28 | access to local variable sink18 : String | @@ -165,42 +165,42 @@ edges | GlobalDataFlow.cs:154:21:154:25 | call to method Out : String | GlobalDataFlow.cs:155:15:155:19 | access to local variable sink6 | | GlobalDataFlow.cs:157:20:157:24 | SSA def(sink7) : String | GlobalDataFlow.cs:158:15:158:19 | access to local variable sink7 | | GlobalDataFlow.cs:160:20:160:24 | SSA def(sink8) : String | GlobalDataFlow.cs:161:15:161:19 | access to local variable sink8 | -| GlobalDataFlow.cs:162:22:162:31 | call to method OutYield [[]] : String | GlobalDataFlow.cs:162:22:162:39 | call to method First : String | +| GlobalDataFlow.cs:162:22:162:31 | call to method OutYield [element] : String | GlobalDataFlow.cs:162:22:162:39 | call to method First : String | | GlobalDataFlow.cs:162:22:162:39 | call to method First : String | GlobalDataFlow.cs:163:15:163:20 | access to local variable sink12 | | GlobalDataFlow.cs:164:22:164:43 | call to method TaintedParam : String | GlobalDataFlow.cs:165:15:165:20 | access to local variable sink23 | | GlobalDataFlow.cs:180:35:180:48 | "taint source" : String | GlobalDataFlow.cs:181:21:181:26 | delegate call : String | | GlobalDataFlow.cs:181:21:181:26 | delegate call : String | GlobalDataFlow.cs:182:15:182:19 | access to local variable sink9 | -| GlobalDataFlow.cs:190:22:190:42 | object creation of type Lazy [Value] : String | GlobalDataFlow.cs:190:22:190:48 | access to property Value : String | +| GlobalDataFlow.cs:190:22:190:42 | object creation of type Lazy [property Value] : String | GlobalDataFlow.cs:190:22:190:48 | access to property Value : String | | GlobalDataFlow.cs:190:22:190:48 | access to property Value : String | GlobalDataFlow.cs:191:15:191:20 | access to local variable sink10 | | GlobalDataFlow.cs:198:22:198:32 | access to property OutProperty : String | GlobalDataFlow.cs:199:15:199:20 | access to local variable sink19 | -| GlobalDataFlow.cs:208:38:208:61 | array creation of type String[] [[]] : String | GlobalDataFlow.cs:208:38:208:75 | call to method AsQueryable [[]] : String | -| GlobalDataFlow.cs:208:38:208:75 | call to method AsQueryable [[]] : String | GlobalDataFlow.cs:213:22:213:28 | access to local variable tainted [[]] : String | -| GlobalDataFlow.cs:208:38:208:75 | call to method AsQueryable [[]] : String | GlobalDataFlow.cs:215:22:215:28 | access to local variable tainted [[]] : String | -| GlobalDataFlow.cs:208:38:208:75 | call to method AsQueryable [[]] : String | GlobalDataFlow.cs:217:22:217:28 | access to local variable tainted [[]] : String | -| GlobalDataFlow.cs:208:44:208:61 | { ..., ... } [[]] : String | GlobalDataFlow.cs:208:38:208:61 | array creation of type String[] [[]] : String | -| GlobalDataFlow.cs:208:46:208:59 | "taint source" : String | GlobalDataFlow.cs:208:44:208:61 | { ..., ... } [[]] : String | +| GlobalDataFlow.cs:208:38:208:61 | array creation of type String[] [element] : String | GlobalDataFlow.cs:208:38:208:75 | call to method AsQueryable [element] : String | +| GlobalDataFlow.cs:208:38:208:75 | call to method AsQueryable [element] : String | GlobalDataFlow.cs:213:22:213:28 | access to local variable tainted [element] : String | +| GlobalDataFlow.cs:208:38:208:75 | call to method AsQueryable [element] : String | GlobalDataFlow.cs:215:22:215:28 | access to local variable tainted [element] : String | +| GlobalDataFlow.cs:208:38:208:75 | call to method AsQueryable [element] : String | GlobalDataFlow.cs:217:22:217:28 | access to local variable tainted [element] : String | +| GlobalDataFlow.cs:208:44:208:61 | { ..., ... } [element] : String | GlobalDataFlow.cs:208:38:208:61 | array creation of type String[] [element] : String | +| GlobalDataFlow.cs:208:46:208:59 | "taint source" : String | GlobalDataFlow.cs:208:44:208:61 | { ..., ... } [element] : String | | GlobalDataFlow.cs:211:35:211:45 | sinkParam10 : String | GlobalDataFlow.cs:211:58:211:68 | access to parameter sinkParam10 | | GlobalDataFlow.cs:212:71:212:71 | x : String | GlobalDataFlow.cs:212:89:212:89 | access to parameter x : String | | GlobalDataFlow.cs:212:89:212:89 | access to parameter x : String | GlobalDataFlow.cs:318:32:318:41 | sinkParam9 : String | -| GlobalDataFlow.cs:213:22:213:28 | access to local variable tainted [[]] : String | GlobalDataFlow.cs:211:35:211:45 | sinkParam10 : String | -| GlobalDataFlow.cs:213:22:213:28 | access to local variable tainted [[]] : String | GlobalDataFlow.cs:213:22:213:39 | call to method Select [[]] : String | -| GlobalDataFlow.cs:213:22:213:39 | call to method Select [[]] : String | GlobalDataFlow.cs:213:22:213:47 | call to method First : String | +| GlobalDataFlow.cs:213:22:213:28 | access to local variable tainted [element] : String | GlobalDataFlow.cs:211:35:211:45 | sinkParam10 : String | +| GlobalDataFlow.cs:213:22:213:28 | access to local variable tainted [element] : String | GlobalDataFlow.cs:213:22:213:39 | call to method Select [element] : String | +| GlobalDataFlow.cs:213:22:213:39 | call to method Select [element] : String | GlobalDataFlow.cs:213:22:213:47 | call to method First : String | | GlobalDataFlow.cs:213:22:213:47 | call to method First : String | GlobalDataFlow.cs:214:15:214:20 | access to local variable sink24 | -| GlobalDataFlow.cs:215:22:215:28 | access to local variable tainted [[]] : String | GlobalDataFlow.cs:212:71:212:71 | x : String | -| GlobalDataFlow.cs:215:22:215:28 | access to local variable tainted [[]] : String | GlobalDataFlow.cs:215:22:215:39 | call to method Select [[]] : String | -| GlobalDataFlow.cs:215:22:215:39 | call to method Select [[]] : String | GlobalDataFlow.cs:215:22:215:47 | call to method First : String | +| GlobalDataFlow.cs:215:22:215:28 | access to local variable tainted [element] : String | GlobalDataFlow.cs:212:71:212:71 | x : String | +| GlobalDataFlow.cs:215:22:215:28 | access to local variable tainted [element] : String | GlobalDataFlow.cs:215:22:215:39 | call to method Select [element] : String | +| GlobalDataFlow.cs:215:22:215:39 | call to method Select [element] : String | GlobalDataFlow.cs:215:22:215:47 | call to method First : String | | GlobalDataFlow.cs:215:22:215:47 | call to method First : String | GlobalDataFlow.cs:216:15:216:20 | access to local variable sink25 | -| GlobalDataFlow.cs:217:22:217:28 | access to local variable tainted [[]] : String | GlobalDataFlow.cs:217:22:217:49 | call to method Select [[]] : String | -| GlobalDataFlow.cs:217:22:217:28 | access to local variable tainted [[]] : String | GlobalDataFlow.cs:324:32:324:42 | sinkParam11 : String | -| GlobalDataFlow.cs:217:22:217:49 | call to method Select [[]] : String | GlobalDataFlow.cs:217:22:217:57 | call to method First : String | +| GlobalDataFlow.cs:217:22:217:28 | access to local variable tainted [element] : String | GlobalDataFlow.cs:217:22:217:49 | call to method Select [element] : String | +| GlobalDataFlow.cs:217:22:217:28 | access to local variable tainted [element] : String | GlobalDataFlow.cs:324:32:324:42 | sinkParam11 : String | +| GlobalDataFlow.cs:217:22:217:49 | call to method Select [element] : String | GlobalDataFlow.cs:217:22:217:57 | call to method First : String | | GlobalDataFlow.cs:217:22:217:57 | call to method First : String | GlobalDataFlow.cs:218:15:218:20 | access to local variable sink26 | -| GlobalDataFlow.cs:238:20:238:49 | call to method Run [Result] : String | GlobalDataFlow.cs:239:22:239:25 | access to local variable task [Result] : String | -| GlobalDataFlow.cs:238:20:238:49 | call to method Run [Result] : String | GlobalDataFlow.cs:241:28:241:31 | access to local variable task [Result] : String | -| GlobalDataFlow.cs:238:35:238:48 | "taint source" : String | GlobalDataFlow.cs:238:20:238:49 | call to method Run [Result] : String | -| GlobalDataFlow.cs:239:22:239:25 | access to local variable task [Result] : String | GlobalDataFlow.cs:239:22:239:32 | access to property Result : String | +| GlobalDataFlow.cs:238:20:238:49 | call to method Run [property Result] : String | GlobalDataFlow.cs:239:22:239:25 | access to local variable task [property Result] : String | +| GlobalDataFlow.cs:238:20:238:49 | call to method Run [property Result] : String | GlobalDataFlow.cs:241:28:241:31 | access to local variable task [property Result] : String | +| GlobalDataFlow.cs:238:35:238:48 | "taint source" : String | GlobalDataFlow.cs:238:20:238:49 | call to method Run [property Result] : String | +| GlobalDataFlow.cs:239:22:239:25 | access to local variable task [property Result] : String | GlobalDataFlow.cs:239:22:239:32 | access to property Result : String | | GlobalDataFlow.cs:239:22:239:32 | access to property Result : String | GlobalDataFlow.cs:240:15:240:20 | access to local variable sink41 | | GlobalDataFlow.cs:241:22:241:31 | await ... : String | GlobalDataFlow.cs:242:15:242:20 | access to local variable sink42 | -| GlobalDataFlow.cs:241:28:241:31 | access to local variable task [Result] : String | GlobalDataFlow.cs:241:22:241:31 | await ... : String | +| GlobalDataFlow.cs:241:28:241:31 | access to local variable task [property Result] : String | GlobalDataFlow.cs:241:22:241:31 | await ... : String | | GlobalDataFlow.cs:254:26:254:35 | sinkParam0 : String | GlobalDataFlow.cs:256:16:256:25 | access to parameter sinkParam0 : String | | GlobalDataFlow.cs:254:26:254:35 | sinkParam0 : String | GlobalDataFlow.cs:257:15:257:24 | access to parameter sinkParam0 | | GlobalDataFlow.cs:256:16:256:25 | access to parameter sinkParam0 : String | GlobalDataFlow.cs:254:26:254:35 | sinkParam0 : String | @@ -214,12 +214,12 @@ edges | GlobalDataFlow.cs:318:32:318:41 | sinkParam9 : String | GlobalDataFlow.cs:320:15:320:24 | access to parameter sinkParam9 | | GlobalDataFlow.cs:324:32:324:42 | sinkParam11 : String | GlobalDataFlow.cs:326:15:326:25 | access to parameter sinkParam11 | | GlobalDataFlow.cs:338:16:338:29 | "taint source" : String | GlobalDataFlow.cs:154:21:154:25 | call to method Out : String | -| GlobalDataFlow.cs:338:16:338:29 | "taint source" : String | GlobalDataFlow.cs:190:22:190:42 | object creation of type Lazy [Value] : String | +| GlobalDataFlow.cs:338:16:338:29 | "taint source" : String | GlobalDataFlow.cs:190:22:190:42 | object creation of type Lazy [property Value] : String | | GlobalDataFlow.cs:343:9:343:26 | SSA def(x) : String | GlobalDataFlow.cs:157:20:157:24 | SSA def(sink7) : String | | GlobalDataFlow.cs:343:13:343:26 | "taint source" : String | GlobalDataFlow.cs:343:9:343:26 | SSA def(x) : String | | GlobalDataFlow.cs:348:9:348:26 | SSA def(x) : String | GlobalDataFlow.cs:160:20:160:24 | SSA def(sink8) : String | | GlobalDataFlow.cs:348:13:348:26 | "taint source" : String | GlobalDataFlow.cs:348:9:348:26 | SSA def(x) : String | -| GlobalDataFlow.cs:354:22:354:35 | "taint source" : String | GlobalDataFlow.cs:162:22:162:31 | call to method OutYield [[]] : String | +| GlobalDataFlow.cs:354:22:354:35 | "taint source" : String | GlobalDataFlow.cs:162:22:162:31 | call to method OutYield [element] : String | | GlobalDataFlow.cs:379:41:379:41 | x : String | GlobalDataFlow.cs:381:11:381:11 | access to parameter x : String | | GlobalDataFlow.cs:379:41:379:41 | x : String | GlobalDataFlow.cs:381:11:381:11 | access to parameter x : String | | GlobalDataFlow.cs:381:11:381:11 | access to parameter x : String | GlobalDataFlow.cs:54:15:54:15 | x : String | @@ -235,20 +235,24 @@ edges | GlobalDataFlow.cs:402:16:402:21 | access to local variable sink11 : String | GlobalDataFlow.cs:164:22:164:43 | call to method TaintedParam : String | | GlobalDataFlow.cs:424:9:424:11 | value : String | GlobalDataFlow.cs:424:41:424:46 | access to local variable sink20 | | GlobalDataFlow.cs:435:22:435:35 | "taint source" : String | GlobalDataFlow.cs:198:22:198:32 | access to property OutProperty : String | -| GlobalDataFlow.cs:451:31:451:32 | [post] access to local variable sb [[]] : String | GlobalDataFlow.cs:452:22:452:23 | access to local variable sb [[]] : String | -| GlobalDataFlow.cs:451:35:451:48 | "taint source" : String | GlobalDataFlow.cs:451:31:451:32 | [post] access to local variable sb [[]] : String | -| GlobalDataFlow.cs:452:22:452:23 | access to local variable sb [[]] : String | GlobalDataFlow.cs:452:22:452:34 | call to method ToString : String | +| GlobalDataFlow.cs:451:31:451:32 | [post] access to local variable sb [element] : String | GlobalDataFlow.cs:452:22:452:23 | access to local variable sb [element] : String | +| GlobalDataFlow.cs:451:35:451:48 | "taint source" : String | GlobalDataFlow.cs:451:31:451:32 | [post] access to local variable sb [element] : String | +| GlobalDataFlow.cs:452:22:452:23 | access to local variable sb [element] : String | GlobalDataFlow.cs:452:22:452:34 | call to method ToString : String | | GlobalDataFlow.cs:452:22:452:34 | call to method ToString : String | GlobalDataFlow.cs:453:15:453:20 | access to local variable sink43 | | GlobalDataFlow.cs:462:22:462:65 | call to method Join : String | GlobalDataFlow.cs:463:15:463:20 | access to local variable sink44 | | GlobalDataFlow.cs:462:51:462:64 | "taint source" : String | GlobalDataFlow.cs:462:22:462:65 | call to method Join : String | -| GlobalDataFlow.cs:471:20:471:49 | call to method Run [Result] : String | GlobalDataFlow.cs:472:25:472:28 | access to local variable task [Result] : String | -| GlobalDataFlow.cs:471:35:471:48 | "taint source" : String | GlobalDataFlow.cs:471:20:471:49 | call to method Run [Result] : String | -| GlobalDataFlow.cs:472:25:472:28 | access to local variable task [Result] : String | GlobalDataFlow.cs:472:25:472:50 | call to method ConfigureAwait [m_configuredTaskAwaiter, m_task, Result] : String | -| GlobalDataFlow.cs:472:25:472:50 | call to method ConfigureAwait [m_configuredTaskAwaiter, m_task, Result] : String | GlobalDataFlow.cs:473:23:473:31 | access to local variable awaitable [m_configuredTaskAwaiter, m_task, Result] : String | -| GlobalDataFlow.cs:473:23:473:31 | access to local variable awaitable [m_configuredTaskAwaiter, m_task, Result] : String | GlobalDataFlow.cs:473:23:473:44 | call to method GetAwaiter [m_task, Result] : String | -| GlobalDataFlow.cs:473:23:473:44 | call to method GetAwaiter [m_task, Result] : String | GlobalDataFlow.cs:474:22:474:28 | access to local variable awaiter [m_task, Result] : String | -| GlobalDataFlow.cs:474:22:474:28 | access to local variable awaiter [m_task, Result] : String | GlobalDataFlow.cs:474:22:474:40 | call to method GetResult : String | +| GlobalDataFlow.cs:471:20:471:49 | call to method Run [property Result] : String | GlobalDataFlow.cs:472:25:472:28 | access to local variable task [property Result] : String | +| GlobalDataFlow.cs:471:35:471:48 | "taint source" : String | GlobalDataFlow.cs:471:20:471:49 | call to method Run [property Result] : String | +| GlobalDataFlow.cs:472:25:472:28 | access to local variable task [property Result] : String | GlobalDataFlow.cs:472:25:472:50 | call to method ConfigureAwait [field m_configuredTaskAwaiter, field m_task, property Result] : String | +| GlobalDataFlow.cs:472:25:472:50 | call to method ConfigureAwait [field m_configuredTaskAwaiter, field m_task, property Result] : String | GlobalDataFlow.cs:473:23:473:31 | access to local variable awaitable [field m_configuredTaskAwaiter, field m_task, property Result] : String | +| GlobalDataFlow.cs:473:23:473:31 | access to local variable awaitable [field m_configuredTaskAwaiter, field m_task, property Result] : String | GlobalDataFlow.cs:473:23:473:44 | call to method GetAwaiter [field m_task, property Result] : String | +| GlobalDataFlow.cs:473:23:473:44 | call to method GetAwaiter [field m_task, property Result] : String | GlobalDataFlow.cs:474:22:474:28 | access to local variable awaiter [field m_task, property Result] : String | +| GlobalDataFlow.cs:474:22:474:28 | access to local variable awaiter [field m_task, property Result] : String | GlobalDataFlow.cs:474:22:474:40 | call to method GetResult : String | | GlobalDataFlow.cs:474:22:474:40 | call to method GetResult : String | GlobalDataFlow.cs:475:15:475:20 | access to local variable sink45 | +| GlobalDataFlow.cs:480:53:480:55 | arg : String | GlobalDataFlow.cs:484:15:484:17 | access to parameter arg : String | +| GlobalDataFlow.cs:483:21:483:21 | s : String | GlobalDataFlow.cs:483:32:483:32 | access to parameter s | +| GlobalDataFlow.cs:484:15:484:17 | access to parameter arg : String | GlobalDataFlow.cs:483:21:483:21 | s : String | +| GlobalDataFlow.cs:487:27:487:40 | "taint source" : String | GlobalDataFlow.cs:480:53:480:55 | arg : String | | Splitting.cs:3:28:3:34 | tainted : String | Splitting.cs:8:24:8:30 | [b (line 3): false] access to parameter tainted : String | | Splitting.cs:3:28:3:34 | tainted : String | Splitting.cs:8:24:8:30 | [b (line 3): true] access to parameter tainted : String | | Splitting.cs:8:17:8:31 | [b (line 3): false] call to method Return : String | Splitting.cs:9:15:9:15 | [b (line 3): false] access to local variable x | @@ -335,33 +339,33 @@ nodes | GlobalDataFlow.cs:79:19:79:23 | access to local variable sink2 : String | semmle.label | access to local variable sink2 : String | | GlobalDataFlow.cs:79:30:79:34 | SSA def(sink3) : String | semmle.label | SSA def(sink3) : String | | GlobalDataFlow.cs:80:15:80:19 | access to local variable sink3 | semmle.label | access to local variable sink3 | -| GlobalDataFlow.cs:81:22:81:85 | call to method SelectEven [[]] : String | semmle.label | call to method SelectEven [[]] : String | +| GlobalDataFlow.cs:81:22:81:85 | call to method SelectEven [element] : String | semmle.label | call to method SelectEven [element] : String | | GlobalDataFlow.cs:81:22:81:93 | call to method First : String | semmle.label | call to method First : String | -| GlobalDataFlow.cs:81:23:81:65 | (...) ... [[]] : String | semmle.label | (...) ... [[]] : String | -| GlobalDataFlow.cs:81:57:81:65 | { ..., ... } [[]] : String | semmle.label | { ..., ... } [[]] : String | +| GlobalDataFlow.cs:81:23:81:65 | (...) ... [element] : String | semmle.label | (...) ... [element] : String | +| GlobalDataFlow.cs:81:57:81:65 | { ..., ... } [element] : String | semmle.label | { ..., ... } [element] : String | | GlobalDataFlow.cs:81:59:81:63 | access to local variable sink3 : String | semmle.label | access to local variable sink3 : String | | GlobalDataFlow.cs:82:15:82:20 | access to local variable sink13 | semmle.label | access to local variable sink13 | -| GlobalDataFlow.cs:83:22:83:87 | call to method Select [[]] : String | semmle.label | call to method Select [[]] : String | +| GlobalDataFlow.cs:83:22:83:87 | call to method Select [element] : String | semmle.label | call to method Select [element] : String | | GlobalDataFlow.cs:83:22:83:95 | call to method First : String | semmle.label | call to method First : String | -| GlobalDataFlow.cs:83:23:83:66 | (...) ... [[]] : String | semmle.label | (...) ... [[]] : String | -| GlobalDataFlow.cs:83:57:83:66 | { ..., ... } [[]] : String | semmle.label | { ..., ... } [[]] : String | +| GlobalDataFlow.cs:83:23:83:66 | (...) ... [element] : String | semmle.label | (...) ... [element] : String | +| GlobalDataFlow.cs:83:57:83:66 | { ..., ... } [element] : String | semmle.label | { ..., ... } [element] : String | | GlobalDataFlow.cs:83:59:83:64 | access to local variable sink13 : String | semmle.label | access to local variable sink13 : String | | GlobalDataFlow.cs:84:15:84:20 | access to local variable sink14 | semmle.label | access to local variable sink14 | -| GlobalDataFlow.cs:85:22:85:128 | call to method Zip [[]] : String | semmle.label | call to method Zip [[]] : String | +| GlobalDataFlow.cs:85:22:85:128 | call to method Zip [element] : String | semmle.label | call to method Zip [element] : String | | GlobalDataFlow.cs:85:22:85:136 | call to method First : String | semmle.label | call to method First : String | -| GlobalDataFlow.cs:85:23:85:66 | (...) ... [[]] : String | semmle.label | (...) ... [[]] : String | -| GlobalDataFlow.cs:85:57:85:66 | { ..., ... } [[]] : String | semmle.label | { ..., ... } [[]] : String | +| GlobalDataFlow.cs:85:23:85:66 | (...) ... [element] : String | semmle.label | (...) ... [element] : String | +| GlobalDataFlow.cs:85:57:85:66 | { ..., ... } [element] : String | semmle.label | { ..., ... } [element] : String | | GlobalDataFlow.cs:85:59:85:64 | access to local variable sink14 : String | semmle.label | access to local variable sink14 : String | | GlobalDataFlow.cs:86:15:86:20 | access to local variable sink15 | semmle.label | access to local variable sink15 | -| GlobalDataFlow.cs:87:22:87:128 | call to method Zip [[]] : String | semmle.label | call to method Zip [[]] : String | +| GlobalDataFlow.cs:87:22:87:128 | call to method Zip [element] : String | semmle.label | call to method Zip [element] : String | | GlobalDataFlow.cs:87:22:87:136 | call to method First : String | semmle.label | call to method First : String | -| GlobalDataFlow.cs:87:70:87:113 | (...) ... [[]] : String | semmle.label | (...) ... [[]] : String | -| GlobalDataFlow.cs:87:104:87:113 | { ..., ... } [[]] : String | semmle.label | { ..., ... } [[]] : String | +| GlobalDataFlow.cs:87:70:87:113 | (...) ... [element] : String | semmle.label | (...) ... [element] : String | +| GlobalDataFlow.cs:87:104:87:113 | { ..., ... } [element] : String | semmle.label | { ..., ... } [element] : String | | GlobalDataFlow.cs:87:106:87:111 | access to local variable sink15 : String | semmle.label | access to local variable sink15 : String | | GlobalDataFlow.cs:88:15:88:20 | access to local variable sink16 | semmle.label | access to local variable sink16 | | GlobalDataFlow.cs:89:22:89:110 | call to method Aggregate : String | semmle.label | call to method Aggregate : String | -| GlobalDataFlow.cs:89:23:89:66 | (...) ... [[]] : String | semmle.label | (...) ... [[]] : String | -| GlobalDataFlow.cs:89:57:89:66 | { ..., ... } [[]] : String | semmle.label | { ..., ... } [[]] : String | +| GlobalDataFlow.cs:89:23:89:66 | (...) ... [element] : String | semmle.label | (...) ... [element] : String | +| GlobalDataFlow.cs:89:57:89:66 | { ..., ... } [element] : String | semmle.label | { ..., ... } [element] : String | | GlobalDataFlow.cs:89:59:89:64 | access to local variable sink14 : String | semmle.label | access to local variable sink14 : String | | GlobalDataFlow.cs:90:15:90:20 | access to local variable sink17 | semmle.label | access to local variable sink17 | | GlobalDataFlow.cs:91:22:91:110 | call to method Aggregate : String | semmle.label | call to method Aggregate : String | @@ -385,7 +389,7 @@ nodes | GlobalDataFlow.cs:158:15:158:19 | access to local variable sink7 | semmle.label | access to local variable sink7 | | GlobalDataFlow.cs:160:20:160:24 | SSA def(sink8) : String | semmle.label | SSA def(sink8) : String | | GlobalDataFlow.cs:161:15:161:19 | access to local variable sink8 | semmle.label | access to local variable sink8 | -| GlobalDataFlow.cs:162:22:162:31 | call to method OutYield [[]] : String | semmle.label | call to method OutYield [[]] : String | +| GlobalDataFlow.cs:162:22:162:31 | call to method OutYield [element] : String | semmle.label | call to method OutYield [element] : String | | GlobalDataFlow.cs:162:22:162:39 | call to method First : String | semmle.label | call to method First : String | | GlobalDataFlow.cs:163:15:163:20 | access to local variable sink12 | semmle.label | access to local variable sink12 | | GlobalDataFlow.cs:164:22:164:43 | call to method TaintedParam : String | semmle.label | call to method TaintedParam : String | @@ -393,38 +397,38 @@ nodes | GlobalDataFlow.cs:180:35:180:48 | "taint source" : String | semmle.label | "taint source" : String | | GlobalDataFlow.cs:181:21:181:26 | delegate call : String | semmle.label | delegate call : String | | GlobalDataFlow.cs:182:15:182:19 | access to local variable sink9 | semmle.label | access to local variable sink9 | -| GlobalDataFlow.cs:190:22:190:42 | object creation of type Lazy [Value] : String | semmle.label | object creation of type Lazy [Value] : String | +| GlobalDataFlow.cs:190:22:190:42 | object creation of type Lazy [property Value] : String | semmle.label | object creation of type Lazy [property Value] : String | | GlobalDataFlow.cs:190:22:190:48 | access to property Value : String | semmle.label | access to property Value : String | | GlobalDataFlow.cs:191:15:191:20 | access to local variable sink10 | semmle.label | access to local variable sink10 | | GlobalDataFlow.cs:198:22:198:32 | access to property OutProperty : String | semmle.label | access to property OutProperty : String | | GlobalDataFlow.cs:199:15:199:20 | access to local variable sink19 | semmle.label | access to local variable sink19 | -| GlobalDataFlow.cs:208:38:208:61 | array creation of type String[] [[]] : String | semmle.label | array creation of type String[] [[]] : String | -| GlobalDataFlow.cs:208:38:208:75 | call to method AsQueryable [[]] : String | semmle.label | call to method AsQueryable [[]] : String | -| GlobalDataFlow.cs:208:44:208:61 | { ..., ... } [[]] : String | semmle.label | { ..., ... } [[]] : String | +| GlobalDataFlow.cs:208:38:208:61 | array creation of type String[] [element] : String | semmle.label | array creation of type String[] [element] : String | +| GlobalDataFlow.cs:208:38:208:75 | call to method AsQueryable [element] : String | semmle.label | call to method AsQueryable [element] : String | +| GlobalDataFlow.cs:208:44:208:61 | { ..., ... } [element] : String | semmle.label | { ..., ... } [element] : String | | GlobalDataFlow.cs:208:46:208:59 | "taint source" : String | semmle.label | "taint source" : String | | GlobalDataFlow.cs:211:35:211:45 | sinkParam10 : String | semmle.label | sinkParam10 : String | | GlobalDataFlow.cs:211:58:211:68 | access to parameter sinkParam10 | semmle.label | access to parameter sinkParam10 | | GlobalDataFlow.cs:212:71:212:71 | x : String | semmle.label | x : String | | GlobalDataFlow.cs:212:89:212:89 | access to parameter x : String | semmle.label | access to parameter x : String | -| GlobalDataFlow.cs:213:22:213:28 | access to local variable tainted [[]] : String | semmle.label | access to local variable tainted [[]] : String | -| GlobalDataFlow.cs:213:22:213:39 | call to method Select [[]] : String | semmle.label | call to method Select [[]] : String | +| GlobalDataFlow.cs:213:22:213:28 | access to local variable tainted [element] : String | semmle.label | access to local variable tainted [element] : String | +| GlobalDataFlow.cs:213:22:213:39 | call to method Select [element] : String | semmle.label | call to method Select [element] : String | | GlobalDataFlow.cs:213:22:213:47 | call to method First : String | semmle.label | call to method First : String | | GlobalDataFlow.cs:214:15:214:20 | access to local variable sink24 | semmle.label | access to local variable sink24 | -| GlobalDataFlow.cs:215:22:215:28 | access to local variable tainted [[]] : String | semmle.label | access to local variable tainted [[]] : String | -| GlobalDataFlow.cs:215:22:215:39 | call to method Select [[]] : String | semmle.label | call to method Select [[]] : String | +| GlobalDataFlow.cs:215:22:215:28 | access to local variable tainted [element] : String | semmle.label | access to local variable tainted [element] : String | +| GlobalDataFlow.cs:215:22:215:39 | call to method Select [element] : String | semmle.label | call to method Select [element] : String | | GlobalDataFlow.cs:215:22:215:47 | call to method First : String | semmle.label | call to method First : String | | GlobalDataFlow.cs:216:15:216:20 | access to local variable sink25 | semmle.label | access to local variable sink25 | -| GlobalDataFlow.cs:217:22:217:28 | access to local variable tainted [[]] : String | semmle.label | access to local variable tainted [[]] : String | -| GlobalDataFlow.cs:217:22:217:49 | call to method Select [[]] : String | semmle.label | call to method Select [[]] : String | +| GlobalDataFlow.cs:217:22:217:28 | access to local variable tainted [element] : String | semmle.label | access to local variable tainted [element] : String | +| GlobalDataFlow.cs:217:22:217:49 | call to method Select [element] : String | semmle.label | call to method Select [element] : String | | GlobalDataFlow.cs:217:22:217:57 | call to method First : String | semmle.label | call to method First : String | | GlobalDataFlow.cs:218:15:218:20 | access to local variable sink26 | semmle.label | access to local variable sink26 | -| GlobalDataFlow.cs:238:20:238:49 | call to method Run [Result] : String | semmle.label | call to method Run [Result] : String | +| GlobalDataFlow.cs:238:20:238:49 | call to method Run [property Result] : String | semmle.label | call to method Run [property Result] : String | | GlobalDataFlow.cs:238:35:238:48 | "taint source" : String | semmle.label | "taint source" : String | -| GlobalDataFlow.cs:239:22:239:25 | access to local variable task [Result] : String | semmle.label | access to local variable task [Result] : String | +| GlobalDataFlow.cs:239:22:239:25 | access to local variable task [property Result] : String | semmle.label | access to local variable task [property Result] : String | | GlobalDataFlow.cs:239:22:239:32 | access to property Result : String | semmle.label | access to property Result : String | | GlobalDataFlow.cs:240:15:240:20 | access to local variable sink41 | semmle.label | access to local variable sink41 | | GlobalDataFlow.cs:241:22:241:31 | await ... : String | semmle.label | await ... : String | -| GlobalDataFlow.cs:241:28:241:31 | access to local variable task [Result] : String | semmle.label | access to local variable task [Result] : String | +| GlobalDataFlow.cs:241:28:241:31 | access to local variable task [property Result] : String | semmle.label | access to local variable task [property Result] : String | | GlobalDataFlow.cs:242:15:242:20 | access to local variable sink42 | semmle.label | access to local variable sink42 | | GlobalDataFlow.cs:254:26:254:35 | sinkParam0 : String | semmle.label | sinkParam0 : String | | GlobalDataFlow.cs:256:16:256:25 | access to parameter sinkParam0 : String | semmle.label | access to parameter sinkParam0 : String | @@ -469,23 +473,28 @@ nodes | GlobalDataFlow.cs:424:9:424:11 | value : String | semmle.label | value : String | | GlobalDataFlow.cs:424:41:424:46 | access to local variable sink20 | semmle.label | access to local variable sink20 | | GlobalDataFlow.cs:435:22:435:35 | "taint source" : String | semmle.label | "taint source" : String | -| GlobalDataFlow.cs:451:31:451:32 | [post] access to local variable sb [[]] : String | semmle.label | [post] access to local variable sb [[]] : String | +| GlobalDataFlow.cs:451:31:451:32 | [post] access to local variable sb [element] : String | semmle.label | [post] access to local variable sb [element] : String | | GlobalDataFlow.cs:451:35:451:48 | "taint source" : String | semmle.label | "taint source" : String | -| GlobalDataFlow.cs:452:22:452:23 | access to local variable sb [[]] : String | semmle.label | access to local variable sb [[]] : String | +| GlobalDataFlow.cs:452:22:452:23 | access to local variable sb [element] : String | semmle.label | access to local variable sb [element] : String | | GlobalDataFlow.cs:452:22:452:34 | call to method ToString : String | semmle.label | call to method ToString : String | | GlobalDataFlow.cs:453:15:453:20 | access to local variable sink43 | semmle.label | access to local variable sink43 | | GlobalDataFlow.cs:462:22:462:65 | call to method Join : String | semmle.label | call to method Join : String | | GlobalDataFlow.cs:462:51:462:64 | "taint source" : String | semmle.label | "taint source" : String | | GlobalDataFlow.cs:463:15:463:20 | access to local variable sink44 | semmle.label | access to local variable sink44 | -| GlobalDataFlow.cs:471:20:471:49 | call to method Run [Result] : String | semmle.label | call to method Run [Result] : String | +| GlobalDataFlow.cs:471:20:471:49 | call to method Run [property Result] : String | semmle.label | call to method Run [property Result] : String | | GlobalDataFlow.cs:471:35:471:48 | "taint source" : String | semmle.label | "taint source" : String | -| GlobalDataFlow.cs:472:25:472:28 | access to local variable task [Result] : String | semmle.label | access to local variable task [Result] : String | -| GlobalDataFlow.cs:472:25:472:50 | call to method ConfigureAwait [m_configuredTaskAwaiter, m_task, Result] : String | semmle.label | call to method ConfigureAwait [m_configuredTaskAwaiter, m_task, Result] : String | -| GlobalDataFlow.cs:473:23:473:31 | access to local variable awaitable [m_configuredTaskAwaiter, m_task, Result] : String | semmle.label | access to local variable awaitable [m_configuredTaskAwaiter, m_task, Result] : String | -| GlobalDataFlow.cs:473:23:473:44 | call to method GetAwaiter [m_task, Result] : String | semmle.label | call to method GetAwaiter [m_task, Result] : String | -| GlobalDataFlow.cs:474:22:474:28 | access to local variable awaiter [m_task, Result] : String | semmle.label | access to local variable awaiter [m_task, Result] : String | +| GlobalDataFlow.cs:472:25:472:28 | access to local variable task [property Result] : String | semmle.label | access to local variable task [property Result] : String | +| GlobalDataFlow.cs:472:25:472:50 | call to method ConfigureAwait [field m_configuredTaskAwaiter, field m_task, property Result] : String | semmle.label | call to method ConfigureAwait [field m_configuredTaskAwaiter, field m_task, property Result] : String | +| GlobalDataFlow.cs:473:23:473:31 | access to local variable awaitable [field m_configuredTaskAwaiter, field m_task, property Result] : String | semmle.label | access to local variable awaitable [field m_configuredTaskAwaiter, field m_task, property Result] : String | +| GlobalDataFlow.cs:473:23:473:44 | call to method GetAwaiter [field m_task, property Result] : String | semmle.label | call to method GetAwaiter [field m_task, property Result] : String | +| GlobalDataFlow.cs:474:22:474:28 | access to local variable awaiter [field m_task, property Result] : String | semmle.label | access to local variable awaiter [field m_task, property Result] : String | | GlobalDataFlow.cs:474:22:474:40 | call to method GetResult : String | semmle.label | call to method GetResult : String | | GlobalDataFlow.cs:475:15:475:20 | access to local variable sink45 | semmle.label | access to local variable sink45 | +| GlobalDataFlow.cs:480:53:480:55 | arg : String | semmle.label | arg : String | +| GlobalDataFlow.cs:483:21:483:21 | s : String | semmle.label | s : String | +| GlobalDataFlow.cs:483:32:483:32 | access to parameter s | semmle.label | access to parameter s | +| GlobalDataFlow.cs:484:15:484:17 | access to parameter arg : String | semmle.label | access to parameter arg : String | +| GlobalDataFlow.cs:487:27:487:40 | "taint source" : String | semmle.label | "taint source" : String | | Splitting.cs:3:28:3:34 | tainted : String | semmle.label | tainted : String | | Splitting.cs:8:17:8:31 | [b (line 3): false] call to method Return : String | semmle.label | [b (line 3): false] call to method Return : String | | Splitting.cs:8:17:8:31 | [b (line 3): true] call to method Return : String | semmle.label | [b (line 3): true] call to method Return : String | @@ -573,6 +582,7 @@ nodes | GlobalDataFlow.cs:453:15:453:20 | access to local variable sink43 | GlobalDataFlow.cs:451:35:451:48 | "taint source" : String | GlobalDataFlow.cs:453:15:453:20 | access to local variable sink43 | access to local variable sink43 | | GlobalDataFlow.cs:463:15:463:20 | access to local variable sink44 | GlobalDataFlow.cs:462:51:462:64 | "taint source" : String | GlobalDataFlow.cs:463:15:463:20 | access to local variable sink44 | access to local variable sink44 | | GlobalDataFlow.cs:475:15:475:20 | access to local variable sink45 | GlobalDataFlow.cs:471:35:471:48 | "taint source" : String | GlobalDataFlow.cs:475:15:475:20 | access to local variable sink45 | access to local variable sink45 | +| GlobalDataFlow.cs:483:32:483:32 | access to parameter s | GlobalDataFlow.cs:487:27:487:40 | "taint source" : String | GlobalDataFlow.cs:483:32:483:32 | access to parameter s | access to parameter s | | Splitting.cs:9:15:9:15 | [b (line 3): false] access to local variable x | Splitting.cs:3:28:3:34 | tainted : String | Splitting.cs:9:15:9:15 | [b (line 3): false] access to local variable x | [b (line 3): false] access to local variable x | | Splitting.cs:9:15:9:15 | [b (line 3): true] access to local variable x | Splitting.cs:3:28:3:34 | tainted : String | Splitting.cs:9:15:9:15 | [b (line 3): true] access to local variable x | [b (line 3): true] access to local variable x | | Splitting.cs:11:19:11:19 | access to local variable x | Splitting.cs:3:28:3:34 | tainted : String | Splitting.cs:11:19:11:19 | access to local variable x | access to local variable x | diff --git a/csharp/ql/test/library-tests/dataflow/library/FlowSummaries.expected b/csharp/ql/test/library-tests/dataflow/library/FlowSummaries.expected index 8ea7f7d9875..30b6ee553a1 100644 --- a/csharp/ql/test/library-tests/dataflow/library/FlowSummaries.expected +++ b/csharp/ql/test/library-tests/dataflow/library/FlowSummaries.expected @@ -1,2710 +1,2710 @@ -| MS.Internal.Xml.Linq.ComponentModel.XDeferredAxis<>.GetEnumerator() | this parameter [[]] -> return [Current] | true | -| System.().Create(T1, T2, T3, T4, T5, T6, T7, T8) | parameter 0 -> return [Item1] | true | -| System.().Create(T1, T2, T3, T4, T5, T6, T7, T8) | parameter 1 -> return [Item2] | true | -| System.().Create(T1, T2, T3, T4, T5, T6, T7, T8) | parameter 2 -> return [Item3] | true | -| System.().Create(T1, T2, T3, T4, T5, T6, T7, T8) | parameter 3 -> return [Item4] | true | -| System.().Create(T1, T2, T3, T4, T5, T6, T7, T8) | parameter 4 -> return [Item5] | true | -| System.().Create(T1, T2, T3, T4, T5, T6, T7, T8) | parameter 5 -> return [Item6] | true | -| System.().Create(T1, T2, T3, T4, T5, T6, T7, T8) | parameter 6 -> return [Item7] | true | -| System.().Create(T1, T2, T3, T4, T5, T6, T7, T8) | parameter 7 -> return [Item8] | true | -| System.().Create(T1, T2, T3, T4, T5, T6, T7) | parameter 0 -> return [Item1] | true | -| System.().Create(T1, T2, T3, T4, T5, T6, T7) | parameter 1 -> return [Item2] | true | -| System.().Create(T1, T2, T3, T4, T5, T6, T7) | parameter 2 -> return [Item3] | true | -| System.().Create(T1, T2, T3, T4, T5, T6, T7) | parameter 3 -> return [Item4] | true | -| System.().Create(T1, T2, T3, T4, T5, T6, T7) | parameter 4 -> return [Item5] | true | -| System.().Create(T1, T2, T3, T4, T5, T6, T7) | parameter 5 -> return [Item6] | true | -| System.().Create(T1, T2, T3, T4, T5, T6, T7) | parameter 6 -> return [Item7] | true | -| System.().Create(T1, T2, T3, T4, T5, T6) | parameter 0 -> return [Item1] | true | -| System.().Create(T1, T2, T3, T4, T5, T6) | parameter 1 -> return [Item2] | true | -| System.().Create(T1, T2, T3, T4, T5, T6) | parameter 2 -> return [Item3] | true | -| System.().Create(T1, T2, T3, T4, T5, T6) | parameter 3 -> return [Item4] | true | -| System.().Create(T1, T2, T3, T4, T5, T6) | parameter 4 -> return [Item5] | true | -| System.().Create(T1, T2, T3, T4, T5, T6) | parameter 5 -> return [Item6] | true | -| System.().Create(T1, T2, T3, T4, T5) | parameter 0 -> return [Item1] | true | -| System.().Create(T1, T2, T3, T4, T5) | parameter 1 -> return [Item2] | true | -| System.().Create(T1, T2, T3, T4, T5) | parameter 2 -> return [Item3] | true | -| System.().Create(T1, T2, T3, T4, T5) | parameter 3 -> return [Item4] | true | -| System.().Create(T1, T2, T3, T4, T5) | parameter 4 -> return [Item5] | true | -| System.().Create(T1, T2, T3, T4) | parameter 0 -> return [Item1] | true | -| System.().Create(T1, T2, T3, T4) | parameter 1 -> return [Item2] | true | -| System.().Create(T1, T2, T3, T4) | parameter 2 -> return [Item3] | true | -| System.().Create(T1, T2, T3, T4) | parameter 3 -> return [Item4] | true | -| System.().Create(T1, T2, T3) | parameter 0 -> return [Item1] | true | -| System.().Create(T1, T2, T3) | parameter 1 -> return [Item2] | true | -| System.().Create(T1, T2, T3) | parameter 2 -> return [Item3] | true | -| System.().Create(T1, T2) | parameter 0 -> return [Item1] | true | -| System.().Create(T1, T2) | parameter 1 -> return [Item2] | true | -| System.().Create(T1) | parameter 0 -> return [Item1] | true | -| System.(T1).ValueTuple(T1) | parameter 0 -> return [Item1] | true | -| System.(T1).get_Item(int) | this parameter [Item1] -> return | true | -| System.(T1,T2).ValueTuple(T1, T2) | parameter 0 -> return [Item1] | true | -| System.(T1,T2).ValueTuple(T1, T2) | parameter 1 -> return [Item2] | true | -| System.(T1,T2).get_Item(int) | this parameter [Item1] -> return | true | -| System.(T1,T2).get_Item(int) | this parameter [Item2] -> return | true | -| System.(T1,T2,T3).ValueTuple(T1, T2, T3) | parameter 0 -> return [Item1] | true | -| System.(T1,T2,T3).ValueTuple(T1, T2, T3) | parameter 1 -> return [Item2] | true | -| System.(T1,T2,T3).ValueTuple(T1, T2, T3) | parameter 2 -> return [Item3] | true | -| System.(T1,T2,T3).get_Item(int) | this parameter [Item1] -> return | true | -| System.(T1,T2,T3).get_Item(int) | this parameter [Item2] -> return | true | -| System.(T1,T2,T3).get_Item(int) | this parameter [Item3] -> return | true | -| System.(T1,T2,T3,T4).ValueTuple(T1, T2, T3, T4) | parameter 0 -> return [Item1] | true | -| System.(T1,T2,T3,T4).ValueTuple(T1, T2, T3, T4) | parameter 1 -> return [Item2] | true | -| System.(T1,T2,T3,T4).ValueTuple(T1, T2, T3, T4) | parameter 2 -> return [Item3] | true | -| System.(T1,T2,T3,T4).ValueTuple(T1, T2, T3, T4) | parameter 3 -> return [Item4] | true | -| System.(T1,T2,T3,T4).get_Item(int) | this parameter [Item1] -> return | true | -| System.(T1,T2,T3,T4).get_Item(int) | this parameter [Item2] -> return | true | -| System.(T1,T2,T3,T4).get_Item(int) | this parameter [Item3] -> return | true | -| System.(T1,T2,T3,T4).get_Item(int) | this parameter [Item4] -> return | true | -| System.(T1,T2,T3,T4,T5).ValueTuple(T1, T2, T3, T4, T5) | parameter 0 -> return [Item1] | true | -| System.(T1,T2,T3,T4,T5).ValueTuple(T1, T2, T3, T4, T5) | parameter 1 -> return [Item2] | true | -| System.(T1,T2,T3,T4,T5).ValueTuple(T1, T2, T3, T4, T5) | parameter 2 -> return [Item3] | true | -| System.(T1,T2,T3,T4,T5).ValueTuple(T1, T2, T3, T4, T5) | parameter 3 -> return [Item4] | true | -| System.(T1,T2,T3,T4,T5).ValueTuple(T1, T2, T3, T4, T5) | parameter 4 -> return [Item5] | true | -| System.(T1,T2,T3,T4,T5).get_Item(int) | this parameter [Item1] -> return | true | -| System.(T1,T2,T3,T4,T5).get_Item(int) | this parameter [Item2] -> return | true | -| System.(T1,T2,T3,T4,T5).get_Item(int) | this parameter [Item3] -> return | true | -| System.(T1,T2,T3,T4,T5).get_Item(int) | this parameter [Item4] -> return | true | -| System.(T1,T2,T3,T4,T5).get_Item(int) | this parameter [Item5] -> return | true | -| System.(T1,T2,T3,T4,T5,T6).ValueTuple(T1, T2, T3, T4, T5, T6) | parameter 0 -> return [Item1] | true | -| System.(T1,T2,T3,T4,T5,T6).ValueTuple(T1, T2, T3, T4, T5, T6) | parameter 1 -> return [Item2] | true | -| System.(T1,T2,T3,T4,T5,T6).ValueTuple(T1, T2, T3, T4, T5, T6) | parameter 2 -> return [Item3] | true | -| System.(T1,T2,T3,T4,T5,T6).ValueTuple(T1, T2, T3, T4, T5, T6) | parameter 3 -> return [Item4] | true | -| System.(T1,T2,T3,T4,T5,T6).ValueTuple(T1, T2, T3, T4, T5, T6) | parameter 4 -> return [Item5] | true | -| System.(T1,T2,T3,T4,T5,T6).ValueTuple(T1, T2, T3, T4, T5, T6) | parameter 5 -> return [Item6] | true | -| System.(T1,T2,T3,T4,T5,T6).get_Item(int) | this parameter [Item1] -> return | true | -| System.(T1,T2,T3,T4,T5,T6).get_Item(int) | this parameter [Item2] -> return | true | -| System.(T1,T2,T3,T4,T5,T6).get_Item(int) | this parameter [Item3] -> return | true | -| System.(T1,T2,T3,T4,T5,T6).get_Item(int) | this parameter [Item4] -> return | true | -| System.(T1,T2,T3,T4,T5,T6).get_Item(int) | this parameter [Item5] -> return | true | -| System.(T1,T2,T3,T4,T5,T6).get_Item(int) | this parameter [Item6] -> return | true | -| System.(T1,T2,T3,T4,T5,T6,T7).ValueTuple(T1, T2, T3, T4, T5, T6, T7) | parameter 0 -> return [Item1] | true | -| System.(T1,T2,T3,T4,T5,T6,T7).ValueTuple(T1, T2, T3, T4, T5, T6, T7) | parameter 1 -> return [Item2] | true | -| System.(T1,T2,T3,T4,T5,T6,T7).ValueTuple(T1, T2, T3, T4, T5, T6, T7) | parameter 2 -> return [Item3] | true | -| System.(T1,T2,T3,T4,T5,T6,T7).ValueTuple(T1, T2, T3, T4, T5, T6, T7) | parameter 3 -> return [Item4] | true | -| System.(T1,T2,T3,T4,T5,T6,T7).ValueTuple(T1, T2, T3, T4, T5, T6, T7) | parameter 4 -> return [Item5] | true | -| System.(T1,T2,T3,T4,T5,T6,T7).ValueTuple(T1, T2, T3, T4, T5, T6, T7) | parameter 5 -> return [Item6] | true | -| System.(T1,T2,T3,T4,T5,T6,T7).ValueTuple(T1, T2, T3, T4, T5, T6, T7) | parameter 6 -> return [Item7] | true | -| System.(T1,T2,T3,T4,T5,T6,T7).get_Item(int) | this parameter [Item1] -> return | true | -| System.(T1,T2,T3,T4,T5,T6,T7).get_Item(int) | this parameter [Item2] -> return | true | -| System.(T1,T2,T3,T4,T5,T6,T7).get_Item(int) | this parameter [Item3] -> return | true | -| System.(T1,T2,T3,T4,T5,T6,T7).get_Item(int) | this parameter [Item4] -> return | true | -| System.(T1,T2,T3,T4,T5,T6,T7).get_Item(int) | this parameter [Item5] -> return | true | -| System.(T1,T2,T3,T4,T5,T6,T7).get_Item(int) | this parameter [Item6] -> return | true | -| System.(T1,T2,T3,T4,T5,T6,T7).get_Item(int) | this parameter [Item7] -> return | true | -| System.Array.Add(object) | parameter 0 -> this parameter [[]] | true | -| System.Array.AsReadOnly(T[]) | parameter 0 [[]] -> return [[]] | true | -| System.Array.Clone() | parameter 0 [[]] -> return [[]] | true | -| System.Array.CopyTo(Array, int) | this parameter [[]] -> parameter 0 [[]] | true | -| System.Array.CopyTo(Array, long) | this parameter [[]] -> parameter 0 [[]] | true | -| System.Array.Find(T[], Predicate) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Array.Find(T[], Predicate) | parameter 0 [[]] -> return | true | -| System.Array.FindAll(T[], Predicate) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Array.FindAll(T[], Predicate) | parameter 0 [[]] -> return | true | -| System.Array.FindLast(T[], Predicate) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Array.FindLast(T[], Predicate) | parameter 0 [[]] -> return | true | -| System.Array.GetEnumerator() | this parameter [[]] -> return [Current] | true | -| System.Array.Insert(int, object) | parameter 1 -> this parameter [[]] | true | -| System.Array.Reverse(Array) | parameter 0 [[]] -> return [[]] | true | -| System.Array.Reverse(Array, int, int) | parameter 0 [[]] -> return [[]] | true | -| System.Array.Reverse(T[]) | parameter 0 [[]] -> return [[]] | true | -| System.Array.Reverse(T[], int, int) | parameter 0 [[]] -> return [[]] | true | -| System.Array.get_Item(int) | this parameter [[]] -> return | true | -| System.Array.set_Item(int, object) | parameter 1 -> this parameter [[]] | true | -| System.Boolean.Parse(string) | parameter 0 -> return | false | -| System.Boolean.TryParse(string, out bool) | parameter 0 -> parameter 1 | false | -| System.Boolean.TryParse(string, out bool) | parameter 0 -> return | false | -| System.Collections.ArrayList.Add(object) | parameter 0 -> this parameter [[]] | true | -| System.Collections.ArrayList.AddRange(ICollection) | parameter 0 [[]] -> this parameter [[]] | true | -| System.Collections.ArrayList.Clone() | parameter 0 [[]] -> return [[]] | true | -| System.Collections.ArrayList.CopyTo(Array, int) | this parameter [[]] -> parameter 0 [[]] | true | -| System.Collections.ArrayList.FixedSize(ArrayList) | parameter 0 [[]] -> return [[]] | true | -| System.Collections.ArrayList.FixedSize(IList) | parameter 0 [[]] -> return [[]] | true | -| System.Collections.ArrayList.FixedSizeArrayList.Add(object) | parameter 0 -> this parameter [[]] | true | -| System.Collections.ArrayList.FixedSizeArrayList.AddRange(ICollection) | parameter 0 [[]] -> this parameter [[]] | true | -| System.Collections.ArrayList.FixedSizeArrayList.Clone() | parameter 0 [[]] -> return [[]] | true | -| System.Collections.ArrayList.FixedSizeArrayList.CopyTo(Array, int) | this parameter [[]] -> parameter 0 [[]] | true | -| System.Collections.ArrayList.FixedSizeArrayList.GetEnumerator() | this parameter [[]] -> return [Current] | true | -| System.Collections.ArrayList.FixedSizeArrayList.GetEnumerator(int, int) | this parameter [[]] -> return [Current] | true | -| System.Collections.ArrayList.FixedSizeArrayList.GetRange(int, int) | parameter 0 [[]] -> return [[]] | true | -| System.Collections.ArrayList.FixedSizeArrayList.Insert(int, object) | parameter 1 -> this parameter [[]] | true | -| System.Collections.ArrayList.FixedSizeArrayList.InsertRange(int, ICollection) | parameter 1 [[]] -> this parameter [[]] | true | -| System.Collections.ArrayList.FixedSizeArrayList.Reverse(int, int) | parameter 0 [[]] -> return [[]] | true | -| System.Collections.ArrayList.FixedSizeArrayList.get_Item(int) | this parameter [[]] -> return | true | -| System.Collections.ArrayList.FixedSizeArrayList.set_Item(int, object) | parameter 1 -> this parameter [[]] | true | -| System.Collections.ArrayList.FixedSizeList.Add(object) | parameter 0 -> this parameter [[]] | true | -| System.Collections.ArrayList.FixedSizeList.CopyTo(Array, int) | this parameter [[]] -> parameter 0 [[]] | true | -| System.Collections.ArrayList.FixedSizeList.GetEnumerator() | this parameter [[]] -> return [Current] | true | -| System.Collections.ArrayList.FixedSizeList.Insert(int, object) | parameter 1 -> this parameter [[]] | true | -| System.Collections.ArrayList.FixedSizeList.get_Item(int) | this parameter [[]] -> return | true | -| System.Collections.ArrayList.FixedSizeList.set_Item(int, object) | parameter 1 -> this parameter [[]] | true | -| System.Collections.ArrayList.GetEnumerator() | this parameter [[]] -> return [Current] | true | -| System.Collections.ArrayList.GetEnumerator(int, int) | this parameter [[]] -> return [Current] | true | -| System.Collections.ArrayList.GetRange(int, int) | parameter 0 [[]] -> return [[]] | true | -| System.Collections.ArrayList.IListWrapper.Add(object) | parameter 0 -> this parameter [[]] | true | -| System.Collections.ArrayList.IListWrapper.AddRange(ICollection) | parameter 0 [[]] -> this parameter [[]] | true | -| System.Collections.ArrayList.IListWrapper.Clone() | parameter 0 [[]] -> return [[]] | true | -| System.Collections.ArrayList.IListWrapper.CopyTo(Array, int) | this parameter [[]] -> parameter 0 [[]] | true | -| System.Collections.ArrayList.IListWrapper.GetEnumerator() | this parameter [[]] -> return [Current] | true | -| System.Collections.ArrayList.IListWrapper.GetEnumerator(int, int) | this parameter [[]] -> return [Current] | true | -| System.Collections.ArrayList.IListWrapper.GetRange(int, int) | parameter 0 [[]] -> return [[]] | true | -| System.Collections.ArrayList.IListWrapper.Insert(int, object) | parameter 1 -> this parameter [[]] | true | -| System.Collections.ArrayList.IListWrapper.InsertRange(int, ICollection) | parameter 1 [[]] -> this parameter [[]] | true | -| System.Collections.ArrayList.IListWrapper.Reverse(int, int) | parameter 0 [[]] -> return [[]] | true | -| System.Collections.ArrayList.IListWrapper.get_Item(int) | this parameter [[]] -> return | true | -| System.Collections.ArrayList.IListWrapper.set_Item(int, object) | parameter 1 -> this parameter [[]] | true | -| System.Collections.ArrayList.Insert(int, object) | parameter 1 -> this parameter [[]] | true | -| System.Collections.ArrayList.InsertRange(int, ICollection) | parameter 1 [[]] -> this parameter [[]] | true | -| System.Collections.ArrayList.Range.Add(object) | parameter 0 -> this parameter [[]] | true | -| System.Collections.ArrayList.Range.AddRange(ICollection) | parameter 0 [[]] -> this parameter [[]] | true | -| System.Collections.ArrayList.Range.Clone() | parameter 0 [[]] -> return [[]] | true | -| System.Collections.ArrayList.Range.CopyTo(Array, int) | this parameter [[]] -> parameter 0 [[]] | true | -| System.Collections.ArrayList.Range.GetEnumerator() | this parameter [[]] -> return [Current] | true | -| System.Collections.ArrayList.Range.GetEnumerator(int, int) | this parameter [[]] -> return [Current] | true | -| System.Collections.ArrayList.Range.GetRange(int, int) | parameter 0 [[]] -> return [[]] | true | -| System.Collections.ArrayList.Range.Insert(int, object) | parameter 1 -> this parameter [[]] | true | -| System.Collections.ArrayList.Range.InsertRange(int, ICollection) | parameter 1 [[]] -> this parameter [[]] | true | -| System.Collections.ArrayList.Range.Reverse(int, int) | parameter 0 [[]] -> return [[]] | true | -| System.Collections.ArrayList.Range.get_Item(int) | this parameter [[]] -> return | true | -| System.Collections.ArrayList.Range.set_Item(int, object) | parameter 1 -> this parameter [[]] | true | -| System.Collections.ArrayList.ReadOnlyArrayList.Add(object) | parameter 0 -> this parameter [[]] | true | -| System.Collections.ArrayList.ReadOnlyArrayList.AddRange(ICollection) | parameter 0 [[]] -> this parameter [[]] | true | -| System.Collections.ArrayList.ReadOnlyArrayList.Clone() | parameter 0 [[]] -> return [[]] | true | -| System.Collections.ArrayList.ReadOnlyArrayList.CopyTo(Array, int) | this parameter [[]] -> parameter 0 [[]] | true | -| System.Collections.ArrayList.ReadOnlyArrayList.GetEnumerator() | this parameter [[]] -> return [Current] | true | -| System.Collections.ArrayList.ReadOnlyArrayList.GetEnumerator(int, int) | this parameter [[]] -> return [Current] | true | -| System.Collections.ArrayList.ReadOnlyArrayList.GetRange(int, int) | parameter 0 [[]] -> return [[]] | true | -| System.Collections.ArrayList.ReadOnlyArrayList.Insert(int, object) | parameter 1 -> this parameter [[]] | true | -| System.Collections.ArrayList.ReadOnlyArrayList.InsertRange(int, ICollection) | parameter 1 [[]] -> this parameter [[]] | true | -| System.Collections.ArrayList.ReadOnlyArrayList.Reverse(int, int) | parameter 0 [[]] -> return [[]] | true | -| System.Collections.ArrayList.ReadOnlyArrayList.get_Item(int) | this parameter [[]] -> return | true | -| System.Collections.ArrayList.ReadOnlyArrayList.set_Item(int, object) | parameter 1 -> this parameter [[]] | true | -| System.Collections.ArrayList.ReadOnlyList.Add(object) | parameter 0 -> this parameter [[]] | true | -| System.Collections.ArrayList.ReadOnlyList.CopyTo(Array, int) | this parameter [[]] -> parameter 0 [[]] | true | -| System.Collections.ArrayList.ReadOnlyList.GetEnumerator() | this parameter [[]] -> return [Current] | true | -| System.Collections.ArrayList.ReadOnlyList.Insert(int, object) | parameter 1 -> this parameter [[]] | true | -| System.Collections.ArrayList.ReadOnlyList.get_Item(int) | this parameter [[]] -> return | true | -| System.Collections.ArrayList.ReadOnlyList.set_Item(int, object) | parameter 1 -> this parameter [[]] | true | -| System.Collections.ArrayList.Repeat(object, int) | parameter 0 -> return [[]] | true | -| System.Collections.ArrayList.Reverse() | parameter 0 [[]] -> return [[]] | true | -| System.Collections.ArrayList.Reverse(int, int) | parameter 0 [[]] -> return [[]] | true | -| System.Collections.ArrayList.SyncArrayList.Add(object) | parameter 0 -> this parameter [[]] | true | -| System.Collections.ArrayList.SyncArrayList.AddRange(ICollection) | parameter 0 [[]] -> this parameter [[]] | true | -| System.Collections.ArrayList.SyncArrayList.Clone() | parameter 0 [[]] -> return [[]] | true | -| System.Collections.ArrayList.SyncArrayList.CopyTo(Array, int) | this parameter [[]] -> parameter 0 [[]] | true | -| System.Collections.ArrayList.SyncArrayList.GetEnumerator() | this parameter [[]] -> return [Current] | true | -| System.Collections.ArrayList.SyncArrayList.GetEnumerator(int, int) | this parameter [[]] -> return [Current] | true | -| System.Collections.ArrayList.SyncArrayList.GetRange(int, int) | parameter 0 [[]] -> return [[]] | true | -| System.Collections.ArrayList.SyncArrayList.Insert(int, object) | parameter 1 -> this parameter [[]] | true | -| System.Collections.ArrayList.SyncArrayList.InsertRange(int, ICollection) | parameter 1 [[]] -> this parameter [[]] | true | -| System.Collections.ArrayList.SyncArrayList.Reverse(int, int) | parameter 0 [[]] -> return [[]] | true | -| System.Collections.ArrayList.SyncArrayList.get_Item(int) | this parameter [[]] -> return | true | -| System.Collections.ArrayList.SyncArrayList.set_Item(int, object) | parameter 1 -> this parameter [[]] | true | -| System.Collections.ArrayList.SyncIList.Add(object) | parameter 0 -> this parameter [[]] | true | -| System.Collections.ArrayList.SyncIList.CopyTo(Array, int) | this parameter [[]] -> parameter 0 [[]] | true | -| System.Collections.ArrayList.SyncIList.GetEnumerator() | this parameter [[]] -> return [Current] | true | -| System.Collections.ArrayList.SyncIList.Insert(int, object) | parameter 1 -> this parameter [[]] | true | -| System.Collections.ArrayList.SyncIList.get_Item(int) | this parameter [[]] -> return | true | -| System.Collections.ArrayList.SyncIList.set_Item(int, object) | parameter 1 -> this parameter [[]] | true | -| System.Collections.ArrayList.get_Item(int) | this parameter [[]] -> return | true | -| System.Collections.ArrayList.set_Item(int, object) | parameter 1 -> this parameter [[]] | true | -| System.Collections.BitArray.Clone() | parameter 0 [[]] -> return [[]] | true | -| System.Collections.BitArray.CopyTo(Array, int) | this parameter [[]] -> parameter 0 [[]] | true | -| System.Collections.BitArray.GetEnumerator() | this parameter [[]] -> return [Current] | true | -| System.Collections.CollectionBase.Add(object) | parameter 0 -> this parameter [[]] | true | -| System.Collections.CollectionBase.CopyTo(Array, int) | this parameter [[]] -> parameter 0 [[]] | true | -| System.Collections.CollectionBase.GetEnumerator() | this parameter [[]] -> return [Current] | true | -| System.Collections.CollectionBase.Insert(int, object) | parameter 1 -> this parameter [[]] | true | -| System.Collections.CollectionBase.get_Item(int) | this parameter [[]] -> return | true | -| System.Collections.CollectionBase.set_Item(int, object) | parameter 1 -> this parameter [[]] | true | -| System.Collections.Concurrent.BlockingCollection<>.d__68.GetEnumerator() | this parameter [[]] -> return [Current] | true | -| System.Collections.Concurrent.BlockingCollection<>.Add(T) | parameter 0 -> this parameter [[]] | true | -| System.Collections.Concurrent.BlockingCollection<>.CopyTo(Array, int) | this parameter [[]] -> parameter 0 [[]] | true | -| System.Collections.Concurrent.BlockingCollection<>.CopyTo(T[], int) | this parameter [[]] -> parameter 0 [[]] | true | -| System.Collections.Concurrent.BlockingCollection<>.GetEnumerator() | this parameter [[]] -> return [Current] | true | -| System.Collections.Concurrent.ConcurrentBag<>.Add(T) | parameter 0 -> this parameter [[]] | true | -| System.Collections.Concurrent.ConcurrentBag<>.CopyTo(Array, int) | this parameter [[]] -> parameter 0 [[]] | true | -| System.Collections.Concurrent.ConcurrentBag<>.CopyTo(T[], int) | this parameter [[]] -> parameter 0 [[]] | true | -| System.Collections.Concurrent.ConcurrentBag<>.GetEnumerator() | this parameter [[]] -> return [Current] | true | -| System.Collections.Concurrent.ConcurrentDictionary<,>.Add(KeyValuePair) | parameter 0 -> this parameter [[]] | true | -| System.Collections.Concurrent.ConcurrentDictionary<,>.Add(KeyValuePair) | parameter 0 [Key] -> this parameter [[], Key] | true | -| System.Collections.Concurrent.ConcurrentDictionary<,>.Add(KeyValuePair) | parameter 0 [Value] -> this parameter [[], Value] | true | -| System.Collections.Concurrent.ConcurrentDictionary<,>.Add(TKey, TValue) | parameter 0 -> this parameter [[], Key] | true | -| System.Collections.Concurrent.ConcurrentDictionary<,>.Add(TKey, TValue) | parameter 1 -> this parameter [[], Value] | true | -| System.Collections.Concurrent.ConcurrentDictionary<,>.Add(object, object) | parameter 0 -> this parameter [[], Key] | true | -| System.Collections.Concurrent.ConcurrentDictionary<,>.Add(object, object) | parameter 1 -> this parameter [[], Value] | true | -| System.Collections.Concurrent.ConcurrentDictionary<,>.ConcurrentDictionary(IEnumerable>) | parameter 0 [[], Key] -> return [[], Key] | true | -| System.Collections.Concurrent.ConcurrentDictionary<,>.ConcurrentDictionary(IEnumerable>) | parameter 0 [[], Value] -> return [[], Value] | true | -| System.Collections.Concurrent.ConcurrentDictionary<,>.ConcurrentDictionary(IEnumerable>, IEqualityComparer) | parameter 0 [[], Key] -> return [[], Key] | true | -| System.Collections.Concurrent.ConcurrentDictionary<,>.ConcurrentDictionary(IEnumerable>, IEqualityComparer) | parameter 0 [[], Value] -> return [[], Value] | true | -| System.Collections.Concurrent.ConcurrentDictionary<,>.ConcurrentDictionary(int, IEnumerable>, IEqualityComparer) | parameter 1 [[], Key] -> return [[], Key] | true | -| System.Collections.Concurrent.ConcurrentDictionary<,>.ConcurrentDictionary(int, IEnumerable>, IEqualityComparer) | parameter 1 [[], Value] -> return [[], Value] | true | -| System.Collections.Concurrent.ConcurrentDictionary<,>.CopyTo(Array, int) | this parameter [[]] -> parameter 0 [[]] | true | -| System.Collections.Concurrent.ConcurrentDictionary<,>.CopyTo(KeyValuePair[], int) | this parameter [[]] -> parameter 0 [[]] | true | -| System.Collections.Concurrent.ConcurrentDictionary<,>.GetEnumerator() | this parameter [[]] -> return [Current] | true | -| System.Collections.Concurrent.ConcurrentDictionary<,>.get_Item(TKey) | this parameter [[], Value] -> return | true | -| System.Collections.Concurrent.ConcurrentDictionary<,>.get_Item(object) | this parameter [[], Value] -> return | true | -| System.Collections.Concurrent.ConcurrentDictionary<,>.get_Keys() | this parameter [[], Key] -> return [[]] | true | -| System.Collections.Concurrent.ConcurrentDictionary<,>.get_Values() | this parameter [[], Value] -> return [[]] | true | -| System.Collections.Concurrent.ConcurrentDictionary<,>.set_Item(TKey, TValue) | parameter 0 -> this parameter [[], Key] | true | -| System.Collections.Concurrent.ConcurrentDictionary<,>.set_Item(TKey, TValue) | parameter 1 -> this parameter [[], Value] | true | -| System.Collections.Concurrent.ConcurrentDictionary<,>.set_Item(object, object) | parameter 0 -> this parameter [[], Key] | true | -| System.Collections.Concurrent.ConcurrentDictionary<,>.set_Item(object, object) | parameter 1 -> this parameter [[], Value] | true | -| System.Collections.Concurrent.ConcurrentQueue<>.CopyTo(Array, int) | this parameter [[]] -> parameter 0 [[]] | true | -| System.Collections.Concurrent.ConcurrentQueue<>.CopyTo(T[], int) | this parameter [[]] -> parameter 0 [[]] | true | -| System.Collections.Concurrent.ConcurrentQueue<>.GetEnumerator() | this parameter [[]] -> return [Current] | true | -| System.Collections.Concurrent.ConcurrentStack<>.CopyTo(Array, int) | this parameter [[]] -> parameter 0 [[]] | true | -| System.Collections.Concurrent.ConcurrentStack<>.CopyTo(T[], int) | this parameter [[]] -> parameter 0 [[]] | true | -| System.Collections.Concurrent.ConcurrentStack<>.GetEnumerator() | this parameter [[]] -> return [Current] | true | -| System.Collections.Concurrent.IProducerConsumerCollection<>.CopyTo(T[], int) | this parameter [[]] -> parameter 0 [[]] | true | -| System.Collections.Concurrent.OrderablePartitioner<>.EnumerableDropIndices.GetEnumerator() | this parameter [[]] -> return [Current] | true | -| System.Collections.Concurrent.Partitioner.d__7.GetEnumerator() | this parameter [[]] -> return [Current] | true | -| System.Collections.Concurrent.Partitioner.d__10.GetEnumerator() | this parameter [[]] -> return [Current] | true | -| System.Collections.Concurrent.Partitioner.DynamicPartitionerForArray<>.InternalPartitionEnumerable.GetEnumerator() | this parameter [[]] -> return [Current] | true | -| System.Collections.Concurrent.Partitioner.DynamicPartitionerForIEnumerable<>.InternalPartitionEnumerable.GetEnumerator() | this parameter [[]] -> return [Current] | true | -| System.Collections.Concurrent.Partitioner.DynamicPartitionerForIList<>.InternalPartitionEnumerable.GetEnumerator() | this parameter [[]] -> return [Current] | true | -| System.Collections.DictionaryBase.Add(object, object) | parameter 0 -> this parameter [[], Key] | true | -| System.Collections.DictionaryBase.Add(object, object) | parameter 1 -> this parameter [[], Value] | true | -| System.Collections.DictionaryBase.CopyTo(Array, int) | this parameter [[]] -> parameter 0 [[]] | true | -| System.Collections.DictionaryBase.GetEnumerator() | this parameter [[]] -> return [Current] | true | -| System.Collections.DictionaryBase.get_Item(object) | this parameter [[], Value] -> return | true | -| System.Collections.DictionaryBase.get_Keys() | this parameter [[], Key] -> return [[]] | true | -| System.Collections.DictionaryBase.get_Values() | this parameter [[], Value] -> return [[]] | true | -| System.Collections.DictionaryBase.set_Item(object, object) | parameter 0 -> this parameter [[], Key] | true | -| System.Collections.DictionaryBase.set_Item(object, object) | parameter 1 -> this parameter [[], Value] | true | -| System.Collections.EmptyReadOnlyDictionaryInternal.Add(object, object) | parameter 0 -> this parameter [[], Key] | true | -| System.Collections.EmptyReadOnlyDictionaryInternal.Add(object, object) | parameter 1 -> this parameter [[], Value] | true | -| System.Collections.EmptyReadOnlyDictionaryInternal.CopyTo(Array, int) | this parameter [[]] -> parameter 0 [[]] | true | -| System.Collections.EmptyReadOnlyDictionaryInternal.GetEnumerator() | this parameter [[]] -> return [Current] | true | -| System.Collections.EmptyReadOnlyDictionaryInternal.get_Item(object) | this parameter [[], Value] -> return | true | -| System.Collections.EmptyReadOnlyDictionaryInternal.get_Keys() | this parameter [[], Key] -> return [[]] | true | -| System.Collections.EmptyReadOnlyDictionaryInternal.get_Values() | this parameter [[], Value] -> return [[]] | true | -| System.Collections.EmptyReadOnlyDictionaryInternal.set_Item(object, object) | parameter 0 -> this parameter [[], Key] | true | -| System.Collections.EmptyReadOnlyDictionaryInternal.set_Item(object, object) | parameter 1 -> this parameter [[], Value] | true | -| System.Collections.Generic.Dictionary<,>.Add(KeyValuePair) | parameter 0 -> this parameter [[]] | true | -| System.Collections.Generic.Dictionary<,>.Add(KeyValuePair) | parameter 0 [Key] -> this parameter [[], Key] | true | -| System.Collections.Generic.Dictionary<,>.Add(KeyValuePair) | parameter 0 [Value] -> this parameter [[], Value] | true | -| System.Collections.Generic.Dictionary<,>.Add(TKey, TValue) | parameter 0 -> this parameter [[], Key] | true | -| System.Collections.Generic.Dictionary<,>.Add(TKey, TValue) | parameter 1 -> this parameter [[], Value] | true | -| System.Collections.Generic.Dictionary<,>.Add(object, object) | parameter 0 -> this parameter [[], Key] | true | -| System.Collections.Generic.Dictionary<,>.Add(object, object) | parameter 1 -> this parameter [[], Value] | true | -| System.Collections.Generic.Dictionary<,>.CopyTo(Array, int) | this parameter [[]] -> parameter 0 [[]] | true | -| System.Collections.Generic.Dictionary<,>.CopyTo(KeyValuePair[], int) | this parameter [[]] -> parameter 0 [[]] | true | -| System.Collections.Generic.Dictionary<,>.Dictionary(IDictionary) | parameter 0 [[], Key] -> return [[], Key] | true | -| System.Collections.Generic.Dictionary<,>.Dictionary(IDictionary) | parameter 0 [[], Value] -> return [[], Value] | true | -| System.Collections.Generic.Dictionary<,>.Dictionary(IDictionary, IEqualityComparer) | parameter 0 [[], Key] -> return [[], Key] | true | -| System.Collections.Generic.Dictionary<,>.Dictionary(IDictionary, IEqualityComparer) | parameter 0 [[], Value] -> return [[], Value] | true | -| System.Collections.Generic.Dictionary<,>.Dictionary(IEnumerable>) | parameter 0 [[], Key] -> return [[], Key] | true | -| System.Collections.Generic.Dictionary<,>.Dictionary(IEnumerable>) | parameter 0 [[], Value] -> return [[], Value] | true | -| System.Collections.Generic.Dictionary<,>.Dictionary(IEnumerable>, IEqualityComparer) | parameter 0 [[], Key] -> return [[], Key] | true | -| System.Collections.Generic.Dictionary<,>.Dictionary(IEnumerable>, IEqualityComparer) | parameter 0 [[], Value] -> return [[], Value] | true | -| System.Collections.Generic.Dictionary<,>.GetEnumerator() | this parameter [[]] -> return [Current] | true | -| System.Collections.Generic.Dictionary<,>.KeyCollection.Add(TKey) | parameter 0 -> this parameter [[]] | true | -| System.Collections.Generic.Dictionary<,>.KeyCollection.CopyTo(Array, int) | this parameter [[]] -> parameter 0 [[]] | true | -| System.Collections.Generic.Dictionary<,>.KeyCollection.CopyTo(TKey[], int) | this parameter [[]] -> parameter 0 [[]] | true | -| System.Collections.Generic.Dictionary<,>.KeyCollection.GetEnumerator() | this parameter [[]] -> return [Current] | true | -| System.Collections.Generic.Dictionary<,>.ValueCollection.Add(TValue) | parameter 0 -> this parameter [[]] | true | -| System.Collections.Generic.Dictionary<,>.ValueCollection.CopyTo(Array, int) | this parameter [[]] -> parameter 0 [[]] | true | -| System.Collections.Generic.Dictionary<,>.ValueCollection.CopyTo(TValue[], int) | this parameter [[]] -> parameter 0 [[]] | true | -| System.Collections.Generic.Dictionary<,>.ValueCollection.GetEnumerator() | this parameter [[]] -> return [Current] | true | -| System.Collections.Generic.Dictionary<,>.get_Item(TKey) | this parameter [[], Value] -> return | true | -| System.Collections.Generic.Dictionary<,>.get_Item(object) | this parameter [[], Value] -> return | true | -| System.Collections.Generic.Dictionary<,>.get_Keys() | this parameter [[], Key] -> return [[]] | true | -| System.Collections.Generic.Dictionary<,>.get_Values() | this parameter [[], Value] -> return [[]] | true | -| System.Collections.Generic.Dictionary<,>.set_Item(TKey, TValue) | parameter 0 -> this parameter [[], Key] | true | -| System.Collections.Generic.Dictionary<,>.set_Item(TKey, TValue) | parameter 1 -> this parameter [[], Value] | true | -| System.Collections.Generic.Dictionary<,>.set_Item(object, object) | parameter 0 -> this parameter [[], Key] | true | -| System.Collections.Generic.Dictionary<,>.set_Item(object, object) | parameter 1 -> this parameter [[], Value] | true | -| System.Collections.Generic.HashSet<>.Add(T) | parameter 0 -> this parameter [[]] | true | -| System.Collections.Generic.HashSet<>.CopyTo(T[], int) | this parameter [[]] -> parameter 0 [[]] | true | -| System.Collections.Generic.HashSet<>.GetEnumerator() | this parameter [[]] -> return [Current] | true | -| System.Collections.Generic.ICollection<>.Add(T) | parameter 0 -> this parameter [[]] | true | -| System.Collections.Generic.ICollection<>.CopyTo(T[], int) | this parameter [[]] -> parameter 0 [[]] | true | -| System.Collections.Generic.IDictionary<,>.Add(TKey, TValue) | parameter 0 -> this parameter [[], Key] | true | -| System.Collections.Generic.IDictionary<,>.Add(TKey, TValue) | parameter 1 -> this parameter [[], Value] | true | -| System.Collections.Generic.IDictionary<,>.get_Item(TKey) | this parameter [[], Value] -> return | true | -| System.Collections.Generic.IDictionary<,>.get_Keys() | this parameter [[], Key] -> return [[]] | true | -| System.Collections.Generic.IDictionary<,>.get_Values() | this parameter [[], Value] -> return [[]] | true | -| System.Collections.Generic.IDictionary<,>.set_Item(TKey, TValue) | parameter 0 -> this parameter [[], Key] | true | -| System.Collections.Generic.IDictionary<,>.set_Item(TKey, TValue) | parameter 1 -> this parameter [[], Value] | true | -| System.Collections.Generic.IList<>.Insert(int, T) | parameter 1 -> this parameter [[]] | true | -| System.Collections.Generic.IList<>.get_Item(int) | this parameter [[]] -> return | true | -| System.Collections.Generic.IList<>.set_Item(int, T) | parameter 1 -> this parameter [[]] | true | -| System.Collections.Generic.ISet<>.Add(T) | parameter 0 -> this parameter [[]] | true | -| System.Collections.Generic.KeyValuePair<,>.KeyValuePair() | parameter 0 -> return [Key] | true | -| System.Collections.Generic.KeyValuePair<,>.KeyValuePair() | parameter 1 -> return [Value] | true | -| System.Collections.Generic.KeyValuePair<,>.KeyValuePair(TKey, TValue) | parameter 0 -> return [Key] | true | -| System.Collections.Generic.KeyValuePair<,>.KeyValuePair(TKey, TValue) | parameter 1 -> return [Value] | true | -| System.Collections.Generic.LinkedList<>.Add(T) | parameter 0 -> this parameter [[]] | true | -| System.Collections.Generic.LinkedList<>.CopyTo(Array, int) | this parameter [[]] -> parameter 0 [[]] | true | -| System.Collections.Generic.LinkedList<>.CopyTo(T[], int) | this parameter [[]] -> parameter 0 [[]] | true | -| System.Collections.Generic.LinkedList<>.Find(T) | this parameter [[]] -> return | true | -| System.Collections.Generic.LinkedList<>.FindLast(T) | this parameter [[]] -> return | true | -| System.Collections.Generic.LinkedList<>.GetEnumerator() | this parameter [[]] -> return [Current] | true | -| System.Collections.Generic.List<>.Add(T) | parameter 0 -> this parameter [[]] | true | -| System.Collections.Generic.List<>.Add(object) | parameter 0 -> this parameter [[]] | true | -| System.Collections.Generic.List<>.AddRange(IEnumerable) | parameter 0 [[]] -> this parameter [[]] | true | -| System.Collections.Generic.List<>.AsReadOnly() | parameter 0 [[]] -> return [[]] | true | -| System.Collections.Generic.List<>.CopyTo(Array, int) | this parameter [[]] -> parameter 0 [[]] | true | -| System.Collections.Generic.List<>.CopyTo(T[], int) | this parameter [[]] -> parameter 0 [[]] | true | -| System.Collections.Generic.List<>.Find(Predicate) | this parameter [[]] -> parameter 0 of delegate parameter 0 | true | -| System.Collections.Generic.List<>.Find(Predicate) | this parameter [[]] -> return | true | -| System.Collections.Generic.List<>.FindAll(Predicate) | this parameter [[]] -> parameter 0 of delegate parameter 0 | true | -| System.Collections.Generic.List<>.FindAll(Predicate) | this parameter [[]] -> return | true | -| System.Collections.Generic.List<>.FindLast(Predicate) | this parameter [[]] -> parameter 0 of delegate parameter 0 | true | -| System.Collections.Generic.List<>.FindLast(Predicate) | this parameter [[]] -> return | true | -| System.Collections.Generic.List<>.GetEnumerator() | this parameter [[]] -> return [Current] | true | -| System.Collections.Generic.List<>.GetRange(int, int) | parameter 0 [[]] -> return [[]] | true | -| System.Collections.Generic.List<>.Insert(int, T) | parameter 1 -> this parameter [[]] | true | -| System.Collections.Generic.List<>.Insert(int, object) | parameter 1 -> this parameter [[]] | true | -| System.Collections.Generic.List<>.InsertRange(int, IEnumerable) | parameter 1 [[]] -> this parameter [[]] | true | -| System.Collections.Generic.List<>.Reverse() | parameter 0 [[]] -> return [[]] | true | -| System.Collections.Generic.List<>.Reverse(int, int) | parameter 0 [[]] -> return [[]] | true | -| System.Collections.Generic.List<>.get_Item(int) | this parameter [[]] -> return | true | -| System.Collections.Generic.List<>.set_Item(int, T) | parameter 1 -> this parameter [[]] | true | -| System.Collections.Generic.List<>.set_Item(int, object) | parameter 1 -> this parameter [[]] | true | -| System.Collections.Generic.Queue<>.CopyTo(Array, int) | this parameter [[]] -> parameter 0 [[]] | true | -| System.Collections.Generic.Queue<>.CopyTo(T[], int) | this parameter [[]] -> parameter 0 [[]] | true | -| System.Collections.Generic.Queue<>.GetEnumerator() | this parameter [[]] -> return [Current] | true | -| System.Collections.Generic.Queue<>.Peek() | this parameter [[]] -> return | true | -| System.Collections.Generic.SortedDictionary<,>.Add(KeyValuePair) | parameter 0 -> this parameter [[]] | true | -| System.Collections.Generic.SortedDictionary<,>.Add(KeyValuePair) | parameter 0 [Key] -> this parameter [[], Key] | true | -| System.Collections.Generic.SortedDictionary<,>.Add(KeyValuePair) | parameter 0 [Value] -> this parameter [[], Value] | true | -| System.Collections.Generic.SortedDictionary<,>.Add(TKey, TValue) | parameter 0 -> this parameter [[], Key] | true | -| System.Collections.Generic.SortedDictionary<,>.Add(TKey, TValue) | parameter 1 -> this parameter [[], Value] | true | -| System.Collections.Generic.SortedDictionary<,>.Add(object, object) | parameter 0 -> this parameter [[], Key] | true | -| System.Collections.Generic.SortedDictionary<,>.Add(object, object) | parameter 1 -> this parameter [[], Value] | true | -| System.Collections.Generic.SortedDictionary<,>.CopyTo(Array, int) | this parameter [[]] -> parameter 0 [[]] | true | -| System.Collections.Generic.SortedDictionary<,>.CopyTo(KeyValuePair[], int) | this parameter [[]] -> parameter 0 [[]] | true | -| System.Collections.Generic.SortedDictionary<,>.GetEnumerator() | this parameter [[]] -> return [Current] | true | -| System.Collections.Generic.SortedDictionary<,>.KeyCollection.Add(TKey) | parameter 0 -> this parameter [[]] | true | -| System.Collections.Generic.SortedDictionary<,>.KeyCollection.CopyTo(Array, int) | this parameter [[]] -> parameter 0 [[]] | true | -| System.Collections.Generic.SortedDictionary<,>.KeyCollection.CopyTo(TKey[], int) | this parameter [[]] -> parameter 0 [[]] | true | -| System.Collections.Generic.SortedDictionary<,>.KeyCollection.GetEnumerator() | this parameter [[]] -> return [Current] | true | -| System.Collections.Generic.SortedDictionary<,>.SortedDictionary(IDictionary) | parameter 0 [[], Key] -> return [[], Key] | true | -| System.Collections.Generic.SortedDictionary<,>.SortedDictionary(IDictionary) | parameter 0 [[], Value] -> return [[], Value] | true | -| System.Collections.Generic.SortedDictionary<,>.SortedDictionary(IDictionary, IComparer) | parameter 0 [[], Key] -> return [[], Key] | true | -| System.Collections.Generic.SortedDictionary<,>.SortedDictionary(IDictionary, IComparer) | parameter 0 [[], Value] -> return [[], Value] | true | -| System.Collections.Generic.SortedDictionary<,>.ValueCollection.Add(TValue) | parameter 0 -> this parameter [[]] | true | -| System.Collections.Generic.SortedDictionary<,>.ValueCollection.CopyTo(Array, int) | this parameter [[]] -> parameter 0 [[]] | true | -| System.Collections.Generic.SortedDictionary<,>.ValueCollection.CopyTo(TValue[], int) | this parameter [[]] -> parameter 0 [[]] | true | -| System.Collections.Generic.SortedDictionary<,>.ValueCollection.GetEnumerator() | this parameter [[]] -> return [Current] | true | -| System.Collections.Generic.SortedDictionary<,>.get_Item(TKey) | this parameter [[], Value] -> return | true | -| System.Collections.Generic.SortedDictionary<,>.get_Item(object) | this parameter [[], Value] -> return | true | -| System.Collections.Generic.SortedDictionary<,>.get_Keys() | this parameter [[], Key] -> return [[]] | true | -| System.Collections.Generic.SortedDictionary<,>.get_Values() | this parameter [[], Value] -> return [[]] | true | -| System.Collections.Generic.SortedDictionary<,>.set_Item(TKey, TValue) | parameter 0 -> this parameter [[], Key] | true | -| System.Collections.Generic.SortedDictionary<,>.set_Item(TKey, TValue) | parameter 1 -> this parameter [[], Value] | true | -| System.Collections.Generic.SortedDictionary<,>.set_Item(object, object) | parameter 0 -> this parameter [[], Key] | true | -| System.Collections.Generic.SortedDictionary<,>.set_Item(object, object) | parameter 1 -> this parameter [[], Value] | true | -| System.Collections.Generic.SortedList<,>.Add(KeyValuePair) | parameter 0 -> this parameter [[]] | true | -| System.Collections.Generic.SortedList<,>.Add(KeyValuePair) | parameter 0 [Key] -> this parameter [[], Key] | true | -| System.Collections.Generic.SortedList<,>.Add(KeyValuePair) | parameter 0 [Value] -> this parameter [[], Value] | true | -| System.Collections.Generic.SortedList<,>.Add(TKey, TValue) | parameter 0 -> this parameter [[], Key] | true | -| System.Collections.Generic.SortedList<,>.Add(TKey, TValue) | parameter 1 -> this parameter [[], Value] | true | -| System.Collections.Generic.SortedList<,>.Add(object, object) | parameter 0 -> this parameter [[], Key] | true | -| System.Collections.Generic.SortedList<,>.Add(object, object) | parameter 1 -> this parameter [[], Value] | true | -| System.Collections.Generic.SortedList<,>.CopyTo(Array, int) | this parameter [[]] -> parameter 0 [[]] | true | -| System.Collections.Generic.SortedList<,>.CopyTo(KeyValuePair[], int) | this parameter [[]] -> parameter 0 [[]] | true | -| System.Collections.Generic.SortedList<,>.GetEnumerator() | this parameter [[]] -> return [Current] | true | -| System.Collections.Generic.SortedList<,>.KeyList.Add(TKey) | parameter 0 -> this parameter [[]] | true | -| System.Collections.Generic.SortedList<,>.KeyList.CopyTo(Array, int) | this parameter [[]] -> parameter 0 [[]] | true | -| System.Collections.Generic.SortedList<,>.KeyList.CopyTo(TKey[], int) | this parameter [[]] -> parameter 0 [[]] | true | -| System.Collections.Generic.SortedList<,>.KeyList.GetEnumerator() | this parameter [[]] -> return [Current] | true | -| System.Collections.Generic.SortedList<,>.KeyList.Insert(int, TKey) | parameter 1 -> this parameter [[]] | true | -| System.Collections.Generic.SortedList<,>.KeyList.get_Item(int) | this parameter [[]] -> return | true | -| System.Collections.Generic.SortedList<,>.KeyList.set_Item(int, TKey) | parameter 1 -> this parameter [[]] | true | -| System.Collections.Generic.SortedList<,>.SortedList(IDictionary) | parameter 0 [[], Key] -> return [[], Key] | true | -| System.Collections.Generic.SortedList<,>.SortedList(IDictionary) | parameter 0 [[], Value] -> return [[], Value] | true | -| System.Collections.Generic.SortedList<,>.SortedList(IDictionary, IComparer) | parameter 0 [[], Key] -> return [[], Key] | true | -| System.Collections.Generic.SortedList<,>.SortedList(IDictionary, IComparer) | parameter 0 [[], Value] -> return [[], Value] | true | -| System.Collections.Generic.SortedList<,>.ValueList.Add(TValue) | parameter 0 -> this parameter [[]] | true | -| System.Collections.Generic.SortedList<,>.ValueList.CopyTo(Array, int) | this parameter [[]] -> parameter 0 [[]] | true | -| System.Collections.Generic.SortedList<,>.ValueList.CopyTo(TValue[], int) | this parameter [[]] -> parameter 0 [[]] | true | -| System.Collections.Generic.SortedList<,>.ValueList.GetEnumerator() | this parameter [[]] -> return [Current] | true | -| System.Collections.Generic.SortedList<,>.ValueList.Insert(int, TValue) | parameter 1 -> this parameter [[]] | true | -| System.Collections.Generic.SortedList<,>.ValueList.get_Item(int) | this parameter [[]] -> return | true | -| System.Collections.Generic.SortedList<,>.ValueList.set_Item(int, TValue) | parameter 1 -> this parameter [[]] | true | -| System.Collections.Generic.SortedList<,>.get_Item(TKey) | this parameter [[], Value] -> return | true | -| System.Collections.Generic.SortedList<,>.get_Item(object) | this parameter [[], Value] -> return | true | -| System.Collections.Generic.SortedList<,>.get_Keys() | this parameter [[], Key] -> return [[]] | true | -| System.Collections.Generic.SortedList<,>.get_Values() | this parameter [[], Value] -> return [[]] | true | -| System.Collections.Generic.SortedList<,>.set_Item(TKey, TValue) | parameter 0 -> this parameter [[], Key] | true | -| System.Collections.Generic.SortedList<,>.set_Item(TKey, TValue) | parameter 1 -> this parameter [[], Value] | true | -| System.Collections.Generic.SortedList<,>.set_Item(object, object) | parameter 0 -> this parameter [[], Key] | true | -| System.Collections.Generic.SortedList<,>.set_Item(object, object) | parameter 1 -> this parameter [[], Value] | true | -| System.Collections.Generic.SortedSet<>.d__84.GetEnumerator() | this parameter [[]] -> return [Current] | true | -| System.Collections.Generic.SortedSet<>.Add(T) | parameter 0 -> this parameter [[]] | true | -| System.Collections.Generic.SortedSet<>.CopyTo(Array, int) | this parameter [[]] -> parameter 0 [[]] | true | -| System.Collections.Generic.SortedSet<>.CopyTo(T[], int) | this parameter [[]] -> parameter 0 [[]] | true | -| System.Collections.Generic.SortedSet<>.GetEnumerator() | this parameter [[]] -> return [Current] | true | -| System.Collections.Generic.SortedSet<>.Reverse() | parameter 0 [[]] -> return [[]] | true | -| System.Collections.Generic.Stack<>.CopyTo(Array, int) | this parameter [[]] -> parameter 0 [[]] | true | -| System.Collections.Generic.Stack<>.CopyTo(T[], int) | this parameter [[]] -> parameter 0 [[]] | true | -| System.Collections.Generic.Stack<>.GetEnumerator() | this parameter [[]] -> return [Current] | true | -| System.Collections.Generic.Stack<>.Peek() | this parameter [[]] -> return | true | -| System.Collections.Generic.Stack<>.Pop() | this parameter [[]] -> return | true | -| System.Collections.Hashtable.Add(object, object) | parameter 0 -> this parameter [[], Key] | true | -| System.Collections.Hashtable.Add(object, object) | parameter 1 -> this parameter [[], Value] | true | -| System.Collections.Hashtable.Clone() | parameter 0 [[]] -> return [[]] | true | -| System.Collections.Hashtable.CopyTo(Array, int) | this parameter [[]] -> parameter 0 [[]] | true | -| System.Collections.Hashtable.GetEnumerator() | this parameter [[]] -> return [Current] | true | -| System.Collections.Hashtable.Hashtable(IDictionary) | parameter 0 [[], Key] -> return [[], Key] | true | -| System.Collections.Hashtable.Hashtable(IDictionary) | parameter 0 [[], Value] -> return [[], Value] | true | -| System.Collections.Hashtable.Hashtable(IDictionary, IEqualityComparer) | parameter 0 [[], Key] -> return [[], Key] | true | -| System.Collections.Hashtable.Hashtable(IDictionary, IEqualityComparer) | parameter 0 [[], Value] -> return [[], Value] | true | -| System.Collections.Hashtable.Hashtable(IDictionary, IHashCodeProvider, IComparer) | parameter 0 [[], Key] -> return [[], Key] | true | -| System.Collections.Hashtable.Hashtable(IDictionary, IHashCodeProvider, IComparer) | parameter 0 [[], Value] -> return [[], Value] | true | -| System.Collections.Hashtable.Hashtable(IDictionary, float) | parameter 0 [[], Key] -> return [[], Key] | true | -| System.Collections.Hashtable.Hashtable(IDictionary, float) | parameter 0 [[], Value] -> return [[], Value] | true | -| System.Collections.Hashtable.Hashtable(IDictionary, float, IEqualityComparer) | parameter 0 [[], Key] -> return [[], Key] | true | -| System.Collections.Hashtable.Hashtable(IDictionary, float, IEqualityComparer) | parameter 0 [[], Value] -> return [[], Value] | true | -| System.Collections.Hashtable.Hashtable(IDictionary, float, IHashCodeProvider, IComparer) | parameter 0 [[], Key] -> return [[], Key] | true | -| System.Collections.Hashtable.Hashtable(IDictionary, float, IHashCodeProvider, IComparer) | parameter 0 [[], Value] -> return [[], Value] | true | -| System.Collections.Hashtable.KeyCollection.CopyTo(Array, int) | this parameter [[]] -> parameter 0 [[]] | true | -| System.Collections.Hashtable.KeyCollection.GetEnumerator() | this parameter [[]] -> return [Current] | true | -| System.Collections.Hashtable.SyncHashtable.Add(object, object) | parameter 0 -> this parameter [[], Key] | true | -| System.Collections.Hashtable.SyncHashtable.Add(object, object) | parameter 1 -> this parameter [[], Value] | true | -| System.Collections.Hashtable.SyncHashtable.Clone() | parameter 0 [[]] -> return [[]] | true | -| System.Collections.Hashtable.SyncHashtable.CopyTo(Array, int) | this parameter [[]] -> parameter 0 [[]] | true | -| System.Collections.Hashtable.SyncHashtable.GetEnumerator() | this parameter [[]] -> return [Current] | true | -| System.Collections.Hashtable.SyncHashtable.get_Item(object) | this parameter [[], Value] -> return | true | -| System.Collections.Hashtable.SyncHashtable.get_Keys() | this parameter [[], Key] -> return [[]] | true | -| System.Collections.Hashtable.SyncHashtable.get_Values() | this parameter [[], Value] -> return [[]] | true | -| System.Collections.Hashtable.SyncHashtable.set_Item(object, object) | parameter 0 -> this parameter [[], Key] | true | -| System.Collections.Hashtable.SyncHashtable.set_Item(object, object) | parameter 1 -> this parameter [[], Value] | true | -| System.Collections.Hashtable.ValueCollection.CopyTo(Array, int) | this parameter [[]] -> parameter 0 [[]] | true | -| System.Collections.Hashtable.ValueCollection.GetEnumerator() | this parameter [[]] -> return [Current] | true | -| System.Collections.Hashtable.get_Item(object) | this parameter [[], Value] -> return | true | -| System.Collections.Hashtable.get_Keys() | this parameter [[], Key] -> return [[]] | true | -| System.Collections.Hashtable.get_Values() | this parameter [[], Value] -> return [[]] | true | -| System.Collections.Hashtable.set_Item(object, object) | parameter 0 -> this parameter [[], Key] | true | -| System.Collections.Hashtable.set_Item(object, object) | parameter 1 -> this parameter [[], Value] | true | -| System.Collections.ICollection.CopyTo(Array, int) | this parameter [[]] -> parameter 0 [[]] | true | -| System.Collections.IDictionary.Add(object, object) | parameter 0 -> this parameter [[], Key] | true | -| System.Collections.IDictionary.Add(object, object) | parameter 1 -> this parameter [[], Value] | true | -| System.Collections.IDictionary.get_Item(object) | this parameter [[], Value] -> return | true | -| System.Collections.IDictionary.get_Keys() | this parameter [[], Key] -> return [[]] | true | -| System.Collections.IDictionary.get_Values() | this parameter [[], Value] -> return [[]] | true | -| System.Collections.IDictionary.set_Item(object, object) | parameter 0 -> this parameter [[], Key] | true | -| System.Collections.IDictionary.set_Item(object, object) | parameter 1 -> this parameter [[], Value] | true | -| System.Collections.IEnumerable.GetEnumerator() | this parameter [[]] -> return [Current] | true | -| System.Collections.IList.Add(object) | parameter 0 -> this parameter [[]] | true | -| System.Collections.IList.Insert(int, object) | parameter 1 -> this parameter [[]] | true | -| System.Collections.IList.get_Item(int) | this parameter [[]] -> return | true | -| System.Collections.IList.set_Item(int, object) | parameter 1 -> this parameter [[]] | true | -| System.Collections.ListDictionaryInternal.Add(object, object) | parameter 0 -> this parameter [[], Key] | true | -| System.Collections.ListDictionaryInternal.Add(object, object) | parameter 1 -> this parameter [[], Value] | true | -| System.Collections.ListDictionaryInternal.CopyTo(Array, int) | this parameter [[]] -> parameter 0 [[]] | true | -| System.Collections.ListDictionaryInternal.GetEnumerator() | this parameter [[]] -> return [Current] | true | -| System.Collections.ListDictionaryInternal.NodeKeyValueCollection.CopyTo(Array, int) | this parameter [[]] -> parameter 0 [[]] | true | -| System.Collections.ListDictionaryInternal.NodeKeyValueCollection.GetEnumerator() | this parameter [[]] -> return [Current] | true | -| System.Collections.ListDictionaryInternal.get_Item(object) | this parameter [[], Value] -> return | true | -| System.Collections.ListDictionaryInternal.get_Keys() | this parameter [[], Key] -> return [[]] | true | -| System.Collections.ListDictionaryInternal.get_Values() | this parameter [[], Value] -> return [[]] | true | -| System.Collections.ListDictionaryInternal.set_Item(object, object) | parameter 0 -> this parameter [[], Key] | true | -| System.Collections.ListDictionaryInternal.set_Item(object, object) | parameter 1 -> this parameter [[], Value] | true | -| System.Collections.ObjectModel.Collection<>.Add(T) | parameter 0 -> this parameter [[]] | true | -| System.Collections.ObjectModel.Collection<>.Add(object) | parameter 0 -> this parameter [[]] | true | -| System.Collections.ObjectModel.Collection<>.CopyTo(Array, int) | this parameter [[]] -> parameter 0 [[]] | true | -| System.Collections.ObjectModel.Collection<>.CopyTo(T[], int) | this parameter [[]] -> parameter 0 [[]] | true | -| System.Collections.ObjectModel.Collection<>.GetEnumerator() | this parameter [[]] -> return [Current] | true | -| System.Collections.ObjectModel.Collection<>.Insert(int, T) | parameter 1 -> this parameter [[]] | true | -| System.Collections.ObjectModel.Collection<>.Insert(int, object) | parameter 1 -> this parameter [[]] | true | -| System.Collections.ObjectModel.Collection<>.get_Item(int) | this parameter [[]] -> return | true | -| System.Collections.ObjectModel.Collection<>.set_Item(int, T) | parameter 1 -> this parameter [[]] | true | -| System.Collections.ObjectModel.Collection<>.set_Item(int, object) | parameter 1 -> this parameter [[]] | true | -| System.Collections.ObjectModel.KeyedCollection<,>.get_Item(TKey) | this parameter [[]] -> return | true | -| System.Collections.ObjectModel.ReadOnlyCollection<>.Add(T) | parameter 0 -> this parameter [[]] | true | -| System.Collections.ObjectModel.ReadOnlyCollection<>.Add(object) | parameter 0 -> this parameter [[]] | true | -| System.Collections.ObjectModel.ReadOnlyCollection<>.CopyTo(Array, int) | this parameter [[]] -> parameter 0 [[]] | true | -| System.Collections.ObjectModel.ReadOnlyCollection<>.CopyTo(T[], int) | this parameter [[]] -> parameter 0 [[]] | true | -| System.Collections.ObjectModel.ReadOnlyCollection<>.GetEnumerator() | this parameter [[]] -> return [Current] | true | -| System.Collections.ObjectModel.ReadOnlyCollection<>.Insert(int, T) | parameter 1 -> this parameter [[]] | true | -| System.Collections.ObjectModel.ReadOnlyCollection<>.Insert(int, object) | parameter 1 -> this parameter [[]] | true | -| System.Collections.ObjectModel.ReadOnlyCollection<>.get_Item(int) | this parameter [[]] -> return | true | -| System.Collections.ObjectModel.ReadOnlyCollection<>.set_Item(int, T) | parameter 1 -> this parameter [[]] | true | -| System.Collections.ObjectModel.ReadOnlyCollection<>.set_Item(int, object) | parameter 1 -> this parameter [[]] | true | -| System.Collections.ObjectModel.ReadOnlyDictionary<,>.Add(KeyValuePair) | parameter 0 -> this parameter [[]] | true | -| System.Collections.ObjectModel.ReadOnlyDictionary<,>.Add(KeyValuePair) | parameter 0 [Key] -> this parameter [[], Key] | true | -| System.Collections.ObjectModel.ReadOnlyDictionary<,>.Add(KeyValuePair) | parameter 0 [Value] -> this parameter [[], Value] | true | -| System.Collections.ObjectModel.ReadOnlyDictionary<,>.Add(TKey, TValue) | parameter 0 -> this parameter [[], Key] | true | -| System.Collections.ObjectModel.ReadOnlyDictionary<,>.Add(TKey, TValue) | parameter 1 -> this parameter [[], Value] | true | -| System.Collections.ObjectModel.ReadOnlyDictionary<,>.Add(object, object) | parameter 0 -> this parameter [[], Key] | true | -| System.Collections.ObjectModel.ReadOnlyDictionary<,>.Add(object, object) | parameter 1 -> this parameter [[], Value] | true | -| System.Collections.ObjectModel.ReadOnlyDictionary<,>.CopyTo(Array, int) | this parameter [[]] -> parameter 0 [[]] | true | -| System.Collections.ObjectModel.ReadOnlyDictionary<,>.CopyTo(KeyValuePair[], int) | this parameter [[]] -> parameter 0 [[]] | true | -| System.Collections.ObjectModel.ReadOnlyDictionary<,>.GetEnumerator() | this parameter [[]] -> return [Current] | true | -| System.Collections.ObjectModel.ReadOnlyDictionary<,>.KeyCollection.Add(TKey) | parameter 0 -> this parameter [[]] | true | -| System.Collections.ObjectModel.ReadOnlyDictionary<,>.KeyCollection.CopyTo(Array, int) | this parameter [[]] -> parameter 0 [[]] | true | -| System.Collections.ObjectModel.ReadOnlyDictionary<,>.KeyCollection.CopyTo(TKey[], int) | this parameter [[]] -> parameter 0 [[]] | true | -| System.Collections.ObjectModel.ReadOnlyDictionary<,>.KeyCollection.GetEnumerator() | this parameter [[]] -> return [Current] | true | -| System.Collections.ObjectModel.ReadOnlyDictionary<,>.ReadOnlyDictionary(IDictionary) | parameter 0 [[], Key] -> return [[], Key] | true | -| System.Collections.ObjectModel.ReadOnlyDictionary<,>.ReadOnlyDictionary(IDictionary) | parameter 0 [[], Value] -> return [[], Value] | true | -| System.Collections.ObjectModel.ReadOnlyDictionary<,>.ValueCollection.Add(TValue) | parameter 0 -> this parameter [[]] | true | -| System.Collections.ObjectModel.ReadOnlyDictionary<,>.ValueCollection.CopyTo(Array, int) | this parameter [[]] -> parameter 0 [[]] | true | -| System.Collections.ObjectModel.ReadOnlyDictionary<,>.ValueCollection.CopyTo(TValue[], int) | this parameter [[]] -> parameter 0 [[]] | true | -| System.Collections.ObjectModel.ReadOnlyDictionary<,>.ValueCollection.GetEnumerator() | this parameter [[]] -> return [Current] | true | -| System.Collections.ObjectModel.ReadOnlyDictionary<,>.get_Item(TKey) | this parameter [[], Value] -> return | true | -| System.Collections.ObjectModel.ReadOnlyDictionary<,>.get_Item(object) | this parameter [[], Value] -> return | true | -| System.Collections.ObjectModel.ReadOnlyDictionary<,>.get_Keys() | this parameter [[], Key] -> return [[]] | true | -| System.Collections.ObjectModel.ReadOnlyDictionary<,>.get_Values() | this parameter [[], Value] -> return [[]] | true | -| System.Collections.ObjectModel.ReadOnlyDictionary<,>.set_Item(TKey, TValue) | parameter 0 -> this parameter [[], Key] | true | -| System.Collections.ObjectModel.ReadOnlyDictionary<,>.set_Item(TKey, TValue) | parameter 1 -> this parameter [[], Value] | true | -| System.Collections.ObjectModel.ReadOnlyDictionary<,>.set_Item(object, object) | parameter 0 -> this parameter [[], Key] | true | -| System.Collections.ObjectModel.ReadOnlyDictionary<,>.set_Item(object, object) | parameter 1 -> this parameter [[], Value] | true | -| System.Collections.Queue.Clone() | parameter 0 [[]] -> return [[]] | true | -| System.Collections.Queue.CopyTo(Array, int) | this parameter [[]] -> parameter 0 [[]] | true | -| System.Collections.Queue.GetEnumerator() | this parameter [[]] -> return [Current] | true | -| System.Collections.Queue.Peek() | this parameter [[]] -> return | true | -| System.Collections.Queue.SynchronizedQueue.Clone() | parameter 0 [[]] -> return [[]] | true | -| System.Collections.Queue.SynchronizedQueue.CopyTo(Array, int) | this parameter [[]] -> parameter 0 [[]] | true | -| System.Collections.Queue.SynchronizedQueue.GetEnumerator() | this parameter [[]] -> return [Current] | true | -| System.Collections.Queue.SynchronizedQueue.Peek() | this parameter [[]] -> return | true | -| System.Collections.ReadOnlyCollectionBase.CopyTo(Array, int) | this parameter [[]] -> parameter 0 [[]] | true | -| System.Collections.ReadOnlyCollectionBase.GetEnumerator() | this parameter [[]] -> return [Current] | true | -| System.Collections.SortedList.Add(object, object) | parameter 0 -> this parameter [[], Key] | true | -| System.Collections.SortedList.Add(object, object) | parameter 1 -> this parameter [[], Value] | true | -| System.Collections.SortedList.Clone() | parameter 0 [[]] -> return [[]] | true | -| System.Collections.SortedList.CopyTo(Array, int) | this parameter [[]] -> parameter 0 [[]] | true | -| System.Collections.SortedList.GetByIndex(int) | this parameter [[], Value] -> return | true | -| System.Collections.SortedList.GetEnumerator() | this parameter [[]] -> return [Current] | true | -| System.Collections.SortedList.GetValueList() | this parameter [[], Value] -> return [[]] | true | -| System.Collections.SortedList.KeyList.Add(object) | parameter 0 -> this parameter [[]] | true | -| System.Collections.SortedList.KeyList.CopyTo(Array, int) | this parameter [[]] -> parameter 0 [[]] | true | -| System.Collections.SortedList.KeyList.GetEnumerator() | this parameter [[]] -> return [Current] | true | -| System.Collections.SortedList.KeyList.Insert(int, object) | parameter 1 -> this parameter [[]] | true | -| System.Collections.SortedList.KeyList.get_Item(int) | this parameter [[]] -> return | true | -| System.Collections.SortedList.KeyList.set_Item(int, object) | parameter 1 -> this parameter [[]] | true | -| System.Collections.SortedList.SortedList(IDictionary) | parameter 0 [[], Key] -> return [[], Key] | true | -| System.Collections.SortedList.SortedList(IDictionary) | parameter 0 [[], Value] -> return [[], Value] | true | -| System.Collections.SortedList.SortedList(IDictionary, IComparer) | parameter 0 [[], Key] -> return [[], Key] | true | -| System.Collections.SortedList.SortedList(IDictionary, IComparer) | parameter 0 [[], Value] -> return [[], Value] | true | -| System.Collections.SortedList.SyncSortedList.Add(object, object) | parameter 0 -> this parameter [[], Key] | true | -| System.Collections.SortedList.SyncSortedList.Add(object, object) | parameter 1 -> this parameter [[], Value] | true | -| System.Collections.SortedList.SyncSortedList.Clone() | parameter 0 [[]] -> return [[]] | true | -| System.Collections.SortedList.SyncSortedList.CopyTo(Array, int) | this parameter [[]] -> parameter 0 [[]] | true | -| System.Collections.SortedList.SyncSortedList.GetByIndex(int) | this parameter [[], Value] -> return | true | -| System.Collections.SortedList.SyncSortedList.GetValueList() | this parameter [[], Value] -> return [[]] | true | -| System.Collections.SortedList.SyncSortedList.get_Item(object) | this parameter [[], Value] -> return | true | -| System.Collections.SortedList.SyncSortedList.set_Item(object, object) | parameter 0 -> this parameter [[], Key] | true | -| System.Collections.SortedList.SyncSortedList.set_Item(object, object) | parameter 1 -> this parameter [[], Value] | true | -| System.Collections.SortedList.ValueList.Add(object) | parameter 0 -> this parameter [[]] | true | -| System.Collections.SortedList.ValueList.CopyTo(Array, int) | this parameter [[]] -> parameter 0 [[]] | true | -| System.Collections.SortedList.ValueList.GetEnumerator() | this parameter [[]] -> return [Current] | true | -| System.Collections.SortedList.ValueList.Insert(int, object) | parameter 1 -> this parameter [[]] | true | -| System.Collections.SortedList.ValueList.get_Item(int) | this parameter [[]] -> return | true | -| System.Collections.SortedList.ValueList.set_Item(int, object) | parameter 1 -> this parameter [[]] | true | -| System.Collections.SortedList.get_Item(object) | this parameter [[], Value] -> return | true | -| System.Collections.SortedList.get_Keys() | this parameter [[], Key] -> return [[]] | true | -| System.Collections.SortedList.get_Values() | this parameter [[], Value] -> return [[]] | true | -| System.Collections.SortedList.set_Item(object, object) | parameter 0 -> this parameter [[], Key] | true | -| System.Collections.SortedList.set_Item(object, object) | parameter 1 -> this parameter [[], Value] | true | -| System.Collections.Specialized.HybridDictionary.Add(object, object) | parameter 0 -> this parameter [[], Key] | true | -| System.Collections.Specialized.HybridDictionary.Add(object, object) | parameter 1 -> this parameter [[], Value] | true | -| System.Collections.Specialized.HybridDictionary.CopyTo(Array, int) | this parameter [[]] -> parameter 0 [[]] | true | -| System.Collections.Specialized.HybridDictionary.GetEnumerator() | this parameter [[]] -> return [Current] | true | -| System.Collections.Specialized.HybridDictionary.get_Item(object) | this parameter [[], Value] -> return | true | -| System.Collections.Specialized.HybridDictionary.get_Keys() | this parameter [[], Key] -> return [[]] | true | -| System.Collections.Specialized.HybridDictionary.get_Values() | this parameter [[], Value] -> return [[]] | true | -| System.Collections.Specialized.HybridDictionary.set_Item(object, object) | parameter 0 -> this parameter [[], Key] | true | -| System.Collections.Specialized.HybridDictionary.set_Item(object, object) | parameter 1 -> this parameter [[], Value] | true | -| System.Collections.Specialized.IOrderedDictionary.get_Item(int) | this parameter [[], Value] -> return | true | -| System.Collections.Specialized.IOrderedDictionary.set_Item(int, object) | parameter 0 -> this parameter [[], Key] | true | -| System.Collections.Specialized.IOrderedDictionary.set_Item(int, object) | parameter 1 -> this parameter [[], Value] | true | -| System.Collections.Specialized.ListDictionary.Add(object, object) | parameter 0 -> this parameter [[], Key] | true | -| System.Collections.Specialized.ListDictionary.Add(object, object) | parameter 1 -> this parameter [[], Value] | true | -| System.Collections.Specialized.ListDictionary.CopyTo(Array, int) | this parameter [[]] -> parameter 0 [[]] | true | -| System.Collections.Specialized.ListDictionary.GetEnumerator() | this parameter [[]] -> return [Current] | true | -| System.Collections.Specialized.ListDictionary.NodeKeyValueCollection.CopyTo(Array, int) | this parameter [[]] -> parameter 0 [[]] | true | -| System.Collections.Specialized.ListDictionary.NodeKeyValueCollection.GetEnumerator() | this parameter [[]] -> return [Current] | true | -| System.Collections.Specialized.ListDictionary.get_Item(object) | this parameter [[], Value] -> return | true | -| System.Collections.Specialized.ListDictionary.get_Keys() | this parameter [[], Key] -> return [[]] | true | -| System.Collections.Specialized.ListDictionary.get_Values() | this parameter [[], Value] -> return [[]] | true | -| System.Collections.Specialized.ListDictionary.set_Item(object, object) | parameter 0 -> this parameter [[], Key] | true | -| System.Collections.Specialized.ListDictionary.set_Item(object, object) | parameter 1 -> this parameter [[], Value] | true | -| System.Collections.Specialized.NameObjectCollectionBase.CopyTo(Array, int) | this parameter [[]] -> parameter 0 [[]] | true | -| System.Collections.Specialized.NameObjectCollectionBase.GetEnumerator() | this parameter [[]] -> return [Current] | true | -| System.Collections.Specialized.NameObjectCollectionBase.KeysCollection.CopyTo(Array, int) | this parameter [[]] -> parameter 0 [[]] | true | -| System.Collections.Specialized.NameObjectCollectionBase.KeysCollection.GetEnumerator() | this parameter [[]] -> return [Current] | true | -| System.Collections.Specialized.NameValueCollection.Add(NameValueCollection) | parameter 0 -> this parameter [[]] | true | -| System.Collections.Specialized.NameValueCollection.CopyTo(Array, int) | this parameter [[]] -> parameter 0 [[]] | true | -| System.Collections.Specialized.OrderedDictionary.Add(object, object) | parameter 0 -> this parameter [[], Key] | true | -| System.Collections.Specialized.OrderedDictionary.Add(object, object) | parameter 1 -> this parameter [[], Value] | true | -| System.Collections.Specialized.OrderedDictionary.AsReadOnly() | parameter 0 [[]] -> return [[]] | true | -| System.Collections.Specialized.OrderedDictionary.CopyTo(Array, int) | this parameter [[]] -> parameter 0 [[]] | true | -| System.Collections.Specialized.OrderedDictionary.GetEnumerator() | this parameter [[]] -> return [Current] | true | -| System.Collections.Specialized.OrderedDictionary.OrderedDictionaryKeyValueCollection.CopyTo(Array, int) | this parameter [[]] -> parameter 0 [[]] | true | -| System.Collections.Specialized.OrderedDictionary.OrderedDictionaryKeyValueCollection.GetEnumerator() | this parameter [[]] -> return [Current] | true | -| System.Collections.Specialized.OrderedDictionary.get_Item(int) | this parameter [[], Value] -> return | true | -| System.Collections.Specialized.OrderedDictionary.get_Item(object) | this parameter [[], Value] -> return | true | -| System.Collections.Specialized.OrderedDictionary.get_Keys() | this parameter [[], Key] -> return [[]] | true | -| System.Collections.Specialized.OrderedDictionary.get_Values() | this parameter [[], Value] -> return [[]] | true | -| System.Collections.Specialized.OrderedDictionary.set_Item(int, object) | parameter 0 -> this parameter [[], Key] | true | -| System.Collections.Specialized.OrderedDictionary.set_Item(int, object) | parameter 1 -> this parameter [[], Value] | true | -| System.Collections.Specialized.OrderedDictionary.set_Item(object, object) | parameter 0 -> this parameter [[], Key] | true | -| System.Collections.Specialized.OrderedDictionary.set_Item(object, object) | parameter 1 -> this parameter [[], Value] | true | -| System.Collections.Specialized.ReadOnlyList.Add(object) | parameter 0 -> this parameter [[]] | true | -| System.Collections.Specialized.ReadOnlyList.CopyTo(Array, int) | this parameter [[]] -> parameter 0 [[]] | true | -| System.Collections.Specialized.ReadOnlyList.GetEnumerator() | this parameter [[]] -> return [Current] | true | -| System.Collections.Specialized.ReadOnlyList.Insert(int, object) | parameter 1 -> this parameter [[]] | true | -| System.Collections.Specialized.ReadOnlyList.get_Item(int) | this parameter [[]] -> return | true | -| System.Collections.Specialized.ReadOnlyList.set_Item(int, object) | parameter 1 -> this parameter [[]] | true | -| System.Collections.Specialized.StringCollection.Add(object) | parameter 0 -> this parameter [[]] | true | -| System.Collections.Specialized.StringCollection.Add(string) | parameter 0 -> this parameter [[]] | true | -| System.Collections.Specialized.StringCollection.AddRange(String[]) | parameter 0 [[]] -> this parameter [[]] | true | -| System.Collections.Specialized.StringCollection.CopyTo(Array, int) | this parameter [[]] -> parameter 0 [[]] | true | -| System.Collections.Specialized.StringCollection.CopyTo(String[], int) | this parameter [[]] -> parameter 0 [[]] | true | -| System.Collections.Specialized.StringCollection.GetEnumerator() | this parameter [[]] -> return [Current] | true | -| System.Collections.Specialized.StringCollection.Insert(int, object) | parameter 1 -> this parameter [[]] | true | -| System.Collections.Specialized.StringCollection.Insert(int, string) | parameter 1 -> this parameter [[]] | true | -| System.Collections.Specialized.StringCollection.get_Item(int) | this parameter [[]] -> return | true | -| System.Collections.Specialized.StringCollection.set_Item(int, object) | parameter 1 -> this parameter [[]] | true | -| System.Collections.Specialized.StringCollection.set_Item(int, string) | parameter 1 -> this parameter [[]] | true | -| System.Collections.Specialized.StringDictionary.GetEnumerator() | this parameter [[]] -> return [Current] | true | -| System.Collections.Stack.Clone() | parameter 0 [[]] -> return [[]] | true | -| System.Collections.Stack.CopyTo(Array, int) | this parameter [[]] -> parameter 0 [[]] | true | -| System.Collections.Stack.GetEnumerator() | this parameter [[]] -> return [Current] | true | -| System.Collections.Stack.Peek() | this parameter [[]] -> return | true | -| System.Collections.Stack.Pop() | this parameter [[]] -> return | true | -| System.Collections.Stack.SyncStack.Clone() | parameter 0 [[]] -> return [[]] | true | -| System.Collections.Stack.SyncStack.CopyTo(Array, int) | this parameter [[]] -> parameter 0 [[]] | true | -| System.Collections.Stack.SyncStack.GetEnumerator() | this parameter [[]] -> return [Current] | true | -| System.Collections.Stack.SyncStack.Peek() | this parameter [[]] -> return | true | -| System.Collections.Stack.SyncStack.Pop() | this parameter [[]] -> return | true | -| System.ComponentModel.AttributeCollection.CopyTo(Array, int) | this parameter [[]] -> parameter 0 [[]] | true | -| System.ComponentModel.AttributeCollection.GetEnumerator() | this parameter [[]] -> return [Current] | true | -| System.ComponentModel.BindingList<>.Find(PropertyDescriptor, object) | this parameter [[]] -> return | true | -| System.ComponentModel.Design.DesignerCollection.CopyTo(Array, int) | this parameter [[]] -> parameter 0 [[]] | true | -| System.ComponentModel.Design.DesignerCollection.GetEnumerator() | this parameter [[]] -> return [Current] | true | -| System.ComponentModel.Design.DesignerOptionService.DesignerOptionCollection.Add(object) | parameter 0 -> this parameter [[]] | true | -| System.ComponentModel.Design.DesignerOptionService.DesignerOptionCollection.CopyTo(Array, int) | this parameter [[]] -> parameter 0 [[]] | true | -| System.ComponentModel.Design.DesignerOptionService.DesignerOptionCollection.GetEnumerator() | this parameter [[]] -> return [Current] | true | -| System.ComponentModel.Design.DesignerOptionService.DesignerOptionCollection.Insert(int, object) | parameter 1 -> this parameter [[]] | true | -| System.ComponentModel.Design.DesignerOptionService.DesignerOptionCollection.get_Item(int) | this parameter [[]] -> return | true | -| System.ComponentModel.Design.DesignerOptionService.DesignerOptionCollection.get_Item(string) | this parameter [[]] -> return | true | -| System.ComponentModel.Design.DesignerOptionService.DesignerOptionCollection.set_Item(int, object) | parameter 1 -> this parameter [[]] | true | -| System.ComponentModel.Design.DesignerVerbCollection.Add(DesignerVerb) | parameter 0 -> this parameter [[]] | true | -| System.ComponentModel.Design.DesignerVerbCollection.AddRange(DesignerVerbCollection) | parameter 0 [[]] -> this parameter [[]] | true | -| System.ComponentModel.Design.DesignerVerbCollection.AddRange(DesignerVerb[]) | parameter 0 [[]] -> this parameter [[]] | true | -| System.ComponentModel.Design.DesignerVerbCollection.CopyTo(DesignerVerb[], int) | this parameter [[]] -> parameter 0 [[]] | true | -| System.ComponentModel.Design.DesignerVerbCollection.Insert(int, DesignerVerb) | parameter 1 -> this parameter [[]] | true | -| System.ComponentModel.Design.DesignerVerbCollection.get_Item(int) | this parameter [[]] -> return | true | -| System.ComponentModel.Design.DesignerVerbCollection.set_Item(int, DesignerVerb) | parameter 1 -> this parameter [[]] | true | -| System.ComponentModel.EventDescriptorCollection.Add(EventDescriptor) | parameter 0 -> this parameter [[]] | true | -| System.ComponentModel.EventDescriptorCollection.Add(object) | parameter 0 -> this parameter [[]] | true | -| System.ComponentModel.EventDescriptorCollection.CopyTo(Array, int) | this parameter [[]] -> parameter 0 [[]] | true | -| System.ComponentModel.EventDescriptorCollection.Find(string, bool) | this parameter [[]] -> return | true | -| System.ComponentModel.EventDescriptorCollection.GetEnumerator() | this parameter [[]] -> return [Current] | true | -| System.ComponentModel.EventDescriptorCollection.Insert(int, EventDescriptor) | parameter 1 -> this parameter [[]] | true | -| System.ComponentModel.EventDescriptorCollection.Insert(int, object) | parameter 1 -> this parameter [[]] | true | -| System.ComponentModel.EventDescriptorCollection.get_Item(int) | this parameter [[]] -> return | true | -| System.ComponentModel.EventDescriptorCollection.get_Item(string) | this parameter [[]] -> return | true | -| System.ComponentModel.EventDescriptorCollection.set_Item(int, object) | parameter 1 -> this parameter [[]] | true | -| System.ComponentModel.IBindingList.Find(PropertyDescriptor, object) | this parameter [[]] -> return | true | -| System.ComponentModel.ListSortDescriptionCollection.Add(object) | parameter 0 -> this parameter [[]] | true | -| System.ComponentModel.ListSortDescriptionCollection.CopyTo(Array, int) | this parameter [[]] -> parameter 0 [[]] | true | -| System.ComponentModel.ListSortDescriptionCollection.GetEnumerator() | this parameter [[]] -> return [Current] | true | -| System.ComponentModel.ListSortDescriptionCollection.Insert(int, object) | parameter 1 -> this parameter [[]] | true | -| System.ComponentModel.ListSortDescriptionCollection.get_Item(int) | this parameter [[]] -> return | true | -| System.ComponentModel.ListSortDescriptionCollection.set_Item(int, ListSortDescription) | parameter 1 -> this parameter [[]] | true | -| System.ComponentModel.ListSortDescriptionCollection.set_Item(int, object) | parameter 1 -> this parameter [[]] | true | -| System.ComponentModel.PropertyDescriptorCollection.Add(PropertyDescriptor) | parameter 0 -> this parameter [[]] | true | -| System.ComponentModel.PropertyDescriptorCollection.Add(PropertyDescriptor) | parameter 0 [Key] -> this parameter [[], Key] | true | -| System.ComponentModel.PropertyDescriptorCollection.Add(PropertyDescriptor) | parameter 0 [Value] -> this parameter [[], Value] | true | -| System.ComponentModel.PropertyDescriptorCollection.Add(object) | parameter 0 -> this parameter [[]] | true | -| System.ComponentModel.PropertyDescriptorCollection.Add(object) | parameter 0 [Key] -> this parameter [[], Key] | true | -| System.ComponentModel.PropertyDescriptorCollection.Add(object) | parameter 0 [Value] -> this parameter [[], Value] | true | -| System.ComponentModel.PropertyDescriptorCollection.Add(object, object) | parameter 0 -> this parameter [[], Key] | true | -| System.ComponentModel.PropertyDescriptorCollection.Add(object, object) | parameter 1 -> this parameter [[], Value] | true | -| System.ComponentModel.PropertyDescriptorCollection.CopyTo(Array, int) | this parameter [[]] -> parameter 0 [[]] | true | -| System.ComponentModel.PropertyDescriptorCollection.Find(string, bool) | this parameter [[]] -> return | true | -| System.ComponentModel.PropertyDescriptorCollection.GetEnumerator() | this parameter [[]] -> return [Current] | true | -| System.ComponentModel.PropertyDescriptorCollection.Insert(int, PropertyDescriptor) | parameter 1 -> this parameter [[]] | true | -| System.ComponentModel.PropertyDescriptorCollection.Insert(int, object) | parameter 1 -> this parameter [[]] | true | -| System.ComponentModel.PropertyDescriptorCollection.PropertyDescriptorCollection(PropertyDescriptor[]) | parameter 0 [[], Key] -> return [[], Key] | true | -| System.ComponentModel.PropertyDescriptorCollection.PropertyDescriptorCollection(PropertyDescriptor[]) | parameter 0 [[], Value] -> return [[], Value] | true | -| System.ComponentModel.PropertyDescriptorCollection.PropertyDescriptorCollection(PropertyDescriptor[], bool) | parameter 0 [[], Key] -> return [[], Key] | true | -| System.ComponentModel.PropertyDescriptorCollection.PropertyDescriptorCollection(PropertyDescriptor[], bool) | parameter 0 [[], Value] -> return [[], Value] | true | -| System.ComponentModel.PropertyDescriptorCollection.get_Item(int) | this parameter [[], Value] -> return | true | -| System.ComponentModel.PropertyDescriptorCollection.get_Item(int) | this parameter [[]] -> return | true | -| System.ComponentModel.PropertyDescriptorCollection.get_Item(object) | this parameter [[], Value] -> return | true | -| System.ComponentModel.PropertyDescriptorCollection.get_Item(object) | this parameter [[]] -> return | true | -| System.ComponentModel.PropertyDescriptorCollection.get_Item(string) | this parameter [[], Value] -> return | true | -| System.ComponentModel.PropertyDescriptorCollection.get_Item(string) | this parameter [[]] -> return | true | -| System.ComponentModel.PropertyDescriptorCollection.get_Keys() | this parameter [[], Key] -> return [[]] | true | -| System.ComponentModel.PropertyDescriptorCollection.get_Values() | this parameter [[], Value] -> return [[]] | true | -| System.ComponentModel.PropertyDescriptorCollection.set_Item(int, object) | parameter 0 -> this parameter [[], Key] | true | -| System.ComponentModel.PropertyDescriptorCollection.set_Item(int, object) | parameter 1 -> this parameter [[], Value] | true | -| System.ComponentModel.PropertyDescriptorCollection.set_Item(int, object) | parameter 1 -> this parameter [[]] | true | -| System.ComponentModel.PropertyDescriptorCollection.set_Item(object, object) | parameter 0 -> this parameter [[], Key] | true | -| System.ComponentModel.PropertyDescriptorCollection.set_Item(object, object) | parameter 1 -> this parameter [[], Value] | true | -| System.ComponentModel.PropertyDescriptorCollection.set_Item(object, object) | parameter 1 -> this parameter [[]] | true | -| System.ComponentModel.TypeConverter.StandardValuesCollection.CopyTo(Array, int) | this parameter [[]] -> parameter 0 [[]] | true | -| System.ComponentModel.TypeConverter.StandardValuesCollection.GetEnumerator() | this parameter [[]] -> return [Current] | true | -| System.ConsolePal.UnixConsoleStream.Read(Byte[], int, int) | this parameter -> parameter 0 | false | -| System.ConsolePal.UnixConsoleStream.Write(Byte[], int, int) | parameter 0 -> this parameter | false | -| System.Convert.ChangeType(object, Type) | parameter 0 -> return | false | -| System.Convert.ChangeType(object, Type, IFormatProvider) | parameter 0 -> return | false | -| System.Convert.ChangeType(object, TypeCode) | parameter 0 -> return | false | -| System.Convert.ChangeType(object, TypeCode, IFormatProvider) | parameter 0 -> return | false | -| System.Convert.FromBase64CharArray(Char[], int, int) | parameter 0 -> return | false | -| System.Convert.FromBase64String(string) | parameter 0 -> return | false | -| System.Convert.FromHexString(ReadOnlySpan) | parameter 0 -> return | false | -| System.Convert.FromHexString(string) | parameter 0 -> return | false | -| System.Convert.GetTypeCode(object) | parameter 0 -> return | false | -| System.Convert.IsDBNull(object) | parameter 0 -> return | false | -| System.Convert.ToBase64CharArray(Byte[], int, int, Char[], int) | parameter 0 -> return | false | -| System.Convert.ToBase64CharArray(Byte[], int, int, Char[], int, Base64FormattingOptions) | parameter 0 -> return | false | -| System.Convert.ToBase64String(Byte[]) | parameter 0 -> return | false | -| System.Convert.ToBase64String(Byte[], Base64FormattingOptions) | parameter 0 -> return | false | -| System.Convert.ToBase64String(Byte[], int, int) | parameter 0 -> return | false | -| System.Convert.ToBase64String(Byte[], int, int, Base64FormattingOptions) | parameter 0 -> return | false | -| System.Convert.ToBase64String(ReadOnlySpan, Base64FormattingOptions) | parameter 0 -> return | false | -| System.Convert.ToBoolean(DateTime) | parameter 0 -> return | false | -| System.Convert.ToBoolean(bool) | parameter 0 -> return | false | -| System.Convert.ToBoolean(byte) | parameter 0 -> return | false | -| System.Convert.ToBoolean(char) | parameter 0 -> return | false | -| System.Convert.ToBoolean(decimal) | parameter 0 -> return | false | -| System.Convert.ToBoolean(double) | parameter 0 -> return | false | -| System.Convert.ToBoolean(float) | parameter 0 -> return | false | -| System.Convert.ToBoolean(int) | parameter 0 -> return | false | -| System.Convert.ToBoolean(long) | parameter 0 -> return | false | -| System.Convert.ToBoolean(object) | parameter 0 -> return | false | -| System.Convert.ToBoolean(object, IFormatProvider) | parameter 0 -> return | false | -| System.Convert.ToBoolean(sbyte) | parameter 0 -> return | false | -| System.Convert.ToBoolean(short) | parameter 0 -> return | false | -| System.Convert.ToBoolean(string) | parameter 0 -> return | false | -| System.Convert.ToBoolean(string, IFormatProvider) | parameter 0 -> return | false | -| System.Convert.ToBoolean(uint) | parameter 0 -> return | false | -| System.Convert.ToBoolean(ulong) | parameter 0 -> return | false | -| System.Convert.ToBoolean(ushort) | parameter 0 -> return | false | -| System.Convert.ToByte(DateTime) | parameter 0 -> return | false | -| System.Convert.ToByte(bool) | parameter 0 -> return | false | -| System.Convert.ToByte(byte) | parameter 0 -> return | false | -| System.Convert.ToByte(char) | parameter 0 -> return | false | -| System.Convert.ToByte(decimal) | parameter 0 -> return | false | -| System.Convert.ToByte(double) | parameter 0 -> return | false | -| System.Convert.ToByte(float) | parameter 0 -> return | false | -| System.Convert.ToByte(int) | parameter 0 -> return | false | -| System.Convert.ToByte(long) | parameter 0 -> return | false | -| System.Convert.ToByte(object) | parameter 0 -> return | false | -| System.Convert.ToByte(object, IFormatProvider) | parameter 0 -> return | false | -| System.Convert.ToByte(sbyte) | parameter 0 -> return | false | -| System.Convert.ToByte(short) | parameter 0 -> return | false | -| System.Convert.ToByte(string) | parameter 0 -> return | false | -| System.Convert.ToByte(string, IFormatProvider) | parameter 0 -> return | false | -| System.Convert.ToByte(string, int) | parameter 0 -> return | false | -| System.Convert.ToByte(uint) | parameter 0 -> return | false | -| System.Convert.ToByte(ulong) | parameter 0 -> return | false | -| System.Convert.ToByte(ushort) | parameter 0 -> return | false | -| System.Convert.ToChar(DateTime) | parameter 0 -> return | false | -| System.Convert.ToChar(bool) | parameter 0 -> return | false | -| System.Convert.ToChar(byte) | parameter 0 -> return | false | -| System.Convert.ToChar(char) | parameter 0 -> return | false | -| System.Convert.ToChar(decimal) | parameter 0 -> return | false | -| System.Convert.ToChar(double) | parameter 0 -> return | false | -| System.Convert.ToChar(float) | parameter 0 -> return | false | -| System.Convert.ToChar(int) | parameter 0 -> return | false | -| System.Convert.ToChar(long) | parameter 0 -> return | false | -| System.Convert.ToChar(object) | parameter 0 -> return | false | -| System.Convert.ToChar(object, IFormatProvider) | parameter 0 -> return | false | -| System.Convert.ToChar(sbyte) | parameter 0 -> return | false | -| System.Convert.ToChar(short) | parameter 0 -> return | false | -| System.Convert.ToChar(string) | parameter 0 -> return | false | -| System.Convert.ToChar(string, IFormatProvider) | parameter 0 -> return | false | -| System.Convert.ToChar(uint) | parameter 0 -> return | false | -| System.Convert.ToChar(ulong) | parameter 0 -> return | false | -| System.Convert.ToChar(ushort) | parameter 0 -> return | false | -| System.Convert.ToDateTime(DateTime) | parameter 0 -> return | false | -| System.Convert.ToDateTime(bool) | parameter 0 -> return | false | -| System.Convert.ToDateTime(byte) | parameter 0 -> return | false | -| System.Convert.ToDateTime(char) | parameter 0 -> return | false | -| System.Convert.ToDateTime(decimal) | parameter 0 -> return | false | -| System.Convert.ToDateTime(double) | parameter 0 -> return | false | -| System.Convert.ToDateTime(float) | parameter 0 -> return | false | -| System.Convert.ToDateTime(int) | parameter 0 -> return | false | -| System.Convert.ToDateTime(long) | parameter 0 -> return | false | -| System.Convert.ToDateTime(object) | parameter 0 -> return | false | -| System.Convert.ToDateTime(object, IFormatProvider) | parameter 0 -> return | false | -| System.Convert.ToDateTime(sbyte) | parameter 0 -> return | false | -| System.Convert.ToDateTime(short) | parameter 0 -> return | false | -| System.Convert.ToDateTime(string) | parameter 0 -> return | false | -| System.Convert.ToDateTime(string, IFormatProvider) | parameter 0 -> return | false | -| System.Convert.ToDateTime(uint) | parameter 0 -> return | false | -| System.Convert.ToDateTime(ulong) | parameter 0 -> return | false | -| System.Convert.ToDateTime(ushort) | parameter 0 -> return | false | -| System.Convert.ToDecimal(DateTime) | parameter 0 -> return | false | -| System.Convert.ToDecimal(bool) | parameter 0 -> return | false | -| System.Convert.ToDecimal(byte) | parameter 0 -> return | false | -| System.Convert.ToDecimal(char) | parameter 0 -> return | false | -| System.Convert.ToDecimal(decimal) | parameter 0 -> return | false | -| System.Convert.ToDecimal(double) | parameter 0 -> return | false | -| System.Convert.ToDecimal(float) | parameter 0 -> return | false | -| System.Convert.ToDecimal(int) | parameter 0 -> return | false | -| System.Convert.ToDecimal(long) | parameter 0 -> return | false | -| System.Convert.ToDecimal(object) | parameter 0 -> return | false | -| System.Convert.ToDecimal(object, IFormatProvider) | parameter 0 -> return | false | -| System.Convert.ToDecimal(sbyte) | parameter 0 -> return | false | -| System.Convert.ToDecimal(short) | parameter 0 -> return | false | -| System.Convert.ToDecimal(string) | parameter 0 -> return | false | -| System.Convert.ToDecimal(string, IFormatProvider) | parameter 0 -> return | false | -| System.Convert.ToDecimal(uint) | parameter 0 -> return | false | -| System.Convert.ToDecimal(ulong) | parameter 0 -> return | false | -| System.Convert.ToDecimal(ushort) | parameter 0 -> return | false | -| System.Convert.ToDouble(DateTime) | parameter 0 -> return | false | -| System.Convert.ToDouble(bool) | parameter 0 -> return | false | -| System.Convert.ToDouble(byte) | parameter 0 -> return | false | -| System.Convert.ToDouble(char) | parameter 0 -> return | false | -| System.Convert.ToDouble(decimal) | parameter 0 -> return | false | -| System.Convert.ToDouble(double) | parameter 0 -> return | false | -| System.Convert.ToDouble(float) | parameter 0 -> return | false | -| System.Convert.ToDouble(int) | parameter 0 -> return | false | -| System.Convert.ToDouble(long) | parameter 0 -> return | false | -| System.Convert.ToDouble(object) | parameter 0 -> return | false | -| System.Convert.ToDouble(object, IFormatProvider) | parameter 0 -> return | false | -| System.Convert.ToDouble(sbyte) | parameter 0 -> return | false | -| System.Convert.ToDouble(short) | parameter 0 -> return | false | -| System.Convert.ToDouble(string) | parameter 0 -> return | false | -| System.Convert.ToDouble(string, IFormatProvider) | parameter 0 -> return | false | -| System.Convert.ToDouble(uint) | parameter 0 -> return | false | -| System.Convert.ToDouble(ulong) | parameter 0 -> return | false | -| System.Convert.ToDouble(ushort) | parameter 0 -> return | false | -| System.Convert.ToHexString(Byte[]) | parameter 0 -> return | false | -| System.Convert.ToHexString(Byte[], int, int) | parameter 0 -> return | false | -| System.Convert.ToHexString(ReadOnlySpan) | parameter 0 -> return | false | -| System.Convert.ToInt16(DateTime) | parameter 0 -> return | false | -| System.Convert.ToInt16(bool) | parameter 0 -> return | false | -| System.Convert.ToInt16(byte) | parameter 0 -> return | false | -| System.Convert.ToInt16(char) | parameter 0 -> return | false | -| System.Convert.ToInt16(decimal) | parameter 0 -> return | false | -| System.Convert.ToInt16(double) | parameter 0 -> return | false | -| System.Convert.ToInt16(float) | parameter 0 -> return | false | -| System.Convert.ToInt16(int) | parameter 0 -> return | false | -| System.Convert.ToInt16(long) | parameter 0 -> return | false | -| System.Convert.ToInt16(object) | parameter 0 -> return | false | -| System.Convert.ToInt16(object, IFormatProvider) | parameter 0 -> return | false | -| System.Convert.ToInt16(sbyte) | parameter 0 -> return | false | -| System.Convert.ToInt16(short) | parameter 0 -> return | false | -| System.Convert.ToInt16(string) | parameter 0 -> return | false | -| System.Convert.ToInt16(string, IFormatProvider) | parameter 0 -> return | false | -| System.Convert.ToInt16(string, int) | parameter 0 -> return | false | -| System.Convert.ToInt16(uint) | parameter 0 -> return | false | -| System.Convert.ToInt16(ulong) | parameter 0 -> return | false | -| System.Convert.ToInt16(ushort) | parameter 0 -> return | false | -| System.Convert.ToInt32(DateTime) | parameter 0 -> return | false | -| System.Convert.ToInt32(bool) | parameter 0 -> return | false | -| System.Convert.ToInt32(byte) | parameter 0 -> return | false | -| System.Convert.ToInt32(char) | parameter 0 -> return | false | -| System.Convert.ToInt32(decimal) | parameter 0 -> return | false | -| System.Convert.ToInt32(double) | parameter 0 -> return | false | -| System.Convert.ToInt32(float) | parameter 0 -> return | false | -| System.Convert.ToInt32(int) | parameter 0 -> return | false | -| System.Convert.ToInt32(long) | parameter 0 -> return | false | -| System.Convert.ToInt32(object) | parameter 0 -> return | false | -| System.Convert.ToInt32(object, IFormatProvider) | parameter 0 -> return | false | -| System.Convert.ToInt32(sbyte) | parameter 0 -> return | false | -| System.Convert.ToInt32(short) | parameter 0 -> return | false | -| System.Convert.ToInt32(string) | parameter 0 -> return | false | -| System.Convert.ToInt32(string, IFormatProvider) | parameter 0 -> return | false | -| System.Convert.ToInt32(string, int) | parameter 0 -> return | false | -| System.Convert.ToInt32(uint) | parameter 0 -> return | false | -| System.Convert.ToInt32(ulong) | parameter 0 -> return | false | -| System.Convert.ToInt32(ushort) | parameter 0 -> return | false | -| System.Convert.ToInt64(DateTime) | parameter 0 -> return | false | -| System.Convert.ToInt64(bool) | parameter 0 -> return | false | -| System.Convert.ToInt64(byte) | parameter 0 -> return | false | -| System.Convert.ToInt64(char) | parameter 0 -> return | false | -| System.Convert.ToInt64(decimal) | parameter 0 -> return | false | -| System.Convert.ToInt64(double) | parameter 0 -> return | false | -| System.Convert.ToInt64(float) | parameter 0 -> return | false | -| System.Convert.ToInt64(int) | parameter 0 -> return | false | -| System.Convert.ToInt64(long) | parameter 0 -> return | false | -| System.Convert.ToInt64(object) | parameter 0 -> return | false | -| System.Convert.ToInt64(object, IFormatProvider) | parameter 0 -> return | false | -| System.Convert.ToInt64(sbyte) | parameter 0 -> return | false | -| System.Convert.ToInt64(short) | parameter 0 -> return | false | -| System.Convert.ToInt64(string) | parameter 0 -> return | false | -| System.Convert.ToInt64(string, IFormatProvider) | parameter 0 -> return | false | -| System.Convert.ToInt64(string, int) | parameter 0 -> return | false | -| System.Convert.ToInt64(uint) | parameter 0 -> return | false | -| System.Convert.ToInt64(ulong) | parameter 0 -> return | false | -| System.Convert.ToInt64(ushort) | parameter 0 -> return | false | -| System.Convert.ToSByte(DateTime) | parameter 0 -> return | false | -| System.Convert.ToSByte(bool) | parameter 0 -> return | false | -| System.Convert.ToSByte(byte) | parameter 0 -> return | false | -| System.Convert.ToSByte(char) | parameter 0 -> return | false | -| System.Convert.ToSByte(decimal) | parameter 0 -> return | false | -| System.Convert.ToSByte(double) | parameter 0 -> return | false | -| System.Convert.ToSByte(float) | parameter 0 -> return | false | -| System.Convert.ToSByte(int) | parameter 0 -> return | false | -| System.Convert.ToSByte(long) | parameter 0 -> return | false | -| System.Convert.ToSByte(object) | parameter 0 -> return | false | -| System.Convert.ToSByte(object, IFormatProvider) | parameter 0 -> return | false | -| System.Convert.ToSByte(sbyte) | parameter 0 -> return | false | -| System.Convert.ToSByte(short) | parameter 0 -> return | false | -| System.Convert.ToSByte(string) | parameter 0 -> return | false | -| System.Convert.ToSByte(string, IFormatProvider) | parameter 0 -> return | false | -| System.Convert.ToSByte(string, int) | parameter 0 -> return | false | -| System.Convert.ToSByte(uint) | parameter 0 -> return | false | -| System.Convert.ToSByte(ulong) | parameter 0 -> return | false | -| System.Convert.ToSByte(ushort) | parameter 0 -> return | false | -| System.Convert.ToSingle(DateTime) | parameter 0 -> return | false | -| System.Convert.ToSingle(bool) | parameter 0 -> return | false | -| System.Convert.ToSingle(byte) | parameter 0 -> return | false | -| System.Convert.ToSingle(char) | parameter 0 -> return | false | -| System.Convert.ToSingle(decimal) | parameter 0 -> return | false | -| System.Convert.ToSingle(double) | parameter 0 -> return | false | -| System.Convert.ToSingle(float) | parameter 0 -> return | false | -| System.Convert.ToSingle(int) | parameter 0 -> return | false | -| System.Convert.ToSingle(long) | parameter 0 -> return | false | -| System.Convert.ToSingle(object) | parameter 0 -> return | false | -| System.Convert.ToSingle(object, IFormatProvider) | parameter 0 -> return | false | -| System.Convert.ToSingle(sbyte) | parameter 0 -> return | false | -| System.Convert.ToSingle(short) | parameter 0 -> return | false | -| System.Convert.ToSingle(string) | parameter 0 -> return | false | -| System.Convert.ToSingle(string, IFormatProvider) | parameter 0 -> return | false | -| System.Convert.ToSingle(uint) | parameter 0 -> return | false | -| System.Convert.ToSingle(ulong) | parameter 0 -> return | false | -| System.Convert.ToSingle(ushort) | parameter 0 -> return | false | -| System.Convert.ToString(DateTime) | parameter 0 -> return | false | -| System.Convert.ToString(DateTime, IFormatProvider) | parameter 0 -> return | false | -| System.Convert.ToString(bool) | parameter 0 -> return | false | -| System.Convert.ToString(bool, IFormatProvider) | parameter 0 -> return | false | -| System.Convert.ToString(byte) | parameter 0 -> return | false | -| System.Convert.ToString(byte, IFormatProvider) | parameter 0 -> return | false | -| System.Convert.ToString(byte, int) | parameter 0 -> return | false | -| System.Convert.ToString(char) | parameter 0 -> return | false | -| System.Convert.ToString(char, IFormatProvider) | parameter 0 -> return | false | -| System.Convert.ToString(decimal) | parameter 0 -> return | false | -| System.Convert.ToString(decimal, IFormatProvider) | parameter 0 -> return | false | -| System.Convert.ToString(double) | parameter 0 -> return | false | -| System.Convert.ToString(double, IFormatProvider) | parameter 0 -> return | false | -| System.Convert.ToString(float) | parameter 0 -> return | false | -| System.Convert.ToString(float, IFormatProvider) | parameter 0 -> return | false | -| System.Convert.ToString(int) | parameter 0 -> return | false | -| System.Convert.ToString(int, IFormatProvider) | parameter 0 -> return | false | -| System.Convert.ToString(int, int) | parameter 0 -> return | false | -| System.Convert.ToString(long) | parameter 0 -> return | false | -| System.Convert.ToString(long, IFormatProvider) | parameter 0 -> return | false | -| System.Convert.ToString(long, int) | parameter 0 -> return | false | -| System.Convert.ToString(object) | parameter 0 -> return | false | -| System.Convert.ToString(object, IFormatProvider) | parameter 0 -> return | false | -| System.Convert.ToString(sbyte) | parameter 0 -> return | false | -| System.Convert.ToString(sbyte, IFormatProvider) | parameter 0 -> return | false | -| System.Convert.ToString(short) | parameter 0 -> return | false | -| System.Convert.ToString(short, IFormatProvider) | parameter 0 -> return | false | -| System.Convert.ToString(short, int) | parameter 0 -> return | false | -| System.Convert.ToString(string) | parameter 0 -> return | false | -| System.Convert.ToString(string, IFormatProvider) | parameter 0 -> return | false | -| System.Convert.ToString(uint) | parameter 0 -> return | false | -| System.Convert.ToString(uint, IFormatProvider) | parameter 0 -> return | false | -| System.Convert.ToString(ulong) | parameter 0 -> return | false | -| System.Convert.ToString(ulong, IFormatProvider) | parameter 0 -> return | false | -| System.Convert.ToString(ushort) | parameter 0 -> return | false | -| System.Convert.ToString(ushort, IFormatProvider) | parameter 0 -> return | false | -| System.Convert.ToUInt16(DateTime) | parameter 0 -> return | false | -| System.Convert.ToUInt16(bool) | parameter 0 -> return | false | -| System.Convert.ToUInt16(byte) | parameter 0 -> return | false | -| System.Convert.ToUInt16(char) | parameter 0 -> return | false | -| System.Convert.ToUInt16(decimal) | parameter 0 -> return | false | -| System.Convert.ToUInt16(double) | parameter 0 -> return | false | -| System.Convert.ToUInt16(float) | parameter 0 -> return | false | -| System.Convert.ToUInt16(int) | parameter 0 -> return | false | -| System.Convert.ToUInt16(long) | parameter 0 -> return | false | -| System.Convert.ToUInt16(object) | parameter 0 -> return | false | -| System.Convert.ToUInt16(object, IFormatProvider) | parameter 0 -> return | false | -| System.Convert.ToUInt16(sbyte) | parameter 0 -> return | false | -| System.Convert.ToUInt16(short) | parameter 0 -> return | false | -| System.Convert.ToUInt16(string) | parameter 0 -> return | false | -| System.Convert.ToUInt16(string, IFormatProvider) | parameter 0 -> return | false | -| System.Convert.ToUInt16(string, int) | parameter 0 -> return | false | -| System.Convert.ToUInt16(uint) | parameter 0 -> return | false | -| System.Convert.ToUInt16(ulong) | parameter 0 -> return | false | -| System.Convert.ToUInt16(ushort) | parameter 0 -> return | false | -| System.Convert.ToUInt32(DateTime) | parameter 0 -> return | false | -| System.Convert.ToUInt32(bool) | parameter 0 -> return | false | -| System.Convert.ToUInt32(byte) | parameter 0 -> return | false | -| System.Convert.ToUInt32(char) | parameter 0 -> return | false | -| System.Convert.ToUInt32(decimal) | parameter 0 -> return | false | -| System.Convert.ToUInt32(double) | parameter 0 -> return | false | -| System.Convert.ToUInt32(float) | parameter 0 -> return | false | -| System.Convert.ToUInt32(int) | parameter 0 -> return | false | -| System.Convert.ToUInt32(long) | parameter 0 -> return | false | -| System.Convert.ToUInt32(object) | parameter 0 -> return | false | -| System.Convert.ToUInt32(object, IFormatProvider) | parameter 0 -> return | false | -| System.Convert.ToUInt32(sbyte) | parameter 0 -> return | false | -| System.Convert.ToUInt32(short) | parameter 0 -> return | false | -| System.Convert.ToUInt32(string) | parameter 0 -> return | false | -| System.Convert.ToUInt32(string, IFormatProvider) | parameter 0 -> return | false | -| System.Convert.ToUInt32(string, int) | parameter 0 -> return | false | -| System.Convert.ToUInt32(uint) | parameter 0 -> return | false | -| System.Convert.ToUInt32(ulong) | parameter 0 -> return | false | -| System.Convert.ToUInt32(ushort) | parameter 0 -> return | false | -| System.Convert.ToUInt64(DateTime) | parameter 0 -> return | false | -| System.Convert.ToUInt64(bool) | parameter 0 -> return | false | -| System.Convert.ToUInt64(byte) | parameter 0 -> return | false | -| System.Convert.ToUInt64(char) | parameter 0 -> return | false | -| System.Convert.ToUInt64(decimal) | parameter 0 -> return | false | -| System.Convert.ToUInt64(double) | parameter 0 -> return | false | -| System.Convert.ToUInt64(float) | parameter 0 -> return | false | -| System.Convert.ToUInt64(int) | parameter 0 -> return | false | -| System.Convert.ToUInt64(long) | parameter 0 -> return | false | -| System.Convert.ToUInt64(object) | parameter 0 -> return | false | -| System.Convert.ToUInt64(object, IFormatProvider) | parameter 0 -> return | false | -| System.Convert.ToUInt64(sbyte) | parameter 0 -> return | false | -| System.Convert.ToUInt64(short) | parameter 0 -> return | false | -| System.Convert.ToUInt64(string) | parameter 0 -> return | false | -| System.Convert.ToUInt64(string, IFormatProvider) | parameter 0 -> return | false | -| System.Convert.ToUInt64(string, int) | parameter 0 -> return | false | -| System.Convert.ToUInt64(uint) | parameter 0 -> return | false | -| System.Convert.ToUInt64(ulong) | parameter 0 -> return | false | -| System.Convert.ToUInt64(ushort) | parameter 0 -> return | false | -| System.Convert.TryFromBase64Chars(ReadOnlySpan, Span, out int) | parameter 0 -> return | false | -| System.Convert.TryFromBase64String(string, Span, out int) | parameter 0 -> return | false | -| System.Convert.TryToBase64Chars(ReadOnlySpan, Span, out int, Base64FormattingOptions) | parameter 0 -> return | false | -| System.Diagnostics.Tracing.CounterPayload.d__51.GetEnumerator() | this parameter [[]] -> return [Current] | true | -| System.Diagnostics.Tracing.CounterPayload.GetEnumerator() | this parameter [[]] -> return [Current] | true | -| System.Diagnostics.Tracing.EventPayload.Add(KeyValuePair) | parameter 0 -> this parameter [[]] | true | -| System.Diagnostics.Tracing.EventPayload.Add(KeyValuePair) | parameter 0 [Key] -> this parameter [[], Key] | true | -| System.Diagnostics.Tracing.EventPayload.Add(KeyValuePair) | parameter 0 [Value] -> this parameter [[], Value] | true | -| System.Diagnostics.Tracing.EventPayload.Add(string, object) | parameter 0 -> this parameter [[], Key] | true | -| System.Diagnostics.Tracing.EventPayload.Add(string, object) | parameter 1 -> this parameter [[], Value] | true | -| System.Diagnostics.Tracing.EventPayload.CopyTo(KeyValuePair[], int) | this parameter [[]] -> parameter 0 [[]] | true | -| System.Diagnostics.Tracing.EventPayload.GetEnumerator() | this parameter [[]] -> return [Current] | true | -| System.Diagnostics.Tracing.EventPayload.get_Item(string) | this parameter [[], Value] -> return | true | -| System.Diagnostics.Tracing.EventPayload.get_Keys() | this parameter [[], Key] -> return [[]] | true | -| System.Diagnostics.Tracing.EventPayload.get_Values() | this parameter [[], Value] -> return [[]] | true | -| System.Diagnostics.Tracing.EventPayload.set_Item(string, object) | parameter 0 -> this parameter [[], Key] | true | -| System.Diagnostics.Tracing.EventPayload.set_Item(string, object) | parameter 1 -> this parameter [[], Value] | true | -| System.Diagnostics.Tracing.IncrementingCounterPayload.d__39.GetEnumerator() | this parameter [[]] -> return [Current] | true | -| System.Diagnostics.Tracing.IncrementingCounterPayload.GetEnumerator() | this parameter [[]] -> return [Current] | true | -| System.Dynamic.ExpandoObject.Add(KeyValuePair) | parameter 0 -> this parameter [[]] | true | -| System.Dynamic.ExpandoObject.Add(KeyValuePair) | parameter 0 [Key] -> this parameter [[], Key] | true | -| System.Dynamic.ExpandoObject.Add(KeyValuePair) | parameter 0 [Value] -> this parameter [[], Value] | true | -| System.Dynamic.ExpandoObject.Add(string, object) | parameter 0 -> this parameter [[], Key] | true | -| System.Dynamic.ExpandoObject.Add(string, object) | parameter 1 -> this parameter [[], Value] | true | -| System.Dynamic.ExpandoObject.CopyTo(KeyValuePair[], int) | this parameter [[]] -> parameter 0 [[]] | true | -| System.Dynamic.ExpandoObject.GetEnumerator() | this parameter [[]] -> return [Current] | true | -| System.Dynamic.ExpandoObject.KeyCollection.Add(string) | parameter 0 -> this parameter [[]] | true | -| System.Dynamic.ExpandoObject.KeyCollection.CopyTo(String[], int) | this parameter [[]] -> parameter 0 [[]] | true | -| System.Dynamic.ExpandoObject.KeyCollection.GetEnumerator() | this parameter [[]] -> return [Current] | true | -| System.Dynamic.ExpandoObject.MetaExpando.d__6.GetEnumerator() | this parameter [[]] -> return [Current] | true | -| System.Dynamic.ExpandoObject.ValueCollection.Add(object) | parameter 0 -> this parameter [[]] | true | -| System.Dynamic.ExpandoObject.ValueCollection.CopyTo(Object[], int) | this parameter [[]] -> parameter 0 [[]] | true | -| System.Dynamic.ExpandoObject.ValueCollection.GetEnumerator() | this parameter [[]] -> return [Current] | true | -| System.Dynamic.ExpandoObject.get_Item(string) | this parameter [[], Value] -> return | true | -| System.Dynamic.ExpandoObject.get_Keys() | this parameter [[], Key] -> return [[]] | true | -| System.Dynamic.ExpandoObject.get_Values() | this parameter [[], Value] -> return [[]] | true | -| System.Dynamic.ExpandoObject.set_Item(string, object) | parameter 0 -> this parameter [[], Key] | true | -| System.Dynamic.ExpandoObject.set_Item(string, object) | parameter 1 -> this parameter [[], Value] | true | -| System.Dynamic.Utils.ListProvider<>.Add(T) | parameter 0 -> this parameter [[]] | true | -| System.Dynamic.Utils.ListProvider<>.CopyTo(T[], int) | this parameter [[]] -> parameter 0 [[]] | true | -| System.Dynamic.Utils.ListProvider<>.GetEnumerator() | this parameter [[]] -> return [Current] | true | -| System.Dynamic.Utils.ListProvider<>.Insert(int, T) | parameter 1 -> this parameter [[]] | true | -| System.Dynamic.Utils.ListProvider<>.get_Item(int) | this parameter [[]] -> return | true | -| System.Dynamic.Utils.ListProvider<>.set_Item(int, T) | parameter 1 -> this parameter [[]] | true | -| System.IO.BufferedStream.BeginRead(Byte[], int, int, AsyncCallback, object) | this parameter -> parameter 0 | false | -| System.IO.BufferedStream.BeginWrite(Byte[], int, int, AsyncCallback, object) | parameter 0 -> this parameter | false | -| System.IO.BufferedStream.CopyTo(Stream, int) | this parameter -> parameter 0 | false | -| System.IO.BufferedStream.CopyToAsync(Stream, int, CancellationToken) | this parameter -> parameter 0 | false | -| System.IO.BufferedStream.Read(Byte[], int, int) | this parameter -> parameter 0 | false | -| System.IO.BufferedStream.ReadAsync(Byte[], int, int, CancellationToken) | this parameter -> parameter 0 | false | -| System.IO.BufferedStream.Write(Byte[], int, int) | parameter 0 -> this parameter | false | -| System.IO.BufferedStream.WriteAsync(Byte[], int, int, CancellationToken) | parameter 0 -> this parameter | false | -| System.IO.Compression.CheckSumAndSizeWriteStream.Read(Byte[], int, int) | this parameter -> parameter 0 | false | -| System.IO.Compression.CheckSumAndSizeWriteStream.Write(Byte[], int, int) | parameter 0 -> this parameter | false | -| System.IO.Compression.DeflateManagedStream.BeginRead(Byte[], int, int, AsyncCallback, object) | this parameter -> parameter 0 | false | -| System.IO.Compression.DeflateManagedStream.Read(Byte[], int, int) | this parameter -> parameter 0 | false | -| System.IO.Compression.DeflateManagedStream.ReadAsync(Byte[], int, int, CancellationToken) | this parameter -> parameter 0 | false | -| System.IO.Compression.DeflateManagedStream.Write(Byte[], int, int) | parameter 0 -> this parameter | false | -| System.IO.Compression.DeflateStream.BeginRead(Byte[], int, int, AsyncCallback, object) | this parameter -> parameter 0 | false | -| System.IO.Compression.DeflateStream.BeginWrite(Byte[], int, int, AsyncCallback, object) | parameter 0 -> this parameter | false | -| System.IO.Compression.DeflateStream.CopyTo(Stream, int) | this parameter -> parameter 0 | false | -| System.IO.Compression.DeflateStream.CopyToAsync(Stream, int, CancellationToken) | this parameter -> parameter 0 | false | -| System.IO.Compression.DeflateStream.CopyToStream.Read(Byte[], int, int) | this parameter -> parameter 0 | false | -| System.IO.Compression.DeflateStream.CopyToStream.Write(Byte[], int, int) | parameter 0 -> this parameter | false | -| System.IO.Compression.DeflateStream.CopyToStream.WriteAsync(Byte[], int, int, CancellationToken) | parameter 0 -> this parameter | false | -| System.IO.Compression.DeflateStream.DeflateStream(Stream, CompressionLevel) | parameter 0 -> return | false | -| System.IO.Compression.DeflateStream.DeflateStream(Stream, CompressionLevel, bool) | parameter 0 -> return | false | -| System.IO.Compression.DeflateStream.DeflateStream(Stream, CompressionMode) | parameter 0 -> return | false | -| System.IO.Compression.DeflateStream.DeflateStream(Stream, CompressionMode, bool) | parameter 0 -> return | false | -| System.IO.Compression.DeflateStream.Read(Byte[], int, int) | this parameter -> parameter 0 | false | -| System.IO.Compression.DeflateStream.ReadAsync(Byte[], int, int, CancellationToken) | this parameter -> parameter 0 | false | -| System.IO.Compression.DeflateStream.Write(Byte[], int, int) | parameter 0 -> this parameter | false | -| System.IO.Compression.DeflateStream.WriteAsync(Byte[], int, int, CancellationToken) | parameter 0 -> this parameter | false | -| System.IO.Compression.GZipStream.BeginRead(Byte[], int, int, AsyncCallback, object) | this parameter -> parameter 0 | false | -| System.IO.Compression.GZipStream.BeginWrite(Byte[], int, int, AsyncCallback, object) | parameter 0 -> this parameter | false | -| System.IO.Compression.GZipStream.CopyTo(Stream, int) | this parameter -> parameter 0 | false | -| System.IO.Compression.GZipStream.CopyToAsync(Stream, int, CancellationToken) | this parameter -> parameter 0 | false | -| System.IO.Compression.GZipStream.Read(Byte[], int, int) | this parameter -> parameter 0 | false | -| System.IO.Compression.GZipStream.ReadAsync(Byte[], int, int, CancellationToken) | this parameter -> parameter 0 | false | -| System.IO.Compression.GZipStream.Write(Byte[], int, int) | parameter 0 -> this parameter | false | -| System.IO.Compression.GZipStream.WriteAsync(Byte[], int, int, CancellationToken) | parameter 0 -> this parameter | false | -| System.IO.Compression.PositionPreservingWriteOnlyStreamWrapper.BeginWrite(Byte[], int, int, AsyncCallback, object) | parameter 0 -> this parameter | false | -| System.IO.Compression.PositionPreservingWriteOnlyStreamWrapper.Read(Byte[], int, int) | this parameter -> parameter 0 | false | -| System.IO.Compression.PositionPreservingWriteOnlyStreamWrapper.Write(Byte[], int, int) | parameter 0 -> this parameter | false | -| System.IO.Compression.PositionPreservingWriteOnlyStreamWrapper.WriteAsync(Byte[], int, int, CancellationToken) | parameter 0 -> this parameter | false | -| System.IO.Compression.SubReadStream.Read(Byte[], int, int) | this parameter -> parameter 0 | false | -| System.IO.Compression.SubReadStream.Write(Byte[], int, int) | parameter 0 -> this parameter | false | -| System.IO.Compression.WrappedStream.Read(Byte[], int, int) | this parameter -> parameter 0 | false | -| System.IO.Compression.WrappedStream.Write(Byte[], int, int) | parameter 0 -> this parameter | false | -| System.IO.Compression.ZipArchiveEntry.DirectToArchiveWriterStream.Read(Byte[], int, int) | this parameter -> parameter 0 | false | -| System.IO.Compression.ZipArchiveEntry.DirectToArchiveWriterStream.Write(Byte[], int, int) | parameter 0 -> this parameter | false | -| System.IO.FileStream.BeginRead(Byte[], int, int, AsyncCallback, object) | this parameter -> parameter 0 | false | -| System.IO.FileStream.BeginWrite(Byte[], int, int, AsyncCallback, object) | parameter 0 -> this parameter | false | -| System.IO.FileStream.CopyToAsync(Stream, int, CancellationToken) | this parameter -> parameter 0 | false | -| System.IO.FileStream.Read(Byte[], int, int) | this parameter -> parameter 0 | false | -| System.IO.FileStream.ReadAsync(Byte[], int, int, CancellationToken) | this parameter -> parameter 0 | false | -| System.IO.FileStream.Write(Byte[], int, int) | parameter 0 -> this parameter | false | -| System.IO.FileStream.WriteAsync(Byte[], int, int, CancellationToken) | parameter 0 -> this parameter | false | -| System.IO.MemoryStream.CopyTo(Stream, int) | this parameter -> parameter 0 | false | -| System.IO.MemoryStream.CopyToAsync(Stream, int, CancellationToken) | this parameter -> parameter 0 | false | -| System.IO.MemoryStream.MemoryStream(Byte[]) | parameter 0 -> return | false | -| System.IO.MemoryStream.MemoryStream(Byte[], bool) | parameter 0 -> return | false | -| System.IO.MemoryStream.MemoryStream(Byte[], int, int) | parameter 0 -> return | false | -| System.IO.MemoryStream.MemoryStream(Byte[], int, int, bool) | parameter 0 -> return | false | -| System.IO.MemoryStream.MemoryStream(Byte[], int, int, bool, bool) | parameter 0 -> return | false | -| System.IO.MemoryStream.Read(Byte[], int, int) | this parameter -> parameter 0 | false | -| System.IO.MemoryStream.ReadAsync(Byte[], int, int, CancellationToken) | this parameter -> parameter 0 | false | -| System.IO.MemoryStream.ToArray() | this parameter -> return | false | -| System.IO.MemoryStream.Write(Byte[], int, int) | parameter 0 -> this parameter | false | -| System.IO.MemoryStream.WriteAsync(Byte[], int, int, CancellationToken) | parameter 0 -> this parameter | false | -| System.IO.Path.Combine(params String[]) | parameter 0 [[]] -> return | false | -| System.IO.Path.Combine(string, string) | parameter 0 -> return | false | -| System.IO.Path.Combine(string, string) | parameter 1 -> return | false | -| System.IO.Path.Combine(string, string, string) | parameter 0 -> return | false | -| System.IO.Path.Combine(string, string, string) | parameter 1 -> return | false | -| System.IO.Path.Combine(string, string, string) | parameter 2 -> return | false | -| System.IO.Path.Combine(string, string, string, string) | parameter 0 -> return | false | -| System.IO.Path.Combine(string, string, string, string) | parameter 1 -> return | false | -| System.IO.Path.Combine(string, string, string, string) | parameter 2 -> return | false | -| System.IO.Path.Combine(string, string, string, string) | parameter 3 -> return | false | -| System.IO.Path.GetDirectoryName(ReadOnlySpan) | parameter 0 -> return | false | -| System.IO.Path.GetDirectoryName(string) | parameter 0 -> return | false | -| System.IO.Path.GetExtension(ReadOnlySpan) | parameter 0 -> return | false | -| System.IO.Path.GetExtension(string) | parameter 0 -> return | false | -| System.IO.Path.GetFileName(ReadOnlySpan) | parameter 0 -> return | false | -| System.IO.Path.GetFileName(string) | parameter 0 -> return | false | -| System.IO.Path.GetFileNameWithoutExtension(ReadOnlySpan) | parameter 0 -> return | false | -| System.IO.Path.GetFileNameWithoutExtension(string) | parameter 0 -> return | false | -| System.IO.Path.GetFullPath(string) | parameter 0 -> return | false | -| System.IO.Path.GetFullPath(string, string) | parameter 0 -> return | false | -| System.IO.Path.GetPathRoot(ReadOnlySpan) | parameter 0 -> return | false | -| System.IO.Path.GetPathRoot(string) | parameter 0 -> return | false | -| System.IO.Path.GetRelativePath(string, string) | parameter 1 -> return | false | -| System.IO.Pipes.PipeStream.BeginRead(Byte[], int, int, AsyncCallback, object) | this parameter -> parameter 0 | false | -| System.IO.Pipes.PipeStream.BeginWrite(Byte[], int, int, AsyncCallback, object) | parameter 0 -> this parameter | false | -| System.IO.Pipes.PipeStream.Read(Byte[], int, int) | this parameter -> parameter 0 | false | -| System.IO.Pipes.PipeStream.ReadAsync(Byte[], int, int, CancellationToken) | this parameter -> parameter 0 | false | -| System.IO.Pipes.PipeStream.Write(Byte[], int, int) | parameter 0 -> this parameter | false | -| System.IO.Pipes.PipeStream.WriteAsync(Byte[], int, int, CancellationToken) | parameter 0 -> this parameter | false | -| System.IO.Stream.BeginRead(Byte[], int, int, AsyncCallback, object) | this parameter -> parameter 0 | false | -| System.IO.Stream.BeginWrite(Byte[], int, int, AsyncCallback, object) | parameter 0 -> this parameter | false | -| System.IO.Stream.CopyTo(Stream) | this parameter -> parameter 0 | false | -| System.IO.Stream.CopyTo(Stream, int) | this parameter -> parameter 0 | false | -| System.IO.Stream.CopyToAsync(Stream) | this parameter -> parameter 0 | false | -| System.IO.Stream.CopyToAsync(Stream, CancellationToken) | this parameter -> parameter 0 | false | -| System.IO.Stream.CopyToAsync(Stream, int) | this parameter -> parameter 0 | false | -| System.IO.Stream.CopyToAsync(Stream, int, CancellationToken) | this parameter -> parameter 0 | false | -| System.IO.Stream.NullStream.BeginRead(Byte[], int, int, AsyncCallback, object) | this parameter -> parameter 0 | false | -| System.IO.Stream.NullStream.BeginWrite(Byte[], int, int, AsyncCallback, object) | parameter 0 -> this parameter | false | -| System.IO.Stream.NullStream.CopyTo(Stream, int) | this parameter -> parameter 0 | false | -| System.IO.Stream.NullStream.CopyToAsync(Stream, int, CancellationToken) | this parameter -> parameter 0 | false | -| System.IO.Stream.NullStream.Read(Byte[], int, int) | this parameter -> parameter 0 | false | -| System.IO.Stream.NullStream.ReadAsync(Byte[], int, int, CancellationToken) | this parameter -> parameter 0 | false | -| System.IO.Stream.NullStream.Write(Byte[], int, int) | parameter 0 -> this parameter | false | -| System.IO.Stream.NullStream.WriteAsync(Byte[], int, int, CancellationToken) | parameter 0 -> this parameter | false | -| System.IO.Stream.Read(Byte[], int, int) | this parameter -> parameter 0 | false | -| System.IO.Stream.ReadAsync(Byte[], int, int) | this parameter -> parameter 0 | false | -| System.IO.Stream.ReadAsync(Byte[], int, int, CancellationToken) | this parameter -> parameter 0 | false | -| System.IO.Stream.SyncStream.BeginRead(Byte[], int, int, AsyncCallback, object) | this parameter -> parameter 0 | false | -| System.IO.Stream.SyncStream.BeginWrite(Byte[], int, int, AsyncCallback, object) | parameter 0 -> this parameter | false | -| System.IO.Stream.SyncStream.Read(Byte[], int, int) | this parameter -> parameter 0 | false | -| System.IO.Stream.SyncStream.Write(Byte[], int, int) | parameter 0 -> this parameter | false | -| System.IO.Stream.Write(Byte[], int, int) | parameter 0 -> this parameter | false | -| System.IO.Stream.WriteAsync(Byte[], int, int) | parameter 0 -> this parameter | false | -| System.IO.Stream.WriteAsync(Byte[], int, int, CancellationToken) | parameter 0 -> this parameter | false | -| System.IO.StringReader.Read() | this parameter -> return | false | -| System.IO.StringReader.Read(Char[], int, int) | this parameter -> return | false | -| System.IO.StringReader.Read(Span) | this parameter -> return | false | -| System.IO.StringReader.ReadAsync(Char[], int, int) | this parameter -> return | false | -| System.IO.StringReader.ReadAsync(Memory, CancellationToken) | this parameter -> return | false | -| System.IO.StringReader.ReadBlock(Span) | this parameter -> return | false | -| System.IO.StringReader.ReadBlockAsync(Char[], int, int) | this parameter -> return | false | -| System.IO.StringReader.ReadBlockAsync(Memory, CancellationToken) | this parameter -> return | false | -| System.IO.StringReader.ReadLine() | this parameter -> return | false | -| System.IO.StringReader.ReadLineAsync() | this parameter -> return | false | -| System.IO.StringReader.ReadToEnd() | this parameter -> return | false | -| System.IO.StringReader.ReadToEndAsync() | this parameter -> return | false | -| System.IO.StringReader.StringReader(string) | parameter 0 -> return | false | -| System.IO.TextReader.Read() | this parameter -> return | false | -| System.IO.TextReader.Read(Char[], int, int) | this parameter -> return | false | -| System.IO.TextReader.Read(Span) | this parameter -> return | false | -| System.IO.TextReader.ReadAsync(Char[], int, int) | this parameter -> return | false | -| System.IO.TextReader.ReadAsync(Memory, CancellationToken) | this parameter -> return | false | -| System.IO.TextReader.ReadAsyncInternal(Memory, CancellationToken) | this parameter -> return | false | -| System.IO.TextReader.ReadBlock(Char[], int, int) | this parameter -> return | false | -| System.IO.TextReader.ReadBlock(Span) | this parameter -> return | false | -| System.IO.TextReader.ReadBlockAsync(Char[], int, int) | this parameter -> return | false | -| System.IO.TextReader.ReadBlockAsync(Memory, CancellationToken) | this parameter -> return | false | -| System.IO.TextReader.ReadLine() | this parameter -> return | false | -| System.IO.TextReader.ReadLineAsync() | this parameter -> return | false | -| System.IO.TextReader.ReadToEnd() | this parameter -> return | false | -| System.IO.TextReader.ReadToEndAsync() | this parameter -> return | false | -| System.IO.UnmanagedMemoryStream.Read(Byte[], int, int) | this parameter -> parameter 0 | false | -| System.IO.UnmanagedMemoryStream.ReadAsync(Byte[], int, int, CancellationToken) | this parameter -> parameter 0 | false | -| System.IO.UnmanagedMemoryStream.Write(Byte[], int, int) | parameter 0 -> this parameter | false | -| System.IO.UnmanagedMemoryStream.WriteAsync(Byte[], int, int, CancellationToken) | parameter 0 -> this parameter | false | -| System.IO.UnmanagedMemoryStreamWrapper.CopyToAsync(Stream, int, CancellationToken) | this parameter -> parameter 0 | false | -| System.IO.UnmanagedMemoryStreamWrapper.Read(Byte[], int, int) | this parameter -> parameter 0 | false | -| System.IO.UnmanagedMemoryStreamWrapper.ReadAsync(Byte[], int, int, CancellationToken) | this parameter -> parameter 0 | false | -| System.IO.UnmanagedMemoryStreamWrapper.ToArray() | this parameter -> return | false | -| System.IO.UnmanagedMemoryStreamWrapper.Write(Byte[], int, int) | parameter 0 -> this parameter | false | -| System.IO.UnmanagedMemoryStreamWrapper.WriteAsync(Byte[], int, int, CancellationToken) | parameter 0 -> this parameter | false | -| System.Int32.Parse(string) | parameter 0 -> return | false | -| System.Int32.Parse(string, IFormatProvider) | parameter 0 -> return | false | -| System.Int32.Parse(string, NumberStyles) | parameter 0 -> return | false | -| System.Int32.Parse(string, NumberStyles, IFormatProvider) | parameter 0 -> return | false | -| System.Int32.TryParse(string, NumberStyles, IFormatProvider, out int) | parameter 0 -> parameter 3 | false | -| System.Int32.TryParse(string, NumberStyles, IFormatProvider, out int) | parameter 0 -> return | false | -| System.Int32.TryParse(string, out int) | parameter 0 -> parameter 1 | false | -| System.Int32.TryParse(string, out int) | parameter 0 -> return | false | -| System.Lazy<>.Lazy(Func) | deleget output from parameter 0 -> return [Value] | true | -| System.Lazy<>.Lazy(Func, LazyThreadSafetyMode) | deleget output from parameter 0 -> return [Value] | true | -| System.Lazy<>.Lazy(Func, bool) | deleget output from parameter 0 -> return [Value] | true | -| System.Lazy<>.get_Value() | this parameter -> return | false | -| System.Linq.EmptyPartition<>.GetEnumerator() | this parameter [[]] -> return [Current] | true | -| System.Linq.Enumerable.d__64<>.GetEnumerator() | this parameter [[]] -> return [Current] | true | -| System.Linq.Enumerable.d__81<>.GetEnumerator() | this parameter [[]] -> return [Current] | true | -| System.Linq.Enumerable.d__98<,,,>.GetEnumerator() | this parameter [[]] -> return [Current] | true | -| System.Linq.Enumerable.d__101<>.GetEnumerator() | this parameter [[]] -> return [Current] | true | -| System.Linq.Enumerable.d__105<,,,>.GetEnumerator() | this parameter [[]] -> return [Current] | true | -| System.Linq.Enumerable.d__62<>.GetEnumerator() | this parameter [[]] -> return [Current] | true | -| System.Linq.Enumerable.d__174<,>.GetEnumerator() | this parameter [[]] -> return [Current] | true | -| System.Linq.Enumerable.d__177<,>.GetEnumerator() | this parameter [[]] -> return [Current] | true | -| System.Linq.Enumerable.d__179<,,>.GetEnumerator() | this parameter [[]] -> return [Current] | true | -| System.Linq.Enumerable.d__181<,,>.GetEnumerator() | this parameter [[]] -> return [Current] | true | -| System.Linq.Enumerable.d__194<>.GetEnumerator() | this parameter [[]] -> return [Current] | true | -| System.Linq.Enumerable.d__190<>.GetEnumerator() | this parameter [[]] -> return [Current] | true | -| System.Linq.Enumerable.d__192<>.GetEnumerator() | this parameter [[]] -> return [Current] | true | -| System.Linq.Enumerable.d__221<>.GetEnumerator() | this parameter [[]] -> return [Current] | true | -| System.Linq.Enumerable.d__217<>.GetEnumerator() | this parameter [[]] -> return [Current] | true | -| System.Linq.Enumerable.d__219<>.GetEnumerator() | this parameter [[]] -> return [Current] | true | -| System.Linq.Enumerable.d__240<>.GetEnumerator() | this parameter [[]] -> return [Current] | true | -| System.Linq.Enumerable.d__243<,>.GetEnumerator() | this parameter [[]] -> return [Current] | true | -| System.Linq.Enumerable.d__244<,,>.GetEnumerator() | this parameter [[]] -> return [Current] | true | -| System.Linq.Enumerable.Aggregate(IEnumerable, TAccumulate, Func, Func) | deleget output from parameter 2 -> parameter 0 of delegate parameter 3 | true | -| System.Linq.Enumerable.Aggregate(IEnumerable, TAccumulate, Func, Func) | deleget output from parameter 3 -> return | true | -| System.Linq.Enumerable.Aggregate(IEnumerable, TAccumulate, Func, Func) | parameter 0 [[]] -> parameter 1 of delegate parameter 2 | true | -| System.Linq.Enumerable.Aggregate(IEnumerable, TAccumulate, Func, Func) | parameter 1 -> parameter 0 of delegate parameter 2 | true | -| System.Linq.Enumerable.Aggregate(IEnumerable, TAccumulate, Func) | deleget output from parameter 2 -> return | true | -| System.Linq.Enumerable.Aggregate(IEnumerable, TAccumulate, Func) | parameter 0 [[]] -> parameter 1 of delegate parameter 2 | true | -| System.Linq.Enumerable.Aggregate(IEnumerable, TAccumulate, Func) | parameter 1 -> parameter 0 of delegate parameter 2 | true | -| System.Linq.Enumerable.Aggregate(IEnumerable, Func) | deleget output from parameter 1 -> return | true | -| System.Linq.Enumerable.Aggregate(IEnumerable, Func) | parameter 0 [[]] -> parameter 1 of delegate parameter 1 | true | -| System.Linq.Enumerable.All(IEnumerable, Func) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.Enumerable.Any(IEnumerable, Func) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.Enumerable.AsEnumerable(IEnumerable) | parameter 0 [[]] -> return [[]] | true | -| System.Linq.Enumerable.Average(IEnumerable, Func) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.Enumerable.Average(IEnumerable, Func) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.Enumerable.Average(IEnumerable, Func) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.Enumerable.Average(IEnumerable, Func) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.Enumerable.Average(IEnumerable, Func>) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.Enumerable.Average(IEnumerable, Func>) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.Enumerable.Average(IEnumerable, Func>) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.Enumerable.Average(IEnumerable, Func>) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.Enumerable.Average(IEnumerable, Func>) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.Enumerable.Average(IEnumerable, Func) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.Enumerable.Cast(IEnumerable) | parameter 0 [[]] -> return [[]] | true | -| System.Linq.Enumerable.Concat(IEnumerable, IEnumerable) | parameter 0 [[]] -> return [[]] | true | -| System.Linq.Enumerable.Concat(IEnumerable, IEnumerable) | parameter 1 [[]] -> return [[]] | true | -| System.Linq.Enumerable.Count(IEnumerable, Func) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.Enumerable.DefaultIfEmpty(IEnumerable) | parameter 0 [[]] -> return | true | -| System.Linq.Enumerable.DefaultIfEmpty(IEnumerable, TSource) | parameter 0 [[]] -> return | true | -| System.Linq.Enumerable.DefaultIfEmpty(IEnumerable, TSource) | parameter 1 -> return | true | -| System.Linq.Enumerable.Distinct(IEnumerable) | parameter 0 [[]] -> return [[]] | true | -| System.Linq.Enumerable.Distinct(IEnumerable, IEqualityComparer) | parameter 0 [[]] -> return [[]] | true | -| System.Linq.Enumerable.ElementAt(IEnumerable, int) | parameter 0 [[]] -> return | true | -| System.Linq.Enumerable.ElementAtOrDefault(IEnumerable, int) | parameter 0 [[]] -> return | true | -| System.Linq.Enumerable.Except(IEnumerable, IEnumerable) | parameter 0 [[]] -> return | true | -| System.Linq.Enumerable.Except(IEnumerable, IEnumerable, IEqualityComparer) | parameter 0 [[]] -> return | true | -| System.Linq.Enumerable.First(IEnumerable) | parameter 0 [[]] -> return | true | -| System.Linq.Enumerable.First(IEnumerable, Func) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.Enumerable.First(IEnumerable, Func) | parameter 0 [[]] -> return | true | -| System.Linq.Enumerable.FirstOrDefault(IEnumerable) | parameter 0 [[]] -> return | true | -| System.Linq.Enumerable.FirstOrDefault(IEnumerable, Func) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.Enumerable.FirstOrDefault(IEnumerable, Func) | parameter 0 [[]] -> return | true | -| System.Linq.Enumerable.GroupBy(IEnumerable, Func, Func, Func, TResult>) | deleget output from parameter 1 -> parameter 0 of delegate parameter 2 | true | -| System.Linq.Enumerable.GroupBy(IEnumerable, Func, Func, Func, TResult>) | deleget output from parameter 2 -> parameter 1 of delegate parameter 3 [[]] | true | -| System.Linq.Enumerable.GroupBy(IEnumerable, Func, Func, Func, TResult>) | deleget output from parameter 3 -> return [[]] | true | -| System.Linq.Enumerable.GroupBy(IEnumerable, Func, Func, Func, TResult>) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.Enumerable.GroupBy(IEnumerable, Func, Func, Func, TResult>) | parameter 0 [[]] -> parameter 0 of delegate parameter 2 | true | -| System.Linq.Enumerable.GroupBy(IEnumerable, Func, Func, Func, TResult>, IEqualityComparer) | deleget output from parameter 1 -> parameter 0 of delegate parameter 2 | true | -| System.Linq.Enumerable.GroupBy(IEnumerable, Func, Func, Func, TResult>, IEqualityComparer) | deleget output from parameter 2 -> parameter 1 of delegate parameter 3 [[]] | true | -| System.Linq.Enumerable.GroupBy(IEnumerable, Func, Func, Func, TResult>, IEqualityComparer) | deleget output from parameter 3 -> return [[]] | true | -| System.Linq.Enumerable.GroupBy(IEnumerable, Func, Func, Func, TResult>, IEqualityComparer) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.Enumerable.GroupBy(IEnumerable, Func, Func, Func, TResult>, IEqualityComparer) | parameter 0 [[]] -> parameter 0 of delegate parameter 2 | true | -| System.Linq.Enumerable.GroupBy(IEnumerable, Func, Func) | deleget output from parameter 2 -> return [[]] | true | -| System.Linq.Enumerable.GroupBy(IEnumerable, Func, Func) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.Enumerable.GroupBy(IEnumerable, Func, Func) | parameter 0 [[]] -> parameter 0 of delegate parameter 2 | true | -| System.Linq.Enumerable.GroupBy(IEnumerable, Func, Func, IEqualityComparer) | deleget output from parameter 1 -> parameter 0 of delegate parameter 2 | true | -| System.Linq.Enumerable.GroupBy(IEnumerable, Func, Func, IEqualityComparer) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.Enumerable.GroupBy(IEnumerable, Func, Func, IEqualityComparer) | parameter 0 [[]] -> parameter 0 of delegate parameter 2 | true | -| System.Linq.Enumerable.GroupBy(IEnumerable, Func, Func, TResult>) | deleget output from parameter 1 -> parameter 0 of delegate parameter 2 | true | -| System.Linq.Enumerable.GroupBy(IEnumerable, Func, Func, TResult>) | deleget output from parameter 2 -> return [[]] | true | -| System.Linq.Enumerable.GroupBy(IEnumerable, Func, Func, TResult>) | parameter 0 -> parameter 1 of delegate parameter 2 | true | -| System.Linq.Enumerable.GroupBy(IEnumerable, Func, Func, TResult>) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.Enumerable.GroupBy(IEnumerable, Func, Func, TResult>, IEqualityComparer) | deleget output from parameter 1 -> parameter 0 of delegate parameter 2 | true | -| System.Linq.Enumerable.GroupBy(IEnumerable, Func, Func, TResult>, IEqualityComparer) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.Enumerable.GroupBy(IEnumerable, Func, Func, TResult>, IEqualityComparer) | parameter 0 [[]] -> parameter 0 of delegate parameter 2 | true | -| System.Linq.Enumerable.GroupBy(IEnumerable, Func) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.Enumerable.GroupBy(IEnumerable, Func, IEqualityComparer) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.Enumerable.GroupJoin(IEnumerable, IEnumerable, Func, Func, Func, TResult>) | deleget output from parameter 4 -> return [[]] | true | -| System.Linq.Enumerable.GroupJoin(IEnumerable, IEnumerable, Func, Func, Func, TResult>) | parameter 0 [[]] -> parameter 0 of delegate parameter 2 | true | -| System.Linq.Enumerable.GroupJoin(IEnumerable, IEnumerable, Func, Func, Func, TResult>) | parameter 0 [[]] -> parameter 0 of delegate parameter 4 | true | -| System.Linq.Enumerable.GroupJoin(IEnumerable, IEnumerable, Func, Func, Func, TResult>) | parameter 1 [[]] -> parameter 0 of delegate parameter 3 | true | -| System.Linq.Enumerable.GroupJoin(IEnumerable, IEnumerable, Func, Func, Func, TResult>) | parameter 1 [[]] -> parameter 1 of delegate parameter 4 | true | -| System.Linq.Enumerable.GroupJoin(IEnumerable, IEnumerable, Func, Func, Func, TResult>, IEqualityComparer) | deleget output from parameter 4 -> return [[]] | true | -| System.Linq.Enumerable.GroupJoin(IEnumerable, IEnumerable, Func, Func, Func, TResult>, IEqualityComparer) | parameter 0 [[]] -> parameter 0 of delegate parameter 2 | true | -| System.Linq.Enumerable.GroupJoin(IEnumerable, IEnumerable, Func, Func, Func, TResult>, IEqualityComparer) | parameter 0 [[]] -> parameter 0 of delegate parameter 4 | true | -| System.Linq.Enumerable.GroupJoin(IEnumerable, IEnumerable, Func, Func, Func, TResult>, IEqualityComparer) | parameter 1 [[]] -> parameter 0 of delegate parameter 3 | true | -| System.Linq.Enumerable.GroupJoin(IEnumerable, IEnumerable, Func, Func, Func, TResult>, IEqualityComparer) | parameter 1 [[]] -> parameter 1 of delegate parameter 4 | true | -| System.Linq.Enumerable.Intersect(IEnumerable, IEnumerable) | parameter 0 [[]] -> return [[]] | true | -| System.Linq.Enumerable.Intersect(IEnumerable, IEnumerable) | parameter 1 [[]] -> return [[]] | true | -| System.Linq.Enumerable.Intersect(IEnumerable, IEnumerable, IEqualityComparer) | parameter 0 [[]] -> return [[]] | true | -| System.Linq.Enumerable.Intersect(IEnumerable, IEnumerable, IEqualityComparer) | parameter 1 [[]] -> return [[]] | true | -| System.Linq.Enumerable.Iterator<>.GetEnumerator() | this parameter [[]] -> return [Current] | true | -| System.Linq.Enumerable.Join(IEnumerable, IEnumerable, Func, Func, Func) | deleget output from parameter 4 -> return [[]] | true | -| System.Linq.Enumerable.Join(IEnumerable, IEnumerable, Func, Func, Func) | parameter 0 [[]] -> parameter 0 of delegate parameter 2 | true | -| System.Linq.Enumerable.Join(IEnumerable, IEnumerable, Func, Func, Func) | parameter 0 [[]] -> parameter 0 of delegate parameter 4 | true | -| System.Linq.Enumerable.Join(IEnumerable, IEnumerable, Func, Func, Func) | parameter 1 [[]] -> parameter 0 of delegate parameter 3 | true | -| System.Linq.Enumerable.Join(IEnumerable, IEnumerable, Func, Func, Func) | parameter 1 [[]] -> parameter 1 of delegate parameter 4 | true | -| System.Linq.Enumerable.Join(IEnumerable, IEnumerable, Func, Func, Func, IEqualityComparer) | deleget output from parameter 4 -> return [[]] | true | -| System.Linq.Enumerable.Join(IEnumerable, IEnumerable, Func, Func, Func, IEqualityComparer) | parameter 0 [[]] -> parameter 0 of delegate parameter 2 | true | -| System.Linq.Enumerable.Join(IEnumerable, IEnumerable, Func, Func, Func, IEqualityComparer) | parameter 0 [[]] -> parameter 0 of delegate parameter 4 | true | -| System.Linq.Enumerable.Join(IEnumerable, IEnumerable, Func, Func, Func, IEqualityComparer) | parameter 1 [[]] -> parameter 0 of delegate parameter 3 | true | -| System.Linq.Enumerable.Join(IEnumerable, IEnumerable, Func, Func, Func, IEqualityComparer) | parameter 1 [[]] -> parameter 1 of delegate parameter 4 | true | -| System.Linq.Enumerable.Last(IEnumerable) | parameter 0 [[]] -> return | true | -| System.Linq.Enumerable.Last(IEnumerable, Func) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.Enumerable.Last(IEnumerable, Func) | parameter 0 [[]] -> return | true | -| System.Linq.Enumerable.LastOrDefault(IEnumerable) | parameter 0 [[]] -> return | true | -| System.Linq.Enumerable.LastOrDefault(IEnumerable, Func) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.Enumerable.LastOrDefault(IEnumerable, Func) | parameter 0 [[]] -> return | true | -| System.Linq.Enumerable.LongCount(IEnumerable, Func) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.Enumerable.Max(IEnumerable, Func) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.Enumerable.Max(IEnumerable, Func) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.Enumerable.Max(IEnumerable, Func) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.Enumerable.Max(IEnumerable, Func) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.Enumerable.Max(IEnumerable, Func) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.Enumerable.Max(IEnumerable, Func>) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.Enumerable.Max(IEnumerable, Func>) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.Enumerable.Max(IEnumerable, Func>) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.Enumerable.Max(IEnumerable, Func>) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.Enumerable.Max(IEnumerable, Func>) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.Enumerable.Max(IEnumerable, Func) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.Enumerable.Min(IEnumerable, Func) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.Enumerable.Min(IEnumerable, Func) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.Enumerable.Min(IEnumerable, Func) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.Enumerable.Min(IEnumerable, Func) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.Enumerable.Min(IEnumerable, Func) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.Enumerable.Min(IEnumerable, Func>) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.Enumerable.Min(IEnumerable, Func>) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.Enumerable.Min(IEnumerable, Func>) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.Enumerable.Min(IEnumerable, Func>) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.Enumerable.Min(IEnumerable, Func>) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.Enumerable.Min(IEnumerable, Func) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.Enumerable.OfType(IEnumerable) | parameter 0 [[]] -> return [[]] | true | -| System.Linq.Enumerable.OrderBy(IEnumerable, Func) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.Enumerable.OrderBy(IEnumerable, Func) | parameter 0 [[]] -> return [[]] | true | -| System.Linq.Enumerable.OrderBy(IEnumerable, Func, IComparer) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.Enumerable.OrderBy(IEnumerable, Func, IComparer) | parameter 0 [[]] -> return [[]] | true | -| System.Linq.Enumerable.OrderByDescending(IEnumerable, Func) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.Enumerable.OrderByDescending(IEnumerable, Func) | parameter 0 [[]] -> return [[]] | true | -| System.Linq.Enumerable.OrderByDescending(IEnumerable, Func, IComparer) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.Enumerable.OrderByDescending(IEnumerable, Func, IComparer) | parameter 0 [[]] -> return [[]] | true | -| System.Linq.Enumerable.Reverse(IEnumerable) | parameter 0 [[]] -> return [[]] | true | -| System.Linq.Enumerable.Select(IEnumerable, Func) | deleget output from parameter 1 -> return [[]] | true | -| System.Linq.Enumerable.Select(IEnumerable, Func) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.Enumerable.Select(IEnumerable, Func) | deleget output from parameter 1 -> return [[]] | true | -| System.Linq.Enumerable.Select(IEnumerable, Func) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.Enumerable.SelectMany(IEnumerable, Func>, Func) | deleget output from parameter 1 [[]] -> parameter 1 of delegate parameter 2 | true | -| System.Linq.Enumerable.SelectMany(IEnumerable, Func>, Func) | deleget output from parameter 2 -> return [[]] | true | -| System.Linq.Enumerable.SelectMany(IEnumerable, Func>, Func) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.Enumerable.SelectMany(IEnumerable, Func>, Func) | parameter 0 [[]] -> parameter 0 of delegate parameter 2 | true | -| System.Linq.Enumerable.SelectMany(IEnumerable, Func>, Func) | deleget output from parameter 1 [[]] -> parameter 1 of delegate parameter 2 | true | -| System.Linq.Enumerable.SelectMany(IEnumerable, Func>, Func) | deleget output from parameter 2 -> return [[]] | true | -| System.Linq.Enumerable.SelectMany(IEnumerable, Func>, Func) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.Enumerable.SelectMany(IEnumerable, Func>, Func) | parameter 0 [[]] -> parameter 0 of delegate parameter 2 | true | -| System.Linq.Enumerable.SelectMany(IEnumerable, Func>) | deleget output from parameter 1 -> return [[]] | true | -| System.Linq.Enumerable.SelectMany(IEnumerable, Func>) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.Enumerable.SelectMany(IEnumerable, Func>) | deleget output from parameter 1 -> return [[]] | true | -| System.Linq.Enumerable.SelectMany(IEnumerable, Func>) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.Enumerable.Single(IEnumerable) | parameter 0 [[]] -> return | true | -| System.Linq.Enumerable.Single(IEnumerable, Func) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.Enumerable.Single(IEnumerable, Func) | parameter 0 [[]] -> return | true | -| System.Linq.Enumerable.SingleOrDefault(IEnumerable) | parameter 0 [[]] -> return | true | -| System.Linq.Enumerable.SingleOrDefault(IEnumerable, Func) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.Enumerable.SingleOrDefault(IEnumerable, Func) | parameter 0 [[]] -> return | true | -| System.Linq.Enumerable.Skip(IEnumerable, int) | parameter 0 [[]] -> return [[]] | true | -| System.Linq.Enumerable.SkipWhile(IEnumerable, Func) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.Enumerable.SkipWhile(IEnumerable, Func) | parameter 0 [[]] -> return [[]] | true | -| System.Linq.Enumerable.SkipWhile(IEnumerable, Func) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.Enumerable.SkipWhile(IEnumerable, Func) | parameter 0 [[]] -> return [[]] | true | -| System.Linq.Enumerable.Sum(IEnumerable, Func) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.Enumerable.Sum(IEnumerable, Func) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.Enumerable.Sum(IEnumerable, Func) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.Enumerable.Sum(IEnumerable, Func) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.Enumerable.Sum(IEnumerable, Func>) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.Enumerable.Sum(IEnumerable, Func>) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.Enumerable.Sum(IEnumerable, Func>) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.Enumerable.Sum(IEnumerable, Func>) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.Enumerable.Sum(IEnumerable, Func>) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.Enumerable.Sum(IEnumerable, Func) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.Enumerable.Take(IEnumerable, int) | parameter 0 [[]] -> return [[]] | true | -| System.Linq.Enumerable.TakeWhile(IEnumerable, Func) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.Enumerable.TakeWhile(IEnumerable, Func) | parameter 0 [[]] -> return [[]] | true | -| System.Linq.Enumerable.TakeWhile(IEnumerable, Func) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.Enumerable.TakeWhile(IEnumerable, Func) | parameter 0 [[]] -> return [[]] | true | -| System.Linq.Enumerable.ThenBy(IOrderedEnumerable, Func) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.Enumerable.ThenBy(IOrderedEnumerable, Func) | parameter 0 [[]] -> return [[]] | true | -| System.Linq.Enumerable.ThenBy(IOrderedEnumerable, Func, IComparer) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.Enumerable.ThenBy(IOrderedEnumerable, Func, IComparer) | parameter 0 [[]] -> return [[]] | true | -| System.Linq.Enumerable.ThenByDescending(IOrderedEnumerable, Func) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.Enumerable.ThenByDescending(IOrderedEnumerable, Func) | parameter 0 [[]] -> return [[]] | true | -| System.Linq.Enumerable.ThenByDescending(IOrderedEnumerable, Func, IComparer) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.Enumerable.ThenByDescending(IOrderedEnumerable, Func, IComparer) | parameter 0 [[]] -> return [[]] | true | -| System.Linq.Enumerable.ToArray(IEnumerable) | parameter 0 [[]] -> return [[]] | true | -| System.Linq.Enumerable.ToDictionary(IEnumerable, Func, Func) | deleget output from parameter 2 -> return [[]] | true | -| System.Linq.Enumerable.ToDictionary(IEnumerable, Func, Func) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.Enumerable.ToDictionary(IEnumerable, Func, Func) | parameter 0 [[]] -> parameter 0 of delegate parameter 2 | true | -| System.Linq.Enumerable.ToDictionary(IEnumerable, Func, Func, IEqualityComparer) | deleget output from parameter 2 -> return [[]] | true | -| System.Linq.Enumerable.ToDictionary(IEnumerable, Func, Func, IEqualityComparer) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.Enumerable.ToDictionary(IEnumerable, Func, Func, IEqualityComparer) | parameter 0 [[]] -> parameter 0 of delegate parameter 2 | true | -| System.Linq.Enumerable.ToDictionary(IEnumerable, Func) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.Enumerable.ToDictionary(IEnumerable, Func) | parameter 0 [[]] -> return [[]] | true | -| System.Linq.Enumerable.ToDictionary(IEnumerable, Func, IEqualityComparer) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.Enumerable.ToDictionary(IEnumerable, Func, IEqualityComparer) | parameter 0 [[]] -> return [[]] | true | -| System.Linq.Enumerable.ToList(IEnumerable) | parameter 0 [[]] -> return [[]] | true | -| System.Linq.Enumerable.ToLookup(IEnumerable, Func, Func) | deleget output from parameter 2 -> return [[]] | true | -| System.Linq.Enumerable.ToLookup(IEnumerable, Func, Func) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.Enumerable.ToLookup(IEnumerable, Func, Func) | parameter 0 [[]] -> parameter 0 of delegate parameter 2 | true | -| System.Linq.Enumerable.ToLookup(IEnumerable, Func, Func, IEqualityComparer) | deleget output from parameter 2 -> return [[]] | true | -| System.Linq.Enumerable.ToLookup(IEnumerable, Func, Func, IEqualityComparer) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.Enumerable.ToLookup(IEnumerable, Func, Func, IEqualityComparer) | parameter 0 [[]] -> parameter 0 of delegate parameter 2 | true | -| System.Linq.Enumerable.ToLookup(IEnumerable, Func) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.Enumerable.ToLookup(IEnumerable, Func) | parameter 0 [[]] -> return [[]] | true | -| System.Linq.Enumerable.ToLookup(IEnumerable, Func, IEqualityComparer) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.Enumerable.ToLookup(IEnumerable, Func, IEqualityComparer) | parameter 0 [[]] -> return [[]] | true | -| System.Linq.Enumerable.Union(IEnumerable, IEnumerable) | parameter 0 [[]] -> return [[]] | true | -| System.Linq.Enumerable.Union(IEnumerable, IEnumerable) | parameter 1 [[]] -> return [[]] | true | -| System.Linq.Enumerable.Union(IEnumerable, IEnumerable, IEqualityComparer) | parameter 0 [[]] -> return [[]] | true | -| System.Linq.Enumerable.Union(IEnumerable, IEnumerable, IEqualityComparer) | parameter 1 [[]] -> return [[]] | true | -| System.Linq.Enumerable.Where(IEnumerable, Func) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.Enumerable.Where(IEnumerable, Func) | parameter 0 [[]] -> return [[]] | true | -| System.Linq.Enumerable.Where(IEnumerable, Func) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.Enumerable.Where(IEnumerable, Func) | parameter 0 [[]] -> return [[]] | true | -| System.Linq.Enumerable.Zip(IEnumerable, IEnumerable, Func) | deleget output from parameter 2 -> return [[]] | true | -| System.Linq.Enumerable.Zip(IEnumerable, IEnumerable, Func) | parameter 0 [[]] -> parameter 0 of delegate parameter 2 | true | -| System.Linq.Enumerable.Zip(IEnumerable, IEnumerable, Func) | parameter 1 [[]] -> parameter 1 of delegate parameter 2 | true | -| System.Linq.EnumerableQuery<>.GetEnumerator() | this parameter [[]] -> return [Current] | true | -| System.Linq.Expressions.BlockExpressionList.Add(Expression) | parameter 0 -> this parameter [[]] | true | -| System.Linq.Expressions.BlockExpressionList.CopyTo(Expression[], int) | this parameter [[]] -> parameter 0 [[]] | true | -| System.Linq.Expressions.BlockExpressionList.GetEnumerator() | this parameter [[]] -> return [Current] | true | -| System.Linq.Expressions.BlockExpressionList.Insert(int, Expression) | parameter 1 -> this parameter [[]] | true | -| System.Linq.Expressions.BlockExpressionList.get_Item(int) | this parameter [[]] -> return | true | -| System.Linq.Expressions.BlockExpressionList.set_Item(int, Expression) | parameter 1 -> this parameter [[]] | true | -| System.Linq.Expressions.Compiler.CompilerScope.d__32.GetEnumerator() | this parameter [[]] -> return [Current] | true | -| System.Linq.Expressions.Compiler.ParameterList.GetEnumerator() | this parameter [[]] -> return [Current] | true | -| System.Linq.Expressions.Interpreter.InterpretedFrame.d__29.GetEnumerator() | this parameter [[]] -> return [Current] | true | -| System.Linq.GroupedEnumerable<,,>.GetEnumerator() | this parameter [[]] -> return [Current] | true | -| System.Linq.GroupedEnumerable<,>.GetEnumerator() | this parameter [[]] -> return [Current] | true | -| System.Linq.GroupedResultEnumerable<,,,>.GetEnumerator() | this parameter [[]] -> return [Current] | true | -| System.Linq.GroupedResultEnumerable<,,>.GetEnumerator() | this parameter [[]] -> return [Current] | true | -| System.Linq.Grouping<,>.Add(TElement) | parameter 0 -> this parameter [[]] | true | -| System.Linq.Grouping<,>.CopyTo(TElement[], int) | this parameter [[]] -> parameter 0 [[]] | true | -| System.Linq.Grouping<,>.GetEnumerator() | this parameter [[]] -> return [Current] | true | -| System.Linq.Grouping<,>.Insert(int, TElement) | parameter 1 -> this parameter [[]] | true | -| System.Linq.Grouping<,>.get_Item(int) | this parameter [[]] -> return | true | -| System.Linq.Grouping<,>.set_Item(int, TElement) | parameter 1 -> this parameter [[]] | true | -| System.Linq.Lookup<,>.d__19<>.GetEnumerator() | this parameter [[]] -> return [Current] | true | -| System.Linq.Lookup<,>.GetEnumerator() | this parameter [[]] -> return [Current] | true | -| System.Linq.OrderedEnumerable<>.GetEnumerator() | this parameter [[]] -> return [Current] | true | -| System.Linq.OrderedPartition<>.GetEnumerator() | this parameter [[]] -> return [Current] | true | -| System.Linq.Parallel.CancellableEnumerable.d__0<>.GetEnumerator() | this parameter [[]] -> return [Current] | true | -| System.Linq.Parallel.EnumerableWrapperWeakToStrong.GetEnumerator() | this parameter [[]] -> return [Current] | true | -| System.Linq.Parallel.ExceptionAggregator.d__0<>.GetEnumerator() | this parameter [[]] -> return [Current] | true | -| System.Linq.Parallel.ExceptionAggregator.d__1<,>.GetEnumerator() | this parameter [[]] -> return [Current] | true | -| System.Linq.Parallel.GroupByGrouping<,>.GetEnumerator() | this parameter [[]] -> return [Current] | true | -| System.Linq.Parallel.ListChunk<>.GetEnumerator() | this parameter [[]] -> return [Current] | true | -| System.Linq.Parallel.Lookup<,>.GetEnumerator() | this parameter [[]] -> return [Current] | true | -| System.Linq.Parallel.MergeExecutor<>.GetEnumerator() | this parameter [[]] -> return [Current] | true | -| System.Linq.Parallel.OrderedGroupByGrouping<,,>.GetEnumerator() | this parameter [[]] -> return [Current] | true | -| System.Linq.Parallel.ParallelEnumerableWrapper.GetEnumerator() | this parameter [[]] -> return [Current] | true | -| System.Linq.Parallel.PartitionerQueryOperator<>.d__5.GetEnumerator() | this parameter [[]] -> return [Current] | true | -| System.Linq.Parallel.QueryResults<>.Add(T) | parameter 0 -> this parameter [[]] | true | -| System.Linq.Parallel.QueryResults<>.CopyTo(T[], int) | this parameter [[]] -> parameter 0 [[]] | true | -| System.Linq.Parallel.QueryResults<>.GetEnumerator() | this parameter [[]] -> return [Current] | true | -| System.Linq.Parallel.QueryResults<>.Insert(int, T) | parameter 1 -> this parameter [[]] | true | -| System.Linq.Parallel.QueryResults<>.get_Item(int) | this parameter [[]] -> return | true | -| System.Linq.Parallel.QueryResults<>.set_Item(int, T) | parameter 1 -> this parameter [[]] | true | -| System.Linq.Parallel.RangeEnumerable.GetEnumerator() | this parameter [[]] -> return [Current] | true | -| System.Linq.Parallel.ZipQueryOperator<,,>.d__9.GetEnumerator() | this parameter [[]] -> return [Current] | true | -| System.Linq.ParallelEnumerable.Aggregate(ParallelQuery, TAccumulate, Func, Func) | deleget output from parameter 2 -> parameter 0 of delegate parameter 3 | true | -| System.Linq.ParallelEnumerable.Aggregate(ParallelQuery, TAccumulate, Func, Func) | deleget output from parameter 3 -> return | true | -| System.Linq.ParallelEnumerable.Aggregate(ParallelQuery, TAccumulate, Func, Func) | parameter 0 [[]] -> parameter 1 of delegate parameter 2 | true | -| System.Linq.ParallelEnumerable.Aggregate(ParallelQuery, TAccumulate, Func, Func) | parameter 1 -> parameter 0 of delegate parameter 2 | true | -| System.Linq.ParallelEnumerable.Aggregate(ParallelQuery, TAccumulate, Func) | deleget output from parameter 2 -> return | true | -| System.Linq.ParallelEnumerable.Aggregate(ParallelQuery, TAccumulate, Func) | parameter 0 [[]] -> parameter 1 of delegate parameter 2 | true | -| System.Linq.ParallelEnumerable.Aggregate(ParallelQuery, TAccumulate, Func) | parameter 1 -> parameter 0 of delegate parameter 2 | true | -| System.Linq.ParallelEnumerable.Aggregate(ParallelQuery, Func) | deleget output from parameter 1 -> return | true | -| System.Linq.ParallelEnumerable.Aggregate(ParallelQuery, Func) | parameter 0 [[]] -> parameter 1 of delegate parameter 1 | true | -| System.Linq.ParallelEnumerable.All(ParallelQuery, Func) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.ParallelEnumerable.Any(ParallelQuery, Func) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.ParallelEnumerable.AsEnumerable(ParallelQuery) | parameter 0 [[]] -> return [[]] | true | -| System.Linq.ParallelEnumerable.Average(ParallelQuery, Func) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.ParallelEnumerable.Average(ParallelQuery, Func) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.ParallelEnumerable.Average(ParallelQuery, Func) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.ParallelEnumerable.Average(ParallelQuery, Func) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.ParallelEnumerable.Average(ParallelQuery, Func>) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.ParallelEnumerable.Average(ParallelQuery, Func>) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.ParallelEnumerable.Average(ParallelQuery, Func>) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.ParallelEnumerable.Average(ParallelQuery, Func>) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.ParallelEnumerable.Average(ParallelQuery, Func>) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.ParallelEnumerable.Average(ParallelQuery, Func) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.ParallelEnumerable.Cast(ParallelQuery) | parameter 0 [[]] -> return [[]] | true | -| System.Linq.ParallelEnumerable.Concat(ParallelQuery, IEnumerable) | parameter 0 [[]] -> return [[]] | true | -| System.Linq.ParallelEnumerable.Concat(ParallelQuery, IEnumerable) | parameter 1 [[]] -> return [[]] | true | -| System.Linq.ParallelEnumerable.Concat(ParallelQuery, ParallelQuery) | parameter 0 [[]] -> return [[]] | true | -| System.Linq.ParallelEnumerable.Concat(ParallelQuery, ParallelQuery) | parameter 1 [[]] -> return [[]] | true | -| System.Linq.ParallelEnumerable.Count(ParallelQuery, Func) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.ParallelEnumerable.DefaultIfEmpty(ParallelQuery) | parameter 0 [[]] -> return | true | -| System.Linq.ParallelEnumerable.DefaultIfEmpty(ParallelQuery, TSource) | parameter 0 [[]] -> return | true | -| System.Linq.ParallelEnumerable.DefaultIfEmpty(ParallelQuery, TSource) | parameter 1 -> return | true | -| System.Linq.ParallelEnumerable.Distinct(ParallelQuery) | parameter 0 [[]] -> return [[]] | true | -| System.Linq.ParallelEnumerable.Distinct(ParallelQuery, IEqualityComparer) | parameter 0 [[]] -> return [[]] | true | -| System.Linq.ParallelEnumerable.ElementAt(ParallelQuery, int) | parameter 0 [[]] -> return | true | -| System.Linq.ParallelEnumerable.ElementAtOrDefault(ParallelQuery, int) | parameter 0 [[]] -> return | true | -| System.Linq.ParallelEnumerable.Except(ParallelQuery, IEnumerable) | parameter 0 [[]] -> return | true | -| System.Linq.ParallelEnumerable.Except(ParallelQuery, IEnumerable, IEqualityComparer) | parameter 0 [[]] -> return | true | -| System.Linq.ParallelEnumerable.Except(ParallelQuery, ParallelQuery) | parameter 0 [[]] -> return | true | -| System.Linq.ParallelEnumerable.Except(ParallelQuery, ParallelQuery, IEqualityComparer) | parameter 0 [[]] -> return | true | -| System.Linq.ParallelEnumerable.First(ParallelQuery) | parameter 0 [[]] -> return | true | -| System.Linq.ParallelEnumerable.First(ParallelQuery, Func) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.ParallelEnumerable.First(ParallelQuery, Func) | parameter 0 [[]] -> return | true | -| System.Linq.ParallelEnumerable.FirstOrDefault(ParallelQuery) | parameter 0 [[]] -> return | true | -| System.Linq.ParallelEnumerable.FirstOrDefault(ParallelQuery, Func) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.ParallelEnumerable.FirstOrDefault(ParallelQuery, Func) | parameter 0 [[]] -> return | true | -| System.Linq.ParallelEnumerable.GroupBy(ParallelQuery, Func, Func, Func, TResult>) | deleget output from parameter 1 -> parameter 0 of delegate parameter 2 | true | -| System.Linq.ParallelEnumerable.GroupBy(ParallelQuery, Func, Func, Func, TResult>) | deleget output from parameter 2 -> parameter 1 of delegate parameter 3 [[]] | true | -| System.Linq.ParallelEnumerable.GroupBy(ParallelQuery, Func, Func, Func, TResult>) | deleget output from parameter 3 -> return [[]] | true | -| System.Linq.ParallelEnumerable.GroupBy(ParallelQuery, Func, Func, Func, TResult>) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.ParallelEnumerable.GroupBy(ParallelQuery, Func, Func, Func, TResult>) | parameter 0 [[]] -> parameter 0 of delegate parameter 2 | true | -| System.Linq.ParallelEnumerable.GroupBy(ParallelQuery, Func, Func, Func, TResult>, IEqualityComparer) | deleget output from parameter 1 -> parameter 0 of delegate parameter 2 | true | -| System.Linq.ParallelEnumerable.GroupBy(ParallelQuery, Func, Func, Func, TResult>, IEqualityComparer) | deleget output from parameter 2 -> parameter 1 of delegate parameter 3 [[]] | true | -| System.Linq.ParallelEnumerable.GroupBy(ParallelQuery, Func, Func, Func, TResult>, IEqualityComparer) | deleget output from parameter 3 -> return [[]] | true | -| System.Linq.ParallelEnumerable.GroupBy(ParallelQuery, Func, Func, Func, TResult>, IEqualityComparer) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.ParallelEnumerable.GroupBy(ParallelQuery, Func, Func, Func, TResult>, IEqualityComparer) | parameter 0 [[]] -> parameter 0 of delegate parameter 2 | true | -| System.Linq.ParallelEnumerable.GroupBy(ParallelQuery, Func, Func) | deleget output from parameter 2 -> return [[]] | true | -| System.Linq.ParallelEnumerable.GroupBy(ParallelQuery, Func, Func) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.ParallelEnumerable.GroupBy(ParallelQuery, Func, Func) | parameter 0 [[]] -> parameter 0 of delegate parameter 2 | true | -| System.Linq.ParallelEnumerable.GroupBy(ParallelQuery, Func, Func, IEqualityComparer) | deleget output from parameter 1 -> parameter 0 of delegate parameter 2 | true | -| System.Linq.ParallelEnumerable.GroupBy(ParallelQuery, Func, Func, IEqualityComparer) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.ParallelEnumerable.GroupBy(ParallelQuery, Func, Func, IEqualityComparer) | parameter 0 [[]] -> parameter 0 of delegate parameter 2 | true | -| System.Linq.ParallelEnumerable.GroupBy(ParallelQuery, Func, Func, TResult>) | deleget output from parameter 1 -> parameter 0 of delegate parameter 2 | true | -| System.Linq.ParallelEnumerable.GroupBy(ParallelQuery, Func, Func, TResult>) | deleget output from parameter 2 -> return [[]] | true | -| System.Linq.ParallelEnumerable.GroupBy(ParallelQuery, Func, Func, TResult>) | parameter 0 -> parameter 1 of delegate parameter 2 | true | -| System.Linq.ParallelEnumerable.GroupBy(ParallelQuery, Func, Func, TResult>) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.ParallelEnumerable.GroupBy(ParallelQuery, Func, Func, TResult>, IEqualityComparer) | deleget output from parameter 1 -> parameter 0 of delegate parameter 2 | true | -| System.Linq.ParallelEnumerable.GroupBy(ParallelQuery, Func, Func, TResult>, IEqualityComparer) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.ParallelEnumerable.GroupBy(ParallelQuery, Func, Func, TResult>, IEqualityComparer) | parameter 0 [[]] -> parameter 0 of delegate parameter 2 | true | -| System.Linq.ParallelEnumerable.GroupBy(ParallelQuery, Func) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.ParallelEnumerable.GroupBy(ParallelQuery, Func, IEqualityComparer) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.ParallelEnumerable.GroupJoin(ParallelQuery, IEnumerable, Func, Func, Func, TResult>) | deleget output from parameter 4 -> return [[]] | true | -| System.Linq.ParallelEnumerable.GroupJoin(ParallelQuery, IEnumerable, Func, Func, Func, TResult>) | parameter 0 [[]] -> parameter 0 of delegate parameter 2 | true | -| System.Linq.ParallelEnumerable.GroupJoin(ParallelQuery, IEnumerable, Func, Func, Func, TResult>) | parameter 0 [[]] -> parameter 0 of delegate parameter 4 | true | -| System.Linq.ParallelEnumerable.GroupJoin(ParallelQuery, IEnumerable, Func, Func, Func, TResult>) | parameter 1 [[]] -> parameter 0 of delegate parameter 3 | true | -| System.Linq.ParallelEnumerable.GroupJoin(ParallelQuery, IEnumerable, Func, Func, Func, TResult>) | parameter 1 [[]] -> parameter 1 of delegate parameter 4 | true | -| System.Linq.ParallelEnumerable.GroupJoin(ParallelQuery, IEnumerable, Func, Func, Func, TResult>, IEqualityComparer) | deleget output from parameter 4 -> return [[]] | true | -| System.Linq.ParallelEnumerable.GroupJoin(ParallelQuery, IEnumerable, Func, Func, Func, TResult>, IEqualityComparer) | parameter 0 [[]] -> parameter 0 of delegate parameter 2 | true | -| System.Linq.ParallelEnumerable.GroupJoin(ParallelQuery, IEnumerable, Func, Func, Func, TResult>, IEqualityComparer) | parameter 0 [[]] -> parameter 0 of delegate parameter 4 | true | -| System.Linq.ParallelEnumerable.GroupJoin(ParallelQuery, IEnumerable, Func, Func, Func, TResult>, IEqualityComparer) | parameter 1 [[]] -> parameter 0 of delegate parameter 3 | true | -| System.Linq.ParallelEnumerable.GroupJoin(ParallelQuery, IEnumerable, Func, Func, Func, TResult>, IEqualityComparer) | parameter 1 [[]] -> parameter 1 of delegate parameter 4 | true | -| System.Linq.ParallelEnumerable.GroupJoin(ParallelQuery, ParallelQuery, Func, Func, Func, TResult>) | deleget output from parameter 4 -> return [[]] | true | -| System.Linq.ParallelEnumerable.GroupJoin(ParallelQuery, ParallelQuery, Func, Func, Func, TResult>) | parameter 0 [[]] -> parameter 0 of delegate parameter 2 | true | -| System.Linq.ParallelEnumerable.GroupJoin(ParallelQuery, ParallelQuery, Func, Func, Func, TResult>) | parameter 0 [[]] -> parameter 0 of delegate parameter 4 | true | -| System.Linq.ParallelEnumerable.GroupJoin(ParallelQuery, ParallelQuery, Func, Func, Func, TResult>) | parameter 1 [[]] -> parameter 0 of delegate parameter 3 | true | -| System.Linq.ParallelEnumerable.GroupJoin(ParallelQuery, ParallelQuery, Func, Func, Func, TResult>) | parameter 1 [[]] -> parameter 1 of delegate parameter 4 | true | -| System.Linq.ParallelEnumerable.GroupJoin(ParallelQuery, ParallelQuery, Func, Func, Func, TResult>, IEqualityComparer) | deleget output from parameter 4 -> return [[]] | true | -| System.Linq.ParallelEnumerable.GroupJoin(ParallelQuery, ParallelQuery, Func, Func, Func, TResult>, IEqualityComparer) | parameter 0 [[]] -> parameter 0 of delegate parameter 2 | true | -| System.Linq.ParallelEnumerable.GroupJoin(ParallelQuery, ParallelQuery, Func, Func, Func, TResult>, IEqualityComparer) | parameter 0 [[]] -> parameter 0 of delegate parameter 4 | true | -| System.Linq.ParallelEnumerable.GroupJoin(ParallelQuery, ParallelQuery, Func, Func, Func, TResult>, IEqualityComparer) | parameter 1 [[]] -> parameter 0 of delegate parameter 3 | true | -| System.Linq.ParallelEnumerable.GroupJoin(ParallelQuery, ParallelQuery, Func, Func, Func, TResult>, IEqualityComparer) | parameter 1 [[]] -> parameter 1 of delegate parameter 4 | true | -| System.Linq.ParallelEnumerable.Intersect(ParallelQuery, IEnumerable) | parameter 0 [[]] -> return [[]] | true | -| System.Linq.ParallelEnumerable.Intersect(ParallelQuery, IEnumerable) | parameter 1 [[]] -> return [[]] | true | -| System.Linq.ParallelEnumerable.Intersect(ParallelQuery, IEnumerable, IEqualityComparer) | parameter 0 [[]] -> return [[]] | true | -| System.Linq.ParallelEnumerable.Intersect(ParallelQuery, IEnumerable, IEqualityComparer) | parameter 1 [[]] -> return [[]] | true | -| System.Linq.ParallelEnumerable.Intersect(ParallelQuery, ParallelQuery) | parameter 0 [[]] -> return [[]] | true | -| System.Linq.ParallelEnumerable.Intersect(ParallelQuery, ParallelQuery) | parameter 1 [[]] -> return [[]] | true | -| System.Linq.ParallelEnumerable.Intersect(ParallelQuery, ParallelQuery, IEqualityComparer) | parameter 0 [[]] -> return [[]] | true | -| System.Linq.ParallelEnumerable.Intersect(ParallelQuery, ParallelQuery, IEqualityComparer) | parameter 1 [[]] -> return [[]] | true | -| System.Linq.ParallelEnumerable.Join(ParallelQuery, IEnumerable, Func, Func, Func) | deleget output from parameter 4 -> return [[]] | true | -| System.Linq.ParallelEnumerable.Join(ParallelQuery, IEnumerable, Func, Func, Func) | parameter 0 [[]] -> parameter 0 of delegate parameter 2 | true | -| System.Linq.ParallelEnumerable.Join(ParallelQuery, IEnumerable, Func, Func, Func) | parameter 0 [[]] -> parameter 0 of delegate parameter 4 | true | -| System.Linq.ParallelEnumerable.Join(ParallelQuery, IEnumerable, Func, Func, Func) | parameter 1 [[]] -> parameter 0 of delegate parameter 3 | true | -| System.Linq.ParallelEnumerable.Join(ParallelQuery, IEnumerable, Func, Func, Func) | parameter 1 [[]] -> parameter 1 of delegate parameter 4 | true | -| System.Linq.ParallelEnumerable.Join(ParallelQuery, IEnumerable, Func, Func, Func, IEqualityComparer) | deleget output from parameter 4 -> return [[]] | true | -| System.Linq.ParallelEnumerable.Join(ParallelQuery, IEnumerable, Func, Func, Func, IEqualityComparer) | parameter 0 [[]] -> parameter 0 of delegate parameter 2 | true | -| System.Linq.ParallelEnumerable.Join(ParallelQuery, IEnumerable, Func, Func, Func, IEqualityComparer) | parameter 0 [[]] -> parameter 0 of delegate parameter 4 | true | -| System.Linq.ParallelEnumerable.Join(ParallelQuery, IEnumerable, Func, Func, Func, IEqualityComparer) | parameter 1 [[]] -> parameter 0 of delegate parameter 3 | true | -| System.Linq.ParallelEnumerable.Join(ParallelQuery, IEnumerable, Func, Func, Func, IEqualityComparer) | parameter 1 [[]] -> parameter 1 of delegate parameter 4 | true | -| System.Linq.ParallelEnumerable.Join(ParallelQuery, ParallelQuery, Func, Func, Func) | deleget output from parameter 4 -> return [[]] | true | -| System.Linq.ParallelEnumerable.Join(ParallelQuery, ParallelQuery, Func, Func, Func) | parameter 0 [[]] -> parameter 0 of delegate parameter 2 | true | -| System.Linq.ParallelEnumerable.Join(ParallelQuery, ParallelQuery, Func, Func, Func) | parameter 0 [[]] -> parameter 0 of delegate parameter 4 | true | -| System.Linq.ParallelEnumerable.Join(ParallelQuery, ParallelQuery, Func, Func, Func) | parameter 1 [[]] -> parameter 0 of delegate parameter 3 | true | -| System.Linq.ParallelEnumerable.Join(ParallelQuery, ParallelQuery, Func, Func, Func) | parameter 1 [[]] -> parameter 1 of delegate parameter 4 | true | -| System.Linq.ParallelEnumerable.Join(ParallelQuery, ParallelQuery, Func, Func, Func, IEqualityComparer) | deleget output from parameter 4 -> return [[]] | true | -| System.Linq.ParallelEnumerable.Join(ParallelQuery, ParallelQuery, Func, Func, Func, IEqualityComparer) | parameter 0 [[]] -> parameter 0 of delegate parameter 2 | true | -| System.Linq.ParallelEnumerable.Join(ParallelQuery, ParallelQuery, Func, Func, Func, IEqualityComparer) | parameter 0 [[]] -> parameter 0 of delegate parameter 4 | true | -| System.Linq.ParallelEnumerable.Join(ParallelQuery, ParallelQuery, Func, Func, Func, IEqualityComparer) | parameter 1 [[]] -> parameter 0 of delegate parameter 3 | true | -| System.Linq.ParallelEnumerable.Join(ParallelQuery, ParallelQuery, Func, Func, Func, IEqualityComparer) | parameter 1 [[]] -> parameter 1 of delegate parameter 4 | true | -| System.Linq.ParallelEnumerable.Last(ParallelQuery) | parameter 0 [[]] -> return | true | -| System.Linq.ParallelEnumerable.Last(ParallelQuery, Func) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.ParallelEnumerable.Last(ParallelQuery, Func) | parameter 0 [[]] -> return | true | -| System.Linq.ParallelEnumerable.LastOrDefault(ParallelQuery) | parameter 0 [[]] -> return | true | -| System.Linq.ParallelEnumerable.LastOrDefault(ParallelQuery, Func) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.ParallelEnumerable.LastOrDefault(ParallelQuery, Func) | parameter 0 [[]] -> return | true | -| System.Linq.ParallelEnumerable.LongCount(ParallelQuery, Func) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.ParallelEnumerable.Max(ParallelQuery, Func) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.ParallelEnumerable.Max(ParallelQuery, Func) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.ParallelEnumerable.Max(ParallelQuery, Func) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.ParallelEnumerable.Max(ParallelQuery, Func) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.ParallelEnumerable.Max(ParallelQuery, Func) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.ParallelEnumerable.Max(ParallelQuery, Func>) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.ParallelEnumerable.Max(ParallelQuery, Func>) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.ParallelEnumerable.Max(ParallelQuery, Func>) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.ParallelEnumerable.Max(ParallelQuery, Func>) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.ParallelEnumerable.Max(ParallelQuery, Func>) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.ParallelEnumerable.Max(ParallelQuery, Func) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.ParallelEnumerable.Min(ParallelQuery, Func) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.ParallelEnumerable.Min(ParallelQuery, Func) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.ParallelEnumerable.Min(ParallelQuery, Func) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.ParallelEnumerable.Min(ParallelQuery, Func) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.ParallelEnumerable.Min(ParallelQuery, Func) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.ParallelEnumerable.Min(ParallelQuery, Func>) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.ParallelEnumerable.Min(ParallelQuery, Func>) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.ParallelEnumerable.Min(ParallelQuery, Func>) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.ParallelEnumerable.Min(ParallelQuery, Func>) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.ParallelEnumerable.Min(ParallelQuery, Func>) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.ParallelEnumerable.Min(ParallelQuery, Func) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.ParallelEnumerable.OfType(ParallelQuery) | parameter 0 [[]] -> return [[]] | true | -| System.Linq.ParallelEnumerable.OrderBy(ParallelQuery, Func) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.ParallelEnumerable.OrderBy(ParallelQuery, Func) | parameter 0 [[]] -> return [[]] | true | -| System.Linq.ParallelEnumerable.OrderBy(ParallelQuery, Func, IComparer) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.ParallelEnumerable.OrderBy(ParallelQuery, Func, IComparer) | parameter 0 [[]] -> return [[]] | true | -| System.Linq.ParallelEnumerable.OrderByDescending(ParallelQuery, Func) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.ParallelEnumerable.OrderByDescending(ParallelQuery, Func) | parameter 0 [[]] -> return [[]] | true | -| System.Linq.ParallelEnumerable.OrderByDescending(ParallelQuery, Func, IComparer) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.ParallelEnumerable.OrderByDescending(ParallelQuery, Func, IComparer) | parameter 0 [[]] -> return [[]] | true | -| System.Linq.ParallelEnumerable.Reverse(ParallelQuery) | parameter 0 [[]] -> return [[]] | true | -| System.Linq.ParallelEnumerable.Select(ParallelQuery, Func) | deleget output from parameter 1 -> return [[]] | true | -| System.Linq.ParallelEnumerable.Select(ParallelQuery, Func) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.ParallelEnumerable.Select(ParallelQuery, Func) | deleget output from parameter 1 -> return [[]] | true | -| System.Linq.ParallelEnumerable.Select(ParallelQuery, Func) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.ParallelEnumerable.SelectMany(ParallelQuery, Func>, Func) | deleget output from parameter 1 [[]] -> parameter 1 of delegate parameter 2 | true | -| System.Linq.ParallelEnumerable.SelectMany(ParallelQuery, Func>, Func) | deleget output from parameter 2 -> return [[]] | true | -| System.Linq.ParallelEnumerable.SelectMany(ParallelQuery, Func>, Func) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.ParallelEnumerable.SelectMany(ParallelQuery, Func>, Func) | parameter 0 [[]] -> parameter 0 of delegate parameter 2 | true | -| System.Linq.ParallelEnumerable.SelectMany(ParallelQuery, Func>, Func) | deleget output from parameter 1 [[]] -> parameter 1 of delegate parameter 2 | true | -| System.Linq.ParallelEnumerable.SelectMany(ParallelQuery, Func>, Func) | deleget output from parameter 2 -> return [[]] | true | -| System.Linq.ParallelEnumerable.SelectMany(ParallelQuery, Func>, Func) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.ParallelEnumerable.SelectMany(ParallelQuery, Func>, Func) | parameter 0 [[]] -> parameter 0 of delegate parameter 2 | true | -| System.Linq.ParallelEnumerable.SelectMany(ParallelQuery, Func>) | deleget output from parameter 1 -> return [[]] | true | -| System.Linq.ParallelEnumerable.SelectMany(ParallelQuery, Func>) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.ParallelEnumerable.SelectMany(ParallelQuery, Func>) | deleget output from parameter 1 -> return [[]] | true | -| System.Linq.ParallelEnumerable.SelectMany(ParallelQuery, Func>) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.ParallelEnumerable.Single(ParallelQuery) | parameter 0 [[]] -> return | true | -| System.Linq.ParallelEnumerable.Single(ParallelQuery, Func) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.ParallelEnumerable.Single(ParallelQuery, Func) | parameter 0 [[]] -> return | true | -| System.Linq.ParallelEnumerable.SingleOrDefault(ParallelQuery) | parameter 0 [[]] -> return | true | -| System.Linq.ParallelEnumerable.SingleOrDefault(ParallelQuery, Func) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.ParallelEnumerable.SingleOrDefault(ParallelQuery, Func) | parameter 0 [[]] -> return | true | -| System.Linq.ParallelEnumerable.Skip(ParallelQuery, int) | parameter 0 [[]] -> return [[]] | true | -| System.Linq.ParallelEnumerable.SkipWhile(ParallelQuery, Func) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.ParallelEnumerable.SkipWhile(ParallelQuery, Func) | parameter 0 [[]] -> return [[]] | true | -| System.Linq.ParallelEnumerable.SkipWhile(ParallelQuery, Func) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.ParallelEnumerable.SkipWhile(ParallelQuery, Func) | parameter 0 [[]] -> return [[]] | true | -| System.Linq.ParallelEnumerable.Sum(ParallelQuery, Func) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.ParallelEnumerable.Sum(ParallelQuery, Func) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.ParallelEnumerable.Sum(ParallelQuery, Func) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.ParallelEnumerable.Sum(ParallelQuery, Func) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.ParallelEnumerable.Sum(ParallelQuery, Func>) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.ParallelEnumerable.Sum(ParallelQuery, Func>) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.ParallelEnumerable.Sum(ParallelQuery, Func>) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.ParallelEnumerable.Sum(ParallelQuery, Func>) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.ParallelEnumerable.Sum(ParallelQuery, Func>) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.ParallelEnumerable.Sum(ParallelQuery, Func) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.ParallelEnumerable.Take(ParallelQuery, int) | parameter 0 [[]] -> return [[]] | true | -| System.Linq.ParallelEnumerable.TakeWhile(ParallelQuery, Func) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.ParallelEnumerable.TakeWhile(ParallelQuery, Func) | parameter 0 [[]] -> return [[]] | true | -| System.Linq.ParallelEnumerable.TakeWhile(ParallelQuery, Func) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.ParallelEnumerable.TakeWhile(ParallelQuery, Func) | parameter 0 [[]] -> return [[]] | true | -| System.Linq.ParallelEnumerable.ThenBy(OrderedParallelQuery, Func) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.ParallelEnumerable.ThenBy(OrderedParallelQuery, Func) | parameter 0 [[]] -> return [[]] | true | -| System.Linq.ParallelEnumerable.ThenBy(OrderedParallelQuery, Func, IComparer) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.ParallelEnumerable.ThenBy(OrderedParallelQuery, Func, IComparer) | parameter 0 [[]] -> return [[]] | true | -| System.Linq.ParallelEnumerable.ThenByDescending(OrderedParallelQuery, Func) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.ParallelEnumerable.ThenByDescending(OrderedParallelQuery, Func) | parameter 0 [[]] -> return [[]] | true | -| System.Linq.ParallelEnumerable.ThenByDescending(OrderedParallelQuery, Func, IComparer) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.ParallelEnumerable.ThenByDescending(OrderedParallelQuery, Func, IComparer) | parameter 0 [[]] -> return [[]] | true | -| System.Linq.ParallelEnumerable.ToArray(ParallelQuery) | parameter 0 [[]] -> return [[]] | true | -| System.Linq.ParallelEnumerable.ToDictionary(ParallelQuery, Func, Func) | deleget output from parameter 2 -> return [[]] | true | -| System.Linq.ParallelEnumerable.ToDictionary(ParallelQuery, Func, Func) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.ParallelEnumerable.ToDictionary(ParallelQuery, Func, Func) | parameter 0 [[]] -> parameter 0 of delegate parameter 2 | true | -| System.Linq.ParallelEnumerable.ToDictionary(ParallelQuery, Func, Func, IEqualityComparer) | deleget output from parameter 2 -> return [[]] | true | -| System.Linq.ParallelEnumerable.ToDictionary(ParallelQuery, Func, Func, IEqualityComparer) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.ParallelEnumerable.ToDictionary(ParallelQuery, Func, Func, IEqualityComparer) | parameter 0 [[]] -> parameter 0 of delegate parameter 2 | true | -| System.Linq.ParallelEnumerable.ToDictionary(ParallelQuery, Func) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.ParallelEnumerable.ToDictionary(ParallelQuery, Func) | parameter 0 [[]] -> return [[]] | true | -| System.Linq.ParallelEnumerable.ToDictionary(ParallelQuery, Func, IEqualityComparer) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.ParallelEnumerable.ToDictionary(ParallelQuery, Func, IEqualityComparer) | parameter 0 [[]] -> return [[]] | true | -| System.Linq.ParallelEnumerable.ToList(ParallelQuery) | parameter 0 [[]] -> return [[]] | true | -| System.Linq.ParallelEnumerable.ToLookup(ParallelQuery, Func, Func) | deleget output from parameter 2 -> return [[]] | true | -| System.Linq.ParallelEnumerable.ToLookup(ParallelQuery, Func, Func) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.ParallelEnumerable.ToLookup(ParallelQuery, Func, Func) | parameter 0 [[]] -> parameter 0 of delegate parameter 2 | true | -| System.Linq.ParallelEnumerable.ToLookup(ParallelQuery, Func, Func, IEqualityComparer) | deleget output from parameter 2 -> return [[]] | true | -| System.Linq.ParallelEnumerable.ToLookup(ParallelQuery, Func, Func, IEqualityComparer) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.ParallelEnumerable.ToLookup(ParallelQuery, Func, Func, IEqualityComparer) | parameter 0 [[]] -> parameter 0 of delegate parameter 2 | true | -| System.Linq.ParallelEnumerable.ToLookup(ParallelQuery, Func) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.ParallelEnumerable.ToLookup(ParallelQuery, Func) | parameter 0 [[]] -> return [[]] | true | -| System.Linq.ParallelEnumerable.ToLookup(ParallelQuery, Func, IEqualityComparer) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.ParallelEnumerable.ToLookup(ParallelQuery, Func, IEqualityComparer) | parameter 0 [[]] -> return [[]] | true | -| System.Linq.ParallelEnumerable.Union(ParallelQuery, IEnumerable) | parameter 0 [[]] -> return [[]] | true | -| System.Linq.ParallelEnumerable.Union(ParallelQuery, IEnumerable) | parameter 1 [[]] -> return [[]] | true | -| System.Linq.ParallelEnumerable.Union(ParallelQuery, IEnumerable, IEqualityComparer) | parameter 0 [[]] -> return [[]] | true | -| System.Linq.ParallelEnumerable.Union(ParallelQuery, IEnumerable, IEqualityComparer) | parameter 1 [[]] -> return [[]] | true | -| System.Linq.ParallelEnumerable.Union(ParallelQuery, ParallelQuery) | parameter 0 [[]] -> return [[]] | true | -| System.Linq.ParallelEnumerable.Union(ParallelQuery, ParallelQuery) | parameter 1 [[]] -> return [[]] | true | -| System.Linq.ParallelEnumerable.Union(ParallelQuery, ParallelQuery, IEqualityComparer) | parameter 0 [[]] -> return [[]] | true | -| System.Linq.ParallelEnumerable.Union(ParallelQuery, ParallelQuery, IEqualityComparer) | parameter 1 [[]] -> return [[]] | true | -| System.Linq.ParallelEnumerable.Where(ParallelQuery, Func) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.ParallelEnumerable.Where(ParallelQuery, Func) | parameter 0 [[]] -> return [[]] | true | -| System.Linq.ParallelEnumerable.Where(ParallelQuery, Func) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.ParallelEnumerable.Where(ParallelQuery, Func) | parameter 0 [[]] -> return [[]] | true | -| System.Linq.ParallelEnumerable.Zip(ParallelQuery, IEnumerable, Func) | deleget output from parameter 2 -> return [[]] | true | -| System.Linq.ParallelEnumerable.Zip(ParallelQuery, IEnumerable, Func) | parameter 0 [[]] -> parameter 0 of delegate parameter 2 | true | -| System.Linq.ParallelEnumerable.Zip(ParallelQuery, IEnumerable, Func) | parameter 1 [[]] -> parameter 1 of delegate parameter 2 | true | -| System.Linq.ParallelEnumerable.Zip(ParallelQuery, ParallelQuery, Func) | deleget output from parameter 2 -> return [[]] | true | -| System.Linq.ParallelEnumerable.Zip(ParallelQuery, ParallelQuery, Func) | parameter 0 [[]] -> parameter 0 of delegate parameter 2 | true | -| System.Linq.ParallelEnumerable.Zip(ParallelQuery, ParallelQuery, Func) | parameter 1 [[]] -> parameter 1 of delegate parameter 2 | true | -| System.Linq.ParallelQuery.GetEnumerator() | this parameter [[]] -> return [Current] | true | -| System.Linq.Queryable.Aggregate(IQueryable, TAccumulate, Expression>, Expression>) | deleget output from parameter 2 -> parameter 0 of delegate parameter 3 | true | -| System.Linq.Queryable.Aggregate(IQueryable, TAccumulate, Expression>, Expression>) | deleget output from parameter 3 -> return | true | -| System.Linq.Queryable.Aggregate(IQueryable, TAccumulate, Expression>, Expression>) | parameter 0 [[]] -> parameter 1 of delegate parameter 2 | true | -| System.Linq.Queryable.Aggregate(IQueryable, TAccumulate, Expression>, Expression>) | parameter 1 -> parameter 0 of delegate parameter 2 | true | -| System.Linq.Queryable.Aggregate(IQueryable, TAccumulate, Expression>) | deleget output from parameter 2 -> return | true | -| System.Linq.Queryable.Aggregate(IQueryable, TAccumulate, Expression>) | parameter 0 [[]] -> parameter 1 of delegate parameter 2 | true | -| System.Linq.Queryable.Aggregate(IQueryable, TAccumulate, Expression>) | parameter 1 -> parameter 0 of delegate parameter 2 | true | -| System.Linq.Queryable.Aggregate(IQueryable, Expression>) | deleget output from parameter 1 -> return | true | -| System.Linq.Queryable.Aggregate(IQueryable, Expression>) | parameter 0 [[]] -> parameter 1 of delegate parameter 1 | true | -| System.Linq.Queryable.All(IQueryable, Expression>) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.Queryable.Any(IQueryable, Expression>) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.Queryable.AsQueryable(IEnumerable) | parameter 0 [[]] -> return [[]] | true | -| System.Linq.Queryable.AsQueryable(IEnumerable) | parameter 0 [[]] -> return [[]] | true | -| System.Linq.Queryable.Average(IQueryable, Expression>) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.Queryable.Average(IQueryable, Expression>) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.Queryable.Average(IQueryable, Expression>) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.Queryable.Average(IQueryable, Expression>) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.Queryable.Average(IQueryable, Expression>>) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.Queryable.Average(IQueryable, Expression>>) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.Queryable.Average(IQueryable, Expression>>) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.Queryable.Average(IQueryable, Expression>>) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.Queryable.Average(IQueryable, Expression>>) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.Queryable.Average(IQueryable, Expression>) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.Queryable.Cast(IQueryable) | parameter 0 [[]] -> return [[]] | true | -| System.Linq.Queryable.Concat(IQueryable, IEnumerable) | parameter 0 [[]] -> return [[]] | true | -| System.Linq.Queryable.Concat(IQueryable, IEnumerable) | parameter 1 [[]] -> return [[]] | true | -| System.Linq.Queryable.Count(IQueryable, Expression>) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.Queryable.DefaultIfEmpty(IQueryable) | parameter 0 [[]] -> return | true | -| System.Linq.Queryable.DefaultIfEmpty(IQueryable, TSource) | parameter 0 [[]] -> return | true | -| System.Linq.Queryable.DefaultIfEmpty(IQueryable, TSource) | parameter 1 -> return | true | -| System.Linq.Queryable.Distinct(IQueryable) | parameter 0 [[]] -> return [[]] | true | -| System.Linq.Queryable.Distinct(IQueryable, IEqualityComparer) | parameter 0 [[]] -> return [[]] | true | -| System.Linq.Queryable.ElementAt(IQueryable, int) | parameter 0 [[]] -> return | true | -| System.Linq.Queryable.ElementAtOrDefault(IQueryable, int) | parameter 0 [[]] -> return | true | -| System.Linq.Queryable.Except(IQueryable, IEnumerable) | parameter 0 [[]] -> return | true | -| System.Linq.Queryable.Except(IQueryable, IEnumerable, IEqualityComparer) | parameter 0 [[]] -> return | true | -| System.Linq.Queryable.First(IQueryable) | parameter 0 [[]] -> return | true | -| System.Linq.Queryable.First(IQueryable, Expression>) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.Queryable.First(IQueryable, Expression>) | parameter 0 [[]] -> return | true | -| System.Linq.Queryable.FirstOrDefault(IQueryable) | parameter 0 [[]] -> return | true | -| System.Linq.Queryable.FirstOrDefault(IQueryable, Expression>) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.Queryable.FirstOrDefault(IQueryable, Expression>) | parameter 0 [[]] -> return | true | -| System.Linq.Queryable.GroupBy(IQueryable, Expression>, Expression>, Expression,TResult>>) | deleget output from parameter 1 -> parameter 0 of delegate parameter 2 | true | -| System.Linq.Queryable.GroupBy(IQueryable, Expression>, Expression>, Expression,TResult>>) | deleget output from parameter 2 -> parameter 1 of delegate parameter 3 [[]] | true | -| System.Linq.Queryable.GroupBy(IQueryable, Expression>, Expression>, Expression,TResult>>) | deleget output from parameter 3 -> return [[]] | true | -| System.Linq.Queryable.GroupBy(IQueryable, Expression>, Expression>, Expression,TResult>>) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.Queryable.GroupBy(IQueryable, Expression>, Expression>, Expression,TResult>>) | parameter 0 [[]] -> parameter 0 of delegate parameter 2 | true | -| System.Linq.Queryable.GroupBy(IQueryable, Expression>, Expression>, Expression,TResult>>, IEqualityComparer) | deleget output from parameter 1 -> parameter 0 of delegate parameter 2 | true | -| System.Linq.Queryable.GroupBy(IQueryable, Expression>, Expression>, Expression,TResult>>, IEqualityComparer) | deleget output from parameter 2 -> parameter 1 of delegate parameter 3 [[]] | true | -| System.Linq.Queryable.GroupBy(IQueryable, Expression>, Expression>, Expression,TResult>>, IEqualityComparer) | deleget output from parameter 3 -> return [[]] | true | -| System.Linq.Queryable.GroupBy(IQueryable, Expression>, Expression>, Expression,TResult>>, IEqualityComparer) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.Queryable.GroupBy(IQueryable, Expression>, Expression>, Expression,TResult>>, IEqualityComparer) | parameter 0 [[]] -> parameter 0 of delegate parameter 2 | true | -| System.Linq.Queryable.GroupBy(IQueryable, Expression>, Expression>) | deleget output from parameter 2 -> return [[]] | true | -| System.Linq.Queryable.GroupBy(IQueryable, Expression>, Expression>) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.Queryable.GroupBy(IQueryable, Expression>, Expression>, IEqualityComparer) | deleget output from parameter 1 -> parameter 0 of delegate parameter 2 | true | -| System.Linq.Queryable.GroupBy(IQueryable, Expression>, Expression>, IEqualityComparer) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.Queryable.GroupBy(IQueryable, Expression>, Expression>, IEqualityComparer) | parameter 0 [[]] -> parameter 0 of delegate parameter 2 | true | -| System.Linq.Queryable.GroupBy(IQueryable, Expression>, Expression,TResult>>) | deleget output from parameter 2 -> return [[]] | true | -| System.Linq.Queryable.GroupBy(IQueryable, Expression>, Expression,TResult>>) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.Queryable.GroupBy(IQueryable, Expression>, Expression,TResult>>, IEqualityComparer) | deleget output from parameter 1 -> parameter 0 of delegate parameter 2 | true | -| System.Linq.Queryable.GroupBy(IQueryable, Expression>, Expression,TResult>>, IEqualityComparer) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.Queryable.GroupBy(IQueryable, Expression>, Expression,TResult>>, IEqualityComparer) | parameter 0 [[]] -> parameter 0 of delegate parameter 2 | true | -| System.Linq.Queryable.GroupBy(IQueryable, Expression>) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.Queryable.GroupBy(IQueryable, Expression>, IEqualityComparer) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.Queryable.GroupJoin(IQueryable, IEnumerable, Expression>, Expression>, Expression,TResult>>) | deleget output from parameter 4 -> return [[]] | true | -| System.Linq.Queryable.GroupJoin(IQueryable, IEnumerable, Expression>, Expression>, Expression,TResult>>) | parameter 0 [[]] -> parameter 0 of delegate parameter 2 | true | -| System.Linq.Queryable.GroupJoin(IQueryable, IEnumerable, Expression>, Expression>, Expression,TResult>>) | parameter 0 [[]] -> parameter 0 of delegate parameter 4 | true | -| System.Linq.Queryable.GroupJoin(IQueryable, IEnumerable, Expression>, Expression>, Expression,TResult>>) | parameter 1 [[]] -> parameter 0 of delegate parameter 3 | true | -| System.Linq.Queryable.GroupJoin(IQueryable, IEnumerable, Expression>, Expression>, Expression,TResult>>) | parameter 1 [[]] -> parameter 1 of delegate parameter 4 | true | -| System.Linq.Queryable.GroupJoin(IQueryable, IEnumerable, Expression>, Expression>, Expression,TResult>>, IEqualityComparer) | deleget output from parameter 4 -> return [[]] | true | -| System.Linq.Queryable.GroupJoin(IQueryable, IEnumerable, Expression>, Expression>, Expression,TResult>>, IEqualityComparer) | parameter 0 [[]] -> parameter 0 of delegate parameter 2 | true | -| System.Linq.Queryable.GroupJoin(IQueryable, IEnumerable, Expression>, Expression>, Expression,TResult>>, IEqualityComparer) | parameter 0 [[]] -> parameter 0 of delegate parameter 4 | true | -| System.Linq.Queryable.GroupJoin(IQueryable, IEnumerable, Expression>, Expression>, Expression,TResult>>, IEqualityComparer) | parameter 1 [[]] -> parameter 0 of delegate parameter 3 | true | -| System.Linq.Queryable.GroupJoin(IQueryable, IEnumerable, Expression>, Expression>, Expression,TResult>>, IEqualityComparer) | parameter 1 [[]] -> parameter 1 of delegate parameter 4 | true | -| System.Linq.Queryable.Intersect(IQueryable, IEnumerable) | parameter 0 [[]] -> return [[]] | true | -| System.Linq.Queryable.Intersect(IQueryable, IEnumerable) | parameter 1 [[]] -> return [[]] | true | -| System.Linq.Queryable.Intersect(IQueryable, IEnumerable, IEqualityComparer) | parameter 0 [[]] -> return [[]] | true | -| System.Linq.Queryable.Intersect(IQueryable, IEnumerable, IEqualityComparer) | parameter 1 [[]] -> return [[]] | true | -| System.Linq.Queryable.Join(IQueryable, IEnumerable, Expression>, Expression>, Expression>) | deleget output from parameter 4 -> return [[]] | true | -| System.Linq.Queryable.Join(IQueryable, IEnumerable, Expression>, Expression>, Expression>) | parameter 0 [[]] -> parameter 0 of delegate parameter 2 | true | -| System.Linq.Queryable.Join(IQueryable, IEnumerable, Expression>, Expression>, Expression>) | parameter 0 [[]] -> parameter 0 of delegate parameter 4 | true | -| System.Linq.Queryable.Join(IQueryable, IEnumerable, Expression>, Expression>, Expression>) | parameter 1 [[]] -> parameter 0 of delegate parameter 3 | true | -| System.Linq.Queryable.Join(IQueryable, IEnumerable, Expression>, Expression>, Expression>) | parameter 1 [[]] -> parameter 1 of delegate parameter 4 | true | -| System.Linq.Queryable.Join(IQueryable, IEnumerable, Expression>, Expression>, Expression>, IEqualityComparer) | deleget output from parameter 4 -> return [[]] | true | -| System.Linq.Queryable.Join(IQueryable, IEnumerable, Expression>, Expression>, Expression>, IEqualityComparer) | parameter 0 [[]] -> parameter 0 of delegate parameter 2 | true | -| System.Linq.Queryable.Join(IQueryable, IEnumerable, Expression>, Expression>, Expression>, IEqualityComparer) | parameter 0 [[]] -> parameter 0 of delegate parameter 4 | true | -| System.Linq.Queryable.Join(IQueryable, IEnumerable, Expression>, Expression>, Expression>, IEqualityComparer) | parameter 1 [[]] -> parameter 0 of delegate parameter 3 | true | -| System.Linq.Queryable.Join(IQueryable, IEnumerable, Expression>, Expression>, Expression>, IEqualityComparer) | parameter 1 [[]] -> parameter 1 of delegate parameter 4 | true | -| System.Linq.Queryable.Last(IQueryable) | parameter 0 [[]] -> return | true | -| System.Linq.Queryable.Last(IQueryable, Expression>) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.Queryable.Last(IQueryable, Expression>) | parameter 0 [[]] -> return | true | -| System.Linq.Queryable.LastOrDefault(IQueryable) | parameter 0 [[]] -> return | true | -| System.Linq.Queryable.LastOrDefault(IQueryable, Expression>) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.Queryable.LastOrDefault(IQueryable, Expression>) | parameter 0 [[]] -> return | true | -| System.Linq.Queryable.LongCount(IQueryable, Expression>) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.Queryable.Max(IQueryable, Expression>) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.Queryable.Min(IQueryable, Expression>) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.Queryable.OfType(IQueryable) | parameter 0 [[]] -> return [[]] | true | -| System.Linq.Queryable.OrderBy(IQueryable, Expression>) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.Queryable.OrderBy(IQueryable, Expression>) | parameter 0 [[]] -> return [[]] | true | -| System.Linq.Queryable.OrderBy(IQueryable, Expression>, IComparer) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.Queryable.OrderBy(IQueryable, Expression>, IComparer) | parameter 0 [[]] -> return [[]] | true | -| System.Linq.Queryable.OrderByDescending(IQueryable, Expression>) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.Queryable.OrderByDescending(IQueryable, Expression>) | parameter 0 [[]] -> return [[]] | true | -| System.Linq.Queryable.OrderByDescending(IQueryable, Expression>, IComparer) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.Queryable.OrderByDescending(IQueryable, Expression>, IComparer) | parameter 0 [[]] -> return [[]] | true | -| System.Linq.Queryable.Reverse(IQueryable) | parameter 0 [[]] -> return [[]] | true | -| System.Linq.Queryable.Select(IQueryable, Expression>) | deleget output from parameter 1 -> return [[]] | true | -| System.Linq.Queryable.Select(IQueryable, Expression>) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.Queryable.Select(IQueryable, Expression>) | deleget output from parameter 1 -> return [[]] | true | -| System.Linq.Queryable.Select(IQueryable, Expression>) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.Queryable.SelectMany(IQueryable, Expression>>, Expression>) | deleget output from parameter 1 [[]] -> parameter 1 of delegate parameter 2 | true | -| System.Linq.Queryable.SelectMany(IQueryable, Expression>>, Expression>) | deleget output from parameter 2 -> return [[]] | true | -| System.Linq.Queryable.SelectMany(IQueryable, Expression>>, Expression>) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.Queryable.SelectMany(IQueryable, Expression>>, Expression>) | parameter 0 [[]] -> parameter 0 of delegate parameter 2 | true | -| System.Linq.Queryable.SelectMany(IQueryable, Expression>>, Expression>) | deleget output from parameter 1 [[]] -> parameter 1 of delegate parameter 2 | true | -| System.Linq.Queryable.SelectMany(IQueryable, Expression>>, Expression>) | deleget output from parameter 2 -> return [[]] | true | -| System.Linq.Queryable.SelectMany(IQueryable, Expression>>, Expression>) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.Queryable.SelectMany(IQueryable, Expression>>, Expression>) | parameter 0 [[]] -> parameter 0 of delegate parameter 2 | true | -| System.Linq.Queryable.SelectMany(IQueryable, Expression>>) | deleget output from parameter 1 -> return [[]] | true | -| System.Linq.Queryable.SelectMany(IQueryable, Expression>>) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.Queryable.SelectMany(IQueryable, Expression>>) | deleget output from parameter 1 -> return [[]] | true | -| System.Linq.Queryable.SelectMany(IQueryable, Expression>>) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.Queryable.Single(IQueryable) | parameter 0 [[]] -> return | true | -| System.Linq.Queryable.Single(IQueryable, Expression>) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.Queryable.Single(IQueryable, Expression>) | parameter 0 [[]] -> return | true | -| System.Linq.Queryable.SingleOrDefault(IQueryable) | parameter 0 [[]] -> return | true | -| System.Linq.Queryable.SingleOrDefault(IQueryable, Expression>) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.Queryable.SingleOrDefault(IQueryable, Expression>) | parameter 0 [[]] -> return | true | -| System.Linq.Queryable.Skip(IQueryable, int) | parameter 0 [[]] -> return [[]] | true | -| System.Linq.Queryable.SkipWhile(IQueryable, Expression>) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.Queryable.SkipWhile(IQueryable, Expression>) | parameter 0 [[]] -> return [[]] | true | -| System.Linq.Queryable.SkipWhile(IQueryable, Expression>) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.Queryable.SkipWhile(IQueryable, Expression>) | parameter 0 [[]] -> return [[]] | true | -| System.Linq.Queryable.Sum(IQueryable, Expression>) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.Queryable.Sum(IQueryable, Expression>) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.Queryable.Sum(IQueryable, Expression>) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.Queryable.Sum(IQueryable, Expression>) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.Queryable.Sum(IQueryable, Expression>>) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.Queryable.Sum(IQueryable, Expression>>) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.Queryable.Sum(IQueryable, Expression>>) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.Queryable.Sum(IQueryable, Expression>>) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.Queryable.Sum(IQueryable, Expression>>) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.Queryable.Sum(IQueryable, Expression>) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.Queryable.Take(IQueryable, int) | parameter 0 [[]] -> return [[]] | true | -| System.Linq.Queryable.TakeWhile(IQueryable, Expression>) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.Queryable.TakeWhile(IQueryable, Expression>) | parameter 0 [[]] -> return [[]] | true | -| System.Linq.Queryable.TakeWhile(IQueryable, Expression>) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.Queryable.TakeWhile(IQueryable, Expression>) | parameter 0 [[]] -> return [[]] | true | -| System.Linq.Queryable.ThenBy(IOrderedQueryable, Expression>) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.Queryable.ThenBy(IOrderedQueryable, Expression>) | parameter 0 [[]] -> return [[]] | true | -| System.Linq.Queryable.ThenBy(IOrderedQueryable, Expression>, IComparer) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.Queryable.ThenBy(IOrderedQueryable, Expression>, IComparer) | parameter 0 [[]] -> return [[]] | true | -| System.Linq.Queryable.ThenByDescending(IOrderedQueryable, Expression>) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.Queryable.ThenByDescending(IOrderedQueryable, Expression>) | parameter 0 [[]] -> return [[]] | true | -| System.Linq.Queryable.ThenByDescending(IOrderedQueryable, Expression>, IComparer) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.Queryable.ThenByDescending(IOrderedQueryable, Expression>, IComparer) | parameter 0 [[]] -> return [[]] | true | -| System.Linq.Queryable.Union(IQueryable, IEnumerable) | parameter 0 [[]] -> return [[]] | true | -| System.Linq.Queryable.Union(IQueryable, IEnumerable) | parameter 1 [[]] -> return [[]] | true | -| System.Linq.Queryable.Union(IQueryable, IEnumerable, IEqualityComparer) | parameter 0 [[]] -> return [[]] | true | -| System.Linq.Queryable.Union(IQueryable, IEnumerable, IEqualityComparer) | parameter 1 [[]] -> return [[]] | true | -| System.Linq.Queryable.Where(IQueryable, Expression>) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.Queryable.Where(IQueryable, Expression>) | parameter 0 [[]] -> return [[]] | true | -| System.Linq.Queryable.Where(IQueryable, Expression>) | parameter 0 [[]] -> parameter 0 of delegate parameter 1 | true | -| System.Linq.Queryable.Where(IQueryable, Expression>) | parameter 0 [[]] -> return [[]] | true | -| System.Linq.Queryable.Zip(IQueryable, IEnumerable, Expression>) | deleget output from parameter 2 -> return [[]] | true | -| System.Linq.Queryable.Zip(IQueryable, IEnumerable, Expression>) | parameter 0 [[]] -> parameter 0 of delegate parameter 2 | true | -| System.Linq.Queryable.Zip(IQueryable, IEnumerable, Expression>) | parameter 1 [[]] -> parameter 1 of delegate parameter 2 | true | -| System.Net.Cookie.get_Value() | this parameter -> return | false | -| System.Net.CookieCollection.Add(Cookie) | parameter 0 -> this parameter [[]] | true | -| System.Net.CookieCollection.Add(CookieCollection) | parameter 0 -> this parameter [[]] | true | -| System.Net.CookieCollection.CopyTo(Array, int) | this parameter [[]] -> parameter 0 [[]] | true | -| System.Net.CookieCollection.CopyTo(Cookie[], int) | this parameter [[]] -> parameter 0 [[]] | true | -| System.Net.CookieCollection.GetEnumerator() | this parameter [[]] -> return [Current] | true | -| System.Net.CredentialCache.GetEnumerator() | this parameter [[]] -> return [Current] | true | -| System.Net.HttpListenerPrefixCollection.Add(string) | parameter 0 -> this parameter [[]] | true | -| System.Net.HttpListenerPrefixCollection.CopyTo(Array, int) | this parameter [[]] -> parameter 0 [[]] | true | -| System.Net.HttpListenerPrefixCollection.CopyTo(String[], int) | this parameter [[]] -> parameter 0 [[]] | true | -| System.Net.HttpListenerPrefixCollection.GetEnumerator() | this parameter [[]] -> return [Current] | true | -| System.Net.HttpRequestStream.BeginRead(Byte[], int, int, AsyncCallback, object) | this parameter -> parameter 0 | false | -| System.Net.HttpRequestStream.BeginWrite(Byte[], int, int, AsyncCallback, object) | parameter 0 -> this parameter | false | -| System.Net.HttpRequestStream.Read(Byte[], int, int) | this parameter -> parameter 0 | false | -| System.Net.HttpRequestStream.Write(Byte[], int, int) | parameter 0 -> this parameter | false | -| System.Net.HttpResponseStream.BeginRead(Byte[], int, int, AsyncCallback, object) | this parameter -> parameter 0 | false | -| System.Net.HttpResponseStream.BeginWrite(Byte[], int, int, AsyncCallback, object) | parameter 0 -> this parameter | false | -| System.Net.HttpResponseStream.Read(Byte[], int, int) | this parameter -> parameter 0 | false | -| System.Net.HttpResponseStream.Write(Byte[], int, int) | parameter 0 -> this parameter | false | -| System.Net.NetworkInformation.IPAddressCollection.Add(IPAddress) | parameter 0 -> this parameter [[]] | true | -| System.Net.NetworkInformation.IPAddressCollection.CopyTo(IPAddress[], int) | this parameter [[]] -> parameter 0 [[]] | true | -| System.Net.NetworkInformation.IPAddressCollection.GetEnumerator() | this parameter [[]] -> return [Current] | true | -| System.Net.Security.CipherSuitesPolicy.d__6.GetEnumerator() | this parameter [[]] -> return [Current] | true | -| System.Net.Security.NegotiateStream.BeginRead(Byte[], int, int, AsyncCallback, object) | this parameter -> parameter 0 | false | -| System.Net.Security.NegotiateStream.BeginWrite(Byte[], int, int, AsyncCallback, object) | parameter 0 -> this parameter | false | -| System.Net.Security.NegotiateStream.Read(Byte[], int, int) | this parameter -> parameter 0 | false | -| System.Net.Security.NegotiateStream.ReadAsync(Byte[], int, int, CancellationToken) | this parameter -> parameter 0 | false | -| System.Net.Security.NegotiateStream.Write(Byte[], int, int) | parameter 0 -> this parameter | false | -| System.Net.Security.NegotiateStream.WriteAsync(Byte[], int, int, CancellationToken) | parameter 0 -> this parameter | false | -| System.Net.Security.SslStream.BeginRead(Byte[], int, int, AsyncCallback, object) | this parameter -> parameter 0 | false | -| System.Net.Security.SslStream.BeginWrite(Byte[], int, int, AsyncCallback, object) | parameter 0 -> this parameter | false | -| System.Net.Security.SslStream.Read(Byte[], int, int) | this parameter -> parameter 0 | false | -| System.Net.Security.SslStream.ReadAsync(Byte[], int, int, CancellationToken) | this parameter -> parameter 0 | false | -| System.Net.Security.SslStream.Write(Byte[], int, int) | parameter 0 -> this parameter | false | -| System.Net.Security.SslStream.WriteAsync(Byte[], int, int, CancellationToken) | parameter 0 -> this parameter | false | -| System.Net.WebUtility.HtmlEncode(string) | parameter 0 -> return | false | -| System.Net.WebUtility.HtmlEncode(string, TextWriter) | parameter 0 -> return | false | -| System.Net.WebUtility.UrlEncode(string) | parameter 0 -> return | false | -| System.Nullable<>.GetValueOrDefault() | this parameter [Value] -> return | true | -| System.Nullable<>.GetValueOrDefault(T) | parameter 0 -> return | true | -| System.Nullable<>.GetValueOrDefault(T) | this parameter [Value] -> return | true | -| System.Nullable<>.Nullable(T) | parameter 0 -> return [Value] | true | -| System.Nullable<>.get_HasValue() | this parameter [Value] -> return | false | -| System.Nullable<>.get_Value() | this parameter -> return | false | -| System.Reflection.TypeInfo.d__10.GetEnumerator() | this parameter [[]] -> return [Current] | true | -| System.Reflection.TypeInfo.d__22.GetEnumerator() | this parameter [[]] -> return [Current] | true | -| System.Resources.ResourceFallbackManager.GetEnumerator() | this parameter [[]] -> return [Current] | true | -| System.Resources.ResourceReader.GetEnumerator() | this parameter [[]] -> return [Current] | true | -| System.Resources.ResourceSet.GetEnumerator() | this parameter [[]] -> return [Current] | true | -| System.Resources.RuntimeResourceSet.GetEnumerator() | this parameter [[]] -> return [Current] | true | -| System.Runtime.CompilerServices.ConditionalWeakTable<,>.GetEnumerator() | this parameter [[]] -> return [Current] | true | -| System.Runtime.CompilerServices.ConfiguredTaskAwaitable<>.ConfiguredTaskAwaiter.GetResult() | this parameter [m_task, Result] -> return | true | -| System.Runtime.CompilerServices.ConfiguredTaskAwaitable<>.GetAwaiter() | this parameter [m_configuredTaskAwaiter] -> return | true | -| System.Runtime.CompilerServices.ReadOnlyCollectionBuilder<>.Add(T) | parameter 0 -> this parameter [[]] | true | -| System.Runtime.CompilerServices.ReadOnlyCollectionBuilder<>.Add(object) | parameter 0 -> this parameter [[]] | true | -| System.Runtime.CompilerServices.ReadOnlyCollectionBuilder<>.CopyTo(Array, int) | this parameter [[]] -> parameter 0 [[]] | true | -| System.Runtime.CompilerServices.ReadOnlyCollectionBuilder<>.CopyTo(T[], int) | this parameter [[]] -> parameter 0 [[]] | true | -| System.Runtime.CompilerServices.ReadOnlyCollectionBuilder<>.GetEnumerator() | this parameter [[]] -> return [Current] | true | -| System.Runtime.CompilerServices.ReadOnlyCollectionBuilder<>.Insert(int, T) | parameter 1 -> this parameter [[]] | true | -| System.Runtime.CompilerServices.ReadOnlyCollectionBuilder<>.Insert(int, object) | parameter 1 -> this parameter [[]] | true | -| System.Runtime.CompilerServices.ReadOnlyCollectionBuilder<>.Reverse() | parameter 0 [[]] -> return [[]] | true | -| System.Runtime.CompilerServices.ReadOnlyCollectionBuilder<>.Reverse(int, int) | parameter 0 [[]] -> return [[]] | true | -| System.Runtime.CompilerServices.ReadOnlyCollectionBuilder<>.get_Item(int) | this parameter [[]] -> return | true | -| System.Runtime.CompilerServices.ReadOnlyCollectionBuilder<>.set_Item(int, T) | parameter 1 -> this parameter [[]] | true | -| System.Runtime.CompilerServices.ReadOnlyCollectionBuilder<>.set_Item(int, object) | parameter 1 -> this parameter [[]] | true | -| System.Runtime.CompilerServices.TaskAwaiter<>.GetResult() | this parameter [m_task, Result] -> return | true | -| System.Runtime.InteropServices.MemoryMarshal.d__15<>.GetEnumerator() | this parameter [[]] -> return [Current] | true | -| System.Runtime.Loader.AssemblyLoadContext.d__83.GetEnumerator() | this parameter [[]] -> return [Current] | true | -| System.Runtime.Loader.AssemblyLoadContext.d__53.GetEnumerator() | this parameter [[]] -> return [Current] | true | -| System.Runtime.Loader.LibraryNameVariation.d__5.GetEnumerator() | this parameter [[]] -> return [Current] | true | -| System.Security.Cryptography.CryptoStream.BeginRead(Byte[], int, int, AsyncCallback, object) | this parameter -> parameter 0 | false | -| System.Security.Cryptography.CryptoStream.BeginWrite(Byte[], int, int, AsyncCallback, object) | parameter 0 -> this parameter | false | -| System.Security.Cryptography.CryptoStream.Read(Byte[], int, int) | this parameter -> parameter 0 | false | -| System.Security.Cryptography.CryptoStream.ReadAsync(Byte[], int, int, CancellationToken) | this parameter -> parameter 0 | false | -| System.Security.Cryptography.CryptoStream.Write(Byte[], int, int) | parameter 0 -> this parameter | false | -| System.Security.Cryptography.CryptoStream.WriteAsync(Byte[], int, int, CancellationToken) | parameter 0 -> this parameter | false | -| System.Security.PermissionSet.CopyTo(Array, int) | this parameter [[]] -> parameter 0 [[]] | true | -| System.Security.PermissionSet.GetEnumerator() | this parameter [[]] -> return [Current] | true | -| System.String.Clone() | this parameter -> return | true | -| System.String.Concat(IEnumerable) | parameter 0 [[]] -> return | false | -| System.String.Concat(ReadOnlySpan, ReadOnlySpan) | parameter 0 -> return | false | -| System.String.Concat(ReadOnlySpan, ReadOnlySpan) | parameter 1 -> return | false | -| System.String.Concat(ReadOnlySpan, ReadOnlySpan, ReadOnlySpan) | parameter 0 -> return | false | -| System.String.Concat(ReadOnlySpan, ReadOnlySpan, ReadOnlySpan) | parameter 1 -> return | false | -| System.String.Concat(ReadOnlySpan, ReadOnlySpan, ReadOnlySpan) | parameter 2 -> return | false | -| System.String.Concat(ReadOnlySpan, ReadOnlySpan, ReadOnlySpan, ReadOnlySpan) | parameter 0 -> return | false | -| System.String.Concat(ReadOnlySpan, ReadOnlySpan, ReadOnlySpan, ReadOnlySpan) | parameter 1 -> return | false | -| System.String.Concat(ReadOnlySpan, ReadOnlySpan, ReadOnlySpan, ReadOnlySpan) | parameter 2 -> return | false | -| System.String.Concat(ReadOnlySpan, ReadOnlySpan, ReadOnlySpan, ReadOnlySpan) | parameter 3 -> return | false | -| System.String.Concat(object) | parameter 0 -> return | false | -| System.String.Concat(object, object) | parameter 0 -> return | false | -| System.String.Concat(object, object) | parameter 1 -> return | false | -| System.String.Concat(object, object, object) | parameter 0 -> return | false | -| System.String.Concat(object, object, object) | parameter 1 -> return | false | -| System.String.Concat(object, object, object) | parameter 2 -> return | false | -| System.String.Concat(params Object[]) | parameter 0 [[]] -> return | false | -| System.String.Concat(params String[]) | parameter 0 [[]] -> return | false | -| System.String.Concat(string, string) | parameter 0 -> return | false | -| System.String.Concat(string, string) | parameter 1 -> return | false | -| System.String.Concat(string, string, string) | parameter 0 -> return | false | -| System.String.Concat(string, string, string) | parameter 1 -> return | false | -| System.String.Concat(string, string, string) | parameter 2 -> return | false | -| System.String.Concat(string, string, string, string) | parameter 0 -> return | false | -| System.String.Concat(string, string, string, string) | parameter 1 -> return | false | -| System.String.Concat(string, string, string, string) | parameter 2 -> return | false | -| System.String.Concat(string, string, string, string) | parameter 3 -> return | false | -| System.String.Concat(IEnumerable) | parameter 0 [[]] -> return | false | -| System.String.Copy(string) | parameter 0 -> return | true | -| System.String.Format(IFormatProvider, string, object) | parameter 1 -> return | false | -| System.String.Format(IFormatProvider, string, object) | parameter 2 -> return | false | -| System.String.Format(IFormatProvider, string, object, object) | parameter 1 -> return | false | -| System.String.Format(IFormatProvider, string, object, object) | parameter 2 -> return | false | -| System.String.Format(IFormatProvider, string, object, object) | parameter 3 -> return | false | -| System.String.Format(IFormatProvider, string, object, object, object) | parameter 1 -> return | false | -| System.String.Format(IFormatProvider, string, object, object, object) | parameter 2 -> return | false | -| System.String.Format(IFormatProvider, string, object, object, object) | parameter 3 -> return | false | -| System.String.Format(IFormatProvider, string, object, object, object) | parameter 4 -> return | false | -| System.String.Format(IFormatProvider, string, params Object[]) | parameter 1 -> return | false | -| System.String.Format(IFormatProvider, string, params Object[]) | parameter 2 [[]] -> return | false | -| System.String.Format(string, object) | parameter 0 -> return | false | -| System.String.Format(string, object) | parameter 1 -> return | false | -| System.String.Format(string, object, object) | parameter 0 -> return | false | -| System.String.Format(string, object, object) | parameter 1 -> return | false | -| System.String.Format(string, object, object) | parameter 2 -> return | false | -| System.String.Format(string, object, object, object) | parameter 0 -> return | false | -| System.String.Format(string, object, object, object) | parameter 1 -> return | false | -| System.String.Format(string, object, object, object) | parameter 2 -> return | false | -| System.String.Format(string, object, object, object) | parameter 3 -> return | false | -| System.String.Format(string, params Object[]) | parameter 0 -> return | false | -| System.String.Format(string, params Object[]) | parameter 1 [[]] -> return | false | -| System.String.GetEnumerator() | this parameter [[]] -> return [Current] | true | -| System.String.Insert(int, string) | parameter 1 -> return | false | -| System.String.Insert(int, string) | this parameter -> return | false | -| System.String.Join(char, String[], int, int) | parameter 0 -> return | false | -| System.String.Join(char, String[], int, int) | parameter 1 [[]] -> return | false | -| System.String.Join(char, params Object[]) | parameter 0 -> return | false | -| System.String.Join(char, params Object[]) | parameter 1 [[]] -> return | false | -| System.String.Join(char, params String[]) | parameter 0 -> return | false | -| System.String.Join(char, params String[]) | parameter 1 [[]] -> return | false | -| System.String.Join(string, IEnumerable) | parameter 0 -> return | false | -| System.String.Join(string, IEnumerable) | parameter 1 [[]] -> return | false | -| System.String.Join(string, String[], int, int) | parameter 0 -> return | false | -| System.String.Join(string, String[], int, int) | parameter 1 [[]] -> return | false | -| System.String.Join(string, params Object[]) | parameter 0 -> return | false | -| System.String.Join(string, params Object[]) | parameter 1 [[]] -> return | false | -| System.String.Join(string, params String[]) | parameter 0 -> return | false | -| System.String.Join(string, params String[]) | parameter 1 [[]] -> return | false | -| System.String.Join(char, IEnumerable) | parameter 0 -> return | false | -| System.String.Join(char, IEnumerable) | parameter 1 [[]] -> return | false | -| System.String.Join(string, IEnumerable) | parameter 0 -> return | false | -| System.String.Join(string, IEnumerable) | parameter 1 [[]] -> return | false | -| System.String.Normalize() | this parameter -> return | false | -| System.String.Normalize(NormalizationForm) | this parameter -> return | false | -| System.String.PadLeft(int) | this parameter -> return | false | -| System.String.PadLeft(int, char) | this parameter -> return | false | -| System.String.PadRight(int) | this parameter -> return | false | -| System.String.PadRight(int, char) | this parameter -> return | false | -| System.String.Remove(int) | this parameter -> return | false | -| System.String.Remove(int, int) | this parameter -> return | false | -| System.String.Replace(char, char) | parameter 1 -> return | false | -| System.String.Replace(char, char) | this parameter -> return | false | -| System.String.Replace(string, string) | parameter 1 -> return | false | -| System.String.Replace(string, string) | this parameter -> return | false | -| System.String.Split(Char[], StringSplitOptions) | this parameter -> return [[]] | false | -| System.String.Split(Char[], int) | this parameter -> return [[]] | false | -| System.String.Split(Char[], int, StringSplitOptions) | this parameter -> return [[]] | false | -| System.String.Split(String[], StringSplitOptions) | this parameter -> return [[]] | false | -| System.String.Split(String[], int, StringSplitOptions) | this parameter -> return [[]] | false | -| System.String.Split(char, StringSplitOptions) | this parameter -> return [[]] | false | -| System.String.Split(char, int, StringSplitOptions) | this parameter -> return [[]] | false | -| System.String.Split(params Char[]) | this parameter -> return [[]] | false | -| System.String.Split(string, StringSplitOptions) | this parameter -> return [[]] | false | -| System.String.Split(string, int, StringSplitOptions) | this parameter -> return [[]] | false | -| System.String.String(Char[]) | parameter 0 [[]] -> return | false | -| System.String.String(Char[], int, int) | parameter 0 [[]] -> return | false | -| System.String.Substring(int) | this parameter -> return | false | -| System.String.Substring(int, int) | this parameter -> return | false | -| System.String.ToLower() | this parameter -> return | false | -| System.String.ToLower(CultureInfo) | this parameter -> return | false | -| System.String.ToLowerInvariant() | this parameter -> return | false | -| System.String.ToString() | this parameter -> return | true | -| System.String.ToString(IFormatProvider) | this parameter -> return | true | -| System.String.ToUpper() | this parameter -> return | false | -| System.String.ToUpper(CultureInfo) | this parameter -> return | false | -| System.String.ToUpperInvariant() | this parameter -> return | false | -| System.String.Trim() | this parameter -> return | false | -| System.String.Trim(char) | this parameter -> return | false | -| System.String.Trim(params Char[]) | this parameter -> return | false | -| System.String.TrimEnd() | this parameter -> return | false | -| System.String.TrimEnd(char) | this parameter -> return | false | -| System.String.TrimEnd(params Char[]) | this parameter -> return | false | -| System.String.TrimStart() | this parameter -> return | false | -| System.String.TrimStart(char) | this parameter -> return | false | -| System.String.TrimStart(params Char[]) | this parameter -> return | false | -| System.Text.Encoding.GetBytes(Char[]) | parameter 0 [[]] -> return | false | -| System.Text.Encoding.GetBytes(Char[], int, int) | parameter 0 [[]] -> return | false | -| System.Text.Encoding.GetBytes(Char[], int, int, Byte[], int) | parameter 0 [[]] -> return | false | -| System.Text.Encoding.GetBytes(ReadOnlySpan, Span) | parameter 0 -> return | false | -| System.Text.Encoding.GetBytes(char*, int, byte*, int) | parameter 0 -> return | false | -| System.Text.Encoding.GetBytes(char*, int, byte*, int, EncoderNLS) | parameter 0 -> return | false | -| System.Text.Encoding.GetBytes(string) | parameter 0 -> return | false | -| System.Text.Encoding.GetBytes(string, int, int) | parameter 0 -> return | false | -| System.Text.Encoding.GetBytes(string, int, int, Byte[], int) | parameter 0 -> return | false | -| System.Text.Encoding.GetChars(Byte[]) | parameter 0 [[]] -> return | false | -| System.Text.Encoding.GetChars(Byte[], int, int) | parameter 0 [[]] -> return | false | -| System.Text.Encoding.GetChars(Byte[], int, int, Char[], int) | parameter 0 [[]] -> return | false | -| System.Text.Encoding.GetChars(ReadOnlySpan, Span) | parameter 0 [[]] -> return | false | -| System.Text.Encoding.GetChars(byte*, int, char*, int) | parameter 0 [[]] -> return | false | -| System.Text.Encoding.GetChars(byte*, int, char*, int, DecoderNLS) | parameter 0 [[]] -> return | false | -| System.Text.Encoding.GetString(Byte[]) | parameter 0 [[]] -> return | false | -| System.Text.Encoding.GetString(Byte[], int, int) | parameter 0 [[]] -> return | false | -| System.Text.Encoding.GetString(ReadOnlySpan) | parameter 0 [[]] -> return | false | -| System.Text.Encoding.GetString(byte*, int) | parameter 0 [[]] -> return | false | -| System.Text.RegularExpressions.CaptureCollection.Add(Capture) | parameter 0 -> this parameter [[]] | true | -| System.Text.RegularExpressions.CaptureCollection.Add(object) | parameter 0 -> this parameter [[]] | true | -| System.Text.RegularExpressions.CaptureCollection.CopyTo(Array, int) | this parameter [[]] -> parameter 0 [[]] | true | -| System.Text.RegularExpressions.CaptureCollection.CopyTo(Capture[], int) | this parameter [[]] -> parameter 0 [[]] | true | -| System.Text.RegularExpressions.CaptureCollection.GetEnumerator() | this parameter [[]] -> return [Current] | true | -| System.Text.RegularExpressions.CaptureCollection.Insert(int, Capture) | parameter 1 -> this parameter [[]] | true | -| System.Text.RegularExpressions.CaptureCollection.Insert(int, object) | parameter 1 -> this parameter [[]] | true | -| System.Text.RegularExpressions.CaptureCollection.get_Item(int) | this parameter [[]] -> return | true | -| System.Text.RegularExpressions.CaptureCollection.set_Item(int, Capture) | parameter 1 -> this parameter [[]] | true | -| System.Text.RegularExpressions.CaptureCollection.set_Item(int, object) | parameter 1 -> this parameter [[]] | true | -| System.Text.RegularExpressions.GroupCollection.d__49.GetEnumerator() | this parameter [[]] -> return [Current] | true | -| System.Text.RegularExpressions.GroupCollection.d__51.GetEnumerator() | this parameter [[]] -> return [Current] | true | -| System.Text.RegularExpressions.GroupCollection.Add(Group) | parameter 0 -> this parameter [[]] | true | -| System.Text.RegularExpressions.GroupCollection.Add(object) | parameter 0 -> this parameter [[]] | true | -| System.Text.RegularExpressions.GroupCollection.CopyTo(Array, int) | this parameter [[]] -> parameter 0 [[]] | true | -| System.Text.RegularExpressions.GroupCollection.CopyTo(Group[], int) | this parameter [[]] -> parameter 0 [[]] | true | -| System.Text.RegularExpressions.GroupCollection.GetEnumerator() | this parameter [[]] -> return [Current] | true | -| System.Text.RegularExpressions.GroupCollection.Insert(int, Group) | parameter 1 -> this parameter [[]] | true | -| System.Text.RegularExpressions.GroupCollection.Insert(int, object) | parameter 1 -> this parameter [[]] | true | -| System.Text.RegularExpressions.GroupCollection.get_Item(int) | this parameter [[]] -> return | true | -| System.Text.RegularExpressions.GroupCollection.get_Item(string) | this parameter [[]] -> return | true | -| System.Text.RegularExpressions.GroupCollection.set_Item(int, Group) | parameter 1 -> this parameter [[]] | true | -| System.Text.RegularExpressions.GroupCollection.set_Item(int, object) | parameter 1 -> this parameter [[]] | true | -| System.Text.RegularExpressions.MatchCollection.Add(Match) | parameter 0 -> this parameter [[]] | true | -| System.Text.RegularExpressions.MatchCollection.Add(object) | parameter 0 -> this parameter [[]] | true | -| System.Text.RegularExpressions.MatchCollection.CopyTo(Array, int) | this parameter [[]] -> parameter 0 [[]] | true | -| System.Text.RegularExpressions.MatchCollection.CopyTo(Match[], int) | this parameter [[]] -> parameter 0 [[]] | true | -| System.Text.RegularExpressions.MatchCollection.GetEnumerator() | this parameter [[]] -> return [Current] | true | -| System.Text.RegularExpressions.MatchCollection.Insert(int, Match) | parameter 1 -> this parameter [[]] | true | -| System.Text.RegularExpressions.MatchCollection.Insert(int, object) | parameter 1 -> this parameter [[]] | true | -| System.Text.RegularExpressions.MatchCollection.get_Item(int) | this parameter [[]] -> return | true | -| System.Text.RegularExpressions.MatchCollection.set_Item(int, Match) | parameter 1 -> this parameter [[]] | true | -| System.Text.RegularExpressions.MatchCollection.set_Item(int, object) | parameter 1 -> this parameter [[]] | true | -| System.Text.StringBuilder.Append(object) | parameter 0 -> return [[]] | true | -| System.Text.StringBuilder.Append(object) | parameter 0 -> this parameter [[]] | true | -| System.Text.StringBuilder.Append(string) | parameter 0 -> return [[]] | true | -| System.Text.StringBuilder.Append(string) | parameter 0 -> this parameter [[]] | true | -| System.Text.StringBuilder.Append(string, int, int) | parameter 0 -> return [[]] | true | -| System.Text.StringBuilder.Append(string, int, int) | parameter 0 -> this parameter [[]] | true | -| System.Text.StringBuilder.AppendFormat(IFormatProvider, string, object) | parameter 1 -> return [[]] | true | -| System.Text.StringBuilder.AppendFormat(IFormatProvider, string, object) | parameter 1 -> this parameter [[]] | true | -| System.Text.StringBuilder.AppendFormat(IFormatProvider, string, object) | parameter 2 -> return [[]] | true | -| System.Text.StringBuilder.AppendFormat(IFormatProvider, string, object) | parameter 2 -> this parameter [[]] | true | -| System.Text.StringBuilder.AppendFormat(IFormatProvider, string, object, object) | parameter 1 -> return [[]] | true | -| System.Text.StringBuilder.AppendFormat(IFormatProvider, string, object, object) | parameter 1 -> this parameter [[]] | true | -| System.Text.StringBuilder.AppendFormat(IFormatProvider, string, object, object) | parameter 2 -> return [[]] | true | -| System.Text.StringBuilder.AppendFormat(IFormatProvider, string, object, object) | parameter 2 -> this parameter [[]] | true | -| System.Text.StringBuilder.AppendFormat(IFormatProvider, string, object, object) | parameter 3 -> return [[]] | true | -| System.Text.StringBuilder.AppendFormat(IFormatProvider, string, object, object) | parameter 3 -> this parameter [[]] | true | -| System.Text.StringBuilder.AppendFormat(IFormatProvider, string, object, object, object) | parameter 1 -> return [[]] | true | -| System.Text.StringBuilder.AppendFormat(IFormatProvider, string, object, object, object) | parameter 1 -> this parameter [[]] | true | -| System.Text.StringBuilder.AppendFormat(IFormatProvider, string, object, object, object) | parameter 2 -> return [[]] | true | -| System.Text.StringBuilder.AppendFormat(IFormatProvider, string, object, object, object) | parameter 2 -> this parameter [[]] | true | -| System.Text.StringBuilder.AppendFormat(IFormatProvider, string, object, object, object) | parameter 3 -> return [[]] | true | -| System.Text.StringBuilder.AppendFormat(IFormatProvider, string, object, object, object) | parameter 3 -> this parameter [[]] | true | -| System.Text.StringBuilder.AppendFormat(IFormatProvider, string, object, object, object) | parameter 4 -> return [[]] | true | -| System.Text.StringBuilder.AppendFormat(IFormatProvider, string, object, object, object) | parameter 4 -> this parameter [[]] | true | -| System.Text.StringBuilder.AppendFormat(IFormatProvider, string, params Object[]) | parameter 1 -> return [[]] | true | -| System.Text.StringBuilder.AppendFormat(IFormatProvider, string, params Object[]) | parameter 1 -> this parameter [[]] | true | -| System.Text.StringBuilder.AppendFormat(string, object) | parameter 0 -> return [[]] | true | -| System.Text.StringBuilder.AppendFormat(string, object) | parameter 0 -> this parameter [[]] | true | -| System.Text.StringBuilder.AppendFormat(string, object) | parameter 1 -> return [[]] | true | -| System.Text.StringBuilder.AppendFormat(string, object) | parameter 1 -> this parameter [[]] | true | -| System.Text.StringBuilder.AppendFormat(string, object, object) | parameter 0 -> return [[]] | true | -| System.Text.StringBuilder.AppendFormat(string, object, object) | parameter 0 -> this parameter [[]] | true | -| System.Text.StringBuilder.AppendFormat(string, object, object) | parameter 1 -> return [[]] | true | -| System.Text.StringBuilder.AppendFormat(string, object, object) | parameter 1 -> this parameter [[]] | true | -| System.Text.StringBuilder.AppendFormat(string, object, object) | parameter 2 -> return [[]] | true | -| System.Text.StringBuilder.AppendFormat(string, object, object) | parameter 2 -> this parameter [[]] | true | -| System.Text.StringBuilder.AppendFormat(string, object, object, object) | parameter 0 -> return [[]] | true | -| System.Text.StringBuilder.AppendFormat(string, object, object, object) | parameter 0 -> this parameter [[]] | true | -| System.Text.StringBuilder.AppendFormat(string, object, object, object) | parameter 1 -> return [[]] | true | -| System.Text.StringBuilder.AppendFormat(string, object, object, object) | parameter 1 -> this parameter [[]] | true | -| System.Text.StringBuilder.AppendFormat(string, object, object, object) | parameter 2 -> return [[]] | true | -| System.Text.StringBuilder.AppendFormat(string, object, object, object) | parameter 2 -> this parameter [[]] | true | -| System.Text.StringBuilder.AppendFormat(string, object, object, object) | parameter 3 -> return [[]] | true | -| System.Text.StringBuilder.AppendFormat(string, object, object, object) | parameter 3 -> this parameter [[]] | true | -| System.Text.StringBuilder.AppendFormat(string, params Object[]) | parameter 0 -> return [[]] | true | -| System.Text.StringBuilder.AppendFormat(string, params Object[]) | parameter 0 -> this parameter [[]] | true | -| System.Text.StringBuilder.AppendLine(string) | parameter 0 -> return [[]] | true | -| System.Text.StringBuilder.AppendLine(string) | parameter 0 -> this parameter [[]] | true | -| System.Text.StringBuilder.StringBuilder(string) | parameter 0 -> return [[]] | true | -| System.Text.StringBuilder.StringBuilder(string, int) | parameter 0 -> return [[]] | true | -| System.Text.StringBuilder.StringBuilder(string, int, int, int) | parameter 0 -> return [[]] | true | -| System.Text.StringBuilder.ToString() | this parameter [[]] -> return | false | -| System.Text.StringBuilder.ToString(int, int) | this parameter [[]] -> return | false | -| System.Text.TranscodingStream.BeginRead(Byte[], int, int, AsyncCallback, object) | this parameter -> parameter 0 | false | -| System.Text.TranscodingStream.BeginWrite(Byte[], int, int, AsyncCallback, object) | parameter 0 -> this parameter | false | -| System.Text.TranscodingStream.Read(Byte[], int, int) | this parameter -> parameter 0 | false | -| System.Text.TranscodingStream.ReadAsync(Byte[], int, int, CancellationToken) | this parameter -> parameter 0 | false | -| System.Text.TranscodingStream.Write(Byte[], int, int) | parameter 0 -> this parameter | false | -| System.Text.TranscodingStream.WriteAsync(Byte[], int, int, CancellationToken) | parameter 0 -> this parameter | false | -| System.Threading.Tasks.SingleProducerSingleConsumerQueue<>.GetEnumerator() | this parameter [[]] -> return [Current] | true | -| System.Threading.Tasks.Task.ContinueWith(Action, object) | parameter 1 -> parameter 1 of delegate parameter 0 | true | -| System.Threading.Tasks.Task.ContinueWith(Action, object, CancellationToken) | parameter 1 -> parameter 1 of delegate parameter 0 | true | -| System.Threading.Tasks.Task.ContinueWith(Action, object, CancellationToken, TaskContinuationOptions, TaskScheduler) | parameter 1 -> parameter 1 of delegate parameter 0 | true | -| System.Threading.Tasks.Task.ContinueWith(Action, object, TaskContinuationOptions) | parameter 1 -> parameter 1 of delegate parameter 0 | true | -| System.Threading.Tasks.Task.ContinueWith(Action, object, TaskScheduler) | parameter 1 -> parameter 1 of delegate parameter 0 | true | -| System.Threading.Tasks.Task.ContinueWith(Func, object) | deleget output from parameter 0 -> return [Result] | true | -| System.Threading.Tasks.Task.ContinueWith(Func, object) | parameter 1 -> parameter 1 of delegate parameter 0 | true | -| System.Threading.Tasks.Task.ContinueWith(Func, object, CancellationToken) | deleget output from parameter 0 -> return [Result] | true | -| System.Threading.Tasks.Task.ContinueWith(Func, object, CancellationToken) | parameter 1 -> parameter 1 of delegate parameter 0 | true | -| System.Threading.Tasks.Task.ContinueWith(Func, object, CancellationToken, TaskContinuationOptions, TaskScheduler) | deleget output from parameter 0 -> return [Result] | true | -| System.Threading.Tasks.Task.ContinueWith(Func, object, CancellationToken, TaskContinuationOptions, TaskScheduler) | parameter 1 -> parameter 1 of delegate parameter 0 | true | -| System.Threading.Tasks.Task.ContinueWith(Func, object, TaskContinuationOptions) | deleget output from parameter 0 -> return [Result] | true | -| System.Threading.Tasks.Task.ContinueWith(Func, object, TaskContinuationOptions) | parameter 1 -> parameter 1 of delegate parameter 0 | true | -| System.Threading.Tasks.Task.ContinueWith(Func, object, TaskScheduler) | deleget output from parameter 0 -> return [Result] | true | -| System.Threading.Tasks.Task.ContinueWith(Func, object, TaskScheduler) | parameter 1 -> parameter 1 of delegate parameter 0 | true | -| System.Threading.Tasks.Task.ContinueWith(Func) | deleget output from parameter 0 -> return [Result] | true | -| System.Threading.Tasks.Task.ContinueWith(Func, CancellationToken) | deleget output from parameter 0 -> return [Result] | true | -| System.Threading.Tasks.Task.ContinueWith(Func, CancellationToken, TaskContinuationOptions, TaskScheduler) | deleget output from parameter 0 -> return [Result] | true | -| System.Threading.Tasks.Task.ContinueWith(Func, TaskContinuationOptions) | deleget output from parameter 0 -> return [Result] | true | -| System.Threading.Tasks.Task.ContinueWith(Func, TaskScheduler) | deleget output from parameter 0 -> return [Result] | true | -| System.Threading.Tasks.Task.FromResult(TResult) | parameter 0 -> return [Result] | true | -| System.Threading.Tasks.Task.Run(Func) | deleget output from parameter 0 -> return [Result] | true | -| System.Threading.Tasks.Task.Run(Func, CancellationToken) | deleget output from parameter 0 -> return [Result] | true | -| System.Threading.Tasks.Task.Run(Func>) | deleget output from parameter 0 -> return [Result] | true | -| System.Threading.Tasks.Task.Run(Func>, CancellationToken) | deleget output from parameter 0 -> return [Result] | true | -| System.Threading.Tasks.Task.Task(Action, object) | parameter 1 -> parameter 0 of delegate parameter 0 | true | -| System.Threading.Tasks.Task.Task(Action, object, CancellationToken) | parameter 1 -> parameter 0 of delegate parameter 0 | true | -| System.Threading.Tasks.Task.Task(Action, object, CancellationToken, TaskCreationOptions) | parameter 1 -> parameter 0 of delegate parameter 0 | true | -| System.Threading.Tasks.Task.Task(Action, object, TaskCreationOptions) | parameter 1 -> parameter 0 of delegate parameter 0 | true | -| System.Threading.Tasks.Task.WhenAll(IEnumerable>) | parameter 0 [[], Result] -> return [Result, []] | true | -| System.Threading.Tasks.Task.WhenAll(params Task[]) | parameter 0 [[], Result] -> return [Result, []] | true | -| System.Threading.Tasks.Task.WhenAny(IEnumerable>) | parameter 0 [[], Result] -> return [Result, []] | true | -| System.Threading.Tasks.Task.WhenAny(Task, Task) | parameter 0 [[], Result] -> return [Result, []] | true | -| System.Threading.Tasks.Task.WhenAny(Task, Task) | parameter 1 [[], Result] -> return [Result, []] | true | -| System.Threading.Tasks.Task.WhenAny(params Task[]) | parameter 0 [[], Result] -> return [Result, []] | true | -| System.Threading.Tasks.Task<>.ConfigureAwait(bool) | this parameter -> return [m_configuredTaskAwaiter, m_task] | true | -| System.Threading.Tasks.Task<>.ContinueWith(Action, Object>, object) | parameter 1 -> parameter 1 of delegate parameter 0 | true | -| System.Threading.Tasks.Task<>.ContinueWith(Action, Object>, object) | this parameter -> parameter 0 of delegate parameter 0 | true | -| System.Threading.Tasks.Task<>.ContinueWith(Action, Object>, object, CancellationToken) | parameter 1 -> parameter 1 of delegate parameter 0 | true | -| System.Threading.Tasks.Task<>.ContinueWith(Action, Object>, object, CancellationToken) | this parameter -> parameter 0 of delegate parameter 0 | true | -| System.Threading.Tasks.Task<>.ContinueWith(Action, Object>, object, CancellationToken, TaskContinuationOptions, TaskScheduler) | parameter 1 -> parameter 1 of delegate parameter 0 | true | -| System.Threading.Tasks.Task<>.ContinueWith(Action, Object>, object, CancellationToken, TaskContinuationOptions, TaskScheduler) | this parameter -> parameter 0 of delegate parameter 0 | true | -| System.Threading.Tasks.Task<>.ContinueWith(Action, Object>, object, TaskContinuationOptions) | parameter 1 -> parameter 1 of delegate parameter 0 | true | -| System.Threading.Tasks.Task<>.ContinueWith(Action, Object>, object, TaskContinuationOptions) | this parameter -> parameter 0 of delegate parameter 0 | true | -| System.Threading.Tasks.Task<>.ContinueWith(Action, Object>, object, TaskScheduler) | parameter 1 -> parameter 1 of delegate parameter 0 | true | -| System.Threading.Tasks.Task<>.ContinueWith(Action, Object>, object, TaskScheduler) | this parameter -> parameter 0 of delegate parameter 0 | true | -| System.Threading.Tasks.Task<>.ContinueWith(Action>) | this parameter -> parameter 0 of delegate parameter 0 | true | -| System.Threading.Tasks.Task<>.ContinueWith(Action>, CancellationToken) | this parameter -> parameter 0 of delegate parameter 0 | true | -| System.Threading.Tasks.Task<>.ContinueWith(Action>, CancellationToken, TaskContinuationOptions, TaskScheduler) | this parameter -> parameter 0 of delegate parameter 0 | true | -| System.Threading.Tasks.Task<>.ContinueWith(Action>, TaskContinuationOptions) | this parameter -> parameter 0 of delegate parameter 0 | true | -| System.Threading.Tasks.Task<>.ContinueWith(Action>, TaskScheduler) | this parameter -> parameter 0 of delegate parameter 0 | true | -| System.Threading.Tasks.Task<>.ContinueWith(Func, Object, TNewResult>, object) | deleget output from parameter 0 -> return [Result] | true | -| System.Threading.Tasks.Task<>.ContinueWith(Func, Object, TNewResult>, object) | parameter 1 -> parameter 1 of delegate parameter 0 | true | -| System.Threading.Tasks.Task<>.ContinueWith(Func, Object, TNewResult>, object) | this parameter -> parameter 0 of delegate parameter 0 | true | -| System.Threading.Tasks.Task<>.ContinueWith(Func, Object, TNewResult>, object, CancellationToken) | deleget output from parameter 0 -> return [Result] | true | -| System.Threading.Tasks.Task<>.ContinueWith(Func, Object, TNewResult>, object, CancellationToken) | parameter 1 -> parameter 1 of delegate parameter 0 | true | -| System.Threading.Tasks.Task<>.ContinueWith(Func, Object, TNewResult>, object, CancellationToken) | this parameter -> parameter 0 of delegate parameter 0 | true | -| System.Threading.Tasks.Task<>.ContinueWith(Func, Object, TNewResult>, object, CancellationToken, TaskContinuationOptions, TaskScheduler) | deleget output from parameter 0 -> return [Result] | true | -| System.Threading.Tasks.Task<>.ContinueWith(Func, Object, TNewResult>, object, CancellationToken, TaskContinuationOptions, TaskScheduler) | parameter 1 -> parameter 1 of delegate parameter 0 | true | -| System.Threading.Tasks.Task<>.ContinueWith(Func, Object, TNewResult>, object, CancellationToken, TaskContinuationOptions, TaskScheduler) | this parameter -> parameter 0 of delegate parameter 0 | true | -| System.Threading.Tasks.Task<>.ContinueWith(Func, Object, TNewResult>, object, TaskContinuationOptions) | deleget output from parameter 0 -> return [Result] | true | -| System.Threading.Tasks.Task<>.ContinueWith(Func, Object, TNewResult>, object, TaskContinuationOptions) | parameter 1 -> parameter 1 of delegate parameter 0 | true | -| System.Threading.Tasks.Task<>.ContinueWith(Func, Object, TNewResult>, object, TaskContinuationOptions) | this parameter -> parameter 0 of delegate parameter 0 | true | -| System.Threading.Tasks.Task<>.ContinueWith(Func, Object, TNewResult>, object, TaskScheduler) | deleget output from parameter 0 -> return [Result] | true | -| System.Threading.Tasks.Task<>.ContinueWith(Func, Object, TNewResult>, object, TaskScheduler) | parameter 1 -> parameter 1 of delegate parameter 0 | true | -| System.Threading.Tasks.Task<>.ContinueWith(Func, Object, TNewResult>, object, TaskScheduler) | this parameter -> parameter 0 of delegate parameter 0 | true | -| System.Threading.Tasks.Task<>.ContinueWith(Func, TNewResult>) | deleget output from parameter 0 -> return [Result] | true | -| System.Threading.Tasks.Task<>.ContinueWith(Func, TNewResult>) | this parameter -> parameter 0 of delegate parameter 0 | true | -| System.Threading.Tasks.Task<>.ContinueWith(Func, TNewResult>, CancellationToken) | deleget output from parameter 0 -> return [Result] | true | -| System.Threading.Tasks.Task<>.ContinueWith(Func, TNewResult>, CancellationToken) | this parameter -> parameter 0 of delegate parameter 0 | true | -| System.Threading.Tasks.Task<>.ContinueWith(Func, TNewResult>, CancellationToken, TaskContinuationOptions, TaskScheduler) | deleget output from parameter 0 -> return [Result] | true | -| System.Threading.Tasks.Task<>.ContinueWith(Func, TNewResult>, CancellationToken, TaskContinuationOptions, TaskScheduler) | this parameter -> parameter 0 of delegate parameter 0 | true | -| System.Threading.Tasks.Task<>.ContinueWith(Func, TNewResult>, TaskContinuationOptions) | deleget output from parameter 0 -> return [Result] | true | -| System.Threading.Tasks.Task<>.ContinueWith(Func, TNewResult>, TaskContinuationOptions) | this parameter -> parameter 0 of delegate parameter 0 | true | -| System.Threading.Tasks.Task<>.ContinueWith(Func, TNewResult>, TaskScheduler) | deleget output from parameter 0 -> return [Result] | true | -| System.Threading.Tasks.Task<>.ContinueWith(Func, TNewResult>, TaskScheduler) | this parameter -> parameter 0 of delegate parameter 0 | true | -| System.Threading.Tasks.Task<>.GetAwaiter() | this parameter -> return [m_task] | true | -| System.Threading.Tasks.Task<>.Task(Func, object) | deleget output from parameter 0 -> return [Result] | true | -| System.Threading.Tasks.Task<>.Task(Func, object) | parameter 1 -> parameter 0 of delegate parameter 0 | true | -| System.Threading.Tasks.Task<>.Task(Func, object, CancellationToken) | deleget output from parameter 0 -> return [Result] | true | -| System.Threading.Tasks.Task<>.Task(Func, object, CancellationToken) | parameter 1 -> parameter 0 of delegate parameter 0 | true | -| System.Threading.Tasks.Task<>.Task(Func, object, CancellationToken, TaskCreationOptions) | deleget output from parameter 0 -> return [Result] | true | -| System.Threading.Tasks.Task<>.Task(Func, object, CancellationToken, TaskCreationOptions) | parameter 1 -> parameter 0 of delegate parameter 0 | true | -| System.Threading.Tasks.Task<>.Task(Func, object, TaskCreationOptions) | deleget output from parameter 0 -> return [Result] | true | -| System.Threading.Tasks.Task<>.Task(Func, object, TaskCreationOptions) | parameter 1 -> parameter 0 of delegate parameter 0 | true | -| System.Threading.Tasks.Task<>.Task(Func) | deleget output from parameter 0 -> return [Result] | true | -| System.Threading.Tasks.Task<>.Task(Func, CancellationToken) | deleget output from parameter 0 -> return [Result] | true | -| System.Threading.Tasks.Task<>.Task(Func, CancellationToken, TaskCreationOptions) | deleget output from parameter 0 -> return [Result] | true | -| System.Threading.Tasks.Task<>.Task(Func, TaskCreationOptions) | deleget output from parameter 0 -> return [Result] | true | -| System.Threading.Tasks.Task<>.get_Result() | this parameter -> return | false | -| System.Threading.Tasks.TaskFactory.ContinueWhenAll(Task[], Func) | deleget output from parameter 1 -> return [Result] | true | -| System.Threading.Tasks.TaskFactory.ContinueWhenAll(Task[], Func) | parameter 0 -> parameter 0 of delegate parameter 1 | true | -| System.Threading.Tasks.TaskFactory.ContinueWhenAll(Task[], Func, CancellationToken) | deleget output from parameter 1 -> return [Result] | true | -| System.Threading.Tasks.TaskFactory.ContinueWhenAll(Task[], Func, CancellationToken) | parameter 0 -> parameter 0 of delegate parameter 1 | true | -| System.Threading.Tasks.TaskFactory.ContinueWhenAll(Task[], Func, CancellationToken, TaskContinuationOptions, TaskScheduler) | deleget output from parameter 1 -> return [Result] | true | -| System.Threading.Tasks.TaskFactory.ContinueWhenAll(Task[], Func, CancellationToken, TaskContinuationOptions, TaskScheduler) | parameter 0 -> parameter 0 of delegate parameter 1 | true | -| System.Threading.Tasks.TaskFactory.ContinueWhenAll(Task[], Func, TaskContinuationOptions) | deleget output from parameter 1 -> return [Result] | true | -| System.Threading.Tasks.TaskFactory.ContinueWhenAll(Task[], Func, TaskContinuationOptions) | parameter 0 -> parameter 0 of delegate parameter 1 | true | -| System.Threading.Tasks.TaskFactory.ContinueWhenAll(Task[], Action) | parameter 0 -> parameter 0 of delegate parameter 1 | true | -| System.Threading.Tasks.TaskFactory.ContinueWhenAll(Task[], Action, CancellationToken) | parameter 0 -> parameter 0 of delegate parameter 1 | true | -| System.Threading.Tasks.TaskFactory.ContinueWhenAll(Task[], Action, CancellationToken, TaskContinuationOptions, TaskScheduler) | parameter 0 -> parameter 0 of delegate parameter 1 | true | -| System.Threading.Tasks.TaskFactory.ContinueWhenAll(Task[], Action, TaskContinuationOptions) | parameter 0 -> parameter 0 of delegate parameter 1 | true | -| System.Threading.Tasks.TaskFactory.ContinueWhenAll(Task[], Func) | deleget output from parameter 1 -> return [Result] | true | -| System.Threading.Tasks.TaskFactory.ContinueWhenAll(Task[], Func, CancellationToken) | deleget output from parameter 1 -> return [Result] | true | -| System.Threading.Tasks.TaskFactory.ContinueWhenAll(Task[], Func, CancellationToken, TaskContinuationOptions, TaskScheduler) | deleget output from parameter 1 -> return [Result] | true | -| System.Threading.Tasks.TaskFactory.ContinueWhenAll(Task[], Func, TaskContinuationOptions) | deleget output from parameter 1 -> return [Result] | true | -| System.Threading.Tasks.TaskFactory.ContinueWhenAny(Task[], Func, TResult>) | deleget output from parameter 1 -> return [Result] | true | -| System.Threading.Tasks.TaskFactory.ContinueWhenAny(Task[], Func, TResult>) | parameter 0 -> parameter 0 of delegate parameter 1 | true | -| System.Threading.Tasks.TaskFactory.ContinueWhenAny(Task[], Func, TResult>, CancellationToken) | deleget output from parameter 1 -> return [Result] | true | -| System.Threading.Tasks.TaskFactory.ContinueWhenAny(Task[], Func, TResult>, CancellationToken) | parameter 0 -> parameter 0 of delegate parameter 1 | true | -| System.Threading.Tasks.TaskFactory.ContinueWhenAny(Task[], Func, TResult>, CancellationToken, TaskContinuationOptions, TaskScheduler) | deleget output from parameter 1 -> return [Result] | true | -| System.Threading.Tasks.TaskFactory.ContinueWhenAny(Task[], Func, TResult>, CancellationToken, TaskContinuationOptions, TaskScheduler) | parameter 0 -> parameter 0 of delegate parameter 1 | true | -| System.Threading.Tasks.TaskFactory.ContinueWhenAny(Task[], Func, TResult>, TaskContinuationOptions) | deleget output from parameter 1 -> return [Result] | true | -| System.Threading.Tasks.TaskFactory.ContinueWhenAny(Task[], Func, TResult>, TaskContinuationOptions) | parameter 0 -> parameter 0 of delegate parameter 1 | true | -| System.Threading.Tasks.TaskFactory.ContinueWhenAny(Task[], Action>) | parameter 0 -> parameter 0 of delegate parameter 1 | true | -| System.Threading.Tasks.TaskFactory.ContinueWhenAny(Task[], Action>, CancellationToken) | parameter 0 -> parameter 0 of delegate parameter 1 | true | -| System.Threading.Tasks.TaskFactory.ContinueWhenAny(Task[], Action>, CancellationToken, TaskContinuationOptions, TaskScheduler) | parameter 0 -> parameter 0 of delegate parameter 1 | true | -| System.Threading.Tasks.TaskFactory.ContinueWhenAny(Task[], Action>, TaskContinuationOptions) | parameter 0 -> parameter 0 of delegate parameter 1 | true | -| System.Threading.Tasks.TaskFactory.ContinueWhenAny(Task[], Func) | deleget output from parameter 1 -> return [Result] | true | -| System.Threading.Tasks.TaskFactory.ContinueWhenAny(Task[], Func, CancellationToken) | deleget output from parameter 1 -> return [Result] | true | -| System.Threading.Tasks.TaskFactory.ContinueWhenAny(Task[], Func, CancellationToken, TaskContinuationOptions, TaskScheduler) | deleget output from parameter 1 -> return [Result] | true | -| System.Threading.Tasks.TaskFactory.ContinueWhenAny(Task[], Func, TaskContinuationOptions) | deleget output from parameter 1 -> return [Result] | true | -| System.Threading.Tasks.TaskFactory.StartNew(Action, object) | parameter 1 -> parameter 0 of delegate parameter 0 | true | -| System.Threading.Tasks.TaskFactory.StartNew(Action, object, CancellationToken) | parameter 1 -> parameter 0 of delegate parameter 0 | true | -| System.Threading.Tasks.TaskFactory.StartNew(Action, object, CancellationToken, TaskCreationOptions, TaskScheduler) | parameter 1 -> parameter 0 of delegate parameter 0 | true | -| System.Threading.Tasks.TaskFactory.StartNew(Action, object, TaskCreationOptions) | parameter 1 -> parameter 0 of delegate parameter 0 | true | -| System.Threading.Tasks.TaskFactory.StartNew(Func, object) | deleget output from parameter 0 -> return [Result] | true | -| System.Threading.Tasks.TaskFactory.StartNew(Func, object) | parameter 1 -> parameter 0 of delegate parameter 0 | true | -| System.Threading.Tasks.TaskFactory.StartNew(Func, object, CancellationToken) | deleget output from parameter 0 -> return [Result] | true | -| System.Threading.Tasks.TaskFactory.StartNew(Func, object, CancellationToken) | parameter 1 -> parameter 0 of delegate parameter 0 | true | -| System.Threading.Tasks.TaskFactory.StartNew(Func, object, CancellationToken, TaskCreationOptions, TaskScheduler) | deleget output from parameter 0 -> return [Result] | true | -| System.Threading.Tasks.TaskFactory.StartNew(Func, object, CancellationToken, TaskCreationOptions, TaskScheduler) | parameter 1 -> parameter 0 of delegate parameter 0 | true | -| System.Threading.Tasks.TaskFactory.StartNew(Func, object, TaskCreationOptions) | deleget output from parameter 0 -> return [Result] | true | -| System.Threading.Tasks.TaskFactory.StartNew(Func, object, TaskCreationOptions) | parameter 1 -> parameter 0 of delegate parameter 0 | true | -| System.Threading.Tasks.TaskFactory.StartNew(Func) | deleget output from parameter 0 -> return [Result] | true | -| System.Threading.Tasks.TaskFactory.StartNew(Func, CancellationToken) | deleget output from parameter 0 -> return [Result] | true | -| System.Threading.Tasks.TaskFactory.StartNew(Func, CancellationToken, TaskCreationOptions, TaskScheduler) | deleget output from parameter 0 -> return [Result] | true | -| System.Threading.Tasks.TaskFactory.StartNew(Func, TaskCreationOptions) | deleget output from parameter 0 -> return [Result] | true | -| System.Threading.Tasks.TaskFactory<>.ContinueWhenAll(Task[], Func) | deleget output from parameter 1 -> return [Result] | true | -| System.Threading.Tasks.TaskFactory<>.ContinueWhenAll(Task[], Func, CancellationToken) | deleget output from parameter 1 -> return [Result] | true | -| System.Threading.Tasks.TaskFactory<>.ContinueWhenAll(Task[], Func, CancellationToken, TaskContinuationOptions, TaskScheduler) | deleget output from parameter 1 -> return [Result] | true | -| System.Threading.Tasks.TaskFactory<>.ContinueWhenAll(Task[], Func, TaskContinuationOptions) | deleget output from parameter 1 -> return [Result] | true | -| System.Threading.Tasks.TaskFactory<>.ContinueWhenAll(Task[], Func) | deleget output from parameter 1 -> return [Result] | true | -| System.Threading.Tasks.TaskFactory<>.ContinueWhenAll(Task[], Func) | parameter 0 -> parameter 0 of delegate parameter 1 | true | -| System.Threading.Tasks.TaskFactory<>.ContinueWhenAll(Task[], Func, CancellationToken) | deleget output from parameter 1 -> return [Result] | true | -| System.Threading.Tasks.TaskFactory<>.ContinueWhenAll(Task[], Func, CancellationToken) | parameter 0 -> parameter 0 of delegate parameter 1 | true | -| System.Threading.Tasks.TaskFactory<>.ContinueWhenAll(Task[], Func, CancellationToken, TaskContinuationOptions, TaskScheduler) | deleget output from parameter 1 -> return [Result] | true | -| System.Threading.Tasks.TaskFactory<>.ContinueWhenAll(Task[], Func, CancellationToken, TaskContinuationOptions, TaskScheduler) | parameter 0 -> parameter 0 of delegate parameter 1 | true | -| System.Threading.Tasks.TaskFactory<>.ContinueWhenAll(Task[], Func, TaskContinuationOptions) | deleget output from parameter 1 -> return [Result] | true | -| System.Threading.Tasks.TaskFactory<>.ContinueWhenAll(Task[], Func, TaskContinuationOptions) | parameter 0 -> parameter 0 of delegate parameter 1 | true | -| System.Threading.Tasks.TaskFactory<>.ContinueWhenAny(Task[], Func) | deleget output from parameter 1 -> return [Result] | true | -| System.Threading.Tasks.TaskFactory<>.ContinueWhenAny(Task[], Func, CancellationToken) | deleget output from parameter 1 -> return [Result] | true | -| System.Threading.Tasks.TaskFactory<>.ContinueWhenAny(Task[], Func, CancellationToken, TaskContinuationOptions, TaskScheduler) | deleget output from parameter 1 -> return [Result] | true | -| System.Threading.Tasks.TaskFactory<>.ContinueWhenAny(Task[], Func, TaskContinuationOptions) | deleget output from parameter 1 -> return [Result] | true | -| System.Threading.Tasks.TaskFactory<>.ContinueWhenAny(Task[], Func, TResult>) | deleget output from parameter 1 -> return [Result] | true | -| System.Threading.Tasks.TaskFactory<>.ContinueWhenAny(Task[], Func, TResult>) | parameter 0 -> parameter 0 of delegate parameter 1 | true | -| System.Threading.Tasks.TaskFactory<>.ContinueWhenAny(Task[], Func, TResult>, CancellationToken) | deleget output from parameter 1 -> return [Result] | true | -| System.Threading.Tasks.TaskFactory<>.ContinueWhenAny(Task[], Func, TResult>, CancellationToken) | parameter 0 -> parameter 0 of delegate parameter 1 | true | -| System.Threading.Tasks.TaskFactory<>.ContinueWhenAny(Task[], Func, TResult>, CancellationToken, TaskContinuationOptions, TaskScheduler) | deleget output from parameter 1 -> return [Result] | true | -| System.Threading.Tasks.TaskFactory<>.ContinueWhenAny(Task[], Func, TResult>, CancellationToken, TaskContinuationOptions, TaskScheduler) | parameter 0 -> parameter 0 of delegate parameter 1 | true | -| System.Threading.Tasks.TaskFactory<>.ContinueWhenAny(Task[], Func, TResult>, TaskContinuationOptions) | deleget output from parameter 1 -> return [Result] | true | -| System.Threading.Tasks.TaskFactory<>.ContinueWhenAny(Task[], Func, TResult>, TaskContinuationOptions) | parameter 0 -> parameter 0 of delegate parameter 1 | true | -| System.Threading.Tasks.TaskFactory<>.StartNew(Func, object) | deleget output from parameter 0 -> return [Result] | true | -| System.Threading.Tasks.TaskFactory<>.StartNew(Func, object) | parameter 1 -> parameter 0 of delegate parameter 0 | true | -| System.Threading.Tasks.TaskFactory<>.StartNew(Func, object, CancellationToken) | deleget output from parameter 0 -> return [Result] | true | -| System.Threading.Tasks.TaskFactory<>.StartNew(Func, object, CancellationToken) | parameter 1 -> parameter 0 of delegate parameter 0 | true | -| System.Threading.Tasks.TaskFactory<>.StartNew(Func, object, CancellationToken, TaskCreationOptions, TaskScheduler) | deleget output from parameter 0 -> return [Result] | true | -| System.Threading.Tasks.TaskFactory<>.StartNew(Func, object, CancellationToken, TaskCreationOptions, TaskScheduler) | parameter 1 -> parameter 0 of delegate parameter 0 | true | -| System.Threading.Tasks.TaskFactory<>.StartNew(Func, object, TaskCreationOptions) | deleget output from parameter 0 -> return [Result] | true | -| System.Threading.Tasks.TaskFactory<>.StartNew(Func, object, TaskCreationOptions) | parameter 1 -> parameter 0 of delegate parameter 0 | true | -| System.Threading.Tasks.TaskFactory<>.StartNew(Func) | deleget output from parameter 0 -> return [Result] | true | -| System.Threading.Tasks.TaskFactory<>.StartNew(Func, CancellationToken) | deleget output from parameter 0 -> return [Result] | true | -| System.Threading.Tasks.TaskFactory<>.StartNew(Func, CancellationToken, TaskCreationOptions, TaskScheduler) | deleget output from parameter 0 -> return [Result] | true | -| System.Threading.Tasks.TaskFactory<>.StartNew(Func, TaskCreationOptions) | deleget output from parameter 0 -> return [Result] | true | -| System.Threading.Tasks.ThreadPoolTaskScheduler.d__6.GetEnumerator() | this parameter [[]] -> return [Current] | true | -| System.Threading.ThreadPool.d__52.GetEnumerator() | this parameter [[]] -> return [Current] | true | -| System.Threading.ThreadPool.d__51.GetEnumerator() | this parameter [[]] -> return [Current] | true | -| System.Tuple.Create(T1, T2, T3, T4, T5, T6, T7, T8) | parameter 0 -> return [Item1] | true | -| System.Tuple.Create(T1, T2, T3, T4, T5, T6, T7, T8) | parameter 1 -> return [Item2] | true | -| System.Tuple.Create(T1, T2, T3, T4, T5, T6, T7, T8) | parameter 2 -> return [Item3] | true | -| System.Tuple.Create(T1, T2, T3, T4, T5, T6, T7, T8) | parameter 3 -> return [Item4] | true | -| System.Tuple.Create(T1, T2, T3, T4, T5, T6, T7, T8) | parameter 4 -> return [Item5] | true | -| System.Tuple.Create(T1, T2, T3, T4, T5, T6, T7, T8) | parameter 5 -> return [Item6] | true | -| System.Tuple.Create(T1, T2, T3, T4, T5, T6, T7, T8) | parameter 6 -> return [Item7] | true | -| System.Tuple.Create(T1, T2, T3, T4, T5, T6, T7) | parameter 0 -> return [Item1] | true | -| System.Tuple.Create(T1, T2, T3, T4, T5, T6, T7) | parameter 1 -> return [Item2] | true | -| System.Tuple.Create(T1, T2, T3, T4, T5, T6, T7) | parameter 2 -> return [Item3] | true | -| System.Tuple.Create(T1, T2, T3, T4, T5, T6, T7) | parameter 3 -> return [Item4] | true | -| System.Tuple.Create(T1, T2, T3, T4, T5, T6, T7) | parameter 4 -> return [Item5] | true | -| System.Tuple.Create(T1, T2, T3, T4, T5, T6, T7) | parameter 5 -> return [Item6] | true | -| System.Tuple.Create(T1, T2, T3, T4, T5, T6, T7) | parameter 6 -> return [Item7] | true | -| System.Tuple.Create(T1, T2, T3, T4, T5, T6) | parameter 0 -> return [Item1] | true | -| System.Tuple.Create(T1, T2, T3, T4, T5, T6) | parameter 1 -> return [Item2] | true | -| System.Tuple.Create(T1, T2, T3, T4, T5, T6) | parameter 2 -> return [Item3] | true | -| System.Tuple.Create(T1, T2, T3, T4, T5, T6) | parameter 3 -> return [Item4] | true | -| System.Tuple.Create(T1, T2, T3, T4, T5, T6) | parameter 4 -> return [Item5] | true | -| System.Tuple.Create(T1, T2, T3, T4, T5, T6) | parameter 5 -> return [Item6] | true | -| System.Tuple.Create(T1, T2, T3, T4, T5) | parameter 0 -> return [Item1] | true | -| System.Tuple.Create(T1, T2, T3, T4, T5) | parameter 1 -> return [Item2] | true | -| System.Tuple.Create(T1, T2, T3, T4, T5) | parameter 2 -> return [Item3] | true | -| System.Tuple.Create(T1, T2, T3, T4, T5) | parameter 3 -> return [Item4] | true | -| System.Tuple.Create(T1, T2, T3, T4, T5) | parameter 4 -> return [Item5] | true | -| System.Tuple.Create(T1, T2, T3, T4) | parameter 0 -> return [Item1] | true | -| System.Tuple.Create(T1, T2, T3, T4) | parameter 1 -> return [Item2] | true | -| System.Tuple.Create(T1, T2, T3, T4) | parameter 2 -> return [Item3] | true | -| System.Tuple.Create(T1, T2, T3, T4) | parameter 3 -> return [Item4] | true | -| System.Tuple.Create(T1, T2, T3) | parameter 0 -> return [Item1] | true | -| System.Tuple.Create(T1, T2, T3) | parameter 1 -> return [Item2] | true | -| System.Tuple.Create(T1, T2, T3) | parameter 2 -> return [Item3] | true | -| System.Tuple.Create(T1, T2) | parameter 0 -> return [Item1] | true | -| System.Tuple.Create(T1, T2) | parameter 1 -> return [Item2] | true | -| System.Tuple.Create(T1) | parameter 0 -> return [Item1] | true | -| System.Tuple<,,,,,,,>.Tuple(T1, T2, T3, T4, T5, T6, T7, TRest) | parameter 0 -> return [Item1] | true | -| System.Tuple<,,,,,,,>.Tuple(T1, T2, T3, T4, T5, T6, T7, TRest) | parameter 1 -> return [Item2] | true | -| System.Tuple<,,,,,,,>.Tuple(T1, T2, T3, T4, T5, T6, T7, TRest) | parameter 2 -> return [Item3] | true | -| System.Tuple<,,,,,,,>.Tuple(T1, T2, T3, T4, T5, T6, T7, TRest) | parameter 3 -> return [Item4] | true | -| System.Tuple<,,,,,,,>.Tuple(T1, T2, T3, T4, T5, T6, T7, TRest) | parameter 4 -> return [Item5] | true | -| System.Tuple<,,,,,,,>.Tuple(T1, T2, T3, T4, T5, T6, T7, TRest) | parameter 5 -> return [Item6] | true | -| System.Tuple<,,,,,,,>.Tuple(T1, T2, T3, T4, T5, T6, T7, TRest) | parameter 6 -> return [Item7] | true | -| System.Tuple<,,,,,,,>.get_Item(int) | this parameter [Item1] -> return | true | -| System.Tuple<,,,,,,,>.get_Item(int) | this parameter [Item2] -> return | true | -| System.Tuple<,,,,,,,>.get_Item(int) | this parameter [Item3] -> return | true | -| System.Tuple<,,,,,,,>.get_Item(int) | this parameter [Item4] -> return | true | -| System.Tuple<,,,,,,,>.get_Item(int) | this parameter [Item5] -> return | true | -| System.Tuple<,,,,,,,>.get_Item(int) | this parameter [Item6] -> return | true | -| System.Tuple<,,,,,,,>.get_Item(int) | this parameter [Item7] -> return | true | -| System.Tuple<,,,,,,>.Tuple(T1, T2, T3, T4, T5, T6, T7) | parameter 0 -> return [Item1] | true | -| System.Tuple<,,,,,,>.Tuple(T1, T2, T3, T4, T5, T6, T7) | parameter 1 -> return [Item2] | true | -| System.Tuple<,,,,,,>.Tuple(T1, T2, T3, T4, T5, T6, T7) | parameter 2 -> return [Item3] | true | -| System.Tuple<,,,,,,>.Tuple(T1, T2, T3, T4, T5, T6, T7) | parameter 3 -> return [Item4] | true | -| System.Tuple<,,,,,,>.Tuple(T1, T2, T3, T4, T5, T6, T7) | parameter 4 -> return [Item5] | true | -| System.Tuple<,,,,,,>.Tuple(T1, T2, T3, T4, T5, T6, T7) | parameter 5 -> return [Item6] | true | -| System.Tuple<,,,,,,>.Tuple(T1, T2, T3, T4, T5, T6, T7) | parameter 6 -> return [Item7] | true | -| System.Tuple<,,,,,,>.get_Item(int) | this parameter [Item1] -> return | true | -| System.Tuple<,,,,,,>.get_Item(int) | this parameter [Item2] -> return | true | -| System.Tuple<,,,,,,>.get_Item(int) | this parameter [Item3] -> return | true | -| System.Tuple<,,,,,,>.get_Item(int) | this parameter [Item4] -> return | true | -| System.Tuple<,,,,,,>.get_Item(int) | this parameter [Item5] -> return | true | -| System.Tuple<,,,,,,>.get_Item(int) | this parameter [Item6] -> return | true | -| System.Tuple<,,,,,,>.get_Item(int) | this parameter [Item7] -> return | true | -| System.Tuple<,,,,,>.Tuple(T1, T2, T3, T4, T5, T6) | parameter 0 -> return [Item1] | true | -| System.Tuple<,,,,,>.Tuple(T1, T2, T3, T4, T5, T6) | parameter 1 -> return [Item2] | true | -| System.Tuple<,,,,,>.Tuple(T1, T2, T3, T4, T5, T6) | parameter 2 -> return [Item3] | true | -| System.Tuple<,,,,,>.Tuple(T1, T2, T3, T4, T5, T6) | parameter 3 -> return [Item4] | true | -| System.Tuple<,,,,,>.Tuple(T1, T2, T3, T4, T5, T6) | parameter 4 -> return [Item5] | true | -| System.Tuple<,,,,,>.Tuple(T1, T2, T3, T4, T5, T6) | parameter 5 -> return [Item6] | true | -| System.Tuple<,,,,,>.get_Item(int) | this parameter [Item1] -> return | true | -| System.Tuple<,,,,,>.get_Item(int) | this parameter [Item2] -> return | true | -| System.Tuple<,,,,,>.get_Item(int) | this parameter [Item3] -> return | true | -| System.Tuple<,,,,,>.get_Item(int) | this parameter [Item4] -> return | true | -| System.Tuple<,,,,,>.get_Item(int) | this parameter [Item5] -> return | true | -| System.Tuple<,,,,,>.get_Item(int) | this parameter [Item6] -> return | true | -| System.Tuple<,,,,>.Tuple(T1, T2, T3, T4, T5) | parameter 0 -> return [Item1] | true | -| System.Tuple<,,,,>.Tuple(T1, T2, T3, T4, T5) | parameter 1 -> return [Item2] | true | -| System.Tuple<,,,,>.Tuple(T1, T2, T3, T4, T5) | parameter 2 -> return [Item3] | true | -| System.Tuple<,,,,>.Tuple(T1, T2, T3, T4, T5) | parameter 3 -> return [Item4] | true | -| System.Tuple<,,,,>.Tuple(T1, T2, T3, T4, T5) | parameter 4 -> return [Item5] | true | -| System.Tuple<,,,,>.get_Item(int) | this parameter [Item1] -> return | true | -| System.Tuple<,,,,>.get_Item(int) | this parameter [Item2] -> return | true | -| System.Tuple<,,,,>.get_Item(int) | this parameter [Item3] -> return | true | -| System.Tuple<,,,,>.get_Item(int) | this parameter [Item4] -> return | true | -| System.Tuple<,,,,>.get_Item(int) | this parameter [Item5] -> return | true | -| System.Tuple<,,,>.Tuple(T1, T2, T3, T4) | parameter 0 -> return [Item1] | true | -| System.Tuple<,,,>.Tuple(T1, T2, T3, T4) | parameter 1 -> return [Item2] | true | -| System.Tuple<,,,>.Tuple(T1, T2, T3, T4) | parameter 2 -> return [Item3] | true | -| System.Tuple<,,,>.Tuple(T1, T2, T3, T4) | parameter 3 -> return [Item4] | true | -| System.Tuple<,,,>.get_Item(int) | this parameter [Item1] -> return | true | -| System.Tuple<,,,>.get_Item(int) | this parameter [Item2] -> return | true | -| System.Tuple<,,,>.get_Item(int) | this parameter [Item3] -> return | true | -| System.Tuple<,,,>.get_Item(int) | this parameter [Item4] -> return | true | -| System.Tuple<,,>.Tuple(T1, T2, T3) | parameter 0 -> return [Item1] | true | -| System.Tuple<,,>.Tuple(T1, T2, T3) | parameter 1 -> return [Item2] | true | -| System.Tuple<,,>.Tuple(T1, T2, T3) | parameter 2 -> return [Item3] | true | -| System.Tuple<,,>.get_Item(int) | this parameter [Item1] -> return | true | -| System.Tuple<,,>.get_Item(int) | this parameter [Item2] -> return | true | -| System.Tuple<,,>.get_Item(int) | this parameter [Item3] -> return | true | -| System.Tuple<,>.Tuple(T1, T2) | parameter 0 -> return [Item1] | true | -| System.Tuple<,>.Tuple(T1, T2) | parameter 1 -> return [Item2] | true | -| System.Tuple<,>.get_Item(int) | this parameter [Item1] -> return | true | -| System.Tuple<,>.get_Item(int) | this parameter [Item2] -> return | true | -| System.Tuple<>.Tuple(T1) | parameter 0 -> return [Item1] | true | -| System.Tuple<>.get_Item(int) | this parameter [Item1] -> return | true | -| System.TupleExtensions.Deconstruct(Tuple>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13, out T14, out T15, out T16, out T17, out T18, out T19, out T20, out T21) | parameter 0 [Item1] -> parameter 1 | true | -| System.TupleExtensions.Deconstruct(Tuple>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13, out T14, out T15, out T16, out T17, out T18, out T19, out T20, out T21) | parameter 0 [Item2] -> parameter 2 | true | -| System.TupleExtensions.Deconstruct(Tuple>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13, out T14, out T15, out T16, out T17, out T18, out T19, out T20, out T21) | parameter 0 [Item3] -> parameter 3 | true | -| System.TupleExtensions.Deconstruct(Tuple>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13, out T14, out T15, out T16, out T17, out T18, out T19, out T20, out T21) | parameter 0 [Item4] -> parameter 4 | true | -| System.TupleExtensions.Deconstruct(Tuple>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13, out T14, out T15, out T16, out T17, out T18, out T19, out T20, out T21) | parameter 0 [Item5] -> parameter 5 | true | -| System.TupleExtensions.Deconstruct(Tuple>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13, out T14, out T15, out T16, out T17, out T18, out T19, out T20, out T21) | parameter 0 [Item6] -> parameter 6 | true | -| System.TupleExtensions.Deconstruct(Tuple>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13, out T14, out T15, out T16, out T17, out T18, out T19, out T20, out T21) | parameter 0 [Item7] -> parameter 7 | true | -| System.TupleExtensions.Deconstruct(Tuple>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13, out T14, out T15, out T16, out T17, out T18, out T19, out T20) | parameter 0 [Item1] -> parameter 1 | true | -| System.TupleExtensions.Deconstruct(Tuple>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13, out T14, out T15, out T16, out T17, out T18, out T19, out T20) | parameter 0 [Item2] -> parameter 2 | true | -| System.TupleExtensions.Deconstruct(Tuple>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13, out T14, out T15, out T16, out T17, out T18, out T19, out T20) | parameter 0 [Item3] -> parameter 3 | true | -| System.TupleExtensions.Deconstruct(Tuple>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13, out T14, out T15, out T16, out T17, out T18, out T19, out T20) | parameter 0 [Item4] -> parameter 4 | true | -| System.TupleExtensions.Deconstruct(Tuple>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13, out T14, out T15, out T16, out T17, out T18, out T19, out T20) | parameter 0 [Item5] -> parameter 5 | true | -| System.TupleExtensions.Deconstruct(Tuple>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13, out T14, out T15, out T16, out T17, out T18, out T19, out T20) | parameter 0 [Item6] -> parameter 6 | true | -| System.TupleExtensions.Deconstruct(Tuple>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13, out T14, out T15, out T16, out T17, out T18, out T19, out T20) | parameter 0 [Item7] -> parameter 7 | true | -| System.TupleExtensions.Deconstruct(Tuple>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13, out T14, out T15, out T16, out T17, out T18, out T19) | parameter 0 [Item1] -> parameter 1 | true | -| System.TupleExtensions.Deconstruct(Tuple>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13, out T14, out T15, out T16, out T17, out T18, out T19) | parameter 0 [Item2] -> parameter 2 | true | -| System.TupleExtensions.Deconstruct(Tuple>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13, out T14, out T15, out T16, out T17, out T18, out T19) | parameter 0 [Item3] -> parameter 3 | true | -| System.TupleExtensions.Deconstruct(Tuple>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13, out T14, out T15, out T16, out T17, out T18, out T19) | parameter 0 [Item4] -> parameter 4 | true | -| System.TupleExtensions.Deconstruct(Tuple>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13, out T14, out T15, out T16, out T17, out T18, out T19) | parameter 0 [Item5] -> parameter 5 | true | -| System.TupleExtensions.Deconstruct(Tuple>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13, out T14, out T15, out T16, out T17, out T18, out T19) | parameter 0 [Item6] -> parameter 6 | true | -| System.TupleExtensions.Deconstruct(Tuple>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13, out T14, out T15, out T16, out T17, out T18, out T19) | parameter 0 [Item7] -> parameter 7 | true | -| System.TupleExtensions.Deconstruct(Tuple>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13, out T14, out T15, out T16, out T17, out T18) | parameter 0 [Item1] -> parameter 1 | true | -| System.TupleExtensions.Deconstruct(Tuple>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13, out T14, out T15, out T16, out T17, out T18) | parameter 0 [Item2] -> parameter 2 | true | -| System.TupleExtensions.Deconstruct(Tuple>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13, out T14, out T15, out T16, out T17, out T18) | parameter 0 [Item3] -> parameter 3 | true | -| System.TupleExtensions.Deconstruct(Tuple>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13, out T14, out T15, out T16, out T17, out T18) | parameter 0 [Item4] -> parameter 4 | true | -| System.TupleExtensions.Deconstruct(Tuple>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13, out T14, out T15, out T16, out T17, out T18) | parameter 0 [Item5] -> parameter 5 | true | -| System.TupleExtensions.Deconstruct(Tuple>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13, out T14, out T15, out T16, out T17, out T18) | parameter 0 [Item6] -> parameter 6 | true | -| System.TupleExtensions.Deconstruct(Tuple>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13, out T14, out T15, out T16, out T17, out T18) | parameter 0 [Item7] -> parameter 7 | true | -| System.TupleExtensions.Deconstruct(Tuple>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13, out T14, out T15, out T16, out T17) | parameter 0 [Item1] -> parameter 1 | true | -| System.TupleExtensions.Deconstruct(Tuple>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13, out T14, out T15, out T16, out T17) | parameter 0 [Item2] -> parameter 2 | true | -| System.TupleExtensions.Deconstruct(Tuple>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13, out T14, out T15, out T16, out T17) | parameter 0 [Item3] -> parameter 3 | true | -| System.TupleExtensions.Deconstruct(Tuple>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13, out T14, out T15, out T16, out T17) | parameter 0 [Item4] -> parameter 4 | true | -| System.TupleExtensions.Deconstruct(Tuple>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13, out T14, out T15, out T16, out T17) | parameter 0 [Item5] -> parameter 5 | true | -| System.TupleExtensions.Deconstruct(Tuple>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13, out T14, out T15, out T16, out T17) | parameter 0 [Item6] -> parameter 6 | true | -| System.TupleExtensions.Deconstruct(Tuple>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13, out T14, out T15, out T16, out T17) | parameter 0 [Item7] -> parameter 7 | true | -| System.TupleExtensions.Deconstruct(Tuple>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13, out T14, out T15, out T16) | parameter 0 [Item1] -> parameter 1 | true | -| System.TupleExtensions.Deconstruct(Tuple>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13, out T14, out T15, out T16) | parameter 0 [Item2] -> parameter 2 | true | -| System.TupleExtensions.Deconstruct(Tuple>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13, out T14, out T15, out T16) | parameter 0 [Item3] -> parameter 3 | true | -| System.TupleExtensions.Deconstruct(Tuple>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13, out T14, out T15, out T16) | parameter 0 [Item4] -> parameter 4 | true | -| System.TupleExtensions.Deconstruct(Tuple>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13, out T14, out T15, out T16) | parameter 0 [Item5] -> parameter 5 | true | -| System.TupleExtensions.Deconstruct(Tuple>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13, out T14, out T15, out T16) | parameter 0 [Item6] -> parameter 6 | true | -| System.TupleExtensions.Deconstruct(Tuple>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13, out T14, out T15, out T16) | parameter 0 [Item7] -> parameter 7 | true | -| System.TupleExtensions.Deconstruct(Tuple>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13, out T14, out T15) | parameter 0 [Item1] -> parameter 1 | true | -| System.TupleExtensions.Deconstruct(Tuple>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13, out T14, out T15) | parameter 0 [Item2] -> parameter 2 | true | -| System.TupleExtensions.Deconstruct(Tuple>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13, out T14, out T15) | parameter 0 [Item3] -> parameter 3 | true | -| System.TupleExtensions.Deconstruct(Tuple>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13, out T14, out T15) | parameter 0 [Item4] -> parameter 4 | true | -| System.TupleExtensions.Deconstruct(Tuple>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13, out T14, out T15) | parameter 0 [Item5] -> parameter 5 | true | -| System.TupleExtensions.Deconstruct(Tuple>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13, out T14, out T15) | parameter 0 [Item6] -> parameter 6 | true | -| System.TupleExtensions.Deconstruct(Tuple>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13, out T14, out T15) | parameter 0 [Item7] -> parameter 7 | true | -| System.TupleExtensions.Deconstruct(Tuple>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13, out T14) | parameter 0 [Item1] -> parameter 1 | true | -| System.TupleExtensions.Deconstruct(Tuple>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13, out T14) | parameter 0 [Item2] -> parameter 2 | true | -| System.TupleExtensions.Deconstruct(Tuple>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13, out T14) | parameter 0 [Item3] -> parameter 3 | true | -| System.TupleExtensions.Deconstruct(Tuple>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13, out T14) | parameter 0 [Item4] -> parameter 4 | true | -| System.TupleExtensions.Deconstruct(Tuple>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13, out T14) | parameter 0 [Item5] -> parameter 5 | true | -| System.TupleExtensions.Deconstruct(Tuple>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13, out T14) | parameter 0 [Item6] -> parameter 6 | true | -| System.TupleExtensions.Deconstruct(Tuple>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13, out T14) | parameter 0 [Item7] -> parameter 7 | true | -| System.TupleExtensions.Deconstruct(Tuple>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13) | parameter 0 [Item1] -> parameter 1 | true | -| System.TupleExtensions.Deconstruct(Tuple>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13) | parameter 0 [Item2] -> parameter 2 | true | -| System.TupleExtensions.Deconstruct(Tuple>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13) | parameter 0 [Item3] -> parameter 3 | true | -| System.TupleExtensions.Deconstruct(Tuple>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13) | parameter 0 [Item4] -> parameter 4 | true | -| System.TupleExtensions.Deconstruct(Tuple>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13) | parameter 0 [Item5] -> parameter 5 | true | -| System.TupleExtensions.Deconstruct(Tuple>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13) | parameter 0 [Item6] -> parameter 6 | true | -| System.TupleExtensions.Deconstruct(Tuple>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13) | parameter 0 [Item7] -> parameter 7 | true | -| System.TupleExtensions.Deconstruct(Tuple>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12) | parameter 0 [Item1] -> parameter 1 | true | -| System.TupleExtensions.Deconstruct(Tuple>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12) | parameter 0 [Item2] -> parameter 2 | true | -| System.TupleExtensions.Deconstruct(Tuple>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12) | parameter 0 [Item3] -> parameter 3 | true | -| System.TupleExtensions.Deconstruct(Tuple>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12) | parameter 0 [Item4] -> parameter 4 | true | -| System.TupleExtensions.Deconstruct(Tuple>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12) | parameter 0 [Item5] -> parameter 5 | true | -| System.TupleExtensions.Deconstruct(Tuple>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12) | parameter 0 [Item6] -> parameter 6 | true | -| System.TupleExtensions.Deconstruct(Tuple>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12) | parameter 0 [Item7] -> parameter 7 | true | -| System.TupleExtensions.Deconstruct(Tuple>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11) | parameter 0 [Item1] -> parameter 1 | true | -| System.TupleExtensions.Deconstruct(Tuple>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11) | parameter 0 [Item2] -> parameter 2 | true | -| System.TupleExtensions.Deconstruct(Tuple>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11) | parameter 0 [Item3] -> parameter 3 | true | -| System.TupleExtensions.Deconstruct(Tuple>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11) | parameter 0 [Item4] -> parameter 4 | true | -| System.TupleExtensions.Deconstruct(Tuple>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11) | parameter 0 [Item5] -> parameter 5 | true | -| System.TupleExtensions.Deconstruct(Tuple>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11) | parameter 0 [Item6] -> parameter 6 | true | -| System.TupleExtensions.Deconstruct(Tuple>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11) | parameter 0 [Item7] -> parameter 7 | true | -| System.TupleExtensions.Deconstruct(Tuple>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10) | parameter 0 [Item1] -> parameter 1 | true | -| System.TupleExtensions.Deconstruct(Tuple>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10) | parameter 0 [Item2] -> parameter 2 | true | -| System.TupleExtensions.Deconstruct(Tuple>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10) | parameter 0 [Item3] -> parameter 3 | true | -| System.TupleExtensions.Deconstruct(Tuple>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10) | parameter 0 [Item4] -> parameter 4 | true | -| System.TupleExtensions.Deconstruct(Tuple>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10) | parameter 0 [Item5] -> parameter 5 | true | -| System.TupleExtensions.Deconstruct(Tuple>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10) | parameter 0 [Item6] -> parameter 6 | true | -| System.TupleExtensions.Deconstruct(Tuple>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10) | parameter 0 [Item7] -> parameter 7 | true | -| System.TupleExtensions.Deconstruct(Tuple>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9) | parameter 0 [Item1] -> parameter 1 | true | -| System.TupleExtensions.Deconstruct(Tuple>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9) | parameter 0 [Item2] -> parameter 2 | true | -| System.TupleExtensions.Deconstruct(Tuple>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9) | parameter 0 [Item3] -> parameter 3 | true | -| System.TupleExtensions.Deconstruct(Tuple>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9) | parameter 0 [Item4] -> parameter 4 | true | -| System.TupleExtensions.Deconstruct(Tuple>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9) | parameter 0 [Item5] -> parameter 5 | true | -| System.TupleExtensions.Deconstruct(Tuple>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9) | parameter 0 [Item6] -> parameter 6 | true | -| System.TupleExtensions.Deconstruct(Tuple>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9) | parameter 0 [Item7] -> parameter 7 | true | -| System.TupleExtensions.Deconstruct(Tuple>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8) | parameter 0 [Item1] -> parameter 1 | true | -| System.TupleExtensions.Deconstruct(Tuple>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8) | parameter 0 [Item2] -> parameter 2 | true | -| System.TupleExtensions.Deconstruct(Tuple>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8) | parameter 0 [Item3] -> parameter 3 | true | -| System.TupleExtensions.Deconstruct(Tuple>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8) | parameter 0 [Item4] -> parameter 4 | true | -| System.TupleExtensions.Deconstruct(Tuple>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8) | parameter 0 [Item5] -> parameter 5 | true | -| System.TupleExtensions.Deconstruct(Tuple>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8) | parameter 0 [Item6] -> parameter 6 | true | -| System.TupleExtensions.Deconstruct(Tuple>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8) | parameter 0 [Item7] -> parameter 7 | true | -| System.TupleExtensions.Deconstruct(Tuple, out T1, out T2, out T3, out T4, out T5, out T6, out T7) | parameter 0 [Item1] -> parameter 1 | true | -| System.TupleExtensions.Deconstruct(Tuple, out T1, out T2, out T3, out T4, out T5, out T6, out T7) | parameter 0 [Item2] -> parameter 2 | true | -| System.TupleExtensions.Deconstruct(Tuple, out T1, out T2, out T3, out T4, out T5, out T6, out T7) | parameter 0 [Item3] -> parameter 3 | true | -| System.TupleExtensions.Deconstruct(Tuple, out T1, out T2, out T3, out T4, out T5, out T6, out T7) | parameter 0 [Item4] -> parameter 4 | true | -| System.TupleExtensions.Deconstruct(Tuple, out T1, out T2, out T3, out T4, out T5, out T6, out T7) | parameter 0 [Item5] -> parameter 5 | true | -| System.TupleExtensions.Deconstruct(Tuple, out T1, out T2, out T3, out T4, out T5, out T6, out T7) | parameter 0 [Item6] -> parameter 6 | true | -| System.TupleExtensions.Deconstruct(Tuple, out T1, out T2, out T3, out T4, out T5, out T6, out T7) | parameter 0 [Item7] -> parameter 7 | true | -| System.TupleExtensions.Deconstruct(Tuple, out T1, out T2, out T3, out T4, out T5, out T6) | parameter 0 [Item1] -> parameter 1 | true | -| System.TupleExtensions.Deconstruct(Tuple, out T1, out T2, out T3, out T4, out T5, out T6) | parameter 0 [Item2] -> parameter 2 | true | -| System.TupleExtensions.Deconstruct(Tuple, out T1, out T2, out T3, out T4, out T5, out T6) | parameter 0 [Item3] -> parameter 3 | true | -| System.TupleExtensions.Deconstruct(Tuple, out T1, out T2, out T3, out T4, out T5, out T6) | parameter 0 [Item4] -> parameter 4 | true | -| System.TupleExtensions.Deconstruct(Tuple, out T1, out T2, out T3, out T4, out T5, out T6) | parameter 0 [Item5] -> parameter 5 | true | -| System.TupleExtensions.Deconstruct(Tuple, out T1, out T2, out T3, out T4, out T5, out T6) | parameter 0 [Item6] -> parameter 6 | true | -| System.TupleExtensions.Deconstruct(Tuple, out T1, out T2, out T3, out T4, out T5) | parameter 0 [Item1] -> parameter 1 | true | -| System.TupleExtensions.Deconstruct(Tuple, out T1, out T2, out T3, out T4, out T5) | parameter 0 [Item2] -> parameter 2 | true | -| System.TupleExtensions.Deconstruct(Tuple, out T1, out T2, out T3, out T4, out T5) | parameter 0 [Item3] -> parameter 3 | true | -| System.TupleExtensions.Deconstruct(Tuple, out T1, out T2, out T3, out T4, out T5) | parameter 0 [Item4] -> parameter 4 | true | -| System.TupleExtensions.Deconstruct(Tuple, out T1, out T2, out T3, out T4, out T5) | parameter 0 [Item5] -> parameter 5 | true | -| System.TupleExtensions.Deconstruct(Tuple, out T1, out T2, out T3, out T4) | parameter 0 [Item1] -> parameter 1 | true | -| System.TupleExtensions.Deconstruct(Tuple, out T1, out T2, out T3, out T4) | parameter 0 [Item2] -> parameter 2 | true | -| System.TupleExtensions.Deconstruct(Tuple, out T1, out T2, out T3, out T4) | parameter 0 [Item3] -> parameter 3 | true | -| System.TupleExtensions.Deconstruct(Tuple, out T1, out T2, out T3, out T4) | parameter 0 [Item4] -> parameter 4 | true | -| System.TupleExtensions.Deconstruct(Tuple, out T1, out T2, out T3) | parameter 0 [Item1] -> parameter 1 | true | -| System.TupleExtensions.Deconstruct(Tuple, out T1, out T2, out T3) | parameter 0 [Item2] -> parameter 2 | true | -| System.TupleExtensions.Deconstruct(Tuple, out T1, out T2, out T3) | parameter 0 [Item3] -> parameter 3 | true | -| System.TupleExtensions.Deconstruct(Tuple, out T1, out T2) | parameter 0 [Item1] -> parameter 1 | true | -| System.TupleExtensions.Deconstruct(Tuple, out T1, out T2) | parameter 0 [Item2] -> parameter 2 | true | -| System.TupleExtensions.Deconstruct(Tuple, out T1) | parameter 0 [Item1] -> parameter 1 | true | -| System.Uri.ToString() | this parameter -> return | false | -| System.Uri.Uri(string) | parameter 0 -> return | false | -| System.Uri.Uri(string, UriKind) | parameter 0 -> return | false | -| System.Uri.Uri(string, bool) | parameter 0 -> return | false | -| System.Uri.get_OriginalString() | this parameter -> return | false | -| System.Uri.get_PathAndQuery() | this parameter -> return | false | -| System.Uri.get_Query() | this parameter -> return | false | -| System.ValueTuple<,,,,,,,>.ValueTuple(T1, T2, T3, T4, T5, T6, T7, TRest) | parameter 0 -> return [Item1] | true | -| System.ValueTuple<,,,,,,,>.ValueTuple(T1, T2, T3, T4, T5, T6, T7, TRest) | parameter 1 -> return [Item2] | true | -| System.ValueTuple<,,,,,,,>.ValueTuple(T1, T2, T3, T4, T5, T6, T7, TRest) | parameter 2 -> return [Item3] | true | -| System.ValueTuple<,,,,,,,>.ValueTuple(T1, T2, T3, T4, T5, T6, T7, TRest) | parameter 3 -> return [Item4] | true | -| System.ValueTuple<,,,,,,,>.ValueTuple(T1, T2, T3, T4, T5, T6, T7, TRest) | parameter 4 -> return [Item5] | true | -| System.ValueTuple<,,,,,,,>.ValueTuple(T1, T2, T3, T4, T5, T6, T7, TRest) | parameter 5 -> return [Item6] | true | -| System.ValueTuple<,,,,,,,>.ValueTuple(T1, T2, T3, T4, T5, T6, T7, TRest) | parameter 6 -> return [Item7] | true | -| System.ValueTuple<,,,,,,,>.get_Item(int) | this parameter [Item1] -> return | true | -| System.ValueTuple<,,,,,,,>.get_Item(int) | this parameter [Item2] -> return | true | -| System.ValueTuple<,,,,,,,>.get_Item(int) | this parameter [Item3] -> return | true | -| System.ValueTuple<,,,,,,,>.get_Item(int) | this parameter [Item4] -> return | true | -| System.ValueTuple<,,,,,,,>.get_Item(int) | this parameter [Item5] -> return | true | -| System.ValueTuple<,,,,,,,>.get_Item(int) | this parameter [Item6] -> return | true | -| System.ValueTuple<,,,,,,,>.get_Item(int) | this parameter [Item7] -> return | true | -| System.Web.HttpCookie.get_Value() | this parameter -> return | false | -| System.Web.HttpCookie.get_Values() | this parameter -> return | false | -| System.Web.HttpServerUtility.UrlEncode(string) | parameter 0 -> return | false | -| System.Web.HttpUtility.HtmlAttributeEncode(string) | parameter 0 -> return | false | -| System.Web.HttpUtility.HtmlEncode(object) | parameter 0 -> return | false | -| System.Web.HttpUtility.HtmlEncode(string) | parameter 0 -> return | false | -| System.Web.HttpUtility.UrlEncode(string) | parameter 0 -> return | false | -| System.Web.UI.WebControls.TextBox.get_Text() | this parameter -> return | false | +| MS.Internal.Xml.Linq.ComponentModel.XDeferredAxis<>.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | +| System.().Create(T1, T2, T3, T4, T5, T6, T7, T8) | argument 0 -> field Item1 of return (normal) | true | +| System.().Create(T1, T2, T3, T4, T5, T6, T7, T8) | argument 1 -> field Item2 of return (normal) | true | +| System.().Create(T1, T2, T3, T4, T5, T6, T7, T8) | argument 2 -> field Item3 of return (normal) | true | +| System.().Create(T1, T2, T3, T4, T5, T6, T7, T8) | argument 3 -> field Item4 of return (normal) | true | +| System.().Create(T1, T2, T3, T4, T5, T6, T7, T8) | argument 4 -> field Item5 of return (normal) | true | +| System.().Create(T1, T2, T3, T4, T5, T6, T7, T8) | argument 5 -> field Item6 of return (normal) | true | +| System.().Create(T1, T2, T3, T4, T5, T6, T7, T8) | argument 6 -> field Item7 of return (normal) | true | +| System.().Create(T1, T2, T3, T4, T5, T6, T7, T8) | argument 7 -> field Item8 of return (normal) | true | +| System.().Create(T1, T2, T3, T4, T5, T6, T7) | argument 0 -> field Item1 of return (normal) | true | +| System.().Create(T1, T2, T3, T4, T5, T6, T7) | argument 1 -> field Item2 of return (normal) | true | +| System.().Create(T1, T2, T3, T4, T5, T6, T7) | argument 2 -> field Item3 of return (normal) | true | +| System.().Create(T1, T2, T3, T4, T5, T6, T7) | argument 3 -> field Item4 of return (normal) | true | +| System.().Create(T1, T2, T3, T4, T5, T6, T7) | argument 4 -> field Item5 of return (normal) | true | +| System.().Create(T1, T2, T3, T4, T5, T6, T7) | argument 5 -> field Item6 of return (normal) | true | +| System.().Create(T1, T2, T3, T4, T5, T6, T7) | argument 6 -> field Item7 of return (normal) | true | +| System.().Create(T1, T2, T3, T4, T5, T6) | argument 0 -> field Item1 of return (normal) | true | +| System.().Create(T1, T2, T3, T4, T5, T6) | argument 1 -> field Item2 of return (normal) | true | +| System.().Create(T1, T2, T3, T4, T5, T6) | argument 2 -> field Item3 of return (normal) | true | +| System.().Create(T1, T2, T3, T4, T5, T6) | argument 3 -> field Item4 of return (normal) | true | +| System.().Create(T1, T2, T3, T4, T5, T6) | argument 4 -> field Item5 of return (normal) | true | +| System.().Create(T1, T2, T3, T4, T5, T6) | argument 5 -> field Item6 of return (normal) | true | +| System.().Create(T1, T2, T3, T4, T5) | argument 0 -> field Item1 of return (normal) | true | +| System.().Create(T1, T2, T3, T4, T5) | argument 1 -> field Item2 of return (normal) | true | +| System.().Create(T1, T2, T3, T4, T5) | argument 2 -> field Item3 of return (normal) | true | +| System.().Create(T1, T2, T3, T4, T5) | argument 3 -> field Item4 of return (normal) | true | +| System.().Create(T1, T2, T3, T4, T5) | argument 4 -> field Item5 of return (normal) | true | +| System.().Create(T1, T2, T3, T4) | argument 0 -> field Item1 of return (normal) | true | +| System.().Create(T1, T2, T3, T4) | argument 1 -> field Item2 of return (normal) | true | +| System.().Create(T1, T2, T3, T4) | argument 2 -> field Item3 of return (normal) | true | +| System.().Create(T1, T2, T3, T4) | argument 3 -> field Item4 of return (normal) | true | +| System.().Create(T1, T2, T3) | argument 0 -> field Item1 of return (normal) | true | +| System.().Create(T1, T2, T3) | argument 1 -> field Item2 of return (normal) | true | +| System.().Create(T1, T2, T3) | argument 2 -> field Item3 of return (normal) | true | +| System.().Create(T1, T2) | argument 0 -> field Item1 of return (normal) | true | +| System.().Create(T1, T2) | argument 1 -> field Item2 of return (normal) | true | +| System.().Create(T1) | argument 0 -> field Item1 of return (normal) | true | +| System.(T1).ValueTuple(T1) | argument 0 -> field Item1 of return (normal) | true | +| System.(T1).get_Item(int) | field Item1 of argument -1 -> return (normal) | true | +| System.(T1,T2).ValueTuple(T1, T2) | argument 0 -> field Item1 of return (normal) | true | +| System.(T1,T2).ValueTuple(T1, T2) | argument 1 -> field Item2 of return (normal) | true | +| System.(T1,T2).get_Item(int) | field Item1 of argument -1 -> return (normal) | true | +| System.(T1,T2).get_Item(int) | field Item2 of argument -1 -> return (normal) | true | +| System.(T1,T2,T3).ValueTuple(T1, T2, T3) | argument 0 -> field Item1 of return (normal) | true | +| System.(T1,T2,T3).ValueTuple(T1, T2, T3) | argument 1 -> field Item2 of return (normal) | true | +| System.(T1,T2,T3).ValueTuple(T1, T2, T3) | argument 2 -> field Item3 of return (normal) | true | +| System.(T1,T2,T3).get_Item(int) | field Item1 of argument -1 -> return (normal) | true | +| System.(T1,T2,T3).get_Item(int) | field Item2 of argument -1 -> return (normal) | true | +| System.(T1,T2,T3).get_Item(int) | field Item3 of argument -1 -> return (normal) | true | +| System.(T1,T2,T3,T4).ValueTuple(T1, T2, T3, T4) | argument 0 -> field Item1 of return (normal) | true | +| System.(T1,T2,T3,T4).ValueTuple(T1, T2, T3, T4) | argument 1 -> field Item2 of return (normal) | true | +| System.(T1,T2,T3,T4).ValueTuple(T1, T2, T3, T4) | argument 2 -> field Item3 of return (normal) | true | +| System.(T1,T2,T3,T4).ValueTuple(T1, T2, T3, T4) | argument 3 -> field Item4 of return (normal) | true | +| System.(T1,T2,T3,T4).get_Item(int) | field Item1 of argument -1 -> return (normal) | true | +| System.(T1,T2,T3,T4).get_Item(int) | field Item2 of argument -1 -> return (normal) | true | +| System.(T1,T2,T3,T4).get_Item(int) | field Item3 of argument -1 -> return (normal) | true | +| System.(T1,T2,T3,T4).get_Item(int) | field Item4 of argument -1 -> return (normal) | true | +| System.(T1,T2,T3,T4,T5).ValueTuple(T1, T2, T3, T4, T5) | argument 0 -> field Item1 of return (normal) | true | +| System.(T1,T2,T3,T4,T5).ValueTuple(T1, T2, T3, T4, T5) | argument 1 -> field Item2 of return (normal) | true | +| System.(T1,T2,T3,T4,T5).ValueTuple(T1, T2, T3, T4, T5) | argument 2 -> field Item3 of return (normal) | true | +| System.(T1,T2,T3,T4,T5).ValueTuple(T1, T2, T3, T4, T5) | argument 3 -> field Item4 of return (normal) | true | +| System.(T1,T2,T3,T4,T5).ValueTuple(T1, T2, T3, T4, T5) | argument 4 -> field Item5 of return (normal) | true | +| System.(T1,T2,T3,T4,T5).get_Item(int) | field Item1 of argument -1 -> return (normal) | true | +| System.(T1,T2,T3,T4,T5).get_Item(int) | field Item2 of argument -1 -> return (normal) | true | +| System.(T1,T2,T3,T4,T5).get_Item(int) | field Item3 of argument -1 -> return (normal) | true | +| System.(T1,T2,T3,T4,T5).get_Item(int) | field Item4 of argument -1 -> return (normal) | true | +| System.(T1,T2,T3,T4,T5).get_Item(int) | field Item5 of argument -1 -> return (normal) | true | +| System.(T1,T2,T3,T4,T5,T6).ValueTuple(T1, T2, T3, T4, T5, T6) | argument 0 -> field Item1 of return (normal) | true | +| System.(T1,T2,T3,T4,T5,T6).ValueTuple(T1, T2, T3, T4, T5, T6) | argument 1 -> field Item2 of return (normal) | true | +| System.(T1,T2,T3,T4,T5,T6).ValueTuple(T1, T2, T3, T4, T5, T6) | argument 2 -> field Item3 of return (normal) | true | +| System.(T1,T2,T3,T4,T5,T6).ValueTuple(T1, T2, T3, T4, T5, T6) | argument 3 -> field Item4 of return (normal) | true | +| System.(T1,T2,T3,T4,T5,T6).ValueTuple(T1, T2, T3, T4, T5, T6) | argument 4 -> field Item5 of return (normal) | true | +| System.(T1,T2,T3,T4,T5,T6).ValueTuple(T1, T2, T3, T4, T5, T6) | argument 5 -> field Item6 of return (normal) | true | +| System.(T1,T2,T3,T4,T5,T6).get_Item(int) | field Item1 of argument -1 -> return (normal) | true | +| System.(T1,T2,T3,T4,T5,T6).get_Item(int) | field Item2 of argument -1 -> return (normal) | true | +| System.(T1,T2,T3,T4,T5,T6).get_Item(int) | field Item3 of argument -1 -> return (normal) | true | +| System.(T1,T2,T3,T4,T5,T6).get_Item(int) | field Item4 of argument -1 -> return (normal) | true | +| System.(T1,T2,T3,T4,T5,T6).get_Item(int) | field Item5 of argument -1 -> return (normal) | true | +| System.(T1,T2,T3,T4,T5,T6).get_Item(int) | field Item6 of argument -1 -> return (normal) | true | +| System.(T1,T2,T3,T4,T5,T6,T7).ValueTuple(T1, T2, T3, T4, T5, T6, T7) | argument 0 -> field Item1 of return (normal) | true | +| System.(T1,T2,T3,T4,T5,T6,T7).ValueTuple(T1, T2, T3, T4, T5, T6, T7) | argument 1 -> field Item2 of return (normal) | true | +| System.(T1,T2,T3,T4,T5,T6,T7).ValueTuple(T1, T2, T3, T4, T5, T6, T7) | argument 2 -> field Item3 of return (normal) | true | +| System.(T1,T2,T3,T4,T5,T6,T7).ValueTuple(T1, T2, T3, T4, T5, T6, T7) | argument 3 -> field Item4 of return (normal) | true | +| System.(T1,T2,T3,T4,T5,T6,T7).ValueTuple(T1, T2, T3, T4, T5, T6, T7) | argument 4 -> field Item5 of return (normal) | true | +| System.(T1,T2,T3,T4,T5,T6,T7).ValueTuple(T1, T2, T3, T4, T5, T6, T7) | argument 5 -> field Item6 of return (normal) | true | +| System.(T1,T2,T3,T4,T5,T6,T7).ValueTuple(T1, T2, T3, T4, T5, T6, T7) | argument 6 -> field Item7 of return (normal) | true | +| System.(T1,T2,T3,T4,T5,T6,T7).get_Item(int) | field Item1 of argument -1 -> return (normal) | true | +| System.(T1,T2,T3,T4,T5,T6,T7).get_Item(int) | field Item2 of argument -1 -> return (normal) | true | +| System.(T1,T2,T3,T4,T5,T6,T7).get_Item(int) | field Item3 of argument -1 -> return (normal) | true | +| System.(T1,T2,T3,T4,T5,T6,T7).get_Item(int) | field Item4 of argument -1 -> return (normal) | true | +| System.(T1,T2,T3,T4,T5,T6,T7).get_Item(int) | field Item5 of argument -1 -> return (normal) | true | +| System.(T1,T2,T3,T4,T5,T6,T7).get_Item(int) | field Item6 of argument -1 -> return (normal) | true | +| System.(T1,T2,T3,T4,T5,T6,T7).get_Item(int) | field Item7 of argument -1 -> return (normal) | true | +| System.Array.Add(object) | argument 0 -> element of argument -1 | true | +| System.Array.AsReadOnly(T[]) | element of argument 0 -> element of return (normal) | true | +| System.Array.Clone() | element of argument 0 -> element of return (normal) | true | +| System.Array.CopyTo(Array, int) | element of argument -1 -> element of return (out parameter 0) | true | +| System.Array.CopyTo(Array, long) | element of argument -1 -> element of return (out parameter 0) | true | +| System.Array.Find(T[], Predicate) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Array.Find(T[], Predicate) | element of argument 0 -> return (normal) | true | +| System.Array.FindAll(T[], Predicate) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Array.FindAll(T[], Predicate) | element of argument 0 -> return (normal) | true | +| System.Array.FindLast(T[], Predicate) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Array.FindLast(T[], Predicate) | element of argument 0 -> return (normal) | true | +| System.Array.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | +| System.Array.Insert(int, object) | argument 1 -> element of argument -1 | true | +| System.Array.Reverse(Array) | element of argument 0 -> element of return (normal) | true | +| System.Array.Reverse(Array, int, int) | element of argument 0 -> element of return (normal) | true | +| System.Array.Reverse(T[]) | element of argument 0 -> element of return (normal) | true | +| System.Array.Reverse(T[], int, int) | element of argument 0 -> element of return (normal) | true | +| System.Array.get_Item(int) | element of argument -1 -> return (normal) | true | +| System.Array.set_Item(int, object) | argument 1 -> element of argument -1 | true | +| System.Boolean.Parse(string) | argument 0 -> return (normal) | false | +| System.Boolean.TryParse(string, out bool) | argument 0 -> return (normal) | false | +| System.Boolean.TryParse(string, out bool) | argument 0 -> return (out parameter 1) | false | +| System.Collections.ArrayList.Add(object) | argument 0 -> element of argument -1 | true | +| System.Collections.ArrayList.AddRange(ICollection) | element of argument 0 -> element of argument -1 | true | +| System.Collections.ArrayList.Clone() | element of argument 0 -> element of return (normal) | true | +| System.Collections.ArrayList.CopyTo(Array, int) | element of argument -1 -> element of return (out parameter 0) | true | +| System.Collections.ArrayList.FixedSize(ArrayList) | element of argument 0 -> element of return (normal) | true | +| System.Collections.ArrayList.FixedSize(IList) | element of argument 0 -> element of return (normal) | true | +| System.Collections.ArrayList.FixedSizeArrayList.Add(object) | argument 0 -> element of argument -1 | true | +| System.Collections.ArrayList.FixedSizeArrayList.AddRange(ICollection) | element of argument 0 -> element of argument -1 | true | +| System.Collections.ArrayList.FixedSizeArrayList.Clone() | element of argument 0 -> element of return (normal) | true | +| System.Collections.ArrayList.FixedSizeArrayList.CopyTo(Array, int) | element of argument -1 -> element of return (out parameter 0) | true | +| System.Collections.ArrayList.FixedSizeArrayList.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | +| System.Collections.ArrayList.FixedSizeArrayList.GetEnumerator(int, int) | element of argument -1 -> property Current of return (normal) | true | +| System.Collections.ArrayList.FixedSizeArrayList.GetRange(int, int) | element of argument 0 -> element of return (normal) | true | +| System.Collections.ArrayList.FixedSizeArrayList.Insert(int, object) | argument 1 -> element of argument -1 | true | +| System.Collections.ArrayList.FixedSizeArrayList.InsertRange(int, ICollection) | element of argument 1 -> element of argument -1 | true | +| System.Collections.ArrayList.FixedSizeArrayList.Reverse(int, int) | element of argument 0 -> element of return (normal) | true | +| System.Collections.ArrayList.FixedSizeArrayList.get_Item(int) | element of argument -1 -> return (normal) | true | +| System.Collections.ArrayList.FixedSizeArrayList.set_Item(int, object) | argument 1 -> element of argument -1 | true | +| System.Collections.ArrayList.FixedSizeList.Add(object) | argument 0 -> element of argument -1 | true | +| System.Collections.ArrayList.FixedSizeList.CopyTo(Array, int) | element of argument -1 -> element of return (out parameter 0) | true | +| System.Collections.ArrayList.FixedSizeList.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | +| System.Collections.ArrayList.FixedSizeList.Insert(int, object) | argument 1 -> element of argument -1 | true | +| System.Collections.ArrayList.FixedSizeList.get_Item(int) | element of argument -1 -> return (normal) | true | +| System.Collections.ArrayList.FixedSizeList.set_Item(int, object) | argument 1 -> element of argument -1 | true | +| System.Collections.ArrayList.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | +| System.Collections.ArrayList.GetEnumerator(int, int) | element of argument -1 -> property Current of return (normal) | true | +| System.Collections.ArrayList.GetRange(int, int) | element of argument 0 -> element of return (normal) | true | +| System.Collections.ArrayList.IListWrapper.Add(object) | argument 0 -> element of argument -1 | true | +| System.Collections.ArrayList.IListWrapper.AddRange(ICollection) | element of argument 0 -> element of argument -1 | true | +| System.Collections.ArrayList.IListWrapper.Clone() | element of argument 0 -> element of return (normal) | true | +| System.Collections.ArrayList.IListWrapper.CopyTo(Array, int) | element of argument -1 -> element of return (out parameter 0) | true | +| System.Collections.ArrayList.IListWrapper.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | +| System.Collections.ArrayList.IListWrapper.GetEnumerator(int, int) | element of argument -1 -> property Current of return (normal) | true | +| System.Collections.ArrayList.IListWrapper.GetRange(int, int) | element of argument 0 -> element of return (normal) | true | +| System.Collections.ArrayList.IListWrapper.Insert(int, object) | argument 1 -> element of argument -1 | true | +| System.Collections.ArrayList.IListWrapper.InsertRange(int, ICollection) | element of argument 1 -> element of argument -1 | true | +| System.Collections.ArrayList.IListWrapper.Reverse(int, int) | element of argument 0 -> element of return (normal) | true | +| System.Collections.ArrayList.IListWrapper.get_Item(int) | element of argument -1 -> return (normal) | true | +| System.Collections.ArrayList.IListWrapper.set_Item(int, object) | argument 1 -> element of argument -1 | true | +| System.Collections.ArrayList.Insert(int, object) | argument 1 -> element of argument -1 | true | +| System.Collections.ArrayList.InsertRange(int, ICollection) | element of argument 1 -> element of argument -1 | true | +| System.Collections.ArrayList.Range.Add(object) | argument 0 -> element of argument -1 | true | +| System.Collections.ArrayList.Range.AddRange(ICollection) | element of argument 0 -> element of argument -1 | true | +| System.Collections.ArrayList.Range.Clone() | element of argument 0 -> element of return (normal) | true | +| System.Collections.ArrayList.Range.CopyTo(Array, int) | element of argument -1 -> element of return (out parameter 0) | true | +| System.Collections.ArrayList.Range.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | +| System.Collections.ArrayList.Range.GetEnumerator(int, int) | element of argument -1 -> property Current of return (normal) | true | +| System.Collections.ArrayList.Range.GetRange(int, int) | element of argument 0 -> element of return (normal) | true | +| System.Collections.ArrayList.Range.Insert(int, object) | argument 1 -> element of argument -1 | true | +| System.Collections.ArrayList.Range.InsertRange(int, ICollection) | element of argument 1 -> element of argument -1 | true | +| System.Collections.ArrayList.Range.Reverse(int, int) | element of argument 0 -> element of return (normal) | true | +| System.Collections.ArrayList.Range.get_Item(int) | element of argument -1 -> return (normal) | true | +| System.Collections.ArrayList.Range.set_Item(int, object) | argument 1 -> element of argument -1 | true | +| System.Collections.ArrayList.ReadOnlyArrayList.Add(object) | argument 0 -> element of argument -1 | true | +| System.Collections.ArrayList.ReadOnlyArrayList.AddRange(ICollection) | element of argument 0 -> element of argument -1 | true | +| System.Collections.ArrayList.ReadOnlyArrayList.Clone() | element of argument 0 -> element of return (normal) | true | +| System.Collections.ArrayList.ReadOnlyArrayList.CopyTo(Array, int) | element of argument -1 -> element of return (out parameter 0) | true | +| System.Collections.ArrayList.ReadOnlyArrayList.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | +| System.Collections.ArrayList.ReadOnlyArrayList.GetEnumerator(int, int) | element of argument -1 -> property Current of return (normal) | true | +| System.Collections.ArrayList.ReadOnlyArrayList.GetRange(int, int) | element of argument 0 -> element of return (normal) | true | +| System.Collections.ArrayList.ReadOnlyArrayList.Insert(int, object) | argument 1 -> element of argument -1 | true | +| System.Collections.ArrayList.ReadOnlyArrayList.InsertRange(int, ICollection) | element of argument 1 -> element of argument -1 | true | +| System.Collections.ArrayList.ReadOnlyArrayList.Reverse(int, int) | element of argument 0 -> element of return (normal) | true | +| System.Collections.ArrayList.ReadOnlyArrayList.get_Item(int) | element of argument -1 -> return (normal) | true | +| System.Collections.ArrayList.ReadOnlyArrayList.set_Item(int, object) | argument 1 -> element of argument -1 | true | +| System.Collections.ArrayList.ReadOnlyList.Add(object) | argument 0 -> element of argument -1 | true | +| System.Collections.ArrayList.ReadOnlyList.CopyTo(Array, int) | element of argument -1 -> element of return (out parameter 0) | true | +| System.Collections.ArrayList.ReadOnlyList.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | +| System.Collections.ArrayList.ReadOnlyList.Insert(int, object) | argument 1 -> element of argument -1 | true | +| System.Collections.ArrayList.ReadOnlyList.get_Item(int) | element of argument -1 -> return (normal) | true | +| System.Collections.ArrayList.ReadOnlyList.set_Item(int, object) | argument 1 -> element of argument -1 | true | +| System.Collections.ArrayList.Repeat(object, int) | argument 0 -> element of return (normal) | true | +| System.Collections.ArrayList.Reverse() | element of argument 0 -> element of return (normal) | true | +| System.Collections.ArrayList.Reverse(int, int) | element of argument 0 -> element of return (normal) | true | +| System.Collections.ArrayList.SyncArrayList.Add(object) | argument 0 -> element of argument -1 | true | +| System.Collections.ArrayList.SyncArrayList.AddRange(ICollection) | element of argument 0 -> element of argument -1 | true | +| System.Collections.ArrayList.SyncArrayList.Clone() | element of argument 0 -> element of return (normal) | true | +| System.Collections.ArrayList.SyncArrayList.CopyTo(Array, int) | element of argument -1 -> element of return (out parameter 0) | true | +| System.Collections.ArrayList.SyncArrayList.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | +| System.Collections.ArrayList.SyncArrayList.GetEnumerator(int, int) | element of argument -1 -> property Current of return (normal) | true | +| System.Collections.ArrayList.SyncArrayList.GetRange(int, int) | element of argument 0 -> element of return (normal) | true | +| System.Collections.ArrayList.SyncArrayList.Insert(int, object) | argument 1 -> element of argument -1 | true | +| System.Collections.ArrayList.SyncArrayList.InsertRange(int, ICollection) | element of argument 1 -> element of argument -1 | true | +| System.Collections.ArrayList.SyncArrayList.Reverse(int, int) | element of argument 0 -> element of return (normal) | true | +| System.Collections.ArrayList.SyncArrayList.get_Item(int) | element of argument -1 -> return (normal) | true | +| System.Collections.ArrayList.SyncArrayList.set_Item(int, object) | argument 1 -> element of argument -1 | true | +| System.Collections.ArrayList.SyncIList.Add(object) | argument 0 -> element of argument -1 | true | +| System.Collections.ArrayList.SyncIList.CopyTo(Array, int) | element of argument -1 -> element of return (out parameter 0) | true | +| System.Collections.ArrayList.SyncIList.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | +| System.Collections.ArrayList.SyncIList.Insert(int, object) | argument 1 -> element of argument -1 | true | +| System.Collections.ArrayList.SyncIList.get_Item(int) | element of argument -1 -> return (normal) | true | +| System.Collections.ArrayList.SyncIList.set_Item(int, object) | argument 1 -> element of argument -1 | true | +| System.Collections.ArrayList.get_Item(int) | element of argument -1 -> return (normal) | true | +| System.Collections.ArrayList.set_Item(int, object) | argument 1 -> element of argument -1 | true | +| System.Collections.BitArray.Clone() | element of argument 0 -> element of return (normal) | true | +| System.Collections.BitArray.CopyTo(Array, int) | element of argument -1 -> element of return (out parameter 0) | true | +| System.Collections.BitArray.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | +| System.Collections.CollectionBase.Add(object) | argument 0 -> element of argument -1 | true | +| System.Collections.CollectionBase.CopyTo(Array, int) | element of argument -1 -> element of return (out parameter 0) | true | +| System.Collections.CollectionBase.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | +| System.Collections.CollectionBase.Insert(int, object) | argument 1 -> element of argument -1 | true | +| System.Collections.CollectionBase.get_Item(int) | element of argument -1 -> return (normal) | true | +| System.Collections.CollectionBase.set_Item(int, object) | argument 1 -> element of argument -1 | true | +| System.Collections.Concurrent.BlockingCollection<>.d__68.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | +| System.Collections.Concurrent.BlockingCollection<>.Add(T) | argument 0 -> element of argument -1 | true | +| System.Collections.Concurrent.BlockingCollection<>.CopyTo(Array, int) | element of argument -1 -> element of return (out parameter 0) | true | +| System.Collections.Concurrent.BlockingCollection<>.CopyTo(T[], int) | element of argument -1 -> element of return (out parameter 0) | true | +| System.Collections.Concurrent.BlockingCollection<>.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | +| System.Collections.Concurrent.ConcurrentBag<>.Add(T) | argument 0 -> element of argument -1 | true | +| System.Collections.Concurrent.ConcurrentBag<>.CopyTo(Array, int) | element of argument -1 -> element of return (out parameter 0) | true | +| System.Collections.Concurrent.ConcurrentBag<>.CopyTo(T[], int) | element of argument -1 -> element of return (out parameter 0) | true | +| System.Collections.Concurrent.ConcurrentBag<>.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | +| System.Collections.Concurrent.ConcurrentDictionary<,>.Add(KeyValuePair) | argument 0 -> element of argument -1 | true | +| System.Collections.Concurrent.ConcurrentDictionary<,>.Add(KeyValuePair) | property Key of argument 0 -> property Key of element of argument -1 | true | +| System.Collections.Concurrent.ConcurrentDictionary<,>.Add(KeyValuePair) | property Value of argument 0 -> property Value of element of argument -1 | true | +| System.Collections.Concurrent.ConcurrentDictionary<,>.Add(TKey, TValue) | argument 0 -> property Key of element of argument -1 | true | +| System.Collections.Concurrent.ConcurrentDictionary<,>.Add(TKey, TValue) | argument 1 -> property Value of element of argument -1 | true | +| System.Collections.Concurrent.ConcurrentDictionary<,>.Add(object, object) | argument 0 -> property Key of element of argument -1 | true | +| System.Collections.Concurrent.ConcurrentDictionary<,>.Add(object, object) | argument 1 -> property Value of element of argument -1 | true | +| System.Collections.Concurrent.ConcurrentDictionary<,>.ConcurrentDictionary(IEnumerable>) | property Key of element of argument 0 -> property Key of element of return (normal) | true | +| System.Collections.Concurrent.ConcurrentDictionary<,>.ConcurrentDictionary(IEnumerable>) | property Value of element of argument 0 -> property Value of element of return (normal) | true | +| System.Collections.Concurrent.ConcurrentDictionary<,>.ConcurrentDictionary(IEnumerable>, IEqualityComparer) | property Key of element of argument 0 -> property Key of element of return (normal) | true | +| System.Collections.Concurrent.ConcurrentDictionary<,>.ConcurrentDictionary(IEnumerable>, IEqualityComparer) | property Value of element of argument 0 -> property Value of element of return (normal) | true | +| System.Collections.Concurrent.ConcurrentDictionary<,>.ConcurrentDictionary(int, IEnumerable>, IEqualityComparer) | property Key of element of argument 1 -> property Key of element of return (normal) | true | +| System.Collections.Concurrent.ConcurrentDictionary<,>.ConcurrentDictionary(int, IEnumerable>, IEqualityComparer) | property Value of element of argument 1 -> property Value of element of return (normal) | true | +| System.Collections.Concurrent.ConcurrentDictionary<,>.CopyTo(Array, int) | element of argument -1 -> element of return (out parameter 0) | true | +| System.Collections.Concurrent.ConcurrentDictionary<,>.CopyTo(KeyValuePair[], int) | element of argument -1 -> element of return (out parameter 0) | true | +| System.Collections.Concurrent.ConcurrentDictionary<,>.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | +| System.Collections.Concurrent.ConcurrentDictionary<,>.get_Item(TKey) | property Value of element of argument -1 -> return (normal) | true | +| System.Collections.Concurrent.ConcurrentDictionary<,>.get_Item(object) | property Value of element of argument -1 -> return (normal) | true | +| System.Collections.Concurrent.ConcurrentDictionary<,>.get_Keys() | property Key of element of argument -1 -> element of return (normal) | true | +| System.Collections.Concurrent.ConcurrentDictionary<,>.get_Values() | property Value of element of argument -1 -> element of return (normal) | true | +| System.Collections.Concurrent.ConcurrentDictionary<,>.set_Item(TKey, TValue) | argument 0 -> property Key of element of argument -1 | true | +| System.Collections.Concurrent.ConcurrentDictionary<,>.set_Item(TKey, TValue) | argument 1 -> property Value of element of argument -1 | true | +| System.Collections.Concurrent.ConcurrentDictionary<,>.set_Item(object, object) | argument 0 -> property Key of element of argument -1 | true | +| System.Collections.Concurrent.ConcurrentDictionary<,>.set_Item(object, object) | argument 1 -> property Value of element of argument -1 | true | +| System.Collections.Concurrent.ConcurrentQueue<>.CopyTo(Array, int) | element of argument -1 -> element of return (out parameter 0) | true | +| System.Collections.Concurrent.ConcurrentQueue<>.CopyTo(T[], int) | element of argument -1 -> element of return (out parameter 0) | true | +| System.Collections.Concurrent.ConcurrentQueue<>.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | +| System.Collections.Concurrent.ConcurrentStack<>.CopyTo(Array, int) | element of argument -1 -> element of return (out parameter 0) | true | +| System.Collections.Concurrent.ConcurrentStack<>.CopyTo(T[], int) | element of argument -1 -> element of return (out parameter 0) | true | +| System.Collections.Concurrent.ConcurrentStack<>.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | +| System.Collections.Concurrent.IProducerConsumerCollection<>.CopyTo(T[], int) | element of argument -1 -> element of return (out parameter 0) | true | +| System.Collections.Concurrent.OrderablePartitioner<>.EnumerableDropIndices.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | +| System.Collections.Concurrent.Partitioner.d__7.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | +| System.Collections.Concurrent.Partitioner.d__10.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | +| System.Collections.Concurrent.Partitioner.DynamicPartitionerForArray<>.InternalPartitionEnumerable.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | +| System.Collections.Concurrent.Partitioner.DynamicPartitionerForIEnumerable<>.InternalPartitionEnumerable.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | +| System.Collections.Concurrent.Partitioner.DynamicPartitionerForIList<>.InternalPartitionEnumerable.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | +| System.Collections.DictionaryBase.Add(object, object) | argument 0 -> property Key of element of argument -1 | true | +| System.Collections.DictionaryBase.Add(object, object) | argument 1 -> property Value of element of argument -1 | true | +| System.Collections.DictionaryBase.CopyTo(Array, int) | element of argument -1 -> element of return (out parameter 0) | true | +| System.Collections.DictionaryBase.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | +| System.Collections.DictionaryBase.get_Item(object) | property Value of element of argument -1 -> return (normal) | true | +| System.Collections.DictionaryBase.get_Keys() | property Key of element of argument -1 -> element of return (normal) | true | +| System.Collections.DictionaryBase.get_Values() | property Value of element of argument -1 -> element of return (normal) | true | +| System.Collections.DictionaryBase.set_Item(object, object) | argument 0 -> property Key of element of argument -1 | true | +| System.Collections.DictionaryBase.set_Item(object, object) | argument 1 -> property Value of element of argument -1 | true | +| System.Collections.EmptyReadOnlyDictionaryInternal.Add(object, object) | argument 0 -> property Key of element of argument -1 | true | +| System.Collections.EmptyReadOnlyDictionaryInternal.Add(object, object) | argument 1 -> property Value of element of argument -1 | true | +| System.Collections.EmptyReadOnlyDictionaryInternal.CopyTo(Array, int) | element of argument -1 -> element of return (out parameter 0) | true | +| System.Collections.EmptyReadOnlyDictionaryInternal.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | +| System.Collections.EmptyReadOnlyDictionaryInternal.get_Item(object) | property Value of element of argument -1 -> return (normal) | true | +| System.Collections.EmptyReadOnlyDictionaryInternal.get_Keys() | property Key of element of argument -1 -> element of return (normal) | true | +| System.Collections.EmptyReadOnlyDictionaryInternal.get_Values() | property Value of element of argument -1 -> element of return (normal) | true | +| System.Collections.EmptyReadOnlyDictionaryInternal.set_Item(object, object) | argument 0 -> property Key of element of argument -1 | true | +| System.Collections.EmptyReadOnlyDictionaryInternal.set_Item(object, object) | argument 1 -> property Value of element of argument -1 | true | +| System.Collections.Generic.Dictionary<,>.Add(KeyValuePair) | argument 0 -> element of argument -1 | true | +| System.Collections.Generic.Dictionary<,>.Add(KeyValuePair) | property Key of argument 0 -> property Key of element of argument -1 | true | +| System.Collections.Generic.Dictionary<,>.Add(KeyValuePair) | property Value of argument 0 -> property Value of element of argument -1 | true | +| System.Collections.Generic.Dictionary<,>.Add(TKey, TValue) | argument 0 -> property Key of element of argument -1 | true | +| System.Collections.Generic.Dictionary<,>.Add(TKey, TValue) | argument 1 -> property Value of element of argument -1 | true | +| System.Collections.Generic.Dictionary<,>.Add(object, object) | argument 0 -> property Key of element of argument -1 | true | +| System.Collections.Generic.Dictionary<,>.Add(object, object) | argument 1 -> property Value of element of argument -1 | true | +| System.Collections.Generic.Dictionary<,>.CopyTo(Array, int) | element of argument -1 -> element of return (out parameter 0) | true | +| System.Collections.Generic.Dictionary<,>.CopyTo(KeyValuePair[], int) | element of argument -1 -> element of return (out parameter 0) | true | +| System.Collections.Generic.Dictionary<,>.Dictionary(IDictionary) | property Key of element of argument 0 -> property Key of element of return (normal) | true | +| System.Collections.Generic.Dictionary<,>.Dictionary(IDictionary) | property Value of element of argument 0 -> property Value of element of return (normal) | true | +| System.Collections.Generic.Dictionary<,>.Dictionary(IDictionary, IEqualityComparer) | property Key of element of argument 0 -> property Key of element of return (normal) | true | +| System.Collections.Generic.Dictionary<,>.Dictionary(IDictionary, IEqualityComparer) | property Value of element of argument 0 -> property Value of element of return (normal) | true | +| System.Collections.Generic.Dictionary<,>.Dictionary(IEnumerable>) | property Key of element of argument 0 -> property Key of element of return (normal) | true | +| System.Collections.Generic.Dictionary<,>.Dictionary(IEnumerable>) | property Value of element of argument 0 -> property Value of element of return (normal) | true | +| System.Collections.Generic.Dictionary<,>.Dictionary(IEnumerable>, IEqualityComparer) | property Key of element of argument 0 -> property Key of element of return (normal) | true | +| System.Collections.Generic.Dictionary<,>.Dictionary(IEnumerable>, IEqualityComparer) | property Value of element of argument 0 -> property Value of element of return (normal) | true | +| System.Collections.Generic.Dictionary<,>.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | +| System.Collections.Generic.Dictionary<,>.KeyCollection.Add(TKey) | argument 0 -> element of argument -1 | true | +| System.Collections.Generic.Dictionary<,>.KeyCollection.CopyTo(Array, int) | element of argument -1 -> element of return (out parameter 0) | true | +| System.Collections.Generic.Dictionary<,>.KeyCollection.CopyTo(TKey[], int) | element of argument -1 -> element of return (out parameter 0) | true | +| System.Collections.Generic.Dictionary<,>.KeyCollection.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | +| System.Collections.Generic.Dictionary<,>.ValueCollection.Add(TValue) | argument 0 -> element of argument -1 | true | +| System.Collections.Generic.Dictionary<,>.ValueCollection.CopyTo(Array, int) | element of argument -1 -> element of return (out parameter 0) | true | +| System.Collections.Generic.Dictionary<,>.ValueCollection.CopyTo(TValue[], int) | element of argument -1 -> element of return (out parameter 0) | true | +| System.Collections.Generic.Dictionary<,>.ValueCollection.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | +| System.Collections.Generic.Dictionary<,>.get_Item(TKey) | property Value of element of argument -1 -> return (normal) | true | +| System.Collections.Generic.Dictionary<,>.get_Item(object) | property Value of element of argument -1 -> return (normal) | true | +| System.Collections.Generic.Dictionary<,>.get_Keys() | property Key of element of argument -1 -> element of return (normal) | true | +| System.Collections.Generic.Dictionary<,>.get_Values() | property Value of element of argument -1 -> element of return (normal) | true | +| System.Collections.Generic.Dictionary<,>.set_Item(TKey, TValue) | argument 0 -> property Key of element of argument -1 | true | +| System.Collections.Generic.Dictionary<,>.set_Item(TKey, TValue) | argument 1 -> property Value of element of argument -1 | true | +| System.Collections.Generic.Dictionary<,>.set_Item(object, object) | argument 0 -> property Key of element of argument -1 | true | +| System.Collections.Generic.Dictionary<,>.set_Item(object, object) | argument 1 -> property Value of element of argument -1 | true | +| System.Collections.Generic.HashSet<>.Add(T) | argument 0 -> element of argument -1 | true | +| System.Collections.Generic.HashSet<>.CopyTo(T[], int) | element of argument -1 -> element of return (out parameter 0) | true | +| System.Collections.Generic.HashSet<>.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | +| System.Collections.Generic.ICollection<>.Add(T) | argument 0 -> element of argument -1 | true | +| System.Collections.Generic.ICollection<>.CopyTo(T[], int) | element of argument -1 -> element of return (out parameter 0) | true | +| System.Collections.Generic.IDictionary<,>.Add(TKey, TValue) | argument 0 -> property Key of element of argument -1 | true | +| System.Collections.Generic.IDictionary<,>.Add(TKey, TValue) | argument 1 -> property Value of element of argument -1 | true | +| System.Collections.Generic.IDictionary<,>.get_Item(TKey) | property Value of element of argument -1 -> return (normal) | true | +| System.Collections.Generic.IDictionary<,>.get_Keys() | property Key of element of argument -1 -> element of return (normal) | true | +| System.Collections.Generic.IDictionary<,>.get_Values() | property Value of element of argument -1 -> element of return (normal) | true | +| System.Collections.Generic.IDictionary<,>.set_Item(TKey, TValue) | argument 0 -> property Key of element of argument -1 | true | +| System.Collections.Generic.IDictionary<,>.set_Item(TKey, TValue) | argument 1 -> property Value of element of argument -1 | true | +| System.Collections.Generic.IList<>.Insert(int, T) | argument 1 -> element of argument -1 | true | +| System.Collections.Generic.IList<>.get_Item(int) | element of argument -1 -> return (normal) | true | +| System.Collections.Generic.IList<>.set_Item(int, T) | argument 1 -> element of argument -1 | true | +| System.Collections.Generic.ISet<>.Add(T) | argument 0 -> element of argument -1 | true | +| System.Collections.Generic.KeyValuePair<,>.KeyValuePair() | argument 0 -> property Key of return (normal) | true | +| System.Collections.Generic.KeyValuePair<,>.KeyValuePair() | argument 1 -> property Value of return (normal) | true | +| System.Collections.Generic.KeyValuePair<,>.KeyValuePair(TKey, TValue) | argument 0 -> property Key of return (normal) | true | +| System.Collections.Generic.KeyValuePair<,>.KeyValuePair(TKey, TValue) | argument 1 -> property Value of return (normal) | true | +| System.Collections.Generic.LinkedList<>.Add(T) | argument 0 -> element of argument -1 | true | +| System.Collections.Generic.LinkedList<>.CopyTo(Array, int) | element of argument -1 -> element of return (out parameter 0) | true | +| System.Collections.Generic.LinkedList<>.CopyTo(T[], int) | element of argument -1 -> element of return (out parameter 0) | true | +| System.Collections.Generic.LinkedList<>.Find(T) | element of argument -1 -> return (normal) | true | +| System.Collections.Generic.LinkedList<>.FindLast(T) | element of argument -1 -> return (normal) | true | +| System.Collections.Generic.LinkedList<>.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | +| System.Collections.Generic.List<>.Add(T) | argument 0 -> element of argument -1 | true | +| System.Collections.Generic.List<>.Add(object) | argument 0 -> element of argument -1 | true | +| System.Collections.Generic.List<>.AddRange(IEnumerable) | element of argument 0 -> element of argument -1 | true | +| System.Collections.Generic.List<>.AsReadOnly() | element of argument 0 -> element of return (normal) | true | +| System.Collections.Generic.List<>.CopyTo(Array, int) | element of argument -1 -> element of return (out parameter 0) | true | +| System.Collections.Generic.List<>.CopyTo(T[], int) | element of argument -1 -> element of return (out parameter 0) | true | +| System.Collections.Generic.List<>.Find(Predicate) | element of argument -1 -> parameter 0 of argument 0 | true | +| System.Collections.Generic.List<>.Find(Predicate) | element of argument -1 -> return (normal) | true | +| System.Collections.Generic.List<>.FindAll(Predicate) | element of argument -1 -> parameter 0 of argument 0 | true | +| System.Collections.Generic.List<>.FindAll(Predicate) | element of argument -1 -> return (normal) | true | +| System.Collections.Generic.List<>.FindLast(Predicate) | element of argument -1 -> parameter 0 of argument 0 | true | +| System.Collections.Generic.List<>.FindLast(Predicate) | element of argument -1 -> return (normal) | true | +| System.Collections.Generic.List<>.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | +| System.Collections.Generic.List<>.GetRange(int, int) | element of argument 0 -> element of return (normal) | true | +| System.Collections.Generic.List<>.Insert(int, T) | argument 1 -> element of argument -1 | true | +| System.Collections.Generic.List<>.Insert(int, object) | argument 1 -> element of argument -1 | true | +| System.Collections.Generic.List<>.InsertRange(int, IEnumerable) | element of argument 1 -> element of argument -1 | true | +| System.Collections.Generic.List<>.Reverse() | element of argument 0 -> element of return (normal) | true | +| System.Collections.Generic.List<>.Reverse(int, int) | element of argument 0 -> element of return (normal) | true | +| System.Collections.Generic.List<>.get_Item(int) | element of argument -1 -> return (normal) | true | +| System.Collections.Generic.List<>.set_Item(int, T) | argument 1 -> element of argument -1 | true | +| System.Collections.Generic.List<>.set_Item(int, object) | argument 1 -> element of argument -1 | true | +| System.Collections.Generic.Queue<>.CopyTo(Array, int) | element of argument -1 -> element of return (out parameter 0) | true | +| System.Collections.Generic.Queue<>.CopyTo(T[], int) | element of argument -1 -> element of return (out parameter 0) | true | +| System.Collections.Generic.Queue<>.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | +| System.Collections.Generic.Queue<>.Peek() | element of argument -1 -> return (normal) | true | +| System.Collections.Generic.SortedDictionary<,>.Add(KeyValuePair) | argument 0 -> element of argument -1 | true | +| System.Collections.Generic.SortedDictionary<,>.Add(KeyValuePair) | property Key of argument 0 -> property Key of element of argument -1 | true | +| System.Collections.Generic.SortedDictionary<,>.Add(KeyValuePair) | property Value of argument 0 -> property Value of element of argument -1 | true | +| System.Collections.Generic.SortedDictionary<,>.Add(TKey, TValue) | argument 0 -> property Key of element of argument -1 | true | +| System.Collections.Generic.SortedDictionary<,>.Add(TKey, TValue) | argument 1 -> property Value of element of argument -1 | true | +| System.Collections.Generic.SortedDictionary<,>.Add(object, object) | argument 0 -> property Key of element of argument -1 | true | +| System.Collections.Generic.SortedDictionary<,>.Add(object, object) | argument 1 -> property Value of element of argument -1 | true | +| System.Collections.Generic.SortedDictionary<,>.CopyTo(Array, int) | element of argument -1 -> element of return (out parameter 0) | true | +| System.Collections.Generic.SortedDictionary<,>.CopyTo(KeyValuePair[], int) | element of argument -1 -> element of return (out parameter 0) | true | +| System.Collections.Generic.SortedDictionary<,>.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | +| System.Collections.Generic.SortedDictionary<,>.KeyCollection.Add(TKey) | argument 0 -> element of argument -1 | true | +| System.Collections.Generic.SortedDictionary<,>.KeyCollection.CopyTo(Array, int) | element of argument -1 -> element of return (out parameter 0) | true | +| System.Collections.Generic.SortedDictionary<,>.KeyCollection.CopyTo(TKey[], int) | element of argument -1 -> element of return (out parameter 0) | true | +| System.Collections.Generic.SortedDictionary<,>.KeyCollection.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | +| System.Collections.Generic.SortedDictionary<,>.SortedDictionary(IDictionary) | property Key of element of argument 0 -> property Key of element of return (normal) | true | +| System.Collections.Generic.SortedDictionary<,>.SortedDictionary(IDictionary) | property Value of element of argument 0 -> property Value of element of return (normal) | true | +| System.Collections.Generic.SortedDictionary<,>.SortedDictionary(IDictionary, IComparer) | property Key of element of argument 0 -> property Key of element of return (normal) | true | +| System.Collections.Generic.SortedDictionary<,>.SortedDictionary(IDictionary, IComparer) | property Value of element of argument 0 -> property Value of element of return (normal) | true | +| System.Collections.Generic.SortedDictionary<,>.ValueCollection.Add(TValue) | argument 0 -> element of argument -1 | true | +| System.Collections.Generic.SortedDictionary<,>.ValueCollection.CopyTo(Array, int) | element of argument -1 -> element of return (out parameter 0) | true | +| System.Collections.Generic.SortedDictionary<,>.ValueCollection.CopyTo(TValue[], int) | element of argument -1 -> element of return (out parameter 0) | true | +| System.Collections.Generic.SortedDictionary<,>.ValueCollection.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | +| System.Collections.Generic.SortedDictionary<,>.get_Item(TKey) | property Value of element of argument -1 -> return (normal) | true | +| System.Collections.Generic.SortedDictionary<,>.get_Item(object) | property Value of element of argument -1 -> return (normal) | true | +| System.Collections.Generic.SortedDictionary<,>.get_Keys() | property Key of element of argument -1 -> element of return (normal) | true | +| System.Collections.Generic.SortedDictionary<,>.get_Values() | property Value of element of argument -1 -> element of return (normal) | true | +| System.Collections.Generic.SortedDictionary<,>.set_Item(TKey, TValue) | argument 0 -> property Key of element of argument -1 | true | +| System.Collections.Generic.SortedDictionary<,>.set_Item(TKey, TValue) | argument 1 -> property Value of element of argument -1 | true | +| System.Collections.Generic.SortedDictionary<,>.set_Item(object, object) | argument 0 -> property Key of element of argument -1 | true | +| System.Collections.Generic.SortedDictionary<,>.set_Item(object, object) | argument 1 -> property Value of element of argument -1 | true | +| System.Collections.Generic.SortedList<,>.Add(KeyValuePair) | argument 0 -> element of argument -1 | true | +| System.Collections.Generic.SortedList<,>.Add(KeyValuePair) | property Key of argument 0 -> property Key of element of argument -1 | true | +| System.Collections.Generic.SortedList<,>.Add(KeyValuePair) | property Value of argument 0 -> property Value of element of argument -1 | true | +| System.Collections.Generic.SortedList<,>.Add(TKey, TValue) | argument 0 -> property Key of element of argument -1 | true | +| System.Collections.Generic.SortedList<,>.Add(TKey, TValue) | argument 1 -> property Value of element of argument -1 | true | +| System.Collections.Generic.SortedList<,>.Add(object, object) | argument 0 -> property Key of element of argument -1 | true | +| System.Collections.Generic.SortedList<,>.Add(object, object) | argument 1 -> property Value of element of argument -1 | true | +| System.Collections.Generic.SortedList<,>.CopyTo(Array, int) | element of argument -1 -> element of return (out parameter 0) | true | +| System.Collections.Generic.SortedList<,>.CopyTo(KeyValuePair[], int) | element of argument -1 -> element of return (out parameter 0) | true | +| System.Collections.Generic.SortedList<,>.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | +| System.Collections.Generic.SortedList<,>.KeyList.Add(TKey) | argument 0 -> element of argument -1 | true | +| System.Collections.Generic.SortedList<,>.KeyList.CopyTo(Array, int) | element of argument -1 -> element of return (out parameter 0) | true | +| System.Collections.Generic.SortedList<,>.KeyList.CopyTo(TKey[], int) | element of argument -1 -> element of return (out parameter 0) | true | +| System.Collections.Generic.SortedList<,>.KeyList.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | +| System.Collections.Generic.SortedList<,>.KeyList.Insert(int, TKey) | argument 1 -> element of argument -1 | true | +| System.Collections.Generic.SortedList<,>.KeyList.get_Item(int) | element of argument -1 -> return (normal) | true | +| System.Collections.Generic.SortedList<,>.KeyList.set_Item(int, TKey) | argument 1 -> element of argument -1 | true | +| System.Collections.Generic.SortedList<,>.SortedList(IDictionary) | property Key of element of argument 0 -> property Key of element of return (normal) | true | +| System.Collections.Generic.SortedList<,>.SortedList(IDictionary) | property Value of element of argument 0 -> property Value of element of return (normal) | true | +| System.Collections.Generic.SortedList<,>.SortedList(IDictionary, IComparer) | property Key of element of argument 0 -> property Key of element of return (normal) | true | +| System.Collections.Generic.SortedList<,>.SortedList(IDictionary, IComparer) | property Value of element of argument 0 -> property Value of element of return (normal) | true | +| System.Collections.Generic.SortedList<,>.ValueList.Add(TValue) | argument 0 -> element of argument -1 | true | +| System.Collections.Generic.SortedList<,>.ValueList.CopyTo(Array, int) | element of argument -1 -> element of return (out parameter 0) | true | +| System.Collections.Generic.SortedList<,>.ValueList.CopyTo(TValue[], int) | element of argument -1 -> element of return (out parameter 0) | true | +| System.Collections.Generic.SortedList<,>.ValueList.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | +| System.Collections.Generic.SortedList<,>.ValueList.Insert(int, TValue) | argument 1 -> element of argument -1 | true | +| System.Collections.Generic.SortedList<,>.ValueList.get_Item(int) | element of argument -1 -> return (normal) | true | +| System.Collections.Generic.SortedList<,>.ValueList.set_Item(int, TValue) | argument 1 -> element of argument -1 | true | +| System.Collections.Generic.SortedList<,>.get_Item(TKey) | property Value of element of argument -1 -> return (normal) | true | +| System.Collections.Generic.SortedList<,>.get_Item(object) | property Value of element of argument -1 -> return (normal) | true | +| System.Collections.Generic.SortedList<,>.get_Keys() | property Key of element of argument -1 -> element of return (normal) | true | +| System.Collections.Generic.SortedList<,>.get_Values() | property Value of element of argument -1 -> element of return (normal) | true | +| System.Collections.Generic.SortedList<,>.set_Item(TKey, TValue) | argument 0 -> property Key of element of argument -1 | true | +| System.Collections.Generic.SortedList<,>.set_Item(TKey, TValue) | argument 1 -> property Value of element of argument -1 | true | +| System.Collections.Generic.SortedList<,>.set_Item(object, object) | argument 0 -> property Key of element of argument -1 | true | +| System.Collections.Generic.SortedList<,>.set_Item(object, object) | argument 1 -> property Value of element of argument -1 | true | +| System.Collections.Generic.SortedSet<>.d__84.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | +| System.Collections.Generic.SortedSet<>.Add(T) | argument 0 -> element of argument -1 | true | +| System.Collections.Generic.SortedSet<>.CopyTo(Array, int) | element of argument -1 -> element of return (out parameter 0) | true | +| System.Collections.Generic.SortedSet<>.CopyTo(T[], int) | element of argument -1 -> element of return (out parameter 0) | true | +| System.Collections.Generic.SortedSet<>.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | +| System.Collections.Generic.SortedSet<>.Reverse() | element of argument 0 -> element of return (normal) | true | +| System.Collections.Generic.Stack<>.CopyTo(Array, int) | element of argument -1 -> element of return (out parameter 0) | true | +| System.Collections.Generic.Stack<>.CopyTo(T[], int) | element of argument -1 -> element of return (out parameter 0) | true | +| System.Collections.Generic.Stack<>.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | +| System.Collections.Generic.Stack<>.Peek() | element of argument -1 -> return (normal) | true | +| System.Collections.Generic.Stack<>.Pop() | element of argument -1 -> return (normal) | true | +| System.Collections.Hashtable.Add(object, object) | argument 0 -> property Key of element of argument -1 | true | +| System.Collections.Hashtable.Add(object, object) | argument 1 -> property Value of element of argument -1 | true | +| System.Collections.Hashtable.Clone() | element of argument 0 -> element of return (normal) | true | +| System.Collections.Hashtable.CopyTo(Array, int) | element of argument -1 -> element of return (out parameter 0) | true | +| System.Collections.Hashtable.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | +| System.Collections.Hashtable.Hashtable(IDictionary) | property Key of element of argument 0 -> property Key of element of return (normal) | true | +| System.Collections.Hashtable.Hashtable(IDictionary) | property Value of element of argument 0 -> property Value of element of return (normal) | true | +| System.Collections.Hashtable.Hashtable(IDictionary, IEqualityComparer) | property Key of element of argument 0 -> property Key of element of return (normal) | true | +| System.Collections.Hashtable.Hashtable(IDictionary, IEqualityComparer) | property Value of element of argument 0 -> property Value of element of return (normal) | true | +| System.Collections.Hashtable.Hashtable(IDictionary, IHashCodeProvider, IComparer) | property Key of element of argument 0 -> property Key of element of return (normal) | true | +| System.Collections.Hashtable.Hashtable(IDictionary, IHashCodeProvider, IComparer) | property Value of element of argument 0 -> property Value of element of return (normal) | true | +| System.Collections.Hashtable.Hashtable(IDictionary, float) | property Key of element of argument 0 -> property Key of element of return (normal) | true | +| System.Collections.Hashtable.Hashtable(IDictionary, float) | property Value of element of argument 0 -> property Value of element of return (normal) | true | +| System.Collections.Hashtable.Hashtable(IDictionary, float, IEqualityComparer) | property Key of element of argument 0 -> property Key of element of return (normal) | true | +| System.Collections.Hashtable.Hashtable(IDictionary, float, IEqualityComparer) | property Value of element of argument 0 -> property Value of element of return (normal) | true | +| System.Collections.Hashtable.Hashtable(IDictionary, float, IHashCodeProvider, IComparer) | property Key of element of argument 0 -> property Key of element of return (normal) | true | +| System.Collections.Hashtable.Hashtable(IDictionary, float, IHashCodeProvider, IComparer) | property Value of element of argument 0 -> property Value of element of return (normal) | true | +| System.Collections.Hashtable.KeyCollection.CopyTo(Array, int) | element of argument -1 -> element of return (out parameter 0) | true | +| System.Collections.Hashtable.KeyCollection.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | +| System.Collections.Hashtable.SyncHashtable.Add(object, object) | argument 0 -> property Key of element of argument -1 | true | +| System.Collections.Hashtable.SyncHashtable.Add(object, object) | argument 1 -> property Value of element of argument -1 | true | +| System.Collections.Hashtable.SyncHashtable.Clone() | element of argument 0 -> element of return (normal) | true | +| System.Collections.Hashtable.SyncHashtable.CopyTo(Array, int) | element of argument -1 -> element of return (out parameter 0) | true | +| System.Collections.Hashtable.SyncHashtable.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | +| System.Collections.Hashtable.SyncHashtable.get_Item(object) | property Value of element of argument -1 -> return (normal) | true | +| System.Collections.Hashtable.SyncHashtable.get_Keys() | property Key of element of argument -1 -> element of return (normal) | true | +| System.Collections.Hashtable.SyncHashtable.get_Values() | property Value of element of argument -1 -> element of return (normal) | true | +| System.Collections.Hashtable.SyncHashtable.set_Item(object, object) | argument 0 -> property Key of element of argument -1 | true | +| System.Collections.Hashtable.SyncHashtable.set_Item(object, object) | argument 1 -> property Value of element of argument -1 | true | +| System.Collections.Hashtable.ValueCollection.CopyTo(Array, int) | element of argument -1 -> element of return (out parameter 0) | true | +| System.Collections.Hashtable.ValueCollection.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | +| System.Collections.Hashtable.get_Item(object) | property Value of element of argument -1 -> return (normal) | true | +| System.Collections.Hashtable.get_Keys() | property Key of element of argument -1 -> element of return (normal) | true | +| System.Collections.Hashtable.get_Values() | property Value of element of argument -1 -> element of return (normal) | true | +| System.Collections.Hashtable.set_Item(object, object) | argument 0 -> property Key of element of argument -1 | true | +| System.Collections.Hashtable.set_Item(object, object) | argument 1 -> property Value of element of argument -1 | true | +| System.Collections.ICollection.CopyTo(Array, int) | element of argument -1 -> element of return (out parameter 0) | true | +| System.Collections.IDictionary.Add(object, object) | argument 0 -> property Key of element of argument -1 | true | +| System.Collections.IDictionary.Add(object, object) | argument 1 -> property Value of element of argument -1 | true | +| System.Collections.IDictionary.get_Item(object) | property Value of element of argument -1 -> return (normal) | true | +| System.Collections.IDictionary.get_Keys() | property Key of element of argument -1 -> element of return (normal) | true | +| System.Collections.IDictionary.get_Values() | property Value of element of argument -1 -> element of return (normal) | true | +| System.Collections.IDictionary.set_Item(object, object) | argument 0 -> property Key of element of argument -1 | true | +| System.Collections.IDictionary.set_Item(object, object) | argument 1 -> property Value of element of argument -1 | true | +| System.Collections.IEnumerable.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | +| System.Collections.IList.Add(object) | argument 0 -> element of argument -1 | true | +| System.Collections.IList.Insert(int, object) | argument 1 -> element of argument -1 | true | +| System.Collections.IList.get_Item(int) | element of argument -1 -> return (normal) | true | +| System.Collections.IList.set_Item(int, object) | argument 1 -> element of argument -1 | true | +| System.Collections.ListDictionaryInternal.Add(object, object) | argument 0 -> property Key of element of argument -1 | true | +| System.Collections.ListDictionaryInternal.Add(object, object) | argument 1 -> property Value of element of argument -1 | true | +| System.Collections.ListDictionaryInternal.CopyTo(Array, int) | element of argument -1 -> element of return (out parameter 0) | true | +| System.Collections.ListDictionaryInternal.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | +| System.Collections.ListDictionaryInternal.NodeKeyValueCollection.CopyTo(Array, int) | element of argument -1 -> element of return (out parameter 0) | true | +| System.Collections.ListDictionaryInternal.NodeKeyValueCollection.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | +| System.Collections.ListDictionaryInternal.get_Item(object) | property Value of element of argument -1 -> return (normal) | true | +| System.Collections.ListDictionaryInternal.get_Keys() | property Key of element of argument -1 -> element of return (normal) | true | +| System.Collections.ListDictionaryInternal.get_Values() | property Value of element of argument -1 -> element of return (normal) | true | +| System.Collections.ListDictionaryInternal.set_Item(object, object) | argument 0 -> property Key of element of argument -1 | true | +| System.Collections.ListDictionaryInternal.set_Item(object, object) | argument 1 -> property Value of element of argument -1 | true | +| System.Collections.ObjectModel.Collection<>.Add(T) | argument 0 -> element of argument -1 | true | +| System.Collections.ObjectModel.Collection<>.Add(object) | argument 0 -> element of argument -1 | true | +| System.Collections.ObjectModel.Collection<>.CopyTo(Array, int) | element of argument -1 -> element of return (out parameter 0) | true | +| System.Collections.ObjectModel.Collection<>.CopyTo(T[], int) | element of argument -1 -> element of return (out parameter 0) | true | +| System.Collections.ObjectModel.Collection<>.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | +| System.Collections.ObjectModel.Collection<>.Insert(int, T) | argument 1 -> element of argument -1 | true | +| System.Collections.ObjectModel.Collection<>.Insert(int, object) | argument 1 -> element of argument -1 | true | +| System.Collections.ObjectModel.Collection<>.get_Item(int) | element of argument -1 -> return (normal) | true | +| System.Collections.ObjectModel.Collection<>.set_Item(int, T) | argument 1 -> element of argument -1 | true | +| System.Collections.ObjectModel.Collection<>.set_Item(int, object) | argument 1 -> element of argument -1 | true | +| System.Collections.ObjectModel.KeyedCollection<,>.get_Item(TKey) | element of argument -1 -> return (normal) | true | +| System.Collections.ObjectModel.ReadOnlyCollection<>.Add(T) | argument 0 -> element of argument -1 | true | +| System.Collections.ObjectModel.ReadOnlyCollection<>.Add(object) | argument 0 -> element of argument -1 | true | +| System.Collections.ObjectModel.ReadOnlyCollection<>.CopyTo(Array, int) | element of argument -1 -> element of return (out parameter 0) | true | +| System.Collections.ObjectModel.ReadOnlyCollection<>.CopyTo(T[], int) | element of argument -1 -> element of return (out parameter 0) | true | +| System.Collections.ObjectModel.ReadOnlyCollection<>.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | +| System.Collections.ObjectModel.ReadOnlyCollection<>.Insert(int, T) | argument 1 -> element of argument -1 | true | +| System.Collections.ObjectModel.ReadOnlyCollection<>.Insert(int, object) | argument 1 -> element of argument -1 | true | +| System.Collections.ObjectModel.ReadOnlyCollection<>.get_Item(int) | element of argument -1 -> return (normal) | true | +| System.Collections.ObjectModel.ReadOnlyCollection<>.set_Item(int, T) | argument 1 -> element of argument -1 | true | +| System.Collections.ObjectModel.ReadOnlyCollection<>.set_Item(int, object) | argument 1 -> element of argument -1 | true | +| System.Collections.ObjectModel.ReadOnlyDictionary<,>.Add(KeyValuePair) | argument 0 -> element of argument -1 | true | +| System.Collections.ObjectModel.ReadOnlyDictionary<,>.Add(KeyValuePair) | property Key of argument 0 -> property Key of element of argument -1 | true | +| System.Collections.ObjectModel.ReadOnlyDictionary<,>.Add(KeyValuePair) | property Value of argument 0 -> property Value of element of argument -1 | true | +| System.Collections.ObjectModel.ReadOnlyDictionary<,>.Add(TKey, TValue) | argument 0 -> property Key of element of argument -1 | true | +| System.Collections.ObjectModel.ReadOnlyDictionary<,>.Add(TKey, TValue) | argument 1 -> property Value of element of argument -1 | true | +| System.Collections.ObjectModel.ReadOnlyDictionary<,>.Add(object, object) | argument 0 -> property Key of element of argument -1 | true | +| System.Collections.ObjectModel.ReadOnlyDictionary<,>.Add(object, object) | argument 1 -> property Value of element of argument -1 | true | +| System.Collections.ObjectModel.ReadOnlyDictionary<,>.CopyTo(Array, int) | element of argument -1 -> element of return (out parameter 0) | true | +| System.Collections.ObjectModel.ReadOnlyDictionary<,>.CopyTo(KeyValuePair[], int) | element of argument -1 -> element of return (out parameter 0) | true | +| System.Collections.ObjectModel.ReadOnlyDictionary<,>.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | +| System.Collections.ObjectModel.ReadOnlyDictionary<,>.KeyCollection.Add(TKey) | argument 0 -> element of argument -1 | true | +| System.Collections.ObjectModel.ReadOnlyDictionary<,>.KeyCollection.CopyTo(Array, int) | element of argument -1 -> element of return (out parameter 0) | true | +| System.Collections.ObjectModel.ReadOnlyDictionary<,>.KeyCollection.CopyTo(TKey[], int) | element of argument -1 -> element of return (out parameter 0) | true | +| System.Collections.ObjectModel.ReadOnlyDictionary<,>.KeyCollection.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | +| System.Collections.ObjectModel.ReadOnlyDictionary<,>.ReadOnlyDictionary(IDictionary) | property Key of element of argument 0 -> property Key of element of return (normal) | true | +| System.Collections.ObjectModel.ReadOnlyDictionary<,>.ReadOnlyDictionary(IDictionary) | property Value of element of argument 0 -> property Value of element of return (normal) | true | +| System.Collections.ObjectModel.ReadOnlyDictionary<,>.ValueCollection.Add(TValue) | argument 0 -> element of argument -1 | true | +| System.Collections.ObjectModel.ReadOnlyDictionary<,>.ValueCollection.CopyTo(Array, int) | element of argument -1 -> element of return (out parameter 0) | true | +| System.Collections.ObjectModel.ReadOnlyDictionary<,>.ValueCollection.CopyTo(TValue[], int) | element of argument -1 -> element of return (out parameter 0) | true | +| System.Collections.ObjectModel.ReadOnlyDictionary<,>.ValueCollection.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | +| System.Collections.ObjectModel.ReadOnlyDictionary<,>.get_Item(TKey) | property Value of element of argument -1 -> return (normal) | true | +| System.Collections.ObjectModel.ReadOnlyDictionary<,>.get_Item(object) | property Value of element of argument -1 -> return (normal) | true | +| System.Collections.ObjectModel.ReadOnlyDictionary<,>.get_Keys() | property Key of element of argument -1 -> element of return (normal) | true | +| System.Collections.ObjectModel.ReadOnlyDictionary<,>.get_Values() | property Value of element of argument -1 -> element of return (normal) | true | +| System.Collections.ObjectModel.ReadOnlyDictionary<,>.set_Item(TKey, TValue) | argument 0 -> property Key of element of argument -1 | true | +| System.Collections.ObjectModel.ReadOnlyDictionary<,>.set_Item(TKey, TValue) | argument 1 -> property Value of element of argument -1 | true | +| System.Collections.ObjectModel.ReadOnlyDictionary<,>.set_Item(object, object) | argument 0 -> property Key of element of argument -1 | true | +| System.Collections.ObjectModel.ReadOnlyDictionary<,>.set_Item(object, object) | argument 1 -> property Value of element of argument -1 | true | +| System.Collections.Queue.Clone() | element of argument 0 -> element of return (normal) | true | +| System.Collections.Queue.CopyTo(Array, int) | element of argument -1 -> element of return (out parameter 0) | true | +| System.Collections.Queue.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | +| System.Collections.Queue.Peek() | element of argument -1 -> return (normal) | true | +| System.Collections.Queue.SynchronizedQueue.Clone() | element of argument 0 -> element of return (normal) | true | +| System.Collections.Queue.SynchronizedQueue.CopyTo(Array, int) | element of argument -1 -> element of return (out parameter 0) | true | +| System.Collections.Queue.SynchronizedQueue.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | +| System.Collections.Queue.SynchronizedQueue.Peek() | element of argument -1 -> return (normal) | true | +| System.Collections.ReadOnlyCollectionBase.CopyTo(Array, int) | element of argument -1 -> element of return (out parameter 0) | true | +| System.Collections.ReadOnlyCollectionBase.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | +| System.Collections.SortedList.Add(object, object) | argument 0 -> property Key of element of argument -1 | true | +| System.Collections.SortedList.Add(object, object) | argument 1 -> property Value of element of argument -1 | true | +| System.Collections.SortedList.Clone() | element of argument 0 -> element of return (normal) | true | +| System.Collections.SortedList.CopyTo(Array, int) | element of argument -1 -> element of return (out parameter 0) | true | +| System.Collections.SortedList.GetByIndex(int) | property Value of element of argument -1 -> return (normal) | true | +| System.Collections.SortedList.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | +| System.Collections.SortedList.GetValueList() | property Value of element of argument -1 -> element of return (normal) | true | +| System.Collections.SortedList.KeyList.Add(object) | argument 0 -> element of argument -1 | true | +| System.Collections.SortedList.KeyList.CopyTo(Array, int) | element of argument -1 -> element of return (out parameter 0) | true | +| System.Collections.SortedList.KeyList.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | +| System.Collections.SortedList.KeyList.Insert(int, object) | argument 1 -> element of argument -1 | true | +| System.Collections.SortedList.KeyList.get_Item(int) | element of argument -1 -> return (normal) | true | +| System.Collections.SortedList.KeyList.set_Item(int, object) | argument 1 -> element of argument -1 | true | +| System.Collections.SortedList.SortedList(IDictionary) | property Key of element of argument 0 -> property Key of element of return (normal) | true | +| System.Collections.SortedList.SortedList(IDictionary) | property Value of element of argument 0 -> property Value of element of return (normal) | true | +| System.Collections.SortedList.SortedList(IDictionary, IComparer) | property Key of element of argument 0 -> property Key of element of return (normal) | true | +| System.Collections.SortedList.SortedList(IDictionary, IComparer) | property Value of element of argument 0 -> property Value of element of return (normal) | true | +| System.Collections.SortedList.SyncSortedList.Add(object, object) | argument 0 -> property Key of element of argument -1 | true | +| System.Collections.SortedList.SyncSortedList.Add(object, object) | argument 1 -> property Value of element of argument -1 | true | +| System.Collections.SortedList.SyncSortedList.Clone() | element of argument 0 -> element of return (normal) | true | +| System.Collections.SortedList.SyncSortedList.CopyTo(Array, int) | element of argument -1 -> element of return (out parameter 0) | true | +| System.Collections.SortedList.SyncSortedList.GetByIndex(int) | property Value of element of argument -1 -> return (normal) | true | +| System.Collections.SortedList.SyncSortedList.GetValueList() | property Value of element of argument -1 -> element of return (normal) | true | +| System.Collections.SortedList.SyncSortedList.get_Item(object) | property Value of element of argument -1 -> return (normal) | true | +| System.Collections.SortedList.SyncSortedList.set_Item(object, object) | argument 0 -> property Key of element of argument -1 | true | +| System.Collections.SortedList.SyncSortedList.set_Item(object, object) | argument 1 -> property Value of element of argument -1 | true | +| System.Collections.SortedList.ValueList.Add(object) | argument 0 -> element of argument -1 | true | +| System.Collections.SortedList.ValueList.CopyTo(Array, int) | element of argument -1 -> element of return (out parameter 0) | true | +| System.Collections.SortedList.ValueList.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | +| System.Collections.SortedList.ValueList.Insert(int, object) | argument 1 -> element of argument -1 | true | +| System.Collections.SortedList.ValueList.get_Item(int) | element of argument -1 -> return (normal) | true | +| System.Collections.SortedList.ValueList.set_Item(int, object) | argument 1 -> element of argument -1 | true | +| System.Collections.SortedList.get_Item(object) | property Value of element of argument -1 -> return (normal) | true | +| System.Collections.SortedList.get_Keys() | property Key of element of argument -1 -> element of return (normal) | true | +| System.Collections.SortedList.get_Values() | property Value of element of argument -1 -> element of return (normal) | true | +| System.Collections.SortedList.set_Item(object, object) | argument 0 -> property Key of element of argument -1 | true | +| System.Collections.SortedList.set_Item(object, object) | argument 1 -> property Value of element of argument -1 | true | +| System.Collections.Specialized.HybridDictionary.Add(object, object) | argument 0 -> property Key of element of argument -1 | true | +| System.Collections.Specialized.HybridDictionary.Add(object, object) | argument 1 -> property Value of element of argument -1 | true | +| System.Collections.Specialized.HybridDictionary.CopyTo(Array, int) | element of argument -1 -> element of return (out parameter 0) | true | +| System.Collections.Specialized.HybridDictionary.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | +| System.Collections.Specialized.HybridDictionary.get_Item(object) | property Value of element of argument -1 -> return (normal) | true | +| System.Collections.Specialized.HybridDictionary.get_Keys() | property Key of element of argument -1 -> element of return (normal) | true | +| System.Collections.Specialized.HybridDictionary.get_Values() | property Value of element of argument -1 -> element of return (normal) | true | +| System.Collections.Specialized.HybridDictionary.set_Item(object, object) | argument 0 -> property Key of element of argument -1 | true | +| System.Collections.Specialized.HybridDictionary.set_Item(object, object) | argument 1 -> property Value of element of argument -1 | true | +| System.Collections.Specialized.IOrderedDictionary.get_Item(int) | property Value of element of argument -1 -> return (normal) | true | +| System.Collections.Specialized.IOrderedDictionary.set_Item(int, object) | argument 0 -> property Key of element of argument -1 | true | +| System.Collections.Specialized.IOrderedDictionary.set_Item(int, object) | argument 1 -> property Value of element of argument -1 | true | +| System.Collections.Specialized.ListDictionary.Add(object, object) | argument 0 -> property Key of element of argument -1 | true | +| System.Collections.Specialized.ListDictionary.Add(object, object) | argument 1 -> property Value of element of argument -1 | true | +| System.Collections.Specialized.ListDictionary.CopyTo(Array, int) | element of argument -1 -> element of return (out parameter 0) | true | +| System.Collections.Specialized.ListDictionary.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | +| System.Collections.Specialized.ListDictionary.NodeKeyValueCollection.CopyTo(Array, int) | element of argument -1 -> element of return (out parameter 0) | true | +| System.Collections.Specialized.ListDictionary.NodeKeyValueCollection.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | +| System.Collections.Specialized.ListDictionary.get_Item(object) | property Value of element of argument -1 -> return (normal) | true | +| System.Collections.Specialized.ListDictionary.get_Keys() | property Key of element of argument -1 -> element of return (normal) | true | +| System.Collections.Specialized.ListDictionary.get_Values() | property Value of element of argument -1 -> element of return (normal) | true | +| System.Collections.Specialized.ListDictionary.set_Item(object, object) | argument 0 -> property Key of element of argument -1 | true | +| System.Collections.Specialized.ListDictionary.set_Item(object, object) | argument 1 -> property Value of element of argument -1 | true | +| System.Collections.Specialized.NameObjectCollectionBase.CopyTo(Array, int) | element of argument -1 -> element of return (out parameter 0) | true | +| System.Collections.Specialized.NameObjectCollectionBase.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | +| System.Collections.Specialized.NameObjectCollectionBase.KeysCollection.CopyTo(Array, int) | element of argument -1 -> element of return (out parameter 0) | true | +| System.Collections.Specialized.NameObjectCollectionBase.KeysCollection.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | +| System.Collections.Specialized.NameValueCollection.Add(NameValueCollection) | argument 0 -> element of argument -1 | true | +| System.Collections.Specialized.NameValueCollection.CopyTo(Array, int) | element of argument -1 -> element of return (out parameter 0) | true | +| System.Collections.Specialized.OrderedDictionary.Add(object, object) | argument 0 -> property Key of element of argument -1 | true | +| System.Collections.Specialized.OrderedDictionary.Add(object, object) | argument 1 -> property Value of element of argument -1 | true | +| System.Collections.Specialized.OrderedDictionary.AsReadOnly() | element of argument 0 -> element of return (normal) | true | +| System.Collections.Specialized.OrderedDictionary.CopyTo(Array, int) | element of argument -1 -> element of return (out parameter 0) | true | +| System.Collections.Specialized.OrderedDictionary.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | +| System.Collections.Specialized.OrderedDictionary.OrderedDictionaryKeyValueCollection.CopyTo(Array, int) | element of argument -1 -> element of return (out parameter 0) | true | +| System.Collections.Specialized.OrderedDictionary.OrderedDictionaryKeyValueCollection.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | +| System.Collections.Specialized.OrderedDictionary.get_Item(int) | property Value of element of argument -1 -> return (normal) | true | +| System.Collections.Specialized.OrderedDictionary.get_Item(object) | property Value of element of argument -1 -> return (normal) | true | +| System.Collections.Specialized.OrderedDictionary.get_Keys() | property Key of element of argument -1 -> element of return (normal) | true | +| System.Collections.Specialized.OrderedDictionary.get_Values() | property Value of element of argument -1 -> element of return (normal) | true | +| System.Collections.Specialized.OrderedDictionary.set_Item(int, object) | argument 0 -> property Key of element of argument -1 | true | +| System.Collections.Specialized.OrderedDictionary.set_Item(int, object) | argument 1 -> property Value of element of argument -1 | true | +| System.Collections.Specialized.OrderedDictionary.set_Item(object, object) | argument 0 -> property Key of element of argument -1 | true | +| System.Collections.Specialized.OrderedDictionary.set_Item(object, object) | argument 1 -> property Value of element of argument -1 | true | +| System.Collections.Specialized.ReadOnlyList.Add(object) | argument 0 -> element of argument -1 | true | +| System.Collections.Specialized.ReadOnlyList.CopyTo(Array, int) | element of argument -1 -> element of return (out parameter 0) | true | +| System.Collections.Specialized.ReadOnlyList.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | +| System.Collections.Specialized.ReadOnlyList.Insert(int, object) | argument 1 -> element of argument -1 | true | +| System.Collections.Specialized.ReadOnlyList.get_Item(int) | element of argument -1 -> return (normal) | true | +| System.Collections.Specialized.ReadOnlyList.set_Item(int, object) | argument 1 -> element of argument -1 | true | +| System.Collections.Specialized.StringCollection.Add(object) | argument 0 -> element of argument -1 | true | +| System.Collections.Specialized.StringCollection.Add(string) | argument 0 -> element of argument -1 | true | +| System.Collections.Specialized.StringCollection.AddRange(String[]) | element of argument 0 -> element of argument -1 | true | +| System.Collections.Specialized.StringCollection.CopyTo(Array, int) | element of argument -1 -> element of return (out parameter 0) | true | +| System.Collections.Specialized.StringCollection.CopyTo(String[], int) | element of argument -1 -> element of return (out parameter 0) | true | +| System.Collections.Specialized.StringCollection.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | +| System.Collections.Specialized.StringCollection.Insert(int, object) | argument 1 -> element of argument -1 | true | +| System.Collections.Specialized.StringCollection.Insert(int, string) | argument 1 -> element of argument -1 | true | +| System.Collections.Specialized.StringCollection.get_Item(int) | element of argument -1 -> return (normal) | true | +| System.Collections.Specialized.StringCollection.set_Item(int, object) | argument 1 -> element of argument -1 | true | +| System.Collections.Specialized.StringCollection.set_Item(int, string) | argument 1 -> element of argument -1 | true | +| System.Collections.Specialized.StringDictionary.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | +| System.Collections.Stack.Clone() | element of argument 0 -> element of return (normal) | true | +| System.Collections.Stack.CopyTo(Array, int) | element of argument -1 -> element of return (out parameter 0) | true | +| System.Collections.Stack.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | +| System.Collections.Stack.Peek() | element of argument -1 -> return (normal) | true | +| System.Collections.Stack.Pop() | element of argument -1 -> return (normal) | true | +| System.Collections.Stack.SyncStack.Clone() | element of argument 0 -> element of return (normal) | true | +| System.Collections.Stack.SyncStack.CopyTo(Array, int) | element of argument -1 -> element of return (out parameter 0) | true | +| System.Collections.Stack.SyncStack.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | +| System.Collections.Stack.SyncStack.Peek() | element of argument -1 -> return (normal) | true | +| System.Collections.Stack.SyncStack.Pop() | element of argument -1 -> return (normal) | true | +| System.ComponentModel.AttributeCollection.CopyTo(Array, int) | element of argument -1 -> element of return (out parameter 0) | true | +| System.ComponentModel.AttributeCollection.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | +| System.ComponentModel.BindingList<>.Find(PropertyDescriptor, object) | element of argument -1 -> return (normal) | true | +| System.ComponentModel.Design.DesignerCollection.CopyTo(Array, int) | element of argument -1 -> element of return (out parameter 0) | true | +| System.ComponentModel.Design.DesignerCollection.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | +| System.ComponentModel.Design.DesignerOptionService.DesignerOptionCollection.Add(object) | argument 0 -> element of argument -1 | true | +| System.ComponentModel.Design.DesignerOptionService.DesignerOptionCollection.CopyTo(Array, int) | element of argument -1 -> element of return (out parameter 0) | true | +| System.ComponentModel.Design.DesignerOptionService.DesignerOptionCollection.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | +| System.ComponentModel.Design.DesignerOptionService.DesignerOptionCollection.Insert(int, object) | argument 1 -> element of argument -1 | true | +| System.ComponentModel.Design.DesignerOptionService.DesignerOptionCollection.get_Item(int) | element of argument -1 -> return (normal) | true | +| System.ComponentModel.Design.DesignerOptionService.DesignerOptionCollection.get_Item(string) | element of argument -1 -> return (normal) | true | +| System.ComponentModel.Design.DesignerOptionService.DesignerOptionCollection.set_Item(int, object) | argument 1 -> element of argument -1 | true | +| System.ComponentModel.Design.DesignerVerbCollection.Add(DesignerVerb) | argument 0 -> element of argument -1 | true | +| System.ComponentModel.Design.DesignerVerbCollection.AddRange(DesignerVerbCollection) | element of argument 0 -> element of argument -1 | true | +| System.ComponentModel.Design.DesignerVerbCollection.AddRange(DesignerVerb[]) | element of argument 0 -> element of argument -1 | true | +| System.ComponentModel.Design.DesignerVerbCollection.CopyTo(DesignerVerb[], int) | element of argument -1 -> element of return (out parameter 0) | true | +| System.ComponentModel.Design.DesignerVerbCollection.Insert(int, DesignerVerb) | argument 1 -> element of argument -1 | true | +| System.ComponentModel.Design.DesignerVerbCollection.get_Item(int) | element of argument -1 -> return (normal) | true | +| System.ComponentModel.Design.DesignerVerbCollection.set_Item(int, DesignerVerb) | argument 1 -> element of argument -1 | true | +| System.ComponentModel.EventDescriptorCollection.Add(EventDescriptor) | argument 0 -> element of argument -1 | true | +| System.ComponentModel.EventDescriptorCollection.Add(object) | argument 0 -> element of argument -1 | true | +| System.ComponentModel.EventDescriptorCollection.CopyTo(Array, int) | element of argument -1 -> element of return (out parameter 0) | true | +| System.ComponentModel.EventDescriptorCollection.Find(string, bool) | element of argument -1 -> return (normal) | true | +| System.ComponentModel.EventDescriptorCollection.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | +| System.ComponentModel.EventDescriptorCollection.Insert(int, EventDescriptor) | argument 1 -> element of argument -1 | true | +| System.ComponentModel.EventDescriptorCollection.Insert(int, object) | argument 1 -> element of argument -1 | true | +| System.ComponentModel.EventDescriptorCollection.get_Item(int) | element of argument -1 -> return (normal) | true | +| System.ComponentModel.EventDescriptorCollection.get_Item(string) | element of argument -1 -> return (normal) | true | +| System.ComponentModel.EventDescriptorCollection.set_Item(int, object) | argument 1 -> element of argument -1 | true | +| System.ComponentModel.IBindingList.Find(PropertyDescriptor, object) | element of argument -1 -> return (normal) | true | +| System.ComponentModel.ListSortDescriptionCollection.Add(object) | argument 0 -> element of argument -1 | true | +| System.ComponentModel.ListSortDescriptionCollection.CopyTo(Array, int) | element of argument -1 -> element of return (out parameter 0) | true | +| System.ComponentModel.ListSortDescriptionCollection.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | +| System.ComponentModel.ListSortDescriptionCollection.Insert(int, object) | argument 1 -> element of argument -1 | true | +| System.ComponentModel.ListSortDescriptionCollection.get_Item(int) | element of argument -1 -> return (normal) | true | +| System.ComponentModel.ListSortDescriptionCollection.set_Item(int, ListSortDescription) | argument 1 -> element of argument -1 | true | +| System.ComponentModel.ListSortDescriptionCollection.set_Item(int, object) | argument 1 -> element of argument -1 | true | +| System.ComponentModel.PropertyDescriptorCollection.Add(PropertyDescriptor) | argument 0 -> element of argument -1 | true | +| System.ComponentModel.PropertyDescriptorCollection.Add(PropertyDescriptor) | property Key of argument 0 -> property Key of element of argument -1 | true | +| System.ComponentModel.PropertyDescriptorCollection.Add(PropertyDescriptor) | property Value of argument 0 -> property Value of element of argument -1 | true | +| System.ComponentModel.PropertyDescriptorCollection.Add(object) | argument 0 -> element of argument -1 | true | +| System.ComponentModel.PropertyDescriptorCollection.Add(object) | property Key of argument 0 -> property Key of element of argument -1 | true | +| System.ComponentModel.PropertyDescriptorCollection.Add(object) | property Value of argument 0 -> property Value of element of argument -1 | true | +| System.ComponentModel.PropertyDescriptorCollection.Add(object, object) | argument 0 -> property Key of element of argument -1 | true | +| System.ComponentModel.PropertyDescriptorCollection.Add(object, object) | argument 1 -> property Value of element of argument -1 | true | +| System.ComponentModel.PropertyDescriptorCollection.CopyTo(Array, int) | element of argument -1 -> element of return (out parameter 0) | true | +| System.ComponentModel.PropertyDescriptorCollection.Find(string, bool) | element of argument -1 -> return (normal) | true | +| System.ComponentModel.PropertyDescriptorCollection.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | +| System.ComponentModel.PropertyDescriptorCollection.Insert(int, PropertyDescriptor) | argument 1 -> element of argument -1 | true | +| System.ComponentModel.PropertyDescriptorCollection.Insert(int, object) | argument 1 -> element of argument -1 | true | +| System.ComponentModel.PropertyDescriptorCollection.PropertyDescriptorCollection(PropertyDescriptor[]) | property Key of element of argument 0 -> property Key of element of return (normal) | true | +| System.ComponentModel.PropertyDescriptorCollection.PropertyDescriptorCollection(PropertyDescriptor[]) | property Value of element of argument 0 -> property Value of element of return (normal) | true | +| System.ComponentModel.PropertyDescriptorCollection.PropertyDescriptorCollection(PropertyDescriptor[], bool) | property Key of element of argument 0 -> property Key of element of return (normal) | true | +| System.ComponentModel.PropertyDescriptorCollection.PropertyDescriptorCollection(PropertyDescriptor[], bool) | property Value of element of argument 0 -> property Value of element of return (normal) | true | +| System.ComponentModel.PropertyDescriptorCollection.get_Item(int) | element of argument -1 -> return (normal) | true | +| System.ComponentModel.PropertyDescriptorCollection.get_Item(int) | property Value of element of argument -1 -> return (normal) | true | +| System.ComponentModel.PropertyDescriptorCollection.get_Item(object) | element of argument -1 -> return (normal) | true | +| System.ComponentModel.PropertyDescriptorCollection.get_Item(object) | property Value of element of argument -1 -> return (normal) | true | +| System.ComponentModel.PropertyDescriptorCollection.get_Item(string) | element of argument -1 -> return (normal) | true | +| System.ComponentModel.PropertyDescriptorCollection.get_Item(string) | property Value of element of argument -1 -> return (normal) | true | +| System.ComponentModel.PropertyDescriptorCollection.get_Keys() | property Key of element of argument -1 -> element of return (normal) | true | +| System.ComponentModel.PropertyDescriptorCollection.get_Values() | property Value of element of argument -1 -> element of return (normal) | true | +| System.ComponentModel.PropertyDescriptorCollection.set_Item(int, object) | argument 0 -> property Key of element of argument -1 | true | +| System.ComponentModel.PropertyDescriptorCollection.set_Item(int, object) | argument 1 -> element of argument -1 | true | +| System.ComponentModel.PropertyDescriptorCollection.set_Item(int, object) | argument 1 -> property Value of element of argument -1 | true | +| System.ComponentModel.PropertyDescriptorCollection.set_Item(object, object) | argument 0 -> property Key of element of argument -1 | true | +| System.ComponentModel.PropertyDescriptorCollection.set_Item(object, object) | argument 1 -> element of argument -1 | true | +| System.ComponentModel.PropertyDescriptorCollection.set_Item(object, object) | argument 1 -> property Value of element of argument -1 | true | +| System.ComponentModel.TypeConverter.StandardValuesCollection.CopyTo(Array, int) | element of argument -1 -> element of return (out parameter 0) | true | +| System.ComponentModel.TypeConverter.StandardValuesCollection.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | +| System.ConsolePal.UnixConsoleStream.Read(Byte[], int, int) | argument -1 -> return (out parameter 0) | false | +| System.ConsolePal.UnixConsoleStream.Write(Byte[], int, int) | argument 0 -> argument -1 | false | +| System.Convert.ChangeType(object, Type) | argument 0 -> return (normal) | false | +| System.Convert.ChangeType(object, Type, IFormatProvider) | argument 0 -> return (normal) | false | +| System.Convert.ChangeType(object, TypeCode) | argument 0 -> return (normal) | false | +| System.Convert.ChangeType(object, TypeCode, IFormatProvider) | argument 0 -> return (normal) | false | +| System.Convert.FromBase64CharArray(Char[], int, int) | argument 0 -> return (normal) | false | +| System.Convert.FromBase64String(string) | argument 0 -> return (normal) | false | +| System.Convert.FromHexString(ReadOnlySpan) | argument 0 -> return (normal) | false | +| System.Convert.FromHexString(string) | argument 0 -> return (normal) | false | +| System.Convert.GetTypeCode(object) | argument 0 -> return (normal) | false | +| System.Convert.IsDBNull(object) | argument 0 -> return (normal) | false | +| System.Convert.ToBase64CharArray(Byte[], int, int, Char[], int) | argument 0 -> return (normal) | false | +| System.Convert.ToBase64CharArray(Byte[], int, int, Char[], int, Base64FormattingOptions) | argument 0 -> return (normal) | false | +| System.Convert.ToBase64String(Byte[]) | argument 0 -> return (normal) | false | +| System.Convert.ToBase64String(Byte[], Base64FormattingOptions) | argument 0 -> return (normal) | false | +| System.Convert.ToBase64String(Byte[], int, int) | argument 0 -> return (normal) | false | +| System.Convert.ToBase64String(Byte[], int, int, Base64FormattingOptions) | argument 0 -> return (normal) | false | +| System.Convert.ToBase64String(ReadOnlySpan, Base64FormattingOptions) | argument 0 -> return (normal) | false | +| System.Convert.ToBoolean(DateTime) | argument 0 -> return (normal) | false | +| System.Convert.ToBoolean(bool) | argument 0 -> return (normal) | false | +| System.Convert.ToBoolean(byte) | argument 0 -> return (normal) | false | +| System.Convert.ToBoolean(char) | argument 0 -> return (normal) | false | +| System.Convert.ToBoolean(decimal) | argument 0 -> return (normal) | false | +| System.Convert.ToBoolean(double) | argument 0 -> return (normal) | false | +| System.Convert.ToBoolean(float) | argument 0 -> return (normal) | false | +| System.Convert.ToBoolean(int) | argument 0 -> return (normal) | false | +| System.Convert.ToBoolean(long) | argument 0 -> return (normal) | false | +| System.Convert.ToBoolean(object) | argument 0 -> return (normal) | false | +| System.Convert.ToBoolean(object, IFormatProvider) | argument 0 -> return (normal) | false | +| System.Convert.ToBoolean(sbyte) | argument 0 -> return (normal) | false | +| System.Convert.ToBoolean(short) | argument 0 -> return (normal) | false | +| System.Convert.ToBoolean(string) | argument 0 -> return (normal) | false | +| System.Convert.ToBoolean(string, IFormatProvider) | argument 0 -> return (normal) | false | +| System.Convert.ToBoolean(uint) | argument 0 -> return (normal) | false | +| System.Convert.ToBoolean(ulong) | argument 0 -> return (normal) | false | +| System.Convert.ToBoolean(ushort) | argument 0 -> return (normal) | false | +| System.Convert.ToByte(DateTime) | argument 0 -> return (normal) | false | +| System.Convert.ToByte(bool) | argument 0 -> return (normal) | false | +| System.Convert.ToByte(byte) | argument 0 -> return (normal) | false | +| System.Convert.ToByte(char) | argument 0 -> return (normal) | false | +| System.Convert.ToByte(decimal) | argument 0 -> return (normal) | false | +| System.Convert.ToByte(double) | argument 0 -> return (normal) | false | +| System.Convert.ToByte(float) | argument 0 -> return (normal) | false | +| System.Convert.ToByte(int) | argument 0 -> return (normal) | false | +| System.Convert.ToByte(long) | argument 0 -> return (normal) | false | +| System.Convert.ToByte(object) | argument 0 -> return (normal) | false | +| System.Convert.ToByte(object, IFormatProvider) | argument 0 -> return (normal) | false | +| System.Convert.ToByte(sbyte) | argument 0 -> return (normal) | false | +| System.Convert.ToByte(short) | argument 0 -> return (normal) | false | +| System.Convert.ToByte(string) | argument 0 -> return (normal) | false | +| System.Convert.ToByte(string, IFormatProvider) | argument 0 -> return (normal) | false | +| System.Convert.ToByte(string, int) | argument 0 -> return (normal) | false | +| System.Convert.ToByte(uint) | argument 0 -> return (normal) | false | +| System.Convert.ToByte(ulong) | argument 0 -> return (normal) | false | +| System.Convert.ToByte(ushort) | argument 0 -> return (normal) | false | +| System.Convert.ToChar(DateTime) | argument 0 -> return (normal) | false | +| System.Convert.ToChar(bool) | argument 0 -> return (normal) | false | +| System.Convert.ToChar(byte) | argument 0 -> return (normal) | false | +| System.Convert.ToChar(char) | argument 0 -> return (normal) | false | +| System.Convert.ToChar(decimal) | argument 0 -> return (normal) | false | +| System.Convert.ToChar(double) | argument 0 -> return (normal) | false | +| System.Convert.ToChar(float) | argument 0 -> return (normal) | false | +| System.Convert.ToChar(int) | argument 0 -> return (normal) | false | +| System.Convert.ToChar(long) | argument 0 -> return (normal) | false | +| System.Convert.ToChar(object) | argument 0 -> return (normal) | false | +| System.Convert.ToChar(object, IFormatProvider) | argument 0 -> return (normal) | false | +| System.Convert.ToChar(sbyte) | argument 0 -> return (normal) | false | +| System.Convert.ToChar(short) | argument 0 -> return (normal) | false | +| System.Convert.ToChar(string) | argument 0 -> return (normal) | false | +| System.Convert.ToChar(string, IFormatProvider) | argument 0 -> return (normal) | false | +| System.Convert.ToChar(uint) | argument 0 -> return (normal) | false | +| System.Convert.ToChar(ulong) | argument 0 -> return (normal) | false | +| System.Convert.ToChar(ushort) | argument 0 -> return (normal) | false | +| System.Convert.ToDateTime(DateTime) | argument 0 -> return (normal) | false | +| System.Convert.ToDateTime(bool) | argument 0 -> return (normal) | false | +| System.Convert.ToDateTime(byte) | argument 0 -> return (normal) | false | +| System.Convert.ToDateTime(char) | argument 0 -> return (normal) | false | +| System.Convert.ToDateTime(decimal) | argument 0 -> return (normal) | false | +| System.Convert.ToDateTime(double) | argument 0 -> return (normal) | false | +| System.Convert.ToDateTime(float) | argument 0 -> return (normal) | false | +| System.Convert.ToDateTime(int) | argument 0 -> return (normal) | false | +| System.Convert.ToDateTime(long) | argument 0 -> return (normal) | false | +| System.Convert.ToDateTime(object) | argument 0 -> return (normal) | false | +| System.Convert.ToDateTime(object, IFormatProvider) | argument 0 -> return (normal) | false | +| System.Convert.ToDateTime(sbyte) | argument 0 -> return (normal) | false | +| System.Convert.ToDateTime(short) | argument 0 -> return (normal) | false | +| System.Convert.ToDateTime(string) | argument 0 -> return (normal) | false | +| System.Convert.ToDateTime(string, IFormatProvider) | argument 0 -> return (normal) | false | +| System.Convert.ToDateTime(uint) | argument 0 -> return (normal) | false | +| System.Convert.ToDateTime(ulong) | argument 0 -> return (normal) | false | +| System.Convert.ToDateTime(ushort) | argument 0 -> return (normal) | false | +| System.Convert.ToDecimal(DateTime) | argument 0 -> return (normal) | false | +| System.Convert.ToDecimal(bool) | argument 0 -> return (normal) | false | +| System.Convert.ToDecimal(byte) | argument 0 -> return (normal) | false | +| System.Convert.ToDecimal(char) | argument 0 -> return (normal) | false | +| System.Convert.ToDecimal(decimal) | argument 0 -> return (normal) | false | +| System.Convert.ToDecimal(double) | argument 0 -> return (normal) | false | +| System.Convert.ToDecimal(float) | argument 0 -> return (normal) | false | +| System.Convert.ToDecimal(int) | argument 0 -> return (normal) | false | +| System.Convert.ToDecimal(long) | argument 0 -> return (normal) | false | +| System.Convert.ToDecimal(object) | argument 0 -> return (normal) | false | +| System.Convert.ToDecimal(object, IFormatProvider) | argument 0 -> return (normal) | false | +| System.Convert.ToDecimal(sbyte) | argument 0 -> return (normal) | false | +| System.Convert.ToDecimal(short) | argument 0 -> return (normal) | false | +| System.Convert.ToDecimal(string) | argument 0 -> return (normal) | false | +| System.Convert.ToDecimal(string, IFormatProvider) | argument 0 -> return (normal) | false | +| System.Convert.ToDecimal(uint) | argument 0 -> return (normal) | false | +| System.Convert.ToDecimal(ulong) | argument 0 -> return (normal) | false | +| System.Convert.ToDecimal(ushort) | argument 0 -> return (normal) | false | +| System.Convert.ToDouble(DateTime) | argument 0 -> return (normal) | false | +| System.Convert.ToDouble(bool) | argument 0 -> return (normal) | false | +| System.Convert.ToDouble(byte) | argument 0 -> return (normal) | false | +| System.Convert.ToDouble(char) | argument 0 -> return (normal) | false | +| System.Convert.ToDouble(decimal) | argument 0 -> return (normal) | false | +| System.Convert.ToDouble(double) | argument 0 -> return (normal) | false | +| System.Convert.ToDouble(float) | argument 0 -> return (normal) | false | +| System.Convert.ToDouble(int) | argument 0 -> return (normal) | false | +| System.Convert.ToDouble(long) | argument 0 -> return (normal) | false | +| System.Convert.ToDouble(object) | argument 0 -> return (normal) | false | +| System.Convert.ToDouble(object, IFormatProvider) | argument 0 -> return (normal) | false | +| System.Convert.ToDouble(sbyte) | argument 0 -> return (normal) | false | +| System.Convert.ToDouble(short) | argument 0 -> return (normal) | false | +| System.Convert.ToDouble(string) | argument 0 -> return (normal) | false | +| System.Convert.ToDouble(string, IFormatProvider) | argument 0 -> return (normal) | false | +| System.Convert.ToDouble(uint) | argument 0 -> return (normal) | false | +| System.Convert.ToDouble(ulong) | argument 0 -> return (normal) | false | +| System.Convert.ToDouble(ushort) | argument 0 -> return (normal) | false | +| System.Convert.ToHexString(Byte[]) | argument 0 -> return (normal) | false | +| System.Convert.ToHexString(Byte[], int, int) | argument 0 -> return (normal) | false | +| System.Convert.ToHexString(ReadOnlySpan) | argument 0 -> return (normal) | false | +| System.Convert.ToInt16(DateTime) | argument 0 -> return (normal) | false | +| System.Convert.ToInt16(bool) | argument 0 -> return (normal) | false | +| System.Convert.ToInt16(byte) | argument 0 -> return (normal) | false | +| System.Convert.ToInt16(char) | argument 0 -> return (normal) | false | +| System.Convert.ToInt16(decimal) | argument 0 -> return (normal) | false | +| System.Convert.ToInt16(double) | argument 0 -> return (normal) | false | +| System.Convert.ToInt16(float) | argument 0 -> return (normal) | false | +| System.Convert.ToInt16(int) | argument 0 -> return (normal) | false | +| System.Convert.ToInt16(long) | argument 0 -> return (normal) | false | +| System.Convert.ToInt16(object) | argument 0 -> return (normal) | false | +| System.Convert.ToInt16(object, IFormatProvider) | argument 0 -> return (normal) | false | +| System.Convert.ToInt16(sbyte) | argument 0 -> return (normal) | false | +| System.Convert.ToInt16(short) | argument 0 -> return (normal) | false | +| System.Convert.ToInt16(string) | argument 0 -> return (normal) | false | +| System.Convert.ToInt16(string, IFormatProvider) | argument 0 -> return (normal) | false | +| System.Convert.ToInt16(string, int) | argument 0 -> return (normal) | false | +| System.Convert.ToInt16(uint) | argument 0 -> return (normal) | false | +| System.Convert.ToInt16(ulong) | argument 0 -> return (normal) | false | +| System.Convert.ToInt16(ushort) | argument 0 -> return (normal) | false | +| System.Convert.ToInt32(DateTime) | argument 0 -> return (normal) | false | +| System.Convert.ToInt32(bool) | argument 0 -> return (normal) | false | +| System.Convert.ToInt32(byte) | argument 0 -> return (normal) | false | +| System.Convert.ToInt32(char) | argument 0 -> return (normal) | false | +| System.Convert.ToInt32(decimal) | argument 0 -> return (normal) | false | +| System.Convert.ToInt32(double) | argument 0 -> return (normal) | false | +| System.Convert.ToInt32(float) | argument 0 -> return (normal) | false | +| System.Convert.ToInt32(int) | argument 0 -> return (normal) | false | +| System.Convert.ToInt32(long) | argument 0 -> return (normal) | false | +| System.Convert.ToInt32(object) | argument 0 -> return (normal) | false | +| System.Convert.ToInt32(object, IFormatProvider) | argument 0 -> return (normal) | false | +| System.Convert.ToInt32(sbyte) | argument 0 -> return (normal) | false | +| System.Convert.ToInt32(short) | argument 0 -> return (normal) | false | +| System.Convert.ToInt32(string) | argument 0 -> return (normal) | false | +| System.Convert.ToInt32(string, IFormatProvider) | argument 0 -> return (normal) | false | +| System.Convert.ToInt32(string, int) | argument 0 -> return (normal) | false | +| System.Convert.ToInt32(uint) | argument 0 -> return (normal) | false | +| System.Convert.ToInt32(ulong) | argument 0 -> return (normal) | false | +| System.Convert.ToInt32(ushort) | argument 0 -> return (normal) | false | +| System.Convert.ToInt64(DateTime) | argument 0 -> return (normal) | false | +| System.Convert.ToInt64(bool) | argument 0 -> return (normal) | false | +| System.Convert.ToInt64(byte) | argument 0 -> return (normal) | false | +| System.Convert.ToInt64(char) | argument 0 -> return (normal) | false | +| System.Convert.ToInt64(decimal) | argument 0 -> return (normal) | false | +| System.Convert.ToInt64(double) | argument 0 -> return (normal) | false | +| System.Convert.ToInt64(float) | argument 0 -> return (normal) | false | +| System.Convert.ToInt64(int) | argument 0 -> return (normal) | false | +| System.Convert.ToInt64(long) | argument 0 -> return (normal) | false | +| System.Convert.ToInt64(object) | argument 0 -> return (normal) | false | +| System.Convert.ToInt64(object, IFormatProvider) | argument 0 -> return (normal) | false | +| System.Convert.ToInt64(sbyte) | argument 0 -> return (normal) | false | +| System.Convert.ToInt64(short) | argument 0 -> return (normal) | false | +| System.Convert.ToInt64(string) | argument 0 -> return (normal) | false | +| System.Convert.ToInt64(string, IFormatProvider) | argument 0 -> return (normal) | false | +| System.Convert.ToInt64(string, int) | argument 0 -> return (normal) | false | +| System.Convert.ToInt64(uint) | argument 0 -> return (normal) | false | +| System.Convert.ToInt64(ulong) | argument 0 -> return (normal) | false | +| System.Convert.ToInt64(ushort) | argument 0 -> return (normal) | false | +| System.Convert.ToSByte(DateTime) | argument 0 -> return (normal) | false | +| System.Convert.ToSByte(bool) | argument 0 -> return (normal) | false | +| System.Convert.ToSByte(byte) | argument 0 -> return (normal) | false | +| System.Convert.ToSByte(char) | argument 0 -> return (normal) | false | +| System.Convert.ToSByte(decimal) | argument 0 -> return (normal) | false | +| System.Convert.ToSByte(double) | argument 0 -> return (normal) | false | +| System.Convert.ToSByte(float) | argument 0 -> return (normal) | false | +| System.Convert.ToSByte(int) | argument 0 -> return (normal) | false | +| System.Convert.ToSByte(long) | argument 0 -> return (normal) | false | +| System.Convert.ToSByte(object) | argument 0 -> return (normal) | false | +| System.Convert.ToSByte(object, IFormatProvider) | argument 0 -> return (normal) | false | +| System.Convert.ToSByte(sbyte) | argument 0 -> return (normal) | false | +| System.Convert.ToSByte(short) | argument 0 -> return (normal) | false | +| System.Convert.ToSByte(string) | argument 0 -> return (normal) | false | +| System.Convert.ToSByte(string, IFormatProvider) | argument 0 -> return (normal) | false | +| System.Convert.ToSByte(string, int) | argument 0 -> return (normal) | false | +| System.Convert.ToSByte(uint) | argument 0 -> return (normal) | false | +| System.Convert.ToSByte(ulong) | argument 0 -> return (normal) | false | +| System.Convert.ToSByte(ushort) | argument 0 -> return (normal) | false | +| System.Convert.ToSingle(DateTime) | argument 0 -> return (normal) | false | +| System.Convert.ToSingle(bool) | argument 0 -> return (normal) | false | +| System.Convert.ToSingle(byte) | argument 0 -> return (normal) | false | +| System.Convert.ToSingle(char) | argument 0 -> return (normal) | false | +| System.Convert.ToSingle(decimal) | argument 0 -> return (normal) | false | +| System.Convert.ToSingle(double) | argument 0 -> return (normal) | false | +| System.Convert.ToSingle(float) | argument 0 -> return (normal) | false | +| System.Convert.ToSingle(int) | argument 0 -> return (normal) | false | +| System.Convert.ToSingle(long) | argument 0 -> return (normal) | false | +| System.Convert.ToSingle(object) | argument 0 -> return (normal) | false | +| System.Convert.ToSingle(object, IFormatProvider) | argument 0 -> return (normal) | false | +| System.Convert.ToSingle(sbyte) | argument 0 -> return (normal) | false | +| System.Convert.ToSingle(short) | argument 0 -> return (normal) | false | +| System.Convert.ToSingle(string) | argument 0 -> return (normal) | false | +| System.Convert.ToSingle(string, IFormatProvider) | argument 0 -> return (normal) | false | +| System.Convert.ToSingle(uint) | argument 0 -> return (normal) | false | +| System.Convert.ToSingle(ulong) | argument 0 -> return (normal) | false | +| System.Convert.ToSingle(ushort) | argument 0 -> return (normal) | false | +| System.Convert.ToString(DateTime) | argument 0 -> return (normal) | false | +| System.Convert.ToString(DateTime, IFormatProvider) | argument 0 -> return (normal) | false | +| System.Convert.ToString(bool) | argument 0 -> return (normal) | false | +| System.Convert.ToString(bool, IFormatProvider) | argument 0 -> return (normal) | false | +| System.Convert.ToString(byte) | argument 0 -> return (normal) | false | +| System.Convert.ToString(byte, IFormatProvider) | argument 0 -> return (normal) | false | +| System.Convert.ToString(byte, int) | argument 0 -> return (normal) | false | +| System.Convert.ToString(char) | argument 0 -> return (normal) | false | +| System.Convert.ToString(char, IFormatProvider) | argument 0 -> return (normal) | false | +| System.Convert.ToString(decimal) | argument 0 -> return (normal) | false | +| System.Convert.ToString(decimal, IFormatProvider) | argument 0 -> return (normal) | false | +| System.Convert.ToString(double) | argument 0 -> return (normal) | false | +| System.Convert.ToString(double, IFormatProvider) | argument 0 -> return (normal) | false | +| System.Convert.ToString(float) | argument 0 -> return (normal) | false | +| System.Convert.ToString(float, IFormatProvider) | argument 0 -> return (normal) | false | +| System.Convert.ToString(int) | argument 0 -> return (normal) | false | +| System.Convert.ToString(int, IFormatProvider) | argument 0 -> return (normal) | false | +| System.Convert.ToString(int, int) | argument 0 -> return (normal) | false | +| System.Convert.ToString(long) | argument 0 -> return (normal) | false | +| System.Convert.ToString(long, IFormatProvider) | argument 0 -> return (normal) | false | +| System.Convert.ToString(long, int) | argument 0 -> return (normal) | false | +| System.Convert.ToString(object) | argument 0 -> return (normal) | false | +| System.Convert.ToString(object, IFormatProvider) | argument 0 -> return (normal) | false | +| System.Convert.ToString(sbyte) | argument 0 -> return (normal) | false | +| System.Convert.ToString(sbyte, IFormatProvider) | argument 0 -> return (normal) | false | +| System.Convert.ToString(short) | argument 0 -> return (normal) | false | +| System.Convert.ToString(short, IFormatProvider) | argument 0 -> return (normal) | false | +| System.Convert.ToString(short, int) | argument 0 -> return (normal) | false | +| System.Convert.ToString(string) | argument 0 -> return (normal) | false | +| System.Convert.ToString(string, IFormatProvider) | argument 0 -> return (normal) | false | +| System.Convert.ToString(uint) | argument 0 -> return (normal) | false | +| System.Convert.ToString(uint, IFormatProvider) | argument 0 -> return (normal) | false | +| System.Convert.ToString(ulong) | argument 0 -> return (normal) | false | +| System.Convert.ToString(ulong, IFormatProvider) | argument 0 -> return (normal) | false | +| System.Convert.ToString(ushort) | argument 0 -> return (normal) | false | +| System.Convert.ToString(ushort, IFormatProvider) | argument 0 -> return (normal) | false | +| System.Convert.ToUInt16(DateTime) | argument 0 -> return (normal) | false | +| System.Convert.ToUInt16(bool) | argument 0 -> return (normal) | false | +| System.Convert.ToUInt16(byte) | argument 0 -> return (normal) | false | +| System.Convert.ToUInt16(char) | argument 0 -> return (normal) | false | +| System.Convert.ToUInt16(decimal) | argument 0 -> return (normal) | false | +| System.Convert.ToUInt16(double) | argument 0 -> return (normal) | false | +| System.Convert.ToUInt16(float) | argument 0 -> return (normal) | false | +| System.Convert.ToUInt16(int) | argument 0 -> return (normal) | false | +| System.Convert.ToUInt16(long) | argument 0 -> return (normal) | false | +| System.Convert.ToUInt16(object) | argument 0 -> return (normal) | false | +| System.Convert.ToUInt16(object, IFormatProvider) | argument 0 -> return (normal) | false | +| System.Convert.ToUInt16(sbyte) | argument 0 -> return (normal) | false | +| System.Convert.ToUInt16(short) | argument 0 -> return (normal) | false | +| System.Convert.ToUInt16(string) | argument 0 -> return (normal) | false | +| System.Convert.ToUInt16(string, IFormatProvider) | argument 0 -> return (normal) | false | +| System.Convert.ToUInt16(string, int) | argument 0 -> return (normal) | false | +| System.Convert.ToUInt16(uint) | argument 0 -> return (normal) | false | +| System.Convert.ToUInt16(ulong) | argument 0 -> return (normal) | false | +| System.Convert.ToUInt16(ushort) | argument 0 -> return (normal) | false | +| System.Convert.ToUInt32(DateTime) | argument 0 -> return (normal) | false | +| System.Convert.ToUInt32(bool) | argument 0 -> return (normal) | false | +| System.Convert.ToUInt32(byte) | argument 0 -> return (normal) | false | +| System.Convert.ToUInt32(char) | argument 0 -> return (normal) | false | +| System.Convert.ToUInt32(decimal) | argument 0 -> return (normal) | false | +| System.Convert.ToUInt32(double) | argument 0 -> return (normal) | false | +| System.Convert.ToUInt32(float) | argument 0 -> return (normal) | false | +| System.Convert.ToUInt32(int) | argument 0 -> return (normal) | false | +| System.Convert.ToUInt32(long) | argument 0 -> return (normal) | false | +| System.Convert.ToUInt32(object) | argument 0 -> return (normal) | false | +| System.Convert.ToUInt32(object, IFormatProvider) | argument 0 -> return (normal) | false | +| System.Convert.ToUInt32(sbyte) | argument 0 -> return (normal) | false | +| System.Convert.ToUInt32(short) | argument 0 -> return (normal) | false | +| System.Convert.ToUInt32(string) | argument 0 -> return (normal) | false | +| System.Convert.ToUInt32(string, IFormatProvider) | argument 0 -> return (normal) | false | +| System.Convert.ToUInt32(string, int) | argument 0 -> return (normal) | false | +| System.Convert.ToUInt32(uint) | argument 0 -> return (normal) | false | +| System.Convert.ToUInt32(ulong) | argument 0 -> return (normal) | false | +| System.Convert.ToUInt32(ushort) | argument 0 -> return (normal) | false | +| System.Convert.ToUInt64(DateTime) | argument 0 -> return (normal) | false | +| System.Convert.ToUInt64(bool) | argument 0 -> return (normal) | false | +| System.Convert.ToUInt64(byte) | argument 0 -> return (normal) | false | +| System.Convert.ToUInt64(char) | argument 0 -> return (normal) | false | +| System.Convert.ToUInt64(decimal) | argument 0 -> return (normal) | false | +| System.Convert.ToUInt64(double) | argument 0 -> return (normal) | false | +| System.Convert.ToUInt64(float) | argument 0 -> return (normal) | false | +| System.Convert.ToUInt64(int) | argument 0 -> return (normal) | false | +| System.Convert.ToUInt64(long) | argument 0 -> return (normal) | false | +| System.Convert.ToUInt64(object) | argument 0 -> return (normal) | false | +| System.Convert.ToUInt64(object, IFormatProvider) | argument 0 -> return (normal) | false | +| System.Convert.ToUInt64(sbyte) | argument 0 -> return (normal) | false | +| System.Convert.ToUInt64(short) | argument 0 -> return (normal) | false | +| System.Convert.ToUInt64(string) | argument 0 -> return (normal) | false | +| System.Convert.ToUInt64(string, IFormatProvider) | argument 0 -> return (normal) | false | +| System.Convert.ToUInt64(string, int) | argument 0 -> return (normal) | false | +| System.Convert.ToUInt64(uint) | argument 0 -> return (normal) | false | +| System.Convert.ToUInt64(ulong) | argument 0 -> return (normal) | false | +| System.Convert.ToUInt64(ushort) | argument 0 -> return (normal) | false | +| System.Convert.TryFromBase64Chars(ReadOnlySpan, Span, out int) | argument 0 -> return (normal) | false | +| System.Convert.TryFromBase64String(string, Span, out int) | argument 0 -> return (normal) | false | +| System.Convert.TryToBase64Chars(ReadOnlySpan, Span, out int, Base64FormattingOptions) | argument 0 -> return (normal) | false | +| System.Diagnostics.Tracing.CounterPayload.d__51.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | +| System.Diagnostics.Tracing.CounterPayload.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | +| System.Diagnostics.Tracing.EventPayload.Add(KeyValuePair) | argument 0 -> element of argument -1 | true | +| System.Diagnostics.Tracing.EventPayload.Add(KeyValuePair) | property Key of argument 0 -> property Key of element of argument -1 | true | +| System.Diagnostics.Tracing.EventPayload.Add(KeyValuePair) | property Value of argument 0 -> property Value of element of argument -1 | true | +| System.Diagnostics.Tracing.EventPayload.Add(string, object) | argument 0 -> property Key of element of argument -1 | true | +| System.Diagnostics.Tracing.EventPayload.Add(string, object) | argument 1 -> property Value of element of argument -1 | true | +| System.Diagnostics.Tracing.EventPayload.CopyTo(KeyValuePair[], int) | element of argument -1 -> element of return (out parameter 0) | true | +| System.Diagnostics.Tracing.EventPayload.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | +| System.Diagnostics.Tracing.EventPayload.get_Item(string) | property Value of element of argument -1 -> return (normal) | true | +| System.Diagnostics.Tracing.EventPayload.get_Keys() | property Key of element of argument -1 -> element of return (normal) | true | +| System.Diagnostics.Tracing.EventPayload.get_Values() | property Value of element of argument -1 -> element of return (normal) | true | +| System.Diagnostics.Tracing.EventPayload.set_Item(string, object) | argument 0 -> property Key of element of argument -1 | true | +| System.Diagnostics.Tracing.EventPayload.set_Item(string, object) | argument 1 -> property Value of element of argument -1 | true | +| System.Diagnostics.Tracing.IncrementingCounterPayload.d__39.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | +| System.Diagnostics.Tracing.IncrementingCounterPayload.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | +| System.Dynamic.ExpandoObject.Add(KeyValuePair) | argument 0 -> element of argument -1 | true | +| System.Dynamic.ExpandoObject.Add(KeyValuePair) | property Key of argument 0 -> property Key of element of argument -1 | true | +| System.Dynamic.ExpandoObject.Add(KeyValuePair) | property Value of argument 0 -> property Value of element of argument -1 | true | +| System.Dynamic.ExpandoObject.Add(string, object) | argument 0 -> property Key of element of argument -1 | true | +| System.Dynamic.ExpandoObject.Add(string, object) | argument 1 -> property Value of element of argument -1 | true | +| System.Dynamic.ExpandoObject.CopyTo(KeyValuePair[], int) | element of argument -1 -> element of return (out parameter 0) | true | +| System.Dynamic.ExpandoObject.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | +| System.Dynamic.ExpandoObject.KeyCollection.Add(string) | argument 0 -> element of argument -1 | true | +| System.Dynamic.ExpandoObject.KeyCollection.CopyTo(String[], int) | element of argument -1 -> element of return (out parameter 0) | true | +| System.Dynamic.ExpandoObject.KeyCollection.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | +| System.Dynamic.ExpandoObject.MetaExpando.d__6.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | +| System.Dynamic.ExpandoObject.ValueCollection.Add(object) | argument 0 -> element of argument -1 | true | +| System.Dynamic.ExpandoObject.ValueCollection.CopyTo(Object[], int) | element of argument -1 -> element of return (out parameter 0) | true | +| System.Dynamic.ExpandoObject.ValueCollection.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | +| System.Dynamic.ExpandoObject.get_Item(string) | property Value of element of argument -1 -> return (normal) | true | +| System.Dynamic.ExpandoObject.get_Keys() | property Key of element of argument -1 -> element of return (normal) | true | +| System.Dynamic.ExpandoObject.get_Values() | property Value of element of argument -1 -> element of return (normal) | true | +| System.Dynamic.ExpandoObject.set_Item(string, object) | argument 0 -> property Key of element of argument -1 | true | +| System.Dynamic.ExpandoObject.set_Item(string, object) | argument 1 -> property Value of element of argument -1 | true | +| System.Dynamic.Utils.ListProvider<>.Add(T) | argument 0 -> element of argument -1 | true | +| System.Dynamic.Utils.ListProvider<>.CopyTo(T[], int) | element of argument -1 -> element of return (out parameter 0) | true | +| System.Dynamic.Utils.ListProvider<>.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | +| System.Dynamic.Utils.ListProvider<>.Insert(int, T) | argument 1 -> element of argument -1 | true | +| System.Dynamic.Utils.ListProvider<>.get_Item(int) | element of argument -1 -> return (normal) | true | +| System.Dynamic.Utils.ListProvider<>.set_Item(int, T) | argument 1 -> element of argument -1 | true | +| System.IO.BufferedStream.BeginRead(Byte[], int, int, AsyncCallback, object) | argument -1 -> return (out parameter 0) | false | +| System.IO.BufferedStream.BeginWrite(Byte[], int, int, AsyncCallback, object) | argument 0 -> argument -1 | false | +| System.IO.BufferedStream.CopyTo(Stream, int) | argument -1 -> return (out parameter 0) | false | +| System.IO.BufferedStream.CopyToAsync(Stream, int, CancellationToken) | argument -1 -> return (out parameter 0) | false | +| System.IO.BufferedStream.Read(Byte[], int, int) | argument -1 -> return (out parameter 0) | false | +| System.IO.BufferedStream.ReadAsync(Byte[], int, int, CancellationToken) | argument -1 -> return (out parameter 0) | false | +| System.IO.BufferedStream.Write(Byte[], int, int) | argument 0 -> argument -1 | false | +| System.IO.BufferedStream.WriteAsync(Byte[], int, int, CancellationToken) | argument 0 -> argument -1 | false | +| System.IO.Compression.CheckSumAndSizeWriteStream.Read(Byte[], int, int) | argument -1 -> return (out parameter 0) | false | +| System.IO.Compression.CheckSumAndSizeWriteStream.Write(Byte[], int, int) | argument 0 -> argument -1 | false | +| System.IO.Compression.DeflateManagedStream.BeginRead(Byte[], int, int, AsyncCallback, object) | argument -1 -> return (out parameter 0) | false | +| System.IO.Compression.DeflateManagedStream.Read(Byte[], int, int) | argument -1 -> return (out parameter 0) | false | +| System.IO.Compression.DeflateManagedStream.ReadAsync(Byte[], int, int, CancellationToken) | argument -1 -> return (out parameter 0) | false | +| System.IO.Compression.DeflateManagedStream.Write(Byte[], int, int) | argument 0 -> argument -1 | false | +| System.IO.Compression.DeflateStream.BeginRead(Byte[], int, int, AsyncCallback, object) | argument -1 -> return (out parameter 0) | false | +| System.IO.Compression.DeflateStream.BeginWrite(Byte[], int, int, AsyncCallback, object) | argument 0 -> argument -1 | false | +| System.IO.Compression.DeflateStream.CopyTo(Stream, int) | argument -1 -> return (out parameter 0) | false | +| System.IO.Compression.DeflateStream.CopyToAsync(Stream, int, CancellationToken) | argument -1 -> return (out parameter 0) | false | +| System.IO.Compression.DeflateStream.CopyToStream.Read(Byte[], int, int) | argument -1 -> return (out parameter 0) | false | +| System.IO.Compression.DeflateStream.CopyToStream.Write(Byte[], int, int) | argument 0 -> argument -1 | false | +| System.IO.Compression.DeflateStream.CopyToStream.WriteAsync(Byte[], int, int, CancellationToken) | argument 0 -> argument -1 | false | +| System.IO.Compression.DeflateStream.DeflateStream(Stream, CompressionLevel) | argument 0 -> return (normal) | false | +| System.IO.Compression.DeflateStream.DeflateStream(Stream, CompressionLevel, bool) | argument 0 -> return (normal) | false | +| System.IO.Compression.DeflateStream.DeflateStream(Stream, CompressionMode) | argument 0 -> return (normal) | false | +| System.IO.Compression.DeflateStream.DeflateStream(Stream, CompressionMode, bool) | argument 0 -> return (normal) | false | +| System.IO.Compression.DeflateStream.Read(Byte[], int, int) | argument -1 -> return (out parameter 0) | false | +| System.IO.Compression.DeflateStream.ReadAsync(Byte[], int, int, CancellationToken) | argument -1 -> return (out parameter 0) | false | +| System.IO.Compression.DeflateStream.Write(Byte[], int, int) | argument 0 -> argument -1 | false | +| System.IO.Compression.DeflateStream.WriteAsync(Byte[], int, int, CancellationToken) | argument 0 -> argument -1 | false | +| System.IO.Compression.GZipStream.BeginRead(Byte[], int, int, AsyncCallback, object) | argument -1 -> return (out parameter 0) | false | +| System.IO.Compression.GZipStream.BeginWrite(Byte[], int, int, AsyncCallback, object) | argument 0 -> argument -1 | false | +| System.IO.Compression.GZipStream.CopyTo(Stream, int) | argument -1 -> return (out parameter 0) | false | +| System.IO.Compression.GZipStream.CopyToAsync(Stream, int, CancellationToken) | argument -1 -> return (out parameter 0) | false | +| System.IO.Compression.GZipStream.Read(Byte[], int, int) | argument -1 -> return (out parameter 0) | false | +| System.IO.Compression.GZipStream.ReadAsync(Byte[], int, int, CancellationToken) | argument -1 -> return (out parameter 0) | false | +| System.IO.Compression.GZipStream.Write(Byte[], int, int) | argument 0 -> argument -1 | false | +| System.IO.Compression.GZipStream.WriteAsync(Byte[], int, int, CancellationToken) | argument 0 -> argument -1 | false | +| System.IO.Compression.PositionPreservingWriteOnlyStreamWrapper.BeginWrite(Byte[], int, int, AsyncCallback, object) | argument 0 -> argument -1 | false | +| System.IO.Compression.PositionPreservingWriteOnlyStreamWrapper.Read(Byte[], int, int) | argument -1 -> return (out parameter 0) | false | +| System.IO.Compression.PositionPreservingWriteOnlyStreamWrapper.Write(Byte[], int, int) | argument 0 -> argument -1 | false | +| System.IO.Compression.PositionPreservingWriteOnlyStreamWrapper.WriteAsync(Byte[], int, int, CancellationToken) | argument 0 -> argument -1 | false | +| System.IO.Compression.SubReadStream.Read(Byte[], int, int) | argument -1 -> return (out parameter 0) | false | +| System.IO.Compression.SubReadStream.Write(Byte[], int, int) | argument 0 -> argument -1 | false | +| System.IO.Compression.WrappedStream.Read(Byte[], int, int) | argument -1 -> return (out parameter 0) | false | +| System.IO.Compression.WrappedStream.Write(Byte[], int, int) | argument 0 -> argument -1 | false | +| System.IO.Compression.ZipArchiveEntry.DirectToArchiveWriterStream.Read(Byte[], int, int) | argument -1 -> return (out parameter 0) | false | +| System.IO.Compression.ZipArchiveEntry.DirectToArchiveWriterStream.Write(Byte[], int, int) | argument 0 -> argument -1 | false | +| System.IO.FileStream.BeginRead(Byte[], int, int, AsyncCallback, object) | argument -1 -> return (out parameter 0) | false | +| System.IO.FileStream.BeginWrite(Byte[], int, int, AsyncCallback, object) | argument 0 -> argument -1 | false | +| System.IO.FileStream.CopyToAsync(Stream, int, CancellationToken) | argument -1 -> return (out parameter 0) | false | +| System.IO.FileStream.Read(Byte[], int, int) | argument -1 -> return (out parameter 0) | false | +| System.IO.FileStream.ReadAsync(Byte[], int, int, CancellationToken) | argument -1 -> return (out parameter 0) | false | +| System.IO.FileStream.Write(Byte[], int, int) | argument 0 -> argument -1 | false | +| System.IO.FileStream.WriteAsync(Byte[], int, int, CancellationToken) | argument 0 -> argument -1 | false | +| System.IO.MemoryStream.CopyTo(Stream, int) | argument -1 -> return (out parameter 0) | false | +| System.IO.MemoryStream.CopyToAsync(Stream, int, CancellationToken) | argument -1 -> return (out parameter 0) | false | +| System.IO.MemoryStream.MemoryStream(Byte[]) | argument 0 -> return (normal) | false | +| System.IO.MemoryStream.MemoryStream(Byte[], bool) | argument 0 -> return (normal) | false | +| System.IO.MemoryStream.MemoryStream(Byte[], int, int) | argument 0 -> return (normal) | false | +| System.IO.MemoryStream.MemoryStream(Byte[], int, int, bool) | argument 0 -> return (normal) | false | +| System.IO.MemoryStream.MemoryStream(Byte[], int, int, bool, bool) | argument 0 -> return (normal) | false | +| System.IO.MemoryStream.Read(Byte[], int, int) | argument -1 -> return (out parameter 0) | false | +| System.IO.MemoryStream.ReadAsync(Byte[], int, int, CancellationToken) | argument -1 -> return (out parameter 0) | false | +| System.IO.MemoryStream.ToArray() | argument -1 -> return (normal) | false | +| System.IO.MemoryStream.Write(Byte[], int, int) | argument 0 -> argument -1 | false | +| System.IO.MemoryStream.WriteAsync(Byte[], int, int, CancellationToken) | argument 0 -> argument -1 | false | +| System.IO.Path.Combine(params String[]) | element of argument 0 -> return (normal) | false | +| System.IO.Path.Combine(string, string) | argument 0 -> return (normal) | false | +| System.IO.Path.Combine(string, string) | argument 1 -> return (normal) | false | +| System.IO.Path.Combine(string, string, string) | argument 0 -> return (normal) | false | +| System.IO.Path.Combine(string, string, string) | argument 1 -> return (normal) | false | +| System.IO.Path.Combine(string, string, string) | argument 2 -> return (normal) | false | +| System.IO.Path.Combine(string, string, string, string) | argument 0 -> return (normal) | false | +| System.IO.Path.Combine(string, string, string, string) | argument 1 -> return (normal) | false | +| System.IO.Path.Combine(string, string, string, string) | argument 2 -> return (normal) | false | +| System.IO.Path.Combine(string, string, string, string) | argument 3 -> return (normal) | false | +| System.IO.Path.GetDirectoryName(ReadOnlySpan) | argument 0 -> return (normal) | false | +| System.IO.Path.GetDirectoryName(string) | argument 0 -> return (normal) | false | +| System.IO.Path.GetExtension(ReadOnlySpan) | argument 0 -> return (normal) | false | +| System.IO.Path.GetExtension(string) | argument 0 -> return (normal) | false | +| System.IO.Path.GetFileName(ReadOnlySpan) | argument 0 -> return (normal) | false | +| System.IO.Path.GetFileName(string) | argument 0 -> return (normal) | false | +| System.IO.Path.GetFileNameWithoutExtension(ReadOnlySpan) | argument 0 -> return (normal) | false | +| System.IO.Path.GetFileNameWithoutExtension(string) | argument 0 -> return (normal) | false | +| System.IO.Path.GetFullPath(string) | argument 0 -> return (normal) | false | +| System.IO.Path.GetFullPath(string, string) | argument 0 -> return (normal) | false | +| System.IO.Path.GetPathRoot(ReadOnlySpan) | argument 0 -> return (normal) | false | +| System.IO.Path.GetPathRoot(string) | argument 0 -> return (normal) | false | +| System.IO.Path.GetRelativePath(string, string) | argument 1 -> return (normal) | false | +| System.IO.Pipes.PipeStream.BeginRead(Byte[], int, int, AsyncCallback, object) | argument -1 -> return (out parameter 0) | false | +| System.IO.Pipes.PipeStream.BeginWrite(Byte[], int, int, AsyncCallback, object) | argument 0 -> argument -1 | false | +| System.IO.Pipes.PipeStream.Read(Byte[], int, int) | argument -1 -> return (out parameter 0) | false | +| System.IO.Pipes.PipeStream.ReadAsync(Byte[], int, int, CancellationToken) | argument -1 -> return (out parameter 0) | false | +| System.IO.Pipes.PipeStream.Write(Byte[], int, int) | argument 0 -> argument -1 | false | +| System.IO.Pipes.PipeStream.WriteAsync(Byte[], int, int, CancellationToken) | argument 0 -> argument -1 | false | +| System.IO.Stream.BeginRead(Byte[], int, int, AsyncCallback, object) | argument -1 -> return (out parameter 0) | false | +| System.IO.Stream.BeginWrite(Byte[], int, int, AsyncCallback, object) | argument 0 -> argument -1 | false | +| System.IO.Stream.CopyTo(Stream) | argument -1 -> return (out parameter 0) | false | +| System.IO.Stream.CopyTo(Stream, int) | argument -1 -> return (out parameter 0) | false | +| System.IO.Stream.CopyToAsync(Stream) | argument -1 -> return (out parameter 0) | false | +| System.IO.Stream.CopyToAsync(Stream, CancellationToken) | argument -1 -> return (out parameter 0) | false | +| System.IO.Stream.CopyToAsync(Stream, int) | argument -1 -> return (out parameter 0) | false | +| System.IO.Stream.CopyToAsync(Stream, int, CancellationToken) | argument -1 -> return (out parameter 0) | false | +| System.IO.Stream.NullStream.BeginRead(Byte[], int, int, AsyncCallback, object) | argument -1 -> return (out parameter 0) | false | +| System.IO.Stream.NullStream.BeginWrite(Byte[], int, int, AsyncCallback, object) | argument 0 -> argument -1 | false | +| System.IO.Stream.NullStream.CopyTo(Stream, int) | argument -1 -> return (out parameter 0) | false | +| System.IO.Stream.NullStream.CopyToAsync(Stream, int, CancellationToken) | argument -1 -> return (out parameter 0) | false | +| System.IO.Stream.NullStream.Read(Byte[], int, int) | argument -1 -> return (out parameter 0) | false | +| System.IO.Stream.NullStream.ReadAsync(Byte[], int, int, CancellationToken) | argument -1 -> return (out parameter 0) | false | +| System.IO.Stream.NullStream.Write(Byte[], int, int) | argument 0 -> argument -1 | false | +| System.IO.Stream.NullStream.WriteAsync(Byte[], int, int, CancellationToken) | argument 0 -> argument -1 | false | +| System.IO.Stream.Read(Byte[], int, int) | argument -1 -> return (out parameter 0) | false | +| System.IO.Stream.ReadAsync(Byte[], int, int) | argument -1 -> return (out parameter 0) | false | +| System.IO.Stream.ReadAsync(Byte[], int, int, CancellationToken) | argument -1 -> return (out parameter 0) | false | +| System.IO.Stream.SyncStream.BeginRead(Byte[], int, int, AsyncCallback, object) | argument -1 -> return (out parameter 0) | false | +| System.IO.Stream.SyncStream.BeginWrite(Byte[], int, int, AsyncCallback, object) | argument 0 -> argument -1 | false | +| System.IO.Stream.SyncStream.Read(Byte[], int, int) | argument -1 -> return (out parameter 0) | false | +| System.IO.Stream.SyncStream.Write(Byte[], int, int) | argument 0 -> argument -1 | false | +| System.IO.Stream.Write(Byte[], int, int) | argument 0 -> argument -1 | false | +| System.IO.Stream.WriteAsync(Byte[], int, int) | argument 0 -> argument -1 | false | +| System.IO.Stream.WriteAsync(Byte[], int, int, CancellationToken) | argument 0 -> argument -1 | false | +| System.IO.StringReader.Read() | argument -1 -> return (normal) | false | +| System.IO.StringReader.Read(Char[], int, int) | argument -1 -> return (normal) | false | +| System.IO.StringReader.Read(Span) | argument -1 -> return (normal) | false | +| System.IO.StringReader.ReadAsync(Char[], int, int) | argument -1 -> return (normal) | false | +| System.IO.StringReader.ReadAsync(Memory, CancellationToken) | argument -1 -> return (normal) | false | +| System.IO.StringReader.ReadBlock(Span) | argument -1 -> return (normal) | false | +| System.IO.StringReader.ReadBlockAsync(Char[], int, int) | argument -1 -> return (normal) | false | +| System.IO.StringReader.ReadBlockAsync(Memory, CancellationToken) | argument -1 -> return (normal) | false | +| System.IO.StringReader.ReadLine() | argument -1 -> return (normal) | false | +| System.IO.StringReader.ReadLineAsync() | argument -1 -> return (normal) | false | +| System.IO.StringReader.ReadToEnd() | argument -1 -> return (normal) | false | +| System.IO.StringReader.ReadToEndAsync() | argument -1 -> return (normal) | false | +| System.IO.StringReader.StringReader(string) | argument 0 -> return (normal) | false | +| System.IO.TextReader.Read() | argument -1 -> return (normal) | false | +| System.IO.TextReader.Read(Char[], int, int) | argument -1 -> return (normal) | false | +| System.IO.TextReader.Read(Span) | argument -1 -> return (normal) | false | +| System.IO.TextReader.ReadAsync(Char[], int, int) | argument -1 -> return (normal) | false | +| System.IO.TextReader.ReadAsync(Memory, CancellationToken) | argument -1 -> return (normal) | false | +| System.IO.TextReader.ReadAsyncInternal(Memory, CancellationToken) | argument -1 -> return (normal) | false | +| System.IO.TextReader.ReadBlock(Char[], int, int) | argument -1 -> return (normal) | false | +| System.IO.TextReader.ReadBlock(Span) | argument -1 -> return (normal) | false | +| System.IO.TextReader.ReadBlockAsync(Char[], int, int) | argument -1 -> return (normal) | false | +| System.IO.TextReader.ReadBlockAsync(Memory, CancellationToken) | argument -1 -> return (normal) | false | +| System.IO.TextReader.ReadLine() | argument -1 -> return (normal) | false | +| System.IO.TextReader.ReadLineAsync() | argument -1 -> return (normal) | false | +| System.IO.TextReader.ReadToEnd() | argument -1 -> return (normal) | false | +| System.IO.TextReader.ReadToEndAsync() | argument -1 -> return (normal) | false | +| System.IO.UnmanagedMemoryStream.Read(Byte[], int, int) | argument -1 -> return (out parameter 0) | false | +| System.IO.UnmanagedMemoryStream.ReadAsync(Byte[], int, int, CancellationToken) | argument -1 -> return (out parameter 0) | false | +| System.IO.UnmanagedMemoryStream.Write(Byte[], int, int) | argument 0 -> argument -1 | false | +| System.IO.UnmanagedMemoryStream.WriteAsync(Byte[], int, int, CancellationToken) | argument 0 -> argument -1 | false | +| System.IO.UnmanagedMemoryStreamWrapper.CopyToAsync(Stream, int, CancellationToken) | argument -1 -> return (out parameter 0) | false | +| System.IO.UnmanagedMemoryStreamWrapper.Read(Byte[], int, int) | argument -1 -> return (out parameter 0) | false | +| System.IO.UnmanagedMemoryStreamWrapper.ReadAsync(Byte[], int, int, CancellationToken) | argument -1 -> return (out parameter 0) | false | +| System.IO.UnmanagedMemoryStreamWrapper.ToArray() | argument -1 -> return (normal) | false | +| System.IO.UnmanagedMemoryStreamWrapper.Write(Byte[], int, int) | argument 0 -> argument -1 | false | +| System.IO.UnmanagedMemoryStreamWrapper.WriteAsync(Byte[], int, int, CancellationToken) | argument 0 -> argument -1 | false | +| System.Int32.Parse(string) | argument 0 -> return (normal) | false | +| System.Int32.Parse(string, IFormatProvider) | argument 0 -> return (normal) | false | +| System.Int32.Parse(string, NumberStyles) | argument 0 -> return (normal) | false | +| System.Int32.Parse(string, NumberStyles, IFormatProvider) | argument 0 -> return (normal) | false | +| System.Int32.TryParse(string, NumberStyles, IFormatProvider, out int) | argument 0 -> return (normal) | false | +| System.Int32.TryParse(string, NumberStyles, IFormatProvider, out int) | argument 0 -> return (out parameter 3) | false | +| System.Int32.TryParse(string, out int) | argument 0 -> return (normal) | false | +| System.Int32.TryParse(string, out int) | argument 0 -> return (out parameter 1) | false | +| System.Lazy<>.Lazy(Func) | return (normal) of argument 0 -> property Value of return (normal) | true | +| System.Lazy<>.Lazy(Func, LazyThreadSafetyMode) | return (normal) of argument 0 -> property Value of return (normal) | true | +| System.Lazy<>.Lazy(Func, bool) | return (normal) of argument 0 -> property Value of return (normal) | true | +| System.Lazy<>.get_Value() | argument -1 -> return (normal) | false | +| System.Linq.EmptyPartition<>.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | +| System.Linq.Enumerable.d__64<>.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | +| System.Linq.Enumerable.d__81<>.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | +| System.Linq.Enumerable.d__98<,,,>.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | +| System.Linq.Enumerable.d__101<>.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | +| System.Linq.Enumerable.d__105<,,,>.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | +| System.Linq.Enumerable.d__62<>.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | +| System.Linq.Enumerable.d__174<,>.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | +| System.Linq.Enumerable.d__177<,>.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | +| System.Linq.Enumerable.d__179<,,>.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | +| System.Linq.Enumerable.d__181<,,>.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | +| System.Linq.Enumerable.d__194<>.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | +| System.Linq.Enumerable.d__190<>.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | +| System.Linq.Enumerable.d__192<>.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | +| System.Linq.Enumerable.d__221<>.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | +| System.Linq.Enumerable.d__217<>.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | +| System.Linq.Enumerable.d__219<>.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | +| System.Linq.Enumerable.d__240<>.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | +| System.Linq.Enumerable.d__243<,>.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | +| System.Linq.Enumerable.d__244<,,>.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | +| System.Linq.Enumerable.Aggregate(IEnumerable, TAccumulate, Func, Func) | argument 1 -> parameter 0 of argument 2 | true | +| System.Linq.Enumerable.Aggregate(IEnumerable, TAccumulate, Func, Func) | element of argument 0 -> parameter 1 of argument 2 | true | +| System.Linq.Enumerable.Aggregate(IEnumerable, TAccumulate, Func, Func) | return (normal) of argument 2 -> parameter 0 of argument 3 | true | +| System.Linq.Enumerable.Aggregate(IEnumerable, TAccumulate, Func, Func) | return (normal) of argument 3 -> return (normal) | true | +| System.Linq.Enumerable.Aggregate(IEnumerable, TAccumulate, Func) | argument 1 -> parameter 0 of argument 2 | true | +| System.Linq.Enumerable.Aggregate(IEnumerable, TAccumulate, Func) | element of argument 0 -> parameter 1 of argument 2 | true | +| System.Linq.Enumerable.Aggregate(IEnumerable, TAccumulate, Func) | return (normal) of argument 2 -> return (normal) | true | +| System.Linq.Enumerable.Aggregate(IEnumerable, Func) | element of argument 0 -> parameter 1 of argument 1 | true | +| System.Linq.Enumerable.Aggregate(IEnumerable, Func) | return (normal) of argument 1 -> return (normal) | true | +| System.Linq.Enumerable.All(IEnumerable, Func) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.Enumerable.Any(IEnumerable, Func) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.Enumerable.AsEnumerable(IEnumerable) | element of argument 0 -> element of return (normal) | true | +| System.Linq.Enumerable.Average(IEnumerable, Func) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.Enumerable.Average(IEnumerable, Func) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.Enumerable.Average(IEnumerable, Func) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.Enumerable.Average(IEnumerable, Func) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.Enumerable.Average(IEnumerable, Func>) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.Enumerable.Average(IEnumerable, Func>) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.Enumerable.Average(IEnumerable, Func>) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.Enumerable.Average(IEnumerable, Func>) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.Enumerable.Average(IEnumerable, Func>) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.Enumerable.Average(IEnumerable, Func) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.Enumerable.Cast(IEnumerable) | element of argument 0 -> element of return (normal) | true | +| System.Linq.Enumerable.Concat(IEnumerable, IEnumerable) | element of argument 0 -> element of return (normal) | true | +| System.Linq.Enumerable.Concat(IEnumerable, IEnumerable) | element of argument 1 -> element of return (normal) | true | +| System.Linq.Enumerable.Count(IEnumerable, Func) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.Enumerable.DefaultIfEmpty(IEnumerable) | element of argument 0 -> return (normal) | true | +| System.Linq.Enumerable.DefaultIfEmpty(IEnumerable, TSource) | argument 1 -> return (normal) | true | +| System.Linq.Enumerable.DefaultIfEmpty(IEnumerable, TSource) | element of argument 0 -> return (normal) | true | +| System.Linq.Enumerable.Distinct(IEnumerable) | element of argument 0 -> element of return (normal) | true | +| System.Linq.Enumerable.Distinct(IEnumerable, IEqualityComparer) | element of argument 0 -> element of return (normal) | true | +| System.Linq.Enumerable.ElementAt(IEnumerable, int) | element of argument 0 -> return (normal) | true | +| System.Linq.Enumerable.ElementAtOrDefault(IEnumerable, int) | element of argument 0 -> return (normal) | true | +| System.Linq.Enumerable.Except(IEnumerable, IEnumerable) | element of argument 0 -> return (normal) | true | +| System.Linq.Enumerable.Except(IEnumerable, IEnumerable, IEqualityComparer) | element of argument 0 -> return (normal) | true | +| System.Linq.Enumerable.First(IEnumerable) | element of argument 0 -> return (normal) | true | +| System.Linq.Enumerable.First(IEnumerable, Func) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.Enumerable.First(IEnumerable, Func) | element of argument 0 -> return (normal) | true | +| System.Linq.Enumerable.FirstOrDefault(IEnumerable) | element of argument 0 -> return (normal) | true | +| System.Linq.Enumerable.FirstOrDefault(IEnumerable, Func) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.Enumerable.FirstOrDefault(IEnumerable, Func) | element of argument 0 -> return (normal) | true | +| System.Linq.Enumerable.GroupBy(IEnumerable, Func, Func, Func, TResult>) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.Enumerable.GroupBy(IEnumerable, Func, Func, Func, TResult>) | element of argument 0 -> parameter 0 of argument 2 | true | +| System.Linq.Enumerable.GroupBy(IEnumerable, Func, Func, Func, TResult>) | return (normal) of argument 1 -> parameter 0 of argument 2 | true | +| System.Linq.Enumerable.GroupBy(IEnumerable, Func, Func, Func, TResult>) | return (normal) of argument 2 -> element of parameter 1 of argument 3 | true | +| System.Linq.Enumerable.GroupBy(IEnumerable, Func, Func, Func, TResult>) | return (normal) of argument 3 -> element of return (normal) | true | +| System.Linq.Enumerable.GroupBy(IEnumerable, Func, Func, Func, TResult>, IEqualityComparer) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.Enumerable.GroupBy(IEnumerable, Func, Func, Func, TResult>, IEqualityComparer) | element of argument 0 -> parameter 0 of argument 2 | true | +| System.Linq.Enumerable.GroupBy(IEnumerable, Func, Func, Func, TResult>, IEqualityComparer) | return (normal) of argument 1 -> parameter 0 of argument 2 | true | +| System.Linq.Enumerable.GroupBy(IEnumerable, Func, Func, Func, TResult>, IEqualityComparer) | return (normal) of argument 2 -> element of parameter 1 of argument 3 | true | +| System.Linq.Enumerable.GroupBy(IEnumerable, Func, Func, Func, TResult>, IEqualityComparer) | return (normal) of argument 3 -> element of return (normal) | true | +| System.Linq.Enumerable.GroupBy(IEnumerable, Func, Func) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.Enumerable.GroupBy(IEnumerable, Func, Func) | element of argument 0 -> parameter 0 of argument 2 | true | +| System.Linq.Enumerable.GroupBy(IEnumerable, Func, Func) | return (normal) of argument 2 -> element of return (normal) | true | +| System.Linq.Enumerable.GroupBy(IEnumerable, Func, Func, IEqualityComparer) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.Enumerable.GroupBy(IEnumerable, Func, Func, IEqualityComparer) | element of argument 0 -> parameter 0 of argument 2 | true | +| System.Linq.Enumerable.GroupBy(IEnumerable, Func, Func, IEqualityComparer) | return (normal) of argument 1 -> parameter 0 of argument 2 | true | +| System.Linq.Enumerable.GroupBy(IEnumerable, Func, Func, TResult>) | argument 0 -> parameter 1 of argument 2 | true | +| System.Linq.Enumerable.GroupBy(IEnumerable, Func, Func, TResult>) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.Enumerable.GroupBy(IEnumerable, Func, Func, TResult>) | return (normal) of argument 1 -> parameter 0 of argument 2 | true | +| System.Linq.Enumerable.GroupBy(IEnumerable, Func, Func, TResult>) | return (normal) of argument 2 -> element of return (normal) | true | +| System.Linq.Enumerable.GroupBy(IEnumerable, Func, Func, TResult>, IEqualityComparer) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.Enumerable.GroupBy(IEnumerable, Func, Func, TResult>, IEqualityComparer) | element of argument 0 -> parameter 0 of argument 2 | true | +| System.Linq.Enumerable.GroupBy(IEnumerable, Func, Func, TResult>, IEqualityComparer) | return (normal) of argument 1 -> parameter 0 of argument 2 | true | +| System.Linq.Enumerable.GroupBy(IEnumerable, Func) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.Enumerable.GroupBy(IEnumerable, Func, IEqualityComparer) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.Enumerable.GroupJoin(IEnumerable, IEnumerable, Func, Func, Func, TResult>) | element of argument 0 -> parameter 0 of argument 2 | true | +| System.Linq.Enumerable.GroupJoin(IEnumerable, IEnumerable, Func, Func, Func, TResult>) | element of argument 0 -> parameter 0 of argument 4 | true | +| System.Linq.Enumerable.GroupJoin(IEnumerable, IEnumerable, Func, Func, Func, TResult>) | element of argument 1 -> parameter 0 of argument 3 | true | +| System.Linq.Enumerable.GroupJoin(IEnumerable, IEnumerable, Func, Func, Func, TResult>) | element of argument 1 -> parameter 1 of argument 4 | true | +| System.Linq.Enumerable.GroupJoin(IEnumerable, IEnumerable, Func, Func, Func, TResult>) | return (normal) of argument 4 -> element of return (normal) | true | +| System.Linq.Enumerable.GroupJoin(IEnumerable, IEnumerable, Func, Func, Func, TResult>, IEqualityComparer) | element of argument 0 -> parameter 0 of argument 2 | true | +| System.Linq.Enumerable.GroupJoin(IEnumerable, IEnumerable, Func, Func, Func, TResult>, IEqualityComparer) | element of argument 0 -> parameter 0 of argument 4 | true | +| System.Linq.Enumerable.GroupJoin(IEnumerable, IEnumerable, Func, Func, Func, TResult>, IEqualityComparer) | element of argument 1 -> parameter 0 of argument 3 | true | +| System.Linq.Enumerable.GroupJoin(IEnumerable, IEnumerable, Func, Func, Func, TResult>, IEqualityComparer) | element of argument 1 -> parameter 1 of argument 4 | true | +| System.Linq.Enumerable.GroupJoin(IEnumerable, IEnumerable, Func, Func, Func, TResult>, IEqualityComparer) | return (normal) of argument 4 -> element of return (normal) | true | +| System.Linq.Enumerable.Intersect(IEnumerable, IEnumerable) | element of argument 0 -> element of return (normal) | true | +| System.Linq.Enumerable.Intersect(IEnumerable, IEnumerable) | element of argument 1 -> element of return (normal) | true | +| System.Linq.Enumerable.Intersect(IEnumerable, IEnumerable, IEqualityComparer) | element of argument 0 -> element of return (normal) | true | +| System.Linq.Enumerable.Intersect(IEnumerable, IEnumerable, IEqualityComparer) | element of argument 1 -> element of return (normal) | true | +| System.Linq.Enumerable.Iterator<>.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | +| System.Linq.Enumerable.Join(IEnumerable, IEnumerable, Func, Func, Func) | element of argument 0 -> parameter 0 of argument 2 | true | +| System.Linq.Enumerable.Join(IEnumerable, IEnumerable, Func, Func, Func) | element of argument 0 -> parameter 0 of argument 4 | true | +| System.Linq.Enumerable.Join(IEnumerable, IEnumerable, Func, Func, Func) | element of argument 1 -> parameter 0 of argument 3 | true | +| System.Linq.Enumerable.Join(IEnumerable, IEnumerable, Func, Func, Func) | element of argument 1 -> parameter 1 of argument 4 | true | +| System.Linq.Enumerable.Join(IEnumerable, IEnumerable, Func, Func, Func) | return (normal) of argument 4 -> element of return (normal) | true | +| System.Linq.Enumerable.Join(IEnumerable, IEnumerable, Func, Func, Func, IEqualityComparer) | element of argument 0 -> parameter 0 of argument 2 | true | +| System.Linq.Enumerable.Join(IEnumerable, IEnumerable, Func, Func, Func, IEqualityComparer) | element of argument 0 -> parameter 0 of argument 4 | true | +| System.Linq.Enumerable.Join(IEnumerable, IEnumerable, Func, Func, Func, IEqualityComparer) | element of argument 1 -> parameter 0 of argument 3 | true | +| System.Linq.Enumerable.Join(IEnumerable, IEnumerable, Func, Func, Func, IEqualityComparer) | element of argument 1 -> parameter 1 of argument 4 | true | +| System.Linq.Enumerable.Join(IEnumerable, IEnumerable, Func, Func, Func, IEqualityComparer) | return (normal) of argument 4 -> element of return (normal) | true | +| System.Linq.Enumerable.Last(IEnumerable) | element of argument 0 -> return (normal) | true | +| System.Linq.Enumerable.Last(IEnumerable, Func) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.Enumerable.Last(IEnumerable, Func) | element of argument 0 -> return (normal) | true | +| System.Linq.Enumerable.LastOrDefault(IEnumerable) | element of argument 0 -> return (normal) | true | +| System.Linq.Enumerable.LastOrDefault(IEnumerable, Func) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.Enumerable.LastOrDefault(IEnumerable, Func) | element of argument 0 -> return (normal) | true | +| System.Linq.Enumerable.LongCount(IEnumerable, Func) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.Enumerable.Max(IEnumerable, Func) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.Enumerable.Max(IEnumerable, Func) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.Enumerable.Max(IEnumerable, Func) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.Enumerable.Max(IEnumerable, Func) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.Enumerable.Max(IEnumerable, Func) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.Enumerable.Max(IEnumerable, Func>) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.Enumerable.Max(IEnumerable, Func>) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.Enumerable.Max(IEnumerable, Func>) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.Enumerable.Max(IEnumerable, Func>) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.Enumerable.Max(IEnumerable, Func>) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.Enumerable.Max(IEnumerable, Func) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.Enumerable.Min(IEnumerable, Func) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.Enumerable.Min(IEnumerable, Func) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.Enumerable.Min(IEnumerable, Func) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.Enumerable.Min(IEnumerable, Func) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.Enumerable.Min(IEnumerable, Func) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.Enumerable.Min(IEnumerable, Func>) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.Enumerable.Min(IEnumerable, Func>) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.Enumerable.Min(IEnumerable, Func>) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.Enumerable.Min(IEnumerable, Func>) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.Enumerable.Min(IEnumerable, Func>) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.Enumerable.Min(IEnumerable, Func) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.Enumerable.OfType(IEnumerable) | element of argument 0 -> element of return (normal) | true | +| System.Linq.Enumerable.OrderBy(IEnumerable, Func) | element of argument 0 -> element of return (normal) | true | +| System.Linq.Enumerable.OrderBy(IEnumerable, Func) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.Enumerable.OrderBy(IEnumerable, Func, IComparer) | element of argument 0 -> element of return (normal) | true | +| System.Linq.Enumerable.OrderBy(IEnumerable, Func, IComparer) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.Enumerable.OrderByDescending(IEnumerable, Func) | element of argument 0 -> element of return (normal) | true | +| System.Linq.Enumerable.OrderByDescending(IEnumerable, Func) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.Enumerable.OrderByDescending(IEnumerable, Func, IComparer) | element of argument 0 -> element of return (normal) | true | +| System.Linq.Enumerable.OrderByDescending(IEnumerable, Func, IComparer) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.Enumerable.Reverse(IEnumerable) | element of argument 0 -> element of return (normal) | true | +| System.Linq.Enumerable.Select(IEnumerable, Func) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.Enumerable.Select(IEnumerable, Func) | return (normal) of argument 1 -> element of return (normal) | true | +| System.Linq.Enumerable.Select(IEnumerable, Func) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.Enumerable.Select(IEnumerable, Func) | return (normal) of argument 1 -> element of return (normal) | true | +| System.Linq.Enumerable.SelectMany(IEnumerable, Func>, Func) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.Enumerable.SelectMany(IEnumerable, Func>, Func) | element of argument 0 -> parameter 0 of argument 2 | true | +| System.Linq.Enumerable.SelectMany(IEnumerable, Func>, Func) | element of return (normal) of argument 1 -> parameter 1 of argument 2 | true | +| System.Linq.Enumerable.SelectMany(IEnumerable, Func>, Func) | return (normal) of argument 2 -> element of return (normal) | true | +| System.Linq.Enumerable.SelectMany(IEnumerable, Func>, Func) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.Enumerable.SelectMany(IEnumerable, Func>, Func) | element of argument 0 -> parameter 0 of argument 2 | true | +| System.Linq.Enumerable.SelectMany(IEnumerable, Func>, Func) | element of return (normal) of argument 1 -> parameter 1 of argument 2 | true | +| System.Linq.Enumerable.SelectMany(IEnumerable, Func>, Func) | return (normal) of argument 2 -> element of return (normal) | true | +| System.Linq.Enumerable.SelectMany(IEnumerable, Func>) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.Enumerable.SelectMany(IEnumerable, Func>) | return (normal) of argument 1 -> element of return (normal) | true | +| System.Linq.Enumerable.SelectMany(IEnumerable, Func>) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.Enumerable.SelectMany(IEnumerable, Func>) | return (normal) of argument 1 -> element of return (normal) | true | +| System.Linq.Enumerable.Single(IEnumerable) | element of argument 0 -> return (normal) | true | +| System.Linq.Enumerable.Single(IEnumerable, Func) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.Enumerable.Single(IEnumerable, Func) | element of argument 0 -> return (normal) | true | +| System.Linq.Enumerable.SingleOrDefault(IEnumerable) | element of argument 0 -> return (normal) | true | +| System.Linq.Enumerable.SingleOrDefault(IEnumerable, Func) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.Enumerable.SingleOrDefault(IEnumerable, Func) | element of argument 0 -> return (normal) | true | +| System.Linq.Enumerable.Skip(IEnumerable, int) | element of argument 0 -> element of return (normal) | true | +| System.Linq.Enumerable.SkipWhile(IEnumerable, Func) | element of argument 0 -> element of return (normal) | true | +| System.Linq.Enumerable.SkipWhile(IEnumerable, Func) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.Enumerable.SkipWhile(IEnumerable, Func) | element of argument 0 -> element of return (normal) | true | +| System.Linq.Enumerable.SkipWhile(IEnumerable, Func) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.Enumerable.Sum(IEnumerable, Func) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.Enumerable.Sum(IEnumerable, Func) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.Enumerable.Sum(IEnumerable, Func) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.Enumerable.Sum(IEnumerable, Func) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.Enumerable.Sum(IEnumerable, Func>) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.Enumerable.Sum(IEnumerable, Func>) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.Enumerable.Sum(IEnumerable, Func>) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.Enumerable.Sum(IEnumerable, Func>) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.Enumerable.Sum(IEnumerable, Func>) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.Enumerable.Sum(IEnumerable, Func) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.Enumerable.Take(IEnumerable, int) | element of argument 0 -> element of return (normal) | true | +| System.Linq.Enumerable.TakeWhile(IEnumerable, Func) | element of argument 0 -> element of return (normal) | true | +| System.Linq.Enumerable.TakeWhile(IEnumerable, Func) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.Enumerable.TakeWhile(IEnumerable, Func) | element of argument 0 -> element of return (normal) | true | +| System.Linq.Enumerable.TakeWhile(IEnumerable, Func) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.Enumerable.ThenBy(IOrderedEnumerable, Func) | element of argument 0 -> element of return (normal) | true | +| System.Linq.Enumerable.ThenBy(IOrderedEnumerable, Func) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.Enumerable.ThenBy(IOrderedEnumerable, Func, IComparer) | element of argument 0 -> element of return (normal) | true | +| System.Linq.Enumerable.ThenBy(IOrderedEnumerable, Func, IComparer) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.Enumerable.ThenByDescending(IOrderedEnumerable, Func) | element of argument 0 -> element of return (normal) | true | +| System.Linq.Enumerable.ThenByDescending(IOrderedEnumerable, Func) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.Enumerable.ThenByDescending(IOrderedEnumerable, Func, IComparer) | element of argument 0 -> element of return (normal) | true | +| System.Linq.Enumerable.ThenByDescending(IOrderedEnumerable, Func, IComparer) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.Enumerable.ToArray(IEnumerable) | element of argument 0 -> element of return (normal) | true | +| System.Linq.Enumerable.ToDictionary(IEnumerable, Func, Func) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.Enumerable.ToDictionary(IEnumerable, Func, Func) | element of argument 0 -> parameter 0 of argument 2 | true | +| System.Linq.Enumerable.ToDictionary(IEnumerable, Func, Func) | return (normal) of argument 2 -> element of return (normal) | true | +| System.Linq.Enumerable.ToDictionary(IEnumerable, Func, Func, IEqualityComparer) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.Enumerable.ToDictionary(IEnumerable, Func, Func, IEqualityComparer) | element of argument 0 -> parameter 0 of argument 2 | true | +| System.Linq.Enumerable.ToDictionary(IEnumerable, Func, Func, IEqualityComparer) | return (normal) of argument 2 -> element of return (normal) | true | +| System.Linq.Enumerable.ToDictionary(IEnumerable, Func) | element of argument 0 -> element of return (normal) | true | +| System.Linq.Enumerable.ToDictionary(IEnumerable, Func) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.Enumerable.ToDictionary(IEnumerable, Func, IEqualityComparer) | element of argument 0 -> element of return (normal) | true | +| System.Linq.Enumerable.ToDictionary(IEnumerable, Func, IEqualityComparer) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.Enumerable.ToList(IEnumerable) | element of argument 0 -> element of return (normal) | true | +| System.Linq.Enumerable.ToLookup(IEnumerable, Func, Func) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.Enumerable.ToLookup(IEnumerable, Func, Func) | element of argument 0 -> parameter 0 of argument 2 | true | +| System.Linq.Enumerable.ToLookup(IEnumerable, Func, Func) | return (normal) of argument 2 -> element of return (normal) | true | +| System.Linq.Enumerable.ToLookup(IEnumerable, Func, Func, IEqualityComparer) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.Enumerable.ToLookup(IEnumerable, Func, Func, IEqualityComparer) | element of argument 0 -> parameter 0 of argument 2 | true | +| System.Linq.Enumerable.ToLookup(IEnumerable, Func, Func, IEqualityComparer) | return (normal) of argument 2 -> element of return (normal) | true | +| System.Linq.Enumerable.ToLookup(IEnumerable, Func) | element of argument 0 -> element of return (normal) | true | +| System.Linq.Enumerable.ToLookup(IEnumerable, Func) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.Enumerable.ToLookup(IEnumerable, Func, IEqualityComparer) | element of argument 0 -> element of return (normal) | true | +| System.Linq.Enumerable.ToLookup(IEnumerable, Func, IEqualityComparer) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.Enumerable.Union(IEnumerable, IEnumerable) | element of argument 0 -> element of return (normal) | true | +| System.Linq.Enumerable.Union(IEnumerable, IEnumerable) | element of argument 1 -> element of return (normal) | true | +| System.Linq.Enumerable.Union(IEnumerable, IEnumerable, IEqualityComparer) | element of argument 0 -> element of return (normal) | true | +| System.Linq.Enumerable.Union(IEnumerable, IEnumerable, IEqualityComparer) | element of argument 1 -> element of return (normal) | true | +| System.Linq.Enumerable.Where(IEnumerable, Func) | element of argument 0 -> element of return (normal) | true | +| System.Linq.Enumerable.Where(IEnumerable, Func) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.Enumerable.Where(IEnumerable, Func) | element of argument 0 -> element of return (normal) | true | +| System.Linq.Enumerable.Where(IEnumerable, Func) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.Enumerable.Zip(IEnumerable, IEnumerable, Func) | element of argument 0 -> parameter 0 of argument 2 | true | +| System.Linq.Enumerable.Zip(IEnumerable, IEnumerable, Func) | element of argument 1 -> parameter 1 of argument 2 | true | +| System.Linq.Enumerable.Zip(IEnumerable, IEnumerable, Func) | return (normal) of argument 2 -> element of return (normal) | true | +| System.Linq.EnumerableQuery<>.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | +| System.Linq.Expressions.BlockExpressionList.Add(Expression) | argument 0 -> element of argument -1 | true | +| System.Linq.Expressions.BlockExpressionList.CopyTo(Expression[], int) | element of argument -1 -> element of return (out parameter 0) | true | +| System.Linq.Expressions.BlockExpressionList.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | +| System.Linq.Expressions.BlockExpressionList.Insert(int, Expression) | argument 1 -> element of argument -1 | true | +| System.Linq.Expressions.BlockExpressionList.get_Item(int) | element of argument -1 -> return (normal) | true | +| System.Linq.Expressions.BlockExpressionList.set_Item(int, Expression) | argument 1 -> element of argument -1 | true | +| System.Linq.Expressions.Compiler.CompilerScope.d__32.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | +| System.Linq.Expressions.Compiler.ParameterList.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | +| System.Linq.Expressions.Interpreter.InterpretedFrame.d__29.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | +| System.Linq.GroupedEnumerable<,,>.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | +| System.Linq.GroupedEnumerable<,>.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | +| System.Linq.GroupedResultEnumerable<,,,>.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | +| System.Linq.GroupedResultEnumerable<,,>.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | +| System.Linq.Grouping<,>.Add(TElement) | argument 0 -> element of argument -1 | true | +| System.Linq.Grouping<,>.CopyTo(TElement[], int) | element of argument -1 -> element of return (out parameter 0) | true | +| System.Linq.Grouping<,>.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | +| System.Linq.Grouping<,>.Insert(int, TElement) | argument 1 -> element of argument -1 | true | +| System.Linq.Grouping<,>.get_Item(int) | element of argument -1 -> return (normal) | true | +| System.Linq.Grouping<,>.set_Item(int, TElement) | argument 1 -> element of argument -1 | true | +| System.Linq.Lookup<,>.d__19<>.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | +| System.Linq.Lookup<,>.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | +| System.Linq.OrderedEnumerable<>.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | +| System.Linq.OrderedPartition<>.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | +| System.Linq.Parallel.CancellableEnumerable.d__0<>.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | +| System.Linq.Parallel.EnumerableWrapperWeakToStrong.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | +| System.Linq.Parallel.ExceptionAggregator.d__0<>.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | +| System.Linq.Parallel.ExceptionAggregator.d__1<,>.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | +| System.Linq.Parallel.GroupByGrouping<,>.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | +| System.Linq.Parallel.ListChunk<>.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | +| System.Linq.Parallel.Lookup<,>.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | +| System.Linq.Parallel.MergeExecutor<>.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | +| System.Linq.Parallel.OrderedGroupByGrouping<,,>.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | +| System.Linq.Parallel.ParallelEnumerableWrapper.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | +| System.Linq.Parallel.PartitionerQueryOperator<>.d__5.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | +| System.Linq.Parallel.QueryResults<>.Add(T) | argument 0 -> element of argument -1 | true | +| System.Linq.Parallel.QueryResults<>.CopyTo(T[], int) | element of argument -1 -> element of return (out parameter 0) | true | +| System.Linq.Parallel.QueryResults<>.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | +| System.Linq.Parallel.QueryResults<>.Insert(int, T) | argument 1 -> element of argument -1 | true | +| System.Linq.Parallel.QueryResults<>.get_Item(int) | element of argument -1 -> return (normal) | true | +| System.Linq.Parallel.QueryResults<>.set_Item(int, T) | argument 1 -> element of argument -1 | true | +| System.Linq.Parallel.RangeEnumerable.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | +| System.Linq.Parallel.ZipQueryOperator<,,>.d__9.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | +| System.Linq.ParallelEnumerable.Aggregate(ParallelQuery, TAccumulate, Func, Func) | argument 1 -> parameter 0 of argument 2 | true | +| System.Linq.ParallelEnumerable.Aggregate(ParallelQuery, TAccumulate, Func, Func) | element of argument 0 -> parameter 1 of argument 2 | true | +| System.Linq.ParallelEnumerable.Aggregate(ParallelQuery, TAccumulate, Func, Func) | return (normal) of argument 2 -> parameter 0 of argument 3 | true | +| System.Linq.ParallelEnumerable.Aggregate(ParallelQuery, TAccumulate, Func, Func) | return (normal) of argument 3 -> return (normal) | true | +| System.Linq.ParallelEnumerable.Aggregate(ParallelQuery, TAccumulate, Func) | argument 1 -> parameter 0 of argument 2 | true | +| System.Linq.ParallelEnumerable.Aggregate(ParallelQuery, TAccumulate, Func) | element of argument 0 -> parameter 1 of argument 2 | true | +| System.Linq.ParallelEnumerable.Aggregate(ParallelQuery, TAccumulate, Func) | return (normal) of argument 2 -> return (normal) | true | +| System.Linq.ParallelEnumerable.Aggregate(ParallelQuery, Func) | element of argument 0 -> parameter 1 of argument 1 | true | +| System.Linq.ParallelEnumerable.Aggregate(ParallelQuery, Func) | return (normal) of argument 1 -> return (normal) | true | +| System.Linq.ParallelEnumerable.All(ParallelQuery, Func) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.ParallelEnumerable.Any(ParallelQuery, Func) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.ParallelEnumerable.AsEnumerable(ParallelQuery) | element of argument 0 -> element of return (normal) | true | +| System.Linq.ParallelEnumerable.Average(ParallelQuery, Func) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.ParallelEnumerable.Average(ParallelQuery, Func) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.ParallelEnumerable.Average(ParallelQuery, Func) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.ParallelEnumerable.Average(ParallelQuery, Func) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.ParallelEnumerable.Average(ParallelQuery, Func>) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.ParallelEnumerable.Average(ParallelQuery, Func>) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.ParallelEnumerable.Average(ParallelQuery, Func>) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.ParallelEnumerable.Average(ParallelQuery, Func>) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.ParallelEnumerable.Average(ParallelQuery, Func>) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.ParallelEnumerable.Average(ParallelQuery, Func) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.ParallelEnumerable.Cast(ParallelQuery) | element of argument 0 -> element of return (normal) | true | +| System.Linq.ParallelEnumerable.Concat(ParallelQuery, IEnumerable) | element of argument 0 -> element of return (normal) | true | +| System.Linq.ParallelEnumerable.Concat(ParallelQuery, IEnumerable) | element of argument 1 -> element of return (normal) | true | +| System.Linq.ParallelEnumerable.Concat(ParallelQuery, ParallelQuery) | element of argument 0 -> element of return (normal) | true | +| System.Linq.ParallelEnumerable.Concat(ParallelQuery, ParallelQuery) | element of argument 1 -> element of return (normal) | true | +| System.Linq.ParallelEnumerable.Count(ParallelQuery, Func) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.ParallelEnumerable.DefaultIfEmpty(ParallelQuery) | element of argument 0 -> return (normal) | true | +| System.Linq.ParallelEnumerable.DefaultIfEmpty(ParallelQuery, TSource) | argument 1 -> return (normal) | true | +| System.Linq.ParallelEnumerable.DefaultIfEmpty(ParallelQuery, TSource) | element of argument 0 -> return (normal) | true | +| System.Linq.ParallelEnumerable.Distinct(ParallelQuery) | element of argument 0 -> element of return (normal) | true | +| System.Linq.ParallelEnumerable.Distinct(ParallelQuery, IEqualityComparer) | element of argument 0 -> element of return (normal) | true | +| System.Linq.ParallelEnumerable.ElementAt(ParallelQuery, int) | element of argument 0 -> return (normal) | true | +| System.Linq.ParallelEnumerable.ElementAtOrDefault(ParallelQuery, int) | element of argument 0 -> return (normal) | true | +| System.Linq.ParallelEnumerable.Except(ParallelQuery, IEnumerable) | element of argument 0 -> return (normal) | true | +| System.Linq.ParallelEnumerable.Except(ParallelQuery, IEnumerable, IEqualityComparer) | element of argument 0 -> return (normal) | true | +| System.Linq.ParallelEnumerable.Except(ParallelQuery, ParallelQuery) | element of argument 0 -> return (normal) | true | +| System.Linq.ParallelEnumerable.Except(ParallelQuery, ParallelQuery, IEqualityComparer) | element of argument 0 -> return (normal) | true | +| System.Linq.ParallelEnumerable.First(ParallelQuery) | element of argument 0 -> return (normal) | true | +| System.Linq.ParallelEnumerable.First(ParallelQuery, Func) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.ParallelEnumerable.First(ParallelQuery, Func) | element of argument 0 -> return (normal) | true | +| System.Linq.ParallelEnumerable.FirstOrDefault(ParallelQuery) | element of argument 0 -> return (normal) | true | +| System.Linq.ParallelEnumerable.FirstOrDefault(ParallelQuery, Func) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.ParallelEnumerable.FirstOrDefault(ParallelQuery, Func) | element of argument 0 -> return (normal) | true | +| System.Linq.ParallelEnumerable.GroupBy(ParallelQuery, Func, Func, Func, TResult>) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.ParallelEnumerable.GroupBy(ParallelQuery, Func, Func, Func, TResult>) | element of argument 0 -> parameter 0 of argument 2 | true | +| System.Linq.ParallelEnumerable.GroupBy(ParallelQuery, Func, Func, Func, TResult>) | return (normal) of argument 1 -> parameter 0 of argument 2 | true | +| System.Linq.ParallelEnumerable.GroupBy(ParallelQuery, Func, Func, Func, TResult>) | return (normal) of argument 2 -> element of parameter 1 of argument 3 | true | +| System.Linq.ParallelEnumerable.GroupBy(ParallelQuery, Func, Func, Func, TResult>) | return (normal) of argument 3 -> element of return (normal) | true | +| System.Linq.ParallelEnumerable.GroupBy(ParallelQuery, Func, Func, Func, TResult>, IEqualityComparer) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.ParallelEnumerable.GroupBy(ParallelQuery, Func, Func, Func, TResult>, IEqualityComparer) | element of argument 0 -> parameter 0 of argument 2 | true | +| System.Linq.ParallelEnumerable.GroupBy(ParallelQuery, Func, Func, Func, TResult>, IEqualityComparer) | return (normal) of argument 1 -> parameter 0 of argument 2 | true | +| System.Linq.ParallelEnumerable.GroupBy(ParallelQuery, Func, Func, Func, TResult>, IEqualityComparer) | return (normal) of argument 2 -> element of parameter 1 of argument 3 | true | +| System.Linq.ParallelEnumerable.GroupBy(ParallelQuery, Func, Func, Func, TResult>, IEqualityComparer) | return (normal) of argument 3 -> element of return (normal) | true | +| System.Linq.ParallelEnumerable.GroupBy(ParallelQuery, Func, Func) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.ParallelEnumerable.GroupBy(ParallelQuery, Func, Func) | element of argument 0 -> parameter 0 of argument 2 | true | +| System.Linq.ParallelEnumerable.GroupBy(ParallelQuery, Func, Func) | return (normal) of argument 2 -> element of return (normal) | true | +| System.Linq.ParallelEnumerable.GroupBy(ParallelQuery, Func, Func, IEqualityComparer) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.ParallelEnumerable.GroupBy(ParallelQuery, Func, Func, IEqualityComparer) | element of argument 0 -> parameter 0 of argument 2 | true | +| System.Linq.ParallelEnumerable.GroupBy(ParallelQuery, Func, Func, IEqualityComparer) | return (normal) of argument 1 -> parameter 0 of argument 2 | true | +| System.Linq.ParallelEnumerable.GroupBy(ParallelQuery, Func, Func, TResult>) | argument 0 -> parameter 1 of argument 2 | true | +| System.Linq.ParallelEnumerable.GroupBy(ParallelQuery, Func, Func, TResult>) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.ParallelEnumerable.GroupBy(ParallelQuery, Func, Func, TResult>) | return (normal) of argument 1 -> parameter 0 of argument 2 | true | +| System.Linq.ParallelEnumerable.GroupBy(ParallelQuery, Func, Func, TResult>) | return (normal) of argument 2 -> element of return (normal) | true | +| System.Linq.ParallelEnumerable.GroupBy(ParallelQuery, Func, Func, TResult>, IEqualityComparer) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.ParallelEnumerable.GroupBy(ParallelQuery, Func, Func, TResult>, IEqualityComparer) | element of argument 0 -> parameter 0 of argument 2 | true | +| System.Linq.ParallelEnumerable.GroupBy(ParallelQuery, Func, Func, TResult>, IEqualityComparer) | return (normal) of argument 1 -> parameter 0 of argument 2 | true | +| System.Linq.ParallelEnumerable.GroupBy(ParallelQuery, Func) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.ParallelEnumerable.GroupBy(ParallelQuery, Func, IEqualityComparer) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.ParallelEnumerable.GroupJoin(ParallelQuery, IEnumerable, Func, Func, Func, TResult>) | element of argument 0 -> parameter 0 of argument 2 | true | +| System.Linq.ParallelEnumerable.GroupJoin(ParallelQuery, IEnumerable, Func, Func, Func, TResult>) | element of argument 0 -> parameter 0 of argument 4 | true | +| System.Linq.ParallelEnumerable.GroupJoin(ParallelQuery, IEnumerable, Func, Func, Func, TResult>) | element of argument 1 -> parameter 0 of argument 3 | true | +| System.Linq.ParallelEnumerable.GroupJoin(ParallelQuery, IEnumerable, Func, Func, Func, TResult>) | element of argument 1 -> parameter 1 of argument 4 | true | +| System.Linq.ParallelEnumerable.GroupJoin(ParallelQuery, IEnumerable, Func, Func, Func, TResult>) | return (normal) of argument 4 -> element of return (normal) | true | +| System.Linq.ParallelEnumerable.GroupJoin(ParallelQuery, IEnumerable, Func, Func, Func, TResult>, IEqualityComparer) | element of argument 0 -> parameter 0 of argument 2 | true | +| System.Linq.ParallelEnumerable.GroupJoin(ParallelQuery, IEnumerable, Func, Func, Func, TResult>, IEqualityComparer) | element of argument 0 -> parameter 0 of argument 4 | true | +| System.Linq.ParallelEnumerable.GroupJoin(ParallelQuery, IEnumerable, Func, Func, Func, TResult>, IEqualityComparer) | element of argument 1 -> parameter 0 of argument 3 | true | +| System.Linq.ParallelEnumerable.GroupJoin(ParallelQuery, IEnumerable, Func, Func, Func, TResult>, IEqualityComparer) | element of argument 1 -> parameter 1 of argument 4 | true | +| System.Linq.ParallelEnumerable.GroupJoin(ParallelQuery, IEnumerable, Func, Func, Func, TResult>, IEqualityComparer) | return (normal) of argument 4 -> element of return (normal) | true | +| System.Linq.ParallelEnumerable.GroupJoin(ParallelQuery, ParallelQuery, Func, Func, Func, TResult>) | element of argument 0 -> parameter 0 of argument 2 | true | +| System.Linq.ParallelEnumerable.GroupJoin(ParallelQuery, ParallelQuery, Func, Func, Func, TResult>) | element of argument 0 -> parameter 0 of argument 4 | true | +| System.Linq.ParallelEnumerable.GroupJoin(ParallelQuery, ParallelQuery, Func, Func, Func, TResult>) | element of argument 1 -> parameter 0 of argument 3 | true | +| System.Linq.ParallelEnumerable.GroupJoin(ParallelQuery, ParallelQuery, Func, Func, Func, TResult>) | element of argument 1 -> parameter 1 of argument 4 | true | +| System.Linq.ParallelEnumerable.GroupJoin(ParallelQuery, ParallelQuery, Func, Func, Func, TResult>) | return (normal) of argument 4 -> element of return (normal) | true | +| System.Linq.ParallelEnumerable.GroupJoin(ParallelQuery, ParallelQuery, Func, Func, Func, TResult>, IEqualityComparer) | element of argument 0 -> parameter 0 of argument 2 | true | +| System.Linq.ParallelEnumerable.GroupJoin(ParallelQuery, ParallelQuery, Func, Func, Func, TResult>, IEqualityComparer) | element of argument 0 -> parameter 0 of argument 4 | true | +| System.Linq.ParallelEnumerable.GroupJoin(ParallelQuery, ParallelQuery, Func, Func, Func, TResult>, IEqualityComparer) | element of argument 1 -> parameter 0 of argument 3 | true | +| System.Linq.ParallelEnumerable.GroupJoin(ParallelQuery, ParallelQuery, Func, Func, Func, TResult>, IEqualityComparer) | element of argument 1 -> parameter 1 of argument 4 | true | +| System.Linq.ParallelEnumerable.GroupJoin(ParallelQuery, ParallelQuery, Func, Func, Func, TResult>, IEqualityComparer) | return (normal) of argument 4 -> element of return (normal) | true | +| System.Linq.ParallelEnumerable.Intersect(ParallelQuery, IEnumerable) | element of argument 0 -> element of return (normal) | true | +| System.Linq.ParallelEnumerable.Intersect(ParallelQuery, IEnumerable) | element of argument 1 -> element of return (normal) | true | +| System.Linq.ParallelEnumerable.Intersect(ParallelQuery, IEnumerable, IEqualityComparer) | element of argument 0 -> element of return (normal) | true | +| System.Linq.ParallelEnumerable.Intersect(ParallelQuery, IEnumerable, IEqualityComparer) | element of argument 1 -> element of return (normal) | true | +| System.Linq.ParallelEnumerable.Intersect(ParallelQuery, ParallelQuery) | element of argument 0 -> element of return (normal) | true | +| System.Linq.ParallelEnumerable.Intersect(ParallelQuery, ParallelQuery) | element of argument 1 -> element of return (normal) | true | +| System.Linq.ParallelEnumerable.Intersect(ParallelQuery, ParallelQuery, IEqualityComparer) | element of argument 0 -> element of return (normal) | true | +| System.Linq.ParallelEnumerable.Intersect(ParallelQuery, ParallelQuery, IEqualityComparer) | element of argument 1 -> element of return (normal) | true | +| System.Linq.ParallelEnumerable.Join(ParallelQuery, IEnumerable, Func, Func, Func) | element of argument 0 -> parameter 0 of argument 2 | true | +| System.Linq.ParallelEnumerable.Join(ParallelQuery, IEnumerable, Func, Func, Func) | element of argument 0 -> parameter 0 of argument 4 | true | +| System.Linq.ParallelEnumerable.Join(ParallelQuery, IEnumerable, Func, Func, Func) | element of argument 1 -> parameter 0 of argument 3 | true | +| System.Linq.ParallelEnumerable.Join(ParallelQuery, IEnumerable, Func, Func, Func) | element of argument 1 -> parameter 1 of argument 4 | true | +| System.Linq.ParallelEnumerable.Join(ParallelQuery, IEnumerable, Func, Func, Func) | return (normal) of argument 4 -> element of return (normal) | true | +| System.Linq.ParallelEnumerable.Join(ParallelQuery, IEnumerable, Func, Func, Func, IEqualityComparer) | element of argument 0 -> parameter 0 of argument 2 | true | +| System.Linq.ParallelEnumerable.Join(ParallelQuery, IEnumerable, Func, Func, Func, IEqualityComparer) | element of argument 0 -> parameter 0 of argument 4 | true | +| System.Linq.ParallelEnumerable.Join(ParallelQuery, IEnumerable, Func, Func, Func, IEqualityComparer) | element of argument 1 -> parameter 0 of argument 3 | true | +| System.Linq.ParallelEnumerable.Join(ParallelQuery, IEnumerable, Func, Func, Func, IEqualityComparer) | element of argument 1 -> parameter 1 of argument 4 | true | +| System.Linq.ParallelEnumerable.Join(ParallelQuery, IEnumerable, Func, Func, Func, IEqualityComparer) | return (normal) of argument 4 -> element of return (normal) | true | +| System.Linq.ParallelEnumerable.Join(ParallelQuery, ParallelQuery, Func, Func, Func) | element of argument 0 -> parameter 0 of argument 2 | true | +| System.Linq.ParallelEnumerable.Join(ParallelQuery, ParallelQuery, Func, Func, Func) | element of argument 0 -> parameter 0 of argument 4 | true | +| System.Linq.ParallelEnumerable.Join(ParallelQuery, ParallelQuery, Func, Func, Func) | element of argument 1 -> parameter 0 of argument 3 | true | +| System.Linq.ParallelEnumerable.Join(ParallelQuery, ParallelQuery, Func, Func, Func) | element of argument 1 -> parameter 1 of argument 4 | true | +| System.Linq.ParallelEnumerable.Join(ParallelQuery, ParallelQuery, Func, Func, Func) | return (normal) of argument 4 -> element of return (normal) | true | +| System.Linq.ParallelEnumerable.Join(ParallelQuery, ParallelQuery, Func, Func, Func, IEqualityComparer) | element of argument 0 -> parameter 0 of argument 2 | true | +| System.Linq.ParallelEnumerable.Join(ParallelQuery, ParallelQuery, Func, Func, Func, IEqualityComparer) | element of argument 0 -> parameter 0 of argument 4 | true | +| System.Linq.ParallelEnumerable.Join(ParallelQuery, ParallelQuery, Func, Func, Func, IEqualityComparer) | element of argument 1 -> parameter 0 of argument 3 | true | +| System.Linq.ParallelEnumerable.Join(ParallelQuery, ParallelQuery, Func, Func, Func, IEqualityComparer) | element of argument 1 -> parameter 1 of argument 4 | true | +| System.Linq.ParallelEnumerable.Join(ParallelQuery, ParallelQuery, Func, Func, Func, IEqualityComparer) | return (normal) of argument 4 -> element of return (normal) | true | +| System.Linq.ParallelEnumerable.Last(ParallelQuery) | element of argument 0 -> return (normal) | true | +| System.Linq.ParallelEnumerable.Last(ParallelQuery, Func) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.ParallelEnumerable.Last(ParallelQuery, Func) | element of argument 0 -> return (normal) | true | +| System.Linq.ParallelEnumerable.LastOrDefault(ParallelQuery) | element of argument 0 -> return (normal) | true | +| System.Linq.ParallelEnumerable.LastOrDefault(ParallelQuery, Func) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.ParallelEnumerable.LastOrDefault(ParallelQuery, Func) | element of argument 0 -> return (normal) | true | +| System.Linq.ParallelEnumerable.LongCount(ParallelQuery, Func) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.ParallelEnumerable.Max(ParallelQuery, Func) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.ParallelEnumerable.Max(ParallelQuery, Func) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.ParallelEnumerable.Max(ParallelQuery, Func) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.ParallelEnumerable.Max(ParallelQuery, Func) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.ParallelEnumerable.Max(ParallelQuery, Func) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.ParallelEnumerable.Max(ParallelQuery, Func>) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.ParallelEnumerable.Max(ParallelQuery, Func>) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.ParallelEnumerable.Max(ParallelQuery, Func>) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.ParallelEnumerable.Max(ParallelQuery, Func>) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.ParallelEnumerable.Max(ParallelQuery, Func>) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.ParallelEnumerable.Max(ParallelQuery, Func) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.ParallelEnumerable.Min(ParallelQuery, Func) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.ParallelEnumerable.Min(ParallelQuery, Func) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.ParallelEnumerable.Min(ParallelQuery, Func) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.ParallelEnumerable.Min(ParallelQuery, Func) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.ParallelEnumerable.Min(ParallelQuery, Func) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.ParallelEnumerable.Min(ParallelQuery, Func>) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.ParallelEnumerable.Min(ParallelQuery, Func>) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.ParallelEnumerable.Min(ParallelQuery, Func>) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.ParallelEnumerable.Min(ParallelQuery, Func>) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.ParallelEnumerable.Min(ParallelQuery, Func>) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.ParallelEnumerable.Min(ParallelQuery, Func) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.ParallelEnumerable.OfType(ParallelQuery) | element of argument 0 -> element of return (normal) | true | +| System.Linq.ParallelEnumerable.OrderBy(ParallelQuery, Func) | element of argument 0 -> element of return (normal) | true | +| System.Linq.ParallelEnumerable.OrderBy(ParallelQuery, Func) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.ParallelEnumerable.OrderBy(ParallelQuery, Func, IComparer) | element of argument 0 -> element of return (normal) | true | +| System.Linq.ParallelEnumerable.OrderBy(ParallelQuery, Func, IComparer) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.ParallelEnumerable.OrderByDescending(ParallelQuery, Func) | element of argument 0 -> element of return (normal) | true | +| System.Linq.ParallelEnumerable.OrderByDescending(ParallelQuery, Func) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.ParallelEnumerable.OrderByDescending(ParallelQuery, Func, IComparer) | element of argument 0 -> element of return (normal) | true | +| System.Linq.ParallelEnumerable.OrderByDescending(ParallelQuery, Func, IComparer) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.ParallelEnumerable.Reverse(ParallelQuery) | element of argument 0 -> element of return (normal) | true | +| System.Linq.ParallelEnumerable.Select(ParallelQuery, Func) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.ParallelEnumerable.Select(ParallelQuery, Func) | return (normal) of argument 1 -> element of return (normal) | true | +| System.Linq.ParallelEnumerable.Select(ParallelQuery, Func) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.ParallelEnumerable.Select(ParallelQuery, Func) | return (normal) of argument 1 -> element of return (normal) | true | +| System.Linq.ParallelEnumerable.SelectMany(ParallelQuery, Func>, Func) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.ParallelEnumerable.SelectMany(ParallelQuery, Func>, Func) | element of argument 0 -> parameter 0 of argument 2 | true | +| System.Linq.ParallelEnumerable.SelectMany(ParallelQuery, Func>, Func) | element of return (normal) of argument 1 -> parameter 1 of argument 2 | true | +| System.Linq.ParallelEnumerable.SelectMany(ParallelQuery, Func>, Func) | return (normal) of argument 2 -> element of return (normal) | true | +| System.Linq.ParallelEnumerable.SelectMany(ParallelQuery, Func>, Func) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.ParallelEnumerable.SelectMany(ParallelQuery, Func>, Func) | element of argument 0 -> parameter 0 of argument 2 | true | +| System.Linq.ParallelEnumerable.SelectMany(ParallelQuery, Func>, Func) | element of return (normal) of argument 1 -> parameter 1 of argument 2 | true | +| System.Linq.ParallelEnumerable.SelectMany(ParallelQuery, Func>, Func) | return (normal) of argument 2 -> element of return (normal) | true | +| System.Linq.ParallelEnumerable.SelectMany(ParallelQuery, Func>) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.ParallelEnumerable.SelectMany(ParallelQuery, Func>) | return (normal) of argument 1 -> element of return (normal) | true | +| System.Linq.ParallelEnumerable.SelectMany(ParallelQuery, Func>) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.ParallelEnumerable.SelectMany(ParallelQuery, Func>) | return (normal) of argument 1 -> element of return (normal) | true | +| System.Linq.ParallelEnumerable.Single(ParallelQuery) | element of argument 0 -> return (normal) | true | +| System.Linq.ParallelEnumerable.Single(ParallelQuery, Func) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.ParallelEnumerable.Single(ParallelQuery, Func) | element of argument 0 -> return (normal) | true | +| System.Linq.ParallelEnumerable.SingleOrDefault(ParallelQuery) | element of argument 0 -> return (normal) | true | +| System.Linq.ParallelEnumerable.SingleOrDefault(ParallelQuery, Func) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.ParallelEnumerable.SingleOrDefault(ParallelQuery, Func) | element of argument 0 -> return (normal) | true | +| System.Linq.ParallelEnumerable.Skip(ParallelQuery, int) | element of argument 0 -> element of return (normal) | true | +| System.Linq.ParallelEnumerable.SkipWhile(ParallelQuery, Func) | element of argument 0 -> element of return (normal) | true | +| System.Linq.ParallelEnumerable.SkipWhile(ParallelQuery, Func) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.ParallelEnumerable.SkipWhile(ParallelQuery, Func) | element of argument 0 -> element of return (normal) | true | +| System.Linq.ParallelEnumerable.SkipWhile(ParallelQuery, Func) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.ParallelEnumerable.Sum(ParallelQuery, Func) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.ParallelEnumerable.Sum(ParallelQuery, Func) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.ParallelEnumerable.Sum(ParallelQuery, Func) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.ParallelEnumerable.Sum(ParallelQuery, Func) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.ParallelEnumerable.Sum(ParallelQuery, Func>) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.ParallelEnumerable.Sum(ParallelQuery, Func>) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.ParallelEnumerable.Sum(ParallelQuery, Func>) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.ParallelEnumerable.Sum(ParallelQuery, Func>) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.ParallelEnumerable.Sum(ParallelQuery, Func>) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.ParallelEnumerable.Sum(ParallelQuery, Func) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.ParallelEnumerable.Take(ParallelQuery, int) | element of argument 0 -> element of return (normal) | true | +| System.Linq.ParallelEnumerable.TakeWhile(ParallelQuery, Func) | element of argument 0 -> element of return (normal) | true | +| System.Linq.ParallelEnumerable.TakeWhile(ParallelQuery, Func) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.ParallelEnumerable.TakeWhile(ParallelQuery, Func) | element of argument 0 -> element of return (normal) | true | +| System.Linq.ParallelEnumerable.TakeWhile(ParallelQuery, Func) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.ParallelEnumerable.ThenBy(OrderedParallelQuery, Func) | element of argument 0 -> element of return (normal) | true | +| System.Linq.ParallelEnumerable.ThenBy(OrderedParallelQuery, Func) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.ParallelEnumerable.ThenBy(OrderedParallelQuery, Func, IComparer) | element of argument 0 -> element of return (normal) | true | +| System.Linq.ParallelEnumerable.ThenBy(OrderedParallelQuery, Func, IComparer) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.ParallelEnumerable.ThenByDescending(OrderedParallelQuery, Func) | element of argument 0 -> element of return (normal) | true | +| System.Linq.ParallelEnumerable.ThenByDescending(OrderedParallelQuery, Func) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.ParallelEnumerable.ThenByDescending(OrderedParallelQuery, Func, IComparer) | element of argument 0 -> element of return (normal) | true | +| System.Linq.ParallelEnumerable.ThenByDescending(OrderedParallelQuery, Func, IComparer) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.ParallelEnumerable.ToArray(ParallelQuery) | element of argument 0 -> element of return (normal) | true | +| System.Linq.ParallelEnumerable.ToDictionary(ParallelQuery, Func, Func) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.ParallelEnumerable.ToDictionary(ParallelQuery, Func, Func) | element of argument 0 -> parameter 0 of argument 2 | true | +| System.Linq.ParallelEnumerable.ToDictionary(ParallelQuery, Func, Func) | return (normal) of argument 2 -> element of return (normal) | true | +| System.Linq.ParallelEnumerable.ToDictionary(ParallelQuery, Func, Func, IEqualityComparer) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.ParallelEnumerable.ToDictionary(ParallelQuery, Func, Func, IEqualityComparer) | element of argument 0 -> parameter 0 of argument 2 | true | +| System.Linq.ParallelEnumerable.ToDictionary(ParallelQuery, Func, Func, IEqualityComparer) | return (normal) of argument 2 -> element of return (normal) | true | +| System.Linq.ParallelEnumerable.ToDictionary(ParallelQuery, Func) | element of argument 0 -> element of return (normal) | true | +| System.Linq.ParallelEnumerable.ToDictionary(ParallelQuery, Func) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.ParallelEnumerable.ToDictionary(ParallelQuery, Func, IEqualityComparer) | element of argument 0 -> element of return (normal) | true | +| System.Linq.ParallelEnumerable.ToDictionary(ParallelQuery, Func, IEqualityComparer) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.ParallelEnumerable.ToList(ParallelQuery) | element of argument 0 -> element of return (normal) | true | +| System.Linq.ParallelEnumerable.ToLookup(ParallelQuery, Func, Func) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.ParallelEnumerable.ToLookup(ParallelQuery, Func, Func) | element of argument 0 -> parameter 0 of argument 2 | true | +| System.Linq.ParallelEnumerable.ToLookup(ParallelQuery, Func, Func) | return (normal) of argument 2 -> element of return (normal) | true | +| System.Linq.ParallelEnumerable.ToLookup(ParallelQuery, Func, Func, IEqualityComparer) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.ParallelEnumerable.ToLookup(ParallelQuery, Func, Func, IEqualityComparer) | element of argument 0 -> parameter 0 of argument 2 | true | +| System.Linq.ParallelEnumerable.ToLookup(ParallelQuery, Func, Func, IEqualityComparer) | return (normal) of argument 2 -> element of return (normal) | true | +| System.Linq.ParallelEnumerable.ToLookup(ParallelQuery, Func) | element of argument 0 -> element of return (normal) | true | +| System.Linq.ParallelEnumerable.ToLookup(ParallelQuery, Func) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.ParallelEnumerable.ToLookup(ParallelQuery, Func, IEqualityComparer) | element of argument 0 -> element of return (normal) | true | +| System.Linq.ParallelEnumerable.ToLookup(ParallelQuery, Func, IEqualityComparer) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.ParallelEnumerable.Union(ParallelQuery, IEnumerable) | element of argument 0 -> element of return (normal) | true | +| System.Linq.ParallelEnumerable.Union(ParallelQuery, IEnumerable) | element of argument 1 -> element of return (normal) | true | +| System.Linq.ParallelEnumerable.Union(ParallelQuery, IEnumerable, IEqualityComparer) | element of argument 0 -> element of return (normal) | true | +| System.Linq.ParallelEnumerable.Union(ParallelQuery, IEnumerable, IEqualityComparer) | element of argument 1 -> element of return (normal) | true | +| System.Linq.ParallelEnumerable.Union(ParallelQuery, ParallelQuery) | element of argument 0 -> element of return (normal) | true | +| System.Linq.ParallelEnumerable.Union(ParallelQuery, ParallelQuery) | element of argument 1 -> element of return (normal) | true | +| System.Linq.ParallelEnumerable.Union(ParallelQuery, ParallelQuery, IEqualityComparer) | element of argument 0 -> element of return (normal) | true | +| System.Linq.ParallelEnumerable.Union(ParallelQuery, ParallelQuery, IEqualityComparer) | element of argument 1 -> element of return (normal) | true | +| System.Linq.ParallelEnumerable.Where(ParallelQuery, Func) | element of argument 0 -> element of return (normal) | true | +| System.Linq.ParallelEnumerable.Where(ParallelQuery, Func) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.ParallelEnumerable.Where(ParallelQuery, Func) | element of argument 0 -> element of return (normal) | true | +| System.Linq.ParallelEnumerable.Where(ParallelQuery, Func) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.ParallelEnumerable.Zip(ParallelQuery, IEnumerable, Func) | element of argument 0 -> parameter 0 of argument 2 | true | +| System.Linq.ParallelEnumerable.Zip(ParallelQuery, IEnumerable, Func) | element of argument 1 -> parameter 1 of argument 2 | true | +| System.Linq.ParallelEnumerable.Zip(ParallelQuery, IEnumerable, Func) | return (normal) of argument 2 -> element of return (normal) | true | +| System.Linq.ParallelEnumerable.Zip(ParallelQuery, ParallelQuery, Func) | element of argument 0 -> parameter 0 of argument 2 | true | +| System.Linq.ParallelEnumerable.Zip(ParallelQuery, ParallelQuery, Func) | element of argument 1 -> parameter 1 of argument 2 | true | +| System.Linq.ParallelEnumerable.Zip(ParallelQuery, ParallelQuery, Func) | return (normal) of argument 2 -> element of return (normal) | true | +| System.Linq.ParallelQuery.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | +| System.Linq.Queryable.Aggregate(IQueryable, TAccumulate, Expression>, Expression>) | argument 1 -> parameter 0 of argument 2 | true | +| System.Linq.Queryable.Aggregate(IQueryable, TAccumulate, Expression>, Expression>) | element of argument 0 -> parameter 1 of argument 2 | true | +| System.Linq.Queryable.Aggregate(IQueryable, TAccumulate, Expression>, Expression>) | return (normal) of argument 2 -> parameter 0 of argument 3 | true | +| System.Linq.Queryable.Aggregate(IQueryable, TAccumulate, Expression>, Expression>) | return (normal) of argument 3 -> return (normal) | true | +| System.Linq.Queryable.Aggregate(IQueryable, TAccumulate, Expression>) | argument 1 -> parameter 0 of argument 2 | true | +| System.Linq.Queryable.Aggregate(IQueryable, TAccumulate, Expression>) | element of argument 0 -> parameter 1 of argument 2 | true | +| System.Linq.Queryable.Aggregate(IQueryable, TAccumulate, Expression>) | return (normal) of argument 2 -> return (normal) | true | +| System.Linq.Queryable.Aggregate(IQueryable, Expression>) | element of argument 0 -> parameter 1 of argument 1 | true | +| System.Linq.Queryable.Aggregate(IQueryable, Expression>) | return (normal) of argument 1 -> return (normal) | true | +| System.Linq.Queryable.All(IQueryable, Expression>) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.Queryable.Any(IQueryable, Expression>) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.Queryable.AsQueryable(IEnumerable) | element of argument 0 -> element of return (normal) | true | +| System.Linq.Queryable.AsQueryable(IEnumerable) | element of argument 0 -> element of return (normal) | true | +| System.Linq.Queryable.Average(IQueryable, Expression>) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.Queryable.Average(IQueryable, Expression>) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.Queryable.Average(IQueryable, Expression>) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.Queryable.Average(IQueryable, Expression>) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.Queryable.Average(IQueryable, Expression>>) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.Queryable.Average(IQueryable, Expression>>) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.Queryable.Average(IQueryable, Expression>>) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.Queryable.Average(IQueryable, Expression>>) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.Queryable.Average(IQueryable, Expression>>) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.Queryable.Average(IQueryable, Expression>) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.Queryable.Cast(IQueryable) | element of argument 0 -> element of return (normal) | true | +| System.Linq.Queryable.Concat(IQueryable, IEnumerable) | element of argument 0 -> element of return (normal) | true | +| System.Linq.Queryable.Concat(IQueryable, IEnumerable) | element of argument 1 -> element of return (normal) | true | +| System.Linq.Queryable.Count(IQueryable, Expression>) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.Queryable.DefaultIfEmpty(IQueryable) | element of argument 0 -> return (normal) | true | +| System.Linq.Queryable.DefaultIfEmpty(IQueryable, TSource) | argument 1 -> return (normal) | true | +| System.Linq.Queryable.DefaultIfEmpty(IQueryable, TSource) | element of argument 0 -> return (normal) | true | +| System.Linq.Queryable.Distinct(IQueryable) | element of argument 0 -> element of return (normal) | true | +| System.Linq.Queryable.Distinct(IQueryable, IEqualityComparer) | element of argument 0 -> element of return (normal) | true | +| System.Linq.Queryable.ElementAt(IQueryable, int) | element of argument 0 -> return (normal) | true | +| System.Linq.Queryable.ElementAtOrDefault(IQueryable, int) | element of argument 0 -> return (normal) | true | +| System.Linq.Queryable.Except(IQueryable, IEnumerable) | element of argument 0 -> return (normal) | true | +| System.Linq.Queryable.Except(IQueryable, IEnumerable, IEqualityComparer) | element of argument 0 -> return (normal) | true | +| System.Linq.Queryable.First(IQueryable) | element of argument 0 -> return (normal) | true | +| System.Linq.Queryable.First(IQueryable, Expression>) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.Queryable.First(IQueryable, Expression>) | element of argument 0 -> return (normal) | true | +| System.Linq.Queryable.FirstOrDefault(IQueryable) | element of argument 0 -> return (normal) | true | +| System.Linq.Queryable.FirstOrDefault(IQueryable, Expression>) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.Queryable.FirstOrDefault(IQueryable, Expression>) | element of argument 0 -> return (normal) | true | +| System.Linq.Queryable.GroupBy(IQueryable, Expression>, Expression>, Expression,TResult>>) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.Queryable.GroupBy(IQueryable, Expression>, Expression>, Expression,TResult>>) | element of argument 0 -> parameter 0 of argument 2 | true | +| System.Linq.Queryable.GroupBy(IQueryable, Expression>, Expression>, Expression,TResult>>) | return (normal) of argument 1 -> parameter 0 of argument 2 | true | +| System.Linq.Queryable.GroupBy(IQueryable, Expression>, Expression>, Expression,TResult>>) | return (normal) of argument 2 -> element of parameter 1 of argument 3 | true | +| System.Linq.Queryable.GroupBy(IQueryable, Expression>, Expression>, Expression,TResult>>) | return (normal) of argument 3 -> element of return (normal) | true | +| System.Linq.Queryable.GroupBy(IQueryable, Expression>, Expression>, Expression,TResult>>, IEqualityComparer) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.Queryable.GroupBy(IQueryable, Expression>, Expression>, Expression,TResult>>, IEqualityComparer) | element of argument 0 -> parameter 0 of argument 2 | true | +| System.Linq.Queryable.GroupBy(IQueryable, Expression>, Expression>, Expression,TResult>>, IEqualityComparer) | return (normal) of argument 1 -> parameter 0 of argument 2 | true | +| System.Linq.Queryable.GroupBy(IQueryable, Expression>, Expression>, Expression,TResult>>, IEqualityComparer) | return (normal) of argument 2 -> element of parameter 1 of argument 3 | true | +| System.Linq.Queryable.GroupBy(IQueryable, Expression>, Expression>, Expression,TResult>>, IEqualityComparer) | return (normal) of argument 3 -> element of return (normal) | true | +| System.Linq.Queryable.GroupBy(IQueryable, Expression>, Expression>) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.Queryable.GroupBy(IQueryable, Expression>, Expression>) | return (normal) of argument 2 -> element of return (normal) | true | +| System.Linq.Queryable.GroupBy(IQueryable, Expression>, Expression>, IEqualityComparer) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.Queryable.GroupBy(IQueryable, Expression>, Expression>, IEqualityComparer) | element of argument 0 -> parameter 0 of argument 2 | true | +| System.Linq.Queryable.GroupBy(IQueryable, Expression>, Expression>, IEqualityComparer) | return (normal) of argument 1 -> parameter 0 of argument 2 | true | +| System.Linq.Queryable.GroupBy(IQueryable, Expression>, Expression,TResult>>) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.Queryable.GroupBy(IQueryable, Expression>, Expression,TResult>>) | return (normal) of argument 2 -> element of return (normal) | true | +| System.Linq.Queryable.GroupBy(IQueryable, Expression>, Expression,TResult>>, IEqualityComparer) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.Queryable.GroupBy(IQueryable, Expression>, Expression,TResult>>, IEqualityComparer) | element of argument 0 -> parameter 0 of argument 2 | true | +| System.Linq.Queryable.GroupBy(IQueryable, Expression>, Expression,TResult>>, IEqualityComparer) | return (normal) of argument 1 -> parameter 0 of argument 2 | true | +| System.Linq.Queryable.GroupBy(IQueryable, Expression>) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.Queryable.GroupBy(IQueryable, Expression>, IEqualityComparer) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.Queryable.GroupJoin(IQueryable, IEnumerable, Expression>, Expression>, Expression,TResult>>) | element of argument 0 -> parameter 0 of argument 2 | true | +| System.Linq.Queryable.GroupJoin(IQueryable, IEnumerable, Expression>, Expression>, Expression,TResult>>) | element of argument 0 -> parameter 0 of argument 4 | true | +| System.Linq.Queryable.GroupJoin(IQueryable, IEnumerable, Expression>, Expression>, Expression,TResult>>) | element of argument 1 -> parameter 0 of argument 3 | true | +| System.Linq.Queryable.GroupJoin(IQueryable, IEnumerable, Expression>, Expression>, Expression,TResult>>) | element of argument 1 -> parameter 1 of argument 4 | true | +| System.Linq.Queryable.GroupJoin(IQueryable, IEnumerable, Expression>, Expression>, Expression,TResult>>) | return (normal) of argument 4 -> element of return (normal) | true | +| System.Linq.Queryable.GroupJoin(IQueryable, IEnumerable, Expression>, Expression>, Expression,TResult>>, IEqualityComparer) | element of argument 0 -> parameter 0 of argument 2 | true | +| System.Linq.Queryable.GroupJoin(IQueryable, IEnumerable, Expression>, Expression>, Expression,TResult>>, IEqualityComparer) | element of argument 0 -> parameter 0 of argument 4 | true | +| System.Linq.Queryable.GroupJoin(IQueryable, IEnumerable, Expression>, Expression>, Expression,TResult>>, IEqualityComparer) | element of argument 1 -> parameter 0 of argument 3 | true | +| System.Linq.Queryable.GroupJoin(IQueryable, IEnumerable, Expression>, Expression>, Expression,TResult>>, IEqualityComparer) | element of argument 1 -> parameter 1 of argument 4 | true | +| System.Linq.Queryable.GroupJoin(IQueryable, IEnumerable, Expression>, Expression>, Expression,TResult>>, IEqualityComparer) | return (normal) of argument 4 -> element of return (normal) | true | +| System.Linq.Queryable.Intersect(IQueryable, IEnumerable) | element of argument 0 -> element of return (normal) | true | +| System.Linq.Queryable.Intersect(IQueryable, IEnumerable) | element of argument 1 -> element of return (normal) | true | +| System.Linq.Queryable.Intersect(IQueryable, IEnumerable, IEqualityComparer) | element of argument 0 -> element of return (normal) | true | +| System.Linq.Queryable.Intersect(IQueryable, IEnumerable, IEqualityComparer) | element of argument 1 -> element of return (normal) | true | +| System.Linq.Queryable.Join(IQueryable, IEnumerable, Expression>, Expression>, Expression>) | element of argument 0 -> parameter 0 of argument 2 | true | +| System.Linq.Queryable.Join(IQueryable, IEnumerable, Expression>, Expression>, Expression>) | element of argument 0 -> parameter 0 of argument 4 | true | +| System.Linq.Queryable.Join(IQueryable, IEnumerable, Expression>, Expression>, Expression>) | element of argument 1 -> parameter 0 of argument 3 | true | +| System.Linq.Queryable.Join(IQueryable, IEnumerable, Expression>, Expression>, Expression>) | element of argument 1 -> parameter 1 of argument 4 | true | +| System.Linq.Queryable.Join(IQueryable, IEnumerable, Expression>, Expression>, Expression>) | return (normal) of argument 4 -> element of return (normal) | true | +| System.Linq.Queryable.Join(IQueryable, IEnumerable, Expression>, Expression>, Expression>, IEqualityComparer) | element of argument 0 -> parameter 0 of argument 2 | true | +| System.Linq.Queryable.Join(IQueryable, IEnumerable, Expression>, Expression>, Expression>, IEqualityComparer) | element of argument 0 -> parameter 0 of argument 4 | true | +| System.Linq.Queryable.Join(IQueryable, IEnumerable, Expression>, Expression>, Expression>, IEqualityComparer) | element of argument 1 -> parameter 0 of argument 3 | true | +| System.Linq.Queryable.Join(IQueryable, IEnumerable, Expression>, Expression>, Expression>, IEqualityComparer) | element of argument 1 -> parameter 1 of argument 4 | true | +| System.Linq.Queryable.Join(IQueryable, IEnumerable, Expression>, Expression>, Expression>, IEqualityComparer) | return (normal) of argument 4 -> element of return (normal) | true | +| System.Linq.Queryable.Last(IQueryable) | element of argument 0 -> return (normal) | true | +| System.Linq.Queryable.Last(IQueryable, Expression>) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.Queryable.Last(IQueryable, Expression>) | element of argument 0 -> return (normal) | true | +| System.Linq.Queryable.LastOrDefault(IQueryable) | element of argument 0 -> return (normal) | true | +| System.Linq.Queryable.LastOrDefault(IQueryable, Expression>) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.Queryable.LastOrDefault(IQueryable, Expression>) | element of argument 0 -> return (normal) | true | +| System.Linq.Queryable.LongCount(IQueryable, Expression>) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.Queryable.Max(IQueryable, Expression>) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.Queryable.Min(IQueryable, Expression>) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.Queryable.OfType(IQueryable) | element of argument 0 -> element of return (normal) | true | +| System.Linq.Queryable.OrderBy(IQueryable, Expression>) | element of argument 0 -> element of return (normal) | true | +| System.Linq.Queryable.OrderBy(IQueryable, Expression>) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.Queryable.OrderBy(IQueryable, Expression>, IComparer) | element of argument 0 -> element of return (normal) | true | +| System.Linq.Queryable.OrderBy(IQueryable, Expression>, IComparer) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.Queryable.OrderByDescending(IQueryable, Expression>) | element of argument 0 -> element of return (normal) | true | +| System.Linq.Queryable.OrderByDescending(IQueryable, Expression>) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.Queryable.OrderByDescending(IQueryable, Expression>, IComparer) | element of argument 0 -> element of return (normal) | true | +| System.Linq.Queryable.OrderByDescending(IQueryable, Expression>, IComparer) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.Queryable.Reverse(IQueryable) | element of argument 0 -> element of return (normal) | true | +| System.Linq.Queryable.Select(IQueryable, Expression>) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.Queryable.Select(IQueryable, Expression>) | return (normal) of argument 1 -> element of return (normal) | true | +| System.Linq.Queryable.Select(IQueryable, Expression>) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.Queryable.Select(IQueryable, Expression>) | return (normal) of argument 1 -> element of return (normal) | true | +| System.Linq.Queryable.SelectMany(IQueryable, Expression>>, Expression>) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.Queryable.SelectMany(IQueryable, Expression>>, Expression>) | element of argument 0 -> parameter 0 of argument 2 | true | +| System.Linq.Queryable.SelectMany(IQueryable, Expression>>, Expression>) | element of return (normal) of argument 1 -> parameter 1 of argument 2 | true | +| System.Linq.Queryable.SelectMany(IQueryable, Expression>>, Expression>) | return (normal) of argument 2 -> element of return (normal) | true | +| System.Linq.Queryable.SelectMany(IQueryable, Expression>>, Expression>) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.Queryable.SelectMany(IQueryable, Expression>>, Expression>) | element of argument 0 -> parameter 0 of argument 2 | true | +| System.Linq.Queryable.SelectMany(IQueryable, Expression>>, Expression>) | element of return (normal) of argument 1 -> parameter 1 of argument 2 | true | +| System.Linq.Queryable.SelectMany(IQueryable, Expression>>, Expression>) | return (normal) of argument 2 -> element of return (normal) | true | +| System.Linq.Queryable.SelectMany(IQueryable, Expression>>) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.Queryable.SelectMany(IQueryable, Expression>>) | return (normal) of argument 1 -> element of return (normal) | true | +| System.Linq.Queryable.SelectMany(IQueryable, Expression>>) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.Queryable.SelectMany(IQueryable, Expression>>) | return (normal) of argument 1 -> element of return (normal) | true | +| System.Linq.Queryable.Single(IQueryable) | element of argument 0 -> return (normal) | true | +| System.Linq.Queryable.Single(IQueryable, Expression>) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.Queryable.Single(IQueryable, Expression>) | element of argument 0 -> return (normal) | true | +| System.Linq.Queryable.SingleOrDefault(IQueryable) | element of argument 0 -> return (normal) | true | +| System.Linq.Queryable.SingleOrDefault(IQueryable, Expression>) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.Queryable.SingleOrDefault(IQueryable, Expression>) | element of argument 0 -> return (normal) | true | +| System.Linq.Queryable.Skip(IQueryable, int) | element of argument 0 -> element of return (normal) | true | +| System.Linq.Queryable.SkipWhile(IQueryable, Expression>) | element of argument 0 -> element of return (normal) | true | +| System.Linq.Queryable.SkipWhile(IQueryable, Expression>) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.Queryable.SkipWhile(IQueryable, Expression>) | element of argument 0 -> element of return (normal) | true | +| System.Linq.Queryable.SkipWhile(IQueryable, Expression>) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.Queryable.Sum(IQueryable, Expression>) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.Queryable.Sum(IQueryable, Expression>) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.Queryable.Sum(IQueryable, Expression>) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.Queryable.Sum(IQueryable, Expression>) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.Queryable.Sum(IQueryable, Expression>>) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.Queryable.Sum(IQueryable, Expression>>) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.Queryable.Sum(IQueryable, Expression>>) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.Queryable.Sum(IQueryable, Expression>>) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.Queryable.Sum(IQueryable, Expression>>) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.Queryable.Sum(IQueryable, Expression>) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.Queryable.Take(IQueryable, int) | element of argument 0 -> element of return (normal) | true | +| System.Linq.Queryable.TakeWhile(IQueryable, Expression>) | element of argument 0 -> element of return (normal) | true | +| System.Linq.Queryable.TakeWhile(IQueryable, Expression>) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.Queryable.TakeWhile(IQueryable, Expression>) | element of argument 0 -> element of return (normal) | true | +| System.Linq.Queryable.TakeWhile(IQueryable, Expression>) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.Queryable.ThenBy(IOrderedQueryable, Expression>) | element of argument 0 -> element of return (normal) | true | +| System.Linq.Queryable.ThenBy(IOrderedQueryable, Expression>) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.Queryable.ThenBy(IOrderedQueryable, Expression>, IComparer) | element of argument 0 -> element of return (normal) | true | +| System.Linq.Queryable.ThenBy(IOrderedQueryable, Expression>, IComparer) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.Queryable.ThenByDescending(IOrderedQueryable, Expression>) | element of argument 0 -> element of return (normal) | true | +| System.Linq.Queryable.ThenByDescending(IOrderedQueryable, Expression>) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.Queryable.ThenByDescending(IOrderedQueryable, Expression>, IComparer) | element of argument 0 -> element of return (normal) | true | +| System.Linq.Queryable.ThenByDescending(IOrderedQueryable, Expression>, IComparer) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.Queryable.Union(IQueryable, IEnumerable) | element of argument 0 -> element of return (normal) | true | +| System.Linq.Queryable.Union(IQueryable, IEnumerable) | element of argument 1 -> element of return (normal) | true | +| System.Linq.Queryable.Union(IQueryable, IEnumerable, IEqualityComparer) | element of argument 0 -> element of return (normal) | true | +| System.Linq.Queryable.Union(IQueryable, IEnumerable, IEqualityComparer) | element of argument 1 -> element of return (normal) | true | +| System.Linq.Queryable.Where(IQueryable, Expression>) | element of argument 0 -> element of return (normal) | true | +| System.Linq.Queryable.Where(IQueryable, Expression>) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.Queryable.Where(IQueryable, Expression>) | element of argument 0 -> element of return (normal) | true | +| System.Linq.Queryable.Where(IQueryable, Expression>) | element of argument 0 -> parameter 0 of argument 1 | true | +| System.Linq.Queryable.Zip(IQueryable, IEnumerable, Expression>) | element of argument 0 -> parameter 0 of argument 2 | true | +| System.Linq.Queryable.Zip(IQueryable, IEnumerable, Expression>) | element of argument 1 -> parameter 1 of argument 2 | true | +| System.Linq.Queryable.Zip(IQueryable, IEnumerable, Expression>) | return (normal) of argument 2 -> element of return (normal) | true | +| System.Net.Cookie.get_Value() | argument -1 -> return (normal) | false | +| System.Net.CookieCollection.Add(Cookie) | argument 0 -> element of argument -1 | true | +| System.Net.CookieCollection.Add(CookieCollection) | argument 0 -> element of argument -1 | true | +| System.Net.CookieCollection.CopyTo(Array, int) | element of argument -1 -> element of return (out parameter 0) | true | +| System.Net.CookieCollection.CopyTo(Cookie[], int) | element of argument -1 -> element of return (out parameter 0) | true | +| System.Net.CookieCollection.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | +| System.Net.CredentialCache.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | +| System.Net.HttpListenerPrefixCollection.Add(string) | argument 0 -> element of argument -1 | true | +| System.Net.HttpListenerPrefixCollection.CopyTo(Array, int) | element of argument -1 -> element of return (out parameter 0) | true | +| System.Net.HttpListenerPrefixCollection.CopyTo(String[], int) | element of argument -1 -> element of return (out parameter 0) | true | +| System.Net.HttpListenerPrefixCollection.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | +| System.Net.HttpRequestStream.BeginRead(Byte[], int, int, AsyncCallback, object) | argument -1 -> return (out parameter 0) | false | +| System.Net.HttpRequestStream.BeginWrite(Byte[], int, int, AsyncCallback, object) | argument 0 -> argument -1 | false | +| System.Net.HttpRequestStream.Read(Byte[], int, int) | argument -1 -> return (out parameter 0) | false | +| System.Net.HttpRequestStream.Write(Byte[], int, int) | argument 0 -> argument -1 | false | +| System.Net.HttpResponseStream.BeginRead(Byte[], int, int, AsyncCallback, object) | argument -1 -> return (out parameter 0) | false | +| System.Net.HttpResponseStream.BeginWrite(Byte[], int, int, AsyncCallback, object) | argument 0 -> argument -1 | false | +| System.Net.HttpResponseStream.Read(Byte[], int, int) | argument -1 -> return (out parameter 0) | false | +| System.Net.HttpResponseStream.Write(Byte[], int, int) | argument 0 -> argument -1 | false | +| System.Net.NetworkInformation.IPAddressCollection.Add(IPAddress) | argument 0 -> element of argument -1 | true | +| System.Net.NetworkInformation.IPAddressCollection.CopyTo(IPAddress[], int) | element of argument -1 -> element of return (out parameter 0) | true | +| System.Net.NetworkInformation.IPAddressCollection.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | +| System.Net.Security.CipherSuitesPolicy.d__6.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | +| System.Net.Security.NegotiateStream.BeginRead(Byte[], int, int, AsyncCallback, object) | argument -1 -> return (out parameter 0) | false | +| System.Net.Security.NegotiateStream.BeginWrite(Byte[], int, int, AsyncCallback, object) | argument 0 -> argument -1 | false | +| System.Net.Security.NegotiateStream.Read(Byte[], int, int) | argument -1 -> return (out parameter 0) | false | +| System.Net.Security.NegotiateStream.ReadAsync(Byte[], int, int, CancellationToken) | argument -1 -> return (out parameter 0) | false | +| System.Net.Security.NegotiateStream.Write(Byte[], int, int) | argument 0 -> argument -1 | false | +| System.Net.Security.NegotiateStream.WriteAsync(Byte[], int, int, CancellationToken) | argument 0 -> argument -1 | false | +| System.Net.Security.SslStream.BeginRead(Byte[], int, int, AsyncCallback, object) | argument -1 -> return (out parameter 0) | false | +| System.Net.Security.SslStream.BeginWrite(Byte[], int, int, AsyncCallback, object) | argument 0 -> argument -1 | false | +| System.Net.Security.SslStream.Read(Byte[], int, int) | argument -1 -> return (out parameter 0) | false | +| System.Net.Security.SslStream.ReadAsync(Byte[], int, int, CancellationToken) | argument -1 -> return (out parameter 0) | false | +| System.Net.Security.SslStream.Write(Byte[], int, int) | argument 0 -> argument -1 | false | +| System.Net.Security.SslStream.WriteAsync(Byte[], int, int, CancellationToken) | argument 0 -> argument -1 | false | +| System.Net.WebUtility.HtmlEncode(string) | argument 0 -> return (normal) | false | +| System.Net.WebUtility.HtmlEncode(string, TextWriter) | argument 0 -> return (normal) | false | +| System.Net.WebUtility.UrlEncode(string) | argument 0 -> return (normal) | false | +| System.Nullable<>.GetValueOrDefault() | property Value of argument -1 -> return (normal) | true | +| System.Nullable<>.GetValueOrDefault(T) | argument 0 -> return (normal) | true | +| System.Nullable<>.GetValueOrDefault(T) | property Value of argument -1 -> return (normal) | true | +| System.Nullable<>.Nullable(T) | argument 0 -> property Value of return (normal) | true | +| System.Nullable<>.get_HasValue() | property Value of argument -1 -> return (normal) | false | +| System.Nullable<>.get_Value() | argument -1 -> return (normal) | false | +| System.Reflection.TypeInfo.d__10.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | +| System.Reflection.TypeInfo.d__22.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | +| System.Resources.ResourceFallbackManager.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | +| System.Resources.ResourceReader.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | +| System.Resources.ResourceSet.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | +| System.Resources.RuntimeResourceSet.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | +| System.Runtime.CompilerServices.ConditionalWeakTable<,>.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | +| System.Runtime.CompilerServices.ConfiguredTaskAwaitable<>.ConfiguredTaskAwaiter.GetResult() | property Result of field m_task of argument -1 -> return (normal) | true | +| System.Runtime.CompilerServices.ConfiguredTaskAwaitable<>.GetAwaiter() | field m_configuredTaskAwaiter of argument -1 -> return (normal) | true | +| System.Runtime.CompilerServices.ReadOnlyCollectionBuilder<>.Add(T) | argument 0 -> element of argument -1 | true | +| System.Runtime.CompilerServices.ReadOnlyCollectionBuilder<>.Add(object) | argument 0 -> element of argument -1 | true | +| System.Runtime.CompilerServices.ReadOnlyCollectionBuilder<>.CopyTo(Array, int) | element of argument -1 -> element of return (out parameter 0) | true | +| System.Runtime.CompilerServices.ReadOnlyCollectionBuilder<>.CopyTo(T[], int) | element of argument -1 -> element of return (out parameter 0) | true | +| System.Runtime.CompilerServices.ReadOnlyCollectionBuilder<>.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | +| System.Runtime.CompilerServices.ReadOnlyCollectionBuilder<>.Insert(int, T) | argument 1 -> element of argument -1 | true | +| System.Runtime.CompilerServices.ReadOnlyCollectionBuilder<>.Insert(int, object) | argument 1 -> element of argument -1 | true | +| System.Runtime.CompilerServices.ReadOnlyCollectionBuilder<>.Reverse() | element of argument 0 -> element of return (normal) | true | +| System.Runtime.CompilerServices.ReadOnlyCollectionBuilder<>.Reverse(int, int) | element of argument 0 -> element of return (normal) | true | +| System.Runtime.CompilerServices.ReadOnlyCollectionBuilder<>.get_Item(int) | element of argument -1 -> return (normal) | true | +| System.Runtime.CompilerServices.ReadOnlyCollectionBuilder<>.set_Item(int, T) | argument 1 -> element of argument -1 | true | +| System.Runtime.CompilerServices.ReadOnlyCollectionBuilder<>.set_Item(int, object) | argument 1 -> element of argument -1 | true | +| System.Runtime.CompilerServices.TaskAwaiter<>.GetResult() | property Result of field m_task of argument -1 -> return (normal) | true | +| System.Runtime.InteropServices.MemoryMarshal.d__15<>.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | +| System.Runtime.Loader.AssemblyLoadContext.d__83.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | +| System.Runtime.Loader.AssemblyLoadContext.d__53.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | +| System.Runtime.Loader.LibraryNameVariation.d__5.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | +| System.Security.Cryptography.CryptoStream.BeginRead(Byte[], int, int, AsyncCallback, object) | argument -1 -> return (out parameter 0) | false | +| System.Security.Cryptography.CryptoStream.BeginWrite(Byte[], int, int, AsyncCallback, object) | argument 0 -> argument -1 | false | +| System.Security.Cryptography.CryptoStream.Read(Byte[], int, int) | argument -1 -> return (out parameter 0) | false | +| System.Security.Cryptography.CryptoStream.ReadAsync(Byte[], int, int, CancellationToken) | argument -1 -> return (out parameter 0) | false | +| System.Security.Cryptography.CryptoStream.Write(Byte[], int, int) | argument 0 -> argument -1 | false | +| System.Security.Cryptography.CryptoStream.WriteAsync(Byte[], int, int, CancellationToken) | argument 0 -> argument -1 | false | +| System.Security.PermissionSet.CopyTo(Array, int) | element of argument -1 -> element of return (out parameter 0) | true | +| System.Security.PermissionSet.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | +| System.String.Clone() | argument -1 -> return (normal) | true | +| System.String.Concat(IEnumerable) | element of argument 0 -> return (normal) | false | +| System.String.Concat(ReadOnlySpan, ReadOnlySpan) | argument 0 -> return (normal) | false | +| System.String.Concat(ReadOnlySpan, ReadOnlySpan) | argument 1 -> return (normal) | false | +| System.String.Concat(ReadOnlySpan, ReadOnlySpan, ReadOnlySpan) | argument 0 -> return (normal) | false | +| System.String.Concat(ReadOnlySpan, ReadOnlySpan, ReadOnlySpan) | argument 1 -> return (normal) | false | +| System.String.Concat(ReadOnlySpan, ReadOnlySpan, ReadOnlySpan) | argument 2 -> return (normal) | false | +| System.String.Concat(ReadOnlySpan, ReadOnlySpan, ReadOnlySpan, ReadOnlySpan) | argument 0 -> return (normal) | false | +| System.String.Concat(ReadOnlySpan, ReadOnlySpan, ReadOnlySpan, ReadOnlySpan) | argument 1 -> return (normal) | false | +| System.String.Concat(ReadOnlySpan, ReadOnlySpan, ReadOnlySpan, ReadOnlySpan) | argument 2 -> return (normal) | false | +| System.String.Concat(ReadOnlySpan, ReadOnlySpan, ReadOnlySpan, ReadOnlySpan) | argument 3 -> return (normal) | false | +| System.String.Concat(object) | argument 0 -> return (normal) | false | +| System.String.Concat(object, object) | argument 0 -> return (normal) | false | +| System.String.Concat(object, object) | argument 1 -> return (normal) | false | +| System.String.Concat(object, object, object) | argument 0 -> return (normal) | false | +| System.String.Concat(object, object, object) | argument 1 -> return (normal) | false | +| System.String.Concat(object, object, object) | argument 2 -> return (normal) | false | +| System.String.Concat(params Object[]) | element of argument 0 -> return (normal) | false | +| System.String.Concat(params String[]) | element of argument 0 -> return (normal) | false | +| System.String.Concat(string, string) | argument 0 -> return (normal) | false | +| System.String.Concat(string, string) | argument 1 -> return (normal) | false | +| System.String.Concat(string, string, string) | argument 0 -> return (normal) | false | +| System.String.Concat(string, string, string) | argument 1 -> return (normal) | false | +| System.String.Concat(string, string, string) | argument 2 -> return (normal) | false | +| System.String.Concat(string, string, string, string) | argument 0 -> return (normal) | false | +| System.String.Concat(string, string, string, string) | argument 1 -> return (normal) | false | +| System.String.Concat(string, string, string, string) | argument 2 -> return (normal) | false | +| System.String.Concat(string, string, string, string) | argument 3 -> return (normal) | false | +| System.String.Concat(IEnumerable) | element of argument 0 -> return (normal) | false | +| System.String.Copy(string) | argument 0 -> return (normal) | true | +| System.String.Format(IFormatProvider, string, object) | argument 1 -> return (normal) | false | +| System.String.Format(IFormatProvider, string, object) | argument 2 -> return (normal) | false | +| System.String.Format(IFormatProvider, string, object, object) | argument 1 -> return (normal) | false | +| System.String.Format(IFormatProvider, string, object, object) | argument 2 -> return (normal) | false | +| System.String.Format(IFormatProvider, string, object, object) | argument 3 -> return (normal) | false | +| System.String.Format(IFormatProvider, string, object, object, object) | argument 1 -> return (normal) | false | +| System.String.Format(IFormatProvider, string, object, object, object) | argument 2 -> return (normal) | false | +| System.String.Format(IFormatProvider, string, object, object, object) | argument 3 -> return (normal) | false | +| System.String.Format(IFormatProvider, string, object, object, object) | argument 4 -> return (normal) | false | +| System.String.Format(IFormatProvider, string, params Object[]) | argument 1 -> return (normal) | false | +| System.String.Format(IFormatProvider, string, params Object[]) | element of argument 2 -> return (normal) | false | +| System.String.Format(string, object) | argument 0 -> return (normal) | false | +| System.String.Format(string, object) | argument 1 -> return (normal) | false | +| System.String.Format(string, object, object) | argument 0 -> return (normal) | false | +| System.String.Format(string, object, object) | argument 1 -> return (normal) | false | +| System.String.Format(string, object, object) | argument 2 -> return (normal) | false | +| System.String.Format(string, object, object, object) | argument 0 -> return (normal) | false | +| System.String.Format(string, object, object, object) | argument 1 -> return (normal) | false | +| System.String.Format(string, object, object, object) | argument 2 -> return (normal) | false | +| System.String.Format(string, object, object, object) | argument 3 -> return (normal) | false | +| System.String.Format(string, params Object[]) | argument 0 -> return (normal) | false | +| System.String.Format(string, params Object[]) | element of argument 1 -> return (normal) | false | +| System.String.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | +| System.String.Insert(int, string) | argument 1 -> return (normal) | false | +| System.String.Insert(int, string) | argument -1 -> return (normal) | false | +| System.String.Join(char, String[], int, int) | argument 0 -> return (normal) | false | +| System.String.Join(char, String[], int, int) | element of argument 1 -> return (normal) | false | +| System.String.Join(char, params Object[]) | argument 0 -> return (normal) | false | +| System.String.Join(char, params Object[]) | element of argument 1 -> return (normal) | false | +| System.String.Join(char, params String[]) | argument 0 -> return (normal) | false | +| System.String.Join(char, params String[]) | element of argument 1 -> return (normal) | false | +| System.String.Join(string, IEnumerable) | argument 0 -> return (normal) | false | +| System.String.Join(string, IEnumerable) | element of argument 1 -> return (normal) | false | +| System.String.Join(string, String[], int, int) | argument 0 -> return (normal) | false | +| System.String.Join(string, String[], int, int) | element of argument 1 -> return (normal) | false | +| System.String.Join(string, params Object[]) | argument 0 -> return (normal) | false | +| System.String.Join(string, params Object[]) | element of argument 1 -> return (normal) | false | +| System.String.Join(string, params String[]) | argument 0 -> return (normal) | false | +| System.String.Join(string, params String[]) | element of argument 1 -> return (normal) | false | +| System.String.Join(char, IEnumerable) | argument 0 -> return (normal) | false | +| System.String.Join(char, IEnumerable) | element of argument 1 -> return (normal) | false | +| System.String.Join(string, IEnumerable) | argument 0 -> return (normal) | false | +| System.String.Join(string, IEnumerable) | element of argument 1 -> return (normal) | false | +| System.String.Normalize() | argument -1 -> return (normal) | false | +| System.String.Normalize(NormalizationForm) | argument -1 -> return (normal) | false | +| System.String.PadLeft(int) | argument -1 -> return (normal) | false | +| System.String.PadLeft(int, char) | argument -1 -> return (normal) | false | +| System.String.PadRight(int) | argument -1 -> return (normal) | false | +| System.String.PadRight(int, char) | argument -1 -> return (normal) | false | +| System.String.Remove(int) | argument -1 -> return (normal) | false | +| System.String.Remove(int, int) | argument -1 -> return (normal) | false | +| System.String.Replace(char, char) | argument 1 -> return (normal) | false | +| System.String.Replace(char, char) | argument -1 -> return (normal) | false | +| System.String.Replace(string, string) | argument 1 -> return (normal) | false | +| System.String.Replace(string, string) | argument -1 -> return (normal) | false | +| System.String.Split(Char[], StringSplitOptions) | argument -1 -> element of return (normal) | false | +| System.String.Split(Char[], int) | argument -1 -> element of return (normal) | false | +| System.String.Split(Char[], int, StringSplitOptions) | argument -1 -> element of return (normal) | false | +| System.String.Split(String[], StringSplitOptions) | argument -1 -> element of return (normal) | false | +| System.String.Split(String[], int, StringSplitOptions) | argument -1 -> element of return (normal) | false | +| System.String.Split(char, StringSplitOptions) | argument -1 -> element of return (normal) | false | +| System.String.Split(char, int, StringSplitOptions) | argument -1 -> element of return (normal) | false | +| System.String.Split(params Char[]) | argument -1 -> element of return (normal) | false | +| System.String.Split(string, StringSplitOptions) | argument -1 -> element of return (normal) | false | +| System.String.Split(string, int, StringSplitOptions) | argument -1 -> element of return (normal) | false | +| System.String.String(Char[]) | element of argument 0 -> return (normal) | false | +| System.String.String(Char[], int, int) | element of argument 0 -> return (normal) | false | +| System.String.Substring(int) | argument -1 -> return (normal) | false | +| System.String.Substring(int, int) | argument -1 -> return (normal) | false | +| System.String.ToLower() | argument -1 -> return (normal) | false | +| System.String.ToLower(CultureInfo) | argument -1 -> return (normal) | false | +| System.String.ToLowerInvariant() | argument -1 -> return (normal) | false | +| System.String.ToString() | argument -1 -> return (normal) | true | +| System.String.ToString(IFormatProvider) | argument -1 -> return (normal) | true | +| System.String.ToUpper() | argument -1 -> return (normal) | false | +| System.String.ToUpper(CultureInfo) | argument -1 -> return (normal) | false | +| System.String.ToUpperInvariant() | argument -1 -> return (normal) | false | +| System.String.Trim() | argument -1 -> return (normal) | false | +| System.String.Trim(char) | argument -1 -> return (normal) | false | +| System.String.Trim(params Char[]) | argument -1 -> return (normal) | false | +| System.String.TrimEnd() | argument -1 -> return (normal) | false | +| System.String.TrimEnd(char) | argument -1 -> return (normal) | false | +| System.String.TrimEnd(params Char[]) | argument -1 -> return (normal) | false | +| System.String.TrimStart() | argument -1 -> return (normal) | false | +| System.String.TrimStart(char) | argument -1 -> return (normal) | false | +| System.String.TrimStart(params Char[]) | argument -1 -> return (normal) | false | +| System.Text.Encoding.GetBytes(Char[]) | element of argument 0 -> return (normal) | false | +| System.Text.Encoding.GetBytes(Char[], int, int) | element of argument 0 -> return (normal) | false | +| System.Text.Encoding.GetBytes(Char[], int, int, Byte[], int) | element of argument 0 -> return (normal) | false | +| System.Text.Encoding.GetBytes(ReadOnlySpan, Span) | argument 0 -> return (normal) | false | +| System.Text.Encoding.GetBytes(char*, int, byte*, int) | argument 0 -> return (normal) | false | +| System.Text.Encoding.GetBytes(char*, int, byte*, int, EncoderNLS) | argument 0 -> return (normal) | false | +| System.Text.Encoding.GetBytes(string) | argument 0 -> return (normal) | false | +| System.Text.Encoding.GetBytes(string, int, int) | argument 0 -> return (normal) | false | +| System.Text.Encoding.GetBytes(string, int, int, Byte[], int) | argument 0 -> return (normal) | false | +| System.Text.Encoding.GetChars(Byte[]) | element of argument 0 -> return (normal) | false | +| System.Text.Encoding.GetChars(Byte[], int, int) | element of argument 0 -> return (normal) | false | +| System.Text.Encoding.GetChars(Byte[], int, int, Char[], int) | element of argument 0 -> return (normal) | false | +| System.Text.Encoding.GetChars(ReadOnlySpan, Span) | element of argument 0 -> return (normal) | false | +| System.Text.Encoding.GetChars(byte*, int, char*, int) | element of argument 0 -> return (normal) | false | +| System.Text.Encoding.GetChars(byte*, int, char*, int, DecoderNLS) | element of argument 0 -> return (normal) | false | +| System.Text.Encoding.GetString(Byte[]) | element of argument 0 -> return (normal) | false | +| System.Text.Encoding.GetString(Byte[], int, int) | element of argument 0 -> return (normal) | false | +| System.Text.Encoding.GetString(ReadOnlySpan) | element of argument 0 -> return (normal) | false | +| System.Text.Encoding.GetString(byte*, int) | element of argument 0 -> return (normal) | false | +| System.Text.RegularExpressions.CaptureCollection.Add(Capture) | argument 0 -> element of argument -1 | true | +| System.Text.RegularExpressions.CaptureCollection.Add(object) | argument 0 -> element of argument -1 | true | +| System.Text.RegularExpressions.CaptureCollection.CopyTo(Array, int) | element of argument -1 -> element of return (out parameter 0) | true | +| System.Text.RegularExpressions.CaptureCollection.CopyTo(Capture[], int) | element of argument -1 -> element of return (out parameter 0) | true | +| System.Text.RegularExpressions.CaptureCollection.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | +| System.Text.RegularExpressions.CaptureCollection.Insert(int, Capture) | argument 1 -> element of argument -1 | true | +| System.Text.RegularExpressions.CaptureCollection.Insert(int, object) | argument 1 -> element of argument -1 | true | +| System.Text.RegularExpressions.CaptureCollection.get_Item(int) | element of argument -1 -> return (normal) | true | +| System.Text.RegularExpressions.CaptureCollection.set_Item(int, Capture) | argument 1 -> element of argument -1 | true | +| System.Text.RegularExpressions.CaptureCollection.set_Item(int, object) | argument 1 -> element of argument -1 | true | +| System.Text.RegularExpressions.GroupCollection.d__49.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | +| System.Text.RegularExpressions.GroupCollection.d__51.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | +| System.Text.RegularExpressions.GroupCollection.Add(Group) | argument 0 -> element of argument -1 | true | +| System.Text.RegularExpressions.GroupCollection.Add(object) | argument 0 -> element of argument -1 | true | +| System.Text.RegularExpressions.GroupCollection.CopyTo(Array, int) | element of argument -1 -> element of return (out parameter 0) | true | +| System.Text.RegularExpressions.GroupCollection.CopyTo(Group[], int) | element of argument -1 -> element of return (out parameter 0) | true | +| System.Text.RegularExpressions.GroupCollection.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | +| System.Text.RegularExpressions.GroupCollection.Insert(int, Group) | argument 1 -> element of argument -1 | true | +| System.Text.RegularExpressions.GroupCollection.Insert(int, object) | argument 1 -> element of argument -1 | true | +| System.Text.RegularExpressions.GroupCollection.get_Item(int) | element of argument -1 -> return (normal) | true | +| System.Text.RegularExpressions.GroupCollection.get_Item(string) | element of argument -1 -> return (normal) | true | +| System.Text.RegularExpressions.GroupCollection.set_Item(int, Group) | argument 1 -> element of argument -1 | true | +| System.Text.RegularExpressions.GroupCollection.set_Item(int, object) | argument 1 -> element of argument -1 | true | +| System.Text.RegularExpressions.MatchCollection.Add(Match) | argument 0 -> element of argument -1 | true | +| System.Text.RegularExpressions.MatchCollection.Add(object) | argument 0 -> element of argument -1 | true | +| System.Text.RegularExpressions.MatchCollection.CopyTo(Array, int) | element of argument -1 -> element of return (out parameter 0) | true | +| System.Text.RegularExpressions.MatchCollection.CopyTo(Match[], int) | element of argument -1 -> element of return (out parameter 0) | true | +| System.Text.RegularExpressions.MatchCollection.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | +| System.Text.RegularExpressions.MatchCollection.Insert(int, Match) | argument 1 -> element of argument -1 | true | +| System.Text.RegularExpressions.MatchCollection.Insert(int, object) | argument 1 -> element of argument -1 | true | +| System.Text.RegularExpressions.MatchCollection.get_Item(int) | element of argument -1 -> return (normal) | true | +| System.Text.RegularExpressions.MatchCollection.set_Item(int, Match) | argument 1 -> element of argument -1 | true | +| System.Text.RegularExpressions.MatchCollection.set_Item(int, object) | argument 1 -> element of argument -1 | true | +| System.Text.StringBuilder.Append(object) | argument 0 -> element of argument -1 | true | +| System.Text.StringBuilder.Append(object) | argument 0 -> element of return (normal) | true | +| System.Text.StringBuilder.Append(string) | argument 0 -> element of argument -1 | true | +| System.Text.StringBuilder.Append(string) | argument 0 -> element of return (normal) | true | +| System.Text.StringBuilder.Append(string, int, int) | argument 0 -> element of argument -1 | true | +| System.Text.StringBuilder.Append(string, int, int) | argument 0 -> element of return (normal) | true | +| System.Text.StringBuilder.AppendFormat(IFormatProvider, string, object) | argument 1 -> element of argument -1 | true | +| System.Text.StringBuilder.AppendFormat(IFormatProvider, string, object) | argument 1 -> element of return (normal) | true | +| System.Text.StringBuilder.AppendFormat(IFormatProvider, string, object) | argument 2 -> element of argument -1 | true | +| System.Text.StringBuilder.AppendFormat(IFormatProvider, string, object) | argument 2 -> element of return (normal) | true | +| System.Text.StringBuilder.AppendFormat(IFormatProvider, string, object, object) | argument 1 -> element of argument -1 | true | +| System.Text.StringBuilder.AppendFormat(IFormatProvider, string, object, object) | argument 1 -> element of return (normal) | true | +| System.Text.StringBuilder.AppendFormat(IFormatProvider, string, object, object) | argument 2 -> element of argument -1 | true | +| System.Text.StringBuilder.AppendFormat(IFormatProvider, string, object, object) | argument 2 -> element of return (normal) | true | +| System.Text.StringBuilder.AppendFormat(IFormatProvider, string, object, object) | argument 3 -> element of argument -1 | true | +| System.Text.StringBuilder.AppendFormat(IFormatProvider, string, object, object) | argument 3 -> element of return (normal) | true | +| System.Text.StringBuilder.AppendFormat(IFormatProvider, string, object, object, object) | argument 1 -> element of argument -1 | true | +| System.Text.StringBuilder.AppendFormat(IFormatProvider, string, object, object, object) | argument 1 -> element of return (normal) | true | +| System.Text.StringBuilder.AppendFormat(IFormatProvider, string, object, object, object) | argument 2 -> element of argument -1 | true | +| System.Text.StringBuilder.AppendFormat(IFormatProvider, string, object, object, object) | argument 2 -> element of return (normal) | true | +| System.Text.StringBuilder.AppendFormat(IFormatProvider, string, object, object, object) | argument 3 -> element of argument -1 | true | +| System.Text.StringBuilder.AppendFormat(IFormatProvider, string, object, object, object) | argument 3 -> element of return (normal) | true | +| System.Text.StringBuilder.AppendFormat(IFormatProvider, string, object, object, object) | argument 4 -> element of argument -1 | true | +| System.Text.StringBuilder.AppendFormat(IFormatProvider, string, object, object, object) | argument 4 -> element of return (normal) | true | +| System.Text.StringBuilder.AppendFormat(IFormatProvider, string, params Object[]) | argument 1 -> element of argument -1 | true | +| System.Text.StringBuilder.AppendFormat(IFormatProvider, string, params Object[]) | argument 1 -> element of return (normal) | true | +| System.Text.StringBuilder.AppendFormat(string, object) | argument 0 -> element of argument -1 | true | +| System.Text.StringBuilder.AppendFormat(string, object) | argument 0 -> element of return (normal) | true | +| System.Text.StringBuilder.AppendFormat(string, object) | argument 1 -> element of argument -1 | true | +| System.Text.StringBuilder.AppendFormat(string, object) | argument 1 -> element of return (normal) | true | +| System.Text.StringBuilder.AppendFormat(string, object, object) | argument 0 -> element of argument -1 | true | +| System.Text.StringBuilder.AppendFormat(string, object, object) | argument 0 -> element of return (normal) | true | +| System.Text.StringBuilder.AppendFormat(string, object, object) | argument 1 -> element of argument -1 | true | +| System.Text.StringBuilder.AppendFormat(string, object, object) | argument 1 -> element of return (normal) | true | +| System.Text.StringBuilder.AppendFormat(string, object, object) | argument 2 -> element of argument -1 | true | +| System.Text.StringBuilder.AppendFormat(string, object, object) | argument 2 -> element of return (normal) | true | +| System.Text.StringBuilder.AppendFormat(string, object, object, object) | argument 0 -> element of argument -1 | true | +| System.Text.StringBuilder.AppendFormat(string, object, object, object) | argument 0 -> element of return (normal) | true | +| System.Text.StringBuilder.AppendFormat(string, object, object, object) | argument 1 -> element of argument -1 | true | +| System.Text.StringBuilder.AppendFormat(string, object, object, object) | argument 1 -> element of return (normal) | true | +| System.Text.StringBuilder.AppendFormat(string, object, object, object) | argument 2 -> element of argument -1 | true | +| System.Text.StringBuilder.AppendFormat(string, object, object, object) | argument 2 -> element of return (normal) | true | +| System.Text.StringBuilder.AppendFormat(string, object, object, object) | argument 3 -> element of argument -1 | true | +| System.Text.StringBuilder.AppendFormat(string, object, object, object) | argument 3 -> element of return (normal) | true | +| System.Text.StringBuilder.AppendFormat(string, params Object[]) | argument 0 -> element of argument -1 | true | +| System.Text.StringBuilder.AppendFormat(string, params Object[]) | argument 0 -> element of return (normal) | true | +| System.Text.StringBuilder.AppendLine(string) | argument 0 -> element of argument -1 | true | +| System.Text.StringBuilder.AppendLine(string) | argument 0 -> element of return (normal) | true | +| System.Text.StringBuilder.StringBuilder(string) | argument 0 -> element of return (normal) | true | +| System.Text.StringBuilder.StringBuilder(string, int) | argument 0 -> element of return (normal) | true | +| System.Text.StringBuilder.StringBuilder(string, int, int, int) | argument 0 -> element of return (normal) | true | +| System.Text.StringBuilder.ToString() | element of argument -1 -> return (normal) | false | +| System.Text.StringBuilder.ToString(int, int) | element of argument -1 -> return (normal) | false | +| System.Text.TranscodingStream.BeginRead(Byte[], int, int, AsyncCallback, object) | argument -1 -> return (out parameter 0) | false | +| System.Text.TranscodingStream.BeginWrite(Byte[], int, int, AsyncCallback, object) | argument 0 -> argument -1 | false | +| System.Text.TranscodingStream.Read(Byte[], int, int) | argument -1 -> return (out parameter 0) | false | +| System.Text.TranscodingStream.ReadAsync(Byte[], int, int, CancellationToken) | argument -1 -> return (out parameter 0) | false | +| System.Text.TranscodingStream.Write(Byte[], int, int) | argument 0 -> argument -1 | false | +| System.Text.TranscodingStream.WriteAsync(Byte[], int, int, CancellationToken) | argument 0 -> argument -1 | false | +| System.Threading.Tasks.SingleProducerSingleConsumerQueue<>.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | +| System.Threading.Tasks.Task.ContinueWith(Action, object) | argument 1 -> parameter 1 of argument 0 | true | +| System.Threading.Tasks.Task.ContinueWith(Action, object, CancellationToken) | argument 1 -> parameter 1 of argument 0 | true | +| System.Threading.Tasks.Task.ContinueWith(Action, object, CancellationToken, TaskContinuationOptions, TaskScheduler) | argument 1 -> parameter 1 of argument 0 | true | +| System.Threading.Tasks.Task.ContinueWith(Action, object, TaskContinuationOptions) | argument 1 -> parameter 1 of argument 0 | true | +| System.Threading.Tasks.Task.ContinueWith(Action, object, TaskScheduler) | argument 1 -> parameter 1 of argument 0 | true | +| System.Threading.Tasks.Task.ContinueWith(Func, object) | argument 1 -> parameter 1 of argument 0 | true | +| System.Threading.Tasks.Task.ContinueWith(Func, object) | return (normal) of argument 0 -> property Result of return (normal) | true | +| System.Threading.Tasks.Task.ContinueWith(Func, object, CancellationToken) | argument 1 -> parameter 1 of argument 0 | true | +| System.Threading.Tasks.Task.ContinueWith(Func, object, CancellationToken) | return (normal) of argument 0 -> property Result of return (normal) | true | +| System.Threading.Tasks.Task.ContinueWith(Func, object, CancellationToken, TaskContinuationOptions, TaskScheduler) | argument 1 -> parameter 1 of argument 0 | true | +| System.Threading.Tasks.Task.ContinueWith(Func, object, CancellationToken, TaskContinuationOptions, TaskScheduler) | return (normal) of argument 0 -> property Result of return (normal) | true | +| System.Threading.Tasks.Task.ContinueWith(Func, object, TaskContinuationOptions) | argument 1 -> parameter 1 of argument 0 | true | +| System.Threading.Tasks.Task.ContinueWith(Func, object, TaskContinuationOptions) | return (normal) of argument 0 -> property Result of return (normal) | true | +| System.Threading.Tasks.Task.ContinueWith(Func, object, TaskScheduler) | argument 1 -> parameter 1 of argument 0 | true | +| System.Threading.Tasks.Task.ContinueWith(Func, object, TaskScheduler) | return (normal) of argument 0 -> property Result of return (normal) | true | +| System.Threading.Tasks.Task.ContinueWith(Func) | return (normal) of argument 0 -> property Result of return (normal) | true | +| System.Threading.Tasks.Task.ContinueWith(Func, CancellationToken) | return (normal) of argument 0 -> property Result of return (normal) | true | +| System.Threading.Tasks.Task.ContinueWith(Func, CancellationToken, TaskContinuationOptions, TaskScheduler) | return (normal) of argument 0 -> property Result of return (normal) | true | +| System.Threading.Tasks.Task.ContinueWith(Func, TaskContinuationOptions) | return (normal) of argument 0 -> property Result of return (normal) | true | +| System.Threading.Tasks.Task.ContinueWith(Func, TaskScheduler) | return (normal) of argument 0 -> property Result of return (normal) | true | +| System.Threading.Tasks.Task.FromResult(TResult) | argument 0 -> property Result of return (normal) | true | +| System.Threading.Tasks.Task.Run(Func) | return (normal) of argument 0 -> property Result of return (normal) | true | +| System.Threading.Tasks.Task.Run(Func, CancellationToken) | return (normal) of argument 0 -> property Result of return (normal) | true | +| System.Threading.Tasks.Task.Run(Func>) | return (normal) of argument 0 -> property Result of return (normal) | true | +| System.Threading.Tasks.Task.Run(Func>, CancellationToken) | return (normal) of argument 0 -> property Result of return (normal) | true | +| System.Threading.Tasks.Task.Task(Action, object) | argument 1 -> parameter 0 of argument 0 | true | +| System.Threading.Tasks.Task.Task(Action, object, CancellationToken) | argument 1 -> parameter 0 of argument 0 | true | +| System.Threading.Tasks.Task.Task(Action, object, CancellationToken, TaskCreationOptions) | argument 1 -> parameter 0 of argument 0 | true | +| System.Threading.Tasks.Task.Task(Action, object, TaskCreationOptions) | argument 1 -> parameter 0 of argument 0 | true | +| System.Threading.Tasks.Task.WhenAll(IEnumerable>) | property Result of element of argument 0 -> element of property Result of return (normal) | true | +| System.Threading.Tasks.Task.WhenAll(params Task[]) | property Result of element of argument 0 -> element of property Result of return (normal) | true | +| System.Threading.Tasks.Task.WhenAny(IEnumerable>) | property Result of element of argument 0 -> element of property Result of return (normal) | true | +| System.Threading.Tasks.Task.WhenAny(Task, Task) | property Result of element of argument 0 -> element of property Result of return (normal) | true | +| System.Threading.Tasks.Task.WhenAny(Task, Task) | property Result of element of argument 1 -> element of property Result of return (normal) | true | +| System.Threading.Tasks.Task.WhenAny(params Task[]) | property Result of element of argument 0 -> element of property Result of return (normal) | true | +| System.Threading.Tasks.Task<>.ConfigureAwait(bool) | argument -1 -> field m_task of field m_configuredTaskAwaiter of return (normal) | true | +| System.Threading.Tasks.Task<>.ContinueWith(Action, Object>, object) | argument 1 -> parameter 1 of argument 0 | true | +| System.Threading.Tasks.Task<>.ContinueWith(Action, Object>, object) | argument -1 -> parameter 0 of argument 0 | true | +| System.Threading.Tasks.Task<>.ContinueWith(Action, Object>, object, CancellationToken) | argument 1 -> parameter 1 of argument 0 | true | +| System.Threading.Tasks.Task<>.ContinueWith(Action, Object>, object, CancellationToken) | argument -1 -> parameter 0 of argument 0 | true | +| System.Threading.Tasks.Task<>.ContinueWith(Action, Object>, object, CancellationToken, TaskContinuationOptions, TaskScheduler) | argument 1 -> parameter 1 of argument 0 | true | +| System.Threading.Tasks.Task<>.ContinueWith(Action, Object>, object, CancellationToken, TaskContinuationOptions, TaskScheduler) | argument -1 -> parameter 0 of argument 0 | true | +| System.Threading.Tasks.Task<>.ContinueWith(Action, Object>, object, TaskContinuationOptions) | argument 1 -> parameter 1 of argument 0 | true | +| System.Threading.Tasks.Task<>.ContinueWith(Action, Object>, object, TaskContinuationOptions) | argument -1 -> parameter 0 of argument 0 | true | +| System.Threading.Tasks.Task<>.ContinueWith(Action, Object>, object, TaskScheduler) | argument 1 -> parameter 1 of argument 0 | true | +| System.Threading.Tasks.Task<>.ContinueWith(Action, Object>, object, TaskScheduler) | argument -1 -> parameter 0 of argument 0 | true | +| System.Threading.Tasks.Task<>.ContinueWith(Action>) | argument -1 -> parameter 0 of argument 0 | true | +| System.Threading.Tasks.Task<>.ContinueWith(Action>, CancellationToken) | argument -1 -> parameter 0 of argument 0 | true | +| System.Threading.Tasks.Task<>.ContinueWith(Action>, CancellationToken, TaskContinuationOptions, TaskScheduler) | argument -1 -> parameter 0 of argument 0 | true | +| System.Threading.Tasks.Task<>.ContinueWith(Action>, TaskContinuationOptions) | argument -1 -> parameter 0 of argument 0 | true | +| System.Threading.Tasks.Task<>.ContinueWith(Action>, TaskScheduler) | argument -1 -> parameter 0 of argument 0 | true | +| System.Threading.Tasks.Task<>.ContinueWith(Func, Object, TNewResult>, object) | argument 1 -> parameter 1 of argument 0 | true | +| System.Threading.Tasks.Task<>.ContinueWith(Func, Object, TNewResult>, object) | argument -1 -> parameter 0 of argument 0 | true | +| System.Threading.Tasks.Task<>.ContinueWith(Func, Object, TNewResult>, object) | return (normal) of argument 0 -> property Result of return (normal) | true | +| System.Threading.Tasks.Task<>.ContinueWith(Func, Object, TNewResult>, object, CancellationToken) | argument 1 -> parameter 1 of argument 0 | true | +| System.Threading.Tasks.Task<>.ContinueWith(Func, Object, TNewResult>, object, CancellationToken) | argument -1 -> parameter 0 of argument 0 | true | +| System.Threading.Tasks.Task<>.ContinueWith(Func, Object, TNewResult>, object, CancellationToken) | return (normal) of argument 0 -> property Result of return (normal) | true | +| System.Threading.Tasks.Task<>.ContinueWith(Func, Object, TNewResult>, object, CancellationToken, TaskContinuationOptions, TaskScheduler) | argument 1 -> parameter 1 of argument 0 | true | +| System.Threading.Tasks.Task<>.ContinueWith(Func, Object, TNewResult>, object, CancellationToken, TaskContinuationOptions, TaskScheduler) | argument -1 -> parameter 0 of argument 0 | true | +| System.Threading.Tasks.Task<>.ContinueWith(Func, Object, TNewResult>, object, CancellationToken, TaskContinuationOptions, TaskScheduler) | return (normal) of argument 0 -> property Result of return (normal) | true | +| System.Threading.Tasks.Task<>.ContinueWith(Func, Object, TNewResult>, object, TaskContinuationOptions) | argument 1 -> parameter 1 of argument 0 | true | +| System.Threading.Tasks.Task<>.ContinueWith(Func, Object, TNewResult>, object, TaskContinuationOptions) | argument -1 -> parameter 0 of argument 0 | true | +| System.Threading.Tasks.Task<>.ContinueWith(Func, Object, TNewResult>, object, TaskContinuationOptions) | return (normal) of argument 0 -> property Result of return (normal) | true | +| System.Threading.Tasks.Task<>.ContinueWith(Func, Object, TNewResult>, object, TaskScheduler) | argument 1 -> parameter 1 of argument 0 | true | +| System.Threading.Tasks.Task<>.ContinueWith(Func, Object, TNewResult>, object, TaskScheduler) | argument -1 -> parameter 0 of argument 0 | true | +| System.Threading.Tasks.Task<>.ContinueWith(Func, Object, TNewResult>, object, TaskScheduler) | return (normal) of argument 0 -> property Result of return (normal) | true | +| System.Threading.Tasks.Task<>.ContinueWith(Func, TNewResult>) | argument -1 -> parameter 0 of argument 0 | true | +| System.Threading.Tasks.Task<>.ContinueWith(Func, TNewResult>) | return (normal) of argument 0 -> property Result of return (normal) | true | +| System.Threading.Tasks.Task<>.ContinueWith(Func, TNewResult>, CancellationToken) | argument -1 -> parameter 0 of argument 0 | true | +| System.Threading.Tasks.Task<>.ContinueWith(Func, TNewResult>, CancellationToken) | return (normal) of argument 0 -> property Result of return (normal) | true | +| System.Threading.Tasks.Task<>.ContinueWith(Func, TNewResult>, CancellationToken, TaskContinuationOptions, TaskScheduler) | argument -1 -> parameter 0 of argument 0 | true | +| System.Threading.Tasks.Task<>.ContinueWith(Func, TNewResult>, CancellationToken, TaskContinuationOptions, TaskScheduler) | return (normal) of argument 0 -> property Result of return (normal) | true | +| System.Threading.Tasks.Task<>.ContinueWith(Func, TNewResult>, TaskContinuationOptions) | argument -1 -> parameter 0 of argument 0 | true | +| System.Threading.Tasks.Task<>.ContinueWith(Func, TNewResult>, TaskContinuationOptions) | return (normal) of argument 0 -> property Result of return (normal) | true | +| System.Threading.Tasks.Task<>.ContinueWith(Func, TNewResult>, TaskScheduler) | argument -1 -> parameter 0 of argument 0 | true | +| System.Threading.Tasks.Task<>.ContinueWith(Func, TNewResult>, TaskScheduler) | return (normal) of argument 0 -> property Result of return (normal) | true | +| System.Threading.Tasks.Task<>.GetAwaiter() | argument -1 -> field m_task of return (normal) | true | +| System.Threading.Tasks.Task<>.Task(Func, object) | argument 1 -> parameter 0 of argument 0 | true | +| System.Threading.Tasks.Task<>.Task(Func, object) | return (normal) of argument 0 -> property Result of return (normal) | true | +| System.Threading.Tasks.Task<>.Task(Func, object, CancellationToken) | argument 1 -> parameter 0 of argument 0 | true | +| System.Threading.Tasks.Task<>.Task(Func, object, CancellationToken) | return (normal) of argument 0 -> property Result of return (normal) | true | +| System.Threading.Tasks.Task<>.Task(Func, object, CancellationToken, TaskCreationOptions) | argument 1 -> parameter 0 of argument 0 | true | +| System.Threading.Tasks.Task<>.Task(Func, object, CancellationToken, TaskCreationOptions) | return (normal) of argument 0 -> property Result of return (normal) | true | +| System.Threading.Tasks.Task<>.Task(Func, object, TaskCreationOptions) | argument 1 -> parameter 0 of argument 0 | true | +| System.Threading.Tasks.Task<>.Task(Func, object, TaskCreationOptions) | return (normal) of argument 0 -> property Result of return (normal) | true | +| System.Threading.Tasks.Task<>.Task(Func) | return (normal) of argument 0 -> property Result of return (normal) | true | +| System.Threading.Tasks.Task<>.Task(Func, CancellationToken) | return (normal) of argument 0 -> property Result of return (normal) | true | +| System.Threading.Tasks.Task<>.Task(Func, CancellationToken, TaskCreationOptions) | return (normal) of argument 0 -> property Result of return (normal) | true | +| System.Threading.Tasks.Task<>.Task(Func, TaskCreationOptions) | return (normal) of argument 0 -> property Result of return (normal) | true | +| System.Threading.Tasks.Task<>.get_Result() | argument -1 -> return (normal) | false | +| System.Threading.Tasks.TaskFactory.ContinueWhenAll(Task[], Func) | argument 0 -> parameter 0 of argument 1 | true | +| System.Threading.Tasks.TaskFactory.ContinueWhenAll(Task[], Func) | return (normal) of argument 1 -> property Result of return (normal) | true | +| System.Threading.Tasks.TaskFactory.ContinueWhenAll(Task[], Func, CancellationToken) | argument 0 -> parameter 0 of argument 1 | true | +| System.Threading.Tasks.TaskFactory.ContinueWhenAll(Task[], Func, CancellationToken) | return (normal) of argument 1 -> property Result of return (normal) | true | +| System.Threading.Tasks.TaskFactory.ContinueWhenAll(Task[], Func, CancellationToken, TaskContinuationOptions, TaskScheduler) | argument 0 -> parameter 0 of argument 1 | true | +| System.Threading.Tasks.TaskFactory.ContinueWhenAll(Task[], Func, CancellationToken, TaskContinuationOptions, TaskScheduler) | return (normal) of argument 1 -> property Result of return (normal) | true | +| System.Threading.Tasks.TaskFactory.ContinueWhenAll(Task[], Func, TaskContinuationOptions) | argument 0 -> parameter 0 of argument 1 | true | +| System.Threading.Tasks.TaskFactory.ContinueWhenAll(Task[], Func, TaskContinuationOptions) | return (normal) of argument 1 -> property Result of return (normal) | true | +| System.Threading.Tasks.TaskFactory.ContinueWhenAll(Task[], Action) | argument 0 -> parameter 0 of argument 1 | true | +| System.Threading.Tasks.TaskFactory.ContinueWhenAll(Task[], Action, CancellationToken) | argument 0 -> parameter 0 of argument 1 | true | +| System.Threading.Tasks.TaskFactory.ContinueWhenAll(Task[], Action, CancellationToken, TaskContinuationOptions, TaskScheduler) | argument 0 -> parameter 0 of argument 1 | true | +| System.Threading.Tasks.TaskFactory.ContinueWhenAll(Task[], Action, TaskContinuationOptions) | argument 0 -> parameter 0 of argument 1 | true | +| System.Threading.Tasks.TaskFactory.ContinueWhenAll(Task[], Func) | return (normal) of argument 1 -> property Result of return (normal) | true | +| System.Threading.Tasks.TaskFactory.ContinueWhenAll(Task[], Func, CancellationToken) | return (normal) of argument 1 -> property Result of return (normal) | true | +| System.Threading.Tasks.TaskFactory.ContinueWhenAll(Task[], Func, CancellationToken, TaskContinuationOptions, TaskScheduler) | return (normal) of argument 1 -> property Result of return (normal) | true | +| System.Threading.Tasks.TaskFactory.ContinueWhenAll(Task[], Func, TaskContinuationOptions) | return (normal) of argument 1 -> property Result of return (normal) | true | +| System.Threading.Tasks.TaskFactory.ContinueWhenAny(Task[], Func, TResult>) | argument 0 -> parameter 0 of argument 1 | true | +| System.Threading.Tasks.TaskFactory.ContinueWhenAny(Task[], Func, TResult>) | return (normal) of argument 1 -> property Result of return (normal) | true | +| System.Threading.Tasks.TaskFactory.ContinueWhenAny(Task[], Func, TResult>, CancellationToken) | argument 0 -> parameter 0 of argument 1 | true | +| System.Threading.Tasks.TaskFactory.ContinueWhenAny(Task[], Func, TResult>, CancellationToken) | return (normal) of argument 1 -> property Result of return (normal) | true | +| System.Threading.Tasks.TaskFactory.ContinueWhenAny(Task[], Func, TResult>, CancellationToken, TaskContinuationOptions, TaskScheduler) | argument 0 -> parameter 0 of argument 1 | true | +| System.Threading.Tasks.TaskFactory.ContinueWhenAny(Task[], Func, TResult>, CancellationToken, TaskContinuationOptions, TaskScheduler) | return (normal) of argument 1 -> property Result of return (normal) | true | +| System.Threading.Tasks.TaskFactory.ContinueWhenAny(Task[], Func, TResult>, TaskContinuationOptions) | argument 0 -> parameter 0 of argument 1 | true | +| System.Threading.Tasks.TaskFactory.ContinueWhenAny(Task[], Func, TResult>, TaskContinuationOptions) | return (normal) of argument 1 -> property Result of return (normal) | true | +| System.Threading.Tasks.TaskFactory.ContinueWhenAny(Task[], Action>) | argument 0 -> parameter 0 of argument 1 | true | +| System.Threading.Tasks.TaskFactory.ContinueWhenAny(Task[], Action>, CancellationToken) | argument 0 -> parameter 0 of argument 1 | true | +| System.Threading.Tasks.TaskFactory.ContinueWhenAny(Task[], Action>, CancellationToken, TaskContinuationOptions, TaskScheduler) | argument 0 -> parameter 0 of argument 1 | true | +| System.Threading.Tasks.TaskFactory.ContinueWhenAny(Task[], Action>, TaskContinuationOptions) | argument 0 -> parameter 0 of argument 1 | true | +| System.Threading.Tasks.TaskFactory.ContinueWhenAny(Task[], Func) | return (normal) of argument 1 -> property Result of return (normal) | true | +| System.Threading.Tasks.TaskFactory.ContinueWhenAny(Task[], Func, CancellationToken) | return (normal) of argument 1 -> property Result of return (normal) | true | +| System.Threading.Tasks.TaskFactory.ContinueWhenAny(Task[], Func, CancellationToken, TaskContinuationOptions, TaskScheduler) | return (normal) of argument 1 -> property Result of return (normal) | true | +| System.Threading.Tasks.TaskFactory.ContinueWhenAny(Task[], Func, TaskContinuationOptions) | return (normal) of argument 1 -> property Result of return (normal) | true | +| System.Threading.Tasks.TaskFactory.StartNew(Action, object) | argument 1 -> parameter 0 of argument 0 | true | +| System.Threading.Tasks.TaskFactory.StartNew(Action, object, CancellationToken) | argument 1 -> parameter 0 of argument 0 | true | +| System.Threading.Tasks.TaskFactory.StartNew(Action, object, CancellationToken, TaskCreationOptions, TaskScheduler) | argument 1 -> parameter 0 of argument 0 | true | +| System.Threading.Tasks.TaskFactory.StartNew(Action, object, TaskCreationOptions) | argument 1 -> parameter 0 of argument 0 | true | +| System.Threading.Tasks.TaskFactory.StartNew(Func, object) | argument 1 -> parameter 0 of argument 0 | true | +| System.Threading.Tasks.TaskFactory.StartNew(Func, object) | return (normal) of argument 0 -> property Result of return (normal) | true | +| System.Threading.Tasks.TaskFactory.StartNew(Func, object, CancellationToken) | argument 1 -> parameter 0 of argument 0 | true | +| System.Threading.Tasks.TaskFactory.StartNew(Func, object, CancellationToken) | return (normal) of argument 0 -> property Result of return (normal) | true | +| System.Threading.Tasks.TaskFactory.StartNew(Func, object, CancellationToken, TaskCreationOptions, TaskScheduler) | argument 1 -> parameter 0 of argument 0 | true | +| System.Threading.Tasks.TaskFactory.StartNew(Func, object, CancellationToken, TaskCreationOptions, TaskScheduler) | return (normal) of argument 0 -> property Result of return (normal) | true | +| System.Threading.Tasks.TaskFactory.StartNew(Func, object, TaskCreationOptions) | argument 1 -> parameter 0 of argument 0 | true | +| System.Threading.Tasks.TaskFactory.StartNew(Func, object, TaskCreationOptions) | return (normal) of argument 0 -> property Result of return (normal) | true | +| System.Threading.Tasks.TaskFactory.StartNew(Func) | return (normal) of argument 0 -> property Result of return (normal) | true | +| System.Threading.Tasks.TaskFactory.StartNew(Func, CancellationToken) | return (normal) of argument 0 -> property Result of return (normal) | true | +| System.Threading.Tasks.TaskFactory.StartNew(Func, CancellationToken, TaskCreationOptions, TaskScheduler) | return (normal) of argument 0 -> property Result of return (normal) | true | +| System.Threading.Tasks.TaskFactory.StartNew(Func, TaskCreationOptions) | return (normal) of argument 0 -> property Result of return (normal) | true | +| System.Threading.Tasks.TaskFactory<>.ContinueWhenAll(Task[], Func) | return (normal) of argument 1 -> property Result of return (normal) | true | +| System.Threading.Tasks.TaskFactory<>.ContinueWhenAll(Task[], Func, CancellationToken) | return (normal) of argument 1 -> property Result of return (normal) | true | +| System.Threading.Tasks.TaskFactory<>.ContinueWhenAll(Task[], Func, CancellationToken, TaskContinuationOptions, TaskScheduler) | return (normal) of argument 1 -> property Result of return (normal) | true | +| System.Threading.Tasks.TaskFactory<>.ContinueWhenAll(Task[], Func, TaskContinuationOptions) | return (normal) of argument 1 -> property Result of return (normal) | true | +| System.Threading.Tasks.TaskFactory<>.ContinueWhenAll(Task[], Func) | argument 0 -> parameter 0 of argument 1 | true | +| System.Threading.Tasks.TaskFactory<>.ContinueWhenAll(Task[], Func) | return (normal) of argument 1 -> property Result of return (normal) | true | +| System.Threading.Tasks.TaskFactory<>.ContinueWhenAll(Task[], Func, CancellationToken) | argument 0 -> parameter 0 of argument 1 | true | +| System.Threading.Tasks.TaskFactory<>.ContinueWhenAll(Task[], Func, CancellationToken) | return (normal) of argument 1 -> property Result of return (normal) | true | +| System.Threading.Tasks.TaskFactory<>.ContinueWhenAll(Task[], Func, CancellationToken, TaskContinuationOptions, TaskScheduler) | argument 0 -> parameter 0 of argument 1 | true | +| System.Threading.Tasks.TaskFactory<>.ContinueWhenAll(Task[], Func, CancellationToken, TaskContinuationOptions, TaskScheduler) | return (normal) of argument 1 -> property Result of return (normal) | true | +| System.Threading.Tasks.TaskFactory<>.ContinueWhenAll(Task[], Func, TaskContinuationOptions) | argument 0 -> parameter 0 of argument 1 | true | +| System.Threading.Tasks.TaskFactory<>.ContinueWhenAll(Task[], Func, TaskContinuationOptions) | return (normal) of argument 1 -> property Result of return (normal) | true | +| System.Threading.Tasks.TaskFactory<>.ContinueWhenAny(Task[], Func) | return (normal) of argument 1 -> property Result of return (normal) | true | +| System.Threading.Tasks.TaskFactory<>.ContinueWhenAny(Task[], Func, CancellationToken) | return (normal) of argument 1 -> property Result of return (normal) | true | +| System.Threading.Tasks.TaskFactory<>.ContinueWhenAny(Task[], Func, CancellationToken, TaskContinuationOptions, TaskScheduler) | return (normal) of argument 1 -> property Result of return (normal) | true | +| System.Threading.Tasks.TaskFactory<>.ContinueWhenAny(Task[], Func, TaskContinuationOptions) | return (normal) of argument 1 -> property Result of return (normal) | true | +| System.Threading.Tasks.TaskFactory<>.ContinueWhenAny(Task[], Func, TResult>) | argument 0 -> parameter 0 of argument 1 | true | +| System.Threading.Tasks.TaskFactory<>.ContinueWhenAny(Task[], Func, TResult>) | return (normal) of argument 1 -> property Result of return (normal) | true | +| System.Threading.Tasks.TaskFactory<>.ContinueWhenAny(Task[], Func, TResult>, CancellationToken) | argument 0 -> parameter 0 of argument 1 | true | +| System.Threading.Tasks.TaskFactory<>.ContinueWhenAny(Task[], Func, TResult>, CancellationToken) | return (normal) of argument 1 -> property Result of return (normal) | true | +| System.Threading.Tasks.TaskFactory<>.ContinueWhenAny(Task[], Func, TResult>, CancellationToken, TaskContinuationOptions, TaskScheduler) | argument 0 -> parameter 0 of argument 1 | true | +| System.Threading.Tasks.TaskFactory<>.ContinueWhenAny(Task[], Func, TResult>, CancellationToken, TaskContinuationOptions, TaskScheduler) | return (normal) of argument 1 -> property Result of return (normal) | true | +| System.Threading.Tasks.TaskFactory<>.ContinueWhenAny(Task[], Func, TResult>, TaskContinuationOptions) | argument 0 -> parameter 0 of argument 1 | true | +| System.Threading.Tasks.TaskFactory<>.ContinueWhenAny(Task[], Func, TResult>, TaskContinuationOptions) | return (normal) of argument 1 -> property Result of return (normal) | true | +| System.Threading.Tasks.TaskFactory<>.StartNew(Func, object) | argument 1 -> parameter 0 of argument 0 | true | +| System.Threading.Tasks.TaskFactory<>.StartNew(Func, object) | return (normal) of argument 0 -> property Result of return (normal) | true | +| System.Threading.Tasks.TaskFactory<>.StartNew(Func, object, CancellationToken) | argument 1 -> parameter 0 of argument 0 | true | +| System.Threading.Tasks.TaskFactory<>.StartNew(Func, object, CancellationToken) | return (normal) of argument 0 -> property Result of return (normal) | true | +| System.Threading.Tasks.TaskFactory<>.StartNew(Func, object, CancellationToken, TaskCreationOptions, TaskScheduler) | argument 1 -> parameter 0 of argument 0 | true | +| System.Threading.Tasks.TaskFactory<>.StartNew(Func, object, CancellationToken, TaskCreationOptions, TaskScheduler) | return (normal) of argument 0 -> property Result of return (normal) | true | +| System.Threading.Tasks.TaskFactory<>.StartNew(Func, object, TaskCreationOptions) | argument 1 -> parameter 0 of argument 0 | true | +| System.Threading.Tasks.TaskFactory<>.StartNew(Func, object, TaskCreationOptions) | return (normal) of argument 0 -> property Result of return (normal) | true | +| System.Threading.Tasks.TaskFactory<>.StartNew(Func) | return (normal) of argument 0 -> property Result of return (normal) | true | +| System.Threading.Tasks.TaskFactory<>.StartNew(Func, CancellationToken) | return (normal) of argument 0 -> property Result of return (normal) | true | +| System.Threading.Tasks.TaskFactory<>.StartNew(Func, CancellationToken, TaskCreationOptions, TaskScheduler) | return (normal) of argument 0 -> property Result of return (normal) | true | +| System.Threading.Tasks.TaskFactory<>.StartNew(Func, TaskCreationOptions) | return (normal) of argument 0 -> property Result of return (normal) | true | +| System.Threading.Tasks.ThreadPoolTaskScheduler.d__6.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | +| System.Threading.ThreadPool.d__52.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | +| System.Threading.ThreadPool.d__51.GetEnumerator() | element of argument -1 -> property Current of return (normal) | true | +| System.Tuple.Create(T1, T2, T3, T4, T5, T6, T7, T8) | argument 0 -> property Item1 of return (normal) | true | +| System.Tuple.Create(T1, T2, T3, T4, T5, T6, T7, T8) | argument 1 -> property Item2 of return (normal) | true | +| System.Tuple.Create(T1, T2, T3, T4, T5, T6, T7, T8) | argument 2 -> property Item3 of return (normal) | true | +| System.Tuple.Create(T1, T2, T3, T4, T5, T6, T7, T8) | argument 3 -> property Item4 of return (normal) | true | +| System.Tuple.Create(T1, T2, T3, T4, T5, T6, T7, T8) | argument 4 -> property Item5 of return (normal) | true | +| System.Tuple.Create(T1, T2, T3, T4, T5, T6, T7, T8) | argument 5 -> property Item6 of return (normal) | true | +| System.Tuple.Create(T1, T2, T3, T4, T5, T6, T7, T8) | argument 6 -> property Item7 of return (normal) | true | +| System.Tuple.Create(T1, T2, T3, T4, T5, T6, T7) | argument 0 -> property Item1 of return (normal) | true | +| System.Tuple.Create(T1, T2, T3, T4, T5, T6, T7) | argument 1 -> property Item2 of return (normal) | true | +| System.Tuple.Create(T1, T2, T3, T4, T5, T6, T7) | argument 2 -> property Item3 of return (normal) | true | +| System.Tuple.Create(T1, T2, T3, T4, T5, T6, T7) | argument 3 -> property Item4 of return (normal) | true | +| System.Tuple.Create(T1, T2, T3, T4, T5, T6, T7) | argument 4 -> property Item5 of return (normal) | true | +| System.Tuple.Create(T1, T2, T3, T4, T5, T6, T7) | argument 5 -> property Item6 of return (normal) | true | +| System.Tuple.Create(T1, T2, T3, T4, T5, T6, T7) | argument 6 -> property Item7 of return (normal) | true | +| System.Tuple.Create(T1, T2, T3, T4, T5, T6) | argument 0 -> property Item1 of return (normal) | true | +| System.Tuple.Create(T1, T2, T3, T4, T5, T6) | argument 1 -> property Item2 of return (normal) | true | +| System.Tuple.Create(T1, T2, T3, T4, T5, T6) | argument 2 -> property Item3 of return (normal) | true | +| System.Tuple.Create(T1, T2, T3, T4, T5, T6) | argument 3 -> property Item4 of return (normal) | true | +| System.Tuple.Create(T1, T2, T3, T4, T5, T6) | argument 4 -> property Item5 of return (normal) | true | +| System.Tuple.Create(T1, T2, T3, T4, T5, T6) | argument 5 -> property Item6 of return (normal) | true | +| System.Tuple.Create(T1, T2, T3, T4, T5) | argument 0 -> property Item1 of return (normal) | true | +| System.Tuple.Create(T1, T2, T3, T4, T5) | argument 1 -> property Item2 of return (normal) | true | +| System.Tuple.Create(T1, T2, T3, T4, T5) | argument 2 -> property Item3 of return (normal) | true | +| System.Tuple.Create(T1, T2, T3, T4, T5) | argument 3 -> property Item4 of return (normal) | true | +| System.Tuple.Create(T1, T2, T3, T4, T5) | argument 4 -> property Item5 of return (normal) | true | +| System.Tuple.Create(T1, T2, T3, T4) | argument 0 -> property Item1 of return (normal) | true | +| System.Tuple.Create(T1, T2, T3, T4) | argument 1 -> property Item2 of return (normal) | true | +| System.Tuple.Create(T1, T2, T3, T4) | argument 2 -> property Item3 of return (normal) | true | +| System.Tuple.Create(T1, T2, T3, T4) | argument 3 -> property Item4 of return (normal) | true | +| System.Tuple.Create(T1, T2, T3) | argument 0 -> property Item1 of return (normal) | true | +| System.Tuple.Create(T1, T2, T3) | argument 1 -> property Item2 of return (normal) | true | +| System.Tuple.Create(T1, T2, T3) | argument 2 -> property Item3 of return (normal) | true | +| System.Tuple.Create(T1, T2) | argument 0 -> property Item1 of return (normal) | true | +| System.Tuple.Create(T1, T2) | argument 1 -> property Item2 of return (normal) | true | +| System.Tuple.Create(T1) | argument 0 -> property Item1 of return (normal) | true | +| System.Tuple<,,,,,,,>.Tuple(T1, T2, T3, T4, T5, T6, T7, TRest) | argument 0 -> property Item1 of return (normal) | true | +| System.Tuple<,,,,,,,>.Tuple(T1, T2, T3, T4, T5, T6, T7, TRest) | argument 1 -> property Item2 of return (normal) | true | +| System.Tuple<,,,,,,,>.Tuple(T1, T2, T3, T4, T5, T6, T7, TRest) | argument 2 -> property Item3 of return (normal) | true | +| System.Tuple<,,,,,,,>.Tuple(T1, T2, T3, T4, T5, T6, T7, TRest) | argument 3 -> property Item4 of return (normal) | true | +| System.Tuple<,,,,,,,>.Tuple(T1, T2, T3, T4, T5, T6, T7, TRest) | argument 4 -> property Item5 of return (normal) | true | +| System.Tuple<,,,,,,,>.Tuple(T1, T2, T3, T4, T5, T6, T7, TRest) | argument 5 -> property Item6 of return (normal) | true | +| System.Tuple<,,,,,,,>.Tuple(T1, T2, T3, T4, T5, T6, T7, TRest) | argument 6 -> property Item7 of return (normal) | true | +| System.Tuple<,,,,,,,>.get_Item(int) | property Item1 of argument -1 -> return (normal) | true | +| System.Tuple<,,,,,,,>.get_Item(int) | property Item2 of argument -1 -> return (normal) | true | +| System.Tuple<,,,,,,,>.get_Item(int) | property Item3 of argument -1 -> return (normal) | true | +| System.Tuple<,,,,,,,>.get_Item(int) | property Item4 of argument -1 -> return (normal) | true | +| System.Tuple<,,,,,,,>.get_Item(int) | property Item5 of argument -1 -> return (normal) | true | +| System.Tuple<,,,,,,,>.get_Item(int) | property Item6 of argument -1 -> return (normal) | true | +| System.Tuple<,,,,,,,>.get_Item(int) | property Item7 of argument -1 -> return (normal) | true | +| System.Tuple<,,,,,,>.Tuple(T1, T2, T3, T4, T5, T6, T7) | argument 0 -> property Item1 of return (normal) | true | +| System.Tuple<,,,,,,>.Tuple(T1, T2, T3, T4, T5, T6, T7) | argument 1 -> property Item2 of return (normal) | true | +| System.Tuple<,,,,,,>.Tuple(T1, T2, T3, T4, T5, T6, T7) | argument 2 -> property Item3 of return (normal) | true | +| System.Tuple<,,,,,,>.Tuple(T1, T2, T3, T4, T5, T6, T7) | argument 3 -> property Item4 of return (normal) | true | +| System.Tuple<,,,,,,>.Tuple(T1, T2, T3, T4, T5, T6, T7) | argument 4 -> property Item5 of return (normal) | true | +| System.Tuple<,,,,,,>.Tuple(T1, T2, T3, T4, T5, T6, T7) | argument 5 -> property Item6 of return (normal) | true | +| System.Tuple<,,,,,,>.Tuple(T1, T2, T3, T4, T5, T6, T7) | argument 6 -> property Item7 of return (normal) | true | +| System.Tuple<,,,,,,>.get_Item(int) | property Item1 of argument -1 -> return (normal) | true | +| System.Tuple<,,,,,,>.get_Item(int) | property Item2 of argument -1 -> return (normal) | true | +| System.Tuple<,,,,,,>.get_Item(int) | property Item3 of argument -1 -> return (normal) | true | +| System.Tuple<,,,,,,>.get_Item(int) | property Item4 of argument -1 -> return (normal) | true | +| System.Tuple<,,,,,,>.get_Item(int) | property Item5 of argument -1 -> return (normal) | true | +| System.Tuple<,,,,,,>.get_Item(int) | property Item6 of argument -1 -> return (normal) | true | +| System.Tuple<,,,,,,>.get_Item(int) | property Item7 of argument -1 -> return (normal) | true | +| System.Tuple<,,,,,>.Tuple(T1, T2, T3, T4, T5, T6) | argument 0 -> property Item1 of return (normal) | true | +| System.Tuple<,,,,,>.Tuple(T1, T2, T3, T4, T5, T6) | argument 1 -> property Item2 of return (normal) | true | +| System.Tuple<,,,,,>.Tuple(T1, T2, T3, T4, T5, T6) | argument 2 -> property Item3 of return (normal) | true | +| System.Tuple<,,,,,>.Tuple(T1, T2, T3, T4, T5, T6) | argument 3 -> property Item4 of return (normal) | true | +| System.Tuple<,,,,,>.Tuple(T1, T2, T3, T4, T5, T6) | argument 4 -> property Item5 of return (normal) | true | +| System.Tuple<,,,,,>.Tuple(T1, T2, T3, T4, T5, T6) | argument 5 -> property Item6 of return (normal) | true | +| System.Tuple<,,,,,>.get_Item(int) | property Item1 of argument -1 -> return (normal) | true | +| System.Tuple<,,,,,>.get_Item(int) | property Item2 of argument -1 -> return (normal) | true | +| System.Tuple<,,,,,>.get_Item(int) | property Item3 of argument -1 -> return (normal) | true | +| System.Tuple<,,,,,>.get_Item(int) | property Item4 of argument -1 -> return (normal) | true | +| System.Tuple<,,,,,>.get_Item(int) | property Item5 of argument -1 -> return (normal) | true | +| System.Tuple<,,,,,>.get_Item(int) | property Item6 of argument -1 -> return (normal) | true | +| System.Tuple<,,,,>.Tuple(T1, T2, T3, T4, T5) | argument 0 -> property Item1 of return (normal) | true | +| System.Tuple<,,,,>.Tuple(T1, T2, T3, T4, T5) | argument 1 -> property Item2 of return (normal) | true | +| System.Tuple<,,,,>.Tuple(T1, T2, T3, T4, T5) | argument 2 -> property Item3 of return (normal) | true | +| System.Tuple<,,,,>.Tuple(T1, T2, T3, T4, T5) | argument 3 -> property Item4 of return (normal) | true | +| System.Tuple<,,,,>.Tuple(T1, T2, T3, T4, T5) | argument 4 -> property Item5 of return (normal) | true | +| System.Tuple<,,,,>.get_Item(int) | property Item1 of argument -1 -> return (normal) | true | +| System.Tuple<,,,,>.get_Item(int) | property Item2 of argument -1 -> return (normal) | true | +| System.Tuple<,,,,>.get_Item(int) | property Item3 of argument -1 -> return (normal) | true | +| System.Tuple<,,,,>.get_Item(int) | property Item4 of argument -1 -> return (normal) | true | +| System.Tuple<,,,,>.get_Item(int) | property Item5 of argument -1 -> return (normal) | true | +| System.Tuple<,,,>.Tuple(T1, T2, T3, T4) | argument 0 -> property Item1 of return (normal) | true | +| System.Tuple<,,,>.Tuple(T1, T2, T3, T4) | argument 1 -> property Item2 of return (normal) | true | +| System.Tuple<,,,>.Tuple(T1, T2, T3, T4) | argument 2 -> property Item3 of return (normal) | true | +| System.Tuple<,,,>.Tuple(T1, T2, T3, T4) | argument 3 -> property Item4 of return (normal) | true | +| System.Tuple<,,,>.get_Item(int) | property Item1 of argument -1 -> return (normal) | true | +| System.Tuple<,,,>.get_Item(int) | property Item2 of argument -1 -> return (normal) | true | +| System.Tuple<,,,>.get_Item(int) | property Item3 of argument -1 -> return (normal) | true | +| System.Tuple<,,,>.get_Item(int) | property Item4 of argument -1 -> return (normal) | true | +| System.Tuple<,,>.Tuple(T1, T2, T3) | argument 0 -> property Item1 of return (normal) | true | +| System.Tuple<,,>.Tuple(T1, T2, T3) | argument 1 -> property Item2 of return (normal) | true | +| System.Tuple<,,>.Tuple(T1, T2, T3) | argument 2 -> property Item3 of return (normal) | true | +| System.Tuple<,,>.get_Item(int) | property Item1 of argument -1 -> return (normal) | true | +| System.Tuple<,,>.get_Item(int) | property Item2 of argument -1 -> return (normal) | true | +| System.Tuple<,,>.get_Item(int) | property Item3 of argument -1 -> return (normal) | true | +| System.Tuple<,>.Tuple(T1, T2) | argument 0 -> property Item1 of return (normal) | true | +| System.Tuple<,>.Tuple(T1, T2) | argument 1 -> property Item2 of return (normal) | true | +| System.Tuple<,>.get_Item(int) | property Item1 of argument -1 -> return (normal) | true | +| System.Tuple<,>.get_Item(int) | property Item2 of argument -1 -> return (normal) | true | +| System.Tuple<>.Tuple(T1) | argument 0 -> property Item1 of return (normal) | true | +| System.Tuple<>.get_Item(int) | property Item1 of argument -1 -> return (normal) | true | +| System.TupleExtensions.Deconstruct(Tuple>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13, out T14, out T15, out T16, out T17, out T18, out T19, out T20, out T21) | property Item1 of argument 0 -> return (out parameter 1) | true | +| System.TupleExtensions.Deconstruct(Tuple>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13, out T14, out T15, out T16, out T17, out T18, out T19, out T20, out T21) | property Item2 of argument 0 -> return (out parameter 2) | true | +| System.TupleExtensions.Deconstruct(Tuple>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13, out T14, out T15, out T16, out T17, out T18, out T19, out T20, out T21) | property Item3 of argument 0 -> return (out parameter 3) | true | +| System.TupleExtensions.Deconstruct(Tuple>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13, out T14, out T15, out T16, out T17, out T18, out T19, out T20, out T21) | property Item4 of argument 0 -> return (out parameter 4) | true | +| System.TupleExtensions.Deconstruct(Tuple>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13, out T14, out T15, out T16, out T17, out T18, out T19, out T20, out T21) | property Item5 of argument 0 -> return (out parameter 5) | true | +| System.TupleExtensions.Deconstruct(Tuple>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13, out T14, out T15, out T16, out T17, out T18, out T19, out T20, out T21) | property Item6 of argument 0 -> return (out parameter 6) | true | +| System.TupleExtensions.Deconstruct(Tuple>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13, out T14, out T15, out T16, out T17, out T18, out T19, out T20, out T21) | property Item7 of argument 0 -> return (out parameter 7) | true | +| System.TupleExtensions.Deconstruct(Tuple>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13, out T14, out T15, out T16, out T17, out T18, out T19, out T20) | property Item1 of argument 0 -> return (out parameter 1) | true | +| System.TupleExtensions.Deconstruct(Tuple>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13, out T14, out T15, out T16, out T17, out T18, out T19, out T20) | property Item2 of argument 0 -> return (out parameter 2) | true | +| System.TupleExtensions.Deconstruct(Tuple>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13, out T14, out T15, out T16, out T17, out T18, out T19, out T20) | property Item3 of argument 0 -> return (out parameter 3) | true | +| System.TupleExtensions.Deconstruct(Tuple>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13, out T14, out T15, out T16, out T17, out T18, out T19, out T20) | property Item4 of argument 0 -> return (out parameter 4) | true | +| System.TupleExtensions.Deconstruct(Tuple>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13, out T14, out T15, out T16, out T17, out T18, out T19, out T20) | property Item5 of argument 0 -> return (out parameter 5) | true | +| System.TupleExtensions.Deconstruct(Tuple>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13, out T14, out T15, out T16, out T17, out T18, out T19, out T20) | property Item6 of argument 0 -> return (out parameter 6) | true | +| System.TupleExtensions.Deconstruct(Tuple>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13, out T14, out T15, out T16, out T17, out T18, out T19, out T20) | property Item7 of argument 0 -> return (out parameter 7) | true | +| System.TupleExtensions.Deconstruct(Tuple>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13, out T14, out T15, out T16, out T17, out T18, out T19) | property Item1 of argument 0 -> return (out parameter 1) | true | +| System.TupleExtensions.Deconstruct(Tuple>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13, out T14, out T15, out T16, out T17, out T18, out T19) | property Item2 of argument 0 -> return (out parameter 2) | true | +| System.TupleExtensions.Deconstruct(Tuple>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13, out T14, out T15, out T16, out T17, out T18, out T19) | property Item3 of argument 0 -> return (out parameter 3) | true | +| System.TupleExtensions.Deconstruct(Tuple>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13, out T14, out T15, out T16, out T17, out T18, out T19) | property Item4 of argument 0 -> return (out parameter 4) | true | +| System.TupleExtensions.Deconstruct(Tuple>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13, out T14, out T15, out T16, out T17, out T18, out T19) | property Item5 of argument 0 -> return (out parameter 5) | true | +| System.TupleExtensions.Deconstruct(Tuple>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13, out T14, out T15, out T16, out T17, out T18, out T19) | property Item6 of argument 0 -> return (out parameter 6) | true | +| System.TupleExtensions.Deconstruct(Tuple>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13, out T14, out T15, out T16, out T17, out T18, out T19) | property Item7 of argument 0 -> return (out parameter 7) | true | +| System.TupleExtensions.Deconstruct(Tuple>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13, out T14, out T15, out T16, out T17, out T18) | property Item1 of argument 0 -> return (out parameter 1) | true | +| System.TupleExtensions.Deconstruct(Tuple>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13, out T14, out T15, out T16, out T17, out T18) | property Item2 of argument 0 -> return (out parameter 2) | true | +| System.TupleExtensions.Deconstruct(Tuple>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13, out T14, out T15, out T16, out T17, out T18) | property Item3 of argument 0 -> return (out parameter 3) | true | +| System.TupleExtensions.Deconstruct(Tuple>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13, out T14, out T15, out T16, out T17, out T18) | property Item4 of argument 0 -> return (out parameter 4) | true | +| System.TupleExtensions.Deconstruct(Tuple>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13, out T14, out T15, out T16, out T17, out T18) | property Item5 of argument 0 -> return (out parameter 5) | true | +| System.TupleExtensions.Deconstruct(Tuple>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13, out T14, out T15, out T16, out T17, out T18) | property Item6 of argument 0 -> return (out parameter 6) | true | +| System.TupleExtensions.Deconstruct(Tuple>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13, out T14, out T15, out T16, out T17, out T18) | property Item7 of argument 0 -> return (out parameter 7) | true | +| System.TupleExtensions.Deconstruct(Tuple>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13, out T14, out T15, out T16, out T17) | property Item1 of argument 0 -> return (out parameter 1) | true | +| System.TupleExtensions.Deconstruct(Tuple>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13, out T14, out T15, out T16, out T17) | property Item2 of argument 0 -> return (out parameter 2) | true | +| System.TupleExtensions.Deconstruct(Tuple>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13, out T14, out T15, out T16, out T17) | property Item3 of argument 0 -> return (out parameter 3) | true | +| System.TupleExtensions.Deconstruct(Tuple>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13, out T14, out T15, out T16, out T17) | property Item4 of argument 0 -> return (out parameter 4) | true | +| System.TupleExtensions.Deconstruct(Tuple>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13, out T14, out T15, out T16, out T17) | property Item5 of argument 0 -> return (out parameter 5) | true | +| System.TupleExtensions.Deconstruct(Tuple>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13, out T14, out T15, out T16, out T17) | property Item6 of argument 0 -> return (out parameter 6) | true | +| System.TupleExtensions.Deconstruct(Tuple>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13, out T14, out T15, out T16, out T17) | property Item7 of argument 0 -> return (out parameter 7) | true | +| System.TupleExtensions.Deconstruct(Tuple>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13, out T14, out T15, out T16) | property Item1 of argument 0 -> return (out parameter 1) | true | +| System.TupleExtensions.Deconstruct(Tuple>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13, out T14, out T15, out T16) | property Item2 of argument 0 -> return (out parameter 2) | true | +| System.TupleExtensions.Deconstruct(Tuple>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13, out T14, out T15, out T16) | property Item3 of argument 0 -> return (out parameter 3) | true | +| System.TupleExtensions.Deconstruct(Tuple>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13, out T14, out T15, out T16) | property Item4 of argument 0 -> return (out parameter 4) | true | +| System.TupleExtensions.Deconstruct(Tuple>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13, out T14, out T15, out T16) | property Item5 of argument 0 -> return (out parameter 5) | true | +| System.TupleExtensions.Deconstruct(Tuple>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13, out T14, out T15, out T16) | property Item6 of argument 0 -> return (out parameter 6) | true | +| System.TupleExtensions.Deconstruct(Tuple>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13, out T14, out T15, out T16) | property Item7 of argument 0 -> return (out parameter 7) | true | +| System.TupleExtensions.Deconstruct(Tuple>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13, out T14, out T15) | property Item1 of argument 0 -> return (out parameter 1) | true | +| System.TupleExtensions.Deconstruct(Tuple>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13, out T14, out T15) | property Item2 of argument 0 -> return (out parameter 2) | true | +| System.TupleExtensions.Deconstruct(Tuple>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13, out T14, out T15) | property Item3 of argument 0 -> return (out parameter 3) | true | +| System.TupleExtensions.Deconstruct(Tuple>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13, out T14, out T15) | property Item4 of argument 0 -> return (out parameter 4) | true | +| System.TupleExtensions.Deconstruct(Tuple>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13, out T14, out T15) | property Item5 of argument 0 -> return (out parameter 5) | true | +| System.TupleExtensions.Deconstruct(Tuple>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13, out T14, out T15) | property Item6 of argument 0 -> return (out parameter 6) | true | +| System.TupleExtensions.Deconstruct(Tuple>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13, out T14, out T15) | property Item7 of argument 0 -> return (out parameter 7) | true | +| System.TupleExtensions.Deconstruct(Tuple>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13, out T14) | property Item1 of argument 0 -> return (out parameter 1) | true | +| System.TupleExtensions.Deconstruct(Tuple>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13, out T14) | property Item2 of argument 0 -> return (out parameter 2) | true | +| System.TupleExtensions.Deconstruct(Tuple>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13, out T14) | property Item3 of argument 0 -> return (out parameter 3) | true | +| System.TupleExtensions.Deconstruct(Tuple>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13, out T14) | property Item4 of argument 0 -> return (out parameter 4) | true | +| System.TupleExtensions.Deconstruct(Tuple>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13, out T14) | property Item5 of argument 0 -> return (out parameter 5) | true | +| System.TupleExtensions.Deconstruct(Tuple>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13, out T14) | property Item6 of argument 0 -> return (out parameter 6) | true | +| System.TupleExtensions.Deconstruct(Tuple>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13, out T14) | property Item7 of argument 0 -> return (out parameter 7) | true | +| System.TupleExtensions.Deconstruct(Tuple>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13) | property Item1 of argument 0 -> return (out parameter 1) | true | +| System.TupleExtensions.Deconstruct(Tuple>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13) | property Item2 of argument 0 -> return (out parameter 2) | true | +| System.TupleExtensions.Deconstruct(Tuple>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13) | property Item3 of argument 0 -> return (out parameter 3) | true | +| System.TupleExtensions.Deconstruct(Tuple>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13) | property Item4 of argument 0 -> return (out parameter 4) | true | +| System.TupleExtensions.Deconstruct(Tuple>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13) | property Item5 of argument 0 -> return (out parameter 5) | true | +| System.TupleExtensions.Deconstruct(Tuple>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13) | property Item6 of argument 0 -> return (out parameter 6) | true | +| System.TupleExtensions.Deconstruct(Tuple>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13) | property Item7 of argument 0 -> return (out parameter 7) | true | +| System.TupleExtensions.Deconstruct(Tuple>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12) | property Item1 of argument 0 -> return (out parameter 1) | true | +| System.TupleExtensions.Deconstruct(Tuple>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12) | property Item2 of argument 0 -> return (out parameter 2) | true | +| System.TupleExtensions.Deconstruct(Tuple>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12) | property Item3 of argument 0 -> return (out parameter 3) | true | +| System.TupleExtensions.Deconstruct(Tuple>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12) | property Item4 of argument 0 -> return (out parameter 4) | true | +| System.TupleExtensions.Deconstruct(Tuple>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12) | property Item5 of argument 0 -> return (out parameter 5) | true | +| System.TupleExtensions.Deconstruct(Tuple>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12) | property Item6 of argument 0 -> return (out parameter 6) | true | +| System.TupleExtensions.Deconstruct(Tuple>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12) | property Item7 of argument 0 -> return (out parameter 7) | true | +| System.TupleExtensions.Deconstruct(Tuple>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11) | property Item1 of argument 0 -> return (out parameter 1) | true | +| System.TupleExtensions.Deconstruct(Tuple>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11) | property Item2 of argument 0 -> return (out parameter 2) | true | +| System.TupleExtensions.Deconstruct(Tuple>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11) | property Item3 of argument 0 -> return (out parameter 3) | true | +| System.TupleExtensions.Deconstruct(Tuple>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11) | property Item4 of argument 0 -> return (out parameter 4) | true | +| System.TupleExtensions.Deconstruct(Tuple>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11) | property Item5 of argument 0 -> return (out parameter 5) | true | +| System.TupleExtensions.Deconstruct(Tuple>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11) | property Item6 of argument 0 -> return (out parameter 6) | true | +| System.TupleExtensions.Deconstruct(Tuple>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11) | property Item7 of argument 0 -> return (out parameter 7) | true | +| System.TupleExtensions.Deconstruct(Tuple>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10) | property Item1 of argument 0 -> return (out parameter 1) | true | +| System.TupleExtensions.Deconstruct(Tuple>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10) | property Item2 of argument 0 -> return (out parameter 2) | true | +| System.TupleExtensions.Deconstruct(Tuple>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10) | property Item3 of argument 0 -> return (out parameter 3) | true | +| System.TupleExtensions.Deconstruct(Tuple>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10) | property Item4 of argument 0 -> return (out parameter 4) | true | +| System.TupleExtensions.Deconstruct(Tuple>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10) | property Item5 of argument 0 -> return (out parameter 5) | true | +| System.TupleExtensions.Deconstruct(Tuple>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10) | property Item6 of argument 0 -> return (out parameter 6) | true | +| System.TupleExtensions.Deconstruct(Tuple>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10) | property Item7 of argument 0 -> return (out parameter 7) | true | +| System.TupleExtensions.Deconstruct(Tuple>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9) | property Item1 of argument 0 -> return (out parameter 1) | true | +| System.TupleExtensions.Deconstruct(Tuple>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9) | property Item2 of argument 0 -> return (out parameter 2) | true | +| System.TupleExtensions.Deconstruct(Tuple>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9) | property Item3 of argument 0 -> return (out parameter 3) | true | +| System.TupleExtensions.Deconstruct(Tuple>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9) | property Item4 of argument 0 -> return (out parameter 4) | true | +| System.TupleExtensions.Deconstruct(Tuple>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9) | property Item5 of argument 0 -> return (out parameter 5) | true | +| System.TupleExtensions.Deconstruct(Tuple>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9) | property Item6 of argument 0 -> return (out parameter 6) | true | +| System.TupleExtensions.Deconstruct(Tuple>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9) | property Item7 of argument 0 -> return (out parameter 7) | true | +| System.TupleExtensions.Deconstruct(Tuple>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8) | property Item1 of argument 0 -> return (out parameter 1) | true | +| System.TupleExtensions.Deconstruct(Tuple>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8) | property Item2 of argument 0 -> return (out parameter 2) | true | +| System.TupleExtensions.Deconstruct(Tuple>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8) | property Item3 of argument 0 -> return (out parameter 3) | true | +| System.TupleExtensions.Deconstruct(Tuple>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8) | property Item4 of argument 0 -> return (out parameter 4) | true | +| System.TupleExtensions.Deconstruct(Tuple>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8) | property Item5 of argument 0 -> return (out parameter 5) | true | +| System.TupleExtensions.Deconstruct(Tuple>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8) | property Item6 of argument 0 -> return (out parameter 6) | true | +| System.TupleExtensions.Deconstruct(Tuple>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8) | property Item7 of argument 0 -> return (out parameter 7) | true | +| System.TupleExtensions.Deconstruct(Tuple, out T1, out T2, out T3, out T4, out T5, out T6, out T7) | property Item1 of argument 0 -> return (out parameter 1) | true | +| System.TupleExtensions.Deconstruct(Tuple, out T1, out T2, out T3, out T4, out T5, out T6, out T7) | property Item2 of argument 0 -> return (out parameter 2) | true | +| System.TupleExtensions.Deconstruct(Tuple, out T1, out T2, out T3, out T4, out T5, out T6, out T7) | property Item3 of argument 0 -> return (out parameter 3) | true | +| System.TupleExtensions.Deconstruct(Tuple, out T1, out T2, out T3, out T4, out T5, out T6, out T7) | property Item4 of argument 0 -> return (out parameter 4) | true | +| System.TupleExtensions.Deconstruct(Tuple, out T1, out T2, out T3, out T4, out T5, out T6, out T7) | property Item5 of argument 0 -> return (out parameter 5) | true | +| System.TupleExtensions.Deconstruct(Tuple, out T1, out T2, out T3, out T4, out T5, out T6, out T7) | property Item6 of argument 0 -> return (out parameter 6) | true | +| System.TupleExtensions.Deconstruct(Tuple, out T1, out T2, out T3, out T4, out T5, out T6, out T7) | property Item7 of argument 0 -> return (out parameter 7) | true | +| System.TupleExtensions.Deconstruct(Tuple, out T1, out T2, out T3, out T4, out T5, out T6) | property Item1 of argument 0 -> return (out parameter 1) | true | +| System.TupleExtensions.Deconstruct(Tuple, out T1, out T2, out T3, out T4, out T5, out T6) | property Item2 of argument 0 -> return (out parameter 2) | true | +| System.TupleExtensions.Deconstruct(Tuple, out T1, out T2, out T3, out T4, out T5, out T6) | property Item3 of argument 0 -> return (out parameter 3) | true | +| System.TupleExtensions.Deconstruct(Tuple, out T1, out T2, out T3, out T4, out T5, out T6) | property Item4 of argument 0 -> return (out parameter 4) | true | +| System.TupleExtensions.Deconstruct(Tuple, out T1, out T2, out T3, out T4, out T5, out T6) | property Item5 of argument 0 -> return (out parameter 5) | true | +| System.TupleExtensions.Deconstruct(Tuple, out T1, out T2, out T3, out T4, out T5, out T6) | property Item6 of argument 0 -> return (out parameter 6) | true | +| System.TupleExtensions.Deconstruct(Tuple, out T1, out T2, out T3, out T4, out T5) | property Item1 of argument 0 -> return (out parameter 1) | true | +| System.TupleExtensions.Deconstruct(Tuple, out T1, out T2, out T3, out T4, out T5) | property Item2 of argument 0 -> return (out parameter 2) | true | +| System.TupleExtensions.Deconstruct(Tuple, out T1, out T2, out T3, out T4, out T5) | property Item3 of argument 0 -> return (out parameter 3) | true | +| System.TupleExtensions.Deconstruct(Tuple, out T1, out T2, out T3, out T4, out T5) | property Item4 of argument 0 -> return (out parameter 4) | true | +| System.TupleExtensions.Deconstruct(Tuple, out T1, out T2, out T3, out T4, out T5) | property Item5 of argument 0 -> return (out parameter 5) | true | +| System.TupleExtensions.Deconstruct(Tuple, out T1, out T2, out T3, out T4) | property Item1 of argument 0 -> return (out parameter 1) | true | +| System.TupleExtensions.Deconstruct(Tuple, out T1, out T2, out T3, out T4) | property Item2 of argument 0 -> return (out parameter 2) | true | +| System.TupleExtensions.Deconstruct(Tuple, out T1, out T2, out T3, out T4) | property Item3 of argument 0 -> return (out parameter 3) | true | +| System.TupleExtensions.Deconstruct(Tuple, out T1, out T2, out T3, out T4) | property Item4 of argument 0 -> return (out parameter 4) | true | +| System.TupleExtensions.Deconstruct(Tuple, out T1, out T2, out T3) | property Item1 of argument 0 -> return (out parameter 1) | true | +| System.TupleExtensions.Deconstruct(Tuple, out T1, out T2, out T3) | property Item2 of argument 0 -> return (out parameter 2) | true | +| System.TupleExtensions.Deconstruct(Tuple, out T1, out T2, out T3) | property Item3 of argument 0 -> return (out parameter 3) | true | +| System.TupleExtensions.Deconstruct(Tuple, out T1, out T2) | property Item1 of argument 0 -> return (out parameter 1) | true | +| System.TupleExtensions.Deconstruct(Tuple, out T1, out T2) | property Item2 of argument 0 -> return (out parameter 2) | true | +| System.TupleExtensions.Deconstruct(Tuple, out T1) | property Item1 of argument 0 -> return (out parameter 1) | true | +| System.Uri.ToString() | argument -1 -> return (normal) | false | +| System.Uri.Uri(string) | argument 0 -> return (normal) | false | +| System.Uri.Uri(string, UriKind) | argument 0 -> return (normal) | false | +| System.Uri.Uri(string, bool) | argument 0 -> return (normal) | false | +| System.Uri.get_OriginalString() | argument -1 -> return (normal) | false | +| System.Uri.get_PathAndQuery() | argument -1 -> return (normal) | false | +| System.Uri.get_Query() | argument -1 -> return (normal) | false | +| System.ValueTuple<,,,,,,,>.ValueTuple(T1, T2, T3, T4, T5, T6, T7, TRest) | argument 0 -> field Item1 of return (normal) | true | +| System.ValueTuple<,,,,,,,>.ValueTuple(T1, T2, T3, T4, T5, T6, T7, TRest) | argument 1 -> field Item2 of return (normal) | true | +| System.ValueTuple<,,,,,,,>.ValueTuple(T1, T2, T3, T4, T5, T6, T7, TRest) | argument 2 -> field Item3 of return (normal) | true | +| System.ValueTuple<,,,,,,,>.ValueTuple(T1, T2, T3, T4, T5, T6, T7, TRest) | argument 3 -> field Item4 of return (normal) | true | +| System.ValueTuple<,,,,,,,>.ValueTuple(T1, T2, T3, T4, T5, T6, T7, TRest) | argument 4 -> field Item5 of return (normal) | true | +| System.ValueTuple<,,,,,,,>.ValueTuple(T1, T2, T3, T4, T5, T6, T7, TRest) | argument 5 -> field Item6 of return (normal) | true | +| System.ValueTuple<,,,,,,,>.ValueTuple(T1, T2, T3, T4, T5, T6, T7, TRest) | argument 6 -> field Item7 of return (normal) | true | +| System.ValueTuple<,,,,,,,>.get_Item(int) | field Item1 of argument -1 -> return (normal) | true | +| System.ValueTuple<,,,,,,,>.get_Item(int) | field Item2 of argument -1 -> return (normal) | true | +| System.ValueTuple<,,,,,,,>.get_Item(int) | field Item3 of argument -1 -> return (normal) | true | +| System.ValueTuple<,,,,,,,>.get_Item(int) | field Item4 of argument -1 -> return (normal) | true | +| System.ValueTuple<,,,,,,,>.get_Item(int) | field Item5 of argument -1 -> return (normal) | true | +| System.ValueTuple<,,,,,,,>.get_Item(int) | field Item6 of argument -1 -> return (normal) | true | +| System.ValueTuple<,,,,,,,>.get_Item(int) | field Item7 of argument -1 -> return (normal) | true | +| System.Web.HttpCookie.get_Value() | argument -1 -> return (normal) | false | +| System.Web.HttpCookie.get_Values() | argument -1 -> return (normal) | false | +| System.Web.HttpServerUtility.UrlEncode(string) | argument 0 -> return (normal) | false | +| System.Web.HttpUtility.HtmlAttributeEncode(string) | argument 0 -> return (normal) | false | +| System.Web.HttpUtility.HtmlEncode(object) | argument 0 -> return (normal) | false | +| System.Web.HttpUtility.HtmlEncode(string) | argument 0 -> return (normal) | false | +| System.Web.HttpUtility.UrlEncode(string) | argument 0 -> return (normal) | false | +| System.Web.UI.WebControls.TextBox.get_Text() | argument -1 -> return (normal) | false | diff --git a/csharp/ql/test/library-tests/dataflow/library/FlowSummaries.ql b/csharp/ql/test/library-tests/dataflow/library/FlowSummaries.ql index 12eafa32a0f..0ff3ce7de04 100644 --- a/csharp/ql/test/library-tests/dataflow/library/FlowSummaries.ql +++ b/csharp/ql/test/library-tests/dataflow/library/FlowSummaries.ql @@ -1,6 +1,8 @@ import semmle.code.csharp.dataflow.FlowSummary -import semmle.code.csharp.dataflow.FlowSummary::TestOutput +import semmle.code.csharp.dataflow.internal.FlowSummaryImpl::Private::TestOutput -private class IncludeEFSummarizedCallable extends RelevantSummarizedCallable { - IncludeEFSummarizedCallable() { this instanceof SummarizedCallable } +private class IncludeSummarizedCallable extends RelevantSummarizedCallable { + IncludeSummarizedCallable() { this instanceof SummarizedCallable } + + override string getFullString() { result = this.(Callable).getQualifiedNameWithTypes() } } diff --git a/csharp/ql/test/library-tests/dataflow/local/DataFlowStep.ql b/csharp/ql/test/library-tests/dataflow/local/DataFlowStep.ql index f1fc98c459b..8f820cfea48 100644 --- a/csharp/ql/test/library-tests/dataflow/local/DataFlowStep.ql +++ b/csharp/ql/test/library-tests/dataflow/local/DataFlowStep.ql @@ -1,5 +1,5 @@ import csharp from DataFlow::Node pred, DataFlow::Node succ -where DataFlow::localFlowStep(pred, succ) +where not pred.asExpr().fromLibrary() and DataFlow::localFlowStep(pred, succ) select pred, succ diff --git a/csharp/ql/test/library-tests/dataflow/local/TaintTrackingStep.ql b/csharp/ql/test/library-tests/dataflow/local/TaintTrackingStep.ql index 1866acfcda8..ffbdcd4dddf 100644 --- a/csharp/ql/test/library-tests/dataflow/local/TaintTrackingStep.ql +++ b/csharp/ql/test/library-tests/dataflow/local/TaintTrackingStep.ql @@ -1,5 +1,7 @@ import csharp from DataFlow::Node pred, DataFlow::Node succ -where TaintTracking::localTaintStep(pred, succ) +where + not pred.asExpr().fromLibrary() and + TaintTracking::localTaintStep(pred, succ) select pred, succ diff --git a/csharp/ql/test/library-tests/dataflow/modulusanalysis/ModulusAnalysis.ql b/csharp/ql/test/library-tests/dataflow/modulusanalysis/ModulusAnalysis.ql index b07608ea009..02ffbc535ce 100644 --- a/csharp/ql/test/library-tests/dataflow/modulusanalysis/ModulusAnalysis.ql +++ b/csharp/ql/test/library-tests/dataflow/modulusanalysis/ModulusAnalysis.ql @@ -4,5 +4,7 @@ import semmle.code.csharp.dataflow.ModulusAnalysis import semmle.code.csharp.dataflow.Bound from ControlFlow::Nodes::ExprNode e, Bound b, int delta, int mod -where exprModulus(e, b, delta, mod) +where + not e.getExpr().fromLibrary() and + exprModulus(e, b, delta, mod) select e, b.toString(), delta, mod diff --git a/csharp/ql/test/library-tests/dataflow/signanalysis/SignAnalysis.ql b/csharp/ql/test/library-tests/dataflow/signanalysis/SignAnalysis.ql index 5427cdc631d..650d0f6bed4 100644 --- a/csharp/ql/test/library-tests/dataflow/signanalysis/SignAnalysis.ql +++ b/csharp/ql/test/library-tests/dataflow/signanalysis/SignAnalysis.ql @@ -18,4 +18,5 @@ string getASignString(ControlFlow::Nodes::ExprNode e) { } from ControlFlow::Nodes::ExprNode e +where not e.getExpr().fromLibrary() select e, strictconcat(string s | s = getASignString(e) | s, " ") diff --git a/csharp/ql/test/library-tests/dataflow/tuples/DataFlowStep.ql b/csharp/ql/test/library-tests/dataflow/tuples/DataFlowStep.ql index f1fc98c459b..8f820cfea48 100644 --- a/csharp/ql/test/library-tests/dataflow/tuples/DataFlowStep.ql +++ b/csharp/ql/test/library-tests/dataflow/tuples/DataFlowStep.ql @@ -1,5 +1,5 @@ import csharp from DataFlow::Node pred, DataFlow::Node succ -where DataFlow::localFlowStep(pred, succ) +where not pred.asExpr().fromLibrary() and DataFlow::localFlowStep(pred, succ) select pred, succ diff --git a/csharp/ql/test/library-tests/dataflow/tuples/Tuples.expected b/csharp/ql/test/library-tests/dataflow/tuples/Tuples.expected index 339c859a6ce..ae634781cd7 100644 --- a/csharp/ql/test/library-tests/dataflow/tuples/Tuples.expected +++ b/csharp/ql/test/library-tests/dataflow/tuples/Tuples.expected @@ -1,148 +1,148 @@ edges -| Tuples.cs:7:17:7:56 | (..., ...) [Item1] : String | Tuples.cs:8:9:8:23 | (..., ...) [Item1] : String | -| Tuples.cs:7:17:7:56 | (..., ...) [Item1] : String | Tuples.cs:13:9:13:19 | (..., ...) [Item1] : String | -| Tuples.cs:7:17:7:56 | (..., ...) [Item1] : String | Tuples.cs:18:9:18:22 | (..., ...) [Item1] : String | -| Tuples.cs:7:17:7:56 | (..., ...) [Item1] : String | Tuples.cs:23:14:23:14 | access to local variable x [Item1] : String | -| Tuples.cs:7:17:7:56 | (..., ...) [Item1] : String | Tuples.cs:24:14:24:14 | access to local variable x [Item1] : String | -| Tuples.cs:7:17:7:56 | (..., ...) [Item2, Item2] : String | Tuples.cs:8:9:8:23 | (..., ...) [Item2, Item2] : String | -| Tuples.cs:7:17:7:56 | (..., ...) [Item2, Item2] : String | Tuples.cs:13:9:13:19 | (..., ...) [Item2, Item2] : String | -| Tuples.cs:7:17:7:56 | (..., ...) [Item2, Item2] : String | Tuples.cs:18:9:18:22 | (..., ...) [Item2, Item2] : String | -| Tuples.cs:7:17:7:56 | (..., ...) [Item2, Item2] : String | Tuples.cs:26:14:26:14 | access to local variable x [Item2, Item2] : String | -| Tuples.cs:7:21:7:34 | "taint source" : String | Tuples.cs:7:17:7:56 | (..., ...) [Item1] : String | -| Tuples.cs:7:37:7:55 | (..., ...) [Item2] : String | Tuples.cs:7:17:7:56 | (..., ...) [Item2, Item2] : String | -| Tuples.cs:7:41:7:54 | "taint source" : String | Tuples.cs:7:37:7:55 | (..., ...) [Item2] : String | -| Tuples.cs:8:9:8:23 | (..., ...) [Item1] : String | Tuples.cs:8:9:8:27 | SSA def(a) : String | -| Tuples.cs:8:9:8:23 | (..., ...) [Item2, Item2] : String | Tuples.cs:8:9:8:23 | (..., ...) [Item2] : String | -| Tuples.cs:8:9:8:23 | (..., ...) [Item2] : String | Tuples.cs:8:9:8:27 | SSA def(c) : String | +| Tuples.cs:7:17:7:56 | (..., ...) [field Item1] : String | Tuples.cs:8:9:8:23 | (..., ...) [field Item1] : String | +| Tuples.cs:7:17:7:56 | (..., ...) [field Item1] : String | Tuples.cs:13:9:13:19 | (..., ...) [field Item1] : String | +| Tuples.cs:7:17:7:56 | (..., ...) [field Item1] : String | Tuples.cs:18:9:18:22 | (..., ...) [field Item1] : String | +| Tuples.cs:7:17:7:56 | (..., ...) [field Item1] : String | Tuples.cs:23:14:23:14 | access to local variable x [field Item1] : String | +| Tuples.cs:7:17:7:56 | (..., ...) [field Item1] : String | Tuples.cs:24:14:24:14 | access to local variable x [field Item1] : String | +| Tuples.cs:7:17:7:56 | (..., ...) [field Item2, field Item2] : String | Tuples.cs:8:9:8:23 | (..., ...) [field Item2, field Item2] : String | +| Tuples.cs:7:17:7:56 | (..., ...) [field Item2, field Item2] : String | Tuples.cs:13:9:13:19 | (..., ...) [field Item2, field Item2] : String | +| Tuples.cs:7:17:7:56 | (..., ...) [field Item2, field Item2] : String | Tuples.cs:18:9:18:22 | (..., ...) [field Item2, field Item2] : String | +| Tuples.cs:7:17:7:56 | (..., ...) [field Item2, field Item2] : String | Tuples.cs:26:14:26:14 | access to local variable x [field Item2, field Item2] : String | +| Tuples.cs:7:21:7:34 | "taint source" : String | Tuples.cs:7:17:7:56 | (..., ...) [field Item1] : String | +| Tuples.cs:7:37:7:55 | (..., ...) [field Item2] : String | Tuples.cs:7:17:7:56 | (..., ...) [field Item2, field Item2] : String | +| Tuples.cs:7:41:7:54 | "taint source" : String | Tuples.cs:7:37:7:55 | (..., ...) [field Item2] : String | +| Tuples.cs:8:9:8:23 | (..., ...) [field Item1] : String | Tuples.cs:8:9:8:27 | SSA def(a) : String | +| Tuples.cs:8:9:8:23 | (..., ...) [field Item2, field Item2] : String | Tuples.cs:8:9:8:23 | (..., ...) [field Item2] : String | +| Tuples.cs:8:9:8:23 | (..., ...) [field Item2] : String | Tuples.cs:8:9:8:27 | SSA def(c) : String | | Tuples.cs:8:9:8:27 | SSA def(a) : String | Tuples.cs:9:14:9:14 | access to local variable a | | Tuples.cs:8:9:8:27 | SSA def(c) : String | Tuples.cs:11:14:11:14 | access to local variable c | -| Tuples.cs:13:9:13:19 | (..., ...) [Item1] : String | Tuples.cs:13:9:13:23 | SSA def(a) : String | -| Tuples.cs:13:9:13:19 | (..., ...) [Item2, Item2] : String | Tuples.cs:13:13:13:18 | (..., ...) [Item2] : String | +| Tuples.cs:13:9:13:19 | (..., ...) [field Item1] : String | Tuples.cs:13:9:13:23 | SSA def(a) : String | +| Tuples.cs:13:9:13:19 | (..., ...) [field Item2, field Item2] : String | Tuples.cs:13:13:13:18 | (..., ...) [field Item2] : String | | Tuples.cs:13:9:13:23 | SSA def(a) : String | Tuples.cs:14:14:14:14 | access to local variable a | | Tuples.cs:13:9:13:23 | SSA def(c) : String | Tuples.cs:16:14:16:14 | access to local variable c | -| Tuples.cs:13:13:13:18 | (..., ...) [Item2] : String | Tuples.cs:13:9:13:23 | SSA def(c) : String | -| Tuples.cs:18:9:18:22 | (..., ...) [Item1] : String | Tuples.cs:18:9:18:26 | SSA def(p) : String | -| Tuples.cs:18:9:18:22 | (..., ...) [Item2, Item2] : String | Tuples.cs:18:9:18:26 | SSA def(q) [Item2] : String | +| Tuples.cs:13:13:13:18 | (..., ...) [field Item2] : String | Tuples.cs:13:9:13:23 | SSA def(c) : String | +| Tuples.cs:18:9:18:22 | (..., ...) [field Item1] : String | Tuples.cs:18:9:18:26 | SSA def(p) : String | +| Tuples.cs:18:9:18:22 | (..., ...) [field Item2, field Item2] : String | Tuples.cs:18:9:18:26 | SSA def(q) [field Item2] : String | | Tuples.cs:18:9:18:26 | SSA def(p) : String | Tuples.cs:19:14:19:14 | access to local variable p | -| Tuples.cs:18:9:18:26 | SSA def(q) [Item2] : String | Tuples.cs:21:14:21:14 | access to local variable q [Item2] : String | -| Tuples.cs:21:14:21:14 | access to local variable q [Item2] : String | Tuples.cs:21:14:21:20 | access to field Item2 | -| Tuples.cs:23:14:23:14 | access to local variable x [Item1] : String | Tuples.cs:23:14:23:20 | access to field Item1 | -| Tuples.cs:24:14:24:14 | access to local variable x [Item1] : String | Tuples.cs:24:14:24:16 | access to field Item1 | -| Tuples.cs:26:14:26:14 | access to local variable x [Item2, Item2] : String | Tuples.cs:26:14:26:20 | access to field Item2 [Item2] : String | -| Tuples.cs:26:14:26:20 | access to field Item2 [Item2] : String | Tuples.cs:26:14:26:26 | access to field Item2 | -| Tuples.cs:31:17:31:72 | (..., ...) [Item1] : String | Tuples.cs:32:14:32:14 | access to local variable x [Item1] : String | -| Tuples.cs:31:17:31:72 | (..., ...) [Item10] : String | Tuples.cs:34:14:34:14 | access to local variable x [Item10] : String | -| Tuples.cs:31:18:31:31 | "taint source" : String | Tuples.cs:31:17:31:72 | (..., ...) [Item1] : String | -| Tuples.cs:31:58:31:71 | "taint source" : String | Tuples.cs:31:17:31:72 | (..., ...) [Item10] : String | -| Tuples.cs:32:14:32:14 | access to local variable x [Item1] : String | Tuples.cs:32:14:32:20 | access to field Item1 | -| Tuples.cs:34:14:34:14 | access to local variable x [Item10] : String | Tuples.cs:34:14:34:21 | access to field Item10 | -| Tuples.cs:39:17:39:68 | (...) ... [Item1] : String | Tuples.cs:40:14:40:14 | access to local variable x [Item1] : String | -| Tuples.cs:39:47:39:68 | (..., ...) [Item1] : String | Tuples.cs:39:17:39:68 | (...) ... [Item1] : String | -| Tuples.cs:39:48:39:61 | "taint source" : String | Tuples.cs:39:47:39:68 | (..., ...) [Item1] : String | -| Tuples.cs:40:14:40:14 | access to local variable x [Item1] : String | Tuples.cs:40:14:40:20 | access to field Item1 | -| Tuples.cs:50:17:50:56 | (..., ...) [Item1] : String | Tuples.cs:53:18:53:57 | SSA def(t) [Item1] : String | -| Tuples.cs:50:17:50:56 | (..., ...) [Item1] : String | Tuples.cs:58:18:58:35 | (..., ...) [Item1] : String | -| Tuples.cs:50:17:50:56 | (..., ...) [Item1] : String | Tuples.cs:77:18:77:35 | (..., ...) [Item1] : String | -| Tuples.cs:50:17:50:56 | (..., ...) [Item2, Item2] : String | Tuples.cs:53:18:53:57 | SSA def(t) [Item2, Item2] : String | -| Tuples.cs:50:17:50:56 | (..., ...) [Item2, Item2] : String | Tuples.cs:58:18:58:35 | (..., ...) [Item2, Item2] : String | -| Tuples.cs:50:17:50:56 | (..., ...) [Item2, Item2] : String | Tuples.cs:77:18:77:35 | (..., ...) [Item2, Item2] : String | -| Tuples.cs:50:18:50:31 | "taint source" : String | Tuples.cs:50:17:50:56 | (..., ...) [Item1] : String | -| Tuples.cs:50:34:50:52 | (..., ...) [Item2] : String | Tuples.cs:50:17:50:56 | (..., ...) [Item2, Item2] : String | -| Tuples.cs:50:38:50:51 | "taint source" : String | Tuples.cs:50:34:50:52 | (..., ...) [Item2] : String | -| Tuples.cs:53:18:53:57 | SSA def(t) [Item1] : String | Tuples.cs:54:22:54:22 | access to local variable t [Item1] : String | -| Tuples.cs:53:18:53:57 | SSA def(t) [Item2, Item2] : String | Tuples.cs:55:22:55:22 | access to local variable t [Item2, Item2] : String | -| Tuples.cs:54:22:54:22 | access to local variable t [Item1] : String | Tuples.cs:54:22:54:28 | access to field Item1 | -| Tuples.cs:55:22:55:22 | access to local variable t [Item2, Item2] : String | Tuples.cs:55:22:55:28 | access to field Item2 [Item2] : String | -| Tuples.cs:55:22:55:28 | access to field Item2 [Item2] : String | Tuples.cs:55:22:55:34 | access to field Item2 | -| Tuples.cs:58:18:58:35 | (..., ...) [Item1] : String | Tuples.cs:58:23:58:23 | SSA def(a) : String | -| Tuples.cs:58:18:58:35 | (..., ...) [Item2, Item2] : String | Tuples.cs:58:18:58:35 | (..., ...) [Item2] : String | -| Tuples.cs:58:18:58:35 | (..., ...) [Item2] : String | Tuples.cs:58:30:58:30 | SSA def(c) : String | +| Tuples.cs:18:9:18:26 | SSA def(q) [field Item2] : String | Tuples.cs:21:14:21:14 | access to local variable q [field Item2] : String | +| Tuples.cs:21:14:21:14 | access to local variable q [field Item2] : String | Tuples.cs:21:14:21:20 | access to field Item2 | +| Tuples.cs:23:14:23:14 | access to local variable x [field Item1] : String | Tuples.cs:23:14:23:20 | access to field Item1 | +| Tuples.cs:24:14:24:14 | access to local variable x [field Item1] : String | Tuples.cs:24:14:24:16 | access to field Item1 | +| Tuples.cs:26:14:26:14 | access to local variable x [field Item2, field Item2] : String | Tuples.cs:26:14:26:20 | access to field Item2 [field Item2] : String | +| Tuples.cs:26:14:26:20 | access to field Item2 [field Item2] : String | Tuples.cs:26:14:26:26 | access to field Item2 | +| Tuples.cs:31:17:31:72 | (..., ...) [field Item1] : String | Tuples.cs:32:14:32:14 | access to local variable x [field Item1] : String | +| Tuples.cs:31:17:31:72 | (..., ...) [field Item10] : String | Tuples.cs:34:14:34:14 | access to local variable x [field Item10] : String | +| Tuples.cs:31:18:31:31 | "taint source" : String | Tuples.cs:31:17:31:72 | (..., ...) [field Item1] : String | +| Tuples.cs:31:58:31:71 | "taint source" : String | Tuples.cs:31:17:31:72 | (..., ...) [field Item10] : String | +| Tuples.cs:32:14:32:14 | access to local variable x [field Item1] : String | Tuples.cs:32:14:32:20 | access to field Item1 | +| Tuples.cs:34:14:34:14 | access to local variable x [field Item10] : String | Tuples.cs:34:14:34:21 | access to field Item10 | +| Tuples.cs:39:17:39:68 | (...) ... [field Item1] : String | Tuples.cs:40:14:40:14 | access to local variable x [field Item1] : String | +| Tuples.cs:39:47:39:68 | (..., ...) [field Item1] : String | Tuples.cs:39:17:39:68 | (...) ... [field Item1] : String | +| Tuples.cs:39:48:39:61 | "taint source" : String | Tuples.cs:39:47:39:68 | (..., ...) [field Item1] : String | +| Tuples.cs:40:14:40:14 | access to local variable x [field Item1] : String | Tuples.cs:40:14:40:20 | access to field Item1 | +| Tuples.cs:50:17:50:56 | (..., ...) [field Item1] : String | Tuples.cs:53:18:53:57 | SSA def(t) [field Item1] : String | +| Tuples.cs:50:17:50:56 | (..., ...) [field Item1] : String | Tuples.cs:58:18:58:35 | (..., ...) [field Item1] : String | +| Tuples.cs:50:17:50:56 | (..., ...) [field Item1] : String | Tuples.cs:77:18:77:35 | (..., ...) [field Item1] : String | +| Tuples.cs:50:17:50:56 | (..., ...) [field Item2, field Item2] : String | Tuples.cs:53:18:53:57 | SSA def(t) [field Item2, field Item2] : String | +| Tuples.cs:50:17:50:56 | (..., ...) [field Item2, field Item2] : String | Tuples.cs:58:18:58:35 | (..., ...) [field Item2, field Item2] : String | +| Tuples.cs:50:17:50:56 | (..., ...) [field Item2, field Item2] : String | Tuples.cs:77:18:77:35 | (..., ...) [field Item2, field Item2] : String | +| Tuples.cs:50:18:50:31 | "taint source" : String | Tuples.cs:50:17:50:56 | (..., ...) [field Item1] : String | +| Tuples.cs:50:34:50:52 | (..., ...) [field Item2] : String | Tuples.cs:50:17:50:56 | (..., ...) [field Item2, field Item2] : String | +| Tuples.cs:50:38:50:51 | "taint source" : String | Tuples.cs:50:34:50:52 | (..., ...) [field Item2] : String | +| Tuples.cs:53:18:53:57 | SSA def(t) [field Item1] : String | Tuples.cs:54:22:54:22 | access to local variable t [field Item1] : String | +| Tuples.cs:53:18:53:57 | SSA def(t) [field Item2, field Item2] : String | Tuples.cs:55:22:55:22 | access to local variable t [field Item2, field Item2] : String | +| Tuples.cs:54:22:54:22 | access to local variable t [field Item1] : String | Tuples.cs:54:22:54:28 | access to field Item1 | +| Tuples.cs:55:22:55:22 | access to local variable t [field Item2, field Item2] : String | Tuples.cs:55:22:55:28 | access to field Item2 [field Item2] : String | +| Tuples.cs:55:22:55:28 | access to field Item2 [field Item2] : String | Tuples.cs:55:22:55:34 | access to field Item2 | +| Tuples.cs:58:18:58:35 | (..., ...) [field Item1] : String | Tuples.cs:58:23:58:23 | SSA def(a) : String | +| Tuples.cs:58:18:58:35 | (..., ...) [field Item2, field Item2] : String | Tuples.cs:58:18:58:35 | (..., ...) [field Item2] : String | +| Tuples.cs:58:18:58:35 | (..., ...) [field Item2] : String | Tuples.cs:58:30:58:30 | SSA def(c) : String | | Tuples.cs:58:23:58:23 | SSA def(a) : String | Tuples.cs:59:22:59:22 | access to local variable a | | Tuples.cs:58:30:58:30 | SSA def(c) : String | Tuples.cs:60:22:60:22 | access to local variable c | -| Tuples.cs:77:18:77:35 | (..., ...) [Item1] : String | Tuples.cs:77:23:77:23 | SSA def(p) : String | -| Tuples.cs:77:18:77:35 | (..., ...) [Item2, Item2] : String | Tuples.cs:77:18:77:35 | (..., ...) [Item2] : String | -| Tuples.cs:77:18:77:35 | (..., ...) [Item2] : String | Tuples.cs:77:30:77:30 | SSA def(r) : String | +| Tuples.cs:77:18:77:35 | (..., ...) [field Item1] : String | Tuples.cs:77:23:77:23 | SSA def(p) : String | +| Tuples.cs:77:18:77:35 | (..., ...) [field Item2, field Item2] : String | Tuples.cs:77:18:77:35 | (..., ...) [field Item2] : String | +| Tuples.cs:77:18:77:35 | (..., ...) [field Item2] : String | Tuples.cs:77:30:77:30 | SSA def(r) : String | | Tuples.cs:77:23:77:23 | SSA def(p) : String | Tuples.cs:79:18:79:18 | access to local variable p | | Tuples.cs:77:30:77:30 | SSA def(r) : String | Tuples.cs:80:18:80:18 | access to local variable r | -| Tuples.cs:89:17:89:41 | object creation of type R1 [i] : String | Tuples.cs:90:14:90:14 | access to local variable r [i] : String | -| Tuples.cs:89:24:89:37 | "taint source" : String | Tuples.cs:89:17:89:41 | object creation of type R1 [i] : String | -| Tuples.cs:90:14:90:14 | access to local variable r [i] : String | Tuples.cs:90:14:90:16 | access to property i | +| Tuples.cs:89:17:89:41 | object creation of type R1 [property i] : String | Tuples.cs:90:14:90:14 | access to local variable r [property i] : String | +| Tuples.cs:89:24:89:37 | "taint source" : String | Tuples.cs:89:17:89:41 | object creation of type R1 [property i] : String | +| Tuples.cs:90:14:90:14 | access to local variable r [property i] : String | Tuples.cs:90:14:90:16 | access to property i | nodes -| Tuples.cs:7:17:7:56 | (..., ...) [Item1] : String | semmle.label | (..., ...) [Item1] : String | -| Tuples.cs:7:17:7:56 | (..., ...) [Item2, Item2] : String | semmle.label | (..., ...) [Item2, Item2] : String | +| Tuples.cs:7:17:7:56 | (..., ...) [field Item1] : String | semmle.label | (..., ...) [field Item1] : String | +| Tuples.cs:7:17:7:56 | (..., ...) [field Item2, field Item2] : String | semmle.label | (..., ...) [field Item2, field Item2] : String | | Tuples.cs:7:21:7:34 | "taint source" : String | semmle.label | "taint source" : String | -| Tuples.cs:7:37:7:55 | (..., ...) [Item2] : String | semmle.label | (..., ...) [Item2] : String | +| Tuples.cs:7:37:7:55 | (..., ...) [field Item2] : String | semmle.label | (..., ...) [field Item2] : String | | Tuples.cs:7:41:7:54 | "taint source" : String | semmle.label | "taint source" : String | -| Tuples.cs:8:9:8:23 | (..., ...) [Item1] : String | semmle.label | (..., ...) [Item1] : String | -| Tuples.cs:8:9:8:23 | (..., ...) [Item2, Item2] : String | semmle.label | (..., ...) [Item2, Item2] : String | -| Tuples.cs:8:9:8:23 | (..., ...) [Item2] : String | semmle.label | (..., ...) [Item2] : String | +| Tuples.cs:8:9:8:23 | (..., ...) [field Item1] : String | semmle.label | (..., ...) [field Item1] : String | +| Tuples.cs:8:9:8:23 | (..., ...) [field Item2, field Item2] : String | semmle.label | (..., ...) [field Item2, field Item2] : String | +| Tuples.cs:8:9:8:23 | (..., ...) [field Item2] : String | semmle.label | (..., ...) [field Item2] : String | | Tuples.cs:8:9:8:27 | SSA def(a) : String | semmle.label | SSA def(a) : String | | Tuples.cs:8:9:8:27 | SSA def(c) : String | semmle.label | SSA def(c) : String | | Tuples.cs:9:14:9:14 | access to local variable a | semmle.label | access to local variable a | | Tuples.cs:11:14:11:14 | access to local variable c | semmle.label | access to local variable c | -| Tuples.cs:13:9:13:19 | (..., ...) [Item1] : String | semmle.label | (..., ...) [Item1] : String | -| Tuples.cs:13:9:13:19 | (..., ...) [Item2, Item2] : String | semmle.label | (..., ...) [Item2, Item2] : String | +| Tuples.cs:13:9:13:19 | (..., ...) [field Item1] : String | semmle.label | (..., ...) [field Item1] : String | +| Tuples.cs:13:9:13:19 | (..., ...) [field Item2, field Item2] : String | semmle.label | (..., ...) [field Item2, field Item2] : String | | Tuples.cs:13:9:13:23 | SSA def(a) : String | semmle.label | SSA def(a) : String | | Tuples.cs:13:9:13:23 | SSA def(c) : String | semmle.label | SSA def(c) : String | -| Tuples.cs:13:13:13:18 | (..., ...) [Item2] : String | semmle.label | (..., ...) [Item2] : String | +| Tuples.cs:13:13:13:18 | (..., ...) [field Item2] : String | semmle.label | (..., ...) [field Item2] : String | | Tuples.cs:14:14:14:14 | access to local variable a | semmle.label | access to local variable a | | Tuples.cs:16:14:16:14 | access to local variable c | semmle.label | access to local variable c | -| Tuples.cs:18:9:18:22 | (..., ...) [Item1] : String | semmle.label | (..., ...) [Item1] : String | -| Tuples.cs:18:9:18:22 | (..., ...) [Item2, Item2] : String | semmle.label | (..., ...) [Item2, Item2] : String | +| Tuples.cs:18:9:18:22 | (..., ...) [field Item1] : String | semmle.label | (..., ...) [field Item1] : String | +| Tuples.cs:18:9:18:22 | (..., ...) [field Item2, field Item2] : String | semmle.label | (..., ...) [field Item2, field Item2] : String | | Tuples.cs:18:9:18:26 | SSA def(p) : String | semmle.label | SSA def(p) : String | -| Tuples.cs:18:9:18:26 | SSA def(q) [Item2] : String | semmle.label | SSA def(q) [Item2] : String | +| Tuples.cs:18:9:18:26 | SSA def(q) [field Item2] : String | semmle.label | SSA def(q) [field Item2] : String | | Tuples.cs:19:14:19:14 | access to local variable p | semmle.label | access to local variable p | -| Tuples.cs:21:14:21:14 | access to local variable q [Item2] : String | semmle.label | access to local variable q [Item2] : String | +| Tuples.cs:21:14:21:14 | access to local variable q [field Item2] : String | semmle.label | access to local variable q [field Item2] : String | | Tuples.cs:21:14:21:20 | access to field Item2 | semmle.label | access to field Item2 | -| Tuples.cs:23:14:23:14 | access to local variable x [Item1] : String | semmle.label | access to local variable x [Item1] : String | +| Tuples.cs:23:14:23:14 | access to local variable x [field Item1] : String | semmle.label | access to local variable x [field Item1] : String | | Tuples.cs:23:14:23:20 | access to field Item1 | semmle.label | access to field Item1 | -| Tuples.cs:24:14:24:14 | access to local variable x [Item1] : String | semmle.label | access to local variable x [Item1] : String | +| Tuples.cs:24:14:24:14 | access to local variable x [field Item1] : String | semmle.label | access to local variable x [field Item1] : String | | Tuples.cs:24:14:24:16 | access to field Item1 | semmle.label | access to field Item1 | -| Tuples.cs:26:14:26:14 | access to local variable x [Item2, Item2] : String | semmle.label | access to local variable x [Item2, Item2] : String | -| Tuples.cs:26:14:26:20 | access to field Item2 [Item2] : String | semmle.label | access to field Item2 [Item2] : String | +| Tuples.cs:26:14:26:14 | access to local variable x [field Item2, field Item2] : String | semmle.label | access to local variable x [field Item2, field Item2] : String | +| Tuples.cs:26:14:26:20 | access to field Item2 [field Item2] : String | semmle.label | access to field Item2 [field Item2] : String | | Tuples.cs:26:14:26:26 | access to field Item2 | semmle.label | access to field Item2 | -| Tuples.cs:31:17:31:72 | (..., ...) [Item1] : String | semmle.label | (..., ...) [Item1] : String | -| Tuples.cs:31:17:31:72 | (..., ...) [Item10] : String | semmle.label | (..., ...) [Item10] : String | +| Tuples.cs:31:17:31:72 | (..., ...) [field Item1] : String | semmle.label | (..., ...) [field Item1] : String | +| Tuples.cs:31:17:31:72 | (..., ...) [field Item10] : String | semmle.label | (..., ...) [field Item10] : String | | Tuples.cs:31:18:31:31 | "taint source" : String | semmle.label | "taint source" : String | | Tuples.cs:31:58:31:71 | "taint source" : String | semmle.label | "taint source" : String | -| Tuples.cs:32:14:32:14 | access to local variable x [Item1] : String | semmle.label | access to local variable x [Item1] : String | +| Tuples.cs:32:14:32:14 | access to local variable x [field Item1] : String | semmle.label | access to local variable x [field Item1] : String | | Tuples.cs:32:14:32:20 | access to field Item1 | semmle.label | access to field Item1 | -| Tuples.cs:34:14:34:14 | access to local variable x [Item10] : String | semmle.label | access to local variable x [Item10] : String | +| Tuples.cs:34:14:34:14 | access to local variable x [field Item10] : String | semmle.label | access to local variable x [field Item10] : String | | Tuples.cs:34:14:34:21 | access to field Item10 | semmle.label | access to field Item10 | -| Tuples.cs:39:17:39:68 | (...) ... [Item1] : String | semmle.label | (...) ... [Item1] : String | -| Tuples.cs:39:47:39:68 | (..., ...) [Item1] : String | semmle.label | (..., ...) [Item1] : String | +| Tuples.cs:39:17:39:68 | (...) ... [field Item1] : String | semmle.label | (...) ... [field Item1] : String | +| Tuples.cs:39:47:39:68 | (..., ...) [field Item1] : String | semmle.label | (..., ...) [field Item1] : String | | Tuples.cs:39:48:39:61 | "taint source" : String | semmle.label | "taint source" : String | -| Tuples.cs:40:14:40:14 | access to local variable x [Item1] : String | semmle.label | access to local variable x [Item1] : String | +| Tuples.cs:40:14:40:14 | access to local variable x [field Item1] : String | semmle.label | access to local variable x [field Item1] : String | | Tuples.cs:40:14:40:20 | access to field Item1 | semmle.label | access to field Item1 | -| Tuples.cs:50:17:50:56 | (..., ...) [Item1] : String | semmle.label | (..., ...) [Item1] : String | -| Tuples.cs:50:17:50:56 | (..., ...) [Item2, Item2] : String | semmle.label | (..., ...) [Item2, Item2] : String | +| Tuples.cs:50:17:50:56 | (..., ...) [field Item1] : String | semmle.label | (..., ...) [field Item1] : String | +| Tuples.cs:50:17:50:56 | (..., ...) [field Item2, field Item2] : String | semmle.label | (..., ...) [field Item2, field Item2] : String | | Tuples.cs:50:18:50:31 | "taint source" : String | semmle.label | "taint source" : String | -| Tuples.cs:50:34:50:52 | (..., ...) [Item2] : String | semmle.label | (..., ...) [Item2] : String | +| Tuples.cs:50:34:50:52 | (..., ...) [field Item2] : String | semmle.label | (..., ...) [field Item2] : String | | Tuples.cs:50:38:50:51 | "taint source" : String | semmle.label | "taint source" : String | -| Tuples.cs:53:18:53:57 | SSA def(t) [Item1] : String | semmle.label | SSA def(t) [Item1] : String | -| Tuples.cs:53:18:53:57 | SSA def(t) [Item2, Item2] : String | semmle.label | SSA def(t) [Item2, Item2] : String | -| Tuples.cs:54:22:54:22 | access to local variable t [Item1] : String | semmle.label | access to local variable t [Item1] : String | +| Tuples.cs:53:18:53:57 | SSA def(t) [field Item1] : String | semmle.label | SSA def(t) [field Item1] : String | +| Tuples.cs:53:18:53:57 | SSA def(t) [field Item2, field Item2] : String | semmle.label | SSA def(t) [field Item2, field Item2] : String | +| Tuples.cs:54:22:54:22 | access to local variable t [field Item1] : String | semmle.label | access to local variable t [field Item1] : String | | Tuples.cs:54:22:54:28 | access to field Item1 | semmle.label | access to field Item1 | -| Tuples.cs:55:22:55:22 | access to local variable t [Item2, Item2] : String | semmle.label | access to local variable t [Item2, Item2] : String | -| Tuples.cs:55:22:55:28 | access to field Item2 [Item2] : String | semmle.label | access to field Item2 [Item2] : String | +| Tuples.cs:55:22:55:22 | access to local variable t [field Item2, field Item2] : String | semmle.label | access to local variable t [field Item2, field Item2] : String | +| Tuples.cs:55:22:55:28 | access to field Item2 [field Item2] : String | semmle.label | access to field Item2 [field Item2] : String | | Tuples.cs:55:22:55:34 | access to field Item2 | semmle.label | access to field Item2 | -| Tuples.cs:58:18:58:35 | (..., ...) [Item1] : String | semmle.label | (..., ...) [Item1] : String | -| Tuples.cs:58:18:58:35 | (..., ...) [Item2, Item2] : String | semmle.label | (..., ...) [Item2, Item2] : String | -| Tuples.cs:58:18:58:35 | (..., ...) [Item2] : String | semmle.label | (..., ...) [Item2] : String | +| Tuples.cs:58:18:58:35 | (..., ...) [field Item1] : String | semmle.label | (..., ...) [field Item1] : String | +| Tuples.cs:58:18:58:35 | (..., ...) [field Item2, field Item2] : String | semmle.label | (..., ...) [field Item2, field Item2] : String | +| Tuples.cs:58:18:58:35 | (..., ...) [field Item2] : String | semmle.label | (..., ...) [field Item2] : String | | Tuples.cs:58:23:58:23 | SSA def(a) : String | semmle.label | SSA def(a) : String | | Tuples.cs:58:30:58:30 | SSA def(c) : String | semmle.label | SSA def(c) : String | | Tuples.cs:59:22:59:22 | access to local variable a | semmle.label | access to local variable a | | Tuples.cs:60:22:60:22 | access to local variable c | semmle.label | access to local variable c | -| Tuples.cs:77:18:77:35 | (..., ...) [Item1] : String | semmle.label | (..., ...) [Item1] : String | -| Tuples.cs:77:18:77:35 | (..., ...) [Item2, Item2] : String | semmle.label | (..., ...) [Item2, Item2] : String | -| Tuples.cs:77:18:77:35 | (..., ...) [Item2] : String | semmle.label | (..., ...) [Item2] : String | +| Tuples.cs:77:18:77:35 | (..., ...) [field Item1] : String | semmle.label | (..., ...) [field Item1] : String | +| Tuples.cs:77:18:77:35 | (..., ...) [field Item2, field Item2] : String | semmle.label | (..., ...) [field Item2, field Item2] : String | +| Tuples.cs:77:18:77:35 | (..., ...) [field Item2] : String | semmle.label | (..., ...) [field Item2] : String | | Tuples.cs:77:23:77:23 | SSA def(p) : String | semmle.label | SSA def(p) : String | | Tuples.cs:77:30:77:30 | SSA def(r) : String | semmle.label | SSA def(r) : String | | Tuples.cs:79:18:79:18 | access to local variable p | semmle.label | access to local variable p | | Tuples.cs:80:18:80:18 | access to local variable r | semmle.label | access to local variable r | -| Tuples.cs:89:17:89:41 | object creation of type R1 [i] : String | semmle.label | object creation of type R1 [i] : String | +| Tuples.cs:89:17:89:41 | object creation of type R1 [property i] : String | semmle.label | object creation of type R1 [property i] : String | | Tuples.cs:89:24:89:37 | "taint source" : String | semmle.label | "taint source" : String | -| Tuples.cs:90:14:90:14 | access to local variable r [i] : String | semmle.label | access to local variable r [i] : String | +| Tuples.cs:90:14:90:14 | access to local variable r [property i] : String | semmle.label | access to local variable r [property i] : String | | Tuples.cs:90:14:90:16 | access to property i | semmle.label | access to property i | #select | Tuples.cs:7:21:7:34 | "taint source" : String | Tuples.cs:7:21:7:34 | "taint source" : String | Tuples.cs:9:14:9:14 | access to local variable a | $@ | Tuples.cs:9:14:9:14 | access to local variable a | access to local variable a | diff --git a/csharp/ql/test/library-tests/dataflow/types/Types.expected b/csharp/ql/test/library-tests/dataflow/types/Types.expected index 43b06fb7cba..93be8ab587a 100644 --- a/csharp/ql/test/library-tests/dataflow/types/Types.expected +++ b/csharp/ql/test/library-tests/dataflow/types/Types.expected @@ -33,23 +33,23 @@ edges | Types.cs:77:22:77:22 | a : C | Types.cs:79:18:79:25 | SSA def(b) : C | | Types.cs:79:18:79:25 | SSA def(b) : C | Types.cs:80:18:80:18 | access to local variable b | | Types.cs:90:22:90:22 | e : Types.E.E2 | Types.cs:92:26:92:26 | access to parameter e : Types.E.E2 | -| Types.cs:92:13:92:16 | [post] this access [Field] : Types.E.E2 | Types.cs:93:13:93:16 | this access [Field] : Types.E.E2 | -| Types.cs:92:26:92:26 | access to parameter e : Types.E.E2 | Types.cs:92:13:92:16 | [post] this access [Field] : Types.E.E2 | -| Types.cs:93:13:93:16 | this access [Field] : Types.E.E2 | Types.cs:113:34:113:34 | this [Field] : Types.E.E2 | +| Types.cs:92:13:92:16 | [post] this access [field Field] : Types.E.E2 | Types.cs:93:13:93:16 | this access [field Field] : Types.E.E2 | +| Types.cs:92:26:92:26 | access to parameter e : Types.E.E2 | Types.cs:92:13:92:16 | [post] this access [field Field] : Types.E.E2 | +| Types.cs:93:13:93:16 | this access [field Field] : Types.E.E2 | Types.cs:113:34:113:34 | this [field Field] : Types.E.E2 | | Types.cs:110:25:110:32 | object creation of type E2 : Types.E.E2 | Types.cs:90:22:90:22 | e : Types.E.E2 | -| Types.cs:113:34:113:34 | this [Field] : Types.E.E2 | Types.cs:115:22:115:25 | this access [Field] : Types.E.E2 | -| Types.cs:115:22:115:25 | this access [Field] : Types.E.E2 | Types.cs:115:22:115:31 | access to field Field | +| Types.cs:113:34:113:34 | this [field Field] : Types.E.E2 | Types.cs:115:22:115:25 | this access [field Field] : Types.E.E2 | +| Types.cs:115:22:115:25 | this access [field Field] : Types.E.E2 | Types.cs:115:22:115:31 | access to field Field | | Types.cs:120:25:120:31 | object creation of type A : A | Types.cs:122:30:122:30 | access to local variable a : A | | Types.cs:121:26:121:33 | object creation of type E2 : Types.E.E2 | Types.cs:123:30:123:31 | access to local variable e2 : Types.E.E2 | | Types.cs:122:30:122:30 | access to local variable a : A | Types.cs:122:22:122:31 | call to method Through | | Types.cs:123:30:123:31 | access to local variable e2 : Types.E.E2 | Types.cs:123:22:123:32 | call to method Through | -| Types.cs:138:21:138:25 | this [Field] : Object | Types.cs:138:32:138:35 | this access [Field] : Object | -| Types.cs:138:32:138:35 | this access [Field] : Object | Types.cs:153:30:153:30 | this [Field] : Object | -| Types.cs:144:13:144:13 | [post] access to parameter c [Field] : Object | Types.cs:145:13:145:13 | access to parameter c [Field] : Object | -| Types.cs:144:23:144:34 | object creation of type Object : Object | Types.cs:144:13:144:13 | [post] access to parameter c [Field] : Object | -| Types.cs:145:13:145:13 | access to parameter c [Field] : Object | Types.cs:138:21:138:25 | this [Field] : Object | -| Types.cs:153:30:153:30 | this [Field] : Object | Types.cs:153:42:153:45 | this access [Field] : Object | -| Types.cs:153:42:153:45 | this access [Field] : Object | Types.cs:153:42:153:51 | access to field Field | +| Types.cs:138:21:138:25 | this [field Field] : Object | Types.cs:138:32:138:35 | this access [field Field] : Object | +| Types.cs:138:32:138:35 | this access [field Field] : Object | Types.cs:153:30:153:30 | this [field Field] : Object | +| Types.cs:144:13:144:13 | [post] access to parameter c [field Field] : Object | Types.cs:145:13:145:13 | access to parameter c [field Field] : Object | +| Types.cs:144:23:144:34 | object creation of type Object : Object | Types.cs:144:13:144:13 | [post] access to parameter c [field Field] : Object | +| Types.cs:145:13:145:13 | access to parameter c [field Field] : Object | Types.cs:138:21:138:25 | this [field Field] : Object | +| Types.cs:153:30:153:30 | this [field Field] : Object | Types.cs:153:42:153:45 | this access [field Field] : Object | +| Types.cs:153:42:153:45 | this access [field Field] : Object | Types.cs:153:42:153:51 | access to field Field | nodes | Types.cs:7:21:7:25 | this : D | semmle.label | this : D | | Types.cs:7:32:7:35 | this access : D | semmle.label | this access : D | @@ -94,12 +94,12 @@ nodes | Types.cs:79:18:79:25 | SSA def(b) : C | semmle.label | SSA def(b) : C | | Types.cs:80:18:80:18 | access to local variable b | semmle.label | access to local variable b | | Types.cs:90:22:90:22 | e : Types.E.E2 | semmle.label | e : Types.E.E2 | -| Types.cs:92:13:92:16 | [post] this access [Field] : Types.E.E2 | semmle.label | [post] this access [Field] : Types.E.E2 | +| Types.cs:92:13:92:16 | [post] this access [field Field] : Types.E.E2 | semmle.label | [post] this access [field Field] : Types.E.E2 | | Types.cs:92:26:92:26 | access to parameter e : Types.E.E2 | semmle.label | access to parameter e : Types.E.E2 | -| Types.cs:93:13:93:16 | this access [Field] : Types.E.E2 | semmle.label | this access [Field] : Types.E.E2 | +| Types.cs:93:13:93:16 | this access [field Field] : Types.E.E2 | semmle.label | this access [field Field] : Types.E.E2 | | Types.cs:110:25:110:32 | object creation of type E2 : Types.E.E2 | semmle.label | object creation of type E2 : Types.E.E2 | -| Types.cs:113:34:113:34 | this [Field] : Types.E.E2 | semmle.label | this [Field] : Types.E.E2 | -| Types.cs:115:22:115:25 | this access [Field] : Types.E.E2 | semmle.label | this access [Field] : Types.E.E2 | +| Types.cs:113:34:113:34 | this [field Field] : Types.E.E2 | semmle.label | this [field Field] : Types.E.E2 | +| Types.cs:115:22:115:25 | this access [field Field] : Types.E.E2 | semmle.label | this access [field Field] : Types.E.E2 | | Types.cs:115:22:115:31 | access to field Field | semmle.label | access to field Field | | Types.cs:120:25:120:31 | object creation of type A : A | semmle.label | object creation of type A : A | | Types.cs:121:26:121:33 | object creation of type E2 : Types.E.E2 | semmle.label | object creation of type E2 : Types.E.E2 | @@ -107,13 +107,13 @@ nodes | Types.cs:122:30:122:30 | access to local variable a : A | semmle.label | access to local variable a : A | | Types.cs:123:22:123:32 | call to method Through | semmle.label | call to method Through | | Types.cs:123:30:123:31 | access to local variable e2 : Types.E.E2 | semmle.label | access to local variable e2 : Types.E.E2 | -| Types.cs:138:21:138:25 | this [Field] : Object | semmle.label | this [Field] : Object | -| Types.cs:138:32:138:35 | this access [Field] : Object | semmle.label | this access [Field] : Object | -| Types.cs:144:13:144:13 | [post] access to parameter c [Field] : Object | semmle.label | [post] access to parameter c [Field] : Object | +| Types.cs:138:21:138:25 | this [field Field] : Object | semmle.label | this [field Field] : Object | +| Types.cs:138:32:138:35 | this access [field Field] : Object | semmle.label | this access [field Field] : Object | +| Types.cs:144:13:144:13 | [post] access to parameter c [field Field] : Object | semmle.label | [post] access to parameter c [field Field] : Object | | Types.cs:144:23:144:34 | object creation of type Object : Object | semmle.label | object creation of type Object : Object | -| Types.cs:145:13:145:13 | access to parameter c [Field] : Object | semmle.label | access to parameter c [Field] : Object | -| Types.cs:153:30:153:30 | this [Field] : Object | semmle.label | this [Field] : Object | -| Types.cs:153:42:153:45 | this access [Field] : Object | semmle.label | this access [Field] : Object | +| Types.cs:145:13:145:13 | access to parameter c [field Field] : Object | semmle.label | access to parameter c [field Field] : Object | +| Types.cs:153:30:153:30 | this [field Field] : Object | semmle.label | this [field Field] : Object | +| Types.cs:153:42:153:45 | this access [field Field] : Object | semmle.label | this access [field Field] : Object | | Types.cs:153:42:153:51 | access to field Field | semmle.label | access to field Field | #select | Types.cs:23:12:23:18 | object creation of type C : C | Types.cs:23:12:23:18 | object creation of type C : C | Types.cs:50:18:50:18 | access to local variable c | $@ | Types.cs:50:18:50:18 | access to local variable c | access to local variable c | diff --git a/csharp/ql/test/library-tests/exprorstmtparent/Parameter.ql b/csharp/ql/test/library-tests/exprorstmtparent/Parameter.ql index 3c12d5b870f..33f6eeb2b9d 100644 --- a/csharp/ql/test/library-tests/exprorstmtparent/Parameter.ql +++ b/csharp/ql/test/library-tests/exprorstmtparent/Parameter.ql @@ -1,4 +1,5 @@ import csharp from Parameter p +where p.fromSource() select p, p.getDefaultValue() diff --git a/csharp/ql/test/library-tests/frameworks/EntityFramework/Dataflow.expected b/csharp/ql/test/library-tests/frameworks/EntityFramework/Dataflow.expected index 7d0bd289f9c..d58177238b5 100644 --- a/csharp/ql/test/library-tests/frameworks/EntityFramework/Dataflow.expected +++ b/csharp/ql/test/library-tests/frameworks/EntityFramework/Dataflow.expected @@ -1,97 +1,97 @@ edges -| ../../../resources/stubs/EntityFramework.cs:40:20:40:30 | this [Addresses, [], Street] : String | EntityFramework.cs:214:18:214:30 | access to property Addresses [[], Street] : String | -| ../../../resources/stubs/EntityFramework.cs:40:20:40:30 | this [Addresses, [], Street] : String | EntityFramework.cs:221:18:221:28 | access to property Persons [[], Addresses, [], Street] : String | -| ../../../resources/stubs/EntityFramework.cs:40:20:40:30 | this [PersonAddresses, [], Address, Street] : String | EntityFramework.cs:214:18:214:30 | access to property Addresses [[], Street] : String | -| ../../../resources/stubs/EntityFramework.cs:40:20:40:30 | this [PersonAddresses, [], Address, Street] : String | EntityFramework.cs:221:18:221:28 | access to property Persons [[], Addresses, [], Street] : String | -| ../../../resources/stubs/EntityFramework.cs:40:20:40:30 | this [PersonAddresses, [], Person, Name] : String | EntityFramework.cs:206:18:206:28 | access to property Persons [[], Name] : String | -| ../../../resources/stubs/EntityFramework.cs:40:20:40:30 | this [Persons, [], Addresses, [], Street] : String | EntityFramework.cs:214:18:214:30 | access to property Addresses [[], Street] : String | -| ../../../resources/stubs/EntityFramework.cs:40:20:40:30 | this [Persons, [], Addresses, [], Street] : String | EntityFramework.cs:221:18:221:28 | access to property Persons [[], Addresses, [], Street] : String | -| ../../../resources/stubs/EntityFramework.cs:40:20:40:30 | this [Persons, [], Name] : String | EntityFramework.cs:206:18:206:28 | access to property Persons [[], Name] : String | -| ../../../resources/stubs/EntityFramework.cs:41:49:41:64 | this [Persons, [], Name] : String | EntityFramework.cs:206:18:206:28 | access to property Persons [[], Name] : String | -| ../../../resources/stubs/EntityFramework.cs:80:20:80:30 | this [Addresses, [], Street] : String | EntityFrameworkCore.cs:238:18:238:30 | access to property Addresses [[], Street] : String | -| ../../../resources/stubs/EntityFramework.cs:80:20:80:30 | this [Addresses, [], Street] : String | EntityFrameworkCore.cs:245:18:245:28 | access to property Persons [[], Addresses, [], Street] : String | -| ../../../resources/stubs/EntityFramework.cs:80:20:80:30 | this [PersonAddresses, [], Address, Street] : String | EntityFrameworkCore.cs:238:18:238:30 | access to property Addresses [[], Street] : String | -| ../../../resources/stubs/EntityFramework.cs:80:20:80:30 | this [PersonAddresses, [], Address, Street] : String | EntityFrameworkCore.cs:245:18:245:28 | access to property Persons [[], Addresses, [], Street] : String | -| ../../../resources/stubs/EntityFramework.cs:80:20:80:30 | this [PersonAddresses, [], Person, Name] : String | EntityFrameworkCore.cs:230:18:230:28 | access to property Persons [[], Name] : String | -| ../../../resources/stubs/EntityFramework.cs:80:20:80:30 | this [Persons, [], Addresses, [], Street] : String | EntityFrameworkCore.cs:238:18:238:30 | access to property Addresses [[], Street] : String | -| ../../../resources/stubs/EntityFramework.cs:80:20:80:30 | this [Persons, [], Addresses, [], Street] : String | EntityFrameworkCore.cs:245:18:245:28 | access to property Persons [[], Addresses, [], Street] : String | -| ../../../resources/stubs/EntityFramework.cs:80:20:80:30 | this [Persons, [], Name] : String | EntityFrameworkCore.cs:230:18:230:28 | access to property Persons [[], Name] : String | -| ../../../resources/stubs/EntityFramework.cs:81:49:81:64 | this [Persons, [], Name] : String | EntityFrameworkCore.cs:230:18:230:28 | access to property Persons [[], Name] : String | -| EntityFramework.cs:61:13:64:13 | { ..., ... } [Name] : String | EntityFramework.cs:68:29:68:30 | access to local variable p1 [Name] : String | -| EntityFramework.cs:63:24:63:32 | "tainted" : String | EntityFramework.cs:61:13:64:13 | { ..., ... } [Name] : String | -| EntityFramework.cs:68:13:68:15 | [post] access to local variable ctx [Persons, [], Name] : String | EntityFramework.cs:70:13:70:15 | access to local variable ctx [Persons, [], Name] : String | -| EntityFramework.cs:68:13:68:23 | [post] access to property Persons [[], Name] : String | EntityFramework.cs:68:13:68:15 | [post] access to local variable ctx [Persons, [], Name] : String | -| EntityFramework.cs:68:29:68:30 | access to local variable p1 [Name] : String | EntityFramework.cs:68:13:68:23 | [post] access to property Persons [[], Name] : String | -| EntityFramework.cs:70:13:70:15 | access to local variable ctx [Persons, [], Name] : String | ../../../resources/stubs/EntityFramework.cs:40:20:40:30 | this [Persons, [], Name] : String | -| EntityFramework.cs:83:13:86:13 | { ..., ... } [Name] : String | EntityFramework.cs:90:29:90:30 | access to local variable p1 [Name] : String | -| EntityFramework.cs:85:24:85:32 | "tainted" : String | EntityFramework.cs:83:13:86:13 | { ..., ... } [Name] : String | -| EntityFramework.cs:90:13:90:15 | [post] access to local variable ctx [Persons, [], Name] : String | EntityFramework.cs:92:19:92:21 | access to local variable ctx [Persons, [], Name] : String | -| EntityFramework.cs:90:13:90:23 | [post] access to property Persons [[], Name] : String | EntityFramework.cs:90:13:90:15 | [post] access to local variable ctx [Persons, [], Name] : String | -| EntityFramework.cs:90:29:90:30 | access to local variable p1 [Name] : String | EntityFramework.cs:90:13:90:23 | [post] access to property Persons [[], Name] : String | -| EntityFramework.cs:92:19:92:21 | access to local variable ctx [Persons, [], Name] : String | ../../../resources/stubs/EntityFramework.cs:41:49:41:64 | this [Persons, [], Name] : String | -| EntityFramework.cs:105:13:108:13 | { ..., ... } [Name] : String | EntityFramework.cs:111:27:111:28 | access to local variable p1 [Name] : String | -| EntityFramework.cs:107:24:107:32 | "tainted" : String | EntityFramework.cs:105:13:108:13 | { ..., ... } [Name] : String | -| EntityFramework.cs:111:27:111:28 | access to local variable p1 [Name] : String | EntityFramework.cs:195:35:195:35 | p [Name] : String | -| EntityFramework.cs:124:13:127:13 | { ..., ... } [Title] : String | EntityFramework.cs:131:18:131:19 | access to local variable p1 [Title] : String | -| EntityFramework.cs:126:25:126:33 | "tainted" : String | EntityFramework.cs:124:13:127:13 | { ..., ... } [Title] : String | -| EntityFramework.cs:131:18:131:19 | access to local variable p1 [Title] : String | EntityFramework.cs:131:18:131:25 | access to property Title | -| EntityFramework.cs:143:13:150:13 | { ..., ... } [Addresses, [], Street] : String | EntityFramework.cs:151:29:151:30 | access to local variable p1 [Addresses, [], Street] : String | -| EntityFramework.cs:144:29:149:17 | array creation of type Address[] [[], Street] : String | EntityFramework.cs:143:13:150:13 | { ..., ... } [Addresses, [], Street] : String | -| EntityFramework.cs:144:35:149:17 | { ..., ... } [[], Street] : String | EntityFramework.cs:144:29:149:17 | array creation of type Address[] [[], Street] : String | -| EntityFramework.cs:145:21:148:21 | object creation of type Address [Street] : String | EntityFramework.cs:144:35:149:17 | { ..., ... } [[], Street] : String | -| EntityFramework.cs:145:33:148:21 | { ..., ... } [Street] : String | EntityFramework.cs:145:21:148:21 | object creation of type Address [Street] : String | -| EntityFramework.cs:147:34:147:42 | "tainted" : String | EntityFramework.cs:145:33:148:21 | { ..., ... } [Street] : String | -| EntityFramework.cs:151:13:151:15 | [post] access to local variable ctx [Persons, [], Addresses, [], Street] : String | EntityFramework.cs:152:13:152:15 | access to local variable ctx [Persons, [], Addresses, [], Street] : String | -| EntityFramework.cs:151:13:151:15 | [post] access to local variable ctx [Persons, [], Addresses, [], Street] : String | EntityFramework.cs:156:13:156:15 | access to local variable ctx [Persons, [], Addresses, [], Street] : String | -| EntityFramework.cs:151:13:151:15 | [post] access to local variable ctx [Persons, [], Addresses, [], Street] : String | EntityFramework.cs:164:13:164:15 | access to local variable ctx [Persons, [], Addresses, [], Street] : String | -| EntityFramework.cs:151:13:151:15 | [post] access to local variable ctx [Persons, [], Addresses, [], Street] : String | EntityFramework.cs:168:13:168:15 | access to local variable ctx [Persons, [], Addresses, [], Street] : String | -| EntityFramework.cs:151:13:151:23 | [post] access to property Persons [[], Addresses, [], Street] : String | EntityFramework.cs:151:13:151:15 | [post] access to local variable ctx [Persons, [], Addresses, [], Street] : String | -| EntityFramework.cs:151:29:151:30 | access to local variable p1 [Addresses, [], Street] : String | EntityFramework.cs:151:13:151:23 | [post] access to property Persons [[], Addresses, [], Street] : String | -| EntityFramework.cs:152:13:152:15 | access to local variable ctx [Persons, [], Addresses, [], Street] : String | ../../../resources/stubs/EntityFramework.cs:40:20:40:30 | this [Persons, [], Addresses, [], Street] : String | -| EntityFramework.cs:156:13:156:15 | access to local variable ctx [Persons, [], Addresses, [], Street] : String | ../../../resources/stubs/EntityFramework.cs:40:20:40:30 | this [Persons, [], Addresses, [], Street] : String | -| EntityFramework.cs:159:13:162:13 | { ..., ... } [Street] : String | EntityFramework.cs:163:31:163:32 | access to local variable a1 [Street] : String | -| EntityFramework.cs:161:26:161:34 | "tainted" : String | EntityFramework.cs:159:13:162:13 | { ..., ... } [Street] : String | -| EntityFramework.cs:163:13:163:15 | [post] access to local variable ctx [Addresses, [], Street] : String | EntityFramework.cs:164:13:164:15 | access to local variable ctx [Addresses, [], Street] : String | -| EntityFramework.cs:163:13:163:15 | [post] access to local variable ctx [Addresses, [], Street] : String | EntityFramework.cs:168:13:168:15 | access to local variable ctx [Addresses, [], Street] : String | -| EntityFramework.cs:163:13:163:25 | [post] access to property Addresses [[], Street] : String | EntityFramework.cs:163:13:163:15 | [post] access to local variable ctx [Addresses, [], Street] : String | -| EntityFramework.cs:163:31:163:32 | access to local variable a1 [Street] : String | EntityFramework.cs:163:13:163:25 | [post] access to property Addresses [[], Street] : String | -| EntityFramework.cs:164:13:164:15 | access to local variable ctx [Addresses, [], Street] : String | ../../../resources/stubs/EntityFramework.cs:40:20:40:30 | this [Addresses, [], Street] : String | -| EntityFramework.cs:164:13:164:15 | access to local variable ctx [Persons, [], Addresses, [], Street] : String | ../../../resources/stubs/EntityFramework.cs:40:20:40:30 | this [Persons, [], Addresses, [], Street] : String | -| EntityFramework.cs:168:13:168:15 | access to local variable ctx [Addresses, [], Street] : String | ../../../resources/stubs/EntityFramework.cs:40:20:40:30 | this [Addresses, [], Street] : String | -| EntityFramework.cs:168:13:168:15 | access to local variable ctx [Persons, [], Addresses, [], Street] : String | ../../../resources/stubs/EntityFramework.cs:40:20:40:30 | this [Persons, [], Addresses, [], Street] : String | -| EntityFramework.cs:175:13:178:13 | { ..., ... } [Name] : String | EntityFramework.cs:184:71:184:72 | access to local variable p1 [Name] : String | -| EntityFramework.cs:177:24:177:32 | "tainted" : String | EntityFramework.cs:175:13:178:13 | { ..., ... } [Name] : String | -| EntityFramework.cs:180:13:183:13 | { ..., ... } [Street] : String | EntityFramework.cs:184:85:184:86 | access to local variable a1 [Street] : String | -| EntityFramework.cs:182:26:182:34 | "tainted" : String | EntityFramework.cs:180:13:183:13 | { ..., ... } [Street] : String | -| EntityFramework.cs:184:60:184:88 | { ..., ... } [Address, Street] : String | EntityFramework.cs:185:37:185:53 | access to local variable personAddressMap1 [Address, Street] : String | -| EntityFramework.cs:184:60:184:88 | { ..., ... } [Person, Name] : String | EntityFramework.cs:185:37:185:53 | access to local variable personAddressMap1 [Person, Name] : String | -| EntityFramework.cs:184:71:184:72 | access to local variable p1 [Name] : String | EntityFramework.cs:184:60:184:88 | { ..., ... } [Person, Name] : String | -| EntityFramework.cs:184:85:184:86 | access to local variable a1 [Street] : String | EntityFramework.cs:184:60:184:88 | { ..., ... } [Address, Street] : String | -| EntityFramework.cs:185:13:185:15 | [post] access to local variable ctx [PersonAddresses, [], Address, Street] : String | EntityFramework.cs:186:13:186:15 | access to local variable ctx [PersonAddresses, [], Address, Street] : String | -| EntityFramework.cs:185:13:185:15 | [post] access to local variable ctx [PersonAddresses, [], Address, Street] : String | EntityFramework.cs:192:13:192:15 | access to local variable ctx [PersonAddresses, [], Address, Street] : String | -| EntityFramework.cs:185:13:185:15 | [post] access to local variable ctx [PersonAddresses, [], Person, Name] : String | EntityFramework.cs:186:13:186:15 | access to local variable ctx [PersonAddresses, [], Person, Name] : String | -| EntityFramework.cs:185:13:185:15 | [post] access to local variable ctx [PersonAddresses, [], Person, Name] : String | EntityFramework.cs:192:13:192:15 | access to local variable ctx [PersonAddresses, [], Person, Name] : String | -| EntityFramework.cs:185:13:185:31 | [post] access to property PersonAddresses [[], Address, Street] : String | EntityFramework.cs:185:13:185:15 | [post] access to local variable ctx [PersonAddresses, [], Address, Street] : String | -| EntityFramework.cs:185:13:185:31 | [post] access to property PersonAddresses [[], Person, Name] : String | EntityFramework.cs:185:13:185:15 | [post] access to local variable ctx [PersonAddresses, [], Person, Name] : String | -| EntityFramework.cs:185:37:185:53 | access to local variable personAddressMap1 [Address, Street] : String | EntityFramework.cs:185:13:185:31 | [post] access to property PersonAddresses [[], Address, Street] : String | -| EntityFramework.cs:185:37:185:53 | access to local variable personAddressMap1 [Person, Name] : String | EntityFramework.cs:185:13:185:31 | [post] access to property PersonAddresses [[], Person, Name] : String | -| EntityFramework.cs:186:13:186:15 | access to local variable ctx [PersonAddresses, [], Address, Street] : String | ../../../resources/stubs/EntityFramework.cs:40:20:40:30 | this [PersonAddresses, [], Address, Street] : String | -| EntityFramework.cs:186:13:186:15 | access to local variable ctx [PersonAddresses, [], Person, Name] : String | ../../../resources/stubs/EntityFramework.cs:40:20:40:30 | this [PersonAddresses, [], Person, Name] : String | -| EntityFramework.cs:192:13:192:15 | access to local variable ctx [PersonAddresses, [], Address, Street] : String | ../../../resources/stubs/EntityFramework.cs:40:20:40:30 | this [PersonAddresses, [], Address, Street] : String | -| EntityFramework.cs:192:13:192:15 | access to local variable ctx [PersonAddresses, [], Person, Name] : String | ../../../resources/stubs/EntityFramework.cs:40:20:40:30 | this [PersonAddresses, [], Person, Name] : String | -| EntityFramework.cs:195:35:195:35 | p [Name] : String | EntityFramework.cs:198:29:198:29 | access to parameter p [Name] : String | -| EntityFramework.cs:198:13:198:15 | [post] access to local variable ctx [Persons, [], Name] : String | EntityFramework.cs:199:13:199:15 | access to local variable ctx [Persons, [], Name] : String | -| EntityFramework.cs:198:13:198:23 | [post] access to property Persons [[], Name] : String | EntityFramework.cs:198:13:198:15 | [post] access to local variable ctx [Persons, [], Name] : String | -| EntityFramework.cs:198:29:198:29 | access to parameter p [Name] : String | EntityFramework.cs:198:13:198:23 | [post] access to property Persons [[], Name] : String | -| EntityFramework.cs:199:13:199:15 | access to local variable ctx [Persons, [], Name] : String | ../../../resources/stubs/EntityFramework.cs:40:20:40:30 | this [Persons, [], Name] : String | -| EntityFramework.cs:206:18:206:28 | access to property Persons [[], Name] : String | EntityFramework.cs:206:18:206:36 | call to method First [Name] : String | -| EntityFramework.cs:206:18:206:36 | call to method First [Name] : String | EntityFramework.cs:206:18:206:41 | access to property Name | -| EntityFramework.cs:214:18:214:30 | access to property Addresses [[], Street] : String | EntityFramework.cs:214:18:214:38 | call to method First [Street] : String | -| EntityFramework.cs:214:18:214:38 | call to method First [Street] : String | EntityFramework.cs:214:18:214:45 | access to property Street | -| EntityFramework.cs:221:18:221:28 | access to property Persons [[], Addresses, [], Street] : String | EntityFramework.cs:221:18:221:36 | call to method First [Addresses, [], Street] : String | -| EntityFramework.cs:221:18:221:36 | call to method First [Addresses, [], Street] : String | EntityFramework.cs:221:18:221:46 | access to property Addresses [[], Street] : String | -| EntityFramework.cs:221:18:221:46 | access to property Addresses [[], Street] : String | EntityFramework.cs:221:18:221:54 | call to method First [Street] : String | -| EntityFramework.cs:221:18:221:54 | call to method First [Street] : String | EntityFramework.cs:221:18:221:61 | access to property Street | +| ../../../resources/stubs/EntityFramework.cs:40:20:40:30 | this [property Addresses, element, property Street] : String | EntityFramework.cs:214:18:214:30 | access to property Addresses [element, property Street] : String | +| ../../../resources/stubs/EntityFramework.cs:40:20:40:30 | this [property Addresses, element, property Street] : String | EntityFramework.cs:221:18:221:28 | access to property Persons [element, property Addresses, element, property Street] : String | +| ../../../resources/stubs/EntityFramework.cs:40:20:40:30 | this [property PersonAddresses, element, property Address, property Street] : String | EntityFramework.cs:214:18:214:30 | access to property Addresses [element, property Street] : String | +| ../../../resources/stubs/EntityFramework.cs:40:20:40:30 | this [property PersonAddresses, element, property Address, property Street] : String | EntityFramework.cs:221:18:221:28 | access to property Persons [element, property Addresses, element, property Street] : String | +| ../../../resources/stubs/EntityFramework.cs:40:20:40:30 | this [property PersonAddresses, element, property Person, property Name] : String | EntityFramework.cs:206:18:206:28 | access to property Persons [element, property Name] : String | +| ../../../resources/stubs/EntityFramework.cs:40:20:40:30 | this [property Persons, element, property Addresses, element, property Street] : String | EntityFramework.cs:214:18:214:30 | access to property Addresses [element, property Street] : String | +| ../../../resources/stubs/EntityFramework.cs:40:20:40:30 | this [property Persons, element, property Addresses, element, property Street] : String | EntityFramework.cs:221:18:221:28 | access to property Persons [element, property Addresses, element, property Street] : String | +| ../../../resources/stubs/EntityFramework.cs:40:20:40:30 | this [property Persons, element, property Name] : String | EntityFramework.cs:206:18:206:28 | access to property Persons [element, property Name] : String | +| ../../../resources/stubs/EntityFramework.cs:41:49:41:64 | this [property Persons, element, property Name] : String | EntityFramework.cs:206:18:206:28 | access to property Persons [element, property Name] : String | +| ../../../resources/stubs/EntityFramework.cs:80:20:80:30 | this [property Addresses, element, property Street] : String | EntityFrameworkCore.cs:238:18:238:30 | access to property Addresses [element, property Street] : String | +| ../../../resources/stubs/EntityFramework.cs:80:20:80:30 | this [property Addresses, element, property Street] : String | EntityFrameworkCore.cs:245:18:245:28 | access to property Persons [element, property Addresses, element, property Street] : String | +| ../../../resources/stubs/EntityFramework.cs:80:20:80:30 | this [property PersonAddresses, element, property Address, property Street] : String | EntityFrameworkCore.cs:238:18:238:30 | access to property Addresses [element, property Street] : String | +| ../../../resources/stubs/EntityFramework.cs:80:20:80:30 | this [property PersonAddresses, element, property Address, property Street] : String | EntityFrameworkCore.cs:245:18:245:28 | access to property Persons [element, property Addresses, element, property Street] : String | +| ../../../resources/stubs/EntityFramework.cs:80:20:80:30 | this [property PersonAddresses, element, property Person, property Name] : String | EntityFrameworkCore.cs:230:18:230:28 | access to property Persons [element, property Name] : String | +| ../../../resources/stubs/EntityFramework.cs:80:20:80:30 | this [property Persons, element, property Addresses, element, property Street] : String | EntityFrameworkCore.cs:238:18:238:30 | access to property Addresses [element, property Street] : String | +| ../../../resources/stubs/EntityFramework.cs:80:20:80:30 | this [property Persons, element, property Addresses, element, property Street] : String | EntityFrameworkCore.cs:245:18:245:28 | access to property Persons [element, property Addresses, element, property Street] : String | +| ../../../resources/stubs/EntityFramework.cs:80:20:80:30 | this [property Persons, element, property Name] : String | EntityFrameworkCore.cs:230:18:230:28 | access to property Persons [element, property Name] : String | +| ../../../resources/stubs/EntityFramework.cs:81:49:81:64 | this [property Persons, element, property Name] : String | EntityFrameworkCore.cs:230:18:230:28 | access to property Persons [element, property Name] : String | +| EntityFramework.cs:61:13:64:13 | { ..., ... } [property Name] : String | EntityFramework.cs:68:29:68:30 | access to local variable p1 [property Name] : String | +| EntityFramework.cs:63:24:63:32 | "tainted" : String | EntityFramework.cs:61:13:64:13 | { ..., ... } [property Name] : String | +| EntityFramework.cs:68:13:68:15 | [post] access to local variable ctx [property Persons, element, property Name] : String | EntityFramework.cs:70:13:70:15 | access to local variable ctx [property Persons, element, property Name] : String | +| EntityFramework.cs:68:13:68:23 | [post] access to property Persons [element, property Name] : String | EntityFramework.cs:68:13:68:15 | [post] access to local variable ctx [property Persons, element, property Name] : String | +| EntityFramework.cs:68:29:68:30 | access to local variable p1 [property Name] : String | EntityFramework.cs:68:13:68:23 | [post] access to property Persons [element, property Name] : String | +| EntityFramework.cs:70:13:70:15 | access to local variable ctx [property Persons, element, property Name] : String | ../../../resources/stubs/EntityFramework.cs:40:20:40:30 | this [property Persons, element, property Name] : String | +| EntityFramework.cs:83:13:86:13 | { ..., ... } [property Name] : String | EntityFramework.cs:90:29:90:30 | access to local variable p1 [property Name] : String | +| EntityFramework.cs:85:24:85:32 | "tainted" : String | EntityFramework.cs:83:13:86:13 | { ..., ... } [property Name] : String | +| EntityFramework.cs:90:13:90:15 | [post] access to local variable ctx [property Persons, element, property Name] : String | EntityFramework.cs:92:19:92:21 | access to local variable ctx [property Persons, element, property Name] : String | +| EntityFramework.cs:90:13:90:23 | [post] access to property Persons [element, property Name] : String | EntityFramework.cs:90:13:90:15 | [post] access to local variable ctx [property Persons, element, property Name] : String | +| EntityFramework.cs:90:29:90:30 | access to local variable p1 [property Name] : String | EntityFramework.cs:90:13:90:23 | [post] access to property Persons [element, property Name] : String | +| EntityFramework.cs:92:19:92:21 | access to local variable ctx [property Persons, element, property Name] : String | ../../../resources/stubs/EntityFramework.cs:41:49:41:64 | this [property Persons, element, property Name] : String | +| EntityFramework.cs:105:13:108:13 | { ..., ... } [property Name] : String | EntityFramework.cs:111:27:111:28 | access to local variable p1 [property Name] : String | +| EntityFramework.cs:107:24:107:32 | "tainted" : String | EntityFramework.cs:105:13:108:13 | { ..., ... } [property Name] : String | +| EntityFramework.cs:111:27:111:28 | access to local variable p1 [property Name] : String | EntityFramework.cs:195:35:195:35 | p [property Name] : String | +| EntityFramework.cs:124:13:127:13 | { ..., ... } [property Title] : String | EntityFramework.cs:131:18:131:19 | access to local variable p1 [property Title] : String | +| EntityFramework.cs:126:25:126:33 | "tainted" : String | EntityFramework.cs:124:13:127:13 | { ..., ... } [property Title] : String | +| EntityFramework.cs:131:18:131:19 | access to local variable p1 [property Title] : String | EntityFramework.cs:131:18:131:25 | access to property Title | +| EntityFramework.cs:143:13:150:13 | { ..., ... } [property Addresses, element, property Street] : String | EntityFramework.cs:151:29:151:30 | access to local variable p1 [property Addresses, element, property Street] : String | +| EntityFramework.cs:144:29:149:17 | array creation of type Address[] [element, property Street] : String | EntityFramework.cs:143:13:150:13 | { ..., ... } [property Addresses, element, property Street] : String | +| EntityFramework.cs:144:35:149:17 | { ..., ... } [element, property Street] : String | EntityFramework.cs:144:29:149:17 | array creation of type Address[] [element, property Street] : String | +| EntityFramework.cs:145:21:148:21 | object creation of type Address [property Street] : String | EntityFramework.cs:144:35:149:17 | { ..., ... } [element, property Street] : String | +| EntityFramework.cs:145:33:148:21 | { ..., ... } [property Street] : String | EntityFramework.cs:145:21:148:21 | object creation of type Address [property Street] : String | +| EntityFramework.cs:147:34:147:42 | "tainted" : String | EntityFramework.cs:145:33:148:21 | { ..., ... } [property Street] : String | +| EntityFramework.cs:151:13:151:15 | [post] access to local variable ctx [property Persons, element, property Addresses, element, property Street] : String | EntityFramework.cs:152:13:152:15 | access to local variable ctx [property Persons, element, property Addresses, element, property Street] : String | +| EntityFramework.cs:151:13:151:15 | [post] access to local variable ctx [property Persons, element, property Addresses, element, property Street] : String | EntityFramework.cs:156:13:156:15 | access to local variable ctx [property Persons, element, property Addresses, element, property Street] : String | +| EntityFramework.cs:151:13:151:15 | [post] access to local variable ctx [property Persons, element, property Addresses, element, property Street] : String | EntityFramework.cs:164:13:164:15 | access to local variable ctx [property Persons, element, property Addresses, element, property Street] : String | +| EntityFramework.cs:151:13:151:15 | [post] access to local variable ctx [property Persons, element, property Addresses, element, property Street] : String | EntityFramework.cs:168:13:168:15 | access to local variable ctx [property Persons, element, property Addresses, element, property Street] : String | +| EntityFramework.cs:151:13:151:23 | [post] access to property Persons [element, property Addresses, element, property Street] : String | EntityFramework.cs:151:13:151:15 | [post] access to local variable ctx [property Persons, element, property Addresses, element, property Street] : String | +| EntityFramework.cs:151:29:151:30 | access to local variable p1 [property Addresses, element, property Street] : String | EntityFramework.cs:151:13:151:23 | [post] access to property Persons [element, property Addresses, element, property Street] : String | +| EntityFramework.cs:152:13:152:15 | access to local variable ctx [property Persons, element, property Addresses, element, property Street] : String | ../../../resources/stubs/EntityFramework.cs:40:20:40:30 | this [property Persons, element, property Addresses, element, property Street] : String | +| EntityFramework.cs:156:13:156:15 | access to local variable ctx [property Persons, element, property Addresses, element, property Street] : String | ../../../resources/stubs/EntityFramework.cs:40:20:40:30 | this [property Persons, element, property Addresses, element, property Street] : String | +| EntityFramework.cs:159:13:162:13 | { ..., ... } [property Street] : String | EntityFramework.cs:163:31:163:32 | access to local variable a1 [property Street] : String | +| EntityFramework.cs:161:26:161:34 | "tainted" : String | EntityFramework.cs:159:13:162:13 | { ..., ... } [property Street] : String | +| EntityFramework.cs:163:13:163:15 | [post] access to local variable ctx [property Addresses, element, property Street] : String | EntityFramework.cs:164:13:164:15 | access to local variable ctx [property Addresses, element, property Street] : String | +| EntityFramework.cs:163:13:163:15 | [post] access to local variable ctx [property Addresses, element, property Street] : String | EntityFramework.cs:168:13:168:15 | access to local variable ctx [property Addresses, element, property Street] : String | +| EntityFramework.cs:163:13:163:25 | [post] access to property Addresses [element, property Street] : String | EntityFramework.cs:163:13:163:15 | [post] access to local variable ctx [property Addresses, element, property Street] : String | +| EntityFramework.cs:163:31:163:32 | access to local variable a1 [property Street] : String | EntityFramework.cs:163:13:163:25 | [post] access to property Addresses [element, property Street] : String | +| EntityFramework.cs:164:13:164:15 | access to local variable ctx [property Addresses, element, property Street] : String | ../../../resources/stubs/EntityFramework.cs:40:20:40:30 | this [property Addresses, element, property Street] : String | +| EntityFramework.cs:164:13:164:15 | access to local variable ctx [property Persons, element, property Addresses, element, property Street] : String | ../../../resources/stubs/EntityFramework.cs:40:20:40:30 | this [property Persons, element, property Addresses, element, property Street] : String | +| EntityFramework.cs:168:13:168:15 | access to local variable ctx [property Addresses, element, property Street] : String | ../../../resources/stubs/EntityFramework.cs:40:20:40:30 | this [property Addresses, element, property Street] : String | +| EntityFramework.cs:168:13:168:15 | access to local variable ctx [property Persons, element, property Addresses, element, property Street] : String | ../../../resources/stubs/EntityFramework.cs:40:20:40:30 | this [property Persons, element, property Addresses, element, property Street] : String | +| EntityFramework.cs:175:13:178:13 | { ..., ... } [property Name] : String | EntityFramework.cs:184:71:184:72 | access to local variable p1 [property Name] : String | +| EntityFramework.cs:177:24:177:32 | "tainted" : String | EntityFramework.cs:175:13:178:13 | { ..., ... } [property Name] : String | +| EntityFramework.cs:180:13:183:13 | { ..., ... } [property Street] : String | EntityFramework.cs:184:85:184:86 | access to local variable a1 [property Street] : String | +| EntityFramework.cs:182:26:182:34 | "tainted" : String | EntityFramework.cs:180:13:183:13 | { ..., ... } [property Street] : String | +| EntityFramework.cs:184:60:184:88 | { ..., ... } [property Address, property Street] : String | EntityFramework.cs:185:37:185:53 | access to local variable personAddressMap1 [property Address, property Street] : String | +| EntityFramework.cs:184:60:184:88 | { ..., ... } [property Person, property Name] : String | EntityFramework.cs:185:37:185:53 | access to local variable personAddressMap1 [property Person, property Name] : String | +| EntityFramework.cs:184:71:184:72 | access to local variable p1 [property Name] : String | EntityFramework.cs:184:60:184:88 | { ..., ... } [property Person, property Name] : String | +| EntityFramework.cs:184:85:184:86 | access to local variable a1 [property Street] : String | EntityFramework.cs:184:60:184:88 | { ..., ... } [property Address, property Street] : String | +| EntityFramework.cs:185:13:185:15 | [post] access to local variable ctx [property PersonAddresses, element, property Address, property Street] : String | EntityFramework.cs:186:13:186:15 | access to local variable ctx [property PersonAddresses, element, property Address, property Street] : String | +| EntityFramework.cs:185:13:185:15 | [post] access to local variable ctx [property PersonAddresses, element, property Address, property Street] : String | EntityFramework.cs:192:13:192:15 | access to local variable ctx [property PersonAddresses, element, property Address, property Street] : String | +| EntityFramework.cs:185:13:185:15 | [post] access to local variable ctx [property PersonAddresses, element, property Person, property Name] : String | EntityFramework.cs:186:13:186:15 | access to local variable ctx [property PersonAddresses, element, property Person, property Name] : String | +| EntityFramework.cs:185:13:185:15 | [post] access to local variable ctx [property PersonAddresses, element, property Person, property Name] : String | EntityFramework.cs:192:13:192:15 | access to local variable ctx [property PersonAddresses, element, property Person, property Name] : String | +| EntityFramework.cs:185:13:185:31 | [post] access to property PersonAddresses [element, property Address, property Street] : String | EntityFramework.cs:185:13:185:15 | [post] access to local variable ctx [property PersonAddresses, element, property Address, property Street] : String | +| EntityFramework.cs:185:13:185:31 | [post] access to property PersonAddresses [element, property Person, property Name] : String | EntityFramework.cs:185:13:185:15 | [post] access to local variable ctx [property PersonAddresses, element, property Person, property Name] : String | +| EntityFramework.cs:185:37:185:53 | access to local variable personAddressMap1 [property Address, property Street] : String | EntityFramework.cs:185:13:185:31 | [post] access to property PersonAddresses [element, property Address, property Street] : String | +| EntityFramework.cs:185:37:185:53 | access to local variable personAddressMap1 [property Person, property Name] : String | EntityFramework.cs:185:13:185:31 | [post] access to property PersonAddresses [element, property Person, property Name] : String | +| EntityFramework.cs:186:13:186:15 | access to local variable ctx [property PersonAddresses, element, property Address, property Street] : String | ../../../resources/stubs/EntityFramework.cs:40:20:40:30 | this [property PersonAddresses, element, property Address, property Street] : String | +| EntityFramework.cs:186:13:186:15 | access to local variable ctx [property PersonAddresses, element, property Person, property Name] : String | ../../../resources/stubs/EntityFramework.cs:40:20:40:30 | this [property PersonAddresses, element, property Person, property Name] : String | +| EntityFramework.cs:192:13:192:15 | access to local variable ctx [property PersonAddresses, element, property Address, property Street] : String | ../../../resources/stubs/EntityFramework.cs:40:20:40:30 | this [property PersonAddresses, element, property Address, property Street] : String | +| EntityFramework.cs:192:13:192:15 | access to local variable ctx [property PersonAddresses, element, property Person, property Name] : String | ../../../resources/stubs/EntityFramework.cs:40:20:40:30 | this [property PersonAddresses, element, property Person, property Name] : String | +| EntityFramework.cs:195:35:195:35 | p [property Name] : String | EntityFramework.cs:198:29:198:29 | access to parameter p [property Name] : String | +| EntityFramework.cs:198:13:198:15 | [post] access to local variable ctx [property Persons, element, property Name] : String | EntityFramework.cs:199:13:199:15 | access to local variable ctx [property Persons, element, property Name] : String | +| EntityFramework.cs:198:13:198:23 | [post] access to property Persons [element, property Name] : String | EntityFramework.cs:198:13:198:15 | [post] access to local variable ctx [property Persons, element, property Name] : String | +| EntityFramework.cs:198:29:198:29 | access to parameter p [property Name] : String | EntityFramework.cs:198:13:198:23 | [post] access to property Persons [element, property Name] : String | +| EntityFramework.cs:199:13:199:15 | access to local variable ctx [property Persons, element, property Name] : String | ../../../resources/stubs/EntityFramework.cs:40:20:40:30 | this [property Persons, element, property Name] : String | +| EntityFramework.cs:206:18:206:28 | access to property Persons [element, property Name] : String | EntityFramework.cs:206:18:206:36 | call to method First [property Name] : String | +| EntityFramework.cs:206:18:206:36 | call to method First [property Name] : String | EntityFramework.cs:206:18:206:41 | access to property Name | +| EntityFramework.cs:214:18:214:30 | access to property Addresses [element, property Street] : String | EntityFramework.cs:214:18:214:38 | call to method First [property Street] : String | +| EntityFramework.cs:214:18:214:38 | call to method First [property Street] : String | EntityFramework.cs:214:18:214:45 | access to property Street | +| EntityFramework.cs:221:18:221:28 | access to property Persons [element, property Addresses, element, property Street] : String | EntityFramework.cs:221:18:221:36 | call to method First [property Addresses, element, property Street] : String | +| EntityFramework.cs:221:18:221:36 | call to method First [property Addresses, element, property Street] : String | EntityFramework.cs:221:18:221:46 | access to property Addresses [element, property Street] : String | +| EntityFramework.cs:221:18:221:46 | access to property Addresses [element, property Street] : String | EntityFramework.cs:221:18:221:54 | call to method First [property Street] : String | +| EntityFramework.cs:221:18:221:54 | call to method First [property Street] : String | EntityFramework.cs:221:18:221:61 | access to property Street | | EntityFrameworkCore.cs:75:31:75:39 | "tainted" : String | EntityFrameworkCore.cs:76:18:76:28 | access to local variable taintSource | | EntityFrameworkCore.cs:75:31:75:39 | "tainted" : String | EntityFrameworkCore.cs:77:35:77:45 | access to local variable taintSource : String | | EntityFrameworkCore.cs:75:31:75:39 | "tainted" : String | EntityFrameworkCore.cs:78:32:78:42 | access to local variable taintSource : String | @@ -99,166 +99,166 @@ edges | EntityFrameworkCore.cs:77:35:77:45 | access to local variable taintSource : String | EntityFrameworkCore.cs:77:18:77:46 | object creation of type RawSqlString : RawSqlString | | EntityFrameworkCore.cs:78:18:78:42 | call to operator implicit conversion : RawSqlString | EntityFrameworkCore.cs:78:18:78:42 | (...) ... | | EntityFrameworkCore.cs:78:32:78:42 | access to local variable taintSource : String | EntityFrameworkCore.cs:78:18:78:42 | call to operator implicit conversion : RawSqlString | -| EntityFrameworkCore.cs:85:13:88:13 | { ..., ... } [Name] : String | EntityFrameworkCore.cs:92:29:92:30 | access to local variable p1 [Name] : String | -| EntityFrameworkCore.cs:87:24:87:32 | "tainted" : String | EntityFrameworkCore.cs:85:13:88:13 | { ..., ... } [Name] : String | -| EntityFrameworkCore.cs:92:13:92:15 | [post] access to local variable ctx [Persons, [], Name] : String | EntityFrameworkCore.cs:94:13:94:15 | access to local variable ctx [Persons, [], Name] : String | -| EntityFrameworkCore.cs:92:13:92:23 | [post] access to property Persons [[], Name] : String | EntityFrameworkCore.cs:92:13:92:15 | [post] access to local variable ctx [Persons, [], Name] : String | -| EntityFrameworkCore.cs:92:29:92:30 | access to local variable p1 [Name] : String | EntityFrameworkCore.cs:92:13:92:23 | [post] access to property Persons [[], Name] : String | -| EntityFrameworkCore.cs:94:13:94:15 | access to local variable ctx [Persons, [], Name] : String | ../../../resources/stubs/EntityFramework.cs:80:20:80:30 | this [Persons, [], Name] : String | -| EntityFrameworkCore.cs:107:13:110:13 | { ..., ... } [Name] : String | EntityFrameworkCore.cs:114:29:114:30 | access to local variable p1 [Name] : String | -| EntityFrameworkCore.cs:109:24:109:32 | "tainted" : String | EntityFrameworkCore.cs:107:13:110:13 | { ..., ... } [Name] : String | -| EntityFrameworkCore.cs:114:13:114:15 | [post] access to local variable ctx [Persons, [], Name] : String | EntityFrameworkCore.cs:116:19:116:21 | access to local variable ctx [Persons, [], Name] : String | -| EntityFrameworkCore.cs:114:13:114:23 | [post] access to property Persons [[], Name] : String | EntityFrameworkCore.cs:114:13:114:15 | [post] access to local variable ctx [Persons, [], Name] : String | -| EntityFrameworkCore.cs:114:29:114:30 | access to local variable p1 [Name] : String | EntityFrameworkCore.cs:114:13:114:23 | [post] access to property Persons [[], Name] : String | -| EntityFrameworkCore.cs:116:19:116:21 | access to local variable ctx [Persons, [], Name] : String | ../../../resources/stubs/EntityFramework.cs:81:49:81:64 | this [Persons, [], Name] : String | -| EntityFrameworkCore.cs:129:13:132:13 | { ..., ... } [Name] : String | EntityFrameworkCore.cs:135:27:135:28 | access to local variable p1 [Name] : String | -| EntityFrameworkCore.cs:131:24:131:32 | "tainted" : String | EntityFrameworkCore.cs:129:13:132:13 | { ..., ... } [Name] : String | -| EntityFrameworkCore.cs:135:27:135:28 | access to local variable p1 [Name] : String | EntityFrameworkCore.cs:219:35:219:35 | p [Name] : String | -| EntityFrameworkCore.cs:148:13:151:13 | { ..., ... } [Title] : String | EntityFrameworkCore.cs:155:18:155:19 | access to local variable p1 [Title] : String | -| EntityFrameworkCore.cs:150:25:150:33 | "tainted" : String | EntityFrameworkCore.cs:148:13:151:13 | { ..., ... } [Title] : String | -| EntityFrameworkCore.cs:155:18:155:19 | access to local variable p1 [Title] : String | EntityFrameworkCore.cs:155:18:155:25 | access to property Title | -| EntityFrameworkCore.cs:167:13:174:13 | { ..., ... } [Addresses, [], Street] : String | EntityFrameworkCore.cs:175:29:175:30 | access to local variable p1 [Addresses, [], Street] : String | -| EntityFrameworkCore.cs:168:29:173:17 | array creation of type Address[] [[], Street] : String | EntityFrameworkCore.cs:167:13:174:13 | { ..., ... } [Addresses, [], Street] : String | -| EntityFrameworkCore.cs:168:35:173:17 | { ..., ... } [[], Street] : String | EntityFrameworkCore.cs:168:29:173:17 | array creation of type Address[] [[], Street] : String | -| EntityFrameworkCore.cs:169:21:172:21 | object creation of type Address [Street] : String | EntityFrameworkCore.cs:168:35:173:17 | { ..., ... } [[], Street] : String | -| EntityFrameworkCore.cs:169:33:172:21 | { ..., ... } [Street] : String | EntityFrameworkCore.cs:169:21:172:21 | object creation of type Address [Street] : String | -| EntityFrameworkCore.cs:171:34:171:42 | "tainted" : String | EntityFrameworkCore.cs:169:33:172:21 | { ..., ... } [Street] : String | -| EntityFrameworkCore.cs:175:13:175:15 | [post] access to local variable ctx [Persons, [], Addresses, [], Street] : String | EntityFrameworkCore.cs:176:13:176:15 | access to local variable ctx [Persons, [], Addresses, [], Street] : String | -| EntityFrameworkCore.cs:175:13:175:15 | [post] access to local variable ctx [Persons, [], Addresses, [], Street] : String | EntityFrameworkCore.cs:180:13:180:15 | access to local variable ctx [Persons, [], Addresses, [], Street] : String | -| EntityFrameworkCore.cs:175:13:175:15 | [post] access to local variable ctx [Persons, [], Addresses, [], Street] : String | EntityFrameworkCore.cs:188:13:188:15 | access to local variable ctx [Persons, [], Addresses, [], Street] : String | -| EntityFrameworkCore.cs:175:13:175:15 | [post] access to local variable ctx [Persons, [], Addresses, [], Street] : String | EntityFrameworkCore.cs:192:13:192:15 | access to local variable ctx [Persons, [], Addresses, [], Street] : String | -| EntityFrameworkCore.cs:175:13:175:23 | [post] access to property Persons [[], Addresses, [], Street] : String | EntityFrameworkCore.cs:175:13:175:15 | [post] access to local variable ctx [Persons, [], Addresses, [], Street] : String | -| EntityFrameworkCore.cs:175:29:175:30 | access to local variable p1 [Addresses, [], Street] : String | EntityFrameworkCore.cs:175:13:175:23 | [post] access to property Persons [[], Addresses, [], Street] : String | -| EntityFrameworkCore.cs:176:13:176:15 | access to local variable ctx [Persons, [], Addresses, [], Street] : String | ../../../resources/stubs/EntityFramework.cs:80:20:80:30 | this [Persons, [], Addresses, [], Street] : String | -| EntityFrameworkCore.cs:180:13:180:15 | access to local variable ctx [Persons, [], Addresses, [], Street] : String | ../../../resources/stubs/EntityFramework.cs:80:20:80:30 | this [Persons, [], Addresses, [], Street] : String | -| EntityFrameworkCore.cs:183:13:186:13 | { ..., ... } [Street] : String | EntityFrameworkCore.cs:187:31:187:32 | access to local variable a1 [Street] : String | -| EntityFrameworkCore.cs:185:26:185:34 | "tainted" : String | EntityFrameworkCore.cs:183:13:186:13 | { ..., ... } [Street] : String | -| EntityFrameworkCore.cs:187:13:187:15 | [post] access to local variable ctx [Addresses, [], Street] : String | EntityFrameworkCore.cs:188:13:188:15 | access to local variable ctx [Addresses, [], Street] : String | -| EntityFrameworkCore.cs:187:13:187:15 | [post] access to local variable ctx [Addresses, [], Street] : String | EntityFrameworkCore.cs:192:13:192:15 | access to local variable ctx [Addresses, [], Street] : String | -| EntityFrameworkCore.cs:187:13:187:25 | [post] access to property Addresses [[], Street] : String | EntityFrameworkCore.cs:187:13:187:15 | [post] access to local variable ctx [Addresses, [], Street] : String | -| EntityFrameworkCore.cs:187:31:187:32 | access to local variable a1 [Street] : String | EntityFrameworkCore.cs:187:13:187:25 | [post] access to property Addresses [[], Street] : String | -| EntityFrameworkCore.cs:188:13:188:15 | access to local variable ctx [Addresses, [], Street] : String | ../../../resources/stubs/EntityFramework.cs:80:20:80:30 | this [Addresses, [], Street] : String | -| EntityFrameworkCore.cs:188:13:188:15 | access to local variable ctx [Persons, [], Addresses, [], Street] : String | ../../../resources/stubs/EntityFramework.cs:80:20:80:30 | this [Persons, [], Addresses, [], Street] : String | -| EntityFrameworkCore.cs:192:13:192:15 | access to local variable ctx [Addresses, [], Street] : String | ../../../resources/stubs/EntityFramework.cs:80:20:80:30 | this [Addresses, [], Street] : String | -| EntityFrameworkCore.cs:192:13:192:15 | access to local variable ctx [Persons, [], Addresses, [], Street] : String | ../../../resources/stubs/EntityFramework.cs:80:20:80:30 | this [Persons, [], Addresses, [], Street] : String | -| EntityFrameworkCore.cs:199:13:202:13 | { ..., ... } [Name] : String | EntityFrameworkCore.cs:208:71:208:72 | access to local variable p1 [Name] : String | -| EntityFrameworkCore.cs:201:24:201:32 | "tainted" : String | EntityFrameworkCore.cs:199:13:202:13 | { ..., ... } [Name] : String | -| EntityFrameworkCore.cs:204:13:207:13 | { ..., ... } [Street] : String | EntityFrameworkCore.cs:208:85:208:86 | access to local variable a1 [Street] : String | -| EntityFrameworkCore.cs:206:26:206:34 | "tainted" : String | EntityFrameworkCore.cs:204:13:207:13 | { ..., ... } [Street] : String | -| EntityFrameworkCore.cs:208:60:208:88 | { ..., ... } [Address, Street] : String | EntityFrameworkCore.cs:209:37:209:53 | access to local variable personAddressMap1 [Address, Street] : String | -| EntityFrameworkCore.cs:208:60:208:88 | { ..., ... } [Person, Name] : String | EntityFrameworkCore.cs:209:37:209:53 | access to local variable personAddressMap1 [Person, Name] : String | -| EntityFrameworkCore.cs:208:71:208:72 | access to local variable p1 [Name] : String | EntityFrameworkCore.cs:208:60:208:88 | { ..., ... } [Person, Name] : String | -| EntityFrameworkCore.cs:208:85:208:86 | access to local variable a1 [Street] : String | EntityFrameworkCore.cs:208:60:208:88 | { ..., ... } [Address, Street] : String | -| EntityFrameworkCore.cs:209:13:209:15 | [post] access to local variable ctx [PersonAddresses, [], Address, Street] : String | EntityFrameworkCore.cs:210:13:210:15 | access to local variable ctx [PersonAddresses, [], Address, Street] : String | -| EntityFrameworkCore.cs:209:13:209:15 | [post] access to local variable ctx [PersonAddresses, [], Address, Street] : String | EntityFrameworkCore.cs:216:13:216:15 | access to local variable ctx [PersonAddresses, [], Address, Street] : String | -| EntityFrameworkCore.cs:209:13:209:15 | [post] access to local variable ctx [PersonAddresses, [], Person, Name] : String | EntityFrameworkCore.cs:210:13:210:15 | access to local variable ctx [PersonAddresses, [], Person, Name] : String | -| EntityFrameworkCore.cs:209:13:209:15 | [post] access to local variable ctx [PersonAddresses, [], Person, Name] : String | EntityFrameworkCore.cs:216:13:216:15 | access to local variable ctx [PersonAddresses, [], Person, Name] : String | -| EntityFrameworkCore.cs:209:13:209:31 | [post] access to property PersonAddresses [[], Address, Street] : String | EntityFrameworkCore.cs:209:13:209:15 | [post] access to local variable ctx [PersonAddresses, [], Address, Street] : String | -| EntityFrameworkCore.cs:209:13:209:31 | [post] access to property PersonAddresses [[], Person, Name] : String | EntityFrameworkCore.cs:209:13:209:15 | [post] access to local variable ctx [PersonAddresses, [], Person, Name] : String | -| EntityFrameworkCore.cs:209:37:209:53 | access to local variable personAddressMap1 [Address, Street] : String | EntityFrameworkCore.cs:209:13:209:31 | [post] access to property PersonAddresses [[], Address, Street] : String | -| EntityFrameworkCore.cs:209:37:209:53 | access to local variable personAddressMap1 [Person, Name] : String | EntityFrameworkCore.cs:209:13:209:31 | [post] access to property PersonAddresses [[], Person, Name] : String | -| EntityFrameworkCore.cs:210:13:210:15 | access to local variable ctx [PersonAddresses, [], Address, Street] : String | ../../../resources/stubs/EntityFramework.cs:80:20:80:30 | this [PersonAddresses, [], Address, Street] : String | -| EntityFrameworkCore.cs:210:13:210:15 | access to local variable ctx [PersonAddresses, [], Person, Name] : String | ../../../resources/stubs/EntityFramework.cs:80:20:80:30 | this [PersonAddresses, [], Person, Name] : String | -| EntityFrameworkCore.cs:216:13:216:15 | access to local variable ctx [PersonAddresses, [], Address, Street] : String | ../../../resources/stubs/EntityFramework.cs:80:20:80:30 | this [PersonAddresses, [], Address, Street] : String | -| EntityFrameworkCore.cs:216:13:216:15 | access to local variable ctx [PersonAddresses, [], Person, Name] : String | ../../../resources/stubs/EntityFramework.cs:80:20:80:30 | this [PersonAddresses, [], Person, Name] : String | -| EntityFrameworkCore.cs:219:35:219:35 | p [Name] : String | EntityFrameworkCore.cs:222:29:222:29 | access to parameter p [Name] : String | -| EntityFrameworkCore.cs:222:13:222:15 | [post] access to local variable ctx [Persons, [], Name] : String | EntityFrameworkCore.cs:223:13:223:15 | access to local variable ctx [Persons, [], Name] : String | -| EntityFrameworkCore.cs:222:13:222:23 | [post] access to property Persons [[], Name] : String | EntityFrameworkCore.cs:222:13:222:15 | [post] access to local variable ctx [Persons, [], Name] : String | -| EntityFrameworkCore.cs:222:29:222:29 | access to parameter p [Name] : String | EntityFrameworkCore.cs:222:13:222:23 | [post] access to property Persons [[], Name] : String | -| EntityFrameworkCore.cs:223:13:223:15 | access to local variable ctx [Persons, [], Name] : String | ../../../resources/stubs/EntityFramework.cs:80:20:80:30 | this [Persons, [], Name] : String | -| EntityFrameworkCore.cs:230:18:230:28 | access to property Persons [[], Name] : String | EntityFrameworkCore.cs:230:18:230:36 | call to method First [Name] : String | -| EntityFrameworkCore.cs:230:18:230:36 | call to method First [Name] : String | EntityFrameworkCore.cs:230:18:230:41 | access to property Name | -| EntityFrameworkCore.cs:238:18:238:30 | access to property Addresses [[], Street] : String | EntityFrameworkCore.cs:238:18:238:38 | call to method First [Street] : String | -| EntityFrameworkCore.cs:238:18:238:38 | call to method First [Street] : String | EntityFrameworkCore.cs:238:18:238:45 | access to property Street | -| EntityFrameworkCore.cs:245:18:245:28 | access to property Persons [[], Addresses, [], Street] : String | EntityFrameworkCore.cs:245:18:245:36 | call to method First [Addresses, [], Street] : String | -| EntityFrameworkCore.cs:245:18:245:36 | call to method First [Addresses, [], Street] : String | EntityFrameworkCore.cs:245:18:245:46 | access to property Addresses [[], Street] : String | -| EntityFrameworkCore.cs:245:18:245:46 | access to property Addresses [[], Street] : String | EntityFrameworkCore.cs:245:18:245:54 | call to method First [Street] : String | -| EntityFrameworkCore.cs:245:18:245:54 | call to method First [Street] : String | EntityFrameworkCore.cs:245:18:245:61 | access to property Street | +| EntityFrameworkCore.cs:85:13:88:13 | { ..., ... } [property Name] : String | EntityFrameworkCore.cs:92:29:92:30 | access to local variable p1 [property Name] : String | +| EntityFrameworkCore.cs:87:24:87:32 | "tainted" : String | EntityFrameworkCore.cs:85:13:88:13 | { ..., ... } [property Name] : String | +| EntityFrameworkCore.cs:92:13:92:15 | [post] access to local variable ctx [property Persons, element, property Name] : String | EntityFrameworkCore.cs:94:13:94:15 | access to local variable ctx [property Persons, element, property Name] : String | +| EntityFrameworkCore.cs:92:13:92:23 | [post] access to property Persons [element, property Name] : String | EntityFrameworkCore.cs:92:13:92:15 | [post] access to local variable ctx [property Persons, element, property Name] : String | +| EntityFrameworkCore.cs:92:29:92:30 | access to local variable p1 [property Name] : String | EntityFrameworkCore.cs:92:13:92:23 | [post] access to property Persons [element, property Name] : String | +| EntityFrameworkCore.cs:94:13:94:15 | access to local variable ctx [property Persons, element, property Name] : String | ../../../resources/stubs/EntityFramework.cs:80:20:80:30 | this [property Persons, element, property Name] : String | +| EntityFrameworkCore.cs:107:13:110:13 | { ..., ... } [property Name] : String | EntityFrameworkCore.cs:114:29:114:30 | access to local variable p1 [property Name] : String | +| EntityFrameworkCore.cs:109:24:109:32 | "tainted" : String | EntityFrameworkCore.cs:107:13:110:13 | { ..., ... } [property Name] : String | +| EntityFrameworkCore.cs:114:13:114:15 | [post] access to local variable ctx [property Persons, element, property Name] : String | EntityFrameworkCore.cs:116:19:116:21 | access to local variable ctx [property Persons, element, property Name] : String | +| EntityFrameworkCore.cs:114:13:114:23 | [post] access to property Persons [element, property Name] : String | EntityFrameworkCore.cs:114:13:114:15 | [post] access to local variable ctx [property Persons, element, property Name] : String | +| EntityFrameworkCore.cs:114:29:114:30 | access to local variable p1 [property Name] : String | EntityFrameworkCore.cs:114:13:114:23 | [post] access to property Persons [element, property Name] : String | +| EntityFrameworkCore.cs:116:19:116:21 | access to local variable ctx [property Persons, element, property Name] : String | ../../../resources/stubs/EntityFramework.cs:81:49:81:64 | this [property Persons, element, property Name] : String | +| EntityFrameworkCore.cs:129:13:132:13 | { ..., ... } [property Name] : String | EntityFrameworkCore.cs:135:27:135:28 | access to local variable p1 [property Name] : String | +| EntityFrameworkCore.cs:131:24:131:32 | "tainted" : String | EntityFrameworkCore.cs:129:13:132:13 | { ..., ... } [property Name] : String | +| EntityFrameworkCore.cs:135:27:135:28 | access to local variable p1 [property Name] : String | EntityFrameworkCore.cs:219:35:219:35 | p [property Name] : String | +| EntityFrameworkCore.cs:148:13:151:13 | { ..., ... } [property Title] : String | EntityFrameworkCore.cs:155:18:155:19 | access to local variable p1 [property Title] : String | +| EntityFrameworkCore.cs:150:25:150:33 | "tainted" : String | EntityFrameworkCore.cs:148:13:151:13 | { ..., ... } [property Title] : String | +| EntityFrameworkCore.cs:155:18:155:19 | access to local variable p1 [property Title] : String | EntityFrameworkCore.cs:155:18:155:25 | access to property Title | +| EntityFrameworkCore.cs:167:13:174:13 | { ..., ... } [property Addresses, element, property Street] : String | EntityFrameworkCore.cs:175:29:175:30 | access to local variable p1 [property Addresses, element, property Street] : String | +| EntityFrameworkCore.cs:168:29:173:17 | array creation of type Address[] [element, property Street] : String | EntityFrameworkCore.cs:167:13:174:13 | { ..., ... } [property Addresses, element, property Street] : String | +| EntityFrameworkCore.cs:168:35:173:17 | { ..., ... } [element, property Street] : String | EntityFrameworkCore.cs:168:29:173:17 | array creation of type Address[] [element, property Street] : String | +| EntityFrameworkCore.cs:169:21:172:21 | object creation of type Address [property Street] : String | EntityFrameworkCore.cs:168:35:173:17 | { ..., ... } [element, property Street] : String | +| EntityFrameworkCore.cs:169:33:172:21 | { ..., ... } [property Street] : String | EntityFrameworkCore.cs:169:21:172:21 | object creation of type Address [property Street] : String | +| EntityFrameworkCore.cs:171:34:171:42 | "tainted" : String | EntityFrameworkCore.cs:169:33:172:21 | { ..., ... } [property Street] : String | +| EntityFrameworkCore.cs:175:13:175:15 | [post] access to local variable ctx [property Persons, element, property Addresses, element, property Street] : String | EntityFrameworkCore.cs:176:13:176:15 | access to local variable ctx [property Persons, element, property Addresses, element, property Street] : String | +| EntityFrameworkCore.cs:175:13:175:15 | [post] access to local variable ctx [property Persons, element, property Addresses, element, property Street] : String | EntityFrameworkCore.cs:180:13:180:15 | access to local variable ctx [property Persons, element, property Addresses, element, property Street] : String | +| EntityFrameworkCore.cs:175:13:175:15 | [post] access to local variable ctx [property Persons, element, property Addresses, element, property Street] : String | EntityFrameworkCore.cs:188:13:188:15 | access to local variable ctx [property Persons, element, property Addresses, element, property Street] : String | +| EntityFrameworkCore.cs:175:13:175:15 | [post] access to local variable ctx [property Persons, element, property Addresses, element, property Street] : String | EntityFrameworkCore.cs:192:13:192:15 | access to local variable ctx [property Persons, element, property Addresses, element, property Street] : String | +| EntityFrameworkCore.cs:175:13:175:23 | [post] access to property Persons [element, property Addresses, element, property Street] : String | EntityFrameworkCore.cs:175:13:175:15 | [post] access to local variable ctx [property Persons, element, property Addresses, element, property Street] : String | +| EntityFrameworkCore.cs:175:29:175:30 | access to local variable p1 [property Addresses, element, property Street] : String | EntityFrameworkCore.cs:175:13:175:23 | [post] access to property Persons [element, property Addresses, element, property Street] : String | +| EntityFrameworkCore.cs:176:13:176:15 | access to local variable ctx [property Persons, element, property Addresses, element, property Street] : String | ../../../resources/stubs/EntityFramework.cs:80:20:80:30 | this [property Persons, element, property Addresses, element, property Street] : String | +| EntityFrameworkCore.cs:180:13:180:15 | access to local variable ctx [property Persons, element, property Addresses, element, property Street] : String | ../../../resources/stubs/EntityFramework.cs:80:20:80:30 | this [property Persons, element, property Addresses, element, property Street] : String | +| EntityFrameworkCore.cs:183:13:186:13 | { ..., ... } [property Street] : String | EntityFrameworkCore.cs:187:31:187:32 | access to local variable a1 [property Street] : String | +| EntityFrameworkCore.cs:185:26:185:34 | "tainted" : String | EntityFrameworkCore.cs:183:13:186:13 | { ..., ... } [property Street] : String | +| EntityFrameworkCore.cs:187:13:187:15 | [post] access to local variable ctx [property Addresses, element, property Street] : String | EntityFrameworkCore.cs:188:13:188:15 | access to local variable ctx [property Addresses, element, property Street] : String | +| EntityFrameworkCore.cs:187:13:187:15 | [post] access to local variable ctx [property Addresses, element, property Street] : String | EntityFrameworkCore.cs:192:13:192:15 | access to local variable ctx [property Addresses, element, property Street] : String | +| EntityFrameworkCore.cs:187:13:187:25 | [post] access to property Addresses [element, property Street] : String | EntityFrameworkCore.cs:187:13:187:15 | [post] access to local variable ctx [property Addresses, element, property Street] : String | +| EntityFrameworkCore.cs:187:31:187:32 | access to local variable a1 [property Street] : String | EntityFrameworkCore.cs:187:13:187:25 | [post] access to property Addresses [element, property Street] : String | +| EntityFrameworkCore.cs:188:13:188:15 | access to local variable ctx [property Addresses, element, property Street] : String | ../../../resources/stubs/EntityFramework.cs:80:20:80:30 | this [property Addresses, element, property Street] : String | +| EntityFrameworkCore.cs:188:13:188:15 | access to local variable ctx [property Persons, element, property Addresses, element, property Street] : String | ../../../resources/stubs/EntityFramework.cs:80:20:80:30 | this [property Persons, element, property Addresses, element, property Street] : String | +| EntityFrameworkCore.cs:192:13:192:15 | access to local variable ctx [property Addresses, element, property Street] : String | ../../../resources/stubs/EntityFramework.cs:80:20:80:30 | this [property Addresses, element, property Street] : String | +| EntityFrameworkCore.cs:192:13:192:15 | access to local variable ctx [property Persons, element, property Addresses, element, property Street] : String | ../../../resources/stubs/EntityFramework.cs:80:20:80:30 | this [property Persons, element, property Addresses, element, property Street] : String | +| EntityFrameworkCore.cs:199:13:202:13 | { ..., ... } [property Name] : String | EntityFrameworkCore.cs:208:71:208:72 | access to local variable p1 [property Name] : String | +| EntityFrameworkCore.cs:201:24:201:32 | "tainted" : String | EntityFrameworkCore.cs:199:13:202:13 | { ..., ... } [property Name] : String | +| EntityFrameworkCore.cs:204:13:207:13 | { ..., ... } [property Street] : String | EntityFrameworkCore.cs:208:85:208:86 | access to local variable a1 [property Street] : String | +| EntityFrameworkCore.cs:206:26:206:34 | "tainted" : String | EntityFrameworkCore.cs:204:13:207:13 | { ..., ... } [property Street] : String | +| EntityFrameworkCore.cs:208:60:208:88 | { ..., ... } [property Address, property Street] : String | EntityFrameworkCore.cs:209:37:209:53 | access to local variable personAddressMap1 [property Address, property Street] : String | +| EntityFrameworkCore.cs:208:60:208:88 | { ..., ... } [property Person, property Name] : String | EntityFrameworkCore.cs:209:37:209:53 | access to local variable personAddressMap1 [property Person, property Name] : String | +| EntityFrameworkCore.cs:208:71:208:72 | access to local variable p1 [property Name] : String | EntityFrameworkCore.cs:208:60:208:88 | { ..., ... } [property Person, property Name] : String | +| EntityFrameworkCore.cs:208:85:208:86 | access to local variable a1 [property Street] : String | EntityFrameworkCore.cs:208:60:208:88 | { ..., ... } [property Address, property Street] : String | +| EntityFrameworkCore.cs:209:13:209:15 | [post] access to local variable ctx [property PersonAddresses, element, property Address, property Street] : String | EntityFrameworkCore.cs:210:13:210:15 | access to local variable ctx [property PersonAddresses, element, property Address, property Street] : String | +| EntityFrameworkCore.cs:209:13:209:15 | [post] access to local variable ctx [property PersonAddresses, element, property Address, property Street] : String | EntityFrameworkCore.cs:216:13:216:15 | access to local variable ctx [property PersonAddresses, element, property Address, property Street] : String | +| EntityFrameworkCore.cs:209:13:209:15 | [post] access to local variable ctx [property PersonAddresses, element, property Person, property Name] : String | EntityFrameworkCore.cs:210:13:210:15 | access to local variable ctx [property PersonAddresses, element, property Person, property Name] : String | +| EntityFrameworkCore.cs:209:13:209:15 | [post] access to local variable ctx [property PersonAddresses, element, property Person, property Name] : String | EntityFrameworkCore.cs:216:13:216:15 | access to local variable ctx [property PersonAddresses, element, property Person, property Name] : String | +| EntityFrameworkCore.cs:209:13:209:31 | [post] access to property PersonAddresses [element, property Address, property Street] : String | EntityFrameworkCore.cs:209:13:209:15 | [post] access to local variable ctx [property PersonAddresses, element, property Address, property Street] : String | +| EntityFrameworkCore.cs:209:13:209:31 | [post] access to property PersonAddresses [element, property Person, property Name] : String | EntityFrameworkCore.cs:209:13:209:15 | [post] access to local variable ctx [property PersonAddresses, element, property Person, property Name] : String | +| EntityFrameworkCore.cs:209:37:209:53 | access to local variable personAddressMap1 [property Address, property Street] : String | EntityFrameworkCore.cs:209:13:209:31 | [post] access to property PersonAddresses [element, property Address, property Street] : String | +| EntityFrameworkCore.cs:209:37:209:53 | access to local variable personAddressMap1 [property Person, property Name] : String | EntityFrameworkCore.cs:209:13:209:31 | [post] access to property PersonAddresses [element, property Person, property Name] : String | +| EntityFrameworkCore.cs:210:13:210:15 | access to local variable ctx [property PersonAddresses, element, property Address, property Street] : String | ../../../resources/stubs/EntityFramework.cs:80:20:80:30 | this [property PersonAddresses, element, property Address, property Street] : String | +| EntityFrameworkCore.cs:210:13:210:15 | access to local variable ctx [property PersonAddresses, element, property Person, property Name] : String | ../../../resources/stubs/EntityFramework.cs:80:20:80:30 | this [property PersonAddresses, element, property Person, property Name] : String | +| EntityFrameworkCore.cs:216:13:216:15 | access to local variable ctx [property PersonAddresses, element, property Address, property Street] : String | ../../../resources/stubs/EntityFramework.cs:80:20:80:30 | this [property PersonAddresses, element, property Address, property Street] : String | +| EntityFrameworkCore.cs:216:13:216:15 | access to local variable ctx [property PersonAddresses, element, property Person, property Name] : String | ../../../resources/stubs/EntityFramework.cs:80:20:80:30 | this [property PersonAddresses, element, property Person, property Name] : String | +| EntityFrameworkCore.cs:219:35:219:35 | p [property Name] : String | EntityFrameworkCore.cs:222:29:222:29 | access to parameter p [property Name] : String | +| EntityFrameworkCore.cs:222:13:222:15 | [post] access to local variable ctx [property Persons, element, property Name] : String | EntityFrameworkCore.cs:223:13:223:15 | access to local variable ctx [property Persons, element, property Name] : String | +| EntityFrameworkCore.cs:222:13:222:23 | [post] access to property Persons [element, property Name] : String | EntityFrameworkCore.cs:222:13:222:15 | [post] access to local variable ctx [property Persons, element, property Name] : String | +| EntityFrameworkCore.cs:222:29:222:29 | access to parameter p [property Name] : String | EntityFrameworkCore.cs:222:13:222:23 | [post] access to property Persons [element, property Name] : String | +| EntityFrameworkCore.cs:223:13:223:15 | access to local variable ctx [property Persons, element, property Name] : String | ../../../resources/stubs/EntityFramework.cs:80:20:80:30 | this [property Persons, element, property Name] : String | +| EntityFrameworkCore.cs:230:18:230:28 | access to property Persons [element, property Name] : String | EntityFrameworkCore.cs:230:18:230:36 | call to method First [property Name] : String | +| EntityFrameworkCore.cs:230:18:230:36 | call to method First [property Name] : String | EntityFrameworkCore.cs:230:18:230:41 | access to property Name | +| EntityFrameworkCore.cs:238:18:238:30 | access to property Addresses [element, property Street] : String | EntityFrameworkCore.cs:238:18:238:38 | call to method First [property Street] : String | +| EntityFrameworkCore.cs:238:18:238:38 | call to method First [property Street] : String | EntityFrameworkCore.cs:238:18:238:45 | access to property Street | +| EntityFrameworkCore.cs:245:18:245:28 | access to property Persons [element, property Addresses, element, property Street] : String | EntityFrameworkCore.cs:245:18:245:36 | call to method First [property Addresses, element, property Street] : String | +| EntityFrameworkCore.cs:245:18:245:36 | call to method First [property Addresses, element, property Street] : String | EntityFrameworkCore.cs:245:18:245:46 | access to property Addresses [element, property Street] : String | +| EntityFrameworkCore.cs:245:18:245:46 | access to property Addresses [element, property Street] : String | EntityFrameworkCore.cs:245:18:245:54 | call to method First [property Street] : String | +| EntityFrameworkCore.cs:245:18:245:54 | call to method First [property Street] : String | EntityFrameworkCore.cs:245:18:245:61 | access to property Street | nodes -| ../../../resources/stubs/EntityFramework.cs:40:20:40:30 | this [Addresses, [], Street] : String | semmle.label | this [Addresses, [], Street] : String | -| ../../../resources/stubs/EntityFramework.cs:40:20:40:30 | this [PersonAddresses, [], Address, Street] : String | semmle.label | this [PersonAddresses, [], Address, Street] : String | -| ../../../resources/stubs/EntityFramework.cs:40:20:40:30 | this [PersonAddresses, [], Person, Name] : String | semmle.label | this [PersonAddresses, [], Person, Name] : String | -| ../../../resources/stubs/EntityFramework.cs:40:20:40:30 | this [Persons, [], Addresses, [], Street] : String | semmle.label | this [Persons, [], Addresses, [], Street] : String | -| ../../../resources/stubs/EntityFramework.cs:40:20:40:30 | this [Persons, [], Name] : String | semmle.label | this [Persons, [], Name] : String | -| ../../../resources/stubs/EntityFramework.cs:41:49:41:64 | this [Persons, [], Name] : String | semmle.label | this [Persons, [], Name] : String | -| ../../../resources/stubs/EntityFramework.cs:80:20:80:30 | this [Addresses, [], Street] : String | semmle.label | this [Addresses, [], Street] : String | -| ../../../resources/stubs/EntityFramework.cs:80:20:80:30 | this [PersonAddresses, [], Address, Street] : String | semmle.label | this [PersonAddresses, [], Address, Street] : String | -| ../../../resources/stubs/EntityFramework.cs:80:20:80:30 | this [PersonAddresses, [], Person, Name] : String | semmle.label | this [PersonAddresses, [], Person, Name] : String | -| ../../../resources/stubs/EntityFramework.cs:80:20:80:30 | this [Persons, [], Addresses, [], Street] : String | semmle.label | this [Persons, [], Addresses, [], Street] : String | -| ../../../resources/stubs/EntityFramework.cs:80:20:80:30 | this [Persons, [], Name] : String | semmle.label | this [Persons, [], Name] : String | -| ../../../resources/stubs/EntityFramework.cs:81:49:81:64 | this [Persons, [], Name] : String | semmle.label | this [Persons, [], Name] : String | -| EntityFramework.cs:61:13:64:13 | { ..., ... } [Name] : String | semmle.label | { ..., ... } [Name] : String | +| ../../../resources/stubs/EntityFramework.cs:40:20:40:30 | this [property Addresses, element, property Street] : String | semmle.label | this [property Addresses, element, property Street] : String | +| ../../../resources/stubs/EntityFramework.cs:40:20:40:30 | this [property PersonAddresses, element, property Address, property Street] : String | semmle.label | this [property PersonAddresses, element, property Address, property Street] : String | +| ../../../resources/stubs/EntityFramework.cs:40:20:40:30 | this [property PersonAddresses, element, property Person, property Name] : String | semmle.label | this [property PersonAddresses, element, property Person, property Name] : String | +| ../../../resources/stubs/EntityFramework.cs:40:20:40:30 | this [property Persons, element, property Addresses, element, property Street] : String | semmle.label | this [property Persons, element, property Addresses, element, property Street] : String | +| ../../../resources/stubs/EntityFramework.cs:40:20:40:30 | this [property Persons, element, property Name] : String | semmle.label | this [property Persons, element, property Name] : String | +| ../../../resources/stubs/EntityFramework.cs:41:49:41:64 | this [property Persons, element, property Name] : String | semmle.label | this [property Persons, element, property Name] : String | +| ../../../resources/stubs/EntityFramework.cs:80:20:80:30 | this [property Addresses, element, property Street] : String | semmle.label | this [property Addresses, element, property Street] : String | +| ../../../resources/stubs/EntityFramework.cs:80:20:80:30 | this [property PersonAddresses, element, property Address, property Street] : String | semmle.label | this [property PersonAddresses, element, property Address, property Street] : String | +| ../../../resources/stubs/EntityFramework.cs:80:20:80:30 | this [property PersonAddresses, element, property Person, property Name] : String | semmle.label | this [property PersonAddresses, element, property Person, property Name] : String | +| ../../../resources/stubs/EntityFramework.cs:80:20:80:30 | this [property Persons, element, property Addresses, element, property Street] : String | semmle.label | this [property Persons, element, property Addresses, element, property Street] : String | +| ../../../resources/stubs/EntityFramework.cs:80:20:80:30 | this [property Persons, element, property Name] : String | semmle.label | this [property Persons, element, property Name] : String | +| ../../../resources/stubs/EntityFramework.cs:81:49:81:64 | this [property Persons, element, property Name] : String | semmle.label | this [property Persons, element, property Name] : String | +| EntityFramework.cs:61:13:64:13 | { ..., ... } [property Name] : String | semmle.label | { ..., ... } [property Name] : String | | EntityFramework.cs:63:24:63:32 | "tainted" : String | semmle.label | "tainted" : String | -| EntityFramework.cs:68:13:68:15 | [post] access to local variable ctx [Persons, [], Name] : String | semmle.label | [post] access to local variable ctx [Persons, [], Name] : String | -| EntityFramework.cs:68:13:68:23 | [post] access to property Persons [[], Name] : String | semmle.label | [post] access to property Persons [[], Name] : String | -| EntityFramework.cs:68:29:68:30 | access to local variable p1 [Name] : String | semmle.label | access to local variable p1 [Name] : String | -| EntityFramework.cs:70:13:70:15 | access to local variable ctx [Persons, [], Name] : String | semmle.label | access to local variable ctx [Persons, [], Name] : String | -| EntityFramework.cs:83:13:86:13 | { ..., ... } [Name] : String | semmle.label | { ..., ... } [Name] : String | +| EntityFramework.cs:68:13:68:15 | [post] access to local variable ctx [property Persons, element, property Name] : String | semmle.label | [post] access to local variable ctx [property Persons, element, property Name] : String | +| EntityFramework.cs:68:13:68:23 | [post] access to property Persons [element, property Name] : String | semmle.label | [post] access to property Persons [element, property Name] : String | +| EntityFramework.cs:68:29:68:30 | access to local variable p1 [property Name] : String | semmle.label | access to local variable p1 [property Name] : String | +| EntityFramework.cs:70:13:70:15 | access to local variable ctx [property Persons, element, property Name] : String | semmle.label | access to local variable ctx [property Persons, element, property Name] : String | +| EntityFramework.cs:83:13:86:13 | { ..., ... } [property Name] : String | semmle.label | { ..., ... } [property Name] : String | | EntityFramework.cs:85:24:85:32 | "tainted" : String | semmle.label | "tainted" : String | -| EntityFramework.cs:90:13:90:15 | [post] access to local variable ctx [Persons, [], Name] : String | semmle.label | [post] access to local variable ctx [Persons, [], Name] : String | -| EntityFramework.cs:90:13:90:23 | [post] access to property Persons [[], Name] : String | semmle.label | [post] access to property Persons [[], Name] : String | -| EntityFramework.cs:90:29:90:30 | access to local variable p1 [Name] : String | semmle.label | access to local variable p1 [Name] : String | -| EntityFramework.cs:92:19:92:21 | access to local variable ctx [Persons, [], Name] : String | semmle.label | access to local variable ctx [Persons, [], Name] : String | -| EntityFramework.cs:105:13:108:13 | { ..., ... } [Name] : String | semmle.label | { ..., ... } [Name] : String | +| EntityFramework.cs:90:13:90:15 | [post] access to local variable ctx [property Persons, element, property Name] : String | semmle.label | [post] access to local variable ctx [property Persons, element, property Name] : String | +| EntityFramework.cs:90:13:90:23 | [post] access to property Persons [element, property Name] : String | semmle.label | [post] access to property Persons [element, property Name] : String | +| EntityFramework.cs:90:29:90:30 | access to local variable p1 [property Name] : String | semmle.label | access to local variable p1 [property Name] : String | +| EntityFramework.cs:92:19:92:21 | access to local variable ctx [property Persons, element, property Name] : String | semmle.label | access to local variable ctx [property Persons, element, property Name] : String | +| EntityFramework.cs:105:13:108:13 | { ..., ... } [property Name] : String | semmle.label | { ..., ... } [property Name] : String | | EntityFramework.cs:107:24:107:32 | "tainted" : String | semmle.label | "tainted" : String | -| EntityFramework.cs:111:27:111:28 | access to local variable p1 [Name] : String | semmle.label | access to local variable p1 [Name] : String | -| EntityFramework.cs:124:13:127:13 | { ..., ... } [Title] : String | semmle.label | { ..., ... } [Title] : String | +| EntityFramework.cs:111:27:111:28 | access to local variable p1 [property Name] : String | semmle.label | access to local variable p1 [property Name] : String | +| EntityFramework.cs:124:13:127:13 | { ..., ... } [property Title] : String | semmle.label | { ..., ... } [property Title] : String | | EntityFramework.cs:126:25:126:33 | "tainted" : String | semmle.label | "tainted" : String | -| EntityFramework.cs:131:18:131:19 | access to local variable p1 [Title] : String | semmle.label | access to local variable p1 [Title] : String | +| EntityFramework.cs:131:18:131:19 | access to local variable p1 [property Title] : String | semmle.label | access to local variable p1 [property Title] : String | | EntityFramework.cs:131:18:131:25 | access to property Title | semmle.label | access to property Title | -| EntityFramework.cs:143:13:150:13 | { ..., ... } [Addresses, [], Street] : String | semmle.label | { ..., ... } [Addresses, [], Street] : String | -| EntityFramework.cs:144:29:149:17 | array creation of type Address[] [[], Street] : String | semmle.label | array creation of type Address[] [[], Street] : String | -| EntityFramework.cs:144:35:149:17 | { ..., ... } [[], Street] : String | semmle.label | { ..., ... } [[], Street] : String | -| EntityFramework.cs:145:21:148:21 | object creation of type Address [Street] : String | semmle.label | object creation of type Address [Street] : String | -| EntityFramework.cs:145:33:148:21 | { ..., ... } [Street] : String | semmle.label | { ..., ... } [Street] : String | +| EntityFramework.cs:143:13:150:13 | { ..., ... } [property Addresses, element, property Street] : String | semmle.label | { ..., ... } [property Addresses, element, property Street] : String | +| EntityFramework.cs:144:29:149:17 | array creation of type Address[] [element, property Street] : String | semmle.label | array creation of type Address[] [element, property Street] : String | +| EntityFramework.cs:144:35:149:17 | { ..., ... } [element, property Street] : String | semmle.label | { ..., ... } [element, property Street] : String | +| EntityFramework.cs:145:21:148:21 | object creation of type Address [property Street] : String | semmle.label | object creation of type Address [property Street] : String | +| EntityFramework.cs:145:33:148:21 | { ..., ... } [property Street] : String | semmle.label | { ..., ... } [property Street] : String | | EntityFramework.cs:147:34:147:42 | "tainted" : String | semmle.label | "tainted" : String | -| EntityFramework.cs:151:13:151:15 | [post] access to local variable ctx [Persons, [], Addresses, [], Street] : String | semmle.label | [post] access to local variable ctx [Persons, [], Addresses, [], Street] : String | -| EntityFramework.cs:151:13:151:23 | [post] access to property Persons [[], Addresses, [], Street] : String | semmle.label | [post] access to property Persons [[], Addresses, [], Street] : String | -| EntityFramework.cs:151:29:151:30 | access to local variable p1 [Addresses, [], Street] : String | semmle.label | access to local variable p1 [Addresses, [], Street] : String | -| EntityFramework.cs:152:13:152:15 | access to local variable ctx [Persons, [], Addresses, [], Street] : String | semmle.label | access to local variable ctx [Persons, [], Addresses, [], Street] : String | -| EntityFramework.cs:156:13:156:15 | access to local variable ctx [Persons, [], Addresses, [], Street] : String | semmle.label | access to local variable ctx [Persons, [], Addresses, [], Street] : String | -| EntityFramework.cs:159:13:162:13 | { ..., ... } [Street] : String | semmle.label | { ..., ... } [Street] : String | +| EntityFramework.cs:151:13:151:15 | [post] access to local variable ctx [property Persons, element, property Addresses, element, property Street] : String | semmle.label | [post] access to local variable ctx [property Persons, element, property Addresses, element, property Street] : String | +| EntityFramework.cs:151:13:151:23 | [post] access to property Persons [element, property Addresses, element, property Street] : String | semmle.label | [post] access to property Persons [element, property Addresses, element, property Street] : String | +| EntityFramework.cs:151:29:151:30 | access to local variable p1 [property Addresses, element, property Street] : String | semmle.label | access to local variable p1 [property Addresses, element, property Street] : String | +| EntityFramework.cs:152:13:152:15 | access to local variable ctx [property Persons, element, property Addresses, element, property Street] : String | semmle.label | access to local variable ctx [property Persons, element, property Addresses, element, property Street] : String | +| EntityFramework.cs:156:13:156:15 | access to local variable ctx [property Persons, element, property Addresses, element, property Street] : String | semmle.label | access to local variable ctx [property Persons, element, property Addresses, element, property Street] : String | +| EntityFramework.cs:159:13:162:13 | { ..., ... } [property Street] : String | semmle.label | { ..., ... } [property Street] : String | | EntityFramework.cs:161:26:161:34 | "tainted" : String | semmle.label | "tainted" : String | -| EntityFramework.cs:163:13:163:15 | [post] access to local variable ctx [Addresses, [], Street] : String | semmle.label | [post] access to local variable ctx [Addresses, [], Street] : String | -| EntityFramework.cs:163:13:163:25 | [post] access to property Addresses [[], Street] : String | semmle.label | [post] access to property Addresses [[], Street] : String | -| EntityFramework.cs:163:31:163:32 | access to local variable a1 [Street] : String | semmle.label | access to local variable a1 [Street] : String | -| EntityFramework.cs:164:13:164:15 | access to local variable ctx [Addresses, [], Street] : String | semmle.label | access to local variable ctx [Addresses, [], Street] : String | -| EntityFramework.cs:164:13:164:15 | access to local variable ctx [Persons, [], Addresses, [], Street] : String | semmle.label | access to local variable ctx [Persons, [], Addresses, [], Street] : String | -| EntityFramework.cs:168:13:168:15 | access to local variable ctx [Addresses, [], Street] : String | semmle.label | access to local variable ctx [Addresses, [], Street] : String | -| EntityFramework.cs:168:13:168:15 | access to local variable ctx [Persons, [], Addresses, [], Street] : String | semmle.label | access to local variable ctx [Persons, [], Addresses, [], Street] : String | -| EntityFramework.cs:175:13:178:13 | { ..., ... } [Name] : String | semmle.label | { ..., ... } [Name] : String | +| EntityFramework.cs:163:13:163:15 | [post] access to local variable ctx [property Addresses, element, property Street] : String | semmle.label | [post] access to local variable ctx [property Addresses, element, property Street] : String | +| EntityFramework.cs:163:13:163:25 | [post] access to property Addresses [element, property Street] : String | semmle.label | [post] access to property Addresses [element, property Street] : String | +| EntityFramework.cs:163:31:163:32 | access to local variable a1 [property Street] : String | semmle.label | access to local variable a1 [property Street] : String | +| EntityFramework.cs:164:13:164:15 | access to local variable ctx [property Addresses, element, property Street] : String | semmle.label | access to local variable ctx [property Addresses, element, property Street] : String | +| EntityFramework.cs:164:13:164:15 | access to local variable ctx [property Persons, element, property Addresses, element, property Street] : String | semmle.label | access to local variable ctx [property Persons, element, property Addresses, element, property Street] : String | +| EntityFramework.cs:168:13:168:15 | access to local variable ctx [property Addresses, element, property Street] : String | semmle.label | access to local variable ctx [property Addresses, element, property Street] : String | +| EntityFramework.cs:168:13:168:15 | access to local variable ctx [property Persons, element, property Addresses, element, property Street] : String | semmle.label | access to local variable ctx [property Persons, element, property Addresses, element, property Street] : String | +| EntityFramework.cs:175:13:178:13 | { ..., ... } [property Name] : String | semmle.label | { ..., ... } [property Name] : String | | EntityFramework.cs:177:24:177:32 | "tainted" : String | semmle.label | "tainted" : String | -| EntityFramework.cs:180:13:183:13 | { ..., ... } [Street] : String | semmle.label | { ..., ... } [Street] : String | +| EntityFramework.cs:180:13:183:13 | { ..., ... } [property Street] : String | semmle.label | { ..., ... } [property Street] : String | | EntityFramework.cs:182:26:182:34 | "tainted" : String | semmle.label | "tainted" : String | -| EntityFramework.cs:184:60:184:88 | { ..., ... } [Address, Street] : String | semmle.label | { ..., ... } [Address, Street] : String | -| EntityFramework.cs:184:60:184:88 | { ..., ... } [Person, Name] : String | semmle.label | { ..., ... } [Person, Name] : String | -| EntityFramework.cs:184:71:184:72 | access to local variable p1 [Name] : String | semmle.label | access to local variable p1 [Name] : String | -| EntityFramework.cs:184:85:184:86 | access to local variable a1 [Street] : String | semmle.label | access to local variable a1 [Street] : String | -| EntityFramework.cs:185:13:185:15 | [post] access to local variable ctx [PersonAddresses, [], Address, Street] : String | semmle.label | [post] access to local variable ctx [PersonAddresses, [], Address, Street] : String | -| EntityFramework.cs:185:13:185:15 | [post] access to local variable ctx [PersonAddresses, [], Person, Name] : String | semmle.label | [post] access to local variable ctx [PersonAddresses, [], Person, Name] : String | -| EntityFramework.cs:185:13:185:31 | [post] access to property PersonAddresses [[], Address, Street] : String | semmle.label | [post] access to property PersonAddresses [[], Address, Street] : String | -| EntityFramework.cs:185:13:185:31 | [post] access to property PersonAddresses [[], Person, Name] : String | semmle.label | [post] access to property PersonAddresses [[], Person, Name] : String | -| EntityFramework.cs:185:37:185:53 | access to local variable personAddressMap1 [Address, Street] : String | semmle.label | access to local variable personAddressMap1 [Address, Street] : String | -| EntityFramework.cs:185:37:185:53 | access to local variable personAddressMap1 [Person, Name] : String | semmle.label | access to local variable personAddressMap1 [Person, Name] : String | -| EntityFramework.cs:186:13:186:15 | access to local variable ctx [PersonAddresses, [], Address, Street] : String | semmle.label | access to local variable ctx [PersonAddresses, [], Address, Street] : String | -| EntityFramework.cs:186:13:186:15 | access to local variable ctx [PersonAddresses, [], Person, Name] : String | semmle.label | access to local variable ctx [PersonAddresses, [], Person, Name] : String | -| EntityFramework.cs:192:13:192:15 | access to local variable ctx [PersonAddresses, [], Address, Street] : String | semmle.label | access to local variable ctx [PersonAddresses, [], Address, Street] : String | -| EntityFramework.cs:192:13:192:15 | access to local variable ctx [PersonAddresses, [], Person, Name] : String | semmle.label | access to local variable ctx [PersonAddresses, [], Person, Name] : String | -| EntityFramework.cs:195:35:195:35 | p [Name] : String | semmle.label | p [Name] : String | -| EntityFramework.cs:198:13:198:15 | [post] access to local variable ctx [Persons, [], Name] : String | semmle.label | [post] access to local variable ctx [Persons, [], Name] : String | -| EntityFramework.cs:198:13:198:23 | [post] access to property Persons [[], Name] : String | semmle.label | [post] access to property Persons [[], Name] : String | -| EntityFramework.cs:198:29:198:29 | access to parameter p [Name] : String | semmle.label | access to parameter p [Name] : String | -| EntityFramework.cs:199:13:199:15 | access to local variable ctx [Persons, [], Name] : String | semmle.label | access to local variable ctx [Persons, [], Name] : String | -| EntityFramework.cs:206:18:206:28 | access to property Persons [[], Name] : String | semmle.label | access to property Persons [[], Name] : String | -| EntityFramework.cs:206:18:206:36 | call to method First [Name] : String | semmle.label | call to method First [Name] : String | +| EntityFramework.cs:184:60:184:88 | { ..., ... } [property Address, property Street] : String | semmle.label | { ..., ... } [property Address, property Street] : String | +| EntityFramework.cs:184:60:184:88 | { ..., ... } [property Person, property Name] : String | semmle.label | { ..., ... } [property Person, property Name] : String | +| EntityFramework.cs:184:71:184:72 | access to local variable p1 [property Name] : String | semmle.label | access to local variable p1 [property Name] : String | +| EntityFramework.cs:184:85:184:86 | access to local variable a1 [property Street] : String | semmle.label | access to local variable a1 [property Street] : String | +| EntityFramework.cs:185:13:185:15 | [post] access to local variable ctx [property PersonAddresses, element, property Address, property Street] : String | semmle.label | [post] access to local variable ctx [property PersonAddresses, element, property Address, property Street] : String | +| EntityFramework.cs:185:13:185:15 | [post] access to local variable ctx [property PersonAddresses, element, property Person, property Name] : String | semmle.label | [post] access to local variable ctx [property PersonAddresses, element, property Person, property Name] : String | +| EntityFramework.cs:185:13:185:31 | [post] access to property PersonAddresses [element, property Address, property Street] : String | semmle.label | [post] access to property PersonAddresses [element, property Address, property Street] : String | +| EntityFramework.cs:185:13:185:31 | [post] access to property PersonAddresses [element, property Person, property Name] : String | semmle.label | [post] access to property PersonAddresses [element, property Person, property Name] : String | +| EntityFramework.cs:185:37:185:53 | access to local variable personAddressMap1 [property Address, property Street] : String | semmle.label | access to local variable personAddressMap1 [property Address, property Street] : String | +| EntityFramework.cs:185:37:185:53 | access to local variable personAddressMap1 [property Person, property Name] : String | semmle.label | access to local variable personAddressMap1 [property Person, property Name] : String | +| EntityFramework.cs:186:13:186:15 | access to local variable ctx [property PersonAddresses, element, property Address, property Street] : String | semmle.label | access to local variable ctx [property PersonAddresses, element, property Address, property Street] : String | +| EntityFramework.cs:186:13:186:15 | access to local variable ctx [property PersonAddresses, element, property Person, property Name] : String | semmle.label | access to local variable ctx [property PersonAddresses, element, property Person, property Name] : String | +| EntityFramework.cs:192:13:192:15 | access to local variable ctx [property PersonAddresses, element, property Address, property Street] : String | semmle.label | access to local variable ctx [property PersonAddresses, element, property Address, property Street] : String | +| EntityFramework.cs:192:13:192:15 | access to local variable ctx [property PersonAddresses, element, property Person, property Name] : String | semmle.label | access to local variable ctx [property PersonAddresses, element, property Person, property Name] : String | +| EntityFramework.cs:195:35:195:35 | p [property Name] : String | semmle.label | p [property Name] : String | +| EntityFramework.cs:198:13:198:15 | [post] access to local variable ctx [property Persons, element, property Name] : String | semmle.label | [post] access to local variable ctx [property Persons, element, property Name] : String | +| EntityFramework.cs:198:13:198:23 | [post] access to property Persons [element, property Name] : String | semmle.label | [post] access to property Persons [element, property Name] : String | +| EntityFramework.cs:198:29:198:29 | access to parameter p [property Name] : String | semmle.label | access to parameter p [property Name] : String | +| EntityFramework.cs:199:13:199:15 | access to local variable ctx [property Persons, element, property Name] : String | semmle.label | access to local variable ctx [property Persons, element, property Name] : String | +| EntityFramework.cs:206:18:206:28 | access to property Persons [element, property Name] : String | semmle.label | access to property Persons [element, property Name] : String | +| EntityFramework.cs:206:18:206:36 | call to method First [property Name] : String | semmle.label | call to method First [property Name] : String | | EntityFramework.cs:206:18:206:41 | access to property Name | semmle.label | access to property Name | -| EntityFramework.cs:214:18:214:30 | access to property Addresses [[], Street] : String | semmle.label | access to property Addresses [[], Street] : String | -| EntityFramework.cs:214:18:214:38 | call to method First [Street] : String | semmle.label | call to method First [Street] : String | +| EntityFramework.cs:214:18:214:30 | access to property Addresses [element, property Street] : String | semmle.label | access to property Addresses [element, property Street] : String | +| EntityFramework.cs:214:18:214:38 | call to method First [property Street] : String | semmle.label | call to method First [property Street] : String | | EntityFramework.cs:214:18:214:45 | access to property Street | semmle.label | access to property Street | -| EntityFramework.cs:221:18:221:28 | access to property Persons [[], Addresses, [], Street] : String | semmle.label | access to property Persons [[], Addresses, [], Street] : String | -| EntityFramework.cs:221:18:221:36 | call to method First [Addresses, [], Street] : String | semmle.label | call to method First [Addresses, [], Street] : String | -| EntityFramework.cs:221:18:221:46 | access to property Addresses [[], Street] : String | semmle.label | access to property Addresses [[], Street] : String | -| EntityFramework.cs:221:18:221:54 | call to method First [Street] : String | semmle.label | call to method First [Street] : String | +| EntityFramework.cs:221:18:221:28 | access to property Persons [element, property Addresses, element, property Street] : String | semmle.label | access to property Persons [element, property Addresses, element, property Street] : String | +| EntityFramework.cs:221:18:221:36 | call to method First [property Addresses, element, property Street] : String | semmle.label | call to method First [property Addresses, element, property Street] : String | +| EntityFramework.cs:221:18:221:46 | access to property Addresses [element, property Street] : String | semmle.label | access to property Addresses [element, property Street] : String | +| EntityFramework.cs:221:18:221:54 | call to method First [property Street] : String | semmle.label | call to method First [property Street] : String | | EntityFramework.cs:221:18:221:61 | access to property Street | semmle.label | access to property Street | | EntityFrameworkCore.cs:75:31:75:39 | "tainted" : String | semmle.label | "tainted" : String | | EntityFrameworkCore.cs:76:18:76:28 | access to local variable taintSource | semmle.label | access to local variable taintSource | @@ -268,78 +268,78 @@ nodes | EntityFrameworkCore.cs:78:18:78:42 | (...) ... | semmle.label | (...) ... | | EntityFrameworkCore.cs:78:18:78:42 | call to operator implicit conversion : RawSqlString | semmle.label | call to operator implicit conversion : RawSqlString | | EntityFrameworkCore.cs:78:32:78:42 | access to local variable taintSource : String | semmle.label | access to local variable taintSource : String | -| EntityFrameworkCore.cs:85:13:88:13 | { ..., ... } [Name] : String | semmle.label | { ..., ... } [Name] : String | +| EntityFrameworkCore.cs:85:13:88:13 | { ..., ... } [property Name] : String | semmle.label | { ..., ... } [property Name] : String | | EntityFrameworkCore.cs:87:24:87:32 | "tainted" : String | semmle.label | "tainted" : String | -| EntityFrameworkCore.cs:92:13:92:15 | [post] access to local variable ctx [Persons, [], Name] : String | semmle.label | [post] access to local variable ctx [Persons, [], Name] : String | -| EntityFrameworkCore.cs:92:13:92:23 | [post] access to property Persons [[], Name] : String | semmle.label | [post] access to property Persons [[], Name] : String | -| EntityFrameworkCore.cs:92:29:92:30 | access to local variable p1 [Name] : String | semmle.label | access to local variable p1 [Name] : String | -| EntityFrameworkCore.cs:94:13:94:15 | access to local variable ctx [Persons, [], Name] : String | semmle.label | access to local variable ctx [Persons, [], Name] : String | -| EntityFrameworkCore.cs:107:13:110:13 | { ..., ... } [Name] : String | semmle.label | { ..., ... } [Name] : String | +| EntityFrameworkCore.cs:92:13:92:15 | [post] access to local variable ctx [property Persons, element, property Name] : String | semmle.label | [post] access to local variable ctx [property Persons, element, property Name] : String | +| EntityFrameworkCore.cs:92:13:92:23 | [post] access to property Persons [element, property Name] : String | semmle.label | [post] access to property Persons [element, property Name] : String | +| EntityFrameworkCore.cs:92:29:92:30 | access to local variable p1 [property Name] : String | semmle.label | access to local variable p1 [property Name] : String | +| EntityFrameworkCore.cs:94:13:94:15 | access to local variable ctx [property Persons, element, property Name] : String | semmle.label | access to local variable ctx [property Persons, element, property Name] : String | +| EntityFrameworkCore.cs:107:13:110:13 | { ..., ... } [property Name] : String | semmle.label | { ..., ... } [property Name] : String | | EntityFrameworkCore.cs:109:24:109:32 | "tainted" : String | semmle.label | "tainted" : String | -| EntityFrameworkCore.cs:114:13:114:15 | [post] access to local variable ctx [Persons, [], Name] : String | semmle.label | [post] access to local variable ctx [Persons, [], Name] : String | -| EntityFrameworkCore.cs:114:13:114:23 | [post] access to property Persons [[], Name] : String | semmle.label | [post] access to property Persons [[], Name] : String | -| EntityFrameworkCore.cs:114:29:114:30 | access to local variable p1 [Name] : String | semmle.label | access to local variable p1 [Name] : String | -| EntityFrameworkCore.cs:116:19:116:21 | access to local variable ctx [Persons, [], Name] : String | semmle.label | access to local variable ctx [Persons, [], Name] : String | -| EntityFrameworkCore.cs:129:13:132:13 | { ..., ... } [Name] : String | semmle.label | { ..., ... } [Name] : String | +| EntityFrameworkCore.cs:114:13:114:15 | [post] access to local variable ctx [property Persons, element, property Name] : String | semmle.label | [post] access to local variable ctx [property Persons, element, property Name] : String | +| EntityFrameworkCore.cs:114:13:114:23 | [post] access to property Persons [element, property Name] : String | semmle.label | [post] access to property Persons [element, property Name] : String | +| EntityFrameworkCore.cs:114:29:114:30 | access to local variable p1 [property Name] : String | semmle.label | access to local variable p1 [property Name] : String | +| EntityFrameworkCore.cs:116:19:116:21 | access to local variable ctx [property Persons, element, property Name] : String | semmle.label | access to local variable ctx [property Persons, element, property Name] : String | +| EntityFrameworkCore.cs:129:13:132:13 | { ..., ... } [property Name] : String | semmle.label | { ..., ... } [property Name] : String | | EntityFrameworkCore.cs:131:24:131:32 | "tainted" : String | semmle.label | "tainted" : String | -| EntityFrameworkCore.cs:135:27:135:28 | access to local variable p1 [Name] : String | semmle.label | access to local variable p1 [Name] : String | -| EntityFrameworkCore.cs:148:13:151:13 | { ..., ... } [Title] : String | semmle.label | { ..., ... } [Title] : String | +| EntityFrameworkCore.cs:135:27:135:28 | access to local variable p1 [property Name] : String | semmle.label | access to local variable p1 [property Name] : String | +| EntityFrameworkCore.cs:148:13:151:13 | { ..., ... } [property Title] : String | semmle.label | { ..., ... } [property Title] : String | | EntityFrameworkCore.cs:150:25:150:33 | "tainted" : String | semmle.label | "tainted" : String | -| EntityFrameworkCore.cs:155:18:155:19 | access to local variable p1 [Title] : String | semmle.label | access to local variable p1 [Title] : String | +| EntityFrameworkCore.cs:155:18:155:19 | access to local variable p1 [property Title] : String | semmle.label | access to local variable p1 [property Title] : String | | EntityFrameworkCore.cs:155:18:155:25 | access to property Title | semmle.label | access to property Title | -| EntityFrameworkCore.cs:167:13:174:13 | { ..., ... } [Addresses, [], Street] : String | semmle.label | { ..., ... } [Addresses, [], Street] : String | -| EntityFrameworkCore.cs:168:29:173:17 | array creation of type Address[] [[], Street] : String | semmle.label | array creation of type Address[] [[], Street] : String | -| EntityFrameworkCore.cs:168:35:173:17 | { ..., ... } [[], Street] : String | semmle.label | { ..., ... } [[], Street] : String | -| EntityFrameworkCore.cs:169:21:172:21 | object creation of type Address [Street] : String | semmle.label | object creation of type Address [Street] : String | -| EntityFrameworkCore.cs:169:33:172:21 | { ..., ... } [Street] : String | semmle.label | { ..., ... } [Street] : String | +| EntityFrameworkCore.cs:167:13:174:13 | { ..., ... } [property Addresses, element, property Street] : String | semmle.label | { ..., ... } [property Addresses, element, property Street] : String | +| EntityFrameworkCore.cs:168:29:173:17 | array creation of type Address[] [element, property Street] : String | semmle.label | array creation of type Address[] [element, property Street] : String | +| EntityFrameworkCore.cs:168:35:173:17 | { ..., ... } [element, property Street] : String | semmle.label | { ..., ... } [element, property Street] : String | +| EntityFrameworkCore.cs:169:21:172:21 | object creation of type Address [property Street] : String | semmle.label | object creation of type Address [property Street] : String | +| EntityFrameworkCore.cs:169:33:172:21 | { ..., ... } [property Street] : String | semmle.label | { ..., ... } [property Street] : String | | EntityFrameworkCore.cs:171:34:171:42 | "tainted" : String | semmle.label | "tainted" : String | -| EntityFrameworkCore.cs:175:13:175:15 | [post] access to local variable ctx [Persons, [], Addresses, [], Street] : String | semmle.label | [post] access to local variable ctx [Persons, [], Addresses, [], Street] : String | -| EntityFrameworkCore.cs:175:13:175:23 | [post] access to property Persons [[], Addresses, [], Street] : String | semmle.label | [post] access to property Persons [[], Addresses, [], Street] : String | -| EntityFrameworkCore.cs:175:29:175:30 | access to local variable p1 [Addresses, [], Street] : String | semmle.label | access to local variable p1 [Addresses, [], Street] : String | -| EntityFrameworkCore.cs:176:13:176:15 | access to local variable ctx [Persons, [], Addresses, [], Street] : String | semmle.label | access to local variable ctx [Persons, [], Addresses, [], Street] : String | -| EntityFrameworkCore.cs:180:13:180:15 | access to local variable ctx [Persons, [], Addresses, [], Street] : String | semmle.label | access to local variable ctx [Persons, [], Addresses, [], Street] : String | -| EntityFrameworkCore.cs:183:13:186:13 | { ..., ... } [Street] : String | semmle.label | { ..., ... } [Street] : String | +| EntityFrameworkCore.cs:175:13:175:15 | [post] access to local variable ctx [property Persons, element, property Addresses, element, property Street] : String | semmle.label | [post] access to local variable ctx [property Persons, element, property Addresses, element, property Street] : String | +| EntityFrameworkCore.cs:175:13:175:23 | [post] access to property Persons [element, property Addresses, element, property Street] : String | semmle.label | [post] access to property Persons [element, property Addresses, element, property Street] : String | +| EntityFrameworkCore.cs:175:29:175:30 | access to local variable p1 [property Addresses, element, property Street] : String | semmle.label | access to local variable p1 [property Addresses, element, property Street] : String | +| EntityFrameworkCore.cs:176:13:176:15 | access to local variable ctx [property Persons, element, property Addresses, element, property Street] : String | semmle.label | access to local variable ctx [property Persons, element, property Addresses, element, property Street] : String | +| EntityFrameworkCore.cs:180:13:180:15 | access to local variable ctx [property Persons, element, property Addresses, element, property Street] : String | semmle.label | access to local variable ctx [property Persons, element, property Addresses, element, property Street] : String | +| EntityFrameworkCore.cs:183:13:186:13 | { ..., ... } [property Street] : String | semmle.label | { ..., ... } [property Street] : String | | EntityFrameworkCore.cs:185:26:185:34 | "tainted" : String | semmle.label | "tainted" : String | -| EntityFrameworkCore.cs:187:13:187:15 | [post] access to local variable ctx [Addresses, [], Street] : String | semmle.label | [post] access to local variable ctx [Addresses, [], Street] : String | -| EntityFrameworkCore.cs:187:13:187:25 | [post] access to property Addresses [[], Street] : String | semmle.label | [post] access to property Addresses [[], Street] : String | -| EntityFrameworkCore.cs:187:31:187:32 | access to local variable a1 [Street] : String | semmle.label | access to local variable a1 [Street] : String | -| EntityFrameworkCore.cs:188:13:188:15 | access to local variable ctx [Addresses, [], Street] : String | semmle.label | access to local variable ctx [Addresses, [], Street] : String | -| EntityFrameworkCore.cs:188:13:188:15 | access to local variable ctx [Persons, [], Addresses, [], Street] : String | semmle.label | access to local variable ctx [Persons, [], Addresses, [], Street] : String | -| EntityFrameworkCore.cs:192:13:192:15 | access to local variable ctx [Addresses, [], Street] : String | semmle.label | access to local variable ctx [Addresses, [], Street] : String | -| EntityFrameworkCore.cs:192:13:192:15 | access to local variable ctx [Persons, [], Addresses, [], Street] : String | semmle.label | access to local variable ctx [Persons, [], Addresses, [], Street] : String | -| EntityFrameworkCore.cs:199:13:202:13 | { ..., ... } [Name] : String | semmle.label | { ..., ... } [Name] : String | +| EntityFrameworkCore.cs:187:13:187:15 | [post] access to local variable ctx [property Addresses, element, property Street] : String | semmle.label | [post] access to local variable ctx [property Addresses, element, property Street] : String | +| EntityFrameworkCore.cs:187:13:187:25 | [post] access to property Addresses [element, property Street] : String | semmle.label | [post] access to property Addresses [element, property Street] : String | +| EntityFrameworkCore.cs:187:31:187:32 | access to local variable a1 [property Street] : String | semmle.label | access to local variable a1 [property Street] : String | +| EntityFrameworkCore.cs:188:13:188:15 | access to local variable ctx [property Addresses, element, property Street] : String | semmle.label | access to local variable ctx [property Addresses, element, property Street] : String | +| EntityFrameworkCore.cs:188:13:188:15 | access to local variable ctx [property Persons, element, property Addresses, element, property Street] : String | semmle.label | access to local variable ctx [property Persons, element, property Addresses, element, property Street] : String | +| EntityFrameworkCore.cs:192:13:192:15 | access to local variable ctx [property Addresses, element, property Street] : String | semmle.label | access to local variable ctx [property Addresses, element, property Street] : String | +| EntityFrameworkCore.cs:192:13:192:15 | access to local variable ctx [property Persons, element, property Addresses, element, property Street] : String | semmle.label | access to local variable ctx [property Persons, element, property Addresses, element, property Street] : String | +| EntityFrameworkCore.cs:199:13:202:13 | { ..., ... } [property Name] : String | semmle.label | { ..., ... } [property Name] : String | | EntityFrameworkCore.cs:201:24:201:32 | "tainted" : String | semmle.label | "tainted" : String | -| EntityFrameworkCore.cs:204:13:207:13 | { ..., ... } [Street] : String | semmle.label | { ..., ... } [Street] : String | +| EntityFrameworkCore.cs:204:13:207:13 | { ..., ... } [property Street] : String | semmle.label | { ..., ... } [property Street] : String | | EntityFrameworkCore.cs:206:26:206:34 | "tainted" : String | semmle.label | "tainted" : String | -| EntityFrameworkCore.cs:208:60:208:88 | { ..., ... } [Address, Street] : String | semmle.label | { ..., ... } [Address, Street] : String | -| EntityFrameworkCore.cs:208:60:208:88 | { ..., ... } [Person, Name] : String | semmle.label | { ..., ... } [Person, Name] : String | -| EntityFrameworkCore.cs:208:71:208:72 | access to local variable p1 [Name] : String | semmle.label | access to local variable p1 [Name] : String | -| EntityFrameworkCore.cs:208:85:208:86 | access to local variable a1 [Street] : String | semmle.label | access to local variable a1 [Street] : String | -| EntityFrameworkCore.cs:209:13:209:15 | [post] access to local variable ctx [PersonAddresses, [], Address, Street] : String | semmle.label | [post] access to local variable ctx [PersonAddresses, [], Address, Street] : String | -| EntityFrameworkCore.cs:209:13:209:15 | [post] access to local variable ctx [PersonAddresses, [], Person, Name] : String | semmle.label | [post] access to local variable ctx [PersonAddresses, [], Person, Name] : String | -| EntityFrameworkCore.cs:209:13:209:31 | [post] access to property PersonAddresses [[], Address, Street] : String | semmle.label | [post] access to property PersonAddresses [[], Address, Street] : String | -| EntityFrameworkCore.cs:209:13:209:31 | [post] access to property PersonAddresses [[], Person, Name] : String | semmle.label | [post] access to property PersonAddresses [[], Person, Name] : String | -| EntityFrameworkCore.cs:209:37:209:53 | access to local variable personAddressMap1 [Address, Street] : String | semmle.label | access to local variable personAddressMap1 [Address, Street] : String | -| EntityFrameworkCore.cs:209:37:209:53 | access to local variable personAddressMap1 [Person, Name] : String | semmle.label | access to local variable personAddressMap1 [Person, Name] : String | -| EntityFrameworkCore.cs:210:13:210:15 | access to local variable ctx [PersonAddresses, [], Address, Street] : String | semmle.label | access to local variable ctx [PersonAddresses, [], Address, Street] : String | -| EntityFrameworkCore.cs:210:13:210:15 | access to local variable ctx [PersonAddresses, [], Person, Name] : String | semmle.label | access to local variable ctx [PersonAddresses, [], Person, Name] : String | -| EntityFrameworkCore.cs:216:13:216:15 | access to local variable ctx [PersonAddresses, [], Address, Street] : String | semmle.label | access to local variable ctx [PersonAddresses, [], Address, Street] : String | -| EntityFrameworkCore.cs:216:13:216:15 | access to local variable ctx [PersonAddresses, [], Person, Name] : String | semmle.label | access to local variable ctx [PersonAddresses, [], Person, Name] : String | -| EntityFrameworkCore.cs:219:35:219:35 | p [Name] : String | semmle.label | p [Name] : String | -| EntityFrameworkCore.cs:222:13:222:15 | [post] access to local variable ctx [Persons, [], Name] : String | semmle.label | [post] access to local variable ctx [Persons, [], Name] : String | -| EntityFrameworkCore.cs:222:13:222:23 | [post] access to property Persons [[], Name] : String | semmle.label | [post] access to property Persons [[], Name] : String | -| EntityFrameworkCore.cs:222:29:222:29 | access to parameter p [Name] : String | semmle.label | access to parameter p [Name] : String | -| EntityFrameworkCore.cs:223:13:223:15 | access to local variable ctx [Persons, [], Name] : String | semmle.label | access to local variable ctx [Persons, [], Name] : String | -| EntityFrameworkCore.cs:230:18:230:28 | access to property Persons [[], Name] : String | semmle.label | access to property Persons [[], Name] : String | -| EntityFrameworkCore.cs:230:18:230:36 | call to method First [Name] : String | semmle.label | call to method First [Name] : String | +| EntityFrameworkCore.cs:208:60:208:88 | { ..., ... } [property Address, property Street] : String | semmle.label | { ..., ... } [property Address, property Street] : String | +| EntityFrameworkCore.cs:208:60:208:88 | { ..., ... } [property Person, property Name] : String | semmle.label | { ..., ... } [property Person, property Name] : String | +| EntityFrameworkCore.cs:208:71:208:72 | access to local variable p1 [property Name] : String | semmle.label | access to local variable p1 [property Name] : String | +| EntityFrameworkCore.cs:208:85:208:86 | access to local variable a1 [property Street] : String | semmle.label | access to local variable a1 [property Street] : String | +| EntityFrameworkCore.cs:209:13:209:15 | [post] access to local variable ctx [property PersonAddresses, element, property Address, property Street] : String | semmle.label | [post] access to local variable ctx [property PersonAddresses, element, property Address, property Street] : String | +| EntityFrameworkCore.cs:209:13:209:15 | [post] access to local variable ctx [property PersonAddresses, element, property Person, property Name] : String | semmle.label | [post] access to local variable ctx [property PersonAddresses, element, property Person, property Name] : String | +| EntityFrameworkCore.cs:209:13:209:31 | [post] access to property PersonAddresses [element, property Address, property Street] : String | semmle.label | [post] access to property PersonAddresses [element, property Address, property Street] : String | +| EntityFrameworkCore.cs:209:13:209:31 | [post] access to property PersonAddresses [element, property Person, property Name] : String | semmle.label | [post] access to property PersonAddresses [element, property Person, property Name] : String | +| EntityFrameworkCore.cs:209:37:209:53 | access to local variable personAddressMap1 [property Address, property Street] : String | semmle.label | access to local variable personAddressMap1 [property Address, property Street] : String | +| EntityFrameworkCore.cs:209:37:209:53 | access to local variable personAddressMap1 [property Person, property Name] : String | semmle.label | access to local variable personAddressMap1 [property Person, property Name] : String | +| EntityFrameworkCore.cs:210:13:210:15 | access to local variable ctx [property PersonAddresses, element, property Address, property Street] : String | semmle.label | access to local variable ctx [property PersonAddresses, element, property Address, property Street] : String | +| EntityFrameworkCore.cs:210:13:210:15 | access to local variable ctx [property PersonAddresses, element, property Person, property Name] : String | semmle.label | access to local variable ctx [property PersonAddresses, element, property Person, property Name] : String | +| EntityFrameworkCore.cs:216:13:216:15 | access to local variable ctx [property PersonAddresses, element, property Address, property Street] : String | semmle.label | access to local variable ctx [property PersonAddresses, element, property Address, property Street] : String | +| EntityFrameworkCore.cs:216:13:216:15 | access to local variable ctx [property PersonAddresses, element, property Person, property Name] : String | semmle.label | access to local variable ctx [property PersonAddresses, element, property Person, property Name] : String | +| EntityFrameworkCore.cs:219:35:219:35 | p [property Name] : String | semmle.label | p [property Name] : String | +| EntityFrameworkCore.cs:222:13:222:15 | [post] access to local variable ctx [property Persons, element, property Name] : String | semmle.label | [post] access to local variable ctx [property Persons, element, property Name] : String | +| EntityFrameworkCore.cs:222:13:222:23 | [post] access to property Persons [element, property Name] : String | semmle.label | [post] access to property Persons [element, property Name] : String | +| EntityFrameworkCore.cs:222:29:222:29 | access to parameter p [property Name] : String | semmle.label | access to parameter p [property Name] : String | +| EntityFrameworkCore.cs:223:13:223:15 | access to local variable ctx [property Persons, element, property Name] : String | semmle.label | access to local variable ctx [property Persons, element, property Name] : String | +| EntityFrameworkCore.cs:230:18:230:28 | access to property Persons [element, property Name] : String | semmle.label | access to property Persons [element, property Name] : String | +| EntityFrameworkCore.cs:230:18:230:36 | call to method First [property Name] : String | semmle.label | call to method First [property Name] : String | | EntityFrameworkCore.cs:230:18:230:41 | access to property Name | semmle.label | access to property Name | -| EntityFrameworkCore.cs:238:18:238:30 | access to property Addresses [[], Street] : String | semmle.label | access to property Addresses [[], Street] : String | -| EntityFrameworkCore.cs:238:18:238:38 | call to method First [Street] : String | semmle.label | call to method First [Street] : String | +| EntityFrameworkCore.cs:238:18:238:30 | access to property Addresses [element, property Street] : String | semmle.label | access to property Addresses [element, property Street] : String | +| EntityFrameworkCore.cs:238:18:238:38 | call to method First [property Street] : String | semmle.label | call to method First [property Street] : String | | EntityFrameworkCore.cs:238:18:238:45 | access to property Street | semmle.label | access to property Street | -| EntityFrameworkCore.cs:245:18:245:28 | access to property Persons [[], Addresses, [], Street] : String | semmle.label | access to property Persons [[], Addresses, [], Street] : String | -| EntityFrameworkCore.cs:245:18:245:36 | call to method First [Addresses, [], Street] : String | semmle.label | call to method First [Addresses, [], Street] : String | -| EntityFrameworkCore.cs:245:18:245:46 | access to property Addresses [[], Street] : String | semmle.label | access to property Addresses [[], Street] : String | -| EntityFrameworkCore.cs:245:18:245:54 | call to method First [Street] : String | semmle.label | call to method First [Street] : String | +| EntityFrameworkCore.cs:245:18:245:28 | access to property Persons [element, property Addresses, element, property Street] : String | semmle.label | access to property Persons [element, property Addresses, element, property Street] : String | +| EntityFrameworkCore.cs:245:18:245:36 | call to method First [property Addresses, element, property Street] : String | semmle.label | call to method First [property Addresses, element, property Street] : String | +| EntityFrameworkCore.cs:245:18:245:46 | access to property Addresses [element, property Street] : String | semmle.label | access to property Addresses [element, property Street] : String | +| EntityFrameworkCore.cs:245:18:245:54 | call to method First [property Street] : String | semmle.label | call to method First [property Street] : String | | EntityFrameworkCore.cs:245:18:245:61 | access to property Street | semmle.label | access to property Street | #select | EntityFramework.cs:131:18:131:25 | access to property Title | EntityFramework.cs:126:25:126:33 | "tainted" : String | EntityFramework.cs:131:18:131:25 | access to property Title | $@ | EntityFramework.cs:126:25:126:33 | "tainted" : String | "tainted" : String | diff --git a/csharp/ql/test/library-tests/frameworks/EntityFramework/FlowSummaries.expected b/csharp/ql/test/library-tests/frameworks/EntityFramework/FlowSummaries.expected index 255b6ac988b..91b24479fbb 100644 --- a/csharp/ql/test/library-tests/frameworks/EntityFramework/FlowSummaries.expected +++ b/csharp/ql/test/library-tests/frameworks/EntityFramework/FlowSummaries.expected @@ -1,158 +1,134 @@ -| Microsoft.EntityFrameworkCore.DbContext.SaveChanges() | this parameter [Addresses, [], Id] -> jump to get_Addresses (return) [[], Id] | true | -| Microsoft.EntityFrameworkCore.DbContext.SaveChanges() | this parameter [Addresses, [], Id] -> jump to get_PersonAddresses (return) [[], Address, Id] | true | -| Microsoft.EntityFrameworkCore.DbContext.SaveChanges() | this parameter [Addresses, [], Id] -> jump to get_PersonAddresses (return) [[], Person, Addresses, [], Id] | true | -| Microsoft.EntityFrameworkCore.DbContext.SaveChanges() | this parameter [Addresses, [], Id] -> jump to get_Persons (return) [[], Addresses, [], Id] | true | -| Microsoft.EntityFrameworkCore.DbContext.SaveChanges() | this parameter [Addresses, [], Street] -> jump to get_Addresses (return) [[], Street] | true | -| Microsoft.EntityFrameworkCore.DbContext.SaveChanges() | this parameter [Addresses, [], Street] -> jump to get_PersonAddresses (return) [[], Address, Street] | true | -| Microsoft.EntityFrameworkCore.DbContext.SaveChanges() | this parameter [Addresses, [], Street] -> jump to get_PersonAddresses (return) [[], Person, Addresses, [], Street] | true | -| Microsoft.EntityFrameworkCore.DbContext.SaveChanges() | this parameter [Addresses, [], Street] -> jump to get_Persons (return) [[], Addresses, [], Street] | true | -| Microsoft.EntityFrameworkCore.DbContext.SaveChanges() | this parameter [PersonAddresses, [], Address, Id] -> jump to get_Addresses (return) [[], Id] | true | -| Microsoft.EntityFrameworkCore.DbContext.SaveChanges() | this parameter [PersonAddresses, [], Address, Id] -> jump to get_PersonAddresses (return) [[], Address, Id] | true | -| Microsoft.EntityFrameworkCore.DbContext.SaveChanges() | this parameter [PersonAddresses, [], Address, Id] -> jump to get_PersonAddresses (return) [[], Person, Addresses, [], Id] | true | -| Microsoft.EntityFrameworkCore.DbContext.SaveChanges() | this parameter [PersonAddresses, [], Address, Id] -> jump to get_Persons (return) [[], Addresses, [], Id] | true | -| Microsoft.EntityFrameworkCore.DbContext.SaveChanges() | this parameter [PersonAddresses, [], Address, Street] -> jump to get_Addresses (return) [[], Street] | true | -| Microsoft.EntityFrameworkCore.DbContext.SaveChanges() | this parameter [PersonAddresses, [], Address, Street] -> jump to get_PersonAddresses (return) [[], Address, Street] | true | -| Microsoft.EntityFrameworkCore.DbContext.SaveChanges() | this parameter [PersonAddresses, [], Address, Street] -> jump to get_PersonAddresses (return) [[], Person, Addresses, [], Street] | true | -| Microsoft.EntityFrameworkCore.DbContext.SaveChanges() | this parameter [PersonAddresses, [], Address, Street] -> jump to get_Persons (return) [[], Addresses, [], Street] | true | -| Microsoft.EntityFrameworkCore.DbContext.SaveChanges() | this parameter [PersonAddresses, [], AddressId] -> jump to get_PersonAddresses (return) [[], AddressId] | true | -| Microsoft.EntityFrameworkCore.DbContext.SaveChanges() | this parameter [PersonAddresses, [], Id] -> jump to get_PersonAddresses (return) [[], Id] | true | -| Microsoft.EntityFrameworkCore.DbContext.SaveChanges() | this parameter [PersonAddresses, [], Person, Id] -> jump to get_PersonAddresses (return) [[], Person, Id] | true | -| Microsoft.EntityFrameworkCore.DbContext.SaveChanges() | this parameter [PersonAddresses, [], Person, Id] -> jump to get_Persons (return) [[], Id] | true | -| Microsoft.EntityFrameworkCore.DbContext.SaveChanges() | this parameter [PersonAddresses, [], Person, Name] -> jump to get_PersonAddresses (return) [[], Person, Name] | true | -| Microsoft.EntityFrameworkCore.DbContext.SaveChanges() | this parameter [PersonAddresses, [], Person, Name] -> jump to get_Persons (return) [[], Name] | true | -| Microsoft.EntityFrameworkCore.DbContext.SaveChanges() | this parameter [PersonAddresses, [], PersonId] -> jump to get_PersonAddresses (return) [[], PersonId] | true | -| Microsoft.EntityFrameworkCore.DbContext.SaveChanges() | this parameter [Persons, [], Addresses, [], Id] -> jump to get_Addresses (return) [[], Id] | true | -| Microsoft.EntityFrameworkCore.DbContext.SaveChanges() | this parameter [Persons, [], Addresses, [], Id] -> jump to get_PersonAddresses (return) [[], Address, Id] | true | -| Microsoft.EntityFrameworkCore.DbContext.SaveChanges() | this parameter [Persons, [], Addresses, [], Id] -> jump to get_PersonAddresses (return) [[], Person, Addresses, [], Id] | true | -| Microsoft.EntityFrameworkCore.DbContext.SaveChanges() | this parameter [Persons, [], Addresses, [], Id] -> jump to get_Persons (return) [[], Addresses, [], Id] | true | -| Microsoft.EntityFrameworkCore.DbContext.SaveChanges() | this parameter [Persons, [], Addresses, [], Street] -> jump to get_Addresses (return) [[], Street] | true | -| Microsoft.EntityFrameworkCore.DbContext.SaveChanges() | this parameter [Persons, [], Addresses, [], Street] -> jump to get_PersonAddresses (return) [[], Address, Street] | true | -| Microsoft.EntityFrameworkCore.DbContext.SaveChanges() | this parameter [Persons, [], Addresses, [], Street] -> jump to get_PersonAddresses (return) [[], Person, Addresses, [], Street] | true | -| Microsoft.EntityFrameworkCore.DbContext.SaveChanges() | this parameter [Persons, [], Addresses, [], Street] -> jump to get_Persons (return) [[], Addresses, [], Street] | true | -| Microsoft.EntityFrameworkCore.DbContext.SaveChanges() | this parameter [Persons, [], Id] -> jump to get_PersonAddresses (return) [[], Person, Id] | true | -| Microsoft.EntityFrameworkCore.DbContext.SaveChanges() | this parameter [Persons, [], Id] -> jump to get_Persons (return) [[], Id] | true | -| Microsoft.EntityFrameworkCore.DbContext.SaveChanges() | this parameter [Persons, [], Name] -> jump to get_PersonAddresses (return) [[], Person, Name] | true | -| Microsoft.EntityFrameworkCore.DbContext.SaveChanges() | this parameter [Persons, [], Name] -> jump to get_Persons (return) [[], Name] | true | -| Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync() | this parameter [Addresses, [], Id] -> jump to get_Addresses (return) [[], Id] | true | -| Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync() | this parameter [Addresses, [], Id] -> jump to get_PersonAddresses (return) [[], Address, Id] | true | -| Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync() | this parameter [Addresses, [], Id] -> jump to get_PersonAddresses (return) [[], Person, Addresses, [], Id] | true | -| Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync() | this parameter [Addresses, [], Id] -> jump to get_Persons (return) [[], Addresses, [], Id] | true | -| Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync() | this parameter [Addresses, [], Street] -> jump to get_Addresses (return) [[], Street] | true | -| Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync() | this parameter [Addresses, [], Street] -> jump to get_PersonAddresses (return) [[], Address, Street] | true | -| Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync() | this parameter [Addresses, [], Street] -> jump to get_PersonAddresses (return) [[], Person, Addresses, [], Street] | true | -| Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync() | this parameter [Addresses, [], Street] -> jump to get_Persons (return) [[], Addresses, [], Street] | true | -| Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync() | this parameter [PersonAddresses, [], Address, Id] -> jump to get_Addresses (return) [[], Id] | true | -| Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync() | this parameter [PersonAddresses, [], Address, Id] -> jump to get_PersonAddresses (return) [[], Address, Id] | true | -| Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync() | this parameter [PersonAddresses, [], Address, Id] -> jump to get_PersonAddresses (return) [[], Person, Addresses, [], Id] | true | -| Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync() | this parameter [PersonAddresses, [], Address, Id] -> jump to get_Persons (return) [[], Addresses, [], Id] | true | -| Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync() | this parameter [PersonAddresses, [], Address, Street] -> jump to get_Addresses (return) [[], Street] | true | -| Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync() | this parameter [PersonAddresses, [], Address, Street] -> jump to get_PersonAddresses (return) [[], Address, Street] | true | -| Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync() | this parameter [PersonAddresses, [], Address, Street] -> jump to get_PersonAddresses (return) [[], Person, Addresses, [], Street] | true | -| Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync() | this parameter [PersonAddresses, [], Address, Street] -> jump to get_Persons (return) [[], Addresses, [], Street] | true | -| Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync() | this parameter [PersonAddresses, [], AddressId] -> jump to get_PersonAddresses (return) [[], AddressId] | true | -| Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync() | this parameter [PersonAddresses, [], Id] -> jump to get_PersonAddresses (return) [[], Id] | true | -| Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync() | this parameter [PersonAddresses, [], Person, Id] -> jump to get_PersonAddresses (return) [[], Person, Id] | true | -| Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync() | this parameter [PersonAddresses, [], Person, Id] -> jump to get_Persons (return) [[], Id] | true | -| Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync() | this parameter [PersonAddresses, [], Person, Name] -> jump to get_PersonAddresses (return) [[], Person, Name] | true | -| Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync() | this parameter [PersonAddresses, [], Person, Name] -> jump to get_Persons (return) [[], Name] | true | -| Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync() | this parameter [PersonAddresses, [], PersonId] -> jump to get_PersonAddresses (return) [[], PersonId] | true | -| Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync() | this parameter [Persons, [], Addresses, [], Id] -> jump to get_Addresses (return) [[], Id] | true | -| Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync() | this parameter [Persons, [], Addresses, [], Id] -> jump to get_PersonAddresses (return) [[], Address, Id] | true | -| Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync() | this parameter [Persons, [], Addresses, [], Id] -> jump to get_PersonAddresses (return) [[], Person, Addresses, [], Id] | true | -| Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync() | this parameter [Persons, [], Addresses, [], Id] -> jump to get_Persons (return) [[], Addresses, [], Id] | true | -| Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync() | this parameter [Persons, [], Addresses, [], Street] -> jump to get_Addresses (return) [[], Street] | true | -| Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync() | this parameter [Persons, [], Addresses, [], Street] -> jump to get_PersonAddresses (return) [[], Address, Street] | true | -| Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync() | this parameter [Persons, [], Addresses, [], Street] -> jump to get_PersonAddresses (return) [[], Person, Addresses, [], Street] | true | -| Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync() | this parameter [Persons, [], Addresses, [], Street] -> jump to get_Persons (return) [[], Addresses, [], Street] | true | -| Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync() | this parameter [Persons, [], Id] -> jump to get_PersonAddresses (return) [[], Person, Id] | true | -| Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync() | this parameter [Persons, [], Id] -> jump to get_Persons (return) [[], Id] | true | -| Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync() | this parameter [Persons, [], Name] -> jump to get_PersonAddresses (return) [[], Person, Name] | true | -| Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync() | this parameter [Persons, [], Name] -> jump to get_Persons (return) [[], Name] | true | -| Microsoft.EntityFrameworkCore.DbSet<>.Add(T) | parameter 0 -> this parameter [[]] | true | -| Microsoft.EntityFrameworkCore.DbSet<>.AddAsync(T) | parameter 0 -> this parameter [[]] | true | -| Microsoft.EntityFrameworkCore.DbSet<>.AddRange(IEnumerable) | parameter 0 [[]] -> this parameter [[]] | true | -| Microsoft.EntityFrameworkCore.DbSet<>.AddRangeAsync(IEnumerable) | parameter 0 [[]] -> this parameter [[]] | true | -| Microsoft.EntityFrameworkCore.DbSet<>.Attach(T) | parameter 0 -> this parameter [[]] | true | -| Microsoft.EntityFrameworkCore.DbSet<>.AttachRange(IEnumerable) | parameter 0 [[]] -> this parameter [[]] | true | -| Microsoft.EntityFrameworkCore.DbSet<>.Update(T) | parameter 0 -> this parameter [[]] | true | -| Microsoft.EntityFrameworkCore.DbSet<>.UpdateRange(IEnumerable) | parameter 0 [[]] -> this parameter [[]] | true | -| Microsoft.EntityFrameworkCore.RawSqlString.RawSqlString(string) | parameter 0 -> return | false | -| Microsoft.EntityFrameworkCore.RawSqlString.implicit conversion(string) | parameter 0 -> return | false | -| System.Data.Entity.DbContext.SaveChanges() | this parameter [Addresses, [], Id] -> jump to get_Addresses (return) [[], Id] | true | -| System.Data.Entity.DbContext.SaveChanges() | this parameter [Addresses, [], Id] -> jump to get_PersonAddresses (return) [[], Address, Id] | true | -| System.Data.Entity.DbContext.SaveChanges() | this parameter [Addresses, [], Id] -> jump to get_PersonAddresses (return) [[], Person, Addresses, [], Id] | true | -| System.Data.Entity.DbContext.SaveChanges() | this parameter [Addresses, [], Id] -> jump to get_Persons (return) [[], Addresses, [], Id] | true | -| System.Data.Entity.DbContext.SaveChanges() | this parameter [Addresses, [], Street] -> jump to get_Addresses (return) [[], Street] | true | -| System.Data.Entity.DbContext.SaveChanges() | this parameter [Addresses, [], Street] -> jump to get_PersonAddresses (return) [[], Address, Street] | true | -| System.Data.Entity.DbContext.SaveChanges() | this parameter [Addresses, [], Street] -> jump to get_PersonAddresses (return) [[], Person, Addresses, [], Street] | true | -| System.Data.Entity.DbContext.SaveChanges() | this parameter [Addresses, [], Street] -> jump to get_Persons (return) [[], Addresses, [], Street] | true | -| System.Data.Entity.DbContext.SaveChanges() | this parameter [PersonAddresses, [], Address, Id] -> jump to get_Addresses (return) [[], Id] | true | -| System.Data.Entity.DbContext.SaveChanges() | this parameter [PersonAddresses, [], Address, Id] -> jump to get_PersonAddresses (return) [[], Address, Id] | true | -| System.Data.Entity.DbContext.SaveChanges() | this parameter [PersonAddresses, [], Address, Id] -> jump to get_PersonAddresses (return) [[], Person, Addresses, [], Id] | true | -| System.Data.Entity.DbContext.SaveChanges() | this parameter [PersonAddresses, [], Address, Id] -> jump to get_Persons (return) [[], Addresses, [], Id] | true | -| System.Data.Entity.DbContext.SaveChanges() | this parameter [PersonAddresses, [], Address, Street] -> jump to get_Addresses (return) [[], Street] | true | -| System.Data.Entity.DbContext.SaveChanges() | this parameter [PersonAddresses, [], Address, Street] -> jump to get_PersonAddresses (return) [[], Address, Street] | true | -| System.Data.Entity.DbContext.SaveChanges() | this parameter [PersonAddresses, [], Address, Street] -> jump to get_PersonAddresses (return) [[], Person, Addresses, [], Street] | true | -| System.Data.Entity.DbContext.SaveChanges() | this parameter [PersonAddresses, [], Address, Street] -> jump to get_Persons (return) [[], Addresses, [], Street] | true | -| System.Data.Entity.DbContext.SaveChanges() | this parameter [PersonAddresses, [], AddressId] -> jump to get_PersonAddresses (return) [[], AddressId] | true | -| System.Data.Entity.DbContext.SaveChanges() | this parameter [PersonAddresses, [], Id] -> jump to get_PersonAddresses (return) [[], Id] | true | -| System.Data.Entity.DbContext.SaveChanges() | this parameter [PersonAddresses, [], Person, Id] -> jump to get_PersonAddresses (return) [[], Person, Id] | true | -| System.Data.Entity.DbContext.SaveChanges() | this parameter [PersonAddresses, [], Person, Id] -> jump to get_Persons (return) [[], Id] | true | -| System.Data.Entity.DbContext.SaveChanges() | this parameter [PersonAddresses, [], Person, Name] -> jump to get_PersonAddresses (return) [[], Person, Name] | true | -| System.Data.Entity.DbContext.SaveChanges() | this parameter [PersonAddresses, [], Person, Name] -> jump to get_Persons (return) [[], Name] | true | -| System.Data.Entity.DbContext.SaveChanges() | this parameter [PersonAddresses, [], PersonId] -> jump to get_PersonAddresses (return) [[], PersonId] | true | -| System.Data.Entity.DbContext.SaveChanges() | this parameter [Persons, [], Addresses, [], Id] -> jump to get_Addresses (return) [[], Id] | true | -| System.Data.Entity.DbContext.SaveChanges() | this parameter [Persons, [], Addresses, [], Id] -> jump to get_PersonAddresses (return) [[], Address, Id] | true | -| System.Data.Entity.DbContext.SaveChanges() | this parameter [Persons, [], Addresses, [], Id] -> jump to get_PersonAddresses (return) [[], Person, Addresses, [], Id] | true | -| System.Data.Entity.DbContext.SaveChanges() | this parameter [Persons, [], Addresses, [], Id] -> jump to get_Persons (return) [[], Addresses, [], Id] | true | -| System.Data.Entity.DbContext.SaveChanges() | this parameter [Persons, [], Addresses, [], Street] -> jump to get_Addresses (return) [[], Street] | true | -| System.Data.Entity.DbContext.SaveChanges() | this parameter [Persons, [], Addresses, [], Street] -> jump to get_PersonAddresses (return) [[], Address, Street] | true | -| System.Data.Entity.DbContext.SaveChanges() | this parameter [Persons, [], Addresses, [], Street] -> jump to get_PersonAddresses (return) [[], Person, Addresses, [], Street] | true | -| System.Data.Entity.DbContext.SaveChanges() | this parameter [Persons, [], Addresses, [], Street] -> jump to get_Persons (return) [[], Addresses, [], Street] | true | -| System.Data.Entity.DbContext.SaveChanges() | this parameter [Persons, [], Id] -> jump to get_PersonAddresses (return) [[], Person, Id] | true | -| System.Data.Entity.DbContext.SaveChanges() | this parameter [Persons, [], Id] -> jump to get_Persons (return) [[], Id] | true | -| System.Data.Entity.DbContext.SaveChanges() | this parameter [Persons, [], Name] -> jump to get_PersonAddresses (return) [[], Person, Name] | true | -| System.Data.Entity.DbContext.SaveChanges() | this parameter [Persons, [], Name] -> jump to get_Persons (return) [[], Name] | true | -| System.Data.Entity.DbContext.SaveChangesAsync() | this parameter [Addresses, [], Id] -> jump to get_Addresses (return) [[], Id] | true | -| System.Data.Entity.DbContext.SaveChangesAsync() | this parameter [Addresses, [], Id] -> jump to get_PersonAddresses (return) [[], Address, Id] | true | -| System.Data.Entity.DbContext.SaveChangesAsync() | this parameter [Addresses, [], Id] -> jump to get_PersonAddresses (return) [[], Person, Addresses, [], Id] | true | -| System.Data.Entity.DbContext.SaveChangesAsync() | this parameter [Addresses, [], Id] -> jump to get_Persons (return) [[], Addresses, [], Id] | true | -| System.Data.Entity.DbContext.SaveChangesAsync() | this parameter [Addresses, [], Street] -> jump to get_Addresses (return) [[], Street] | true | -| System.Data.Entity.DbContext.SaveChangesAsync() | this parameter [Addresses, [], Street] -> jump to get_PersonAddresses (return) [[], Address, Street] | true | -| System.Data.Entity.DbContext.SaveChangesAsync() | this parameter [Addresses, [], Street] -> jump to get_PersonAddresses (return) [[], Person, Addresses, [], Street] | true | -| System.Data.Entity.DbContext.SaveChangesAsync() | this parameter [Addresses, [], Street] -> jump to get_Persons (return) [[], Addresses, [], Street] | true | -| System.Data.Entity.DbContext.SaveChangesAsync() | this parameter [PersonAddresses, [], Address, Id] -> jump to get_Addresses (return) [[], Id] | true | -| System.Data.Entity.DbContext.SaveChangesAsync() | this parameter [PersonAddresses, [], Address, Id] -> jump to get_PersonAddresses (return) [[], Address, Id] | true | -| System.Data.Entity.DbContext.SaveChangesAsync() | this parameter [PersonAddresses, [], Address, Id] -> jump to get_PersonAddresses (return) [[], Person, Addresses, [], Id] | true | -| System.Data.Entity.DbContext.SaveChangesAsync() | this parameter [PersonAddresses, [], Address, Id] -> jump to get_Persons (return) [[], Addresses, [], Id] | true | -| System.Data.Entity.DbContext.SaveChangesAsync() | this parameter [PersonAddresses, [], Address, Street] -> jump to get_Addresses (return) [[], Street] | true | -| System.Data.Entity.DbContext.SaveChangesAsync() | this parameter [PersonAddresses, [], Address, Street] -> jump to get_PersonAddresses (return) [[], Address, Street] | true | -| System.Data.Entity.DbContext.SaveChangesAsync() | this parameter [PersonAddresses, [], Address, Street] -> jump to get_PersonAddresses (return) [[], Person, Addresses, [], Street] | true | -| System.Data.Entity.DbContext.SaveChangesAsync() | this parameter [PersonAddresses, [], Address, Street] -> jump to get_Persons (return) [[], Addresses, [], Street] | true | -| System.Data.Entity.DbContext.SaveChangesAsync() | this parameter [PersonAddresses, [], AddressId] -> jump to get_PersonAddresses (return) [[], AddressId] | true | -| System.Data.Entity.DbContext.SaveChangesAsync() | this parameter [PersonAddresses, [], Id] -> jump to get_PersonAddresses (return) [[], Id] | true | -| System.Data.Entity.DbContext.SaveChangesAsync() | this parameter [PersonAddresses, [], Person, Id] -> jump to get_PersonAddresses (return) [[], Person, Id] | true | -| System.Data.Entity.DbContext.SaveChangesAsync() | this parameter [PersonAddresses, [], Person, Id] -> jump to get_Persons (return) [[], Id] | true | -| System.Data.Entity.DbContext.SaveChangesAsync() | this parameter [PersonAddresses, [], Person, Name] -> jump to get_PersonAddresses (return) [[], Person, Name] | true | -| System.Data.Entity.DbContext.SaveChangesAsync() | this parameter [PersonAddresses, [], Person, Name] -> jump to get_Persons (return) [[], Name] | true | -| System.Data.Entity.DbContext.SaveChangesAsync() | this parameter [PersonAddresses, [], PersonId] -> jump to get_PersonAddresses (return) [[], PersonId] | true | -| System.Data.Entity.DbContext.SaveChangesAsync() | this parameter [Persons, [], Addresses, [], Id] -> jump to get_Addresses (return) [[], Id] | true | -| System.Data.Entity.DbContext.SaveChangesAsync() | this parameter [Persons, [], Addresses, [], Id] -> jump to get_PersonAddresses (return) [[], Address, Id] | true | -| System.Data.Entity.DbContext.SaveChangesAsync() | this parameter [Persons, [], Addresses, [], Id] -> jump to get_PersonAddresses (return) [[], Person, Addresses, [], Id] | true | -| System.Data.Entity.DbContext.SaveChangesAsync() | this parameter [Persons, [], Addresses, [], Id] -> jump to get_Persons (return) [[], Addresses, [], Id] | true | -| System.Data.Entity.DbContext.SaveChangesAsync() | this parameter [Persons, [], Addresses, [], Street] -> jump to get_Addresses (return) [[], Street] | true | -| System.Data.Entity.DbContext.SaveChangesAsync() | this parameter [Persons, [], Addresses, [], Street] -> jump to get_PersonAddresses (return) [[], Address, Street] | true | -| System.Data.Entity.DbContext.SaveChangesAsync() | this parameter [Persons, [], Addresses, [], Street] -> jump to get_PersonAddresses (return) [[], Person, Addresses, [], Street] | true | -| System.Data.Entity.DbContext.SaveChangesAsync() | this parameter [Persons, [], Addresses, [], Street] -> jump to get_Persons (return) [[], Addresses, [], Street] | true | -| System.Data.Entity.DbContext.SaveChangesAsync() | this parameter [Persons, [], Id] -> jump to get_PersonAddresses (return) [[], Person, Id] | true | -| System.Data.Entity.DbContext.SaveChangesAsync() | this parameter [Persons, [], Id] -> jump to get_Persons (return) [[], Id] | true | -| System.Data.Entity.DbContext.SaveChangesAsync() | this parameter [Persons, [], Name] -> jump to get_PersonAddresses (return) [[], Person, Name] | true | -| System.Data.Entity.DbContext.SaveChangesAsync() | this parameter [Persons, [], Name] -> jump to get_Persons (return) [[], Name] | true | -| System.Data.Entity.DbSet<>.Add(T) | parameter 0 -> this parameter [[]] | true | -| System.Data.Entity.DbSet<>.AddAsync(T) | parameter 0 -> this parameter [[]] | true | -| System.Data.Entity.DbSet<>.AddRange(IEnumerable) | parameter 0 [[]] -> this parameter [[]] | true | -| System.Data.Entity.DbSet<>.AddRangeAsync(IEnumerable) | parameter 0 [[]] -> this parameter [[]] | true | -| System.Data.Entity.DbSet<>.Attach(T) | parameter 0 -> this parameter [[]] | true | -| System.Data.Entity.DbSet<>.AttachRange(IEnumerable) | parameter 0 [[]] -> this parameter [[]] | true | -| System.Data.Entity.DbSet<>.Update(T) | parameter 0 -> this parameter [[]] | true | -| System.Data.Entity.DbSet<>.UpdateRange(IEnumerable) | parameter 0 [[]] -> this parameter [[]] | true | +| Microsoft.EntityFrameworkCore.DbContext.SaveChanges() | property AddressId of element of property PersonAddresses of argument -1 -> property AddressId of element of return (jump to get_PersonAddresses) | true | +| Microsoft.EntityFrameworkCore.DbContext.SaveChanges() | property Id of element of property Addresses of argument -1 -> property Id of element of property Addresses of element of return (jump to get_Persons) | true | +| Microsoft.EntityFrameworkCore.DbContext.SaveChanges() | property Id of element of property Addresses of argument -1 -> property Id of element of return (jump to get_Addresses) | true | +| Microsoft.EntityFrameworkCore.DbContext.SaveChanges() | property Id of element of property Addresses of argument -1 -> property Id of property Address of element of return (jump to get_PersonAddresses) | true | +| Microsoft.EntityFrameworkCore.DbContext.SaveChanges() | property Id of element of property Addresses of element of property Persons of argument -1 -> property Id of element of property Addresses of element of return (jump to get_Persons) | true | +| Microsoft.EntityFrameworkCore.DbContext.SaveChanges() | property Id of element of property Addresses of element of property Persons of argument -1 -> property Id of element of return (jump to get_Addresses) | true | +| Microsoft.EntityFrameworkCore.DbContext.SaveChanges() | property Id of element of property Addresses of element of property Persons of argument -1 -> property Id of property Address of element of return (jump to get_PersonAddresses) | true | +| Microsoft.EntityFrameworkCore.DbContext.SaveChanges() | property Id of element of property PersonAddresses of argument -1 -> property Id of element of return (jump to get_PersonAddresses) | true | +| Microsoft.EntityFrameworkCore.DbContext.SaveChanges() | property Id of element of property Persons of argument -1 -> property Id of element of return (jump to get_Persons) | true | +| Microsoft.EntityFrameworkCore.DbContext.SaveChanges() | property Id of element of property Persons of argument -1 -> property Id of property Person of element of return (jump to get_PersonAddresses) | true | +| Microsoft.EntityFrameworkCore.DbContext.SaveChanges() | property Id of property Address of element of property PersonAddresses of argument -1 -> property Id of element of property Addresses of element of return (jump to get_Persons) | true | +| Microsoft.EntityFrameworkCore.DbContext.SaveChanges() | property Id of property Address of element of property PersonAddresses of argument -1 -> property Id of element of return (jump to get_Addresses) | true | +| Microsoft.EntityFrameworkCore.DbContext.SaveChanges() | property Id of property Address of element of property PersonAddresses of argument -1 -> property Id of property Address of element of return (jump to get_PersonAddresses) | true | +| Microsoft.EntityFrameworkCore.DbContext.SaveChanges() | property Id of property Person of element of property PersonAddresses of argument -1 -> property Id of element of return (jump to get_Persons) | true | +| Microsoft.EntityFrameworkCore.DbContext.SaveChanges() | property Id of property Person of element of property PersonAddresses of argument -1 -> property Id of property Person of element of return (jump to get_PersonAddresses) | true | +| Microsoft.EntityFrameworkCore.DbContext.SaveChanges() | property Name of element of property Persons of argument -1 -> property Name of element of return (jump to get_Persons) | true | +| Microsoft.EntityFrameworkCore.DbContext.SaveChanges() | property Name of element of property Persons of argument -1 -> property Name of property Person of element of return (jump to get_PersonAddresses) | true | +| Microsoft.EntityFrameworkCore.DbContext.SaveChanges() | property Name of property Person of element of property PersonAddresses of argument -1 -> property Name of element of return (jump to get_Persons) | true | +| Microsoft.EntityFrameworkCore.DbContext.SaveChanges() | property Name of property Person of element of property PersonAddresses of argument -1 -> property Name of property Person of element of return (jump to get_PersonAddresses) | true | +| Microsoft.EntityFrameworkCore.DbContext.SaveChanges() | property PersonId of element of property PersonAddresses of argument -1 -> property PersonId of element of return (jump to get_PersonAddresses) | true | +| Microsoft.EntityFrameworkCore.DbContext.SaveChanges() | property Street of element of property Addresses of argument -1 -> property Street of element of property Addresses of element of return (jump to get_Persons) | true | +| Microsoft.EntityFrameworkCore.DbContext.SaveChanges() | property Street of element of property Addresses of argument -1 -> property Street of element of return (jump to get_Addresses) | true | +| Microsoft.EntityFrameworkCore.DbContext.SaveChanges() | property Street of element of property Addresses of argument -1 -> property Street of property Address of element of return (jump to get_PersonAddresses) | true | +| Microsoft.EntityFrameworkCore.DbContext.SaveChanges() | property Street of element of property Addresses of element of property Persons of argument -1 -> property Street of element of property Addresses of element of return (jump to get_Persons) | true | +| Microsoft.EntityFrameworkCore.DbContext.SaveChanges() | property Street of element of property Addresses of element of property Persons of argument -1 -> property Street of element of return (jump to get_Addresses) | true | +| Microsoft.EntityFrameworkCore.DbContext.SaveChanges() | property Street of element of property Addresses of element of property Persons of argument -1 -> property Street of property Address of element of return (jump to get_PersonAddresses) | true | +| Microsoft.EntityFrameworkCore.DbContext.SaveChanges() | property Street of property Address of element of property PersonAddresses of argument -1 -> property Street of element of property Addresses of element of return (jump to get_Persons) | true | +| Microsoft.EntityFrameworkCore.DbContext.SaveChanges() | property Street of property Address of element of property PersonAddresses of argument -1 -> property Street of element of return (jump to get_Addresses) | true | +| Microsoft.EntityFrameworkCore.DbContext.SaveChanges() | property Street of property Address of element of property PersonAddresses of argument -1 -> property Street of property Address of element of return (jump to get_PersonAddresses) | true | +| Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync() | property AddressId of element of property PersonAddresses of argument -1 -> property AddressId of element of return (jump to get_PersonAddresses) | true | +| Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync() | property Id of element of property Addresses of argument -1 -> property Id of element of property Addresses of element of return (jump to get_Persons) | true | +| Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync() | property Id of element of property Addresses of argument -1 -> property Id of element of return (jump to get_Addresses) | true | +| Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync() | property Id of element of property Addresses of argument -1 -> property Id of property Address of element of return (jump to get_PersonAddresses) | true | +| Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync() | property Id of element of property Addresses of element of property Persons of argument -1 -> property Id of element of property Addresses of element of return (jump to get_Persons) | true | +| Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync() | property Id of element of property Addresses of element of property Persons of argument -1 -> property Id of element of return (jump to get_Addresses) | true | +| Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync() | property Id of element of property Addresses of element of property Persons of argument -1 -> property Id of property Address of element of return (jump to get_PersonAddresses) | true | +| Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync() | property Id of element of property PersonAddresses of argument -1 -> property Id of element of return (jump to get_PersonAddresses) | true | +| Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync() | property Id of element of property Persons of argument -1 -> property Id of element of return (jump to get_Persons) | true | +| Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync() | property Id of element of property Persons of argument -1 -> property Id of property Person of element of return (jump to get_PersonAddresses) | true | +| Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync() | property Id of property Address of element of property PersonAddresses of argument -1 -> property Id of element of property Addresses of element of return (jump to get_Persons) | true | +| Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync() | property Id of property Address of element of property PersonAddresses of argument -1 -> property Id of element of return (jump to get_Addresses) | true | +| Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync() | property Id of property Address of element of property PersonAddresses of argument -1 -> property Id of property Address of element of return (jump to get_PersonAddresses) | true | +| Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync() | property Id of property Person of element of property PersonAddresses of argument -1 -> property Id of element of return (jump to get_Persons) | true | +| Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync() | property Id of property Person of element of property PersonAddresses of argument -1 -> property Id of property Person of element of return (jump to get_PersonAddresses) | true | +| Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync() | property Name of element of property Persons of argument -1 -> property Name of element of return (jump to get_Persons) | true | +| Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync() | property Name of element of property Persons of argument -1 -> property Name of property Person of element of return (jump to get_PersonAddresses) | true | +| Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync() | property Name of property Person of element of property PersonAddresses of argument -1 -> property Name of element of return (jump to get_Persons) | true | +| Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync() | property Name of property Person of element of property PersonAddresses of argument -1 -> property Name of property Person of element of return (jump to get_PersonAddresses) | true | +| Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync() | property PersonId of element of property PersonAddresses of argument -1 -> property PersonId of element of return (jump to get_PersonAddresses) | true | +| Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync() | property Street of element of property Addresses of argument -1 -> property Street of element of property Addresses of element of return (jump to get_Persons) | true | +| Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync() | property Street of element of property Addresses of argument -1 -> property Street of element of return (jump to get_Addresses) | true | +| Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync() | property Street of element of property Addresses of argument -1 -> property Street of property Address of element of return (jump to get_PersonAddresses) | true | +| Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync() | property Street of element of property Addresses of element of property Persons of argument -1 -> property Street of element of property Addresses of element of return (jump to get_Persons) | true | +| Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync() | property Street of element of property Addresses of element of property Persons of argument -1 -> property Street of element of return (jump to get_Addresses) | true | +| Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync() | property Street of element of property Addresses of element of property Persons of argument -1 -> property Street of property Address of element of return (jump to get_PersonAddresses) | true | +| Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync() | property Street of property Address of element of property PersonAddresses of argument -1 -> property Street of element of property Addresses of element of return (jump to get_Persons) | true | +| Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync() | property Street of property Address of element of property PersonAddresses of argument -1 -> property Street of element of return (jump to get_Addresses) | true | +| Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync() | property Street of property Address of element of property PersonAddresses of argument -1 -> property Street of property Address of element of return (jump to get_PersonAddresses) | true | +| Microsoft.EntityFrameworkCore.DbSet<>.Add(T) | argument 0 -> element of argument -1 | true | +| Microsoft.EntityFrameworkCore.DbSet<>.AddAsync(T) | argument 0 -> element of argument -1 | true | +| Microsoft.EntityFrameworkCore.DbSet<>.AddRange(IEnumerable) | element of argument 0 -> element of argument -1 | true | +| Microsoft.EntityFrameworkCore.DbSet<>.AddRangeAsync(IEnumerable) | element of argument 0 -> element of argument -1 | true | +| Microsoft.EntityFrameworkCore.DbSet<>.Attach(T) | argument 0 -> element of argument -1 | true | +| Microsoft.EntityFrameworkCore.DbSet<>.AttachRange(IEnumerable) | element of argument 0 -> element of argument -1 | true | +| Microsoft.EntityFrameworkCore.DbSet<>.Update(T) | argument 0 -> element of argument -1 | true | +| Microsoft.EntityFrameworkCore.DbSet<>.UpdateRange(IEnumerable) | element of argument 0 -> element of argument -1 | true | +| Microsoft.EntityFrameworkCore.RawSqlString.RawSqlString(string) | argument 0 -> return (normal) | false | +| Microsoft.EntityFrameworkCore.RawSqlString.implicit conversion(string) | argument 0 -> return (normal) | false | +| System.Data.Entity.DbContext.SaveChanges() | property AddressId of element of property PersonAddresses of argument -1 -> property AddressId of element of return (jump to get_PersonAddresses) | true | +| System.Data.Entity.DbContext.SaveChanges() | property Id of element of property Addresses of argument -1 -> property Id of element of property Addresses of element of return (jump to get_Persons) | true | +| System.Data.Entity.DbContext.SaveChanges() | property Id of element of property Addresses of argument -1 -> property Id of element of return (jump to get_Addresses) | true | +| System.Data.Entity.DbContext.SaveChanges() | property Id of element of property Addresses of argument -1 -> property Id of property Address of element of return (jump to get_PersonAddresses) | true | +| System.Data.Entity.DbContext.SaveChanges() | property Id of element of property Addresses of element of property Persons of argument -1 -> property Id of element of property Addresses of element of return (jump to get_Persons) | true | +| System.Data.Entity.DbContext.SaveChanges() | property Id of element of property Addresses of element of property Persons of argument -1 -> property Id of element of return (jump to get_Addresses) | true | +| System.Data.Entity.DbContext.SaveChanges() | property Id of element of property Addresses of element of property Persons of argument -1 -> property Id of property Address of element of return (jump to get_PersonAddresses) | true | +| System.Data.Entity.DbContext.SaveChanges() | property Id of element of property PersonAddresses of argument -1 -> property Id of element of return (jump to get_PersonAddresses) | true | +| System.Data.Entity.DbContext.SaveChanges() | property Id of element of property Persons of argument -1 -> property Id of element of return (jump to get_Persons) | true | +| System.Data.Entity.DbContext.SaveChanges() | property Id of element of property Persons of argument -1 -> property Id of property Person of element of return (jump to get_PersonAddresses) | true | +| System.Data.Entity.DbContext.SaveChanges() | property Id of property Address of element of property PersonAddresses of argument -1 -> property Id of element of property Addresses of element of return (jump to get_Persons) | true | +| System.Data.Entity.DbContext.SaveChanges() | property Id of property Address of element of property PersonAddresses of argument -1 -> property Id of element of return (jump to get_Addresses) | true | +| System.Data.Entity.DbContext.SaveChanges() | property Id of property Address of element of property PersonAddresses of argument -1 -> property Id of property Address of element of return (jump to get_PersonAddresses) | true | +| System.Data.Entity.DbContext.SaveChanges() | property Id of property Person of element of property PersonAddresses of argument -1 -> property Id of element of return (jump to get_Persons) | true | +| System.Data.Entity.DbContext.SaveChanges() | property Id of property Person of element of property PersonAddresses of argument -1 -> property Id of property Person of element of return (jump to get_PersonAddresses) | true | +| System.Data.Entity.DbContext.SaveChanges() | property Name of element of property Persons of argument -1 -> property Name of element of return (jump to get_Persons) | true | +| System.Data.Entity.DbContext.SaveChanges() | property Name of element of property Persons of argument -1 -> property Name of property Person of element of return (jump to get_PersonAddresses) | true | +| System.Data.Entity.DbContext.SaveChanges() | property Name of property Person of element of property PersonAddresses of argument -1 -> property Name of element of return (jump to get_Persons) | true | +| System.Data.Entity.DbContext.SaveChanges() | property Name of property Person of element of property PersonAddresses of argument -1 -> property Name of property Person of element of return (jump to get_PersonAddresses) | true | +| System.Data.Entity.DbContext.SaveChanges() | property PersonId of element of property PersonAddresses of argument -1 -> property PersonId of element of return (jump to get_PersonAddresses) | true | +| System.Data.Entity.DbContext.SaveChanges() | property Street of element of property Addresses of argument -1 -> property Street of element of property Addresses of element of return (jump to get_Persons) | true | +| System.Data.Entity.DbContext.SaveChanges() | property Street of element of property Addresses of argument -1 -> property Street of element of return (jump to get_Addresses) | true | +| System.Data.Entity.DbContext.SaveChanges() | property Street of element of property Addresses of argument -1 -> property Street of property Address of element of return (jump to get_PersonAddresses) | true | +| System.Data.Entity.DbContext.SaveChanges() | property Street of element of property Addresses of element of property Persons of argument -1 -> property Street of element of property Addresses of element of return (jump to get_Persons) | true | +| System.Data.Entity.DbContext.SaveChanges() | property Street of element of property Addresses of element of property Persons of argument -1 -> property Street of element of return (jump to get_Addresses) | true | +| System.Data.Entity.DbContext.SaveChanges() | property Street of element of property Addresses of element of property Persons of argument -1 -> property Street of property Address of element of return (jump to get_PersonAddresses) | true | +| System.Data.Entity.DbContext.SaveChanges() | property Street of property Address of element of property PersonAddresses of argument -1 -> property Street of element of property Addresses of element of return (jump to get_Persons) | true | +| System.Data.Entity.DbContext.SaveChanges() | property Street of property Address of element of property PersonAddresses of argument -1 -> property Street of element of return (jump to get_Addresses) | true | +| System.Data.Entity.DbContext.SaveChanges() | property Street of property Address of element of property PersonAddresses of argument -1 -> property Street of property Address of element of return (jump to get_PersonAddresses) | true | +| System.Data.Entity.DbContext.SaveChangesAsync() | property AddressId of element of property PersonAddresses of argument -1 -> property AddressId of element of return (jump to get_PersonAddresses) | true | +| System.Data.Entity.DbContext.SaveChangesAsync() | property Id of element of property Addresses of argument -1 -> property Id of element of property Addresses of element of return (jump to get_Persons) | true | +| System.Data.Entity.DbContext.SaveChangesAsync() | property Id of element of property Addresses of argument -1 -> property Id of element of return (jump to get_Addresses) | true | +| System.Data.Entity.DbContext.SaveChangesAsync() | property Id of element of property Addresses of argument -1 -> property Id of property Address of element of return (jump to get_PersonAddresses) | true | +| System.Data.Entity.DbContext.SaveChangesAsync() | property Id of element of property Addresses of element of property Persons of argument -1 -> property Id of element of property Addresses of element of return (jump to get_Persons) | true | +| System.Data.Entity.DbContext.SaveChangesAsync() | property Id of element of property Addresses of element of property Persons of argument -1 -> property Id of element of return (jump to get_Addresses) | true | +| System.Data.Entity.DbContext.SaveChangesAsync() | property Id of element of property Addresses of element of property Persons of argument -1 -> property Id of property Address of element of return (jump to get_PersonAddresses) | true | +| System.Data.Entity.DbContext.SaveChangesAsync() | property Id of element of property PersonAddresses of argument -1 -> property Id of element of return (jump to get_PersonAddresses) | true | +| System.Data.Entity.DbContext.SaveChangesAsync() | property Id of element of property Persons of argument -1 -> property Id of element of return (jump to get_Persons) | true | +| System.Data.Entity.DbContext.SaveChangesAsync() | property Id of element of property Persons of argument -1 -> property Id of property Person of element of return (jump to get_PersonAddresses) | true | +| System.Data.Entity.DbContext.SaveChangesAsync() | property Id of property Address of element of property PersonAddresses of argument -1 -> property Id of element of property Addresses of element of return (jump to get_Persons) | true | +| System.Data.Entity.DbContext.SaveChangesAsync() | property Id of property Address of element of property PersonAddresses of argument -1 -> property Id of element of return (jump to get_Addresses) | true | +| System.Data.Entity.DbContext.SaveChangesAsync() | property Id of property Address of element of property PersonAddresses of argument -1 -> property Id of property Address of element of return (jump to get_PersonAddresses) | true | +| System.Data.Entity.DbContext.SaveChangesAsync() | property Id of property Person of element of property PersonAddresses of argument -1 -> property Id of element of return (jump to get_Persons) | true | +| System.Data.Entity.DbContext.SaveChangesAsync() | property Id of property Person of element of property PersonAddresses of argument -1 -> property Id of property Person of element of return (jump to get_PersonAddresses) | true | +| System.Data.Entity.DbContext.SaveChangesAsync() | property Name of element of property Persons of argument -1 -> property Name of element of return (jump to get_Persons) | true | +| System.Data.Entity.DbContext.SaveChangesAsync() | property Name of element of property Persons of argument -1 -> property Name of property Person of element of return (jump to get_PersonAddresses) | true | +| System.Data.Entity.DbContext.SaveChangesAsync() | property Name of property Person of element of property PersonAddresses of argument -1 -> property Name of element of return (jump to get_Persons) | true | +| System.Data.Entity.DbContext.SaveChangesAsync() | property Name of property Person of element of property PersonAddresses of argument -1 -> property Name of property Person of element of return (jump to get_PersonAddresses) | true | +| System.Data.Entity.DbContext.SaveChangesAsync() | property PersonId of element of property PersonAddresses of argument -1 -> property PersonId of element of return (jump to get_PersonAddresses) | true | +| System.Data.Entity.DbContext.SaveChangesAsync() | property Street of element of property Addresses of argument -1 -> property Street of element of property Addresses of element of return (jump to get_Persons) | true | +| System.Data.Entity.DbContext.SaveChangesAsync() | property Street of element of property Addresses of argument -1 -> property Street of element of return (jump to get_Addresses) | true | +| System.Data.Entity.DbContext.SaveChangesAsync() | property Street of element of property Addresses of argument -1 -> property Street of property Address of element of return (jump to get_PersonAddresses) | true | +| System.Data.Entity.DbContext.SaveChangesAsync() | property Street of element of property Addresses of element of property Persons of argument -1 -> property Street of element of property Addresses of element of return (jump to get_Persons) | true | +| System.Data.Entity.DbContext.SaveChangesAsync() | property Street of element of property Addresses of element of property Persons of argument -1 -> property Street of element of return (jump to get_Addresses) | true | +| System.Data.Entity.DbContext.SaveChangesAsync() | property Street of element of property Addresses of element of property Persons of argument -1 -> property Street of property Address of element of return (jump to get_PersonAddresses) | true | +| System.Data.Entity.DbContext.SaveChangesAsync() | property Street of property Address of element of property PersonAddresses of argument -1 -> property Street of element of property Addresses of element of return (jump to get_Persons) | true | +| System.Data.Entity.DbContext.SaveChangesAsync() | property Street of property Address of element of property PersonAddresses of argument -1 -> property Street of element of return (jump to get_Addresses) | true | +| System.Data.Entity.DbContext.SaveChangesAsync() | property Street of property Address of element of property PersonAddresses of argument -1 -> property Street of property Address of element of return (jump to get_PersonAddresses) | true | +| System.Data.Entity.DbSet<>.Add(T) | argument 0 -> element of argument -1 | true | +| System.Data.Entity.DbSet<>.AddAsync(T) | argument 0 -> element of argument -1 | true | +| System.Data.Entity.DbSet<>.AddRange(IEnumerable) | element of argument 0 -> element of argument -1 | true | +| System.Data.Entity.DbSet<>.AddRangeAsync(IEnumerable) | element of argument 0 -> element of argument -1 | true | +| System.Data.Entity.DbSet<>.Attach(T) | argument 0 -> element of argument -1 | true | +| System.Data.Entity.DbSet<>.AttachRange(IEnumerable) | element of argument 0 -> element of argument -1 | true | +| System.Data.Entity.DbSet<>.Update(T) | argument 0 -> element of argument -1 | true | +| System.Data.Entity.DbSet<>.UpdateRange(IEnumerable) | element of argument 0 -> element of argument -1 | true | diff --git a/csharp/ql/test/library-tests/frameworks/EntityFramework/FlowSummaries.ql b/csharp/ql/test/library-tests/frameworks/EntityFramework/FlowSummaries.ql index 598d8c0f20c..ff518640b00 100644 --- a/csharp/ql/test/library-tests/frameworks/EntityFramework/FlowSummaries.ql +++ b/csharp/ql/test/library-tests/frameworks/EntityFramework/FlowSummaries.ql @@ -1,6 +1,9 @@ -import semmle.code.csharp.dataflow.FlowSummary::TestOutput +import semmle.code.csharp.dataflow.FlowSummary +import semmle.code.csharp.dataflow.internal.FlowSummaryImpl::Private::TestOutput import semmle.code.csharp.frameworks.EntityFramework::EntityFramework -private class IncludeEFSummarizedCallable extends RelevantSummarizedCallable { - IncludeEFSummarizedCallable() { this instanceof EFSummarizedCallable } +private class IncludeSummarizedCallable extends RelevantSummarizedCallable { + IncludeSummarizedCallable() { this instanceof EFSummarizedCallable } + + override string getFullString() { result = this.(Callable).getQualifiedNameWithTypes() } } diff --git a/csharp/ql/test/library-tests/goto/Goto1.ql b/csharp/ql/test/library-tests/goto/Goto1.ql index e7ee0b3ff8a..97dd1fa2af0 100644 --- a/csharp/ql/test/library-tests/goto/Goto1.ql +++ b/csharp/ql/test/library-tests/goto/Goto1.ql @@ -1,6 +1,7 @@ import csharp query predicate edges(ControlFlow::Node node, ControlFlow::Node successor, string attr, string val) { + not node.getElement().fromLibrary() and exists(ControlFlow::SuccessorType t | successor = node.getASuccessorByType(t) | attr = "semmle.label" and val = t.toString() diff --git a/csharp/ql/test/library-tests/parameters/Parameters.cs b/csharp/ql/test/library-tests/parameters/Parameters.cs new file mode 100644 index 00000000000..b7cc3b001a9 --- /dev/null +++ b/csharp/ql/test/library-tests/parameters/Parameters.cs @@ -0,0 +1,17 @@ +public class Parameters +{ + public void M1(int a, object b, string c) => throw null; + public void M2(int a, object b = null, string c = "default string") => throw null; + public void M3(int a = 1, object b = null, string c = "null") => throw null; + public void M4(int a = default, object b = default) => throw null; + public void M5(int a = new int(), object b = default) => throw null; + public void M6(MyStruct s1, MyStruct s2 = default(MyStruct), MyStruct s3 = new MyStruct()) => throw null; + public void M7(MyEnum e1, MyEnum e2 = default(MyEnum), MyEnum e3 = new MyEnum(), MyEnum e4 = MyEnum.A, MyEnum e5 = (MyEnum)5) => throw null; + + public void M8(T t = default) => throw null; + public void M9(T t = default) where T : struct => throw null; + public void M10(T t = default) where T : class => throw null; + + public struct MyStruct { } + public enum MyEnum { A = 1, B = 2 } +} \ No newline at end of file diff --git a/csharp/ql/test/library-tests/parameters/Parameters.cs_ b/csharp/ql/test/library-tests/parameters/Parameters.cs_ new file mode 100644 index 00000000000..062c4b98b18 --- /dev/null +++ b/csharp/ql/test/library-tests/parameters/Parameters.cs_ @@ -0,0 +1,17 @@ +public class ParametersDll +{ + public void M1(int a, object b, string c) => throw null; + public void M2(int a, object b = null, string c = "default string") => throw null; + public void M3(int a = 1, object b = null, string c = "null") => throw null; + public void M4(int a = default, object b = default) => throw null; + public void M5(int a = new int(), object b = default) => throw null; + public void M6(MyStruct s1, MyStruct s2 = default(MyStruct), MyStruct s3 = new MyStruct()) => throw null; + public void M7(MyEnum e1, MyEnum e2 = default(MyEnum), MyEnum e3 = new MyEnum(), MyEnum e4 = MyEnum.A, MyEnum e5 = (MyEnum)5) => throw null; + + public void M8(T t = default) => throw null; + public void M9(T t = default) where T : struct => throw null; + public void M10(T t = default) where T : class => throw null; + + public struct MyStruct { } + public enum MyEnum { A = 1, B = 2 } +} \ No newline at end of file diff --git a/csharp/ql/test/library-tests/parameters/Parameters.dll b/csharp/ql/test/library-tests/parameters/Parameters.dll new file mode 100644 index 00000000000..cd48ebef015 Binary files /dev/null and b/csharp/ql/test/library-tests/parameters/Parameters.dll differ diff --git a/csharp/ql/test/library-tests/parameters/Parameters.expected b/csharp/ql/test/library-tests/parameters/Parameters.expected new file mode 100644 index 00000000000..864464167b9 --- /dev/null +++ b/csharp/ql/test/library-tests/parameters/Parameters.expected @@ -0,0 +1,50 @@ +noDefaultValue +| Parameters.cs:3:17:3:18 | M1 | Parameters.cs:3:24:3:24 | a | 0 | +| Parameters.cs:3:17:3:18 | M1 | Parameters.cs:3:34:3:34 | b | 1 | +| Parameters.cs:3:17:3:18 | M1 | Parameters.cs:3:44:3:44 | c | 2 | +| Parameters.cs:4:17:4:18 | M2 | Parameters.cs:4:24:4:24 | a | 0 | +| Parameters.cs:8:17:8:18 | M6 | Parameters.cs:8:29:8:30 | s1 | 0 | +| Parameters.cs:9:17:9:18 | M7 | Parameters.cs:9:27:9:28 | e1 | 0 | +| Parameters.dll:0:0:0:0 | M1 | Parameters.dll:0:0:0:0 | a | 0 | +| Parameters.dll:0:0:0:0 | M1 | Parameters.dll:0:0:0:0 | b | 1 | +| Parameters.dll:0:0:0:0 | M1 | Parameters.dll:0:0:0:0 | c | 2 | +| Parameters.dll:0:0:0:0 | M2 | Parameters.dll:0:0:0:0 | a | 0 | +| Parameters.dll:0:0:0:0 | M6 | Parameters.dll:0:0:0:0 | s1 | 0 | +| Parameters.dll:0:0:0:0 | M7 | Parameters.dll:0:0:0:0 | e1 | 0 | +withDefaultValue +| Parameters.cs:4:17:4:18 | M2 | Parameters.cs:4:34:4:34 | b | 1 | Parameters.cs:4:38:4:41 | null | null | +| Parameters.cs:4:17:4:18 | M2 | Parameters.cs:4:51:4:51 | c | 2 | Parameters.cs:4:55:4:70 | "default string" | default string | +| Parameters.cs:5:17:5:18 | M3 | Parameters.cs:5:24:5:24 | a | 0 | Parameters.cs:5:28:5:28 | 1 | 1 | +| Parameters.cs:5:17:5:18 | M3 | Parameters.cs:5:38:5:38 | b | 1 | Parameters.cs:5:42:5:45 | null | null | +| Parameters.cs:5:17:5:18 | M3 | Parameters.cs:5:55:5:55 | c | 2 | Parameters.cs:5:59:5:64 | "null" | null | +| Parameters.cs:6:17:6:18 | M4 | Parameters.cs:6:24:6:24 | a | 0 | Parameters.cs:6:28:6:34 | (...) ... | 0 | +| Parameters.cs:6:17:6:18 | M4 | Parameters.cs:6:44:6:44 | b | 1 | Parameters.cs:6:48:6:54 | default | null | +| Parameters.cs:7:17:7:18 | M5 | Parameters.cs:7:24:7:24 | a | 0 | Parameters.cs:7:28:7:36 | object creation of type Int32 | 0 | +| Parameters.cs:7:17:7:18 | M5 | Parameters.cs:7:46:7:46 | b | 1 | Parameters.cs:7:50:7:56 | default | null | +| Parameters.cs:8:17:8:18 | M6 | Parameters.cs:8:42:8:43 | s2 | 1 | Parameters.cs:8:47:8:63 | default(...) | - | +| Parameters.cs:8:17:8:18 | M6 | Parameters.cs:8:75:8:76 | s3 | 2 | Parameters.cs:8:80:8:93 | object creation of type MyStruct | - | +| Parameters.cs:9:17:9:18 | M7 | Parameters.cs:9:38:9:39 | e2 | 1 | Parameters.cs:9:43:9:57 | default(...) | 0 | +| Parameters.cs:9:17:9:18 | M7 | Parameters.cs:9:67:9:68 | e3 | 2 | Parameters.cs:9:72:9:83 | object creation of type MyEnum | 0 | +| Parameters.cs:9:17:9:18 | M7 | Parameters.cs:9:93:9:94 | e4 | 3 | Parameters.cs:9:98:9:105 | access to constant A | 1 | +| Parameters.cs:9:17:9:18 | M7 | Parameters.cs:9:115:9:116 | e5 | 4 | Parameters.cs:9:120:9:128 | (...) ... | 5 | +| Parameters.cs:11:17:11:21 | M8 | Parameters.cs:11:25:11:25 | t | 0 | Parameters.cs:11:29:11:35 | (...) ... | - | +| Parameters.cs:12:17:12:21 | M9 | Parameters.cs:12:25:12:25 | t | 0 | Parameters.cs:12:29:12:35 | (...) ... | - | +| Parameters.cs:13:17:13:22 | M10 | Parameters.cs:13:26:13:26 | t | 0 | Parameters.cs:13:30:13:36 | (...) ... | null | +| Parameters.dll:0:0:0:0 | M2 | Parameters.dll:0:0:0:0 | b | 1 | Parameters.dll:0:0:0:0 | default | null | +| Parameters.dll:0:0:0:0 | M2 | Parameters.dll:0:0:0:0 | c | 2 | Parameters.dll:0:0:0:0 | "default string" | default string | +| Parameters.dll:0:0:0:0 | M3 | Parameters.dll:0:0:0:0 | a | 0 | Parameters.dll:0:0:0:0 | 1 | 1 | +| Parameters.dll:0:0:0:0 | M3 | Parameters.dll:0:0:0:0 | b | 1 | Parameters.dll:0:0:0:0 | default | null | +| Parameters.dll:0:0:0:0 | M3 | Parameters.dll:0:0:0:0 | c | 2 | Parameters.dll:0:0:0:0 | "null" | null | +| Parameters.dll:0:0:0:0 | M4 | Parameters.dll:0:0:0:0 | a | 0 | Parameters.dll:0:0:0:0 | 0 | 0 | +| Parameters.dll:0:0:0:0 | M4 | Parameters.dll:0:0:0:0 | b | 1 | Parameters.dll:0:0:0:0 | default | null | +| Parameters.dll:0:0:0:0 | M5 | Parameters.dll:0:0:0:0 | a | 0 | Parameters.dll:0:0:0:0 | 0 | 0 | +| Parameters.dll:0:0:0:0 | M5 | Parameters.dll:0:0:0:0 | b | 1 | Parameters.dll:0:0:0:0 | default | null | +| Parameters.dll:0:0:0:0 | M6 | Parameters.dll:0:0:0:0 | s2 | 1 | Parameters.dll:0:0:0:0 | default | - | +| Parameters.dll:0:0:0:0 | M6 | Parameters.dll:0:0:0:0 | s3 | 2 | Parameters.dll:0:0:0:0 | default | - | +| Parameters.dll:0:0:0:0 | M7 | Parameters.dll:0:0:0:0 | e2 | 1 | Parameters.dll:0:0:0:0 | (...) ... | 0 | +| Parameters.dll:0:0:0:0 | M7 | Parameters.dll:0:0:0:0 | e3 | 2 | Parameters.dll:0:0:0:0 | (...) ... | 0 | +| Parameters.dll:0:0:0:0 | M7 | Parameters.dll:0:0:0:0 | e4 | 3 | Parameters.dll:0:0:0:0 | (...) ... | 1 | +| Parameters.dll:0:0:0:0 | M7 | Parameters.dll:0:0:0:0 | e5 | 4 | Parameters.dll:0:0:0:0 | (...) ... | 5 | +| Parameters.dll:0:0:0:0 | M8 | Parameters.dll:0:0:0:0 | t | 0 | Parameters.dll:0:0:0:0 | default | - | +| Parameters.dll:0:0:0:0 | M9 | Parameters.dll:0:0:0:0 | t | 0 | Parameters.dll:0:0:0:0 | default | - | +| Parameters.dll:0:0:0:0 | M10 | Parameters.dll:0:0:0:0 | t | 0 | Parameters.dll:0:0:0:0 | default | null | diff --git a/csharp/ql/test/library-tests/parameters/Parameters.ql b/csharp/ql/test/library-tests/parameters/Parameters.ql new file mode 100644 index 00000000000..dca5c2d9006 --- /dev/null +++ b/csharp/ql/test/library-tests/parameters/Parameters.ql @@ -0,0 +1,19 @@ +import csharp + +private predicate fromTestLocation(Element e) { + e.fromSource() or e.getFile().getStem() = "Parameters" +} + +query predicate noDefaultValue(Parameterizable container, Parameter p, int i) { + fromTestLocation(container) and + not p.hasDefaultValue() and + container.getParameter(i) = p +} + +query predicate withDefaultValue(Parameterizable container, Parameter p, int i, Expr e, string value) { + fromTestLocation(container) and + p.hasDefaultValue() and + container.getParameter(i) = p and + p.getDefaultValue() = e and + if exists(e.getValue()) then value = e.getValue() else value = "-" +} diff --git a/csharp/ql/test/library-tests/standalone/controlflow/cfg.ql b/csharp/ql/test/library-tests/standalone/controlflow/cfg.ql index 88a0a00c632..4936dc9b4cd 100644 --- a/csharp/ql/test/library-tests/standalone/controlflow/cfg.ql +++ b/csharp/ql/test/library-tests/standalone/controlflow/cfg.ql @@ -17,4 +17,6 @@ class UnknownLocalVariableDeclExpr extends LocalVariableDeclAndInitExpr { override string toString() { result = "(unknown type) " + this.getName() } } -query predicate edges(ControlFlow::Node n1, ControlFlow::Node n2) { n2 = n1.getASuccessor() } +query predicate edges(ControlFlow::Node n1, ControlFlow::Node n2) { + not n1.getElement().fromLibrary() and n2 = n1.getASuccessor() +} diff --git a/csharp/ql/test/query-tests/Metrics/Dependencies/ExternalDependencies/File1.cs b/csharp/ql/test/query-tests/Metrics/Dependencies/ExternalDependencies/File1.cs deleted file mode 100644 index aff76d83b3f..00000000000 --- a/csharp/ql/test/query-tests/Metrics/Dependencies/ExternalDependencies/File1.cs +++ /dev/null @@ -1,30 +0,0 @@ -// semmle-extractor-options: /r:System.Collections.dll /r:System.Data.Common.dll /r:System.Runtime.Serialization.Primitives.dll /r:System.Private.Xml.dll /r:System.Xml.ReaderWriter.dll /r:System.Net.Primitives.dll /r:System.Net.Http.dll /r:System.Private.DataContractSerialization.dll /r:System.Runtime.Serialization.dll /r:System.ComponentModel.Primitives.dll - -using System.Collections.Generic; -using System.Net.Http; -using System.Xml; -using System.Runtime.Serialization.Json; -using System.Data; - -class C -{ - System.Net.Http.HttpClient client; - System.Xml.XmlReader reader; - IXmlJsonReaderInitializer init; - - [DataSysDescription("")] - void Test() - { - client = new HttpClient(); - var request = new HttpRequestMessage(); - client.SendAsync(request); - - Method(); - } - - List initializerList; - - void Method() - { - } -} diff --git a/csharp/ql/test/query-tests/Metrics/Dependencies/ExternalDependencies/File2.cs b/csharp/ql/test/query-tests/Metrics/Dependencies/ExternalDependencies/File2.cs deleted file mode 100644 index 8df4d961b26..00000000000 --- a/csharp/ql/test/query-tests/Metrics/Dependencies/ExternalDependencies/File2.cs +++ /dev/null @@ -1,5 +0,0 @@ - -class D -{ - System.Net.Http.HttpClient client; -} diff --git a/csharp/ql/test/query-tests/Metrics/Files/FLinesOfDuplicatedCode/file1.cs b/csharp/ql/test/query-tests/Metrics/Files/FLinesOfDuplicatedCode/file1.cs deleted file mode 100644 index a1af845b74d..00000000000 --- a/csharp/ql/test/query-tests/Metrics/Files/FLinesOfDuplicatedCode/file1.cs +++ /dev/null @@ -1,48 +0,0 @@ -// These are not counted as duplicates: - -using System; -using System; -using System; -using System; -using System; -using System; -using System; -using System; -using System; -using System; - -class C1 -{ - void f() - { - int a; - int b; - int c; - int d; - int e; - int f; - int g; - int h; - int i; - int j; - int k; - } -} - -class C2 -{ - void f() - { - int a; - int b; - int c; - int d; - int e; - int f; - int g; - int h; - int i; - int j; - int k; - } -} diff --git a/csharp/ql/test/query-tests/Metrics/Files/FLinesOfDuplicatedCode/file2.cs b/csharp/ql/test/query-tests/Metrics/Files/FLinesOfDuplicatedCode/file2.cs deleted file mode 100644 index 2ac99295c6b..00000000000 --- a/csharp/ql/test/query-tests/Metrics/Files/FLinesOfDuplicatedCode/file2.cs +++ /dev/null @@ -1,30 +0,0 @@ -// These are not counted as duplicates: - -using System; -using System; -using System; -using System; -using System; -using System; -using System; -using System; -using System; - -class C3 -{ - void f() - { - int a; - int b; - int c; - int d; - int e; - int f; - int g; - int h; - int i; - int j; - int k; - } -} - diff --git a/csharp/ql/test/query-tests/Security Features/CWE-079/StoredXSS/XSS.expected b/csharp/ql/test/query-tests/Security Features/CWE-079/StoredXSS/XSS.expected index a661a86c71c..b4137bdb36d 100644 --- a/csharp/ql/test/query-tests/Security Features/CWE-079/StoredXSS/XSS.expected +++ b/csharp/ql/test/query-tests/Security Features/CWE-079/StoredXSS/XSS.expected @@ -1,12 +1,12 @@ edges -| XSS.cs:25:13:25:21 | [post] access to local variable userInput [[]] : String | XSS.cs:26:32:26:40 | access to local variable userInput [[]] : String | -| XSS.cs:25:13:25:21 | [post] access to local variable userInput [[]] : String | XSS.cs:27:29:27:37 | access to local variable userInput [[]] : String | -| XSS.cs:25:13:25:21 | [post] access to local variable userInput [[]] : String | XSS.cs:28:26:28:34 | access to local variable userInput [[]] : String | +| XSS.cs:25:13:25:21 | [post] access to local variable userInput [element] : String | XSS.cs:26:32:26:40 | access to local variable userInput [element] : String | +| XSS.cs:25:13:25:21 | [post] access to local variable userInput [element] : String | XSS.cs:27:29:27:37 | access to local variable userInput [element] : String | +| XSS.cs:25:13:25:21 | [post] access to local variable userInput [element] : String | XSS.cs:28:26:28:34 | access to local variable userInput [element] : String | | XSS.cs:25:48:25:62 | access to field categoryTextBox : TextBox | XSS.cs:25:48:25:67 | access to property Text : String | -| XSS.cs:25:48:25:67 | access to property Text : String | XSS.cs:25:13:25:21 | [post] access to local variable userInput [[]] : String | -| XSS.cs:26:32:26:40 | access to local variable userInput [[]] : String | XSS.cs:26:32:26:51 | call to method ToString | -| XSS.cs:27:29:27:37 | access to local variable userInput [[]] : String | XSS.cs:27:29:27:48 | call to method ToString | -| XSS.cs:28:26:28:34 | access to local variable userInput [[]] : String | XSS.cs:28:26:28:45 | call to method ToString | +| XSS.cs:25:48:25:67 | access to property Text : String | XSS.cs:25:13:25:21 | [post] access to local variable userInput [element] : String | +| XSS.cs:26:32:26:40 | access to local variable userInput [element] : String | XSS.cs:26:32:26:51 | call to method ToString | +| XSS.cs:27:29:27:37 | access to local variable userInput [element] : String | XSS.cs:27:29:27:48 | call to method ToString | +| XSS.cs:28:26:28:34 | access to local variable userInput [element] : String | XSS.cs:28:26:28:45 | call to method ToString | | XSS.cs:37:27:37:53 | access to property QueryString : NameValueCollection | XSS.cs:38:36:38:39 | access to local variable name | | XSS.cs:57:27:57:65 | access to property QueryString : NameValueCollection | XSS.cs:59:22:59:25 | access to local variable name | | XSS.cs:75:27:75:53 | access to property QueryString : NameValueCollection | XSS.cs:76:36:76:39 | access to local variable name | diff --git a/csharp/ql/test/query-tests/Security Features/CWE-089/SqlInjection.cs b/csharp/ql/test/query-tests/Security Features/CWE-089/SqlInjection.cs index 09a01281f79..f3593096e1e 100644 --- a/csharp/ql/test/query-tests/Security Features/CWE-089/SqlInjection.cs +++ b/csharp/ql/test/query-tests/Security Features/CWE-089/SqlInjection.cs @@ -1,4 +1,4 @@ -// semmle-extractor-options: /r:System.ComponentModel.Primitives.dll /r:System.ComponentModel.TypeConverter.dll /r:System.Data.Common.dll ${testdir}/../../../resources/stubs/EntityFramework.cs ${testdir}/../../../resources/stubs/System.Data.cs ${testdir}/../../../resources/stubs/System.Windows.cs +// semmle-extractor-options: /r:System.ComponentModel.Primitives.dll /r:System.ComponentModel.TypeConverter.dll /r:System.Data.Common.dll ${testdir}/../../../resources/stubs/EntityFramework.cs ${testdir}/../../../resources/stubs/System.Data.cs ${testdir}/../../../resources/stubs/System.Windows.cs ${testdir}/../../../resources/stubs/Dapper.cs /r:System.Linq.Expressions.dll using System; diff --git a/csharp/ql/test/query-tests/Security Features/CWE-089/SqlInjection.expected b/csharp/ql/test/query-tests/Security Features/CWE-089/SqlInjection.expected index 61dffee741f..2ad651f8c0e 100644 --- a/csharp/ql/test/query-tests/Security Features/CWE-089/SqlInjection.expected +++ b/csharp/ql/test/query-tests/Security Features/CWE-089/SqlInjection.expected @@ -5,6 +5,13 @@ edges | SqlInjection.cs:73:33:73:52 | access to property Text : String | SqlInjection.cs:74:56:74:61 | access to local variable query1 | | SqlInjection.cs:73:33:73:52 | access to property Text : String | SqlInjection.cs:75:55:75:60 | access to local variable query1 | | SqlInjection.cs:87:21:87:29 | access to property Text : String | SqlInjection.cs:88:50:88:55 | access to local variable query1 | +| SqlInjectionDapper.cs:20:86:20:94 | access to property Text : String | SqlInjectionDapper.cs:21:55:21:59 | access to local variable query | +| SqlInjectionDapper.cs:29:86:29:94 | access to property Text : String | SqlInjectionDapper.cs:30:66:30:70 | access to local variable query | +| SqlInjectionDapper.cs:38:86:38:94 | access to property Text : String | SqlInjectionDapper.cs:39:63:39:67 | access to local variable query | +| SqlInjectionDapper.cs:47:86:47:94 | access to property Text : String | SqlInjectionDapper.cs:49:47:49:51 | access to local variable query | +| SqlInjectionDapper.cs:57:86:57:94 | access to property Text : String | SqlInjectionDapper.cs:58:42:58:46 | access to local variable query | +| SqlInjectionDapper.cs:66:86:66:94 | access to property Text : String | SqlInjectionDapper.cs:67:42:67:46 | access to local variable query | +| SqlInjectionDapper.cs:75:86:75:94 | access to property Text : String | SqlInjectionDapper.cs:77:52:77:56 | access to local variable query | nodes | SqlInjection.cs:38:21:38:35 | access to field categoryTextBox : TextBox | semmle.label | access to field categoryTextBox : TextBox | | SqlInjection.cs:38:21:38:40 | access to property Text : String | semmle.label | access to property Text : String | @@ -15,8 +22,29 @@ nodes | SqlInjection.cs:75:55:75:60 | access to local variable query1 | semmle.label | access to local variable query1 | | SqlInjection.cs:87:21:87:29 | access to property Text : String | semmle.label | access to property Text : String | | SqlInjection.cs:88:50:88:55 | access to local variable query1 | semmle.label | access to local variable query1 | +| SqlInjectionDapper.cs:20:86:20:94 | access to property Text : String | semmle.label | access to property Text : String | +| SqlInjectionDapper.cs:21:55:21:59 | access to local variable query | semmle.label | access to local variable query | +| SqlInjectionDapper.cs:29:86:29:94 | access to property Text : String | semmle.label | access to property Text : String | +| SqlInjectionDapper.cs:30:66:30:70 | access to local variable query | semmle.label | access to local variable query | +| SqlInjectionDapper.cs:38:86:38:94 | access to property Text : String | semmle.label | access to property Text : String | +| SqlInjectionDapper.cs:39:63:39:67 | access to local variable query | semmle.label | access to local variable query | +| SqlInjectionDapper.cs:47:86:47:94 | access to property Text : String | semmle.label | access to property Text : String | +| SqlInjectionDapper.cs:49:47:49:51 | access to local variable query | semmle.label | access to local variable query | +| SqlInjectionDapper.cs:57:86:57:94 | access to property Text : String | semmle.label | access to property Text : String | +| SqlInjectionDapper.cs:58:42:58:46 | access to local variable query | semmle.label | access to local variable query | +| SqlInjectionDapper.cs:66:86:66:94 | access to property Text : String | semmle.label | access to property Text : String | +| SqlInjectionDapper.cs:67:42:67:46 | access to local variable query | semmle.label | access to local variable query | +| SqlInjectionDapper.cs:75:86:75:94 | access to property Text : String | semmle.label | access to property Text : String | +| SqlInjectionDapper.cs:77:52:77:56 | access to local variable query | semmle.label | access to local variable query | #select | SqlInjection.cs:39:50:39:55 | access to local variable query1 | SqlInjection.cs:38:21:38:35 | access to field categoryTextBox : TextBox | SqlInjection.cs:39:50:39:55 | access to local variable query1 | Query might include code from $@. | SqlInjection.cs:38:21:38:35 | access to field categoryTextBox : TextBox | this ASP.NET user input | | SqlInjection.cs:74:56:74:61 | access to local variable query1 | SqlInjection.cs:73:33:73:47 | access to field categoryTextBox : TextBox | SqlInjection.cs:74:56:74:61 | access to local variable query1 | Query might include code from $@. | SqlInjection.cs:73:33:73:47 | access to field categoryTextBox : TextBox | this ASP.NET user input | | SqlInjection.cs:75:55:75:60 | access to local variable query1 | SqlInjection.cs:73:33:73:47 | access to field categoryTextBox : TextBox | SqlInjection.cs:75:55:75:60 | access to local variable query1 | Query might include code from $@. | SqlInjection.cs:73:33:73:47 | access to field categoryTextBox : TextBox | this ASP.NET user input | | SqlInjection.cs:88:50:88:55 | access to local variable query1 | SqlInjection.cs:87:21:87:29 | access to property Text : String | SqlInjection.cs:88:50:88:55 | access to local variable query1 | Query might include code from $@. | SqlInjection.cs:87:21:87:29 | access to property Text : String | this TextBox text | +| SqlInjectionDapper.cs:21:55:21:59 | access to local variable query | SqlInjectionDapper.cs:20:86:20:94 | access to property Text : String | SqlInjectionDapper.cs:21:55:21:59 | access to local variable query | Query might include code from $@. | SqlInjectionDapper.cs:20:86:20:94 | access to property Text : String | this TextBox text | +| SqlInjectionDapper.cs:30:66:30:70 | access to local variable query | SqlInjectionDapper.cs:29:86:29:94 | access to property Text : String | SqlInjectionDapper.cs:30:66:30:70 | access to local variable query | Query might include code from $@. | SqlInjectionDapper.cs:29:86:29:94 | access to property Text : String | this TextBox text | +| SqlInjectionDapper.cs:39:63:39:67 | access to local variable query | SqlInjectionDapper.cs:38:86:38:94 | access to property Text : String | SqlInjectionDapper.cs:39:63:39:67 | access to local variable query | Query might include code from $@. | SqlInjectionDapper.cs:38:86:38:94 | access to property Text : String | this TextBox text | +| SqlInjectionDapper.cs:49:47:49:51 | access to local variable query | SqlInjectionDapper.cs:47:86:47:94 | access to property Text : String | SqlInjectionDapper.cs:49:47:49:51 | access to local variable query | Query might include code from $@. | SqlInjectionDapper.cs:47:86:47:94 | access to property Text : String | this TextBox text | +| SqlInjectionDapper.cs:58:42:58:46 | access to local variable query | SqlInjectionDapper.cs:57:86:57:94 | access to property Text : String | SqlInjectionDapper.cs:58:42:58:46 | access to local variable query | Query might include code from $@. | SqlInjectionDapper.cs:57:86:57:94 | access to property Text : String | this TextBox text | +| SqlInjectionDapper.cs:67:42:67:46 | access to local variable query | SqlInjectionDapper.cs:66:86:66:94 | access to property Text : String | SqlInjectionDapper.cs:67:42:67:46 | access to local variable query | Query might include code from $@. | SqlInjectionDapper.cs:66:86:66:94 | access to property Text : String | this TextBox text | +| SqlInjectionDapper.cs:77:52:77:56 | access to local variable query | SqlInjectionDapper.cs:75:86:75:94 | access to property Text : String | SqlInjectionDapper.cs:77:52:77:56 | access to local variable query | Query might include code from $@. | SqlInjectionDapper.cs:75:86:75:94 | access to property Text : String | this TextBox text | diff --git a/csharp/ql/test/query-tests/Security Features/CWE-089/SqlInjectionDapper.cs b/csharp/ql/test/query-tests/Security Features/CWE-089/SqlInjectionDapper.cs new file mode 100644 index 00000000000..ec54c70ddeb --- /dev/null +++ b/csharp/ql/test/query-tests/Security Features/CWE-089/SqlInjectionDapper.cs @@ -0,0 +1,95 @@ +using System; + +namespace Test +{ + using System.Data; + using System.Data.Entity; + using System.Data.SqlClient; + using System.Web.UI.WebControls; + using System.Threading.Tasks; + using Dapper; + + class SqlInjectionDapper + { + string connectionString; + + public void Bad01() + { + using (var connection = new SqlConnection(connectionString)) + { + var query = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='" + box1.Text + "' ORDER BY PRICE"; + var result = connection.Query(query); + } + } + + public async Task Bad02() + { + using (var connection = new SqlConnection(connectionString)) + { + var query = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='" + box1.Text + "' ORDER BY PRICE"; + var result = await connection.QueryAsync(query); + } + } + + public async Task Bad03() + { + using (var connection = new SqlConnection(connectionString)) + { + var query = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='" + box1.Text + "' ORDER BY PRICE"; + var result = await connection.QueryFirstAsync(query); + } + } + + public async Task Bad04() + { + using (var connection = new SqlConnection(connectionString)) + { + var query = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='" + box1.Text + "' ORDER BY PRICE"; + + await connection.ExecuteAsync(query); + } + } + + public void Bad05() + { + using (var connection = new SqlConnection(connectionString)) + { + var query = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='" + box1.Text + "' ORDER BY PRICE"; + connection.ExecuteScalar(query); + } + } + + public void Bad06() + { + using (var connection = new SqlConnection(connectionString)) + { + var query = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='" + box1.Text + "' ORDER BY PRICE"; + connection.ExecuteReader(query); + } + } + + public async Task Bad07() + { + using (var connection = new SqlConnection(connectionString)) + { + var query = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='" + box1.Text + "' ORDER BY PRICE"; + + var comDef = new CommandDefinition(query); + var result = await connection.QueryFirstAsync(comDef); + } + } + + public async Task Ok07() + { + using (var connection = new SqlConnection(connectionString)) + { + var query = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='" + box1.Text + "' ORDER BY PRICE"; + + var comDef = new CommandDefinition(query); + // no call to any query method + } + } + + System.Windows.Forms.TextBox box1; + } +} diff --git a/csharp/ql/test/query-tests/Security Features/CWE-338/InsecureRandomness.expected b/csharp/ql/test/query-tests/Security Features/CWE-338/InsecureRandomness.expected index 138451c31dc..6b2615a85ce 100644 --- a/csharp/ql/test/query-tests/Security Features/CWE-338/InsecureRandomness.expected +++ b/csharp/ql/test/query-tests/Security Features/CWE-338/InsecureRandomness.expected @@ -1,11 +1,11 @@ edges -| InsecureRandomness.cs:28:13:28:16 | [post] access to local variable data [[]] : Int32 | InsecureRandomness.cs:29:57:29:60 | access to local variable data [[]] : Int32 | -| InsecureRandomness.cs:28:23:28:43 | (...) ... : Int32 | InsecureRandomness.cs:28:13:28:16 | [post] access to local variable data [[]] : Int32 | +| InsecureRandomness.cs:28:13:28:16 | [post] access to local variable data [element] : Int32 | InsecureRandomness.cs:29:57:29:60 | access to local variable data [element] : Int32 | +| InsecureRandomness.cs:28:23:28:43 | (...) ... : Int32 | InsecureRandomness.cs:28:13:28:16 | [post] access to local variable data [element] : Int32 | | InsecureRandomness.cs:28:29:28:43 | call to method Next : Int32 | InsecureRandomness.cs:28:23:28:43 | (...) ... : Int32 | -| InsecureRandomness.cs:29:13:29:18 | [post] access to local variable result [[]] : String | InsecureRandomness.cs:31:16:31:21 | access to local variable result [[]] : String | -| InsecureRandomness.cs:29:27:29:61 | call to method GetString : String | InsecureRandomness.cs:29:13:29:18 | [post] access to local variable result [[]] : String | -| InsecureRandomness.cs:29:57:29:60 | access to local variable data [[]] : Int32 | InsecureRandomness.cs:29:27:29:61 | call to method GetString : String | -| InsecureRandomness.cs:31:16:31:21 | access to local variable result [[]] : String | InsecureRandomness.cs:31:16:31:32 | call to method ToString : String | +| InsecureRandomness.cs:29:13:29:18 | [post] access to local variable result [element] : String | InsecureRandomness.cs:31:16:31:21 | access to local variable result [element] : String | +| InsecureRandomness.cs:29:27:29:61 | call to method GetString : String | InsecureRandomness.cs:29:13:29:18 | [post] access to local variable result [element] : String | +| InsecureRandomness.cs:29:57:29:60 | access to local variable data [element] : Int32 | InsecureRandomness.cs:29:27:29:61 | call to method GetString : String | +| InsecureRandomness.cs:31:16:31:21 | access to local variable result [element] : String | InsecureRandomness.cs:31:16:31:32 | call to method ToString : String | | InsecureRandomness.cs:31:16:31:32 | call to method ToString : String | InsecureRandomness.cs:12:27:12:50 | call to method InsecureRandomString | | InsecureRandomness.cs:60:31:60:39 | call to method Next : Int32 | InsecureRandomness.cs:62:16:62:21 | access to local variable result : String | | InsecureRandomness.cs:62:16:62:21 | access to local variable result : String | InsecureRandomness.cs:62:16:62:32 | call to method ToString : String | @@ -16,13 +16,13 @@ nodes | InsecureRandomness.cs:12:27:12:50 | call to method InsecureRandomString | semmle.label | call to method InsecureRandomString | | InsecureRandomness.cs:13:20:13:56 | call to method InsecureRandomStringFromSelection | semmle.label | call to method InsecureRandomStringFromSelection | | InsecureRandomness.cs:14:20:14:54 | call to method InsecureRandomStringFromIndexer | semmle.label | call to method InsecureRandomStringFromIndexer | -| InsecureRandomness.cs:28:13:28:16 | [post] access to local variable data [[]] : Int32 | semmle.label | [post] access to local variable data [[]] : Int32 | +| InsecureRandomness.cs:28:13:28:16 | [post] access to local variable data [element] : Int32 | semmle.label | [post] access to local variable data [element] : Int32 | | InsecureRandomness.cs:28:23:28:43 | (...) ... : Int32 | semmle.label | (...) ... : Int32 | | InsecureRandomness.cs:28:29:28:43 | call to method Next : Int32 | semmle.label | call to method Next : Int32 | -| InsecureRandomness.cs:29:13:29:18 | [post] access to local variable result [[]] : String | semmle.label | [post] access to local variable result [[]] : String | +| InsecureRandomness.cs:29:13:29:18 | [post] access to local variable result [element] : String | semmle.label | [post] access to local variable result [element] : String | | InsecureRandomness.cs:29:27:29:61 | call to method GetString : String | semmle.label | call to method GetString : String | -| InsecureRandomness.cs:29:57:29:60 | access to local variable data [[]] : Int32 | semmle.label | access to local variable data [[]] : Int32 | -| InsecureRandomness.cs:31:16:31:21 | access to local variable result [[]] : String | semmle.label | access to local variable result [[]] : String | +| InsecureRandomness.cs:29:57:29:60 | access to local variable data [element] : Int32 | semmle.label | access to local variable data [element] : Int32 | +| InsecureRandomness.cs:31:16:31:21 | access to local variable result [element] : String | semmle.label | access to local variable result [element] : String | | InsecureRandomness.cs:31:16:31:32 | call to method ToString : String | semmle.label | call to method ToString : String | | InsecureRandomness.cs:60:31:60:39 | call to method Next : Int32 | semmle.label | call to method Next : Int32 | | InsecureRandomness.cs:62:16:62:21 | access to local variable result : String | semmle.label | access to local variable result : String | diff --git a/csharp/ql/test/query-tests/Security Features/CWE-937/VulnerablePackage.expected b/csharp/ql/test/query-tests/Security Features/CWE-937/VulnerablePackage.expected deleted file mode 100644 index 8aeb3d517e0..00000000000 --- a/csharp/ql/test/query-tests/Security Features/CWE-937/VulnerablePackage.expected +++ /dev/null @@ -1,12 +0,0 @@ -| csproj.config:4:5:4:77 | System.Text.Encodings.Web 4.3.0 | Package 'System.Text.Encodings.Web 4.3.0' has vulnerability $@, and should be upgraded to version 4.3.1. | https://github.com/dotnet/corefx/issues/19535 | Microsoft Security Advisory 4021279 | -| csproj.config:5:5:5:75 | system.text.encodings.web 4.3 | Package 'system.text.encodings.web 4.3' has vulnerability $@, and should be upgraded to version 4.3.1. | https://github.com/dotnet/corefx/issues/19535 | Microsoft Security Advisory 4021279 | -| csproj.config:6:5:6:67 | System.Net.Http 4.1.1 | Package 'System.Net.Http 4.1.1' has vulnerability $@, and should be upgraded to version 4.1.2. | https://github.com/dotnet/corefx/issues/19535 | Microsoft Security Advisory 4021279 | -| csproj.config:7:5:7:67 | System.Net.Http 4.1.2 | Package 'System.Net.Http 4.1.2' has vulnerability $@, and should be upgraded to version 4.3.4. | https://github.com/dotnet/announcements/issues/88 | CVE-2018-8292 | -| csproj.config:8:5:8:70 | System.Private.Uri 4.3.0 | Package 'System.Private.Uri 4.3.0' has vulnerability $@, and should be upgraded to version 4.3.1. | https://github.com/dotnet/announcements/issues/97 | CVE-2019-0657 | -| csproj.config:9:5:9:73 | Microsoft.NETCore.App 2.1.0 | Package 'Microsoft.NETCore.App 2.1.0' has vulnerability $@, and should be upgraded to version 2.1.8. | https://github.com/dotnet/announcements/issues/97 | CVE-2019-0657 | -| csproj.config:10:5:10:73 | Microsoft.NETCore.App 2.2.1 | Package 'Microsoft.NETCore.App 2.2.1' has vulnerability $@, and should be upgraded to version 2.2.2. | https://github.com/dotnet/announcements/issues/97 | CVE-2019-0657 | -| packages.config:9:3:9:79 | System.IO.Pipelines 4.5.0 | Package 'System.IO.Pipelines 4.5.0' has vulnerability $@, and should be upgraded to version 4.5.1. | https://github.com/aspnet/Announcements/issues/316 | CVE-2018-8409 | -| packages.config:10:3:10:81 | System.IO.Pipelines 4.5.0.0 | Package 'System.IO.Pipelines 4.5.0.0' has vulnerability $@, and should be upgraded to version 4.5.1. | https://github.com/aspnet/Announcements/issues/316 | CVE-2018-8409 | -| packages.config:11:3:11:84 | microsoft.aspnetcore.all 2.0.0 | Package 'microsoft.aspnetcore.all 2.0.0' has vulnerability $@, and should be upgraded to version 2.0.9. | https://github.com/aspnet/Announcements/issues/300 | ASPNETCore-Mar18 | -| packages.config:11:3:11:84 | microsoft.aspnetcore.all 2.0.0 | Package 'microsoft.aspnetcore.all 2.0.0' has vulnerability $@, and should be upgraded to version 2.0.9. | https://github.com/aspnet/Announcements/issues/311 | ASPNETCore-July18 | -| packages.config:12:3:12:84 | Microsoft.AspNetCore.All 2.0.8 | Package 'Microsoft.AspNetCore.All 2.0.8' has vulnerability $@, and should be upgraded to version 2.0.9. | https://github.com/aspnet/Announcements/issues/311 | ASPNETCore-July18 | diff --git a/csharp/ql/test/query-tests/Security Features/CWE-937/VulnerablePackage.qlref b/csharp/ql/test/query-tests/Security Features/CWE-937/VulnerablePackage.qlref deleted file mode 100644 index fb8a73b25f9..00000000000 --- a/csharp/ql/test/query-tests/Security Features/CWE-937/VulnerablePackage.qlref +++ /dev/null @@ -1 +0,0 @@ -Security Features/CWE-937/VulnerablePackage.ql \ No newline at end of file diff --git a/csharp/ql/test/query-tests/Security Features/CWE-937/csproj.config b/csharp/ql/test/query-tests/Security Features/CWE-937/csproj.config deleted file mode 100644 index 114d0631ba3..00000000000 --- a/csharp/ql/test/query-tests/Security Features/CWE-937/csproj.config +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - diff --git a/csharp/ql/test/query-tests/Security Features/CWE-937/packages.config b/csharp/ql/test/query-tests/Security Features/CWE-937/packages.config deleted file mode 100644 index 12f63f71043..00000000000 --- a/csharp/ql/test/query-tests/Security Features/CWE-937/packages.config +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - - - diff --git a/csharp/ql/test/query-tests/Stubs/MinimalStubsFromSource.expected b/csharp/ql/test/query-tests/Stubs/MinimalStubsFromSource.expected index d2dd3037e3c..d4a68c97906 100644 --- a/csharp/ql/test/query-tests/Stubs/MinimalStubsFromSource.expected +++ b/csharp/ql/test/query-tests/Stubs/MinimalStubsFromSource.expected @@ -1 +1 @@ -| // This file contains auto-generated code.\n// original-extractor-options: /r:System.Text.RegularExpressions.dll /r:System.Collections.Specialized.dll /r:System.Net.dll /r:System.Web.dll /r:System.Net.HttpListener.dll /r:System.Collections.Specialized.dll /r:System.Private.Uri.dll /r:System.Runtime.Extensions.dll /r:System.Linq.Parallel.dll /r:System.Collections.Concurrent.dll /r:System.Linq.Expressions.dll /r:System.Collections.dll /r:System.Linq.Queryable.dll /r:System.Linq.dll /r:System.Collections.NonGeneric.dll /r:System.ObjectModel.dll /r:System.ComponentModel.TypeConverter.dll /r:System.IO.Compression.dll /r:System.IO.Pipes.dll /r:System.Net.Primitives.dll /r:System.Net.Security.dll /r:System.Security.Cryptography.Primitives.dll /r:System.Text.RegularExpressions.dll ${testdir}/../../resources/stubs/System.Web.cs /r:System.Runtime.Serialization.Primitives.dll\n\nnamespace System\n{\n// Generated from `System.Uri` in `System.Private.Uri, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic class Uri : System.Runtime.Serialization.ISerializable\n{\n public override bool Equals(object comparand) => throw null;\n public override int GetHashCode() => throw null;\n public override string ToString() => throw null;\n void System.Runtime.Serialization.ISerializable.GetObjectData(System.Runtime.Serialization.SerializationInfo serializationInfo, System.Runtime.Serialization.StreamingContext streamingContext) => throw null;\n}\n\nnamespace Collections\n{\n// Generated from `System.Collections.Queue` in `System.Collections.NonGeneric, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic class Queue : System.ICloneable, System.Collections.IEnumerable, System.Collections.ICollection\n{\n public virtual System.Collections.IEnumerator GetEnumerator() => throw null;\n public virtual bool IsSynchronized { get => throw null; }\n public virtual int Count { get => throw null; }\n public virtual object Clone() => throw null;\n public virtual object SyncRoot { get => throw null; }\n public virtual void CopyTo(System.Array array, int index) => throw null;\n}\n\n// Generated from `System.Collections.SortedList` in `System.Collections.NonGeneric, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic class SortedList : System.ICloneable, System.Collections.IEnumerable, System.Collections.IDictionary, System.Collections.ICollection\n{\n System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => throw null;\n public virtual System.Collections.ICollection Keys { get => throw null; }\n public virtual System.Collections.ICollection Values { get => throw null; }\n public virtual System.Collections.IDictionaryEnumerator GetEnumerator() => throw null;\n public virtual bool Contains(object key) => throw null;\n public virtual bool IsFixedSize { get => throw null; }\n public virtual bool IsReadOnly { get => throw null; }\n public virtual bool IsSynchronized { get => throw null; }\n public virtual int Count { get => throw null; }\n public virtual object Clone() => throw null;\n public virtual object GetByIndex(int index) => throw null;\n public virtual object SyncRoot { get => throw null; }\n public virtual object this[object key] { get => throw null; set => throw null; }\n public virtual void Add(object key, object value) => throw null;\n public virtual void Clear() => throw null;\n public virtual void CopyTo(System.Array array, int arrayIndex) => throw null;\n public virtual void Remove(object key) => throw null;\n}\n\n// Generated from `System.Collections.Stack` in `System.Collections.NonGeneric, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic class Stack : System.ICloneable, System.Collections.IEnumerable, System.Collections.ICollection\n{\n public virtual System.Collections.IEnumerator GetEnumerator() => throw null;\n public virtual bool IsSynchronized { get => throw null; }\n public virtual int Count { get => throw null; }\n public virtual object Clone() => throw null;\n public virtual object SyncRoot { get => throw null; }\n public virtual void CopyTo(System.Array array, int index) => throw null;\n}\n\nnamespace Concurrent\n{\n// Generated from `System.Collections.Concurrent.BlockingCollection<>` in `System.Collections.Concurrent, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic class BlockingCollection : System.IDisposable, System.Collections.IEnumerable, System.Collections.ICollection, System.Collections.Generic.IReadOnlyCollection, System.Collections.Generic.IEnumerable\n{\n System.Collections.Generic.IEnumerator System.Collections.Generic.IEnumerable.GetEnumerator() => throw null;\n System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => throw null;\n bool System.Collections.ICollection.IsSynchronized { get => throw null; }\n object System.Collections.ICollection.SyncRoot { get => throw null; }\n public int Count { get => throw null; }\n public void Dispose() => throw null;\n void System.Collections.ICollection.CopyTo(System.Array array, int index) => throw null;\n}\n\n// Generated from `System.Collections.Concurrent.BlockingCollectionDebugView<>` in `System.Collections.Concurrent, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\nclass BlockingCollectionDebugView\n{\n}\n\n// Generated from `System.Collections.Concurrent.IDictionaryDebugView<,>` in `System.Collections.Concurrent, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\nclass IDictionaryDebugView\n{\n}\n\n}\nnamespace Generic\n{\n// Generated from `System.Collections.Generic.CollectionDebugView<>` in `System.ObjectModel, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\nclass CollectionDebugView\n{\n}\n\n// Generated from `System.Collections.Generic.DictionaryDebugView<,>` in `System.ObjectModel, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\nclass DictionaryDebugView\n{\n}\n\n// Generated from `System.Collections.Generic.QueueDebugView<>` in `System.Collections, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\nclass QueueDebugView\n{\n}\n\n// Generated from `System.Collections.Generic.SortedSet<>` in `System.Collections, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic class SortedSet : System.Runtime.Serialization.ISerializable, System.Runtime.Serialization.IDeserializationCallback, System.Collections.IEnumerable, System.Collections.ICollection, System.Collections.Generic.ISet, System.Collections.Generic.IReadOnlySet, System.Collections.Generic.IReadOnlyCollection, System.Collections.Generic.IEnumerable, System.Collections.Generic.ICollection\n{\n System.Collections.Generic.IEnumerator System.Collections.Generic.IEnumerable.GetEnumerator() => throw null;\n System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => throw null;\n bool System.Collections.Generic.ICollection.IsReadOnly { get => throw null; }\n bool System.Collections.ICollection.IsSynchronized { get => throw null; }\n object System.Collections.ICollection.SyncRoot { get => throw null; }\n public bool Add(T item) => throw null;\n public bool IsProperSubsetOf(System.Collections.Generic.IEnumerable other) => throw null;\n public bool IsProperSupersetOf(System.Collections.Generic.IEnumerable other) => throw null;\n public bool IsSubsetOf(System.Collections.Generic.IEnumerable other) => throw null;\n public bool IsSupersetOf(System.Collections.Generic.IEnumerable other) => throw null;\n public bool Overlaps(System.Collections.Generic.IEnumerable other) => throw null;\n public bool Remove(T item) => throw null;\n public bool SetEquals(System.Collections.Generic.IEnumerable other) => throw null;\n public int Count { get => throw null; }\n public virtual bool Contains(T item) => throw null;\n public virtual void Clear() => throw null;\n public virtual void IntersectWith(System.Collections.Generic.IEnumerable other) => throw null;\n public void CopyTo(T[] array, int index) => throw null;\n public void ExceptWith(System.Collections.Generic.IEnumerable other) => throw null;\n public void SymmetricExceptWith(System.Collections.Generic.IEnumerable other) => throw null;\n public void UnionWith(System.Collections.Generic.IEnumerable other) => throw null;\n void System.Collections.Generic.ICollection.Add(T item) => throw null;\n void System.Collections.ICollection.CopyTo(System.Array array, int index) => throw null;\n void System.Runtime.Serialization.IDeserializationCallback.OnDeserialization(object sender) => throw null;\n void System.Runtime.Serialization.ISerializable.GetObjectData(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) => throw null;\n}\n\n// Generated from `System.Collections.Generic.Stack<>` in `System.Collections, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic class Stack : System.Collections.IEnumerable, System.Collections.ICollection, System.Collections.Generic.IReadOnlyCollection, System.Collections.Generic.IEnumerable\n{\n System.Collections.Generic.IEnumerator System.Collections.Generic.IEnumerable.GetEnumerator() => throw null;\n System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => throw null;\n bool System.Collections.ICollection.IsSynchronized { get => throw null; }\n object System.Collections.ICollection.SyncRoot { get => throw null; }\n public T Peek() => throw null;\n public int Count { get => throw null; }\n void System.Collections.ICollection.CopyTo(System.Array array, int arrayIndex) => throw null;\n}\n\n// Generated from `System.Collections.Generic.StackDebugView<>` in `System.Collections, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\nclass StackDebugView\n{\n}\n\n}\nnamespace Specialized\n{\n// Generated from `System.Collections.Specialized.NameObjectCollectionBase` in `System.Collections.Specialized, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\nabstract public class NameObjectCollectionBase : System.Runtime.Serialization.ISerializable, System.Runtime.Serialization.IDeserializationCallback, System.Collections.IEnumerable, System.Collections.ICollection\n{\n bool System.Collections.ICollection.IsSynchronized { get => throw null; }\n object System.Collections.ICollection.SyncRoot { get => throw null; }\n public virtual System.Collections.IEnumerator GetEnumerator() => throw null;\n public virtual int Count { get => throw null; }\n public virtual void GetObjectData(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) => throw null;\n public virtual void OnDeserialization(object sender) => throw null;\n void System.Collections.ICollection.CopyTo(System.Array array, int index) => throw null;\n}\n\n// Generated from `System.Collections.Specialized.NameValueCollection` in `System.Collections.Specialized, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic class NameValueCollection : System.Collections.Specialized.NameObjectCollectionBase\n{\n public string this[string name] { get => throw null; set => throw null; }\n}\n\n}\n}\nnamespace ComponentModel\n{\n// Generated from `System.ComponentModel.ComponentConverter` in `System.ComponentModel.TypeConverter, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic class ComponentConverter : System.ComponentModel.ReferenceConverter\n{\n}\n\n// Generated from `System.ComponentModel.DefaultEventAttribute` in `System.ComponentModel.TypeConverter, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic class DefaultEventAttribute : System.Attribute\n{\n public DefaultEventAttribute(string name) => throw null;\n public override bool Equals(object obj) => throw null;\n public override int GetHashCode() => throw null;\n}\n\n// Generated from `System.ComponentModel.DefaultPropertyAttribute` in `System.ComponentModel.TypeConverter, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic class DefaultPropertyAttribute : System.Attribute\n{\n public DefaultPropertyAttribute(string name) => throw null;\n public override bool Equals(object obj) => throw null;\n public override int GetHashCode() => throw null;\n}\n\n// Generated from `System.ComponentModel.INotifyPropertyChanged` in `System.ObjectModel, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic interface INotifyPropertyChanged\n{\n}\n\n// Generated from `System.ComponentModel.ReferenceConverter` in `System.ComponentModel.TypeConverter, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic class ReferenceConverter : System.ComponentModel.TypeConverter\n{\n}\n\n// Generated from `System.ComponentModel.TypeConverterAttribute` in `System.ObjectModel, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic class TypeConverterAttribute : System.Attribute\n{\n public TypeConverterAttribute() => throw null;\n public TypeConverterAttribute(System.Type type) => throw null;\n public TypeConverterAttribute(string typeName) => throw null;\n public override bool Equals(object obj) => throw null;\n public override int GetHashCode() => throw null;\n}\n\n// Generated from `System.ComponentModel.TypeConverter` in `System.ComponentModel.TypeConverter, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic class TypeConverter\n{\n}\n\n// Generated from `System.ComponentModel.TypeDescriptionProviderAttribute` in `System.ObjectModel, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic class TypeDescriptionProviderAttribute : System.Attribute\n{\n public TypeDescriptionProviderAttribute(System.Type type) => throw null;\n public TypeDescriptionProviderAttribute(string typeName) => throw null;\n}\n\n// Generated from `System.ComponentModel.TypeDescriptionProvider` in `System.ComponentModel.TypeConverter, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\nabstract public class TypeDescriptionProvider\n{\n}\n\n// Generated from `System.ComponentModel.TypeDescriptor` in `System.ComponentModel.TypeConverter, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic class TypeDescriptor\n{\n}\n\nnamespace Design\n{\n// Generated from `System.ComponentModel.Design.DesignerOptionService` in `System.ComponentModel.TypeConverter, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\nabstract public class DesignerOptionService : System.ComponentModel.Design.IDesignerOptionService\n{\n}\n\n// Generated from `System.ComponentModel.Design.IDesignerOptionService` in `System.ComponentModel.TypeConverter, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic interface IDesignerOptionService\n{\n}\n\n}\n}\nnamespace Dynamic\n{\n// Generated from `System.Dynamic.DynamicMetaObject` in `System.Linq.Expressions, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic class DynamicMetaObject\n{\n}\n\n// Generated from `System.Dynamic.ExpandoObject` in `System.Linq.Expressions, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic class ExpandoObject : System.Dynamic.IDynamicMetaObjectProvider, System.ComponentModel.INotifyPropertyChanged, System.Collections.IEnumerable, System.Collections.Generic.IEnumerable>, System.Collections.Generic.IDictionary, System.Collections.Generic.ICollection>\n{\n System.Collections.Generic.ICollection System.Collections.Generic.IDictionary.Values { get => throw null; }\n System.Collections.Generic.ICollection System.Collections.Generic.IDictionary.Keys { get => throw null; }\n System.Collections.Generic.IEnumerator> System.Collections.Generic.IEnumerable>.GetEnumerator() => throw null;\n System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => throw null;\n bool System.Collections.Generic.ICollection>.Contains(System.Collections.Generic.KeyValuePair item) => throw null;\n bool System.Collections.Generic.ICollection>.IsReadOnly { get => throw null; }\n bool System.Collections.Generic.ICollection>.Remove(System.Collections.Generic.KeyValuePair item) => throw null;\n bool System.Collections.Generic.IDictionary.ContainsKey(string key) => throw null;\n bool System.Collections.Generic.IDictionary.Remove(string key) => throw null;\n bool System.Collections.Generic.IDictionary.TryGetValue(string key, out object value) => throw null;\n int System.Collections.Generic.ICollection>.Count { get => throw null; }\n object this[string key] { get => throw null; set => throw null; }\n void System.Collections.Generic.ICollection>.Add(System.Collections.Generic.KeyValuePair item) => throw null;\n void System.Collections.Generic.ICollection>.Clear() => throw null;\n void System.Collections.Generic.ICollection>.CopyTo(System.Collections.Generic.KeyValuePair[] array, int arrayIndex) => throw null;\n void System.Collections.Generic.IDictionary.Add(string key, object value) => throw null;\n}\n\n// Generated from `System.Dynamic.IDynamicMetaObjectProvider` in `System.Linq.Expressions, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic interface IDynamicMetaObjectProvider\n{\n}\n\nnamespace Utils\n{\n// Generated from `System.Dynamic.Utils.ListProvider<>` in `System.Linq.Expressions, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\nabstract class ListProvider : System.Collections.IEnumerable, System.Collections.Generic.IList, System.Collections.Generic.IEnumerable, System.Collections.Generic.ICollection where T: class\n{\n System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => throw null;\n public System.Collections.Generic.IEnumerator GetEnumerator() => throw null;\n public T this[int index] { get => throw null; set => throw null; }\n public bool Contains(T item) => throw null;\n public bool IsReadOnly { get => throw null; }\n public bool Remove(T item) => throw null;\n public int Count { get => throw null; }\n public int IndexOf(T item) => throw null;\n public void Add(T item) => throw null;\n public void Clear() => throw null;\n public void CopyTo(T[] array, int index) => throw null;\n public void Insert(int index, T item) => throw null;\n public void RemoveAt(int index) => throw null;\n}\n\n}\n}\nnamespace IO\n{\nnamespace Compression\n{\n// Generated from `System.IO.Compression.DeflateStream` in `System.IO.Compression, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089`\npublic class DeflateStream : System.IO.Stream\n{\n protected override void Dispose(bool disposing) => throw null;\n public override System.IAsyncResult BeginRead(System.Byte[] buffer, int offset, int count, System.AsyncCallback asyncCallback, object asyncState) => throw null;\n public override System.IAsyncResult BeginWrite(System.Byte[] array, int offset, int count, System.AsyncCallback asyncCallback, object asyncState) => throw null;\n public override System.Int64 Length { get => throw null; }\n public override System.Int64 Position { get => throw null; set => throw null; }\n public override System.Int64 Seek(System.Int64 offset, System.IO.SeekOrigin origin) => throw null;\n public override System.Threading.Tasks.Task CopyToAsync(System.IO.Stream destination, int bufferSize, System.Threading.CancellationToken cancellationToken) => throw null;\n public override System.Threading.Tasks.Task FlushAsync(System.Threading.CancellationToken cancellationToken) => throw null;\n public override System.Threading.Tasks.Task WriteAsync(System.Byte[] array, int offset, int count, System.Threading.CancellationToken cancellationToken) => throw null;\n public override System.Threading.Tasks.Task ReadAsync(System.Byte[] array, int offset, int count, System.Threading.CancellationToken cancellationToken) => throw null;\n public override System.Threading.Tasks.ValueTask DisposeAsync() => throw null;\n public override System.Threading.Tasks.ValueTask WriteAsync(System.ReadOnlyMemory buffer, System.Threading.CancellationToken cancellationToken) => throw null;\n public override System.Threading.Tasks.ValueTask ReadAsync(System.Memory buffer, System.Threading.CancellationToken cancellationToken) => throw null;\n public override bool CanRead { get => throw null; }\n public override bool CanSeek { get => throw null; }\n public override bool CanWrite { get => throw null; }\n public override int EndRead(System.IAsyncResult asyncResult) => throw null;\n public override int Read(System.Byte[] array, int offset, int count) => throw null;\n public override int Read(System.Span buffer) => throw null;\n public override int ReadByte() => throw null;\n public override void CopyTo(System.IO.Stream destination, int bufferSize) => throw null;\n public override void EndWrite(System.IAsyncResult asyncResult) => throw null;\n public override void Flush() => throw null;\n public override void SetLength(System.Int64 value) => throw null;\n public override void Write(System.Byte[] array, int offset, int count) => throw null;\n public override void Write(System.ReadOnlySpan buffer) => throw null;\n}\n\n}\n}\nnamespace Linq\n{\n// Generated from `System.Linq.Enumerable` in `System.Linq, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\nstatic public class Enumerable\n{\n public static System.Collections.Generic.IEnumerable Select(this System.Collections.Generic.IEnumerable source, System.Func selector) => throw null;\n}\n\n// Generated from `System.Linq.Grouping<,>` in `System.Linq, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic class Grouping : System.Linq.IGrouping, System.Collections.IEnumerable, System.Collections.Generic.IList, System.Collections.Generic.IEnumerable, System.Collections.Generic.ICollection\n{\n System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => throw null;\n TElement this[int index] { get => throw null; set => throw null; }\n bool System.Collections.Generic.ICollection.Contains(TElement item) => throw null;\n bool System.Collections.Generic.ICollection.IsReadOnly { get => throw null; }\n bool System.Collections.Generic.ICollection.Remove(TElement item) => throw null;\n int System.Collections.Generic.ICollection.Count { get => throw null; }\n int System.Collections.Generic.IList.IndexOf(TElement item) => throw null;\n public System.Collections.Generic.IEnumerator GetEnumerator() => throw null;\n void System.Collections.Generic.ICollection.Add(TElement item) => throw null;\n void System.Collections.Generic.ICollection.Clear() => throw null;\n void System.Collections.Generic.ICollection.CopyTo(TElement[] array, int arrayIndex) => throw null;\n void System.Collections.Generic.IList.Insert(int index, TElement item) => throw null;\n void System.Collections.Generic.IList.RemoveAt(int index) => throw null;\n}\n\n// Generated from `System.Linq.IGrouping<,>` in `System.Linq, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic interface IGrouping : System.Collections.IEnumerable, System.Collections.Generic.IEnumerable\n{\n}\n\n// Generated from `System.Linq.IIListProvider<>` in `System.Linq, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\ninterface IIListProvider : System.Collections.IEnumerable, System.Collections.Generic.IEnumerable\n{\n}\n\n// Generated from `System.Linq.ILookup<,>` in `System.Linq, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic interface ILookup : System.Collections.IEnumerable, System.Collections.Generic.IEnumerable>\n{\n}\n\n// Generated from `System.Linq.IOrderedEnumerable<>` in `System.Linq, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic interface IOrderedEnumerable : System.Collections.IEnumerable, System.Collections.Generic.IEnumerable\n{\n}\n\n// Generated from `System.Linq.IPartition<>` in `System.Linq, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\ninterface IPartition : System.Linq.IIListProvider, System.Collections.IEnumerable, System.Collections.Generic.IEnumerable\n{\n}\n\n// Generated from `System.Linq.IQueryable` in `System.Linq.Expressions, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic interface IQueryable : System.Collections.IEnumerable\n{\n}\n\n// Generated from `System.Linq.Lookup<,>` in `System.Linq, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic class Lookup : System.Linq.ILookup, System.Linq.IIListProvider>, System.Collections.IEnumerable, System.Collections.Generic.IEnumerable>\n{\n System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => throw null;\n public System.Collections.Generic.IEnumerator> GetEnumerator() => throw null;\n}\n\n// Generated from `System.Linq.OrderedEnumerable<>` in `System.Linq, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\nabstract class OrderedEnumerable : System.Linq.IPartition, System.Linq.IOrderedEnumerable, System.Linq.IIListProvider, System.Collections.IEnumerable, System.Collections.Generic.IEnumerable\n{\n System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => throw null;\n public System.Collections.Generic.IEnumerator GetEnumerator() => throw null;\n}\n\n// Generated from `System.Linq.ParallelEnumerable` in `System.Linq.Parallel, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\nstatic public class ParallelEnumerable\n{\n public static System.Linq.ParallelQuery AsParallel(this System.Collections.IEnumerable source) => throw null;\n}\n\n// Generated from `System.Linq.ParallelQuery<>` in `System.Linq.Parallel, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic class ParallelQuery : System.Linq.ParallelQuery, System.Collections.IEnumerable, System.Collections.Generic.IEnumerable\n{\n public virtual System.Collections.Generic.IEnumerator GetEnumerator() => throw null;\n}\n\n// Generated from `System.Linq.ParallelQuery` in `System.Linq.Parallel, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic class ParallelQuery : System.Collections.IEnumerable\n{\n System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => throw null;\n}\n\n// Generated from `System.Linq.Queryable` in `System.Linq.Queryable, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\nstatic public class Queryable\n{\n public static System.Linq.IQueryable AsQueryable(this System.Collections.IEnumerable source) => throw null;\n}\n\n// Generated from `System.Linq.SystemLinq_GroupingDebugView<,>` in `System.Linq, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\nclass SystemLinq_GroupingDebugView\n{\n}\n\n// Generated from `System.Linq.SystemLinq_LookupDebugView<,>` in `System.Linq, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\nclass SystemLinq_LookupDebugView\n{\n}\n\nnamespace Expressions\n{\n// Generated from `System.Linq.Expressions.BlockExpressionList` in `System.Linq.Expressions, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\nclass BlockExpressionList : System.Collections.IEnumerable, System.Collections.Generic.IList, System.Collections.Generic.IEnumerable, System.Collections.Generic.ICollection\n{\n System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => throw null;\n public System.Collections.Generic.IEnumerator GetEnumerator() => throw null;\n public System.Linq.Expressions.Expression this[int index] { get => throw null; set => throw null; }\n public bool Contains(System.Linq.Expressions.Expression item) => throw null;\n public bool IsReadOnly { get => throw null; }\n public bool Remove(System.Linq.Expressions.Expression item) => throw null;\n public int Count { get => throw null; }\n public int IndexOf(System.Linq.Expressions.Expression item) => throw null;\n public void Add(System.Linq.Expressions.Expression item) => throw null;\n public void Clear() => throw null;\n public void CopyTo(System.Linq.Expressions.Expression[] array, int index) => throw null;\n public void Insert(int index, System.Linq.Expressions.Expression item) => throw null;\n public void RemoveAt(int index) => throw null;\n}\n\n// Generated from `System.Linq.Expressions.Expression` in `System.Linq.Expressions, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\nabstract public class Expression\n{\n public override string ToString() => throw null;\n}\n\n// Generated from `System.Linq.Expressions.ParameterExpression` in `System.Linq.Expressions, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic class ParameterExpression : System.Linq.Expressions.Expression\n{\n}\n\nnamespace Compiler\n{\n// Generated from `System.Linq.Expressions.Compiler.ParameterList` in `System.Linq.Expressions, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\nclass ParameterList : System.Collections.IEnumerable, System.Collections.Generic.IReadOnlyList, System.Collections.Generic.IReadOnlyCollection, System.Collections.Generic.IEnumerable\n{\n System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => throw null;\n public System.Collections.Generic.IEnumerator GetEnumerator() => throw null;\n public System.Linq.Expressions.ParameterExpression this[int index] { get => throw null; }\n public int Count { get => throw null; }\n}\n\n}\nnamespace Interpreter\n{\n// Generated from `System.Linq.Expressions.Interpreter.InstructionArray` in `System.Linq.Expressions, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\nstruct InstructionArray\n{\n}\n\n// Generated from `System.Linq.Expressions.Interpreter.InstructionList` in `System.Linq.Expressions, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\nclass InstructionList\n{\n}\n\n// Generated from `System.Linq.Expressions.Interpreter.InterpretedFrameInfo` in `System.Linq.Expressions, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\nstruct InterpretedFrameInfo\n{\n public override string ToString() => throw null;\n}\n\n// Generated from `System.Linq.Expressions.Interpreter.InterpretedFrame` in `System.Linq.Expressions, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\nclass InterpretedFrame\n{\n}\n\n}\n}\nnamespace Parallel\n{\n// Generated from `System.Linq.Parallel.ListChunk<>` in `System.Linq.Parallel, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\nclass ListChunk : System.Collections.IEnumerable, System.Collections.Generic.IEnumerable\n{\n System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => throw null;\n public System.Collections.Generic.IEnumerator GetEnumerator() => throw null;\n}\n\n// Generated from `System.Linq.Parallel.Lookup<,>` in `System.Linq.Parallel, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\nclass Lookup : System.Linq.ILookup, System.Collections.IEnumerable, System.Collections.Generic.IEnumerable>\n{\n System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => throw null;\n public System.Collections.Generic.IEnumerator> GetEnumerator() => throw null;\n}\n\n// Generated from `System.Linq.Parallel.PartitionerQueryOperator<>` in `System.Linq.Parallel, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\nclass PartitionerQueryOperator : System.Linq.Parallel.QueryOperator\n{\n}\n\n// Generated from `System.Linq.Parallel.QueryOperator<>` in `System.Linq.Parallel, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\nabstract class QueryOperator : System.Linq.ParallelQuery\n{\n public override System.Collections.Generic.IEnumerator GetEnumerator() => throw null;\n}\n\n// Generated from `System.Linq.Parallel.QueryResults<>` in `System.Linq.Parallel, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\nabstract class QueryResults : System.Collections.IEnumerable, System.Collections.Generic.IList, System.Collections.Generic.IEnumerable, System.Collections.Generic.ICollection\n{\n System.Collections.Generic.IEnumerator System.Collections.Generic.IEnumerable.GetEnumerator() => throw null;\n System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => throw null;\n bool System.Collections.Generic.ICollection.Contains(T item) => throw null;\n bool System.Collections.Generic.ICollection.IsReadOnly { get => throw null; }\n bool System.Collections.Generic.ICollection.Remove(T item) => throw null;\n int System.Collections.Generic.IList.IndexOf(T item) => throw null;\n public T this[int index] { get => throw null; set => throw null; }\n public int Count { get => throw null; }\n void System.Collections.Generic.ICollection.Add(T item) => throw null;\n void System.Collections.Generic.ICollection.Clear() => throw null;\n void System.Collections.Generic.ICollection.CopyTo(T[] array, int arrayIndex) => throw null;\n void System.Collections.Generic.IList.Insert(int index, T item) => throw null;\n void System.Collections.Generic.IList.RemoveAt(int index) => throw null;\n}\n\n// Generated from `System.Linq.Parallel.ZipQueryOperator<,,>` in `System.Linq.Parallel, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\nclass ZipQueryOperator : System.Linq.Parallel.QueryOperator\n{\n}\n\n}\n}\nnamespace Net\n{\n// Generated from `System.Net.CookieCollection` in `System.Net.Primitives, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic class CookieCollection : System.Collections.IEnumerable, System.Collections.ICollection, System.Collections.Generic.IReadOnlyCollection, System.Collections.Generic.IEnumerable, System.Collections.Generic.ICollection\n{\n System.Collections.Generic.IEnumerator System.Collections.Generic.IEnumerable.GetEnumerator() => throw null;\n public System.Collections.IEnumerator GetEnumerator() => throw null;\n public bool Contains(System.Net.Cookie cookie) => throw null;\n public bool IsReadOnly { get => throw null; }\n public bool IsSynchronized { get => throw null; }\n public bool Remove(System.Net.Cookie cookie) => throw null;\n public int Count { get => throw null; }\n public object SyncRoot { get => throw null; }\n public void Add(System.Net.Cookie cookie) => throw null;\n public void Clear() => throw null;\n public void CopyTo(System.Array array, int index) => throw null;\n public void CopyTo(System.Net.Cookie[] array, int index) => throw null;\n}\n\n// Generated from `System.Net.Cookie` in `System.Net.Primitives, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic class Cookie\n{\n public override bool Equals(object comparand) => throw null;\n public override int GetHashCode() => throw null;\n public override string ToString() => throw null;\n}\n\n// Generated from `System.Net.StreamFramer` in `System.Net.Security, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\nclass StreamFramer\n{\n}\n\nnamespace Security\n{\n// Generated from `System.Net.Security.AuthenticatedStream` in `System.Net.Security, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\nabstract public class AuthenticatedStream : System.IO.Stream\n{\n protected override void Dispose(bool disposing) => throw null;\n public override System.Threading.Tasks.ValueTask DisposeAsync() => throw null;\n}\n\n// Generated from `System.Net.Security.CipherSuitesPolicy` in `System.Net.Security, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic class CipherSuitesPolicy\n{\n}\n\n// Generated from `System.Net.Security.NegotiateStream` in `System.Net.Security, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic class NegotiateStream : System.Net.Security.AuthenticatedStream\n{\n protected override void Dispose(bool disposing) => throw null;\n public override System.IAsyncResult BeginRead(System.Byte[] buffer, int offset, int count, System.AsyncCallback asyncCallback, object asyncState) => throw null;\n public override System.IAsyncResult BeginWrite(System.Byte[] buffer, int offset, int count, System.AsyncCallback asyncCallback, object asyncState) => throw null;\n public override System.Int64 Length { get => throw null; }\n public override System.Int64 Position { get => throw null; set => throw null; }\n public override System.Int64 Seek(System.Int64 offset, System.IO.SeekOrigin origin) => throw null;\n public override System.Threading.Tasks.Task FlushAsync(System.Threading.CancellationToken cancellationToken) => throw null;\n public override System.Threading.Tasks.Task WriteAsync(System.Byte[] buffer, int offset, int count, System.Threading.CancellationToken cancellationToken) => throw null;\n public override System.Threading.Tasks.Task ReadAsync(System.Byte[] buffer, int offset, int count, System.Threading.CancellationToken cancellationToken) => throw null;\n public override System.Threading.Tasks.ValueTask DisposeAsync() => throw null;\n public override System.Threading.Tasks.ValueTask WriteAsync(System.ReadOnlyMemory buffer, System.Threading.CancellationToken cancellationToken) => throw null;\n public override System.Threading.Tasks.ValueTask ReadAsync(System.Memory buffer, System.Threading.CancellationToken cancellationToken) => throw null;\n public override bool CanRead { get => throw null; }\n public override bool CanSeek { get => throw null; }\n public override bool CanTimeout { get => throw null; }\n public override bool CanWrite { get => throw null; }\n public override int EndRead(System.IAsyncResult asyncResult) => throw null;\n public override int Read(System.Byte[] buffer, int offset, int count) => throw null;\n public override int ReadTimeout { get => throw null; set => throw null; }\n public override int WriteTimeout { get => throw null; set => throw null; }\n public override void EndWrite(System.IAsyncResult asyncResult) => throw null;\n public override void Flush() => throw null;\n public override void SetLength(System.Int64 value) => throw null;\n public override void Write(System.Byte[] buffer, int offset, int count) => throw null;\n}\n\n// Generated from `System.Net.Security.SslStream` in `System.Net.Security, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic class SslStream : System.Net.Security.AuthenticatedStream\n{\n protected override void Dispose(bool disposing) => throw null;\n public override System.IAsyncResult BeginRead(System.Byte[] buffer, int offset, int count, System.AsyncCallback asyncCallback, object asyncState) => throw null;\n public override System.IAsyncResult BeginWrite(System.Byte[] buffer, int offset, int count, System.AsyncCallback asyncCallback, object asyncState) => throw null;\n public override System.Int64 Length { get => throw null; }\n public override System.Int64 Position { get => throw null; set => throw null; }\n public override System.Int64 Seek(System.Int64 offset, System.IO.SeekOrigin origin) => throw null;\n public override System.Threading.Tasks.Task FlushAsync(System.Threading.CancellationToken cancellationToken) => throw null;\n public override System.Threading.Tasks.Task WriteAsync(System.Byte[] buffer, int offset, int count, System.Threading.CancellationToken cancellationToken) => throw null;\n public override System.Threading.Tasks.Task ReadAsync(System.Byte[] buffer, int offset, int count, System.Threading.CancellationToken cancellationToken) => throw null;\n public override System.Threading.Tasks.ValueTask DisposeAsync() => throw null;\n public override System.Threading.Tasks.ValueTask WriteAsync(System.ReadOnlyMemory buffer, System.Threading.CancellationToken cancellationToken) => throw null;\n public override System.Threading.Tasks.ValueTask ReadAsync(System.Memory buffer, System.Threading.CancellationToken cancellationToken) => throw null;\n public override bool CanRead { get => throw null; }\n public override bool CanSeek { get => throw null; }\n public override bool CanTimeout { get => throw null; }\n public override bool CanWrite { get => throw null; }\n public override int EndRead(System.IAsyncResult asyncResult) => throw null;\n public override int Read(System.Byte[] buffer, int offset, int count) => throw null;\n public override int ReadByte() => throw null;\n public override int ReadTimeout { get => throw null; set => throw null; }\n public override int WriteTimeout { get => throw null; set => throw null; }\n public override void EndWrite(System.IAsyncResult asyncResult) => throw null;\n public override void Flush() => throw null;\n public override void SetLength(System.Int64 value) => throw null;\n public override void Write(System.Byte[] buffer, int offset, int count) => throw null;\n}\n\n// Generated from `System.Net.Security.TlsCipherSuite` in `System.Net.Security, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic enum TlsCipherSuite\n{\n}\n\n}\n}\nnamespace Runtime\n{\nnamespace Serialization\n{\n// Generated from `System.Runtime.Serialization.DataContractAttribute` in `System.Runtime.Serialization.Primitives, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic class DataContractAttribute : System.Attribute\n{\n public DataContractAttribute() => throw null;\n}\n\n// Generated from `System.Runtime.Serialization.DataMemberAttribute` in `System.Runtime.Serialization.Primitives, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic class DataMemberAttribute : System.Attribute\n{\n public DataMemberAttribute() => throw null;\n}\n\n}\n}\nnamespace Text\n{\nnamespace RegularExpressions\n{\n// Generated from `System.Text.RegularExpressions.Capture` in `System.Text.RegularExpressions, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic class Capture\n{\n public override string ToString() => throw null;\n}\n\n// Generated from `System.Text.RegularExpressions.CollectionDebuggerProxy<>` in `System.Text.RegularExpressions, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\nclass CollectionDebuggerProxy\n{\n}\n\n// Generated from `System.Text.RegularExpressions.GroupCollection` in `System.Text.RegularExpressions, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic class GroupCollection : System.Collections.IList, System.Collections.IEnumerable, System.Collections.ICollection, System.Collections.Generic.IReadOnlyList, System.Collections.Generic.IReadOnlyDictionary, System.Collections.Generic.IReadOnlyCollection, System.Collections.Generic.IReadOnlyCollection>, System.Collections.Generic.IList, System.Collections.Generic.IEnumerable, System.Collections.Generic.IEnumerable>, System.Collections.Generic.ICollection\n{\n System.Collections.Generic.IEnumerator> System.Collections.Generic.IEnumerable>.GetEnumerator() => throw null;\n System.Collections.Generic.IEnumerator System.Collections.Generic.IEnumerable.GetEnumerator() => throw null;\n System.Text.RegularExpressions.Group this[int index] { get => throw null; set => throw null; }\n bool System.Collections.Generic.ICollection.Contains(System.Text.RegularExpressions.Group item) => throw null;\n bool System.Collections.Generic.ICollection.Remove(System.Text.RegularExpressions.Group item) => throw null;\n bool System.Collections.IList.Contains(object value) => throw null;\n bool System.Collections.IList.IsFixedSize { get => throw null; }\n int System.Collections.Generic.IList.IndexOf(System.Text.RegularExpressions.Group item) => throw null;\n int System.Collections.IList.Add(object value) => throw null;\n int System.Collections.IList.IndexOf(object value) => throw null;\n object this[int index] { get => throw null; set => throw null; }\n public System.Collections.Generic.IEnumerable Values { get => throw null; }\n public System.Collections.Generic.IEnumerable Keys { get => throw null; }\n public System.Collections.IEnumerator GetEnumerator() => throw null;\n public System.Text.RegularExpressions.Group this[string groupname] { get => throw null; }\n public bool ContainsKey(string key) => throw null;\n public bool IsReadOnly { get => throw null; }\n public bool IsSynchronized { get => throw null; }\n public bool TryGetValue(string key, out System.Text.RegularExpressions.Group value) => throw null;\n public int Count { get => throw null; }\n public object SyncRoot { get => throw null; }\n public void CopyTo(System.Array array, int arrayIndex) => throw null;\n public void CopyTo(System.Text.RegularExpressions.Group[] array, int arrayIndex) => throw null;\n void System.Collections.Generic.ICollection.Add(System.Text.RegularExpressions.Group item) => throw null;\n void System.Collections.Generic.ICollection.Clear() => throw null;\n void System.Collections.Generic.IList.Insert(int index, System.Text.RegularExpressions.Group item) => throw null;\n void System.Collections.Generic.IList.RemoveAt(int index) => throw null;\n void System.Collections.IList.Clear() => throw null;\n void System.Collections.IList.Insert(int index, object value) => throw null;\n void System.Collections.IList.Remove(object value) => throw null;\n void System.Collections.IList.RemoveAt(int index) => throw null;\n}\n\n// Generated from `System.Text.RegularExpressions.Group` in `System.Text.RegularExpressions, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic class Group : System.Text.RegularExpressions.Capture\n{\n}\n\n// Generated from `System.Text.RegularExpressions.Match` in `System.Text.RegularExpressions, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic class Match : System.Text.RegularExpressions.Group\n{\n}\n\n// Generated from `System.Text.RegularExpressions.RegexOptions` in `System.Text.RegularExpressions, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\n[System.Flags]\npublic enum RegexOptions\n{\n IgnoreCase,\n}\n\n// Generated from `System.Text.RegularExpressions.Regex` in `System.Text.RegularExpressions, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic class Regex : System.Runtime.Serialization.ISerializable\n{\n public Regex(string pattern) => throw null;\n public Regex(string pattern, System.Text.RegularExpressions.RegexOptions options, System.TimeSpan matchTimeout) => throw null;\n public System.Text.RegularExpressions.Match Match(string input) => throw null;\n public override string ToString() => throw null;\n public static System.Text.RegularExpressions.Match Match(string input, string pattern) => throw null;\n public static System.Text.RegularExpressions.Match Match(string input, string pattern, System.Text.RegularExpressions.RegexOptions options, System.TimeSpan matchTimeout) => throw null;\n public string Replace(string input, string replacement) => throw null;\n void System.Runtime.Serialization.ISerializable.GetObjectData(System.Runtime.Serialization.SerializationInfo si, System.Runtime.Serialization.StreamingContext context) => throw null;\n}\n\n}\n}\nnamespace Timers\n{\n// Generated from `System.Timers.TimersDescriptionAttribute` in `System.ComponentModel.TypeConverter, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic class TimersDescriptionAttribute\n{\n public TimersDescriptionAttribute(string description) => throw null;\n}\n\n}\nnamespace Windows\n{\nnamespace Markup\n{\n// Generated from `System.Windows.Markup.ValueSerializerAttribute` in `System.ObjectModel, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic class ValueSerializerAttribute : System.Attribute\n{\n public ValueSerializerAttribute(System.Type valueSerializerType) => throw null;\n public ValueSerializerAttribute(string valueSerializerTypeName) => throw null;\n}\n\n}\n}\n}\n | +| // This file contains auto-generated code.\n// original-extractor-options: /r:System.Text.RegularExpressions.dll /r:System.Collections.Specialized.dll /r:System.Net.dll /r:System.Web.dll /r:System.Net.HttpListener.dll /r:System.Collections.Specialized.dll /r:System.Private.Uri.dll /r:System.Runtime.Extensions.dll /r:System.Linq.Parallel.dll /r:System.Collections.Concurrent.dll /r:System.Linq.Expressions.dll /r:System.Collections.dll /r:System.Linq.Queryable.dll /r:System.Linq.dll /r:System.Collections.NonGeneric.dll /r:System.ObjectModel.dll /r:System.ComponentModel.TypeConverter.dll /r:System.IO.Compression.dll /r:System.IO.Pipes.dll /r:System.Net.Primitives.dll /r:System.Net.Security.dll /r:System.Security.Cryptography.Primitives.dll /r:System.Text.RegularExpressions.dll ${testdir}/../../resources/stubs/System.Web.cs /r:System.Runtime.Serialization.Primitives.dll\n\nnamespace System\n{\n// Generated from `System.Uri` in `System.Private.Uri, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic class Uri : System.Runtime.Serialization.ISerializable\n{\n public override bool Equals(object comparand) => throw null;\n public override int GetHashCode() => throw null;\n public override string ToString() => throw null;\n void System.Runtime.Serialization.ISerializable.GetObjectData(System.Runtime.Serialization.SerializationInfo serializationInfo, System.Runtime.Serialization.StreamingContext streamingContext) => throw null;\n}\n\nnamespace Collections\n{\n// Generated from `System.Collections.Queue` in `System.Collections.NonGeneric, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic class Queue : System.ICloneable, System.Collections.IEnumerable, System.Collections.ICollection\n{\n public virtual System.Collections.IEnumerator GetEnumerator() => throw null;\n public virtual bool IsSynchronized { get => throw null; }\n public virtual int Count { get => throw null; }\n public virtual object Clone() => throw null;\n public virtual object SyncRoot { get => throw null; }\n public virtual void CopyTo(System.Array array, int index) => throw null;\n}\n\n// Generated from `System.Collections.SortedList` in `System.Collections.NonGeneric, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic class SortedList : System.ICloneable, System.Collections.IEnumerable, System.Collections.IDictionary, System.Collections.ICollection\n{\n System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => throw null;\n public virtual System.Collections.ICollection Keys { get => throw null; }\n public virtual System.Collections.ICollection Values { get => throw null; }\n public virtual System.Collections.IDictionaryEnumerator GetEnumerator() => throw null;\n public virtual bool Contains(object key) => throw null;\n public virtual bool IsFixedSize { get => throw null; }\n public virtual bool IsReadOnly { get => throw null; }\n public virtual bool IsSynchronized { get => throw null; }\n public virtual int Count { get => throw null; }\n public virtual object Clone() => throw null;\n public virtual object GetByIndex(int index) => throw null;\n public virtual object SyncRoot { get => throw null; }\n public virtual object this[object key] { get => throw null; set => throw null; }\n public virtual void Add(object key, object value) => throw null;\n public virtual void Clear() => throw null;\n public virtual void CopyTo(System.Array array, int arrayIndex) => throw null;\n public virtual void Remove(object key) => throw null;\n}\n\n// Generated from `System.Collections.Stack` in `System.Collections.NonGeneric, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic class Stack : System.ICloneable, System.Collections.IEnumerable, System.Collections.ICollection\n{\n public virtual System.Collections.IEnumerator GetEnumerator() => throw null;\n public virtual bool IsSynchronized { get => throw null; }\n public virtual int Count { get => throw null; }\n public virtual object Clone() => throw null;\n public virtual object SyncRoot { get => throw null; }\n public virtual void CopyTo(System.Array array, int index) => throw null;\n}\n\nnamespace Concurrent\n{\n// Generated from `System.Collections.Concurrent.BlockingCollection<>` in `System.Collections.Concurrent, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic class BlockingCollection : System.IDisposable, System.Collections.IEnumerable, System.Collections.ICollection, System.Collections.Generic.IReadOnlyCollection, System.Collections.Generic.IEnumerable\n{\n System.Collections.Generic.IEnumerator System.Collections.Generic.IEnumerable.GetEnumerator() => throw null;\n System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => throw null;\n bool System.Collections.ICollection.IsSynchronized { get => throw null; }\n object System.Collections.ICollection.SyncRoot { get => throw null; }\n public int Count { get => throw null; }\n public void Dispose() => throw null;\n void System.Collections.ICollection.CopyTo(System.Array array, int index) => throw null;\n}\n\n// Generated from `System.Collections.Concurrent.BlockingCollectionDebugView<>` in `System.Collections.Concurrent, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\nclass BlockingCollectionDebugView\n{\n}\n\n// Generated from `System.Collections.Concurrent.IDictionaryDebugView<,>` in `System.Collections.Concurrent, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\nclass IDictionaryDebugView\n{\n}\n\n}\nnamespace Generic\n{\n// Generated from `System.Collections.Generic.CollectionDebugView<>` in `System.ObjectModel, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\nclass CollectionDebugView\n{\n}\n\n// Generated from `System.Collections.Generic.DictionaryDebugView<,>` in `System.ObjectModel, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\nclass DictionaryDebugView\n{\n}\n\n// Generated from `System.Collections.Generic.QueueDebugView<>` in `System.Collections, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\nclass QueueDebugView\n{\n}\n\n// Generated from `System.Collections.Generic.SortedSet<>` in `System.Collections, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic class SortedSet : System.Runtime.Serialization.ISerializable, System.Runtime.Serialization.IDeserializationCallback, System.Collections.IEnumerable, System.Collections.ICollection, System.Collections.Generic.ISet, System.Collections.Generic.IReadOnlySet, System.Collections.Generic.IReadOnlyCollection, System.Collections.Generic.IEnumerable, System.Collections.Generic.ICollection\n{\n System.Collections.Generic.IEnumerator System.Collections.Generic.IEnumerable.GetEnumerator() => throw null;\n System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => throw null;\n bool System.Collections.Generic.ICollection.IsReadOnly { get => throw null; }\n bool System.Collections.ICollection.IsSynchronized { get => throw null; }\n object System.Collections.ICollection.SyncRoot { get => throw null; }\n public bool Add(T item) => throw null;\n public bool IsProperSubsetOf(System.Collections.Generic.IEnumerable other) => throw null;\n public bool IsProperSupersetOf(System.Collections.Generic.IEnumerable other) => throw null;\n public bool IsSubsetOf(System.Collections.Generic.IEnumerable other) => throw null;\n public bool IsSupersetOf(System.Collections.Generic.IEnumerable other) => throw null;\n public bool Overlaps(System.Collections.Generic.IEnumerable other) => throw null;\n public bool Remove(T item) => throw null;\n public bool SetEquals(System.Collections.Generic.IEnumerable other) => throw null;\n public int Count { get => throw null; }\n public virtual bool Contains(T item) => throw null;\n public virtual void Clear() => throw null;\n public virtual void IntersectWith(System.Collections.Generic.IEnumerable other) => throw null;\n public void CopyTo(T[] array, int index) => throw null;\n public void ExceptWith(System.Collections.Generic.IEnumerable other) => throw null;\n public void SymmetricExceptWith(System.Collections.Generic.IEnumerable other) => throw null;\n public void UnionWith(System.Collections.Generic.IEnumerable other) => throw null;\n void System.Collections.Generic.ICollection.Add(T item) => throw null;\n void System.Collections.ICollection.CopyTo(System.Array array, int index) => throw null;\n void System.Runtime.Serialization.IDeserializationCallback.OnDeserialization(object sender) => throw null;\n void System.Runtime.Serialization.ISerializable.GetObjectData(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) => throw null;\n}\n\n// Generated from `System.Collections.Generic.Stack<>` in `System.Collections, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic class Stack : System.Collections.IEnumerable, System.Collections.ICollection, System.Collections.Generic.IReadOnlyCollection, System.Collections.Generic.IEnumerable\n{\n System.Collections.Generic.IEnumerator System.Collections.Generic.IEnumerable.GetEnumerator() => throw null;\n System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => throw null;\n bool System.Collections.ICollection.IsSynchronized { get => throw null; }\n object System.Collections.ICollection.SyncRoot { get => throw null; }\n public T Peek() => throw null;\n public int Count { get => throw null; }\n void System.Collections.ICollection.CopyTo(System.Array array, int arrayIndex) => throw null;\n}\n\n// Generated from `System.Collections.Generic.StackDebugView<>` in `System.Collections, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\nclass StackDebugView\n{\n}\n\n}\nnamespace Specialized\n{\n// Generated from `System.Collections.Specialized.NameObjectCollectionBase` in `System.Collections.Specialized, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\nabstract public class NameObjectCollectionBase : System.Runtime.Serialization.ISerializable, System.Runtime.Serialization.IDeserializationCallback, System.Collections.IEnumerable, System.Collections.ICollection\n{\n bool System.Collections.ICollection.IsSynchronized { get => throw null; }\n object System.Collections.ICollection.SyncRoot { get => throw null; }\n public virtual System.Collections.IEnumerator GetEnumerator() => throw null;\n public virtual int Count { get => throw null; }\n public virtual void GetObjectData(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) => throw null;\n public virtual void OnDeserialization(object sender) => throw null;\n void System.Collections.ICollection.CopyTo(System.Array array, int index) => throw null;\n}\n\n// Generated from `System.Collections.Specialized.NameValueCollection` in `System.Collections.Specialized, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic class NameValueCollection : System.Collections.Specialized.NameObjectCollectionBase\n{\n public string this[string name] { get => throw null; set => throw null; }\n}\n\n}\n}\nnamespace ComponentModel\n{\n// Generated from `System.ComponentModel.ComponentConverter` in `System.ComponentModel.TypeConverter, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic class ComponentConverter : System.ComponentModel.ReferenceConverter\n{\n}\n\n// Generated from `System.ComponentModel.DefaultEventAttribute` in `System.ComponentModel.TypeConverter, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic class DefaultEventAttribute : System.Attribute\n{\n public DefaultEventAttribute(string name) => throw null;\n public override bool Equals(object obj) => throw null;\n public override int GetHashCode() => throw null;\n}\n\n// Generated from `System.ComponentModel.DefaultPropertyAttribute` in `System.ComponentModel.TypeConverter, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic class DefaultPropertyAttribute : System.Attribute\n{\n public DefaultPropertyAttribute(string name) => throw null;\n public override bool Equals(object obj) => throw null;\n public override int GetHashCode() => throw null;\n}\n\n// Generated from `System.ComponentModel.INotifyPropertyChanged` in `System.ObjectModel, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic interface INotifyPropertyChanged\n{\n}\n\n// Generated from `System.ComponentModel.ReferenceConverter` in `System.ComponentModel.TypeConverter, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic class ReferenceConverter : System.ComponentModel.TypeConverter\n{\n}\n\n// Generated from `System.ComponentModel.TypeConverterAttribute` in `System.ObjectModel, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic class TypeConverterAttribute : System.Attribute\n{\n public TypeConverterAttribute() => throw null;\n public TypeConverterAttribute(System.Type type) => throw null;\n public TypeConverterAttribute(string typeName) => throw null;\n public override bool Equals(object obj) => throw null;\n public override int GetHashCode() => throw null;\n}\n\n// Generated from `System.ComponentModel.TypeConverter` in `System.ComponentModel.TypeConverter, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic class TypeConverter\n{\n}\n\n// Generated from `System.ComponentModel.TypeDescriptionProviderAttribute` in `System.ObjectModel, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic class TypeDescriptionProviderAttribute : System.Attribute\n{\n public TypeDescriptionProviderAttribute(System.Type type) => throw null;\n public TypeDescriptionProviderAttribute(string typeName) => throw null;\n}\n\n// Generated from `System.ComponentModel.TypeDescriptionProvider` in `System.ComponentModel.TypeConverter, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\nabstract public class TypeDescriptionProvider\n{\n}\n\n// Generated from `System.ComponentModel.TypeDescriptor` in `System.ComponentModel.TypeConverter, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic class TypeDescriptor\n{\n}\n\nnamespace Design\n{\n// Generated from `System.ComponentModel.Design.DesignerOptionService` in `System.ComponentModel.TypeConverter, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\nabstract public class DesignerOptionService : System.ComponentModel.Design.IDesignerOptionService\n{\n}\n\n// Generated from `System.ComponentModel.Design.IDesignerOptionService` in `System.ComponentModel.TypeConverter, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic interface IDesignerOptionService\n{\n}\n\n}\n}\nnamespace Dynamic\n{\n// Generated from `System.Dynamic.DynamicMetaObject` in `System.Linq.Expressions, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic class DynamicMetaObject\n{\n}\n\n// Generated from `System.Dynamic.ExpandoObject` in `System.Linq.Expressions, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic class ExpandoObject : System.Dynamic.IDynamicMetaObjectProvider, System.ComponentModel.INotifyPropertyChanged, System.Collections.IEnumerable, System.Collections.Generic.IEnumerable>, System.Collections.Generic.IDictionary, System.Collections.Generic.ICollection>\n{\n System.Collections.Generic.ICollection System.Collections.Generic.IDictionary.Values { get => throw null; }\n System.Collections.Generic.ICollection System.Collections.Generic.IDictionary.Keys { get => throw null; }\n System.Collections.Generic.IEnumerator> System.Collections.Generic.IEnumerable>.GetEnumerator() => throw null;\n System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => throw null;\n bool System.Collections.Generic.ICollection>.Contains(System.Collections.Generic.KeyValuePair item) => throw null;\n bool System.Collections.Generic.ICollection>.IsReadOnly { get => throw null; }\n bool System.Collections.Generic.ICollection>.Remove(System.Collections.Generic.KeyValuePair item) => throw null;\n bool System.Collections.Generic.IDictionary.ContainsKey(string key) => throw null;\n bool System.Collections.Generic.IDictionary.Remove(string key) => throw null;\n bool System.Collections.Generic.IDictionary.TryGetValue(string key, out object value) => throw null;\n int System.Collections.Generic.ICollection>.Count { get => throw null; }\n object this[string key] { get => throw null; set => throw null; }\n void System.Collections.Generic.ICollection>.Add(System.Collections.Generic.KeyValuePair item) => throw null;\n void System.Collections.Generic.ICollection>.Clear() => throw null;\n void System.Collections.Generic.ICollection>.CopyTo(System.Collections.Generic.KeyValuePair[] array, int arrayIndex) => throw null;\n void System.Collections.Generic.IDictionary.Add(string key, object value) => throw null;\n}\n\n// Generated from `System.Dynamic.IDynamicMetaObjectProvider` in `System.Linq.Expressions, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic interface IDynamicMetaObjectProvider\n{\n}\n\nnamespace Utils\n{\n// Generated from `System.Dynamic.Utils.ListProvider<>` in `System.Linq.Expressions, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\nabstract class ListProvider : System.Collections.IEnumerable, System.Collections.Generic.IList, System.Collections.Generic.IEnumerable, System.Collections.Generic.ICollection where T: class\n{\n System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => throw null;\n public System.Collections.Generic.IEnumerator GetEnumerator() => throw null;\n public T this[int index] { get => throw null; set => throw null; }\n public bool Contains(T item) => throw null;\n public bool IsReadOnly { get => throw null; }\n public bool Remove(T item) => throw null;\n public int Count { get => throw null; }\n public int IndexOf(T item) => throw null;\n public void Add(T item) => throw null;\n public void Clear() => throw null;\n public void CopyTo(T[] array, int index) => throw null;\n public void Insert(int index, T item) => throw null;\n public void RemoveAt(int index) => throw null;\n}\n\n}\n}\nnamespace IO\n{\nnamespace Compression\n{\n// Generated from `System.IO.Compression.DeflateStream` in `System.IO.Compression, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089`\npublic class DeflateStream : System.IO.Stream\n{\n protected override void Dispose(bool disposing) => throw null;\n public override System.IAsyncResult BeginRead(System.Byte[] buffer, int offset, int count, System.AsyncCallback asyncCallback, object asyncState) => throw null;\n public override System.IAsyncResult BeginWrite(System.Byte[] array, int offset, int count, System.AsyncCallback asyncCallback, object asyncState) => throw null;\n public override System.Int64 Length { get => throw null; }\n public override System.Int64 Position { get => throw null; set => throw null; }\n public override System.Int64 Seek(System.Int64 offset, System.IO.SeekOrigin origin) => throw null;\n public override System.Threading.Tasks.Task CopyToAsync(System.IO.Stream destination, int bufferSize, System.Threading.CancellationToken cancellationToken) => throw null;\n public override System.Threading.Tasks.Task FlushAsync(System.Threading.CancellationToken cancellationToken) => throw null;\n public override System.Threading.Tasks.Task WriteAsync(System.Byte[] array, int offset, int count, System.Threading.CancellationToken cancellationToken) => throw null;\n public override System.Threading.Tasks.Task ReadAsync(System.Byte[] array, int offset, int count, System.Threading.CancellationToken cancellationToken) => throw null;\n public override System.Threading.Tasks.ValueTask DisposeAsync() => throw null;\n public override System.Threading.Tasks.ValueTask WriteAsync(System.ReadOnlyMemory buffer, System.Threading.CancellationToken cancellationToken) => throw null;\n public override System.Threading.Tasks.ValueTask ReadAsync(System.Memory buffer, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) => throw null;\n public override bool CanRead { get => throw null; }\n public override bool CanSeek { get => throw null; }\n public override bool CanWrite { get => throw null; }\n public override int EndRead(System.IAsyncResult asyncResult) => throw null;\n public override int Read(System.Byte[] array, int offset, int count) => throw null;\n public override int Read(System.Span buffer) => throw null;\n public override int ReadByte() => throw null;\n public override void CopyTo(System.IO.Stream destination, int bufferSize) => throw null;\n public override void EndWrite(System.IAsyncResult asyncResult) => throw null;\n public override void Flush() => throw null;\n public override void SetLength(System.Int64 value) => throw null;\n public override void Write(System.Byte[] array, int offset, int count) => throw null;\n public override void Write(System.ReadOnlySpan buffer) => throw null;\n}\n\n}\n}\nnamespace Linq\n{\n// Generated from `System.Linq.Enumerable` in `System.Linq, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\nstatic public class Enumerable\n{\n public static System.Collections.Generic.IEnumerable Select(this System.Collections.Generic.IEnumerable source, System.Func selector) => throw null;\n}\n\n// Generated from `System.Linq.Grouping<,>` in `System.Linq, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic class Grouping : System.Linq.IGrouping, System.Collections.IEnumerable, System.Collections.Generic.IList, System.Collections.Generic.IEnumerable, System.Collections.Generic.ICollection\n{\n System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => throw null;\n TElement this[int index] { get => throw null; set => throw null; }\n bool System.Collections.Generic.ICollection.Contains(TElement item) => throw null;\n bool System.Collections.Generic.ICollection.IsReadOnly { get => throw null; }\n bool System.Collections.Generic.ICollection.Remove(TElement item) => throw null;\n int System.Collections.Generic.ICollection.Count { get => throw null; }\n int System.Collections.Generic.IList.IndexOf(TElement item) => throw null;\n public System.Collections.Generic.IEnumerator GetEnumerator() => throw null;\n void System.Collections.Generic.ICollection.Add(TElement item) => throw null;\n void System.Collections.Generic.ICollection.Clear() => throw null;\n void System.Collections.Generic.ICollection.CopyTo(TElement[] array, int arrayIndex) => throw null;\n void System.Collections.Generic.IList.Insert(int index, TElement item) => throw null;\n void System.Collections.Generic.IList.RemoveAt(int index) => throw null;\n}\n\n// Generated from `System.Linq.IGrouping<,>` in `System.Linq, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic interface IGrouping : System.Collections.IEnumerable, System.Collections.Generic.IEnumerable\n{\n}\n\n// Generated from `System.Linq.IIListProvider<>` in `System.Linq, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\ninterface IIListProvider : System.Collections.IEnumerable, System.Collections.Generic.IEnumerable\n{\n}\n\n// Generated from `System.Linq.ILookup<,>` in `System.Linq, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic interface ILookup : System.Collections.IEnumerable, System.Collections.Generic.IEnumerable>\n{\n}\n\n// Generated from `System.Linq.IOrderedEnumerable<>` in `System.Linq, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic interface IOrderedEnumerable : System.Collections.IEnumerable, System.Collections.Generic.IEnumerable\n{\n}\n\n// Generated from `System.Linq.IPartition<>` in `System.Linq, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\ninterface IPartition : System.Linq.IIListProvider, System.Collections.IEnumerable, System.Collections.Generic.IEnumerable\n{\n}\n\n// Generated from `System.Linq.IQueryable` in `System.Linq.Expressions, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic interface IQueryable : System.Collections.IEnumerable\n{\n}\n\n// Generated from `System.Linq.Lookup<,>` in `System.Linq, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic class Lookup : System.Linq.ILookup, System.Linq.IIListProvider>, System.Collections.IEnumerable, System.Collections.Generic.IEnumerable>\n{\n System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => throw null;\n public System.Collections.Generic.IEnumerator> GetEnumerator() => throw null;\n}\n\n// Generated from `System.Linq.OrderedEnumerable<>` in `System.Linq, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\nabstract class OrderedEnumerable : System.Linq.IPartition, System.Linq.IOrderedEnumerable, System.Linq.IIListProvider, System.Collections.IEnumerable, System.Collections.Generic.IEnumerable\n{\n System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => throw null;\n public System.Collections.Generic.IEnumerator GetEnumerator() => throw null;\n}\n\n// Generated from `System.Linq.ParallelEnumerable` in `System.Linq.Parallel, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\nstatic public class ParallelEnumerable\n{\n public static System.Linq.ParallelQuery AsParallel(this System.Collections.IEnumerable source) => throw null;\n}\n\n// Generated from `System.Linq.ParallelQuery<>` in `System.Linq.Parallel, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic class ParallelQuery : System.Linq.ParallelQuery, System.Collections.IEnumerable, System.Collections.Generic.IEnumerable\n{\n public virtual System.Collections.Generic.IEnumerator GetEnumerator() => throw null;\n}\n\n// Generated from `System.Linq.ParallelQuery` in `System.Linq.Parallel, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic class ParallelQuery : System.Collections.IEnumerable\n{\n System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => throw null;\n}\n\n// Generated from `System.Linq.Queryable` in `System.Linq.Queryable, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\nstatic public class Queryable\n{\n public static System.Linq.IQueryable AsQueryable(this System.Collections.IEnumerable source) => throw null;\n}\n\n// Generated from `System.Linq.SystemLinq_GroupingDebugView<,>` in `System.Linq, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\nclass SystemLinq_GroupingDebugView\n{\n}\n\n// Generated from `System.Linq.SystemLinq_LookupDebugView<,>` in `System.Linq, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\nclass SystemLinq_LookupDebugView\n{\n}\n\nnamespace Expressions\n{\n// Generated from `System.Linq.Expressions.BlockExpressionList` in `System.Linq.Expressions, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\nclass BlockExpressionList : System.Collections.IEnumerable, System.Collections.Generic.IList, System.Collections.Generic.IEnumerable, System.Collections.Generic.ICollection\n{\n System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => throw null;\n public System.Collections.Generic.IEnumerator GetEnumerator() => throw null;\n public System.Linq.Expressions.Expression this[int index] { get => throw null; set => throw null; }\n public bool Contains(System.Linq.Expressions.Expression item) => throw null;\n public bool IsReadOnly { get => throw null; }\n public bool Remove(System.Linq.Expressions.Expression item) => throw null;\n public int Count { get => throw null; }\n public int IndexOf(System.Linq.Expressions.Expression item) => throw null;\n public void Add(System.Linq.Expressions.Expression item) => throw null;\n public void Clear() => throw null;\n public void CopyTo(System.Linq.Expressions.Expression[] array, int index) => throw null;\n public void Insert(int index, System.Linq.Expressions.Expression item) => throw null;\n public void RemoveAt(int index) => throw null;\n}\n\n// Generated from `System.Linq.Expressions.Expression` in `System.Linq.Expressions, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\nabstract public class Expression\n{\n public override string ToString() => throw null;\n}\n\n// Generated from `System.Linq.Expressions.ParameterExpression` in `System.Linq.Expressions, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic class ParameterExpression : System.Linq.Expressions.Expression\n{\n}\n\nnamespace Compiler\n{\n// Generated from `System.Linq.Expressions.Compiler.ParameterList` in `System.Linq.Expressions, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\nclass ParameterList : System.Collections.IEnumerable, System.Collections.Generic.IReadOnlyList, System.Collections.Generic.IReadOnlyCollection, System.Collections.Generic.IEnumerable\n{\n System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => throw null;\n public System.Collections.Generic.IEnumerator GetEnumerator() => throw null;\n public System.Linq.Expressions.ParameterExpression this[int index] { get => throw null; }\n public int Count { get => throw null; }\n}\n\n}\nnamespace Interpreter\n{\n// Generated from `System.Linq.Expressions.Interpreter.InstructionArray` in `System.Linq.Expressions, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\nstruct InstructionArray\n{\n}\n\n// Generated from `System.Linq.Expressions.Interpreter.InstructionList` in `System.Linq.Expressions, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\nclass InstructionList\n{\n}\n\n// Generated from `System.Linq.Expressions.Interpreter.InterpretedFrameInfo` in `System.Linq.Expressions, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\nstruct InterpretedFrameInfo\n{\n public override string ToString() => throw null;\n}\n\n// Generated from `System.Linq.Expressions.Interpreter.InterpretedFrame` in `System.Linq.Expressions, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\nclass InterpretedFrame\n{\n}\n\n}\n}\nnamespace Parallel\n{\n// Generated from `System.Linq.Parallel.ListChunk<>` in `System.Linq.Parallel, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\nclass ListChunk : System.Collections.IEnumerable, System.Collections.Generic.IEnumerable\n{\n System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => throw null;\n public System.Collections.Generic.IEnumerator GetEnumerator() => throw null;\n}\n\n// Generated from `System.Linq.Parallel.Lookup<,>` in `System.Linq.Parallel, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\nclass Lookup : System.Linq.ILookup, System.Collections.IEnumerable, System.Collections.Generic.IEnumerable>\n{\n System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => throw null;\n public System.Collections.Generic.IEnumerator> GetEnumerator() => throw null;\n}\n\n// Generated from `System.Linq.Parallel.PartitionerQueryOperator<>` in `System.Linq.Parallel, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\nclass PartitionerQueryOperator : System.Linq.Parallel.QueryOperator\n{\n}\n\n// Generated from `System.Linq.Parallel.QueryOperator<>` in `System.Linq.Parallel, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\nabstract class QueryOperator : System.Linq.ParallelQuery\n{\n public override System.Collections.Generic.IEnumerator GetEnumerator() => throw null;\n}\n\n// Generated from `System.Linq.Parallel.QueryResults<>` in `System.Linq.Parallel, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\nabstract class QueryResults : System.Collections.IEnumerable, System.Collections.Generic.IList, System.Collections.Generic.IEnumerable, System.Collections.Generic.ICollection\n{\n System.Collections.Generic.IEnumerator System.Collections.Generic.IEnumerable.GetEnumerator() => throw null;\n System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => throw null;\n bool System.Collections.Generic.ICollection.Contains(T item) => throw null;\n bool System.Collections.Generic.ICollection.IsReadOnly { get => throw null; }\n bool System.Collections.Generic.ICollection.Remove(T item) => throw null;\n int System.Collections.Generic.IList.IndexOf(T item) => throw null;\n public T this[int index] { get => throw null; set => throw null; }\n public int Count { get => throw null; }\n void System.Collections.Generic.ICollection.Add(T item) => throw null;\n void System.Collections.Generic.ICollection.Clear() => throw null;\n void System.Collections.Generic.ICollection.CopyTo(T[] array, int arrayIndex) => throw null;\n void System.Collections.Generic.IList.Insert(int index, T item) => throw null;\n void System.Collections.Generic.IList.RemoveAt(int index) => throw null;\n}\n\n// Generated from `System.Linq.Parallel.ZipQueryOperator<,,>` in `System.Linq.Parallel, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\nclass ZipQueryOperator : System.Linq.Parallel.QueryOperator\n{\n}\n\n}\n}\nnamespace Net\n{\n// Generated from `System.Net.CookieCollection` in `System.Net.Primitives, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic class CookieCollection : System.Collections.IEnumerable, System.Collections.ICollection, System.Collections.Generic.IReadOnlyCollection, System.Collections.Generic.IEnumerable, System.Collections.Generic.ICollection\n{\n System.Collections.Generic.IEnumerator System.Collections.Generic.IEnumerable.GetEnumerator() => throw null;\n public System.Collections.IEnumerator GetEnumerator() => throw null;\n public bool Contains(System.Net.Cookie cookie) => throw null;\n public bool IsReadOnly { get => throw null; }\n public bool IsSynchronized { get => throw null; }\n public bool Remove(System.Net.Cookie cookie) => throw null;\n public int Count { get => throw null; }\n public object SyncRoot { get => throw null; }\n public void Add(System.Net.Cookie cookie) => throw null;\n public void Clear() => throw null;\n public void CopyTo(System.Array array, int index) => throw null;\n public void CopyTo(System.Net.Cookie[] array, int index) => throw null;\n}\n\n// Generated from `System.Net.Cookie` in `System.Net.Primitives, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic class Cookie\n{\n public override bool Equals(object comparand) => throw null;\n public override int GetHashCode() => throw null;\n public override string ToString() => throw null;\n}\n\n// Generated from `System.Net.StreamFramer` in `System.Net.Security, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\nclass StreamFramer\n{\n}\n\nnamespace Security\n{\n// Generated from `System.Net.Security.AuthenticatedStream` in `System.Net.Security, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\nabstract public class AuthenticatedStream : System.IO.Stream\n{\n protected override void Dispose(bool disposing) => throw null;\n public override System.Threading.Tasks.ValueTask DisposeAsync() => throw null;\n}\n\n// Generated from `System.Net.Security.CipherSuitesPolicy` in `System.Net.Security, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic class CipherSuitesPolicy\n{\n}\n\n// Generated from `System.Net.Security.NegotiateStream` in `System.Net.Security, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic class NegotiateStream : System.Net.Security.AuthenticatedStream\n{\n protected override void Dispose(bool disposing) => throw null;\n public override System.IAsyncResult BeginRead(System.Byte[] buffer, int offset, int count, System.AsyncCallback asyncCallback, object asyncState) => throw null;\n public override System.IAsyncResult BeginWrite(System.Byte[] buffer, int offset, int count, System.AsyncCallback asyncCallback, object asyncState) => throw null;\n public override System.Int64 Length { get => throw null; }\n public override System.Int64 Position { get => throw null; set => throw null; }\n public override System.Int64 Seek(System.Int64 offset, System.IO.SeekOrigin origin) => throw null;\n public override System.Threading.Tasks.Task FlushAsync(System.Threading.CancellationToken cancellationToken) => throw null;\n public override System.Threading.Tasks.Task WriteAsync(System.Byte[] buffer, int offset, int count, System.Threading.CancellationToken cancellationToken) => throw null;\n public override System.Threading.Tasks.Task ReadAsync(System.Byte[] buffer, int offset, int count, System.Threading.CancellationToken cancellationToken) => throw null;\n public override System.Threading.Tasks.ValueTask DisposeAsync() => throw null;\n public override System.Threading.Tasks.ValueTask WriteAsync(System.ReadOnlyMemory buffer, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) => throw null;\n public override System.Threading.Tasks.ValueTask ReadAsync(System.Memory buffer, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) => throw null;\n public override bool CanRead { get => throw null; }\n public override bool CanSeek { get => throw null; }\n public override bool CanTimeout { get => throw null; }\n public override bool CanWrite { get => throw null; }\n public override int EndRead(System.IAsyncResult asyncResult) => throw null;\n public override int Read(System.Byte[] buffer, int offset, int count) => throw null;\n public override int ReadTimeout { get => throw null; set => throw null; }\n public override int WriteTimeout { get => throw null; set => throw null; }\n public override void EndWrite(System.IAsyncResult asyncResult) => throw null;\n public override void Flush() => throw null;\n public override void SetLength(System.Int64 value) => throw null;\n public override void Write(System.Byte[] buffer, int offset, int count) => throw null;\n}\n\n// Generated from `System.Net.Security.SslStream` in `System.Net.Security, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic class SslStream : System.Net.Security.AuthenticatedStream\n{\n protected override void Dispose(bool disposing) => throw null;\n public override System.IAsyncResult BeginRead(System.Byte[] buffer, int offset, int count, System.AsyncCallback asyncCallback, object asyncState) => throw null;\n public override System.IAsyncResult BeginWrite(System.Byte[] buffer, int offset, int count, System.AsyncCallback asyncCallback, object asyncState) => throw null;\n public override System.Int64 Length { get => throw null; }\n public override System.Int64 Position { get => throw null; set => throw null; }\n public override System.Int64 Seek(System.Int64 offset, System.IO.SeekOrigin origin) => throw null;\n public override System.Threading.Tasks.Task FlushAsync(System.Threading.CancellationToken cancellationToken) => throw null;\n public override System.Threading.Tasks.Task WriteAsync(System.Byte[] buffer, int offset, int count, System.Threading.CancellationToken cancellationToken) => throw null;\n public override System.Threading.Tasks.Task ReadAsync(System.Byte[] buffer, int offset, int count, System.Threading.CancellationToken cancellationToken) => throw null;\n public override System.Threading.Tasks.ValueTask DisposeAsync() => throw null;\n public override System.Threading.Tasks.ValueTask WriteAsync(System.ReadOnlyMemory buffer, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) => throw null;\n public override System.Threading.Tasks.ValueTask ReadAsync(System.Memory buffer, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) => throw null;\n public override bool CanRead { get => throw null; }\n public override bool CanSeek { get => throw null; }\n public override bool CanTimeout { get => throw null; }\n public override bool CanWrite { get => throw null; }\n public override int EndRead(System.IAsyncResult asyncResult) => throw null;\n public override int Read(System.Byte[] buffer, int offset, int count) => throw null;\n public override int ReadByte() => throw null;\n public override int ReadTimeout { get => throw null; set => throw null; }\n public override int WriteTimeout { get => throw null; set => throw null; }\n public override void EndWrite(System.IAsyncResult asyncResult) => throw null;\n public override void Flush() => throw null;\n public override void SetLength(System.Int64 value) => throw null;\n public override void Write(System.Byte[] buffer, int offset, int count) => throw null;\n}\n\n// Generated from `System.Net.Security.TlsCipherSuite` in `System.Net.Security, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic enum TlsCipherSuite\n{\n}\n\n// Generated from `System.Net.Security.TlsFrameHelper` in `System.Net.Security, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\nclass TlsFrameHelper\n{\n}\n\n}\n}\nnamespace Runtime\n{\nnamespace Serialization\n{\n// Generated from `System.Runtime.Serialization.DataContractAttribute` in `System.Runtime.Serialization.Primitives, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic class DataContractAttribute : System.Attribute\n{\n public DataContractAttribute() => throw null;\n}\n\n// Generated from `System.Runtime.Serialization.DataMemberAttribute` in `System.Runtime.Serialization.Primitives, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic class DataMemberAttribute : System.Attribute\n{\n public DataMemberAttribute() => throw null;\n}\n\n}\n}\nnamespace Text\n{\nnamespace RegularExpressions\n{\n// Generated from `System.Text.RegularExpressions.Capture` in `System.Text.RegularExpressions, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic class Capture\n{\n public override string ToString() => throw null;\n}\n\n// Generated from `System.Text.RegularExpressions.CollectionDebuggerProxy<>` in `System.Text.RegularExpressions, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\nclass CollectionDebuggerProxy\n{\n}\n\n// Generated from `System.Text.RegularExpressions.GroupCollection` in `System.Text.RegularExpressions, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic class GroupCollection : System.Collections.IList, System.Collections.IEnumerable, System.Collections.ICollection, System.Collections.Generic.IReadOnlyList, System.Collections.Generic.IReadOnlyDictionary, System.Collections.Generic.IReadOnlyCollection, System.Collections.Generic.IReadOnlyCollection>, System.Collections.Generic.IList, System.Collections.Generic.IEnumerable, System.Collections.Generic.IEnumerable>, System.Collections.Generic.ICollection\n{\n System.Collections.Generic.IEnumerator> System.Collections.Generic.IEnumerable>.GetEnumerator() => throw null;\n System.Collections.Generic.IEnumerator System.Collections.Generic.IEnumerable.GetEnumerator() => throw null;\n System.Text.RegularExpressions.Group this[int index] { get => throw null; set => throw null; }\n bool System.Collections.Generic.ICollection.Contains(System.Text.RegularExpressions.Group item) => throw null;\n bool System.Collections.Generic.ICollection.Remove(System.Text.RegularExpressions.Group item) => throw null;\n bool System.Collections.IList.Contains(object value) => throw null;\n bool System.Collections.IList.IsFixedSize { get => throw null; }\n int System.Collections.Generic.IList.IndexOf(System.Text.RegularExpressions.Group item) => throw null;\n int System.Collections.IList.Add(object value) => throw null;\n int System.Collections.IList.IndexOf(object value) => throw null;\n object this[int index] { get => throw null; set => throw null; }\n public System.Collections.Generic.IEnumerable Values { get => throw null; }\n public System.Collections.Generic.IEnumerable Keys { get => throw null; }\n public System.Collections.IEnumerator GetEnumerator() => throw null;\n public System.Text.RegularExpressions.Group this[string groupname] { get => throw null; }\n public bool ContainsKey(string key) => throw null;\n public bool IsReadOnly { get => throw null; }\n public bool IsSynchronized { get => throw null; }\n public bool TryGetValue(string key, out System.Text.RegularExpressions.Group value) => throw null;\n public int Count { get => throw null; }\n public object SyncRoot { get => throw null; }\n public void CopyTo(System.Array array, int arrayIndex) => throw null;\n public void CopyTo(System.Text.RegularExpressions.Group[] array, int arrayIndex) => throw null;\n void System.Collections.Generic.ICollection.Add(System.Text.RegularExpressions.Group item) => throw null;\n void System.Collections.Generic.ICollection.Clear() => throw null;\n void System.Collections.Generic.IList.Insert(int index, System.Text.RegularExpressions.Group item) => throw null;\n void System.Collections.Generic.IList.RemoveAt(int index) => throw null;\n void System.Collections.IList.Clear() => throw null;\n void System.Collections.IList.Insert(int index, object value) => throw null;\n void System.Collections.IList.Remove(object value) => throw null;\n void System.Collections.IList.RemoveAt(int index) => throw null;\n}\n\n// Generated from `System.Text.RegularExpressions.Group` in `System.Text.RegularExpressions, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic class Group : System.Text.RegularExpressions.Capture\n{\n}\n\n// Generated from `System.Text.RegularExpressions.Match` in `System.Text.RegularExpressions, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic class Match : System.Text.RegularExpressions.Group\n{\n}\n\n// Generated from `System.Text.RegularExpressions.RegexOptions` in `System.Text.RegularExpressions, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\n[System.Flags]\npublic enum RegexOptions\n{\n IgnoreCase,\n}\n\n// Generated from `System.Text.RegularExpressions.Regex` in `System.Text.RegularExpressions, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic class Regex : System.Runtime.Serialization.ISerializable\n{\n public Regex(string pattern) => throw null;\n public Regex(string pattern, System.Text.RegularExpressions.RegexOptions options, System.TimeSpan matchTimeout) => throw null;\n public System.Text.RegularExpressions.Match Match(string input) => throw null;\n public override string ToString() => throw null;\n public static System.Text.RegularExpressions.Match Match(string input, string pattern) => throw null;\n public static System.Text.RegularExpressions.Match Match(string input, string pattern, System.Text.RegularExpressions.RegexOptions options, System.TimeSpan matchTimeout) => throw null;\n public string Replace(string input, string replacement) => throw null;\n void System.Runtime.Serialization.ISerializable.GetObjectData(System.Runtime.Serialization.SerializationInfo si, System.Runtime.Serialization.StreamingContext context) => throw null;\n}\n\n}\n}\nnamespace Timers\n{\n// Generated from `System.Timers.TimersDescriptionAttribute` in `System.ComponentModel.TypeConverter, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic class TimersDescriptionAttribute\n{\n public TimersDescriptionAttribute(string description) => throw null;\n}\n\n}\nnamespace Windows\n{\nnamespace Markup\n{\n// Generated from `System.Windows.Markup.ValueSerializerAttribute` in `System.ObjectModel, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`\npublic class ValueSerializerAttribute : System.Attribute\n{\n public ValueSerializerAttribute(System.Type valueSerializerType) => throw null;\n public ValueSerializerAttribute(string valueSerializerTypeName) => throw null;\n}\n\n}\n}\n}\n | diff --git a/csharp/ql/test/resources/stubs/Dapper.cs b/csharp/ql/test/resources/stubs/Dapper.cs new file mode 100644 index 00000000000..d96f1cd4ee6 --- /dev/null +++ b/csharp/ql/test/resources/stubs/Dapper.cs @@ -0,0 +1,34 @@ +// This file contains auto-generated code. +// original-extractor-options: /r:Dapper.dll /r:System.Data.SqlClient.dll ... + +namespace Dapper +{ + // Generated from `Dapper.CommandDefinition` in `Dapper, Version=2.0.0.0, Culture=neutral, PublicKeyToken=null` + public struct CommandDefinition + { + public CommandDefinition(string commandText, object parameters = null, System.Data.IDbTransaction transaction = null, int? commandTimeout = null, System.Data.CommandType? commandType = null, Dapper.CommandFlags flags = CommandFlags.Buffered, System.Threading.CancellationToken cancellationToken = default) => throw null; + } + + // Generated from `Dapper.CommandFlags` in `Dapper, Version=2.0.0.0, Culture=neutral, PublicKeyToken=null` + [System.Flags] + public enum CommandFlags + { + None = 0x0, + Buffered = 0x1, + Pipelined = 0x2, + NoCache = 0x4 + } + + // Generated from `Dapper.SqlMapper` in `Dapper, Version=2.0.0.0, Culture=neutral, PublicKeyToken=null` + static public class SqlMapper + { + public static System.Collections.Generic.IEnumerable Query(this System.Data.IDbConnection cnn, string sql, object param = null, System.Data.IDbTransaction transaction = null, bool buffered = true, int? commandTimeout = null, System.Data.CommandType? commandType = null) => throw null; + public static System.Data.IDataReader ExecuteReader(this System.Data.IDbConnection cnn, string sql, object param = null, System.Data.IDbTransaction transaction = null, int? commandTimeout = null, System.Data.CommandType? commandType = null) => throw null; + public static System.Threading.Tasks.Task> QueryAsync(this System.Data.IDbConnection cnn, string sql, object param = null, System.Data.IDbTransaction transaction = null, int? commandTimeout = null, System.Data.CommandType? commandType = null) => throw null; + public static System.Threading.Tasks.Task QueryFirstAsync(this System.Data.IDbConnection cnn, Dapper.CommandDefinition command) => throw null; + public static System.Threading.Tasks.Task QueryFirstAsync(this System.Data.IDbConnection cnn, string sql, object param = null, System.Data.IDbTransaction transaction = null, int? commandTimeout = null, System.Data.CommandType? commandType = null) => throw null; + public static System.Threading.Tasks.Task ExecuteAsync(this System.Data.IDbConnection cnn, string sql, object param = null, System.Data.IDbTransaction transaction = null, int? commandTimeout = null, System.Data.CommandType? commandType = null) => throw null; + public static object ExecuteScalar(this System.Data.IDbConnection cnn, string sql, object param = null, System.Data.IDbTransaction transaction = null, int? commandTimeout = null, System.Data.CommandType? commandType = null) => throw null; + } +} + diff --git a/docs/codeql/codeql-cli/about-ql-packs.rst b/docs/codeql/codeql-cli/about-ql-packs.rst index 200dadc173b..b3f3c13ed88 100644 --- a/docs/codeql/codeql-cli/about-ql-packs.rst +++ b/docs/codeql/codeql-cli/about-ql-packs.rst @@ -75,11 +75,11 @@ The following properties are supported in ``qlpack.yml`` files. * - ``name`` - ``org-queries`` - All packs - - The name of the QL pack defined using alphanumeric characters, hyphens, and periods. It must be unique as CodeQL cannot differentiate between QL packs with identical names. If you intend to distribute the pack, prefix the name with your (or your organization's) name followed by a hyphen. Use the pack name to specify queries to run using ``database analyze`` and to define dependencies between QL packs (see examples below).- ' + - The name of the QL pack defined using alphanumeric characters, hyphens, and periods. It must be unique as CodeQL cannot differentiate between QL packs with identical names. If you intend to distribute the pack, prefix the name with your (or your organization's) name followed by a hyphen. Use the pack name to specify queries to run using ``database analyze`` and to define dependencies between QL packs (see examples below). * - ``version`` - ``0.0.0`` - All packs - - A version number for this QL pack. This field is not currently used by any commands, but may be required by future releases of CodeQL. + - A version number for this QL pack. This must be a valid semantic version that meets the `SemVer v2.0.0 specification `__. * - ``libraryPathDependencies`` - ``codeql-javascript`` - Optional diff --git a/docs/codeql/codeql-cli/codeql-cli-reference.rst b/docs/codeql/codeql-cli/codeql-cli-reference.rst index 75513a06b54..0c53121d379 100644 --- a/docs/codeql/codeql-cli/codeql-cli-reference.rst +++ b/docs/codeql/codeql-cli/codeql-cli-reference.rst @@ -21,11 +21,3 @@ Learn more about the files you can use when running CodeQL processes and the res - :doc:`SARIF output `: CodeQL supports SARIF as an output format for sharing static analysis results. - :doc:`Exit codes `: The CodeQL CLI reports the status of each command it runs as an exit code. This exit code provides information for subsequent commands or for other tools that rely on the CodeQL CLI. - -.. _cli-commands: - -CodeQL CLI manual ------------------ - -To view detailed information about each CodeQL CLI command, -including its usage and options, add the ``--help`` flag or visit the "`CodeQL CLI manual <../manual>`__." diff --git a/docs/codeql/codeql-cli/creating-codeql-databases.rst b/docs/codeql/codeql-cli/creating-codeql-databases.rst index 73fa4fb4818..4f7212050df 100644 --- a/docs/codeql/codeql-cli/creating-codeql-databases.rst +++ b/docs/codeql/codeql-cli/creating-codeql-databases.rst @@ -168,7 +168,7 @@ build steps, you may need to explicitly define each step in the command line. For Go, you should always use the CodeQL autobuilder. Install the Go toolchain (version 1.11 or later) and, if there are dependencies, the appropriate dependency manager (such as `dep - `__ or `Glide `__). + `__). Do not specify any build commands, as you will override the autobuilder invocation, which will create an empty database. diff --git a/docs/codeql/codeql-cli/getting-started-with-the-codeql-cli.rst b/docs/codeql/codeql-cli/getting-started-with-the-codeql-cli.rst index cb4cd413f25..53d08e41d72 100644 --- a/docs/codeql/codeql-cli/getting-started-with-the-codeql-cli.rst +++ b/docs/codeql/codeql-cli/getting-started-with-the-codeql-cli.rst @@ -121,24 +121,24 @@ see ":doc:`About QL packs `." There are different versions of the CodeQL queries available for different users. Check out the correct version for your use case: + + - For the queries used on `LGTM.com `__, check out the + ``lgtm.com`` branch. You should use this branch for databases you've built + using the CodeQL CLI, fetched from code scanning on GitHub, or recently downloaded from LGTM.com. + The queries on the ``lgtm.com`` branch are more likely to be compatible + with the ``latest`` CLI, so you'll be less likely to have to upgrade + newly-created databases than if you use the ``main`` branch. Older databases + may need to be upgraded before you can analyze them. - For the most up to date CodeQL queries, check out the ``main`` branch. This branch represents the very latest version of CodeQL's analysis. Even databases created using the most recent version of the CLI may have to be upgraded before you can analyze them. For more information, see ":doc:`Upgrading CodeQL databases `." - - - For the queries used on `LGTM.com `__, check out the - ``lgtm.com`` branch. You can run these queries on databases you've recently - downloaded from LGTM.com. Older databases may need to be upgraded before - you can analyze them. The queries on the ``lgtm.com`` branch are also more - likely to be compatible with the ``latest`` CLI, so you'll be less likely - to have to upgrade newly-created databases than if you use the ``main`` - branch. - + - For the queries used in a particular LGTM Enterprise release, check out the branch tagged with the relevant release number. For example, the branch - tagged ``v1.23.0`` corresponds to LGTM Enterprise 1.23. You must use this + tagged ``v1.27.0`` corresponds to LGTM Enterprise 1.27. You must use this version if you want to upload data to LGTM Enterprise. For further information, see `Preparing CodeQL databases to upload to LGTM `__ diff --git a/docs/codeql/codeql-cli/index.rst b/docs/codeql/codeql-cli/index.rst index 07ec8431235..d7a8a407364 100644 --- a/docs/codeql/codeql-cli/index.rst +++ b/docs/codeql/codeql-cli/index.rst @@ -18,4 +18,4 @@ CodeQL CLI using-the-codeql-cli codeql-cli-reference - + CodeQL CLI manual diff --git a/docs/codeql/codeql-cli/testing-custom-queries.rst b/docs/codeql/codeql-cli/testing-custom-queries.rst index 3890703a83d..7f347de8b1c 100644 --- a/docs/codeql/codeql-cli/testing-custom-queries.rst +++ b/docs/codeql/codeql-cli/testing-custom-queries.rst @@ -13,20 +13,6 @@ on the query and the expected results until the actual results and the expected results exactly match. This topic shows you how to create test files and execute tests on them using the ``test run`` subcommand. -.. container:: toggle - - .. container:: name - - **Information for LGTM Enterprise 1.23 users** - - CodeQL tests are a new feature in CodeQL CLI version 2.0.2. - - If you are an LGTM Enterprise 1.23 user, you should still use CodeQL CLI - version 2.0.1 to prepare databases to upload to your instance of LGTM. You - can use version 2.0.2 (or newer) to test your custom queries, but databases - created with versions newer than 2.0.1 are not compatible with LGTM - Enterprise 1.23. For more information, see ":ref:`Getting started with the CodeQL CLI `." - Setting up a test QL pack for custom queries -------------------------------------------- diff --git a/docs/codeql/codeql-cli/testing-query-help-files.rst b/docs/codeql/codeql-cli/testing-query-help-files.rst index d8285eb57cc..ba5cf3901e7 100644 --- a/docs/codeql/codeql-cli/testing-query-help-files.rst +++ b/docs/codeql/codeql-cli/testing-query-help-files.rst @@ -38,7 +38,7 @@ where ```` is one of: - the path to a ``.ql`` file. - the path to a directory containing queries and query help files. - the path to a query suite, or the name of a well-known query suite for a QL pack. - For more information, see "`Creating CodeQL query suites `__." + For more information, see "`Creating CodeQL query suites `__." You must specify a ``--format`` option, which defines how the query help is rendered. Currently, you must specify ``markdown`` to render the query help as markdown. diff --git a/docs/codeql/codeql-for-visual-studio-code/analyzing-your-projects.rst b/docs/codeql/codeql-for-visual-studio-code/analyzing-your-projects.rst index 02ece5284fa..b9a275cfb41 100644 --- a/docs/codeql/codeql-for-visual-studio-code/analyzing-your-projects.rst +++ b/docs/codeql/codeql-for-visual-studio-code/analyzing-your-projects.rst @@ -14,7 +14,7 @@ To analyze a project, you need to add a :ref:`CodeQL database ` #. Open the CodeQL Databases view in the sidebar. -#. Hover over the **Databases** title bar and click the appropriate icon to add your database. You can add a database from a local ZIP archive or folder, from a public URL, or from a project URL on LGTM.com. +#. Hover over the **Databases** title bar and click the appropriate icon to add your database. You can add a database from a local ZIP archive or folder, from a public URL, or from a project slug or URL on LGTM.com. .. image:: ../images/codeql-for-visual-studio-code/choose-database.png :width: 350 diff --git a/docs/codeql/codeql-for-visual-studio-code/customizing-settings.rst b/docs/codeql/codeql-for-visual-studio-code/customizing-settings.rst index fd61771831a..8197858d3ab 100644 --- a/docs/codeql/codeql-for-visual-studio-code/customizing-settings.rst +++ b/docs/codeql/codeql-for-visual-studio-code/customizing-settings.rst @@ -58,6 +58,11 @@ Configuring settings for testing queries To increase the number of threads used for testing queries, you can update the **Running Tests > Number Of Threads** setting. +Configuring settings for telemetry and data collection +-------------------------------------------------------- + +You can configure whether the CodeQL extension collects telemetry data. This is disabled by default. For more information, see ":doc:`About telemetry in CodeQL for Visual Studio Code `." + Further reading ---------------- diff --git a/docs/codeql/codeql-for-visual-studio-code/setting-up-codeql-in-visual-studio-code.rst b/docs/codeql/codeql-for-visual-studio-code/setting-up-codeql-in-visual-studio-code.rst index cfc85fa23bd..93b070dba18 100644 --- a/docs/codeql/codeql-for-visual-studio-code/setting-up-codeql-in-visual-studio-code.rst +++ b/docs/codeql/codeql-for-visual-studio-code/setting-up-codeql-in-visual-studio-code.rst @@ -64,7 +64,7 @@ There are two ways to do this: **Click to show information for LGTM Enterprise users** Your local version of the CodeQL queries and libraries should match your version of LGTM Enterprise. For example, if you - use LGTM Enterprise 1.23, then you should clone the ``1.23.0`` branch of the `starter workspace `__ (or the appropriate ``1.23.x`` branch, corresponding to each maintenance release). + use LGTM Enterprise 1.27, then you should clone the ``1.27.0`` branch of the `starter workspace `__ (or the appropriate ``1.27.x`` branch, corresponding to each maintenance release). This ensures that the queries and libraries you write in VS Code also work in the query console on LGTM Enterprise. diff --git a/docs/codeql/codeql-language-guides/analyzing-data-flow-in-python.rst b/docs/codeql/codeql-language-guides/analyzing-data-flow-in-python.rst index 068e925534e..f5128e5eafd 100644 --- a/docs/codeql/codeql-language-guides/analyzing-data-flow-in-python.rst +++ b/docs/codeql/codeql-language-guides/analyzing-data-flow-in-python.rst @@ -99,6 +99,8 @@ Python has builtin functionality for reading and writing files, such as the func ➤ `See this in the query console on LGTM.com `__. Two of the demo projects make use of this low-level API. +Notice the use of the ``API`` module for referring to library functions. For more information, see ":doc:`Using API graphs in Python `." + Unfortunately this will only give the expression in the argument, not the values which could be passed to it. So we use local data flow to find all expressions that flow into the argument: .. code-block:: ql diff --git a/docs/codeql/codeql-language-guides/codeql-for-python.rst b/docs/codeql/codeql-language-guides/codeql-for-python.rst index 3504b1fb2c3..15b0c4a84f8 100644 --- a/docs/codeql/codeql-language-guides/codeql-for-python.rst +++ b/docs/codeql/codeql-language-guides/codeql-for-python.rst @@ -11,6 +11,7 @@ Experiment and learn how to write effective and efficient queries for CodeQL dat basic-query-for-python-code codeql-library-for-python analyzing-data-flow-in-python + using-api-graphs-in-python functions-in-python expressions-and-statements-in-python analyzing-control-flow-in-python @@ -21,6 +22,8 @@ Experiment and learn how to write effective and efficient queries for CodeQL dat - :doc:`Analyzing data flow in Python `: You can use CodeQL to track the flow of data through a Python program to places where the data is used. +- :doc:`Using API graphs in Python `: API graphs are a uniform interface for referring to functions, classes, and methods defined in external libraries. + - :doc:`Functions in Python `: You can use syntactic classes from the standard CodeQL library to find Python functions and identify calls to them. - :doc:`Expressions and statements in Python `: You can use syntactic classes from the CodeQL library to explore how Python expressions and statements are used in a codebase. diff --git a/docs/codeql/codeql-language-guides/codeql-library-for-python.rst b/docs/codeql/codeql-language-guides/codeql-library-for-python.rst index 3f546dad1d0..204a6d22c3b 100644 --- a/docs/codeql/codeql-language-guides/codeql-library-for-python.rst +++ b/docs/codeql/codeql-language-guides/codeql-library-for-python.rst @@ -23,10 +23,9 @@ The CodeQL library for Python incorporates a large number of classes. Each class - **Data flow** - classes that represent entities from the data flow graphs. - **API graphs** - classes that represent entities from the API graphs. -The first two categories are described below. See ":doc:`Analyzing data flow in Python `" for a description of data flow and associated classes. - -.. - and [TO COME IN FUTURE PR] for a description of API graphs and their use. +The first two categories are described below. +For a description of data flow and associated classes, see ":doc:`Analyzing data flow in Python `". +For a description of API graphs and their use, see ":doc:`Using API graphs in Python `." Syntactic classes ----------------- diff --git a/docs/codeql/codeql-language-guides/data-flow-cheat-sheet-for-javascript.rst b/docs/codeql/codeql-language-guides/data-flow-cheat-sheet-for-javascript.rst index 92eb35d4d2e..1b2e5ca450b 100644 --- a/docs/codeql/codeql-language-guides/data-flow-cheat-sheet-for-javascript.rst +++ b/docs/codeql/codeql-language-guides/data-flow-cheat-sheet-for-javascript.rst @@ -63,7 +63,7 @@ Classes and member predicates in the ``DataFlow::`` module: - `getAnInstantiation `__ -- find ``new``-calls with this as the callee - `getAnInvocation `__ -- find calls or ``new``-calls with this as the callee - `getAMethodCall `__ -- find method calls with this as the receiver - - `getAMemberCall `__ -- find calls with a member of this as the receiver + - `getAMemberCall `__ -- find calls with a member of this as the callee - `getAPropertyRead `__ -- find property reads with this as the base - `getAPropertyWrite `__ -- find property writes with this as the base - `getAPropertySource `__ -- find nodes flowing into a property of this node @@ -109,12 +109,14 @@ StringOps module - StringOps::`StartsWith `__ -- check if a string starts with something - StringOps::`EndsWith `__ -- check if a string ends with something - StringOps::`Includes `__ -- check if a string contains something +- StringOps::`RegExpTest `__ -- check if a string matches a RegExp Utility -------- - `ExtendCall `__ -- call that copies properties from one object to another - `JsonParserCall `__ -- call that deserializes a JSON string +- `JsonStringifyCall `__ -- call that serializes a JSON string - `PropertyProjection `__ -- call that extracts nested properties by name System and Network @@ -128,7 +130,7 @@ System and Network - `FileSystemWriteAccess `__ -- writing to the contents of a file - `PersistentReadAccess `__ -- reading from persistent storage, like cookies - `PersistentWriteAccess `__ -- writing to persistent storage -- `RemoteFlowSource `__ -- source of untrusted user input +- `RemoteFlowSource `__ -- source of untrusted user input - `SystemCommandExecution `__ -- execution of a system command Files diff --git a/docs/codeql/codeql-language-guides/specifying-additional-remote-flow-sources-for-javascript.rst b/docs/codeql/codeql-language-guides/specifying-additional-remote-flow-sources-for-javascript.rst index fabe58bf5c9..082a7e3fcb7 100644 --- a/docs/codeql/codeql-language-guides/specifying-additional-remote-flow-sources-for-javascript.rst +++ b/docs/codeql/codeql-language-guides/specifying-additional-remote-flow-sources-for-javascript.rst @@ -12,7 +12,7 @@ You can model potential sources of untrusted user input in your code without mak Specifying remote flow sources in external files is currently in beta and subject to change. As mentioned in the :doc:`Data flow cheat sheet for JavaScript `, the CodeQL libraries for JavaScript -provide a class `RemoteFlowSource `__ to represent sources of untrusted user input, sometimes also referred to as remote flow +provide a class `RemoteFlowSource `__ to represent sources of untrusted user input, sometimes also referred to as remote flow sources. To model a new source of untrusted input, such as a previously unmodelled library API, you can diff --git a/docs/codeql/codeql-language-guides/using-api-graphs-in-python.rst b/docs/codeql/codeql-language-guides/using-api-graphs-in-python.rst new file mode 100644 index 00000000000..24be065c912 --- /dev/null +++ b/docs/codeql/codeql-language-guides/using-api-graphs-in-python.rst @@ -0,0 +1,164 @@ +.. _using-api-graphs-in-python: + +Using API graphs in Python +========================== + +API graphs are a uniform interface for referring to functions, classes, and methods defined in +external libraries. + +About this article +------------------ + +This article describes how to use API graphs to reference classes and functions defined in library +code. You can use API graphs to conveniently refer to external library functions when defining things like +remote flow sources. + + +Module imports +-------------- + +The most common entry point into the API graph will be the point where an external module or package is +imported. For example, you can access the API graph node corresponding to the ``re`` library +by using the ``API::moduleImport`` method defined in the ``semmle.python.ApiGraphs`` module, as the +following snippet demonstrates. + +.. code-block:: ql + + import python + import semmle.python.ApiGraphs + + select API::moduleImport("re") + +➤ `See this in the query console on LGTM.com `__. + +This query selects the API graph node corresponding to the ``re`` module. This node represents the fact that the ``re`` module has been imported rather than a specific location in the program where the import happens. Therefore, there will be at most one result per project, and it will not have a useful location, so you'll have to click `Show 1 non-source result` in order to see it. + +To find where the ``re`` module is referenced in the program, you can use the ``getAUse`` method. The following query selects all references to the ``re`` module in the current database. + +.. code-block:: ql + + import python + import semmle.python.ApiGraphs + + select API::moduleImport("re").getAUse() + +➤ `See this in the query console on LGTM.com `__. + +Note that the ``getAUse`` method accounts for local flow, so that ``my_re_compile`` +in the following snippet is +correctly recognized as a reference to the ``re.compile`` function. + +.. code-block:: python + + from re import compile as re_compile + + my_re_compile = re_compile + + r = my_re_compile(".*") + +If you only require immediate uses, without taking local flow into account, then you can use +the ``getAnImmediateUse`` method instead. + +Note that the given module name *must not* contain any dots. Thus, something like +``API::moduleImport("flask.views")`` will not do what you expect. Instead, this should be decomposed +into an access of the ``views`` member of the API graph node for ``flask``, as described in the next +section. + +Accessing attributes +-------------------- + +Given a node in the API graph, you can access its attributes by using the ``getMember`` method. Using +the above ``re.compile`` example, you can now find references to ``re.compile``. + +.. code-block:: ql + + import python + import semmle.python.ApiGraphs + + select API::moduleImport("re").getMember("compile").getAUse() + +➤ `See this in the query console on LGTM.com `__. + +In addition to ``getMember``, you can use the ``getUnknownMember`` method to find references to API +components where the name is not known statically. You can use the ``getAMember`` method to +access all members, both known and unknown. + +Calls and class instantiations +------------------------------ + +To track instances of classes defined in external libraries, or the results of calling externally +defined functions, you can use the ``getReturn`` method. The following snippet finds all places +where the return value of ``re.compile`` is used: + +.. code-block:: ql + + import python + import semmle.python.ApiGraphs + + select API::moduleImport("re").getMember("compile").getReturn().getAUse() + +➤ `See this in the query console on LGTM.com `__. + +Note that this includes all uses of the result of ``re.compile``, including those reachable via +local flow. To get just the *calls* to ``re.compile``, you can use ``getAnImmediateUse`` instead of +``getAUse``. As this is a common occurrence, you can use ``getACall`` instead of +``getReturn`` followed by ``getAnImmediateUse``. + +➤ `See this in the query console on LGTM.com `__. + +Note that the API graph does not distinguish between class instantiations and function calls. As far +as it's concerned, both are simply places where an API graph node is called. + +Subclasses +---------- + +For many libraries, the main mode of usage is to extend one or more library classes. To track this +in the API graph, you can use the ``getASubclass`` method to get the API graph node corresponding to +all the immediate subclasses of this node. To find *all* subclasses, use ``*`` or ``+`` to apply the +method repeatedly, as in ``getASubclass*``. + +Note that ``getASubclass`` does not account for any subclassing that takes place in library code +that has not been extracted. Thus, it may be necessary to account for this in the models you write. +For example, the ``flask.views.View`` class has a predefined subclass ``MethodView``. To find +all subclasses of ``View``, you must explicitly include the subclasses of ``MethodView`` as well. + +.. code-block:: ql + + import python + import semmle.python.ApiGraphs + + API::Node viewClass() { + result = + API::moduleImport("flask").getMember("views").getMember(["View", "MethodView"]).getASubclass*() + } + + select viewClass().getAUse() + +➤ `See this in the query console on LGTM.com `__. + +Note the use of the set literal ``["View", "MethodView"]`` to match both classes simultaneously. + +Built-in functions and classes +------------------------------ + +You can access built-in functions and classes using the ``API::builtin`` method, giving the name of +the built-in as an argument. + +For example, to find all calls to the built-in ``open`` function, you can use the following snippet. + +.. code-block:: ql + + import python + import semmle.python.ApiGraphs + + select API::builtin("open").getACall() + + + + +Further reading +--------------- + + +.. include:: ../reusables/python-further-reading.rst +.. include:: ../reusables/codeql-ref-tools-further-reading.rst diff --git a/docs/codeql/ql-language-reference/annotations.rst b/docs/codeql/ql-language-reference/annotations.rst index b3dabb42bfb..ec60e55bf9b 100644 --- a/docs/codeql/ql-language-reference/annotations.rst +++ b/docs/codeql/ql-language-reference/annotations.rst @@ -385,21 +385,23 @@ For more information, see ":ref:`monotonic-aggregates`." Binding sets ============ -**Available for**: |characteristic predicates|, |member predicates|, |non-member predicates| +**Available for**: |classes|, |characteristic predicates|, |member predicates|, |non-member predicates| ``bindingset[...]`` ------------------- -You can use this annotation to explicitly state the binding sets for a predicate. A binding set -is a subset of the predicate's arguments such that, if those arguments are constrained to a -finite set of values, then the predicate itself is finite (that is, it evaluates to a finite +You can use this annotation to explicitly state the binding sets for a predicate or class. A binding set +is a subset of a predicate's or class body's arguments such that, if those arguments are constrained to a +finite set of values, then the predicate or class itself is finite (that is, it evaluates to a finite set of tuples). -The ``bindingset`` annotation takes a comma-separated list of variables. Each variable must be -an argument of the predicate, possibly including ``this`` (for characteristic predicates and -member predicates) and ``result`` (for predicates that return a result). +The ``bindingset`` annotation takes a comma-separated list of variables. -For more information, see ":ref:`predicate-binding`." +- When you annotate a predicate, each variable must be an argument of the predicate, possibly including ``this`` + (for characteristic predicates and member predicates) and ``result`` (for predicates that return a result). + For more information, see ":ref:`predicate-binding`." +- When you annotate a class, each variable must be ``this`` or a field in the class. + Binding sets for classes are supported from release 2.3.0 of the CodeQL CLI, and release 1.26 of LGTM Enterprise. .. Links to use in substitutions diff --git a/docs/codeql/support/conf.py b/docs/codeql/support/conf.py index 45a8456ce9a..3d2f5d6cf81 100644 --- a/docs/codeql/support/conf.py +++ b/docs/codeql/support/conf.py @@ -16,7 +16,7 @@ ############################################################################## # -# Modified 22052019. +# Modified 22032021. # The configuration values below are specific to the supported languages and frameworks project # To amend html_theme_options, update version/release number, or add more sphinx extensions, @@ -41,9 +41,9 @@ project = u'Supported languages and frameworks for LGTM Enterprise' # The version info for this project, if different from version and release in main conf.py file. # The short X.Y version. -version = u'1.26' +version = u'1.27' # The full version, including alpha/beta/rc tags. -release = u'1.26' +release = u'1.27' # -- Project-specifc options for HTML output ---------------------------------------------- @@ -95,4 +95,4 @@ html_favicon = '../images/site/favicon.ico' # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. -exclude_patterns = ['read-me-project.rst', 'reusables/*'] \ No newline at end of file +exclude_patterns = ['read-me-project.rst', 'reusables/*'] diff --git a/docs/codeql/support/framework-support.rst b/docs/codeql/support/framework-support.rst index 37d54829475..d04293adfe5 100644 --- a/docs/codeql/support/framework-support.rst +++ b/docs/codeql/support/framework-support.rst @@ -10,6 +10,4 @@ The libraries and queries in version |version| have been explicitly checked agai If you're interested in other libraries or frameworks, you can extend the analysis to cover them. For example, by extending the data flow libraries to include data sources and sinks for additional libraries or frameworks. -.. There is currently no built-in support for libraries or frameworks for C/C++. - .. include:: reusables/frameworks.rst diff --git a/docs/codeql/support/reusables/frameworks.rst b/docs/codeql/support/reusables/frameworks.rst index 3963d82fcec..22569cbdcc6 100644 --- a/docs/codeql/support/reusables/frameworks.rst +++ b/docs/codeql/support/reusables/frameworks.rst @@ -1,4 +1,15 @@ -.. There is currently no built-in support for libraries or frameworks for C/C++. +C and C++ built-in support +================================ + +.. csv-table:: + :header-rows: 1 + :class: fullWidthTable + :widths: auto + + Name, Category + `Bloomberg Standard Library `__, Utility library + `Berkeley socket API library `__, Network communicator + string.h, String library C# built-in support ================================ @@ -78,6 +89,9 @@ Java built-in support :widths: auto Name, Category + Apache Commons Lang, Utility library + Apache HTTP components, Network communicator + Guava, Utility and collections library Hibernate, Database iBatis / MyBatis, Database Java Persistence API (JPA), Database @@ -126,7 +140,6 @@ JavaScript and TypeScript built-in support vue, HTML framework - Python built-in support ==================================== diff --git a/docs/codeql/support/reusables/versions-compilers.rst b/docs/codeql/support/reusables/versions-compilers.rst index 39e30bbc7cb..ff49b01a441 100644 --- a/docs/codeql/support/reusables/versions-compilers.rst +++ b/docs/codeql/support/reusables/versions-compilers.rst @@ -11,10 +11,12 @@ Microsoft extensions (up to VS 2019), Arm Compiler 5 [2]_","``.cpp``, ``.c++``, ``.cxx``, ``.hpp``, ``.hh``, ``.h++``, ``.hxx``, ``.c``, ``.cc``, ``.h``" - C#,C# up to 8.0,"Microsoft Visual Studio up to 2019 with .NET up to 4.8, + C#,C# up to 9.0,"Microsoft Visual Studio up to 2019 with .NET up to 4.8, - .NET Core up to 3.1","``.sln``, ``.csproj``, ``.cs``, ``.cshtml``, ``.xaml``" - Go (aka Golang), "Go up to 1.15", "Go 1.11 or more recent", ``.go`` + .NET Core up to 3.1 + + .NET 5","``.sln``, ``.csproj``, ``.cs``, ``.cshtml``, ``.xaml``" + Go (aka Golang), "Go up to 1.16", "Go 1.11 or more recent", ``.go`` Java,"Java 7 to 15 [3]_","javac (OpenJDK and Oracle JDK), Eclipse compiler for Java (ECJ) [4]_",``.java`` @@ -28,5 +30,5 @@ .. [2] Support for the Arm Compiler (armcc) is preliminary. .. [3] Builds that execute on Java 7 to 15 can be analyzed. The analysis understands Java 15 standard language features. .. [4] ECJ is supported when the build invokes it via the Maven Compiler plugin or the Takari Lifecycle plugin. - .. [5] JSX and Flow code, YAML, JSON, HTML, and XML files may also be analyzed with JavaScript files. - .. [6] TypeScript analysis is performed by running the JavaScript extractor with TypeScript enabled. This is the default for LGTM. + .. [5] JSX and Flow code, YAML, JSON, HTML, and XML files may also be analyzed with JavaScript files. + .. [6] TypeScript analysis is performed by running the JavaScript extractor with TypeScript enabled. This is the default for LGTM. diff --git a/docs/codeql/writing-codeql-queries/creating-path-queries.rst b/docs/codeql/writing-codeql-queries/creating-path-queries.rst index 11d72b8baf1..60723f488e1 100644 --- a/docs/codeql/writing-codeql-queries/creating-path-queries.rst +++ b/docs/codeql/writing-codeql-queries/creating-path-queries.rst @@ -55,10 +55,12 @@ You should use the following template: */ import + // For some languages (Java/C++/Python) you need to explicitly import the data flow library, such as + // import semmle.code.java.dataflow.DataFlow import DataFlow::PathGraph ... - from Configuration config, DataFlow::PathNode source, DataFlow::PathNode sink + from MyConfiguration config, DataFlow::PathNode source, DataFlow::PathNode sink where config.hasFlowPath(source, sink) select sink.getNode(), source, sink, "" @@ -66,7 +68,7 @@ Where: - ``DataFlow::Pathgraph`` is the path graph module you need to import from the standard CodeQL libraries. - ``source`` and ``sink`` are nodes on the `path graph `__, and ``DataFlow::PathNode`` is their type. -- ``Configuration`` is a class containing the predicates which define how data may flow between the ``source`` and the ``sink``. +- ``MyConfiguration`` is a class containing the predicates which define how data may flow between the ``source`` and the ``sink``. The following sections describe the main requirements for a valid path query. diff --git a/docs/ql-libraries/dataflow/dataflow.md b/docs/ql-libraries/dataflow/dataflow.md index 46ba27acccf..ea3379f3967 100644 --- a/docs/ql-libraries/dataflow/dataflow.md +++ b/docs/ql-libraries/dataflow/dataflow.md @@ -98,10 +98,6 @@ Recommendations: also work, but the upside of `use-use` steps is that sources defined in terms of variable reads just work out of the box. It also makes certain barrier-implementations simpler. -* A predicate `DataFlowCallable Node::getEnclosingCallable()` is required, and in - order to ensure appropriate join-orders, it is important that the QL compiler knows - that this predicate is functional. It can therefore be necessary to enclose the body - of this predicate in a `unique` aggregate. The shared library does not use `localFlowStep` nor `localFlow` but users of `DataFlow.qll` may expect the existence of `DataFlow::localFlowStep` and @@ -186,6 +182,45 @@ values, for example through `out` parameters in C#, the `ReturnKind` class can be defined and used to match up different kinds of `ReturnNode`s with the corresponding `OutNode`s. +#### First-class functions + +For calls to first-class functions, the library supports built-in call resolution based on data flow between a function creation expression and a call. The interface that needs to be implemented is + +```ql +class LambdaCallKind + +/** Holds if `creation` is an expression that creates a lambda of kind `kind` for `c`. */ +predicate lambdaCreation(Node creation, LambdaCallKind kind, DataFlowCallable c) + +/** Holds if `call` is a lambda call of kind `kind` where `receiver` is the lambda expression. */ +predicate lambdaCall(DataFlowCall call, LambdaCallKind kind, Node receiver) + +/** Extra data-flow steps needed for lambda flow analysis. */ +predicate additionalLambdaFlowStep(Node nodeFrom, Node nodeTo, boolean preservesValue) +``` + +with the semantics that `call` will resolve to `c` if there is a data-flow path from `creation` to `receiver`, with matching `kind`s. + +The implementation keeps track of a one-level call context, which means that we are able to handle situations like this: +```csharp +Apply(f, x) { f(x); } + +Apply(x => NonSink(x), "tainted"); // GOOD + +Apply(x => Sink(x), "not tainted"); // GOOD +``` + +However, since we only track one level the following example will have false-positive flow: +```csharp +Apply(f, x) { f(x); } + +ApplyWrapper(f, x) { Apply(f, x) } + +ApplyWrapper(x => NonSink(x), "tainted"); // GOOD (FALSE POSITIVE) + +ApplyWrapper(x => Sink(x), "not tainted"); // GOOD (FALSE POSITIVE) +``` + ## Flow through global variables Flow through global variables are called jump-steps, since such flow steps diff --git a/java/change-notes/2021-03-25-remove-legacy-code-duplication-library.md b/java/change-notes/2021-03-25-remove-legacy-code-duplication-library.md new file mode 100644 index 00000000000..2a4ac2033ea --- /dev/null +++ b/java/change-notes/2021-03-25-remove-legacy-code-duplication-library.md @@ -0,0 +1,2 @@ +lgtm,codescanning +* The legacy code duplication library has been removed. diff --git a/java/change-notes/2021-03-25-remove-legacy-filter-queries.md b/java/change-notes/2021-03-25-remove-legacy-filter-queries.md new file mode 100644 index 00000000000..e3e4b9b4b1e --- /dev/null +++ b/java/change-notes/2021-03-25-remove-legacy-filter-queries.md @@ -0,0 +1,2 @@ +lgtm,codescanning +* Legacy filter queries have been removed. diff --git a/java/change-notes/2021-04-14-membertype.md b/java/change-notes/2021-04-14-membertype.md new file mode 100644 index 00000000000..910a5c91423 --- /dev/null +++ b/java/change-notes/2021-04-14-membertype.md @@ -0,0 +1,2 @@ +lgtm,codescanning +* A CodeQL class `MemberType` is introduced to describe nested classes. Its `getQualifiedName` method returns `$`-delimited nested type names (for example, `mypackage.Outer$Middle$Inner`), where previously the same type would be named differently depending on whether it was addressed as a `NestedType` or a `Member`. diff --git a/java/ql/src/Likely Bugs/Likely Typos/StringBufferCharInit.ql b/java/ql/src/Likely Bugs/Likely Typos/StringBufferCharInit.ql index c410c7745ee..d565c5bb7ad 100644 --- a/java/ql/src/Likely Bugs/Likely Typos/StringBufferCharInit.ql +++ b/java/ql/src/Likely Bugs/Likely Typos/StringBufferCharInit.ql @@ -13,12 +13,7 @@ import java class NewStringBufferOrBuilder extends ClassInstanceExpr { - NewStringBufferOrBuilder() { - exists(Class c | c = this.getConstructedType() | - c.hasQualifiedName("java.lang", "StringBuilder") or - c.hasQualifiedName("java.lang", "StringBuffer") - ) - } + NewStringBufferOrBuilder() { getConstructedType() instanceof StringBuildingType } string getName() { result = this.getConstructedType().getName() } } diff --git a/java/ql/src/Metrics/Dependencies/ExternalDependencies.ql b/java/ql/src/Metrics/Dependencies/ExternalDependencies.ql index 79fd9db7557..f3cb1b5ce9a 100644 --- a/java/ql/src/Metrics/Dependencies/ExternalDependencies.ql +++ b/java/ql/src/Metrics/Dependencies/ExternalDependencies.ql @@ -5,7 +5,6 @@ * @kind treemap * @treemap.warnOn highValues * @metricType externalDependency - * @precision medium * @id java/external-dependencies */ diff --git a/java/ql/src/Metrics/Files/FLinesOfCode.ql b/java/ql/src/Metrics/Files/FLinesOfCode.ql index 45bea0faf4c..5c8436a18d8 100644 --- a/java/ql/src/Metrics/Files/FLinesOfCode.ql +++ b/java/ql/src/Metrics/Files/FLinesOfCode.ql @@ -5,7 +5,6 @@ * @treemap.warnOn highValues * @metricType file * @metricAggregate avg sum max - * @precision very-high * @id java/lines-of-code-in-files * @tags maintainability * complexity diff --git a/java/ql/src/Metrics/Files/FLinesOfComment.ql b/java/ql/src/Metrics/Files/FLinesOfComment.ql index ee2c21f0d9f..da9560516a3 100644 --- a/java/ql/src/Metrics/Files/FLinesOfComment.ql +++ b/java/ql/src/Metrics/Files/FLinesOfComment.ql @@ -5,7 +5,6 @@ * @treemap.warnOn lowValues * @metricType file * @metricAggregate avg sum max - * @precision very-high * @id java/lines-of-comments-in-files * @tags maintainability * documentation diff --git a/java/ql/src/Metrics/Files/FLinesOfCommentedCode.ql b/java/ql/src/Metrics/Files/FLinesOfCommentedCode.ql index d6fd316a2d9..62054ccfb87 100644 --- a/java/ql/src/Metrics/Files/FLinesOfCommentedCode.ql +++ b/java/ql/src/Metrics/Files/FLinesOfCommentedCode.ql @@ -5,7 +5,6 @@ * @treemap.warnOn highValues * @metricType file * @metricAggregate avg sum max - * @precision high * @id java/lines-of-commented-out-code-in-files * @tags maintainability * documentation diff --git a/java/ql/src/Metrics/Files/FLinesOfDuplicatedCode.ql b/java/ql/src/Metrics/Files/FLinesOfDuplicatedCode.ql index f6e99fa6b4b..89277750efb 100644 --- a/java/ql/src/Metrics/Files/FLinesOfDuplicatedCode.ql +++ b/java/ql/src/Metrics/Files/FLinesOfDuplicatedCode.ql @@ -7,21 +7,13 @@ * @treemap.warnOn highValues * @metricType file * @metricAggregate avg sum max - * @precision high * @id java/duplicated-lines-in-files * @tags testability * modularity */ -import external.CodeDuplication +import java from File f, int n -where - n = - count(int line | - exists(DuplicateBlock d | d.sourceFile() = f | - line in [d.sourceStartLine() .. d.sourceEndLine()] and - not whitelistedLineForDuplication(f, line) - ) - ) +where none() select f, n order by n desc diff --git a/java/ql/src/Metrics/Files/FLinesOfSimilarCode.ql b/java/ql/src/Metrics/Files/FLinesOfSimilarCode.ql index f7de197055f..a15d673612a 100644 --- a/java/ql/src/Metrics/Files/FLinesOfSimilarCode.ql +++ b/java/ql/src/Metrics/Files/FLinesOfSimilarCode.ql @@ -11,15 +11,8 @@ * @tags testability */ -import external.CodeDuplication +import java from File f, int n -where - n = - count(int line | - exists(SimilarBlock d | d.sourceFile() = f | - line in [d.sourceStartLine() .. d.sourceEndLine()] and - not whitelistedLineForDuplication(f, line) - ) - ) +where none() select f, n order by n desc diff --git a/java/ql/src/Metrics/Files/FNumberOfTests.ql b/java/ql/src/Metrics/Files/FNumberOfTests.ql index dc9ed989ef8..c37a4f88298 100644 --- a/java/ql/src/Metrics/Files/FNumberOfTests.ql +++ b/java/ql/src/Metrics/Files/FNumberOfTests.ql @@ -5,7 +5,6 @@ * @treemap.warnOn lowValues * @metricType file * @metricAggregate avg sum max - * @precision medium * @id java/tests-in-files * @tags maintainability */ diff --git a/java/ql/src/Performance/InnerClassCouldBeStatic.ql b/java/ql/src/Performance/InnerClassCouldBeStatic.ql index a18d801549d..5dba77761c6 100644 --- a/java/ql/src/Performance/InnerClassCouldBeStatic.ql +++ b/java/ql/src/Performance/InnerClassCouldBeStatic.ql @@ -100,8 +100,7 @@ predicate potentiallyStatic(InnerClass c) { m = a.getEnclosingCallable() and m.getDeclaringType() = c ) and - not c instanceof AnonymousClass and - not c instanceof LocalClass and + c instanceof MemberType and forall( InnerClass other // If nested and non-static, ... | diff --git a/java/ql/src/Security/CWE/CWE-209/StackTraceExposure.ql b/java/ql/src/Security/CWE/CWE-209/StackTraceExposure.ql index c9c1e2917c0..3426d9f6f62 100644 --- a/java/ql/src/Security/CWE/CWE-209/StackTraceExposure.ql +++ b/java/ql/src/Security/CWE/CWE-209/StackTraceExposure.ql @@ -79,8 +79,7 @@ predicate stackTraceExpr(Expr exception, MethodAccess stackTraceString) { printStackCall.getAnArgument() = printWriter and printStackCall.getQualifier() = exception and stackTraceString.getQualifier() = stringWriterVar.getAnAccess() and - stackTraceString.getMethod().getName() = "toString" and - stackTraceString.getMethod().getNumberOfParameters() = 0 + stackTraceString.getMethod() instanceof ToStringMethod ) } diff --git a/java/ql/src/Security/CWE/CWE-327/MaybeBrokenCryptoAlgorithm.ql b/java/ql/src/Security/CWE/CWE-327/MaybeBrokenCryptoAlgorithm.ql index efcd01548d8..7b026efb7ae 100644 --- a/java/ql/src/Security/CWE/CWE-327/MaybeBrokenCryptoAlgorithm.ql +++ b/java/ql/src/Security/CWE/CWE-327/MaybeBrokenCryptoAlgorithm.ql @@ -33,9 +33,8 @@ class InsecureAlgoLiteral extends ShortStringLiteral { } predicate objectToString(MethodAccess ma) { - exists(Method m | + exists(ToStringMethod m | m = ma.getMethod() and - m.hasName("toString") and m.getDeclaringType() instanceof TypeObject and variableTrack(ma.getQualifier()).getType().getErasure() instanceof TypeObject ) @@ -44,8 +43,7 @@ predicate objectToString(MethodAccess ma) { class StringContainer extends RefType { StringContainer() { this instanceof TypeString or - this.hasQualifiedName("java.lang", "StringBuilder") or - this.hasQualifiedName("java.lang", "StringBuffer") or + this instanceof StringBuildingType or this.hasQualifiedName("java.util", "StringTokenizer") or this.(Array).getComponentType() instanceof StringContainer } diff --git a/java/ql/src/Security/CWE/CWE-798/HardcodedCredentialsApiCall.ql b/java/ql/src/Security/CWE/CWE-798/HardcodedCredentialsApiCall.ql index 4fb3f14c993..c76527bc538 100644 --- a/java/ql/src/Security/CWE/CWE-798/HardcodedCredentialsApiCall.ql +++ b/java/ql/src/Security/CWE/CWE-798/HardcodedCredentialsApiCall.ql @@ -19,14 +19,14 @@ class HardcodedCredentialApiCallConfiguration extends DataFlow::Configuration { override predicate isSource(DataFlow::Node n) { n.asExpr() instanceof HardcodedExpr and - not n.asExpr().getEnclosingCallable().getName() = "toString" + not n.asExpr().getEnclosingCallable() instanceof ToStringMethod } override predicate isSink(DataFlow::Node n) { n.asExpr() instanceof CredentialsApiSink } override predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) { node1.asExpr().getType() instanceof TypeString and - exists(MethodAccess ma | ma.getMethod().getName().regexpMatch("getBytes|toCharArray") | + exists(MethodAccess ma | ma.getMethod().hasName(["getBytes", "toCharArray"]) | node2.asExpr() = ma and ma.getQualifier() = node1.asExpr() ) diff --git a/java/ql/src/Violations of Best Practice/Undesirable Calls/CallsToStringToString.ql b/java/ql/src/Violations of Best Practice/Undesirable Calls/CallsToStringToString.ql index 40a4e36d70c..c1395669405 100644 --- a/java/ql/src/Violations of Best Practice/Undesirable Calls/CallsToStringToString.ql +++ b/java/ql/src/Violations of Best Practice/Undesirable Calls/CallsToStringToString.ql @@ -10,9 +10,8 @@ import java -from MethodAccess ma, Method tostring +from MethodAccess ma, ToStringMethod tostring where - tostring.hasName("toString") and tostring.getDeclaringType() instanceof TypeString and ma.getMethod() = tostring select ma, "Redundant call to 'toString' on a String object." diff --git a/java/ql/src/Violations of Best Practice/Undesirable Calls/DefaultToString.ql b/java/ql/src/Violations of Best Practice/Undesirable Calls/DefaultToString.ql index 7d9ef5b85f9..c6eaf5af2cb 100644 --- a/java/ql/src/Violations of Best Practice/Undesirable Calls/DefaultToString.ql +++ b/java/ql/src/Violations of Best Practice/Undesirable Calls/DefaultToString.ql @@ -14,20 +14,13 @@ import java import semmle.code.java.StringFormat predicate explicitToStringCall(Expr e) { - exists(MethodAccess ma, Method toString | toString = ma.getMethod() | - e = ma.getQualifier() and - toString.getName() = "toString" and - toString.getNumberOfParameters() = 0 and - not toString.isStatic() + exists(MethodAccess ma | + ma.getMethod() instanceof ToStringMethod and + e = ma.getQualifier() ) } -predicate directlyDeclaresToString(Class c) { - exists(Method m | m.getDeclaringType() = c | - m.getName() = "toString" and - m.getNumberOfParameters() = 0 - ) -} +predicate directlyDeclaresToString(Class c) { any(ToStringMethod m).getDeclaringType() = c } predicate inheritsObjectToString(Class t) { not directlyDeclaresToString(t.getSourceDeclaration()) and diff --git a/java/ql/src/experimental/Security/CWE/CWE-016/InsecureSpringActuatorConfig.qhelp b/java/ql/src/experimental/Security/CWE/CWE-016/InsecureSpringActuatorConfig.qhelp new file mode 100644 index 00000000000..e201156728a --- /dev/null +++ b/java/ql/src/experimental/Security/CWE/CWE-016/InsecureSpringActuatorConfig.qhelp @@ -0,0 +1,47 @@ + + + +

    Spring Boot is a popular framework that facilitates the development of stand-alone applications +and micro services. Spring Boot Actuator helps to expose production-ready support features against +Spring Boot applications.

    + +

    Endpoints of Spring Boot Actuator allow to monitor and interact with a Spring Boot application. +Exposing unprotected actuator endpoints through configuration files can lead to information disclosure +or even remote code execution vulnerability.

    + +

    Rather than programmatically permitting endpoint requests or enforcing access control, frequently +developers simply leave management endpoints publicly accessible in the application configuration file +application.properties without enforcing access control through Spring Security.

    +
    + + +

    Declare the Spring Boot Starter Security module in XML configuration or programmatically enforce +security checks on management endpoints using Spring Security. Otherwise accessing management endpoints +on a different HTTP port other than the port that the web application is listening on also helps to +improve the security.

    +
    + + +

    The following examples show both 'BAD' and 'GOOD' configurations. In the 'BAD' configuration, +no security module is declared and sensitive management endpoints are exposed. In the 'GOOD' configuration, +security is enforced and only endpoints requiring exposure are exposed.

    + + + +
    + + +
  • + Spring Boot documentation: + Spring Boot Actuator: Production-ready Features +
  • +
  • + VERACODE Blog: + Exploiting Spring Boot Actuators +
  • +
  • + HackerOne Report: + Spring Actuator endpoints publicly available, leading to account takeover +
  • +
    +
    diff --git a/java/ql/src/experimental/Security/CWE/CWE-016/InsecureSpringActuatorConfig.ql b/java/ql/src/experimental/Security/CWE/CWE-016/InsecureSpringActuatorConfig.ql new file mode 100644 index 00000000000..e6965959d13 --- /dev/null +++ b/java/ql/src/experimental/Security/CWE/CWE-016/InsecureSpringActuatorConfig.ql @@ -0,0 +1,116 @@ +/** + * @name Insecure Spring Boot Actuator Configuration + * @description Exposed Spring Boot Actuator through configuration files without declarative or procedural + * security enforcement leads to information leak or even remote code execution. + * @kind problem + * @id java/insecure-spring-actuator-config + * @tags security + * external/cwe-016 + */ + +/* + * Note this query requires properties files to be indexed before it can produce results. + * If creating your own database with the CodeQL CLI, you should run + * `codeql database index-files --language=properties ...` + * If using lgtm.com, you should add `properties_files: true` to the index block of your + * lgtm.yml file (see https://lgtm.com/help/lgtm/java-extraction) + */ + +import java +import semmle.code.configfiles.ConfigFiles +import semmle.code.xml.MavenPom + +/** The parent node of the `org.springframework.boot` group. */ +class SpringBootParent extends Parent { + SpringBootParent() { this.getGroup().getValue() = "org.springframework.boot" } +} + +/** Class of Spring Boot dependencies. */ +class SpringBootPom extends Pom { + SpringBootPom() { this.getParentElement() instanceof SpringBootParent } + + /** Holds if the Spring Boot Actuator module `spring-boot-starter-actuator` is used in the project. */ + predicate isSpringBootActuatorUsed() { + this.getADependency().getArtifact().getValue() = "spring-boot-starter-actuator" + } + + /** + * Holds if the Spring Boot Security module is used in the project, which brings in other security + * related libraries. + */ + predicate isSpringBootSecurityUsed() { + this.getADependency().getArtifact().getValue() = "spring-boot-starter-security" + } +} + +/** The properties file `application.properties`. */ +class ApplicationProperties extends ConfigPair { + ApplicationProperties() { this.getFile().getBaseName() = "application.properties" } +} + +/** The configuration property `management.security.enabled`. */ +class ManagementSecurityConfig extends ApplicationProperties { + ManagementSecurityConfig() { this.getNameElement().getName() = "management.security.enabled" } + + /** Gets the whitespace-trimmed value of this property. */ + string getValue() { result = this.getValueElement().getValue().trim() } + + /** Holds if `management.security.enabled` is set to `false`. */ + predicate hasSecurityDisabled() { getValue() = "false" } + + /** Holds if `management.security.enabled` is set to `true`. */ + predicate hasSecurityEnabled() { getValue() = "true" } +} + +/** The configuration property `management.endpoints.web.exposure.include`. */ +class ManagementEndPointInclude extends ApplicationProperties { + ManagementEndPointInclude() { + this.getNameElement().getName() = "management.endpoints.web.exposure.include" + } + + /** Gets the whitespace-trimmed value of this property. */ + string getValue() { result = this.getValueElement().getValue().trim() } +} + +/** + * Holds if `ApplicationProperties` ap of a repository managed by `SpringBootPom` pom + * has a vulnerable configuration of Spring Boot Actuator management endpoints. + */ +predicate hasConfidentialEndPointExposed(SpringBootPom pom, ApplicationProperties ap) { + pom.isSpringBootActuatorUsed() and + not pom.isSpringBootSecurityUsed() and + ap.getFile() + .getParentContainer() + .getAbsolutePath() + .matches(pom.getFile().getParentContainer().getAbsolutePath() + "%") and // in the same sub-directory + exists(string springBootVersion | springBootVersion = pom.getParentElement().getVersionString() | + springBootVersion.regexpMatch("1\\.[0-4].*") and // version 1.0, 1.1, ..., 1.4 + not exists(ManagementSecurityConfig me | + me.hasSecurityEnabled() and me.getFile() = ap.getFile() + ) + or + springBootVersion.matches("1.5%") and // version 1.5 + exists(ManagementSecurityConfig me | me.hasSecurityDisabled() and me.getFile() = ap.getFile()) + or + springBootVersion.matches("2.%") and //version 2.x + exists(ManagementEndPointInclude mi | + mi.getFile() = ap.getFile() and + ( + mi.getValue() = "*" // all endpoints are enabled + or + mi.getValue() + .matches([ + "%dump%", "%trace%", "%logfile%", "%shutdown%", "%startup%", "%mappings%", "%env%", + "%beans%", "%sessions%" + ]) // confidential endpoints to check although all endpoints apart from '/health' and '/info' are considered sensitive by Spring + ) + ) + ) +} + +from SpringBootPom pom, ApplicationProperties ap, Dependency d +where + hasConfidentialEndPointExposed(pom, ap) and + d = pom.getADependency() and + d.getArtifact().getValue() = "spring-boot-starter-actuator" +select d, "Insecure configuration of Spring Boot Actuator exposes sensitive endpoints." diff --git a/java/ql/src/experimental/Security/CWE/CWE-016/application.properties b/java/ql/src/experimental/Security/CWE/CWE-016/application.properties new file mode 100644 index 00000000000..4f5defdd948 --- /dev/null +++ b/java/ql/src/experimental/Security/CWE/CWE-016/application.properties @@ -0,0 +1,22 @@ +#management.endpoints.web.base-path=/admin + + +#### BAD: All management endpoints are accessible #### +# vulnerable configuration (spring boot 1.0 - 1.4): exposes actuators by default + +# vulnerable configuration (spring boot 1.5+): requires value false to expose sensitive actuators +management.security.enabled=false + +# vulnerable configuration (spring boot 2+): exposes health and info only by default, here overridden to expose everything +management.endpoints.web.exposure.include=* + + +#### GOOD: All management endpoints have access control #### +# safe configuration (spring boot 1.0 - 1.4): exposes actuators by default +management.security.enabled=true + +# safe configuration (spring boot 1.5+): requires value false to expose sensitive actuators +management.security.enabled=true + +# safe configuration (spring boot 2+): exposes health and info only by default, here overridden to expose one additional endpoint which we assume is intentional and safe. +management.endpoints.web.exposure.include=beans,info,health diff --git a/java/ql/src/experimental/Security/CWE/CWE-016/pom_bad.xml b/java/ql/src/experimental/Security/CWE/CWE-016/pom_bad.xml new file mode 100644 index 00000000000..9dd5c9c188b --- /dev/null +++ b/java/ql/src/experimental/Security/CWE/CWE-016/pom_bad.xml @@ -0,0 +1,50 @@ + + + 4.0.0 + + spring-boot-actuator-app + spring-boot-actuator-app + 1.0-SNAPSHOT + + + UTF-8 + 1.8 + 1.8 + + + + org.springframework.boot + spring-boot-starter-parent + 2.3.8.RELEASE + + + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-actuator + + + org.springframework.boot + spring-boot-devtools + + + + + + + org.springframework.boot + spring-boot-test + + + + \ No newline at end of file diff --git a/java/ql/src/experimental/Security/CWE/CWE-016/pom_good.xml b/java/ql/src/experimental/Security/CWE/CWE-016/pom_good.xml new file mode 100644 index 00000000000..89f577f21e5 --- /dev/null +++ b/java/ql/src/experimental/Security/CWE/CWE-016/pom_good.xml @@ -0,0 +1,50 @@ + + + 4.0.0 + + spring-boot-actuator-app + spring-boot-actuator-app + 1.0-SNAPSHOT + + + UTF-8 + 1.8 + 1.8 + + + + org.springframework.boot + spring-boot-starter-parent + 2.3.8.RELEASE + + + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-actuator + + + org.springframework.boot + spring-boot-devtools + + + + + org.springframework.boot + spring-boot-starter-security + + + + org.springframework.boot + spring-boot-test + + + + \ No newline at end of file diff --git a/java/ql/src/experimental/Security/CWE/CWE-036/OpenStream.ql b/java/ql/src/experimental/Security/CWE/CWE-036/OpenStream.ql index 5835c3f17ef..871d6bb4737 100644 --- a/java/ql/src/experimental/Security/CWE/CWE-036/OpenStream.ql +++ b/java/ql/src/experimental/Security/CWE/CWE-036/OpenStream.ql @@ -1,8 +1,13 @@ /** * @name openStream called on URLs created from remote source * @description Calling openStream on URLs created from remote source - * can lead to local file disclosure. + * can lead to local file disclosure. * @kind path-problem + * @problem.severity warning + * @precision medium + * @id java/openstream-called-on-tainted-url + * @tags security + * external/cwe/cwe-036 */ import java diff --git a/java/ql/src/experimental/Security/CWE/CWE-094/FlowUtils.qll b/java/ql/src/experimental/Security/CWE/CWE-094/FlowUtils.qll new file mode 100644 index 00000000000..5371c51aa8f --- /dev/null +++ b/java/ql/src/experimental/Security/CWE/CWE-094/FlowUtils.qll @@ -0,0 +1,14 @@ +import java +import semmle.code.java.dataflow.FlowSources + +/** + * Holds if `fromNode` to `toNode` is a dataflow step that returns data from + * a bean by calling one of its getters. + */ +predicate hasGetterFlow(DataFlow::Node fromNode, DataFlow::Node toNode) { + exists(MethodAccess ma, Method m | ma.getMethod() = m | + m instanceof GetterMethod and + ma.getQualifier() = fromNode.asExpr() and + ma = toNode.asExpr() + ) +} diff --git a/java/ql/src/experimental/Security/CWE/CWE-094/GroovyInjection.qhelp b/java/ql/src/experimental/Security/CWE/CWE-094/GroovyInjection.qhelp new file mode 100644 index 00000000000..9bf84f710dc --- /dev/null +++ b/java/ql/src/experimental/Security/CWE/CWE-094/GroovyInjection.qhelp @@ -0,0 +1,81 @@ + + + + +

    +Apache Groovy is a powerful, optionally typed and dynamic language, +with static-typing and static compilation capabilities. + +It integrates smoothly with any Java program, +and immediately delivers to your application powerful features, +including scripting capabilities, Domain-Specific Language authoring, +runtime and compile-time meta-programming and functional programming. + +If a Groovy script is built using attacker-controlled data, +and then evaluated, then it may allow the attacker to achieve RCE. +

    +
    + + +

    +It is generally recommended to avoid using untrusted input in a Groovy evaluation. +If this is not possible, use a sandbox solution. Developers must also take care that Groovy +compile-time metaprogramming can also lead to RCE: it is possible to achieve RCE by compiling +a Groovy script (see the article "Abusing Meta Programming for Unauthenticated RCE!" linked below). + +Groovy's SecureASTCustomizer allows securing source code by controlling what code constructs are permitted. +This is typically done when using Groovy for its scripting or domain specific language (DSL) features. +The fundamental problem is that Groovy is a dynamic language, yet SecureASTCustomizer works by looking at Groovy AST statically. + +This makes it very easy for an attacker to bypass many of the intended checks +(see https://kohsuke.org/2012/04/27/groovy-secureastcustomizer-is-harmful/). +Therefore, besides SecureASTCustomizer, runtime checks are also necessary before calling Groovy methods +(see https://melix.github.io/blog/2015/03/sandboxing.html). + +It is also possible to use a block-list method, excluding unwanted classes from being loaded by the JVM. +This method is not always recommended, because block-lists can be bypassed by unexpected values. + +

    +
    + + +

    +The following example uses untrusted data to evaluate a Groovy script. +

    + + +

    +The following example uses classloader block-list approach to exclude loading dangerous classes. +

    + + +
    + + +
  • + Orange Tsai: + Abusing Meta Programming for Unauthenticated RCE!. +
  • +
  • + Cédric Champeau: + Improved sandboxing of Groovy scripts. +
  • +
  • + Kohsuke Kawaguchi: + Groovy SecureASTCustomizer is harmful. +
  • +
  • + Welk1n: + Groovy Injection payloads. +
  • +
  • + Charles Chan: + Secure Groovy Script Execution in a Sandbox. +
  • +
  • + Eugene: + Scripting and sandboxing in a JVM environment. +
  • +
    + +
    diff --git a/java/ql/src/experimental/Security/CWE/CWE-094/GroovyInjection.ql b/java/ql/src/experimental/Security/CWE/CWE-094/GroovyInjection.ql new file mode 100644 index 00000000000..0622c9cd7e3 --- /dev/null +++ b/java/ql/src/experimental/Security/CWE/CWE-094/GroovyInjection.ql @@ -0,0 +1,20 @@ +/** + * @name Groovy Language injection + * @description Evaluation of a user-controlled Groovy script + * may lead to arbitrary code execution. + * @kind path-problem + * @problem.severity error + * @precision high + * @id java/groovy-injection + * @tags security + * external/cwe/cwe-094 + */ + +import java +import DataFlow::PathGraph +import GroovyInjectionLib + +from DataFlow::PathNode source, DataFlow::PathNode sink, GroovyInjectionConfig conf +where conf.hasFlowPath(source, sink) +select sink.getNode(), source, sink, "Groovy Injection from $@.", source.getNode(), + "this user input" diff --git a/java/ql/src/experimental/Security/CWE/CWE-094/GroovyInjectionBad.java b/java/ql/src/experimental/Security/CWE/CWE-094/GroovyInjectionBad.java new file mode 100644 index 00000000000..8afe77d2a39 --- /dev/null +++ b/java/ql/src/experimental/Security/CWE/CWE-094/GroovyInjectionBad.java @@ -0,0 +1,27 @@ +public class GroovyInjection { + void injectionViaClassLoader(HttpServletRequest request) { + String script = request.getParameter("script"); + final GroovyClassLoader classLoader = new GroovyClassLoader(); + Class groovy = classLoader.parseClass(script); + GroovyObject groovyObj = (GroovyObject) groovy.newInstance(); + } + + void injectionViaEval(HttpServletRequest request) { + String script = request.getParameter("script"); + Eval.me(script); + } + + void injectionViaGroovyShell(HttpServletRequest request) { + GroovyShell shell = new GroovyShell(); + String script = request.getParameter("script"); + shell.evaluate(script); + } + + void injectionViaGroovyShellGroovyCodeSource(HttpServletRequest request) { + GroovyShell shell = new GroovyShell(); + String script = request.getParameter("script"); + GroovyCodeSource gcs = new GroovyCodeSource(script, "test", "Test"); + shell.evaluate(gcs); + } +} + diff --git a/java/ql/src/experimental/Security/CWE/CWE-094/GroovyInjectionBlocklist.java b/java/ql/src/experimental/Security/CWE/CWE-094/GroovyInjectionBlocklist.java new file mode 100644 index 00000000000..61159a3137f --- /dev/null +++ b/java/ql/src/experimental/Security/CWE/CWE-094/GroovyInjectionBlocklist.java @@ -0,0 +1,17 @@ +public class SandboxGroovyClassLoader extends ClassLoader { + public SandboxGroovyClassLoader(ClassLoader parent) { + super(parent); + } + + /* override `loadClass` here to prevent loading sensitive classes, such as `java.lang.Runtime`, `java.lang.ProcessBuilder`, `java.lang.System`, etc. */ + /* Note we must also block `groovy.transform.ASTTest`, `groovy.lang.GrabConfig` and `org.buildobjects.process.ProcBuilder` to prevent compile-time RCE. */ + + static void runWithSandboxGroovyClassLoader() throws Exception { + // GOOD: route all class-loading via sand-boxing classloader. + SandboxGroovyClassLoader classLoader = new GroovyClassLoader(new SandboxGroovyClassLoader()); + + Class scriptClass = classLoader.parseClass(untrusted.getQueryString()); + Object scriptInstance = scriptClass.newInstance(); + Object result = scriptClass.getDeclaredMethod("bar", new Class[]{}).invoke(scriptInstance, new Object[]{}); + } +} \ No newline at end of file diff --git a/java/ql/src/experimental/Security/CWE/CWE-094/GroovyInjectionLib.qll b/java/ql/src/experimental/Security/CWE/CWE-094/GroovyInjectionLib.qll new file mode 100644 index 00000000000..61ddb9b9a1a --- /dev/null +++ b/java/ql/src/experimental/Security/CWE/CWE-094/GroovyInjectionLib.qll @@ -0,0 +1,160 @@ +/** + * Provides classes and predicates for Groovy Code Injection + * taint-tracking configuration. + */ + +import java +import semmle.code.java.dataflow.FlowSources +import semmle.code.java.dataflow.TaintTracking + +/** A data flow sink for Groovy expression injection vulnerabilities. */ +abstract private class GroovyInjectionSink extends DataFlow::ExprNode { } + +/** + * A taint-tracking configuration for unsafe user input + * that is used to evaluate a Groovy expression. + */ +class GroovyInjectionConfig extends TaintTracking::Configuration { + GroovyInjectionConfig() { this = "GroovyInjectionConfig" } + + override predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource } + + override predicate isSink(DataFlow::Node sink) { sink instanceof GroovyInjectionSink } + + override predicate isAdditionalTaintStep(DataFlow::Node fromNode, DataFlow::Node toNode) { + groovyCodeSourceTaintStep(fromNode, toNode) + } +} + +/** The class `groovy.lang.GroovyShell`. */ +private class TypeGroovyShell extends RefType { + TypeGroovyShell() { this.hasQualifiedName("groovy.lang", "GroovyShell") } +} + +/** The class `groovy.lang.GroovyCodeSource`. */ +private class TypeGroovyCodeSource extends RefType { + TypeGroovyCodeSource() { this.hasQualifiedName("groovy.lang", "GroovyCodeSource") } +} + +/** + * Methods in the `GroovyShell` class that evaluate a Groovy expression. + */ +private class GroovyShellMethod extends Method { + GroovyShellMethod() { + this.getDeclaringType() instanceof TypeGroovyShell and + this.getName() in ["evaluate", "parse", "run"] + } +} + +private class GroovyShellMethodAccess extends MethodAccess { + GroovyShellMethodAccess() { this.getMethod() instanceof GroovyShellMethod } +} + +/** + * Holds if `fromNode` to `toNode` is a dataflow step from a tainted string to + * a `GroovyCodeSource` instance, i.e. `new GroovyCodeSource(tainted, ...)`. + */ +private predicate groovyCodeSourceTaintStep(DataFlow::Node fromNode, DataFlow::Node toNode) { + exists(ConstructorCall gcscc | + gcscc.getConstructedType() instanceof TypeGroovyCodeSource and + gcscc = toNode.asExpr() and + gcscc.getArgument(0) = fromNode.asExpr() + ) +} + +/** + * A sink for Groovy Injection via the `GroovyShell` class. + * + * ``` + * GroovyShell gs = new GroovyShell(); + * gs.evaluate(sink, ....) + * gs.run(sink, ....) + * gs.parse(sink,...) + * ``` + */ +private class GroovyShellSink extends GroovyInjectionSink { + GroovyShellSink() { + exists(GroovyShellMethodAccess ma, Argument firstArg | + ma.getArgument(0) = firstArg and + firstArg = this.asExpr() and + ( + firstArg.getType() instanceof TypeString or + firstArg.getType() instanceof TypeGroovyCodeSource + ) + ) + } +} + +/** The class `groovy.util.Eval`. */ +private class TypeEval extends RefType { + TypeEval() { this.hasQualifiedName("groovy.util", "Eval") } +} + +/** + * Methods in the `Eval` class that evaluate a Groovy expression. + */ +private class EvalMethod extends Method { + EvalMethod() { + this.getDeclaringType() instanceof TypeEval and + this.getName() in ["me", "x", "xy", "xyz"] + } +} + +private class EvalMethodAccess extends MethodAccess { + EvalMethodAccess() { this.getMethod() instanceof EvalMethod } + + Expr getArgumentExpr() { result = this.getArgument(this.getNumArgument() - 1) } +} + +/** + * A sink for Groovy Injection via the `Eval` class. + * + * ``` + * Eval.me(sink) + * Eval.me("p1", "p2", sink) + * Eval.x("p1", sink) + * Eval.xy("p1", "p2" sink) + * Eval.xyz("p1", "p2", "p3", sink) + * ``` + */ +private class EvalSink extends GroovyInjectionSink { + EvalSink() { exists(EvalMethodAccess ma | ma.getArgumentExpr() = this.asExpr()) } +} + +/** The class `groovy.lang.GroovyClassLoader`. */ +private class TypeGroovyClassLoader extends RefType { + TypeGroovyClassLoader() { this.hasQualifiedName("groovy.lang", "GroovyClassLoader") } +} + +/** + * A method in the `GroovyClassLoader` class that evaluates a Groovy expression. + */ +private class GroovyClassLoaderParseClassMethod extends Method { + GroovyClassLoaderParseClassMethod() { + this.getDeclaringType() instanceof TypeGroovyClassLoader and + this.hasName("parseClass") + } +} + +private class GroovyClassLoaderParseClassMethodAccess extends MethodAccess { + GroovyClassLoaderParseClassMethodAccess() { + this.getMethod() instanceof GroovyClassLoaderParseClassMethod + } +} + +/** + * A sink for Groovy Injection via the `GroovyClassLoader` class. + * + * ``` + * GroovyClassLoader classLoader = new GroovyClassLoader(); + * Class groovy = classLoader.parseClass(script); + * ``` + * + * Groovy supports compile-time metaprogramming, so just calling the `parseClass` + * method is enough to achieve RCE. + */ +private class GroovyClassLoadParseClassSink extends GroovyInjectionSink { + GroovyClassLoadParseClassSink() { + exists(GroovyClassLoaderParseClassMethodAccess ma | ma.getArgument(0) = this.asExpr()) + } +} diff --git a/java/ql/src/experimental/Security/CWE/CWE-094/InsecureDexLoading.qhelp b/java/ql/src/experimental/Security/CWE/CWE-094/InsecureDexLoading.qhelp new file mode 100644 index 00000000000..216bdeaebf3 --- /dev/null +++ b/java/ql/src/experimental/Security/CWE/CWE-094/InsecureDexLoading.qhelp @@ -0,0 +1,42 @@ + + + +

    +It is dangerous to load Dex libraries from shared world-writable storage spaces. A malicious actor can replace a dex file with a maliciously crafted file +which when loaded by the app can lead to code execution. +

    +
    + + +

    + Loading a file from private storage instead of a world-writable one can prevent this issue, + because the attacker cannot access files stored there. +

    +
    + + +

    + The following example loads a Dex file from a shared world-writable location. in this case, + since the `/sdcard` directory is on external storage, anyone can read/write to the location. + bypassing all Android security policies. Hence, this is insecure. +

    + + +

    + The next example loads a Dex file stored inside the app's private storage. + This is not exploitable as nobody else except the app can access the data stored there. +

    + +
    + + +
  • + Android Documentation: + Data and file storage overview. +
  • +
  • + Android Documentation: + DexClassLoader. +
  • +
    +
    diff --git a/java/ql/src/experimental/Security/CWE/CWE-094/InsecureDexLoading.ql b/java/ql/src/experimental/Security/CWE/CWE-094/InsecureDexLoading.ql new file mode 100644 index 00000000000..bae3ed63d70 --- /dev/null +++ b/java/ql/src/experimental/Security/CWE/CWE-094/InsecureDexLoading.ql @@ -0,0 +1,20 @@ +/** + * @name Insecure loading of an Android Dex File + * @description Loading a DEX library located in a world-writable location such as + * an SD card can lead to arbitrary code execution vulnerabilities. + * @kind path-problem + * @problem.severity error + * @precision high + * @id java/android-insecure-dex-loading + * @tags security + * external/cwe/cwe-094 + */ + +import java +import InsecureDexLoading +import DataFlow::PathGraph + +from DataFlow::PathNode source, DataFlow::PathNode sink, InsecureDexConfiguration conf +where conf.hasFlowPath(source, sink) +select sink.getNode(), source, sink, "Potential arbitrary code execution due to $@.", + source.getNode(), "a value loaded from a world-writable source." diff --git a/java/ql/src/experimental/Security/CWE/CWE-094/InsecureDexLoading.qll b/java/ql/src/experimental/Security/CWE/CWE-094/InsecureDexLoading.qll new file mode 100644 index 00000000000..0ee0954216e --- /dev/null +++ b/java/ql/src/experimental/Security/CWE/CWE-094/InsecureDexLoading.qll @@ -0,0 +1,100 @@ +import java +import semmle.code.java.dataflow.FlowSources + +/** + * A taint-tracking configuration detecting unsafe use of a + * `DexClassLoader` by an Android app. + */ +class InsecureDexConfiguration extends TaintTracking::Configuration { + InsecureDexConfiguration() { this = "Insecure Dex File Load" } + + override predicate isSource(DataFlow::Node source) { source instanceof InsecureDexSource } + + override predicate isSink(DataFlow::Node sink) { sink instanceof InsecureDexSink } + + override predicate isAdditionalTaintStep(DataFlow::Node pred, DataFlow::Node succ) { + flowStep(pred, succ) + } +} + +/** A data flow source for insecure Dex class loading vulnerabilities. */ +abstract class InsecureDexSource extends DataFlow::Node { } + +/** A data flow sink for insecure Dex class loading vulnerabilities. */ +abstract class InsecureDexSink extends DataFlow::Node { } + +private predicate flowStep(DataFlow::Node pred, DataFlow::Node succ) { + // propagate from a `java.io.File` via the `File.getAbsolutePath` call. + exists(MethodAccess m | + m.getMethod().getDeclaringType() instanceof TypeFile and + m.getMethod().hasName("getAbsolutePath") and + m.getQualifier() = pred.asExpr() and + m = succ.asExpr() + ) + or + // propagate from a `java.io.File` via the `File.toString` call. + exists(MethodAccess m | + m.getMethod().getDeclaringType() instanceof TypeFile and + m.getMethod().hasName("toString") and + m.getQualifier() = pred.asExpr() and + m = succ.asExpr() + ) + or + // propagate to newly created `File` if the parent directory of the new `File` is tainted + exists(ConstructorCall cc | + cc.getConstructedType() instanceof TypeFile and + cc.getArgument(0) = pred.asExpr() and + cc = succ.asExpr() + ) +} + +/** + * An argument to a `DexClassLoader` call taken as a sink for + * insecure Dex class loading vulnerabilities. + */ +private class DexClassLoader extends InsecureDexSink { + DexClassLoader() { + exists(ConstructorCall cc | + cc.getConstructedType().hasQualifiedName("dalvik.system", "DexClassLoader") + | + this.asExpr() = cc.getArgument(0) + ) + } +} + +/** + * A `File` instance which reads from an SD card + * taken as a source for insecure Dex class loading vulnerabilities. + */ +private class ExternalFile extends InsecureDexSource { + ExternalFile() { + exists(ConstructorCall cc, Argument a | + cc.getConstructedType() instanceof TypeFile and + a = cc.getArgument(0) and + a.(CompileTimeConstantExpr).getStringValue().matches("%sdcard%") + | + this.asExpr() = a + ) + } +} + +/** + * A directory or file which may be stored in an world writable directory + * taken as a source for insecure Dex class loading vulnerabilities. + */ +private class ExternalStorageDirSource extends InsecureDexSource { + ExternalStorageDirSource() { + exists(Method m | + m.getDeclaringType().hasQualifiedName("android.os", "Environment") and + m.hasName("getExternalStorageDirectory") + or + m.getDeclaringType().hasQualifiedName("android.content", "Context") and + m.hasName([ + "getExternalFilesDir", "getExternalFilesDirs", "getExternalMediaDirs", + "getExternalCacheDir", "getExternalCacheDirs" + ]) + | + this.asExpr() = m.getAReference() + ) + } +} diff --git a/java/ql/src/experimental/Security/CWE/CWE-094/InsecureDexLoadingBad.java b/java/ql/src/experimental/Security/CWE/CWE-094/InsecureDexLoadingBad.java new file mode 100644 index 00000000000..869b6bc571c --- /dev/null +++ b/java/ql/src/experimental/Security/CWE/CWE-094/InsecureDexLoadingBad.java @@ -0,0 +1,32 @@ + +import android.app.Application; +import android.content.Context; +import android.content.pm.PackageInfo; +import android.os.Bundle; + +import dalvik.system.DexClassLoader; +import dalvik.system.DexFile; + +public class InsecureDexLoading extends Application { + @Override + public void onCreate() { + super.onCreate(); + updateChecker(); + } + + private void updateChecker() { + try { + File file = new File("/sdcard/updater.apk"); + if (file.exists() && file.isFile() && file.length() <= 1000) { + DexClassLoader cl = new DexClassLoader(file.getAbsolutePath(), getCacheDir().getAbsolutePath(), null, + getClassLoader()); + int version = (int) cl.loadClass("my.package.class").getDeclaredMethod("myMethod").invoke(null); + if (Build.VERSION.SDK_INT < version) { + Toast.makeText(this, "Loaded Dex!", Toast.LENGTH_LONG).show(); + } + } + } catch (Exception e) { + // ignore + } + } +} diff --git a/java/ql/src/experimental/Security/CWE/CWE-094/InsecureDexLoadingGood.java b/java/ql/src/experimental/Security/CWE/CWE-094/InsecureDexLoadingGood.java new file mode 100644 index 00000000000..e45e3938f7b --- /dev/null +++ b/java/ql/src/experimental/Security/CWE/CWE-094/InsecureDexLoadingGood.java @@ -0,0 +1,23 @@ +public class SecureDexLoading extends Application { + @Override + public void onCreate() { + super.onCreate(); + updateChecker(); + } + + private void updateChecker() { + try { + File file = new File(getCacheDir() + "/updater.apk"); + if (file.exists() && file.isFile() && file.length() <= 1000) { + DexClassLoader cl = new DexClassLoader(file.getAbsolutePath(), getCacheDir().getAbsolutePath(), null, + getClassLoader()); + int version = (int) cl.loadClass("my.package.class").getDeclaredMethod("myMethod").invoke(null); + if (Build.VERSION.SDK_INT < version) { + Toast.makeText(this, "Securely loaded Dex!", Toast.LENGTH_LONG).show(); + } + } + } catch (Exception e) { + // ignore + } + } +} \ No newline at end of file diff --git a/java/ql/src/experimental/Security/CWE/CWE-094/JakartaExpressionInjection.qhelp b/java/ql/src/experimental/Security/CWE/CWE-094/JakartaExpressionInjection.qhelp new file mode 100644 index 00000000000..a8d3cd0fe70 --- /dev/null +++ b/java/ql/src/experimental/Security/CWE/CWE-094/JakartaExpressionInjection.qhelp @@ -0,0 +1,61 @@ + + + + +

    +Jakarta Expression Language (EL) is an expression language for Java applications. +There is a single language specification and multiple implementations +such as Glassfish, Juel, Apache Commons EL, etc. +The language allows invocation of methods available in the JVM. +If an expression is built using attacker-controlled data, +and then evaluated, it may allow the attacker to run arbitrary code. +

    +
    + + +

    +It is generally recommended to avoid using untrusted data in an EL expression. +Before using untrusted data to build an EL expression, the data should be validated +to ensure it is not evaluated as expression language. If the EL implementation offers +configuring a sandbox for EL expressions, they should be run in a restrictive sandbox +that allows accessing only explicitly allowed classes. If the EL implementation +does not support sandboxing, consider using other expression language implementations +with sandboxing capabilities such as Apache Commons JEXL or the Spring Expression Language. +

    +
    + + +

    +The following example shows how untrusted data is used to build and run an expression +using the JUEL interpreter: +

    + + +

    +JUEL does not support running expressions in a sandbox. To prevent running arbitrary code, +incoming data has to be checked before including it in an expression. The next example +uses a Regex pattern to check whether a user tries to run an allowed expression or not: +

    + + +
    + + +
  • + Eclipse Foundation: + Jakarta Expression Language. +
  • +
  • + Jakarta EE documentation: + Jakarta Expression Language API +
  • +
  • + OWASP: + Expression Language Injection. +
  • +
  • + JUEL: + Home page +
  • +
    +
    diff --git a/java/ql/src/experimental/Security/CWE/CWE-094/JakartaExpressionInjection.ql b/java/ql/src/experimental/Security/CWE/CWE-094/JakartaExpressionInjection.ql new file mode 100644 index 00000000000..8190ec3d61f --- /dev/null +++ b/java/ql/src/experimental/Security/CWE/CWE-094/JakartaExpressionInjection.ql @@ -0,0 +1,20 @@ +/** + * @name Jakarta Expression Language injection + * @description Evaluation of a user-controlled expression + * may lead to arbitrary code execution. + * @kind path-problem + * @problem.severity error + * @precision high + * @id java/javaee-expression-injection + * @tags security + * external/cwe/cwe-094 + */ + +import java +import JakartaExpressionInjectionLib +import DataFlow::PathGraph + +from DataFlow::PathNode source, DataFlow::PathNode sink, JakartaExpressionInjectionConfig conf +where conf.hasFlowPath(source, sink) +select sink.getNode(), source, sink, "Jakarta Expression Language injection from $@.", + source.getNode(), "this user input" diff --git a/java/ql/src/experimental/Security/CWE/CWE-094/JakartaExpressionInjectionLib.qll b/java/ql/src/experimental/Security/CWE/CWE-094/JakartaExpressionInjectionLib.qll new file mode 100644 index 00000000000..43090974364 --- /dev/null +++ b/java/ql/src/experimental/Security/CWE/CWE-094/JakartaExpressionInjectionLib.qll @@ -0,0 +1,108 @@ +import java +import FlowUtils +import semmle.code.java.dataflow.FlowSources +import semmle.code.java.dataflow.TaintTracking + +/** + * A taint-tracking configuration for unsafe user input + * that is used to construct and evaluate an expression. + */ +class JakartaExpressionInjectionConfig extends TaintTracking::Configuration { + JakartaExpressionInjectionConfig() { this = "JakartaExpressionInjectionConfig" } + + override predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource } + + override predicate isSink(DataFlow::Node sink) { sink instanceof ExpressionEvaluationSink } + + override predicate isAdditionalTaintStep(DataFlow::Node fromNode, DataFlow::Node toNode) { + any(TaintPropagatingCall c).taintFlow(fromNode, toNode) or + hasGetterFlow(fromNode, toNode) + } +} + +/** + * A sink for Expresssion Language injection vulnerabilities, + * i.e. method calls that run evaluation of an expression. + */ +private class ExpressionEvaluationSink extends DataFlow::ExprNode { + ExpressionEvaluationSink() { + exists(MethodAccess ma, Method m, Expr taintFrom | + ma.getMethod() = m and taintFrom = this.asExpr() + | + m.getDeclaringType() instanceof ValueExpression and + m.hasName(["getValue", "setValue"]) and + ma.getQualifier() = taintFrom + or + m.getDeclaringType() instanceof MethodExpression and + m.hasName("invoke") and + ma.getQualifier() = taintFrom + or + m.getDeclaringType() instanceof LambdaExpression and + m.hasName("invoke") and + ma.getQualifier() = taintFrom + or + m.getDeclaringType() instanceof ELProcessor and + m.hasName(["eval", "getValue", "setValue"]) and + ma.getArgument(0) = taintFrom + or + m.getDeclaringType() instanceof ELProcessor and + m.hasName("setVariable") and + ma.getArgument(1) = taintFrom + ) + } +} + +/** + * Defines method calls that propagate tainted expressions. + */ +private class TaintPropagatingCall extends Call { + Expr taintFromExpr; + + TaintPropagatingCall() { + taintFromExpr = this.getArgument(1) and + ( + exists(Method m | this.(MethodAccess).getMethod() = m | + m.getDeclaringType() instanceof ExpressionFactory and + m.hasName(["createValueExpression", "createMethodExpression"]) and + taintFromExpr.getType() instanceof TypeString + ) + or + exists(Constructor c | this.(ConstructorCall).getConstructor() = c | + c.getDeclaringType() instanceof LambdaExpression and + taintFromExpr.getType() instanceof ValueExpression + ) + ) + } + + /** + * Holds if `fromNode` to `toNode` is a dataflow step that propagates + * tainted data. + */ + predicate taintFlow(DataFlow::Node fromNode, DataFlow::Node toNode) { + fromNode.asExpr() = taintFromExpr and toNode.asExpr() = this + } +} + +private class JakartaType extends RefType { + JakartaType() { getPackage().hasName(["javax.el", "jakarta.el"]) } +} + +private class ELProcessor extends JakartaType { + ELProcessor() { hasName("ELProcessor") } +} + +private class ExpressionFactory extends JakartaType { + ExpressionFactory() { hasName("ExpressionFactory") } +} + +private class ValueExpression extends JakartaType { + ValueExpression() { hasName("ValueExpression") } +} + +private class MethodExpression extends JakartaType { + MethodExpression() { hasName("MethodExpression") } +} + +private class LambdaExpression extends JakartaType { + LambdaExpression() { hasName("LambdaExpression") } +} diff --git a/java/ql/src/experimental/Security/CWE/CWE-094/JexlInjectionLib.qll b/java/ql/src/experimental/Security/CWE/CWE-094/JexlInjectionLib.qll index 561d7e46ae9..89d7cb496a4 100644 --- a/java/ql/src/experimental/Security/CWE/CWE-094/JexlInjectionLib.qll +++ b/java/ql/src/experimental/Security/CWE/CWE-094/JexlInjectionLib.qll @@ -1,4 +1,5 @@ import java +import FlowUtils import semmle.code.java.dataflow.FlowSources import semmle.code.java.dataflow.TaintTracking @@ -16,7 +17,7 @@ class JexlInjectionConfig extends TaintTracking::Configuration { override predicate isAdditionalTaintStep(DataFlow::Node fromNode, DataFlow::Node toNode) { any(TaintPropagatingJexlMethodCall c).taintFlow(fromNode, toNode) or - returnsDataFromBean(fromNode, toNode) + hasGetterFlow(fromNode, toNode) } } @@ -152,18 +153,6 @@ private predicate createsJexlEngine(DataFlow::Node fromNode, DataFlow::Node toNo ) } -/** - * Holds if `fromNode` to `toNode` is a dataflow step that returns data from - * a bean by calling one of its getters. - */ -private predicate returnsDataFromBean(DataFlow::Node fromNode, DataFlow::Node toNode) { - exists(MethodAccess ma, Method m | ma.getMethod() = m | - m instanceof GetterMethod and - ma.getQualifier() = fromNode.asExpr() and - ma = toNode.asExpr() - ) -} - /** * A methods in the `JexlEngine` class that gets or sets a property with a JEXL expression. */ diff --git a/java/ql/src/experimental/Security/CWE/CWE-094/SaferExpressionEvaluationWithJuel.java b/java/ql/src/experimental/Security/CWE/CWE-094/SaferExpressionEvaluationWithJuel.java new file mode 100644 index 00000000000..3dfaaead68a --- /dev/null +++ b/java/ql/src/experimental/Security/CWE/CWE-094/SaferExpressionEvaluationWithJuel.java @@ -0,0 +1,10 @@ +String input = getRemoteUserInput(); +String pattern = "(inside|outside)\\.(temperature|humidity)"; +if (!input.matches(pattern)) { + throw new IllegalArgumentException("Unexpected expression"); +} +String expression = "${" + input + "}"; +ExpressionFactory factory = new de.odysseus.el.ExpressionFactoryImpl(); +ValueExpression e = factory.createValueExpression(context, expression, Object.class); +SimpleContext context = getContext(); +Object result = e.getValue(context); diff --git a/java/ql/src/experimental/Security/CWE/CWE-094/UnsafeExpressionEvaluationWithJuel.java b/java/ql/src/experimental/Security/CWE/CWE-094/UnsafeExpressionEvaluationWithJuel.java new file mode 100644 index 00000000000..27afa0fcb49 --- /dev/null +++ b/java/ql/src/experimental/Security/CWE/CWE-094/UnsafeExpressionEvaluationWithJuel.java @@ -0,0 +1,5 @@ +String expression = "${" + getRemoteUserInput() + "}"; +ExpressionFactory factory = new de.odysseus.el.ExpressionFactoryImpl(); +ValueExpression e = factory.createValueExpression(context, expression, Object.class); +SimpleContext context = getContext(); +Object result = e.getValue(context); \ No newline at end of file diff --git a/java/ql/src/experimental/Security/CWE/CWE-1004/SensitiveCookieNotHttpOnly.java b/java/ql/src/experimental/Security/CWE/CWE-1004/SensitiveCookieNotHttpOnly.java new file mode 100644 index 00000000000..48d80707ff8 --- /dev/null +++ b/java/ql/src/experimental/Security/CWE/CWE-1004/SensitiveCookieNotHttpOnly.java @@ -0,0 +1,44 @@ +class SensitiveCookieNotHttpOnly { + // GOOD - Create a sensitive cookie with the `HttpOnly` flag set. + public void addCookie(String jwt_token, HttpServletRequest request, HttpServletResponse response) { + Cookie jwtCookie =new Cookie("jwt_token", jwt_token); + jwtCookie.setPath("/"); + jwtCookie.setMaxAge(3600*24*7); + jwtCookie.setHttpOnly(true); + response.addCookie(jwtCookie); + } + + // BAD - Create a sensitive cookie without the `HttpOnly` flag set. + public void addCookie2(String jwt_token, String userId, HttpServletRequest request, HttpServletResponse response) { + Cookie jwtCookie =new Cookie("jwt_token", jwt_token); + jwtCookie.setPath("/"); + jwtCookie.setMaxAge(3600*24*7); + response.addCookie(jwtCookie); + } + + // GOOD - Set a sensitive cookie header with the `HttpOnly` flag set. + public void addCookie3(String authId, HttpServletRequest request, HttpServletResponse response) { + response.addHeader("Set-Cookie", "token=" +authId + ";HttpOnly;Secure"); + } + + // BAD - Set a sensitive cookie header without the `HttpOnly` flag set. + public void addCookie4(String authId, HttpServletRequest request, HttpServletResponse response) { + response.addHeader("Set-Cookie", "token=" +authId + ";Secure"); + } + + // GOOD - Set a sensitive cookie header using the class `javax.ws.rs.core.Cookie` with the `HttpOnly` flag set through string concatenation. + public void addCookie5(String accessKey, HttpServletRequest request, HttpServletResponse response) { + response.setHeader("Set-Cookie", new NewCookie("session-access-key", accessKey, "/", null, null, 0, true) + ";HttpOnly"); + } + + // BAD - Set a sensitive cookie header using the class `javax.ws.rs.core.Cookie` without the `HttpOnly` flag set. + public void addCookie6(String accessKey, HttpServletRequest request, HttpServletResponse response) { + response.setHeader("Set-Cookie", new NewCookie("session-access-key", accessKey, "/", null, null, 0, true).toString()); + } + + // GOOD - Set a sensitive cookie header using the class `javax.ws.rs.core.Cookie` with the `HttpOnly` flag set through the constructor. + public void addCookie7(String accessKey, HttpServletRequest request, HttpServletResponse response) { + NewCookie accessKeyCookie = new NewCookie("session-access-key", accessKey, "/", null, null, 0, true, true); + response.setHeader("Set-Cookie", accessKeyCookie.toString()); + } +} diff --git a/java/ql/src/experimental/Security/CWE/CWE-1004/SensitiveCookieNotHttpOnly.qhelp b/java/ql/src/experimental/Security/CWE/CWE-1004/SensitiveCookieNotHttpOnly.qhelp new file mode 100644 index 00000000000..ee3e8a4181a --- /dev/null +++ b/java/ql/src/experimental/Security/CWE/CWE-1004/SensitiveCookieNotHttpOnly.qhelp @@ -0,0 +1,27 @@ + + + + +

    Cross-Site Scripting (XSS) is categorized as one of the OWASP Top 10 Security Vulnerabilities. The HttpOnly flag directs compatible browsers to prevent client-side script from accessing cookies. Including the HttpOnly flag in the Set-Cookie HTTP response header for a sensitive cookie helps mitigate the risk associated with XSS where an attacker's script code attempts to read the contents of a cookie and exfiltrate information obtained.

    +
    + + +

    Use the HttpOnly flag when generating a cookie containing sensitive information to help mitigate the risk of client side script accessing the protected cookie.

    +
    + + +

    The following example shows two ways of generating sensitive cookies. In the 'BAD' cases, the HttpOnly flag is not set. In the 'GOOD' cases, the HttpOnly flag is set.

    + +
    + + +
  • + PortSwigger: + Cookie without HttpOnly flag set +
  • +
  • + OWASP: + HttpOnly +
  • +
    +
    diff --git a/java/ql/src/experimental/Security/CWE/CWE-1004/SensitiveCookieNotHttpOnly.ql b/java/ql/src/experimental/Security/CWE/CWE-1004/SensitiveCookieNotHttpOnly.ql new file mode 100644 index 00000000000..4c0dc624d07 --- /dev/null +++ b/java/ql/src/experimental/Security/CWE/CWE-1004/SensitiveCookieNotHttpOnly.ql @@ -0,0 +1,221 @@ +/** + * @name Sensitive cookies without the HttpOnly response header set + * @description Sensitive cookies without the 'HttpOnly' flag set leaves session cookies vulnerable to + * an XSS attack. + * @kind path-problem + * @id java/sensitive-cookie-not-httponly + * @tags security + * external/cwe/cwe-1004 + */ + +/* + * Sketch of the structure of this query: we track cookie names that appear to be sensitive + * (e.g. `session` or `token`) to a `ServletResponse.addHeader(...)` or `.addCookie(...)` + * method that does not set the `httpOnly` flag. Subsidiary configurations + * `MatchesHttpOnlyConfiguration` and `SetHttpOnlyInCookieConfiguration` are used to establish + * when the `httpOnly` flag is likely to have been set, before configuration + * `MissingHttpOnlyConfiguration` establishes that a non-`httpOnly` cookie has a sensitive-seeming name. + */ + +import java +import semmle.code.java.dataflow.FlowSteps +import semmle.code.java.frameworks.Servlets +import semmle.code.java.dataflow.TaintTracking +import semmle.code.java.dataflow.TaintTracking2 +import DataFlow::PathGraph + +/** Gets a regular expression for matching common names of sensitive cookies. */ +string getSensitiveCookieNameRegex() { result = "(?i).*(auth|session|token|key|credential).*" } + +/** Gets a regular expression for matching CSRF cookies. */ +string getCsrfCookieNameRegex() { result = "(?i).*(csrf).*" } + +/** + * Holds if a string is concatenated with the name of a sensitive cookie. Excludes CSRF cookies since + * they are special cookies implementing the Synchronizer Token Pattern that can be used in JavaScript. + */ +predicate isSensitiveCookieNameExpr(Expr expr) { + exists(string s | s = expr.(CompileTimeConstantExpr).getStringValue() | + s.regexpMatch(getSensitiveCookieNameRegex()) and not s.regexpMatch(getCsrfCookieNameRegex()) + ) + or + isSensitiveCookieNameExpr(expr.(AddExpr).getAnOperand()) +} + +/** A sensitive cookie name. */ +class SensitiveCookieNameExpr extends Expr { + SensitiveCookieNameExpr() { isSensitiveCookieNameExpr(this) } +} + +/** A method call that sets a `Set-Cookie` header. */ +class SetCookieMethodAccess extends MethodAccess { + SetCookieMethodAccess() { + ( + this.getMethod() instanceof ResponseAddHeaderMethod or + this.getMethod() instanceof ResponseSetHeaderMethod + ) and + this.getArgument(0).(CompileTimeConstantExpr).getStringValue().toLowerCase() = "set-cookie" + } +} + +/** + * A taint configuration tracking flow from the text `httponly` to argument 1 of + * `SetCookieMethodAccess`. + */ +class MatchesHttpOnlyConfiguration extends TaintTracking2::Configuration { + MatchesHttpOnlyConfiguration() { this = "MatchesHttpOnlyConfiguration" } + + override predicate isSource(DataFlow::Node source) { + source.asExpr().(CompileTimeConstantExpr).getStringValue().toLowerCase().matches("%httponly%") + } + + override predicate isSink(DataFlow::Node sink) { + sink.asExpr() = any(SetCookieMethodAccess ma).getArgument(1) + } +} + +/** A class descended from `javax.servlet.http.Cookie` or `javax/jakarta.ws.rs.core.Cookie`. */ +class CookieClass extends RefType { + CookieClass() { + this.getASupertype*() + .hasQualifiedName(["javax.servlet.http", "javax.ws.rs.core", "jakarta.ws.rs.core"], "Cookie") + } +} + +/** Holds if `expr` is any boolean-typed expression other than literal `false`. */ +// Inlined because this could be a very large result set if computed out of context +pragma[inline] +predicate mayBeBooleanTrue(Expr expr) { + expr.getType() instanceof BooleanType and + not expr.(CompileTimeConstantExpr).getBooleanValue() = false +} + +/** Holds if the method call may set the `HttpOnly` flag. */ +predicate setsCookieHttpOnly(MethodAccess ma) { + ma.getMethod().getName() = "setHttpOnly" and + // any use of setHttpOnly(x) where x isn't false is probably safe + mayBeBooleanTrue(ma.getArgument(0)) +} + +/** Holds if `ma` removes a cookie. */ +predicate removesCookie(MethodAccess ma) { + ma.getMethod().getName() = "setMaxAge" and + ma.getArgument(0).(IntegerLiteral).getIntValue() = 0 +} + +/** + * Holds if the MethodAccess `ma` is a test method call indicated by: + * a) in a test directory such as `src/test/java` + * b) in a test package whose name has the word `test` + * c) in a test class whose name has the word `test` + * d) in a test class implementing a test framework such as JUnit or TestNG + */ +predicate isTestMethod(MethodAccess ma) { + exists(Method m | + m = ma.getEnclosingCallable() and + ( + m.getDeclaringType().getName().toLowerCase().matches("%test%") or // Simple check to exclude test classes to reduce FPs + m.getDeclaringType().getPackage().getName().toLowerCase().matches("%test%") or // Simple check to exclude classes in test packages to reduce FPs + exists(m.getLocation().getFile().getAbsolutePath().indexOf("/src/test/java")) or // Match test directory structure of build tools like maven + m instanceof TestMethod // Test method of a test case implementing a test framework such as JUnit or TestNG + ) + ) +} + +/** + * A taint configuration tracking flow of a method that sets the `HttpOnly` flag, + * or one that removes a cookie, to a `ServletResponse.addCookie` call. + */ +class SetHttpOnlyOrRemovesCookieConfiguration extends TaintTracking2::Configuration { + SetHttpOnlyOrRemovesCookieConfiguration() { this = "SetHttpOnlyOrRemovesCookieConfiguration" } + + override predicate isSource(DataFlow::Node source) { + source.asExpr() = + any(MethodAccess ma | setsCookieHttpOnly(ma) or removesCookie(ma)).getQualifier() + } + + override predicate isSink(DataFlow::Node sink) { + sink.asExpr() = + any(MethodAccess ma | ma.getMethod() instanceof ResponseAddCookieMethod).getArgument(0) + } +} + +/** + * A cookie that is added to an HTTP response and which doesn't have `httpOnly` set, used as a sink + * in `MissingHttpOnlyConfiguration`. + */ +class CookieResponseSink extends DataFlow::ExprNode { + CookieResponseSink() { + exists(MethodAccess ma | + ( + ma.getMethod() instanceof ResponseAddCookieMethod and + this.getExpr() = ma.getArgument(0) and + not exists(SetHttpOnlyOrRemovesCookieConfiguration cc | cc.hasFlowTo(this)) + or + ma instanceof SetCookieMethodAccess and + this.getExpr() = ma.getArgument(1) and + not exists(MatchesHttpOnlyConfiguration cc | cc.hasFlowTo(this)) // response.addHeader("Set-Cookie", "token=" +authId + ";HttpOnly;Secure") + ) and + not isTestMethod(ma) // Test class or method + ) + } +} + +/** Holds if `cie` is an invocation of a JAX-RS `NewCookie` constructor that sets `HttpOnly` to true. */ +predicate setsHttpOnlyInNewCookie(ClassInstanceExpr cie) { + cie.getConstructedType().hasQualifiedName(["javax.ws.rs.core", "jakarta.ws.rs.core"], "NewCookie") and + ( + cie.getNumArgument() = 6 and + mayBeBooleanTrue(cie.getArgument(5)) // NewCookie(Cookie cookie, String comment, int maxAge, Date expiry, boolean secure, boolean httpOnly) + or + cie.getNumArgument() = 8 and + cie.getArgument(6).getType() instanceof BooleanType and + mayBeBooleanTrue(cie.getArgument(7)) // NewCookie(String name, String value, String path, String domain, String comment, int maxAge, boolean secure, boolean httpOnly) + or + cie.getNumArgument() = 10 and + mayBeBooleanTrue(cie.getArgument(9)) // NewCookie(String name, String value, String path, String domain, int version, String comment, int maxAge, Date expiry, boolean secure, boolean httpOnly) + ) +} + +/** + * A taint configuration tracking flow from a sensitive cookie without the `HttpOnly` flag + * set to its HTTP response. + */ +class MissingHttpOnlyConfiguration extends TaintTracking::Configuration { + MissingHttpOnlyConfiguration() { this = "MissingHttpOnlyConfiguration" } + + override predicate isSource(DataFlow::Node source) { + source.asExpr() instanceof SensitiveCookieNameExpr + } + + override predicate isSink(DataFlow::Node sink) { sink instanceof CookieResponseSink } + + override predicate isSanitizer(DataFlow::Node node) { + // JAX-RS's `new NewCookie("session-access-key", accessKey, "/", null, null, 0, true, true)` and similar + setsHttpOnlyInNewCookie(node.asExpr()) + } + + override predicate isAdditionalTaintStep(DataFlow::Node pred, DataFlow::Node succ) { + exists( + ConstructorCall cc // new Cookie(...) + | + cc.getConstructedType() instanceof CookieClass and + pred.asExpr() = cc.getAnArgument() and + succ.asExpr() = cc + ) + or + exists( + MethodAccess ma // cookie.toString() + | + ma.getMethod().getName() = "toString" and + ma.getQualifier().getType() instanceof CookieClass and + pred.asExpr() = ma.getQualifier() and + succ.asExpr() = ma + ) + } +} + +from DataFlow::PathNode source, DataFlow::PathNode sink, MissingHttpOnlyConfiguration c +where c.hasFlowPath(source, sink) +select sink.getNode(), source, sink, "$@ doesn't have the HttpOnly flag set.", source.getNode(), + "This sensitive cookie" diff --git a/java/ql/src/experimental/Security/CWE/CWE-117/LogInjection.qhelp b/java/ql/src/experimental/Security/CWE/CWE-117/LogInjection.qhelp new file mode 100644 index 00000000000..4ad7b2d5380 --- /dev/null +++ b/java/ql/src/experimental/Security/CWE/CWE-117/LogInjection.qhelp @@ -0,0 +1,49 @@ + + + + + + +

    If unsanitized user input is written to a log entry, a malicious user may be able to forge new log entries.

    + +

    Forgery can occur if a user provides some input creating the appearance of multiple + log entries. This can include unescaped new-line characters, or HTML or other markup.

    +
    + + +

    +User input should be suitably sanitized before it is logged. +

    +

    +If the log entries are plain text then line breaks should be removed from user input, using for example +String replace(char oldChar, char newChar) or similar. Care should also be taken that user input is clearly marked +in log entries, and that a malicious user cannot cause confusion in other ways. +

    +

    +For log entries that will be displayed in HTML, user input should be HTML encoded before being logged, to prevent forgery and +other forms of HTML injection. +

    + +
    + + +

    In the example, a username, provided by the user, is logged using logger.warn (from org.slf4j.Logger). + In the first case (/bad endpoint), the username is logged without any sanitization. + If a malicious user provides Guest'%0AUser:'Admin as a username parameter, + the log entry will be split into two separate lines, where the first line will be User:'Guest' and the second one will be User:'Admin'. +

    + + +

    In the second case (/good endpoint), matches() is used to ensure the user input only has alphanumeric characters. + If a malicious user provides `Guest'%0AUser:'Admin` as a username parameter, + the log entry will not be split into two separate lines, resulting in a single line User:'Guest'User:'Admin'.

    + + +
    + + +
  • OWASP: Log Injection.
  • +
    +
    diff --git a/java/ql/src/experimental/Security/CWE/CWE-117/LogInjection.ql b/java/ql/src/experimental/Security/CWE/CWE-117/LogInjection.ql new file mode 100644 index 00000000000..7183c74b5bf --- /dev/null +++ b/java/ql/src/experimental/Security/CWE/CWE-117/LogInjection.ql @@ -0,0 +1,38 @@ +/** + * @name Log Injection + * @description Building log entries from user-controlled data is vulnerable to + * insertion of forged log entries by a malicious user. + * @kind path-problem + * @problem.severity error + * @precision high + * @id java/log-injection + * @tags security + * external/cwe/cwe-117 + */ + +import java +import DataFlow::PathGraph +import experimental.semmle.code.java.Logging +import semmle.code.java.dataflow.FlowSources + +/** + * A taint-tracking configuration for tracking untrusted user input used in log entries. + */ +private class LogInjectionConfiguration extends TaintTracking::Configuration { + LogInjectionConfiguration() { this = "Log Injection" } + + override predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource } + + override predicate isSink(DataFlow::Node sink) { + sink.asExpr() = any(LoggingCall c).getALogArgument() + } + + override predicate isSanitizer(DataFlow::Node node) { + node.getType() instanceof BoxedType or node.getType() instanceof PrimitiveType + } +} + +from LogInjectionConfiguration cfg, DataFlow::PathNode source, DataFlow::PathNode sink +where cfg.hasFlowPath(source, sink) +select sink.getNode(), source, sink, "$@ flows to log entry.", source.getNode(), + "User-provided value" diff --git a/java/ql/src/experimental/Security/CWE/CWE-117/LogInjectionBad.java b/java/ql/src/experimental/Security/CWE/CWE-117/LogInjectionBad.java new file mode 100644 index 00000000000..620b9801631 --- /dev/null +++ b/java/ql/src/experimental/Security/CWE/CWE-117/LogInjectionBad.java @@ -0,0 +1,24 @@ +package com.example.restservice; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +@RestController +public class LogInjection { + + private final Logger log = LoggerFactory.getLogger(LogInjection.class); + + // /bad?username=Guest'%0AUser:'Admin + @GetMapping("/bad") + public String bad(@RequestParam(value = "username", defaultValue = "name") String username) { + log.warn("User:'{}'", username); + // The logging call above would result in multiple log entries as shown below: + // User:'Guest' + // User:'Admin' + return username; + } +} + diff --git a/java/ql/src/experimental/Security/CWE/CWE-117/LogInjectionGood.java b/java/ql/src/experimental/Security/CWE/CWE-117/LogInjectionGood.java new file mode 100644 index 00000000000..2ed683a2760 --- /dev/null +++ b/java/ql/src/experimental/Security/CWE/CWE-117/LogInjectionGood.java @@ -0,0 +1,25 @@ +package com.example.restservice; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +@RestController +public class LogInjection { + + private final Logger log = LoggerFactory.getLogger(LogInjection.class); + + // /good?username=Guest'%0AUser:'Admin + @GetMapping("/good") + public String good(@RequestParam(value = "username", defaultValue = "name") String username) { + // The regex check here, allows only alphanumeric characters to pass. + // Hence, does not result in log injection + if (username.matches("\w*")) { + log.warn("User:'{}'", username); + + return username; + } + } +} diff --git a/java/ql/src/experimental/Security/CWE/CWE-273/UnsafeCertTrust.ql b/java/ql/src/experimental/Security/CWE/CWE-273/UnsafeCertTrust.ql index 3dca54a8de6..9efdcbf4c6e 100644 --- a/java/ql/src/experimental/Security/CWE/CWE-273/UnsafeCertTrust.ql +++ b/java/ql/src/experimental/Security/CWE/CWE-273/UnsafeCertTrust.ql @@ -1,7 +1,12 @@ /** * @name Unsafe certificate trust - * @description Unsafe implementation of the interface X509TrustManager and SSLSocket/SSLEngine ignores all SSL certificate validation errors when establishing an HTTPS connection, thereby making the app vulnerable to man-in-the-middle attacks. + * @description Unsafe implementation of the interface X509TrustManager and + * SSLSocket/SSLEngine ignores all SSL certificate validation + * errors when establishing an HTTPS connection, thereby making + * the app vulnerable to man-in-the-middle attacks. * @kind problem + * @problem.severity warning + * @precision medium * @id java/unsafe-cert-trust * @tags security * external/cwe-273 diff --git a/java/ql/src/experimental/Security/CWE/CWE-295/JxBrowserWithoutCertValidation.ql b/java/ql/src/experimental/Security/CWE/CWE-295/JxBrowserWithoutCertValidation.ql index aecffaf3f3b..f664f4ce953 100644 --- a/java/ql/src/experimental/Security/CWE/CWE-295/JxBrowserWithoutCertValidation.ql +++ b/java/ql/src/experimental/Security/CWE/CWE-295/JxBrowserWithoutCertValidation.ql @@ -1,7 +1,11 @@ /** * @name JxBrowser with disabled certificate validation - * @description Insecure configuration of JxBrowser disables certificate validation making the app vulnerable to man-in-the-middle attacks. + * @description Insecure configuration of JxBrowser disables certificate + * validation making the app vulnerable to man-in-the-middle + * attacks. * @kind problem + * @problem.severity warning + * @precision medium * @id java/jxbrowser/disabled-certificate-validation * @tags security * external/cwe/cwe-295 diff --git a/java/ql/src/experimental/Security/CWE/CWE-297/InsecureJavaMail.ql b/java/ql/src/experimental/Security/CWE/CWE-297/InsecureJavaMail.ql index 6b9176ce034..c17c83448cb 100644 --- a/java/ql/src/experimental/Security/CWE/CWE-297/InsecureJavaMail.ql +++ b/java/ql/src/experimental/Security/CWE/CWE-297/InsecureJavaMail.ql @@ -1,8 +1,12 @@ /** - * @id java/insecure-smtp-ssl * @name Insecure JavaMail SSL Configuration - * @description Java application configured to use authenticated mail session over SSL does not validate the SSL certificate to properly ensure that it is actually associated with that host. + * @description Java application configured to use authenticated mail session + * over SSL does not validate the SSL certificate to properly + * ensure that it is actually associated with that host. * @kind problem + * @problem.severity warning + * @precision medium + * @id java/insecure-smtp-ssl * @tags security * external/cwe-297 */ diff --git a/java/ql/src/experimental/Security/CWE/CWE-297/InsecureLdapEndpoint.java b/java/ql/src/experimental/Security/CWE/CWE-297/InsecureLdapEndpoint.java new file mode 100644 index 00000000000..6f7494f8811 --- /dev/null +++ b/java/ql/src/experimental/Security/CWE/CWE-297/InsecureLdapEndpoint.java @@ -0,0 +1,18 @@ +public class InsecureLdapEndpoint { + public Hashtable createConnectionEnv() { + Hashtable env = new Hashtable(); + env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory"); + env.put(Context.PROVIDER_URL, "ldaps://ad.your-server.com:636"); + + env.put(Context.SECURITY_AUTHENTICATION, "simple"); + env.put(Context.SECURITY_PRINCIPAL, "username"); + env.put(Context.SECURITY_CREDENTIALS, "secpassword"); + + // BAD - Test configuration with disabled SSL endpoint check. + { + System.setProperty("com.sun.jndi.ldap.object.disableEndpointIdentification", "true"); + } + + return env; + } +} diff --git a/java/ql/src/experimental/Security/CWE/CWE-297/InsecureLdapEndpoint.qhelp b/java/ql/src/experimental/Security/CWE/CWE-297/InsecureLdapEndpoint.qhelp new file mode 100644 index 00000000000..50e1febf894 --- /dev/null +++ b/java/ql/src/experimental/Security/CWE/CWE-297/InsecureLdapEndpoint.qhelp @@ -0,0 +1,40 @@ + + + + +

    Java versions 8u181 or greater have enabled LDAPS endpoint identification by default. Nowadays + infrastructure services like LDAP are commonly deployed behind load balancers therefore the LDAP + server name can be different from the FQDN of the LDAPS endpoint. If a service certificate does not + properly contain a matching DNS name as part of the certificate, Java will reject it by default.

    +

    Instead of addressing the issue properly by having a compliant certificate deployed, frequently + developers simply disable the LDAPS endpoint check.

    +

    Failing to validate the certificate makes the SSL session susceptible to a man-in-the-middle attack. + This query checks whether the LDAPS endpoint check is disabled in system properties.

    +
    + + +

    Replace any non-conforming LDAP server certificates to include a DNS name in the subjectAltName field + of the certificate that matches the FQDN of the service.

    +
    + + +

    The following two examples show two ways of configuring LDAPS endpoint. In the 'BAD' case, + endpoint check is disabled. In the 'GOOD' case, endpoint check is left enabled through the + default Java configuration.

    + + +
    + + +
  • + Oracle Java 8 Update 181 (8u181): + Endpoint identification enabled on LDAPS connections +
  • +
  • + IBM: + Fix this LDAP SSL error +
  • +
    +
    diff --git a/java/ql/src/experimental/Security/CWE/CWE-297/InsecureLdapEndpoint.ql b/java/ql/src/experimental/Security/CWE/CWE-297/InsecureLdapEndpoint.ql new file mode 100644 index 00000000000..9fa2fe596fd --- /dev/null +++ b/java/ql/src/experimental/Security/CWE/CWE-297/InsecureLdapEndpoint.ql @@ -0,0 +1,110 @@ +/** + * @name Insecure LDAPS Endpoint Configuration + * @description Java application configured to disable LDAPS endpoint + * identification does not validate the SSL certificate to + * properly ensure that it is actually associated with that host. + * @kind problem + * @problem.severity warning + * @precision medium + * @id java/insecure-ldaps-endpoint + * @tags security + * external/cwe-297 + */ + +import java + +/** The method to set a system property. */ +class SetSystemPropertyMethod extends Method { + SetSystemPropertyMethod() { + this.hasName("setProperty") and + this.getDeclaringType().hasQualifiedName("java.lang", "System") + } +} + +/** The class `java.util.Hashtable`. */ +class TypeHashtable extends Class { + TypeHashtable() { this.getSourceDeclaration().hasQualifiedName("java.util", "Hashtable") } +} + +/** + * The method to set Java properties either through `setProperty` declared in the class `Properties` + * or `put` declared in its parent class `HashTable`. + */ +class SetPropertyMethod extends Method { + SetPropertyMethod() { + this.getDeclaringType().getAnAncestor() instanceof TypeHashtable and + this.hasName(["put", "setProperty"]) + } +} + +/** The `setProperties` method declared in `java.lang.System`. */ +class SetSystemPropertiesMethod extends Method { + SetSystemPropertiesMethod() { + this.hasName("setProperties") and + this.getDeclaringType().hasQualifiedName("java.lang", "System") + } +} + +/** + * Holds if `Expr` expr is evaluated to the string literal + * `com.sun.jndi.ldap.object.disableEndpointIdentification`. + */ +predicate isPropertyDisableLdapEndpointId(Expr expr) { + expr.(CompileTimeConstantExpr).getStringValue() = + "com.sun.jndi.ldap.object.disableEndpointIdentification" + or + exists(Field f | + expr = f.getAnAccess() and + f.getAnAssignedValue().(StringLiteral).getValue() = + "com.sun.jndi.ldap.object.disableEndpointIdentification" + ) +} + +/** Holds if an expression is evaluated to the boolean value true. */ +predicate isBooleanTrue(Expr expr) { + expr.(CompileTimeConstantExpr).getStringValue() = "true" // "true" + or + expr.(BooleanLiteral).getBooleanValue() = true // true + or + exists(MethodAccess ma | + expr = ma and + ma.getMethod() instanceof ToStringMethod and + ma.getQualifier().(FieldAccess).getField().hasName("TRUE") and + ma.getQualifier() + .(FieldAccess) + .getField() + .getDeclaringType() + .hasQualifiedName("java.lang", "Boolean") // Boolean.TRUE.toString() + ) +} + +/** Holds if `ma` is in a test class or method. */ +predicate isTestMethod(MethodAccess ma) { + ma.getEnclosingCallable() instanceof TestMethod or + ma.getEnclosingCallable().getDeclaringType() instanceof TestClass or + ma.getEnclosingCallable().getDeclaringType().getPackage().getName().matches("%test%") or + ma.getEnclosingCallable().getDeclaringType().getName().toLowerCase().matches("%test%") +} + +/** Holds if `MethodAccess` ma disables SSL endpoint check. */ +predicate isInsecureSSLEndpoint(MethodAccess ma) { + ( + ma.getMethod() instanceof SetSystemPropertyMethod and + isPropertyDisableLdapEndpointId(ma.getArgument(0)) and + isBooleanTrue(ma.getArgument(1)) //com.sun.jndi.ldap.object.disableEndpointIdentification=true + or + ma.getMethod() instanceof SetSystemPropertiesMethod and + exists(MethodAccess ma2 | + ma2.getMethod() instanceof SetPropertyMethod and + isPropertyDisableLdapEndpointId(ma2.getArgument(0)) and + isBooleanTrue(ma2.getArgument(1)) and //com.sun.jndi.ldap.object.disableEndpointIdentification=true + ma2.getQualifier().(VarAccess).getVariable().getAnAccess() = ma.getArgument(0) // systemProps.setProperties(properties) + ) + ) +} + +from MethodAccess ma +where + isInsecureSSLEndpoint(ma) and + not isTestMethod(ma) +select ma, "LDAPS configuration allows insecure endpoint identification" diff --git a/java/ql/src/experimental/Security/CWE/CWE-297/InsecureLdapEndpoint2.java b/java/ql/src/experimental/Security/CWE/CWE-297/InsecureLdapEndpoint2.java new file mode 100644 index 00000000000..2a5c3c87bc7 --- /dev/null +++ b/java/ql/src/experimental/Security/CWE/CWE-297/InsecureLdapEndpoint2.java @@ -0,0 +1,17 @@ +public class InsecureLdapEndpoint2 { + public Hashtable createConnectionEnv() { + Hashtable env = new Hashtable(); + env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory"); + env.put(Context.PROVIDER_URL, "ldaps://ad.your-server.com:636"); + + env.put(Context.SECURITY_AUTHENTICATION, "simple"); + env.put(Context.SECURITY_PRINCIPAL, "username"); + env.put(Context.SECURITY_CREDENTIALS, "secpassword"); + + // GOOD - No configuration to disable SSL endpoint check since it is enabled by default. + { + } + + return env; + } +} diff --git a/java/ql/src/experimental/Security/CWE/CWE-312/CleartextStorageSharedPrefs.ql b/java/ql/src/experimental/Security/CWE/CWE-312/CleartextStorageSharedPrefs.ql index fcfe3f82651..b10741c2048 100644 --- a/java/ql/src/experimental/Security/CWE/CWE-312/CleartextStorageSharedPrefs.ql +++ b/java/ql/src/experimental/Security/CWE/CWE-312/CleartextStorageSharedPrefs.ql @@ -1,7 +1,11 @@ /** * @name Cleartext storage of sensitive information using `SharedPreferences` on Android - * @description Cleartext Storage of Sensitive Information using SharedPreferences on Android allows access for users with root privileges or unexpected exposure from chained vulnerabilities. + * @description Cleartext Storage of Sensitive Information using + * SharedPreferences on Android allows access for users with root + * privileges or unexpected exposure from chained vulnerabilities. * @kind problem + * @problem.severity warning + * @precision medium * @id java/android/cleartext-storage-shared-prefs * @tags security * external/cwe/cwe-312 diff --git a/java/ql/src/experimental/Security/CWE/CWE-326/InsufficientKeySize.ql b/java/ql/src/experimental/Security/CWE/CWE-326/InsufficientKeySize.ql index 41242a44805..155d05abfae 100644 --- a/java/ql/src/experimental/Security/CWE/CWE-326/InsufficientKeySize.ql +++ b/java/ql/src/experimental/Security/CWE/CWE-326/InsufficientKeySize.ql @@ -2,6 +2,8 @@ * @name Weak encryption: Insufficient key size * @description Finds uses of encryption algorithms with too small a key size * @kind problem + * @problem.severity warning + * @precision medium * @id java/insufficient-key-size * @tags security * external/cwe/cwe-326 diff --git a/java/ql/src/experimental/Security/CWE/CWE-346/UnvalidatedCors.java b/java/ql/src/experimental/Security/CWE/CWE-346/UnvalidatedCors.java new file mode 100644 index 00000000000..fd562d44f30 --- /dev/null +++ b/java/ql/src/experimental/Security/CWE/CWE-346/UnvalidatedCors.java @@ -0,0 +1,45 @@ +import java.io.IOException; + +import javax.servlet.Filter; +import javax.servlet.FilterChain; +import javax.servlet.FilterConfig; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.commons.lang3.StringUtils; + +public class CorsFilter implements Filter { + public void init(FilterConfig filterConfig) throws ServletException {} + + public void doFilter(ServletRequest req, ServletResponse res, + FilterChain chain) throws IOException, ServletException { + HttpServletRequest request = (HttpServletRequest) req; + HttpServletResponse response = (HttpServletResponse) res; + String url = request.getHeader("Origin"); + + if (!StringUtils.isEmpty(url)) { + String val = response.getHeader("Access-Control-Allow-Origin"); + + if (StringUtils.isEmpty(val)) { + response.addHeader("Access-Control-Allow-Origin", url); // BAD -> User controlled CORS header being set here. + response.addHeader("Access-Control-Allow-Credentials", "true"); + } + } + + if (!StringUtils.isEmpty(url)) { + List checkorigins = Arrays.asList("www.example.com", "www.sub.example.com"); + + if (checkorigins.contains(url)) { // GOOD -> Origin is validated here. + response.addHeader("Access-Control-Allow-Origin", url); + response.addHeader("Access-Control-Allow-Credentials", "true"); + } + } + + chain.doFilter(req, res); + } + + public void destroy() {} +} diff --git a/java/ql/src/experimental/Security/CWE/CWE-346/UnvalidatedCors.qhelp b/java/ql/src/experimental/Security/CWE/CWE-346/UnvalidatedCors.qhelp new file mode 100644 index 00000000000..da98e896a60 --- /dev/null +++ b/java/ql/src/experimental/Security/CWE/CWE-346/UnvalidatedCors.qhelp @@ -0,0 +1,76 @@ + + + + +

    + + A server can send the + Access-Control-Allow-Credentials CORS header to control + when a browser may send user credentials in Cross-Origin HTTP + requests. + +

    +

    + + When the Access-Control-Allow-Credentials header + is true, the Access-Control-Allow-Origin + header must have a value different from * in order + for browsers to accept the header. Therefore, to allow multiple origins + for cross-origin requests with credentials, the server must + dynamically compute the value of the + Access-Control-Allow-Origin header. Computing this + header value from information in the request to the server can + therefore potentially allow an attacker to control the origins that + the browser sends credentials to. + +

    + + + +
    + + +

    + + When the Access-Control-Allow-Credentials header + value is true, a dynamic computation of the + Access-Control-Allow-Origin header must involve + sanitization if it relies on user-controlled input. + + +

    +

    + + Since the null origin is easy to obtain for an + attacker, it is never safe to use null as the value of + the Access-Control-Allow-Origin header when the + Access-Control-Allow-Credentials header value is + true.A null origin can be set by an attacker using a sandboxed iframe. + A more detailed explanation is available in the portswigger blogpost referenced below. + +

    +
    + + +

    + + In the example below, the server allows the browser to send + user credentials in a cross-origin request. The request header + origins controls the allowed origins for such a + Cross-Origin request. + +

    + + + +
    + + +
  • Mozilla Developer Network: CORS, Access-Control-Allow-Origin.
  • +
  • Mozilla Developer Network: CORS, Access-Control-Allow-Credentials.
  • +
  • PortSwigger: Exploiting CORS Misconfigurations for Bitcoins and Bounties
  • +
  • W3C: CORS for developers, Advice for Resource Owners
  • +
    +
    diff --git a/java/ql/src/experimental/Security/CWE/CWE-346/UnvalidatedCors.ql b/java/ql/src/experimental/Security/CWE/CWE-346/UnvalidatedCors.ql new file mode 100644 index 00000000000..c5a6c36d6a6 --- /dev/null +++ b/java/ql/src/experimental/Security/CWE/CWE-346/UnvalidatedCors.ql @@ -0,0 +1,86 @@ +/** + * @name CORS is derived from untrusted input + * @description CORS header is derived from untrusted input, allowing a remote user to control which origins are trusted. + * @kind path-problem + * @problem.severity error + * @precision high + * @id java/unvalidated-cors-origin-set + * @tags security + * external/cwe/cwe-346 + */ + +import java +import semmle.code.java.dataflow.FlowSources +import semmle.code.java.frameworks.Servlets +import semmle.code.java.dataflow.TaintTracking +import semmle.code.java.dataflow.TaintTracking2 +import DataFlow::PathGraph + +/** + * Holds if `header` sets `Access-Control-Allow-Credentials` to `true`. This ensures fair chances of exploitability. + */ +private predicate setsAllowCredentials(MethodAccess header) { + ( + header.getMethod() instanceof ResponseSetHeaderMethod or + header.getMethod() instanceof ResponseAddHeaderMethod + ) and + header.getArgument(0).(CompileTimeConstantExpr).getStringValue().toLowerCase() = + "access-control-allow-credentials" and + header.getArgument(1).(CompileTimeConstantExpr).getStringValue().toLowerCase() = "true" +} + +private class CorsProbableCheckAccess extends MethodAccess { + CorsProbableCheckAccess() { + getMethod().hasName("contains") and + getMethod().getDeclaringType().getASourceSupertype*() instanceof CollectionType + or + getMethod().hasName("containsKey") and + getMethod().getDeclaringType().getASourceSupertype*() instanceof MapType + or + getMethod().hasName("equals") and + getQualifier().getType() instanceof TypeString + } +} + +private Expr getAccessControlAllowOriginHeaderName() { + result.(CompileTimeConstantExpr).getStringValue().toLowerCase() = "access-control-allow-origin" +} + +/** + * This taintflow2 configuration checks if there is a flow from source node towards CorsProbableCheckAccess methods. + */ +class CorsSourceReachesCheckConfig extends TaintTracking2::Configuration { + CorsSourceReachesCheckConfig() { this = "CorsOriginConfig" } + + override predicate isSource(DataFlow::Node source) { any(CorsOriginConfig c).hasFlow(source, _) } + + override predicate isSink(DataFlow::Node sink) { + sink.asExpr() = any(CorsProbableCheckAccess check).getAnArgument() + } +} + +private class CorsOriginConfig extends TaintTracking::Configuration { + CorsOriginConfig() { this = "CorsOriginConfig" } + + override predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource } + + override predicate isSink(DataFlow::Node sink) { + exists(MethodAccess corsHeader, MethodAccess allowCredentialsHeader | + ( + corsHeader.getMethod() instanceof ResponseSetHeaderMethod or + corsHeader.getMethod() instanceof ResponseAddHeaderMethod + ) and + getAccessControlAllowOriginHeaderName() = corsHeader.getArgument(0) and + setsAllowCredentials(allowCredentialsHeader) and + corsHeader.getEnclosingCallable() = allowCredentialsHeader.getEnclosingCallable() and + sink.asExpr() = corsHeader.getArgument(1) + ) + } +} + +from + DataFlow::PathNode source, DataFlow::PathNode sink, CorsOriginConfig conf, + CorsSourceReachesCheckConfig sanconf +where conf.hasFlowPath(source, sink) and not sanconf.hasFlow(source.getNode(), _) +select sink.getNode(), source, sink, "CORS header is being set using user controlled value $@.", + source.getNode(), "user-provided value" diff --git a/java/ql/src/experimental/Security/CWE/CWE-352/JsonStringLib.qll b/java/ql/src/experimental/Security/CWE/CWE-352/JsonStringLib.qll new file mode 100644 index 00000000000..b8f1a13b119 --- /dev/null +++ b/java/ql/src/experimental/Security/CWE/CWE-352/JsonStringLib.qll @@ -0,0 +1,57 @@ +import java +import semmle.code.java.dataflow.DataFlow +import semmle.code.java.dataflow.FlowSources +import DataFlow::PathGraph + +/** Json string type data. */ +abstract class JsonStringSource extends DataFlow::Node { } + +/** + * Convert to String using Gson library. * + * + * For example, in the method access `Gson.toJson(...)`, + * the `Object` type data is converted to the `String` type data. + */ +private class GsonString extends JsonStringSource { + GsonString() { + exists(MethodAccess ma, Method m | ma.getMethod() = m | + m.hasName("toJson") and + m.getDeclaringType().getASupertype*().hasQualifiedName("com.google.gson", "Gson") and + this.asExpr() = ma + ) + } +} + +/** + * Convert to String using Fastjson library. + * + * For example, in the method access `JSON.toJSONString(...)`, + * the `Object` type data is converted to the `String` type data. + */ +private class FastjsonString extends JsonStringSource { + FastjsonString() { + exists(MethodAccess ma, Method m | ma.getMethod() = m | + m.hasName("toJSONString") and + m.getDeclaringType().getASupertype*().hasQualifiedName("com.alibaba.fastjson", "JSON") and + this.asExpr() = ma + ) + } +} + +/** + * Convert to String using Jackson library. + * + * For example, in the method access `ObjectMapper.writeValueAsString(...)`, + * the `Object` type data is converted to the `String` type data. + */ +private class JacksonString extends JsonStringSource { + JacksonString() { + exists(MethodAccess ma, Method m | ma.getMethod() = m | + m.hasName("writeValueAsString") and + m.getDeclaringType() + .getASupertype*() + .hasQualifiedName("com.fasterxml.jackson.databind", "ObjectMapper") and + this.asExpr() = ma + ) + } +} diff --git a/java/ql/src/experimental/Security/CWE/CWE-352/JsonpInjection.java b/java/ql/src/experimental/Security/CWE/CWE-352/JsonpInjection.java new file mode 100644 index 00000000000..8f39efbc2b6 --- /dev/null +++ b/java/ql/src/experimental/Security/CWE/CWE-352/JsonpInjection.java @@ -0,0 +1,161 @@ +import com.alibaba.fastjson.JSONObject; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.google.gson.Gson; +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.PrintWriter; +import java.util.HashMap; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.multipart.MultipartFile; + +@Controller +public class JsonpInjection { + + private static HashMap hashMap = new HashMap(); + + static { + hashMap.put("username","admin"); + hashMap.put("password","123456"); + } + + @GetMapping(value = "jsonp1") + @ResponseBody + public String bad1(HttpServletRequest request) { + String resultStr = null; + String jsonpCallback = request.getParameter("jsonpCallback"); + Gson gson = new Gson(); + String result = gson.toJson(hashMap); + resultStr = jsonpCallback + "(" + result + ")"; + return resultStr; + } + + @GetMapping(value = "jsonp2") + @ResponseBody + public String bad2(HttpServletRequest request) { + String resultStr = null; + String jsonpCallback = request.getParameter("jsonpCallback"); + resultStr = jsonpCallback + "(" + JSONObject.toJSONString(hashMap) + ")"; + return resultStr; + } + + @GetMapping(value = "jsonp3") + @ResponseBody + public String bad3(HttpServletRequest request) { + String resultStr = null; + String jsonpCallback = request.getParameter("jsonpCallback"); + String jsonStr = getJsonStr(hashMap); + resultStr = jsonpCallback + "(" + jsonStr + ")"; + return resultStr; + } + + @GetMapping(value = "jsonp4") + @ResponseBody + public String bad4(HttpServletRequest request) { + String resultStr = null; + String jsonpCallback = request.getParameter("jsonpCallback"); + String restr = JSONObject.toJSONString(hashMap); + resultStr = jsonpCallback + "(" + restr + ");"; + return resultStr; + } + + @GetMapping(value = "jsonp5") + @ResponseBody + public void bad5(HttpServletRequest request, + HttpServletResponse response) throws Exception { + String jsonpCallback = request.getParameter("jsonpCallback"); + PrintWriter pw = null; + Gson gson = new Gson(); + String result = gson.toJson(hashMap); + String resultStr = null; + pw = response.getWriter(); + resultStr = jsonpCallback + "(" + result + ")"; + pw.println(resultStr); + } + + @GetMapping(value = "jsonp6") + @ResponseBody + public void bad6(HttpServletRequest request, + HttpServletResponse response) throws Exception { + String jsonpCallback = request.getParameter("jsonpCallback"); + PrintWriter pw = null; + ObjectMapper mapper = new ObjectMapper(); + String result = mapper.writeValueAsString(hashMap); + String resultStr = null; + pw = response.getWriter(); + resultStr = jsonpCallback + "(" + result + ")"; + pw.println(resultStr); + } + + @RequestMapping(value = "jsonp7", method = RequestMethod.GET) + @ResponseBody + public String bad7(HttpServletRequest request) { + String resultStr = null; + String jsonpCallback = request.getParameter("jsonpCallback"); + Gson gson = new Gson(); + String result = gson.toJson(hashMap); + resultStr = jsonpCallback + "(" + result + ")"; + return resultStr; + } + + @RequestMapping(value = "jsonp11") + @ResponseBody + public String good1(HttpServletRequest request) { + JSONObject parameterObj = readToJSONObect(request); + String resultStr = null; + String jsonpCallback = request.getParameter("jsonpCallback"); + String restr = JSONObject.toJSONString(hashMap); + resultStr = jsonpCallback + "(" + restr + ");"; + return resultStr; + } + + @RequestMapping(value = "jsonp12") + @ResponseBody + public String good2(@RequestParam("file") MultipartFile file,HttpServletRequest request) { + if(null == file){ + return "upload file error"; + } + String fileName = file.getOriginalFilename(); + System.out.println("file operations"); + String resultStr = null; + String jsonpCallback = request.getParameter("jsonpCallback"); + String restr = JSONObject.toJSONString(hashMap); + resultStr = jsonpCallback + "(" + restr + ");"; + return resultStr; + } + + public static JSONObject readToJSONObect(HttpServletRequest request){ + String jsonText = readPostContent(request); + JSONObject jsonObj = JSONObject.parseObject(jsonText, JSONObject.class); + return jsonObj; + } + + public static String readPostContent(HttpServletRequest request){ + BufferedReader in= null; + String content = null; + String line = null; + try { + in = new BufferedReader(new InputStreamReader(request.getInputStream(),"UTF-8")); + StringBuilder buf = new StringBuilder(); + while ((line = in.readLine()) != null) { + buf.append(line); + } + content = buf.toString(); + } catch (IOException e) { + e.printStackTrace(); + } + String uri = request.getRequestURI(); + return content; + } + + public static String getJsonStr(Object result) { + return JSONObject.toJSONString(result); + } +} \ No newline at end of file diff --git a/java/ql/src/experimental/Security/CWE/CWE-352/JsonpInjection.qhelp b/java/ql/src/experimental/Security/CWE/CWE-352/JsonpInjection.qhelp new file mode 100644 index 00000000000..e8fb89d3989 --- /dev/null +++ b/java/ql/src/experimental/Security/CWE/CWE-352/JsonpInjection.qhelp @@ -0,0 +1,37 @@ + + + +

    The software uses external input as the function name to wrap JSON data and returns it to the client as a request response. +When there is a cross-domain problem, this could lead to information leakage.

    + +
    + + +

    Adding Referer/Origin or random token verification processing can effectively prevent the leakage of sensitive information.

    + +
    + + +

    The following examples show the bad case and the good case respectively. Bad cases, such as bad1 to bad7, +will cause information leakage when there are cross-domain problems. In a good case, for example, in the good1 +method and the good2 method, When these two methods process the request, there must be a request body in the request, which does not meet the conditions of Jsonp injection.

    + + + +
    + + +
  • +OWASPLondon20161124_JSON_Hijacking_Gareth_Heyes: +JSON hijacking. +
  • +
  • +Practical JSONP Injection: + + Completely controllable from the URL (GET variable) +. +
  • +
    +
    diff --git a/java/ql/src/experimental/Security/CWE/CWE-352/JsonpInjection.ql b/java/ql/src/experimental/Security/CWE/CWE-352/JsonpInjection.ql new file mode 100644 index 00000000000..71ee842f162 --- /dev/null +++ b/java/ql/src/experimental/Security/CWE/CWE-352/JsonpInjection.ql @@ -0,0 +1,45 @@ +/** + * @name JSONP Injection + * @description User-controlled callback function names that are not verified are vulnerable + * to jsonp injection attacks. + * @kind path-problem + * @problem.severity error + * @precision high + * @id java/jsonp-injection + * @tags security + * external/cwe/cwe-352 + */ + +import java +import JsonpInjectionLib +import semmle.code.java.dataflow.FlowSources +import semmle.code.java.deadcode.WebEntryPoints +import DataFlow::PathGraph + +/** Taint-tracking configuration tracing flow from get method request sources to output jsonp data. */ +class RequestResponseFlowConfig extends TaintTracking::Configuration { + RequestResponseFlowConfig() { this = "RequestResponseFlowConfig" } + + override predicate isSource(DataFlow::Node source) { + source instanceof RemoteFlowSource and + any(RequestGetMethod m).polyCalls*(source.getEnclosingCallable()) + } + + override predicate isSink(DataFlow::Node sink) { + sink instanceof XssSink and + any(RequestGetMethod m).polyCalls*(sink.getEnclosingCallable()) + } + + override predicate isAdditionalTaintStep(DataFlow::Node pred, DataFlow::Node succ) { + exists(MethodAccess ma | + isRequestGetParamMethod(ma) and pred.asExpr() = ma.getQualifier() and succ.asExpr() = ma + ) + } +} + +from DataFlow::PathNode source, DataFlow::PathNode sink, RequestResponseFlowConfig conf +where + conf.hasFlowPath(source, sink) and + exists(JsonpInjectionFlowConfig jhfc | jhfc.hasFlowTo(sink.getNode())) +select sink.getNode(), source, sink, "Jsonp response might include code from $@.", source.getNode(), + "this user input" diff --git a/java/ql/src/experimental/Security/CWE/CWE-352/JsonpInjectionLib.qll b/java/ql/src/experimental/Security/CWE/CWE-352/JsonpInjectionLib.qll new file mode 100644 index 00000000000..6da4f87294a --- /dev/null +++ b/java/ql/src/experimental/Security/CWE/CWE-352/JsonpInjectionLib.qll @@ -0,0 +1,118 @@ +import java +import DataFlow +import JsonStringLib +import semmle.code.java.security.XSS +import semmle.code.java.dataflow.DataFlow +import semmle.code.java.dataflow.DataFlow3 +import semmle.code.java.dataflow.FlowSources +import semmle.code.java.frameworks.spring.SpringController + +/** + * A method that is called to handle an HTTP GET request. + */ +abstract class RequestGetMethod extends Method { + RequestGetMethod() { + not exists(MethodAccess ma | + // Exclude apparent GET handlers that read a request entity, because this likely indicates this is not in fact a GET handler. + // This is particularly a problem with Spring handlers, which can sometimes neglect to specify a request method. + // Even if it is in fact a GET handler, such a request method will be unusable in the context `
  • Wikipedia: Duplicate code.