Compare commits

..

1 Commits

Author SHA1 Message Date
erik-krogh
9109546adb sync up the QL extractor with the Ruby one 2022-11-20 14:19:01 +01:00
418 changed files with 7015 additions and 11352 deletions

View File

@@ -1,61 +0,0 @@
name: Cache query compilation
description: Caches CodeQL compilation caches - should be run both on PRs and pushes to main.
inputs:
key:
description: 'The cache key to use - should be unique to the workflow'
required: true
outputs:
cache-dir:
description: "The directory where the cache was stored"
value: ${{ steps.fill-compilation-dir.outputs.compdir }}
runs:
using: composite
steps:
# Cache the query compilation caches.
# calculate the merge-base with main, in a way that works both on PRs and pushes to main.
- name: Calculate merge-base
shell: bash
if: ${{ github.event_name == 'pull_request' }}
env:
BASE_BRANCH: ${{ github.base_ref }}
run: |
MERGE_BASE=$(git cat-file commit $GITHUB_SHA | grep '^parent ' | head -1 | cut -f 2 -d " ")
echo "merge_base=$MERGE_BASE" >> $GITHUB_ENV
- name: Read CodeQL query compilation - PR
if: ${{ github.event_name == 'pull_request' }}
uses: erik-krogh/actions-cache@a88d0603fe5fb5606db9f002dfcadeb32b5f84c6
with:
path: '**/.cache'
read-only: true
key: codeql-compile-${{ inputs.key }}-pr-${{ github.sha }} # deliberately not using the `compile-compile-main` keys here.
restore-keys: |
codeql-compile-${{ inputs.key }}-${{ github.base_ref }}-${{ env.merge_base }}
codeql-compile-${{ inputs.key }}-${{ github.base_ref }}-
codeql-compile-${{ inputs.key }}-main-
- name: Fill CodeQL query compilation cache - main
if: ${{ github.event_name != 'pull_request' }}
uses: erik-krogh/actions-cache@a88d0603fe5fb5606db9f002dfcadeb32b5f84c6
with:
path: '**/.cache'
key: codeql-compile-${{ inputs.key }}-${{ github.ref_name }}-${{ github.sha }} # just fill on main
restore-keys: | # restore from another random commit, to speed up compilation.
codeql-compile-${{ inputs.key }}-${{ github.ref_name }}-
codeql-compile-${{ inputs.key }}-main-
- name: Fill compilation cache directory
id: fill-compilation-dir
shell: bash
run: |
# Move all the existing cache into another folder, so we only preserve the cache for the current queries.
mkdir -p ${COMBINED_CACHE_DIR}
rm -f **/.cache/{lock,size} # -f to avoid errors if the cache is empty.
# copy the contents of the .cache folders into the combined cache folder.
cp -r **/.cache/* ${COMBINED_CACHE_DIR}/ || : # ignore missing files
# clean up the .cache folders
rm -rf **/.cache/*
echo "compdir=${COMBINED_CACHE_DIR}" >> $GITHUB_OUTPUT
env:
COMBINED_CACHE_DIR: ${{ github.workspace }}/compilation-dir

View File

@@ -14,26 +14,58 @@ jobs:
steps:
- uses: actions/checkout@v3
# calculate the merge-base with main, in a way that works both on PRs and pushes to main.
- name: Calculate merge-base
if: ${{ github.event_name == 'pull_request' }}
env:
BASE_BRANCH: ${{ github.base_ref }}
run: |
MERGE_BASE=$(git cat-file commit $GITHUB_SHA | grep '^parent ' | head -1 | cut -f 2 -d " ")
echo "merge-base=$MERGE_BASE" >> $GITHUB_ENV
- name: Read CodeQL query compilation - PR
if: ${{ github.event_name == 'pull_request' }}
uses: actions/cache@v3
with:
path: '**/.cache'
key: codeql-compile-pr-${{ github.sha }} # deliberately not using the `compile-compile-main` keys here.
restore-keys: |
codeql-compile-${{ github.base_ref }}-${{ env.merge-base }}
codeql-compile-${{ github.base_ref }}-
codeql-compile-main-
- name: Fill CodeQL query compilation cache - main
if: ${{ github.event_name != 'pull_request' }}
uses: actions/cache@v3
with:
path: '**/.cache'
key: codeql-compile-${{ github.ref_name }}-${{ github.sha }} # just fill on main
restore-keys: | # restore from another random commit, to speed up compilation.
codeql-compile-${{ github.ref_name }}-
codeql-compile-main-
- name: Setup CodeQL
uses: ./.github/actions/fetch-codeql
with:
channel: 'release'
- name: Cache compilation cache
id: query-cache
uses: ./.github/actions/cache-query-compilation
with:
key: all-queries
- name: check formatting
run: find */ql -type f \( -name "*.qll" -o -name "*.ql" \) -print0 | xargs -0 codeql query format --check-only
- name: compile queries - check-only
# run with --check-only if running in a PR (github.sha != main)
if : ${{ github.event_name == 'pull_request' }}
shell: bash
run: codeql query compile -j0 */ql/{src,examples} --keep-going --warnings=error --check-only --compilation-cache "${{ steps.query-cache.outputs.cache-dir }}"
run: codeql query compile -j0 */ql/{src,examples} --keep-going --warnings=error --check-only
- name: compile queries - full
# do full compile if running on main - this populates the cache
if : ${{ github.event_name != 'pull_request' }}
shell: bash
run: codeql query compile -j0 */ql/{src,examples} --keep-going --warnings=error --compilation-cache "${{ steps.query-cache.outputs.cache-dir }}"
run: |
# Move all the existing cache into another folder, so we only preserve the cache for the current queries.
mkdir -p ${COMBINED_CACHE_DIR}
rm -f */ql/{src,examples}/.cache/{lock,size} # -f to avoid errors if the cache is empty.
# copy the contents of the .cache folders into the combined cache folder.
cp -r */ql/{src,examples}/.cache/* ${COMBINED_CACHE_DIR}/ || : # ignore missing files
# clean up the .cache folders
rm -rf */ql/{src,examples}/.cache/*
# compile the queries
codeql query compile -j0 */ql/{src,examples} --keep-going --warnings=error --compilation-cache ${COMBINED_CACHE_DIR}
env:
COMBINED_CACHE_DIR: ${{ github.workspace }}/compilation-dir

View File

@@ -1,86 +0,0 @@
name: "C#: Run QL Tests"
on:
push:
paths:
- "csharp/**"
- "shared/**"
- .github/actions/fetch-codeql/action.yml
- codeql-workspace.yml
branches:
- main
- "rc/*"
pull_request:
paths:
- "csharp/**"
- "shared/**"
- .github/workflows/csharp-qltest.yml
- .github/actions/fetch-codeql/action.yml
- codeql-workspace.yml
branches:
- main
- "rc/*"
defaults:
run:
working-directory: csharp
jobs:
qlupgrade:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: ./.github/actions/fetch-codeql
- name: Check DB upgrade scripts
run: |
echo >empty.trap
codeql dataset import -S ql/lib/upgrades/initial/semmlecode.csharp.dbscheme testdb empty.trap
codeql dataset upgrade testdb --additional-packs ql/lib
diff -q testdb/semmlecode.csharp.dbscheme ql/lib/semmlecode.csharp.dbscheme
- name: Check DB downgrade scripts
run: |
echo >empty.trap
rm -rf testdb; codeql dataset import -S ql/lib/semmlecode.csharp.dbscheme testdb empty.trap
codeql resolve upgrades --format=lines --allow-downgrades --additional-packs downgrades \
--dbscheme=ql/lib/semmlecode.csharp.dbscheme --target-dbscheme=downgrades/initial/semmlecode.csharp.dbscheme |
xargs codeql execute upgrades testdb
diff -q testdb/semmlecode.csharp.dbscheme downgrades/initial/semmlecode.csharp.dbscheme
qltest:
runs-on: ubuntu-latest-xl
strategy:
fail-fast: false
matrix:
slice: ["1/2", "2/2"]
steps:
- uses: actions/checkout@v3
- uses: ./.github/actions/fetch-codeql
- uses: ./csharp/actions/create-extractor-pack
- name: Cache compilation cache
id: query-cache
uses: ./.github/actions/cache-query-compilation
with:
key: csharp-qltest-${{ matrix.slice }}
- name: Run QL tests
run: |
CODEQL_PATH=$(gh codeql version --format=json | jq -r .unpackedLocation)
# The legacy ASP extractor is not in this repo, so take the one from the nightly build
mv "$CODEQL_PATH/csharp/tools/extractor-asp.jar" "${{ github.workspace }}/csharp/extractor-pack/tools"
# Safe guard against using the bundled extractor
rm -rf "$CODEQL_PATH/csharp"
codeql test run --threads=0 --ram 52000 --slice ${{ matrix.slice }} --search-path "${{ github.workspace }}/csharp/extractor-pack" --check-databases --check-undefined-labels --check-repeated-labels --check-redefined-labels --consistency-queries ql/consistency-queries ql/test --compilation-cache "${{ steps.query-cache.outputs.cache-dir }}"
env:
GITHUB_TOKEN: ${{ github.token }}
unit-tests:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Setup dotnet
uses: actions/setup-dotnet@v3
with:
dotnet-version: 6.0.202
- name: Extractor unit tests
run: |
dotnet test -p:RuntimeFrameworkVersion=6.0.4 "${{ github.workspace }}/csharp/extractor/Semmle.Util.Tests"
dotnet test -p:RuntimeFrameworkVersion=6.0.4 "${{ github.workspace }}/csharp/extractor/Semmle.Extraction.Tests"
dotnet test -p:RuntimeFrameworkVersion=6.0.4 "${{ github.workspace }}/csharp/autobuilder/Semmle.Autobuild.CSharp.Tests"
dotnet test -p:RuntimeFrameworkVersion=6.0.4 "${{ github.workspace }}/cpp/autobuilder/Semmle.Autobuild.Cpp.Tests"

View File

@@ -47,3 +47,8 @@ jobs:
find ql/ql/src "(" -name "*.ql" -or -name "*.qll" ")" -print0 | xargs -0 "${CODEQL}" query format --check-only
env:
CODEQL: ${{ steps.find-codeql.outputs.codeql-path }}
- name: Check QL compilation
run: |
"${CODEQL}" query compile --check-only --threads=4 --warnings=error --search-path "${{ github.workspace }}/ql/extractor-pack" "ql/ql/src" "ql/ql/examples"
env:
CODEQL: ${{ steps.find-codeql.outputs.codeql-path }}

View File

@@ -86,24 +86,19 @@ jobs:
ruby/target/release/ruby-extractor.exe
retention-days: 1
compile-queries:
runs-on: ubuntu-latest-xl
runs-on: ubuntu-latest
env:
CODEQL_THREADS: 4 # TODO: remove this once it's set by the CLI
steps:
- uses: actions/checkout@v3
- name: Fetch CodeQL
uses: ./.github/actions/fetch-codeql
- name: Cache compilation cache
id: query-cache
uses: ./.github/actions/cache-query-compilation
with:
key: ruby-build
- name: Build Query Pack
run: |
rm -rf target/packs
codeql pack create ../shared/ssa --output target/packs
codeql pack create ../misc/suite-helpers --output target/packs
codeql pack create ../shared/regex --output target/packs
codeql pack create ql/lib --output target/packs
codeql pack create -j0 ql/src --output target/packs --compilation-cache "${{ steps.query-cache.outputs.cache-dir }}"
codeql pack create ql/src --output target/packs
PACK_FOLDER=$(readlink -f target/packs/codeql/ruby-queries/*)
codeql generate query-help --format=sarifv2.1.0 --output="${PACK_FOLDER}/rules.sarif" ql/src
(cd ql/src; find queries \( -name '*.qhelp' -o -name '*.rb' -o -name '*.erb' \) -exec bash -c 'mkdir -p "'"${PACK_FOLDER}"'/$(dirname "{}")"' \; -exec cp "{}" "${PACK_FOLDER}/{}" \;)

View File

@@ -4,7 +4,7 @@ on:
push:
paths:
- "ruby/**"
- .github/workflows/ruby-build.yml
- .github/workflows/ruby-qltest.yml
- .github/actions/fetch-codeql/action.yml
- codeql-workspace.yml
branches:
@@ -28,6 +28,16 @@ defaults:
working-directory: ruby
jobs:
qlcompile:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: ./.github/actions/fetch-codeql
- name: Check QL compilation
run: |
codeql query compile --check-only --threads=0 --ram 5000 --warnings=error "ql/src" "ql/examples"
env:
GITHUB_TOKEN: ${{ github.token }}
qlupgrade:
runs-on: ubuntu-latest
steps:
@@ -48,20 +58,17 @@ jobs:
xargs codeql execute upgrades testdb
diff -q testdb/ruby.dbscheme downgrades/initial/ruby.dbscheme
qltest:
runs-on: ubuntu-latest-xl
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
slice: ["1/2", "2/2"]
steps:
- uses: actions/checkout@v3
- uses: ./.github/actions/fetch-codeql
- uses: ./ruby/actions/create-extractor-pack
- name: Cache compilation cache
id: query-cache
uses: ./.github/actions/cache-query-compilation
with:
key: ruby-qltest
- name: Run QL tests
run: |
codeql test run --threads=0 --ram 52000 --search-path "${{ github.workspace }}/ruby/extractor-pack" --check-databases --check-undefined-labels --check-unused-labels --check-repeated-labels --check-redefined-labels --check-use-before-definition --consistency-queries ql/consistency-queries ql/test --compilation-cache "${{ steps.query-cache.outputs.cache-dir }}"
codeql test run --threads=0 --ram 5000 --slice ${{ matrix.slice }} --search-path "${{ github.workspace }}/ruby/extractor-pack" --check-databases --check-unused-labels --check-repeated-labels --check-redefined-labels --check-use-before-definition --consistency-queries ql/consistency-queries ql/test
env:
GITHUB_TOKEN: ${{ github.token }}

View File

@@ -39,7 +39,6 @@ jobs:
- 'swift/ql/lib/codeql/swift/elements/**'
- 'swift/ql/lib/codeql/swift/generated/**'
- 'swift/ql/test/extractor-tests/generated/**'
- 'swift/ql/.generated.list'
ql:
- 'github/workflows/swift.yml'
- 'swift/**/*.ql'

2
.gitignore vendored
View File

@@ -27,6 +27,8 @@
# It's useful (though not required) to be able to unpack codeql in the ql checkout itself
/codeql/
csharp/extractor/Semmle.Extraction.CSharp.Driver/Properties/launchSettings.json
# Avoid committing cached package components
.codeql

View File

@@ -44,7 +44,7 @@ repos:
- id: swift-codegen
name: Run Swift checked in code generation
files: ^swift/(schema.py$|codegen/|.*/generated/|ql/lib/(swift\.dbscheme$|codeql/swift/elements)|ql/\.generated.list)
files: ^swift/(schema.py$|codegen/|.*/generated/|ql/lib/(swift\.dbscheme$|codeql/swift/elements))
language: system
entry: bazel run //swift/codegen -- --quiet
pass_filenames: false

View File

@@ -1,5 +1,3 @@
{
"omnisharp.autoStart": false,
"cmake.sourceDirectory": "${workspaceFolder}/swift",
"cmake.buildDirectory": "${workspaceFolder}/bazel-cmake-build"
"omnisharp.autoStart": false
}

View File

@@ -5,7 +5,7 @@
/javascript/ @github/codeql-javascript
/python/ @github/codeql-python
/ruby/ @github/codeql-ruby
/swift/ @github/codeql-swift
/swift/ @github/codeql-c
/java/kotlin-extractor/ @github/codeql-kotlin
/java/kotlin-explorer/ @github/codeql-kotlin
@@ -45,4 +45,4 @@ WORKSPACE.bazel @github/codeql-ci-reviewers
/.github/workflows/js-ml-tests.yml @github/codeql-ml-powered-queries-reviewers
/.github/workflows/ql-for-ql-* @github/codeql-ql-for-ql-reviewers
/.github/workflows/ruby-* @github/codeql-ruby
/.github/workflows/swift.yml @github/codeql-swift
/.github/workflows/swift.yml @github/codeql-c

View File

@@ -25,7 +25,7 @@ provide:
- "misc/suite-helpers/qlpack.yml"
- "ruby/extractor-pack/codeql-extractor.yml"
- "swift/extractor-pack/codeql-extractor.yml"
- "ql/extractor-pack/codeql-extractor.yml"
- "ql/extractor-pack/codeql-extractor.ym"
versionPolicies:
default:

View File

@@ -257,11 +257,11 @@ namespace Semmle.Autobuild.Cpp.Tests
Actions.GetCurrentDirectory = cwd;
Actions.IsWindows = isWindows;
var options = new CppAutobuildOptions(Actions);
var options = new AutobuildOptions(Actions, Language.Cpp);
return new CppAutobuilder(Actions, options);
}
void TestAutobuilderScript(CppAutobuilder autobuilder, int expectedOutput, int commandsRun)
void TestAutobuilderScript(Autobuilder autobuilder, int expectedOutput, int commandsRun)
{
Assert.Equal(expectedOutput, autobuilder.GetBuildScript().Run(Actions, StartCallback, EndCallback));
@@ -299,7 +299,7 @@ namespace Semmle.Autobuild.Cpp.Tests
{
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 && msbuild C:\Project\test.sln /t:rebuild /p:Platform=""x86"" /p:Configuration=""Release"""] = 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 /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;
Actions.RunProcess[@"C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe -prerelease -legacy -property installationVersion"] = 0;

View File

@@ -2,26 +2,9 @@
namespace Semmle.Autobuild.Cpp
{
/// <summary>
/// Encapsulates C++ build options.
/// </summary>
public class CppAutobuildOptions : AutobuildOptionsShared
public class CppAutobuilder : Autobuilder
{
public override Language Language => Language.Cpp;
/// <summary>
/// Reads options from environment variables.
/// Throws ArgumentOutOfRangeException for invalid arguments.
/// </summary>
public CppAutobuildOptions(IBuildActions actions) : base(actions)
{
}
}
public class CppAutobuilder : Autobuilder<CppAutobuildOptions>
{
public CppAutobuilder(IBuildActions actions, CppAutobuildOptions options) : base(actions, options) { }
public CppAutobuilder(IBuildActions actions, AutobuildOptions options) : base(actions, options) { }
public override BuildScript GetBuildScript()
{

View File

@@ -11,14 +11,14 @@ namespace Semmle.Autobuild.Cpp
try
{
var actions = SystemBuildActions.Instance;
var options = new CppAutobuildOptions(actions);
var options = new AutobuildOptions(actions, Language.Cpp);
try
{
Console.WriteLine("CodeQL C++ autobuilder");
var builder = new CppAutobuilder(actions, options);
return builder.AttemptBuild();
}
catch (InvalidEnvironmentException ex)
catch(InvalidEnvironmentException ex)
{
Console.WriteLine("The environment is invalid: {0}", ex.Message);
}

View File

@@ -1,7 +1,3 @@
## 0.4.4
No user-facing changes.
## 0.4.3
### Minor Analysis Improvements

View File

@@ -1,6 +0,0 @@
---
category: deprecated
---
* Deprecated `semmle.code.cpp.valuenumbering.GlobalValueNumberingImpl`. Use `semmle.code.cpp.valuenumbering.GlobalValueNumbering`, which exposes the same API.

View File

@@ -1,4 +0,0 @@
---
category: breaking
---
The predicates in the `MustFlow::Configuration` class used by the `MustFlow` library (`semmle.code.cpp.ir.dataflow.MustFlow`) have changed to be defined directly in terms of the C++ IR instead of IR dataflow nodes.

View File

@@ -1,3 +0,0 @@
## 0.4.4
No user-facing changes.

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 0.4.4
lastReleaseVersion: 0.4.3

View File

@@ -1,5 +1,5 @@
name: codeql/cpp-all
version: 0.4.5-dev
version: 0.4.4-dev
groups: cpp
dbscheme: semmlecode.cpp.dbscheme
extractor: cpp

View File

@@ -5,6 +5,7 @@
*/
private import cpp
import semmle.code.cpp.ir.dataflow.DataFlow
private import semmle.code.cpp.ir.IR
/**
@@ -24,18 +25,18 @@ abstract class MustFlowConfiguration extends string {
/**
* Holds if `source` is a relevant data flow source.
*/
abstract predicate isSource(Instruction source);
abstract predicate isSource(DataFlow::Node source);
/**
* Holds if `sink` is a relevant data flow sink.
*/
abstract predicate isSink(Operand sink);
abstract predicate isSink(DataFlow::Node sink);
/**
* Holds if the additional flow step from `node1` to `node2` must be taken
* into account in the analysis.
*/
predicate isAdditionalFlowStep(Operand node1, Instruction node2) { none() }
predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) { none() }
/** Holds if this configuration allows flow from arguments to parameters. */
predicate allowInterproceduralFlow() { any() }
@@ -47,17 +48,17 @@ abstract class MustFlowConfiguration extends string {
* included in the module `PathGraph`.
*/
final predicate hasFlowPath(MustFlowPathNode source, MustFlowPathSink sink) {
this.isSource(source.getInstruction()) and
this.isSource(source.getNode()) and
source.getASuccessor+() = sink
}
}
/** Holds if `node` flows from a source. */
pragma[nomagic]
private predicate flowsFromSource(Instruction node, MustFlowConfiguration config) {
private predicate flowsFromSource(DataFlow::Node node, MustFlowConfiguration config) {
config.isSource(node)
or
exists(Instruction mid |
exists(DataFlow::Node mid |
step(mid, node, config) and
flowsFromSource(mid, pragma[only_bind_into](config))
)
@@ -65,12 +66,12 @@ private predicate flowsFromSource(Instruction node, MustFlowConfiguration config
/** Holds if `node` flows to a sink. */
pragma[nomagic]
private predicate flowsToSink(Instruction node, MustFlowConfiguration config) {
private predicate flowsToSink(DataFlow::Node node, MustFlowConfiguration config) {
flowsFromSource(node, pragma[only_bind_into](config)) and
(
config.isSink(node.getAUse())
config.isSink(node)
or
exists(Instruction mid |
exists(DataFlow::Node mid |
step(node, mid, config) and
flowsToSink(mid, pragma[only_bind_into](config))
)
@@ -197,13 +198,12 @@ private module Cached {
}
cached
predicate step(Instruction nodeFrom, Instruction nodeTo) {
exists(Operand mid |
instructionToOperandStep(nodeFrom, mid) and
operandToInstructionStep(mid, nodeTo)
)
predicate step(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) {
instructionToOperandStep(nodeFrom.asInstruction(), nodeTo.asOperand())
or
flowThroughCallable(nodeFrom, nodeTo)
flowThroughCallable(nodeFrom.asInstruction(), nodeTo.asInstruction())
or
operandToInstructionStep(nodeFrom.asOperand(), nodeTo.asInstruction())
}
}
@@ -213,12 +213,12 @@ private module Cached {
* way around.
*/
pragma[inline]
private IRFunction getEnclosingCallable(Instruction n) {
pragma[only_bind_into](result) = pragma[only_bind_out](n).getEnclosingIRFunction()
private Declaration getEnclosingCallable(DataFlow::Node n) {
pragma[only_bind_into](result) = pragma[only_bind_out](n).getEnclosingCallable()
}
/** Holds if `nodeFrom` flows to `nodeTo`. */
private predicate step(Instruction nodeFrom, Instruction nodeTo, MustFlowConfiguration config) {
private predicate step(DataFlow::Node nodeFrom, DataFlow::Node nodeTo, MustFlowConfiguration config) {
exists(config) and
Cached::step(pragma[only_bind_into](nodeFrom), pragma[only_bind_into](nodeTo)) and
(
@@ -227,37 +227,37 @@ private predicate step(Instruction nodeFrom, Instruction nodeTo, MustFlowConfigu
getEnclosingCallable(nodeFrom) = getEnclosingCallable(nodeTo)
)
or
config.isAdditionalFlowStep(nodeFrom.getAUse(), nodeTo)
config.isAdditionalFlowStep(nodeFrom, nodeTo)
}
private newtype TLocalPathNode =
MkLocalPathNode(Instruction n, MustFlowConfiguration config) {
MkLocalPathNode(DataFlow::Node n, MustFlowConfiguration config) {
flowsToSink(n, config) and
(
config.isSource(n)
or
exists(MustFlowPathNode mid | step(mid.getInstruction(), n, config))
exists(MustFlowPathNode mid | step(mid.getNode(), n, config))
)
}
/** A `Node` that is in a path from a source to a sink. */
class MustFlowPathNode extends TLocalPathNode {
Instruction n;
DataFlow::Node n;
MustFlowPathNode() { this = MkLocalPathNode(n, _) }
/** Gets the underlying node. */
Instruction getInstruction() { result = n }
DataFlow::Node getNode() { result = n }
/** Gets a textual representation of this node. */
string toString() { result = n.getAst().toString() }
string toString() { result = n.toString() }
/** Gets the location of this element. */
Location getLocation() { result = n.getLocation() }
/** Gets a successor node, if any. */
MustFlowPathNode getASuccessor() {
step(this.getInstruction(), result.getInstruction(), this.getConfiguration())
step(this.getNode(), result.getNode(), this.getConfiguration())
}
/** Gets the associated configuration. */
@@ -265,7 +265,7 @@ class MustFlowPathNode extends TLocalPathNode {
}
private class MustFlowPathSink extends MustFlowPathNode {
MustFlowPathSink() { this.getConfiguration().isSink(this.getInstruction().getAUse()) }
MustFlowPathSink() { this.getConfiguration().isSink(this.getNode()) }
}
/**

View File

@@ -1,4 +1,4 @@
/**
/*
* Support for tracking tainted data through the program. This is an alias for
* `semmle.code.cpp.ir.dataflow.DefaultTaintTracking` provided for backwards
* compatibility.

View File

@@ -1,8 +1,4 @@
/**
* DEPRECATED: This library has been replaced with a newer version which
* provides better performance and precision. Use
* `semmle.code.cpp.valuenumbering.GlobalValueNumbering` instead.
*
* Provides an implementation of Global Value Numbering.
* See https://en.wikipedia.org/wiki/Global_value_numbering
*
@@ -225,7 +221,7 @@ private newtype GvnBase =
* expression with this `GVN` and using its `toString` and `getLocation`
* methods.
*/
deprecated class GVN extends GvnBase {
class GVN extends GvnBase {
GVN() { this instanceof GvnBase }
/** Gets an expression that has this GVN. */
@@ -507,7 +503,7 @@ private predicate mk_Deref(GVN p, ControlFlowNode dominator, PointerDereferenceE
/** Gets the global value number of expression `e`. */
cached
deprecated GVN globalValueNumber(Expr e) {
GVN globalValueNumber(Expr e) {
exists(int val, Type t |
mk_IntConst(val, t, e) and
result = GVN_IntConst(val, t)

View File

@@ -1,7 +1,3 @@
## 0.4.4
No user-facing changes.
## 0.4.3
### Minor Analysis Improvements

View File

@@ -26,11 +26,11 @@ predicate intentionallyReturnsStackPointer(Function f) {
class ReturnStackAllocatedMemoryConfig extends MustFlowConfiguration {
ReturnStackAllocatedMemoryConfig() { this = "ReturnStackAllocatedMemoryConfig" }
override predicate isSource(Instruction source) {
override predicate isSource(DataFlow::Node source) {
// Holds if `source` is a node that represents the use of a stack variable
exists(VariableAddressInstruction var, Function func |
var = source and
func = source.getEnclosingFunction() and
var = source.asInstruction() and
func = var.getEnclosingFunction() and
var.getAstVariable() instanceof StackVariable and
// Pointer-to-member types aren't properly handled in the dbscheme.
not var.getResultType() instanceof PointerToMemberType and
@@ -40,7 +40,7 @@ class ReturnStackAllocatedMemoryConfig extends MustFlowConfiguration {
)
}
override predicate isSink(Operand sink) {
override predicate isSink(DataFlow::Node sink) {
// Holds if `sink` is a node that represents the `StoreInstruction` that is subsequently used in
// a `ReturnValueInstruction`.
// We use the `StoreInstruction` instead of the instruction that defines the
@@ -48,7 +48,7 @@ class ReturnStackAllocatedMemoryConfig extends MustFlowConfiguration {
exists(StoreInstruction store |
store.getDestinationAddress().(VariableAddressInstruction).getIRVariable() instanceof
IRReturnVariable and
sink = store.getSourceValueOperand()
sink.asOperand() = store.getSourceValueOperand()
)
}
@@ -77,10 +77,10 @@ class ReturnStackAllocatedMemoryConfig extends MustFlowConfiguration {
* }
* ```
*/
override predicate isAdditionalFlowStep(Operand node1, Instruction node2) {
node2.(FieldAddressInstruction).getObjectAddressOperand() = node1
override predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) {
node2.asInstruction().(FieldAddressInstruction).getObjectAddressOperand() = node1.asOperand()
or
node2.(PointerOffsetInstruction).getLeftOperand() = node1
node2.asInstruction().(PointerOffsetInstruction).getLeftOperand() = node1.asOperand()
}
}
@@ -89,6 +89,6 @@ from
ReturnStackAllocatedMemoryConfig conf
where
conf.hasFlowPath(pragma[only_bind_into](source), pragma[only_bind_into](sink)) and
source.getInstruction() = var
select sink.getInstruction(), source, sink, "May return stack-allocated memory from $@.",
var.getAst(), var.getAst().toString()
source.getNode().asInstruction() = var
select sink.getNode(), source, sink, "May return stack-allocated memory from $@.", var.getAst(),
var.getAst().toString()

View File

@@ -22,40 +22,37 @@ import PathGraph
class UnsafeUseOfThisConfig extends MustFlowConfiguration {
UnsafeUseOfThisConfig() { this = "UnsafeUseOfThisConfig" }
override predicate isSource(Instruction source) { isSource(source, _, _) }
override predicate isSource(DataFlow::Node source) { isSource(source, _, _) }
override predicate isSink(Operand sink) { isSink(sink, _) }
override predicate isSink(DataFlow::Node sink) { isSink(sink, _) }
}
/** Holds if `sink` is a `this` pointer used by the call instruction `call`. */
predicate isSink(Operand sink, CallInstruction call) {
/** Holds if `instr` is a `this` pointer used by the call instruction `call`. */
predicate isSink(DataFlow::Node sink, CallInstruction call) {
exists(PureVirtualFunction func |
call.getStaticCallTarget() = func and
call.getThisArgumentOperand() = sink and
call.getThisArgument() = sink.asInstruction() and
// Weed out implicit calls to destructors of a base class
not func instanceof Destructor
)
}
/**
* Holds if `source` initializes the `this` pointer in class `c`.
*
* The string `msg` describes whether the enclosing function is a
* constructor or destructor.
*/
predicate isSource(InitializeParameterInstruction source, string msg, Class c) {
(
exists(Constructor func |
not func instanceof CopyConstructor and
not func instanceof MoveConstructor and
func = source.getEnclosingFunction() and
msg = "construction"
)
or
source.getEnclosingFunction() instanceof Destructor and msg = "destruction"
) and
source.getIRVariable() instanceof IRThisVariable and
source.getEnclosingFunction().getDeclaringType() = c
/** Holds if `init` initializes the `this` pointer in class `c`. */
predicate isSource(DataFlow::Node source, string msg, Class c) {
exists(InitializeParameterInstruction init | init = source.asInstruction() |
(
exists(Constructor func |
not func instanceof CopyConstructor and
not func instanceof MoveConstructor and
func = init.getEnclosingFunction() and
msg = "construction"
)
or
init.getEnclosingFunction() instanceof Destructor and msg = "destruction"
) and
init.getIRVariable() instanceof IRThisVariable and
init.getEnclosingFunction().getDeclaringType() = c
)
}
/**
@@ -71,8 +68,8 @@ predicate flows(
) {
exists(UnsafeUseOfThisConfig conf |
conf.hasFlowPath(source, sink) and
isSource(source.getInstruction(), msg, sourceClass) and
isSink(sink.getInstruction().getAUse(), call)
isSource(source.getNode(), msg, sourceClass) and
isSink(sink.getNode(), call)
)
}

View File

@@ -1,3 +0,0 @@
## 0.4.4
No user-facing changes.

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 0.4.4
lastReleaseVersion: 0.4.3

View File

@@ -1,4 +1,4 @@
/**
/*
* Common functions for implementing naming conventions
*
* Naming rules are the following:

View File

@@ -1,5 +1,5 @@
name: codeql/cpp-queries
version: 0.4.5-dev
version: 0.4.4-dev
groups:
- cpp
- queries

View File

@@ -1,4 +1,3 @@
WARNING: Type GVN has been deprecated and may be removed in future (ast_gvn.ql:4,6-9)
| test.cpp:5:3:5:3 | x | 5:c3-c3 6:c3-c3 |
| test.cpp:5:7:5:8 | p0 | 5:c7-c8 6:c7-c8 |
| test.cpp:5:7:5:13 | ... + ... | 5:c7-c13 6:c7-c13 7:c7-c7 |

View File

@@ -1,3 +0,0 @@
WARNING: Predicate globalValueNumber has been deprecated and may be removed in future (ast_uniqueness.ql:7,13-30)
WARNING: Predicate globalValueNumber has been deprecated and may be removed in future (ast_uniqueness.ql:8,30-47)
WARNING: Type GVN has been deprecated and may be removed in future (ast_uniqueness.ql:8,18-21)

View File

@@ -1,4 +1,3 @@
WARNING: Predicate globalValueNumber has been deprecated and may be removed in future (diff_ir_expr.ql:8,29-51)
| test.cpp:5:3:5:13 | ... = ... | test.cpp:5:3:5:13 | ... = ... | AST only |
| test.cpp:6:3:6:13 | ... = ... | test.cpp:6:3:6:13 | ... = ... | AST only |
| test.cpp:7:3:7:7 | ... = ... | test.cpp:7:3:7:7 | ... = ... | AST only |

View File

@@ -1,61 +1,103 @@
edges
| test.cpp:7:3:7:3 | B | test.cpp:8:12:8:15 | this |
| test.cpp:7:3:7:3 | this | test.cpp:8:12:8:15 | Load |
| test.cpp:8:12:8:15 | Load | test.cpp:8:12:8:15 | this |
| test.cpp:8:12:8:15 | this | test.cpp:34:16:34:16 | x |
| test.cpp:11:8:11:8 | b | test.cpp:12:5:12:5 | b |
| test.cpp:12:5:12:5 | (reference dereference) | test.cpp:12:5:12:5 | (A)... |
| test.cpp:12:5:12:5 | b | test.cpp:12:5:12:5 | (reference dereference) |
| test.cpp:15:3:15:4 | ~B | test.cpp:16:5:16:5 | this |
| test.cpp:16:5:16:5 | this | file://:0:0:0:0 | (A *)... |
| test.cpp:21:3:21:3 | C | test.cpp:21:13:21:13 | call to B |
| test.cpp:21:3:21:3 | C | test.cpp:22:12:22:15 | this |
| test.cpp:21:3:21:3 | C | test.cpp:25:7:25:10 | this |
| test.cpp:21:13:21:13 | call to B | test.cpp:7:3:7:3 | B |
| test.cpp:11:8:11:8 | b | test.cpp:12:5:12:5 | Load |
| test.cpp:12:5:12:5 | (reference dereference) | test.cpp:12:5:12:5 | Unary |
| test.cpp:12:5:12:5 | Load | test.cpp:12:5:12:5 | b |
| test.cpp:12:5:12:5 | Unary | test.cpp:12:5:12:5 | (A)... |
| test.cpp:12:5:12:5 | Unary | test.cpp:12:5:12:5 | (reference dereference) |
| test.cpp:12:5:12:5 | b | test.cpp:12:5:12:5 | Unary |
| test.cpp:15:3:15:4 | this | test.cpp:16:5:16:5 | Load |
| test.cpp:16:5:16:5 | Load | test.cpp:16:5:16:5 | this |
| test.cpp:16:5:16:5 | Unary | file://:0:0:0:0 | (A *)... |
| test.cpp:16:5:16:5 | this | test.cpp:16:5:16:5 | Unary |
| test.cpp:21:3:21:3 | Unary | test.cpp:21:13:21:13 | ConvertToNonVirtualBase |
| test.cpp:21:3:21:3 | this | test.cpp:21:3:21:3 | Unary |
| test.cpp:21:3:21:3 | this | test.cpp:22:12:22:15 | Load |
| test.cpp:21:3:21:3 | this | test.cpp:25:7:25:10 | Load |
| test.cpp:21:13:21:13 | ConvertToNonVirtualBase | test.cpp:7:3:7:3 | this |
| test.cpp:22:12:22:15 | (B *)... | test.cpp:34:16:34:16 | x |
| test.cpp:22:12:22:15 | this | test.cpp:22:12:22:15 | (B *)... |
| test.cpp:25:7:25:10 | (B *)... | test.cpp:25:7:25:10 | (A *)... |
| test.cpp:25:7:25:10 | this | test.cpp:25:7:25:10 | (B *)... |
| test.cpp:31:3:31:3 | D | test.cpp:31:12:31:15 | this |
| test.cpp:31:11:31:15 | (B)... | test.cpp:31:11:31:15 | (reference to) |
| test.cpp:22:12:22:15 | Load | test.cpp:22:12:22:15 | this |
| test.cpp:22:12:22:15 | Unary | test.cpp:22:12:22:15 | (B *)... |
| test.cpp:22:12:22:15 | this | test.cpp:22:12:22:15 | Unary |
| test.cpp:25:7:25:10 | (B *)... | test.cpp:25:7:25:10 | Unary |
| test.cpp:25:7:25:10 | Load | test.cpp:25:7:25:10 | this |
| test.cpp:25:7:25:10 | Unary | test.cpp:25:7:25:10 | (A *)... |
| test.cpp:25:7:25:10 | Unary | test.cpp:25:7:25:10 | (B *)... |
| test.cpp:25:7:25:10 | this | test.cpp:25:7:25:10 | Unary |
| test.cpp:31:3:31:3 | this | test.cpp:31:12:31:15 | Load |
| test.cpp:31:11:31:15 | (B)... | test.cpp:31:11:31:15 | Unary |
| test.cpp:31:11:31:15 | (reference to) | test.cpp:11:8:11:8 | b |
| test.cpp:31:11:31:15 | * ... | test.cpp:31:11:31:15 | (B)... |
| test.cpp:31:12:31:15 | this | test.cpp:31:11:31:15 | * ... |
| test.cpp:34:16:34:16 | x | test.cpp:35:3:35:3 | x |
| test.cpp:35:3:35:3 | x | test.cpp:35:3:35:3 | (A *)... |
| test.cpp:47:3:47:3 | F | test.cpp:48:10:48:13 | this |
| test.cpp:48:10:48:13 | (E *)... | test.cpp:48:6:48:13 | (A *)... |
| test.cpp:48:10:48:13 | this | test.cpp:48:10:48:13 | (E *)... |
| test.cpp:31:11:31:15 | * ... | test.cpp:31:11:31:15 | Unary |
| test.cpp:31:11:31:15 | Unary | test.cpp:31:11:31:15 | (B)... |
| test.cpp:31:11:31:15 | Unary | test.cpp:31:11:31:15 | (reference to) |
| test.cpp:31:12:31:15 | Load | test.cpp:31:12:31:15 | this |
| test.cpp:31:12:31:15 | Unary | test.cpp:31:11:31:15 | * ... |
| test.cpp:31:12:31:15 | this | test.cpp:31:12:31:15 | Unary |
| test.cpp:34:16:34:16 | x | test.cpp:35:3:35:3 | Load |
| test.cpp:35:3:35:3 | Load | test.cpp:35:3:35:3 | x |
| test.cpp:35:3:35:3 | Unary | test.cpp:35:3:35:3 | (A *)... |
| test.cpp:35:3:35:3 | x | test.cpp:35:3:35:3 | Unary |
| test.cpp:47:3:47:3 | this | test.cpp:48:10:48:13 | Load |
| test.cpp:48:10:48:13 | (E *)... | test.cpp:48:10:48:13 | Unary |
| test.cpp:48:10:48:13 | Load | test.cpp:48:10:48:13 | this |
| test.cpp:48:10:48:13 | Unary | test.cpp:48:6:48:13 | (A *)... |
| test.cpp:48:10:48:13 | Unary | test.cpp:48:10:48:13 | (E *)... |
| test.cpp:48:10:48:13 | this | test.cpp:48:10:48:13 | Unary |
nodes
| file://:0:0:0:0 | (A *)... | semmle.label | (A *)... |
| test.cpp:7:3:7:3 | B | semmle.label | B |
| test.cpp:7:3:7:3 | this | semmle.label | this |
| test.cpp:8:12:8:15 | Load | semmle.label | Load |
| test.cpp:8:12:8:15 | this | semmle.label | this |
| test.cpp:11:8:11:8 | b | semmle.label | b |
| test.cpp:12:5:12:5 | (A)... | semmle.label | (A)... |
| test.cpp:12:5:12:5 | (reference dereference) | semmle.label | (reference dereference) |
| test.cpp:12:5:12:5 | Load | semmle.label | Load |
| test.cpp:12:5:12:5 | Unary | semmle.label | Unary |
| test.cpp:12:5:12:5 | Unary | semmle.label | Unary |
| test.cpp:12:5:12:5 | b | semmle.label | b |
| test.cpp:15:3:15:4 | ~B | semmle.label | ~B |
| test.cpp:15:3:15:4 | this | semmle.label | this |
| test.cpp:16:5:16:5 | Load | semmle.label | Load |
| test.cpp:16:5:16:5 | Unary | semmle.label | Unary |
| test.cpp:16:5:16:5 | this | semmle.label | this |
| test.cpp:21:3:21:3 | C | semmle.label | C |
| test.cpp:21:13:21:13 | call to B | semmle.label | call to B |
| test.cpp:21:3:21:3 | Unary | semmle.label | Unary |
| test.cpp:21:3:21:3 | this | semmle.label | this |
| test.cpp:21:13:21:13 | ConvertToNonVirtualBase | semmle.label | ConvertToNonVirtualBase |
| test.cpp:22:12:22:15 | (B *)... | semmle.label | (B *)... |
| test.cpp:22:12:22:15 | Load | semmle.label | Load |
| test.cpp:22:12:22:15 | Unary | semmle.label | Unary |
| test.cpp:22:12:22:15 | this | semmle.label | this |
| test.cpp:25:7:25:10 | (A *)... | semmle.label | (A *)... |
| test.cpp:25:7:25:10 | (B *)... | semmle.label | (B *)... |
| test.cpp:25:7:25:10 | Load | semmle.label | Load |
| test.cpp:25:7:25:10 | Unary | semmle.label | Unary |
| test.cpp:25:7:25:10 | Unary | semmle.label | Unary |
| test.cpp:25:7:25:10 | this | semmle.label | this |
| test.cpp:31:3:31:3 | D | semmle.label | D |
| test.cpp:31:3:31:3 | this | semmle.label | this |
| test.cpp:31:11:31:15 | (B)... | semmle.label | (B)... |
| test.cpp:31:11:31:15 | (reference to) | semmle.label | (reference to) |
| test.cpp:31:11:31:15 | * ... | semmle.label | * ... |
| test.cpp:31:11:31:15 | Unary | semmle.label | Unary |
| test.cpp:31:11:31:15 | Unary | semmle.label | Unary |
| test.cpp:31:12:31:15 | Load | semmle.label | Load |
| test.cpp:31:12:31:15 | Unary | semmle.label | Unary |
| test.cpp:31:12:31:15 | this | semmle.label | this |
| test.cpp:34:16:34:16 | x | semmle.label | x |
| test.cpp:35:3:35:3 | (A *)... | semmle.label | (A *)... |
| test.cpp:35:3:35:3 | Load | semmle.label | Load |
| test.cpp:35:3:35:3 | Unary | semmle.label | Unary |
| test.cpp:35:3:35:3 | x | semmle.label | x |
| test.cpp:47:3:47:3 | F | semmle.label | F |
| test.cpp:47:3:47:3 | this | semmle.label | this |
| test.cpp:48:6:48:13 | (A *)... | semmle.label | (A *)... |
| test.cpp:48:10:48:13 | (E *)... | semmle.label | (E *)... |
| test.cpp:48:10:48:13 | Load | semmle.label | Load |
| test.cpp:48:10:48:13 | Unary | semmle.label | Unary |
| test.cpp:48:10:48:13 | Unary | semmle.label | Unary |
| test.cpp:48:10:48:13 | this | semmle.label | this |
#select
| test.cpp:12:7:12:7 | call to f | test.cpp:31:3:31:3 | D | test.cpp:12:5:12:5 | (A)... | Call to pure virtual function during construction. |
| test.cpp:16:5:16:5 | call to f | test.cpp:15:3:15:4 | ~B | file://:0:0:0:0 | (A *)... | Call to pure virtual function during destruction. |
| test.cpp:25:13:25:13 | call to f | test.cpp:21:3:21:3 | C | test.cpp:25:7:25:10 | (A *)... | Call to pure virtual function during construction. |
| test.cpp:35:6:35:6 | call to f | test.cpp:7:3:7:3 | B | test.cpp:35:3:35:3 | (A *)... | Call to pure virtual function during construction. |
| test.cpp:35:6:35:6 | call to f | test.cpp:21:3:21:3 | C | test.cpp:35:3:35:3 | (A *)... | Call to pure virtual function during construction. |
| test.cpp:12:7:12:7 | call to f | test.cpp:31:3:31:3 | this | test.cpp:12:5:12:5 | (A)... | Call to pure virtual function during construction. |
| test.cpp:16:5:16:5 | call to f | test.cpp:15:3:15:4 | this | file://:0:0:0:0 | (A *)... | Call to pure virtual function during destruction. |
| test.cpp:25:13:25:13 | call to f | test.cpp:21:3:21:3 | this | test.cpp:25:7:25:10 | (A *)... | Call to pure virtual function during construction. |
| test.cpp:35:6:35:6 | call to f | test.cpp:7:3:7:3 | this | test.cpp:35:3:35:3 | (A *)... | Call to pure virtual function during construction. |
| test.cpp:35:6:35:6 | call to f | test.cpp:21:3:21:3 | this | test.cpp:35:3:35:3 | (A *)... | Call to pure virtual function during construction. |

View File

@@ -1,117 +1,231 @@
edges
| test.cpp:17:10:17:11 | mc | test.cpp:17:9:17:11 | & ... |
| test.cpp:23:17:23:19 | & ... | test.cpp:23:17:23:19 | & ... |
| test.cpp:23:17:23:19 | & ... | test.cpp:25:9:25:11 | ptr |
| test.cpp:23:18:23:19 | mc | test.cpp:23:17:23:19 | & ... |
| test.cpp:39:17:39:18 | (reference to) | test.cpp:39:17:39:18 | (reference to) |
| test.cpp:39:17:39:18 | (reference to) | test.cpp:41:10:41:12 | ref |
| test.cpp:39:17:39:18 | mc | test.cpp:39:17:39:18 | (reference to) |
| test.cpp:41:10:41:12 | (reference dereference) | test.cpp:41:9:41:12 | & ... |
| test.cpp:41:10:41:12 | ref | test.cpp:41:10:41:12 | (reference dereference) |
| test.cpp:47:9:47:10 | mc | test.cpp:47:9:47:10 | (reference to) |
| test.cpp:54:11:54:12 | mc | test.cpp:54:14:54:14 | a |
| test.cpp:54:14:54:14 | a | test.cpp:54:9:54:15 | & ... |
| test.cpp:89:3:89:11 | ... = ... | test.cpp:92:9:92:11 | ptr |
| test.cpp:89:9:89:11 | & ... | test.cpp:89:3:89:11 | ... = ... |
| test.cpp:89:10:89:11 | mc | test.cpp:89:9:89:11 | & ... |
| test.cpp:112:9:112:11 | arr | test.cpp:112:9:112:11 | array to pointer conversion |
| test.cpp:119:11:119:13 | arr | test.cpp:119:11:119:13 | array to pointer conversion |
| test.cpp:119:11:119:13 | array to pointer conversion | test.cpp:119:11:119:17 | access to array |
| test.cpp:119:11:119:17 | access to array | test.cpp:119:9:119:18 | & ... |
| test.cpp:134:2:134:14 | ... = ... | test.cpp:135:2:135:4 | ptr |
| test.cpp:134:8:134:10 | arr | test.cpp:134:8:134:10 | array to pointer conversion |
| test.cpp:134:8:134:10 | array to pointer conversion | test.cpp:134:8:134:14 | ... + ... |
| test.cpp:134:8:134:14 | ... + ... | test.cpp:134:2:134:14 | ... = ... |
| test.cpp:135:2:135:4 | ptr | test.cpp:135:2:135:6 | ... ++ |
| test.cpp:135:2:135:6 | ... ++ | test.cpp:135:2:135:6 | ... ++ |
| test.cpp:135:2:135:6 | ... ++ | test.cpp:137:9:137:11 | ptr |
| test.cpp:170:26:170:41 | (void *)... | test.cpp:170:26:170:41 | (void *)... |
| test.cpp:170:26:170:41 | (void *)... | test.cpp:171:10:171:23 | pointerToLocal |
| test.cpp:170:34:170:41 | & ... | test.cpp:170:26:170:41 | (void *)... |
| test.cpp:170:35:170:41 | myLocal | test.cpp:170:34:170:41 | & ... |
| test.cpp:176:25:176:34 | array to pointer conversion | test.cpp:176:25:176:34 | array to pointer conversion |
| test.cpp:176:25:176:34 | array to pointer conversion | test.cpp:177:10:177:23 | pointerToLocal |
| test.cpp:176:25:176:34 | localArray | test.cpp:176:25:176:34 | array to pointer conversion |
| test.cpp:177:10:177:23 | pointerToLocal | test.cpp:177:10:177:23 | (void *)... |
| test.cpp:182:21:182:27 | (reference to) | test.cpp:182:21:182:27 | (reference to) |
| test.cpp:182:21:182:27 | (reference to) | test.cpp:183:10:183:19 | refToLocal |
| test.cpp:182:21:182:27 | myLocal | test.cpp:182:21:182:27 | (reference to) |
| test.cpp:183:10:183:19 | (reference dereference) | test.cpp:183:10:183:19 | (reference to) |
| test.cpp:183:10:183:19 | refToLocal | test.cpp:183:10:183:19 | (reference dereference) |
| test.cpp:189:16:189:16 | (reference to) | test.cpp:189:16:189:16 | (reference to) |
| test.cpp:189:16:189:16 | (reference to) | test.cpp:190:10:190:13 | pRef |
| test.cpp:189:16:189:16 | p | test.cpp:189:16:189:16 | (reference to) |
| test.cpp:190:10:190:13 | (reference dereference) | test.cpp:190:10:190:13 | (reference to) |
| test.cpp:190:10:190:13 | pRef | test.cpp:190:10:190:13 | (reference dereference) |
| test.cpp:17:9:17:11 | & ... | test.cpp:17:9:17:11 | StoreValue |
| test.cpp:17:10:17:11 | Unary | test.cpp:17:9:17:11 | & ... |
| test.cpp:17:10:17:11 | mc | test.cpp:17:10:17:11 | Unary |
| test.cpp:23:17:23:19 | & ... | test.cpp:23:17:23:19 | StoreValue |
| test.cpp:23:17:23:19 | Store | test.cpp:25:9:25:11 | Load |
| test.cpp:23:17:23:19 | StoreValue | test.cpp:23:17:23:19 | Store |
| test.cpp:23:18:23:19 | Unary | test.cpp:23:17:23:19 | & ... |
| test.cpp:23:18:23:19 | mc | test.cpp:23:18:23:19 | Unary |
| test.cpp:25:9:25:11 | Load | test.cpp:25:9:25:11 | ptr |
| test.cpp:25:9:25:11 | ptr | test.cpp:25:9:25:11 | StoreValue |
| test.cpp:39:17:39:18 | (reference to) | test.cpp:39:17:39:18 | StoreValue |
| test.cpp:39:17:39:18 | Store | test.cpp:41:10:41:12 | Load |
| test.cpp:39:17:39:18 | StoreValue | test.cpp:39:17:39:18 | Store |
| test.cpp:39:17:39:18 | Unary | test.cpp:39:17:39:18 | (reference to) |
| test.cpp:39:17:39:18 | mc | test.cpp:39:17:39:18 | Unary |
| test.cpp:41:9:41:12 | & ... | test.cpp:41:9:41:12 | StoreValue |
| test.cpp:41:10:41:12 | (reference dereference) | test.cpp:41:10:41:12 | Unary |
| test.cpp:41:10:41:12 | Load | test.cpp:41:10:41:12 | ref |
| test.cpp:41:10:41:12 | Unary | test.cpp:41:9:41:12 | & ... |
| test.cpp:41:10:41:12 | Unary | test.cpp:41:10:41:12 | (reference dereference) |
| test.cpp:41:10:41:12 | ref | test.cpp:41:10:41:12 | Unary |
| test.cpp:47:9:47:10 | (reference to) | test.cpp:47:9:47:10 | StoreValue |
| test.cpp:47:9:47:10 | Unary | test.cpp:47:9:47:10 | (reference to) |
| test.cpp:47:9:47:10 | mc | test.cpp:47:9:47:10 | Unary |
| test.cpp:54:9:54:15 | & ... | test.cpp:54:9:54:15 | StoreValue |
| test.cpp:54:11:54:12 | Unary | test.cpp:54:14:54:14 | a |
| test.cpp:54:11:54:12 | mc | test.cpp:54:11:54:12 | Unary |
| test.cpp:54:14:54:14 | Unary | test.cpp:54:9:54:15 | & ... |
| test.cpp:54:14:54:14 | a | test.cpp:54:14:54:14 | Unary |
| test.cpp:89:3:89:11 | Store | test.cpp:92:9:92:11 | Load |
| test.cpp:89:9:89:11 | & ... | test.cpp:89:9:89:11 | StoreValue |
| test.cpp:89:9:89:11 | StoreValue | test.cpp:89:3:89:11 | Store |
| test.cpp:89:10:89:11 | Unary | test.cpp:89:9:89:11 | & ... |
| test.cpp:89:10:89:11 | mc | test.cpp:89:10:89:11 | Unary |
| test.cpp:92:9:92:11 | Load | test.cpp:92:9:92:11 | ptr |
| test.cpp:92:9:92:11 | ptr | test.cpp:92:9:92:11 | StoreValue |
| test.cpp:112:9:112:11 | Unary | test.cpp:112:9:112:11 | array to pointer conversion |
| test.cpp:112:9:112:11 | arr | test.cpp:112:9:112:11 | Unary |
| test.cpp:112:9:112:11 | array to pointer conversion | test.cpp:112:9:112:11 | StoreValue |
| test.cpp:119:9:119:18 | & ... | test.cpp:119:9:119:18 | StoreValue |
| test.cpp:119:11:119:13 | Left | test.cpp:119:11:119:17 | access to array |
| test.cpp:119:11:119:13 | Unary | test.cpp:119:11:119:13 | array to pointer conversion |
| test.cpp:119:11:119:13 | arr | test.cpp:119:11:119:13 | Unary |
| test.cpp:119:11:119:13 | array to pointer conversion | test.cpp:119:11:119:13 | Left |
| test.cpp:119:11:119:17 | Unary | test.cpp:119:9:119:18 | & ... |
| test.cpp:119:11:119:17 | access to array | test.cpp:119:11:119:17 | Unary |
| test.cpp:134:2:134:14 | Store | test.cpp:135:2:135:4 | Load |
| test.cpp:134:8:134:10 | Left | test.cpp:134:8:134:14 | ... + ... |
| test.cpp:134:8:134:10 | Unary | test.cpp:134:8:134:10 | array to pointer conversion |
| test.cpp:134:8:134:10 | arr | test.cpp:134:8:134:10 | Unary |
| test.cpp:134:8:134:10 | array to pointer conversion | test.cpp:134:8:134:10 | Left |
| test.cpp:134:8:134:14 | ... + ... | test.cpp:134:8:134:14 | StoreValue |
| test.cpp:134:8:134:14 | StoreValue | test.cpp:134:2:134:14 | Store |
| test.cpp:135:2:135:4 | Left | test.cpp:135:2:135:6 | PointerAdd |
| test.cpp:135:2:135:4 | Load | test.cpp:135:2:135:4 | ptr |
| test.cpp:135:2:135:4 | ptr | test.cpp:135:2:135:4 | Left |
| test.cpp:135:2:135:6 | PointerAdd | test.cpp:135:2:135:6 | StoreValue |
| test.cpp:135:2:135:6 | Store | test.cpp:137:9:137:11 | Load |
| test.cpp:135:2:135:6 | StoreValue | test.cpp:135:2:135:6 | Store |
| test.cpp:137:9:137:11 | Load | test.cpp:137:9:137:11 | ptr |
| test.cpp:137:9:137:11 | ptr | test.cpp:137:9:137:11 | StoreValue |
| test.cpp:170:26:170:41 | (void *)... | test.cpp:170:26:170:41 | StoreValue |
| test.cpp:170:26:170:41 | Store | test.cpp:171:10:171:23 | Load |
| test.cpp:170:26:170:41 | StoreValue | test.cpp:170:26:170:41 | Store |
| test.cpp:170:34:170:41 | & ... | test.cpp:170:34:170:41 | Unary |
| test.cpp:170:34:170:41 | Unary | test.cpp:170:26:170:41 | (void *)... |
| test.cpp:170:35:170:41 | Unary | test.cpp:170:34:170:41 | & ... |
| test.cpp:170:35:170:41 | myLocal | test.cpp:170:35:170:41 | Unary |
| test.cpp:171:10:171:23 | Load | test.cpp:171:10:171:23 | pointerToLocal |
| test.cpp:171:10:171:23 | pointerToLocal | test.cpp:171:10:171:23 | StoreValue |
| test.cpp:176:25:176:34 | Store | test.cpp:177:10:177:23 | Load |
| test.cpp:176:25:176:34 | StoreValue | test.cpp:176:25:176:34 | Store |
| test.cpp:176:25:176:34 | Unary | test.cpp:176:25:176:34 | array to pointer conversion |
| test.cpp:176:25:176:34 | array to pointer conversion | test.cpp:176:25:176:34 | StoreValue |
| test.cpp:176:25:176:34 | localArray | test.cpp:176:25:176:34 | Unary |
| test.cpp:177:10:177:23 | (void *)... | test.cpp:177:10:177:23 | StoreValue |
| test.cpp:177:10:177:23 | Load | test.cpp:177:10:177:23 | pointerToLocal |
| test.cpp:177:10:177:23 | Unary | test.cpp:177:10:177:23 | (void *)... |
| test.cpp:177:10:177:23 | pointerToLocal | test.cpp:177:10:177:23 | Unary |
| test.cpp:182:21:182:27 | (reference to) | test.cpp:182:21:182:27 | StoreValue |
| test.cpp:182:21:182:27 | Store | test.cpp:183:10:183:19 | Load |
| test.cpp:182:21:182:27 | StoreValue | test.cpp:182:21:182:27 | Store |
| test.cpp:182:21:182:27 | Unary | test.cpp:182:21:182:27 | (reference to) |
| test.cpp:182:21:182:27 | myLocal | test.cpp:182:21:182:27 | Unary |
| test.cpp:183:10:183:19 | (reference dereference) | test.cpp:183:10:183:19 | Unary |
| test.cpp:183:10:183:19 | (reference to) | test.cpp:183:10:183:19 | StoreValue |
| test.cpp:183:10:183:19 | Load | test.cpp:183:10:183:19 | refToLocal |
| test.cpp:183:10:183:19 | Unary | test.cpp:183:10:183:19 | (reference dereference) |
| test.cpp:183:10:183:19 | Unary | test.cpp:183:10:183:19 | (reference to) |
| test.cpp:183:10:183:19 | refToLocal | test.cpp:183:10:183:19 | Unary |
| test.cpp:189:16:189:16 | (reference to) | test.cpp:189:16:189:16 | StoreValue |
| test.cpp:189:16:189:16 | Store | test.cpp:190:10:190:13 | Load |
| test.cpp:189:16:189:16 | StoreValue | test.cpp:189:16:189:16 | Store |
| test.cpp:189:16:189:16 | Unary | test.cpp:189:16:189:16 | (reference to) |
| test.cpp:189:16:189:16 | p | test.cpp:189:16:189:16 | Unary |
| test.cpp:190:10:190:13 | (reference dereference) | test.cpp:190:10:190:13 | Unary |
| test.cpp:190:10:190:13 | (reference to) | test.cpp:190:10:190:13 | StoreValue |
| test.cpp:190:10:190:13 | Load | test.cpp:190:10:190:13 | pRef |
| test.cpp:190:10:190:13 | Unary | test.cpp:190:10:190:13 | (reference dereference) |
| test.cpp:190:10:190:13 | Unary | test.cpp:190:10:190:13 | (reference to) |
| test.cpp:190:10:190:13 | pRef | test.cpp:190:10:190:13 | Unary |
nodes
| test.cpp:17:9:17:11 | & ... | semmle.label | & ... |
| test.cpp:17:9:17:11 | StoreValue | semmle.label | StoreValue |
| test.cpp:17:10:17:11 | Unary | semmle.label | Unary |
| test.cpp:17:10:17:11 | mc | semmle.label | mc |
| test.cpp:23:17:23:19 | & ... | semmle.label | & ... |
| test.cpp:23:17:23:19 | & ... | semmle.label | & ... |
| test.cpp:23:17:23:19 | Store | semmle.label | Store |
| test.cpp:23:17:23:19 | StoreValue | semmle.label | StoreValue |
| test.cpp:23:18:23:19 | Unary | semmle.label | Unary |
| test.cpp:23:18:23:19 | mc | semmle.label | mc |
| test.cpp:25:9:25:11 | Load | semmle.label | Load |
| test.cpp:25:9:25:11 | StoreValue | semmle.label | StoreValue |
| test.cpp:25:9:25:11 | ptr | semmle.label | ptr |
| test.cpp:39:17:39:18 | (reference to) | semmle.label | (reference to) |
| test.cpp:39:17:39:18 | (reference to) | semmle.label | (reference to) |
| test.cpp:39:17:39:18 | Store | semmle.label | Store |
| test.cpp:39:17:39:18 | StoreValue | semmle.label | StoreValue |
| test.cpp:39:17:39:18 | Unary | semmle.label | Unary |
| test.cpp:39:17:39:18 | mc | semmle.label | mc |
| test.cpp:41:9:41:12 | & ... | semmle.label | & ... |
| test.cpp:41:9:41:12 | StoreValue | semmle.label | StoreValue |
| test.cpp:41:10:41:12 | (reference dereference) | semmle.label | (reference dereference) |
| test.cpp:41:10:41:12 | Load | semmle.label | Load |
| test.cpp:41:10:41:12 | Unary | semmle.label | Unary |
| test.cpp:41:10:41:12 | Unary | semmle.label | Unary |
| test.cpp:41:10:41:12 | ref | semmle.label | ref |
| test.cpp:47:9:47:10 | (reference to) | semmle.label | (reference to) |
| test.cpp:47:9:47:10 | StoreValue | semmle.label | StoreValue |
| test.cpp:47:9:47:10 | Unary | semmle.label | Unary |
| test.cpp:47:9:47:10 | mc | semmle.label | mc |
| test.cpp:54:9:54:15 | & ... | semmle.label | & ... |
| test.cpp:54:9:54:15 | StoreValue | semmle.label | StoreValue |
| test.cpp:54:11:54:12 | Unary | semmle.label | Unary |
| test.cpp:54:11:54:12 | mc | semmle.label | mc |
| test.cpp:54:14:54:14 | Unary | semmle.label | Unary |
| test.cpp:54:14:54:14 | a | semmle.label | a |
| test.cpp:89:3:89:11 | ... = ... | semmle.label | ... = ... |
| test.cpp:89:3:89:11 | Store | semmle.label | Store |
| test.cpp:89:9:89:11 | & ... | semmle.label | & ... |
| test.cpp:89:9:89:11 | StoreValue | semmle.label | StoreValue |
| test.cpp:89:10:89:11 | Unary | semmle.label | Unary |
| test.cpp:89:10:89:11 | mc | semmle.label | mc |
| test.cpp:92:9:92:11 | Load | semmle.label | Load |
| test.cpp:92:9:92:11 | StoreValue | semmle.label | StoreValue |
| test.cpp:92:9:92:11 | ptr | semmle.label | ptr |
| test.cpp:112:9:112:11 | StoreValue | semmle.label | StoreValue |
| test.cpp:112:9:112:11 | Unary | semmle.label | Unary |
| test.cpp:112:9:112:11 | arr | semmle.label | arr |
| test.cpp:112:9:112:11 | array to pointer conversion | semmle.label | array to pointer conversion |
| test.cpp:119:9:119:18 | & ... | semmle.label | & ... |
| test.cpp:119:9:119:18 | StoreValue | semmle.label | StoreValue |
| test.cpp:119:11:119:13 | Left | semmle.label | Left |
| test.cpp:119:11:119:13 | Unary | semmle.label | Unary |
| test.cpp:119:11:119:13 | arr | semmle.label | arr |
| test.cpp:119:11:119:13 | array to pointer conversion | semmle.label | array to pointer conversion |
| test.cpp:119:11:119:17 | Unary | semmle.label | Unary |
| test.cpp:119:11:119:17 | access to array | semmle.label | access to array |
| test.cpp:134:2:134:14 | ... = ... | semmle.label | ... = ... |
| test.cpp:134:2:134:14 | Store | semmle.label | Store |
| test.cpp:134:8:134:10 | Left | semmle.label | Left |
| test.cpp:134:8:134:10 | Unary | semmle.label | Unary |
| test.cpp:134:8:134:10 | arr | semmle.label | arr |
| test.cpp:134:8:134:10 | array to pointer conversion | semmle.label | array to pointer conversion |
| test.cpp:134:8:134:14 | ... + ... | semmle.label | ... + ... |
| test.cpp:134:8:134:14 | StoreValue | semmle.label | StoreValue |
| test.cpp:135:2:135:4 | Left | semmle.label | Left |
| test.cpp:135:2:135:4 | Load | semmle.label | Load |
| test.cpp:135:2:135:4 | ptr | semmle.label | ptr |
| test.cpp:135:2:135:6 | ... ++ | semmle.label | ... ++ |
| test.cpp:135:2:135:6 | ... ++ | semmle.label | ... ++ |
| test.cpp:135:2:135:6 | PointerAdd | semmle.label | PointerAdd |
| test.cpp:135:2:135:6 | Store | semmle.label | Store |
| test.cpp:135:2:135:6 | StoreValue | semmle.label | StoreValue |
| test.cpp:137:9:137:11 | Load | semmle.label | Load |
| test.cpp:137:9:137:11 | StoreValue | semmle.label | StoreValue |
| test.cpp:137:9:137:11 | ptr | semmle.label | ptr |
| test.cpp:170:26:170:41 | (void *)... | semmle.label | (void *)... |
| test.cpp:170:26:170:41 | (void *)... | semmle.label | (void *)... |
| test.cpp:170:26:170:41 | Store | semmle.label | Store |
| test.cpp:170:26:170:41 | StoreValue | semmle.label | StoreValue |
| test.cpp:170:34:170:41 | & ... | semmle.label | & ... |
| test.cpp:170:34:170:41 | Unary | semmle.label | Unary |
| test.cpp:170:35:170:41 | Unary | semmle.label | Unary |
| test.cpp:170:35:170:41 | myLocal | semmle.label | myLocal |
| test.cpp:171:10:171:23 | Load | semmle.label | Load |
| test.cpp:171:10:171:23 | StoreValue | semmle.label | StoreValue |
| test.cpp:171:10:171:23 | pointerToLocal | semmle.label | pointerToLocal |
| test.cpp:176:25:176:34 | array to pointer conversion | semmle.label | array to pointer conversion |
| test.cpp:176:25:176:34 | Store | semmle.label | Store |
| test.cpp:176:25:176:34 | StoreValue | semmle.label | StoreValue |
| test.cpp:176:25:176:34 | Unary | semmle.label | Unary |
| test.cpp:176:25:176:34 | array to pointer conversion | semmle.label | array to pointer conversion |
| test.cpp:176:25:176:34 | localArray | semmle.label | localArray |
| test.cpp:177:10:177:23 | (void *)... | semmle.label | (void *)... |
| test.cpp:177:10:177:23 | Load | semmle.label | Load |
| test.cpp:177:10:177:23 | StoreValue | semmle.label | StoreValue |
| test.cpp:177:10:177:23 | Unary | semmle.label | Unary |
| test.cpp:177:10:177:23 | pointerToLocal | semmle.label | pointerToLocal |
| test.cpp:182:21:182:27 | (reference to) | semmle.label | (reference to) |
| test.cpp:182:21:182:27 | (reference to) | semmle.label | (reference to) |
| test.cpp:182:21:182:27 | Store | semmle.label | Store |
| test.cpp:182:21:182:27 | StoreValue | semmle.label | StoreValue |
| test.cpp:182:21:182:27 | Unary | semmle.label | Unary |
| test.cpp:182:21:182:27 | myLocal | semmle.label | myLocal |
| test.cpp:183:10:183:19 | (reference dereference) | semmle.label | (reference dereference) |
| test.cpp:183:10:183:19 | (reference to) | semmle.label | (reference to) |
| test.cpp:183:10:183:19 | Load | semmle.label | Load |
| test.cpp:183:10:183:19 | StoreValue | semmle.label | StoreValue |
| test.cpp:183:10:183:19 | Unary | semmle.label | Unary |
| test.cpp:183:10:183:19 | Unary | semmle.label | Unary |
| test.cpp:183:10:183:19 | refToLocal | semmle.label | refToLocal |
| test.cpp:189:16:189:16 | (reference to) | semmle.label | (reference to) |
| test.cpp:189:16:189:16 | (reference to) | semmle.label | (reference to) |
| test.cpp:189:16:189:16 | Store | semmle.label | Store |
| test.cpp:189:16:189:16 | StoreValue | semmle.label | StoreValue |
| test.cpp:189:16:189:16 | Unary | semmle.label | Unary |
| test.cpp:189:16:189:16 | p | semmle.label | p |
| test.cpp:190:10:190:13 | (reference dereference) | semmle.label | (reference dereference) |
| test.cpp:190:10:190:13 | (reference to) | semmle.label | (reference to) |
| test.cpp:190:10:190:13 | Load | semmle.label | Load |
| test.cpp:190:10:190:13 | StoreValue | semmle.label | StoreValue |
| test.cpp:190:10:190:13 | Unary | semmle.label | Unary |
| test.cpp:190:10:190:13 | Unary | semmle.label | Unary |
| test.cpp:190:10:190:13 | pRef | semmle.label | pRef |
#select
| test.cpp:17:9:17:11 | CopyValue: & ... | test.cpp:17:10:17:11 | mc | test.cpp:17:9:17:11 | & ... | May return stack-allocated memory from $@. | test.cpp:17:10:17:11 | mc | mc |
| test.cpp:25:9:25:11 | Load: ptr | test.cpp:23:18:23:19 | mc | test.cpp:25:9:25:11 | ptr | May return stack-allocated memory from $@. | test.cpp:23:18:23:19 | mc | mc |
| test.cpp:41:9:41:12 | CopyValue: & ... | test.cpp:39:17:39:18 | mc | test.cpp:41:9:41:12 | & ... | May return stack-allocated memory from $@. | test.cpp:39:17:39:18 | mc | mc |
| test.cpp:47:9:47:10 | CopyValue: (reference to) | test.cpp:47:9:47:10 | mc | test.cpp:47:9:47:10 | (reference to) | May return stack-allocated memory from $@. | test.cpp:47:9:47:10 | mc | mc |
| test.cpp:54:9:54:15 | CopyValue: & ... | test.cpp:54:11:54:12 | mc | test.cpp:54:9:54:15 | & ... | May return stack-allocated memory from $@. | test.cpp:54:11:54:12 | mc | mc |
| test.cpp:92:9:92:11 | Load: ptr | test.cpp:89:10:89:11 | mc | test.cpp:92:9:92:11 | ptr | May return stack-allocated memory from $@. | test.cpp:89:10:89:11 | mc | mc |
| test.cpp:112:9:112:11 | Convert: array to pointer conversion | test.cpp:112:9:112:11 | arr | test.cpp:112:9:112:11 | array to pointer conversion | May return stack-allocated memory from $@. | test.cpp:112:9:112:11 | arr | arr |
| test.cpp:119:9:119:18 | CopyValue: & ... | test.cpp:119:11:119:13 | arr | test.cpp:119:9:119:18 | & ... | May return stack-allocated memory from $@. | test.cpp:119:11:119:13 | arr | arr |
| test.cpp:137:9:137:11 | Load: ptr | test.cpp:134:8:134:10 | arr | test.cpp:137:9:137:11 | ptr | May return stack-allocated memory from $@. | test.cpp:134:8:134:10 | arr | arr |
| test.cpp:171:10:171:23 | Load: pointerToLocal | test.cpp:170:35:170:41 | myLocal | test.cpp:171:10:171:23 | pointerToLocal | May return stack-allocated memory from $@. | test.cpp:170:35:170:41 | myLocal | myLocal |
| test.cpp:177:10:177:23 | Convert: (void *)... | test.cpp:176:25:176:34 | localArray | test.cpp:177:10:177:23 | (void *)... | May return stack-allocated memory from $@. | test.cpp:176:25:176:34 | localArray | localArray |
| test.cpp:183:10:183:19 | CopyValue: (reference to) | test.cpp:182:21:182:27 | myLocal | test.cpp:183:10:183:19 | (reference to) | May return stack-allocated memory from $@. | test.cpp:182:21:182:27 | myLocal | myLocal |
| test.cpp:190:10:190:13 | CopyValue: (reference to) | test.cpp:189:16:189:16 | p | test.cpp:190:10:190:13 | (reference to) | May return stack-allocated memory from $@. | test.cpp:189:16:189:16 | p | p |
| test.cpp:17:9:17:11 | StoreValue | test.cpp:17:10:17:11 | mc | test.cpp:17:9:17:11 | StoreValue | May return stack-allocated memory from $@. | test.cpp:17:10:17:11 | mc | mc |
| test.cpp:25:9:25:11 | StoreValue | test.cpp:23:18:23:19 | mc | test.cpp:25:9:25:11 | StoreValue | May return stack-allocated memory from $@. | test.cpp:23:18:23:19 | mc | mc |
| test.cpp:41:9:41:12 | StoreValue | test.cpp:39:17:39:18 | mc | test.cpp:41:9:41:12 | StoreValue | May return stack-allocated memory from $@. | test.cpp:39:17:39:18 | mc | mc |
| test.cpp:47:9:47:10 | StoreValue | test.cpp:47:9:47:10 | mc | test.cpp:47:9:47:10 | StoreValue | May return stack-allocated memory from $@. | test.cpp:47:9:47:10 | mc | mc |
| test.cpp:54:9:54:15 | StoreValue | test.cpp:54:11:54:12 | mc | test.cpp:54:9:54:15 | StoreValue | May return stack-allocated memory from $@. | test.cpp:54:11:54:12 | mc | mc |
| test.cpp:92:9:92:11 | StoreValue | test.cpp:89:10:89:11 | mc | test.cpp:92:9:92:11 | StoreValue | May return stack-allocated memory from $@. | test.cpp:89:10:89:11 | mc | mc |
| test.cpp:112:9:112:11 | StoreValue | test.cpp:112:9:112:11 | arr | test.cpp:112:9:112:11 | StoreValue | May return stack-allocated memory from $@. | test.cpp:112:9:112:11 | arr | arr |
| test.cpp:119:9:119:18 | StoreValue | test.cpp:119:11:119:13 | arr | test.cpp:119:9:119:18 | StoreValue | May return stack-allocated memory from $@. | test.cpp:119:11:119:13 | arr | arr |
| test.cpp:137:9:137:11 | StoreValue | test.cpp:134:8:134:10 | arr | test.cpp:137:9:137:11 | StoreValue | May return stack-allocated memory from $@. | test.cpp:134:8:134:10 | arr | arr |
| test.cpp:171:10:171:23 | StoreValue | test.cpp:170:35:170:41 | myLocal | test.cpp:171:10:171:23 | StoreValue | May return stack-allocated memory from $@. | test.cpp:170:35:170:41 | myLocal | myLocal |
| test.cpp:177:10:177:23 | StoreValue | test.cpp:176:25:176:34 | localArray | test.cpp:177:10:177:23 | StoreValue | May return stack-allocated memory from $@. | test.cpp:176:25:176:34 | localArray | localArray |
| test.cpp:183:10:183:19 | StoreValue | test.cpp:182:21:182:27 | myLocal | test.cpp:183:10:183:19 | StoreValue | May return stack-allocated memory from $@. | test.cpp:182:21:182:27 | myLocal | myLocal |
| test.cpp:190:10:190:13 | StoreValue | test.cpp:189:16:189:16 | p | test.cpp:190:10:190:13 | StoreValue | May return stack-allocated memory from $@. | test.cpp:189:16:189:16 | p | p |

5
csharp/.gitignore vendored
View File

@@ -11,7 +11,4 @@ csharp.log
*.tlog
.vs
*.user
.vscode/launch.json
extractor/Semmle.Extraction.CSharp.Driver/Properties/launchSettings.json
extractor-pack
.vscode/launch.json

View File

@@ -1,13 +0,0 @@
name: Build C# CodeQL pack
description: Builds the C# CodeQL pack
runs:
using: composite
steps:
- name: Setup dotnet
uses: actions/setup-dotnet@v3
with:
dotnet-version: 6.0.202
- name: Build Extractor
shell: bash
run: scripts/create-extractor-pack.sh
working-directory: csharp

View File

@@ -403,7 +403,7 @@ namespace Semmle.Autobuild.CSharp.Tests
actions.GetCurrentDirectory = cwd;
actions.IsWindows = isWindows;
var options = new CSharpAutobuildOptions(actions);
var options = new AutobuildOptions(actions, Language.CSharp);
return new CSharpAutobuilder(actions, options);
}
@@ -576,7 +576,7 @@ namespace Semmle.Autobuild.CSharp.Tests
actions.FileExists[@"C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\vcvarsall.bat"] = false;
}
private void TestAutobuilderScript(CSharpAutobuilder autobuilder, int expectedOutput, int commandsRun)
private void TestAutobuilderScript(Autobuilder autobuilder, int expectedOutput, int commandsRun)
{
Assert.Equal(expectedOutput, autobuilder.GetBuildScript().Run(actions, StartCallback, EndCallback));

View File

@@ -4,32 +4,9 @@ using Semmle.Autobuild.Shared;
namespace Semmle.Autobuild.CSharp
{
/// <summary>
/// Encapsulates C# build options.
/// </summary>
public class CSharpAutobuildOptions : AutobuildOptionsShared
public class CSharpAutobuilder : Autobuilder
{
private const string extractorOptionPrefix = "CODEQL_EXTRACTOR_CSHARP_OPTION_";
public bool Buildless { get; }
public override Language Language => Language.CSharp;
/// <summary>
/// Reads options from environment variables.
/// Throws ArgumentOutOfRangeException for invalid arguments.
/// </summary>
public CSharpAutobuildOptions(IBuildActions actions) : base(actions)
{
Buildless = actions.GetEnvironmentVariable(lgtmPrefix + "BUILDLESS").AsBool("buildless", false) ||
actions.GetEnvironmentVariable(extractorOptionPrefix + "BUILDLESS").AsBool("buildless", false);
}
}
public class CSharpAutobuilder : Autobuilder<CSharpAutobuildOptions>
{
public CSharpAutobuilder(IBuildActions actions, CSharpAutobuildOptions options) : base(actions, options) { }
public CSharpAutobuilder(IBuildActions actions, AutobuildOptions options) : base(actions, options) { }
public override BuildScript GetBuildScript()
{

View File

@@ -13,9 +13,9 @@ namespace Semmle.Autobuild.CSharp
/// A build rule where the build command is of the form "dotnet build".
/// Currently unused because the tracer does not work with dotnet.
/// </summary>
internal class DotNetRule : IBuildRule<CSharpAutobuildOptions>
internal class DotNetRule : IBuildRule
{
public BuildScript Analyse(IAutobuilder<CSharpAutobuildOptions> builder, bool auto)
public BuildScript Analyse(Autobuilder builder, bool auto)
{
if (!builder.ProjectsOrSolutionsToBuild.Any())
return BuildScript.Failure;
@@ -24,7 +24,7 @@ namespace Semmle.Autobuild.CSharp
{
var notDotNetProject = builder.ProjectsOrSolutionsToBuild
.SelectMany(p => Enumerators.Singleton(p).Concat(p.IncludedProjects))
.OfType<Project<CSharpAutobuildOptions>>()
.OfType<Project>()
.FirstOrDefault(p => !p.DotNetProject);
if (notDotNetProject is not null)
{
@@ -56,7 +56,7 @@ namespace Semmle.Autobuild.CSharp
});
}
private static BuildScript WithDotNet(IAutobuilder<AutobuildOptionsShared> builder, Func<string?, IDictionary<string, string>?, BuildScript> f)
private static BuildScript WithDotNet(Autobuilder builder, Func<string?, IDictionary<string, string>?, BuildScript> f)
{
var installDir = builder.Actions.PathCombine(builder.Options.RootDirectory, ".dotnet");
var installScript = DownloadDotNet(builder, installDir);
@@ -92,7 +92,7 @@ namespace Semmle.Autobuild.CSharp
/// variables needed by the installed .NET Core (<code>null</code> when no variables
/// are needed).
/// </summary>
public static BuildScript WithDotNet(IAutobuilder<AutobuildOptionsShared> builder, Func<IDictionary<string, string>?, BuildScript> f)
public static BuildScript WithDotNet(Autobuilder builder, Func<IDictionary<string, string>?, BuildScript> f)
=> WithDotNet(builder, (_1, env) => f(env));
/// <summary>
@@ -100,7 +100,7 @@ namespace Semmle.Autobuild.CSharp
/// .NET Core SDK. The SDK(s) will be installed at <code>installDir</code>
/// (provided that the script succeeds).
/// </summary>
private static BuildScript DownloadDotNet(IAutobuilder<AutobuildOptionsShared> builder, string installDir)
private static BuildScript DownloadDotNet(Autobuilder builder, string installDir)
{
if (!string.IsNullOrEmpty(builder.Options.DotNetVersion))
// Specific version supplied in configuration: always use that
@@ -137,7 +137,7 @@ namespace Semmle.Autobuild.CSharp
///
/// See https://docs.microsoft.com/en-us/dotnet/core/tools/dotnet-install-script.
/// </summary>
private static BuildScript DownloadDotNetVersion(IAutobuilder<AutobuildOptionsShared> builder, string path, string version)
private static BuildScript DownloadDotNetVersion(Autobuilder builder, string path, string version)
{
return BuildScript.Bind(GetInstalledSdksScript(builder.Actions), (sdks, sdksRet) =>
{
@@ -233,7 +233,7 @@ namespace Semmle.Autobuild.CSharp
/// <summary>
/// Gets the `dotnet build` script.
/// </summary>
private static BuildScript GetBuildScript(IAutobuilder<CSharpAutobuildOptions> builder, string? dotNetPath, IDictionary<string, string>? environment, string projOrSln)
private static BuildScript GetBuildScript(Autobuilder builder, string? dotNetPath, IDictionary<string, string>? environment, string projOrSln)
{
var build = new CommandBuilder(builder.Actions, null, environment);
var script = build.RunCommand(DotNetCommand(builder.Actions, dotNetPath)).

View File

@@ -11,7 +11,7 @@ namespace Semmle.Autobuild.CSharp
try
{
var actions = SystemBuildActions.Instance;
var options = new CSharpAutobuildOptions(actions);
var options = new AutobuildOptions(actions, Language.CSharp);
try
{
Console.WriteLine("CodeQL C# autobuilder");

View File

@@ -6,9 +6,9 @@ namespace Semmle.Autobuild.CSharp
/// <summary>
/// Build using standalone extraction.
/// </summary>
internal class StandaloneBuildRule : IBuildRule<CSharpAutobuildOptions>
internal class StandaloneBuildRule : IBuildRule
{
public BuildScript Analyse(IAutobuilder<CSharpAutobuildOptions> builder, bool auto)
public BuildScript Analyse(Autobuilder builder, bool auto)
{
BuildScript GetCommand(string? solution)
{

View File

@@ -6,12 +6,12 @@ using System.Text.RegularExpressions;
namespace Semmle.Autobuild.Shared
{
/// <summary>
/// Encapsulates build options shared between C# and C++.
/// Encapsulates build options.
/// </summary>
public abstract class AutobuildOptionsShared
public class AutobuildOptions
{
protected const string lgtmPrefix = "LGTM_INDEX_";
private const string lgtmPrefix = "LGTM_INDEX_";
private const string extractorOptionPrefix = "CODEQL_EXTRACTOR_CSHARP_OPTION_";
public int SearchDepth { get; } = 3;
public string RootDirectory { get; }
@@ -25,16 +25,16 @@ namespace Semmle.Autobuild.Shared
public string? BuildCommand { get; }
public IEnumerable<string> Solution { get; }
public bool IgnoreErrors { get; }
public bool Buildless { get; }
public bool AllSolutions { get; }
public bool NugetRestore { get; }
public abstract Language Language { get; }
public Language Language { get; }
/// <summary>
/// Reads options from environment variables.
/// Throws ArgumentOutOfRangeException for invalid arguments.
/// </summary>
public AutobuildOptionsShared(IBuildActions actions)
public AutobuildOptions(IBuildActions actions, Language language)
{
RootDirectory = actions.GetCurrentDirectory();
VsToolsVersion = actions.GetEnvironmentVariable(lgtmPrefix + "VSTOOLS_VERSION");
@@ -48,8 +48,12 @@ namespace Semmle.Autobuild.Shared
Solution = actions.GetEnvironmentVariable(lgtmPrefix + "SOLUTION").AsListWithExpandedEnvVars(actions, Array.Empty<string>());
IgnoreErrors = actions.GetEnvironmentVariable(lgtmPrefix + "IGNORE_ERRORS").AsBool("ignore_errors", false);
Buildless = actions.GetEnvironmentVariable(lgtmPrefix + "BUILDLESS").AsBool("buildless", false) ||
actions.GetEnvironmentVariable(extractorOptionPrefix + "BUILDLESS").AsBool("buildless", false);
AllSolutions = actions.GetEnvironmentVariable(lgtmPrefix + "ALL_SOLUTIONS").AsBool("all_solutions", false);
NugetRestore = actions.GetEnvironmentVariable(lgtmPrefix + "NUGET_RESTORE").AsBool("nuget_restore", true);
Language = language;
}
}

View File

@@ -9,21 +9,21 @@ namespace Semmle.Autobuild.Shared
/// <summary>
/// A build rule analyses the files in "builder" and outputs a build script.
/// </summary>
public interface IBuildRule<TAutobuildOptions> where TAutobuildOptions : AutobuildOptionsShared
public interface IBuildRule
{
/// <summary>
/// Analyse the files and produce a build script.
/// </summary>
/// <param name="builder">The files and options relating to the build.</param>
/// <param name="auto">Whether this build rule is being automatically applied.</param>
BuildScript Analyse(IAutobuilder<TAutobuildOptions> builder, bool auto);
BuildScript Analyse(Autobuilder builder, bool auto);
}
/// <summary>
/// A delegate used to wrap a build script in an environment where an appropriate
/// version of .NET Core is automatically installed.
/// </summary>
public delegate BuildScript WithDotNet<TAutobuildOptions>(IAutobuilder<TAutobuildOptions> builder, Func<IDictionary<string, string>?, BuildScript> f) where TAutobuildOptions : AutobuildOptionsShared;
public delegate BuildScript WithDotNet(Autobuilder builder, Func<IDictionary<string, string>?, BuildScript> f);
/// <summary>
/// Exception indicating that environment variables are missing or invalid.
@@ -33,59 +33,6 @@ namespace Semmle.Autobuild.Shared
public InvalidEnvironmentException(string m) : base(m) { }
}
public interface IAutobuilder<out TAutobuildOptions> where TAutobuildOptions : AutobuildOptionsShared
{
/// <summary>
/// Full file paths of files found in the project directory, as well as
/// their distance from the project root folder. The list is sorted
/// by distance in ascending order.
/// </summary>
IEnumerable<(string, int)> Paths { get; }
/// <summary>
/// Gets all paths matching a particular filename, as well as
/// their distance from the project root folder. The list is sorted
/// by distance in ascending order.
/// </summary>
/// <param name="name">The filename to find.</param>
/// <returns>Possibly empty sequence of paths with the given filename.</returns>
IEnumerable<(string, int)> GetFilename(string name) =>
Paths.Where(p => Actions.GetFileName(p.Item1) == name);
/// <summary>
/// List of project/solution files to build.
/// </summary>
IList<IProjectOrSolution> ProjectsOrSolutionsToBuild { get; }
/// <summary>
/// Gets the supplied build configuration.
/// </summary>
TAutobuildOptions Options { get; }
/// <summary>
/// The set of build actions used during the autobuilder.
/// Could be real system operations, or a stub for testing.
/// </summary>
IBuildActions Actions { get; }
/// <summary>
/// Log a given build event to the console.
/// </summary>
/// <param name="format">The format string.</param>
/// <param name="args">Inserts to the format string.</param>
void Log(Severity severity, string format, params object[] args);
/// <summary>
/// Value of CODEQL_EXTRACTOR_<LANG>_ROOT environment variable.
/// </summary>
string? CodeQLExtractorLangRoot { get; }
/// <summary>
/// Value of CODEQL_PLATFORM environment variable.
/// </summary>
string? CodeQlPlatform { get; }
}
/// <summary>
/// Main application logic, containing all data
/// gathered from the project and filesystem.
@@ -93,7 +40,7 @@ namespace Semmle.Autobuild.Shared
/// The overall design is intended to be extensible so that in theory,
/// it should be possible to add new build rules without touching this code.
/// </summary>
public abstract class Autobuilder<TAutobuildOptions> : IAutobuilder<TAutobuildOptions> where TAutobuildOptions : AutobuildOptionsShared
public abstract class Autobuilder
{
/// <summary>
/// Full file paths of files found in the project directory, as well as
@@ -113,6 +60,16 @@ namespace Semmle.Autobuild.Shared
public IEnumerable<(string, int)> GetExtensions(params string[] extensions) =>
Paths.Where(p => extensions.Contains(Path.GetExtension(p.Item1)));
/// <summary>
/// Gets all paths matching a particular filename, as well as
/// their distance from the project root folder. The list is sorted
/// by distance in ascending order.
/// </summary>
/// <param name="name">The filename to find.</param>
/// <returns>Possibly empty sequence of paths with the given filename.</returns>
public IEnumerable<(string, int)> GetFilename(string name) =>
Paths.Where(p => Actions.GetFileName(p.Item1) == name);
/// <summary>
/// Holds if a given path, relative to the root of the source directory
/// was found.
@@ -158,7 +115,7 @@ namespace Semmle.Autobuild.Shared
/// <summary>
/// Gets the supplied build configuration.
/// </summary>
public TAutobuildOptions Options { get; }
public AutobuildOptions Options { get; }
/// <summary>
/// The set of build actions used during the autobuilder.
@@ -166,7 +123,7 @@ namespace Semmle.Autobuild.Shared
/// </summary>
public IBuildActions Actions { get; }
private IEnumerable<IProjectOrSolution>? FindFiles(string extension, Func<string, ProjectOrSolution<TAutobuildOptions>> create)
private IEnumerable<IProjectOrSolution>? FindFiles(string extension, Func<string, ProjectOrSolution> create)
{
var matchingFiles = GetExtensions(extension)
.Select(p => (ProjectOrSolution: create(p.Item1), DistanceFromRoot: p.Item2))
@@ -189,7 +146,7 @@ namespace Semmle.Autobuild.Shared
/// solution file and tools.
/// </summary>
/// <param name="options">The command line options.</param>
protected Autobuilder(IBuildActions actions, TAutobuildOptions options)
protected Autobuilder(IBuildActions actions, AutobuildOptions options)
{
Actions = actions;
Options = options;
@@ -210,7 +167,7 @@ namespace Semmle.Autobuild.Shared
foreach (var solution in options.Solution)
{
if (actions.FileExists(solution))
ret.Add(new Solution<TAutobuildOptions>(this, solution, true));
ret.Add(new Solution(this, solution, true));
else
Log(Severity.Error, $"The specified project or solution file {solution} was not found");
}
@@ -218,17 +175,17 @@ namespace Semmle.Autobuild.Shared
}
// First look for `.proj` files
ret = FindFiles(".proj", f => new Project<TAutobuildOptions>(this, f))?.ToList();
ret = FindFiles(".proj", f => new Project(this, f))?.ToList();
if (ret is not null)
return ret;
// Then look for `.sln` files
ret = FindFiles(".sln", f => new Solution<TAutobuildOptions>(this, f, false))?.ToList();
ret = FindFiles(".sln", f => new Solution(this, f, false))?.ToList();
if (ret is not null)
return ret;
// Finally look for language specific project files, e.g. `.csproj` files
ret = FindFiles(this.Options.Language.ProjectExtension, f => new Project<TAutobuildOptions>(this, f))?.ToList();
ret = FindFiles(this.Options.Language.ProjectExtension, f => new Project(this, f))?.ToList();
return ret ?? new List<IProjectOrSolution>();
});

View File

@@ -7,11 +7,11 @@ namespace Semmle.Autobuild.Shared
/// <summary>
/// Auto-detection of build scripts.
/// </summary>
public class BuildCommandAutoRule : IBuildRule<AutobuildOptionsShared>
public class BuildCommandAutoRule : IBuildRule
{
private readonly WithDotNet<AutobuildOptionsShared> withDotNet;
private readonly WithDotNet withDotNet;
public BuildCommandAutoRule(WithDotNet<AutobuildOptionsShared> withDotNet)
public BuildCommandAutoRule(WithDotNet withDotNet)
{
this.withDotNet = withDotNet;
}
@@ -31,7 +31,7 @@ namespace Semmle.Autobuild.Shared
"build"
};
public BuildScript Analyse(IAutobuilder<AutobuildOptionsShared> builder, bool auto)
public BuildScript Analyse(Autobuilder builder, bool auto)
{
builder.Log(Severity.Info, "Attempting to locate build script");

View File

@@ -3,16 +3,16 @@
/// <summary>
/// Execute the build_command rule.
/// </summary>
public class BuildCommandRule : IBuildRule<AutobuildOptionsShared>
public class BuildCommandRule : IBuildRule
{
private readonly WithDotNet<AutobuildOptionsShared> withDotNet;
private readonly WithDotNet withDotNet;
public BuildCommandRule(WithDotNet<AutobuildOptionsShared> withDotNet)
public BuildCommandRule(WithDotNet withDotNet)
{
this.withDotNet = withDotNet;
}
public BuildScript Analyse(IAutobuilder<AutobuildOptionsShared> builder, bool auto)
public BuildScript Analyse(Autobuilder builder, bool auto)
{
if (builder.Options.BuildCommand is null)
return BuildScript.Failure;

View File

@@ -6,14 +6,14 @@ namespace Semmle.Autobuild.Shared
/// <summary>
/// A build rule using msbuild.
/// </summary>
public class MsBuildRule : IBuildRule<AutobuildOptionsShared>
public class MsBuildRule : IBuildRule
{
/// <summary>
/// The name of the msbuild command.
/// </summary>
private const string msBuild = "msbuild";
public BuildScript Analyse(IAutobuilder<AutobuildOptionsShared> builder, bool auto)
public BuildScript Analyse(Autobuilder builder, bool auto)
{
if (!builder.ProjectsOrSolutionsToBuild.Any())
return BuildScript.Failure;
@@ -27,8 +27,8 @@ namespace Semmle.Autobuild.Shared
{
var firstSolution = builder.ProjectsOrSolutionsToBuild.OfType<ISolution>().FirstOrDefault();
vsTools = firstSolution is not null
? BuildTools.FindCompatibleVcVars(builder.Actions, firstSolution)
: BuildTools.VcVarsAllBatFiles(builder.Actions).OrderByDescending(b => b.ToolsVersion).FirstOrDefault();
? BuildTools.FindCompatibleVcVars(builder.Actions, firstSolution)
: BuildTools.VcVarsAllBatFiles(builder.Actions).OrderByDescending(b => b.ToolsVersion).FirstOrDefault();
}
if (vsTools is null && builder.Actions.IsWindows())
@@ -123,7 +123,7 @@ namespace Semmle.Autobuild.Shared
///
/// Returns <code>null</code> when no version is specified.
/// </summary>
public static VcVarsBatFile? GetVcVarsBatFile<TAutobuildOptions>(IAutobuilder<TAutobuildOptions> builder) where TAutobuildOptions : AutobuildOptionsShared
public static VcVarsBatFile? GetVcVarsBatFile(Autobuilder builder)
{
VcVarsBatFile? vsTools = null;
@@ -154,7 +154,7 @@ namespace Semmle.Autobuild.Shared
/// <summary>
/// Returns a script for downloading `nuget.exe` from nuget.org.
/// </summary>
private static BuildScript DownloadNugetExe<TAutobuildOptions>(IAutobuilder<TAutobuildOptions> builder, string path) where TAutobuildOptions : AutobuildOptionsShared =>
private static BuildScript DownloadNugetExe(Autobuilder builder, string path) =>
BuildScript.Create(_ =>
{
builder.Log(Severity.Info, "Attempting to download nuget.exe");

View File

@@ -12,7 +12,7 @@ namespace Semmle.Autobuild.Shared
/// C# project files come in 2 flavours, .Net core and msbuild, but they
/// have the same file extension.
/// </summary>
public class Project<TAutobuildOptions> : ProjectOrSolution<TAutobuildOptions> where TAutobuildOptions : AutobuildOptionsShared
public class Project : ProjectOrSolution
{
/// <summary>
/// Holds if this project is for .Net core.
@@ -23,13 +23,13 @@ namespace Semmle.Autobuild.Shared
public Version ToolsVersion { get; private set; }
private readonly Lazy<List<Project<TAutobuildOptions>>> includedProjectsLazy;
private readonly Lazy<List<Project>> includedProjectsLazy;
public override IEnumerable<IProjectOrSolution> IncludedProjects => includedProjectsLazy.Value;
public Project(Autobuilder<TAutobuildOptions> builder, string path) : base(builder, path)
public Project(Autobuilder builder, string path) : base(builder, path)
{
ToolsVersion = new Version();
includedProjectsLazy = new Lazy<List<Project<TAutobuildOptions>>>(() => new List<Project<TAutobuildOptions>>());
includedProjectsLazy = new Lazy<List<Project>>(() => new List<Project>());
if (!builder.Actions.FileExists(FullPath))
return;
@@ -70,9 +70,9 @@ namespace Semmle.Autobuild.Shared
}
}
includedProjectsLazy = new Lazy<List<Project<TAutobuildOptions>>>(() =>
includedProjectsLazy = new Lazy<List<Project>>(() =>
{
var ret = new List<Project<TAutobuildOptions>>();
var ret = new List<Project>();
// The documentation on `.proj` files is very limited, but it appears that both
// `<ProjectFile Include="X"/>` and `<ProjectFiles Include="X"/>` is valid
var mgr = new XmlNamespaceManager(projFile.NameTable);
@@ -89,7 +89,7 @@ namespace Semmle.Autobuild.Shared
}
var includePath = builder.Actions.PathCombine(include.Value.Split('\\', StringSplitOptions.RemoveEmptyEntries));
ret.Add(new Project<TAutobuildOptions>(builder, builder.Actions.PathCombine(DirectoryName, includePath)));
ret.Add(new Project(builder, builder.Actions.PathCombine(DirectoryName, includePath)));
}
return ret;
});

View File

@@ -20,13 +20,13 @@ namespace Semmle.Autobuild.Shared
IEnumerable<IProjectOrSolution> IncludedProjects { get; }
}
public abstract class ProjectOrSolution<TAutobuildOptions> : IProjectOrSolution where TAutobuildOptions : AutobuildOptionsShared
public abstract class ProjectOrSolution : IProjectOrSolution
{
public string FullPath { get; }
public string DirectoryName { get; }
protected ProjectOrSolution(Autobuilder<TAutobuildOptions> builder, string path)
protected ProjectOrSolution(Autobuilder builder, string path)
{
FullPath = builder.Actions.GetFullPath(path);
DirectoryName = builder.Actions.GetDirectoryName(path) ?? "";

View File

@@ -40,11 +40,11 @@ namespace Semmle.Autobuild.Shared
/// <summary>
/// A solution file on the filesystem, read using Microsoft.Build.
/// </summary>
internal class Solution<TAutobuildOptions> : ProjectOrSolution<TAutobuildOptions>, ISolution where TAutobuildOptions : AutobuildOptionsShared
internal class Solution : ProjectOrSolution, ISolution
{
private readonly SolutionFile? solution;
private readonly IEnumerable<Project<TAutobuildOptions>> includedProjects;
private readonly IEnumerable<Project> includedProjects;
public override IEnumerable<IProjectOrSolution> IncludedProjects => includedProjects;
@@ -57,7 +57,7 @@ namespace Semmle.Autobuild.Shared
public string DefaultPlatformName =>
solution is null ? "" : solution.GetDefaultPlatformName();
public Solution(Autobuilder<TAutobuildOptions> builder, string path, bool allowProject) : base(builder, path)
public Solution(Autobuilder builder, string path, bool allowProject) : base(builder, path)
{
try
{
@@ -69,19 +69,19 @@ namespace Semmle.Autobuild.Shared
// that scenario as a solution with just that one project
if (allowProject)
{
includedProjects = new[] { new Project<TAutobuildOptions>(builder, path) };
includedProjects = new[] { new Project(builder, path) };
return;
}
builder.Log(Severity.Info, $"Unable to read solution file {path}.");
includedProjects = Array.Empty<Project<TAutobuildOptions>>();
includedProjects = Array.Empty<Project>();
return;
}
includedProjects = solution.ProjectsInOrder
.Where(p => p.ProjectType == SolutionProjectType.KnownToBeMSBuildFormat)
.Select(p => builder.Actions.PathCombine(DirectoryName, builder.Actions.PathCombine(p.RelativePath.Split('\\', StringSplitOptions.RemoveEmptyEntries))))
.Select(p => new Project<TAutobuildOptions>(builder, p))
.Select(p => new Project(builder, p))
.ToArray();
}

View File

@@ -1,7 +1,3 @@
## 1.3.4
No user-facing changes.
## 1.3.3
No user-facing changes.

View File

@@ -1,4 +1,4 @@
/**
/*
* Provides reusable predicates related to Solorigate
*/

View File

@@ -1,3 +0,0 @@
## 1.3.4
No user-facing changes.

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 1.3.4
lastReleaseVersion: 1.3.3

View File

@@ -1,5 +1,5 @@
name: codeql/csharp-solorigate-all
version: 1.3.5-dev
version: 1.3.4-dev
groups:
- csharp
- solorigate

View File

@@ -1,7 +1,3 @@
## 1.3.4
No user-facing changes.
## 1.3.3
No user-facing changes.

View File

@@ -1,3 +0,0 @@
## 1.3.4
No user-facing changes.

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 1.3.4
lastReleaseVersion: 1.3.3

View File

@@ -1,5 +1,5 @@
name: codeql/csharp-solorigate-queries
version: 1.3.5-dev
version: 1.3.4-dev
groups:
- csharp
- solorigate

View File

@@ -1,9 +1,3 @@
## 0.4.4
### Minor Analysis Improvements
* The `[Summary|Sink|Source]ModelCsv` classes have been deprecated and Models as Data models are defined as data extensions instead.
## 0.4.3
No user-facing changes.

View File

@@ -1,5 +1,4 @@
## 0.4.4
### Minor Analysis Improvements
* The `[Summary|Sink|Source]ModelCsv` classes have been deprecated and Models as Data models are defined as data extensions instead.
---
category: minorAnalysis
---
* The `[Summary|Sink|Source]ModelCsv` classes have been deprecated and Models as Data models are defined as data extensions instead.

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 0.4.4
lastReleaseVersion: 0.4.3

View File

@@ -1,4 +1,4 @@
/**
/*
* Predicates that help detect potential non-cryptographic hash functions
*
* By themselves, non-cryptographic functions are common and not dangerous

View File

@@ -1,5 +1,5 @@
name: codeql/csharp-all
version: 0.4.5-dev
version: 0.4.4-dev
groups: csharp
dbscheme: semmlecode.csharp.dbscheme
extractor: csharp

View File

@@ -47,19 +47,19 @@ private module Cached {
}
cached
ReadAccess getAFirstReadExt(DefinitionExt def) {
ReadAccess getAFirstRead(Definition def) {
exists(BasicBlock bb1, int i1, BasicBlock bb2, int i2 |
def.definesAt(_, bb1, i1, _) and
adjacentDefReadExt(def, _, bb1, i1, bb2, i2) and
def.definesAt(_, bb1, i1) and
adjacentDefRead(def, bb1, i1, bb2, i2) and
result = bb2.getNode(i2)
)
}
cached
predicate hasAdjacentReadsExt(DefinitionExt def, ReadAccess first, ReadAccess second) {
predicate hasAdjacentReads(Definition def, ReadAccess first, ReadAccess second) {
exists(BasicBlock bb1, int i1, BasicBlock bb2, int i2 |
first = bb1.getNode(i1) and
adjacentDefReadExt(def, _, bb1, i1, bb2, i2) and
adjacentDefRead(def, bb1, i1, bb2, i2) and
second = bb2.getNode(i2)
)
}
@@ -68,35 +68,9 @@ private module Cached {
Definition getAPhiInput(PhiNode phi) { phiHasInputFromBlock(phi, result, _) }
cached
predicate lastRefBeforeRedefExt(DefinitionExt def, BasicBlock bb, int i, DefinitionExt next) {
lastRefRedefExt(def, _, bb, i, next)
}
}
import Cached
private module Deprecated {
private import CIL
deprecated 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)
)
}
deprecated 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)
)
}
deprecated predicate lastRefBeforeRedef(Definition def, BasicBlock bb, int i, Definition next) {
predicate lastRefBeforeRedef(Definition def, BasicBlock bb, int i, Definition next) {
lastRefRedef(def, bb, i, next)
}
}
import Deprecated
import Cached

View File

@@ -103,6 +103,7 @@ abstract class Completion extends TCompletion {
* otherwise it is a normal non-Boolean completion.
*/
predicate isValidFor(ControlFlowElement cfe) {
cfe instanceof NonReturningCall and
this = cfe.(NonReturningCall).getACompletion()
or
this = TThrowCompletion(cfe.(TriedControlFlowElement).getAThrownException())

View File

@@ -907,13 +907,9 @@ module TestOutput {
query predicate edges(RelevantNode pred, RelevantNode succ, string attr, string val) {
attr = "semmle.label" and
val =
strictconcat(SuccessorType t, string s |
succ = getASuccessor(pred, t) and
if successorTypeIsSimple(t) then s = "" else s = t.toString()
|
s, ", " order by s
)
exists(SuccessorType t | succ = getASuccessor(pred, t) |
if successorTypeIsSimple(t) then val = "" else val = t.toString()
)
or
attr = "semmle.order" and
val =

View File

@@ -90,6 +90,43 @@ private import internal.FlowSummaryImpl::Public
private import internal.FlowSummaryImpl::Private::External
private import internal.FlowSummaryImplSpecific
/**
* A module importing the frameworks that provide external flow data,
* ensuring that they are visible to the taint tracking / data flow library.
*/
private module Frameworks {
private import semmle.code.csharp.frameworks.EntityFramework
private import semmle.code.csharp.frameworks.JsonNET
private import semmle.code.csharp.frameworks.ServiceStack
private import semmle.code.csharp.frameworks.Sql
private import semmle.code.csharp.frameworks.System
private import semmle.code.csharp.frameworks.system.CodeDom
private import semmle.code.csharp.frameworks.system.Collections
private import semmle.code.csharp.frameworks.system.collections.Generic
private import semmle.code.csharp.frameworks.system.collections.Specialized
private import semmle.code.csharp.frameworks.system.Data
private import semmle.code.csharp.frameworks.system.data.Common
private import semmle.code.csharp.frameworks.system.Diagnostics
private import semmle.code.csharp.frameworks.system.Linq
private import semmle.code.csharp.frameworks.system.Net
private import semmle.code.csharp.frameworks.system.net.Mail
private import semmle.code.csharp.frameworks.system.IO
private import semmle.code.csharp.frameworks.system.io.Compression
private import semmle.code.csharp.frameworks.system.runtime.CompilerServices
private import semmle.code.csharp.frameworks.system.Security
private import semmle.code.csharp.frameworks.system.security.Cryptography
private import semmle.code.csharp.frameworks.system.security.cryptography.X509Certificates
private import semmle.code.csharp.frameworks.system.Text
private import semmle.code.csharp.frameworks.system.text.RegularExpressions
private import semmle.code.csharp.frameworks.system.threading.Tasks
private import semmle.code.csharp.frameworks.system.Web
private import semmle.code.csharp.frameworks.system.web.ui.WebControls
private import semmle.code.csharp.frameworks.system.Xml
private import semmle.code.csharp.security.dataflow.flowsinks.Html
private import semmle.code.csharp.security.dataflow.flowsources.Local
private import semmle.code.csharp.security.dataflow.XSSSinks
}
/**
* DEPRECATED: Define source models as data extensions instead.
*

View File

@@ -6,6 +6,7 @@ private import DataFlowPublic
private import DataFlowPrivate
private import FlowSummaryImpl as FlowSummaryImpl
private import semmle.code.csharp.dataflow.FlowSummary as FlowSummary
private import semmle.code.csharp.dataflow.ExternalFlow
private import semmle.code.csharp.dispatch.Dispatch
private import semmle.code.csharp.dispatch.RuntimeCallable
private import semmle.code.csharp.frameworks.system.Collections

View File

@@ -18,7 +18,6 @@ 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.cil.Ssa::Ssa as CilSsa
private import semmle.code.cil.internal.SsaImpl as CilSsaImpl
/** Gets the callable in which this node occurs. */
DataFlowCallable nodeGetEnclosingCallable(NodeImpl n) { result = n.getEnclosingCallableImpl() }
@@ -175,7 +174,7 @@ predicate hasNodePath(ControlFlowReachabilityConfiguration conf, ExprNode n1, No
cfn = n1.getControlFlowNode() and
ssaDef.getADefinition() = def and
ssaDef.getControlFlowNode() = cfnDef and
n2.(SsaDefinitionExtNode).getDefinitionExt() = ssaDef
n2.(SsaDefinitionNode).getDefinition() = ssaDef
)
}
@@ -307,28 +306,17 @@ module LocalFlow {
}
}
/** An SSA definition into which another SSA definition may flow. */
private class SsaInputDefinitionExtNode extends SsaDefinitionExtNode {
SsaInputDefinitionExtNode() {
def instanceof Ssa::PhiNode
or
def instanceof SsaImpl::PhiReadNode
or
def instanceof LocalFlow::UncertainExplicitSsaDefinition
}
}
/**
* Holds if `nodeFrom` is a last node referencing SSA definition `def`, which
* can reach `next`.
*/
private predicate localFlowSsaInputFromDef(
Node nodeFrom, SsaImpl::DefinitionExt def, SsaInputDefinitionExtNode next
Node nodeFrom, Ssa::Definition def, Ssa::Definition next
) {
exists(ControlFlow::BasicBlock bb, int i |
SsaImpl::lastRefBeforeRedefExt(def, bb, i, next.getDefinitionExt()) and
def.definesAt(_, bb, i, _) and
def = getSsaDefinitionExt(nodeFrom)
SsaImpl::lastRefBeforeRedef(def, bb, i, next) and
def.definesAt(_, bb, i) and
def = getSsaDefinition(nodeFrom)
)
}
@@ -336,17 +324,18 @@ module LocalFlow {
* Holds if `read` is a last node reading SSA definition `def`, which
* can reach `next`.
*/
predicate localFlowSsaInputFromRead(
Node read, SsaImpl::DefinitionExt def, SsaInputDefinitionExtNode next
predicate localFlowSsaInputFromExpr(
ControlFlow::Node read, Ssa::Definition def, Ssa::Definition next
) {
exists(ControlFlow::BasicBlock bb, int i |
SsaImpl::lastRefBeforeRedefExt(def, bb, i, next.getDefinitionExt()) and
read.asExprAtNode(bb.getNode(i)) instanceof AssignableRead
SsaImpl::lastRefBeforeRedef(def, bb, i, next) and
read = bb.getNode(i) and
read.getElement() instanceof AssignableRead
)
}
private SsaImpl::DefinitionExt getSsaDefinitionExt(Node n) {
result = n.(SsaDefinitionExtNode).getDefinitionExt()
private Ssa::Definition getSsaDefinition(Node n) {
result = n.(SsaDefinitionNode).getDefinition()
or
result = n.(ExplicitParameterNode).getSsaDefinition()
}
@@ -355,9 +344,9 @@ module LocalFlow {
* Holds if there is a local use-use flow step from `nodeFrom` to `nodeTo`
* involving SSA definition `def`.
*/
predicate localSsaFlowStepUseUse(SsaImpl::DefinitionExt def, Node nodeFrom, Node nodeTo) {
predicate localSsaFlowStepUseUse(Ssa::Definition def, Node nodeFrom, Node nodeTo) {
exists(ControlFlow::Node cfnFrom, ControlFlow::Node cfnTo |
SsaImpl::adjacentReadPairSameVarExt(def, cfnFrom, cfnTo) and
SsaImpl::adjacentReadPairSameVar(def, cfnFrom, cfnTo) and
nodeTo = TExprNode(cfnTo) and
nodeFrom = TExprNode(cfnFrom)
)
@@ -367,22 +356,31 @@ module LocalFlow {
* Holds if there is a local flow step from `nodeFrom` to `nodeTo` involving
* SSA definition `def`.
*/
predicate localSsaFlowStep(SsaImpl::DefinitionExt def, Node nodeFrom, Node nodeTo) {
predicate localSsaFlowStep(Ssa::Definition def, Node nodeFrom, Node nodeTo) {
// Flow from SSA definition/parameter to first read
def = getSsaDefinitionExt(nodeFrom) and
SsaImpl::firstReadSameVarExt(def, nodeTo.(ExprNode).getControlFlowNode())
exists(ControlFlow::Node cfn |
def = getSsaDefinition(nodeFrom) and
nodeTo.asExprAtNode(cfn) = def.getAFirstReadAtNode(cfn)
)
or
// Flow from read to next read
localSsaFlowStepUseUse(def, nodeFrom.(PostUpdateNode).getPreUpdateNode(), nodeTo)
or
// Flow into phi (read)/uncertain SSA definition node from def
localFlowSsaInputFromDef(nodeFrom, def, nodeTo)
// Flow into phi/uncertain SSA definition node from def
exists(Ssa::Definition next |
localFlowSsaInputFromDef(nodeFrom, def, next) and
next = nodeTo.(SsaDefinitionNode).getDefinition()
|
def = next.(Ssa::PhiNode).getAnInput()
or
def = next.(LocalFlow::UncertainExplicitSsaDefinition).getPriorDefinition()
)
}
/**
* Holds if the source variable of SSA definition `def` is an instance field.
*/
predicate usesInstanceField(SsaImpl::DefinitionExt def) {
predicate usesInstanceField(Ssa::Definition def) {
exists(Ssa::SourceVariables::FieldOrPropSourceVariable fp | fp = def.getSourceVariable() |
not fp.getAssignable().(Modifiable).isStatic()
)
@@ -391,23 +389,25 @@ module LocalFlow {
predicate localFlowCapturedVarStep(Node nodeFrom, ImplicitCapturedArgumentNode nodeTo) {
// Flow from SSA definition to implicit captured variable argument
exists(Ssa::ExplicitDefinition def, ControlFlow::Nodes::ElementNode call |
def = getSsaDefinitionExt(nodeFrom) and
def = getSsaDefinition(nodeFrom) and
def.isCapturedVariableDefinitionFlowIn(_, call, _) and
nodeTo = TImplicitCapturedArgumentNode(call, def.getSourceVariable().getAssignable())
)
}
private module CilFlow {
private import semmle.code.cil.internal.SsaImpl as CilSsaImpl
/**
* Holds if `nodeFrom` is a last node referencing SSA definition `def`, which
* can reach `next`.
*/
private predicate localFlowCilSsaInput(
Node nodeFrom, CilSsaImpl::DefinitionExt def, CilSsaImpl::DefinitionExt next
Node nodeFrom, CilSsa::Definition def, CilSsa::Definition next
) {
exists(CIL::BasicBlock bb, int i | CilSsaImpl::lastRefBeforeRedefExt(def, bb, i, next) |
def.definesAt(_, bb, i, _) and
def = nodeFrom.(CilSsaDefinitionExtNode).getDefinition()
exists(CIL::BasicBlock bb, int i | CilSsaImpl::lastRefBeforeRedef(def, bb, i, next) |
def.definesAt(_, bb, i) and
def = nodeFrom.(CilSsaDefinitionNode).getDefinition()
or
nodeFrom = TCilExprNode(bb.getNode(i).(CIL::ReadAccess))
)
@@ -417,33 +417,30 @@ module LocalFlow {
* Holds if there is a local flow step from `nodeFrom` to `nodeTo` involving
* CIL SSA definition `def`.
*/
private predicate localCilSsaFlowStep(CilSsaImpl::DefinitionExt def, Node nodeFrom, Node nodeTo) {
private predicate localCilSsaFlowStep(CilSsa::Definition def, Node nodeFrom, Node nodeTo) {
// Flow into SSA definition
exists(CIL::VariableUpdate vu |
vu = def.(CilSsa::Definition).getVariableUpdate() and
vu = def.getVariableUpdate() and
vu.getSource() = asCilDataFlowNode(nodeFrom) and
def = nodeTo.(CilSsaDefinitionExtNode).getDefinition()
def = nodeTo.(CilSsaDefinitionNode).getDefinition()
)
or
// Flow from SSA definition to first read
def = nodeFrom.(CilSsaDefinitionExtNode).getDefinition() and
nodeTo = TCilExprNode(CilSsaImpl::getAFirstReadExt(def))
def = nodeFrom.(CilSsaDefinitionNode).getDefinition() and
nodeTo = TCilExprNode(CilSsaImpl::getAFirstRead(def))
or
// Flow from read to next read
exists(CIL::ReadAccess readFrom, CIL::ReadAccess readTo |
CilSsaImpl::hasAdjacentReadsExt(def, readFrom, readTo) and
CilSsaImpl::hasAdjacentReads(def, readFrom, readTo) and
nodeTo = TCilExprNode(readTo) and
nodeFrom = TCilExprNode(readFrom)
)
or
// Flow into phi (read) node
exists(CilSsaImpl::DefinitionExt phi |
// Flow into phi node
exists(CilSsa::PhiNode phi |
localFlowCilSsaInput(nodeFrom, def, phi) and
phi = nodeTo.(CilSsaDefinitionExtNode).getDefinition()
|
phi instanceof CilSsa::PhiNode
or
phi instanceof CilSsaImpl::PhiReadNode
phi = nodeTo.(CilSsaDefinitionNode).getDefinition() and
def = CilSsaImpl::getAPhiInput(phi)
)
}
@@ -469,7 +466,7 @@ module LocalFlow {
}
predicate localFlowStepCommon(Node nodeFrom, Node nodeTo) {
exists(SsaImpl::DefinitionExt def |
exists(Ssa::Definition def |
localSsaFlowStep(def, nodeFrom, nodeTo) and
not usesInstanceField(def)
)
@@ -531,20 +528,26 @@ module LocalFlow {
predicate simpleLocalFlowStep(Node nodeFrom, Node nodeTo) {
LocalFlow::localFlowStepCommon(nodeFrom, nodeTo)
or
exists(SsaImpl::DefinitionExt def |
exists(Ssa::Definition def |
LocalFlow::localSsaFlowStepUseUse(def, nodeFrom, nodeTo) and
not FlowSummaryImpl::Private::Steps::prohibitsUseUseFlow(nodeFrom, _) and
not LocalFlow::usesInstanceField(def)
)
or
// Flow into phi (read)/uncertain SSA definition node from read
exists(SsaImpl::DefinitionExt def, Node read |
LocalFlow::localFlowSsaInputFromRead(read, def, nodeTo)
// Flow into phi/uncertain SSA definition node from read
exists(Ssa::Definition def, ControlFlow::Node read, Ssa::Definition next |
LocalFlow::localFlowSsaInputFromExpr(read, def, next) and
next = nodeTo.(SsaDefinitionNode).getDefinition() and
def =
[
next.(Ssa::PhiNode).getAnInput(),
next.(LocalFlow::UncertainExplicitSsaDefinition).getPriorDefinition()
]
|
nodeFrom = read and
exists(nodeFrom.asExprAtNode(read)) and
not FlowSummaryImpl::Private::Steps::prohibitsUseUseFlow(nodeFrom, _)
or
nodeFrom.(PostUpdateNode).getPreUpdateNode() = read
exists(nodeFrom.(PostUpdateNode).getPreUpdateNode().asExprAtNode(read))
)
or
LocalFlow::localFlowCapturedVarStep(nodeFrom, nodeTo)
@@ -810,8 +813,8 @@ private module Cached {
cfn.getElement() instanceof Expr
} or
TCilExprNode(CIL::Expr e) { e.getImplementation() instanceof CIL::BestImplementation } or
TCilSsaDefinitionExtNode(CilSsaImpl::DefinitionExt def) or
TSsaDefinitionExtNode(SsaImpl::DefinitionExt def) {
TCilSsaDefinitionNode(CilSsa::Definition def) or
TSsaDefinitionNode(Ssa::Definition def) {
// Handled by `TExplicitParameterNode` below
not def.(Ssa::ExplicitDefinition).getADefinition() instanceof
AssignableDefinitions::ImplicitParameterDefinition
@@ -877,18 +880,24 @@ private module Cached {
or
LocalFlow::localSsaFlowStepUseUse(_, nodeFrom, nodeTo)
or
exists(SsaImpl::DefinitionExt def |
exists(Ssa::Definition def |
LocalFlow::localSsaFlowStep(def, nodeFrom, nodeTo) and
LocalFlow::usesInstanceField(def)
)
or
// Flow into phi (read)/uncertain SSA definition node from read
exists(SsaImpl::DefinitionExt def, Node read |
LocalFlow::localFlowSsaInputFromRead(read, def, nodeTo)
// Flow into phi/uncertain SSA definition node from read
exists(Ssa::Definition def, ControlFlow::Node read, Ssa::Definition next |
LocalFlow::localFlowSsaInputFromExpr(read, def, next) and
next = nodeTo.(SsaDefinitionNode).getDefinition() and
def =
[
next.(Ssa::PhiNode).getAnInput(),
next.(LocalFlow::UncertainExplicitSsaDefinition).getPriorDefinition()
]
|
nodeFrom = read
exists(nodeFrom.asExprAtNode(read))
or
nodeFrom.(PostUpdateNode).getPreUpdateNode() = read
exists(nodeFrom.(PostUpdateNode).getPreUpdateNode().asExprAtNode(read))
)
or
// Simple flow through library code is included in the exposed local
@@ -936,11 +945,9 @@ import Cached
/** Holds if `n` should be hidden from path explanations. */
predicate nodeIsHidden(Node n) {
exists(SsaImpl::DefinitionExt def | def = n.(SsaDefinitionExtNode).getDefinitionExt() |
exists(Ssa::Definition def | def = n.(SsaDefinitionNode).getDefinition() |
def instanceof Ssa::PhiNode
or
def instanceof SsaImpl::PhiReadNode
or
def instanceof Ssa::ImplicitEntryDefinition
or
def instanceof Ssa::ImplicitCallDefinition
@@ -971,13 +978,13 @@ predicate nodeIsHidden(Node n) {
}
/** A CIL SSA definition, viewed as a node in a data flow graph. */
class CilSsaDefinitionExtNode extends NodeImpl, TCilSsaDefinitionExtNode {
CilSsaImpl::DefinitionExt def;
class CilSsaDefinitionNode extends NodeImpl, TCilSsaDefinitionNode {
CilSsa::Definition def;
CilSsaDefinitionExtNode() { this = TCilSsaDefinitionExtNode(def) }
CilSsaDefinitionNode() { this = TCilSsaDefinitionNode(def) }
/** Gets the underlying SSA definition. */
CilSsaImpl::DefinitionExt getDefinition() { result = def }
CilSsa::Definition getDefinition() { result = def }
override DataFlowCallable getEnclosingCallableImpl() {
result.asCallable() = def.getBasicBlock().getFirstNode().getImplementation().getMethod()
@@ -993,13 +1000,13 @@ class CilSsaDefinitionExtNode extends NodeImpl, TCilSsaDefinitionExtNode {
}
/** An SSA definition, viewed as a node in a data flow graph. */
class SsaDefinitionExtNode extends NodeImpl, TSsaDefinitionExtNode {
SsaImpl::DefinitionExt def;
class SsaDefinitionNode extends NodeImpl, TSsaDefinitionNode {
Ssa::Definition def;
SsaDefinitionExtNode() { this = TSsaDefinitionExtNode(def) }
SsaDefinitionNode() { this = TSsaDefinitionNode(def) }
/** Gets the underlying SSA definition. */
SsaImpl::DefinitionExt getDefinitionExt() { result = def }
Ssa::Definition getDefinition() { result = def }
override DataFlowCallable getEnclosingCallableImpl() {
result.asCallable() = def.getEnclosingCallable()
@@ -1007,9 +1014,7 @@ class SsaDefinitionExtNode extends NodeImpl, TSsaDefinitionExtNode {
override Type getTypeImpl() { result = def.getSourceVariable().getType() }
override ControlFlow::Node getControlFlowNodeImpl() {
result = def.(Ssa::Definition).getControlFlowNode()
}
override ControlFlow::Node getControlFlowNodeImpl() { result = def.getControlFlowNode() }
override Location getLocationImpl() { result = def.getLocation() }
@@ -1103,11 +1108,13 @@ private module ParameterNodes {
* } }
* ```
*/
class ImplicitCapturedParameterNode extends ParameterNodeImpl, SsaDefinitionExtNode {
ImplicitCapturedParameterNode() { def instanceof SsaCapturedEntryDefinition }
class ImplicitCapturedParameterNode extends ParameterNodeImpl, SsaDefinitionNode {
override SsaCapturedEntryDefinition def;
ImplicitCapturedParameterNode() { def = this.getDefinition() }
/** Gets the captured variable that this implicit parameter models. */
LocalScopeVariable getVariable() { result = def.(SsaCapturedEntryDefinition).getVariable() }
LocalScopeVariable getVariable() { result = def.getVariable() }
override predicate isParameterOf(DataFlowCallable c, ParameterPosition pos) {
pos.isImplicitCapturedParameterPosition(def.getSourceVariable().getAssignable()) and
@@ -1342,12 +1349,12 @@ private module ReturnNodes {
* A data-flow node that represents an assignment to an `out` or a `ref`
* parameter.
*/
class OutRefReturnNode extends ReturnNode, SsaDefinitionExtNode {
class OutRefReturnNode extends ReturnNode, SsaDefinitionNode {
OutRefReturnKind kind;
OutRefReturnNode() {
exists(Parameter p |
this.getDefinitionExt().(Ssa::Definition).isLiveOutRefParameterDefinition(p) and
this.getDefinition().isLiveOutRefParameterDefinition(p) and
kind.getPosition() = p.getPosition()
|
p.isOut() and kind instanceof OutReturnKind
@@ -1431,11 +1438,11 @@ private module ReturnNodes {
* } }
* ```
*/
class ImplicitCapturedReturnNode extends ReturnNode, SsaDefinitionExtNode {
class ImplicitCapturedReturnNode extends ReturnNode, SsaDefinitionNode {
private Ssa::ExplicitDefinition edef;
ImplicitCapturedReturnNode() {
edef = this.getDefinitionExt() and
edef = this.getDefinition() and
edef.isCapturedVariableDefinitionFlowOut(_, _)
}
@@ -1443,8 +1450,8 @@ private module ReturnNodes {
* Holds if the value at this node may flow out to the implicit call definition
* at `node`, using one or more calls.
*/
predicate flowsOutTo(SsaDefinitionExtNode node, boolean additionalCalls) {
edef.isCapturedVariableDefinitionFlowOut(node.getDefinitionExt(), additionalCalls)
predicate flowsOutTo(SsaDefinitionNode node, boolean additionalCalls) {
edef.isCapturedVariableDefinitionFlowOut(node.getDefinition(), additionalCalls)
}
override ImplicitCapturedReturnKind getKind() {
@@ -1551,13 +1558,13 @@ private module OutNodes {
* A data-flow node that reads a value returned implicitly by a callable
* using a captured variable.
*/
class CapturedOutNode extends OutNode, SsaDefinitionExtNode {
class CapturedOutNode extends OutNode, SsaDefinitionNode {
private DataFlowCall call;
CapturedOutNode() {
exists(ImplicitCapturedReturnNode n, boolean additionalCalls, ControlFlow::Node cfn |
n.flowsOutTo(this, additionalCalls) and
cfn = this.getDefinitionExt().(Ssa::Definition).getControlFlowNode()
cfn = this.getDefinition().getControlFlowNode()
|
additionalCalls = false and call = csharpCall(_, cfn)
or
@@ -1569,7 +1576,7 @@ private module OutNodes {
override DataFlowCall getCall(ReturnKind kind) {
result = call and
kind.(ImplicitCapturedReturnKind).getVariable() =
this.getDefinitionExt().getSourceVariable().getAssignable()
this.getDefinition().getSourceVariable().getAssignable()
}
}
@@ -1850,7 +1857,7 @@ predicate readStep(Node node1, Content c, Node node2) {
exists(ForeachStmt fs, Ssa::ExplicitDefinition def |
x.hasDefPath(fs.getIterableExpr(), node1.getControlFlowNode(), def.getADefinition(),
def.getControlFlowNode()) and
node2.(SsaDefinitionExtNode).getDefinitionExt() = def and
node2.(SsaDefinitionNode).getDefinition() = def and
c instanceof ElementContent
)
or
@@ -1873,7 +1880,7 @@ predicate readStep(Node node1, Content c, Node node2) {
or
// item = variable in node1 = (..., variable, ...)
exists(AssignableDefinitions::TupleAssignmentDefinition tad, Ssa::ExplicitDefinition def |
node2.(SsaDefinitionExtNode).getDefinitionExt() = def and
node2.(SsaDefinitionNode).getDefinition() = def and
def.getADefinition() = tad and
tad.getLeaf() = item and
hasNodePath(x, node1, node2)
@@ -1882,7 +1889,7 @@ predicate readStep(Node node1, Content c, Node node2) {
// item = variable in node1 = (..., variable, ...) in a case/is var (..., ...)
te = any(PatternExpr pe).getAChildExpr*() and
exists(AssignableDefinitions::LocalVariableDefinition lvd, Ssa::ExplicitDefinition def |
node2.(SsaDefinitionExtNode).getDefinitionExt() = def and
node2.(SsaDefinitionNode).getDefinition() = def and
def.getADefinition() = lvd and
lvd.getDeclaration() = item and
hasNodePath(x, node1, node2)
@@ -2216,7 +2223,7 @@ 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) {
exists(SsaImpl::DefinitionExt def |
exists(Ssa::Definition def |
LocalFlow::localSsaFlowStep(def, nodeFrom, nodeTo) and
LocalFlow::usesInstanceField(def) and
preservesValue = true

View File

@@ -119,10 +119,10 @@ class ParameterNode extends Node instanceof ParameterNodeImpl {
}
/** A definition, viewed as a node in a data flow graph. */
class AssignableDefinitionNode extends Node, TSsaDefinitionExtNode {
class AssignableDefinitionNode extends Node, TSsaDefinitionNode {
private Ssa::ExplicitDefinition edef;
AssignableDefinitionNode() { this = TSsaDefinitionExtNode(edef) }
AssignableDefinitionNode() { this = TSsaDefinitionNode(edef) }
/** Gets the underlying definition. */
AssignableDefinition getDefinition() { result = this.getDefinitionAtNode(_) }

View File

@@ -1093,79 +1093,35 @@ private predicate adjacentDefRead(
}
private predicate adjacentDefReachesRead(
Definition def, SsaInput::SourceVariable v, SsaInput::BasicBlock bb1, int i1,
SsaInput::BasicBlock bb2, int i2
Definition def, SsaInput::BasicBlock bb1, int i1, SsaInput::BasicBlock bb2, int i2
) {
adjacentDefRead(def, bb1, i1, bb2, i2, v) and
(
exists(SsaInput::SourceVariable v | adjacentDefRead(def, bb1, i1, bb2, i2, v) |
def.definesAt(v, bb1, i1)
or
SsaInput::variableRead(bb1, i1, v, true)
)
or
exists(SsaInput::BasicBlock bb3, int i3 |
adjacentDefReachesRead(def, v, bb1, i1, bb3, i3) and
adjacentDefReachesRead(def, bb1, i1, bb3, i3) and
SsaInput::variableRead(bb3, i3, _, false) and
Impl::adjacentDefRead(def, bb3, i3, bb2, i2)
)
}
private predicate adjacentDefReachesReadExt(
DefinitionExt def, SsaInput::SourceVariable v, SsaInput::BasicBlock bb1, int i1,
SsaInput::BasicBlock bb2, int i2
) {
Impl::adjacentDefReadExt(def, v, bb1, i1, bb2, i2) and
(
def.definesAt(v, bb1, i1, _)
or
SsaInput::variableRead(bb1, i1, v, true)
)
or
exists(SsaInput::BasicBlock bb3, int i3 |
adjacentDefReachesReadExt(def, v, bb1, i1, bb3, i3) and
SsaInput::variableRead(bb3, i3, v, false) and
Impl::adjacentDefReadExt(def, v, bb3, i3, bb2, i2)
)
}
/** Same as `adjacentDefRead`, but skips uncertain reads. */
pragma[nomagic]
private predicate adjacentDefSkipUncertainReads(
Definition def, SsaInput::BasicBlock bb1, int i1, SsaInput::BasicBlock bb2, int i2
) {
exists(SsaInput::SourceVariable v |
adjacentDefReachesRead(def, v, bb1, i1, bb2, i2) and
SsaInput::variableRead(bb2, i2, v, true)
)
}
/** Same as `adjacentDefReadExt`, but skips uncertain reads. */
pragma[nomagic]
private predicate adjacentDefSkipUncertainReadsExt(
DefinitionExt def, SsaInput::BasicBlock bb1, int i1, SsaInput::BasicBlock bb2, int i2
) {
exists(SsaInput::SourceVariable v |
adjacentDefReachesReadExt(def, v, bb1, i1, bb2, i2) and
SsaInput::variableRead(bb2, i2, v, true)
)
adjacentDefReachesRead(def, bb1, i1, bb2, i2) and
SsaInput::variableRead(bb2, i2, _, true)
}
private predicate adjacentDefReachesUncertainRead(
Definition def, SsaInput::BasicBlock bb1, int i1, SsaInput::BasicBlock bb2, int i2
) {
exists(SsaInput::SourceVariable v |
adjacentDefReachesRead(def, v, bb1, i1, bb2, i2) and
SsaInput::variableRead(bb2, i2, v, false)
)
}
private predicate adjacentDefReachesUncertainReadExt(
DefinitionExt def, SsaInput::BasicBlock bb1, int i1, SsaInput::BasicBlock bb2, int i2
) {
exists(SsaInput::SourceVariable v |
adjacentDefReachesReadExt(def, v, bb1, i1, bb2, i2) and
SsaInput::variableRead(bb2, i2, v, false)
)
adjacentDefReachesRead(def, bb1, i1, bb2, i2) and
SsaInput::variableRead(bb2, i2, _, false)
}
/** Same as `lastRefRedef`, but skips uncertain reads. */
@@ -1355,19 +1311,6 @@ private module Cached {
)
}
/**
* Holds if the value defined at SSA definition `def` can reach a read at `cfn`,
* without passing through any other read.
*/
cached
predicate firstReadSameVarExt(DefinitionExt def, ControlFlow::Node cfn) {
exists(ControlFlow::BasicBlock bb1, int i1, ControlFlow::BasicBlock bb2, int i2 |
def.definesAt(_, bb1, i1, _) and
adjacentDefSkipUncertainReadsExt(def, bb1, i1, bb2, i2) and
cfn = bb2.getNode(i2)
)
}
/**
* Holds if the read at `cfn2` is a read of the same SSA definition `def`
* as the read at `cfn1`, and `cfn2` can be reached from `cfn1` without
@@ -1383,23 +1326,7 @@ private module Cached {
)
}
/**
* Holds if the read at `cfn2` is a read of the same SSA definition `def`
* as the read at `cfn1`, and `cfn2` can be reached from `cfn1` without
* passing through another read.
*/
cached
predicate adjacentReadPairSameVarExt(
DefinitionExt def, ControlFlow::Node cfn1, ControlFlow::Node cfn2
) {
exists(ControlFlow::BasicBlock bb1, int i1, ControlFlow::BasicBlock bb2, int i2 |
cfn1 = bb1.getNode(i1) and
variableReadActual(bb1, i1, _) and
adjacentDefSkipUncertainReadsExt(def, bb1, i1, bb2, i2) and
cfn2 = bb2.getNode(i2)
)
}
/** Same as `lastRefRedef`, but skips uncertain reads. */
cached
predicate lastRefBeforeRedef(Definition def, ControlFlow::BasicBlock bb, int i, Definition next) {
Impl::lastRefRedef(def, bb, i, next) and
@@ -1411,21 +1338,6 @@ private module Cached {
)
}
cached
predicate lastRefBeforeRedefExt(
DefinitionExt def, ControlFlow::BasicBlock bb, int i, DefinitionExt next
) {
exists(SsaInput::SourceVariable v |
Impl::lastRefRedefExt(def, v, bb, i, next) and
not SsaInput::variableRead(bb, i, v, false)
)
or
exists(SsaInput::BasicBlock bb0, int i0 |
Impl::lastRefRedefExt(def, _, bb0, i0, next) and
adjacentDefReachesUncertainReadExt(def, bb, i, bb0, i0)
)
}
cached
predicate lastReadSameVar(Definition def, ControlFlow::Node cfn) {
exists(ControlFlow::BasicBlock bb, int i |
@@ -1487,9 +1399,6 @@ class DefinitionExt extends Impl::DefinitionExt {
/** Gets the location of this definition. */
Location getLocation() { result = this.(Ssa::Definition).getLocation() }
/** Gets the enclosing callable of this definition. */
Callable getEnclosingCallable() { result = this.(Ssa::Definition).getEnclosingCallable() }
}
/**
@@ -1503,8 +1412,4 @@ class PhiReadNode extends DefinitionExt, Impl::PhiReadNode {
}
override Location getLocation() { result = this.getBasicBlock().getLocation() }
override Callable getEnclosingCallable() {
result = this.getSourceVariable().getEnclosingCallable()
}
}

View File

@@ -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.ExternalFlow
private import semmle.code.csharp.dataflow.internal.DataFlowPrivate as DataFlowPrivate
/**

View File

@@ -3,6 +3,7 @@
*/
import csharp
private import semmle.code.csharp.dataflow.ExternalFlow
/** Definitions relating to the `Json.NET` package. */
module JsonNET {

View File

@@ -6,6 +6,7 @@
*/
import csharp
private import semmle.code.csharp.dataflow.ExternalFlow
/** A class representing a Service */
private class ServiceClass extends Class {

View File

@@ -7,6 +7,7 @@ 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
private import semmle.code.csharp.dataflow.ExternalFlow
/** An expression containing a SQL command. */
abstract class SqlExpr extends Expr {

View File

@@ -2,6 +2,7 @@
import csharp
private import system.Reflection
private import semmle.code.csharp.dataflow.ExternalFlow
/** The `System` namespace. */
class SystemNamespace extends Namespace {

View File

@@ -2,6 +2,7 @@
import csharp
private import semmle.code.csharp.frameworks.System
private import semmle.code.csharp.dataflow.ExternalFlow
/** The `System.CodeDome` namespace. */
class SystemCodeDomNamespace extends Namespace {

View File

@@ -2,6 +2,7 @@
import csharp
private import semmle.code.csharp.frameworks.System
private import semmle.code.csharp.dataflow.ExternalFlow
private import semmle.code.csharp.dataflow.FlowSummary
/** The `System.Collections` namespace. */

View File

@@ -2,6 +2,7 @@
import csharp
private import semmle.code.csharp.frameworks.System
private import semmle.code.csharp.dataflow.ExternalFlow
/** The `System.Data` namespace. */
class SystemDataNamespace extends Namespace {

View File

@@ -2,6 +2,7 @@
import semmle.code.csharp.Type
private import semmle.code.csharp.frameworks.System
private import semmle.code.csharp.dataflow.ExternalFlow
/** The `System.Diagnostics` namespace. */
class SystemDiagnosticsNamespace extends Namespace {

View File

@@ -2,6 +2,7 @@
import csharp
private import semmle.code.csharp.frameworks.System
private import semmle.code.csharp.dataflow.ExternalFlow
/** The `System.IO` namespace. */
class SystemIONamespace extends Namespace {

View File

@@ -4,6 +4,7 @@
private import csharp as CSharp
private import semmle.code.csharp.frameworks.System as System
private import semmle.code.csharp.dataflow.ExternalFlow as ExternalFlow
/** Definitions relating to the `System.Linq` namespace. */
module SystemLinq {

View File

@@ -2,6 +2,7 @@
import csharp
private import semmle.code.csharp.frameworks.System
private import semmle.code.csharp.dataflow.ExternalFlow
/** The `System.Net` namespace. */
class SystemNetNamespace extends Namespace {

View File

@@ -1,6 +1,7 @@
/** Provides classes related to the namespace `System.Security`. */
import csharp
private import semmle.code.csharp.dataflow.ExternalFlow
private import semmle.code.csharp.frameworks.System
/** The `System.Security` namespace. */

View File

@@ -2,6 +2,7 @@
import csharp
private import semmle.code.csharp.frameworks.System
private import semmle.code.csharp.dataflow.ExternalFlow
private import semmle.code.csharp.dataflow.FlowSummary
/** The `System.Text` namespace. */

View File

@@ -3,6 +3,7 @@
import csharp
private import semmle.code.csharp.frameworks.System
private import semmle.code.csharp.frameworks.system.collections.Specialized
private import semmle.code.csharp.dataflow.ExternalFlow
/** The `System.Web` namespace. */
class SystemWebNamespace extends Namespace {

View File

@@ -3,6 +3,7 @@
import csharp
private import semmle.code.csharp.frameworks.System
private import semmle.code.csharp.dataflow.DataFlow3
private import semmle.code.csharp.dataflow.ExternalFlow
/** The `System.Xml` namespace. */
class SystemXmlNamespace extends Namespace {

View File

@@ -2,6 +2,7 @@
import csharp
private import semmle.code.csharp.frameworks.system.Collections
private import semmle.code.csharp.dataflow.ExternalFlow
/** The `System.Collections.Generic` namespace. */
class SystemCollectionsGenericNamespace extends Namespace {

View File

@@ -2,6 +2,7 @@
import csharp
private import semmle.code.csharp.frameworks.system.Collections
private import semmle.code.csharp.dataflow.ExternalFlow
/** The `System.Collections.Specialized` namespace. */
class SystemCollectionsSpecializedNamespace extends Namespace {

View File

@@ -4,6 +4,7 @@
private import csharp as CSharp
private import semmle.code.csharp.frameworks.system.Data as Data
private import semmle.code.csharp.dataflow.ExternalFlow as ExternalFlow
/** Definitions relating to the `System.Data.Common` namespace. */
module SystemDataCommon {

View File

@@ -2,6 +2,7 @@
import csharp
private import semmle.code.csharp.frameworks.system.IO
private import semmle.code.csharp.dataflow.ExternalFlow
/** The `System.IO.Compression` namespace. */
class SystemIOCompressionNamespace extends Namespace {

View File

@@ -2,6 +2,7 @@
import csharp
private import semmle.code.csharp.frameworks.system.Net
private import semmle.code.csharp.dataflow.ExternalFlow
/** The `System.Net.Mail` namespace. */
class SystemNetMailNamespace extends Namespace {

View File

@@ -3,6 +3,7 @@
import csharp
private import semmle.code.csharp.frameworks.system.Runtime
private import semmle.code.csharp.dataflow.internal.DataFlowPrivate
private import semmle.code.csharp.dataflow.ExternalFlow
/** The `System.Runtime.CompilerServices` namespace. */
class SystemRuntimeCompilerServicesNamespace extends Namespace {

View File

@@ -2,6 +2,7 @@
import csharp
private import semmle.code.csharp.frameworks.system.Security
private import semmle.code.csharp.dataflow.ExternalFlow
/** The `System.Security.Cryptography` namespace. */
class SystemSecurityCryptographyNamespace extends Namespace {

View File

@@ -2,6 +2,7 @@
import csharp
private import semmle.code.csharp.frameworks.system.security.Cryptography
private import semmle.code.csharp.dataflow.ExternalFlow
/** The `System.Security.Cryptography.X509Certificates` namespace. */
class SystemSecurityCryptographyX509CertificatesNamespace extends Namespace {

View File

@@ -4,6 +4,7 @@
import default
import semmle.code.csharp.frameworks.system.Text
private import semmle.code.csharp.dataflow.ExternalFlow
/** The `System.Text.RegularExpressions` namespace. */
class SystemTextRegularExpressionsNamespace extends Namespace {

View File

@@ -3,6 +3,7 @@
import csharp
private import semmle.code.csharp.frameworks.system.Threading
private import semmle.code.csharp.dataflow.internal.DataFlowPrivate
private import semmle.code.csharp.dataflow.ExternalFlow
/** The `System.Threading.Tasks` namespace. */
class SystemThreadingTasksNamespace extends Namespace {

View File

@@ -2,6 +2,7 @@
import csharp
private import semmle.code.csharp.frameworks.system.web.UI
private import semmle.code.csharp.dataflow.ExternalFlow
/** The `System.Web.UI.WebControls` namespace. */
class SystemWebUIWebControlsNamespace extends Namespace {

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