mirror of
https://github.com/github/codeql.git
synced 2026-05-24 08:07:07 +02:00
Compare commits
1 Commits
testing-po
...
redsun82/r
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
840d166efe |
5
.gitattributes
vendored
5
.gitattributes
vendored
@@ -88,8 +88,3 @@
|
||||
# swift prebuilt resources
|
||||
/swift/third_party/resources/*.zip filter=lfs diff=lfs merge=lfs -text
|
||||
/swift/third_party/resources/*.tar.zst filter=lfs diff=lfs merge=lfs -text
|
||||
|
||||
# This upgrade script must use windows line-endings to be compatible with old
|
||||
# databases.
|
||||
/powershell/ql/lib/upgrades/ce269c61feda10a8ca0d16519085f7e55741a694/old.dbscheme eol=crlf
|
||||
/powershell/downgrades/802d5b9f407fb0dac894df1c0b4584f2215e1512/semmlecode.powershell.dbscheme eol=crlf
|
||||
35
.github/workflows/go-tests-other-os.yml
vendored
Normal file
35
.github/workflows/go-tests-other-os.yml
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
name: "Go: Run Tests - Other OS"
|
||||
on:
|
||||
pull_request:
|
||||
paths:
|
||||
- "go/**"
|
||||
- "!go/documentation/**"
|
||||
- "!go/ql/**" # don't run other-os if only ql/ files changed
|
||||
- .github/workflows/go-tests-other-os.yml
|
||||
- .github/actions/**
|
||||
- codeql-workspace.yml
|
||||
- MODULE.bazel
|
||||
- .bazelrc
|
||||
- misc/bazel/**
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
test-mac:
|
||||
name: Test MacOS
|
||||
runs-on: macos-latest
|
||||
steps:
|
||||
- name: Check out code
|
||||
uses: actions/checkout@v4
|
||||
- name: Run tests
|
||||
uses: ./go/actions/test
|
||||
|
||||
test-win:
|
||||
name: Test Windows
|
||||
runs-on: windows-latest
|
||||
steps:
|
||||
- name: Check out code
|
||||
uses: actions/checkout@v4
|
||||
- name: Run tests
|
||||
uses: ./go/actions/test
|
||||
22
.github/workflows/go-tests-rtjo.yml
vendored
Normal file
22
.github/workflows/go-tests-rtjo.yml
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
name: "Go: Run RTJO Tests"
|
||||
on:
|
||||
pull_request:
|
||||
types:
|
||||
- labeled
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
test-linux:
|
||||
if: "github.repository_owner == 'github' && github.event.label.name == 'Run: RTJO Language Tests'"
|
||||
name: RTJO Test Linux (Ubuntu)
|
||||
runs-on: ubuntu-latest-xl
|
||||
steps:
|
||||
- name: Check out code
|
||||
uses: actions/checkout@v4
|
||||
- name: Run tests
|
||||
uses: ./go/actions/test
|
||||
with:
|
||||
run-code-checks: true
|
||||
dynamic-join-order-mode: all
|
||||
13
.github/workflows/go-tests.yml
vendored
13
.github/workflows/go-tests.yml
vendored
@@ -1,6 +1,6 @@
|
||||
name: "Go: Run Tests"
|
||||
on:
|
||||
pull_request:
|
||||
push:
|
||||
paths:
|
||||
- "go/**"
|
||||
- "!go/documentation/**"
|
||||
@@ -8,6 +8,17 @@ on:
|
||||
- .github/workflows/go-tests.yml
|
||||
- .github/actions/**
|
||||
- codeql-workspace.yml
|
||||
branches:
|
||||
- main
|
||||
- "rc/*"
|
||||
pull_request:
|
||||
paths:
|
||||
- "go/**"
|
||||
- "!go/documentation/**"
|
||||
- "shared/**"
|
||||
- .github/workflows/go-tests.yml
|
||||
- .github/actions/**
|
||||
- codeql-workspace.yml
|
||||
- MODULE.bazel
|
||||
- .bazelrc
|
||||
- misc/bazel/**
|
||||
|
||||
152
.github/workflows/microsoft-codeql-pack-publish.yml
vendored
152
.github/workflows/microsoft-codeql-pack-publish.yml
vendored
@@ -1,152 +0,0 @@
|
||||
name: Microsoft CodeQL Pack Publish
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
check-branch:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Fail if not on main branch
|
||||
run: |
|
||||
if [ "$GITHUB_REF" != "refs/heads/main" ]; then
|
||||
echo "This workflow can only run on the 'main' branch."
|
||||
exit 1
|
||||
fi
|
||||
codeqlversion:
|
||||
needs: check-branch
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
codeql_version: ${{ steps.set_codeql_version.outputs.codeql_version }}
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Set CodeQL Version
|
||||
id: set_codeql_version
|
||||
run: |
|
||||
git fetch
|
||||
git fetch --tags
|
||||
CURRENT_COMMIT=$(git rev-list -1 HEAD)
|
||||
CURRENT_TAG=$(git describe --tags --abbrev=0 --match 'codeql-cli/v*' $CURRENT_COMMIT)
|
||||
CODEQL_VERSION="${CURRENT_TAG#codeql-cli/}"
|
||||
echo "CODEQL_VERSION=$CODEQL_VERSION" >> $GITHUB_OUTPUT
|
||||
publishlibs:
|
||||
environment: secure-publish
|
||||
needs: codeqlversion
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
language: ['powershell']
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
- name: Install CodeQL
|
||||
shell: bash
|
||||
run: |
|
||||
gh extension install github/gh-codeql
|
||||
gh codeql download "${{ needs.codeqlversion.outputs.codeql_version }}"
|
||||
gh codeql set-version "${{ needs.codeqlversion.outputs.codeql_version }}"
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ github.token }}
|
||||
- name: Publish OS Microsoft CodeQL Lib Pack
|
||||
shell: bash
|
||||
run: |
|
||||
# Download latest qlpack
|
||||
gh codeql pack download "microsoft/$LANGUAGE-all"
|
||||
PACK_DIR="$HOME/.codeql/packages/microsoft/$LANGUAGE-all"
|
||||
VERSION_COUNT=$(ls -d "$PACK_DIR"/*/ | wc -l)
|
||||
[[ "$VERSION_COUNT" -ne 1 ]] && { echo "Expected exactly one version in $PACK_DIR, but found $VERSION_COUNT. Exiting."; exit 1; }
|
||||
|
||||
# Increment version
|
||||
CURRENT_VERSION=$(ls -v "$PACK_DIR" | tail -n 1)
|
||||
MAJOR=$(echo "$CURRENT_VERSION" | cut -d. -f1)
|
||||
MINOR=$(echo "$CURRENT_VERSION" | cut -d. -f2)
|
||||
PATCH=$(echo "$CURRENT_VERSION" | cut -d. -f3)
|
||||
NEXT_VERSION="$MAJOR.$MINOR.$((PATCH + 1))"
|
||||
|
||||
# Extract dependencies from the existing qlpack.yml before deleting
|
||||
DEPENDENCIES=$(yq 'select(has("dependencies")) | .dependencies | {"dependencies": .}' "$LANGUAGE/ql/lib/qlpack.yml" 2>/dev/null)
|
||||
DATAEXTENSIONS=$(yq 'select(has("dataExtensions")) | .dataExtensions | {"dataExtensions": .}' "$LANGUAGE/ql/lib/qlpack.yml" 2>/dev/null)
|
||||
rm -f "$LANGUAGE/ql/lib/qlpack.yml" "$LANGUAGE/ql/lib/qlpack.lock"
|
||||
|
||||
# Create new qlpack.yml with modified content
|
||||
cat <<EOF > "$LANGUAGE/ql/lib/qlpack.yml"
|
||||
name: microsoft/$LANGUAGE-all
|
||||
version: $NEXT_VERSION
|
||||
extractor: $LANGUAGE
|
||||
groups:
|
||||
- $LANGUAGE
|
||||
- microsoft-all
|
||||
dbscheme: semmlecode.$LANGUAGE.dbscheme
|
||||
extractor: $LANGUAGE
|
||||
library: true
|
||||
upgrades: upgrades
|
||||
$DEPENDENCIES
|
||||
$DATAEXTENSIONS
|
||||
warnOnImplicitThis: true
|
||||
EOF
|
||||
|
||||
# Publish pack
|
||||
cat "$LANGUAGE/ql/lib/qlpack.yml"
|
||||
gh codeql pack publish "$LANGUAGE/ql/lib"
|
||||
env:
|
||||
LANGUAGE: ${{ matrix.language }}
|
||||
GITHUB_TOKEN: ${{ secrets.PACKAGE_PUBLISH }}
|
||||
publish:
|
||||
environment: secure-publish
|
||||
needs: codeqlversion
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
language: ['csharp', 'cpp', 'java', 'javascript', 'python', 'ruby', 'go', 'rust', 'swift', 'powershell', 'iac']
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
- name: Install CodeQL
|
||||
shell: bash
|
||||
run: |
|
||||
gh extension install github/gh-codeql
|
||||
gh codeql download "${{ needs.codeqlversion.outputs.codeql_version }}"
|
||||
gh codeql set-version "${{ needs.codeqlversion.outputs.codeql_version }}"
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ github.token }}
|
||||
- name: Publish OS Microsoft CodeQL Pack
|
||||
shell: bash
|
||||
run: |
|
||||
# Download latest qlpack
|
||||
gh codeql pack download "microsoft/$LANGUAGE-queries"
|
||||
PACK_DIR="$HOME/.codeql/packages/microsoft/$LANGUAGE-queries"
|
||||
VERSION_COUNT=$(ls -d "$PACK_DIR"/*/ | wc -l)
|
||||
[[ "$VERSION_COUNT" -ne 1 ]] && { echo "Expected exactly one version in $PACK_DIR, but found $VERSION_COUNT. Exiting."; exit 1; }
|
||||
|
||||
# Increment version
|
||||
CURRENT_VERSION=$(ls -v "$PACK_DIR" | tail -n 1)
|
||||
MAJOR=$(echo "$CURRENT_VERSION" | cut -d. -f1)
|
||||
MINOR=$(echo "$CURRENT_VERSION" | cut -d. -f2)
|
||||
PATCH=$(echo "$CURRENT_VERSION" | cut -d. -f3)
|
||||
NEXT_VERSION="$MAJOR.$MINOR.$((PATCH + 1))"
|
||||
|
||||
# Extract dependencies from the existing qlpack.yml before deleting
|
||||
DEPENDENCIES=$(yq 'select(has("dependencies")) | .dependencies | {"dependencies": .}' "$LANGUAGE/ql/src/qlpack.yml" 2>/dev/null)
|
||||
rm -f "$LANGUAGE/ql/src/qlpack.yml" "$LANGUAGE/ql/src/qlpack.lock"
|
||||
|
||||
# Create new qlpack.yml with modified content
|
||||
cat <<EOF > "$LANGUAGE/ql/src/qlpack.yml"
|
||||
name: microsoft/$LANGUAGE-queries
|
||||
version: $NEXT_VERSION
|
||||
extractor: $LANGUAGE
|
||||
groups:
|
||||
- $LANGUAGE
|
||||
- queries
|
||||
$DEPENDENCIES
|
||||
EOF
|
||||
|
||||
# Publish pack
|
||||
cat "$LANGUAGE/ql/src/qlpack.yml"
|
||||
gh codeql pack publish "$LANGUAGE/ql/src"
|
||||
env:
|
||||
LANGUAGE: ${{ matrix.language }}
|
||||
GITHUB_TOKEN: ${{ secrets.PACKAGE_PUBLISH }}
|
||||
|
||||
32
.github/workflows/powershell-pr-check.yml
vendored
32
.github/workflows/powershell-pr-check.yml
vendored
@@ -1,32 +0,0 @@
|
||||
name: PowerShell PR Check
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
branches:
|
||||
- main
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
powershell-pr-check:
|
||||
name: powershell-pr-check
|
||||
runs-on: windows-latest
|
||||
if: github.repository == 'microsoft/codeql'
|
||||
permissions:
|
||||
contents: read
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
token: ${{ github.token }}
|
||||
- name: Setup CodeQL
|
||||
uses: ./.github/actions/fetch-codeql
|
||||
with:
|
||||
channel: release
|
||||
- name: Install PowerShell
|
||||
run: |
|
||||
$path = Split-Path (Get-Command codeql).Source
|
||||
./powershell/build-win64.ps1 $path
|
||||
- name: Run QL tests
|
||||
run: |
|
||||
codeql test run --threads=0 powershell/ql/test
|
||||
28
.github/workflows/sync-main-tags.yml
vendored
28
.github/workflows/sync-main-tags.yml
vendored
@@ -1,28 +0,0 @@
|
||||
name: Sync Main Tags
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
types:
|
||||
- closed
|
||||
branches:
|
||||
- main
|
||||
|
||||
jobs:
|
||||
sync-main-tags:
|
||||
name: Sync Main Tags
|
||||
runs-on: ubuntu-latest
|
||||
if: github.repository == 'microsoft/codeql' && github.event.pull_request.merged == true && github.event.pull_request.head.ref == 'auto/sync-main-pr'
|
||||
permissions:
|
||||
contents: write
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Push Tags
|
||||
run: |
|
||||
git remote add upstream https://github.com/github/codeql.git
|
||||
git fetch upstream --tags --force
|
||||
git push --force origin --tags
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.WORKFLOW_TOKEN }}
|
||||
91
.github/workflows/sync-main.yml
vendored
91
.github/workflows/sync-main.yml
vendored
@@ -1,91 +0,0 @@
|
||||
name: Sync Main
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
paths:
|
||||
- .github/workflows/sync-main.yml
|
||||
schedule:
|
||||
- cron: '55 * * * *'
|
||||
|
||||
jobs:
|
||||
sync-main:
|
||||
name: Sync-main
|
||||
runs-on: ubuntu-latest
|
||||
if: github.repository == 'microsoft/codeql'
|
||||
permissions:
|
||||
contents: write
|
||||
pull-requests: write
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
token: ${{ secrets.WORKFLOW_TOKEN }}
|
||||
- name: Git config
|
||||
shell: bash
|
||||
run: |
|
||||
git config user.name "dilanbhalla"
|
||||
git config user.email "dilanbhalla@microsoft.com"
|
||||
- name: Git checkout auto/sync-main-pr
|
||||
shell: bash
|
||||
run: |
|
||||
git fetch origin
|
||||
if git ls-remote --exit-code --heads origin auto/sync-main-pr > /dev/null; then
|
||||
echo "Branch exists remotely. Checking it out."
|
||||
git checkout -B auto/sync-main-pr origin/auto/sync-main-pr
|
||||
else
|
||||
echo "Branch does not exist remotely. Creating from main."
|
||||
git checkout -B auto/sync-main-pr origin/main
|
||||
git push -u origin auto/sync-main-pr
|
||||
fi
|
||||
- name: Sync origin/main
|
||||
shell: bash
|
||||
run: |
|
||||
echo "::group::Sync with main branch"
|
||||
git pull origin auto/sync-main-pr; exitCode=$?; if [ $exitCode -ne 0 ]; then exitCode=0; fi
|
||||
git pull origin main --no-rebase
|
||||
git push --force origin auto/sync-main-pr
|
||||
echo "::endgroup::"
|
||||
- name: Sync upstream/codeql-cli/latest
|
||||
shell: bash
|
||||
run: |
|
||||
echo "::group::Set up remote"
|
||||
git remote add upstream https://github.com/github/codeql.git
|
||||
git fetch upstream --tags --force
|
||||
echo "::endgroup::"
|
||||
echo "::group::Merge codeql-cli/latest"
|
||||
set -x
|
||||
git merge codeql-cli/latest
|
||||
set +x
|
||||
echo "::endgroup::"
|
||||
- name: Push sync branch
|
||||
run: |
|
||||
git push origin auto/sync-main-pr
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.WORKFLOW_TOKEN }}
|
||||
GH_TOKEN: ${{ secrets.WORKFLOW_TOKEN }}
|
||||
- name: Create PR if it doesn't exist
|
||||
shell: bash
|
||||
run: |
|
||||
pr_number=$(gh pr list --repo microsoft/codeql --head auto/sync-main-pr --base main --json number --jq '.[0].number')
|
||||
if [ -n "$pr_number" ]; then
|
||||
echo "PR from auto/sync-main-pr to main already exists (PR #$pr_number). Exiting gracefully."
|
||||
else
|
||||
if git fetch origin main auto/sync-main-pr && [ -n "$(git rev-list origin/main..origin/auto/sync-main-pr)" ]; then
|
||||
echo "PR does not exist. Creating one..."
|
||||
gh pr create --repo microsoft/codeql --fill -B main -H auto/sync-main-pr \
|
||||
--label 'autogenerated' \
|
||||
--title 'Sync Main (autogenerated)' \
|
||||
--body "This PR syncs the latest changes from \`codeql-cli/latest\` into \`main\`." \
|
||||
--reviewer 'MathiasVP' \
|
||||
--reviewer 'ropwareJB'
|
||||
else
|
||||
echo "No changes to sync from auto/sync-main-pr to main. Exiting gracefully."
|
||||
fi
|
||||
fi
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.WORKFLOW_TOKEN }}
|
||||
|
||||
3
.gitmodules
vendored
3
.gitmodules
vendored
@@ -1,3 +0,0 @@
|
||||
[submodule "iac"]
|
||||
path = iac
|
||||
url = https://github.com/advanced-security/codeql-extractor-iac
|
||||
27
MODULE.bazel
27
MODULE.bazel
@@ -37,7 +37,6 @@ bazel_dep(name = "buildifier_prebuilt", version = "6.4.0", dev_dependency = True
|
||||
# the versions there are canonical, the versions here are used for CI in github/codeql, as well as for the vendoring of dependencies.
|
||||
RUST_EDITION = "2024"
|
||||
|
||||
# run buildutils-internal/scripts/fill-rust-sha256s.py when updating (internal repo)
|
||||
RUST_VERSION = "1.86.0"
|
||||
|
||||
rust = use_extension("@rules_rust//rust:extensions.bzl", "rust")
|
||||
@@ -48,29 +47,6 @@ rust.toolchain(
|
||||
"x86_64-apple-darwin",
|
||||
"aarch64-apple-darwin",
|
||||
],
|
||||
# generated by buildutils-internal/scripts/fill-rust-sha256s.py (internal repo)
|
||||
sha256s = {
|
||||
"rustc-1.86.0-x86_64-unknown-linux-gnu.tar.xz": "4438b809ce4a083af31ed17aeeedcc8fc60ccffc0625bef1926620751b6989d7",
|
||||
"rustc-1.86.0-x86_64-apple-darwin.tar.xz": "42b76253626febb7912541a30d3379f463dec89581aad4cb72c6c04fb5a71dc5",
|
||||
"rustc-1.86.0-aarch64-apple-darwin.tar.xz": "23b8f52102249a47ab5bc859d54c9a3cb588a3259ba3f00f557d50edeca4fde9",
|
||||
"rustc-1.86.0-x86_64-pc-windows-msvc.tar.xz": "fdde839fea274529a31e51eb85c6df1782cc8479c9d1bc24e2914d66a0de41ab",
|
||||
"clippy-1.86.0-x86_64-unknown-linux-gnu.tar.xz": "02aaff2c1407d2da8dba19aa4970dd873e311902b120a66cbcdbe51eb8836edf",
|
||||
"clippy-1.86.0-x86_64-apple-darwin.tar.xz": "bb85efda7bbffaf124867f5ca36d50932b1e8f533c62ee923438afb32ff8fe9a",
|
||||
"clippy-1.86.0-aarch64-apple-darwin.tar.xz": "239fa3a604b124f0312f2af08537874a1227dba63385484b468cca62e7c4f2f2",
|
||||
"clippy-1.86.0-x86_64-pc-windows-msvc.tar.xz": "d00498f47d49219f032e2c5eeebdfc3d32317c0dc3d3fd7125327445bc482cb4",
|
||||
"cargo-1.86.0-x86_64-unknown-linux-gnu.tar.xz": "c5c1590f7e9246ad9f4f97cfe26ffa92707b52a769726596a9ef81565ebd908b",
|
||||
"cargo-1.86.0-x86_64-apple-darwin.tar.xz": "af163eb02d1a178044d1b4f2375960efd47130f795f6e33d09e345454bb26f4e",
|
||||
"cargo-1.86.0-aarch64-apple-darwin.tar.xz": "3cb13873d48c3e1e4cc684d42c245226a11fba52af6b047c3346ed654e7a05c0",
|
||||
"cargo-1.86.0-x86_64-pc-windows-msvc.tar.xz": "e57a9d89619b5604899bac443e68927bdd371e40f2e03e18950b6ceb3eb67966",
|
||||
"llvm-tools-1.86.0-x86_64-unknown-linux-gnu.tar.xz": "282145ab7a63c98b625856f44b905b4dc726b497246b824632a5790debe95a78",
|
||||
"llvm-tools-1.86.0-x86_64-apple-darwin.tar.xz": "b55706e92f7da989207c50c13c7add483a9fedd233bc431b106eca2a8f151ec9",
|
||||
"llvm-tools-1.86.0-aarch64-apple-darwin.tar.xz": "04d3618c686845853585f036e3211eb9e18f2d290f4610a7a78bdc1fcce1ebd9",
|
||||
"llvm-tools-1.86.0-x86_64-pc-windows-msvc.tar.xz": "721a17cc8dc219177e4277a3592253934ef08daa1e1b12eda669a67d15fad8dd",
|
||||
"rust-std-1.86.0-x86_64-unknown-linux-gnu.tar.xz": "67be7184ea388d8ce0feaf7fdea46f1775cfc2970930264343b3089898501d37",
|
||||
"rust-std-1.86.0-x86_64-apple-darwin.tar.xz": "3b1140d54870a080080e84700143f4a342fbd02a410a319b05d9c02e7dcf44cc",
|
||||
"rust-std-1.86.0-aarch64-apple-darwin.tar.xz": "0fb121fb3b8fa9027d79ff598500a7e5cd086ddbc3557482ed3fdda00832c61b",
|
||||
"rust-std-1.86.0-x86_64-pc-windows-msvc.tar.xz": "3d5354b7b9cb950b58bff3fce18a652aa374bb30c8f70caebd3bd0b43cb41a33",
|
||||
},
|
||||
versions = [RUST_VERSION],
|
||||
)
|
||||
use_repo(rust, "rust_toolchains")
|
||||
@@ -230,7 +206,6 @@ use_repo(
|
||||
"kotlin-compiler-2.1.0-Beta1",
|
||||
"kotlin-compiler-2.1.20-Beta1",
|
||||
"kotlin-compiler-2.2.0-Beta1",
|
||||
"kotlin-compiler-2.2.20-Beta2",
|
||||
"kotlin-compiler-embeddable-1.6.0",
|
||||
"kotlin-compiler-embeddable-1.6.20",
|
||||
"kotlin-compiler-embeddable-1.7.0",
|
||||
@@ -243,7 +218,6 @@ use_repo(
|
||||
"kotlin-compiler-embeddable-2.1.0-Beta1",
|
||||
"kotlin-compiler-embeddable-2.1.20-Beta1",
|
||||
"kotlin-compiler-embeddable-2.2.0-Beta1",
|
||||
"kotlin-compiler-embeddable-2.2.20-Beta2",
|
||||
"kotlin-stdlib-1.6.0",
|
||||
"kotlin-stdlib-1.6.20",
|
||||
"kotlin-stdlib-1.7.0",
|
||||
@@ -256,7 +230,6 @@ use_repo(
|
||||
"kotlin-stdlib-2.1.0-Beta1",
|
||||
"kotlin-stdlib-2.1.20-Beta1",
|
||||
"kotlin-stdlib-2.2.0-Beta1",
|
||||
"kotlin-stdlib-2.2.20-Beta2",
|
||||
)
|
||||
|
||||
go_sdk = use_extension("@rules_go//go:extensions.bzl", "go_sdk")
|
||||
|
||||
@@ -29,5 +29,3 @@ You can install the [CodeQL for Visual Studio Code](https://marketplace.visualst
|
||||
### Tasks
|
||||
|
||||
The `.vscode/tasks.json` file defines custom tasks specific to working in this repository. To invoke one of these tasks, select the `Terminal | Run Task...` menu option, and then select the desired task from the dropdown. You can also invoke the `Tasks: Run Task` command from the command palette.
|
||||
|
||||
|
||||
|
||||
41
SECURITY.md
41
SECURITY.md
@@ -1,41 +0,0 @@
|
||||
<!-- BEGIN MICROSOFT SECURITY.MD V0.0.8 BLOCK -->
|
||||
|
||||
## Security
|
||||
|
||||
Microsoft takes the security of our software products and services seriously, which includes all source code repositories managed through our GitHub organizations, which include [Microsoft](https://github.com/microsoft), [Azure](https://github.com/Azure), [DotNet](https://github.com/dotnet), [AspNet](https://github.com/aspnet), [Xamarin](https://github.com/xamarin), and [our GitHub organizations](https://opensource.microsoft.com/).
|
||||
|
||||
If you believe you have found a security vulnerability in any Microsoft-owned repository that meets [Microsoft's definition of a security vulnerability](https://aka.ms/opensource/security/definition), please report it to us as described below.
|
||||
|
||||
## Reporting Security Issues
|
||||
|
||||
**Please do not report security vulnerabilities through public GitHub issues.**
|
||||
|
||||
Instead, please report them to the Microsoft Security Response Center (MSRC) at [https://msrc.microsoft.com/create-report](https://aka.ms/opensource/security/create-report).
|
||||
|
||||
If you prefer to submit without logging in, send email to [secure@microsoft.com](mailto:secure@microsoft.com). If possible, encrypt your message with our PGP key; please download it from the [Microsoft Security Response Center PGP Key page](https://aka.ms/opensource/security/pgpkey).
|
||||
|
||||
You should receive a response within 24 hours. If for some reason you do not, please follow up via email to ensure we received your original message. Additional information can be found at [microsoft.com/msrc](https://aka.ms/opensource/security/msrc).
|
||||
|
||||
Please include the requested information listed below (as much as you can provide) to help us better understand the nature and scope of the possible issue:
|
||||
|
||||
* Type of issue (e.g. buffer overflow, SQL injection, cross-site scripting, etc.)
|
||||
* Full paths of source file(s) related to the manifestation of the issue
|
||||
* The location of the affected source code (tag/branch/commit or direct URL)
|
||||
* Any special configuration required to reproduce the issue
|
||||
* Step-by-step instructions to reproduce the issue
|
||||
* Proof-of-concept or exploit code (if possible)
|
||||
* Impact of the issue, including how an attacker might exploit the issue
|
||||
|
||||
This information will help us triage your report more quickly.
|
||||
|
||||
If you are reporting for a bug bounty, more complete reports can contribute to a higher bounty award. Please visit our [Microsoft Bug Bounty Program](https://aka.ms/opensource/security/bounty) page for more details about our active programs.
|
||||
|
||||
## Preferred Languages
|
||||
|
||||
We prefer all communications to be in English.
|
||||
|
||||
## Policy
|
||||
|
||||
Microsoft follows the principle of [Coordinated Vulnerability Disclosure](https://aka.ms/opensource/security/cvd).
|
||||
|
||||
<!-- END MICROSOFT SECURITY.MD BLOCK -->
|
||||
@@ -1,13 +1,3 @@
|
||||
## 0.4.14
|
||||
|
||||
No user-facing changes.
|
||||
|
||||
## 0.4.13
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* The `actions/artifact-poisoning/critical` and `actions/artifact-poisoning/medium` queries now exclude artifacts downloaded to `$[{ runner.temp }}` in addition to `/tmp`.
|
||||
|
||||
## 0.4.12
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
## 0.4.13
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* The `actions/artifact-poisoning/critical` and `actions/artifact-poisoning/medium` queries now exclude artifacts downloaded to `$[{ runner.temp }}` in addition to `/tmp`.
|
||||
@@ -1,3 +0,0 @@
|
||||
## 0.4.14
|
||||
|
||||
No user-facing changes.
|
||||
@@ -1,2 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 0.4.14
|
||||
lastReleaseVersion: 0.4.12
|
||||
|
||||
@@ -72,7 +72,7 @@ string normalizePath(string path) {
|
||||
then result = path
|
||||
else
|
||||
// foo -> GITHUB_WORKSPACE/foo
|
||||
if path.regexpMatch("^[^$/~].*")
|
||||
if path.regexpMatch("^[^/~].*")
|
||||
then result = "GITHUB_WORKSPACE/" + path.regexpReplaceAll("/$", "")
|
||||
else
|
||||
// ~/foo -> ~/foo
|
||||
|
||||
@@ -262,10 +262,8 @@ class ArtifactPoisoningSink extends DataFlow::Node {
|
||||
|
||||
ArtifactPoisoningSink() {
|
||||
download.getAFollowingStep() = poisonable and
|
||||
// excluding artifacts downloaded to the temporary directory
|
||||
// excluding artifacts downloaded to /tmp
|
||||
not download.getPath().regexpMatch("^/tmp.*") and
|
||||
not download.getPath().regexpMatch("^\\$\\{\\{\\s*runner\\.temp\\s*}}.*") and
|
||||
not download.getPath().regexpMatch("^\\$RUNNER_TEMP.*") and
|
||||
(
|
||||
poisonable.(Run).getScript() = this.asExpr() and
|
||||
(
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql/actions-all
|
||||
version: 0.4.14
|
||||
version: 0.4.13-dev
|
||||
library: true
|
||||
warnOnImplicitThis: true
|
||||
dependencies:
|
||||
|
||||
@@ -1,11 +1,3 @@
|
||||
## 0.6.6
|
||||
|
||||
No user-facing changes.
|
||||
|
||||
## 0.6.5
|
||||
|
||||
No user-facing changes.
|
||||
|
||||
## 0.6.4
|
||||
|
||||
No user-facing changes.
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
## 0.6.5
|
||||
|
||||
No user-facing changes.
|
||||
@@ -1,3 +0,0 @@
|
||||
## 0.6.6
|
||||
|
||||
No user-facing changes.
|
||||
@@ -1,2 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 0.6.6
|
||||
lastReleaseVersion: 0.6.4
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql/actions-queries
|
||||
version: 0.6.6
|
||||
version: 0.6.5-dev
|
||||
library: false
|
||||
warnOnImplicitThis: true
|
||||
groups: [actions, queries]
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
on:
|
||||
workflow_run:
|
||||
workflows:
|
||||
- Benchmark
|
||||
types:
|
||||
- completed
|
||||
|
||||
jobs:
|
||||
benchmark:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Download From PR
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
run-id: ${{ github.event.workflow_run.id }}
|
||||
path: ${{ runner.temp }}/artifacts/
|
||||
- run: npm install
|
||||
@@ -1,19 +0,0 @@
|
||||
on:
|
||||
workflow_run:
|
||||
workflows:
|
||||
- Benchmark
|
||||
types:
|
||||
- completed
|
||||
|
||||
jobs:
|
||||
benchmark:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Download From PR
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
run-id: ${{ github.event.workflow_run.id }}
|
||||
path: /tmp/artifacts/
|
||||
- run: npm install
|
||||
@@ -1,19 +0,0 @@
|
||||
on:
|
||||
workflow_run:
|
||||
workflows:
|
||||
- Benchmark
|
||||
types:
|
||||
- completed
|
||||
|
||||
jobs:
|
||||
benchmark:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Download From PR
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
run-id: ${{ github.event.workflow_run.id }}
|
||||
path: $RUNNER_TEMP/artifacts/
|
||||
- run: npm install
|
||||
@@ -1,18 +0,0 @@
|
||||
on:
|
||||
workflow_run:
|
||||
workflows:
|
||||
- Benchmark
|
||||
types:
|
||||
- completed
|
||||
|
||||
jobs:
|
||||
benchmark:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Download From PR
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
run-id: ${{ github.event.workflow_run.id }}
|
||||
- run: npm install
|
||||
@@ -1,19 +0,0 @@
|
||||
on:
|
||||
workflow_run:
|
||||
workflows:
|
||||
- Benchmark
|
||||
types:
|
||||
- completed
|
||||
|
||||
jobs:
|
||||
benchmark:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Download From PR
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
run-id: ${{ github.event.workflow_run.id }}
|
||||
path: ${{ runner.temp }}/artifacts/
|
||||
- run: npm install
|
||||
@@ -13,7 +13,6 @@ edges
|
||||
| .github/workflows/artifactpoisoning42.yml:13:9:21:6 | Run Step | .github/workflows/artifactpoisoning42.yml:22:14:22:18 | ./cmd | provenance | Config |
|
||||
| .github/workflows/artifactpoisoning71.yml:9:9:16:6 | Uses Step | .github/workflows/artifactpoisoning71.yml:17:14:18:40 | sed -f config foo.md > bar.md\n | provenance | Config |
|
||||
| .github/workflows/artifactpoisoning81.yml:28:9:31:6 | Uses Step | .github/workflows/artifactpoisoning81.yml:31:14:31:27 | python test.py | provenance | Config |
|
||||
| .github/workflows/artifactpoisoning96.yml:13:9:18:6 | Uses Step | .github/workflows/artifactpoisoning96.yml:18:14:18:24 | npm install | provenance | Config |
|
||||
| .github/workflows/artifactpoisoning101.yml:10:9:16:6 | Uses Step | .github/workflows/artifactpoisoning101.yml:17:14:19:59 | PR_NUMBER=$(./get_pull_request_number.sh pr_number.txt)\necho "PR_NUMBER=$PR_NUMBER" >> $GITHUB_OUTPUT \n | provenance | Config |
|
||||
| .github/workflows/test18.yml:12:15:33:12 | Uses Step | .github/workflows/test18.yml:36:15:40:58 | Uses Step | provenance | Config |
|
||||
| .github/workflows/test25.yml:22:9:32:6 | Uses Step: downloadBuildScan | .github/workflows/test25.yml:39:14:40:45 | ./gradlew buildScanPublishPrevious\n | provenance | Config |
|
||||
@@ -45,8 +44,6 @@ nodes
|
||||
| .github/workflows/artifactpoisoning81.yml:31:14:31:27 | python test.py | semmle.label | python test.py |
|
||||
| .github/workflows/artifactpoisoning92.yml:28:9:29:6 | Uses Step | semmle.label | Uses Step |
|
||||
| .github/workflows/artifactpoisoning92.yml:29:14:29:26 | make snapshot | semmle.label | make snapshot |
|
||||
| .github/workflows/artifactpoisoning96.yml:13:9:18:6 | Uses Step | semmle.label | Uses Step |
|
||||
| .github/workflows/artifactpoisoning96.yml:18:14:18:24 | npm install | semmle.label | npm install |
|
||||
| .github/workflows/artifactpoisoning101.yml:10:9:16:6 | Uses Step | semmle.label | Uses Step |
|
||||
| .github/workflows/artifactpoisoning101.yml:17:14:19:59 | PR_NUMBER=$(./get_pull_request_number.sh pr_number.txt)\necho "PR_NUMBER=$PR_NUMBER" >> $GITHUB_OUTPUT \n | semmle.label | PR_NUMBER=$(./get_pull_request_number.sh pr_number.txt)\necho "PR_NUMBER=$PR_NUMBER" >> $GITHUB_OUTPUT \n |
|
||||
| .github/workflows/test18.yml:12:15:33:12 | Uses Step | semmle.label | Uses Step |
|
||||
@@ -69,7 +66,6 @@ subpaths
|
||||
| .github/workflows/artifactpoisoning81.yml:31:14:31:27 | python test.py | .github/workflows/artifactpoisoning81.yml:28:9:31:6 | Uses Step | .github/workflows/artifactpoisoning81.yml:31:14:31:27 | python test.py | Potential artifact poisoning in $@, which may be controlled by an external user ($@). | .github/workflows/artifactpoisoning81.yml:31:14:31:27 | python test.py | python test.py | .github/workflows/artifactpoisoning81.yml:3:5:3:23 | pull_request_target | pull_request_target |
|
||||
| .github/workflows/artifactpoisoning92.yml:28:9:29:6 | Uses Step | .github/actions/download-artifact-2/action.yaml:6:7:25:4 | Uses Step | .github/workflows/artifactpoisoning92.yml:28:9:29:6 | Uses Step | Potential artifact poisoning in $@, which may be controlled by an external user ($@). | .github/workflows/artifactpoisoning92.yml:28:9:29:6 | Uses Step | Uses Step | .github/workflows/artifactpoisoning92.yml:3:3:3:14 | workflow_run | workflow_run |
|
||||
| .github/workflows/artifactpoisoning92.yml:29:14:29:26 | make snapshot | .github/actions/download-artifact-2/action.yaml:6:7:25:4 | Uses Step | .github/workflows/artifactpoisoning92.yml:29:14:29:26 | make snapshot | Potential artifact poisoning in $@, which may be controlled by an external user ($@). | .github/workflows/artifactpoisoning92.yml:29:14:29:26 | make snapshot | make snapshot | .github/workflows/artifactpoisoning92.yml:3:3:3:14 | workflow_run | workflow_run |
|
||||
| .github/workflows/artifactpoisoning96.yml:18:14:18:24 | npm install | .github/workflows/artifactpoisoning96.yml:13:9:18:6 | Uses Step | .github/workflows/artifactpoisoning96.yml:18:14:18:24 | npm install | Potential artifact poisoning in $@, which may be controlled by an external user ($@). | .github/workflows/artifactpoisoning96.yml:18:14:18:24 | npm install | npm install | .github/workflows/artifactpoisoning96.yml:2:3:2:14 | workflow_run | workflow_run |
|
||||
| .github/workflows/artifactpoisoning101.yml:17:14:19:59 | PR_NUMBER=$(./get_pull_request_number.sh pr_number.txt)\necho "PR_NUMBER=$PR_NUMBER" >> $GITHUB_OUTPUT \n | .github/workflows/artifactpoisoning101.yml:10:9:16:6 | Uses Step | .github/workflows/artifactpoisoning101.yml:17:14:19:59 | PR_NUMBER=$(./get_pull_request_number.sh pr_number.txt)\necho "PR_NUMBER=$PR_NUMBER" >> $GITHUB_OUTPUT \n | Potential artifact poisoning in $@, which may be controlled by an external user ($@). | .github/workflows/artifactpoisoning101.yml:17:14:19:59 | PR_NUMBER=$(./get_pull_request_number.sh pr_number.txt)\necho "PR_NUMBER=$PR_NUMBER" >> $GITHUB_OUTPUT \n | PR_NUMBER=$(./get_pull_request_number.sh pr_number.txt)\necho "PR_NUMBER=$PR_NUMBER" >> $GITHUB_OUTPUT \n | .github/workflows/artifactpoisoning101.yml:4:3:4:21 | pull_request_target | pull_request_target |
|
||||
| .github/workflows/test18.yml:36:15:40:58 | Uses Step | .github/workflows/test18.yml:12:15:33:12 | Uses Step | .github/workflows/test18.yml:36:15:40:58 | Uses Step | Potential artifact poisoning in $@, which may be controlled by an external user ($@). | .github/workflows/test18.yml:36:15:40:58 | Uses Step | Uses Step | .github/workflows/test18.yml:3:5:3:16 | workflow_run | workflow_run |
|
||||
| .github/workflows/test25.yml:39:14:40:45 | ./gradlew buildScanPublishPrevious\n | .github/workflows/test25.yml:22:9:32:6 | Uses Step: downloadBuildScan | .github/workflows/test25.yml:39:14:40:45 | ./gradlew buildScanPublishPrevious\n | Potential artifact poisoning in $@, which may be controlled by an external user ($@). | .github/workflows/test25.yml:39:14:40:45 | ./gradlew buildScanPublishPrevious\n | ./gradlew buildScanPublishPrevious\n | .github/workflows/test25.yml:2:3:2:14 | workflow_run | workflow_run |
|
||||
|
||||
@@ -13,7 +13,6 @@ edges
|
||||
| .github/workflows/artifactpoisoning42.yml:13:9:21:6 | Run Step | .github/workflows/artifactpoisoning42.yml:22:14:22:18 | ./cmd | provenance | Config |
|
||||
| .github/workflows/artifactpoisoning71.yml:9:9:16:6 | Uses Step | .github/workflows/artifactpoisoning71.yml:17:14:18:40 | sed -f config foo.md > bar.md\n | provenance | Config |
|
||||
| .github/workflows/artifactpoisoning81.yml:28:9:31:6 | Uses Step | .github/workflows/artifactpoisoning81.yml:31:14:31:27 | python test.py | provenance | Config |
|
||||
| .github/workflows/artifactpoisoning96.yml:13:9:18:6 | Uses Step | .github/workflows/artifactpoisoning96.yml:18:14:18:24 | npm install | provenance | Config |
|
||||
| .github/workflows/artifactpoisoning101.yml:10:9:16:6 | Uses Step | .github/workflows/artifactpoisoning101.yml:17:14:19:59 | PR_NUMBER=$(./get_pull_request_number.sh pr_number.txt)\necho "PR_NUMBER=$PR_NUMBER" >> $GITHUB_OUTPUT \n | provenance | Config |
|
||||
| .github/workflows/test18.yml:12:15:33:12 | Uses Step | .github/workflows/test18.yml:36:15:40:58 | Uses Step | provenance | Config |
|
||||
| .github/workflows/test25.yml:22:9:32:6 | Uses Step: downloadBuildScan | .github/workflows/test25.yml:39:14:40:45 | ./gradlew buildScanPublishPrevious\n | provenance | Config |
|
||||
@@ -45,8 +44,6 @@ nodes
|
||||
| .github/workflows/artifactpoisoning81.yml:31:14:31:27 | python test.py | semmle.label | python test.py |
|
||||
| .github/workflows/artifactpoisoning92.yml:28:9:29:6 | Uses Step | semmle.label | Uses Step |
|
||||
| .github/workflows/artifactpoisoning92.yml:29:14:29:26 | make snapshot | semmle.label | make snapshot |
|
||||
| .github/workflows/artifactpoisoning96.yml:13:9:18:6 | Uses Step | semmle.label | Uses Step |
|
||||
| .github/workflows/artifactpoisoning96.yml:18:14:18:24 | npm install | semmle.label | npm install |
|
||||
| .github/workflows/artifactpoisoning101.yml:10:9:16:6 | Uses Step | semmle.label | Uses Step |
|
||||
| .github/workflows/artifactpoisoning101.yml:17:14:19:59 | PR_NUMBER=$(./get_pull_request_number.sh pr_number.txt)\necho "PR_NUMBER=$PR_NUMBER" >> $GITHUB_OUTPUT \n | semmle.label | PR_NUMBER=$(./get_pull_request_number.sh pr_number.txt)\necho "PR_NUMBER=$PR_NUMBER" >> $GITHUB_OUTPUT \n |
|
||||
| .github/workflows/test18.yml:12:15:33:12 | Uses Step | semmle.label | Uses Step |
|
||||
|
||||
@@ -51,16 +51,6 @@ edges
|
||||
| .github/workflows/artifactpoisoning92.yml:19:9:25:6 | Run Step: metadata | .github/workflows/artifactpoisoning92.yml:25:9:28:6 | Uses Step |
|
||||
| .github/workflows/artifactpoisoning92.yml:25:9:28:6 | Uses Step | .github/workflows/artifactpoisoning92.yml:28:9:29:6 | Uses Step |
|
||||
| .github/workflows/artifactpoisoning92.yml:28:9:29:6 | Uses Step | .github/workflows/artifactpoisoning92.yml:29:9:29:27 | Run Step |
|
||||
| .github/workflows/artifactpoisoning93.yml:12:9:13:6 | Uses Step | .github/workflows/artifactpoisoning93.yml:13:9:19:6 | Uses Step |
|
||||
| .github/workflows/artifactpoisoning93.yml:13:9:19:6 | Uses Step | .github/workflows/artifactpoisoning93.yml:19:9:19:24 | Run Step |
|
||||
| .github/workflows/artifactpoisoning94.yml:12:9:13:6 | Uses Step | .github/workflows/artifactpoisoning94.yml:13:9:19:6 | Uses Step |
|
||||
| .github/workflows/artifactpoisoning94.yml:13:9:19:6 | Uses Step | .github/workflows/artifactpoisoning94.yml:19:9:19:24 | Run Step |
|
||||
| .github/workflows/artifactpoisoning95.yml:12:9:13:6 | Uses Step | .github/workflows/artifactpoisoning95.yml:13:9:19:6 | Uses Step |
|
||||
| .github/workflows/artifactpoisoning95.yml:13:9:19:6 | Uses Step | .github/workflows/artifactpoisoning95.yml:19:9:19:24 | Run Step |
|
||||
| .github/workflows/artifactpoisoning96.yml:12:9:13:6 | Uses Step | .github/workflows/artifactpoisoning96.yml:13:9:18:6 | Uses Step |
|
||||
| .github/workflows/artifactpoisoning96.yml:13:9:18:6 | Uses Step | .github/workflows/artifactpoisoning96.yml:18:9:18:24 | Run Step |
|
||||
| .github/workflows/artifactpoisoning97.yml:12:9:13:6 | Uses Step | .github/workflows/artifactpoisoning97.yml:13:9:19:6 | Uses Step |
|
||||
| .github/workflows/artifactpoisoning97.yml:13:9:19:6 | Uses Step | .github/workflows/artifactpoisoning97.yml:19:9:19:25 | Run Step |
|
||||
| .github/workflows/artifactpoisoning101.yml:10:9:16:6 | Uses Step | .github/workflows/artifactpoisoning101.yml:16:9:19:59 | Run Step: pr_number |
|
||||
| .github/workflows/auto_ci.yml:20:9:27:6 | Uses Step | .github/workflows/auto_ci.yml:27:9:32:6 | Uses Step |
|
||||
| .github/workflows/auto_ci.yml:27:9:32:6 | Uses Step | .github/workflows/auto_ci.yml:32:9:37:6 | Run Step |
|
||||
|
||||
@@ -231,10 +231,35 @@
|
||||
"java/ql/src/experimental/Security/CWE/CWE-400/LocalThreadResourceAbuse.qhelp",
|
||||
"java/ql/src/experimental/Security/CWE/CWE-400/ThreadResourceAbuse.qhelp"
|
||||
],
|
||||
"CryptoAlgorithms Python/JS/Ruby": [
|
||||
"javascript/ql/lib/semmle/javascript/security/CryptoAlgorithms.qll",
|
||||
"python/ql/lib/semmle/python/concepts/CryptoAlgorithms.qll",
|
||||
"ruby/ql/lib/codeql/ruby/security/CryptoAlgorithms.qll",
|
||||
"rust/ql/lib/codeql/rust/security/CryptoAlgorithms.qll"
|
||||
],
|
||||
"CryptoAlgorithmNames Python/JS/Ruby": [
|
||||
"javascript/ql/lib/semmle/javascript/security/internal/CryptoAlgorithmNames.qll",
|
||||
"python/ql/lib/semmle/python/concepts/internal/CryptoAlgorithmNames.qll",
|
||||
"ruby/ql/lib/codeql/ruby/security/internal/CryptoAlgorithmNames.qll",
|
||||
"rust/ql/lib/codeql/rust/security/internal/CryptoAlgorithmNames.qll"
|
||||
],
|
||||
"SensitiveDataHeuristics Python/JS": [
|
||||
"javascript/ql/lib/semmle/javascript/security/internal/SensitiveDataHeuristics.qll",
|
||||
"python/ql/lib/semmle/python/security/internal/SensitiveDataHeuristics.qll",
|
||||
"ruby/ql/lib/codeql/ruby/security/internal/SensitiveDataHeuristics.qll",
|
||||
"swift/ql/lib/codeql/swift/security/internal/SensitiveDataHeuristics.qll",
|
||||
"rust/ql/lib/codeql/rust/security/internal/SensitiveDataHeuristics.qll"
|
||||
],
|
||||
"IncompleteUrlSubstringSanitization": [
|
||||
"javascript/ql/src/Security/CWE-020/IncompleteUrlSubstringSanitization.qll",
|
||||
"ruby/ql/src/queries/security/cwe-020/IncompleteUrlSubstringSanitization.qll"
|
||||
],
|
||||
"Concepts Python/Ruby/JS": [
|
||||
"python/ql/lib/semmle/python/internal/ConceptsShared.qll",
|
||||
"ruby/ql/lib/codeql/ruby/internal/ConceptsShared.qll",
|
||||
"javascript/ql/lib/semmle/javascript/internal/ConceptsShared.qll",
|
||||
"rust/ql/lib/codeql/rust/internal/ConceptsShared.qll"
|
||||
],
|
||||
"ApiGraphModels": [
|
||||
"javascript/ql/lib/semmle/javascript/frameworks/data/internal/ApiGraphModels.qll",
|
||||
"ruby/ql/lib/codeql/ruby/frameworks/data/internal/ApiGraphModels.qll",
|
||||
|
||||
@@ -2,9 +2,6 @@ language: cpp
|
||||
strategy: dca
|
||||
destination: cpp/ql/lib/ext/generated
|
||||
targets:
|
||||
- name: glibc
|
||||
with-sinks: false
|
||||
with-sources: false
|
||||
- name: zlib
|
||||
with-sinks: false
|
||||
with-sources: false
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,2 +0,0 @@
|
||||
description: Uncomment cases in dbscheme
|
||||
compatibility: full
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,2 +0,0 @@
|
||||
description: Remove unused external_package tables from the dbscheme
|
||||
compatibility: full
|
||||
@@ -1,9 +0,0 @@
|
||||
class Function extends @function {
|
||||
string toString() { none() }
|
||||
}
|
||||
|
||||
from Function f, string n, int k, int new_k
|
||||
where
|
||||
functions(f, n, k) and
|
||||
if builtin_functions(f) then new_k = 6 else new_k = k
|
||||
select f, n, new_k
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,4 +0,0 @@
|
||||
description: Move builtin function identification to its own table
|
||||
compatibility: full
|
||||
functions.rel: run functions.qlo
|
||||
builtin_functions.rel: delete
|
||||
@@ -4,3 +4,4 @@
|
||||
int main() {
|
||||
return ONE + TWO + THREE + FOUR;
|
||||
}
|
||||
// semmle-extractor-options: --clang -include-pch ${testdir}/clang-pch.testproj/a.pch -Iextra_dummy_path
|
||||
|
||||
@@ -1,30 +1,3 @@
|
||||
## 5.4.0
|
||||
|
||||
### New Features
|
||||
|
||||
* Exposed various SSA-related classes (`Definition`, `PhiNode`, `ExplicitDefinition`, `DirectExplicitDefinition`, and `IndirectExplicitDefinition`) which were previously only usable inside the internal dataflow directory.
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
* The `cpp/overrun-write` query now recognizes more bound checks and thus produces fewer false positives.
|
||||
|
||||
## 5.3.0
|
||||
|
||||
### Deprecated APIs
|
||||
|
||||
* The `UnknownDefaultLocation`, `UnknownExprLocation`, and `UnknownStmtLocation` classes have been deprecated. Use `UnknownLocation` instead.
|
||||
|
||||
### New Features
|
||||
|
||||
* Added a `isFinalValueOfParameter` predicate to `DataFlow::Node` which holds when a dataflow node represents the final value of an output parameter of a function.
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
* The `FunctionWithWrappers` library (`semmle.code.cpp.security.FunctionWithWrappers`) no longer considers calls through function pointers as wrapper functions.
|
||||
* The analysis of C/C++ code targeting 64-bit Arm platforms has been improved. This includes support for the Arm-specific builtin functions, support for the `arm_neon.h` header and Neon vector types, and support for the `fp8` scalar type. The `arm_sve.h` header and scalable vectors are only partially supported at this point.
|
||||
* Added support for `__fp16 _Complex` and `__bf16 _Complex` types
|
||||
* Added `sql-injection` sink models for the Oracle Call Interface (OCI) database library functions `OCIStmtPrepare` and `OCIStmtPrepare2`.
|
||||
|
||||
## 5.2.0
|
||||
|
||||
### Deprecated APIs
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
---
|
||||
category: feature
|
||||
---
|
||||
* Added a new class `AdditionalCallTarget` for specifying additional call targets.
|
||||
4
cpp/ql/lib/change-notes/2025-06-20-oracle-oci-models.md
Normal file
4
cpp/ql/lib/change-notes/2025-06-20-oracle-oci-models.md
Normal file
@@ -0,0 +1,4 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* Added `sql-injection` sink models for the Oracle Call Interface (OCI) database library functions `OCIStmtPrepare` and `OCIStmtPrepare2`.
|
||||
4
cpp/ql/lib/change-notes/2025-06-24-float16 copy.md
Normal file
4
cpp/ql/lib/change-notes/2025-06-24-float16 copy.md
Normal file
@@ -0,0 +1,4 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* The analysis of C/C++ code targeting 64-bit Arm platforms has been improved. This includes support for the Arm-specific builtin functions, support for the `arm_neon.h` header and Neon vector types, and support for the `fp8` scalar type. The `arm_sve.h` header and scalable vectors are only partially supported at this point.
|
||||
4
cpp/ql/lib/change-notes/2025-06-24-float16.md
Normal file
4
cpp/ql/lib/change-notes/2025-06-24-float16.md
Normal file
@@ -0,0 +1,4 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* Added support for `__fp16 _Complex` and `__bf16 _Complex` types
|
||||
4
cpp/ql/lib/change-notes/2025-06-27-locations.md
Normal file
4
cpp/ql/lib/change-notes/2025-06-27-locations.md
Normal file
@@ -0,0 +1,4 @@
|
||||
---
|
||||
category: deprecated
|
||||
---
|
||||
* The `UnknownDefaultLocation`, `UnknownExprLocation`, and `UnknownStmtLocation` classes have been deprecated. Use `UnknownLocation` instead.
|
||||
@@ -1,16 +0,0 @@
|
||||
## 5.3.0
|
||||
|
||||
### Deprecated APIs
|
||||
|
||||
* The `UnknownDefaultLocation`, `UnknownExprLocation`, and `UnknownStmtLocation` classes have been deprecated. Use `UnknownLocation` instead.
|
||||
|
||||
### New Features
|
||||
|
||||
* Added a `isFinalValueOfParameter` predicate to `DataFlow::Node` which holds when a dataflow node represents the final value of an output parameter of a function.
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
* The `FunctionWithWrappers` library (`semmle.code.cpp.security.FunctionWithWrappers`) no longer considers calls through function pointers as wrapper functions.
|
||||
* The analysis of C/C++ code targeting 64-bit Arm platforms has been improved. This includes support for the Arm-specific builtin functions, support for the `arm_neon.h` header and Neon vector types, and support for the `fp8` scalar type. The `arm_sve.h` header and scalable vectors are only partially supported at this point.
|
||||
* Added support for `__fp16 _Complex` and `__bf16 _Complex` types
|
||||
* Added `sql-injection` sink models for the Oracle Call Interface (OCI) database library functions `OCIStmtPrepare` and `OCIStmtPrepare2`.
|
||||
@@ -1,9 +0,0 @@
|
||||
## 5.4.0
|
||||
|
||||
### New Features
|
||||
|
||||
* Exposed various SSA-related classes (`Definition`, `PhiNode`, `ExplicitDefinition`, `DirectExplicitDefinition`, and `IndirectExplicitDefinition`) which were previously only usable inside the internal dataflow directory.
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
* The `cpp/overrun-write` query now recognizes more bound checks and thus produces fewer false positives.
|
||||
@@ -1,2 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 5.4.0
|
||||
lastReleaseVersion: 5.2.0
|
||||
|
||||
@@ -115,10 +115,6 @@ private string normalizeFunctionName(Function f, string algType) {
|
||||
(result.matches("RSA") implies not f.getName().toUpperCase().matches("%UNIVERSAL%")) and
|
||||
//rsaz functions deemed to be too low level, and can be ignored
|
||||
not f.getLocation().getFile().getBaseName().matches("rsaz_exp.c") and
|
||||
// SHA false positives
|
||||
(result.matches("SHA") implies not f.getName().toUpperCase().matches("%SHAKE%")) and
|
||||
// CAST false positives
|
||||
(result.matches("CAST") implies not f.getName().toUpperCase().matches(["%UPCAST%", "%DOWNCAST%"])) and
|
||||
// General False positives
|
||||
// Functions that 'get' do not set an algorithm, and therefore are considered ignorable
|
||||
not f.getName().toLowerCase().matches("%get%")
|
||||
|
||||
@@ -32,18 +32,4 @@ extensions:
|
||||
- ["", "", False, "CommandLineToArgvA", "", "", "Argument[*0]", "ReturnValue[**]", "taint", "manual"]
|
||||
- ["", "", False, "CommandLineToArgvW", "", "", "Argument[*0]", "ReturnValue[**]", "taint", "manual"]
|
||||
# fileapi.h
|
||||
- ["", "", False, "ReadFileEx", "", "", "Argument[*3].Field[@hEvent]", "Argument[4].Parameter[*2].Field[@hEvent]", "value", "manual"]
|
||||
# processthreadsapi.h
|
||||
- ["", "", False, "CreateThread", "", "", "Argument[@3]", "Argument[2].Parameter[@0]", "value", "manual"]
|
||||
- ["", "", False, "CreateRemoteThread", "", "", "Argument[@4]", "Argument[3].Parameter[@0]", "value", "manual"]
|
||||
- ["", "", False, "CreateRemoteThreadEx", "", "", "Argument[@4]", "Argument[3].Parameter[@0]", "value", "manual"]
|
||||
# wdm.h
|
||||
- ["", "", False, "RtlCopyVolatileMemory", "", "", "Argument[*@1]", "Argument[*@0]", "value", "manual"]
|
||||
- ["", "", False, "RtlCopyDeviceMemory", "", "", "Argument[*@1]", "Argument[*@0]", "value", "manual"]
|
||||
- ["", "", False, "RtlCopyMemory", "", "", "Argument[*@1]", "Argument[*@0]", "value", "manual"]
|
||||
- ["", "", False, "RtlCopyMemoryNonTemporal", "", "", "Argument[*@1]", "Argument[*@0]", "value", "manual"]
|
||||
- ["", "", False, "RtlCopyUnicodeString", "", "", "Argument[*1].Field[*Buffer]", "Argument[*0].Field[*Buffer]", "value", "manual"]
|
||||
- ["", "", False, "RtlMoveMemory", "", "", "Argument[*@1]", "Argument[*@0]", "value", "manual"]
|
||||
- ["", "", False, "RtlMoveVolatileMemory", "", "", "Argument[*@1]", "Argument[*@0]", "value", "manual"]
|
||||
# winternl.h
|
||||
- ["", "", False, "RtlInitUnicodeString", "", "", "Argument[*1]", "Argument[*0].Field[*Buffer]", "value", "manual"]
|
||||
- ["", "", False, "ReadFileEx", "", "", "Argument[*3].Field[@hEvent]", "Argument[4].Parameter[*2].Field[@hEvent]", "value", "manual"]
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,6 +0,0 @@
|
||||
extensions:
|
||||
- addsTo:
|
||||
pack: codeql/cpp-all
|
||||
extensible: summaryModel
|
||||
data: # namespace, type, subtypes, name, signature, ext, input, output, kind, provenance
|
||||
- ["", "", False, "pthread_create", "", "", "Argument[@3]", "Argument[2].Parameter[@0]", "value", "manual"]
|
||||
@@ -1,11 +0,0 @@
|
||||
extensions:
|
||||
- addsTo:
|
||||
pack: codeql/cpp-all
|
||||
extensible: summaryModel
|
||||
data: # namespace, type, subtypes, name, signature, ext, input, output, kind, provenance
|
||||
- ["std", "thread", True, "thread", "", "", "Argument[*@1]", "Argument[0].Parameter[@0]", "value", "manual"]
|
||||
- ["std", "thread", True, "thread", "", "", "Argument[*@2]", "Argument[0].Parameter[@1]", "value", "manual"]
|
||||
- ["std", "thread", True, "thread", "", "", "Argument[*@3]", "Argument[0].Parameter[@2]", "value", "manual"]
|
||||
- ["std", "thread", True, "thread", "", "", "Argument[*@4]", "Argument[0].Parameter[@3]", "value", "manual"]
|
||||
- ["std", "thread", True, "thread", "", "", "Argument[*@5]", "Argument[0].Parameter[@4]", "value", "manual"]
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql/cpp-all
|
||||
version: 5.4.0
|
||||
version: 5.2.1-dev
|
||||
groups: cpp
|
||||
dbscheme: semmlecode.cpp.dbscheme
|
||||
extractor: cpp
|
||||
@@ -15,7 +15,6 @@ dependencies:
|
||||
codeql/tutorial: ${workspace}
|
||||
codeql/util: ${workspace}
|
||||
codeql/xml: ${workspace}
|
||||
codeql/global-controlflow: ${workspace}
|
||||
dataExtensions:
|
||||
- ext/*.model.yml
|
||||
- ext/generated/**/*.model.yml
|
||||
|
||||
@@ -57,9 +57,7 @@ class RequiresExpr extends Expr, @requires_expr {
|
||||
/**
|
||||
* A C++ requirement in a requires expression.
|
||||
*/
|
||||
class RequirementExpr extends Expr {
|
||||
RequirementExpr() { this.getParent() instanceof RequiresExpr }
|
||||
}
|
||||
class RequirementExpr extends Expr { }
|
||||
|
||||
/**
|
||||
* A C++ simple requirement in a requires expression.
|
||||
@@ -72,6 +70,7 @@ class RequirementExpr extends Expr {
|
||||
*/
|
||||
class SimpleRequirementExpr extends RequirementExpr {
|
||||
SimpleRequirementExpr() {
|
||||
this.getParent() instanceof RequiresExpr and
|
||||
not this instanceof TypeRequirementExpr and
|
||||
not this instanceof CompoundRequirementExpr and
|
||||
not this instanceof NestedRequirementExpr
|
||||
@@ -90,6 +89,8 @@ class SimpleRequirementExpr extends RequirementExpr {
|
||||
* with `T` a template parameter, then `typename T::a_field;` is a type requirement.
|
||||
*/
|
||||
class TypeRequirementExpr extends RequirementExpr, TypeName {
|
||||
TypeRequirementExpr() { this.getParent() instanceof RequiresExpr }
|
||||
|
||||
override string getAPrimaryQlClass() { result = "TypeRequirementExpr" }
|
||||
}
|
||||
|
||||
@@ -139,7 +140,7 @@ class CompoundRequirementExpr extends RequirementExpr, @compound_requirement {
|
||||
* with `T` a template parameter, then `requires std::is_same<T, int>::value;` is
|
||||
* a nested requirement.
|
||||
*/
|
||||
class NestedRequirementExpr extends RequirementExpr, @nested_requirement {
|
||||
class NestedRequirementExpr extends Expr, @nested_requirement {
|
||||
override string toString() { result = "requires ..." }
|
||||
|
||||
override string getAPrimaryQlClass() { result = "NestedRequirementExpr" }
|
||||
@@ -162,7 +163,7 @@ class NestedRequirementExpr extends RequirementExpr, @nested_requirement {
|
||||
* then `C<int, 1>` is a concept id expression that refers to
|
||||
* the concept `C`.
|
||||
*/
|
||||
class ConceptIdExpr extends Expr, @concept_id {
|
||||
class ConceptIdExpr extends RequirementExpr, @concept_id {
|
||||
override string toString() {
|
||||
result = this.getConcept().getName() + "<...>"
|
||||
or
|
||||
|
||||
@@ -282,12 +282,9 @@ class Function extends Declaration, ControlFlowNode, AccessHolder, @function {
|
||||
* definition, if possible.)
|
||||
*/
|
||||
override Location getLocation() {
|
||||
if this instanceof BuiltInFunction
|
||||
then result instanceof UnknownLocation // a dummy location for the built-in function
|
||||
else
|
||||
if exists(this.getDefinition())
|
||||
then result = this.getDefinitionLocation()
|
||||
else result = this.getADeclarationLocation()
|
||||
if exists(this.getDefinition())
|
||||
then result = this.getDefinitionLocation()
|
||||
else result = this.getADeclarationLocation()
|
||||
}
|
||||
|
||||
/** Gets a child declaration of this function. */
|
||||
@@ -899,9 +896,17 @@ class FunctionTemplateSpecialization extends Function {
|
||||
* A GCC built-in function. For example: `__builtin___memcpy_chk`.
|
||||
*/
|
||||
class BuiltInFunction extends Function {
|
||||
BuiltInFunction() { builtin_functions(underlyingElement(this)) }
|
||||
BuiltInFunction() { functions(underlyingElement(this), _, 6) }
|
||||
|
||||
/** Gets a dummy location for the built-in function. */
|
||||
override Location getLocation() {
|
||||
suppressUnusedThis(this) and
|
||||
result instanceof UnknownLocation
|
||||
}
|
||||
}
|
||||
|
||||
private predicate suppressUnusedThis(Function f) { any() }
|
||||
|
||||
/**
|
||||
* A C++ user-defined literal [N4140 13.5.8].
|
||||
*/
|
||||
|
||||
@@ -15,13 +15,6 @@ class StandardSsa extends SsaHelper {
|
||||
}
|
||||
|
||||
/**
|
||||
* NOTE: If possible, prefer the SSA classes exposed by the new dataflow
|
||||
* library:
|
||||
* ```
|
||||
* import semmle.code.cpp.dataflow.new.DataFlow
|
||||
* // use `DataFlow::Ssa::Definition`
|
||||
* ```
|
||||
*
|
||||
* A definition of one or more SSA variables, including phi node definitions.
|
||||
* An _SSA variable_, as defined in the literature, is effectively the pair of
|
||||
* an `SsaDefinition d` and a `StackVariable v`, written `(d, v)` in this
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
import cpp
|
||||
|
||||
/**
|
||||
* Provides classes for performing global (inter-procedural) control flow analyses.
|
||||
*/
|
||||
module ControlFlow {
|
||||
private import internal.ControlFlowSpecific
|
||||
private import codeql.globalcontrolflow.ControlFlow
|
||||
import ControlFlowMake<Location, CppControlFlow>
|
||||
import Public
|
||||
}
|
||||
@@ -1,41 +0,0 @@
|
||||
private import semmle.code.cpp.ir.IR
|
||||
private import cpp as Cpp
|
||||
private import ControlFlowPublic
|
||||
private import semmle.code.cpp.ir.dataflow.internal.DataFlowPrivate as DataFlowPrivate
|
||||
private import semmle.code.cpp.ir.dataflow.internal.DataFlowImplCommon as DataFlowImplCommon
|
||||
|
||||
predicate edge(Node n1, Node n2) { n1.asInstruction().getASuccessor() = n2.asInstruction() }
|
||||
|
||||
predicate callTarget(CallNode call, Callable target) {
|
||||
exists(DataFlowPrivate::DataFlowCall dfCall | dfCall.asCallInstruction() = call.asInstruction() |
|
||||
DataFlowImplCommon::viableCallableCached(dfCall).asSourceCallable() = target
|
||||
or
|
||||
DataFlowImplCommon::viableCallableLambda(dfCall, _).asSourceCallable() = target
|
||||
)
|
||||
}
|
||||
|
||||
predicate flowEntry(Callable c, Node entry) {
|
||||
entry.asInstruction().(EnterFunctionInstruction).getEnclosingFunction() = c
|
||||
}
|
||||
|
||||
predicate flowExit(Callable c, Node exitNode) {
|
||||
exitNode.asInstruction().(ExitFunctionInstruction).getEnclosingFunction() = c
|
||||
}
|
||||
|
||||
Callable getEnclosingCallable(Node n) { n.getEnclosingFunction() = result }
|
||||
|
||||
predicate hiddenNode(Node n) { n.asInstruction() instanceof PhiInstruction }
|
||||
|
||||
private newtype TSplit = TNone() { none() }
|
||||
|
||||
class Split extends TSplit {
|
||||
abstract string toString();
|
||||
|
||||
abstract Cpp::Location getLocation();
|
||||
|
||||
abstract predicate entry(Node n1, Node n2);
|
||||
|
||||
abstract predicate exit(Node n1, Node n2);
|
||||
|
||||
abstract predicate blocked(Node n1, Node n2);
|
||||
}
|
||||
@@ -1,79 +0,0 @@
|
||||
private import semmle.code.cpp.ir.IR
|
||||
private import cpp
|
||||
|
||||
private newtype TNode = TInstructionNode(Instruction i)
|
||||
|
||||
abstract private class NodeImpl extends TNode {
|
||||
/** Gets the `Instruction` associated with this node, if any. */
|
||||
Instruction asInstruction() { result = this.(InstructionNode).getInstruction() }
|
||||
|
||||
/** Gets the `Expr` associated with this node, if any. */
|
||||
Expr asExpr() { result = this.(ExprNode).getExpr() }
|
||||
|
||||
/** Gets the `Parameter` associated with this node, if any. */
|
||||
Parameter asParameter() { result = this.(ParameterNode).getParameter() }
|
||||
|
||||
/** Gets the location of this node. */
|
||||
Location getLocation() { none() }
|
||||
|
||||
/**
|
||||
* Holds if this element is at the specified location.
|
||||
* The location spans column `startcolumn` of line `startline` to
|
||||
* column `endcolumn` of line `endline` in file `filepath`.
|
||||
* For more information, see
|
||||
* [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
|
||||
*/
|
||||
final predicate hasLocationInfo(
|
||||
string filepath, int startline, int startcolumn, int endline, int endcolumn
|
||||
) {
|
||||
this.getLocation().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
|
||||
}
|
||||
|
||||
/** Gets a textual representation of this node. */
|
||||
abstract string toString();
|
||||
|
||||
/** Gets the enclosing callable of this node. */
|
||||
abstract Callable getEnclosingFunction();
|
||||
}
|
||||
|
||||
final class Node = NodeImpl;
|
||||
|
||||
private class InstructionNode extends NodeImpl {
|
||||
Instruction instr;
|
||||
|
||||
InstructionNode() { this = TInstructionNode(instr) }
|
||||
|
||||
/** Gets the `Instruction` associated with this node. */
|
||||
Instruction getInstruction() { result = instr }
|
||||
|
||||
final override Location getLocation() { result = instr.getLocation() }
|
||||
|
||||
final override string toString() { result = instr.getAst().toString() }
|
||||
|
||||
final override Callable getEnclosingFunction() { result = instr.getEnclosingFunction() }
|
||||
}
|
||||
|
||||
private class ExprNode extends InstructionNode {
|
||||
Expr e;
|
||||
|
||||
ExprNode() { e = this.getInstruction().getConvertedResultExpression() }
|
||||
|
||||
/** Gets the `Expr` associated with this node. */
|
||||
Expr getExpr() { result = e }
|
||||
}
|
||||
|
||||
private class ParameterNode extends InstructionNode {
|
||||
override InitializeParameterInstruction instr;
|
||||
Parameter p;
|
||||
|
||||
ParameterNode() { p = instr.getParameter() }
|
||||
|
||||
/** Gets the `Parameter` associated with this node. */
|
||||
Parameter getParameter() { result = p }
|
||||
}
|
||||
|
||||
class CallNode extends InstructionNode {
|
||||
override CallInstruction instr;
|
||||
}
|
||||
|
||||
class Callable = Function;
|
||||
@@ -1,19 +0,0 @@
|
||||
/**
|
||||
* Provides IR-specific definitions for use in the data flow library.
|
||||
*/
|
||||
|
||||
private import cpp
|
||||
private import codeql.globalcontrolflow.ControlFlow
|
||||
|
||||
module Private {
|
||||
import ControlFlowPrivate
|
||||
}
|
||||
|
||||
module Public {
|
||||
import ControlFlowPublic
|
||||
}
|
||||
|
||||
module CppControlFlow implements InputSig<Location> {
|
||||
import Private
|
||||
import Public
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
private import cpp
|
||||
private import semmle.code.cpp.ir.IR
|
||||
private import semmle.code.cpp.ir.dataflow.DataFlow
|
||||
private import DataFlowPrivate
|
||||
private import DataFlowUtil
|
||||
private import DataFlowImplCommon as DataFlowImplCommon
|
||||
@@ -59,7 +60,7 @@ private module VirtualDispatch {
|
||||
* `resolve` predicate to stitch that information together and resolve the
|
||||
* call.
|
||||
*/
|
||||
abstract Node getDispatchValue();
|
||||
abstract DataFlow::Node getDispatchValue();
|
||||
|
||||
/** Gets a candidate target for this call. */
|
||||
abstract Function resolve();
|
||||
@@ -71,13 +72,17 @@ private module VirtualDispatch {
|
||||
* parameter is true when the search is allowed to continue backwards into
|
||||
* a parameter; non-recursive callers should pass `_` for `allowFromArg`.
|
||||
*/
|
||||
predicate flowsFrom(Node src, boolean allowFromArg) {
|
||||
predicate flowsFrom(DataFlow::Node src, boolean allowFromArg) {
|
||||
src = this.getDispatchValue() and allowFromArg = true
|
||||
or
|
||||
exists(Node other, boolean allowOtherFromArg | this.flowsFrom(other, allowOtherFromArg) |
|
||||
exists(DataFlow::Node other, boolean allowOtherFromArg |
|
||||
this.flowsFrom(other, allowOtherFromArg)
|
||||
|
|
||||
// Call argument
|
||||
exists(DataFlowCall call, Position i |
|
||||
other.(ParameterNode).isParameterOf(pragma[only_bind_into](call).getStaticCallTarget(), i) and
|
||||
other
|
||||
.(DataFlow::ParameterNode)
|
||||
.isParameterOf(pragma[only_bind_into](call).getStaticCallTarget(), i) and
|
||||
src.(ArgumentNode).argumentOf(call, pragma[only_bind_into](pragma[only_bind_out](i)))
|
||||
) and
|
||||
allowOtherFromArg = true and
|
||||
@@ -91,7 +96,7 @@ private module VirtualDispatch {
|
||||
allowFromArg = false
|
||||
or
|
||||
// Local flow
|
||||
localFlowStep(src, other) and
|
||||
DataFlow::localFlowStep(src, other) and
|
||||
allowFromArg = allowOtherFromArg
|
||||
or
|
||||
// Flow from global variable to load.
|
||||
@@ -154,11 +159,11 @@ private module VirtualDispatch {
|
||||
private class DataSensitiveExprCall extends DataSensitiveCall {
|
||||
DataSensitiveExprCall() { not exists(this.getStaticCallTarget()) }
|
||||
|
||||
override Node getDispatchValue() { result.asOperand() = this.getCallTargetOperand() }
|
||||
override DataFlow::Node getDispatchValue() { result.asOperand() = this.getCallTargetOperand() }
|
||||
|
||||
override Function resolve() {
|
||||
exists(FunctionInstruction fi |
|
||||
this.flowsFrom(instructionNode(fi), _) and
|
||||
this.flowsFrom(DataFlow::instructionNode(fi), _) and
|
||||
result = fi.getFunctionSymbol()
|
||||
) and
|
||||
(
|
||||
@@ -181,7 +186,7 @@ private module VirtualDispatch {
|
||||
)
|
||||
}
|
||||
|
||||
override Node getDispatchValue() { result.asInstruction() = this.getArgument(-1) }
|
||||
override DataFlow::Node getDispatchValue() { result.asInstruction() = this.getArgument(-1) }
|
||||
|
||||
override MemberFunction resolve() {
|
||||
exists(Class overridingClass |
|
||||
@@ -208,7 +213,7 @@ private module VirtualDispatch {
|
||||
pragma[noinline]
|
||||
private predicate hasFlowFromCastFrom(Class derivedClass) {
|
||||
exists(ConvertToBaseInstruction toBase |
|
||||
this.flowsFrom(instructionNode(toBase), _) and
|
||||
this.flowsFrom(DataFlow::instructionNode(toBase), _) and
|
||||
derivedClass = toBase.getDerivedClass()
|
||||
)
|
||||
}
|
||||
@@ -265,7 +270,7 @@ private predicate mayBenefitFromCallContext(
|
||||
exists(InitializeParameterInstruction init |
|
||||
not exists(call.getStaticCallTarget()) and
|
||||
init.getEnclosingFunction() = f.getUnderlyingCallable() and
|
||||
call.flowsFrom(instructionNode(init), _) and
|
||||
call.flowsFrom(DataFlow::instructionNode(init), _) and
|
||||
init.getParameter().getIndex() = arg
|
||||
)
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ private import semmle.code.cpp.ir.IR
|
||||
private import DataFlowDispatch
|
||||
private import semmle.code.cpp.ir.internal.IRCppLanguage
|
||||
private import semmle.code.cpp.dataflow.internal.FlowSummaryImpl as FlowSummaryImpl
|
||||
private import SsaImpl as Ssa
|
||||
private import SsaInternals as Ssa
|
||||
private import DataFlowImplCommon as DataFlowImplCommon
|
||||
private import codeql.util.Unit
|
||||
private import Node0ToString
|
||||
@@ -1382,89 +1382,16 @@ predicate neverSkipInPathGraph(Node n) {
|
||||
exists(n.asIndirectDefinition())
|
||||
}
|
||||
|
||||
private newtype TLambdaCallKind =
|
||||
TFunctionPointer() or
|
||||
TFunctor()
|
||||
|
||||
class LambdaCallKind extends TLambdaCallKind {
|
||||
predicate isFunctionPointer() { this = TFunctionPointer() }
|
||||
|
||||
predicate isFunctor() { this = TFunctor() }
|
||||
|
||||
string toString() {
|
||||
this.isFunctionPointer() and
|
||||
result = "Function pointer kind"
|
||||
or
|
||||
this.isFunctor() and
|
||||
result = "Functor kind"
|
||||
}
|
||||
}
|
||||
|
||||
private class ConstructorCallInstruction extends CallInstruction {
|
||||
Cpp::Class constructedType;
|
||||
|
||||
ConstructorCallInstruction() {
|
||||
this.getStaticCallTarget().(Cpp::Constructor).getDeclaringType() = constructedType
|
||||
}
|
||||
|
||||
Cpp::Class getConstructedType() { result = constructedType }
|
||||
}
|
||||
|
||||
private class OperatorCall extends Cpp::MemberFunction {
|
||||
OperatorCall() { this.hasName("operator()") }
|
||||
}
|
||||
|
||||
private predicate isFunctorCreationWithoutConstructor(Node creation, OperatorCall operator) {
|
||||
exists(UninitializedInstruction init, Instruction dest |
|
||||
// A construction of an object with no constructor. In this case we use
|
||||
// the `UninitializedInstruction` as the creation node.
|
||||
init = creation.asInstruction() and
|
||||
dest = init.getDestinationAddress() and
|
||||
not any(ConstructorCallInstruction constructorCall).getThisArgument() = dest and
|
||||
operator.getDeclaringType() = init.getResultType()
|
||||
)
|
||||
or
|
||||
// Workaround for an extractor bug. In this snippet:
|
||||
// ```
|
||||
// struct S { };
|
||||
// void f(S);
|
||||
// f(S());
|
||||
// ```
|
||||
// The expression `S()` is represented as a 0 literal in the database.
|
||||
exists(ConstantValueInstruction constant |
|
||||
constant.getValue() = "0" and
|
||||
creation.asInstruction() = constant and
|
||||
constant.getResultType() = operator.getDeclaringType()
|
||||
)
|
||||
}
|
||||
|
||||
private predicate isFunctorCreationWithConstructor(Node creation, OperatorCall operator) {
|
||||
exists(DataFlowCall constructorCall, IndirectionPosition pos |
|
||||
// A construction of an object with a constructor. In this case we use
|
||||
// the post-update node of the qualifier
|
||||
pos.getArgumentIndex() = -1 and
|
||||
isArgumentNode(creation.(PostUpdateNode).getPreUpdateNode(), constructorCall, pos) and
|
||||
operator.getDeclaringType() =
|
||||
constructorCall.asCallInstruction().(ConstructorCallInstruction).getConstructedType()
|
||||
)
|
||||
}
|
||||
class LambdaCallKind = Unit;
|
||||
|
||||
/** Holds if `creation` is an expression that creates a lambda of kind `kind` for `c`. */
|
||||
predicate lambdaCreation(Node creation, LambdaCallKind kind, DataFlowCallable c) {
|
||||
kind.isFunctionPointer() and
|
||||
creation.asInstruction().(FunctionAddressInstruction).getFunctionSymbol() = c.asSourceCallable()
|
||||
or
|
||||
kind.isFunctor() and
|
||||
exists(OperatorCall operator | operator = c.asSourceCallable() |
|
||||
isFunctorCreationWithoutConstructor(creation, operator)
|
||||
or
|
||||
isFunctorCreationWithConstructor(creation, operator)
|
||||
)
|
||||
creation.asInstruction().(FunctionAddressInstruction).getFunctionSymbol() = c.asSourceCallable() and
|
||||
exists(kind)
|
||||
}
|
||||
|
||||
/** Holds if `call` is a lambda call of kind `kind` where `receiver` is the lambda expression. */
|
||||
predicate lambdaCall(DataFlowCall call, LambdaCallKind kind, Node receiver) {
|
||||
kind.isFunctionPointer() and
|
||||
(
|
||||
call.(SummaryCall).getReceiver() = receiver.(FlowSummaryNode).getSummaryNode()
|
||||
or
|
||||
@@ -1473,15 +1400,8 @@ predicate lambdaCall(DataFlowCall call, LambdaCallKind kind, Node receiver) {
|
||||
// has a result for `getStaticCallTarget`.
|
||||
not exists(call.getStaticCallTarget()) and
|
||||
call.asCallInstruction().getCallTargetOperand() = receiver.asOperand()
|
||||
)
|
||||
or
|
||||
kind.isFunctor() and
|
||||
(
|
||||
call.(SummaryCall).getReceiver() = receiver.(FlowSummaryNode).getSummaryNode()
|
||||
or
|
||||
not exists(call.getStaticCallTarget()) and
|
||||
call.asCallInstruction().getThisArgumentOperand() = receiver.asOperand()
|
||||
)
|
||||
) and
|
||||
exists(kind)
|
||||
}
|
||||
|
||||
/** Extra data-flow steps needed for lambda flow analysis. */
|
||||
@@ -1982,23 +1902,19 @@ module IteratorFlow {
|
||||
|
||||
predicate allowFlowIntoUncertainDef(IteratorSsa::UncertainWriteDefinition def) { any() }
|
||||
|
||||
class GuardValue = Void;
|
||||
|
||||
class Guard extends Void {
|
||||
predicate hasValueBranchEdge(
|
||||
SsaInput::BasicBlock bb1, SsaInput::BasicBlock bb2, GuardValue val
|
||||
) {
|
||||
predicate hasBranchEdge(SsaInput::BasicBlock bb1, SsaInput::BasicBlock bb2, boolean branch) {
|
||||
none()
|
||||
}
|
||||
|
||||
predicate valueControlsBranchEdge(
|
||||
SsaInput::BasicBlock bb1, SsaInput::BasicBlock bb2, GuardValue val
|
||||
predicate controlsBranchEdge(
|
||||
SsaInput::BasicBlock bb1, SsaInput::BasicBlock bb2, boolean branch
|
||||
) {
|
||||
none()
|
||||
}
|
||||
}
|
||||
|
||||
predicate guardDirectlyControlsBlock(Guard guard, SsaInput::BasicBlock bb, GuardValue val) {
|
||||
predicate guardDirectlyControlsBlock(Guard guard, SsaInput::BasicBlock bb, boolean branch) {
|
||||
none()
|
||||
}
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ private import semmle.code.cpp.models.interfaces.DataFlow
|
||||
private import semmle.code.cpp.dataflow.internal.FlowSummaryImpl as FlowSummaryImpl
|
||||
private import DataFlowPrivate
|
||||
private import ModelUtil
|
||||
private import SsaImpl as SsaImpl
|
||||
private import SsaInternals as Ssa
|
||||
private import DataFlowImplCommon as DataFlowImplCommon
|
||||
private import codeql.util.Unit
|
||||
private import Node0ToString
|
||||
@@ -39,39 +39,38 @@ private newtype TIRDataFlowNode =
|
||||
TNode0(Node0Impl node) { DataFlowImplCommon::forceCachingInSameStage() } or
|
||||
TGlobalLikeVariableNode(GlobalLikeVariable var, int indirectionIndex) {
|
||||
indirectionIndex =
|
||||
[getMinIndirectionsForType(var.getUnspecifiedType()) .. SsaImpl::getMaxIndirectionsForType(var.getUnspecifiedType())]
|
||||
[getMinIndirectionsForType(var.getUnspecifiedType()) .. Ssa::getMaxIndirectionsForType(var.getUnspecifiedType())]
|
||||
} or
|
||||
TPostUpdateNodeImpl(Operand operand, int indirectionIndex) {
|
||||
operand = any(FieldAddress fa).getObjectAddressOperand() and
|
||||
indirectionIndex =
|
||||
[0 .. SsaImpl::countIndirectionsForCppType(SsaImpl::getLanguageType(operand))]
|
||||
indirectionIndex = [0 .. Ssa::countIndirectionsForCppType(Ssa::getLanguageType(operand))]
|
||||
or
|
||||
SsaImpl::isModifiableByCall(operand, indirectionIndex)
|
||||
Ssa::isModifiableByCall(operand, indirectionIndex)
|
||||
} or
|
||||
TSsaSynthNode(SsaImpl::SynthNode n) or
|
||||
TSsaSynthNode(Ssa::SynthNode n) or
|
||||
TSsaIteratorNode(IteratorFlow::IteratorFlowNode n) or
|
||||
TRawIndirectOperand0(Node0Impl node, int indirectionIndex) {
|
||||
SsaImpl::hasRawIndirectOperand(node.asOperand(), indirectionIndex)
|
||||
Ssa::hasRawIndirectOperand(node.asOperand(), indirectionIndex)
|
||||
} or
|
||||
TRawIndirectInstruction0(Node0Impl node, int indirectionIndex) {
|
||||
not exists(node.asOperand()) and
|
||||
SsaImpl::hasRawIndirectInstruction(node.asInstruction(), indirectionIndex)
|
||||
Ssa::hasRawIndirectInstruction(node.asInstruction(), indirectionIndex)
|
||||
} or
|
||||
TFinalParameterNode(Parameter p, int indirectionIndex) {
|
||||
exists(SsaImpl::FinalParameterUse use |
|
||||
exists(Ssa::FinalParameterUse use |
|
||||
use.getParameter() = p and
|
||||
use.getIndirectionIndex() = indirectionIndex
|
||||
)
|
||||
} or
|
||||
TFinalGlobalValue(SsaImpl::GlobalUse globalUse) or
|
||||
TInitialGlobalValue(SsaImpl::GlobalDef globalUse) or
|
||||
TFinalGlobalValue(Ssa::GlobalUse globalUse) or
|
||||
TInitialGlobalValue(Ssa::GlobalDef globalUse) or
|
||||
TBodyLessParameterNodeImpl(Parameter p, int indirectionIndex) {
|
||||
// Rule out parameters of catch blocks.
|
||||
not exists(p.getCatchBlock()) and
|
||||
// We subtract one because `getMaxIndirectionsForType` returns the maximum
|
||||
// indirection for a glvalue of a given type, and this doesn't apply to
|
||||
// parameters.
|
||||
indirectionIndex = [0 .. SsaImpl::getMaxIndirectionsForType(p.getUnspecifiedType()) - 1] and
|
||||
indirectionIndex = [0 .. Ssa::getMaxIndirectionsForType(p.getUnspecifiedType()) - 1] and
|
||||
not any(InitializeParameterInstruction init).getParameter() = p
|
||||
} or
|
||||
TFlowSummaryNode(FlowSummaryImpl::Private::SummaryNode sn)
|
||||
@@ -82,7 +81,7 @@ private newtype TIRDataFlowNode =
|
||||
class FieldAddress extends Operand {
|
||||
FieldAddressInstruction fai;
|
||||
|
||||
FieldAddress() { fai = this.getDef() and not SsaImpl::ignoreOperand(this) }
|
||||
FieldAddress() { fai = this.getDef() and not Ssa::ignoreOperand(this) }
|
||||
|
||||
/** Gets the field associated with this instruction. */
|
||||
Field getField() { result = fai.getField() }
|
||||
@@ -127,7 +126,7 @@ predicate conversionFlow(
|
||||
)
|
||||
or
|
||||
additional = true and
|
||||
SsaImpl::isAdditionalConversionFlow(opFrom, instrTo)
|
||||
Ssa::isAdditionalConversionFlow(opFrom, instrTo)
|
||||
)
|
||||
or
|
||||
isPointerArith = true and
|
||||
@@ -184,7 +183,7 @@ class Node extends TIRDataFlowNode {
|
||||
or
|
||||
this.asOperand().getUse() = block.getInstruction(i)
|
||||
or
|
||||
exists(SsaImpl::SynthNode ssaNode |
|
||||
exists(Ssa::SynthNode ssaNode |
|
||||
this.(SsaSynthNode).getSynthNode() = ssaNode and
|
||||
ssaNode.getBasicBlock() = block and
|
||||
ssaNode.getIndex() = i
|
||||
@@ -365,10 +364,10 @@ class Node extends TIRDataFlowNode {
|
||||
* pointed to by `p`.
|
||||
*/
|
||||
Expr asDefinition(boolean uncertain) {
|
||||
exists(StoreInstruction store, SsaImpl::Definition def |
|
||||
exists(StoreInstruction store, Ssa::Definition def |
|
||||
store = this.asInstruction() and
|
||||
result = asDefinitionImpl(store) and
|
||||
SsaImpl::defToNode(this, def, _) and
|
||||
Ssa::defToNode(this, def, _) and
|
||||
if def.isCertain() then uncertain = false else uncertain = true
|
||||
)
|
||||
}
|
||||
@@ -489,23 +488,6 @@ class Node extends TIRDataFlowNode {
|
||||
result = this.(IndirectParameterNode).getParameter()
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if this node represents the `indirectionIndex`'th indirection of
|
||||
* the value of an output parameter `p` just before reaching the end of a function.
|
||||
*/
|
||||
predicate isFinalValueOfParameter(Parameter p, int indirectionIndex) {
|
||||
exists(FinalParameterNode n | n = this |
|
||||
p = n.getParameter() and
|
||||
indirectionIndex = n.getIndirectionIndex()
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if this node represents the value of an output parameter `p`
|
||||
* just before reaching the end of a function.
|
||||
*/
|
||||
predicate isFinalValueOfParameter(Parameter p) { this.isFinalValueOfParameter(p, _) }
|
||||
|
||||
/**
|
||||
* Gets the variable corresponding to this node, if any. This can be used for
|
||||
* modeling flow in and out of global variables.
|
||||
@@ -628,7 +610,7 @@ class OperandNode extends Node, Node0 {
|
||||
* For example, `stripPointers(int*&)` is `int*` and `stripPointers(int*)` is `int`.
|
||||
*/
|
||||
Type stripPointer(Type t) {
|
||||
result = any(SsaImpl::Indirection ind | ind.getType() = t).getBaseType()
|
||||
result = any(Ssa::Indirection ind | ind.getType() = t).getBaseType()
|
||||
or
|
||||
result = t.(PointerToMemberType).getBaseType()
|
||||
or
|
||||
@@ -695,12 +677,12 @@ class PostFieldUpdateNode extends PostUpdateNodeImpl {
|
||||
* in a data flow graph.
|
||||
*/
|
||||
class SsaSynthNode extends Node, TSsaSynthNode {
|
||||
SsaImpl::SynthNode node;
|
||||
Ssa::SynthNode node;
|
||||
|
||||
SsaSynthNode() { this = TSsaSynthNode(node) }
|
||||
|
||||
/** Gets the synthesized SSA node associated with this node. */
|
||||
SsaImpl::SynthNode getSynthNode() { result = node }
|
||||
Ssa::SynthNode getSynthNode() { result = node }
|
||||
|
||||
override DataFlowCallable getEnclosingCallable() {
|
||||
result.asSourceCallable() = this.getFunction()
|
||||
@@ -783,12 +765,12 @@ class SideEffectOperandNode extends Node instanceof IndirectOperand {
|
||||
* from a function body.
|
||||
*/
|
||||
class FinalGlobalValue extends Node, TFinalGlobalValue {
|
||||
SsaImpl::GlobalUse globalUse;
|
||||
Ssa::GlobalUse globalUse;
|
||||
|
||||
FinalGlobalValue() { this = TFinalGlobalValue(globalUse) }
|
||||
|
||||
/** Gets the underlying SSA use. */
|
||||
SsaImpl::GlobalUse getGlobalUse() { result = globalUse }
|
||||
Ssa::GlobalUse getGlobalUse() { result = globalUse }
|
||||
|
||||
override DataFlowCallable getEnclosingCallable() {
|
||||
result.asSourceCallable() = this.getFunction()
|
||||
@@ -815,12 +797,12 @@ class FinalGlobalValue extends Node, TFinalGlobalValue {
|
||||
* a function body.
|
||||
*/
|
||||
class InitialGlobalValue extends Node, TInitialGlobalValue {
|
||||
SsaImpl::GlobalDef globalDef;
|
||||
Ssa::GlobalDef globalDef;
|
||||
|
||||
InitialGlobalValue() { this = TInitialGlobalValue(globalDef) }
|
||||
|
||||
/** Gets the underlying SSA definition. */
|
||||
SsaImpl::GlobalDef getGlobalDef() { result = globalDef }
|
||||
Ssa::GlobalDef getGlobalDef() { result = globalDef }
|
||||
|
||||
override DataFlowCallable getEnclosingCallable() {
|
||||
result.asSourceCallable() = this.getFunction()
|
||||
@@ -1243,7 +1225,7 @@ import RawIndirectNodes
|
||||
/**
|
||||
* INTERNAL: do not use.
|
||||
*
|
||||
* A node representing the value of an output parameter
|
||||
* A node representing the value of an update parameter
|
||||
* just before reaching the end of a function.
|
||||
*/
|
||||
class FinalParameterNode extends Node, TFinalParameterNode {
|
||||
@@ -1289,11 +1271,11 @@ class UninitializedNode extends Node {
|
||||
LocalVariable v;
|
||||
|
||||
UninitializedNode() {
|
||||
exists(SsaImpl::Definition def, SsaImpl::SourceVariable sv |
|
||||
exists(Ssa::Definition def, Ssa::SourceVariable sv |
|
||||
def.getIndirectionIndex() = 0 and
|
||||
def.getValue().asInstruction() instanceof UninitializedInstruction and
|
||||
SsaImpl::defToNode(this, def, sv) and
|
||||
v = sv.getBaseVariable().(SsaImpl::BaseIRVariable).getIRVariable().getAst()
|
||||
Ssa::defToNode(this, def, sv) and
|
||||
v = sv.getBaseVariable().(Ssa::BaseIRVariable).getIRVariable().getAst()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1723,7 +1705,7 @@ private module Cached {
|
||||
cached
|
||||
predicate flowsToBackEdge(Node n) {
|
||||
exists(Node succ, IRBlock bb1, IRBlock bb2 |
|
||||
SsaImpl::ssaFlow(n, succ) and
|
||||
Ssa::ssaFlow(n, succ) and
|
||||
bb1 = n.getBasicBlock() and
|
||||
bb2 = succ.getBasicBlock() and
|
||||
bb1 != bb2 and
|
||||
@@ -1821,7 +1803,7 @@ private module Cached {
|
||||
predicate simpleLocalFlowStep(Node nodeFrom, Node nodeTo, string model) {
|
||||
(
|
||||
// Def-use/Use-use flow
|
||||
SsaImpl::ssaFlow(nodeFrom, nodeTo)
|
||||
Ssa::ssaFlow(nodeFrom, nodeTo)
|
||||
or
|
||||
IteratorFlow::localFlowStep(nodeFrom, nodeTo)
|
||||
or
|
||||
@@ -1834,7 +1816,7 @@ private module Cached {
|
||||
|
|
||||
simpleOperandLocalFlowStep(iFrom, opTo) and
|
||||
// Omit when the instruction node also represents the operand.
|
||||
not iFrom = SsaImpl::getIRRepresentationOfOperand(opTo)
|
||||
not iFrom = Ssa::getIRRepresentationOfOperand(opTo)
|
||||
)
|
||||
or
|
||||
// Indirect operand -> (indirect) instruction flow
|
||||
@@ -1907,7 +1889,7 @@ private module Cached {
|
||||
// We also want a write coming out of an `OutNode` to flow `nodeTo`.
|
||||
// This is different from `reverseFlowInstruction` since `nodeFrom` can never
|
||||
// be an `OutNode` when it's defined by an instruction.
|
||||
SsaImpl::outNodeHasAddressAndIndex(nodeFrom, address, indirectionIndex)
|
||||
Ssa::outNodeHasAddressAndIndex(nodeFrom, address, indirectionIndex)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2100,7 +2082,7 @@ private newtype TContent =
|
||||
TFieldContent(Field f, int indirectionIndex) {
|
||||
// the indirection index for field content starts at 1 (because `TFieldContent` is thought of as
|
||||
// the address of the field, `FieldAddress` in the IR).
|
||||
indirectionIndex = [1 .. SsaImpl::getMaxIndirectionsForType(f.getUnspecifiedType())] and
|
||||
indirectionIndex = [1 .. Ssa::getMaxIndirectionsForType(f.getUnspecifiedType())] and
|
||||
// Reads and writes of union fields are tracked using `UnionContent`.
|
||||
not f.getDeclaringType() instanceof Union
|
||||
} or
|
||||
@@ -2112,9 +2094,7 @@ private newtype TContent =
|
||||
// field can be read by any read of the union's fields. Again, the indirection index
|
||||
// is 1-based (because 0 is considered the address).
|
||||
indirectionIndex =
|
||||
[1 .. max(SsaImpl::getMaxIndirectionsForType(getAFieldWithSize(u, bytes)
|
||||
.getUnspecifiedType())
|
||||
)]
|
||||
[1 .. max(Ssa::getMaxIndirectionsForType(getAFieldWithSize(u, bytes).getUnspecifiedType()))]
|
||||
)
|
||||
} or
|
||||
TElementContent(int indirectionIndex) {
|
||||
@@ -2357,7 +2337,7 @@ module BarrierGuard<guardChecksSig/3 guardChecks> {
|
||||
controls(g, result, edge)
|
||||
)
|
||||
or
|
||||
result = SsaImpl::BarrierGuard<guardChecksNode/3>::getABarrierNode()
|
||||
result = Ssa::BarrierGuard<guardChecksNode/3>::getABarrierNode()
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2456,7 +2436,7 @@ module BarrierGuard<guardChecksSig/3 guardChecks> {
|
||||
)
|
||||
or
|
||||
result =
|
||||
SsaImpl::BarrierGuardWithIntParam<guardChecksIndirectNode/4>::getABarrierNode(indirectionIndex)
|
||||
Ssa::BarrierGuardWithIntParam<guardChecksIndirectNode/4>::getABarrierNode(indirectionIndex)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2493,7 +2473,7 @@ module InstructionBarrierGuard<instructionGuardChecksSig/3 instructionGuardCheck
|
||||
controls(g, result, edge)
|
||||
)
|
||||
or
|
||||
result = SsaImpl::BarrierGuard<guardChecksNode/3>::getABarrierNode()
|
||||
result = Ssa::BarrierGuard<guardChecksNode/3>::getABarrierNode()
|
||||
}
|
||||
|
||||
bindingset[value, n]
|
||||
@@ -2523,7 +2503,7 @@ module InstructionBarrierGuard<instructionGuardChecksSig/3 instructionGuardCheck
|
||||
)
|
||||
or
|
||||
result =
|
||||
SsaImpl::BarrierGuardWithIntParam<guardChecksIndirectNode/4>::getABarrierNode(indirectionIndex)
|
||||
Ssa::BarrierGuardWithIntParam<guardChecksIndirectNode/4>::getABarrierNode(indirectionIndex)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2579,16 +2559,3 @@ Function getARuntimeTarget(Call call) {
|
||||
result = DataFlowImplCommon::viableCallableLambda(dfCall, _).asSourceCallable()
|
||||
)
|
||||
}
|
||||
|
||||
/** A module that provides static single assignment (SSA) information. */
|
||||
module Ssa {
|
||||
class Definition = SsaImpl::Definition;
|
||||
|
||||
class ExplicitDefinition = SsaImpl::ExplicitDefinition;
|
||||
|
||||
class DirectExplicitDefinition = SsaImpl::DirectExplicitDefinition;
|
||||
|
||||
class IndirectExplicitDefinition = SsaImpl::IndirectExplicitDefinition;
|
||||
|
||||
class PhiNode = SsaImpl::PhiNode;
|
||||
}
|
||||
|
||||
@@ -151,7 +151,7 @@ private module Cached {
|
||||
)
|
||||
or
|
||||
// Similarly for `i++` and `++i` we pretend that the generated
|
||||
// `StoreInstruction` contains the result of the expression even though
|
||||
// `StoreInstruction` is contains the result of the expression even though
|
||||
// this isn't totally aligned with the C/C++ standard.
|
||||
exists(TranslatedCrementOperation tco |
|
||||
store = tco.getInstruction(CrementStoreTag()) and
|
||||
|
||||
@@ -4,15 +4,15 @@
|
||||
*/
|
||||
|
||||
private import semmle.code.cpp.ir.IR
|
||||
private import semmle.code.cpp.models.interfaces.FunctionInputsAndOutputs
|
||||
private import semmle.code.cpp.ir.dataflow.DataFlow
|
||||
private import DataFlowUtil
|
||||
private import DataFlowPrivate
|
||||
private import SsaImpl as Ssa
|
||||
private import SsaInternals as Ssa
|
||||
|
||||
/**
|
||||
* Gets the instruction that goes into `input` for `call`.
|
||||
*/
|
||||
Node callInput(CallInstruction call, FunctionInput input) {
|
||||
DataFlow::Node callInput(CallInstruction call, FunctionInput input) {
|
||||
// An argument or qualifier
|
||||
exists(int index |
|
||||
result.asOperand() = call.getArgumentOperand(index) and
|
||||
@@ -62,8 +62,8 @@ Node callOutput(CallInstruction call, FunctionOutput output) {
|
||||
result = callOutputWithIndirectionIndex(call, output, _)
|
||||
}
|
||||
|
||||
Node callInput(CallInstruction call, FunctionInput input, int d) {
|
||||
exists(Node n | n = callInput(call, input) and d > 0 |
|
||||
DataFlow::Node callInput(CallInstruction call, FunctionInput input, int d) {
|
||||
exists(DataFlow::Node n | n = callInput(call, input) and d > 0 |
|
||||
// An argument or qualifier
|
||||
hasOperandAndIndex(result, n.asOperand(), d)
|
||||
or
|
||||
@@ -85,7 +85,7 @@ private IndirectReturnOutNode getIndirectReturnOutNode(CallInstruction call, int
|
||||
*/
|
||||
bindingset[d]
|
||||
Node callOutput(CallInstruction call, FunctionOutput output, int d) {
|
||||
exists(Node n, int indirectionIndex |
|
||||
exists(DataFlow::Node n, int indirectionIndex |
|
||||
n = callOutputWithIndirectionIndex(call, output, indirectionIndex) and d > 0
|
||||
|
|
||||
// The return value
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
private import cpp
|
||||
private import semmle.code.cpp.ir.IR
|
||||
private import SsaImpl as Ssa
|
||||
private import SsaInternals as Ssa
|
||||
|
||||
/**
|
||||
* A property provider that hides all instructions and operands that are not relevant for IR dataflow.
|
||||
|
||||
@@ -2,7 +2,7 @@ private import cpp
|
||||
private import semmle.code.cpp.ir.IR
|
||||
private import semmle.code.cpp.ir.dataflow.internal.DataFlowUtil
|
||||
private import semmle.code.cpp.ir.dataflow.internal.DataFlowPrivate
|
||||
private import SsaImpl as Ssa
|
||||
private import SsaInternals as Ssa
|
||||
private import PrintIRUtilities
|
||||
|
||||
/**
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
1160
cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaInternals.qll
Normal file
1160
cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaInternals.qll
Normal file
File diff suppressed because it is too large
Load Diff
@@ -5,7 +5,7 @@ private import semmle.code.cpp.models.interfaces.DataFlow
|
||||
private import semmle.code.cpp.models.interfaces.SideEffect
|
||||
private import DataFlowUtil
|
||||
private import DataFlowPrivate
|
||||
private import SsaImpl as Ssa
|
||||
private import SsaInternals as Ssa
|
||||
private import semmle.code.cpp.dataflow.internal.FlowSummaryImpl as FlowSummaryImpl
|
||||
private import semmle.code.cpp.ir.dataflow.FlowSteps
|
||||
|
||||
|
||||
@@ -42,7 +42,6 @@ private newtype TOpcode =
|
||||
TCompareGT() or
|
||||
TCompareLE() or
|
||||
TCompareGE() or
|
||||
TSpaceship() or
|
||||
TPointerAdd() or
|
||||
TPointerSub() or
|
||||
TPointerDiff() or
|
||||
@@ -93,9 +92,7 @@ private newtype TOpcode =
|
||||
TUninitializedGroup() or
|
||||
TInlineAsm() or
|
||||
TUnreached() or
|
||||
TNewObj() or
|
||||
TTypeidExpr() or
|
||||
TTypeidType()
|
||||
TNewObj()
|
||||
|
||||
/**
|
||||
* An opcode that specifies the operation performed by an `Instruction`.
|
||||
@@ -766,15 +763,6 @@ module Opcode {
|
||||
final override string toString() { result = "CompareGE" }
|
||||
}
|
||||
|
||||
/**
|
||||
* The `Opcode` for a `SpaceshipInstruction`.
|
||||
*
|
||||
* See the `SpaceshipInstruction` documentation for more details.
|
||||
*/
|
||||
class Spaceship extends BinaryOpcode, TSpaceship {
|
||||
final override string toString() { result = "Spaceship" }
|
||||
}
|
||||
|
||||
/**
|
||||
* The `Opcode` for a `PointerAddInstruction`.
|
||||
*
|
||||
@@ -1293,29 +1281,4 @@ module Opcode {
|
||||
class NewObj extends Opcode, TNewObj {
|
||||
final override string toString() { result = "NewObj" }
|
||||
}
|
||||
|
||||
/**
|
||||
* The `Opcode` for a `TypeidInstruction`.
|
||||
*
|
||||
* See the `TypeidInstruction` documentation for more details.
|
||||
*/
|
||||
abstract class Typeid extends Opcode { }
|
||||
|
||||
/**
|
||||
* The `Opcode` for a `TypeidExprInstruction`.
|
||||
*
|
||||
* See the `TypeidExprInstruction` documentation for more details.
|
||||
*/
|
||||
class TypeidExpr extends Typeid, UnaryOpcode, TTypeidExpr {
|
||||
final override string toString() { result = "TypeidExpr" }
|
||||
}
|
||||
|
||||
/**
|
||||
* The `Opcode` for a `TypeidTypeInstruction`.
|
||||
*
|
||||
* See the `TypeidTypeInstruction` documentation for more details.
|
||||
*/
|
||||
class TypeidType extends Typeid, TTypeidType {
|
||||
final override string toString() { result = "TypeidType" }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -725,20 +725,6 @@ class UninitializedInstruction extends VariableInstruction {
|
||||
* Gets the variable that is uninitialized.
|
||||
*/
|
||||
final Language::Variable getLocalVariable() { result = var.(IRUserVariable).getVariable() }
|
||||
|
||||
/**
|
||||
* Gets the operand that provides the address of the location to which the
|
||||
* uninitialized value will be stored.
|
||||
*/
|
||||
final AddressOperand getDestinationAddressOperand() { result = this.getAnOperand() }
|
||||
|
||||
/**
|
||||
* Gets the instruction whose result provides the address of the location to
|
||||
* which the value will be stored, if an exact definition is available.
|
||||
*/
|
||||
final Instruction getDestinationAddress() {
|
||||
result = this.getDestinationAddressOperand().getDef()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1604,13 +1590,6 @@ class CompareGEInstruction extends RelationalInstruction {
|
||||
override predicate isStrict() { none() }
|
||||
}
|
||||
|
||||
/**
|
||||
* An instruction that represents a three-way comparison operator.
|
||||
*/
|
||||
class SpaceshipInstruction extends BinaryInstruction {
|
||||
SpaceshipInstruction() { this.getOpcode() instanceof Opcode::Spaceship }
|
||||
}
|
||||
|
||||
/**
|
||||
* An instruction that branches to one of multiple successor instructions based on the value of an
|
||||
* integer operand.
|
||||
@@ -2300,26 +2279,3 @@ class NextVarArgInstruction extends UnaryInstruction {
|
||||
class NewObjInstruction extends Instruction {
|
||||
NewObjInstruction() { this.getOpcode() instanceof Opcode::NewObj }
|
||||
}
|
||||
|
||||
/**
|
||||
* An instruction that returns the type info for its operand.
|
||||
*/
|
||||
class TypeidInstruction extends Instruction {
|
||||
TypeidInstruction() { this.getOpcode() instanceof Opcode::Typeid }
|
||||
}
|
||||
|
||||
/**
|
||||
* An instruction that returns the type info for its operand, where the
|
||||
* operand occurs as an expression in the AST.
|
||||
*/
|
||||
class TypeidExprInstruction extends TypeidInstruction, UnaryInstruction {
|
||||
TypeidExprInstruction() { this.getOpcode() instanceof Opcode::TypeidExpr }
|
||||
}
|
||||
|
||||
/**
|
||||
* An instruction that returns the type info for its operand, where the
|
||||
* operand occurs as a type in the AST.
|
||||
*/
|
||||
class TypeidTypeInstruction extends TypeidInstruction {
|
||||
TypeidTypeInstruction() { this.getOpcode() instanceof Opcode::TypeidType }
|
||||
}
|
||||
|
||||
@@ -725,20 +725,6 @@ class UninitializedInstruction extends VariableInstruction {
|
||||
* Gets the variable that is uninitialized.
|
||||
*/
|
||||
final Language::Variable getLocalVariable() { result = var.(IRUserVariable).getVariable() }
|
||||
|
||||
/**
|
||||
* Gets the operand that provides the address of the location to which the
|
||||
* uninitialized value will be stored.
|
||||
*/
|
||||
final AddressOperand getDestinationAddressOperand() { result = this.getAnOperand() }
|
||||
|
||||
/**
|
||||
* Gets the instruction whose result provides the address of the location to
|
||||
* which the value will be stored, if an exact definition is available.
|
||||
*/
|
||||
final Instruction getDestinationAddress() {
|
||||
result = this.getDestinationAddressOperand().getDef()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1604,13 +1590,6 @@ class CompareGEInstruction extends RelationalInstruction {
|
||||
override predicate isStrict() { none() }
|
||||
}
|
||||
|
||||
/**
|
||||
* An instruction that represents a three-way comparison operator.
|
||||
*/
|
||||
class SpaceshipInstruction extends BinaryInstruction {
|
||||
SpaceshipInstruction() { this.getOpcode() instanceof Opcode::Spaceship }
|
||||
}
|
||||
|
||||
/**
|
||||
* An instruction that branches to one of multiple successor instructions based on the value of an
|
||||
* integer operand.
|
||||
@@ -2300,26 +2279,3 @@ class NextVarArgInstruction extends UnaryInstruction {
|
||||
class NewObjInstruction extends Instruction {
|
||||
NewObjInstruction() { this.getOpcode() instanceof Opcode::NewObj }
|
||||
}
|
||||
|
||||
/**
|
||||
* An instruction that returns the type info for its operand.
|
||||
*/
|
||||
class TypeidInstruction extends Instruction {
|
||||
TypeidInstruction() { this.getOpcode() instanceof Opcode::Typeid }
|
||||
}
|
||||
|
||||
/**
|
||||
* An instruction that returns the type info for its operand, where the
|
||||
* operand occurs as an expression in the AST.
|
||||
*/
|
||||
class TypeidExprInstruction extends TypeidInstruction, UnaryInstruction {
|
||||
TypeidExprInstruction() { this.getOpcode() instanceof Opcode::TypeidExpr }
|
||||
}
|
||||
|
||||
/**
|
||||
* An instruction that returns the type info for its operand, where the
|
||||
* operand occurs as a type in the AST.
|
||||
*/
|
||||
class TypeidTypeInstruction extends TypeidInstruction {
|
||||
TypeidTypeInstruction() { this.getOpcode() instanceof Opcode::TypeidType }
|
||||
}
|
||||
|
||||
@@ -1808,11 +1808,6 @@ private Opcode comparisonOpcode(ComparisonOperation expr) {
|
||||
expr instanceof GEExpr and result instanceof Opcode::CompareGE
|
||||
}
|
||||
|
||||
private Opcode spaceShipOpcode(SpaceshipExpr expr) {
|
||||
exists(expr) and
|
||||
result instanceof Opcode::Spaceship
|
||||
}
|
||||
|
||||
/**
|
||||
* IR translation of a simple binary operation.
|
||||
*/
|
||||
@@ -1872,8 +1867,7 @@ class TranslatedBinaryOperation extends TranslatedSingleInstructionExpr {
|
||||
override Opcode getOpcode() {
|
||||
result = binaryArithmeticOpcode(expr) or
|
||||
result = binaryBitwiseOpcode(expr) or
|
||||
result = comparisonOpcode(expr) or
|
||||
result = spaceShipOpcode(expr)
|
||||
result = comparisonOpcode(expr)
|
||||
}
|
||||
|
||||
override Type getExprType() {
|
||||
@@ -4152,8 +4146,7 @@ predicate exprNeedsCopyIfNotLoaded(Expr expr) {
|
||||
private predicate exprImmediatelyDiscarded(Expr expr) {
|
||||
exists(ExprStmt s |
|
||||
s = expr.getParent() and
|
||||
not exists(StmtExpr se | s = se.getStmt().(BlockStmt).getLastStmt()) and
|
||||
not exists(expr.getConversion())
|
||||
not exists(StmtExpr se | s = se.getStmt().(BlockStmt).getLastStmt())
|
||||
)
|
||||
or
|
||||
exists(CommaExpr c | c.getLeftOperand() = expr)
|
||||
@@ -4191,52 +4184,3 @@ class TranslatedAssumeExpr extends TranslatedSingleInstructionExpr {
|
||||
none()
|
||||
}
|
||||
}
|
||||
|
||||
class TranslatedTypeidExpr extends TranslatedSingleInstructionExpr {
|
||||
override TypeidOperator expr;
|
||||
|
||||
final override Opcode getOpcode() {
|
||||
exists(this.getOperand()) and
|
||||
result instanceof Opcode::TypeidExpr
|
||||
or
|
||||
not exists(this.getOperand()) and
|
||||
result instanceof Opcode::TypeidType
|
||||
}
|
||||
|
||||
final override Instruction getFirstInstruction(EdgeKind kind) {
|
||||
result = this.getOperand().getFirstInstruction(kind)
|
||||
or
|
||||
not exists(this.getOperand()) and
|
||||
result = this.getInstruction(OnlyInstructionTag()) and
|
||||
kind instanceof GotoEdge
|
||||
}
|
||||
|
||||
override Instruction getALastInstructionInternal() {
|
||||
result = this.getInstruction(OnlyInstructionTag())
|
||||
}
|
||||
|
||||
final override TranslatedElement getChildInternal(int id) {
|
||||
id = 0 and result = this.getOperand()
|
||||
}
|
||||
|
||||
final override Instruction getInstructionSuccessorInternal(InstructionTag tag, EdgeKind kind) {
|
||||
tag = OnlyInstructionTag() and
|
||||
result = this.getParent().getChildSuccessor(this, kind)
|
||||
}
|
||||
|
||||
final override Instruction getChildSuccessorInternal(TranslatedElement child, EdgeKind kind) {
|
||||
child = this.getOperand() and
|
||||
result = this.getInstruction(OnlyInstructionTag()) and
|
||||
kind instanceof GotoEdge
|
||||
}
|
||||
|
||||
final override Instruction getInstructionRegisterOperand(InstructionTag tag, OperandTag operandTag) {
|
||||
tag = OnlyInstructionTag() and
|
||||
result = this.getOperand().getResult() and
|
||||
operandTag instanceof UnaryOperandTag
|
||||
}
|
||||
|
||||
private TranslatedExpr getOperand() {
|
||||
result = getTranslatedExpr(expr.getExpr().getFullyConverted())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -725,20 +725,6 @@ class UninitializedInstruction extends VariableInstruction {
|
||||
* Gets the variable that is uninitialized.
|
||||
*/
|
||||
final Language::Variable getLocalVariable() { result = var.(IRUserVariable).getVariable() }
|
||||
|
||||
/**
|
||||
* Gets the operand that provides the address of the location to which the
|
||||
* uninitialized value will be stored.
|
||||
*/
|
||||
final AddressOperand getDestinationAddressOperand() { result = this.getAnOperand() }
|
||||
|
||||
/**
|
||||
* Gets the instruction whose result provides the address of the location to
|
||||
* which the value will be stored, if an exact definition is available.
|
||||
*/
|
||||
final Instruction getDestinationAddress() {
|
||||
result = this.getDestinationAddressOperand().getDef()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1604,13 +1590,6 @@ class CompareGEInstruction extends RelationalInstruction {
|
||||
override predicate isStrict() { none() }
|
||||
}
|
||||
|
||||
/**
|
||||
* An instruction that represents a three-way comparison operator.
|
||||
*/
|
||||
class SpaceshipInstruction extends BinaryInstruction {
|
||||
SpaceshipInstruction() { this.getOpcode() instanceof Opcode::Spaceship }
|
||||
}
|
||||
|
||||
/**
|
||||
* An instruction that branches to one of multiple successor instructions based on the value of an
|
||||
* integer operand.
|
||||
@@ -2300,26 +2279,3 @@ class NextVarArgInstruction extends UnaryInstruction {
|
||||
class NewObjInstruction extends Instruction {
|
||||
NewObjInstruction() { this.getOpcode() instanceof Opcode::NewObj }
|
||||
}
|
||||
|
||||
/**
|
||||
* An instruction that returns the type info for its operand.
|
||||
*/
|
||||
class TypeidInstruction extends Instruction {
|
||||
TypeidInstruction() { this.getOpcode() instanceof Opcode::Typeid }
|
||||
}
|
||||
|
||||
/**
|
||||
* An instruction that returns the type info for its operand, where the
|
||||
* operand occurs as an expression in the AST.
|
||||
*/
|
||||
class TypeidExprInstruction extends TypeidInstruction, UnaryInstruction {
|
||||
TypeidExprInstruction() { this.getOpcode() instanceof Opcode::TypeidExpr }
|
||||
}
|
||||
|
||||
/**
|
||||
* An instruction that returns the type info for its operand, where the
|
||||
* operand occurs as a type in the AST.
|
||||
*/
|
||||
class TypeidTypeInstruction extends TypeidInstruction {
|
||||
TypeidTypeInstruction() { this.getOpcode() instanceof Opcode::TypeidType }
|
||||
}
|
||||
|
||||
@@ -26,14 +26,6 @@ private class IteratorTraits extends Class {
|
||||
}
|
||||
|
||||
Type getIteratorType() { result = this.getTemplateArgument(0) }
|
||||
|
||||
Type getValueType() {
|
||||
exists(TypedefType t |
|
||||
this.getAMember() = t and
|
||||
t.getName() = "value_type" and
|
||||
result = t.getUnderlyingType()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -42,13 +34,16 @@ private class IteratorTraits extends Class {
|
||||
*/
|
||||
private class IteratorByTraits extends Iterator {
|
||||
IteratorTraits trait;
|
||||
IteratorByTraits() {
|
||||
trait.getIteratorType() = this and
|
||||
not trait.getValueType() = this
|
||||
|
||||
IteratorByTraits() { trait.getIteratorType() = this }
|
||||
|
||||
override Type getValueType() {
|
||||
exists(TypedefType t |
|
||||
trait.getAMember() = t and
|
||||
t.getName() = "value_type" and
|
||||
result = t.getUnderlyingType()
|
||||
)
|
||||
}
|
||||
|
||||
override Type getValueType() { result = trait.getValueType() }
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
|
||||
import cpp
|
||||
import PrintfLike
|
||||
private import semmle.code.cpp.ir.dataflow.ResolveCall
|
||||
|
||||
bindingset[index]
|
||||
private string toCause(Function func, int index) {
|
||||
@@ -36,9 +37,9 @@ private predicate wrapperFunctionStep(
|
||||
not target.isVirtual() and
|
||||
not source.isVirtual() and
|
||||
source.hasDefinition() and
|
||||
exists(FunctionCall call, Expr arg, Parameter sourceParam |
|
||||
exists(Call call, Expr arg, Parameter sourceParam |
|
||||
// there is a 'call' to 'target' with argument 'arg' at index 'targetParamIndex'
|
||||
target = call.getTarget() and
|
||||
target = resolveCall(call) and
|
||||
arg = call.getArgument(targetParamIndex) and
|
||||
// 'call' is enclosed in 'source'
|
||||
source = call.getEnclosingFunction() and
|
||||
@@ -153,8 +154,8 @@ abstract class FunctionWithWrappers extends Function {
|
||||
* Whether 'arg' is an argument in a call to an outermost wrapper function of 'this' function.
|
||||
*/
|
||||
predicate outermostWrapperFunctionCall(Expr arg, string callChain) {
|
||||
exists(Function targetFunc, FunctionCall call, int argIndex |
|
||||
targetFunc = call.getTarget() and
|
||||
exists(Function targetFunc, Call call, int argIndex |
|
||||
targetFunc = resolveCall(call) and
|
||||
this.wrapperFunction(targetFunc, argIndex, callChain) and
|
||||
(
|
||||
exists(Function sourceFunc | sourceFunc = call.getEnclosingFunction() |
|
||||
|
||||
@@ -53,12 +53,44 @@
|
||||
|
||||
private import cpp
|
||||
private import semmle.code.cpp.ir.dataflow.internal.ProductFlow
|
||||
private import semmle.code.cpp.security.ProductFlowUtils.ProductFlowUtils
|
||||
private import semmle.code.cpp.ir.ValueNumbering
|
||||
private import semmle.code.cpp.controlflow.IRGuards
|
||||
private import codeql.util.Unit
|
||||
private import semmle.code.cpp.rangeanalysis.new.RangeAnalysisUtil
|
||||
|
||||
private VariableAccess getAVariableAccess(Expr e) { e.getAChild*() = result }
|
||||
|
||||
/**
|
||||
* Gets a (sub)expression that may be the result of evaluating `size`.
|
||||
*
|
||||
* For example, `getASizeCandidate(a ? b : c)` gives `a ? b : c`, `b` and `c`.
|
||||
*/
|
||||
bindingset[size]
|
||||
pragma[inline_late]
|
||||
private Expr getASizeCandidate(Expr size) {
|
||||
result = size
|
||||
or
|
||||
result = [size.(ConditionalExpr).getThen(), size.(ConditionalExpr).getElse()]
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if the `(n, state)` pair represents the source of flow for the size
|
||||
* expression associated with `alloc`.
|
||||
*/
|
||||
predicate hasSize(HeuristicAllocationExpr alloc, DataFlow::Node n, int state) {
|
||||
exists(VariableAccess va, Expr size, int delta, Expr s |
|
||||
size = alloc.getSizeExpr() and
|
||||
s = getASizeCandidate(size) and
|
||||
// Get the unique variable in a size expression like `x` in `malloc(x + 1)`.
|
||||
va = unique( | | getAVariableAccess(s)) and
|
||||
// Compute `delta` as the constant difference between `x` and `x + 1`.
|
||||
bounded1(any(Instruction instr | instr.getUnconvertedResultExpression() = s),
|
||||
any(LoadInstruction load | load.getUnconvertedResultExpression() = va), delta) and
|
||||
n.asExpr() = va and
|
||||
state = delta
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the virtual dispatch branching limit when calculating field flow while searching
|
||||
* for flow from an allocation to the construction of an out-of-bounds pointer.
|
||||
@@ -68,6 +100,125 @@ private import semmle.code.cpp.rangeanalysis.new.RangeAnalysisUtil
|
||||
*/
|
||||
int allocationToInvalidPointerFieldFlowBranchLimit() { result = 0 }
|
||||
|
||||
/**
|
||||
* A module that encapsulates a barrier guard to remove false positives from flow like:
|
||||
* ```cpp
|
||||
* char *p = new char[size];
|
||||
* // ...
|
||||
* unsigned n = size;
|
||||
* // ...
|
||||
* if(n < size) {
|
||||
* use(*p[n]);
|
||||
* }
|
||||
* ```
|
||||
* In this case, the sink pair identified by the product flow library (without any additional barriers)
|
||||
* would be `(p, n)` (where `n` is the `n` in `p[n]`), because there exists a pointer-arithmetic
|
||||
* instruction `pai = a + b` such that:
|
||||
* 1. the allocation flows to `a`, and
|
||||
* 2. `b <= n` where `n` is the `n` in `p[n]`
|
||||
* but because there's a strict comparison that compares `n` against the size of the allocation this
|
||||
* snippet is fine.
|
||||
*/
|
||||
private module SizeBarrier {
|
||||
private module SizeBarrierConfig implements DataFlow::ConfigSig {
|
||||
predicate isSource(DataFlow::Node source) {
|
||||
// The sources is the same as in the sources for the second
|
||||
// projection in the `AllocToInvalidPointerConfig` module.
|
||||
hasSize(_, source, _) and
|
||||
InterestingPointerAddInstruction::isInterestingSize(source)
|
||||
}
|
||||
|
||||
int fieldFlowBranchLimit() { result = allocationToInvalidPointerFieldFlowBranchLimit() }
|
||||
|
||||
/**
|
||||
* Holds if `small <= large + k` holds if `g` evaluates to `testIsTrue`.
|
||||
*/
|
||||
additional predicate isSink(
|
||||
DataFlow::Node small, DataFlow::Node large, IRGuardCondition g, int k, boolean testIsTrue
|
||||
) {
|
||||
// The sink is any "large" side of a relational comparison. i.e., the `large` expression
|
||||
// in a guard such as `small <= large + k`.
|
||||
g.comparesLt(small.asOperand(), large.asOperand(), k + 1, true, testIsTrue)
|
||||
}
|
||||
|
||||
predicate isSink(DataFlow::Node sink) { isSink(_, sink, _, _, _) }
|
||||
}
|
||||
|
||||
module SizeBarrierFlow = DataFlow::Global<SizeBarrierConfig>;
|
||||
|
||||
private int getASizeAddend(DataFlow::Node node) {
|
||||
exists(DataFlow::Node source |
|
||||
SizeBarrierFlow::flow(source, node) and
|
||||
hasSize(_, source, result)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `small <= large + k` holds if `g` evaluates to `edge`.
|
||||
*/
|
||||
private predicate operandGuardChecks(
|
||||
IRGuardCondition g, Operand small, DataFlow::Node large, int k, boolean edge
|
||||
) {
|
||||
SizeBarrierFlow::flowTo(large) and
|
||||
SizeBarrierConfig::isSink(DataFlow::operandNode(small), large, g, k, edge)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an instruction `instr` that is guarded by a check such as `instr <= small + delta` where
|
||||
* `small <= _ + k` and `small` is the "small side" of of a relational comparison that checks
|
||||
* whether `small <= size` where `size` is the size of an allocation.
|
||||
*/
|
||||
Instruction getABarrierInstruction0(int delta, int k) {
|
||||
exists(
|
||||
IRGuardCondition g, ValueNumber value, Operand small, boolean edge, DataFlow::Node large
|
||||
|
|
||||
// We know:
|
||||
// 1. result <= value + delta (by `bounded`)
|
||||
// 2. value <= large + k (by `operandGuardChecks`).
|
||||
// So:
|
||||
// result <= value + delta (by 1.)
|
||||
// <= large + k + delta (by 2.)
|
||||
small = value.getAUse() and
|
||||
operandGuardChecks(pragma[only_bind_into](g), pragma[only_bind_into](small), large,
|
||||
pragma[only_bind_into](k), pragma[only_bind_into](edge)) and
|
||||
bounded(result, value.getAnInstruction(), delta) and
|
||||
g.controls(result.getBlock(), edge) and
|
||||
k < getASizeAddend(large)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an instruction that is guarded by a guard condition which ensures that
|
||||
* the value of the instruction is upper-bounded by size of some allocation.
|
||||
*/
|
||||
bindingset[state]
|
||||
pragma[inline_late]
|
||||
Instruction getABarrierInstruction(int state) {
|
||||
exists(int delta, int k |
|
||||
state > k + delta and
|
||||
// result <= "size of allocation" + delta + k
|
||||
// < "size of allocation" + state
|
||||
result = getABarrierInstruction0(delta, k)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a `DataFlow::Node` that is guarded by a guard condition which ensures that
|
||||
* the value of the node is upper-bounded by size of some allocation.
|
||||
*/
|
||||
DataFlow::Node getABarrierNode(int state) {
|
||||
exists(DataFlow::Node source, int delta, int k |
|
||||
SizeBarrierFlow::flow(source, result) and
|
||||
hasSize(_, source, state) and
|
||||
result.asInstruction() = SizeBarrier::getABarrierInstruction0(delta, k) and
|
||||
state > k + delta
|
||||
// so now we have:
|
||||
// result <= "size of allocation" + delta + k
|
||||
// < "size of allocation" + state
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private module InterestingPointerAddInstruction {
|
||||
private module PointerAddInstructionConfig implements DataFlow::ConfigSig {
|
||||
predicate isSource(DataFlow::Node source) {
|
||||
@@ -76,7 +227,7 @@ private module InterestingPointerAddInstruction {
|
||||
hasSize(source.asExpr(), _, _)
|
||||
}
|
||||
|
||||
predicate fieldFlowBranchLimit = allocationToInvalidPointerFieldFlowBranchLimit/0;
|
||||
int fieldFlowBranchLimit() { result = allocationToInvalidPointerFieldFlowBranchLimit() }
|
||||
|
||||
predicate isSink(DataFlow::Node sink) {
|
||||
sink.asInstruction() = any(PointerAddInstruction pai).getLeft()
|
||||
@@ -112,17 +263,6 @@ private module InterestingPointerAddInstruction {
|
||||
}
|
||||
}
|
||||
|
||||
private module SizeBarrierInput implements SizeBarrierInputSig {
|
||||
predicate fieldFlowBranchLimit = allocationToInvalidPointerFieldFlowBranchLimit/0;
|
||||
|
||||
predicate isSource(DataFlow::Node source) {
|
||||
// The sources is the same as in the sources for the second
|
||||
// projection in the `AllocToInvalidPointerConfig` module.
|
||||
hasSize(_, source, _) and
|
||||
InterestingPointerAddInstruction::isInterestingSize(source)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A product-flow configuration for flow from an `(allocation, size)` pair to a
|
||||
* pointer-arithmetic operation `pai` such that `pai <= allocation + size`.
|
||||
@@ -161,7 +301,7 @@ private module Config implements ProductFlow::StateConfigSig {
|
||||
private import semmle.code.cpp.ir.dataflow.internal.DataFlowPrivate
|
||||
|
||||
predicate isBarrier2(DataFlow::Node node, FlowState2 state) {
|
||||
node = SizeBarrier<SizeBarrierInput>::getABarrierNode(state)
|
||||
node = SizeBarrier::getABarrierNode(state)
|
||||
}
|
||||
|
||||
predicate isBarrier2(DataFlow::Node node) {
|
||||
@@ -217,8 +357,8 @@ private predicate pointerAddInstructionHasBounds0(
|
||||
sizeInstr = sizeSink.asInstruction() and
|
||||
// pai.getRight() <= sizeSink + delta
|
||||
bounded1(right, sizeInstr, delta) and
|
||||
not right = SizeBarrier<SizeBarrierInput>::getABarrierInstruction(delta) and
|
||||
not sizeInstr = SizeBarrier<SizeBarrierInput>::getABarrierInstruction(delta)
|
||||
not right = SizeBarrier::getABarrierInstruction(delta) and
|
||||
not sizeInstr = SizeBarrier::getABarrierInstruction(delta)
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -1,167 +0,0 @@
|
||||
/**
|
||||
* This file provides the `SizeBarrier` module which provides barriers for
|
||||
* both the `cpp/invalid-pointer-deref` query and the `cpp/overrun-write`
|
||||
* query.
|
||||
*/
|
||||
|
||||
private import cpp
|
||||
private import semmle.code.cpp.dataflow.new.DataFlow
|
||||
private import semmle.code.cpp.ir.ValueNumbering
|
||||
private import semmle.code.cpp.controlflow.IRGuards
|
||||
private import semmle.code.cpp.rangeanalysis.new.RangeAnalysisUtil
|
||||
|
||||
private VariableAccess getAVariableAccess(Expr e) { e.getAChild*() = result }
|
||||
|
||||
/**
|
||||
* Gets a (sub)expression that may be the result of evaluating `size`.
|
||||
*
|
||||
* For example, `getASizeCandidate(a ? b : c)` gives `a ? b : c`, `b` and `c`.
|
||||
*/
|
||||
bindingset[size]
|
||||
pragma[inline_late]
|
||||
private Expr getASizeCandidate(Expr size) {
|
||||
result = size
|
||||
or
|
||||
result = [size.(ConditionalExpr).getThen(), size.(ConditionalExpr).getElse()]
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if the `(n, state)` pair represents the source of flow for the size
|
||||
* expression associated with `alloc`.
|
||||
*/
|
||||
predicate hasSize(HeuristicAllocationExpr alloc, DataFlow::Node n, int state) {
|
||||
exists(VariableAccess va, Expr size, int delta, Expr s |
|
||||
size = alloc.getSizeExpr() and
|
||||
s = getASizeCandidate(size) and
|
||||
// Get the unique variable in a size expression like `x` in `malloc(x + 1)`.
|
||||
va = unique( | | getAVariableAccess(s)) and
|
||||
// Compute `delta` as the constant difference between `x` and `x + 1`.
|
||||
bounded1(any(Instruction instr | instr.getUnconvertedResultExpression() = s),
|
||||
any(LoadInstruction load | load.getUnconvertedResultExpression() = va), delta) and
|
||||
n.asExpr() = va and
|
||||
state = delta
|
||||
)
|
||||
}
|
||||
|
||||
/** Provides the input specification of the `SizeBarrier` module. */
|
||||
signature module SizeBarrierInputSig {
|
||||
/** Gets the virtual dispatch branching limit when calculating field flow. */
|
||||
int fieldFlowBranchLimit();
|
||||
|
||||
/** Holds if `source` is a relevant data flow source. */
|
||||
predicate isSource(DataFlow::Node source);
|
||||
}
|
||||
|
||||
/**
|
||||
* A module that encapsulates a barrier guard to remove false positives from flow like:
|
||||
* ```cpp
|
||||
* char *p = new char[size];
|
||||
* // ...
|
||||
* unsigned n = size;
|
||||
* // ...
|
||||
* if(n < size) {
|
||||
* use(*p[n]);
|
||||
* }
|
||||
* ```
|
||||
* In this case, the sink pair identified by the product flow library (without any additional barriers)
|
||||
* would be `(p, n)` (where `n` is the `n` in `p[n]`), because there exists a pointer-arithmetic
|
||||
* instruction `pai = a + b` such that:
|
||||
* 1. the allocation flows to `a`, and
|
||||
* 2. `b <= n` where `n` is the `n` in `p[n]`
|
||||
* but because there's a strict comparison that compares `n` against the size of the allocation this
|
||||
* snippet is fine.
|
||||
*/
|
||||
module SizeBarrier<SizeBarrierInputSig Input> {
|
||||
private module SizeBarrierConfig implements DataFlow::ConfigSig {
|
||||
predicate isSource = Input::isSource/1;
|
||||
|
||||
predicate fieldFlowBranchLimit = Input::fieldFlowBranchLimit/0;
|
||||
|
||||
/**
|
||||
* Holds if `small <= large + k` holds if `g` evaluates to `testIsTrue`.
|
||||
*/
|
||||
additional predicate isSink(
|
||||
DataFlow::Node small, DataFlow::Node large, IRGuardCondition g, int k, boolean testIsTrue
|
||||
) {
|
||||
// The sink is any "large" side of a relational comparison. i.e., the `large` expression
|
||||
// in a guard such as `small <= large + k`.
|
||||
g.comparesLt(small.asOperand(), large.asOperand(), k + 1, true, testIsTrue)
|
||||
}
|
||||
|
||||
predicate isSink(DataFlow::Node sink) { isSink(_, sink, _, _, _) }
|
||||
}
|
||||
|
||||
private module SizeBarrierFlow = DataFlow::Global<SizeBarrierConfig>;
|
||||
|
||||
private int getASizeAddend(DataFlow::Node node) {
|
||||
exists(DataFlow::Node source |
|
||||
SizeBarrierFlow::flow(source, node) and
|
||||
hasSize(_, source, result)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `small <= large + k` holds if `g` evaluates to `edge`.
|
||||
*/
|
||||
private predicate operandGuardChecks(
|
||||
IRGuardCondition g, Operand small, DataFlow::Node large, int k, boolean edge
|
||||
) {
|
||||
SizeBarrierFlow::flowTo(large) and
|
||||
SizeBarrierConfig::isSink(DataFlow::operandNode(small), large, g, k, edge)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an instruction `instr` that is guarded by a check such as `instr <= small + delta` where
|
||||
* `small <= _ + k` and `small` is the "small side" of a relational comparison that checks
|
||||
* whether `small <= size` where `size` is the size of an allocation.
|
||||
*/
|
||||
private Instruction getABarrierInstruction0(int delta, int k) {
|
||||
exists(
|
||||
IRGuardCondition g, ValueNumber value, Operand small, boolean edge, DataFlow::Node large
|
||||
|
|
||||
// We know:
|
||||
// 1. result <= value + delta (by `bounded`)
|
||||
// 2. value <= large + k (by `operandGuardChecks`).
|
||||
// So:
|
||||
// result <= value + delta (by 1.)
|
||||
// <= large + k + delta (by 2.)
|
||||
small = value.getAUse() and
|
||||
operandGuardChecks(pragma[only_bind_into](g), pragma[only_bind_into](small), large,
|
||||
pragma[only_bind_into](k), pragma[only_bind_into](edge)) and
|
||||
bounded(result, value.getAnInstruction(), delta) and
|
||||
g.controls(result.getBlock(), edge) and
|
||||
k < getASizeAddend(large)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an instruction that is guarded by a guard condition which ensures that
|
||||
* the value of the instruction is upper-bounded by size of some allocation.
|
||||
*/
|
||||
bindingset[state]
|
||||
pragma[inline_late]
|
||||
Instruction getABarrierInstruction(int state) {
|
||||
exists(int delta, int k |
|
||||
state > k + delta and
|
||||
// result <= "size of allocation" + delta + k
|
||||
// < "size of allocation" + state
|
||||
result = getABarrierInstruction0(delta, k)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a `DataFlow::Node` that is guarded by a guard condition which ensures that
|
||||
* the value of the node is upper-bounded by size of some allocation.
|
||||
*/
|
||||
DataFlow::Node getABarrierNode(int state) {
|
||||
exists(DataFlow::Node source, int delta, int k |
|
||||
SizeBarrierFlow::flow(source, result) and
|
||||
hasSize(_, source, state) and
|
||||
result.asInstruction() = getABarrierInstruction0(delta, k) and
|
||||
state > k + delta
|
||||
// so now we have:
|
||||
// result <= "size of allocation" + delta + k
|
||||
// < "size of allocation" + state
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -217,6 +217,33 @@ diagnostics(
|
||||
|
||||
/*- C++ dbscheme -*/
|
||||
|
||||
/**
|
||||
* Information about packages that provide code used during compilation.
|
||||
* The `id` is just a unique identifier.
|
||||
* The `namespace` is typically the name of the package manager that
|
||||
* provided the package (e.g. "dpkg" or "yum").
|
||||
* The `package_name` is the name of the package, and `version` is its
|
||||
* version (as a string).
|
||||
*/
|
||||
external_packages(
|
||||
unique int id: @external_package,
|
||||
string namespace : string ref,
|
||||
string package_name : string ref,
|
||||
string version : string ref
|
||||
);
|
||||
|
||||
/**
|
||||
* Holds if File `fileid` was provided by package `package`.
|
||||
*/
|
||||
header_to_external_package(
|
||||
int fileid : @file ref,
|
||||
int package : @external_package ref
|
||||
);
|
||||
|
||||
/*
|
||||
* C++ dbscheme
|
||||
*/
|
||||
|
||||
extractor_version(
|
||||
string codeql_version: string ref,
|
||||
string frontend_version: string ref
|
||||
@@ -282,17 +309,18 @@ macro_argument_expanded(
|
||||
string text: string ref
|
||||
);
|
||||
|
||||
/*
|
||||
case @function.kind of
|
||||
0 = @unknown_function
|
||||
| 1 = @normal_function
|
||||
1 = @normal_function
|
||||
| 2 = @constructor
|
||||
| 3 = @destructor
|
||||
| 4 = @conversion_function
|
||||
| 5 = @operator
|
||||
// ... 6 = @builtin_function deprecated // GCC built-in functions, e.g. __builtin___memcpy_chk
|
||||
| 6 = @builtin_function // GCC built-in functions, e.g. __builtin___memcpy_chk
|
||||
| 7 = @user_defined_literal
|
||||
| 8 = @deduction_guide
|
||||
;
|
||||
*/
|
||||
|
||||
functions(
|
||||
unique int id: @function,
|
||||
@@ -300,10 +328,6 @@ functions(
|
||||
int kind: int ref
|
||||
);
|
||||
|
||||
builtin_functions(
|
||||
int id: @function ref
|
||||
)
|
||||
|
||||
function_entry_point(
|
||||
int id: @function ref,
|
||||
unique int entry_point: @stmt ref
|
||||
@@ -712,8 +736,9 @@ decltypes(
|
||||
boolean parentheses_would_change_meaning: boolean ref
|
||||
);
|
||||
|
||||
/*
|
||||
case @type_operator.kind of
|
||||
0 = @typeof // The frontend does not differentiate between typeof and typeof_unqual
|
||||
| 0 = @typeof // The frontend does not differentiate between typeof and typeof_unqual
|
||||
| 1 = @underlying_type
|
||||
| 2 = @bases
|
||||
| 3 = @direct_bases
|
||||
@@ -734,6 +759,7 @@ case @type_operator.kind of
|
||||
| 18 = @remove_volatile
|
||||
| 19 = @remove_reference
|
||||
;
|
||||
*/
|
||||
|
||||
type_operators(
|
||||
unique int id: @type_operator,
|
||||
@@ -742,8 +768,9 @@ type_operators(
|
||||
int base_type: @type ref
|
||||
)
|
||||
|
||||
/*
|
||||
case @usertype.kind of
|
||||
0 = @unknown_usertype
|
||||
| 0 = @unknown_usertype
|
||||
| 1 = @struct
|
||||
| 2 = @class
|
||||
| 3 = @union
|
||||
@@ -763,6 +790,7 @@ case @usertype.kind of
|
||||
| 17 = @template_union
|
||||
| 18 = @alias
|
||||
;
|
||||
*/
|
||||
|
||||
usertypes(
|
||||
unique int id: @usertype,
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,7 +0,0 @@
|
||||
class Function extends @function {
|
||||
string toString() { none() }
|
||||
}
|
||||
|
||||
from Function f
|
||||
where functions(f, _, 6)
|
||||
select f
|
||||
@@ -1,9 +0,0 @@
|
||||
class Function extends @function {
|
||||
string toString() { none() }
|
||||
}
|
||||
|
||||
from Function f, string n, int k, int new_k
|
||||
where
|
||||
functions(f, n, k) and
|
||||
if k = 6 then new_k = 1 else new_k = k
|
||||
select f, n, new_k
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,4 +0,0 @@
|
||||
description: Move builtin function identification to its own table
|
||||
compatibility: full
|
||||
functions.rel: run functions.qlo
|
||||
builtin_functions.rel: run builtin_functions.qlo
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,2 +0,0 @@
|
||||
description: Uncomment cases in dbscheme
|
||||
compatibility: full
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,4 +0,0 @@
|
||||
description: Remove unused external_package tables from the dbscheme
|
||||
compatibility: full
|
||||
external_packages.rel: delete
|
||||
header_to_external_package.rel: delete
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user