Compare commits

..

1 Commits

Author SHA1 Message Date
Nick Rolfe
740fd27707 Ruby: add dataflow for getters/setters defined using alias_attribute 2022-11-08 12:47:05 +00:00
2058 changed files with 155913 additions and 178375 deletions

View File

@@ -0,0 +1,24 @@
---
name: LGTM.com - false positive
about: Tell us about an alert that shouldn't be reported
title: LGTM.com - false positive
labels: false-positive
assignees: ''
---
**Description of the false positive**
<!-- Please explain briefly why you think it shouldn't be included. -->
**URL to the alert on the project page on LGTM.com**
<!--
1. Open the project on LGTM.com.
For example, https://lgtm.com/projects/g/pallets/click/.
2. Switch to the `Alerts` tab. For example, https://lgtm.com/projects/g/pallets/click/alerts/.
3. Scroll to the alert that you would like to report.
4. Click on the right most icon `View this alert within the complete file`.
5. A new browser tab opens. Copy and paste the page URL here.
For example, https://lgtm.com/projects/g/pallets/click/snapshot/719fb7d8322b0767cdd1e5903ba3eb3233ba8dd5/files/click/_winconsole.py#xa08d213ab3289f87:1.
-->

View File

@@ -10,5 +10,5 @@ assignees: ''
**Description of the issue**
<!-- Please explain briefly what is the problem.
If it is about a GitHub project, please include its URL. -->
If it is about an LGTM project, please include its URL.-->

View File

@@ -1,36 +0,0 @@
---
name: CodeQL false positive
about: Report CodeQL alerts that you think should not have been detected (not applicable, not exploitable, etc.)
title: False positive
labels: false-positive
assignees: ''
---
**Description of the false positive**
<!-- Please explain briefly why you think it shouldn't be included. -->
**Code samples or links to source code**
<!--
For open source code: file links with line numbers on GitHub, for example:
https://github.com/github/codeql/blob/dc440aaee6695deb0d9676b87e06ea984e1b4ae5/javascript/ql/test/query-tests/Security/CWE-078/CommandInjection/exec-sh2.js#L10
For closed source code: (redacted) code samples that illustrate the problem, for example:
```
function execSh(command, options) {
return cp.spawn(getShell(), ["-c", command], options) // <- command line injection
};
```
-->
**URL to the alert on GitHub code scanning (optional)**
<!--
1. Open the project on GitHub.com.
2. Switch to the `Security` tab.
3. Browse to the alert that you would like to report.
4. Copy and paste the page URL here.
-->

View File

@@ -1,55 +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:
# 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: Restore read-only cache (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 }}
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 cache (push)
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 the latest cache if the exact cache is unavailable, 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.
node $GITHUB_WORKSPACE/.github/actions/cache-query-compilation/move-caches.js ${COMBINED_CACHE_DIR}
echo "compdir=${COMBINED_CACHE_DIR}" >> $GITHUB_OUTPUT
env:
COMBINED_CACHE_DIR: ${{ runner.temp }}/compilation-dir

View File

@@ -1,75 +0,0 @@
// # 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/*
const fs = require("fs");
const path = require("path");
// the first argv is the cache folder to create.
const COMBINED_CACHE_DIR = process.argv[2];
function* walkCaches(dir) {
const files = fs.readdirSync(dir, { withFileTypes: true });
for (const file of files) {
if (file.isDirectory()) {
const filePath = path.join(dir, file.name);
yield* walkCaches(filePath);
if (file.name === ".cache") {
yield filePath;
}
}
}
}
async function copyDir(src, dest) {
for await (const file of await fs.promises.readdir(src, { withFileTypes: true })) {
const srcPath = path.join(src, file.name);
const destPath = path.join(dest, file.name);
if (file.isDirectory()) {
if (!fs.existsSync(destPath)) {
fs.mkdirSync(destPath);
}
await copyDir(srcPath, destPath);
} else {
await fs.promises.copyFile(srcPath, destPath);
}
}
}
async function main() {
const cacheDirs = [...walkCaches(".")];
for (const dir of cacheDirs) {
console.log(`Found .cache dir at ${dir}`);
}
// mkdir -p ${COMBINED_CACHE_DIR}
fs.mkdirSync(COMBINED_CACHE_DIR, { recursive: true });
// rm -f **/.cache/{lock,size} # -f to avoid errors if the cache is empty.
await Promise.all(
cacheDirs.map((cacheDir) =>
(async function () {
await fs.promises.rm(path.join(cacheDir, "lock"), { force: true });
await fs.promises.rm(path.join(cacheDir, "size"), { force: true });
})()
)
);
// # copy the contents of the .cache folders into the combined cache folder.
// cp -r **/.cache/* ${COMBINED_CACHE_DIR}/ || : # ignore missing files
await Promise.all(
cacheDirs.map((cacheDir) => copyDir(cacheDir, COMBINED_CACHE_DIR))
);
// # clean up the .cache folders
// rm -rf **/.cache/*
await Promise.all(
cacheDirs.map((cacheDir) => fs.promises.rm(cacheDir, { recursive: true }))
);
}
main();

View File

@@ -2,11 +2,11 @@ name: "Compile all queries using the latest stable CodeQL CLI"
on:
push:
branches: # makes sure the cache gets populated - running on the branches people tend to merge into.
branches: [main] # makes sure the cache gets populated
pull_request:
branches:
- main
- "rc/*"
- "codeql-cli-*"
pull_request:
jobs:
compile-queries:
@@ -14,24 +14,44 @@ jobs:
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 0
# 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 merge-base --fork-point origin/$BASE_BRANCH)
echo "merge-base=$MERGE_BASE" >> $GITHUB_ENV
- name: Calculate merge-base - branch
if: ${{ github.event_name != 'pull_request' }}
# using github.sha instead, since we're directly on a branch, and not in a PR
run: |
MERGE_BASE=${{ github.sha }}
echo "merge-base=$MERGE_BASE" >> $GITHUB_ENV
- name: Cache CodeQL query compilation
uses: actions/cache@v3
with:
path: '*/ql/src/.cache'
# current GH HEAD first, merge-base second, generic third
key: codeql-stable-compile-${{ github.sha }}
restore-keys: |
codeql-stable-compile-${{ env.merge-base }}
codeql-stable-compile-
- 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
run: codeql query format */ql/{src,lib,test}/**/*.{qll,ql} --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 --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: codeql query compile -j0 */ql/src --keep-going --warnings=error

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

@@ -1,80 +0,0 @@
name: "Go: Run Tests - Other OS"
on:
pull_request:
paths:
- "go/**"
- "!go/ql/**" # don't run other-os if only ql/ files changed
- .github/workflows/go-tests-other-os.yml
- .github/actions/**
- codeql-workspace.yml
jobs:
test-mac:
name: Test MacOS
runs-on: macos-latest
steps:
- name: Set up Go 1.19
uses: actions/setup-go@v3
with:
go-version: 1.19
id: go
- name: Check out code
uses: actions/checkout@v2
- name: Set up CodeQL CLI
uses: ./.github/actions/fetch-codeql
- name: Enable problem matchers in repository
shell: bash
run: 'find .github/problem-matchers -name \*.json -exec echo "::add-matcher::{}" \;'
- name: Build
run: |
cd go
make
- name: Cache compilation cache
id: query-cache
uses: ./.github/actions/cache-query-compilation
with:
key: go-qltest
- name: Test
run: |
cd go
make test cache="${{ steps.query-cache.outputs.cache-dir }}"
test-win:
name: Test Windows
runs-on: windows-latest-xl
steps:
- name: Set up Go 1.19
uses: actions/setup-go@v3
with:
go-version: 1.19
id: go
- name: Check out code
uses: actions/checkout@v2
- name: Set up CodeQL CLI
uses: ./.github/actions/fetch-codeql
- name: Enable problem matchers in repository
shell: bash
run: 'find .github/problem-matchers -name \*.json -exec echo "::add-matcher::{}" \;'
- name: Build
run: |
cd go
make
- name: Cache compilation cache
id: query-cache
uses: ./.github/actions/cache-query-compilation
with:
key: go-qltest
- name: Test
run: |
cd go
make test cache="${{ steps.query-cache.outputs.cache-dir }}"

View File

@@ -1,24 +1,15 @@
name: "Go: Run Tests"
on:
push:
paths:
- "go/**"
- .github/workflows/go-tests.yml
- .github/actions/**
- codeql-workspace.yml
branches:
- main
- "rc/*"
pull_request:
paths:
- "go/**"
- .github/workflows/go-tests.yml
- .github/actions/**
- .github/actions/fetch-codeql/action.yml
- codeql-workspace.yml
jobs:
test-linux:
name: Test Linux (Ubuntu)
runs-on: ubuntu-latest-xl
runs-on: ubuntu-latest
steps:
- name: Set up Go 1.19
uses: actions/setup-go@v3
@@ -41,7 +32,7 @@ jobs:
cd go
make
- name: Check that all Go code is autoformatted
- name: Check that all QL and Go code is autoformatted
run: |
cd go
make check-formatting
@@ -57,13 +48,67 @@ jobs:
name: qhelp-markdown
path: go/qhelp-out/**/*.md
- name: Cache compilation cache
id: query-cache
uses: ./.github/actions/cache-query-compilation
- name: Test
run: |
cd go
make test
test-mac:
name: Test MacOS
runs-on: macos-latest
steps:
- name: Set up Go 1.19
uses: actions/setup-go@v3
with:
key: go-qltest
go-version: 1.19
id: go
- name: Check out code
uses: actions/checkout@v2
- name: Set up CodeQL CLI
uses: ./.github/actions/fetch-codeql
- name: Enable problem matchers in repository
shell: bash
run: 'find .github/problem-matchers -name \*.json -exec echo "::add-matcher::{}" \;'
- name: Build
run: |
cd go
make
- name: Test
run: |
cd go
make test cache="${{ steps.query-cache.outputs.cache-dir }}"
make test
test-win:
name: Test Windows
runs-on: windows-2019
steps:
- name: Set up Go 1.19
uses: actions/setup-go@v3
with:
go-version: 1.19
id: go
- name: Check out code
uses: actions/checkout@v2
- name: Set up CodeQL CLI
uses: ./.github/actions/fetch-codeql
- name: Enable problem matchers in repository
shell: bash
run: 'find .github/problem-matchers -name \*.json -exec echo "::add-matcher::{}" \;'
- name: Build
run: |
cd go
make
- name: Test
run: |
cd go
make test

View File

@@ -1,30 +0,0 @@
name: Internal CI Checks
# This workflows checks if the author of a PR is a member of the CodeQL team
# and adds `ready-for-internal-ci` label to trigger the internal CI
on:
pull_request_target:
jobs:
set-label:
runs-on: ubuntu-latest
steps:
- name: Set a label to trigger internal CI checks
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
USERNAME: ${{ github.event.pull_request.user.login }}
PR_NUMBER: ${{ github.event.pull_request.number }}
LABEL: "ready-for-internal-ci"
run: |
set +eo pipefail
echo "Testing API calls"
gh api -i /repos/github/codeql
echo "Checking if user $USERNAME is a member of the CodeQL team"
if [ "$(gh api "/orgs/github/teams/codeql/memberships/$USERNAME" --jq .state)" == "active" ]; then
echo "User $USERNAME is a member of the CodeQL team"
echo "Adding '${LABEL}' label"
gh pr edit "${PR_NUMBER}" --repo "$GITHUB_REPOSITORY" --add-label "$LABEL"
else
echo "User $USERNAME is not a member of the CodeQL team"
echo "To trigger the internal CI, a maintainer needs to add the '${LABEL}' label"
fi

View File

@@ -23,6 +23,19 @@ defaults:
working-directory: javascript/ql/experimental/adaptivethreatmodeling
jobs:
qlformat:
name: Check QL formatting
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: ./.github/actions/fetch-codeql
- name: Check QL formatting
run: |
find . "(" -name "*.ql" -or -name "*.qll" ")" -print0 | \
xargs -0 codeql query format --check-only
qlcompile:
name: Check QL compilation
runs-on: ubuntu-latest

View File

@@ -24,13 +24,13 @@ jobs:
- uses: actions/checkout@v3
- name: Find codeql
id: find-codeql
uses: github/codeql-action/init@77a8d2d10c0b403a8b4aadbd223dc489ecd22683
uses: github/codeql-action/init@71a8b35ff4c80fcfcd05bc1cd932fe3c08f943ca
with:
languages: javascript # does not matter
- name: Get CodeQL version
id: get-codeql-version
run: |
echo "version=$("${CODEQL}" --version | head -n 1 | rev | cut -d " " -f 1 | rev)" >> $GITHUB_OUTPUT
echo "::set-output name=version::$("${CODEQL}" --version | head -n 1 | rev | cut -d " " -f 1 | rev)"
shell: bash
env:
CODEQL: ${{ steps.find-codeql.outputs.codeql-path }}
@@ -133,7 +133,7 @@ jobs:
env:
CONF: ./ql-for-ql-config.yml
- name: Initialize CodeQL
uses: github/codeql-action/init@77a8d2d10c0b403a8b4aadbd223dc489ecd22683
uses: github/codeql-action/init@71a8b35ff4c80fcfcd05bc1cd932fe3c08f943ca
with:
languages: ql
db-location: ${{ runner.temp }}/db
@@ -145,7 +145,7 @@ jobs:
PACK: ${{ runner.temp }}/pack
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@77a8d2d10c0b403a8b4aadbd223dc489ecd22683
uses: github/codeql-action/analyze@71a8b35ff4c80fcfcd05bc1cd932fe3c08f943ca
with:
category: "ql-for-ql"
- name: Copy sarif file to CWD

View File

@@ -25,7 +25,7 @@ jobs:
- name: Find codeql
id: find-codeql
uses: github/codeql-action/init@77a8d2d10c0b403a8b4aadbd223dc489ecd22683
uses: github/codeql-action/init@71a8b35ff4c80fcfcd05bc1cd932fe3c08f943ca
with:
languages: javascript # does not matter
- uses: actions/cache@v3

View File

@@ -22,7 +22,7 @@ jobs:
- uses: actions/checkout@v3
- name: Find codeql
id: find-codeql
uses: github/codeql-action/init@77a8d2d10c0b403a8b4aadbd223dc489ecd22683
uses: github/codeql-action/init@71a8b35ff4c80fcfcd05bc1cd932fe3c08f943ca
with:
languages: javascript # does not matter
- uses: actions/cache@v3
@@ -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

@@ -48,19 +48,7 @@ jobs:
run: |
brew install gnu-tar
echo "/usr/local/opt/gnu-tar/libexec/gnubin" >> $GITHUB_PATH
- name: Cache entire extractor
uses: actions/cache@v3
id: cache-extractor
with:
path: |
ruby/target/release/ruby-autobuilder
ruby/target/release/ruby-autobuilder.exe
ruby/target/release/ruby-extractor
ruby/target/release/ruby-extractor.exe
ruby/ql/lib/codeql/ruby/ast/internal/TreeSitter.qll
key: ${{ runner.os }}-ruby-extractor-${{ hashFiles('ruby/rust-toolchain.toml', 'ruby/**/Cargo.lock') }}--${{ hashFiles('ruby/**/*.rs') }}
- uses: actions/cache@v3
if: steps.cache-extractor.outputs.cache-hit != 'true'
with:
path: |
~/.cargo/registry
@@ -68,19 +56,15 @@ jobs:
ruby/target
key: ${{ runner.os }}-ruby-rust-cargo-${{ hashFiles('ruby/rust-toolchain.toml', 'ruby/**/Cargo.lock') }}
- name: Check formatting
if: steps.cache-extractor.outputs.cache-hit != 'true'
run: cargo fmt --all -- --check
- name: Build
if: steps.cache-extractor.outputs.cache-hit != 'true'
run: cargo build --verbose
- name: Run tests
if: steps.cache-extractor.outputs.cache-hit != 'true'
run: cargo test --verbose
- name: Release build
if: steps.cache-extractor.outputs.cache-hit != 'true'
run: cargo build --release
- name: Generate dbscheme
if: ${{ matrix.os == 'ubuntu-latest' && steps.cache-extractor.outputs.cache-hit != 'true'}}
if: ${{ matrix.os == 'ubuntu-latest' }}
run: target/release/ruby-generator --dbscheme ql/lib/ruby.dbscheme --library ql/lib/codeql/ruby/ast/internal/TreeSitter.qll
- uses: actions/upload-artifact@v3
if: ${{ matrix.os == 'ubuntu-latest' }}
@@ -102,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,23 @@ defaults:
working-directory: ruby
jobs:
qlformat:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: ./.github/actions/fetch-codeql
- name: Check QL formatting
run: find ql "(" -name "*.ql" -or -name "*.qll" ")" -print0 | xargs -0 codeql query format --check-only
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 +65,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

@@ -7,76 +7,93 @@ on:
- "misc/bazel/**"
- "*.bazel*"
- .github/workflows/swift.yml
- .github/actions/**
- .github/actions/fetch-codeql/action.yml
- codeql-workspace.yml
- .pre-commit-config.yaml
- "!**/*.md"
- "!**/*.qhelp"
branches:
- main
- rc/*
push:
paths:
- "swift/**"
- "misc/bazel/**"
- "*.bazel*"
- .github/workflows/swift.yml
- .github/actions/**
- codeql-workspace.yml
- "!**/*.md"
- "!**/*.qhelp"
branches:
- main
- rc/*
jobs:
changes:
runs-on: ubuntu-latest
outputs:
codegen: ${{ steps.filter.outputs.codegen }}
ql: ${{ steps.filter.outputs.ql }}
steps:
- uses: dorny/paths-filter@4512585405083f25c027a35db413c2b3b9006d50
id: filter
with:
filters: |
codegen:
- 'github/workflows/swift.yml'
- "misc/bazel/**"
- "*.bazel*"
- 'swift/actions/setup-env/**'
- '.pre-commit-config.yaml'
- 'swift/codegen/**'
- 'swift/schema.py'
- 'swift/**/*.dbscheme'
- 'swift/ql/lib/codeql/swift/elements.qll'
- 'swift/ql/lib/codeql/swift/elements/**'
- 'swift/ql/lib/codeql/swift/generated/**'
- 'swift/ql/test/extractor-tests/generated/**'
ql:
- 'github/workflows/swift.yml'
- 'swift/**/*.ql'
- 'swift/**/*.qll'
# not using a matrix as you cannot depend on a specific job in a matrix, and we want to start linux checks
# without waiting for the macOS build
build-and-test-macos:
runs-on: macos-12-xl
steps:
- uses: actions/checkout@v3
- uses: ./swift/actions/build-and-test
- uses: ./swift/actions/create-extractor-pack
- uses: ./swift/actions/run-quick-tests
build-and-test-linux:
runs-on: ubuntu-latest-xl
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v3
- uses: ./swift/actions/build-and-test
- uses: ./swift/actions/create-extractor-pack
- uses: ./swift/actions/run-quick-tests
qltests-linux:
needs: build-and-test-linux
runs-on: ubuntu-latest-xl
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: ./swift/actions/run-ql-tests
qltests-macos:
if : ${{ github.event_name == 'pull_request' }}
needs: build-and-test-macos
runs-on: macos-12-xl
strategy:
fail-fast: false
matrix:
slice: ["1/2", "2/2"]
steps:
- uses: actions/checkout@v3
- uses: ./swift/actions/run-ql-tests
with:
flags: --slice ${{ matrix.slice }}
integration-tests-linux:
needs: build-and-test-linux
runs-on: ubuntu-latest-xl
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: ./swift/actions/run-integration-tests
integration-tests-macos:
if : ${{ github.event_name == 'pull_request' }}
needs: build-and-test-macos
runs-on: macos-12-xl
steps:
- uses: actions/checkout@v3
- uses: ./swift/actions/run-integration-tests
codegen:
if : ${{ github.event_name == 'pull_request' }}
runs-on: ubuntu-latest
needs: changes
if: ${{ needs.changes.outputs.codegen == 'true' }}
steps:
- uses: actions/checkout@v3
- uses: bazelbuild/setup-bazelisk@v2
- uses: actions/setup-python@v4
with:
python-version-file: 'swift/.python-version'
- uses: ./swift/actions/setup-env
- uses: pre-commit/action@v3.0.0
name: Check that python code is properly formatted
with:
@@ -92,11 +109,13 @@ jobs:
- uses: actions/upload-artifact@v3
with:
name: swift-generated-cpp-files
path: generated-cpp-files/**
database-upgrade-scripts:
if : ${{ github.event_name == 'pull_request' }}
path: swift/generated-cpp-files/**
qlformat:
runs-on: ubuntu-latest
needs: changes
if: ${{ needs.changes.outputs.ql == 'true' }}
steps:
- uses: actions/checkout@v3
- uses: ./.github/actions/fetch-codeql
- uses: ./swift/actions/database-upgrade-scripts
- name: Check QL formatting
run: find swift/ql "(" -name "*.ql" -or -name "*.qll" ")" -print0 | xargs -0 codeql query format --check-only

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

@@ -19,7 +19,7 @@ repos:
rev: v1.6.0
hooks:
- id: autopep8
files: ^swift/.*\.py
files: ^swift/codegen/.*\.py
- repo: local
hooks:
@@ -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/(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,13 +5,20 @@
/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
# ML-powered queries
/javascript/ql/experimental/adaptivethreatmodeling/ @github/codeql-ml-powered-queries-reviewers
# Notify members of codeql-go about PRs to the shared data-flow library files
/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl.qll @github/codeql-java @github/codeql-go
/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl2.qll @github/codeql-java @github/codeql-go
/java/ql/src/semmle/code/java/dataflow/internal/DataFlowImplCommon.qll @github/codeql-java @github/codeql-go
/java/ql/src/semmle/code/java/dataflow/internal/tainttracking1/TaintTrackingImpl.qll @github/codeql-java @github/codeql-go
/java/ql/src/semmle/code/java/dataflow/internal/tainttracking2/TaintTrackingImpl.qll @github/codeql-java @github/codeql-go
# CodeQL tools and associated docs
/docs/codeql/codeql-cli/ @github/codeql-cli-reviewers
/docs/codeql/codeql-for-visual-studio-code/ @github/codeql-vscode-reviewers
@@ -38,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-* @github/codeql-c

View File

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

View File

@@ -1,5 +1,5 @@
{
"DataFlow Java/C++/C#/Go/Python/Ruby/Swift": [
"DataFlow Java/C++/C#/Python": [
"java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl.qll",
"java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl2.qll",
"java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl3.qll",
@@ -27,8 +27,6 @@
"csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl4.qll",
"csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl5.qll",
"csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImplForContentDataFlow.qll",
"go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl.qll",
"go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl2.qll",
"python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl.qll",
"python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl2.qll",
"python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl3.qll",
@@ -40,18 +38,17 @@
"ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImplForPathname.qll",
"swift/ql/lib/codeql/swift/dataflow/internal/DataFlowImpl.qll"
],
"DataFlow Java/C++/C#/Go/Python/Ruby/Swift Common": [
"DataFlow Java/C++/C#/Python Common": [
"java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImplCommon.qll",
"cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImplCommon.qll",
"cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImplCommon.qll",
"cpp/ql/lib/experimental/semmle/code/cpp/ir/dataflow/internal/DataFlowImplCommon.qll",
"csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImplCommon.qll",
"go/ql/lib/semmle/go/dataflow/internal/DataFlowImplCommon.qll",
"python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImplCommon.qll",
"ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImplCommon.qll",
"swift/ql/lib/codeql/swift/dataflow/internal/DataFlowImplCommon.qll"
],
"TaintTracking::Configuration Java/C++/C#/Go/Python/Ruby/Swift": [
"TaintTracking::Configuration Java/C++/C#/Python": [
"cpp/ql/lib/semmle/code/cpp/dataflow/internal/tainttracking1/TaintTrackingImpl.qll",
"cpp/ql/lib/semmle/code/cpp/dataflow/internal/tainttracking2/TaintTrackingImpl.qll",
"cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/tainttracking1/TaintTrackingImpl.qll",
@@ -65,8 +62,6 @@
"csharp/ql/lib/semmle/code/csharp/dataflow/internal/tainttracking3/TaintTrackingImpl.qll",
"csharp/ql/lib/semmle/code/csharp/dataflow/internal/tainttracking4/TaintTrackingImpl.qll",
"csharp/ql/lib/semmle/code/csharp/dataflow/internal/tainttracking5/TaintTrackingImpl.qll",
"go/ql/lib/semmle/go/dataflow/internal/tainttracking1/TaintTrackingImpl.qll",
"go/ql/lib/semmle/go/dataflow/internal/tainttracking2/TaintTrackingImpl.qll",
"java/ql/lib/semmle/code/java/dataflow/internal/tainttracking1/TaintTrackingImpl.qll",
"java/ql/lib/semmle/code/java/dataflow/internal/tainttracking2/TaintTrackingImpl.qll",
"java/ql/lib/semmle/code/java/dataflow/internal/tainttracking3/TaintTrackingImpl.qll",
@@ -77,7 +72,7 @@
"ruby/ql/lib/codeql/ruby/dataflow/internal/tainttracking1/TaintTrackingImpl.qll",
"swift/ql/lib/codeql/swift/dataflow/internal/tainttracking1/TaintTrackingImpl.qll"
],
"DataFlow Java/C++/C#/Python/Ruby/Swift Consistency checks": [
"DataFlow Java/C++/C#/Python Consistency checks": [
"java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImplConsistency.qll",
"cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImplConsistency.qll",
"cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImplConsistency.qll",
@@ -87,10 +82,9 @@
"ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImplConsistency.qll",
"swift/ql/lib/codeql/swift/dataflow/internal/DataFlowImplConsistency.qll"
],
"DataFlow Java/C#/Go/Ruby/Python/Swift Flow Summaries": [
"DataFlow Java/C#/Ruby/Python/Swift Flow Summaries": [
"java/ql/lib/semmle/code/java/dataflow/internal/FlowSummaryImpl.qll",
"csharp/ql/lib/semmle/code/csharp/dataflow/internal/FlowSummaryImpl.qll",
"go/ql/lib/semmle/go/dataflow/internal/FlowSummaryImpl.qll",
"ruby/ql/lib/codeql/ruby/dataflow/internal/FlowSummaryImpl.qll",
"python/ql/lib/semmle/python/dataflow/new/internal/FlowSummaryImpl.qll",
"swift/ql/lib/codeql/swift/dataflow/internal/FlowSummaryImpl.qll"
@@ -100,8 +94,8 @@
"csharp/ql/lib/semmle/code/csharp/dataflow/internal/rangeanalysis/SsaReadPositionCommon.qll"
],
"Model as Data Generation Java/C# - CaptureModels": [
"java/ql/src/utils/modelgenerator/internal/CaptureModels.qll",
"csharp/ql/src/utils/modelgenerator/internal/CaptureModels.qll"
"java/ql/src/utils/model-generator/internal/CaptureModels.qll",
"csharp/ql/src/utils/model-generator/internal/CaptureModels.qll"
],
"Sign Java/C#": [
"java/ql/lib/semmle/code/java/dataflow/internal/rangeanalysis/Sign.qll",
@@ -492,6 +486,40 @@
"python/ql/lib/semmle/python/security/internal/SensitiveDataHeuristics.qll",
"ruby/ql/lib/codeql/ruby/security/internal/SensitiveDataHeuristics.qll"
],
"ReDoS Util Python/JS/Ruby/Java": [
"javascript/ql/lib/semmle/javascript/security/regexp/NfaUtils.qll",
"python/ql/lib/semmle/python/security/regexp/NfaUtils.qll",
"ruby/ql/lib/codeql/ruby/security/regexp/NfaUtils.qll",
"java/ql/lib/semmle/code/java/security/regexp/NfaUtils.qll"
],
"ReDoS Exponential Python/JS/Ruby/Java": [
"javascript/ql/lib/semmle/javascript/security/regexp/ExponentialBackTracking.qll",
"python/ql/lib/semmle/python/security/regexp/ExponentialBackTracking.qll",
"ruby/ql/lib/codeql/ruby/security/regexp/ExponentialBackTracking.qll",
"java/ql/lib/semmle/code/java/security/regexp/ExponentialBackTracking.qll"
],
"ReDoS Polynomial Python/JS/Ruby/Java": [
"javascript/ql/lib/semmle/javascript/security/regexp/SuperlinearBackTracking.qll",
"python/ql/lib/semmle/python/security/regexp/SuperlinearBackTracking.qll",
"ruby/ql/lib/codeql/ruby/security/regexp/SuperlinearBackTracking.qll",
"java/ql/lib/semmle/code/java/security/regexp/SuperlinearBackTracking.qll"
],
"RegexpMatching Python/JS/Ruby": [
"javascript/ql/lib/semmle/javascript/security/regexp/RegexpMatching.qll",
"python/ql/lib/semmle/python/security/regexp/RegexpMatching.qll",
"ruby/ql/lib/codeql/ruby/security/regexp/RegexpMatching.qll"
],
"BadTagFilterQuery Python/JS/Ruby": [
"javascript/ql/lib/semmle/javascript/security/BadTagFilterQuery.qll",
"python/ql/lib/semmle/python/security/BadTagFilterQuery.qll",
"ruby/ql/lib/codeql/ruby/security/BadTagFilterQuery.qll"
],
"OverlyLargeRange Python/JS/Ruby/Java": [
"javascript/ql/lib/semmle/javascript/security/OverlyLargeRangeQuery.qll",
"python/ql/lib/semmle/python/security/OverlyLargeRangeQuery.qll",
"ruby/ql/lib/codeql/ruby/security/OverlyLargeRangeQuery.qll",
"java/ql/lib/semmle/code/java/security/OverlyLargeRangeQuery.qll"
],
"CFG": [
"csharp/ql/lib/semmle/code/csharp/controlflow/internal/ControlFlowGraphImplShared.qll",
"ruby/ql/lib/codeql/ruby/controlflow/internal/ControlFlowGraphImplShared.qll",
@@ -511,7 +539,6 @@
],
"AccessPathSyntax": [
"csharp/ql/lib/semmle/code/csharp/dataflow/internal/AccessPathSyntax.qll",
"go/ql/lib/semmle/go/dataflow/internal/AccessPathSyntax.qll",
"java/ql/lib/semmle/code/java/dataflow/internal/AccessPathSyntax.qll",
"javascript/ql/lib/semmle/javascript/frameworks/data/internal/AccessPathSyntax.qll",
"ruby/ql/lib/codeql/ruby/dataflow/internal/AccessPathSyntax.qll",

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

@@ -11,12 +11,11 @@
<ItemGroup>
<PackageReference Include="System.IO.FileSystem" Version="4.3.0" />
<PackageReference Include="System.IO.FileSystem.Primitives" Version="4.3.0" />
<PackageReference Include="xunit" Version="2.4.2" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.5">
<PackageReference Include="xunit" Version="2.4.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.1">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.4.0" />
</ItemGroup>
<ItemGroup>

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

@@ -17,7 +17,7 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Build" Version="17.3.2" />
<PackageReference Include="Microsoft.Build" Version="16.11.0" />
</ItemGroup>
<ItemGroup>

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,4 +0,0 @@
---
category: minorAnalysis
---
* Deleted the deprecated `getName` and `getShortName` predicates from the `Folder` class.

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

@@ -12,8 +12,8 @@ import IDEContextual
*
* In some cases it is preferable to modify locations (the
* `hasLocationInfo()` predicate) so that they are short, and
* non-overlapping with other locations that might be reported as
* code scanning alerts on GitHub.
* non-overlapping with other locations that might be highlighted in
* the LGTM interface.
*
* We need to give locations that may not be in the database, so
* we use `hasLocationInfo()` rather than `getLocation()`.

View File

@@ -915,17 +915,6 @@ private module Cached {
TDataFlowCallNone() or
TDataFlowCallSome(DataFlowCall call)
cached
newtype TParameterPositionOption =
TParameterPositionNone() or
TParameterPositionSome(ParameterPosition pos)
cached
newtype TReturnCtx =
TReturnCtxNone() or
TReturnCtxNoFlowThrough() or
TReturnCtxMaybeFlowThrough(ReturnKindExt kind)
cached
newtype TTypedContent = MkTypedContent(Content c, DataFlowType t) { store(_, c, _, _, t) }
@@ -1315,44 +1304,6 @@ class DataFlowCallOption extends TDataFlowCallOption {
}
}
/** An optional `ParameterPosition`. */
class ParameterPositionOption extends TParameterPositionOption {
string toString() {
this = TParameterPositionNone() and
result = "(none)"
or
exists(ParameterPosition pos |
this = TParameterPositionSome(pos) and
result = pos.toString()
)
}
}
/**
* A return context used to calculate flow summaries in reverse flow.
*
* The possible values are:
*
* - `TReturnCtxNone()`: no return flow.
* - `TReturnCtxNoFlowThrough()`: return flow, but flow through is not possible.
* - `TReturnCtxMaybeFlowThrough(ReturnKindExt kind)`: return flow, of kind `kind`, and
* flow through may be possible.
*/
class ReturnCtx extends TReturnCtx {
string toString() {
this = TReturnCtxNone() and
result = "(none)"
or
this = TReturnCtxNoFlowThrough() and
result = "(no flow through)"
or
exists(ReturnKindExt kind |
this = TReturnCtxMaybeFlowThrough(kind) and
result = kind.toString()
)
}
}
/** A `Content` tagged with the type of a containing object. */
class TypedContent extends MkTypedContent {
private Content c;

View File

@@ -136,18 +136,6 @@ module Consistency {
msg = "Local flow step does not preserve enclosing callable."
}
query predicate readStepIsLocal(Node n1, Node n2, string msg) {
readStep(n1, _, n2) and
nodeGetEnclosingCallable(n1) != nodeGetEnclosingCallable(n2) and
msg = "Read step does not preserve enclosing callable."
}
query predicate storeStepIsLocal(Node n1, Node n2, string msg) {
storeStep(n1, _, n2) and
nodeGetEnclosingCallable(n1) != nodeGetEnclosingCallable(n2) and
msg = "Store step does not preserve enclosing callable."
}
private DataFlowType typeRepr() { result = getNodeType(_) }
query predicate compatibleTypesReflexive(DataFlowType t, string msg) {

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

@@ -189,6 +189,18 @@ class Folder extends Container, @folder {
* Gets the URL of this folder.
*/
deprecated override string getURL() { result = "file://" + this.getAbsolutePath() + ":0:0:0:0" }
/**
* DEPRECATED: use `getAbsolutePath` instead.
* Gets the name of this folder.
*/
deprecated string getName() { folders(underlyingElement(this), result) }
/**
* DEPRECATED: use `getBaseName` instead.
* Gets the last part of the folder name.
*/
deprecated string getShortName() { result = this.getBaseName() }
}
/**

File diff suppressed because it is too large Load Diff

View File

@@ -915,17 +915,6 @@ private module Cached {
TDataFlowCallNone() or
TDataFlowCallSome(DataFlowCall call)
cached
newtype TParameterPositionOption =
TParameterPositionNone() or
TParameterPositionSome(ParameterPosition pos)
cached
newtype TReturnCtx =
TReturnCtxNone() or
TReturnCtxNoFlowThrough() or
TReturnCtxMaybeFlowThrough(ReturnKindExt kind)
cached
newtype TTypedContent = MkTypedContent(Content c, DataFlowType t) { store(_, c, _, _, t) }
@@ -1315,44 +1304,6 @@ class DataFlowCallOption extends TDataFlowCallOption {
}
}
/** An optional `ParameterPosition`. */
class ParameterPositionOption extends TParameterPositionOption {
string toString() {
this = TParameterPositionNone() and
result = "(none)"
or
exists(ParameterPosition pos |
this = TParameterPositionSome(pos) and
result = pos.toString()
)
}
}
/**
* A return context used to calculate flow summaries in reverse flow.
*
* The possible values are:
*
* - `TReturnCtxNone()`: no return flow.
* - `TReturnCtxNoFlowThrough()`: return flow, but flow through is not possible.
* - `TReturnCtxMaybeFlowThrough(ReturnKindExt kind)`: return flow, of kind `kind`, and
* flow through may be possible.
*/
class ReturnCtx extends TReturnCtx {
string toString() {
this = TReturnCtxNone() and
result = "(none)"
or
this = TReturnCtxNoFlowThrough() and
result = "(no flow through)"
or
exists(ReturnKindExt kind |
this = TReturnCtxMaybeFlowThrough(kind) and
result = kind.toString()
)
}
}
/** A `Content` tagged with the type of a containing object. */
class TypedContent extends MkTypedContent {
private Content c;

View File

@@ -136,18 +136,6 @@ module Consistency {
msg = "Local flow step does not preserve enclosing callable."
}
query predicate readStepIsLocal(Node n1, Node n2, string msg) {
readStep(n1, _, n2) and
nodeGetEnclosingCallable(n1) != nodeGetEnclosingCallable(n2) and
msg = "Read step does not preserve enclosing callable."
}
query predicate storeStepIsLocal(Node n1, Node n2, string msg) {
storeStep(n1, _, n2) and
nodeGetEnclosingCallable(n1) != nodeGetEnclosingCallable(n2) and
msg = "Store step does not preserve enclosing callable."
}
private DataFlowType typeRepr() { result = getNodeType(_) }
query predicate compatibleTypesReflexive(DataFlowType t, string msg) {

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

@@ -915,17 +915,6 @@ private module Cached {
TDataFlowCallNone() or
TDataFlowCallSome(DataFlowCall call)
cached
newtype TParameterPositionOption =
TParameterPositionNone() or
TParameterPositionSome(ParameterPosition pos)
cached
newtype TReturnCtx =
TReturnCtxNone() or
TReturnCtxNoFlowThrough() or
TReturnCtxMaybeFlowThrough(ReturnKindExt kind)
cached
newtype TTypedContent = MkTypedContent(Content c, DataFlowType t) { store(_, c, _, _, t) }
@@ -1315,44 +1304,6 @@ class DataFlowCallOption extends TDataFlowCallOption {
}
}
/** An optional `ParameterPosition`. */
class ParameterPositionOption extends TParameterPositionOption {
string toString() {
this = TParameterPositionNone() and
result = "(none)"
or
exists(ParameterPosition pos |
this = TParameterPositionSome(pos) and
result = pos.toString()
)
}
}
/**
* A return context used to calculate flow summaries in reverse flow.
*
* The possible values are:
*
* - `TReturnCtxNone()`: no return flow.
* - `TReturnCtxNoFlowThrough()`: return flow, but flow through is not possible.
* - `TReturnCtxMaybeFlowThrough(ReturnKindExt kind)`: return flow, of kind `kind`, and
* flow through may be possible.
*/
class ReturnCtx extends TReturnCtx {
string toString() {
this = TReturnCtxNone() and
result = "(none)"
or
this = TReturnCtxNoFlowThrough() and
result = "(no flow through)"
or
exists(ReturnKindExt kind |
this = TReturnCtxMaybeFlowThrough(kind) and
result = kind.toString()
)
}
}
/** A `Content` tagged with the type of a containing object. */
class TypedContent extends MkTypedContent {
private Content c;

View File

@@ -136,18 +136,6 @@ module Consistency {
msg = "Local flow step does not preserve enclosing callable."
}
query predicate readStepIsLocal(Node n1, Node n2, string msg) {
readStep(n1, _, n2) and
nodeGetEnclosingCallable(n1) != nodeGetEnclosingCallable(n2) and
msg = "Read step does not preserve enclosing callable."
}
query predicate storeStepIsLocal(Node n1, Node n2, string msg) {
storeStep(n1, _, n2) and
nodeGetEnclosingCallable(n1) != nodeGetEnclosingCallable(n2) and
msg = "Store step does not preserve enclosing callable."
}
private DataFlowType typeRepr() { result = getNodeType(_) }
query predicate compatibleTypesReflexive(DataFlowType t, string msg) {

View File

@@ -16,23 +16,21 @@ private class StdBasicString extends ClassTemplateInstantiation {
}
/**
* The `std::basic_string::iterator` declaration.
* Additional model for `std::string` constructors that reference the character
* type of the container, or an iterator. For example construction from
* iterators:
* ```
* std::string b(a.begin(), a.end());
* ```
*/
private class StdBasicStringIterator extends Iterator, Type {
StdBasicStringIterator() {
this.getEnclosingElement() instanceof StdBasicString and this.hasName("iterator")
}
}
private class StdStringConstructor extends Constructor, TaintFunction {
StdStringConstructor() { this.getDeclaringType() instanceof StdBasicString }
/**
* A `std::string` function for which taint should be propagated.
*/
abstract private class StdStringTaintFunction extends TaintFunction {
/**
* Gets the index of a parameter to this function that is a string (or
* character).
*/
final int getAStringParameterIndex() {
int getAStringParameterIndex() {
exists(Type paramType | paramType = this.getParameter(result).getUnspecifiedType() |
// e.g. `std::basic_string::CharT *`
paramType instanceof PointerType
@@ -43,28 +41,15 @@ abstract private class StdStringTaintFunction extends TaintFunction {
this.getDeclaringType().getTemplateArgument(2).(Type).getUnspecifiedType()
or
// i.e. `std::basic_string::CharT`
paramType = this.getDeclaringType().getTemplateArgument(0).(Type).getUnspecifiedType()
this.getParameter(result).getUnspecifiedType() =
this.getDeclaringType().getTemplateArgument(0).(Type).getUnspecifiedType()
)
}
/**
* Gets the index of a parameter to this function that is an iterator.
*/
final int getAnIteratorParameterIndex() {
this.getParameter(result).getType() instanceof Iterator
}
}
/**
* Additional model for `std::string` constructors that reference the character
* type of the container, or an iterator. For example construction from
* iterators:
* ```
* std::string b(a.begin(), a.end());
* ```
*/
private class StdStringConstructor extends Constructor, StdStringTaintFunction {
StdStringConstructor() { this.getDeclaringType() instanceof StdBasicString }
int getAnIteratorParameterIndex() { this.getParameter(result).getType() instanceof Iterator }
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
// taint flow from any parameter of the value type to the returned object
@@ -83,7 +68,7 @@ private class StdStringConstructor extends Constructor, StdStringTaintFunction {
/**
* The `std::string` function `c_str`.
*/
private class StdStringCStr extends StdStringTaintFunction {
private class StdStringCStr extends TaintFunction {
StdStringCStr() { this.getClassAndName("c_str") instanceof StdBasicString }
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
@@ -96,7 +81,7 @@ private class StdStringCStr extends StdStringTaintFunction {
/**
* The `std::string` function `data`.
*/
private class StdStringData extends StdStringTaintFunction {
private class StdStringData extends TaintFunction {
StdStringData() { this.getClassAndName("data") instanceof StdBasicString }
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
@@ -114,7 +99,7 @@ private class StdStringData extends StdStringTaintFunction {
/**
* The `std::string` function `push_back`.
*/
private class StdStringPush extends StdStringTaintFunction {
private class StdStringPush extends TaintFunction {
StdStringPush() { this.getClassAndName("push_back") instanceof StdBasicString }
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
@@ -127,7 +112,7 @@ private class StdStringPush extends StdStringTaintFunction {
/**
* The `std::string` functions `front` and `back`.
*/
private class StdStringFrontBack extends StdStringTaintFunction {
private class StdStringFrontBack extends TaintFunction {
StdStringFrontBack() { this.getClassAndName(["front", "back"]) instanceof StdBasicString }
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
@@ -140,7 +125,7 @@ private class StdStringFrontBack extends StdStringTaintFunction {
/**
* The (non-member) `std::string` function `operator+`.
*/
private class StdStringPlus extends StdStringTaintFunction {
private class StdStringPlus extends TaintFunction {
StdStringPlus() {
this.hasQualifiedName(["std", "bsl"], "operator+") and
this.getUnspecifiedType() instanceof StdBasicString
@@ -157,15 +142,31 @@ private class StdStringPlus extends StdStringTaintFunction {
}
/**
* The `std::string` functions `operator+=`, `append` and `replace`.
* All of these functions combine the existing string with a new
* string (or character) from one of the arguments.
* The `std::string` functions `operator+=`, `append`, `insert` and
* `replace`. All of these functions combine the existing string
* with a new string (or character) from one of the arguments.
*/
private class StdStringAppend extends StdStringTaintFunction {
private class StdStringAppend extends TaintFunction {
StdStringAppend() {
this.getClassAndName(["operator+=", "append", "replace"]) instanceof StdBasicString
this.getClassAndName(["operator+=", "append", "insert", "replace"]) instanceof StdBasicString
}
/**
* Gets the index of a parameter to this function that is a string (or
* character).
*/
int getAStringParameterIndex() {
this.getParameter(result).getType() instanceof PointerType or // e.g. `std::basic_string::CharT *`
this.getParameter(result).getType() instanceof ReferenceType or // e.g. `std::basic_string &`
this.getParameter(result).getUnspecifiedType() =
this.getDeclaringType().getTemplateArgument(0).(Type).getUnspecifiedType() // i.e. `std::basic_string::CharT`
}
/**
* Gets the index of a parameter to this function that is an iterator.
*/
int getAnIteratorParameterIndex() { this.getParameter(result).getType() instanceof Iterator }
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
// flow from string and parameter to string (qualifier) and return value
(
@@ -185,44 +186,28 @@ private class StdStringAppend extends StdStringTaintFunction {
}
}
/**
* The `std::string` function `insert`.
*/
private class StdStringInsert extends StdStringTaintFunction {
StdStringInsert() { this.getClassAndName("insert") instanceof StdBasicString }
/**
* Holds if the return type is an iterator.
*/
predicate hasIteratorReturnValue() { this.getType() instanceof Iterator }
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
// flow from string and parameter to string (qualifier) and return value
(
input.isQualifierObject() or
input.isParameterDeref(this.getAStringParameterIndex()) or
input.isParameter(this.getAnIteratorParameterIndex())
) and
(
output.isQualifierObject()
or
if this.hasIteratorReturnValue() then output.isReturnValue() else output.isReturnValueDeref()
)
or
// reverse flow from returned reference to the qualifier (for writes to
// the result)
not this.hasIteratorReturnValue() and
input.isReturnValueDeref() and
output.isQualifierObject()
}
}
/**
* The standard function `std::string.assign`.
*/
private class StdStringAssign extends StdStringTaintFunction {
private class StdStringAssign extends TaintFunction {
StdStringAssign() { this.getClassAndName("assign") instanceof StdBasicString }
/**
* Gets the index of a parameter to this function that is a string (or
* character).
*/
int getAStringParameterIndex() {
this.getParameter(result).getType() instanceof PointerType or // e.g. `std::basic_string::CharT *`
this.getParameter(result).getType() instanceof ReferenceType or // e.g. `std::basic_string &`
this.getParameter(result).getUnspecifiedType() =
this.getDeclaringType().getTemplateArgument(0).(Type).getUnspecifiedType() // i.e. `std::basic_string::CharT`
}
/**
* Gets the index of a parameter to this function that is an iterator.
*/
int getAnIteratorParameterIndex() { this.getParameter(result).getType() instanceof Iterator }
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
// flow from parameter to string itself (qualifier) and return value
(
@@ -244,7 +229,7 @@ private class StdStringAssign extends StdStringTaintFunction {
/**
* The standard function `std::string.copy`.
*/
private class StdStringCopy extends StdStringTaintFunction {
private class StdStringCopy extends TaintFunction {
StdStringCopy() { this.getClassAndName("copy") instanceof StdBasicString }
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
@@ -257,7 +242,7 @@ private class StdStringCopy extends StdStringTaintFunction {
/**
* The standard function `std::string.substr`.
*/
private class StdStringSubstr extends StdStringTaintFunction {
private class StdStringSubstr extends TaintFunction {
StdStringSubstr() { this.getClassAndName("substr") instanceof StdBasicString }
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
@@ -270,7 +255,7 @@ private class StdStringSubstr extends StdStringTaintFunction {
/**
* The `std::string` functions `at` and `operator[]`.
*/
private class StdStringAt extends StdStringTaintFunction {
private class StdStringAt extends TaintFunction {
StdStringAt() { this.getClassAndName(["at", "operator[]"]) instanceof StdBasicString }
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {

View File

@@ -50,18 +50,19 @@ class StrcatFunction extends TaintFunction, DataFlowFunction, ArrayFunction, Sid
}
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
(
this.getName() = ["strncat", "wcsncat", "_mbsncat", "_mbsncat_l"] and
input.isParameter(2)
or
this.getName() = ["_mbsncat_l", "_mbsnbcat_l"] and
input.isParameter(3)
or
input.isParameterDeref(0)
or
input.isParameterDeref(1)
) and
(output.isParameterDeref(0) or output.isReturnValueDeref())
this.getName() = ["strncat", "wcsncat", "_mbsncat", "_mbsncat_l"] and
input.isParameter(2) and
output.isParameterDeref(0)
or
this.getName() = ["_mbsncat_l", "_mbsnbcat_l"] and
input.isParameter(3) and
output.isParameterDeref(0)
or
input.isParameterDeref(0) and
output.isParameterDeref(0)
or
input.isParameterDeref(1) and
output.isParameterDeref(0)
}
override predicate hasArrayInput(int param) {

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

@@ -13,18 +13,11 @@
import cpp
from FormatLiteral fl, FormattingFunctionCall ffc, int expected, int given, string ffcName
from FormatLiteral fl, FormattingFunctionCall ffc, int expected, int given
where
ffc = fl.getUse() and
expected = fl.getNumArgNeeded() and
given = ffc.getNumFormatArgument() and
expected < given and
fl.specsAreKnown() and
(
if ffc.isInMacroExpansion()
then ffcName = ffc.getTarget().getName() + " (in a macro expansion)"
else ffcName = ffc.getTarget().getName()
)
select ffc,
"Format for " + ffcName + " expects " + expected.toString() + " arguments but given " +
given.toString()
fl.specsAreKnown()
select ffc, "Format expects " + expected.toString() + " arguments but given " + given.toString()

View File

@@ -16,18 +16,11 @@
import cpp
from FormatLiteral fl, FormattingFunctionCall ffc, int expected, int given, string ffcName
from FormatLiteral fl, FormattingFunctionCall ffc, int expected, int given
where
ffc = fl.getUse() and
expected = fl.getNumArgNeeded() and
given = ffc.getNumFormatArgument() and
expected > given and
fl.specsAreKnown() and
(
if ffc.isInMacroExpansion()
then ffcName = ffc.getTarget().getName() + " (in a macro expansion)"
else ffcName = ffc.getTarget().getName()
)
select ffc,
"Format for " + ffcName + " expects " + expected.toString() + " arguments but given " +
given.toString()
fl.specsAreKnown()
select ffc, "Format expects " + expected.toString() + " arguments but given " + given.toString()

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

@@ -12,8 +12,8 @@
*/
/*
* Note: this query is not assigned a precision yet because we don't want it
* to be included in query suites until its performance is well understood.
* Note: this query is not assigned a precision yet because we don't want it on
* LGTM until its performance is well understood.
*/
import cpp

View File

@@ -52,7 +52,7 @@ class Library extends LibraryT {
// The versions reported for C/C++ dependencies are just the versions that
// happen to be installed on the system where the build takes place.
// Reporting those versions is likely to cause misunderstandings, both for
// people reading them and for vulnerability checkers.
// people reading them and for the vulnerability checker of lgtm.
result = "unknown"
}

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

@@ -6,8 +6,6 @@ uniqueNodeToString
missingToString
parameterCallable
localFlowIsLocal
readStepIsLocal
storeStepIsLocal
compatibleTypesReflexive
unreachableNodeCCtx
localCallNodes
@@ -89,7 +87,4 @@ postWithInFlow
| test.cpp:465:3:465:4 | * ... [post update] | PostUpdateNode should not be the target of local flow. |
| test.cpp:465:4:465:4 | p [inner post update] | PostUpdateNode should not be the target of local flow. |
| test.cpp:470:22:470:22 | x [inner post update] | PostUpdateNode should not be the target of local flow. |
| test.cpp:499:3:499:4 | * ... [post update] | PostUpdateNode should not be the target of local flow. |
| test.cpp:499:4:499:4 | p [inner post update] | PostUpdateNode should not be the target of local flow. |
| test.cpp:505:35:505:35 | x [inner post update] | PostUpdateNode should not be the target of local flow. |
viableImplInCallContextTooLarge

View File

@@ -21,8 +21,6 @@ uniqueNodeToString
missingToString
parameterCallable
localFlowIsLocal
readStepIsLocal
storeStepIsLocal
compatibleTypesReflexive
unreachableNodeCCtx
localCallNodes
@@ -584,13 +582,6 @@ postWithInFlow
| test.cpp:489:7:489:7 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
| test.cpp:491:5:491:5 | x [post update] | PostUpdateNode should not be the target of local flow. |
| test.cpp:494:5:494:5 | x [post update] | PostUpdateNode should not be the target of local flow. |
| test.cpp:499:3:499:4 | * ... [post update] | PostUpdateNode should not be the target of local flow. |
| test.cpp:499:4:499:4 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
| test.cpp:499:4:499:4 | p [post update] | PostUpdateNode should not be the target of local flow. |
| test.cpp:504:7:504:7 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
| test.cpp:505:34:505:35 | & ... [post update] | PostUpdateNode should not be the target of local flow. |
| test.cpp:505:34:505:35 | & ... [post update] | PostUpdateNode should not be the target of local flow. |
| test.cpp:505:35:505:35 | x [post update] | PostUpdateNode should not be the target of local flow. |
| true_upon_entry.cpp:9:7:9:7 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
| true_upon_entry.cpp:10:12:10:12 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
| true_upon_entry.cpp:10:27:10:27 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |

View File

@@ -87,7 +87,7 @@ Top *identity(Top *top) {
void callIdentityFunctions(Top *top, Bottom *bottom) {
identity(bottom)->isSink(source()); // $ MISSING: ast,ir
identity(top)->isSink(source()); // no flow
identity(top)->isSink(source()); // now flow
}
using SinkFunctionType = void (*)(int);

View File

@@ -494,14 +494,3 @@ void regression_with_phi_flow(int clean1) {
x = source();
}
}
int intOutparamSourceMissingReturn(int *p) {
*p = source();
// return deliberately omitted to test IR dataflow behavior
}
void viaOutparamMissingReturn() {
int x = 0;
intOutparamSourceMissingReturn(&x);
sink(x); // $ ast,ir
}

View File

@@ -12,8 +12,6 @@ uniqueNodeToString
missingToString
parameterCallable
localFlowIsLocal
readStepIsLocal
storeStepIsLocal
compatibleTypesReflexive
unreachableNodeCCtx
localCallNodes

View File

@@ -15,8 +15,6 @@ uniqueNodeToString
missingToString
parameterCallable
localFlowIsLocal
readStepIsLocal
storeStepIsLocal
compatibleTypesReflexive
unreachableNodeCCtx
localCallNodes

View File

@@ -9,7 +9,7 @@ struct sockaddr {
char* sa_data;
};
int accept(int, sockaddr*, int*);
int accept(int, const sockaddr*, int*);
void sink(sockaddr);
@@ -20,5 +20,5 @@ void test_accept() {
int a = accept(s, &addr, &size);
sink(a); // $ ast=17:11 ir SPURIOUS: ast=18:12
sink(addr); // $ ast=17:11 ir SPURIOUS: ast=18:12
sink(addr); // $ ast,ir
}

View File

@@ -142,14 +142,9 @@
| bsd.cpp:19:14:19:29 | sizeof(sockaddr) | bsd.cpp:20:29:20:32 | size | |
| bsd.cpp:20:11:20:16 | call to accept | bsd.cpp:22:8:22:8 | a | |
| bsd.cpp:20:18:20:18 | s | bsd.cpp:20:11:20:16 | call to accept | TAINT |
| bsd.cpp:20:18:20:18 | s | bsd.cpp:20:21:20:25 | ref arg & ... | TAINT |
| bsd.cpp:20:21:20:25 | & ... | bsd.cpp:20:11:20:16 | call to accept | TAINT |
| bsd.cpp:20:21:20:25 | & ... | bsd.cpp:20:21:20:25 | ref arg & ... | TAINT |
| bsd.cpp:20:21:20:25 | ref arg & ... | bsd.cpp:20:22:20:25 | addr [inner post update] | |
| bsd.cpp:20:21:20:25 | ref arg & ... | bsd.cpp:23:8:23:11 | addr | |
| bsd.cpp:20:22:20:25 | addr | bsd.cpp:20:11:20:16 | call to accept | TAINT |
| bsd.cpp:20:22:20:25 | addr | bsd.cpp:20:21:20:25 | & ... | |
| bsd.cpp:20:22:20:25 | addr | bsd.cpp:20:21:20:25 | ref arg & ... | TAINT |
| bsd.cpp:20:28:20:32 | ref arg & ... | bsd.cpp:20:29:20:32 | size [inner post update] | |
| bsd.cpp:20:29:20:32 | size | bsd.cpp:20:28:20:32 | & ... | |
| constructor_delegation.cpp:8:2:8:8 | this | constructor_delegation.cpp:8:20:8:24 | constructor init of field x [pre-this] | |
@@ -5969,7 +5964,6 @@
| taint.cpp:172:10:172:15 | buffer | taint.cpp:172:3:172:8 | call to strcat | |
| taint.cpp:172:10:172:15 | buffer | taint.cpp:172:10:172:15 | ref arg buffer | TAINT |
| taint.cpp:172:10:172:15 | ref arg buffer | taint.cpp:173:8:173:13 | buffer | |
| taint.cpp:172:18:172:24 | tainted | taint.cpp:172:3:172:8 | call to strcat | TAINT |
| taint.cpp:172:18:172:24 | tainted | taint.cpp:172:10:172:15 | ref arg buffer | TAINT |
| taint.cpp:180:19:180:19 | p | taint.cpp:180:19:180:19 | p | |
| taint.cpp:180:19:180:19 | p | taint.cpp:181:9:181:9 | p | |
@@ -6379,14 +6373,12 @@
| taint.cpp:561:9:561:13 | dest1 | taint.cpp:561:9:561:13 | ref arg dest1 | TAINT |
| taint.cpp:561:9:561:13 | ref arg dest1 | taint.cpp:560:24:560:28 | dest1 | |
| taint.cpp:561:9:561:13 | ref arg dest1 | taint.cpp:562:7:562:11 | dest1 | |
| taint.cpp:561:16:561:21 | source | taint.cpp:561:2:561:7 | call to strcat | TAINT |
| taint.cpp:561:16:561:21 | source | taint.cpp:561:9:561:13 | ref arg dest1 | TAINT |
| taint.cpp:562:7:562:11 | ref arg dest1 | taint.cpp:560:24:560:28 | dest1 | |
| taint.cpp:564:9:564:13 | dest2 | taint.cpp:564:2:564:7 | call to strcat | |
| taint.cpp:564:9:564:13 | dest2 | taint.cpp:564:9:564:13 | ref arg dest2 | TAINT |
| taint.cpp:564:9:564:13 | ref arg dest2 | taint.cpp:560:37:560:41 | dest2 | |
| taint.cpp:564:9:564:13 | ref arg dest2 | taint.cpp:565:7:565:11 | dest2 | |
| taint.cpp:564:16:564:20 | clean | taint.cpp:564:2:564:7 | call to strcat | TAINT |
| taint.cpp:564:16:564:20 | clean | taint.cpp:564:9:564:13 | ref arg dest2 | TAINT |
| taint.cpp:565:7:565:11 | ref arg dest2 | taint.cpp:560:37:560:41 | dest2 | |
| taint.cpp:572:37:572:41 | dest1 | taint.cpp:572:37:572:41 | dest1 | |
@@ -6413,12 +6405,9 @@
| taint.cpp:574:36:574:40 | ref arg dest1 | taint.cpp:572:37:572:41 | dest1 | |
| taint.cpp:574:36:574:40 | ref arg dest1 | taint.cpp:575:7:575:11 | dest1 | |
| taint.cpp:574:36:574:40 | ref arg dest1 | taint.cpp:576:8:576:12 | dest1 | |
| taint.cpp:574:43:574:45 | ptr | taint.cpp:574:25:574:34 | call to _mbsncat_l | TAINT |
| taint.cpp:574:43:574:45 | ptr | taint.cpp:574:36:574:40 | ref arg dest1 | TAINT |
| taint.cpp:574:48:574:48 | n | taint.cpp:574:25:574:34 | call to _mbsncat_l | TAINT |
| taint.cpp:574:48:574:48 | n | taint.cpp:574:36:574:40 | ref arg dest1 | TAINT |
| taint.cpp:574:51:574:56 | ref arg source | taint.cpp:573:49:573:54 | source | |
| taint.cpp:574:51:574:56 | source | taint.cpp:574:25:574:34 | call to _mbsncat_l | TAINT |
| taint.cpp:574:51:574:56 | source | taint.cpp:574:36:574:40 | ref arg dest1 | TAINT |
| taint.cpp:575:7:575:11 | ref arg dest1 | taint.cpp:572:37:572:41 | dest1 | |
| taint.cpp:575:7:575:11 | ref arg dest1 | taint.cpp:576:8:576:12 | dest1 | |
@@ -6432,11 +6421,8 @@
| taint.cpp:580:36:580:40 | ref arg dest3 | taint.cpp:572:85:572:89 | dest3 | |
| taint.cpp:580:36:580:40 | ref arg dest3 | taint.cpp:581:7:581:11 | dest3 | |
| taint.cpp:580:36:580:40 | ref arg dest3 | taint.cpp:582:8:582:12 | dest3 | |
| taint.cpp:580:43:580:45 | ptr | taint.cpp:580:25:580:34 | call to _mbsncat_l | TAINT |
| taint.cpp:580:43:580:45 | ptr | taint.cpp:580:36:580:40 | ref arg dest3 | TAINT |
| taint.cpp:580:48:580:48 | n | taint.cpp:580:25:580:34 | call to _mbsncat_l | TAINT |
| taint.cpp:580:48:580:48 | n | taint.cpp:580:36:580:40 | ref arg dest3 | TAINT |
| taint.cpp:580:51:580:55 | clean | taint.cpp:580:25:580:34 | call to _mbsncat_l | TAINT |
| taint.cpp:580:51:580:55 | clean | taint.cpp:580:36:580:40 | ref arg dest3 | TAINT |
| taint.cpp:580:51:580:55 | ref arg clean | taint.cpp:573:32:573:36 | clean | |
| taint.cpp:581:7:581:11 | ref arg dest3 | taint.cpp:572:85:572:89 | dest3 | |

View File

@@ -574,8 +574,8 @@ void test__mbsncat_l(unsigned char* dest1, unsigned const char* ptr, unsigned ch
unsigned char* dest2 = _mbsncat_l(dest1, ptr, n, source);
sink(dest1); // $ SPURIOUS: ast,ir
sink(*dest1); // $ ast,ir
sink(dest2); // $ SPURIOUS: ast,ir
sink(*dest2); // $ ast,ir
sink(dest2); // $ SPURIOUS: ir
sink(*dest2); // $ ir
unsigned char* dest4 = _mbsncat_l(dest3, ptr, n, clean);
sink(dest3);

View File

@@ -95,7 +95,16 @@ module IRTest {
override predicate isSink(DataFlow::Node sink) {
exists(FunctionCall call |
call.getTarget().getName() = "sink" and
sink.asExpr() = call.getAnArgument()
sink.asConvertedExpr() = call.getAnArgument()
or
call.getTarget().getName() = "sink" and
sink.asExpr() = call.getAnArgument() and
sink.asConvertedExpr() instanceof ReferenceDereferenceExpr
)
or
exists(ReadSideEffectInstruction read |
read.getSideEffectOperand() = sink.asOperand() and
read.getPrimaryInstruction().(CallInstruction).getStaticCallTarget().hasName("sink")
)
}

View File

@@ -52,8 +52,6 @@ uniqueNodeToString
missingToString
parameterCallable
localFlowIsLocal
readStepIsLocal
storeStepIsLocal
compatibleTypesReflexive
unreachableNodeCCtx
localCallNodes

View File

@@ -1463,8 +1463,6 @@ uniqueNodeToString
missingToString
parameterCallable
localFlowIsLocal
readStepIsLocal
storeStepIsLocal
compatibleTypesReflexive
unreachableNodeCCtx
localCallNodes

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,14 +1,14 @@
| a.c:18:3:18:25 | call to myMultiplyDefinedPrintf | Format for myMultiplyDefinedPrintf expects 1 arguments but given 2 |
| b.c:15:3:15:25 | call to myMultiplyDefinedPrintf | Format for myMultiplyDefinedPrintf expects 1 arguments but given 2 |
| c.c:7:3:7:25 | call to myMultiplyDefinedPrintf | Format for myMultiplyDefinedPrintf expects 1 arguments but given 2 |
| custom_printf.cpp:31:5:31:12 | call to myPrintf | Format for myPrintf expects 2 arguments but given 3 |
| macros.cpp:12:2:12:31 | call to printf | Format for printf (in a macro expansion) expects 2 arguments but given 3 |
| macros.cpp:16:2:16:30 | call to printf | Format for printf (in a macro expansion) expects 2 arguments but given 3 |
| test.c:7:2:7:7 | call to printf | Format for printf expects 0 arguments but given 1 |
| test.c:21:2:21:7 | call to printf | Format for printf expects 2 arguments but given 3 |
| test.c:27:3:27:8 | call to printf | Format for printf expects 2 arguments but given 3 |
| test.c:31:3:31:8 | call to printf | Format for printf expects 1 arguments but given 3 |
| test.c:32:3:32:8 | call to printf | Format for printf expects 1 arguments but given 2 |
| test.c:39:3:39:8 | call to printf | Format for printf expects 2 arguments but given 5 |
| test.c:40:3:40:8 | call to printf | Format for printf expects 2 arguments but given 4 |
| test.c:41:3:41:8 | call to printf | Format for printf expects 2 arguments but given 3 |
| a.c:18:3:18:25 | call to myMultiplyDefinedPrintf | Format expects 1 arguments but given 2 |
| b.c:15:3:15:25 | call to myMultiplyDefinedPrintf | Format expects 1 arguments but given 2 |
| c.c:7:3:7:25 | call to myMultiplyDefinedPrintf | Format expects 1 arguments but given 2 |
| custom_printf.cpp:31:5:31:12 | call to myPrintf | Format expects 2 arguments but given 3 |
| macros.cpp:12:2:12:31 | call to printf | Format expects 2 arguments but given 3 |
| macros.cpp:16:2:16:30 | call to printf | Format expects 2 arguments but given 3 |
| test.c:7:2:7:7 | call to printf | Format expects 0 arguments but given 1 |
| test.c:21:2:21:7 | call to printf | Format expects 2 arguments but given 3 |
| test.c:27:3:27:8 | call to printf | Format expects 2 arguments but given 3 |
| test.c:31:3:31:8 | call to printf | Format expects 1 arguments but given 3 |
| test.c:32:3:32:8 | call to printf | Format expects 1 arguments but given 2 |
| test.c:39:3:39:8 | call to printf | Format expects 2 arguments but given 5 |
| test.c:40:3:40:8 | call to printf | Format expects 2 arguments but given 4 |
| test.c:41:3:41:8 | call to printf | Format expects 2 arguments but given 3 |

View File

@@ -1,12 +1,11 @@
| a.c:16:3:16:25 | call to myMultiplyDefinedPrintf | Format for myMultiplyDefinedPrintf expects 1 arguments but given 0 |
| b.c:13:3:13:25 | call to myMultiplyDefinedPrintf | Format for myMultiplyDefinedPrintf expects 1 arguments but given 0 |
| c.c:5:3:5:25 | call to myMultiplyDefinedPrintf | Format for myMultiplyDefinedPrintf expects 1 arguments but given 0 |
| custom_printf.cpp:29:5:29:12 | call to myPrintf | Format for myPrintf expects 2 arguments but given 1 |
| macros.cpp:14:2:14:37 | call to printf | Format for printf (in a macro expansion) expects 4 arguments but given 3 |
| macros.cpp:21:2:21:36 | call to printf | Format for printf (in a macro expansion) expects 4 arguments but given 3 |
| macros.cpp:32:2:32:25 | call to printf | Format for printf (in a macro expansion) expects 1 arguments but given 0 |
| test.c:9:2:9:7 | call to printf | Format for printf expects 1 arguments but given 0 |
| test.c:12:2:12:7 | call to printf | Format for printf expects 2 arguments but given 1 |
| test.c:15:2:15:7 | call to printf | Format for printf expects 3 arguments but given 2 |
| test.c:19:2:19:7 | call to printf | Format for printf expects 2 arguments but given 1 |
| test.c:29:3:29:8 | call to printf | Format for printf expects 2 arguments but given 1 |
| a.c:16:3:16:25 | call to myMultiplyDefinedPrintf | Format expects 1 arguments but given 0 |
| b.c:13:3:13:25 | call to myMultiplyDefinedPrintf | Format expects 1 arguments but given 0 |
| c.c:5:3:5:25 | call to myMultiplyDefinedPrintf | Format expects 1 arguments but given 0 |
| custom_printf.cpp:29:5:29:12 | call to myPrintf | Format expects 2 arguments but given 1 |
| macros.cpp:14:2:14:37 | call to printf | Format expects 4 arguments but given 3 |
| macros.cpp:21:2:21:36 | call to printf | Format expects 4 arguments but given 3 |
| test.c:9:2:9:7 | call to printf | Format expects 1 arguments but given 0 |
| test.c:12:2:12:7 | call to printf | Format expects 2 arguments but given 1 |
| test.c:15:2:15:7 | call to printf | Format expects 3 arguments but given 2 |
| test.c:19:2:19:7 | call to printf | Format expects 2 arguments but given 1 |
| test.c:29:3:29:8 | call to printf | Format expects 2 arguments but given 1 |

View File

@@ -13,21 +13,10 @@ void testMacros(int a, int b, int c)
GOODPRINTF("%i %i %i\n", a, b, c); // GOOD
GOODPRINTF("%i %i %i %i\n", a, b, c); // BAD: too few format arguments
BADPRINTF("%i %i\n", a, b, 0); // DUBIOUS: too many format arguments
BADPRINTF("%i %i\n", a, b, 0); // BAD: too many format arguments
// ^ here there are too many format arguments, but the design of the Macro forces the user
// to do this, and the extra argument is harmlessly ignored in practice. Reporting these
// results can be extremely noisy (e.g. in openldap).
BADPRINTF("%i %i %i\n", a, b, c); // GOOD
BADPRINTF("%i %i %i %i\n", a, b, c); // BAD: too few format arguments
}
#define DOTHING(x) \
printf("doing thing: " #x); x
void testMacros2()
{
int x;
DOTHING(x++); // GOOD
DOTHING(printf("%i", x)); // BAD: the printf inside the macro has too few format arguments
}

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 |

View File

@@ -332,13 +332,4 @@ void ptr_diff_case() {
char* admin_begin_pos = strstr(user, "ADMIN");
int offset = admin_begin_pos ? user - admin_begin_pos : 0;
malloc(offset); // GOOD
}
void equality_barrier() {
int size1 = atoi(getenv("USER"));
int size2 = atoi(getenv("USER"));
if (size1 == size2) {
int* a = (int*)malloc(size1 * sizeof(int)); // GOOD
}
}
}

View File

@@ -95,12 +95,5 @@ int main(int argc, char** argv) {
}
}
// GOOD: check the user input first
int maxConnections3 = atoi(argv[1]);
int maxConnections4 = atoi(argv[1]);
if (maxConnections3 == maxConnections4) {
startServer(maxConnections3 * 1000);
}
return 0;
}

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

@@ -6,17 +6,17 @@
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="System.IO.FileSystem" Version="4.3.0" />
<PackageReference Include="System.IO.FileSystem.Primitives" Version="4.3.0" />
<PackageReference Include="xunit" Version="2.4.2" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.5">
<PackageReference Include="System.IO.FileSystem" Version="4.3.0"/>
<PackageReference Include="System.IO.FileSystem.Primitives" Version="4.3.0"/>
<PackageReference Include="xunit" Version="2.4.1"/>
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.3">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.4.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.0.0"/>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Semmle.Autobuild.CSharp\Semmle.Autobuild.CSharp.csproj" />
<ProjectReference Include="..\Semmle.Autobuild.Shared\Semmle.Autobuild.Shared.csproj" />
<ProjectReference Include="..\Semmle.Autobuild.CSharp\Semmle.Autobuild.CSharp.csproj"/>
<ProjectReference Include="..\Semmle.Autobuild.Shared\Semmle.Autobuild.Shared.csproj"/>
</ItemGroup>
</Project>

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

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