Compare commits

..

1 Commits

Author SHA1 Message Date
dependabot[bot]
195d87c7ef Bump rules_nodejs from 6.7.3 to 6.7.4
Bumps [rules_nodejs](https://github.com/bazel-contrib/rules_nodejs) from 6.7.3 to 6.7.4.
- [Release notes](https://github.com/bazel-contrib/rules_nodejs/releases)
- [Changelog](https://github.com/bazel-contrib/rules_nodejs/blob/main/CHANGELOG.md)
- [Commits](https://github.com/bazel-contrib/rules_nodejs/compare/v6.7.3...v6.7.4)

---
updated-dependencies:
- dependency-name: rules_nodejs
  dependency-version: 6.7.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-04-16 03:08:28 +00:00
1210 changed files with 93708 additions and 145776 deletions

View File

@@ -70,7 +70,7 @@ jobs:
SHORTNAME=`basename $DATABASE`
python misc/scripts/models-as-data/generate_mad.py --language java --with-summaries --with-sinks $DATABASE $SHORTNAME/$QL_VARIANT
mkdir -p $MODELS/$SHORTNAME
mv java/ql/lib/ext/generated/modelgenerator/$SHORTNAME/$QL_VARIANT $MODELS/$SHORTNAME
mv java/ql/lib/ext/generated/$SHORTNAME/$QL_VARIANT $MODELS/$SHORTNAME
cd ..
}

View File

@@ -5,7 +5,7 @@ on:
paths:
- "misc/bazel/**"
- "misc/codegen/**"
- "misc/scripts/models-as-data/*.py"
- "misc/scripts/models-as-data/bulk_generate_mad.py"
- "*.bazel*"
- .github/workflows/codegen.yml
- .pre-commit-config.yaml

75
Cargo.lock generated
View File

@@ -240,9 +240,9 @@ dependencies = [
[[package]]
name = "cc"
version = "1.2.61"
version = "1.2.37"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d16d90359e986641506914ba71350897565610e87ce0ad9e6f28569db3dd5c6d"
checksum = "65193589c6404eb80b450d618eaf9a2cafaaafd57ecce47370519ef674a7bd44"
dependencies = [
"find-msvc-tools",
"jobserver",
@@ -416,7 +416,6 @@ dependencies = [
"tree-sitter",
"tree-sitter-json",
"tree-sitter-ql",
"yeast",
"zstd",
]
@@ -438,25 +437,6 @@ dependencies = [
"tree-sitter-ruby",
]
[[package]]
name = "codeql-extractor-unified"
version = "0.1.0"
dependencies = [
"clap",
"codeql-extractor",
"encoding",
"lazy_static",
"rayon",
"regex",
"serde_json",
"tracing",
"tracing-subscriber",
"tree-sitter",
"tree-sitter-embedded-template",
"tree-sitter-swift",
"yeast",
]
[[package]]
name = "codeql-rust"
version = "0.1.0"
@@ -774,9 +754,9 @@ dependencies = [
[[package]]
name = "find-msvc-tools"
version = "0.1.9"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582"
checksum = "7fd99930f64d146689264c637b5af2f0233a933bef0d8570e2526bf9e083192d"
[[package]]
name = "fixedbitset"
@@ -2873,9 +2853,9 @@ dependencies = [
[[package]]
name = "tree-sitter"
version = "0.26.8"
version = "0.25.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "887bd495d0582c5e3e0d8ece2233666169fa56a9644d172fc22ad179ab2d0538"
checksum = "ccd2a058a86cfece0bf96f7cce1021efef9c8ed0e892ab74639173e5ed7a34fa"
dependencies = [
"cc",
"regex",
@@ -2911,16 +2891,6 @@ version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c4013970217383f67b18aef68f6fb2e8d409bc5755227092d32efb0422ba24b8"
[[package]]
name = "tree-sitter-python"
version = "0.23.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3d065aaa27f3aaceaf60c1f0e0ac09e1cb9eb8ed28e7bcdaa52129cffc7f4b04"
dependencies = [
"cc",
"tree-sitter-language",
]
[[package]]
name = "tree-sitter-ql"
version = "0.23.1"
@@ -2941,16 +2911,6 @@ dependencies = [
"tree-sitter-language",
]
[[package]]
name = "tree-sitter-swift"
version = "0.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f3b98fb6bc8e6a6a10023f401aa6a1858115e849dfaf7de57dd8b8ea0f257bd9"
dependencies = [
"cc",
"tree-sitter-language",
]
[[package]]
name = "triomphe"
version = "0.1.14"
@@ -3407,29 +3367,6 @@ version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cfe53a6657fd280eaa890a3bc59152892ffa3e30101319d168b781ed6529b049"
[[package]]
name = "yeast"
version = "0.1.0"
dependencies = [
"clap",
"serde",
"serde_json",
"serde_yaml",
"tree-sitter",
"tree-sitter-python",
"tree-sitter-ruby",
"yeast-macros",
]
[[package]]
name = "yeast-macros"
version = "0.1.0"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "yoke"
version = "0.8.0"

View File

@@ -4,10 +4,7 @@
resolver = "2"
members = [
"shared/tree-sitter-extractor",
"shared/yeast",
"shared/yeast-macros",
"ruby/extractor",
"unified/extractor",
"rust/extractor",
"rust/extractor/macros",
"rust/ast-generator",

View File

@@ -19,7 +19,7 @@ bazel_dep(name = "rules_cc", version = "0.2.17")
bazel_dep(name = "rules_go", version = "0.60.0")
bazel_dep(name = "rules_java", version = "9.6.1")
bazel_dep(name = "rules_pkg", version = "1.2.0")
bazel_dep(name = "rules_nodejs", version = "6.7.3")
bazel_dep(name = "rules_nodejs", version = "6.7.4")
bazel_dep(name = "rules_python", version = "1.9.0")
bazel_dep(name = "rules_shell", version = "0.7.1")
bazel_dep(name = "bazel_skylib", version = "1.9.0")
@@ -141,19 +141,16 @@ use_repo(
"vendor_ts__serde-1.0.228",
"vendor_ts__serde_json-1.0.145",
"vendor_ts__serde_with-3.14.1",
"vendor_ts__serde_yaml-0.9.34-deprecated",
"vendor_ts__syn-2.0.106",
"vendor_ts__toml-0.9.7",
"vendor_ts__tracing-0.1.41",
"vendor_ts__tracing-flame-0.2.0",
"vendor_ts__tracing-subscriber-0.3.20",
"vendor_ts__tree-sitter-0.26.8",
"vendor_ts__tree-sitter-0.25.9",
"vendor_ts__tree-sitter-embedded-template-0.25.0",
"vendor_ts__tree-sitter-json-0.24.8",
"vendor_ts__tree-sitter-python-0.23.6",
"vendor_ts__tree-sitter-ql-0.23.1",
"vendor_ts__tree-sitter-ruby-0.23.1",
"vendor_ts__tree-sitter-swift-0.7.2",
"vendor_ts__triomphe-0.1.14",
"vendor_ts__ungrammar-1.16.1",
"vendor_ts__zstd-0.13.3",

View File

@@ -1,13 +1,3 @@
## 0.4.35
No user-facing changes.
## 0.4.34
### Minor Analysis Improvements
* Removed false positive injection sink models for the `context` input of `docker/build-push-action` and the `allowed-endpoints` input of `step-security/harden-runner`.
## 0.4.33
No user-facing changes.

View File

@@ -1,4 +0,0 @@
---
category: minorAnalysis
---
* Altered 2 patterns in the `poisonable_steps` modelling. Extra sinks are detected in the following cases: scripts executed via python modules and `go run` in directories are detected as potential mechanisms of injection. For the go execution pattern, the pattern is updated to now ignore flags that occur between go and the specific command. This change may lead to more results being detected by the following queries: `actions/untrusted-checkout/high`, `actions/untrusted-checkout/critical`, `actions/untrusted-checkout-toctou/high`, `actions/untrusted-checkout-toctou/critical`, `actions/cache-poisoning/poisonable-step`, `actions/cache-poisoning/direct-cache` and `actions/artifact-poisoning/path-traversal`.

View File

@@ -1,5 +0,0 @@
## 0.4.34
### Minor Analysis Improvements
* Removed false positive injection sink models for the `context` input of `docker/build-push-action` and the `allowed-endpoints` input of `step-security/harden-runner`.

View File

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

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 0.4.35
lastReleaseVersion: 0.4.33

View File

@@ -70,7 +70,7 @@ extensions:
- ["(source|sh|bash|zsh|fish)\\s+([^\\s]+)\\b", 2]
- ["(node)\\s+([^\\s]+)(\\.js|\\.ts)\\b", 2]
- ["(python[\\d\\.]*)\\s+([^\\s]+)\\.py\\b", 2]
- ["(python[\\d\\.]*)\\s+-m\\s+([A-Za-z_][\\w\\.]*)\\b", 2] # eg: pythonX -m anything(dir or file)
- ["(ruby)\\s+([^\\s]+)\\.rb\\b", 2]
- ["(go)\\s+(generate|run)(?:\\s+-[^\\s]+)*\\s+([^\\s]+)", 3]
- ["(go)\\s+(generate|run)\\s+([^\\s]+)\\.go\\b", 3]
- ["(dotnet)\\s+([^\\s]+)\\.csproj\\b", 2]

View File

@@ -0,0 +1,6 @@
extensions:
- addsTo:
pack: codeql/actions-all
extensible: actionsSinkModel
data:
- ["docker/build-push-action", "*", "input.context", "code-injection", "manual"]

View File

@@ -0,0 +1,6 @@
extensions:
- addsTo:
pack: codeql/actions-all
extensible: actionsSinkModel
data:
- ["step-security/harden-runner", "*", "input.allowed-endpoints", "command-injection", "manual"]

View File

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

View File

@@ -1,17 +1,3 @@
## 0.6.27
No user-facing changes.
## 0.6.26
### Major Analysis Improvements
* Fixed alert messages in `actions/artifact-poisoning/critical` and `actions/artifact-poisoning/medium` as they previously included a redundant placeholder in the alert message that would on occasion contain a long block of yml that makes the alert difficult to understand. Also improved the wording to make it clearer that it is not the artifact that is being poisoned, but instead a potentially untrusted artifact that is consumed. Finally, changed the alert location to be the source, to align more with other queries reporting an artifact (e.g. zipslip) which is more useful.
### Minor Analysis Improvements
* The query `actions/missing-workflow-permissions` no longer produces false positive results on reusable workflows where all callers set permissions.
## 0.6.25
No user-facing changes.

View File

@@ -1,35 +1,6 @@
## Overview
GitHub workflows can be triggered through various repository events, including incoming pull requests (PRs) or comments on Issues/PRs. Under certain conditions described below, attackers can take over a repository by opening malicious PRs from forks. The attacks can result in malicious code execution causing unauthorized changes to the repository or exfiltration of repository secrets and a compromise of connected systems.
## Workflow Security Model
In GitHub Actions, there is a distinction between unprivileged and privileged workflows. For example, a workflow with a `pull_request` trigger is unprivileged while a workflow with `pull_request_target` is privileged.
This is relevant especially for PRs from forks. Normal PRs can only be submitted by people who have write access to a repository, while PRs from forks can be submitted by anyone.
On a PR from a fork, an unprivileged `pull_request` workflow has only limited capabilities but a privileged `pull_request_target` workflow is much more dangerous. A privileged workflow:
* Runs in the context of the base repository
* Has access to organization and repository secrets (e.g., API keys, deployment tokens)
* Has a read/write `GITHUB_TOKEN` by default
* Can access private resources
Certain triggers automatically grant a workflow elevated privileges:
* `pull_request_target` as described above
* `workflow_run`: Triggered when another workflow completes.
* `issue_comment`: Triggered when a comment is made on an issue or PR.
## Attack Details
* A repository has a privileged workflow
* An attacker forks the repository and adds malicious code (e.g., in the build script)
* The attacker opens a PR from the fork, and, if needed, comments on the PR
* The workflow in the base repository checks out the forked code
* The workflow runs, (e.g. the build script etc.), which contains the malicious code
Please note that not only build scripts can be malicious code vectors. There is a large number of other possibilities. Some of them are listed in the [LOTP](https://boostsecurityio.github.io/lotp/) catalog.
GitHub workflows can be triggered through various repository events, including incoming pull requests (PRs) or comments on Issues/PRs. A potentially dangerous misuse of the triggers such as `pull_request_target` or `issue_comment` followed by an explicit checkout of untrusted code (Pull Request HEAD) may lead to repository compromise if untrusted code gets executed (e.g., due to a modified build script) in a privileged job.
## Recommendation
@@ -162,5 +133,3 @@ jobs:
## References
- GitHub Security Lab Research: [Keeping your GitHub Actions and workflows secure Part 1: Preventing pwn requests](https://securitylab.github.com/research/github-actions-preventing-pwn-requests/).
- Mitigating risks of untrusted checkout: [GitHub Docs](https://docs.github.com/en/enterprise-cloud@latest/actions/reference/security/secure-use#mitigating-the-risks-of-untrusted-code-checkout).
- Living Off the Pipeline: [LOTP](https://boostsecurityio.github.io/lotp/).

View File

@@ -1,35 +1,6 @@
## Overview
GitHub workflows can be triggered through various repository events, including incoming pull requests (PRs) or comments on Issues/PRs. Under certain conditions described below, attackers can take over a repository by opening malicious PRs from forks. The attacks can result in malicious code execution causing unauthorized changes to the repository or exfiltration of repository secrets and a compromise of connected systems.
## Workflow Security Model
In GitHub Actions, there is a distinction between unprivileged and privileged workflows. For example, a workflow with a `pull_request` trigger is unprivileged while a workflow with `pull_request_target` is privileged.
This is relevant especially for PRs from forks. Normal PRs can only be submitted by people who have write access to a repository, while PRs from forks can be submitted by anyone.
On a PR from a fork, an unprivileged `pull_request` workflow has only limited capabilities but a privileged `pull_request_target` workflow is much more dangerous. A privileged workflow:
* Runs in the context of the base repository
* Has access to organization and repository secrets (e.g., API keys, deployment tokens)
* Has a read/write `GITHUB_TOKEN` by default
* Can access private resources
Certain triggers automatically grant a workflow elevated privileges:
* `pull_request_target` as described above
* `workflow_run`: Triggered when another workflow completes.
* `issue_comment`: Triggered when a comment is made on an issue or PR.
## Attack Details
* A repository has a privileged workflow
* An attacker forks the repository and adds malicious code (e.g., in the build script)
* The attacker opens a PR from the fork, and, if needed, comments on the PR
* The workflow in the base repository checks out the forked code
* The workflow runs, (e.g. the build script etc.), which contains the malicious code
Please note that not only build scripts can be malicious code vectors. There is a large number of other possibilities. Some of them are listed in the [LOTP](https://boostsecurityio.github.io/lotp/) catalog.
GitHub workflows can be triggered through various repository events, including incoming pull requests (PRs) or comments on Issues/PRs. A potentially dangerous misuse of the triggers such as `pull_request_target` or `issue_comment` followed by an explicit checkout of untrusted code (Pull Request HEAD) may lead to repository compromise if untrusted code gets executed (e.g., due to a modified build script) in a privileged job.
## Recommendation
@@ -162,5 +133,3 @@ jobs:
## References
- GitHub Security Lab Research: [Keeping your GitHub Actions and workflows secure Part 1: Preventing pwn requests](https://securitylab.github.com/research/github-actions-preventing-pwn-requests/).
- Mitigating risks of untrusted checkout: [GitHub Docs](https://docs.github.com/en/enterprise-cloud@latest/actions/reference/security/secure-use#mitigating-the-risks-of-untrusted-code-checkout).
- Living Off the Pipeline: [LOTP](https://boostsecurityio.github.io/lotp/).

View File

@@ -1,5 +1,5 @@
/**
* @name Checkout of untrusted code in privileged context without privileged context use
* @name Checkout of untrusted code in trusted 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.

View File

@@ -1,35 +1,6 @@
## Overview
GitHub workflows can be triggered through various repository events, including incoming pull requests (PRs) or comments on Issues/PRs. Under certain conditions described below, attackers can take over a repository by opening malicious PRs from forks. The attacks can result in malicious code execution causing unauthorized changes to the repository or exfiltration of repository secrets and a compromise of connected systems.
## Workflow Security Model
In GitHub Actions, there is a distinction between unprivileged and privileged workflows. For example, a workflow with a `pull_request` trigger is unprivileged while a workflow with `pull_request_target` is privileged.
This is relevant especially for PRs from forks. Normal PRs can only be submitted by people who have write access to a repository, while PRs from forks can be submitted by anyone.
On a PR from a fork, an unprivileged `pull_request` workflow has only limited capabilities but a privileged `pull_request_target` workflow is much more dangerous. A privileged workflow:
* Runs in the context of the base repository
* Has access to organization and repository secrets (e.g., API keys, deployment tokens)
* Has a read/write `GITHUB_TOKEN` by default
* Can access private resources
Certain triggers automatically grant a workflow elevated privileges:
* `pull_request_target` as described above
* `workflow_run`: Triggered when another workflow completes.
* `issue_comment`: Triggered when a comment is made on an issue or PR.
## Attack Details
* A repository has a privileged workflow
* An attacker forks the repository and adds malicious code (e.g., in the build script)
* The attacker opens a PR from the fork, and, if needed, comments on the PR
* The workflow in the base repository checks out the forked code
* The workflow runs, (e.g. the build script etc.), which contains the malicious code
Please note that not only build scripts can be malicious code vectors. There is a large number of other possibilities. Some of them are listed in the [LOTP](https://boostsecurityio.github.io/lotp/) catalog.
GitHub workflows can be triggered through various repository events, including incoming pull requests (PRs) or comments on Issues/PRs. A potentially dangerous misuse of the triggers such as `pull_request_target` or `issue_comment` followed by an explicit checkout of untrusted code (Pull Request HEAD) may lead to repository compromise if untrusted code gets executed (e.g., due to a modified build script) in a privileged job.
## Recommendation
@@ -162,5 +133,3 @@ jobs:
## References
- GitHub Security Lab Research: [Keeping your GitHub Actions and workflows secure Part 1: Preventing pwn requests](https://securitylab.github.com/research/github-actions-preventing-pwn-requests/).
- Mitigating risks of untrusted checkout: [GitHub Docs](https://docs.github.com/en/enterprise-cloud@latest/actions/reference/security/secure-use#mitigating-the-risks-of-untrusted-code-checkout).
- Living Off the Pipeline: [LOTP](https://boostsecurityio.github.io/lotp/).

View File

@@ -0,0 +1,4 @@
---
category: majorAnalysis
---
* Fixed alert messages in `actions/artifact-poisoning/critical` and `actions/artifact-poisoning/medium` as they previously included a redundant placeholder in the alert message that would on occasion contain a long block of yml that makes the alert difficult to understand. Also clarify the wording to make it clear that it is not the artifact that is being poisoned, but instead a potentially untrusted artifact that is consumed. Also change the alert location to be the source, to align more with other queries reporting an artifact (e.g. zipslip) which is more useful.

View File

@@ -0,0 +1,4 @@
---
category: minorAnalysis
---
* The query `actions/missing-workflow-permissions` no longer produces false positive results on reusable workflows where all callers set permissions.

View File

@@ -1,4 +0,0 @@
---
category: fix
---
* Fixed help file descriptions for queries: `actions/untrusted-checkout/critical`, `actions/untrusted-checkout/high`, `actions/untrusted-checkout/medium`. Previously the messages were unclear as to why and how the vulnerabilities could occur.

View File

@@ -1,4 +0,0 @@
---
category: queryMetadata
---
* Adjusted the name of `actions/untrusted-checkout/high` to more clearly describe which parts of the scenario are in a privileged context.

View File

@@ -1,9 +0,0 @@
## 0.6.26
### Major Analysis Improvements
* Fixed alert messages in `actions/artifact-poisoning/critical` and `actions/artifact-poisoning/medium` as they previously included a redundant placeholder in the alert message that would on occasion contain a long block of yml that makes the alert difficult to understand. Also improved the wording to make it clearer that it is not the artifact that is being poisoned, but instead a potentially untrusted artifact that is consumed. Finally, changed the alert location to be the source, to align more with other queries reporting an artifact (e.g. zipslip) which is more useful.
### Minor Analysis Improvements
* The query `actions/missing-workflow-permissions` no longer produces false positive results on reusable workflows where all callers set permissions.

View File

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

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 0.6.27
lastReleaseVersion: 0.6.25

View File

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

View File

@@ -1,25 +1,3 @@
## 10.1.0
### New Features
* A new predicate `getSwitchCase` was added to the `SwitchStmt` class, which yields the `n`th `case` statement from a `switch` statement.
* Data flow barriers and barrier guards can now be added using data extensions. For more information see [Customizing library models for C and C++](https://codeql.github.com/docs/codeql-language-guides/customizing-library-models-for-cpp/).
### Minor Analysis Improvements
* Added taint flow models for the `Strsafe.h` header from the Windows SDK.
## 10.0.0
### Breaking Changes
* The deprecated `NonThrowingFunction` class has been removed, use `NonCppThrowingFunction` instead.
* The deprecated `ThrowingFunction` class has been removed, use `AlwaysSehThrowingFunction` instead.
### New Features
* Added a subclass `AutoconfConfigureTestFile` of `ConfigurationTestFile` that represents files created by GNU autoconf configure scripts to test the build configuration.
## 9.0.0
### Breaking Changes

View File

@@ -0,0 +1,4 @@
---
category: feature
---
* Added a subclass `AutoconfConfigureTestFile` of `ConfigurationTestFile` that represents files created by GNU autoconf configure scripts to test the build configuration.

View File

@@ -0,0 +1,5 @@
---
category: breaking
---
* The deprecated `NonThrowingFunction` class has been removed, use `NonCppThrowingFunction` instead.
* The deprecated `ThrowingFunction` class has been removed, use `AlwaysSehThrowingFunction` instead.

View File

@@ -1,10 +0,0 @@
## 10.0.0
### Breaking Changes
* The deprecated `NonThrowingFunction` class has been removed, use `NonCppThrowingFunction` instead.
* The deprecated `ThrowingFunction` class has been removed, use `AlwaysSehThrowingFunction` instead.
### New Features
* Added a subclass `AutoconfConfigureTestFile` of `ConfigurationTestFile` that represents files created by GNU autoconf configure scripts to test the build configuration.

View File

@@ -1,10 +0,0 @@
## 10.1.0
### New Features
* A new predicate `getSwitchCase` was added to the `SwitchStmt` class, which yields the `n`th `case` statement from a `switch` statement.
* Data flow barriers and barrier guards can now be added using data extensions. For more information see [Customizing library models for C and C++](https://codeql.github.com/docs/codeql-language-guides/customizing-library-models-for-cpp/).
### Minor Analysis Improvements
* Added taint flow models for the `Strsafe.h` header from the Windows SDK.

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 10.1.0
lastReleaseVersion: 9.0.0

View File

@@ -1,94 +0,0 @@
# Models for strsafe.h safe string functions
extensions:
- addsTo:
pack: codeql/cpp-all
extensible: sourceModel
data: # namespace, type, subtypes, name, signature, ext, output, kind, provenance
# StringCchGets: (pszDest, cchDest)
- ["", "", False, "StringCchGetsA", "", "", "Argument[*0]", "local", "manual"]
- ["", "", False, "StringCchGetsW", "", "", "Argument[*0]", "local", "manual"]
# StringCbGets: (pszDest, cbDest)
- ["", "", False, "StringCbGetsA", "", "", "Argument[*0]", "local", "manual"]
- ["", "", False, "StringCbGetsW", "", "", "Argument[*0]", "local", "manual"]
# StringCchGetsEx: (pszDest, cchDest, ppszDestEnd, pcchRemaining, dwFlags)
- ["", "", False, "StringCchGetsExA", "", "", "Argument[*0]", "local", "manual"]
- ["", "", False, "StringCchGetsExW", "", "", "Argument[*0]", "local", "manual"]
# StringCbGetsEx: (pszDest, cbDest, ppszDestEnd, pcbRemaining, dwFlags)
- ["", "", False, "StringCbGetsExA", "", "", "Argument[*0]", "local", "manual"]
- ["", "", False, "StringCbGetsExW", "", "", "Argument[*0]", "local", "manual"]
- addsTo:
pack: codeql/cpp-all
extensible: summaryModel
data: # namespace, type, subtypes, name, signature, ext, input, output, kind, provenance
# StringCchCopy: (pszDest, cchDest, pszSrc)
- ["", "", False, "StringCchCopyA", "", "", "Argument[*2]", "Argument[*0]", "taint", "manual"]
- ["", "", False, "StringCchCopyW", "", "", "Argument[*2]", "Argument[*0]", "taint", "manual"]
# StringCbCopy: (pszDest, cbDest, pszSrc)
- ["", "", False, "StringCbCopyA", "", "", "Argument[*2]", "Argument[*0]", "taint", "manual"]
- ["", "", False, "StringCbCopyW", "", "", "Argument[*2]", "Argument[*0]", "taint", "manual"]
# StringCchCopyEx: (pszDest, cchDest, pszSrc, ppszDestEnd, pcchRemaining, dwFlags)
- ["", "", False, "StringCchCopyExA", "", "", "Argument[*2]", "Argument[*0]", "taint", "manual"]
- ["", "", False, "StringCchCopyExW", "", "", "Argument[*2]", "Argument[*0]", "taint", "manual"]
# StringCbCopyEx: (pszDest, cbDest, pszSrc, ppszDestEnd, pcbRemaining, dwFlags)
- ["", "", False, "StringCbCopyExA", "", "", "Argument[*2]", "Argument[*0]", "taint", "manual"]
- ["", "", False, "StringCbCopyExW", "", "", "Argument[*2]", "Argument[*0]", "taint", "manual"]
# StringCchCopyN: (pszDest, cchDest, pszSrc, cchToCopy)
- ["", "", False, "StringCchCopyNA", "", "", "Argument[*2]", "Argument[*0]", "taint", "manual"]
- ["", "", False, "StringCchCopyNW", "", "", "Argument[*2]", "Argument[*0]", "taint", "manual"]
# StringCbCopyN: (pszDest, cbDest, pszSrc, cbToCopy)
- ["", "", False, "StringCbCopyNA", "", "", "Argument[*2]", "Argument[*0]", "taint", "manual"]
- ["", "", False, "StringCbCopyNW", "", "", "Argument[*2]", "Argument[*0]", "taint", "manual"]
# StringCchCopyNEx: (pszDest, cchDest, pszSrc, cchToCopy, ppszDestEnd, pcchRemaining, dwFlags)
- ["", "", False, "StringCchCopyNExA", "", "", "Argument[*2]", "Argument[*0]", "taint", "manual"]
- ["", "", False, "StringCchCopyNExW", "", "", "Argument[*2]", "Argument[*0]", "taint", "manual"]
# StringCbCopyNEx: (pszDest, cbDest, pszSrc, cbToCopy, ppszDestEnd, pcbRemaining, dwFlags)
- ["", "", False, "StringCbCopyNExA", "", "", "Argument[*2]", "Argument[*0]", "taint", "manual"]
- ["", "", False, "StringCbCopyNExW", "", "", "Argument[*2]", "Argument[*0]", "taint", "manual"]
# StringCchCat: (pszDest, cchDest, pszSrc)
- ["", "", False, "StringCchCatA", "", "", "Argument[*2]", "Argument[*0]", "taint", "manual"]
- ["", "", False, "StringCchCatW", "", "", "Argument[*2]", "Argument[*0]", "taint", "manual"]
# StringCbCat: (pszDest, cbDest, pszSrc)
- ["", "", False, "StringCbCatA", "", "", "Argument[*2]", "Argument[*0]", "taint", "manual"]
- ["", "", False, "StringCbCatW", "", "", "Argument[*2]", "Argument[*0]", "taint", "manual"]
# StringCchCatEx: (pszDest, cchDest, pszSrc, ppszDestEnd, pcchRemaining, dwFlags)
- ["", "", False, "StringCchCatExA", "", "", "Argument[*2]", "Argument[*0]", "taint", "manual"]
- ["", "", False, "StringCchCatExW", "", "", "Argument[*2]", "Argument[*0]", "taint", "manual"]
# StringCbCatEx: (pszDest, cbDest, pszSrc, ppszDestEnd, pcbRemaining, dwFlags)
- ["", "", False, "StringCbCatExA", "", "", "Argument[*2]", "Argument[*0]", "taint", "manual"]
- ["", "", False, "StringCbCatExW", "", "", "Argument[*2]", "Argument[*0]", "taint", "manual"]
# StringCchCatN: (pszDest, cchDest, pszSrc, cchToAppend)
- ["", "", False, "StringCchCatNA", "", "", "Argument[*2]", "Argument[*0]", "taint", "manual"]
- ["", "", False, "StringCchCatNW", "", "", "Argument[*2]", "Argument[*0]", "taint", "manual"]
# StringCbCatN: (pszDest, cbDest, pszSrc, cbToAppend)
- ["", "", False, "StringCbCatNA", "", "", "Argument[*2]", "Argument[*0]", "taint", "manual"]
- ["", "", False, "StringCbCatNW", "", "", "Argument[*2]", "Argument[*0]", "taint", "manual"]
# StringCchCatNEx: (pszDest, cchDest, pszSrc, cchToAppend, ppszDestEnd, pcchRemaining, dwFlags)
- ["", "", False, "StringCchCatNExA", "", "", "Argument[*2]", "Argument[*0]", "taint", "manual"]
- ["", "", False, "StringCchCatNExW", "", "", "Argument[*2]", "Argument[*0]", "taint", "manual"]
# StringCbCatNEx: (pszDest, cbDest, pszSrc, cbToAppend, ppszDestEnd, pcbRemaining, dwFlags)
- ["", "", False, "StringCbCatNExA", "", "", "Argument[*2]", "Argument[*0]", "taint", "manual"]
- ["", "", False, "StringCbCatNExW", "", "", "Argument[*2]", "Argument[*0]", "taint", "manual"]
# StringCchPrintf: (pszDest, cchDest, pszFormat, ...)
- ["", "", False, "StringCchPrintfA", "", "", "Argument[*2..8]", "Argument[*0]", "taint", "manual"]
- ["", "", False, "StringCchPrintfW", "", "", "Argument[*2..8]", "Argument[*0]", "taint", "manual"]
# StringCbPrintf: (pszDest, cbDest, pszFormat, ...)
- ["", "", False, "StringCbPrintfA", "", "", "Argument[*2..8]", "Argument[*0]", "taint", "manual"]
- ["", "", False, "StringCbPrintfW", "", "", "Argument[*2..8]", "Argument[*0]", "taint", "manual"]
# StringCchPrintfEx: (pszDest, cchDest, ppszDestEnd, pcchRemaining, dwFlags, pszFormat, ...)
- ["", "", False, "StringCchPrintfExA", "", "", "Argument[*5..11]", "Argument[*0]", "taint", "manual"]
- ["", "", False, "StringCchPrintfExW", "", "", "Argument[*5..11]", "Argument[*0]", "taint", "manual"]
# StringCbPrintfEx: (pszDest, cbDest, ppszDestEnd, pcbRemaining, dwFlags, pszFormat, ...)
- ["", "", False, "StringCbPrintfExA", "", "", "Argument[*5..11]", "Argument[*0]", "taint", "manual"]
- ["", "", False, "StringCbPrintfExW", "", "", "Argument[*5..11]", "Argument[*0]", "taint", "manual"]
# StringCchVPrintf: (pszDest, cchDest, pszFormat, argList)
- ["", "", False, "StringCchVPrintfA", "", "", "Argument[*2]", "Argument[*0]", "taint", "manual"]
- ["", "", False, "StringCchVPrintfW", "", "", "Argument[*2]", "Argument[*0]", "taint", "manual"]
# StringCbVPrintf: (pszDest, cbDest, pszFormat, argList)
- ["", "", False, "StringCbVPrintfA", "", "", "Argument[*2]", "Argument[*0]", "taint", "manual"]
- ["", "", False, "StringCbVPrintfW", "", "", "Argument[*2]", "Argument[*0]", "taint", "manual"]
# StringCchVPrintfEx: (pszDest, cchDest, ppszDestEnd, pcchRemaining, dwFlags, pszFormat, argList)
- ["", "", False, "StringCchVPrintfExA", "", "", "Argument[*5]", "Argument[*0]", "taint", "manual"]
- ["", "", False, "StringCchVPrintfExW", "", "", "Argument[*5]", "Argument[*0]", "taint", "manual"]
# StringCbVPrintfEx: (pszDest, cbDest, ppszDestEnd, pcbRemaining, dwFlags, pszFormat, argList)
- ["", "", False, "StringCbVPrintfExA", "", "", "Argument[*5]", "Argument[*0]", "taint", "manual"]
- ["", "", False, "StringCbVPrintfExW", "", "", "Argument[*5]", "Argument[*0]", "taint", "manual"]

View File

@@ -12,7 +12,4 @@ extensions:
- ["", "", False, "_malloca", "0", "", "", False]
- ["", "", False, "calloc", "1", "0", "", True]
- ["std", "", False, "calloc", "1", "0", "", True]
- ["bsl", "", False, "calloc", "1", "0", "", True]
- ["", "", False, "aligned_alloc", "1", "", "", True]
- ["std", "", False, "aligned_alloc", "1", "", "", True]
- ["bsl", "", False, "aligned_alloc", "1", "", "", True]
- ["bsl", "", False, "calloc", "1", "0", "", True]

View File

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

View File

@@ -18,7 +18,7 @@ class Namespace extends @namespace {
if namespacembrs(_, this)
then
exists(Namespace ns |
namespacembrs(ns, pragma[only_bind_out](this)) and
namespacembrs(ns, this) and
result = ns.getQualifiedName() + "::" + this.getName()
)
else result = this.getName()
@@ -37,7 +37,7 @@ class Namespace extends @namespace {
string getAQualifierForMembers() {
if namespacembrs(_, this)
then
exists(Namespace ns | namespacembrs(ns, pragma[only_bind_out](this)) |
exists(Namespace ns | namespacembrs(ns, this) |
result = ns.getAQualifierForMembers() + "::" + this.getName()
or
// If this is an inline namespace, its members are also visible in any

View File

@@ -114,7 +114,6 @@ private predicate parseArgument(string arg, string s, int i, Opcode opcode) {
private Element getAChildScope(Element scope) { result.getParentScope() = scope }
pragma[nomagic]
private predicate hasAVariable(MacroInvocation mi, Stmt s, Element scope) {
assertion0(mi, s, _) and
s.getParent() = scope
@@ -122,32 +121,15 @@ private predicate hasAVariable(MacroInvocation mi, Stmt s, Element scope) {
hasAVariable(mi, s, getAChildScope(scope))
}
private predicate hasParentScope(Variable v, Element scope) { v.getParentScope() = scope }
pragma[nomagic]
private predicate hasAssertionOperand(MacroInvocation mi, int i, Stmt s, string operand) {
exists(string arg |
assertion0(mi, s, arg) and
parseArgument(arg, operand, i, _)
)
}
pragma[nomagic]
private predicate hasNameAndParentScope(string name, Element scope, Variable v) {
v.hasName(name) and
hasParentScope(v, scope)
}
pragma[nomagic]
private LocalScopeVariable getVariable(MacroInvocation mi, int i) {
exists(string name, Stmt s |
hasAssertionOperand(mi, i, s, name) and
exists(string operand, string arg, Stmt s |
assertion0(mi, s, arg) and
parseArgument(arg, operand, i, _) and
result =
unique(Variable v, Element parentScope |
hasAssertionOperand(mi, _, s, name) and
unique(Variable v |
v.getLocation().getStartLine() < s.getLocation().getStartLine() and
hasAVariable(mi, s, parentScope) and
hasNameAndParentScope(name, parentScope, v)
hasAVariable(mi, s, v.getParentScope()) and
v.hasName(operand)
|
v
)

View File

@@ -1412,9 +1412,9 @@ private int indexOfSwitchCaseRank(BlockStmt b, int rnk) {
* switch (i)
* {
* case 5:
* ...
* ...
* default:
* ...
* ...
* }
* ```
*/
@@ -1516,10 +1516,8 @@ class SwitchCase extends Stmt, @stmt_switch_case {
* which has result `default:`, which has no result.
*/
SwitchCase getNextSwitchCase() {
exists(SwitchStmt s, int n |
this = s.getSwitchCase(n) and
result = s.getSwitchCase(n + 1)
)
result.getSwitchStmt() = this.getSwitchStmt() and
result.getChildNum() = this.getChildNum() + 1
}
/**
@@ -1709,9 +1707,9 @@ class SwitchCase extends Stmt, @stmt_switch_case {
* switch (i)
* {
* case 5:
* ...
* ...
* default:
* ...
* ...
* }
* ```
*/
@@ -1733,9 +1731,9 @@ class DefaultCase extends SwitchCase {
* switch (i)
* {
* case 5:
* ...
* ...
* default:
* ...
* ...
* }
* ```
*/
@@ -1770,10 +1768,10 @@ class SwitchStmt extends ConditionalStmt, @stmt_switch {
* For example, for
* ```
* switch(i) {
* case 1:
* case 2:
* case 1:
* case 2:
* break;
* default:
* default:
* break;
* }
* ```
@@ -1792,20 +1790,20 @@ class SwitchStmt extends ConditionalStmt, @stmt_switch {
* For example, for
* ```
* switch(i) {
* case 1:
* case 2:
* case 1:
* case 2:
* break;
* default:
* default:
* break;
* }
* ```
* the result is
* ```
* {
* case 1:
* case 2:
* case 1:
* case 2:
* break;
* default:
* default:
* break;
* }
* ```
@@ -1818,10 +1816,10 @@ class SwitchStmt extends ConditionalStmt, @stmt_switch {
* For example, for
* ```
* switch(i) {
* case 1:
* case 2:
* case 1:
* case 2:
* break;
* default:
* default:
* break;
* }
* ```
@@ -1829,23 +1827,6 @@ class SwitchStmt extends ConditionalStmt, @stmt_switch {
*/
SwitchCase getASwitchCase() { switch_case(underlyingElement(this), _, unresolveElement(result)) }
/**
* Gets the `n`th 'switch case' statement of this 'switch' statement, where
* `n` is 0-based.
*
* For example, for
* ```
* switch(i) {
* case 5:
* case 6:
* default:
* } * ```
* 0 yields `case 5:`, 1 yields `case 6:`, and 2 yields `default:`.
*/
SwitchCase getSwitchCase(int n) {
switch_case(underlyingElement(this), n, unresolveElement(result))
}
/**
* Gets the 'default case' statement of this 'switch' statement,
* if any.
@@ -1853,18 +1834,18 @@ class SwitchStmt extends ConditionalStmt, @stmt_switch {
* For example, for
* ```
* switch(i) {
* case 1:
* case 2:
* case 1:
* case 2:
* break;
* default:
* default:
* break;
* }
* ```
* the result is `default:`, but there is no result for
* ```
* switch(i) {
* case 1:
* case 2:
* case 1:
* case 2:
* break;
* }
* ```
@@ -1877,18 +1858,18 @@ class SwitchStmt extends ConditionalStmt, @stmt_switch {
* For example, this holds for
* ```
* switch(i) {
* case 1:
* case 2:
* case 1:
* case 2:
* break;
* default:
* default:
* break;
* }
* ```
* but not for
* ```
* switch(i) {
* case 1:
* case 2:
* case 1:
* case 2:
* break;
* }
* ```

View File

@@ -1,18 +1,3 @@
## 1.6.2
No user-facing changes.
## 1.6.1
### Minor Analysis Improvements
* Added `AllocationFunction` models for `aligned_alloc`, `std::aligned_alloc`, and `bsl::aligned_alloc`.
* The "Comparison of narrow type with wide type in loop condition" (`cpp/comparison-with-wider-type`) query has been upgraded to `high` precision. This query will now run in the default code scanning suite.
* The "Multiplication result converted to larger type" (`cpp/integer-multiplication-cast-to-long`) query has been upgraded to `high` precision. This query will now run in the default code scanning suite.
* The "Suspicious add with sizeof" (`cpp/suspicious-add-sizeof`) query has been upgraded to `high` precision. This query will now run in the default code scanning suite.
* The "Wrong type of arguments to formatting function" (`cpp/wrong-type-format-argument`) query has been upgraded to `high` precision. This query will now run in the default code scanning suite.
* The "Implicit function declaration" (`cpp/implicit-function-declaration`) query has been upgraded to `high` precision. However, for `build-mode: none` databases, it no longer produces any results. The results in this mode were found to be very noisy and fundamentally imprecise.
## 1.6.0
### Query Metadata Changes

View File

@@ -227,30 +227,6 @@ class IgnorableUnaryBitwiseOperation extends IgnorableOperation instanceof Unary
class IgnorableAssignmentBitwiseOperation extends IgnorableOperation instanceof AssignBitwiseOperation
{ }
class YearFieldAssignmentNode extends DataFlow::Node {
YearFieldAccess access;
YearFieldAssignmentNode() {
exists(Function f |
f = this.getEnclosingCallable().getUnderlyingCallable() and not f instanceof IgnorableFunction
|
this.asDefinition().(Assignment).getLValue() = access
or
this.asDefinition().(CrementOperation).getOperand() = access
or
exists(Call c | c.getAnArgument() = access and this.asDefiningArgument() = access)
or
exists(Call c, AddressOfExpr aoe |
c.getAnArgument() = aoe and
aoe.getOperand() = access and
this.asDefiningArgument() = aoe
)
)
}
YearFieldAccess getYearFieldAccess() { result = access }
}
/**
* An arithmetic operation where one of the operands is a pointer or char type, ignore it
*/
@@ -311,7 +287,24 @@ predicate isOperationSourceCandidate(Expr e) {
}
/**
* The set of all expressions that are candidate expression.
* A data flow that tracks an ignorable operation (such as a bitwise operation) to an operation source, so we may disqualify it.
*/
module IgnorableOperationToOperationSourceCandidateConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node n) { n.asExpr() instanceof IgnorableOperation }
predicate isSink(DataFlow::Node n) { isOperationSourceCandidate(n.asExpr()) }
// looking for sources and sinks in the same function
DataFlow::FlowFeature getAFeature() {
result instanceof DataFlow::FeatureEqualSourceSinkCallContext
}
}
module IgnorableOperationToOperationSourceCandidateFlow =
TaintTracking::Global<IgnorableOperationToOperationSourceCandidateConfig>;
/**
* The set of all expressions which is a candidate expression and also does not flow from to to some ignorable expression (eg. bitwise op)
* ```
* a = something <<< 2;
* myDate.year = a + 1; // invalid
@@ -321,16 +314,49 @@ predicate isOperationSourceCandidate(Expr e) {
* ```
*/
class OperationSource extends Expr {
OperationSource() { isOperationSourceCandidate(this) }
OperationSource() {
isOperationSourceCandidate(this) and
// If the candidate came from an ignorable operation, ignore the candidate
// NOTE: we cannot easily flow the candidate to an ignorable operation as that can
// be tricky in practice, e.g., a mod operation on a year would be part of a leap year check
// but a mod operation ending in a year is more indicative of something to ignore (a conversion)
not exists(IgnorableOperationToOperationSourceCandidateFlow::PathNode sink |
sink.getNode().asExpr() = this and
sink.isSink()
)
}
}
class YearFieldAssignmentNode extends DataFlow::Node {
YearFieldAccess access;
YearFieldAssignmentNode() {
exists(Function f |
f = this.getEnclosingCallable().getUnderlyingCallable() and not f instanceof IgnorableFunction
) and
(
this.asDefinition().(Assignment).getLValue() = access
or
this.asDefinition().(CrementOperation).getOperand() = access
or
exists(Call c | c.getAnArgument() = access and this.asDefiningArgument() = access)
or
exists(Call c, AddressOfExpr aoe |
c.getAnArgument() = aoe and
aoe.getOperand() = access and
this.asDefiningArgument() = aoe
)
)
}
YearFieldAccess getYearFieldAccess() { result = access }
}
/**
* An initial DataFlow configuration for identifying flows from an identified source
* to the Year field of a date object. This is used to restrict the sinks of
* `IgnorableOperationToOperationSourceCandidateConfig` and the sinks of the
* final `OperationToYearAssignmentConfig`.
* A DataFlow configuration for identifying flows from an identified source
* to the Year field of a date object.
*/
module OperationToYearAssignmentConfig0 implements DataFlow::ConfigSig {
module OperationToYearAssignmentConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node n) { n.asExpr() instanceof OperationSource }
predicate isSink(DataFlow::Node n) {
@@ -385,62 +411,6 @@ module OperationToYearAssignmentConfig0 implements DataFlow::ConfigSig {
predicate isBarrierOut(DataFlow::Node n) { isSink(n) }
}
module OperationToYearAssignmentFlow0 = TaintTracking::Global<OperationToYearAssignmentConfig0>;
predicate yearAssignmentFlowsFromSource(DataFlow::Node source, DataFlow::Node sink) {
OperationToYearAssignmentFlow0::flow(source, sink)
}
/**
* A data flow that tracks an ignorable operation (such as a bitwise operation) to an operation source, so we may disqualify it.
* Sinks are restricted to operation source candidates that have a flow to a year assignment in `OperationToYearAssignmentFlow0`.
*/
module IgnorableOperationToOperationSourceCandidateConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node n) { n.asExpr() instanceof IgnorableOperation }
predicate isSink(DataFlow::Node n) {
isOperationSourceCandidate(n.asExpr()) and
yearAssignmentFlowsFromSource(n, _)
}
// looking for sources and sinks in the same function
DataFlow::FlowFeature getAFeature() {
result instanceof DataFlow::FeatureEqualSourceSinkCallContext
}
}
module IgnorableOperationToOperationSourceCandidateFlow =
TaintTracking::Global<IgnorableOperationToOperationSourceCandidateConfig>;
/**
* The final DataFlow configuration that refines `OperationToYearAssignmentConfig0` by
* additionally filtering out operation sources that flow from an ignorable operation
* (via `IgnorableOperationToOperationSourceCandidateFlow`).
*/
module OperationToYearAssignmentConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node n) { yearAssignmentFlowsFromSource(n, _) }
predicate isSink(DataFlow::Node n) {
exists(DataFlow::Node operation |
yearAssignmentFlowsFromSource(operation, n) and
// If the candidate came from an ignorable operation, ignore the candidate
// NOTE: we cannot easily flow the candidate to an ignorable operation as that can
// be tricky in practice, e.g., a mod operation on a year would be part of a leap year check
// but a mod operation ending in a year is more indicative of something to ignore (a conversion)
not exists(IgnorableOperationToOperationSourceCandidateFlow::PathNode sink |
sink.getNode() = operation and
sink.isSink()
)
)
}
predicate isBarrier(DataFlow::Node n) { OperationToYearAssignmentConfig0::isBarrier(n) }
predicate isBarrierIn(DataFlow::Node n) { isSource(n) }
predicate isBarrierOut(DataFlow::Node n) { isSink(n) }
}
module OperationToYearAssignmentFlow = TaintTracking::Global<OperationToYearAssignmentConfig>;
predicate isLeapYearCheckSink(DataFlow::Node sink) {

View File

@@ -14,7 +14,7 @@ function may behave unpredictably.</p>
<p>This may indicate a misspelled function name, or that the required header containing
the function declaration has not been included.</p>
<p>Note: This query is not compatible with <code>build-mode: none</code> databases, and produces
<p>Note: This query is not compatible with <code>build mode: none</code> databases, and produces
no results on those databases.</p>
</overview>

View File

@@ -18,7 +18,7 @@ import TooManyArguments
import semmle.code.cpp.commons.Exclusions
/*
* This query is not compatible with build-mode: none databases, and produces
* This query is not compatible with build mode: none databases, and produces
* no results on those databases.
*/

View File

@@ -0,0 +1,4 @@
---
category: minorAnalysis
---
* The "Implicit function declaration" (`cpp/implicit-function-declaration`) query no longer produces results on `build mode: none` databases. These results were found to be very noisy and fundamentally imprecise in this mode.

View File

@@ -0,0 +1,4 @@
---
category: minorAnalysis
---
* The "Comparison of narrow type with wide type in loop condition" (`cpp/comparison-with-wider-type`) query has been upgraded to `high` precision. This query will now run in the default code scanning suite.

View File

@@ -0,0 +1,4 @@
---
category: minorAnalysis
---
* The "Implicit function declaration" (`cpp/implicit-function-declaration`) query has been upgraded to `high` precision.

View File

@@ -0,0 +1,4 @@
---
category: minorAnalysis
---
* The "Multiplication result converted to larger type" (`cpp/integer-multiplication-cast-to-long`) query has been upgraded to `high` precision. This query will now run in the default code scanning suite.

View File

@@ -0,0 +1,4 @@
---
category: minorAnalysis
---
* The "Suspicious add with sizeof" (`cpp/suspicious-add-sizeof`) query has been upgraded to `high` precision. This query will now run in the default code scanning suite.

View File

@@ -0,0 +1,4 @@
---
category: minorAnalysis
---
* The "Wrong type of arguments to formatting function" (`cpp/wrong-type-format-argument`) query has been upgraded to `high` precision. This query will now run in the default code scanning suite.

View File

@@ -1,10 +0,0 @@
## 1.6.1
### Minor Analysis Improvements
* Added `AllocationFunction` models for `aligned_alloc`, `std::aligned_alloc`, and `bsl::aligned_alloc`.
* The "Comparison of narrow type with wide type in loop condition" (`cpp/comparison-with-wider-type`) query has been upgraded to `high` precision. This query will now run in the default code scanning suite.
* The "Multiplication result converted to larger type" (`cpp/integer-multiplication-cast-to-long`) query has been upgraded to `high` precision. This query will now run in the default code scanning suite.
* The "Suspicious add with sizeof" (`cpp/suspicious-add-sizeof`) query has been upgraded to `high` precision. This query will now run in the default code scanning suite.
* The "Wrong type of arguments to formatting function" (`cpp/wrong-type-format-argument`) query has been upgraded to `high` precision. This query will now run in the default code scanning suite.
* The "Implicit function declaration" (`cpp/implicit-function-declaration`) query has been upgraded to `high` precision. However, for `build-mode: none` databases, it no longer produces any results. The results in this mode were found to be very noisy and fundamentally imprecise.

View File

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

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 1.6.2
lastReleaseVersion: 1.6.0

View File

@@ -1,5 +1,5 @@
name: codeql/cpp-queries
version: 1.6.3-dev
version: 1.6.1-dev
groups:
- cpp
- queries

View File

@@ -1,4 +1,4 @@
| complex.c:3:23:3:51 | __builtin_complex | file://:0:0:0:0 | _Complex double | complex.c:3:41:3:44 | real | file://:0:0:0:0 | double | complex.c:3:47:3:50 | imag | file://:0:0:0:0 | double |
| complex.c:4:23:4:57 | __builtin_complex | file://:0:0:0:0 | _Complex double | complex.c:4:41:4:47 | 2.71828 | file://:0:0:0:0 | double | complex.c:4:50:4:56 | 3.14159 | file://:0:0:0:0 | double |
| complex.c:4:23:4:57 | __builtin_complex | file://:0:0:0:0 | _Complex double | complex.c:4:41:4:47 | 2.71828000000000003 | file://:0:0:0:0 | double | complex.c:4:50:4:56 | 3.141589999999999883 | file://:0:0:0:0 | double |
| complex.c:8:22:8:52 | __builtin_complex | file://:0:0:0:0 | _Complex float | complex.c:8:40:8:44 | realf | file://:0:0:0:0 | float | complex.c:8:47:8:51 | imagf | file://:0:0:0:0 | float |
| complex.c:9:22:9:52 | __builtin_complex | file://:0:0:0:0 | _Complex float | complex.c:9:40:9:44 | 1.23 | file://:0:0:0:0 | float | complex.c:9:47:9:51 | 4.56 | file://:0:0:0:0 | float |
| complex.c:9:22:9:52 | __builtin_complex | file://:0:0:0:0 | _Complex float | complex.c:9:40:9:44 | 1.230000019 | file://:0:0:0:0 | float | complex.c:9:47:9:51 | 4.559999943 | file://:0:0:0:0 | float |

View File

@@ -298,16 +298,16 @@
| test.c:182:8:182:34 | ! ... | ! ... == 1 when ! ... is true |
| test.c:182:8:182:34 | ! ... | ... && ... != 0 when ! ... is false |
| test.c:182:8:182:34 | ! ... | ... && ... == 0 when ! ... is true |
| test.c:182:10:182:20 | ... >= ... | 1.0E-6 < foo+1 when ... >= ... is true |
| test.c:182:10:182:20 | ... >= ... | 1.0E-6 >= foo+1 when ... >= ... is false |
| test.c:182:10:182:20 | ... >= ... | 9.999999999999999547e-07 < foo+1 when ... >= ... is true |
| test.c:182:10:182:20 | ... >= ... | 9.999999999999999547e-07 >= foo+1 when ... >= ... is false |
| test.c:182:10:182:20 | ... >= ... | ... >= ... != 0 when ... >= ... is true |
| test.c:182:10:182:20 | ... >= ... | ... >= ... != 1 when ... >= ... is false |
| test.c:182:10:182:20 | ... >= ... | ... >= ... == 0 when ... >= ... is false |
| test.c:182:10:182:20 | ... >= ... | ... >= ... == 1 when ... >= ... is true |
| test.c:182:10:182:20 | ... >= ... | foo < 1.0E-6+0 when ... >= ... is false |
| test.c:182:10:182:20 | ... >= ... | foo >= 1.0E-6+0 when ... >= ... is true |
| test.c:182:10:182:20 | ... >= ... | foo < 9.999999999999999547e-07+0 when ... >= ... is false |
| test.c:182:10:182:20 | ... >= ... | foo >= 9.999999999999999547e-07+0 when ... >= ... is true |
| test.c:182:10:182:33 | ... && ... | 1.0 >= foo+1 when ... && ... is true |
| test.c:182:10:182:33 | ... && ... | 1.0E-6 < foo+1 when ... && ... is true |
| test.c:182:10:182:33 | ... && ... | 9.999999999999999547e-07 < foo+1 when ... && ... is true |
| test.c:182:10:182:33 | ... && ... | ! ... != 0 when ... && ... is false |
| test.c:182:10:182:33 | ... && ... | ! ... != 1 when ... && ... is true |
| test.c:182:10:182:33 | ... && ... | ! ... == 0 when ... && ... is true |
@@ -319,7 +319,7 @@
| test.c:182:10:182:33 | ... && ... | ... >= ... != 0 when ... && ... is true |
| test.c:182:10:182:33 | ... && ... | ... >= ... == 1 when ... && ... is true |
| test.c:182:10:182:33 | ... && ... | foo < 1.0+0 when ... && ... is true |
| test.c:182:10:182:33 | ... && ... | foo >= 1.0E-6+0 when ... && ... is true |
| test.c:182:10:182:33 | ... && ... | foo >= 9.999999999999999547e-07+0 when ... && ... is true |
| test.c:182:25:182:33 | ... < ... | 1.0 < foo+1 when ... < ... is false |
| test.c:182:25:182:33 | ... < ... | 1.0 >= foo+1 when ... < ... is true |
| test.c:182:25:182:33 | ... < ... | ... < ... != 0 when ... < ... is true |

View File

@@ -169,12 +169,12 @@ binary
| test.c:176:8:176:15 | ! ... | test.c:176:14:176:14 | b | < | test.c:176:10:176:10 | a | 1 | test.c:176:18:178:5 | { ... } |
| test.c:176:10:176:14 | ... < ... | test.c:176:10:176:10 | a | >= | test.c:176:14:176:14 | b | 0 | test.c:176:18:178:5 | { ... } |
| test.c:176:10:176:14 | ... < ... | test.c:176:14:176:14 | b | < | test.c:176:10:176:10 | a | 1 | test.c:176:18:178:5 | { ... } |
| test.c:182:10:182:20 | ... >= ... | test.c:182:10:182:12 | foo | >= | test.c:182:17:182:20 | 1.0E-6 | 0 | test.c:181:25:182:20 | { ... } |
| test.c:182:10:182:20 | ... >= ... | test.c:182:10:182:12 | foo | >= | test.c:182:17:182:20 | 1.0E-6 | 0 | test.c:182:25:182:33 | foo |
| test.c:182:10:182:20 | ... >= ... | test.c:182:17:182:20 | 1.0E-6 | < | test.c:182:10:182:12 | foo | 1 | test.c:181:25:182:20 | { ... } |
| test.c:182:10:182:20 | ... >= ... | test.c:182:17:182:20 | 1.0E-6 | < | test.c:182:10:182:12 | foo | 1 | test.c:182:25:182:33 | foo |
| test.c:182:10:182:33 | ... && ... | test.c:182:10:182:12 | foo | >= | test.c:182:17:182:20 | 1.0E-6 | 0 | test.c:181:25:182:20 | { ... } |
| test.c:182:10:182:33 | ... && ... | test.c:182:17:182:20 | 1.0E-6 | < | test.c:182:10:182:12 | foo | 1 | test.c:181:25:182:20 | { ... } |
| test.c:182:10:182:20 | ... >= ... | test.c:182:10:182:12 | foo | >= | test.c:182:17:182:20 | 9.999999999999999547e-07 | 0 | test.c:181:25:182:20 | { ... } |
| test.c:182:10:182:20 | ... >= ... | test.c:182:10:182:12 | foo | >= | test.c:182:17:182:20 | 9.999999999999999547e-07 | 0 | test.c:182:25:182:33 | foo |
| test.c:182:10:182:20 | ... >= ... | test.c:182:17:182:20 | 9.999999999999999547e-07 | < | test.c:182:10:182:12 | foo | 1 | test.c:181:25:182:20 | { ... } |
| test.c:182:10:182:20 | ... >= ... | test.c:182:17:182:20 | 9.999999999999999547e-07 | < | test.c:182:10:182:12 | foo | 1 | test.c:182:25:182:33 | foo |
| test.c:182:10:182:33 | ... && ... | test.c:182:10:182:12 | foo | >= | test.c:182:17:182:20 | 9.999999999999999547e-07 | 0 | test.c:181:25:182:20 | { ... } |
| test.c:182:10:182:33 | ... && ... | test.c:182:17:182:20 | 9.999999999999999547e-07 | < | test.c:182:10:182:12 | foo | 1 | test.c:181:25:182:20 | { ... } |
| test.c:182:10:182:33 | ... && ... | test.c:182:25:182:27 | foo | < | test.c:182:31:182:33 | 1.0 | 0 | test.c:181:25:182:20 | { ... } |
| test.c:182:10:182:33 | ... && ... | test.c:182:31:182:33 | 1.0 | >= | test.c:182:25:182:27 | foo | 1 | test.c:181:25:182:20 | { ... } |
| test.c:182:25:182:33 | ... < ... | test.c:182:25:182:27 | foo | < | test.c:182:31:182:33 | 1.0 | 0 | test.c:181:25:182:20 | { ... } |

View File

@@ -115,19 +115,3 @@ void test_zmc(void *socket) {
// ...
}
}
long StringCchGetsA(char *, size_t);
long StringCchGetsExA(char *, size_t, char **, size_t *, unsigned long);
void test_strsafe_gets() {
{
char dest[256] = {0};
StringCchGetsA(dest, sizeof(dest)); // $ local_source
}
{
char dest[256] = {0};
char *end;
size_t remaining;
StringCchGetsExA(dest, sizeof(dest), &end, &remaining, 0); // $ local_source
}
}

View File

@@ -8008,174 +8008,6 @@ WARNING: module 'TaintTracking' has been deprecated and may be removed in future
| taint.cpp:866:26:866:34 | ref arg & ... | taint.cpp:866:27:866:34 | size_out [inner post update] | |
| taint.cpp:866:27:866:34 | size_out | taint.cpp:866:26:866:34 | & ... | |
| taint.cpp:867:8:867:8 | p | taint.cpp:867:7:867:8 | * ... | TAINT |
| taint.cpp:892:17:892:31 | call to indirect_source | taint.cpp:897:38:897:43 | source | |
| taint.cpp:892:17:892:31 | call to indirect_source | taint.cpp:907:37:907:42 | source | |
| taint.cpp:892:17:892:31 | call to indirect_source | taint.cpp:914:40:914:45 | source | |
| taint.cpp:892:17:892:31 | call to indirect_source | taint.cpp:919:39:919:44 | source | |
| taint.cpp:892:17:892:31 | call to indirect_source | taint.cpp:926:41:926:46 | source | |
| taint.cpp:892:17:892:31 | call to indirect_source | taint.cpp:931:37:931:42 | source | |
| taint.cpp:892:17:892:31 | call to indirect_source | taint.cpp:941:36:941:41 | source | |
| taint.cpp:892:17:892:31 | call to indirect_source | taint.cpp:948:39:948:44 | source | |
| taint.cpp:892:17:892:31 | call to indirect_source | taint.cpp:953:38:953:43 | source | |
| taint.cpp:892:17:892:31 | call to indirect_source | taint.cpp:960:40:960:45 | source | |
| taint.cpp:892:17:892:31 | call to indirect_source | taint.cpp:965:46:965:51 | source | |
| taint.cpp:892:17:892:31 | call to indirect_source | taint.cpp:975:45:975:50 | source | |
| taint.cpp:892:17:892:31 | call to indirect_source | taint.cpp:982:69:982:74 | source | |
| taint.cpp:893:32:893:46 | call to indirect_source | taint.cpp:902:38:902:44 | wsource | |
| taint.cpp:893:32:893:46 | call to indirect_source | taint.cpp:936:37:936:43 | wsource | |
| taint.cpp:893:32:893:46 | call to indirect_source | taint.cpp:970:47:970:53 | wsource | |
| taint.cpp:896:19:896:22 | {...} | taint.cpp:897:18:897:21 | dest | |
| taint.cpp:896:19:896:22 | {...} | taint.cpp:897:31:897:34 | dest | |
| taint.cpp:896:19:896:22 | {...} | taint.cpp:898:9:898:12 | dest | |
| taint.cpp:896:21:896:21 | 0 | taint.cpp:896:19:896:22 | {...} | TAINT |
| taint.cpp:897:18:897:21 | ref arg dest | taint.cpp:898:9:898:12 | dest | |
| taint.cpp:898:9:898:12 | dest | taint.cpp:898:8:898:12 | * ... | |
| taint.cpp:901:22:901:25 | {...} | taint.cpp:902:18:902:21 | dest | |
| taint.cpp:901:22:901:25 | {...} | taint.cpp:902:31:902:34 | dest | |
| taint.cpp:901:22:901:25 | {...} | taint.cpp:903:9:903:12 | dest | |
| taint.cpp:901:24:901:24 | 0 | taint.cpp:901:22:901:25 | {...} | TAINT |
| taint.cpp:902:18:902:21 | ref arg dest | taint.cpp:903:9:903:12 | dest | |
| taint.cpp:903:9:903:12 | dest | taint.cpp:903:8:903:12 | * ... | |
| taint.cpp:906:19:906:22 | {...} | taint.cpp:907:17:907:20 | dest | |
| taint.cpp:906:19:906:22 | {...} | taint.cpp:907:30:907:33 | dest | |
| taint.cpp:906:19:906:22 | {...} | taint.cpp:908:9:908:12 | dest | |
| taint.cpp:906:21:906:21 | 0 | taint.cpp:906:19:906:22 | {...} | TAINT |
| taint.cpp:907:17:907:20 | ref arg dest | taint.cpp:908:9:908:12 | dest | |
| taint.cpp:908:9:908:12 | dest | taint.cpp:908:8:908:12 | * ... | |
| taint.cpp:911:19:911:22 | {...} | taint.cpp:914:20:914:23 | dest | |
| taint.cpp:911:19:911:22 | {...} | taint.cpp:914:33:914:36 | dest | |
| taint.cpp:911:19:911:22 | {...} | taint.cpp:915:9:915:12 | dest | |
| taint.cpp:911:21:911:21 | 0 | taint.cpp:911:19:911:22 | {...} | TAINT |
| taint.cpp:912:9:912:11 | end | taint.cpp:914:49:914:51 | end | |
| taint.cpp:913:10:913:18 | remaining | taint.cpp:914:55:914:63 | remaining | |
| taint.cpp:914:20:914:23 | ref arg dest | taint.cpp:915:9:915:12 | dest | |
| taint.cpp:914:48:914:51 | ref arg & ... | taint.cpp:914:49:914:51 | end [inner post update] | |
| taint.cpp:914:49:914:51 | end | taint.cpp:914:48:914:51 | & ... | |
| taint.cpp:914:54:914:63 | ref arg & ... | taint.cpp:914:55:914:63 | remaining [inner post update] | |
| taint.cpp:914:55:914:63 | remaining | taint.cpp:914:54:914:63 | & ... | |
| taint.cpp:915:9:915:12 | dest | taint.cpp:915:8:915:12 | * ... | |
| taint.cpp:918:19:918:22 | {...} | taint.cpp:919:19:919:22 | dest | |
| taint.cpp:918:19:918:22 | {...} | taint.cpp:919:32:919:35 | dest | |
| taint.cpp:918:19:918:22 | {...} | taint.cpp:920:9:920:12 | dest | |
| taint.cpp:918:21:918:21 | 0 | taint.cpp:918:19:918:22 | {...} | TAINT |
| taint.cpp:919:19:919:22 | ref arg dest | taint.cpp:920:9:920:12 | dest | |
| taint.cpp:920:9:920:12 | dest | taint.cpp:920:8:920:12 | * ... | |
| taint.cpp:923:19:923:22 | {...} | taint.cpp:926:21:926:24 | dest | |
| taint.cpp:923:19:923:22 | {...} | taint.cpp:926:34:926:37 | dest | |
| taint.cpp:923:19:923:22 | {...} | taint.cpp:927:8:927:11 | dest | |
| taint.cpp:923:21:923:21 | 0 | taint.cpp:923:19:923:22 | {...} | TAINT |
| taint.cpp:924:9:924:11 | end | taint.cpp:926:55:926:57 | end | |
| taint.cpp:925:10:925:18 | remaining | taint.cpp:926:61:926:69 | remaining | |
| taint.cpp:926:21:926:24 | ref arg dest | taint.cpp:927:8:927:11 | dest | |
| taint.cpp:926:54:926:57 | ref arg & ... | taint.cpp:926:55:926:57 | end [inner post update] | |
| taint.cpp:926:55:926:57 | end | taint.cpp:926:54:926:57 | & ... | |
| taint.cpp:926:60:926:69 | ref arg & ... | taint.cpp:926:61:926:69 | remaining [inner post update] | |
| taint.cpp:926:61:926:69 | remaining | taint.cpp:926:60:926:69 | & ... | |
| taint.cpp:930:20:930:27 | prefix | taint.cpp:931:17:931:20 | dest | |
| taint.cpp:930:20:930:27 | prefix | taint.cpp:931:30:931:33 | dest | |
| taint.cpp:930:20:930:27 | prefix | taint.cpp:932:9:932:12 | dest | |
| taint.cpp:931:17:931:20 | ref arg dest | taint.cpp:932:9:932:12 | dest | |
| taint.cpp:932:9:932:12 | dest | taint.cpp:932:8:932:12 | * ... | |
| taint.cpp:935:23:935:31 | prefix | taint.cpp:936:17:936:20 | dest | |
| taint.cpp:935:23:935:31 | prefix | taint.cpp:936:30:936:33 | dest | |
| taint.cpp:935:23:935:31 | prefix | taint.cpp:937:9:937:12 | dest | |
| taint.cpp:936:17:936:20 | ref arg dest | taint.cpp:937:9:937:12 | dest | |
| taint.cpp:937:9:937:12 | dest | taint.cpp:937:8:937:12 | * ... | |
| taint.cpp:940:20:940:27 | prefix | taint.cpp:941:16:941:19 | dest | |
| taint.cpp:940:20:940:27 | prefix | taint.cpp:941:29:941:32 | dest | |
| taint.cpp:940:20:940:27 | prefix | taint.cpp:942:9:942:12 | dest | |
| taint.cpp:941:16:941:19 | ref arg dest | taint.cpp:942:9:942:12 | dest | |
| taint.cpp:942:9:942:12 | dest | taint.cpp:942:8:942:12 | * ... | |
| taint.cpp:945:20:945:27 | prefix | taint.cpp:948:19:948:22 | dest | |
| taint.cpp:945:20:945:27 | prefix | taint.cpp:948:32:948:35 | dest | |
| taint.cpp:945:20:945:27 | prefix | taint.cpp:949:9:949:12 | dest | |
| taint.cpp:946:9:946:11 | end | taint.cpp:948:48:948:50 | end | |
| taint.cpp:947:10:947:18 | remaining | taint.cpp:948:54:948:62 | remaining | |
| taint.cpp:948:19:948:22 | ref arg dest | taint.cpp:949:9:949:12 | dest | |
| taint.cpp:948:47:948:50 | ref arg & ... | taint.cpp:948:48:948:50 | end [inner post update] | |
| taint.cpp:948:48:948:50 | end | taint.cpp:948:47:948:50 | & ... | |
| taint.cpp:948:53:948:62 | ref arg & ... | taint.cpp:948:54:948:62 | remaining [inner post update] | |
| taint.cpp:948:54:948:62 | remaining | taint.cpp:948:53:948:62 | & ... | |
| taint.cpp:949:9:949:12 | dest | taint.cpp:949:8:949:12 | * ... | |
| taint.cpp:952:20:952:27 | prefix | taint.cpp:953:18:953:21 | dest | |
| taint.cpp:952:20:952:27 | prefix | taint.cpp:953:31:953:34 | dest | |
| taint.cpp:952:20:952:27 | prefix | taint.cpp:954:9:954:12 | dest | |
| taint.cpp:953:18:953:21 | ref arg dest | taint.cpp:954:9:954:12 | dest | |
| taint.cpp:954:9:954:12 | dest | taint.cpp:954:8:954:12 | * ... | |
| taint.cpp:957:20:957:27 | prefix | taint.cpp:960:20:960:23 | dest | |
| taint.cpp:957:20:957:27 | prefix | taint.cpp:960:33:960:36 | dest | |
| taint.cpp:957:20:957:27 | prefix | taint.cpp:961:9:961:12 | dest | |
| taint.cpp:958:9:958:11 | end | taint.cpp:960:54:960:56 | end | |
| taint.cpp:959:10:959:18 | remaining | taint.cpp:960:60:960:68 | remaining | |
| taint.cpp:960:20:960:23 | ref arg dest | taint.cpp:961:9:961:12 | dest | |
| taint.cpp:960:53:960:56 | ref arg & ... | taint.cpp:960:54:960:56 | end [inner post update] | |
| taint.cpp:960:54:960:56 | end | taint.cpp:960:53:960:56 | & ... | |
| taint.cpp:960:59:960:68 | ref arg & ... | taint.cpp:960:60:960:68 | remaining [inner post update] | |
| taint.cpp:960:60:960:68 | remaining | taint.cpp:960:59:960:68 | & ... | |
| taint.cpp:961:9:961:12 | dest | taint.cpp:961:8:961:12 | * ... | |
| taint.cpp:964:19:964:22 | {...} | taint.cpp:965:20:965:23 | dest | |
| taint.cpp:964:19:964:22 | {...} | taint.cpp:965:33:965:36 | dest | |
| taint.cpp:964:19:964:22 | {...} | taint.cpp:966:9:966:12 | dest | |
| taint.cpp:964:21:964:21 | 0 | taint.cpp:964:19:964:22 | {...} | TAINT |
| taint.cpp:965:20:965:23 | ref arg dest | taint.cpp:966:9:966:12 | dest | |
| taint.cpp:965:40:965:43 | %s | taint.cpp:965:20:965:23 | ref arg dest | TAINT |
| taint.cpp:965:46:965:51 | ref arg source | taint.cpp:975:45:975:50 | source | |
| taint.cpp:965:46:965:51 | ref arg source | taint.cpp:982:69:982:74 | source | |
| taint.cpp:965:46:965:51 | source | taint.cpp:965:20:965:23 | ref arg dest | TAINT |
| taint.cpp:966:9:966:12 | dest | taint.cpp:966:8:966:12 | * ... | |
| taint.cpp:969:22:969:25 | {...} | taint.cpp:970:20:970:23 | dest | |
| taint.cpp:969:22:969:25 | {...} | taint.cpp:970:33:970:36 | dest | |
| taint.cpp:969:22:969:25 | {...} | taint.cpp:971:9:971:12 | dest | |
| taint.cpp:969:24:969:24 | 0 | taint.cpp:969:22:969:25 | {...} | TAINT |
| taint.cpp:970:20:970:23 | ref arg dest | taint.cpp:971:9:971:12 | dest | |
| taint.cpp:970:40:970:44 | %s | taint.cpp:970:20:970:23 | ref arg dest | TAINT |
| taint.cpp:970:47:970:53 | wsource | taint.cpp:970:20:970:23 | ref arg dest | TAINT |
| taint.cpp:971:9:971:12 | dest | taint.cpp:971:8:971:12 | * ... | |
| taint.cpp:974:19:974:22 | {...} | taint.cpp:975:19:975:22 | dest | |
| taint.cpp:974:19:974:22 | {...} | taint.cpp:975:32:975:35 | dest | |
| taint.cpp:974:19:974:22 | {...} | taint.cpp:976:9:976:12 | dest | |
| taint.cpp:974:21:974:21 | 0 | taint.cpp:974:19:974:22 | {...} | TAINT |
| taint.cpp:975:19:975:22 | ref arg dest | taint.cpp:976:9:976:12 | dest | |
| taint.cpp:975:39:975:42 | %s | taint.cpp:975:19:975:22 | ref arg dest | TAINT |
| taint.cpp:975:45:975:50 | ref arg source | taint.cpp:982:69:982:74 | source | |
| taint.cpp:975:45:975:50 | source | taint.cpp:975:19:975:22 | ref arg dest | TAINT |
| taint.cpp:976:9:976:12 | dest | taint.cpp:976:8:976:12 | * ... | |
| taint.cpp:979:19:979:22 | {...} | taint.cpp:982:22:982:25 | dest | |
| taint.cpp:979:19:979:22 | {...} | taint.cpp:982:35:982:38 | dest | |
| taint.cpp:979:19:979:22 | {...} | taint.cpp:983:9:983:12 | dest | |
| taint.cpp:979:21:979:21 | 0 | taint.cpp:979:19:979:22 | {...} | TAINT |
| taint.cpp:980:9:980:11 | end | taint.cpp:982:43:982:45 | end | |
| taint.cpp:981:10:981:18 | remaining | taint.cpp:982:49:982:57 | remaining | |
| taint.cpp:982:22:982:25 | ref arg dest | taint.cpp:983:9:983:12 | dest | |
| taint.cpp:982:42:982:45 | ref arg & ... | taint.cpp:982:43:982:45 | end [inner post update] | |
| taint.cpp:982:43:982:45 | end | taint.cpp:982:42:982:45 | & ... | |
| taint.cpp:982:48:982:57 | ref arg & ... | taint.cpp:982:49:982:57 | remaining [inner post update] | |
| taint.cpp:982:49:982:57 | remaining | taint.cpp:982:48:982:57 | & ... | |
| taint.cpp:982:63:982:66 | %s | taint.cpp:982:22:982:25 | ref arg dest | TAINT |
| taint.cpp:982:69:982:74 | source | taint.cpp:982:22:982:25 | ref arg dest | TAINT |
| taint.cpp:983:9:983:12 | dest | taint.cpp:983:8:983:12 | * ... | |
| taint.cpp:986:19:986:22 | {...} | taint.cpp:988:20:988:23 | dest | |
| taint.cpp:986:19:986:22 | {...} | taint.cpp:988:33:988:36 | dest | |
| taint.cpp:986:19:986:22 | {...} | taint.cpp:989:9:989:12 | dest | |
| taint.cpp:986:21:986:21 | 0 | taint.cpp:986:19:986:22 | {...} | TAINT |
| taint.cpp:987:15:987:29 | call to indirect_source | taint.cpp:988:40:988:42 | fmt | |
| taint.cpp:988:20:988:23 | ref arg dest | taint.cpp:989:9:989:12 | dest | |
| taint.cpp:988:40:988:42 | fmt | taint.cpp:988:20:988:23 | ref arg dest | TAINT |
| taint.cpp:989:9:989:12 | dest | taint.cpp:989:8:989:12 | * ... | |
| taint.cpp:992:19:992:22 | {...} | taint.cpp:993:20:993:23 | dest | |
| taint.cpp:992:19:992:22 | {...} | taint.cpp:993:33:993:36 | dest | |
| taint.cpp:992:19:992:22 | {...} | taint.cpp:994:9:994:12 | dest | |
| taint.cpp:992:21:992:21 | 0 | taint.cpp:992:19:992:22 | {...} | TAINT |
| taint.cpp:993:20:993:23 | ref arg dest | taint.cpp:994:9:994:12 | dest | |
| taint.cpp:993:40:993:43 | %d | taint.cpp:993:20:993:23 | ref arg dest | TAINT |
| taint.cpp:993:46:993:47 | 42 | taint.cpp:993:20:993:23 | ref arg dest | TAINT |
| taint.cpp:994:9:994:12 | dest | taint.cpp:994:8:994:12 | * ... | |
| taint.cpp:997:19:997:22 | {...} | taint.cpp:998:18:998:21 | dest | |
| taint.cpp:997:19:997:22 | {...} | taint.cpp:998:31:998:34 | dest | |
| taint.cpp:997:19:997:22 | {...} | taint.cpp:999:9:999:12 | dest | |
| taint.cpp:997:21:997:21 | 0 | taint.cpp:997:19:997:22 | {...} | TAINT |
| taint.cpp:998:18:998:21 | ref arg dest | taint.cpp:999:9:999:12 | dest | |
| taint.cpp:999:9:999:12 | dest | taint.cpp:999:8:999:12 | * ... | |
| thread.cpp:10:27:10:27 | s | thread.cpp:10:27:10:27 | s | |
| thread.cpp:10:27:10:27 | s | thread.cpp:11:8:11:8 | s | |
| thread.cpp:14:26:14:26 | s | thread.cpp:15:8:15:8 | s | |

View File

@@ -866,136 +866,3 @@ void test_iconv(size_t size) {
iconv(0, &s, &size, &p, &size_out);
sink(*p); // $ ast,ir
}
using va_list = void*;
long StringCchCopyA(char *, size_t, const char *);
long StringCchCopyW(wchar_t *, size_t, const wchar_t *);
long StringCbCopyA(char *, size_t, const char *);
long StringCchCopyExA(char *, size_t, const char *, char **, size_t *, unsigned long);
long StringCchCopyNA(char *, size_t, const char *, size_t);
long StringCchCopyNExA(char *, size_t, const char *, size_t, char **, size_t *, unsigned long);
long StringCchCatA(char *, size_t, const char *);
long StringCchCatW(wchar_t *, size_t, const wchar_t *);
long StringCbCatA(char *, size_t, const char *);
long StringCchCatExA(char *, size_t, const char *, char **, size_t *, unsigned long);
long StringCchCatNA(char *, size_t, const char *, size_t);
long StringCchCatNExA(char *, size_t, const char *, size_t, char **, size_t *, unsigned long);
long StringCchPrintfA(char *, size_t, const char *, ...);
long StringCchPrintfW(wchar_t *, size_t, const wchar_t *, ...);
long StringCbPrintfA(char *, size_t, const char *, ...);
long StringCchPrintfExA(char *, size_t, char **, size_t *, unsigned long, const char *, ...);
long StringCchVPrintfA(char *, size_t, const char *, va_list);
long StringCchVPrintfExA(char *, size_t, char **, size_t *, unsigned long, const char *, va_list);
void test_strsafe() {
char *source = indirect_source();
wchar_t *wsource = (wchar_t *)indirect_source();
{
char dest[256] = {0};
StringCchCopyA(dest, sizeof(dest), source);
sink(*dest); // $ ir MISSING: ast
}
{
wchar_t dest[256] = {0};
StringCchCopyW(dest, sizeof(dest), wsource);
sink(*dest); // $ ir MISSING: ast
}
{
char dest[256] = {0};
StringCbCopyA(dest, sizeof(dest), source);
sink(*dest); // $ ir MISSING: ast
}
{
char dest[256] = {0};
char *end;
size_t remaining;
StringCchCopyExA(dest, sizeof(dest), source, &end, &remaining, 0);
sink(*dest); // $ ir MISSING: ast
}
{
char dest[256] = {0};
StringCchCopyNA(dest, sizeof(dest), source, 128);
sink(*dest); // $ ir MISSING: ast
}
{
char dest[256] = {0};
char *end;
size_t remaining;
StringCchCopyNExA(dest, sizeof(dest), source, 128, &end, &remaining, 0);
sink(dest); // $ ir MISSING: ast
}
{
char dest[256] = "prefix";
StringCchCatA(dest, sizeof(dest), source);
sink(*dest); // $ ir MISSING: ast
}
{
wchar_t dest[256] = L"prefix";
StringCchCatW(dest, sizeof(dest), wsource);
sink(*dest); // $ ir MISSING: ast
}
{
char dest[256] = "prefix";
StringCbCatA(dest, sizeof(dest), source);
sink(*dest); // $ ir MISSING: ast
}
{
char dest[256] = "prefix";
char *end;
size_t remaining;
StringCchCatExA(dest, sizeof(dest), source, &end, &remaining, 0);
sink(*dest); // $ ir MISSING: ast
}
{
char dest[256] = "prefix";
StringCchCatNA(dest, sizeof(dest), source, 128);
sink(*dest); // $ ir MISSING: ast
}
{
char dest[256] = "prefix";
char *end;
size_t remaining;
StringCchCatNExA(dest, sizeof(dest), source, 128, &end, &remaining, 0);
sink(*dest); // $ ir MISSING: ast
}
{
char dest[256] = {0};
StringCchPrintfA(dest, sizeof(dest), "%s", source);
sink(*dest); // $ ir MISSING: ast
}
{
wchar_t dest[256] = {0};
StringCchPrintfW(dest, sizeof(dest), L"%s", wsource);
sink(*dest); // $ ir MISSING: ast
}
{
char dest[256] = {0};
StringCbPrintfA(dest, sizeof(dest), "%s", source);
sink(*dest); // $ ir MISSING: ast
}
{
char dest[256] = {0};
char *end;
size_t remaining;
StringCchPrintfExA(dest, sizeof(dest), &end, &remaining, 0, "%s", source);
sink(*dest); // $ ir MISSING: ast
}
{
char dest[256] = {0};
char *fmt = indirect_source();
StringCchPrintfA(dest, sizeof(dest), fmt);
sink(*dest); // $ ir MISSING: ast
}
{
char dest[256] = {0};
StringCchPrintfA(dest, sizeof(dest), "%d", 42);
sink(*dest); // clean
}
{
char dest[256] = {0};
StringCchCopyA(dest, sizeof(dest), "hello");
sink(*dest); // clean
}
}

View File

@@ -28044,118 +28044,6 @@ getParameterTypeName
| taint.cpp:859:8:859:12 | iconv | 4 | unsigned long * |
| taint.cpp:861:6:861:15 | test_iconv | 0 | size_t |
| taint.cpp:861:6:861:15 | test_iconv | 0 | unsigned long |
| taint.cpp:872:6:872:19 | StringCchCopyA | 0 | char * |
| taint.cpp:872:6:872:19 | StringCchCopyA | 1 | size_t |
| taint.cpp:872:6:872:19 | StringCchCopyA | 1 | unsigned long |
| taint.cpp:872:6:872:19 | StringCchCopyA | 2 | const char * |
| taint.cpp:873:6:873:19 | StringCchCopyW | 0 | wchar_t * |
| taint.cpp:873:6:873:19 | StringCchCopyW | 1 | size_t |
| taint.cpp:873:6:873:19 | StringCchCopyW | 1 | unsigned long |
| taint.cpp:873:6:873:19 | StringCchCopyW | 2 | const wchar_t * |
| taint.cpp:874:6:874:18 | StringCbCopyA | 0 | char * |
| taint.cpp:874:6:874:18 | StringCbCopyA | 1 | size_t |
| taint.cpp:874:6:874:18 | StringCbCopyA | 1 | unsigned long |
| taint.cpp:874:6:874:18 | StringCbCopyA | 2 | const char * |
| taint.cpp:875:6:875:21 | StringCchCopyExA | 0 | char * |
| taint.cpp:875:6:875:21 | StringCchCopyExA | 1 | size_t |
| taint.cpp:875:6:875:21 | StringCchCopyExA | 1 | unsigned long |
| taint.cpp:875:6:875:21 | StringCchCopyExA | 2 | const char * |
| taint.cpp:875:6:875:21 | StringCchCopyExA | 3 | char ** |
| taint.cpp:875:6:875:21 | StringCchCopyExA | 4 | size_t * |
| taint.cpp:875:6:875:21 | StringCchCopyExA | 4 | unsigned long * |
| taint.cpp:875:6:875:21 | StringCchCopyExA | 5 | unsigned long |
| taint.cpp:876:6:876:20 | StringCchCopyNA | 0 | char * |
| taint.cpp:876:6:876:20 | StringCchCopyNA | 1 | size_t |
| taint.cpp:876:6:876:20 | StringCchCopyNA | 1 | unsigned long |
| taint.cpp:876:6:876:20 | StringCchCopyNA | 2 | const char * |
| taint.cpp:876:6:876:20 | StringCchCopyNA | 3 | size_t |
| taint.cpp:876:6:876:20 | StringCchCopyNA | 3 | unsigned long |
| taint.cpp:877:6:877:22 | StringCchCopyNExA | 0 | char * |
| taint.cpp:877:6:877:22 | StringCchCopyNExA | 1 | size_t |
| taint.cpp:877:6:877:22 | StringCchCopyNExA | 1 | unsigned long |
| taint.cpp:877:6:877:22 | StringCchCopyNExA | 2 | const char * |
| taint.cpp:877:6:877:22 | StringCchCopyNExA | 3 | size_t |
| taint.cpp:877:6:877:22 | StringCchCopyNExA | 3 | unsigned long |
| taint.cpp:877:6:877:22 | StringCchCopyNExA | 4 | char ** |
| taint.cpp:877:6:877:22 | StringCchCopyNExA | 5 | size_t * |
| taint.cpp:877:6:877:22 | StringCchCopyNExA | 5 | unsigned long * |
| taint.cpp:877:6:877:22 | StringCchCopyNExA | 6 | unsigned long |
| taint.cpp:878:6:878:18 | StringCchCatA | 0 | char * |
| taint.cpp:878:6:878:18 | StringCchCatA | 1 | size_t |
| taint.cpp:878:6:878:18 | StringCchCatA | 1 | unsigned long |
| taint.cpp:878:6:878:18 | StringCchCatA | 2 | const char * |
| taint.cpp:879:6:879:18 | StringCchCatW | 0 | wchar_t * |
| taint.cpp:879:6:879:18 | StringCchCatW | 1 | size_t |
| taint.cpp:879:6:879:18 | StringCchCatW | 1 | unsigned long |
| taint.cpp:879:6:879:18 | StringCchCatW | 2 | const wchar_t * |
| taint.cpp:880:6:880:17 | StringCbCatA | 0 | char * |
| taint.cpp:880:6:880:17 | StringCbCatA | 1 | size_t |
| taint.cpp:880:6:880:17 | StringCbCatA | 1 | unsigned long |
| taint.cpp:880:6:880:17 | StringCbCatA | 2 | const char * |
| taint.cpp:881:6:881:20 | StringCchCatExA | 0 | char * |
| taint.cpp:881:6:881:20 | StringCchCatExA | 1 | size_t |
| taint.cpp:881:6:881:20 | StringCchCatExA | 1 | unsigned long |
| taint.cpp:881:6:881:20 | StringCchCatExA | 2 | const char * |
| taint.cpp:881:6:881:20 | StringCchCatExA | 3 | char ** |
| taint.cpp:881:6:881:20 | StringCchCatExA | 4 | size_t * |
| taint.cpp:881:6:881:20 | StringCchCatExA | 4 | unsigned long * |
| taint.cpp:881:6:881:20 | StringCchCatExA | 5 | unsigned long |
| taint.cpp:882:6:882:19 | StringCchCatNA | 0 | char * |
| taint.cpp:882:6:882:19 | StringCchCatNA | 1 | size_t |
| taint.cpp:882:6:882:19 | StringCchCatNA | 1 | unsigned long |
| taint.cpp:882:6:882:19 | StringCchCatNA | 2 | const char * |
| taint.cpp:882:6:882:19 | StringCchCatNA | 3 | size_t |
| taint.cpp:882:6:882:19 | StringCchCatNA | 3 | unsigned long |
| taint.cpp:883:6:883:21 | StringCchCatNExA | 0 | char * |
| taint.cpp:883:6:883:21 | StringCchCatNExA | 1 | size_t |
| taint.cpp:883:6:883:21 | StringCchCatNExA | 1 | unsigned long |
| taint.cpp:883:6:883:21 | StringCchCatNExA | 2 | const char * |
| taint.cpp:883:6:883:21 | StringCchCatNExA | 3 | size_t |
| taint.cpp:883:6:883:21 | StringCchCatNExA | 3 | unsigned long |
| taint.cpp:883:6:883:21 | StringCchCatNExA | 4 | char ** |
| taint.cpp:883:6:883:21 | StringCchCatNExA | 5 | size_t * |
| taint.cpp:883:6:883:21 | StringCchCatNExA | 5 | unsigned long * |
| taint.cpp:883:6:883:21 | StringCchCatNExA | 6 | unsigned long |
| taint.cpp:884:6:884:21 | StringCchPrintfA | 0 | char * |
| taint.cpp:884:6:884:21 | StringCchPrintfA | 1 | size_t |
| taint.cpp:884:6:884:21 | StringCchPrintfA | 1 | unsigned long |
| taint.cpp:884:6:884:21 | StringCchPrintfA | 2 | const char * |
| taint.cpp:884:6:884:21 | StringCchPrintfA | 3 | ... |
| taint.cpp:885:6:885:21 | StringCchPrintfW | 0 | wchar_t * |
| taint.cpp:885:6:885:21 | StringCchPrintfW | 1 | size_t |
| taint.cpp:885:6:885:21 | StringCchPrintfW | 1 | unsigned long |
| taint.cpp:885:6:885:21 | StringCchPrintfW | 2 | const wchar_t * |
| taint.cpp:885:6:885:21 | StringCchPrintfW | 3 | ... |
| taint.cpp:886:6:886:20 | StringCbPrintfA | 0 | char * |
| taint.cpp:886:6:886:20 | StringCbPrintfA | 1 | size_t |
| taint.cpp:886:6:886:20 | StringCbPrintfA | 1 | unsigned long |
| taint.cpp:886:6:886:20 | StringCbPrintfA | 2 | const char * |
| taint.cpp:886:6:886:20 | StringCbPrintfA | 3 | ... |
| taint.cpp:887:6:887:23 | StringCchPrintfExA | 0 | char * |
| taint.cpp:887:6:887:23 | StringCchPrintfExA | 1 | size_t |
| taint.cpp:887:6:887:23 | StringCchPrintfExA | 1 | unsigned long |
| taint.cpp:887:6:887:23 | StringCchPrintfExA | 2 | char ** |
| taint.cpp:887:6:887:23 | StringCchPrintfExA | 3 | size_t * |
| taint.cpp:887:6:887:23 | StringCchPrintfExA | 3 | unsigned long * |
| taint.cpp:887:6:887:23 | StringCchPrintfExA | 4 | unsigned long |
| taint.cpp:887:6:887:23 | StringCchPrintfExA | 5 | const char * |
| taint.cpp:887:6:887:23 | StringCchPrintfExA | 6 | ... |
| taint.cpp:888:6:888:22 | StringCchVPrintfA | 0 | char * |
| taint.cpp:888:6:888:22 | StringCchVPrintfA | 1 | size_t |
| taint.cpp:888:6:888:22 | StringCchVPrintfA | 1 | unsigned long |
| taint.cpp:888:6:888:22 | StringCchVPrintfA | 2 | const char * |
| taint.cpp:888:6:888:22 | StringCchVPrintfA | 3 | va_list |
| taint.cpp:888:6:888:22 | StringCchVPrintfA | 3 | void * |
| taint.cpp:889:6:889:24 | StringCchVPrintfExA | 0 | char * |
| taint.cpp:889:6:889:24 | StringCchVPrintfExA | 1 | size_t |
| taint.cpp:889:6:889:24 | StringCchVPrintfExA | 1 | unsigned long |
| taint.cpp:889:6:889:24 | StringCchVPrintfExA | 2 | char ** |
| taint.cpp:889:6:889:24 | StringCchVPrintfExA | 3 | size_t * |
| taint.cpp:889:6:889:24 | StringCchVPrintfExA | 3 | unsigned long * |
| taint.cpp:889:6:889:24 | StringCchVPrintfExA | 4 | unsigned long |
| taint.cpp:889:6:889:24 | StringCchVPrintfExA | 5 | const char * |
| taint.cpp:889:6:889:24 | StringCchVPrintfExA | 6 | va_list |
| taint.cpp:889:6:889:24 | StringCchVPrintfExA | 6 | void * |
| thread.cpp:4:6:4:9 | sink | 0 | int |
| thread.cpp:6:8:6:8 | operator= | 0 | S && |
| thread.cpp:6:8:6:8 | operator= | 0 | const S & |

View File

@@ -25796,9 +25796,9 @@ ir.cpp:
# 2919| getExpr(): [FunctionCall] call to VariableTemplateFunc
# 2919| Type = [DoubleType] double
# 2919| ValueCategory = prvalue
# 2919| getArgument(0): [Literal] 2.3
# 2919| getArgument(0): [Literal] 2.299999999999999822
# 2919| Type = [DoubleType] double
# 2919| Value = [Literal] 2.3
# 2919| Value = [Literal] 2.299999999999999822
# 2919| ValueCategory = prvalue
# 2919| getExpr().getFullyConverted(): [CStyleCast] (int)...
# 2919| Conversion = [FloatingPointToIntegralConversion] floating point to integral conversion

View File

@@ -12954,21 +12954,21 @@ ir.cpp:
# 1592| double StructuredBindingTupleRefGet::d
# 1592| Block 0
# 1592| v1592_1(void) = EnterFunction :
# 1592| m1592_2(unknown) = AliasedDefinition :
# 1592| m1592_3(unknown) = InitializeNonLocal :
# 1592| m1592_4(unknown) = Chi : total:m1592_2, partial:m1592_3
# 1592| r1592_5(glval<unknown>) = VariableAddress[#this] :
# 1592| m1592_6(glval<StructuredBindingTupleRefGet>) = InitializeParameter[#this] : &:r1592_5
# 1592| r1592_7(glval<StructuredBindingTupleRefGet>) = Load[#this] : &:r1592_5, m1592_6
# 1592| m1592_8(StructuredBindingTupleRefGet) = InitializeIndirection[#this] : &:r1592_7
# 1592| r1592_9(glval<double>) = FieldAddress[d] : r1592_7
# 1592| r1592_10(double) = Constant[2.2] :
# 1592| m1592_11(double) = Store[?] : &:r1592_9, r1592_10
# 1592| m1592_12(unknown) = Chi : total:m1592_8, partial:m1592_11
# 1592| v1592_13(void) = ReturnVoid :
# 1592| v1592_14(void) = AliasedUse : m1592_3
# 1592| v1592_15(void) = ExitFunction :
# 1592| v1592_1(void) = EnterFunction :
# 1592| m1592_2(unknown) = AliasedDefinition :
# 1592| m1592_3(unknown) = InitializeNonLocal :
# 1592| m1592_4(unknown) = Chi : total:m1592_2, partial:m1592_3
# 1592| r1592_5(glval<unknown>) = VariableAddress[#this] :
# 1592| m1592_6(glval<StructuredBindingTupleRefGet>) = InitializeParameter[#this] : &:r1592_5
# 1592| r1592_7(glval<StructuredBindingTupleRefGet>) = Load[#this] : &:r1592_5, m1592_6
# 1592| m1592_8(StructuredBindingTupleRefGet) = InitializeIndirection[#this] : &:r1592_7
# 1592| r1592_9(glval<double>) = FieldAddress[d] : r1592_7
# 1592| r1592_10(double) = Constant[2.200000000000000178] :
# 1592| m1592_11(double) = Store[?] : &:r1592_9, r1592_10
# 1592| m1592_12(unknown) = Chi : total:m1592_8, partial:m1592_11
# 1592| v1592_13(void) = ReturnVoid :
# 1592| v1592_14(void) = AliasedUse : m1592_3
# 1592| v1592_15(void) = ExitFunction :
# 1593| int& StructuredBindingTupleRefGet::r
# 1593| Block 0
@@ -21761,7 +21761,7 @@ ir.cpp:
# 2919| m2919_2(unknown) = AliasedDefinition :
# 2919| r2919_3(glval<int>) = VariableAddress[VariableTemplateFuncUse] :
# 2919| r2919_4(glval<unknown>) = FunctionAddress[VariableTemplateFunc] :
# 2919| r2919_5(double) = Constant[2.3] :
# 2919| r2919_5(double) = Constant[2.299999999999999822] :
# 2919| r2919_6(double) = Call[VariableTemplateFunc] : func:r2919_4, 0:r2919_5
# 2919| m2919_7(unknown) = ^CallSideEffect : ~m2919_2
# 2919| m2919_8(unknown) = Chi : total:m2919_2, partial:m2919_7

View File

@@ -11861,19 +11861,19 @@ ir.cpp:
# 1592| double StructuredBindingTupleRefGet::d
# 1592| Block 0
# 1592| v1592_1(void) = EnterFunction :
# 1592| mu1592_2(unknown) = AliasedDefinition :
# 1592| mu1592_3(unknown) = InitializeNonLocal :
# 1592| r1592_4(glval<unknown>) = VariableAddress[#this] :
# 1592| mu1592_5(glval<StructuredBindingTupleRefGet>) = InitializeParameter[#this] : &:r1592_4
# 1592| r1592_6(glval<StructuredBindingTupleRefGet>) = Load[#this] : &:r1592_4, ~m?
# 1592| mu1592_7(StructuredBindingTupleRefGet) = InitializeIndirection[#this] : &:r1592_6
# 1592| r1592_8(glval<double>) = FieldAddress[d] : r1592_6
# 1592| r1592_9(double) = Constant[2.2] :
# 1592| mu1592_10(double) = Store[?] : &:r1592_8, r1592_9
# 1592| v1592_11(void) = ReturnVoid :
# 1592| v1592_12(void) = AliasedUse : ~m?
# 1592| v1592_13(void) = ExitFunction :
# 1592| v1592_1(void) = EnterFunction :
# 1592| mu1592_2(unknown) = AliasedDefinition :
# 1592| mu1592_3(unknown) = InitializeNonLocal :
# 1592| r1592_4(glval<unknown>) = VariableAddress[#this] :
# 1592| mu1592_5(glval<StructuredBindingTupleRefGet>) = InitializeParameter[#this] : &:r1592_4
# 1592| r1592_6(glval<StructuredBindingTupleRefGet>) = Load[#this] : &:r1592_4, ~m?
# 1592| mu1592_7(StructuredBindingTupleRefGet) = InitializeIndirection[#this] : &:r1592_6
# 1592| r1592_8(glval<double>) = FieldAddress[d] : r1592_6
# 1592| r1592_9(double) = Constant[2.200000000000000178] :
# 1592| mu1592_10(double) = Store[?] : &:r1592_8, r1592_9
# 1592| v1592_11(void) = ReturnVoid :
# 1592| v1592_12(void) = AliasedUse : ~m?
# 1592| v1592_13(void) = ExitFunction :
# 1593| int& StructuredBindingTupleRefGet::r
# 1593| Block 0
@@ -19768,7 +19768,7 @@ ir.cpp:
# 2919| mu2919_2(unknown) = AliasedDefinition :
# 2919| r2919_3(glval<int>) = VariableAddress[VariableTemplateFuncUse] :
# 2919| r2919_4(glval<unknown>) = FunctionAddress[VariableTemplateFunc] :
# 2919| r2919_5(double) = Constant[2.3] :
# 2919| r2919_5(double) = Constant[2.299999999999999822] :
# 2919| r2919_6(double) = Call[VariableTemplateFunc] : func:r2919_4, 0:r2919_5
# 2919| mu2919_7(unknown) = ^CallSideEffect : ~m?
# 2919| r2919_8(int) = Convert : r2919_6

View File

@@ -1293,12 +1293,12 @@ estimateNrOfBounds
| test.c:415:26:415:69 | ... ? ... : ... | 1.0 | 1.0 | 1.0 |
| test.c:415:30:415:30 | q | 1.0 | 1.0 | 1.0 |
| test.c:415:30:415:56 | ... ? ... : ... | 1.0 | 1.0 | 1.0 |
| test.c:415:34:415:43 | 0.47438827 | 1.0 | -1.0 | -1.0 |
| test.c:415:47:415:56 | 0.14333887 | 1.0 | -1.0 | -1.0 |
| test.c:415:60:415:69 | 0.35279203 | 1.0 | -1.0 | -1.0 |
| test.c:415:73:415:82 | 0.39206458 | 1.0 | -1.0 | -1.0 |
| test.c:415:86:415:95 | 0.21540225 | 1.0 | -1.0 | -1.0 |
| test.c:415:99:415:108 | 0.40496805 | 1.0 | -1.0 | -1.0 |
| test.c:415:34:415:43 | 0.4743882700000000008 | 1.0 | -1.0 | -1.0 |
| test.c:415:47:415:56 | 0.1433388700000000071 | 1.0 | -1.0 | -1.0 |
| test.c:415:60:415:69 | 0.3527920299999999787 | 1.0 | -1.0 | -1.0 |
| test.c:415:73:415:82 | 0.3920645799999999959 | 1.0 | -1.0 | -1.0 |
| test.c:415:86:415:95 | 0.2154022499999999896 | 1.0 | -1.0 | -1.0 |
| test.c:415:99:415:108 | 0.4049680500000000238 | 1.0 | -1.0 | -1.0 |
| test.c:416:14:416:14 | m | 2.0 | 1.0 | 1.0 |
| test.c:416:14:416:108 | ... ? ... : ... | 1.0 | 1.0 | 1.0 |
| test.c:416:18:416:18 | n | 3.0 | 1.0 | 1.0 |
@@ -1309,12 +1309,12 @@ estimateNrOfBounds
| test.c:416:26:416:69 | ... ? ... : ... | 1.0 | 1.0 | 1.0 |
| test.c:416:30:416:30 | q | 3.0 | 1.0 | 1.0 |
| test.c:416:30:416:56 | ... ? ... : ... | 1.0 | 1.0 | 1.0 |
| test.c:416:34:416:43 | 0.34183348 | 1.0 | -1.0 | -1.0 |
| test.c:416:47:416:56 | 0.3533464 | 1.0 | -1.0 | -1.0 |
| test.c:416:60:416:69 | 0.22247853 | 1.0 | -1.0 | -1.0 |
| test.c:416:73:416:82 | 0.32661893 | 1.0 | -1.0 | -1.0 |
| test.c:416:86:416:95 | 0.59270465 | 1.0 | -1.0 | -1.0 |
| test.c:416:99:416:108 | 0.5297741 | 1.0 | -1.0 | -1.0 |
| test.c:416:34:416:43 | 0.3418334800000000229 | 1.0 | -1.0 | -1.0 |
| test.c:416:47:416:56 | 0.3533464000000000049 | 1.0 | -1.0 | -1.0 |
| test.c:416:60:416:69 | 0.2224785300000000077 | 1.0 | -1.0 | -1.0 |
| test.c:416:73:416:82 | 0.326618929999999974 | 1.0 | -1.0 | -1.0 |
| test.c:416:86:416:95 | 0.5927046500000000551 | 1.0 | -1.0 | -1.0 |
| test.c:416:99:416:108 | 0.5297741000000000255 | 1.0 | -1.0 | -1.0 |
| test.c:417:14:417:14 | m | 3.5 | 1.0 | 1.0 |
| test.c:417:14:417:108 | ... ? ... : ... | 1.0 | 1.0 | 1.0 |
| test.c:417:18:417:18 | n | 8.0 | 1.0 | 1.0 |
@@ -1325,12 +1325,12 @@ estimateNrOfBounds
| test.c:417:26:417:69 | ... ? ... : ... | 1.0 | 1.0 | 1.0 |
| test.c:417:30:417:30 | q | 8.0 | 1.0 | 1.0 |
| test.c:417:30:417:56 | ... ? ... : ... | 1.0 | 1.0 | 1.0 |
| test.c:417:34:417:43 | 0.77429603 | 1.0 | -1.0 | -1.0 |
| test.c:417:47:417:56 | 0.31478084 | 1.0 | -1.0 | -1.0 |
| test.c:417:60:417:69 | 0.31235514 | 1.0 | -1.0 | -1.0 |
| test.c:417:73:417:82 | 0.05121256 | 1.0 | -1.0 | -1.0 |
| test.c:417:86:417:95 | 0.79310745 | 1.0 | -1.0 | -1.0 |
| test.c:417:99:417:108 | 0.67981451 | 1.0 | -1.0 | -1.0 |
| test.c:417:34:417:43 | 0.774296030000000024 | 1.0 | -1.0 | -1.0 |
| test.c:417:47:417:56 | 0.3147808400000000062 | 1.0 | -1.0 | -1.0 |
| test.c:417:60:417:69 | 0.3123551399999999756 | 1.0 | -1.0 | -1.0 |
| test.c:417:73:417:82 | 0.05121255999999999725 | 1.0 | -1.0 | -1.0 |
| test.c:417:86:417:95 | 0.7931074500000000471 | 1.0 | -1.0 | -1.0 |
| test.c:417:99:417:108 | 0.6798145100000000385 | 1.0 | -1.0 | -1.0 |
| test.c:418:14:418:14 | m | 5.75 | 1.0 | 1.0 |
| test.c:418:14:418:108 | ... ? ... : ... | 1.0 | 1.0 | 1.0 |
| test.c:418:18:418:18 | n | 20.5 | 1.0 | 1.0 |
@@ -1341,12 +1341,12 @@ estimateNrOfBounds
| test.c:418:26:418:69 | ... ? ... : ... | 1.0 | 1.0 | 1.0 |
| test.c:418:30:418:30 | q | 20.5 | 1.0 | 1.0 |
| test.c:418:30:418:56 | ... ? ... : ... | 1.0 | 1.0 | 1.0 |
| test.c:418:34:418:43 | 0.44729556 | 1.0 | -1.0 | -1.0 |
| test.c:418:47:418:56 | 0.80599202 | 1.0 | -1.0 | -1.0 |
| test.c:418:60:418:69 | 0.98997262 | 1.0 | -1.0 | -1.0 |
| test.c:418:73:418:82 | 0.59952732 | 1.0 | -1.0 | -1.0 |
| test.c:418:86:418:95 | 0.36976948 | 1.0 | -1.0 | -1.0 |
| test.c:418:99:418:108 | 0.83866835 | 1.0 | -1.0 | -1.0 |
| test.c:418:34:418:43 | 0.4472955599999999809 | 1.0 | -1.0 | -1.0 |
| test.c:418:47:418:56 | 0.8059920200000000312 | 1.0 | -1.0 | -1.0 |
| test.c:418:60:418:69 | 0.9899726199999999698 | 1.0 | -1.0 | -1.0 |
| test.c:418:73:418:82 | 0.5995273199999999747 | 1.0 | -1.0 | -1.0 |
| test.c:418:86:418:95 | 0.3697694799999999837 | 1.0 | -1.0 | -1.0 |
| test.c:418:99:418:108 | 0.8386683499999999514 | 1.0 | -1.0 | -1.0 |
| test.c:419:14:419:14 | m | 9.125 | 1.0 | 1.0 |
| test.c:419:14:419:108 | ... ? ... : ... | 1.0 | 1.0 | 1.0 |
| test.c:419:18:419:18 | n | 51.75 | 1.0 | 1.0 |
@@ -1357,12 +1357,12 @@ estimateNrOfBounds
| test.c:419:26:419:69 | ... ? ... : ... | 1.0 | 1.0 | 1.0 |
| test.c:419:30:419:30 | q | 51.75 | 1.0 | 1.0 |
| test.c:419:30:419:56 | ... ? ... : ... | 1.0 | 1.0 | 1.0 |
| test.c:419:34:419:43 | 0.49311828 | 1.0 | -1.0 | -1.0 |
| test.c:419:47:419:56 | 0.90389911 | 1.0 | -1.0 | -1.0 |
| test.c:419:60:419:69 | 0.10597712 | 1.0 | -1.0 | -1.0 |
| test.c:419:73:419:82 | 0.21778426 | 1.0 | -1.0 | -1.0 |
| test.c:419:86:419:95 | 0.72485966 | 1.0 | -1.0 | -1.0 |
| test.c:419:99:419:108 | 0.68734874 | 1.0 | -1.0 | -1.0 |
| test.c:419:34:419:43 | 0.4931182800000000199 | 1.0 | -1.0 | -1.0 |
| test.c:419:47:419:56 | 0.9038991100000000056 | 1.0 | -1.0 | -1.0 |
| test.c:419:60:419:69 | 0.1059771199999999941 | 1.0 | -1.0 | -1.0 |
| test.c:419:73:419:82 | 0.2177842600000000073 | 1.0 | -1.0 | -1.0 |
| test.c:419:86:419:95 | 0.7248596600000000167 | 1.0 | -1.0 | -1.0 |
| test.c:419:99:419:108 | 0.6873487400000000136 | 1.0 | -1.0 | -1.0 |
| test.c:420:14:420:14 | m | 14.1875 | 1.0 | 1.0 |
| test.c:420:14:420:108 | ... ? ... : ... | 1.0 | 1.0 | 1.0 |
| test.c:420:18:420:18 | n | 129.875 | 1.0 | 1.0 |
@@ -1373,12 +1373,12 @@ estimateNrOfBounds
| test.c:420:26:420:69 | ... ? ... : ... | 1.0 | 1.0 | 1.0 |
| test.c:420:30:420:30 | q | 129.875 | 1.0 | 1.0 |
| test.c:420:30:420:56 | ... ? ... : ... | 1.0 | 1.0 | 1.0 |
| test.c:420:34:420:43 | 0.47452848 | 1.0 | -1.0 | -1.0 |
| test.c:420:47:420:56 | 0.1078665 | 1.0 | -1.0 | -1.0 |
| test.c:420:60:420:69 | 0.11884576 | 1.0 | -1.0 | -1.0 |
| test.c:420:73:420:82 | 0.76164052 | 1.0 | -1.0 | -1.0 |
| test.c:420:86:420:95 | 0.34808892 | 1.0 | -1.0 | -1.0 |
| test.c:420:99:420:108 | 0.58440865 | 1.0 | -1.0 | -1.0 |
| test.c:420:34:420:43 | 0.4745284799999999747 | 1.0 | -1.0 | -1.0 |
| test.c:420:47:420:56 | 0.107866500000000004 | 1.0 | -1.0 | -1.0 |
| test.c:420:60:420:69 | 0.1188457599999999947 | 1.0 | -1.0 | -1.0 |
| test.c:420:73:420:82 | 0.7616405200000000431 | 1.0 | -1.0 | -1.0 |
| test.c:420:86:420:95 | 0.3480889200000000239 | 1.0 | -1.0 | -1.0 |
| test.c:420:99:420:108 | 0.584408649999999974 | 1.0 | -1.0 | -1.0 |
| test.c:421:14:421:14 | m | 21.78125 | 1.0 | 1.0 |
| test.c:421:14:421:108 | ... ? ... : ... | 1.0 | 1.0 | 1.0 |
| test.c:421:18:421:18 | n | 325.1875 | 1.0 | 1.0 |
@@ -1390,11 +1390,11 @@ estimateNrOfBounds
| test.c:421:30:421:30 | q | 325.1875 | 1.0 | 1.0 |
| test.c:421:30:421:56 | ... ? ... : ... | 1.0 | 1.0 | 1.0 |
| test.c:421:34:421:43 | 0.02524326 | 1.0 | -1.0 | -1.0 |
| test.c:421:47:421:56 | 0.82905046 | 1.0 | -1.0 | -1.0 |
| test.c:421:60:421:69 | 0.95823075 | 1.0 | -1.0 | -1.0 |
| test.c:421:73:421:82 | 0.12516558 | 1.0 | -1.0 | -1.0 |
| test.c:421:86:421:95 | 0.85235179 | 1.0 | -1.0 | -1.0 |
| test.c:421:99:421:108 | 0.36232384 | 1.0 | -1.0 | -1.0 |
| test.c:421:47:421:56 | 0.8290504600000000446 | 1.0 | -1.0 | -1.0 |
| test.c:421:60:421:69 | 0.95823075000000002 | 1.0 | -1.0 | -1.0 |
| test.c:421:73:421:82 | 0.1251655799999999985 | 1.0 | -1.0 | -1.0 |
| test.c:421:86:421:95 | 0.8523517900000000536 | 1.0 | -1.0 | -1.0 |
| test.c:421:99:421:108 | 0.3623238400000000081 | 1.0 | -1.0 | -1.0 |
| test.c:422:14:422:14 | m | 33.171875 | 1.0 | 1.0 |
| test.c:422:14:422:108 | ... ? ... : ... | 1.0 | 1.0 | 1.0 |
| test.c:422:18:422:18 | n | 813.46875 | 1.0 | 1.0 |
@@ -1405,12 +1405,12 @@ estimateNrOfBounds
| test.c:422:26:422:69 | ... ? ... : ... | 1.0 | 1.0 | 1.0 |
| test.c:422:30:422:30 | q | 813.46875 | 1.0 | 1.0 |
| test.c:422:30:422:56 | ... ? ... : ... | 1.0 | 1.0 | 1.0 |
| test.c:422:34:422:43 | 0.38708626 | 1.0 | -1.0 | -1.0 |
| test.c:422:47:422:56 | 0.32876044 | 1.0 | -1.0 | -1.0 |
| test.c:422:60:422:69 | 0.14963485 | 1.0 | -1.0 | -1.0 |
| test.c:422:73:422:82 | 0.45041108 | 1.0 | -1.0 | -1.0 |
| test.c:422:86:422:95 | 0.48640909 | 1.0 | -1.0 | -1.0 |
| test.c:422:99:422:108 | 0.84331272 | 1.0 | -1.0 | -1.0 |
| test.c:422:34:422:43 | 0.3870862600000000153 | 1.0 | -1.0 | -1.0 |
| test.c:422:47:422:56 | 0.3287604399999999871 | 1.0 | -1.0 | -1.0 |
| test.c:422:60:422:69 | 0.1496348500000000137 | 1.0 | -1.0 | -1.0 |
| test.c:422:73:422:82 | 0.4504110800000000192 | 1.0 | -1.0 | -1.0 |
| test.c:422:86:422:95 | 0.4864090899999999884 | 1.0 | -1.0 | -1.0 |
| test.c:422:99:422:108 | 0.8433127200000000157 | 1.0 | -1.0 | -1.0 |
| test.c:423:14:423:14 | m | 50.2578125 | 1.0 | 1.0 |
| test.c:423:14:423:108 | ... ? ... : ... | 1.0 | 1.0 | 1.0 |
| test.c:423:18:423:18 | n | 2034.171875 | 1.0 | 1.0 |
@@ -1421,12 +1421,12 @@ estimateNrOfBounds
| test.c:423:26:423:69 | ... ? ... : ... | 1.0 | 1.0 | 1.0 |
| test.c:423:30:423:30 | q | 2034.171875 | 1.0 | 1.0 |
| test.c:423:30:423:56 | ... ? ... : ... | 1.0 | 1.0 | 1.0 |
| test.c:423:34:423:43 | 0.15755063 | 1.0 | -1.0 | -1.0 |
| test.c:423:47:423:56 | 0.77086833 | 1.0 | -1.0 | -1.0 |
| test.c:423:60:423:69 | 0.26428481 | 1.0 | -1.0 | -1.0 |
| test.c:423:73:423:82 | 0.14800508 | 1.0 | -1.0 | -1.0 |
| test.c:423:86:423:95 | 0.37428143 | 1.0 | -1.0 | -1.0 |
| test.c:423:99:423:108 | 0.05328182 | 1.0 | -1.0 | -1.0 |
| test.c:423:34:423:43 | 0.1575506299999999971 | 1.0 | -1.0 | -1.0 |
| test.c:423:47:423:56 | 0.7708683299999999905 | 1.0 | -1.0 | -1.0 |
| test.c:423:60:423:69 | 0.2642848099999999811 | 1.0 | -1.0 | -1.0 |
| test.c:423:73:423:82 | 0.1480050800000000111 | 1.0 | -1.0 | -1.0 |
| test.c:423:86:423:95 | 0.374281430000000026 | 1.0 | -1.0 | -1.0 |
| test.c:423:99:423:108 | 0.05328182000000000057 | 1.0 | -1.0 | -1.0 |
| test.c:424:14:424:14 | m | 75.88671875 | 1.0 | 1.0 |
| test.c:424:14:424:108 | ... ? ... : ... | 1.0 | 1.0 | 1.0 |
| test.c:424:18:424:18 | n | 5085.9296875 | 1.0 | 1.0 |
@@ -1437,12 +1437,12 @@ estimateNrOfBounds
| test.c:424:26:424:69 | ... ? ... : ... | 1.0 | 1.0 | 1.0 |
| test.c:424:30:424:30 | q | 5085.9296875 | 1.0 | 1.0 |
| test.c:424:30:424:56 | ... ? ... : ... | 1.0 | 1.0 | 1.0 |
| test.c:424:34:424:43 | 0.41736536 | 1.0 | -1.0 | -1.0 |
| test.c:424:47:424:56 | 0.76826628 | 1.0 | -1.0 | -1.0 |
| test.c:424:60:424:69 | 0.27643238 | 1.0 | -1.0 | -1.0 |
| test.c:424:73:424:82 | 0.55679274 | 1.0 | -1.0 | -1.0 |
| test.c:424:86:424:95 | 0.39468857 | 1.0 | -1.0 | -1.0 |
| test.c:424:99:424:108 | 0.69072144 | 1.0 | -1.0 | -1.0 |
| test.c:424:34:424:43 | 0.4173653600000000186 | 1.0 | -1.0 | -1.0 |
| test.c:424:47:424:56 | 0.7682662799999999681 | 1.0 | -1.0 | -1.0 |
| test.c:424:60:424:69 | 0.2764323799999999776 | 1.0 | -1.0 | -1.0 |
| test.c:424:73:424:82 | 0.5567927400000000082 | 1.0 | -1.0 | -1.0 |
| test.c:424:86:424:95 | 0.3946885700000000163 | 1.0 | -1.0 | -1.0 |
| test.c:424:99:424:108 | 0.6907214400000000198 | 1.0 | -1.0 | -1.0 |
| test.c:425:14:425:14 | m | 114.330078125 | 1.0 | 1.0 |
| test.c:425:14:425:108 | ... ? ... : ... | 1.0 | 1.0 | 1.0 |
| test.c:425:18:425:18 | n | 12715.32421875 | 1.0 | 1.0 |
@@ -1453,12 +1453,12 @@ estimateNrOfBounds
| test.c:425:26:425:69 | ... ? ... : ... | 1.0 | 1.0 | 1.0 |
| test.c:425:30:425:30 | q | 12715.32421875 | 1.0 | 1.0 |
| test.c:425:30:425:56 | ... ? ... : ... | 1.0 | 1.0 | 1.0 |
| test.c:425:34:425:43 | 0.88955345 | 1.0 | -1.0 | -1.0 |
| test.c:425:47:425:56 | 0.29904824 | 1.0 | -1.0 | -1.0 |
| test.c:425:60:425:69 | 0.76242583 | 1.0 | -1.0 | -1.0 |
| test.c:425:73:425:82 | 0.2051911 | 1.0 | -1.0 | -1.0 |
| test.c:425:86:425:95 | 0.88745559 | 1.0 | -1.0 | -1.0 |
| test.c:425:99:425:108 | 0.81372798 | 1.0 | -1.0 | -1.0 |
| test.c:425:34:425:43 | 0.8895534499999999678 | 1.0 | -1.0 | -1.0 |
| test.c:425:47:425:56 | 0.2990482400000000207 | 1.0 | -1.0 | -1.0 |
| test.c:425:60:425:69 | 0.7624258299999999711 | 1.0 | -1.0 | -1.0 |
| test.c:425:73:425:82 | 0.2051910999999999874 | 1.0 | -1.0 | -1.0 |
| test.c:425:86:425:95 | 0.8874555899999999609 | 1.0 | -1.0 | -1.0 |
| test.c:425:99:425:108 | 0.8137279800000000174 | 1.0 | -1.0 | -1.0 |
| test.c:426:14:426:14 | m | 171.9951171875 | 1.0 | 1.0 |
| test.c:426:14:426:108 | ... ? ... : ... | 1.0 | 1.0 | 1.0 |
| test.c:426:18:426:18 | n | 31788.810546875 | 1.0 | 1.0 |
@@ -1469,12 +1469,12 @@ estimateNrOfBounds
| test.c:426:26:426:69 | ... ? ... : ... | 1.0 | 1.0 | 1.0 |
| test.c:426:30:426:30 | q | 31788.810546875 | 1.0 | 1.0 |
| test.c:426:30:426:56 | ... ? ... : ... | 1.0 | 1.0 | 1.0 |
| test.c:426:34:426:43 | 0.42186276 | 1.0 | -1.0 | -1.0 |
| test.c:426:47:426:56 | 0.53843358 | 1.0 | -1.0 | -1.0 |
| test.c:426:60:426:69 | 0.44996679 | 1.0 | -1.0 | -1.0 |
| test.c:426:73:426:82 | 0.13204114 | 1.0 | -1.0 | -1.0 |
| test.c:426:86:426:95 | 0.52031241 | 1.0 | -1.0 | -1.0 |
| test.c:426:99:426:108 | 0.42762647 | 1.0 | -1.0 | -1.0 |
| test.c:426:34:426:43 | 0.4218627600000000033 | 1.0 | -1.0 | -1.0 |
| test.c:426:47:426:56 | 0.5384335799999999672 | 1.0 | -1.0 | -1.0 |
| test.c:426:60:426:69 | 0.4499667900000000054 | 1.0 | -1.0 | -1.0 |
| test.c:426:73:426:82 | 0.1320411400000000013 | 1.0 | -1.0 | -1.0 |
| test.c:426:86:426:95 | 0.5203124099999999475 | 1.0 | -1.0 | -1.0 |
| test.c:426:99:426:108 | 0.4276264699999999808 | 1.0 | -1.0 | -1.0 |
| test.c:432:19:432:19 | a | 1.0 | 1.0 | 1.0 |
| test.c:432:19:432:23 | ... + ... | 1.0 | 1.0 | 1.0 |
| test.c:432:19:432:27 | ... + ... | 1.0 | 1.0 | 1.0 |

View File

@@ -11,13 +11,8 @@ edges
| nested.cpp:86:19:86:46 | *call to __builtin_alloca | nested.cpp:87:18:87:20 | *fmt | provenance | |
| test.cpp:46:27:46:30 | **argv | test.cpp:130:20:130:26 | *access to array | provenance | |
| test.cpp:167:31:167:34 | *data | test.cpp:170:12:170:14 | *res | provenance | DataFlowFunction |
| test.cpp:179:6:179:21 | [summary param] *2 in StringCchPrintfW | test.cpp:179:6:179:21 | [summary param] *0 in StringCchPrintfW [Return] | provenance | MaD:403 |
| test.cpp:193:32:193:34 | *str | test.cpp:195:31:195:33 | *str | provenance | |
| test.cpp:193:32:193:34 | *str | test.cpp:195:31:195:33 | *str | provenance | |
| test.cpp:193:32:193:34 | *str | test.cpp:197:11:197:14 | *wstr | provenance | TaintFunction |
| test.cpp:195:20:195:23 | StringCchPrintfW output argument | test.cpp:197:11:197:14 | *wstr | provenance | |
| test.cpp:195:31:195:33 | *str | test.cpp:179:6:179:21 | [summary param] *2 in StringCchPrintfW | provenance | |
| test.cpp:195:31:195:33 | *str | test.cpp:195:20:195:23 | StringCchPrintfW output argument | provenance | MaD:403 |
| test.cpp:204:25:204:36 | *call to get_string | test.cpp:204:25:204:36 | *call to get_string | provenance | |
| test.cpp:204:25:204:36 | *call to get_string | test.cpp:205:12:205:20 | *... + ... | provenance | |
| test.cpp:204:25:204:36 | *call to get_string | test.cpp:206:12:206:16 | *hello | provenance | |
@@ -60,11 +55,7 @@ nodes
| test.cpp:130:20:130:26 | *access to array | semmle.label | *access to array |
| test.cpp:167:31:167:34 | *data | semmle.label | *data |
| test.cpp:170:12:170:14 | *res | semmle.label | *res |
| test.cpp:179:6:179:21 | [summary param] *0 in StringCchPrintfW [Return] | semmle.label | [summary param] *0 in StringCchPrintfW [Return] |
| test.cpp:179:6:179:21 | [summary param] *2 in StringCchPrintfW | semmle.label | [summary param] *2 in StringCchPrintfW |
| test.cpp:193:32:193:34 | *str | semmle.label | *str |
| test.cpp:195:20:195:23 | StringCchPrintfW output argument | semmle.label | StringCchPrintfW output argument |
| test.cpp:195:31:195:33 | *str | semmle.label | *str |
| test.cpp:195:31:195:33 | *str | semmle.label | *str |
| test.cpp:197:11:197:14 | *wstr | semmle.label | *wstr |
| test.cpp:204:25:204:36 | *call to get_string | semmle.label | *call to get_string |
@@ -97,7 +88,6 @@ nodes
| test.cpp:245:25:245:36 | *call to get_string | semmle.label | *call to get_string |
| test.cpp:247:12:247:16 | *hello | semmle.label | *hello |
subpaths
| test.cpp:195:31:195:33 | *str | test.cpp:179:6:179:21 | [summary param] *2 in StringCchPrintfW | test.cpp:179:6:179:21 | [summary param] *0 in StringCchPrintfW [Return] | test.cpp:195:20:195:23 | StringCchPrintfW output argument |
#select
| NonConstantFormat.c:30:10:30:16 | *access to array | NonConstantFormat.c:28:27:28:30 | **argv | NonConstantFormat.c:30:10:30:16 | *access to array | The format string argument to $@ has a source which cannot be verified to originate from a string literal. | NonConstantFormat.c:30:3:30:8 | call to printf | printf |
| NonConstantFormat.c:41:9:41:45 | *call to any_random_function | NonConstantFormat.c:41:9:41:45 | *call to any_random_function | NonConstantFormat.c:41:9:41:45 | *call to any_random_function | The format string argument to $@ has a source which cannot be verified to originate from a string literal. | NonConstantFormat.c:41:2:41:7 | call to printf | printf |

View File

@@ -2,10 +2,10 @@
| test.c:33:3:33:19 | call to not_yet_declared2 | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:77:6:77:22 | not_yet_declared2 | not_yet_declared2 | test.c:33:21:33:22 | ca | ca | file://:0:0:0:0 | int[4] | int[4] | test.c:77:24:77:26 | (unnamed parameter 0) | int (unnamed parameter 0) |
| test.c:41:3:41:29 | call to declared_empty_defined_with | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:78:6:78:32 | declared_empty_defined_with | declared_empty_defined_with | test.c:41:31:41:32 | & ... | & ... | file://:0:0:0:0 | int * | int * | test.c:78:38:78:38 | x | int x |
| test.c:45:3:45:27 | call to not_declared_defined_with | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:81:6:81:30 | not_declared_defined_with | not_declared_defined_with | test.c:45:29:45:31 | 4 | 4 | file://:0:0:0:0 | long long | long long | test.c:81:36:81:36 | x | int x |
| test.c:45:3:45:27 | call to not_declared_defined_with | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:81:6:81:30 | not_declared_defined_with | not_declared_defined_with | test.c:45:37:45:42 | 2.5E9 | 2.5E9 | file://:0:0:0:0 | float | float | test.c:81:50:81:50 | z | int z |
| test.c:48:3:48:24 | call to declared_with_pointers | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:5:6:5:27 | declared_with_pointers | declared_with_pointers | test.c:48:26:48:31 | 3.5E15 | 3.5E15 | file://:0:0:0:0 | double | double | test.c:93:34:93:34 | x | int * x |
| test.c:45:3:45:27 | call to not_declared_defined_with | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:81:6:81:30 | not_declared_defined_with | not_declared_defined_with | test.c:45:37:45:42 | 2500000000.0 | 2500000000.0 | file://:0:0:0:0 | float | float | test.c:81:50:81:50 | z | int z |
| test.c:48:3:48:24 | call to declared_with_pointers | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:5:6:5:27 | declared_with_pointers | declared_with_pointers | test.c:48:26:48:31 | 3500000000000000.0 | 3500000000000000.0 | file://:0:0:0:0 | double | double | test.c:93:34:93:34 | x | int * x |
| test.c:48:3:48:24 | call to declared_with_pointers | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:5:6:5:27 | declared_with_pointers | declared_with_pointers | test.c:48:34:48:34 | 0 | 0 | file://:0:0:0:0 | int | int | test.c:93:43:93:43 | y | void * y |
| test.c:48:3:48:24 | call to declared_with_pointers | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:93:6:93:27 | declared_with_pointers | declared_with_pointers | test.c:48:26:48:31 | 3.5E15 | 3.5E15 | file://:0:0:0:0 | double | double | test.c:93:34:93:34 | x | int * x |
| test.c:48:3:48:24 | call to declared_with_pointers | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:93:6:93:27 | declared_with_pointers | declared_with_pointers | test.c:48:26:48:31 | 3500000000000000.0 | 3500000000000000.0 | file://:0:0:0:0 | double | double | test.c:93:34:93:34 | x | int * x |
| test.c:48:3:48:24 | call to declared_with_pointers | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:93:6:93:27 | declared_with_pointers | declared_with_pointers | test.c:48:34:48:34 | 0 | 0 | file://:0:0:0:0 | int | int | test.c:93:43:93:43 | y | void * y |
| test.c:50:3:50:21 | call to declared_with_array | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:6:6:6:24 | declared_with_array | declared_with_array | test.c:50:23:50:24 | & ... | & ... | file://:0:0:0:0 | int * | int * | test.c:94:31:94:31 | a | char[6] a |
| test.c:50:3:50:21 | call to declared_with_array | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:94:6:94:24 | declared_with_array | declared_with_array | test.c:50:23:50:24 | & ... | & ... | file://:0:0:0:0 | int * | int * | test.c:94:31:94:31 | a | char[6] a |
@@ -15,4 +15,4 @@
| test.c:58:3:58:24 | call to defined_with_long_long | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:104:11:104:32 | defined_with_long_long | defined_with_long_long | test.c:58:26:58:28 | 99 | 99 | file://:0:0:0:0 | int | int | test.c:104:44:104:45 | ll | long long ll |
| test.c:59:3:59:24 | call to defined_with_long_long | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:104:11:104:32 | defined_with_long_long | defined_with_long_long | test.c:59:26:59:26 | 3 | 3 | file://:0:0:0:0 | int | int | test.c:104:44:104:45 | ll | long long ll |
| test.c:61:3:61:21 | call to defined_with_double | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:100:8:100:26 | defined_with_double | defined_with_double | test.c:61:23:61:25 | 2 | 2 | file://:0:0:0:0 | long long | long long | test.c:100:35:100:35 | d | double d |
| test.c:62:3:62:24 | call to defined_with_long_long | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:104:11:104:32 | defined_with_long_long | defined_with_long_long | test.c:62:26:62:31 | 3.5E15 | 3.5E15 | file://:0:0:0:0 | double | double | test.c:104:44:104:45 | ll | long long ll |
| test.c:62:3:62:24 | call to defined_with_long_long | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:104:11:104:32 | defined_with_long_long | defined_with_long_long | test.c:62:26:62:31 | 3500000000000000.0 | 3500000000000000.0 | file://:0:0:0:0 | double | double | test.c:104:44:104:45 | ll | long long ll |

View File

@@ -1,2 +0,0 @@
description: Remove `@parameter` from `@control_flow_element`
compatibility: full

View File

@@ -1,2 +0,0 @@
description: Remove @assign_op_call_expr from @qualifiable_expr.
compatibility: full

View File

@@ -95,9 +95,9 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
args += " /p:EnableWindowsTargeting=true";
}
if (restoreSettings.NugetSources is not null)
if (restoreSettings.ExtraArgs is not null)
{
args += $" {restoreSettings.NugetSources}";
args += $" {restoreSettings.ExtraArgs}";
}
return args;

View File

@@ -17,7 +17,7 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
IList<string> GetNugetFeedsFromFolder(string folderPath);
}
public record class RestoreSettings(string File, string PackageDirectory, bool ForceDotnetRefAssemblyFetching, string? NugetSources = null, string? PathToNugetConfig = null, bool ForceReevaluation = false, bool TargetWindows = false);
public record class RestoreSettings(string File, string PackageDirectory, bool ForceDotnetRefAssemblyFetching, string? ExtraArgs = null, string? PathToNugetConfig = null, bool ForceReevaluation = false, bool TargetWindows = false);
public partial record class RestoreResult(bool Success, IList<string> Output)
{
@@ -33,9 +33,6 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
private readonly Lazy<bool> hasNugetNoStablePackageVersionError = new(() => Output.Any(s => s.Contains("NU1103")));
public bool HasNugetNoStablePackageVersionError => hasNugetNoStablePackageVersionError.Value;
private readonly Lazy<bool> hasNugetPackageMissingError = new(() => Output.Any(s => s.Contains("NU1101")));
public bool HasNugetPackageMissingError => hasNugetPackageMissingError.Value;
private static IEnumerable<string> GetFirstGroupOnMatch(Regex regex, IEnumerable<string> lines) =>
lines
.Select(line => regex.Match(line))

View File

@@ -33,7 +33,7 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
/// <summary>
/// Create the package manager for a specified source tree.
/// </summary>
public NugetExeWrapper(FileProvider fileProvider, DependencyDirectory packageDirectory, Semmle.Util.Logging.ILogger logger, Func<bool> useDefaultFeed)
public NugetExeWrapper(FileProvider fileProvider, DependencyDirectory packageDirectory, Semmle.Util.Logging.ILogger logger)
{
this.fileProvider = fileProvider;
this.packageDirectory = packageDirectory;
@@ -43,7 +43,7 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
{
logger.LogInfo($"Found packages.config files, trying to use nuget.exe for package restore");
nugetExe = ResolveNugetExe();
if (HasNoPackageSource() && useDefaultFeed())
if (HasNoPackageSource())
{
// We only modify or add a top level nuget.config file
nugetConfigPath = Path.Combine(fileProvider.SourceDir.FullName, "nuget.config");

View File

@@ -1,7 +1,6 @@
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.IO;
using System.Linq;
using System.Net;
@@ -28,12 +27,8 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
private readonly IDiagnosticsWriter diagnosticsWriter;
private readonly DependencyDirectory legacyPackageDirectory;
private readonly DependencyDirectory missingPackageDirectory;
private readonly DependencyDirectory emptyPackageDirectory;
private readonly ILogger logger;
private readonly ICompilationInfoContainer compilationInfoContainer;
private readonly bool checkNugetFeedResponsiveness = EnvironmentVariables.GetBooleanOptOut(EnvironmentVariableNames.CheckNugetFeedResponsiveness);
private readonly ImmutableHashSet<string> privateRegistryFeeds;
private readonly bool hasPrivateRegistryFeeds;
public DependencyDirectory PackageDirectory { get; }
@@ -50,8 +45,6 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
this.fileContent = fileContent;
this.dotnet = dotnet;
this.dependabotProxy = dependabotProxy;
this.privateRegistryFeeds = dependabotProxy?.RegistryURLs.ToImmutableHashSet() ?? [];
this.hasPrivateRegistryFeeds = privateRegistryFeeds.Count > 0;
this.diagnosticsWriter = diagnosticsWriter;
this.logger = logger;
this.compilationInfoContainer = compilationInfoContainer;
@@ -59,7 +52,6 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
PackageDirectory = new DependencyDirectory("packages", "package", logger);
legacyPackageDirectory = new DependencyDirectory("legacypackages", "legacy package", logger);
missingPackageDirectory = new DependencyDirectory("missingpackages", "missing package", logger);
emptyPackageDirectory = new DependencyDirectory("empty", "empty package", logger);
}
public string? TryRestore(string package)
@@ -118,50 +110,25 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
public HashSet<AssemblyLookupLocation> Restore()
{
var assemblyLookupLocations = new HashSet<AssemblyLookupLocation>();
var checkNugetFeedResponsiveness = EnvironmentVariables.GetBooleanOptOut(EnvironmentVariableNames.CheckNugetFeedResponsiveness);
logger.LogInfo($"Checking NuGet feed responsiveness: {checkNugetFeedResponsiveness}");
compilationInfoContainer.CompilationInfos.Add(("NuGet feed responsiveness checked", checkNugetFeedResponsiveness ? "1" : "0"));
HashSet<string> explicitFeeds = [];
HashSet<string> reachableFeeds = [];
HashSet<string>? explicitFeeds = null;
HashSet<string>? allFeeds = null;
try
{
// Find feeds that are configured in NuGet.config files and divide them into ones that
// are explicitly configured for the project or by a private registry, and "all feeds"
// (including inherited ones) from other locations on the host outside of the working directory.
(explicitFeeds, var allFeeds) = GetAllFeeds();
if (checkNugetFeedResponsiveness)
if (checkNugetFeedResponsiveness && !CheckFeeds(out explicitFeeds, out allFeeds))
{
var inheritedFeeds = allFeeds.Except(explicitFeeds).ToHashSet();
if (inheritedFeeds.Count > 0)
{
compilationInfoContainer.CompilationInfos.Add(("Inherited NuGet feed count", inheritedFeeds.Count.ToString()));
}
var timeout = CheckSpecifiedFeeds(explicitFeeds, out var reachableExplicitFeeds);
reachableFeeds.UnionWith(reachableExplicitFeeds);
var allExplicitReachable = explicitFeeds.Count == reachableExplicitFeeds.Count;
EmitUnreachableFeedsDiagnostics(allExplicitReachable);
if (timeout)
{
// If we experience a timeout, we use this fallback.
// todo: we could also check the reachability of the inherited nuget feeds, but to use those in the fallback we would need to handle authentication too.
var unresponsiveMissingPackageLocation = DownloadMissingPackagesFromSpecificFeeds([], explicitFeeds);
return unresponsiveMissingPackageLocation is null
? []
: [unresponsiveMissingPackageLocation];
}
// Inherited feeds should only be used, if they are indeed reachable (as they may be environment specific).
CheckSpecifiedFeeds(inheritedFeeds, out var reachableInheritedFeeds);
reachableFeeds.UnionWith(reachableInheritedFeeds);
// todo: we could also check the reachability of the inherited nuget feeds, but to use those in the fallback we would need to handle authentication too.
var unresponsiveMissingPackageLocation = DownloadMissingPackagesFromSpecificFeeds([], explicitFeeds);
return unresponsiveMissingPackageLocation is null
? []
: [unresponsiveMissingPackageLocation];
}
using (var nuget = new NugetExeWrapper(fileProvider, legacyPackageDirectory, logger, IsDefaultFeedReachable))
using (var nuget = new NugetExeWrapper(fileProvider, legacyPackageDirectory, logger))
{
var count = nuget.InstallPackages();
@@ -200,10 +167,9 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
logger.LogError($"Failed to restore NuGet packages with nuget.exe: {exc.Message}");
}
// Restore project dependencies with `dotnet restore`.
var restoredProjects = RestoreSolutions(reachableFeeds, out var container);
var restoredProjects = RestoreSolutions(out var container);
var projects = fileProvider.Projects.Except(restoredProjects);
RestoreProjects(projects, reachableFeeds, out var containers);
RestoreProjects(projects, allFeeds, out var containers);
var dependencies = containers.Flatten(container);
@@ -226,53 +192,6 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
return assemblyLookupLocations;
}
/// <summary>
/// Tests which of the feeds given by <paramref name="feedsToCheck"/> are reachable.
/// </summary>
/// <param name="feedsToCheck">The feeds to check.</param>
/// <param name="isFallback">Whether the feeds are fallback feeds or not.</param>
/// <param name="isTimeout">Whether a timeout occurred while checking the feeds.</param>
/// <returns>The list of feeds that could be reached.</returns>
private List<string> GetReachableNuGetFeeds(HashSet<string> feedsToCheck, bool isFallback, out bool isTimeout)
{
var fallbackStr = isFallback ? "fallback " : "";
logger.LogInfo($"Checking {fallbackStr}NuGet feed reachability on feeds: {string.Join(", ", feedsToCheck.OrderBy(f => f))}");
var (initialTimeout, tryCount) = GetFeedRequestSettings(isFallback);
var timeout = false;
var reachableFeeds = feedsToCheck
.Where(feed =>
{
var reachable = IsFeedReachable(feed, initialTimeout, tryCount, out var feedTimeout);
timeout |= feedTimeout;
return reachable;
})
.ToList();
if (reachableFeeds.Count == 0)
{
logger.LogWarning($"No {fallbackStr}NuGet feeds are reachable.");
}
else
{
logger.LogInfo($"Reachable {fallbackStr}NuGet feeds: {string.Join(", ", reachableFeeds.OrderBy(f => f))}");
}
isTimeout = timeout;
return reachableFeeds;
}
private bool IsDefaultFeedReachable()
{
if (checkNugetFeedResponsiveness)
{
var (initialTimeout, tryCount) = GetFeedRequestSettings(isFallback: false);
return IsFeedReachable(PublicNugetOrgFeed, initialTimeout, tryCount, out var _);
}
return true;
}
private List<string> GetReachableFallbackNugetFeeds(HashSet<string>? feedsFromNugetConfigs)
{
var fallbackFeeds = EnvironmentVariables.GetURLs(EnvironmentVariableNames.FallbackNugetFeeds).ToHashSet();
@@ -293,7 +212,17 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
}
}
var reachableFallbackFeeds = GetReachableNuGetFeeds(fallbackFeeds, isFallback: true, out var _);
logger.LogInfo($"Checking fallback NuGet feed reachability on feeds: {string.Join(", ", fallbackFeeds.OrderBy(f => f))}");
var (initialTimeout, tryCount) = GetFeedRequestSettings(isFallback: true);
var reachableFallbackFeeds = fallbackFeeds.Where(feed => IsFeedReachable(feed, initialTimeout, tryCount, allowExceptions: false)).ToList();
if (reachableFallbackFeeds.Count == 0)
{
logger.LogWarning("No fallback NuGet feeds are reachable.");
}
else
{
logger.LogInfo($"Reachable fallback NuGet feeds: {string.Join(", ", reachableFallbackFeeds.OrderBy(f => f))}");
}
compilationInfoContainer.CompilationInfos.Add(("Reachable fallback NuGet feed count", reachableFallbackFeeds.Count.ToString()));
@@ -308,12 +237,10 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
/// Populates dependencies with the relevant dependencies from the assets files generated by the restore.
/// Returns a list of projects that are up to date with respect to restore.
/// </summary>
private IEnumerable<string> RestoreSolutions(HashSet<string> reachableFeeds, out DependencyContainer dependencies)
private IEnumerable<string> RestoreSolutions(out DependencyContainer dependencies)
{
var successCount = 0;
var nugetSourceFailures = 0;
var nugetMissingPackageFailures = 0;
var assets = new Assets(logger);
var isWindows = fileContent.UseWindowsForms || fileContent.UseWpf;
@@ -321,8 +248,7 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
var projects = fileProvider.Solutions.SelectMany(solution =>
{
logger.LogInfo($"Restoring solution {solution}...");
var nugetSources = MakeRestoreSourcesArgument(solution, reachableFeeds);
var res = dotnet.Restore(new(solution, PackageDirectory.DirInfo.FullName, ForceDotnetRefAssemblyFetching: true, NugetSources: nugetSources, TargetWindows: isWindows));
var res = dotnet.Restore(new(solution, PackageDirectory.DirInfo.FullName, ForceDotnetRefAssemblyFetching: true, TargetWindows: isWindows));
if (res.Success)
{
successCount++;
@@ -331,84 +257,51 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
{
nugetSourceFailures++;
}
if (res.HasNugetPackageMissingError)
{
nugetMissingPackageFailures++;
}
assets.AddDependenciesRange(res.AssetsFilePaths);
return res.RestoredProjects;
}).ToList();
dependencies = assets.Dependencies;
compilationInfoContainer.CompilationInfos.Add(("Successfully restored solution files", successCount.ToString()));
compilationInfoContainer.CompilationInfos.Add(("Failed solution restore with package source error", nugetSourceFailures.ToString()));
compilationInfoContainer.CompilationInfos.Add(("Failed solution restore with missing package error", nugetMissingPackageFailures.ToString()));
compilationInfoContainer.CompilationInfos.Add(("Restored projects through solution files", projects.Count.ToString()));
return projects;
}
private string FeedsToRestoreArgument(IEnumerable<string> feeds)
{
// If there are no feeds, we want to override any default feeds that `dotnet restore` would use by passing a dummy source argument.
if (!feeds.Any())
{
return $" -s \"{emptyPackageDirectory.DirInfo.FullName}\"";
}
// Add package sources. If any are present, they override all sources specified in
// the configuration file(s).
var feedArgs = new StringBuilder();
foreach (var feed in feeds)
{
feedArgs.Append($" -s \"{feed}\"");
}
return feedArgs.ToString();
}
/// <summary>
/// Constructs the list of NuGet sources to use for this restore.
/// (1) Use the feeds we get from `dotnet nuget list source`
/// (2) Use private registries, if they are configured
/// </summary>
/// <param name="path">Path to project/solution</param>
/// <param name="reachableFeeds">The set of reachable NuGet feeds.</param>
/// <returns>A string representing the NuGet sources argument for the restore command.</returns>
private string? MakeRestoreSourcesArgument(string path, HashSet<string> reachableFeeds)
{
// Do not construct an set of explicit NuGet sources to use for restore.
if (!checkNugetFeedResponsiveness && !hasPrivateRegistryFeeds)
{
return null;
}
// Find the path specific feeds.
var folder = GetDirectoryName(path);
var feedsToConsider = folder is not null ? GetFeeds(() => dotnet.GetNugetFeedsFromFolder(folder)).ToHashSet() : [];
if (hasPrivateRegistryFeeds)
{
feedsToConsider.UnionWith(privateRegistryFeeds);
}
var feedsToUse = checkNugetFeedResponsiveness
? feedsToConsider.Where(reachableFeeds.Contains)
: feedsToConsider;
return FeedsToRestoreArgument(feedsToUse);
}
/// <summary>
/// Executes `dotnet restore` on all projects in projects.
/// This is done in parallel for performance reasons.
/// Populates dependencies with the relative paths to the assets files generated by the restore.
/// </summary>
/// <param name="projects">A list of paths to project files.</param>
/// <param name="reachableFeeds">The set of reachable NuGet feeds.</param>
private void RestoreProjects(IEnumerable<string> projects, HashSet<string> reachableFeeds, out ConcurrentBag<DependencyContainer> dependencies)
private void RestoreProjects(IEnumerable<string> projects, HashSet<string>? configuredSources, out ConcurrentBag<DependencyContainer> dependencies)
{
// Conservatively, we only set this to a non-null value if a Dependabot proxy is enabled.
// This ensures that we continue to get the old behaviour where feeds are taken from
// `nuget.config` files instead of the command-line arguments.
string? extraArgs = null;
if (this.dependabotProxy is not null)
{
// If the Dependabot proxy is configured, then our main goal is to make `dotnet` aware
// of the private registry feeds. However, since providing them as command-line arguments
// to `dotnet` ignores other feeds that may be configured, we also need to add the feeds
// we have discovered from analysing `nuget.config` files.
var sources = configuredSources ?? new();
this.dependabotProxy.RegistryURLs.ForEach(url => sources.Add(url));
// Add package sources. If any are present, they override all sources specified in
// the configuration file(s).
var feedArgs = new StringBuilder();
foreach (string source in sources)
{
feedArgs.Append($" -s {source}");
}
extraArgs = feedArgs.ToString();
}
var successCount = 0;
var nugetSourceFailures = 0;
var nugetMissingPackageFailures = 0;
ConcurrentBag<DependencyContainer> collectedDependencies = [];
var isWindows = fileContent.UseWindowsForms || fileContent.UseWpf;
@@ -421,8 +314,7 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
foreach (var project in projectGroup)
{
logger.LogInfo($"Restoring project {project}...");
var nugetSources = MakeRestoreSourcesArgument(project, reachableFeeds);
var res = dotnet.Restore(new(project, PackageDirectory.DirInfo.FullName, ForceDotnetRefAssemblyFetching: true, NugetSources: nugetSources, TargetWindows: isWindows));
var res = dotnet.Restore(new(project, PackageDirectory.DirInfo.FullName, ForceDotnetRefAssemblyFetching: true, extraArgs, TargetWindows: isWindows));
assets.AddDependenciesRange(res.AssetsFilePaths);
lock (sync)
{
@@ -434,10 +326,6 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
{
nugetSourceFailures++;
}
if (res.HasNugetPackageMissingError)
{
nugetMissingPackageFailures++;
}
}
}
collectedDependencies.Add(assets.Dependencies);
@@ -445,7 +333,6 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
dependencies = collectedDependencies;
compilationInfoContainer.CompilationInfos.Add(("Successfully restored project files", successCount.ToString()));
compilationInfoContainer.CompilationInfos.Add(("Failed project restore with package source error", nugetSourceFailures.ToString()));
compilationInfoContainer.CompilationInfos.Add(("Failed project restore with missing package error", nugetMissingPackageFailures.ToString()));
}
private AssemblyLookupLocation? DownloadMissingPackagesFromSpecificFeeds(IEnumerable<string> usedPackageNames, HashSet<string>? feedsFromNugetConfigs)
@@ -736,22 +623,28 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
}
}
private static async Task<HttpResponseMessage> ExecuteGetRequest(string address, HttpClient httpClient, CancellationToken cancellationToken)
private static async Task ExecuteGetRequest(string address, HttpClient httpClient, CancellationToken cancellationToken)
{
return await httpClient.GetAsync(address, HttpCompletionOption.ResponseHeadersRead, cancellationToken);
using var stream = await httpClient.GetStreamAsync(address, cancellationToken);
var buffer = new byte[1024];
int bytesRead;
while ((bytesRead = stream.Read(buffer, 0, buffer.Length)) > 0)
{
// do nothing
}
}
private bool IsFeedReachable(string feed, int timeoutMilliSeconds, int tryCount, out bool isTimeout)
private bool IsFeedReachable(string feed, int timeoutMilliSeconds, int tryCount, bool allowExceptions = true)
{
logger.LogInfo($"Checking if NuGet feed '{feed}' is reachable...");
// Configure the HttpClient to be aware of the Dependabot Proxy, if used.
HttpClientHandler httpClientHandler = new();
if (dependabotProxy != null)
if (this.dependabotProxy != null)
{
httpClientHandler.Proxy = new WebProxy(dependabotProxy.Address);
httpClientHandler.Proxy = new WebProxy(this.dependabotProxy.Address);
if (dependabotProxy.Certificate != null)
if (this.dependabotProxy.Certificate != null)
{
httpClientHandler.ServerCertificateCustomValidationCallback = (message, cert, chain, _) =>
{
@@ -766,7 +659,7 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
return false;
}
chain.ChainPolicy.TrustMode = X509ChainTrustMode.CustomRootTrust;
chain.ChainPolicy.CustomTrustStore.Add(dependabotProxy.Certificate);
chain.ChainPolicy.CustomTrustStore.Add(this.dependabotProxy.Certificate);
return chain.Build(cert);
};
}
@@ -774,17 +667,13 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
using HttpClient client = new(httpClientHandler);
isTimeout = false;
for (var i = 0; i < tryCount; i++)
{
using var cts = new CancellationTokenSource();
cts.CancelAfter(timeoutMilliSeconds);
try
{
logger.LogInfo($"Attempt {i + 1}/{tryCount} to reach NuGet feed '{feed}'.");
using var response = ExecuteGetRequest(feed, client, cts.Token).GetAwaiter().GetResult();
response.EnsureSuccessStatusCode();
ExecuteGetRequest(feed, client, cts.Token).GetAwaiter().GetResult();
logger.LogInfo($"Querying NuGet feed '{feed}' succeeded.");
return true;
}
@@ -799,13 +688,14 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
continue;
}
logger.LogInfo($"Querying NuGet feed '{feed}' failed. The reason for the failure: {exc.Message}");
return false;
// We're only interested in timeouts.
var start = allowExceptions ? "Considering" : "Not considering";
logger.LogInfo($"Querying NuGet feed '{feed}' failed in a timely manner. {start} the feed for use. The reason for the failure: {exc.Message}");
return allowExceptions;
}
}
logger.LogWarning($"Didn't receive answer from NuGet feed '{feed}'. Tried it {tryCount} times.");
isTimeout = true;
return false;
}
@@ -829,10 +719,42 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
}
/// <summary>
/// Retrieves a list of excluded NuGet feeds from the corresponding environment variable.
/// Checks that we can connect to all NuGet feeds that are explicitly configured in configuration files
/// as well as any private package registry feeds that are configured.
/// </summary>
private HashSet<string> GetExcludedFeeds()
/// <param name="explicitFeeds">Outputs the set of explicit feeds.</param>
/// <param name="allFeeds">Outputs the set of all feeds (explicit and inherited).</param>
/// <returns>True if all feeds are reachable or false otherwise.</returns>
private bool CheckFeeds(out HashSet<string> explicitFeeds, out HashSet<string> allFeeds)
{
(explicitFeeds, allFeeds) = GetAllFeeds();
HashSet<string> feedsToCheck = explicitFeeds;
// If private package registries are configured for C#, then check those
// in addition to the ones that are configured in `nuget.config` files.
this.dependabotProxy?.RegistryURLs.ForEach(url => feedsToCheck.Add(url));
var allFeedsReachable = this.CheckSpecifiedFeeds(feedsToCheck);
var inheritedFeeds = allFeeds.Except(explicitFeeds).ToHashSet();
if (inheritedFeeds.Count > 0)
{
logger.LogInfo($"Inherited NuGet feeds (not checked for reachability): {string.Join(", ", inheritedFeeds.OrderBy(f => f))}");
compilationInfoContainer.CompilationInfos.Add(("Inherited NuGet feed count", inheritedFeeds.Count.ToString()));
}
return allFeedsReachable;
}
/// <summary>
/// Checks that we can connect to the specified NuGet feeds.
/// </summary>
/// <param name="feeds">The set of package feeds to check.</param>
/// <returns>True if all feeds are reachable or false otherwise.</returns>
private bool CheckSpecifiedFeeds(HashSet<string> feeds)
{
logger.LogInfo("Checking that NuGet feeds are reachable...");
var excludedFeeds = EnvironmentVariables.GetURLs(EnvironmentVariableNames.ExcludedNugetFeedsFromResponsivenessCheck)
.ToHashSet();
@@ -841,49 +763,9 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
logger.LogInfo($"Excluded NuGet feeds from responsiveness check: {string.Join(", ", excludedFeeds.OrderBy(f => f))}");
}
return excludedFeeds;
}
var (initialTimeout, tryCount) = GetFeedRequestSettings(isFallback: false);
/// <summary>
/// Checks that we can connect to the specified NuGet feeds.
/// </summary>
/// <param name="feeds">The set of package feeds to check.</param>
/// <param name="reachableFeeds">The list of feeds that were reachable.</param>
/// <returns>
/// True if there is a timeout when trying to reach the feeds (excluding any feeds that are configured
/// to be excluded from the check) or false otherwise.
/// </returns>
private bool CheckSpecifiedFeeds(HashSet<string> feeds, out HashSet<string> reachableFeeds)
{
// Exclude any feeds from the feed check that are configured by the corresponding environment variable.
// These feeds are always assumed to be reachable.
var excludedFeeds = GetExcludedFeeds();
HashSet<string> feedsToCheck = feeds.Where(feed =>
{
if (excludedFeeds.Contains(feed))
{
logger.LogInfo($"Not checking reachability of NuGet feed '{feed}' as it is in the list of excluded feeds.");
return false;
}
return true;
}).ToHashSet();
reachableFeeds = GetReachableNuGetFeeds(feedsToCheck, isFallback: false, out var isTimeout).ToHashSet();
// Always consider feeds excluded for the reachability check as reachable.
reachableFeeds.UnionWith(feeds.Where(feed => excludedFeeds.Contains(feed)));
return isTimeout;
}
/// <summary>
/// If <paramref name="allFeedsReachable"/> is `false`, logs this and emits a diagnostic.
/// Adds a `CompilationInfos` entry either way.
/// </summary>
/// <param name="allFeedsReachable">Whether all feeds were reachable or not.</param>
private void EmitUnreachableFeedsDiagnostics(bool allFeedsReachable)
{
var allFeedsReachable = feeds.All(feed => excludedFeeds.Contains(feed) || IsFeedReachable(feed, initialTimeout, tryCount));
if (!allFeedsReachable)
{
logger.LogWarning("Found unreachable NuGet feed in C# analysis with build-mode 'none'. This may cause missing dependencies in the analysis.");
@@ -897,6 +779,8 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
));
}
compilationInfoContainer.CompilationInfos.Add(("All NuGet feeds reachable", allFeedsReachable ? "1" : "0"));
return allFeedsReachable;
}
private IEnumerable<string> GetFeeds(Func<IList<string>> getNugetFeeds)
@@ -927,19 +811,6 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
}
}
private string? GetDirectoryName(string path)
{
try
{
return new FileInfo(path).Directory?.FullName;
}
catch (Exception exc)
{
logger.LogWarning($"Failed to get directory of '{path}': {exc}");
}
return null;
}
private (HashSet<string> explicitFeeds, HashSet<string> allFeeds) GetAllFeeds()
{
var nugetConfigs = fileProvider.NugetConfigs;
@@ -957,11 +828,11 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
if (invalidNugetConfigs.Count() > 0)
{
logger.LogWarning(string.Format(
this.logger.LogWarning(string.Format(
"Found incorrectly named NuGet configuration files: {0}",
string.Join(", ", invalidNugetConfigs)
));
diagnosticsWriter.AddEntry(new DiagnosticMessage(
this.diagnosticsWriter.AddEntry(new DiagnosticMessage(
Language.CSharp,
"buildless/case-sensitive-nuget-config",
"Found NuGet configuration files which are not correctly named",
@@ -993,33 +864,41 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
logger.LogDebug("No NuGet feeds found in nuget.config files.");
}
// If private package registries are configured for C#, then consider those
// in addition to the ones that are configured in `nuget.config` files.
if (hasPrivateRegistryFeeds)
{
logger.LogInfo($"Found {privateRegistryFeeds.Count} private registry feeds configured for C#: {string.Join(", ", privateRegistryFeeds.OrderBy(f => f))}");
explicitFeeds.UnionWith(privateRegistryFeeds);
}
HashSet<string> allFeeds = [];
// Add all explicitFeeds to the set of all feeds.
allFeeds.UnionWith(explicitFeeds);
// Obtain the list of feeds from the root source directory.
// If a NuGet file is present it will be respected, otherwise we will just get the machine/environment specific feeds.
var nugetFeedsFromRoot = GetFeeds(() => dotnet.GetNugetFeedsFromFolder(fileProvider.SourceDir.FullName));
allFeeds.UnionWith(nugetFeedsFromRoot);
// todo: this could be improved.
HashSet<string>? allFeeds = null;
if (nugetConfigs.Count > 0)
{
var nugetConfigFeeds = nugetConfigs
.Select(GetDirectoryName)
// We don't have to get the feeds from each of the folders from below, it would be enought to check the folders that recursively contain the others.
allFeeds = nugetConfigs
.Select(config =>
{
try
{
return new FileInfo(config).Directory?.FullName;
}
catch (Exception exc)
{
logger.LogWarning($"Failed to get directory of '{config}': {exc}");
}
return null;
})
.Where(folder => folder != null)
.SelectMany(folder => GetFeeds(() => dotnet.GetNugetFeedsFromFolder(folder!)))
.ToHashSet();
allFeeds.UnionWith(nugetConfigFeeds);
// If we have discovered any explicit feeds, then we also expect these to be in the set of all feeds.
// Normally, it is a safe assumption to make that `GetNugetFeedsFromFolder` will include the feeds configured
// in a NuGet configuration file in the given directory. There is one exception: on a system with case-sensitive
// file systems, we may discover a configuration file such as `Nuget.Config` which is not recognised by `dotnet nuget`.
// In that case, our call to `GetNugetFeeds` will retrieve the feeds from that file (because it is accepted when
// provided explicitly as `--configfile` argument), but the call to `GetNugetFeedsFromFolder` will not.
allFeeds.UnionWith(explicitFeeds);
}
else
{
// If we haven't found any `nuget.config` files, then obtain a list of feeds from the root source directory.
allFeeds = GetFeeds(() => dotnet.GetNugetFeedsFromFolder(this.fileProvider.SourceDir.FullName)).ToHashSet();
}
logger.LogInfo($"Found {allFeeds.Count} NuGet feeds (with inherited ones) in nuget.config files: {string.Join(", ", allFeeds.OrderBy(f => f))}");
@@ -1044,7 +923,6 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
PackageDirectory?.Dispose();
legacyPackageDirectory?.Dispose();
missingPackageDirectory?.Dispose();
emptyPackageDirectory?.Dispose();
}
/// <summary>

View File

@@ -1,5 +1,3 @@
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Text.RegularExpressions;
using Microsoft.CodeAnalysis;
@@ -20,68 +18,114 @@ namespace Semmle.Extraction.CSharp.Util
return symbol.CanBeReferencedByName ? name : name.Substring(symbol.Name.LastIndexOf('.') + 1);
}
private static readonly ReadOnlyDictionary<string, string> methodToOperator = new(new Dictionary<string, string>
{
{ "op_LogicalNot", "!" },
{ "op_BitwiseAnd", "&" },
{ "op_Equality", "==" },
{ "op_Inequality", "!=" },
{ "op_UnaryPlus", "+" },
{ "op_Addition", "+" },
{ "op_UnaryNegation", "-" },
{ "op_Subtraction", "-" },
{ "op_Multiply", "*" },
{ "op_Multiplication", "*" },
{ "op_Division", "/" },
{ "op_Modulus", "%" },
{ "op_GreaterThan", ">" },
{ "op_GreaterThanOrEqual", ">=" },
{ "op_LessThan", "<" },
{ "op_LessThanOrEqual", "<=" },
{ "op_Decrement", "--" },
{ "op_Increment", "++" },
{ "op_Implicit", "implicit conversion" },
{ "op_Explicit", "explicit conversion" },
{ "op_OnesComplement", "~" },
{ "op_RightShift", ">>" },
{ "op_UnsignedRightShift", ">>>" },
{ "op_LeftShift", "<<" },
{ "op_BitwiseOr", "|" },
{ "op_ExclusiveOr", "^" },
{ "op_True", "true" },
{ "op_False", "false" }
});
/// <summary>
/// Convert an operator method name in to a symbolic name.
/// A return value indicates whether the conversion succeeded.
/// </summary>
public static bool TryGetOperatorSymbol(this ISymbol symbol, out string operatorName)
{
static bool TryGetOperatorSymbolFromName(string methodName, out string operatorName)
{
var success = true;
switch (methodName)
{
case "op_LogicalNot":
operatorName = "!";
break;
case "op_BitwiseAnd":
operatorName = "&";
break;
case "op_Equality":
operatorName = "==";
break;
case "op_Inequality":
operatorName = "!=";
break;
case "op_UnaryPlus":
case "op_Addition":
operatorName = "+";
break;
case "op_UnaryNegation":
case "op_Subtraction":
operatorName = "-";
break;
case "op_Multiply":
operatorName = "*";
break;
case "op_Division":
operatorName = "/";
break;
case "op_Modulus":
operatorName = "%";
break;
case "op_GreaterThan":
operatorName = ">";
break;
case "op_GreaterThanOrEqual":
operatorName = ">=";
break;
case "op_LessThan":
operatorName = "<";
break;
case "op_LessThanOrEqual":
operatorName = "<=";
break;
case "op_Decrement":
operatorName = "--";
break;
case "op_Increment":
operatorName = "++";
break;
case "op_Implicit":
operatorName = "implicit conversion";
break;
case "op_Explicit":
operatorName = "explicit conversion";
break;
case "op_OnesComplement":
operatorName = "~";
break;
case "op_RightShift":
operatorName = ">>";
break;
case "op_UnsignedRightShift":
operatorName = ">>>";
break;
case "op_LeftShift":
operatorName = "<<";
break;
case "op_BitwiseOr":
operatorName = "|";
break;
case "op_ExclusiveOr":
operatorName = "^";
break;
case "op_True":
operatorName = "true";
break;
case "op_False":
operatorName = "false";
break;
default:
var match = CheckedRegex().Match(methodName);
if (match.Success)
{
TryGetOperatorSymbolFromName($"op_{match.Groups[1]}", out var uncheckedName);
operatorName = $"checked {uncheckedName}";
break;
}
operatorName = methodName;
success = false;
break;
}
return success;
}
var methodName = symbol.GetName(useMetadataName: false);
// Most common use-case.
if (methodToOperator.TryGetValue(methodName, out var opName))
{
operatorName = opName;
return true;
}
// Attempt to parse using a regexp.
var match = OperatorRegex().Match(methodName);
if (match.Success && methodToOperator.TryGetValue($"op_{match.Groups[2]}", out var rawOperatorName))
{
var prefix = match.Groups[1].Success ? "checked " : "";
var postfix = match.Groups[3].Success ? "=" : "";
operatorName = $"{prefix}{rawOperatorName}{postfix}";
return true;
}
operatorName = methodName;
return false;
return TryGetOperatorSymbolFromName(methodName, out operatorName);
}
[GeneratedRegex("^op_(Checked)?(.*?)(Assignment)?$")]
private static partial Regex OperatorRegex();
[GeneratedRegex("^op_Checked(.*)$")]
private static partial Regex CheckedRegex();
}
}

View File

@@ -228,41 +228,6 @@ namespace Semmle.Extraction.CSharp.Entities
return Literal.CreateGenerated(cx, parent, childIndex, type, defaultValue, location);
}
/// <summary>
/// Given an expression syntax node, attempt to resolve the target method symbol for it.
/// The operation takes extension methods into account.
/// </summary>
/// <param name="node">The expression syntax node.</param>
/// <returns>Returns the target method symbol, or null if it cannot be resolved.</returns>
protected IMethodSymbol? GetTargetSymbol(ExpressionSyntax node)
{
var si = Context.GetSymbolInfo(node);
if (si.Symbol is ISymbol symbol)
{
var method = symbol as IMethodSymbol;
// Case for compiler-generated extension methods.
return method?.TryGetExtensionMethod() ?? method;
}
if (si.CandidateReason == CandidateReason.OverloadResolutionFailure && node is InvocationExpressionSyntax syntax)
{
// This seems to be a bug in Roslyn
// For some reason, typeof(X).InvokeMember(...) fails to resolve the correct
// InvokeMember() method, even though the number of parameters clearly identifies the correct method
var candidates = si.CandidateSymbols
.OfType<IMethodSymbol>()
.Where(method => method.Parameters.Length >= syntax.ArgumentList.Arguments.Count)
.Where(method => method.Parameters.Count(p => !p.HasExplicitDefaultValue) <= syntax.ArgumentList.Arguments.Count);
return Context.ExtractionContext.IsStandalone ?
candidates.FirstOrDefault() :
candidates.SingleOrDefault();
}
return si.Symbol as IMethodSymbol;
}
/// <summary>
/// Adapt the operator kind depending on whether it's a dynamic call or a user-operator call.
/// </summary>
@@ -279,10 +244,10 @@ namespace Semmle.Extraction.CSharp.Entities
/// name if available.
/// </summary>
/// <param name="node">The expression.</param>
public void AddOperatorCall(TextWriter trapFile, ExpressionSyntax node)
public void OperatorCall(TextWriter trapFile, ExpressionSyntax node)
{
var @operator = GetTargetSymbol(node);
if (@operator is IMethodSymbol method)
var @operator = Context.GetSymbolInfo(node);
if (@operator.Symbol is IMethodSymbol method)
{
var callType = GetCallType(Context, node);
if (callType == CallType.Dynamic)

View File

@@ -24,9 +24,10 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions
{
Create(Context, Syntax.Left, this, 0);
Create(Context, Syntax.Right, this, 1);
if (Kind != ExprKind.SIMPLE_ASSIGN && Kind != ExprKind.ASSIGN_COALESCE)
{
AddOperatorCall(trapFile, Syntax);
OperatorCall(trapFile, Syntax);
}
}

View File

@@ -40,7 +40,7 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions
protected override void PopulateExpression(TextWriter trapFile)
{
AddOperatorCall(trapFile, Syntax);
OperatorCall(trapFile, Syntax);
CreateDeferred(Context, Syntax.Left, 0);
CreateDeferred(Context, Syntax.Right, 1);
}

View File

@@ -25,7 +25,7 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions
else
{
// Type conversion
AddOperatorCall(trapFile, Syntax);
OperatorCall(trapFile, Syntax);
TypeMention.Create(Context, Syntax.Type, this, Type);
}
}

View File

@@ -44,7 +44,7 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions
var child = -1;
string? memberName = null;
var target = GetTargetSymbol(Syntax);
var target = TargetSymbol;
switch (Syntax.Expression)
{
case MemberAccessExpressionSyntax memberAccess when IsValidMemberAccessKind():
@@ -129,6 +129,39 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions
method.TryGetExtensionMethod()?.MethodKind == MethodKind.UserDefinedOperator;
}
public IMethodSymbol? TargetSymbol
{
get
{
var si = SymbolInfo;
if (si.Symbol is ISymbol symbol)
{
var method = symbol as IMethodSymbol;
// Case for compiler-generated extension methods.
return method?.TryGetExtensionMethod() ?? method;
}
if (si.CandidateReason == CandidateReason.OverloadResolutionFailure)
{
// This seems to be a bug in Roslyn
// For some reason, typeof(X).InvokeMember(...) fails to resolve the correct
// InvokeMember() method, even though the number of parameters clearly identifies the correct method
var candidates = si.CandidateSymbols
.OfType<IMethodSymbol>()
.Where(method => method.Parameters.Length >= Syntax.ArgumentList.Arguments.Count)
.Where(method => method.Parameters.Count(p => !p.HasExplicitDefaultValue) <= Syntax.ArgumentList.Arguments.Count);
return Context.ExtractionContext.IsStandalone ?
candidates.FirstOrDefault() :
candidates.SingleOrDefault();
}
return si.Symbol as IMethodSymbol;
}
}
private static bool IsDelegateLikeCall(ExpressionNodeInfo info)
{
return IsDelegateLikeCall(info, symbol => IsFunctionPointer(symbol) || IsDelegateInvoke(symbol));

View File

@@ -25,7 +25,7 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions
if ((operatorKind == ExprKind.POST_INCR || operatorKind == ExprKind.POST_DECR) &&
Kind == ExprKind.OPERATOR_INVOCATION)
{
AddOperatorCall(trapFile, Syntax);
OperatorCall(trapFile, Syntax);
trapFile.mutator_invocation_mode(this, 2);
}
}

View File

@@ -24,7 +24,7 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions
protected override void PopulateExpression(TextWriter trapFile)
{
Create(Context, Syntax.Operand, this, 0);
AddOperatorCall(trapFile, Syntax);
OperatorCall(trapFile, Syntax);
if ((operatorKind == ExprKind.PRE_INCR || operatorKind == ExprKind.PRE_DECR) &&
Kind == ExprKind.OPERATOR_INVOCATION)

View File

@@ -1,11 +1,3 @@
## 1.7.66
No user-facing changes.
## 1.7.65
No user-facing changes.
## 1.7.64
No user-facing changes.

View File

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

View File

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

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 1.7.66
lastReleaseVersion: 1.7.64

View File

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

View File

@@ -1,11 +1,3 @@
## 1.7.66
No user-facing changes.
## 1.7.65
No user-facing changes.
## 1.7.64
No user-facing changes.

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