Merge branch 'main' into henrymercer/actions-status

This commit is contained in:
Henry Mercer
2025-09-05 14:55:58 +01:00
committed by GitHub
762 changed files with 50210 additions and 26571 deletions

View File

@@ -20,7 +20,7 @@ jobs:
os: [ubuntu-22.04, macos-13, windows-2022] os: [ubuntu-22.04, macos-13, windows-2022]
runs-on: ${{ matrix.os }} runs-on: ${{ matrix.os }}
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v5
with: with:
repository: google/ripunzip repository: google/ripunzip
ref: ${{ inputs.ripunzip-version }} ref: ${{ inputs.ripunzip-version }}
@@ -28,7 +28,7 @@ jobs:
# see https://github.com/sfackler/rust-openssl/issues/183 # see https://github.com/sfackler/rust-openssl/issues/183
- if: runner.os == 'Linux' - if: runner.os == 'Linux'
name: checkout openssl name: checkout openssl
uses: actions/checkout@v4 uses: actions/checkout@v5
with: with:
repository: openssl/openssl repository: openssl/openssl
path: openssl path: openssl

View File

@@ -17,7 +17,7 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v4 uses: actions/checkout@v5
- name: Check bazel formatting - name: Check bazel formatting
uses: pre-commit/action@646c83fcd040023954eafda54b4db0192ce70507 uses: pre-commit/action@646c83fcd040023954eafda54b4db0192ce70507
with: with:

View File

@@ -16,7 +16,7 @@ jobs:
check: check:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v5
- name: Check that implicit this warnings is enabled for all packs - name: Check that implicit this warnings is enabled for all packs
shell: bash shell: bash
run: | run: |

View File

@@ -17,7 +17,7 @@ jobs:
sync: sync:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v5
- name: Check overlay annotations - name: Check overlay annotations
run: python config/add-overlay-annotations.py --check java run: python config/add-overlay-annotations.py --check java

View File

@@ -18,7 +18,7 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v5
with: with:
fetch-depth: 2 fetch-depth: 2

View File

@@ -19,6 +19,6 @@ jobs:
name: Check query IDs name: Check query IDs
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v5
- name: Check for duplicate query IDs - name: Check for duplicate query IDs
run: python3 misc/scripts/check-query-ids.py run: python3 misc/scripts/check-query-ids.py

View File

@@ -37,7 +37,7 @@ jobs:
dotnet-version: 9.0.100 dotnet-version: 9.0.100
- name: Checkout repository - name: Checkout repository
uses: actions/checkout@v4 uses: actions/checkout@v5
# Initializes the CodeQL tools for scanning. # Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL - name: Initialize CodeQL

View File

@@ -22,7 +22,7 @@ jobs:
runs-on: ubuntu-latest-xl runs-on: ubuntu-latest-xl
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v5
- name: Setup CodeQL - name: Setup CodeQL
uses: ./.github/actions/fetch-codeql uses: ./.github/actions/fetch-codeql
with: with:

View File

@@ -28,7 +28,7 @@ jobs:
steps: steps:
- name: Checkout repository - name: Checkout repository
uses: actions/checkout@v4 uses: actions/checkout@v5
# Initializes the CodeQL tools for scanning. # Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL - name: Initialize CodeQL

View File

@@ -39,7 +39,7 @@ jobs:
os: [ubuntu-latest, windows-latest] os: [ubuntu-latest, windows-latest]
runs-on: ${{ matrix.os }} runs-on: ${{ matrix.os }}
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v5
- name: Setup dotnet - name: Setup dotnet
uses: actions/setup-dotnet@v4 uses: actions/setup-dotnet@v4
with: with:
@@ -55,7 +55,7 @@ jobs:
stubgentest: stubgentest:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v5
- uses: ./csharp/actions/create-extractor-pack - uses: ./csharp/actions/create-extractor-pack
- name: Run stub generator tests - name: Run stub generator tests
run: | run: |

View File

@@ -23,7 +23,7 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout repository - name: Checkout repository
uses: actions/checkout@v4 uses: actions/checkout@v5
- name: Setup CodeQL - name: Setup CodeQL
uses: ./.github/actions/fetch-codeql uses: ./.github/actions/fetch-codeql
- name: Create empty database - name: Create empty database
@@ -51,7 +51,7 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout repository - name: Checkout repository
uses: actions/checkout@v4 uses: actions/checkout@v5
- name: Setup CodeQL - name: Setup CodeQL
uses: ./.github/actions/fetch-codeql uses: ./.github/actions/fetch-codeql
- name: Create empty database - name: Create empty database

View File

@@ -35,11 +35,11 @@ jobs:
GITHUB_CONTEXT: ${{ toJSON(github.event) }} GITHUB_CONTEXT: ${{ toJSON(github.event) }}
run: echo "$GITHUB_CONTEXT" run: echo "$GITHUB_CONTEXT"
- name: Clone self (github/codeql) - MERGE - name: Clone self (github/codeql) - MERGE
uses: actions/checkout@v4 uses: actions/checkout@v5
with: with:
path: merge path: merge
- name: Clone self (github/codeql) - BASE - name: Clone self (github/codeql) - BASE
uses: actions/checkout@v4 uses: actions/checkout@v5
with: with:
fetch-depth: 2 fetch-depth: 2
path: base path: base

View File

@@ -24,7 +24,7 @@ jobs:
GITHUB_CONTEXT: ${{ toJSON(github.event) }} GITHUB_CONTEXT: ${{ toJSON(github.event) }}
run: echo "$GITHUB_CONTEXT" run: echo "$GITHUB_CONTEXT"
- name: Clone self (github/codeql) - name: Clone self (github/codeql)
uses: actions/checkout@v4 uses: actions/checkout@v5
- name: Set up Python 3.8 - name: Set up Python 3.8
uses: actions/setup-python@v4 uses: actions/setup-python@v4
with: with:

View File

@@ -12,11 +12,11 @@ jobs:
steps: steps:
- name: Clone self (github/codeql) - name: Clone self (github/codeql)
uses: actions/checkout@v4 uses: actions/checkout@v5
with: with:
path: script path: script
- name: Clone self (github/codeql) for analysis - name: Clone self (github/codeql) for analysis
uses: actions/checkout@v4 uses: actions/checkout@v5
with: with:
path: codeqlModels path: codeqlModels
fetch-depth: 0 fetch-depth: 0

View File

@@ -21,7 +21,7 @@ jobs:
GITHUB_CONTEXT: ${{ toJSON(github.event) }} GITHUB_CONTEXT: ${{ toJSON(github.event) }}
run: echo "$GITHUB_CONTEXT" run: echo "$GITHUB_CONTEXT"
- name: Clone self (github/codeql) - name: Clone self (github/codeql)
uses: actions/checkout@v4 uses: actions/checkout@v5
with: with:
path: ql path: ql
fetch-depth: 0 fetch-depth: 0

View File

@@ -16,11 +16,11 @@ jobs:
steps: steps:
- name: Clone self (github/codeql) - name: Clone self (github/codeql)
uses: actions/checkout@v4 uses: actions/checkout@v5
with: with:
path: script path: script
- name: Clone self (github/codeql) for analysis - name: Clone self (github/codeql) for analysis
uses: actions/checkout@v4 uses: actions/checkout@v5
with: with:
path: codeqlModels path: codeqlModels
ref: ${{ github.event.inputs.qlModelShaOverride || github.ref }} ref: ${{ github.event.inputs.qlModelShaOverride || github.ref }}

View File

@@ -26,7 +26,7 @@ jobs:
exit 1 exit 1
- name: Checkout - name: Checkout
uses: actions/checkout@v4 uses: actions/checkout@v5
- name: Git config - name: Git config
shell: bash shell: bash

View File

@@ -22,7 +22,7 @@ jobs:
runs-on: ubuntu-latest-xl runs-on: ubuntu-latest-xl
steps: steps:
- name: Check out code - name: Check out code
uses: actions/checkout@v4 uses: actions/checkout@v5
- name: Run tests - name: Run tests
uses: ./go/actions/test uses: ./go/actions/test
with: with:

View File

@@ -20,7 +20,7 @@ jobs:
build: build:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v5
- run: | - run: |
bazel query //java/kotlin-extractor/... bazel query //java/kotlin-extractor/...
# only build the default version as a quick check that we can build from `codeql` # only build the default version as a quick check that we can build from `codeql`

View File

@@ -28,12 +28,12 @@ jobs:
slug: ${{fromJson(github.event.inputs.projects || '["apache/commons-codec", "apache/commons-io", "apache/commons-beanutils", "apache/commons-logging", "apache/commons-fileupload", "apache/commons-lang", "apache/commons-validator", "apache/commons-csv", "apache/dubbo"]' )}} slug: ${{fromJson(github.event.inputs.projects || '["apache/commons-codec", "apache/commons-io", "apache/commons-beanutils", "apache/commons-logging", "apache/commons-fileupload", "apache/commons-lang", "apache/commons-validator", "apache/commons-csv", "apache/dubbo"]' )}}
steps: steps:
- name: Clone github/codeql from PR - name: Clone github/codeql from PR
uses: actions/checkout@v4 uses: actions/checkout@v5
if: github.event.pull_request if: github.event.pull_request
with: with:
path: codeql-pr path: codeql-pr
- name: Clone github/codeql from main - name: Clone github/codeql from main
uses: actions/checkout@v4 uses: actions/checkout@v5
with: with:
path: codeql-main path: codeql-main
ref: main ref: main

View File

@@ -30,11 +30,11 @@ jobs:
ref: "placeholder" ref: "placeholder"
steps: steps:
- name: Clone self (github/codeql) - name: Clone self (github/codeql)
uses: actions/checkout@v4 uses: actions/checkout@v5
- name: Setup CodeQL binaries - name: Setup CodeQL binaries
uses: ./.github/actions/fetch-codeql uses: ./.github/actions/fetch-codeql
- name: Clone repositories - name: Clone repositories
uses: actions/checkout@v4 uses: actions/checkout@v5
with: with:
path: repos/${{ matrix.ref }} path: repos/${{ matrix.ref }}
ref: ${{ matrix.ref }} ref: ${{ matrix.ref }}

View File

@@ -21,7 +21,7 @@ jobs:
check-python-tooling: check-python-tooling:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v5
- uses: actions/setup-python@v5 - uses: actions/setup-python@v5
with: with:
python-version: '3.12' python-version: '3.12'

View File

@@ -43,7 +43,7 @@ jobs:
if-no-files-found: error if-no-files-found: error
retention-days: 1 retention-days: 1
- uses: actions/checkout@v4 - uses: actions/checkout@v5
with: with:
fetch-depth: 2 fetch-depth: 2
persist-credentials: false persist-credentials: false

View File

@@ -19,7 +19,7 @@ jobs:
runs-on: ubuntu-latest-xl runs-on: ubuntu-latest-xl
steps: steps:
### Build the queries ### ### Build the queries ###
- uses: actions/checkout@v4 - uses: actions/checkout@v5
with: with:
fetch-depth: 0 fetch-depth: 0
- name: Find codeql - name: Find codeql

View File

@@ -25,7 +25,7 @@ jobs:
- github/codeql - github/codeql
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v5
- name: Find codeql - name: Find codeql
id: find-codeql id: find-codeql
@@ -46,7 +46,7 @@ jobs:
env: env:
CODEQL: ${{ steps.find-codeql.outputs.codeql-path }} CODEQL: ${{ steps.find-codeql.outputs.codeql-path }}
- name: Checkout ${{ matrix.repo }} - name: Checkout ${{ matrix.repo }}
uses: actions/checkout@v4 uses: actions/checkout@v5
with: with:
repository: ${{ matrix.repo }} repository: ${{ matrix.repo }}
path: ${{ github.workspace }}/repo path: ${{ github.workspace }}/repo
@@ -75,7 +75,7 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
needs: measure needs: measure
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v5
- uses: actions/download-artifact@v4 - uses: actions/download-artifact@v4
with: with:
name: measurements name: measurements

View File

@@ -24,7 +24,7 @@ jobs:
qltest: qltest:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v5
- name: Find codeql - name: Find codeql
id: find-codeql id: find-codeql
uses: github/codeql-action/init@main uses: github/codeql-action/init@main
@@ -64,7 +64,7 @@ jobs:
needs: [qltest] needs: [qltest]
runs-on: ${{ matrix.os }} runs-on: ${{ matrix.os }}
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v5
- name: Install GNU tar - name: Install GNU tar
if: runner.os == 'macOS' if: runner.os == 'macOS'
run: | run: |

View File

@@ -23,7 +23,7 @@ jobs:
steps: steps:
- name: Clone self (github/codeql) - name: Clone self (github/codeql)
uses: actions/checkout@v4 uses: actions/checkout@v5
with: with:
path: codeql path: codeql
- name: Set up Python 3.8 - name: Set up Python 3.8
@@ -31,7 +31,7 @@ jobs:
with: with:
python-version: 3.8 python-version: 3.8
- name: Download CodeQL CLI - name: Download CodeQL CLI
# Look under the `codeql` directory, as this is where we checked out the `github/codeql` repo # Look under the `codeql` directory, as this is where we checked out the `github/codeql` repo
uses: ./codeql/.github/actions/fetch-codeql uses: ./codeql/.github/actions/fetch-codeql
- name: Build code scanning query list - name: Build code scanning query list
run: | run: |

View File

@@ -47,7 +47,7 @@ jobs:
runs-on: ${{ matrix.os }} runs-on: ${{ matrix.os }}
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v5
- name: Install GNU tar - name: Install GNU tar
if: runner.os == 'macOS' if: runner.os == 'macOS'
run: | run: |
@@ -113,7 +113,7 @@ jobs:
if: github.repository_owner == 'github' if: github.repository_owner == 'github'
runs-on: ubuntu-latest-xl runs-on: ubuntu-latest-xl
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v5
- name: Fetch CodeQL - name: Fetch CodeQL
uses: ./.github/actions/fetch-codeql uses: ./.github/actions/fetch-codeql
- name: Cache compilation cache - name: Cache compilation cache
@@ -146,7 +146,7 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
needs: [build, compile-queries] needs: [build, compile-queries]
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v5
- uses: actions/download-artifact@v4 - uses: actions/download-artifact@v4
with: with:
name: ruby.dbscheme name: ruby.dbscheme
@@ -209,7 +209,7 @@ jobs:
runs-on: ${{ matrix.os }} runs-on: ${{ matrix.os }}
needs: [package] needs: [package]
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v5
- name: Fetch CodeQL - name: Fetch CodeQL
uses: ./.github/actions/fetch-codeql uses: ./.github/actions/fetch-codeql

View File

@@ -30,14 +30,14 @@ jobs:
repo: [rails/rails, discourse/discourse, spree/spree, ruby/ruby] repo: [rails/rails, discourse/discourse, spree/spree, ruby/ruby]
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v5
- uses: ./.github/actions/fetch-codeql - uses: ./.github/actions/fetch-codeql
- uses: ./ruby/actions/create-extractor-pack - uses: ./ruby/actions/create-extractor-pack
- name: Checkout ${{ matrix.repo }} - name: Checkout ${{ matrix.repo }}
uses: actions/checkout@v4 uses: actions/checkout@v5
with: with:
repository: ${{ matrix.repo }} repository: ${{ matrix.repo }}
path: ${{ github.workspace }}/repo path: ${{ github.workspace }}/repo
@@ -62,7 +62,7 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
needs: measure needs: measure
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v5
- uses: actions/download-artifact@v4 - uses: actions/download-artifact@v4
with: with:
path: stats path: stats

View File

@@ -25,7 +25,7 @@ jobs:
strategy: strategy:
fail-fast: false fail-fast: false
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v5
- uses: ./.github/actions/fetch-codeql - uses: ./.github/actions/fetch-codeql
- uses: ./ruby/actions/create-extractor-pack - uses: ./ruby/actions/create-extractor-pack
- name: Cache compilation cache - name: Cache compilation cache

View File

@@ -36,7 +36,7 @@ jobs:
qlupgrade: qlupgrade:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v5
- uses: ./.github/actions/fetch-codeql - uses: ./.github/actions/fetch-codeql
- name: Check DB upgrade scripts - name: Check DB upgrade scripts
run: | run: |
@@ -58,7 +58,7 @@ jobs:
strategy: strategy:
fail-fast: false fail-fast: false
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v5
- uses: ./.github/actions/fetch-codeql - uses: ./.github/actions/fetch-codeql
- uses: ./ruby/actions/create-extractor-pack - uses: ./ruby/actions/create-extractor-pack
- name: Cache compilation cache - name: Cache compilation cache

View File

@@ -35,7 +35,7 @@ jobs:
steps: steps:
- name: Checkout repository - name: Checkout repository
uses: actions/checkout@v4 uses: actions/checkout@v5
- name: Query latest nightly CodeQL bundle - name: Query latest nightly CodeQL bundle
shell: bash shell: bash

View File

@@ -30,7 +30,7 @@ jobs:
working-directory: rust/ast-generator working-directory: rust/ast-generator
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v4 uses: actions/checkout@v5
- name: Inject sources - name: Inject sources
shell: bash shell: bash
run: | run: |
@@ -53,7 +53,7 @@ jobs:
working-directory: rust/extractor working-directory: rust/extractor
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v4 uses: actions/checkout@v5
- name: Format - name: Format
shell: bash shell: bash
run: | run: |
@@ -69,7 +69,7 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v4 uses: actions/checkout@v5
- name: Install CodeQL - name: Install CodeQL
uses: ./.github/actions/fetch-codeql uses: ./.github/actions/fetch-codeql
- name: Code generation - name: Code generation

View File

@@ -36,7 +36,7 @@ jobs:
fail-fast: false fail-fast: false
runs-on: ${{ matrix.runner }} runs-on: ${{ matrix.runner }}
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v5
- name: Setup (Linux) - name: Setup (Linux)
if: runner.os == 'Linux' if: runner.os == 'Linux'
run: | run: |
@@ -53,7 +53,7 @@ jobs:
clang-format: clang-format:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v5
- uses: pre-commit/action@646c83fcd040023954eafda54b4db0192ce70507 - uses: pre-commit/action@646c83fcd040023954eafda54b4db0192ce70507
name: Check that python code is properly formatted name: Check that python code is properly formatted
with: with:
@@ -61,7 +61,7 @@ jobs:
codegen: codegen:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v5
- uses: ./.github/actions/fetch-codeql - uses: ./.github/actions/fetch-codeql
- uses: pre-commit/action@646c83fcd040023954eafda54b4db0192ce70507 - uses: pre-commit/action@646c83fcd040023954eafda54b4db0192ce70507
name: Check that QL generated code was checked in name: Check that QL generated code was checked in
@@ -77,6 +77,6 @@ jobs:
check-no-override: check-no-override:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v5
- name: Check that no override is present in load.bzl - name: Check that no override is present in load.bzl
run: bazel test ... --test_tag_filters=override --test_output=errors run: bazel test ... --test_tag_filters=override --test_output=errors

View File

@@ -17,7 +17,7 @@ jobs:
sync: sync:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v5
- name: Check synchronized files - name: Check synchronized files
run: python config/sync-files.py run: python config/sync-files.py
- name: Check dbscheme fragments - name: Check dbscheme fragments

View File

@@ -30,7 +30,7 @@ jobs:
test: test:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v5
- name: Check formatting - name: Check formatting
run: cargo fmt -- --check run: cargo fmt -- --check
- name: Run tests - name: Run tests
@@ -38,12 +38,12 @@ jobs:
fmt: fmt:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v5
- name: Check formatting - name: Check formatting
run: cargo fmt --check run: cargo fmt --check
clippy: clippy:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v5
- name: Run clippy - name: Run clippy
run: cargo clippy -- --no-deps -D warnings -A clippy::new_without_default -A clippy::too_many_arguments run: cargo clippy -- --no-deps -D warnings -A clippy::new_without_default -A clippy::too_many_arguments

View File

@@ -23,7 +23,7 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout repository - name: Checkout repository
uses: actions/checkout@v4 uses: actions/checkout@v5
- name: Setup CodeQL - name: Setup CodeQL
uses: ./.github/actions/fetch-codeql uses: ./.github/actions/fetch-codeql

View File

@@ -18,6 +18,6 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v5
- run: | - run: |
bazel test //misc/bazel/internal/zipmerge:test --test_output=all bazel test //misc/bazel/internal/zipmerge:test --test_output=all

View File

@@ -1,11 +1,12 @@
name: "actions" name: "actions"
aliases: []
display_name: "GitHub Actions" display_name: "GitHub Actions"
version: 0.0.1 version: 0.0.1
column_kind: "utf16" column_kind: "utf16"
unicode_newlines: true unicode_newlines: true
build_modes: build_modes:
- none - none
default_queries:
- codeql/actions-queries
# Actions workflows are not reported separately by the GitHub API, so we can't # Actions workflows are not reported separately by the GitHub API, so we can't
# associate them with a specific language. # associate them with a specific language.
github_api_languages: [] github_api_languages: []

View File

@@ -1,3 +1,7 @@
## 0.4.16
No user-facing changes.
## 0.4.15 ## 0.4.15
No user-facing changes. No user-facing changes.

View File

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

View File

@@ -1,2 +1,2 @@
--- ---
lastReleaseVersion: 0.4.15 lastReleaseVersion: 0.4.16

View File

@@ -70,8 +70,8 @@ class Location extends TLocation, TBaseLocation {
/** /**
* Holds if this element is at the specified location. * Holds if this element is at the specified location.
* The location spans column `startcolumn` of line `startline` to * The location spans column `sc` of line `sl` to
* column `endcolumn` of line `endline` in file `filepath`. * column `ec` of line `el` in file `p`.
* For more information, see * For more information, see
* [Providing locations in CodeQL queries](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). * [Providing locations in CodeQL queries](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
*/ */

View File

@@ -261,7 +261,7 @@ class If extends AstNode instanceof IfImpl {
} }
/** /**
* An Environemnt node representing a deployment environment. * An Environment node representing a deployment environment.
*/ */
class Environment extends AstNode instanceof EnvironmentImpl { class Environment extends AstNode instanceof EnvironmentImpl {
string getName() { result = super.getName() } string getName() { result = super.getName() }

View File

@@ -125,12 +125,11 @@ abstract class AstNodeImpl extends TAstNode {
* Gets the enclosing Step. * Gets the enclosing Step.
*/ */
StepImpl getEnclosingStep() { StepImpl getEnclosingStep() {
if this instanceof StepImpl this instanceof StepImpl and
then result = this result = this
else or
if this instanceof ScalarValueImpl this instanceof ScalarValueImpl and
then result.getAChildNode*() = this.getParentNode() result.getAChildNode*() = this.getParentNode()
else none()
} }
/** /**
@@ -1416,9 +1415,8 @@ class ExternalJobImpl extends JobImpl, UsesImpl {
override string getVersion() { override string getVersion() {
exists(YamlString name | exists(YamlString name |
n.lookup("uses") = name and n.lookup("uses") = name and
if not name.getValue().matches("\\.%") not name.getValue().matches("\\.%") and
then result = name.getValue().regexpCapture(repoUsesParser(), 4) result = name.getValue().regexpCapture(repoUsesParser(), 4)
else none()
) )
} }
} }

View File

@@ -286,7 +286,7 @@ private module Cached {
/** /**
* Holds if `cfn` is the `i`th node in basic block `bb`. * Holds if `cfn` is the `i`th node in basic block `bb`.
* *
* In other words, `i` is the shortest distance from a node `bb` * In other words, `i` is the shortest distance from a node `bbStart`
* that starts a basic block to `cfn` along the `intraBBSucc` relation. * that starts a basic block to `cfn` along the `intraBBSucc` relation.
*/ */
cached cached

View File

@@ -3,6 +3,8 @@ private import codeql.controlflow.Cfg as CfgShared
private import codeql.Locations private import codeql.Locations
module Completion { module Completion {
import codeql.controlflow.SuccessorType
private newtype TCompletion = private newtype TCompletion =
TSimpleCompletion() or TSimpleCompletion() or
TBooleanCompletion(boolean b) { b in [false, true] } or TBooleanCompletion(boolean b) { b in [false, true] } or
@@ -25,7 +27,7 @@ module Completion {
override predicate isValidFor(AstNode e) { not any(Completion c).isValidForSpecific(e) } override predicate isValidFor(AstNode e) { not any(Completion c).isValidForSpecific(e) }
override NormalSuccessor getAMatchingSuccessorType() { any() } override DirectSuccessor getAMatchingSuccessorType() { any() }
} }
class BooleanCompletion extends NormalCompletion, TBooleanCompletion { class BooleanCompletion extends NormalCompletion, TBooleanCompletion {
@@ -49,34 +51,6 @@ module Completion {
override ReturnSuccessor getAMatchingSuccessorType() { any() } override ReturnSuccessor getAMatchingSuccessorType() { any() }
} }
cached
private newtype TSuccessorType =
TNormalSuccessor() or
TBooleanSuccessor(boolean b) { b in [false, true] } or
TReturnSuccessor()
class SuccessorType extends TSuccessorType {
string toString() { none() }
}
class NormalSuccessor extends SuccessorType, TNormalSuccessor {
override string toString() { result = "successor" }
}
class BooleanSuccessor extends SuccessorType, TBooleanSuccessor {
boolean value;
BooleanSuccessor() { this = TBooleanSuccessor(value) }
override string toString() { result = value.toString() }
boolean getValue() { result = value }
}
class ReturnSuccessor extends SuccessorType, TReturnSuccessor {
override string toString() { result = "return" }
}
} }
module CfgScope { module CfgScope {
@@ -127,14 +101,8 @@ private module Implementation implements CfgShared::InputSig<Location> {
last(scope.(CompositeAction), e, c) last(scope.(CompositeAction), e, c)
} }
predicate successorTypeIsSimple(SuccessorType t) { t instanceof NormalSuccessor }
predicate successorTypeIsCondition(SuccessorType t) { t instanceof BooleanSuccessor }
SuccessorType getAMatchingSuccessorType(Completion c) { result = c.getAMatchingSuccessorType() } SuccessorType getAMatchingSuccessorType(Completion c) { result = c.getAMatchingSuccessorType() }
predicate isAbnormalExitType(SuccessorType t) { none() }
int idOfAstNode(AstNode node) { none() } int idOfAstNode(AstNode node) { none() }
int idOfCfgScope(CfgScope scope) { none() } int idOfCfgScope(CfgScope scope) { none() }

View File

@@ -63,10 +63,10 @@ predicate madSource(DataFlow::Node source, string kind, string fieldName) {
( (
if fieldName.trim().matches("env.%") if fieldName.trim().matches("env.%")
then source.asExpr() = uses.getInScopeEnvVarExpr(fieldName.trim().replaceAll("env.", "")) then source.asExpr() = uses.getInScopeEnvVarExpr(fieldName.trim().replaceAll("env.", ""))
else else (
if fieldName.trim().matches("output.%") fieldName.trim().matches("output.%") and
then source.asExpr() = uses source.asExpr() = uses
else none() )
) )
) )
} }

View File

@@ -31,14 +31,14 @@ abstract class RemoteFlowSource extends SourceNode {
class GitHubCtxSource extends RemoteFlowSource { class GitHubCtxSource extends RemoteFlowSource {
string flag; string flag;
string event; string event;
GitHubExpression e;
GitHubCtxSource() { GitHubCtxSource() {
this.asExpr() = e and exists(GitHubExpression e |
// github.head_ref this.asExpr() = e and
e.getFieldName() = "head_ref" and // github.head_ref
flag = "branch" and e.getFieldName() = "head_ref" and
( flag = "branch"
|
event = e.getATriggerEvent().getName() and event = e.getATriggerEvent().getName() and
event = "pull_request_target" event = "pull_request_target"
or or
@@ -148,7 +148,6 @@ class GhCLICommandSource extends RemoteFlowSource, CommandSource {
class GitHubEventPathSource extends RemoteFlowSource, CommandSource { class GitHubEventPathSource extends RemoteFlowSource, CommandSource {
string cmd; string cmd;
string flag; string flag;
string access_path;
Run run; Run run;
// Examples // Examples
@@ -163,7 +162,7 @@ class GitHubEventPathSource extends RemoteFlowSource, CommandSource {
run.getScript().getACommand() = cmd and run.getScript().getACommand() = cmd and
cmd.matches("jq%") and cmd.matches("jq%") and
cmd.matches("%GITHUB_EVENT_PATH%") and cmd.matches("%GITHUB_EVENT_PATH%") and
exists(string regexp | exists(string regexp, string access_path |
untrustedEventPropertiesDataModel(regexp, flag) and untrustedEventPropertiesDataModel(regexp, flag) and
not flag = "json" and not flag = "json" and
access_path = "github.event" + cmd.regexpCapture(".*\\s+([^\\s]+)\\s+.*", 1) and access_path = "github.event" + cmd.regexpCapture(".*\\s+([^\\s]+)\\s+.*", 1) and

View File

@@ -19,7 +19,6 @@ abstract class ArgumentInjectionSink extends DataFlow::Node {
*/ */
class ArgumentInjectionFromEnvVarSink extends ArgumentInjectionSink { class ArgumentInjectionFromEnvVarSink extends ArgumentInjectionSink {
string command; string command;
string argument;
ArgumentInjectionFromEnvVarSink() { ArgumentInjectionFromEnvVarSink() {
exists(Run run, string var | exists(Run run, string var |
@@ -28,7 +27,7 @@ class ArgumentInjectionFromEnvVarSink extends ArgumentInjectionSink {
exists(run.getInScopeEnvVarExpr(var)) or exists(run.getInScopeEnvVarExpr(var)) or
var = "GITHUB_HEAD_REF" var = "GITHUB_HEAD_REF"
) and ) and
run.getScript().getAnEnvReachingArgumentInjectionSink(var, command, argument) run.getScript().getAnEnvReachingArgumentInjectionSink(var, command, _)
) )
} }
@@ -44,13 +43,12 @@ class ArgumentInjectionFromEnvVarSink extends ArgumentInjectionSink {
*/ */
class ArgumentInjectionFromCommandSink extends ArgumentInjectionSink { class ArgumentInjectionFromCommandSink extends ArgumentInjectionSink {
string command; string command;
string argument;
ArgumentInjectionFromCommandSink() { ArgumentInjectionFromCommandSink() {
exists(CommandSource source, Run run | exists(CommandSource source, Run run |
run = source.getEnclosingRun() and run = source.getEnclosingRun() and
this.asExpr() = run.getScript() and this.asExpr() = run.getScript() and
run.getScript().getACmdReachingArgumentInjectionSink(source.getCommand(), command, argument) run.getScript().getACmdReachingArgumentInjectionSink(source.getCommand(), command, _)
) )
} }

View File

@@ -125,8 +125,6 @@ class LegitLabsDownloadArtifactActionStep extends UntrustedArtifactDownloadStep,
} }
class ActionsGitHubScriptDownloadStep extends UntrustedArtifactDownloadStep, UsesStep { class ActionsGitHubScriptDownloadStep extends UntrustedArtifactDownloadStep, UsesStep {
string script;
ActionsGitHubScriptDownloadStep() { ActionsGitHubScriptDownloadStep() {
// eg: // eg:
// - uses: actions/github-script@v6 // - uses: actions/github-script@v6
@@ -149,12 +147,14 @@ class ActionsGitHubScriptDownloadStep extends UntrustedArtifactDownloadStep, Use
// var fs = require('fs'); // var fs = require('fs');
// fs.writeFileSync('${{github.workspace}}/test-results.zip', Buffer.from(download.data)); // fs.writeFileSync('${{github.workspace}}/test-results.zip', Buffer.from(download.data));
this.getCallee() = "actions/github-script" and this.getCallee() = "actions/github-script" and
this.getArgument("script") = script and exists(string script |
script.matches("%listWorkflowRunArtifacts(%") and this.getArgument("script") = script and
script.matches("%downloadArtifact(%") and script.matches("%listWorkflowRunArtifacts(%") and
script.matches("%writeFileSync(%") and script.matches("%downloadArtifact(%") and
// Filter out artifacts that were created by pull-request. script.matches("%writeFileSync(%") and
not script.matches("%exclude_pull_requests: true%") // Filter out artifacts that were created by pull-request.
not script.matches("%exclude_pull_requests: true%")
)
} }
override string getPath() { override string getPath() {
@@ -171,10 +171,10 @@ class ActionsGitHubScriptDownloadStep extends UntrustedArtifactDownloadStep, Use
.getScript() .getScript()
.getACommand() .getACommand()
.regexpCapture(unzipRegexp() + unzipDirArgRegexp(), 3))) .regexpCapture(unzipRegexp() + unzipDirArgRegexp(), 3)))
else else (
if this.getAFollowingStep().(Run).getScript().getACommand().regexpMatch(unzipRegexp()) this.getAFollowingStep().(Run).getScript().getACommand().regexpMatch(unzipRegexp()) and
then result = "GITHUB_WORKSPACE/" result = "GITHUB_WORKSPACE/"
else none() )
} }
} }
@@ -207,12 +207,13 @@ class GHRunArtifactDownloadStep extends UntrustedArtifactDownloadStep, Run {
.getScript() .getScript()
.getACommand() .getACommand()
.regexpCapture(unzipRegexp() + unzipDirArgRegexp(), 3))) .regexpCapture(unzipRegexp() + unzipDirArgRegexp(), 3)))
else else (
if (
this.getAFollowingStep().(Run).getScript().getACommand().regexpMatch(unzipRegexp()) or this.getAFollowingStep().(Run).getScript().getACommand().regexpMatch(unzipRegexp()) or
this.getScript().getACommand().regexpMatch(unzipRegexp()) this.getScript().getACommand().regexpMatch(unzipRegexp())
then result = "GITHUB_WORKSPACE/" ) and
else none() result = "GITHUB_WORKSPACE/"
)
} }
} }
@@ -259,15 +260,15 @@ class DirectArtifactDownloadStep extends UntrustedArtifactDownloadStep, Run {
class ArtifactPoisoningSink extends DataFlow::Node { class ArtifactPoisoningSink extends DataFlow::Node {
UntrustedArtifactDownloadStep download; UntrustedArtifactDownloadStep download;
PoisonableStep poisonable;
ArtifactPoisoningSink() { ArtifactPoisoningSink() {
download.getAFollowingStep() = poisonable and exists(PoisonableStep poisonable |
// excluding artifacts downloaded to the temporary directory download.getAFollowingStep() = poisonable and
not download.getPath().regexpMatch("^/tmp.*") and // excluding artifacts downloaded to the temporary directory
not download.getPath().regexpMatch("^\\$\\{\\{\\s*runner\\.temp\\s*}}.*") and not download.getPath().regexpMatch("^/tmp.*") and
not download.getPath().regexpMatch("^\\$RUNNER_TEMP.*") and not download.getPath().regexpMatch("^\\$\\{\\{\\s*runner\\.temp\\s*}}.*") and
( not download.getPath().regexpMatch("^\\$RUNNER_TEMP.*")
|
poisonable.(Run).getScript() = this.asExpr() and poisonable.(Run).getScript() = this.asExpr() and
( (
// Check if the poisonable step is a local script execution step // Check if the poisonable step is a local script execution step

View File

@@ -159,11 +159,8 @@ abstract class CommentVsHeadDateCheck extends ControlCheck {
/* Specific implementations of control checks */ /* Specific implementations of control checks */
class LabelIfCheck extends LabelCheck instanceof If { class LabelIfCheck extends LabelCheck instanceof If {
string condition;
LabelIfCheck() { LabelIfCheck() {
condition = normalizeExpr(this.getCondition()) and exists(string condition | condition = normalizeExpr(this.getCondition()) |
(
// eg: contains(github.event.pull_request.labels.*.name, 'safe to test') // eg: contains(github.event.pull_request.labels.*.name, 'safe to test')
condition.regexpMatch(".*(^|[^!])contains\\(\\s*github\\.event\\.pull_request\\.labels\\b.*") condition.regexpMatch(".*(^|[^!])contains\\(\\s*github\\.event\\.pull_request\\.labels\\b.*")
or or

View File

@@ -55,12 +55,8 @@ class EnvVarInjectionFromFileReadSink extends EnvVarInjectionSink {
* echo "COMMIT_MESSAGE=${COMMIT_MESSAGE}" >> $GITHUB_ENV * echo "COMMIT_MESSAGE=${COMMIT_MESSAGE}" >> $GITHUB_ENV
*/ */
class EnvVarInjectionFromCommandSink extends EnvVarInjectionSink { class EnvVarInjectionFromCommandSink extends EnvVarInjectionSink {
CommandSource inCommand;
string injectedVar;
string command;
EnvVarInjectionFromCommandSink() { EnvVarInjectionFromCommandSink() {
exists(Run run | exists(Run run, CommandSource inCommand, string injectedVar, string command |
this.asExpr() = inCommand.getEnclosingRun().getScript() and this.asExpr() = inCommand.getEnclosingRun().getScript() and
run = inCommand.getEnclosingRun() and run = inCommand.getEnclosingRun() and
run.getScript().getACmdReachingGitHubEnvWrite(inCommand.getCommand(), injectedVar) and run.getScript().getACmdReachingGitHubEnvWrite(inCommand.getCommand(), injectedVar) and
@@ -86,12 +82,8 @@ class EnvVarInjectionFromCommandSink extends EnvVarInjectionSink {
* echo "FOO=$BODY" >> $GITHUB_ENV * echo "FOO=$BODY" >> $GITHUB_ENV
*/ */
class EnvVarInjectionFromEnvVarSink extends EnvVarInjectionSink { class EnvVarInjectionFromEnvVarSink extends EnvVarInjectionSink {
string inVar;
string injectedVar;
string command;
EnvVarInjectionFromEnvVarSink() { EnvVarInjectionFromEnvVarSink() {
exists(Run run | exists(Run run, string inVar, string injectedVar, string command |
run.getScript() = this.asExpr() and run.getScript() = this.asExpr() and
exists(run.getInScopeEnvVarExpr(inVar)) and exists(run.getInScopeEnvVarExpr(inVar)) and
run.getScript().getAnEnvReachingGitHubEnvWrite(inVar, injectedVar) and run.getScript().getAnEnvReachingGitHubEnvWrite(inVar, injectedVar) and

View File

@@ -99,18 +99,14 @@ class OutputClobberingFromEnvVarSink extends OutputClobberingSink {
* echo $BODY * echo $BODY
*/ */
class WorkflowCommandClobberingFromEnvVarSink extends OutputClobberingSink { class WorkflowCommandClobberingFromEnvVarSink extends OutputClobberingSink {
string clobbering_var;
string clobbered_value;
WorkflowCommandClobberingFromEnvVarSink() { WorkflowCommandClobberingFromEnvVarSink() {
exists(Run run, string workflow_cmd_stmt, string clobbering_stmt | exists(Run run, string workflow_cmd_stmt, string clobbering_stmt, string clobbering_var |
run.getScript() = this.asExpr() and run.getScript() = this.asExpr() and
run.getScript().getAStmt() = clobbering_stmt and run.getScript().getAStmt() = clobbering_stmt and
clobbering_stmt.regexpMatch("echo\\s+(-e\\s+)?(\"|')?\\$(\\{)?" + clobbering_var + ".*") and clobbering_stmt.regexpMatch("echo\\s+(-e\\s+)?(\"|')?\\$(\\{)?" + clobbering_var + ".*") and
exists(run.getInScopeEnvVarExpr(clobbering_var)) and exists(run.getInScopeEnvVarExpr(clobbering_var)) and
run.getScript().getAStmt() = workflow_cmd_stmt and run.getScript().getAStmt() = workflow_cmd_stmt and
clobbered_value = exists(trimQuotes(workflow_cmd_stmt.regexpCapture(".*::set-output\\s+name=.*::(.*)", 1)))
trimQuotes(workflow_cmd_stmt.regexpCapture(".*::set-output\\s+name=.*::(.*)", 1))
) )
} }
} }

View File

@@ -1,10 +1,8 @@
import actions import actions
class UnversionedImmutableAction extends UsesStep { class UnversionedImmutableAction extends UsesStep {
string immutable_action;
UnversionedImmutableAction() { UnversionedImmutableAction() {
isImmutableAction(this, immutable_action) and isImmutableAction(this, _) and
not isSemVer(this.getVersion()) not isSemVer(this.getVersion())
} }
} }

View File

@@ -1,5 +1,5 @@
name: codeql/actions-all name: codeql/actions-all
version: 0.4.16-dev version: 0.4.17-dev
library: true library: true
warnOnImplicitThis: true warnOnImplicitThis: true
dependencies: dependencies:

View File

@@ -1,3 +1,7 @@
## 0.6.8
No user-facing changes.
## 0.6.7 ## 0.6.7
No user-facing changes. No user-facing changes.

View File

@@ -32,7 +32,7 @@ jobs:
- uses: actions/setup-node@v1 - uses: actions/setup-node@v1
- run: | - run: |
npm install # scripts in package.json from PR would be executed here npm install # scripts in package.json from PR would be executed here
npm build npm build
- uses: completely/fakeaction@v2 - uses: completely/fakeaction@v2

View File

@@ -32,7 +32,7 @@ jobs:
- uses: actions/setup-node@v1 - uses: actions/setup-node@v1
- run: | - run: |
npm install # scripts in package.json from PR would be executed here npm install # scripts in package.json from PR would be executed here
npm build npm build
- uses: completely/fakeaction@v2 - uses: completely/fakeaction@v2

View File

@@ -32,7 +32,7 @@ jobs:
- uses: actions/setup-node@v1 - uses: actions/setup-node@v1
- run: | - run: |
npm install # scripts in package.json from PR would be executed here npm install # scripts in package.json from PR would be executed here
npm build npm build
- uses: completely/fakeaction@v2 - uses: completely/fakeaction@v2

View File

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

View File

@@ -1,2 +1,2 @@
--- ---
lastReleaseVersion: 0.6.7 lastReleaseVersion: 0.6.8

View File

@@ -37,8 +37,6 @@ where
) )
or or
// upload artifact is not used in the same workflow // upload artifact is not used in the same workflow
not exists(UsesStep upload | not download.getEnclosingWorkflow().getAJob().(LocalJob).getAStep() instanceof UsesStep
download.getEnclosingWorkflow().getAJob().(LocalJob).getAStep() = upload
)
) )
select download, "Potential artifact poisoning" select download, "Potential artifact poisoning"

View File

@@ -1,5 +1,5 @@
name: codeql/actions-queries name: codeql/actions-queries
version: 0.6.8-dev version: 0.6.9-dev
library: false library: false
warnOnImplicitThis: true warnOnImplicitThis: true
groups: [actions, queries] groups: [actions, queries]

View File

@@ -1,3 +1,14 @@
## 5.5.0
### New Features
* Added a new class `PchFile` representing precompiled header (PCH) files used during project compilation.
### Minor Analysis Improvements
* Added flow summaries for the `Microsoft::WRL::ComPtr` member functions.
* The new dataflow/taint-tracking library (`semmle.code.cpp.dataflow.new.DataFlow` and `semmle.code.cpp.dataflow.new.TaintTracking`) now resolves virtual function calls more precisely. This results in fewer false positives when running dataflow/taint-tracking queries on C++ projects.
## 5.4.1 ## 5.4.1
### Minor Analysis Improvements ### Minor Analysis Improvements

View File

@@ -35,7 +35,7 @@ class CustomOptions extends Options {
override predicate returnsNull(Call call) { Options.super.returnsNull(call) } override predicate returnsNull(Call call) { Options.super.returnsNull(call) }
/** /**
* Holds if a call to this function will never return. * Holds if a call to the function `f` will never return.
* *
* By default, this holds for `exit`, `_exit`, `abort`, `__assert_fail`, * By default, this holds for `exit`, `_exit`, `abort`, `__assert_fail`,
* `longjmp`, `error`, `__builtin_unreachable` and any function with a * `longjmp`, `error`, `__builtin_unreachable` and any function with a

View File

@@ -1,4 +0,0 @@
---
category: minorAnalysis
---
* The new dataflow/taint-tracking library (`semmle.code.cpp.dataflow.new.DataFlow` and `semmle.code.cpp.dataflow.new.TaintTracking`) now resolves virtual function calls more precisely. This results in fewer false positives when running dataflow/taint-tracking queries on C++ projects.

View File

@@ -1,5 +0,0 @@
---
category: feature
---
* Added a new class `PchFile` representing precompiled header (PCH) files used during project compilation.

View File

@@ -1,4 +0,0 @@
---
category: minorAnalysis
---
* Added flow summaries for the `Microsoft::WRL::ComPtr` member functions.

View File

@@ -0,0 +1,4 @@
---
category: feature
---
* Added predicates `getTransitiveNumberOfVlaDimensionStmts`, `getTransitiveVlaDimensionStmt`, and `getParentVlaDecl` to `VlaDeclStmt` for handling `VlaDeclStmt`s whose base type defined in terms of an other `VlaDeclStmt` via a `typedef`.

View File

@@ -0,0 +1,4 @@
---
category: deprecated
---
* The predicate `getAContructorCall` in the class `SslContextClass` has been deprecated. Use `getAConstructorCall` instead.

View File

@@ -0,0 +1,10 @@
## 5.5.0
### New Features
* Added a new class `PchFile` representing precompiled header (PCH) files used during project compilation.
### Minor Analysis Improvements
* Added flow summaries for the `Microsoft::WRL::ComPtr` member functions.
* The new dataflow/taint-tracking library (`semmle.code.cpp.dataflow.new.DataFlow` and `semmle.code.cpp.dataflow.new.TaintTracking`) now resolves virtual function calls more precisely. This results in fewer false positives when running dataflow/taint-tracking queries on C++ projects.

View File

@@ -1,2 +1,2 @@
--- ---
lastReleaseVersion: 5.4.1 lastReleaseVersion: 5.5.0

View File

@@ -127,7 +127,7 @@ abstract class CryptographicAlgorithm extends CryptographicArtifact {
/** /**
* Normalizes a raw name into a normalized name as found in `CryptoAlgorithmNames.qll`. * Normalizes a raw name into a normalized name as found in `CryptoAlgorithmNames.qll`.
* Subclassess should override for more api-specific normalization. * Subclassess should override for more api-specific normalization.
* By deafult, converts a raw name to upper-case with no hyphen, underscore, hash, or space. * By default, converts a raw name to upper-case with no hyphen, underscore, hash, or space.
*/ */
bindingset[s] bindingset[s]
string normalizeName(string s) { string normalizeName(string s) {

View File

@@ -652,14 +652,14 @@ module KeyGeneration {
* Trace from EVP_PKEY_CTX* at algorithm sink to keygen, * Trace from EVP_PKEY_CTX* at algorithm sink to keygen,
* users can then extrapolatae the matching algorithm from the alg sink to the keygen * users can then extrapolatae the matching algorithm from the alg sink to the keygen
*/ */
module EVP_PKEY_CTX_Ptr_Source_to_KeyGenOperationWithNoSize implements DataFlow::ConfigSig { module EVP_PKEY_CTX_Ptr_Source_to_KeyGenOperationWithNoSizeConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) { isEVP_PKEY_CTX_Source(source, _) } predicate isSource(DataFlow::Node source) { isEVP_PKEY_CTX_Source(source, _) }
predicate isSink(DataFlow::Node sink) { isKeyGen_EVP_PKEY_CTX_Sink(sink, _) } predicate isSink(DataFlow::Node sink) { isKeyGen_EVP_PKEY_CTX_Sink(sink, _) }
} }
module EVP_PKEY_CTX_Ptr_Source_to_KeyGenOperationWithNoSize_Flow = module EVP_PKEY_CTX_Ptr_Source_to_KeyGenOperationWithNoSize_Flow =
DataFlow::Global<EVP_PKEY_CTX_Ptr_Source_to_KeyGenOperationWithNoSize>; DataFlow::Global<EVP_PKEY_CTX_Ptr_Source_to_KeyGenOperationWithNoSizeConfig>;
/** /**
* UNKNOWN key sizes to general purpose key generation functions (i.e., that take in no key size and assume * UNKNOWN key sizes to general purpose key generation functions (i.e., that take in no key size and assume

View File

@@ -59,7 +59,7 @@ private string privateNormalizeFunctionName(Function f, string algType) {
* *
* The predicate attempts to restrict normalization to what looks like an openssl * The predicate attempts to restrict normalization to what looks like an openssl
* library by looking for functions only in an openssl path (see `isPossibleOpenSSLFunction`). * library by looking for functions only in an openssl path (see `isPossibleOpenSSLFunction`).
* This may give false postive functions if a directory erronously appears to be openssl; * This may give false positive functions if a directory erronously appears to be openssl;
* however, we take the stance that if a function * however, we take the stance that if a function
* exists strongly mapping to a known function name in a directory such as these, * exists strongly mapping to a known function name in a directory such as these,
* regardless of whether its actually a part of openSSL or not, we will analyze it as though it were. * regardless of whether its actually a part of openSSL or not, we will analyze it as though it were.

View File

@@ -49,7 +49,7 @@ private string privateNormalizeFunctionName(Function f, string algType) {
* *
* The predicate attempts to restrict normalization to what looks like an openssl * The predicate attempts to restrict normalization to what looks like an openssl
* library by looking for functions only in an openssl path (see `isPossibleOpenSSLFunction`). * library by looking for functions only in an openssl path (see `isPossibleOpenSSLFunction`).
* This may give false postive functions if a directory erronously appears to be openssl; * This may give false positive functions if a directory erronously appears to be openssl;
* however, we take the stance that if a function * however, we take the stance that if a function
* exists strongly mapping to a known function name in a directory such as these, * exists strongly mapping to a known function name in a directory such as these,
* regardless of whether its actually a part of openSSL or not, we will analyze it as though it were. * regardless of whether its actually a part of openSSL or not, we will analyze it as though it were.

View File

@@ -31,7 +31,7 @@ predicate knownPassthroughFunction(Function f, int inInd, int outInd) {
/** /**
* `c` is a call to a function that preserves the algorithm but changes its form. * `c` is a call to a function that preserves the algorithm but changes its form.
* `onExpr` is the input argument passing through to, `outExpr` is the next expression in a dataflow step associated with `c` * `inExpr` is the input argument passing through to, `outExpr` is the next expression in a dataflow step associated with `c`
*/ */
predicate knownPassthoughCall(Call c, Expr inExpr, Expr outExpr) { predicate knownPassthoughCall(Call c, Expr inExpr, Expr outExpr) {
exists(int inInd, int outInd | exists(int inInd, int outInd |

View File

@@ -298,10 +298,11 @@ private predicate boundFlowStep(Instruction i, NonPhiOperand op, int delta, bool
else else
if strictlyNegative(x) if strictlyNegative(x)
then upper = true and delta = -1 then upper = true and delta = -1
else else (
if negative(x) negative(x) and
then upper = true and delta = 0 upper = true and
else none() delta = 0
)
) )
or or
exists(Operand x | exists(Operand x |
@@ -321,10 +322,11 @@ private predicate boundFlowStep(Instruction i, NonPhiOperand op, int delta, bool
else else
if strictlyNegative(x) if strictlyNegative(x)
then upper = false and delta = 1 then upper = false and delta = 1
else else (
if negative(x) negative(x) and
then upper = false and delta = 0 upper = false and
else none() delta = 0
)
) )
or or
i.(RemInstruction).getRightOperand() = op and positive(op) and delta = -1 and upper = true i.(RemInstruction).getRightOperand() = op and positive(op) and delta = -1 and upper = true

View File

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

View File

@@ -198,7 +198,7 @@ class ConceptIdExpr extends Expr, @concept_id {
final Locatable getATemplateArgumentKind() { result = this.getTemplateArgumentKind(_) } final Locatable getATemplateArgumentKind() { result = this.getTemplateArgumentKind(_) }
/** /**
* Gets the `i`th template argument passed to the concept. * Gets template argument at index `index` passed to the concept, if any.
* *
* For example, if: * For example, if:
* ```cpp * ```cpp
@@ -219,7 +219,7 @@ class ConceptIdExpr extends Expr, @concept_id {
} }
/** /**
* Gets the kind of the `i`th template argument value passed to the concept. * Gets the kind of the template argument value at index `index` passed to the concept, if any.
* *
* For example, if: * For example, if:
* ```cpp * ```cpp

View File

@@ -223,8 +223,8 @@ class Declaration extends Locatable, @declaration {
final Locatable getATemplateArgumentKind() { result = this.getTemplateArgumentKind(_) } final Locatable getATemplateArgumentKind() { result = this.getTemplateArgumentKind(_) }
/** /**
* Gets the `i`th template argument used to instantiate this declaration from a * Gets the template argument at index `index` used to instantiate this declaration from a
* template. * template, if any.
* *
* For example: * For example:
* *
@@ -245,9 +245,9 @@ class Declaration extends Locatable, @declaration {
} }
/** /**
* Gets the `i`th template argument value used to instantiate this declaration * Gets the template argument value at index `index` used to instantiate this declaration
* from a template. When called on a template, this will return the `i`th template * from a template. When called on a template, this will return the template
* parameter value if it exists. * parameter value at index `index` if it exists.
* *
* For example: * For example:
* *

View File

@@ -877,7 +877,7 @@ class FormatLiteral extends Literal instanceof StringLiteral {
} }
/** /**
* Gets the char type required by the nth conversion specifier. * Gets the char type required by the `n`th conversion specifier.
* - in the base case this is the default for the formatting function * - in the base case this is the default for the formatting function
* (e.g. `char` for `printf`, `char` or `wchar_t` for `wprintf`). * (e.g. `char` for `printf`, `char` or `wchar_t` for `wprintf`).
* - the `%C` format character reverses wideness. * - the `%C` format character reverses wideness.
@@ -922,7 +922,7 @@ class FormatLiteral extends Literal instanceof StringLiteral {
} }
/** /**
* Gets the string type required by the nth conversion specifier. * Gets the string type required by the `n`th conversion specifier.
* - in the base case this is the default for the formatting function * - in the base case this is the default for the formatting function
* (e.g. `char *` for `printf`, `char *` or `wchar_t *` for `wprintf`). * (e.g. `char *` for `printf`, `char *` or `wchar_t *` for `wprintf`).
* - the `%S` format character reverses wideness on some platforms. * - the `%S` format character reverses wideness on some platforms.

View File

@@ -101,7 +101,7 @@ predicate postDominates(ControlFlowNode postDominator, ControlFlowNode node) {
*/ */
/** /**
* Holds if `dominator` is an immediate dominator of `node` in the control-flow * Holds if `dom` is an immediate dominator of `node` in the control-flow
* graph of basic blocks. * graph of basic blocks.
*/ */
predicate bbIDominates(BasicBlock dom, BasicBlock node) = predicate bbIDominates(BasicBlock dom, BasicBlock node) =
@@ -117,7 +117,7 @@ private predicate bb_predecessor(BasicBlock succ, BasicBlock pred) { bb_successo
private predicate bb_exit(ExitBasicBlock exit) { any() } private predicate bb_exit(ExitBasicBlock exit) { any() }
/** /**
* Holds if `postDominator` is an immediate post-dominator of `node` in the control-flow * Holds if `pDom` is an immediate post-dominator of `node` in the control-flow
* graph of basic blocks. * graph of basic blocks.
*/ */
predicate bbIPostDominates(BasicBlock pDom, BasicBlock node) = predicate bbIPostDominates(BasicBlock pDom, BasicBlock node) =

View File

@@ -1042,8 +1042,8 @@ private predicate subEdgeIncludingDestructors(Pos p1, Node n1, Node n2, Pos p2)
* - `MicrosoftTryFinallyStmt`: On the edge following the `__finally` block for * - `MicrosoftTryFinallyStmt`: On the edge following the `__finally` block for
* the case where an exception was thrown and needs to be propagated. * the case where an exception was thrown and needs to be propagated.
*/ */
DestructorCall getSynthesisedDestructorCallAfterNode(Node n, int i) { DestructorCall getSynthesisedDestructorCallAfterNode(Node node, int index) {
synthetic_destructor_call(n, i, result) synthetic_destructor_call(node, index, result)
} }
/** /**

View File

@@ -834,8 +834,10 @@ class ContentSet instanceof Content {
* For more information, see * For more information, see
* [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
*/ */
predicate hasLocationInfo(string path, int sl, int sc, int el, int ec) { predicate hasLocationInfo(
super.hasLocationInfo(path, sl, sc, el, ec) string filepath, int startline, int startcolumn, int endline, int endcolumn
) {
super.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
} }
} }

View File

@@ -1880,9 +1880,7 @@ module IteratorFlow {
} }
} }
private module SsaInput implements SsaImpl::InputSig<Location> { private module SsaInput implements SsaImpl::InputSig<Location, IRCfg::BasicBlock> {
import Ssa::InputSigCommon
class SourceVariable = IteratorFlow::SourceVariable; class SourceVariable = IteratorFlow::SourceVariable;
/** A call to function that dereferences an iterator. */ /** A call to function that dereferences an iterator. */
@@ -1960,7 +1958,7 @@ module IteratorFlow {
* Holds if `(bb, i)` contains a write to an iterator that may have been obtained * Holds if `(bb, i)` contains a write to an iterator that may have been obtained
* by calling `begin` (or related functions) on the variable `v`. * by calling `begin` (or related functions) on the variable `v`.
*/ */
predicate variableWrite(BasicBlock bb, int i, SourceVariable v, boolean certain) { predicate variableWrite(IRCfg::BasicBlock bb, int i, SourceVariable v, boolean certain) {
certain = false and certain = false and
exists(GetsIteratorCall beginCall, Instruction writeToDeref, IRBlock bbQual, int iQual | exists(GetsIteratorCall beginCall, Instruction writeToDeref, IRBlock bbQual, int iQual |
isIteratorStoreInstruction(beginCall, writeToDeref) and isIteratorStoreInstruction(beginCall, writeToDeref) and
@@ -1971,12 +1969,12 @@ module IteratorFlow {
} }
/** Holds if `(bb, i)` reads the container variable `v`. */ /** Holds if `(bb, i)` reads the container variable `v`. */
predicate variableRead(BasicBlock bb, int i, SourceVariable v, boolean certain) { predicate variableRead(IRCfg::BasicBlock bb, int i, SourceVariable v, boolean certain) {
Ssa::variableRead(bb, i, v, certain) Ssa::variableRead(bb, i, v, certain)
} }
} }
private module IteratorSsa = SsaImpl::Make<Location, SsaInput>; private module IteratorSsa = SsaImpl::Make<Location, IRCfg, SsaInput>;
private module DataFlowIntegrationInput implements IteratorSsa::DataFlowIntegrationInputSig { private module DataFlowIntegrationInput implements IteratorSsa::DataFlowIntegrationInputSig {
private import codeql.util.Void private import codeql.util.Void
@@ -1989,7 +1987,7 @@ module IteratorFlow {
) )
} }
predicate hasCfgNode(SsaInput::BasicBlock bb, int i) { bb.getInstruction(i) = this } predicate hasCfgNode(IRCfg::BasicBlock bb, int i) { bb.getInstruction(i) = this }
} }
predicate ssaDefHasSource(IteratorSsa::WriteDefinition def) { none() } predicate ssaDefHasSource(IteratorSsa::WriteDefinition def) { none() }
@@ -1999,20 +1997,16 @@ module IteratorFlow {
class GuardValue = Void; class GuardValue = Void;
class Guard extends Void { class Guard extends Void {
predicate hasValueBranchEdge( predicate hasValueBranchEdge(IRCfg::BasicBlock bb1, IRCfg::BasicBlock bb2, GuardValue val) {
SsaInput::BasicBlock bb1, SsaInput::BasicBlock bb2, GuardValue val
) {
none() none()
} }
predicate valueControlsBranchEdge( predicate valueControlsBranchEdge(IRCfg::BasicBlock bb1, IRCfg::BasicBlock bb2, GuardValue val) {
SsaInput::BasicBlock bb1, SsaInput::BasicBlock bb2, GuardValue val
) {
none() none()
} }
} }
predicate guardDirectlyControlsBlock(Guard guard, SsaInput::BasicBlock bb, GuardValue val) { predicate guardDirectlyControlsBlock(Guard guard, IRCfg::BasicBlock bb, GuardValue val) {
none() none()
} }

View File

@@ -2273,8 +2273,10 @@ class ContentSet instanceof Content {
* For more information, see * For more information, see
* [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
*/ */
predicate hasLocationInfo(string path, int sl, int sc, int el, int ec) { predicate hasLocationInfo(
super.hasLocationInfo(path, sl, sc, el, ec) string filepath, int startline, int startcolumn, int endline, int endcolumn
) {
super.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
} }
} }

View File

@@ -891,15 +891,14 @@ private predicate baseSourceVariableIsGlobal(
) )
} }
private module SsaInput implements Ssa::InputSig<Location> { private module SsaInput implements Ssa::InputSig<Location, IRCfg::BasicBlock> {
import InputSigCommon
import SourceVariables import SourceVariables
/** /**
* Holds if the `i`'th write in block `bb` writes to the variable `v`. * Holds if the `i`'th write in block `bb` writes to the variable `v`.
* `certain` is `true` if the write is guaranteed to overwrite the entire variable. * `certain` is `true` if the write is guaranteed to overwrite the entire variable.
*/ */
predicate variableWrite(BasicBlock bb, int i, SourceVariable v, boolean certain) { predicate variableWrite(IRCfg::BasicBlock bb, int i, SourceVariable v, boolean certain) {
DataFlowImplCommon::forceCachingInSameStage() and DataFlowImplCommon::forceCachingInSameStage() and
( (
exists(DefImpl def | def.hasIndexInBlock(v, bb, i) | exists(DefImpl def | def.hasIndexInBlock(v, bb, i) |
@@ -917,7 +916,7 @@ private module SsaInput implements Ssa::InputSig<Location> {
* Holds if the `i`'th read in block `bb` reads to the variable `v`. * Holds if the `i`'th read in block `bb` reads to the variable `v`.
* `certain` is `true` if the read is guaranteed. For C++, this is always the case. * `certain` is `true` if the read is guaranteed. For C++, this is always the case.
*/ */
predicate variableRead(BasicBlock bb, int i, SourceVariable v, boolean certain) { predicate variableRead(IRCfg::BasicBlock bb, int i, SourceVariable v, boolean certain) {
exists(UseImpl use | use.hasIndexInBlock(bb, i, v) | exists(UseImpl use | use.hasIndexInBlock(bb, i, v) |
if use.isCertain() then certain = true else certain = false if use.isCertain() then certain = true else certain = false
) )
@@ -965,7 +964,7 @@ class GlobalDef extends Definition {
GlobalLikeVariable getVariable() { result = impl.getVariable() } GlobalLikeVariable getVariable() { result = impl.getVariable() }
} }
private module SsaImpl = Ssa::Make<Location, SsaInput>; private module SsaImpl = Ssa::Make<Location, IRCfg, SsaInput>;
private module DataFlowIntegrationInput implements SsaImpl::DataFlowIntegrationInputSig { private module DataFlowIntegrationInput implements SsaImpl::DataFlowIntegrationInputSig {
private import codeql.util.Boolean private import codeql.util.Boolean
@@ -978,7 +977,7 @@ private module DataFlowIntegrationInput implements SsaImpl::DataFlowIntegrationI
) )
} }
predicate hasCfgNode(SsaInput::BasicBlock bb, int i) { bb.getInstruction(i) = this } predicate hasCfgNode(IRCfg::BasicBlock bb, int i) { bb.getInstruction(i) = this }
} }
Expr getARead(SsaImpl::Definition def) { Expr getARead(SsaImpl::Definition def) {
@@ -1006,9 +1005,7 @@ private module DataFlowIntegrationInput implements SsaImpl::DataFlowIntegrationI
class Guard instanceof IRGuards::IRGuardCondition { class Guard instanceof IRGuards::IRGuardCondition {
string toString() { result = super.toString() } string toString() { result = super.toString() }
predicate hasValueBranchEdge( predicate hasValueBranchEdge(IRCfg::BasicBlock bb1, IRCfg::BasicBlock bb2, GuardValue branch) {
SsaInput::BasicBlock bb1, SsaInput::BasicBlock bb2, GuardValue branch
) {
exists(EdgeKind kind | exists(EdgeKind kind |
super.getBlock() = bb1 and super.getBlock() = bb1 and
kind = getConditionalEdge(branch) and kind = getConditionalEdge(branch) and
@@ -1017,13 +1014,13 @@ private module DataFlowIntegrationInput implements SsaImpl::DataFlowIntegrationI
} }
predicate valueControlsBranchEdge( predicate valueControlsBranchEdge(
SsaInput::BasicBlock bb1, SsaInput::BasicBlock bb2, GuardValue branch IRCfg::BasicBlock bb1, IRCfg::BasicBlock bb2, GuardValue branch
) { ) {
this.hasValueBranchEdge(bb1, bb2, branch) this.hasValueBranchEdge(bb1, bb2, branch)
} }
} }
predicate guardDirectlyControlsBlock(Guard guard, SsaInput::BasicBlock bb, GuardValue branch) { predicate guardDirectlyControlsBlock(Guard guard, IRCfg::BasicBlock bb, GuardValue branch) {
guard.(IRGuards::IRGuardCondition).controls(bb, branch) guard.(IRGuards::IRGuardCondition).controls(bb, branch)
} }

View File

@@ -768,21 +768,3 @@ private module Cached {
} }
import Cached import Cached
/**
* Inputs to the shared SSA library's parameterized module that is shared
* between the SSA pruning stage, and the final SSA stage.
*/
module InputSigCommon {
class BasicBlock extends IRBlock {
ControlFlowNode getNode(int i) { result = this.getInstruction(i) }
int length() { result = this.getInstructionCount() }
}
class ControlFlowNode = Instruction;
BasicBlock getImmediateBasicBlockDominator(BasicBlock bb) { result.immediatelyDominates(bb) }
BasicBlock getABasicBlockSuccessor(BasicBlock bb) { result = bb.getASuccessor() }
}

View File

@@ -2,6 +2,7 @@
* Provides classes that specify the conditions under which control flows along a given edge. * Provides classes that specify the conditions under which control flows along a given edge.
*/ */
private import codeql.controlflow.SuccessorType
private import internal.EdgeKindInternal private import internal.EdgeKindInternal
private newtype TEdgeKind = private newtype TEdgeKind =
@@ -28,6 +29,21 @@ abstract private class EdgeKindImpl extends TEdgeKind {
final class EdgeKind = EdgeKindImpl; final class EdgeKind = EdgeKindImpl;
private SuccessorType getAMatchingSpecificSuccessorType(EdgeKind k) {
result.(BooleanSuccessor).getValue() = true and k instanceof TrueEdge
or
result.(BooleanSuccessor).getValue() = false and k instanceof FalseEdge
or
result instanceof ExceptionSuccessor and k instanceof ExceptionEdge
}
SuccessorType getAMatchingSuccessorType(EdgeKind k) {
result = getAMatchingSpecificSuccessorType(k)
or
not exists(getAMatchingSpecificSuccessorType(k)) and
result instanceof DirectSuccessor
}
/** /**
* A "goto" edge, representing the unconditional successor of an `Instruction` * A "goto" edge, representing the unconditional successor of an `Instruction`
* or `IRBlock`. * or `IRBlock`.

View File

@@ -7,6 +7,7 @@ import Instruction
private import internal.IRBlockImports as Imports private import internal.IRBlockImports as Imports
import Imports::EdgeKind import Imports::EdgeKind
private import Cached private import Cached
private import codeql.controlflow.BasicBlock as BB
/** /**
* Holds if `block` is a block in `func` and `sortOverride`, `sortKey1`, and `sortKey2` are the * Holds if `block` is a block in `func` and `sortOverride`, `sortKey1`, and `sortKey2` are the
@@ -263,6 +264,54 @@ private predicate isEntryBlock(TIRBlock block) {
block = MkIRBlock(any(EnterFunctionInstruction enter)) block = MkIRBlock(any(EnterFunctionInstruction enter))
} }
module IRCfg implements BB::CfgSig<Language::Location> {
private import codeql.controlflow.SuccessorType
class ControlFlowNode = Instruction;
final private class FinalIRBlock = IRBlock;
class BasicBlock extends FinalIRBlock {
ControlFlowNode getNode(int i) { result = this.getInstruction(i) }
ControlFlowNode getLastNode() { result = super.getLastInstruction() }
int length() { result = this.getInstructionCount() }
BasicBlock getASuccessor() { result = super.getASuccessor() }
BasicBlock getASuccessor(SuccessorType t) {
exists(EdgeKind k |
result = super.getSuccessor(k) and
t = getAMatchingSuccessorType(k)
)
}
predicate strictlyDominates(BasicBlock bb) { super.strictlyDominates(bb) }
predicate dominates(BasicBlock bb) { super.dominates(bb) }
BasicBlock getImmediateDominator() { result.immediatelyDominates(this) }
predicate inDominanceFrontier(BasicBlock df) { super.dominanceFrontier() = df }
predicate strictlyPostDominates(BasicBlock bb) { super.strictlyPostDominates(bb) }
predicate postDominates(BasicBlock bb) { super.postDominates(bb) }
}
class EntryBasicBlock extends BasicBlock {
EntryBasicBlock() { isEntryBlock(this) }
}
pragma[nomagic]
predicate dominatingEdge(BasicBlock bb1, BasicBlock bb2) {
bb1.getASuccessor() = bb2 and
bb1 = bb2.getImmediateDominator() and
forall(BasicBlock pred | pred = bb2.getAPredecessor() and pred != bb1 | bb2.dominates(pred))
}
}
cached cached
private module Cached { private module Cached {
cached cached

View File

@@ -7,6 +7,7 @@ import Instruction
private import internal.IRBlockImports as Imports private import internal.IRBlockImports as Imports
import Imports::EdgeKind import Imports::EdgeKind
private import Cached private import Cached
private import codeql.controlflow.BasicBlock as BB
/** /**
* Holds if `block` is a block in `func` and `sortOverride`, `sortKey1`, and `sortKey2` are the * Holds if `block` is a block in `func` and `sortOverride`, `sortKey1`, and `sortKey2` are the
@@ -263,6 +264,54 @@ private predicate isEntryBlock(TIRBlock block) {
block = MkIRBlock(any(EnterFunctionInstruction enter)) block = MkIRBlock(any(EnterFunctionInstruction enter))
} }
module IRCfg implements BB::CfgSig<Language::Location> {
private import codeql.controlflow.SuccessorType
class ControlFlowNode = Instruction;
final private class FinalIRBlock = IRBlock;
class BasicBlock extends FinalIRBlock {
ControlFlowNode getNode(int i) { result = this.getInstruction(i) }
ControlFlowNode getLastNode() { result = super.getLastInstruction() }
int length() { result = this.getInstructionCount() }
BasicBlock getASuccessor() { result = super.getASuccessor() }
BasicBlock getASuccessor(SuccessorType t) {
exists(EdgeKind k |
result = super.getSuccessor(k) and
t = getAMatchingSuccessorType(k)
)
}
predicate strictlyDominates(BasicBlock bb) { super.strictlyDominates(bb) }
predicate dominates(BasicBlock bb) { super.dominates(bb) }
BasicBlock getImmediateDominator() { result.immediatelyDominates(this) }
predicate inDominanceFrontier(BasicBlock df) { super.dominanceFrontier() = df }
predicate strictlyPostDominates(BasicBlock bb) { super.strictlyPostDominates(bb) }
predicate postDominates(BasicBlock bb) { super.postDominates(bb) }
}
class EntryBasicBlock extends BasicBlock {
EntryBasicBlock() { isEntryBlock(this) }
}
pragma[nomagic]
predicate dominatingEdge(BasicBlock bb1, BasicBlock bb2) {
bb1.getASuccessor() = bb2 and
bb1 = bb2.getImmediateDominator() and
forall(BasicBlock pred | pred = bb2.getAPredecessor() and pred != bb1 | bb2.dominates(pred))
}
}
cached cached
private module Cached { private module Cached {
cached cached

View File

@@ -97,7 +97,14 @@ newtype TInstructionTag =
exists(Stmt s | exists(s.getImplicitDestructorCall(index))) exists(Stmt s | exists(s.getImplicitDestructorCall(index)))
} or } or
CoAwaitBranchTag() or CoAwaitBranchTag() or
BoolToIntConversionTag() BoolToIntConversionTag() or
SizeofVlaBaseSizeTag() or
SizeofVlaConversionTag(int index) {
exists(VlaDeclStmt v | exists(v.getTransitiveVlaDimensionStmt(index)))
} or
SizeofVlaDimensionTag(int index) {
exists(VlaDeclStmt v | exists(v.getTransitiveVlaDimensionStmt(index)))
}
class InstructionTag extends TInstructionTag { class InstructionTag extends TInstructionTag {
final string toString() { result = getInstructionTagId(this) } final string toString() { result = getInstructionTagId(this) }

View File

@@ -123,13 +123,16 @@ private predicate ignoreExprAndDescendants(Expr expr) {
// or // or
ignoreExprAndDescendants(getRealParent(expr)) // recursive case ignoreExprAndDescendants(getRealParent(expr)) // recursive case
or or
// va_start doesn't evaluate its argument, so we don't need to translate it. // va_start does not evaluate its argument, so we do not need to translate it.
exists(BuiltInVarArgsStart vaStartExpr | exists(BuiltInVarArgsStart vaStartExpr |
vaStartExpr.getLastNamedParameter().getFullyConverted() = expr vaStartExpr.getLastNamedParameter().getFullyConverted() = expr
) )
or or
// sizeof does not evaluate its argument, so we do not need to translate it.
exists(SizeofExprOperator sizeofExpr | sizeofExpr.getExprOperand().getFullyConverted() = expr)
or
// The children of C11 _Generic expressions are just surface syntax. // The children of C11 _Generic expressions are just surface syntax.
exists(C11GenericExpr generic | generic.getAChild() = expr) exists(C11GenericExpr generic | generic.getAChild().getFullyConverted() = expr)
or or
// Do not translate implicit destructor calls for unnamed temporary variables that are // Do not translate implicit destructor calls for unnamed temporary variables that are
// conditionally constructed (until we have a mechanism for calling these only when the // conditionally constructed (until we have a mechanism for calling these only when the

View File

@@ -187,7 +187,7 @@ Variable getEnclosingVariable(Expr e) {
} }
/** /**
* The IR translation of the "core" part of an expression. This is the part of * The IR translation of the "core" part of an expression. This is the part of
* the expression that produces the result value of the expression, before any * the expression that produces the result value of the expression, before any
* lvalue-to-rvalue conversion on the result. Every expression has a single * lvalue-to-rvalue conversion on the result. Every expression has a single
* `TranslatedCoreExpr`. * `TranslatedCoreExpr`.
@@ -4094,6 +4094,155 @@ class TranslatedStmtExpr extends TranslatedNonConstantExpr {
TranslatedStmt getStmt() { result = getTranslatedStmt(expr.getStmt()) } TranslatedStmt getStmt() { result = getTranslatedStmt(expr.getStmt()) }
} }
private VlaDeclStmt getVlaDeclStmt(Expr expr, int pointerDerefCount) {
expr.(VariableAccess).getTarget() = result.getVariable() and
pointerDerefCount = 0
or
not expr.(PointerDereferenceExpr).getOperand() instanceof AddressOfExpr and
result = getVlaDeclStmt(expr.(PointerDereferenceExpr).getOperand(), pointerDerefCount - 1)
or
// Skip sequences of the form `*&...`
result =
getVlaDeclStmt(expr.(PointerDereferenceExpr).getOperand().(AddressOfExpr).getOperand(),
pointerDerefCount)
or
result = getVlaDeclStmt(expr.(ArrayExpr).getArrayBase(), pointerDerefCount - 1)
}
/**
* The IR translation of `SizeofExprOperator` when its result is non-constant, i.e.,
* when the operand expression refers to a variable length array.
*/
class TranslatedSizeofExpr extends TranslatedNonConstantExpr {
override SizeofExprOperator expr;
VlaDeclStmt vlaDeclStmt;
int vlaDimensions;
int pointerDerefCount;
TranslatedSizeofExpr() {
vlaDeclStmt = getVlaDeclStmt(expr.getExprOperand(), pointerDerefCount) and
vlaDimensions = vlaDeclStmt.getTransitiveNumberOfVlaDimensionStmts() and
pointerDerefCount < vlaDimensions
}
final override Instruction getFirstInstruction(EdgeKind kind) {
result = this.getInstruction(SizeofVlaBaseSizeTag()) and
kind instanceof GotoEdge
}
override Instruction getALastInstructionInternal() {
result = this.getInstruction(SizeofVlaDimensionTag(vlaDimensions - 1))
}
final override TranslatedElement getChildInternal(int id) { none() }
final override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
opcode instanceof Opcode::Constant and
tag = SizeofVlaBaseSizeTag() and
resultType = this.getResultType()
or
exists(int n, Type dimType |
pointerDerefCount <= n and
n < vlaDimensions and
dimType = this.getDimensionExpr(n).getUnderlyingType() and
tag = SizeofVlaConversionTag(n)
|
(
expr.getUnderlyingType() = dimType and
opcode instanceof Opcode::CopyValue
or
not expr.getUnderlyingType() = dimType and
opcode instanceof Opcode::Convert
)
) and
resultType = this.getResultType()
or
opcode instanceof Opcode::Mul and
exists(int n | pointerDerefCount <= n and n < vlaDimensions | tag = SizeofVlaDimensionTag(n)) and
resultType = this.getResultType()
}
final override Instruction getInstructionSuccessorInternal(InstructionTag tag, EdgeKind kind) {
tag = SizeofVlaBaseSizeTag() and
result = this.getInstruction(SizeofVlaConversionTag(pointerDerefCount)) and
kind instanceof GotoEdge
or
exists(int n | pointerDerefCount <= n and n < vlaDimensions |
tag = SizeofVlaConversionTag(n) and
result = this.getInstruction(SizeofVlaDimensionTag(n))
) and
kind instanceof GotoEdge
or
exists(int n | pointerDerefCount <= n and n < vlaDimensions - 1 |
tag = SizeofVlaDimensionTag(n) and
result = this.getInstruction(SizeofVlaConversionTag(n + 1))
) and
kind instanceof GotoEdge
or
tag = SizeofVlaDimensionTag(vlaDimensions - 1) and
result = this.getParent().getChildSuccessor(this, kind)
}
override string getInstructionConstantValue(InstructionTag tag) {
tag = SizeofVlaBaseSizeTag() and
result = this.getBaseType(vlaDeclStmt).getSize().toString()
}
private Type getBaseType(VlaDeclStmt v) {
not exists(v.getParentVlaDecl()) and
(
result =
this.getBaseType(v.getVariable().getUnderlyingType(), v.getNumberOfVlaDimensionStmts())
or
result = this.getBaseType(v.getType().getUnderlyingType(), v.getNumberOfVlaDimensionStmts())
)
or
result = this.getBaseType(v.getParentVlaDecl())
}
private Type getBaseType(Type type, int n) {
n = 0 and
result = type
or
result = this.getBaseType(type.(DerivedType).getBaseType(), n - 1)
}
override Instruction getInstructionRegisterOperand(InstructionTag tag, OperandTag operandTag) {
exists(int n | pointerDerefCount <= n and n < vlaDimensions |
tag = SizeofVlaConversionTag(n) and
(
operandTag instanceof UnaryOperandTag and
result = getTranslatedExpr(this.getDimensionExpr(n)).getResult()
)
)
or
exists(int n | pointerDerefCount <= n and n < vlaDimensions |
tag = SizeofVlaDimensionTag(n) and
(
operandTag instanceof LeftOperandTag and
(
n - 1 >= pointerDerefCount and
result = this.getInstruction(SizeofVlaDimensionTag(n - 1))
or
n - 1 < pointerDerefCount and
result = this.getInstruction(SizeofVlaBaseSizeTag())
)
or
operandTag instanceof RightOperandTag and
result = this.getInstruction(SizeofVlaConversionTag(n))
)
)
}
private Expr getDimensionExpr(int n) {
result = vlaDeclStmt.getTransitiveVlaDimensionStmt(n).getDimensionExpr().getFullyConverted()
}
final override Instruction getResult() {
result = this.getInstruction(SizeofVlaDimensionTag(vlaDimensions - 1))
}
}
class TranslatedErrorExpr extends TranslatedSingleInstructionExpr { class TranslatedErrorExpr extends TranslatedSingleInstructionExpr {
override ErrorExpr expr; override ErrorExpr expr;

View File

@@ -50,7 +50,7 @@ CppType getEllipsisVariablePRValueType() {
CppType getEllipsisVariableGLValueType() { result = getTypeForGLValue(any(UnknownType t)) } CppType getEllipsisVariableGLValueType() { result = getTypeForGLValue(any(UnknownType t)) }
/** /**
* Holds if the function returns a value, as opposed to returning `void`. * Holds if the function `func` returns a value, as opposed to returning `void`.
*/ */
predicate hasReturnValue(Function func) { not func.getUnspecifiedType() instanceof VoidType } predicate hasReturnValue(Function func) { not func.getUnspecifiedType() instanceof VoidType }

View File

@@ -601,7 +601,7 @@ class TranslatedReturnVoidStmt extends TranslatedReturnStmt {
* The IR translation of an implicit `return` statement generated by the extractor to handle control * The IR translation of an implicit `return` statement generated by the extractor to handle control
* flow that reaches the end of a non-`void`-returning function body. Such control flow * flow that reaches the end of a non-`void`-returning function body. Such control flow
* produces undefined behavior in C++ but not in C. However even in C using the return value is * produces undefined behavior in C++ but not in C. However even in C using the return value is
* undefined behaviour. We make it return uninitialized memory to get as much flow as possible. * undefined behavior. We make it return uninitialized memory to get as much flow as possible.
*/ */
class TranslatedNoValueReturnStmt extends TranslatedReturnStmt, TranslatedVariableInitialization { class TranslatedNoValueReturnStmt extends TranslatedReturnStmt, TranslatedVariableInitialization {
TranslatedNoValueReturnStmt() { TranslatedNoValueReturnStmt() {

View File

@@ -7,6 +7,7 @@ import Instruction
private import internal.IRBlockImports as Imports private import internal.IRBlockImports as Imports
import Imports::EdgeKind import Imports::EdgeKind
private import Cached private import Cached
private import codeql.controlflow.BasicBlock as BB
/** /**
* Holds if `block` is a block in `func` and `sortOverride`, `sortKey1`, and `sortKey2` are the * Holds if `block` is a block in `func` and `sortOverride`, `sortKey1`, and `sortKey2` are the
@@ -263,6 +264,54 @@ private predicate isEntryBlock(TIRBlock block) {
block = MkIRBlock(any(EnterFunctionInstruction enter)) block = MkIRBlock(any(EnterFunctionInstruction enter))
} }
module IRCfg implements BB::CfgSig<Language::Location> {
private import codeql.controlflow.SuccessorType
class ControlFlowNode = Instruction;
final private class FinalIRBlock = IRBlock;
class BasicBlock extends FinalIRBlock {
ControlFlowNode getNode(int i) { result = this.getInstruction(i) }
ControlFlowNode getLastNode() { result = super.getLastInstruction() }
int length() { result = this.getInstructionCount() }
BasicBlock getASuccessor() { result = super.getASuccessor() }
BasicBlock getASuccessor(SuccessorType t) {
exists(EdgeKind k |
result = super.getSuccessor(k) and
t = getAMatchingSuccessorType(k)
)
}
predicate strictlyDominates(BasicBlock bb) { super.strictlyDominates(bb) }
predicate dominates(BasicBlock bb) { super.dominates(bb) }
BasicBlock getImmediateDominator() { result.immediatelyDominates(this) }
predicate inDominanceFrontier(BasicBlock df) { super.dominanceFrontier() = df }
predicate strictlyPostDominates(BasicBlock bb) { super.strictlyPostDominates(bb) }
predicate postDominates(BasicBlock bb) { super.postDominates(bb) }
}
class EntryBasicBlock extends BasicBlock {
EntryBasicBlock() { isEntryBlock(this) }
}
pragma[nomagic]
predicate dominatingEdge(BasicBlock bb1, BasicBlock bb2) {
bb1.getASuccessor() = bb2 and
bb1 = bb2.getImmediateDominator() and
forall(BasicBlock pred | pred = bb2.getAPredecessor() and pred != bb1 | bb2.dominates(pred))
}
}
cached cached
private module Cached { private module Cached {
cached cached

View File

@@ -49,7 +49,8 @@ Type getVariableType(Variable v) {
} }
/** /**
* Holds if the database contains a `case` label with the specified minimum and maximum value. * Holds if the database contains a `switchCase` label with the specified minimum `minValue`
* and maximum `maxValue` value.
*/ */
predicate hasCaseEdge(SwitchCase switchCase, string minValue, string maxValue) { predicate hasCaseEdge(SwitchCase switchCase, string minValue, string maxValue) {
minValue = switchCase.getExpr().getFullyConverted().getValue() and minValue = switchCase.getExpr().getFullyConverted().getValue() and

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