mirror of
https://github.com/github/codeql.git
synced 2026-04-28 18:25:24 +02:00
Merge branch 'main' into jcogs33/java/do-not-use-finalizers
This commit is contained in:
1
.bazelrc
1
.bazelrc
@@ -37,5 +37,6 @@ build --java_language_version=17
|
||||
build --tool_java_language_version=17
|
||||
build --tool_java_runtime_version=remotejdk_17
|
||||
build --java_runtime_version=remotejdk_17
|
||||
build --@rules_python//python/config_settings:python_version=3.12
|
||||
|
||||
try-import %workspace%/local.bazelrc
|
||||
|
||||
@@ -8,3 +8,5 @@ common --registry=https://bcr.bazel.build
|
||||
# its implementation packages without providing any code itself.
|
||||
# We either can depend on internal implementation details, or turn of strict deps.
|
||||
common --@rules_dotnet//dotnet/settings:strict_deps=false
|
||||
|
||||
build --@rules_python//python/config_settings:python_version=3.12
|
||||
|
||||
@@ -1 +1 @@
|
||||
8.0.0
|
||||
8.1.1
|
||||
|
||||
@@ -72,7 +72,7 @@ repos:
|
||||
|
||||
- id: rust-codegen
|
||||
name: Run Rust checked in code generation
|
||||
files: ^misc/codegen/|^rust/(prefix\.dbscheme|schema/|codegen/|.*/generated/|ql/lib/(rust\.dbscheme$|codeql/rust/elements)|\.generated.list)
|
||||
files: ^misc/codegen/|^rust/(prefix\.dbscheme|schema/|codegen/|.*/generated/|ql/lib/(rust\.dbscheme$|codeql/rust/elements)|\.generated.list|ast-generator/)
|
||||
language: system
|
||||
entry: bazel run //rust/codegen -- --quiet
|
||||
pass_filenames: false
|
||||
|
||||
@@ -8,12 +8,16 @@
|
||||
/javascript/ @github/codeql-javascript
|
||||
/python/ @github/codeql-python
|
||||
/ruby/ @github/codeql-ruby
|
||||
/rust/ @github/codeql-rust
|
||||
/swift/ @github/codeql-swift
|
||||
/misc/codegen/ @github/codeql-swift
|
||||
/java/kotlin-extractor/ @github/codeql-kotlin
|
||||
/java/ql/test-kotlin1/ @github/codeql-kotlin
|
||||
/java/ql/test-kotlin2/ @github/codeql-kotlin
|
||||
|
||||
# Experimental CodeQL cryptography
|
||||
**/experimental/quantum/ @github/ps-codeql
|
||||
|
||||
# CodeQL tools and associated docs
|
||||
/docs/codeql/codeql-cli/ @github/codeql-cli-reviewers
|
||||
/docs/codeql/codeql-for-visual-studio-code/ @github/codeql-vscode-reviewers
|
||||
@@ -38,6 +42,7 @@ MODULE.bazel @github/codeql-ci-reviewers
|
||||
/.github/workflows/go-* @github/codeql-go
|
||||
/.github/workflows/ql-for-ql-* @github/codeql-ql-for-ql-reviewers
|
||||
/.github/workflows/ruby-* @github/codeql-ruby
|
||||
/.github/workflows/rust.yml @github/codeql-rust
|
||||
/.github/workflows/swift.yml @github/codeql-swift
|
||||
|
||||
# Misc
|
||||
|
||||
604
Cargo.lock
generated
604
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
@@ -14,4 +14,4 @@ members = [
|
||||
[patch.crates-io]
|
||||
# patch for build script bug preventing bazel build
|
||||
# see https://github.com/rust-lang/rustc_apfloat/pull/17
|
||||
rustc_apfloat = { git = "https://github.com/redsun82/rustc_apfloat.git", rev = "096d585100636bc2e9f09d7eefec38c5b334d47b" }
|
||||
rustc_apfloat = { git = "https://github.com/redsun82/rustc_apfloat.git", rev = "32968f16ef1b082243f9bf43a3fbd65c381b3e27" }
|
||||
|
||||
54
MODULE.bazel
54
MODULE.bazel
@@ -71,13 +71,13 @@ use_repo(
|
||||
tree_sitter_extractors_deps = use_extension("//misc/bazel/3rdparty:tree_sitter_extractors_extension.bzl", "r")
|
||||
use_repo(
|
||||
tree_sitter_extractors_deps,
|
||||
"vendor_ts__anyhow-1.0.96",
|
||||
"vendor_ts__anyhow-1.0.97",
|
||||
"vendor_ts__argfile-0.2.1",
|
||||
"vendor_ts__chalk-ir-0.99.0",
|
||||
"vendor_ts__chrono-0.4.39",
|
||||
"vendor_ts__clap-4.5.31",
|
||||
"vendor_ts__chalk-ir-0.100.0",
|
||||
"vendor_ts__chrono-0.4.40",
|
||||
"vendor_ts__clap-4.5.35",
|
||||
"vendor_ts__dunce-1.0.5",
|
||||
"vendor_ts__either-1.14.0",
|
||||
"vendor_ts__either-1.15.0",
|
||||
"vendor_ts__encoding-0.2.33",
|
||||
"vendor_ts__figment-0.10.19",
|
||||
"vendor_ts__flate2-1.1.0",
|
||||
@@ -88,31 +88,31 @@ use_repo(
|
||||
"vendor_ts__mustache-0.9.0",
|
||||
"vendor_ts__num-traits-0.2.19",
|
||||
"vendor_ts__num_cpus-1.16.0",
|
||||
"vendor_ts__proc-macro2-1.0.93",
|
||||
"vendor_ts__quote-1.0.38",
|
||||
"vendor_ts__ra_ap_base_db-0.0.266",
|
||||
"vendor_ts__ra_ap_cfg-0.0.266",
|
||||
"vendor_ts__ra_ap_hir-0.0.266",
|
||||
"vendor_ts__ra_ap_hir_def-0.0.266",
|
||||
"vendor_ts__ra_ap_hir_expand-0.0.266",
|
||||
"vendor_ts__ra_ap_hir_ty-0.0.266",
|
||||
"vendor_ts__ra_ap_ide_db-0.0.266",
|
||||
"vendor_ts__ra_ap_intern-0.0.266",
|
||||
"vendor_ts__ra_ap_load-cargo-0.0.266",
|
||||
"vendor_ts__ra_ap_parser-0.0.266",
|
||||
"vendor_ts__ra_ap_paths-0.0.266",
|
||||
"vendor_ts__ra_ap_project_model-0.0.266",
|
||||
"vendor_ts__ra_ap_span-0.0.266",
|
||||
"vendor_ts__ra_ap_stdx-0.0.266",
|
||||
"vendor_ts__ra_ap_syntax-0.0.266",
|
||||
"vendor_ts__ra_ap_vfs-0.0.266",
|
||||
"vendor_ts__proc-macro2-1.0.94",
|
||||
"vendor_ts__quote-1.0.40",
|
||||
"vendor_ts__ra_ap_base_db-0.0.273",
|
||||
"vendor_ts__ra_ap_cfg-0.0.273",
|
||||
"vendor_ts__ra_ap_hir-0.0.273",
|
||||
"vendor_ts__ra_ap_hir_def-0.0.273",
|
||||
"vendor_ts__ra_ap_hir_expand-0.0.273",
|
||||
"vendor_ts__ra_ap_hir_ty-0.0.273",
|
||||
"vendor_ts__ra_ap_ide_db-0.0.273",
|
||||
"vendor_ts__ra_ap_intern-0.0.273",
|
||||
"vendor_ts__ra_ap_load-cargo-0.0.273",
|
||||
"vendor_ts__ra_ap_parser-0.0.273",
|
||||
"vendor_ts__ra_ap_paths-0.0.273",
|
||||
"vendor_ts__ra_ap_project_model-0.0.273",
|
||||
"vendor_ts__ra_ap_span-0.0.273",
|
||||
"vendor_ts__ra_ap_stdx-0.0.273",
|
||||
"vendor_ts__ra_ap_syntax-0.0.273",
|
||||
"vendor_ts__ra_ap_vfs-0.0.273",
|
||||
"vendor_ts__rand-0.9.0",
|
||||
"vendor_ts__rayon-1.10.0",
|
||||
"vendor_ts__regex-1.11.1",
|
||||
"vendor_ts__serde-1.0.218",
|
||||
"vendor_ts__serde_json-1.0.139",
|
||||
"vendor_ts__serde-1.0.219",
|
||||
"vendor_ts__serde_json-1.0.140",
|
||||
"vendor_ts__serde_with-3.12.0",
|
||||
"vendor_ts__syn-2.0.98",
|
||||
"vendor_ts__syn-2.0.100",
|
||||
"vendor_ts__toml-0.8.20",
|
||||
"vendor_ts__tracing-0.1.41",
|
||||
"vendor_ts__tracing-flame-0.2.0",
|
||||
@@ -155,7 +155,7 @@ use_repo(csharp_main_extension, "paket.main")
|
||||
pip = use_extension("@rules_python//python/extensions:pip.bzl", "pip")
|
||||
pip.parse(
|
||||
hub_name = "codegen_deps",
|
||||
python_version = "3.11",
|
||||
python_version = "3.12",
|
||||
requirements_lock = "//misc/codegen:requirements_lock.txt",
|
||||
)
|
||||
use_repo(pip, "codegen_deps")
|
||||
|
||||
@@ -1,27 +1,34 @@
|
||||
if (($null -ne $env:LGTM_INDEX_INCLUDE) -or ($null -ne $env:LGTM_INDEX_EXCLUDE) -or ($null -ne $env:LGTM_INDEX_FILTERS)) {
|
||||
Write-Output 'Path filters set. Passing them through to the JavaScript extractor.'
|
||||
} else {
|
||||
Write-Output 'No path filters set. Using the default filters.'
|
||||
# Note: We're adding the `reusable_workflows` subdirectories to proactively
|
||||
# record workflows that were called cross-repo, check them out locally,
|
||||
# and enable an interprocedural analysis across the workflow files.
|
||||
# These workflows follow the convention `.github/reusable_workflows/<nwo>/*.ya?ml`
|
||||
$DefaultPathFilters = @(
|
||||
'exclude:**/*',
|
||||
'include:.github/workflows/*.yml',
|
||||
'include:.github/workflows/*.yaml',
|
||||
'include:.github/reusable_workflows/**/*.yml',
|
||||
'include:.github/reusable_workflows/**/*.yaml',
|
||||
'include:**/action.yml',
|
||||
'include:**/action.yaml'
|
||||
)
|
||||
# Note: We're adding the `reusable_workflows` subdirectories to proactively
|
||||
# record workflows that were called cross-repo, check them out locally,
|
||||
# and enable an interprocedural analysis across the workflow files.
|
||||
# These workflows follow the convention `.github/reusable_workflows/<nwo>/*.ya?ml`
|
||||
$DefaultPathFilters = @(
|
||||
'exclude:**/*',
|
||||
'include:.github/workflows/*.yml',
|
||||
'include:.github/workflows/*.yaml',
|
||||
'include:.github/reusable_workflows/**/*.yml',
|
||||
'include:.github/reusable_workflows/**/*.yaml',
|
||||
'include:**/action.yml',
|
||||
'include:**/action.yaml'
|
||||
)
|
||||
|
||||
if ($null -ne $env:LGTM_INDEX_FILTERS) {
|
||||
Write-Output 'LGTM_INDEX_FILTERS set. Using the default filters together with the user-provided filters, and passing through to the JavaScript extractor.'
|
||||
# Begin with the default path inclusions only,
|
||||
# followed by the user-provided filters.
|
||||
# If the user provided `paths`, those patterns override the default inclusions
|
||||
# (because `LGTM_INDEX_FILTERS` will begin with `exclude:**/*`).
|
||||
# If the user provided `paths-ignore`, those patterns are excluded.
|
||||
$PathFilters = ($DefaultPathFilters -join "`n") + "`n" + $env:LGTM_INDEX_FILTERS
|
||||
$env:LGTM_INDEX_FILTERS = $PathFilters
|
||||
} else {
|
||||
Write-Output 'LGTM_INDEX_FILTERS not set. Using the default filters, and passing through to the JavaScript extractor.'
|
||||
$env:LGTM_INDEX_FILTERS = $DefaultPathFilters -join "`n"
|
||||
}
|
||||
|
||||
# Find the JavaScript extractor directory via `codeql resolve extractor`.
|
||||
$CodeQL = Join-Path $env:CODEQL_DIST 'codeql.exe'
|
||||
$env:CODEQL_EXTRACTOR_JAVASCRIPT_ROOT = &$CodeQL resolve extractor --language javascript
|
||||
$env:CODEQL_EXTRACTOR_JAVASCRIPT_ROOT = &"$CodeQL" resolve extractor --language javascript
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
throw 'Failed to resolve JavaScript extractor.'
|
||||
}
|
||||
@@ -40,7 +47,7 @@ $env:CODEQL_EXTRACTOR_JAVASCRIPT_SOURCE_ARCHIVE_DIR = $env:CODEQL_EXTRACTOR_ACTI
|
||||
$env:CODEQL_EXTRACTOR_JAVASCRIPT_TRAP_DIR = $env:CODEQL_EXTRACTOR_ACTIONS_TRAP_DIR
|
||||
$env:CODEQL_EXTRACTOR_JAVASCRIPT_WIP_DATABASE = $env:CODEQL_EXTRACTOR_ACTIONS_WIP_DATABASE
|
||||
|
||||
&$JavaScriptAutoBuild
|
||||
&"$JavaScriptAutoBuild"
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
throw "JavaScript autobuilder failed."
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
@echo off
|
||||
rem All of the work is done in the PowerShell script
|
||||
powershell.exe %~dp0autobuild-impl.ps1
|
||||
echo "Running PowerShell script at '%~dp0autobuild-impl.ps1'"
|
||||
powershell.exe -File "%~dp0autobuild-impl.ps1"
|
||||
|
||||
@@ -17,16 +17,28 @@ include:**/action.yaml
|
||||
END
|
||||
)
|
||||
|
||||
if [ -n "${LGTM_INDEX_INCLUDE:-}" ] || [ -n "${LGTM_INDEX_EXCLUDE:-}" ] || [ -n "${LGTM_INDEX_FILTERS:-}" ] ; then
|
||||
echo "Path filters set. Passing them through to the JavaScript extractor."
|
||||
if [ -n "${LGTM_INDEX_FILTERS:-}" ]; then
|
||||
echo "LGTM_INDEX_FILTERS set. Using the default filters together with the user-provided filters, and passing through to the JavaScript extractor."
|
||||
# Begin with the default path inclusions only,
|
||||
# followed by the user-provided filters.
|
||||
# If the user provided `paths`, those patterns override the default inclusions
|
||||
# (because `LGTM_INDEX_FILTERS` will begin with `exclude:**/*`).
|
||||
# If the user provided `paths-ignore`, those patterns are excluded.
|
||||
PATH_FILTERS="$(cat << END
|
||||
${DEFAULT_PATH_FILTERS}
|
||||
${LGTM_INDEX_FILTERS}
|
||||
END
|
||||
)"
|
||||
LGTM_INDEX_FILTERS="${PATH_FILTERS}"
|
||||
export LGTM_INDEX_FILTERS
|
||||
else
|
||||
echo "No path filters set. Using the default filters."
|
||||
echo "LGTM_INDEX_FILTERS not set. Using the default filters, and passing through to the JavaScript extractor."
|
||||
LGTM_INDEX_FILTERS="${DEFAULT_PATH_FILTERS}"
|
||||
export LGTM_INDEX_FILTERS
|
||||
fi
|
||||
|
||||
# Find the JavaScript extractor directory via `codeql resolve extractor`.
|
||||
CODEQL_EXTRACTOR_JAVASCRIPT_ROOT="$($CODEQL_DIST/codeql resolve extractor --language javascript)"
|
||||
CODEQL_EXTRACTOR_JAVASCRIPT_ROOT="$("${CODEQL_DIST}/codeql" resolve extractor --language javascript)"
|
||||
export CODEQL_EXTRACTOR_JAVASCRIPT_ROOT
|
||||
|
||||
echo "Found JavaScript extractor at '${CODEQL_EXTRACTOR_JAVASCRIPT_ROOT}'."
|
||||
@@ -42,4 +54,4 @@ env CODEQL_EXTRACTOR_JAVASCRIPT_DIAGNOSTIC_DIR="${CODEQL_EXTRACTOR_ACTIONS_DIAGN
|
||||
CODEQL_EXTRACTOR_JAVASCRIPT_SOURCE_ARCHIVE_DIR="${CODEQL_EXTRACTOR_ACTIONS_SOURCE_ARCHIVE_DIR}" \
|
||||
CODEQL_EXTRACTOR_JAVASCRIPT_TRAP_DIR="${CODEQL_EXTRACTOR_ACTIONS_TRAP_DIR}" \
|
||||
CODEQL_EXTRACTOR_JAVASCRIPT_WIP_DATABASE="${CODEQL_EXTRACTOR_ACTIONS_WIP_DATABASE}" \
|
||||
${JAVASCRIPT_AUTO_BUILD}
|
||||
"${JAVASCRIPT_AUTO_BUILD}"
|
||||
|
||||
5
actions/ql/integration-tests/filters-default/actions.ql
Normal file
5
actions/ql/integration-tests/filters-default/actions.ql
Normal file
@@ -0,0 +1,5 @@
|
||||
import actions
|
||||
|
||||
from AstNode n
|
||||
where n instanceof Workflow or n instanceof CompositeAction
|
||||
select n
|
||||
@@ -0,0 +1,6 @@
|
||||
| src/.github/action.yaml:1:1:11:32 | name: ' ... action' |
|
||||
| src/.github/actions/action-name/action.yml:1:1:11:32 | name: ' ... action' |
|
||||
| src/.github/workflows/workflow.yml:1:1:12:33 | name: A workflow |
|
||||
| src/action.yml:1:1:11:32 | name: ' ... action' |
|
||||
| src/excluded/action.yml:1:1:11:32 | name: ' ... action' |
|
||||
| src/included/action.yml:1:1:11:32 | name: ' ... action' |
|
||||
@@ -0,0 +1,2 @@
|
||||
| src/included/action.yml:1:1:11:32 | name: ' ... action' |
|
||||
| src/included/unreachable-workflow.yml:1:1:12:33 | name: A ... orkflow |
|
||||
@@ -0,0 +1,5 @@
|
||||
| src/.github/action.yaml:1:1:11:32 | name: ' ... action' |
|
||||
| src/.github/actions/action-name/action.yml:1:1:11:32 | name: ' ... action' |
|
||||
| src/.github/workflows/workflow.yml:1:1:12:33 | name: A workflow |
|
||||
| src/action.yml:1:1:11:32 | name: ' ... action' |
|
||||
| src/included/action.yml:1:1:11:32 | name: ' ... action' |
|
||||
@@ -0,0 +1,2 @@
|
||||
| src/included/action.yml:1:1:11:32 | name: ' ... action' |
|
||||
| src/included/unreachable-workflow.yml:1:1:12:33 | name: A ... orkflow |
|
||||
5
actions/ql/integration-tests/filters/actions.ql
Normal file
5
actions/ql/integration-tests/filters/actions.ql
Normal file
@@ -0,0 +1,5 @@
|
||||
import actions
|
||||
|
||||
from AstNode n
|
||||
where n instanceof Workflow or n instanceof CompositeAction
|
||||
select n
|
||||
@@ -0,0 +1,4 @@
|
||||
paths:
|
||||
- 'included'
|
||||
paths-ignore:
|
||||
- 'excluded'
|
||||
@@ -0,0 +1,2 @@
|
||||
paths-ignore:
|
||||
- 'excluded'
|
||||
@@ -0,0 +1,2 @@
|
||||
paths:
|
||||
- 'included'
|
||||
@@ -0,0 +1,6 @@
|
||||
src/.github/action.yaml
|
||||
src/.github/actions/action-name/action.yml
|
||||
src/.github/workflows/workflow.yml
|
||||
src/action.yml
|
||||
src/excluded/action.yml
|
||||
src/included/action.yml
|
||||
@@ -0,0 +1,3 @@
|
||||
src/included/action.yml
|
||||
src/included/not-an-action.yml
|
||||
src/included/unreachable-workflow.yml
|
||||
@@ -0,0 +1,5 @@
|
||||
src/.github/action.yaml
|
||||
src/.github/actions/action-name/action.yml
|
||||
src/.github/workflows/workflow.yml
|
||||
src/action.yml
|
||||
src/included/action.yml
|
||||
@@ -0,0 +1,3 @@
|
||||
src/included/action.yml
|
||||
src/included/not-an-action.yml
|
||||
src/included/unreachable-workflow.yml
|
||||
11
actions/ql/integration-tests/filters/src/.github/action.yaml
vendored
Normal file
11
actions/ql/integration-tests/filters/src/.github/action.yaml
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
name: 'A composite action'
|
||||
description: 'Do something'
|
||||
runs:
|
||||
using: "composite"
|
||||
steps:
|
||||
- name: Print
|
||||
run: echo "Hello world"
|
||||
shell: bash
|
||||
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
11
actions/ql/integration-tests/filters/src/.github/actions/action-name/action.yml
vendored
Normal file
11
actions/ql/integration-tests/filters/src/.github/actions/action-name/action.yml
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
name: 'A composite action'
|
||||
description: 'Do something'
|
||||
runs:
|
||||
using: "composite"
|
||||
steps:
|
||||
- name: Print
|
||||
run: echo "Hello world"
|
||||
shell: bash
|
||||
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
12
actions/ql/integration-tests/filters/src/.github/unreachable-workflow.yml
vendored
Normal file
12
actions/ql/integration-tests/filters/src/.github/unreachable-workflow.yml
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
name: An unreachable workflow
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
|
||||
jobs:
|
||||
job:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
12
actions/ql/integration-tests/filters/src/.github/workflows/workflow.yml
vendored
Normal file
12
actions/ql/integration-tests/filters/src/.github/workflows/workflow.yml
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
name: A workflow
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
|
||||
jobs:
|
||||
job:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
11
actions/ql/integration-tests/filters/src/action.yml
Normal file
11
actions/ql/integration-tests/filters/src/action.yml
Normal file
@@ -0,0 +1,11 @@
|
||||
name: 'A composite action'
|
||||
description: 'Do something'
|
||||
runs:
|
||||
using: "composite"
|
||||
steps:
|
||||
- name: Print
|
||||
run: echo "Hello world"
|
||||
shell: bash
|
||||
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
11
actions/ql/integration-tests/filters/src/excluded/action.yml
Normal file
11
actions/ql/integration-tests/filters/src/excluded/action.yml
Normal file
@@ -0,0 +1,11 @@
|
||||
name: 'A composite action'
|
||||
description: 'Do something'
|
||||
runs:
|
||||
using: "composite"
|
||||
steps:
|
||||
- name: Print
|
||||
run: echo "Hello world"
|
||||
shell: bash
|
||||
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
@@ -0,0 +1,12 @@
|
||||
name: An unreachable workflow
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
|
||||
jobs:
|
||||
job:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
11
actions/ql/integration-tests/filters/src/included/action.yml
Normal file
11
actions/ql/integration-tests/filters/src/included/action.yml
Normal file
@@ -0,0 +1,11 @@
|
||||
name: 'A composite action'
|
||||
description: 'Do something'
|
||||
runs:
|
||||
using: "composite"
|
||||
steps:
|
||||
- name: Print
|
||||
run: echo "Hello world"
|
||||
shell: bash
|
||||
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
@@ -0,0 +1 @@
|
||||
name: 'Not an action, just a YAML file'
|
||||
@@ -0,0 +1,12 @@
|
||||
name: An unreachable workflow
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
|
||||
jobs:
|
||||
job:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
@@ -0,0 +1,12 @@
|
||||
name: An unreachable workflow
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
|
||||
jobs:
|
||||
job:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
18
actions/ql/integration-tests/filters/test.py
Executable file
18
actions/ql/integration-tests/filters/test.py
Executable file
@@ -0,0 +1,18 @@
|
||||
import pytest
|
||||
|
||||
@pytest.mark.ql_test(expected=".default-filters.expected")
|
||||
def test_default_filters(codeql, actions, check_source_archive):
|
||||
check_source_archive.expected_suffix = ".default-filters.expected"
|
||||
codeql.database.create(source_root="src")
|
||||
|
||||
@pytest.mark.ql_test(expected=".paths-only.expected")
|
||||
def test_config_paths_only(codeql, actions):
|
||||
codeql.database.create(source_root="src", codescanning_config="codeql-config.paths-only.yml")
|
||||
|
||||
@pytest.mark.ql_test(expected=".paths-ignore-only.expected")
|
||||
def test_config_paths_ignore_only(codeql, actions):
|
||||
codeql.database.create(source_root="src", codescanning_config="codeql-config.paths-ignore-only.yml")
|
||||
|
||||
@pytest.mark.ql_test(expected=".paths-and-paths-ignore.expected")
|
||||
def test_config_paths_and_paths_ignore(codeql, actions):
|
||||
codeql.database.create(source_root="src", codescanning_config="codeql-config.paths-and-paths-ignore.yml")
|
||||
@@ -1,3 +1,14 @@
|
||||
## 0.4.7
|
||||
|
||||
No user-facing changes.
|
||||
|
||||
## 0.4.6
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* The query `actions/code-injection/medium` now produces alerts for injection
|
||||
vulnerabilities on `pull_request` events.
|
||||
|
||||
## 0.4.5
|
||||
|
||||
No user-facing changes.
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
---
|
||||
category: fix
|
||||
---
|
||||
## 0.4.6
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* The query `actions/code-injection/medium` now produces alerts for injection
|
||||
vulnerabilities on `pull_request` events.
|
||||
vulnerabilities on `pull_request` events.
|
||||
3
actions/ql/lib/change-notes/released/0.4.7.md
Normal file
3
actions/ql/lib/change-notes/released/0.4.7.md
Normal file
@@ -0,0 +1,3 @@
|
||||
## 0.4.7
|
||||
|
||||
No user-facing changes.
|
||||
@@ -1,2 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 0.4.5
|
||||
lastReleaseVersion: 0.4.7
|
||||
|
||||
@@ -154,3 +154,13 @@ predicate untrustedGitCommandDataModel(string cmd_regex, string flag) {
|
||||
predicate untrustedGhCommandDataModel(string cmd_regex, string flag) {
|
||||
Extensions::untrustedGhCommandDataModel(cmd_regex, flag)
|
||||
}
|
||||
|
||||
/**
|
||||
* MaD models for permissions needed by actions
|
||||
* Fields:
|
||||
* - action: action name, e.g. `actions/checkout`
|
||||
* - permission: permission name, e.g. `contents: read`
|
||||
*/
|
||||
predicate actionsPermissionsDataModel(string action, string permission) {
|
||||
Extensions::actionsPermissionsDataModel(action, permission)
|
||||
}
|
||||
|
||||
@@ -77,3 +77,14 @@ extensible predicate untrustedGitCommandDataModel(string cmd_regex, string flag)
|
||||
* Holds for gh commands that may introduce untrusted data
|
||||
*/
|
||||
extensible predicate untrustedGhCommandDataModel(string cmd_regex, string flag);
|
||||
|
||||
/**
|
||||
* Holds if `action` needs `permission` to run.
|
||||
* - 'action' is the name of the action without any version information.
|
||||
* E.g. for the action selector `actions/checkout@v2`, `action` is `actions/checkout`.
|
||||
* - `permission` is of the form `scope-name: read|write`, for example `contents: read`.
|
||||
* - see https://github.com/actions/checkout?tab=readme-ov-file#recommended-permissions
|
||||
* for an example of recommended permissions.
|
||||
* - see https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/controlling-permissions-for-github_token for documentation of token permissions.
|
||||
*/
|
||||
extensible predicate actionsPermissionsDataModel(string action, string permission);
|
||||
|
||||
37
actions/ql/lib/ext/config/actions_permissions.yml
Normal file
37
actions/ql/lib/ext/config/actions_permissions.yml
Normal file
@@ -0,0 +1,37 @@
|
||||
extensions:
|
||||
- addsTo:
|
||||
pack: codeql/actions-all
|
||||
extensible: actionsPermissionsDataModel
|
||||
data:
|
||||
- ["actions/checkout", "contents: read"]
|
||||
- ["actions/setup-node", "contents: read"]
|
||||
- ["actions/setup-python", "contents: read"]
|
||||
- ["actions/setup-java", "contents: read"]
|
||||
- ["actions/setup-go", "contents: read"]
|
||||
- ["actions/setup-dotnet", "contents: read"]
|
||||
- ["actions/labeler", "contents: read"]
|
||||
- ["actions/labeler", "pull-requests: write"]
|
||||
- ["actions/attest", "id-token: write"]
|
||||
- ["actions/attest", "attestations: write"]
|
||||
# No permissions needed for actions/add-to-project
|
||||
- ["actions/dependency-review-action", "contents: read"]
|
||||
- ["actions/attest-sbom", "id-token: write"]
|
||||
- ["actions/attest-sbom", "attestations: write"]
|
||||
- ["actions/stale", "contents: write"]
|
||||
- ["actions/stale", "issues: write"]
|
||||
- ["actions/stale", "pull-requests: write"]
|
||||
- ["actions/attest-build-provenance", "id-token: write"]
|
||||
- ["actions/attest-build-provenance", "attestations: write"]
|
||||
- ["actions/jekyll-build-pages", "contents: read"]
|
||||
- ["actions/jekyll-build-pages", "pages: write"]
|
||||
- ["actions/jekyll-build-pages", "id-token: write"]
|
||||
- ["actions/publish-action", "contents: write"]
|
||||
- ["actions/versions-package-tools", "contents: read"]
|
||||
- ["actions/versions-package-tools", "actions: read"]
|
||||
- ["actions/reusable-workflows", "contents: read"]
|
||||
- ["actions/reusable-workflows", "actions: read"]
|
||||
# TODO: Add permissions for actions/download-artifact
|
||||
# TODO: Add permissions for actions/upload-artifact
|
||||
# TODO: Add permissions for actions/cache
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql/actions-all
|
||||
version: 0.4.6-dev
|
||||
version: 0.4.8-dev
|
||||
library: true
|
||||
warnOnImplicitThis: true
|
||||
dependencies:
|
||||
|
||||
@@ -1,3 +1,17 @@
|
||||
## 0.5.4
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* Alerts produced by the query `actions/missing-workflow-permissions` now include a minimal set of recommended permissions in the alert message, based on well-known actions seen within the workflow file.
|
||||
|
||||
## 0.5.3
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* Fixed typos in the query and alert titles for the queries
|
||||
`actions/envpath-injection/critical`, `actions/envpath-injection/medium`,
|
||||
`actions/envvar-injection/critical`, and `actions/envvar-injection/medium`.
|
||||
|
||||
## 0.5.2
|
||||
|
||||
No user-facing changes.
|
||||
@@ -7,9 +21,10 @@ No user-facing changes.
|
||||
### Bug Fixes
|
||||
|
||||
* The `actions/unversioned-immutable-action` query will no longer report any alerts, since the
|
||||
Immutable Actions feature is not yet available for customer use. The query remains in the
|
||||
default Code Scanning suites for use internal to GitHub. Once the Immutable Actions feature is
|
||||
available, the query will be updated to report alerts again.
|
||||
Immutable Actions feature is not yet available for customer use. The query has also been moved
|
||||
to the experimental folder and will not be used in code scanning unless it is explicitly added
|
||||
to a code scanning configuration. Once the Immutable Actions feature is available, the query will
|
||||
be updated to report alerts again.
|
||||
|
||||
## 0.5.0
|
||||
|
||||
|
||||
@@ -109,7 +109,7 @@ An attacker could craft a malicious artifact that writes dangerous environment v
|
||||
|
||||
### Exploitation
|
||||
|
||||
An attacker is be able to run arbitrary code by injecting environment variables such as `LD_PRELOAD`, `BASH_ENV`, etc.
|
||||
An attacker would be able to run arbitrary code by injecting environment variables such as `LD_PRELOAD`, `BASH_ENV`, etc.
|
||||
|
||||
## References
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* @name Use of a known vulnerable action.
|
||||
* @name Use of a known vulnerable action
|
||||
* @description The workflow is using an action with known vulnerabilities.
|
||||
* @kind problem
|
||||
* @problem.severity error
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/**
|
||||
* @name Workflow does not contain permissions
|
||||
* @description Workflows should contain permissions to provide a clear understanding has permissions to run the workflow.
|
||||
* @description Workflows should contain explicit permissions to restrict the scope of the default GITHUB_TOKEN.
|
||||
* @kind problem
|
||||
* @security-severity 5.0
|
||||
* @problem.severity warning
|
||||
@@ -14,7 +14,19 @@
|
||||
|
||||
import actions
|
||||
|
||||
from Job job
|
||||
Step stepInJob(Job job) { result = job.(LocalJob).getAStep() }
|
||||
|
||||
string jobNeedsPermission(Job job) {
|
||||
actionsPermissionsDataModel(stepInJob(job).(UsesStep).getCallee(), result)
|
||||
}
|
||||
|
||||
/** Gets a suggestion for the minimal token permissions for `job`, as a JSON string. */
|
||||
string permissionsForJob(Job job) {
|
||||
result =
|
||||
"{" + concat(string permission | permission = jobNeedsPermission(job) | permission, ", ") + "}"
|
||||
}
|
||||
|
||||
from Job job, string permissions
|
||||
where
|
||||
not exists(job.getPermissions()) and
|
||||
not exists(job.getEnclosingWorkflow().getPermissions()) and
|
||||
@@ -22,5 +34,8 @@ where
|
||||
exists(Event e |
|
||||
e = job.getATriggerEvent() and
|
||||
not e.getName() = "workflow_call"
|
||||
)
|
||||
select job, "Actions Job or Workflow does not set permissions"
|
||||
) and
|
||||
permissions = permissionsForJob(job)
|
||||
select job,
|
||||
"Actions job or workflow does not limit the permissions of the GITHUB_TOKEN. Consider setting an explicit permissions block, using the following as a minimal starting point: "
|
||||
+ permissions
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
* @description All organization and repository secrets are passed to the workflow runner.
|
||||
* @kind problem
|
||||
* @precision high
|
||||
* @security-severity 5.0
|
||||
* @problem.severity warning
|
||||
* @id actions/excessive-secrets-exposure
|
||||
* @tags actions
|
||||
|
||||
@@ -2,11 +2,11 @@
|
||||
|
||||
## Description
|
||||
|
||||
Secrets derived from other secrets are not know to the workflow runner and therefore not masked unless explicitly registered.
|
||||
Secrets derived from other secrets are not known to the workflow runner, and therefore are not masked unless explicitly registered.
|
||||
|
||||
## Recommendations
|
||||
|
||||
Avoid defining non-plain secrets. For example, do not define a new secret containing a JSON object and then read properties out of it from the workflow since these read values will not be masked by the workflow runner.
|
||||
Avoid defining non-plain secrets. For example, do not define a new secret containing a JSON object and then read properties out of it from the workflow, since these read values will not be masked by the workflow runner.
|
||||
|
||||
## Examples
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* @name Checkout of untrusted code in trusted context
|
||||
* @name Checkout of untrusted code in a privileged context
|
||||
* @description Privileged workflows have read/write access to the base repository and access to secrets.
|
||||
* By explicitly checking out and running the build script from a fork the untrusted code is running in an environment
|
||||
* that is able to push to the base repository and to access secrets.
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
category: fix
|
||||
---
|
||||
* Assigned a `security-severity` to the query `actions/excessive-secrets-exposure`.
|
||||
@@ -1,6 +1,7 @@
|
||||
---
|
||||
category: fix
|
||||
---
|
||||
## 0.5.3
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* Fixed typos in the query and alert titles for the queries
|
||||
`actions/envpath-injection/critical`, `actions/envpath-injection/medium`,
|
||||
`actions/envvar-injection/critical`, and `actions/envvar-injection/medium`.
|
||||
`actions/envvar-injection/critical`, and `actions/envvar-injection/medium`.
|
||||
5
actions/ql/src/change-notes/released/0.5.4.md
Normal file
5
actions/ql/src/change-notes/released/0.5.4.md
Normal file
@@ -0,0 +1,5 @@
|
||||
## 0.5.4
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* Alerts produced by the query `actions/missing-workflow-permissions` now include a minimal set of recommended permissions in the alert message, based on well-known actions seen within the workflow file.
|
||||
@@ -1,2 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 0.5.2
|
||||
lastReleaseVersion: 0.5.4
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql/actions-queries
|
||||
version: 0.5.3-dev
|
||||
version: 0.5.5-dev
|
||||
library: false
|
||||
warnOnImplicitThis: true
|
||||
groups: [actions, queries]
|
||||
|
||||
13
actions/ql/test/query-tests/Security/CWE-275/.github/workflows/perms6.yml
vendored
Normal file
13
actions/ql/test/query-tests/Security/CWE-275/.github/workflows/perms6.yml
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
on:
|
||||
workflow_call:
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Build and test
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/jekyll-build-pages
|
||||
|
||||
|
||||
10
actions/ql/test/query-tests/Security/CWE-275/.github/workflows/perms7.yml
vendored
Normal file
10
actions/ql/test/query-tests/Security/CWE-275/.github/workflows/perms7.yml
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
on:
|
||||
workflow_call:
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Build and test
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/add-to-project@v2
|
||||
@@ -1,3 +1,5 @@
|
||||
| .github/workflows/perms1.yml:6:5:9:32 | Job: build | Actions Job or Workflow does not set permissions |
|
||||
| .github/workflows/perms2.yml:6:5:10:2 | Job: build | Actions Job or Workflow does not set permissions |
|
||||
| .github/workflows/perms5.yml:7:5:10:32 | Job: build | Actions Job or Workflow does not set permissions |
|
||||
| .github/workflows/perms1.yml:6:5:9:32 | Job: build | Actions job or workflow does not limit the permissions of the GITHUB_TOKEN. Consider setting an explicit permissions block, using the following as a minimal starting point: {contents: read} |
|
||||
| .github/workflows/perms2.yml:6:5:10:2 | Job: build | Actions job or workflow does not limit the permissions of the GITHUB_TOKEN. Consider setting an explicit permissions block, using the following as a minimal starting point: {contents: read} |
|
||||
| .github/workflows/perms5.yml:7:5:10:32 | Job: build | Actions job or workflow does not limit the permissions of the GITHUB_TOKEN. Consider setting an explicit permissions block, using the following as a minimal starting point: {contents: read} |
|
||||
| .github/workflows/perms6.yml:7:5:11:39 | Job: build | Actions job or workflow does not limit the permissions of the GITHUB_TOKEN. Consider setting an explicit permissions block, using the following as a minimal starting point: {contents: read, id-token: write, pages: write} |
|
||||
| .github/workflows/perms7.yml:7:5:10:38 | Job: build | Actions job or workflow does not limit the permissions of the GITHUB_TOKEN. Consider setting an explicit permissions block, using the following as a minimal starting point: {} |
|
||||
|
||||
@@ -58,7 +58,19 @@ def file_checksum(filename):
|
||||
with open(filename, 'rb') as file_handle:
|
||||
return hashlib.sha1(file_handle.read()).hexdigest()
|
||||
|
||||
def check_group(group_name, files, master_file_picker, emit_error):
|
||||
def accept_prefix(line1, line2):
|
||||
suffix = line2.removeprefix(line1)
|
||||
return not suffix or suffix.lstrip().startswith("//")
|
||||
|
||||
def equivalent_lines(lines1, lines2):
|
||||
if len(lines1) != len(lines2):
|
||||
return False
|
||||
for line1, line2 in zip(lines1, lines2):
|
||||
if not accept_prefix(line1, line2) and not accept_prefix(line2, line1):
|
||||
return False
|
||||
return True
|
||||
|
||||
def check_group(group_name, files, master_file_picker, emit_error, accept_prefix):
|
||||
extant_files = [f for f in files if path.isfile(f)]
|
||||
if len(extant_files) == 0:
|
||||
emit_error(__file__, 0, "No files found from group '" + group_name + "'.")
|
||||
@@ -70,11 +82,23 @@ def check_group(group_name, files, master_file_picker, emit_error):
|
||||
return
|
||||
|
||||
checksums = {file_checksum(f) for f in extant_files}
|
||||
|
||||
if len(checksums) == 1 and len(extant_files) == len(files):
|
||||
same_lengths = len(extant_files) == len(files)
|
||||
if len(checksums) == 1 and same_lengths:
|
||||
# All files are present and identical.
|
||||
return
|
||||
|
||||
# In this case we also consider files indentical, if
|
||||
# (1) The group only containts two files.
|
||||
# (2) The lines of one file are the same as the lines of another file
|
||||
# modulo comments.
|
||||
if accept_prefix and same_lengths and len(extant_files) == 2:
|
||||
with open(extant_files[0], 'r') as f1:
|
||||
file1_lines = [l.strip('\n\r') for l in f1.readlines()]
|
||||
with open(extant_files[1], 'r') as f2:
|
||||
file2_lines = [l.strip('\n\r') for l in f2.readlines()]
|
||||
if equivalent_lines(file1_lines, file2_lines):
|
||||
return
|
||||
|
||||
master_file = master_file_picker(extant_files)
|
||||
if master_file is None:
|
||||
emit_error(__file__, 0,
|
||||
@@ -139,9 +163,10 @@ def sync_identical_files(emit_error):
|
||||
raise Exception("Bad command line or file not found")
|
||||
chdir_repo_root()
|
||||
load_if_exists('.', 'config/identical-files.json')
|
||||
file_groups.update(csharp_test_files())
|
||||
for group_name, files in csharp_test_files().items():
|
||||
check_group(group_name, files, master_file_picker, emit_error, True)
|
||||
for group_name, files in file_groups.items():
|
||||
check_group(group_name, files, master_file_picker, emit_error)
|
||||
check_group(group_name, files, master_file_picker, emit_error, False)
|
||||
|
||||
def main():
|
||||
sync_identical_files(emit_local_error)
|
||||
|
||||
2446
cpp/downgrades/0f0a390468a5eb43d1dc72937c028070b106bf53/old.dbscheme
Normal file
2446
cpp/downgrades/0f0a390468a5eb43d1dc72937c028070b106bf53/old.dbscheme
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,3 @@
|
||||
description: Add a new predicate `isVla()` to the `ArrayType` class
|
||||
compatibility: full
|
||||
type_is_vla.rel: delete
|
||||
@@ -0,0 +1,11 @@
|
||||
class Expr extends @expr {
|
||||
string toString() { none() }
|
||||
}
|
||||
|
||||
class AggregateLiteral extends Expr, @aggregateliteral {
|
||||
override string toString() { none() }
|
||||
}
|
||||
|
||||
from AggregateLiteral aggregate, Expr initializer, int element_index, int position
|
||||
where aggregate_array_init(aggregate, initializer, element_index, position, _)
|
||||
select aggregate, initializer, element_index, position
|
||||
@@ -0,0 +1,15 @@
|
||||
class Expr extends @expr {
|
||||
string toString() { none() }
|
||||
}
|
||||
|
||||
class AggregateLiteral extends Expr, @aggregateliteral {
|
||||
override string toString() { none() }
|
||||
}
|
||||
|
||||
class MemberVariable extends @membervariable {
|
||||
string toString() { none() }
|
||||
}
|
||||
|
||||
from AggregateLiteral aggregate, Expr initializer, MemberVariable field, int position
|
||||
where aggregate_field_init(aggregate, initializer, field, position, _)
|
||||
select aggregate, initializer, field, position
|
||||
2448
cpp/downgrades/2e2d805ef93d060b813403cb9b51dc72455a4c68/old.dbscheme
Normal file
2448
cpp/downgrades/2e2d805ef93d060b813403cb9b51dc72455a4c68/old.dbscheme
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,4 @@
|
||||
description: add `hasDesignator` predicate to `ArrayOrVectorAggregateLiteral` and `ClassAggregateLiteral`
|
||||
compatibility: backwards
|
||||
aggregate_array_init.rel: run aggregate_array_init.qlo
|
||||
aggregate_field_init.rel: run aggregate_field_init.qlo
|
||||
@@ -1,3 +1,16 @@
|
||||
## 4.2.0
|
||||
|
||||
### New Features
|
||||
|
||||
* Calling conventions explicitly specified on function declarations (`__cdecl`, `__stdcall`, `__fastcall`, etc.) are now represented as specifiers of those declarations.
|
||||
* A new class `CallingConventionSpecifier` extending the `Specifier` class was introduced, which represents explicitly specified calling conventions.
|
||||
|
||||
## 4.1.0
|
||||
|
||||
### New Features
|
||||
|
||||
* Added `Node.asUncertainDefinition` and `Node.asCertainDefinition` to the `DataFlow::Node` class for querying whether a definition overwrites the entire destination buffer.
|
||||
|
||||
## 4.0.3
|
||||
|
||||
No user-facing changes.
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
category: feature
|
||||
---
|
||||
* Added the `isVla()` predicate to the `ArrayType` class. This allows queries to identify variable-length arrays (VLAs).
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
category: feature
|
||||
---
|
||||
* Introduced `hasDesignator()` predicates to distinguish between designated and positional initializations for both struct/union fields and array elements.
|
||||
@@ -1,4 +1,5 @@
|
||||
---
|
||||
category: feature
|
||||
---
|
||||
* Added `Node.asUncertainDefinition` and `Node.asCertainDefinition` to the `DataFlow::Node` class for querying whether a definition overwrites the entire destination buffer.
|
||||
## 4.1.0
|
||||
|
||||
### New Features
|
||||
|
||||
* Added `Node.asUncertainDefinition` and `Node.asCertainDefinition` to the `DataFlow::Node` class for querying whether a definition overwrites the entire destination buffer.
|
||||
6
cpp/ql/lib/change-notes/released/4.2.0.md
Normal file
6
cpp/ql/lib/change-notes/released/4.2.0.md
Normal file
@@ -0,0 +1,6 @@
|
||||
## 4.2.0
|
||||
|
||||
### New Features
|
||||
|
||||
* Calling conventions explicitly specified on function declarations (`__cdecl`, `__stdcall`, `__fastcall`, etc.) are now represented as specifiers of those declarations.
|
||||
* A new class `CallingConventionSpecifier` extending the `Specifier` class was introduced, which represents explicitly specified calling conventions.
|
||||
@@ -1,2 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 4.0.3
|
||||
lastReleaseVersion: 4.2.0
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql/cpp-all
|
||||
version: 4.0.4-dev
|
||||
version: 4.2.1-dev
|
||||
groups: cpp
|
||||
dbscheme: semmlecode.cpp.dbscheme
|
||||
extractor: cpp
|
||||
|
||||
@@ -97,6 +97,18 @@ class AccessSpecifier extends Specifier {
|
||||
override string getAPrimaryQlClass() { result = "AccessSpecifier" }
|
||||
}
|
||||
|
||||
/**
|
||||
* A C/C++ calling convention specifier: `cdecl`, `fastcall`, `stdcall`, `thiscall`,
|
||||
* `vectorcall`, or `clrcall`.
|
||||
*/
|
||||
class CallingConventionSpecifier extends Specifier {
|
||||
CallingConventionSpecifier() {
|
||||
this.hasName(["cdecl", "fastcall", "stdcall", "thiscall", "vectorcall", "clrcall"])
|
||||
}
|
||||
|
||||
override string getAPrimaryQlClass() { result = "CallingConventionSpecifier" }
|
||||
}
|
||||
|
||||
/**
|
||||
* An attribute introduced by GNU's `__attribute__((name))` syntax,
|
||||
* Microsoft's `__declspec(name)` syntax, Microsoft's `[name]` syntax, the
|
||||
|
||||
@@ -1369,6 +1369,11 @@ class ArrayType extends DerivedType {
|
||||
override predicate isDeeplyConst() { this.getBaseType().isDeeplyConst() } // No such thing as a const array type
|
||||
|
||||
override predicate isDeeplyConstBelow() { this.getBaseType().isDeeplyConst() }
|
||||
|
||||
/**
|
||||
* Holds if this array is a variable-length array (VLA).
|
||||
*/
|
||||
predicate isVla() { type_is_vla(underlyingElement(this)) }
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -465,7 +465,7 @@ private predicate isFunctionConstructedFrom(Function f, Function templateFunc) {
|
||||
}
|
||||
|
||||
/** Gets the fully templated version of `f`. */
|
||||
private Function getFullyTemplatedFunction(Function f) {
|
||||
Function getFullyTemplatedFunction(Function f) {
|
||||
not f.isFromUninstantiatedTemplate(_) and
|
||||
(
|
||||
exists(Class c, Class templateClass, int i |
|
||||
@@ -559,12 +559,15 @@ private string getTypeName(Type t, boolean needsSpace) {
|
||||
|
||||
/**
|
||||
* Gets a type name for the `n`'th parameter of `f` without any template
|
||||
* arguments. The result may be a string representing a type for which the
|
||||
* typedefs have been resolved.
|
||||
* arguments.
|
||||
*
|
||||
* If `canonical = false` then the result may be a string representing a type
|
||||
* for which the typedefs have been resolved. If `canonical = true` then the
|
||||
* result will be a string representing a type without resolving `typedefs`.
|
||||
*/
|
||||
bindingset[f]
|
||||
pragma[inline_late]
|
||||
string getParameterTypeWithoutTemplateArguments(Function f, int n) {
|
||||
string getParameterTypeWithoutTemplateArguments(Function f, int n, boolean canonical) {
|
||||
exists(string s, string base, string specifiers, Type t |
|
||||
t = f.getParameter(n).getType() and
|
||||
// The name of the string can either be the possibly typedefed name
|
||||
@@ -572,14 +575,19 @@ string getParameterTypeWithoutTemplateArguments(Function f, int n) {
|
||||
// `getTypeName(t, _)` is almost equal to `t.resolveTypedefs().getName()`,
|
||||
// except that `t.resolveTypedefs()` doesn't have a result when the
|
||||
// resulting type doesn't appear in the database.
|
||||
s = [t.getName(), getTypeName(t, _)] and
|
||||
(
|
||||
s = t.getName() and canonical = true
|
||||
or
|
||||
s = getTypeName(t, _) and canonical = false
|
||||
) and
|
||||
parseAngles(s, base, _, specifiers) and
|
||||
result = base + specifiers
|
||||
)
|
||||
or
|
||||
f.isVarargs() and
|
||||
n = f.getNumberOfParameters() and
|
||||
result = "..."
|
||||
result = "..." and
|
||||
canonical = true
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -590,7 +598,7 @@ private string getTypeNameWithoutFunctionTemplates(Function f, int n, int remain
|
||||
exists(Function templateFunction |
|
||||
templateFunction = getFullyTemplatedFunction(f) and
|
||||
remaining = templateFunction.getNumberOfTemplateArguments() and
|
||||
result = getParameterTypeWithoutTemplateArguments(templateFunction, n)
|
||||
result = getParameterTypeWithoutTemplateArguments(templateFunction, n, _)
|
||||
)
|
||||
or
|
||||
exists(string mid, TypeTemplateParameter tp, Function templateFunction |
|
||||
@@ -627,7 +635,7 @@ private string getTypeNameWithoutClassTemplates(Function f, int n, int remaining
|
||||
}
|
||||
|
||||
/** Gets the string representation of the `i`'th parameter of `c`. */
|
||||
private string getParameterTypeName(Function c, int i) {
|
||||
string getParameterTypeName(Function c, int i) {
|
||||
result = getTypeNameWithoutClassTemplates(c, i, 0)
|
||||
}
|
||||
|
||||
|
||||
@@ -213,7 +213,24 @@ class ClassAggregateLiteral extends AggregateLiteral {
|
||||
Expr getFieldExpr(Field field, int position) {
|
||||
field = classType.getAField() and
|
||||
aggregate_field_init(underlyingElement(this), unresolveElement(result), unresolveElement(field),
|
||||
position)
|
||||
position, _)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if the `position`-th initialization of `field` in this aggregate initializer
|
||||
* uses a designated (e.g., `.x = ...`) rather than a positional initializer.
|
||||
*
|
||||
* For example, in:
|
||||
* ```c
|
||||
* struct S { int x, y; };
|
||||
* struct S s = { .x = 1, 2 };
|
||||
* ```
|
||||
* - `.x = 1` is a designated initializer, therefore `hasDesignator(x, 0)` holds.
|
||||
* - `2` is a positional initializer for `s.y`, therefore `hasDesignator(y, 1)` does not hold.
|
||||
*/
|
||||
predicate hasDesignator(Field field, int position) {
|
||||
field = classType.getAField() and
|
||||
aggregate_field_init(underlyingElement(this), _, unresolveElement(field), position, true)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -304,7 +321,24 @@ class ArrayOrVectorAggregateLiteral extends AggregateLiteral {
|
||||
* - `a.getElementExpr(0, 2)` gives `789`.
|
||||
*/
|
||||
Expr getElementExpr(int elementIndex, int position) {
|
||||
aggregate_array_init(underlyingElement(this), unresolveElement(result), elementIndex, position)
|
||||
aggregate_array_init(underlyingElement(this), unresolveElement(result), elementIndex, position,
|
||||
_)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if the `position`-th initialization of the array element at `elementIndex`
|
||||
* in this aggregate initializer uses a designated (e.g., `[0] = ...`) rather than
|
||||
* a positional initializer.
|
||||
*
|
||||
* For example, in:
|
||||
* ```c
|
||||
* int x[] = { [0] = 1, 2 };
|
||||
* ```
|
||||
* - `[0] = 1` is a designated initializer, therefore `hasDesignator(0, 0)` holds.
|
||||
* - `2` is a positional initializer for `x[1]`, therefore `hasDesignator(1, 1)` does not hold.
|
||||
*/
|
||||
predicate hasDesignator(int elementIndex, int position) {
|
||||
aggregate_array_init(underlyingElement(this), _, elementIndex, position, true)
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -371,7 +371,7 @@ private class PrimaryArgumentNode extends ArgumentNode, OperandNode {
|
||||
PrimaryArgumentNode() { exists(CallInstruction call | op = call.getAnArgumentOperand()) }
|
||||
|
||||
override predicate argumentOf(DataFlowCall call, ArgumentPosition pos) {
|
||||
op = call.getArgumentOperand(pos.(DirectPosition).getIndex())
|
||||
op = call.getArgumentOperand(pos.(DirectPosition).getArgumentIndex())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -410,8 +410,16 @@ class ParameterPosition = Position;
|
||||
class ArgumentPosition = Position;
|
||||
|
||||
abstract class Position extends TPosition {
|
||||
/** Gets a textual representation of this position. */
|
||||
abstract string toString();
|
||||
|
||||
/**
|
||||
* Gets the argument index of this position. The qualifier of a call has
|
||||
* argument index `-1`.
|
||||
*/
|
||||
abstract int getArgumentIndex();
|
||||
|
||||
/** Gets the indirection index of this position. */
|
||||
abstract int getIndirectionIndex();
|
||||
}
|
||||
|
||||
@@ -428,7 +436,7 @@ class DirectPosition extends Position, TDirectPosition {
|
||||
result = index.toString()
|
||||
}
|
||||
|
||||
int getIndex() { result = index }
|
||||
override int getArgumentIndex() { result = index }
|
||||
|
||||
final override int getIndirectionIndex() { result = 0 }
|
||||
}
|
||||
@@ -445,16 +453,29 @@ class IndirectionPosition extends Position, TIndirectionPosition {
|
||||
else result = repeatStars(indirectionIndex) + argumentIndex.toString()
|
||||
}
|
||||
|
||||
int getArgumentIndex() { result = argumentIndex }
|
||||
override int getArgumentIndex() { result = argumentIndex }
|
||||
|
||||
final override int getIndirectionIndex() { result = indirectionIndex }
|
||||
}
|
||||
|
||||
newtype TPosition =
|
||||
TDirectPosition(int argumentIndex) { exists(any(CallInstruction c).getArgument(argumentIndex)) } or
|
||||
TDirectPosition(int argumentIndex) {
|
||||
exists(any(CallInstruction c).getArgument(argumentIndex))
|
||||
or
|
||||
// Handle the rare case where there is a function definition but no call to
|
||||
// the function.
|
||||
exists(any(Cpp::Function f).getParameter(argumentIndex))
|
||||
} or
|
||||
TIndirectionPosition(int argumentIndex, int indirectionIndex) {
|
||||
Ssa::hasIndirectOperand(any(CallInstruction call).getArgumentOperand(argumentIndex),
|
||||
indirectionIndex)
|
||||
or
|
||||
// Handle the rare case where there is a function definition but no call to
|
||||
// the function.
|
||||
exists(Cpp::Function f, Cpp::Parameter p |
|
||||
p = f.getParameter(argumentIndex) and
|
||||
indirectionIndex = [1 .. Ssa::getMaxIndirectionsForType(p.getUnspecifiedType()) - 1]
|
||||
)
|
||||
}
|
||||
|
||||
private newtype TReturnKind =
|
||||
@@ -501,6 +522,15 @@ class ReturnKind extends TReturnKind {
|
||||
|
||||
/** Gets a textual representation of this return kind. */
|
||||
abstract string toString();
|
||||
|
||||
/** Holds if this `ReturnKind` is generated from a `return` statement. */
|
||||
abstract predicate isNormalReturn();
|
||||
|
||||
/**
|
||||
* Holds if this `ReturnKind` is generated from a write to the parameter with
|
||||
* index `argumentIndex`
|
||||
*/
|
||||
abstract predicate isIndirectReturn(int argumentIndex);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -514,6 +544,10 @@ class NormalReturnKind extends ReturnKind, TNormalReturnKind {
|
||||
override int getIndirectionIndex() { result = indirectionIndex }
|
||||
|
||||
override string toString() { result = "indirect return" }
|
||||
|
||||
override predicate isNormalReturn() { any() }
|
||||
|
||||
override predicate isIndirectReturn(int argumentIndex) { none() }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -528,6 +562,10 @@ private class IndirectReturnKind extends ReturnKind, TIndirectReturnKind {
|
||||
override int getIndirectionIndex() { result = indirectionIndex }
|
||||
|
||||
override string toString() { result = "indirect outparam[" + argumentIndex.toString() + "]" }
|
||||
|
||||
override predicate isNormalReturn() { none() }
|
||||
|
||||
override predicate isIndirectReturn(int argumentIndex_) { argumentIndex_ = argumentIndex }
|
||||
}
|
||||
|
||||
/** A data flow node that occurs as the result of a `ReturnStmt`. */
|
||||
@@ -1834,7 +1872,47 @@ module IteratorFlow {
|
||||
|
||||
private module IteratorSsa = SsaImpl::Make<Location, SsaInput>;
|
||||
|
||||
private class Def extends IteratorSsa::DefinitionExt {
|
||||
private module DataFlowIntegrationInput implements IteratorSsa::DataFlowIntegrationInputSig {
|
||||
private import codeql.util.Void
|
||||
|
||||
class Expr extends Instruction {
|
||||
Expr() {
|
||||
exists(IRBlock bb, int i |
|
||||
SsaInput::variableRead(bb, i, _, true) and
|
||||
this = bb.getInstruction(i)
|
||||
)
|
||||
}
|
||||
|
||||
predicate hasCfgNode(SsaInput::BasicBlock bb, int i) { bb.getInstruction(i) = this }
|
||||
}
|
||||
|
||||
predicate ssaDefHasSource(IteratorSsa::WriteDefinition def) { none() }
|
||||
|
||||
predicate allowFlowIntoUncertainDef(IteratorSsa::UncertainWriteDefinition def) { any() }
|
||||
|
||||
class Guard extends Void {
|
||||
predicate controlsBranchEdge(
|
||||
SsaInput::BasicBlock bb1, SsaInput::BasicBlock bb2, boolean branch
|
||||
) {
|
||||
none()
|
||||
}
|
||||
}
|
||||
|
||||
predicate guardDirectlyControlsBlock(Guard guard, SsaInput::BasicBlock bb, boolean branch) {
|
||||
none()
|
||||
}
|
||||
|
||||
predicate supportBarrierGuardsOnPhiEdges() { none() }
|
||||
}
|
||||
|
||||
private module DataFlowIntegrationImpl =
|
||||
IteratorSsa::DataFlowIntegration<DataFlowIntegrationInput>;
|
||||
|
||||
private class IteratorSynthNode extends DataFlowIntegrationImpl::SsaNode {
|
||||
IteratorSynthNode() { not this.asDefinition() instanceof IteratorSsa::WriteDefinition }
|
||||
}
|
||||
|
||||
private class Def extends IteratorSsa::Definition {
|
||||
final override Location getLocation() { result = this.getImpl().getLocation() }
|
||||
|
||||
/**
|
||||
@@ -1842,7 +1920,7 @@ module IteratorFlow {
|
||||
* and is a definition (or use) of the variable `sv`.
|
||||
*/
|
||||
predicate hasIndexInBlock(IRBlock block, int index, SourceVariable sv) {
|
||||
super.definesAt(sv, block, index, _)
|
||||
super.definesAt(sv, block, index)
|
||||
}
|
||||
|
||||
private Ssa::DefImpl getImpl() {
|
||||
@@ -1859,46 +1937,15 @@ module IteratorFlow {
|
||||
int getIndirectionIndex() { result = this.getImpl().getIndirectionIndex() }
|
||||
}
|
||||
|
||||
private class PhiNode extends IteratorSsa::DefinitionExt {
|
||||
PhiNode() {
|
||||
this instanceof IteratorSsa::PhiNode or
|
||||
this instanceof IteratorSsa::PhiReadNode
|
||||
}
|
||||
|
||||
SsaIteratorNode getNode() { result.getIteratorFlowNode() = this }
|
||||
}
|
||||
|
||||
cached
|
||||
private module IteratorSsaCached {
|
||||
cached
|
||||
predicate adjacentDefRead(IRBlock bb1, int i1, SourceVariable sv, IRBlock bb2, int i2) {
|
||||
IteratorSsa::adjacentDefReadExt(_, sv, bb1, i1, bb2, i2)
|
||||
or
|
||||
exists(PhiNode phi |
|
||||
IteratorSsa::lastRefRedefExt(_, sv, bb1, i1, phi) and
|
||||
phi.definesAt(sv, bb2, i2, _)
|
||||
)
|
||||
}
|
||||
|
||||
cached
|
||||
Node getAPriorDefinition(IteratorSsa::DefinitionExt next) {
|
||||
exists(IRBlock bb, int i, SourceVariable sv, IteratorSsa::DefinitionExt def |
|
||||
IteratorSsa::lastRefRedefExt(pragma[only_bind_into](def), pragma[only_bind_into](sv),
|
||||
pragma[only_bind_into](bb), pragma[only_bind_into](i), next) and
|
||||
nodeToDefOrUse(result, sv, bb, i, _)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/** The set of nodes necessary for iterator flow. */
|
||||
class IteratorFlowNode instanceof PhiNode {
|
||||
class IteratorFlowNode instanceof IteratorSynthNode {
|
||||
/** Gets a textual representation of this node. */
|
||||
string toString() { result = super.toString() }
|
||||
|
||||
/** Gets the type of this node. */
|
||||
DataFlowType getType() {
|
||||
exists(Ssa::SourceVariable sv |
|
||||
super.definesAt(sv, _, _, _) and
|
||||
super.getSourceVariable() = sv and
|
||||
result = sv.getType()
|
||||
)
|
||||
}
|
||||
@@ -1910,60 +1957,33 @@ module IteratorFlow {
|
||||
Location getLocation() { result = super.getBasicBlock().getLocation() }
|
||||
}
|
||||
|
||||
private import IteratorSsaCached
|
||||
|
||||
private predicate defToNode(Node node, Def def, boolean uncertain) {
|
||||
(
|
||||
nodeHasOperand(node, def.getValue().asOperand(), def.getIndirectionIndex())
|
||||
or
|
||||
nodeHasInstruction(node, def.getValue().asInstruction(), def.getIndirectionIndex())
|
||||
) and
|
||||
uncertain = false
|
||||
private predicate defToNode(Node node, Def def) {
|
||||
nodeHasOperand(node, def.getValue().asOperand(), def.getIndirectionIndex())
|
||||
or
|
||||
nodeHasInstruction(node, def.getValue().asInstruction(), def.getIndirectionIndex())
|
||||
}
|
||||
|
||||
private predicate nodeToDefOrUse(
|
||||
Node node, SourceVariable sv, IRBlock bb, int i, boolean uncertain
|
||||
) {
|
||||
exists(Def def |
|
||||
def.hasIndexInBlock(bb, i, sv) and
|
||||
defToNode(node, def, uncertain)
|
||||
bindingset[result, v]
|
||||
pragma[inline_late]
|
||||
private DataFlowIntegrationImpl::Node fromDfNode(Node n, SourceVariable v) {
|
||||
result = n.(SsaIteratorNode).getIteratorFlowNode()
|
||||
or
|
||||
exists(Ssa::UseImpl use, IRBlock bb, int i |
|
||||
result.(DataFlowIntegrationImpl::ExprNode).getExpr().hasCfgNode(bb, i) and
|
||||
use.hasIndexInBlock(bb, i, v) and
|
||||
use.getNode() = n
|
||||
)
|
||||
or
|
||||
useToNode(bb, i, sv, node) and
|
||||
uncertain = false
|
||||
}
|
||||
|
||||
private predicate useToNode(IRBlock bb, int i, SourceVariable sv, Node nodeTo) {
|
||||
exists(PhiNode phi |
|
||||
phi.definesAt(sv, bb, i, _) and
|
||||
nodeTo = phi.getNode()
|
||||
)
|
||||
or
|
||||
exists(Ssa::UseImpl use |
|
||||
use.hasIndexInBlock(bb, i, sv) and
|
||||
nodeTo = use.getNode()
|
||||
)
|
||||
defToNode(n, result.(DataFlowIntegrationImpl::SsaDefinitionNode).getDefinition())
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `nodeFrom` flows to `nodeTo` in a single step.
|
||||
*/
|
||||
predicate localFlowStep(Node nodeFrom, Node nodeTo) {
|
||||
exists(
|
||||
Node nFrom, SourceVariable sv, IRBlock bb1, int i1, IRBlock bb2, int i2, boolean uncertain
|
||||
|
|
||||
adjacentDefRead(bb1, i1, sv, bb2, i2) and
|
||||
nodeToDefOrUse(nFrom, sv, bb1, i1, uncertain) and
|
||||
useToNode(bb2, i2, sv, nodeTo)
|
||||
|
|
||||
if uncertain = true
|
||||
then
|
||||
nodeFrom =
|
||||
[
|
||||
nFrom,
|
||||
getAPriorDefinition(any(IteratorSsa::DefinitionExt next | next.definesAt(sv, bb1, i1, _)))
|
||||
]
|
||||
else nFrom = nodeFrom
|
||||
exists(SourceVariable v |
|
||||
nodeFrom != nodeTo and
|
||||
DataFlowIntegrationImpl::localFlowStep(v, fromDfNode(nodeFrom, v), fromDfNode(nodeTo, v), _)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1445,7 +1445,7 @@ private class ExplicitParameterInstructionNode extends AbstractExplicitParameter
|
||||
ExplicitParameterInstructionNode() { exists(instr.getParameter()) }
|
||||
|
||||
override predicate isSourceParameterOf(Function f, ParameterPosition pos) {
|
||||
f.getParameter(pos.(DirectPosition).getIndex()) = instr.getParameter()
|
||||
f.getParameter(pos.(DirectPosition).getArgumentIndex()) = instr.getParameter()
|
||||
}
|
||||
|
||||
override string toStringImpl() { result = instr.getParameter().toString() }
|
||||
@@ -1460,7 +1460,7 @@ class ThisParameterInstructionNode extends AbstractExplicitParameterNode,
|
||||
ThisParameterInstructionNode() { instr.getIRVariable() instanceof IRThisVariable }
|
||||
|
||||
override predicate isSourceParameterOf(Function f, ParameterPosition pos) {
|
||||
pos.(DirectPosition).getIndex() = -1 and
|
||||
pos.(DirectPosition).getArgumentIndex() = -1 and
|
||||
instr.getEnclosingFunction() = f
|
||||
}
|
||||
|
||||
@@ -1494,7 +1494,7 @@ private class DirectBodyLessParameterNode extends AbstractExplicitParameterNode,
|
||||
|
||||
override predicate isSourceParameterOf(Function f, ParameterPosition pos) {
|
||||
this.getFunction() = f and
|
||||
f.getParameter(pos.(DirectPosition).getIndex()) = p
|
||||
f.getParameter(pos.(DirectPosition).getArgumentIndex()) = p
|
||||
}
|
||||
|
||||
override Parameter getParameter() { result = p }
|
||||
|
||||
@@ -956,8 +956,6 @@ class GlobalDef extends Definition {
|
||||
private module SsaImpl = SsaImplCommon::Make<Location, SsaInput>;
|
||||
|
||||
private module DataFlowIntegrationInput implements SsaImpl::DataFlowIntegrationInputSig {
|
||||
private import codeql.util.Void
|
||||
|
||||
class Expr extends Instruction {
|
||||
Expr() {
|
||||
exists(IRBlock bb, int i |
|
||||
@@ -977,13 +975,7 @@ private module DataFlowIntegrationInput implements SsaImpl::DataFlowIntegrationI
|
||||
)
|
||||
}
|
||||
|
||||
predicate ssaDefAssigns(SsaImpl::WriteDefinition def, Expr value) { none() }
|
||||
|
||||
class Parameter extends Void {
|
||||
Location getLocation() { none() }
|
||||
}
|
||||
|
||||
predicate ssaDefInitializesParam(SsaImpl::WriteDefinition def, Parameter p) { none() }
|
||||
predicate ssaDefHasSource(SsaImpl::WriteDefinition def) { none() }
|
||||
|
||||
predicate allowFlowIntoUncertainDef(SsaImpl::UncertainWriteDefinition def) { any() }
|
||||
|
||||
@@ -1007,9 +999,11 @@ private module DataFlowIntegrationInput implements SsaImpl::DataFlowIntegrationI
|
||||
}
|
||||
}
|
||||
|
||||
predicate guardControlsBlock(Guard guard, SsaInput::BasicBlock bb, boolean branch) {
|
||||
predicate guardDirectlyControlsBlock(Guard guard, SsaInput::BasicBlock bb, boolean branch) {
|
||||
guard.(IRGuards::IRGuardCondition).controls(bb, branch)
|
||||
}
|
||||
|
||||
predicate keepAllPhiInputBackEdges() { any() }
|
||||
}
|
||||
|
||||
private module DataFlowIntegrationImpl = SsaImpl::DataFlowIntegration<DataFlowIntegrationInput>;
|
||||
@@ -1075,7 +1069,7 @@ module BarrierGuard<guardChecksNodeSig/3 guardChecksNode> {
|
||||
|
||||
bindingset[result, v]
|
||||
pragma[inline_late]
|
||||
DataFlowIntegrationImpl::Node fromDfNode(Node n, SourceVariable v) {
|
||||
private DataFlowIntegrationImpl::Node fromDfNode(Node n, SourceVariable v) {
|
||||
result = n.(SsaSynthNode).getSynthNode()
|
||||
or
|
||||
exists(UseImpl use, IRBlock bb, int i |
|
||||
|
||||
@@ -229,11 +229,11 @@ private module SpeculativeTaintFlow {
|
||||
not exists(DataFlowDispatch::viableCallable(call)) and
|
||||
src.(DataFlowPrivate::ArgumentNode).argumentOf(call, argpos)
|
||||
|
|
||||
not argpos.(DirectPosition).getIndex() = -1 and
|
||||
not argpos.(DirectPosition).getArgumentIndex() = -1 and
|
||||
sink.(PostUpdateNode)
|
||||
.getPreUpdateNode()
|
||||
.(DataFlowPrivate::ArgumentNode)
|
||||
.argumentOf(call, any(DirectPosition qualpos | qualpos.getIndex() = -1))
|
||||
.argumentOf(call, any(DirectPosition qualpos | qualpos.getArgumentIndex() = -1))
|
||||
or
|
||||
sink.(DataFlowPrivate::OutNode).getCall() = call
|
||||
)
|
||||
|
||||
@@ -2039,7 +2039,8 @@ aggregate_field_init(
|
||||
int aggregate: @aggregateliteral ref,
|
||||
int initializer: @expr ref,
|
||||
int field: @membervariable ref,
|
||||
int position: int ref
|
||||
int position: int ref,
|
||||
boolean is_designated: boolean ref
|
||||
);
|
||||
|
||||
/**
|
||||
@@ -2051,7 +2052,8 @@ aggregate_array_init(
|
||||
int aggregate: @aggregateliteral ref,
|
||||
int initializer: @expr ref,
|
||||
int element_index: int ref,
|
||||
int position: int ref
|
||||
int position: int ref,
|
||||
boolean is_designated: boolean ref
|
||||
);
|
||||
|
||||
@ctorinit = @ctordirectinit
|
||||
@@ -2178,6 +2180,8 @@ variable_vla(
|
||||
int decl: @stmt_vla_decl ref
|
||||
);
|
||||
|
||||
type_is_vla(unique int type_id: @derivedtype ref)
|
||||
|
||||
if_initialization(
|
||||
unique int if_stmt: @stmt_if ref,
|
||||
int init_id: @stmt ref
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,11 @@
|
||||
class Expr extends @expr {
|
||||
string toString() { none() }
|
||||
}
|
||||
|
||||
class AggregateLiteral extends Expr, @aggregateliteral {
|
||||
override string toString() { none() }
|
||||
}
|
||||
|
||||
from AggregateLiteral aggregate, Expr initializer, int element_index, int position
|
||||
where aggregate_array_init(aggregate, initializer, element_index, position)
|
||||
select aggregate, initializer, element_index, position, false
|
||||
@@ -0,0 +1,15 @@
|
||||
class Expr extends @expr {
|
||||
string toString() { none() }
|
||||
}
|
||||
|
||||
class AggregateLiteral extends Expr, @aggregateliteral {
|
||||
override string toString() { none() }
|
||||
}
|
||||
|
||||
class MemberVariable extends @membervariable {
|
||||
string toString() { none() }
|
||||
}
|
||||
|
||||
from AggregateLiteral aggregate, Expr initializer, MemberVariable field, int position
|
||||
where aggregate_field_init(aggregate, initializer, field, position)
|
||||
select aggregate, initializer, field, position, false
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,4 @@
|
||||
description: add `hasDesignator` predicate to `ArrayOrVectorAggregateLiteral` and `ClassAggregateLiteral`
|
||||
compatibility: backwards
|
||||
aggregate_array_init.rel: run aggregate_array_init.qlo
|
||||
aggregate_field_init.rel: run aggregate_field_init.qlo
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,2 @@
|
||||
description: Add a new predicate `isVla()` to the `ArrayType` class
|
||||
compatibility: backwards
|
||||
@@ -1,3 +1,14 @@
|
||||
## 1.3.8
|
||||
|
||||
No user-facing changes.
|
||||
|
||||
## 1.3.7
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
* Fixed a bug in the models for Microsoft's Active Template Library (ATL).
|
||||
* The query "Use of basic integral type" (`cpp/jpl-c/basic-int-types`) no longer produces alerts for the standard fixed width integer types (`int8_t`, `uint8_t`, etc.), and the `_Bool` and `bool` types.
|
||||
|
||||
## 1.3.6
|
||||
|
||||
No user-facing changes.
|
||||
|
||||
@@ -14,5 +14,5 @@ where
|
||||
or
|
||||
warning instanceof ExtractionUnknownProblem
|
||||
select warning,
|
||||
"Extraction failed in " + warning.getFile() + " with warning " + warning.getProblemMessage(),
|
||||
warning.getSeverity()
|
||||
"Extraction failed in " + warning.getFile() + " with warning " +
|
||||
warning.getProblemMessage().replaceAll("$", "$$"), warning.getSeverity()
|
||||
|
||||
@@ -17,5 +17,6 @@ from ExtractionError error
|
||||
where
|
||||
error instanceof ExtractionUnknownError or
|
||||
exists(error.getFile().getRelativePath())
|
||||
select error, "Extraction failed in " + error.getFile() + " with error " + error.getErrorMessage(),
|
||||
error.getSeverity()
|
||||
select error,
|
||||
"Extraction failed in " + error.getFile() + " with error " +
|
||||
error.getErrorMessage().replaceAll("$", "$$"), error.getSeverity()
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* Fixed a bug in the models for Microsoft's Active Template Library (ATL).
|
||||
@@ -1,4 +1,6 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* The query "Use of basic integral type" (`cpp/jpl-c/basic-int-types`) no longer produces alerts for the standard fixed width integer types (`int8_t`, `uint8_t`, etc.), and the `_Bool` and `bool` types.
|
||||
## 1.3.7
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
* Fixed a bug in the models for Microsoft's Active Template Library (ATL).
|
||||
* The query "Use of basic integral type" (`cpp/jpl-c/basic-int-types`) no longer produces alerts for the standard fixed width integer types (`int8_t`, `uint8_t`, etc.), and the `_Bool` and `bool` types.
|
||||
3
cpp/ql/src/change-notes/released/1.3.8.md
Normal file
3
cpp/ql/src/change-notes/released/1.3.8.md
Normal file
@@ -0,0 +1,3 @@
|
||||
## 1.3.8
|
||||
|
||||
No user-facing changes.
|
||||
@@ -1,2 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 1.3.6
|
||||
lastReleaseVersion: 1.3.8
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user